// Will become util.h or so #include #include #include #define info(msg, ...) { fprintf( stdout, msg, ##__VA_ARGS__ ) ; fprintf( stdout, "\n" ); } #define warn(msg, ...) { fprintf( stderr, msg, ##__VA_ARGS__ ) ; fprintf( stderr, "\n" ); } void* xmalloc( size_t bytes ) { void* result = malloc( bytes ); if ( bytes > 0 && result == NULL ) { warn( "Couldn't allocate memory, exiting!" ); exit(2); } memset( result, 0, bytes ); return result; } // dependencies for reading the rloc registry; will become rlocs.h/c or so #include #include #include #include #include #include #include // For now typedef struct rloc_registry { json_object* config; } rloc_registry; rloc_registry* rlocs_get( char* filename ) { rloc_registry* result = NULL; struct stat filedata; json_object* config; ssize_t have_read = 0; char* json_text; int fd; fd = open( filename, O_RDONLY ); if ( errno < 0 ) { warn( "Error %s (%i) opening %s", strerror(errno), errno, filename ); return NULL; } fstat( fd, &filedata ); if ( errno < 0 ) { warn( "Error %s (%i) getting size of %s", strerror(errno), errno, filename ); return NULL; } /* Make sure we're null-terminated */ json_text = xmalloc( filedata.st_size + 1 ); while ( have_read < filedata.st_size ) { ssize_t bytes = read( fd, json_text + have_read, filedata.st_size - have_read ); if ( bytes < 0 ) { warn( "Error %s (%i) reading %s", strerror(errno), errno, filename ) ; free( json_text ); close( fd ); return NULL; } have_read += bytes; //EOF if ( bytes == 0 ) { warn( "short read of %s: %zu instead of %zu", filename, have_read, filedata.st_size ); filedata.st_size = have_read; } } warn( json_text ); close( fd ); config = json_tokener_parse( json_text ); free( json_text ); // TODO: Check for config-file errors here, ja? result = xmalloc( sizeof( struct rloc_registry ) ); result->config = config; // TODO: process the config into an easy-to-look-up format return result; } void rlocs_free(rloc_registry* rlocs ) { // No need to do json_object_put() here. free( rlocs ); return; } #include typedef struct wrapper { rloc_registry* rlocs; pcap_t* listen_if; pcap_t* output_if; char** us_rlocs; } wrapper; void wrapper_handle_packet( u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) { //wrapper *wrap = ( wrapper* ) user; info( "Received packet \\o/" ); return; } /* * Entry point. Expects an invocation like: * wrapper */ int main(int argc, char** argv) { char errbuf[PCAP_ERRBUF_SIZE]; int result; wrapper wrap; if ( argc < 5 ) { warn( "Usage: %s +", argv[0] ); return 1; } memset( &wrap, 0, sizeof( wrapper ) ); wrap.rlocs = rlocs_get( argv[1] ); if ( wrap.rlocs == NULL ) { warn( "Failed to get config from %s", argv[1] ); return 1; } wrap.listen_if = pcap_create( argv[2], errbuf ); if ( wrap.listen_if == NULL ) { warn( "Error opening %s for listening: %s", argv[2], errbuf ); rlocs_free( wrap.rlocs ); return 1; } wrap.output_if = pcap_create( argv[3], errbuf ); if ( wrap.output_if == NULL ) { warn( "Error opening %s for forwarding: %s", argv[3], errbuf ); pcap_close( wrap.listen_if ); rlocs_free( wrap.rlocs ); return 1; } pcap_set_snaplen( wrap.listen_if, 65535 ); pcap_set_promisc( wrap.listen_if, 1 ); pcap_set_timeout( wrap.listen_if, 5 ); /* TODO: needs tuning */ /* TODO: Make buffer size tuneable */ warn( "TODO: Write BGP interventions to file" ); info( "Entering main loop" ); result = pcap_activate( wrap.listen_if ); if ( result != 0 ) { warn( "Failed to activate %s for listening", argv[2] ); pcap_perror( wrap.listen_if, "pcap error was" ); goto done; } pcap_loop( wrap.listen_if, -1, wrapper_handle_packet, (u_char*) &wrap ); done: rlocs_free( wrap.rlocs ); pcap_close( wrap.listen_if ); pcap_close( wrap.output_if ); return 0; }