#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>/**//* defines */#define in 1#define out 0#define true 1#define false 0/**//****************************************************//**//* define types */typedef unsigned long UINT4;typedef unsigned short UINT2;typedef unsigned char UINT1;typedef int bool;typedef char * string;/**//****************************************************//**//****************************************************///_st_flow_stattypedef struct _st_flow_stat...{ UINT4 tv; UINT4 sip; UINT4 dip; UINT4 flow_in; UINT4 flow_out; UINT2 pkts_in; UINT2 pkts_out; UINT2 sport; UINT2 dport; UINT1 app_proto; UINT1 inout; UINT1 proto; UINT1 reserved; char name[20];}flow, *flow_p;//ip listtypedef struct ip_list...{ //UINT4 ip; //ip number UINT1 proto; //application protocol UINT4 in_byte; UINT4 out_byte; UINT4 in_pack; UINT4 out_pack; struct ip_list *next_proto;}element, *element_ptr;//hash headtypedef struct iplist_head...{ UINT4 ip; element_ptr rear; struct ip_list *hash_element;}*iplist_head_p;//ip_fluxtypedef struct ip_flux...{ UINT4 index; //index of every element UINT4 ip_num; //ip UINT4 flux; //flux,default is byte_in}*ip_flux_p;/**//******************************************************//**//*************************************************************///functions //read file,and operate on the data of the filevoid read_file(const string file_name, UINT4 file_size, UINT4 read_size, int top_n);//deal with the hash tablevoid deal_iplist(flow ip_flow, struct iplist_head hash_table[], UINT4 ip);//ip_hash codeUINT2 ip_hash(UINT4 ip_num);//print all ip information int print_ip_info(struct iplist_head hash_table[], struct ip_flux flux_table[]);//convert protocol number to protocol stringstring protonum_to_proto(UINT1 proto);//===============operate the ip list====================//make a ip liststruct ip_list *make_list(element_ptr *rear_ptr);//add a element to the listelement_ptr add_to_list(element_ptr *rear_ptr,UINT1 app_proto, UINT4 in_byte, UINT4 out_byte, UINT2 pack_in, UINT2 pack_out);//query a ip list whether it has already set the protocolbool query_proto(struct ip_list *list, UINT1 app_proto, element_ptr *same);//======================================================//heap sort,operate on hash tablevoid heap_sort(struct ip_flux flux_table[], struct ip_flux extra_table[], struct ip_flux topn_flux_table[], int flux_table_len, int topn);//insert sort,operate on flux tablevoid insert_sort(struct ip_flux topn_table[], int topn, struct ip_flux max_flux);//insert the max to topn tablevoid insert_to_pos(struct ip_flux topn_table[], struct ip_flux max_flux, int high, int insert_pos);//return the size of a fileUINT4 count_file_size(const string file_name);//return a IP stringstring ipnum_to_ipstr(UINT4 ip_num);void free_space(struct iplist_head *hash_table, struct ip_flux *flux_table, struct ip_flux *topn_table);/**//**********************************************************************///mainint main()...{ UINT4 file_size = 0; /**//* string path; printf("Please input the file path:"); scanf("%s", path); */ /**//* get the size of the file "flowstat.dat" */ file_size = count_file_size("flowstat.dat"); printf("The size of the file is:%d ", file_size); UINT4 read_size = 1048576; //read 1MB everytime from the file int topn; printf("Please input the top number:"); scanf("%d", &topn); /**//* read the file */ read_file("flowstat.dat", file_size, read_size, topn); return 0;}/**//*************************************************************************///read filevoid read_file(const string file_name, UINT4 file_size, UINT4 read_size, int top_n)...{ FILE *fp; flow flow_format; UINT2 block_sum = file_size/read_size; flow_p file_buf = (flow_p)malloc( (read_size/sizeof(flow)) * sizeof(flow) ); assert(file_buf); fp = fopen(file_name, "rb"); //open the specified file to read flow_p flow_index = file_buf; //flow_index that point to the file_buf //hash_table record the pointer that point a ip list struct iplist_head *sip_hash_table = (struct iplist_head *)malloc(65536 * sizeof(struct iplist_head)); struct iplist_head *dip_hash_table = (struct iplist_head *)malloc(65536 * sizeof(struct iplist_head)); //malloc enough space for memory every ip and flux from the hash table struct ip_flux *sip_flux_table = (struct ip_flux *)malloc(65536 * sizeof(struct ip_flux)); struct ip_flux *dip_flux_table = (struct ip_flux *)malloc(65536 * sizeof(struct ip_flux)); //sip topn struct ip_flux *sip_topn_flux_table = (struct ip_flux *)malloc(top_n * sizeof(struct ip_flux)); //dip topn struct ip_flux *dip_topn_flux_table = (struct ip_flux *)malloc(top_n * sizeof(struct ip_flux)); assert(sip_hash_table); assert(dip_hash_table); assert(sip_flux_table); assert(dip_flux_table); assert(sip_topn_flux_table); assert(dip_topn_flux_table); int index; //index the offset of flow_stat structure int sip_flux_table_len = 0; //record the sip flux table length int dip_flux_table_len = 0; //record the dip flux table length while((block_sum--) > 0) //whether reach the end of the file ---feof() ...{ //read 1MB data from the file to the buffer every time fread(file_buf, (read_size/sizeof(flow)) * sizeof(flow), 1, fp); index = read_size/sizeof(flow); while( (index--) > 0 ) ...{ flow_format = *flow_index; //deal with the sip deal_iplist(flow_format, sip_hash_table, flow_format.sip); //deal with the dip deal_iplist(flow_format, dip_hash_table, flow_format.dip); ++flow_index; } printf("------The sip information:------ "); sip_flux_table_len = print_ip_info(sip_hash_table, sip_flux_table); printf("------The dip information:------ "); dip_flux_table_len = print_ip_info(dip_hash_table, dip_flux_table); struct ip_flux *sip_extra_table = (struct ip_flux *)malloc(sip_flux_table_len*sizeof(struct ip_flux)); struct ip_flux *dip_extra_table = (struct ip_flux *)malloc(dip_flux_table_len*sizeof(struct ip_flux)); //heap sort of sip flux table,get TopN of it heap_sort(sip_flux_table, sip_extra_table, sip_topn_flux_table, sip_flux_table_len, top_n); //heap sort of dip flux table,get TopN of it heap_sort(dip_flux_table, dip_extra_table, dip_topn_flux_table, dip_flux_table_len, top_n); //free the extra space free(sip_extra_table); sip_extra_table = NULL; free(dip_extra_table); dip_extra_table = NULL; } printf(" -------------SIP TopN------------- "); /**//* test the topn*/ int n = 0; for(; n<top_n; ++n) ...{ printf("The sip owning No.%d flux is:%s, flux is:%d ",n+1, ipnum_to_ipstr(sip_topn_flux_table[n].ip_num), sip_topn_flux_table[n].flux); } printf(" -------------DIP TopN-------------- "); for(n=0; n<top_n; ++n) ...{ printf("The dip owning No.%d flux is:%s, flux is:%d ",n+1, ipnum_to_ipstr(dip_topn_flux_table[n].ip_num), dip_topn_flux_table[n].flux); } //free sip space free_space(sip_hash_table, sip_flux_table, sip_topn_flux_table); //free dip space,the same as sip free_space(dip_hash_table, dip_flux_table, dip_topn_flux_table); //reset fp rewind(fp); fclose(fp);}/**//******************************************************************///deal with a ip list,sip or dip.void deal_iplist(flow ip_flow, struct iplist_head hash_table[], UINT4 ip) ...{ element_ptr rear = (element_ptr)malloc(sizeof(element)); //the rear of a list element_ptr same_proto = (element_ptr)malloc(sizeof(element)); //record the position that own the same protocol int offset = ip_hash(ip); struct ip_list *temp_ip_head = hash_table[offset].hash_element; //ip_hash(ip_flow.sip) is offset if( temp_ip_head == NULL) ...{ temp_ip_head = make_list(&rear); //assign temp_ip_head to member hash_element of ip element hash_table[offset].hash_element = temp_ip_head; //assign ip_flow.ip to member ip of ip element hash_table[offset].ip = ip; add_to_list(&rear, ip_flow.app_proto, ip_flow.flow_in, ip_flow.flow_out, ip_flow.pkts_in, ip_flow.pkts_out); hash_table[offset].rear = rear; //assign the list rear to hash element member rear } else if(temp_ip_head != NULL) ...{ if( !query_proto(temp_ip_head, ip_flow.app_proto, &same_proto) ) ...{ add_to_list(&(hash_table[offset].rear), ip_flow.app_proto, ip_flow.flow_in, ip_flow.flow_out, ip_flow.pkts_in, ip_flow.pkts_out); } else ...{ //add the flow data to the same protocol members same_proto -> in_byte += ip_flow.flow_in; same_proto -> out_byte += ip_flow.flow_out; same_proto -> in_pack += ip_flow.pkts_in; same_proto -> out_pack += ip_flow.pkts_out; } }}/**//***************************************************************************///print all ip informationint print_ip_info(struct iplist_head hash_table[], struct ip_flux flux_table[])...{ UINT4 i, j; UINT4 ptr_sum = 65536; //hash element sum UINT4 in_byte_sum, out_byte_sum, in_pack_sum, out_pack_sum; UINT4 in_byte_ip_sum, out_byte_ip_sum, in_pack_ip_sum, out_pack_ip_sum; j = 0; in_byte_ip_sum = out_byte_ip_sum = in_pack_ip_sum = out_pack_ip_sum = 0; in_byte_sum = out_byte_sum = in_pack_sum = out_pack_sum = 0; element_ptr curr_ptr = NULL; for(i=0; i<ptr_sum; ++i) ...{ if(hash_table[i].hash_element != NULL) ...{ flux_table[j].ip_num = hash_table[i].ip; //assign ip flux_table[j].index = j; //assign index curr_ptr = hash_table[i].hash_element -> next_proto; //printf("%s's information is: ", ipnum_to_ipstr(hash_table[i].ip)); while(curr_ptr != NULL) ...{ //accumulate a ip 's all protocol in_byte,out_byte,in_pack,out_pack in_byte_ip_sum += curr_ptr->in_byte; out_byte_ip_sum += curr_ptr->out_byte; in_pack_ip_sum += curr_ptr->in_pack; out_pack_ip_sum += curr_ptr->out_pack; //accumulate all ips' flux in_byte_sum += in_byte_ip_sum; out_byte_sum += out_byte_ip_sum; in_pack_sum += in_pack_ip_sum; out_pack_sum += out_pack_ip_sum; //printf("Protocol:%ld, bytes_in:%ld, bytes_out:%ld, packets_in:%ld, packets_out:%ld ", //curr_ptr->proto, curr_ptr->in_byte, curr_ptr->out_byte, //curr_ptr->in_pack, curr_ptr->out_pack); curr_ptr = curr_ptr -> next_proto; }//while //head node record the sum of all protocols' flux flux_table[j].flux = hash_table[i].hash_element -> in_byte = in_byte_ip_sum; //default is the in_byte hash_table[i].hash_element -> out_byte = out_byte_ip_sum; hash_table[i].hash_element -> in_pack = in_pack_ip_sum; hash_table[i].hash_element -> out_pack = out_pack_ip_sum; in_byte_ip_sum = out_byte_ip_sum = in_pack_ip_sum = out_pack_ip_sum = 0; ++j; //j is the index of flux table }//if }//for printf("All bytes_in:%ld, all bytes_out:%ld, all packets_in:%ld, all packets_out:%ld ", in_byte_sum, out_byte_sum, in_pack_sum, out_pack_sum); return j;}/**//***************************************************************************///ip hashUINT2 ip_hash(UINT4 ip_num)...{ UINT4 temp = ip_num; UINT4 mask = 65535; return (UINT2)((ip_num&mask)^(temp>>16));}/**//***************************************************************************///make a list struct ip_list *make_list(element_ptr *rear)...{ struct ip_list *head = (struct ip_list *) malloc(sizeof(element)); assert(head); *rear = head; //assign values to the members of the head head -> proto = 0; head -> in_byte = 0; head -> out_byte = 0; head -> in_pack = 0; head -> out_pack = 0; head -> next_proto = NULL; return head;}//add a element to the list element_ptr add_to_list(element_ptr *rear_ptr, UINT1 app_proto, UINT4 in_byte, UINT4 out_byte, UINT2 pack_in, UINT2 pack_out)...{ element_ptr curr_ptr = *rear_ptr; element_ptr item_ptr = (element_ptr) malloc(sizeof(element)); assert(item_ptr); //assign values to the members of protocol element item_ptr -> proto = app_proto; item_ptr -> in_byte = in_byte; item_ptr -> out_byte = out_byte; item_ptr -> in_pack = pack_in; item_ptr -> out_pack = pack_out; //link it to the list curr_ptr -> next_proto = item_ptr; item_ptr -> next_proto = NULL; curr_ptr = item_ptr; *rear_ptr = curr_ptr; return item_ptr;}//query a certified element of listbool query_proto(struct ip_list *list, UINT1 app_proto, element_ptr *same)...{ element_ptr curr_ptr = list -> next_proto; int i = 0; while(curr_ptr != NULL ) ...{ if(curr_ptr->proto == app_proto) ...{ *same = curr_ptr; return true; } curr_ptr = curr_ptr -> next_proto; } return false;}/**//****************************************************************************///heap sort,operate on flux tablevoid heap_sort(struct ip_flux flux_table[], struct ip_flux extra_table[], struct ip_flux topn_flux_table[], int flux_table_len, int topn)...{ int extra_len; int i, j, temp, end; int flag; flag = i = j = temp = end = 0; int top_n = topn; if( (flux_table_len%2) ==0 ) ...{ extra_len = flux_table_len - 1; } else ...{ extra_len = flux_table_len; } while( topn-- > 0) ...{ for(i=0; i<flux_table_len; i+=2) ...{ if(i+1 > flux_table_len) ...{ extra_table[j].index = flux_table[i].index; extra_table[j].ip_num = flux_table[i].ip_num; extra_table[j].flux = flux_table[i].flux; } else ...{ if(flux_table[i].flux >= flux_table[i+1].flux) ...{ extra_table[j].index = flux_table[i].index; extra_table[j].ip_num = flux_table[i].ip_num; extra_table[j].flux = flux_table[i].flux; } else ...{ extra_table[j].index = flux_table[i+1].index; extra_table[j].ip_num = flux_table[i+1].ip_num; extra_table[j].flux = flux_table[i+1].flux; } } ++j; } while(j < extra_len) ...{ end = j; for(; temp<end; temp+=2) ...{ if(temp+1 >= end) ...{ flag = 1; break; } else ...{ if(extra_table[temp].flux >= extra_table[temp+1].flux) ...{ extra_table[j].index = extra_table[temp].index; extra_table[j].ip_num = extra_table[temp].ip_num; extra_table[j].flux = extra_table[temp].flux; } else ...{ extra_table[j].index = extra_table[temp+1].index; extra_table[j].ip_num = extra_table[temp+1].ip_num; extra_table[j].flux = extra_table[temp+1].flux; } } ++j; } if(flag == 1) ...{ temp = end - 1; } else ...{ temp = end; } flag = 0; } (*(&flux_table[extra_table[extra_len-1].index])).flux = 0; //set the biggest flux element owning smallest flux insert_sort(topn_flux_table, top_n, extra_table[extra_len-1]); flag = i = j = temp = end = 0; //reset all variables }}/**//*****************************************************************************///insert sort void insert_sort(struct ip_flux topn_table[], int topn, struct ip_flux max_flux)...{ int low = 0; int high = topn - 1; int mid = 0; int insert_pos; //insert position while(low <= high) ...{ mid = (low+high)/2; if(max_flux.flux == topn_table[mid].flux) ...{ insert_to_pos(topn_table, max_flux, high, mid); return; } else if(max_flux.flux > topn_table[mid].flux) ...{ high = mid - 1; } else ...{ low = mid + 1; } } insert_pos = (low>high) ? low : high; high = topn - 1; insert_to_pos(topn_table, max_flux, high, insert_pos);}/**//*****************************************************************************/void insert_to_pos(struct ip_flux topn_table[], struct ip_flux max_flux, int high, int insert_pos)...{ int i = 0; for(i=high; i>insert_pos; --i) ...{ topn_table[i].index = topn_table[i-1].index; topn_table[i].ip_num = topn_table[i-1].ip_num; topn_table[i].flux = topn_table[i-1].flux; } //insert the max to pos mid topn_table[insert_pos].index = max_flux.index; topn_table[insert_pos].ip_num = max_flux.ip_num; topn_table[insert_pos].flux = max_flux.flux;}/**//*****************************************************************************///count the size of a fileUINT4 count_file_size(const string file_name)...{ int file_size = 0; struct stat file_stat; stat(file_name, &file_stat); file_size = file_stat.st_size; return file_size;}/**//*****************************************************************************///get the ip sting according to ip numberstring ipnum_to_ipstr(UINT4 ip_num)...{ string ip_str = (string)malloc(16*sizeof(char)); UINT4 ip_host_num = ntohl(ip_num); //convert the net format to host format struct in_addr ip_addr; ip_addr.s_addr = ip_host_num; strcpy(ip_str, inet_ntoa(ip_addr)); return ip_str;}/**//*****************************************************************************/void free_space(struct iplist_head *hash_table, struct ip_flux *flux_table, struct ip_flux *topn_table)...{ //free hash table UINT4 i; struct ip_list *curr_hash_ptr=NULL, *temp_hash_ptr=NULL; for(i=0; i<65536; ++i) ...{ if(hash_table[i].hash_element == NULL) ...{ continue; } else ...{ curr_hash_ptr = hash_table[i].hash_element; for(; curr_hash_ptr!=NULL; curr_hash_ptr=temp_hash_ptr) ...{ temp_hash_ptr = curr_hash_ptr -> next_proto; free(curr_hash_ptr); } temp_hash_ptr = curr_hash_ptr = NULL; } } free(hash_table); hash_table = NULL; //free flux_table free(flux_table); flux_table = NULL; //free topn table free(topn_table); topn_table = NULL;}