2017-04-27 41 views
0

我正在使用libpcap解碼一些ip數據包。有關使用libpcap的以太網/ IP標頭主機/地址的問題?

但我發現以太網ether_shost/ether_dhost和ip saddr/daddr解碼都是一樣的。

我在哪裏搞砸了?

在此先感謝。

這裏的回調函數的一部分:

void 
got_packet(u_char *args, const struct pcap_pkthdr *header, 
    const u_char *packet) 
{ 
    ... 
    eth_h = (struct ether_header *) packet; 
    struct ether_addr shost, dhost; 
    memcpy(&shost, eth_h->ether_shost, sizeof(shost)); 
    memcpy(&dhost, eth_h->ether_dhost, sizeof(dhost)); 
    printf("L2 DLT_EN10MB: %s -> %s\n", ether_ntoa(&shost), ether_ntoa(&dhost)); // shost == dhost? 

    if (ntohs(eth_h->ether_type) != ETHERTYPE_IP) { 
     return; 
    } 

    // only work for L2 DLT_EN10MB 
    ip_h = (struct iphdr *) (packet + sizeof(struct ether_header)); 
    if (ip_h->version != 4) { 
     return; 
    } 

    struct in_addr saddr, daddr; 
    saddr.s_addr = ip_h->saddr; 
    daddr.s_addr = ip_h->daddr; 

    printf("%s -> %s\n", inet_ntoa(saddr), inet_ntoa(daddr)); // saddr == daddr? 
    printf("%" PRIu32 " -> %" PRIu32 "\n", ntohl(ip_h->saddr), ntohl(ip_h->daddr)); // actually not the same 
    ... 
} 

回答

1

inet_ntoa執行以下操作:

  • 放地址的字符串形式到緩衝區
  • 返回緩衝區的地址

關鍵是它使用了相同緩衝每次你打電話給它!

所以,當這條線運行:

printf("%s -> %s\n", inet_ntoa(saddr), inet_ntoa(daddr)); 

首先它會放一個地址在緩衝區中,然後它會把其他地址在緩衝區中,然後將打印緩衝區的內容兩倍。

你可以通過存儲在自己單獨的緩衝區中的字符串解決這個問題:

char saddr_str[INET_ADDRSTRLEN]; 
char daddr_str[INET_ADDRSTRLEN]; 
strcpy(saddr_str, inet_ntoa(saddr)); 
strcpy(daddr_str, inet_ntoa(daddr)); 
printf("%s -> %s\n", saddr_str, daddr_str); 

或致電printf兩次:

printf("%s -> ", inet_ntoa(saddr)); 
printf("%s\n", inet_ntoa(daddr)); 

 

ether_ntoa有同樣的問題。

相關問題