2015-03-02 67 views
0

首先是結構:麻煩捕獲IP數據包與libpcap的

/* Ethernet addresses are 6 bytes */ 
#define ETHER_ADDR_LEN 6 

/* Ethernet header */ 
struct sniff_ethernet { 
    u_char ether_dhost[ETHER_ADDR_LEN]; /* Destination host address */ 
    u_char ether_shost[ETHER_ADDR_LEN]; /* Source host address */ 
    u_short ether_type; /* IP? ARP? RARP? etc */ 
}; 
#define ETHERTYPE_IP  0x0800  /* IP */ 

/* IP header */ 
struct sniff_ip { 
    u_char ip_vhl;  /* version << 4 | header length >> 2 */ 
    u_char ip_tos;  /* type of service */ 
    u_short ip_len;  /* total length */ 
    u_short ip_id;  /* identification */ 
    u_short ip_off;  /* fragment offset field */ 
    u_char ip_ttl;  /* time to live */ 
    u_char ip_p;  /* protocol */ 
    u_short ip_sum;  /* checksum */ 
    struct in_addr ip_src,ip_dst; /* source and dest address */ 
}; 
#define IP_HL(ip)  (((ip)->ip_vhl) & 0x0f) 
#define IP_V(ip)  (((ip)->ip_vhl) >> 4) 

我與pcap_open_live打開網絡設備,該pcap_datalinkDLT_EN10MB該設備,但我獲得了大量的IP報頭的0長度,怪異版本號等 下面是輸出片段這樣的:

eth = (struct sniff_ethernet*)(packet); 
    ip = (struct sniff_ip*)(eth + 14); /* ETHERNET = 14 */ 
    int version_ip = IP_V(ip); 
    int size_ip = IP_HL(ip)*4; 

    printf("caplen=%d len=%d eth->type=%d version_ip=%d size_ip=%d !\n", header.caplen, header.len, eth->ether_type, version_ip, size_ip); 

和一些輸出樣本:

caplen=94 len=94 eth->type=8 version_ip=0 size_ip=0 ! 
caplen=159 len=159 eth->type=8 version_ip=9 size_ip=12 ! 
caplen=110 len=110 eth->type=8 version_ip=0 size_ip=12 ! 
caplen=200 len=336 eth->type=8 version_ip=4 size_ip=20 ! (this one is OK) 

這是怎麼回事?

  • 爲什麼eth類型是0x0008而不是0x0800?字節序?
  • 怎麼了奇怪的IP頭版本?
  • IP標頭長度如何低於20字節?
+0

'ntohs(eth-> ether_type)'修復了第一個問題。 – xnor 2015-03-02 13:07:25

回答

0

發現問題...

eth = (struct sniff_ethernet*)(packet); 
ip = (struct sniff_ip*)(eth + 14); /* should be (packet + 14) */ 

的 '智能' C指針算術不添加14個字節,但14*sizeof(struct sniff_ethernet)