+++ /dev/null
-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
--- /dev/null
+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
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
+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.
-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:
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
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.
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.
+++ /dev/null
-#!/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
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
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
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
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]) ]
)
+++ /dev/null
-zarq:Ivo Timmermans <ivo@o2w.nl>
-guus:Guus Sliepen <guus@sliepen.eu.org>
-wsl:Wessel Dankers <wsl@nl.linux.org>
+++ /dev/null
-Makefile.in Makefile tinc.info sample-config.tar.gz
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
==================
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
==============
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
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
----------------------------------
+++ /dev/null
-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.
-
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
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),
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
.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
\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
<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
<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
@end titlepage
+@ifinfo
@c ==================================================================
-@node Top, Introduction, (dir), (dir)
+@node Top
+@top Top
@menu
* Introduction::
* 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.
@end menu
@c ==================================================================
-@node Virtual Private Networks, tinc, Introduction, Introduction
+@node Virtual Private Networks
@section Virtual Private Networks
@cindex VPN
@c ==================================================================
-@node tinc, Supported platforms, Virtual Private Networks, Introduction
+@node tinc
@section tinc
@cindex vpnd
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.
@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
@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.
@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.
@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.
@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.
@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.
@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}.
@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/}.
@c
@c ==================================================================
-@node Preparations, Installation, Introduction, Top
+@node Preparations
@chapter Preparations
This chapter contains information on how to prepare your system to
@c ==================================================================
-@node Configuring the kernel, Libraries, Preparations, Preparations
+@node Configuring the kernel
@section Configuring the kernel
@cindex RedHat
@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:
@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:
@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
@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,
@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,
@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
@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
@c ==================================================================
-@node OpenSSL, zlib, Libraries, Libraries
+@node OpenSSL
@subsection OpenSSL
@cindex OpenSSL
@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
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
@c ==================================================================
-@node lzo, , zlib, Libraries
+@node lzo
@subsection lzo
@cindex lzo
@c
@c ==================================================================
-@node Installation, Configuration, Preparations, Top
+@node Installation
@chapter Installation
If you use Debian, you may want to install one of 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
@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
@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
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
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}.
@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
@c ==================================================================
-@node Device files, Other files, System files, System files
+@node Device files
@subsection Device files
@cindex device files
@c ==================================================================
-@node Other files, , Device files, System files
+@node Other files
@subsection Other files
@subsubheading @file{/etc/networks}
@c ==================================================================
-@node Configuration, Running tinc, Installation, Top
+@node Configuration
@chapter Configuration
@menu
@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,
@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.
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
@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
@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
@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.
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
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.
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
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
@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
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
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.
@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
@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
@c ==================================================================
-@node How to configure, , Scripts, Configuration files
+@node How to configure
@subsection How to configure
@subsubheading Step 1. Creating the main configuration file
@c ==================================================================
-@node Generating keypairs, Network interfaces, Configuration files, Configuration
+@node Generating keypairs
@section Generating keypairs
@cindex key generation
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
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:
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
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
@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
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
@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
@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
@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
@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:
@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
@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
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.
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.
@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
@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!
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
@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
@c ==================================================================
-@node The UDP tunnel, The meta-connection, The connection, The connection
+@node The UDP tunnel
@subsection The UDP tunnel
@cindex virtual network device
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.
@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
@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
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.
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
@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
@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
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
@c ==================================================================
-@node Authors, , Contact Information, About us
+@node Authors
@section Authors
@table @asis
@c ==================================================================
-@node Concept Index, , About us, Top
-@c node-name, next, previous, up
+@node Concept Index
@unnumbered Concept Index
@c ==================================================================
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.
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
+++ /dev/null
-Makefile Makefile.in .deps
## 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
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"
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)
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 $
*/
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"
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__
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
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
* 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
#include "ipv4.h"
#include "ipv6.h"
#include "fake-getaddrinfo.h"
+#include "xalloc.h"
#ifndef HAVE_GAI_STRERROR
char *gai_strerror(int ecode)
-/* $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
-/* $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
+++ /dev/null
-/*
- 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);
-}
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
uint8_t ip_p;
uint16_t ip_sum;
struct in_addr ip_src, ip_dst;
-};
+} __attribute__ ((__packed__));
#endif
#ifndef HAVE_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__ */
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__
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
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
uint32_t sin6_scope_id;
-};
+} __attribute__ ((__packed__));
#endif
#ifndef IN6_IS_ADDR_V4MAPPED
} 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
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__ */
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"
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)
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__
* 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;
}
*
* 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 ()))
/* But... errno is usually changed only on error.. */
errno = 0;
if (kill(pid, 0) && errno == ESRCH)
- return(0);
+ return 0;
return 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)
{
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;
}
#ifdef HAVE_FLOCK
if (flock(fd, LOCK_UN) == -1) {
- printf("Can't unlock pidfile %s, %s.\n", pidfile, strerror(errno));
close(fd);
return 0;
}
* 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
*
* 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
*
+++ /dev/null
-Makefile.am Makefile.in Makefile
--- /dev/null
+## Process this file with automake to produce Makefile.in -*-Makefile-*-
+
+EXTRA_DIST = README *.m4
+
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,
[
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,
[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.")]
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.
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
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,
[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,
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.
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
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"]
)]
)
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,
[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.")]
+++ /dev/null
-Makefile.in.in POTFILES Makefile.in Makefile cat-id-tbl.c *.gmo stamp-cat-id *.pot
# 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 =
# 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"
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 "
"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"
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)"
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"
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!"
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 "
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"
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"
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"
"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"
" --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, "
"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"
"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"
"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"
"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"
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 "
"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:%"
"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"
#: 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"
#: 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"
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"
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!"
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"
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"
#, 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"
--- /dev/null
+# 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"
+++ /dev/null
-*.o .libs tincd Makefile.in Makefile .deps
## 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
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"
{
cp();
- return (config_t *) xmalloc_and_zero(sizeof(config_t));
+ return xmalloc_and_zero(sizeof(config_t));
}
void free_config(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;
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;
/* 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;
}
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;
variable = value = line;
+ eol = line + strlen(line);
+ while(strchr("\t ", *--eol))
+ *eol = '\0';
+
len = strcspn(value, "\t =");
value += len;
value += strspn(value, "\t ");
}
variable[len] = '\0';
+
if(!*value) {
logger(LOG_ERR, _("No value for variable `%s' on line %d while reading config file %s"),
variable, lineno, fname);
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__
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"
cp();
- c = (connection_t *) xmalloc_and_zero(sizeof(connection_t));
+ c = xmalloc_and_zero(sizeof(connection_t));
if(!c)
return NULL;
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);
}
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__
#define OPTION_INDIRECT 0x0001
#define OPTION_TCPONLY 0x0002
+#define OPTION_PMTU_DISCOVERY 0x0004
typedef struct connection_status_t {
int pinged:1; /* sent ping */
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"
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"
bool setup_device(void)
{
HKEY key, key2;
- int i;
+ int i, err;
char regpath[1024];
char adapterid[1024];
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"
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__
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"
{
cp();
- return (edge_t *) xmalloc_and_zero(sizeof(edge_t));
+ return xmalloc_and_zero(sizeof(edge_t));
}
void free_edge(edge_t *e)
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);
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__
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"
{
cp();
- return (event_t *) xmalloc_and_zero(sizeof(event_t));
+ return xmalloc_and_zero(sizeof(event_t));
}
void free_event(event_t *event)
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);
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__
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"
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:
/* 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;
}
/* 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++;
}
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;
/* 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;
}
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:
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();
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;
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 ? : "");
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__ */
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"
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;
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"
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);
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"
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
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);
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];
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;
}
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;
return false;
c->buflen -= reqlen;
- lenin -= reqlen;
+ lenin -= reqlen - oldlen;
memmove(c->buffer, c->buffer + reqlen, c->buflen);
oldlen = 0;
continue;
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__
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;
char adaptername[1024];
char tapname[1024];
long len;
+ unsigned long status;
bool found = false;
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);
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"
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,
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);
}
}
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;
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);
closesocket(c->socket);
if(c->edge) {
- if(report)
+ if(report && !tunnelserver)
send_del_edge(broadcast, c->edge);
edge_del(c->edge);
/* 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 */
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) {
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;
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);
last_ping_check = now;
if(routing_mode == RMODE_SWITCH)
- age_mac();
+ age_subnets();
age_past_requests();
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);
}
/* 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);
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__
typedef short length_t;
-#define AF_UNKNOWN 0xFFFF
+#define AF_UNKNOWN 255
struct sockaddr_unknown {
uint16_t family;
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)
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>
#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) {
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)
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) {
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;
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)
/* 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);
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;
}
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;
#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;
}
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);
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);
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);
}
}
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;
}
return;
}
- if(n->connection)
- n->connection->last_ping_time = now;
-
receive_udppacket(n, &pkt);
}
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"
#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"
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;
}
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 */
/* 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;
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;
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))
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... */
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;
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"
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
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);
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();
}
#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
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)
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"
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"
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__
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"
node_t *new_node(void)
{
- node_t *n = (node_t *) xmalloc_and_zero(sizeof(*n));
+ node_t *n = xmalloc_and_zero(sizeof(*n));
cp();
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;
}
sockaddrfree(&n->address);
EVP_CIPHER_CTX_cleanup(&n->packet_ctx);
+
+ if(n->mtuevent)
+ event_del(n->mtuevent);
free(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);
}
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."));
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 */
} 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 */
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;
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"
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"
/* 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;
*/
static bool write_pidfile(void)
{
- int pid;
+ pid_t pid;
cp();
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;
}
bool kill_other(int signal)
{
#ifndef HAVE_MINGW
- int pid;
+ pid_t pid;
cp();
/* 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());
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)
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__
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"
#include "utils.h"
#include "xalloc.h"
+bool tunnelserver = false;
+
/* Jumptable for the request handlers */
static bool (*request_handlers[])(connection_t *) = {
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);
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++;
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__
time_t firstseen;
} past_request_t;
+extern bool tunnelserver;
+
/* Maximum size of strings in a request */
#define MAX_STRING_SIZE 2048
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"
bool id_h(connection_t *c)
{
char name[MAX_STRING_SIZE];
- bool choice;
cp();
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);
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:
/* 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;
}
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 {
/* Copy random data to the buffer */
- RAND_bytes(c->hischallenge, len);
+ RAND_pseudo_bytes(c->hischallenge, len);
/* Convert to hex */
/* 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 */
/* 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 */
to create node_t and edge_t structures. */
struct timeval now;
+ bool choice;
cp();
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);
}
/* 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);
}
}
{
char hisport[MAX_STRING_SIZE];
char *hisaddress, *dummy;
- int weight;
+ int weight, mtu;
long int options;
node_t *n;
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;
/* 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 */
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"
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);
/* Tell the rest about the new edge */
- forward_request(c);
+ if(!tunnelserver)
+ forward_request(c);
/* Run MST before or after we tell the rest? */
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);
/* Tell the rest about the deleted edge */
- forward_request(c);
+ if(!tunnelserver)
+ forward_request(c);
/* Delete the edge */
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;
}
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"
/* Tell the others */
- forward_request(c);
+ if(!tunnelserver)
+ forward_request(c);
return true;
}
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);
}
/* Forward it if necessary */
if(to != myself) {
+ if(tunnelserver)
+ return false;
+
return send_request(to->nexthop->connection, "%s", c->buffer);
}
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);
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"
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)
char subnetstr[MAX_STRING_SIZE];
char name[MAX_STRING_SIZE];
node_t *owner;
- subnet_t *s;
+ subnet_t s = {0}, *new;
cp();
/* 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;
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)
char subnetstr[MAX_STRING_SIZE];
char name[MAX_STRING_SIZE];
node_t *owner;
- subnet_t *s, *find;
+ subnet_t s = {0}, *find;
cp();
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;
/* 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"),
/* Tell the rest */
- forward_request(c);
+ if(!tunnelserver)
+ forward_request(c);
/* Finally, delete it. */
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"
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"
#include "avl_tree.h"
#include "connection.h"
-#include "device.h"
#include "ethernet.h"
#include "ipv4.h"
#include "ipv6.h"
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;
}
if(len)
- checksum += *(unsigned char *)p;
+ checksum += *(uint8_t *)p;
while(checksum >> 16)
checksum = (checksum & 0xFFFF) + (checksum >> 16);
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;
/* 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;
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);
}
}
}
-static node_t *route_mac(vpn_packet_t *packet)
+static __inline__ void route_mac(node_t *source, vpn_packet_t *packet)
{
subnet_t *subnet;
/* 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 {
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;
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"));
/* 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;
}
/* 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;
}
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;
}
}
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__
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__ */
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 $
*/
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"
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;
{
cp();
- return (subnet_t *) xmalloc_and_zero(sizeof(subnet_t));
+ return xmalloc_and_zero(sizeof(subnet_t));
}
void free_subnet(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;
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",
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) {
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",
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",
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],
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],
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]),
subnet.net.mac.address = *address;
subnet.owner = NULL;
- p = (subnet_t *) avl_search(subnet_tree, &subnet);
+ p = avl_search(subnet_tree, &subnet);
return p;
}
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 */
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 */
void dump_subnets(void)
{
- char *netstr;
+ char netstr[MAXNETSTR];
subnet_t *subnet;
avl_node_t *node;
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."));
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__
typedef struct subnet_mac_t {
mac_t address;
- time_t lastseen;
} subnet_mac_t;
typedef struct subnet_ipv4_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: */
} 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);
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 *);
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"
#include <lzo1x.h>
#include <getopt.h>
+#include <pidfile.h>
#include "conf.h"
#include "device.h"
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"));
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. */
ifdebug(CONNECTIONS)
dump_device_stats();
+end:
logger(LOG_NOTICE, _("Terminating"));
+
+#ifndef HAVE_MINGW
+ remove_pid(pidfilename);
+#endif
+
return status;
}