├── debian ├── compat ├── n2n-edge.docs ├── n2n-edge.install ├── n2n-edge.manpages ├── n2n-supernode.manpages ├── n2n-supernode.install ├── rules ├── README.Debian ├── copyright ├── changelog ├── n2n-edge.default ├── control ├── n2n-supernode.init └── n2n-edge.init ├── win32 ├── DotNet │ ├── n2n.suo │ ├── n2n.sln │ ├── supernode.vcproj │ └── n2n.vcproj ├── CMakeLists.txt ├── version-msvc.c ├── wintap.h ├── n2n_win32.h ├── getopt1.c └── getopt.h ├── NEW_FEATURES.txt ├── version.c ├── test.c ├── edge_mgmt.h ├── scripts ├── mk_SRPM.sh ├── mk_deb.sh └── mk_tar.sh ├── INSTALL ├── gen_keyfile.py ├── n2n_log.h ├── openwrt └── kamikaze │ └── Makefile ├── n2n.spec ├── supernode.1 ├── n2n_utils.h ├── sn.h ├── tuntap.h ├── transform_null.c ├── n2n_log.c ├── sn_multiple.h ├── n2n_transforms.h ├── README ├── Makefile ├── minilzo.h ├── benchmark.c ├── n2n_keyfile.h ├── tuntap_freebsd.c ├── CMakeLists.txt ├── tuntap_osx.c ├── sn_multiple.c ├── edge.h ├── tuntap_netbsd.c ├── n2n.h ├── sn_multiple_wire.h ├── n2n_net.h ├── n2n_list.c ├── n2n.c ├── n2n_keyfile.c ├── edge_mgmt.c ├── tuntap_linux.c ├── n2n_v3.0 ├── n2n_utils.c ├── edge.8 ├── n2n_list.h └── sn_multiple_wire.c /debian/compat: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /debian/n2n-edge.docs: -------------------------------------------------------------------------------- 1 | README 2 | -------------------------------------------------------------------------------- /debian/n2n-edge.install: -------------------------------------------------------------------------------- 1 | edge /usr/sbin 2 | -------------------------------------------------------------------------------- /debian/n2n-edge.manpages: -------------------------------------------------------------------------------- 1 | edge.8 2 | n2n_v2.7 3 | -------------------------------------------------------------------------------- /debian/n2n-supernode.manpages: -------------------------------------------------------------------------------- 1 | supernode.1 2 | -------------------------------------------------------------------------------- /debian/n2n-supernode.install: -------------------------------------------------------------------------------- 1 | supernode /usr/sbin 2 | -------------------------------------------------------------------------------- /win32/DotNet/n2n.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukablurr/n2n_v3/HEAD/win32/DotNet/n2n.suo -------------------------------------------------------------------------------- /win32/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(n2n_win32 2 | win32/getopt1.c 3 | win32/getopt.c 4 | win32/wintap.c) 5 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | include /usr/share/cdbs/1/rules/debhelper.mk 4 | include /usr/share/cdbs/1/class/makefile.mk 5 | 6 | -------------------------------------------------------------------------------- /NEW_FEATURES.txt: -------------------------------------------------------------------------------- 1 | 2 | Between 2.0.x and 2.1.x 3 | 4 | * Better ming Windows build support. 5 | * Added -E flag to allow multicast ethernet traffic. 6 | 7 | -------------------------------------------------------------------------------- /version.c: -------------------------------------------------------------------------------- 1 | const char *n2n_sw_version = N2N_VERSION; 2 | const char *n2n_sw_osName = N2N_OSNAME; 3 | const char *n2n_sw_buildDate = __DATE__ " " __TIME__; 4 | -------------------------------------------------------------------------------- /win32/version-msvc.c: -------------------------------------------------------------------------------- 1 | const char *n2n_sw_version = "2.0.0"; 2 | const char *n2n_sw_osName = "Win32"; 3 | const char *n2n_sw_buildDate = __DATE__ " " __TIME__; 4 | -------------------------------------------------------------------------------- /debian/README.Debian: -------------------------------------------------------------------------------- 1 | n2n for Debian 2 | -------------- 3 | 4 | This package depends on the kernel having the TUN/TAP driver configured in using 5 | CONFIG_TUN=yes. 6 | 7 | -- Richard Andrews Thu, 10 Jul 2008 22:38:02 +1000 8 | -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | #include "n2n.h" 2 | #include "n2n_keyfile.h" 3 | #include 4 | #include 5 | #include 6 | 7 | int main(int arc, const char *argv[]) 8 | { 9 | int e; 10 | n2n_cipherspec_t specs[N2N_MAX_NUM_CIPHERSPECS]; 11 | 12 | e = n2n_read_keyfile(specs, N2N_MAX_NUM_CIPHERSPECS, "keyctrl.conf"); 13 | 14 | if (e < 0) 15 | { 16 | perror("Failed to read keyfile"); 17 | } 18 | else 19 | { 20 | fprintf(stderr, "Stored %d keys.\n", e); 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | This package was debianized by Jean-Baptiste Denis on 2 | Thu, 20 Nov 2008 23:53:02 +1000. 3 | 4 | It was downloaded from http://www.ntop.org/n2n/ 5 | 6 | Upstream Author(s): 7 | 8 | Luca Deri 9 | Richard Andrews 10 | 11 | Copyright: 12 | 13 | Copyright (C) 2008 Luca Deri 14 | Copyright (C) 2008 Richard Andrews 15 | 16 | License: 17 | 18 | GPLv3 19 | 20 | The Debian packaging is (C) 2008, Richard Andrews , 21 | Luca Deri and is licensed under the GPLv3, see 22 | `/usr/share/common-licenses/GPL-3'. 23 | 24 | -------------------------------------------------------------------------------- /edge_mgmt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * edge_mgmt.h 3 | * 4 | * Created on: Aug 22, 2013 5 | * Author: wolf 6 | */ 7 | 8 | #ifndef EDGE_MGMT_H_ 9 | #define EDGE_MGMT_H_ 10 | 11 | #include "n2n.h" 12 | #include "edge.h" 13 | 14 | 15 | 16 | typedef enum edge_cmd 17 | { 18 | EDGE_CMD_NONE = 0, 19 | EDGE_CMD_STATS, 20 | EDGE_CMD_STOP, 21 | EDGE_CMD_HELP, 22 | EDGE_CMD_VERB_INC, 23 | EDGE_CMD_VERB_DEC, 24 | EDGE_CMD_RELOAD 25 | 26 | } edge_cmd_t; 27 | 28 | 29 | edge_cmd_t process_edge_mgmt(n2n_edge_t *eee, 30 | uint8_t req_buf[], ssize_t req_len, 31 | uint8_t rsp_buf[], size_t *rsp_len); 32 | 33 | #endif /* EDGE_MGMT_H_ */ 34 | -------------------------------------------------------------------------------- /scripts/mk_SRPM.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This script makes a SRPM - a source RPM file which can be built into the 4 | # appropriate distro specific RPM for any platform. 5 | # 6 | # To build the binary package: 7 | # rpm -i n2n-.src.rpm 8 | # rpmbuild -bb n2n.spec 9 | # 10 | # Look for the "Wrote:" line to see where the final RPM is. 11 | # 12 | # To run this script cd to the n2n directory and run it as follows 13 | # scripts/mk_SRPMS.sh 14 | # 15 | 16 | set -e 17 | 18 | set -x 19 | 20 | BASE=`pwd` 21 | 22 | TARFILE=`${BASE}/scripts/mk_tar.sh` 23 | 24 | test -f ${TARFILE} 25 | 26 | echo "Building SRPM" 27 | # -ts means build source RPM from tarfile 28 | rpmbuild -ts ${TARFILE} 29 | 30 | echo "Done" 31 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | n2n (2.1.0-1) unstable; urgency=low 2 | 3 | * Split package in two. 4 | * Move manpage for edge to section 8. 5 | * Install manpage for n2n_v2 to section 7. 6 | * Create init.d files for the daemons. 7 | 8 | -- Kim Hansen Sun, 04 Apr 2010 21:40:46 +0200 9 | 10 | n2n (2.0-1) hardy; urgency=low 11 | 12 | * New upstream release 13 | 14 | -- Richard Andrews Tue, 30 Oct 2009 22:26:04 +1100 15 | 16 | n2n (1.3-1) hardy; urgency=low 17 | 18 | * New upstream release 19 | 20 | -- Richard Andrews Fri, 30 Jan 2009 23:49:56 +1100 21 | 22 | n2n (1.2-1) unstable; urgency=low 23 | 24 | * Initial release 25 | 26 | -- Richard Andrews Thu, 10 Jul 2008 22:38:02 +1000 27 | 28 | -------------------------------------------------------------------------------- /debian/n2n-edge.default: -------------------------------------------------------------------------------- 1 | # Config file for the n2n edge node daemon. 2 | 3 | # Sets the n2n community name. All edges within the same community appear on 4 | # the same LAN (layer 2 network segment). Community name is 16 bytes in length. 5 | N2N_COMMUNITY="MyCommunityName" 6 | 7 | # Sets the twofish encryption key from ASCII text. All edges communicating must 8 | # use the same key and community name. 9 | N2N_KEY="MySecretCode" 10 | 11 | # Sets the n2n supernode IP address to register to. 12 | N2N_SUPERNODE="gw1.example.com" 13 | 14 | # Sets the n2n virtual LAN IP address being claimed. This is a private IP 15 | # address. All IP addresses in an n2n community typical belong to the same /24 16 | # net‐ work (ie. only the last octet of the IP addresses varies). 17 | N2N_IP="10.10.10.11" 18 | 19 | # Uncomment this to get edge node started. 20 | #N2N_EDGE_CONFIG_DONE="yes" 21 | 22 | -------------------------------------------------------------------------------- /scripts/mk_deb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script makes a SRPM - a source RPM file which can be built into the 4 | # appropriate distro specific RPM for any platform. 5 | # 6 | # To build the binary package: 7 | # rpm -i n2n-.src.rpm 8 | # rpmbuild -bb n2n.spec 9 | # 10 | # Look for the "Wrote:" line to see where the final RPM is. 11 | # 12 | # To run this script cd to the n2n directory and run it as follows 13 | # scripts/mk_SRPMS.sh 14 | # 15 | 16 | set -e 17 | 18 | set -x 19 | 20 | BASE=`pwd` 21 | 22 | TARFILE=`${BASE}/scripts/mk_tar.sh` 23 | TEMPDIR="build_deb" 24 | 25 | test -f ${TARFILE} 26 | 27 | echo "Building .deb" 28 | 29 | if [ -d ${TEMPDIR} ]; then 30 | echo "Removing ${TEMPDIR} directory" 31 | rm -rf ${TEMPDIR} >&2 32 | fi 33 | 34 | mkdir ${TEMPDIR} 35 | 36 | pushd ${TEMPDIR} 37 | 38 | tar xzf ${TARFILE} #At original location 39 | 40 | cd n2n* 41 | 42 | dpkg-buildpackage -rfakeroot 43 | 44 | popd 45 | 46 | echo "Done" 47 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | INSTALL 2 | 3 | To build the programs: 4 | 5 | $ make 6 | 7 | To install the programs and man pages: 8 | 9 | $ make install 10 | 11 | or 12 | 13 | $ make PREFIX=/usr/local install 14 | 15 | 16 | RPM Package 17 | ----------- 18 | 19 | These steps should work with RPM based Linux distributions since rpmbuild was 20 | split from the rpm utility (c RedHat 9). 21 | 22 | 23 | To build an RPM the easy way follow these steps. 24 | 25 | 1. Build SRPM 26 | 27 | $ cd n2n 28 | $ scripts/mk_SRPM.sh 29 | 30 | Look for where the src.rpm file was put ( "Wrote:" ). 31 | 32 | 2. Build binary RPM from SRPM 33 | 34 | $ rpm -i path/to/n2n-.src.rpm 35 | $ rpmbuild -bb n2n.spec 36 | 37 | 38 | All this can be done as non-root user if you have a ~/.rpmmacros file with this 39 | line in it: 40 | 41 | %_topdir /home/username/rpmtopdir 42 | 43 | 44 | To build an RPM the hard way follow these steps. 45 | 46 | $ cp -a n2ndir n2n-2.0 47 | $ tar czf n2n-2.0.tar.gz n2n-2.0 48 | $ mv n2n-2.0.tar.gz /usr/src/redhat/SOURCES 49 | $ cp n2ndir/n2n.spec /usr/src/redhat/SPECS 50 | $ rpmbuild -bb n2n.spec 51 | -------------------------------------------------------------------------------- /gen_keyfile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # (c) 2009 Richard Andrews 4 | 5 | # Program to generate a n2n_edge key schedule file for twofish keys 6 | # Each key line consists of the following element 7 | # 8 | # 9 | # where , are UNIX time_t values of key valid period 10 | # is the transform ID (=2 for twofish) 11 | # is twofish-specific data as follows 12 | # _ 13 | 14 | import os 15 | import sys 16 | import time 17 | import random 18 | 19 | NUM_KEYS=30 20 | KEY_LIFE=300 21 | KEY_LEN=16 22 | 23 | now=time.time() 24 | start_sa=random.randint( 0, 0xffffffff ) 25 | 26 | random.seed(now) # note now is a floating point time value 27 | 28 | def rand_key(): 29 | key=str() 30 | for i in range(0,KEY_LEN): 31 | key += "%02x"%( random.randint( 0, 255) ) 32 | 33 | return key 34 | 35 | for i in range(0,NUM_KEYS): 36 | from_time = now + (KEY_LIFE * (i-1) ) 37 | until_time = now + (KEY_LIFE * (i+1) ) 38 | key = rand_key() 39 | sa_idx = start_sa + i 40 | transform_id = random.randint( 2, 3 ) 41 | 42 | sys.stdout.write("%d %d %d %d_%s\n"%(from_time, until_time, transform_id,sa_idx, key) ) 43 | 44 | 45 | -------------------------------------------------------------------------------- /n2n_log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * n2n_log.h 3 | * 4 | * Created on: Aug 21, 2013 5 | * Author: wolf 6 | */ 7 | 8 | #ifndef N2N_LOG_H_ 9 | #define N2N_LOG_H_ 10 | 11 | 12 | 13 | /* Logging levels */ 14 | 15 | #define N2N_LOG_ERROR 0 16 | #define N2N_LOG_WARNING 1 17 | #define N2N_LOG_NORMAL 2 18 | #define N2N_LOG_INFO 3 19 | #define N2N_LOG_DEBUG 4 20 | 21 | #define TRACE(LOG_LVL) LOG_LVL, __FILE__, __LINE__ 22 | 23 | #define TRACE_ERROR TRACE(N2N_LOG_ERROR) 24 | #define TRACE_WARNING TRACE(N2N_LOG_WARNING) 25 | #define TRACE_NORMAL TRACE(N2N_LOG_NORMAL) 26 | #define TRACE_INFO TRACE(N2N_LOG_INFO) 27 | #define TRACE_DEBUG TRACE(N2N_LOG_DEBUG) 28 | 29 | /* ************************************** */ 30 | 31 | extern int traceLevel; 32 | 33 | #ifndef WIN32 34 | extern int useSyslog; 35 | #endif 36 | 37 | void traceEvent(int eventTraceLevel, char *file, int line, char *format, ...); 38 | 39 | /* ************************************** */ 40 | 41 | #define traceError(...) traceEvent(TRACE_ERROR, __VA_ARGS__) 42 | #define traceWarning(...) traceEvent(TRACE_WARNING, __VA_ARGS__) 43 | #define traceNormal(...) traceEvent(TRACE_NORMAL, __VA_ARGS__) 44 | #define traceInfo(...) traceEvent(TRACE_INFO, __VA_ARGS__) 45 | #define traceDebug(...) traceEvent(TRACE_DEBUG, __VA_ARGS__) 46 | 47 | 48 | 49 | #endif /* N2N_LOG_H_ */ 50 | -------------------------------------------------------------------------------- /openwrt/kamikaze/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2008 OpenWrt.org 3 | # 4 | # This is free software, licensed under the GNU General Public License v2. 5 | 6 | 7 | include $(TOPDIR)/rules.mk 8 | 9 | PKG_BRANCH:=trunk 10 | PKG_SOURCE_URL:=https://svn.ntop.org/svn/ntop/trunk/n2n 11 | PKG_REV:=$(shell LC_ALL=C svn info ${PKG_SOURCE_URL} | sed -ne's/^Last Changed Rev: //p') 12 | 13 | PKG_NAME:=n2n 14 | PKG_VERSION:=svn$(PKG_REV) 15 | PKG_RELEASE:=1 16 | 17 | PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) 18 | PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz 19 | PKG_SOURCE_PROTO:=svn 20 | PKG_SOURCE_VERSION:=$(PKG_REV) 21 | 22 | PKG_BUILD_DEPENDS:= 23 | 24 | PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) 25 | PKG_INSTALL_DIR:=$(PKG_BUILD_DIR) 26 | 27 | 28 | 29 | include $(INCLUDE_DIR)/package.mk 30 | 31 | define Package/n2n 32 | SECTION:=net 33 | CATEGORY:=Network 34 | TITLE:=VPN tunneling daemon 35 | URL:=http://www.ntop.org/n2n/ 36 | SUBMENU:=VPN 37 | DEPENDS:=libpthread 38 | endef 39 | 40 | 41 | define Build/Configure 42 | endef 43 | 44 | define Build/Compile 45 | $(MAKE) CC="$(TARGET_CC)" -C $(PKG_BUILD_DIR) 46 | endef 47 | 48 | 49 | define Package/n2n/install 50 | $(INSTALL_DIR) $(1)/usr/sbin 51 | $(INSTALL_BIN) $(PKG_INSTALL_DIR)/edge $(1)/usr/sbin/ 52 | $(INSTALL_BIN) $(PKG_INSTALL_DIR)/supernode $(1)/usr/sbin/ 53 | endef 54 | 55 | $(eval $(call BuildPackage,n2n)) 56 | -------------------------------------------------------------------------------- /win32/DotNet/n2n.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual C++ Express 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "edge", "n2n.vcproj", "{4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "supernode", "supernode.vcproj", "{BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Debug|Win32.Build.0 = Debug|Win32 16 | {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Release|Win32.ActiveCfg = Release|Win32 17 | {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Release|Win32.Build.0 = Release|Win32 18 | {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Debug|Win32.Build.0 = Debug|Win32 20 | {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Release|Win32.ActiveCfg = Release|Win32 21 | {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Release|Win32.Build.0 = Release|Win32 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /n2n.spec: -------------------------------------------------------------------------------- 1 | Summary: N2N peer-to-peer virtual private network system. 2 | Name: n2n 3 | Version: 2.1.0 4 | Release: 1 5 | License: GPLv3 6 | Vendor: ntop.org 7 | Group: None 8 | URL: http://www.ntop.org/n2n 9 | Source0: %{name}-%{version}.tar.gz 10 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root 11 | 12 | %description 13 | N2N is a peer-to-peer virtual private network system. N2N uses the universal 14 | TUNTAP interface to create TAP network interfaces to an encrypted virtual 15 | LAN. Members of a community share encryption keys which allow exchange of 16 | data. The supernode is used for peer discovery and initial packet relay before 17 | direct peer-to-peer exchange is established. Once direct packet exchange is 18 | established, the supernode is not required. 19 | 20 | N2N-2 introduces additional security features and multiple supernodes. 21 | 22 | %prep 23 | 24 | %setup -q 25 | 26 | echo -e "\n *** Building ${RPM_PACKAGE_NAME}-${RPM_PACKAGE_VERSION}-${RPM_PACKAGE_RELEASE} ***\n" 27 | 28 | %build 29 | make 30 | 31 | %install 32 | make PREFIX=${RPM_BUILD_ROOT}/usr install 33 | 34 | %clean 35 | rm -rf $RPM_BUILD_ROOT 36 | 37 | 38 | %files 39 | %defattr(-,root,root,-) 40 | /usr/sbin/supernode 41 | /usr/sbin/edge 42 | %doc /usr/share/man/man1/supernode.1.gz 43 | %doc /usr/share/man/man8/edge.8.gz 44 | %doc /usr/share/man/man7/n2n_v2.7.gz 45 | 46 | 47 | %changelog 48 | * Fri Oct 30 2009 Richard Andrews - 49 | - First beta for n2n-2 50 | * Sat May 3 2008 Richard Andrews - 51 | - Initial build. 52 | 53 | -------------------------------------------------------------------------------- /supernode.1: -------------------------------------------------------------------------------- 1 | .TH supernode 1 "Jan 3, 2009" "revision 3679" "USER COMMANDS" 2 | .SH NAME 3 | supernode \- n2n supernode daemon 4 | .SH SYNOPSIS 5 | .B supernode \-l [\-v] 6 | .SH DESCRIPTION 7 | N2N is a peer-to-peer VPN system. Supernode is a node introduction registry, 8 | broadcast conduit and packet relay node for the n2n system. On startup supernode 9 | begins listening on the specified UDP port for node registrations, and other 10 | packets to route. The supernode can service any number of communities and routes 11 | packets only between members of the same community. The supernode does not hold 12 | the community encryption key and so cannot snoop or inject packets into the 13 | community. 14 | .PP 15 | Supernode can service a number of n2n communities concurrently. Traffic does not 16 | cross between communities. 17 | .PP 18 | All logging goes to stdout. 19 | .SH OPTIONS 20 | .TP 21 | \-l 22 | listen on the given UDP port 23 | .TP 24 | \-v 25 | use verbose logging 26 | .TP 27 | \-f 28 | disable daemon mode (UNIX) and run in foreground. 29 | .SH EXAMPLES 30 | .TP 31 | .B supernode -l 7654 -v 32 | Start supernode listening on UDP port 7654 with verbose output. 33 | .PP 34 | .SH RESTART 35 | When suprenode restarts it loses all registration information from associated 36 | edge nodes. It can take up to five minutes for the edge nodes to re-register and 37 | normal traffic flow to resume. 38 | .SH EXIT STATUS 39 | supernode is a daemon and any exit is an error 40 | .SH AUTHOR 41 | Luca Deri ( deri (at) ntop.org ), Richard Andrews ( andrews (at) ntop.org ), Don Bindner 42 | .SH SEE ALSO 43 | ifconfig(8) edge(8) 44 | -------------------------------------------------------------------------------- /n2n_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-09 - Luca Deri 3 | * Richard Andrews 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, see 17 | * 18 | */ 19 | 20 | #ifndef N2N_UTILS_H_ 21 | #define N2N_UTILS_H_ 22 | 23 | #ifdef WIN32 24 | # include "win32/n2n_win32.h" 25 | #else 26 | # include 27 | # include 28 | #endif 29 | 30 | 31 | 32 | /** maximum length of command line arguments */ 33 | #define MAX_CMDLINE_BUFFER_LENGTH 4096 34 | 35 | /** maximum length of a line in the configuration file */ 36 | #define MAX_CONFFILE_LINE_LENGTH 1024 37 | 38 | 39 | 40 | /* ************************************** */ 41 | 42 | struct effective_args 43 | { 44 | int argc; 45 | char **argv; 46 | }; 47 | 48 | typedef struct effective_args effective_args_t; 49 | 50 | 51 | void build_effective_args(int argc, char *argv[], effective_args_t *effective_args); 52 | void destroy_effective_args(effective_args_t *effective_args); 53 | 54 | 55 | 56 | /* ************************************** */ 57 | 58 | 59 | void hexdump(const uint8_t *buf, size_t len); 60 | 61 | /* ************************************** */ 62 | 63 | #ifndef max 64 | #define max(a, b) ((a < b) ? b : a) 65 | #endif 66 | 67 | #ifndef min 68 | #define min(a, b) ((a > b) ? b : a) 69 | #endif 70 | 71 | 72 | #endif /* N2N_UTILS_H_ */ 73 | -------------------------------------------------------------------------------- /sn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sn.h 3 | * 4 | * Created on: Aug 22, 2013 5 | * Author: wolf 6 | */ 7 | 8 | #ifndef SN_H_ 9 | #define SN_H_ 10 | 11 | #include "n2n.h" 12 | #include "n2n_list.h" 13 | #ifdef N2N_MULTIPLE_SUPERNODES 14 | # include "sn_multiple.h" 15 | #endif 16 | 17 | 18 | #define N2N_SN_LPORT_DEFAULT 7654 19 | #define N2N_SN_MGMT_PORT 5645 20 | 21 | #define N2N_SN_PKTBUF_SIZE 2048 22 | 23 | 24 | 25 | struct sn_stats 26 | { 27 | size_t errors; /* Number of errors encountered. */ 28 | size_t reg_super; /* Number of REGISTER_SUPER requests received. */ 29 | size_t reg_super_nak; /* Number of REGISTER_SUPER requests declined. */ 30 | size_t fwd; /* Number of messages forwarded. */ 31 | size_t broadcast; /* Number of messages broadcast to a community. */ 32 | time_t last_fwd; /* Time when last message was forwarded. */ 33 | time_t last_reg_super; /* Time when last REGISTER_SUPER was received. */ 34 | #ifdef N2N_MULTIPLE_SUPERNODES 35 | time_t last_fed_upd; 36 | #endif 37 | }; 38 | 39 | typedef struct sn_stats sn_stats_t; 40 | 41 | 42 | 43 | struct n2n_sn 44 | { 45 | time_t start_time; /* Used to measure uptime. */ 46 | sn_stats_t stats; 47 | int daemon; /* If non-zero then daemonise. */ 48 | uint16_t lport; /* Local UDP port to bind to. */ 49 | uint16_t mport; /* Management UDP port to bind to. */ 50 | int sock; /* Main socket for UDP traffic with edges. */ 51 | int mgmt_sock; /* management socket. */ 52 | #ifdef N2N_MULTIPLE_SUPERNODES 53 | n2n_snm_state_t snm_state; 54 | n2n_list_head_t federation; 55 | n2n_list_head_t queried_supernodes; 56 | #endif 57 | n2n_list_head_t edges; /* Link list of registered edges. */ 58 | }; 59 | 60 | typedef struct n2n_sn n2n_sn_t; 61 | 62 | 63 | 64 | #endif /* SN_H_ */ 65 | -------------------------------------------------------------------------------- /tuntap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tuntap.h 3 | * 4 | * Created on: Aug 21, 2013 5 | * Author: wolf 6 | */ 7 | 8 | #ifndef TUNTAP_H_ 9 | #define TUNTAP_H_ 10 | 11 | /* 12 | tunctl -t tun0 13 | tunctl -t tun1 14 | ifconfig tun0 1.2.3.4 up 15 | ifconfig tun1 1.2.3.5 up 16 | ./edge -d tun0 -l 2000 -r 127.0.0.1:3000 -c hello 17 | ./edge -d tun1 -l 3000 -r 127.0.0.1:2000 -c hello 18 | 19 | 20 | tunctl -u UID -t tunX 21 | */ 22 | 23 | #include "n2n_net.h" 24 | 25 | #ifdef __linux__ 26 | # include 27 | # define N2N_CAN_NAME_IFACE 1 28 | #endif /* #ifdef __linux__ */ 29 | 30 | 31 | /* N2N_IFNAMSIZ is needed on win32 even if dev_name is not used after declaration */ 32 | #define N2N_IFNAMSIZ 16 /* 15 chars * NULL */ 33 | 34 | 35 | #ifndef WIN32 36 | 37 | typedef struct tuntap_dev 38 | { 39 | int fd; 40 | uint8_t mac_addr[6]; 41 | uint32_t ip_addr; 42 | uint32_t device_mask; 43 | uint16_t mtu; 44 | char dev_name[N2N_IFNAMSIZ]; 45 | } tuntap_dev_t; 46 | 47 | #else 48 | typedef struct tuntap_dev 49 | { 50 | HANDLE device_handle; 51 | char *device_name; 52 | char *ifName; 53 | OVERLAPPED overlap_read; 54 | OVERLAPPED overlap_write; 55 | uint8_t mac_addr[6]; 56 | uint32_t ip_addr; 57 | uint32_t device_mask; 58 | unsigned int mtu; 59 | } tuntap_dev_t; 60 | 61 | #endif /* #ifndef WIN32 */ 62 | 63 | 64 | 65 | /*extern int tuntap_open(tuntap_dev *device, char *dev, const char *address_mode, char *device_ip, 66 | char *device_mask, const char *device_mac, int mtu);*/ 67 | extern int tuntap_open(tuntap_dev_t *device, ip_mode_t ip_mode); 68 | 69 | extern int tuntap_read(tuntap_dev_t *device, unsigned char *buf, int len); 70 | 71 | extern int tuntap_write(tuntap_dev_t *device, unsigned char *buf, int len); 72 | 73 | extern void tuntap_close(tuntap_dev_t *device); 74 | 75 | extern void tuntap_get_address(tuntap_dev_t *device); 76 | 77 | 78 | 79 | #endif /* TUNTAP_H_ */ 80 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: n2n 2 | Section: net 3 | Priority: extra 4 | Maintainer: Jean-Baptiste Denis 5 | Build-Depends: cdbs, debhelper (>= 5), libc6-dev (>= 2.0), dpatch, gcc, libssl-dev 6 | Standards-Version: 3.7.2 7 | 8 | Package: n2n 9 | Architecture: any 10 | Depends: n2n-edge, n2n-supernode 11 | Description: dummy package for transition purposes 12 | A dummy package for transition purposes that depends on n2n-edge and 13 | n2n-supernode 14 | 15 | Package: n2n-edge 16 | Architecture: any 17 | Suggests: uml-utilities 18 | Depends: ${shlibs:Depends}, ${misc:Depends} 19 | Conflicts: n2n (<< 2.1.0-1) 20 | Replaces: n2n (<< 2.1.0-1) 21 | Description: a layer-two peer-to-peer virtual private network (VPN) 22 | n2n is a layer-two peer-to-peer virtual private network (VPN) which allows 23 | users to exploit features typical of P2P applications at network instead of 24 | application level. This means that users can gain native IP visibility (e.g. 25 | two PCs belonging to the same n2n network can ping each other) and be 26 | reachable with the same network IP address regardless of the network where 27 | they currently belong. In a nutshell, as OpenVPN moved SSL from application 28 | (e.g. used to implement the https protocol) to network protocol, n2n moves 29 | P2P from application to network level. 30 | . 31 | Edge is the edge node daemon for n2n which creates a TAP interface to expose 32 | the n2n virtual LAN. 33 | 34 | Package: n2n-supernode 35 | Architecture: any 36 | Suggests: n2n-edge 37 | Depends: ${shlibs:Depends}, ${misc:Depends} 38 | Conflicts: n2n (<< 2.1.0-1) 39 | Replaces: n2n (<< 2.1.0-1) 40 | Description: a layer-two peer-to-peer virtual private network (VPN) 41 | n2n is a layer-two peer-to-peer virtual private network (VPN) which allows 42 | users to exploit features typical of P2P applications at network instead of 43 | application level. This means that users can gain native IP visibility (e.g. 44 | two PCs belonging to the same n2n network can ping each other) and be 45 | reachable with the same network IP address regardless of the network where 46 | they currently belong. In a nutshell, as OpenVPN moved SSL from application 47 | (e.g. used to implement the https protocol) to network protocol, n2n moves 48 | P2P from application to network level. 49 | . 50 | Supernode is a node introduction registry, broadcast conduit and packet relay 51 | node for the n2n system. 52 | -------------------------------------------------------------------------------- /win32/wintap.h: -------------------------------------------------------------------------------- 1 | /* 2 | (C) 2007 - Luca Deri 3 | */ 4 | 5 | #ifndef _WINTAP_H_ 6 | #define _WINTAP_H_ 7 | 8 | #undef UNICODE 9 | #undef _UNICODE 10 | #define _CRT_SECURE_NO_WARNINGS 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | 18 | //=============================================== 19 | // This file is included both by OpenVPN and 20 | // the TAP-Win32 driver and contains definitions 21 | // common to both. 22 | //=============================================== 23 | 24 | //============= 25 | // TAP IOCTLs 26 | //============= 27 | 28 | #define TAP_CONTROL_CODE(request,method) \ 29 | CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) 30 | 31 | #define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) 32 | #define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) 33 | #define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) 34 | #define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) 35 | #define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) 36 | #define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) 37 | #define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) 38 | #define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) 39 | #define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) 40 | 41 | //================= 42 | // Registry keys 43 | //================= 44 | 45 | #define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 46 | #define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 47 | 48 | //====================== 49 | // Filesystem prefixes 50 | //====================== 51 | 52 | #define USERMODEDEVICEDIR "\\\\.\\Global\\" 53 | #define SYSDEVICEDIR "\\Device\\" 54 | #define USERDEVICEDIR "\\DosDevices\\Global\\" 55 | #define TAPSUFFIX ".tap" 56 | 57 | //========================================================= 58 | // TAP_COMPONENT_ID -- This string defines the TAP driver 59 | // type -- different component IDs can reside in the system 60 | // simultaneously. 61 | //========================================================= 62 | 63 | #define TAP_COMPONENT_ID "tap0801" 64 | 65 | extern void initWin32(); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /transform_null.c: -------------------------------------------------------------------------------- 1 | /* (c) 2009 Richard Andrews */ 2 | 3 | #include "n2n.h" 4 | #include "n2n_transforms.h" 5 | #include "n2n_log.h" 6 | 7 | 8 | 9 | static int transop_deinit_null(n2n_trans_op_t *arg) 10 | { 11 | /* nothing to deallocate, nothing to release. */ 12 | return 0; 13 | } 14 | 15 | static int transop_encode_null(n2n_trans_op_t *arg, 16 | uint8_t *outbuf, 17 | size_t out_len, 18 | const uint8_t *inbuf, 19 | size_t in_len) 20 | { 21 | int retval = -1; 22 | 23 | traceDebug("encode_null %lu", in_len); 24 | if (out_len >= in_len) 25 | { 26 | memcpy(outbuf, inbuf, in_len); 27 | retval = in_len; 28 | } 29 | else 30 | { 31 | traceDebug("encode_null %lu too big for packet buffer", in_len); 32 | } 33 | 34 | return retval; 35 | } 36 | 37 | static int transop_decode_null(n2n_trans_op_t *arg, 38 | uint8_t *outbuf, 39 | size_t out_len, 40 | const uint8_t *inbuf, 41 | size_t in_len) 42 | { 43 | int retval = -1; 44 | 45 | traceDebug("decode_null %lu", in_len); 46 | if (out_len >= in_len) 47 | { 48 | memcpy(outbuf, inbuf, in_len); 49 | retval = in_len; 50 | } 51 | else 52 | { 53 | traceDebug("decode_null %lu too big for packet buffer", in_len); 54 | } 55 | 56 | return retval; 57 | } 58 | 59 | static int transop_addspec_null(n2n_trans_op_t *arg, const n2n_cipherspec_t *cspec) 60 | { 61 | return 0; 62 | } 63 | 64 | static n2n_tostat_t transop_tick_null(n2n_trans_op_t *arg, time_t now) 65 | { 66 | n2n_tostat_t r; 67 | 68 | r.can_tx = 1; 69 | r.tx_spec.t = N2N_TRANSFORM_ID_NULL; 70 | r.tx_spec.valid_from = 0; 71 | r.tx_spec.valid_until = (time_t) (-1); 72 | r.tx_spec.opaque_size = 0; 73 | 74 | return r; 75 | } 76 | 77 | void transop_null_init(n2n_trans_op_t *ttt) 78 | { 79 | memset(ttt, 0, sizeof(n2n_trans_op_t)); 80 | 81 | ttt->transform_id = N2N_TRANSFORM_ID_NULL; 82 | ttt->deinit = transop_deinit_null; 83 | ttt->addspec = transop_addspec_null; 84 | ttt->tick = transop_tick_null; 85 | ttt->fwd = transop_encode_null; 86 | ttt->rev = transop_decode_null; 87 | } 88 | -------------------------------------------------------------------------------- /scripts/mk_tar.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script makes a SRPM - a source RPM file which can be built into the 4 | # appropriate distro specific RPM for any platform. 5 | # 6 | # To build the binary package: 7 | # rpm -i n2n-.src.rpm 8 | # rpmbuild -bb n2n.spec 9 | # 10 | # Look for the "Wrote:" line to see where the final RPM is. 11 | # 12 | # To run this script cd to the n2n directory and run it as follows 13 | # scripts/mk_SRPMS.sh 14 | # 15 | 16 | set -e 17 | 18 | function exit_fail() 19 | { 20 | echo "$1" 21 | exit 1 22 | } 23 | 24 | PACKAGE="n2n" 25 | PKG_VERSION="2.1.0" 26 | PKG_AND_VERSION="${PACKAGE}-${PKG_VERSION}" 27 | 28 | TEMPDIR="tmp" 29 | 30 | SOURCE_MANIFEST=" 31 | README 32 | edge.c 33 | lzoconf.h 34 | lzodefs.h 35 | Makefile 36 | minilzo.c 37 | minilzo.h 38 | n2n.c 39 | n2n.h 40 | n2n_keyfile.c 41 | n2n_keyfile.h 42 | n2n.spec 43 | n2n_transforms.h 44 | n2n_wire.h 45 | sn.c 46 | transform_aes.c 47 | transform_null.c 48 | transform_tf.c 49 | tuntap_linux.c 50 | tuntap_freebsd.c 51 | tuntap_netbsd.c 52 | tuntap_osx.c 53 | twofish.c 54 | twofish.h 55 | version.c 56 | wire.c 57 | edge.8 58 | supernode.1 59 | n2n_v2.7 60 | debian/changelog 61 | debian/compat 62 | debian/control 63 | debian/copyright 64 | debian/n2n-edge.docs 65 | debian/n2n-edge.install 66 | debian/n2n-supernode.install 67 | debian/n2n-edge.manpages 68 | debian/n2n-supernode.manpages 69 | debian/README.Debian 70 | debian/rules 71 | " 72 | 73 | BASE=`pwd` 74 | 75 | for F in ${SOURCE_MANIFEST}; do 76 | test -e $F || exit_fail "Cannot find $F. Maybe you're in the wrong directory. Please execute from n2n directory."; >&2 77 | done 78 | 79 | echo "Found critical files. Proceeding." >&2 80 | 81 | if [ -d ${TEMPDIR} ]; then 82 | echo "Removing ${TEMPDIR} directory" 83 | rm -rf ${TEMPDIR} >&2 84 | fi 85 | 86 | mkdir ${TEMPDIR} >&2 87 | 88 | pushd ${TEMPDIR} >&2 89 | 90 | echo "Creating staging directory ${PWD}/${PKG_AND_VERSION}" >&2 91 | 92 | if [ -d ${PKG_AND_VERSION} ] ; then 93 | echo "Removing ${PKG_AND_VERSION} directory" 94 | rm -rf ${PKG_AND_VERSION} >&2 95 | fi 96 | 97 | mkdir ${PKG_AND_VERSION} 98 | 99 | pushd ${BASE} >&2 100 | 101 | echo "Copying in files" >&2 102 | for F in ${SOURCE_MANIFEST}; do 103 | cp --parents -a $F ${TEMPDIR}/${PKG_AND_VERSION}/ 104 | done 105 | 106 | popd >&2 107 | 108 | TARFILE="${PKG_AND_VERSION}.tar.gz" 109 | echo "Creating ${TARFILE}" >&2 110 | tar czf ${BASE}/${TARFILE} ${PKG_AND_VERSION} 111 | 112 | popd >&2 113 | 114 | rm -rf ${TEMPDIR} >&2 115 | 116 | echo ${BASE}/${TARFILE} 117 | -------------------------------------------------------------------------------- /n2n_log.c: -------------------------------------------------------------------------------- 1 | /* 2 | * n2n_log.c 3 | * 4 | * Created on: Aug 21, 2013 5 | * Author: wolf 6 | */ 7 | 8 | #include "n2n.h" 9 | #include "n2n_log.h" 10 | #include 11 | #ifndef WIN32 12 | # include 13 | 14 | int useSyslog = 0; 15 | int syslog_opened = 0; 16 | 17 | #endif /* #ifndef WIN32 */ 18 | 19 | 20 | #define N2N_TRACE_DATESIZE 32 21 | 22 | 23 | int traceLevel = N2N_LOG_NORMAL; 24 | 25 | 26 | 27 | void traceEvent(int eventTraceLevel, char *file, int line, char *format, ...) 28 | { 29 | va_list va_ap; 30 | 31 | if (eventTraceLevel <= traceLevel) 32 | { 33 | char buf[2048]; 34 | char out_buf[640]; 35 | char theDate[N2N_TRACE_DATESIZE]; 36 | char *extra_msg = ""; 37 | time_t theTime = time(NULL); 38 | #ifdef WIN32 39 | int i; 40 | #endif 41 | 42 | /* We have two paths - one if we're logging, one if we aren't 43 | * Note that the no-log case is those systems which don't support it (WIN32), 44 | * those without the headers !defined(USE_SYSLOG) 45 | * those where it's parametrically off... 46 | */ 47 | 48 | memset(buf, 0, sizeof(buf)); 49 | strftime(theDate, N2N_TRACE_DATESIZE, "%d/%b/%Y %H:%M:%S", localtime(&theTime)); 50 | 51 | va_start(va_ap, format); 52 | vsnprintf(buf, sizeof(buf) - 1, format, va_ap); 53 | va_end(va_ap); 54 | 55 | if (eventTraceLevel == N2N_LOG_ERROR) 56 | extra_msg = "ERROR: "; 57 | else if (eventTraceLevel == N2N_LOG_WARNING) 58 | extra_msg = "WARNING: "; 59 | 60 | while (buf[strlen(buf) - 1] == '\n') 61 | buf[strlen(buf) - 1] = '\0'; 62 | 63 | #ifndef WIN32 64 | if (useSyslog) 65 | { 66 | if (!syslog_opened) 67 | { 68 | openlog("n2n", LOG_PID, LOG_DAEMON); 69 | syslog_opened = 1; 70 | } 71 | 72 | snprintf(out_buf, sizeof(out_buf), "%s%s", extra_msg, buf); 73 | syslog(LOG_INFO, "%s", out_buf); 74 | } 75 | else 76 | { 77 | snprintf(out_buf, sizeof(out_buf), "%s [%11s:%4d] %s%s", theDate, file, line, extra_msg, buf); 78 | printf("%s\n", out_buf); 79 | fflush(stdout); 80 | } 81 | #else 82 | /* this is the WIN32 code */ 83 | for (i = strlen(file) - 1; i > 0; i--) 84 | { 85 | if (file[i] == '\\') 86 | { 87 | i++; 88 | break; 89 | } 90 | } 91 | snprintf(out_buf, sizeof(out_buf), "%s [%11s:%4d] %s%s", theDate, &file[i], line, extra_msg, buf); 92 | printf("%s\n", out_buf); 93 | fflush(stdout); 94 | #endif 95 | } 96 | } 97 | 98 | 99 | -------------------------------------------------------------------------------- /win32/n2n_win32.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | (C) 2007-09 - Luca Deri 4 | 5 | */ 6 | 7 | #ifndef _N2N_WIN32_H_ 8 | #define _N2N_WIN32_H_ 9 | 10 | #ifndef _CRT_SECURE_NO_WARNINGS 11 | #define _CRT_SECURE_NO_WARNINGS 12 | #endif 13 | 14 | #if defined(__MINGW32__) || defined(__CYGWIN__) 15 | /* should be defined here and before winsock gets included */ 16 | #define _WIN32_WINNT 0x501 //Otherwise the linker doesnt find getaddrinfo 17 | #include 18 | #endif /* #if defined(__MINGW32__) */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | 25 | #include "wintap.h" 26 | 27 | #ifdef _MSC_VER 28 | # define inline __inline 29 | # define __attribute__ 30 | 31 | # include "getopt.h" 32 | 33 | /* Other Win environments are expected to support stdint.h */ 34 | 35 | /* stdint.h typedefs (C99) (not present in Visual Studio) */ 36 | typedef unsigned int uint32_t; 37 | typedef unsigned short uint16_t; 38 | typedef unsigned char uint8_t; 39 | 40 | /* sys/types.h typedefs (not present in Visual Studio) */ 41 | typedef unsigned int u_int32_t; 42 | typedef unsigned short u_int16_t; 43 | typedef unsigned char u_int8_t; 44 | 45 | typedef int ssize_t; 46 | 47 | # define snprintf _snprintf 48 | # define strdup _strdup 49 | 50 | #else 51 | # define _snprintf snprintf 52 | # define _strdup strdup 53 | #endif /* #ifdef _MSC_VER */ 54 | 55 | typedef unsigned long in_addr_t; 56 | 57 | 58 | #define EAFNOSUPPORT WSAEAFNOSUPPORT 59 | #define MAX(a,b) (a > b ? a : b) 60 | #define MIN(a,b) (a < b ? a : b) 61 | 62 | #define socklen_t int 63 | 64 | /* ************************************* */ 65 | 66 | struct ip { 67 | #if BYTE_ORDER == LITTLE_ENDIAN 68 | u_char ip_hl:4, /* header length */ 69 | ip_v:4; /* version */ 70 | #else 71 | u_char ip_v:4, /* version */ 72 | ip_hl:4; /* header length */ 73 | #endif 74 | u_char ip_tos; /* type of service */ 75 | short ip_len; /* total length */ 76 | u_short ip_id; /* identification */ 77 | short ip_off; /* fragment offset field */ 78 | #define IP_DF 0x4000 /* dont fragment flag */ 79 | #define IP_MF 0x2000 /* more fragments flag */ 80 | #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ 81 | u_char ip_ttl; /* time to live */ 82 | u_char ip_p; /* protocol */ 83 | u_short ip_sum; /* checksum */ 84 | struct in_addr ip_src,ip_dst; /* source and dest address */ 85 | }; 86 | 87 | 88 | /* ************************************* */ 89 | 90 | #define index(a, b) strchr(a, b) 91 | 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /sn_multiple.h: -------------------------------------------------------------------------------- 1 | /* 2 | *sn_multiple.h 3 | * 4 | * Created on: Mar 25, 2012 5 | * Author: Costin Lupu 6 | */ 7 | 8 | #ifndef SN_MULTIPLE_H_ 9 | #define SN_MULTIPLE_H_ 10 | 11 | #include "n2n_list.h" 12 | #include "n2n_wire.h" 13 | #include "sn_multiple_wire.h" 14 | 15 | 16 | #define N2N_SN_COMM_PORT 5646 17 | #define N2N_PERSIST_FILENAME_LEN 64 18 | 19 | #define N2N_MIN_SN_PER_COMM 3 20 | #define N2N_MAX_SN_PER_COMM 4 21 | #define N2N_MAX_COMM_PER_SN 3 22 | 23 | #define N2N_SUPER_DISCOVERY_INTERVAL 3//60 /* seconds */ 24 | 25 | #define N2N_SNM_STATE_NONE 0 26 | #define N2N_SNM_STATE_DISCOVERY 1 27 | #define N2N_SNM_STATE_READY 2 28 | 29 | 30 | 31 | 32 | enum n2n_snm_state 33 | { 34 | n2n_snm_none = 0, 35 | n2n_snm_discovery = 1, 36 | n2n_snm_ready = 2 37 | }; 38 | 39 | typedef enum n2n_snm_state n2n_snm_state_t; 40 | 41 | 42 | struct sn_info 43 | { 44 | n2n_list_node_t list; 45 | n2n_sock_t sock; 46 | size_t edges_num; 47 | size_t vouched;//TODO 48 | time_t timestamp; 49 | }; 50 | 51 | typedef struct sn_info sn_info_t; 52 | 53 | 54 | 55 | struct sn_federation 56 | { 57 | n2n_list_node_t list; 58 | n2n_list_head_t members;//TODO entry type 59 | size_t count; 60 | }; 61 | 62 | typedef struct sn_federation sn_federation_t; 63 | 64 | 65 | typedef struct sn_list 66 | { 67 | n2n_list_head_t head; 68 | char filename[N2N_PERSIST_FILENAME_LEN]; 69 | } sn_list_t; 70 | 71 | 72 | 73 | /* functions */ 74 | 75 | sn_info_t * create_supernode_info(const n2n_sock_t *sock); 76 | sn_info_t * add_supernode_info(n2n_list_head_t *head, const n2n_sock_t *sock); 77 | sn_info_t * find_supernode_info(n2n_list_head_t *head, const n2n_sock_t *sock); 78 | 79 | /* IO */ 80 | n2n_list_node_t *read_supernode_info(FILE *f); 81 | void write_supernode_info(FILE *f, const void *entry); 82 | 83 | static inline int read_supernodes_from_file(const char *filename, n2n_list_head_t *list) 84 | { 85 | return read_list_from_file(filename, list, read_supernode_info); 86 | } 87 | 88 | static inline int write_supernodes_to_file(const char *filename, n2n_list_head_t *list) 89 | { 90 | return write_list_to_file(filename, list, write_supernode_info); 91 | } 92 | 93 | 94 | int update_supernodes(sn_list_t *supernodes, const n2n_sock_t *sn); 95 | int update_and_save_supernodes(sn_list_t *supernodes, n2n_sock_t *sn_array, int sn_num); 96 | 97 | 98 | 99 | 100 | /******************************************************************* 101 | * Utils * 102 | *******************************************************************/ 103 | 104 | int sn_cmp(const n2n_sock_t *left, const n2n_sock_t *right); 105 | int sn_is_zero_addr(n2n_sock_t *sn); 106 | int sn_is_loopback(n2n_sock_t *sn, uint16_t local_port); /* TODO hack until explicit binding */ 107 | int sn_local_addr(int sock, n2n_sock_t *sn); 108 | 109 | 110 | #endif /*SN_MULTIPLE_H_ */ 111 | -------------------------------------------------------------------------------- /n2n_transforms.h: -------------------------------------------------------------------------------- 1 | /* (c) 2009 Richard Andrews */ 2 | 3 | #if !defined(N2N_TRANSFORMS_H_) 4 | #define N2N_TRANSFORMS_H_ 5 | 6 | #include "n2n_keyfile.h" 7 | #include "n2n_wire.h" 8 | 9 | 10 | #define N2N_TRANSFORM_ID_INVAL 0 /* marks uninitialised data */ 11 | #define N2N_TRANSFORM_ID_NULL 1 12 | #define N2N_TRANSFORM_ID_TWOFISH 2 13 | #define N2N_TRANSFORM_ID_AESCBC 3 14 | #define N2N_TRANSFORM_ID_LZO 4 15 | #define N2N_TRANSFORM_ID_TWOFISH_LZO 5 16 | #define N2N_TRANSFORM_ID_AESCBC_LZO 6 17 | #define N2N_TRANSFORM_ID_USER_START 64 18 | #define N2N_TRANSFORM_ID_MAX 65535 19 | 20 | 21 | struct n2n_trans_op; 22 | typedef struct n2n_trans_op n2n_trans_op_t; 23 | 24 | struct n2n_tostat 25 | { 26 | uint8_t can_tx; /* Does this transop have a valid SA for encoding. */ 27 | n2n_cipherspec_t tx_spec; /* If can_tx, the spec used to encode. */ 28 | }; 29 | 30 | typedef struct n2n_tostat n2n_tostat_t; 31 | 32 | 33 | typedef int (*n2n_transdeinit_f) (n2n_trans_op_t *arg); 34 | typedef int (*n2n_transaddspec_f) (n2n_trans_op_t *arg, 35 | const n2n_cipherspec_t *cspec); 36 | typedef n2n_tostat_t (*n2n_transtick_f) (n2n_trans_op_t *arg, 37 | time_t now); 38 | 39 | typedef int (*n2n_transform_f) (n2n_trans_op_t *arg, 40 | uint8_t *outbuf, 41 | size_t out_len, 42 | const uint8_t *inbuf, 43 | size_t in_len); 44 | 45 | /** Holds the info associated with a data transform plugin. 46 | * 47 | * When a packet arrives the transform ID is extracted. This defines the code 48 | * to use to decode the packet content. The transform code then decodes the 49 | * packet and consults its internal key lookup. 50 | */ 51 | struct n2n_trans_op 52 | { 53 | void *priv; /* opaque data. Key schedule goes here. */ 54 | 55 | n2n_transform_t transform_id; /* link header enum to a transform */ 56 | size_t tx_cnt; 57 | size_t rx_cnt; 58 | 59 | n2n_transdeinit_f deinit; /* destructor function */ 60 | n2n_transaddspec_f addspec; /* parse opaque data from a key schedule file. */ 61 | n2n_transtick_f tick; /* periodic maintenance */ 62 | n2n_transform_f fwd; /* encode a payload */ 63 | n2n_transform_f rev; /* decode a payload */ 64 | }; 65 | 66 | /* Setup a single twofish SA for single-key operation. */ 67 | int transop_twofish_setup(n2n_trans_op_t *ttt, 68 | n2n_sa_t sa_num, 69 | uint8_t *encrypt_pwd, 70 | uint32_t encrypt_pwd_len); 71 | 72 | /* Initialise an empty transop ready to receive cipherspec elements. */ 73 | int transop_twofish_init(n2n_trans_op_t *ttt); 74 | int transop_aes_init(n2n_trans_op_t *ttt); 75 | void transop_null_init(n2n_trans_op_t *ttt); 76 | 77 | #endif /* #if !defined(N2N_TRANSFORMS_H_) */ 78 | 79 | -------------------------------------------------------------------------------- /debian/n2n-supernode.init: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: n2n-supernode 4 | # Required-Start: $remote_fs $syslog 5 | # Required-Stop: $remote_fs $syslog 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: n2n-supernode 9 | # Description: Start n2n supernode 10 | ### END INIT INFO 11 | 12 | # Init script for n2n supernode 13 | # Copyright (C) 2010 Kim Hansen 14 | # 15 | # This program is free software: you can redistribute it and/or modify 16 | # it under the terms of the GNU General Public License as published by 17 | # the Free Software Foundation, either version 3 of the License, or 18 | # (at your option) any later version. 19 | # 20 | # This program is distributed in the hope that it will be useful, 21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | # GNU General Public License for more details. 24 | # 25 | # You should have received a copy of the GNU General Public License 26 | # along with this program. If not, see . 27 | 28 | # Do NOT "set -e" 29 | 30 | # PATH should only include /usr/* if it runs after the mountnfs.sh script 31 | PATH=/sbin:/usr/sbin:/bin:/usr/bin 32 | DESC="n2n supernode" 33 | NAME=n2n-supernode 34 | DAEMON=/usr/sbin/supernode 35 | DAEMON_ARGS="" 36 | SCRIPTNAME=/etc/init.d/$NAME 37 | 38 | # Exit if the package is not installed 39 | [ -x "$DAEMON" ] || exit 0 40 | 41 | # Read configuration variable file if it is present 42 | [ -r /etc/default/$NAME ] && . /etc/default/$NAME 43 | 44 | # Load the VERBOSE setting and other rcS variables 45 | . /lib/init/vars.sh 46 | 47 | # Define LSB log_* functions. 48 | # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. 49 | . /lib/lsb/init-functions 50 | 51 | # 52 | # Function that starts the daemon/service 53 | # 54 | do_start() 55 | { 56 | # Return 57 | # 0 if daemon has been started 58 | # 1 if daemon was already running 59 | # 2 if daemon could not be started 60 | start-stop-daemon --start --quiet --user nobody --exec $DAEMON --test \ 61 | || return 1 62 | start-stop-daemon --start --quiet --user nobody --chuid nobody --exec $DAEMON -- \ 63 | $DAEMON_ARGS \ 64 | || return 2 65 | } 66 | 67 | # 68 | # Function that stops the daemon/service 69 | # 70 | do_stop() 71 | { 72 | # Return 73 | # 0 if daemon has been stopped 74 | # 1 if daemon was already stopped 75 | # 2 if daemon could not be stopped 76 | # other if a failure occurred 77 | start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --user nobody --exec $DAEMON 78 | } 79 | 80 | case "$1" in 81 | start) 82 | [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" 83 | do_start 84 | case "$?" in 85 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 86 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 87 | esac 88 | ;; 89 | stop) 90 | [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" 91 | do_stop 92 | case "$?" in 93 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 94 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 95 | esac 96 | ;; 97 | restart|force-reload) 98 | log_daemon_msg "Restarting $DESC" "$NAME" 99 | do_stop 100 | case "$?" in 101 | 0|1) 102 | do_start 103 | case "$?" in 104 | 0) log_end_msg 0 ;; 105 | 1) log_end_msg 1 ;; # Old process is still running 106 | *) log_end_msg 1 ;; # Failed to start 107 | esac 108 | ;; 109 | *) 110 | # Failed to stop 111 | log_end_msg 1 112 | ;; 113 | esac 114 | ;; 115 | *) 116 | echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 117 | exit 3 118 | ;; 119 | esac 120 | 121 | true # Set exit status to 0 (succes) 122 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | 3 | Edge node 4 | --------- 5 | 6 | You need to start an edge node on each host you want to connect with the *same* 7 | community. 8 | 9 | 0. become root 10 | 11 | 1. create tun device 12 | # tunctl -t tun0 13 | 14 | 3. enable the edge process 15 | # ./edge -d n2n0 -c mynetwork -k encryptme -u 99 -g 99 -m 3C:A0:12:34:56:78 -a 1.2.3.4 -l a.b.c.d:xyw 16 | or 17 | # N2N_KEY=encryptme ./edge -d n2n0 -c mynetwork -u 99 -g 99 -m 3C:A0:12:34:56:78 -a 1.2.3.4 -l a.b.c.d:xyw 18 | 19 | Once you have this worked out, you can add the "-f" option to make edge detach 20 | and run as a daemon. 21 | 22 | Note that -u, -g and -f options are not available for Windows. 23 | 24 | Supernode 25 | -------- 26 | 27 | You need to start the supernode once 28 | 29 | 1. ./supernode -l 1234 -v 30 | 31 | 32 | Dropping Root Privileges and SUID-Root Executables (UNIX) 33 | -------------------------------------------------- 34 | 35 | The edge node uses superuser privileges to create a TAP network interface 36 | device. Once this is created root privileges are not required and can constitute 37 | a security hazard if there is some way for an attacker to take control of an 38 | edge process while it is running. Edge will drop to a non-privileged user if you 39 | specify the -u and -g options. These are numeric IDs. Consult 40 | /etc/passwd. 41 | 42 | You may choose to install edge SUID-root to do this: 43 | 44 | 1. Become root 45 | 2. chown root:root edge 46 | 3. chmod +s edge 47 | done 48 | 49 | Any user can now run edge. You may not want this, but it may be convenient and 50 | safe if your host has only one login user. 51 | 52 | 53 | Running As a Daemon (UNIX) 54 | ------------------- 55 | 56 | Unless given "-f" as a command line option, edge will call daemon(3) after 57 | successful setup. This causes the process to fork a child which closes stdin, 58 | stdout and stderr then sets itself as process group leader. When this is done, 59 | the edge command returns immediately and you will only see the edge process in 60 | the process listings, eg. from ps or top. 61 | 62 | If the edge command returns 0 then the daemon started successfully. If it 63 | returns non-zero then edge failed to start up for some reason. When edge starts 64 | running as a daemon, all logging goes to syslog daemon.info facility. 65 | 66 | 67 | IPv6 Support 68 | ------------ 69 | 70 | n2n supports the carriage of IPv6 packets within the n2n tunnel. N2n does not 71 | yet use IPv6 for transport between edges and supernodes. 72 | 73 | To make IPv6 carriage work you need to manually add IPv6 addresses to the TAP 74 | interfaces at each end. There is currently no way to specify an IPv6 address on 75 | the edge command line. 76 | 77 | eg. under linux: 78 | 79 | on hostA: 80 | [hostA] # /sbin/ip -6 addr add fc00:abcd:1234::7/48 dev n2n0 81 | 82 | on hostB: 83 | [hostB] # /sbin/ip -6 addr add fc00:abcd:1234::6/48 dev n2n0 84 | 85 | You may find it useful to make use of tunctl from the uml-utilities 86 | package. Tunctl allow you to bring up a TAP interface and configure addressing 87 | prior to starting edge. It also allows edge to be restarted without the 88 | interface closing (which would normally affect routing tables). 89 | 90 | Once the IPv6 addresses are configured and edge started, IPv6 neighbor discovery 91 | packets flow (get broadcast) and IPv6 entities self arrange. Test your IPv6 92 | setup with ping6 - the IPv6 ping command. 93 | 94 | 95 | Performance Notes 96 | ----------------- 97 | 98 | The time taken to perform a ping test for various ciphers is given below: 99 | 100 | Test: ping -f -l 8 -s 800 -c 10000 101 | 102 | AES (-O0) 11820 103 | TF (-O0) 25761 104 | 105 | TF (-O2) 20554 106 | 107 | AES (-O3) 12532 108 | TF (-O3) 14046 109 | NULL (-O3) 10659 110 | 111 | (C) 2007-2010 - Luca Deri , Richard Andrews 112 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | N2N_MAJOR=3 2 | N2N_MINOR=0 3 | N2N_VERSION=$(N2N_MAJOR).$(N2N_MINOR) 4 | N2N_OSNAME=$(shell uname -p) 5 | 6 | ######## 7 | 8 | CC=gcc 9 | DEBUG?=-g3 10 | #OPTIMIZATION?=-O2 11 | WARN?=-Wall -Wshadow -Wpointer-arith -Wmissing-declarations -Wnested-externs 12 | 13 | #Ultrasparc64 users experiencing SIGBUS should try the following gcc options 14 | #(thanks to Robert Gibbon) 15 | PLATOPTS_SPARC64=-mcpu=ultrasparc -pipe -fomit-frame-pointer -ffast-math -finline-functions -fweb -frename-registers -mapp-regs 16 | 17 | N2N_DEFINES= 18 | N2N_OBJS_OPT= 19 | LIBS_EDGE_OPT= 20 | LIBS_SN_OPT= 21 | 22 | N2N_OPTION_AES?="yes" 23 | #N2N_OPTION_AES=no 24 | 25 | ifeq ($(N2N_OPTION_AES), "yes") 26 | N2N_DEFINES+="-DN2N_HAVE_AES" 27 | LIBS_EDGE_OPT+=-lcrypto 28 | endif 29 | 30 | ifeq ($(SNM), yes) 31 | N2N_DEFINES+="-DN2N_MULTIPLE_SUPERNODES" 32 | endif 33 | 34 | CFLAGS+=$(DEBUG) $(OPTIMIZATION) $(WARN) $(OPTIONS) $(PLATOPTS) $(N2N_DEFINES) 35 | 36 | INSTALL=install 37 | MKDIR=mkdir -p 38 | 39 | INSTALL_PROG=$(INSTALL) -m755 40 | INSTALL_DOC=$(INSTALL) -m644 41 | 42 | 43 | # DESTDIR set in debian make system 44 | PREFIX?=$(DESTDIR)/usr 45 | #BINDIR=$(PREFIX)/bin 46 | SBINDIR=$(PREFIX)/sbin 47 | MANDIR?=$(PREFIX)/share/man 48 | MAN1DIR=$(MANDIR)/man1 49 | MAN7DIR=$(MANDIR)/man7 50 | MAN8DIR=$(MANDIR)/man8 51 | 52 | N2N_LIB=n2n.a 53 | N2N_OBJS=n2n.o n2n_net.o n2n_keyfile.o n2n_list.o n2n_log.o n2n_utils.o n2n_wire.o minilzo.o twofish.o \ 54 | transform_null.o transform_tf.o transform_aes.o 55 | 56 | XNIX_OBJS=tuntap_freebsd.o tuntap_netbsd.o tuntap_linux.o tuntap_osx.o version.o 57 | 58 | WIN32_DIR=win32 59 | WIN32_OBJS=$(WIN32_DIR)/wintap.o $(WIN32_DIR)/version-msvc.o 60 | 61 | ifeq ($(shell uname -o), Cygwin) 62 | N2N_OBJS+=$(WIN32_OBJS) 63 | CFLAGS+="-DWIN32" 64 | CFLAGS+="-D__USE_W32_SOCKETS" 65 | LIBS_EDGE_OPT+=-lws2_32 66 | LIBS_SN_OPT+=-lws2_32 67 | else 68 | N2N_OBJS+=$(XNIX_OBJS) 69 | endif 70 | 71 | ifeq ($(SNM), yes) 72 | N2N_OBJS+=sn_multiple.o 73 | endif 74 | 75 | LIBS_EDGE+=$(LIBS_EDGE_OPT) 76 | LIBS_SN+=$(LIBS_SN_OPT) 77 | 78 | #For OpenSolaris (Solaris too?) 79 | ifeq ($(shell uname), SunOS) 80 | LIBS_EDGE+=-lsocket -lnsl 81 | LIBS_SN+=-lsocket -lnsl 82 | endif 83 | 84 | APPS=edge 85 | APPS+=supernode 86 | 87 | DOCS=edge.8.gz supernode.1.gz n2n_v$(N2N_VERSION).gz 88 | 89 | all: $(APPS) $(DOCS) 90 | 91 | edge: edge.c edge.h edge_mgmt.c edge_mgmt.h $(N2N_LIB) n2n_wire.h n2n.h Makefile 92 | $(CC) $(CFLAGS) edge.c edge_mgmt.c $(N2N_LIB) $(LIBS_EDGE) -o edge 93 | 94 | test: test.c $(N2N_LIB) n2n_wire.h n2n.h Makefile 95 | $(CC) $(CFLAGS) test.c $(N2N_LIB) $(LIBS_EDGE) -o test 96 | 97 | supernode: sn.c sn.h $(N2N_LIB) n2n.h Makefile 98 | $(CC) $(CFLAGS) sn.c $(N2N_LIB) $(LIBS_SN) -o supernode 99 | 100 | benchmark: benchmark.c $(N2N_LIB) n2n_wire.h n2n.h Makefile 101 | $(CC) $(CFLAGS) benchmark.c $(N2N_LIB) $(LIBS_SN) -o benchmark 102 | 103 | ifeq ($(SNM), yes) 104 | test_snm: sn_multiple_test.c $(N2N_LIB) n2n.h Makefile 105 | $(CC) $(CFLAGS) sn_multiple_test.c $(N2N_LIB) $(LIBS_SN) -o test_snm 106 | endif 107 | 108 | .c.o: n2n.h n2n_keyfile.h n2n_transforms.h n2n_wire.h twofish.h Makefile 109 | $(CC) $(CFLAGS) -c $< -o $@ 110 | 111 | %.gz : % 112 | gzip -c $< > $@ 113 | 114 | $(N2N_LIB): $(N2N_OBJS) 115 | ar rcs $(N2N_LIB) $(N2N_OBJS) 116 | # $(RANLIB) $@ 117 | 118 | version.o: Makefile 119 | $(CC) $(CFLAGS) -DN2N_VERSION='"$(N2N_VERSION)"' -DN2N_OSNAME='"$(N2N_OSNAME)"' -c version.c 120 | 121 | clean: 122 | rm -rf $(N2N_OBJS) $(N2N_LIB) $(APPS) $(DOCS) test *.dSYM *~ 123 | 124 | install: edge supernode edge.8.gz supernode.1.gz n2n_v$(N2N_VERSION).gz 125 | echo "MANDIR=$(MANDIR)" 126 | $(MKDIR) $(SBINDIR) $(MAN1DIR) $(MAN7DIR) $(MAN8DIR) 127 | $(INSTALL_PROG) supernode $(SBINDIR)/ 128 | $(INSTALL_PROG) edge $(SBINDIR)/ 129 | $(INSTALL_DOC) edge.8.gz $(MAN8DIR)/ 130 | $(INSTALL_DOC) supernode.1.gz $(MAN1DIR)/ 131 | $(INSTALL_DOC) n2n_v$(N2N_VERSION).gz $(MAN7DIR)/ 132 | -------------------------------------------------------------------------------- /minilzo.h: -------------------------------------------------------------------------------- 1 | /* minilzo.h -- mini subset of the LZO real-time data compression library 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer 6 | Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer 7 | Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer 8 | Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer 9 | Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer 10 | Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer 11 | Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer 12 | Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer 13 | Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer 14 | Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer 15 | Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer 16 | Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer 17 | Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer 18 | All Rights Reserved. 19 | 20 | The LZO library is free software; you can redistribute it and/or 21 | modify it under the terms of the GNU General Public License as 22 | published by the Free Software Foundation; either version 2 of 23 | the License, or (at your option) any later version. 24 | 25 | The LZO library is distributed in the hope that it will be useful, 26 | but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | GNU General Public License for more details. 29 | 30 | You should have received a copy of the GNU General Public License 31 | along with the LZO library; see the file COPYING. 32 | If not, write to the Free Software Foundation, Inc., 33 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 34 | 35 | Markus F.X.J. Oberhumer 36 | 37 | http://www.oberhumer.com/opensource/lzo/ 38 | */ 39 | 40 | /* 41 | * NOTE: 42 | * the full LZO package can be found at 43 | * http://www.oberhumer.com/opensource/lzo/ 44 | */ 45 | 46 | 47 | #ifndef __MINILZO_H 48 | #define __MINILZO_H 49 | 50 | #define MINILZO_VERSION 0x2030 51 | 52 | #ifdef __LZOCONF_H 53 | # error "you cannot use both LZO and miniLZO" 54 | #endif 55 | 56 | #undef LZO_HAVE_CONFIG_H 57 | #include "lzoconf.h" 58 | 59 | #if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION) 60 | # error "version mismatch in header files" 61 | #endif 62 | 63 | 64 | #ifdef __cplusplus 65 | extern "C" { 66 | #endif 67 | 68 | 69 | /*********************************************************************** 70 | // 71 | ************************************************************************/ 72 | 73 | /* Memory required for the wrkmem parameter. 74 | * When the required size is 0, you can also pass a NULL pointer. 75 | */ 76 | 77 | #define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS 78 | #define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) 79 | #define LZO1X_MEM_DECOMPRESS (0) 80 | 81 | 82 | /* compression */ 83 | LZO_EXTERN(int) 84 | lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len, 85 | lzo_bytep dst, lzo_uintp dst_len, 86 | lzo_voidp wrkmem ); 87 | 88 | /* decompression */ 89 | LZO_EXTERN(int) 90 | lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len, 91 | lzo_bytep dst, lzo_uintp dst_len, 92 | lzo_voidp wrkmem /* NOT USED */ ); 93 | 94 | /* safe decompression with overrun testing */ 95 | LZO_EXTERN(int) 96 | lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len, 97 | lzo_bytep dst, lzo_uintp dst_len, 98 | lzo_voidp wrkmem /* NOT USED */ ); 99 | 100 | 101 | #ifdef __cplusplus 102 | } /* extern "C" */ 103 | #endif 104 | 105 | #endif /* already included */ 106 | 107 | -------------------------------------------------------------------------------- /debian/n2n-edge.init: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | ### BEGIN INIT INFO 3 | # Provides: n2n-edge 4 | # Required-Start: $remote_fs $syslog 5 | # Required-Stop: $remote_fs $syslog 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: n2n-edge 9 | # Description: Start n2n edge node daemon 10 | ### END INIT INFO 11 | 12 | # Init script for n2n edge node 13 | # Copyright (C) 2010 Kim Hansen 14 | # 15 | # This program is free software: you can redistribute it and/or modify 16 | # it under the terms of the GNU General Public License as published by 17 | # the Free Software Foundation, either version 3 of the License, or 18 | # (at your option) any later version. 19 | # 20 | # This program is distributed in the hope that it will be useful, 21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | # GNU General Public License for more details. 24 | # 25 | # You should have received a copy of the GNU General Public License 26 | # along with this program. If not, see . 27 | 28 | # Do NOT "set -e" 29 | 30 | # PATH should only include /usr/* if it runs after the mountnfs.sh script 31 | PATH=/sbin:/usr/sbin:/bin:/usr/bin 32 | DESC="n2n edge" 33 | NAME=n2n-edge 34 | DAEMON=/usr/sbin/edge 35 | SCRIPTNAME=/etc/init.d/$NAME 36 | 37 | # Exit if the package is not installed 38 | [ -x "$DAEMON" ] || exit 0 39 | 40 | # Read configuration variable file if it is present 41 | [ -r /etc/default/$NAME ] && . /etc/default/$NAME 42 | 43 | # Check config 44 | if [ -z "$N2N_EDGE_CONFIG_DONE" ] 45 | then 46 | echo "Warning: n2n-edge not configured, edit config file in /etc/default/$NAME." 1>&2 47 | exit 0 48 | fi 49 | 50 | # Load the VERBOSE setting and other rcS variables 51 | . /lib/init/vars.sh 52 | 53 | # Define LSB log_* functions. 54 | # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. 55 | . /lib/lsb/init-functions 56 | 57 | # 58 | # Function that starts the daemon/service 59 | # 60 | do_start() 61 | { 62 | # Return 63 | # 0 if daemon has been started 64 | # 1 if daemon was already running 65 | # 2 if daemon could not be started 66 | start-stop-daemon --start --quiet --user nobody --exec $DAEMON --test \ 67 | || return 1 68 | export N2N_KEY 69 | start-stop-daemon --start --quiet --user nobody --exec $DAEMON -- \ 70 | -a $N2N_IP -c $N2N_COMMUNITY -l $N2N_SUPERNODE:7654 -u $(id -u nobody) -g $(id -g nobody) \ 71 | $DAEMON_ARGS \ 72 | || return 2 73 | } 74 | 75 | # 76 | # Function that stops the daemon/service 77 | # 78 | do_stop() 79 | { 80 | # Return 81 | # 0 if daemon has been stopped 82 | # 1 if daemon was already stopped 83 | # 2 if daemon could not be stopped 84 | # other if a failure occurred 85 | start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --user nobody --exec $DAEMON 86 | } 87 | 88 | case "$1" in 89 | start) 90 | [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" 91 | do_start 92 | case "$?" in 93 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 94 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 95 | esac 96 | ;; 97 | stop) 98 | [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" 99 | do_stop 100 | case "$?" in 101 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 102 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 103 | esac 104 | ;; 105 | restart|force-reload) 106 | log_daemon_msg "Restarting $DESC" "$NAME" 107 | do_stop 108 | case "$?" in 109 | 0|1) 110 | do_start 111 | case "$?" in 112 | 0) log_end_msg 0 ;; 113 | 1) log_end_msg 1 ;; # Old process is still running 114 | *) log_end_msg 1 ;; # Failed to start 115 | esac 116 | ;; 117 | *) 118 | # Failed to stop 119 | log_end_msg 1 120 | ;; 121 | esac 122 | ;; 123 | *) 124 | echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 125 | exit 3 126 | ;; 127 | esac 128 | 129 | true # Set exit status to 0 (succes) 130 | -------------------------------------------------------------------------------- /benchmark.c: -------------------------------------------------------------------------------- 1 | #include "n2n_wire.h" 2 | #include "n2n_transforms.h" 3 | #include "n2n.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | uint8_t PKT_CONTENT[]={ 11 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 12 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 13 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 14 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 15 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 16 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 17 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 18 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 19 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 20 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 21 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 22 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 23 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 24 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 25 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 26 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 }; 27 | 28 | /* Prototypes */ 29 | static ssize_t do_encode_packet(uint8_t *pktbuf, 30 | size_t bufsize, 31 | const n2n_community_t c); 32 | 33 | int main(int argc, char *argv[]) 34 | { 35 | uint8_t pktbuf[N2N_PKT_BUF_SIZE]; 36 | n2n_trans_op_t transop_null; 37 | 38 | n2n_common_t cmn; 39 | n2n_PACKET_t pkt; 40 | n2n_community_t c; 41 | 42 | struct timeval t1; 43 | struct timeval t2; 44 | 45 | size_t i; 46 | size_t n; 47 | size_t idx; 48 | size_t rem; 49 | ssize_t nw; 50 | ssize_t tdiff; 51 | 52 | transop_null_init(&transop_null); 53 | memset(c, 0, sizeof(N2N_COMMUNITY_SIZE)); 54 | 55 | n = 10000; 56 | memcpy(c, "abc123def456", 12); 57 | 58 | gettimeofday(&t1, NULL); 59 | for (i = 0; i < n; ++i) 60 | { 61 | nw = do_encode_packet(pktbuf, N2N_PKT_BUF_SIZE, c); 62 | 63 | nw += transop_null.fwd(&transop_null, 64 | pktbuf + nw, N2N_PKT_BUF_SIZE - nw, 65 | PKT_CONTENT, sizeof(PKT_CONTENT)); 66 | 67 | idx = 0; 68 | rem = nw; 69 | 70 | decode_common(&cmn, pktbuf, &rem, &idx); 71 | decode_PACKET(&pkt, &cmn, pktbuf, &rem, &idx); 72 | 73 | if (0 == (i % 1000)) 74 | { 75 | fprintf(stderr, "."); 76 | } 77 | } 78 | gettimeofday(&t2, NULL); 79 | 80 | tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec); 81 | 82 | fprintf(stderr, "\nrun %u times. (%u -> %u nsec each) %u.%06u -> %u.%06u.\n", 83 | i, tdiff, (tdiff * 1000) / i, 84 | (uint32_t) t1.tv_sec, (uint32_t) t1.tv_usec, 85 | (uint32_t) t2.tv_sec, (uint32_t) t2.tv_usec); 86 | 87 | return 0; 88 | } 89 | 90 | static ssize_t do_encode_packet(uint8_t *pktbuf, 91 | size_t bufsize, 92 | const n2n_community_t c) 93 | { 94 | n2n_mac_t destMac = { 0, 1, 2, 3, 4, 5 }; 95 | n2n_common_t cmn; 96 | n2n_PACKET_t pkt; 97 | size_t idx; 98 | 99 | memset(&cmn, 0, sizeof(cmn)); 100 | cmn.ttl = N2N_DEFAULT_TTL; 101 | cmn.pc = n2n_packet; 102 | cmn.flags = 0; /* no options, not from supernode, no socket */ 103 | memcpy(cmn.community, c, N2N_COMMUNITY_SIZE); 104 | 105 | memset(&pkt, 0, sizeof(pkt)); 106 | memcpy(pkt.srcMac, destMac, N2N_MAC_SIZE); 107 | memcpy(pkt.dstMac, destMac, N2N_MAC_SIZE); 108 | 109 | pkt.sock.family = 0; /* do not encode sock */ 110 | 111 | idx = 0; 112 | encode_PACKET(pktbuf, &idx, &cmn, &pkt); 113 | traceDebug("encoded PACKET header of size=%u", (unsigned int) idx); 114 | 115 | return idx; 116 | } 117 | -------------------------------------------------------------------------------- /n2n_keyfile.h: -------------------------------------------------------------------------------- 1 | /* (c) 2009 Richard Andrews */ 2 | 3 | /** Key files 4 | * 5 | * Edge implements a very simple interface for getting instructions about 6 | * rolling keys. 7 | * 8 | * Key definitions are written as individual files in /.key. The 9 | * format of each key is a single line of hex nibbles as follows: 10 | * 11 | * 0102030405060708090a0b0c0d0e0f 12 | * 13 | * Any external key exchange mechanism can receive the key data write it into 14 | * the keyfiles. 15 | * 16 | * To control which keys are active at what times the key control file is 17 | * used. This is a single file which is periodically reread. It contains key 18 | * definitions in chronological order with one line per key definition as 19 | * follows: 20 | * 21 | * 22 | * 23 | * edge reads the key control file periodically to get updates in policy. edge 24 | * holds a number of keys in memory. Data can be decoded if it was encoded by 25 | * any of the keys still in memory. By having at least 2 keys in memory it 26 | * allows for clock skew and transmission delay when encoder and decoder roll 27 | * keys at slightly different times. The amount of overlap in the valid time 28 | * ranges provides the tolerance to timing skews in the system. 29 | * 30 | * The keys have the same level of secrecy as any other user file. Existing 31 | * UNIX permission systems can be used to provide access controls. 32 | * 33 | */ 34 | 35 | /** How Edge Uses The Key Schedule 36 | * 37 | * Edge provides state space for a number of transform algorithms. Each 38 | * transform uses its state space to store the SA information for its keys as 39 | * found in the key file. When a packet is received the transform ID is in 40 | * plain text. The packets is then sent to that transform for decoding. Each 41 | * transform can store its SA numbers differently (or not at all). The 42 | * transform code then finds the SA number, then finds the cipher (with key) in 43 | * the state space and uses this to decode the packet. 44 | * 45 | * To support this, as edge reads each key line, it passes it to the 46 | * appropriate transform to parse the line and store the SA information in its 47 | * state space. 48 | * 49 | * When encoding a packet, edge has several transforms and potentially valid 50 | * SAs to choose from. To keep track of which one to use for encoding edge does 51 | * its own book-keeping as each key line is passed to the transform code: it 52 | * stores a lookup of valid_from -> transform. When encoding a packet it then 53 | * just calls the transform with the best valid_from in the table. The 54 | * transform's own state space has all the SAs for its keys and the best of 55 | * those is chosen. 56 | */ 57 | 58 | #if !defined( N2N_KEYFILE_H_ ) 59 | #define N2N_KEYFILE_H_ 60 | 61 | 62 | #include "n2n_wire.h" 63 | #include 64 | 65 | #define N2N_MAX_KEYSIZE 256 /* bytes */ 66 | #define N2N_MAX_NUM_CIPHERSPECS 8 67 | #define N2N_KEYPATH_SIZE 256 68 | #define N2N_KEYFILE_LINESIZE 256 69 | 70 | /** This structure stores an encryption cipher spec. */ 71 | struct n2n_cipherspec 72 | { 73 | n2n_transform_t t; /* N2N_TRANSFORM_ID_xxx for this spec. */ 74 | time_t valid_from; /* Start using the key at this time. */ 75 | time_t valid_until; /* Key is valid if time < valid_until. */ 76 | uint16_t opaque_size; /* Size in bytes of key. */ 77 | uint8_t opaque[N2N_MAX_KEYSIZE];/* Key matter. */ 78 | }; 79 | 80 | typedef struct n2n_cipherspec n2n_cipherspec_t; 81 | 82 | 83 | static const char * const DELIMITERS=" \t\n\r"; 84 | 85 | 86 | /** @return number of cipherspec items filled. */ 87 | int n2n_read_keyfile(n2n_cipherspec_t *specs, /* fill out this array of cipherspecs */ 88 | size_t numspecs, /* number of slots in the array. */ 89 | const char *ctrlfile_path); /* path to control file */ 90 | 91 | int validCipherSpec(const n2n_cipherspec_t *k, 92 | time_t now ); 93 | 94 | ssize_t n2n_parse_hex(uint8_t *keyBuf, 95 | size_t keyMax, 96 | const char *textKey, 97 | size_t textLen); 98 | 99 | /*----------------------------------------------------------------------------*/ 100 | 101 | #endif /* #if !defined( N2N_KEYFILE_H_ ) */ 102 | -------------------------------------------------------------------------------- /tuntap_freebsd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-09 - Luca Deri 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not see see 16 | */ 17 | 18 | #include "n2n.h" 19 | 20 | #ifdef __FreeBSD__ 21 | 22 | void tun_close(tuntap_dev *device); 23 | 24 | /* ********************************** */ 25 | 26 | #define N2N_FREEBSD_TAPDEVICE_SIZE 32 27 | int tuntap_open(tuntap_dev *device /* ignored */, 28 | char *dev, 29 | const char *address_mode, /* static or dhcp */ 30 | char *device_ip, 31 | char *device_mask, 32 | const char *device_mac, 33 | int mtu) 34 | { 35 | int i; 36 | char tap_device[N2N_FREEBSD_TAPDEVICE_SIZE]; 37 | 38 | for (i = 0; i < 255; i++) 39 | { 40 | snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); 41 | 42 | device->fd = open(tap_device, O_RDWR); 43 | if (device->fd > 0) 44 | { 45 | traceNormal("Succesfully open %s", tap_device); 46 | break; 47 | } 48 | } 49 | 50 | if (device->fd < 0) 51 | { 52 | traceError("Unable to open tap device"); 53 | return (-1); 54 | } 55 | else 56 | { 57 | char buf[256]; 58 | FILE *fd; 59 | 60 | device->ip_addr = inet_addr(device_ip); 61 | 62 | if (device_mac && device_mac[0] != '\0') 63 | { 64 | /* FIXME - This is not tested. Might be wrong syntax for OS X */ 65 | 66 | /* Set the hw address before bringing the if up. */ 67 | snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", 68 | i, device_mac); 69 | system(buf); 70 | } 71 | 72 | snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", 73 | i, device_ip, device_mask, mtu); 74 | system(buf); 75 | 76 | traceNormal("Interface tap%d up and running (%s/%s)", 77 | i, device_ip, device_mask); 78 | 79 | /* Read MAC address */ 80 | 81 | snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); 82 | /* traceInfo("%s", buf); */ 83 | 84 | fd = popen(buf, "r"); 85 | if (fd < 0) 86 | { 87 | tun_close(device); 88 | return (-1); 89 | } 90 | else 91 | { 92 | int a, b, c, d, e, f; 93 | 94 | buf[0] = 0; 95 | fgets(buf, sizeof(buf), fd); 96 | pclose(fd); 97 | 98 | if (buf[0] == '\0') 99 | { 100 | traceError("Unable to read tap%d interface MAC address"); 101 | exit(0); 102 | } 103 | 104 | traceNormal("Interface tap%d mac %s", i, buf); 105 | if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) 106 | { 107 | device->mac_addr[0] = a, device->mac_addr[1] = b; 108 | device->mac_addr[2] = c, device->mac_addr[3] = d; 109 | device->mac_addr[4] = e, device->mac_addr[5] = f; 110 | } 111 | } 112 | } 113 | 114 | /* read_mac(dev, device->mac_addr); */ 115 | return (device->fd); 116 | } 117 | 118 | /* ********************************** */ 119 | 120 | int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) 121 | { 122 | return (read(tuntap->fd, buf, len)); 123 | } 124 | 125 | /* ********************************** */ 126 | 127 | int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) 128 | { 129 | return (write(tuntap->fd, buf, len)); 130 | } 131 | 132 | /* ********************************** */ 133 | 134 | void tuntap_close(struct tuntap_dev *tuntap) 135 | { 136 | close(tuntap->fd); 137 | } 138 | 139 | /* Fill out the ip_addr value from the interface. Called to pick up dynamic 140 | * address changes. */ 141 | void tuntap_get_address(struct tuntap_dev *tuntap) 142 | { 143 | } 144 | 145 | #endif /* #ifdef __FreeBSD__ */ 146 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(n2n) 2 | cmake_minimum_required(VERSION 2.6) 3 | 4 | # N2n information 5 | set(N2N_VERSION 2.1.0) 6 | set(N2N_OSNAME ${CMAKE_SYSTEM}) 7 | 8 | # N2n specific params 9 | if(NOT DEFINED N2N_OPTION_AES) 10 | set(N2N_OPTION_AES ON) 11 | endif(NOT DEFINED N2N_OPTION_AES) 12 | 13 | add_definitions(-DN2N_VERSION='\"${N2N_VERSION}\"' -DN2N_OSNAME='\"${N2N_OSNAME}\"') 14 | 15 | if(N2N_OPTION_AES) 16 | add_definitions(-DN2N_HAVE_AES) 17 | endif(N2N_OPTION_AES) 18 | 19 | # Build information 20 | if(NOT DEFINED BUILD_SHARED_LIBS) 21 | set(BUILD_SHARED_LIBS OFF) 22 | endif(NOT DEFINED BUILD_SHARED_LIBS) 23 | 24 | if(NOT DEFINED CMAKE_BUILD_TYPE) 25 | set(CMAKE_BUILD_TYPE None) 26 | endif(NOT DEFINED CMAKE_BUILD_TYPE) 27 | #set(CMAKE_BUILD_TYPE Debug) 28 | #set(CMAKE_BUILD_TYPE Release) 29 | 30 | #Ultrasparc64 users experiencing SIGBUS should try the following gcc options 31 | #(thanks to Robert Gibbon) 32 | #PLATOPTS_SPARC64=-mcpu=ultrasparc -pipe -fomit-frame-pointer -ffast-math -finline-functions -fweb -frename-registers -mapp-regs 33 | 34 | # None 35 | set(CMAKE_C_FLAGS "-Wall -Wshadow -Wpointer-arith -Wmissing-declarations -Wnested-externs") 36 | set(CMAKE_CXX_FLAGS "-Wall -Wshadow -Wpointer-arith -Wmissing-declarations -Wnested-externs") 37 | # Debug 38 | set(CMAKE_C_FLAGS_DEBUG "-g") 39 | set(CMAKE_CXX_FLAGS_DEBUG "-g") 40 | # Release 41 | set(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG") 42 | set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") 43 | 44 | ## DEBUG FOR CMAKE 45 | #message(${N2N_VERSION}) 46 | #message(${N2N_OSNAME}) 47 | ##message(${CMAKE_BUILD_TYPE}) 48 | #message(${N2N_OPTION_AES}) 49 | ## DEBUG FOR CMAKE 50 | 51 | add_library(n2n n2n.c 52 | n2n_keyfile.c 53 | wire.c 54 | minilzo.c 55 | twofish.c 56 | transform_null.c 57 | transform_tf.c 58 | transform_aes.c 59 | tuntap_freebsd.c 60 | tuntap_netbsd.c 61 | tuntap_linux.c 62 | tuntap_osx.c 63 | version.c 64 | ) 65 | 66 | if(DEFINED WIN32) 67 | add_subdirectory(win32) 68 | target_link_libraries(n2n n2n_win32) 69 | endif(DEFINED WIN32) 70 | 71 | if(N2N_OPTION_AES) 72 | target_link_libraries(n2n crypto) 73 | endif(N2N_OPTION_AES) 74 | 75 | # For Solaris (or OpenSolaris?) 76 | #target_link_libraries(n2n socket nsl) 77 | 78 | add_executable(edge edge.c) 79 | target_link_libraries(edge n2n) 80 | 81 | add_executable(supernode sn.c) 82 | target_link_libraries(supernode n2n) 83 | 84 | add_executable(test test.c) 85 | target_link_libraries(test n2n) 86 | 87 | add_executable(benchmark benchmark.c) 88 | target_link_libraries(benchmark n2n) 89 | 90 | install(TARGETS edge supernode 91 | RUNTIME DESTINATION sbin 92 | LIBRARY DESTINATION lib 93 | ARCHIVE DESTINATION lib 94 | ) 95 | 96 | # Documentation 97 | if(DEFINED UNIX) 98 | add_dependencies(n2n doc) 99 | file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/doc) 100 | add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/edge.8.gz 101 | COMMAND gzip -c ${PROJECT_SOURCE_DIR}/edge.8 > ${PROJECT_BINARY_DIR}/doc/edge.8.gz 102 | DEPENDS ${PROJECT_SOURCE_DIR}/edge.8 103 | ) 104 | 105 | add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/supernode.1.gz 106 | COMMAND gzip -c ${PROJECT_SOURCE_DIR}/supernode.1 > ${PROJECT_BINARY_DIR}/doc/supernode.1.gz 107 | DEPENDS ${PROJECT_SOURCE_DIR}/supernode.1 108 | ) 109 | 110 | add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz 111 | COMMAND gzip -c ${PROJECT_SOURCE_DIR}/n2n_v2.7 > ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz 112 | DEPENDS ${PROJECT_SOURCE_DIR}/n2n_v2.7 113 | ) 114 | 115 | add_custom_target(doc DEPENDS ${PROJECT_BINARY_DIR}/doc/edge.8.gz 116 | ${PROJECT_BINARY_DIR}/doc/supernode.1.gz 117 | ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz 118 | ) 119 | 120 | set_source_files_properties(${PROJECT_BINARY_DIR}/doc/edge.8.gz 121 | ${PROJECT_BINARY_DIR}/doc/supernode.1.gz 122 | ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz 123 | PROPERTIES GENERATED 1) 124 | 125 | install(FILES ${PROJECT_BINARY_DIR}/doc/edge.8.gz 126 | DESTINATION /usr/share/man8) 127 | install(FILES ${PROJECT_BINARY_DIR}/doc/supernode.1.gz 128 | DESTINATION /usr/share/man1) 129 | install(FILES ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz 130 | DESTINATION /usr/share/man7) 131 | endif(DEFINED UNIX) 132 | -------------------------------------------------------------------------------- /tuntap_osx.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-09 - Luca Deri 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not see see 16 | */ 17 | 18 | #include "n2n.h" 19 | #include "n2n_log.h" 20 | #include "tuntap.h" 21 | 22 | #ifdef _DARWIN_ 23 | 24 | /* ********************************** */ 25 | 26 | #define N2N_OSX_TAPDEVICE_SIZE 32 27 | int tuntap_open(tuntap_dev_t *device , ip_mode_t ip_mode) 28 | /*char *dev, 29 | const char *address_mode, // static or dhcp 30 | char *device_ip, 31 | char *device_mask, 32 | const char *device_mac, 33 | int mtu)*/ 34 | { 35 | int i; 36 | char tap_device[N2N_OSX_TAPDEVICE_SIZE]; 37 | 38 | for (i = 0; i < 255; i++) 39 | { 40 | snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); 41 | 42 | device->fd = open(tap_device, O_RDWR); 43 | if (device->fd > 0) 44 | { 45 | traceNormal("Succesfully open %s", tap_device); 46 | break; 47 | } 48 | } 49 | 50 | if (device->fd < 0) 51 | { 52 | traceError("Unable to open tap device"); 53 | return (-1); 54 | } 55 | else 56 | { 57 | char buf[256]; 58 | ipstr_t ipstr, maskstr; 59 | FILE *fd; 60 | 61 | //TODO remove device->ip_addr = inet_addr(device_ip); 62 | 63 | if ( !is_empty_mac(device->mac_addr) ) 64 | { 65 | /* FIXME - This is not tested. Might be wrong syntax for OS X */ 66 | 67 | /* Set the hw address before bringing the if up. */ 68 | macstr_t macstr; 69 | snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", 70 | i, mac2str(macstr, device->mac_addr)); 71 | system(buf); 72 | } 73 | 74 | ipv4_to_str(ipstr, sizeof(ipstr_t), (const uint8_t *) &device->ip_addr); 75 | ipv4_to_str(maskstr, sizeof(ipstr_t), (const uint8_t *) &device->device_mask); 76 | 77 | snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", 78 | i, ipstr, maskstr, device->mtu); 79 | system(buf); 80 | 81 | traceNormal("Interface tap%d up and running (%s/%s)", 82 | i, ipstr, maskstr); 83 | 84 | /* Read MAC address */ 85 | 86 | snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); 87 | /* traceInfo("%s", buf); */ 88 | 89 | fd = popen(buf, "r"); 90 | if (fd < 0) 91 | { 92 | tuntap_close(device); 93 | return (-1); 94 | } 95 | else 96 | { 97 | int a, b, c, d, e, f; 98 | 99 | buf[0] = 0; 100 | fgets(buf, sizeof(buf), fd); 101 | pclose(fd); 102 | 103 | if (buf[0] == '\0') 104 | { 105 | traceError("Unable to read tap%d interface MAC address"); 106 | exit(0); 107 | } 108 | 109 | traceNormal("Interface tap%d [MTU %d] mac %s", i, device->mtu, buf); 110 | if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) 111 | { 112 | device->mac_addr[0] = a, device->mac_addr[1] = b; 113 | device->mac_addr[2] = c, device->mac_addr[3] = d; 114 | device->mac_addr[4] = e, device->mac_addr[5] = f; 115 | } 116 | } 117 | } 118 | 119 | /* read_mac(dev, device->mac_addr); */ 120 | return (device->fd); 121 | } 122 | 123 | /* ********************************** */ 124 | 125 | int tuntap_read(tuntap_dev_t *device, unsigned char *buf, int len) 126 | { 127 | return (read(device->fd, buf, len)); 128 | } 129 | 130 | /* ********************************** */ 131 | 132 | int tuntap_write(tuntap_dev_t *device, unsigned char *buf, int len) 133 | { 134 | return (write(device->fd, buf, len)); 135 | } 136 | 137 | /* ********************************** */ 138 | 139 | void tuntap_close(tuntap_dev_t *device) 140 | { 141 | close(device->fd); 142 | } 143 | 144 | /* Fill out the ip_addr value from the interface. Called to pick up dynamic 145 | * address changes. */ 146 | void tuntap_get_address(tuntap_dev_t *device) 147 | { 148 | } 149 | 150 | #endif /* _DARWIN_ */ 151 | -------------------------------------------------------------------------------- /sn_multiple.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sn_multiple.c 3 | * 4 | * Created on: Mar 25, 2012 5 | * Author: Costin Lupu 6 | */ 7 | 8 | #include "n2n.h" 9 | #include "n2n_log.h" 10 | #include "sn_multiple.h" 11 | //#include "n2n_list.h" 12 | 13 | 14 | 15 | 16 | /******************************************************************* 17 | * Operations on sn_info lists. * 18 | *******************************************************************/ 19 | 20 | 21 | 22 | 23 | 24 | 25 | sn_info_t *create_supernode_info(const n2n_sock_t *sock) 26 | { 27 | sn_info_t *sn = calloc(1, sizeof(sn_info_t)); 28 | if (NULL == sn) 29 | { 30 | traceError("Error allocating new 'sn_info_t'"); 31 | return NULL; 32 | } 33 | 34 | sock_cpy(&sn->sock, sock); 35 | return sn; 36 | } 37 | 38 | 39 | sn_info_t *add_supernode_info(n2n_list_head_t *head, const n2n_sock_t *sock) 40 | { 41 | sn_info_t *sn = create_supernode_info(sock); 42 | if (sn != NULL) 43 | list_add(head, &sn->list); 44 | return sn; 45 | } 46 | 47 | 48 | sn_info_t *find_supernode_info(n2n_list_head_t *head, const n2n_sock_t *sock) 49 | { 50 | sn_info_t *scan = NULL; 51 | 52 | N2N_LIST_FOR_EACH(head, scan) 53 | { 54 | if (sock_equal(&scan->sock, sock) == 0) 55 | return scan; 56 | } 57 | return NULL; 58 | } 59 | 60 | 61 | n2n_list_node_t *read_supernode_info(FILE *f) 62 | { 63 | sn_info_t *sni = NULL; 64 | n2n_sock_t sock; 65 | n2n_sock_str_t sockbuf; 66 | 67 | if (fscanf(f, "%s\n", sockbuf) <= 0) 68 | return NULL; 69 | 70 | if (0 != str2sock(&sock, sockbuf)) 71 | { 72 | traceError("Invalid address: %s\n", sockbuf); 73 | return NULL; 74 | } 75 | 76 | sni = create_supernode_info(&sock); 77 | return (sni ? &sni->list : NULL); 78 | } 79 | 80 | 81 | void write_supernode_info(FILE *f, const void *entry) 82 | { 83 | const sn_info_t *sni = (const sn_info_t *) entry; 84 | n2n_sock_str_t sockbuf; 85 | 86 | if (fprintf(f, "%s\n", sock2str(sockbuf, &sni->sock)) < 0) 87 | { 88 | traceError("couldn't write supernode entry to file"); 89 | } 90 | } 91 | 92 | #if 0 93 | 94 | int update_supernodes(sn_list_t *supernodes, const n2n_sock_t *sn) 95 | { 96 | n2n_sock_str_t sock_str; 97 | struct sn_info *sni = sn_find(&supernodes->head, sn); 98 | 99 | if (sni) 100 | { 101 | /* existing supernode */ 102 | sni->timestamp = time(NULL); 103 | return 0; 104 | } 105 | 106 | if (add_new_supernode(&supernodes->head, sn) == NULL) 107 | return -1; 108 | 109 | traceDebug("Added supernode %s", sock2str(sock_str, sn)); 110 | return 1; 111 | } 112 | 113 | int update_and_save_supernodes(sn_list_t *supernodes, n2n_sock_t *sn_array, int sn_num) 114 | { 115 | int need_write = 0, i = 0; 116 | 117 | for (; i < sn_num; i++) 118 | { 119 | need_write += update_supernodes(supernodes, &sn_array[i]); 120 | } 121 | 122 | if (need_write) 123 | { 124 | /* elements added */ 125 | write_supernodes_to_file(supernodes->filename, &supernodes->head); 126 | } 127 | 128 | return need_write; 129 | } 130 | 131 | 132 | 133 | 134 | /******************************************************************* 135 | * Utils * 136 | *******************************************************************/ 137 | 138 | int sn_cmp(const n2n_sock_t *left, const n2n_sock_t *right) 139 | { 140 | if (left->family != right->family) 141 | return (left->family - right->family); 142 | else if (left->port != right->port) 143 | return (left->port - right->port); 144 | else if (left->family == AF_INET) 145 | return memcmp(left->addr.v4, right->addr.v4, IPV4_SIZE); 146 | 147 | return memcmp(left->addr.v6, right->addr.v6, IPV6_SIZE); 148 | } 149 | 150 | int sn_is_zero_addr(n2n_sock_t *sn) 151 | { 152 | int i = (sn->family == AF_INET ? (IPV4_SIZE - 1) : (IPV6_SIZE - 1)); 153 | 154 | for (; i >= 0; --i) 155 | { 156 | if (sn->addr.v6[i] != 0) 157 | return 0; 158 | } 159 | 160 | //return (*((unsigned int *) sn->addr.v4) == 0); 161 | return 1; 162 | } 163 | 164 | int sn_is_loopback(n2n_sock_t *sn, uint16_t local_port) 165 | { 166 | if (sn->family == AF_INET && 167 | sn->port == local_port && 168 | sn->addr.v4[0] == 127 && 169 | sn->addr.v4[1] == 0 && 170 | sn->addr.v4[2] == 0 && 171 | sn->addr.v4[3] == 1) 172 | { 173 | return 1; 174 | } 175 | 176 | return 0; 177 | } 178 | 179 | int sn_local_addr(int sock, n2n_sock_t *sn) 180 | { 181 | int retval = 0; 182 | struct sockaddr_in *sa = NULL; 183 | 184 | struct sockaddr addr; 185 | unsigned int addrlen = sizeof(struct sockaddr); 186 | retval += getsockname(sock, &addr, &addrlen); 187 | 188 | sa = (struct sockaddr_in *) &addr; 189 | sa->sin_port = ntohs(sa->sin_port); 190 | 191 | sock_cpy(sn, (n2n_sock_t *) sa); 192 | 193 | return retval; 194 | } 195 | 196 | #endif 197 | -------------------------------------------------------------------------------- /edge.h: -------------------------------------------------------------------------------- 1 | /* 2 | * edge.h 3 | * 4 | * Created on: Aug 22, 2013 5 | * Author: wolf 6 | */ 7 | 8 | #ifndef EDGE_H_ 9 | #define EDGE_H_ 10 | 11 | 12 | #include "n2n_net.h" 13 | #include "n2n_wire.h" 14 | #include "n2n_transforms.h" 15 | #include "n2n_list.h" 16 | #include "tuntap.h" 17 | #ifdef N2N_MULTIPLE_SUPERNODES 18 | # include "sn_multiple.h" 19 | #endif 20 | 21 | 22 | 23 | #if defined(DEBUG) 24 | #define SOCKET_TIMEOUT_INTERVAL_SECS 5 25 | #define REGISTER_SUPER_INTERVAL_DFL 20 /* sec */ 26 | #else /* #if defined(DEBUG) */ 27 | #define SOCKET_TIMEOUT_INTERVAL_SECS 10 28 | #define REGISTER_SUPER_INTERVAL_DFL 6 /*TODO 60 sec */ 29 | #endif /* #if defined(DEBUG) */ 30 | 31 | #define REGISTER_SUPER_INTERVAL_MIN 2 /* TODO 20 sec */ 32 | #define REGISTER_SUPER_INTERVAL_MAX 6 /* TODO 3600 sec */ 33 | 34 | #define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */ 35 | #define TRANSOP_TICK_INTERVAL (10) /* sec */ 36 | 37 | #define N2N_PATHNAME_MAXLEN 256 38 | #define N2N_MAX_TRANSFORMS 16 39 | #define N2N_EDGE_MGMT_PORT 5644 40 | 41 | 42 | 43 | /** Positions in the transop array where various transforms are stored. 44 | * 45 | * Used by transop_enum_to_index(). See also the transform enumerations in 46 | * n2n_transforms.h */ 47 | #define N2N_TRANSOP_NULL_IDX 0 48 | #define N2N_TRANSOP_TF_IDX 1 49 | #define N2N_TRANSOP_AESCBC_IDX 2 50 | /* etc. */ 51 | 52 | #define N2N_EDGE_SN_HOST_SIZE 48 53 | 54 | typedef char n2n_sn_name_t[N2N_EDGE_SN_HOST_SIZE]; 55 | 56 | #ifdef N2N_MULTIPLE_SUPERNODESx 57 | #define N2N_EDGE_NUM_SUPERNODES N2N_MAX_SN_PER_COMM 58 | #else 59 | #define N2N_EDGE_NUM_SUPERNODES 2 60 | #endif 61 | #define N2N_EDGE_SUP_ATTEMPTS 3 /* Number of failed attmpts before moving on to next supernode. */ 62 | 63 | 64 | 65 | struct sn_list_entry 66 | { 67 | n2n_list_node_t list; 68 | n2n_sock_t sock; 69 | }; 70 | 71 | typedef struct sn_list_entry sn_list_entry_t; 72 | 73 | 74 | 75 | /** Main structure type for edge. */ 76 | struct n2n_edge 77 | { 78 | int daemon; /**< Non-zero if edge should detach and run in the background. */ 79 | uint8_t re_resolve_supernode_ip; 80 | 81 | n2n_sock_t * supernode; 82 | 83 | size_t sn_idx; /**< Currently active supernode. */ 84 | size_t sn_num; /**< Number of supernode addresses defined. */ 85 | //n2n_sock_t supernodes[N2N_EDGE_NUM_SUPERNODES];//TODO 86 | n2n_list_head_t supernodes; 87 | 88 | int sn_wait; /**< Whether we are waiting for a supernode response. */ 89 | 90 | n2n_community_t community_name; /**< The community. 16 full octets. */ 91 | char keyschedule[N2N_PATHNAME_MAXLEN]; 92 | int null_transop; /**< Only allowed if no key sources defined. */ 93 | 94 | int udp_sock; 95 | int udp_mgmt_sock; /**< socket for status info. */ 96 | 97 | tuntap_dev_t device; /**< All about the TUNTAP device */ 98 | ip_mode_t ip_mode; /**< Interface IP address allocation mode (eg. static, DHCP). */ 99 | int allow_routing; /**< Accept packet no to interface address. */ 100 | int drop_multicast; /**< Multicast ethernet addresses. */ 101 | 102 | n2n_trans_op_t transop[N2N_MAX_TRANSFORMS]; /* one for each transform at fixed positions */ 103 | size_t tx_transop_idx; /**< The transop to use when encoding. */ 104 | 105 | n2n_list_head_t known_peers; /**< Edges we are connected to. */ 106 | n2n_list_head_t pending_peers; /**< Edges we have tried to register with. */ 107 | time_t last_register_req; /**< Check if time to re-register with super*/ 108 | size_t register_lifetime; /**< Time distance after last_register_req at which to re-register. */ 109 | time_t last_p2p; /**< Last time p2p traffic was received. */ 110 | time_t last_sup; /**< Last time a packet arrived from supernode. */ 111 | size_t sup_attempts; /**< Number of remaining attempts to this supernode. */ 112 | n2n_cookie_t last_cookie; /**< Cookie sent in last REGISTER_SUPER. */ 113 | 114 | time_t start_time; /**< For calculating uptime */ 115 | 116 | /* Statistics */ 117 | size_t tx_p2p; 118 | size_t rx_p2p; 119 | size_t tx_sup; 120 | size_t rx_sup; 121 | 122 | #ifdef N2N_MULTIPLE_SUPERNODES 123 | n2n_snm_state_t snm_state; 124 | n2n_list_head_t queried_supernodes; 125 | char snm_filename[N2N_PATHNAME_MAXLEN]; 126 | #endif 127 | }; 128 | 129 | typedef struct n2n_edge n2n_edge_t; 130 | 131 | 132 | 133 | int edge_init_keyschedule(n2n_edge_t *eee); 134 | 135 | 136 | 137 | #endif /* EDGE_H_ */ 138 | -------------------------------------------------------------------------------- /tuntap_netbsd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-09 - Luca Deri 3 | * (C) 2009 - Alaric Snell-Pym 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not see see 17 | */ 18 | 19 | #include "n2n.h" 20 | 21 | #ifdef __NetBSD__ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | void tun_close(tuntap_dev *device); 28 | 29 | /* ********************************** */ 30 | 31 | #define N2N_NETBSD_TAPDEVICE_SIZE 32 32 | int tuntap_open(tuntap_dev *device /* ignored */, 33 | char *dev, 34 | const char *address_mode, /* static or dhcp */ 35 | char *device_ip, 36 | char *device_mask, 37 | const char *device_mac, 38 | int mtu) 39 | { 40 | char tap_device[N2N_NETBSD_TAPDEVICE_SIZE]; 41 | struct ifreq req; 42 | 43 | if (dev) 44 | { 45 | snprintf(tap_device, sizeof(tap_device), "/dev/%s", dev); 46 | device->fd = open(tap_device, O_RDWR); 47 | snprintf(tap_device, sizeof(tap_device), "%s", dev); 48 | } 49 | else 50 | { 51 | device->fd = open("/dev/tap", O_RDWR); 52 | if (device->fd >= 0) 53 | { 54 | if (ioctl(device->fd, TAPGIFNAME, &req) == -1) 55 | { 56 | traceError("Unable to obtain name of tap device (%s)", strerror(errno)); 57 | close(device->fd); 58 | return (-1); 59 | } 60 | else 61 | { 62 | snprintf(tap_device, sizeof(tap_device), req.ifr_name); 63 | } 64 | } 65 | } 66 | 67 | if (device->fd < 0) 68 | { 69 | traceError("Unable to open tap device (%s)", strerror(errno)); 70 | return (-1); 71 | } 72 | else 73 | { 74 | char buf[256]; 75 | FILE *fd; 76 | 77 | traceNormal("Succesfully open %s", tap_device); 78 | 79 | device->ip_addr = inet_addr(device_ip); 80 | 81 | if (device_mac && device_mac[0] != '\0') 82 | { 83 | /* Set the hw address before bringing the if up. */ 84 | snprintf(buf, sizeof(buf), "ifconfig %s link %s active", 85 | tap_device, device_mac); 86 | system(buf); 87 | } 88 | 89 | snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s mtu %d up", 90 | tap_device, device_ip, device_mask, mtu); 91 | system(buf); 92 | 93 | traceNormal("Interface %s up and running (%s/%s)", 94 | tap_device, device_ip, device_mask); 95 | 96 | /* Read MAC address */ 97 | 98 | snprintf(buf, sizeof(buf), "ifconfig %s |grep address|cut -c 11-28", tap_device); 99 | /* traceInfo("%s", buf); */ 100 | 101 | fd = popen(buf, "r"); 102 | if (fd < 0) 103 | { 104 | tun_close(device); 105 | return (-1); 106 | } 107 | else 108 | { 109 | int a, b, c, d, e, f; 110 | 111 | buf[0] = 0; 112 | fgets(buf, sizeof(buf), fd); 113 | pclose(fd); 114 | 115 | if (buf[0] == '\0') 116 | { 117 | traceError("Unable to read %s interface MAC address", tap_device); 118 | exit(0); 119 | } 120 | 121 | traceNormal("Interface %s mac %s", tap_device, buf); 122 | if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) 123 | { 124 | device->mac_addr[0] = a, device->mac_addr[1] = b; 125 | device->mac_addr[2] = c, device->mac_addr[3] = d; 126 | device->mac_addr[4] = e, device->mac_addr[5] = f; 127 | } 128 | } 129 | } 130 | 131 | /* read_mac(dev, device->mac_addr); */ 132 | return (device->fd); 133 | } 134 | 135 | /* ********************************** */ 136 | 137 | int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) 138 | { 139 | return (read(tuntap->fd, buf, len)); 140 | } 141 | 142 | /* ********************************** */ 143 | 144 | int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) 145 | { 146 | return (write(tuntap->fd, buf, len)); 147 | } 148 | 149 | /* ********************************** */ 150 | 151 | void tuntap_close(struct tuntap_dev *tuntap) 152 | { 153 | close(tuntap->fd); 154 | } 155 | 156 | /* Fill out the ip_addr value from the interface. Called to pick up dynamic 157 | * address changes. */ 158 | void tuntap_get_address(struct tuntap_dev *tuntap) 159 | { 160 | } 161 | 162 | #endif /* #ifdef __NetBSD__ */ 163 | -------------------------------------------------------------------------------- /n2n.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-09 - Luca Deri 3 | * Richard Andrews 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, see 17 | * 18 | * Code contributions courtesy of: 19 | * Babak Farrokhi [FreeBSD port] 20 | * Lukasz Taczuk 21 | * 22 | */ 23 | 24 | #ifndef _N2N_H_ 25 | #define _N2N_H_ 26 | 27 | 28 | #if defined(__APPLE__) && defined(__MACH__) 29 | #define _DARWIN_ 30 | #endif 31 | 32 | 33 | /* Some capability defaults which can be reset for particular platforms. */ 34 | #define N2N_HAVE_DAEMON 1 35 | #define N2N_HAVE_SETUID 1 36 | /* #define N2N_CAN_NAME_IFACE */ 37 | 38 | /* Moved here to define _CRT_SECURE_NO_WARNINGS before all the including takes place */ 39 | #ifdef WIN32 40 | # include "win32/n2n_win32.h" 41 | # undef N2N_HAVE_DAEMON 42 | # undef N2N_HAVE_SETUID 43 | #endif 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | #ifndef _MSC_VER 54 | # include 55 | #endif /* #ifndef _MSC_VER */ 56 | 57 | #ifndef WIN32 58 | # include 59 | # include 60 | # include 61 | # include 62 | # ifdef __sun__ 63 | # include /* MIN() and MAX() declared here */ 64 | # undef N2N_HAVE_DAEMON 65 | # endif /* #ifdef __sun__ */ 66 | # include 67 | # include 68 | #endif /* #ifndef WIN32 */ 69 | 70 | #include "n2n_list.h" 71 | #include "n2n_wire.h" 72 | 73 | 74 | /****************************************************************************** 75 | * 76 | * MESSAGES 77 | * 78 | */ 79 | 80 | /* N2N packet header indicators. */ 81 | #define MSG_TYPE_REGISTER 1 82 | #define MSG_TYPE_DEREGISTER 2 83 | #define MSG_TYPE_PACKET 3 84 | #define MSG_TYPE_REGISTER_ACK 4 85 | #define MSG_TYPE_REGISTER_SUPER 5 86 | #define MSG_TYPE_REGISTER_SUPER_ACK 6 87 | #define MSG_TYPE_REGISTER_SUPER_NAK 7 88 | #define MSG_TYPE_FEDERATION 8 89 | #ifdef N2N_MULTIPLE_SUPERNODES 90 | # define MSG_TYPE_QUERY_SUPER 9 91 | # define MSG_TYPE_QUERY_SUPER_ACK 10 92 | #endif 93 | 94 | /* Functions */ 95 | extern char *msg_type2str(uint16_t msg_type); 96 | 97 | 98 | /****************************************************************************** 99 | * 100 | * COMPRESSION 101 | * 102 | */ 103 | 104 | #define QUICKLZ 1 105 | 106 | /* Set N2N_COMPRESSION_ENABLED to 0 to disable lzo1x compression of Ethernet 107 | * frames. Doing this will break compatibility with the standard n2n packet 108 | * format so do it only for experimentation. All edges must be built with the 109 | * same value if they are to understand each other. */ 110 | #define N2N_COMPRESSION_ENABLED 1 111 | 112 | 113 | /****************************************************************************** 114 | * 115 | * SUPERNODE INFORMATION 116 | * 117 | */ 118 | 119 | #define SUPERNODE_IP "127.0.0.1" 120 | #define SUPERNODE_PORT 1234 121 | 122 | 123 | /****************************************************************************** 124 | * 125 | * P2P INFORMATION 126 | * 127 | */ 128 | 129 | struct peer_info 130 | { 131 | n2n_list_node_t list; 132 | n2n_community_t community_name; 133 | n2n_mac_t mac_addr; 134 | n2n_sock_t sock; 135 | time_t last_seen; 136 | }; 137 | 138 | typedef struct peer_info peer_info_t; 139 | 140 | 141 | /* Operations on peer_info lists. */ 142 | void peer_list_add(n2n_list_head_t *peers, peer_info_t *info); 143 | size_t purge_peer_list(n2n_list_head_t *peers, time_t purge_before); 144 | size_t purge_expired_registrations(n2n_list_head_t *peers); 145 | 146 | /* Search functions */ 147 | peer_info_t *find_peer_by_mac(n2n_list_head_t *peers, const n2n_mac_t mac); 148 | peer_info_t *find_peer_by_mac_for_removal(n2n_list_head_t *peers, const n2n_mac_t mac, 149 | n2n_list_node_t **prev_node); 150 | 151 | peer_info_t *find_peer_by_community(n2n_list_head_t *peers, const n2n_community_t comm); 152 | 153 | 154 | 155 | static inline int community_equal(const n2n_community_t a, const n2n_community_t b) 156 | { 157 | return (0 == memcmp(a, b, sizeof(n2n_community_t))); 158 | } 159 | 160 | 161 | /****************************************************************************** 162 | * 163 | * N2N VERSION 164 | * 165 | */ 166 | 167 | /* version.c */ 168 | extern char *n2n_sw_version, *n2n_sw_osName, *n2n_sw_buildDate; 169 | 170 | 171 | void print_n2n_version(); 172 | 173 | 174 | #endif /* _N2N_H_ */ 175 | -------------------------------------------------------------------------------- /sn_multiple_wire.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sn_multiple_wire.h 3 | * 4 | * Created on: Mar 25, 2012 5 | * Author: Costin Lupu 6 | */ 7 | 8 | #ifndef SN_MULTIPLE_WIRE_H_ 9 | #define SN_MULTIPLE_WIRE_H_ 10 | 11 | #if defined(WIN32) 12 | #include "win32/n2n_win32.h" 13 | 14 | #if defined(__MINGW32__) 15 | #include 16 | #endif /* #ifdef __MINGW32__ */ 17 | 18 | #else /* #if defined(WIN32) */ 19 | #include 20 | #endif /* #if defined(WIN32) */ 21 | 22 | #include "n2n_wire.h" 23 | 24 | #define SNM_TYPE_REQ_LIST_MSG 0x01 25 | #define SNM_TYPE_RSP_LIST_MSG 0x02 26 | #define SNM_TYPE_ADV_MSG 0x03 27 | 28 | typedef struct snm_hdr 29 | { 30 | uint8_t type; 31 | uint8_t flags; 32 | uint16_t seq_num; 33 | } snm_hdr_t; 34 | 35 | #define IS_REQ_LIST(pMsg) ((pMsg)->hdr.type == SNM_TYPE_REQ_LIST_MSG) 36 | #define IS_RSP_LIST(pMsg) ((pMsg)->hdr.type == SNM_TYPE_RSP_LIST_MSG) 37 | #define IS_ADV_ME(pMsg) ((pMsg)->hdr.type == SNM_TYPE_ADV_MSG) 38 | 39 | /* 40 | * Flags (MSB order): 41 | * 0 1 2 3 4 5 6 7 42 | * +-+-+-+-+-+-+-+-+ 43 | * |S|C|N|A| rfu | 44 | * +-+-+-+-+-+-+-+-+ 45 | */ 46 | #define S_FLAG_POS 7 47 | #define C_FLAG_POS 6 48 | #define N_FLAG_POS 5 49 | #define A_FLAG_POS 4 50 | #define E_FLAG_POS 3 51 | 52 | #define __FLAG_MASK(pos) (1 << (pos)) 53 | #define __BIT_FLAG(flags, pos) (((flags) >> (pos)) & 1) 54 | 55 | #define SET_S(flags) (flags) |= __FLAG_MASK(S_FLAG_POS) 56 | #define SET_C(flags) (flags) |= __FLAG_MASK(C_FLAG_POS) 57 | #define SET_N(flags) (flags) |= __FLAG_MASK(N_FLAG_POS) 58 | #define SET_A(flags) (flags) |= __FLAG_MASK(A_FLAG_POS) 59 | #define SET_E(flags) (flags) |= __FLAG_MASK(E_FLAG_POS) 60 | 61 | #define GET_S(flags) __BIT_FLAG(flags, S_FLAG_POS) 62 | #define GET_C(flags) __BIT_FLAG(flags, C_FLAG_POS) 63 | #define GET_N(flags) __BIT_FLAG(flags, N_FLAG_POS) 64 | #define GET_A(flags) __BIT_FLAG(flags, A_FLAG_POS) 65 | #define GET_E(flags) __BIT_FLAG(flags, E_FLAG_POS) 66 | 67 | #define CLR_S(flags) (flags) &= ~__FLAG_MASK(S_FLAG_POS) 68 | #define CLR_C(flags) (flags) &= ~__FLAG_MASK(C_FLAG_POS) 69 | #define CLR_N(flags) (flags) &= ~__FLAG_MASK(N_FLAG_POS) 70 | #define CLR_A(flags) (flags) &= ~__FLAG_MASK(A_FLAG_POS) 71 | #define CLR_E(flags) (flags) &= ~__FLAG_MASK(E_FLAG_POS) 72 | 73 | typedef struct snm_comm_name 74 | { 75 | uint8_t size; 76 | n2n_community_t name; 77 | } snm_comm_name_t; 78 | 79 | typedef struct n2n_SNM_REQ_INFO 80 | { 81 | uint16_t comm_num; 82 | snm_comm_name_t *comm_ptr; 83 | } n2n_SNM_REQ_t; 84 | 85 | typedef struct n2n_SNM_INFO 86 | { 87 | uint16_t sn_num; 88 | uint16_t comm_num; 89 | n2n_sock_t *sn_ptr; 90 | snm_comm_name_t *comm_ptr; 91 | } n2n_SNM_INFO_t; 92 | 93 | typedef struct n2n_ADVERTISE_ME 94 | { 95 | n2n_sock_t sn; 96 | uint16_t comm_num; 97 | snm_comm_name_t *comm_ptr; 98 | } n2n_SNM_ADV_t; 99 | 100 | 101 | int alloc_communities( snm_comm_name_t **comm_ptr, unsigned int comm_num ); 102 | void free_communities( snm_comm_name_t **comm_ptr ); 103 | int alloc_supernodes( n2n_sock_t **sn_ptr, unsigned int sn_num ); 104 | void free_supernodes( n2n_sock_t **sn_ptr ); 105 | 106 | int encode_SNM_comm( uint8_t *base, 107 | size_t *idx, 108 | const snm_comm_name_t *comm_name ); 109 | int decode_SNM_comm( snm_comm_name_t *comm_name, 110 | const uint8_t *base, 111 | size_t *rem, 112 | size_t *idx ); 113 | 114 | int encode_SNM_hdr( uint8_t *base, 115 | size_t *idx, 116 | const snm_hdr_t *hdr ); 117 | 118 | int decode_SNM_hdr( snm_hdr_t *hdr, 119 | const uint8_t *base, 120 | size_t *rem, 121 | size_t *idx ); 122 | 123 | int encode_SNM_REQ( uint8_t *base, 124 | size_t *idx, 125 | const snm_hdr_t *hdr, 126 | const n2n_SNM_REQ_t *req ); 127 | 128 | int decode_SNM_REQ( n2n_SNM_REQ_t *pkt, 129 | const snm_hdr_t *hdr, 130 | const uint8_t *base, 131 | size_t *rem, 132 | size_t *idx ); 133 | 134 | int encode_SNM_INFO( uint8_t *base, 135 | size_t *idx, 136 | const snm_hdr_t *hdr, 137 | const n2n_SNM_INFO_t *rsp ); 138 | 139 | int decode_SNM_INFO( n2n_SNM_INFO_t *pkt, 140 | const snm_hdr_t *hdr, 141 | const uint8_t *base, 142 | size_t * rem, 143 | size_t * idx ); 144 | 145 | int encode_SNM_ADV( uint8_t *base, 146 | size_t *idx, 147 | const snm_hdr_t *hdr, 148 | const n2n_SNM_ADV_t *adv ); 149 | 150 | int decode_SNM_ADV( n2n_SNM_ADV_t *pkt, 151 | const snm_hdr_t *hdr, 152 | const uint8_t *base, 153 | size_t *rem, 154 | size_t *idx ); 155 | 156 | 157 | void log_SNM_hdr( const snm_hdr_t *hdr ); 158 | void log_SNM_REQ( const n2n_SNM_REQ_t *req ); 159 | void log_SNM_INFO( const n2n_SNM_INFO_t *info ); 160 | void log_SNM_ADV( const n2n_SNM_ADV_t *adv ); 161 | 162 | 163 | #endif /* SN_MULTIPLE_WIRE_H_ */ 164 | -------------------------------------------------------------------------------- /n2n_net.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-09 - Luca Deri 3 | * Richard Andrews 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, see 17 | * 18 | * Code contributions courtesy of: 19 | * Babak Farrokhi [FreeBSD port] 20 | * Lukasz Taczuk 21 | * 22 | */ 23 | 24 | #ifndef N2N_NET_H_ 25 | #define N2N_NET_H_ 26 | 27 | #ifdef WIN32 28 | # include "win32/n2n_win32.h" 29 | #else /* #ifdef WIN32 */ 30 | //#include //TODO ??? 31 | # include 32 | 33 | # ifdef __linux__ 34 | # include 35 | # endif /* #ifdef __linux__ */ 36 | 37 | # ifdef __FreeBSD__ 38 | # include 39 | # endif /* #ifdef __FreeBSD__ */ 40 | 41 | # include 42 | # include 43 | # include 44 | # include 45 | #endif /* #ifdef WIN32 */ 46 | 47 | #include 48 | 49 | 50 | 51 | /****************************************************************************** 52 | * 53 | * LAYER 2 54 | * 55 | */ 56 | 57 | #define ETH_ADDR_LEN 6 58 | 59 | #define N2N_MAC_SIZE ETH_ADDR_LEN 60 | #define N2N_MACSTR_SIZE 32 61 | 62 | 63 | typedef uint8_t n2n_mac_t[ETH_ADDR_LEN]; 64 | 65 | /** Common type used to hold stringified MAC addresses. */ 66 | typedef char macstr_t[N2N_MACSTR_SIZE]; 67 | 68 | /* 69 | * Structure of a 10Mb/s Ethernet header. 70 | */ 71 | struct ether_hdr 72 | { 73 | n2n_mac_t dhost; 74 | n2n_mac_t shost; 75 | uint16_t type; /* higher layer protocol encapsulated */ 76 | } PACKED; 77 | 78 | typedef struct ether_hdr ether_hdr_t; 79 | 80 | 81 | /* functions */ 82 | int is_empty_mac(const uint8_t *mac); 83 | int is_broadcast_mac(const uint8_t *mac); 84 | int is_ipv4_multicast_mac(const uint8_t *mac); 85 | int is_ipv6_multicast_mac(const uint8_t *mac); 86 | 87 | uint8_t is_multi_broadcast_mac(const uint8_t *dest_mac); 88 | 89 | static inline int mac_equal(const n2n_mac_t a, const n2n_mac_t b) 90 | { 91 | return (0 == memcmp(a, b, ETH_ADDR_LEN)); 92 | } 93 | 94 | char *mac2str(macstr_t buf, const n2n_mac_t mac); 95 | int str2mac(uint8_t *outmac /* 6 bytes */, const char *s); 96 | 97 | 98 | /****************************************************************************** 99 | * 100 | * LAYER 3 101 | * 102 | */ 103 | 104 | #define IPV4_SIZE 4 105 | #define IPV6_SIZE 16 106 | 107 | 108 | /** Common type used to hold stringified IP addresses. */ 109 | typedef char ipstr_t[32]; 110 | 111 | 112 | extern char *intoa(uint32_t addr, char *buf, uint16_t buf_len); 113 | const char *ipv4_to_str(char *buf, size_t buf_len, const uint8_t* ip); 114 | 115 | 116 | /****************************************************************************** 117 | * 118 | * LAYER 4 119 | * 120 | */ 121 | 122 | #define DEFAULT_MTU 1400 123 | #define N2N_SOCKBUF_SIZE 64 /* string representation of INET or INET6 sockets */ 124 | 125 | 126 | #ifndef WIN32 127 | #define closesocket(a) close(a) 128 | #define SOCKET int 129 | #endif /* #ifndef WIN32 */ 130 | 131 | 132 | struct n2n_sock 133 | { 134 | uint8_t family; /* AF_INET or AF_INET6; or 0 if invalid */ 135 | uint16_t port; /* host order TODO */ 136 | union 137 | { 138 | uint8_t v6[IPV6_SIZE]; /* byte sequence */ 139 | uint8_t v4[IPV4_SIZE]; /* byte sequence */ 140 | } addr; 141 | }; 142 | 143 | typedef struct n2n_sock n2n_sock_t; 144 | 145 | 146 | /* tracing string buffer */ 147 | typedef char n2n_sock_str_t[N2N_SOCKBUF_SIZE]; 148 | 149 | 150 | /* functions */ 151 | SOCKET open_socket(int local_port, int bind_any); 152 | 153 | ssize_t sendto_sock(int sock_fd, const void *pktbuf, size_t pktsize, const n2n_sock_t *dest); 154 | 155 | int is_empty_ip_address(const n2n_sock_t *sock); 156 | 157 | int sock_equal(const n2n_sock_t *a, const n2n_sock_t *b); 158 | 159 | char* sock2str(n2n_sock_str_t out, const n2n_sock_t *sock); 160 | n2n_sock_t* sock_from_cstr(n2n_sock_t *out, const n2n_sock_str_t str); 161 | 162 | int str2sock(n2n_sock_t *out, const n2n_sock_str_t str); 163 | 164 | void sock_cpy_addr(n2n_sock_t *dst, const n2n_sock_t *src); 165 | void sock_cpy(n2n_sock_t *dst, const n2n_sock_t *src); 166 | 167 | int sockaddr2sock(n2n_sock_t *out, const struct sockaddr_storage *sockaddr); 168 | int sock2sockaddr(struct sockaddr_storage *out, const n2n_sock_t *sock); 169 | 170 | 171 | /****************************************************************************** 172 | * 173 | * TUNNELING 174 | * 175 | */ 176 | 177 | enum ip_mode 178 | { 179 | N2N_IPM_NONE = 0, 180 | N2N_IPM_STATIC, 181 | N2N_IPM_DHCP 182 | }; 183 | 184 | typedef enum ip_mode ip_mode_t; 185 | 186 | 187 | /* functions */ 188 | int scan_address(uint32_t *ip_addr, ip_mode_t *ip_mode, const char *s); 189 | 190 | 191 | #endif /* N2N_NET_H_ */ 192 | -------------------------------------------------------------------------------- /n2n_list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * n2n_list.c 3 | * 4 | * Created on: Aug 31, 2012 5 | * Author: Costin Lupu 6 | */ 7 | 8 | #include "n2n.h" 9 | #include "n2n_list.h" 10 | #include "n2n_log.h" 11 | #include 12 | 13 | 14 | 15 | /** 16 | * Return the number of elements in the list. 17 | */ 18 | size_t list_size(const n2n_list_head_t *head) 19 | { 20 | size_t count = 0; 21 | const n2n_list_node_t *node = NULL; 22 | LIST_FOR_EACH_NODE(head, node) 23 | { 24 | ++count; 25 | } 26 | return count; 27 | } 28 | 29 | /** 30 | * Purge all items from the list and return the number 31 | * of items that were removed. 32 | */ 33 | size_t list_clear(n2n_list_head_t *head) 34 | { 35 | size_t count = 0; 36 | n2n_list_node_t *scan = NULL; 37 | n2n_list_node_t *next = NULL; 38 | 39 | LIST_FOR_EACH_NODE_SAFE(head, scan, next) 40 | { 41 | free(scan); /* free list entry */ 42 | ++count; 43 | } 44 | list_head_init(head); 45 | 46 | return count; 47 | } 48 | 49 | void list_reverse(n2n_list_head_t *head) 50 | { 51 | n2n_list_head_t aux = *head; 52 | n2n_list_node_t *scan = NULL; 53 | n2n_list_node_t *next = NULL; 54 | 55 | list_head_init(head); 56 | LIST_FOR_EACH_NODE_SAFE(&aux, scan, next) 57 | { 58 | list_add(head, scan); 59 | } 60 | } 61 | 62 | /** 63 | * Merge sort 64 | */ 65 | static void merge(n2n_list_node_t *left, size_t left_size, 66 | n2n_list_node_t *right, size_t right_size, 67 | n2n_list_head_t *merged, 68 | cmp_func_t cmp); 69 | 70 | static void merge_sort(n2n_list_head_t *head, size_t size, cmp_func_t func)//TODO may just sort first 'size' entries 71 | { 72 | size_t i, middle; 73 | LIST_HEAD(left); 74 | LIST_HEAD(right); 75 | LIST_HEAD(merged); 76 | n2n_list_node_t *left_last = NULL; 77 | 78 | if (size < 2) 79 | return; 80 | /* else list size is > 1, so split the list into two sublists */ 81 | 82 | middle = size / 2; 83 | 84 | LIST_FIRST_NODE(&left) = LIST_FIRST_NODE(head); 85 | for (i = 0, left_last = LIST_FIRST_NODE(head); i < middle - 1; i++) 86 | { 87 | left_last = left_last->next; 88 | } 89 | 90 | LIST_FIRST_NODE(&right) = left_last->next; 91 | left_last->next = NULL; 92 | 93 | merge_sort(&left, middle, func); 94 | merge_sort(&right, size - middle, func); 95 | merge(LIST_FIRST_NODE(&left), middle, LIST_FIRST_NODE(&right), size - middle, &merged, func); 96 | 97 | LIST_FIRST_NODE(head) = LIST_FIRST_NODE(&merged); 98 | } 99 | 100 | static void merge(n2n_list_node_t *left, size_t left_size, 101 | n2n_list_node_t *right, size_t right_size, 102 | n2n_list_head_t *merged, 103 | cmp_func_t cmp) 104 | { 105 | n2n_list_node_t *last_added = &merged->node; 106 | 107 | while (left_size > 0 && right_size > 0) 108 | { 109 | if (cmp(left, right) <= 0) 110 | { 111 | last_added->next = left; 112 | last_added = left; 113 | left = left->next; 114 | left_size--; 115 | } 116 | else 117 | { 118 | last_added->next = right; 119 | last_added = right; 120 | right = right->next; 121 | right_size--; 122 | } 123 | } 124 | 125 | if (left_size > 0) 126 | { 127 | last_added->next = left; 128 | } 129 | else if (right_size > 0) 130 | { 131 | last_added->next = right; 132 | } 133 | } 134 | 135 | void list_sort(n2n_list_head_t *head, cmp_func_t func) 136 | { 137 | size_t size = list_size(head); 138 | merge_sort(head, size, func); 139 | } 140 | 141 | /********************************************/ 142 | 143 | 144 | #include //TODO remove after fixing file open 145 | 146 | 147 | 148 | static FILE *open_list_file_for_read(const char *filename) 149 | { 150 | #if defined(WIN32) 151 | FILE *f = fopen(filename, "a+"); 152 | fseek(f, 0L, SEEK_SET); 153 | return f; 154 | #else//TODO remove 155 | int fd = open(filename, O_CREAT | O_RDONLY, 0666); 156 | if (fd < 0) 157 | return NULL; 158 | 159 | return fdopen(fd, "r"); 160 | #endif 161 | } 162 | 163 | int read_list_from_file(const char *filename, n2n_list_head_t *head, rd_entry_func_t rd_entry_func) 164 | { 165 | FILE *f = NULL; 166 | n2n_list_node_t *new_item = NULL; 167 | 168 | traceInfo("opening file %s for reading", filename); 169 | 170 | f = open_list_file_for_read(filename); 171 | if (!f) 172 | { 173 | traceError("couldn't open file. %s", strerror(errno)); 174 | return -1; 175 | } 176 | 177 | while ((new_item = rd_entry_func(f)) != NULL) 178 | { 179 | list_add(head, new_item); 180 | } 181 | 182 | list_reverse(head); 183 | 184 | fclose(f); 185 | return 0; 186 | 187 | out_err: 188 | list_clear(head); 189 | fclose(f); 190 | return -1; 191 | } 192 | 193 | int write_list_to_file(const char *filename, n2n_list_head_t *head, wr_entry_func_t wr_entry_func) 194 | { 195 | n2n_list_node_t *node; 196 | 197 | FILE *f = fopen(filename, "w"); 198 | if (!f) 199 | { 200 | traceError("couldn't open community file"); 201 | return -1; 202 | } 203 | 204 | LIST_FOR_EACH_NODE(head, node) 205 | { 206 | wr_entry_func(f, node); 207 | } 208 | 209 | fclose(f); 210 | return 0; 211 | 212 | out_err: 213 | fclose(f); 214 | return -1; 215 | } 216 | 217 | 218 | -------------------------------------------------------------------------------- /win32/getopt1.c: -------------------------------------------------------------------------------- 1 | /* getopt_long and getopt_long_only entry points for GNU getopt. 2 | Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 3 | Free Software Foundation, Inc. 4 | This file is part of the GNU C Library. 5 | 6 | The GNU C Library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Library General Public License as 8 | published by the Free Software Foundation; either version 2 of the 9 | License, or (at your option) any later version. 10 | 11 | The GNU C Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Library General Public License for more details. 15 | 16 | You should have received a copy of the GNU Library General Public 17 | License along with the GNU C Library; see the file COPYING.LIB. If not, 18 | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | Boston, MA 02111-1307, USA. */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include 23 | #endif 24 | 25 | #include "getopt.h" 26 | 27 | #if !defined __STDC__ || !__STDC__ 28 | /* This is a separate conditional since some stdc systems 29 | reject `defined (const)'. */ 30 | #ifndef const 31 | #define const 32 | #endif 33 | #endif 34 | 35 | #include 36 | 37 | /* Comment out all this code if we are using the GNU C Library, and are not 38 | actually compiling the library itself. This code is part of the GNU C 39 | Library, but also included in many other GNU distributions. Compiling 40 | and linking in this code is a waste when using the GNU C library 41 | (especially if it is a shared library). Rather than having every GNU 42 | program understand `configure --with-gnu-libc' and omit the object files, 43 | it is simpler to just do this in the source for each such file. */ 44 | 45 | #define GETOPT_INTERFACE_VERSION 2 46 | #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 47 | #include 48 | #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION 49 | #define ELIDE_CODE 50 | #endif 51 | #endif 52 | 53 | #ifndef ELIDE_CODE 54 | 55 | 56 | /* This needs to come after some library #include 57 | to get __GNU_LIBRARY__ defined. */ 58 | #ifdef __GNU_LIBRARY__ 59 | #include 60 | #endif 61 | 62 | #ifndef NULL 63 | #define NULL 0 64 | #endif 65 | 66 | int 67 | getopt_long (argc, argv, options, long_options, opt_index) 68 | int argc; 69 | char *const *argv; 70 | const char *options; 71 | const struct option *long_options; 72 | int *opt_index; 73 | { 74 | return _getopt_internal (argc, argv, options, long_options, opt_index, 0); 75 | } 76 | 77 | /* Like getopt_long, but '-' as well as '--' can indicate a long option. 78 | If an option that starts with '-' (not '--') doesn't match a long option, 79 | but does match a short option, it is parsed as a short option 80 | instead. */ 81 | 82 | int 83 | getopt_long_only (argc, argv, options, long_options, opt_index) 84 | int argc; 85 | char *const *argv; 86 | const char *options; 87 | const struct option *long_options; 88 | int *opt_index; 89 | { 90 | return _getopt_internal (argc, argv, options, long_options, opt_index, 1); 91 | } 92 | 93 | 94 | #endif /* Not ELIDE_CODE. */ 95 | 96 | #ifdef TEST 97 | 98 | #include 99 | 100 | int 101 | main (argc, argv) 102 | int argc; 103 | char **argv; 104 | { 105 | int c; 106 | int digit_optind = 0; 107 | 108 | while (1) 109 | { 110 | int this_option_optind = optind ? optind : 1; 111 | int option_index = 0; 112 | static struct option long_options[] = 113 | { 114 | {"add", 1, 0, 0}, 115 | {"append", 0, 0, 0}, 116 | {"delete", 1, 0, 0}, 117 | {"verbose", 0, 0, 0}, 118 | {"create", 0, 0, 0}, 119 | {"file", 1, 0, 0}, 120 | {0, 0, 0, 0} 121 | }; 122 | 123 | c = getopt_long (argc, argv, "abc:d:0123456789", 124 | long_options, &option_index); 125 | if (c == -1) 126 | break; 127 | 128 | switch (c) 129 | { 130 | case 0: 131 | printf ("option %s", long_options[option_index].name); 132 | if (optarg) 133 | printf (" with arg %s", optarg); 134 | printf ("\n"); 135 | break; 136 | 137 | case '0': 138 | case '1': 139 | case '2': 140 | case '3': 141 | case '4': 142 | case '5': 143 | case '6': 144 | case '7': 145 | case '8': 146 | case '9': 147 | if (digit_optind != 0 && digit_optind != this_option_optind) 148 | printf ("digits occur in two different argv-elements.\n"); 149 | digit_optind = this_option_optind; 150 | printf ("option %c\n", c); 151 | break; 152 | 153 | case 'a': 154 | printf ("option a\n"); 155 | break; 156 | 157 | case 'b': 158 | printf ("option b\n"); 159 | break; 160 | 161 | case 'c': 162 | printf ("option c with value `%s'\n", optarg); 163 | break; 164 | 165 | case 'd': 166 | printf ("option d with value `%s'\n", optarg); 167 | break; 168 | 169 | case '?': 170 | break; 171 | 172 | default: 173 | printf ("?? getopt returned character code 0%o ??\n", c); 174 | } 175 | } 176 | 177 | if (optind < argc) 178 | { 179 | printf ("non-option ARGV-elements: "); 180 | while (optind < argc) 181 | printf ("%s ", argv[optind++]); 182 | printf ("\n"); 183 | } 184 | 185 | exit (0); 186 | } 187 | 188 | #endif /* TEST */ 189 | -------------------------------------------------------------------------------- /n2n.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-09 - Luca Deri 3 | * Richard Andrews 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, see 17 | * 18 | * Code contributions courtesy of: 19 | * Massimo Torquati 20 | * Matt Gilg 21 | * 22 | */ 23 | 24 | #include "n2n.h" 25 | #include "n2n_log.h" 26 | #include "minilzo.h" 27 | #include 28 | 29 | 30 | #if defined(DEBUG) 31 | # define PURGE_REGISTRATION_FREQUENCY 60 32 | # define REGISTRATION_TIMEOUT 120 33 | #else /* #if defined(DEBUG) */ 34 | # define PURGE_REGISTRATION_FREQUENCY 60 35 | # define REGISTRATION_TIMEOUT (60*20) 36 | #endif /* #if defined(DEBUG) */ 37 | 38 | 39 | 40 | /****************************************************************************** 41 | * 42 | * MESSAGES 43 | * 44 | */ 45 | 46 | char *msg_type2str(uint16_t msg_type) 47 | { 48 | switch (msg_type) 49 | { 50 | case MSG_TYPE_REGISTER: return ("MSG_TYPE_REGISTER"); 51 | case MSG_TYPE_DEREGISTER: return ("MSG_TYPE_DEREGISTER"); 52 | case MSG_TYPE_PACKET: return ("MSG_TYPE_PACKET"); 53 | case MSG_TYPE_REGISTER_ACK: return ("MSG_TYPE_REGISTER_ACK"); 54 | case MSG_TYPE_REGISTER_SUPER: return ("MSG_TYPE_REGISTER_SUPER"); 55 | case MSG_TYPE_REGISTER_SUPER_ACK: return ("MSG_TYPE_REGISTER_SUPER_ACK"); 56 | case MSG_TYPE_REGISTER_SUPER_NAK: return ("MSG_TYPE_REGISTER_SUPER_NAK"); 57 | case MSG_TYPE_FEDERATION: return ("MSG_TYPE_FEDERATION"); 58 | default: return ("???"); 59 | } 60 | return ("???"); 61 | } 62 | 63 | 64 | /****************************************************************************** 65 | * 66 | * PEER INFORMATION 67 | * 68 | */ 69 | 70 | 71 | /** 72 | * Add info to the head of list. If list is NULL; create it. 73 | * 74 | * The item new is added to the head of the list. New is modified during 75 | * insertion. list takes ownership of new. 76 | */ 77 | void peer_list_add(n2n_list_head_t *peers, peer_info_t *info) 78 | { 79 | list_add(peers, &info->list); 80 | info->last_seen = time(NULL); 81 | } 82 | 83 | 84 | size_t purge_expired_registrations(n2n_list_head_t *peers) 85 | { 86 | static time_t last_purge = 0; 87 | time_t now = time(NULL); 88 | size_t num_reg = 0; 89 | 90 | if ((now - last_purge) < PURGE_REGISTRATION_FREQUENCY) 91 | return 0; 92 | 93 | traceInfo("Purging old registrations"); 94 | 95 | num_reg = purge_peer_list(peers, now - REGISTRATION_TIMEOUT); 96 | 97 | last_purge = now; 98 | traceInfo("Remove %ld registrations", num_reg); 99 | 100 | return num_reg; 101 | } 102 | 103 | 104 | /** 105 | * Purge old items from the peer_list and return the number of items that 106 | * were removed. 107 | */ 108 | size_t purge_peer_list(n2n_list_head_t *peers, time_t purge_before) 109 | { 110 | peer_info_t *scan = NULL; 111 | peer_info_t *prev = NULL; 112 | peer_info_t *next = NULL; 113 | size_t retval = 0; 114 | 115 | N2N_LIST_FOR_EACH_SAFE(peers, scan, next) 116 | { 117 | if (scan->last_seen < purge_before) 118 | { 119 | if (prev == NULL) 120 | { 121 | peers->node.next = &next->list; 122 | } 123 | else 124 | { 125 | prev->list.next = &next->list; 126 | } 127 | 128 | ++retval; 129 | free(scan); 130 | } 131 | else 132 | { 133 | prev = scan; 134 | } 135 | } 136 | 137 | return retval; 138 | } 139 | 140 | 141 | /** Find the peer entry in list with mac_addr equal to mac. 142 | * 143 | * Does not modify the list. 144 | * 145 | * @return NULL if not found; otherwise pointer to peer entry. 146 | */ 147 | peer_info_t *find_peer_by_mac(n2n_list_head_t *peers, const n2n_mac_t mac) 148 | { 149 | peer_info_t *peer = NULL; 150 | 151 | N2N_LIST_FOR_EACH(peers, peer) 152 | { 153 | if (mac_equal(mac, peer->mac_addr))//TODO 154 | return peer; 155 | } 156 | 157 | return NULL; 158 | } 159 | 160 | 161 | peer_info_t *find_peer_by_mac_for_removal(n2n_list_head_t *peers, const n2n_mac_t mac, 162 | n2n_list_node_t **prev_node) 163 | { 164 | peer_info_t *peer = NULL; 165 | 166 | *prev_node = &peers->node; 167 | N2N_LIST_FOR_EACH(peers, peer) 168 | { 169 | if (mac_equal(mac, peer->mac_addr))//TODO 170 | return peer; 171 | 172 | *prev_node = &peer->list; 173 | } 174 | 175 | *prev_node = NULL; 176 | return NULL; 177 | } 178 | 179 | peer_info_t *find_peer_by_community(n2n_list_head_t *peers, const n2n_community_t comm) 180 | { 181 | peer_info_t *peer = NULL; 182 | 183 | N2N_LIST_FOR_EACH(peers, peer) 184 | { 185 | if (community_equal(comm, peer->community_name))//TODO 186 | return peer; 187 | } 188 | 189 | return NULL; 190 | } 191 | 192 | 193 | /****************************************************************************** 194 | * 195 | * N2N VERSION 196 | * 197 | */ 198 | 199 | void print_n2n_version() 200 | { 201 | printf("Welcome to n2n v.%s for %s\n" 202 | "Built on %s\n" 203 | "Copyright 2007-09 - http://www.ntop.org\n\n", 204 | n2n_sw_version, n2n_sw_osName, n2n_sw_buildDate); 205 | } 206 | 207 | 208 | -------------------------------------------------------------------------------- /n2n_keyfile.c: -------------------------------------------------------------------------------- 1 | /* (c) 2009 Richard Andrews */ 2 | /* Contributions from: 3 | * - Jozef Kralik 4 | */ 5 | 6 | #include "n2n.h" 7 | #include "n2n_keyfile.h" 8 | #include "n2n_log.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | #ifdef WIN32 16 | char *strsep(char **ppsz_string, const char *psz_delimiters) 17 | { 18 | char *p; 19 | char *psz_string = *ppsz_string; 20 | if (!psz_string) 21 | return NULL; 22 | 23 | p = strpbrk(psz_string, psz_delimiters); 24 | if (!p) 25 | { 26 | *ppsz_string = NULL; 27 | return psz_string; 28 | } 29 | *p++ = '\0'; 30 | 31 | *ppsz_string = p; 32 | return psz_string; 33 | } 34 | #endif 35 | 36 | 37 | /* Parse hex nibbles in ascii until a non-nibble character is found. Nibble 38 | * characters are 0-9, a-f and A-F. 39 | * 40 | * Return number of bytes parsed into keyBuf or a negative error code. 41 | */ 42 | ssize_t n2n_parse_hex(uint8_t *keyBuf, 43 | size_t keyLen, 44 | const char *textKey, 45 | size_t textLen) 46 | { 47 | ssize_t retval = 0; 48 | uint8_t *pout = keyBuf; 49 | size_t octet = 0; 50 | const char *textEnd; 51 | const char *pbeg; 52 | 53 | textEnd = textKey + textLen; 54 | pbeg = textKey; 55 | 56 | while ((pbeg + 1 < textEnd) && (retval < (ssize_t) keyLen)) 57 | { 58 | if (1 != sscanf(pbeg, "%02x", (unsigned int*) &octet)) 59 | { 60 | retval = -1; 61 | break; 62 | } 63 | 64 | *pout = (octet & 0xff); 65 | ++pout; 66 | ++retval; 67 | pbeg += 2; 68 | } 69 | 70 | return retval; 71 | } 72 | 73 | 74 | static int parseKeyLine(n2n_cipherspec_t *spec, 75 | const char *linein) 76 | { 77 | /* parameters are separated by whitespace */ 78 | char line[N2N_KEYFILE_LINESIZE]; 79 | char *lp = line; 80 | const char *token; 81 | strncpy(line, linein, N2N_KEYFILE_LINESIZE); 82 | 83 | memset(spec, 0, sizeof(n2n_cipherspec_t)); 84 | 85 | /* decode valid_from time */ 86 | token = strsep(&lp, DELIMITERS); 87 | if (!token) 88 | { 89 | goto error; 90 | } 91 | spec->valid_from = atol(token); 92 | 93 | /* decode valid_until time */ 94 | token = strsep(&lp, DELIMITERS); 95 | if (!token) 96 | { 97 | goto error; 98 | } 99 | spec->valid_until = atol(token); 100 | 101 | /* decode the transform number */ 102 | token = strsep(&lp, DELIMITERS); 103 | if (!token) 104 | { 105 | goto error; 106 | } 107 | spec->t = atoi(token); 108 | 109 | /* The reset if opaque key data */ 110 | token = strsep(&lp, DELIMITERS); 111 | if (!token) 112 | { 113 | goto error; 114 | } 115 | strncpy((char *) spec->opaque, token, N2N_MAX_KEYSIZE); 116 | spec->opaque_size = strlen((char *) spec->opaque); 117 | 118 | return 0; 119 | 120 | error: return -1; 121 | } 122 | 123 | 124 | #define SEP "/" 125 | 126 | 127 | int validCipherSpec(const n2n_cipherspec_t *k, 128 | time_t now) 129 | { 130 | if (k->valid_until < k->valid_from) 131 | { 132 | goto bad; 133 | } 134 | if (k->valid_from > now) 135 | { 136 | goto bad; 137 | } 138 | if (k->valid_until < now) 139 | { 140 | goto bad; 141 | } 142 | 143 | return 0; 144 | 145 | bad: return -1; 146 | } 147 | 148 | /* Read key control file and return the number of specs stored or a negative 149 | * error code. 150 | * 151 | * As the specs are read in the from and until time values are compared to 152 | * present time. Only those keys which are valid are stored. 153 | */ 154 | int n2n_read_keyfile(n2n_cipherspec_t *specs, /* fill out this array of cipherspecs */ 155 | size_t numspecs, /* number of slots in the array. */ 156 | const char *ctrlfile_path) /* path to control file */ 157 | { 158 | /* Each line contains one cipherspec. */ 159 | 160 | int retval = 0; 161 | FILE *fp = NULL; 162 | size_t idx = 0; 163 | time_t now = time(NULL); 164 | 165 | traceDebug("Reading '%s'\n", ctrlfile_path); 166 | 167 | fp = fopen(ctrlfile_path, "r"); 168 | if (fp) 169 | { 170 | /* Read the file a line a time with fgets. */ 171 | char line[N2N_KEYFILE_LINESIZE]; 172 | size_t lineNum = 0; 173 | 174 | while (idx < numspecs) 175 | { 176 | n2n_cipherspec_t *k = &(specs[idx]); 177 | fgets(line, N2N_KEYFILE_LINESIZE, fp); 178 | ++lineNum; 179 | 180 | if (strlen(line) > 1) 181 | { 182 | if (0 == parseKeyLine(k, line)) 183 | { 184 | if (k->valid_until > now) 185 | { 186 | traceInfo(" --> [%u] from %lu, until %lu, transform=%hu, data=%s\n", 187 | idx, k->valid_from, k->valid_until, k->t, k->opaque); 188 | 189 | ++retval; 190 | ++idx; 191 | } 192 | else 193 | { 194 | traceInfo(" --X [%u] from %lu, until %lu, transform=%hu, data=%s\n", 195 | idx, k->valid_from, k->valid_until, k->t, k->opaque); 196 | 197 | } 198 | } 199 | else 200 | { 201 | traceWarning("Failed to decode line %u\n", lineNum); 202 | } 203 | } 204 | 205 | if (feof(fp)) 206 | { 207 | break; 208 | } 209 | 210 | line[0] = 0; /* this line has been consumed */ 211 | } 212 | 213 | fclose(fp); 214 | fp = NULL; 215 | } 216 | else 217 | { 218 | traceError("Failed to open '%s'\n", ctrlfile_path); 219 | retval = -1; 220 | } 221 | 222 | return retval; 223 | } 224 | -------------------------------------------------------------------------------- /edge_mgmt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * edge_mgmt.c 3 | * 4 | * Created on: Aug 22, 2013 5 | * Author: wolf 6 | */ 7 | 8 | #include "edge_mgmt.h" 9 | #include "n2n_log.h" 10 | #include 11 | 12 | 13 | #define CMD_STOP "stop" 14 | #define CMD_HELP "help" 15 | #define CMD_VERB_INC "+verb" 16 | #define CMD_VERB_DEC "-verb" 17 | #define CMD_RELOAD "reload" 18 | 19 | 20 | 21 | static size_t build_stats_response(n2n_edge_t *eee, uint8_t rsp_buf[]) 22 | { 23 | size_t msg_len = 0; 24 | time_t now = time(NULL); 25 | 26 | traceDebug("mgmt status rq"); 27 | 28 | msg_len += snprintf((char *) (rsp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), 29 | "Statistics for edge\n"); 30 | 31 | msg_len += snprintf((char *) (rsp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), 32 | "uptime %lu\n", 33 | time(NULL) - eee->start_time); 34 | 35 | msg_len += snprintf((char *) (rsp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), 36 | "paths super:%u,%u p2p:%u,%u\n", 37 | (unsigned int) eee->tx_sup, 38 | (unsigned int) eee->rx_sup, 39 | (unsigned int) eee->tx_p2p, 40 | (unsigned int) eee->rx_p2p); 41 | 42 | msg_len += snprintf((char *) (rsp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), 43 | "trans:null |%6u|%6u|\n" 44 | "trans:tf |%6u|%6u|\n" 45 | "trans:aes |%6u|%6u|\n", 46 | (unsigned int) eee->transop[N2N_TRANSOP_NULL_IDX].tx_cnt, 47 | (unsigned int) eee->transop[N2N_TRANSOP_NULL_IDX].rx_cnt, 48 | (unsigned int) eee->transop[N2N_TRANSOP_TF_IDX].tx_cnt, 49 | (unsigned int) eee->transop[N2N_TRANSOP_TF_IDX].rx_cnt, 50 | (unsigned int) eee->transop[N2N_TRANSOP_AESCBC_IDX].tx_cnt, 51 | (unsigned int) eee->transop[N2N_TRANSOP_AESCBC_IDX].rx_cnt); 52 | 53 | msg_len += snprintf((char *) (rsp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), 54 | "peers pend:%u full:%u\n", 55 | (unsigned int) list_size(&eee->pending_peers), 56 | (unsigned int) list_size(&eee->known_peers)); 57 | 58 | msg_len += snprintf((char *) (rsp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), 59 | "last super:%lu(%ld sec ago) p2p:%lu(%ld sec ago)\n", 60 | eee->last_sup, (now - eee->last_sup), eee->last_p2p, (now - eee->last_p2p)); 61 | 62 | return msg_len; 63 | } 64 | 65 | 66 | static size_t build_help_response(uint8_t rsp_buf[]) 67 | { 68 | size_t msg_len = 0; 69 | msg_len = snprintf((char *) rsp_buf, N2N_PKT_BUF_SIZE, 70 | "Help for edge management console:\n" 71 | " %7s Gracefully exit edge\n" 72 | " %7s This help message\n" 73 | " %7s Increase verbosity of logging\n" 74 | " %7s Decrease verbosity of logging\n" 75 | " %7s Re-read the keyschedule\n" 76 | " Display statistics\n\n", 77 | CMD_STOP, CMD_HELP, CMD_VERB_INC, CMD_VERB_DEC, CMD_RELOAD); 78 | return msg_len; 79 | } 80 | 81 | 82 | static size_t process_verb_inc_cmd(uint8_t rsp_buf[]) 83 | { 84 | size_t msg_len = 0; 85 | 86 | ++traceLevel; 87 | traceError("+verb traceLevel=%u", (unsigned int) traceLevel); 88 | 89 | msg_len += snprintf((char *) rsp_buf, N2N_PKT_BUF_SIZE, 90 | "> +OK traceLevel=%u\n", (unsigned int) traceLevel); 91 | return msg_len; 92 | } 93 | 94 | 95 | static size_t process_verb_dec_cmd(uint8_t rsp_buf[]) 96 | { 97 | size_t msg_len = 0; 98 | 99 | if (traceLevel > 0) 100 | { 101 | --traceLevel; 102 | msg_len += snprintf((char *) rsp_buf, N2N_PKT_BUF_SIZE, 103 | "> -OK traceLevel=%u\n", traceLevel); 104 | } 105 | else 106 | { 107 | msg_len += snprintf((char *) rsp_buf, N2N_PKT_BUF_SIZE, 108 | "> -NOK traceLevel=%u\n", traceLevel); 109 | } 110 | 111 | traceError("-verb traceLevel=%u", (unsigned int) traceLevel); 112 | return msg_len; 113 | } 114 | 115 | 116 | static size_t process_reload_cmd(n2n_edge_t *eee, uint8_t buf[]) 117 | { 118 | size_t msg_len = 0; 119 | 120 | if (strlen(eee->keyschedule) > 0) 121 | { 122 | if (edge_init_keyschedule(eee) == 0) 123 | { 124 | msg_len += snprintf((char *) buf, N2N_PKT_BUF_SIZE, "> OK\n"); 125 | } 126 | } 127 | 128 | return msg_len; 129 | } 130 | 131 | 132 | edge_cmd_t process_edge_mgmt(n2n_edge_t *eee, 133 | uint8_t req_buf[], ssize_t req_len, 134 | uint8_t rsp_buf[], size_t *rsp_len) 135 | { 136 | if (req_len >= 4) 137 | { 138 | if (0 == memcmp(req_buf, CMD_STOP, strlen(CMD_STOP))) 139 | { 140 | return EDGE_CMD_STOP; 141 | } 142 | 143 | if (0 == memcmp(req_buf, "help", 4)) 144 | { 145 | *rsp_len = build_help_response(rsp_buf); 146 | return EDGE_CMD_HELP; 147 | } 148 | 149 | } 150 | 151 | if (req_len >= 5) 152 | { 153 | if (0 == memcmp(req_buf, CMD_VERB_INC, strlen(CMD_VERB_INC))) 154 | { 155 | *rsp_len = process_verb_inc_cmd(rsp_buf); 156 | return EDGE_CMD_VERB_INC; 157 | } 158 | 159 | if (0 == memcmp(req_buf, CMD_VERB_DEC, strlen(CMD_VERB_DEC))) 160 | { 161 | *rsp_len = process_verb_dec_cmd(rsp_buf); 162 | return EDGE_CMD_VERB_DEC; 163 | } 164 | } 165 | 166 | if (req_len >= 6) 167 | { 168 | if (0 == memcmp(req_buf, CMD_RELOAD, strlen(CMD_RELOAD))) 169 | { 170 | *rsp_len = process_reload_cmd(eee, rsp_buf); 171 | return EDGE_CMD_RELOAD; 172 | } 173 | } 174 | 175 | *rsp_len = build_stats_response(eee, rsp_buf); 176 | return EDGE_CMD_STATS; 177 | } 178 | 179 | 180 | -------------------------------------------------------------------------------- /win32/DotNet/supernode.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 28 | 31 | 34 | 37 | 40 | 50 | 53 | 56 | 59 | 65 | 68 | 71 | 74 | 77 | 80 | 83 | 86 | 87 | 95 | 98 | 101 | 104 | 107 | 110 | 120 | 123 | 126 | 129 | 137 | 140 | 143 | 146 | 149 | 152 | 155 | 158 | 159 | 160 | 161 | 162 | 163 | 168 | 171 | 172 | 175 | 176 | 179 | 180 | 183 | 184 | 187 | 188 | 191 | 192 | 195 | 196 | 199 | 200 | 203 | 204 | 207 | 208 | 211 | 212 | 213 | 218 | 221 | 222 | 225 | 226 | 229 | 230 | 233 | 234 | 237 | 238 | 241 | 242 | 245 | 246 | 249 | 250 | 253 | 254 | 255 | 260 | 261 | 262 | 263 | 264 | 265 | -------------------------------------------------------------------------------- /tuntap_linux.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-09 - Luca Deri 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, see 16 | */ 17 | 18 | #include "n2n.h" 19 | #include "n2n_log.h" 20 | #include "tuntap.h" 21 | 22 | 23 | 24 | #ifdef __linux__ 25 | 26 | static void read_mac(char *ifname, n2n_mac_t mac_addr) 27 | { 28 | int _sock, res; 29 | struct ifreq ifr; 30 | macstr_t mac_addr_buf; 31 | 32 | memset(&ifr, 0, sizeof(struct ifreq)); 33 | 34 | /* Dummy socket, just to make ioctls with */ 35 | _sock = socket(PF_INET, SOCK_DGRAM, 0); 36 | strcpy(ifr.ifr_name, ifname); 37 | res = ioctl(_sock, SIOCGIFHWADDR, &ifr); 38 | if (res < 0) 39 | { 40 | perror("Get hw addr"); 41 | } 42 | else 43 | memcpy(mac_addr, ifr.ifr_ifru.ifru_hwaddr.sa_data, 6); 44 | 45 | traceNormal("Interface %s has MAC %s", 46 | ifname, 47 | mac2str(mac_addr_buf, mac_addr)); 48 | close(_sock); 49 | } 50 | 51 | /* ********************************** */ 52 | 53 | /** @brief Open and configure the TAP device for packet read/write. 54 | * 55 | * This routine creates the interface via the tuntap driver then uses ifconfig 56 | * to configure address/mask and MTU. 57 | * 58 | * @param device - [inout] a device info holder object 59 | * @param dev - user-defined name for the new iface, 60 | * if NULL system will assign a name 61 | * @param device_ip - address of iface 62 | * @param device_mask - netmask for device_ip 63 | * @param mtu - MTU for device_ip 64 | * 65 | * @return - negative value on error 66 | * - non-negative file-descriptor on success 67 | */ 68 | int tuntap_open(tuntap_dev_t *device, ip_mode_t ip_mode) 69 | //char *dev, /* user-definable interface name, eg. edge0 */ 70 | //const char *address_mode, /* static or dhcp */ 71 | //char *device_ip, 72 | //char *device_mask, 73 | //const char *device_mac, 74 | //int mtu) 75 | { 76 | char *tuntap_device = "/dev/net/tun"; 77 | #define N2N_LINUX_SYSTEMCMD_SIZE 128 78 | char buf[N2N_LINUX_SYSTEMCMD_SIZE]; 79 | struct ifreq ifr; 80 | int rc; 81 | 82 | //TODO 83 | ipstr_t ipstr; 84 | 85 | device->fd = open(tuntap_device, O_RDWR); 86 | if (device->fd < 0) 87 | { 88 | traceEvent(TRACE_ERROR, "Unable to open TUN/TAP device: ioctl() [%s][%d]\n", strerror(errno), errno); 89 | return -1; 90 | } 91 | 92 | traceEvent(TRACE_NORMAL, "Succesfully open %s\n", tuntap_device); 93 | memset(&ifr, 0, sizeof(ifr)); 94 | ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* Want a TAP device for layer 2 frames. */ 95 | strncpy(ifr.ifr_name, device->dev_name, IFNAMSIZ); 96 | rc = ioctl(device->fd, TUNSETIFF, (void *) &ifr); 97 | 98 | if (rc < 0) 99 | { 100 | traceError("ioctl() [%s][%d]\n", strerror(errno), rc); 101 | close(device->fd); 102 | return -1; 103 | } 104 | 105 | /* Store the device name for later reuse */ 106 | strncpy(device->dev_name, ifr.ifr_name, MIN(IFNAMSIZ, N2N_IFNAMSIZ)); 107 | 108 | if ( !is_empty_mac(device->mac_addr) ) 109 | { 110 | /* Set the hw address before bringing the if up. */ 111 | macstr_t macstr; 112 | snprintf(buf, sizeof(buf), "/sbin/ifconfig %s hw ether %s", 113 | ifr.ifr_name, mac2str(macstr, device->mac_addr)); 114 | system(buf); 115 | traceInfo("Setting MAC: %s", buf); 116 | } 117 | 118 | 119 | ipv4_to_str(ipstr, sizeof(ipstr_t), (const uint8_t *) &device->ip_addr);//TODO make array 120 | 121 | if (ip_mode == N2N_IPM_DHCP) 122 | { 123 | snprintf(buf, sizeof(buf), "/sbin/ifconfig %s %s mtu %d up", 124 | ifr.ifr_name, ipstr, device->mtu); 125 | } 126 | else 127 | { 128 | ipstr_t maskstr; 129 | strcpy((char *) maskstr, inet_ntoa( *( (struct in_addr *) &device->device_mask) ));//TODO 130 | //intoa(device->device_mask, maskstr, sizeof(maskstr)); 131 | 132 | snprintf(buf, sizeof(buf), "/sbin/ifconfig %s %s netmask %s mtu %d up", 133 | ifr.ifr_name, ipstr, maskstr, device->mtu); 134 | } 135 | 136 | traceInfo("Bringing up: %s", buf); 137 | system(buf); 138 | 139 | //device->ip_addr = inet_addr(device_ip); 140 | //device->device_mask = inet_addr(device_mask); 141 | read_mac(device->dev_name, device->mac_addr); 142 | return (device->fd); 143 | } 144 | 145 | int tuntap_read(tuntap_dev_t *device, unsigned char *buf, int len) 146 | { 147 | return (read(device->fd, buf, len)); 148 | } 149 | 150 | int tuntap_write(tuntap_dev_t *device, unsigned char *buf, int len) 151 | { 152 | return (write(device->fd, buf, len)); 153 | } 154 | 155 | void tuntap_close(tuntap_dev_t *device) 156 | { 157 | close(device->fd); 158 | } 159 | 160 | /* Fill out the ip_addr value from the interface. Called to pick up dynamic 161 | * address changes. */ 162 | void tuntap_get_address(tuntap_dev_t *device) 163 | { 164 | FILE *fp = NULL; 165 | ssize_t nread = 0; 166 | char buf[N2N_LINUX_SYSTEMCMD_SIZE]; 167 | 168 | /* Would rather have a more direct way to get the inet address but a netlink 169 | * socket is overkill and probably less portable than ifconfig and sed. */ 170 | 171 | /* If the interface has no address (0.0.0.0) there will be no inet addr 172 | * line and the returned string will be empty. */ 173 | snprintf(buf, sizeof(buf), 174 | "/sbin/ifconfig %s | /bin/sed -e '/inet addr:/!d' -e 's/^.*inet addr://' -e 's/ .*$//'", 175 | device->dev_name); 176 | fp = popen(buf, "r"); 177 | if (fp) 178 | { 179 | memset(buf, 0, N2N_LINUX_SYSTEMCMD_SIZE); /* make sure buf is NULL terminated. */ 180 | nread = fread(buf, 1, 15, fp); 181 | fclose(fp); 182 | fp = NULL; 183 | 184 | traceInfo("ifconfig address = %s", buf); 185 | 186 | device->ip_addr = inet_addr(buf); 187 | } 188 | } 189 | 190 | 191 | #endif /* #ifdef __linux__ */ 192 | -------------------------------------------------------------------------------- /n2n_v3.0: -------------------------------------------------------------------------------- 1 | .TH "n2n_v2" 7 "Sep 21, 2009" "revision 3909" "Background" 2 | .SH NAME 3 | N2n Version 2 \- version 2 of the n2n decentralised peer-to-peer network overlay 4 | VPN. 5 | .SH DESCRIPTION 6 | N2n is a peer-to-peer network overlay or VPN system that provides layer 2 over 7 | layer 3 encapsulation with data transform capabilities such as encryption and 8 | compression. This guide discusses the differences of version 2 or n2n from 9 | version 1. 10 | .SH PROTOCOLS 11 | N2n-2 uses a different set of messages to communicate with edges and 12 | supernodes. The n2n-2 messages are not compatible with n2n-1. There is no 13 | backward compatibility for n2n-1. 14 | .SH ENCRYPTION 15 | N2n-2 offers a new way of handling encryption compared to n2n-1. N2n-1 provided 16 | facility for a single community password with no expiration. In n2n-2 this 17 | method is preserved but a new mechanism has been added using a key schedule 18 | file. 19 | .TP 20 | Key Schedule 21 | A key schedule file lists a number of keys with the period for which each is 22 | valid along with the encryption type identifier and the actual key value. This 23 | allows the user to define up to 32 keys in advance with a pre-set time at which 24 | they keys will change. The key schedule file can be reloaded while the edge is 25 | running to allow new keys to be loaded and unused keys expunged. 26 | .TP 27 | Timing Requirements When a key rolls over to the next in the schedule, the new 28 | key is used for all transmitted packets; however any packets received using an 29 | older key can still be decoded as the keys from the key schedule are still 30 | known. As a result edges do not need to have accurate time synchronisation. The 31 | accuracy of required synchronisation depends to a large degree on the key 32 | schedule. Rapid key roll-overs requires more accurate time synchronisation. 33 | .P 34 | N2n-2 provides the following encryption ciphers; more can be added as required: 35 | .TP 36 | .B (1) NULL 37 | Data is encapsulated unchanged. Useful for testing and high-performance, low 38 | sensitivity applications. 39 | .TP 40 | .B (2) TF 41 | Twofish AES candidate. 42 | .P 43 | The following additional ciphers are specified but not yet implemented: 44 | .TP 45 | .B (3) AES-CBC 46 | AES in CBC mode with 256-bit key. 47 | .TP 48 | .B (4) LZO 49 | LZO compression of data (no encryption). 50 | .TP 51 | .B (5) TF-LZO 52 | TF cipher with LZO compression of data prior to encryption. 53 | .TP 54 | .B (6) AES-CBC-LZO 55 | AES-CBC ciper with LZO compression of data prior to encryption. 56 | 57 | .SH EXTENSIBILITY 58 | N2n-2 decouples the data transform system from the core of the edge 59 | operation. This allows for easier addition of new data transform 60 | operations. N2n-2 reserves 64 standard transform identifiers (such as TwoFish 61 | encryption) but allocates transform identifiers 64 - 65536 for user-defined 62 | transforms. This allows anyone to add to n2n new private transforms without 63 | breaking compatibility with the standard offering. 64 | 65 | .SH MULTIPLE SUPERNODES 66 | N2n-2 introduces the capability of multiple supernodes to be used by an 67 | edge. N2n-2 offers supernode in several flavours: 68 | .TP 69 | Stand-alone supernode 70 | 71 | This is the same concept as from n2n-1. Supernode is a small efficient C program 72 | which operates in isolation. 73 | .TP 74 | Federated supernodes 75 | 76 | This is a cluster of supernodes which share information. Edges registered to any 77 | of the cooperating supernodes can relay packets through the supernode federation 78 | and switch supernodes if required. Supernodes can send PACKET or REGISTER 79 | messages to other supernodes to try and find the destination edge. 80 | 81 | .P 82 | The n2n-2 edge implementation allows multiple supernodes to be specified on the 83 | command line. Edges monitor the current supernode for responses to 84 | REGISTER_SUPER messages. If 3 responses are missed then the edge starts looking 85 | for a new supernode. It cycles through the list of supernodes specified until it 86 | finds a working one. 87 | 88 | .SH EFFICIENCY 89 | The n2n-2 message formats have been made more efficient. The amount of data 90 | overhead has been reduced by ensuring the messages contain only the data fields 91 | required. Some optional fields do not consume data if they are not present. 92 | 93 | .SH DAEMON OPERATION 94 | The supernode and edge use daemon mode of operation by default. This sense is 95 | inverted from n2n-1 where they ran in the foreground by default. They can be 96 | made to run in the foreground so tools such a DJB's daemontools can work with 97 | them. See the 98 | .B -f 99 | option 100 | 101 | .SH MANAGEMENT CONSOLE 102 | Edge and supernode in n2n-2 provide a UDP-based management console. Both listen 103 | on the localhost address 127.0.0.1. Commands can be sent to the programs by 104 | sending to the UDP socket. Responses are returned to the socket from which 105 | commands were issued. This only works from the computer on which the programs 106 | are running. Statistics can be retrieved and commands issued. The netcat utility 107 | is all that is required; but more sophisticated tools could be built on the 108 | interface. 109 | 110 | .SH SUPERNODE AUTHENTICATION 111 | .B (To be implemented) 112 | Space has been reserved in the supernode registration messages for an 113 | authentication mechanism. 114 | 115 | .SH MESSAGE SUMMARY 116 | The following message types work within n2n-2. 117 | .TP 118 | REGISTER_SUPER 119 | Sent from an edge to its local supernode to register its MAC with the community. 120 | .TP 121 | REGISTER_SUPER_ACK 122 | Sent from a supernode to an edge to confirm registration. This also carries the 123 | definition of the edge socket as seen at the supernode so NAT can be detected 124 | and described. 125 | .TP 126 | REGISTER_SUPER_NAK 127 | Supernode refusing to register an edge. 128 | .TP 129 | PACKET 130 | Encapsulated ethernet packets sent between edges. Supernodes forward or 131 | broadcast these and edges send them direct in peer-to-peer mode. 132 | .TP 133 | REGISTER 134 | A peer-to-peer mode registration request from one edge to another. Supernodes 135 | forward these to facilitate NAT crossing introductions. 136 | .TP 137 | REGISTER_ACK 138 | Complete peer-to-peer mode setup between two edges. These messages need to 139 | travel direct between edges. 140 | .TP 141 | FEDERATION 142 | Federated supernodes exchanging community information. 143 | 144 | .SH OTHER DIFFERENCES 145 | .TP 146 | HTTP Tunneling 147 | This experimental feature (-t option in n2n_v1) of n2n_v1 has been removed 148 | entirely from n2n_v2. 149 | .SH AUTHORS 150 | .TP 151 | Richard Andrews andrews (at) ntop.org - main author of n2n-2 152 | .TP 153 | Luca Deri 154 | deri (at) ntop.org - code inherited from n2n-1 155 | .SH SEE ALSO 156 | ifconfig(8) edge(8) supernode(1) 157 | -------------------------------------------------------------------------------- /win32/getopt.h: -------------------------------------------------------------------------------- 1 | /* Declarations for getopt. 2 | Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | 5 | The GNU C Library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Library General Public License as 7 | published by the Free Software Foundation; either version 2 of the 8 | License, or (at your option) any later version. 9 | 10 | The GNU C Library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Library General Public License for more details. 14 | 15 | You should have received a copy of the GNU Library General Public 16 | License along with the GNU C Library; see the file COPYING.LIB. If not, 17 | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 | Boston, MA 02111-1307, USA. */ 19 | 20 | #ifndef _GETOPT_H 21 | 22 | #ifndef __need_getopt 23 | # define _GETOPT_H 1 24 | #endif 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* For communication from `getopt' to the caller. 31 | When `getopt' finds an option that takes an argument, 32 | the argument value is returned here. 33 | Also, when `ordering' is RETURN_IN_ORDER, 34 | each non-option ARGV-element is returned here. */ 35 | 36 | extern char *optarg; 37 | 38 | /* Index in ARGV of the next element to be scanned. 39 | This is used for communication to and from the caller 40 | and for communication between successive calls to `getopt'. 41 | 42 | On entry to `getopt', zero means this is the first call; initialize. 43 | 44 | When `getopt' returns -1, this is the index of the first of the 45 | non-option elements that the caller should itself scan. 46 | 47 | Otherwise, `optind' communicates from one call to the next 48 | how much of ARGV has been scanned so far. */ 49 | 50 | extern int optind; 51 | 52 | /* Callers store zero here to inhibit the error message `getopt' prints 53 | for unrecognized options. */ 54 | 55 | extern int opterr; 56 | 57 | /* Set to an option character which was unrecognized. */ 58 | 59 | extern int optopt; 60 | 61 | #ifndef __need_getopt 62 | /* Describe the long-named options requested by the application. 63 | The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector 64 | of `struct option' terminated by an element containing a name which is 65 | zero. 66 | 67 | The field `has_arg' is: 68 | no_argument (or 0) if the option does not take an argument, 69 | required_argument (or 1) if the option requires an argument, 70 | optional_argument (or 2) if the option takes an optional argument. 71 | 72 | If the field `flag' is not NULL, it points to a variable that is set 73 | to the value given in the field `val' when the option is found, but 74 | left unchanged if the option is not found. 75 | 76 | To have a long-named option do something other than set an `int' to 77 | a compiled-in constant, such as set a value from `optarg', set the 78 | option's `flag' field to zero and its `val' field to a nonzero 79 | value (the equivalent single-letter option character, if there is 80 | one). For long options that have a zero `flag' field, `getopt' 81 | returns the contents of the `val' field. */ 82 | 83 | struct option 84 | { 85 | # if defined __STDC__ && __STDC__ 86 | const char *name; 87 | # else 88 | char *name; 89 | # endif 90 | /* has_arg can't be an enum because some compilers complain about 91 | type mismatches in all the code that assumes it is an int. */ 92 | int has_arg; 93 | int *flag; 94 | int val; 95 | }; 96 | 97 | /* Names for the values of the `has_arg' field of `struct option'. */ 98 | 99 | # define no_argument 0 100 | # define required_argument 1 101 | # define optional_argument 2 102 | #endif /* need getopt */ 103 | 104 | 105 | /* Get definitions and prototypes for functions to process the 106 | arguments in ARGV (ARGC of them, minus the program name) for 107 | options given in OPTS. 108 | 109 | Return the option character from OPTS just read. Return -1 when 110 | there are no more options. For unrecognized options, or options 111 | missing arguments, `optopt' is set to the option letter, and '?' is 112 | returned. 113 | 114 | The OPTS string is a list of characters which are recognized option 115 | letters, optionally followed by colons, specifying that that letter 116 | takes an argument, to be placed in `optarg'. 117 | 118 | If a letter in OPTS is followed by two colons, its argument is 119 | optional. This behavior is specific to the GNU `getopt'. 120 | 121 | The argument `--' causes premature termination of argument 122 | scanning, explicitly telling `getopt' that there are no more 123 | options. 124 | 125 | If OPTS begins with `--', then non-option arguments are treated as 126 | arguments to the option '\0'. This behavior is specific to the GNU 127 | `getopt'. */ 128 | 129 | #if defined __STDC__ && __STDC__ 130 | # ifdef __GNU_LIBRARY__ 131 | /* Many other libraries have conflicting prototypes for getopt, with 132 | differences in the consts, in stdlib.h. To avoid compilation 133 | errors, only prototype getopt for the GNU C library. */ 134 | extern int getopt (int __argc, char *const *__argv, const char *__shortopts); 135 | # else /* not __GNU_LIBRARY__ */ 136 | extern int getopt (); 137 | # endif /* __GNU_LIBRARY__ */ 138 | 139 | # ifndef __need_getopt 140 | extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, 141 | const struct option *__longopts, int *__longind); 142 | extern int getopt_long_only (int __argc, char *const *__argv, 143 | const char *__shortopts, 144 | const struct option *__longopts, int *__longind); 145 | 146 | /* Internal only. Users should not call this directly. */ 147 | extern int _getopt_internal (int __argc, char *const *__argv, 148 | const char *__shortopts, 149 | const struct option *__longopts, int *__longind, 150 | int __long_only); 151 | # endif 152 | #else /* not __STDC__ */ 153 | extern int getopt (); 154 | # ifndef __need_getopt 155 | extern int getopt_long (); 156 | extern int getopt_long_only (); 157 | 158 | extern int _getopt_internal (); 159 | # endif 160 | #endif /* __STDC__ */ 161 | 162 | #ifdef __cplusplus 163 | } 164 | #endif 165 | 166 | /* Make sure we later can get all the definitions and declarations. */ 167 | #undef __need_getopt 168 | 169 | #endif /* getopt.h */ 170 | -------------------------------------------------------------------------------- /n2n_utils.c: -------------------------------------------------------------------------------- 1 | /** 2 | * (C) 2007-09 - Luca Deri 3 | * Richard Andrews 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not see see 17 | * 18 | */ 19 | 20 | #include "n2n_utils.h" 21 | #include "n2n_log.h" 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | 29 | /* parse the configuration file */ 30 | static int readConfFile(const char *filename, char * const linebuffer) 31 | { 32 | struct stat stats; 33 | FILE *fd; 34 | char *buffer = NULL; 35 | 36 | buffer = (char *) malloc(MAX_CONFFILE_LINE_LENGTH); 37 | if (!buffer) 38 | { 39 | traceError("Unable to allocate memory"); 40 | return -1; 41 | } 42 | 43 | if (stat(filename, &stats)) 44 | { 45 | if (errno == ENOENT) 46 | traceError("parameter file %s not found/unable to access\n", filename); 47 | else 48 | traceError("cannot stat file %s, errno=%d\n", filename, errno); 49 | free(buffer); 50 | return -1; 51 | } 52 | 53 | fd = fopen(filename, "rb"); 54 | if (!fd) 55 | { 56 | traceError("Unable to open parameter file '%s' (%d)...\n", filename, errno); 57 | free(buffer); 58 | return -1; 59 | } 60 | while (fgets(buffer, MAX_CONFFILE_LINE_LENGTH, fd)) 61 | { 62 | char *p = NULL; 63 | 64 | /* strip out comments */ 65 | p = strchr(buffer, '#'); 66 | if (p) 67 | *p = '\0'; 68 | 69 | /* remove \n */ 70 | p = strchr(buffer, '\n'); 71 | if (p) 72 | *p = '\0'; 73 | 74 | /* strip out heading spaces */ 75 | p = buffer; 76 | while (*p == ' ' && *p != '\0') 77 | ++p; 78 | if (p != buffer) 79 | strncpy(buffer, p, strlen(p) + 1); 80 | 81 | /* strip out trailing spaces */ 82 | while (strlen(buffer) && buffer[strlen(buffer) - 1] == ' ') 83 | buffer[strlen(buffer) - 1] = '\0'; 84 | 85 | /* check for nested @file option */ 86 | if (strchr(buffer, '@')) 87 | { 88 | traceError("@file in file nesting is not supported\n"); 89 | free(buffer); 90 | return -1; 91 | } 92 | if ((strlen(linebuffer) + strlen(buffer) + 2) < MAX_CMDLINE_BUFFER_LENGTH) 93 | { 94 | strncat(linebuffer, " ", 1); 95 | strncat(linebuffer, buffer, strlen(buffer)); 96 | } 97 | else 98 | { 99 | traceError("too many argument"); 100 | free(buffer); 101 | return -1; 102 | } 103 | } 104 | 105 | free(buffer); 106 | fclose(fd); 107 | 108 | return 0; 109 | } 110 | 111 | /* Create the argv vector */ 112 | static void buildargv(const char * const linebuffer, effective_args_t *effective_args) 113 | { 114 | const int INITIAL_MAXARGC = 16; /* Number of args + NULL in initial argv */ 115 | int maxargc; 116 | int argc = 0; 117 | char **argv; 118 | char *buffer, *buff; 119 | 120 | buffer = (char *) calloc(1, strlen(linebuffer) + 2); 121 | if (!buffer) 122 | { 123 | traceError("Unable to allocate memory"); 124 | exit(1); 125 | } 126 | strncpy(buffer, linebuffer, strlen(linebuffer)); 127 | 128 | maxargc = INITIAL_MAXARGC; 129 | argv = (char **) malloc(maxargc * sizeof(char*)); 130 | if (argv == NULL) 131 | { 132 | traceError("Unable to allocate memory"); 133 | exit(1); 134 | } 135 | buff = buffer; 136 | while (buff) 137 | { 138 | char *p = strchr(buff, ' '); 139 | if (p) 140 | { 141 | *p = '\0'; 142 | argv[argc++] = strdup(buff); 143 | while (*++p == ' ' && *p != '\0') 144 | ; 145 | buff = p; 146 | if (argc >= maxargc) 147 | { 148 | maxargc *= 2; 149 | argv = (char **) realloc(argv, maxargc * sizeof(char*)); 150 | if (argv == NULL) 151 | { 152 | traceError("Unable to re-allocate memory"); 153 | free(buffer); 154 | exit(1); 155 | } 156 | } 157 | } 158 | else 159 | { 160 | argv[argc++] = strdup(buff); 161 | break; 162 | } 163 | } 164 | free(buffer); 165 | 166 | effective_args->argc = argc; 167 | effective_args->argv = argv; 168 | } 169 | 170 | void build_effective_args(int argc, char *argv[], effective_args_t *effective_args) 171 | { 172 | int i; 173 | 174 | char *linebuffer = (char *) malloc(MAX_CMDLINE_BUFFER_LENGTH); 175 | if (!linebuffer) 176 | { 177 | traceError("Unable to allocate memory"); 178 | exit(1); 179 | } 180 | 181 | snprintf(linebuffer, MAX_CMDLINE_BUFFER_LENGTH, "%s", argv[0]); 182 | 183 | #ifdef WIN32 184 | for (i = 0; i < (int) strlen(linebuffer); i++) 185 | if (linebuffer[i] == '\\') 186 | linebuffer[i] = '/'; 187 | #endif 188 | 189 | for (i = 1; i < argc; ++i) 190 | { 191 | if (argv[i][0] == '@') 192 | { 193 | if (readConfFile(&argv[i][1], linebuffer) < 0) 194 | exit(1); /* <<<<----- check */ 195 | } 196 | else if ((strlen(linebuffer) + strlen(argv[i]) + 2) < MAX_CMDLINE_BUFFER_LENGTH) 197 | { 198 | strncat(linebuffer, " ", 1); 199 | strncat(linebuffer, argv[i], strlen(argv[i])); 200 | } 201 | else 202 | { 203 | traceError("too many argument"); 204 | exit(1); 205 | } 206 | } 207 | /* strip trailing spaces */ 208 | while (strlen(linebuffer) && linebuffer[ strlen(linebuffer) - 1 ] == ' ') 209 | linebuffer[ strlen(linebuffer) - 1 ] = '\0'; 210 | 211 | /* build the new argv from the linebuffer */ 212 | buildargv(linebuffer, effective_args); 213 | 214 | if (linebuffer) 215 | { 216 | free(linebuffer); 217 | linebuffer = NULL; 218 | } 219 | 220 | /* {int k;for(k=0;kargc; ++i) 227 | { 228 | free(effective_args->argv[i]); 229 | } 230 | free(effective_args->argv); 231 | effective_args->argv = NULL; 232 | effective_args->argc = 0; 233 | } 234 | 235 | /* *********************************************** */ 236 | 237 | void hexdump(const uint8_t *buf, size_t len) 238 | { 239 | size_t i; 240 | 241 | if (0 == len) 242 | return; 243 | 244 | for (i = 0; i < len; i++) 245 | { 246 | if ((i > 0) && ((i % 16) == 0)) 247 | printf("\n"); 248 | 249 | printf("%02X ", buf[i] & 0xFF); 250 | } 251 | 252 | printf("\n"); 253 | } 254 | 255 | 256 | -------------------------------------------------------------------------------- /win32/DotNet/n2n.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 26 | 29 | 32 | 35 | 38 | 41 | 54 | 57 | 60 | 63 | 73 | 76 | 79 | 82 | 85 | 88 | 91 | 94 | 95 | 103 | 106 | 109 | 112 | 115 | 118 | 128 | 131 | 134 | 137 | 149 | 152 | 155 | 158 | 161 | 164 | 167 | 170 | 171 | 172 | 173 | 174 | 175 | 180 | 183 | 184 | 187 | 188 | 191 | 192 | 195 | 196 | 199 | 200 | 203 | 204 | 207 | 208 | 211 | 212 | 215 | 216 | 219 | 220 | 223 | 224 | 227 | 228 | 231 | 232 | 235 | 236 | 239 | 240 | 243 | 244 | 247 | 248 | 251 | 252 | 253 | 258 | 261 | 262 | 265 | 266 | 269 | 270 | 273 | 274 | 277 | 278 | 281 | 282 | 285 | 286 | 289 | 290 | 293 | 294 | 297 | 298 | 301 | 302 | 305 | 306 | 309 | 310 | 313 | 314 | 317 | 318 | 321 | 322 | 325 | 326 | 329 | 330 | 331 | 336 | 337 | 340 | 341 | 344 | 345 | 346 | 347 | 348 | 349 | -------------------------------------------------------------------------------- /edge.8: -------------------------------------------------------------------------------- 1 | .TH edge 8 "17 Mar 2010" "n2n-2.1" "SUPERUSER COMMANDS" 2 | .SH NAME 3 | edge \- n2n edge node daemon 4 | .SH SYNOPSIS 5 | .B edge 6 | [\-d ] \-a \-c {\-k |\-K } 7 | [\-s ] \-l 8 | [\-p ] [\-u ] [\-g ] [-f] [\-m ] [\-r] [\-v] 9 | .SH DESCRIPTION 10 | N2N is a peer-to-peer VPN system. Edge is the edge node daemon for n2n which 11 | creates a TAP interface to expose the n2n virtual LAN. On startup n2n creates 12 | the TAP interface and configures it then registers with the supernode so it can 13 | begin to find other nodes in the community. 14 | .PP 15 | .SH OPTIONS 16 | .TP 17 | \-d 18 | sets the TAP device name as seen in ifconfig. Only available on Linux. 19 | .TP 20 | \-a {|static:|dhcp:0.0.0.0} 21 | sets the n2n virtual LAN IP address being claimed. This is a private IP 22 | address. All IP addresses in an n2n community typical belong to the same /24 23 | network (ie. only the last octet of the IP addresses varies). If DHCP is used to 24 | assign interface addresses then specify the address as 25 | .B -a dhcp:0.0.0.0 26 | .TP 27 | \-b 28 | cause edge to perform hostname resolution for the supernode address each time 29 | the supernode is periodically contacted. This can cause reliability problems 30 | because all packet processing stops while the supernode address is resolved 31 | which might take 15 seconds. 32 | .TP 33 | \-c 34 | sets the n2n community name. All edges within the same community appear on the 35 | same LAN (layer 2 network segment). Community name is 16 bytes in length. A name 36 | smaller than this is padded with 0x00 bytes and a name longer than this is 37 | truncated to take the first 16 bytes. 38 | .TP 39 | \-h 40 | write usage then exit. 41 | .TP 42 | \-k 43 | sets the twofish encryption key from ASCII text (see also N2N_KEY in 44 | ENVIRONMENT). All edges communicating must use the same key and community 45 | name. If neither -k nor -K is used to specify a key source then edge uses 46 | cleartext mode (no encryption). The -k and -K options are mutually exclusive. 47 | .TP 48 | \-K 49 | Reads a key-schedule file and populates the internal transform 50 | operations with the data found there. This mechanism allows keys to roll at 51 | pre-determined times for a group of hosts. Accurate time synchronisation is not 52 | required as older keys can be decoded for some time after expiry. If neither -k 53 | nor -K is used to specify a key source then edge uses cleartext mode (no 54 | encryption). The -k and -K options are mutually exclusive. 55 | .TP 56 | \-l : 57 | sets the n2n supernode IP address and port to register to. Up to 2 supernodes 58 | can be specified by two invocations of -l :. eg. 59 | .B edge -l 12.34.56.78:7654 -l 98.76.54.32:7654 60 | . 61 | .TP 62 | \-p 63 | binds edge to the given UDP port. Useful for keeping the same external socket 64 | across restarts of edge. This allows peer edges which know the edge socket to 65 | continue p2p operation without going back to the supernode. 66 | .TP 67 | \-t 68 | binds the edge management system to the given UDP port. Default 5644. Use this 69 | if you need to run multiple instance of edge; or something is bound to that 70 | port. 71 | .TP 72 | \-u 73 | causes the edge process to drop to the given user ID when privileges are no 74 | longer required (UNIX). 75 | .TP 76 | \-g 77 | causes the edge process to drop to the given group ID when privileges are no 78 | longer required (UNIX). 79 | .TP 80 | \-f 81 | disables daemon mode (UNIX) and causes edge to run in the foreground. 82 | .TP 83 | \-m 84 | start the TAP interface with the given MAC address. This is highly recommended 85 | as it means the same address will be used if edge stops and restarts. If this is 86 | not done, the ARP caches of all peers will be wrong and packets will not flow to 87 | this edge until the next ARP refresh. 88 | .TP 89 | \-M 90 | set the MTU of the edge interface in bytes. MTU is the largest packet fragment 91 | size allowed to be moved throught the interface. The default is 1400. 92 | .TP 93 | \-s 94 | set the netmask of edge interface in IPv4 dotted decimal notation. The default 95 | is 255.255.255.0 (ie. /24). 96 | .TP 97 | \-r 98 | enable IP packet forwarding/routing through the n2n virtual LAN. Without this 99 | option, IP packets arriving over n2n are dropped if not for the -a (or 100 | DHCP assigned) IP address of the edge interface. 101 | .TP 102 | \-E 103 | accept packets destined for multicast ethernet MAC addresses. These addresses 104 | are used in multicast ethernet and IPv6 neighbour discovery. If this option is 105 | not present these multicast packets are discarded as most users do not need or 106 | understand them. 107 | .TP 108 | \-v 109 | more verbose logging (may be specified several times for more verbosity). 110 | .SH ENVIRONMENT 111 | .TP 112 | .B N2N_KEY 113 | set the encryption key so it is not visible on the command line 114 | .SH EXAMPLES 115 | .TP 116 | .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 117 | 118 | Start edge with TAP device n2n0 on community "mynetwork" with community 119 | supernode at 123.121.120.119 UDP port 7654 and bind the locally used UDP port to 120 | 50001. Use "encryptme" as the single permanent shared encryption key. Assign MAC 121 | address DE:AD:BE:EF:01:23 to the n2n interface and drop to user=99 and group=99 122 | after the TAP device is successfull configured. 123 | .PP 124 | Add the -f option to stop edge running as a daemon. 125 | .PP 126 | Somewhere else setup another edge with similar parameters, eg. 127 | 128 | .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 129 | .PP 130 | Now you can ping from 192.168.254.5 to 192.168.254.7. 131 | .PP 132 | The MAC address (-m ) and virtual IP address (-a ) must be different 133 | on all edges in the same community. 134 | 135 | .SH KEY SCHEDULE FILES 136 | (See 137 | .B n2n_v2(7) 138 | for more details). 139 | 140 | The -K option reads a key schedule file. 141 | 142 | .B edge \-d n2n0 \-c mynetwork \-K /path/to/file \-u 99 \-g 99 \-m DE:AD:BE:EF:01:21 \-a 192.168.254.5 \-p 50001 \-l 123.121.120.119:7654 143 | .PP 144 | 145 | The key schedule file consists of line, one per key in the schedule. The purpose 146 | of key schedules is to encourage regular changing of the encryption keys used by 147 | a community. The file structure also allows for full binary keys to be specified 148 | as compared to the ASCII keys allowed by the single key injection. Each key line 149 | consists of the following: 150 | 151 | .B 152 | 153 | and are ASCII decimal values of the UNIX times during which the 154 | key is valid. is the index of the transform that applies 155 | to. is some text which is parsed by the transform module to derive the 156 | key for that line. 157 | 158 | Supported values are: 159 | .TP 160 | 2 = TwoFish 161 | has the form _. eg. 162 | 163 | .B 1252327945 1252328305 2 602_3d7c7769b34b2a4812f8c0e9d87ce9 164 | 165 | This specifies security association number 602 and a 16-octet key of numeric 166 | value 0x3d7c7769b34b2a4812f8c0e9d87ce9. is a 32-bit unsigned integer which 167 | is used to identify the encryption key to the receiver. The SA number is sent 168 | unencrypted so the receiver may find the correct key from the key 169 | schedule. is up to 16 octets although shorter keys are allowed. 170 | 171 | .TP 172 | 3 = AES-CBC 173 | has the form _. Same rules as TwoFish. 174 | 175 | .SH CLEARTEXT MODE 176 | If neither 177 | .B -k 178 | nor 179 | .B -K 180 | is specified then edge uses cleartext mode. In cleartext mode there is no 181 | transform of the packet data it is simply encrypted. This is useful for 182 | debugging n2n as packet contents can be seen clearly. 183 | 184 | To prevent accidental exposure of data, edge only enters cleartext mode when no 185 | keying parameters are specified. In the case where keying parameters are 186 | specified but no valid keys can be determined, edge exits with an error at 187 | startup. If all keys become invalid while running, edge continues to encode 188 | using the last key that was valid. 189 | 190 | .SH MANAGEMENT INTERFACE 191 | Edge provides a very simple management system on UDP port 5644. Send a newline 192 | to receive a status output. Send 'reload' to cause re-read of the 193 | keyfile. Send 'stop' to cause edge to exit cleanly. 194 | 195 | .SH EXIT STATUS 196 | edge is a daemon and any exit is an error. 197 | .SH AUTHORS 198 | .TP 199 | Richard Andrews 200 | andrews (at) ntop.org - n2n-1 maintainer and main author of n2n-2 201 | .TP 202 | Luca Deri 203 | deri (at) ntop.org - original author of n2n 204 | .TP 205 | Don Bindner 206 | (--) - significant contributions to n2n-1 207 | .SH SEE ALSO 208 | ifconfig(8) supernode(1) tunctl(8) n2n_v2(7) 209 | -------------------------------------------------------------------------------- /n2n_list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * n2n_list.h 3 | * 4 | * Created on: Aug 31, 2012 5 | * Author: Costin Lupu 6 | */ 7 | 8 | #ifndef N2N_LIST_H_ 9 | #define N2N_LIST_H_ 10 | 11 | #include 12 | 13 | #ifdef _MSC_VER 14 | # define inline __inline 15 | # if _MSC_VER < 1600 16 | # define NO_TYPEOF 17 | # else 18 | # define typeof decltype 19 | # endif 20 | #endif 21 | 22 | 23 | /** 24 | * CONTAINER_* macros adapted from: 25 | * http://ccodearchive.net/info/container_of.html 26 | * Author: Rusty Russell 27 | */ 28 | 29 | /** 30 | * CONTAINER_OF - get pointer to enclosing structure 31 | * @member_ptr: pointer to the structure member 32 | * @containing_type: the type this member is within 33 | * @member: the name of this member within the structure. 34 | * 35 | * Given a pointer to a member of a structure, this macro does pointer 36 | * subtraction to return the pointer to the enclosing type. 37 | */ 38 | #define CONTAINER_OF(member_ptr, containing_type, member) \ 39 | ((containing_type *) ((char *)(member_ptr) - offsetof(containing_type, member))) 40 | 41 | /** 42 | * CONTAINER_OFF_VAR - get offset of a field in enclosing structure 43 | * @container_var: a pointer to a container structure 44 | * @member: the name of a member within the structure. 45 | * 46 | * Given (any) pointer to a structure and a its member name, this 47 | * macro does pointer subtraction to return offset of member in a 48 | * structure memory layout. 49 | * 50 | */ 51 | #ifdef NO_TYPEOF 52 | #define CONTAINER_OFF_VAR(var, member) \ 53 | ((char *) &(var)->member - (char *) (var)) 54 | #else 55 | #define CONTAINER_OFF_VAR(var, member) \ 56 | offsetof(typeof(*var), member) 57 | #endif 58 | 59 | 60 | 61 | /** 62 | * List structures, macros and functions adapted from: 63 | * http://ccodearchive.net/info/list.html 64 | * Author: Rusty Russell 65 | */ 66 | 67 | /** 68 | * struct n2n_list_node - an entry in a singly-linked list 69 | * @next: next entry 70 | */ 71 | struct n2n_list_node 72 | { 73 | struct n2n_list_node *next; 74 | }; 75 | 76 | typedef struct n2n_list_node n2n_list_node_t; 77 | 78 | 79 | /** 80 | * struct n2n_list_head - the head of a singly-linked list 81 | * @node: the list_head (containing next pointer) 82 | */ 83 | struct n2n_list_head 84 | { 85 | n2n_list_node_t node; 86 | }; 87 | 88 | typedef struct n2n_list_head n2n_list_head_t; 89 | 90 | 91 | 92 | /** 93 | * LIST_HEAD - define and initialize an empty list_head 94 | * @name: the name of the list. 95 | * 96 | * The LIST_HEAD macro defines a list_head and initializes it to an empty 97 | * list. It can be prepended by "static" to define a static list_head. 98 | */ 99 | #define LIST_HEAD(name) \ 100 | n2n_list_head_t name = {{ &name.node }} 101 | 102 | /** 103 | * list_head_init - initialize a list_head 104 | * @head: the list_head to set to the empty list 105 | */ 106 | static inline void list_head_init(n2n_list_head_t *head) 107 | { 108 | head->node.next = &head->node; 109 | } 110 | 111 | /** 112 | * list_add - add an entry at the start of a linked list. 113 | * @head: the list_head to add the node to 114 | * @node: the list_node to add to the list. 115 | * 116 | * The list_node does not need to be initialized; it will be overwritten. 117 | */ 118 | static inline void list_add(n2n_list_head_t *head, n2n_list_node_t *node) 119 | { 120 | node->next = head->node.next; 121 | head->node.next = node; 122 | } 123 | 124 | /** 125 | * list_empty - is a list empty? 126 | * @head: the list_head 127 | */ 128 | static inline int list_empty(const n2n_list_head_t *head) 129 | { 130 | return (head->node.next == &head->node); 131 | } 132 | 133 | /** 134 | * LIST_FIRST_NODE - returns the first node of a list. 135 | * @head: the list_head 136 | */ 137 | #define LIST_FIRST_NODE(head) \ 138 | (head)->node.next 139 | 140 | /** 141 | * LIST_FOR_EACH_NODE - iterate through a list of nodes. 142 | * @head: the list_head 143 | * @n: the list_node 144 | */ 145 | #define LIST_FOR_EACH_NODE(head, n) \ 146 | for (n = LIST_FIRST_NODE(head); n != &(head)->node; n = n->next) 147 | 148 | /** 149 | * LIST_FOR_EACH_NODE_SAFE - iterate through a list of nodes, maybe 150 | * during deletion 151 | * @head: the list_head 152 | * @n: the list_node 153 | * @nxt: the next list_node 154 | */ 155 | #define LIST_FOR_EACH_NODE_SAFE(head, n, nxt) \ 156 | for (n = LIST_FIRST_NODE(head), nxt = n->next; \ 157 | n != &(head)->node; \ 158 | n = nxt, nxt = nxt->next) 159 | 160 | /** 161 | * LIST_ENTRY - convert a list_node back into the structure containing it. 162 | * @node: the list_node 163 | * @type: the type of the entry 164 | * @member: the list_node member of the type 165 | */ 166 | #define LIST_ENTRY(node, type, member) \ 167 | CONTAINER_OF(node, type, member) 168 | 169 | /** 170 | * LIST_FIRST_ENTRY - convert the first list_node back into the structure 171 | * containing it. 172 | * @node: the list_node 173 | * @type: the type of the entry 174 | * @member: the list_node member of the type 175 | */ 176 | #define LIST_FIRST_ENTRY(head, type, member) \ 177 | (list_empty(head) ? NULL : LIST_ENTRY((head)->node.next, type, member)) 178 | 179 | /* Offset helper functions so we only single-evaluate. */ 180 | static inline void *list_node_to_off_(n2n_list_node_t *node, size_t off) 181 | { 182 | return (void *) ((char *) node - off); 183 | } 184 | 185 | static inline n2n_list_node_t *list_node_from_off_(void *ptr, size_t off) 186 | { 187 | return (n2n_list_node_t *) ((char *) ptr + off); 188 | } 189 | 190 | /** 191 | * LIST_FOR_EACH_OFF - iterate through a list of memory regions. 192 | * @head: the list_head 193 | * @i: the pointer to a memory region which contains list node data. 194 | * @off: offset(relative to @i) at which list node data resides. 195 | * 196 | * This is a low-level wrapper to iterate @i over the entire list, used to 197 | * implement all other, more high-level, for-each constructs. It's a for loop, 198 | * so you can break and continue as normal. 199 | */ 200 | #define LIST_FOR_EACH_OFF(head, i, off) \ 201 | for (i = list_node_to_off_((head)->node.next, (off)); \ 202 | list_node_from_off_((void *) i, (off)) != &(head)->node; \ 203 | i = list_node_to_off_(list_node_from_off_((void *) i, (off))->next, (off))) 204 | 205 | /** 206 | * LIST_FOR_EACH - iterate through a list. 207 | * @head: the list_head (warning: evaluated multiple times!) 208 | * @i: the structure containing the list_node 209 | * @member: the list_node member of the structure 210 | * 211 | * This is a convenient wrapper to iterate @i over the entire list. It's 212 | * a for loop, so you can break and continue as normal. 213 | */ 214 | #define LIST_FOR_EACH(head, i, member) \ 215 | LIST_FOR_EACH_OFF(head, i, CONTAINER_OFF_VAR(i, member)) 216 | 217 | /** 218 | * LIST_FOR_EACH_SAFE_OFF - iterate through a list of memory regions, maybe 219 | * during deletion 220 | * @head: the list_head 221 | * @i: the pointer to a memory region wich contains list node data. 222 | * @nxt: the structure containing the list_node 223 | * @off: offset(relative to @i) at which list node data resides. 224 | */ 225 | #define LIST_FOR_EACH_SAFE_OFF(head, i, nxt, off) \ 226 | for (i = list_node_to_off_((head)->node.next, (off)), \ 227 | nxt = list_node_to_off_(list_node_from_off_(i, (off))->next, (off)); \ 228 | list_node_from_off_(i, (off)) != &(head)->node; \ 229 | i = nxt, \ 230 | nxt = list_node_to_off_(list_node_from_off_(i, (off))->next, (off))) 231 | 232 | /** 233 | * LIST_FOR_EACH_SAFE - iterate through a list, maybe during deletion 234 | * @head: the list_head 235 | * @i: the structure containing the list_node 236 | * @nxt: the structure containing the list_node 237 | * @member: the list_node member of the structure 238 | * 239 | * This is a convenient wrapper to iterate @i over the entire list. It's 240 | * a for loop, so you can break and continue as normal. The extra variable 241 | * @nxt is used to hold the next element, so you can delete @i from the list. 242 | */ 243 | #define LIST_FOR_EACH_SAFE(head, i, nxt, member) \ 244 | LIST_FOR_EACH_SAFE_OFF(head, i, nxt, CONTAINER_OFF_VAR(i, member)) 245 | 246 | /** 247 | * End of adapted code 248 | */ 249 | 250 | 251 | /** 252 | * N2N customizations: 253 | * - The member name in N2N is always 'list' 254 | */ 255 | 256 | #define N2N_LIST_ENTRY(node, type) \ 257 | LIST_ENTRY(node, type, list) 258 | 259 | #define N2N_LIST_FIRST_ENTRY(head, type) \ 260 | LIST_FIRST_ENTRY(head, type, list) 261 | 262 | #define N2N_LIST_NEXT_ENTRY(ptr, type) \ 263 | CONTAINER_OF(ptr->list.next, type, list) 264 | 265 | #define N2N_LIST_FOR_EACH(head, node) \ 266 | LIST_FOR_EACH(head, node, list) 267 | 268 | #define N2N_LIST_FOR_EACH_SAFE(head, node, next) \ 269 | LIST_FOR_EACH_SAFE(head, node, next, list) 270 | 271 | /*************************************/ 272 | 273 | typedef int (*cmp_func_t)(const void *a, const void *b); 274 | 275 | size_t list_size(const n2n_list_head_t *head); 276 | size_t list_clear(n2n_list_head_t *head); 277 | void list_reverse(n2n_list_head_t *head); 278 | void list_sort(n2n_list_head_t *head, cmp_func_t func); 279 | 280 | /*************************************/ 281 | 282 | #include 283 | 284 | typedef n2n_list_node_t *(*rd_entry_func_t)(FILE *f); 285 | typedef void (*wr_entry_func_t)(FILE *f, const void *entry); 286 | 287 | int read_list_from_file(const char *filename, n2n_list_head_t *head, rd_entry_func_t rd_entry_func); 288 | int write_list_to_file(const char *filename, n2n_list_head_t *head, wr_entry_func_t wr_entry_func); 289 | 290 | 291 | 292 | #endif /* N2N_LIST_H_ */ 293 | -------------------------------------------------------------------------------- /sn_multiple_wire.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sn_multiple_wire.c 3 | * 4 | * Created on: Mar 25, 2012 5 | * Author: Costin Lupu 6 | */ 7 | 8 | #include "n2n.h" 9 | #include "sn_multiple_wire.h" 10 | 11 | 12 | 13 | static int alloc_array( void **array_ptr, unsigned int num, unsigned int item_size ) 14 | { 15 | if (num > 0) 16 | { 17 | *array_ptr = calloc(num, item_size); 18 | if (!*array_ptr) 19 | { 20 | traceError("not enough memory for allocating array"); 21 | return -1; 22 | } 23 | } 24 | else 25 | { 26 | *array_ptr = NULL; 27 | } 28 | 29 | return 0; 30 | } 31 | static void free_array( void **array_ptr ) 32 | { 33 | if(array_ptr && *array_ptr) 34 | { 35 | free(*array_ptr); 36 | *array_ptr = NULL; 37 | } 38 | } 39 | 40 | int alloc_communities( snm_comm_name_t **comm_ptr, unsigned int comm_num ) 41 | { 42 | return alloc_array((void **) comm_ptr, comm_num, sizeof(snm_comm_name_t)); 43 | } 44 | void free_communities( snm_comm_name_t **comm_ptr ) 45 | { 46 | free_array((void **) comm_ptr); 47 | } 48 | 49 | int alloc_supernodes( n2n_sock_t **sn_ptr, unsigned int sn_num ) 50 | { 51 | return alloc_array((void **) sn_ptr, sn_num, sizeof(n2n_sock_t)); 52 | } 53 | void free_supernodes( n2n_sock_t **sn_ptr ) 54 | { 55 | free_array((void **) sn_ptr); 56 | } 57 | 58 | int encode_SNM_comm( uint8_t *base, 59 | size_t *idx, 60 | const snm_comm_name_t *comm_name ) 61 | { 62 | int retval = 0; 63 | retval += encode_uint8(base, idx, comm_name->size); 64 | retval += encode_buf(base, idx, comm_name->name, comm_name->size); 65 | return retval; 66 | } 67 | 68 | int decode_SNM_comm( snm_comm_name_t *comm_name, 69 | const uint8_t *base, 70 | size_t *rem, 71 | size_t *idx ) 72 | { 73 | int retval = 0; 74 | memset(comm_name, 0, N2N_COMMUNITY_SIZE); 75 | retval += decode_uint8(&comm_name->size, base, rem, idx); 76 | retval += decode_buf(comm_name->name, comm_name->size, base, rem, idx); 77 | return retval; 78 | } 79 | 80 | int encode_SNM_hdr( uint8_t *base, 81 | size_t *idx, 82 | const snm_hdr_t *hdr ) 83 | { 84 | int retval = 0; 85 | retval += encode_uint8(base, idx, hdr->type); 86 | retval += encode_uint8(base, idx, hdr->flags); 87 | retval += encode_uint16(base, idx, hdr->seq_num); 88 | return retval; 89 | } 90 | 91 | int decode_SNM_hdr( snm_hdr_t *hdr, 92 | const uint8_t *base, 93 | size_t *rem, 94 | size_t *idx ) 95 | { 96 | int retval = 0; 97 | retval += decode_uint8(&hdr->type, base, rem, idx); 98 | retval += decode_uint8(&hdr->flags, base, rem, idx); 99 | retval += decode_uint16(&hdr->seq_num, base, rem, idx); 100 | return retval; 101 | } 102 | 103 | int encode_SNM_REQ( uint8_t *base, 104 | size_t *idx, 105 | const snm_hdr_t *hdr, 106 | const n2n_SNM_REQ_t *req ) 107 | { 108 | int i, retval = 0; 109 | retval += encode_SNM_hdr(base, idx, hdr); 110 | if (GET_N(hdr->flags)) 111 | { 112 | retval += encode_uint16(base, idx, req->comm_num); 113 | 114 | for (i = 0; i < req->comm_num; i++) 115 | { 116 | retval += encode_SNM_comm(base, idx, &req->comm_ptr[i]); 117 | } 118 | } 119 | return retval; 120 | } 121 | 122 | int decode_SNM_REQ( n2n_SNM_REQ_t *pkt, 123 | const snm_hdr_t *hdr, 124 | const uint8_t *base, 125 | size_t *rem, 126 | size_t *idx ) 127 | { 128 | int i, retval = 0; 129 | 130 | memset(pkt, 0, sizeof(n2n_SNM_REQ_t)); 131 | 132 | if (GET_N(hdr->flags)) 133 | { 134 | retval += decode_uint16(&pkt->comm_num, base, rem, idx); 135 | 136 | if (alloc_communities(&pkt->comm_ptr, pkt->comm_num)) 137 | { 138 | return -1; 139 | } 140 | 141 | for (i = 0; i < pkt->comm_num; i++) 142 | { 143 | retval += decode_SNM_comm(&pkt->comm_ptr[i], base, rem, idx); 144 | } 145 | } 146 | 147 | return retval; 148 | } 149 | 150 | int encode_SNM_INFO( uint8_t *base, 151 | size_t *idx, 152 | const snm_hdr_t *hdr, 153 | const n2n_SNM_INFO_t *info ) 154 | { 155 | int i, retval = 0; 156 | retval += encode_SNM_hdr(base, idx, hdr); 157 | retval += encode_uint16(base, idx, info->sn_num); 158 | retval += encode_uint16(base, idx, info->comm_num); 159 | 160 | if (GET_S(hdr->flags) || GET_A(hdr->flags)) /* SNM / ADV adresses */ 161 | { 162 | for (i = 0; i < info->sn_num; i++) 163 | { 164 | retval += encode_sock(base, idx, &info->sn_ptr[i]); 165 | } 166 | } 167 | if (GET_C(hdr->flags) || GET_N(hdr->flags)) 168 | { 169 | for (i = 0; i < info->comm_num; i++) 170 | { 171 | retval += encode_SNM_comm(base, idx, &info->comm_ptr[i]); 172 | } 173 | } 174 | return retval; 175 | } 176 | 177 | int decode_SNM_INFO( n2n_SNM_INFO_t *pkt, 178 | const snm_hdr_t *hdr, 179 | const uint8_t *base, 180 | size_t * rem, 181 | size_t * idx ) 182 | { 183 | int i, retval = 0; 184 | 185 | memset(pkt, 0, sizeof(n2n_SNM_INFO_t)); 186 | 187 | retval += decode_uint16(&pkt->sn_num, base, rem, idx); 188 | retval += decode_uint16(&pkt->comm_num, base, rem, idx); 189 | 190 | if (GET_S(hdr->flags) || GET_A(hdr->flags)) /* SNM / ADV adresses */ 191 | { 192 | if (alloc_supernodes(&pkt->sn_ptr, pkt->sn_num)) 193 | { 194 | return -1; 195 | } 196 | for (i = 0; i < pkt->sn_num; i++) 197 | { 198 | retval += decode_sock(&pkt->sn_ptr[i], base, rem, idx); 199 | } 200 | } 201 | if (GET_C(hdr->flags) || GET_N(hdr->flags)) 202 | { 203 | if (alloc_communities(&pkt->comm_ptr, pkt->comm_num)) 204 | { 205 | free_supernodes(&pkt->sn_ptr); 206 | return -1; 207 | } 208 | 209 | for (i = 0; i < pkt->comm_num; i++) 210 | { 211 | retval += decode_SNM_comm(&pkt->comm_ptr[i], base, rem, idx); 212 | } 213 | } 214 | 215 | return retval; 216 | } 217 | 218 | int encode_SNM_ADV( uint8_t *base, 219 | size_t *idx, 220 | const snm_hdr_t *hdr, 221 | const n2n_SNM_ADV_t *adv ) 222 | { 223 | int i, retval = 0; 224 | retval += encode_SNM_hdr(base, idx, hdr); 225 | retval += encode_sock(base, idx, &adv->sn); 226 | if (GET_N(hdr->flags)) 227 | { 228 | retval += encode_uint16(base, idx, adv->comm_num); 229 | 230 | for (i = 0; i < adv->comm_num; i++) 231 | { 232 | retval += encode_SNM_comm(base, idx, &adv->comm_ptr[i]); 233 | } 234 | } 235 | return retval; 236 | } 237 | 238 | int decode_SNM_ADV( n2n_SNM_ADV_t *pkt, 239 | const snm_hdr_t *hdr, 240 | const uint8_t *base, 241 | size_t *rem, 242 | size_t *idx ) 243 | { 244 | int i, retval = 0; 245 | 246 | memset(pkt, 0, sizeof(n2n_SNM_ADV_t)); 247 | 248 | retval += decode_sock(&pkt->sn, base, rem, idx); 249 | if (GET_N(hdr->flags)) 250 | { 251 | retval += decode_uint16(&pkt->comm_num, base, rem, idx); 252 | 253 | if (alloc_communities(&pkt->comm_ptr, pkt->comm_num)) 254 | { 255 | return -1; 256 | } 257 | 258 | for (i = 0; i < pkt->comm_num; i++) 259 | { 260 | retval += decode_SNM_comm(&pkt->comm_ptr[i], base, rem, idx); 261 | } 262 | } 263 | 264 | return retval; 265 | } 266 | 267 | void log_SNM_hdr( const snm_hdr_t *hdr ) 268 | { 269 | traceEvent( TRACE_DEBUG, "HEADER type=%d S=%d C=%d N=%d A=%d E=%d Seq=%d", hdr->type, 270 | GET_S(hdr->flags), GET_C(hdr->flags), GET_N(hdr->flags), GET_A(hdr->flags), GET_E(hdr->flags), 271 | hdr->seq_num ); 272 | } 273 | void log_SNM_REQ( const n2n_SNM_REQ_t *req ) 274 | { 275 | int i; 276 | traceEvent( TRACE_DEBUG, "REQ Communities=%d", req->comm_num ); 277 | if (req->comm_ptr) 278 | { 279 | for(i = 0; i < req->comm_num; i++) 280 | { 281 | traceEvent( TRACE_DEBUG, "\t[%d] len=%d name=%s", i, 282 | req->comm_ptr[i].size, req->comm_ptr[i].name ); 283 | } 284 | } 285 | } 286 | void log_SNM_INFO( const n2n_SNM_INFO_t *info ) 287 | { 288 | int i; 289 | n2n_sock_str_t sockbuf; 290 | 291 | traceEvent( TRACE_DEBUG, "INFO Supernodes=%d Communities=%d", 292 | info->sn_num, info->comm_num ); 293 | 294 | if (info->sn_ptr) 295 | { 296 | for(i = 0; i < info->sn_num; i++) 297 | { 298 | traceEvent( TRACE_DEBUG, "\t[S%d] %s", i, sock2str(sockbuf, &info->sn_ptr[i]) ); 299 | } 300 | } 301 | 302 | if (info->comm_ptr) 303 | { 304 | for(i = 0; i < info->comm_num; i++) 305 | { 306 | traceEvent( TRACE_DEBUG, "\t[C%d] len=%d name=%s", i, info->comm_ptr[i].size, 307 | (info->comm_ptr[i].size > 0) ? (const char *) info->comm_ptr[i].name : "" ); 308 | } 309 | } 310 | } 311 | void log_SNM_ADV( const n2n_SNM_ADV_t *adv ) 312 | { 313 | int i; 314 | n2n_sock_str_t sockbuf; 315 | 316 | traceEvent( TRACE_DEBUG, "ADV Supernode=%s Communities=%d", 317 | sock2str(sockbuf, &adv->sn), adv->comm_num ); 318 | 319 | if (adv->comm_ptr) 320 | { 321 | for(i = 0; i < adv->comm_num; i++) 322 | { 323 | traceEvent( TRACE_DEBUG, "\t[C%d] len=%d name=%s", i, adv->comm_ptr[i].size, 324 | (adv->comm_ptr[i].size > 0) ? (const char *) adv->comm_ptr[i].name : "" ); 325 | } 326 | } 327 | } 328 | --------------------------------------------------------------------------------