您的位置:首页 > 编程语言 > C语言/C++

C++解析与生成PCAP抓包数据

2014-04-16 10:40 519 查看
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <time.h>
#include <WinSock2.h>
#include <io.h>
typedef unsigned int  bpf_u_int32;
typedef unsigned short u_short;
typedef int    bpf_int32;
typedef unsigned char  u_int8_t;
typedef unsigned short int u_int16_t;
typedef unsigned int  u_int32_t;
typedef struct pcap_file_header
{
bpf_u_int32 magic;
u_short version_major;
u_short version_minor;
bpf_int32 thiszone;
bpf_u_int32 sigfigs;
bpf_u_int32 snaplen;
bpf_u_int32 linktype;
} pcap_file_header;
typedef struct timestamp
{
bpf_u_int32 timestamp_s;
bpf_u_int32 timestamp_ms;
} timestamp;
typedef struct pcap_header
{
timestamp ts;
bpf_u_int32 capture_len;
bpf_u_int32 len;
} pcap_header;
typedef struct ether_header
{
u_int8_t ether_dhost[6];        //destination mac address
u_int8_t ether_shost[6]; //source mac address
u_int16_t ether_type;  //ethernet type
} ether_header;

typedef struct ip_hdr
{
#if LITTLE_ENDIAN
u_int8_t    ihl:4; //
u_int8_t    version:4; //version
#else
u_int8_t    version:4;
u_int8_t    ihr:4;
#endif

u_int8_t      tos;  //service type
u_int16_t     tos_len; //total len
u_int16_t     id;  //
u_int16_t     frag_off; //offset
u_int8_t      ttl;  //live time
u_int8_t      protocol; //
u_int16_t     chk_sum; //check sum
struct in_addr    srcaddr; //source ip
struct in_addr    dstaddr; //destnation ip
} ip_hdr;
//total length : 20Bytes
typedef struct tcp_hdr
{
u_int16_t     src_port;  //source port
u_int16_t     dst_port;  //destination port
u_int32_t     seq_no;  //
u_int32_t     ack_no;  //

u_int8_t      reserved_1:4;
u_int8_t      th1:4;  //tcp header length
u_int8_t      flag:6;
u_int8_t      reserverd_2:2;
u_int16_t     wnd_size;  //16 bit windows
u_int16_t     chk_sum;  //16 bits check sum
u_int16_t     urgt_p;  //16 urgent p
} tcp_hdr;
//total length :8 Bytes
typedef struct udp_hdr
{
u_int16_t src_port;
u_int16_t dst_port;
u_int16_t uh1;
u_int16_t chk_sum;
} udp_hdr;
typedef struct raw_data_pcap
{
u_int8_t   hostname[20];
u_int8_t   *timestamp;
u_int8_t   src_mac[6];
u_int8_t   dst_mac[6];
u_int16_t  NetL_type;

u_int8_t   src_IP[4];
u_int8_t   dst_IP[4];
u_int8_t   TransL_type;
u_int16_t  src_port;
u_int16_t  dst_port;

u_int8_t   *data;
} raw_data_pcap;
typedef struct pcap_ip_data_hdr_s {
ip_hdr __hdr__;
u_int32_t length;
} pcap_ip_data_hdr;
#define PCAP_IPDATA_HDR(obj) ((pcap_ip_data_hdr*)obj)
#define PCAP_IPHEADER(obj) ((ip_hdr*)obj)
typedef struct pcap_ip_raw_data_s {
pcap_ip_data_hdr __hdr__;
u_int8_t* data;
} pcap_ip_raw_data;
typedef struct pcap_raw_data_s {
u_int8_t length;
u_int8_t* data;
} pcap_raw_data;
typedef struct pcap_tcp_data_s {
pcap_ip_data_hdr __hdr__;
tcp_hdr hdr;
u_int8_t* data;
} pcap_tcp_data;
typedef struct pcap_udp_data_s {
pcap_ip_data_hdr __hdr__;
udp_hdr hdr;
u_int8_t* data;
} pcap_udp_data;
typedef struct pcap_link_s {
pcap_header pcaphdr;
ether_header etherhdr;
void* data;
struct pcap_link_s* next;
} pcap_link;
typedef struct pcap_s {
pcap_file_header fhdr;
pcap_link* link;
} pcap_data;
void free_pcap(pcap_data** pcap);
typedef enum pcap_result_s {
PARSE_SUCCESS,
PARSE_ERROR,
} pcap_result;
pcap_result parse_pcap(const char* fname,pcap_data**pcap)  ;
pcap_result parse_pcap(const char* fname,pcap_data**pcap) {
pcap_link* link=NULL;
pcap_result result=PARSE_SUCCESS;
ip_hdr iphdr;
FILE* pRead = fopen(fname, "rb");
long fsize=0;
long foffset=0;

if(!pRead) {
result=PARSE_ERROR;
goto Fail;
}

*pcap=(pcap_data*)calloc(1,sizeof(pcap_data));
fseek(pRead,0,SEEK_END);
fsize=ftell(pRead);
fseek(pRead,0,SEEK_SET);

if(sizeof(pcap_file_header)!=fread(&(*pcap)->fhdr, 1, sizeof(pcap_file_header), pRead)) {
result=PARSE_ERROR;
free_pcap(pcap);
goto Fail;
}

while((fsize-(foffset=ftell(pRead)))) {
u_int16_t ether_type=0;

if(!link) {
link=(pcap_link*)calloc(1,sizeof(pcap_link));
(*pcap)->link=link;

} else {
link->next=(pcap_link*)calloc(1,sizeof(pcap_link));
link=link->next;
}

if(sizeof(pcap_header)!=fread(&link->pcaphdr,1,sizeof(pcap_header),pRead)) {
result=PARSE_ERROR;
free_pcap(pcap);
goto Fail;
}

if(sizeof(ether_header)!=fread(&link->etherhdr,1,sizeof(ether_header),pRead)) {
result=PARSE_ERROR;
free_pcap(pcap);
goto Fail;
}

ether_type=ntohs(link->etherhdr.ether_type);

switch(ether_type) {
case 0x0800://ip
if(sizeof(iphdr)!=fread(&iphdr,1,sizeof(iphdr),pRead)) {
result=PARSE_ERROR;
free_pcap(pcap);
goto Fail;
}

switch(iphdr.protocol) {
case 6://tcp
{
// tcp_hdr tcphdr;
pcap_tcp_data* tcpData=(pcap_tcp_data*)calloc(1,sizeof(pcap_tcp_data));
PCAP_IPDATA_HDR(tcpData)->length= link->pcaphdr.capture_len-sizeof(ether_header)-sizeof(ip_hdr)-sizeof(tcp_hdr);
*PCAP_IPHEADER(tcpData)=iphdr;

if(sizeof(tcp_hdr)!=fread(&tcpData->hdr,1,sizeof(tcp_hdr),pRead)) {
result=PARSE_ERROR;
free_pcap(pcap);
goto Fail;
}

tcpData->data=(u_int8_t*)calloc(1,PCAP_IPDATA_HDR(tcpData)->length);

if(PCAP_IPDATA_HDR(tcpData)->length!=fread(tcpData->data,1,PCAP_IPDATA_HDR(tcpData)->length,pRead)) {
result=PARSE_ERROR;
free_pcap(pcap);
goto Fail;
}

link->data=tcpData;

break;
}

case 17://udp
{
pcap_udp_data* udpData=(pcap_udp_data*)calloc(1,sizeof(pcap_udp_data));
PCAP_IPDATA_HDR(udpData)->length= link->pcaphdr.capture_len-sizeof(ether_header)-sizeof(ip_hdr)-sizeof(udp_hdr);
*PCAP_IPHEADER(udpData)=iphdr;

if(sizeof(udp_hdr)!=fread(&udpData->hdr,1,sizeof(udp_hdr),pRead)) {
result=PARSE_ERROR;
free_pcap(pcap);
goto Fail;
}

udpData->data=(u_int8_t*)calloc(1,udpData->__hdr__.length);

if(PCAP_IPDATA_HDR(udpData)->length!=fread(udpData->data,1,PCAP_IPDATA_HDR(udpData)->length,pRead)) {
result=PARSE_ERROR;
free_pcap(pcap);
goto Fail;
}

link->data=udpData;
}
break;

default:
{
pcap_ip_raw_data* rawData=(pcap_ip_raw_data*)calloc(1,sizeof(pcap_ip_raw_data));
PCAP_IPDATA_HDR(rawData)->length=link->pcaphdr.capture_len-sizeof(ether_header)-sizeof(ip_hdr);
*PCAP_IPHEADER(rawData)=iphdr;

if(PCAP_IPDATA_HDR(rawData)->length!=fread(rawData->data,1,PCAP_IPDATA_HDR(rawData)->length,pRead)) {
result=PARSE_ERROR;
free_pcap(pcap);
goto Fail;
}
}
break;
}

break;

default:
{
pcap_raw_data* rawData=(pcap_raw_data*)calloc(1,sizeof(pcap_raw_data));
rawData->length=link->pcaphdr.capture_len-sizeof(ether_header);
rawData->data=(u_int8_t*)calloc(1,rawData->length);

if(rawData->length!=fread(rawData->data,1,rawData->length,pRead)) {
result=PARSE_ERROR;
free_pcap(pcap);
goto Fail;
}

link->data=rawData;
}
break;
}
}

Fail:

if(pRead) {
fclose(pRead);
}

return result;
}
void free_pcap(pcap_data** pcap) {
pcap_link* link=NULL;
pcap_link* prv=NULL;
link=(*pcap)->link;

while(link) {
int ether_type;
ether_type=ntohs(link->etherhdr.ether_type);

switch(ether_type) {
case 0x0800:
{
switch(PCAP_IPDATA_HDR(link->data)->__hdr__.protocol)
{
case 6://tcp
{
pcap_tcp_data* tcpData=(pcap_tcp_data*)link->data;
free(tcpData->data),tcpData->data=NULL;
free(tcpData),link->data=NULL;
}
break;

case 17://udp
{
pcap_udp_data* udpData=(pcap_udp_data*)link->data;
free(udpData->data),udpData->data=NULL;
free(udpData),link->data=NULL;

}
break;

default:
{
pcap_ip_raw_data* rawData=(pcap_ip_raw_data*)link->data;
free(rawData->data),rawData->data=NULL;
free(rawData),link->data=NULL;
}
break;
}
}
break;

default:
{
pcap_raw_data* rawData=(pcap_raw_data*)link->data;
free(rawData->data),rawData->data=NULL;
free(rawData),link->data=NULL;
}
break;
}

prv=link;
link=link->next;
free(prv);
(*pcap)->link=link;
}

free(*pcap);
*pcap=NULL;
}
int main()
{
const char* readfile="C:/111.pcap";
const char* writefile="C:/111_2.pcap";
pcap_data* pcap=NULL;
pcap_link* link=NULL;
FILE* pWrite = NULL;
if(PARSE_SUCCESS!=parse_pcap(readfile,&pcap))
{
printf("parse pcap file error.");
goto OVER;
}
pWrite=fopen(writefile, "wb");
if(!pWrite){
printf("con't create write file:%s",writefile);
goto OVER;
}
link=pcap->link;
fwrite(&pcap->fhdr, 1, sizeof(pcap_file_header), pWrite);

while(link) {
int ether_type;
fwrite(&link->pcaphdr, 1, sizeof(pcap_header), pWrite);
fwrite(&link->etherhdr, 1, sizeof(ether_header), pWrite);
ether_type=ntohs(link->etherhdr.ether_type);

switch(ether_type) {
case 0x0800:
fwrite(&PCAP_IPDATA_HDR(link->data)->__hdr__, 1, sizeof(ip_hdr), pWrite);

switch(PCAP_IPDATA_HDR(link->data)->__hdr__.protocol) {
case 6://tcp
{
pcap_tcp_data* tcpData=(pcap_tcp_data*)link->data;
fwrite(&tcpData->hdr, 1, sizeof(tcp_hdr), pWrite);
fwrite(tcpData->data, 1, PCAP_IPDATA_HDR(tcpData)->length, pWrite);
}
break;

case 17://udp
{
pcap_udp_data* udpData=(pcap_udp_data*)link->data;
fwrite(&udpData->hdr, 1, sizeof(udp_hdr), pWrite);
fwrite(udpData->data, 1, PCAP_IPDATA_HDR(udpData)->length, pWrite);

}
break;

default:
{
pcap_ip_raw_data* rawData=(pcap_ip_raw_data*)link->data;
fwrite(rawData->data, 1, PCAP_IPDATA_HDR(rawData)->length, pWrite);
}
break;
}

break;

default:
{
pcap_raw_data* rawData=(pcap_raw_data*)link->data;
fwrite(rawData->data, 1, rawData->length, pWrite);
}
break;
}

link=link->next;
}
OVER:
if(pWrite) fclose(pWrite);
if(pcap) free_pcap(&pcap);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: