├── contrib ├── debian │ ├── compat │ ├── n2n-edge.docs │ ├── n2n-edge.install │ ├── n2n-supernode.manpages │ ├── n2n-edge.manpages │ ├── n2n-supernode.install │ ├── rules │ ├── README.Debian │ ├── copyright │ ├── changelog │ ├── n2n-edge.default │ ├── control │ ├── n2n-supernode.init │ └── n2n-edge.init ├── scripts │ ├── mk_SRPM.sh │ ├── mk_deb.sh │ └── mk_tar.sh ├── gen_keyfile.py ├── openwrt │ └── kamikaze │ │ └── Makefile └── n2n.spec ├── systemd ├── supernode.conf ├── cf0.conf ├── supernode.service └── edge@.service ├── .gitignore ├── version.c ├── .vscode ├── settings.json └── c_cpp_properties.json ├── test.c ├── win32 ├── CMakeLists.txt ├── application.manifest ├── msg.mc ├── edge.rc ├── sn.rc ├── wintap.h ├── n2n_win32.h ├── install.ps1 ├── getopt1.c ├── getopt.h └── scm_service.c ├── NEW_FEATURES.md ├── aes.h ├── supernode.troff ├── transform_null.c ├── random.h ├── n2n_transforms.h ├── minilzo.h ├── benchmark.c ├── tuntap_osx.c ├── tuntap_freebsd.c ├── n2n_keyfile.h ├── tuntap_netbsd.c ├── README.md ├── n2n_keyfile.c ├── CMakeLists.txt ├── n2n_v2.troff ├── aes.c ├── n2n.h ├── edge.troff ├── HACKING ├── twofish.h ├── n2n_wire.h ├── tuntap_linux.c └── n2n.c /contrib/debian/compat: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /contrib/debian/n2n-edge.docs: -------------------------------------------------------------------------------- 1 | README 2 | -------------------------------------------------------------------------------- /systemd/supernode.conf: -------------------------------------------------------------------------------- 1 | PORT="4385" 2 | 3 | -------------------------------------------------------------------------------- /contrib/debian/n2n-edge.install: -------------------------------------------------------------------------------- 1 | edge /usr/sbin 2 | -------------------------------------------------------------------------------- /contrib/debian/n2n-supernode.manpages: -------------------------------------------------------------------------------- 1 | supernode.1 2 | -------------------------------------------------------------------------------- /contrib/debian/n2n-edge.manpages: -------------------------------------------------------------------------------- 1 | edge.8 2 | n2n_v2.7 3 | -------------------------------------------------------------------------------- /contrib/debian/n2n-supernode.install: -------------------------------------------------------------------------------- 1 | supernode /usr/sbin 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.o 3 | *.a 4 | edge 5 | supernode 6 | *.gz 7 | win32/DotNet -------------------------------------------------------------------------------- /contrib/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /systemd/cf0.conf: -------------------------------------------------------------------------------- 1 | SUPERNODE="supernode:4385" 2 | COMMUNITY="n2n" 3 | IP_ADDRESS="static:192.168.1.10" 4 | NETMASK="255.255.255.0" 5 | MAC_ADDRESS="68:17:75:EA:46:1F" 6 | PARAMETER="-b" 7 | N2N_DEVICE=edge0 8 | N2N_KEY="SOME_KEY" 9 | -------------------------------------------------------------------------------- /contrib/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 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.h": "c", 4 | "*.tcc": "c", 5 | "array": "c", 6 | "hash_map": "c", 7 | "initializer_list": "c", 8 | "string_view": "c", 9 | "utility": "c" 10 | } 11 | } -------------------------------------------------------------------------------- /systemd/supernode.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=N2N network edge instance 3 | Documentation=man:edge(8) 4 | After=network.target 5 | 6 | [Service] 7 | DynamicUser=Yes 8 | ExecStart=supernode -t /run/supernode/mgmt -f -l $PORT $PARAMETER 9 | EnvironmentFile=/etc/n2n/supernode.conf 10 | RuntimeDirectory=supernode 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /systemd/edge@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=N2N network edge instance %i 3 | Documentation=man:edge(8) 4 | After=network.target network-online.target 5 | 6 | [Service] 7 | DynamicUser=Yes 8 | AmbientCapabilities=CAP_NET_ADMIN 9 | ExecStart=edge -t /run/edge-%i/mgmt -f -d $N2N_DEVICE -l $SUPERNODE -c $COMMUNITY -a $IP_ADDRESS -m $MAC_ADDRESS $PARAMETER 10 | ExecReload=sh -c 'echo reload | socat stdin unix-sendto:/run/edge-%i/mgmt' 11 | EnvironmentFile=/etc/n2n/%i.conf 12 | ConfigurationDirectory=n2n 13 | RuntimeDirectory=edge-%i 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /win32/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_MC_COMPILER mc.exe) 2 | add_custom_command( 3 | OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/msg.h ${CMAKE_CURRENT_BINARY_DIR}/msg.rc ${CMAKE_CURRENT_BINARY_DIR}/MSG00000.bin 4 | COMMAND ${CMAKE_MC_COMPILER} -U ${CMAKE_CURRENT_SOURCE_DIR}/msg.mc -r ${CMAKE_CURRENT_BINARY_DIR} -h ${CMAKE_CURRENT_BINARY_DIR} 5 | DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/msg.mc) 6 | 7 | set(N2N_RESOURCE ${CMAKE_CURRENT_BINARY_DIR}/msg.rc) 8 | 9 | add_library(n2n_win32 OBJECT 10 | getopt1.c 11 | getopt.c 12 | wintap.c 13 | scm_service.c 14 | ${N2N_RESOURCE} 15 | ) 16 | -------------------------------------------------------------------------------- /contrib/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 | -------------------------------------------------------------------------------- /win32/application.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /contrib/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 | -------------------------------------------------------------------------------- /contrib/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 | -------------------------------------------------------------------------------- /win32/msg.mc: -------------------------------------------------------------------------------- 1 | MessageIdTypedef=DWORD 2 | 3 | SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS 4 | Informational=0x1:STATUS_SEVERITY_INFORMATIONAL 5 | Warning=0x2:STATUS_SEVERITY_WARNING 6 | Error=0x3:STATUS_SEVERITY_ERROR 7 | ) 8 | 9 | 10 | FacilityNames=(System=0x0:FACILITY_SYSTEM 11 | Runtime=0x2:FACILITY_RUNTIME 12 | Stubs=0x3:FACILITY_STUBS 13 | Io=0x4:FACILITY_IO_ERROR_CODE 14 | ) 15 | 16 | LanguageNames=(Neutral=0x0000:MSG00000) 17 | 18 | ; // The following are message definitions. 19 | 20 | ; // Just provide the message contents no extras, 21 | ; // Message contains 22 | ; // %1: Service name, i.e. edge or supernode 23 | ; // %2: Message 24 | 25 | MessageId=0x0 26 | Severity=Informational 27 | Facility=Runtime 28 | SymbolicName=SVC_MESSAGE 29 | Language=Neutral 30 | %2 31 | . 32 | -------------------------------------------------------------------------------- /contrib/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 | -------------------------------------------------------------------------------- /win32/edge.rc: -------------------------------------------------------------------------------- 1 | #include 2 | /* use utf8 and lf line endings */ 3 | #pragma code_page(65001) 4 | 5 | VS_VERSION_INFO VERSIONINFO 6 | FILEVERSION 2,3,0,0 7 | PRODUCTVERSION 2,3,0,0 8 | FILEFLAGSMASK 0x3fL 9 | #ifdef _DEBUG 10 | FILEFLAGS 0x1L 11 | #else 12 | FILEFLAGS 0x0L 13 | #endif 14 | FILEOS VOS_NT_WINDOWS32 15 | FILETYPE VFT_APP 16 | FILESUBTYPE 0x0L 17 | BEGIN 18 | BLOCK "StringFileInfo" 19 | BEGIN 20 | BLOCK "000904b0" 21 | BEGIN 22 | VALUE "FileDescription", "n2n edge" 23 | VALUE "FileVersion", N2N_VERSION 24 | VALUE "ProductName", "n2n" 25 | VALUE "ProductVersion", "n2n " N2N_VERSION " for Windows" 26 | VALUE "OriginalFilename", "edge.exe" 27 | END 28 | END 29 | BLOCK "VarFileInfo" 30 | BEGIN 31 | VALUE "Translation", 0x009, 1200 32 | END 33 | END 34 | -------------------------------------------------------------------------------- /win32/sn.rc: -------------------------------------------------------------------------------- 1 | #include 2 | /* use utf8 and lf line endings */ 3 | #pragma code_page(65001) 4 | 5 | VS_VERSION_INFO VERSIONINFO 6 | FILEVERSION 2,3,0,0 7 | PRODUCTVERSION 2,3,0,0 8 | FILEFLAGSMASK 0x3fL 9 | #ifdef _DEBUG 10 | FILEFLAGS 0x1L 11 | #else 12 | FILEFLAGS 0x0L 13 | #endif 14 | FILEOS VOS_NT_WINDOWS32 15 | FILETYPE VFT_APP 16 | FILESUBTYPE 0x0L 17 | BEGIN 18 | BLOCK "StringFileInfo" 19 | BEGIN 20 | BLOCK "000904b0" 21 | BEGIN 22 | VALUE "FileDescription", "n2n supernode" 23 | VALUE "FileVersion", N2N_VERSION 24 | VALUE "ProductName", "n2n" 25 | VALUE "ProductVersion", "n2n " N2N_VERSION " for Windows" 26 | VALUE "OriginalFilename", "supernode.exe" 27 | END 28 | END 29 | BLOCK "VarFileInfo" 30 | BEGIN 31 | VALUE "Translation", 0x009, 1200 32 | END 33 | END 34 | -------------------------------------------------------------------------------- /NEW_FEATURES.md: -------------------------------------------------------------------------------- 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 | Further Additions: 8 | * Windows User Access Control 9 | * Windows Service (and Windows Event Log) 10 | * Specifying which Windows TAP adapter to use using `-d` 11 | * Linux capability awareness 12 | * Use API on Windows (IPHLPAPI.DLL) and Linux (ioctl) to set IP address 13 | * AES can use several crypto implementations: 14 | - OpenSSL 15 | - mbedTLS (default for OpenWRT) 16 | - nettle (low level library for GnuTLS) 17 | - gcrypt (part of GnuPG) 18 | - bcrypt.dll (Microsoft NextGen Crypto API, Part of Windows Vista and up) 19 | - libell (Embeded Linux Library, uses Kernel for Cryptography support) 20 | * IPv6 support 21 | 22 | Future: 23 | * NetBSD/FreeBSD/MacOS (most definitley broken, never checked) 24 | * Other Ciphers 25 | * Better Documentation 26 | * Code cleanup 27 | -------------------------------------------------------------------------------- /contrib/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 | -------------------------------------------------------------------------------- /contrib/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 secrets 18 | 19 | # a year worth of keys 20 | NUM_KEYS = 365 * 10 21 | # a is valid for one day 22 | KEY_LIFE = 60 * 60 * 24 23 | KEY_LEN = 32 24 | 25 | now = time.time() 26 | start_sa = secrets.randbelow( 0xffffffff ) 27 | 28 | for i in range(0,NUM_KEYS): 29 | from_time = now + (KEY_LIFE * (i-1) ) 30 | until_time = now + (KEY_LIFE * (i+1) ) 31 | key = secrets.token_hex(KEY_LEN) 32 | sa_idx = start_sa + i 33 | # use AES 34 | transform_id = 3 35 | #random.randint( 2, 3 ) 36 | 37 | sys.stdout.write("%d %d %d %d_%s\n"%(from_time, until_time, transform_id,sa_idx, key) ) 38 | -------------------------------------------------------------------------------- /contrib/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 | -------------------------------------------------------------------------------- /contrib/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 | -------------------------------------------------------------------------------- /aes.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @brief AES crypto library abstraction layer 3 | * 4 | * @file aes.h 5 | * @author Max Resch 6 | * @date 2018 7 | */ 8 | 9 | #ifndef N2N_AES_H_ 10 | #define N2N_AES_H_ 11 | 12 | #ifdef N2N_HAVE_AES 13 | 14 | #include 15 | #include 16 | 17 | 18 | #if USE_OPENSSL 19 | #include 20 | #include 21 | #elif USE_NETTLE 22 | #include 23 | #include 24 | #elif USE_GCRYPT 25 | #include 26 | #elif USE_MBEDTLS 27 | #include 28 | #elif USE_ELL 29 | #include 30 | #include 31 | #elif USE_BCRYPT 32 | #include 33 | #include 34 | #else 35 | #error "Unknown Crypto Library" 36 | #endif 37 | 38 | #define AES256_KEY_BYTES (256/8) 39 | #define AES192_KEY_BYTES (192/8) 40 | #define AES128_KEY_BYTES (128/8) 41 | 42 | #define AES_BLOCK_SIZE 16 43 | 44 | typedef struct cipher_ctx { 45 | #if USE_OPENSSL 46 | EVP_CIPHER_CTX *ctx; 47 | const EVP_CIPHER *cipher; 48 | uint8_t key[AES256_KEY_BYTES]; 49 | #elif USE_NETTLE 50 | struct aes256_ctx enc_ctx; 51 | struct aes256_ctx dec_ctx; 52 | nettle_cipher_func* enc_fun; 53 | nettle_cipher_func* dec_fun; 54 | #elif USE_GCRYPT 55 | gcry_cipher_hd_t cipher; 56 | #elif USE_MBEDTLS 57 | mbedtls_cipher_context_t enc_ctx; 58 | mbedtls_cipher_context_t dec_ctx; 59 | #elif USE_ELL 60 | struct l_cipher* cipher; 61 | #elif USE_BCRYPT 62 | BCRYPT_ALG_HANDLE hAlgorithm; 63 | BCRYPT_KEY_HANDLE hKey; 64 | #endif 65 | } *cipher_ctx_t; 66 | 67 | void n2n_aes_init(cipher_ctx_t ctx); 68 | 69 | void n2n_aes_free(cipher_ctx_t ctx); 70 | 71 | uint8_t n2n_aes_set_key(cipher_ctx_t ctx, const uint8_t* key, size_t length); 72 | 73 | void n2n_aes_encrypt(cipher_ctx_t ctx, const uint8_t* iv, const uint8_t* in, uint8_t* out, size_t length); 74 | 75 | void n2n_aes_decrypt(cipher_ctx_t ctx, const uint8_t* iv, const uint8_t* in, uint8_t* out, size_t length); 76 | 77 | #endif // N2N_HAVE_AES 78 | #endif // N2N_AES_H_ 79 | -------------------------------------------------------------------------------- /supernode.troff: -------------------------------------------------------------------------------- 1 | .TH supernode 1 "May 19 2018" "n2n-2.2" "USER COMMANDS" 2 | .SH NAME 3 | supernode \- n2n supernode daemon 4 | .SH SYNOPSIS 5 | .B supernode [\-l ] [\-v] [\-4] [\-6] 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. Defaults to 7654 23 | .TP 24 | \-4 25 | bind to the any interface IPv4 address. This is the default. 26 | .TP 27 | \-6 28 | bind to the any interface IPv6 address. This disables IPv4 but it can be combined with 29 | the \-4 switch to allow IPv4 and IPv6 traffic. 30 | .TP 31 | \-v 32 | use verbose logging 33 | .TP 34 | \-f 35 | disable daemon mode (UNIX) and run in foreground. 36 | .SH EXAMPLES 37 | .TP 38 | .B supernode -l 7654 -v 39 | Start supernode listening on UDP port 7654 with verbose output. 40 | .PP 41 | .SH REMARKS 42 | Additionally supernode opens UDP port 5645 on the IPv4 loopback interface (127.0.0.1). 43 | On this management socket statistical information can be queried, i.e. using 44 | .B socat(1). 45 | .SH RESTART 46 | When supernode restarts it loses all registration information from associated 47 | edge nodes. It can take up to five minutes for the edge nodes to re-register and 48 | normal traffic flow to resume. 49 | .SH EXIT STATUS 50 | supernode is a daemon and any exit is an error 51 | .SH AUTHOR 52 | Luca Deri ( deri (at) ntop.org ), Richard Andrews ( andrews (at) ntop.org ), Don Bindner, Max Resch 53 | .SH SEE ALSO 54 | edge(8) n2n(7) 55 | -------------------------------------------------------------------------------- /contrib/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 | -------------------------------------------------------------------------------- /transform_null.c: -------------------------------------------------------------------------------- 1 | /* (c) 2009 Richard Andrews */ 2 | 3 | #include "n2n.h" 4 | #include "n2n_transforms.h" 5 | 6 | static int transop_deinit_null( n2n_trans_op_t * arg ) 7 | { 8 | /* nothing to deallocate, nothing to release. */ 9 | return 0; 10 | } 11 | 12 | static ssize_t transop_encode_null( n2n_trans_op_t * arg, 13 | uint8_t * outbuf, 14 | size_t out_len, 15 | const uint8_t * inbuf, 16 | size_t in_len ) 17 | { 18 | ssize_t retval = -1; 19 | 20 | traceEvent( TRACE_DEBUG, "encode_null %lu", in_len ); 21 | if ( out_len >= in_len ) 22 | { 23 | memcpy( outbuf, inbuf, in_len ); 24 | retval = in_len; 25 | } 26 | else 27 | { 28 | traceEvent( TRACE_DEBUG, "encode_null %lu too big for packet buffer", in_len ); 29 | } 30 | 31 | return retval; 32 | } 33 | 34 | static ssize_t transop_decode_null( n2n_trans_op_t * arg, 35 | uint8_t * outbuf, 36 | size_t out_len, 37 | const uint8_t * inbuf, 38 | size_t in_len ) 39 | { 40 | ssize_t retval = -1; 41 | 42 | traceEvent( TRACE_DEBUG, "decode_null %lu", in_len ); 43 | if ( out_len >= in_len ) 44 | { 45 | memcpy( outbuf, inbuf, in_len ); 46 | retval = in_len; 47 | } 48 | else 49 | { 50 | traceEvent( TRACE_DEBUG, "decode_null %lu too big for packet buffer", in_len ); 51 | } 52 | 53 | return retval; 54 | } 55 | 56 | static int transop_addspec_null( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) 57 | { 58 | return 0; 59 | } 60 | 61 | static n2n_tostat_t transop_tick_null( n2n_trans_op_t * arg, time_t now ) 62 | { 63 | n2n_tostat_t r; 64 | 65 | r.can_tx=1; 66 | r.tx_spec.t = N2N_TRANSFORM_ID_NULL; 67 | r.tx_spec.valid_from = 0; 68 | r.tx_spec.valid_until = (time_t)(-1); 69 | r.tx_spec.opaque_size=0; 70 | 71 | return r; 72 | } 73 | 74 | void transop_null_init( n2n_trans_op_t * ttt ) 75 | { 76 | memset(ttt, 0, sizeof(n2n_trans_op_t) ); 77 | 78 | ttt->transform_id = N2N_TRANSFORM_ID_NULL; 79 | ttt->deinit = transop_deinit_null; 80 | ttt->addspec = transop_addspec_null; 81 | ttt->tick = transop_tick_null; 82 | ttt->fwd = transop_encode_null; 83 | ttt->rev = transop_decode_null; 84 | } 85 | -------------------------------------------------------------------------------- /contrib/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 | -------------------------------------------------------------------------------- /win32/wintap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | #ifndef __TAP_WIN_H 25 | #define __TAP_WIN_H 26 | 27 | /* 28 | * ============= 29 | * TAP IOCTLs 30 | * ============= 31 | */ 32 | 33 | #define TAP_WIN_CONTROL_CODE(request,method) \ 34 | CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) 35 | 36 | /* Present in 8.1 */ 37 | 38 | #define TAP_WIN_IOCTL_GET_MAC TAP_WIN_CONTROL_CODE (1, METHOD_BUFFERED) 39 | #define TAP_WIN_IOCTL_GET_VERSION TAP_WIN_CONTROL_CODE (2, METHOD_BUFFERED) 40 | #define TAP_WIN_IOCTL_GET_MTU TAP_WIN_CONTROL_CODE (3, METHOD_BUFFERED) 41 | #define TAP_WIN_IOCTL_GET_INFO TAP_WIN_CONTROL_CODE (4, METHOD_BUFFERED) 42 | #define TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT TAP_WIN_CONTROL_CODE (5, METHOD_BUFFERED) 43 | #define TAP_WIN_IOCTL_SET_MEDIA_STATUS TAP_WIN_CONTROL_CODE (6, METHOD_BUFFERED) 44 | #define TAP_WIN_IOCTL_CONFIG_DHCP_MASQ TAP_WIN_CONTROL_CODE (7, METHOD_BUFFERED) 45 | #define TAP_WIN_IOCTL_GET_LOG_LINE TAP_WIN_CONTROL_CODE (8, METHOD_BUFFERED) 46 | #define TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT TAP_WIN_CONTROL_CODE (9, METHOD_BUFFERED) 47 | 48 | /* Added in 8.2 */ 49 | 50 | /* obsoletes TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT */ 51 | #define TAP_WIN_IOCTL_CONFIG_TUN TAP_WIN_CONTROL_CODE (10, METHOD_BUFFERED) 52 | 53 | /* 54 | * ================= 55 | * Registry keys 56 | * ================= 57 | */ 58 | 59 | #define ADAPTER_KEY L"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 60 | 61 | #define NETWORK_CONNECTIONS_KEY L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 62 | 63 | /* 64 | * ====================== 65 | * Filesystem prefixes 66 | * ====================== 67 | */ 68 | 69 | #define USERMODEDEVICEDIR L"\\\\.\\Global\\" 70 | #define SYSDEVICEDIR L"\\Device\\" 71 | #define USERDEVICEDIR L"\\DosDevices\\Global\\" 72 | #define TAP_WIN_SUFFIX L".tap" 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /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 | #ifdef _WIN32 11 | 12 | /* use our own definition for min/max */ 13 | #define NOMINMAX 14 | 15 | /* use windows unicode API */ 16 | #define UNICODE 17 | #define _UNICODE 18 | 19 | #if defined(__MINGW32__) 20 | /* should be defined here and before winsock gets included */ 21 | #define _WIN32_WINNT 0x501 //Otherwise the linker doesnt find getaddrinfo 22 | #include 23 | #endif /* #if defined(__MINGW32__) */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | /* ip helper api */ 32 | #include 33 | 34 | #include 35 | 36 | /* for CLSIDFromString */ 37 | #include 38 | 39 | /* for _access */ 40 | #include 41 | 42 | #ifdef _MSC_VER 43 | #pragma comment(lib, "ws2_32.lib") 44 | #pragma comment(lib, "advapi32.lib") 45 | #pragma comment(lib, "iphlpapi.lib") 46 | #pragma comment(lib, "ole32.lib") 47 | #endif 48 | 49 | #include "wintap.h" 50 | 51 | #include 52 | #include 53 | #ifdef _MSC_VER 54 | #include "getopt.h" 55 | 56 | #ifdef _WIN64 57 | typedef __int64 ssize_t; 58 | #else 59 | typedef long ssize_t; 60 | #endif 61 | #endif /* #ifdef _MSC_VER */ 62 | 63 | #define reallocarray(p, n, s) realloc((p), ((n)*(s))) 64 | 65 | #define access _access 66 | #define R_OK 4 67 | 68 | typedef unsigned long in_addr_t; 69 | 70 | #ifdef EAFNOSUPPORT 71 | #undef EAFNOSUPPORT 72 | #endif 73 | #define EAFNOSUPPORT WSAEAFNOSUPPORT 74 | 75 | #define socklen_t int 76 | 77 | /* ************************************* */ 78 | 79 | #define N2N_IFNAMSIZ MAX_ADAPTER_NAME_LENGTH /* 256 */ 80 | 81 | typedef struct tuntap_dev { 82 | HANDLE device_handle; 83 | wchar_t device_name[40]; /* legnth of a CLSID is 38 */ 84 | NET_IFINDEX ifIdx; 85 | NET_LUID luid; 86 | OVERLAPPED overlap_read, overlap_write; 87 | bool dyn_ip4; 88 | uint8_t mac_addr[6]; 89 | uint32_t ip_addr; 90 | uint8_t ip_prefixlen; 91 | struct in6_addr ip6_addr; 92 | uint8_t ip6_prefixlen; 93 | uint32_t mtu; 94 | uint8_t routes_count; 95 | struct route* routes; 96 | } tuntap_dev; 97 | 98 | #define W32_ERROR(rc, error_string) \ 99 | LPTSTR error_string = NULL; \ 100 | FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | \ 101 | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ARGUMENT_ARRAY ,\ 102 | L"%0", rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &error_string, 0, NULL ); 103 | #define W32_ERROR_FREE(error_string) LocalFree( error_string ); 104 | 105 | extern HANDLE event_log; 106 | 107 | #define _SCM_NAME_LENGTH 128 108 | extern wchar_t scm_name[_SCM_NAME_LENGTH]; 109 | 110 | void initWin32(); 111 | 112 | int scm_startup(wchar_t* name); 113 | 114 | int tuntap_restart( tuntap_dev* device ); 115 | 116 | #endif /* _WIN32 */ 117 | #endif 118 | -------------------------------------------------------------------------------- /random.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @brief Cryptographic random number generator 3 | * 4 | * @file random.h 5 | * @author Max Resch 6 | */ 7 | 8 | #ifndef N2N_RANDOM_H_ 9 | #define N2N_RANDOM_H_ 10 | 11 | #if __linux__ 12 | // linux supports syscall random 13 | #include 14 | #elif __unix__ 15 | // BSD has arc4random 16 | #include 17 | #endif 18 | 19 | 20 | #include 21 | #include 22 | 23 | #if defined(_WIN32) && !defined(USE_BCRYPT) 24 | #define USE_BCRYPT 1 25 | #endif 26 | 27 | #if USE_OPENSSL 28 | #include 29 | #elif USE_NETTLE 30 | #include 31 | #elif USE_GCRYPT 32 | #include 33 | #elif USE_MBEDTLS 34 | #include 35 | #include 36 | #include 37 | #elif USE_ELL 38 | #include 39 | #elif USE_BCRYPT 40 | #include 41 | #include 42 | #endif 43 | 44 | typedef struct random_ctx { 45 | #if USE_NETTLE 46 | struct yarrow256_ctx yarrow; 47 | #elif USE_MBEDTLS 48 | mbedtls_entropy_context entropy; 49 | mbedtls_ctr_drbg_context random; 50 | #elif USE_BCRYPT 51 | BCRYPT_ALG_HANDLE hRandom; 52 | #endif 53 | } *random_ctx_t; 54 | 55 | static inline void random_init(random_ctx_t ctx) { 56 | #if USE_NETTLE 57 | yarrow256_init(&ctx->yarrow, 0, NULL); 58 | uint8_t rnd_data[YARROW256_SEED_FILE_SIZE]; 59 | #if __linux__ 60 | getrandom(rnd_data, YARROW256_SEED_FILE_SIZE, 0); 61 | #else 62 | arc4random_buf(rnd_data, YARROW256_SEED_FILE_SIZE); 63 | #endif 64 | yarrow256_seed(&ctx->yarrow, YARROW256_SEED_FILE_SIZE, rnd_data); 65 | #elif USE_MBEDTLS 66 | mbedtls_ctr_drbg_init(&ctx->random); 67 | mbedtls_entropy_init(&ctx->entropy); 68 | mbedtls_entropy_add_source(&ctx->entropy, &mbedtls_platform_entropy_poll, NULL, 16, MBEDTLS_ENTROPY_SOURCE_STRONG); 69 | mbedtls_ctr_drbg_seed(&ctx->random, &mbedtls_entropy_func, &ctx->entropy, NULL, 0); 70 | #elif USE_BCRYPT 71 | BCryptOpenAlgorithmProvider (&ctx->hRandom, BCRYPT_RNG_ALGORITHM, NULL, 0); 72 | #endif 73 | } 74 | 75 | static inline void random_free(random_ctx_t ctx) { 76 | #if USE_MBEDTLS 77 | mbedtls_ctr_drbg_free(&ctx->random); 78 | mbedtls_entropy_free(&ctx->entropy); 79 | #elif USE_BCRYPT 80 | BCryptCloseAlgorithmProvider(ctx->hRandom, 0); 81 | #endif 82 | } 83 | 84 | static inline void random_bytes(random_ctx_t ctx, uint8_t* buffer, size_t size) { 85 | #if USE_OPENSSL 86 | RAND_bytes((void*) buffer, size); 87 | #elif USE_GCRYPT 88 | gcry_create_nonce(buffer, size); 89 | #elif USE_NETTLE 90 | yarrow256_random(&ctx->yarrow, size, buffer); 91 | #elif USE_MBEDTLS 92 | mbedtls_ctr_drbg_random(&ctx->random, buffer, (uint32_t) size); 93 | #elif USE_ELL 94 | l_getrandom(buffer, (uint32_t) size); 95 | #elif USE_BCRYPT 96 | BCryptGenRandom(ctx->hRandom, buffer, (uint32_t) size, 0); 97 | #elif __linux__ 98 | getrandom(buffer, size, 0); 99 | #elif __unix__ 100 | arc4random_buf(buffer, size); 101 | #endif 102 | } 103 | 104 | #endif // N2N_RANDOM_H_ -------------------------------------------------------------------------------- /n2n_transforms.h: -------------------------------------------------------------------------------- 1 | /* (c) 2009 Richard Andrews */ 2 | 3 | #ifndef 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 ssize_t (*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 | uint64_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 /* N2N_TRANSFORMS_H_ */ 78 | 79 | -------------------------------------------------------------------------------- /contrib/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /contrib/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, size_t bufsize, const n2n_community_t c ); 30 | 31 | int main( int argc, char * argv[] ) 32 | { 33 | uint8_t pktbuf[N2N_PKT_BUF_SIZE]; 34 | n2n_trans_op_t transop_null; 35 | 36 | n2n_common_t cmn; 37 | n2n_PACKET_t pkt; 38 | n2n_community_t c; 39 | 40 | struct timeval t1; 41 | struct timeval t2; 42 | 43 | size_t i; 44 | size_t n; 45 | size_t idx; 46 | size_t rem; 47 | ssize_t nw; 48 | ssize_t tdiff; 49 | 50 | transop_null_init( &transop_null ); 51 | memset(c,0,sizeof(N2N_COMMUNITY_SIZE)); 52 | 53 | n=10000; 54 | memcpy( c, "abc123def456", 12 ); 55 | 56 | gettimeofday( &t1, NULL ); 57 | for(i=0; i %u nsec each) %u.%06u -> %u.%06u.\n", i, tdiff, (tdiff *1000)/i, (uint32_t)t1.tv_sec, (uint32_t)t1.tv_usec, (uint32_t)t2.tv_sec, (uint32_t)t2.tv_usec ); 81 | 82 | return 0; 83 | } 84 | 85 | static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c ) 86 | { 87 | n2n_mac_t destMac={0,1,2,3,4,5}; 88 | n2n_common_t cmn; 89 | n2n_PACKET_t pkt; 90 | size_t idx; 91 | 92 | 93 | memset( &cmn, 0, sizeof(cmn) ); 94 | cmn.ttl = N2N_DEFAULT_TTL; 95 | cmn.pc = n2n_packet; 96 | cmn.flags=0; /* no options, not from supernode, no socket */ 97 | memcpy( cmn.community, c, N2N_COMMUNITY_SIZE ); 98 | 99 | memset( &pkt, 0, sizeof(pkt) ); 100 | memcpy( pkt.srcMac, destMac, N2N_MAC_SIZE); 101 | memcpy( pkt.dstMac, destMac, N2N_MAC_SIZE); 102 | 103 | pkt.sock.family=0; /* do not encode sock */ 104 | 105 | idx=0; 106 | encode_PACKET( pktbuf, &idx, &cmn, &pkt ); 107 | traceEvent( TRACE_DEBUG, "encoded PACKET header of size=%u", (unsigned int)idx ); 108 | 109 | return idx; 110 | } 111 | -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Mac", 5 | "includePath": [ 6 | "/usr/include", 7 | "/usr/local/include", 8 | "${workspaceFolder}" 9 | ], 10 | "defines": [], 11 | "intelliSenseMode": "clang-x64", 12 | "browse": { 13 | "path": [ 14 | "/usr/include", 15 | "/usr/local/include", 16 | "${workspaceFolder}" 17 | ], 18 | "limitSymbolsToIncludedHeaders": true, 19 | "databaseFilename": "" 20 | }, 21 | "macFrameworkPath": [ 22 | "/System/Library/Frameworks", 23 | "/Library/Frameworks" 24 | ], 25 | "compilerPath": "/usr/bin/clang", 26 | "cStandard": "c11", 27 | "cppStandard": "c++17" 28 | }, 29 | { 30 | "name": "Linux", 31 | "includePath": [ 32 | "/usr/include", 33 | "/usr/local/include", 34 | "${workspaceFolder}" 35 | ], 36 | "defines": [ 37 | "_POSIX_C_SOURCE=200809", 38 | "N2N_HAVE_AES", 39 | "USE_NETTLE=1" 40 | ], 41 | "intelliSenseMode": "clang-x64", 42 | "browse": { 43 | "path": [ 44 | "/usr/include", 45 | "/usr/local/include", 46 | "${workspaceFolder}" 47 | ], 48 | "limitSymbolsToIncludedHeaders": true, 49 | "databaseFilename": "" 50 | }, 51 | "compilerPath": "/usr/bin/clang", 52 | "cStandard": "c11", 53 | "cppStandard": "c++17", 54 | "configurationProvider": "vector-of-bool.cmake-tools" 55 | }, 56 | { 57 | "name": "Win32", 58 | "includePath": [ 59 | "${workspaceFolder}", 60 | "C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.13.26128/include/*", 61 | "C:/Program Files (x86)/Windows Kits/10/Include/10.0.16299.0/um", 62 | "C:/Program Files (x86)/Windows Kits/10/Include/10.0.16299.0/ucrt", 63 | "C:/Program Files (x86)/Windows Kits/10/Include/10.0.16299.0/shared", 64 | "C:/Program Files (x86)/Windows Kits/10/Include/10.0.16299.0/winrt", 65 | "/run/media/max/Volume/Windows/VS14/WK/include/um", 66 | "/run/media/max/Volume/Windows/VS14/WK/include/ucrt", 67 | "/run/media/max/Volume/Windows/VS14/WK/include/shared" 68 | ], 69 | "defines": [ 70 | "_DEBUG", 71 | "_UNICODE", 72 | "_WIN32", 73 | "N2N_HAVE_AES", 74 | "USE_BCRYPT=1" 75 | ], 76 | "intelliSenseMode": "msvc-x64", 77 | "browse": { 78 | "path": [ 79 | "${workspaceFolder}", 80 | "C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.13.26128/include/*", 81 | "C:/Program Files (x86)/Windows Kits/10/Include/10.0.16299.0/um", 82 | "C:/Program Files (x86)/Windows Kits/10/Include/10.0.16299.0/ucrt", 83 | "C:/Program Files (x86)/Windows Kits/10/Include/10.0.16299.0/shared", 84 | "C:/Program Files (x86)/Windows Kits/10/Include/10.0.16299.0/winrt", 85 | "/run/media/max/Volume/Windows/VS14/WK/include/um", 86 | "/run/media/max/Volume/Windows/VS14/WK/include/ucrt", 87 | "/run/media/max/Volume/Windows/VS14/WK/include/shared" 88 | ], 89 | "limitSymbolsToIncludedHeaders": true, 90 | "databaseFilename": "" 91 | }, 92 | "cStandard": "c11", 93 | "cppStandard": "c++17", 94 | "compilerPath": "/usr/bin/clang", 95 | "compileCommands": "${workspaceFolder}/build/compile_commands.json" 96 | } 97 | ], 98 | "version": 4 99 | } -------------------------------------------------------------------------------- /win32/install.ps1: -------------------------------------------------------------------------------- 1 | # install path for edge 2 | $binaryPath = "$env:ProgramFiles\n2n" 3 | 4 | # function to install a service 5 | Function Install-ServiceInstance($binaryName, $instanceName, $arguments, $depends) 6 | { 7 | 8 | # stop the service 9 | if (Get-Service -Name $instanceName) { 10 | Stop-Service -Name $instanceName | Out-Null 11 | # a cmdlet is only available for PWSH 6+ 12 | & "$env:SystemRoot\System32\sc.exe" delete $instanceName | Out-Null 13 | } else { 14 | Write-Host -ForegroundColor Green ` 15 | "Could not find existing service '$instanceName', this is ok, if it was not installed." 16 | } 17 | 18 | # create a new program folder 19 | if (!(Test-Path -Path "$binaryPath" -Type Container)) { 20 | New-Item -Type Directory -Path "$binaryPath" | Out-Null 21 | } 22 | 23 | # copy the edge executable 24 | Try { 25 | Copy-Item "$binaryName" "$binaryPath\$binaryName" 26 | } Catch { 27 | Write-Host -ForegroundColor Red "$instanceName cannot be installed: $_" 28 | Return 29 | } 30 | 31 | # create a new service with manual startup type 32 | if ($depends) { 33 | New-Service -Name $instanceName -BinaryPathName "$binaryPath\$binaryName" ` 34 | -StartupType Manual -DependsOn $depends | Out-Null 35 | } else { 36 | New-Service -Name $instanceName -BinaryPathName "$binaryPath\$binaryName" ` 37 | -StartupType Manual | Out-Null 38 | } 39 | 40 | # create the registry key 41 | if (!(Test-Path -Path "HKLM:\SOFTWARE\n2n" -PathType Container)) { 42 | New-Item -Type Directory -Path "HKLM:\SOFTWARE\n2n" | Out-Null 43 | } 44 | 45 | if (!(Test-Path -Path "HKLM:\SOFTWARE\n2n\$instanceName" -PathType Container)) { 46 | New-Item -Type Directory -Path "HKLM:\SOFTWARE\n2n\$instanceName" | Out-Null 47 | 48 | } 49 | 50 | # add or update the value in the registry key 51 | New-ItemProperty -Path "HKLM:\SOFTWARE\n2n\$instanceName" -Name "Arguments" ` 52 | -PropertyType MultiString -Value $arguments -Force | Out-Null 53 | 54 | # install application resource for event log messages 55 | # (needed so eventlog actually display something) 56 | $eventLog = "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\Application\$instanceName" 57 | if (!(Test-Path -Path $eventLog -PathType Container)) { 58 | New-Item -Type Directory -Path $eventLog | Out-Null 59 | } 60 | 61 | New-ItemProperty -Path $eventLog -Name "EventMessageFile" ` 62 | -PropertyType String -Value "$binaryPath\$binaryName" -Force | Out-Null 63 | New-ItemProperty -Path $eventLog -Name "TypesSupported" ` 64 | -PropertyType DWORD -Value 0x7 -Force | Out-Null 65 | 66 | # start the service 67 | #Start-Service $instanceName 68 | 69 | Write-Host -ForegroundColor Green "$binaryName installed as service $instanceName" 70 | } #end Function Install-ServiceInstance 71 | 72 | # arguments for edge to be saved in the registry 73 | # can be a string or a multistring (aka an array of strings). 74 | # multistrings are required for parameters with spaces in them 75 | $arguments_edge = @( 76 | "-a", "static:192.168.1.1", 77 | "-A", "fdf0::1/64", 78 | "-c", "x", 79 | "-l", "[::1]:4385", 80 | "-k", "x", 81 | "-b" 82 | ) 83 | 84 | # add a dependency to edge, so that is won't get started before the TAP device 85 | # note that the tap0901 name might change, this is for the TAP device driver 86 | # version 9. version 8 would be tap0801. 87 | 88 | Install-ServiceInstance "edge.exe" "edge" $arguments_edge -depends $("tap0901", "netman") 89 | Install-ServiceInstance "supernode.exe" "supernode" @("-4", "-6", "-l", "4385") 90 | 91 | # Edge can run multiple instances (as different services), simply by giving 92 | # another instance name and a different set of parameters. Note that we provide 93 | # a -d paramter to set a TAP interface name, this interface must exist in 94 | # advance. and the for mutliple edge instances to run in parallel at least the 95 | # same number of TAP adapters must exist on the system. The TAP driver comes 96 | # with a tool to increas the number of virutal interfaces. 97 | 98 | #$arguments_edge2 = @( "-a", "static:192.168.2.1", "-c", "y", "-l", "[::1]:4385", "-k", "x", "-d", "TUNTAP2", "-b" ) 99 | #Install-ServiceInstance "edge.exe" "edge2" $arguments_edge2 -depends "tap0901" 100 | -------------------------------------------------------------------------------- /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 | 20 | #ifdef _DARWIN_ 21 | 22 | void tun_close(tuntap_dev *device); 23 | 24 | /* ********************************** */ 25 | 26 | #define N2N_OSX_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 | int i; 35 | char tap_device[N2N_OSX_TAPDEVICE_SIZE]; 36 | 37 | for (i = 0; i < 255; i++) { 38 | snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); 39 | 40 | device->fd = open(tap_device, O_RDWR); 41 | if(device->fd > 0) { 42 | traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); 43 | break; 44 | } 45 | } 46 | 47 | if(device->fd < 0) { 48 | traceEvent(TRACE_ERROR, "Unable to open tap device"); 49 | return(-1); 50 | } else { 51 | char buf[256]; 52 | FILE *fd; 53 | 54 | device->ip_addr = inet_addr(device_ip); 55 | 56 | if ( device_mac && device_mac[0] != '\0' ) 57 | { 58 | /* FIXME - This is not tested. Might be wrong syntax for OS X */ 59 | 60 | /* Set the hw address before bringing the if up. */ 61 | snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", 62 | i, device_mac); 63 | system(buf); 64 | } 65 | 66 | snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", 67 | i, device_ip, device_mask, mtu); 68 | system(buf); 69 | 70 | traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", 71 | i, device_ip, device_mask); 72 | 73 | /* Read MAC address */ 74 | 75 | snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); 76 | /* traceEvent(TRACE_INFO, "%s", buf); */ 77 | 78 | fd = popen(buf, "r"); 79 | if(fd < 0) { 80 | tun_close(device); 81 | return(-1); 82 | } else { 83 | int a, b, c, d, e, f; 84 | 85 | buf[0] = 0; 86 | fgets(buf, sizeof(buf), fd); 87 | pclose(fd); 88 | 89 | if(buf[0] == '\0') { 90 | traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); 91 | exit(0); 92 | } 93 | 94 | traceEvent(TRACE_NORMAL, "Interface tap%d [MTU %d] mac %s", i, mtu, buf); 95 | if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { 96 | device->mac_addr[0] = a, device->mac_addr[1] = b; 97 | device->mac_addr[2] = c, device->mac_addr[3] = d; 98 | device->mac_addr[4] = e, device->mac_addr[5] = f; 99 | } 100 | } 101 | } 102 | 103 | 104 | /* read_mac(dev, device->mac_addr); */ 105 | return(device->fd); 106 | } 107 | 108 | /* ********************************** */ 109 | 110 | int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { 111 | return(read(tuntap->fd, buf, len)); 112 | } 113 | 114 | /* ********************************** */ 115 | 116 | int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { 117 | return(write(tuntap->fd, buf, len)); 118 | } 119 | 120 | /* ********************************** */ 121 | 122 | void tuntap_close(struct tuntap_dev *tuntap) { 123 | close(tuntap->fd); 124 | } 125 | 126 | /* Fill out the ip_addr value from the interface. Called to pick up dynamic 127 | * address changes. */ 128 | void tuntap_get_address(struct tuntap_dev *tuntap) 129 | { 130 | } 131 | 132 | #endif /* _DARWIN_ */ 133 | -------------------------------------------------------------------------------- /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 | int i; 35 | char tap_device[N2N_FREEBSD_TAPDEVICE_SIZE]; 36 | 37 | for (i = 0; i < 255; i++) { 38 | snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); 39 | 40 | device->fd = open(tap_device, O_RDWR); 41 | if(device->fd > 0) { 42 | traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); 43 | break; 44 | } 45 | } 46 | 47 | if(device->fd < 0) { 48 | traceEvent(TRACE_ERROR, "Unable to open tap device"); 49 | return(-1); 50 | } else { 51 | char buf[256]; 52 | FILE *fd; 53 | 54 | device->ip_addr = inet_addr(device_ip); 55 | 56 | if ( device_mac && device_mac[0] != '\0' ) 57 | { 58 | /* FIXME - This is not tested. Might be wrong syntax for OS X */ 59 | 60 | /* Set the hw address before bringing the if up. */ 61 | snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", 62 | i, device_mac); 63 | system(buf); 64 | } 65 | 66 | snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", 67 | i, device_ip, device_mask, mtu); 68 | system(buf); 69 | 70 | traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", 71 | i, device_ip, device_mask); 72 | 73 | /* Read MAC address */ 74 | 75 | snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); 76 | /* traceEvent(TRACE_INFO, "%s", buf); */ 77 | 78 | fd = popen(buf, "r"); 79 | if(fd < 0) { 80 | tun_close(device); 81 | return(-1); 82 | } else { 83 | int a, b, c, d, e, f; 84 | 85 | buf[0] = 0; 86 | fgets(buf, sizeof(buf), fd); 87 | pclose(fd); 88 | 89 | if(buf[0] == '\0') { 90 | traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); 91 | exit(0); 92 | } 93 | 94 | traceEvent(TRACE_NORMAL, "Interface tap%d mac %s", i, buf); 95 | if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { 96 | device->mac_addr[0] = a, device->mac_addr[1] = b; 97 | device->mac_addr[2] = c, device->mac_addr[3] = d; 98 | device->mac_addr[4] = e, device->mac_addr[5] = f; 99 | } 100 | } 101 | } 102 | 103 | 104 | /* read_mac(dev, device->mac_addr); */ 105 | return(device->fd); 106 | } 107 | 108 | /* ********************************** */ 109 | 110 | int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { 111 | return(read(tuntap->fd, buf, len)); 112 | } 113 | 114 | /* ********************************** */ 115 | 116 | int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { 117 | return(write(tuntap->fd, buf, len)); 118 | } 119 | 120 | /* ********************************** */ 121 | 122 | void tuntap_close(struct tuntap_dev *tuntap) { 123 | close(tuntap->fd); 124 | } 125 | 126 | /* Fill out the ip_addr value from the interface. Called to pick up dynamic 127 | * address changes. */ 128 | void tuntap_get_address(struct tuntap_dev *tuntap) 129 | { 130 | } 131 | 132 | #endif /* #ifdef __FreeBSD__ */ 133 | -------------------------------------------------------------------------------- /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_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 | char tap_device[N2N_NETBSD_TAPDEVICE_SIZE]; 40 | struct ifreq req; 41 | 42 | if (dev) { 43 | snprintf(tap_device, sizeof(tap_device), "/dev/%s", dev); 44 | device->fd = open(tap_device, O_RDWR); 45 | snprintf(tap_device, sizeof(tap_device), "%s", dev); 46 | } 47 | else { 48 | device->fd = open("/dev/tap", O_RDWR); 49 | if(device->fd >= 0) { 50 | if (ioctl(device->fd, TAPGIFNAME, &req) == -1) { 51 | traceEvent(TRACE_ERROR, "Unable to obtain name of tap device (%s)", strerror(errno)); 52 | close(device->fd); 53 | return(-1); 54 | } 55 | else { 56 | snprintf(tap_device, sizeof(tap_device), req.ifr_name); 57 | } 58 | } 59 | } 60 | 61 | if(device->fd < 0) { 62 | traceEvent(TRACE_ERROR, "Unable to open tap device (%s)", strerror(errno)); 63 | return(-1); 64 | } else { 65 | char buf[256]; 66 | FILE *fd; 67 | 68 | traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); 69 | 70 | device->ip_addr = inet_addr(device_ip); 71 | 72 | if ( device_mac && device_mac[0] != '\0' ) 73 | { 74 | /* Set the hw address before bringing the if up. */ 75 | snprintf(buf, sizeof(buf), "ifconfig %s link %s active", 76 | tap_device, device_mac); 77 | system(buf); 78 | } 79 | 80 | snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s mtu %d up", 81 | tap_device, device_ip, device_mask, mtu); 82 | system(buf); 83 | 84 | traceEvent(TRACE_NORMAL, "Interface %s up and running (%s/%s)", 85 | tap_device, device_ip, device_mask); 86 | 87 | /* Read MAC address */ 88 | 89 | snprintf(buf, sizeof(buf), "ifconfig %s |grep address|cut -c 11-28", tap_device); 90 | /* traceEvent(TRACE_INFO, "%s", buf); */ 91 | 92 | fd = popen(buf, "r"); 93 | if(fd < 0) { 94 | tun_close(device); 95 | return(-1); 96 | } else { 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 | traceEvent(TRACE_ERROR, "Unable to read %s interface MAC address", tap_device); 105 | exit(0); 106 | } 107 | 108 | traceEvent(TRACE_NORMAL, "Interface %s mac %s", tap_device, buf); 109 | if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { 110 | device->mac_addr[0] = a, device->mac_addr[1] = b; 111 | device->mac_addr[2] = c, device->mac_addr[3] = d; 112 | device->mac_addr[4] = e, device->mac_addr[5] = f; 113 | } 114 | } 115 | } 116 | 117 | 118 | /* read_mac(dev, device->mac_addr); */ 119 | return(device->fd); 120 | } 121 | 122 | /* ********************************** */ 123 | 124 | int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { 125 | return(read(tuntap->fd, buf, len)); 126 | } 127 | 128 | /* ********************************** */ 129 | 130 | int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { 131 | return(write(tuntap->fd, buf, len)); 132 | } 133 | 134 | /* ********************************** */ 135 | 136 | void tuntap_close(struct tuntap_dev *tuntap) { 137 | close(tuntap->fd); 138 | } 139 | 140 | /* Fill out the ip_addr value from the interface. Called to pick up dynamic 141 | * address changes. */ 142 | void tuntap_get_address(struct tuntap_dev *tuntap) 143 | { 144 | } 145 | 146 | #endif /* #ifdef __NetBSD__ */ 147 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Edge node 4 | 5 | You need to start an edge node on each host you want to connect with the *same* 6 | community. 7 | 8 | Become root 9 | ``` 10 | ./edge -f -d n2n0 -c mynetwork -u 99 -g 99 -k encryptme -m 00:FF:12:34:56:78 -a 192.168.254.1 -s 255.255.255.0 -l a.b.c.d:xyw 11 | ``` 12 | or 13 | ``` 14 | N2N_KEY=encryptme ./edge -f -d n2n0 -c mynetwork -u 99 -g 99 -m 00:FF:12:34:56:78 -a 192.168.254.1 -s 255.255.255.0 -l a.b.c.d:xyw 15 | ``` 16 | 17 | Once you have this worked out, you can drop the `-f` option to make edge detach 18 | and run as a daemon. 19 | 20 | Note that `-u`, `-g` and `-f` options are not available for Windows. 21 | 22 | When running edge on Windows a compatile TAP network interface is required, the driver is included in the 23 | [OpenVPN installer](https://openvpn.net/index.php/open-source/downloads.html). If multiple TAP adapters 24 | exist in the system one can be specified using the `-d` parameter and the "Friendly Name" of the adapter 25 | (the one shown in the Network Adapter List in the Control Pannel). If the name containes spaces be sure to use quotation marks around it. 26 | 27 | # Supernode 28 | 29 | You need to start the supernode once, it does not require any privileges. 30 | 31 | 1. `./supernode -l 1234 -v -f` 32 | 33 | # IPv6 Support 34 | 35 | This version of edge and supernode support transport inbetween over IPv6. 36 | 37 | Start supernode either in IPv6 or IPv4 and IPv6 mode, by specifing `-6` or `-4` and `-6` switches. 38 | 39 | ``` 40 | ./supernode -6 -f 41 | ``` 42 | or 43 | ``` 44 | ./supernode -4 -6 -f 45 | ``` 46 | 47 | The default setting is to launch supernode in IPv4 only mode. 48 | 49 | To use IPv6 with edge only the address needs to be specified for 50 | the supernode. 51 | 52 | ``` 53 | ./edge -f -v [ other options ] -l [2001:aa00:bb00::1]:1234 54 | ``` 55 | 56 | If DNS name resolution is required, then use the `-6` parameter, 57 | to force a IPv6 address to be resolved. 58 | 59 | ``` 60 | ./edge -f -v [ other options ] -6 -l example.com:1234 61 | ``` 62 | 63 | 64 | # IPv6 Support (Inner) 65 | 66 | n2n supports the carriage of IPv6 packets within the n2n tunnel. 67 | 68 | ``` 69 | ./edge -f -v [ other options ] -a 192.168.254.1 -s 255.255.255.0 -A fdf0:aa01:bb02::1/64 70 | ``` 71 | 72 | # Considerations of running edge as system service 73 | 74 | ## Use net_admin capabilities (LINUX) 75 | 76 | This version of edge is capabilties aware and uses the `NET_ADMIN` capability if it is found 77 | in its permissive set. 78 | 79 | To use this feature set as root the admin capability: 80 | ``` 81 | setcap cap_net_admin+p ./edge 82 | ``` 83 | 84 | Edge can now be run as any user that has executive permission for edge. 85 | 86 | 87 | ## Running As a Daemon (UNIX) 88 | 89 | Unless given `-f` as a command line option, edge will call `daemon(3)` after 90 | successful setup. This causes the process to fork a child which closes `stdin`, 91 | `stdout` and `stderr` then sets itself as process group leader. When this is done, 92 | the edge command returns immediately and you will only see the edge process in 93 | the process listings, eg. from `ps` or `top`. 94 | 95 | If the edge command returns 0 then the daemon started successfully. If it 96 | returns non-zero then edge failed to start up for some reason. When edge starts 97 | running as a daemon, all logging goes to syslog `daemon.info` facility. 98 | 99 | 100 | ## Dropping Root Privileges and SUID-Root Executables (UNIX) 101 | 102 | The edge node uses superuser privileges to create a TAP network interface 103 | device. Once this is created root privileges are not required and can constitute 104 | a security hazard if there is some way for an attacker to take control of an 105 | edge process while it is running. Edge will drop to a non-privileged user if you 106 | specify the `-u ` and `-g ` options. These are numeric IDs. Consult `/etc/passwd`. 107 | 108 | You may choose to install edge SUID-root to do this: 109 | 110 | 1. Become root 111 | 2. `chown root:root edge` 112 | 3. `chmod +s edge` 113 | 114 | Any user can now run edge. You may not want this, but it may be convenient and 115 | safe if your host has only one login user. 116 | 117 | ## Systemd Service (LINUX) 118 | 119 | Examples for an systemd service file are provided in the systemd/ folder. 120 | The edge service uses AmbientCapabilities to set the net_admin capability 121 | to run edge as a dynamically created user. 122 | 123 | Systemd requires a Linux Kernel 4.3 or greater for this feature. 124 | 125 | 126 | ## SCM Service (WINDOWS) 127 | 128 | edge and supernode can be installed as a Windows SCM service, consult the [`win32/install.ps1`](win32/install.ps1) 129 | script in the repository. 130 | 131 | When running as a service, edge and supernode are not attached to 132 | a console, messages are logged in the Windows Event Log. 133 | 134 | The commandline parameters are stored in `HKLM:\SOFTWARE\n2n\edge\Arguments` and `HKLM:\SOFTWARE\n2n\supernode\Arguments`. 135 | They can be modified using `regedit` or an administrative PowerShell Console. Both entries are *MulitStrings*, so that parameters 136 | containing spaces can properly supported but if this is not needed the registry entries can be of type *String* too. 137 | -------------------------------------------------------------------------------- /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_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 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | #ifdef WIN32 15 | char *strsep( char **ppsz_string, const char *psz_delimiters ) 16 | { 17 | char *p; 18 | char *psz_string = *ppsz_string; 19 | if( !psz_string ) 20 | return NULL; 21 | 22 | p = strpbrk( psz_string, psz_delimiters ); 23 | if( !p ) 24 | { 25 | *ppsz_string = NULL; 26 | return psz_string; 27 | } 28 | *p++ = '\0'; 29 | 30 | *ppsz_string = p; 31 | return psz_string; 32 | } 33 | #endif 34 | 35 | 36 | /* Parse hex nibbles in ascii until a non-nibble character is found. Nibble 37 | * characters are 0-9, a-f and A-F. 38 | * 39 | * Return number of bytes parsed into keyBuf or a negative error code. 40 | */ 41 | ssize_t n2n_parse_hex( uint8_t * keyBuf, 42 | size_t keyLen, 43 | const char * textKey, 44 | size_t textLen) 45 | { 46 | ssize_t retval=0; 47 | uint8_t * pout=keyBuf; 48 | size_t octet=0; 49 | const char * textEnd; 50 | const char * pbeg; 51 | 52 | textEnd = textKey+textLen; 53 | pbeg=textKey; 54 | 55 | while ( ( pbeg + 1 < textEnd ) && ( retval < (ssize_t)keyLen ) ) 56 | { 57 | if ( 1 != sscanf( pbeg, "%02x", (unsigned int*)&octet ) ) 58 | { 59 | retval=-1; 60 | break; 61 | } 62 | 63 | *pout = (octet & 0xff); 64 | ++pout; 65 | ++retval; 66 | pbeg += 2; 67 | } 68 | 69 | return retval; 70 | } 71 | 72 | 73 | static int parseKeyLine( n2n_cipherspec_t * spec, 74 | const char * linein ) 75 | { 76 | /* parameters are separated by whitespace */ 77 | char line[N2N_KEYFILE_LINESIZE]; 78 | char * lp=line; 79 | const char * token; 80 | strncpy( line, linein, N2N_KEYFILE_LINESIZE ); 81 | 82 | memset( spec, 0, sizeof( n2n_cipherspec_t ) ); 83 | 84 | /* decode valid_from time */ 85 | token = strsep( &lp, DELIMITERS ); 86 | if ( !token ) { goto error; } 87 | spec->valid_from = atol(token); 88 | 89 | /* decode valid_until time */ 90 | token = strsep( &lp, DELIMITERS ); 91 | if ( !token ) { goto error; } 92 | spec->valid_until = atol(token); 93 | 94 | /* decode the transform number */ 95 | token = strsep( &lp, DELIMITERS ); 96 | if ( !token ) { goto error; } 97 | spec->t = atoi(token); 98 | 99 | /* The reset if opaque key data */ 100 | token = strsep( &lp, DELIMITERS ); 101 | if ( !token ) { goto error; } 102 | strncpy( (char *)spec->opaque, token, N2N_MAX_KEYSIZE ); 103 | spec->opaque_size= (uint16_t) strlen( (char *)spec->opaque); 104 | 105 | return 0; 106 | 107 | error: 108 | return -1; 109 | } 110 | 111 | 112 | #define SEP "/" 113 | 114 | 115 | int validCipherSpec( const n2n_cipherspec_t * k, 116 | time_t now ) 117 | { 118 | if ( k->valid_until < k->valid_from ) { goto bad; } 119 | if ( k->valid_from > now ) { goto bad; } 120 | if ( k->valid_until < now ) { goto bad; } 121 | 122 | return 0; 123 | 124 | bad: 125 | return -1; 126 | } 127 | 128 | /* Read key control file and return the number of specs stored or a negative 129 | * error code. 130 | * 131 | * As the specs are read in the from and until time values are compared to 132 | * present time. Only those keys which are valid are stored. 133 | */ 134 | int n2n_read_keyfile( n2n_cipherspec_t * specs, /* fill out this array of cipherspecs */ 135 | size_t numspecs, /* number of slots in the array. */ 136 | const char * ctrlfile_path ) /* path to control file */ 137 | { 138 | /* Each line contains one cipherspec. */ 139 | 140 | int retval=0; 141 | FILE * fp=NULL; 142 | size_t idx=0; 143 | time_t now = time(NULL); 144 | 145 | traceEvent( TRACE_DEBUG, "Reading '%s'\n", ctrlfile_path ); 146 | 147 | fp = fopen( ctrlfile_path, "r" ); 148 | if ( fp ) 149 | { 150 | /* Read the file a line a time with fgets. */ 151 | char line[N2N_KEYFILE_LINESIZE]; 152 | size_t lineNum=0; 153 | 154 | while ( idx < numspecs ) 155 | { 156 | n2n_cipherspec_t * k = &(specs[idx]); 157 | fgets( line, N2N_KEYFILE_LINESIZE, fp ); 158 | ++lineNum; 159 | 160 | if ( strlen(line) > 1 ) 161 | { 162 | if ( 0 == parseKeyLine( k, line ) ) 163 | { 164 | if ( k->valid_until > now ) 165 | { 166 | traceEvent( TRACE_INFO, " --> [%u] from %lu, until %lu, transform=%hu, data=%s\n", 167 | idx, k->valid_from, k->valid_until, k->t, k->opaque ); 168 | 169 | ++retval; 170 | ++idx; 171 | } 172 | else 173 | { 174 | traceEvent( TRACE_INFO, " --X [%u] from %lu, until %lu, transform=%hu, data=%s\n", 175 | idx, k->valid_from, k->valid_until, k->t, k->opaque ); 176 | 177 | } 178 | } 179 | else 180 | { 181 | traceEvent( TRACE_WARNING, "Failed to decode line %u\n", lineNum ); 182 | } 183 | } 184 | 185 | if ( feof(fp) ) 186 | { 187 | break; 188 | } 189 | 190 | line[0]=0; /* this line has been consumed */ 191 | } 192 | 193 | fclose( fp); 194 | fp=NULL; 195 | } 196 | else 197 | { 198 | traceEvent( TRACE_ERROR, "Failed to open '%s'\n", ctrlfile_path ); 199 | retval = -1; 200 | } 201 | 202 | return retval; 203 | } 204 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(n2n C) 2 | cmake_minimum_required(VERSION 3.7) 3 | 4 | # N2n information 5 | set(N2N_VERSION 2.3.0) 6 | set(N2N_OSNAME ${CMAKE_SYSTEM_NAME}) 7 | 8 | add_definitions(-DN2N_VERSION=\"${N2N_VERSION}\" -DN2N_OSNAME=\"${N2N_OSNAME}\") 9 | 10 | # N2n specific params 11 | if(NOT DEFINED N2N_OPTION_AES) 12 | set(N2N_OPTION_AES OFF) 13 | endif(NOT DEFINED N2N_OPTION_AES) 14 | 15 | if(N2N_OPTION_AES) 16 | add_definitions(-DN2N_HAVE_AES) 17 | endif(N2N_OPTION_AES) 18 | 19 | if(USE_GCRYPT) 20 | add_definitions(-DUSE_GCRYPT=1) 21 | set(CRYPTO_LIB gcrypt) 22 | elseif(USE_NETTLE) 23 | add_definitions(-DUSE_NETTLE=1) 24 | set(CRYPTO_LIB nettle) 25 | elseif(USE_MBEDTLS) 26 | add_definitions(-DUSE_MBEDTLS=1) 27 | set(CRYPTO_LIB mbedcrypto) 28 | elseif(USE_OPENSSL) 29 | add_definitions(-DUSE_OPENSSL=1) 30 | set(CRYPTO_LIB crypto) 31 | elseif(USE_ELL) 32 | add_definitions(-DUSE_ELL=1) 33 | set(CRYPTO_LIB dl ell) 34 | elseif(DEFINED WIN32) 35 | add_definitions(-DUSE_BCRYPT=1) 36 | set(CRYPTO_LIB bcrypt) 37 | endif() 38 | 39 | # Build information 40 | if(NOT DEFINED BUILD_SHARED_LIBS) 41 | set(BUILD_SHARED_LIBS OFF) 42 | endif(NOT DEFINED BUILD_SHARED_LIBS) 43 | 44 | if(NOT DEFINED CMAKE_BUILD_TYPE) 45 | set(CMAKE_BUILD_TYPE None) 46 | endif(NOT DEFINED CMAKE_BUILD_TYPE) 47 | #set(CMAKE_BUILD_TYPE Debug) 48 | #set(CMAKE_BUILD_TYPE Release) 49 | 50 | #Ultrasparc64 users experiencing SIGBUS should try the following gcc options 51 | #(thanks to Robert Gibbon) 52 | #PLATOPTS_SPARC64=-mcpu=ultrasparc -pipe -fomit-frame-pointer -ffast-math -finline-functions -fweb -frename-registers -mapp-regs 53 | 54 | ## DEBUG FOR CMAKE 55 | #message(${N2N_VERSION}) 56 | #message(${N2N_OSNAME}) 57 | ##message(${CMAKE_BUILD_TYPE}) 58 | #message(${N2N_OPTION_AES}) 59 | ## DEBUG FOR CMAKE 60 | 61 | add_library(n2n OBJECT 62 | n2n.c 63 | wire.c 64 | version.c 65 | ) 66 | set_property(TARGET n2n PROPERTY C_STANDARD 99) 67 | set(OBJECTS $) 68 | 69 | if(DEFINED WIN32) 70 | set(CMAKE_RC_FLAGS /nologo) 71 | if (MSVC) 72 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4477 /wd4267 /utf-8") 73 | add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE) 74 | endif(MSVC) 75 | 76 | add_subdirectory(win32) 77 | set(OBJECTS 78 | ${OBJECTS} 79 | $ 80 | ${CMAKE_CURRENT_SOURCE_DIR}/win32/application.manifest 81 | ) 82 | set(EDGE_RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/win32/edge.rc ) 83 | set(SN_RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/win32/sn.rc ) 84 | 85 | else(DEFINED WIN32) 86 | 87 | set(EDGE_RESOURCE ) 88 | set(SN_RESOURCE ) 89 | 90 | endif(DEFINED WIN32) 91 | 92 | add_executable(edge 93 | edge.c 94 | aes.c 95 | twofish.c 96 | transform_null.c 97 | transform_tf.c 98 | transform_aes.c 99 | n2n_keyfile.c 100 | minilzo.c 101 | tuntap_freebsd.c 102 | tuntap_netbsd.c 103 | tuntap_linux.c 104 | tuntap_osx.c 105 | ${OBJECTS} ${EDGE_RESOURCE} 106 | ) 107 | if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") 108 | target_link_libraries(edge cap) 109 | endif() 110 | set_property(TARGET edge PROPERTY C_STANDARD 99) 111 | 112 | add_executable(supernode 113 | sn.c 114 | ${OBJECTS} ${SN_RESOURCE} 115 | ) 116 | set_property(TARGET supernode PROPERTY C_STANDARD 99) 117 | 118 | if(DEFINED WIN32) 119 | set_target_properties(edge PROPERTIES LINK_FLAGS "/manifestuac:level='requireAdministrator'") 120 | add_custom_command( 121 | TARGET supernode 122 | POST_BUILD 123 | COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/win32/install.ps1" "${CMAKE_CURRENT_BINARY_DIR}/install.ps1" 124 | DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/win32/install.ps1" 125 | ) 126 | endif(DEFINED WIN32) 127 | 128 | # For Solaris (or OpenSolaris?) 129 | #target_link_libraries(edge socket nsl) 130 | #target_link_libraries(supernode socket nsl) 131 | 132 | if(N2N_OPTION_AES) 133 | target_link_libraries(edge ${CRYPTO_LIB}) 134 | endif(N2N_OPTION_AES) 135 | 136 | if(NOT DEFINED WIN32) 137 | #add_executable(test test.c) 138 | #target_link_libraries(test n2n) 139 | 140 | #add_executable(benchmark benchmark.c) 141 | #target_link_libraries(benchmark n2n) 142 | endif(NOT DEFINED WIN32) 143 | 144 | install(TARGETS edge supernode 145 | RUNTIME DESTINATION sbin 146 | LIBRARY DESTINATION lib 147 | ARCHIVE DESTINATION lib 148 | ) 149 | 150 | # Documentation 151 | if(DEFINED UNIX) 152 | add_dependencies(n2n doc) 153 | file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/doc) 154 | add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/edge.8.gz 155 | COMMAND gzip -c ${PROJECT_SOURCE_DIR}/edge.troff > ${PROJECT_BINARY_DIR}/doc/edge.8.gz 156 | DEPENDS ${PROJECT_SOURCE_DIR}/edge.troff 157 | ) 158 | 159 | add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/supernode.1.gz 160 | COMMAND gzip -c ${PROJECT_SOURCE_DIR}/supernode.troff > ${PROJECT_BINARY_DIR}/doc/supernode.1.gz 161 | DEPENDS ${PROJECT_SOURCE_DIR}/supernode.troff 162 | ) 163 | 164 | add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz 165 | COMMAND gzip -c ${PROJECT_SOURCE_DIR}/n2n_v2.troff > ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz 166 | DEPENDS ${PROJECT_SOURCE_DIR}/n2n_v2.troff 167 | ) 168 | 169 | add_custom_target(doc DEPENDS ${PROJECT_BINARY_DIR}/doc/edge.8.gz 170 | ${PROJECT_BINARY_DIR}/doc/supernode.1.gz 171 | ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz 172 | ) 173 | 174 | set_source_files_properties(${PROJECT_BINARY_DIR}/doc/edge.8.gz 175 | ${PROJECT_BINARY_DIR}/doc/supernode.1.gz 176 | ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz 177 | PROPERTIES GENERATED 1) 178 | 179 | install(FILES ${PROJECT_BINARY_DIR}/doc/edge.8.gz 180 | DESTINATION /usr/share/man8) 181 | install(FILES ${PROJECT_BINARY_DIR}/doc/supernode.1.gz 182 | DESTINATION /usr/share/man1) 183 | install(FILES ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz 184 | DESTINATION /usr/share/man7) 185 | endif(DEFINED UNIX) 186 | -------------------------------------------------------------------------------- /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_v2.troff: -------------------------------------------------------------------------------- 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 | .TP 43 | .B (3) AES-CBC 44 | AES in CBC mode with 256-bit key. 45 | .P 46 | The following additional ciphers are specified but not yet implemented: 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 | edge(8) supernode(1) 157 | -------------------------------------------------------------------------------- /win32/scm_service.c: -------------------------------------------------------------------------------- 1 | #include "../n2n.h" 2 | #include "n2n_win32.h" 3 | 4 | #ifdef _WIN32 5 | 6 | static SERVICE_STATUS_HANDLE service_status_handle; 7 | static SERVICE_STATUS service_status; 8 | 9 | HANDLE event_log = INVALID_HANDLE_VALUE; 10 | 11 | static bool scm_startup_complete = false; 12 | 13 | extern int main(int argc, char* argv[]); 14 | 15 | int scm_start_service(uint32_t, wchar_t**); 16 | 17 | wchar_t scm_name[_SCM_NAME_LENGTH]; 18 | 19 | int scm_startup(wchar_t* name) { 20 | wcsncpy(scm_name, name, _SCM_NAME_LENGTH); 21 | 22 | SERVICE_TABLE_ENTRYW dispatch_table[] = 23 | { 24 | { scm_name, (LPSERVICE_MAIN_FUNCTIONW) scm_start_service }, 25 | { NULL, NULL } 26 | }; 27 | 28 | if (scm_startup_complete) { 29 | return 0; 30 | } 31 | 32 | scm_startup_complete = true; 33 | 34 | if (!StartServiceCtrlDispatcherW(dispatch_table)) { 35 | if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { 36 | /* not running as a service */ 37 | return 0; 38 | } else { 39 | exit(1); 40 | } 41 | } 42 | 43 | return 1; 44 | } 45 | 46 | static void ReportSvcStatus(uint32_t dwCurrentState, uint32_t dwWin32ExitCode, uint32_t dwWaitHint) { 47 | service_status.dwCurrentState = dwCurrentState; 48 | service_status.dwWin32ExitCode = dwWin32ExitCode; 49 | service_status.dwWaitHint = dwWaitHint; 50 | 51 | if (dwCurrentState == SERVICE_START_PENDING) 52 | service_status.dwControlsAccepted = 0; 53 | else 54 | service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP; 55 | 56 | if ((dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED)) 57 | service_status.dwCheckPoint = 0; 58 | else 59 | service_status.dwCheckPoint = 1; 60 | 61 | SetServiceStatus(service_status_handle, &service_status); 62 | } 63 | 64 | static VOID WINAPI service_handler(DWORD dwControl) { 65 | switch (dwControl) { 66 | case SERVICE_CONTROL_STOP: { 67 | ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 500); 68 | ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0); 69 | return; 70 | } 71 | case SERVICE_CONTROL_INTERROGATE: 72 | break; 73 | default: 74 | break; 75 | } 76 | 77 | ReportSvcStatus(service_status.dwCurrentState, NO_ERROR, 0); 78 | } 79 | 80 | #define REGKEY_TEMPLATE L"SOFTWARE\\n2n" 81 | 82 | int get_argv_from_registry(wchar_t* scm_name, char*** argv) { 83 | #define ARGUMENT_LENGTH 4048 84 | wchar_t regpath[1024]; 85 | HKEY key; 86 | 87 | swprintf(regpath, sizeof(regpath), REGKEY_TEMPLATE "\\%s", scm_name); 88 | 89 | if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key)) { 90 | W32_ERROR(GetLastError(), error) 91 | traceEvent(TRACE_ERROR, "Could not open key HKLM\\%ls: %ls", regpath, error); 92 | W32_ERROR_FREE(error) 93 | return 0; 94 | } 95 | 96 | wchar_t data[ARGUMENT_LENGTH]; 97 | uint32_t len = ARGUMENT_LENGTH; 98 | uint32_t type = 0; 99 | if (RegGetValue(key, NULL, L"Arguments", RRF_RT_REG_SZ | RRF_RT_REG_MULTI_SZ, &type, &data, &len)) { 100 | W32_ERROR(GetLastError(), error) 101 | traceEvent(TRACE_ERROR, "Registry key HKLM\\%ls has no string value 'Arguments': %ls", regpath, error); 102 | W32_ERROR_FREE(error); 103 | return 0; 104 | } 105 | 106 | int maxargc = 16; 107 | int argc = 0; 108 | *argv = (char**) malloc(maxargc * sizeof(char*)); 109 | size_t buffer_size = (wcslen(scm_name) + 1); 110 | (*argv)[argc] = malloc(buffer_size); 111 | wcstombs((*argv)[argc], scm_name, buffer_size); 112 | argc++; 113 | 114 | if (type == REG_SZ) { 115 | wchar_t* buffer = data; 116 | wchar_t* buff = buffer; 117 | while(buff) { 118 | wchar_t* p = wcschr(buff, L' '); 119 | if (p) { 120 | *p = L'\0'; 121 | buffer_size = (wcslen(buff) + 1); 122 | (*argv)[argc] = malloc(buffer_size); 123 | wcstombs((*argv)[argc], buff, buffer_size); 124 | argc++; 125 | while(*++p == ' ' && *p != '\0'); 126 | buff = p; 127 | if (argc >= maxargc) { 128 | maxargc *= 2; 129 | *argv = (char **) realloc(*argv, maxargc * sizeof(char*)); 130 | if (*argv == NULL) { 131 | traceEvent(TRACE_ERROR, "Unable to re-allocate memory"); 132 | return 0; 133 | } 134 | } 135 | } else { 136 | buffer_size = (wcslen(buff) + 1); 137 | (*argv)[argc] = malloc(buffer_size); 138 | wcstombs((*argv)[argc], buff, buffer_size); 139 | argc++; 140 | break; 141 | } 142 | } 143 | } else if (type == REG_MULTI_SZ) { 144 | wchar_t* buffer = data; 145 | 146 | while(*buffer) { 147 | buffer_size = (wcslen(buffer) + 1); 148 | (*argv)[argc] = malloc(buffer_size); 149 | wcstombs((*argv)[argc], buffer, buffer_size); 150 | argc++; 151 | if (argc >= maxargc) { 152 | maxargc *= 2; 153 | *argv = (char **) realloc(*argv, maxargc * sizeof(char*)); 154 | if (*argv == NULL) { 155 | traceEvent(TRACE_ERROR, "Unable to re-allocate memory"); 156 | return 0; 157 | } 158 | } 159 | buffer = buffer + buffer_size; 160 | } 161 | } else { 162 | traceEvent(TRACE_ERROR, "Registry value HKLM\\%ls\\Arguments is of unknown type %u", regpath, type); 163 | } 164 | 165 | RegCloseKey(key); 166 | 167 | return argc; 168 | } 169 | 170 | int scm_start_service(uint32_t num, wchar_t** args) { 171 | wcsncpy(scm_name, args[0], _SCM_NAME_LENGTH); 172 | 173 | service_status_handle = RegisterServiceCtrlHandlerW(scm_name, service_handler); 174 | event_log = RegisterEventSource(NULL, scm_name); 175 | 176 | ZeroMemory(&service_status, sizeof(service_status)); 177 | service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 178 | ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 300); 179 | ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); 180 | 181 | char** argv = NULL; 182 | int argc = get_argv_from_registry(scm_name, &argv); 183 | 184 | if (!argv) { 185 | ReportSvcStatus(SERVICE_STOP_PENDING, ERROR_BAD_CONFIGURATION, 500); 186 | ReportSvcStatus(SERVICE_STOPPED, ERROR_BAD_CONFIGURATION, 0); 187 | return -1; 188 | } else { 189 | /* 190 | * note that memory allocated for argv WILL leak, but the program 191 | * exits directly after running main, so ... 192 | */ 193 | return main(argc, argv); 194 | } 195 | } 196 | 197 | #endif /* _WIN32 */ 198 | -------------------------------------------------------------------------------- /aes.c: -------------------------------------------------------------------------------- 1 | #ifdef N2N_HAVE_AES 2 | 3 | #include "aes.h" 4 | 5 | /* Return the best acceptable AES key size (in bytes) given an input keysize. 6 | * 7 | * The value returned will be one of AES128_KEY_BYTES, AES192_KEY_BYTES or 8 | * AES256_KEY_BYTES. 9 | */ 10 | #if USE_OPENSSL 11 | static const EVP_CIPHER* n2n_aes_best_keysize(size_t numBytes) 12 | { 13 | if (numBytes >= AES256_KEY_BYTES ) 14 | { 15 | return EVP_aes_256_cbc(); 16 | } 17 | else if (numBytes >= AES192_KEY_BYTES) 18 | { 19 | return EVP_aes_192_cbc(); 20 | } 21 | else 22 | { 23 | return EVP_aes_128_cbc(); 24 | } 25 | } 26 | #elif USE_GCRYPT 27 | static int n2n_aes_best_keysize(size_t numBytes) { 28 | if (numBytes >= AES256_KEY_BYTES ) 29 | { 30 | return GCRY_CIPHER_AES256; 31 | } 32 | else if (numBytes >= AES192_KEY_BYTES) 33 | { 34 | return GCRY_CIPHER_AES192; 35 | } 36 | else 37 | { 38 | return GCRY_CIPHER_AES128; 39 | } 40 | } 41 | #elif USE_BCRYPT || USE_NETTLE || USE_MBEDTLS || USE_ELL 42 | static uint32_t n2n_aes_best_keysize(size_t numBytes) { 43 | if (numBytes >= AES256_KEY_BYTES ) 44 | { 45 | return 32; 46 | } 47 | else if (numBytes >= AES192_KEY_BYTES) 48 | { 49 | return 24; 50 | } 51 | else 52 | { 53 | return 16; 54 | } 55 | } 56 | #endif 57 | 58 | void n2n_aes_init(cipher_ctx_t ctx) { 59 | #if USE_OPENSSL 60 | memset(ctx->key, 0, sizeof(ctx->key)); 61 | ctx->ctx = EVP_CIPHER_CTX_new(); 62 | #elif USE_NETTLE 63 | #elif USE_GCRYPT 64 | ctx->cipher = NULL; 65 | #elif USE_MBEDTLS 66 | mbedtls_cipher_init( &ctx->enc_ctx ); 67 | mbedtls_cipher_init( &ctx->dec_ctx ); 68 | #elif USE_ELL 69 | ctx->cipher = NULL; 70 | #elif USE_BCRYPT 71 | BCryptOpenAlgorithmProvider ( &ctx->hAlgorithm, BCRYPT_AES_ALGORITHM, NULL, 0 ); 72 | BCryptSetProperty ( ctx->hAlgorithm, BCRYPT_CHAINING_MODE, 73 | (uint8_t*) BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0 ); 74 | ctx->hKey = NULL; 75 | #endif 76 | } 77 | 78 | void n2n_aes_free(cipher_ctx_t ctx) { 79 | #if USE_OPENSSL 80 | EVP_CIPHER_CTX_free( ctx->ctx ); 81 | #elif USE_GCRYPT 82 | if (ctx->cipher) 83 | gcry_cipher_close( ctx->cipher ); 84 | #elif USE_MBEDTLS 85 | mbedtls_cipher_free( &ctx->enc_ctx ); 86 | mbedtls_cipher_free( &ctx->dec_ctx ); 87 | #elif USE_ELL 88 | if ( ctx->cipher ) 89 | l_cipher_free( ctx->cipher ); 90 | #elif USE_BCRYPT 91 | if ( ctx->hKey ) 92 | BCryptDestroyKey( ctx->hKey ); 93 | BCryptCloseAlgorithmProvider( ctx->hAlgorithm, 0 ); 94 | #endif 95 | } 96 | 97 | uint8_t n2n_aes_set_key(cipher_ctx_t ctx, const uint8_t* key, size_t length) { 98 | #if USE_OPENSSL 99 | ctx->cipher = n2n_aes_best_keysize(length); 100 | unsigned int key_length = EVP_CIPHER_key_length(ctx->cipher); 101 | memcpy(ctx->key, key, key_length); 102 | #elif USE_NETTLE 103 | uint32_t key_length = n2n_aes_best_keysize(length); 104 | switch (key_length) { 105 | case 32: 106 | aes256_set_encrypt_key((struct aes256_ctx*) &ctx->enc_ctx, key); 107 | aes256_set_decrypt_key((struct aes256_ctx*) &ctx->dec_ctx, key); 108 | ctx->enc_fun = (nettle_cipher_func*) aes256_encrypt; 109 | ctx->dec_fun = (nettle_cipher_func*) aes256_decrypt; 110 | break; 111 | case 24: 112 | aes192_set_encrypt_key((struct aes192_ctx*) &ctx->enc_ctx, key); 113 | aes192_set_decrypt_key((struct aes192_ctx*) &ctx->dec_ctx, key); 114 | ctx->enc_fun = (nettle_cipher_func*) aes192_encrypt; 115 | ctx->dec_fun = (nettle_cipher_func*) aes192_decrypt; 116 | break; 117 | case 16: 118 | aes128_set_encrypt_key((struct aes128_ctx*) &ctx->enc_ctx, key); 119 | aes128_set_decrypt_key((struct aes128_ctx*) &ctx->dec_ctx, key); 120 | ctx->enc_fun = (nettle_cipher_func*) aes128_encrypt; 121 | ctx->dec_fun = (nettle_cipher_func*) aes128_decrypt; 122 | break; 123 | default: 124 | break; 125 | } 126 | #elif USE_GCRYPT 127 | if (ctx->cipher) 128 | gcry_cipher_close( ctx->cipher ); 129 | int _algo = n2n_aes_best_keysize(length); 130 | unsigned int key_length = gcry_cipher_get_algo_keylen ( _algo ); 131 | gcry_cipher_open ( &ctx->cipher, _algo, GCRY_CIPHER_MODE_CBC, 0 ); 132 | gcry_cipher_setkey ( ctx->cipher, key, key_length ); 133 | #elif USE_MBEDTLS 134 | uint32_t key_length = n2n_aes_best_keysize(length); 135 | const mbedtls_cipher_info_t* _algo = mbedtls_cipher_info_from_values( 136 | MBEDTLS_CIPHER_ID_AES, (int) key_length, MBEDTLS_MODE_CBC); 137 | mbedtls_cipher_reset( &ctx->enc_ctx ); 138 | mbedtls_cipher_setup( &ctx->enc_ctx, _algo ); 139 | mbedtls_cipher_setkey( &ctx->enc_ctx, key, (int) key_length, MBEDTLS_ENCRYPT ); 140 | mbedtls_cipher_set_padding_mode( &ctx->enc_ctx, MBEDTLS_PADDING_NONE ); 141 | mbedtls_cipher_reset( &ctx->dec_ctx ); 142 | mbedtls_cipher_setup( &ctx->dec_ctx, _algo ); 143 | mbedtls_cipher_setkey( &ctx->dec_ctx, key, (int) key_length, MBEDTLS_DECRYPT ); 144 | mbedtls_cipher_set_padding_mode( &ctx->dec_ctx, MBEDTLS_PADDING_NONE ); 145 | #elif USE_ELL 146 | uint32_t key_length = n2n_aes_best_keysize(length); 147 | ctx->cipher = l_cipher_new( L_CIPHER_AES_CBC, key, key_length ); 148 | #elif USE_BCRYPT 149 | if (ctx->hKey != NULL) 150 | BCryptDestroyKey ( ctx->hKey ); 151 | uint32_t key_length = n2n_aes_best_keysize(length) * 8; 152 | BCryptSetProperty( ctx->hAlgorithm, BCRYPT_KEY_LENGTH, (uint8_t*) &key_length, sizeof(uint32_t), 0 ); 153 | key_length /= 8; 154 | BCryptGenerateSymmetricKey( ctx->hAlgorithm, &ctx->hKey, NULL, 0, (uint8_t*) key, key_length, 0 ); 155 | #endif 156 | return key_length; 157 | } 158 | 159 | void n2n_aes_encrypt(cipher_ctx_t ctx, const uint8_t* iv, const uint8_t* in, uint8_t* out, size_t length) { 160 | #if USE_OPENSSL 161 | int res_length = -1; 162 | EVP_CIPHER_CTX_reset( ctx->ctx ); 163 | EVP_EncryptInit( ctx->ctx, ctx->cipher, ctx->key, iv ); 164 | EVP_CIPHER_CTX_set_padding( ctx->ctx, 0 ); 165 | EVP_EncryptUpdate( ctx->ctx, out, &res_length, in, length ); 166 | EVP_EncryptFinal( ctx->ctx, out + res_length, &res_length ); 167 | #elif USE_NETTLE 168 | cbc_encrypt(&ctx->enc_ctx, (nettle_cipher_func*) ctx->enc_fun, AES_BLOCK_SIZE, (uint8_t*) iv, length, out, in); 169 | #elif USE_GCRYPT 170 | gcry_cipher_reset( ctx->cipher ); 171 | gcry_cipher_setiv( ctx->cipher, iv, AES_BLOCK_SIZE ); 172 | gcry_cipher_encrypt( ctx->cipher, out, length, in, length ); 173 | #elif USE_MBEDTLS 174 | size_t res_length = res_length; 175 | mbedtls_cipher_crypt( &ctx->enc_ctx, iv, AES_BLOCK_SIZE, in, length, out, &res_length ); 176 | #elif USE_ELL 177 | l_cipher_set_iv( ctx->cipher, iv, AES_BLOCK_SIZE ); 178 | l_cipher_encrypt( ctx->cipher, in, out, length ); 179 | #elif USE_BCRYPT 180 | uint32_t res_length = length; 181 | BCryptEncrypt( ctx->hKey, (uint8_t*) in, (uint32_t) length, NULL, (uint8_t*) iv, AES_BLOCK_SIZE, out, res_length, &res_length, 0 ); 182 | #endif 183 | } 184 | 185 | void n2n_aes_decrypt(cipher_ctx_t ctx, const uint8_t* iv, const uint8_t* in, uint8_t* out, size_t length) { 186 | #if USE_OPENSSL 187 | int res_length = -1; 188 | EVP_CIPHER_CTX_reset(ctx->ctx); 189 | EVP_DecryptInit( ctx->ctx, ctx->cipher, ctx->key, iv); 190 | EVP_CIPHER_CTX_set_padding(ctx->ctx, 0); 191 | EVP_DecryptUpdate( ctx->ctx, out, &res_length, in, length ); 192 | EVP_DecryptFinal( ctx->ctx, out + res_length, &res_length ); 193 | #elif USE_NETTLE 194 | cbc_decrypt(&ctx->dec_ctx, (nettle_cipher_func*) ctx->dec_fun, AES_BLOCK_SIZE, (uint8_t*) iv, length, out, in); 195 | #elif USE_GCRYPT 196 | gcry_cipher_reset( ctx->cipher ); 197 | gcry_cipher_setiv( ctx->cipher, iv, AES_BLOCK_SIZE ); 198 | gcry_cipher_decrypt( ctx->cipher, out, length, in, length ); 199 | #elif USE_MBEDTLS 200 | size_t res_length = 0; 201 | mbedtls_cipher_crypt( &ctx->dec_ctx, iv, AES_BLOCK_SIZE, in, length, out, &res_length ); 202 | #elif USE_ELL 203 | l_cipher_set_iv( ctx->cipher, iv, AES_BLOCK_SIZE ); 204 | l_cipher_decrypt( ctx->cipher, in, out, length ); 205 | #elif USE_BCRYPT 206 | uint32_t res_length = length; 207 | BCryptDecrypt( ctx->hKey, (uint8_t*) in, (uint32_t) length, NULL, (uint8_t*) iv, AES_BLOCK_SIZE,out, res_length, &res_length, 0 ); 208 | #endif 209 | } 210 | 211 | #endif // N2N_HAVE_AES 212 | -------------------------------------------------------------------------------- /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 | #if defined(__APPLE__) && defined(__MACH__) 28 | #define _DARWIN_ 29 | #endif 30 | 31 | /* Moved here to define _CRT_SECURE_NO_WARNINGS before all the including takes place */ 32 | #if defined(_WIN32) 33 | #undef N2N_HAVE_DAEMON 34 | #undef N2N_HAVE_SETUID 35 | 36 | /* windows can't name an interface, but we can tell edge which to use */ 37 | #define N2N_CAN_NAME_IFACE 1 38 | 39 | #else 40 | /* Some capability defaults which can be reset for particular platforms. */ 41 | #define N2N_HAVE_DAEMON 1 42 | #define N2N_HAVE_SETUID 1 43 | #ifdef __linux__ 44 | #define N2N_CAN_NAME_IFACE 1 45 | #define N2N_HAS_CAPABILITIES 1 46 | #endif 47 | #endif 48 | 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #ifndef _WIN32 56 | #include 57 | #endif 58 | 59 | #ifndef _MSC_VER 60 | #include 61 | #endif /* #ifndef _MSC_VER */ 62 | 63 | #include 64 | #include 65 | #include 66 | 67 | #ifndef _WIN32 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | #include 74 | 75 | #ifdef __linux__ 76 | #include 77 | #include 78 | #include 79 | #include 80 | #include 81 | #endif /* #ifdef __linux__ */ 82 | 83 | #ifdef __FreeBSD__ 84 | #include 85 | #endif /* #ifdef __FreeBSD__ */ 86 | 87 | #include 88 | #include 89 | 90 | #ifdef __sun__ 91 | #undef N2N_HAVE_DAEMON 92 | #endif /* #ifdef __sun__ */ 93 | 94 | #include 95 | #include 96 | #include 97 | #include 98 | #include 99 | #include 100 | #include 101 | #include 102 | #include 103 | 104 | #define closesocket(a) close(a) 105 | #endif /* #ifndef _WIN32 */ 106 | 107 | #define ETH_ADDR_LEN 6 108 | 109 | #if defined(_MSC_VER) 110 | #pragma pack(push,1) 111 | #endif 112 | struct ether_hdr 113 | { 114 | uint8_t dhost[ETH_ADDR_LEN]; 115 | uint8_t shost[ETH_ADDR_LEN]; 116 | /* higher layer protocol encapsulated */ 117 | uint16_t type; 118 | } 119 | #if defined(__GNUC__) 120 | __attribute__ ((__packed__)); 121 | #elif defined(_MSC_VER) 122 | ; 123 | #pragma pack(pop) 124 | #endif 125 | 126 | typedef struct ether_hdr ether_hdr_t; 127 | 128 | #include 129 | #include 130 | 131 | #ifdef __GNUC__ 132 | #define _unused_ __attribute__((unused)) 133 | #else 134 | #define _unused_ 135 | #endif 136 | 137 | #ifdef WIN32 138 | #include "win32/wintap.h" 139 | #endif /* #ifdef _WIN32 */ 140 | 141 | #include "n2n_wire.h" 142 | 143 | typedef struct route { 144 | int family; 145 | uint8_t dest[IPV6_SIZE]; 146 | uint8_t prefixlen; 147 | uint8_t gateway[IPV6_SIZE]; 148 | } route; 149 | 150 | /* N2N_IFNAMSIZ is needed on win32 even if dev_name is not used after declaration */ 151 | #ifndef _WIN32 152 | #define N2N_IFNAMSIZ 16 /* 15 chars * NULL */ 153 | 154 | typedef struct tuntap_dev { 155 | int fd; 156 | uint8_t mac_addr[6]; 157 | uint32_t ip_addr; 158 | uint8_t ip_prefixlen; 159 | struct in6_addr ip6_addr; 160 | uint8_t ip6_prefixlen; 161 | uint32_t mtu; 162 | char dev_name[N2N_IFNAMSIZ]; 163 | uint8_t routes_count; 164 | route* routes; 165 | } tuntap_dev; 166 | 167 | #define SOCKET int 168 | #endif /* #ifndef _WIN32 */ 169 | 170 | struct tuntap_config { 171 | /* device configuration */ 172 | char* if_name; 173 | n2n_mac_t device_mac; 174 | int mtu; 175 | /* ipv4 configuration */ 176 | bool dyn_ip4; 177 | in_addr_t ip_addr; 178 | uint8_t ip_prefixlen; 179 | /* ipv6 configuration */ 180 | struct in6_addr ip6_addr; 181 | uint8_t ip6_prefixlen; 182 | uint8_t routes_count; 183 | route* routes; 184 | }; 185 | 186 | #define QUICKLZ 1 187 | 188 | /* N2N packet header indicators. */ 189 | #define MSG_TYPE_REGISTER 1 190 | #define MSG_TYPE_DEREGISTER 2 191 | #define MSG_TYPE_PACKET 3 192 | #define MSG_TYPE_REGISTER_ACK 4 193 | #define MSG_TYPE_REGISTER_SUPER 5 194 | #define MSG_TYPE_REGISTER_SUPER_ACK 6 195 | #define MSG_TYPE_REGISTER_SUPER_NAK 7 196 | #define MSG_TYPE_FEDERATION 8 197 | 198 | /* Set N2N_COMPRESSION_ENABLED to 0 to disable lzo1x compression of ethernet 199 | * frames. Doing this will break compatibility with the standard n2n packet 200 | * format so do it only for experimentation. All edges must be built with the 201 | * same value if they are to understand each other. */ 202 | #define N2N_COMPRESSION_ENABLED 1 203 | 204 | #define DEFAULT_MTU 1400 205 | 206 | /** Common type used to hold stringified IP addresses. */ 207 | typedef char ipstr_t[INET6_ADDRSTRLEN]; 208 | 209 | /** Common type used to hold stringified MAC addresses. */ 210 | #define N2N_MACSTR_SIZE 32 211 | typedef char macstr_t[N2N_MACSTR_SIZE]; 212 | 213 | struct peer_info { 214 | struct peer_info * next; 215 | n2n_community_t community_name; 216 | n2n_mac_t mac_addr; 217 | n2n_sock_t sock; 218 | time_t last_seen; 219 | }; 220 | 221 | struct n2n_edge; /* defined in edge.c */ 222 | typedef struct n2n_edge n2n_edge_t; 223 | 224 | 225 | /* ************************************** */ 226 | 227 | #define TRACE_ERROR 0, __FILE__, __LINE__ 228 | #define TRACE_WARNING 1, __FILE__, __LINE__ 229 | #define TRACE_NORMAL 2, __FILE__, __LINE__ 230 | #define TRACE_INFO 3, __FILE__, __LINE__ 231 | #define TRACE_DEBUG 4, __FILE__, __LINE__ 232 | 233 | /* ************************************** */ 234 | 235 | #define SUPERNODE_IP "127.0.0.1" 236 | #define SUPERNODE_PORT 7654 237 | 238 | /* ************************************** */ 239 | 240 | #ifndef max 241 | #define max(a, b) ((a < b) ? b : a) 242 | #endif 243 | 244 | #ifndef min 245 | #define min(a, b) ((a > b) ? b : a) 246 | #endif 247 | 248 | /* ************************************** */ 249 | 250 | /* Variables */ 251 | /* extern TWOFISH *tf; */ 252 | extern int traceLevel; 253 | extern bool useSyslog; 254 | extern bool useSystemd; 255 | extern const uint8_t broadcast_addr[6]; 256 | extern const uint8_t multicast_addr[6]; 257 | 258 | /* Functions */ 259 | extern void traceEvent(int eventTraceLevel, char* file, int line, char * format, ...); 260 | extern int tuntap_open(tuntap_dev *device, struct tuntap_config* config); 261 | extern ssize_t tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, size_t len); 262 | extern ssize_t tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, size_t len); 263 | extern void tuntap_close(struct tuntap_dev *tuntap); 264 | extern void tuntap_get_address(struct tuntap_dev *tuntap); 265 | 266 | extern SOCKET open_socket(uint16_t local_port, int bind_any); 267 | extern SOCKET open_socket6(uint16_t local_port, int bind_any); 268 | #ifndef _WIN32 269 | extern SOCKET open_socket_unix(const char* path, mode_t access); 270 | #endif // _WIN32 271 | 272 | extern char* macaddr_str(macstr_t buf, const n2n_mac_t mac); 273 | extern char * sock_to_cstr( n2n_sock_str_t out, 274 | const n2n_sock_t * sock ); 275 | 276 | extern uint32_t ip4_prefixlen_to_netmask(uint8_t prefixlen); 277 | 278 | extern int sock_equal( const n2n_sock_t * a, 279 | const n2n_sock_t * b ); 280 | 281 | extern uint8_t is_multi_broadcast(const uint8_t * dest_mac); 282 | extern char* msg_type2str(uint16_t msg_type); 283 | extern void hexdump(const uint8_t * buf, size_t len); 284 | 285 | void print_n2n_version(); 286 | 287 | 288 | /* Operations on peer_info lists. */ 289 | struct peer_info * find_peer_by_mac( struct peer_info * list, 290 | const n2n_mac_t mac ); 291 | void peer_list_add( struct peer_info * * list, 292 | struct peer_info * element ); 293 | size_t peer_list_size( const struct peer_info * list ); 294 | size_t purge_peer_list( struct peer_info ** peer_list, 295 | time_t purge_before ); 296 | size_t clear_peer_list( struct peer_info ** peer_list ); 297 | size_t purge_expired_registrations( struct peer_info ** peer_list ); 298 | 299 | /* version.c */ 300 | extern char *n2n_sw_version, *n2n_sw_osName, *n2n_sw_buildDate; 301 | 302 | #endif /* _N2N_H_ */ 303 | -------------------------------------------------------------------------------- /edge.troff: -------------------------------------------------------------------------------- 1 | .TH edge 8 "May 19 2018" "n2n-2.2" "SUPERUSER COMMANDS" 2 | .SH NAME 3 | edge \- n2n edge node daemon 4 | .SH SYNOPSIS 5 | .B edge 6 | [\-d ] \-a [\-A ] \-c {\-k |\-K } 7 | [\-s ] [\-4|\-6] \-l 8 | [\-p ] [\-u ] [\-g ] [-f] [\-m ] [\-E] [\-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 interface name. Only available on Linux. 19 | .TP 20 | \-a {|static:|dhcp:0.0.0.0} 21 | sets the n2n virtual LAN IP address. 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 | \-A [/] 28 | set the n2n virtual LAN IPv6 address. Works only in conjunction with a set IPv4 address. 29 | The default is no set IPv6. The default prefix for an address is /64 but this can be changed 30 | by appending a prefix to the address. 31 | .B -A fdf0:dead:beef::102/48 32 | .TP 33 | \-b 34 | cause edge to perform hostname resolution for the supernode address each time 35 | the supernode is periodically contacted. This can cause reliability problems 36 | because all packet processing stops while the supernode address is resolved 37 | which might take 15 seconds. 38 | .TP 39 | \-c 40 | sets the n2n community name. All edges within the same community appear on the 41 | same LAN (layer 2 network segment). Community name is 16 bytes in length. A name 42 | smaller than this is padded with 0x00 bytes and a name longer than this is 43 | truncated to take the first 16 bytes. 44 | .TP 45 | \-h 46 | write usage then exit. 47 | .TP 48 | \-k 49 | sets the twofish encryption key from ASCII text (see also N2N_KEY in 50 | ENVIRONMENT). All edges communicating must use the same key and community 51 | name. If neither -k nor -K is used to specify a key source then edge uses 52 | cleartext mode (no encryption). The -k and -K options are mutually exclusive. 53 | .TP 54 | \-K 55 | Reads a key-schedule file and populates the internal transform 56 | operations with the data found there. This mechanism allows keys to roll at 57 | pre-determined times for a group of hosts. Accurate time synchronisation is not 58 | required as older keys can be decoded for some time after expiry. If neither -k 59 | nor -K is used to specify a key source then edge uses cleartext mode (no 60 | encryption). The -k and -K options are mutually exclusive. 61 | .TP 62 | \-l : 63 | sets the n2n supernode IP address and port to register to. Up to 2 supernodes 64 | can be specified by two invocations of -l :. Also IPv6 addresses are 65 | possible, they have to be enclosed in square brackets, if the port is ommited the 66 | default 7654 is assumed. 67 | 68 | .B edge -l 203.0.113.21 -l [2001:db8:cafe:babe::fed0]:7654 69 | 70 | If a DNS name is provided it is resolved. Provide the \-b switch 71 | to periodically lookup the name, incase of a dynamic IP. 72 | .TP 73 | [\-4|\-6] 74 | limit resolving the supernode DNS name provided with \-k to either 75 | IPv4 or IPv6. If the supernode is provied using an numeric address, 76 | this parameter does nothing. The default is to not specify any protocol 77 | preference. 78 | .TP 79 | \-p 80 | binds edge to the given UDP port. Useful for keeping the same external socket 81 | across restarts of edge. This allows peer edges which know the edge socket to 82 | continue p2p operation without going back to the supernode. 83 | .TP 84 | \-t 85 | binds the edge management system to the given UDP port. Default 5644. Use this 86 | if you need to run multiple instance of edge; or something is bound to that 87 | port. 88 | .TP 89 | \-u 90 | causes the edge process to drop to the given user ID when privileges are no 91 | longer required (UNIX). 92 | .TP 93 | \-g 94 | causes the edge process to drop to the given group ID when privileges are no 95 | longer required (UNIX). 96 | .TP 97 | \-f 98 | disables daemon mode (UNIX) and causes edge to run in the foreground. 99 | .TP 100 | \-m 101 | start the TAP interface with the given MAC address. This is highly recommended 102 | as it means the same address will be used if edge stops and restarts. If this is 103 | not done, the ARP caches of all peers will be wrong and packets will not flow to 104 | this edge until the next ARP refresh. 105 | .TP 106 | \-M 107 | set the MTU of the edge interface in bytes. MTU is the largest packet fragment 108 | size allowed to be moved throught the interface. The default is 1400. 109 | .TP 110 | \-s 111 | set the netmask of edge interface in IPv4 dotted decimal notation. The default 112 | is 255.255.255.0 (ie. /24). 113 | .TP 114 | \-r 115 | enable IP packet forwarding/routing through the n2n virtual LAN. Without this 116 | option, IP packets arriving over n2n are dropped if not for the -a (or 117 | DHCP assigned) IP address of the edge interface. 118 | .TP 119 | \-E 120 | accept packets destined for multicast ethernet MAC addresses. These addresses 121 | are used in multicast ethernet. If this option is not present these multicast 122 | packets are discarded as most users do not need or 123 | understand them. 124 | 125 | ARP requests and IPv6 neighborhood discovery are not limited by this switch, 126 | these packages are always sent, as they are required for the clients to 127 | discover each other. 128 | .TP 129 | \-v 130 | more verbose logging (may be specified several times for more verbosity). 131 | .SH ENVIRONMENT 132 | .TP 133 | .B N2N_KEY 134 | set the encryption key so it is not visible on the command line 135 | .SH EXAMPLES 136 | .TP 137 | .B edge -f -d n2n0 -c mynetwork -k encryptme -u 99 -g 99 -m 00:DE:AD:BE:EF:01 -a 192.168.254.7 -l 123.121.120.119:7654 138 | 139 | Start edge with TAP device n2n0 on community "mynetwork" with community 140 | supernode at 123.121.120.119 UDP port 7654 and bind the locally used UDP port to 141 | 50001. Use "encryptme" as the single permanent shared encryption key. Assign MAC 142 | address 00:DE:AD:BE:EF:01 to the n2n interface and drop to user=99 and group=99 143 | after the TAP device is successfull configured. 144 | .PP 145 | Remove the \-f option to run edge as a daemon. 146 | .PP 147 | Somewhere else setup another edge with similar parameters, eg. 148 | 149 | .B edge -f -d n2n0 -c mynetwork -k encryptme -u 99 -g 99 -m 00:DE:AD:BE:EF:02 -a 192.168.254.5 -l 123.121.120.119:7654 150 | .PP 151 | Now you can ping from 192.168.254.5 to 192.168.254.7. 152 | .PP 153 | The MAC address (-m ) and virtual IP address (-a ) must be different 154 | on all edges in the same community. 155 | 156 | .SH LINUX CAPABILITIES 157 | Edge is aware of Linux 158 | .B capabilities(7) 159 | and drops all capabilities, after network setup. edge needs 160 | .B CAP_NET_ADMIN 161 | for network setup and 162 | .B CAP_SETUID 163 | and 164 | .B CAP_SETGID 165 | to change to a user/group if \-u and/or \-g was provided as a command line parameter. 166 | 167 | edge can run as any user by setting the set of permited capabilities to 168 | .B CAP_NET_ADMIN 169 | e.g., 170 | 171 | .B setcap cap_net_admin+p ./edge 172 | 173 | .SH IPv6 174 | When running in IPv6 mode (by using a IPv6 supernode), edge can only directly connect to other 175 | IPv6 edges directly. 176 | 177 | .SH KEY SCHEDULE FILES 178 | (See 179 | .B n2n_v2(7) 180 | for more details). 181 | 182 | The -K option reads a key schedule file. 183 | 184 | .B edge \-d n2n0 \-c mynetwork \-K /path/to/file \-u 99 \-g 99 \-m 00:DE:AD:BE:EF:01 \-a 192.168.254.5 \-p 50001 \-l 123.121.120.119:7654 185 | .PP 186 | 187 | The key schedule file consists of line, one per key in the schedule. The purpose 188 | of key schedules is to encourage regular changing of the encryption keys used by 189 | a community. The file structure also allows for full binary keys to be specified 190 | as compared to the ASCII keys allowed by the single key injection. Each key line 191 | consists of the following: 192 | 193 | .B 194 | 195 | and are ASCII decimal values of the UNIX times during which the 196 | key is valid. is the index of the transform that applies 197 | to. is some text which is parsed by the transform module to derive the 198 | key for that line. 199 | 200 | Supported values are: 201 | .TP 202 | 2 = TwoFish 203 | has the form _. eg. 204 | 205 | .B 1252327945 1252328305 2 602_3d7c7769b34b2a4812f8c0e9d87ce9 206 | 207 | This specifies security association number 602 and a 16-octet key of numeric 208 | value 0x3d7c7769b34b2a4812f8c0e9d87ce9. is a 32-bit unsigned integer which 209 | is used to identify the encryption key to the receiver. The SA number is sent 210 | unencrypted so the receiver may find the correct key from the key 211 | schedule. is up to 16 octets although shorter keys are allowed. 212 | 213 | .TP 214 | 3 = AES-CBC 215 | has the form _. Same rules as TwoFish. 216 | 217 | .SH CLEARTEXT MODE 218 | If neither 219 | .B -k 220 | nor 221 | .B -K 222 | is specified then edge uses cleartext mode. In cleartext mode there is no 223 | transform of the packet data it is simply encrypted. This is useful for 224 | debugging n2n as packet contents can be seen clearly. 225 | 226 | To prevent accidental exposure of data, edge only enters cleartext mode when no 227 | keying parameters are specified. In the case where keying parameters are 228 | specified but no valid keys can be determined, edge exits with an error at 229 | startup. If all keys become invalid while running, edge continues to encode 230 | using the last key that was valid. 231 | 232 | .SH MANAGEMENT INTERFACE 233 | Edge provides a very simple management system on UDP port 5644. Send a newline 234 | to receive a status output. Send 'reload' to cause re-read of the 235 | keyfile. Send 'stop' to cause edge to exit cleanly. 236 | 237 | .SH EXIT STATUS 238 | edge is a daemon and any exit is an error. 239 | .SH AUTHORS 240 | .TP 241 | Richard Andrews 242 | andrews (at) ntop.org - n2n-1 maintainer and main author of n2n-2 243 | .TP 244 | Luca Deri 245 | deri (at) ntop.org - original author of n2n 246 | .TP 247 | Don Bindner 248 | (--) - significant contributions to n2n-1 249 | .TP 250 | Max Resch 251 | 252 | .SH SEE ALSO 253 | supernode(1) n2n_v2(7) capabilities(7) 254 | -------------------------------------------------------------------------------- /HACKING: -------------------------------------------------------------------------------- 1 | file: HACKING 2 | 3 | Last updated: 2010-01-01 09:55 UTC 4 | 5 | -------- 6 | (C) 2008-2010 - Richard Andrews 7 | 8 | This program and document is free software; you can redistribute 9 | it and/or modify it under the terms of the GNU General Public License 10 | as published by the Free Software Foundation; either version 3 of the 11 | License, or (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program; if not see see 20 | 21 | -------- 22 | 23 | 24 | This file describes the internals of n2n. Read this before starting to modify 25 | the code. Because coding examples may be present in this document it is licensed 26 | under the GPL rather than FDL. 27 | 28 | 29 | SYMMETRIC NAT 30 | ------------- 31 | 32 | Symmetric NAT is a form of firewall NAT in which an UDP packets are only passed 33 | back to an inside host socket when the return packets originate from the outside 34 | socket to which the initiating UDP packets were sent. This means that when an 35 | inside host sends UDP to some outside socket; other hosts cannot piggyback on 36 | this opening in the firewall to send data to the inside host. 37 | 38 | When two inside hosts are both behind symmetric NAT, peer-to-peer packet 39 | exchange is not possible via n2n. These hosts will require the supernode to 40 | relay packets. 41 | 42 | 43 | ARP CACHE 44 | --------- 45 | 46 | n2n makes use of the host operating system's own ARP cache. Each edge node 47 | allocates a random MAC address to itself. This MAC is constant for the life of 48 | the edge process. ARP packets are passed around as broadcast ethernet packets 49 | over n2n and these packets cause the native ARP cache to be updated. 50 | 51 | Edge nodes send gratuitous ARP packets on startup. See GRATUITOUS ARP below. 52 | 53 | 54 | REGISTRATION AND PEER-TO-PEER COMMUNICATION SETUP 55 | ------------------------------------------------- 56 | 57 | A and B are edge nodes with public sockets Apub and Bpub; and private network 58 | addresses A and B respectively. S is the supernode. 59 | 60 | A sends {REGISTER,Amac} to S. S registers {Amac->Apub}. 61 | B sends {REGISTER,Bmac} to S. S registers {Bmac->Bpub}. 62 | 63 | Now ping from A to B. 64 | 65 | A sends broadcast "arp who-has B" to S. S relays the packet to all known edge 66 | nodes. B replies "B at Bmac" to supernode which forwards this to A. So now ping 67 | A->B is known to be ping Amac(A)->Bmac(B). Note: gratuitous arp also requires 68 | discussion. 69 | 70 | In response to receiving the arp reply, Apub sends {REGISTER,Amac} to Bpub. If 71 | Bpub receives the request it sends back {REGISTER_ACK,Amac} and also sends its 72 | own {REGISTER,Bmac} request. 73 | 74 | In response to receiving the "arp who-has", Bpub sends {REGISTER,Bmac} to Apub. 75 | 76 | Now the OS has received the arp reply and sends ICMP to Bmac(B) via the tunnel 77 | on A. A looks up Bmac in the peers list and encapsulates the packet to Bpub or 78 | the supernode if the MAC is not found. 79 | 80 | We assume that between two edge nodes, if Bpub receives a packet from Apub then 81 | Apub can receive a packet from Bpub. This is the symmetric NAT case. Note: In 82 | the symmetric NAT case, the public socket for a MAC address will be different 83 | for direct contact when compared to information from the supernode. 84 | 85 | When two edge nodes are both behind symmetric NAT they cannot establish direct 86 | communication. 87 | 88 | If A receives {REGISTER,Bmac} from B, A adds {Bmac->Bpub} to its peers list 89 | knowing that Bmac is now reachable via that public socket. Similarly if B 90 | receives {REGISTER,Amac} from A. 91 | 92 | The supernode never forwards REGISTER messages because the public socket seen by 93 | the supervisor for some edge (eg. A) may be different to the socket seen by 94 | another edge due to the actions of symmetric NAT (alocating a new public socket 95 | for the new outbound UDP "connection"). 96 | 97 | 98 | EDGE REGISTRATION DESIGN AMMENDMENTS (starting from 2008-04-10) 99 | ------------------------------------ 100 | 101 | * Send REGISTER on rx of PACKET or REGISTER only when dest_mac == device MAC 102 | (do not send REGISTER on Rx of broadcast packets). 103 | * After sending REGISTER add the new peer to pending_peers list; but 104 | * Don't send REGISTER to a peer in pending_peers list 105 | * Remove old entries from pending_peers at regular intervals 106 | * On rx of REGISTER_ACK, move peer from pending_peers to known_peers for direct 107 | comms and set last_seen=now 108 | * On rx of any packet set last_seen=now in the known_peers entry (if it 109 | exists); but do not add a new entry. 110 | * If the public socket address for a known_peers entry changes, deleted it and 111 | restart registration to the new peer. 112 | * Peer sockets provided by the supernode are ignored unless no other entry 113 | exists. Direct peer-to-peer sockets are always given more priority as the 114 | supernode socket will not be usable for direct contact if the peer is behind 115 | symmetric NAT. 116 | 117 | 118 | The pending_peers list concept is to prevent massive registration traffic when 119 | supernode relay is in force - this would occur if REGISTER was sent for every 120 | incident packet sent via supernode. Periodic REGISTER attempts will still occur; 121 | not for every received packet. In the case where the peer cannot be contacted 122 | (eg. both peers behind symmetric NAT), then there will still be periodic 123 | attempts. Suggest a pending timeout of about 60 sec. 124 | 125 | A peer is only considered operational for peer-to-peer sending when a 126 | REGISTER_ACK is returned. Once operational the peer is kept operational while 127 | any direct packet communications are occurring. REGISTER is not required to 128 | keep the path open through any firewalls; just some activity in one direction. 129 | 130 | After an idle period; the peer should be deleted from the known_peers list. We 131 | should not try to re-register when this time expires. If there is no data to 132 | send then forget the peer. This helps scalability. 133 | 134 | If a peer wants to be remembered it can send gratuitous ARP traffic which will 135 | keep its entry in the known_peers list of any peers which already have the 136 | entry. 137 | 138 | 139 | 140 | 141 | peer = find_by_src_mac( hdr, known_peers ); /* return NULL or entry */ 142 | 143 | if ( peer ) 144 | { 145 | peer_last_seen = time(NULL); 146 | } 147 | else 148 | { 149 | if ( ! is_broadcast( hdr ) ) /* ignore broadcasts */ 150 | { 151 | if ( IS_REGISTER_ACK( hdr ) ) 152 | { 153 | /* move from pending to known_peers */ 154 | set_peer_operational( hdr ); 155 | } 156 | else 157 | { 158 | /* add to pending and send REGISTER - ignore if in pending. */ 159 | try_send_register( hdr ) 160 | } 161 | } 162 | } 163 | 164 | 165 | (Notes): 166 | 167 | * In testing it was noted that if a symmetric NAT firewall shuts down the UDP 168 | association but the known_peers registration is still active, then the peer 169 | becomes unreachable until the known_peers registration is deleted. Suggest two 170 | ways to mitigate this problem: 171 | (a) make the known_peers purge timeout a config paramter; 172 | (b) send packets direct and via supernode if the registration is older than 173 | eg. 60 sec. 174 | 175 | 176 | GRATUITOUS ARP 177 | -------------- 178 | 179 | In addition to the ARP who-has mechanism noted above, two edge nodes can become 180 | aware of one another by gratuitous ARP. A gratuitous ARP packet is a broadcast 181 | packet sent by a node for no other purpose than to announce its presence and 182 | identify its MAC and IP address. Gratuitous ARP packets are to keep ARP caches 183 | up to date so contacting the host will be faster after an long idle time. 184 | 185 | 186 | MAN PAGES 187 | --------- 188 | 189 | Look at a non-installed man page like this (linux/UNIX): 190 | 191 | nroff -man edge.8 | less 192 | 193 | 194 | PACKET message FORMAT 195 | --------------------- 196 | 197 | All message encoding and decoding is contained in wire.c. The PACKET message is 198 | of main concern as it is the most frequently transferred as it contains 199 | encapsulated ethernet packets. 200 | 201 | Version 2 202 | 203 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 204 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 205 | ! Version=2 ! TTL ! Flags ! 206 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 207 | 4 ! Community : 208 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 209 | 8 ! ... Community ... : 210 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 211 | 12 ! ... Community ... : 212 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 213 | 16 ! ... Community ... ! 214 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 215 | 20 ! Source MAC Address : 216 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 217 | 24 : ! Destination MAC Address : 218 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 219 | 28 : ! 220 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 221 | 32 ! Socket Flags (v=IPv4) ! Destination UDP Port ! 222 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 223 | 36 ! Destination IPv4 Address ! 224 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 225 | 40 ! Transform ID ! 226 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 227 | 44 ! Payload 228 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 229 | 230 | So each n2n PACKET has a 44 byte overhead. For a 1500 byte ethernet packet this 231 | is roughly 3%. 232 | 233 | Socket flags provides support for IPv6. In this case the PACKET message ends as 234 | follows: 235 | 236 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 237 | 32 ! Socket Flags (v=IPv6) ! Destination UDP Port ! 238 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 239 | 36 ! Destination IPv6 Address : 240 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 241 | 40 : : 242 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 243 | 44 : : 244 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 245 | 48 : ! 246 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 247 | 52 ! Transform ID ! 248 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 249 | 56 ! Encapsulated ethernet payload 250 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 251 | 252 | 253 | ------- 254 | 255 | January 2010 - Richard Andrews 256 | -------------------------------------------------------------------------------- /twofish.h: -------------------------------------------------------------------------------- 1 | /* $Id: twofish.h,v 2.0 2002/08/11 22:32:25 fknobbe Exp $ 2 | * 3 | * 4 | * Copyright (C) 1997-2000 The Cryptix Foundation Limited. 5 | * Copyright (C) 2000 Farm9. 6 | * Copyright (C) 2001 Frank Knobbe. 7 | * All rights reserved. 8 | * 9 | * For Cryptix code: 10 | * Use, modification, copying and distribution of this software is subject 11 | * the terms and conditions of the Cryptix General Licence. You should have 12 | * received a copy of the Cryptix General Licence along with this library; 13 | * if not, you can download a copy from http://www.cryptix.org/ . 14 | * 15 | * For Farm9: 16 | * --- jojo@farm9.com, August 2000, converted from Java to C++, added CBC mode and 17 | * ciphertext stealing technique, added AsciiTwofish class for easy encryption 18 | * decryption of text strings 19 | * 20 | * Frank Knobbe : 21 | * --- April 2001, converted from C++ to C, prefixed global variables 22 | * with TwoFish, substituted some defines, changed functions to make use of 23 | * variables supplied in a struct, modified and added routines for modular calls. 24 | * Cleaned up the code so that defines are used instead of fixed 16's and 32's. 25 | * Created two general purpose crypt routines for one block and multiple block 26 | * encryption using Joh's CBC code. 27 | * Added crypt routines that use a header (with a magic and data length). 28 | * (Basically a major rewrite). 29 | * 30 | * Note: Routines labeled _TwoFish are private and should not be used 31 | * (or with extreme caution). 32 | * 33 | */ 34 | 35 | #ifndef __TWOFISH_LIBRARY_HEADER__ 36 | #define __TWOFISH_LIBRARY_HEADER__ 37 | 38 | #ifdef WIN32 39 | #include "win32/n2n_win32.h" 40 | #endif 41 | 42 | #include 43 | #include /* defines uintN_t types */ 44 | 45 | #ifdef __sun__ /* Should be HAVE_SYS_TYPES */ 46 | /* The following are redefinitions if sys/types.h has been included too.*/ 47 | typedef uint32_t uint32_t; 48 | typedef uint8_t uint8_t; 49 | #endif /* #ifdef __sun__ */ 50 | 51 | /* Constants */ 52 | 53 | #define TwoFish_DEFAULT_PW "SnortHas2FishEncryptionRoutines!" /* default password (not more than 32 chars) */ 54 | #define TwoFish_DEFAULT_PW_LEN 32 55 | #define TwoFish_MAGIC "TwoFish" /* to indentify a successful decryption */ 56 | 57 | enum 58 | { TwoFish_KEY_SIZE = 256, /* Valid values: 64, 128, 192, 256 */ 59 | /* User 256, other key sizes have not been tested. */ 60 | /* (But should work. I substitutes as much as */ 61 | /* I could with this define.) */ 62 | TwoFish_ROUNDS = 16, 63 | TwoFish_BLOCK_SIZE = 16, /* bytes in a data-block */ 64 | TwoFish_KEY_LENGTH = TwoFish_KEY_SIZE/8, /* 32= 256-bit key */ 65 | TwoFish_TOTAL_SUBKEYS = 4+4+2*TwoFish_ROUNDS, 66 | TwoFish_MAGIC_LEN = TwoFish_BLOCK_SIZE-8, 67 | TwoFish_SK_BUMP = 0x01010101, 68 | TwoFish_SK_ROTL = 9, 69 | TwoFish_P_00 = 1, 70 | TwoFish_P_01 = 0, 71 | TwoFish_P_02 = 0, 72 | TwoFish_P_03 = TwoFish_P_01 ^ 1, 73 | TwoFish_P_04 = 1, 74 | TwoFish_P_10 = 0, 75 | TwoFish_P_11 = 0, 76 | TwoFish_P_12 = 1, 77 | TwoFish_P_13 = TwoFish_P_11 ^ 1, 78 | TwoFish_P_14 = 0, 79 | TwoFish_P_20 = 1, 80 | TwoFish_P_21 = 1, 81 | TwoFish_P_22 = 0, 82 | TwoFish_P_23 = TwoFish_P_21 ^ 1, 83 | TwoFish_P_24 = 0, 84 | TwoFish_P_30 = 0, 85 | TwoFish_P_31 = 1, 86 | TwoFish_P_32 = 1, 87 | TwoFish_P_33 = TwoFish_P_31 ^ 1, 88 | TwoFish_P_34 = 1, 89 | TwoFish_GF256_FDBK = 0x169, 90 | TwoFish_GF256_FDBK_2 = 0x169 / 2, 91 | TwoFish_GF256_FDBK_4 = 0x169 / 4, 92 | TwoFish_RS_GF_FDBK = 0x14D, /* field generator */ 93 | TwoFish_MDS_GF_FDBK = 0x169 /* primitive polynomial for GF(256) */ 94 | }; 95 | 96 | 97 | /* Global data structure for callers */ 98 | 99 | typedef struct 100 | { 101 | uint32_t sBox[4 * 256]; /* Key dependent S-box */ 102 | uint32_t subKeys[TwoFish_TOTAL_SUBKEYS]; /* Subkeys */ 103 | uint8_t key[TwoFish_KEY_LENGTH]; /* Encryption Key */ 104 | uint8_t *output; /* Pointer to output buffer */ 105 | uint8_t qBlockPlain[TwoFish_BLOCK_SIZE]; /* Used by CBC */ 106 | uint8_t qBlockCrypt[TwoFish_BLOCK_SIZE]; 107 | uint8_t prevCipher[TwoFish_BLOCK_SIZE]; 108 | struct /* Header for crypt functions. Has to be at least one block long. */ 109 | { uint32_t salt; /* Random salt in first block (will salt the rest through CBC) */ 110 | uint8_t length[4]; /* The amount of data following the header */ 111 | uint8_t magic[TwoFish_MAGIC_LEN]; /* Magic to identify successful decryption */ 112 | } header; 113 | bool qBlockDefined; 114 | bool dontflush; 115 | } TWOFISH; 116 | 117 | #ifndef __TWOFISH_LIBRARY_SOURCE__ 118 | 119 | extern bool TwoFish_srand; /* if set to TRUE (default), first call of TwoFishInit will seed rand(); */ 120 | /* call of TwoFishInit */ 121 | #endif 122 | 123 | 124 | /**** Public Functions ****/ 125 | 126 | /* TwoFish Initialization 127 | * 128 | * This routine generates a global data structure for use with TwoFish, 129 | * initializes important values (such as subkeys, sBoxes), generates subkeys 130 | * and precomputes the MDS matrix if not already done. 131 | * 132 | * Input: User supplied password (will be appended by default password of 'SnortHas2FishEncryptionRoutines!') 133 | * 134 | * Output: Pointer to TWOFISH structure. This data structure contains key dependent data. 135 | * This pointer is used with all other crypt functions. 136 | */ 137 | TWOFISH *TwoFishInit(const uint8_t *userkey, uint64_t keysize ); 138 | 139 | 140 | /* TwoFish Destroy 141 | * 142 | * Nothing else but a free... 143 | * 144 | * Input: Pointer to the TwoFish structure. 145 | * 146 | */ 147 | void TwoFishDestroy(TWOFISH *tfdata); 148 | 149 | 150 | /* TwoFish Alloc 151 | * 152 | * Allocates enough memory for the output buffer as required. 153 | * 154 | * Input: Length of the plaintext. 155 | * Boolean flag for BinHex Output. 156 | * Pointer to the TwoFish structure. 157 | * 158 | * Output: Returns a pointer to the memory allocated. 159 | */ 160 | void *TwoFishAlloc(uint64_t len,bool binhex,bool decrypt,TWOFISH *tfdata); 161 | 162 | 163 | /* TwoFish Free 164 | * 165 | * Free's the allocated buffer. 166 | * 167 | * Input: Pointer to the TwoFish structure 168 | * 169 | * Output: (none) 170 | */ 171 | void TwoFishFree(TWOFISH *tfdata); 172 | 173 | 174 | /* TwoFish Set Output 175 | * 176 | * If you want to allocate the output buffer yourself, 177 | * then you can set it with this function. 178 | * 179 | * Input: Pointer to your output buffer 180 | * Pointer to the TwoFish structure 181 | * 182 | * Output: (none) 183 | */ 184 | void TwoFishSetOutput(uint8_t *outp,TWOFISH *tfdata); 185 | 186 | 187 | /* TwoFish Raw Encryption 188 | * 189 | * Does not use header, but does use CBC (if more than one block has to be encrypted). 190 | * 191 | * Input: Pointer to the buffer of the plaintext to be encrypted. 192 | * Pointer to the buffer receiving the ciphertext. 193 | * The length of the plaintext buffer. 194 | * The TwoFish structure. 195 | * 196 | * Output: The amount of bytes encrypted if successful, otherwise 0. 197 | */ 198 | uint64_t TwoFishEncryptRaw(uint8_t *in,uint8_t *out,uint64_t len,TWOFISH *tfdata); 199 | 200 | /* TwoFish Raw Decryption 201 | * 202 | * Does not use header, but does use CBC (if more than one block has to be decrypted). 203 | * 204 | * Input: Pointer to the buffer of the ciphertext to be decrypted. 205 | * Pointer to the buffer receiving the plaintext. 206 | * The length of the ciphertext buffer (at least one cipher block). 207 | * The TwoFish structure. 208 | * 209 | * Output: The amount of bytes decrypted if successful, otherwise 0. 210 | */ 211 | uint64_t TwoFishDecryptRaw(uint8_t *in,uint8_t *out,uint64_t len,TWOFISH *tfdata); 212 | 213 | 214 | /* TwoFish Encryption 215 | * 216 | * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, 217 | * this routine will alloc the memory. In addition, it will include a small 'header' 218 | * containing the magic and some salt. That way the decrypt routine can check if the 219 | * packet got decrypted successfully, and return 0 instead of garbage. 220 | * 221 | * Input: Pointer to the buffer of the plaintext to be encrypted. 222 | * Pointer to the pointer to the buffer receiving the ciphertext. 223 | * The pointer either points to user allocated output buffer space, or to NULL, in which case 224 | * this routine will set the pointer to the buffer allocated through the struct. 225 | * The length of the plaintext buffer. 226 | * Can be -1 if the input is a null terminated string, in which case we'll count for you. 227 | * Boolean flag for BinHex Output (if used, output will be twice as large as input). 228 | * Note: BinHex conversion overwrites (converts) input buffer! 229 | * The TwoFish structure. 230 | * 231 | * Output: The amount of bytes encrypted if successful, otherwise 0. 232 | */ 233 | uint64_t TwoFishEncrypt(uint8_t *in,uint8_t **out,uint64_t len,bool binhex,TWOFISH *tfdata); 234 | 235 | 236 | /* TwoFish Decryption 237 | * 238 | * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, 239 | * this routine will alloc the memory. In addition, it will check the small 'header' 240 | * containing the magic. If magic does not match we return 0. Otherwise we return the 241 | * amount of bytes decrypted (should be the same as the length in the header). 242 | * 243 | * Input: Pointer to the buffer of the ciphertext to be decrypted. 244 | * Pointer to the pointer to the buffer receiving the plaintext. 245 | * The pointer either points to user allocated output buffer space, or to NULL, in which case 246 | * this routine will set the pointer to the buffer allocated through the struct. 247 | * The length of the ciphertext buffer. 248 | * Can be -1 if the input is a null terminated binhex string, in which case we'll count for you. 249 | * Boolean flag for BinHex Input (if used, plaintext will be half as large as input). 250 | * Note: BinHex conversion overwrites (converts) input buffer! 251 | * The TwoFish structure. 252 | * 253 | * Output: The amount of bytes decrypted if successful, otherwise 0. 254 | */ 255 | uint64_t TwoFishDecrypt(uint8_t *in,uint8_t **out,uint64_t len,bool binhex,TWOFISH *tfdata); 256 | 257 | 258 | /**** Private Functions ****/ 259 | 260 | uint8_t TwoFish__b(uint32_t x,int n); 261 | void _TwoFish_BinHex(uint8_t *buf,uint64_t len,bool bintohex); 262 | uint64_t _TwoFish_CryptRawCBC(uint8_t *in,uint8_t *out,uint64_t len,bool decrypt,TWOFISH *tfdata); 263 | uint64_t _TwoFish_CryptRaw16(uint8_t *in,uint8_t *out,uint64_t len,bool decrypt,TWOFISH *tfdata); 264 | uint64_t _TwoFish_CryptRaw(uint8_t *in,uint8_t *out,uint64_t len,bool decrypt,TWOFISH *tfdata); 265 | void _TwoFish_PrecomputeMDSmatrix(void); 266 | void _TwoFish_MakeSubKeys(TWOFISH *tfdata); 267 | void _TwoFish_qBlockPush(uint8_t *p,uint8_t *c,TWOFISH *tfdata); 268 | void _TwoFish_qBlockPop(uint8_t *p,uint8_t *c,TWOFISH *tfdata); 269 | void _TwoFish_ResetCBC(TWOFISH *tfdata); 270 | void _TwoFish_FlushOutput(uint8_t *b,uint64_t len,TWOFISH *tfdata); 271 | void _TwoFish_BlockCrypt(uint8_t *in,uint8_t *out,uint64_t size,int decrypt,TWOFISH *tfdata); 272 | void _TwoFish_BlockCrypt16(uint8_t *in,uint8_t *out,bool decrypt,TWOFISH *tfdata); 273 | uint32_t _TwoFish_RS_MDS_Encode(uint32_t k0,uint32_t k1); 274 | uint32_t _TwoFish_F32(uint32_t k64Cnt,uint32_t x,uint32_t *k32); 275 | uint32_t _TwoFish_Fe320(uint32_t *lsBox,uint32_t x); 276 | uint32_t _TwoFish_Fe323(uint32_t *lsBox,uint32_t x); 277 | uint32_t _TwoFish_Fe32(uint32_t *lsBox,uint32_t x,uint32_t R); 278 | 279 | 280 | #endif 281 | -------------------------------------------------------------------------------- /n2n_wire.h: -------------------------------------------------------------------------------- 1 | /* (c) 2009 Richard Andrews 2 | * 3 | * Contributions by: 4 | * Luca Deri 5 | * Lukasz Taczuk 6 | */ 7 | 8 | #if !defined( N2N_WIRE_H_ ) 9 | #define N2N_WIRE_H_ 10 | 11 | #include 12 | 13 | #if defined(WIN32) 14 | #include "win32/n2n_win32.h" 15 | 16 | #if defined(__MINGW32__) 17 | #include 18 | #endif /* #ifdef __MINGW32__ */ 19 | 20 | #else /* #if defined(WIN32) */ 21 | #include 22 | #include 23 | #include /* AF_INET and AF_INET6 */ 24 | #endif /* #if defined(WIN32) */ 25 | 26 | #define N2N_PKT_VERSION 2 27 | #define N2N_DEFAULT_TTL 2 /* can be forwarded twice at most */ 28 | #define N2N_COMMUNITY_SIZE 16 29 | #define N2N_MAC_SIZE 6 30 | #define N2N_COOKIE_SIZE 4 31 | #define N2N_PKT_BUF_SIZE 2048 32 | #define N2N_SOCKBUF_SIZE 64 /* string representation of INET or INET6 sockets */ 33 | 34 | typedef uint8_t n2n_community_t[N2N_COMMUNITY_SIZE]; 35 | typedef uint8_t n2n_mac_t[N2N_MAC_SIZE]; 36 | typedef uint8_t n2n_cookie_t[N2N_COOKIE_SIZE]; 37 | 38 | typedef char n2n_sock_str_t[N2N_SOCKBUF_SIZE]; /* tracing string buffer */ 39 | 40 | enum n2n_pc 41 | { 42 | n2n_ping=0, /* Not used */ 43 | n2n_register=1, /* Register edge to edge */ 44 | n2n_deregister=2, /* Deregister this edge */ 45 | n2n_packet=3, /* PACKET data content */ 46 | n2n_register_ack=4, /* ACK of a registration from edge to edge */ 47 | n2n_register_super=5, /* Register edge to supernode */ 48 | n2n_register_super_ack=6, /* ACK from supernode to edge */ 49 | n2n_register_super_nak=7, /* NAK from supernode to edge - registration refused */ 50 | n2n_federation=8 /* Not used by edge */ 51 | }; 52 | 53 | typedef enum n2n_pc n2n_pc_t; 54 | 55 | #define N2N_FLAGS_OPTIONS 0x0080 56 | #define N2N_FLAGS_SOCKET 0x0040 57 | #define N2N_FLAGS_FROM_SUPERNODE 0x0020 58 | 59 | /* The bits in flag that are the packet type */ 60 | #define N2N_FLAGS_TYPE_MASK 0x001f /* 0 - 31 */ 61 | #define N2N_FLAGS_BITS_MASK 0xffe0 62 | 63 | #define IPV4_SIZE 4 64 | #define IPV6_SIZE 16 65 | 66 | 67 | #define N2N_AUTH_TOKEN_SIZE 32 /* bytes */ 68 | 69 | 70 | #define N2N_EUNKNOWN -1 71 | #define N2N_ENOTIMPL -2 72 | #define N2N_EINVAL -3 73 | #define N2N_ENOSPACE -4 74 | 75 | 76 | typedef uint16_t n2n_flags_t; 77 | typedef uint16_t n2n_transform_t; /* Encryption, compression type. */ 78 | typedef uint32_t n2n_sa_t; /* security association number */ 79 | 80 | struct n2n_sock 81 | { 82 | uint8_t family; /* AF_INET or AF_INET6; or 0 if invalid */ 83 | uint16_t port; /* host order */ 84 | union 85 | { 86 | uint8_t v6[IPV6_SIZE]; /* byte sequence */ 87 | uint8_t v4[IPV4_SIZE]; /* byte sequence */ 88 | } addr; 89 | }; 90 | 91 | typedef struct n2n_sock n2n_sock_t; 92 | 93 | struct n2n_auth 94 | { 95 | uint16_t scheme; /* What kind of auth */ 96 | uint16_t toksize; /* Size of auth token */ 97 | uint8_t token[N2N_AUTH_TOKEN_SIZE]; /* Auth data interpreted based on scheme */ 98 | }; 99 | 100 | typedef struct n2n_auth n2n_auth_t; 101 | 102 | 103 | struct n2n_common 104 | { 105 | /* int version; */ 106 | uint8_t ttl; 107 | n2n_pc_t pc; 108 | n2n_flags_t flags; 109 | n2n_community_t community; 110 | }; 111 | 112 | typedef struct n2n_common n2n_common_t; 113 | 114 | struct n2n_REGISTER 115 | { 116 | n2n_cookie_t cookie; /* Link REGISTER and REGISTER_ACK */ 117 | n2n_mac_t srcMac; /* MAC of registering party */ 118 | n2n_mac_t dstMac; /* MAC of target edge */ 119 | n2n_sock_t sock; /* REVISIT: unused? */ 120 | }; 121 | 122 | typedef struct n2n_REGISTER n2n_REGISTER_t; 123 | 124 | struct n2n_REGISTER_ACK 125 | { 126 | n2n_cookie_t cookie; /* Return cookie from REGISTER */ 127 | n2n_mac_t srcMac; /* MAC of acknowledging party (supernode or edge) */ 128 | n2n_mac_t dstMac; /* Reflected MAC of registering edge from REGISTER */ 129 | n2n_sock_t sock; /* Supernode's view of edge socket (IP Addr, port) */ 130 | }; 131 | 132 | typedef struct n2n_REGISTER_ACK n2n_REGISTER_ACK_t; 133 | 134 | struct n2n_PACKET 135 | { 136 | n2n_mac_t srcMac; 137 | n2n_mac_t dstMac; 138 | n2n_sock_t sock; 139 | n2n_transform_t transform; 140 | }; 141 | 142 | typedef struct n2n_PACKET n2n_PACKET_t; 143 | 144 | 145 | /* Linked with n2n_register_super in n2n_pc_t. Only from edge to supernode. */ 146 | struct n2n_REGISTER_SUPER 147 | { 148 | n2n_cookie_t cookie; /* Link REGISTER_SUPER and REGISTER_SUPER_ACK */ 149 | n2n_mac_t edgeMac; /* MAC to register with edge sending socket */ 150 | n2n_auth_t auth; /* Authentication scheme and tokens */ 151 | }; 152 | 153 | typedef struct n2n_REGISTER_SUPER n2n_REGISTER_SUPER_t; 154 | 155 | 156 | /* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */ 157 | struct n2n_REGISTER_SUPER_ACK 158 | { 159 | n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */ 160 | n2n_mac_t edgeMac; /* MAC registered to edge sending socket */ 161 | uint16_t lifetime; /* How long the registration will live */ 162 | n2n_sock_t sock; /* Sending sockets associated with edgeMac */ 163 | 164 | /* The packet format provides additional supernode definitions here. 165 | * uint8_t count, then for each count there is one 166 | * n2n_sock_t. 167 | */ 168 | uint8_t num_sn; /* Number of supernodes that were send 169 | * even if we cannot store them all. If 170 | * non-zero then sn_bak is valid. */ 171 | n2n_sock_t sn_bak; /* Socket of the first backup supernode */ 172 | 173 | }; 174 | 175 | typedef struct n2n_REGISTER_SUPER_ACK n2n_REGISTER_SUPER_ACK_t; 176 | 177 | 178 | /* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */ 179 | struct n2n_REGISTER_SUPER_NAK 180 | { 181 | n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */ 182 | }; 183 | 184 | typedef struct n2n_REGISTER_SUPER_NAK n2n_REGISTER_SUPER_NAK_t; 185 | 186 | 187 | 188 | struct n2n_buf 189 | { 190 | uint8_t * data; 191 | size_t size; 192 | }; 193 | 194 | typedef struct n2n_buf n2n_buf_t; 195 | 196 | size_t encode_uint8( uint8_t * base, 197 | size_t * idx, 198 | const uint8_t v ); 199 | 200 | size_t decode_uint8( uint8_t * out, 201 | const uint8_t * base, 202 | size_t * rem, 203 | size_t * idx ); 204 | 205 | size_t encode_uint16( uint8_t * base, 206 | size_t * idx, 207 | const uint16_t v ); 208 | 209 | size_t decode_uint16( uint16_t * out, 210 | const uint8_t * base, 211 | size_t * rem, 212 | size_t * idx ); 213 | 214 | size_t encode_uint32( uint8_t * base, 215 | size_t * idx, 216 | const uint32_t v ); 217 | 218 | size_t decode_uint32( uint32_t * out, 219 | const uint8_t * base, 220 | size_t * rem, 221 | size_t * idx ); 222 | 223 | size_t encode_buf( uint8_t * base, 224 | size_t * idx, 225 | const void * p, 226 | size_t s); 227 | 228 | size_t decode_buf( uint8_t * out, 229 | size_t bufsize, 230 | const uint8_t * base, 231 | size_t * rem, 232 | size_t * idx ); 233 | 234 | size_t encode_mac( uint8_t * base, 235 | size_t * idx, 236 | const n2n_mac_t m ); 237 | 238 | size_t decode_mac( uint8_t * out, /* of size N2N_MAC_SIZE. This clearer than passing a n2n_mac_t */ 239 | const uint8_t * base, 240 | size_t * rem, 241 | size_t * idx ); 242 | 243 | ssize_t encode_common( uint8_t * base, 244 | size_t * idx, 245 | const n2n_common_t * common ); 246 | 247 | ssize_t decode_common( n2n_common_t * out, 248 | const uint8_t * base, 249 | size_t * rem, 250 | size_t * idx ); 251 | 252 | ssize_t encode_sock( uint8_t * base, 253 | size_t * idx, 254 | const n2n_sock_t * sock ); 255 | 256 | ssize_t decode_sock( n2n_sock_t * sock, 257 | const uint8_t * base, 258 | size_t * rem, 259 | size_t * idx ); 260 | 261 | size_t encode_REGISTER( uint8_t * base, 262 | size_t * idx, 263 | const n2n_common_t * common, 264 | const n2n_REGISTER_t * reg ); 265 | 266 | size_t decode_REGISTER( n2n_REGISTER_t * pkt, 267 | const n2n_common_t * cmn, /* info on how to interpret it */ 268 | const uint8_t * base, 269 | size_t * rem, 270 | size_t * idx ); 271 | 272 | size_t encode_REGISTER_SUPER( uint8_t * base, 273 | size_t * idx, 274 | const n2n_common_t * common, 275 | const n2n_REGISTER_SUPER_t * reg ); 276 | 277 | size_t decode_REGISTER_SUPER( n2n_REGISTER_SUPER_t * pkt, 278 | const n2n_common_t * cmn, /* info on how to interpret it */ 279 | const uint8_t * base, 280 | size_t * rem, 281 | size_t * idx ); 282 | 283 | size_t encode_REGISTER_ACK( uint8_t * base, 284 | size_t * idx, 285 | const n2n_common_t * common, 286 | const n2n_REGISTER_ACK_t * reg ); 287 | 288 | size_t decode_REGISTER_ACK( n2n_REGISTER_ACK_t * pkt, 289 | const n2n_common_t * cmn, /* info on how to interpret it */ 290 | const uint8_t * base, 291 | size_t * rem, 292 | size_t * idx ); 293 | 294 | size_t encode_REGISTER_SUPER_ACK( uint8_t * base, 295 | size_t * idx, 296 | const n2n_common_t * cmn, 297 | const n2n_REGISTER_SUPER_ACK_t * reg ); 298 | 299 | size_t decode_REGISTER_SUPER_ACK( n2n_REGISTER_SUPER_ACK_t * reg, 300 | const n2n_common_t * cmn, /* info on how to interpret it */ 301 | const uint8_t * base, 302 | size_t * rem, 303 | size_t * idx ); 304 | 305 | int fill_sockaddr( struct sockaddr * addr, 306 | size_t addrlen, 307 | const n2n_sock_t * sock ); 308 | 309 | size_t encode_PACKET( uint8_t * base, 310 | size_t * idx, 311 | const n2n_common_t * common, 312 | const n2n_PACKET_t * pkt ); 313 | 314 | size_t decode_PACKET( n2n_PACKET_t * pkt, 315 | const n2n_common_t * cmn, /* info on how to interpret it */ 316 | const uint8_t * base, 317 | size_t * rem, 318 | size_t * idx ); 319 | 320 | 321 | #endif /* #if !defined( N2N_WIRE_H_ ) */ 322 | -------------------------------------------------------------------------------- /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 | 19 | #ifdef __linux__ 20 | #include /* if_nametoindex */ 21 | #include /* required for ARPHRD_ETHER */ 22 | #include 23 | #include 24 | 25 | #include "n2n.h" 26 | 27 | struct rtnl_req { 28 | struct nlmsghdr nl; 29 | union { 30 | struct ifinfomsg ifinfo; 31 | struct rtmsg rt; 32 | struct ifaddrmsg ifaddr; 33 | }; 34 | uint8_t buf[256]; 35 | }; 36 | 37 | static void read_mac(const char *ifname, n2n_mac_t mac_addr) { 38 | int _sock, res; 39 | struct ifreq ifr; 40 | macstr_t mac_addr_buf; 41 | 42 | memset(&ifr, 0, sizeof(struct ifreq)); 43 | 44 | _sock = socket(PF_INET, SOCK_DGRAM, 0); 45 | strncpy(ifr.ifr_name, ifname, N2N_IFNAMSIZ); 46 | 47 | res = ioctl(_sock, SIOCGIFHWADDR, &ifr); 48 | if (res < 0) { 49 | traceEvent(TRACE_ERROR, "ioctl() [%s][%d]\n", strerror(errno), res); 50 | } else 51 | memcpy(mac_addr, &ifr.ifr_ifru.ifru_hwaddr.sa_data, sizeof(n2n_mac_t)); 52 | 53 | traceEvent(TRACE_NORMAL, "Interface %s has MAC %s", 54 | ifname, 55 | macaddr_str(mac_addr_buf, mac_addr)); 56 | close(_sock); 57 | } 58 | 59 | static int set_mac(int fd, const char* dev, n2n_mac_t device_mac) { 60 | int rc; 61 | struct ifreq ifr; 62 | 63 | memset(&ifr, 0, sizeof(struct ifreq)); 64 | memcpy(&ifr.ifr_hwaddr.sa_data, device_mac, sizeof(n2n_mac_t)); 65 | strncpy(ifr.ifr_name, dev, IFNAMSIZ); 66 | 67 | ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; 68 | rc = ioctl(fd, SIOCSIFHWADDR, &ifr); 69 | if (rc < 0) { 70 | traceEvent(TRACE_ERROR, "ioctl() [%s][%d]\n", strerror(errno), rc); 71 | return -1; 72 | } 73 | return 0; 74 | } 75 | 76 | static int netlink_talk(int nl_sock, struct rtnl_req* req) { 77 | uint8_t buf[1024] = { 0 }; 78 | ssize_t rtn = -1; 79 | 80 | struct iovec iov = { 81 | .iov_base = req, 82 | .iov_len = req->nl.nlmsg_len 83 | }; 84 | 85 | struct sockaddr_nl nl_addr = { 86 | .nl_family = AF_NETLINK, 87 | .nl_pid = 0, 88 | .nl_groups = 0 89 | }; 90 | 91 | const struct msghdr msg = { 92 | .msg_name = &nl_addr, 93 | .msg_namelen = sizeof(nl_addr), 94 | 95 | .msg_iov = &iov, 96 | .msg_iovlen = 1, 97 | 98 | .msg_control = NULL, 99 | .msg_controllen = 0, 100 | .msg_flags = 0 101 | }; 102 | 103 | if (sendmsg(nl_sock, &msg, 0) < 0) { 104 | traceEvent(TRACE_ERROR, "netlink send() [%s]\n", strerror(errno)); 105 | return -1; 106 | } 107 | 108 | if (recv(nl_sock, buf, sizeof(buf), 0) > 0) { 109 | struct nlmsghdr* nlp = (struct nlmsghdr*) buf; 110 | if (nlp->nlmsg_type == NLMSG_ERROR) { 111 | return -((struct nlmsgerr*) NLMSG_DATA(nlp))->error; 112 | } else { 113 | traceEvent(TRACE_DEBUG, "netlink recv() unexpected msg type: %d\n", nlp->nlmsg_type); 114 | return -1; 115 | } 116 | rtn = 0; 117 | } 118 | return rtn; 119 | } 120 | 121 | static int set_device_state(const tuntap_dev* device, bool up) { 122 | int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); 123 | struct ifreq ifr = { 0 }; 124 | strncpy(ifr.ifr_name, device->dev_name, IFNAMSIZ); 125 | /* retrieve flags */ 126 | if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) { 127 | traceEvent(TRACE_INFO, "ioctl(SIOCGIFFLAGS) [%s]\n", strerror(errno)); 128 | close(s); 129 | return -1; 130 | } 131 | 132 | /* bring up interface */ 133 | if (up) 134 | ifr.ifr_flags |= IFF_UP | IFF_RUNNING; 135 | else 136 | ifr.ifr_flags &= IFF_UP | IFF_RUNNING; 137 | if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0) { 138 | traceEvent(TRACE_INFO, "ioctl(SIOCSIFFLAGS) [%s]\n", strerror(errno)); 139 | close(s); 140 | return -1; 141 | } 142 | 143 | close(s); 144 | return 0; 145 | } 146 | 147 | static int set_ipaddress(const tuntap_dev* device, int static_address) { 148 | int ifnum = if_nametoindex(device->dev_name); 149 | traceEvent(TRACE_DEBUG, "if_nametoindex(%s) %d\n", device->dev_name, ifnum); 150 | 151 | int error; 152 | int _sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 153 | if (_sock < 0) { 154 | traceEvent(TRACE_ERROR, "socket() [%s][%d]\n", strerror(errno), _sock); 155 | return -1; 156 | } 157 | 158 | struct sockaddr_nl nl_addr = { 159 | .nl_family = AF_NETLINK, 160 | .nl_pid = (uint32_t) getpid(), 161 | .nl_groups = 0 162 | }; 163 | 164 | if (bind(_sock, (struct sockaddr*) &nl_addr, sizeof(nl_addr)) < 0) { 165 | fprintf(stderr, "bind() [%s][%d]\n", strerror(errno), _sock); 166 | close(_sock); 167 | return -1; 168 | } 169 | 170 | struct rtnl_req req = { 0 }; 171 | struct rtattr* rta = NULL; 172 | 173 | req.nl.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); 174 | req.nl.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; 175 | req.nl.nlmsg_type = RTM_SETLINK; 176 | req.nl.nlmsg_pid = (uint32_t) getpid(); 177 | 178 | req.ifinfo.ifi_family = AF_UNSPEC; 179 | req.ifinfo.ifi_type = ARPHRD_ETHER; 180 | req.ifinfo.ifi_index = ifnum; 181 | req.ifinfo.ifi_change = 0xFFFFFFFF; 182 | 183 | rta = (struct rtattr*) (((uint8_t*) &req) + NLMSG_ALIGN(req.nl.nlmsg_len)); 184 | rta->rta_len = RTA_LENGTH(sizeof(uint32_t)); 185 | rta->rta_type = IFLA_MTU; 186 | req.nl.nlmsg_len = NLMSG_ALIGN(req.nl.nlmsg_len) + rta->rta_len; 187 | memcpy(RTA_DATA(rta), &device->mtu, sizeof(uint32_t)); 188 | 189 | 190 | 191 | if ((error = netlink_talk(_sock, &req)) != 0) { 192 | traceEvent(TRACE_ERROR, "netlink set_mtu %u: [%s]", device->mtu, strerror(error)); 193 | close(_sock); 194 | return -1; 195 | } 196 | 197 | if (static_address) { 198 | req.nl.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); 199 | req.nl.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK; 200 | req.nl.nlmsg_type = RTM_NEWADDR; 201 | 202 | memset(&req.ifaddr, 0, sizeof(req.ifaddr)); 203 | req.ifaddr.ifa_family = AF_INET; 204 | req.ifaddr.ifa_index = ifnum; 205 | req.ifaddr.ifa_prefixlen = device->ip_prefixlen; 206 | req.ifaddr.ifa_scope = RT_SCOPE_UNIVERSE; 207 | 208 | rta = (struct rtattr*) (((uint8_t*) &req) + NLMSG_ALIGN(req.nl.nlmsg_len)); 209 | rta->rta_len = RTA_LENGTH(sizeof(struct in_addr)); 210 | rta->rta_type = IFA_LOCAL; 211 | req.nl.nlmsg_len = NLMSG_ALIGN(req.nl.nlmsg_len) + rta->rta_len; 212 | memcpy(RTA_DATA(rta), &device->ip_addr, sizeof(struct in_addr)); 213 | 214 | if ((error = netlink_talk(_sock, &req)) != 0) { 215 | traceEvent(TRACE_ERROR, "netlink set_ip: [%s]", strerror(error)); 216 | close(_sock); 217 | return -1; 218 | } 219 | } 220 | 221 | /* set ipv6 address */ 222 | if (static_address && device->ip6_prefixlen > 0) { 223 | req.nl.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); 224 | req.nl.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE |NLM_F_ACK; 225 | req.nl.nlmsg_type = RTM_NEWADDR; 226 | 227 | memset(&req.ifaddr, 0, sizeof(req.ifaddr)); 228 | req.ifaddr.ifa_family = AF_INET6; 229 | req.ifaddr.ifa_index = ifnum; 230 | req.ifaddr.ifa_prefixlen = device->ip6_prefixlen; 231 | req.ifaddr.ifa_scope = RT_SCOPE_UNIVERSE; 232 | 233 | rta = (struct rtattr *)(((uint8_t*) &req) + NLMSG_ALIGN(req.nl.nlmsg_len)); 234 | rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr)); 235 | rta->rta_type = IFA_LOCAL; 236 | req.nl.nlmsg_len = NLMSG_ALIGN(req.nl.nlmsg_len) + rta->rta_len; 237 | memcpy(RTA_DATA(rta), &device->ip6_addr, sizeof(struct in6_addr)); 238 | 239 | if ((error = netlink_talk(_sock, &req)) != 0) { 240 | traceEvent(TRACE_ERROR, "netlink set_ip6: [%s]", strerror(error)); 241 | close(_sock); 242 | return -1; 243 | } 244 | } 245 | 246 | if (set_device_state(device, true) != 0) { 247 | traceEvent(TRACE_ERROR, "netlink device up: [%s]", strerror(error)); 248 | return -1; 249 | } 250 | 251 | uint32_t address_size = 0; 252 | if (device->routes) { 253 | req.nl.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK; 254 | req.nl.nlmsg_type = RTM_NEWROUTE; 255 | 256 | memset(&req.rt, 0, sizeof(req.rt)); 257 | req.rt.rtm_table = RT_TABLE_MAIN; 258 | req.rt.rtm_protocol = RTPROT_STATIC; 259 | req.rt.rtm_type = RTN_UNICAST; 260 | req.rt.rtm_scope = RT_SCOPE_UNIVERSE; 261 | req.rt.rtm_flags = RTM_F_PREFIX; 262 | 263 | for(int i = 0; i < device->routes_count; i++) { 264 | route* r = &device->routes[i]; 265 | if (r->family == AF_INET) 266 | address_size = sizeof(struct in_addr); 267 | else if (r->family == AF_INET6) 268 | address_size = sizeof(struct in6_addr); 269 | else abort(); 270 | 271 | req.nl.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); 272 | req.rt.rtm_family = r->family; 273 | req.rt.rtm_dst_len = r->prefixlen; 274 | 275 | // 1st attribute: DST address 276 | rta = (struct rtattr *)(((uint8_t*) &req) + NLMSG_ALIGN(req.nl.nlmsg_len)); 277 | rta->rta_type = RTA_DST; 278 | rta->rta_len = RTA_LENGTH(address_size); 279 | req.nl.nlmsg_len = NLMSG_ALIGN(req.nl.nlmsg_len) + rta->rta_len; 280 | memcpy(RTA_DATA(rta), &r->dest, address_size); 281 | 282 | // 2nd attribute: set ifc index and increment the size 283 | rta = (struct rtattr*)(((uint8_t*) &req) + NLMSG_ALIGN(req.nl.nlmsg_len)); 284 | rta->rta_type = RTA_GATEWAY; 285 | rta->rta_len = RTA_LENGTH(address_size); 286 | req.nl.nlmsg_len = NLMSG_ALIGN(req.nl.nlmsg_len) + rta->rta_len; 287 | memcpy(RTA_DATA(rta), &r->gateway, address_size); 288 | 289 | if ((error = netlink_talk(_sock, &req)) != 0) { 290 | char buf1[INET6_ADDRSTRLEN]; 291 | char buf2[INET6_ADDRSTRLEN]; 292 | traceEvent(TRACE_ERROR, "netlink add_route: %s/%u via %s [%s]", 293 | inet_ntop(r->family, r->dest, buf1, INET6_ADDRSTRLEN), 294 | r->prefixlen, 295 | inet_ntop(r->family, r->gateway, buf2, INET6_ADDRSTRLEN), 296 | strerror(error) 297 | ); 298 | } 299 | } 300 | } 301 | 302 | close(_sock); 303 | return 0; 304 | } 305 | 306 | /* ********************************** */ 307 | 308 | /** @brief Open and configure the TAP device for packet read/write. 309 | * 310 | * This routine creates the interface via the tuntap driver then uses ifconfig 311 | * to configure address/mask and MTU. 312 | * 313 | * @param device - [inout] a device info holder object 314 | * @param dev - user-defined name for the new iface, 315 | * if NULL system will assign a name 316 | * @param device_ip - address of iface 317 | * @param device_mask - netmask for device_ip 318 | * @param mtu - MTU for device_ip 319 | * 320 | * @return - negative value on error 321 | * - non-negative file-descriptor on success 322 | */ 323 | int tuntap_open(tuntap_dev *device, struct tuntap_config* config) { 324 | char *tuntap_device = "/dev/net/tun"; 325 | struct ifreq ifr; 326 | int rc; 327 | 328 | device->fd = open(tuntap_device, O_RDWR | O_CLOEXEC); 329 | if(device->fd < 0) { 330 | printf("ERROR: ioctl() [%s][%d]\n", strerror(errno), errno); 331 | return -1; 332 | } 333 | 334 | memset(&ifr, 0, sizeof(ifr)); 335 | ifr.ifr_flags = IFF_TAP|IFF_NO_PI; /* Want a TAP device for layer 2 frames. */ 336 | strncpy(ifr.ifr_name, config->if_name, IFNAMSIZ); 337 | rc = ioctl(device->fd, TUNSETIFF, (void *)&ifr); 338 | 339 | if(rc < 0) { 340 | traceEvent(TRACE_ERROR, "ioctl() [%s][%d]\n", strerror(errno), rc); 341 | close(device->fd); 342 | return -1; 343 | } 344 | 345 | /* set mac address */ 346 | if (!(config->device_mac[0] == 0 && config->device_mac[1] == 0 && 347 | config->device_mac[2] == 0 && config->device_mac[3] == 0 && 348 | config->device_mac[4] == 0 && config->device_mac[5] == 0)) 349 | { 350 | set_mac(device->fd, config->if_name, config->device_mac); 351 | } 352 | 353 | /* Store the device name for later reuse */ 354 | strncpy(device->dev_name, config->if_name, MIN(IFNAMSIZ, N2N_IFNAMSIZ) ); 355 | memcpy(&device->ip_addr, &config->ip_addr, sizeof(config->ip_addr)); 356 | device->ip_prefixlen = config->ip_prefixlen; 357 | memcpy(&device->ip6_addr, &config->ip6_addr, sizeof(config->ip6_addr)); 358 | device->ip6_prefixlen = config->ip6_prefixlen; 359 | device->mtu = config->mtu; 360 | device->routes_count = config->routes_count; 361 | device->routes = config->routes; 362 | 363 | read_mac(device->dev_name, device->mac_addr); 364 | 365 | if ( set_ipaddress(device, !config->dyn_ip4) < 0 ) { 366 | traceEvent(TRACE_ERROR, "Could not setup up interface %s", device->dev_name); 367 | close(device->fd); 368 | return -1; 369 | } 370 | 371 | return(device->fd); 372 | } 373 | 374 | ssize_t tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, size_t len) { 375 | return(read(tuntap->fd, buf, len)); 376 | } 377 | 378 | ssize_t tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, size_t len) { 379 | return(write(tuntap->fd, buf, len)); 380 | } 381 | 382 | void tuntap_close(struct tuntap_dev *tuntap) { 383 | close(tuntap->fd); 384 | } 385 | 386 | /* Fill out the ip_addr value from the interface. Called to pick up dynamic 387 | * address changes. */ 388 | void tuntap_get_address(struct tuntap_dev *tuntap) { 389 | int _sock, res; 390 | struct ifreq ifr; 391 | ipstr_t buf; 392 | 393 | memset(&ifr, 0, sizeof(ifr)); 394 | _sock = socket(PF_INET, SOCK_DGRAM, 0); 395 | 396 | strcpy(ifr.ifr_name, tuntap->dev_name); 397 | ifr.ifr_addr.sa_family = AF_INET; 398 | 399 | res = ioctl(_sock, SIOCGIFADDR, &ifr); 400 | if (res < 0) { 401 | perror ("Get ip addr"); 402 | } else 403 | tuntap->ip_addr = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr; 404 | close(_sock); 405 | 406 | traceEvent(TRACE_NORMAL, "Interface %s has IPv4 %s", 407 | tuntap->dev_name, 408 | inet_ntop(AF_INET, &tuntap->ip_addr, buf, sizeof(buf))); 409 | } 410 | 411 | #endif /* #ifdef __linux__ */ 412 | -------------------------------------------------------------------------------- /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 | 26 | #include "minilzo.h" 27 | 28 | #include 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 | const uint8_t broadcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 40 | const uint8_t multicast_addr[6] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 }; /* First 3 bytes are meaningful */ 41 | const uint8_t ipv6_multicast_addr[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; /* First 2 bytes are meaningful */ 42 | 43 | /* ************************************** */ 44 | 45 | SOCKET open_socket(uint16_t local_port, int bind_any) { 46 | SOCKET sock_fd; 47 | struct sockaddr_in local_address; 48 | int sockopt = 1; 49 | 50 | if((sock_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { 51 | traceEvent(TRACE_ERROR, "Unable to create socket [%s][%d]\n", strerror(errno), sock_fd); 52 | return -1; 53 | } 54 | 55 | #ifndef _WIN32 56 | fcntl(sock_fd, F_SETFL, O_NONBLOCK); 57 | #endif 58 | 59 | setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt)); 60 | 61 | memset(&local_address, 0, sizeof(local_address)); 62 | local_address.sin_family = AF_INET; 63 | local_address.sin_port = htons(local_port); 64 | local_address.sin_addr.s_addr = htonl(bind_any?INADDR_ANY:INADDR_LOOPBACK); 65 | 66 | if(bind(sock_fd, (struct sockaddr*) &local_address, sizeof(local_address)) == -1) { 67 | traceEvent(TRACE_ERROR, "Bind error [%s]\n", strerror(errno)); 68 | return -1; 69 | } 70 | 71 | return sock_fd; 72 | } 73 | 74 | SOCKET open_socket6(uint16_t local_port, int bind_any) { 75 | SOCKET sock_fd; 76 | struct sockaddr_in6 local_address; 77 | int sockopt = 1; 78 | 79 | if((sock_fd = socket(PF_INET6, SOCK_DGRAM, 0)) < 0) { 80 | traceEvent(TRACE_ERROR, "Unable to create socket [%s][%d]\n", strerror(errno), sock_fd); 81 | return -1; 82 | } 83 | 84 | #ifndef _WIN32 85 | fcntl(sock_fd, F_SETFL, O_NONBLOCK); 86 | #endif 87 | 88 | setsockopt(sock_fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&sockopt, sizeof(sockopt)); 89 | setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt)); 90 | 91 | memset(&local_address, 0, sizeof(local_address)); 92 | local_address.sin6_family = AF_INET6; 93 | local_address.sin6_port = htons(local_port); 94 | local_address.sin6_addr = bind_any ? in6addr_any : in6addr_loopback; 95 | 96 | if(bind(sock_fd, (struct sockaddr*) &local_address, sizeof(local_address)) == -1) { 97 | traceEvent(TRACE_ERROR, "Bind error [%s]\n", strerror(errno)); 98 | return -1; 99 | } 100 | 101 | return sock_fd; 102 | } 103 | 104 | #ifndef _WIN32 105 | SOCKET open_socket_unix(const char* path, mode_t access) { 106 | SOCKET sock_fd; 107 | struct sockaddr_un socket_address; 108 | struct stat stat_buf; 109 | 110 | if (stat(path, &stat_buf) == 0) { 111 | traceEvent(TRACE_WARNING, "socket exists %s ... deleting\n", path); 112 | unlink(path); 113 | } else { 114 | if (errno != ENOENT) { 115 | traceEvent(TRACE_WARNING, "could not stat socket [%s]\n", strerror(errno)); 116 | return -1; 117 | } 118 | } 119 | 120 | if((sock_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { 121 | traceEvent(TRACE_ERROR, "Unable to create socket [%s][%d]\n", strerror(errno), sock_fd); 122 | return -1; 123 | } 124 | 125 | fcntl(sock_fd, F_SETFL, O_NONBLOCK); 126 | 127 | memset(&socket_address, 0, sizeof(socket_address)); 128 | socket_address.sun_family = AF_UNIX; 129 | strncpy(socket_address.sun_path, path, 108); 130 | 131 | #if __linux__ 132 | fchmod(sock_fd, access); 133 | #endif 134 | 135 | if(bind(sock_fd, (struct sockaddr*) &socket_address, sizeof(socket_address)) == -1) { 136 | traceEvent(TRACE_ERROR, "Bind error [%s]\n", strerror(errno)); 137 | return -1; 138 | } 139 | 140 | chmod(path, access); 141 | 142 | return sock_fd; 143 | } 144 | #endif // _WIN32 145 | 146 | int traceLevel = 2 /* NORMAL */; 147 | bool useSyslog = false, syslog_opened = false, useSystemd = false; 148 | 149 | #define N2N_TRACE_DATESIZE 32 150 | void traceEvent(int eventTraceLevel, char* file, int line, char * format, ...) { 151 | va_list va_ap; 152 | 153 | if(eventTraceLevel <= traceLevel) { 154 | char buf[2048]; 155 | char out_buf[640]; 156 | char theDate[N2N_TRACE_DATESIZE]; 157 | char *extra_msg = ""; 158 | time_t theTime = time(NULL); 159 | size_t i; 160 | 161 | /* We have two paths - one if we're logging, one if we aren't 162 | * Note that the no-log case is those systems which don't support it (WIN32), 163 | * those without the headers !defined(USE_SYSLOG) 164 | * those where it's parametrically off... 165 | */ 166 | 167 | memset(buf, 0, sizeof(buf)); 168 | 169 | va_start (va_ap, format); 170 | vsnprintf(buf, sizeof(buf)-1, format, va_ap); 171 | va_end(va_ap); 172 | 173 | if(eventTraceLevel == 0 /* TRACE_ERROR */) 174 | extra_msg = "ERROR: "; 175 | else if(eventTraceLevel == 1 /* TRACE_WARNING */) 176 | extra_msg = "WARNING: "; 177 | 178 | while(buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; 179 | 180 | #ifndef _WIN32 181 | if(useSyslog) { 182 | if(!syslog_opened) { 183 | openlog("n2n", LOG_PID, LOG_DAEMON); 184 | syslog_opened = 1; 185 | } 186 | 187 | snprintf(out_buf, sizeof(out_buf), "%s%s", extra_msg, buf); 188 | syslog(LOG_INFO, "%s", out_buf); 189 | } else { 190 | if (useSystemd) 191 | snprintf(out_buf, sizeof(out_buf), "%s%s", extra_msg, buf); 192 | else { 193 | strftime(theDate, N2N_TRACE_DATESIZE, "%d/%b/%Y %H:%M:%S", localtime(&theTime)); 194 | for(i=strlen(file)-1; i>0; i--) if(file[i] == '/') { i++; break; }; 195 | snprintf(out_buf, sizeof(out_buf), "%s [%15s:%4d] %s%s", theDate, &file[i], line, extra_msg, buf); 196 | } 197 | printf("%s\n", out_buf); 198 | fflush(stdout); 199 | } 200 | #else 201 | if (event_log == INVALID_HANDLE_VALUE) { 202 | /* running in the console */ 203 | strftime(theDate, N2N_TRACE_DATESIZE, "%d/%b/%Y %H:%M:%S", localtime(&theTime)); 204 | for(i=strlen(file)-1; i>0; i--) if(file[i] == '\\') { i++; break; }; 205 | snprintf(out_buf, sizeof(out_buf), "%s [%15s:%4d] %s%s", theDate, &file[i], line, extra_msg, buf); 206 | printf("%s\n", out_buf); 207 | fflush(stdout); 208 | } else { 209 | /* running as a service */ 210 | wchar_t out[640]; 211 | swprintf(out, sizeof(out), L"%hs%hs", extra_msg, buf); 212 | 213 | wchar_t* msg[] = { 214 | scm_name, 215 | out 216 | }; 217 | 218 | short level = EVENTLOG_ERROR_TYPE; 219 | if(eventTraceLevel == 1) 220 | level = EVENTLOG_WARNING_TYPE; 221 | else if(eventTraceLevel == 2) 222 | level = EVENTLOG_INFORMATION_TYPE; 223 | 224 | ReportEventW(event_log, level, 0, 0x40020000L, NULL, 2, 0, msg, NULL); 225 | } 226 | #endif 227 | } 228 | 229 | } 230 | 231 | /* *********************************************** */ 232 | 233 | char * macaddr_str( macstr_t buf, 234 | const n2n_mac_t mac ) 235 | { 236 | snprintf(buf, N2N_MACSTR_SIZE, "%02X:%02X:%02X:%02X:%02X:%02X", 237 | mac[0] & 0xFF, mac[1] & 0xFF, mac[2] & 0xFF, 238 | mac[3] & 0xFF, mac[4] & 0xFF, mac[5] & 0xFF); 239 | return(buf); 240 | } 241 | 242 | /* *********************************************** */ 243 | 244 | uint8_t is_multi_broadcast(const uint8_t * dest_mac) { 245 | 246 | int is_broadcast = ( memcmp(broadcast_addr, dest_mac, 6) == 0 ); 247 | int is_multicast = ( memcmp(multicast_addr, dest_mac, 3) == 0 ); 248 | int is_ipv6_multicast = ( memcmp(ipv6_multicast_addr, dest_mac, 2) == 0 ); 249 | 250 | return is_broadcast || is_multicast || is_ipv6_multicast; 251 | 252 | } 253 | 254 | /* http://www.faqs.org/rfcs/rfc908.html */ 255 | 256 | 257 | /* *********************************************** */ 258 | 259 | char* msg_type2str(uint16_t msg_type) { 260 | switch(msg_type) { 261 | case MSG_TYPE_REGISTER: return "MSG_TYPE_REGISTER"; 262 | case MSG_TYPE_DEREGISTER: return "MSG_TYPE_DEREGISTER"; 263 | case MSG_TYPE_PACKET: return "MSG_TYPE_PACKET"; 264 | case MSG_TYPE_REGISTER_ACK: return "MSG_TYPE_REGISTER_ACK"; 265 | case MSG_TYPE_REGISTER_SUPER: return "MSG_TYPE_REGISTER_SUPER"; 266 | case MSG_TYPE_REGISTER_SUPER_ACK: return "MSG_TYPE_REGISTER_SUPER_ACK"; 267 | case MSG_TYPE_REGISTER_SUPER_NAK: return "MSG_TYPE_REGISTER_SUPER_NAK"; 268 | case MSG_TYPE_FEDERATION: return "MSG_TYPE_FEDERATION"; 269 | default: return "???"; 270 | } 271 | } 272 | 273 | /* *********************************************** */ 274 | 275 | void hexdump(const uint8_t * buf, size_t len) 276 | { 277 | size_t i; 278 | 279 | if ( 0 == len ) { return; } 280 | 281 | for(i=0; i 0) && ((i % 16) == 0)) { printf("\n"); } 284 | printf("%02X ", buf[i] & 0xFF); 285 | } 286 | 287 | printf("\n"); 288 | } 289 | 290 | /* *********************************************** */ 291 | 292 | /** Find the peer entry in list with mac_addr equal to mac. 293 | * 294 | * Does not modify the list. 295 | * 296 | * @return NULL if not found; otherwise pointer to peer entry. 297 | */ 298 | struct peer_info * find_peer_by_mac( struct peer_info * list, const n2n_mac_t mac ) 299 | { 300 | while(list != NULL) 301 | { 302 | if( 0 == memcmp(mac, list->mac_addr, 6) ) 303 | { 304 | return list; 305 | } 306 | list = list->next; 307 | } 308 | 309 | return NULL; 310 | } 311 | 312 | 313 | /** Return the number of elements in the list. 314 | * 315 | */ 316 | size_t peer_list_size( const struct peer_info * list ) 317 | { 318 | size_t retval=0; 319 | 320 | while ( list ) { 321 | ++retval; 322 | list = list->next; 323 | } 324 | 325 | return retval; 326 | } 327 | 328 | /** Add new to the head of list. If list is NULL; create it. 329 | * 330 | * The item new is added to the head of the list. New is modified during 331 | * insertion. list takes ownership of new. 332 | */ 333 | void peer_list_add(struct peer_info * * list, 334 | struct peer_info * element ) 335 | { 336 | element->next = *list; 337 | element->last_seen = time(NULL); 338 | *list = element; 339 | } 340 | 341 | 342 | size_t purge_expired_registrations( struct peer_info ** peer_list ) { 343 | static time_t last_purge = 0; 344 | time_t now = time(NULL); 345 | size_t num_reg = 0; 346 | 347 | if ((now - last_purge) < PURGE_REGISTRATION_FREQUENCY) 348 | return 0; 349 | 350 | traceEvent(TRACE_INFO, "Purging old registrations"); 351 | 352 | num_reg = purge_peer_list( peer_list, now-REGISTRATION_TIMEOUT ); 353 | 354 | last_purge = now; 355 | traceEvent(TRACE_INFO, "Remove %ld registrations", num_reg); 356 | 357 | return num_reg; 358 | } 359 | 360 | /** Purge old items from the peer_list and return the number of items that were removed. */ 361 | size_t purge_peer_list( struct peer_info ** peer_list, 362 | time_t purge_before ) 363 | { 364 | struct peer_info *scan; 365 | struct peer_info *prev; 366 | size_t retval=0; 367 | 368 | scan = *peer_list; 369 | prev = NULL; 370 | while(scan != NULL) { 371 | if(scan->last_seen < purge_before) { 372 | struct peer_info *next = scan->next; 373 | 374 | if(prev == NULL) { 375 | *peer_list = next; 376 | } else { 377 | prev->next = next; 378 | } 379 | 380 | ++retval; 381 | free(scan); 382 | scan = next; 383 | } else { 384 | prev = scan; 385 | scan = scan->next; 386 | } 387 | } 388 | 389 | return retval; 390 | } 391 | 392 | /** Purge all items from the peer_list and return the number of items that were removed. */ 393 | size_t clear_peer_list( struct peer_info ** peer_list ) 394 | { 395 | struct peer_info *scan; 396 | struct peer_info *prev; 397 | size_t retval=0; 398 | 399 | scan = *peer_list; 400 | prev = NULL; 401 | while(scan != NULL) { 402 | struct peer_info *next = scan->next; 403 | 404 | if(prev == NULL) { 405 | *peer_list = next; 406 | } else { 407 | prev->next = next; 408 | } 409 | 410 | ++retval; 411 | free(scan); 412 | scan = next; 413 | } 414 | 415 | return retval; 416 | } 417 | 418 | char * sock_to_cstr( n2n_sock_str_t out, const n2n_sock_t * sock ) 419 | { 420 | ipstr_t buffer; 421 | 422 | if ( NULL == out ) { return NULL; } 423 | memset(out, 0, N2N_SOCKBUF_SIZE); 424 | 425 | if ( AF_INET6 == sock->family ) 426 | { 427 | inet_ntop(AF_INET6, &sock->addr, buffer, sizeof(buffer)); 428 | snprintf( out, N2N_SOCKBUF_SIZE, "[%s]:%hu", buffer, sock->port ); 429 | return out; 430 | } 431 | else 432 | { 433 | inet_ntop(AF_INET, &sock->addr, buffer, sizeof(buffer)); 434 | snprintf( out, N2N_SOCKBUF_SIZE, "%s:%hu", buffer, sock->port ); 435 | return out; 436 | } 437 | } 438 | 439 | uint32_t ip4_prefixlen_to_netmask(uint8_t prefixlen) { 440 | return prefixlen ? htonl(~((1 << (32 - prefixlen)) - 1)) : 0; 441 | } 442 | 443 | /* @return zero if the two sockets are equivalent. */ 444 | int sock_equal( const n2n_sock_t * a, 445 | const n2n_sock_t * b ) 446 | { 447 | if ( a->port != b->port ) { return 1; } 448 | if ( a->family != b->family ) { return 1; } 449 | switch (a->family) /* they are the same */ 450 | { 451 | case AF_INET: 452 | if ( 0 != memcmp( a->addr.v4, b->addr.v4, IPV4_SIZE ) ) { return 1;}; 453 | break; 454 | default: 455 | if ( 0 != memcmp( a->addr.v6, b->addr.v6, IPV6_SIZE ) ) { return 1;}; 456 | break; 457 | } 458 | 459 | return 0; 460 | } 461 | --------------------------------------------------------------------------------