提取一个pcap文件里的每个pcap数据包的五元组和根域名,插入到哈希表。
提取一个pcap文件里的每个pcap数据包的五元组,去哈希表中查找,如果可以查到,取出对应的根域名,并且输出为pcap数据包,名字是根域名。
以下为一些小记:(判断一个数据包是否有域名!
用一个数组记录已存在的数据包,再决定进行新建pcap还是追加。
根域名数组里有,说明已经有了pcap包,追加在后面。
根域名数组里没有,新建一个。
tmp代表这个根域名在数组的什么位置。)
代码如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<netinet/in.h>
typedef int32_t bpf_int32;
typedef u_int32_t bpf_u_int32;
typedef u_int16_t u_short;
typedef u_int32_t u_int32;
typedef u_int16_t u_int16;
typedef u_int8_t u_int8;
char tempSrcIp[256];//存储转化后的字符地址。
char tempDstIp[256];
//pacp文件头结构体
struct pcap_file_header
{
bpf_u_int32 magic; /* 0xa1b2c3d4 */
u_short version_major; /* magjor Version 2 */
u_short version_minor; /* magjor Version 4 */
bpf_int32 thiszone; /* gmt to local correction */
bpf_u_int32 sigfigs; /* accuracy of timestamps */
bpf_u_int32 snaplen; /* max length saved portion of each pkt */
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
};
//时间戳
struct time_val
{
int tv_sec; /* seconds 含义同 time_t 对象的值 */
int tv_usec; /* and microseconds */
};
//pcap数据包头结构体
struct pcap_pkthdr
{
struct time_val ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
};
//IP数据报头 20字节
typedef struct IPHeader_t
{ //IP数据报头
u_int8 Ver_HLen; //版本+报头长度
u_int8 TOS; //服务类型
u_int16 TotalLen; //总长度
u_int16 ID; //标识
u_int16 Flag_Segment; //标志+片偏移
u_int8 TTL; //生存周期
u_int8 Protocol; //协议类型
u_int16 Checksum; //头部校验和
u_int32 SrcIP; //源IP地址
u_int32 DstIP; //目的IP地址
} IPHeader_t;
//TCP/UDP数据
typedef struct TCPUDPHeader_t
{
u_int16_t SrcPort; // 源端口号16bit
u_int16_t DstPort; // 目的端口号16bit
}TCPUDPHeader_t;
typedef struct Quintet
{
u_int32 SrcIP; //源IP地址
u_int32 DstIP; //目的IP地址
u_int16_t SrcPort; // 源端口号16bit
u_int16_t DstPort; // 目的端口号16bit
u_int8 Protocol; //协议类型
}Quintet_t;
struct NODE{//定义结点
char * tuple;
char * dm_host;
struct NODE *next;
} ;
struct wuyuan //用来保存转换后的结果
{
char * srcip;
char * dstip;
int srcport;
int dstport;
int proto;
};
//编写一个比较两个五元组是否相同的函数,0表示不相等,1表示相等
int wuyuan_isEqual(struct wuyuan a,struct wuyuan b)
{
if(a.proto==b.proto){
if(a.srcip==b.srcip && a.dstip==b.dstip && a.srcport==b.srcport && a.dstport==b.dstport)//五元组一模一样时.
{
return 1;
}
else{
if(a.srcip==b.dstip && a.dstip==b.srcip && a.srcport==b.dstport && a.dstport==b.srcport)//五元组恰好相反
{
return 1;
}
else{
return 0;
}
}
}
else{
return 0;
}
}
//输入为数组和根域名和数量
int host_isexist(char * shuzu,char * dm_host,int sl){
int host_len=strlen(dm_host);
int z=0;
while(z<host_len){
if(*(shuzu+z)==*(dm_host+z)){
if(z=host_len-1){
//printf("loooook:%c",*(shuzu+z));
return 1;
}
}
z++;
}
return 0;
}
//建立新pcap包并写入内容,或在已有的pcap包的基础上写入内容。
//输入是w0/a1(新建还是追加)、根域名(arr)、文件指针、caplen值和偏移量,表格内的数量sl,tmp,pcap_head.
int out_pcap(int a,char * dm_host,FILE* pFile,int caplen,int pkt_offset,int sl,int tmp,char pcap_head[24])
{
//先根据根域名拼接好pcap包名。
char * outfile;
outfile = (char *)malloc(100);
int len=strlen(dm_host);
int j;
for(j=0;j<len;j++){
*(outfile+j)=*(dm_host+j);
}
strcat(outfile,".pcap");
if(0==a){//创建新pcap包
//定义pcap包的格式。
FILE *output = fopen(outfile,"w+");//a+是在文件末尾开始加入。
if( output == 0)
{
printf( "创建pcap文件失败");
return 0;
}
if(0==tmp)//说明是第一个,所以要上传pcap数据包头。
{
//这是第一个数据包,所有没有偏移。
//每个数据包头都要传上pcap文件头。
fseek(pFile,24, SEEK_SET);
fwrite(pcap_head,24,1,output);
char cs[16+caplen];
// fwrite(pFile,(16+ptk_header->caplen),1,output);
fread(cs,(16+caplen),1,pFile);
fwrite(cs,(16+caplen),1,output);
//printf("%s",cs);
fclose(output);
}else{
//把这个数据包写入。是数组里没有的数据包,要新建一个叫host的pcap文件。
fseek(pFile, pkt_offset-16-caplen, SEEK_SET);//移动pfile文件指针位置,回到文件开头
fwrite(pcap_head,24,1,output);
char cs[16+caplen];
// fwrite(pFile,(16+ptk_header->caplen),1,output);
fread(cs,(16+caplen),1,pFile);
fwrite(cs,(16+caplen),1,output);
//printf("%s",cs);
fclose(output);
}
}else if(1==a){//在已有的pcap包基础上追加内容
//打开已有的pcap包,在后面写入新数据。得到数组中的五元组,并拼接。
FILE *output = fopen(outfile,"a+");
if( output == 0)
{
printf( "打开pcap文件失败");
return 0;
}
//把这个数据包写入
fseek(pFile, (pkt_offset-16-caplen), SEEK_SET);//移动pfile文件指针位置,回到数据包开头。
char cs1[16+caplen];
// fwrite(pFile,(16+ptk_header->caplen),1,output);
fread(cs1,(16+caplen),1,pFile);
fwrite(cs1,(16+caplen),1,output);
//printf("%s",cs);
fclose(output);
}
return 1;
}
//查找src在dst中的位置,不存在则返回-1.考虑HOST、Host、host三种情况
//直接return host的值。
char * get_data_offset(char *src, char *dst,int dst_len)
{
//先把src的首字母在dst中找,如果找到,则把dst中后面一部分与src相同长度的字符串摘出来进行比较,若相等则返回第一个位置,
//否则返回-1.
int dIndex=0;//dst移动下标
int sIndex = 0;//src移动下标
int src_len=strlen(src);
//printf("%s\n",dst);
//printf("!!!%d",src_len);
while(dIndex <= dst_len-src_len){
//如果两个字母相等,继续判断剩下的
if(*src == *(dst+dIndex)){
sIndex = 0;
for(;sIndex<src_len;sIndex++){//往后遍历src长度的字符串
//dst 和src一直没移动。
if(*(dst+sIndex+dIndex)!=*(src+sIndex))//如果中间任何一个字母不等于
{
break;
}else{ //如果全部等于
//之前是sIndex和dIndex一直在移动。用一个tmpindex记录。
}
}
if(sIndex == src_len){
int tmp_index=dIndex+sIndex+2;//把: 都省略掉
int host_len=0;
char * host;
host=(char *)malloc (100);
while(*(dst+tmp_index)!='\r' && *(dst+tmp_index+1)!='\n'){//一直+1,直到碰到\r\n
// printf("%c",*(dst+tmp_index));
*(host+host_len)=*(dst+tmp_index);
tmp_index++;
host_len++;
}
printf("\n");
return host;
}
}
dIndex++; //printf("src:%s",src);
//printf("dst:%s\n",dst);
}
return NULL;
}
//先用字符串匹配,匹配是否有.com.cn,有的话取倒数第三个.右边的所有字符;没有的话取倒数第二个.右边的所有字符。
char * get_domain_from_host(char * host)
{
char *z=".com.cn";
char *tmp_res;
char *res;
int len=strlen(host);//记录host的长度。
tmp_res=(char *)malloc (100);
res=(char *)malloc (20);//输出的结果
//调用字符串查找函数找有没有.com.cn
tmp_res=get_data_offset(z,host,len);
//创建一个函数,读取host中.的个数,并将其对应的下标位置记录下。
//定义一个数组,记录下标值。再定义一个num记录.的个数。
int mark[10];
int num=0;
int i=0;
while(i<len){//遍历host
if(*(host+i)=='.'){
mark[num]=i;
num++;
}
i++;
}
if(tmp_res==NULL){//说明没有.com.cn
//取倒数第二个.右边的所有字符。第一个.的位置是mark[0],第二个.的位置是mark[1]... 倒数第一个.的位置是num-1;倒数第二个是num-2,倒数第三个是num-3.
int j=mark[num-2]+1;
int k=0;
while(j<len){
*(res+k)=*(host+j);
k++;
j++;
}
return res;
}else{//说明有,取倒数第三个.右边的所有字符
int j=mark[num-3]+1;
int k=0;
while(j<len){
*(res+k)=*(host+j);
k++;
j++;
}
return res;
}
return NULL;
}
int hash(char *s){//计算字符串的hashcode值
int h=0;
for(;*s;s++)
h=*s+h*31;
if(h<0){
h=0-h;
}
return h%100;
}
//有tuple和dm_host两个
//将五元组-根域名,插入到哈希表(五元组作为key)
//确认这个五元组信息,是否可以从哈希表中查到(输入五元组去查找,值是damain_host),如果可以查到则将这个包写到pcap文件中,pcap文件名字是domain_host
//把字符串跟索引值联系起来的方法:计算字符串的hashcode
void hash_insert(struct NODE * host_5tuple_hash[],char* tuple,char * dm_host){
int index=hash(tuple);
printf("hashcode:%d\n",index);
//创建一个新节点
struct NODE *p;
p=(struct NODE *)malloc (sizeof(struct NODE));
int i = 0;
p->tuple= (char*)malloc(strlen(tuple)+1);
memcpy(p->tuple,tuple,strlen(tuple));
*(p->tuple+strlen(tuple)) = '\0';
p->dm_host=dm_host;
//printf("????%s\n",p->tuple);
//判断对应的哈希桶是否为空
if(host_5tuple_hash[index]->next==NULL){
//如果为空,将新节点接上去
host_5tuple_hash[index]->next=p;
p->next=NULL;
}
else{
//不为空则遍历到为空的地方,再接上
struct NODE *temp_head;
temp_head=(struct NODE *)malloc (sizeof(struct NODE));
temp_head=host_5tuple_hash[index];//移动temp_head指针
while(temp_head->next!=NULL){
temp_head=temp_head->next;
}
temp_head->next=p;
p->next=NULL;
}
}
//查询,从根域名查询host名称
struct NODE * hash_search(struct NODE * host_5tuple_hash[],char * tuple){
int index=hash(tuple);
if(host_5tuple_hash[index]->next==NULL){
printf("zero");
return NULL;
}
else{
//不为空则打印domain_host及五元组值,再返回首地址
printf("5tuple:%s\n",host_5tuple_hash[index]->next->tuple);
printf("dmhost:%s\n",host_5tuple_hash[index]->next->dm_host);
return host_5tuple_hash[index];
}
}
//遍历一个数据包,得到数据包的五元组和根域名并且插入哈希表中。
void get_tuple_dmhost_hash(FILE* pFile,struct NODE * host_5tuple_hash[])
{
struct pcap_pkthdr *ptk_header = NULL;//设置将要读取的pcap包的包头
IPHeader_t *ip_header = NULL;
TCPUDPHeader_t *tcpudp_header = NULL;
Quintet_t *quintet = NULL;
//初始化,分配内存
ptk_header = (struct pcap_pkthdr *)malloc(256);
ip_header = (IPHeader_t *)malloc(sizeof(IPHeader_t));
tcpudp_header = (TCPUDPHeader_t *)malloc(sizeof(TCPUDPHeader_t));
quintet = (Quintet_t *)malloc(sizeof(Quintet_t));
//memset(buf, 0, sizeof(buf));
//开始读数据包------------
long int pkt_offset; //用来文件偏移
pkt_offset = 24; //pcap文件头结构 24个字节
int i = 0;int j;
while(1) //遍历数据包,结构:pcap文件头24B,数据包头16B(包括caplen),数据包内容中包括数据帧头14B,IP数据报头20B(源地址和目的地址),UDP/TCP数据包内容。
{
i++;
fseek(pFile, pkt_offset, SEEK_SET);//移动pfile文件指针位置,跳过pcap文件头
//对要存储的变量地址的内容进行初始化。
memset(ptk_header, 0, sizeof(struct pcap_pkthdr));
memset(quintet,0,sizeof(struct Quintet));
//读pcap数据包头结构,16个字节
if(fread(ptk_header, 16, 1, pFile) != 1)
{
printf("%d: can not read ptk_header\n", i);
break;
}
pkt_offset += 16 + ptk_header->caplen; //下一个数据包的开始位置为此数据包的起始位置+数据包头(16B)+数据长度caplen
//printf("caplen:%d\n",ptk_header->caplen);
//数据帧头 14字为ethnet协议大小,跳过。
fseek(pFile,14, SEEK_CUR);
//IP数据报头 20字节
memset(ip_header, 0, sizeof(IPHeader_t));
if(fread(ip_header, sizeof(IPHeader_t), 1, pFile) != 1)
{
printf("%d: can not read ip_header\n", i);
break;
}
quintet->SrcIP = ip_header->SrcIP;
quintet->DstIP = ip_header->DstIP;
quintet->Protocol = ip_header->Protocol;
memset(tcpudp_header,0,sizeof(TCPUDPHeader_t));
//TCP/UDP头 20字节,端口字段是一样的
if(fread(tcpudp_header, sizeof(TCPUDPHeader_t), 1, pFile) != 1)
{
printf("%d: can not read tcpudp_header\n", i);
break;
}
quintet->SrcPort = tcpudp_header->SrcPort;
quintet->DstPort = tcpudp_header->DstPort;
//将数值转化为ip地址
//printf("???%d\n",&ip_header->SrcIP);
inet_ntop(AF_INET,&(ip_header->SrcIP),tempSrcIp,sizeof(tempSrcIp));
inet_ntop(AF_INET, &(ip_header->DstIP),tempDstIp,sizeof(tempDstIp));
//将数值转换为端口号
quintet->SrcPort = ntohs(quintet->SrcPort);
quintet->DstPort = ntohs(quintet->DstPort);
//先把caplen长度的数据包内容读取到一个空间。再使用字符串查找的方法,形如http.host == "xxx" 或者Host: jingxi.co\r\n
char tmp_http[10000];
fseek(pFile, (pkt_offset-16-ptk_header->caplen), SEEK_SET);//回到每个数据包的开头。
if(fread(tmp_http,ptk_header->caplen,1,pFile)!=1)
{
printf("fail");
}
//使用字符串查找的方法。
char *x="host";
char * res;
res=(char *)malloc (100);
res=get_data_offset(x,tmp_http,ptk_header->caplen);
if(res==NULL){
x="Host";
res=get_data_offset(x,tmp_http,ptk_header->caplen);
if(res==NULL){
x="HOST";
res=get_data_offset(x,tmp_http,ptk_header->caplen);
if(res==NULL){
printf("search host fail");
break;
}
}
}
//从host里面提取出顶级域名。考虑以下几种情况:除了.com.cn,都取倒数第二个.右边的所有字符。
//所以先用字符串匹配,匹配是否有.com.cn,有的话取倒数第三个.右边的所有字符;没有的话取倒数第二个.右边的所有字符。
char * domain_host;
domain_host=(char *)malloc (20);
domain_host=get_domain_from_host(res);
printf("res:%s\n",domain_host);
//插入哈希表,tuple=五元组
char * tuple;
tuple=(char *)malloc (100);
char *sport;
sport = (char *)malloc(20);
sprintf(sport, "%d", quintet->SrcPort);
char *dport;
dport = (char *)malloc(20);
sprintf(dport, "%d", quintet->DstPort);
char *pro;
pro = (char *)malloc(10);
sprintf(pro, "%d", quintet->Protocol);
tuple=tempSrcIp;strcat(tuple,"_");strcat(tuple,tempDstIp);strcat(tuple,"_");strcat(tuple,sport);strcat(tuple,"_");
strcat(tuple,dport);strcat(tuple,"_");strcat(tuple,pro);
hash_insert(host_5tuple_hash,tuple,domain_host);
}
//根据五元组查找根域名并输出。
struct NODE * tmp_tuple;
tmp_tuple=(struct NODE *)malloc (sizeof(struct NODE));
//tmp_tuple=hash_search(host_5tuple_hash,"58.216.4.176_180.163.39.54_42205_80_6");
//遍历链表进行输出
/*for(j=0;j<100;j++){
//说明桶子内有值,循环输出直到next为null
if(host_5tuple_hash[j]->next!=NULL){
printf("bucket%d:\n",j);
struct NODE *temp_head2;
temp_head2=(struct NODE *)malloc (sizeof(struct NODE));
temp_head2=host_5tuple_hash[j];//移动temo_head2指针
while(temp_head2->next!=NULL){
printf("tuple:%s,",temp_head2->next->tuple);
printf("dm_host:%s\n",temp_head2->next->dm_host);
//指针移动
temp_head2=temp_head2->next;
}
}*/
free(ip_header);free(tcpudp_header);free(quintet);free(ptk_header);
}
//提取各个数据包的五元组,并去哈希表中进行查找,存在的话得到对应的根域名值,并且以此作为文件名把相同五元组的数据包输出为一个pcap数据包。
void search_hash_bydmhost(FILE* pFile,struct NODE * host_5tuple_hash[])
{
struct pcap_pkthdr *ptk_header = NULL;//设置将要读取的pcap包的包头
IPHeader_t *ip_header = NULL;
TCPUDPHeader_t *tcpudp_header = NULL;
Quintet_t *quintet = NULL;
//初始化,分配内存
ptk_header = (struct pcap_pkthdr *)malloc(256);
ip_header = (IPHeader_t *)malloc(sizeof(IPHeader_t));
tcpudp_header = (TCPUDPHeader_t *)malloc(sizeof(TCPUDPHeader_t));
quintet = (Quintet_t *)malloc(sizeof(Quintet_t));
//memset(buf, 0, sizeof(buf));
/* char filename[100];
scanf("%s", &filename);
FILE* pFile = fopen( filename, "r");*/
if( pFile == 0)
{
printf( "打开pcap文件失败");
}
//先创建一个数组记录已经创建过pcap包的根域名
char * pcaped_host[10000];
//计数,记录数组中已经存储多少个五元组了。
int sl=0;
//开始读数据包------------
long int pkt_offset; //用来文件偏移
pkt_offset = 24; //pcap文件头结构 24个字节
int i = 0;
//定义一个东西记录pcap数据包头,24字节。
char pcap_head[24];
fread(pcap_head,24,1,pFile);
while(1) //遍历数据包,结构:pcap文件头24B,数据包头16B(包括caplen),数据包内容中包括数据帧头14B,IP数据报头20B(源地址和目的地址),UDP/TCP数据包内容。
{//提取到它的五元组
i++;
fseek(pFile, pkt_offset, SEEK_SET);//移动pfile文件指针位置,跳过pcap文件头;到每一次数据包开头的位置。
//对要存储的变量地址的内容进行初始化。
memset(ptk_header, 0, sizeof(struct pcap_pkthdr));
memset(quintet,0,sizeof(struct Quintet));
//读pcap数据包头结构,16个字节
if(fread(ptk_header, 16, 1, pFile) != 1)
{
printf("%d: can not read ptk_header\n", i);
break;
}
pkt_offset += 16 + ptk_header->caplen; //下一个数据包的开始位置为此数据包的起始位置+数据包头(16B)+数据长度caplen
//printf("caplen:%d\n",ptk_header->caplen);
//数据帧头 14字为ethnet协议大小,跳过。
fseek(pFile,14, SEEK_CUR);
//IP数据报头 20字节
memset(ip_header, 0, sizeof(IPHeader_t));
if(fread(ip_header, sizeof(IPHeader_t), 1, pFile) != 1)
{
printf("%d: can not read ip_header\n", i);
break;
}
quintet->SrcIP = ip_header->SrcIP;
quintet->DstIP = ip_header->DstIP;
quintet->Protocol = ip_header->Protocol;
memset(tcpudp_header,0,sizeof(TCPUDPHeader_t));
//TCP/UDP头 20字节,端口字段是一样的
if(fread(tcpudp_header, sizeof(TCPUDPHeader_t), 1, pFile) != 1)
{
printf("%d: can not read tcpudp_header\n", i);
break;
}
quintet->SrcPort = tcpudp_header->SrcPort;
quintet->DstPort = tcpudp_header->DstPort;
//将数值转化为ip地址
//printf("???%d\n",&ip_header->SrcIP);
inet_ntop(AF_INET,&(ip_header->SrcIP),tempSrcIp,sizeof(tempSrcIp));
inet_ntop(AF_INET, &(ip_header->DstIP),tempDstIp,sizeof(tempDstIp));
//将数值转换为端口号
quintet->SrcPort = ntohs(quintet->SrcPort);
quintet->DstPort = ntohs(quintet->DstPort);
//到此为止得到了其五元组。暂时不考虑同一条流的,目的地和起始地互发的情况。把五元组进行拼接,再去哈希表中查找得到根域名。
//插入哈希表,tuple=五元组
char * tuple2;
tuple2=(char *)malloc (100);
char *sport2;
sport2 = (char *)malloc(20);
sprintf(sport2, "%d", quintet->SrcPort);
char *dport2;
dport2 = (char *)malloc(20);
sprintf(dport2, "%d", quintet->DstPort);
char *pro2;
pro2 = (char *)malloc(10);
sprintf(pro2, "%d", quintet->Protocol);
tuple2=tempSrcIp;strcat(tuple2,"_");strcat(tuple2,tempDstIp);strcat(tuple2,"_");strcat(tuple2,sport2);strcat(tuple2,"_");
strcat(tuple2,dport2);strcat(tuple2,"_");strcat(tuple2,pro2);
//根据五元组查找根域名。
struct NODE * tmp_host;
tmp_host=(struct NODE *)malloc (sizeof(struct NODE));
tmp_host=(hash_search(host_5tuple_hash,tuple2));
int hostlen=strlen(tmp_host->next->dm_host);//这个是根域名
//若两个数据包的端口号和ip地址恰好相反,则为同一个流。
//每一个流输出一个文件。
//创建一个数组,记录所有不同的五元组,并对应所有输出的pcap文件。每次检查一个新的数据包,就去数组里找,存不存在,存在就直接插入这个输出包里,不存在就先加入数组,再新建对应的pcap文件并写入。
if(sl==0)//如果这是第一个数据包,直接插入数组中,并创建新文件。
{
pcaped_host[0]= (char*)malloc(hostlen+1);
memcpy(pcaped_host[0],tmp_host->next->dm_host,hostlen);
*(pcaped_host[0]+hostlen) = '\0';
//创建新pcap包并写入数据。
//调用函数创建一个新的pcap包。(int a,struct wuyuan arr,FILE* pFile,int caplen,int pkt_offset,int sl,int temp,pcaphead)
out_pcap(0,tmp_host->next->dm_host,pFile,ptk_header->caplen,0,sl,0,pcap_head);
sl++;
}
else{//根据sl值遍历数组,判断是否存在。
int tmp=0;
int result=0;//先默认不存在.
while(tmp<sl)
{
result=host_isexist(pcaped_host[tmp],tmp_host->next->dm_host,sl);
if(result==1)//如果已经找到存在的
{
break;
}
tmp++;//到数组的下一个元素。
}
if(result==0){//如果不在数组里,建立一个新的pcap包。
//添加进数组,并且sl+1.
pcaped_host[sl]= (char*)malloc(hostlen+1);
memcpy(pcaped_host[sl],tmp_host->next->dm_host,hostlen);
*(pcaped_host[sl]+hostlen) = '\0';
//建议一个新的pcap包。
out_pcap(0,tmp_host->next->dm_host,pFile,ptk_header->caplen,pkt_offset,sl,1,pcap_head);
sl++;//假如有10个数据,最后一位已有的是9.现在添加第11个数据,位置是10
}
else if(result==1)//如果在数组里,tmp代表所相同的五元组的位置,输入到对应的pcap包里。
{
//打开已有的pcap包,在后面写入新数据。得到数组中的五元组,并拼接。
out_pcap(1,tmp_host->next->dm_host,pFile,ptk_header->caplen,pkt_offset,sl,tmp,pcap_head);
}
}
}
//遍历完后,显示一下一共多少个pcap包。
printf("shuliang:%d\n",sl);
}
int main()
{
//创建哈希表的指针数组
struct NODE * host_5tuple_hash[1000];
//创建100个链表,并保存在指针数组中。
int ii;
for(ii=0;ii<100;ii++){
struct NODE *head;
head=(struct NODE *)malloc (sizeof(struct NODE));
host_5tuple_hash[ii]=head;
host_5tuple_hash[ii]->next=NULL;
}
FILE* pFile = fopen( "data.pcap", "r");
if( pFile == 0)
{
printf( "打开pcap文件失败");
return 0;
}
FILE* pFile2 = fopen( "data.pcap", "r");
if( pFile == 0)
{
printf( "打开pcap文件失败");
return 0;
}
//运行该函数,得到以五元组为key,根域名为值的哈希表,输入为数据包和空哈希表。
get_tuple_dmhost_hash(pFile,host_5tuple_hash); fclose(pFile);
//提取各个数据包的五元组,并去哈希表中进行查找,存在的话得到对应的根域名值,并且以此作为文件名把相同五元组的数据包输出为一个pcap数据包。
search_hash_bydmhost(pFile2,host_5tuple_hash);
fclose(pFile2);
return 0;
}