C++ 使用<;pcap.h>;

C++ 使用<;pcap.h>;,c++,pcap,C++,Pcap,假设我们有一个包含数据包信息的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> <protoco

假设我们有一个包含数据包信息的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>
u_char*dumpfile,const struct pcap_pkthdr*头,const u_char*pkt_数据

< >我如何假设使用纯C++( >/p>填充>代码> pktl数据< /COD>和<代码>头<代码> >
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
的数据示例


编辑

所以在谷歌搜索了一段时间后,我发现了这一点

所以我使用这些结构来填充我的Ethernet->IP->TCP数据包,如下所示

我不熟悉uint16、uint8等类型

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(&ethernethdr, 1, sizeof(ethernet_hdr_t), ptr_myfile);
fwrite(&ipp, 1, sizeof(ip_hdr_t), ptr_myfile);
fclose(ptr_myfile);
pcap\u hdr\t pcaphdr;

pcaphdr.magic_编号=0xd4c3b2a1//0xa1b2c3d4 | | 0xd4c3b2a1您实际上不需要pcap_转储,您只需自己打开文件并写入即可

示例pcap文件头,每个文件在文件开头一次

结构pcap文件头fh;
fh.magic=TCPDUMP\u magic;
fh.sigifigs=0;
fh.version_major=2;
fh.version_minor=4;
fh.snaplen=USHRT_MAX;
fh.thiszone=0;
fh.linktype=linktype\u以太网;
fwrite(&fh,sizeof(fh),1,文件);

样本pcap数据包头,每个数据包一次

结构pcap_pkthdr pkhdr;
pkhdr.len=pkhdr.caplen=您的内容长度;
pkhdr.ts.tv_sec=1396306094;//一些unix时间戳
fwrite(&pkhdr,sizeof(pkhdr),1,文件);
fwrite(你的二进制数据包,你的内容长度,1,文件)
对要写入的每个数据包重复此操作

如果要使用pcap_dump,第一个参数是pcap_dump_open返回的值,标头与上面的pkhdr相同,pkt_数据是二进制数据,该数据的长度应与指定的pkhdr.len匹配。要使pkt_数据指向有意义的内容,请将所有数据转换为二进制

编辑: 在示例中,您似乎没有在任何地方写入pcap文件头。此外,您需要多读一点关于您正在使用的协议的内容。我假设您有理由使用DLT_EN10MB而不是LINKTYPE_以太网。我对前者不熟悉

对于以太网dst/src,只需填写0进行测试。我假设您稍后想要转换XML中的内容

ip_hl是32位字的数量,而不是字节数,因此20=5。您也没有指定ip_len,它是ip头+数据的总字节数。如果您想从一个ethernet+IP报头开始,而不需要额外的数据来进行测试,您可以将其保留在20。使用htons()函数。为了保证正确性,您最终还需要计算IP校验和


对于x86,请考虑uint16\u t=unsigned short,uint8\u t=unsigned char

是否要将XML数据包转换为pcap数据包?除非您的示例中没有显示整个二进制数据/十六进制转储,否则实际上没有足够的信息来这样做。你可以用你得到的信息为Ethernet/IP/UDP创建合成报头,但是UDP部分没有数据,所以它有点毫无意义。我知道没有数据,我试图理解如何将数据包数据放入u_char变量(更多的是C),但总的来说,我试图理解pcap_pkthdr结构的概念(我知道有一个手动文件,但还不清楚)winpcap.org/docs/docs_41b5/html/structpcap____pkthdr.html“Ethernet2”如果每个包都有不同的帧类型,你不能使用pcap,你必须使用pcap-ng。它可以是以太网,也可以是802.3这就是我想要的(现在我放弃了使用
pcap\u dump()
)。您还可以提供“您的二进制数据包”示例吗?假设我将文件保存到test.bin(使用
fwrite(&pkhdr…
),我无法通过wireshark打开文件(因此我可以调试).有什么提示吗?创建\u binary\u数据包完全取决于您如何获得二进制数据,因为您没有显示该示例,我真的无法显示如何转换它。您失败的文件,您是否也编写了pcap文件头?您是如何提供数据的?请参阅编辑。这并不难做到,只是要求您对所做的操作进行精确。我不确定从哪里开始,fh.magic必须是0xa1b2c3d4,否则所有其他成员也必须交换。无论您是否在windows上,wireshark都支持,它只需要保持一致。文件头显示正常。文件中似乎没有有效的数据包头,或者如果您编写了一个,则没有t set caplen=len,但即使读取caplen字节也不起作用,因此它可能会丢失,因为读取头后文件中只剩下12个字节。LINKTYPE_ETHERNET定义为1 btw。
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(&ethernethdr, 1, sizeof(ethernet_hdr_t), ptr_myfile);
fwrite(&ipp, 1, sizeof(ip_hdr_t), ptr_myfile);
fclose(ptr_myfile);