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

1 篇文章 0 订阅
1 篇文章 0 订阅
#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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值