#include <stdio.h>#include <winsock2.h>#pragma comment(lib,"ws2_32.lib")#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)#define IP_HDRINCL 2 //在ws2tcpip.h里定义了的,他的值就是2int main(){ WSADATA WSAdata; // 加载正确版本的winsock库 if(WSAStartup(MAKEWORD(2,2),&WSAdata)!=0) { printf("WSAStartup failed: %d\n",GetLastError()); return 1; } // 创建原始套节字 SOCKET rs; rs=socket(AF_INET,SOCK_RAW,IPPROTO_RAW); if(rs==INVALID_SOCKET) { printf("Socket() failed: %d\n",WSAGetLastError()); return 1; } // 设置IP头操作选项,flag为TRUE,亲自对IP头部处理 BOOL flag = true; if(setsockopt(rs,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR) { printf("setsockopt() failed: %d\n",WSAGetLastError()); return 1; } // 获取机器名和IP地址 char LocalName[255]; struct hostent *pHost; gethostname(LocalName,sizeof(LocalName)-1); pHost = gethostbyname((char *)LocalName); // 填充SOCKADDR_IN结构 SOCKADDR_IN sa; sa.sin_family = AF_INET; sa.sin_port = htons(10000); //sa.sin_addr.S_un.S_addr = inet_addr("172.24.22.222"); //sa.sin_addr =* (in_addr *)pHost->h_addr_list[0]; //填充IP memcpy(&sa.sin_addr,pHost->h_addr_list[0],pHost->h_length); //这三种填充IP的方式都可以 //printf("IP: %s \n",pHost->h_addr); // 将原始套节字绑定到某个确定的网络接口上 if(bind(rs,(PSOCKADDR)&sa,sizeof(sa))==SOCKET_ERROR) { printf("bind() failed: %d\n",WSAGetLastError()); closesocket(rs); return 1; } // 设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包 DWORD dwBufferLen[10]; DWORD dwBufferInLen = 1; DWORD dwBytesReturned = 0; if(WSAIoctl(rs,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL)==SOCKET_ERROR) { printf("WSAIoctl() failed: %d\n",WSAGetLastError()); closesocket(rs); return 1; } // 从绑定的套节字不断接收数据,并打印出来 char buf[65535]={0}; int i=1; while(true) { int ret = recv(rs,buf,sizeof(buf),0); if(ret>0) { for(int j=0;j<255;j++) { printf("%02x",buf[j]); } printf("\n我已经抓了%d个包啦 \n",i); i++; } } closesocket(rs); return 1;}