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 }