I am reading a buffer from a socket (AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP)) with the following code. I am using an arp_frame struct to access the component parts of the contained ARP reply. The inet_ntoa() returns the correct first octet of the IP but the other octets are 0 producing 172.0.0.0.
Question 1 is why might this happen? Question 2 is how can I print r bytes of the msg buffer as hex in host byte order to debug the packet?
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));
}
}
}
struct ether_arp
looks like this:
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 */
};
With that in mind, I think that your addr.s_addr = *arp_frame->arp_spa;
looks a little fishy. arp_frame->arp_spa
yields a u_int8_t[4]
, which you then dereference as a pointer. I think memcpy()
might be more appropriate there.