Imported Upstream version 1.3.1~svn3789

This commit is contained in:
root 2012-07-21 05:14:09 +00:00
parent ce56f3183d
commit d869f11566
24 changed files with 420 additions and 456 deletions

81
HACKING
View file

@ -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 <bbmaj7@yahoo.com.au>
January 2009 - Richard Andrews <bbmaj7@yahoo.com.au>

View file

@ -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

View file

@ -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 <ole@tange.dk>
deb:
dpkg-buildpackage

34
debian/README.Debian vendored
View file

@ -1,34 +0,0 @@
n2n for Debian
--------------
This package depends on the kernel having the TUN/TAP driver configured in using
CONFIG_TUN=yes.
Quickstart
----------
* Decide where to place your supernode. Suppose you put it on host a.b.c.d
at port xyw.
* Decide what encryption password you want to use to secure your data.
Suppose you use the password encryptme
* Decide the network name you want to use. Suppose you call it mynetwork.
Note that you can use your supernode/edge nodes to handle multiple networks,
not just one.
* Decide what IP address you plan to use on your edge nodes. Suppose you
use IP address 10.1.2.0/24
* Start your applications:
o #supernode > supernode -l xyw
o #edge node1> edge -a 10.1.2.1 -c mynetwork -k encryptme -l a.b.c.d:xyw
o #edge node2> edge -a 10.1.2.2 -c mynetwork -k encryptme -l a.b.c.d:xyw
Now test your n2n network:
o #edge node1> ping 10.1.2.2
o #edge node2> ping 10.1.2.1
For more info check http://www.ntop.org/n2n
-- cristian paul peñaranda rojas <kristian.paul@gmail.com> Sat, 29 Nov 2008 00:31:58 -0500

6
debian/changelog vendored
View file

@ -1,6 +0,0 @@
n2n (1.2.2~svn3653) unstable; urgency=low
* Initial release (closes: Bug#507750)
-- cristian paul peñaranda rojas <kristian.paul@gmail.com> Sat, 29 Nov 2008 00:31:58 -0500

1
debian/compat vendored
View file

@ -1 +0,0 @@
5

14
debian/control vendored
View file

@ -1,14 +0,0 @@
Source: n2n
Section: net
Priority: extra
Maintainer: cristian paul peñaranda rojas <kristian.paul@gmail.com>
Build-Depends: debhelper (>= 5), libc6-dev (>= 2.0), quilt
Standards-Version: 3.8.0
Package: n2n
Architecture: any
Depends: ${shlibs:Depends}
Description: Peer-to-Peer VPN network daemon
n2n is an open source VPN application which utilizes
a Peer-to-peer architecture for network membership
and routing.

110
debian/copyright vendored
View file

@ -1,110 +0,0 @@
This package was debianized by cristian paul peñaranda rojas <kristian.paul@gmail.com> 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'.
Sat, 29 Nov 2008 00:31:58 -0500.
The current Debian maintainer is cristian paul peñaranda rojas <kristian.paul@gmail.com>
It was downloaded from https://svn.ntop.org/svn/ntop/trunk/n2n
Upstream Author: Luca Deri deri@ntop.org
Copyright:
Copyright (C) 2008 Luca Deri
Copyright (C) 2008 Richard Andrews
License:
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
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License with
the Debian GNU/Linux distribution in file /usr/share/common-licenses/GPL;
if not, write to the Free Software Foundation, Inc., 51 Franklin St,
Fifth Floor, Boston, MA 02110-1301, USA.
On Debian systems, the complete text of the GNU General Public
License, version 3, can be found in /usr/share/common-licenses/GPL-3.
The Files:
twofish.c
twofish.h
Copyright (C) 1997-2000 The Cryptix Foundation Limited.
Copyright (C) 2000 Farm9.
Copyright (C) 2001 Frank Knobbe.
All rights reserved.
For Cryptix code:
Use, modification, copying and distribution of this software is subject
the terms and conditions of the Cryptix General Licence.
Cryptix General License
Copyright (c) 1995 -2005 The Cryptix Foundation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE CRYPTIX FOUNDATION LIMITED AND
CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE CRYPTIX FOUNDATION LIMITED OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The Files:
minilzo.c
minilzo.h
lzodefs.h
Copyright (C) 1996 - 2005 Markus Franz Xaver Johannes Oberhumer
These file are part of the LZO real-time data compression library.
All Rights Reserved.
The LZO library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
The LZO library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the LZO library; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

2
debian/dirs vendored
View file

@ -1,2 +0,0 @@
usr/bin
usr/sbin

1
debian/docs vendored
View file

@ -1 +0,0 @@
README

View file

@ -1,8 +0,0 @@
--- 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"
.SH NAME
edge \- n2n edge node daemon
.SH SYNOPSIS

View file

@ -1 +0,0 @@
01-edge.8.diff

79
debian/rules vendored
View file

@ -1,79 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
include /usr/share/quilt/quilt.make
CFLAGS = -Wall -g
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
else
CFLAGS += -O2
endif
configure: configure-stamp
configure-stamp:
dh_testdir
# Add here commands to configure the package.
touch configure-stamp
build: patch build-stamp
build-stamp: configure-stamp
dh_testdir
# Add here commands to compile the package.
$(MAKE)
#docbook-to-man debian/n2n.sgml > n2n.1
touch $@
clean: unpatch
dh_testdir
dh_testroot
rm -f build-stamp configure-stamp
# Add here commands to clean up after the build process.
[ ! -f Makefile ] || $(MAKE) clean
dh_clean
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/n2n.
$(MAKE) DESTDIR=$(CURDIR)/debian/n2n install
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installchangelogs
dh_installdocs
dh_installexamples
dh_installman supernode.1 edge.8
dh_link
dh_strip
dh_compress
dh_fixperms
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure

95
edge.8
View file

@ -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 <name>
sets the TAP device name as seen in ifconfig.
.TP
\-a
sets the n2n LAN IP address being claimed.
\-a <addr>
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 <community>
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 <keystring>
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 <addr>:<port>
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 <num>
binds edge to the given UDP port. Useful for keeping the same external socket
across restarts of edge.
.TP
\-u <uid>
causes the edge process to drop to the given user ID when privileges are no
longer required.
.TP
\-g <gid>
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 <MAC>
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 <MTU>
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 <netmask>
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 <addr> 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 <MAC>) and virtual IP address (-a <addr>) 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)

140
edge.c
View file

@ -1,5 +1,6 @@
/*
* (C) 2007-09 - Luca Deri <deri@ntop.org>
* Richard Andrews <andrews@ntop.org>
*
* 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 <http://www.gnu.org/licenses/>
*
* Code contributions courtesy of:
* Richard Andrews <bbmaj7@yahoo.com.au>
* Don Bindner <don.bindner@gmail.com>
* Sylwester Sosnowski <syso-n2n@no-route.org>
* 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 <tun IP address> "
"-c <community> "
"-k <encrypt key> "
"-s <netmask> "
#ifndef WIN32
"[-u <uid> -g <gid>]"
"[-f]"
@ -255,7 +262,7 @@ static void help() {
"[-m <MAC address>]"
"\n"
"-l <supernode host:port> "
"[-p <local port>] "
"[-p <local port>] [-M <mtu>] "
"[-t] [-r] [-v] [-b] [-h]\n\n");
#ifdef __linux__
@ -265,6 +272,7 @@ static void help() {
printf("-a <tun IP address> | n2n IP address\n");
printf("-c <community> | n2n community name\n");
printf("-k <encrypt key> | Encryption key (ASCII) - also N2N_KEY=<encrypt key>\n");
printf("-s <netmask> | Edge interface netmask in dotted decimal notation (255.255.255.0)\n");
printf("-l <supernode host:port> | 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 <MAC address> | Choose a MAC address for the TAP interface\n"
" | eg. -m 01:02:03:04:05:06\n");
printf("-M <mtu> | 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<strlen(linebuffer); i++)
if(linebuffer[i] == '\\') linebuffer[i] = '/';
#endif
for(i=1;i<argc;++i) {
if(argv[i][0] == '@') {
if (readConfFile(&argv[i][1], linebuffer)<0) exit(1); /* <<<<----- check */
@ -1192,7 +1221,7 @@ int main(int argc, char* argv[]) {
effectiveargc =0;
while (effectiveargv[effectiveargc]) ++effectiveargc;
effectiveargv[effectiveargc] = 0;
if (linebuffer) {
free(linebuffer);
linebuffer = NULL;
@ -1201,9 +1230,10 @@ int main(int argc, char* argv[]) {
/* {int k;for(k=0;k<effectiveargc;++k) printf("%s\n",effectiveargv[k]);} */
optarg = NULL;
while((opt = getopt_long(effectiveargc, effectiveargv, "k:a:bc:u:g:m:d:l:p:fvhrt", long_options, NULL)) != EOF) {
while((opt = getopt_long(effectiveargc, effectiveargv, "k:a:bc:u:g:m:M:s:d:l:p:fvhrt", long_options, NULL)) != EOF) {
switch (opt) {
case 'a':
printf("%s\n", optarg);
ip_addr = strdup(optarg);
break;
case 'c': /* community */
@ -1215,23 +1245,28 @@ int main(int argc, char* argv[]) {
case 'u': /* uid */
{
userid=atoi(optarg);
userid = atoi(optarg);
break;
}
case 'g': /* uid */
{
groupid=atoi(optarg);
groupid = atoi(optarg);
break;
}
case 'f' : /* fork as daemon */
{
fork_as_daemon=1;
fork_as_daemon = 1;
break;
}
#endif
case 'm' : /* device_mac */
{
device_mac=strdup(optarg);
device_mac = strdup(optarg);
break;
}
case 'M' : /* device_mac */
{
mtu = atoi(optarg);
break;
}
case 'k': /* encrypt key */
@ -1258,6 +1293,13 @@ int main(int argc, char* argv[]) {
case 'p':
local_port = atoi(optarg);
break;
case 's': /* Subnet Mask */
if (0 != got_s) {
traceEvent(TRACE_WARNING, "Multiple subnet masks supplied.");
}
strncpy(netmask, optarg, N2N_NETMASK_STR_SIZE);
got_s = 1;
break;
case 'h': /* help */
help();
break;
@ -1283,7 +1325,7 @@ int main(int argc, char* argv[]) {
/* setgid( 0 ); */
#endif
if(tuntap_open(&(eee.device), tuntap_dev_name, ip_addr, "255.255.255.0", device_mac ) < 0)
if(tuntap_open(&(eee.device), tuntap_dev_name, ip_addr, netmask, device_mac, mtu) < 0)
return(-1);
#ifndef WIN32

170
n2n.c
View file

@ -1,5 +1,6 @@
/*
* (C) 2007-08 - Luca Deri <deri@ntop.org>
* (C) 2007-09 - Luca Deri <deri@ntop.org>
* Richard Andrews <andrews@ntop.org>
*
* 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);

17
n2n.h
View file

@ -1,5 +1,6 @@
/*
* (C) 2007-08 - Luca Deri <deri@ntop.org>
* (C) 2007-09 - Luca Deri <deri@ntop.org>
* Richard Andrews <andrews@ntop.org>
*
* 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 <http://www.gnu.org/licenses/>
*
* Code contributions courtesy of:
* Richard Andrews <bbmaj7@yahoo.com.au>
* Babak Farrokhi <babak@farrokhi.net> [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);

View file

@ -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

View file

@ -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

View file

@ -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 <port>
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)

View file

@ -1,5 +1,6 @@
/*
* (C) 2007-08 - Luca Deri <deri@ntop.org>
* (C) 2007-09 - Luca Deri <deri@ntop.org>
* Richard Andrews <andrews@ntop.org>
*
* 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 <http://www.gnu.org/licenses/>
*
* Code contributions courtesy of:
* Richard Andrews <bbmaj7@yahoo.com.au>
*
*/
#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) {

View file

@ -1,5 +1,5 @@
/*
* (C) 2007-08 - Luca Deri <deri@ntop.org>
* (C) 2007-09 - Luca Deri <deri@ntop.org>
*
* 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)",

View file

@ -1,5 +1,5 @@
/*
* (C) 2007-08 - Luca Deri <deri@ntop.org>
* (C) 2007-09 - Luca Deri <deri@ntop.org>
*
* 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);
}

View file

@ -1,5 +1,5 @@
/*
* (C) 2007-08 - Luca Deri <deri@ntop.org>
* (C) 2007-09 - Luca Deri <deri@ntop.org>
*
* 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;