如何解决PCAP编码::我的代码设置了错误的以太网类型
我正在编写一个C程序,该程序构建一个Ethernet / 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文件格式错误。我应该 不 在其中具有Logical-Link Control标头;我的代码认为它正在编写以太网II / IPv4 / TCP标头。此时,我的直觉是PCAP数据包头(必须处理PCAP文件中的每个数据包)或我的以太网头都不正确。哪个会告诉Wireshark“ 接下来的X个字节是以太网II标头?”
这是我的代码,摘录如下:
PCAP标头和以太网帧的结构直接来自the before-mentioned SO post.,该解决方案是对PCAP数据包标头使用pcap_sf_pkthdr
结构:
// 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应该如何知道我的以太网头是Ethernet II,而不是具有Logical-Link头的802.3以太网。是否在PCAP数据包头中进行了通信?还是在某个地方的以太网框架中?我希望获得建议。谢谢
解决方法
Wireshark应该知道我的以太网头是Ethernet II,而不是具有Logical-Link头的802.3以太网。是在PCAP数据包标题中传达的信息吗?
否。
还是在以太网框架中的某个地方?
是的
如果需要详细信息,请参见the "Types" section中的the Wikipedia "Ethernet frame" page。
但是,问题似乎出在,您正在写入文件的数据包中没有完整的6字节目标和源地址-目标地址的最后两个字节是0x08 0x00,即
以某种方式,程序的版本1将目标地址和源地址放入pcap记录的数据部分,而版本2则没有。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。