2013-07-31 79 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

相关问题