【发布时间】:2021-06-21 08:16:55
【问题描述】:
我正在尝试在 Windows 中使用 npcap SDK (https://nmap.org/npcap/) 获取所有数据包的源地址和目标地址。它适用于 IPv4,但它为 IPv6 地址的源和目标返回相同的地址。这是我的 packet_handler 回调函数的代码:
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);
}
}
我看到的问题是,当 eth_type 用于 IPv6 数据包(例如 eth_type == 0x86DD)时,saddr 和 daddr 是相同的 IP 地址,但字节顺序不同。我已经检查了两倍和三倍的代码,但是当我检查 iph->ip_src 和 iph->ip_dst 时,我看到了相同的类型,所以看起来 npcap 库返回了相同的地址。我看不出我能做些什么来改变这种行为。有人遇到过这种情况吗?
【问题讨论】:
-
我对npcap一无所知,但是ipv4和ipv6的听者是不同的。您的代码将所有内容都视为 ipv4 标头,只是盲目地将 ipv4 地址转换为 ipv6 地址,这显然是行不通的。
-
卢克,你能澄清一下你的意思吗?我正在获取 eth_type 并检查它以确定我何时有 IPv6 数据包。如果数据包是 IPv4 (eth_type == 0x0800) 我使用 IPv4 调用,当它们是 IPv6 (eth_type == 0x86DD) 我使用 IPv6 调用。当 eth_type 指定它们是 IPv6 时,我只转换为 IPv6。
-
我假设 npcap 为您提供了以太网帧的缓冲区。这将包含一个 IP 帧。 IP 帧将有一个标头,并且该标头的格式在 IPv4 和 IPv6 之间有所不同。鉴于上下文,我假设 sniff_ip 代表 IPv4 标头。当您处理 IPv6 数据时,这将包含垃圾值。您需要转换为 IPv6 标头结构。我认为这种情况下一定有类似 sniff_ip6 的东西。
-
谢谢你,卢克。这就说得通了。我一直在四处寻找文档,告诉我 pkt_data 结构对于 IPv6 数据包是什么,但我还没有找到任何东西。您的反馈有助于为我指明正确的方向。我现在正在挖掘 npcap 和 libpcap 的源代码,但我还没有找到调用回调的代码。
标签: c++ windows pcap libpcap npcap