使用socket编程实现IP协议数据帧的抓取:
#include "stdafx.h" #include<winsock2.h> #pragma comment(lib,"ws2_32.lib") #define MAX_HOSTNAME_LAN 255 #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) #define MAX_ADDR_LEN 16 //IP协议头 struct ipheader { unsigned char ip_hl:4, ip_v:4; /* this means that each member is 4 bits */ unsigned char ip_tos; unsigned short int ip_len; unsigned short int ip_id; unsigned short int ip_off; unsigned char ip_ttl; unsigned char ip_p; unsigned short int ip_sum; unsigned int ip_src; unsigned int ip_dst; }; /* total ip header length: 20 bytes (=160 bits) */ //UDP协议头 typedef struct udphdr { unsigned short sport; unsigned short dport; unsigned short len; unsigned short cksum; }UDP_HDR; //TCP协议头 typedef struct tcphdr { //待实现 }TCP_HDR; void main() { SOCKET sock; WSADATA wsd; DWORD dwBytesRet; unsigned int optval = 1; unsigned char *dataudp,*pUdpData; int QQ,iUdpDataLen; SOCKADDR_IN sa,saSource, saDest; struct hostent FAR * pHostent; char FAR name[MAX_HOSTNAME_LAN]; char szSourceIP[MAX_ADDR_LEN],RecvBuf[65535] = {0}; struct udphdr *pUdpheader; struct ipheader *pIpheader; WSAStartup(MAKEWORD(2,1),&wsd); if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP))==SOCKET_ERROR) exit(1); gethostname(name, MAX_HOSTNAME_LAN); pHostent = gethostbyname(name); sa.sin_family = AF_INET; sa.sin_port = htons(0);//0即监听所有端口 memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length); bind(sock, (SOCKADDR *)&sa, sizeof(sa)); if ((WSAGetLastError())==10013) exit(1); WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL); while (1) { memset(RecvBuf, 0, sizeof(RecvBuf)); recv(sock, RecvBuf, sizeof(RecvBuf), 0); pIpheader = (struct ipheader *)RecvBuf; if((pIpheader->ip_p)==IPPROTO_UDP) { pUdpheader = (struct udphdr *) (RecvBuf+ sizeof(struct ipheader )); pUdpData=(unsigned char *) RecvBuf+sizeof(struct ipheader)+sizeof(struct udphdr); iUdpDataLen=ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct udphdr)); printf("recv udp data from %d:%d,to %d:%d,data len:%d\n",ntohl(pIpheader->ip_src),ntohs(pUdpheader->sport),ntohl(pIpheader->ip_dst),ntohs(pUdpheader->dport),iUdpDataLen); printf("udp data:%s\n",pUdpData); } else if((pIpheader->ip_p)==IPPROTO_TCP) { //解析TCP协议头和数据 printf("recv tcp data\n"); } else if((pIpheader->ip_p)==IPPROTO_ICMP) { //解析ICMP协议头和数据 printf("recv icmp data\n"); } else if((pIpheader->ip_p)==IPPROTO_IGMP) { //解析IGMP协议头和数据 printf("recv igmp data\n"); } else { printf("other ip protocol:%d\n",pIpheader->ip_p); } } }