#include "util.h" #include "rlocs.h" #include #include #include "packet.h" // We use writev() to send the packet, so we don't have to copy the // unencrypted part. #include /* * Entry point. Expects an invocation like: * wrapper */ int main(int argc, char** argv) { struct session wrap; struct recv_pkt recv_pkt; struct rsp_data to_send; ssize_t count; int result; if ( argc < 4 ) { warn( "Usage: %s ", argv[0] ); return 1; } rlocs_init(); if ( !session_setup( &wrap, argv[1], argv[2], argv[3] ) ) { warn( "Failed to set up session, exiting" ); 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( wrap.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 = wrap_ipv4_packet( wrap.rlocs, &recv_pkt, &to_send ); break; case 0x06 : result = wrap_ipv6_packet( wrap.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 construct a wrapped version of received packet, dropping." ); continue; } // no failure, but nothing to forward. if ( to_send.count == 0 ) { continue; } // TODO: Drop the packet if we would fragment. A real implementation // will need to fragment or inform the source, of course. // docs say this should never block and should always write everything - // trust that for now. if ( ( count = writev( wrap.output_if, to_send.iovs, to_send.count ) ) < 0 ) { warn( "Error writing wrapped packet to output: %s", strerror(errno) ); } } info( "Finished, cleaning up" ); session_teardown( &wrap ); return 0; }