use nibble vector
[rrq/rrqmisc.git] / socket-sniff / socket-sniff.c
index ae9f41da6d71e2aabbe797e5822884114486aae3..4256ee127efa32bb8b3a8027c54a81cd308ce513 100644 (file)
@@ -12,7 +12,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include <hashvector.h>
+#include <HashVector.h>
+#include <stringitem.h>
 
 // Seconds between outputs
 static int DELAY = 5;
@@ -29,78 +30,95 @@ 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;
-    struct _Count *prev;
-    struct timeval when;
-    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 );
 }
 
-// Return pointer to the key for an item
-static void *Countp_itemkey(void *item) {
+// Returns the hashcode for a key
+static unsigned long Countp_hashcode(void *this,void *key) {
+    return HashVector_hashcode( key, IPBUFMAX );
+}
+
+// Return pointer a key for an item (could be temporary allocation)
+static void *Countp_itemkey(void *this,void *item) {
     return ((Count*) item)->ip;
 }
 
 // Return 1 if the item has the key, or 0 otherwise.
-static int Countp_haskey(void *item,void *key) {
-    return memcmp( key, Countp_itemkey( item ), IPBUFMAX ) == 0;
+static int Countp_haskey(void *this,void *item,void *key) {
+    return memcmp( key, Countp_itemkey( this, item ), IPBUFMAX ) == 0;
 }
 
-// Returns the hashcode for a key
-static unsigned long Countp_hashcode(void *key) {
-    return hashvector_hashcode( key, IPBUFMAX );
+#if 0
+// Releasing a key does nothing
+static void Countp_releasekey(void *this,void *item) {
 }
+#endif
 
-static hashvector TBL = {
-    .table = { 256, 0 },
+static ItemKeyFun Countp_itemkeyfun = {
+    .hashcode = Countp_hashcode,
+    .haskey = Countp_haskey,
+    .itemkey = Countp_itemkey,
+    //.releasekey = Countp_releasekey,
+    //.tostring = Countp_tostring
+};
+
+// The HashVector of seen IP
+static HashVector TBL = {
+    .table = { Nibble_index_levels, 16, 0 },
     .fill = 0,
     .holes = 0,
-    .keyhashcode = Countp_hashcode,
-    .itemkey = Countp_itemkey,
-    .haskey = Countp_haskey
+    .type = &Countp_itemkeyfun,
 };
 
+// The Count records in time order
 static struct {
     Count *head;
     Count *tail;
 } trail;
 
+// Temporary buffer for IP addresses in ascii
 static char buffer[ IPBUFMAX ];
 
 /*============================================================
  * Reading ignore lines.
  */
+#if 0
 // Return pointer to the key for an item
-static void *charp_itemkey(void *item) {
+static void *charp_itemkey(void *this,void *item) {
     return item;
 }
 
 // Return 1 if the item has the key, or 0 otherwise.
-static int charp_haskey(void *item,void *key) {
+static int charp_haskey(void *this,void *item,void *key) {
     return strcmp( key, item ) == 0;
 }
 
 // Returns the hashcode for a key
-static unsigned long charp_hashcode(void *key) {
-    return hashvector_hashcode( key, strlen( (const char *) key ) );
+static unsigned long charp_hashcode(void *this,void *key) {
+    return HashVector_hashcode( key, strlen( (const char *) key ) );
 }
+#endif
 
-static hashvector IGN = {
-    .table = { 256, 0 },
+static HashVector IGN = {
+    .table = { Nibble_index_levels, 16, 0 },
     .fill = 0,
     .holes = 0,
-    .keyhashcode = charp_hashcode,
-    .itemkey = charp_itemkey,
-    .haskey = charp_haskey
+    .type = &stringitem
 };
 
 static void read_ignore_file(char *filename) {
@@ -139,7 +157,7 @@ static void read_ignore_file(char *filename) {
        char *ip = calloc( 1, p - cur + 1 );
        memcpy( ip, cur, p - cur );
        cur = p + 1;
-       hashvector_add( &IGN, ip );
+       HashVector_add( &IGN, ip );
     }
 }
 
@@ -161,7 +179,7 @@ static int Countp_compare(const void *ax, const void *bx) {
     return a->last - b->last;
 }
 
-static int Countp_fade_and_print(unsigned long index,void *x,void *d) {
+static int Countp_fade_and_print(VectorIndex index,void *x,void *d) {
     if ( x ) {
        Count *item = (Count *) x;
        item->last = item->accum;
@@ -177,7 +195,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;
 }
 
@@ -185,21 +203,21 @@ static int Countp_reclaim(pvector *pv,unsigned long ix,void *item,void *data) {
 // ip points to [ IPBUFMAX ] of ip address in text
 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 );
+    Count *item = HashVector_find( &TBL, ip );
     struct timeval now;
     if ( gettimeofday( &now, 0 ) ) {
        perror( "gettimeofday" );
        exit( 1 );
     }
-    if ( i == 0 ) {
+    if ( item == 0 ) {
        item = (Count *) calloc( 1, sizeof( Count ) );
        memcpy( item->ip, ip, strlen( ip ) );
-       hashvector_add( &TBL, item );
-       item->ignore = hashvector_find( &IGN, ip, 0 );
+       HashVector_add( &TBL, item );
+       item->ignore = (HashVector_find( &IGN, ip ) != 0);
+       int i;
        for ( i = strlen( ip )-1; i > 1; i-- ) {
            if ( ip[i] == '.' || ip[i] == ':' ) {
-               item->ignore |= hashvector_find( &IGN, ip, 0 );
+               item->ignore |= (HashVector_find( &IGN, ip ) != 0);
            }
            ip[i] = 0;
        }
@@ -238,7 +256,7 @@ static void add_show_table(char *ip,size_t length) {
            trail.head->prev = 0;
        }
        fprintf( stdout, "drop %s\n", old->ip );
-       hashvector_delete( &TBL, old );
+       HashVector_delete( &TBL, old );
        free( old );
     }
     if ( now.tv_sec < show ) {
@@ -248,11 +266,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 };
-    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 ordered = { Nibble_index_levels, 0, 0 };
+    HashVector_contents( &TBL, Nibble_index_levels, &ordered );
+    Vector_qsort( &ordered, Countp_compare );
+    Vector_iterate( &ordered, 0, 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 );
 }