解析pcap文件及读取实现源码

下面pcap文件格式介绍是在网上转的,根据理解,写了个程序来进行解析pcap文件,后续再实现合并pcap功能(wireshark已经自带命令行合并pcap文件工具,在这里只是为了分析pcap文件和学习)。
==========================
默认的*.pcap文件保存格式。

Pcap文件头24B各字段说明:

Magic:4B:0x1A 2B 3C 4D:用来标示文件的开始
Major:2B,0×02 00:当前文件主要的版本号
Minor:2B,0×04 00当前文件次要的版本号
ThisZone:4B当地的标准时间;全零
SigFigs:4B时间戳的精度;全零
SnapLen:4B最大的存储长度
LinkType:4B链路类型
常用类型:
           BSD loopback devices, except for later OpenBSD
           Ethernet, and Linux loopback devices
           802.5 Token Ring
           ARCnet
           SLIP
           PPP
10           FDDI
100         LLC/SNAP-encapsulated ATM
101         “raw IP”, with no link
102         BSD/OS SLIP
103         BSD/OS PPP
104         Cisco HDLC
105         802.11
108         later OpenBSD loopback devices (with the AF_value in network byte order)
113         special Linux “cooked” capture
114         LocalTalk
Packet 包头和Packet数据组成
字段说明:
Timestamp:时间戳高位,精确到seconds
Timestamp:时间戳低位,精确到microseconds
Caplen:当前数据区的长度,即抓取到的数据帧长度,由此可以得到下一个数据帧的位置。
Len:离线数据长度网络中实际数据帧的长度,一般不大于caplen,多数情况下和Caplen数值相等。
Packet 数据: 即 Packet(通常就是链路层的数据帧)具体内容,长度就是Caplen,这个长度的后面,就是当前PCAP文件中存放的下一个Packet数据包,也就 是说:PCAP文件里面并没有规定捕获的Packet数据包之间有什么间隔字符串,下一组数据在文件中的起始位置。我们需要靠第一个Packet包确定。 最后,Packet数据部分的格式其实就是标准的网路协议格式了可以任何网络教材上找得到。
//
//  pcap.h
//  pcaptest
//
//  Created by zc on 12-1-24.
//  Copyright 2012年 __MyCompanyName__. All rights reserved.
//
 
#ifndef pcaptest_pcap_h
#define pcaptest_pcap_h
 
typedef unsigned int  bpf_u_int32;
typedef unsigned short  u_short;
typedef int bpf_int32;
 

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;
 
 
void prinfPcapFileHeader(pcap_file_header *pfh);
void printfPcapHeader(pcap_header *ph);
void printPcap(void * data,size_t size);
 
#endif

//
//  pcap.c
//  pcaptest
//
//  Created by zc on 12-1-24.
//  Copyright 2012年 __MyCompanyName__. All rights reserved.
//
 
#include 
#include "pcap.h"
 
void prinfPcapFileHeader(pcap_file_header *pfh){
        if (pfh==NULL) {
                return;
        }
        printf("=====================\n"
                   "magic:0x%0x\n"
                   "version_major:%u\n"
                   "version_minor:%u\n"
                   "thiszone:%d\n"
                   "sigfigs:%u\n"
                   "snaplen:%u\n"
                   "linktype:%u\n"
                   "=====================\n",
                   pfh->magic,
                   pfh->version_major,
                   pfh->version_minor,
                   pfh->thiszone,
                   pfh->sigfigs,
                   pfh->snaplen,
                   pfh->linktype);
}
 
void printfPcapHeader(pcap_header *ph){
        if (ph==NULL) {
                return;
        }
        printf("=====================\n"
                   "ts.timestamp_s:%u\n"
                   "ts.timestamp_ms:%u\n"
                   "capture_len:%u\n"
                   "len:%d\n"
                   "=====================\n",
                   ph->ts.timestamp_s,
                   ph->ts.timestamp_ms,
                   ph->capture_len,
                   ph->len);
 
 
}
 
void printPcap(void * data,size_t size){
        unsigned  short iPos = 0;
        //int * p = (int *)data;
        //unsigned short* p = (unsigned short *)data;
        if (data==NULL) {
                return;
        }
 
        printf("\n==data:0x%x,len:%lu=========",data,size);
 
        for (iPos=0; iPos <</span> size/sizeof(unsigned short); iPos++) {
                //printf(" %x ",(int)( * (p+iPos) ));
                //unsigned short a = ntohs(p[iPos]);
 
                unsigned short a = ntohs( *((unsigned short *)data + iPos ) );
                if (iPos%8==0) printf("\n");
                if (iPos%4==0) printf(" ");
 
                printf("x",a);
 
 
        }
        
        printf("\n============\n");
}

//
//  main.c
//  pcaptest
//
//  Created by zc on 12-1-24.
//  Copyright 2012年 __MyCompanyName__. All rights reserved.
//
 
#include 
#include 
#include "pcap.h"
 
#define PCAP_FILE "ping.pcap"
#define MAX_ETH_FRAME 1514
#define ERROR_FILE_OPEN_FAILED -1
#define ERROR_MEM_ALLOC_FAILED -2
#define ERROR_PCAP_PARSE_FAILED -3
 
 
int main (int argc, const char * argv[])
{
 
        printf("sizeof:int %lu,unsigned int %lu,char %lu,unsigned char %lu,short:%lu,unsigned short:%lu\n",
                    sizeof(int),sizeof(unsigned int),sizeof(char),sizeof(unsigned char),sizeof(short),sizeof(unsigned short));
 
        pcap_file_header  pfh;
        pcap_header  ph;
        int count=0;
        void * buff = NULL;
        int readSize=0;
        int ret = 0;
 
        FILE *fp = fopen(PCAP_FILE, "rw");
 
        if (fp==NULL) {
                fprintf(stderr, "Open file %s error.",PCAP_FILE);
                ret = ERROR_FILE_OPEN_FAILED;
                goto ERROR;
        }
 
        fread(&pfh, sizeof(pcap_file_header), 1, fp);   
        prinfPcapFileHeader(&pfh);
        //fseek(fp, 0, sizeof(pcap_file_header));
 
        buff = (void *)malloc(MAX_ETH_FRAME);
        for (count=1; ; count++) {
                memset(buff,0,MAX_ETH_FRAME);
                //read pcap header to get a packet
                //get only a pcap head count .
                readSize=fread(&ph, sizeof(pcap_header), 1, fp);
                if (readSize<=0) {
                        break;
                }
                printfPcapHeader(&ph);
 
 
                if (buff==NULL) {
                        fprintf(stderr, "malloc memory failed.\n");
                        ret = ERROR_MEM_ALLOC_FAILED;
                        goto ERROR;
                }
 
                //get a packet contents.
                //read ph.capture_len bytes.
                readSize=fread(buff,1,ph.capture_len, fp);
                if (readSize != ph.capture_len) {
                        free(buff);
                        fprintf(stderr, "pcap file parse error.\n");
                        ret = ERROR_PCAP_PARSE_FAILED;
                        goto ERROR;
                }
                printPcap(buff, ph.capture_len);
 
 
                printf("===count:%d,readSize:%d===\n",count,readSize);
 
                if (feof(fp) || readSize <=0 ) { 
                        break;
                }
        }
 
ERROR:
        //free
        if (buff) {
                free(buff);
                buff=NULL;
        } 
        if (fp) {
                fclose(fp);
                fp=NULL;
        }       
 
    return ret;
}



#########################功能说明################## pcapedit 程序可对pcap报文进行报文过滤,剥离部分包头及打标签功能。 支持通过pcap.conf配置文件设置标签内容及长度。 程序启动时,会导入配置文件中的标签内容,之后会将pcap包中的每个数据包末尾都打上该标签。标签内容填充不足,自动补0. ################################################## *************************可处理报文格式说明******** 可处理的报文格式需如下:ETH格式 --》ipv4 --> udp --> gtp_2152 --> ipv4 -->tcp -->http 剥离特殊包头后的帧格式:ETH格式 --》ipv4 --> tcp -->http *************************************************** @@@@@@@@@@@@@@@@@@@@@@@@@使用说明@@@@@@@@@@@@@@@@@ 将pcapedit 和 配置文件放到用一路径下,处理处的结果文件保存在当前路径。 [root@localhost cll]# ./pcapedit Input the pcap file name:3g_ctrl_data.pcap //符合帧格式的pcap文件处理结果 starting parse pcap file... 3g_ctrl_data.pcap input mark success! Input the pcap file name:aagxxx_data.pcap //符合帧格式的pcap文件处理结果 starting parse pcap file... aagxxx_data.pcap input mark success! Input the pcap file name:new3g_user.pcap //不符合帧格式的pcap文件处理结果 starting parse pcap file... cann't find target format packet. new3g_user.pcap input mark fail! Input the pcap file name:exit //exit 退出程序 [root@localhost cll]# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值