#include <pcap.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/syslog.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
#include <pthread.h>

/**/typedef struct value{  
u_int32_t sip;                                 /*源IP*/  
unsigned long long packets;                    /* 报数 */  
unsigned long long tcp;              
unsigned long long udp;  
unsigned long long icmp;  
unsigned long long other;  
unsigned long long bytes;                      /* 流量 */
}value;

/*  */
typedef struct{  
value v;                        /* 结构体 value*/  
unsigned long long fpacket;     /* 进包数 */  
unsigned long long fbytes;      /* 进流量 */
}xvalue;

#define HASHSIZE 10000        /* hash表大小 */
#define HASHSIZEIN 1000       /* hash表大小 */

/*自定义结构体 */
typedef struct node{  
u_int32_t ip;                                         
// ip地址,次结构体记录Ip对应的以下属性   
unsigned long long bytes;                  /* 字节数 */  
unsigned long long packets;                /* 数据包数 */  
unsigned long long fbytes;                 /* 进流量 */  
unsigned long long fpacket;                /* 进包数 */  
unsigned long long tcp;                    /*  是否为tcp协议 */  
unsigned long long udp;                    /* 是否为udp协议 */  
unsigned long long icmp;                   /* 是否为icmp协议 */  
unsigned long long other;                  /* 其他 */  
struct node *next;                         /* 下一个节点指针 */
}htnode;

typedef htnode **hashtable;
unsigned  long long     in_bytes;           //进网流量
unsigned  long long     in_packets;         //进网包数
unsigned  long long    out_bytes;           //出网流量
unsigned  long long    out_packets=0;       //出网包数
bpf_u_int32 netp,maskp;       /* 网络地址 , 子网掩码*/
hashtable ht,ht_out;  
pthread_mutex_t hash_lock;    /*线程锁*/

pthread_attr_t attr;
sigset_t mask_sig;
int hash(u_int32_t ip, int size) {  
  return ip % size;
}
htnode * hashtable_search(hashtable T, int size, u_int32_t ip){  
    htnode *p=T[hash(ip, size)];  
    while(p!=NULL && p->ip!=ip)    
    p=p->next;  
    return p;
}
int hashtable_insert(hashtable T, int size, htnode *s) {
    int d;  
    htnode *p=hashtable_search(T, size, s->ip);  
    if(p!=NULL){    
      p->fbytes  += s->fbytes;    
      p->fpacket += s->fpacket;    
      p->bytes   += s->bytes;    
      p->packets += s->packets;    
      p->tcp     += s->tcp;    
      p->udp     += s->udp;