【问题标题】:PCAP Coding :: My Code is Setting the Wrong Type of EthernetPCAP 编码 :: 我的代码设置了错误的以太网类型
【发布时间】:2020-09-03 12:52:27
【问题描述】:

我正在编写一个 C 程序,它构建一个以太网/IPv4/TCP 网络数据包,然后将数据包写入 PCAP 文件以供检查。我从SO post here. 构建我的代码 我的代码的第一个版本运行良好,但它是一个很大的main() 函数,不能移植到更大的程序中。

所以我重新组织了代码,以便将其移植到另一个程序中。我不想在这篇文章中讨论版本 1 和版本 2 之间的区别。但不用说,第 2 版效果很好,除了一个烦人的怪癖。当 Wireshark 打开第 1 版 PCAP 文件时,它看到我的第 2 层是以太网 II:

Frame 1: 154 bytes on wire (1232 bits), 154 bytes captured (1232 bits)
Ethernet II, Src: 64:96:c8:fa:fc:ff (64:96:c8:fa:fc:ff), Dst: Woonsang_04:05:06 (01:02:03:04:05:06)
    Destination: Woonsang_04:05:06 (01:02:03:04:05:06)
    Source: 64:96:c8:fa:fc:ff (64:96:c8:fa:fc:ff)
    Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 10.10.10.10, Dst: 20.20.20.20
Transmission Control Protocol, Src Port: 22, Dst Port: 55206, Seq: 1, Ack: 1, Len: 100
SSH Protocol

但在第 2 版中,第 2 层标头变成了 802.3 以太网:

Frame 1: 154 bytes on wire (1232 bits), 134 bytes captured (1072 bits)
IEEE 802.3 Ethernet 
    Destination: Vibratio_1c:08:00 (00:09:70:1c:08:00)
    Source: 45:00:23:28:06:cf (45:00:23:28:06:cf)
    Length: 64
    Trailer: 050401040204000001020506040400070602040704060202…
Logical-Link Control
Data (61 bytes)
[Packet size limited during capture: Ethernet truncated]

我不是网络专家,但我猜我的第 2 版 PCAP 文件在某个地方格式不正确。我应该在其中有一个逻辑链接控制标题;我的代码认为它正在编写以太网 II / IPv4 / TCP 标头。在这一点上,我的直觉是 PCAP 数据包标头(处理 PCAP 文件中的每个数据包所必需的)或我的以太网标头不正确,不知何故。哪个会告诉 Wireshark “接下来的 X 字节是以太网 II 标头?

这是我的代码,摘录:

PCAP 标头和以太网帧的结构直接来自 the before-mentioned SO post. 该帖子中的解决方案是使用pcap_sf_pkthdr 结构作为 PCAP 数据包标头:

// struct for PCAP Packet Header - Timestamp
struct pcap_timeval {
        bpf_int32 tv_sec;       // seconds
        bpf_int32 tv_usec;      // microseconds
};
// struct for PCAP Packet Header
struct pcap_sf_pkthdr {
        struct pcap_timeval ts; // time stamp
        bpf_u_int32 caplen;     // length of portion present
        bpf_u_int32 len;        // length this packet (off wire)
};

以太网标头来自原帖:

// struct for the Ethernet header
struct ethernet {
        u_char          mac1[6];
        u_char          mac2[6];
        u_short         protocol;   // will be ETHERTYPE_IP, for IPv4
};

这两种结构都没有太多内容,对吧?我真的不明白 Wireshark 是怎么看这个的,并且知道数据包的前 20 个字节是以太网。

以下是实际代码,略有删节:

#include <netinet/in.h>     // for ETHERTYPE_IP

struct pcap_sf_pkthdr* allocatePCAPPacketHdr(struct pcap_sf_pkthdr* pcapPacketHdr ){
        pcapPacketHdr = malloc( sizeof(struct pcap_sf_pkthdr) );
        if( pcapPacketHdr == NULL ){
                return NULL;
        }
        uint32_t frameSize = sizeof( struct ethernet) + …correctly computed here
        bzero( pcapPacketHdr, sizeof( struct pcap_sf_pkthdr ) );
        pcapPacketHdr->ts.tv_sec = 0;           // for now
        pcapPacketHdr->ts.tv_usec = 0;          // for now
        pcapPacketHdr->caplen = frameSize;
        pcapPacketHdr->len =    frameSize;
        return pcapPacketHdr;
}
void* allocateL2Hdr( packetChecklist* pc, void* l2header ){
        l2header = malloc( sizeof( struct ethernet ) );
        if( l2header == NULL ){
                return NULL;
        }
        bzero( ((struct ethernet*)l2header)->mac1, 6 );
        bzero( ((struct ethernet*)l2header)->mac2, 6 );
         // …MAC addresses filled in later…
         ((struct ethernet*)l2header)->protocol =  ETHERTYPE_IP;   // This is correctly set
        return l2header;
}

...以及使用上述功能的代码...

struct pcap_sf_pkthdr* pcapPacketHdr;
pcapPacketHdr = allocatePCAPPacketHdr( pcapPacketHdr );
struct ethernet* l2header;
l2header = allocateL2Hdr( l2header );

稍后,代码填充这些结构并将它们连同 IPv4 标头、TCP 标头等写入文件。

但我认为我的问题是我真的不明白 Wireshark 应该如何知道我的以太网标头是以太网 II 而不是带有逻辑链路标头的 802.3 以太网。是否在 PCAP 数据包标头中进行了通信?或者在某个地方的以太网框架中?我希望得到建议。谢谢

【问题讨论】:

    标签: c header ethernet pcap


    【解决方案1】:

    Wireshark 应该知道我的以太网标头是以太网 II,而不是带有逻辑链路标头的 802.3 以太网。是在 PCAP 数据包头中传达的吗?

    没有。

    或者在以太网框架的某个地方?

    是的。

    如果您想了解详细信息,请参阅例如 the "Types" sectionthe Wikipedia "Ethernet frame" page

    但是,问题似乎是您正在写入文件的数据包中没有完整的 6 字节目标地址和源地址 - 目标地址的最后两个字节是 0x08 0x00,它们是ETHERTYPE_IP (0x0800) 的 big-endian 值的前两个字节,源地址的第一个字节是 0x45,这是没有 IP 选项的 IPv4 数据包的 IPv4 标头的第一个字节。

    不知何故,您的程序的版本 1 将目标地址和源地址放入 pcap 记录的数据部分,但版本 2 没有。

    【讨论】:

    • 是的!是的!!!很好的收获,我不敢相信我没有亲眼看到!是的,版本 2 没有以某种方式打印完整的 MAC 地址。现在我知道应该把精力放在哪里。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2021-06-29
    • 2016-03-23
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 2015-12-23
    相关资源
    最近更新 更多