10 #include "hashvector.h"
12 typedef struct _ipslot {
14 unsigned char data[32];
18 static int voidp_hashcode(void *key) {
19 unsigned char *p = (unsigned char *) key;
22 for ( ; i < sizeof( ipslot ); i++ ) {
23 value += ( value << 5 ) + *(p++);
28 static void* voidp_itemkey(void *item) {
32 static int voidp_haskey(void *item,void *key) {
33 return memcmp( item, key, sizeof( ipslot ) ) == 0;
41 .table = { 12000, 0 },
44 .keyhashcode = voidp_hashcode,
45 .itemkey = voidp_itemkey,
46 .haskey = voidp_haskey
58 static int readline(int fd,char **outp) {
60 char *curp = stream.data + stream.cur;
61 char *endp = stream.data + stream.end;
63 while ( curp < endp ) {
64 if ( *(curp++) == '\n' ) {
65 stream.cur = curp - stream.data;
70 if ( top != stream.data ) {
72 while ( top < endp ) {
76 stream.end = endp - stream.data;
79 ssize_t n = read( fd, endp, BUFSZ - stream.end );
81 if ( stream.end == 0 ) {
82 return -1; // No more data
84 (*outp) = stream.data;
92 // Scan to NUL, CR or c. Return pointer not including character.
93 static char *scanto(char *p, char c) {
94 while ( *p && *p != '\n' && *p != c ) {
100 static int parse_addr(char *line,ipslot *addr) {
101 char *end = scanto( line, '\n' );
102 char *slash = scanto( line, '/' );
105 if ( inet_pton( AF_INET6, line, addr->data ) == 1 ) {
107 addr->family = AF_INET6;
108 } else if ( inet_pton( AF_INET, line, addr->data ) == 1 ) {
110 addr->family = AF_INET;
114 if ( slash != end && sscanf( slash+1, "%u", &addr->bits ) != 1 ) {
121 static void add_entry(ipslot *tmp) {
122 ipslot *p = (ipslot *) malloc( sizeof( ipslot ) );
123 memmove( p, tmp, sizeof( ipslot ) );
124 hashvector_add( &table.hv, p );
127 pvector *pv = &table.hv.table;
128 if ( pv->size == table.fill ) {
129 (void) pvector_resize( pv, table.fill + 256, 0, 0 );
131 pvector_set( pv, table.fill++, p );
135 static void load_file(const char *filename) {
136 int fd = open( filename, O_RDONLY );
143 while ( ( n = readline( fd, &line ) ) >= 0 ) {
145 if ( parse_addr( line, &addr ) ) {
146 fprintf( stderr, "Bad address: %s\n", line );
153 static int int_reclaim(pvector *pv,unsigned long index,void *item,void *data) {
157 static int dumpitem(unsigned long index,void *item) {
158 fprintf( stdout, "[%ld] %p\n", index, item );
162 static int dump_ipslot(unsigned long index,void *item) {
163 static char buffer[100];
164 ipslot *ip = (ipslot*) item;
165 const char *p = inet_ntop( ip->family, ip->data, buffer, 100 );
166 fprintf( stdout, "[%ld] %s/%d\n", index, p, ip->bits );
170 static int compare_ipslot(void *ax,void *bx) {
171 ipslot *a = (ipslot *) ax;
172 ipslot *b = (ipslot *) bx;
173 int x = b->family - a->family;
175 return ( x > 0 )? 1 : -1;
177 x = a->bits < b->bits? a->bits : b->bits;
178 unsigned char *ap = a->data;
179 unsigned char *bp = b->data;
181 for ( ; x >= 8; x -= 8 ) {
182 d = *(bp++) - *(ap++);
184 return ( d > 0 )? 1 : -1;
189 d = ( (*bp) >> x ) - ( (*ap) >> x );
191 return ( d > 0 )? 1 : -1;
194 x = b->bits - a->bits;
196 return ( x > 0 )? 1 : -1;
201 int main(int argc,char **argv) {
202 pvector test = { 0 };
203 pvector_resize( &test, 100, 0, 0 );
204 pvector_set( &test, 5, (void*) 500 );
205 pvector_set( &test, 55, (void*) 600 );
206 //pvector_set( &test, 550, (void*) 800 );
207 pvector_resize( &test, 300, 0, 0 );
208 pvector_set( &test, 55, (void*) 650 );
209 pvector_resize( &test, 30000, 0, 0 );
210 pvector_set( &test, 22255, (void*) 26 );
211 pvector_dump( &test, dumpitem );
212 pvector_resize( &test, 100, int_reclaim, 0 );
213 pvector_set( &test, 5, (void*) 2 );
214 pvector_dump( &test, dumpitem );
215 pvector_resize( &test, 0, int_reclaim, 0 ); // clear out the pvector
218 for ( i = 1; i < argc; i++ ) {
219 load_file( argv[ i ] );
221 pvector_dump( &table.hv.table, dump_ipslot );
222 fprintf( stdout, "--------------\n" );
223 if ( hashvector_pack( &table.hv, &test ) < 0 ) {
224 fprintf( stdout, "test is not empty\n" );
226 pvector_dump( &test, dump_ipslot );
227 fprintf( stdout, "--------------\n" );
228 pvector_qsort( &test, compare_ipslot );
229 pvector_dump( &test, dump_ipslot );