I'm using libpcap to decode some ip packets.
But I find both the ethernet ether_shost/ether_dhost and ip saddr/daddr I decode are the same.
Where do I mess up?
Thanks in advance.
Here's part of the callback function:
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
...
}
inet_ntoa
does the following:
The key thing is that it uses the same buffer each time you call it!
So when this line runs:
printf("%s -> %s\n", inet_ntoa(saddr), inet_ntoa(daddr));
first it will put one address in the buffer, then it will put the other address in the buffer, then it will print the contents of the buffer twice.
You could fix this by storing the strings in your own separate buffers:
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);
or by calling printf
twice:
printf("%s -> ", inet_ntoa(saddr));
printf("%s\n", inet_ntoa(daddr));
ether_ntoa
has the same problem.