X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=socket-sniff%2Fsocket-sniff.c;h=545c9f7019690413caded5f65221667a781d5a0d;hb=9e8fceb62721997ca62abfed6080e917bb429eee;hp=e939712b3d8a2935096c86edf2ec4200e2639d32;hpb=b901ebd3cd786e8cec0f10c461f8bcc8e4219081;p=rrq%2Frrqmisc.git diff --git a/socket-sniff/socket-sniff.c b/socket-sniff/socket-sniff.c index e939712..545c9f7 100644 --- a/socket-sniff/socket-sniff.c +++ b/socket-sniff/socket-sniff.c @@ -23,18 +23,25 @@ static int FADE = 10000; // Number of top usage to report static int WORST = 20; +// Drop-out age +static int OLD = 600; + // Number of characters for text format IP holdings #define IPBUFMAX 40 +// Count record for IP -> length mapping typedef struct _Count { - struct _Count *next; - int ignore; - int last; - int accum; - int total; - char ip[ IPBUFMAX ]; + struct _Count *next; // Next Count in time order + struct _Count *prev; // Previous Count in time order + struct timeval when; // Last update time for this Count record + int ignore; // Flag to leave out from reports + int last; // The saved accumulation from the last report period + int accum; // Current accumulation + int total; // The total accumulation (reduced by fading) + char ip[ IPBUFMAX ]; // The IP concerned, in ascii } Count; +// Print message and exit static void die(char *m) { fprintf( stderr, "%s\n", m ); exit( 1 ); @@ -55,8 +62,9 @@ static unsigned long Countp_hashcode(void *key) { return hashvector_hashcode( key, IPBUFMAX ); } +// The hashvector of seen IP static hashvector TBL = { - .table = { 256, 0 }, + .table = { VECTOR_SLOTS, 0 }, .fill = 0, .holes = 0, .keyhashcode = Countp_hashcode, @@ -64,6 +72,13 @@ static hashvector TBL = { .haskey = Countp_haskey }; +// The Count records in time order +static struct { + Count *head; + Count *tail; +} trail; + +// Temporary buffer for IP addresses in ascii static char buffer[ IPBUFMAX ]; /*============================================================ @@ -167,7 +182,7 @@ static int Countp_fade_and_print(unsigned long index,void *x,void *d) { return 0; } -static int Countp_reclaim(pvector *pv,unsigned long ix,void *item,void *data) { +static int Countp_reclaim(vector *pv,unsigned long ix,void *item,void *data) { return 0; } @@ -177,10 +192,14 @@ static void add_show_table(char *ip,size_t length) { static time_t show = 0; Count *item; int i = hashvector_find( &TBL, ip, (void**) &item ); + struct timeval now; + if ( gettimeofday( &now, 0 ) ) { + perror( "gettimeofday" ); + exit( 1 ); + } if ( i == 0 ) { item = (Count *) calloc( 1, sizeof( Count ) ); memcpy( item->ip, ip, strlen( ip ) ); - item->accum = length; hashvector_add( &TBL, item ); item->ignore = hashvector_find( &IGN, ip, 0 ); for ( i = strlen( ip )-1; i > 1; i-- ) { @@ -189,14 +208,43 @@ static void add_show_table(char *ip,size_t length) { } ip[i] = 0; } - //fprintf( stdout, "add %s\n", ip ); + fprintf( stdout, "add %s\n", item->ip ); } else { - item->accum += length; + // Unlink item from the trail + if ( item->next ) { + item->next->prev = item->prev; + } + if ( item->prev ) { + item->prev->next = item->next; + } + if ( trail.head == item ) { + trail.head = item->next; + } + if ( trail.tail == item ) { + trail.tail = item->prev; + } + item->prev = item->next = 0; } - struct timeval now; - if ( gettimeofday( &now, 0 ) ) { - perror( "gettimeofday" ); - exit( 1 ); + item->accum += length; + item->when = now; + // Link in item to the trail end + if ( trail.head == 0 ) { + trail.head = item; + } else { + trail.tail->next = item; + item->prev = trail.tail; + } + trail.tail = item; + // Drop counters older than an hour + while ( trail.head->when.tv_sec + OLD < item->when.tv_sec ) { + Count *old = trail.head; + trail.head = old->next; + if ( trail.head ) { + trail.head->prev = 0; + } + fprintf( stdout, "drop %s\n", old->ip ); + hashvector_delete( &TBL, old ); + free( old ); } if ( now.tv_sec < show ) { return; @@ -205,11 +253,11 @@ static void add_show_table(char *ip,size_t length) { show = now.tv_sec; } show += DELAY; // Time for next output - pvector ordered = { 0, 0 }; + vector ordered = { 0, 0 }; hashvector_contents( &TBL, &ordered ); - pvector_qsort( &ordered, Countp_compare ); - pvector_iterate( &ordered, Countp_fade_and_print, 0 ); - pvector_resize( &ordered, 0, Countp_reclaim, 0 ); + vector_qsort( &ordered, Countp_compare ); + vector_iterate( &ordered, Countp_fade_and_print, 0 ); + vector_resize( &ordered, 0, Countp_reclaim, 0 ); fprintf( stdout, "==%ld/%ld/%ld\n", TBL.fill, TBL.holes, TBL.table.size ); } @@ -252,6 +300,13 @@ int main(int argc,char **argv) { fprintf( stdout, "Displaying at most %d lines in reports\n", WORST ); ARG++; } + if ( ARG < argc && strncmp( argv[ ARG ], "-a", 2 ) == 0 ) { + if ( sscanf( argv[ ARG ]+2, "%d", &OLD ) != 1 ) { + die( "Missing/bad drop-out age (seconds)" ); + } + fprintf( stdout, "Displaying at most %d lines in reports\n", WORST ); + ARG++; + } if ( ARG < argc && strncmp( argv[ ARG ], "-i", 2 ) == 0 ) { char *filename = argv[ ARG ] + 2; if ( (*filename) == 0 ) { @@ -301,10 +356,8 @@ int main(int argc,char **argv) { ( strncmp( p, "0:0:0:0:0:0:0:1", 15 ) != 0 ) ) { add_show_table( p, N ); } - } else if ( code == 0x0800 ) { - // ignore } else if ( code == 0x8100 ) { - // ignore + // ignore VLAN } else { // funny code }