1.网络编程在自己定义结构体实现协议的时候,一定要注意字节对齐这个问题。否则sizeof和强制转换指针的时候都会出现很难发现的bug。
什么是字节对齐自行百度。
1 #pragma pack (1)//字节对齐的控制!非常注意!
2 //定义一个以太网头部
3 typedef struct ehhdr
4
5 {
6
7 UCHAR eh_dst[6]; /* destination ethernet addrress */
8
9 UCHAR eh_src[6]; /* source ethernet addresss */
10
11 USHORT eh_type; /* ethernet pachet type */
12
13 }ETHERHEAD;
14
15 //28字节的ARP请求/应答
16
17 typedef struct arphdr
18
19 {
20
21 USHORT arp_hrd; /* format of hardware address */
22
23 USHORT arp_pro; /* format of protocol address */
24
25 UCHAR arp_hln; /* length of hardware address */
26
27 UCHAR arp_pln; /* length of protocol address */
28
29 USHORT arp_op; /* ARP/RARP operation */
30
31 UCHAR arp_sha[6]; /* sender hardware address */
32
33 ULONG arp_spa; /* sender protocol address */
34
35 UCHAR arp_tha[6]; /* target hardware address */
36
37 ULONG arp_tpa; /* target protocol address */
38
39 }ARPHEAD;
40
41 #pragma pack ()//字节对齐的控制
2. 注意网络字节序和本机字节序的转换。使用ntohs()等函数。下面是一个winpcap回调函数的例子,用来检测本机是否在进行ARP扫描,对代码有任何建议欢迎指出交流。
1 void packet_handler_ARP(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
2 {
3 struct tm *ltime;
4 ltime = new struct tm;
5 char timestr[16];
6 time_t local_tv_sec;
7 time_t tTimer = time(0);
8 static unsigned short nNum;
9
10 if ( tTimer - g_tStartTimer > SNIFF_TIME)//计时嗅探时间
11 pcap_breakloop(g_OpenDev);
12
13 /* 将时间戳转换成可识别的格式 */
14 local_tv_sec = header->ts.tv_sec;
15 localtime_s(ltime, &local_tv_sec);
16 strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
17
18 printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
19
20 //嗅探自己是否发出了ARP
21 ETHERHEAD *pEtherHead = NULL;
22 pEtherHead = (ETHERHEAD*)pkt_data;
23 if ( strncmp((const char*)(pEtherHead->eh_src), (const char*)(g_aMac), 6) == 0) {//检测源地址是否是本机
24 ARPHEAD *pARPHead = NULL;
25 //printf ("是本机发出的ARP数据");
26 pARPHead = (ARPHEAD*)(pkt_data + sizeof(ETHERHEAD));
27 if (ntohs (pARPHead->arp_pro) == 0x0800 &&//IP
28 ntohs(pARPHead->arp_op) == 0x0001 &&//ARP Request
29 (ntohl(pARPHead->arp_tpa) & 0xffff0000)== 0xc0a80000 ) {//是ARP请求内网IP
30 nNum ++;
31 //printf ("计数+1\n");
32 if (nNum > WARN_NUM) {//计数超过了阈值参数
33 g_bWarning = true;
34 pcap_breakloop(g_OpenDev);
35 }
36 }
37 }
38
39
40 }