Move CABAL branch to its rightful place: the trunk.
authorGuus Sliepen <guus@tinc-vpn.org>
Sun, 21 Mar 2004 13:22:24 +0000 (13:22 +0000)
committerGuus Sliepen <guus@tinc-vpn.org>
Sun, 21 Mar 2004 13:22:24 +0000 (13:22 +0000)
97 files changed:
.cvsignore [deleted file]
COPYING.README [new file with mode: 0644]
Makefile.am
NEWS
README
TODO
autogen.sh [deleted file]
configure.in
cvsusers [deleted file]
doc/.cvsignore [deleted file]
doc/CONNECTIVITY
doc/NETWORKING
doc/PROTOCOL
doc/SECURITY2
doc/SECURITY3 [deleted file]
doc/tinc.conf.5.in
doc/tinc.texi
doc/tincd.8.in
lib/.cvsignore [deleted file]
lib/Makefile.am
lib/avl_tree.c
lib/avl_tree.h
lib/dropin.c
lib/dropin.h
lib/ethernet.h
lib/fake-gai-errnos.h
lib/fake-getaddrinfo.c
lib/fake-getaddrinfo.h
lib/fake-getnameinfo.h
lib/hooks.c [deleted file]
lib/ipv4.h
lib/ipv6.h
lib/list.c
lib/list.h
lib/pidfile.c
lib/pidfile.h
m4/.cvsignore [deleted file]
m4/Makefile.am [new file with mode: 0644]
m4/attribute.m4
m4/lzo.m4
m4/malloc.m4
m4/openssl.m4
m4/realloc.m4
m4/tuntap.m4
m4/zlib.m4
po/.cvsignore [deleted file]
po/Makevars
po/nl.po
po/old/es.po [new file with mode: 0644]
src/.cvsignore [deleted file]
src/Makefile.am
src/conf.c
src/conf.h
src/connection.c
src/connection.h
src/cygwin/device.c
src/darwin/device.c
src/device.h
src/edge.c
src/edge.h
src/event.c
src/event.h
src/freebsd/device.c
src/graph.c
src/graph.h
src/linux/device.c
src/logger.c
src/meta.c
src/meta.h
src/mingw/device.c
src/net.c
src/net.h
src/net_packet.c
src/net_setup.c
src/net_socket.c
src/netbsd/device.c
src/netutl.c
src/netutl.h
src/node.c
src/node.h
src/openbsd/device.c
src/process.c
src/process.h
src/protocol.c
src/protocol.h
src/protocol_auth.c
src/protocol_edge.c
src/protocol_key.c
src/protocol_misc.c
src/protocol_subnet.c
src/raw_socket/device.c
src/route.c
src/route.h
src/solaris/device.c
src/subnet.c
src/subnet.h
src/tincd.c

diff --git a/.cvsignore b/.cvsignore
deleted file mode 100644 (file)
index 2a3df8e..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Makefile Makefile.in aclocal.m4 config.cache config.log config.status configure
-config.guess config.sub install-sh missing mkinstalldirs ChangeLog
-config.h.in stamp-h.in config.h libtool stamp-h build-stamp
-intl
diff --git a/COPYING.README b/COPYING.README
new file mode 100644 (file)
index 0000000..26b4b1d
--- /dev/null
@@ -0,0 +1,14 @@
+The following applies to tinc:
+
+This program is released under the GPL with the additional exemption that
+compiling, linking, and/or using OpenSSL is allowed.  You may provide binary
+packages linked to the OpenSSL libraries, provided that all other requirements
+of the GPL are met.
+
+The following applies to the LZO library:
+
+Hereby I grant a special exception to the tinc VPN project
+(http://tinc.nl.linux.org/) to link the LZO library with the OpenSSL library
+(http://www.openssl.org).
+
+Markus F.X.J. Oberhumer
index 8462e68..0667a87 100644 (file)
@@ -8,20 +8,11 @@ ACLOCAL_AMFLAGS = -I m4
 
 EXTRA_DIST = config.rpath mkinstalldirs system.h COPYING.README depcomp
 
-CVS_CREATED = ABOUT-NLS configure aclocal.m4 config.h.in config.guess \
- config.sub install-sh ltconfig ltmain.sh missing mkinstalldirs \
- stamp-h.in m4/Makefile.am ChangeLog po/Makefile.in.in \
- po/tinc.pot po/*.sed po/*.header po/*.sin po/Rules-quot \
- src/.libs intl depcomp
-
 ChangeLog:
-       cvs2cl -U cvsusers --fsf
+       svn log > ChangeLog
 
-cvs-clean: maintainer-clean
-       for f in $(CVS_CREATED) `find . -name Makefile.in` tinc-$(VERSION).tar.gz; do\
-         rm -Rf "$$f"; \
-       done
-       grep -l gettext `find m4 -type f` | xargs rm -f
+svn-clean: maintainer-clean
+       svn status --no-ignore | sed -n 's/^[?I] \+//p' | tr '\012' '\0' | xargs -r0 rm -rf
 
 deb:
        dpkg-buildpackage -rfakeroot
diff --git a/NEWS b/NEWS
index 4c7c939..897719c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,18 @@
+version 1.0.2                Nov  8 2003
+
+* Fix address and hostname resolving under Windows.
+
+* Remove warnings about non-existing scripts and unsupported address families.
+
+* Use the event logger under Windows.
+
+* Fix quoting of filenames and command line arguments under Windows.
+
+* Strict checks for length incoming network packets and return values of
+  cryptographic functions,
+
+* Fix a bug in metadata handling that made the tinc daemon abort.
+
 version 1.0.1                Aug 14 2003
 
 * Allow empty lines in config files.
diff --git a/README b/README
index 1024d60..243f0ef 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-This is the README file for tinc version 1.0.1. Installation
+This is the README file for tinc version 1.0.2. Installation
 instructions may be found in the INSTALL file.
 
 tinc is Copyright (C) 1998-2003 by:
@@ -31,6 +31,14 @@ launch a denial of service attack by replaying intercepted packets. The current
 version adds sequence numbers and message authentication codes to prevent such
 attacks.
 
+On September the 15th of 2003, Peter Gutmann contacted us and showed us a
+writeup describing various security issues in several VPN daemons. He showed
+that tinc lacks perfect forward security, the connection authentication could
+be done more properly, that the sequence number we use as an IV is not the best
+practice and that the default length of the HMAC for packets is too short in
+his opinion. We do not know of a way to exploit these weaknesses, but we will
+address these issues in tinc 2.0.
+
 Cryptography is a hard thing to get right. We cannot make any
 guarantees. Time, review and feedback are the only things that can
 prove the security of any cryptographic product. If you wish to review
@@ -47,7 +55,7 @@ should be changed into "Device", and "Device" should be changed into
 Compatibility
 -------------
 
-Version 1.0.1 is compatible with 1.0 and 1.0pre8 but not with older versions
+Version 1.0.2 is compatible with 1.0.1, 1.0 and 1.0pre8 but not with older versions
 of tinc.
 
 
diff --git a/TODO b/TODO
index 4c4938e..d6a6df4 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,14 +1,3 @@
 TODO LIST
 
-* Stop using UDP source address as the identifier of the remote tinc daemon.
-  Use a unique number sent along with ANS_KEY.
-
-* Efficient multicast support.
-
-* Check if caches using hash tables speed up route.c.
-
-* Streamline the meta protocol. Use a binary format?
-
-* Add (hooks for) a (graphical) frontend, like Pokey.
-
-* Implement future goals as mentioned on the website.
+* Think of new things to do.
diff --git a/autogen.sh b/autogen.sh
deleted file mode 100644 (file)
index ecdd701..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-#!/bin/sh
-# Run this to generate all the initial makefiles,
-# etc. just after a checkout.
-
-DIE=0
-
-if ${MAKE:-gmake} -q -C . autogen.sh 2> /dev/null
-then
-  alias make=${MAKE:-gmake}
-fi
-
-srcdir="`/bin/pwd`"
-
-(autoconf --version) < /dev/null > /dev/null 2>&1 || {
-  echo
-  echo "**Error**: You must have \`autoconf' installed to compile tinc."
-  echo "Download the appropriate package for your distribution,"
-  echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
-  DIE=1
-}
-
-(grep "^AM_PROG_LIBTOOL" $srcdir/configure.in >/dev/null) && {
-  (libtool --version) < /dev/null > /dev/null 2>&1 || {
-    echo
-    echo "**Error**: You must have \`libtool' installed to compile tinc."
-    echo "Get ftp://ftp.gnu.org/pub/gnu/libtool-1.2d.tar.gz"
-    echo "(or a newer version if it is available)"
-    DIE=1
-  }
-}
-
-grep "^AM_GNU_GETTEXT" $srcdir/configure.in >/dev/null && {
-  grep "sed.*POTFILES" $srcdir/configure.in >/dev/null || \
-  (gettext --version) < /dev/null > /dev/null 2>&1 || {
-    echo
-    echo "**Error**: You must have \`gettext' installed to compile tinc."
-    echo "Get ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz"
-    echo "(or a newer version if it is available)"
-    DIE=1
-  }
-}
-
-grep "^AM_GNOME_GETTEXT" $srcdir/configure.in >/dev/null && {
-  grep "sed.*POTFILES" $srcdir/configure.in >/dev/null || \
-  (gettext --version) < /dev/null > /dev/null 2>&1 || {
-    echo
-    echo "**Error**: You must have \`gettext' installed to compile tinc."
-    echo "Get ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz"
-    echo "(or a newer version if it is available)"
-    DIE=1
-  }
-}
-
-(automake --version) < /dev/null > /dev/null 2>&1 || {
-  echo
-  echo "**Error**: You must have \`automake' installed to compile tinc."
-  echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
-  echo "(or a newer version if it is available)"
-  DIE=1
-  NO_AUTOMAKE=yes
-}
-
-
-# if no automake, don't bother testing for aclocal
-test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
-  echo
-  echo "**Error**: Missing \`aclocal'.  The version of \`automake'"
-  echo "installed doesn't appear recent enough."
-  echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
-  echo "(or a newer version if it is available)"
-  DIE=1
-}
-
-if test "$DIE" -eq 1; then
-  exit 1
-fi
-
-if test -z "$*"; then
-  echo "**Warning**: I am going to run \`configure' with no arguments."
-  echo "If you wish to pass any to it, please specify them on the"
-  echo \`$0\'" command line."
-  echo
-fi
-
-case $CC in
-xlc )
-  am_opt=--include-deps;;
-esac
-
-for coin in `find $srcdir -name configure.in -print`
-do 
-  dr=`dirname $coin`
-  if test -f $dr/NO-AUTO-GEN; then
-    echo skipping $dr -- flagged as no auto-gen
-  else
-    echo processing $dr
-    macrodirs=`sed -n -e 's,AM_ACLOCAL_INCLUDE(\(.*\)),\1,gp' < $coin`
-    ( cd $dr
-      if grep "^AM_GNU_GETTEXT" configure.in >/dev/null; then
-       if grep "sed.*POTFILES" configure.in >/dev/null; then
-         : do nothing -- we still have an old unmodified configure.in
-       else
-         echo "Creating $dr/aclocal.m4 ..."
-         test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
-         echo "Running autopoint..."
-         autopoint --force
-         echo "Making $dr/aclocal.m4 writable ..."
-         test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
-        fi
-      fi
-      if grep "^AM_GNOME_GETTEXT" configure.in >/dev/null; then
-       echo "Creating $dr/aclocal.m4 ..."
-       test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
-       echo "Running autopoint..."
-       autopoint --force
-       echo "Making $dr/aclocal.m4 writable ..."
-       test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
-      fi
-      if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then
-       echo "Running libtoolize..."
-       libtoolize --force --copy
-      fi
-      aclocalinclude="$ACLOCAL_FLAGS"
-      for k in $macrodirs; do
-       if test -d $k; then
-         if test -f $k/Makefile.am.in; then
-           make -C $k -f Makefile.am.in Makefile.am
-         fi
-          aclocalinclude="$aclocalinclude -I $k"
-       ##else 
-       ##  echo "**Warning**: No such directory \`$k'.  Ignored."
-        fi
-      done
-      touch ChangeLog
-      echo "Running aclocal $aclocalinclude ..."
-      aclocal $aclocalinclude
-      if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then
-       echo "Running autoheader..."
-       autoheader
-      fi
-      echo "Running automake --gnu $am_opt ..."
-      automake --add-missing --gnu $am_opt
-      echo "Running autoconf ..."
-      autoconf
-    )
-  fi
-done
-
-conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
-
-if test x$NOCONFIGURE = x; then
-  echo Running $srcdir/configure $conf_flags "$@" ...
-  $srcdir/configure $conf_flags "$@" \
-  && echo Now type \`make\' to compile $PKG_NAME || exit 1
-else
-  echo Skipping configure process.
-fi
index eae2c3e..708f171 100644 (file)
@@ -1,11 +1,12 @@
 dnl Process this file with autoconf to produce a configure script.
 
-dnl $Id: configure.in,v 1.21 2003/08/24 20:50:30 guus Exp $
+dnl $Id: configure.in,v 1.13.2.86 2004/01/10 23:21:36 guus Exp $
 
-AC_PREREQ(2.57)
-AC_INIT(src/tincd.c)
-AM_INIT_AUTOMAKE(tinc, 2.0-cvs)
-AM_CONFIG_HEADER(config.h)
+AC_PREREQ(2.59)
+AC_INIT
+AC_CONFIG_SRCDIR([src/tincd.c])
+AM_INIT_AUTOMAKE(tinc, 1.0-cvs)
+AC_CONFIG_HEADERS([config.h])
 AM_MAINTAINER_MODE
 
 dnl Include the macros from the m4/ directory
@@ -197,7 +198,7 @@ AC_STRUCT_TM
 
 tinc_ATTRIBUTE(__malloc__)
 
-AC_CHECK_TYPES([socklen_t, struct arphdr, struct ether_arp, struct in_addr, struct addrinfo, struct ip, struct icmp, struct in6_addr, struct sockaddr_in6, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , ,
+AC_CHECK_TYPES([socklen_t, struct ether_header, struct arphdr, struct ether_arp, struct in_addr, struct addrinfo, struct ip, struct icmp, struct in6_addr, struct sockaddr_in6, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , ,
   [#ifdef HAVE_SYS_TYPES_H
    #include <sys/types.h>
    #endif
@@ -253,7 +254,7 @@ dnl Checks for library functions.
 AC_FUNC_MEMCMP
 AC_FUNC_ALLOCA
 AC_TYPE_SIGNAL
-AC_CHECK_FUNCS([asprintf daemon fchmod fcloseall flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system unsetenv vsyslog])
+AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system unsetenv vsyslog])
 jm_FUNC_MALLOC
 jm_FUNC_REALLOC
 
@@ -284,13 +285,13 @@ tinc_LZO
 
 dnl Check if support for jumbograms is requested 
 AC_ARG_ENABLE(jumbograms,
-  AC_HELP_STRING([--enable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]),
+  AS_HELP_STRING([--enable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]),
   [ AC_DEFINE(ENABLE_JUMBOGRAMS, 1, [Support for jumbograms (packets up to 9000 bytes)]) ]
 )
 
 dnl Check if checkpoint tracing has to be enabled
 AC_ARG_ENABLE(tracing,
-  AC_HELP_STRING([--enable-tracing], [enable checkpoint tracing (debugging only)]),
+  AS_HELP_STRING([--enable-tracing], [enable checkpoint tracing (debugging only)]),
   [ AC_DEFINE(ENABLE_TRACING, 1, [Checkpoint tracing]) ]
 )
 
diff --git a/cvsusers b/cvsusers
deleted file mode 100644 (file)
index 24b8504..0000000
--- a/cvsusers
+++ /dev/null
@@ -1,3 +0,0 @@
-zarq:Ivo Timmermans <ivo@o2w.nl>
-guus:Guus Sliepen <guus@sliepen.eu.org>
-wsl:Wessel Dankers <wsl@nl.linux.org>
diff --git a/doc/.cvsignore b/doc/.cvsignore
deleted file mode 100644 (file)
index d99f5fe..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Makefile.in Makefile tinc.info sample-config.tar.gz
index 3af434f..6cf16dd 100644 (file)
@@ -12,7 +12,7 @@ maintain a stable network.
    provided that the entire resulting derived work is distributed
    under the terms of a permission notice identical to this one.
 
-   $Id: CONNECTIVITY,v 1.3 2003/08/24 20:38:18 guus Exp $
+   $Id: CONNECTIVITY,v 1.1.2.11 2002/09/16 14:08:04 wsl Exp $
 
 1. Synchronisation
 ==================
index 2162dae..053f5bf 100644 (file)
@@ -12,7 +12,7 @@ Network daemon.
    provided that the entire resulting derived work is distributed
    under the terms of a permission notice identical to this one.
 
-   $Id: NETWORKING,v 1.3 2003/08/24 20:38:18 guus Exp $
+   $Id: NETWORKING,v 1.1.2.3 2002/06/21 10:11:10 guus Exp $
 
 1. Packet flow
 ==============
index 727ba79..795be83 100644 (file)
@@ -12,7 +12,7 @@ This is the protocol documentation for tinc, a Virtual Private Network daemon.
    provided that the entire resulting derived work is distributed
    under the terms of a permission notice identical to this one.
 
-   $Id: PROTOCOL,v 1.3 2003/08/24 20:38:18 guus Exp $
+   $Id: PROTOCOL,v 1.1.2.8 2002/09/15 22:19:37 guus Exp $
 
 
 1.  Protocols used in tinc
index 138500e..9b375c2 100644 (file)
@@ -12,7 +12,7 @@ This is the security documentation for tinc, a Virtual Private Network daemon.
    provided that the entire resulting derived work is distributed
    under the terms of a permission notice identical to this one.
 
-   $Id: SECURITY2,v 1.3 2003/08/24 20:38:18 guus Exp $
+   $Id: SECURITY2,v 1.1.2.4 2002/09/15 22:19:37 guus Exp $
 
 Proposed new authentication scheme
 ----------------------------------
diff --git a/doc/SECURITY3 b/doc/SECURITY3
deleted file mode 100644 (file)
index 97270a1..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-This is the security documentation for tinc, a Virtual Private Network daemon.
-
-   Copyright 2001-2003 Guus Sliepen <guus@sliepen.eu.org>,
-             2001-2003 Wessel Dankers <wsl@nl.linux.org>
-
-   Permission is granted to make and distribute verbatim copies of
-   this documentation provided the copyright notice and this
-   permission notice are preserved on all copies.
-
-   Permission is granted to copy and distribute modified versions of
-   this documentation under the conditions for verbatim copying,
-   provided that the entire resulting derived work is distributed
-   under the terms of a permission notice identical to this one.
-
-   $Id: SECURITY3,v 1.1 2003/10/01 09:43:01 guus Exp $
-
-Proposed authentication scheme for tinc 2.0
--------------------------------------------
-
-daemon  message
---------------------------------------------------------------------------
-A       <attempts connection>
-
-B       <accepts connection>
-
-A       ID "A" <version> <cipher> <digest> <compression>
-
-B       ID "B" <version> <cipher> <digest> <compression>
-
-A       META_KEY <Diffie-Hellman public key> <nonce> <signature>
-
-        Where signature is that of the public key and nonce, using A's
-       private RSA key.
-
-B       META_KEY <Diffie-Hellman public key> <nonce> <signature>
-
-Both sides now use Diffie-Hellman to compute the shared secret key. Because
-only A and B can decrypt the respective public keys, only A and B can know this
-shared key.
-
-From the shared key the following things will be derived:
-
-A's symmetric cipher key
-A's symmetric cipher IV
-A's HMAC key
-A's verification data
-B's symmetric cipher key
-B's symmetric cipher IV
-B's HMAC key
-B's verification data
-
-From now on:
- - A will symmetrically encrypt outgoing traffic using A's symmetric cipher key
- - B will symmetrically encrypt outgoing traffic using B's symmetric cipher key
-
-A       ACK <A's verification data> <port> <weight> <options>
-
-B       ACK <B's verification data> <port> <weight> <options>
-
-After ACKs with the correct verification messages have been recieved, both ends have proved
-their identity.
--------------------------------------------------------------------------
-
-Changes from the protocol used in tinc 1.0pre5 up to 1.0.1:
-
-Instead of directly sending the keys which will be used for symmetric
-encryption, a Diffie-Hellman key exchange will be done.  This prevents an
-attacker from being able to send and use his own key if he can't read the key
-that is sent to him.  It also allows us to have perfect forward security, since
-only public keys are exchanged in the Diffie-Hellman key exchange, so after the
-RSA keys have been compromised it still is not possible to recover the shared
-key from recorded authentications from the past.
-
-The CHALLENGE/RESPONSE messages have been replaced by verification data in the
-ACK message, which saves two round trips.
-
-The ID messages will also contain information about the cipher and digest
-algorithm and compression to use for encrypting the TCP connections.
-
index 7257bfe..87106a0 100644 (file)
@@ -219,6 +219,11 @@ Note that there must be exactly one of
 or
 .Va PrivateKeyFile
 specified in the configuration file.
+.It Va TunnelServer Li = yes | no Po no Pc Bq experimental
+When this option is enabled tinc will no longer forward information between other tinc daemons,
+and will only allow nodes and subnets on the VPN which are present in the
+.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
+directory.
 .El
 .Sh HOST CONFIGURATION FILES
 The host configuration files contain all information needed
@@ -246,6 +251,7 @@ Any cipher supported by OpenSSL is recognised.
 Furthermore, specifying
 .Qq none
 will turn off packet encryption.
+It is best to use only those ciphers which support CBC mode.
 .It Va Compression Li = Ar level Pq 0
 This option sets the level of compression used for UDP packets.
 Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib),
@@ -268,6 +274,11 @@ The length of the message authentication code used to authenticate UDP packets.
 Can be anything from
 .Qq 0
 up to the length of the digest produced by the digest algorithm.
+.It Va PMTU Li = Ar mtu Po 1514 Pc Bq experimental
+This option controls the initial path MTU to this node.
+.It Va PMTUDiscovery Li = yes | no Po no Pc Bq experimental
+When this option is enabled, tinc will try to discover the path MTU to this node.
+After the path MTU has been discovered, it will be enforced on the VPN.
 .It Va Port Li = Ar port Pq 655
 The port number on which this tinc daemon is listening for incoming connections.
 .It Va PublicKey Li = Ar key Bq obsolete
@@ -314,7 +325,7 @@ Setting this options also implicitly sets IndirectData.
 .Sh SCRIPTS
 Apart from reading the server and host configuration files,
 tinc can also run scripts at certain moments.
-On Windows (not Cygwin), the scripts should have the extension
+Under Windows (not Cygwin), the scripts should have the extension
 .Pa .bat .
 .Bl -tag -width indent
 .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
index 2132251..33a3529 100644 (file)
@@ -1,5 +1,5 @@
 \input texinfo   @c -*-texinfo-*-
-@c $Id: tinc.texi,v 1.10 2003/08/24 20:38:19 guus Exp $
+@c $Id: tinc.texi,v 1.8.4.46 2003/10/11 14:42:29 guus Exp $
 @c %**start of header
 @setfilename tinc.info
 @settitle tinc Manual
@@ -20,7 +20,7 @@ Copyright @copyright{} 1998-2003 Ivo Timmermans
 <ivo@@o2w.nl>, Guus Sliepen <guus@@sliepen.eu.org> and
 Wessel Dankers <wsl@@nl.linux.org>.
 
-$Id: tinc.texi,v 1.10 2003/08/24 20:38:19 guus Exp $
+$Id: tinc.texi,v 1.8.4.46 2003/10/11 14:42:29 guus Exp $
 
 Permission is granted to make and distribute verbatim copies of this
 manual provided the copyright notice and this permission notice are
@@ -47,7 +47,7 @@ Copyright @copyright{} 1998-2003 Ivo Timmermans
 <ivo@@o2w.nl>, Guus Sliepen <guus@@sliepen.eu.org> and
 Wessel Dankers <wsl@@nl.linux.org>.
 
-$Id: tinc.texi,v 1.10 2003/08/24 20:38:19 guus Exp $
+$Id: tinc.texi,v 1.8.4.46 2003/10/11 14:42:29 guus Exp $
 
 Permission is granted to make and distribute verbatim copies of this
 manual provided the copyright notice and this permission notice are
@@ -60,8 +60,10 @@ permission notice identical to this one.
 
 @end titlepage
 
+@ifinfo
 @c ==================================================================
-@node Top, Introduction, (dir), (dir)
+@node Top
+@top Top
 
 @menu
 * Introduction::
@@ -70,19 +72,18 @@ permission notice identical to this one.
 * Configuration::
 * Running tinc::
 * Technical information::
+* Platform specific information::
 * About us::
 * Concept Index::               All used terms explained
 @end menu
-
-
-@contents
+@end ifinfo
 
 @c ==================================================================
-@node    Introduction, Preparations, Top, Top
+@node    Introduction
 @chapter Introduction
 
 @cindex tinc
-tinc is a Virtual Private Network (VPN) daemon that uses tunneling and
+Tinc is a Virtual Private Network (VPN) daemon that uses tunneling and
 encryption to create a secure private network between hosts on the
 Internet.
 
@@ -102,7 +103,7 @@ process of tinc itself.
 @end menu
 
 @c ==================================================================
-@node    Virtual Private Networks, tinc, Introduction, Introduction
+@node    Virtual Private Networks
 @section Virtual Private Networks
 
 @cindex VPN
@@ -140,7 +141,7 @@ through the VPN.  This is what tinc was made for.
 
 
 @c ==================================================================
-@node    tinc, Supported platforms, Virtual Private Networks, Introduction
+@node    tinc
 @section tinc
 
 @cindex vpnd
@@ -148,22 +149,22 @@ I really don't quite remember what got us started, but it must have been
 Guus' idea.  He wrote a simple implementation (about 50 lines of C) that
 used the ethertap device that Linux knows of since somewhere
 about kernel 2.1.60.  It didn't work immediately and he improved it a
-bit.  At this stage, the project was still simply called @samp{vpnd}.
+bit.  At this stage, the project was still simply called "vpnd".
 
 Since then, a lot has changed---to say the least.
 
 @cindex tincd
-tinc now supports encryption, it consists of a single daemon (tincd) for
+Tinc now supports encryption, it consists of a single daemon (tincd) for
 both the receiving and sending end, it has become largely
 runtime-configurable---in short, it has become a full-fledged
 professional package.
 
-@cindex Traditional VPNs
+@cindex traditional VPNs
 @cindex scalability
-tinc also allows more than two sites to connect to eachother and form a single VPN.
+Tinc also allows more than two sites to connect to eachother and form a single VPN.
 Traditionally VPNs are created by making tunnels, which only have two endpoints.
 Larger VPNs with more sites are created by adding more tunnels.
-tinc takes another approach: only endpoints are specified,
+Tinc takes another approach: only endpoints are specified,
 the software itself will take care of creating the tunnels.
 This allows for easier configuration and improved scalability.
 
@@ -177,11 +178,11 @@ available too.
 
 
 @c ==================================================================
-@node    Supported platforms,  , tinc, Introduction
+@node    Supported platforms
 @section Supported platforms
 
 @cindex platforms
-tinc has been verified to work under Linux, FreeBSD, OpenBSD, NetBSD, MacOS/X (Darwin), Solaris, and Windows (both natively and in a Cygwin environment),
+Tinc has been verified to work under Linux, FreeBSD, OpenBSD, NetBSD, MacOS/X (Darwin), Solaris, and Windows (both natively and in a Cygwin environment),
 with various hardware architectures.  These are some of the platforms
 that are supported by the universal tun/tap device driver or other virtual network device drivers.
 Without such a driver, tinc will most
@@ -198,14 +199,14 @@ our website:
 @subsection Linux
 
 @cindex Linux
-tinc was first written for Linux running on an intel x86 processor, so
+Tinc was first written for Linux running on an intel x86 processor, so
 this is the best supported platform.  The protocol however, and actually
 anything about tinc, has been rewritten to support random byte ordering
 and arbitrary word length.  So in theory it should run on other
 processors that Linux runs on.  It has already been verified to run on
 alpha and sparc processors as well.
 
-tinc uses the ethertap device or the universal tun/tap driver. The former is provided in the standard kernel
+Tinc uses the ethertap device or the universal tun/tap driver. The former is provided in the standard kernel
 from version 2.1.60 up to 2.3.x, but has been replaced in favour of the tun/tap driver in kernel versions 2.4.0 and later.
 
 
@@ -213,7 +214,7 @@ from version 2.1.60 up to 2.3.x, but has been replaced in favour of the tun/tap
 @subsection FreeBSD
 
 @cindex FreeBSD
-tinc on FreeBSD relies on the universal tun/tap driver for its data
+Tinc on FreeBSD relies on the universal tun/tap driver for its data
 acquisition from the kernel.  Therefore, tinc will work on the same platforms
 as this driver.  These are: FreeBSD 3.x, 4.x, 5.x.
 
@@ -222,7 +223,7 @@ as this driver.  These are: FreeBSD 3.x, 4.x, 5.x.
 @subsection OpenBSD
 
 @cindex OpenBSD
-tinc on OpenBSD relies on the tun driver for its data
+Tinc on OpenBSD relies on the tun driver for its data
 acquisition from the kernel. It has been verified to work under at least OpenBSD 2.9.
 
 Tunneling IPv6 packets may not work on OpenBSD.
@@ -235,7 +236,7 @@ Tunneling IPv6 packets may not work on OpenBSD.
 @subsection NetBSD
 
 @cindex NetBSD
-tinc on NetBSD relies on the tun driver for its data
+Tinc on NetBSD relies on the tun driver for its data
 acquisition from the kernel. It has been verified to work under at least NetBSD 1.5.2.
 
 Tunneling IPv6 does not work on OpenBSD.
@@ -245,9 +246,9 @@ Tunneling IPv6 does not work on OpenBSD.
 @subsection Solaris
 
 @cindex Solaris
-tinc on Solaris relies on the universal tun/tap driver for its data
+Tinc on Solaris relies on the universal tun/tap driver for its data
 acquisition from the kernel.  Therefore, tinc will work on the same platforms
-as this driver.  These are: Solaris 8 (SunOS 5.8).
+as this driver. It has been verified to work under Solaris 8 (SunOS 5.8).
 
 IPv6 packets cannot be tunneled on Solaris.
 
@@ -256,7 +257,7 @@ IPv6 packets cannot be tunneled on Solaris.
 
 @cindex Darwin
 @cindex MacOS/X
-tinc on Darwin relies on the tunnel driver for its data
+Tinc on Darwin relies on the tunnel driver for its data
 acquisition from the kernel. This driver is not part of Darwin but can be
 downloaded from @uref{http://chrisp.de/en/projects/tunnel.html}.
 
@@ -266,7 +267,7 @@ IPv6 packets cannot be tunneled on Darwin.
 @subsection Windows
 
 @cindex Windows
-tinc on Windows, in a Cygwin environment, relies on the CIPE driver or the TAP-Win32 driver for its data
+Tinc on Windows, in a Cygwin environment, relies on the CIPE driver or the TAP-Win32 driver for its data
 acquisition from the kernel. This driver is not part of Windows but can be
 downloaded from @uref{http://cipe-win32.sourceforge.net/}.
 
@@ -285,7 +286,7 @@ downloaded from @uref{http://cipe-win32.sourceforge.net/}.
 @c
 
 @c ==================================================================
-@node    Preparations, Installation, Introduction, Top
+@node    Preparations
 @chapter Preparations
 
 This chapter contains information on how to prepare your system to
@@ -298,7 +299,7 @@ support tinc.
 
 
 @c ==================================================================
-@node    Configuring the kernel, Libraries, Preparations, Preparations
+@node    Configuring the kernel
 @section Configuring the kernel
 
 @cindex RedHat
@@ -334,7 +335,7 @@ you should read the @uref{http://howto.linuxberg.com/LDP/HOWTO/Kernel-HOWTO.html
 
 
 @c ==================================================================
-@node       Configuration of Linux kernels 2.1.60 up to 2.4.0, Configuration of Linux kernels 2.4.0 and higher, Configuring the kernel, Configuring the kernel
+@node       Configuration of Linux kernels 2.1.60 up to 2.4.0
 @subsection Configuration of Linux kernels 2.1.60 up to 2.4.0
 
 Here are the options you have to turn on when configuring a new kernel:
@@ -371,7 +372,7 @@ Add as much alias/options lines as necessary.
 
 
 @c ==================================================================
-@node       Configuration of Linux kernels 2.4.0 and higher, Configuration of FreeBSD kernels, Configuration of Linux kernels 2.1.60 up to 2.4.0, Configuring the kernel
+@node       Configuration of Linux kernels 2.4.0 and higher
 @subsection Configuration of Linux kernels 2.4.0 and higher
 
 Here are the options you have to turn on when configuring a new kernel:
@@ -400,7 +401,7 @@ alias char-major-10-200 tun
 
 
 @c ==================================================================
-@node       Configuration of FreeBSD kernels, Configuration of OpenBSD kernels, Configuration of Linux kernels 2.4.0 and higher, Configuring the kernel
+@node       Configuration of FreeBSD kernels
 @subsection Configuration of FreeBSD kernels
 
 For FreeBSD version 4.1 and higher, the tap driver is included in the default kernel configuration, for earlier
@@ -409,7 +410,7 @@ yourself.
 
 
 @c ==================================================================
-@node       Configuration of OpenBSD kernels, Configuration of NetBSD kernels, Configuration of FreeBSD kernels, Configuring the kernel
+@node       Configuration of OpenBSD kernels
 @subsection Configuration of OpenBSD kernels
 
 For OpenBSD version 2.9 and higher,
@@ -417,7 +418,7 @@ the tun driver is included in the default kernel configuration.
 
 
 @c ==================================================================
-@node       Configuration of NetBSD kernels, Configuration of Solaris kernels, Configuration of OpenBSD kernels, Configuring the kernel
+@node       Configuration of NetBSD kernels
 @subsection Configuration of NetBSD kernels
 
 For NetBSD version 1.5.2 and higher,
@@ -425,15 +426,18 @@ the tun driver is included in the default kernel configuration.
 
 
 @c ==================================================================
-@node       Configuration of Solaris kernels, Configuration of Darwin (MacOS/X) kernels, Configuration of NetBSD kernels, Configuring the kernel
+@node       Configuration of Solaris kernels
 @subsection Configuration of Solaris kernels
 
 For Solaris 8 (SunOS 5.8) and higher,
-the tun driver is included in the default kernel configuration.
+the tun driver may or may not be included in the default kernel configuration.
+If it isn't, the source can be downloaded from @uref{http://vtun.sourceforge.net/tun/}.
+For x86 and sparc64 architectures, precompiled versions can be found at @uref{http://www.monkey.org/~dugsong/fragroute/}.
+If the @file{net/if_tun.h} header file is missing, install it from the source package.
 
 
 @c ==================================================================
-@node       Configuration of Darwin (MacOS/X) kernels, Configuration of Windows, Configuration of Solaris kernels, Configuring the kernel
+@node       Configuration of Darwin (MacOS/X) kernels
 @subsection Configuration of Darwin (MacOS/X) kernels
 
 Darwin does not come with a tunnel driver. You must download it at
@@ -450,17 +454,18 @@ and the corresponding network interfaces.
 
 
 @c ==================================================================
-@node       Configuration of Windows,  , Configuration of Darwin (MacOS/X) kernels, Configuring the kernel
+@node       Configuration of Windows
 @subsection Configuration of Windows
 
-You will need to install the CIPE driver or the TAP-Win32 driver. You can download the CIPE driver from
-@uref{http://cipe-win32.sourceforge.net}.  Using the Network Connections control panel,
-configure the CIPE network device in the same way as you would do from the tinc-up script
-as explained in the rest of the documentation.
+You will need to install the CIPE-Win32 driver or the TAP-Win32 driver, it
+doesn't matter which one. You can download the CIPE driver from
+@uref{http://cipe-win32.sourceforge.net}.  Using the Network Connections
+control panel, configure the CIPE-Win32 or TAP-Win32 network interface in the same way as you would
+do from the tinc-up script as explained in the rest of the documentation.
 
 
 @c ==================================================================
-@node    Libraries,  , Configuring the kernel, Preparations
+@node    Libraries
 @section Libraries
 
 @cindex requirements
@@ -477,7 +482,7 @@ having them installed, configure will give you an error message, and stop.
 
 
 @c ==================================================================
-@node       OpenSSL, zlib, Libraries, Libraries
+@node       OpenSSL
 @subsection OpenSSL
 
 @cindex OpenSSL
@@ -514,10 +519,12 @@ to let configure know where they are, by passing configure one of the
 @subsubheading License
 
 @cindex license
+The complete source code of tinc is covered by the GNU GPL version 2.
 Since the license under which OpenSSL is distributed is not directly
 compatible with the terms of the GNU GPL
-@uref{http://www.openssl.org/support/faq.html#LEGAL2}, therefore we
-include an addition to the GPL (see also the file COPYING.README):
+@uref{http://www.openssl.org/support/faq.html#LEGAL2}, we
+include an exemption to the GPL (see also the file COPYING.README) to allow
+everyone to create a statically or dynamically linked executable:
 
 @quotation
 This program is released under the GPL with the additional exemption
@@ -526,9 +533,20 @@ provide binary packages linked to the OpenSSL libraries, provided that
 all other requirements of the GPL are met.
 @end quotation
 
+Since the LZO library used by tinc is also covered by the GPL,
+we also present the following exemption:
+
+@quotation
+Hereby I grant a special exception to the tinc VPN project
+(http://tinc.nl.linux.org/) to link the LZO library with the OpenSSL library
+(http://www.openssl.org).
+
+Markus F.X.J. Oberhumer
+@end quotation
+
 
 @c ==================================================================
-@node       zlib, lzo, OpenSSL, Libraries
+@node       zlib
 @subsection zlib
 
 @cindex zlib
@@ -551,7 +569,7 @@ default).
 
 
 @c ==================================================================
-@node       lzo,  , zlib, Libraries
+@node       lzo
 @subsection lzo
 
 @cindex lzo
@@ -582,7 +600,7 @@ default).
 @c
 
 @c ==================================================================
-@node    Installation, Configuration, Preparations, Top
+@node    Installation
 @chapter Installation
 
 If you use Debian, you may want to install one of the
@@ -596,7 +614,7 @@ the GNU General Public License (GPL).  Download the source from the
 the checksums of these files listed; you may wish to check these with
 md5sum before continuing.
 
-tinc comes in a convenient autoconf/automake package, which you can just
+Tinc comes in a convenient autoconf/automake package, which you can just
 treat the same as any other package.  Which is just untar it, type
 `./configure' and then `make'.
 More detailed instructions are in the file @file{INSTALL}, which is
@@ -609,7 +627,7 @@ included in the source distribution.
 
 
 @c ==================================================================
-@node    Building and installing tinc, System files, Installation, Installation
+@node    Building and installing tinc
 @section Building and installing tinc
 
 Detailed instructions on configuring the source, building tinc and installing tinc
@@ -628,7 +646,7 @@ The documentation that comes along with your distribution will tell you how to d
 
 
 @c ==================================================================
-@node       Darwin (MacOS/X) build environment, Cygwin (Windows) build environment, Building and installing tinc, Building and installing tinc
+@node       Darwin (MacOS/X) build environment
 @subsection Darwin (MacOS/X) build environment
 
 In order to build tinc on Darwin, you need to install the MacOS/X Developer Tools
@@ -639,7 +657,7 @@ After installation use fink to download and install the following packages:
 autoconf25, automake, dlcompat, m4, openssl, zlib and lzo.
 
 @c ==================================================================
-@node       Cygwin (Windows) build environment, MinGW (Windows) build environment, Darwin (MacOS/X) build environment, Building and installing tinc
+@node       Cygwin (Windows) build environment
 @subsection Cygwin (Windows) build environment
 
 If Cygwin hasn't already been installed, install it directly from
@@ -650,7 +668,7 @@ but all programs, including those started outside the Cygwin environment, will b
 It will also support all features.
 
 @c ==================================================================
-@node       MinGW (Windows) build environment,  , Cygwin (Windows) build environment, Building and installing tinc
+@node       MinGW (Windows) build environment
 @subsection MinGW (Windows) build environment
 
 You will need to install the MinGW environment from @uref{http://www.mingw.org}.
@@ -663,7 +681,7 @@ which will be restarted automatically after reboots.
 
 
 @c ==================================================================
-@node    System files,  , Building and installing tinc, Installation
+@node    System files
 @section System files
 
 Before you can run tinc, you must make sure you have all the needed
@@ -676,7 +694,7 @@ files on your system.
 
 
 @c ==================================================================
-@node       Device files, Other files, System files, System files
+@node       Device files
 @subsection Device files
 
 @cindex device files
@@ -716,7 +734,7 @@ you are planning to run multiple tinc daemons.
 
 
 @c ==================================================================
-@node       Other files,  , Device files, System files
+@node       Other files
 @subsection Other files
 
 @subsubheading @file{/etc/networks}
@@ -754,7 +772,7 @@ tinc            655/udp    TINC
 
 
 @c ==================================================================
-@node    Configuration, Running tinc, Installation, Top
+@node    Configuration
 @chapter Configuration
 
 @menu
@@ -768,7 +786,7 @@ tinc            655/udp    TINC
 @end menu
 
 @c ==================================================================
-@node    Configuration introduction, Multiple networks, Configuration, Configuration
+@node    Configuration introduction
 @section Configuration introduction
 
 Before actually starting to configure tinc and editing files,
@@ -796,14 +814,14 @@ These steps are described in the subsections below.
 
 
 @c ==================================================================
-@node    Multiple networks, How connections work, Configuration introduction, Configuration
+@node    Multiple networks
 @section Multiple networks
 
 @cindex multiple networks
 @cindex netname
 In order to allow you to run more than one tinc daemon on one computer,
 for instance if your computer is part of more than one VPN,
-you can assign a ``netname'' to your VPN.
+you can assign a @var{netname} to your VPN.
 It is not required if you only run one tinc daemon,
 it doesn't even have to be the same on all the sites of your VPN,
 but it is recommended that you choose one anyway.
@@ -813,14 +831,14 @@ This means that you call tincd with the -n argument,
 which will assign a netname to this daemon.
 
 The effect of this is that the daemon will set its configuration
-``root'' to @value{sysconfdir}/tinc/@var{netname}/, where @var{netname} is your argument to the -n
-option.  You'll notice that it appears in syslog as ``tinc.@var{netname}''.
+root to @file{@value{sysconfdir}/tinc/@var{netname}/}, where @var{netname} is your argument to the -n
+option.  You'll notice that it appears in syslog as @file{tinc.@var{netname}}.
 
 However, it is not strictly necessary that you call tinc with the -n
 option.  In this case, the network name would just be empty, and it will
-be used as such.  tinc now looks for files in @value{sysconfdir}/tinc/, instead of
-@value{sysconfdir}/tinc/@var{netname}/; the configuration file should be @value{sysconfdir}/tinc/tinc.conf,
-and the host configuration files are now expected to be in @value{sysconfdir}/tinc/hosts/.
+be used as such.  tinc now looks for files in @file{@value{sysconfdir}/tinc/}, instead of
+@file{@value{sysconfdir}/tinc/@var{netname}/}; the configuration file should be @file{@value{sysconfdir}/tinc/tinc.conf},
+and the host configuration files are now expected to be in @file{@value{sysconfdir}/tinc/hosts/}.
 
 But it is highly recommended that you use this feature of tinc, because
 it will be so much clearer whom your daemon talks to.  Hence, we will
@@ -828,7 +846,7 @@ assume that you use it.
 
 
 @c ==================================================================
-@node    How connections work, Configuration files, Multiple networks, Configuration
+@node    How connections work
 @section How connections work
 
 When tinc starts up, it parses the command-line options and then
@@ -853,7 +871,7 @@ It does not matter if two tinc daemons have a `ConnectTo' value pointing to each
 
 
 @c ==================================================================
-@node    Configuration files, Generating keypairs, How connections work, Configuration
+@node    Configuration files
 @section Configuration files
 
 The actual configuration of the daemon is done in the file
@@ -885,18 +903,18 @@ other comments are between square brackets.
 
 
 @c ==================================================================
-@node       Main configuration variables, Host configuration variables, Configuration files, Configuration files
+@node       Main configuration variables
 @subsection Main configuration variables
 
 @table @asis
 @cindex AddressFamily
-@item @var{AddressFamily} = <ipv4|ipv6|any> (any)
+@item AddressFamily = <ipv4|ipv6|any> (any)
 This option affects the address family of listening and outgoing sockets.
-If "any" is selected, then depending on the operating system
+If any is selected, then depending on the operating system
 both IPv4 and IPv6 or just IPv6 listening sockets will be created.
 
 @cindex BindToAddress
-@item @var{BindToAddress} = <address> [experimental]
+@item BindToAddress = <@var{address}> [experimental]
 If your computer has more than one IPv4 or IPv6 address, tinc
 will by default listen on all of them for incoming connections.
 It is possible to bind only to a single address with this variable.
@@ -904,7 +922,7 @@ It is possible to bind only to a single address with this variable.
 This option may not work on all platforms.
 
 @cindex BindToInterface
-@item @var{BindToInterface} = <interface> [experimental]
+@item BindToInterface = <@var{interface}> [experimental]
 If you have more than one network interface in your computer, tinc will
 by default listen on all of them for incoming connections.  It is
 possible to bind tinc to a single interface like eth0 or ppp0 with this
@@ -913,7 +931,7 @@ variable.
 This option may not work on all platforms.
 
 @cindex ConnectTo
-@item @var{ConnectTo} = <name>
+@item ConnectTo = <@var{name}>
 Specifies which other tinc daemon to connect to on startup.
 Multiple ConnectTo variables may be specified,
 in which case outgoing connections to each specified tinc daemon are made.
@@ -925,16 +943,16 @@ tinc won't try to connect to other daemons at all,
 and will instead just listen for incoming connections.
 
 @cindex Device
-@item @var{Device} = <device> (@file{/dev/tap0}, @file{/dev/net/tun} or other depending on platform)
+@item Device = <@var{device}> (@file{/dev/tap0}, @file{/dev/net/tun} or other depending on platform)
 The virtual network device to use.
-tinc will automatically detect what kind of device it is.
+Tinc will automatically detect what kind of device it is.
 Note that you can only use one device per daemon.
 Under Windows, use @var{Interface} instead of @var{Device}.
 Note that you can only use one device per daemon.
 See also @ref{Device files}.
 
 @cindex Hostnames
-@item @var{Hostnames} = <yes|no> (no)
+@item Hostnames = <yes|no> (no)
 This option selects whether IP addresses (both real and on the VPN)
 should be resolved.  Since DNS lookups are blocking, it might affect
 tinc's efficiency, even stopping the daemon for a few seconds everytime
@@ -944,14 +962,14 @@ This does not affect resolving hostnames to IP addresses from the
 configuration file.
 
 @cindex Interface
-@item @var{Interface} = <interface>
+@item Interface = <@var{interface}>
 Defines the name of the interface corresponding to the virtual network device.
 Depending on the operating system and the type of device this may or may not actually set the name of the interface.
 Under Windows, this variable is used to select which network interface will be used.
 If you specified a Device, this variable is almost always already correctly set.
 
 @cindex Mode
-@item @var{Mode} = <router|switch|hub> (router)
+@item Mode = <router|switch|hub> (router)
 This option selects the way packets are routed to other daemons.
 
 @table @asis
@@ -980,82 +998,84 @@ while no routing table is managed.
 @end table
 
 @cindex KeyExpire
-@item @var{KeyExpire} = <seconds> (3600)
+@item KeyExpire = <@var{seconds}> (3600)
 This option controls the time the encryption keys used to encrypt the data
 are valid.  It is common practice to change keys at regular intervals to
 make it even harder for crackers, even though it is thought to be nearly
 impossible to crack a single key.
 
 @cindex MACExpire
-@item @var{MACExpire} = <seconds> (600)
+@item MACExpire = <@var{seconds}> (600)
 This option controls the amount of time MAC addresses are kept before they are removed.
 This only has effect when Mode is set to "switch".
 
 @cindex Name
-@item @var{Name} = <name> [required]
+@item Name = <@var{name}> [required]
 This is a symbolic name for this connection.  It can be anything
 
 @cindex PingTimeout
-@item @var{PingTimeout} = <seconds> (60)
+@item PingTimeout = <@var{seconds}> (60)
 The number of seconds of inactivity that tinc will wait before sending a
 probe to the other end.  If that other end doesn't answer within that
 same amount of seconds, the connection is terminated, and the others
 will be notified of this.
 
 @cindex PriorityInheritance
-@item @var{PriorityInheritance} = <yes|no> (no) [experimental]
+@item PriorityInheritance = <yes|no> (no) [experimental]
 When this option is enabled the value of the TOS field of tunneled IPv4 packets
 will be inherited by the UDP packets that are sent out.
 
 @cindex PrivateKey
-@item @var{PrivateKey} = <key> [obsolete]
+@item PrivateKey = <@var{key}> [obsolete]
 This is the RSA private key for tinc. However, for safety reasons it is
 advised to store private keys of any kind in separate files. This prevents
 accidental eavesdropping if you are editting the configuration file.
 
 @cindex PrivateKeyFile
-@item @var{PrivateKeyFile} = <path> (@file{@value{sysconfdir}/tinc/@var{netname}/rsa_key.priv})
+@item PrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/rsa_key.priv})
 This is the full path name of the RSA private key file that was
-generated by ``tincd --generate-keys''.  It must be a full path, not a
+generated by @samp{tincd --generate-keys}.  It must be a full path, not a
 relative directory.
 
-Note that there must be exactly one of @var{PrivateKey}
-or @var{PrivateKeyFile}
+Note that there must be exactly one of PrivateKey
+or PrivateKeyFile
 specified in the configuration file.
 
 @end table
 
 
 @c ==================================================================
-@node       Host configuration variables, Scripts, Main configuration variables, Configuration files
+@node       Host configuration variables
 @subsection Host configuration variables
 
 @table @asis
 @cindex Address
-@item @var{Address} = <IP address|hostname> [recommended]
+@item Address = <@var{IP address}|@var{hostname}> [recommended]
 This variable is only required if you want to connect to this host.  It
 must resolve to the external IP address where the host can be reached,
 not the one that is internal to the VPN.
 
 @cindex Cipher
-@item @var{Cipher} = <cipher> (blowfish)
+@item Cipher = <@var{cipher}> (blowfish)
 The symmetric cipher algorithm used to encrypt UDP packets.
 Any cipher supported by OpenSSL is recognized.
+Furthermore, specifying "none" will turn off packet encryption.
+It is best to use only those ciphers which support CBC mode.
 
 @cindex Compression
-@item @var{Compression} = <level> (0)
+@item Compression = <@var{level}> (0)
 This option sets the level of compression used for UDP packets.
 Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib),
 10 (fast lzo) and 11 (best lzo).
 
 @cindex Digest
-@item @var{Digest} = <digest> (sha1)
+@item Digest = <@var{digest}> (sha1)
 The digest algorithm used to authenticate UDP packets.
 Any digest supported by OpenSSL is recognized.
 Furthermore, specifying "none" will turn off packet authentication.
 
 @cindex IndirectData
-@item @var{IndirectData} = <yes|no> (no)
+@item IndirectData = <yes|no> (no)
 This option specifies whether other tinc daemons besides the one you
 specified with ConnectTo can make a direct connection to you.  This is
 especially useful if you are behind a firewall and it is impossible to
@@ -1063,24 +1083,24 @@ make a connection from the outside to your tinc daemon.  Otherwise, it
 is best to leave this option out or set it to no.
 
 @cindex MACLength
-@item @var{MACLength} = <length> (4)
+@item MACLength = <@var{bytes}> (4)
 The length of the message authentication code used to authenticate UDP packets.
 Can be anything from 0
 up to the length of the digest produced by the digest algorithm.
 
 @cindex Port
-@item @var{Port} = <port> (655)
+@item Port = <@var{port}> (655)
 This is the port this tinc daemon listens on.
-You can use decimal portnumbers or symbolic names (as listed in /etc/services).
+You can use decimal portnumbers or symbolic names (as listed in @file{/etc/services}).
 
 @cindex PublicKey
-@item @var{PublicKey} = <key> [obsolete]
+@item PublicKey = <@var{key}> [obsolete]
 This is the RSA public key for this host.
 
 @cindex PublicKeyFile
-@item @var{PublicKeyFile} = <path> [obsolete]
+@item PublicKeyFile = <@var{path}> [obsolete]
 This is the full path name of the RSA public key file that was generated
-by ``tincd --generate-keys''.  It must be a full path, not a relative
+by @samp{tincd --generate-keys}.  It must be a full path, not a relative
 directory.
 
 @cindex PEM format
@@ -1092,9 +1112,9 @@ in each host configuration file, if you want to be able to establish a
 connection with that host.
 
 @cindex Subnet
-@item @var{Subnet} = <address[/prefixlength]>
+@item Subnet = <@var{address}[/@var{prefixlength}]>
 The subnet which this tinc daemon will serve.
-tinc tries to look up which other daemon it should send a packet to by searching the appropiate subnet.
+Tinc tries to look up which other daemon it should send a packet to by searching the appropiate subnet.
 If the packet matches a subnet,
 it will be sent to the daemon who has this subnet in his host configuration file.
 Multiple subnet lines can be specified for each daemon.
@@ -1117,7 +1137,7 @@ example: netmask 255.255.255.0 would become /24, 255.255.252.0 becomes
 @uref{ftp://ftp.isi.edu/in-notes/rfc1519.txt, RFC1519}
 
 @cindex TCPonly
-@item @var{TCPonly} = <yes|no> (no) [experimental]
+@item TCPonly = <yes|no> (no) [experimental]
 If this variable is set to yes, then the packets are tunnelled over a
 TCP connection instead of a UDP connection.  This is especially useful
 for those who want to run a tinc daemon from behind a masquerading
@@ -1127,13 +1147,13 @@ Setting this options also implicitly sets IndirectData.
 
 
 @c ==================================================================
-@node       Scripts, How to configure, Host configuration variables, Configuration files
+@node       Scripts
 @subsection Scripts
 
 @cindex scripts
 Apart from reading the server and host configuration files,
 tinc can also run scripts at certain moments.
-On Windows (not Cygwin), the scripts should have the extension .bat.
+Under Windows (not Cygwin), the scripts should have the extension .bat.
 
 @table @file
 @cindex tinc-up
@@ -1196,7 +1216,7 @@ this is set to the port number it uses for communication with other tinc daemons
 
 
 @c ==================================================================
-@node       How to configure,  , Scripts, Configuration files
+@node       How to configure
 @subsection How to configure
 
 @subsubheading Step 1.  Creating the main configuration file
@@ -1230,7 +1250,7 @@ You might also need to add a `Port' if you want your tinc daemon to run on a dif
 
 
 @c ==================================================================
-@node    Generating keypairs, Network interfaces, Configuration files, Configuration
+@node    Generating keypairs
 @section Generating keypairs
 
 @cindex key generation
@@ -1241,12 +1261,12 @@ you can easily create a public/private keypair by entering the following command
 tincd -n @var{netname} -K
 @end example
 
-tinc will generate a public and a private key and ask you where to put them.
+Tinc will generate a public and a private key and ask you where to put them.
 Just press enter to accept the defaults.
 
 
 @c ==================================================================
-@node    Network interfaces, Example configuration, Generating keypairs, Configuration
+@node    Network interfaces
 @section Network interfaces
 
 Before tinc can start transmitting data over the tunnel, it must
@@ -1255,14 +1275,15 @@ set up the virtual network interface.
 First, decide which IP addresses you want to have associated with these
 devices, and what network mask they must have.
 
-tinc will open a virtual network device (@file{/dev/tun}, @file{/dev/tap0} or similar),
-which will also create a network interface called something like `tun0', `tap0', or,
-if you are using the Linux tun/tap driver, the network interface will by default have the same name as the netname.
+Tinc will open a virtual network device (@file{/dev/tun}, @file{/dev/tap0} or similar),
+which will also create a network interface called something like @samp{tun0}, @samp{tap0}.
+If you are using the Linux tun/tap driver, the network interface will by default have the same name as the @var{netname}.
+Under Windows you can change the name of the network interface from the Network Connections control panel.
 
 @cindex tinc-up
 You can configure the network interface by putting ordinary ifconfig, route, and other commands
-to a script named @file{@value{sysconfdir}/tinc/@var{netname}/tinc-up}. When tinc starts, this script
-will be executed. When tinc exits, it will execute the script named
+to a script named @file{@value{sysconfdir}/tinc/@var{netname}/tinc-up}.
+When tinc starts, this script will be executed. When tinc exits, it will execute the script named
 @file{@value{sysconfdir}/tinc/@var{netname}/tinc-down}, but normally you don't need to create that script.
 
 An example @file{tinc-up} script:
@@ -1280,9 +1301,13 @@ The kernel will also bring the interface up after this command.
 The netmask is the mask of the @emph{entire} VPN network, not just your
 own subnet.
 
+The exact syntax of the ifconfig and route commands differs from platform to platform.
+You can look up the commands for setting addresses and adding routes in @ref{Platform specific information},
+but it is best to consult the manpages of those utilities on your platform.
+
 
 @c ==================================================================
-@node    Example configuration,  , Network interfaces, Configuration
+@node    Example configuration
 @section Example configuration
 
 
@@ -1302,9 +1327,9 @@ C: net 10.3.0.0 mask 255.255.0.0 gateway 10.3.69.254 internet IP 3.4.5.6
 D: net 10.4.0.0 mask 255.255.0.0 gateway 10.4.3.32 internet IP 4.5.6.7
 @end example
 
-``gateway'' is the VPN IP address of the machine that is running the
-tincd ``internet IP'' is the IP address of the firewall, which does not
-need to run tincd, but it must do a port forwarding of TCP&UDP on port
+Here, ``gateway'' is the VPN IP address of the machine that is running the
+tincd, and ``internet IP'' is the IP address of the firewall, which does not
+need to run tincd, but it must do a port forwarding of TCP and UDP on port
 655 (unless otherwise configured).
 
 In this example, it is assumed that eth0 is the interface that points to
@@ -1322,7 +1347,7 @@ In @file{@value{sysconfdir}/tinc/company/tinc-up}:
 
 @example
 # Real interface of internal network:
-# ifconfig eth0 10.1.54.1 netmask 255.255.0.0 broadcast 10.1.255.255
+# ifconfig eth0 10.1.54.1 netmask 255.255.0.0
 
 ifconfig $INTERFACE 10.1.54.1 netmask 255.0.0.0
 @end example
@@ -1335,7 +1360,7 @@ PrivateKeyFile = @value{sysconfdir}/tinc/company/rsa_key.priv
 Device = /dev/tap0
 @end example
 
-On all hosts, @value{sysconfdir}/tinc/company/hosts/BranchA contains:
+On all hosts, @file{@value{sysconfdir}/tinc/company/hosts/BranchA} contains:
 
 @example
 Subnet = 10.1.0.0/16
@@ -1358,7 +1383,7 @@ In @file{@value{sysconfdir}/tinc/company/tinc-up}:
 
 @example
 # Real interface of internal network:
-# ifconfig eth0 10.2.43.8 netmask 255.255.0.0 broadcast 10.2.255.255
+# ifconfig eth0 10.2.43.8 netmask 255.255.0.0
 
 ifconfig $INTERFACE 10.2.1.12 netmask 255.0.0.0
 @end example
@@ -1393,7 +1418,7 @@ In @file{@value{sysconfdir}/tinc/company/tinc-up}:
 
 @example
 # Real interface of internal network:
-# ifconfig eth0 10.3.69.254 netmask 255.255.0.0 broadcast 10.3.255.255
+# ifconfig eth0 10.3.69.254 netmask 255.255.0.0
 
 ifconfig $INTERFACE 10.3.69.254 netmask 255.0.0.0
 @end example
@@ -1429,7 +1454,7 @@ In @file{@value{sysconfdir}/tinc/company/tinc-up}:
 
 @example
 # Real interface of internal network:
-# ifconfig eth0 10.4.3.32 netmask 255.255.0.0 broadcast 10.4.255.255
+# ifconfig eth0 10.4.3.32 netmask 255.255.0.0
 
 ifconfig $INTERFACE 10.4.3.32 netmask 255.0.0.0
 @end example
@@ -1482,7 +1507,7 @@ their daemons, tinc will try connecting until they are available.
 
 
 @c ==================================================================
-@node    Running tinc, Technical information, Configuration, Top
+@node    Running tinc
 @chapter Running tinc
 
 If everything else is done, you can start tinc by typing the following command:
@@ -1492,18 +1517,20 @@ tincd -n @var{netname}
 @end example
 
 @cindex daemon
-tinc will detach from the terminal and continue to run in the background like a good daemon.
+Tinc will detach from the terminal and continue to run in the background like a good daemon.
 If there are any problems however you can try to increase the debug level
 and look in the syslog to find out what the problems are.
 
 @menu
 * Runtime options::
+* Solving problems::
 * Error messages::
+* Sending bug reports::
 @end menu
 
 
 @c ==================================================================
-@node    Runtime options, Error messages, Running tinc, Running tinc
+@node    Runtime options
 @section Runtime options
 
 Besides the settings in the configuration file, tinc also accepts some
@@ -1514,8 +1541,8 @@ command line options.
 @cindex options
 @c from the manpage
 @table @option
-@item -c, --config=PATH
-Read configuration options from the directory PATH.  The default is
+@item -c, --config=@var{path}
+Read configuration options from the directory @var{path}.  The default is
 @file{@value{sysconfdir}/tinc/@var{netname}/}.
 
 @item -D, --no-detach
@@ -1523,21 +1550,21 @@ Don't fork and detach.
 This will also disable the automatic restart mechanism for fatal errors.
 
 @cindex debug level
-@item -d, --debug=LEVEL
-Set debug level to LEVEL.  The higher the debug level, the more gets
+@item -d, --debug=@var{level}
+Set debug level to @var{level}.  The higher the debug level, the more gets
 logged.  Everything goes via syslog.
 
-@item -k, --kill[=SIGNAL]
-Attempt to kill a running tincd (optionally with the specified SIGNAL instead of SIGTERM) and exit.
+@item -k, --kill[=@var{signal}]
+Attempt to kill a running tincd (optionally with the specified @var{signal} instead of SIGTERM) and exit.
 Use it in conjunction with the -n option to make sure you kill the right tinc daemon.
 Under native Windows the optional argument is ignored,
 the service will always be stopped and removed.
 
-@item -n, --net=NETNAME
-Connect to net NETNAME.  @xref{Multiple networks}.
+@item -n, --net=@var{netname}
+Use configuration for net @var{netname}. @xref{Multiple networks}.
 
-@item -K, --generate-keys[=BITS]
-Generate public/private keypair of BITS length. If BITS is not specified,
+@item -K, --generate-keys[=@var{bits}]
+Generate public/private keypair of @var{bits} length. If @var{bits} is not specified,
 1024 is the default. tinc will ask where you want to store the files,
 but will default to the configuration directory (you can use the -c or -n option
 in combination with -K). After that, tinc will quit.
@@ -1546,12 +1573,12 @@ in combination with -K). After that, tinc will quit.
 Lock tinc into main memory.
 This will prevent sensitive data like shared private keys to be written to the system swap files/partitions.
 
-@item --logfile[=FILE]
+@item --logfile[=@var{file}]
 Write log entries to a file instead of to the system logging facility.
-If FILE is omitted, the default is @value{localstatedir}/log/tinc.NETNAME.log.
+If @var{file} is omitted, the default is @file{@value{localstatedir}/log/tinc.@var{netname}.log}.
 
-@item --pidfile=FILE
-Write PID to FILE instead of @value{localstatedir}/run/tinc.NETNAME.pid.
+@item --pidfile=@var{file}
+Write PID to @var{file} instead of @file{@value{localstatedir}/run/tinc.@var{netname}.pid}.
 
 @item --bypass-security
 Disables encryption and authentication.
@@ -1565,16 +1592,46 @@ Output version information and exit.
 
 @end table
 
+@c ==================================================================
+@node    Solving problems
+@section Solving problems
+
+If tinc starts without problems, but if the VPN doesn't work, you will have to find the cause of the problem.
+The first thing to do is to start tinc with a high debug level in the foreground,
+so you can directly see everything tinc logs:
+
+@example
+tincd -n @var{netname} -d5 -D
+@end example
+
+If tinc does not log any error messages, then you might want to check the following things:
+
+@itemize
+@item @file{tinc-up} script
+Does this script contain the right commands?
+Normally you must give the interface the address of this host on the VPN, and the netmask must be big enough so that the entire VPN is covered.
+
+@item Subnet
+Does the Subnet (or Subnets) in the host configuration file of this host match the portion of the VPN that belongs to this host?
+
+@item Firewalls and NATs
+Do you have a firewall or a NAT device (a masquerading firewall or perhaps an ADSL router that performs masquerading)?
+If so, check that it allows TCP and UDP traffic on port 655.
+If it masquerades and the host running tinc is behind it, make sure that it forwards TCP and UDP traffic to port 655 to the host running tinc.
+You can add @samp{TCPOnly = yes} to your host config file to force tinc to only use a single TCP connection,
+this works through most firewalls and NATs.
+
+@end itemize
+
 
 @c ==================================================================
-@node    Error messages,  , Runtime options, Running tinc
+@node    Error messages
 @section Error messages
 
-What follows is a list of the most common error messages you can see
-when configuring tinc.  Most of these messages are visible in the syslog
-only, so keep an eye on it!
+What follows is a list of the most common error messages you might find in the logs.
+Some of them will only be visible if the debug level is high enough.
 
-@table @strong
+@table @samp
 @item Could not open /dev/tap0: No such device
 
 @itemize
@@ -1587,6 +1644,52 @@ only, so keep an eye on it!
 @itemize
 @item You forgot to `modprobe tun'.
 @item You forgot to compile `Universal TUN/TAP driver' in the kernel.
+@item The tun device is located somewhere else in @file{/dev/}.
+@end itemize
+
+@item Network address and prefix length do not match!
+
+@itemize
+@item The Subnet field must contain a @emph{network} address, trailing bits should be 0.
+@item If you only want to use one IP address, set the netmask to /32.
+@end itemize
+
+@item Error reading RSA key file `rsa_key.priv': No such file or directory
+
+@itemize
+@item You forgot to create a public/private keypair.
+@item Specify the complete pathname to the private key file with the @samp{PrivateKeyFile} option.
+@end itemize
+
+@item Warning: insecure file permissions for RSA private key file `rsa_key.priv'!
+
+@itemize
+@item The private key file is readable by users other than root.
+Use chmod to correct the file permissions.
+@end itemize
+
+@item Creating metasocket failed: Address family not supported
+
+@itemize
+@item By default tinc tries to create both IPv4 and IPv6 sockets.
+On some platforms this might not be implemented.
+If the logs show @samp{Ready} later on, then at least one metasocket was created,
+and you can ignore this message.
+You can add @samp{AddressFamily = ipv4} to @file{tinc.conf} to prevent this from happening.
+@end itemize
+
+@item Cannot route packet: unknown IPv4 destination 1.2.3.4
+
+@itemize
+@item You try to send traffic to a host on the VPN for which no Subnet is known.
+@item If it is a broadcast address (ending in .255), it probably is a samba server or a Windows host sending broadcast packets.
+You can ignore it.
+@end itemize
+
+@item Cannot route packet: ARP request for unknown address 1.2.3.4
+
+@itemize
+@item You try to send traffic to a host on the VPN for which no Subnet is known.
 @end itemize
 
 @item Packet with destination 1.2.3.4 is looping back to us!
@@ -1600,40 +1703,55 @@ just as large as the prefix of the virtual network interface. The latter should
 cases be larger. Rethink your configuration.
 Note that you will only see this message if you specified a debug
 level of 5 or higher!
-@item Chances are that a `Subnet = ...' line in the host configuration file of this tinc daemon is wrong.
+@item Chances are that a @samp{Subnet = ...} line in the host configuration file of this tinc daemon is wrong.
 Change it to a subnet that is accepted locally by another interface,
 or if that is not the case, try changing the prefix length into /32. 
 @end itemize
 
-@item Network doesn't work, syslog shows only packets of length 46
-
-@item Network address and prefix length do not match!
+@item Node foo (1.2.3.4) is not reachable
 
 @itemize
-@item The Subnet field must contain a @emph{network} address.
-@item If you only want to use one IP address, set the netmask to /32.
+@item Node foo does not have a connection anymore, its tinc daemon is not running or its connection to the Internet is broken.
 @end itemize
 
-@item This is a bug: net.c:253: 24: Some error
+@item Received UDP packet from unknown source 1.2.3.4 (port 12345)
 
 @itemize
-@item This is something that should not have happened.
-Please report this, and tell us exactly what went wrong before you got
-this message.  In normal operation, these errors should not occur.
+@item If you see this only sporadically, it is harmless and caused by a node sending packets using an old key.
+@item If you see this often and another node is not reachable anymore, then a NAT (masquerading firewall) is changing the source address of UDP packets.
+You can add @samp{TCPOnly = yes} to host configuration files to force all VPN traffic to go over a TCP connection.
 @end itemize
 
-@item Error reading RSA key file `rsa_key.priv': No such file or directory
+@item Got bad/bogus/unauthorized REQUEST from foo (1.2.3.4 port 12345)
 
 @itemize
-@item You must specify the complete pathname.
-Specifying a relative path does not make sense here.  tinc changes its
-directory to / when starting (to avoid keeping a mount point busy).
+@item Node foo does not have the right public/private keypair.
+Generate new keypairs and distribute them again.
+@item An attacker tries to gain access to your VPN.
+@item A network error caused corruption of metadata sent from foo.
 @end itemize
 
 @end table
 
 @c ==================================================================
-@node    Technical information, About us, Running tinc, Top
+@node    Sending bug reports
+@section Sending bug reports
+
+If you really can't find the cause of a problem, or if you suspect tinc is not working right,
+you can send us a bugreport, see @ref{Contact information}.
+Be sure to include the following information in your bugreport:
+
+@itemize
+@item A clear description of what you are trying to achieve and what the problem is.
+@item What platform (operating system, version, hardware architecture) and which version of tinc you use.
+@item If compiling tinc fails, a copy of @file{config.log} and the error messages you get.
+@item Otherwise, a copy of @file{tinc.conf}, @file{tinc-up} and all files in the @file{hosts/} directory.
+@item The output of the commands @samp{ifconfig -a} and @samp{route -n} (or @samp{netstat -rn} if that doesn't work).
+@item The output of any command that fails to work as it should (like ping or traceroute).
+@end itemize
+
+@c ==================================================================
+@node    Technical information
 @chapter Technical information
 
 
@@ -1645,11 +1763,11 @@ directory to / when starting (to avoid keeping a mount point busy).
 
 
 @c ==================================================================
-@node    The connection, The meta-protocol, Technical information, Technical information
+@node    The connection
 @section The connection
 
 @cindex connection
-tinc is a daemon that takes VPN data and transmit that to another host
+Tinc is a daemon that takes VPN data and transmit that to another host
 computer over the existing Internet infrastructure.
 
 @menu
@@ -1659,7 +1777,7 @@ computer over the existing Internet infrastructure.
 
 
 @c ==================================================================
-@node    The UDP tunnel, The meta-connection, The connection, The connection
+@node    The UDP tunnel
 @subsection The UDP tunnel
 
 @cindex virtual network device
@@ -1706,7 +1824,7 @@ However, if it is a `tap' device (this is the only available type on FreeBSD),
 the destination MAC address must match that of the virtual network interface.
 If tinc is in it's default routing mode, ARP does not work, so the correct destination MAC 
 can not be known by the sending host.
-tinc solves this by letting the receiving end detect the MAC address of its own virtual network interface
+Tinc solves this by letting the receiving end detect the MAC address of its own virtual network interface
 and overwriting the destination MAC address of the received packet.
 
 In switch or hub modes ARP does work so the sender already knows the correct destination MAC address.
@@ -1717,7 +1835,7 @@ OpenBSD, NetBSD, Darwin and Solaris.
 
 
 @c ==================================================================
-@node    The meta-connection,  , The UDP tunnel, The connection
+@node    The meta-connection
 @subsection The meta-connection
 
 Having only a UDP connection available is not enough.  Though suitable
@@ -1751,7 +1869,7 @@ start re-sending packets.
 
 
 @c ==================================================================
-@node    The meta-protocol, Security, The connection, Technical information
+@node    The meta-protocol
 @section The meta-protocol
 
 The meta protocol is used to tie all tinc daemons together, and
@@ -1868,17 +1986,16 @@ is also some other traffic. A little bit of salt (random data) is added
 with each PING and PONG message, to make sure that long sequences of PING/PONG
 messages without any other traffic won't result in known plaintext.
 
-This basically covers what is sent over the meta connection by
-tinc.
+This basically covers what is sent over the meta connection by tinc.
 
 
 @c ==================================================================
-@node    Security,  , The meta-protocol, Technical information
-@section About tinc's encryption and other security-related issues.
+@node    Security
+@section Security
 
 @cindex TINC
 @cindex Cabal
-tinc got its name from ``TINC,'' short for @emph{There Is No Cabal}; the
+Tinc got its name from ``TINC,'' short for @emph{There Is No Cabal}; the
 alleged Cabal was/is an organisation that was said to keep an eye on the
 entire Internet.  As this is exactly what you @emph{don't} want, we named
 the tinc project after TINC.
@@ -1887,7 +2004,7 @@ the tinc project after TINC.
 But in order to be ``immune'' to eavesdropping, you'll have to encrypt
 your data.  Because tinc is a @emph{Secure} VPN (SVPN) daemon, it does
 exactly that: encrypt.
-tinc by default uses blowfish encryption with 128 bit keys in CBC mode, 32 bit
+Tinc by default uses blowfish encryption with 128 bit keys in CBC mode, 32 bit
 sequence numbers and 4 byte long message authentication codes to make sure
 eavesdroppers cannot get and cannot change any information at all from the
 packets they can intercept. The encryption algorithm and message authentication
@@ -1898,11 +2015,12 @@ encryption algorithm is always the default length used by OpenSSL.
 @menu
 * Authentication protocol::
 * Encryption of network packets::
+* Security issues::
 @end menu
 
 
 @c ==================================================================
-@node       Authentication protocol, Encryption of network packets, Security, Security
+@node       Authentication protocol
 @subsection Authentication protocol
 
 @cindex authentication
@@ -2016,8 +2134,8 @@ an attacker) in the beginning of the encrypted stream.
 
 
 @c ==================================================================
-@node       Encryption of network packets,  , Authentication protocol, Security
-@subsection Encryption of network packet
+@node       Encryption of network packets
+@subsection Encryption of network packets
 @cindex encryption
 
 A data packet can only be sent if the encryption key is known to both
@@ -2045,22 +2163,161 @@ first 4 bytes of the digest are used for this, but this can be changed using
 the MACLength configuration variable.
 
 @c ==================================================================
-@node    About us, Concept Index, Technical information, Top
+@node    Security issues
+@subsection Security issues
+
+In August 2000, we discovered the existence of a security hole in all versions
+of tinc up to and including 1.0pre2. This had to do with the way we exchanged
+keys. Since then, we have been working on a new authentication scheme to make
+tinc as secure as possible. The current version uses the OpenSSL library and
+uses strong authentication with RSA keys.
+
+On the 29th of December 2001, Jerome Etienne posted a security analysis of tinc
+1.0pre4. Due to a lack of sequence numbers and a message authentication code
+for each packet, an attacker could possibly disrupt certain network services or
+launch a denial of service attack by replaying intercepted packets. The current
+version adds sequence numbers and message authentication codes to prevent such
+attacks.
+
+On the 15th of September 2003, Peter Gutmann posted a security analysis of tinc
+1.0.1. He argues that the 32 bit sequence number used by tinc is not a good IV,
+that tinc's default length of 4 bytes for the MAC is too short, and he doesn't
+like tinc's use of RSA during authentication. We do not know of a security hole
+in this version of tinc, but tinc's security is not as strong as TLS or IPsec.
+We will address these issues in tinc 2.0.
+
+Cryptography is a hard thing to get right. We cannot make any
+guarantees. Time, review and feedback are the only things that can
+prove the security of any cryptographic product. If you wish to review
+tinc or give us feedback, you are stronly encouraged to do so.
+
+
+@c ==================================================================
+@node    Platform specific information
+@chapter Platform specific information
+
+@menu
+* Interface configuration::
+* Routes::
+@end menu
+
+@c ==================================================================
+@node    Interface configuration
+@section Interface configuration
+
+When configuring an interface, one normally assigns it an address and a
+netmask.  The address uniquely identifies the host on the network attached to
+the interface.  The netmask, combined with the address, forms a subnet.  It is
+used to add a route to the routing table instructing the kernel to send all
+packets which fall into that subnet to that interface.  Because all packets for
+the entire VPN should go to the virtual network interface used by tinc, the
+netmask should be such that it encompasses the entire VPN.
+
+For IPv4 addresses:
+
+@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
+@item Linux
+@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
+@item Linux iproute2
+@tab @code{ip addr add} @var{address}@code{/}@var{prefixlength} @code{dev} @var{interface}
+@item FreeBSD
+@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
+@item OpenBSD
+@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
+@item NetBSD
+@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
+@item Solaris
+@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
+@item Darwin (MacOS/X)
+@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
+@item Windows
+@tab @code{netsh interface ip set address} @var{interface} @code{static} @var{address} @var{netmask}
+@end multitable
+
+
+For IPv6 addresses:
+
+@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
+@item Linux
+@tab @code{ifconfig} @var{interface} @code{add} @var{address}@code{/}@var{prefixlength}
+@item FreeBSD
+@tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength}
+@item OpenBSD
+@tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength}
+@item NetBSD
+@tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength}
+@item Solaris
+@tab @code{ifconfig} @var{interface} @code{inet6 addif} @var{address}@code{/}@var{prefixlength}
+@item Darwin (MacOS/X)
+@tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength}
+@item Windows
+@tab @code{netsh interface ipv6 add address} @var{interface} @code{static} @var{address}/@var{prefixlength}
+@end multitable
+
+
+@c ==================================================================
+@node    Routes
+@section Routes
+
+In some cases it might be necessary to add more routes to the virtual network
+interface.  There are two ways to indicate which interface a packet should go
+to, one is to use the name of the interface itself, another way is to specify
+the (local) address that is assigned to that interface (@var{local_address}). The
+former way is unambiguous and therefore preferable, but not all platforms
+support this.
+
+Adding routes to IPv4 subnets:
+
+@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
+@item Linux
+@tab @code{route add -net} @var{network_address} @code{netmask} @var{netmask} @var{interface}
+@item Linux iproute2
+@tab @code{ip route add} @var{network_address}@code{/}@var{prefixlength} @code{dev} @var{interface}
+@item FreeBSD
+@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
+@item OpenBSD
+@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
+@item NetBSD
+@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
+@item Solaris
+@item Darwin (MacOS/X)
+@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
+@item Windows
+@end multitable
+
+Adding routes to IPv6 subnets:
+
+@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
+@item Linux
+@tab @code{route add -A inet6} @var{network_address}@code{/}@var{prefixlength} @var{interface}
+@item Linux iproute2
+@tab @code{ip route add} @var{network_address}@code{/}@var{prefixlength} @code{dev} @var{interface}
+@item OpenBSD
+@item NetBSD
+@item Solaris
+@item Darwin (MacOS/X)
+@item Windows
+@tab @code{netsh interface ipv6 add route} @var{network address}/@var{prefixlength} @var{interface}
+@end multitable
+
+
+@c ==================================================================
+@node    About us
 @chapter About us
 
 
 @menu
-* Contact Information::
+* Contact information::
 * Authors::
 @end menu
 
 
 @c ==================================================================
-@node    Contact Information, Authors, About us, About us
+@node    Contact information
 @section Contact information
 
 @cindex website
-tinc's website is at @url{http://tinc.nl.linux.org/},
+Tinc's website is at @url{http://tinc.nl.linux.org/},
 this server is located in the Netherlands.
 
 @cindex IRC
@@ -2072,7 +2329,7 @@ and join channel #tinc.
 
 
 @c ==================================================================
-@node    Authors,  , Contact Information, About us
+@node    Authors
 @section Authors
 
 @table @asis
@@ -2087,8 +2344,7 @@ the source distribution.
 
 
 @c ==================================================================
-@node    Concept Index,  , About us, Top
-@c        node-name,    next, previous,        up
+@node    Concept Index
 @unnumbered Concept Index
 
 @c ==================================================================
index 577e33a..e7789f0 100644 (file)
@@ -67,6 +67,8 @@ Generate public/private RSA keypair and exit.
 If
 .Ar BITS
 is omitted, the default length will be 1024 bits.
+When saving keys to existing files, tinc will not delete the old keys,
+you have to remove them manually.
 .It Fl L, -mlock
 Lock tinc into main memory.
 This will prevent sensitive data like shared private keys to be written to the system swap files/partitions.
@@ -130,7 +132,7 @@ Each level inherits all messages of the previous level:
 This will log a message indicating
 .Nm
 has started along with a version number.
-It will also any serious error.
+It will also log any serious error.
 .It 1
 This will log all connections that are made with other tinc daemons.
 .It 2
diff --git a/lib/.cvsignore b/lib/.cvsignore
deleted file mode 100644 (file)
index 1b907a4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Makefile Makefile.in .deps
index 3376212..9fd9618 100644 (file)
@@ -1,5 +1,5 @@
 ## Process this file with automake to produce Makefile.in
-# $Id: Makefile.am,v 1.10 2003/08/24 20:38:20 guus Exp $
+# $Id: Makefile.am,v 1.2.4.13 2003/07/18 12:16:23 guus Exp $
 
 noinst_LIBRARIES = libvpn.a
 
index 43470a9..24f4a08 100644 (file)
@@ -29,7 +29,7 @@
     library for inclusion into tinc (http://tinc.nl.linux.org/) by
     Guus Sliepen <guus@sliepen.eu.org>.
 
-    $Id: avl_tree.c,v 1.3 2003/08/24 20:38:20 guus Exp $
+    $Id: avl_tree.c,v 1.1.2.19 2003/08/28 21:05:09 guus Exp $
 */
 
 #include "system.h"
@@ -280,7 +280,7 @@ void avl_free_tree(avl_tree_t *tree)
 
 avl_node_t *avl_alloc_node(void)
 {
-       return (avl_node_t *)xmalloc_and_zero(sizeof(avl_node_t));
+       return xmalloc_and_zero(sizeof(avl_node_t));
 }
 
 void avl_free_node(avl_tree_t *tree, avl_node_t *node)
index 13ec3aa..8007a51 100644 (file)
@@ -29,7 +29,7 @@
     library for inclusion into tinc (http://tinc.nl.linux.org/) by
     Guus Sliepen <guus@sliepen.eu.org>.
 
-    $Id: avl_tree.h,v 1.3 2003/08/24 20:38:20 guus Exp $
+    $Id: avl_tree.h,v 1.1.2.10 2003/07/24 12:08:15 guus Exp $
 */
 
 
index 11e6fdd..d475601 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: dropin.c,v 1.3 2003/08/24 20:38:20 guus Exp $
+    $Id: dropin.c,v 1.1.2.18 2003/07/29 22:59:00 guus Exp $
 */
 
 #include "system.h"
index 8255d54..a3afa71 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: dropin.h,v 1.3 2003/08/24 20:38:20 guus Exp $
+    $Id: dropin.h,v 1.1.2.14 2003/07/29 22:59:00 guus Exp $
 */
 
 #ifndef __DROPIN_H__
index bda8a96..0784ce1 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: ethernet.h,v 1.2 2003/08/24 20:38:20 guus Exp $
+    $Id: ethernet.h,v 1.1.2.5 2003/10/08 11:34:55 guus Exp $
 */
 
 #ifndef __TINC_ETHERNET_H__
 #define ETH_ALEN 6
 #endif
 
-#ifndef ETHER_ADDR_LEN
-#define ETHER_ADDR_LEN 6
-#endif
-
 #ifndef ARPHRD_ETHER
 #define ARPHRD_ETHER 1
 #endif
 
-#ifndef ETHERTYPE_IP
-#define ETHERTYPE_IP 0x0800
+#ifndef ETH_P_IP
+#define ETH_P_IP 0x0800
+#endif
+
+#ifndef ETH_P_ARP
+#define ETH_P_ARP 0x0806
+#endif
+
+#ifndef ETH_P_IPV6
+#define ETH_P_IPV6 0x86DD
+#endif
+
+#ifndef HAVE_STRUCT_ETHER_HEADER
+struct ether_header {
+       uint8_t ether_dhost[ETH_ALEN];
+       uint8_t ether_shost[ETH_ALEN];
+       uint16_t ether_type;
+} __attribute__ ((__packed__));
 #endif
 
 #ifndef HAVE_STRUCT_ARPHDR
 struct arphdr {
-       unsigned short int ar_hrd;
-       unsigned short int ar_pro;
-       unsigned char ar_hln;
-       unsigned char ar_pln; 
-       unsigned short int ar_op; 
-};
+       uint16_t ar_hrd;
+       uint16_t ar_pro;
+       uint8_t ar_hln;
+       uint8_t ar_pln; 
+       uint16_t ar_op; 
+} __attribute__ ((__packed__));
 
 #define ARPOP_REQUEST 1 
 #define ARPOP_REPLY 2 
@@ -64,7 +76,7 @@ struct  ether_arp {
        uint8_t arp_spa[4];
        uint8_t arp_tha[ETH_ALEN];
        uint8_t arp_tpa[4];
-};
+} __attribute__ ((__packed__));
 #define arp_hrd ea_hdr.ar_hrd
 #define arp_pro ea_hdr.ar_pro
 #define arp_hln ea_hdr.ar_hln
index cd82d45..f54cf55 100644 (file)
@@ -5,7 +5,7 @@
  * See getaddrinfo.c and getnameinfo.c.
  */
 
-/* $Id: fake-gai-errnos.h,v 1.2 2003/08/24 20:38:20 guus Exp $ */
+/* $Id: fake-gai-errnos.h,v 1.1.2.3 2003/08/17 08:32:38 guus Exp $ */
 
 /* for old netdb.h */
 #ifndef EAI_NODATA
index 161c826..14420b5 100644 (file)
@@ -14,6 +14,7 @@
 #include "ipv4.h"
 #include "ipv6.h"
 #include "fake-getaddrinfo.h"
+#include "xalloc.h"
 
 #ifndef HAVE_GAI_STRERROR
 char *gai_strerror(int ecode)
index 34b524a..db7b147 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fake-getaddrinfo.h,v 1.2 2003/08/24 20:38:20 guus Exp $ */
+/* $Id: fake-getaddrinfo.h,v 1.1.2.3 2003/07/17 15:06:25 guus Exp $ */
 
 #ifndef _FAKE_GETADDRINFO_H
 #define _FAKE_GETADDRINFO_H
index a95b081..1d7b0db 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fake-getnameinfo.h,v 1.2 2003/08/24 20:38:20 guus Exp $ */
+/* $Id: fake-getnameinfo.h,v 1.1.2.3 2003/07/17 15:06:25 guus Exp $ */
 
 #ifndef _FAKE_GETNAMEINFO_H
 #define _FAKE_GETNAMEINFO_H
diff --git a/lib/hooks.c b/lib/hooks.c
deleted file mode 100644 (file)
index 9cb6478..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
-    hooks.c -- hooks management
-    Copyright (C) 2002 Guus Sliepen <guus@sliepen.warande.net>,
-                  2002 Ivo Timmermans <ivo@o2w.nl>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id: hooks.c,v 1.2 2002/05/02 11:50:07 zarq Exp $
-*/
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-#include <avl_tree.h>
-#include <hooks.h>
-#include <xalloc.h>
-
-avl_tree_t *hooks_tree = NULL;
-
-struct hooks_node {
-  const char *type;
-  avl_tree_t *hooks;
-} hooks_node;
-
-static int hook_type_compare(const void *a, const void *b)
-{
-  return strcmp(((const struct hooks_node*)a)->type,
-               ((const struct hooks_node*)b)->type);
-}
-
-static int hook_dummy_compare(const void *a, const void *b)
-{
-  if(a < b)
-    return -1;
-  if(a > b)
-    return 1;
-  return 0;
-}
-
-void run_hooks(const char *type, ...)
-{
-  avl_node_t *avlnode;
-  va_list args;
-  struct hooks_node *hn;
-  struct hooks_node target;
-
-  if(!hooks_tree)
-    return;
-  
-  target.type = type;
-  hn = (struct hooks_node*)avl_search(hooks_tree, &target);
-  if(!hn || !(hn->hooks->head))
-    {
-      fprintf(stderr, "Warning, no hooks found for `%s'\n", type);
-      return;
-    }
-
-  va_start(args, type);
-  for(avlnode = hn->hooks->head; avlnode; avlnode = avlnode->next)
-    {
-      assert(avlnode->data);
-      ((hook_function_t*)(avlnode->data))(type, args);
-    }
-  va_end(args);
-}
-
-void add_hook(const char *type, hook_function_t *hook)
-{
-  struct hooks_node *hn;
-  struct hooks_node target;
-  
-  if(!hooks_tree)
-    hooks_tree = avl_alloc_tree(hook_type_compare, NULL);
-
-  target.type = type;
-  hn = avl_search(hooks_tree, &target);
-  if(!hn)
-    {
-      avl_tree_t *t;
-      
-      hn = xmalloc(sizeof(struct hooks_node));
-      t = avl_alloc_tree(hook_dummy_compare, NULL);
-      hn->type = type;
-      hn->hooks = t;
-      avl_insert(hooks_tree, (void*)hn);
-    }
-
-  avl_insert(hn->hooks, (void*)hook);
-}
-
-void del_hook(const char *type, hook_function_t *hook)
-{
-  avl_tree_t *t;
-  struct hooks_node target;
-
-  if(!hooks_tree)
-    return;
-
-  target.type = type;
-  t = avl_search(hooks_tree, &target);
-  if(!t)
-    return;
-
-  avl_delete(t, (void*)hook);
-}
index 2c346ee..dcac0bf 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: ipv4.h,v 1.2 2003/08/24 20:38:20 guus Exp $
+    $Id: ipv4.h,v 1.1.2.5 2003/12/22 11:05:23 guus Exp $
 */
 
 #ifndef __TINC_IPV4_H__
 #define ICMP_DEST_UNREACH 3
 #endif
 
+#ifndef ICMP_FRAG_NEEDED
+#define ICMP_FRAG_NEEDED 4
+#endif
+
 #ifndef ICMP_NET_UNKNOWN
 #define ICMP_NET_UNKNOWN 6
 #endif
@@ -68,7 +72,7 @@ struct ip {
        uint8_t ip_p;
        uint16_t ip_sum;
        struct in_addr ip_src, ip_dst;
-};
+} __attribute__ ((__packed__));
 #endif
 
 #ifndef HAVE_STRUCT_ICMP
@@ -126,7 +130,7 @@ struct icmp {
 #define icmp_radv icmp_dun.id_radv
 #define icmp_mask icmp_dun.id_mask
 #define icmp_data icmp_dun.id_data
-};
+} __attribute__ ((__packed__));
 #endif
 
 #endif /* __TINC_IPV4_H__ */
index 9946f8c..3fdb959 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: ipv6.h,v 1.2 2003/08/24 20:38:20 guus Exp $
+    $Id: ipv6.h,v 1.1.2.9 2003/12/22 11:05:23 guus Exp $
 */
 
 #ifndef __TINC_IPV6_H__
@@ -38,7 +38,7 @@ struct in6_addr {
                uint16_t u6_addr16[8];
                uint32_t u6_addr32[4];
        } in6_u;
-};
+} __attribute__ ((__packed__));
 #define s6_addr in6_u.u6_addr8
 #define s6_addr16 in6_u.u6_addr16
 #define s6_addr32 in6_u.u6_addr32
@@ -51,7 +51,7 @@ struct sockaddr_in6 {
        uint32_t sin6_flowinfo;
        struct in6_addr sin6_addr;
        uint32_t sin6_scope_id;
-};
+} __attribute__ ((__packed__));
 #endif
 
 #ifndef IN6_IS_ADDR_V4MAPPED
@@ -74,7 +74,7 @@ struct ip6_hdr {
        } ip6_ctlun;
        struct in6_addr ip6_src;
        struct in6_addr ip6_dst;
-};
+} __attribute__ ((__packed__));
 #define ip6_vfc ip6_ctlun.ip6_un2_vfc
 #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
 #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
@@ -93,28 +93,37 @@ struct icmp6_hdr {
                uint16_t icmp6_un_data16[2];
                uint8_t icmp6_un_data8[4];
        } icmp6_dataun;
-};
+} __attribute__ ((__packed__));
 #define ICMP6_DST_UNREACH_NOROUTE 0
 #define ICMP6_DST_UNREACH 1
+#define ICMP6_PACKET_TOO_BIG 2
 #define ICMP6_DST_UNREACH_ADDR 3
 #define ND_NEIGHBOR_SOLICIT 135
 #define ND_NEIGHBOR_ADVERT 136
+#define icmp6_data32 icmp6_dataun.icmp6_un_data32
+#define icmp6_data16 icmp6_dataun.icmp6_un_data16
+#define icmp6_data8 icmp6_dataun.icmp6_un_data8
+#define icmp6_mtu icmp6_data32[0]
 #endif
 
 #ifndef HAVE_STRUCT_ND_NEIGHBOR_SOLICIT
 struct nd_neighbor_solicit {
        struct icmp6_hdr nd_ns_hdr;
        struct in6_addr nd_ns_target;
-};
+} __attribute__ ((__packed__));
 #define ND_OPT_SOURCE_LINKADDR 1
 #define ND_OPT_TARGET_LINKADDR 2
+#define nd_ns_type nd_ns_hdr.icmp6_type
+#define nd_ns_code nd_ns_hdr.icmp6_code
+#define nd_ns_cksum nd_ns_hdr.icmp6_cksum
+#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
 #endif
 
 #ifndef HAVE_STRUCT_ND_OPT_HDR
 struct nd_opt_hdr {
        uint8_t nd_opt_type;
        uint8_t nd_opt_len;
-};
+} __attribute__ ((__packed__));
 #endif
 
 #endif /* __TINC_IPV6_H__ */
index 2c08978..98a3019 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: list.c,v 1.3 2003/08/24 20:38:20 guus Exp $
+    $Id: list.c,v 1.1.2.17 2003/08/28 21:05:09 guus Exp $
 */
 
 #include "system.h"
@@ -44,7 +44,7 @@ void list_free(list_t *list)
 
 list_node_t *list_alloc_node(void)
 {
-       return (list_node_t *)xmalloc_and_zero(sizeof(list_node_t));
+       return xmalloc_and_zero(sizeof(list_node_t));
 }
 
 void list_free_node(list_t *list, list_node_t *node)
index 620eeec..c53e801 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: list.h,v 1.3 2003/08/24 20:38:20 guus Exp $
+    $Id: list.h,v 1.1.2.11 2003/07/31 11:17:39 guus Exp $
 */
 
 #ifndef __TINC_LIST_H__
index 368dad4..61a802f 100644 (file)
  * 0 is returned if either there's no pidfile, it's empty
  * or no pid can be read.
  */
-int read_pid (char *pidfile)
+pid_t read_pid (char *pidfile)
 {
   FILE *f;
-  int pid;
+  long pid;
 
   if (!(f=fopen(pidfile,"r")))
     return 0;
-  fscanf(f,"%d", &pid);
+  fscanf(f,"%ld", &pid);
   fclose(f);
   return pid;
 }
@@ -50,11 +50,11 @@ int read_pid (char *pidfile)
  *
  * Reads the pid using read_pid and looks up the pid in the process
  * table (using /proc) to determine if the process already exists. If
- * so 1 is returned, otherwise 0.
+ * so the pid is returned, otherwise 0.
  */
-int check_pid (char *pidfile)
+pid_t check_pid (char *pidfile)
 {
-  int pid = read_pid(pidfile);
+  pid_t pid = read_pid(pidfile);
 
   /* Amazing ! _I_ am already holding the pid file... */
   if ((!pid) || (pid == getpid ()))
@@ -68,7 +68,7 @@ int check_pid (char *pidfile)
   /* But... errno is usually changed only on error.. */
   errno = 0;
   if (kill(pid, 0) && errno == ESRCH)
-         return(0);
+         return 0;
 
   return pid;
 }
@@ -78,30 +78,26 @@ int check_pid (char *pidfile)
  * Writes the pid to the specified file. If that fails 0 is
  * returned, otherwise the pid.
  */
-int write_pid (char *pidfile)
+pid_t write_pid (char *pidfile)
 {
   FILE *f;
   int fd;
-  int pid;
+  pid_t pid;
 
   if ( ((fd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1)
        || ((f = fdopen(fd, "r+")) == NULL) ) {
-      fprintf(stderr, "Can't open or create %s.\n", pidfile);
       return 0;
   }
   
 #ifdef HAVE_FLOCK
   if (flock(fd, LOCK_EX|LOCK_NB) == -1) {
-      fscanf(f, "%d", &pid);
       fclose(f);
-      printf("Can't lock, lock is held by pid %d.\n", pid);
       return 0;
   }
 #endif
 
   pid = getpid();
-  if (!fprintf(f,"%d\n", pid)) {
-      printf("Can't write pid , %s.\n", strerror(errno));
+  if (!fprintf(f,"%ld\n", (long)pid)) {
       close(fd);
       return 0;
   }
@@ -109,7 +105,6 @@ int write_pid (char *pidfile)
 
 #ifdef HAVE_FLOCK
   if (flock(fd, LOCK_UN) == -1) {
-      printf("Can't unlock pidfile %s, %s.\n", pidfile, strerror(errno));
       close(fd);
       return 0;
   }
index d428d48..152ae2c 100644 (file)
@@ -26,7 +26,7 @@
  * 0 is returned if either there's no pidfile, it's empty
  * or no pid can be read.
  */
-int read_pid (char *pidfile);
+pid_t read_pid (char *pidfile);
 
 /* check_pid
  *
@@ -34,14 +34,14 @@ int read_pid (char *pidfile);
  * table (using /proc) to determine if the process already exists. If
  * so 1 is returned, otherwise 0.
  */
-int check_pid (char *pidfile);
+pid_t check_pid (char *pidfile);
 
 /* write_pid
  *
  * Writes the pid to the specified file. If that fails 0 is
  * returned, otherwise the pid.
  */
-int write_pid (char *pidfile);
+pid_t write_pid (char *pidfile);
 
 /* remove_pid
  *
diff --git a/m4/.cvsignore b/m4/.cvsignore
deleted file mode 100644 (file)
index df1fab1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Makefile.am Makefile.in Makefile
diff --git a/m4/Makefile.am b/m4/Makefile.am
new file mode 100644 (file)
index 0000000..0f58aef
--- /dev/null
@@ -0,0 +1,4 @@
+## Process this file with automake to produce Makefile.in   -*-Makefile-*-
+
+EXTRA_DIST = README *.m4
+
index 58b8346..6a8f555 100644 (file)
@@ -1,7 +1,7 @@
 dnl Check to find out whether function attributes are supported.
 dnl If they are not, #define them to be nothing.
 
-AC_DEFUN(tinc_ATTRIBUTE,
+AC_DEFUN([tinc_ATTRIBUTE],
 [
   AC_CACHE_CHECK([for working $1 attribute], tinc_cv_attribute_$1,
   [ 
index 147318f..8214d4c 100644 (file)
--- a/m4/lzo.m4
+++ b/m4/lzo.m4
@@ -1,28 +1,24 @@
 dnl Check to find the lzo headers/libraries
 
-AC_DEFUN(tinc_LZO,
+AC_DEFUN([tinc_LZO],
 [
-  tinc_ac_save_CPPFLAGS="$CPPFLAGS"
-
   AC_ARG_WITH(lzo,
-    AC_HELP_STRING([--with-lzo=DIR], [lzo base directory, or:]),
+    AS_HELP_STRING([--with-lzo=DIR], [lzo base directory, or:]),
     [lzo="$withval"
-     CFLAGS="$CFLAGS -I$withval/include"
      CPPFLAGS="$CPPFLAGS -I$withval/include"
-     LIBS="$LIBS -L$withval/lib"]
+     LDFLAGS="$LDFLAGS -L$withval/lib"]
   )
 
   AC_ARG_WITH(lzo-include,
-    AC_HELP_STRING([--with-lzo-include=DIR], [lzo headers directory]),
+    AS_HELP_STRING([--with-lzo-include=DIR], [lzo headers directory]),
     [lzo_include="$withval"
-     CFLAGS="$CFLAGS -I$withval"
      CPPFLAGS="$CPPFLAGS -I$withval"]
   )
 
   AC_ARG_WITH(lzo-lib,
-    AC_HELP_STRING([--with-lzo-lib=DIR], [lzo library directory]),
+    AS_HELP_STRING([--with-lzo-lib=DIR], [lzo library directory]),
     [lzo_lib="$withval"
-     LIBS="$LIBS -L$withval"]
+     LDFLAGS="$LDFLAGS -L$withval"]
   )
 
   AC_CHECK_HEADERS(lzo1x.h,
@@ -30,8 +26,6 @@ AC_DEFUN(tinc_LZO,
     [AC_MSG_ERROR("lzo header files not found."); break]
   )
 
-  CPPFLAGS="$tinc_ac_save_CPPFLAGS"
-
   AC_CHECK_LIB(lzo, lzo1x_1_compress,
     [LIBS="$LIBS -llzo"],
     [AC_MSG_ERROR("lzo libraries not found.")]
index a6b4c9a..f8ed112 100644 (file)
@@ -10,7 +10,7 @@ dnl  /* Define to rpl_malloc if the replacement function should be used.  */
 dnl  #undef malloc
 dnl
 
-AC_DEFUN(jm_FUNC_MALLOC,
+AC_DEFUN([jm_FUNC_MALLOC],
 [
  if test x = y; then
    dnl This code is deliberately never run via ./configure.
@@ -23,21 +23,19 @@ AC_DEFUN(jm_FUNC_MALLOC,
  AC_DEFINE(HAVE_DONE_WORKING_MALLOC_CHECK, 1, [Needed for xmalloc.c])
 
  AC_CACHE_CHECK([for working malloc], jm_cv_func_working_malloc,
-  [AC_TRY_RUN([
+  [AC_RUN_IFELSE([AC_LANG_SOURCE([
     char *malloc ();
     int
     main ()
     {
       exit (malloc (0) ? 0 : 1);
     }
-         ],
-        jm_cv_func_working_malloc=yes,
-        jm_cv_func_working_malloc=no,
-        dnl When crosscompiling, assume malloc is broken.
-        jm_cv_func_working_malloc=no)
+   ])],
+   [jm_cv_func_working_malloc=yes],
+   [jm_cv_func_working_malloc=no],
+   [When crosscompiling])
   ])
   if test $jm_cv_func_working_malloc = no; then
-    dnl This was: LIBOBJS="$LIBOBJS malloc.$ac_objext"
     AC_LIBOBJ([malloc])
     AC_DEFINE(malloc, rpl_malloc, [Replacement malloc()])
   fi
index 32e41de..0bc9976 100644 (file)
@@ -1,28 +1,24 @@
 dnl Check to find the OpenSSL headers/libraries
 
-AC_DEFUN(tinc_OPENSSL,
+AC_DEFUN([tinc_OPENSSL],
 [
-  tinc_ac_save_CPPFLAGS="$CPPFLAGS"
-
   AC_ARG_WITH(openssl,
-    AC_HELP_STRING([--with-openssl=DIR], [OpenSSL base directory, or:]),
+    AS_HELP_STRING([--with-openssl=DIR], [OpenSSL base directory, or:]),
     [openssl="$withval"
-     CFLAGS="$CFLAGS -I$withval/include"
      CPPFLAGS="$CPPFLAGS -I$withval/include"
-     LIBS="$LIBS -L$withval/lib"]
+     LDFLAGS="$LDFLAGS -L$withval/lib"]
   )
 
   AC_ARG_WITH(openssl-include,
-    AC_HELP_STRING([--with-openssl-include=DIR], [OpenSSL headers directory (without trailing /openssl)]),
+    AS_HELP_STRING([--with-openssl-include=DIR], [OpenSSL headers directory (without trailing /openssl)]),
     [openssl_include="$withval"
-     CFLAGS="$CFLAGS -I$withval"
      CPPFLAGS="$CPPFLAGS -I$withval"]
   )
 
   AC_ARG_WITH(openssl-lib,
-    AC_HELP_STRING([--with-openssl-lib=DIR], [OpenSSL library directory]),
+    AS_HELP_STRING([--with-openssl-lib=DIR], [OpenSSL library directory]),
     [openssl_lib="$withval"
-     LIBS="$LIBS -L$withval"]
+     LDFLAGS="$LDFLAGS -L$withval"]
   )
 
   AC_CHECK_HEADERS(openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h,
@@ -30,8 +26,6 @@ AC_DEFUN(tinc_OPENSSL,
     [AC_MSG_ERROR([OpenSSL header files not found.]); break]
   )
 
-  CPPFLAGS="$tinc_ac_save_CPPFLAGS"
-
 case $host_os in
   *mingw*)
     AC_CHECK_LIB(crypto, SHA1_version,
index cae9c1f..4ff1d26 100644 (file)
@@ -10,7 +10,7 @@ dnl  /* Define to rpl_realloc if the replacement function should be used.  */
 dnl  #undef realloc
 dnl
 
-AC_DEFUN(jm_FUNC_REALLOC,
+AC_DEFUN([jm_FUNC_REALLOC],
 [
  if test x = y; then
    dnl This code is deliberately never run via ./configure.
@@ -23,21 +23,19 @@ AC_DEFUN(jm_FUNC_REALLOC,
  AC_DEFINE(HAVE_DONE_WORKING_REALLOC_CHECK, 1, [Needed for xmalloc.c])
 
  AC_CACHE_CHECK([for working realloc], jm_cv_func_working_realloc,
-  [AC_TRY_RUN([
+  [AC_RUN_IFELSE([AC_LANG_SOURCE([
     char *realloc ();
     int
     main ()
     {
       exit (realloc (0, 0) ? 0 : 1);
     }
-         ],
-        jm_cv_func_working_realloc=yes,
-        jm_cv_func_working_realloc=no,
-        dnl When crosscompiling, assume realloc is broken.
-        jm_cv_func_working_realloc=no)
+   ])],
+   [jm_cv_func_working_realloc=yes],
+   [jm_cv_func_working_realloc=no],
+   [When crosscompiling])
   ])
   if test $jm_cv_func_working_realloc = no; then
-    dnl This was: LIBOBJS="$LIBOBJS realloc.$ac_objext"
     AC_LIBOBJ([realloc])
     AC_DEFINE(realloc, rpl_realloc, [Replacement realloc()])
   fi
index dcf3a15..8c14a9b 100644 (file)
@@ -1,22 +1,28 @@
 dnl Check to find out whether the running kernel has support for TUN/TAP
 
-AC_DEFUN(tinc_TUNTAP,
+AC_DEFUN([tinc_TUNTAP],
 [
   AC_ARG_WITH(kernel,
-    AC_HELP_STRING([--with-kernel=DIR], [give the directory with kernel sources (default: /usr/src/linux)]),
+    AS_HELP_STRING([--with-kernel=DIR], [give the directory with kernel sources (default: /usr/src/linux)]),
     kerneldir="$withval",
     kerneldir="/usr/src/linux"
   )
   
   AC_CACHE_CHECK([for linux/if_tun.h], tinc_cv_linux_if_tun_h,
   [ 
-    AC_TRY_COMPILE([#include "$kerneldir/include/linux/if_tun.h"],
-      [int a = IFF_TAP;],
-      if_tun_h="\"$kerneldir/include/linux/if_tun.h\"",
-      [AC_TRY_COMPILE([#include <linux/if_tun.h>],
-        [int a = IFF_TAP;],
-        if_tun_h="default",
-        if_tun_h="no"
+    AC_COMPILE_IFELSE(
+      AC_LANG_PROGRAM([
+        #include "$kerneldir/include/linux/if_tun.h"
+       int a = IFF_TAP;
+      ]),
+      [if_tun_h="\"$kerneldir/include/linux/if_tun.h\""],
+      [AC_COMPILE_IFELSE(
+        AC_LANG_PROGRAM([
+         #include <linux/if_tun.h>
+          int a = IFF_TAP;
+       ]),
+        [if_tun_h="default"],
+        [if_tun_h="no"]
       )]
     )
   
index d691326..71f39f7 100644 (file)
@@ -1,28 +1,24 @@
 dnl Check to find the zlib headers/libraries
 
-AC_DEFUN(tinc_ZLIB,
+AC_DEFUN([tinc_ZLIB],
 [
-  tinc_ac_save_CPPFLAGS="$CPPFLAGS"
-
   AC_ARG_WITH(zlib,
-    AC_HELP_STRING([--with-zlib=DIR], [zlib base directory, or:]),
+    AS_HELP_STRING([--with-zlib=DIR], [zlib base directory, or:]),
     [zlib="$withval"
-     CFLAGS="$CFLAGS -I$withval/include"
      CPPFLAGS="$CPPFLAGS -I$withval/include"
-     LIBS="$LIBS -L$withval/lib"]
+     LDFLAGS="$LDFLAGS -L$withval/lib"]
   )
 
   AC_ARG_WITH(zlib-include,
-    AC_HELP_STRING([--with-zlib-include=DIR], [zlib headers directory]),
+    AS_HELP_STRING([--with-zlib-include=DIR], [zlib headers directory]),
     [zlib_include="$withval"
-     CFLAGS="$CFLAGS -I$withval"
      CPPFLAGS="$CPPFLAGS -I$withval"]
   )
 
   AC_ARG_WITH(zlib-lib,
-    AC_HELP_STRING([--with-zlib-lib=DIR], [zlib library directory]),
+    AS_HELP_STRING([--with-zlib-lib=DIR], [zlib library directory]),
     [zlib_lib="$withval"
-     LIBS="$LIBS -L$withval"]
+     LDFLAGS="$LDFLAGS -L$withval"]
   )
 
   AC_CHECK_HEADERS(zlib.h,
@@ -30,8 +26,6 @@ AC_DEFUN(tinc_ZLIB,
     [AC_MSG_ERROR("zlib header files not found."); break]
   )
 
-  CPPFLAGS="$tinc_ac_save_CPPFLAGS"
-
   AC_CHECK_LIB(z, compress2,
     [LIBS="$LIBS -lz"],
     [AC_MSG_ERROR("zlib libraries not found.")]
diff --git a/po/.cvsignore b/po/.cvsignore
deleted file mode 100644 (file)
index 493861c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Makefile.in.in POTFILES Makefile.in Makefile cat-id-tbl.c *.gmo stamp-cat-id *.pot
index f7335a3..93e471e 100644 (file)
@@ -20,6 +20,22 @@ XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
 # their copyright.
 COPYRIGHT_HOLDER = Ivo Timmermans and Guus Sliepen
 
+# This is the email address or URL to which the translators shall report
+# bugs in the untranslated strings:
+# - Strings which are not entire sentences, see the maintainer guidelines
+#   in the GNU gettext documentation, section 'Preparing Strings'.
+# - Strings which use unclear terms or require additional context to be
+#   understood.
+# - Strings which make invalid assumptions about notation of date, time or
+#   money.
+# - Pluralisation problems.
+# - Incorrect English spelling.
+# - Incorrect formatting.
+# It can be your email address, or a mailing list address where translators
+# can write to without being subscribed, or the URL of a web page through
+# which the translators can contact you.
+MSGID_BUGS_ADDRESS = tinc-devel@nl.linux.org
+
 # This is the list of locale categories, beyond LC_MESSAGES, for which the
 # message catalogs shall be used.  It is usually empty.
 EXTRA_LOCALE_CATEGORIES =
index 9c3d23a..d06f7c5 100644 (file)
--- a/po/nl.po
+++ b/po/nl.po
@@ -1,13 +1,13 @@
 # Dutch messages for tinc
-# Copyright (C) 1999-2001 Ivo Timmermans, Guus Sliepen.
-# Ivo Timmermans <ivo@o2w.nl>, 1999-2002.
-# Guus Sliepen <guus@sliepen.eu.org>, 2000-2002.
+# Copyright (C) 1999-2004 Ivo Timmermans, Guus Sliepen.
+# Ivo Timmermans <ivo@o2w.nl>, 1999-2003.
+# Guus Sliepen <guus@sliepen.eu.org>, 2000-2003.
 msgid ""
 msgstr ""
-"Project-Id-Version: tinc 1.0-cvs\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2003-08-09 20:57+0200\n"
-"PO-Revision-Date: 2003-05-06 23:10+0200\n"
+"Project-Id-Version: tinc 1.0-svn\n"
+"Report-Msgid-Bugs-To: tinc-devel@nl.linux.org\n"
+"POT-Creation-Date: 2004-03-15 19:28+0100\n"
+"PO-Revision-Date: 2004-03-15 19:28+0100\n"
 "Last-Translator: Guus Sliepen <guus@sliepen.eu.org>\n"
 "Language-Team: Dutch <vertaling@nl.linux.org>\n"
 "MIME-Version: 1.0\n"
@@ -36,12 +36,12 @@ msgid ""
 msgstr ""
 "Hostnaam of IP adres verwacht voor configuratievariabele %s in %s regel %d"
 
-#: src/conf.c:227
+#: src/conf.c:225
 #, c-format
 msgid "Subnet expected for configuration variable %s in %s line %d"
 msgstr "Subnet verwacht voor configuratievariabele %s in %s regel %d"
 
-#: src/conf.c:238
+#: src/conf.c:236
 #, c-format
 msgid ""
 "Network address and prefix length do not match for configuration variable %s "
@@ -50,34 +50,34 @@ msgstr ""
 "Netwerk adres en prefix lengte komen niet overeen bij configuratievariabele %"
 "s in %s regel %d"
 
-#: src/conf.c:339
+#: src/conf.c:336
 #, c-format
 msgid "Cannot open config file %s: %s"
 msgstr "Kan configuratie bestand %s niet openen: %s"
 
-#: src/conf.c:388
+#: src/conf.c:390
 #, c-format
 msgid "No value for variable `%s' on line %d while reading config file %s"
 msgstr ""
 "Geen waarde voor variabele `%s' op regel %d tijdens het lezen van "
 "configuratie bestand %s"
 
-#: src/conf.c:419
+#: src/conf.c:421
 #, c-format
 msgid "Failed to read `%s': %s"
 msgstr "Lezen van `%s' mislukte: %s"
 
-#: src/conf.c:441
+#: src/conf.c:443
 #, c-format
 msgid "Please enter a file to save %s to [%s]: "
 msgstr "Geef een bestand om de %s naar de schrijven [%s]: "
 
-#: src/conf.c:448
+#: src/conf.c:450
 #, c-format
 msgid "Error while reading stdin: %s\n"
 msgstr "Fout tijdens lezen van standaardinvoer: %s\n"
 
-#: src/conf.c:480
+#: src/conf.c:482
 #, c-format
 msgid "Error opening file `%s': %s\n"
 msgstr "Fout bij het openen van het bestand `%s': %s\n"
@@ -103,37 +103,37 @@ msgstr " %s op %s opties %lx socket %d status %04x"
 msgid "End of connections."
 msgstr "Einde van verbindingen."
 
-#: src/meta.c:44
+#: src/meta.c:46
 #, c-format
 msgid "Sending %d bytes of metadata to %s (%s)"
 msgstr "Verzenden van %d bytes metadata naar %s (%s)"
 
-#: src/meta.c:58 src/meta.c:125
+#: src/meta.c:52
+#, c-format
+msgid "Error while encrypting metadata to %s (%s): %s"
+msgstr "Fout tijdens versleutelen van metadata naar %s (%s): %s"
+
+#: src/meta.c:65 src/meta.c:118
 #, c-format
 msgid "Connection closed by %s (%s)"
 msgstr "Verbinding beëindigd door %s (%s)"
 
-#: src/meta.c:63
+#: src/meta.c:70
 #, c-format
 msgid "Sending meta data to %s (%s) failed: %s"
 msgstr "Fout tijdens verzenden metadata naar %s (%s): %s"
 
-#: src/meta.c:101
-#, c-format
-msgid "This is a bug: %s:%d: %d:%s %s (%s)"
-msgstr "Dit is een programmeerfout: %s:%d: %d:%s %s (%s)"
-
-#: src/meta.c:107
-#, c-format
-msgid "Metadata socket error for %s (%s): %s"
-msgstr "Fout op metadata socket voor %s (%s): %s"
-
-#: src/meta.c:130
+#: src/meta.c:123
 #, c-format
 msgid "Metadata socket read error for %s (%s): %s"
 msgstr "Fout op metadata socket voor %s (%s) tijdens lezen: %s"
 
-#: src/meta.c:193
+#: src/meta.c:138
+#, c-format
+msgid "Error while decrypting metadata from %s (%s): %s"
+msgstr "Fout tijdens ontsleutelen van metadata van %s (%s): %s"
+
+#: src/meta.c:191
 #, c-format
 msgid "Metadata read buffer overflow for %s (%s)"
 msgstr "Metadata leesbuffer overloop voor %s (%s)"
@@ -142,460 +142,490 @@ msgstr "Metadata leesbuffer overloop voor %s (%s)"
 msgid "Purging unreachable nodes"
 msgstr "Verwijderen onbereikbare nodes"
 
-#: src/net.c:67
+#: src/net.c:69
 #, c-format
 msgid "Purging node %s (%s)"
 msgstr "Verwijdering node %s (%s)"
 
-#: src/net.c:148
+#: src/net.c:170
 #, c-format
 msgid "Closing connection with %s (%s)"
 msgstr "Beëindigen verbinding met %s (%s)"
 
-#: src/net.c:201
+#: src/net.c:235
 #, c-format
 msgid "%s (%s) didn't respond to PING"
 msgstr "%s (%s) antwoordde niet op ping"
 
-#: src/net.c:210
+#: src/net.c:244
 #, c-format
 msgid "Old connection_t for %s (%s) status %04x still lingering, deleting..."
 msgstr ""
 "Oude connection_t voor %s (%s) status %04x nog steeds aanwezig, wordt "
 "verwijderd..."
 
-#: src/net.c:215
+#: src/net.c:249
 #, c-format
 msgid "Timeout from %s (%s) during authentication"
 msgstr "Timeout van %s (%s) tijdens authenticatie"
 
-#: src/net.c:257
+#: src/net.c:291
 #, c-format
 msgid "Error while connecting to %s (%s): %s"
 msgstr "Fout tijdens schrijven naar %s (%s): %s"
 
-#: src/net.c:312
+#: src/net.c:347
 #, c-format
 msgid "Error while waiting for input: %s"
 msgstr "Fout tijdens wachten op invoer: %s"
 
-#: src/net.c:343
+#: src/net.c:378
 msgid "Regenerating symmetric key"
 msgstr "Hergenereren symmetrische sleutel"
 
-#: src/net.c:360
+#: src/net.c:395
 msgid "Flushing event queue"
 msgstr "Legen taakrij"
 
-#: src/net.c:384
+#: src/net.c:419
 msgid "Unable to reread configuration file, exitting."
 msgstr "Kan configuratiebestand niet herlezen, beëindigen."
 
-#: src/net_packet.c:103
+#: src/net_packet.c:75
+#, c-format
+msgid "No response to MTU probes from %s (%s)"
+msgstr "Geen antwoord van %s (%s) op MTU probes"
+
+#: src/net_packet.c:82
+#, c-format
+msgid "Fixing MTU of %s (%s) to %d after %d probes"
+msgstr "MTU van %s (%s) vastgezet op %d na %d probes"
+
+#: src/net_packet.c:94
+#, c-format
+msgid "Sending MTU probe length %d to %s (%s)"
+msgstr "Verzending MTU probe lengte %d naar %s (%s)"
+
+#: src/net_packet.c:107
+#, c-format
+msgid "Got MTU probe length %d from %s (%s)"
+msgstr "Kreeg MTU probe met verkeerde lengte %d van %s (%s)"
+
+#: src/net_packet.c:164
 #, c-format
 msgid "Received packet of %d bytes from %s (%s)"
 msgstr "Ontvangst pakket van %d bytes van %s (%s)"
 
-#: src/net_packet.c:129
+#: src/net_packet.c:185 src/route.c:108
+#, c-format
+msgid "Got too short packet from %s (%s)"
+msgstr "Kreeg te kort pakket van %s (%s)"
+
+#: src/net_packet.c:198
 #, c-format
 msgid "Got unauthenticated packet from %s (%s)"
 msgstr "Kreeg niet-geauthenticeerd pakket van %s (%s)"
 
-#: src/net_packet.c:158
+#: src/net_packet.c:213
+#, c-format
+msgid "Error decrypting packet from %s (%s): %s"
+msgstr "Fout tijdens ontsleutelen pakket van %s (%s): %s"
+
+#: src/net_packet.c:229
 #, c-format
 msgid "Lost %d packets from %s (%s)"
 msgstr "%d pakketten van %s (%s) verloren"
 
-#: src/net_packet.c:164
+#: src/net_packet.c:235
 #, c-format
 msgid "Got late or replayed packet from %s (%s), seqno %d, last received %d"
 msgstr ""
 "Kreeg laat of gedupliceerd pakket van %s (%s), seqno %d, laatste ontvangen %d"
 
-#: src/net_packet.c:184
+#: src/net_packet.c:255
 #, c-format
 msgid "Error while uncompressing packet from %s (%s)"
 msgstr "Fout tijdens decomprimeren pakket van %s (%s)"
 
-#: src/net_packet.c:226
+#: src/net_packet.c:303
 #, c-format
 msgid "No valid key known yet for %s (%s), queueing packet"
 msgstr ""
 "Nog geen geldige sleutel bekend voor %s (%s), pakket wordt in wachtrij gezet"
 
-#: src/net_packet.c:256
+#: src/net_packet.c:332
 #, c-format
 msgid "Error while compressing packet to %s (%s)"
 msgstr "Fout tijdens comprimeren pakket naar %s (%s)"
 
-#: src/net_packet.c:307
+#: src/net_packet.c:354
+#, c-format
+msgid "Error while encrypting packet to %s (%s): %s"
+msgstr "Fout tijdens versleutelen pakket naar %s (%s): %s"
+
+#: src/net_packet.c:386
 #, c-format
 msgid "Setting outgoing packet priority to %d"
 msgstr "Instellen prioriteit uitgaand pakket op %d"
 
-#: src/net_packet.c:309 src/net_setup.c:465 src/net_socket.c:74
-#: src/net_socket.c:122 src/net_socket.c:153 src/tincd.c:433 src/tincd.c:467
-#: src/process.c:204 src/process.c:237 src/process.c:415
-#: src/cygwin/device.c:150 src/cygwin/device.c:181 src/mingw/device.c:76
-#: src/mingw/device.c:85 src/mingw/device.c:90 src/mingw/device.c:245
-#: src/mingw/device.c:252 src/mingw/device.c:257 src/mingw/device.c:264
-#: src/mingw/device.c:273 src/mingw/device.c:280
+#: src/net_packet.c:388 src/net_setup.c:475 src/net_socket.c:72
+#: src/net_socket.c:123 src/net_socket.c:152 src/tincd.c:434 src/tincd.c:468
+#: src/process.c:198 src/process.c:231 src/process.c:417
+#: src/cygwin/device.c:150 src/cygwin/device.c:181 src/mingw/device.c:82
+#: src/mingw/device.c:91 src/mingw/device.c:96 src/mingw/device.c:252
+#: src/mingw/device.c:259 src/mingw/device.c:264 src/mingw/device.c:271
+#: src/mingw/device.c:280 src/mingw/device.c:287
 #, c-format
 msgid "System call `%s' failed: %s"
 msgstr "Systeemaanroep `%s' mislukte: %s"
 
-#: src/net_packet.c:314
+#: src/net_packet.c:399
 #, c-format
 msgid "Error sending packet to %s (%s): %s"
 msgstr "Fout tijdens verzenden pakket naar %s (%s): %s"
 
-#: src/net_packet.c:330
+#: src/net_packet.c:422
 #, c-format
 msgid "Sending packet of %d bytes to %s (%s)"
 msgstr "Verzending pakket van %d bytes naar %s (%s)"
 
-#: src/net_packet.c:334
-msgid "Packet is looping back to us!"
-msgstr "Pakket komt terug naar ons!"
-
-#: src/net_packet.c:339
+#: src/net_packet.c:426
 #, c-format
 msgid "Node %s (%s) is not reachable"
 msgstr "Node %s (%s) is niet bereikbaar"
 
-#: src/net_packet.c:347
+#: src/net_packet.c:434
 #, c-format
 msgid "Sending packet to %s via %s (%s)"
 msgstr "Verzending pakket naar %s via %s (%s)"
 
-#: src/net_packet.c:366
+#: src/net_packet.c:453
 #, c-format
 msgid "Broadcasting packet of %d bytes from %s (%s)"
 msgstr "Verspreiding pakket van %d bytes van %s (%s)"
 
-#: src/net_packet.c:383
+#: src/net_packet.c:470
 #, c-format
 msgid "Flushing queue for %s (%s)"
 msgstr "Legen van wachtrij voor %s (%s)"
 
-#: src/net_packet.c:404
-#, c-format
-msgid "This is a bug: %s:%d: %d:%s"
-msgstr "Dit is een programmeerfout: %s:%d: %d:%s"
-
-#: src/net_packet.c:411
-#, c-format
-msgid "Incoming data socket error: %s"
-msgstr "Fout op socket voor inkomend verkeer: %s"
-
-#: src/net_packet.c:418
+#: src/net_packet.c:492
 #, c-format
 msgid "Receiving packet failed: %s"
 msgstr "Ontvangst pakket mislukt: %s"
 
-#: src/net_packet.c:428
+#: src/net_packet.c:502
 #, c-format
 msgid "Received UDP packet from unknown source %s"
 msgstr "Ontvangst UDP pakket van onbekende oorsprong %s"
 
-#: src/net_setup.c:75 src/net_setup.c:92
+#: src/net_setup.c:77 src/net_setup.c:94
 #, c-format
 msgid "Error reading RSA public key file `%s': %s"
 msgstr "Fout tijdens lezen RSA publieke sleutel bestand `%s': %s"
 
-#: src/net_setup.c:107
+#: src/net_setup.c:109
 #, c-format
 msgid "Reading RSA public key file `%s' failed: %s"
 msgstr "Lezen RSA publieke sleutel bestand `%s' mislukt: %s"
 
-#: src/net_setup.c:143
+#: src/net_setup.c:145
 #, c-format
 msgid "No public key for %s specified!"
 msgstr "Geen publieke sleutel bekend voor %s gespecificeerd!"
 
-#: src/net_setup.c:171
+#: src/net_setup.c:160
+msgid "PrivateKey used but no PublicKey found!"
+msgstr "PrivateKey gebruikt maar geen PublicKey gevonden!"
+
+#: src/net_setup.c:179
 #, c-format
 msgid "Error reading RSA private key file `%s': %s"
 msgstr "Fout tijdens lezen RSA privé sleutel bestand `%s': %s"
 
-#: src/net_setup.c:179
+#: src/net_setup.c:187
 #, c-format
 msgid "Could not stat RSA private key file `%s': %s'"
 msgstr "Kon gegevens RSA privé sleutel bestand `%s' niet opvragen: %s"
 
-#: src/net_setup.c:186
+#: src/net_setup.c:194
 #, c-format
 msgid "Warning: insecure file permissions for RSA private key file `%s'!"
 msgstr ""
 "Waarschuwing: onveilige permissies voor RSA privé sleutel bestand `%s'!"
 
-#: src/net_setup.c:193
+#: src/net_setup.c:201
 #, c-format
 msgid "Reading RSA private key file `%s' failed: %s"
 msgstr "Fout tijdens lezen RSA privé sleutel bestand `%s': %s"
 
-#: src/net_setup.c:223 src/net_setup.c:224
+#: src/net_setup.c:231 src/net_setup.c:232
 msgid "MYSELF"
 msgstr "MIJZELF"
 
-#: src/net_setup.c:230
+#: src/net_setup.c:238
 msgid "Name for tinc daemon required!"
 msgstr "Naam voor tinc daemon verplicht!"
 
-#: src/net_setup.c:235
+#: src/net_setup.c:243
 msgid "Invalid name for myself!"
 msgstr "Ongeldige naam voor mijzelf!"
 
-#: src/net_setup.c:247
+#: src/net_setup.c:252
 msgid "Cannot open host configuration file for myself!"
 msgstr "Kan host configuratie bestand voor mijzelf niet openen!"
 
-#: src/net_setup.c:300
+#: src/net_setup.c:305
 msgid "Invalid routing mode!"
 msgstr "Ongeldige routing modus!"
 
-#: src/net_setup.c:311
+#: src/net_setup.c:316
 msgid "PriorityInheritance not supported on this platform"
 msgstr "PriorityInheritance wordt niet ondersteund op dit platform"
 
-#: src/net_setup.c:319
+#: src/net_setup.c:324
 msgid "Bogus maximum timeout!"
 msgstr "Onzinnige maximum timeout!"
 
-#: src/net_setup.c:333
+#: src/net_setup.c:338
 msgid "Invalid address family!"
 msgstr "Ongeldige adresfamilie!"
 
-#: src/net_setup.c:351
+#: src/net_setup.c:356
 msgid "Unrecognized cipher type!"
 msgstr "Onbekend cipher type!"
 
-#: src/net_setup.c:388
+#: src/net_setup.c:381 src/protocol_auth.c:189
+#, c-format
+msgid "Error during initialisation of cipher for %s (%s): %s"
+msgstr "Fout tijdens initialisatie van cipher voor %s (%s): %s"
+
+#: src/net_setup.c:398
 msgid "Unrecognized digest type!"
 msgstr "Onbekend digest type!"
 
-#: src/net_setup.c:401
+#: src/net_setup.c:411
 msgid "MAC length exceeds size of digest!"
 msgstr "MAC lengte is groter dan dat van digest!"
 
-#: src/net_setup.c:404
+#: src/net_setup.c:414
 msgid "Bogus MAC length!"
 msgstr "Onzinnige MAC lengte!"
 
-#: src/net_setup.c:418
+#: src/net_setup.c:428
 msgid "Bogus compression level!"
 msgstr "Onzinnig compressieniveau!"
 
-#: src/net_setup.c:487
+#: src/net_setup.c:497
 #, c-format
 msgid "Listening on %s"
 msgstr "Luisterend op %s"
 
-#: src/net_setup.c:498
+#: src/net_setup.c:508
 msgid "Ready"
 msgstr "Gereed"
 
-#: src/net_setup.c:500
+#: src/net_setup.c:510
 msgid "Unable to create any listening socket!"
 msgstr "Kon geen enkele luistersocket aanmaken!"
 
-#: src/net_socket.c:65
+#: src/net_socket.c:62
 #, c-format
 msgid "Creating metasocket failed: %s"
 msgstr "Aanmaak van metasocket mislukt: %s"
 
-#: src/net_socket.c:102 src/net_socket.c:170
+#: src/net_socket.c:103 src/net_socket.c:195
 #, c-format
 msgid "Can't bind to interface %s: %s"
 msgstr "Kan niet aan interface %s binden: %s"
 
-#: src/net_socket.c:107
+#: src/net_socket.c:108
 msgid "BindToInterface not supported on this platform"
 msgstr "BindToInterface wordt niet ondersteund op dit platform"
 
-#: src/net_socket.c:114
+#: src/net_socket.c:115
 #, c-format
 msgid "Can't bind to %s/tcp: %s"
 msgstr "Kan niet aan %s/tcp binden: %s"
 
-#: src/net_socket.c:145
+#: src/net_socket.c:142
 #, c-format
 msgid "Creating UDP socket failed: %s"
 msgstr "Aanmaak UDP socket mislukte: %s"
 
-#: src/net_socket.c:180
+#: src/net_socket.c:206
 #, c-format
 msgid "Can't bind to %s/udp: %s"
 msgstr "Kan niet aan %s/udp binden: %s"
 
-#: src/net_socket.c:207
+#: src/net_socket.c:233
 #, c-format
 msgid "Trying to re-establish outgoing connection in %d seconds"
 msgstr "Poging tot herstellen van uitgaande verbinding over %d seconden"
 
-#: src/net_socket.c:215
+#: src/net_socket.c:241
 #, c-format
 msgid "Connected to %s (%s)"
 msgstr "Verbonden met %s (%s)"
 
-#: src/net_socket.c:232
+#: src/net_socket.c:258
 #, c-format
 msgid "Could not set up a meta connection to %s"
 msgstr "Kon geen metaverbinding aangaan met %s"
 
-#: src/net_socket.c:267
+#: src/net_socket.c:292
 #, c-format
 msgid "Trying to connect to %s (%s)"
 msgstr "Poging tot verbinden met %s (%s)"
 
-#: src/net_socket.c:273
+#: src/net_socket.c:298
 #, c-format
 msgid "Creating socket for %s failed: %s"
 msgstr "Aanmaken socket voor %s mislukt: %s"
 
-#: src/net_socket.c:297
+#: src/net_socket.c:322
 #, c-format
 msgid "fcntl for %s: %s"
 msgstr "fcntl voor %s: %s"
 
-#: src/net_socket.c:313
+#: src/net_socket.c:338
 #, c-format
 msgid "%s: %s"
 msgstr "%s: %s"
 
-#: src/net_socket.c:334
+#: src/net_socket.c:359
 #, c-format
 msgid "Already connected to %s"
 msgstr "Reeds verbonden met %s"
 
-#: src/net_socket.c:353
+#: src/net_socket.c:378
 #, c-format
 msgid "No address specified for %s"
 msgstr "Geen adres gespecificeerd voor %s"
 
-#: src/net_socket.c:383
+#: src/net_socket.c:408
 #, c-format
 msgid "Accepting a new connection failed: %s"
 msgstr "Aanname van nieuwe verbinding is mislukt: %s"
 
-#: src/net_socket.c:401
+#: src/net_socket.c:426
 #, c-format
 msgid "Connection from %s"
 msgstr "Verbinding van %s"
 
-#: src/net_socket.c:425
+#: src/net_socket.c:450
 #, c-format
 msgid "Invalid name for outgoing connection in %s line %d"
 msgstr "Ongeldige naam voor uitgaande verbinding in %s regel %d"
 
-#: src/netutl.c:50 src/netutl.c:73
+#: src/netutl.c:50
 #, c-format
 msgid "Error looking up %s port %s: %s"
 msgstr "Fout bij het opzoeken van %s poort %s: %s"
 
-#: src/netutl.c:98
+#: src/netutl.c:105
 #, c-format
 msgid "Error while translating addresses: %s"
 msgstr "Fout tijdens vertalen adressen: %s"
 
-#: src/netutl.c:126
-#, c-format
-msgid "Error while looking up hostname: %s"
-msgstr "Fout bij het opzoeken van hostnaam: %s"
-
-#: src/netutl.c:130
+#: src/netutl.c:131 src/netutl.c:142
 #, c-format
 msgid "%s port %s"
 msgstr "%s poort %s"
 
-#: src/netutl.c:167
+#: src/netutl.c:138
+#, c-format
+msgid "Error while looking up hostname: %s"
+msgstr "Fout bij het opzoeken van hostnaam: %s"
+
+#: src/netutl.c:187
 #, c-format
 msgid "sockaddrcmp() was called with unknown address family %d, exitting!"
 msgstr ""
 "sockaddrcmp() werd aangeroepen met onbekende adresfamilie %d, beëindigen!"
 
-#: src/protocol.c:85
+#: src/protocol.c:87
 #, c-format
 msgid "Output buffer overflow while sending request to %s (%s)"
 msgstr "Uitvoer buffer overvol tijdens zenden verzoek naar %s (%s)"
 
-#: src/protocol.c:93
+#: src/protocol.c:95
 #, c-format
 msgid "Sending %s to %s (%s): %s"
 msgstr "Verzending %s naar %s (%s): %s"
 
-#: src/protocol.c:96
+#: src/protocol.c:98
 #, c-format
 msgid "Sending %s to %s (%s)"
 msgstr "Verzending %s naar %s (%s)"
 
-#: src/protocol.c:118
+#: src/protocol.c:120
 #, c-format
 msgid "Forwarding %s from %s (%s): %s"
 msgstr "Doorsturen %s van %s (%s): %s"
 
-#: src/protocol.c:122
+#: src/protocol.c:124
 #, c-format
 msgid "Forwarding %s from %s (%s)"
 msgstr "Doorsturen %s van %s (%s)"
 
-#: src/protocol.c:140
+#: src/protocol.c:142
 #, c-format
 msgid "Unknown request from %s (%s): %s"
 msgstr "Onbekend verzoek van %s (%s): %s"
 
-#: src/protocol.c:143
+#: src/protocol.c:145
 #, c-format
 msgid "Unknown request from %s (%s)"
 msgstr "Onbekend verzoek van %s (%s)"
 
-#: src/protocol.c:150
+#: src/protocol.c:152
 #, c-format
 msgid "Got %s from %s (%s): %s"
 msgstr "Kreeg %s van %s (%s): %s"
 
-#: src/protocol.c:154
+#: src/protocol.c:156
 #, c-format
 msgid "Got %s from %s (%s)"
 msgstr "Kreeg %s van %s (%s)"
 
-#: src/protocol.c:160
+#: src/protocol.c:162
 #, c-format
 msgid "Unauthorized request from %s (%s)"
 msgstr "Niet toegestaan verzoek van %s (%s)"
 
-#: src/protocol.c:168
+#: src/protocol.c:170
 #, c-format
 msgid "Error while processing %s from %s (%s)"
 msgstr "Fout tijdens afhandelen %s van %s (%s)"
 
-#: src/protocol.c:173
+#: src/protocol.c:175
 #, c-format
 msgid "Bogus data received from %s (%s)"
 msgstr "Onzinnige data ontvangen van %s (%s)"
 
-#: src/protocol.c:219
+#: src/protocol.c:221
 msgid "Already seen request"
 msgstr "Verzoek reeds gezien"
 
-#: src/protocol.c:249
+#: src/protocol.c:251
 #, c-format
 msgid "Aging past requests: deleted %d, left %d"
 msgstr "Veroudering vorige verzoeken: %d gewist, %d overgebleven"
 
-#: src/protocol_auth.c:58 src/protocol_auth.c:213 src/protocol_auth.c:338
-#: src/protocol_auth.c:402 src/protocol_auth.c:501 src/protocol_edge.c:73
-#: src/protocol_edge.c:184 src/protocol_key.c:59 src/protocol_key.c:101
-#: src/protocol_key.c:165 src/protocol_misc.c:54 src/protocol_misc.c:83
-#: src/protocol_misc.c:171 src/protocol_subnet.c:61 src/protocol_subnet.c:151
+#: src/protocol_auth.c:58 src/protocol_auth.c:209 src/protocol_auth.c:338
+#: src/protocol_auth.c:405 src/protocol_auth.c:531 src/protocol_edge.c:73
+#: src/protocol_edge.c:188 src/protocol_key.c:62 src/protocol_key.c:105
+#: src/protocol_key.c:172 src/protocol_misc.c:54 src/protocol_misc.c:83
+#: src/protocol_misc.c:171 src/protocol_subnet.c:58 src/protocol_subnet.c:167
 #, c-format
 msgid "Got bad %s from %s (%s)"
 msgstr "Kreeg verkeerde %s van %s (%s)"
 
 #: src/protocol_auth.c:66 src/protocol_edge.c:81 src/protocol_edge.c:87
-#: src/protocol_edge.c:192 src/protocol_edge.c:198 src/protocol_subnet.c:69
-#: src/protocol_subnet.c:79 src/protocol_subnet.c:159
-#: src/protocol_subnet.c:179
+#: src/protocol_edge.c:196 src/protocol_edge.c:202 src/protocol_subnet.c:66
+#: src/protocol_subnet.c:74 src/protocol_subnet.c:175
+#: src/protocol_subnet.c:196
 #, c-format
 msgid "Got bad %s from %s (%s): %s"
 msgstr "Kreeg verkeerde %s van %s (%s): %s"
@@ -615,33 +645,38 @@ msgstr "Ander %s (%s) gebruikt incompatibele versie %d"
 msgid "Peer %s had unknown identity (%s)"
 msgstr "Ander %s heeft onbekende identiteit (%s)"
 
-#: src/protocol_auth.c:161
+#: src/protocol_auth.c:153
 #, c-format
 msgid "Generated random meta key (unencrypted): %s"
 msgstr "Willekeurige meta sleutel aangemaakt (niet versleuteld): %s"
 
-#: src/protocol_auth.c:173 src/protocol_auth.c:242
+#: src/protocol_auth.c:165 src/protocol_auth.c:238
 #, c-format
 msgid "Error during encryption of meta key for %s (%s)"
 msgstr "Fout tijdens versleutelen van meta key voor %s (%s)"
 
-#: src/protocol_auth.c:223 src/protocol_auth.c:348 src/protocol_auth.c:410
-#: src/protocol_auth.c:428
+#: src/protocol_auth.c:219 src/protocol_auth.c:348 src/protocol_auth.c:413
+#: src/protocol_auth.c:435
 #, c-format
 msgid "Possible intruder %s (%s): %s"
 msgstr "Mogelijke indringer %s (%s): %s"
 
-#: src/protocol_auth.c:250
+#: src/protocol_auth.c:246
 #, c-format
 msgid "Received random meta key (unencrypted): %s"
 msgstr "Ontving willekeurige meta key (niet versleuteld): %s"
 
-#: src/protocol_auth.c:261
+#: src/protocol_auth.c:257
 #, c-format
 msgid "%s (%s) uses unknown cipher!"
 msgstr "%s (%s) gebruikt onbekende cipher!"
 
-#: src/protocol_auth.c:281 src/protocol_key.c:232
+#: src/protocol_auth.c:265
+#, c-format
+msgid "Error during initialisation of cipher from %s (%s): %s"
+msgstr "Fout tijdens initalisatie van cipher van %s (%s): %s"
+
+#: src/protocol_auth.c:281 src/protocol_key.c:242
 #, c-format
 msgid "Node %s (%s) uses unknown digest!"
 msgstr "Node %s (%s) gebruikt onbekende digest!"
@@ -651,73 +686,83 @@ msgstr "Node %s (%s) gebruikt onbekende digest!"
 msgid "%s (%s) uses bogus MAC length!"
 msgstr "%s (%s) gebruikt onzinnige MAC lengte!"
 
-#: src/protocol_auth.c:411
+#: src/protocol_auth.c:381
+#, c-format
+msgid "Error during calculation of response for %s (%s): %s"
+msgstr "Fout tijdens berekenen van antwoord voor %s (%s): %s"
+
+#: src/protocol_auth.c:414
 msgid "wrong challenge reply length"
 msgstr "verkeerde lengte antwoord op uitdaging"
 
-#: src/protocol_auth.c:429
+#: src/protocol_auth.c:427
+#, c-format
+msgid "Error during calculation of response from %s (%s): %s"
+msgstr "Fout tijdens narekenen van antwoord van %s (%s): %s"
+
+#: src/protocol_auth.c:436
 msgid "wrong challenge reply"
 msgstr "verkeerd antwoord op uitdaging"
 
-#: src/protocol_auth.c:434
+#: src/protocol_auth.c:441
 #, c-format
 msgid "Expected challenge reply: %s"
 msgstr "Verwachtte antwoord op uitdaging: %s"
 
-#: src/protocol_auth.c:517
+#: src/protocol_auth.c:547
 #, c-format
 msgid "Established a second connection with %s (%s), closing old connection"
 msgstr "Tweede verbinding met %s (%s) gemaakt, oude verbinding wordt gesloten"
 
-#: src/protocol_auth.c:534
+#: src/protocol_auth.c:570
 #, c-format
 msgid "Connection with %s (%s) activated"
 msgstr "Verbinding met %s (%s) geactiveerd"
 
-#: src/protocol_edge.c:82 src/protocol_edge.c:88 src/protocol_edge.c:193
-#: src/protocol_edge.c:199 src/protocol_subnet.c:70 src/protocol_subnet.c:160
+#: src/protocol_edge.c:82 src/protocol_edge.c:88 src/protocol_edge.c:197
+#: src/protocol_edge.c:203 src/protocol_subnet.c:67 src/protocol_subnet.c:176
 msgid "invalid name"
 msgstr "ongeldige naam"
 
-#: src/protocol_edge.c:124
+#: src/protocol_edge.c:127
 #, c-format
 msgid "Got %s from %s (%s) for ourself which does not match existing entry"
 msgstr ""
 "Kreeg %s van %s (%s) voor onszelf welke niet overeenkomt met reeds bekende"
 
-#: src/protocol_edge.c:129
+#: src/protocol_edge.c:132
 #, c-format
 msgid "Got %s from %s (%s) which does not match existing entry"
 msgstr "Kreeg %s van %s (%s) welke niet overeenkomt met reeds bekende"
 
-#: src/protocol_edge.c:137
+#: src/protocol_edge.c:140
 #, c-format
 msgid "Got %s from %s (%s) for ourself which does not exist"
 msgstr "Kreeg %s van %s (%s) voor onszelf welke niet bestaat"
 
-#: src/protocol_edge.c:211 src/protocol_edge.c:219 src/protocol_edge.c:229
+#: src/protocol_edge.c:215 src/protocol_edge.c:223 src/protocol_edge.c:236
 #, c-format
 msgid "Got %s from %s (%s) which does not appear in the edge tree"
 msgstr "Kreeg %s van %s (%s) welke niet voorkomt in de edge tree"
 
-#: src/protocol_edge.c:235 src/protocol_subnet.c:107 src/protocol_subnet.c:204
+#: src/protocol_edge.c:242 src/protocol_subnet.c:103 src/protocol_subnet.c:219
 #, c-format
 msgid "Got %s from %s (%s) for ourself"
 msgstr "Kreeg %s van %s (%s) voor onszelf"
 
-#: src/protocol_key.c:70
+#: src/protocol_key.c:73
 #, c-format
 msgid "Got %s from %s (%s) origin %s which does not exist"
 msgstr "Kreeg %s van %s (%s) herkomst %s welke niet bestaat"
 
-#: src/protocol_key.c:109 src/protocol_key.c:173
+#: src/protocol_key.c:113 src/protocol_key.c:180
 #, c-format
 msgid ""
 "Got %s from %s (%s) origin %s which does not exist in our connection list"
 msgstr ""
 "Kreeg %s van %s (%s) herkomst %s welke niet voorkomt in de verbindingslijst"
 
-#: src/protocol_key.c:117 src/protocol_key.c:181
+#: src/protocol_key.c:121 src/protocol_key.c:188
 #, c-format
 msgid ""
 "Got %s from %s (%s) destination %s which does not exist in our connection "
@@ -725,26 +770,31 @@ msgid ""
 msgstr ""
 "Kreeg %s van %s (%s) doel %s welke niet voorkomt in de verbindingslijst"
 
-#: src/protocol_key.c:212
+#: src/protocol_key.c:222
 #, c-format
 msgid "Node %s (%s) uses unknown cipher!"
 msgstr "Node %s (%s) gebruikt onbekende cipher!"
 
-#: src/protocol_key.c:218
+#: src/protocol_key.c:228
 #, c-format
 msgid "Node %s (%s) uses wrong keylength!"
 msgstr "Node %s (%s) gebruikt verkeerde lengte sleutel!"
 
-#: src/protocol_key.c:238
+#: src/protocol_key.c:248
 #, c-format
 msgid "Node %s (%s) uses bogus MAC length!"
 msgstr "Node %s (%s) gebruikt onzinnige MAC lengte!"
 
-#: src/protocol_key.c:247
+#: src/protocol_key.c:257
 #, c-format
 msgid "Node %s (%s) uses bogus compression level!"
 msgstr "Node %s (%s) gebruikt onzinnig compressieniveau!"
 
+#: src/protocol_key.c:265
+#, c-format
+msgid "Error during initialisation of key from %s (%s): %s"
+msgstr "Fout tijdens initialisatie van sleutel van %s (%s): %s"
+
 #: src/protocol_misc.c:59
 #, c-format
 msgid "Status message from %s (%s): %d: %s"
@@ -755,16 +805,16 @@ msgstr "Statusmelding van %s (%s): %d: %s"
 msgid "Error message from %s (%s): %d: %s"
 msgstr "Foutmelding van %s (%s): %d: %s"
 
-#: src/protocol_subnet.c:80 src/protocol_subnet.c:180
+#: src/protocol_subnet.c:75 src/protocol_subnet.c:197
 msgid "invalid subnet string"
 msgstr "ongeldige subnet string"
 
-#: src/protocol_subnet.c:169
+#: src/protocol_subnet.c:185
 #, c-format
 msgid "Got %s from %s (%s) for %s which is not in our node tree"
 msgstr "Kreeg %s van %s (%s) voor %s welke niet voorkomt in de node boom"
 
-#: src/protocol_subnet.c:196
+#: src/protocol_subnet.c:211
 #, c-format
 msgid "Got %s from %s (%s) for %s which does not appear in his subnet tree"
 msgstr "Kreeg %s van %s (%s) voor %s welke niet voorkomt in zijn subnet boom"
@@ -775,30 +825,30 @@ msgid "subnet_compare() was called with unknown subnet type %d, exitting!"
 msgstr ""
 "subnet_compare() werd aangeroepen met onbekend subnet type %d, beëindigen!"
 
-#: src/subnet.c:288
+#: src/subnet.c:281
 #, c-format
 msgid "net2str() was called with unknown subnet type %d, exiting!"
 msgstr "net2str() werd aangeroepen met onbekend subnet type %d, beëindigen!"
 
-#: src/subnet.c:403
+#: src/subnet.c:396
 msgid "Subnet list:"
 msgstr "Subnet lijst:"
 
-#: src/subnet.c:408
+#: src/subnet.c:402
 #, c-format
 msgid " %s owner %s"
 msgstr " %s eigenaar %s"
 
-#: src/subnet.c:412
+#: src/subnet.c:405
 msgid "End of subnet list."
 msgstr "Einde van subnet lijst."
 
-#: src/tincd.c:107
+#: src/tincd.c:108
 #, c-format
 msgid "Try `%s --help' for more information.\n"
 msgstr "Probeer `%s --help' voor meer informatie.\n"
 
-#: src/tincd.c:110
+#: src/tincd.c:111
 #, c-format
 msgid ""
 "Usage: %s [option]...\n"
@@ -807,7 +857,8 @@ msgstr ""
 "Gebruik: %s [optie]...\n"
 "\n"
 
-#: src/tincd.c:111
+#: src/tincd.c:112
+#, c-format
 msgid ""
 "  -c, --config=DIR           Read configuration options from DIR.\n"
 "  -D, --no-detach            Don't fork and detach.\n"
@@ -836,13 +887,14 @@ msgstr ""
 "      --version              Geef versie informatie en beëindig.\n"
 "\n"
 
-#: src/tincd.c:122
+#: src/tincd.c:123
+#, c-format
 msgid "Report bugs to tinc@nl.linux.org.\n"
 msgstr ""
 "Meld fouten in het programma aan tinc@nl.linux.org;\n"
 "Meld fouten in de vertaling aan vertaling@nl.linux.org.\n"
 
-#: src/tincd.c:178
+#: src/tincd.c:179
 #, c-format
 msgid ""
 "Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, "
@@ -851,7 +903,7 @@ msgstr ""
 "Ongeldig argument `%s'; SIGNAAL moet een getal zijn of één van HUP, TERM, "
 "KILL, USR1, USR2, WINCH, INT of ALRM.\n"
 
-#: src/tincd.c:200
+#: src/tincd.c:201
 #, c-format
 msgid ""
 "Invalid argument `%s'; BITS must be a number equal to or greater than 512.\n"
@@ -859,24 +911,27 @@ msgstr ""
 "Ongeldig argument `%s'; BITS moet een nummer zijn gelijk aan of groter dan "
 "512.\n"
 
-#: src/tincd.c:293
+#: src/tincd.c:294
 #, c-format
 msgid "Generating %d bits keys:\n"
 msgstr "Bezig met genereren van een %d bits sleutel:\n"
 
-#: src/tincd.c:297
+#: src/tincd.c:298
+#, c-format
 msgid "Error during key generation!\n"
 msgstr "Fout tijdens genereren sleutel!\n"
 
-#: src/tincd.c:300
+#: src/tincd.c:301
+#, c-format
 msgid "Done.\n"
 msgstr "Klaar.\n"
 
-#: src/tincd.c:303
+#: src/tincd.c:304
 msgid "private RSA key"
 msgstr "geheime RSA sleutel"
 
-#: src/tincd.c:314 src/tincd.c:333
+#: src/tincd.c:315 src/tincd.c:334
+#, c-format
 msgid ""
 "Appending key to existing contents.\n"
 "Make sure only one key is stored in the file.\n"
@@ -884,21 +939,22 @@ msgstr ""
 "Sleutel wordt toegevoegd aan bestaande inhoud.\n"
 "Let er op dat er slechts één sleutel in het bestand is.\n"
 
-#: src/tincd.c:327
+#: src/tincd.c:328
 msgid "public RSA key"
 msgstr "openbare RSA sleutel"
 
-#: src/tincd.c:386
+#: src/tincd.c:387
 msgid "Both netname and configuration directory given, using the latter..."
 msgstr ""
 "Zowel netnaam als configuratiemap zijn gegeven, laatste wordt gebruikt..."
 
-#: src/tincd.c:407
+#: src/tincd.c:408
 #, c-format
 msgid "%s version %s (built %s %s, protocol %d)\n"
 msgstr "%s versie %s (gemaakt %s %s, protocol %d)\n"
 
-#: src/tincd.c:409
+#: src/tincd.c:410
+#, c-format
 msgid ""
 "Copyright (C) 1998-2003 Ivo Timmermans, Guus Sliepen and others.\n"
 "See the AUTHORS file for a complete list.\n"
@@ -915,24 +971,15 @@ msgstr ""
 "en je bent welkom om het te distribueren onder bepaalde voorwaarden;\n"
 "zie het bestand COPYING voor details.\n"
 
-#: src/tincd.c:437
+#: src/tincd.c:438
 msgid "mlockall() not supported on this platform!"
 msgstr "mlockall() wordt niet ondersteund op dit platform!"
 
-#: src/tincd.c:461
+#: src/tincd.c:462
 msgid "Error initializing LZO compressor!"
 msgstr "Fout tijdens initialiseren LZO compressor!"
 
-#: src/tincd.c:489
-#, c-format
-msgid "Restarting in %d seconds!"
-msgstr "Herstart in %d seconden!"
-
-#: src/tincd.c:492 src/process.c:468
-msgid "Not restarting."
-msgstr "Geen herstart."
-
-#: src/tincd.c:508
+#: src/tincd.c:503
 msgid "Terminating"
 msgstr "Beëindigen"
 
@@ -941,154 +988,171 @@ msgstr "Beëindigen"
 msgid "Memory exhausted (couldn't allocate %d bytes), exitting."
 msgstr "Geheugen uitgeput (kon geen %d bytes reserveren), beëindigen."
 
-#: src/process.c:92 src/process.c:139
+#: src/process.c:79 src/process.c:129
 #, c-format
 msgid "Could not open service manager: %s"
 msgstr "Kon service manager niet openen: %s"
 
-#: src/process.c:120
+#: src/process.c:110
 #, c-format
 msgid "Could not create %s service: %s"
 msgstr "Kon %s service niet aanmaken: %s"
 
-#: src/process.c:126
+#: src/process.c:116
 #, c-format
 msgid "%s service installed"
 msgstr "%s service geïnstalleerd"
 
-#: src/process.c:129
+#: src/process.c:119
 #, c-format
 msgid "Could not start %s service: %s"
 msgstr "Kon %s service niet starten: %s"
 
-#: src/process.c:131
+#: src/process.c:121
 #, c-format
 msgid "%s service started"
 msgstr "%s service gestart"
 
-#: src/process.c:146
+#: src/process.c:136
 #, c-format
 msgid "Could not open %s service: %s"
 msgstr "Kon %s service niet openen: %s"
 
-#: src/process.c:151
+#: src/process.c:141
 #, c-format
 msgid "Could not stop %s service: %s"
 msgstr "Kon %s service niet stoppen: %s"
 
-#: src/process.c:153
+#: src/process.c:143
 #, c-format
 msgid "%s service stopped"
 msgstr "%s service gestopt"
 
-#: src/process.c:156
+#: src/process.c:146
 #, c-format
 msgid "Could not remove %s service: %s"
 msgstr "Kon %s service niet verwijderen: %s"
 
-#: src/process.c:160
+#: src/process.c:150
 #, c-format
 msgid "%s service removed"
 msgstr "%s service verwijderd"
 
-#: src/process.c:168 src/process.c:172
+#: src/process.c:158 src/process.c:161
 #, c-format
 msgid "Got %s request"
 msgstr "Kreeg %s verzoek"
 
-#: src/process.c:176
+#: src/process.c:164
 #, c-format
 msgid "Got unexpected request %d"
 msgstr "Kreeg onverwacht verzoek %d"
 
-#: src/process.c:258
+#: src/process.c:252
+#, c-format
+msgid "A tincd is already running for net `%s' with pid %ld.\n"
+msgstr "Een tincd draait al voor net `%s' met pid %ld.\n"
+
+#: src/process.c:255
 #, c-format
-msgid "A tincd is already running for net `%s' with pid %d.\n"
-msgstr "Een tincd draait al voor net `%s' met pid %d.\n"
+msgid "A tincd is already running with pid %ld.\n"
+msgstr "Een tincd draait al met pid %ld.\n"
 
 #: src/process.c:261
 #, c-format
-msgid "A tincd is already running with pid %d.\n"
-msgstr "Een tincd draait al met pid %d.\n"
+msgid "Could write pid file %s: %s\n"
+msgstr "Kon pid bestand %s niet openen: %s\n"
 
-#: src/process.c:287
+#: src/process.c:283
 #, c-format
 msgid "No other tincd is running for net `%s'.\n"
 msgstr "Geen andere tincd draait voor net `%s'.\n"
 
-#: src/process.c:290
+#: src/process.c:286
+#, c-format
 msgid "No other tincd is running.\n"
 msgstr "Geen andere tincd draait.\n"
 
-#: src/process.c:299
+#: src/process.c:295
 #, c-format
 msgid "The tincd for net `%s' is no longer running. "
 msgstr "De tincd voor net `%s' draait niet meer. "
 
-#: src/process.c:302
+#: src/process.c:298
+#, c-format
 msgid "The tincd is no longer running. "
 msgstr "De tincd draait niet meer. "
 
-#: src/process.c:304
+#: src/process.c:300
+#, c-format
 msgid "Removing stale lock file.\n"
 msgstr "Verwijdering oud vergrendelingsbestand.\n"
 
-#: src/process.c:337
+#: src/process.c:333
 #, c-format
 msgid "Couldn't detach from terminal: %s"
 msgstr "Kon niet ontkoppelen van terminal: %s"
 
-#: src/process.c:354
+#: src/process.c:341
+#, c-format
+msgid "Could not write pid file %s: %s\n"
+msgstr "Kon pid bestand %s niet schrijven: %s\n"
+
+#: src/process.c:352
 #, c-format
 msgid "tincd %s (%s %s) starting, debug level %d"
 msgstr "tincd %s (%s %s) start, debug niveau %d"
 
-#: src/process.c:379
+#: src/process.c:384
 #, c-format
 msgid "Executing script %s"
 msgstr "Uitvoeren script %s"
 
-#: src/process.c:402
+#: src/process.c:404
 #, c-format
 msgid "Script %s exited with non-zero status %d"
 msgstr "Script %s beëindigde met status %d"
 
-#: src/process.c:407
+#: src/process.c:409
 #, c-format
 msgid "Script %s was killed by signal %d (%s)"
 msgstr "Script %s was gestopt door signaal %d (%s)"
 
-#: src/process.c:411
+#: src/process.c:413
 #, c-format
 msgid "Script %s terminated abnormally"
 msgstr "Script %s abnormaal beëindigd"
 
-#: src/process.c:431 src/process.c:437 src/process.c:475 src/process.c:481
-#: src/process.c:499
+#: src/process.c:433 src/process.c:442 src/process.c:483 src/process.c:489
+#: src/process.c:507
 #, c-format
 msgid "Got %s signal"
 msgstr "Kreeg %s signaal"
 
-#: src/process.c:443
+#: src/process.c:451
 #, c-format
 msgid "Got another fatal signal %d (%s): not restarting."
 msgstr "Kreeg nog een fataal signaal %d (%s): geen herstart."
 
-#: src/process.c:452
+#: src/process.c:460
 #, c-format
 msgid "Got fatal signal %d (%s)"
 msgstr "Kreeg fataal signaal %d (%s)"
 
-#: src/process.c:456
+#: src/process.c:464
 msgid "Trying to re-execute in 5 seconds..."
 msgstr "Poging tot herstarten over 5 seconden..."
 
-#: src/process.c:484
+#: src/process.c:476
+msgid "Not restarting."
+msgstr "Geen herstart."
+
+#: src/process.c:492
 #, c-format
 msgid "Reverting to old debug level (%d)"
 msgstr "Herstellen van oud debug niveau (%d)"
 
-#: src/process.c:490
+#: src/process.c:498
 #, c-format
 msgid ""
 "Temporarily setting debug level to 5.  Kill me with SIGINT again to go back "
@@ -1097,58 +1161,89 @@ msgstr ""
 "Tijdelijk instellen debug niveau op 5. Zend nog een SIGINT signaal om niveau "
 "%d te herstellen."
 
-#: src/process.c:523
+#: src/process.c:531
 #, c-format
 msgid "Got unexpected signal %d (%s)"
 msgstr "Kreeg onverwacht signaal %d (%s)"
 
-#: src/process.c:529
+#: src/process.c:537
 #, c-format
 msgid "Ignored signal %d (%s)"
 msgstr "Signaal %d (%s) genegeerd"
 
-#: src/process.c:583
+#: src/process.c:591
 #, c-format
 msgid "Installing signal handler for signal %d (%s) failed: %s\n"
 msgstr "Installeren van signaal afhandelaar voor signaal %d (%s) faalde: %s\n"
 
-#: src/route.c:104
+#: src/route.c:127
 #, c-format
 msgid "Learned new MAC address %hx:%hx:%hx:%hx:%hx:%hx"
 msgstr "Nieuw MAC adres %hx:%hx:%hx:%hx:%hx:%hx geleerd"
 
-#: src/route.c:137
+#: src/route.c:165
+#, c-format
+msgid "Subnet %s expired"
+msgstr "Subnet %s is verlopen"
+
+#: src/route.c:200 src/route.c:353 src/route.c:495
+#, c-format
+msgid "Packet looping back to %s (%s)!"
+msgstr "Pakket komt terug naar %s (%s)!"
+
+#: src/route.c:299
+#, c-format
+msgid "Length of packet (%d) doesn't match length in IPv4 header (%d)"
+msgstr ""
+"Lengte van pakket (%d) komt niet overeen met lengte in IPv4 header (%d)"
+
+#: src/route.c:303
+#, c-format
+msgid "Fragmenting packet of %d bytes to %s (%s)"
+msgstr "Fragmentatie pakket van %d bytes naar %s (%s)"
+
+#: src/route.c:341
 #, c-format
-msgid "MAC address %hx:%hx:%hx:%hx:%hx:%hx expired"
-msgstr "MAC adres %hx:%hx:%hx:%hx:%hx:%hx verlopen"
+msgid ""
+"Cannot route packet from %s (%s): unknown IPv4 destination address %d.%d.%d.%"
+"d"
+msgstr ""
+"Kan pakket van %s (%s) niet routeren: onbekend IPv4 doeladres %d.%d.%d.%d"
 
-#: src/route.c:246
+#: src/route.c:366 src/route.c:505
 #, c-format
-msgid "Cannot route packet: unknown IPv4 destination address %d.%d.%d.%d"
-msgstr "Kan pakket niet routeren: onbekend IPv4 doeladres %d.%d.%d.%d"
+msgid "Packet for %s (%s) length %d larger than MTU %d"
+msgstr "Packet voor %s (%s) lengte %d groter dan MTU %d"
 
-#: src/route.c:337
+#: src/route.c:479
 #, c-format
 msgid ""
-"Cannot route packet: unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%"
-"hx:%hx:%hx"
+"Cannot route packet from %s (%s): unknown IPv6 destination address %hx:%hx:%"
+"hx:%hx:%hx:%hx:%hx:%hx"
+msgstr ""
+"Kan pakket van %s (%s) niet routeren: onbekend IPv6 doeladres %hx:%hx:%hx:%"
+"hx:%hx:%hx:%hx:%hx"
+
+#: src/route.c:537
+#, c-format
+msgid "Got neighbor solicitation request from %s (%s) while in router mode!"
 msgstr ""
-"Kan pakket niet routeren: onbekend IPv6 doeladres %hx:%hx:%hx:%hx:%hx:%hx:%"
-"hx:%hx"
+"Kreeg neighbor solicitation request van %s (%s) terwijl we in router mode "
+"werken!"
 
-#: src/route.c:389
+#: src/route.c:556
 msgid ""
 "Cannot route packet: received unknown type neighbor solicitation request"
 msgstr ""
 "Kan pakket niet routeren: ontvangst van onbekend type neighbor solicitation "
 "verzoek"
 
-#: src/route.c:406
+#: src/route.c:575
 msgid "Cannot route packet: checksum error for neighbor solicitation request"
 msgstr ""
 "Kan pakket niet routeren: checksum fout voor neighbor solicitation verzoek"
 
-#: src/route.c:415
+#: src/route.c:584
 #, c-format
 msgid ""
 "Cannot route packet: neighbor solicitation request for unknown address %hx:%"
@@ -1157,56 +1252,61 @@ msgstr ""
 "Kan pakket niet routeren: neighbor solicitation verzoek voor onbekend adres %"
 "hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"
 
-#: src/route.c:494
+#: src/route.c:671
+#, c-format
+msgid "Got ARP request from %s (%s) while in router mode!"
+msgstr "Kreeg ARP request van %s (%s) terwijl we in router mode werken!"
+
+#: src/route.c:688
 msgid "Cannot route packet: received unknown type ARP request"
 msgstr "Kan pakket niet routeren: ontvangst van onbekend type ARP verzoek"
 
-#: src/route.c:503
+#: src/route.c:697
 #, c-format
 msgid "Cannot route packet: ARP request for unknown address %d.%d.%d.%d"
 msgstr "Kan pakket niet routeren: ARP verzoek voor onbekend adres %d.%d.%d.%d"
 
-#: src/route.c:558
+#: src/route.c:753
 #, c-format
-msgid "Cannot route packet: unknown type %hx"
-msgstr "Kan pakket niet routeren: onbekend type %hx"
+msgid "Cannot route packet from %s (%s): unknown type %hx"
+msgstr "Kan pakket van %s (%s) niet routeren: onbekend type %hx"
 
-#: src/node.c:176
+#: src/node.c:183
 msgid "Nodes:"
 msgstr "Nodes:"
 
-#: src/node.c:180
+#: src/node.c:187
 #, c-format
 msgid ""
 " %s at %s cipher %d digest %d maclength %d compression %d options %lx status "
-"%04x nexthop %s via %s"
+"%04x nexthop %s via %s pmtu %d (min %d max %d)"
 msgstr ""
 " %s op %s cipher %d digest %d maclengte %d compressie %d opties %lx status %"
-"04x nexthop %s via %s"
+"04x nexthop %s via %s pmtu %d (min %d max %d)"
 
-#: src/node.c:187
+#: src/node.c:194
 msgid "End of nodes."
 msgstr "Einde van nodes."
 
-#: src/edge.c:147
+#: src/edge.c:148
 msgid "Edges:"
 msgstr "Edges:"
 
-#: src/edge.c:154
+#: src/edge.c:155
 #, c-format
 msgid " %s to %s at %s options %lx weight %d"
 msgstr " %s naar %s op %s opties %lx gewicht %d"
 
-#: src/edge.c:160
+#: src/edge.c:161
 msgid "End of edges."
 msgstr "Einde van edges."
 
-#: src/graph.c:253
+#: src/graph.c:263
 #, c-format
 msgid "Node %s (%s) became reachable"
 msgstr "Node %s (%s) werd bereikbaar"
 
-#: src/graph.c:256
+#: src/graph.c:266
 #, c-format
 msgid "Node %s (%s) became unreachable"
 msgstr "Node %s (%s) is niet meer bereikbaar"
@@ -1242,22 +1342,22 @@ msgstr "%s is een %s"
 
 #: src/linux/device.c:137 src/linux/device.c:148 src/linux/device.c:159
 #: src/freebsd/device.c:75 src/solaris/device.c:126 src/netbsd/device.c:78
-#: src/darwin/device.c:75 src/cygwin/device.c:249 src/mingw/device.c:113
-#: src/mingw/device.c:307 src/raw_socket/device.c:114
+#: src/darwin/device.c:75 src/cygwin/device.c:249 src/mingw/device.c:119
+#: src/mingw/device.c:319 src/raw_socket/device.c:114
 #, c-format
 msgid "Error while reading from %s %s: %s"
 msgstr "Fout tijdens lezen van %s %s: %s"
 
 #: src/linux/device.c:170 src/freebsd/device.c:84 src/solaris/device.c:138
 #: src/netbsd/device.c:90 src/darwin/device.c:87 src/cygwin/device.c:258
-#: src/mingw/device.c:316 src/raw_socket/device.c:123
+#: src/mingw/device.c:328 src/raw_socket/device.c:123
 #, c-format
 msgid "Read packet of %d bytes from %s"
 msgstr "Pakket van %d bytes gelezen van %s"
 
 #: src/linux/device.c:180 src/freebsd/device.c:94 src/solaris/device.c:148
 #: src/netbsd/device.c:100 src/darwin/device.c:97 src/cygwin/device.c:270
-#: src/mingw/device.c:329 src/raw_socket/device.c:133
+#: src/mingw/device.c:341 src/raw_socket/device.c:133
 #, c-format
 msgid "Writing packet of %d bytes to %s"
 msgstr "Pakket van %d bytes geschreven naar %s"
@@ -1271,21 +1371,21 @@ msgstr "Kan niet schrijven naar %s %s: %s"
 
 #: src/linux/device.c:219 src/freebsd/device.c:112 src/solaris/device.c:166
 #: src/netbsd/device.c:118 src/darwin/device.c:115 src/cygwin/device.c:287
-#: src/mingw/device.c:346 src/raw_socket/device.c:151
+#: src/mingw/device.c:358 src/raw_socket/device.c:151
 #, c-format
 msgid "Statistics for %s %s:"
 msgstr "Statistieken voor %s %s:"
 
 #: src/linux/device.c:220 src/freebsd/device.c:113 src/solaris/device.c:167
 #: src/netbsd/device.c:119 src/darwin/device.c:116 src/cygwin/device.c:288
-#: src/mingw/device.c:347 src/raw_socket/device.c:152
+#: src/mingw/device.c:359 src/raw_socket/device.c:152
 #, c-format
 msgid " total bytes in:  %10d"
 msgstr " totaal aantal bytes in:  %10d"
 
 #: src/linux/device.c:221 src/freebsd/device.c:114 src/solaris/device.c:168
 #: src/netbsd/device.c:120 src/darwin/device.c:117 src/cygwin/device.c:289
-#: src/mingw/device.c:348 src/raw_socket/device.c:153
+#: src/mingw/device.c:360 src/raw_socket/device.c:153
 #, c-format
 msgid " total bytes out: %10d"
 msgstr " totaal aantal bytes uit: %10d"
@@ -1295,7 +1395,7 @@ msgid "FreeBSD tap device"
 msgstr "FreeBSD tap apparaat"
 
 #: src/freebsd/device.c:98 src/darwin/device.c:101 src/cygwin/device.c:274
-#: src/mingw/device.c:333
+#: src/mingw/device.c:345
 #, c-format
 msgid "Error while writing to %s %s: %s"
 msgstr "Fout tijdens schrijven naar %s %s: %s"
@@ -1342,12 +1442,12 @@ msgstr "NetBSD tun apparaat"
 msgid "MacOS/X tun device"
 msgstr "MaxOS/X tun apparaat"
 
-#: src/cygwin/device.c:81 src/mingw/device.c:156
+#: src/cygwin/device.c:81 src/mingw/device.c:163
 #, c-format
 msgid "Unable to read registry: %s"
 msgstr "Kon registry niet lezen: %s"
 
-#: src/cygwin/device.c:133 src/mingw/device.c:207
+#: src/cygwin/device.c:133 src/mingw/device.c:214
 msgid "No Windows tap device found!"
 msgstr "Geen Windows tap apparaat gevonden!"
 
@@ -1356,7 +1456,7 @@ msgstr "Geen Windows tap apparaat gevonden!"
 msgid "Could not open Windows tap device %s (%s) for writing: %s"
 msgstr "Kon Windows tap apparaat %s (%s) niet openen om te schrijven: %s"
 
-#: src/cygwin/device.c:168 src/mingw/device.c:232
+#: src/cygwin/device.c:168 src/mingw/device.c:239
 #, c-format
 msgid "Could not get MAC address from Windows tap device %s (%s): %s"
 msgstr "Kon MAC adres niet achterhalen van Windows tap apparaat %s (%s): %s"
@@ -1374,20 +1474,20 @@ msgstr "Taplezer is geforked en draait."
 msgid "Tap reader failed!"
 msgstr "Taplezer faalde!"
 
-#: src/cygwin/device.c:224 src/mingw/device.c:286
+#: src/cygwin/device.c:224 src/mingw/device.c:298
 msgid "Windows tap device"
 msgstr "Windows tap apparaat"
 
-#: src/cygwin/device.c:226 src/mingw/device.c:288
+#: src/cygwin/device.c:226 src/mingw/device.c:300
 #, c-format
 msgid "%s (%s) is a %s"
 msgstr "%s (%s) is een %s"
 
-#: src/mingw/device.c:94
+#: src/mingw/device.c:100
 msgid "Tap reader running"
 msgstr "Taplezer draait"
 
-#: src/mingw/device.c:225
+#: src/mingw/device.c:232
 #, c-format
 msgid "%s (%s) is not a usable Windows tap device: %s"
 msgstr "%s (%s) is geen bruikbaar Windows tap apparaat: %s"
@@ -1405,3 +1505,12 @@ msgstr "Kan interface %s niet vinden: %s"
 #, c-format
 msgid "Could not bind to %s: %s"
 msgstr "Kon niet aan interface `%s' binden: %s"
+
+#~ msgid "Restarting in %d seconds!"
+#~ msgstr "Herstart in %d seconden!"
+
+#~ msgid "MAC address %hx:%hx:%hx:%hx:%hx:%hx expired"
+#~ msgstr "MAC adres %hx:%hx:%hx:%hx:%hx:%hx verlopen"
+
+#~ msgid "Read too short packet"
+#~ msgstr "Te kort pakket gelezen"
diff --git a/po/old/es.po b/po/old/es.po
new file mode 100644 (file)
index 0000000..30c01a6
--- /dev/null
@@ -0,0 +1,1223 @@
+# Spanish messages for tinc
+# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+# Ivo Timmermans <ivo@o2w.nl>, 1999, 2000.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: tinc 1.0pre3\n"
+"POT-Creation-Date: 2001-03-04 14:33+0100\n"
+"PO-Revision-Date: 2000-11-26 15:20+0000\n"
+"Last-Translator: Enrique Zanardi <ezanardi@id-agora.com>\n"
+"Language-Team: Spanish <debian-l10n-spanish@lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: src/conf.c:238
+#, fuzzy, c-format
+msgid "Cannot open config file %s: %m"
+msgstr "¡No puedo abrir el fichero de configuración de `host' para mí!"
+
+#: src/conf.c:279
+#, fuzzy, c-format
+msgid "Invalid variable name `%s' on line %d while reading config file %s"
+msgstr ""
+"Nombre de variable no válido en la linea %d del fichero de configuración %s"
+
+#: src/conf.c:286
+#, fuzzy, c-format
+msgid "No value for variable `%s' on line %d while reading config file %s"
+msgstr ""
+"No hay valor para la variable en la linea %d del fichero de configuración %s"
+
+#: src/conf.c:294
+#, fuzzy, c-format
+msgid "Invalid value for variable `%s' on line %d while reading config file %s"
+msgstr ""
+"Valor no válido para la variable en la linea %d del fichero de configuración "
+"%s"
+
+#: src/conf.c:323
+#, c-format
+msgid "Failed to read `%s': %m"
+msgstr ""
+
+#: src/conf.c:384
+#, c-format
+msgid "`%s' is not an absolute path"
+msgstr ""
+
+#: src/conf.c:400 src/conf.c:433
+#, fuzzy, c-format
+msgid "Couldn't stat `%s': %m"
+msgstr "No pude abrir %s: %m"
+
+#: src/conf.c:407 src/conf.c:443
+#, c-format
+msgid "`%s' is owned by UID %d instead of %d"
+msgstr ""
+
+#: src/conf.c:414 src/conf.c:450
+#, c-format
+msgid "Warning: `%s' is a symlink"
+msgstr ""
+
+#: src/conf.c:419 src/conf.c:455
+#, c-format
+msgid "Unable to read symbolic link `%s': %m"
+msgstr ""
+
+#. Accessible by others
+#: src/conf.c:466
+#, c-format
+msgid "`%s' has unsecure permissions"
+msgstr ""
+
+#. Ask for a file and/or directory name.
+#: src/conf.c:491
+#, c-format
+msgid "Please enter a file to save %s to [%s]: "
+msgstr ""
+
+#: src/conf.c:497
+#, fuzzy, c-format
+msgid "Error while reading stdin: %m\n"
+msgstr "Error leyendo del dispositivo tap: %m"
+
+#: src/conf.c:523
+#, fuzzy, c-format
+msgid "Error opening file `%s': %m\n"
+msgstr "Error buscando `%s': %m"
+
+#: src/conf.c:533
+#, c-format
+msgid ""
+"The file `%s' (or any of the leading directories) has unsafe permissions.\n"
+"I will not create or overwrite this file.\n"
+msgstr ""
+
+#: src/connection.c:191
+#, fuzzy
+msgid "Connection list:"
+msgstr "Conexión desde %s puerto %d"
+
+#: src/connection.c:193 src/connection.c:200
+#, c-format
+msgid " %s at %s port %hd options %ld sockets %d, %d status %04x"
+msgstr ""
+
+#: src/connection.c:205
+#, fuzzy
+msgid "End of connection list."
+msgstr "Intentando conectar con %s"
+
+#: src/meta.c:53
+#, fuzzy, c-format
+msgid "Sending %d bytes of metadata to %s (%s): %s"
+msgstr "Enviando paquete de %d bytes a %s (%s)"
+
+#: src/meta.c:69
+#, fuzzy, c-format
+msgid "Sending meta data to %s (%s) failed: %m"
+msgstr "Error enviando paquete a %s (%s): %m"
+
+#: src/meta.c:100
+#, c-format
+msgid "This is a bug: %s:%d: %d:%m %s (%s)"
+msgstr "Esto es un `bug': %s:%d: %d:%m %s (%s)"
+
+#: src/meta.c:106
+#, fuzzy, c-format
+msgid "Metadata socket error for %s (%s): %s"
+msgstr "Error en el `socket' de datos salientes para %s (%s): %s"
+
+#: src/meta.c:123 src/protocol.c:1300
+#, fuzzy, c-format
+msgid "Connection closed by %s (%s)"
+msgstr "Cerrando conexión con %s (%s)"
+
+#: src/meta.c:130
+#, fuzzy, c-format
+msgid "Metadata socket read error for %s (%s): %m"
+msgstr "Error en el `socket' de datos salientes para %s (%s): %s"
+
+#: src/meta.c:161
+#, fuzzy, c-format
+msgid "Got request from %s (%s): %s"
+msgstr "Petición desconocida desde %s (%s)"
+
+#: src/meta.c:179
+#, fuzzy, c-format
+msgid "Metadata read buffer overflow for %s (%s)"
+msgstr "Desbordamiento del bufer de salida mientras enviaba %s a %s (%s)"
+
+#: src/net.c:119
+#, c-format
+msgid "No valid key known yet for %s (%s), queueing packet"
+msgstr ""
+"No conozco ninguna clave válida para %s (%s) aún, pongo el paquete en cola"
+
+#: src/net.c:152
+#, c-format
+msgid "Error sending packet to %s (%s): %m"
+msgstr "Error enviando paquete a %s (%s): %m"
+
+#: src/net.c:163
+#, fuzzy, c-format
+msgid "Received packet of %d bytes from %s (%s)"
+msgstr "Enviando paquete de %d bytes a %s (%s)"
+
+#: src/net.c:192
+#, fuzzy, c-format
+msgid "Writing packet of %d bytes to tap device"
+msgstr "Enviando paquete de %d bytes a %s (%s)"
+
+#: src/net.c:198
+#, fuzzy, c-format
+msgid "Can't write to tun/tap device: %m"
+msgstr "No puedo escribir en el dispositivo tap: %m"
+
+#: src/net.c:205
+#, fuzzy, c-format
+msgid "Can't write to ethertap device: %m"
+msgstr "No puedo escribir en el dispositivo tap: %m"
+
+#: src/net.c:219
+#, c-format
+msgid "Sending packet of %d bytes to %s (%s)"
+msgstr "Enviando paquete de %d bytes a %s (%s)"
+
+#: src/net.c:226
+msgid "Packet is looping back to us!"
+msgstr ""
+
+#: src/net.c:235
+#, fuzzy, c-format
+msgid "%s (%s) is not active, dropping packet"
+msgstr "%s (%s) no está listo, poniendo el paquete en cola"
+
+#: src/net.c:257
+#, fuzzy, c-format
+msgid "Flushing queue for %s (%s)"
+msgstr "Vaciando la cola de envíos para %s (%s)"
+
+#: src/net.c:304
+#, c-format
+msgid "Could not open %s: %m"
+msgstr "No pude abrir %s: %m"
+
+#: src/net.c:333
+#, c-format
+msgid "%s is a new style tun/tap device"
+msgstr "%s es un dispositivo tun/tap del nuevo estilo"
+
+#: src/net.c:358
+#, c-format
+msgid "Creating metasocket failed: %m"
+msgstr "Fallo al crear el metasocket: %m"
+
+#: src/net.c:366 src/net.c:410 src/net.c:441 src/net.c:496 src/net.c:982
+#: src/process.c:239 src/process.c:275
+#, c-format
+msgid "System call `%s' failed: %m"
+msgstr ""
+
+#: src/net.c:386
+#, c-format
+msgid "Unable to bind listen socket to interface %s: %m"
+msgstr "No puedo enlazar (bind) el `socket' de escucha a la interfaz %s: %m"
+
+#: src/net.c:403
+#, c-format
+msgid "Can't bind to port %hd/tcp: %m"
+msgstr "No puedo enlazar (bind) al puerto %hd/tcp: %m"
+
+#: src/net.c:431
+#, c-format
+msgid "Creating socket failed: %m"
+msgstr "Error al crear el `socket': %m"
+
+#: src/net.c:454
+#, c-format
+msgid "Can't bind to port %hd/udp: %m"
+msgstr "No puedo enlazar (bind) al puerto %hd/udp: %m"
+
+#: src/net.c:472
+#, c-format
+msgid "Trying to connect to %s"
+msgstr "Intentando conectar con %s"
+
+#: src/net.c:482
+#, c-format
+msgid "Creating socket for %s port %d failed: %m"
+msgstr "Error al crear el `socket' para %s puerto %d: %m"
+
+#: src/net.c:518
+#, c-format
+msgid "%s port %hd: %m"
+msgstr "%s puerto %hd: %m"
+
+#: src/net.c:526
+#, c-format
+msgid "fcntl for %s port %d: %m"
+msgstr "fcntl() para %s puerto %d: %m"
+
+#: src/net.c:532
+#, c-format
+msgid "Connected to %s port %hd"
+msgstr "Conectado a %s puerto %hd"
+
+#: src/net.c:551
+msgid "Invalid name for outgoing connection"
+msgstr "Nombre no válido para conexión saliente"
+
+#: src/net.c:560
+#, c-format
+msgid "Error reading host configuration file for %s"
+msgstr "Error leyendo el fichero de configuración del `host' para %s"
+
+#: src/net.c:567
+#, c-format
+msgid "No address specified for %s"
+msgstr "No se especificó dirección para %s"
+
+#: src/net.c:574
+#, c-format
+msgid "Error looking up `%s': %m"
+msgstr "Error buscando `%s': %m"
+
+#: src/net.c:584
+#, c-format
+msgid "Could not set up a meta connection to %s"
+msgstr "No he podido configurar una meta conexión a %s"
+
+#: src/net.c:629
+#, fuzzy, c-format
+msgid "Error reading RSA public key file `%s': %m"
+msgstr "Error enviando paquete a %s (%s): %m"
+
+#: src/net.c:637
+#, fuzzy, c-format
+msgid "Reading RSA public key file `%s' failed: %m"
+msgstr "Error recibiendo paquete: %m"
+
+#. Nothing worked.
+#: src/net.c:663
+#, c-format
+msgid "No public key for %s specified!"
+msgstr ""
+
+#: src/net.c:686
+#, fuzzy, c-format
+msgid "Error reading RSA private key file `%s': %m"
+msgstr "Error enviando paquete a %s (%s): %m"
+
+#: src/net.c:694
+#, c-format
+msgid "Reading RSA private key file `%s' failed: %m"
+msgstr ""
+
+#: src/net.c:701
+#, fuzzy
+msgid "No private key for tinc daemon specified!"
+msgstr "¡Se requiere un nombre para el demonio tinc!"
+
+#: src/net.c:725
+msgid "Name for tinc daemon required!"
+msgstr "¡Se requiere un nombre para el demonio tinc!"
+
+#: src/net.c:733
+msgid "Invalid name for myself!"
+msgstr "¡Nombre no válido para mí!"
+
+#: src/net.c:742
+msgid "Cannot open host configuration file for myself!"
+msgstr "¡No puedo abrir el fichero de configuración de `host' para mí!"
+
+#: src/net.c:783
+msgid "Network address and subnet mask do not match!"
+msgstr ""
+
+#: src/net.c:792
+#, fuzzy
+msgid "Unable to set up a listening TCP socket!"
+msgstr "¡No puedo configurar un `socket' a la escucha!"
+
+#: src/net.c:798
+#, fuzzy
+msgid "Unable to set up a listening UDP socket!"
+msgstr "¡No puedo configurar un `socket' a la escucha!"
+
+#: src/net.c:839
+#, c-format
+msgid "Ready: listening on port %hd"
+msgstr "Listo: escuchando en el puerto %hd"
+
+#: src/net.c:871
+#, c-format
+msgid "Still failed to connect to other, will retry in %d seconds"
+msgstr "Sigo sin poder conectar con el otro, lo reintentaré en %d segundos."
+
+#: src/net.c:924
+#, c-format
+msgid "Trying to re-establish outgoing connection in %d seconds"
+msgstr "Intento re-establecer la conexión saliente en %d segundos"
+
+#: src/net.c:999
+#, c-format
+msgid "Connection from %s port %d"
+msgstr "Conexión desde %s puerto %d"
+
+#: src/net.c:1047
+#, c-format
+msgid "This is a bug: %s:%d: %d:%m"
+msgstr "Esto es un `bug': %s:%d: %d:%m"
+
+#: src/net.c:1053
+#, c-format
+msgid "Incoming data socket error: %s"
+msgstr "Error en el `socket' de recepción de datos: %s"
+
+#: src/net.c:1059
+#, c-format
+msgid "Receiving packet failed: %m"
+msgstr "Error recibiendo paquete: %m"
+
+#: src/net.c:1067
+#, c-format
+msgid "Received UDP packets on port %hd from unknown source %x:%hd"
+msgstr ""
+
+#: src/net.c:1089
+#, c-format
+msgid "Closing connection with %s (%s)"
+msgstr "Cerrando conexión con %s (%s)"
+
+#: src/net.c:1140
+msgid "Trying to re-establish outgoing connection in 5 seconds"
+msgstr "Intento re-establecer la conexión saliente en 5 segundos."
+
+#: src/net.c:1175
+#, c-format
+msgid "%s (%s) didn't respond to PING"
+msgstr "%s (%s) no respondió al PING"
+
+#: src/net.c:1202
+#, c-format
+msgid "Accepting a new connection failed: %m"
+msgstr "Error al aceptar una nueva conexión: %m"
+
+#: src/net.c:1210
+msgid "Closed attempted connection"
+msgstr "Se ha cerrado la conexión que se intentaba realizar."
+
+#: src/net.c:1267
+#, fuzzy, c-format
+msgid "Error while reading from tun/tap device: %m"
+msgstr "Error leyendo del dispositivo tap: %m"
+
+#: src/net.c:1276
+#, fuzzy, c-format
+msgid "Error while reading from ethertap device: %m"
+msgstr "Error leyendo del dispositivo tap: %m"
+
+#: src/net.c:1287
+msgid "Received short packet from tap device"
+msgstr ""
+
+#: src/net.c:1293
+#, c-format
+msgid "Read packet of length %d from tap device"
+msgstr ""
+
+#: src/net.c:1325
+#, c-format
+msgid "Error while waiting for input: %m"
+msgstr "Error esperando entrada: %m"
+
+#: src/net.c:1332
+#, fuzzy
+msgid "Rereading configuration file and restarting in 5 seconds"
+msgstr "Recibí la señal HUP, voy a releer la configuración y reiniciaré."
+
+#: src/net.c:1339
+#, fuzzy
+msgid "Unable to reread configuration file, exiting"
+msgstr "Recibí la señal HUP, voy a releer la configuración y reiniciaré."
+
+#: src/net.c:1365
+#, fuzzy
+msgid "Regenerating symmetric key"
+msgstr "Generando claves de %d bits"
+
+#: src/netutl.c:95
+#, c-format
+msgid "Error looking up `%s': %s\n"
+msgstr "Error buscando `%s': %s\n"
+
+#: src/protocol.c:103
+#, c-format
+msgid "Output buffer overflow while sending %s to %s (%s)"
+msgstr "Desbordamiento del bufer de salida mientras enviaba %s a %s (%s)"
+
+#: src/protocol.c:110
+#, c-format
+msgid "Sending %s to %s (%s)"
+msgstr "Enviando %s a %s (%s)"
+
+#: src/protocol.c:124
+#, c-format
+msgid "Unknown request from %s (%s)"
+msgstr "Petición desconocida desde %s (%s)"
+
+#: src/protocol.c:131
+#, c-format
+msgid "Got %s from %s (%s)"
+msgstr "He recibido %s desde %s (%s)"
+
+#: src/protocol.c:137
+#, fuzzy, c-format
+msgid "Unauthorized request from %s (%s)"
+msgstr "Petición desconocida desde %s (%s)"
+
+#: src/protocol.c:144
+#, c-format
+msgid "Error while processing %s from %s (%s)"
+msgstr "Error al procesar %s desde %s (%s)"
+
+#: src/protocol.c:151
+#, c-format
+msgid "Bogus data received from %s (%s)"
+msgstr "Se han recibido datos sin sentido desde %s (%s)."
+
+#: src/protocol.c:203
+#, c-format
+msgid "Got bad ID from %s"
+msgstr "Recibí una ID incorrecta desde %s"
+
+#: src/protocol.c:211
+#, c-format
+msgid "Peer %s (%s) uses incompatible version %d"
+msgstr "La máquina remota %s (%s) usa una versión (%d) incompatible."
+
+#: src/protocol.c:220
+#, c-format
+msgid "Peer %s uses invalid identity name"
+msgstr "La máquina remota %s usa un nombre de identidad no válido"
+
+#: src/protocol.c:232
+#, c-format
+msgid "Peer %s had unknown identity (%s)"
+msgstr "La máquina remota %s tiene una identidad desconocida (%s)"
+
+#: src/protocol.c:246
+#, c-format
+msgid "Uplink %s (%s) is already in our connection list"
+msgstr "El enlace %s (%s) ya está en nuestra lista de conexiones."
+
+#: src/protocol.c:289
+#, c-format
+msgid "Removing old entry for %s at %s in favour of new connection from %s"
+msgstr ""
+"Eliminando el registro viejo para %s en %s en favor de la nueva conexión "
+"desde %s"
+
+#: src/protocol.c:304
+#, c-format
+msgid "Connection with %s (%s) activated"
+msgstr "Activada la conexión con %s (%s)."
+
+#: src/protocol.c:400
+#, c-format
+msgid "Got bad CHALLENGE from %s (%s)"
+msgstr "Recibí CHALLENGE incorrecta desde %s (%s)"
+
+#: src/protocol.c:410
+#, c-format
+msgid "Intruder: wrong challenge length from %s (%s)"
+msgstr "Intruso: longitud de desafío incorrecta desde %s (%s)"
+
+#: src/protocol.c:436
+#, c-format
+msgid "Trying to send CHAL_REPLY to %s (%s) without a valid CHALLENGE"
+msgstr "Intento enviar CHAL_REPLY a %s (%s) sin un CHALLENGE válido"
+
+#: src/protocol.c:462
+#, c-format
+msgid "Got bad CHAL_REPLY from %s (%s)"
+msgstr "Recibí CHAL_REPLY incorrecta desde %s (%s)"
+
+#: src/protocol.c:470
+#, c-format
+msgid "Intruder: wrong challenge reply length from %s (%s)"
+msgstr "Intruso: longitud de respuesta de desafío incorrecta desde %s (%s)"
+
+#: src/protocol.c:486
+#, c-format
+msgid "Intruder: wrong challenge reply from %s (%s)"
+msgstr "Intruso: respuesta de desafío incorrecta desde %s (%s)"
+
+#: src/protocol.c:491
+#, c-format
+msgid "Expected challenge reply: %s"
+msgstr ""
+
+#: src/protocol.c:540
+#, c-format
+msgid "Generated random meta key (unencrypted): %s"
+msgstr ""
+
+#: src/protocol.c:552 src/protocol.c:615
+#, fuzzy, c-format
+msgid "Error during encryption of meta key for %s (%s)"
+msgstr "Error enviando paquete a %s (%s): %m"
+
+#: src/protocol.c:585
+#, fuzzy, c-format
+msgid "Got bad METAKEY from %s (%s)"
+msgstr "Recibí REQ_KEY incorrecta desde %s (%s)"
+
+#: src/protocol.c:595
+#, fuzzy, c-format
+msgid "Intruder: wrong meta key length from %s (%s)"
+msgstr "Intruso: longitud de desafío incorrecta desde %s (%s)"
+
+#: src/protocol.c:623
+#, c-format
+msgid "Received random meta key (unencrypted): %s"
+msgstr ""
+
+#: src/protocol.c:669
+#, c-format
+msgid "Got bad ADD_SUBNET from %s (%s)"
+msgstr "Recibí ADD_SUBNET incorrecta desde %s (%s)"
+
+#: src/protocol.c:677
+#, c-format
+msgid "Got bad ADD_SUBNET from %s (%s): invalid identity name"
+msgstr ""
+"Recibí ADD_SUBNET incorrecta desde %s (%s): nombre de identidad no válido"
+
+#: src/protocol.c:685
+#, c-format
+msgid "Got bad ADD_SUBNET from %s (%s): invalid subnet string"
+msgstr "Recibí ADD_SUBNET incorrecta desde %s (%s): cadena de subred no válida"
+
+#: src/protocol.c:693
+#, c-format
+msgid "Warning: got ADD_SUBNET from %s (%s) for ourself, restarting"
+msgstr ""
+"Aviso: recibí ADD_SUBNET desde %s (%s) para nosotros mismos, reiniciando"
+
+#: src/protocol.c:703
+#, c-format
+msgid "Got ADD_SUBNET for %s from %s (%s) which is not in our connection list"
+msgstr ""
+"Recibí ADD_SUBNET para %s desde %s (%s) que no está en nuestra lista de "
+"conexiones"
+
+#: src/protocol.c:751
+#, c-format
+msgid "Got bad DEL_SUBNET from %s (%s)"
+msgstr "Recibí DEL_SUBNET incorrecta desde %s (%s)"
+
+#: src/protocol.c:759
+#, c-format
+msgid "Got bad DEL_SUBNET from %s (%s): invalid identity name"
+msgstr ""
+"Recibí DEL_SUBNET incorrecta desde %s (%s): nombre de identidad no válido"
+
+#: src/protocol.c:767
+#, c-format
+msgid "Got bad DEL_SUBNET from %s (%s): invalid subnet string"
+msgstr "Recibí DEL_SUBNET incorrecta desde %s (%s): cadena de subred no válida"
+
+#: src/protocol.c:777
+#, c-format
+msgid "Warning: got DEL_SUBNET from %s (%s) for ourself, restarting"
+msgstr ""
+"Aviso: recibí DEL_SUBNET desde %s (%s) para nosotros mismos, reiniciando"
+
+#: src/protocol.c:787
+#, c-format
+msgid "Got DEL_SUBNET for %s from %s (%s) which is not in our connection list"
+msgstr ""
+"Recibí DEL_SUBNET para %s desde %s (%s) que no está en nuestra lista de "
+"conexiones"
+
+#: src/protocol.c:830
+#, c-format
+msgid "Got bad ADD_HOST from %s (%s)"
+msgstr "Recibí ADD_HOST incorrecta desde %s (%s)"
+
+#: src/protocol.c:838
+#, c-format
+msgid "Got bad ADD_HOST from %s (%s): invalid identity name"
+msgstr ""
+"Recibí ADD_HOST incorrecta desde %s (%s): nombre de identidad no válido"
+
+#: src/protocol.c:847
+#, c-format
+msgid "Warning: got ADD_HOST from %s (%s) for ourself, restarting"
+msgstr "Aviso: recibí ADD_HOST desde %s (%s) para nosotros mismos, reiniciando"
+
+#: src/protocol.c:864
+#, c-format
+msgid "Got duplicate ADD_HOST for %s (%s) from %s (%s)"
+msgstr "Recibí un ADD_HOST duplicado desde %s (%s) para %s (%s)"
+
+#: src/protocol.c:872
+#, fuzzy, c-format
+msgid "Removing old entry for %s (%s) in favour of new connection"
+msgstr ""
+"Eliminando el registro viejo para %s en %s en favor de la nueva conexión "
+"desde %s"
+
+#: src/protocol.c:925
+#, c-format
+msgid "Got bad DEL_HOST from %s (%s)"
+msgstr "Recibí DEL_HOST incorrecta desde %s (%s)"
+
+#: src/protocol.c:934
+#, c-format
+msgid "Got bad DEL_HOST from %s (%s): invalid identity name"
+msgstr ""
+"Recibí DEL_HOST incorrecta desde %s (%s): nombre de identidad no válido"
+
+#: src/protocol.c:942
+#, c-format
+msgid "Warning: got DEL_HOST from %s (%s) for ourself, restarting"
+msgstr "Aviso: recibí DEL_HOST desde %s (%s) para nosotros mismos, reiniciando"
+
+#: src/protocol.c:952
+#, c-format
+msgid "Got DEL_HOST from %s (%s) for %s which is not in our connection list"
+msgstr ""
+"Recibí DEL_HOST desde %s (%s) para %s que no está en nuestra lista de "
+"conexiones"
+
+#: src/protocol.c:961
+#, c-format
+msgid "Got DEL_HOST from %s (%s) for %s which doesn't match"
+msgstr "Recibí DEL_HOST desde %s (%s) para %s que no concuerda"
+
+#: src/protocol.c:1000
+#, c-format
+msgid "Got bad STATUS from %s (%s)"
+msgstr "Recibí STATUS incorrecta desde %s (%s)"
+
+#: src/protocol.c:1007
+#, c-format
+msgid "Status message from %s (%s): %s: %s"
+msgstr "Mensaje de status desde %s (%s): %s: %s"
+
+#: src/protocol.c:1030
+#, c-format
+msgid "Got bad ERROR from %s (%s)"
+msgstr "Recibí ERROR incorrecta desde %s (%s)"
+
+#: src/protocol.c:1037
+#, c-format
+msgid "Error message from %s (%s): %s: %s"
+msgstr "Mensaje de error desde %s (%s): %s: %s"
+
+#: src/protocol.c:1114
+#, c-format
+msgid "Got bad KEY_CHANGED from %s (%s)"
+msgstr "Recibí KEY_CHANGED incorrecto desde %s (%s)"
+
+#: src/protocol.c:1121
+#, c-format
+msgid ""
+"Got KEY_CHANGED from %s (%s) origin %s which does not exist in our "
+"connection list"
+msgstr ""
+"Recibí KEY_CHANGED desde %s (%s) origen %s que no está en nuestra lista de "
+"conexiones"
+
+#: src/protocol.c:1150
+#, c-format
+msgid "Got bad REQ_KEY from %s (%s)"
+msgstr "Recibí REQ_KEY incorrecta desde %s (%s)"
+
+#: src/protocol.c:1157
+#, c-format
+msgid ""
+"Got REQ_KEY from %s (%s) origin %s which does not exist in our connection "
+"list"
+msgstr ""
+"Recibí REQ_KEY desde %s (%s) origen %s que no está en nuestra lista de "
+"conexiones"
+
+#: src/protocol.c:1174
+#, c-format
+msgid ""
+"Got REQ_KEY from %s (%s) destination %s which does not exist in our "
+"connection list"
+msgstr ""
+"Recibí REQ_KEY desde %s (%s) destino %s que no está en nuestra lista de "
+"conexiones"
+
+#: src/protocol.c:1210
+#, c-format
+msgid "Got bad ANS_KEY from %s (%s)"
+msgstr "Recibí ANS_KEY incorrecta desde %s (%s)"
+
+#: src/protocol.c:1217
+#, c-format
+msgid ""
+"Got ANS_KEY from %s (%s) origin %s which does not exist in our connection "
+"list"
+msgstr ""
+"Recibí ANS_KEY desde %s (%s) origen %s que no está en nuestra lista de "
+"conexiones"
+
+#: src/protocol.c:1228
+#, fuzzy, c-format
+msgid "Got bad ANS_KEY from %s (%s) origin %s: invalid key length"
+msgstr "Recibí ANS_KEY incorrecta desde %s (%s) origen %s: clave no válida"
+
+#: src/protocol.c:1239
+#, c-format
+msgid ""
+"Got ANS_KEY from %s (%s) destination %s which does not exist in our "
+"connection list"
+msgstr ""
+"Recibí ANS_KEY desde %s (%s) destino %s que no está en nuestra lista de "
+"conexiones"
+
+#: src/protocol.c:1284
+#, fuzzy, c-format
+msgid "Got bad PACKET from %s (%s)"
+msgstr "Recibí REQ_KEY incorrecta desde %s (%s)"
+
+#: src/protocol.c:1305
+#, fuzzy, c-format
+msgid "Error during reception of PACKET from %s (%s): %m"
+msgstr "Error enviando paquete a %s (%s): %m"
+
+#: src/subnet.c:108
+#, c-format
+msgid "subnet_compare() was called with unknown subnet type %d, restarting!"
+msgstr ""
+
+#. Do some intl stuff right now
+#: src/subnet.c:251 src/tincd.c:310
+msgid "unknown"
+msgstr "desconocido"
+
+#: src/subnet.c:314
+msgid "Subnet list:"
+msgstr ""
+
+#: src/subnet.c:322
+msgid "End of subnet list."
+msgstr ""
+
+#: src/tincd.c:116
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Pruebe `%s --help' para más información.\n"
+
+#: src/tincd.c:119
+#, c-format
+msgid ""
+"Usage: %s [option]...\n"
+"\n"
+msgstr ""
+"Modo de empleo: %s [opción]...\n"
+"\n"
+
+#: src/tincd.c:120
+#, fuzzy
+msgid ""
+"  -c, --config=DIR           Read configuration options from DIR.\n"
+"  -D, --no-detach            Don't fork and detach.\n"
+"  -d                         Increase debug level.\n"
+"  -k, --kill                 Attempt to kill a running tincd and exit.\n"
+"  -n, --net=NETNAME          Connect to net NETNAME.\n"
+msgstr ""
+"  -c, --config=DIR      Lee opciones de configuración del directorio DIR.\n"
+"  -D, --no-detach       No hagas fork() y liberes la terminal.\n"
+"  -d                    Aumenta el nivel de depuración.\n"
+"  -k, --kill            Intenta eliminar un tincd en ejecución y termina.\n"
+"  -n, --net=NOMBREDERED Conecta a la red NOMBREDERED.\n"
+"  -t, --timeout=TIMEOUT Segundos a esperar antes de dar un timeout.\n"
+
+#: src/tincd.c:125
+#, fuzzy
+msgid ""
+"  -K, --generate-keys[=BITS] Generate public/private RSA keypair.\n"
+"      --help                 Display this help and exit.\n"
+"      --version              Output version information and exit.\n"
+"\n"
+msgstr ""
+"      --help            Muestra esta ayuda y termina.\n"
+"      --version         Muestra información de la versión y termina.\n"
+"\n"
+
+#: src/tincd.c:128
+msgid "Report bugs to tinc@nl.linux.org.\n"
+msgstr "Comunicar `bugs' a tinc@nl.linux.org.\n"
+
+#: src/tincd.c:171
+#, c-format
+msgid ""
+"Invalid argument `%s'; BITS must be a number equal to or greater than 512.\n"
+msgstr ""
+
+#: src/tincd.c:232
+#, c-format
+msgid "Generating %d bits keys:\n"
+msgstr "Generando claves de %d bits:\n"
+
+#: src/tincd.c:237
+msgid "Error during key generation!"
+msgstr ""
+
+#: src/tincd.c:241
+msgid "Done.\n"
+msgstr "Hecho.\n"
+
+#: src/tincd.c:248
+#, fuzzy
+msgid "public RSA key"
+msgstr "Clave pública: %s\n"
+
+#: src/tincd.c:252 src/tincd.c:263
+msgid ""
+"Appending key to existing contents.\n"
+"Make sure only one key is stored in the file.\n"
+msgstr ""
+
+#: src/tincd.c:259
+#, fuzzy
+msgid "private RSA key"
+msgstr "Clave privada: %s\n"
+
+#: src/tincd.c:284
+msgid "Both netname and configuration directory given, using the latter..."
+msgstr ""
+
+#: src/tincd.c:317
+#, c-format
+msgid "%s version %s (built %s %s, protocol %d)\n"
+msgstr "%s versión %s (compilado %s %s, protocolo %d)\n"
+
+#: src/tincd.c:318
+#, fuzzy
+msgid ""
+"Copyright (C) 1998-2001 Ivo Timmermans, Guus Sliepen and others.\n"
+"See the AUTHORS file for a complete list.\n"
+"\n"
+"tinc comes with ABSOLUTELY NO WARRANTY.  This is free software,\n"
+"and you are welcome to redistribute it under certain conditions;\n"
+"see the file COPYING for details.\n"
+msgstr ""
+"Copyright (C) 1998,1999,2000 Ivo Timmermans, Guus Sliepen y otros,\n"
+"vea el fichero AUTHORS para una lista completa.\n"
+"\n"
+"tinc viene SIN NINGUNA GARANTÍA.  Esto es software libre,\n"
+"y puede ser redistribuido bajo ciertas condiciones;\n"
+"vea el fichero COPYING para los detalles.\n"
+
+#: src/tincd.c:332
+#, fuzzy
+msgid "You must be root to run this program.\n"
+msgstr ""
+"Usted debe ser el superusuario para ejecutar este programa. Lo siento.\n"
+
+#: src/tincd.c:372
+msgid "Unrecoverable error"
+msgstr "Error irrecuperable"
+
+#: src/tincd.c:377
+#, c-format
+msgid "Restarting in %d seconds!"
+msgstr "¡Reiniciando en %d segundos!"
+
+#: src/process.c:338 src/tincd.c:382
+#, fuzzy
+msgid "Not restarting."
+msgstr "¡Aayyy! No reinicio."
+
+#: src/process.c:60
+#, fuzzy, c-format
+msgid "Memory exhausted (couldn't allocate %d bytes), exiting."
+msgstr ""
+"Memoria agotada (la última es %s:%d) (no pude asignar %d bytes), terminando."
+
+#: src/process.c:88
+#, c-format
+msgid "Total bytes written: tap %d, socket %d; bytes read: tap %d, socket %d"
+msgstr ""
+"Total de bytes escritos: tap %d, socket %d; bytes leidos: tap %d, socket %d."
+
+#: src/process.c:91
+msgid "Terminating"
+msgstr "Terminando"
+
+#: src/process.c:107
+#, c-format
+msgid "A tincd is already running for net `%s' with pid %d.\n"
+msgstr ""
+"Un tincd está actualmente en ejecución para la red `%s' con el pid %d.\n"
+
+#: src/process.c:110
+#, c-format
+msgid "A tincd is already running with pid %d.\n"
+msgstr "Un tincd está actualmente en ejecución con el pid %d.\n"
+
+#: src/process.c:131
+#, c-format
+msgid "No other tincd is running for net `%s'.\n"
+msgstr "No hay ningún otro tincd en ejecución para la red `%s'.\n"
+
+#: src/process.c:133
+msgid "No other tincd is running.\n"
+msgstr "No hay ningún otro tincd en ejecución.\n"
+
+#: src/process.c:140
+msgid "Removing stale lock file.\n"
+msgstr "Borrando fichero de bloqueo en desuso.\n"
+
+#: src/process.c:167
+#, c-format
+msgid "Couldn't detach from terminal: %m"
+msgstr ""
+
+#: src/process.c:180
+#, c-format
+msgid "tincd %s (%s %s) starting, debug level %d"
+msgstr "tincd %s (%s %s) comenzando, nivel de depuración %d."
+
+#: src/process.c:183
+#, c-format
+msgid "tincd %s starting"
+msgstr "tincd %s comenzando"
+
+#: src/process.c:247
+#, c-format
+msgid "Executing script %s"
+msgstr ""
+
+#: src/process.c:255
+#, c-format
+msgid "Process %d (%s) exited with non-zero status %d"
+msgstr ""
+
+#: src/process.c:263
+#, c-format
+msgid "Process %d (%s) was killed by signal %d (%s)"
+msgstr ""
+
+#: src/process.c:269
+#, c-format
+msgid "Process %d (%s) terminated abnormally"
+msgstr ""
+
+#: src/process.c:294
+msgid "Got TERM signal"
+msgstr "Recibí la señal TERM"
+
+#: src/process.c:303
+msgid "Got QUIT signal"
+msgstr "Recibí la señal QUIT"
+
+#: src/process.c:310
+msgid "Got another SEGV signal: not restarting"
+msgstr "Recibí otra señal SEGV: no reinicio"
+
+#: src/process.c:319
+msgid "Got SEGV signal"
+msgstr "Recibí la señal SEGV"
+
+#: src/process.c:324
+msgid "Trying to re-execute in 5 seconds..."
+msgstr "Intento re-ejecutar en 5 segundos."
+
+#: src/process.c:347
+#, fuzzy
+msgid "Got HUP signal"
+msgstr "Recibí la señal QUIT"
+
+#: src/process.c:355
+msgid "Got INT signal, exiting"
+msgstr "Recibí la señal INT, saliendo"
+
+#: src/process.c:374
+#, c-format
+msgid "Got unexpected signal %d (%s)"
+msgstr "Recibí una señal inesperada %d (%s)."
+
+#: src/process.c:419
+#, c-format
+msgid "Installing signal handler for signal %d (%s) failed: %m\n"
+msgstr ""
+
+#: src/route.c:56
+#, c-format
+msgid "Learned new MAC address %x:%x:%x:%x:%x:%x from %s (%s)"
+msgstr ""
+
+#: src/route.c:84
+#, c-format
+msgid "Cannot route packet: unknown destination address %x:%x:%x:%x:%x:%x"
+msgstr ""
+
+#: src/route.c:111
+#, c-format
+msgid "Cannot route packet: unknown destination address %d.%d.%d.%d"
+msgstr ""
+
+#: src/route.c:126
+msgid "Cannot route packet: IPv6 routing not yet implemented"
+msgstr ""
+
+#: src/route.c:155
+#, c-format
+msgid "Cannot route packet: unknown type %hx"
+msgstr ""
+
+#, fuzzy
+#~ msgid "Got packet of %d bytes from %s (%s)"
+#~ msgstr "Enviando paquete de %d bytes a %s (%s)"
+
+#~ msgid "Trying to look up %d.%d.%d.%d in connection list failed!"
+#~ msgstr "¡Error intentando buscar %d.%d.%d.%d en la lista de conexiones!"
+
+#~ msgid "Opening UDP socket to %s"
+#~ msgstr "Abriendo `socket' UDP a %s"
+
+#~ msgid "Creating UDP socket failed: %m"
+#~ msgstr "Error al crear el `socket' UDP: %m"
+
+#~ msgid "Connecting to %s port %d failed: %m"
+#~ msgstr "Error al conectar a %s puerto %d: %m"
+
+#, fuzzy
+#~ msgid "Error during encryption of challenge for %s (%s)"
+#~ msgstr "Error leyendo el fichero de configuración del `host' para %s"
+
+#~ msgid "Queue flushed"
+#~ msgstr "Cola vaciada"
+
+#~ msgid "Flushing receive queue for %s (%s)"
+#~ msgstr "Vaciando la cola de recepción para %s (%s)"
+
+#~ msgid "%s: option `%s' is ambiguous\n"
+#~ msgstr "%s: la opción `%s' es ambigua\n"
+
+#~ msgid "%s: option `--%s' doesn't allow an argument\n"
+#~ msgstr "%s: la opción `--%s' no lleva parámetros\n"
+
+#~ msgid "%s: option `%c%s' doesn't allow an argument\n"
+#~ msgstr "%s: la opción `%c%s' no lleva parámetros\n"
+
+#~ msgid "%s: option `%s' requires an argument\n"
+#~ msgstr "%s: la opción `%s' requiere un parámetro\n"
+
+#~ msgid "%s: unrecognized option `--%s'\n"
+#~ msgstr "%s: opción desconocida `--%s'\n"
+
+#~ msgid "%s: unrecognized option `%c%s'\n"
+#~ msgstr "%s: opción desconocida `%c%s'\n"
+
+#~ msgid "%s: illegal option -- %c\n"
+#~ msgstr "%s: opción ilegal -- %c\n"
+
+#~ msgid "%s: invalid option -- %c\n"
+#~ msgstr "%s: opción no válida --%c\n"
+
+#~ msgid "%s: option requires an argument -- %c\n"
+#~ msgstr "%s: la opción requiere un parámetro -- %c\n"
+
+#~ msgid "%s: option `-W %s' is ambiguous\n"
+#~ msgstr "%s: la opción `-W %s' es ambigua\n"
+
+#~ msgid "%s: option `-W %s' doesn't allow an argument\n"
+#~ msgstr "%s: la opción `-W %s' no lleva parámetros\n"
+
+#~ msgid "List callback[delete] failed for %08lx - freeing anyway"
+#~ msgstr ""
+#~ "El callback[delete] de la lista falló para %08lx - liberándolo de todos modos"
+
+#~ msgid "Memory exhausted"
+#~ msgstr "Memoria agotada"
+
+#~ msgid "Line %d too long while reading config file %s"
+#~ msgstr "La línea %d es demasiado larga en el fichero de configuración %s"
+
+#~ msgid "Illegal passphrase in %s; size would be %d"
+#~ msgstr "Frase ilegal en %s; el tamaño debe ser %d"
+
+#~ msgid "Opening /dev/urandom failed: %m"
+#~ msgstr "Fallo al abrir /dev/urandom: %m"
+
+#~ msgid "Encryption key set to %s"
+#~ msgstr "Clave de cifrado definida como %s"
+
+#~ msgid "Usage: %s bits\n"
+#~ msgstr "Modo de empleo: %s bits\n"
+
+#~ msgid "Illegal number: %s\n"
+#~ msgstr "Número ilegal: %s\n"
+
+#~ msgid "Receiving packet of %d bytes"
+#~ msgstr "Recibido paquete de %d bytes"
+
+#~ msgid "Could not open UDP connection to %s (%s)"
+#~ msgstr "No pude abrir una conexión UDP a %s (%s)"
+
+#~ msgid "tun/tap device will be left unconfigured"
+#~ msgstr "el dispositivo tun/tap se dejará sin configurar"
+
+#~ msgid "setsockopt: %m"
+#~ msgstr "setsockopt(): %m"
+
+#~ msgid "fcntl: %m"
+#~ msgstr "fcntl(): %m"
+
+#~ msgid "listen: %m"
+#~ msgstr "listen(): %m"
+
+#~ msgid "Unable to set up an incoming vpn data socket!"
+#~ msgstr "¡No puedo configurar un `socket' para recibir datos de la vpn!"
+
+#~ msgid "Error: getpeername: %m"
+#~ msgstr "Error: getpeername(): %m"
+
+#~ msgid "Non-IP ethernet frame %04x from %02x:%02x:%02x:%02x:%02x:%02x"
+#~ msgstr "Trama ethernet no-IP %04x desde %02x:%02x:%02x:%02x:%02x:%02x"
+
+#~ msgid "Dropping short packet from %02x:%02x:%02x:%02x:%02x:%02x"
+#~ msgstr "Ignorando paquete corto desde %02x:%02x:%02x:%02x:%02x:%02x"
+
+#~ msgid "Warning: got ADD_HOST from %s (%s) from ourself, restarting"
+#~ msgstr ""
+#~ "Aviso: recibí ADD_HOST desde %s (%s) de nosotros mismos, reiniciando"
+
+#~ msgid ""
+#~ "Got ADD_HOST from %s (%s) with origin %s which is not in our connection list"
+#~ msgstr ""
+#~ "Recibí ADD_HOST desde %s (%s) con origen %s que no está en nuestra lista de "
+#~ "conexiones"
+
+#~ msgid "Removing old entry for %s (%s)"
+#~ msgstr "Eliminando el registro viejo para %s (%s)"
+
+#~ msgid "Warning: got DEL_HOST from %s (%s) from ourself, restarting"
+#~ msgstr ""
+#~ "Aviso: recibí DEL_HOST desde %s (%s) de nosotros mismos, reiniciando"
+
+#~ msgid ""
+#~ "Got DEL_HOST from %s (%s) with origin %s which is not in our connection list"
+#~ msgstr ""
+#~ "Recibí DEL_HOST desde %s (%s) con origen %s que no está en nuestra lista de "
+#~ "conexiones"
+
+#~ msgid "Invalid timeout value `%s'.\n"
+#~ msgstr "Valor de timeout `%s' no válido.\n"
+
+#~ msgid "Got USR2 signal, forcing new key generation"
+#~ msgstr "Recibí la señal USR2, forzando generación de nueva clave"
diff --git a/src/.cvsignore b/src/.cvsignore
deleted file mode 100644 (file)
index a7e420f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-*.o .libs tincd Makefile.in Makefile .deps
index 5616c57..a3b7202 100644 (file)
@@ -1,5 +1,5 @@
 ## Produce this file with automake to get Makefile.in
-# $Id: Makefile.am,v 1.13 2003/08/24 20:38:23 guus Exp $
+# $Id: Makefile.am,v 1.4.4.33 2003/08/02 15:13:08 guus Exp $
 
 sbin_PROGRAMS = tincd
 
index 52e291a..369a5fb 100644 (file)
@@ -19,7 +19,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: conf.c,v 1.14 2003/08/24 20:38:24 guus Exp $
+    $Id: conf.c,v 1.9.4.77 2003/12/12 19:52:24 guus Exp $
 */
 
 #include "system.h"
@@ -73,7 +73,7 @@ config_t *new_config(void)
 {
        cp();
 
-       return (config_t *) xmalloc_and_zero(sizeof(config_t));
+       return xmalloc_and_zero(sizeof(config_t));
 }
 
 void free_config(config_t *cfg)
@@ -131,7 +131,7 @@ config_t *lookup_config_next(const avl_tree_t *config_tree, const config_t *cfg)
 
        if(node) {
                if(node->next) {
-                       found = (config_t *) node->next->data;
+                       found = node->next->data;
 
                        if(!strcasecmp(found->variable, cfg->variable))
                                return found;
@@ -214,16 +214,14 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result)
 
 bool get_config_subnet(const config_t *cfg, subnet_t ** result)
 {
-       subnet_t *subnet;
+       subnet_t subnet = {0};
 
        cp();
 
        if(!cfg)
                return false;
 
-       subnet = str2net(cfg->value);
-
-       if(!subnet) {
+       if(!str2net(&subnet, cfg->value)) {
                logger(LOG_ERR, _("Subnet expected for configuration variable %s in %s line %d"),
                           cfg->variable, cfg->file, cfg->line);
                return false;
@@ -231,17 +229,16 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result)
 
        /* Teach newbies what subnets are... */
 
-       if(((subnet->type == SUBNET_IPV4)
-               && !maskcheck(&subnet->net.ipv4.address, subnet->net.ipv4.prefixlength, sizeof(ipv4_t)))
-               || ((subnet->type == SUBNET_IPV6)
-               && !maskcheck(&subnet->net.ipv6.address, subnet->net.ipv6.prefixlength, sizeof(ipv6_t)))) {
+       if(((subnet.type == SUBNET_IPV4)
+               && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(ipv4_t)))
+               || ((subnet.type == SUBNET_IPV6)
+               && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(ipv6_t)))) {
                logger(LOG_ERR, _ ("Network address and prefix length do not match for configuration variable %s in %s line %d"),
                           cfg->variable, cfg->file, cfg->line);
-               free(subnet);
                return false;
        }
 
-       *result = subnet;
+       *(*result = new_subnet()) = subnet;
 
        return true;
 }
@@ -324,7 +321,7 @@ int read_config_file(avl_tree_t *config_tree, const char *fname)
        int err = -2;                           /* Parse error */
        FILE *fp;
        char *buffer, *line;
-       char *variable, *value;
+       char *variable, *value, *eol;
        int lineno = 0;
        int len;
        bool ignore = false;
@@ -375,6 +372,10 @@ int read_config_file(avl_tree_t *config_tree, const char *fname)
 
                variable = value = line;
 
+               eol = line + strlen(line);
+               while(strchr("\t ", *--eol))
+                       *eol = '\0';
+
                len = strcspn(value, "\t =");
                value += len;
                value += strspn(value, "\t ");
@@ -384,6 +385,7 @@ int read_config_file(avl_tree_t *config_tree, const char *fname)
                }
                variable[len] = '\0';
 
+       
                if(!*value) {
                        logger(LOG_ERR, _("No value for variable `%s' on line %d while reading config file %s"),
                                   variable, lineno, fname);
index e83a970..ba235c3 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: conf.h,v 1.11 2003/08/24 20:38:24 guus Exp $
+    $Id: conf.h,v 1.6.4.43 2003/08/08 22:11:54 guus Exp $
 */
 
 #ifndef __TINC_CONF_H__
index d970a9a..b4a17ad 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: connection.c,v 1.4 2003/08/24 20:38:24 guus Exp $
+    $Id: connection.c,v 1.1.2.44 2003/08/28 21:05:10 guus Exp $
 */
 
 #include "system.h"
@@ -64,7 +64,7 @@ connection_t *new_connection(void)
 
        cp();
 
-       c = (connection_t *) xmalloc_and_zero(sizeof(connection_t));
+       c = xmalloc_and_zero(sizeof(connection_t));
 
        if(!c)
                return NULL;
@@ -120,7 +120,7 @@ void dump_connections(void)
        logger(LOG_DEBUG, _("Connections:"));
 
        for(node = connection_tree->head; node; node = node->next) {
-               c = (connection_t *) node->data;
+               c = node->data;
                logger(LOG_DEBUG, _(" %s at %s options %lx socket %d status %04x"),
                           c->name, c->hostname, c->options, c->socket, *(uint32_t *)&c->status);
        }
index 0614b10..b1c35af 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: connection.h,v 1.4 2003/08/24 20:38:24 guus Exp $
+    $Id: connection.h,v 1.1.2.40 2003/12/20 21:25:17 guus Exp $
 */
 
 #ifndef __TINC_CONNECTION_H__
@@ -30,6 +30,7 @@
 
 #define OPTION_INDIRECT                0x0001
 #define OPTION_TCPONLY         0x0002
+#define OPTION_PMTU_DISCOVERY  0x0004
 
 typedef struct connection_status_t {
        int pinged:1;                           /* sent ping */
@@ -40,8 +41,8 @@ typedef struct connection_status_t {
        int timeout:1;                          /* 1 if gotten timeout */
        int encryptout:1;                       /* 1 if we can encrypt outgoing traffic */
        int decryptin:1;                        /* 1 if we have to decrypt incoming traffic */
-       int mst:1;                                      /* 1 if this connection is part of a minimum spanning tree */
-       int unused:18;
+       int mst:1;                              /* 1 if this connection is part of a minimum spanning tree */
+       int unused:23;
 } connection_status_t;
 
 #include "edge.h"
index 0ae6780..b7f49af 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: device.c,v 1.3 2003/08/27 13:47:47 guus Exp $
+    $Id: device.c,v 1.1.2.17 2003/10/08 11:37:20 guus Exp $
 */
 
 #include "system.h"
@@ -59,7 +59,7 @@ int sp[2];
 bool setup_device(void)
 {
        HKEY key, key2;
-       int i;
+       int i, err;
 
        char regpath[1024];
        char adapterid[1024];
index 212c0b0..00381a5 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: device.c,v 1.3 2003/08/27 13:47:47 guus Exp $
+    $Id: device.c,v 1.1.2.10 2003/07/22 20:55:21 guus Exp $
 */
 
 #include "system.h"
index 4762f1e..55a0c44 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: device.h,v 1.3 2003/08/24 20:38:24 guus Exp $
+    $Id: device.h,v 1.1.2.11 2003/07/22 20:55:19 guus Exp $
 */
 
 #ifndef __TINC_DEVICE_H__
index 97b3947..bf43d30 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: edge.c,v 1.4 2003/08/24 20:38:24 guus Exp $
+    $Id: edge.c,v 1.1.2.27 2003/08/28 21:05:10 guus Exp $
 */
 
 #include "system.h"
@@ -88,7 +88,7 @@ edge_t *new_edge(void)
 {
        cp();
 
-       return (edge_t *) xmalloc_and_zero(sizeof(edge_t));
+       return xmalloc_and_zero(sizeof(edge_t));
 }
 
 void free_edge(edge_t *e)
@@ -148,9 +148,9 @@ void dump_edges(void)
        logger(LOG_DEBUG, _("Edges:"));
 
        for(node = node_tree->head; node; node = node->next) {
-               n = (node_t *) node->data;
+               n = node->data;
                for(node2 = n->edge_tree->head; node2; node2 = node2->next) {
-                       e = (edge_t *) node2->data;
+                       e = node2->data;
                        address = sockaddr2hostname(&e->address);
                        logger(LOG_DEBUG, _(" %s to %s at %s options %lx weight %d"),
                                   e->from->name, e->to->name, address, e->options, e->weight);
index a001d51..ebb8337 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: edge.h,v 1.4 2003/08/24 20:38:24 guus Exp $
+    $Id: edge.h,v 1.1.2.17 2003/07/30 21:52:41 guus Exp $
 */
 
 #ifndef __TINC_EDGE_H__
index 2396d47..4d6431c 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: event.c,v 1.4 2003/08/24 20:38:24 guus Exp $
+    $Id: event.c,v 1.1.4.11 2003/08/28 21:05:10 guus Exp $
 */
 
 #include "system.h"
@@ -61,7 +61,7 @@ event_t *new_event(void)
 {
        cp();
 
-       return (event_t *) xmalloc_and_zero(sizeof(event_t));
+       return xmalloc_and_zero(sizeof(event_t));
 }
 
 void free_event(event_t *event)
@@ -93,7 +93,7 @@ event_t *get_expired_event(void)
        cp();
 
        if(event_tree->head) {
-               event = (event_t *) event_tree->head->data;
+               event = event_tree->head->data;
 
                if(event->time < now) {
                        avl_delete(event_tree, event);
index 0bc712c..6ec986d 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: event.h,v 1.4 2003/08/24 20:38:24 guus Exp $
+    $Id: event.h,v 1.1.4.8 2003/07/30 21:52:41 guus Exp $
 */
 
 #ifndef __TINC_EVENT_H__
index 382a60a..4ebdac2 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: device.c,v 1.4 2003/08/27 13:47:48 guus Exp $
+    $Id: device.c,v 1.1.2.13 2003/07/22 20:55:21 guus Exp $
 */
 
 #include "system.h"
index 31ead94..3ed1d72 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: graph.c,v 1.6 2003/08/24 20:38:24 guus Exp $
+    $Id: graph.c,v 1.1.2.34 2003/12/22 11:04:16 guus Exp $
 */
 
 /* We need to generate two trees from the graph:
@@ -76,7 +76,7 @@ void mst_kruskal(void)
        /* Clear MST status on connections */
 
        for(node = connection_tree->head; node; node = node->next) {
-               c = (connection_t *) node->data;
+               c = node->data;
                c->status.mst = false;
        }
 
@@ -90,7 +90,7 @@ void mst_kruskal(void)
        /* Clear visited status on nodes */
 
        for(node = node_tree->head; node; node = node->next) {
-               n = (node_t *) node->data;
+               n = node->data;
                n->status.visited = false;
                nodes++;
        }
@@ -103,7 +103,7 @@ void mst_kruskal(void)
 
        for(skipped = false, node = edge_weight_tree->head; node; node = next) {
                next = node->next;
-               e = (edge_t *) node->data;
+               e = node->data;
 
                if(!e->reverse || e->from->status.visited == e->to->status.visited) {
                        skipped = true;
@@ -158,7 +158,7 @@ void sssp_bfs(void)
        /* Clear visited status on nodes */
 
        for(node = node_tree->head; node; node = node->next) {
-               n = (node_t *) node->data;
+               n = node->data;
                n->status.visited = false;
                n->status.indirect = true;
        }
@@ -178,22 +178,23 @@ void sssp_bfs(void)
        while(todo_tree->head) {
                for(from = todo_tree->head; from; from = next) {        /* "from" is the node from which we start */
                        next = from->next;
-                       n = (node_t *) from->data;
+                       n = from->data;
 
                        for(to = n->edge_tree->head; to; to = to->next) {       /* "to" is the edge connected to "from" */
-                               e = (edge_t *) to->data;
+                               e = to->data;
 
                                if(!e->reverse)
                                        continue;
 
                                /* Situation:
 
-                                   /
-                                  /
-                                  ------(n)-----(e->to)
-                                  \
-                                   \
+                                          /
+                                         /
+                                  ----->(n)---e-->(e->to)
+                                         \
+                                          \
 
+                                  Where e is an edge, (n) and (e->to) are nodes.
                                   n->address is set to the e->address of the edge left of n to n.
                                   We are currently examining the edge e right of n from n:
 
@@ -228,6 +229,14 @@ void sssp_bfs(void)
 
                                        e->to->hostname = sockaddr2hostname(&e->to->address);
                                        avl_insert_node(node_udp_tree, node);
+
+                                       if(e->to->options & OPTION_PMTU_DISCOVERY) {
+                                               e->to->mtuprobes = 0;
+                                               e->to->minmtu = 0;
+                                               e->to->maxmtu = MTU;
+                                               if(e->to->status.validkey)
+                                                       send_mtu_probe(e->to);
+                                       }
                                }
 
                                node = avl_alloc_node();
@@ -245,7 +254,7 @@ void sssp_bfs(void)
 
        for(node = node_tree->head; node; node = next) {
                next = node->next;
-               n = (node_t *) node->data;
+               n = node->data;
 
                if(n->status.visited != n->status.reachable) {
                        n->status.reachable = !n->status.reachable;
@@ -261,6 +270,10 @@ void sssp_bfs(void)
                        n->status.validkey = false;
                        n->status.waitingforkey = false;
 
+                       n->maxmtu = MTU;
+                       n->minmtu = 0;
+                       n->mtuprobes = 0;
+
                        asprintf(&envp[0], "NETNAME=%s", netname ? : "");
                        asprintf(&envp[1], "DEVICE=%s", device ? : "");
                        asprintf(&envp[2], "INTERFACE=%s", iface ? : "");
index ba57878..3ce02f3 100644 (file)
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: graph.h,v 1.4 2003/08/24 20:38:24 guus Exp $
+    $Id: graph.h,v 1.1.2.6 2003/09/03 16:20:33 guus Exp $
 */
 
+#ifndef __TINC_GRAPH_H__
+#define __TINC_GRAPH_H__
+
 extern void graph(void);
 extern void mst_kruskal(void);
 extern void sssp_bfs(void);
+
+#endif /* __TINC_GRAPH_H__ */
index 1858f5c..0461278 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: device.c,v 1.4 2003/08/27 13:47:48 guus Exp $
+    $Id: device.c,v 1.1.2.21 2003/08/28 21:05:11 guus Exp $
 */
 
 #include "system.h"
@@ -94,10 +94,10 @@ bool setup_device(void)
        if(iface)
                strncpy(ifr.ifr_name, iface, IFNAMSIZ);
 
-       if(!ioctl(device_fd, TUNSETIFF, (void *) &ifr)) {
+       if(!ioctl(device_fd, TUNSETIFF, &ifr)) {
                strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
                iface = ifrname;
-       } else if(!ioctl(device_fd, (('T' << 8) | 202), (void *) &ifr)) {
+       } else if(!ioctl(device_fd, (('T' << 8) | 202), &ifr)) {
                logger(LOG_WARNING, _("Old ioctl() request was needed for %s"), device);
                strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
                iface = ifrname;
index 6ea6884..dec88fd 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: logger.c,v 1.2 2003/08/24 20:38:24 guus Exp $
+    $Id: logger.c,v 1.1.2.12 2003/10/06 16:13:07 guus Exp $
 */
 
 #include "system.h"
@@ -78,7 +78,7 @@ void logger(int priority, const char *format, ...) {
                        fflush(stderr);
                        break;
                case LOGMODE_FILE:
-                       fprintf(logfile, "%ld %s[%d]: ", time(NULL), logident, logpid);
+                       fprintf(logfile, "%ld %s[%ld]: ", time(NULL), logident, (long)logpid);
                        vfprintf(logfile, format, ap);
                        fprintf(logfile, "\n");
                        fflush(logfile);
index dcb9ee2..0071eb5 100644 (file)
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: meta.c,v 1.5 2003/08/24 20:38:24 guus Exp $
+    $Id: meta.c,v 1.1.2.50 2003/11/17 15:30:17 guus Exp $
 */
 
 #include "system.h"
 
+#include <openssl/err.h>
 #include <openssl/evp.h>
 
 #include "avl_tree.h"
@@ -46,7 +47,12 @@ bool send_meta(connection_t *c, const char *buffer, int length)
                           c->name, c->hostname);
 
        if(c->status.encryptout) {
-               EVP_EncryptUpdate(c->outctx, outbuf, &outlen, buffer, length);
+               result = EVP_EncryptUpdate(c->outctx, outbuf, &outlen, buffer, length);
+               if(!result || outlen != length) {
+                       logger(LOG_ERR, _("Error while encrypting metadata to %s (%s): %s"),
+                                       c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
+                       return false;
+               }
                bufp = outbuf;
                length = outlen;
        } else
@@ -80,7 +86,7 @@ void broadcast_meta(connection_t *from, const char *buffer, int length)
        cp();
 
        for(node = connection_tree->head; node; node = node->next) {
-               c = (connection_t *) node->data;
+               c = node->data;
 
                if(c != from && c->status.active)
                        send_meta(c, buffer, length);
@@ -89,8 +95,8 @@ void broadcast_meta(connection_t *from, const char *buffer, int length)
 
 bool receive_meta(connection_t *c)
 {
-       int oldlen, i;
-       int lenin, reqlen;
+       int oldlen, i, result;
+       int lenin, lenout, reqlen;
        bool decrypted = false;
        char inbuf[MAXBUFSIZE];
 
@@ -123,11 +129,16 @@ bool receive_meta(connection_t *c)
        oldlen = c->buflen;
        c->buflen += lenin;
 
-       while(lenin) {
+       while(lenin > 0) {
                /* Decrypt */
 
                if(c->status.decryptin && !decrypted) {
-                       EVP_DecryptUpdate(c->inctx, inbuf, &lenin, c->buffer + oldlen, lenin);
+                       result = EVP_DecryptUpdate(c->inctx, inbuf, &lenout, c->buffer + oldlen, lenin);
+                       if(!result || lenout != lenin) {
+                               logger(LOG_ERR, _("Error while decrypting metadata from %s (%s): %s"),
+                                               c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
+                               return false;
+                       }
                        memcpy(c->buffer + oldlen, inbuf, lenin);
                        decrypted = true;
                }
@@ -139,7 +150,7 @@ bool receive_meta(connection_t *c)
                                receive_tcppacket(c, c->buffer, c->tcplen);
 
                                c->buflen -= c->tcplen;
-                               lenin -= c->tcplen;
+                               lenin -= c->tcplen - oldlen;
                                memmove(c->buffer, c->buffer + c->tcplen, c->buflen);
                                oldlen = 0;
                                c->tcplen = 0;
@@ -167,7 +178,7 @@ bool receive_meta(connection_t *c)
                                return false;
 
                        c->buflen -= reqlen;
-                       lenin -= reqlen;
+                       lenin -= reqlen - oldlen;
                        memmove(c->buffer, c->buffer + reqlen, c->buflen);
                        oldlen = 0;
                        continue;
index 4ee70c4..15439b7 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: meta.h,v 1.3 2003/08/24 20:38:24 guus Exp $
+    $Id: meta.h,v 1.1.2.11 2003/08/12 14:48:13 guus Exp $
 */
 
 #ifndef __TINC_META_H__
index 3315286..93c6b78 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: device.c,v 1.3 2003/08/27 13:47:49 guus Exp $
+    $Id: device.c,v 1.1.2.14 2003/10/08 11:37:53 guus Exp $
 */
 
 #include "system.h"
 
 #define TAP_CONTROL_CODE(request,method) CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD | 8000, request, method, FILE_ANY_ACCESS)
 
-#define TAP_IOCTL_GET_LASTMAC    TAP_CONTROL_CODE(0, METHOD_BUFFERED)
-#define TAP_IOCTL_GET_MAC        TAP_CONTROL_CODE(1, METHOD_BUFFERED)
-#define TAP_IOCTL_SET_STATISTICS TAP_CONTROL_CODE(2, METHOD_BUFFERED)
+#define TAP_IOCTL_GET_LASTMAC           TAP_CONTROL_CODE(0, METHOD_BUFFERED)
+#define TAP_IOCTL_GET_MAC               TAP_CONTROL_CODE(1, METHOD_BUFFERED)
+#define TAP_IOCTL_SET_STATISTICS        TAP_CONTROL_CODE(2, METHOD_BUFFERED)
+#define TAP_IOCTL_GET_VERSION           TAP_CONTROL_CODE(3, METHOD_BUFFERED)
+#define TAP_IOCTL_GET_MTU               TAP_CONTROL_CODE(4, METHOD_BUFFERED)
+#define TAP_IOCTL_GET_INFO              TAP_CONTROL_CODE(5, METHOD_BUFFERED)
+#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE(6, METHOD_BUFFERED)
+#define TAP_IOCTL_SET_MEDIA_STATUS      TAP_CONTROL_CODE(7, METHOD_BUFFERED)
+
 
 int device_fd = 0;
 HANDLE device_handle = INVALID_HANDLE_VALUE;
@@ -131,6 +137,7 @@ bool setup_device(void)
        char adaptername[1024];
        char tapname[1024];
        long len;
+       unsigned long status;
 
        bool found = false;
 
@@ -283,6 +290,11 @@ bool setup_device(void)
 
        closesocket(sock);
 
+       /* Set media status for newer TAP-Win32 devices */
+
+       status = true;
+       DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL);
+
        device_info = _("Windows tap device");
 
        logger(LOG_INFO, _("%s (%s) is a %s"), device, iface, device_info);
index 42c9401..a6d2bb7 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: net.c,v 1.40 2003/08/24 20:38:24 guus Exp $
+    $Id: net.c,v 1.35.4.203 2003/12/20 19:47:52 guus Exp $
 */
 
 #include "system.h"
@@ -63,7 +63,7 @@ static void purge(void)
 
        for(nnode = node_tree->head; nnode; nnode = nnext) {
                nnext = nnode->next;
-               n = (node_t *) nnode->data;
+               n = nnode->data;
 
                if(!n->status.reachable) {
                        ifdebug(SCARY_THINGS) logger(LOG_DEBUG, _("Purging node %s (%s)"), n->name,
@@ -71,15 +71,17 @@ static void purge(void)
 
                        for(snode = n->subnet_tree->head; snode; snode = snext) {
                                snext = snode->next;
-                               s = (subnet_t *) snode->data;
-                               send_del_subnet(broadcast, s);
+                               s = snode->data;
+                               if(!tunnelserver)
+                                       send_del_subnet(broadcast, s);
                                subnet_del(n, s);
                        }
 
                        for(enode = n->edge_tree->head; enode; enode = enext) {
                                enext = enode->next;
-                               e = (edge_t *) enode->data;
-                               send_del_edge(broadcast, e);
+                               e = enode->data;
+                               if(!tunnelserver)
+                                       send_del_edge(broadcast, e);
                                edge_del(e);
                        }
                }
@@ -89,12 +91,12 @@ static void purge(void)
 
        for(nnode = node_tree->head; nnode; nnode = nnext) {
                nnext = nnode->next;
-               n = (node_t *) nnode->data;
+               n = nnode->data;
 
                if(!n->status.reachable) {
                        for(enode = edge_weight_tree->head; enode; enode = enext) {
                                enext = enode->next;
-                               e = (edge_t *) enode->data;
+                               e = enode->data;
 
                                if(e->to == n)
                                        break;
@@ -122,7 +124,7 @@ static int build_fdset(fd_set * fs)
 
        for(node = connection_tree->head; node; node = next) {
                next = node->next;
-               c = (connection_t *) node->data;
+               c = node->data;
 
                if(c->status.remove) {
                        connection_del(c);
@@ -178,7 +180,7 @@ void terminate_connection(connection_t *c, bool report)
                closesocket(c->socket);
 
        if(c->edge) {
-               if(report)
+               if(report && !tunnelserver)
                        send_del_edge(broadcast, c->edge);
 
                edge_del(c->edge);
@@ -186,6 +188,18 @@ void terminate_connection(connection_t *c, bool report)
                /* Run MST and SSSP algorithms */
 
                graph();
+
+               /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */
+
+               if(report && !c->node->status.reachable) {
+                       edge_t *e;
+                       e = lookup_edge(c->node, myself);
+                       if(e) {
+                               if(!tunnelserver)
+                                       send_del_edge(broadcast, e);
+                               edge_del(e);
+                       }
+               }
        }
 
        /* Check if this was our outgoing connection */
@@ -213,7 +227,7 @@ static void check_dead_connections(void)
 
        for(node = connection_tree->head; node; node = next) {
                next = node->next;
-               c = (connection_t *) node->data;
+               c = node->data;
 
                if(c->last_ping_time + pingtimeout < now) {
                        if(c->status.active) {
@@ -256,11 +270,11 @@ static void check_network_activity(fd_set * f)
 
        if(FD_ISSET(device_fd, f)) {
                if(read_packet(&packet))
-                       route_outgoing(&packet);
+                       route(myself, &packet);
        }
 
        for(node = connection_tree->head; node; node = node->next) {
-               c = (connection_t *) node->data;
+               c = node->data;
 
                if(c->status.remove)
                        continue;
@@ -320,7 +334,8 @@ int main_loop(void)
        while(running) {
                now = time(NULL);
 
-               tv.tv_sec = 1 + (rand() & 7);   /* Approx. 5 seconds, randomized to prevent global synchronisation effects */
+       //      tv.tv_sec = 1 + (rand() & 7);   /* Approx. 5 seconds, randomized to prevent global synchronisation effects */
+               tv.tv_sec = 1;
                tv.tv_usec = 0;
 
                maxfd = build_fdset(&fset);
@@ -353,7 +368,7 @@ int main_loop(void)
                        last_ping_check = now;
 
                        if(routing_mode == RMODE_SWITCH)
-                               age_mac();
+                               age_subnets();
 
                        age_past_requests();
 
@@ -380,7 +395,7 @@ int main_loop(void)
                        logger(LOG_INFO, _("Flushing event queue"));
 
                        while(event_tree->head) {
-                               event = (event_t *) event_tree->head->data;
+                               event = event_tree->head->data;
                                event->handler(event->data);
                                event_del(event);
                        }
@@ -408,7 +423,7 @@ int main_loop(void)
                        /* Close connections to hosts that have a changed or deleted host config file */
                        
                        for(node = connection_tree->head; node; node = node->next) {
-                               c = (connection_t *) node->data;
+                               c = node->data;
                                
                                if(c->outgoing) {
                                        free(c->outgoing->name);
index 092b9dc..5b14553 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: net.h,v 1.13 2003/08/24 20:38:24 guus Exp $
+    $Id: net.h,v 1.9.4.73 2003/12/20 19:47:52 guus Exp $
 */
 
 #ifndef __TINC_NET_H__
@@ -54,7 +54,7 @@ typedef struct ipv6_t {
 
 typedef short length_t;
 
-#define AF_UNKNOWN 0xFFFF
+#define AF_UNKNOWN 255
 
 struct sockaddr_unknown {
        uint16_t family;
@@ -150,6 +150,7 @@ extern int main_loop(void);
 extern void terminate_connection(struct connection_t *, bool);
 extern void flush_queue(struct node_t *);
 extern bool read_rsa_public_key(struct connection_t *);
+extern void send_mtu_probe(struct node_t *);
 
 #ifndef HAVE_MINGW
 #define closesocket(s) close(s)
index 9635faf..255453e 100644 (file)
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: net_packet.c,v 1.5 2003/08/24 20:38:24 guus Exp $
+    $Id: net_packet.c,v 1.1.2.49 2003/12/27 16:32:52 guus Exp $
 */
 
 #include "system.h"
 
 #include <openssl/rand.h>
+#include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 #include <openssl/hmac.h>
@@ -34,6 +35,7 @@
 #include "conf.h"
 #include "connection.h"
 #include "device.h"
+#include "ethernet.h"
 #include "event.h"
 #include "graph.h"
 #include "list.h"
 #include "utils.h"
 #include "xalloc.h"
 
+#ifdef WSAEMSGSIZE
+#define EMSGSIZE WSAEMSGSIZE
+#endif
+
 int keylifetime = 0;
 int keyexpires = 0;
 EVP_CIPHER_CTX packet_ctx;
 static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999_MEM_COMPRESS : LZO1X_1_MEM_COMPRESS];
 
+static void send_udppacket(node_t *, vpn_packet_t *);
 
 #define MAX_SEQNO 1073741824
 
+void send_mtu_probe(node_t *n)
+{
+       vpn_packet_t packet;
+       int len, i;
+       
+       cp();
+
+       n->mtuprobes++;
+       n->mtuevent = NULL;
+
+       if(n->mtuprobes >= 10 && !n->minmtu) {
+               ifdebug(TRAFFIC) logger(LOG_INFO, _("No response to MTU probes from %s (%s)"), n->name, n->hostname);
+               return;
+       }
+
+       for(i = 0; i < 3; i++) {
+               if(n->mtuprobes >= 30 || n->minmtu >= n->maxmtu) {
+                       n->mtu = n->minmtu;
+                       ifdebug(TRAFFIC) logger(LOG_INFO, _("Fixing MTU of %s (%s) to %d after %d probes"), n->name, n->hostname, n->mtu, n->mtuprobes);
+                       return;
+               }
+
+               len = n->minmtu + 1 + random() % (n->maxmtu - n->minmtu);
+               if(len < 64)
+                       len = 64;
+               
+               memset(packet.data, 0, 14);
+               RAND_pseudo_bytes(packet.data + 14, len - 14);
+               packet.len = len;
+
+               ifdebug(TRAFFIC) logger(LOG_INFO, _("Sending MTU probe length %d to %s (%s)"), len, n->name, n->hostname);
+
+               send_udppacket(n, &packet);
+       }
+
+       n->mtuevent = xmalloc(sizeof(*n->mtuevent));
+       n->mtuevent->handler = (event_handler_t)send_mtu_probe;
+       n->mtuevent->data = n;
+       n->mtuevent->time = now + 1;
+       event_add(n->mtuevent);
+}
+
+void mtu_probe_h(node_t *n, vpn_packet_t *packet) {
+       ifdebug(TRAFFIC) logger(LOG_INFO, _("Got MTU probe length %d from %s (%s)"), packet->len, n->name, n->hostname);
+
+       if(!packet->data[0]) {
+               packet->data[0] = 1;
+               send_packet(n, packet);
+       } else {
+               if(n->minmtu < packet->len)
+                       n->minmtu = packet->len;
+       }
+}
+
 static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level)
 {
        if(level == 10) {
@@ -103,7 +164,7 @@ static void receive_packet(node_t *n, vpn_packet_t *packet)
        ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Received packet of %d bytes from %s (%s)"),
                           packet->len, n->name, n->hostname);
 
-       route_incoming(n, packet);
+       route(n, packet);
 }
 
 static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
@@ -118,6 +179,14 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
 
        cp();
 
+       /* Check packet length */
+
+       if(inpkt->len < sizeof(inpkt->seqno) + myself->maclength) {
+               ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Got too short packet from %s (%s)"),
+                                       n->name, n->hostname);
+               return;
+       }
+
        /* Check the message authentication code */
 
        if(myself->digest && myself->maclength) {
@@ -137,12 +206,14 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
        if(myself->cipher) {
                outpkt = pkt[nextpkt++];
 
-//             EVP_DecryptInit_ex(&packet_ctx, myself->cipher, NULL, myself->key,
-//                                             myself->key + myself->cipher->key_len);
-               EVP_DecryptInit_ex(&packet_ctx, NULL, NULL, NULL, NULL);
-               EVP_DecryptUpdate(&packet_ctx, (char *) &outpkt->seqno, &outlen,
-                                                 (char *) &inpkt->seqno, inpkt->len);
-               EVP_DecryptFinal_ex(&packet_ctx, (char *) &outpkt->seqno + outlen, &outpad);
+               if(!EVP_DecryptInit_ex(&packet_ctx, NULL, NULL, NULL, NULL)
+                               || !EVP_DecryptUpdate(&packet_ctx, (char *) &outpkt->seqno, &outlen,
+                                       (char *) &inpkt->seqno, inpkt->len)
+                               || !EVP_DecryptFinal_ex(&packet_ctx, (char *) &outpkt->seqno + outlen, &outpad)) {
+                       ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Error decrypting packet from %s (%s): %s"),
+                                               n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL));
+                       return;
+               }
                
                outpkt->len = outlen + outpad;
                inpkt = outpkt;
@@ -181,15 +252,21 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
                outpkt = pkt[nextpkt++];
 
                if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, myself->compression)) < 0) {
-                       logger(LOG_ERR, _("Error while uncompressing packet from %s (%s)"),
-                                  n->name, n->hostname);
+                       ifdebug(TRAFFIC) logger(LOG_ERR, _("Error while uncompressing packet from %s (%s)"),
+                                                n->name, n->hostname);
                        return;
                }
 
                inpkt = outpkt;
        }
 
-       receive_packet(n, inpkt);
+       if(n->connection)
+               n->connection->last_ping_time = now;
+
+       if(!inpkt->data[12] && !inpkt->data[13])
+               mtu_probe_h(n, inpkt);
+       else
+               receive_packet(n, inpkt);
 }
 
 void receive_tcppacket(connection_t *c, char *buffer, int len)
@@ -228,8 +305,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *inpkt)
 
                /* Since packet is on the stack of handle_tap_input(), we have to make a copy of it first. */
 
-               copy = xmalloc(sizeof(vpn_packet_t));
-               memcpy(copy, inpkt, sizeof(vpn_packet_t));
+               *(copy = xmalloc(sizeof(*copy))) = *inpkt;
 
                list_insert_tail(n->queue, copy);
 
@@ -253,7 +329,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *inpkt)
                outpkt = pkt[nextpkt++];
 
                if((outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->compression)) < 0) {
-                       logger(LOG_ERR, _("Error while compressing packet to %s (%s)"),
+                       ifdebug(TRAFFIC) logger(LOG_ERR, _("Error while compressing packet to %s (%s)"),
                                   n->name, n->hostname);
                        return;
                }
@@ -271,11 +347,14 @@ static void send_udppacket(node_t *n, vpn_packet_t *inpkt)
        if(n->cipher) {
                outpkt = pkt[nextpkt++];
 
-//             EVP_EncryptInit_ex(&packet_ctx, n->cipher, NULL, n->key, n->key + n->cipher->key_len);
-               EVP_EncryptInit_ex(&n->packet_ctx, NULL, NULL, NULL, NULL);
-               EVP_EncryptUpdate(&n->packet_ctx, (char *) &outpkt->seqno, &outlen,
-                                                 (char *) &inpkt->seqno, inpkt->len);
-               EVP_EncryptFinal_ex(&n->packet_ctx, (char *) &outpkt->seqno + outlen, &outpad);
+               if(!EVP_EncryptInit_ex(&n->packet_ctx, NULL, NULL, NULL, NULL)
+                               || !EVP_EncryptUpdate(&n->packet_ctx, (char *) &outpkt->seqno, &outlen,
+                                       (char *) &inpkt->seqno, inpkt->len)
+                               || !EVP_EncryptFinal_ex(&n->packet_ctx, (char *) &outpkt->seqno + outlen, &outpad)) {
+                       ifdebug(TRAFFIC) logger(LOG_ERR, _("Error while encrypting packet to %s (%s): %s"),
+                                               n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL));
+                       goto end;
+               }
 
                outpkt->len = outlen + outpad;
                inpkt = outpkt;
@@ -311,10 +390,16 @@ static void send_udppacket(node_t *n, vpn_packet_t *inpkt)
 #endif
 
        if((sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, &(n->address.sa), SALEN(n->address.sa))) < 0) {
-               logger(LOG_ERR, _("Error sending packet to %s (%s): %s"), n->name, n->hostname, strerror(errno));
-               return;
+               if(errno == EMSGSIZE) {
+                       if(n->maxmtu >= origlen)
+                               n->maxmtu = origlen - 1;
+                       if(n->mtu >= origlen)
+                               n->mtu = origlen - 1;
+               } else
+                       logger(LOG_ERR, _("Error sending packet to %s (%s): %s"), n->name, n->hostname, strerror(errno));
        }
 
+end:
        inpkt->len = origlen;
 }
 
@@ -327,14 +412,16 @@ void send_packet(const node_t *n, vpn_packet_t *packet)
 
        cp();
 
-       ifdebug(TRAFFIC) logger(LOG_ERR, _("Sending packet of %d bytes to %s (%s)"),
-                          packet->len, n->name, n->hostname);
-
        if(n == myself) {
-               ifdebug(TRAFFIC) logger(LOG_NOTICE, _("Packet is looping back to us!"));
+               if(overwrite_mac)
+                        memcpy(packet->data, mymac.x, ETH_ALEN);
+               write_packet(packet);
                return;
        }
 
+       ifdebug(TRAFFIC) logger(LOG_ERR, _("Sending packet of %d bytes to %s (%s)"),
+                          packet->len, n->name, n->hostname);
+
        if(!n->status.reachable) {
                ifdebug(TRAFFIC) logger(LOG_INFO, _("Node %s (%s) is not reachable"),
                                   n->name, n->hostname);
@@ -367,7 +454,7 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet)
                           packet->len, from->name, from->hostname);
 
        for(node = connection_tree->head; node; node = node->next) {
-               c = (connection_t *) node->data;
+               c = node->data;
 
                if(c->status.active && c->status.mst && c != from->nexthop->connection)
                        send_packet(c->node, packet);
@@ -384,7 +471,7 @@ void flush_queue(node_t *n)
 
        for(node = n->queue->head; node; node = next) {
                next = node->next;
-               send_udppacket(n, (vpn_packet_t *) node->data);
+               send_udppacket(n, node->data);
                list_delete_node(n->queue, node);
        }
 }
@@ -401,7 +488,7 @@ void handle_incoming_vpn_data(int sock)
 
        pkt.len = recvfrom(sock, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
 
-       if(pkt.len <= 0) {
+       if(pkt.len < 0) {
                logger(LOG_ERR, _("Receiving packet failed: %s"), strerror(errno));
                return;
        }
@@ -418,8 +505,5 @@ void handle_incoming_vpn_data(int sock)
                return;
        }
 
-       if(n->connection)
-               n->connection->last_ping_time = now;
-
        receive_udppacket(n, &pkt);
 }
index f9de9eb..aa2fbfb 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: net_setup.c,v 1.5 2003/08/24 20:38:24 guus Exp $
+    $Id: net_setup.c,v 1.1.2.50 2003/12/20 21:25:17 guus Exp $
 */
 
 #include "system.h"
@@ -25,6 +25,8 @@
 #include <openssl/pem.h>
 #include <openssl/rsa.h>
 #include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
 
 #include "avl_tree.h"
 #include "conf.h"
@@ -148,17 +150,23 @@ bool read_rsa_public_key(connection_t *c)
 bool read_rsa_private_key(void)
 {
        FILE *fp;
-       char *fname, *key;
+       char *fname, *key, *pubkey;
        struct stat s;
 
        cp();
 
        if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) {
+               if(!get_config_string(lookup_config(myself->connection->config_tree, "PublicKey"), &pubkey)) {
+                       logger(LOG_ERR, _("PrivateKey used but no PublicKey found!"));
+                       return false;
+               }
                myself->connection->rsa_key = RSA_new();
 //             RSA_blinding_on(myself->connection->rsa_key, NULL);
                BN_hex2bn(&myself->connection->rsa_key->d, key);
+               BN_hex2bn(&myself->connection->rsa_key->n, pubkey);
                BN_hex2bn(&myself->connection->rsa_key->e, "FFFF");
                free(key);
+               free(pubkey);
                return true;
        }
 
@@ -240,19 +248,15 @@ bool setup_myself(void)
        myself->name = name;
        myself->connection->name = xstrdup(name);
 
-       if(!read_rsa_private_key())
-               return false;
-
        if(!read_connection_config(myself->connection)) {
                logger(LOG_ERR, _("Cannot open host configuration file for myself!"));
                return false;
        }
 
-       if(!read_rsa_public_key(myself->connection))
+       if(!read_rsa_private_key())
                return false;
 
-       if(!get_config_string
-          (lookup_config(myself->connection->config_tree, "Port"), &myport))
+       if(!get_config_string(lookup_config(myself->connection->config_tree, "Port"), &myport))
                asprintf(&myport, "655");
 
        /* Read in all the subnets specified in the host configuration file */
@@ -270,25 +274,26 @@ bool setup_myself(void)
 
        /* Check some options */
 
-       if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice))
-               if(choice)
-                       myself->options |= OPTION_INDIRECT;
+       if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice)
+               myself->options |= OPTION_INDIRECT;
 
-       if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice))
-               if(choice)
-                       myself->options |= OPTION_TCPONLY;
+       if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice)
+               myself->options |= OPTION_TCPONLY;
 
-       if(get_config_bool(lookup_config(myself->connection->config_tree, "IndirectData"), &choice))
-               if(choice)
-                       myself->options |= OPTION_INDIRECT;
+       if(get_config_bool(lookup_config(myself->connection->config_tree, "IndirectData"), &choice) && choice)
+               myself->options |= OPTION_INDIRECT;
+
+       if(get_config_bool(lookup_config(myself->connection->config_tree, "TCPOnly"), &choice) && choice)
+               myself->options |= OPTION_TCPONLY;
 
-       if(get_config_bool(lookup_config(myself->connection->config_tree, "TCPOnly"), &choice))
-               if(choice)
-                       myself->options |= OPTION_TCPONLY;
+       if(get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice)
+               myself->options |= OPTION_PMTU_DISCOVERY;
 
        if(myself->options & OPTION_TCPONLY)
                myself->options |= OPTION_INDIRECT;
 
+       get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver);
+
        if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) {
                if(!strcasecmp(mode, "router"))
                        routing_mode = RMODE_ROUTER;
@@ -314,7 +319,7 @@ bool setup_myself(void)
        if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire))
                macexpire = 600;
 
-       if(get_config_int(lookup_config(myself->connection->config_tree, "MaxTimeout"), &maxtimeout)) {
+       if(get_config_int(lookup_config(config_tree, "MaxTimeout"), &maxtimeout)) {
                if(maxtimeout <= 0) {
                        logger(LOG_ERR, _("Bogus maximum timeout!"));
                        return false;
@@ -362,7 +367,7 @@ bool setup_myself(void)
 
        myself->connection->outcipher = EVP_bf_ofb();
 
-       myself->key = (char *) xmalloc(myself->keylength);
+       myself->key = xmalloc(myself->keylength);
        RAND_pseudo_bytes(myself->key, myself->keylength);
 
        if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
@@ -372,7 +377,12 @@ bool setup_myself(void)
        
        if(myself->cipher) {
                EVP_CIPHER_CTX_init(&packet_ctx);
-               EVP_DecryptInit_ex(&packet_ctx, myself->cipher, NULL, myself->key, myself->key + myself->cipher->key_len);
+               if(!EVP_DecryptInit_ex(&packet_ctx, myself->cipher, NULL, myself->key, myself->key + myself->cipher->key_len)) {
+                       logger(LOG_ERR, _("Error during initialisation of cipher for %s (%s): %s"),
+                                       myself->name, myself->hostname, ERR_error_string(ERR_get_error(), NULL));
+                       return false;
+               }
+
        }
 
        /* Check if we want to use message authentication codes... */
@@ -549,7 +559,7 @@ void close_network_connections(void)
 
        for(node = connection_tree->head; node; node = next) {
                next = node->next;
-               c = (connection_t *) node->data;
+               c = node->data;
 
                if(c->outgoing)
                        free(c->outgoing->name), free(c->outgoing), c->outgoing = NULL;
index d624a87..3d1be21 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: net_socket.c,v 1.4 2003/08/24 20:38:25 guus Exp $
+    $Id: net_socket.c,v 1.1.2.38 2003/12/22 11:04:16 guus Exp $
 */
 
 #include "system.h"
@@ -49,31 +49,30 @@ int listen_sockets;
 
 int setup_listen_socket(const sockaddr_t *sa)
 {
-       int nfd, flags;
+       int nfd;
        char *addrstr;
        int option;
        char *iface;
-#ifdef SO_BINDTODEVICE
-       struct ifreq ifr;
-#endif
 
        cp();
 
        nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
 
        if(nfd < 0) {
-               logger(LOG_ERR, _("Creating metasocket failed: %s"), strerror(errno));
+               ifdebug(STATUS) logger(LOG_ERR, _("Creating metasocket failed: %s"), strerror(errno));
                return -1;
        }
 
 #ifdef O_NONBLOCK
-       flags = fcntl(nfd, F_GETFL);
+       {
+               int flags = fcntl(nfd, F_GETFL);
 
-       if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
-               closesocket(nfd);
-               logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
-                          strerror(errno));
-               return -1;
+               if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
+                       closesocket(nfd);
+                       logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
+                                  strerror(errno));
+                       return -1;
+               }
        }
 #endif
 
@@ -94,6 +93,8 @@ int setup_listen_socket(const sockaddr_t *sa)
        if(get_config_string
           (lookup_config(config_tree, "BindToInterface"), &iface)) {
 #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
+               struct ifreq ifr;
+
                memset(&ifr, 0, sizeof(ifr));
                strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
 
@@ -129,13 +130,9 @@ int setup_listen_socket(const sockaddr_t *sa)
 
 int setup_vpn_in_socket(const sockaddr_t *sa)
 {
-       int nfd, flags;
+       int nfd;
        char *addrstr;
        int option;
-#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
-       char *iface;
-       struct ifreq ifr;
-#endif
 
        cp();
 
@@ -147,29 +144,58 @@ int setup_vpn_in_socket(const sockaddr_t *sa)
        }
 
 #ifdef O_NONBLOCK
-       flags = fcntl(nfd, F_GETFL);
-       if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
-               closesocket(nfd);
-               logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
-                          strerror(errno));
-               return -1;
+       {
+               int flags = fcntl(nfd, F_GETFL);
+
+               if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
+                       closesocket(nfd);
+                       logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
+                                  strerror(errno));
+                       return -1;
+               }
        }
 #endif
 
        option = 1;
        setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
 
-#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
-       if(get_config_string
-          (lookup_config(config_tree, "BindToInterface"), &iface)) {
-               memset(&ifr, 0, sizeof(ifr));
-               strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
+#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
+       {
+               bool choice;
 
-               if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr))) {
-                       closesocket(nfd);
-                       logger(LOG_ERR, _("Can't bind to interface %s: %s"), iface,
-                                  strerror(errno));
-                       return -1;
+               if(get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice) {
+                       option = IP_PMTUDISC_DO;
+                       setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, &option, sizeof(option));
+               }
+       }
+#endif
+
+#if defined(SOL_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
+       {
+               bool choice;
+
+               if(get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice) {
+                       option = IPV6_PMTUDISC_DO;
+                       setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, &option, sizeof(option));
+               }
+       }
+#endif
+
+#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
+       {
+               char *iface;
+               struct ifreq ifr;
+
+               if(get_config_string(lookup_config(config_tree, "BindToInterface"), &iface)) {
+                       memset(&ifr, 0, sizeof(ifr));
+                       strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
+
+                       if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr))) {
+                               closesocket(nfd);
+                               logger(LOG_ERR, _("Can't bind to interface %s: %s"), iface,
+                                          strerror(errno));
+                               return -1;
+                       }
                }
        }
 #endif
@@ -255,8 +281,7 @@ begin:
                goto begin;
        }
 
-       memcpy(&c->address, c->outgoing->aip->ai_addr,
-                  c->outgoing->aip->ai_addrlen);
+       memcpy(&c->address, c->outgoing->aip->ai_addr, c->outgoing->aip->ai_addrlen);
        c->outgoing->aip = c->outgoing->aip->ai_next;
 
        if(c->hostname)
index 0a506f1..9c3b2cd 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: device.c,v 1.4 2003/08/27 13:47:49 guus Exp $
+    $Id: device.c,v 1.1.2.13 2003/07/31 11:31:50 guus Exp $
 */
 
 #include "system.h"
index 97186e9..c12ed93 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: netutl.c,v 1.17 2003/08/24 20:38:25 guus Exp $
+    $Id: netutl.c,v 1.12.4.54 2003/08/22 15:03:59 guus Exp $
 */
 
 #include "system.h"
index 9524e17..ff557ef 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: netutl.h,v 1.6 2003/08/24 20:38:25 guus Exp $
+    $Id: netutl.h,v 1.2.4.19 2003/08/22 11:18:42 guus Exp $
 */
 
 #ifndef __TINC_NETUTL_H__
index cec3a48..3519916 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: node.c,v 1.4 2003/08/24 20:38:25 guus Exp $
+    $Id: node.c,v 1.1.2.31 2003/12/22 11:04:16 guus Exp $
 */
 
 #include "system.h"
@@ -72,7 +72,7 @@ void exit_nodes(void)
 
 node_t *new_node(void)
 {
-       node_t *n = (node_t *) xmalloc_and_zero(sizeof(*n));
+       node_t *n = xmalloc_and_zero(sizeof(*n));
 
        cp();
 
@@ -80,6 +80,8 @@ node_t *new_node(void)
        n->edge_tree = new_edge_tree();
        n->queue = list_alloc((list_action_t) free);
        EVP_CIPHER_CTX_init(&n->packet_ctx);
+       n->mtu = MTU;
+       n->maxmtu = MTU;
 
        return n;
 }
@@ -109,6 +111,9 @@ void free_node(node_t *n)
        sockaddrfree(&n->address);
 
        EVP_CIPHER_CTX_cleanup(&n->packet_ctx);
+
+       if(n->mtuevent)
+               event_del(n->mtuevent);
        
        free(n);
 }
@@ -131,13 +136,13 @@ void node_del(node_t *n)
 
        for(node = n->subnet_tree->head; node; node = next) {
                next = node->next;
-               s = (subnet_t *) node->data;
+               s = node->data;
                subnet_del(n, s);
        }
 
        for(node = n->edge_tree->head; node; node = next) {
                next = node->next;
-               e = (edge_t *) node->data;
+               e = node->data;
                edge_del(e);
        }
 
@@ -178,12 +183,12 @@ void dump_nodes(void)
        logger(LOG_DEBUG, _("Nodes:"));
 
        for(node = node_tree->head; node; node = node->next) {
-               n = (node_t *) node->data;
-               logger(LOG_DEBUG, _(" %s at %s cipher %d digest %d maclength %d compression %d options %lx status %04x nexthop %s via %s"),
+               n = node->data;
+               logger(LOG_DEBUG, _(" %s at %s cipher %d digest %d maclength %d compression %d options %lx status %04x nexthop %s via %s pmtu %d (min %d max %d)"),
                           n->name, n->hostname, n->cipher ? n->cipher->nid : 0,
                           n->digest ? n->digest->type : 0, n->maclength, n->compression,
                           n->options, *(uint32_t *)&n->status, n->nexthop ? n->nexthop->name : "-",
-                          n->via ? n->via->name : "-");
+                          n->via ? n->via->name : "-", n->mtu, n->minmtu, n->maxmtu);
        }
 
        logger(LOG_DEBUG, _("End of nodes."));
index 05055bb..dd9c7a1 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: node.h,v 1.4 2003/08/24 20:38:25 guus Exp $
+    $Id: node.h,v 1.1.2.31 2003/12/22 11:04:16 guus Exp $
 */
 
 #ifndef __TINC_NODE_H__
 
 #include "avl_tree.h"
 #include "connection.h"
+#include "event.h"
 #include "list.h"
 #include "subnet.h"
 
 typedef struct node_status_t {
        int active:1;                           /* 1 if active.. */
        int validkey:1;                         /* 1 if we currently have a valid key for him */
-       int waitingforkey:1;            /* 1 if we already sent out a request */
+       int waitingforkey:1;                    /* 1 if we already sent out a request */
        int visited:1;                          /* 1 if this node has been visited by one of the graph algorithms */
        int reachable:1;                        /* 1 if this node is reachable in the graph */
        int indirect:1;                         /* 1 if this node is not directly reachable by us */
@@ -39,7 +40,7 @@ typedef struct node_status_t {
 } node_status_t;
 
 typedef struct node_t {
-       char *name;                                     /* name of this node */
+       char *name;                             /* name of this node */
        long int options;                       /* options turned on for this node */
 
        sockaddr_t address;                     /* his real (internet) ip to send UDP packets to */
@@ -47,30 +48,36 @@ typedef struct node_t {
 
        node_status_t status;
 
-       const EVP_CIPHER *cipher;       /* Cipher type for UDP packets */
-       char *key;                                      /* Cipher key and iv */
+       const EVP_CIPHER *cipher;               /* Cipher type for UDP packets */
+       char *key;                              /* Cipher key and iv */
        int keylength;                          /* Cipher key and iv length */
-       EVP_CIPHER_CTX packet_ctx;      /* Cipher context */
+       EVP_CIPHER_CTX packet_ctx;              /* Cipher context */
        
-       const EVP_MD *digest;           /* Digest type for MAC */
+       const EVP_MD *digest;                   /* Digest type for MAC */
        int maclength;                          /* Length of MAC */
 
        int compression;                        /* Compressionlevel, 0 = no compression */
 
        list_t *queue;                          /* Queue for packets awaiting to be encrypted */
 
-       struct node_t *nexthop;         /* nearest node from us to him */
+       struct node_t *nexthop;                 /* nearest node from us to him */
        struct node_t *via;                     /* next hop for UDP packets */
 
-       avl_tree_t *subnet_tree;        /* Pointer to a tree of subnets belonging to this node */
+       avl_tree_t *subnet_tree;                /* Pointer to a tree of subnets belonging to this node */
 
-       avl_tree_t *edge_tree;          /* Edges with this node as one of the endpoints */
+       avl_tree_t *edge_tree;                  /* Edges with this node as one of the endpoints */
 
        struct connection_t *connection;        /* Connection associated with this node (if a direct connection exists) */
 
-       uint32_t sent_seqno;            /* Sequence number last sent to this node */
-       uint32_t received_seqno;        /* Sequence number last received from this node */
-       unsigned char late[16]; /* Bitfield marking late packets */
+       uint32_t sent_seqno;                    /* Sequence number last sent to this node */
+       uint32_t received_seqno;                /* Sequence number last received from this node */
+       unsigned char late[16];                 /* Bitfield marking late packets */
+
+       length_t mtu;                           /* Maximum size of packets to send to this node */
+       length_t minmtu;                        /* Probed minimum MTU */
+       length_t maxmtu;                        /* Probed maximum MTU */
+       int mtuprobes;                          /* Number of probes */
+       event_t *mtuevent;                      /* Probe event */
 } node_t;
 
 extern struct node_t *myself;
index e82f3c3..9519bb6 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: device.c,v 1.4 2003/08/27 13:47:50 guus Exp $
+    $Id: device.c,v 1.1.2.19 2003/08/08 11:45:37 guus Exp $
 */
 
 #include "system.h"
index b988881..b82e951 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: process.c,v 1.5 2003/08/24 20:38:25 guus Exp $
+    $Id: process.c,v 1.1.2.78 2003/12/07 14:29:02 guus Exp $
 */
 
 #include "system.h"
@@ -58,19 +58,6 @@ static void memory_full(int size)
 
 /* Some functions the less gifted operating systems might lack... */
 
-#ifndef HAVE_FCLOSEALL
-static int fcloseall(void)
-{
-       fflush(stdin);
-       fflush(stdout);
-       fflush(stderr);
-       fclose(stdin);
-       fclose(stdout);
-       fclose(stderr);
-       return 0;
-}
-#endif
-
 #ifdef HAVE_MINGW
 extern char *identname;
 extern char *program_name;
@@ -254,7 +241,7 @@ bool init_service(void) {
 */
 static bool write_pidfile(void)
 {
-       int pid;
+       pid_t pid;
 
        cp();
 
@@ -262,16 +249,18 @@ static bool write_pidfile(void)
 
        if(pid) {
                if(netname)
-                       fprintf(stderr, _("A tincd is already running for net `%s' with pid %d.\n"),
-                                       netname, pid);
+                       fprintf(stderr, _("A tincd is already running for net `%s' with pid %ld.\n"),
+                                       netname, (long)pid);
                else
-                       fprintf(stderr, _("A tincd is already running with pid %d.\n"), pid);
+                       fprintf(stderr, _("A tincd is already running with pid %ld.\n"), (long)pid);
                return false;
        }
 
        /* if it's locked, write-protected, or whatever */
-       if(!write_pid(pidfilename))
+       if(!write_pid(pidfilename)) {
+               fprintf(stderr, _("Could write pid file %s: %s\n"), pidfilename, strerror(errno));
                return false;
+       }
 
        return true;
 }
@@ -283,7 +272,7 @@ static bool write_pidfile(void)
 bool kill_other(int signal)
 {
 #ifndef HAVE_MINGW
-       int pid;
+       pid_t pid;
 
        cp();
 
@@ -348,8 +337,10 @@ bool detach(void)
 
                /* Now UPDATE the pid in the pidfile, because we changed it... */
 
-               if(!write_pid(pidfilename))
+               if(!write_pid(pidfilename)) {
+                       fprintf(stderr, _("Could not write pid file %s: %s\n"), pidfilename, strerror(errno));
                        return false;
+               }
 #else
                if(!statushandle)
                        exit(install_service());
@@ -440,13 +431,19 @@ bool execute_script(const char *name, char **envp)
 static RETSIGTYPE sigterm_handler(int a)
 {
        logger(LOG_NOTICE, _("Got %s signal"), "TERM");
-       running = false;
+       if(running)
+               running = false;
+       else
+               exit(1);
 }
 
 static RETSIGTYPE sigquit_handler(int a)
 {
        logger(LOG_NOTICE, _("Got %s signal"), "QUIT");
-       running = false;
+       if(running)
+               running = false;
+       else
+               exit(1);
 }
 
 static RETSIGTYPE fatal_signal_square(int a)
index cf8de25..cf51fc8 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: process.h,v 1.3 2003/08/24 20:38:27 guus Exp $
+    $Id: process.h,v 1.1.2.19 2003/08/02 20:50:38 guus Exp $
 */
 
 #ifndef __TINC_PROCESS_H__
index c7f4b56..e6c13f4 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: protocol.c,v 1.32 2003/08/24 20:38:27 guus Exp $
+    $Id: protocol.c,v 1.28.4.148 2003/11/17 15:30:17 guus Exp $
 */
 
 #include "system.h"
@@ -30,6 +30,8 @@
 #include "utils.h"
 #include "xalloc.h"
 
+bool tunnelserver = false;
+
 /* Jumptable for the request handlers */
 
 static bool (*request_handlers[])(connection_t *) = {
@@ -219,7 +221,7 @@ bool seen_request(char *request)
                ifdebug(SCARY_THINGS) logger(LOG_DEBUG, _("Already seen request"));
                return true;
        } else {
-               new = (past_request_t *) xmalloc(sizeof(*new));
+               new = xmalloc(sizeof(*new));
                new->request = xstrdup(request);
                new->firstseen = now;
                avl_insert(past_request_tree, new);
@@ -237,7 +239,7 @@ void age_past_requests(void)
 
        for(node = past_request_tree->head; node; node = next) {
                next = node->next;
-               p = (past_request_t *) node->data;
+               p = node->data;
 
                if(p->firstseen + pingtimeout < now)
                        avl_delete_node(past_request_tree, node), deleted++;
index 0202af7..8951cbc 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: protocol.h,v 1.9 2003/08/24 20:38:27 guus Exp $
+    $Id: protocol.h,v 1.5.4.45 2003/11/17 15:30:18 guus Exp $
 */
 
 #ifndef __TINC_PROTOCOL_H__
@@ -54,6 +54,8 @@ typedef struct past_request_t {
        time_t firstseen;
 } past_request_t;
 
+extern bool tunnelserver;
+
 /* Maximum size of strings in a request */
 
 #define MAX_STRING_SIZE 2048
index 360cf9c..77561b8 100644 (file)
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: protocol_auth.c,v 1.5 2003/08/24 20:38:27 guus Exp $
+    $Id: protocol_auth.c,v 1.1.4.34 2003/12/22 11:04:16 guus Exp $
 */
 
 #include "system.h"
 
 #include <openssl/sha.h>
 #include <openssl/rand.h>
+#include <openssl/err.h>
 #include <openssl/evp.h>
 
 #include "avl_tree.h"
@@ -50,7 +51,6 @@ bool send_id(connection_t *c)
 bool id_h(connection_t *c)
 {
        char name[MAX_STRING_SIZE];
-       bool choice;
 
        cp();
 
@@ -108,14 +108,6 @@ bool id_h(connection_t *c)
                return false;
        }
 
-       /* Check some options */
-
-       if((get_config_bool(lookup_config(c->config_tree, "IndirectData"), &choice) && choice) || myself->options & OPTION_INDIRECT)
-               c->options |= OPTION_INDIRECT;
-
-       if((get_config_bool(lookup_config(c->config_tree, "TCPOnly"), &choice) && choice) || myself->options & OPTION_TCPONLY)
-               c->options |= OPTION_TCPONLY | OPTION_INDIRECT;
-
        c->allow_request = METAKEY;
 
        return send_metakey(c);
@@ -141,7 +133,7 @@ bool send_metakey(connection_t *c)
        cp();
        /* Copy random data to the buffer */
 
-       RAND_bytes(c->outkey, len);
+       RAND_pseudo_bytes(c->outkey, len);
 
        /* The message we send must be smaller than the modulus of the RSA key.
           By definition, for a key of k bits, the following formula holds:
@@ -190,10 +182,14 @@ bool send_metakey(connection_t *c)
        /* Further outgoing requests are encrypted with the key we just generated */
 
        if(c->outcipher) {
-               EVP_EncryptInit(c->outctx, c->outcipher,
-                                               c->outkey + len - c->outcipher->key_len,
-                                               c->outkey + len - c->outcipher->key_len -
-                                               c->outcipher->iv_len);
+               if(!EVP_EncryptInit(c->outctx, c->outcipher,
+                                       c->outkey + len - c->outcipher->key_len,
+                                       c->outkey + len - c->outcipher->key_len -
+                                       c->outcipher->iv_len)) {
+                       logger(LOG_ERR, _("Error during initialisation of cipher for %s (%s): %s"),
+                                       c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
+                       return false;
+               }
 
                c->status.encryptout = true;
        }
@@ -262,10 +258,14 @@ bool metakey_h(connection_t *c)
                        return false;
                }
 
-               EVP_DecryptInit(c->inctx, c->incipher,
-                                               c->inkey + len - c->incipher->key_len,
-                                               c->inkey + len - c->incipher->key_len -
-                                               c->incipher->iv_len);
+               if(!EVP_DecryptInit(c->inctx, c->incipher,
+                                       c->inkey + len - c->incipher->key_len,
+                                       c->inkey + len - c->incipher->key_len -
+                                       c->incipher->iv_len)) {
+                       logger(LOG_ERR, _("Error during initialisation of cipher from %s (%s): %s"),
+                                       c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
+                       return false;
+               }
 
                c->status.decryptin = true;
        } else {
@@ -315,7 +315,7 @@ bool send_challenge(connection_t *c)
 
        /* Copy random data to the buffer */
 
-       RAND_bytes(c->hischallenge, len);
+       RAND_pseudo_bytes(c->hischallenge, len);
 
        /* Convert to hex */
 
@@ -375,10 +375,13 @@ bool send_chal_reply(connection_t *c)
 
        /* Calculate the hash from the challenge we received */
 
-       EVP_DigestInit(&ctx, c->indigest);
-       EVP_DigestUpdate(&ctx, c->mychallenge,
-                                        RSA_size(myself->connection->rsa_key));
-       EVP_DigestFinal(&ctx, hash, NULL);
+       if(!EVP_DigestInit(&ctx, c->indigest)
+                       || !EVP_DigestUpdate(&ctx, c->mychallenge, RSA_size(myself->connection->rsa_key))
+                       || !EVP_DigestFinal(&ctx, hash, NULL)) {
+               logger(LOG_ERR, _("Error during calculation of response for %s (%s): %s"),
+                       c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
+               return false;
+       }
 
        /* Convert the hash to a hexadecimal formatted string */
 
@@ -418,9 +421,13 @@ bool chal_reply_h(connection_t *c)
 
        /* Calculate the hash from the challenge we sent */
 
-       EVP_DigestInit(&ctx, c->outdigest);
-       EVP_DigestUpdate(&ctx, c->hischallenge, RSA_size(c->rsa_key));
-       EVP_DigestFinal(&ctx, myhash, NULL);
+       if(!EVP_DigestInit(&ctx, c->outdigest)
+                       || !EVP_DigestUpdate(&ctx, c->hischallenge, RSA_size(c->rsa_key))
+                       || !EVP_DigestFinal(&ctx, myhash, NULL)) {
+               logger(LOG_ERR, _("Error during calculation of response from %s (%s): %s"),
+                       c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
+               return false;
+       }
 
        /* Verify the incoming hash with the calculated hash */
 
@@ -452,6 +459,7 @@ bool send_ack(connection_t *c)
           to create node_t and edge_t structures. */
 
        struct timeval now;
+       bool choice;
 
        cp();
 
@@ -460,6 +468,19 @@ bool send_ack(connection_t *c)
        gettimeofday(&now, NULL);
        c->estimated_weight = (now.tv_sec - c->start.tv_sec) * 1000 + (now.tv_usec - c->start.tv_usec) / 1000;
 
+       /* Check some options */
+
+       if((get_config_bool(lookup_config(c->config_tree, "IndirectData"), &choice) && choice) || myself->options & OPTION_INDIRECT)
+               c->options |= OPTION_INDIRECT;
+
+       if((get_config_bool(lookup_config(c->config_tree, "TCPOnly"), &choice) && choice) || myself->options & OPTION_TCPONLY)
+               c->options |= OPTION_TCPONLY | OPTION_INDIRECT;
+
+       if((get_config_bool(lookup_config(c->config_tree, "PMTUDiscovery"), &choice) && choice) || myself->options & OPTION_PMTU_DISCOVERY)
+               c->options |= OPTION_PMTU_DISCOVERY;
+
+       get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight);
+
        return send_request(c, "%d %s %d %lx", ACK, myport, c->estimated_weight, c->options);
 }
 
@@ -472,16 +493,25 @@ static void send_everything(connection_t *c)
 
        /* Send all known subnets and edges */
 
+       if(tunnelserver) {
+               for(node = myself->subnet_tree->head; node; node = node->next) {
+                       s = node->data;
+                       send_add_subnet(c, s);
+               }
+
+               return;
+       }
+
        for(node = node_tree->head; node; node = node->next) {
-               n = (node_t *) node->data;
+               n = node->data;
 
                for(node2 = n->subnet_tree->head; node2; node2 = node2->next) {
-                       s = (subnet_t *) node2->data;
+                       s = node2->data;
                        send_add_subnet(c, s);
                }
 
                for(node2 = n->edge_tree->head; node2; node2 = node2->next) {
-                       e = (edge_t *) node2->data;
+                       e = node2->data;
                        send_add_edge(c, e);
                }
        }
@@ -491,7 +521,7 @@ bool ack_h(connection_t *c)
 {
        char hisport[MAX_STRING_SIZE];
        char *hisaddress, *dummy;
-       int weight;
+       int weight, mtu;
        long int options;
        node_t *n;
 
@@ -526,6 +556,12 @@ bool ack_h(connection_t *c)
        c->node = n;
        c->options |= options;
 
+       if(get_config_int(lookup_config(c->config_tree, "PMTU"), &mtu) && mtu < n->mtu)
+               n->mtu = mtu;
+
+       if(get_config_int(lookup_config(myself->connection->config_tree, "PMTU"), &mtu) && mtu < n->mtu)
+               n->mtu = mtu;
+
        /* Activate this connection */
 
        c->allow_request = ALL;
@@ -556,7 +592,10 @@ bool ack_h(connection_t *c)
 
        /* Notify everyone of the new edge */
 
-       send_add_edge(broadcast, c->edge);
+       if(tunnelserver)
+               send_add_edge(c, c->edge);
+       else
+               send_add_edge(broadcast, c->edge);
 
        /* Run MST and SSSP algorithms */
 
index 4d4276a..9d8443c 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: protocol_edge.c,v 1.4 2003/08/24 20:38:27 guus Exp $
+    $Id: protocol_edge.c,v 1.1.4.23 2003/11/17 15:30:18 guus Exp $
 */
 
 #include "system.h"
@@ -110,6 +110,9 @@ bool add_edge_h(connection_t *c)
                node_add(to);
        }
 
+       if(tunnelserver && from != myself && from != c->node && to != myself && to != c->node)
+               return false;
+
        /* Convert addresses */
 
        address = str2sockaddr(to_address, to_port);
@@ -154,7 +157,8 @@ bool add_edge_h(connection_t *c)
 
        /* Tell the rest about the new edge */
 
-       forward_request(c);
+       if(!tunnelserver)
+               forward_request(c);
 
        /* Run MST before or after we tell the rest? */
 
@@ -221,6 +225,9 @@ bool del_edge_h(connection_t *c)
                return true;
        }
 
+       if(tunnelserver && from != myself && from != c->node && to != myself && to != c->node)
+               return false;
+
        /* Check if edge exists */
 
        e = lookup_edge(from, to);
@@ -240,7 +247,8 @@ bool del_edge_h(connection_t *c)
 
        /* Tell the rest about the deleted edge */
 
-       forward_request(c);
+       if(!tunnelserver)
+               forward_request(c);
 
        /* Delete the edge */
 
@@ -250,5 +258,16 @@ bool del_edge_h(connection_t *c)
 
        graph();
 
+       /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */
+
+       if(!to->status.reachable) {
+               e = lookup_edge(to, myself);
+               if(e) {
+                       if(!tunnelserver)
+                               send_del_edge(broadcast, e);
+                       edge_del(e);
+               }
+       }
+
        return true;
 }
index 6f64990..5067a81 100644 (file)
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: protocol_key.c,v 1.4 2003/08/24 20:38:27 guus Exp $
+    $Id: protocol_key.c,v 1.1.4.26 2003/12/20 21:25:17 guus Exp $
 */
 
 #include "system.h"
 
+#include <openssl/evp.h>
+#include <openssl/err.h>
+
 #include "avl_tree.h"
 #include "connection.h"
 #include "logger.h"
@@ -77,7 +80,8 @@ bool key_changed_h(connection_t *c)
 
        /* Tell the others */
 
-       forward_request(c);
+       if(!tunnelserver)
+               forward_request(c);
 
        return true;
 }
@@ -127,6 +131,9 @@ bool req_key_h(connection_t *c)
                memset(from->late, 0, sizeof(from->late));
                send_ans_key(c, myself, from);
        } else {
+               if(tunnelserver)
+                       return false;
+
                send_req_key(to->nexthop->connection, from, to);
        }
 
@@ -186,6 +193,9 @@ bool ans_key_h(connection_t *c)
        /* Forward it if necessary */
 
        if(to != myself) {
+               if(tunnelserver)
+                       return false;
+
                return send_request(to->nexthop->connection, "%s", c->buffer);
        }
 
@@ -251,7 +261,14 @@ bool ans_key_h(connection_t *c)
        from->compression = compression;
 
        if(from->cipher)
-               EVP_EncryptInit_ex(&from->packet_ctx, from->cipher, NULL, from->key, from->key + from->cipher->key_len);
+               if(!EVP_EncryptInit_ex(&from->packet_ctx, from->cipher, NULL, from->key, from->key + from->cipher->key_len)) {
+                       logger(LOG_ERR, _("Error during initialisation of key from %s (%s): %s"),
+                                       from->name, from->hostname, ERR_error_string(ERR_get_error(), NULL));
+                       return false;
+               }
+
+       if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuprobes)
+               send_mtu_probe(from);
 
        flush_queue(from);
 
index f463f28..66f8980 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: protocol_misc.c,v 1.4 2003/08/24 20:38:27 guus Exp $
+    $Id: protocol_misc.c,v 1.1.4.13 2003/07/24 12:08:16 guus Exp $
 */
 
 #include "system.h"
index b3e7e8c..76cdd49 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: protocol_subnet.c,v 1.4 2003/08/24 20:38:27 guus Exp $
+    $Id: protocol_subnet.c,v 1.1.4.18 2003/12/12 19:52:25 guus Exp $
 */
 
 #include "system.h"
 
 bool send_add_subnet(connection_t *c, const subnet_t *subnet)
 {
-       bool x;
-       char *netstr;
+       char netstr[MAXNETSTR];
 
        cp();
 
-       x = send_request(c, "%d %lx %s %s", ADD_SUBNET, random(),
-                                        subnet->owner->name, netstr = net2str(subnet));
-
-       free(netstr);
+       if(!net2str(netstr, sizeof netstr, subnet))
+               return false;
 
-       return x;
+       return send_request(c, "%d %lx %s %s", ADD_SUBNET, random(), subnet->owner->name, netstr);
 }
 
 bool add_subnet_h(connection_t *c)
@@ -53,7 +50,7 @@ bool add_subnet_h(connection_t *c)
        char subnetstr[MAX_STRING_SIZE];
        char name[MAX_STRING_SIZE];
        node_t *owner;
-       subnet_t *s;
+       subnet_t s = {0}, *new;
 
        cp();
 
@@ -73,9 +70,7 @@ bool add_subnet_h(connection_t *c)
 
        /* Check if subnet string is valid */
 
-       s = str2net(subnetstr);
-
-       if(!s) {
+       if(!str2net(&s, subnetstr)) {
                logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_SUBNET", c->name,
                           c->hostname, _("invalid subnet string"));
                return false;
@@ -94,48 +89,69 @@ bool add_subnet_h(connection_t *c)
                node_add(owner);
        }
 
+       if(tunnelserver && owner != myself && owner != c->node)
+               return false;
+
        /* Check if we already know this subnet */
 
-       if(lookup_subnet(owner, s)) {
-               free_subnet(s);
+       if(lookup_subnet(owner, &s))
                return true;
-       }
 
        /* If we don't know this subnet, but we are the owner, retaliate with a DEL_SUBNET */
 
        if(owner == myself) {
                ifdebug(PROTOCOL) logger(LOG_WARNING, _("Got %s from %s (%s) for ourself"),
                                   "ADD_SUBNET", c->name, c->hostname);
-               s->owner = myself;
-               send_del_subnet(c, s);
+               s.owner = myself;
+               send_del_subnet(c, &s);
                return true;
        }
 
+       /* In tunnel server mode, check if the subnet matches one in the config file of this node */
+
+       if(tunnelserver) {
+               config_t *cfg;
+               subnet_t *allowed;
+
+               for(cfg = lookup_config(c->config_tree, "Subnet"); cfg; cfg = lookup_config_next(c->config_tree, cfg)) {
+                       if(!get_config_subnet(cfg, &allowed))
+                               return false;
+
+                       if(!subnet_compare(&s, allowed))
+                               break;
+
+                       free_subnet(allowed);
+               }
+
+               if(!cfg)
+                       return false;
+
+               free_subnet(allowed);
+       }
+
        /* If everything is correct, add the subnet to the list of the owner */
 
-       subnet_add(owner, s);
+       *(new = new_subnet()) = s;
+       subnet_add(owner, new);
 
        /* Tell the rest */
 
-       forward_request(c);
+       if(!tunnelserver)
+               forward_request(c);
 
        return true;
 }
 
 bool send_del_subnet(connection_t *c, const subnet_t *s)
 {
-       bool x;
-       char *netstr;
+       char netstr[MAXNETSTR];
 
        cp();
 
-       netstr = net2str(s);
-
-       x = send_request(c, "%d %lx %s %s", DEL_SUBNET, random(), s->owner->name, netstr);
-
-       free(netstr);
+       if(!net2str(netstr, sizeof netstr, s))
+               return false;
 
-       return x;
+       return send_request(c, "%d %lx %s %s", DEL_SUBNET, random(), s->owner->name, netstr);
 }
 
 bool del_subnet_h(connection_t *c)
@@ -143,7 +159,7 @@ bool del_subnet_h(connection_t *c)
        char subnetstr[MAX_STRING_SIZE];
        char name[MAX_STRING_SIZE];
        node_t *owner;
-       subnet_t *s, *find;
+       subnet_t s = {0}, *find;
 
        cp();
 
@@ -171,11 +187,12 @@ bool del_subnet_h(connection_t *c)
                return true;
        }
 
-       /* Check if subnet string is valid */
+       if(tunnelserver && owner != myself && owner != c->node)
+               return false;
 
-       s = str2net(subnetstr);
+       /* Check if subnet string is valid */
 
-       if(!s) {
+       if(!str2net(&s, subnetstr)) {
                logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_SUBNET", c->name,
                           c->hostname, _("invalid subnet string"));
                return false;
@@ -186,11 +203,9 @@ bool del_subnet_h(connection_t *c)
 
        /* If everything is correct, delete the subnet from the list of the owner */
 
-       s->owner = owner;
-
-       find = lookup_subnet(owner, s);
+       s.owner = owner;
 
-       free_subnet(s);
+       find = lookup_subnet(owner, &s);
 
        if(!find) {
                ifdebug(PROTOCOL) logger(LOG_WARNING, _("Got %s from %s (%s) for %s which does not appear in his subnet tree"),
@@ -209,7 +224,8 @@ bool del_subnet_h(connection_t *c)
 
        /* Tell the rest */
 
-       forward_request(c);
+       if(!tunnelserver)
+               forward_request(c);
 
        /* Finally, delete it. */
 
index e613b9e..1bece59 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: device.c,v 1.3 2003/08/27 13:47:52 guus Exp $
+    $Id: device.c,v 1.1.2.9 2003/07/31 11:31:51 guus Exp $
 */
 
 #include "config.h"
index 191765d..8f238e2 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: route.c,v 1.4 2003/08/24 20:38:28 guus Exp $
+    $Id: route.c,v 1.1.2.75 2003/12/24 10:48:15 guus Exp $
 */
 
 #include "system.h"
@@ -40,7 +40,6 @@
 
 #include "avl_tree.h"
 #include "connection.h"
-#include "device.h"
 #include "ethernet.h"
 #include "ipv4.h"
 #include "ipv6.h"
@@ -57,9 +56,20 @@ int macexpire = 600;
 bool overwrite_mac = false;
 mac_t mymac = {{0xFE, 0xFD, 0, 0, 0, 0}};
 
+/* Sizes of various headers */
+
+static const size_t ether_size = sizeof(struct ether_header);
+static const size_t arp_size = sizeof(struct ether_arp);
+static const size_t ip_size = sizeof(struct ip);
+static const size_t icmp_size = sizeof(struct icmp) - sizeof(struct ip);
+static const size_t ip6_size = sizeof(struct ip6_hdr);
+static const size_t icmp6_size = sizeof(struct icmp6_hdr);
+static const size_t ns_size = sizeof(struct nd_neighbor_solicit);
+static const size_t opt_size = sizeof(struct nd_opt_hdr);
+
 /* RFC 1071 */
 
-static uint16_t inet_checksum(void *data, int len, uint16_t prevsum)
+static __inline__ uint16_t inet_checksum(void *data, int len, uint16_t prevsum)
 {
        uint16_t *p = data;
        uint32_t checksum = prevsum ^ 0xFFFF;
@@ -70,7 +80,7 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum)
        }
        
        if(len)
-               checksum += *(unsigned char *)p;
+               checksum += *(uint8_t *)p;
 
        while(checksum >> 16)
                checksum = (checksum & 0xFFFF) + (checksum >> 16);
@@ -78,17 +88,30 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum)
        return ~checksum;
 }
 
-static bool ratelimit(void) {
+static __inline__ bool ratelimit(int frequency) {
        static time_t lasttime = 0;
+       static int count = 0;
        
-       if(lasttime == now)
-               return true;
+       if(lasttime == now) {
+               if(++count > frequency)
+                       return true;
+       } else {
+               lasttime = now;
+               count = 0;
+       }
 
-       lasttime = now;
        return false;
 }
+
+static __inline__ bool checklength(node_t *source, vpn_packet_t *packet, length_t length) {
+       if(packet->len < length) {
+               ifdebug(TRAFFIC) logger(LOG_WARNING, _("Got too short packet from %s (%s)"), source->name, source->hostname);
+               return false;
+       } else
+               return true;
+}
        
-static void learn_mac(mac_t *address)
+static __inline__ void learn_mac(mac_t *address)
 {
        subnet_t *subnet;
        avl_node_t *node;
@@ -100,29 +123,31 @@ static void learn_mac(mac_t *address)
 
        /* If we don't know this MAC address yet, store it */
 
-       if(!subnet || subnet->owner != myself) {
+       if(!subnet) {
                ifdebug(TRAFFIC) logger(LOG_INFO, _("Learned new MAC address %hx:%hx:%hx:%hx:%hx:%hx"),
                                   address->x[0], address->x[1], address->x[2], address->x[3],
                                   address->x[4], address->x[5]);
 
                subnet = new_subnet();
                subnet->type = SUBNET_MAC;
-               memcpy(&subnet->net.mac.address, address, sizeof(mac_t));
+               subnet->expires = now + macexpire;
+               subnet->net.mac.address = *address;
                subnet_add(myself, subnet);
 
                /* And tell all other tinc daemons it's our MAC */
 
                for(node = connection_tree->head; node; node = node->next) {
-                       c = (connection_t *) node->data;
+                       c = node->data;
                        if(c->status.active)
                                send_add_subnet(c, subnet);
                }
        }
 
-       subnet->net.mac.lastseen = now;
+       if(subnet->expires)
+               subnet->expires = now + macexpire;
 }
 
-void age_mac(void)
+void age_subnets(void)
 {
        subnet_t *s;
        connection_t *c;
@@ -132,15 +157,16 @@ void age_mac(void)
 
        for(node = myself->subnet_tree->head; node; node = next) {
                next = node->next;
-               s = (subnet_t *) node->data;
-               if(s->type == SUBNET_MAC && s->net.mac.lastseen && s->net.mac.lastseen + macexpire < now) {
-                       ifdebug(TRAFFIC) logger(LOG_INFO, _("MAC address %hx:%hx:%hx:%hx:%hx:%hx expired"),
-                                          s->net.mac.address.x[0], s->net.mac.address.x[1],
-                                          s->net.mac.address.x[2], s->net.mac.address.x[3],
-                                          s->net.mac.address.x[4], s->net.mac.address.x[5]);
+               s = node->data;
+               if(s->expires && s->expires < now) {
+                       ifdebug(TRAFFIC) {
+                               char netstr[MAXNETSTR];
+                               if(net2str(netstr, sizeof netstr, s))
+                                       logger(LOG_INFO, _("Subnet %s expired"), netstr);
+                       }
 
                        for(node2 = connection_tree->head; node2; node2 = node2->next) {
-                               c = (connection_t *) node2->data;
+                               c = node2->data;
                                if(c->status.active)
                                        send_del_subnet(c, s);
                        }
@@ -150,7 +176,7 @@ void age_mac(void)
        }
 }
 
-static node_t *route_mac(vpn_packet_t *packet)
+static __inline__ void route_mac(node_t *source, vpn_packet_t *packet)
 {
        subnet_t *subnet;
 
@@ -158,111 +184,215 @@ static node_t *route_mac(vpn_packet_t *packet)
 
        /* Learn source address */
 
-       learn_mac((mac_t *)(&packet->data[6]));
+       if(source == myself)
+               learn_mac((mac_t *)(&packet->data[6]));
 
        /* Lookup destination address */
 
        subnet = lookup_subnet_mac((mac_t *)(&packet->data[0]));
 
-       if(subnet)
-               return subnet->owner;
-       else
-               return NULL;
+       if(!subnet) {
+               broadcast_packet(source, packet);
+               return;
+       }
+
+       if(subnet->owner == source) {
+               ifdebug(TRAFFIC) logger(LOG_WARNING, _("Packet looping back to %s (%s)!"), source->name, source->hostname);
+               return;
+       }
+
+       send_packet(subnet->owner, packet);
 }
 
 /* RFC 792 */
 
-static void route_ipv4_unreachable(vpn_packet_t *packet, uint8_t code)
+static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code)
 {
-       struct ip *hdr;
-       struct icmp *icmp;
+       struct ip ip = {0};
+       struct icmp icmp = {0};
        
        struct in_addr ip_src;
        struct in_addr ip_dst;
        uint32_t oldlen;
 
-       if(ratelimit())
+       if(ratelimit(3))
                return;
        
        cp();
 
-       hdr = (struct ip *)(packet->data + 14);
-       icmp = (struct icmp *)(packet->data + 14 + 20);
+       /* Copy headers from packet into properly aligned structs on the stack */
+
+       memcpy(&ip, packet->data + ether_size, ip_size);
 
        /* Remember original source and destination */
-               
-       memcpy(&ip_src, &hdr->ip_src, 4);
-       memcpy(&ip_dst, &hdr->ip_dst, 4);
-       oldlen = packet->len - 14;
        
-       if(oldlen >= IP_MSS - sizeof(*hdr) - sizeof(*icmp))
-               oldlen = IP_MSS - sizeof(*hdr) - sizeof(*icmp);
+       ip_src = ip.ip_src;
+       ip_dst = ip.ip_dst;
+
+       oldlen = packet->len - ether_size;
+
+       if(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
+               icmp.icmp_nextmtu = htons(packet->len - ether_size);
+
+       if(oldlen >= IP_MSS - ip_size - icmp_size)
+               oldlen = IP_MSS - ip_size - icmp_size;
        
        /* Copy first part of original contents to ICMP message */
        
-       memmove(&icmp->icmp_ip, hdr, oldlen);
+       memmove(packet->data + ether_size + ip_size + icmp_size, packet->data + ether_size, oldlen);
 
        /* Fill in IPv4 header */
        
-       hdr->ip_v = 4;
-       hdr->ip_hl = sizeof(*hdr) / 4;
-       hdr->ip_tos = 0;
-       hdr->ip_len = htons(20 + 8 + oldlen);
-       hdr->ip_id = 0;
-       hdr->ip_off = 0;
-       hdr->ip_ttl = 255;
-       hdr->ip_p = IPPROTO_ICMP;
-       hdr->ip_sum = 0;
-       memcpy(&hdr->ip_src, &ip_dst, 4);
-       memcpy(&hdr->ip_dst, &ip_src, 4);
-
-       hdr->ip_sum = inet_checksum(hdr, 20, ~0);
+       ip.ip_v = 4;
+       ip.ip_hl = ip_size / 4;
+       ip.ip_tos = 0;
+       ip.ip_len = htons(ip_size + icmp_size + oldlen);
+       ip.ip_id = 0;
+       ip.ip_off = 0;
+       ip.ip_ttl = 255;
+       ip.ip_p = IPPROTO_ICMP;
+       ip.ip_sum = 0;
+       ip.ip_src = ip_dst;
+       ip.ip_dst = ip_src;
+
+       ip.ip_sum = inet_checksum(&ip, ip_size, ~0);
        
        /* Fill in ICMP header */
        
-       icmp->icmp_type = ICMP_DEST_UNREACH;
-       icmp->icmp_code = code;
-       icmp->icmp_cksum = 0;
+       icmp.icmp_type = type;
+       icmp.icmp_code = code;
+       icmp.icmp_cksum = 0;
+       
+       icmp.icmp_cksum = inet_checksum(&icmp, icmp_size, ~0);
+       icmp.icmp_cksum = inet_checksum(packet->data + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum);
+
+       /* Copy structs on stack back to packet */
+
+       memcpy(packet->data + ether_size, &ip, ip_size);
+       memcpy(packet->data + ether_size + ip_size, &icmp, icmp_size);
        
-       icmp->icmp_cksum = inet_checksum(icmp, 8 + oldlen, ~0);
+       packet->len = ether_size + ip_size + icmp_size + oldlen;
+
+       send_packet(source, packet);
+}
+
+/* RFC 791 */
+
+static __inline__ void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet) {
+       struct ip ip;
+       vpn_packet_t fragment;
+       int len, maxlen, todo;
+       uint8_t *offset;
+       uint16_t ip_off, origf;
        
-       packet->len = 14 + 20 + 8 + oldlen;
+       cp();
+
+       memcpy(&ip, packet->data + ether_size, ip_size);
+       fragment.priority = packet->priority;
+
+       if(ip.ip_hl != ip_size / 4)
+               return;
        
-       write_packet(packet);
+       todo = ntohs(ip.ip_len) - ip_size;
+
+       if(ether_size + ip_size + todo != packet->len) {
+               ifdebug(TRAFFIC) logger(LOG_WARNING, _("Length of packet (%d) doesn't match length in IPv4 header (%d)"), packet->len, ether_size + ip_size + todo);
+               return;
+       }
+
+       ifdebug(TRAFFIC) logger(LOG_INFO, _("Fragmenting packet of %d bytes to %s (%s)"), packet->len, dest->name, dest->hostname);
+
+       offset = packet->data + ether_size + ip_size;
+       maxlen = (dest->mtu - ether_size - ip_size) & ~0x7;
+       ip_off = ntohs(ip.ip_off);
+       origf = ip_off & ~IP_OFFMASK;
+       ip_off &= IP_OFFMASK;
+       
+       while(todo) {
+               len = todo > maxlen ? maxlen : todo;
+               memcpy(fragment.data + ether_size + ip_size, offset, len);
+               todo -= len;
+               offset += len;
+
+               ip.ip_len = htons(ip_size + len);
+               ip.ip_off = htons(ip_off | origf | (todo ? IP_MF : 0));
+               ip.ip_sum = 0;
+               ip.ip_sum = inet_checksum(&ip, ip_size, ~0);
+               memcpy(fragment.data, packet->data, ether_size);
+               memcpy(fragment.data + ether_size, &ip, ip_size);
+               fragment.len = ether_size + ip_size + len;
+
+               send_packet(dest, &fragment);
+
+               ip_off += len / 8;
+       }       
 }
 
-static node_t *route_ipv4(vpn_packet_t *packet)
+static __inline__ void route_ipv4_unicast(node_t *source, vpn_packet_t *packet)
 {
        subnet_t *subnet;
+       node_t *via;
 
        cp();
 
-       if(priorityinheritance)
-               packet->priority = packet->data[15];
-
-       subnet = lookup_subnet_ipv4((ipv4_t *) & packet->data[30]);
+       subnet = lookup_subnet_ipv4((ipv4_t *) &packet->data[30]);
 
        if(!subnet) {
-               ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: unknown IPv4 destination address %d.%d.%d.%d"),
-                                  packet->data[30], packet->data[31], packet->data[32],
-                                  packet->data[33]);
-
-               route_ipv4_unreachable(packet, ICMP_NET_UNKNOWN);
-               return NULL;
+               ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet from %s (%s): unknown IPv4 destination address %d.%d.%d.%d"),
+                               source->name, source->hostname,
+                               packet->data[30],
+                               packet->data[31],
+                               packet->data[32],
+                               packet->data[33]);
+
+               route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN);
+               return;
        }
        
+       if(subnet->owner == source) {
+               ifdebug(TRAFFIC) logger(LOG_WARNING, _("Packet looping back to %s (%s)!"), source->name, source->hostname);
+               return;
+       }
+
        if(!subnet->owner->status.reachable)
-               route_ipv4_unreachable(packet, ICMP_NET_UNREACH);
+               route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNREACH);
 
-       return subnet->owner;
+       if(priorityinheritance)
+               packet->priority = packet->data[15];
+
+       via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
+       
+       if(packet->len > via->mtu && via != myself) {
+               ifdebug(TRAFFIC) logger(LOG_INFO, _("Packet for %s (%s) length %d larger than MTU %d"), subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
+               if(packet->data[20] & 0x40) {
+                       packet->len = via->mtu;
+                       route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
+               } else {
+                       fragment_ipv4_packet(via, packet);
+               }
+
+               return;
+       }
+
+       send_packet(subnet->owner, packet);
+}
+
+static __inline__ void route_ipv4(node_t *source, vpn_packet_t *packet)
+{
+       cp();
+
+       if(!checklength(source, packet, ether_size + ip_size))
+               return;
+
+       route_ipv4_unicast(source, packet);
 }
 
 /* RFC 2463 */
 
-static void route_ipv6_unreachable(vpn_packet_t *packet, uint8_t code)
+static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code)
 {
-       struct ip6_hdr *hdr;
-       struct icmp6_hdr *icmp;
+       struct ip6_hdr ip6;
+       struct icmp6_hdr icmp6 = {0};
        uint16_t checksum;      
 
        struct {
@@ -272,95 +402,122 @@ static void route_ipv6_unreachable(vpn_packet_t *packet, uint8_t code)
                uint32_t next;
        } pseudo;
 
-       if(ratelimit())
+       if(ratelimit(3))
                return;
        
        cp();
 
-       hdr = (struct ip6_hdr *)(packet->data + 14);
-       icmp = (struct icmp6_hdr *)(packet->data + 14 + sizeof(*hdr));
+       /* Copy headers from packet to structs on the stack */
+
+       memcpy(&ip6, packet->data + ether_size, ip6_size);
 
        /* Remember original source and destination */
-               
-       memcpy(&pseudo.ip6_src, &hdr->ip6_dst, 16);
-       memcpy(&pseudo.ip6_dst, &hdr->ip6_src, 16);
-       pseudo.length = ntohs(hdr->ip6_plen) + sizeof(*hdr);
        
-       if(pseudo.length >= IP_MSS - sizeof(*hdr) - sizeof(*icmp))
-               pseudo.length = IP_MSS - sizeof(*hdr) - sizeof(*icmp);
+       pseudo.ip6_src = ip6.ip6_dst;
+       pseudo.ip6_dst = ip6.ip6_src;
+
+       pseudo.length = packet->len - ether_size;
+
+       if(type == ICMP6_PACKET_TOO_BIG)
+               icmp6.icmp6_mtu = htonl(pseudo.length);
+       
+       if(pseudo.length >= IP_MSS - ip6_size - icmp6_size)
+               pseudo.length = IP_MSS - ip6_size - icmp6_size;
        
        /* Copy first part of original contents to ICMP message */
        
-       memmove(((char *)icmp) + sizeof(*icmp), hdr, pseudo.length);
+       memmove(packet->data + ether_size + ip6_size + icmp6_size, packet->data + ether_size, pseudo.length);
 
        /* Fill in IPv6 header */
        
-       hdr->ip6_flow = htonl(0x60000000UL);
-       hdr->ip6_plen = htons(sizeof(*icmp) + pseudo.length);
-       hdr->ip6_nxt = IPPROTO_ICMPV6;
-       hdr->ip6_hlim = 255;
-       memcpy(&hdr->ip6_dst, &pseudo.ip6_dst, 16);
-       memcpy(&hdr->ip6_src, &pseudo.ip6_src, 16);
+       ip6.ip6_flow = htonl(0x60000000UL);
+       ip6.ip6_plen = htons(icmp6_size + pseudo.length);
+       ip6.ip6_nxt = IPPROTO_ICMPV6;
+       ip6.ip6_hlim = 255;
+       ip6.ip6_src = pseudo.ip6_src;
+       ip6.ip6_dst = pseudo.ip6_dst;
 
        /* Fill in ICMP header */
        
-       icmp->icmp6_type = ICMP6_DST_UNREACH;
-       icmp->icmp6_code = code;
-       icmp->icmp6_cksum = 0;
+       icmp6.icmp6_type = type;
+       icmp6.icmp6_code = code;
+       icmp6.icmp6_cksum = 0;
 
        /* Create pseudo header */
                
-       pseudo.length = htonl(sizeof(*icmp) + pseudo.length);
+       pseudo.length = htonl(icmp6_size + pseudo.length);
        pseudo.next = htonl(IPPROTO_ICMPV6);
 
        /* Generate checksum */
        
        checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0);
-       checksum = inet_checksum(icmp, ntohl(pseudo.length), checksum);
+       checksum = inet_checksum(&icmp6, icmp6_size, checksum);
+       checksum = inet_checksum(packet->data + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum);
 
-       icmp->icmp6_cksum = checksum;
+       icmp6.icmp6_cksum = checksum;
+
+       /* Copy structs on stack back to packet */
+
+       memcpy(packet->data + ether_size, &ip6, ip6_size);
+       memcpy(packet->data + ether_size + ip6_size, &icmp6, icmp6_size);
        
-       packet->len = 14 + sizeof(*hdr) + ntohl(pseudo.length);
+       packet->len = ether_size + ip6_size + ntohl(pseudo.length);
        
-       write_packet(packet);
+       send_packet(source, packet);
 }
 
-static node_t *route_ipv6(vpn_packet_t *packet)
+static __inline__ void route_ipv6_unicast(node_t *source, vpn_packet_t *packet)
 {
        subnet_t *subnet;
+       node_t *via;
 
        cp();
 
-       subnet = lookup_subnet_ipv6((ipv6_t *) & packet->data[38]);
+       subnet = lookup_subnet_ipv6((ipv6_t *) &packet->data[38]);
 
        if(!subnet) {
-               ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"),
-                                  ntohs(*(uint16_t *) & packet->data[38]),
-                                  ntohs(*(uint16_t *) & packet->data[40]),
-                                  ntohs(*(uint16_t *) & packet->data[42]),
-                                  ntohs(*(uint16_t *) & packet->data[44]),
-                                  ntohs(*(uint16_t *) & packet->data[46]),
-                                  ntohs(*(uint16_t *) & packet->data[48]),
-                                  ntohs(*(uint16_t *) & packet->data[50]),
-                                  ntohs(*(uint16_t *) & packet->data[52]));
-               route_ipv6_unreachable(packet, ICMP6_DST_UNREACH_ADDR);
-
-               return NULL;
+               ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet from %s (%s): unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"),
+                               source->name, source->hostname,
+                               ntohs(*(uint16_t *) &packet->data[38]),
+                               ntohs(*(uint16_t *) &packet->data[40]),
+                               ntohs(*(uint16_t *) &packet->data[42]),
+                               ntohs(*(uint16_t *) &packet->data[44]),
+                               ntohs(*(uint16_t *) &packet->data[46]),
+                               ntohs(*(uint16_t *) &packet->data[48]),
+                               ntohs(*(uint16_t *) &packet->data[50]),
+                               ntohs(*(uint16_t *) &packet->data[52]));
+
+               route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR);
+               return;
+       }
+
+       if(subnet->owner == source) {
+               ifdebug(TRAFFIC) logger(LOG_WARNING, _("Packet looping back to %s (%s)!"), source->name, source->hostname);
+               return;
        }
 
        if(!subnet->owner->status.reachable)
-               route_ipv6_unreachable(packet, ICMP6_DST_UNREACH_NOROUTE);
+               route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
+
+       via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
        
-       return subnet->owner;
+       if(packet->len > via->mtu && via != myself) {
+               ifdebug(TRAFFIC) logger(LOG_INFO, _("Packet for %s (%s) length %d larger than MTU %d"), subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
+               packet->len = via->mtu;
+               route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0);
+               return;
+       }
+
+       send_packet(subnet->owner, packet);
 }
 
 /* RFC 2461 */
 
-static void route_neighborsol(vpn_packet_t *packet)
+static void route_neighborsol(node_t *source, vpn_packet_t *packet)
 {
-       struct ip6_hdr *hdr;
-       struct nd_neighbor_solicit *ns;
-       struct nd_opt_hdr *opt;
+       struct ip6_hdr ip6;
+       struct nd_neighbor_solicit ns;
+       struct nd_opt_hdr opt;
        subnet_t *subnet;
        uint16_t checksum;
 
@@ -373,34 +530,46 @@ static void route_neighborsol(vpn_packet_t *packet)
 
        cp();
 
-       hdr = (struct ip6_hdr *)(packet->data + 14);
-       ns = (struct nd_neighbor_solicit *)(packet->data + 14 + sizeof(*hdr));
-       opt = (struct nd_opt_hdr *)(packet->data + 14 + sizeof(*hdr) + sizeof(*ns));
+       if(!checklength(source, packet, ether_size + ip6_size + ns_size + opt_size + ETH_ALEN))
+               return;
+       
+       if(source != myself) {
+               ifdebug(TRAFFIC) logger(LOG_WARNING, _("Got neighbor solicitation request from %s (%s) while in router mode!"), source->name, source->hostname);
+               return;
+       }
+
+       /* Copy headers from packet to structs on the stack */
+
+       memcpy(&ip6, packet->data + ether_size, ip6_size);
+       memcpy(&ns, packet->data + ether_size + ip6_size, ns_size);
+       memcpy(&opt, packet->data + ether_size + ip6_size + ns_size, opt_size);
 
        /* First, snatch the source address from the neighbor solicitation packet */
 
        if(overwrite_mac)
-               memcpy(mymac.x, packet->data + 6, 6);
+               memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN);
 
        /* Check if this is a valid neighbor solicitation request */
 
-       if(ns->nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT ||
-          opt->nd_opt_type != ND_OPT_SOURCE_LINKADDR) {
+       if(ns.nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT ||
+          opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR) {
                ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: received unknown type neighbor solicitation request"));
                return;
        }
 
        /* Create pseudo header */
 
-       memcpy(&pseudo.ip6_src, &hdr->ip6_src, 16);
-       memcpy(&pseudo.ip6_dst, &hdr->ip6_dst, 16);
-       pseudo.length = htonl(sizeof(*ns) + sizeof(*opt) + 6);
+       pseudo.ip6_src = ip6.ip6_src;
+       pseudo.ip6_dst = ip6.ip6_dst;
+       pseudo.length = htonl(ns_size + opt_size + ETH_ALEN);
        pseudo.next = htonl(IPPROTO_ICMPV6);
 
        /* Generate checksum */
 
        checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0);
-       checksum = inet_checksum(ns, sizeof(*ns) + 8, checksum);
+       checksum = inet_checksum(&ns, ns_size, checksum);
+       checksum = inet_checksum(&opt, opt_size, checksum);
+       checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum);
 
        if(checksum) {
                ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: checksum error for neighbor solicitation request"));
@@ -409,18 +578,18 @@ static void route_neighborsol(vpn_packet_t *packet)
 
        /* Check if the IPv6 address exists on the VPN */
 
-       subnet = lookup_subnet_ipv6((ipv6_t *) & ns->nd_ns_target);
+       subnet = lookup_subnet_ipv6((ipv6_t *) &ns.nd_ns_target);
 
        if(!subnet) {
                ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: neighbor solicitation request for unknown address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"),
-                                  ntohs(((uint16_t *) & ns->nd_ns_target)[0]),
-                                  ntohs(((uint16_t *) & ns->nd_ns_target)[1]),
-                                  ntohs(((uint16_t *) & ns->nd_ns_target)[2]),
-                                  ntohs(((uint16_t *) & ns->nd_ns_target)[3]),
-                                  ntohs(((uint16_t *) & ns->nd_ns_target)[4]),
-                                  ntohs(((uint16_t *) & ns->nd_ns_target)[5]),
-                                  ntohs(((uint16_t *) & ns->nd_ns_target)[6]),
-                                  ntohs(((uint16_t *) & ns->nd_ns_target)[7]));
+                                  ntohs(((uint16_t *) &ns.nd_ns_target)[0]),
+                                  ntohs(((uint16_t *) &ns.nd_ns_target)[1]),
+                                  ntohs(((uint16_t *) &ns.nd_ns_target)[2]),
+                                  ntohs(((uint16_t *) &ns.nd_ns_target)[3]),
+                                  ntohs(((uint16_t *) &ns.nd_ns_target)[4]),
+                                  ntohs(((uint16_t *) &ns.nd_ns_target)[5]),
+                                  ntohs(((uint16_t *) &ns.nd_ns_target)[6]),
+                                  ntohs(((uint16_t *) &ns.nd_ns_target)[7]));
 
                return;
        }
@@ -432,77 +601,102 @@ static void route_neighborsol(vpn_packet_t *packet)
 
        /* Create neighbor advertation reply */
 
-       memcpy(packet->data, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN);    /* copy destination address */
-       packet->data[ETHER_ADDR_LEN * 2 - 1] ^= 0xFF;   /* mangle source address so it looks like it's not from us */
+       memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN);        /* copy destination address */
+       packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
 
-       memcpy(&hdr->ip6_dst, &hdr->ip6_src, 16);       /* swap destination and source protocol address */
-       memcpy(&hdr->ip6_src, &ns->nd_ns_target, 16);   /* ... */
+       ip6.ip6_dst = ip6.ip6_src;                      /* swap destination and source protocoll address */
+       ip6.ip6_src = ns.nd_ns_target;
 
-       memcpy((char *) opt + sizeof(*opt), packet->data + ETHER_ADDR_LEN, 6);  /* add fake source hard addr */
+       memcpy(packet->data + ether_size + ip6_size + ns_size + opt_size, packet->data + ETH_ALEN, ETH_ALEN);   /* add fake source hard addr */
 
-       ns->nd_ns_hdr.icmp6_cksum = 0;
-       ns->nd_ns_hdr.icmp6_type = ND_NEIGHBOR_ADVERT;
-       ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[0] = 0x40;    /* Set solicited flag */
-       ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[1] =
-               ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[2] =
-               ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[3] = 0;
-       opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
+       ns.nd_ns_cksum = 0;
+       ns.nd_ns_type = ND_NEIGHBOR_ADVERT;
+       ns.nd_ns_reserved = htonl(0x40000000UL);        /* Set solicited flag */
+       opt.nd_opt_type = ND_OPT_TARGET_LINKADDR;
 
        /* Create pseudo header */
 
-       memcpy(&pseudo.ip6_src, &hdr->ip6_src, 16);
-       memcpy(&pseudo.ip6_dst, &hdr->ip6_dst, 16);
-       pseudo.length = htonl(sizeof(*ns) + sizeof(*opt) + 6);
+       pseudo.ip6_src = ip6.ip6_src;
+       pseudo.ip6_dst = ip6.ip6_dst;
+       pseudo.length = htonl(ns_size + opt_size + ETH_ALEN);
        pseudo.next = htonl(IPPROTO_ICMPV6);
 
        /* Generate checksum */
 
        checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0);
-       checksum = inet_checksum(ns, sizeof(*ns) + 8, checksum);
+       checksum = inet_checksum(&ns, ns_size, checksum);
+       checksum = inet_checksum(&opt, opt_size, checksum);
+       checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum);
 
-       ns->nd_ns_hdr.icmp6_cksum = checksum;
+       ns.nd_ns_hdr.icmp6_cksum = checksum;
+
+       /* Copy structs on stack back to packet */
+
+       memcpy(packet->data + ether_size, &ip6, ip6_size);
+       memcpy(packet->data + ether_size + ip6_size, &ns, ns_size);
+       memcpy(packet->data + ether_size + ip6_size + ns_size, &opt, opt_size);
+
+       send_packet(source, packet);
+}
+
+static __inline__ void route_ipv6(node_t *source, vpn_packet_t *packet)
+{
+       cp();
+
+       if(!checklength(source, packet, ether_size + ip6_size))
+               return;
+
+       if(packet->data[20] == IPPROTO_ICMPV6 && checklength(source, packet, ether_size + ip6_size + icmp6_size) && packet->data[54] == ND_NEIGHBOR_SOLICIT) {
+               route_neighborsol(source, packet);
+               return;
+       }
 
-       write_packet(packet);
+       route_ipv6_unicast(source, packet);
 }
 
 /* RFC 826 */
 
-static void route_arp(vpn_packet_t *packet)
+static void route_arp(node_t *source, vpn_packet_t *packet)
 {
-       struct ether_arp *arp;
+       struct ether_arp arp;
        subnet_t *subnet;
-       uint8_t ipbuf[4];
+       struct in_addr addr;
 
        cp();
 
+       if(!checklength(source, packet, ether_size + arp_size))
+               return;
+
+       if(source != myself) {
+               ifdebug(TRAFFIC) logger(LOG_WARNING, _("Got ARP request from %s (%s) while in router mode!"), source->name, source->hostname);
+               return;
+       }
+
        /* First, snatch the source address from the ARP packet */
 
        if(overwrite_mac)
-               memcpy(mymac.x, packet->data + 6, 6);
+               memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN);
 
-       /* This routine generates replies to ARP requests.
-          You don't need to set NOARP flag on the interface anymore (which is broken on FreeBSD).
-          Most of the code here is taken from choparp.c by Takamichi Tateoka (tree@mma.club.uec.ac.jp)
-        */
+       /* Copy headers from packet to structs on the stack */
 
-       arp = (struct ether_arp *)(packet->data + 14);
+       memcpy(&arp, packet->data + ether_size, arp_size);
 
        /* Check if this is a valid ARP request */
 
-       if(ntohs(arp->arp_hrd) != ARPHRD_ETHER || ntohs(arp->arp_pro) != ETHERTYPE_IP ||
-          arp->arp_hln != ETHER_ADDR_LEN || arp->arp_pln != 4 || ntohs(arp->arp_op) != ARPOP_REQUEST) {
+       if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP ||
+          arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof(addr) || ntohs(arp.arp_op) != ARPOP_REQUEST) {
                ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: received unknown type ARP request"));
                return;
        }
 
        /* Check if the IPv4 address exists on the VPN */
 
-       subnet = lookup_subnet_ipv4((ipv4_t *) arp->arp_tpa);
+       subnet = lookup_subnet_ipv4((ipv4_t *) &arp.arp_tpa);
 
        if(!subnet) {
                ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: ARP request for unknown address %d.%d.%d.%d"),
-                                  arp->arp_tpa[0], arp->arp_tpa[1], arp->arp_tpa[2],
-                                  arp->arp_tpa[3]);
+                                  arp.arp_tpa[0], arp.arp_tpa[1], arp.arp_tpa[2],
+                                  arp.arp_tpa[3]);
                return;
        }
 
@@ -511,126 +705,63 @@ static void route_arp(vpn_packet_t *packet)
        if(subnet->owner == myself)
                return;                                 /* silently ignore */
 
-       memcpy(packet->data, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN);    /* copy destination address */
-       packet->data[ETHER_ADDR_LEN * 2 - 1] ^= 0xFF;   /* mangle source address so it looks like it's not from us */
+       memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN);        /* copy destination address */
+       packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
+
+       memcpy(&addr, arp.arp_tpa, sizeof(addr));       /* save protocol addr */
+       memcpy(arp.arp_tpa, arp.arp_spa, sizeof(addr)); /* swap destination and source protocol address */
+       memcpy(arp.arp_spa, &addr, sizeof(addr));       /* ... */
+
+       memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN);     /* set target hard/proto addr */
+       memcpy(arp.arp_sha, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */
+       arp.arp_op = htons(ARPOP_REPLY);
 
-       memcpy(ipbuf, arp->arp_tpa, 4); /* save protocol addr */
-       memcpy(arp->arp_tpa, arp->arp_spa, 4);  /* swap destination and source protocol address */
-       memcpy(arp->arp_spa, ipbuf, 4); /* ... */
+       /* Copy structs on stack back to packet */
 
-       memcpy(arp->arp_tha, arp->arp_sha, 10); /* set target hard/proto addr */
-       memcpy(arp->arp_sha, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN);    /* add fake source hard addr */
-       arp->arp_op = htons(ARPOP_REPLY);
+       memcpy(packet->data + ether_size, &arp, arp_size);
 
-       write_packet(packet);
+       send_packet(source, packet);
 }
 
-void route_outgoing(vpn_packet_t *packet)
+void route(node_t *source, vpn_packet_t *packet)
 {
-       uint16_t type;
-       node_t *n = NULL;
-
        cp();
 
-       /* FIXME: multicast? */
-
-       switch (routing_mode) {
-               case RMODE_ROUTER:
-                       type = ntohs(*((uint16_t *)(&packet->data[12])));
-                       switch (type) {
-                               case 0x0800:
-                                       n = route_ipv4(packet);
-                                       break;
-
-                               case 0x86DD:
-                                       if(packet->data[20] == IPPROTO_ICMPV6 && packet->data[54] == ND_NEIGHBOR_SOLICIT) {
-                                               route_neighborsol(packet);
-                                               return;
-                                       }
-                                       n = route_ipv6(packet);
-                                       break;
-
-                               case 0x0806:
-                                       route_arp(packet);
-                                       return;
-
-                               default:
-                                       ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: unknown type %hx"), type);
-                                       return;
-                       }
-                       if(n)
-                               send_packet(n, packet);
-                       break;
-
-               case RMODE_SWITCH:
-                       n = route_mac(packet);
-                       if(n)
-                               send_packet(n, packet);
-                       else
-                               broadcast_packet(myself, packet);
-                       break;
-
-               case RMODE_HUB:
-                       broadcast_packet(myself, packet);
-                       break;
-       }
-}
+       if(!checklength(source, packet, ether_size))
+               return;
 
-void route_incoming(node_t *source, vpn_packet_t *packet)
-{
        switch (routing_mode) {
                case RMODE_ROUTER:
                        {
-                               node_t *n = NULL;
                                uint16_t type;
 
                                type = ntohs(*((uint16_t *)(&packet->data[12])));
                                switch (type) {
-                                       case 0x0800:
-                                               n = route_ipv4(packet);
+                                       case ETH_P_ARP:
+                                               route_arp(source, packet);
                                                break;
 
-                                       case 0x86DD:
-                                               n = route_ipv6(packet);
+                                       case ETH_P_IP:
+                                               route_ipv4(source, packet);
                                                break;
 
-                                       default:
-                                               n = myself;
+                                       case ETH_P_IPV6:
+                                               route_ipv6(source, packet);
                                                break;
-                               }
 
-                               if(n) {
-                                       if(n == myself) {
-                                               if(overwrite_mac)
-                                                       memcpy(packet->data, mymac.x, 6);
-                                               write_packet(packet);
-                                       } else
-                                               send_packet(n, packet);
+                                       default:
+                                               ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet from %s (%s): unknown type %hx"), source->name, source->hostname, type);
+                                               break;
                                }
                        }
                        break;
 
                case RMODE_SWITCH:
-                       {
-                               subnet_t *subnet;
-
-                               subnet = lookup_subnet_mac((mac_t *)(&packet->data[0]));
-
-                               if(subnet) {
-                                       if(subnet->owner == myself)
-                                               write_packet(packet);
-                                       else
-                                               send_packet(subnet->owner, packet);
-                               } else {
-                                       broadcast_packet(source, packet);
-                                       write_packet(packet);
-                               }
-                       }
+                       route_mac(source, packet);
                        break;
 
                case RMODE_HUB:
-                       broadcast_packet(source, packet);       /* Spread it on */
-                       write_packet(packet);
+                       broadcast_packet(source, packet);
                        break;
        }
 }
index 26c55ee..a26411a 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: route.h,v 1.3 2003/08/24 20:38:28 guus Exp $
+    $Id: route.h,v 1.1.2.14 2003/12/12 19:52:25 guus Exp $
 */
 
 #ifndef __TINC_ROUTE_H__
@@ -39,8 +39,7 @@ extern int macexpire;
 
 extern mac_t mymac;
 
-extern void age_mac(void);
-extern void route_incoming(struct node_t *, struct vpn_packet_t *);
-extern void route_outgoing(struct vpn_packet_t *);
+extern void age_subnets(void);
+extern void route(struct node_t *, struct vpn_packet_t *);
 
 #endif                                                 /* __TINC_ROUTE_H__ */
index 3ecaa90..9b92f2e 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: device.c,v 1.4 2003/08/27 13:47:52 guus Exp $
+    $Id: device.c,v 1.1.2.17 2003/07/31 11:20:32 guus Exp $
 */
 
 
index b0c1e04..d5eca58 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: subnet.c,v 1.4 2003/08/24 20:38:28 guus Exp $
+    $Id: subnet.c,v 1.1.2.52 2003/12/12 19:52:25 guus Exp $
 */
 
 #include "system.h"
@@ -83,7 +83,7 @@ static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b)
        return strcmp(a->owner->name, b->owner->name);
 }
 
-static int subnet_compare(const subnet_t *a, const subnet_t *b)
+int subnet_compare(const subnet_t *a, const subnet_t *b)
 {
        int result;
 
@@ -145,7 +145,7 @@ subnet_t *new_subnet(void)
 {
        cp();
 
-       return (subnet_t *) xmalloc_and_zero(sizeof(subnet_t));
+       return xmalloc_and_zero(sizeof(subnet_t));
 }
 
 void free_subnet(subnet_t *subnet)
@@ -177,16 +177,13 @@ void subnet_del(node_t *n, subnet_t *subnet)
 
 /* Ascii representation of subnets */
 
-subnet_t *str2net(const char *subnetstr)
+bool str2net(subnet_t *subnet, const char *subnetstr)
 {
        int i, l;
-       subnet_t *subnet;
        uint16_t x[8];
 
        cp();
 
-       subnet = new_subnet();
-
        if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d",
                          &x[0], &x[1], &x[2], &x[3], &l) == 5) {
                subnet->type = SUBNET_IPV4;
@@ -195,7 +192,7 @@ subnet_t *str2net(const char *subnetstr)
                for(i = 0; i < 4; i++)
                        subnet->net.ipv4.address.x[i] = x[i];
 
-               return subnet;
+               return true;
        }
 
        if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d",
@@ -207,7 +204,7 @@ subnet_t *str2net(const char *subnetstr)
                for(i = 0; i < 8; i++)
                        subnet->net.ipv6.address.x[i] = htons(x[i]);
 
-               return subnet;
+               return true;
        }
 
        if(sscanf(subnetstr, "%hu.%hu.%hu.%hu", &x[0], &x[1], &x[2], &x[3]) == 4) {
@@ -217,7 +214,7 @@ subnet_t *str2net(const char *subnetstr)
                for(i = 0; i < 4; i++)
                        subnet->net.ipv4.address.x[i] = x[i];
 
-               return subnet;
+               return true;
        }
 
        if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
@@ -228,7 +225,7 @@ subnet_t *str2net(const char *subnetstr)
                for(i = 0; i < 8; i++)
                        subnet->net.ipv6.address.x[i] = htons(x[i]);
 
-               return subnet;
+               return true;
        }
 
        if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx",
@@ -238,23 +235,19 @@ subnet_t *str2net(const char *subnetstr)
                for(i = 0; i < 6; i++)
                        subnet->net.mac.address.x[i] = x[i];
 
-               return subnet;
+               return true;
        }
 
-       free(subnet);
-
-       return NULL;
+       return false;
 }
 
-char *net2str(const subnet_t *subnet)
+bool net2str(char *netstr, int len, const subnet_t *subnet)
 {
-       char *netstr;
-
        cp();
 
        switch (subnet->type) {
                case SUBNET_MAC:
-                       asprintf(&netstr, "%hx:%hx:%hx:%hx:%hx:%hx",
+                       snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx",
                                         subnet->net.mac.address.x[0],
                                         subnet->net.mac.address.x[1],
                                         subnet->net.mac.address.x[2],
@@ -263,7 +256,7 @@ char *net2str(const subnet_t *subnet)
                        break;
 
                case SUBNET_IPV4:
-                       asprintf(&netstr, "%hu.%hu.%hu.%hu/%d",
+                       snprintf(netstr, len, "%hu.%hu.%hu.%hu/%d",
                                         subnet->net.ipv4.address.x[0],
                                         subnet->net.ipv4.address.x[1],
                                         subnet->net.ipv4.address.x[2],
@@ -271,7 +264,7 @@ char *net2str(const subnet_t *subnet)
                        break;
 
                case SUBNET_IPV6:
-                       asprintf(&netstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d",
+                       snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d",
                                         ntohs(subnet->net.ipv6.address.x[0]),
                                         ntohs(subnet->net.ipv6.address.x[1]),
                                         ntohs(subnet->net.ipv6.address.x[2]),
@@ -313,7 +306,7 @@ subnet_t *lookup_subnet_mac(const mac_t *address)
        subnet.net.mac.address = *address;
        subnet.owner = NULL;
 
-       p = (subnet_t *) avl_search(subnet_tree, &subnet);
+       p = avl_search(subnet_tree, &subnet);
 
        return p;
 }
@@ -332,7 +325,7 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address)
        do {
                /* Go find subnet */
 
-               p = (subnet_t *) avl_search_closest_smaller(subnet_tree, &subnet);
+               p = avl_search_closest_smaller(subnet_tree, &subnet);
 
                /* Check if the found subnet REALLY matches */
 
@@ -370,7 +363,7 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address)
        do {
                /* Go find subnet */
 
-               p = (subnet_t *) avl_search_closest_smaller(subnet_tree, &subnet);
+               p = avl_search_closest_smaller(subnet_tree, &subnet);
 
                /* Check if the found subnet REALLY matches */
 
@@ -394,7 +387,7 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address)
 
 void dump_subnets(void)
 {
-       char *netstr;
+       char netstr[MAXNETSTR];
        subnet_t *subnet;
        avl_node_t *node;
 
@@ -403,10 +396,10 @@ void dump_subnets(void)
        logger(LOG_DEBUG, _("Subnet list:"));
 
        for(node = subnet_tree->head; node; node = node->next) {
-               subnet = (subnet_t *) node->data;
-               netstr = net2str(subnet);
+               subnet = node->data;
+               if(!net2str(netstr, sizeof netstr, subnet))
+                       continue;
                logger(LOG_DEBUG, _(" %s owner %s"), netstr, subnet->owner->name);
-               free(netstr);
        }
 
        logger(LOG_DEBUG, _("End of subnet list."));
index dcf3b28..d82bfa3 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: subnet.h,v 1.4 2003/08/24 20:38:28 guus Exp $
+    $Id: subnet.h,v 1.1.2.27 2003/12/12 19:52:25 guus Exp $
 */
 
 #ifndef __TINC_SUBNET_H__
@@ -34,7 +34,6 @@ typedef enum subnet_type_t {
 
 typedef struct subnet_mac_t {
        mac_t address;
-       time_t lastseen;
 } subnet_mac_t;
 
 typedef struct subnet_ipv4_t {
@@ -51,9 +50,9 @@ typedef struct subnet_ipv6_t {
 
 typedef struct subnet_t {
        struct node_t *owner;           /* the owner of this subnet */
-       struct node_t *uplink;          /* the uplink which we should send packets to for this subnet */
 
        subnet_type_t type;             /* subnet type (IPv4? IPv6? MAC? something even weirder?) */
+       time_t expires;                 /* expiry time */
 
        /* And now for the actual subnet: */
 
@@ -64,6 +63,9 @@ typedef struct subnet_t {
        } net;
 } subnet_t;
 
+#define MAXNETSTR 64
+
+extern int subnet_compare(const struct subnet_t *, const struct subnet_t *);
 extern subnet_t *new_subnet(void) __attribute__ ((__malloc__));
 extern void free_subnet(subnet_t *);
 extern void init_subnets(void);
@@ -72,8 +74,8 @@ extern avl_tree_t *new_subnet_tree(void) __attribute__ ((__malloc__));
 extern void free_subnet_tree(avl_tree_t *);
 extern void subnet_add(struct node_t *, subnet_t *);
 extern void subnet_del(struct node_t *, subnet_t *);
-extern char *net2str(const subnet_t *);
-extern subnet_t *str2net(const char *);
+extern bool net2str(char *, int, const subnet_t *);
+extern bool str2net(subnet_t *, const char *);
 extern subnet_t *lookup_subnet(const struct node_t *, const subnet_t *);
 extern subnet_t *lookup_subnet_mac(const mac_t *);
 extern subnet_t *lookup_subnet_ipv4(const ipv4_t *);
index 1088884..dd6b1e7 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: tincd.c,v 1.17 2003/08/24 20:38:29 guus Exp $
+    $Id: tincd.c,v 1.10.4.90 2003/12/07 14:31:09 guus Exp $
 */
 
 #include "system.h"
@@ -39,6 +39,7 @@
 #include <lzo1x.h>
 
 #include <getopt.h>
+#include <pidfile.h>
 
 #include "conf.h"
 #include "device.h"
@@ -291,7 +292,7 @@ static bool keygen(int bits)
        char *filename;
 
        fprintf(stderr, _("Generating %d bits keys:\n"), bits);
-       rsa_key = RSA_generate_key(bits, 0xFFFF, indicator, NULL);
+       rsa_key = RSA_generate_key(bits, 0x10001, indicator, NULL);
 
        if(!rsa_key) {
                fprintf(stderr, _("Error during key generation!\n"));
@@ -482,17 +483,10 @@ int main2(int argc, char **argv)
                return 1;
                
 
-       /* Setup sockets and open device. If it doesn't work, don't give up but try again. */
+       /* Setup sockets and open device. */
 
-       while(!setup_network_connections()) {
-               if(do_detach) {
-                       logger(LOG_NOTICE, _("Restarting in %d seconds!"), maxtimeout);
-                       sleep(maxtimeout);
-               } else {
-                       logger(LOG_ERR, _("Not restarting."));
-                       return 1;
-               }
-       }
+       if(!setup_network_connections())
+               goto end;
 
        /* Start main loop. It only exits when tinc is killed. */
 
@@ -505,6 +499,12 @@ int main2(int argc, char **argv)
        ifdebug(CONNECTIONS)
                dump_device_stats();
 
+end:
        logger(LOG_NOTICE, _("Terminating"));
+
+#ifndef HAVE_MINGW
+       remove_pid(pidfilename);
+#endif
+       
        return status;
 }