added IP aging
authorRalph Ronnquist <ralph.ronnquist@gmail.com>
Sat, 25 Jun 2022 22:56:45 +0000 (08:56 +1000)
committerRalph Ronnquist <ralph.ronnquist@gmail.com>
Sat, 25 Jun 2022 22:56:45 +0000 (08:56 +1000)
socket-sniff/socket-sniff.c

index e939712b3d8a2935096c86edf2ec4200e2639d32..ae9f41da6d71e2aabbe797e5822884114486aae3 100644 (file)
@@ -23,11 +23,16 @@ 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
 
 typedef struct _Count {
     struct _Count *next;
+    struct _Count *prev;
+    struct timeval when;
     int ignore;
     int last;
     int accum;
@@ -64,6 +69,11 @@ static hashvector TBL = {
     .haskey = Countp_haskey
 };
 
+static struct {
+    Count *head;
+    Count *tail;
+} trail;
+
 static char buffer[ IPBUFMAX ];
 
 /*============================================================
@@ -177,10 +187,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 +203,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 {
+    // 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;
+    }
+    item->accum += length;
+    item->when = now;
+    // Link in item to the trail end
+    if ( trail.head == 0 ) {
+       trail.head = item;
     } else {
-       item->accum += length;
+       trail.tail->next = item;
+       item->prev = trail.tail;
     }
-    struct timeval now;
-    if ( gettimeofday( &now, 0 ) ) {
-       perror( "gettimeofday" );
-       exit( 1 );
+    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;
@@ -252,6 +295,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 +351,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
        }