#include "util.h" #include "rlocs.h" #include #include #include "packet.h" #include /* * Entry point. Expects an invocation like: * unwrapper */ int main(int argc, char** argv) { struct session unwrap; struct recv_pkt recv_pkt; struct rsp_data to_send; ssize_t count; int result; if ( argc < 6 ) { warn( "Usage: %s [ ]n", argv[0] ); return 1; } rlocs_init(); if ( !session_setup( &unwrap, argv[1], argv[2], argv[3] ) ) { warn( "Failed to set up session, exiting" ); return 1; } if ( !session_upgrade_rlocs( &unwrap, argc - 4, argv + 4 ) ) { warn( "Failed to upgrade rlocs for session, exiting" ); session_teardown( &unwrap ); return 1; } memset( &recv_pkt, 0, sizeof( struct recv_pkt ) ); memset( &to_send, 0, sizeof( struct rsp_data ) ); warn( "TODO: Write BGP interventions to file" ); info( "Processing packets" ); while(1) { // TODO: this isn't zero-copy. Not even close if ( ( count = read( unwrap.listen_if, &recv_pkt, sizeof( struct recv_pkt ) ) ) < 0 ) { warn( "Failed to get a packet (%s)", strerror( errno ) ); break; } info( "Got a packet \\o/. %zu bytes", count ); switch( recv_pkt.hdr.ip.version ) { case 0x04 : result = unwrap_ipv4_packet( unwrap.rlocs, &recv_pkt, &to_send ); break; case 0x06 : result = unwrap_ipv6_packet( unwrap.rlocs, &recv_pkt, &to_send ); break; default: warn( "Unknown IP version: %i", recv_pkt.hdr.ip.version ); } // We can't send the unwrapped one - it'll just be returned to us // forever, given our bgp interventions, unless the router is clever. // TODO: make fallback-to-unwrapped a configurable option? if ( !result ) { warn( "Failed to unwrap received packet, dropping." ); continue; } // no failure, but nothing to forward. if ( to_send.count == 0 ) { continue; } // docs say this should never block and should always write everything - // trust that for now. if ( ( count = writev( unwrap.output_if, to_send.iovs, to_send.count ) ) < 0 ) { warn( "Error writing unwrapped packet to output: %s", strerror(errno) ); } } info( "Finished, cleaning up" ); session_teardown( &unwrap ); return 0; }