一个关于抓包后文件解析的问题,首先,需要了解pcap文件的结构,通过了解,我定义了一个叫做SomeTypes.h的头文件

 


typedef unsigned int DWORD;

typedef unsigned short WORD;

typedef struct timeval
{
 DWORD GMTtime;
 DWORD microTime;
}timeval;

typedef struct pcap_pkthdr
{
struct timeval         ts;
      DWORD              caplen;
      DWORD              len;
}pacp_pkthdr;
 

typedef struct pcap_file_header
{
DWORD              magic;
      WORD                 version_major;
      WORD                 version_minor;
DWORD              thiszone;
DWORD              sigfigs;
DWORD              snaplen;
DWORD              linktype;
}pcap_file_header;

 

因为是在控制台下写的c语言代码而不是VC下,所以DWORD,WORD类型需要自己定义

 

其次,在MessageAlynasis.cpp中,实现了一下功能:在庞大的pcap文件中,分析出几千条数据包,把这些数据包的大小一一列到控制台,并且把数据包中含有特征字符串“HTTP”的寻找出来,有多少个数据包包含该特征字符串,就把这个数量写到控制台,同时,

,将这些数据包的内容写到ActualChars.txt中。

 

// MessageAlynasis.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdio.h"
#include "string.h"
#include "SomeTypes.h"

bool compareBinary(char *src,char *obj){
 //对于报文中查找特征字符,其实用普通的查找效率已经很好,因为很多都是乱码,所以很少会存在aaab--aaac的情况
 int len_src=strlen(src),len_obj=strlen(obj);
 int flag=0;
 for(int i=0;i<len_src-len_obj+1;i++){
  flag=0;
  for(int j=0;j<len_obj;j++){
   if(*(src+i+j)!=*(obj+j)){
    flag=1;
    break;
   }
  }
  if(flag==1) continue;
  return true;
 }
 return false;
}

//文件输出到控制台
void fileView_test(FILE *fp,int len){
 int i=0;
 printf("start.....\n");
 while(i++<len && !feof(fp)){
  printf("%X ",fgetc(fp));
 }
 printf("end.....\n");
}

//输出字符串中的正常字符到文件中
void printActualChars(char *p,FILE *fp){
 fprintf(fp,"\nthe one has %d words:\n",strlen(p));
 for(int i=0;i<strlen(p);i++){
  while(*p++=='\0' || *p<0 || *p>127) ;
  fprintf(fp,"%c",*p);
 }
 
}

//分析pcap
int pcapAlynasis(FILE *fp){
 int i=0,j=0;
 char ch[10000],*p,c;
 p=ch;
 pcap_pkthdr data_head;
 FILE *fp1=fopen("D:/ActualChars.txt","w");
 FILE *fp0=fopen("D:/AllActualChars.txt","w");
 fseek(fp,sizeof(struct pcap_file_header),0);
 while(!feof(fp)){
  fread(&data_head,sizeof(pcap_pkthdr),1,fp);
  printf("data %d has %d data.\n",i+1,data_head.caplen);
  //fread(ch,data_head.caplen,1,fp);   fread会把\0结束符也读入,这样作为实参是不会把后续的字符串传给形参的
  for(int k=0;k<data_head.caplen;k++){
   if((c=fgetc(fp))!='\0') *p++=c;
  }
  p=ch;
  if(compareBinary(p,"HTTP")){
   j++;
   printActualChars(ch,fp1);
  }
  i++;
  printActualChars(ch,fp0);
 }
 printf("all:%d\nget:%d",i,j);
 return 1;
}

int main(){
 FILE *fp = fopen("D:/emule.pcap","rb");
 pcapAlynasis(fp);
 if(fp == NULL){
  printf("cannot open file.");
  return 0;
 }
 return 1;
 //return pcapAlynasis1(fp);
}

 以上程序通过vc++6.0运行测试,测试机要求:必须有D盘

同时,陆续会把MVC版的程序发来


 

posted on 2011-05-22 22:55  王小涛  阅读(2025)  评论(2编辑  收藏  举报