【VS开发】raw socket 的例子

    xiaoxiao2025-01-08  12

    raw socket 的例子

    一. 摘要    Raw Socket: 原始套接字    可以用它来发送和接收 IP 层以上的原始数据包, 如 ICMP, TCP, UDP...

        int sockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);

      这样我们就创建了一个 Raw Socket

      Sniffer: 嗅探器    关于嗅探器的原理我想大多数人可能都知道    1. 把网卡置于混杂模式;    2. 捕获数据包;    3. 分析数据包.

      但具体的实现知道的人恐怕就不是那么多了. 好, 现在让我们用 Raw Socket 的做一个自已的 Sniffer.

    二. 把网卡置于混杂模式    在正常的情况下,一个网络接口应该只响应两种数据帧:    一种是与自己硬件地址相匹配的数据帧    一种是发向所有机器的广播数据帧    如果要网卡接收所有通过它的数据, 而不管是不是发给它的, 那么必须把网卡置于混杂模式. 也就是说让它的思维混乱, 不按正常的方式工作. 用 Raw Socket 实现代码如下:

        setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag); //设置 IP 头操作选项      bind(sockRaw, (PSOCKADDR)&addrLocal, sizeof(addrLocal); //把 sockRaw 绑定到本地网卡上      ioctlsocket(sockRaw, SIO_RCVALL, &dwValue);       //让 sockRaw 接受所有的数据

      flag 标志是用来设置 IP 头操作的, 也就是说要亲自处理 IP 头: bool flag = ture;    addrLocal 为本地地址: SOCKADDR_IN addrLocal;    dwValue 为输入输出参数, 为 1 时执行, 0 时取消: DWORD dwValue = 1;    没想到这么简单吧?

    三. 捕获数据包    你的 sockRaw 现在已经在工作了, 可以在局域网内其它的电脑上用 Sniffer 检测工具检测一下, 看你的网卡是否处于混杂模式(比如 DigitalBrain 的 ARPKiller).    不能让他白白的浪费资源啊, 抓包!

        recv(sockRaw, RecvBuf, BUFFER_SIZE, 0); //接受任意数据包

      #define BUFFER_SIZE 65535    char RecvBuf[BUFFER_SIZE];    越来越发现 Sniffer 原来如此的简单了, 这么一个函数就已经完成抓取数据包的任务了.

    四. 分析数据包    这回抓来的包和平常用 Socket 接受的包可就不是一回事儿了, 里面包含 IP, TCP 等原始信息. 要分析它首先得知道这些结构.    数据包的总体结构:    ----------------------------------------------    | ip header | tcp header(or x header) | data |    ----------------------------------------------

      IP header structure:         4    8    16                    32 bit    |--------|--------|----------------|--------------------------------|    | Ver  | IHL  |Type of service |     Total length     |    |--------|--------|----------------|--------------------------------|    | Identification |   Flags   |     Fragment offset    |    |--------|--------|----------------|--------------------------------|    | Time to live  |  Protocol  |     Header checksum    |    |--------|--------|----------------|--------------------------------|    |             Source address              |    |--------|--------|----------------|--------------------------------|    |            Destination address             |    |--------|--------|----------------|--------------------------------|    |            Option + Padding              |    |--------|--------|----------------|--------------------------------|    |                Data                |    |--------|--------|----------------|--------------------------------|

      TCP header structure:                    16                32 bit    |--------------------------------|--------------------------------|    |     Source port      |    Destination port    |    |--------------------------------|--------------------------------|    |             Sequence number             |    |--------------------------------|--------------------------------|    |           Acknowledgement number           |    |--------------------------------|--------------------------------|    | Offset | Resrvd |U|A|P|R|S|F|      Window       |    |--------------------------------|--------------------------------|    |      Checksum       |    Urgent pointer     |    |--------------------------------|--------------------------------|    |             Option + Padding            |    |--------------------------------|--------------------------------|    |               Data                |    |--------------------------------|--------------------------------|

    五. 实现 Sniffer    OK!    现在都清楚了, 还等什么.    下面是我用 BCB6 写的一个 Simple Sniffer 的代码, 仅供参考.    (需要在工程文件里加入WS2_32.LIB这个文件)  //  //  #include <vcl.h>  #pragma hdrstop

    #include <winsock2.h>  #include <ws2tcpip.h>  #include <mstcpip.h>  #include <netmon.h>  #include "WMain.h"  //---------------------------------------------------------------------------  #pragma package(smart_init)  #pragma resource "*.dfm"  TMainForm *MainForm;  //---------------------------------------------------------------------------  __fastcall TMainForm::TMainForm(TComponent* Owner)    : TForm(Owner)  {  WSADATA WSAData;    BOOL  flag  = true;    int   nTimeout = 1000;    char  LocalName[16];    struct hostent *pHost;

      //检查 Winsock 版本号    if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)      throw Exception("WSAStartup error!");

      //初始化 Raw Socket    if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == INVALID_SOCKET)      throw Exception("socket setup error!");

      //设置IP头操作选项    if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag)) == SOCKET_ERROR)      throw Exception("setsockopt IP_HDRINCL error!");

      //获取本机名    if (gethostname((char*)LocalName, sizeof(LocalName)-1) == SOCKET_ERROR)      throw Exception("gethostname error!");

      //获取本地 IP 地址    if ((pHost = gethostbyname((char*)LocalName)) == NULL)      throw Exception("gethostbyname error!");

      addr_in.sin_addr  = *(in_addr *)pHost->h_addr_list[0]; //IP    addr_in.sin_family = AF_INET;    addr_in.sin_port  = htons(57274);

      //把 sock 绑定到本地地址上    if (bind(sock, (PSOCKADDR)&addr_in, sizeof(addr_in)) == SOCKET_ERROR)      throw Exception("bind error!");

      iSortDirection = 1;  }  //---------------------------------------------------------------------------  __fastcall TMainForm::~TMainForm()  {    WSACleanup();  }  //---------------------------------------------------------------------------

    void __fastcall TMainForm::btnCtrlClick(TObject *Sender)  {    TListItem *Item;    DWORD dwValue;    int nIndex = 0;

      if (btnCtrl->Caption == "&Start")    {      dwValue = 1;      //设置 SOCK_RAW 为SIO_RCVALL,以便接收所有的IP包      if (ioctlsocket(sock, SIO_RCVALL, &dwValue) != 0)        throw Exception("ioctlsocket SIO_RCVALL error!");      bStop = false;      btnCtrl->Caption = "&Stop";      lsvPacket->Items->Clear();    }    else    {      dwValue = 0;      bStop = true;      btnCtrl->Caption = "&Start";      //设置SOCK_RAW为SIO_RCVALL,停止接收      if (ioctlsocket(sock, SIO_RCVALL, &dwValue) != 0)        throw Exception("WSAIoctl SIO_RCVALL error!");    }

      while (!bStop)    {      if (recv(sock, RecvBuf, BUFFER_SIZE, 0) > 0)      {        nIndex++;        ip = *(IP*)RecvBuf;        tcp = *(TCP*)(RecvBuf + (ip.HdrLen & IP_HDRLEN_MASK));

          Item = lsvPacket->Items->Add();        Item->Caption = nIndex;        Item->SubItems->Add(GetProtocolTxt(ip.Protocol));        Item->SubItems->Add(inet_ntoa(*(in_addr*)&ip.SrcAddr));        Item->SubItems->Add(inet_ntoa(*(in_addr*)&ip.DstAddr));        Item->SubItems->Add(tcp.SrcPort);        Item->SubItems->Add(tcp.DstPort);        Item->SubItems->Add(ntohs(ip.TotalLen));      }      Application->ProcessMessages();    }    }  //---------------------------------------------------------------------------

    AnsiString __fastcall TMainForm::GetProtocolTxt(int Protocol)  {    switch (Protocol)    {      case IPPROTO_ICMP :      //1               return PROTOCOL_STRING_ICMP_TXT;      case IPPROTO_TCP :      //6               return PROTOCOL_STRING_TCP_TXT;      case IPPROTO_UDP :      //17              return PROTOCOL_STRING_UDP_TXT;      default :        return PROTOCOL_STRING_UNKNOWN_TXT;    }  }  //---------------------------------------------------------------------------

    //  //  //---------------------------------------------------------------------------

    #ifndef WMainH  #define WMainH  //---------------------------------------------------------------------------  #define BUFFER_SIZE 65535

    #include <Classes.hpp>  #include <Controls.hpp>  #include <StdCtrls.hpp>  #include <Forms.hpp>  #include <ComCtrls.hpp>  #include <ExtCtrls.hpp>  #include <winsock2.h>  #include "netmon.h"

    //---------------------------------------------------------------------------  class TMainForm : public TForm  {  __published: // IDE-managed Components    TPanel *Panel1;    TButton *btnCtrl;    TListView *lsvPacket;    TLabel *Label1;    void __fastcall btnCtrlClick(TObject *Sender);    void __fastcall lsvPacketColumnClick(TObject *Sender,       TListColumn *Column);    void __fastcall lsvPacketCompare(TObject *Sender, TListItem *Item1,       TListItem *Item2, int Data, int &Compare);    void __fastcall Label1Click(TObject *Sender);  private: // User declarations    AnsiString __fastcall GetProtocolTxt(int Protocol);  public: // User declarations    SOCKET   sock;    SOCKADDR_IN addr_in;    IP     ip;    TCP     tcp;    PSUHDR   psdHeader;    char    RecvBuf[BUFFER_SIZE];    bool    bStop;

      int iSortDirection;    int iColumnToSort;    __fastcall TMainForm(TComponent* Owner);    __fastcall ~TMainForm();  };  //---------------------------------------------------------------------------  extern PACKAGE TMainForm *MainForm;  //---------------------------------------------------------------------------  #endif

      偷了个懒, IP, TCP 头及一些宏定义用了 netmon.h 的头, 这个文件在 BCB6 的 include 目录下可以找得到, 其中与本程序相关内容如下:

    //  //  //  // IP Packet Structure  //  typedef struct _IP  {    union    {      BYTE  Version;      BYTE  HdrLen;    };    BYTE ServiceType;    WORD TotalLen;    WORD ID;    union    {      WORD  Flags;      WORD  FragOff;    };    BYTE TimeToLive;    BYTE Protocol;    WORD HdrChksum;    DWORD  SrcAddr;    DWORD  DstAddr;    BYTE Options[0];  } IP;

    typedef IP * LPIP;  typedef IP UNALIGNED * ULPIP;

    //  // TCP Packet Structure  //  typedef struct _TCP    {    WORD SrcPort;    WORD DstPort;    DWORD SeqNum;    DWORD AckNum;    BYTE DataOff;    BYTE Flags;    WORD Window;    WORD Chksum;    WORD UrgPtr;    } TCP;

    typedef TCP *LPTCP;  typedef TCP UNALIGNED * ULPTCP;

    // upper protocols  #define PROTOCOL_STRING_ICMP_TXT    "ICMP"  #define PROTOCOL_STRING_TCP_TXT    "TCP"  #define PROTOCOL_STRING_UDP_TXT    "UDP"  #define PROTOCOL_STRING_SPX_TXT    "SPX"  #define PROTOCOL_STRING_NCP_TXT    "NCP"

    #define PROTOCOL_STRING_UNKNOW_TXT   "UNKNOW"

      这个文件也有人声称没有.  //  //  // Copyright (c) Microsoft Corporation. All rights reserved.  #if _MSC_VER > 1000  #pragma once  #endif

    struct tcp_keepalive {    u_long onoff;    u_long keepalivetime;    u_long keepaliveinterval;  };

    // New WSAIoctl Options

    #define SIO_RCVALL      _WSAIOW(IOC_VENDOR,1)  #define SIO_RCVALL_MCAST   _WSAIOW(IOC_VENDOR,2)  #define SIO_RCVALL_IGMPMCAST _WSAIOW(IOC_VENDOR,3)  #define SIO_KEEPALIVE_VALS  _WSAIOW(IOC_VENDOR,4)  #define SIO_ABSORB_RTRALERT  _WSAIOW(IOC_VENDOR,5)  #define SIO_UCAST_IF     _WSAIOW(IOC_VENDOR,6)  #define SIO_LIMIT_BROADCASTS _WSAIOW(IOC_VENDOR,7)  #define SIO_INDEX_BIND    _WSAIOW(IOC_VENDOR,8)  #define SIO_INDEX_MCASTIF   _WSAIOW(IOC_VENDOR,9)  #define SIO_INDEX_ADD_MCAST  _WSAIOW(IOC_VENDOR,10)  #define SIO_INDEX_DEL_MCAST  _WSAIOW(IOC_VENDOR,11)

    // Values for use with SIO_RCVALL* options  #define RCVALL_OFF       0  #define RCVALL_ON       1  #define RCVALL_SOCKETLEVELONLY 2

      现在我们自已的 Sniffer 就做好了, Run, Start......哇, 这么多数据包, 都是从这一台机器上发出的, 它在干什么? 原来 Adminstrator 密码为空, 中了尼姆达病毒!

    六. 小结    优点: 实现简单, 不需要做驱动程序就可实现抓包.    缺点: 数据包头不含帧信息, 不能接收到与 IP 同层的其它数据包, 如 ARP, RARP...    这里提供的程序仅仅是一个 Sniffer 的例子, 没有对数据包进行进一步的分析. 写此文的目的在于熟悉Raw Socket 编程方法, 了解 TCP/IP 协议结构原理以及各协议之间的关系.

    posted @ 2009-05-07 22:16 WindFly 阅读(354) 评论(0) 编辑

    基于套接字发送伪造IP包

    这 里介绍Windows Sockets的一些关于原始套接字(Raw Socket)的编程。同Winsock1相比,最明显的就是支持了Raw Socket套接字类型,通过原始套接字,我们可以更加自如地控制Windows下的多种协议,而且能够对网络底层的传输机制进行控制。  1、创建一个原始套接字,并设置IP头选项。  SOCKET sock;  sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP);  或者:  s = WSASoccket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);  这 里,我们设置了SOCK_RAW标志,表示我们声明的是一个原始套接字类型。创建原始套接字后,IP头就会包含在接收的数据中,如果我们设定 IP_HDRINCL 选项,那么,就需要自己来构造IP头。注意,如果设置IP_HDRINCL 选项,那么必须具有 administrator权限,要不就必须修改注册表:  HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Afd\Parameter\  修改键:DisableRawSecurity(类型为DWORD),把值修改为 1。如果没有,就添加。  BOOL blnFlag=TRUE;  setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&blnFlag, sizeof(blnFlag);  对于原始套接字在接收数据报的时候,要注意这么几点:  1、如果接收的数据报中协议类型和定义的原始套接字匹配,那么,接收的所有数据就拷贝到套接字中。  2、如果绑定了本地地址,那么只有接收数据IP头中对应的远端地址匹配,接收的数据就拷贝到套接字中。  3、如果定义的是外部地址,比如使用connect(),那么,只有接收数据IP头中对应的源地址匹配,接收的数据就拷贝到套接字中。  2、构造IP头和TCP头  这里,提供IP头和TCP头的结构:  // Standard TCP flags  #define URG 0x20  #define ACK 0x10  #define PSH 0x08  #define RST 0x04  #define SYN 0x02  #define FIN 0x01  typedef struct _iphdr //定义IP首部  {  unsigned char h_lenver; //4位首部长度+4位IP版本号  unsigned char tos; //8位服务类型TOS  unsigned short total_len; //16位总长度(字节)  unsigned short ident; //16位标识  unsigned short frag_and_flags; //3位标志位  unsigned char ttl; //8位生存时间 TTL  unsigned char proto; //8位协议 (TCP, UDP 或其他)  unsigned short checksum; //16位IP首部校验和  unsigned int sourceIP; //32位源IP地址  unsigned int destIP; //32位目的IP地址  }IP_HEADER;  typedef struct psd_hdr //定义TCP伪首部  {  unsigned long saddr; //源地址  unsigned long daddr; //目的地址  char mbz;  char ptcl; //协议类型  unsigned short tcpl; //TCP长度  }PSD_HEADER;  typedef struct _tcphdr //定义TCP首部  {  USHORT th_sport; //16位源端口  USHORT th_dport; //16位目的端口  unsigned int th_seq; //32位序列号  unsigned int th_ack; //32位确认号  unsigned char th_lenres; //4位首部长度/6位保留字  unsigned char th_flag; //6位标志位  USHORT th_win; //16位窗口大小  USHORT th_sum; //16位校验和  USHORT th_urp; //16位紧急数据偏移量  }TCP_HEADER;  TCP伪首部并不是真正存在的,只是用于计算检验和。校验和函数:  USHORT checksum(USHORT *buffer, int size)  {  unsigned long cksum=0;  while (size > 1)  {  cksum += *buffer++;  size -= sizeof(USHORT);  }  if (size)  {  cksum += *(UCHAR*)buffer;  }  cksum = (cksum >> 16) + (cksum & 0xffff);  cksum += (cksum >>16);  return (USHORT)(~cksum);  }  当需要自己填充IP头部和TCP头部的时候,就同时需要自己计算他们的检验和。  3、发送原始套接字数据报  填充这些头部稍微麻烦点,发送就相对简单多了。只需要使用sendto()就OK。  sendto(sock, (char*)&tcpHeader, sizeof(tcpHeader), 0, (sockaddr*)&addr_in,sizeof(addr_in));  下面是一个示例程序,可以作为SYN扫描的一部分。  #include <stdio.h>  #include <winsock2.h>  #include <ws2tcpip.h>  #define SOURCE_PORT 7234  #define MAX_RECEIVEBYTE 255  typedef struct ip_hdr //定义IP首部  {  unsigned char h_verlen; //4位首部长度,4位IP版本号  unsigned char tos; //8位服务类型TOS  unsigned short total_len; //16位总长度(字节)  unsigned short ident; //16位标识  unsigned short frag_and_flags; //3位标志位  unsigned char ttl; //8位生存时间 TTL  unsigned char proto; //8位协议 (TCP, UDP 或其他)  unsigned short checksum; //16位IP首部校验和  unsigned int sourceIP; //32位源IP地址  unsigned int destIP; //32位目的IP地址  }IPHEADER;  typedef struct tsd_hdr //定义TCP伪首部  {  unsigned long saddr; //源地址  unsigned long daddr; //目的地址  char mbz;  char ptcl; //协议类型  unsigned short tcpl; //TCP长度  }PSDHEADER;  typedef struct tcp_hdr //定义TCP首部  {  USHORT th_sport; //16位源端口  USHORT th_dport; //16位目的端口  unsigned int th_seq; //32位序列号  unsigned int th_ack; //32位确认号  unsigned char th_lenres; //4位首部长度/6位保留字  unsigned char th_flag; //6位标志位  USHORT th_win; //16位窗口大小  USHORT th_sum; //16位校验和  USHORT th_urp; //16位紧急数据偏移量  }TCPHEADER;  //CheckSum:计算校验和的子函数  USHORT checksum(USHORT *buffer, int size)  {  unsigned long cksum=0;  while(size >1)  {  cksum+=*buffer++;  size -=sizeof(USHORT);  }  if(size )  {  cksum += *(UCHAR*)buffer;  }  cksum = (cksum >> 16) + (cksum & 0xffff);  cksum += (cksum >>16);  return (USHORT)(~cksum);  }  void useage()  {  printf("******************************************\n");  printf("TCPPing\n");  printf("\t Written by Refdom\n");  printf("\t Email: refdom@263.net\n");  printf("Useage: TCPPing.exe Target_ip Target_port \n");  printf("*******************************************\n");  }  int main(int argc, char* argv[])  {  WSADATA WSAData;  SOCKET sock;  SOCKADDR_IN addr_in;  IPHEADER ipHeader;  TCPHEADER tcpHeader;  PSDHEADER psdHeader;  char szSendBuf[60]={0};  BOOL flag;  int rect,nTimeOver;  useage();  if (argc!= 3)  { return false; }  if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0)  {  printf("WSAStartup Error!\n");  return false;  }  if ((sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)  {  printf("Socket Setup Error!\n");  return false;  }  flag=true;  if (setsockopt(sock,IPPROTO_IP, IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR)  {  printf("setsockopt IP_HDRINCL error!\n");  return false;  }  nTimeOver=1000;  if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver))==SOCKET_ERROR)  {  printf("setsockopt SO_SNDTIMEO error!\n");  return false;  }  addr_in.sin_family=AF_INET;  addr_in.sin_port=htons(atoi(argv[2]));  addr_in.sin_addr.S_un.S_addr=inet_addr(argv[1]);  //  //  //填充IP首部  ipHeader.h_verlen=(4<<4 | sizeof(ipHeader)/sizeof(unsigned long));  // ipHeader.tos=0;  ipHeader.total_len=htons(sizeof(ipHeader)+sizeof(tcpHeader));  ipHeader.ident=1;  ipHeader.frag_and_flags=0;  ipHeader.ttl=128;  ipHeader.proto=IPPROTO_TCP;  ipHeader.checksum=0;  ipHeader.sourceIP=inet_addr("本地地址");  ipHeader.destIP=inet_addr(argv[1]);  //填充TCP首部  tcpHeader.th_dport=htons(atoi(argv[2]));  tcpHeader.th_sport=htons(SOURCE_PORT); //源端口号  tcpHeader.th_seq=htonl(0x12345678);  tcpHeader.th_ack=0;  tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0);  tcpHeader.th_flag=2; //修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK探测 等等  tcpHeader.th_win=htons(512);  tcpHeader.th_urp=0;  tcpHeader.th_sum=0;  psdHeader.saddr=ipHeader.sourceIP;  psdHeader.daddr=ipHeader.destIP;  psdHeader.mbz=0;  psdHeader.ptcl=IPPROTO_TCP;  psdHeader.tcpl=htons(sizeof(tcpHeader));  //计算校验和  memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));  memcpy(szSendBuf+sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));  tcpHeader.th_sum=checksum((USHORT *)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader));  memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));  memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));  memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4);  ipHeader.checksum=checksum((USHORT *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader));  memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));  rect=sendto(sock, szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader),  0, (struct sockaddr*)&addr_in, sizeof(addr_in));  if (rect==SOCKET_ERROR)  {  printf("send error!:%d\n",WSAGetLastError());  return false;  }  else  printf("send ok!\n");  closesocket(sock);  WSACleanup();  return 0;  }  4、接收数据  和 发送原始套接字数据相比,接收就比较麻烦了。因为在WIN我们不能用recv()来接收raw socket上的数据,这是因为,所有的IP包都是先递交给系统核心,然后再传输到用户程序,当发送一个raws socket包的时候(比如syn),核心并不知道,也没有这个数据被发送或者连接建立的记录,因此,当远端主机回应的时候,系统核心就把这些包都全部丢 掉,从而到不了应用程序上。所以,就不能简单地使用接收函数来接收这些数据报。  要达到接收数据的目的,就必须采用嗅探,接收所有通过的数据包,然后进行筛选,留下符合我们需要的。可以再定义一个原始套接字,用来完成接收数据的任务,需要设置SIO_RCVALL,表示接收所有的数据。  SOCKET sniffersock;  sniffsock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);  DWORD lpvBuffer = 1;  DWORD lpcbBytesReturned = 0 ;  WSAIoctl(sniffersock, SIO_RCVALL, &lpvBuffer, sizeof(lpvBuffer), NULL, 0, & lpcbBytesReturned, NULL, NULL);  创建一个用于接收数据的原始套接字,我们可以用接收函数来接收数据包了。然后在使用一个过滤函数达到筛选的目的,接收我们需要的数据包。

    转载请注明原文地址: https://ju.6miu.com/read-1295267.html
    最新回复(0)