/* Return a well formatted string with a time difference at millisecond resolution */ char * elapsed_time (struct timeval * start, struct timeval * stop) { static char et [64]; time_t elapsed = delta_time_in_milliseconds (stop, start); if (time_day (elapsed)) sprintf (et, "%d days, %02d:%02d:%02d.%03ld", time_day (elapsed), time_hour (elapsed), time_min (elapsed), time_sec (elapsed), time_usec (elapsed)); else if (time_hour (elapsed)) sprintf (et, "%02d:%02d:%02d.%03ld", time_hour (elapsed), time_min (elapsed), time_sec (elapsed), time_usec (elapsed)); else if (time_min (elapsed)) sprintf (et, "%02d:%02d.%03ld", time_min (elapsed), time_sec (elapsed), time_usec (elapsed)); else if (time_sec (elapsed)) sprintf (et, "%d.%03d secs", time_sec (elapsed), time_msec (elapsed)); else sprintf (et, "%3d msecs", time_msec (elapsed)); return et; }
static void sniffer_callback (int unused, const short event, void * _interface) { interface_t * interface = _interface; pcap_t * pcap = interface -> pcap; struct pcap_pkthdr header; const unsigned char * packet; double delta; if (! interface -> maxcount || (interface -> partial + interface -> errors) < interface -> maxcount) { /* Please pcap give me next packet from the interface */ if ((packet = pcap_next (pcap, & header))) { interface -> partial ++; if (! (interface -> partial % hb)) { static unsigned long previous = 0; static struct timeval latest; struct timeval now; /* Show pkts/secs in the latest period */ gettimeofday (& now, NULL); delta = delta_time_in_milliseconds (& now, & latest); if (interface -> maxcount) printf ("%s: pkts rcvd #%lu of #%lu %s", progname, interface -> partial, interface -> maxcount, xpercentage (interface -> partial, interface -> maxcount)); else printf ("%s: pkts rcvd #%lu %s", progname, interface -> partial, xpercentage (interface -> partial, interface -> maxcount)); if (previous && delta) printf (" [%8.2f pkts/sec => +%lu pkts in %s]", (double) (interface -> partial - previous) * 1000 / delta, interface -> partial - previous, elapsed_time (& latest, & now)); printf ("\n"); previous = interface -> partial; latest = now; } } else interface -> errors ++; } else { gettimeofday (& interface -> stopped, NULL); delta = (double) delta_time_in_milliseconds (& interface -> stopped, & interface -> started); printf (" \n"); printf ("Time:\n"); printf ("=====\n"); print_time_in_secs (& interface -> started, "Started: "); print_time_in_secs (& interface -> stopped, "Finished: "); printf ("Elapsed Time: %s\n", elapsed_time (& interface -> started, & interface -> stopped)); printf ("\n"); /* Print out test results */ printf ("Great Totals:\n"); printf ("=============\n"); printf ("pkts rcvd #%lu pckts of #%lu => %7.2f pkts/sec\n\n", interface -> partial, interface -> maxcount, (double) interface -> partial * 1000 / delta); event_del (& interface -> read_evt); } }
/* * 1. Open 'p' pcap-handle(s) * 2. Capture 'n' packets per pcap-handle using a round-robin algorithm * 3. Print global statistics information */ int main (int argc, char * argv []) { int option; char * interface = DEFAULT_INTERFACE; /* interface name */ int promiscuous = 1; int snapshot = DEFAULT_SNAPSHOT; /* How many pcap-handles */ int handles = DEFAULT_HANDLES; pcap_t ** table = NULL; int p; char ebuf [PCAP_ERRBUF_SIZE]; const unsigned char * packet; struct pcap_pkthdr header; /* How many packets */ unsigned long maxcount = DEFAULT_PACKETS; unsigned long partial = 0; unsigned long errors = 0; int hb = -1; /* heartbeat */ int quiet = 0; struct timeval started; struct timeval stopped; double delta; /* Notice the program name */ char * progname = strrchr (argv [0], '/'); progname = ! progname ? * argv : progname + 1; #define OPTSTRING "hvi:s:n:c:b:q" while ((option = getopt (argc, argv, OPTSTRING)) != EOF) { switch (option) { default: return -1; case 'h': usage (progname); return 0; case 'v': version (progname); return 0; case 'i': interface = optarg; break; case 's': snapshot = atoi (optarg); break; case 'n': handles = atoi (optarg); if (! handles) handles = 1; break; case 'c': maxcount = atoi (optarg); break; case 'b': hb = atoi (optarg); break; case 'q': quiet = 1; break; } } /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ /* Set unbuffered stdout */ setvbuf (stdout, NULL, _IONBF, 0); if ((getuid () && geteuid ()) || setuid (0)) { printf ("%s: sorry, you must be root in order to run this program\n", progname); return -1; } /* Find a suitable interface, if you don't have one */ if (! interface && ! (interface = pcap_lookupdev (ebuf))) { printf ("%s: no suitable interface found, please specify one with -d\n", progname); return -1; } signal (SIGINT, on_ctrl_c); /* Announce */ printf ("%s: requested to open #%d pcap-handle%s\n", progname, handles, handles > 1 ? "s" : ""); /* Allocate enough memory to keep the pointers to the pcap-handle(s) */ table = calloc ((handles + 1) * sizeof (pcap_t *), 1); for (p = 0; p < handles; p ++) table [p] = NULL; table [p] = NULL; /* Open the interface for packet capturing */ for (p = 0; p < handles; p ++) if (! (table [p] = pcap_open_live (interface, snapshot, promiscuous, 1000, ebuf))) { printf ("%s: cannot open interface '%s' due to '%s'\n", progname, interface, ebuf); return -1; } printf ("%s: listening from %s using %s\n\n", progname, interface, pcap_lib_version ()); /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ if (hb == -1) hb = maxcount / DEFAULT_HB; if (! hb) hb = 1; printf ("%s: starting to capture #%lu pckts using #%d pcap-handle%s...\n", progname, maxcount, handles, handles > 1 ? "s" : ""); gettimeofday (& started, NULL); p = 0; while (! maxcount || (partial + errors) < maxcount) { /* Please give me just a packet at once from the interface */ if ((packet = pcap_next (table [p], & header))) { partial ++; if (! quiet) { if (! (partial % hb)) { static unsigned long previous = 0; static struct timeval latest; struct timeval now; /* Show pkts/secs in the latest period */ gettimeofday (& now, NULL); delta = delta_time_in_milliseconds (& now, & latest); printf ("%s: pkts rcvd #%lu of #%lu %s", progname, partial, maxcount, percentage (partial, maxcount)); if (previous && delta) printf (" [%8.2f pkts/sec => +%lu pkts in %s]", (double) (partial - previous) * 1000 / delta, partial - previous, elapsed_time (& latest, & now)); printf ("\n"); previous = partial; latest = now; } else showbar (partial); } } else errors ++; /* Round-robin to choose the pcap-handle candidate for the packet capture */ p = (p + 1) % handles; } /* Close the pcap-handle(s) */ for (p = 0; p < handles; p ++) pcap_close (table [p]); free (table); gettimeofday (& stopped, NULL); delta = (double) delta_time_in_milliseconds (& stopped, & started); printf (" \n"); printf ("Time:\n"); printf ("=====\n"); print_time_in_secs (& started, "Started: "); print_time_in_secs (& stopped, "Finished: "); printf ("Elapsed Time: %s\n", elapsed_time (& started, & stopped)); printf ("\n"); /* Print out test results */ printf ("Great Totals:\n"); printf ("=============\n"); printf ("pkts rcvd #%lu pckts of #%lu => %7.2f pkts/sec\n", partial, maxcount, (double) partial * 1000 / delta); return 0; }