windows下原始套接字的使用
#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <MSTcpIP.h>
#pragma comment(lib,"Ws2_32.lib")
#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 _icmphdr //定义ICMP首部
{
BYTE i_type; //8位类型
BYTE i_code; //8位代码
USHORT i_cksum; //16位校验和
USHORT i_id; //识别号(一般用进程号作为识别号)
USHORT i_seq; //报文序列号
ULONG timestamp; //时间戳
}ICMP_HEADER;
//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);
}
int main(int argc, char* argv[]){
int res = 0;
WSADATA WSAData;
SOCKET sock;
SOCKADDR_IN addr_in;
IPHEADER ipHeader;
BOOL flag;
int rect,nTimeOver;
if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0)
{
printf("WSAStartup Error!\n");
return false;
}
res = ~0;
sock=socket(AF_INET, SOCK_RAW, IPPROTO_IP);
//sock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, WSA_FLAG_OVERLAPPED);
if(INVALID_SOCKET == sock){
res = -1;
}
flag=true;
if (setsockopt(sock,IPPROTO_IP, IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR)
{
res = WSAGetLastError();
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=0;
addr_in.sin_addr.S_un.S_addr=inet_addr("192.168.10.55");
res = bind(sock, (sockaddr*)&addr_in, sizeof(addr_in));
u_long dwValue = 1;
res = ioctlsocket(sock, SIO_RCVALL, &dwValue);
// DWORD lpvBuffer = 1;
// DWORD lpcbBytesReturned = 0 ;
// res = WSAIoctl(sock, SIO_RCVALL, &lpvBuffer, sizeof(lpvBuffer), NULL, 0, & lpcbBytesReturned, NULL, NULL);
unsigned char buf[1024 << 4] = {0};
for(int i = 0; ;i++){
memset(buf, 0, sizeof(buf));
rect=recv(sock, (char*)buf, sizeof(buf), 0);
if (rect==SOCKET_ERROR){
printf("send error!:%d\n",WSAGetLastError());
return false;
}else{
unsigned char* p = buf;
if(buf[9] == 0x01){
p += 12;
printf("srcIP:%d.%d.%d.%d --> desIP:%d.%d.%d.%d type=%d code=%d\n",
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], buf[sizeof(IPHEADER)], buf[sizeof(IPHEADER) + 1]);
}
}
}
closesocket(sock);
WSACleanup();
getchar();
return 0;
}