如何在 Windows 上使用 C++ 中的 Npcap 库区分 IPv4 和 IPv6 数据包?

问题描述 投票:0回答:1

我正在 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。

c++ ip
1个回答
0
投票

我做了一些更多的研究,并能够找到这个解决方案,我知道它有点基础,但对我有用,解决方案的任何额外内容将不胜感激:

// 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;
}
© www.soinside.com 2019 - 2024. All rights reserved.