Flow文件分析處理程序

#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章