当前位置:   article > 正文

pcap文件格式介绍、解析以及读取(c/c++)_c++ pcap文件读取

c++ pcap文件读取

本文大部分内容均参考 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各字段说明:

Magic:4B:0xA1 B2 C3 D4:用来标示文件的开始
Major:2B,0×02 00:当前文件主要的版本号
Minor:2B,0×04 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
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数据部分的格式其实就是标准的网路协议格式了可以任何网络教材上找得到。

===========================

我的实现:

  1. // pcap.h
  2. // pcaptest
  3. //
  4. // Created by zc on 12-1-24.
  5. // Copyright 2012年 __MyCompanyName__. All rights reserved.
  6. //
  7. #ifndef pcaptest_pcap_h
  8. #define pcaptest_pcap_h
  9. typedef unsigned int bpf_u_int32;
  10. typedef unsigned short u_short;
  11. typedef int bpf_int32;
  12. /*
  13. Pcap文件头24B各字段说明:
  14. Magic:4B:0x1A 2B 3C 4D:用来标示文件的开始
  15. Major:2B,0x02 00:当前文件主要的版本号
  16. Minor:2B,0x04 00当前文件次要的版本号
  17. ThisZone:4B当地的标准时间;全零
  18. SigFigs:4B时间戳的精度;全零
  19. SnapLen:4B最大的存储长度
  20. LinkType:4B链路类型
  21. 常用类型:
  22. 0 BSD loopback devices, except for later OpenBSD
  23. 1 Ethernet, and Linux loopback devices
  24. 6 802.5 Token Ring
  25. 7 ARCnet
  26. 8 SLIP
  27. 9 PPP
  28. */
  29. typedef struct pcap_file_header {
  30. bpf_u_int32 magic;
  31. u_short version_major;
  32. u_short version_minor;
  33. bpf_int32 thiszone;
  34. bpf_u_int32 sigfigs;
  35. bpf_u_int32 snaplen;
  36. bpf_u_int32 linktype;
  37. }pcap_file_header;
  38. /*
  39. Packet包头和Packet数据组成
  40. 字段说明:
  41. Timestamp:时间戳高位,精确到seconds
  42. Timestamp:时间戳低位,精确到microseconds
  43. Caplen:当前数据区的长度,即抓取到的数据帧长度,由此可以得到下一个数据帧的位置。
  44. Len:离线数据长度:网络中实际数据帧的长度,一般不大于caplen,多数情况下和Caplen数值相等。
  45. Packet数据:即 Packet(通常就是链路层的数据帧)具体内容,长度就是Caplen,这个长度的后面,就是当前PCAP文件中存放的下一个Packet数据包,也就 是说:PCAP文件里面并没有规定捕获的Packet数据包之间有什么间隔字符串,下一组数据在文件中的起始位置。我们需要靠第一个Packet包确定。
  46. */
  47. typedef struct timestamp{
  48. bpf_u_int32 timestamp_s;
  49. bpf_u_int32 timestamp_ms;
  50. }timestamp;
  51. typedef struct pcap_header{
  52. timestamp ts;
  53. bpf_u_int32 capture_len;
  54. bpf_u_int32 len;
  55. }pcap_header;
  56. void prinfPcapFileHeader(pcap_file_header *pfh);
  57. void printfPcapHeader(pcap_header *ph);
  58. void printPcap(void * data,size_t size);
  59. #endif


  1. //
  2. // pcap.c
  3. // pcaptest
  4. //
  5. // Created by zc on 12-1-24.
  6. // Copyright 2012年 __MyCompanyName__. All rights reserved.
  7. //
  8. #include <stdio.h>
  9. #include "pcap.h"
  10. void prinfPcapFileHeader(pcap_file_header *pfh){
  11. if (pfh==NULL) {
  12. return;
  13. }
  14. printf("=====================\n"
  15. "magic:0x%0x\n"
  16. "version_major:%u\n"
  17. "version_minor:%u\n"
  18. "thiszone:%d\n"
  19. "sigfigs:%u\n"
  20. "snaplen:%u\n"
  21. "linktype:%u\n"
  22. "=====================\n",
  23. pfh->magic,
  24. pfh->version_major,
  25. pfh->version_minor,
  26. pfh->thiszone,
  27. pfh->sigfigs,
  28. pfh->snaplen,
  29. pfh->linktype);
  30. }
  31. void printfPcapHeader(pcap_header *ph){
  32. if (ph==NULL) {
  33. return;
  34. }
  35. printf("=====================\n"
  36. "ts.timestamp_s:%u\n"
  37. "ts.timestamp_ms:%u\n"
  38. "capture_len:%u\n"
  39. "len:%d\n"
  40. "=====================\n",
  41. ph->ts.timestamp_s,
  42. ph->ts.timestamp_ms,
  43. ph->capture_len,
  44. ph->len);
  45. }
  46. void printPcap(void * data,size_t size){
  47. unsigned short iPos = 0;
  48. //int * p = (int *)data;
  49. //unsigned short* p = (unsigned short *)data;
  50. if (data==NULL) {
  51. return;
  52. }
  53. printf("\n==data:0x%x,len:%lu=========",data,size);
  54. for (iPos=0; iPos < size/sizeof(unsigned short); iPos++) {
  55. //printf(" %x ",(int)( * (p+iPos) ));
  56. //unsigned short a = ntohs(p[iPos]);
  57. unsigned short a = ntohs( *((unsigned short *)data + iPos ) );
  58. if (iPos%8==0) printf("\n");
  59. if (iPos%4==0) printf(" ");
  60. printf("%04x",a);
  61. }
  62. /*
  63. for (iPos=0; iPos <= size/sizeof(int); iPos++) {
  64. //printf(" %x ",(int)( * (p+iPos) ));
  65. int a = ntohl(p[iPos]);
  66. //int a = ntohl( *((int *)data + iPos ) );
  67. if (iPos %4==0) printf("\n");
  68. printf("%08x ",a);
  69. }
  70. */
  71. printf("\n============\n");
  72. }


  1. //
  2. // main.c
  3. // pcaptest
  4. //
  5. // Created by zc on 12-1-24.
  6. // Copyright 2012年 __MyCompanyName__. All rights reserved.
  7. //
  8. #include <stdio.h>
  9. #include <arpa/inet.h>
  10. #include "pcap.h"
  11. #define PCAP_FILE "ping.pcap"
  12. #define MAX_ETH_FRAME 1514
  13. #define ERROR_FILE_OPEN_FAILED -1
  14. #define ERROR_MEM_ALLOC_FAILED -2
  15. #define ERROR_PCAP_PARSE_FAILED -3
  16. int main (int argc, const char * argv[])
  17. {
  18. printf("sizeof:int %lu,unsigned int %lu,char %lu,unsigned char %lu,short:%lu,unsigned short:%lu\n",
  19. sizeof(int),sizeof(unsigned int),sizeof(char),sizeof(unsigned char),sizeof(short),sizeof(unsigned short));
  20. pcap_file_header pfh;
  21. pcap_header ph;
  22. int count=0;
  23. void * buff = NULL;
  24. int readSize=0;
  25. int ret = 0;
  26. FILE *fp = fopen(PCAP_FILE, "rb");
  27. if (fp==NULL) {
  28. fprintf(stderr, "Open file %s error.",PCAP_FILE);
  29. ret = ERROR_FILE_OPEN_FAILED;
  30. goto ERROR;
  31. }
  32. fread(&pfh, sizeof(pcap_file_header), 1, fp);
  33. prinfPcapFileHeader(&pfh);
  34. //fseek(fp, 0, sizeof(pcap_file_header));
  35. buff = (void *)malloc(MAX_ETH_FRAME);
  36. for (count=1; ; count++) {
  37. memset(buff,0,MAX_ETH_FRAME);
  38. //read pcap header to get a packet
  39. //get only a pcap head count .
  40. readSize=fread(&ph, sizeof(pcap_header), 1, fp);
  41. if (readSize<=0) {
  42. break;
  43. }
  44. printfPcapHeader(&ph);
  45. if (buff==NULL) {
  46. fprintf(stderr, "malloc memory failed.\n");
  47. ret = ERROR_MEM_ALLOC_FAILED;
  48. goto ERROR;
  49. }
  50. //get a packet contents.
  51. //read ph.capture_len bytes.
  52. readSize=fread(buff,1,ph.capture_len, fp);
  53. if (readSize != ph.capture_len) {
  54. free(buff);
  55. fprintf(stderr, "pcap file parse error.\n");
  56. ret = ERROR_PCAP_PARSE_FAILED;
  57. goto ERROR;
  58. }
  59. printPcap(buff, ph.capture_len);
  60. printf("===count:%d,readSize:%d===\n",count,readSize);
  61. if (feof(fp) || readSize <=0 ) {
  62. break;
  63. }
  64. }
  65. ERROR:
  66. //free
  67. if (buff) {
  68. free(buff);
  69. buff=NULL;
  70. }
  71. if (fp) {
  72. fclose(fp);
  73. fp=NULL;
  74. }
  75. return ret;
  76. }





声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/162434
推荐阅读
相关标签
  

闽ICP备14008679号