赞
踩
本文大部分内容均参考 http://imzc.net/archives/181/%E8%A7%A3%E6%9E%90pcap%E6%96%87%E4%BB%B6%E5%8F%8A%E6%BA%90%E7%A0%81/,原文有少量错误,已修改。
下面pcap文件格式介绍是在网上转的,根据理解,写了个程序来进行解析pcap文件,后续再实现合并pcap功能(wireshark已经自带命令行合并pcap文件工具,在这里只是为了分析pcap文件和学习)。
==========================
默认的*.pcap文件保存格式。
Pcap文件头24B各字段说明:
===========================
我的实现:
- // 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;
-
- /*
- Pcap文件头24B各字段说明:
- Magic:4B:0x1A 2B 3C 4D:用来标示文件的开始
- Major:2B,0x02 00:当前文件主要的版本号
- Minor:2B,0x04 00当前文件次要的版本号
- ThisZone:4B当地的标准时间;全零
- SigFigs:4B时间戳的精度;全零
- SnapLen:4B最大的存储长度
- LinkType:4B链路类型
- 常用类型:
- 0 BSD loopback devices, except for later OpenBSD
- 1 Ethernet, and Linux loopback devices
- 6 802.5 Token Ring
- 7 ARCnet
- 8 SLIP
- 9 PPP
- */
- 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;
-
- /*
- Packet包头和Packet数据组成
- 字段说明:
- Timestamp:时间戳高位,精确到seconds
- Timestamp:时间戳低位,精确到microseconds
- Caplen:当前数据区的长度,即抓取到的数据帧长度,由此可以得到下一个数据帧的位置。
- Len:离线数据长度:网络中实际数据帧的长度,一般不大于caplen,多数情况下和Caplen数值相等。
- Packet数据:即 Packet(通常就是链路层的数据帧)具体内容,长度就是Caplen,这个长度的后面,就是当前PCAP文件中存放的下一个Packet数据包,也就 是说:PCAP文件里面并没有规定捕获的Packet数据包之间有什么间隔字符串,下一组数据在文件中的起始位置。我们需要靠第一个Packet包确定。
- */
-
- 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 <stdio.h>
- #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 < 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("%04x",a);
-
-
- }
- /*
- for (iPos=0; iPos <= size/sizeof(int); iPos++) {
- //printf(" %x ",(int)( * (p+iPos) ));
- int a = ntohl(p[iPos]);
-
- //int a = ntohl( *((int *)data + iPos ) );
- if (iPos %4==0) printf("\n");
-
- printf("%08x ",a);
-
-
- }
- */
- printf("\n============\n");
- }
- //
- // main.c
- // pcaptest
- //
- // Created by zc on 12-1-24.
- // Copyright 2012年 __MyCompanyName__. All rights reserved.
- //
-
- #include <stdio.h>
- #include <arpa/inet.h>
- #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, "rb");
-
- 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;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。