#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里定义了的,他的值就是2
int 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_IP);
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("192.168.1.83");
//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;
}