2013-07-31 112 views
0

我正在使用以下代碼從套接字(AF_PACKET,SOCK_DGRAM,htons(ETH_P_ARP))讀取緩衝區。我正在使用arp_frame結構來訪問包含的ARP回覆的組件部分。 inet_ntoa()返回IP的正確的第一個字節,但其他八位字節是0,產生172.0.0.0。這段代碼爲什麼會產生一個不完整的IP地址?

問題1是爲什麼會發生這種情況? 問題2是如何在主機字節順序中以十六進制格式打印msg緩衝區的r個字節以調試數據包?

unsigned char msg[65535]; 
    struct ether_arp *arp_frame = (struct ether_arp *)msg; 

    while ((r = recv(sock, msg, sizeof(msg), 0))) { 
      // skip it's not an ARP REPLY 
      if (ntohs(arp_frame->arp_op) != ARPOP_REPLY) 
        continue; 

      for (i = 0; i < SONOS_PREFIX_NUM; i++) { 
        if (!memcmp(sonos_prefixes[i], arp_frame->arp_sha, 3)) { 
          struct in_addr addr; 
          addr.s_addr = *arp_frame->arp_spa; 

          printf("Blah: %lu\n", ntohl(*arp_frame->arp_spa)); 
          printf("Sonos found at %s\n", inet_ntoa(addr)); 
        } 
      } 
    } 

回答

2

struct ether_arp看起來是這樣的:

struct ether_arp { 
    struct arphdr ea_hdr;   /* fixed-size header */ 
    u_int8_t arp_sha[ETH_ALEN];  /* sender hardware address */ 
    u_int8_t arp_spa[4];   /* sender protocol address */ 
    u_int8_t arp_tha[ETH_ALEN];  /* target hardware address */ 
    u_int8_t arp_tpa[4];   /* target protocol address */ 
}; 

考慮到這一點,我認爲你的addr.s_addr = *arp_frame->arp_spa;看起來有點腥。 arp_frame->arp_spa會生成u_int8_t[4],然後您將其作爲指針解除引用。我認爲memcpy()可能更適合那裏。

+0

Bawls。似乎我諮詢完全錯誤的手冊,因爲它說這是一個u_long - http://www.propox.com/download/edunet_doc/all/html/structether__arp.html。謝謝:) –

+0

它可能取決於平臺......在不需要字節反轉的大端系統上,它可以方便地存儲爲32位整數,但在小端系統中,我想它會取決於實施者選擇的'ntohl()'和朋友的實現......儘管它是一個無符號的int/long,但是,將它當作指針是不正確的...... – twalberg

0

如果您認爲API已損壞,請打印出字節。 「這個錯誤不在星星裏。」

+0

您會看到我正在過濾以確保這些回覆。我還應該注意到這是源地址,而不是目的地址,並且代碼爲所有解析的ARP回覆生成172.0.0.0。 –

+0

現在看到了正確的答案,這個答案中唯一有用的部分是「如果您認爲API已損壞,請打印出字節。」 – Joshua

相關問題