我在不使用libpcap库的情况下用c ++编写pcap文件。数据包结构是正确的。但我发现IP数据包的长度是错误的,因此其余的协议都没有显示出来。错误显示在附加的'pcap file error image'文件中。我搜索了libpcap format wireshark等等......但是我没有找到解决问题的方法。
这是我的代码
int iWritePcapHeader(){
pcap_global_header_s.magic_number = 0xa1b2c3d4 ;
pcap_global_header_s.version_major = PCAP_VERSION_MAJOR ;
pcap_global_header_s.version_minor = PCAP_VERSION_MINOR;
pcap_global_header_s.thiszone = 0; // check here if timestamps of packets are not correct
pcap_global_header_s.sigfigs = 0;
pcap_global_header_s.snaplen = 65535;
pcap_global_header_s.network = 1; //Ethernet
return 0;
}
uint16_t uiIPHeader_Checksum(void *data, int len)
{
uint32_t sum=0;
size_t i;
for (i=0; i < len/2; ++i)
sum += ntohs(((uint16_t*)data)[i]);
while (sum & 0xFFFF0000)
sum = (sum & 0xFFFF)+(sum >> 16);
return ((uint16_t) ~sum);
}
int iWrite(
const CString &rcsSrcAddress, unsigned long ulSrcPort,
const CString &rcsDestAddress, unsigned long ulDestPort,
enum E_PROTOCOL_TYPE eProtocolType,
const unsigned char *pucBytes, unsigned long ulNofBytes)
{
printf("iWrite %ul\n" , ulNofBytes);
iWritePcapHeader();
//PCAP header for each data packet
SYSTEMTIME timews;
GetSystemTime(&timews);
PCAP_PKT_HEADER pcap_pkt_header_s ;
pcap_pkt_header_s.ts_sec = time(NULL);
pcap_pkt_header_s.ts_usec = (timews.wMilliseconds * 1000);
pcap_pkt_header_s.incl_len = ulNofBytes + sizeof(UDP_HEADER) + sizeof(IP_HEADER) + sizeof(ETHERNET_HEADER);
pcap_pkt_header_s.orig_len = ulNofBytes + sizeof(UDP_HEADER) + sizeof(IP_HEADER) + sizeof(ETHERNET_HEADER);
//Ethernet Header
ETHERNET_HEADER ethernet_header_s;
unsigned char macAddress[6] = {0x00,0x00,0x00,0x00,0x00,0x00}; // no mac available for now. Hence just fill in dummy data
memcpy(ethernet_header_s.dst,macAddress,6);
memcpy(ethernet_header_s.src,macAddress,6);
ethernet_header_s.type = 0x0800;
//IP_Header
IP_HEADER ip_header_s;
ip_header_s.ip_v = IPVERSION;
ip_header_s.ip_hl = 5;
ip_header_s.ip_tos = 0;
ip_header_s.ip_len = (uint16_t)(ulNofBytes + sizeof(UDP_HEADER) + sizeof(IP_HEADER));
ip_header_s.ip_id = 0;
ip_header_s.ip_off = IP_DF;
ip_header_s.ip_ttl = 0x40; // 40(hex) = 64 , 80(hex) = 128
ip_header_s.ip_p = 0x11;
ip_header_s.ip_src = inet_addr(rcsSrcAddress);
ip_header_s.ip_dst = inet_addr(rcsDestAddress);
ip_header_s.ip_sum = (uint16_t)(uiIPHeader_Checksum(&ip_header_s, sizeof(IP_HEADER)));
//UDP Header
UDP_HEADER udp_header_s;
udp_header_s.srcPort = ulSrcPort;
udp_header_s.dstPort = ulDestPort;
udp_header_s.length = (uint16_t)(ulNofBytes + sizeof(UDP_HEADER));
if (eProtocolType == E_UDP) {
//UDP Header
UDP_HEADER udp_header_s;
udp_header_s.srcPort = ulSrcPort;
udp_header_s.dstPort = ulDestPort;
udp_header_s.length = (uint16_t)(ulNofBytes + sizeof(UDP_HEADER));
// wiresharkPkt = pcap_pkt_header_s + ethernet_header_s + ip_header_s + udp_header_s + pucBytes ;
WIRESHARK_UDP_PKT_HEADER wireshark_udp_pkt_header;
wireshark_udp_pkt_header.pcap_pkt_header = pcap_pkt_header_s;
wireshark_udp_pkt_header.l2l3UDP_header.ethernet_header = ethernet_header_s;
wireshark_udp_pkt_header.l2l3UDP_header.ip_header = ip_header_s;
wireshark_udp_pkt_header.l2l3UDP_header.udp_header = udp_header_s;
fwrite(&pcap_global_header_s, sizeof(PCAP_GLOBAL_HEADER), 1, mpFile);
fwrite(&wireshark_udp_pkt_header, sizeof(WIRESHARK_UDP_PKT_HEADER), 1, mpFile);
fwrite(pucBytes, ulNofBytes, 1, mpFile);
}
else if (eProtocolType == E_TCP)
{
//TCP Header
}
答案 0 :(得分:0)
IP和UDP,与许多其他网络协议一样,都使用大端字节顺序。由于您可能在使用ip_header_s.ip_len
和udp_header_s.length
编写的little-endian机器值上运行此代码,因此不正确。您应该使用htons
函数将短值从主机转换为网络字节顺序。
ip_header_s.ip_len = htons((uint16_t)(ulNofBytes + sizeof(UDP_HEADER) + sizeof(IP_HEADER)));
除了字节顺序之外,您还可以通过检查结构的实际大小并消除幻数来改进代码。你的代码也是用C语言编写的,你为什么要添加C ++标签?