diff --git a/HACKING b/HACKING index 24b4d46..b0b9e67 100644 --- a/HACKING +++ b/HACKING @@ -186,11 +186,88 @@ up to date so contacting the host will be faster after an long idle time. MAN PAGES --------- -Look at a non-installed man page like this (linux): +Look at a non-installed man page like this (linux/UNIX): nroff -man edge.8 | less +PACKET FORMAT +------------- + +Version 1 + + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 0 ! Version=1 ! Message Type ! TTL ! Origin ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 4 ! ! + 8 ! Community Name ! +12 ! ! +16 ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +20 ! Source MAC Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +24 : Source MAC Address ! Destination MAC Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +28 : Destination MAC Address ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +32 ! Public Peer ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +40 : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +48 : ! Alignment ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Private Peer : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +56 : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +64 : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : ! Alignment ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +72 ! Packet Type ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Seq Number ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +80 ! CRC32 ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Payload + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +Version = 1 +MessageType = 1 +TTL = 1 +Origin = 1 +Community = 16 +src MAC = 6 +dst MAC = 6 +Pub Peer = 19 (20) +Priv Peer = 19 (20) +Pkt Type = 1 (4) +Seq = 4 +CRC = 4 +====================== +Total = 79 (84) + +Sizes in parentheses indicate alignment adjusted sizes on i686. The intel +alignment is also shown in the diagram. Some platforms have different alignment +padding. + +The above packet format describes the header of IP packets carried between edge +nodes. Payload is an encoded ethernet frame appended to the packet header. The +ethernet payload is encrypted and compressed. + +When the payload is created it is first encrypted with twofish, then compressed +using lzo1x_compress. When the payload is decoded it is first decompressed using +lzo1x_decompress_safe then decrypted using twofish. + ------- -April 2008 - Richard Andrews +January 2009 - Richard Andrews diff --git a/INSTALL b/INSTALL index d6e7a7b..45221d4 100644 --- a/INSTALL +++ b/INSTALL @@ -43,8 +43,8 @@ line in it: To build an RPM the hard way follow these steps. -$ cp -a n2ndir n2n-1.2 -$ tar czf n2n-1.2.tar.gz n2n-1.2 -$ mv n2n-1.2.tar.gz /usr/src/redhat/SOURCES +$ cp -a n2ndir n2n-1.3 +$ tar czf n2n-1.3.tar.gz n2n-1.3 +$ mv n2n-1.3.tar.gz /usr/src/redhat/SOURCES $ cp n2ndir/n2n.spec /usr/src/redhat/SPECS $ rpmbuild -bb n2n.spec diff --git a/Makefile b/Makefile index d53272a..485adc3 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,18 @@ -N2N_VERSION="1.2.2" - +N2N_VERSION="1.3.2" ######## CC=gcc -CFLAGS+=-g -Wall -Wshadow -Wpointer-arith -Wmissing-declarations -Wnested-externs #-static +DEBUG?=-g +WARN?=-Wall -Wshadow -Wpointer-arith -Wmissing-declarations -Wnested-externs + +#Ultrasparc64 users experiencing SIGBUS should try the following gcc options +#(thanks to Robert Gibbon) +PLATOPTS_SPARC64=-mcpu=ultrasparc -pipe -fomit-frame-pointer -ffast-math -finline-functions -fweb -frename-registers -mapp-regs + + +CFLAGS+=$(DEBUG) $(WARN) $(OPTIONS) $(PLATOPTS) INSTALL=install MKDIR=mkdir -p @@ -48,9 +55,9 @@ $(N2N_LIB): $(N2N_OBJS) # $(RANLIB) $@ version.c: - echo $(N2N_VERSION) | sed -e 's/.*/char * version = "&";/' > version.c - uname -p | sed -e 's/.*/char * osName = "&";/' >> version.c - date +"%D %r" | sed -e 's/.*/char * buildDate = "&";/' >> version.c + @echo $(N2N_VERSION) | sed -e 's/.*/const char * version = "&";/' > version.c + @uname -p | sed -e 's/.*/const char * osName = "&";/' >> version.c + @date +"%D %r" | sed -e 's/.*/const char * buildDate = "&";/' >> version.c clean: rm -rf $(N2N_OBJS) $(N2N_LIB) $(APPS) $(DOCS) *.dSYM *~ version.c @@ -62,3 +69,8 @@ install: edge supernode edge.8.gz supernode.1.gz $(INSTALL_PROG) edge $(SBINDIR)/ $(INSTALL_DOC) edge.8.gz $(MAN8DIR)/ $(INSTALL_DOC) supernode.1.gz $(MAN1DIR)/ + +# Courtesy of Ole Tange + +deb: + dpkg-buildpackage \ No newline at end of file diff --git a/debian/changelog b/debian/changelog index a5da4cf..c96cdeb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +n2n (1.3.1~svn3789-1) unstable; urgency=low + + * Update package to version 1.3 from upstream cvs + * Removed "libc6-dev (>= 2.0)" build dependency (closes: Bug#533881) + * DH compatibility level is 7 + * Run dh_prep instead of dh_clean -k + * Standards Version is 3.8.2 + + -- cristian paul peñaranda rojas Sun, 22 Jun 2009 21:19:58 -0500 + n2n (1.2.2~svn3653) unstable; urgency=low * Initial release (closes: Bug#507750) diff --git a/debian/compat b/debian/compat index 7ed6ff8..7f8f011 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -5 +7 diff --git a/debian/control b/debian/control index e025500..58de329 100644 --- a/debian/control +++ b/debian/control @@ -2,8 +2,8 @@ Source: n2n Section: net Priority: extra Maintainer: cristian paul peñaranda rojas -Build-Depends: debhelper (>= 5), libc6-dev (>= 2.0), quilt -Standards-Version: 3.8.0 +Build-Depends: debhelper (>= 7), quilt +Standards-Version: 3.8.2 Package: n2n Architecture: any diff --git a/debian/copyright b/debian/copyright index 6e4cae6..b138e67 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,6 +1,6 @@ This package was debianized by cristian paul peñaranda rojas on and is licensed under the GNU General Public License (GPL) version 3. -A copy of the GNU GPL version 2 is in `/usr/share/common-licenses/GPL-3'. +A copy of the GNU GPL version 3 is in `/usr/share/common-licenses/GPL-3'. Sat, 29 Nov 2008 00:31:58 -0500. @@ -88,7 +88,7 @@ The Files: Copyright (C) 1996 - 2005 Markus Franz Xaver Johannes Oberhumer -These file are part of the LZO real-time data compression library. +These files are part of the LZO real-time data compression library. All Rights Reserved. diff --git a/debian/patches/01-edge.8.diff b/debian/patches/01-edge.8.diff index 0194e87..a5ccc5e 100644 --- a/debian/patches/01-edge.8.diff +++ b/debian/patches/01-edge.8.diff @@ -1,8 +1,8 @@ --- a/edge.8.old 2008-12-02 20:33:54.000000000 -0500 +++ b/edge.8 2008-12-02 20:34:13.000000000 -0500 @@ -1,4 +1,4 @@ --.TH edge 1 "May 3, 2008" "revision 3472" "SUPERUSER COMMANDS" -+.TH edge 8 "May 3, 2008" "revision 3472" "SUPERUSER COMMANDS" +-.TH edge 1 "Jan 3, 2009" "revision 3679" "SUPERUSER COMMANDS" ++.TH edge 8 "Jan 3, 2009" "revision 3679" "SUPERUSER COMMANDS" .SH NAME edge \- n2n edge node daemon .SH SYNOPSIS diff --git a/debian/rules b/debian/rules index 5494adf..c2daff9 100755 --- a/debian/rules +++ b/debian/rules @@ -46,7 +46,7 @@ clean: unpatch install: build dh_testdir dh_testroot - dh_clean -k + dh_prep dh_installdirs # Add here commands to install the package into debian/n2n. diff --git a/edge.8 b/edge.8 index a5f400c..37d6861 100644 --- a/edge.8 +++ b/edge.8 @@ -1,4 +1,4 @@ -.TH edge 1 "May 3, 2008" "revision 3472" "SUPERUSER COMMANDS" +.TH edge 1 "Jan 3, 2009" "revision 3679" "SUPERUSER COMMANDS" .SH NAME edge \- n2n edge node daemon .SH SYNOPSIS @@ -13,65 +13,104 @@ begin to find other nodes in the community. .PP .SH OPTIONS .TP -\-d +\-d sets the TAP device name as seen in ifconfig. .TP -\-a -sets the n2n LAN IP address being claimed. +\-a +sets the n2n virtual LAN IP address being claimed. This is a private IP +address. All IP addresses in an n2n community should belong to the same /24 +network (ie. only the last segment of the IP addresses varies). .TP -\-c -sets the n2n community name. +\-b +cause edge to perform hostname resolution for the supernode address each time +the supernode is periodically contacted. .TP -\-k -sets the twofish encryption key from ASCII text (see also N2N_KEY in ENVIRONMENT) +\-c +sets the n2n community name. All edges within the same community look to be on +the same LAN (layer 2 network segment). All edges communicating must use the +same key and community name. .TP -\-l -sets the n2n supernode IP address and port to register to +\-h +write usage to tty then exit. .TP -\-p -binds to the given UDP port +\-k +sets the twofish encryption key from ASCII text (see also N2N_KEY in +ENVIRONMENT). All edges communicating must use the same key and community name. .TP -\-u -causes the edge process to drop to the given user ID when privileges are no longer required +\-l : +sets the n2n supernode IP address and port to register to. .TP -\-g -causes the edge process to drop to the given group ID when privileges are no longer required +\-p +binds edge to the given UDP port. Useful for keeping the same external socket +across restarts of edge. +.TP +\-u +causes the edge process to drop to the given user ID when privileges are no +longer required. +.TP +\-g +causes the edge process to drop to the given group ID when privileges are no +longer required. .TP \-f -causes the edge process to fork and run as a daemon, closing stdin, stdout, stderr and becoming a process group leader +causes the edge process to fork and run as a daemon, closing stdin, stdout, +stderr and becoming a process group leader. .TP -\-m +\-m start the TAP interface with the given MAC address. This is highly recommended as it means the same address will be used if edge stops and restarts. If this is not done, the ARP caches of all peers will be wrong and packets will not flow to this edge until the next ARP refresh. .TP +\-M +set the MTU of the edge interface in bytes. MTU is the largest packet fragment +size allowed to be moved throught the interface. The default is 1400. +.TP +\-s +set the netmask of edge interface in IPv4 dotted decimal notation. The default +is 255.255.255.0 (ie. /24). +.TP \-t -use HTTP tunneling instead of the normal UDP mechanism (experimental) +use HTTP tunneling instead of the normal UDP mechanism (experimental). .TP \-r -all packet forwarding/routing through the n2n virtual LAN +enable packet forwarding/routing through the n2n virtual LAN. Without this +option, packets arriving over n2n which are not for the -a IP address are +dropped. .TP \-v -use verbose logging +use verbose logging. .SH ENVIRONMENT .TP .B N2N_KEY set the encryption key so it is not visible on the command line .SH EXAMPLES .TP -.B edge \-d n2n0 \-c mynetwork \-k encryptme \-u 99 \-g 99 \-m DE:AD:BE:EF:01:23 \-a 192.168.254.7 \-l 123.121.120.119:7654 +.B edge \-d n2n0 \-c mynetwork \-k encryptme \-u 99 \-g 99 \-m DE:AD:BE:EF:01:23 \-a 192.168.254.7 \-p 50001 \-l 123.121.120.119:7654 Start edge with TAP device n2n0 on community "mynetwork" with community -supernode at 123.121.120.119 UDP port 7654. Use "encryptme" as the shared -encryption key. Assign MAC address DE:AD:BE:EF:01:23 to the n2n interface and -drop to user=99 and group=99 after the TAP device is successfull configured. +supernode at 123.121.120.119 UDP port 7654 and bind the locally used UDP port to +50001. Use "encryptme" as the shared encryption key. Assign MAC address +DE:AD:BE:EF:01:23 to the n2n interface and drop to user=99 and group=99 after +the TAP device is successfull configured. .PP -Add the -f option to make it run as a daemon +Add the -f option to make edge run as a daemon. .PP +Somewhere else setup another edge with similar parameters, eg. + +.B edge \-d n2n0 \-c mynetwork \-k encryptme \-u 99 \-g 99 \-m DE:AD:BE:EF:01:21 \-a 192.168.254.5 \-p 50001 \-l 123.121.120.119:7654 +.PP +Now you can ping from 192.168.254.5 to 192.168.254.7. +.PP +The MAC address (-m ) and virtual IP address (-a ) must be different on all edges in the same community. + +.SH CONFIGURATION +All configuration for edge is from the command line and environment +variables. If you wish to reconfigure edge you should kill the process and +restart with the desired options. .SH EXIT STATUS -edge is a daemon and any exit is an error +edge is a daemon and any exit is an error. .SH AUTHOR Luca Deri ( deri (at) ntop.org ), Richard Andrews ( andrews (at) ntop.org ), Don Bindner .SH SEE ALSO -ifconfig(1) supernode(1) tunctl(1) +ifconfig(8) supernode(1) tunctl(8) diff --git a/edge.c b/edge.c index 2a67ef7..5f69c5a 100644 --- a/edge.c +++ b/edge.c @@ -1,5 +1,6 @@ /* * (C) 2007-09 - Luca Deri + * Richard Andrews * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,8 +16,9 @@ * along with this program; if not see see * * Code contributions courtesy of: - * Richard Andrews * Don Bindner + * Sylwester Sosnowski + * Wilfried "Wonka" Klaebe * */ @@ -49,7 +51,8 @@ struct n2n_edge int allow_routing /*= 0*/; int drop_ipv6_ndp /*= 0*/; char * encrypt_key /* = NULL*/; - TWOFISH * tf; + TWOFISH * enc_tf; + TWOFISH * dec_tf; struct peer_info * known_peers /* = NULL*/; struct peer_info * pending_peers /* = NULL*/; @@ -141,7 +144,7 @@ static char ** buildargv(char * const linebuffer) { char ** argv; char * buffer, * buff; - buffer = (char *)malloc(strlen(linebuffer)+2); + buffer = (char *)calloc(1, strlen(linebuffer)+2); if (!buffer) { traceEvent( TRACE_ERROR, "Unable to allocate memory"); return NULL; @@ -199,7 +202,8 @@ static int edge_init(n2n_edge_t * eee) { eee->allow_routing = 0; eee->drop_ipv6_ndp = 0; eee->encrypt_key = NULL; - eee->tf = NULL; + eee->enc_tf = NULL; + eee->dec_tf = NULL; eee->known_peers = NULL; eee->pending_peers = NULL; eee->last_register = 0; @@ -214,9 +218,10 @@ static int edge_init(n2n_edge_t * eee) { static int edge_init_twofish( n2n_edge_t * eee, u_int8_t *encrypt_pwd, u_int32_t encrypt_pwd_len ) { - eee->tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len); + eee->enc_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len); + eee->dec_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len); - if ( eee->tf ) + if ( (eee->enc_tf) && (eee->dec_tf) ) { return 0; } @@ -229,7 +234,8 @@ static int edge_init_twofish( n2n_edge_t * eee, u_int8_t *encrypt_pwd, u_int32_t /* ************************************** */ static void edge_deinit(n2n_edge_t * eee) { - TwoFishDestroy(eee->tf); + TwoFishDestroy(eee->enc_tf); + TwoFishDestroy(eee->dec_tf); if ( eee->sinfo.sock >=0 ) { close( eee->sinfo.sock ); @@ -248,6 +254,7 @@ static void help() { "-a " "-c " "-k " + "-s " #ifndef WIN32 "[-u -g ]" "[-f]" @@ -255,7 +262,7 @@ static void help() { "[-m ]" "\n" "-l " - "[-p ] " + "[-p ] [-M ] " "[-t] [-r] [-v] [-b] [-h]\n\n"); #ifdef __linux__ @@ -265,6 +272,7 @@ static void help() { printf("-a | n2n IP address\n"); printf("-c | n2n community name\n"); printf("-k | Encryption key (ASCII) - also N2N_KEY=\n"); + printf("-s | Edge interface netmask in dotted decimal notation (255.255.255.0)\n"); printf("-l | Supernode IP:port\n"); printf("-b | Periodically resolve supernode IP\n"); printf(" | (when supernodes are running on dynamic IPs)\n"); @@ -276,6 +284,7 @@ static void help() { #endif printf("-m | Choose a MAC address for the TAP interface\n" " | eg. -m 01:02:03:04:05:06\n"); + printf("-M | Specify n2n MTU (default %d)\n", DEFAULT_MTU); printf("-t | Use http tunneling (experimental)\n"); printf("-r | Enable packet forwarding through n2n community\n"); printf("-v | Verbose\n"); @@ -288,7 +297,6 @@ static void help() { /* *********************************************** */ - static void send_register( n2n_edge_t * eee, const struct peer_addr *remote_peer, u_char is_ack) { @@ -303,9 +311,9 @@ static void send_register( n2n_edge_t * eee, memcpy(hdr.community_name, eee->community_name, COMMUNITY_LEN); marshall_n2n_packet_header( (u_int8_t *)pkt, &hdr ); - send_packet( &(eee->sinfo), pkt, &len, remote_peer, 1 ); + send_packet( &(eee->sinfo), pkt, &len, remote_peer, N2N_COMPRESSION_ENABLED ); - traceEvent(TRACE_INFO, "Sent %s message to %s:%d", + traceEvent(TRACE_INFO, "Sent %s message to %s:%hd", ((hdr.msg_type==MSG_TYPE_REGISTER)?"MSG_TYPE_REGISTER":"MSG_TYPE_REGISTER_ACK"), intoa(ntohl(remote_peer->addr_type.v4_addr), ip_buf, sizeof(ip_buf)), ntohs(remote_peer->port)); @@ -325,7 +333,7 @@ static void send_deregister(n2n_edge_t * eee, memcpy(hdr.community_name, eee->community_name, COMMUNITY_LEN); marshall_n2n_packet_header( (u_int8_t *)pkt, &hdr ); - send_packet( &(eee->sinfo), pkt, &len, remote_peer, 1); + send_packet( &(eee->sinfo), pkt, &len, remote_peer, N2N_COMPRESSION_ENABLED); } /* *********************************************** */ @@ -377,7 +385,7 @@ void try_send_register( n2n_edge_t * eee, traceEvent( TRACE_NORMAL, "Pending peers list size=%ld", peer_list_size( eee->pending_peers ) ); - traceEvent( TRACE_NORMAL, "Sending REGISTER request to %s:%d", + traceEvent( TRACE_NORMAL, "Sending REGISTER request to %s:%hd", intoa(ntohl(scan->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), ntohs(scan->public_ip.port)); @@ -396,7 +404,7 @@ void try_send_register( n2n_edge_t * eee, /* over-write supernode-based socket with direct socket. */ scan->public_ip = hdr->public_ip; - traceEvent( TRACE_NORMAL, "Sending additional REGISTER request to %s:%d", + traceEvent( TRACE_NORMAL, "Sending additional REGISTER request to %s:%hd", intoa(ntohl(scan->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), ntohs(scan->public_ip.port)); @@ -473,7 +481,7 @@ void set_peer_operational( n2n_edge_t * eee, const struct n2n_packet_header * hd scan->public_ip = hdr->public_ip; - traceEvent(TRACE_INFO, "=== new peer [mac=%s][socket=%s:%d]", + traceEvent(TRACE_INFO, "=== new peer [mac=%s][socket=%s:%hd]", macaddr_str(scan->mac_addr, mac_buf, sizeof(mac_buf)), intoa(ntohl(scan->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), ntohs(scan->public_ip.port)); @@ -501,7 +509,7 @@ void trace_registrations( struct peer_info * scan ) while ( scan ) { - traceEvent(TRACE_INFO, "=== peer [mac=%s][socket=%s:%d]", + traceEvent(TRACE_INFO, "=== peer [mac=%s][socket=%s:%hd]", macaddr_str(scan->mac_addr, mac_buf, sizeof(mac_buf)), intoa(ntohl(scan->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), ntohs(scan->public_ip.port)); @@ -563,7 +571,7 @@ static void update_peer_address(n2n_edge_t * eee, { if ( 0 == hdr->sent_by_supernode ) { - traceEvent( TRACE_NORMAL, "Peer changed public socket, Was %s:%d", + traceEvent( TRACE_NORMAL, "Peer changed public socket, Was %s:%hd", intoa(ntohl(hdr->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), ntohs(hdr->public_ip.port)); @@ -686,7 +694,7 @@ static int find_peer_destination(n2n_edge_t * eee, mac_address[3] & 0xFF, mac_address[4] & 0xFF, mac_address[5] & 0xFF); while(scan != NULL) { - traceEvent(TRACE_INFO, "Evaluating peer [MAC=%02X:%02X:%02X:%02X:%02X:%02X][ip=%s:%d]", + traceEvent(TRACE_INFO, "Evaluating peer [MAC=%02X:%02X:%02X:%02X:%02X:%02X][ip=%s:%hd]", scan->mac_addr[0] & 0xFF, scan->mac_addr[1] & 0xFF, scan->mac_addr[2] & 0xFF, scan->mac_addr[3] & 0xFF, scan->mac_addr[4] & 0xFF, scan->mac_addr[5] & 0xFF, intoa(ntohl(scan->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), @@ -707,7 +715,7 @@ static int find_peer_destination(n2n_edge_t * eee, memcpy(destination, &(eee->supernode), sizeof(struct sockaddr_in)); } - traceEvent(TRACE_INFO, "find_peer_address(%s) -> [socket=%s:%d]", + traceEvent(TRACE_INFO, "find_peer_address(%s) -> [socket=%s:%hd]", macaddr_str( (char *)mac_address, mac_buf, sizeof(mac_buf)), intoa(ntohl(destination->addr_type.v4_addr), ip_buf, sizeof(ip_buf)), ntohs(destination->port)); @@ -746,18 +754,17 @@ static void send_packet2net(n2n_edge_t * eee, /* Discard IP packets that are not originated by this hosts */ if(!(eee->allow_routing)) { if(ntohs(eh->ether_type) == 0x0800) { - /* This is an IP packet from the local source address - not forwarded. */ #define ETH_FRAMESIZE 14 #define IP4_SRCOFFSET 12 -#define IP4_ADDRSIZE 4 + u_int32_t *dst = (u_int32_t*)&decrypted_msg[ETH_FRAMESIZE + IP4_SRCOFFSET]; + /* Note: all elements of the_ip are in network order */ - if( 0 != memcmp( decrypted_msg + ETH_FRAMESIZE + IP4_SRCOFFSET, - &(eee->device.ip_addr), - IP4_ADDRSIZE ) ) { - /* This is a packet that needs to be routed */ - traceEvent(TRACE_INFO, "Discarding routed packet"); - return; + if( *dst != eee->device.ip_addr) { + /* This is a packet that needs to be routed */ + traceEvent(TRACE_INFO, "Discarding routed packet [%s]", + intoa(ntohl(*dst), ip_buf, sizeof(ip_buf))); + return; } else { /* This packet is originated by us */ /* traceEvent(TRACE_INFO, "Sending non-routed packet"); */ @@ -767,7 +774,7 @@ static void send_packet2net(n2n_edge_t * eee, /* Encrypt "decrypted_msg" into the second half of the n2n packet. */ len = TwoFishEncryptRaw((u_int8_t *)decrypted_msg, - (u_int8_t *)&packet[N2N_PKT_HDR_SIZE], len, eee->tf); + (u_int8_t *)&packet[N2N_PKT_HDR_SIZE], len, eee->enc_tf); /* Add the n2n header to the start of the n2n packet. */ fill_standard_header_fields( &(eee->sinfo), &hdr, (char*)(eee->device.mac_addr) ); @@ -781,7 +788,7 @@ static void send_packet2net(n2n_edge_t * eee, len += N2N_PKT_HDR_SIZE; if(find_peer_destination(eee, eh->ether_dhost, &destination)) - traceEvent(TRACE_INFO, "** Going direct [dst_mac=%s][dest=%s:%d]", + traceEvent(TRACE_INFO, "** Going direct [dst_mac=%s][dest=%s:%hd]", macaddr_str((char*)eh->ether_dhost, mac_buf, sizeof(mac_buf)), intoa(ntohl(destination.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), ntohs(destination.port)); @@ -790,7 +797,8 @@ static void send_packet2net(n2n_edge_t * eee, macaddr_str((char*)eh->ether_shost, mac_buf, sizeof(mac_buf)), macaddr_str((char*)eh->ether_dhost, mac2_buf, sizeof(mac2_buf))); - data_sent_len = reliable_sendto( &(eee->sinfo), packet, &len, &destination, 1); + data_sent_len = reliable_sendto( &(eee->sinfo), packet, &len, &destination, + N2N_COMPRESSION_ENABLED); if(data_sent_len != len) traceEvent(TRACE_WARNING, "sendto() [sent=%d][attempted_to_send=%d] [%s]\n", @@ -850,6 +858,8 @@ static int check_received_packet(n2n_edge_t * eee, char *pkt, } else if(pkt_len > 32 /* IP + Ethernet */) { /* Check if this packet is for us or if it's routed */ struct ether_header *eh = (struct ether_header*)pkt; + + const struct in_addr bcast = { 0xffffffff }; if(ntohs(eh->ether_type) == 0x0800) { @@ -857,8 +867,14 @@ static int check_received_packet(n2n_edge_t * eee, char *pkt, struct ip *the_ip = (struct ip*)(pkt+sizeof(struct ether_header)); if((the_ip->ip_dst.s_addr != eee->device.ip_addr) - && ((the_ip->ip_dst.s_addr & eee->device.device_mask) != (eee->device.ip_addr & eee->device.device_mask))) /* Not a broadcast */ - { + && ((the_ip->ip_dst.s_addr & eee->device.device_mask) != (eee->device.ip_addr & eee->device.device_mask)) /* Not a broadcast */ + && ((the_ip->ip_dst.s_addr & 0xE0000000) != (0xE0000000 /* 224.0.0.0-239.255.255.255 */)) /* Not a multicast */ + && ((the_ip->ip_dst.s_addr) != (bcast.s_addr)) /* always broadcast (RFC919) */ + && (!(eee->allow_routing)) /* routing is enabled so let it in */ + ) + { + /* Dropping the packet */ + ipstr_t ip_buf; ipstr_t ip_buf2; @@ -866,7 +882,7 @@ static int check_received_packet(n2n_edge_t * eee, char *pkt, traceEvent(TRACE_INFO, "Discarding routed packet [rcvd=%s][expected=%s]", intoa(ntohl(the_ip->ip_dst.s_addr), ip_buf, sizeof(ip_buf)), intoa(ntohl(eee->device.ip_addr), ip_buf2, sizeof(ip_buf2))); - } else { + } else { /* This packet is for us */ /* traceEvent(TRACE_INFO, "Received non-routed packet"); */ @@ -927,7 +943,8 @@ void readFromIPSocket( n2n_edge_t * eee ) struct n2n_packet_header hdr_storage; len = receive_data( &(eee->sinfo), packet, sizeof(packet), &sender, - &discarded_pkt, (char*)(eee->device.mac_addr), 1, &hdr_storage); + &discarded_pkt, (char*)(eee->device.mac_addr), + N2N_COMPRESSION_ENABLED, &hdr_storage); if(len <= 0) return; @@ -944,7 +961,7 @@ void readFromIPSocket( n2n_edge_t * eee ) else { struct n2n_packet_header *hdr = &hdr_storage; - traceEvent(TRACE_INFO, "Received packet from %s:%d", + traceEvent(TRACE_INFO, "Received packet from %s:%hd", intoa(ntohl(sender.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), ntohs(sender.port)); @@ -953,7 +970,7 @@ void readFromIPSocket( n2n_edge_t * eee ) hdr->sent_by_supernode ? "supernode" : "peer", macaddr_str(hdr->dst_mac, mac_buf, sizeof(mac_buf))); - if(hdr->version != N2N_VERSION) { + if(hdr->version != N2N_PKT_VERSION) { traceEvent(TRACE_WARNING, "Received packet with unknown protocol version (%d): discarded\n", hdr->version); @@ -978,7 +995,7 @@ void readFromIPSocket( n2n_edge_t * eee ) /* Decrypt message first */ len = TwoFishDecryptRaw((u_int8_t *)&packet[N2N_PKT_HDR_SIZE], - (u_int8_t *)decrypted_msg, len, eee->tf); + (u_int8_t *)decrypted_msg, len, eee->dec_tf); if(len > 0) { if(check_received_packet(eee, decrypted_msg, len) == 0) { @@ -998,13 +1015,13 @@ void readFromIPSocket( n2n_edge_t * eee ) traceEvent(TRACE_INFO, "### Tx L2 Msg -> tun"); } } else { - traceEvent(TRACE_WARNING, "Bad destination: message discarded"); + traceEvent(TRACE_WARNING, "Bad destination: message discarded"); } } /* else silently ignore empty packet. */ } else if(hdr->msg_type == MSG_TYPE_REGISTER) { - traceEvent(TRACE_INFO, "Received registration request from remote peer [ip=%s:%d]", + traceEvent(TRACE_INFO, "Received registration request from remote peer [ip=%s:%hd]", intoa(ntohl(hdr->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), ntohs(hdr->public_ip.port)); if ( 0 == memcmp(hdr->dst_mac, (eee->device.mac_addr), 6) ) @@ -1015,7 +1032,7 @@ void readFromIPSocket( n2n_edge_t * eee ) send_register(eee, &hdr->public_ip, 1); /* Send ACK back */ } else if(hdr->msg_type == MSG_TYPE_REGISTER_ACK) { - traceEvent(TRACE_NORMAL, "Received REGISTER_ACK from remote peer [ip=%s:%d]", + traceEvent(TRACE_NORMAL, "Received REGISTER_ACK from remote peer [ip=%s:%hd]", intoa(ntohl(hdr->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), ntohs(hdr->public_ip.port)); @@ -1116,7 +1133,7 @@ static void supernode2addr(n2n_edge_t * eee, char* addr) { eee->supernode.addr_type.v4_addr = inet_addr(supernode_host); } - traceEvent(TRACE_NORMAL, "Using supernode %s:%d", + traceEvent(TRACE_NORMAL, "Using supernode %s:%hd", intoa(ntohl(eee->supernode.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), ntohs(eee->supernode.port)); } else @@ -1127,10 +1144,16 @@ static void supernode2addr(n2n_edge_t * eee, char* addr) { extern int useSyslog; +#define N2N_NETMASK_STR_SIZE 16 /* dotted decimal 12 numbers + 3 dots */ + + int main(int argc, char* argv[]) { int opt, local_port = 0 /* any port */; char *tuntap_dev_name = "edge0"; char *ip_addr = NULL; + char netmask[N2N_NETMASK_STR_SIZE]="255.255.255.0"; + int mtu = DEFAULT_MTU; + int got_s = 0; #ifndef WIN32 uid_t userid=0; /* root is the only guaranteed ID */ @@ -1142,7 +1165,7 @@ int main(int argc, char* argv[]) { time_t lastStatus=0; char * device_mac=NULL; - char * encrypt_key; + char * encrypt_key=NULL; int i, effectiveargc=0; char ** effectiveargv=NULL; @@ -1171,6 +1194,12 @@ int main(int argc, char* argv[]) { exit(1); } snprintf(linebuffer, MAX_CMDLINE_BUFFER_LENGTH, "%s",argv[0]); + +#ifdef WIN32 + for(i=0; i + * (C) 2007-09 - Luca Deri + * Richard Andrews * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -74,10 +75,13 @@ extern void peer_addr2sockaddr_in(const struct peer_addr *in, struct sockaddr_in /* ************************************** */ static -int marshall_peer_addr( u_int8_t * buf, const struct peer_addr * s ) +int marshall_peer_addr( u_int8_t * buf, size_t * offset, const struct peer_addr * s ) { - memcpy( buf, s, sizeof(struct peer_addr)); - buf += sizeof(struct peer_addr); + /* RA: I'm pretty sure that this is broken. There is no guarantee that the + * peer_addr structure is packed. This will always work between like hosts but + * is almost certainly broken between different host types. */ + memcpy( buf + *offset, s, sizeof(struct peer_addr)); + *offset += sizeof(struct peer_addr); return sizeof(struct peer_addr); /* bytes written */ } @@ -85,74 +89,80 @@ int marshall_peer_addr( u_int8_t * buf, const struct peer_addr * s ) /* ************************************** */ static -int marshall_uint32( u_int8_t * buf, u_int32_t val ) +int marshall_uint32( u_int8_t * buf, size_t * offset, u_int32_t val ) { - u_int32_t * nu32 = (u_int32_t *)buf; - *nu32 = htonl(val); + buf[*offset + 0] = ((val >> 24) & 0xff); + buf[*offset + 1] = ((val >> 16) & 0xff); + buf[*offset + 2] = ((val >> 8) & 0xff); + buf[*offset + 3] = ((val ) & 0xff); - return 4; + *offset += 4; + return 4; } /* ************************************** */ int marshall_n2n_packet_header( u_int8_t * buf, const struct n2n_packet_header * hdr ) { - u_int8_t * bufStart = buf; + size_t offset = 0; print_header( "Marshalling ", hdr ); - *buf = hdr->version; - ++buf; + *(buf+offset) = hdr->version; + ++offset; - *buf = hdr->msg_type; - ++buf; + *(buf+offset) = hdr->msg_type; + ++offset; - *buf = hdr->ttl; - ++buf; + *(buf+offset) = hdr->ttl; + ++offset; - *buf = hdr->sent_by_supernode; - ++buf; + *(buf+offset) = hdr->sent_by_supernode; + ++offset; - memcpy( buf, hdr->community_name, COMMUNITY_LEN ); - buf += COMMUNITY_LEN; + memcpy( buf+offset, hdr->community_name, COMMUNITY_LEN ); + offset += COMMUNITY_LEN; - memcpy( buf, hdr->src_mac, 6 ); - buf += 6; + memcpy( buf+offset, hdr->src_mac, 6 ); + offset += 6; - memcpy( buf, hdr->dst_mac, 6 ); - buf += 6; + memcpy( buf+offset, hdr->dst_mac, 6 ); + offset += 6; - buf += marshall_peer_addr( buf, &(hdr->public_ip) ); - buf += marshall_peer_addr( buf, &(hdr->private_ip) ); + marshall_peer_addr( buf, &offset, &(hdr->public_ip) ); + marshall_peer_addr( buf, &offset, &(hdr->private_ip) ); - *buf = (hdr->pkt_type & 0xff); - ++buf; + *(buf+offset) = (hdr->pkt_type & 0xff); + ++offset; - buf += marshall_uint32( buf, hdr->sequence_id ); - buf += marshall_uint32( buf, hdr->crc ); + marshall_uint32( buf, &offset, hdr->sequence_id ); + marshall_uint32( buf, &offset, hdr->crc ); - return (buf - bufStart); + return offset; } /* ************************************** */ static -int unmarshall_peer_addr( struct peer_addr * s, +int unmarshall_peer_addr( struct peer_addr * s, size_t * offset, const u_int8_t * buf ) { - memcpy(s, buf, sizeof(struct peer_addr)); - buf += sizeof(struct peer_addr); + memcpy(s, buf + *offset, sizeof(struct peer_addr)); + *offset += sizeof(struct peer_addr); return (sizeof(struct peer_addr)); /* bytes written */ } /* ************************************** */ static -int unmarshall_uint32( u_int32_t * val, const u_int8_t * buf ) +int unmarshall_uint32( u_int32_t * val, size_t * offset, const u_int8_t * buf ) { - u_int32_t * nu32 = (u_int32_t *)buf; - *val = ntohl(*nu32); + *val = ( (buf[*offset + 0] & 0xff) << 24 ); + *val |= ( (buf[*offset + 1] & 0xff) << 16 ); + *val |= ( (buf[*offset + 2] & 0xff) << 8 ); + *val |= ( (buf[*offset + 3] & 0xff) ); + *offset += 4; return 4; } @@ -160,41 +170,41 @@ int unmarshall_uint32( u_int32_t * val, const u_int8_t * buf ) int unmarshall_n2n_packet_header( struct n2n_packet_header * hdr, const u_int8_t * buf ) { - const u_int8_t * bufStart = buf; + size_t offset=0; - hdr->version = *buf; - ++buf; + hdr->version = *(buf + offset); + ++offset; - hdr->msg_type = *buf; - ++buf; + hdr->msg_type = *(buf + offset); + ++offset; - hdr->ttl = *buf; - ++buf; + hdr->ttl = *(buf + offset); + ++offset; - hdr->sent_by_supernode = *buf; - ++buf; + hdr->sent_by_supernode = *(buf + offset); + ++offset; - memcpy( hdr->community_name, buf, COMMUNITY_LEN ); - buf += COMMUNITY_LEN; + memcpy( hdr->community_name, (buf + offset), COMMUNITY_LEN ); + offset += COMMUNITY_LEN; - memcpy( hdr->src_mac, buf, 6 ); - buf += 6; + memcpy( hdr->src_mac, (buf + offset), 6 ); + offset += 6; - memcpy( hdr->dst_mac, buf, 6 ); - buf += 6; + memcpy( hdr->dst_mac, (buf + offset), 6 ); + offset += 6; - buf += unmarshall_peer_addr( &(hdr->public_ip), buf ); - buf += unmarshall_peer_addr( &(hdr->private_ip), buf ); + unmarshall_peer_addr( &(hdr->public_ip), &offset, buf ); + unmarshall_peer_addr( &(hdr->private_ip), &offset, buf ); - hdr->pkt_type = (*buf & 0xff); /* Make sure only 8 bits are copied. */ - ++buf; + hdr->pkt_type = (*(buf + offset) & 0xff); /* Make sure only 8 bits are copied. */ + ++offset; - buf += unmarshall_uint32( &(hdr->sequence_id), buf ); - buf += unmarshall_uint32( &(hdr->crc), buf ); + unmarshall_uint32( &(hdr->sequence_id), &offset, buf ); + unmarshall_uint32( &(hdr->crc), &offset, buf ); print_header( "Unmarshalled ", hdr ); - return (buf - bufStart); + return offset; } /* ************************************** */ @@ -292,7 +302,9 @@ void traceEvent(int eventTraceLevel, char* file, int line, char * format, ...) { char theDate[N2N_TRACE_DATESIZE]; char *extra_msg = ""; time_t theTime = time(NULL); - +#ifdef WIN32 + int i; +#endif /* We have two paths - one if we're logging, one if we aren't * Note that the no-log case is those systems which don't support it (WIN32), @@ -330,7 +342,8 @@ void traceEvent(int eventTraceLevel, char* file, int line, char * format, ...) { } #else /* this is the WIN32 code */ - snprintf(out_buf, sizeof(out_buf), "%s [%11s:%4d] %s%s", theDate, file, line, extra_msg, buf); + for(i=strlen(file)-1; i>0; i--) if(file[i] == '\\') { i++; break; }; + snprintf(out_buf, sizeof(out_buf), "%s [%11s:%4d] %s%s", theDate, &file[i], line, extra_msg, buf); printf("%s\n", out_buf); fflush(stdout); #endif @@ -385,7 +398,7 @@ void fill_standard_header_fields(n2n_sock_info_t * sinfo, struct n2n_packet_header *hdr, char *src_mac) { socklen_t len = sizeof(hdr->private_ip); memset(hdr, 0, N2N_PKT_HDR_SIZE); - hdr->version = N2N_VERSION; + hdr->version = N2N_PKT_VERSION; hdr->crc = 0; // FIX if(src_mac != NULL) memcpy(hdr->src_mac, src_mac, 6); getsockname(sinfo->sock, (struct sockaddr*)&hdr->private_ip, &len); @@ -405,6 +418,7 @@ void send_ack(n2n_sock_info_t * sinfo, u_int8_t pkt[ N2N_PKT_HDR_SIZE ]; size_t len = sizeof(hdr); size_t len2; + int compress_data = N2N_COMPRESSION_ENABLED; fill_standard_header_fields(sinfo, &hdr, src_mac); hdr.msg_type = MSG_TYPE_ACK_RESPONSE; @@ -414,7 +428,7 @@ void send_ack(n2n_sock_info_t * sinfo, len2=marshall_n2n_packet_header( pkt, &hdr ); assert( len2 == len ); - send_packet(sinfo, (char*)pkt, &len, remote_peer, 1); + send_packet(sinfo, (char*)pkt, &len, remote_peer, compress_data); } /* *********************************************** */ @@ -469,17 +483,26 @@ u_int receive_data(n2n_sock_info_t * sinfo, #endif return(0); } else if(len > MIN_COMPRESSED_PKT_LEN) { - char decompressed[2048]; +#define N2N_DECOMPRESS_BUFSIZE 2048 + char decompressed[N2N_DECOMPRESS_BUFSIZE]; int rc; - lzo_uint decompressed_len; + lzo_uint decompressed_len=N2N_DECOMPRESS_BUFSIZE; + size_t insize = len-N2N_PKT_HDR_SIZE; if(decompress_data) { - rc = lzo1x_decompress((u_char*)&packet[N2N_PKT_HDR_SIZE], - len-N2N_PKT_HDR_SIZE, - (u_char*)decompressed, &decompressed_len, NULL); + rc = lzo1x_decompress_safe((u_char*)&packet[N2N_PKT_HDR_SIZE], + insize, + (u_char*)decompressed, &decompressed_len, NULL); if(rc == LZO_E_OK) - traceEvent(TRACE_INFO, "%u bytes decompressed into %u", len, decompressed_len); + { + traceEvent(TRACE_INFO, "%u bytes decompressed into %u", insize, decompressed_len); + } + else + { + traceEvent(TRACE_WARNING, "Failed to decompress %u byte packet. LZO error=%d", insize, rc ); + return -1; + } if(packet_len > decompressed_len) { memcpy(&packet[N2N_PKT_HDR_SIZE], decompressed, decompressed_len); @@ -584,9 +607,9 @@ static HEAP_ALLOC(wrkmem,LZO1X_1_MEM_COMPRESS); u_int send_data(n2n_sock_info_t * sinfo, char *packet, size_t *packet_len, const struct peer_addr *to, u_int8_t compress_data) { - char compressed[1600]; + char compressed[1650]; int rc; - lzo_uint compressed_len; + lzo_uint compressed_len=0; struct sockaddr_in destsock; if(*packet_len < N2N_PKT_HDR_SIZE) { @@ -603,6 +626,13 @@ u_int send_data(n2n_sock_info_t * sinfo, *packet_len - N2N_PKT_HDR_SIZE, (u_char*)&compressed[N2N_PKT_HDR_SIZE], &compressed_len, wrkmem); + + if ( 0 == compressed_len ) + { + traceEvent(TRACE_WARNING, "failed to compress %u bytes.", (*packet_len - N2N_PKT_HDR_SIZE) ); + return -1; + } + compressed_len += N2N_PKT_HDR_SIZE; traceEvent(TRACE_INFO, "%u bytes compressed into %u", *packet_len, compressed_len); diff --git a/n2n.h b/n2n.h index aaded83..e5fa8e0 100644 --- a/n2n.h +++ b/n2n.h @@ -1,5 +1,6 @@ /* - * (C) 2007-08 - Luca Deri + * (C) 2007-09 - Luca Deri + * Richard Andrews * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,6 @@ * along with this program; if not, see * * Code contributions courtesy of: - * Richard Andrews * Babak Farrokhi [FreeBSD port] * */ @@ -113,7 +113,7 @@ typedef struct tuntap_dev { #endif /* #ifndef WIN32 */ #define QUICKLZ 1 -#define N2N_VERSION 1 +#define N2N_PKT_VERSION 1 #define MSG_TYPE_REGISTER 1 /* FIX invece di usare il sender del pacchetto scriverlo nel pacchetto stesso */ #define MSG_TYPE_DEREGISTER 2 @@ -124,6 +124,14 @@ typedef struct tuntap_dev { #define COMMUNITY_LEN 16 #define MIN_COMPRESSED_PKT_LEN 32 +/* Set N2N_COMPRESSION_ENABLED to 0 to disable lzo1x compression of ethernet + * frames. Doing this will break compatibility with the standard n2n packet + * format so do it only for experimentation. All edges must be built with the + * same value if they are to understand each other. */ +#define N2N_COMPRESSION_ENABLED 1 + +#define DEFAULT_MTU 1400 + /* Maximum enum value is 255 due to marshalling into 1 byte */ enum packet_type { packet_unreliable_data = 0, /* no ACK needed */ @@ -234,7 +242,8 @@ extern void send_ack(n2n_sock_info_t * sinfo, char *src_mac); extern void traceEvent(int eventTraceLevel, char* file, int line, char * format, ...); -extern int tuntap_open(tuntap_dev *device, char *dev, char *device_ip, char *device_mask, const char * device_mac ); +extern int tuntap_open(tuntap_dev *device, char *dev, char *device_ip, + char *device_mask, const char * device_mac, int mtu); extern int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len); extern int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len); extern void tuntap_close(struct tuntap_dev *tuntap); diff --git a/n2n.spec b/n2n.spec index 8eede44..0e7892a 100644 --- a/n2n.spec +++ b/n2n.spec @@ -1,6 +1,6 @@ Summary: N2N peer-to-peer virtual private network system. Name: n2n -Version: 1.2 +Version: 1.3 Release: 1 License: GPLv3 Vendor: ntop.org diff --git a/scripts/mk_tar.sh b/scripts/mk_tar.sh index 347191b..539a565 100755 --- a/scripts/mk_tar.sh +++ b/scripts/mk_tar.sh @@ -22,7 +22,7 @@ function exit_fail() } PACKAGE="n2n" -PKG_VERSION="1.2" +PKG_VERSION="1.3" PKG_AND_VERSION="${PACKAGE}-${PKG_VERSION}" TEMPDIR="tmp" @@ -50,7 +50,6 @@ debian/changelog debian/compat debian/control debian/copyright -debian/files debian/n2n.dirs debian/n2n.docs debian/n2n.install @@ -62,7 +61,7 @@ debian/rules BASE=`pwd` for F in ${SOURCE_MANIFEST}; do - test -e $F || exit_fail "Wrong directory. Please execute from n2n directory."; >&2 + test -e $F || exit_fail "Cannot find $F. Maybe you're in the wrong directory. Please execute from n2n directory."; >&2 done echo "Found critical files. Proceeding." >&2 diff --git a/supernode.1 b/supernode.1 index 808f803..863c498 100644 --- a/supernode.1 +++ b/supernode.1 @@ -1,4 +1,4 @@ -.TH supernode 1 "May 3, 2008" "revision 3472" "USER COMMANDS" +.TH supernode 1 "Jan 3, 2009" "revision 3679" "USER COMMANDS" .SH NAME supernode \- n2n supernode daemon .SH SYNOPSIS @@ -12,11 +12,15 @@ packets only between members of the same community. The supernode does not hold the community encryption key and so cannot snoop or inject packets into the community. .PP +Supernode can service a number of n2n communities concurrently. Traffic does not +cross between communities. +.PP All logging goes to stdout. .SH OPTIONS .TP -\-l +\-l listen on the given UDP port +.TP \-v use verbose logging .SH EXAMPLES @@ -24,9 +28,13 @@ use verbose logging .B supernode -l 7654 -v Start supernode listening on UDP port 7654 with verbose output. .PP +.SH RESTART +When suprenode restarts it loses all registration information from associated +edge nodes. It can take up to five minutes for the edge nodes to re-register and +normal traffic flow to resume. .SH EXIT STATUS -edge is a daemon and any exit is an error +supernode is a daemon and any exit is an error .SH AUTHOR Luca Deri ( deri (at) ntop.org ), Richard Andrews ( andrews (at) ntop.org ), Don Bindner .SH SEE ALSO -ifconfig(1) edge(1) +ifconfig(8) edge(8) diff --git a/supernode.c b/supernode.c index 4031472..ff41927 100644 --- a/supernode.c +++ b/supernode.c @@ -1,5 +1,6 @@ /* - * (C) 2007-08 - Luca Deri + * (C) 2007-09 - Luca Deri + * Richard Andrews * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,9 +15,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, see * - * Code contributions courtesy of: - * Richard Andrews - * */ #include "n2n.h" @@ -65,7 +63,7 @@ static void send_register_ack( n2n_sock_info_t * sinfo, /* leave IP sockets unfilled. */ marshall_n2n_packet_header( pkt, &hdr ); - send_packet(sinfo, (char *)pkt, &len, destination_peer, 1); + send_packet(sinfo, (char *)pkt, &len, destination_peer, N2N_COMPRESSION_ENABLED); } static void register_peer(struct n2n_packet_header *hdr, @@ -90,7 +88,7 @@ static void register_peer(struct n2n_packet_header *hdr, memcpy(&scan->private_ip, &hdr->private_ip, sizeof(struct peer_addr)); /* Overwrite existing peer */ - traceEvent(TRACE_NORMAL, "Re-registered node [public_ip=(%d)%s:%d][private_ip=%s:%d][mac=%s][community=%s]", + traceEvent(TRACE_NORMAL, "Re-registered node [public_ip=(%d)%s:%hd][private_ip=%s:%hd][mac=%s][community=%s]", scan->public_ip.family, intoa(ntohl(scan->public_ip.addr_type.v4_addr), buf, sizeof(buf)), ntohs(scan->public_ip.port), @@ -144,7 +142,7 @@ static void deregister_peer(struct n2n_packet_header *hdr, else prev->next = scan->next; - traceEvent(TRACE_INFO, "Degistered node [public_ip=%s:%d][private_ip=%s:%d]", + traceEvent(TRACE_INFO, "Degistered node [public_ip=%s:%hd][private_ip=%s:%hd]", intoa(ntohl(scan->public_ip.addr_type.v4_addr), buf, sizeof(buf)), ntohs(scan->public_ip.port), intoa(ntohl(scan->private_ip.addr_type.v4_addr), buf1, sizeof(buf1)), @@ -157,7 +155,7 @@ static void deregister_peer(struct n2n_packet_header *hdr, scan = scan->next; } - traceEvent(TRACE_WARNING, "Unable to delete specified peer [%s:%d]", + traceEvent(TRACE_WARNING, "Unable to delete specified peer [%s:%hd]", intoa(ntohl(sender->addr_type.v4_addr), buf, sizeof(buf)), ntohs(sender->port)); } @@ -213,7 +211,7 @@ static size_t broadcast_packet(char *packet, u_int packet_len, ++numsent; ++(supernode_stats.pkts); - traceEvent(TRACE_INFO, "Sent multicast message to remote node [%s:%d][mac=%s]", + traceEvent(TRACE_INFO, "Sent multicast message to remote node [%s:%hd][mac=%s]", intoa(ntohl(scan->public_ip.addr_type.v4_addr), buf, sizeof(buf)), ntohs(scan->public_ip.port), macaddr_str(scan->mac_addr, buf1, sizeof(buf1))); @@ -287,7 +285,7 @@ static size_t forward_packet(char *packet, u_int packet_len, } else { ++(supernode_stats.pkts); - traceEvent(TRACE_INFO, "Sent message to remote node [%s:%d][mac=%s]", + traceEvent(TRACE_INFO, "Sent message to remote node [%s:%hd][mac=%s]", intoa(ntohl(scan->public_ip.addr_type.v4_addr), buf, sizeof(buf)), ntohs(scan->public_ip.port), macaddr_str(scan->mac_addr, buf1, sizeof(buf1))); @@ -311,7 +309,7 @@ static void handle_packet(char *packet, u_int packet_len, n2n_sock_info_t * sinfo) { ipstr_t buf; - traceEvent(TRACE_INFO, "Received message from node [%s:%d]", + traceEvent(TRACE_INFO, "Received message from node [%s:%hd]", intoa(ntohl(sender->addr_type.v4_addr), buf, sizeof(buf)), ntohs(sender->port)); @@ -323,7 +321,7 @@ static void handle_packet(char *packet, u_int packet_len, unmarshall_n2n_packet_header( hdr, (u_int8_t *)packet ); - if(hdr->version != N2N_VERSION) { + if(hdr->version != N2N_PKT_VERSION) { traceEvent(TRACE_WARNING, "Received packet with unknown protocol version (%d): discarded\n", hdr->version); @@ -445,6 +443,10 @@ int main(int argc, char* argv[]) { n2n_sock_info_t udp_sinfo; n2n_sock_info_t tcp_sinfo; +#ifdef WIN32 + initWin32(); +#endif + optarg = NULL; while((opt = getopt_long(argc, argv, "l:vh", long_options, NULL)) != EOF) { switch (opt) { diff --git a/tuntap_freebsd.c b/tuntap_freebsd.c index f4a03a8..95308be 100644 --- a/tuntap_freebsd.c +++ b/tuntap_freebsd.c @@ -1,5 +1,5 @@ /* - * (C) 2007-08 - Luca Deri + * (C) 2007-09 - Luca Deri * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,7 +28,8 @@ int tuntap_open(tuntap_dev *device /* ignored */, char *dev, char *device_ip, char *device_mask, - const char * device_mac ) { + const char * device_mac, + int mtu) { int i; char tap_device[N2N_FREEBSD_TAPDEVICE_SIZE]; @@ -61,8 +62,8 @@ int tuntap_open(tuntap_dev *device /* ignored */, system(buf); } - snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu 1400 up", - i, device_ip, device_mask); + snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", + i, device_ip, device_mask, mtu); system(buf); traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", diff --git a/tuntap_linux.c b/tuntap_linux.c index 7e90ea6..a1d20fb 100644 --- a/tuntap_linux.c +++ b/tuntap_linux.c @@ -1,5 +1,5 @@ /* - * (C) 2007-08 - Luca Deri + * (C) 2007-09 - Luca Deri * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,6 +42,7 @@ static void read_mac(char *ifname, char *mac_addr) { } /* ********************************** */ + /** @brief Open and configure the TAP device for packet read/write. * * This routine creates the interface via the tuntap driver then uses ifconfig @@ -52,6 +53,7 @@ static void read_mac(char *ifname, char *mac_addr) { * if NULL system will assign a name * @param device_ip - address of iface * @param device_mask - netmask for device_ip + * @param mtu - MTU for device_ip * * @return - negative value on error * - non-negative file-descriptor on success @@ -60,7 +62,8 @@ int tuntap_open(tuntap_dev *device, char *dev, /* user-definable interface name, eg. edge0 */ char *device_ip, char *device_mask, - const char * device_mac ) { + const char * device_mac, + int mtu) { char *tuntap_device = "/dev/net/tun"; #define N2N_LINUX_SYSTEMCMD_SIZE 128 char buf[N2N_LINUX_SYSTEMCMD_SIZE]; @@ -69,7 +72,7 @@ int tuntap_open(tuntap_dev *device, device->fd = open(tuntap_device, O_RDWR); if(device->fd < 0) { - printf("ERROR: ioctl() [%s][%d]\n", strerror(errno), rc); + printf("ERROR: ioctl() [%s][%d]\n", strerror(errno), errno); return -1; } @@ -84,10 +87,6 @@ int tuntap_open(tuntap_dev *device, return -1; } - /* REVISIT: BbMja7: MTU should be related to MTU of the interface the tuntap - * is built on. The value 1400 assumes an eth iface with MTU 1500, but would - * fail for ppp at mtu=576. - */ if ( device_mac ) { /* Set the hw address before bringing the if up. */ @@ -97,12 +96,13 @@ int tuntap_open(tuntap_dev *device, traceEvent(TRACE_INFO, "Setting MAC: %s", buf); } - snprintf(buf, sizeof(buf), "/sbin/ifconfig %s %s netmask %s mtu 1400 up", - ifr.ifr_name, device_ip, device_mask); + snprintf(buf, sizeof(buf), "/sbin/ifconfig %s %s netmask %s mtu %d up", + ifr.ifr_name, device_ip, device_mask, mtu); system(buf); traceEvent(TRACE_INFO, "Bringing up: %s", buf); device->ip_addr = inet_addr(device_ip); + device->device_mask = inet_addr(device_mask); read_mac(dev, (char*)device->mac_addr); return(device->fd); } diff --git a/tuntap_osx.c b/tuntap_osx.c index be8b312..c0c4c08 100644 --- a/tuntap_osx.c +++ b/tuntap_osx.c @@ -1,5 +1,5 @@ /* - * (C) 2007-08 - Luca Deri + * (C) 2007-09 - Luca Deri * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,7 +28,8 @@ int tuntap_open(tuntap_dev *device /* ignored */, char *dev, char *device_ip, char *device_mask, - const char * device_mac ) { + const char * device_mac, + int mtu) { int i; char tap_device[N2N_OSX_TAPDEVICE_SIZE]; @@ -61,8 +62,8 @@ int tuntap_open(tuntap_dev *device /* ignored */, system(buf); } - snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu 1400 up", - i, device_ip, device_mask); + snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", + i, device_ip, device_mask, mtu); system(buf); traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", @@ -89,7 +90,7 @@ int tuntap_open(tuntap_dev *device /* ignored */, exit(0); } - traceEvent(TRACE_NORMAL, "Interface tap%d mac %s", i, buf); + traceEvent(TRACE_NORMAL, "Interface tap%d [MTU %d] mac %s", i, mtu, buf); if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { device->mac_addr[0] = a, device->mac_addr[1] = b; device->mac_addr[2] = c, device->mac_addr[3] = d;