用pcap监控端口流量

要对莫个端口监视端口流量,有不想在程序了动手术,唯有用pcap开刀,简单写个pcap的程序

监控端口和端口+1两个端口的连接实时流量。下面的程序直接可以编译。

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>
#include <signal.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#include <sys/utsname.h>
#include <linux/sockios.h>
#include <sys/resource.h>
#include <pcap.h>
#include <pthread.h>
#include <ncurses.h>


/* hack, so we may include kernel's ethtool.h */
typedef unsigned long long __u64;
typedef __uint32_t __u32;
typedef __uint16_t __u16;
typedef __uint8_t __u8;

/* historical: we used to use kernel-like types; remove these once cleaned */
typedef unsigned long long u64;
typedef __uint32_t u32;
typedef __uint16_t u16;
typedef __uint8_t u8;

typedef __uint32_t u_int32_t;
typedef __uint16_t u_int16_t;
typedef __uint8_t  u_int8_t;

/*  ethernet header define from ether.h*/
#define    ETHERTYPE_PUP        0x0200  
#define    ETHERTYPE_IP        0x0800
#define    ETHERTYPE_ARP        0x0806
#define    ETHERTYPE_REVARP    0x8035
#define    ETHER_ADDR_LEN        6

struct    ether_header {
    u_int8_t    ether_dhost[ETHER_ADDR_LEN];
    u_int8_t    ether_shost[ETHER_ADDR_LEN];
    u_int16_t    ether_type;
};

struct vlan_8021q_header {
    u_int16_t    priority_cfi_vid;
    u_int16_t    ether_type;
};

/*
 * Definitions for internet protocol version 4.
 * Per RFC 791, September 1981.
 */
#define    IPVERSION    4

/*
 * Structure of an internet header, naked of options.
 *
 * We declare ip_len and ip_off to be short, rather than u_short
 * pragmatically since otherwise unsigned comparisons can result
 * against negative integers quite easily, and fail in subtle ways.
 */
struct ip {
    u_int8_t    ip_vhl;        /* header length, version */
#define IP_V(ip)    (((ip)->ip_vhl & 0xf0) >> 4)
#define IP_HL(ip)    ((ip)->ip_vhl & 0x0f)
    u_int8_t    ip_tos;        /* type of service */
    u_int16_t    ip_len;        /* total length */
    u_int16_t    ip_id;        /* identification */
    u_int16_t    ip_off;        /* fragment offset field */
#define    IP_DF 0x4000        /* dont fragment flag */
#define    IP_MF 0x2000        /* more fragments flag */
#define    IP_OFFMASK 0x1fff    /* mask for fragmenting bits */
    u_int8_t    ip_ttl;        /* time to live */
    u_int8_t    ip_p;        /* protocol */
    u_int16_t    ip_sum;        /* checksum */
    struct    in_addr ip_src,ip_dst;    /* source and dest address */
};

#define    IP_MAXPACKET    65535        /* maximum packet size */

/*
 * Definitions for IP type of service (ip_tos)
 */
#define    IPTOS_LOWDELAY                0x10
#define    IPTOS_THROUGHPUT            0x08
#define    IPTOS_RELIABILITY            0x04

/*
 * Definitions for IP precedence (also in ip_tos) (hopefully unused)
 */
#define    IPTOS_PREC_NETCONTROL        0xe0
#define    IPTOS_PREC_INTERNETCONTROL    0xc0
#define    IPTOS_PREC_CRITIC_ECP        0xa0
#define    IPTOS_PREC_FLASHOVERRIDE    0x80
#define    IPTOS_PREC_FLASH            0x60
#define    IPTOS_PREC_IMMEDIATE        0x40
#define    IPTOS_PREC_PRIORITY            0x20
#define    IPTOS_PREC_ROUTINE            0x00

/*
 * Definitions for options.
 */
#define    IPOPT_COPIED(o)        ((o)&0x80)
#define    IPOPT_CLASS(o)        ((o)&0x60)
#define    IPOPT_NUMBER(o)        ((o)&0x1f)

#define    IPOPT_CONTROL        0x00
#define    IPOPT_RESERVED1        0x20
#define    IPOPT_DEBMEAS        0x40
#define    IPOPT_RESERVED2        0x60

#define    IPOPT_EOL        0        /* end of option list */
#define    IPOPT_NOP        1        /* no operation */
#define    IPOPT_RR        7        /* record packet route */
#define    IPOPT_TS        68        /* timestamp */
#define    IPOPT_SECURITY    130        /* provide s,c,h,tcc */
#define    IPOPT_LSRR        131        /* loose source route */
#define    IPOPT_SATID        136        /* satnet id */
#define    IPOPT_SSRR        137        /* strict source route */

/*
 * Offsets to fields in options other than EOL and NOP.
 */
#define    IPOPT_OPTVAL    0        /* option ID */
#define    IPOPT_OLEN        1        /* option length */
#define IPOPT_OFFSET    2        /* offset within option */
#define    IPOPT_MINOFF    4        /* min value of above */

/*
 * Time stamp option structure.
 */
struct    ip_timestamp {
    u_int8_t    ipt_code;        /* IPOPT_TS */
    u_int8_t    ipt_len;        /* size of structure (variable) */
    u_int8_t    ipt_ptr;        /* index of current entry */
    u_int8_t    ipt_oflwflg;    /* flags, overflow counter */
#define IPTS_OFLW(ip)    (((ipt)->ipt_oflwflg & 0xf0) >> 4)
#define IPTS_FLG(ip)    ((ipt)->ipt_oflwflg & 0x0f)
    union ipt_timestamp {
        u_int32_t ipt_time[1];
        struct    ipt_ta {
            struct in_addr ipt_addr;
            u_int32_t ipt_time;
        } ipt_ta[1];
    } ipt_timestamp;
};

/* flag bits for ipt_flg */
#define    IPOPT_TS_TSONLY        0    /* timestamps only */
#define    IPOPT_TS_TSANDADDR    1    /* timestamps and addresses */
#define    IPOPT_TS_PRESPEC    3    /* specified modules only */

/* bits for security (not byte swapped) */
#define    IPOPT_SECUR_UNCLASS        0x0000
#define    IPOPT_SECUR_CONFID        0xf135
#define    IPOPT_SECUR_EFTO        0x789a
#define    IPOPT_SECUR_MMMM        0xbc4d
#define    IPOPT_SECUR_RESTR        0xaf13
#define    IPOPT_SECUR_SECRET        0xd788
#define    IPOPT_SECUR_TOPSECRET    0x6bc5

/*
 * Internet implementation parameters.
 */
#define    MAXTTL        255            /* maximum time to live (seconds) */
#define    IPDEFTTL    64            /* default ttl, from RFC 1340 */
#define    IPFRAGTTL    60            /* time to live for frags, slowhz */
#define    IPTTLDEC    1            /* subtracted when forwarding */
#define    IP_MSS        576            /* default maximum segment size */
/*
 *  @(#)tcp.h 8.1 (Berkeley) 6/10/93
 */
typedef    u_int32_t    tcp_seq;

/*
 * TCP header.
 * Per RFC 793, September, 1981.
 */
struct tcphdr {
    u_int16_t    th_sport;        /* source port */
    u_int16_t    th_dport;        /* destination port */
    tcp_seq        th_seq;            /* sequence number */
    tcp_seq        th_ack;            /* acknowledgement number */
    u_int8_t    th_offx2;        /* data offset, rsvd */
#define TH_OFF(th)    (((th)->th_offx2 & 0xf0) >> 4)
    u_int8_t    th_flags;
#define    TH_FIN        0x01
#define    TH_SYN        0x02
#define    TH_RST        0x04
#define    TH_PUSH        0x08
#define    TH_ACK        0x10
#define    TH_URG        0x20
#define TH_ECNECHO    0x40        /* ECN Echo */
#define TH_CWR        0x80        /* ECN Cwnd Reduced */
    u_int16_t    th_win;            /* window */
    u_int16_t    th_sum;            /* checksum */
    u_int16_t    th_urp;            /* urgent pointer */
};

#define    TCPOPT_EOL            0
#define    TCPOPT_NOP            1
#define    TCPOPT_MAXSEG        2
#define TCPOLEN_MAXSEG        4
#define    TCPOPT_WSCALE        3    /* window scale factor (rfc1323) */
#define    TCPOPT_SACKOK        4    /* selective ack ok (rfc2018) */
#define    TCPOPT_SACK            5    /* selective ack (rfc2018) */
#define    TCPOPT_ECHO            6    /* echo (rfc1072) */
#define    TCPOPT_ECHOREPLY    7    /* echo (rfc1072) */
#define TCPOPT_TIMESTAMP    8    /* timestamp (rfc1323) */
#define TCPOLEN_TIMESTAMP    10
#define TCPOLEN_TSTAMP_APPA    (TCPOLEN_TIMESTAMP+2) /* appendix A */
#define TCPOPT_CC            11    /* T/TCP CC options (rfc1644) */
#define TCPOPT_CCNEW        12    /* T/TCP CC options (rfc1644) */
#define TCPOPT_CCECHO        13    /* T/TCP CC options (rfc1644) */
#define TCPOPT_TSTAMP_HDR    /
    (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
   


struct if_stats
{
    char devname[10];   
    unsigned long long rx_packets;
    unsigned long long tx_packets;
    unsigned long long rx_bytes;
    unsigned long long tx_bytes;
    unsigned long long rx_errors;
    unsigned long long tx_errors;
    unsigned long long rx_dropped;
    unsigned long long tx_dropped;
    unsigned long long rx_fifo;
    unsigned long long tx_fifo;
    unsigned long long rx_frame;
    unsigned long long tx_colls;
    unsigned long long rx_multicast;
    unsigned long long tx_carrier;
    unsigned long long rx_compressed;
    unsigned long long tx_compressed;
    unsigned int link;
    struct if_stats* next;
};

struct iface_dev
{
    char name[16];
    struct in_addr ip;
    struct in_addr netmask;
    unsigned int link;
    struct iface_dev* next;
};

/* This should work for both 32 and 64 bit userland. */
struct ethtool_cmd
{
    __u32    cmd;
    __u32    supported;    /* Features this interface supports */
    __u32    advertising;/* Features this interface advertises */
    __u16    speed;        /* The forced speed, 10Mb, 100Mb, gigabit */
    __u8    duplex;        /* Duplex, half or full */
    __u8    port;        /* Which connector port */
    __u8    phy_address;
    __u8    transceiver;/* Which transceiver to use */
    __u8    autoneg;    /* Enable or disable autonegotiation */
    __u32    maxtxpkt;    /* Tx pkts before generating tx int */
    __u32    maxrxpkt;    /* Rx pkts before generating rx int */
    __u32    reserved[4];
};

/* for passing single values */
struct ethtool_value
{
    __u32    cmd;
    __u32    data;
};

union iaddr
{
    unsigned u;
    unsigned char b[4];
};

struct tcp_stat
{
    //unsigned int ip;
    struct in_addr ip;
    unsigned short int port;
    unsigned short int dport;
    unsigned long long recv_bytes;
    unsigned long long sent_bytes;
    unsigned long long total_sent;
    unsigned long long total_recv;   
   
    unsigned long long pre_recv_bytes;
    unsigned long long pre_sent_bytes;
    unsigned long long pre_total_sent;
    unsigned long long pre_total_recv;   
    time_t start_time;
    struct tcp_stat* next;
};

struct vstate
{
    struct iface_dev st_ndev;
    struct tcp_stat st_tcp;
};

int running = 1;   
int options = 0;
uid_t vsuid = 0;
pid_t vspid = 0;
int vsport = 0;
int intetval = 3;
char vsbuf[2046];
char head_line[1024];
char vsdev[10];
char *vsline = vsbuf;
struct vstate vst;
FILE* logfile = NULL;
char* app_name;

/* pcap descriptor */
pcap_t* pd = 0;
pcap_handler packet_handler;
#define CAPTURE_LENGTH 72

/* ethernet address of interface. */
int have_hw_addr = 1;
unsigned char if_hw_addr[6];

/* IP address of interface */
int have_ip_addr = 0;
struct in_addr if_ip_addr;

/* ethernet address of gateway. */
int have_gw_addr = 1;
struct in_addr if_gw_addr;

int get_addrs_ioctl(char *interface, unsigned char* if_hw_addr, struct in_addr *if_ip_addr)
{
    struct ifreq ifr = {};
    int got_hw_addr = 0;
    int got_ip_addr = 0;

    int s = socket(PF_INET, SOCK_DGRAM, 0); /* any sort of IP socket will do */
    if (s == -1) {
        printf("create a socket error/n");
        return -1;
    }

    memset(if_hw_addr, 0, 6);
    strncpy(ifr.ifr_name, interface, IFNAMSIZ);

    if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
        printf( "Error getting hardware address for interface: %s/n", interface);        
    }
    else {
        memcpy(if_hw_addr, ifr.ifr_hwaddr.sa_data, 6);
        got_hw_addr = 1;
    }

    /* Get the IP address of the interface */
    (*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = AF_INET;
    if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
        printf( "Unable to get IP address for interface: %s/n", interface);
    }
    else {
        memcpy(if_ip_addr, &((*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr), sizeof(struct in_addr));
        got_ip_addr = 2;
    }

    close(s);
    return got_hw_addr + got_ip_addr;
}

int get_gateway_addr(const char *dev)
{
    char ifname[64];
    in_addr_t dest, gway, mask;
    int flags, refcnt, use, metric, mtu, win, irtt;
    FILE *fp;
    if_gw_addr.s_addr = 0;
   
    fp = fopen("/proc/net/route", "r");
    if (fp == NULL)
        return -1;
       
    /* Skip the header line */
    if (fscanf(fp, "%*[^/n]/n") < 0) {
        fclose(fp);
        return -1;
    }
   
    while(1){
        int nread = fscanf(fp, "%63s%X%X%X%d%d%d%X%d%d%d/n",
                           ifname, &dest, &gway, &flags, &refcnt, &use, &metric, &mask,
                           &mtu, &win, &irtt);
        if (nread != 11)
            break;
       
        if(strcmp(ifname, dev) == 0 && gway){
            if_gw_addr.s_addr = gway;
            printf("%s gateway %s/n",dev,inet_ntoa(if_gw_addr));
            break;
        }             
    }
   
    fclose(fp);   
    return 0;
}



int ip_addr_match(struct in_addr addr) {
    return addr.s_addr == if_ip_addr.s_addr;
}

struct tcp_stat* get_tcp_stat(struct in_addr* ip,unsigned short int port,unsigned short int dport)
{
    struct tcp_stat *st_tcp = &vst.st_tcp;
    static struct tcp_stat *st_tcp_end = &vst.st_tcp;
   
    while (st_tcp){       
        if(st_tcp->ip.s_addr == ip->s_addr && st_tcp->port == port)
            return st_tcp;
        else
            st_tcp = st_tcp->next;
    }
   
    struct tcp_stat *st_new = 0;
    st_new = malloc(sizeof(struct tcp_stat));
    memset(st_new,0,sizeof(struct tcp_stat));       
    st_new->start_time = time(0);
    st_new->ip = *ip;
    st_new->port = port;
    st_new->dport =    dport;
   
    st_tcp_end->next = st_new;   
    st_tcp_end = st_new;
    return st_new;
}

inline struct tcp_stat* get_tcp_stat_head(struct in_addr* ip,unsigned short int port)
{
    struct tcp_stat *st_tcp = &vst.st_tcp;
    return st_tcp;
}

void calculate_tcp_rate(struct tcp_stat *tcp_stats)
{
    int row = 1;
    int nport1 = 0, nport2=0;
    double rx_bytes,tx_bytes;
    double rx_tbytes,tx_tbytes;
    double rx_port1 = 0,tx_port1 = 0;
    double rx_port2 = 0,tx_port2 = 0;
    double rx_tport1 = 0,tx_tport1 = 0;
    double rx_tport2 = 0,tx_tport2 = 0;
   
    struct tcp_stat *st_tcp = NULL;
    st_tcp = tcp_stats->next ? tcp_stats->next : NULL;
                  
    mvprintw(0,1,head_line);
   
    while (st_tcp){
        rx_bytes = st_tcp->recv_bytes - st_tcp->pre_recv_bytes;
        tx_bytes = st_tcp->sent_bytes - st_tcp->pre_sent_bytes;   
       
        rx_bytes /= (1024*intetval);
        tx_bytes /= (1024*intetval);
               
        st_tcp->pre_recv_bytes = st_tcp->recv_bytes;
        st_tcp->pre_sent_bytes = st_tcp->sent_bytes;

        rx_tbytes = st_tcp->total_recv/1024;
        tx_tbytes = st_tcp->total_sent/1024;
        time_t period = time(0) - st_tcp->start_time;           
       
        if(st_tcp->port == vsport+1 || st_tcp->dport == vsport+1){
            rx_port2 += rx_bytes;
            tx_port2 +=    tx_bytes;
            rx_tport2 += rx_tbytes;
            tx_tport2 += tx_tbytes;           
            nport2++;   
        }else{
            rx_port1 += rx_bytes;
            tx_port1 +=    tx_bytes;           
            rx_tport1 += rx_tbytes;
            tx_tport1 += tx_tbytes;
            nport1++;       
        }
       
        char c = ' ';
        if(st_tcp->port== vsport+1 || st_tcp->dport== vsport+1)
            c = 'B';
        else
            c = 'F';
           
        mvprintw(row,1,"%c %3d %15s :%5d %8.1fk %8.1fk %9.1fM %9.1fM %9.1fk %9.1fk",
            c,
            row,
            inet_ntoa(st_tcp->ip),st_tcp->port,
            rx_bytes,tx_bytes,rx_tbytes/1024,tx_tbytes/1024,
            rx_tbytes/period,tx_tbytes/period);
        row++;
        st_tcp = st_tcp->next;
    }
       
    //mvprintw(row++,1,"--------------------------------------------------------------------------------------------");   
    mvprintw(row++,1,"                                                                                            ");
    mvprintw(row++,1,"  ALL %15s :%5d %8.1fk %8.1fk %9.1fM %9.1fM","PORT  ", vsport,
        rx_port1,tx_port1,rx_tport1/1024,tx_tport1/1024);
   
    mvprintw(row++,1,"  ALL %15s :%5d %8.1fk %8.1fk %9.1fM %9.1fM","PORT  ", vsport+1,
        rx_port2,tx_port2,rx_tport2/1024,tx_tport2/1024);
    refresh();
}

void handle_ip_packet(struct ip* iptr, int hw_dir)
{
    int len;
    struct tcp_stat *st,*sa;
    //unsigned int ip = 0;
    struct in_addr ip;
    unsigned short int port = 0;
    unsigned short int dport = 0;

    /* Does this protocol use ports? */
    if(iptr->ip_p != IPPROTO_TCP)
        return;
   
    /* We take a slight liberty here by treating UDP the same as TCP */
    /* Find the TCP/UDP header */
    struct tcphdr* thdr = ((void*)iptr) + IP_HL(iptr) * 4;
   
    if(hw_dir == 0) {
        /* Packet incoming this interface. */
        ip = iptr->ip_src;
        port = ntohs(thdr->th_sport);
        dport= ntohs(thdr->th_dport);
        if(ip.s_addr == if_gw_addr.s_addr)
            return;               
    }
    else if(hw_dir == 1) {
        /* Packet leaving*/
        ip = iptr->ip_dst;
        port = ntohs(thdr->th_dport);
        dport= ntohs(thdr->th_sport);
        if(ip.s_addr == if_gw_addr.s_addr)
            return;       
    }
   
    /* Add the addresses to be resolved */
    st = get_tcp_stat(&ip,port,dport);
    sa = get_tcp_stat_head(&ip,port);
   
    len = ntohs(iptr->ip_len);
    if(st == NULL)
        return;
       
    //printf("%s:%d len %d/n",inet_ntoa(ip),port,len);
    /* Update record */
    if(hw_dir) {       
        st->sent_bytes += len;  /*leaving*/
        st->total_sent += len;
        sa->total_sent += len;       
    }
    else {       
        st->recv_bytes += len; /*entering*/
        st->total_recv += len;
        sa->total_recv += len;
    }
}

void handle_eth_packet(unsigned char* args, const struct pcap_pkthdr* pkthdr, const unsigned char* packet)
{
    struct ether_header *eptr;
    int ether_type;
    const unsigned char *payload;
    eptr = (struct ether_header*)packet;
    ether_type = ntohs(eptr->ether_type);
    payload = packet + sizeof(struct ether_header);

    if(ether_type == ETHERTYPE_IP) {
        struct ip* iptr;
        int dir = -1;
       
        /*
        * Is a direction implied by the MAC addresses?
        */
        if(have_hw_addr && memcmp(eptr->ether_shost, if_hw_addr, 6) == 0 ) {
            /* packet leaving this i/f */
            dir = 1;
        }
        else if(have_hw_addr && memcmp(eptr->ether_dhost, if_hw_addr, 6) == 0 ) {
            /* packet entering this i/f */
            dir = 0;
        }
        else if (memcmp("/xFF/xFF/xFF/xFF/xFF/xFF", eptr->ether_dhost, 6) == 0) {
            /* broadcast packet, count as incoming */
            dir = 0;
        }

        iptr = (struct ip*)(payload); /* alignment? */
        handle_ip_packet(iptr, dir);
    }   
    else if (ether_type == ETHERTYPE_ARP)
    {
        /*printf ("Ethernet type hex:%x dec:%d is an ARP packet/n");*/
    }
    else{
        /*printf ("Ethernet type %x not IP/n");*/
    }   
}

/*
 * packet_init: performs pcap initialisation, called before ui is initialised
 */
int packet_init(char* dev)
{
    int result = -1;
    int promisc = 0; /* set to promisc mode?*/
    char errbuf[PCAP_ERRBUF_SIZE];
   
    /* get network card interface*/
    have_hw_addr = 1;
    result = get_addrs_ioctl(dev, if_hw_addr, &if_ip_addr);
    if (result < 0)
        return -1;

    /* get interface gateway address*/
    result = get_gateway_addr(dev);
    if (result < 0)
        return -1;
   
    /* open interface with pcap*/
    pd = pcap_open_live(dev, CAPTURE_LENGTH, promisc, 1000, errbuf);
    if(pd == NULL) {
        printf("pcap_open_live(%s): %s/n", dev, errbuf);
        return -1;
    }
   
    /* set callback handle function*/
    packet_handler = handle_eth_packet;
   
    sprintf(head_line,"%s %15s %5s %7s %7s %7s %7s %7s %7s/n",
              "# ###"," dstination ip","port"," recv(k/s)","sent(k/s)","recv total","sent total","in avg(k/s)","out avg(k/s)/n");
              /*"# ###","dst ip       port - port","recv(k/s)","sent(k/s)","recv total","sent total","in avg(k/s)","out avg(k/s)/n");*/
    return 0;
}

int packet_filter(char* dev,int port)
{
    struct bpf_program* fp;              /* The compiled filter expression */
    char filter_exp[20] = "port 13948";/* The filter expression */
    bpf_u_int32 mask;                 /* The netmask of our sniffing device */
    bpf_u_int32 net;                 /* The IP of our sniffing device */
    char errbuf[PCAP_ERRBUF_SIZE];
   
    /* get device ip/mask*/
    if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
         printf("Can't get netmask for device %s/n", dev);
         net = 0;
         mask = 0;
         return -1;
    }
   
    /* compile filter exp*/
    sprintf(filter_exp,"portrange %d-%d",port,port+1);
    fp = malloc(sizeof(struct bpf_program));
    if (pcap_compile(pd, fp, filter_exp, 0, net) == -1) {
        printf("Couldn't parse filter %s: %s/n", filter_exp, pcap_geterr(pd));
        return -1;
    }

    /* set filter for port*/
    if (pcap_setfilter(pd, fp) == -1) {
        printf("Couldn't install filter %s: %s/n", filter_exp, pcap_geterr(pd));
        return -1;
    }
     
    return 0;
}

/* packet_loop:  * Worker function for packet capture thread. */
void* packet_loop(void* ptr)
{
    /* loop pcap tcp/ip*/
    while(running) {
        pcap_loop(pd,-1,(pcap_handler)packet_handler,NULL);
    }
    return 0;
}

void print_usage()
{
    printf(" Options:/n");
    printf("  -d     indicate net device name/n");
    printf("  -p     indicate port/n");
    printf("  -v     print version/n");
    printf("  -h     printf help/n/n");
    printf("sample: -d /"eth0/" -p 8899/n/n");
}
   
int get_options(int argc,char **argv)
{
    int ret,opt = 0;
    /* read options */
    while((ret = getopt(argc, argv, "d:p:h")) >= 0) {
        switch(ret) {
        case 'd':
            strcpy(vsdev,optarg);
            opt++;
            break;               
        case 'p':
            vsport = atoi(optarg);
            opt++;
            break;                               
        case 'h':
            print_usage();
            return -1;
        default:
            /* shouldn't happen */
            return -1;
        }
    }
    if(opt == 2)
        return 0;
    return ret;
}

void sig_handler(int sig)
{
    switch(sig) {
        case SIGHUP:
        case SIGTERM:
        case SIGINT:
        case SIGQUIT:
        case SIGUSR1:
        case SIGSEGV:
            running = 0;
            usleep(300000);
            if(pd != NULL)
            pcap_close(pd);           
            break;
        default:
            break;
    }
}

int main(int argc,char **argv)
{       
    vsline = vsbuf;   
    running = 1;
   
    signal(SIGHUP,  sig_handler);
    signal(SIGTERM, sig_handler);
    signal(SIGINT,  sig_handler);
    signal(SIGQUIT, sig_handler);
    signal(SIGUSR1, sig_handler);
    signal(SIGSEGV, sig_handler);
   
    /* get vstat options*/
    if(get_options(argc,argv) != 0){
        printf("Type vpstat -h for help./n");
        return 0;
    }
   
    /* init vst struct*/
    memset(&vst,0,sizeof(struct vstate));

    /* init pacp with device*/
    if(packet_init(vsdev) == -1)
        return -1;
   
    /* set filter for device*/
    if(packet_filter(vsdev,vsport) == -1)
        return -1;
   
    initscr();
   
    /* create pcap thread*/
    pthread_t tid;
    pthread_create(&tid,NULL,packet_loop,(void*)NULL);
   
    /* loop get pid stat*/
    while(running) {       
        /* print proc stat info*/
        usleep(1000000*intetval);
        calculate_tcp_rate(&vst.st_tcp);
    }

    endwin();   
    return EXIT_SUCCESS;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值