I'm trying to get the source and destination addresses for all packets using the npcap SDK (https://nmap.org/npcap/) in Windows. It works for IPv4, but it is returning the same address for the source and destination for IPv6 addresses. Here is the code for my packet_handler callback function:
void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data)
{
u_int ip_len;
u_short eth_type;
const sniff_ip* iph;
const in6_addr* orig_saddr6;
const in6_addr* orig_daddr6;
in6_addr swapped_saddr;
in6_addr swapped_daddr;
const struct sniff_ethernet* ethernet; /* The ethernet header */
ip_len = header->len;
ethernet = (struct sniff_ethernet*)(pkt_data);
eth_type = ntohs(ethernet->ether_type);
iph = (sniff_ip*)(pkt_data +
14); //length of ethernet header
if (eth_type == 0x0800) {
char str_saddr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(iph->ip_src), str_saddr, INET_ADDRSTRLEN);
char str_daddr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(iph->ip_dst), str_daddr, INET_ADDRSTRLEN);
printf("%s %s\n", str_saddr, str_daddr);
}
else if (eth_type == 0x86DD)
{
char str_saddr[INET6_ADDRSTRLEN];
orig_saddr6 = (const in6_addr*)&(iph->ip_src);
ipv6_sbyteswap(orig_saddr6, &swapped_saddr);
inet_ntop(AF_INET6, &swapped_saddr, str_saddr, INET6_ADDRSTRLEN);
char str_daddr[INET6_ADDRSTRLEN];
orig_daddr6 = (const in6_addr*)&(iph->ip_dst);
ipv6_dbyteswap(orig_daddr6, &swapped_daddr);
inet_ntop(AF_INET6, &swapped_daddr, str_daddr, INET6_ADDRSTRLEN);
printf("%s %s\n", str_saddr, str_daddr);
}
}
The problem I am seeing is that the saddr and daddr are the same IP address when the eth_type is for IPv6 packets (e.g. eth_type == 0x86DD), except the bytes are in a different order. I've doubled and tripled check the code, but when I check the iph->ip_src and iph->ip_dst I see the same types, so it looks like the npcap library is returning the same address. I don't see anything I can do to change the behavior. Has anyone ran into this?
To resolve the problem, you have to cast the IP header using the appropriate IPv6 structure. Here is the working code: