我正在使用以下代码从套接字(AF_PACKET,SOCK_DGRAM,htons(ETH_P_ARP))读取缓冲区。我使用arp_frame结构来访问包含的ARP回复的组成部分。 inet_ntoa()返回IP的正确的第一个八位字节,但其他八位字节为0,产生172.0.0.0。
问题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));
}
}
}
答案 0 :(得分: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()
可能更合适。
答案 1 :(得分:0)
如果您认为API已损坏,请打印出字节。
“Methinks,Brutus,故障不在明星中。”