#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_stat
typedef 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 list
typedef 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 head
typedef struct iplist_head
... {
UINT4 ip;
element_ptr rear;
struct ip_list *hash_element;
} * iplist_head_p;
// ip_flux
typedef 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 file
void read_file( const string file_name, UINT4 file_size, UINT4 read_size, int top_n);
// deal with the hash table
void deal_iplist(flow ip_flow, struct iplist_head hash_table[], UINT4 ip);
// ip_hash code
UINT2 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 string
string protonum_to_proto(UINT1 proto);
// ===============operate the ip list====================
// make a ip list
struct ip_list * make_list(element_ptr * rear_ptr);
// 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);
// query a ip list whether it has already set the protocol
bool query_proto( struct ip_list * list, UINT1 app_proto, element_ptr * same);
// ======================================================
// heap sort,operate on hash table
void 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 table
void insert_sort( struct ip_flux topn_table[], int topn, struct ip_flux max_flux);
// insert the max to topn table
void insert_to_pos( struct ip_flux topn_table[], struct ip_flux max_flux, int high, int insert_pos);
// return the size of a file
UINT4 count_file_size( const string file_name);
// return a IP string
string ipnum_to_ipstr(UINT4 ip_num);
void free_space( struct iplist_head * hash_table, struct ip_flux * flux_table, struct ip_flux * topn_table);
/**/ /**********************************************************************/
// main
int 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 file
void 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 information
int 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 hash
UINT2 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 list
bool 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 table
void 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 file
UINT4 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 number
string 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;
}
#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_stat
typedef 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 list
typedef 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 head
typedef struct iplist_head
... {
UINT4 ip;
element_ptr rear;
struct ip_list *hash_element;
} * iplist_head_p;
// ip_flux
typedef 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 file
void read_file( const string file_name, UINT4 file_size, UINT4 read_size, int top_n);
// deal with the hash table
void deal_iplist(flow ip_flow, struct iplist_head hash_table[], UINT4 ip);
// ip_hash code
UINT2 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 string
string protonum_to_proto(UINT1 proto);
// ===============operate the ip list====================
// make a ip list
struct ip_list * make_list(element_ptr * rear_ptr);
// 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);
// query a ip list whether it has already set the protocol
bool query_proto( struct ip_list * list, UINT1 app_proto, element_ptr * same);
// ======================================================
// heap sort,operate on hash table
void 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 table
void insert_sort( struct ip_flux topn_table[], int topn, struct ip_flux max_flux);
// insert the max to topn table
void insert_to_pos( struct ip_flux topn_table[], struct ip_flux max_flux, int high, int insert_pos);
// return the size of a file
UINT4 count_file_size( const string file_name);
// return a IP string
string ipnum_to_ipstr(UINT4 ip_num);
void free_space( struct iplist_head * hash_table, struct ip_flux * flux_table, struct ip_flux * topn_table);
/**/ /**********************************************************************/
// main
int 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 file
void 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 information
int 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 hash
UINT2 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 list
bool 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 table
void 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 file
UINT4 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 number
string 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;
}