假设我们有一个包含数据包信息的XML文件
<packet>
<frame_type>Ethernet</frame_type>
<local_mac_address>00-21-85-11-29-1b</local_mac_address>
<remote_mac_address>ff-ff-ff-ff-ff</remote_mac_address>
<protocol>IP</protocol>
<version>4</version>
<local_address>147.175.106.141</local_address>
<remote_address>255.255.255.255</remote_address>
<protocol_type>UDP</protocol_type>
<protocol>UDP</protocol>
<local_port>17500</local_port>
<remote_port>17500</remote_port>
<service_name></service_name>
<packets>8</packets>
</packet>
我可以使用pugiXML或其他一些XML解析器轻松解析这个问题。
使用纯C ++生成此类数据包的方法是什么(以正确的顺序获取数据包信息)并使用pcap.h中声明的函数将其保存到wireshark可读的文件中?
pcap_dump(dumpfile, header, pkt_data);
u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data;
我如何使用纯C ++ 填充pkt_data
和header
?
struct pcap_pkthdr {
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
};
我应该在ts
,caplen
,len
设置数据示例吗?
修改
经过一段时间的谷歌搜索后,我在SO上发现了这个thread。
所以我使用这些结构来填充我的以太网 - &gt; IP - &gt; TCP包如下:
我不熟悉uint16_t,uint8_t等类型。
pcap_hdr_t pcaphdr;
pcaphdr.magic_number = 0xd4c3b2a1; //0xa1b2c3d4 || 0xd4c3b2a1 <- i am on winwows (Little endian)
pcaphdr.sigfigs = 0;
pcaphdr.version_major = 2;
pcaphdr.version_minor = 4;
pcaphdr.snaplen = 65536;
pcaphdr.thiszone = 0;
pcaphdr.network = DLT_EN10MB;
ethernet_hdr_t ethernethdr;
ethernethdr.dst = ??; // I have no clue how to fill this either ...dst[0] = 0xFF? type is uint8_t.
ethernethdr.src = ??;//same as above
ethernethdr.type = 2048; //? //(I want to use IP = 0x800), it is uint16_t
//and for IP
ip_hdr_t ipp;
ipp.ip_dst = parseIPV4string(ipAddressString); //this function converts string into uint32_t
ipp.ip_src = parseIPV4string(ipAddressString);
ipp.ip_v = 4; //version
ipp.ip_hl = 20; //header length
ipp.ip_id = 12758; //id whatever id
ipp.ip_ttl = 125; //time to live
ipp.ip_p = 6; //protocol 6 = TCP
ipp.ip_off = 0;
ipp.ip_tos = 0;
//and save all this by
FILE *ptr_myfile;
ptr_myfile=fopen("test.pcap", "wb");
if (!ptr_myfile)
{
printf("Unable to open file!");
return 1;
}
fwrite(&pcaphdr, 1, sizeof(pcap_hdr_t), ptr_myfile);
fwrite(ðernethdr, 1, sizeof(ethernet_hdr_t), ptr_myfile);
fwrite(&ipp, 1, sizeof(ip_hdr_t), ptr_myfile);
fclose(ptr_myfile);
我不打算创建带有效载荷(数据)的数据包,我试图在没有数据的情况下接近纯数据包+在wireshark中检查此数据包。
答案 0 :(得分:2)
你真的不需要pcap_dump,你可以自己打开文件并写信给它。
示例pcap文件头,每个文件开头一次
struct pcap_file_header fh;
fh.magic = TCPDUMP_MAGIC;
fh.sigfigs = 0;
fh.version_major = 2;
fh.version_minor = 4;
fh.snaplen = USHRT_MAX;
fh.thiszone = 0;
fh.linktype = LINKTYPE_ETHERNET;
fwrite(&fh, sizeof(fh), 1, file);
示例pcap数据包标头,每个数据包一次
struct pcap_pkthdr pkhdr;
pkhdr.len = pkhdr.caplen = your_content_length;
pkhdr.ts.tv_sec = 1396306094; // Some unix timestamp
fwrite(&pkhdr, sizeof(pkhdr), 1, file);
fwrite(your_binary_packet, your_content_length, 1, file)
对要写入的每个数据包重复此操作
如果你想使用pcap_dump,第一个参数是pcap_dump_open返回的值,标题与上面的pkhdr相同,pkt_data是你的二进制数据,那个数据的长度应该与你指定的pkhdr.len匹配。要让pkt_data指向有意义的东西,请将您拥有的任何数据转换为二进制数据。
编辑: 您似乎没有在示例中的任何位置写入pcap文件头。此外,您还需要阅读有关您正在使用的协议的更多信息。我假设你有理由使用DLT_EN10MB而不是LINKTYPE_ETHERNET。我不熟悉前者。
对于ethernet dst / src,只需填写0进行测试。我假设您稍后想要转换XML中的内容。
ip_hl是32位字的数字,而不是字节,所以20 = 5。您也没有指定ip_len,它是IP头+数据的总字节数。如果您想通过只有一个以太网+ IP标头并且没有其他数据用于测试目的,可以将其保留为20.使用htons()函数。为了正确起见,您最终也想要计算IP校验和。
for x86想到uint16_t = unsigned short,uint8_t = unsigned char