我正在 Windows 上开发一个桌面应用程序,用于捕获和处理来自网络主机的网络接口的数据包。我正在使用带有 C++ 的 Npcap 库。谁能告诉我如何确定数据包是 IPv4 还是 IPv6?
这是我在网上搜索解决方案后编写的代码:
// check if packet is ipv4
bool IsIpv4Packet(const u_char* packetData)
{
// Assuming Ethernet frame or Wi-Fi frame
if ((packetData[EthernetHeaderSize - 2] == 0x08 && packetData[EthernetHeaderSize - 1] == 0x00) || // EtherType for IPv4
(packetData[EthernetHeaderSize - 2] == 0x08 && packetData[EthernetHeaderSize - 1] == 0x06) || // EtherType for Wi-Fi (WEP)
(packetData[EthernetHeaderSize - 2] == 0x08 && packetData[EthernetHeaderSize - 1] == 0x08) || // EtherType for Wi-Fi (WPA)
(packetData[0] == 0x88 && packetData[1] == 0x8E)) { // Type for Wi-Fi (802.1X)
// It's an IPv4 packet
return true;
}
return false;
}
// check if packet is ipv4
bool IsIpv6Packet(const u_char* packetData)
{
// Assuming Ethernet frame or Wi-Fi frame
if ((packetData[EthernetHeaderSize - 2] == 0x86 && packetData[EthernetHeaderSize - 1] == 0xDD) || // EtherType for IPv6
(packetData[EthernetHeaderSize - 2] == 0x08 && packetData[EthernetHeaderSize - 1] == 0x06) || // EtherType for Wi-Fi (WEP)
(packetData[EthernetHeaderSize - 2] == 0x08 && packetData[EthernetHeaderSize - 1] == 0x08) || // EtherType for Wi-Fi (WPA)
(packetData[0] == 0x88 && packetData[1] == 0x8E)) { // Type for Wi-Fi (802.1X)
// It's an IPv6 packet
return true;
}
return false;
}
代码似乎无法按照预期确定数据包是 IPv4 还是 IPv6。
我做了一些更多的研究,并能够找到这个解决方案,我知道它有点基础,但对我有用,解决方案的任何额外内容将不胜感激:
// Check if packet is IPv4
bool PacketCollector::IsIpv4Packet(const u_char* packetData, int linkType)
{
if (linkType == EthernetFrame)
{
// Ethernet frame
const uint16_t ethType = (packetData[12] << 8) | packetData[13];
return ethType == 0x0800; // IPv4 Ethernet frame
}
else if (linkType == WifiFrame)
{ // Wi-Fi frame (Assuming Wi-Fi data frames)
// parse the data frame to check if it's IPv4
// check the EtherType inside the data frame.
const uint16_t etherType = (packetData[30] << 8) | packetData[31]; // Assuming Ethernet II frame
return etherType == 0x0800; // IPv4 EtherType
}
return false;
}
// Check if packet is IPv6
bool PacketCollector::IsIpv6Packet(const u_char* packetData, int linkType)
{
if (linkType == EthernetFrame)
{
// Ethernet frame
const uint16_t ethType = (packetData[12] << 8) | packetData[13];
return ethType == 0x86DD; // IPv6 Ethernet frame
}
else if (linkType == WifiFrame)
{ // Wi-Fi frame (Assuming Wi-Fi data frames)
// parse the data frame to check if it's IPv6
// check the EtherType inside the data frame.
const uint16_t etherType = (packetData[30] << 8) | packetData[31]; // Assuming Ethernet II frame
return etherType == 0x86DD; // Wi-Fi data frame for IPv6
}
return false;
}