怎么用C语言读取WireShark捕获的数据包文件,要求能分析出以太网头部,Ip头部,TCP头部,并提取出数据部分,下面是我写的一段代码,但是读的不对,希望高手指点
//.pcap文件
//#ifndef xiaohouzi
//#define xiaohouzi
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN (1)
#include
typedef unsigned int bpf_u_int32;
typedef unsigned short u_short;
typedef int bpf_int32;
typedef unsigned char u_int8_t;
//////////////////////////////
typedef char 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 u_int32_t in_addr_t;
// struct in_addr
//{
// in_addr_t s_addr;
//};
//total length : 20Bytes
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 src_IP; //source ip struct in_addr dst_IP; //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_int8_t seq_no[4];
u_int8_t ack_no[4];
//u_int32_t seq_no; //
//u_int32_t ack_no; //
/*struct in_addr seq_no;
struct in_addr 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_int8_t length;//长度 u_int8_t type;//ACK。FIN…… u_int8_t wnd_size[2]; //16 bit windows u_int16_t chk_sum; //16 bits check sum ack,syn...... u_int16_t urgt_p; //16 urgent p
}tcp_hdr;
//total length :8 Bytes
//#endif
#endif
//.cpp文件
#include"pcap.h"
#include
#include
#include
#include
#include
//#include "C:\Users\Administrator\Desktop\zlib\zlib\src\zlib-1.2.3-src\src\zlib\1.2.3\zlib-1.2.3\zlib.h"
//#pragma comment(lib, "zlib1.lib")
#pragma comment(lib,"ws2_32.lib")
int count=0;
void main(/*int argc,charargv[]/)
{
pcap_headerph=(pcap_header)malloc(sizeof(pcap_header));
ether_header*eh=(ether_header*)malloc(sizeof(ether_header));
ip_hdr * iph=(ip_hdr*)malloc(sizeof(ip_hdr));
tcp_hdrtcph=(tcp_hdr)malloc(sizeof(tcp_hdr));
if(ph==NULL||eh==NULL||iph==NULL||tcph==NULL)
{
printf("内存分配失败\n");
return ;
}
/*打开文件*/
FILEpfile=fopen(/*filename/"1.pcap","rb");
if(pfile==NULL)
{
printf("open file failed!\n");
return ;
}
fseek(pfile,0,SEEK_SET);//将文件指针置于头部
/*跳过文件头*/
if( fseek(pfile,24,SEEK_SET)!=0)
{
printf("文件头跳过失败!\n");
exit(0);
return;
}
/*读取每个数据包进行分析*/
while(!feof(pfile))
{
ZeroMemory(ph,sizeof(pcap_header));
ZeroMemory(eh,sizeof(*eh));
ZeroMemory(iph,sizeof(*iph));
ZeroMemory(tcph,sizeof(*tcph));
count++;//读取的数据包计数
/*读取包头*/
if(!fread(ph,sizeof(pcap_header),1,pfile))
{
printf("读取数据包头失败\n");
break;
}
printf("数据包%d的长度是%d,数据包读取的时间是%f\n",count,ph->capture_len ,ph->ts .timestamp_ms0.001+ph->ts .timestamp_s );
/读取以太网头*/
if(!feof(pfile))
{
if(!fread(eh,sizeof(*eh),1,pfile)/*||eh->ether_type !=0x0800*/)
{
printf("读取以太网头部失败\n");
break;
}
}
printf("源MAC地址是:0x%2x:0x%2x:0x%2x:0x%2x:0x%2x:0x%2x\n",eh->ether_shost[0],eh->ether_shost [1],eh->ether_shost [2],eh->ether_shost [3],eh->ether_shost [4],eh->ether_shost [5] );
printf("目的MAC地址是:0x%2x:0x%2x:0x%2x:0x%2x:0x%2x:0x%2x\n",eh->ether_dhost [0],eh->ether_dhost [1],eh->ether_dhost [2],eh->ether_dhost [3],eh->ether_dhost [4],eh->ether_dhost [5]);
/*读取IP头*/
if(!feof(pfile))
{
if(!fread(iph,sizeof(*iph),1,pfile)/*||iph->protocol !=6*/)
{
printf("读取IP头失败\n");
break;
}
}
printf("源IP地址:%s\n",inet_ntoa(iph->src_IP));
printf("目的IP地址:%s\n",inet_ntoa(iph->dst_IP ));
/*读取TCP头*/
if(!feof(pfile))
{
if(!fread(tcph,sizeof(*tcph),1,pfile))
{
printf("读取tcp头失败\n");
break;
}
}
printf("源端口:%d\n",tcph->src_port );
printf("目的端口:%d\n",tcph->dst_port );
if(ph->capture_len -54==0)//没有数据部分
{
continue;
}
else//存在数据部分,读取数据
{
unsigned charbuf=(unsigned char)malloc(ph->capture_len -54);
if(buf==NULL)
{
printf("分配数据区域失败!\n");
break;
}
if(!feof(pfile))
{
if(!fread(buf,sizeof(unsigned char),ph->capture_len -54,pfile))
{
printf("读取数据失败\n");
break;
}
}
}
}//end while
/*释放资源*/
free(ph);
free(eh);
free(iph);
free(tcph);
fclose(pfile);
}