Synchronise HEAD with CABAL branch.
This commit is contained in:
parent
efa5148bc7
commit
013a2e159e
173 changed files with 12252 additions and 28046 deletions
4
AUTHORS
4
AUTHORS
|
@ -1,6 +1,6 @@
|
|||
Main tinc authors:
|
||||
Guus Sliepen <guus@sliepen.warande.net>
|
||||
Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
Guus Sliepen <guus@sliepen.eu.org>
|
||||
Ivo Timmermans <ivo@o2w.nl>
|
||||
|
||||
These files are from other sources:
|
||||
* lib/pidfile.h and lib/pidfile.c are by Martin Schulze, taken from
|
||||
|
|
10
Makefile.am
10
Makefile.am
|
@ -2,16 +2,17 @@
|
|||
|
||||
AUTOMAKE_OPTIONS = gnu
|
||||
|
||||
SUBDIRS = m4 intl lib src doc po
|
||||
SUBDIRS = m4 lib src doc po
|
||||
|
||||
ACLOCAL_AMFLAGS =
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
EXTRA_DIST = system.h COPYING.README depcomp
|
||||
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 src/.libs intl depcomp
|
||||
po/tinc.pot po/*.sed po/*.header po/*.sin po/Rules-quot \
|
||||
src/.libs intl depcomp
|
||||
|
||||
ChangeLog:
|
||||
cvs2cl -U cvsusers --fsf
|
||||
|
@ -20,6 +21,7 @@ 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
|
||||
|
||||
deb:
|
||||
dpkg-buildpackage -rfakeroot
|
||||
|
|
37
NEWS
37
NEWS
|
@ -1,3 +1,40 @@
|
|||
version 1.0.1 Aug 14 2003
|
||||
|
||||
* Allow empty lines in config files.
|
||||
|
||||
* Fix handling of spaces and backslashes in filenames under native Windows.
|
||||
|
||||
* Allow scripts to be executed under native Windows.
|
||||
|
||||
* Update documentation, make it less Linux specific.
|
||||
|
||||
version 1.0 Aug 4 2003
|
||||
|
||||
* Lots of small bugfixes and code cleanups.
|
||||
|
||||
* Throughput doubled and latency reduced.
|
||||
|
||||
* Added support for LZO compression.
|
||||
|
||||
* No need to set MAC address or disable ARP anymore.
|
||||
|
||||
* Added support for Windows 2000 and XP, both natively and in a Cygwin
|
||||
environment.
|
||||
|
||||
version 1.0pre8 Sep 16 2002
|
||||
|
||||
* More fixes for subnets with prefixlength undivisible by 8.
|
||||
|
||||
* Added support for NetBSD and MacOS/X.
|
||||
|
||||
* Switched from undirected graphs to directed graphs to avoid certain race
|
||||
conditions and improve scalability.
|
||||
|
||||
* Generalized broadcasting and forwarding of protocol messages.
|
||||
|
||||
* Cleanup of source code.
|
||||
|
||||
|
||||
version 1.0pre7 Apr 7 2002
|
||||
|
||||
* Don't do blocking read()s when getting a signal.
|
||||
|
|
57
README
57
README
|
@ -1,10 +1,10 @@
|
|||
This is the README file for tinc version 1.0pre7. Installation
|
||||
This is the README file for tinc version 1.0.1. Installation
|
||||
instructions may be found in the INSTALL file.
|
||||
|
||||
tinc is Copyright (C) 1998-2002 by:
|
||||
tinc is Copyright (C) 1998-2003 by:
|
||||
|
||||
Ivo Timmermans <itimmermans@bigfoot.com>,
|
||||
Guus Sliepen <guus@sliepen.warande.net>,
|
||||
Ivo Timmermans <ivo@o2w.nl>,
|
||||
Guus Sliepen <guus@sliepen.eu.org>,
|
||||
and others.
|
||||
|
||||
For a complete list of authors see the AUTHORS file.
|
||||
|
@ -44,13 +44,19 @@ Some configuration variables have different names now. Most notably "TapDevice"
|
|||
should be changed into "Device", and "Device" should be changed into
|
||||
"BindToDevice".
|
||||
|
||||
Compatibility
|
||||
-------------
|
||||
|
||||
Version 1.0.1 is compatible with 1.0 and 1.0pre8 but not with older versions
|
||||
of tinc.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Since 1.0pre3, we use OpenSSL for all cryptographic functions. So you
|
||||
need to install this library first; grab it from
|
||||
http://www.openssl.org/. We recommend version 0.9.5 or better. If
|
||||
http://www.openssl.org/. You will need version 0.9.7 or later. If
|
||||
this library is not installed on you system, configure will fail. The
|
||||
manual in doc/tinc.texi contains more detailed information on how to
|
||||
install this library.
|
||||
|
@ -60,8 +66,11 @@ library whether or not you plan to enable the compression. You can find it at
|
|||
http://www.gzip.org/zlib/. Because of a possible exploit in earlier versions we
|
||||
recommand that you download version 1.1.4 or later.
|
||||
|
||||
In order to compile tinc, you will also need autoconf, automake, GNU make, m4
|
||||
and gettext.
|
||||
Since 1.0, the lzo library is also used for optional compression. You need this
|
||||
library whether or not you plan to enable compression. You can find it at
|
||||
http://www.oberhumer.com/opensource/lzo/.
|
||||
|
||||
In order to compile tinc, you will need a GNU C compiler environment.
|
||||
|
||||
|
||||
Features
|
||||
|
@ -70,17 +79,7 @@ Features
|
|||
This version of tinc supports multiple virtual networks at once. To
|
||||
use this feature, you may supply a netname via the -n or --net
|
||||
options. The standard locations for the config files will then be
|
||||
/etc/tinc/<net>/. Because of this feature, tinc will send packets
|
||||
directly to their destinations, instead of to the uplink. If this
|
||||
behaviour is undesirable (for instance because of firewalls or other
|
||||
restrictions), please use an older version of tinc (I would recommend
|
||||
tinc-0.2.19).
|
||||
|
||||
In order to force the kernel to accept received packets, the
|
||||
destination MAC address will be set to FE:FD:00:00:00:00 upon
|
||||
reception. The MAC address of the ethertap or tun/tap interface must
|
||||
also be set to this address. See the manual for more detailed
|
||||
information.
|
||||
/etc/tinc/<net>/.
|
||||
|
||||
tincd regenerates its encryption key pairs. It does this on the first
|
||||
activity after the keys have expired. This period is adjustable in the
|
||||
|
@ -96,7 +95,7 @@ Since pre5, tinc can operate in several routing modes. The default mode,
|
|||
determine the destination of packets. The other two modes, "switch" and "hub",
|
||||
allow the tinc daemons to work together like a single network switch or hub.
|
||||
This is useful for bridging networks. The latter modes only work properly on
|
||||
Linux and FreeBSD.
|
||||
Linux, FreeBSD and Windows.
|
||||
|
||||
The algorithms used for encryption and generating message authentication codes
|
||||
can now be changed in the configuration files. All cipher and digest algorithms
|
||||
|
@ -107,11 +106,17 @@ etcetera.
|
|||
Support for routing IPv6 packets has been added. Just add Subnet lines with
|
||||
IPv6 addresses (without using :: abbreviations) and use ifconfig or ip (from
|
||||
the iproute package) to give the virtual network interface corresponding IPv6
|
||||
addresses. Autoconfiguration will not work in router mode. Tunneling IPv6
|
||||
packets only works on Linux, FreeBSD and possibly OpenBSD.
|
||||
addresses. tinc does not provide autoconfiguration for IPv6 hosts, if you need
|
||||
it use radvd or zebra. Tunneling IPv6 packets only works on Linux, FreeBSD,
|
||||
Windows and possibly OpenBSD.
|
||||
|
||||
It is also possible to make tunnels to other tinc daemons over IPv6 networks,
|
||||
if the operating system supports IPv6. tinc will automatically use both IPv6
|
||||
and IPv4 when available, but this can be changed by adding the option
|
||||
"AddressFamily = ipv4" or "AddressFamily = ipv6" to the tinc.conf file.
|
||||
|
||||
Normally, when started tinc will detach and run in the background. In a native
|
||||
Windows environment this means tinc will intall itself as a service, which will
|
||||
restart after reboots. To prevent tinc from detaching or running as a service,
|
||||
use the -D option.
|
||||
|
||||
It is also possible to make tunnels to other tinc daemons over IPv6 networks.
|
||||
In order to enable this feature the option "AddressFamily = any" or
|
||||
"AddressFamily = ipv6" must be added to the tinc.conf file. The host
|
||||
configuration files should contain IPv6 addresses for the "Address" variables,
|
||||
or hostnames which have an AAAA or A6 record.
|
||||
|
|
8
THANKS
8
THANKS
|
@ -18,6 +18,14 @@ We would like to thank
|
|||
* Armijn Hemel (for being our very own PR manager)
|
||||
* Jerome Etienne (for a thorough security analysis of tinc)
|
||||
* Mark Glines (for his compression patch)
|
||||
* Nick Patavalis (RedHat package)
|
||||
* Alessandro Gatti (for helping us support Darwin)
|
||||
* Ivo van Dong (for help during the early versions of tinc)
|
||||
* Jeroen Ubbink (for help testing tinc on Free- and NetBSD)
|
||||
* LarstiQ (for help testing tinc on MacOS/X)
|
||||
* Marc A. Lehmann (for criticism)
|
||||
* Teemu Kiviniemi (for his lzo compression patch)
|
||||
* Flynn Marquardt (for help testing tinc on Solaris 2.6)
|
||||
|
||||
for their help, support and ideas. Thank you guys!
|
||||
|
||||
|
|
4
TODO
4
TODO
|
@ -1,5 +1,3 @@
|
|||
TODO LIST
|
||||
|
||||
1.0:
|
||||
|
||||
* A nice, secure and stable release
|
||||
* Think of new things to do.
|
||||
|
|
91
acconfig.h
91
acconfig.h
|
@ -1,91 +0,0 @@
|
|||
/* Define to the name name of this package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the version of the package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
#undef malloc
|
||||
|
||||
/* Define to rpl_realloc if the replacement function should be used. */
|
||||
#undef realloc
|
||||
|
||||
/* This is always defined. It enables GNU extensions on systems that
|
||||
have them. */
|
||||
#if !defined(_GNU_SOURCE)
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#if !defined(__USE_BSD)
|
||||
# undef __USE_BSD
|
||||
#endif
|
||||
|
||||
|
||||
/* Define to 1 if NLS is requested. */
|
||||
#undef ENABLE_NLS
|
||||
|
||||
/* Define as 1 if you have catgets and don't want to use GNU gettext. */
|
||||
#undef HAVE_CATGETS
|
||||
|
||||
/* Define as 1 if you have gettext and don't want to use GNU gettext. */
|
||||
#undef HAVE_GETTEXT
|
||||
|
||||
/* Define if your locale.h file contains LC_MESSAGES. */
|
||||
#undef HAVE_LC_MESSAGES
|
||||
|
||||
/* Define to 1 if you have the stpcpy function. */
|
||||
#undef HAVE_STPCPY
|
||||
|
||||
/* For getopt */
|
||||
#if HAVE_STDLIB_H
|
||||
# define getopt system_getopt
|
||||
# include <stdlib.h>
|
||||
# undef getopt
|
||||
#endif
|
||||
|
||||
/* Linux */
|
||||
#undef HAVE_LINUX
|
||||
|
||||
/* FreeBSD */
|
||||
#undef HAVE_FREEBSD
|
||||
|
||||
/* OpenBSD */
|
||||
#undef HAVE_OPENBSD
|
||||
|
||||
/* Solaris */
|
||||
#undef HAVE_SOLARIS
|
||||
|
||||
/* NetBSD */
|
||||
#undef HAVE_NETBSD
|
||||
|
||||
/* Define to the location of the kernel sources */
|
||||
#undef CONFIG_TINC_KERNELDIR
|
||||
|
||||
/* Define to 1 if tun/tap support is enabled and found */
|
||||
#undef HAVE_TUNTAP
|
||||
|
||||
/* Define to the location of if_tun.h */
|
||||
#undef LINUX_IF_TUN_H
|
||||
|
||||
/* Define to 1 if support for jumbograms is enabled */
|
||||
#undef ENABLE_JUMBOGRAMS
|
||||
|
||||
/* Define to 1 if checkpoint tracing is enabled */
|
||||
#undef ENABLE_TRACING
|
||||
|
||||
/* Define to enable use of old SSLeay_add_all_algorithms() function */
|
||||
#undef HAVE_SSLEAY_ADD_ALL_ALGORITHMS
|
||||
|
||||
/* Define to 1 if you want to include GCRYPT support */
|
||||
#undef USE_GCRYPT
|
||||
|
||||
/* Define to 1 if you want to include OpenSSL support */
|
||||
#undef USE_OPENSSL
|
||||
|
||||
#if defined(USE_GCRYPT) && defined(USE_OPENSSL)
|
||||
# error You can only define one of USE_GCRYPT and USE_OPENSSL
|
||||
#endif
|
||||
|
||||
#if !defined(USE_GCRYPT) && !defined(USE_OPENSSL)
|
||||
# error You must define exactly one of USE_GCRYPT and USE_OPENSSL
|
||||
#endif
|
48
autogen.sh
48
autogen.sh
|
@ -96,6 +96,30 @@ do
|
|||
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
|
||||
|
@ -108,30 +132,6 @@ do
|
|||
fi
|
||||
done
|
||||
touch ChangeLog
|
||||
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 gettextize... Ignore non-fatal messages."
|
||||
echo "no" | gettextize --force --copy
|
||||
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 gettextize... Ignore non-fatal messages."
|
||||
echo "no" | gettextize --force --copy
|
||||
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
|
||||
echo "Running aclocal $aclocalinclude ..."
|
||||
aclocal $aclocalinclude
|
||||
if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then
|
||||
|
|
284
configure.in
284
configure.in
|
@ -1,18 +1,24 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
dnl $Id: configure.in,v 1.19 2002/04/28 12:46:25 zarq Exp $
|
||||
dnl $Id: configure.in,v 1.20 2003/08/24 20:38:18 guus Exp $
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT(src/tincd.c)
|
||||
AM_INIT_AUTOMAKE(tinc, 1.0-cvs)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
dnl Include the macros from the m4/ directory
|
||||
AM_ACLOCAL_INCLUDE(m4)
|
||||
|
||||
AM_GNU_GETTEXT([external])
|
||||
AM_GNU_GETTEXT_VERSION(0.12.1)
|
||||
|
||||
# Enable GNU extensions.
|
||||
# Define this here, not in acconfig's @TOP@ section, since definitions
|
||||
# in the latter don't make it into the configure-time tests.
|
||||
AC_DEFINE([_GNU_SOURCE], [__USE_BSD])
|
||||
AC_DEFINE([_GNU_SOURCE], 1, [Enable GNU extenstions])
|
||||
AC_DEFINE([__USE_BSD], 1, [Enable BSD extensions])
|
||||
|
||||
ALL_LINGUAS="nl"
|
||||
|
||||
|
@ -24,66 +30,233 @@ AC_PROG_AWK
|
|||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
jm_PERL
|
||||
|
||||
AC_PROG_RANLIB
|
||||
|
||||
AC_ISC_POSIX
|
||||
|
||||
dnl Check and set OS
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
#AC_CANONICAL_HOST
|
||||
|
||||
case $host_os in
|
||||
*linux*)
|
||||
AC_DEFINE(HAVE_LINUX)
|
||||
AC_DEFINE(HAVE_LINUX, 1, [Linux])
|
||||
[ rm -f src/device.c; ln -sf linux/device.c src/device.c ]
|
||||
;;
|
||||
*freebsd*)
|
||||
AC_DEFINE(HAVE_FREEBSD)
|
||||
AC_DEFINE(HAVE_FREEBSD, 1, [FreeBSD])
|
||||
[ rm -f src/device.c; ln -sf freebsd/device.c src/device.c ]
|
||||
;;
|
||||
*darwin*)
|
||||
AC_DEFINE(HAVE_DARWIN, 1, [Darwin (MacOS/X)])
|
||||
[ rm -f src/device.c; ln -sf darwin/device.c src/device.c ]
|
||||
;;
|
||||
*solaris*)
|
||||
AC_DEFINE(HAVE_SOLARIS)
|
||||
AC_DEFINE(HAVE_SOLARIS, 1, [Solaris/SunOS])
|
||||
[ rm -f src/device.c; ln -sf solaris/device.c src/device.c ]
|
||||
;;
|
||||
*openbsd*)
|
||||
AC_DEFINE(HAVE_OPENBSD)
|
||||
AC_DEFINE(HAVE_OPENBSD, 1, [OpenBSD])
|
||||
[ rm -f src/device.c; ln -sf openbsd/device.c src/device.c ]
|
||||
;;
|
||||
*netbsd*)
|
||||
AC_DEFINE(HAVE_NETBSD)
|
||||
AC_DEFINE(HAVE_NETBSD, 1, [NetBSD])
|
||||
[ rm -f src/device.c; ln -sf netbsd/device.c src/device.c ]
|
||||
;;
|
||||
*cygwin*)
|
||||
AC_DEFINE(HAVE_CYGWIN, 1, [Cygwin])
|
||||
[ rm -f src/device.c; ln -sf cygwin/device.c src/device.c ]
|
||||
;;
|
||||
*mingw*)
|
||||
AC_DEFINE(HAVE_MINGW, 1, [MinGW])
|
||||
[ rm -f src/device.c; cp -f src/mingw/device.c src/device.c ]
|
||||
LIBS="$LIBS -lws2_32"
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR("Unknown operating system.")
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_CACHE_SAVE
|
||||
|
||||
if test -d /sw/include ; then
|
||||
CPPFLAGS="$CPPFLAGS -I/sw/include"
|
||||
fi
|
||||
if test -d /sw/lib ; then
|
||||
LIBS="$LIBS -L/sw/lib"
|
||||
fi
|
||||
|
||||
dnl Checks for libraries.
|
||||
|
||||
dnl Checks for header files.
|
||||
dnl We do this in multiple stages, because unlike Linux all the other operating systems really suck and don't include their own dependencies.
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([fcntl.h limits.h sys/ioctl.h syslog.h unistd.h \
|
||||
sys/time.h malloc.h strings.h sys/file.h])
|
||||
AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/param.h sys/time.h sys/socket.h sys/wait.h sys/mman.h netdb.h arpa/inet.h])
|
||||
AC_CHECK_HEADERS([net/if.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h],
|
||||
[], [],
|
||||
[#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
]
|
||||
)
|
||||
AC_CHECK_HEADERS([netinet/if_ether.h netinet/ip.h netinet/ip6.h],
|
||||
[], [],
|
||||
[#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_SYSTM_H
|
||||
#include <netinet/in_systm.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN6_H
|
||||
#include <netinet/in6.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_ETHERNET_H
|
||||
#include <net/ethernet.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_IF_ARP_H
|
||||
#include <net/if_arp.h>
|
||||
#endif
|
||||
]
|
||||
)
|
||||
AC_CHECK_HEADERS([netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h],
|
||||
[], [],
|
||||
[#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_SYSTM_H
|
||||
#include <netinet/in_systm.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IP_H
|
||||
#include <netinet/ip.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN6_H
|
||||
#include <netinet/in6.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IP6_H
|
||||
#include <netinet/ip6.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_ETHERNET_H
|
||||
#include <net/ethernet.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_IF_ARP_H
|
||||
#include <net/if_arp.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IF_ETHER_H
|
||||
#include <netinet/if_ether.h>
|
||||
#endif
|
||||
]
|
||||
)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_C_VOLATILE
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_HEADER_TIME
|
||||
AC_STRUCT_TM
|
||||
|
||||
tinc_ATTRIBUTE(__malloc__)
|
||||
|
||||
AC_CHECK_TYPES([socklen_t, struct arphdr, struct ether_arp, struct in_addr, struct addrinfo, struct ip, struct icmp, struct in6_addr, struct sockaddr_in6, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , ,
|
||||
[#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_SYSTM_H
|
||||
#include <netinet/in_systm.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IP_H
|
||||
#include <netinet/ip.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_TCP_H
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN6_H
|
||||
#include <netinet/in6.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IP6_H
|
||||
#include <netinet/ip6.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_ETHERNET_H
|
||||
#include <net/ethernet.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_IF_ARP_H
|
||||
#include <net/if_arp.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IF_ETHER_H
|
||||
#include <netinet/if_ether.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IP_ICMP_H
|
||||
#include <netinet/ip_icmp.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_ICMP6_H
|
||||
#include <netinet/icmp6.h>
|
||||
#endif
|
||||
]
|
||||
)
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_FUNC_MEMCMP
|
||||
AC_FUNC_ALLOCA
|
||||
AC_TYPE_SIGNAL
|
||||
AC_CHECK_FUNCS([ftime socket select strtol strerror flock unsetenv \
|
||||
asprintf putenv strdup fcloseall daemon strsignal get_current_dir_name])
|
||||
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])
|
||||
jm_FUNC_MALLOC
|
||||
jm_FUNC_REALLOC
|
||||
|
||||
AM_GNU_GETTEXT
|
||||
|
||||
|
||||
dnl Support for SunOS
|
||||
|
||||
AC_CHECK_FUNC(socket, [], [
|
||||
|
@ -93,79 +266,36 @@ AC_CHECK_FUNC(gethostbyname, [], [
|
|||
AC_CHECK_LIB(nsl, gethostbyname)
|
||||
])
|
||||
|
||||
AC_CHECK_FUNCS([freeaddrinfo gai_strerror getaddrinfo getnameinfo inet_aton])
|
||||
|
||||
AC_CACHE_SAVE
|
||||
|
||||
dnl These are defined in files in m4/
|
||||
tinc_TUNTAP
|
||||
|
||||
use_gcrypt=0
|
||||
use_openssl=0
|
||||
case $host_os in
|
||||
*linux*)
|
||||
tinc_TUNTAP
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_WITH(gcrypt,
|
||||
[ --with-gcrypt Use GCRYPT for all cryptographic functions],
|
||||
[
|
||||
if test "x$withval" = "xyes" ; then
|
||||
use_gcrypt=1
|
||||
else
|
||||
use_gcrypt=0
|
||||
fi
|
||||
],
|
||||
[use_gcrypt=0])
|
||||
|
||||
AC_ARG_WITH(openssl,
|
||||
[ --with-openssl Use OpenSSL for all cryptographic functions],
|
||||
[
|
||||
if test "x$withval" = "xyes" ; then
|
||||
use_openssl=1
|
||||
else
|
||||
use_openssl=0
|
||||
fi
|
||||
],
|
||||
[use_openssl=0])
|
||||
|
||||
if test \( $use_gcrypt -eq 0 -a $use_openssl -eq 0 \) \
|
||||
-o \( $use_gcrypt -eq 1 -a $use_openssl -eq 1 \) ; then
|
||||
cat << EOM
|
||||
Error: You must select exactly one of GCRYPT or OpenSSL.
|
||||
EOM
|
||||
echo use_openssl=$use_openssl, use_gcrypt=$use_gcrypt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test $use_gcrypt -eq 1 ; then
|
||||
AC_MSG_RESULT([Selecting GCRYPT for crypto])
|
||||
tinc_GCRYPT
|
||||
AC_DEFINE(USE_GCRYPT)
|
||||
fi
|
||||
if test $use_openssl -eq 1 ; then
|
||||
AC_MSG_RESULT([Selecting OpenSSL for crypto])
|
||||
tinc_OPENSSL
|
||||
AC_DEFINE(USE_OPENSSL)
|
||||
fi
|
||||
|
||||
tinc_ZLIB
|
||||
tinc_OPENSSL
|
||||
tinc_ZLIB
|
||||
tinc_LZO
|
||||
|
||||
dnl Check if support for jumbograms is requested
|
||||
AC_ARG_ENABLE(jumbograms,
|
||||
[ --enable-jumbograms enable support for jumbograms (packets up to 9000 bytes)],
|
||||
[ AC_DEFINE(ENABLE_JUMBOGRAMS) ]
|
||||
AC_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,
|
||||
[ --enable-tracing enable checkpoint tracing (debugging only)],
|
||||
[ AC_DEFINE(ENABLE_TRACING) ]
|
||||
AC_HELP_STRING([--enable-tracing], [enable checkpoint tracing (debugging only)]),
|
||||
[ AC_DEFINE(ENABLE_TRACING, 1, [Checkpoint tracing]) ]
|
||||
)
|
||||
|
||||
AC_SUBST(INCLUDES)
|
||||
|
||||
AC_OUTPUT(Makefile
|
||||
src/Makefile
|
||||
src/pokey/Makefile
|
||||
doc/Makefile
|
||||
doc/es/Makefile
|
||||
intl/Makefile
|
||||
lib/Makefile
|
||||
m4/Makefile
|
||||
po/Makefile.in
|
||||
)
|
||||
AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile doc/tincd.8 doc/tinc.conf.5 doc/tincinclude.texi lib/Makefile po/Makefile.in m4/Makefile])
|
||||
|
||||
AC_OUTPUT
|
||||
|
|
4
cvsusers
4
cvsusers
|
@ -1,3 +1,3 @@
|
|||
zarq:Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
guus:Guus Sliepen <guus@sliepen.warande.net>
|
||||
zarq:Ivo Timmermans <ivo@o2w.nl>
|
||||
guus:Guus Sliepen <guus@sliepen.eu.org>
|
||||
wsl:Wessel Dankers <wsl@nl.linux.org>
|
||||
|
|
365
doc/CONNECTIVITY
365
doc/CONNECTIVITY
|
@ -1,7 +1,7 @@
|
|||
This document describes how nodes in a VPN find and connect to eachother and
|
||||
maintain a stable network.
|
||||
|
||||
Copyright 2001-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright 2001-2002 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this documentation provided the copyright notice and this
|
||||
|
@ -12,343 +12,34 @@ maintain a stable network.
|
|||
provided that the entire resulting derived work is distributed
|
||||
under the terms of a permission notice identical to this one.
|
||||
|
||||
$Id: CONNECTIVITY,v 1.2 2002/04/12 08:25:01 guus Exp $
|
||||
$Id: CONNECTIVITY,v 1.3 2003/08/24 20:38:18 guus Exp $
|
||||
|
||||
1. Problem
|
||||
1. Synchronisation
|
||||
==================
|
||||
|
||||
Each tinc daemon has zero or more connections to other tinc daemons. It will
|
||||
try to keep its own information synchronised with the other tinc daemons. If
|
||||
one of its peers sends information, the tinc daemon will check if it is new
|
||||
information. If so, it will update its own information and forward the new
|
||||
information to all the other peers.
|
||||
|
||||
This scheme will make sure that after a short amount of time all tinc daemons
|
||||
share the same information. It will also almost completely prevent information
|
||||
from looping, because "new" information that is already known is ignored and
|
||||
not forwarded any further. However, since information can also be deleted
|
||||
there's the possibility of a looping sequence of add/delete messages. This is
|
||||
resolved by additionaly adding a unique identifier to each broadcasted message.
|
||||
Messages are dropped if the same message with that identifier has already been
|
||||
seen.
|
||||
|
||||
2. Routing
|
||||
==========
|
||||
|
||||
We have a set of nodes (A, B, C, ...) that are part of the same VPN. They need
|
||||
to connect to eachother and form a single graph that satisfies the tree
|
||||
property.
|
||||
Every node tells its peers to which other peers it is connected. This way
|
||||
every node will eventually know every connection every node has on the VPN.
|
||||
Each node will use graph algorithms to determine if other nodes are reachable or not and
|
||||
what the best route is to other nodes.
|
||||
|
||||
There is the possibility that loops are formed, the offending connections must
|
||||
be eliminated.
|
||||
|
||||
Suppose we start with two smaller graphs that want to form a single larger
|
||||
graph. Both graphs consist of three nodes:
|
||||
|
||||
A-----B-----C
|
||||
|
||||
|
||||
|
||||
D-----E-----F
|
||||
|
||||
It is very well possible that A wants to connect to D, and F wants to connect
|
||||
to C, both at the same time. The following loop will occur:
|
||||
|
||||
A-----B-----C
|
||||
| ^
|
||||
| |
|
||||
v |
|
||||
D-----E-----F
|
||||
|
||||
The situation described here is totally symmetric, there is no preference to
|
||||
one connection over the other. The problem of resolving the loop, maintaining
|
||||
consistency and stability is therefore not a trivial one.
|
||||
|
||||
What happens when A---D and C---F are connected to eachother? They exchange
|
||||
lists of known hosts. A knows of B and C, and D knows of E and F. The protocol
|
||||
defines ADD_HOST messages, from now on we will say that "node X sends and
|
||||
ADD_HOST(Y) to Z".
|
||||
|
||||
There are two possible scenarios: either both A---D and C---F finish
|
||||
authentication at the same time, or A---D finishes first, so that ADD_HOST
|
||||
messages will reach C and F before they finish authentication.
|
||||
|
||||
1.1 A---D finishes first
|
||||
------------------------
|
||||
|
||||
After A---D authentication finishes the following actions are taken:
|
||||
|
||||
1 A sends ADD_HOST(B) to D
|
||||
A sends ADD_HOST(C) to D
|
||||
D sends ADD_HOST(E) to A
|
||||
D sends ADD_HOST(F) to A
|
||||
|
||||
2 A sends ADD_HOST(D) to B
|
||||
A receives ADD_HOST(E) from D:
|
||||
A sends ADD_HOST(E) to B
|
||||
A receives ADD_HOST(F) from D:
|
||||
A sends ADD_HOST(F) to B
|
||||
D sends ADD_HOST(A) to E
|
||||
D receives ADD_HOST(B) from A:
|
||||
D sends ADD_HOST(B) to E
|
||||
D receives ADD_HOST(C) from A:
|
||||
D sends ADD_HOST(C) to E
|
||||
|
||||
3 B receives ADD_HOST(D) from A,
|
||||
B sends ADD_HOST(D) to C
|
||||
B receives ADD_HOST(E) from A:
|
||||
B sends ADD_HOST(E) to C
|
||||
B receives ADD_HOST(F) from A:
|
||||
B sends ADD_HOST(F) to C
|
||||
E receives ADD_HOST(A) from D:
|
||||
E sends ADD_HOST(A) to F
|
||||
E receives ADD_HOST(B) from D:
|
||||
E sends ADD_HOST(B) to F
|
||||
E receives ADD_HOST(C) from D:
|
||||
E sends ADD_HOST(C) to F
|
||||
|
||||
4 C receives ADD_HOST(D) from B.
|
||||
C receives ADD_HOST(E) from B.
|
||||
C receives ADD_HOST(F) from B.
|
||||
F receives ADD_HOST(A) from E.
|
||||
F receives ADD_HOST(B) from E.
|
||||
F receives ADD_HOST(C) from E.
|
||||
|
||||
Then C---F authentication finishes, the following actions are taken:
|
||||
|
||||
1 C notes that F is already known:
|
||||
Connection is closed.
|
||||
F notes that C is already known:
|
||||
Connection is closed.
|
||||
|
||||
1.2 Both A---D and C---F finish at the same time.
|
||||
-------------------------------------------------
|
||||
|
||||
1 A sends ADD_HOST(B) to D
|
||||
A sends ADD_HOST(C) to D
|
||||
D sends ADD_HOST(E) to A
|
||||
D sends ADD_HOST(F) to A
|
||||
|
||||
C sends ADD_HOST(A) to F
|
||||
C sends ADD_HOST(B) to F
|
||||
F sends ADD_HOST(D) to C
|
||||
F sends ADD_HOST(E) to C
|
||||
|
||||
2 A sends ADD_HOST(D) to B
|
||||
A receives ADD_HOST(E) from D:
|
||||
A sends ADD_HOST(E) to B
|
||||
A receives ADD_HOST(F) from D:
|
||||
A sends ADD_HOST(F) to B
|
||||
D sends ADD_HOST(A) to E
|
||||
D receives ADD_HOST(B) from A:
|
||||
D sends ADD_HOST(B) to E
|
||||
D receives ADD_HOST(C) from A:
|
||||
D sends ADD_HOST(C) to E
|
||||
|
||||
C sends ADD_HOST(F) to B
|
||||
C receives ADD_HOST(D) from F:
|
||||
A sends ADD_HOST(D) to B
|
||||
C receives ADD_HOST(E) from F:
|
||||
A sends ADD_HOST(E) to B
|
||||
F sends ADD_HOSTS(C) to E
|
||||
F receives ADD_HOST(A) from C:
|
||||
D sends ADD_HOST(A) to E
|
||||
F receives ADD_HOST(B) from C:
|
||||
D sends ADD_HOST(B) to E
|
||||
|
||||
3 B receives ADD_HOST(D) from A,
|
||||
B sends ADD_HOST(D) to C
|
||||
B receives ADD_HOST(E) from A:
|
||||
B sends ADD_HOST(E) to C
|
||||
B receives ADD_HOST(F) from A:
|
||||
B sends ADD_HOST(F) to C
|
||||
E receives ADD_HOST(A) from D:
|
||||
E sends ADD_HOST(A) to F
|
||||
E receives ADD_HOST(B) from D:
|
||||
E sends ADD_HOST(B) to F
|
||||
E receives ADD_HOST(C) from D:
|
||||
E sends ADD_HOST(C) to F
|
||||
|
||||
B receives ADD_HOST(F) from C, and notes that is is already known:
|
||||
<insert solution here>
|
||||
B receives ADD_HOST(D) from C, and notes that is is already known:
|
||||
<insert solution here>
|
||||
B receives ADD_HOST(E) from C, and notes that is is already known:
|
||||
<insert solution here>
|
||||
E receives ADD_HOST(C) from F, and notes that is is already known:
|
||||
<insert solution here>
|
||||
E receives ADD_HOST(A) from F, and notes that is is already known:
|
||||
<insert solution here>
|
||||
E receives ADD_HOST(B) from F, and notes that is is already known:
|
||||
<insert solution here>
|
||||
|
||||
4 A receives ADD_HOST(D) from B, and notes that it is already known:
|
||||
<insert solution here>
|
||||
A receives ADD_HOST(E) from B, and notes that it is already known:
|
||||
<insert solution here>
|
||||
A receives ADD_HOST(F) from B, and notes that it is already known:
|
||||
<insert solution here>
|
||||
F receives ADD_HOST(A) from E, and notes that it is already known:
|
||||
<insert solution here>
|
||||
F receives ADD_HOST(B) from E, and notes that it is already known:
|
||||
<insert solution here>
|
||||
F receives ADD_HOST(B) from E, and notes that it is already known:
|
||||
<insert solution here>
|
||||
|
||||
...
|
||||
|
||||
1.2.1 Augmenting ADD_HOST
|
||||
-------------------------
|
||||
|
||||
A solution would be to augment ADD_HOST with an extra parameter, the nexthop of
|
||||
the added host:
|
||||
|
||||
3 B receives ADD_HOST(D,A) from A,
|
||||
B sends ADD_HOST(D,A) to C
|
||||
B receives ADD_HOST(E,D) from A:
|
||||
B sends ADD_HOST(E,D) to C
|
||||
B receives ADD_HOST(F,E) from A:
|
||||
B sends ADD_HOST(F,E) to C
|
||||
E receives ADD_HOST(A,D) from D:
|
||||
E sends ADD_HOST(A,D) to F
|
||||
E receives ADD_HOST(B,A) from D:
|
||||
E sends ADD_HOST(B,A) to F
|
||||
E receives ADD_HOST(C,B) from D:
|
||||
E sends ADD_HOST(C,B) to F
|
||||
|
||||
B receives ADD_HOST(F,C) from C, and notes that F is already known:
|
||||
<insert solution here>
|
||||
B receives ADD_HOST(D,E) from C, and notes that D is already known:
|
||||
<insert solution here>
|
||||
B receives ADD_HOST(E,F) from C, and notes that E is already known:
|
||||
<insert solution here>
|
||||
E receives ADD_HOST(C,F) from F, and notes that C is already known:
|
||||
<insert solution here>
|
||||
E receives ADD_HOST(A,B) from F, and notes that A is already known:
|
||||
<insert solution here>
|
||||
E receives ADD_HOST(B,C) from F, and notes that B is already known:
|
||||
<insert solution here>
|
||||
|
||||
So, B and E have to make a choice. Which ADD_HOST is going to win? Fortunately,
|
||||
since the ADD_HOST messages are augmented, they have an extra piece of
|
||||
information they can use to decide in a deterministic way which one is going to
|
||||
win. For example, B got ADD_HOST(F,E) and ADD_HOST(F,C). Since "E" > "C", it
|
||||
could let ADD_HOST(F,E) win.
|
||||
|
||||
B receives ADD_HOST(F,C) from C, and notes that F is already known:
|
||||
since "C" < "E", B ignores ADD_HOST(F,E)
|
||||
B sends ADD_HOST(F,C) to A
|
||||
...
|
||||
E receives ADD_HOST(C,F) from F, and notes that C is already known:
|
||||
since "F" > "B", E removes the ADD_HOST(C,B) in favour of the new one
|
||||
E sends ADD_HOST(C,F) to D
|
||||
|
||||
4 A receives ADD_HOST(F,E) from B, and notes that F is already known:
|
||||
since "E" < "D", A ignores ADD_HOST(F,D).
|
||||
...
|
||||
D receives ADD_HOST(C,F) from E, and notes that C is already known:
|
||||
since "F" > "B", D removes the ADD_HOST(C,B),
|
||||
closes the connection with C, in favour of the new one.
|
||||
|
||||
Ok, time to forget this crap.
|
||||
|
||||
1.2.2
|
||||
-----
|
||||
|
||||
The problem with the current ADD/DEL_HOST technique is that each host only
|
||||
knows the general direction in which to send packets for the other hosts. It
|
||||
really doesn't know much about the true topology of the network, only about
|
||||
it's direct neighbours. With so little information each host cannot make a
|
||||
certain decision which it knows for sure all the others will decide too.
|
||||
|
||||
Let's do something totally different. Instead of notifying every host of the
|
||||
addition of a new host, which is represented by a vertex in a graph, lets send
|
||||
out notifications of new connections, which are the edges in a graph. This is
|
||||
rather cheap, since our graphs are (almost) spanning trees, there is
|
||||
approximately one edge for each vertex in the graph, so we don't need to send
|
||||
more messages. Furthermore, an edge is characterized by two vertices, so we
|
||||
only send a fixed amount of extra information. The size/complexity of the
|
||||
problem therefore does not increase much.
|
||||
|
||||
What is the advantage of notifying each vertex of new edges instead of new
|
||||
vertices? Well, all the vertices now know exactly which connections are made
|
||||
between each host. This was not known with the former schemes.
|
||||
|
||||
Ok back to our problem:
|
||||
|
||||
A-----B-----C
|
||||
|
||||
|
||||
|
||||
D-----E-----F
|
||||
|
||||
Edges are undirected, and are characterised by the vertices it connects, sorted
|
||||
alphabetically, so the edges in the two graphs are:
|
||||
|
||||
(A,B), (B,C), (D,E) and (E,F).
|
||||
|
||||
So again we have that A wants to connect to D, and F wants to connect to C,
|
||||
both at the same time. The following loop will occur:
|
||||
|
||||
A-----B-----C
|
||||
| ^
|
||||
| |
|
||||
v |
|
||||
D-----E-----F
|
||||
|
||||
Instead of sending ADD_HOSTs, lets assume the hosts send ADD_EDGEs. So, after
|
||||
making the connections:
|
||||
|
||||
1 A sends ADD_EDGE(A,D) to B
|
||||
A sends ADD_EDGE(A,B) to D
|
||||
A sends ADD_EDGE(B,C) to D
|
||||
D sends ADD_EDGE(A,D) to E
|
||||
D sends ADD_EDGE(D,E) to A
|
||||
D sends ADD_EDGE(E,F) to A
|
||||
|
||||
C sends ADD_EDGE(C,F) to B
|
||||
C sends ADD_EDGE(A,B) to F
|
||||
C sends ADD_EDGE(B,C) to F
|
||||
F sends ADD_EDGE(C,F) to E
|
||||
F sends ADD_EDGE(D,E) to C
|
||||
F sends ADD_EDGE(E,F) to C
|
||||
|
||||
2 B receives ADD_EDGE(A,D) from A:
|
||||
B sends ADD_EDGE(A,D) to C
|
||||
B receives ADD_EDGE(D,E) from A:
|
||||
B sends ADD_EDGE(D,E) to C
|
||||
B receives ADD_EDGE(E,F) from A:
|
||||
B sends ADD_EDGE(E,F) to C
|
||||
...
|
||||
|
||||
B receives ADD_EDGE(C,F) from C, notes that both C and F are already known,
|
||||
but that the edge (C,F) was not known, so a loop has been created:
|
||||
<resolve loop here>
|
||||
|
||||
Ok, how to resolve the loop? Remeber, we want to do that in such a way that it
|
||||
is consistent with the way all the other hosts resolve the loop. Here is the
|
||||
things B does when it notices that a loop is going to be formed:
|
||||
|
||||
B performs a Breadth First Search from the first element of the list of all
|
||||
known hosts sorted alfabetically, in this case A, and thereby finds a
|
||||
spanning tree. (This might later be changed into a minimum spanning tree
|
||||
alhorithm, but the key point here is that all hosts do this with exactly the
|
||||
same starting parameters.) All known edges that are not in the spanning tree
|
||||
are marked inactive.
|
||||
|
||||
An edge marked inactive does not mean anything, unless this edge is connected
|
||||
to B itself. In that case, B will stop sending messages over that edge. B might
|
||||
consider closing this edge, but this is not really needed. Keeping it means no
|
||||
DEL_EDGE has to be sent for it, and if another edge is removed (which will
|
||||
quite certainly split the graph if it's a spanning tree), this edge might be
|
||||
reactivated, without the need of sending a new ADD_EDGE for it. On the other
|
||||
hand, we mustn't keep to many inactive edges, because we want to keep the
|
||||
number of known edges linear to the number of hosts (otherwise the size of the
|
||||
problem will grow quadratically).
|
||||
|
||||
So, since B didn't deactivate one of it's own edges, it forwards the
|
||||
ADD_EDGE(C,F) to A, which also does a BFS, and so on, until it reaches F. F of
|
||||
course also does a BFS, notes that is is one of it's own edges. It deactivates
|
||||
the edge (C,F), and consequently will not forward the ADD_EDGE(C,F) to C
|
||||
anymore. In the mean time, C got messages from B which will make C do the same.
|
||||
|
||||
Ok, suppose a DEL_EDGE was sent, and it means an inactive edge has to be
|
||||
reactivated. The vertices connected by that edge must exchange their entire
|
||||
knowledge of edges again, because in the mean time other messages could have
|
||||
been sent, which were not properly forwarded. Take this example:
|
||||
|
||||
X C-----D
|
||||
| | |
|
||||
| | |
|
||||
v | |
|
||||
A-----B- - -E
|
||||
|
||||
The edge (B,E) is inactive. X is trying to make a new connection with A. A
|
||||
sends an ADD_EDGE(A,X) to B, which forwards it to C. At that time, the
|
||||
connection between C and D goes down, so C sends a DEL_EDGE(C,D) to B, and D
|
||||
sends a DEL_EDGE(C,D) to E. If we just allow (B,E) to be reactivated again
|
||||
without anything else, then E and D will never have received the ADD_EDGE(A,X).
|
||||
So, B and E have to exchange edges again, and propagate them to the hosts they
|
||||
already know.
|
||||
Because all nodes share the same information, using a deterministic algorithm
|
||||
each node will calculate the same minimum spanning tree for the entire VPN.
|
||||
The MST will be used to send broadcast VPN packets.
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
# Having a separate GNUmakefile lets me use features of GNU make
|
||||
# to generate the man pages.
|
||||
# This makefile is used only if you run GNU Make.
|
||||
# It is necessary if you want to build targets usually of interest
|
||||
# only to the maintainer.
|
||||
|
||||
have-Makefile := $(shell test -f Makefile && echo yes)
|
||||
|
||||
# If the user runs GNU make but has not yet run ./configure,
|
||||
# give them a diagnostic.
|
||||
ifeq ($(have-Makefile),yes)
|
||||
|
||||
include Makefile
|
||||
include $(srcdir)/Makefile.maint
|
||||
|
||||
else
|
||||
|
||||
all:
|
||||
@echo There seems to be no Makefile in this directory.
|
||||
@echo "You must run ./configure before running \`make'."
|
||||
@exit 1
|
||||
|
||||
endif
|
175
doc/HOWTO
175
doc/HOWTO
|
@ -1,175 +0,0 @@
|
|||
==============
|
||||
The TINC HOWTO
|
||||
==============
|
||||
|
||||
Wessel Dankers
|
||||
wsl@nl.linux.org
|
||||
|
||||
Introduction
|
||||
------------
|
||||
Tinc is a system to create a virtual ethernet network on top of an existing
|
||||
infrastructure. This infrastructure can be anything from modem lines to
|
||||
gigabit ethernet networks, as long as they talk IP. Once you install and
|
||||
configure tinc, your host will get an extra IP address, just like it would
|
||||
when you stick an extra ethernet card into it. Using this IP address, it can
|
||||
communicate with all hosts in its virtual network using strong encryption.
|
||||
|
||||
If you install Tinc on a router (and pick your numbers correctly) you can
|
||||
have the router forward all packets. This way you can---instead of
|
||||
connecting hosts---connect entire sites together! Now you need only one
|
||||
outgoing network connection for both internet and intranet.
|
||||
|
||||
Architecture
|
||||
------------
|
||||
When a few Tinc daemons are running they will try to seek contact with
|
||||
eachother. A daemon is all the time connected to a few other daemons,
|
||||
but if traffic is required with a daemon it doesn't know yet, it will
|
||||
instantly contact it and exchange keys. These so-called meta-connections
|
||||
are made over TCP, using encryption of course.
|
||||
|
||||
When actual traffic has to be sent, a daemon checks his connection list to
|
||||
see if the addressee is known (and makes contact with it if neccessary).
|
||||
All packets are then sent using UDP to the other host, just like in a real
|
||||
network. If a packet gets lost, the connection layer of Linux will resend
|
||||
the packet, just like it would over a normal network.
|
||||
|
||||
Once in a while the daemons will renegotiate keys so that even if a cracker
|
||||
breaks one, it'll be of limited use.
|
||||
|
||||
Getting Tinc
|
||||
------------
|
||||
Before you fetch the latest tarball, you might want to check if there's a
|
||||
package for your Linux distribution. One of the main authors is a Debian
|
||||
Developer, so you can expect the Debian packages to be very up to date.
|
||||
|
||||
The official website for Tinc can be found at http://tinc.nl.linux.org/.
|
||||
There you can find Debian packages, RPM's and of course... the tarball!
|
||||
Since we run Doohickey Linux Pro 1.0, for which no package exists (or
|
||||
indeed the distribution itself) we shall compile the package ourselves.
|
||||
|
||||
Building
|
||||
--------
|
||||
The Tinc source adheres to so many standards it makes you head spin.
|
||||
Even the debug messages have been localized! Amazing. Tinc also comes
|
||||
with a configuration script. If you like to see what is there to
|
||||
configure run ./configure --help | more. If you don't have time for such
|
||||
nonsense:
|
||||
|
||||
./configure --sysconfdir=/etc
|
||||
|
||||
This will see if your system is nice enough to run tinc on, and will
|
||||
create some Makefiles and other stuff which will together build tinc.
|
||||
|
||||
make
|
||||
make install
|
||||
|
||||
The first will do the actual build, the second copies all files into place.
|
||||
|
||||
The kernel
|
||||
----------
|
||||
Next you will have to configure the kernel to support the tap device.
|
||||
It is important that you run a recent kernel, but anything after 2.2.16
|
||||
will do. You have to enable both the netlink device AND the ethertap
|
||||
device (in that order). Enable them as modules!
|
||||
Compile, install =) You don't even have to reboot.
|
||||
|
||||
Picking your numbers
|
||||
--------------------
|
||||
The first thing we should do is pick network numbers. Tinc has a very
|
||||
peculiar taste for network numbers, which is caused by the way it routes
|
||||
traffic. However, it turns out to be really handy if you want to use
|
||||
your tinc host as a router for a site.
|
||||
|
||||
The numbers have to be in a range that is not yet in use in your existing,
|
||||
real network! In this example we will use numbers from the 192.168.0/16
|
||||
range. This is standard CIDR notation for all IP addresses from 192.168.0.0
|
||||
to 192.168.255.255. The /16 means that the first 16 bits form the network
|
||||
part.
|
||||
|
||||
It is common practice for Tinc networks to use private (RFC 1918) addresses.
|
||||
This is not necessary, but it would be a waste to use official addresses
|
||||
for a private network!
|
||||
|
||||
In the example we will connect three machines: f00f, fdiv and hlt. We will
|
||||
give each an address, but not just that, also a slice of our address space
|
||||
to play with.
|
||||
|
||||
Host Real address Tinc network
|
||||
---------------------------------------------------
|
||||
f00f 126.202.37.20 192.168.1.1/24
|
||||
fdiv 126.202.37.81 192.168.2.1/24
|
||||
hlt 103.22.1.218 192.168.3.1/24
|
||||
|
||||
It is very important that none of the Tinc netmasks overlap! Note how the
|
||||
192.168.0/16 network covers the entire address space of the three hosts.
|
||||
We will refer to the 192.168.0/16 network as the `umbrella' from now on.
|
||||
As you can see we can fit 256 hosts into this umbrella this way, which is
|
||||
also the practical maximum for tinc. Let's name our VPN 'fubar'.
|
||||
|
||||
The configuration file
|
||||
----------------------
|
||||
Let's create a configuration file for f00f. We have to put it in
|
||||
/etc/tinc/fubar because that's how we named our VPN.
|
||||
|
||||
MyOwnVPNIP = 192.168.1.1/24
|
||||
VpnMask = 255.255.0.0
|
||||
ConnectTo = 126.202.37.81
|
||||
ConnectTo = 103.22.1.218
|
||||
TapDevice = /dev/tap0
|
||||
|
||||
The first two lines tell Tinc about the numbers we have chosen above.
|
||||
Using the ConnectTo lines, the daemon will seek contact with the rest of
|
||||
the umbrella. It's possible to configure any number of ConnectTo lines,
|
||||
you can even omit them so that it just sits and waits until someone else
|
||||
contacts it. Until someone does, the poor daemon won't be able to send
|
||||
any data because it doesn't know where everybody is.
|
||||
The TapDevice is where the tinc daemon will interface with the kernel.
|
||||
|
||||
The passphrases
|
||||
---------------
|
||||
We will have to generate keys for ourselves, and get a key from everybody
|
||||
we want to ConnectTo. All of these go into a directory named
|
||||
/etc/tinc/fubar/passphrases. PROTECT THIS DIRECTORY!
|
||||
|
||||
mkdir -m 700 /etc/tinc/fubar/passphrases
|
||||
|
||||
To generate our own key:
|
||||
|
||||
genauth 1024 >/etc/tinc/fubar/passphrases/local
|
||||
|
||||
You should then proceed to give this key to anyone who wants to ConnectTo
|
||||
you. DO THIS IN A SECURE MANNER! Anyone who has this number can do icky
|
||||
things to the umbrella network! Encrypt it using PGP, GPG or another
|
||||
program using asymmetric keys. Read it over the phone (without anyone
|
||||
listening of course). Send it by snailmail. Write the key down and bring
|
||||
it to your partners personally!
|
||||
|
||||
If you get any keys from your partners, store them under their network
|
||||
number. For example, the key we get from fdiv's network administrator
|
||||
will be stored in /etc/tinc/fubar/passphrases/192.168.2.0 (note the 0).
|
||||
|
||||
Running the daemon
|
||||
------------------
|
||||
If you use a package manager to install Tinc, the startup scripts use a file
|
||||
called /etc/tinc/nets.boot to see which umbrella's exist. It has a line
|
||||
per VPN, and lines starting with a # are ignored. Ours will contain:
|
||||
|
||||
# Example VPN from the HOWTO
|
||||
fubar
|
||||
|
||||
In Debian, /etc/init.d/tinc start will start the daemons.
|
||||
|
||||
If you use Doohickey Linux just like we do, you'll have to edit the systems
|
||||
startup scripts by hand. It should contain something along the lines of:
|
||||
|
||||
insmod ethertap -s --name=tap0 unit=0
|
||||
ifconfig tap0 hw ether fe:fd:c0:a8:01:01
|
||||
ifconfig tap0 192.168.1.1 netmask 255.255.0.0 broadcast 192.168.255.255 -arp
|
||||
|
||||
There are two things to note here! First, the MAC address of the ethertap
|
||||
device is very important. It must start with fe:fd, and end in the
|
||||
hexadecimal representation of the VPN IP number.
|
||||
Second, the netmask of the tap device is set to that of the umbrella!
|
||||
|
||||
--
|
||||
$Id: HOWTO,v 1.6 2002/04/12 08:25:01 guus Exp $
|
|
@ -1,20 +1,12 @@
|
|||
## Process this file with automake to get Makefile.in
|
||||
|
||||
SUBDIRS = es
|
||||
|
||||
info_TEXINFOS = tinc.texi
|
||||
|
||||
dyn_MANS =
|
||||
man_aux = $(dyn_MANS:.8=.x)
|
||||
man_MANS = tincd.8 tinc.conf.5
|
||||
|
||||
man_MANS = tincd.8 tinc.conf.5 $(dyn_MANS)
|
||||
EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.conf.5.in sample-config.tar.gz
|
||||
|
||||
PERL = @PERL@
|
||||
HELP2MAN = help2man
|
||||
MAINTAINERCLEANFILES = $(dyn_MANS)
|
||||
|
||||
EXTRA_DIST = $(man_MANS) $(HELP2MAN) $(man_aux) \
|
||||
Makefile.maint GNUmakefile Makefile.summ sample-config.tar.gz
|
||||
CLEANFILES = *.html
|
||||
|
||||
# Use `ginstall' in the definition of man_MANS to avoid
|
||||
# confusion with the `install' target. The install rule transforms `ginstall'
|
||||
|
@ -23,3 +15,12 @@ transform = s/ginstall/install/; @program_transform_name@
|
|||
|
||||
# For additional rules usually of interest only to the maintainer,
|
||||
# see GNUmakefile and Makefile.maint.
|
||||
|
||||
sample-config.tar.gz: sample-config
|
||||
GZIP=$(GZIP_ENV) $(AMTAR) chozf sample-config.tar.gz sample-config
|
||||
|
||||
texi2html: tinc.texi
|
||||
texi2html -split=chapter tinc.texi
|
||||
|
||||
%.html: $(man_MANS)
|
||||
w3mman2html $< > $@
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
# This -*- Makefile -*- uses features of GNU make.
|
||||
# It is included via GNUmakefile.
|
||||
|
||||
# The following one line summaries were extracted from the
|
||||
# original man pages using this bit of sh code:
|
||||
# for i in *.1; do echo "$i: "|tr -d '\012'; \
|
||||
# grep -A1 SH.NAME $i|sed '/SH NAME/d;s/^[^ ][^ ]* .- //'; done
|
||||
|
||||
include Makefile.summ
|
||||
|
||||
HELP2MAN-run = $(PERL) -w -- $(srcdir)/$(HELP2MAN)
|
||||
|
||||
# Depend on configure.in to get version number changes.
|
||||
$(dyn_MANS): $(top_srcdir)/configure.in
|
||||
|
||||
# Depend on the source file containing the --help text.
|
||||
# Filter out irregular cases.
|
||||
regular-men = $(filter-out $(irregular-men),$(dyn_MANS))
|
||||
$(regular-men): %.8: $(top_srcdir)/src/%.c
|
||||
|
||||
executable = $(patsubst %/install,%/ginstall, ../src/$(basename $@))
|
||||
$(dyn_MANS): %.8: %.x $(HELP2MAN)
|
||||
@if test -f $(executable); then \
|
||||
echo "Updating man page $@"; \
|
||||
rm -f $@-t $@; \
|
||||
$(HELP2MAN-run) \
|
||||
--name="$($(basename $@)-summary)" \
|
||||
--include=$(basename $@).x \
|
||||
$(executable) > $@-t; \
|
||||
chmod -w $@-t; \
|
||||
mv $@-t $@; \
|
||||
else \
|
||||
echo "WARNING: The man page $@ cannot be updated yet."; \
|
||||
echo " Retry once the corresponding executable is built."; \
|
||||
fi
|
||||
|
||||
sample-config.tar.gz:
|
||||
GZIP=$(GZIP_ENV) $(AMTAR) chozf sample-config.tar.gz sample-config
|
|
@ -1,2 +0,0 @@
|
|||
# -*- makefile -*-
|
||||
tincd-summary = tinc VPN daemon
|
|
@ -1,7 +1,7 @@
|
|||
This is the network infrastructure documentation for tinc, a Virtual Private
|
||||
Network daemon.
|
||||
|
||||
Copyright 2001-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright 2001-2002 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this documentation provided the copyright notice and this
|
||||
|
@ -12,7 +12,7 @@ Network daemon.
|
|||
provided that the entire resulting derived work is distributed
|
||||
under the terms of a permission notice identical to this one.
|
||||
|
||||
$Id: NETWORKING,v 1.2 2002/04/12 08:25:01 guus Exp $
|
||||
$Id: NETWORKING,v 1.3 2003/08/24 20:38:18 guus Exp $
|
||||
|
||||
1. Packet flow
|
||||
==============
|
||||
|
|
86
doc/PROTOCOL
86
doc/PROTOCOL
|
@ -1,7 +1,7 @@
|
|||
This is the protocol documentation for tinc, a Virtual Private Network daemon.
|
||||
|
||||
Copyright 2000-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2000-2002 Ivo Timmmermans <itimmermans@bigfoot.com>
|
||||
Copyright 2000-2002 Guus Sliepen <guus@sliepen.eu.org>,
|
||||
2000-2002 Ivo Timmmermans <ivo@o2w.nl>
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this documentation provided the copyright notice and this
|
||||
|
@ -12,7 +12,7 @@ This is the protocol documentation for tinc, a Virtual Private Network daemon.
|
|||
provided that the entire resulting derived work is distributed
|
||||
under the terms of a permission notice identical to this one.
|
||||
|
||||
$Id: PROTOCOL,v 1.2 2002/04/12 08:25:01 guus Exp $
|
||||
$Id: PROTOCOL,v 1.3 2003/08/24 20:38:18 guus Exp $
|
||||
|
||||
|
||||
1. Protocols used in tinc
|
||||
|
@ -69,24 +69,62 @@ synchronised.
|
|||
|
||||
daemon message
|
||||
--------------------------------------------------------------------------
|
||||
origin ADD_EDGE node1 12.23.34.45 655 node2 21.32.43.54 655 222 0
|
||||
| | | \___________________/ | +-> options
|
||||
| | | | +----> weight
|
||||
| | | +----------------> see below
|
||||
| | +--> UDP port
|
||||
| +----------> real address
|
||||
+------------------> name of node on one side of the edge
|
||||
origin ADD_EDGE node1 node2 21.32.43.54 655 222 0
|
||||
| | | | | +-> options
|
||||
| | | | +----> weight
|
||||
| | | +--------> UDP port of node2
|
||||
| | +----------------> real address of node2
|
||||
| +-------------------------> name of destination node
|
||||
+-------------------------------> name of source node
|
||||
|
||||
origin ADD_SUBNET node 192.168.1.0/24
|
||||
| | +--> prefixlength
|
||||
| +--------> IPv4 network address
|
||||
| +--------> network address
|
||||
+------------------> owner of this subnet
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
The ADD_EDGE messages are to inform other tinc daemons that a connection between
|
||||
two nodes exist. The address of the destination node is available so that
|
||||
VPN packets can be sent directly to that node.
|
||||
|
||||
The ADD_SUBNET messages inform other tinc daemons that certain subnets belong
|
||||
to certain nodes. tinc will use it to determine to which node a VPN packet has
|
||||
to be sent.
|
||||
|
||||
message
|
||||
------------------------------------------------------------------
|
||||
DEL_EDGE node1 node2
|
||||
| +----> name of destination node
|
||||
+----------> name of source node
|
||||
|
||||
DEL_SUBNET node 192.168.1.0/24
|
||||
| | +--> prefixlength
|
||||
| +--------> network address
|
||||
+------------------> owner of this subnet
|
||||
------------------------------------------------------------------
|
||||
|
||||
In case a connection between two daemons is closed or broken, DEL_EDGE messages
|
||||
are sent to inform the other daemons of that fact. Each daemon will calculate a
|
||||
new route to the the daemons, or mark them unreachable if there isn't any.
|
||||
|
||||
message
|
||||
------------------------------------------------------------------
|
||||
REQ_KEY origin destination
|
||||
| +--> name of the tinc daemon it wants the key from
|
||||
+----------> name of the daemon that wants the key
|
||||
|
||||
ANS_KEY origin destination 4ae0b0a82d6e0078 91 64 4
|
||||
| | \______________/ | | +--> MAC length
|
||||
| | | | +-----> digest algorithm
|
||||
| | | +--------> cipher algorithm
|
||||
| | +--> 128 bits key
|
||||
| +--> name of the daemon that wants the key
|
||||
+----------> name of the daemon that uses this key
|
||||
|
||||
KEY_CHANGED origin
|
||||
+--> daemon that has changed it's packet key
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
The keys used to encrypt VPN packets are not sent out directly. This is
|
||||
because it would generate a lot of traffic on VPNs with many daemons, and
|
||||
chances are that not every tinc daemon will ever send a packet to every
|
||||
|
@ -97,33 +135,17 @@ act as a proxy and forward its copy back to the requestor.
|
|||
|
||||
daemon message
|
||||
--------------------------------------------------------------------------
|
||||
daemon REQ_KEY origin destination
|
||||
| +--> name of the tinc daemon it wants the key from
|
||||
+----------> name of the daemon that wants the key
|
||||
|
||||
daemon ANS_KEY origin destination 4ae0b0a82d6e0078 91 64 4
|
||||
| | \______________/ | | +--> MAC length
|
||||
| | | | +-----> digest algorithm
|
||||
| | | +--------> cipher algorithm
|
||||
| | +--> 128 bits key
|
||||
| +--> name of the daemon that wants the key
|
||||
+----------> name of the daemon that uses this key
|
||||
|
||||
daemon KEY_CHANGED origin
|
||||
+--> daemon that has changed it's packet key
|
||||
origin PING
|
||||
dest. PONG
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
There is also a mechanism to check if hosts are still alive. Since network
|
||||
failures or a crash can cause a daemon to be killed without properly
|
||||
shutting down the TCP connection, this is necessary to keep an up to date
|
||||
connection list. Pings are sent at regular intervals, except when there
|
||||
is also some other traffic.
|
||||
|
||||
daemon message
|
||||
--------------------------------------------------------------------------
|
||||
origin PING
|
||||
dest. PONG
|
||||
--------------------------------------------------------------------------
|
||||
is also some other traffic. A little bit of salt (random data) is added
|
||||
with each PING and PONG message, to make sure that long sequences of PING/PONG
|
||||
messages without any other traffic won't result in known plaintext.
|
||||
|
||||
This basically covers everything that is sent over the meta connection by
|
||||
tinc.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
This is the security documentation for tinc, a Virtual Private Network daemon.
|
||||
|
||||
Copyright 2001-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
Copyright 2001-2002 Guus Sliepen <guus@sliepen.eu.org>,
|
||||
2001-2002 Wessel Dankers <wsl@nl.linux.org>
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
|
@ -12,7 +12,7 @@ This is the security documentation for tinc, a Virtual Private Network daemon.
|
|||
provided that the entire resulting derived work is distributed
|
||||
under the terms of a permission notice identical to this one.
|
||||
|
||||
$Id: SECURITY2,v 1.2 2002/04/12 08:25:01 guus Exp $
|
||||
$Id: SECURITY2,v 1.3 2003/08/24 20:38:18 guus Exp $
|
||||
|
||||
Proposed new authentication scheme
|
||||
----------------------------------
|
||||
|
@ -66,17 +66,15 @@ server CHAL_REPLY 928ffe
|
|||
After the correct challenge replies are recieved, both ends have proved
|
||||
their identity. Further information is exchanged.
|
||||
|
||||
client ACK 655 12.23.34.45 123 0
|
||||
| | | +-> options
|
||||
| | +----> estimated weight
|
||||
| +------------> IP address of server as seen by client
|
||||
+--------------------> UDP port of client
|
||||
client ACK 655 123 0
|
||||
| | +-> options
|
||||
| +----> estimated weight
|
||||
+--------> listening port of client
|
||||
|
||||
server ACK 655 21.32.43.54 321 0
|
||||
| | | +-> options
|
||||
| | +----> estimated weight
|
||||
| +------------> IP address of client as seen by server
|
||||
+--------------------> UDP port of server
|
||||
server ACK 655 321 0
|
||||
| | +-> options
|
||||
| +----> estimated weight
|
||||
+--------> listening port of server
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
This new scheme has several improvements, both in efficiency and security.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Makefile Makefile.in
|
|
@ -1,3 +0,0 @@
|
|||
## Process this file with automake to get Makefile.in
|
||||
|
||||
# Nothing to see here, go away!
|
375
doc/help2man
375
doc/help2man
|
@ -1,375 +0,0 @@
|
|||
#!/usr/bin/perl -w
|
||||
|
||||
# Generate a short man page from --help and --version output.
|
||||
# Copyright © 1997, 98 Free Software Foundation, Inc.
|
||||
|
||||
# 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
# Written by Brendan O'Dea <bod@compusol.com.au>
|
||||
|
||||
use 5.004;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use POSIX qw(strftime setlocale LC_TIME);
|
||||
|
||||
my $this_program = 'help2man';
|
||||
my $this_version = '1.006';
|
||||
my $version_info = <<EOT;
|
||||
$this_program $this_version
|
||||
|
||||
Copyright (C) 1997, 98 Free Software Foundation, Inc.
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
Written by Brendan O'Dea <bod\@compusol.com.au>
|
||||
EOT
|
||||
|
||||
my $help_info = <<EOT;
|
||||
`$this_program' generates a man page out of `--help' and `--version' output.
|
||||
|
||||
Usage: $this_program [OPTION]... EXECUTABLE
|
||||
|
||||
--name=STRING use `STRING' as the description for the NAME paragraph
|
||||
--include=FILE include material from `FILE'
|
||||
--opt-include=FILE include material from `FILE' if it exists
|
||||
--output=FILE send output to `FILE'
|
||||
--no-info suppress pointer to Texinfo manual
|
||||
--help print this help, then exit
|
||||
--version print $this_program program version number, then exit
|
||||
|
||||
EXECUTABLE should accept `--help' and `version' options.
|
||||
EOT
|
||||
|
||||
my ($include, $opt_name, $opt_include, $opt_output, $opt_no_info);
|
||||
|
||||
# Parse options.
|
||||
GetOptions (
|
||||
'name=s' => \$opt_name,
|
||||
'include=s' => \$include,
|
||||
'opt-include=s' => \$opt_include,
|
||||
'output=s' => \$opt_output,
|
||||
'no-info' => \$opt_no_info,
|
||||
help => sub { print $help_info; exit },
|
||||
version => sub { print $version_info; exit },
|
||||
) or die $help_info;
|
||||
|
||||
die $help_info unless @ARGV == 1;
|
||||
|
||||
my %include = ();
|
||||
my @include = (); # to retain order
|
||||
|
||||
# Process include file (if given). Format is:
|
||||
#
|
||||
# [section name]
|
||||
# verbatim text
|
||||
|
||||
if ($include or $opt_include)
|
||||
{
|
||||
if (open INC, $include || $opt_include)
|
||||
{
|
||||
my $sect;
|
||||
|
||||
while (<INC>)
|
||||
{
|
||||
if (/^\[([^]]+)\]/)
|
||||
{
|
||||
$sect = uc $1;
|
||||
$sect =~ s/^\s+//;
|
||||
$sect =~ s/\s+$//;
|
||||
next;
|
||||
}
|
||||
|
||||
# Silently ignore anything before the first
|
||||
# section--allows for comments and revision info.
|
||||
next unless $sect;
|
||||
|
||||
push @include, $sect unless $include{$sect};
|
||||
$include{$sect} ||= '';
|
||||
$include{$sect} .= $_;
|
||||
}
|
||||
|
||||
close INC;
|
||||
|
||||
die "$this_program: no valid information found in `$include'\n"
|
||||
unless %include;
|
||||
|
||||
# Compress trailing blank lines.
|
||||
for (keys %include)
|
||||
{
|
||||
$include{$_} =~ s/\n+$//;
|
||||
$include{$_} .= "\n" unless /^NAME$/;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
die "$this_program: can't open `$include' ($!)\n" if $include;
|
||||
}
|
||||
}
|
||||
|
||||
# Turn off localisation of executable's ouput.
|
||||
@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
|
||||
|
||||
# Turn off localisation of date (for strftime)
|
||||
setlocale LC_TIME, 'C';
|
||||
|
||||
# Grab help and version paragraphs from executable
|
||||
my @help = split /\n\n+/, `$ARGV[0] --help 2>/dev/null`
|
||||
or die "$this_program: can't get `--help' info from $ARGV[0]\n";
|
||||
|
||||
my @version = split /\n\n+/, `$ARGV[0] --version 2>/dev/null`
|
||||
or die "$this_program: can't get `--version' info from $ARGV[0]\n";
|
||||
|
||||
my $date = strftime "%B %Y", localtime;
|
||||
my $program = $ARGV[0]; $program =~ s!.*/!!;
|
||||
my $package = $program;
|
||||
my $version;
|
||||
|
||||
if ($opt_output)
|
||||
{
|
||||
unlink $opt_output
|
||||
or die "$this_program: can't unlink $opt_output ($!)\n"
|
||||
if -e $opt_output;
|
||||
|
||||
open STDOUT, ">$opt_output"
|
||||
or die "$this_program: can't create $opt_output ($!)\n";
|
||||
}
|
||||
|
||||
# The first line of the --version information is assumed to be in one
|
||||
# of the following formats:
|
||||
#
|
||||
# <version>
|
||||
# <program> <version>
|
||||
# GNU <program> <version>
|
||||
# <program> (GNU <package>) <version>
|
||||
# <program> - GNU <package> <version>
|
||||
#
|
||||
# and seperated from any copyright/author details by a blank line.
|
||||
|
||||
$_ = shift @version;
|
||||
|
||||
if (/^(\S+)\s+\((GNU\s+[^)]+)\)\s+(.*)/ or
|
||||
/^(\S+)\s+-\s*(GNU\s+\S+)\s+(.*)/)
|
||||
{
|
||||
$program = $1;
|
||||
$package = $2;
|
||||
$version = $3;
|
||||
}
|
||||
elsif (/^(GNU\s+)?(\S+)\s+(.*)/)
|
||||
{
|
||||
$program = $2;
|
||||
$package = $1 ? "$1$2" : $2;
|
||||
$version = $3;
|
||||
}
|
||||
else
|
||||
{
|
||||
$version = $_;
|
||||
}
|
||||
|
||||
$program =~ s!.*/!!;
|
||||
|
||||
# no info for `info' itself
|
||||
$opt_no_info = 1 if $program eq 'info';
|
||||
|
||||
# --name overrides --include contents
|
||||
$include{NAME} = "$program \\- $opt_name" if $opt_name;
|
||||
|
||||
# Default (useless) NAME paragraph
|
||||
$include{NAME} ||= "$program \\- manual page for $program $version";
|
||||
|
||||
# Man pages traditionally have the page title in caps.
|
||||
my $PROGRAM = uc $program;
|
||||
|
||||
# Header.
|
||||
print <<EOT;
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by $this_program $this_version.
|
||||
.TH $PROGRAM 1 "$date" "$package $version" "FSF"
|
||||
.SH NAME
|
||||
$include{NAME}
|
||||
EOT
|
||||
|
||||
my $accumulate = 1;
|
||||
my @description = ();
|
||||
|
||||
sub convert_option;
|
||||
|
||||
# Output converted --help information.
|
||||
for (@help)
|
||||
{
|
||||
chomp;
|
||||
|
||||
if (s/^Usage:\s+\S+\s+(.*)\n?//)
|
||||
{
|
||||
# Turn the usage clause into a synopsis.
|
||||
my $synopsis = '';
|
||||
|
||||
do {
|
||||
my $syn = $1;
|
||||
$syn =~ s/(([][]|\.\.+)+)/\\fR$1\\fI/g;
|
||||
$syn =~ s/^/\\fI/ unless $syn =~ s/^\\fR//;
|
||||
$syn .= '\fR';
|
||||
$syn =~ s/\\fI(\s*)\\fR/$1/g;
|
||||
|
||||
$synopsis .= ".br\n" unless $accumulate;
|
||||
$synopsis .= ".B $program\n";
|
||||
$synopsis .= "$syn\n";
|
||||
$accumulate = 0;
|
||||
} while s/^(?:Usage|\s*or):\s+\S+\s+(.*)\n?//;
|
||||
|
||||
# Include file overrides SYNOPSIS.
|
||||
print ".SH SYNOPSIS\n", $include{SYNOPSIS} || $synopsis;
|
||||
|
||||
# Dump any accumulated description text.
|
||||
print ".SH DESCRIPTION\n";
|
||||
print @description;
|
||||
|
||||
# Add additional description text from include file.
|
||||
if ($include{DESCRIPTION})
|
||||
{
|
||||
print ".PP\n" unless $include{DESCRIPTION} =~ /^\..P/;
|
||||
print $include{DESCRIPTION};
|
||||
}
|
||||
|
||||
next unless $_;
|
||||
}
|
||||
|
||||
# Accumulate text if the synopsis has not been produced yet.
|
||||
if ($accumulate)
|
||||
{
|
||||
push @description, ".PP\n" if @description;
|
||||
push @description, "$_\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# Catch start of options.
|
||||
if (/^Options:/)
|
||||
{
|
||||
print qq(.SH OPTIONS\n);
|
||||
s/Options://;
|
||||
}
|
||||
|
||||
# Catch bug report text.
|
||||
if (/^Report bugs |^Email bug reports to /)
|
||||
{
|
||||
print qq(.SH "REPORTING BUGS"\n$_\n);
|
||||
next;
|
||||
}
|
||||
|
||||
# Special case for tar 1.12: --label=NAME\nPATTERN.
|
||||
s{(\n[ \t]*)(-V,[ \t]+--label=NAME.*)\n[ \t]+PATTERN[ \t]+}
|
||||
{$1$2$1\\&...=PATTERN };
|
||||
|
||||
# Convert options.
|
||||
s/(\s)(-[][\w=-]+|\\&\S+)/$1 . convert_option $2/ge;
|
||||
|
||||
# Option subsections have second line indented.
|
||||
print qq(.SS "$1"\n) if s/^(\S.*)\n(\s)/$2/;
|
||||
|
||||
# Lines indented more than about 10 spaces may be assumed to be
|
||||
# continuations of the previous line.
|
||||
s/\n {10,}/ /g;
|
||||
|
||||
# Lines following dotted (*) or numbered points may also be
|
||||
# continued if indented to the same level as the text following
|
||||
# the point.
|
||||
1 while s{((?:^|\n)(\s+)(?:[1-9][.)]|\*)(\s+)(?:[^\n]+))\n\2 \3(\S)}
|
||||
{$1 $4}g;
|
||||
|
||||
# Indented paragraph.
|
||||
if (/^\s/)
|
||||
{
|
||||
for (split /\n/)
|
||||
{
|
||||
s/^\s+//;
|
||||
s/([^,])\s+/$1\n/;
|
||||
print ".TP\n$_\n" if $_;
|
||||
}
|
||||
}
|
||||
# Anything else.
|
||||
else
|
||||
{
|
||||
print ".PP\n$_\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Print any include items other than the ones we have already dealt
|
||||
# with.
|
||||
for (@include)
|
||||
{
|
||||
print qq(.SH "$_"\n$include{$_})
|
||||
unless /^(NAME|SYNOPSIS|DESCRIPTION|SEE ALSO)$/;
|
||||
}
|
||||
|
||||
# Refer to the real documentation.
|
||||
if ($include{'SEE ALSO'} or !$opt_no_info)
|
||||
{
|
||||
print qq(.SH "SEE ALSO"\n);
|
||||
print $include{'SEE ALSO'}, ".PP\n" if $include{'SEE ALSO'};
|
||||
|
||||
print <<EOT unless $opt_no_info;
|
||||
The full documentation for
|
||||
.B $program
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B $program
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info $program
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
EOT
|
||||
}
|
||||
|
||||
# Output converted --version information.
|
||||
for (@version)
|
||||
{
|
||||
chomp;
|
||||
|
||||
# Join hyphenated lines.
|
||||
s/([A-Za-z])-\n */$1/g;
|
||||
|
||||
# Convert copyright symbol or (c) to nroff character.
|
||||
s/Copyright\s+(?:\xa9|\([Cc]\))/Copyright \\(co/g;
|
||||
|
||||
# Insert appropriate headings for copyright and author.
|
||||
if (/^Copyright\s\\/) { print ".SH COPYRIGHT\n" }
|
||||
elsif (/^Written\s+by/) { print ".SH AUTHOR\n" }
|
||||
else { print ".PP\n"; }
|
||||
|
||||
# Insert line breaks before additional copyright messages and the
|
||||
# disclaimer.
|
||||
s/(.)\n(Copyright\s|This is free software)/$1\n.br\n$2/g;
|
||||
|
||||
print "$_\n";
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
# Convert option dashes to \- to stop nroff from hyphenating 'em, and
|
||||
# embolden. Option arguments get italicised.
|
||||
sub convert_option
|
||||
{
|
||||
my $option = '\fB' . shift;
|
||||
|
||||
$option =~ s/-/\\-/g;
|
||||
unless ($option =~ s/\[=(.*)\]$/\\fR[=\\fI$1\\fR]/)
|
||||
{
|
||||
$option =~ s/=(.)/\\fR=\\fI$1/;
|
||||
$option =~ s/ (.)/ \\fI$1/;
|
||||
$option .= '\fR';
|
||||
}
|
||||
|
||||
$option;
|
||||
}
|
|
@ -2,14 +2,10 @@
|
|||
# This file sets up the tap device.
|
||||
# It gives you the freedom to do anything you want with it.
|
||||
# Use the correct name for the tap device:
|
||||
# For the Linux tun/tap device $INTERFACE is set to the right name,
|
||||
# but for ethertap and FreeBSD this is tap0, tap1, tap2 etcetera,
|
||||
# for Solaris and OpenBSD it is tun0, tun1, etcetera.
|
||||
|
||||
# Set hardware ethernet address (required!)
|
||||
ifconfig $INTERFACE hw ether fe:fd:0:0:0:0
|
||||
# The environment variable $INTERFACE is set to the right name
|
||||
# on most platforms, but if it doesn't work try to set it manually.
|
||||
|
||||
# Give it the right ip and netmask. Remember, the subnet of the
|
||||
# tap device must be larger than that of the individual Subnets
|
||||
# as defined in the host configuration file!
|
||||
ifconfig $INTERFACE 192.168.1.1 netmask 255.255.0.0 -arp
|
||||
ifconfig $INTERFACE 192.168.1.1 netmask 255.255.0.0
|
||||
|
|
|
@ -15,11 +15,8 @@ Name = alpha
|
|||
# May be used multiple times for redundance.
|
||||
ConnectTo = beta
|
||||
|
||||
# The tap device tinc will use. Required.
|
||||
# The tap device tinc will use.
|
||||
# Default is /dev/tap0 for ethertap or FreeBSD,
|
||||
# /dev/tun0 for Solaris and OpenBSD,
|
||||
# and /dev/misc/net/tun for Linux tun/tap device.
|
||||
Device = /dev/misc/net/tun
|
||||
|
||||
# The file in which the private key for this host is stored. Required.
|
||||
PrivateKeyFile = /etc/tinc/example/rsa_key.priv
|
||||
# and /dev/net/tun for Linux tun/tap device.
|
||||
Device = /dev/net/tun
|
||||
|
|
5484
doc/texinfo.tex
5484
doc/texinfo.tex
File diff suppressed because it is too large
Load diff
196
doc/tinc.conf.5
196
doc/tinc.conf.5
|
@ -1,196 +0,0 @@
|
|||
.TH TINC 5 "May 2000" "tinc version 1.0" "FSF"
|
||||
.SH NAME
|
||||
tincd.conf \- tinc daemon configuration
|
||||
.SH "DESCRIPTION"
|
||||
The files in the \fI/etc/tinc\fR directory contain runtime and
|
||||
security information for the \fBtinc\fR(8) daemon.
|
||||
.PP
|
||||
.SH "NETWORKS"
|
||||
It is perfectly ok for you to run more than one tinc daemon. However,
|
||||
in its default form, you will soon notice that you can't use two
|
||||
different configuration files without the \fI-c\fR option.
|
||||
|
||||
We have thought of another way of dealing with this: network
|
||||
names. This means that you call \fBtincd\fR with the \fI-n\fR argument,
|
||||
which will assign a name to this daemon.
|
||||
|
||||
The effect of this is that the daemon will set its configuration
|
||||
``root'' to \fI/etc/tinc/\fBnn\fI/\fR, where \fBnn\fR is your argument
|
||||
to the \fI-n\fR option. You'll notice that it appears in syslog as
|
||||
``tincd.\fBnn\fR''.
|
||||
|
||||
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 \fI/etc/tinc/\fR,
|
||||
instead of \fI/etc/tinc/\fBnn\fI/\fR; the configuration file should be
|
||||
\fI/etc/tinc/tincd.conf\fR, and the passphrases are now expected to be
|
||||
in \fI/etc/tinc/passphrases/\fR.
|
||||
|
||||
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 assume that you use it.
|
||||
.PP
|
||||
.SH "PASSPHRASES"
|
||||
You should use the \fBgenauth\fR(8) program to generate passphrases.
|
||||
with, it accepts a single parameter, which is the number of bits the
|
||||
passphrase should be. Its output should be stored in
|
||||
\fI/etc/tinc/\fBnn\fI/passphrases/local\fR \-\- where \fBnn\fR stands
|
||||
for the network (See under \fBNETWORKS\fR) above.
|
||||
|
||||
Please see the manpage for \fBgenauth\fR to learn more about setting
|
||||
up an authentication scheme.
|
||||
.PP
|
||||
.SH "CONFIGURATION"
|
||||
The actual configuration of the daemon is done in the file
|
||||
\fI/etc/tinc/\fBnn\fI/tincd.conf\fR.
|
||||
|
||||
This file consists of comments (lines started with a \fB#\fR) or
|
||||
assignments in the form of
|
||||
.PP
|
||||
.Vb 1
|
||||
\& \fIVariable \fB= \fIValue\fR.
|
||||
.Ve
|
||||
.PP
|
||||
The variable names are case insensitive, and any spaces, tabs,
|
||||
newlines and carriage returns are ignored. \fINote\fR: it is not
|
||||
required that you put in the \fB=\fR sign, but doing so improves
|
||||
readability. If you leave it out, remember to replace it with at least
|
||||
one space character.
|
||||
.PP
|
||||
.SH "VARIABLES"
|
||||
.PP
|
||||
Here are all valid variables, listed in alphabetical order. The default
|
||||
value, required or optional is given between parentheses.
|
||||
.TP
|
||||
\fBConnectPort\fR = <\fIport\fR> (655)
|
||||
Connect to the upstream host (given with the \fBConnectTo\fR directive) on
|
||||
port \fIport\fR. port may be given in decimal (default), octal (when preceded
|
||||
by a single zero) or hexadecimal (prefixed with 0x). \fIport\fR is the port
|
||||
number for both the UDP and the TCP (meta) connections.
|
||||
.TP
|
||||
\fBConnectTo\fR = <\fIIP address|hostname\fR> (optional)
|
||||
Specifies which host to connect to on startup. Multiple \fBConnectTo\fR variables
|
||||
may be specified, if connecting to the first one fails then tinc will try
|
||||
the next one, and so on. It is possible to specify hostnames for dynamic IP
|
||||
addresses (like those given on dyndns.org), tinc will not cache the resolved
|
||||
IP address.
|
||||
|
||||
If you don't specify a host with \fBConnectTo\fR, regardless of whether a
|
||||
value for \fBConnectPort\fR is given, tinc won't connect at all, and will
|
||||
instead just listen for incoming connections.
|
||||
.TP
|
||||
\fBHostnames\fR = <\fIyes|no\fR> (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 it does
|
||||
a lookup if your DNS server is not responding.
|
||||
|
||||
This does not affect resolving hostnames to IP addresses from the configuration
|
||||
file.
|
||||
.TP
|
||||
\fBIndirectData\fR = <\fIyes|no\fR> (no)
|
||||
This option specifies whether other tinc daemons besides the one you
|
||||
specified with \fBConnectTo\fR can make a direct connection to you. This is
|
||||
especially useful if you are behind a firewall and it is impossible
|
||||
to make a connection from the outside to your tinc daemon. Otherwise,
|
||||
it is best to leave this option out or set it to no.
|
||||
.TP
|
||||
\fBInterface\fR = <\fIdevice\fR> (optional)
|
||||
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 variable.
|
||||
.TP
|
||||
\fBInterfaceIP\fR = <\fIlocal address\fR> (optional)
|
||||
If your computer has more than one IP address on a single interface (for example
|
||||
if you are running virtual hosts), tinc will by default listen on all of them for
|
||||
incoming connections. It is possible to bind tinc to a single IP address with
|
||||
this variable. It is still possible to listen on several interfaces at the same
|
||||
time though, if they share the same IP address.
|
||||
.TP
|
||||
\fBKeyExpire\fR = <\fIseconds\fR> (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.
|
||||
.TP
|
||||
\fBListenPort\fR = <\fIport\fR> (655)
|
||||
Listen on local port \fIport\fR. The computer connecting to this daemon should
|
||||
use this number as the argument for his \fBConnectPort\fR.
|
||||
.TP
|
||||
\fBMyOwnVPNIP\fR = <\fIlocal address[/maskbits]\fR> (required)
|
||||
The \fIlocal address\fR is the number that the daemon will propagate to
|
||||
other daemons on the network when it is identifying itself. Hence this
|
||||
will be the file name of the passphrase file that the other end expects
|
||||
to find the passphrase in.
|
||||
|
||||
The local address is the IP address of the tap device, not the real IP
|
||||
address of the host running tincd. Due to changes in recent kernels, it
|
||||
is also necessary that you make the ethernet (also known as MAC) address
|
||||
equal to the IP address (see the example).
|
||||
|
||||
\fImaskbits\fR is the number of bits set to 1 in the netmask part.
|
||||
.TP
|
||||
\fBMyVirtualIP\fR = <\fIlocal address[/maskbits]>
|
||||
This is an alias for \fBMyOwnVPNIP\fR.
|
||||
.TP
|
||||
\fBPassphrases\fR = <\fIdirectory\fR> (/etc/tinc/NETNAME/passphrases)
|
||||
The directory where tinc will look for passphrases when someone tries to
|
||||
connect. Please see the manpage for genauth(8) for more information
|
||||
about passphrases as used by tinc.
|
||||
.TP
|
||||
\fBPingTimeout\fR = <\fIseconds\fR> (5)
|
||||
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.
|
||||
.TP
|
||||
\fBTapDevice\fR = <\fIdevice\fR> (/dev/tap0)
|
||||
The ethertap device to use. Note that you can only use one device per
|
||||
daemon. The info pages of the tinc package contain more information
|
||||
about configuring an ethertap device for Linux.
|
||||
.TP
|
||||
\fBTCPonly\fR = <\fIyes|no\fR> (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 firewall, or if
|
||||
UDP packet routing is disabled somehow. This is experimental code,
|
||||
try this at your own risk.
|
||||
.TP
|
||||
\fBVpnMask\fR = <\fImask\fR> (optional)
|
||||
The mask that defines the scope of the entire VPN. This option is not used
|
||||
by the tinc daemon itself, but can be used by startup scripts to configure
|
||||
the ethertap devices correctly.
|
||||
.PP
|
||||
.SH "FILES"
|
||||
.TP
|
||||
\fI/etc/tinc/\fR
|
||||
The top directory for configuration files.
|
||||
.TP
|
||||
\fI/etc/tinc/\fBnn\fI/tincd.conf\fR
|
||||
The default name of the configuration file for net
|
||||
\fBnn\fR.
|
||||
.TP
|
||||
\fI/etc/tinc/\fBnn\fI/passphrases/\fR
|
||||
Passphrases are kept in this directory. (See the section
|
||||
\fBPASSPHRASES\fR above).
|
||||
.PP
|
||||
.SH "SEE ALSO"
|
||||
\fBtincd\fR(8), \fBgenauth\fR(8)
|
||||
.TP
|
||||
\fBhttp://tinc.nl.linux.org/\fR
|
||||
.PP
|
||||
The full documentation for
|
||||
.B tinc
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B tinc
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info tinc
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
.PP
|
||||
tinc comes with ABSOLUTELY NO WARRANTY. This is free software,
|
||||
and you are welcome to redistribute it under certain conditions;
|
||||
see the file COPYING for details.
|
399
doc/tinc.conf.5.in
Normal file
399
doc/tinc.conf.5.in
Normal file
|
@ -0,0 +1,399 @@
|
|||
.Dd 2002-04-09
|
||||
.Dt TINC.CONF 5
|
||||
.\" Manual page created by:
|
||||
.\" Ivo Timmermans <ivo@o2w.nl>
|
||||
.\" Guus Sliepen <guus@sliepen.eu.org>
|
||||
.Sh NAME
|
||||
.Nm tinc.conf
|
||||
.Nd tinc daemon configuration
|
||||
.Sh DESCRIPTION
|
||||
The files in the
|
||||
.Pa @sysconfdir@/tinc/
|
||||
directory contain runtime and security information for the tinc daemon.
|
||||
.Sh NETWORKS
|
||||
It is perfectly ok for you to run more than one tinc daemon.
|
||||
However, in its default form,
|
||||
you will soon notice that you can't use two different configuration files without the
|
||||
.Fl c
|
||||
option.
|
||||
.Pp
|
||||
We have thought of another way of dealing with this: network names.
|
||||
This means that you call
|
||||
.Nm
|
||||
with the
|
||||
.Fl n
|
||||
option, which will assign a name to this daemon.
|
||||
.Pp
|
||||
The effect of this is that the daemon will set its configuration root to
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa / ,
|
||||
where
|
||||
.Ar NETNAME
|
||||
is your argument to the
|
||||
.Fl n
|
||||
option.
|
||||
You'll notice that messages appear in syslog as coming from
|
||||
.Nm tincd. Ns Ar NETNAME .
|
||||
.Pp
|
||||
However, it is not strictly necessary that you call tinc with the
|
||||
.Fl n
|
||||
option.
|
||||
In this case, the network name would just be empty,
|
||||
and it will be used as such.
|
||||
.Nm tinc
|
||||
now looks for files in
|
||||
.Pa @sysconfdir@/tinc/ ,
|
||||
instead of
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa / ;
|
||||
the configuration file should be
|
||||
.Pa @sysconfdir@/tinc/tinc.conf ,
|
||||
and the host configuration files are now expected to be in
|
||||
.Pa @sysconfdir@/tinc/hosts/ .
|
||||
.Pp
|
||||
But it is highly recommended that you use this feature of
|
||||
.Nm tinc ,
|
||||
because it will be so much clearer whom your daemon talks to.
|
||||
Hence, we will assume that you use it.
|
||||
.Sh NAMES
|
||||
Each tinc daemon should have a name that is unique in the network which it will be part of.
|
||||
The name will be used by other tinc daemons for identification.
|
||||
The name has to be declared in the
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf
|
||||
file.
|
||||
.Pp
|
||||
To make things easy,
|
||||
choose something that will give unique and easy to remember names to your tinc daemon(s).
|
||||
You could try things like hostnames, owner surnames or location names.
|
||||
.Sh PUBLIC/PRIVATE KEYS
|
||||
You should use
|
||||
.Ic tincd -K
|
||||
to generate public/private keypairs.
|
||||
It will generate two keys.
|
||||
The private key should be stored in a separate file
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /rsa_key.priv
|
||||
\-\- where
|
||||
.Ar NETNAME
|
||||
stands for the network (see
|
||||
.Sx NETWORKS )
|
||||
above.
|
||||
The public key should be stored in the host configuration file
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Va NAME
|
||||
\-\- where
|
||||
.Va NAME
|
||||
stands for the name of the local tinc daemon (see
|
||||
.Sx NAMES ) .
|
||||
.Sh SERVER CONFIGURATION
|
||||
The server configuration of the daemon is done in the file
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf .
|
||||
This file consists of comments (lines started with a
|
||||
.Li # )
|
||||
or assignments in the form of:
|
||||
.Pp
|
||||
.Va Variable Li = Ar Value .
|
||||
.Pp
|
||||
The variable names are case insensitive, and any spaces, tabs,
|
||||
newlines and carriage returns are ignored.
|
||||
Note: it is not required that you put in the
|
||||
.Li =
|
||||
sign, but doing so improves readability.
|
||||
If you leave it out, remember to replace it with at least one space character.
|
||||
.Pp
|
||||
Here are all valid variables, listed in alphabetical order.
|
||||
The default value is given between parentheses.
|
||||
.Bl -tag -width indent
|
||||
.It Va AddressFamily Li = ipv4 | ipv6 | any Pq any
|
||||
This option affects the address family of listening and outgoing sockets.
|
||||
If
|
||||
.Qq any
|
||||
is selected, then depending on the operating system both IPv4 and IPv6 or just
|
||||
IPv6 listening sockets will be created.
|
||||
.It Va BindToAddress Li = Ar address Bq experimental
|
||||
If your computer has more than one IPv4 or IPv6 address,
|
||||
.Nm 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.
|
||||
.Pp
|
||||
This option may not work on all platforms.
|
||||
.It Va BindToInterface Li = Ar interface Bq experimental
|
||||
If your computer has more than one network interface,
|
||||
.Nm tinc
|
||||
will by default listen on all of them for incoming connections.
|
||||
It is possible to bind only to a single interface with this variable.
|
||||
.Pp
|
||||
This option may not work on all platforms.
|
||||
.It Va ConnectTo Li = Ar name
|
||||
Specifies which other tinc daemon to connect to on startup.
|
||||
Multiple
|
||||
.Va ConnectTo
|
||||
variables may be specified,
|
||||
in which case outgoing connections to each specified tinc daemon are made.
|
||||
The names should be known to this tinc daemon
|
||||
(i.e., there should be a host configuration file for the name on the
|
||||
.Va ConnectTo
|
||||
line).
|
||||
.Pp
|
||||
If you don't specify a host with
|
||||
.Va ConnectTo ,
|
||||
.Nm tinc
|
||||
won't try to connect to other daemons at all,
|
||||
and will instead just listen for incoming connections.
|
||||
.It Va Device Li = Ar device Po Pa /dev/tap0 , Pa /dev/net/tun No or other depending on platform Pc
|
||||
The virtual network device to use.
|
||||
.Nm tinc
|
||||
will automatically detect what kind of device it is.
|
||||
Note that you can only use one device per daemon.
|
||||
Under Windows, use
|
||||
.Va Interface
|
||||
instead of
|
||||
.Va Device .
|
||||
The info pages of the tinc package contain more information
|
||||
about configuring the virtual network device.
|
||||
.It Va Hostnames Li = yes | no Pq 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 every time it does
|
||||
a lookup if your DNS server is not responding.
|
||||
.Pp
|
||||
This does not affect resolving hostnames to IP addresses from the
|
||||
host configuration files.
|
||||
.It Va Interface Li = Ar 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
|
||||
.Va Device ,
|
||||
this variable is almost always already correctly set.
|
||||
.It Va KeyExpire Li = Ar seconds Pq 3600
|
||||
This option controls the period 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.
|
||||
.It Va MACExpire Li = Ar seconds Pq 600
|
||||
This option controls the amount of time MAC addresses are kept before they are removed.
|
||||
This only has effect when
|
||||
.Va Mode
|
||||
is set to
|
||||
.Qq switch .
|
||||
.It Va MaxTimeout Li = Ar seconds Pq 900
|
||||
This is the maximum delay before trying to reconnect to other tinc daemons.
|
||||
.It Va Mode Li = router | switch | hub Pq router
|
||||
This option selects the way packets are routed to other daemons.
|
||||
.Bl -tag -width indent
|
||||
.It router
|
||||
In this mode
|
||||
.Va Subnet
|
||||
variables in the host configuration files will be used to form a routing table.
|
||||
Only unicast packets of routable protocols (IPv4 and IPv6) are supported in this mode.
|
||||
.Pp
|
||||
This is the default mode, and unless you really know you need another mode, don't change it.
|
||||
.It switch
|
||||
In this mode the MAC addresses of the packets on the VPN will be used to
|
||||
dynamically create a routing table just like an Ethernet switch does.
|
||||
Unicast, multicast and broadcast packets of every protocol that runs over Ethernet are supported in this mode
|
||||
at the cost of frequent broadcast ARP requests and routing table updates.
|
||||
.Pp
|
||||
This mode is primarily useful if you want to bridge Ethernet segments.
|
||||
.It hub
|
||||
This mode is almost the same as the switch mode, but instead
|
||||
every packet will be broadcast to the other daemons
|
||||
while no routing table is managed.
|
||||
.El
|
||||
.It Va Name Li = Ar name Bq required
|
||||
This is the name which identifies this tinc daemon.
|
||||
It must be unique for the virtual private network this daemon will connect to.
|
||||
.It Va PingTimeout Li = Ar seconds Pq 60
|
||||
The number of seconds of inactivity that
|
||||
.Nm tinc
|
||||
will wait before sending a probe to the other end.
|
||||
If that other end doesn't answer within that same amount of time,
|
||||
the connection is terminated,
|
||||
and the others will be notified of this.
|
||||
.It Va PriorityInheritance Li = yes | no Po no Pc Bq 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.
|
||||
.It Va PrivateKey Li = Ar key Bq obsolete
|
||||
The private RSA key of this tinc daemon.
|
||||
It will allow this tinc daemon to authenticate itself to other daemons.
|
||||
.It Va PrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /rsa_key.priv Pc
|
||||
The file in which the private RSA key of this tinc daemon resides.
|
||||
Note that there must be exactly one of
|
||||
.Va PrivateKey
|
||||
or
|
||||
.Va PrivateKeyFile
|
||||
specified in the configuration file.
|
||||
.El
|
||||
.Sh HOST CONFIGURATION FILES
|
||||
The host configuration files contain all information needed
|
||||
to establish a connection to those hosts.
|
||||
A host configuration file is also required for the local tinc daemon,
|
||||
it will use it to read in it's listen port, public key and subnets.
|
||||
.Pp
|
||||
The idea is that these files are portable.
|
||||
You can safely mail your own host configuration file to someone else.
|
||||
That other person can then copy it to his own hosts directory,
|
||||
and now his tinc daemon will be able to connect to your tinc daemon.
|
||||
Since host configuration files only contain public keys,
|
||||
no secrets are revealed by sending out this information.
|
||||
.Bl -tag -width indent
|
||||
.It Va Address Li = Ar address Bq recommended
|
||||
The IP address or hostname of this tinc daemon on the real network.
|
||||
This wil only be used when trying to make an outgoing connection to this tinc daemon.
|
||||
Multiple
|
||||
.Va Address
|
||||
variables can be specified, in which case each address will be tried until a working
|
||||
connection has been established.
|
||||
.It Va Cipher Li = Ar cipher Pq blowfish
|
||||
The symmetric cipher algorithm used to encrypt UDP packets.
|
||||
Any cipher supported by OpenSSL is recognised.
|
||||
Furthermore, specifying
|
||||
.Qq none
|
||||
will turn off packet encryption.
|
||||
.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),
|
||||
10 (fast lzo) and 11 (best lzo).
|
||||
.It Va Digest Li = Ar digest Pq sha1
|
||||
The digest algorithm used to authenticate UDP packets.
|
||||
Any digest supported by OpenSSL is recognised.
|
||||
Furthermore, specifying
|
||||
.Qq none
|
||||
will turn off packet authentication.
|
||||
.It Va IndirectData Li = yes | no Pq no
|
||||
This option specifies whether other tinc daemons besides the one you specified with
|
||||
.Va ConnectTo
|
||||
can make a direct connection to you.
|
||||
This is especially useful if you are behind a firewall
|
||||
and it is impossible to make a connection from the outside to your tinc daemon.
|
||||
Otherwise, it is best to leave this option out or set it to no.
|
||||
.It Va MACLength Li = Ar length Pq 4
|
||||
The length of the message authentication code used to authenticate UDP packets.
|
||||
Can be anything from
|
||||
.Qq 0
|
||||
up to the length of the digest produced by the digest algorithm.
|
||||
.It Va 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
|
||||
The public RSA key of this tinc daemon.
|
||||
It will be used to cryptographically verify it's identity and to set up a secure connection.
|
||||
.It Va PublicKeyFile Li = Ar filename Bq obsolete
|
||||
The file in which the public RSA key of this tinc daemon resides.
|
||||
.Pp
|
||||
From version 1.0pre4 on
|
||||
.Nm tinc
|
||||
will store the public key directly into the host configuration file in PEM format,
|
||||
the above two options then are not necessary.
|
||||
Either the PEM format is used, or exactly one of the above two options must be specified
|
||||
in each host configuration file,
|
||||
if you want to be able to establish a connection with that host.
|
||||
.It Va Subnet Li = Ar address Ns Op Li / Ns Ar prefixlength
|
||||
The subnet which this tinc daemon will serve.
|
||||
.Nm tinc
|
||||
tries to look up which other daemon it should send a packet to by searching the appropriate subnet.
|
||||
If the packet matches a subnet,
|
||||
it will be sent to the daemon who has this subnet in his host configuration file.
|
||||
Multiple
|
||||
.Va Subnet
|
||||
variables can be specified.
|
||||
.Pp
|
||||
Subnets can either be single MAC, IPv4 or IPv6 addresses,
|
||||
in which case a subnet consisting of only that single address is assumed,
|
||||
or they can be a IPv4 or IPv6 network address with a prefixlength.
|
||||
Shorthand notations are not supported.
|
||||
For example, IPv4 subnets must be in a form like 192.168.1.0/24,
|
||||
where 192.168.1.0 is the network address and 24 is the number of bits set in the netmask.
|
||||
Note that subnets like 192.168.1.1/24 are invalid!
|
||||
Read a networking HOWTO/FAQ/guide if you don't understand this.
|
||||
IPv6 subnets are notated like fec0:0:0:1:0:0:0:0/64.
|
||||
MAC addresses are notated like 0:1a:2b:3c:4d:5e.
|
||||
.It Va TCPOnly Li = yes | no Pq no
|
||||
If this variable is set to yes,
|
||||
then the packets are tunnelled over the TCP connection instead of a UDP connection.
|
||||
This is especially useful for those who want to run a tinc daemon
|
||||
from behind a masquerading firewall,
|
||||
or if UDP packet routing is disabled somehow.
|
||||
Setting this options also implicitly sets IndirectData.
|
||||
.El
|
||||
.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
|
||||
.Pa .bat .
|
||||
.Bl -tag -width indent
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
|
||||
This is the most important script.
|
||||
If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device.
|
||||
It should be used to set up the corresponding network interface,
|
||||
but can also be used to start other things.
|
||||
Under Windows you can use the Network Connections control panel instead of creating this script.
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down
|
||||
This script is started right before the tinc daemon quits.
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -up
|
||||
This script is started when the tinc daemon with name
|
||||
.Ar HOST
|
||||
becomes reachable.
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -down
|
||||
This script is started when the tinc daemon with name
|
||||
.Ar HOST
|
||||
becomes unreachable.
|
||||
.El
|
||||
.Pp
|
||||
The scripts are started without command line arguments, but can make use of certain environment variables.
|
||||
Under UNIX like operating systems the names of environment variables must be preceded by a
|
||||
.Li $
|
||||
in scripts.
|
||||
Under Windows, in
|
||||
.Pa .bat
|
||||
files, they have to be put between
|
||||
.Li %
|
||||
signs.
|
||||
.Bl -tag -width indent
|
||||
.It Ev NETNAME
|
||||
If a netname was specified, this environment variable contains it.
|
||||
.It Ev NAME
|
||||
Contains the name of this tinc daemon.
|
||||
.It Ev DEVICE
|
||||
Contains the name of the virtual network device that tinc uses.
|
||||
.It Ev INTERFACE
|
||||
Contains the name of the virtual network interface that tinc uses.
|
||||
This should be used for commands like
|
||||
.Pa ifconfig .
|
||||
.It Ev NODE
|
||||
When a host becomes (un)reachable, this is set to its name.
|
||||
.It Ev REMOTEADDRESS
|
||||
When a host becomes (un)reachable, this is set to its real address.
|
||||
.It Ev REMOTEPORT
|
||||
When a host becomes (un)reachable, this is set to the port number it uses for communication with other tinc daemons.
|
||||
.El
|
||||
.Sh FILES
|
||||
The most important files are:
|
||||
.Bl -tag -width indent
|
||||
.It Pa @sysconfdir@/tinc/
|
||||
The top directory for configuration files.
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf
|
||||
The default name of the server configuration file for net
|
||||
.Ar NETNAME .
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
|
||||
Host configuration files are kept in this directory.
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
|
||||
If an executable file with this name exists,
|
||||
it will be executed right after the tinc daemon has connected to the virtual network device.
|
||||
It can be used to set up the corresponding network interface.
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down
|
||||
If an executable file with this name exists,
|
||||
it will be executed right before the tinc daemon is going to close
|
||||
its connection to the virtual network device.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr tincd 8 ,
|
||||
.Pa http://tinc.nl.linux.org/ ,
|
||||
.Pa http://www.linuxdoc.org/LDP/nag2/ .
|
||||
.Pp
|
||||
The full documentation for
|
||||
.Nm tinc
|
||||
is maintained as a Texinfo manual.
|
||||
If the info and tinc programs are properly installed at your site, the command
|
||||
.Ic info tinc
|
||||
should give you access to the complete manual.
|
||||
.Pp
|
||||
.Nm tinc
|
||||
comes with ABSOLUTELY NO WARRANTY.
|
||||
This is free software, and you are welcome to redistribute it under certain conditions;
|
||||
see the file COPYING for details.
|
2173
doc/tinc.texi
2173
doc/tinc.texi
File diff suppressed because it is too large
Load diff
|
@ -1,22 +1,25 @@
|
|||
.Dd 2002-03-25
|
||||
.Dt TINCD 8
|
||||
.\" Manual page created by:
|
||||
.\" Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
.\" Guus Sliepen <guus@sliepen.warande.net>
|
||||
.\" Ivo Timmermans <ivo@o2w.nl>
|
||||
.\" Guus Sliepen <guus@sliepen.eu.org>
|
||||
.Sh NAME
|
||||
.Nm tincd
|
||||
.Nd tinc VPN daemon
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl cdDkKn
|
||||
.Op Fl -bypass-security
|
||||
.Op Fl cdDkKnL
|
||||
.Op Fl -config Ns = Ns Ar DIR
|
||||
.Op Fl -debug Ns = Ns Ar LEVEL
|
||||
.Op Fl -generate-keys Ns Op = Ns Ar BITS
|
||||
.Op Fl -help
|
||||
.Op Fl -kill Ns = Ns Ar SIGNAL
|
||||
.Op Fl -net Ns = Ns Ar NETNAME
|
||||
.Op Fl -no-detach
|
||||
.Op Fl -debug Ns Op = Ns Ar LEVEL
|
||||
.Op Fl -kill Ns Op = Ns Ar SIGNAL
|
||||
.Op Fl -net Ns = Ns Ar NETNAME
|
||||
.Op Fl -generate-keys Ns Op = Ns Ar BITS
|
||||
.Op Fl -mlock
|
||||
.Op Fl -logfile Ns Op = Ns Ar FILE
|
||||
.Op Fl -pidfile Ns = Ns Ar FILE
|
||||
.Op Fl -bypass-security
|
||||
.Op Fl -help
|
||||
.Op Fl -version
|
||||
.Sh DESCRIPTION
|
||||
This is the daemon of tinc, a secure virtual private network (VPN) project.
|
||||
|
@ -31,37 +34,59 @@ If that succeeds,
|
|||
it will detach from the controlling terminal and continue in the background,
|
||||
accepting and setting up connections to other tinc daemons
|
||||
that are part of the virtual private network.
|
||||
Under Windows (not Cygwin) tinc will install itself as a service,
|
||||
which will be restarted automatically after reboots.
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width indent
|
||||
.It Fl -bypass-security
|
||||
Disables encryption and authentication.
|
||||
Only useful for debugging.
|
||||
.It Fl c, -config Ns = Ns Ar DIR
|
||||
Read configuration options from
|
||||
.Ar DIR .
|
||||
Read configuration files from
|
||||
.Ar DIR
|
||||
instead of
|
||||
.Pa @sysconfdir@/tinc/ .
|
||||
.It Fl D, -no-detach
|
||||
Don't fork and detach.
|
||||
This will also disable the automatic restart mechanism for fatal errors.
|
||||
If not mentioned otherwise, this will show log messages on the standard error output.
|
||||
.It Fl d, -debug Ns Op = Ns Ar LEVEL
|
||||
Increase debug level or set it to
|
||||
.Ar LEVEL
|
||||
(see below).
|
||||
.It Fl K, -generate-keys Ns Op = Ns Ar BITS
|
||||
Generate public/private RSA keypair and exit.
|
||||
If
|
||||
.Ar BITS
|
||||
is omitted, the default length will be 1024 bits.
|
||||
.It Fl -help
|
||||
Display short list of options.
|
||||
.It Fl k, -kill Ns Op = Ns Ar SIGNAL
|
||||
Attempt to kill a running
|
||||
.Nm
|
||||
(optionally with the specified
|
||||
.Ar SIGNAL
|
||||
instead of SIGTERM) and exit.
|
||||
Under Windows (not Cygwin) the optional argument is ignored,
|
||||
the service will always be stopped and removed.
|
||||
.It Fl n, -net Ns = Ns Ar NETNAME
|
||||
Connect to net
|
||||
.Ar NETNAME .
|
||||
.It Fl D, -no-detach
|
||||
Don't fork and detach.
|
||||
This will also disable the automatic restart mechanism for fatal errors.
|
||||
.It Fl K, -generate-keys Ns Op = Ns Ar BITS
|
||||
Generate public/private RSA keypair and exit.
|
||||
If
|
||||
.Ar BITS
|
||||
is omitted, the default length will be 1024 bits.
|
||||
.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.
|
||||
.It Fl -logfile Ns Op = Ns Ar FILE
|
||||
Write log entries to a file instead of to the system logging facility.
|
||||
If
|
||||
.Ar FILE
|
||||
is omitted, the default is
|
||||
.Pa @localstatedir@/log/tinc. Ns Ar NETNAME Ns Pa .log.
|
||||
.It Fl -pidfile Ns = Ns Ar FILE
|
||||
Write PID to
|
||||
.Ar FILE
|
||||
instead of
|
||||
.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid.
|
||||
Under Windows this option will be ignored.
|
||||
.It Fl -bypass-security
|
||||
Disables encryption and authentication of the meta protocol.
|
||||
Only useful for debugging.
|
||||
.It Fl -help
|
||||
Display short list of options.
|
||||
.It Fl -version
|
||||
Output version information and exit.
|
||||
.El
|
||||
|
@ -80,7 +105,11 @@ and if
|
|||
didn't succeed to connect to an uplink the first time after it started,
|
||||
it defaults to the maximum time of 15 minutes.
|
||||
.It HUP
|
||||
Closes all connections, rereads the configuration file and restarts the daemon.
|
||||
Partially rereads configuration files.
|
||||
Connections to hosts whose host config file are removed are closed.
|
||||
New outgoing connections specified in
|
||||
.Pa tinc.conf
|
||||
will be made.
|
||||
.It INT
|
||||
Temporarily increases debug level to 5.
|
||||
Send this signal again to revert to the original level.
|
||||
|
@ -105,7 +134,7 @@ It will also any serious error.
|
|||
.It 1
|
||||
This will log all connections that are made with other tinc daemons.
|
||||
.It 2
|
||||
This will log status and error messages from other tinc daemons.
|
||||
This will log status and error messages from scripts and other tinc daemons.
|
||||
.It 3
|
||||
This will log all requests that are exchanged with other tinc daemons. These include
|
||||
authentication, key exchange and connection list updates.
|
||||
|
@ -116,29 +145,11 @@ This will log all network traffic over the virtual private network.
|
|||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width indent
|
||||
.It Pa /etc/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf
|
||||
The configuration file for
|
||||
.Nm .
|
||||
.It Pa /etc/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
|
||||
Script which is executed as soon as the virtual network device has been allocated.
|
||||
Purpose is to further configure that device.
|
||||
.It Pa /etc/tinc/ Ns Ar NETNAME Ns Pa /tinc-down
|
||||
Script which is executed when
|
||||
.Nm
|
||||
exits.
|
||||
Purpose is to cleanly shut down the virtual network device before it will be deallocated.
|
||||
.It Pa /etc/tinc/ Ns Ar NETNAME Ns Pa /hosts/*
|
||||
The directory containing the host configuration files
|
||||
used to authenticate other tinc daemons.
|
||||
.It Pa /etc/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar NAME Ns Pa -up
|
||||
Script which is executed as soon as host
|
||||
.Ar NAME
|
||||
becomes reachable.
|
||||
.It Pa /etc/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar NAME Ns Pa -down
|
||||
Script which is executed as soon as host
|
||||
.Ar NAME
|
||||
becomes unreachable.
|
||||
.It Pa /var/run/tinc. Ns Ar NETNAME Ns Pa .pid
|
||||
.It Pa @sysconfdir@/tinc/
|
||||
Directory containing the configuration files tinc uses.
|
||||
For more information, see
|
||||
.Xr tinc.conf 5 .
|
||||
.It Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid
|
||||
The PID of the currently running
|
||||
.Nm
|
||||
is stored in this file.
|
||||
|
@ -168,7 +179,7 @@ tinc comes with ABSOLUTELY NO WARRANTY.
|
|||
This is free software, and you are welcome to redistribute it under certain conditions;
|
||||
see the file COPYING for details.
|
||||
.Sh AUTHORS
|
||||
.An "Ivo Timmermans" Aq itimmermans@bigfoot.com
|
||||
.An "Guus Sliepen" Aq guus@sliepen.warande.net
|
||||
.An "Ivo Timmermans" Aq ivo@o2w.nl
|
||||
.An "Guus Sliepen" Aq guus@sliepen.eu.org
|
||||
.Pp
|
||||
And thanks to many others for their contributions to tinc!
|
4
doc/tincinclude.texi.in
Normal file
4
doc/tincinclude.texi.in
Normal file
|
@ -0,0 +1,4 @@
|
|||
@set VERSION @VERSION@
|
||||
@set PACKAGE @PACKAGE@
|
||||
@set sysconfdir @sysconfdir@
|
||||
@set localstatedir @localstatedir@
|
|
@ -1,17 +1,15 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
# $Id: Makefile.am,v 1.9 2002/05/02 13:11:55 zarq Exp $
|
||||
# $Id: Makefile.am,v 1.10 2003/08/24 20:38:20 guus Exp $
|
||||
|
||||
noinst_LIBRARIES = libtinc.a
|
||||
noinst_LIBRARIES = libvpn.a
|
||||
|
||||
INCLUDES = @INCLUDES@ -I. -I$(top_builddir) -I$(top_srcdir)/intl
|
||||
INCLUDES = @INCLUDES@ -I. -I$(top_builddir)
|
||||
|
||||
libtinc_a_SOURCES = xmalloc.c pidfile.c utils.c getopt.c getopt1.c \
|
||||
list.c avl_tree.c hooks.c dropin.c edge.c conf.c netutl.c logging.c connection.c subnet.c node.c graph.c event.c
|
||||
libvpn_a_SOURCES = xmalloc.c pidfile.c utils.c getopt.c getopt1.c list.c avl_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c
|
||||
|
||||
libtinc_a_LIBADD = @LIBOBJS@ @ALLOCA@
|
||||
libtinc_a_DEPENDENCIES = $(libvpn_a_LIBADD)
|
||||
libvpn_a_LIBADD = @LIBOBJS@ @ALLOCA@
|
||||
libvpn_a_DEPENDENCIES = $(libvpn_a_LIBADD)
|
||||
|
||||
noinst_HEADERS = xalloc.h pidfile.h utils.h getopt.h list.h avl_tree.h \
|
||||
hooks.h dropin.h edge.h net.h conf.h netutl.h logging.h connection.h subnet.h node.h graph.h event.h
|
||||
noinst_HEADERS = xalloc.h pidfile.h utils.h getopt.h list.h avl_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h gettext.h ipv6.h ipv4.h ethernet.h
|
||||
|
||||
EXTRA_DIST = README
|
||||
EXTRA_DIST =
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
The files in this directory were merely copied from fileutils 4.0.
|
930
lib/avl_tree.c
930
lib/avl_tree.c
File diff suppressed because it is too large
Load diff
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
avl_tree.h -- header file for avl_tree.c
|
||||
Copyright (C) 1998 Michael H. Buselli
|
||||
2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>,
|
||||
2000,2001 Guus Sliepen <guus@sliepen.warande.net>
|
||||
2000,2001 Wessel Dankers <wsl@nl.linux.org>
|
||||
2000-2003 Ivo Timmermans <ivo@o2w.nl>,
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
2000-2003 Wessel Dankers <wsl@nl.linux.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -27,9 +27,9 @@
|
|||
|
||||
Cleaned up and incorporated some of the ideas from the red-black tree
|
||||
library for inclusion into tinc (http://tinc.nl.linux.org/) by
|
||||
Guus Sliepen <guus@sliepen.warande.net>.
|
||||
Guus Sliepen <guus@sliepen.eu.org>.
|
||||
|
||||
$Id: avl_tree.h,v 1.2 2002/04/09 15:26:00 zarq Exp $
|
||||
$Id: avl_tree.h,v 1.3 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
@ -37,54 +37,54 @@
|
|||
#define __AVL_TREE_H__
|
||||
|
||||
#ifndef AVL_DEPTH
|
||||
#ifndef AVL_COUNT
|
||||
#define AVL_DEPTH
|
||||
#endif
|
||||
#ifndef AVL_COUNT
|
||||
#define AVL_DEPTH
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct avl_node_t {
|
||||
|
||||
/* Linked list part */
|
||||
/* Linked list part */
|
||||
|
||||
struct avl_node_t *next;
|
||||
struct avl_node_t *prev;
|
||||
struct avl_node_t *next;
|
||||
struct avl_node_t *prev;
|
||||
|
||||
/* Tree part */
|
||||
/* Tree part */
|
||||
|
||||
struct avl_node_t *parent;
|
||||
struct avl_node_t *left;
|
||||
struct avl_node_t *right;
|
||||
struct avl_node_t *parent;
|
||||
struct avl_node_t *left;
|
||||
struct avl_node_t *right;
|
||||
|
||||
#ifdef AVL_COUNT
|
||||
unsigned int count;
|
||||
unsigned int count;
|
||||
#endif
|
||||
#ifdef AVL_DEPTH
|
||||
unsigned char depth;
|
||||
unsigned char depth;
|
||||
#endif
|
||||
|
||||
/* Payload */
|
||||
/* Payload */
|
||||
|
||||
void *data;
|
||||
void *data;
|
||||
|
||||
} avl_node_t;
|
||||
|
||||
typedef int (*avl_compare_t) (const void *, const void *);
|
||||
typedef void (*avl_action_t) (const void *);
|
||||
typedef void (*avl_action_node_t) (const avl_node_t *);
|
||||
typedef int (*avl_compare_t)(const void *, const void *);
|
||||
typedef void (*avl_action_t)(const void *);
|
||||
typedef void (*avl_action_node_t)(const avl_node_t *);
|
||||
|
||||
typedef struct avl_tree_t {
|
||||
|
||||
/* Linked list part */
|
||||
/* Linked list part */
|
||||
|
||||
avl_node_t *head;
|
||||
avl_node_t *tail;
|
||||
avl_node_t *head;
|
||||
avl_node_t *tail;
|
||||
|
||||
/* Tree part */
|
||||
/* Tree part */
|
||||
|
||||
avl_node_t *root;
|
||||
avl_node_t *root;
|
||||
|
||||
avl_compare_t compare;
|
||||
avl_action_t delete;
|
||||
avl_compare_t compare;
|
||||
avl_action_t delete;
|
||||
|
||||
} avl_tree_t;
|
||||
|
||||
|
@ -128,18 +128,18 @@ extern avl_node_t *avl_search_closest_greater_node(const avl_tree_t *, const voi
|
|||
|
||||
/* Tree walking */
|
||||
|
||||
extern void avl_foreach(avl_tree_t *, avl_action_t);
|
||||
extern void avl_foreach_node(avl_tree_t *, avl_action_t);
|
||||
extern void avl_foreach(const avl_tree_t *, avl_action_t);
|
||||
extern void avl_foreach_node(const avl_tree_t *, avl_action_t);
|
||||
|
||||
/* Indexing */
|
||||
|
||||
#ifdef AVL_COUNT
|
||||
extern unsigned int avl_count(avl_tree_t *);
|
||||
extern unsigned int avl_count(const avl_tree_t *);
|
||||
extern avl_node_t *avl_get_node(const avl_tree_t *, unsigned int);
|
||||
extern unsigned int avl_index(const avl_node_t *);
|
||||
#endif
|
||||
#ifdef AVL_DEPTH
|
||||
extern unsigned int avl_depth(avl_tree_t *);
|
||||
extern unsigned int avl_depth(const avl_tree_t *);
|
||||
#endif
|
||||
|
||||
#endif /* __AVL_TREE_H__ */
|
||||
#endif /* __AVL_TREE_H__ */
|
||||
|
|
269
lib/conf.c
269
lib/conf.c
|
@ -1,269 +0,0 @@
|
|||
/*
|
||||
conf.c -- configuration storage & retrieval code
|
||||
Copyright (C) 1998 Robert van der Meulen
|
||||
1998-2002 Ivo Timmermans <ivo@o2w.nl>
|
||||
2000-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
2000 Cris van Pelt <tribbel@arise.dhs.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
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: conf.c,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <xalloc.h>
|
||||
#include <utils.h> /* for cp */
|
||||
#include <avl_tree.h>
|
||||
|
||||
#include "conf.h"
|
||||
#include "netutl.h" /* for str2address */
|
||||
#include "logging.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
avl_tree_t *config_tree;
|
||||
|
||||
int pingtimeout = 0; /* seconds before timeout */
|
||||
char *confbase = NULL; /* directory in which all config files are */
|
||||
char *netname = NULL; /* name of the vpn network */
|
||||
|
||||
int config_compare(config_t *a, config_t *b)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = strcasecmp(a->variable, b->variable);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = a->line - b->line;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
else
|
||||
return strcmp(a->file, b->file);
|
||||
}
|
||||
|
||||
void init_configuration(avl_tree_t **config_tree)
|
||||
{
|
||||
cp
|
||||
*config_tree = avl_alloc_tree((avl_compare_t)config_compare, (avl_action_t)free_config);
|
||||
cp
|
||||
}
|
||||
|
||||
void exit_configuration(avl_tree_t **config_tree)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(*config_tree);
|
||||
*config_tree = NULL;
|
||||
cp
|
||||
}
|
||||
|
||||
config_t *new_config(void)
|
||||
{
|
||||
config_t *cfg;
|
||||
cp
|
||||
cfg = (config_t *)xmalloc_and_zero(sizeof(*cfg));
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
void free_config(config_t *cfg)
|
||||
{
|
||||
cp
|
||||
if(cfg->variable)
|
||||
free(cfg->variable);
|
||||
if(cfg->value)
|
||||
free(cfg->value);
|
||||
if(cfg->file)
|
||||
free(cfg->file);
|
||||
free(cfg);
|
||||
cp
|
||||
}
|
||||
|
||||
void config_add(avl_tree_t *config_tree, config_t *cfg)
|
||||
{
|
||||
cp
|
||||
avl_insert(config_tree, cfg);
|
||||
cp
|
||||
}
|
||||
|
||||
config_t *lookup_config(avl_tree_t *config_tree, char *variable)
|
||||
{
|
||||
config_t cfg, *found;
|
||||
cp
|
||||
cfg.variable = variable;
|
||||
cfg.file = "";
|
||||
cfg.line = 0;
|
||||
|
||||
found = avl_search_closest_greater(config_tree, &cfg);
|
||||
|
||||
if(!found)
|
||||
return NULL;
|
||||
|
||||
if(strcasecmp(found->variable, variable))
|
||||
return NULL;
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
config_t *lookup_config_next(avl_tree_t *config_tree, config_t *cfg)
|
||||
{
|
||||
avl_node_t *node;
|
||||
config_t *found;
|
||||
cp
|
||||
node = avl_search_node(config_tree, cfg);
|
||||
|
||||
if(node)
|
||||
{
|
||||
if(node->next)
|
||||
{
|
||||
found = (config_t *)node->next->data;
|
||||
if(!strcasecmp(found->variable, cfg->variable))
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int get_config_bool(config_t *cfg, int *result)
|
||||
{
|
||||
cp
|
||||
if(!cfg)
|
||||
return 0;
|
||||
|
||||
if(!strcasecmp(cfg->value, "yes"))
|
||||
{
|
||||
*result = 1;
|
||||
return 1;
|
||||
}
|
||||
else if(!strcasecmp(cfg->value, "no"))
|
||||
{
|
||||
*result = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
syslog(LOG_ERR, _("\"yes\" or \"no\" expected for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_config_int(config_t *cfg, int *result)
|
||||
{
|
||||
cp
|
||||
if(!cfg)
|
||||
return 0;
|
||||
|
||||
if(sscanf(cfg->value, "%d", result) == 1)
|
||||
return 1;
|
||||
|
||||
syslog(LOG_ERR, _("Integer expected for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_config_string(config_t *cfg, char **result)
|
||||
{
|
||||
cp
|
||||
if(!cfg)
|
||||
return 0;
|
||||
|
||||
*result = xstrdup(cfg->value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int get_config_address(config_t *cfg, struct addrinfo **result)
|
||||
{
|
||||
struct addrinfo *ai;
|
||||
cp
|
||||
if(!cfg)
|
||||
return 0;
|
||||
|
||||
ai = str2addrinfo(cfg->value, NULL, 0);
|
||||
|
||||
if(ai)
|
||||
{
|
||||
*result = ai;
|
||||
return 1;
|
||||
}
|
||||
|
||||
syslog(LOG_ERR, _("Hostname or IP address expected for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_config_port(config_t *cfg, port_t *result)
|
||||
{
|
||||
cp
|
||||
if(!cfg)
|
||||
return 0;
|
||||
|
||||
if(sscanf(cfg->value, "%hu", result) == 1)
|
||||
{
|
||||
*result = htons(*result);
|
||||
return 1;
|
||||
}
|
||||
|
||||
syslog(LOG_ERR, _("Port number expected for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_config_subnet(config_t *cfg, subnet_t **result)
|
||||
{
|
||||
subnet_t *subnet;
|
||||
cp
|
||||
if(!cfg)
|
||||
return 0;
|
||||
|
||||
subnet = str2net(cfg->value);
|
||||
|
||||
if(!subnet)
|
||||
{
|
||||
syslog(LOG_ERR, _("Subnet expected for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Teach newbies what subnets are... */
|
||||
|
||||
if(((subnet->type == SUBNET_IPV4) && maskcheck((char *)&subnet->net.ipv4.address, subnet->net.ipv4.prefixlength, sizeof(ipv4_t)))
|
||||
|| ((subnet->type == SUBNET_IPV6) && maskcheck((char *)&subnet->net.ipv6.address, subnet->net.ipv6.prefixlength, sizeof(ipv6_t))))
|
||||
{
|
||||
syslog(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 0;
|
||||
}
|
||||
|
||||
*result = subnet;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
126
lib/connection.c
126
lib/connection.c
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
connection.c -- connection list management
|
||||
Copyright (C) 2000-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2000-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
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: connection.c,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
#include <list.h>
|
||||
|
||||
#include "net.h" /* Don't ask. */
|
||||
#include "netutl.h"
|
||||
#include "config.h"
|
||||
#include "conf.h"
|
||||
#include <utils.h>
|
||||
#include "subnet.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include "xalloc.h"
|
||||
#include "system.h"
|
||||
|
||||
avl_tree_t *connection_tree; /* Meta connections */
|
||||
|
||||
int connection_compare(connection_t *a, connection_t *b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
void init_connections(void)
|
||||
{
|
||||
cp
|
||||
connection_tree = avl_alloc_tree((avl_compare_t)connection_compare, NULL);
|
||||
cp
|
||||
}
|
||||
|
||||
void exit_connections(void)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(connection_tree);
|
||||
cp
|
||||
}
|
||||
|
||||
connection_t *new_connection(void)
|
||||
{
|
||||
connection_t *c;
|
||||
cp
|
||||
c = (connection_t *)xmalloc_and_zero(sizeof(connection_t));
|
||||
|
||||
if(!c)
|
||||
return NULL;
|
||||
|
||||
gettimeofday(&c->start, NULL);
|
||||
cp
|
||||
return c;
|
||||
}
|
||||
|
||||
void free_connection(connection_t *c)
|
||||
{
|
||||
cp
|
||||
if(c->hostname)
|
||||
free(c->hostname);
|
||||
if(c->inkey)
|
||||
free(c->inkey);
|
||||
if(c->outkey)
|
||||
free(c->outkey);
|
||||
if(c->mychallenge)
|
||||
free(c->mychallenge);
|
||||
if(c->hischallenge)
|
||||
free(c->hischallenge);
|
||||
free(c);
|
||||
cp
|
||||
}
|
||||
|
||||
void connection_add(connection_t *c)
|
||||
{
|
||||
cp
|
||||
avl_insert(connection_tree, c);
|
||||
cp
|
||||
}
|
||||
|
||||
void connection_del(connection_t *c)
|
||||
{
|
||||
cp
|
||||
avl_delete(connection_tree, c);
|
||||
cp
|
||||
}
|
||||
|
||||
void dump_connections(void)
|
||||
{
|
||||
avl_node_t *node;
|
||||
connection_t *c;
|
||||
cp
|
||||
syslog(LOG_DEBUG, _("Connections:"));
|
||||
|
||||
for(node = connection_tree->head; node; node = node->next)
|
||||
{
|
||||
c = (connection_t *)node->data;
|
||||
syslog(LOG_DEBUG, _(" %s at %s options %lx socket %d status %04x"),
|
||||
c->name, c->hostname, c->options, c->socket, c->status);
|
||||
}
|
||||
|
||||
syslog(LOG_DEBUG, _("End of connections."));
|
||||
cp
|
||||
}
|
141
lib/connection.h
141
lib/connection.h
|
@ -1,141 +0,0 @@
|
|||
/*
|
||||
connection.h -- header for connection.c
|
||||
Copyright (C) 2000-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2000-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
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: connection.h,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_CONNECTION_H__
|
||||
#define __TINC_CONNECTION_H__
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
#include <list.h>
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
# ifdef HAVE_OPENSSL_EVP_H
|
||||
# include <openssl/evp.h>
|
||||
# else
|
||||
# include <evp.h>
|
||||
# endif
|
||||
|
||||
# ifdef HAVE_OPENSSL_RSA_H
|
||||
# include <openssl/rsa.h>
|
||||
# else
|
||||
# include <rsa.h>
|
||||
# endif
|
||||
#endif /* USE_OPENSSL */
|
||||
|
||||
#ifdef USE_GCRYPT
|
||||
# include <gcrypt.h>
|
||||
#endif
|
||||
|
||||
#include "net.h"
|
||||
#include "conf.h"
|
||||
|
||||
#include "node.h"
|
||||
#include "edge.h"
|
||||
|
||||
#define OPTION_INDIRECT 0x0001
|
||||
#define OPTION_TCPONLY 0x0002
|
||||
|
||||
typedef struct connection_status_t {
|
||||
int pinged:1; /* sent ping */
|
||||
int active:1; /* 1 if active.. */
|
||||
int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */
|
||||
int termreq:1; /* the termination of this connection was requested */
|
||||
int remove:1; /* Set to 1 if you want this connection removed */
|
||||
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;
|
||||
} connection_status_t;
|
||||
|
||||
typedef struct connection_t {
|
||||
char *name; /* name he claims to have */
|
||||
|
||||
sockaddr_t address; /* his real (internet) ip */
|
||||
char *hostname; /* the hostname of its real ip */
|
||||
int protocol_version; /* used protocol */
|
||||
|
||||
int socket; /* socket used for this connection */
|
||||
long int options; /* options for this connection */
|
||||
struct connection_status_t status; /* status info */
|
||||
int estimated_weight; /* estimation for the weight of the edge for this connection */
|
||||
struct timeval start; /* time this connection was started, used for above estimation */
|
||||
struct outgoing_t *outgoing; /* used to keep track of outgoing connections */
|
||||
|
||||
struct node_t *node; /* node associated with the other end */
|
||||
struct edge_t *edge; /* edge associated with this connection */
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
RSA *rsa_key; /* his public/private key */
|
||||
const EVP_CIPHER *incipher; /* Cipher he will use to send data to us */
|
||||
const EVP_CIPHER *outcipher; /* Cipher we will use to send data to him */
|
||||
EVP_CIPHER_CTX *inctx; /* Context of encrypted meta data that will come from him to us */
|
||||
EVP_CIPHER_CTX *outctx; /* Context of encrypted meta data that will be sent from us to him */
|
||||
const EVP_MD *indigest;
|
||||
const EVP_MD *outdigest;
|
||||
#endif
|
||||
|
||||
#ifdef USE_GCRYPT
|
||||
GCRY_SEXP rsa_key;
|
||||
GCRY_CIPHER_HD incipher;
|
||||
GCRY_CIPHER_HD outcipher;
|
||||
GCRY_CIPHER_HD inctx;
|
||||
GCRY_CIPHER_HD outctx;
|
||||
GCRY_MD_HD indigest;
|
||||
GCRY_MD_HD outdigest;
|
||||
/* FIXME */
|
||||
#endif
|
||||
|
||||
char *inkey; /* His symmetric meta key + iv */
|
||||
char *outkey; /* Our symmetric meta key + iv */
|
||||
int inkeylength; /* Length of his key + iv */
|
||||
int outkeylength; /* Length of our key + iv */
|
||||
int inmaclength;
|
||||
int outmaclength;
|
||||
int incompression;
|
||||
int outcompression;
|
||||
char *mychallenge; /* challenge we received from him */
|
||||
char *hischallenge; /* challenge we sent to him */
|
||||
|
||||
char buffer[MAXBUFSIZE]; /* metadata input buffer */
|
||||
int buflen; /* bytes read into buffer */
|
||||
int tcplen; /* length of incoming TCPpacket */
|
||||
int allow_request; /* defined if there's only one request possible */
|
||||
|
||||
time_t last_ping_time; /* last time we saw some activity from the other end */
|
||||
|
||||
avl_tree_t *config_tree; /* Pointer to configuration tree belonging to him */
|
||||
} connection_t;
|
||||
|
||||
extern avl_tree_t *connection_tree;
|
||||
|
||||
extern void init_connections(void);
|
||||
extern void exit_connections(void);
|
||||
extern connection_t *new_connection(void);
|
||||
extern void free_connection(connection_t *);
|
||||
extern void connection_add(connection_t *);
|
||||
extern void connection_del(connection_t *);
|
||||
extern void dump_connections(void);
|
||||
extern int read_connection_config(connection_t *);
|
||||
|
||||
#endif /* __TINC_CONNECTION_H__ */
|
206
lib/dropin.c
206
lib/dropin.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
dropin.c -- a set of drop-in replacements for libc functions
|
||||
Copyright (C) 2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>,
|
||||
2000,2001 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 2000-2003 Ivo Timmermans <ivo@o2w.nl>,
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -17,23 +17,12 @@
|
|||
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.2 2002/04/09 15:26:00 zarq Exp $
|
||||
$Id: dropin.c,v 1.3 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <xalloc.h>
|
||||
|
||||
#include <system.h>
|
||||
#include <errno.h>
|
||||
#include "xalloc.h"
|
||||
|
||||
#ifndef HAVE_DAEMON
|
||||
/*
|
||||
|
@ -51,61 +40,55 @@
|
|||
*/
|
||||
int daemon(int nochdir, int noclose)
|
||||
{
|
||||
pid_t pid;
|
||||
int fd;
|
||||
|
||||
pid = fork();
|
||||
|
||||
/* Check if forking failed */
|
||||
if(pid < 0)
|
||||
{
|
||||
perror("fork");
|
||||
exit(-1);
|
||||
}
|
||||
#ifdef HAVE_FORK
|
||||
pid_t pid;
|
||||
int fd;
|
||||
|
||||
/* If we are the parent, terminate */
|
||||
if(pid)
|
||||
exit(0);
|
||||
pid = fork();
|
||||
|
||||
/* Detach by becoming the new process group leader */
|
||||
if(setsid() < 0)
|
||||
{
|
||||
perror("setsid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Change working directory to the root (to avoid keeping mount
|
||||
points busy) */
|
||||
if(!nochdir)
|
||||
{
|
||||
chdir("/");
|
||||
}
|
||||
|
||||
/* Redirect stdin/out/err to /dev/null */
|
||||
if(!noclose)
|
||||
{
|
||||
fd = open("/dev/null", O_RDWR);
|
||||
/* Check if forking failed */
|
||||
if(pid < 0) {
|
||||
perror("fork");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if(fd < 0)
|
||||
{
|
||||
perror("opening /dev/null");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dup2(fd, 0);
|
||||
dup2(fd, 1);
|
||||
dup2(fd, 2);
|
||||
}
|
||||
}
|
||||
/* If we are the parent, terminate */
|
||||
if(pid)
|
||||
exit(0);
|
||||
|
||||
return 0;
|
||||
/* Detach by becoming the new process group leader */
|
||||
if(setsid() < 0) {
|
||||
perror("setsid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Change working directory to the root (to avoid keeping mount
|
||||
points busy) */
|
||||
if(!nochdir) {
|
||||
chdir("/");
|
||||
}
|
||||
|
||||
/* Redirect stdin/out/err to /dev/null */
|
||||
if(!noclose) {
|
||||
fd = open("/dev/null", O_RDWR);
|
||||
|
||||
if(fd < 0) {
|
||||
perror("opening /dev/null");
|
||||
return -1;
|
||||
} else {
|
||||
dup2(fd, 0);
|
||||
dup2(fd, 1);
|
||||
dup2(fd, 2);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef HAVE_GET_CURRENT_DIR_NAME
|
||||
/*
|
||||
Replacement for the GNU get_current_dir_name function:
|
||||
|
@ -116,56 +99,75 @@ int daemon(int nochdir, int noclose)
|
|||
*/
|
||||
char *get_current_dir_name(void)
|
||||
{
|
||||
size_t size;
|
||||
char *buf;
|
||||
char *r;
|
||||
size_t size;
|
||||
char *buf;
|
||||
char *r;
|
||||
|
||||
/* Start with 100 bytes. If this turns out to be insufficient to
|
||||
contain the working directory, double the size. */
|
||||
size = 100;
|
||||
buf = xmalloc(size);
|
||||
/* Start with 100 bytes. If this turns out to be insufficient to
|
||||
contain the working directory, double the size. */
|
||||
size = 100;
|
||||
buf = xmalloc(size);
|
||||
|
||||
errno = 0; /* Success */
|
||||
r = getcwd(buf, size);
|
||||
/* getcwd returns NULL and sets errno to ERANGE if the bufferspace
|
||||
is insufficient to contain the entire working directory. */
|
||||
while(r == NULL && errno == ERANGE)
|
||||
{
|
||||
free(buf);
|
||||
size <<= 1; /* double the size */
|
||||
buf = xmalloc(size);
|
||||
r = getcwd(buf, size);
|
||||
}
|
||||
errno = 0; /* Success */
|
||||
r = getcwd(buf, size);
|
||||
|
||||
return buf;
|
||||
/* getcwd returns NULL and sets errno to ERANGE if the bufferspace
|
||||
is insufficient to contain the entire working directory. */
|
||||
while(r == NULL && errno == ERANGE) {
|
||||
free(buf);
|
||||
size <<= 1; /* double the size */
|
||||
buf = xmalloc(size);
|
||||
r = getcwd(buf, size);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ASPRINTF
|
||||
int asprintf(char **buf, const char *fmt, ...)
|
||||
{
|
||||
int status;
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
len = 4096;
|
||||
*buf = xmalloc(len);
|
||||
int status;
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
va_start(ap, fmt);
|
||||
status = vsnprintf (*buf, len, fmt, ap);
|
||||
va_end (ap);
|
||||
len = 4096;
|
||||
*buf = xmalloc(len);
|
||||
|
||||
if(status >= 0)
|
||||
*buf = xrealloc(*buf, status);
|
||||
va_start(ap, fmt);
|
||||
status = vsnprintf(*buf, len, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if(status > len-1)
|
||||
{
|
||||
len = status;
|
||||
va_start(ap, fmt);
|
||||
status = vsnprintf (*buf, len, fmt, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
if(status >= 0)
|
||||
*buf = xrealloc(*buf, status + 1);
|
||||
|
||||
return status;
|
||||
if(status > len - 1) {
|
||||
len = status;
|
||||
va_start(ap, fmt);
|
||||
status = vsnprintf(*buf, len, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETTIMEOFDAY
|
||||
int gettimeofday(struct timeval *tv, void *tz) {
|
||||
tv->tv_sec = time(NULL);
|
||||
tv->tv_usec = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RANDOM
|
||||
#include <openssl/rand.h>
|
||||
|
||||
long int random(void) {
|
||||
long int x;
|
||||
|
||||
RAND_pseudo_bytes((unsigned char *)&x, sizeof(x));
|
||||
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
|
26
lib/dropin.h
26
lib/dropin.h
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
dropin.h -- header file for dropin.c
|
||||
Copyright (C) 2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>,
|
||||
2000,2001 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 2000-2003 Ivo Timmermans <ivo@o2w.nl>,
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -17,22 +17,38 @@
|
|||
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.2 2002/04/09 15:26:00 zarq Exp $
|
||||
$Id: dropin.h,v 1.3 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __DROPIN_H__
|
||||
#define __DROPIN_H__
|
||||
|
||||
#include "fake-getaddrinfo.h"
|
||||
#include "fake-getnameinfo.h"
|
||||
|
||||
#ifndef HAVE_DAEMON
|
||||
extern int daemon(int, int);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GET_CURRENT_DIR_NAME
|
||||
extern char* get_current_dir_name(void);
|
||||
extern char *get_current_dir_name(void);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ASPRINTF
|
||||
extern int asprintf(char **, const char *, ...);
|
||||
#endif
|
||||
|
||||
#endif /* __DROPIN_H__ */
|
||||
#ifndef HAVE_GETNAMEINFO
|
||||
extern int getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
|
||||
size_t hostlen, char *serv, size_t servlen, int flags);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETTIMEOFDAY
|
||||
extern int gettimeofday(struct timeval *, void *);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RANDOM
|
||||
extern long int random(void);
|
||||
#endif
|
||||
|
||||
#endif /* __DROPIN_H__ */
|
||||
|
|
212
lib/edge.c
212
lib/edge.c
|
@ -1,212 +0,0 @@
|
|||
/*
|
||||
edge.c -- edge tree management
|
||||
Copyright (C) 2000-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2000-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
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: edge.c,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
#include <list.h>
|
||||
|
||||
#include "net.h" /* Don't ask. */
|
||||
#include "netutl.h"
|
||||
#include "config.h"
|
||||
#include "conf.h"
|
||||
#include <utils.h>
|
||||
#include "subnet.h"
|
||||
|
||||
#include "xalloc.h"
|
||||
#include "system.h"
|
||||
|
||||
avl_tree_t *edge_tree; /* Tree with all known edges (replaces active_tree) */
|
||||
avl_tree_t *edge_weight_tree; /* Tree with all edges, sorted on weight */
|
||||
|
||||
int edge_compare(edge_t *a, edge_t *b)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = strcmp(a->from.node->name, b->from.node->name);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
else
|
||||
return strcmp(a->to.node->name, b->to.node->name);
|
||||
}
|
||||
|
||||
/* Evil edge_compare() from a parallel universe ;)
|
||||
|
||||
int edge_compare(edge_t *a, edge_t *b)
|
||||
{
|
||||
int result;
|
||||
|
||||
return (result = strcmp(a->from.node->name, b->from.node->name)) || (result = strcmp(a->to.node->name, b->to.node->name)), result;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
int edge_name_compare(edge_t *a, edge_t *b)
|
||||
{
|
||||
int result;
|
||||
char *name_a1, *name_a2, *name_b1, *name_b2;
|
||||
|
||||
if(strcmp(a->from.node->name, a->to.node->name) < 0)
|
||||
name_a1 = a->from.node->name, name_a2 = a->to.node->name;
|
||||
else
|
||||
name_a1 = a->to.node->name, name_a2 = a->from.node->name;
|
||||
|
||||
if(strcmp(b->from.node->name, b->to.node->name) < 0)
|
||||
name_b1 = b->from.node->name, name_b2 = b->to.node->name;
|
||||
else
|
||||
name_b1 = b->to.node->name, name_b2 = b->from.node->name;
|
||||
|
||||
result = strcmp(name_a1, name_b1);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
else
|
||||
return strcmp(name_a2, name_b2);
|
||||
}
|
||||
|
||||
int edge_weight_compare(edge_t *a, edge_t *b)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = a->weight - b->weight;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
else
|
||||
return edge_name_compare(a, b);
|
||||
}
|
||||
|
||||
void init_edges(void)
|
||||
{
|
||||
cp
|
||||
edge_tree = avl_alloc_tree((avl_compare_t)edge_compare, NULL);
|
||||
edge_weight_tree = avl_alloc_tree((avl_compare_t)edge_weight_compare, NULL);
|
||||
cp
|
||||
}
|
||||
|
||||
avl_tree_t *new_edge_tree(void)
|
||||
{
|
||||
cp
|
||||
return avl_alloc_tree((avl_compare_t)edge_name_compare, NULL);
|
||||
cp
|
||||
}
|
||||
|
||||
void free_edge_tree(avl_tree_t *edge_tree)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(edge_tree);
|
||||
cp
|
||||
}
|
||||
|
||||
void exit_edges(void)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(edge_tree);
|
||||
cp
|
||||
}
|
||||
|
||||
/* Creation and deletion of connection elements */
|
||||
|
||||
edge_t *new_edge(void)
|
||||
{
|
||||
edge_t *e;
|
||||
cp
|
||||
e = (edge_t *)xmalloc_and_zero(sizeof(*e));
|
||||
cp
|
||||
return e;
|
||||
}
|
||||
|
||||
void free_edge(edge_t *e)
|
||||
{
|
||||
cp
|
||||
free(e);
|
||||
cp
|
||||
}
|
||||
|
||||
void edge_add(edge_t *e)
|
||||
{
|
||||
cp
|
||||
avl_insert(edge_tree, e);
|
||||
avl_insert(edge_weight_tree, e);
|
||||
avl_insert(e->from.node->edge_tree, e);
|
||||
avl_insert(e->to.node->edge_tree, e);
|
||||
cp
|
||||
}
|
||||
|
||||
void edge_del(edge_t *e)
|
||||
{
|
||||
cp
|
||||
avl_delete(edge_tree, e);
|
||||
avl_delete(edge_weight_tree, e);
|
||||
avl_delete(e->from.node->edge_tree, e);
|
||||
avl_delete(e->to.node->edge_tree, e);
|
||||
cp
|
||||
}
|
||||
|
||||
edge_t *lookup_edge(node_t *from, node_t *to)
|
||||
{
|
||||
edge_t v, *result;
|
||||
cp
|
||||
v.from.node = from;
|
||||
v.to.node = to;
|
||||
|
||||
result = avl_search(edge_tree, &v);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
cp
|
||||
v.from.node = to;
|
||||
v.to.node = from;
|
||||
|
||||
return avl_search(edge_tree, &v);
|
||||
}
|
||||
|
||||
void dump_edges(void)
|
||||
{
|
||||
avl_node_t *node;
|
||||
edge_t *e;
|
||||
char *from_udp, *to_udp;
|
||||
cp
|
||||
syslog(LOG_DEBUG, _("Edges:"));
|
||||
|
||||
for(node = edge_tree->head; node; node = node->next)
|
||||
{
|
||||
e = (edge_t *)node->data;
|
||||
from_udp = sockaddr2hostname(&e->from.udpaddress);
|
||||
to_udp = sockaddr2hostname(&e->to.udpaddress);
|
||||
syslog(LOG_DEBUG, _(" %s at %s - %s at %s options %lx weight %d"),
|
||||
e->from.node->name, from_udp,
|
||||
e->to.node->name, to_udp,
|
||||
e->options, e->weight);
|
||||
free(from_udp);
|
||||
free(to_udp);
|
||||
}
|
||||
|
||||
syslog(LOG_DEBUG, _("End of edges."));
|
||||
cp
|
||||
}
|
60
lib/error.c
60
lib/error.c
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
error.c -- generalized error handling
|
||||
Copyright (C) 2000 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
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: error.c,v 1.1 2000/10/19 20:56:49 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
# include <syslog.h>
|
||||
#endif
|
||||
|
||||
#include <error.h>
|
||||
#include <system.h>
|
||||
|
||||
void error(int severity, const char *message, ...)
|
||||
{
|
||||
va_list v;
|
||||
extern int detached;
|
||||
|
||||
va_start(v, message);
|
||||
|
||||
#ifdef HAVE_SYSLOG
|
||||
if(detached)
|
||||
{
|
||||
syslog(LOG_ERR, _(message), v);
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_SYSLOG */
|
||||
{
|
||||
vfprintf(stderr, _(message), v);
|
||||
fputs("\n", stderr);
|
||||
}
|
||||
va_end(v);
|
||||
|
||||
if(severity | ERR_FATAL)
|
||||
exit(1);
|
||||
}
|
34
lib/error.h
34
lib/error.h
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
error.h -- header file for error.h
|
||||
Copyright (C) 2000 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
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: error.h,v 1.1 2000/10/19 20:56:49 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_ERROR_H__
|
||||
#define __TINC_ERROR_H__
|
||||
|
||||
#define ERR_IGNORE 00000 /* Ignore this error */
|
||||
#define ERR_FATAL 00001 /* Terminate program */
|
||||
#define ERR_UNLOAD 00002 /* Unload associated module */
|
||||
#define ERR_WARNING 01000 /* Warning message only */
|
||||
#define ERR_DEBUG 04000 /* Debug message */
|
||||
|
||||
extern void error(int severity, const char *message, ...);
|
||||
|
||||
#endif /* __TINC_ERROR_H__ */
|
75
lib/ethernet.h
Normal file
75
lib/ethernet.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
ethernet.h -- missing Ethernet related definitions
|
||||
Copyright (C) 2003 Ivo Timmermans <ivo@o2w.nl>
|
||||
2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
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: ethernet.h,v 1.2 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_ETHERNET_H__
|
||||
#define __TINC_ETHERNET_H__
|
||||
|
||||
#ifndef ETH_ALEN
|
||||
#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
|
||||
#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;
|
||||
};
|
||||
|
||||
#define ARPOP_REQUEST 1
|
||||
#define ARPOP_REPLY 2
|
||||
#define ARPOP_RREQUEST 3
|
||||
#define ARPOP_RREPLY 4
|
||||
#define ARPOP_InREQUEST 8
|
||||
#define ARPOP_InREPLY 9
|
||||
#define ARPOP_NAK 10
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ETHER_ARP
|
||||
struct ether_arp {
|
||||
struct arphdr ea_hdr;
|
||||
uint8_t arp_sha[ETH_ALEN];
|
||||
uint8_t arp_spa[4];
|
||||
uint8_t arp_tha[ETH_ALEN];
|
||||
uint8_t arp_tpa[4];
|
||||
};
|
||||
#define arp_hrd ea_hdr.ar_hrd
|
||||
#define arp_pro ea_hdr.ar_pro
|
||||
#define arp_hln ea_hdr.ar_hln
|
||||
#define arp_pln ea_hdr.ar_pln
|
||||
#define arp_op ea_hdr.ar_op
|
||||
#endif
|
||||
|
||||
#endif /* __TINC_ETHERNET_H__ */
|
15
lib/fake-gai-errnos.h
Normal file
15
lib/fake-gai-errnos.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* fake library for ssh
|
||||
*
|
||||
* This file is included in getaddrinfo.c and getnameinfo.c.
|
||||
* See getaddrinfo.c and getnameinfo.c.
|
||||
*/
|
||||
|
||||
/* $Id: fake-gai-errnos.h,v 1.2 2003/08/24 20:38:20 guus Exp $ */
|
||||
|
||||
/* for old netdb.h */
|
||||
#ifndef EAI_NODATA
|
||||
#define EAI_NODATA 1
|
||||
#define EAI_MEMORY 2
|
||||
#define EAI_FAMILY 3
|
||||
#endif
|
104
lib/fake-getaddrinfo.c
Normal file
104
lib/fake-getaddrinfo.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* fake library for ssh
|
||||
*
|
||||
* This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
|
||||
* These funtions are defined in rfc2133.
|
||||
*
|
||||
* But these functions are not implemented correctly. The minimum subset
|
||||
* is implemented for ssh use only. For exapmle, this routine assumes
|
||||
* that ai_family is AF_INET. Don't use it for another purpose.
|
||||
*/
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "ipv4.h"
|
||||
#include "ipv6.h"
|
||||
#include "fake-getaddrinfo.h"
|
||||
|
||||
#ifndef HAVE_GAI_STRERROR
|
||||
char *gai_strerror(int ecode)
|
||||
{
|
||||
switch (ecode) {
|
||||
case EAI_NODATA:
|
||||
return "No address associated with hostname";
|
||||
case EAI_MEMORY:
|
||||
return "Memory allocation failure";
|
||||
case EAI_FAMILY:
|
||||
return "Address family not supported";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
}
|
||||
#endif /* !HAVE_GAI_STRERROR */
|
||||
|
||||
#ifndef HAVE_FREEADDRINFO
|
||||
void freeaddrinfo(struct addrinfo *ai)
|
||||
{
|
||||
struct addrinfo *next;
|
||||
|
||||
while(ai) {
|
||||
next = ai->ai_next;
|
||||
free(ai);
|
||||
ai = next;
|
||||
}
|
||||
}
|
||||
#endif /* !HAVE_FREEADDRINFO */
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
static struct addrinfo *malloc_ai(uint16_t port, uint32_t addr)
|
||||
{
|
||||
struct addrinfo *ai;
|
||||
|
||||
ai = xmalloc_and_zero(sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
|
||||
|
||||
ai->ai_addr = (struct sockaddr *)(ai + 1);
|
||||
ai->ai_addrlen = sizeof(struct sockaddr_in);
|
||||
ai->ai_addr->sa_family = ai->ai_family = AF_INET;
|
||||
|
||||
((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
|
||||
((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
|
||||
{
|
||||
struct addrinfo *prev = NULL;
|
||||
struct hostent *hp;
|
||||
struct in_addr in = {0};
|
||||
int i;
|
||||
uint16_t port = 0;
|
||||
|
||||
if(hints && hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC)
|
||||
return EAI_FAMILY;
|
||||
|
||||
if (servname)
|
||||
port = htons(atoi(servname));
|
||||
|
||||
if (hints && hints->ai_flags & AI_PASSIVE) {
|
||||
*res = malloc_ai(port, htonl(0x00000000));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hostname) {
|
||||
*res = malloc_ai(port, htonl(0x7f000001));
|
||||
return 0;
|
||||
}
|
||||
|
||||
hp = gethostbyname(hostname);
|
||||
|
||||
if(!hp || !hp->h_addr_list || !hp->h_addr_list[0])
|
||||
return EAI_NODATA;
|
||||
|
||||
for (i = 0; hp->h_addr_list[i]; i++) {
|
||||
*res = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr);
|
||||
|
||||
if(prev)
|
||||
prev->ai_next = *res;
|
||||
|
||||
prev = *res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !HAVE_GETADDRINFO */
|
49
lib/fake-getaddrinfo.h
Normal file
49
lib/fake-getaddrinfo.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* $Id: fake-getaddrinfo.h,v 1.2 2003/08/24 20:38:20 guus Exp $ */
|
||||
|
||||
#ifndef _FAKE_GETADDRINFO_H
|
||||
#define _FAKE_GETADDRINFO_H
|
||||
|
||||
#include "fake-gai-errnos.h"
|
||||
|
||||
#ifndef AI_PASSIVE
|
||||
# define AI_PASSIVE 1
|
||||
# define AI_CANONNAME 2
|
||||
#endif
|
||||
|
||||
#ifndef NI_NUMERICHOST
|
||||
# define NI_NUMERICHOST 2
|
||||
# define NI_NAMEREQD 4
|
||||
# define NI_NUMERICSERV 8
|
||||
#endif
|
||||
|
||||
#ifndef AI_NUMERICHOST
|
||||
#define AI_NUMERICHOST 4
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ADDRINFO
|
||||
struct addrinfo {
|
||||
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
|
||||
int ai_family; /* PF_xxx */
|
||||
int ai_socktype; /* SOCK_xxx */
|
||||
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
|
||||
size_t ai_addrlen; /* length of ai_addr */
|
||||
char *ai_canonname; /* canonical name for hostname */
|
||||
struct sockaddr *ai_addr; /* binary address */
|
||||
struct addrinfo *ai_next; /* next structure in linked list */
|
||||
};
|
||||
#endif /* !HAVE_STRUCT_ADDRINFO */
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
int getaddrinfo(const char *hostname, const char *servname,
|
||||
const struct addrinfo *hints, struct addrinfo **res);
|
||||
#endif /* !HAVE_GETADDRINFO */
|
||||
|
||||
#ifndef HAVE_GAI_STRERROR
|
||||
char *gai_strerror(int ecode);
|
||||
#endif /* !HAVE_GAI_STRERROR */
|
||||
|
||||
#ifndef HAVE_FREEADDRINFO
|
||||
void freeaddrinfo(struct addrinfo *ai);
|
||||
#endif /* !HAVE_FREEADDRINFO */
|
||||
|
||||
#endif /* _FAKE_GETADDRINFO_H */
|
55
lib/fake-getnameinfo.c
Normal file
55
lib/fake-getnameinfo.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* fake library for ssh
|
||||
*
|
||||
* This file includes getnameinfo().
|
||||
* These funtions are defined in rfc2133.
|
||||
*
|
||||
* But these functions are not implemented correctly. The minimum subset
|
||||
* is implemented for ssh use only. For exapmle, this routine assumes
|
||||
* that ai_family is AF_INET. Don't use it for another purpose.
|
||||
*/
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "fake-getnameinfo.h"
|
||||
#include "fake-getaddrinfo.h"
|
||||
|
||||
#ifndef HAVE_GETNAMEINFO
|
||||
|
||||
int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags)
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
struct hostent *hp;
|
||||
int len;
|
||||
|
||||
if(sa->sa_family != AF_INET)
|
||||
return EAI_FAMILY;
|
||||
|
||||
if(serv && servlen) {
|
||||
len = snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
|
||||
if(len < 0 || len >= servlen)
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
if(!host || !hostlen)
|
||||
return 0;
|
||||
|
||||
if(flags & NI_NUMERICHOST) {
|
||||
len = snprintf(host, hostlen, "%s", inet_ntoa(sin->sin_addr));
|
||||
if(len < 0 || len >= hostlen)
|
||||
return EAI_MEMORY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr), AF_INET);
|
||||
|
||||
if(!hp || !hp->h_name || !hp->h_name[0])
|
||||
return EAI_NODATA;
|
||||
|
||||
len = snprintf(host, hostlen, "%s", hp->h_name);
|
||||
if(len < 0 || len >= hostlen)
|
||||
return EAI_MEMORY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !HAVE_GETNAMEINFO */
|
18
lib/fake-getnameinfo.h
Normal file
18
lib/fake-getnameinfo.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* $Id: fake-getnameinfo.h,v 1.2 2003/08/24 20:38:20 guus Exp $ */
|
||||
|
||||
#ifndef _FAKE_GETNAMEINFO_H
|
||||
#define _FAKE_GETNAMEINFO_H
|
||||
|
||||
#ifndef HAVE_GETNAMEINFO
|
||||
int getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
|
||||
size_t hostlen, char *serv, size_t servlen, int flags);
|
||||
#endif /* !HAVE_GETNAMEINFO */
|
||||
|
||||
#ifndef NI_MAXSERV
|
||||
# define NI_MAXSERV 32
|
||||
#endif /* !NI_MAXSERV */
|
||||
#ifndef NI_MAXHOST
|
||||
# define NI_MAXHOST 1025
|
||||
#endif /* !NI_MAXHOST */
|
||||
|
||||
#endif /* _FAKE_GETNAMEINFO_H */
|
13
lib/getopt.c
13
lib/getopt.c
|
@ -85,16 +85,7 @@ USA. */
|
|||
#define getpid() GetCurrentProcessId()
|
||||
#endif
|
||||
|
||||
#ifndef _
|
||||
/* This is for other GNU distributions with internationalized messages.
|
||||
When compiling libc, the _ macro is predefined. */
|
||||
#ifdef HAVE_LIBINTL_H
|
||||
# include <libintl.h>
|
||||
# define _(msgid) gettext (msgid)
|
||||
#else
|
||||
# define _(msgid) (msgid)
|
||||
#endif
|
||||
#endif
|
||||
#include "gettext.h"
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
|
@ -268,7 +259,7 @@ extern pid_t __libc_pid;
|
|||
is valid for the getopt call we must make sure that the ARGV passed
|
||||
to getopt is that one passed to the process. */
|
||||
static void
|
||||
__attribute__ ((unused))
|
||||
__attribute__ ((__unused__))
|
||||
store_args_and_env (int argc, char *const *argv)
|
||||
{
|
||||
/* XXX This is no good solution. We should rather copy the args so
|
||||
|
|
79
lib/gettext.h
Normal file
79
lib/gettext.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* Convenience header for conditional use of GNU <libintl.h>.
|
||||
Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
by the Free Software Foundation; either version 2, 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
USA. */
|
||||
|
||||
#ifndef _LIBGETTEXT_H
|
||||
#define _LIBGETTEXT_H 1
|
||||
|
||||
/* NLS can be disabled through the configure --disable-nls option. */
|
||||
#if ENABLE_NLS
|
||||
|
||||
/* Get declarations of GNU message catalog functions. */
|
||||
# include <libintl.h>
|
||||
# include <locale.h>
|
||||
|
||||
/* Shorthand notation */
|
||||
|
||||
# define _(Text) gettext (Text)
|
||||
|
||||
#else
|
||||
|
||||
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
|
||||
chokes if dcgettext is defined as a macro. So include it now, to make
|
||||
later inclusions of <locale.h> a NOP. We don't include <libintl.h>
|
||||
as well because people using "gettext.h" will not include <libintl.h>,
|
||||
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
|
||||
is OK. */
|
||||
#if defined(__sun)
|
||||
# include <locale.h>
|
||||
#endif
|
||||
|
||||
/* Disabled NLS.
|
||||
The casts to 'const char *' serve the purpose of producing warnings
|
||||
for invalid uses of the value returned from these functions.
|
||||
On pre-ANSI systems without 'const', the config.h file is supposed to
|
||||
contain "#define const". */
|
||||
# define gettext(Msgid) ((const char *) (Msgid))
|
||||
# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
|
||||
# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
|
||||
# define ngettext(Msgid1, Msgid2, N) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define dngettext(Domainname, Msgid1, Msgid2, N) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define textdomain(Domainname) ((const char *) (Domainname))
|
||||
# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
|
||||
# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
|
||||
|
||||
# define _(Text) Text
|
||||
# define setlocale(Category, Locale) ((const char *) (Locale))
|
||||
|
||||
#endif
|
||||
|
||||
/* A pseudo function call that serves as a marker for the automated
|
||||
extraction of messages, but does not call gettext(). The run-time
|
||||
translation is done at a different place in the code.
|
||||
The argument, String, should be a literal string. Concatenated strings
|
||||
and other string expressions won't work.
|
||||
The macro's expansion is not parenthesized, so that it is suitable as
|
||||
initializer for static 'char[]' or 'const char[]' variables. */
|
||||
#define gettext_noop(String) String
|
||||
|
||||
#define N_(Text) Text
|
||||
|
||||
#endif /* _LIBGETTEXT_H */
|
285
lib/graph.c
285
lib/graph.c
|
@ -1,285 +0,0 @@
|
|||
/*
|
||||
graph.c -- graph algorithms
|
||||
Copyright (C) 2001-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2001-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
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: graph.c,v 1.1 2002/05/02 11:50:07 zarq Exp $
|
||||
*/
|
||||
|
||||
/* We need to generate two trees from the graph:
|
||||
|
||||
1. A minimum spanning tree for broadcasts,
|
||||
2. A single-source shortest path tree for unicasts.
|
||||
|
||||
Actually, the first one alone would suffice but would make unicast packets
|
||||
take longer routes than necessary.
|
||||
|
||||
For the MST algorithm we can choose from Prim's or Kruskal's. I personally
|
||||
favour Kruskal's, because we make an extra AVL tree of edges sorted on
|
||||
weights (metric). That tree only has to be updated when an edge is added or
|
||||
removed, and during the MST algorithm we just have go linearly through that
|
||||
tree, adding safe edges until #edges = #nodes - 1. The implementation here
|
||||
however is not so fast, because I tried to avoid having to make a forest and
|
||||
merge trees.
|
||||
|
||||
For the SSSP algorithm Dijkstra's seems to be a nice choice. Currently a
|
||||
simple breadth-first search is presented here.
|
||||
|
||||
The SSSP algorithm will also be used to determine whether nodes are directly,
|
||||
indirectly or not reachable from the source. It will also set the correct
|
||||
destination address and port of a node if possible.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if defined(HAVE_FREEBSD) || defined(HAVE_OPENBSD)
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
#include <hooks.h>
|
||||
#include <utils.h>
|
||||
|
||||
#include "netutl.h"
|
||||
#include "node.h"
|
||||
#include "edge.h"
|
||||
#include "connection.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
/* Implementation of Kruskal's algorithm.
|
||||
Running time: O(EN)
|
||||
Please note that sorting on weight is already done by add_edge().
|
||||
*/
|
||||
|
||||
void mst_kruskal(void)
|
||||
{
|
||||
avl_node_t *node, *next;
|
||||
edge_t *e;
|
||||
node_t *n;
|
||||
connection_t *c;
|
||||
int nodes = 0;
|
||||
int safe_edges = 0;
|
||||
int skipped;
|
||||
|
||||
/* Clear MST status on connections */
|
||||
|
||||
for(node = connection_tree->head; node; node = node->next)
|
||||
{
|
||||
c = (connection_t *)node->data;
|
||||
c->status.mst = 0;
|
||||
}
|
||||
|
||||
/* Do we have something to do at all? */
|
||||
|
||||
if(!edge_weight_tree->head)
|
||||
return;
|
||||
|
||||
if(debug_lvl >= DEBUG_SCARY_THINGS)
|
||||
syslog(LOG_DEBUG, "Running Kruskal's algorithm:");
|
||||
|
||||
/* Clear visited status on nodes */
|
||||
|
||||
for(node = node_tree->head; node; node = node->next)
|
||||
{
|
||||
n = (node_t *)node->data;
|
||||
n->status.visited = 0;
|
||||
nodes++;
|
||||
}
|
||||
|
||||
/* Starting point */
|
||||
|
||||
((edge_t *)edge_weight_tree->head->data)->from.node->status.visited = 1;
|
||||
|
||||
/* Add safe edges */
|
||||
|
||||
for(skipped = 0, node = edge_weight_tree->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
e = (edge_t *)node->data;
|
||||
|
||||
if(e->from.node->status.visited == e->to.node->status.visited)
|
||||
{
|
||||
skipped = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
e->from.node->status.visited = 1;
|
||||
e->to.node->status.visited = 1;
|
||||
if(e->connection)
|
||||
e->connection->status.mst = 1;
|
||||
|
||||
safe_edges++;
|
||||
|
||||
if(debug_lvl >= DEBUG_SCARY_THINGS)
|
||||
syslog(LOG_DEBUG, " Adding edge %s - %s weight %d", e->from.node->name, e->to.node->name, e->weight);
|
||||
|
||||
if(skipped)
|
||||
{
|
||||
next = edge_weight_tree->head;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(debug_lvl >= DEBUG_SCARY_THINGS)
|
||||
syslog(LOG_DEBUG, "Done, counted %d nodes and %d safe edges.", nodes, safe_edges);
|
||||
}
|
||||
|
||||
/* Implementation of a simple breadth-first search algorithm.
|
||||
Running time: O(E)
|
||||
*/
|
||||
|
||||
void sssp_bfs(void)
|
||||
{
|
||||
avl_node_t *node, *from, *next, *to;
|
||||
edge_t *e;
|
||||
node_t *n;
|
||||
halfconnection_t to_hc, from_hc;
|
||||
avl_tree_t *todo_tree;
|
||||
int indirect;
|
||||
|
||||
todo_tree = avl_alloc_tree(NULL, NULL);
|
||||
|
||||
/* Clear visited status on nodes */
|
||||
|
||||
for(node = node_tree->head; node; node = node->next)
|
||||
{
|
||||
n = (node_t *)node->data;
|
||||
n->status.visited = 0;
|
||||
n->status.indirect = 1;
|
||||
}
|
||||
|
||||
/* Begin with myself */
|
||||
|
||||
myself->status.visited = 1;
|
||||
myself->status.indirect = 0;
|
||||
myself->nexthop = myself;
|
||||
myself->via = myself;
|
||||
node = avl_alloc_node();
|
||||
node->data = myself;
|
||||
avl_insert_top(todo_tree, node);
|
||||
|
||||
/* Loop while todo_tree is filled */
|
||||
|
||||
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;
|
||||
|
||||
for(to = n->edge_tree->head; to; to = to->next) /* "to" is the edge connected to "from" */
|
||||
{
|
||||
e = (edge_t *)to->data;
|
||||
|
||||
if(e->from.node == n) /* "from_hc" is the halfconnection with .node == from */
|
||||
to_hc = e->to, from_hc = e->from;
|
||||
else
|
||||
to_hc = e->from, from_hc = e->to;
|
||||
|
||||
/* Situation:
|
||||
|
||||
/
|
||||
/
|
||||
------(n)from_hc-----to_hc
|
||||
\
|
||||
\
|
||||
|
||||
n->address is set to the to_hc.udpaddress of the edge left of n.
|
||||
We are currently examining the edge right of n:
|
||||
|
||||
- If from_hc.udpaddress != n->address, then to_hc.node is probably
|
||||
not reachable for the nodes left of n. We do as if the indirectdata
|
||||
flag is set on edge e.
|
||||
- If edge e provides for better reachability of to_hc.node, update
|
||||
to_hc.node and (re)add it to the todo_tree to (re)examine the reachability
|
||||
of nodes behind it.
|
||||
*/
|
||||
|
||||
indirect = n->status.indirect || e->options & OPTION_INDIRECT || ((n != myself) && sockaddrcmp(&n->address, &from_hc.udpaddress));
|
||||
|
||||
if(to_hc.node->status.visited && (!to_hc.node->status.indirect || indirect))
|
||||
continue;
|
||||
|
||||
to_hc.node->status.visited = 1;
|
||||
to_hc.node->status.indirect = indirect;
|
||||
to_hc.node->nexthop = (n->nexthop == myself) ? to_hc.node : n->nexthop;
|
||||
to_hc.node->via = indirect ? n->via : to_hc.node;
|
||||
to_hc.node->options = e->options;
|
||||
if(sockaddrcmp(&to_hc.node->address, &to_hc.udpaddress))
|
||||
{
|
||||
node = avl_unlink(node_udp_tree, to_hc.node);
|
||||
to_hc.node->address = to_hc.udpaddress;
|
||||
if(to_hc.node->hostname)
|
||||
free(to_hc.node->hostname);
|
||||
to_hc.node->hostname = sockaddr2hostname(&to_hc.udpaddress);
|
||||
avl_insert_node(node_udp_tree, node);
|
||||
}
|
||||
node = avl_alloc_node();
|
||||
node->data = to_hc.node;
|
||||
avl_insert_before(todo_tree, from, node);
|
||||
}
|
||||
|
||||
avl_delete_node(todo_tree, from);
|
||||
}
|
||||
}
|
||||
|
||||
avl_free_tree(todo_tree);
|
||||
|
||||
/* Check reachability status. */
|
||||
|
||||
for(node = node_tree->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
n = (node_t *)node->data;
|
||||
|
||||
if(n->status.visited)
|
||||
{
|
||||
if(!n->status.reachable)
|
||||
{
|
||||
if(debug_lvl >= DEBUG_TRAFFIC)
|
||||
syslog(LOG_DEBUG, _("Node %s (%s) became reachable"), n->name, n->hostname);
|
||||
n->status.reachable = 1;
|
||||
run_hooks("node-visible", n);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(n->status.reachable)
|
||||
{
|
||||
if(debug_lvl >= DEBUG_TRAFFIC)
|
||||
syslog(LOG_DEBUG, _("Node %s (%s) became unreachable"), n->name, n->hostname);
|
||||
n->status.reachable = 0;
|
||||
n->status.validkey = 0;
|
||||
n->status.waitingforkey = 0;
|
||||
n->sent_seqno = 0;
|
||||
run_hooks("node-invisible", n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void graph(void)
|
||||
{
|
||||
mst_kruskal();
|
||||
sssp_bfs();
|
||||
}
|
56
lib/hash.c
56
lib/hash.c
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
hash.c -- Handle hash datastructures
|
||||
Copyright (C) 2000 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
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: hash.c,v 1.1 2000/10/20 16:44:32 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/*
|
||||
hash_delete
|
||||
delete one element, indicated by key, from hash
|
||||
*/
|
||||
int hash_delete(hash_t hash, char *key)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
hash_insert_maybe
|
||||
insert an element into the hash, unless an element with the
|
||||
same key already exists.
|
||||
*/
|
||||
int hash_insert_maybe(hash_t hash, void *data, char *key)
|
||||
{
|
||||
if(hash_retrieve(hash, key))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
hash_insert_or_update
|
||||
|
||||
If an element indicated by key exists in the hash, update the
|
||||
associated pointer. Otherwise, insert this pointer as a new
|
||||
element.
|
||||
*/
|
||||
int hash_insert_or_update(hash_t hash, void *data, char *key)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
/* */
|
34
lib/hooks.h
34
lib/hooks.h
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
hooks.h -- header file for hooks.c
|
||||
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.h,v 1.2 2002/05/07 14:48:41 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_HOOKS_H__
|
||||
#define __TINC_HOOKS_H__
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef void (hook_function_t)(const char*,va_list);
|
||||
|
||||
void run_hooks(const char *type, ...);
|
||||
void add_hook(const char *type, hook_function_t *hook);
|
||||
void del_hook(const char *type, hook_function_t *hook);
|
||||
|
||||
#endif /* __TINC_HOOKS_H__ */
|
132
lib/ipv4.h
Normal file
132
lib/ipv4.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
ipv4.h -- missing IPv4 related definitions
|
||||
Copyright (C) 2003 Ivo Timmermans <ivo@o2w.nl>
|
||||
2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
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: ipv4.h,v 1.2 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_IPV4_H__
|
||||
#define __TINC_IPV4_H__
|
||||
|
||||
#ifndef AF_INET
|
||||
#define AF_INET 2
|
||||
#endif
|
||||
|
||||
#ifndef IPPROTO_ICMP
|
||||
#define IPPROTO_ICMP 1
|
||||
#endif
|
||||
|
||||
#ifndef ICMP_DEST_UNREACH
|
||||
#define ICMP_DEST_UNREACH 3
|
||||
#endif
|
||||
|
||||
#ifndef ICMP_NET_UNKNOWN
|
||||
#define ICMP_NET_UNKNOWN 6
|
||||
#endif
|
||||
|
||||
#ifndef ICMP_NET_UNREACH
|
||||
#define ICMP_NET_UNREACH 0
|
||||
#endif
|
||||
|
||||
#ifndef IP_MSS
|
||||
#define IP_MSS 576
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_IP
|
||||
struct ip {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int ip_hl:4;
|
||||
unsigned int ip_v:4;
|
||||
#else
|
||||
unsigned int ip_v:4;
|
||||
unsigned int ip_hl:4;
|
||||
#endif
|
||||
uint8_t ip_tos;
|
||||
uint16_t ip_len;
|
||||
uint16_t ip_id;
|
||||
uint16_t ip_off;
|
||||
#define IP_RF 0x8000
|
||||
#define IP_DF 0x4000
|
||||
#define IP_MF 0x2000
|
||||
#define IP_OFFMASK 0x1fff
|
||||
uint8_t ip_ttl;
|
||||
uint8_t ip_p;
|
||||
uint16_t ip_sum;
|
||||
struct in_addr ip_src, ip_dst;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ICMP
|
||||
struct icmp {
|
||||
uint8_t icmp_type;
|
||||
uint8_t icmp_code;
|
||||
uint16_t icmp_cksum;
|
||||
union {
|
||||
uint8_t ih_pptr;
|
||||
struct in_addr ih_gwaddr;
|
||||
struct ih_idseq {
|
||||
uint16_t icd_id;
|
||||
uint16_t icd_seq;
|
||||
} ih_idseq;
|
||||
uint32_t ih_void;
|
||||
|
||||
|
||||
struct ih_pmtu {
|
||||
uint16_t ipm_void;
|
||||
uint16_t ipm_nextmtu;
|
||||
} ih_pmtu;
|
||||
|
||||
struct ih_rtradv {
|
||||
uint8_t irt_num_addrs;
|
||||
uint8_t irt_wpa;
|
||||
uint16_t irt_lifetime;
|
||||
} ih_rtradv;
|
||||
} icmp_hun;
|
||||
#define icmp_pptr icmp_hun.ih_pptr
|
||||
#define icmp_gwaddr icmp_hun.ih_gwaddr
|
||||
#define icmp_id icmp_hun.ih_idseq.icd_id
|
||||
#define icmp_seq icmp_hun.ih_idseq.icd_seq
|
||||
#define icmp_void icmp_hun.ih_void
|
||||
#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
|
||||
#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
|
||||
#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
|
||||
#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
|
||||
#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
|
||||
union {
|
||||
struct {
|
||||
uint32_t its_otime;
|
||||
uint32_t its_rtime;
|
||||
uint32_t its_ttime;
|
||||
} id_ts;
|
||||
struct {
|
||||
struct ip idi_ip;
|
||||
} id_ip;
|
||||
uint32_t id_mask;
|
||||
uint8_t id_data[1];
|
||||
} icmp_dun;
|
||||
#define icmp_otime icmp_dun.id_ts.its_otime
|
||||
#define icmp_rtime icmp_dun.id_ts.its_rtime
|
||||
#define icmp_ttime icmp_dun.id_ts.its_ttime
|
||||
#define icmp_ip icmp_dun.id_ip.idi_ip
|
||||
#define icmp_radv icmp_dun.id_radv
|
||||
#define icmp_mask icmp_dun.id_mask
|
||||
#define icmp_data icmp_dun.id_data
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* __TINC_IPV4_H__ */
|
120
lib/ipv6.h
Normal file
120
lib/ipv6.h
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
ipv6.h -- missing IPv6 related definitions
|
||||
Copyright (C) 2003 Ivo Timmermans <ivo@o2w.nl>
|
||||
2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
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: ipv6.h,v 1.2 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_IPV6_H__
|
||||
#define __TINC_IPV6_H__
|
||||
|
||||
#ifndef AF_INET6
|
||||
#define AF_INET6 10
|
||||
#endif
|
||||
|
||||
#ifndef IPPROTO_ICMPV6
|
||||
#define IPPROTO_ICMPV6 58
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_IN6_ADDR
|
||||
struct in6_addr {
|
||||
union {
|
||||
uint8_t u6_addr8[16];
|
||||
uint16_t u6_addr16[8];
|
||||
uint32_t u6_addr32[4];
|
||||
} in6_u;
|
||||
};
|
||||
#define s6_addr in6_u.u6_addr8
|
||||
#define s6_addr16 in6_u.u6_addr16
|
||||
#define s6_addr32 in6_u.u6_addr32
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_SOCKADDR_IN6
|
||||
struct sockaddr_in6 {
|
||||
uint16_t sin6_family;
|
||||
uint16_t sin6_port;
|
||||
uint32_t sin6_flowinfo;
|
||||
struct in6_addr sin6_addr;
|
||||
uint32_t sin6_scope_id;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef IN6_IS_ADDR_V4MAPPED
|
||||
#define IN6_IS_ADDR_V4MAPPED(a) \
|
||||
((((__const uint32_t *) (a))[0] == 0) \
|
||||
&& (((__const uint32_t *) (a))[1] == 0) \
|
||||
&& (((__const uint32_t *) (a))[2] == htonl (0xffff)))
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_IP6_HDR
|
||||
struct ip6_hdr {
|
||||
union {
|
||||
struct ip6_hdrctl {
|
||||
uint32_t ip6_un1_flow;
|
||||
uint16_t ip6_un1_plen;
|
||||
uint8_t ip6_un1_nxt;
|
||||
uint8_t ip6_un1_hlim;
|
||||
} ip6_un1;
|
||||
uint8_t ip6_un2_vfc;
|
||||
} ip6_ctlun;
|
||||
struct in6_addr ip6_src;
|
||||
struct in6_addr ip6_dst;
|
||||
};
|
||||
#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
|
||||
#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
|
||||
#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
|
||||
#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ICMP6_HDR
|
||||
struct icmp6_hdr {
|
||||
uint8_t icmp6_type;
|
||||
uint8_t icmp6_code;
|
||||
uint16_t icmp6_cksum;
|
||||
union {
|
||||
uint32_t icmp6_un_data32[1];
|
||||
uint16_t icmp6_un_data16[2];
|
||||
uint8_t icmp6_un_data8[4];
|
||||
} icmp6_dataun;
|
||||
};
|
||||
#define ICMP6_DST_UNREACH_NOROUTE 0
|
||||
#define ICMP6_DST_UNREACH 1
|
||||
#define ICMP6_DST_UNREACH_ADDR 3
|
||||
#define ND_NEIGHBOR_SOLICIT 135
|
||||
#define ND_NEIGHBOR_ADVERT 136
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ND_NEIGHBOR_SOLICIT
|
||||
struct nd_neighbor_solicit {
|
||||
struct icmp6_hdr nd_ns_hdr;
|
||||
struct in6_addr nd_ns_target;
|
||||
};
|
||||
#define ND_OPT_SOURCE_LINKADDR 1
|
||||
#define ND_OPT_TARGET_LINKADDR 2
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ND_OPT_HDR
|
||||
struct nd_opt_hdr {
|
||||
uint8_t nd_opt_type;
|
||||
uint8_t nd_opt_len;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* __TINC_IPV6_H__ */
|
183
lib/list.c
183
lib/list.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
list.c -- functions to deal with double linked lists
|
||||
Copyright (C) 2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000,2001 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 2000-2003 Ivo Timmermans <ivo@o2w.nl>
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -17,181 +17,170 @@
|
|||
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.2 2002/04/09 15:26:00 zarq Exp $
|
||||
$Id: list.c,v 1.3 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <xalloc.h>
|
||||
#include <system.h>
|
||||
#include "system.h"
|
||||
|
||||
#include "list.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
/* (De)constructors */
|
||||
|
||||
list_t *list_alloc(list_action_t delete)
|
||||
{
|
||||
list_t *list;
|
||||
list_t *list;
|
||||
|
||||
list = xmalloc_and_zero(sizeof(list_t));
|
||||
list->delete = delete;
|
||||
list = xmalloc_and_zero(sizeof(list_t));
|
||||
list->delete = delete;
|
||||
|
||||
return list;
|
||||
return list;
|
||||
}
|
||||
|
||||
void list_free(list_t *list)
|
||||
{
|
||||
free(list);
|
||||
free(list);
|
||||
}
|
||||
|
||||
list_node_t *list_alloc_node(void)
|
||||
{
|
||||
list_node_t *node;
|
||||
|
||||
node = xmalloc_and_zero(sizeof(list_node_t));
|
||||
|
||||
return node;
|
||||
return (list_node_t *)xmalloc_and_zero(sizeof(list_node_t));
|
||||
}
|
||||
|
||||
void list_free_node(list_t *list, list_node_t *node)
|
||||
{
|
||||
if(node->data && list->delete)
|
||||
list->delete(node->data);
|
||||
|
||||
free(node);
|
||||
if(node->data && list->delete)
|
||||
list->delete(node->data);
|
||||
|
||||
free(node);
|
||||
}
|
||||
|
||||
/* Insertion and deletion */
|
||||
|
||||
list_node_t *list_insert_head(list_t *list, void *data)
|
||||
{
|
||||
list_node_t *node;
|
||||
|
||||
node = list_alloc_node();
|
||||
|
||||
node->data = data;
|
||||
node->prev = NULL;
|
||||
node->next = list->head;
|
||||
list->head = node;
|
||||
|
||||
if(node->next)
|
||||
node->next->prev = node;
|
||||
else
|
||||
list->tail = node;
|
||||
list_node_t *node;
|
||||
|
||||
list->count++;
|
||||
node = list_alloc_node();
|
||||
|
||||
return node;
|
||||
node->data = data;
|
||||
node->prev = NULL;
|
||||
node->next = list->head;
|
||||
list->head = node;
|
||||
|
||||
if(node->next)
|
||||
node->next->prev = node;
|
||||
else
|
||||
list->tail = node;
|
||||
|
||||
list->count++;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
list_node_t *list_insert_tail(list_t *list, void *data)
|
||||
{
|
||||
list_node_t *node;
|
||||
|
||||
node = list_alloc_node();
|
||||
|
||||
node->data = data;
|
||||
node->next = NULL;
|
||||
node->prev = list->tail;
|
||||
list->tail = node;
|
||||
|
||||
if(node->prev)
|
||||
node->prev->next = node;
|
||||
else
|
||||
list->head = node;
|
||||
list_node_t *node;
|
||||
|
||||
list->count++;
|
||||
|
||||
return node;
|
||||
node = list_alloc_node();
|
||||
|
||||
node->data = data;
|
||||
node->next = NULL;
|
||||
node->prev = list->tail;
|
||||
list->tail = node;
|
||||
|
||||
if(node->prev)
|
||||
node->prev->next = node;
|
||||
else
|
||||
list->head = node;
|
||||
|
||||
list->count++;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void list_unlink_node(list_t *list, list_node_t *node)
|
||||
{
|
||||
if(node->prev)
|
||||
node->prev->next = node->next;
|
||||
else
|
||||
list->head = node->next;
|
||||
|
||||
if(node->next)
|
||||
node->next->prev = node->prev;
|
||||
else
|
||||
list->tail = node->prev;
|
||||
if(node->prev)
|
||||
node->prev->next = node->next;
|
||||
else
|
||||
list->head = node->next;
|
||||
|
||||
list->count--;
|
||||
if(node->next)
|
||||
node->next->prev = node->prev;
|
||||
else
|
||||
list->tail = node->prev;
|
||||
|
||||
list->count--;
|
||||
}
|
||||
|
||||
void list_delete_node(list_t *list, list_node_t *node)
|
||||
{
|
||||
list_unlink_node(list, node);
|
||||
list_free_node(list, node);
|
||||
list_unlink_node(list, node);
|
||||
list_free_node(list, node);
|
||||
}
|
||||
|
||||
void list_delete_head(list_t *list)
|
||||
{
|
||||
list_delete_node(list, list->head);
|
||||
list_delete_node(list, list->head);
|
||||
}
|
||||
|
||||
void list_delete_tail(list_t *list)
|
||||
{
|
||||
list_delete_node(list, list->tail);
|
||||
list_delete_node(list, list->tail);
|
||||
}
|
||||
|
||||
/* Head/tail lookup */
|
||||
|
||||
void *list_get_head(list_t *list)
|
||||
{
|
||||
if(list->head)
|
||||
return list->head->data;
|
||||
else
|
||||
return NULL;
|
||||
if(list->head)
|
||||
return list->head->data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *list_get_tail(list_t *list)
|
||||
{
|
||||
if(list->tail)
|
||||
return list->tail->data;
|
||||
else
|
||||
return NULL;
|
||||
if(list->tail)
|
||||
return list->tail->data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Fast list deletion */
|
||||
|
||||
void list_delete_list(list_t *list)
|
||||
{
|
||||
list_node_t *node, *next;
|
||||
|
||||
for(node = list->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
list_free_node(list, node);
|
||||
}
|
||||
list_node_t *node, *next;
|
||||
|
||||
list_free(list);
|
||||
for(node = list->head; node; node = next) {
|
||||
next = node->next;
|
||||
list_free_node(list, node);
|
||||
}
|
||||
|
||||
list_free(list);
|
||||
}
|
||||
|
||||
/* Traversing */
|
||||
|
||||
void list_foreach_node(list_t *list, list_action_node_t action)
|
||||
{
|
||||
list_node_t *node, *next;
|
||||
list_node_t *node, *next;
|
||||
|
||||
for(node = list->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
action(node);
|
||||
}
|
||||
for(node = list->head; node; node = next) {
|
||||
next = node->next;
|
||||
action(node);
|
||||
}
|
||||
}
|
||||
|
||||
void list_foreach(list_t *list, list_action_t action)
|
||||
{
|
||||
list_node_t *node, *next;
|
||||
list_node_t *node, *next;
|
||||
|
||||
for(node = list->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
if(node->data)
|
||||
action(node->data);
|
||||
}
|
||||
for(node = list->head; node; node = next) {
|
||||
next = node->next;
|
||||
if(node->data)
|
||||
action(node->data);
|
||||
}
|
||||
}
|
||||
|
|
38
lib/list.h
38
lib/list.h
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
list.h -- header file for list.c
|
||||
Copyright (C) 2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000,2001 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 2000-2003 Ivo Timmermans <ivo@o2w.nl>
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -17,39 +17,37 @@
|
|||
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.2 2002/04/09 15:26:00 zarq Exp $
|
||||
$Id: list.h,v 1.3 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_LIST_H__
|
||||
#define __TINC_LIST_H__
|
||||
|
||||
typedef struct list_node_t
|
||||
{
|
||||
struct list_node_t *prev;
|
||||
struct list_node_t *next;
|
||||
typedef struct list_node_t {
|
||||
struct list_node_t *prev;
|
||||
struct list_node_t *next;
|
||||
|
||||
/* Payload */
|
||||
/* Payload */
|
||||
|
||||
void *data;
|
||||
void *data;
|
||||
} list_node_t;
|
||||
|
||||
typedef void (*list_action_t) (const void *);
|
||||
typedef void (*list_action_node_t) (const list_node_t *);
|
||||
typedef void (*list_action_t)(const void *);
|
||||
typedef void (*list_action_node_t)(const list_node_t *);
|
||||
|
||||
typedef struct list_t
|
||||
{
|
||||
list_node_t *head;
|
||||
list_node_t *tail;
|
||||
int count;
|
||||
typedef struct list_t {
|
||||
list_node_t *head;
|
||||
list_node_t *tail;
|
||||
int count;
|
||||
|
||||
/* Callbacks */
|
||||
/* Callbacks */
|
||||
|
||||
list_action_t delete;
|
||||
list_action_t delete;
|
||||
} list_t;
|
||||
|
||||
/* (De)constructors */
|
||||
|
||||
extern list_t *list_alloc(list_action_t);
|
||||
extern list_t *list_alloc(list_action_t) __attribute__ ((__malloc__));
|
||||
extern void list_free(list_t *);
|
||||
extern list_node_t *list_alloc_node(void);
|
||||
extern void list_free_node(list_t *, list_node_t *);
|
||||
|
@ -79,4 +77,4 @@ extern void list_delete_list(list_t *);
|
|||
extern void list_foreach(list_t *, list_action_t);
|
||||
extern void list_foreach_node(list_t *, list_action_node_t);
|
||||
|
||||
#endif /* __TINC_LIST_H__ */
|
||||
#endif /* __TINC_LIST_H__ */
|
||||
|
|
106
lib/logging.c
106
lib/logging.c
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
logging.c -- log messages to e.g. syslog
|
||||
Copyright (C) 2001-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2001-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
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: logging.c,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
avl_tree_t *log_hooks_tree = NULL;
|
||||
|
||||
int debug_lvl = 0;
|
||||
|
||||
int log_compare(const void *a, const void *b)
|
||||
{
|
||||
if(a < b)
|
||||
return -1;
|
||||
if(a > b)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void log(int level, int priority, char *fmt, ...)
|
||||
{
|
||||
avl_node_t *avlnode;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
for(avlnode = log_hooks_tree->head; avlnode; avlnode = avlnode->next)
|
||||
{
|
||||
assert(avlnode->data);
|
||||
((log_function_t*)(avlnode->data))(level, priority, fmt, args);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void log_add_hook(log_function_t *fn)
|
||||
{
|
||||
if(!log_hooks_tree)
|
||||
log_hooks_tree = avl_alloc_tree(log_compare, NULL);
|
||||
|
||||
avl_insert(log_hooks_tree, (void*)fn);
|
||||
}
|
||||
|
||||
void log_del_hook(log_function_t *fn)
|
||||
{
|
||||
avl_delete(log_hooks_tree, (void*)fn);
|
||||
}
|
||||
|
||||
void log_default(int level, int priority, char *fmt, va_list ap)
|
||||
{
|
||||
if(debug_lvl >= level)
|
||||
{
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void log_syslog(int level, int priority, char *fmt, va_list ap)
|
||||
{
|
||||
const int priorities[] = { LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_ERR, LOG_CRIT };
|
||||
|
||||
if(debug_lvl >= level)
|
||||
vsyslog(priorities[priority], fmt, ap);
|
||||
}
|
||||
|
||||
void tinc_syslog(int priority, char *fmt, ...)
|
||||
{
|
||||
/* Mapping syslog prio -> tinc prio */
|
||||
const int priorities[] = { TLOG_CRITICAL, TLOG_CRITICAL, TLOG_CRITICAL, TLOG_ERROR,
|
||||
TLOG_NOTICE, TLOG_NOTICE, TLOG_INFO, TLOG_DEBUG };
|
||||
avl_node_t *avlnode;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
for(avlnode = log_hooks_tree->head; avlnode; avlnode = avlnode->next)
|
||||
{
|
||||
assert(avlnode->data);
|
||||
((log_function_t*)(avlnode->data))(0, priorities[priority], fmt, args);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
logging.h -- header for logging.c
|
||||
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: logging.h,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_LOGGING_H__
|
||||
#define __TINC_LOGGING_H__
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
enum {
|
||||
TLOG_DEBUG,
|
||||
TLOG_INFO,
|
||||
TLOG_NOTICE,
|
||||
TLOG_ERROR,
|
||||
TLOG_CRITICAL
|
||||
};
|
||||
|
||||
enum {
|
||||
DEBUG_NOTHING = 0, /* Quiet mode, only show starting/stopping of the daemon */
|
||||
DEBUG_CONNECTIONS = 1, /* Show (dis)connects of other tinc daemons via TCP */
|
||||
DEBUG_ERROR = 2, /* Show error messages received from other hosts */
|
||||
DEBUG_STATUS = 2, /* Show status messages received from other hosts */
|
||||
DEBUG_PROTOCOL = 3, /* Show the requests that are sent/received */
|
||||
DEBUG_META = 4, /* Show contents of every request that is sent/received */
|
||||
DEBUG_TRAFFIC = 5, /* Show network traffic information */
|
||||
DEBUG_PACKET = 6, /* Show contents of each packet that is being sent/received */
|
||||
DEBUG_SCARY_THINGS = 10 /* You have been warned */
|
||||
};
|
||||
|
||||
typedef void (log_function_t)(int,int,char*,va_list);
|
||||
|
||||
extern int debug_lvl;
|
||||
extern avl_tree_t *log_hooks_tree;
|
||||
|
||||
extern void log(int, int, char *, ...);
|
||||
extern void log_add_hook(log_function_t *);
|
||||
extern void log_del_hook(log_function_t *);
|
||||
extern log_function_t log_default;
|
||||
extern log_function_t log_syslog;
|
||||
extern void tinc_syslog(int, char *, ...);
|
||||
|
||||
#ifndef LOG_ERR /* Something from syslog.h */
|
||||
# define syslog tinc_syslog
|
||||
#define LOG_EMERG 0 /* system is unusable */
|
||||
#define LOG_ALERT 1 /* action must be taken immediately */
|
||||
#define LOG_CRIT 2 /* critical conditions */
|
||||
#define LOG_ERR 3 /* error conditions */
|
||||
#define LOG_WARNING 4 /* warning conditions */
|
||||
#define LOG_NOTICE 5 /* normal but significant condition */
|
||||
#define LOG_INFO 6 /* informational */
|
||||
#define LOG_DEBUG 7 /* debug-level messages */
|
||||
#else
|
||||
# warning dont include syslog!
|
||||
#endif
|
||||
|
||||
#endif /* __TINC_LOGGING_H__ */
|
153
lib/net.h
153
lib/net.h
|
@ -1,153 +0,0 @@
|
|||
/*
|
||||
net.h -- header for net.c
|
||||
Copyright (C) 1998-2002 Ivo Timmermans <zarq@iname.com>
|
||||
2000-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
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: net.h,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_NET_H__
|
||||
#define __TINC_NET_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef ENABLE_JUMBOGRAMS
|
||||
#define MTU 9014 /* 9000 bytes payload + 14 bytes ethernet header */
|
||||
#define MAXSIZE 9100 /* MTU + header (seqno) and trailer (CBC padding and HMAC) */
|
||||
#define MAXBUFSIZE 9100 /* Must support TCP packets of length 9000. */
|
||||
#else
|
||||
#define MTU 1514 /* 1500 bytes payload + 14 bytes ethernet header */
|
||||
#define MAXSIZE 1600 /* MTU + header (seqno) and trailer (CBC padding and HMAC) */
|
||||
#define MAXBUFSIZE 2100 /* Quite large but needed for support of keys up to 8192 bits. */
|
||||
#endif
|
||||
|
||||
#define MAXSOCKETS 128 /* Overkill... */
|
||||
|
||||
#define MAXQUEUELENGTH 8 /* Maximum number of packats in a single queue */
|
||||
|
||||
typedef struct mac_t
|
||||
{
|
||||
unsigned char x[6];
|
||||
} mac_t;
|
||||
|
||||
typedef struct ipv4_t
|
||||
{
|
||||
unsigned char x[4];
|
||||
} ipv4_t;
|
||||
|
||||
typedef struct ip_mask_t {
|
||||
ipv4_t address;
|
||||
ipv4_t mask;
|
||||
} ip_mask_t;
|
||||
|
||||
typedef struct ipv6_t
|
||||
{
|
||||
unsigned short x[8];
|
||||
} ipv6_t;
|
||||
|
||||
typedef unsigned short port_t;
|
||||
|
||||
typedef short length_t;
|
||||
|
||||
typedef union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in in;
|
||||
struct sockaddr_in6 in6;
|
||||
} sockaddr_t;
|
||||
|
||||
#ifdef SA_LEN
|
||||
#define SALEN(s) SA_LEN(&s)
|
||||
#else
|
||||
#define SALEN(s) (s.sa_family==AF_INET?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6))
|
||||
#endif
|
||||
|
||||
typedef struct vpn_packet_t {
|
||||
length_t len; /* the actual number of bytes in the `data' field */
|
||||
int priority; /* priority or TOS */
|
||||
unsigned int seqno; /* 32 bits sequence number (network byte order of course) */
|
||||
unsigned char data[MAXSIZE];
|
||||
} vpn_packet_t;
|
||||
|
||||
typedef struct queue_element_t {
|
||||
void *packet;
|
||||
struct queue_element_t *prev;
|
||||
struct queue_element_t *next;
|
||||
} queue_element_t;
|
||||
|
||||
typedef struct packet_queue_t {
|
||||
queue_element_t *head;
|
||||
queue_element_t *tail;
|
||||
} packet_queue_t;
|
||||
|
||||
typedef struct outgoing_t {
|
||||
char *name;
|
||||
int timeout;
|
||||
struct config_t *cfg;
|
||||
struct addrinfo *ai;
|
||||
struct addrinfo *aip;
|
||||
} outgoing_t;
|
||||
|
||||
typedef struct listen_socket_t {
|
||||
int tcp;
|
||||
int udp;
|
||||
sockaddr_t sa;
|
||||
} listen_socket_t;
|
||||
|
||||
extern int maxtimeout;
|
||||
extern int seconds_till_retry;
|
||||
extern int addressfamily;
|
||||
|
||||
extern char *request_name[];
|
||||
extern char *status_text[];
|
||||
|
||||
#include "connection.h" /* Yes, very strange placement indeed, but otherwise the typedefs get all tangled up */
|
||||
|
||||
extern listen_socket_t listen_socket[MAXSOCKETS];
|
||||
extern int listen_sockets;
|
||||
extern int keyexpires;
|
||||
extern int keylifetime;
|
||||
extern int do_prune;
|
||||
extern int do_purge;
|
||||
extern char *myport;
|
||||
extern time_t now;
|
||||
|
||||
extern void retry_outgoing(outgoing_t *);
|
||||
extern void handle_incoming_vpn_data(int);
|
||||
extern void finish_connecting(connection_t *);
|
||||
extern void do_outgoing_connection(connection_t *);
|
||||
extern int handle_new_meta_connection(int);
|
||||
extern int setup_listen_socket(sockaddr_t *);
|
||||
extern int setup_vpn_in_socket(sockaddr_t *);
|
||||
extern void send_packet(struct node_t *, vpn_packet_t *);
|
||||
extern void receive_packet(struct node_t *, vpn_packet_t *);
|
||||
extern void receive_tcppacket(struct connection_t *, char *, int);
|
||||
extern void broadcast_packet(struct node_t *, vpn_packet_t *);
|
||||
extern int setup_network_connections(void);
|
||||
extern void setup_outgoing_connection(struct outgoing_t *);
|
||||
extern void try_outgoing_connections(void);
|
||||
extern void close_network_connections(void);
|
||||
extern void main_loop(void);
|
||||
extern void terminate_connection(connection_t *, int);
|
||||
extern void flush_queue(struct node_t *);
|
||||
extern int read_rsa_public_key(struct connection_t *);
|
||||
|
||||
#endif /* __TINC_NET_H__ */
|
247
lib/netutl.c
247
lib/netutl.c
|
@ -1,247 +0,0 @@
|
|||
/*
|
||||
netutl.c -- some supporting network utility code
|
||||
Copyright (C) 1998-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
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: netutl.c,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <utils.h>
|
||||
#include <xalloc.h>
|
||||
|
||||
#include "errno.h"
|
||||
#include "conf.h"
|
||||
#include "net.h"
|
||||
#include "netutl.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
int hostnames = 0;
|
||||
|
||||
/*
|
||||
Turn a string into a struct addrinfo.
|
||||
Return NULL on failure.
|
||||
*/
|
||||
struct addrinfo *str2addrinfo(char *address, char *service, int socktype)
|
||||
{
|
||||
struct addrinfo hint, *ai;
|
||||
int err;
|
||||
cp
|
||||
memset(&hint, 0, sizeof(hint));
|
||||
|
||||
hint.ai_family = addressfamily;
|
||||
hint.ai_socktype = socktype;
|
||||
|
||||
if((err = getaddrinfo(address, service, &hint, &ai)))
|
||||
{
|
||||
if(debug_lvl >= DEBUG_ERROR)
|
||||
syslog(LOG_WARNING, _("Error looking up %s port %s: %s\n"), address, service, gai_strerror(err));
|
||||
cp_trace();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cp
|
||||
return ai;
|
||||
}
|
||||
|
||||
sockaddr_t str2sockaddr(char *address, char *port)
|
||||
{
|
||||
struct addrinfo hint, *ai;
|
||||
sockaddr_t result;
|
||||
int err;
|
||||
cp
|
||||
memset(&hint, 0, sizeof(hint));
|
||||
|
||||
hint.ai_family = AF_UNSPEC;
|
||||
hint.ai_flags = AI_NUMERICHOST;
|
||||
hint.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if((err = getaddrinfo(address, port, &hint, &ai) || !ai))
|
||||
{
|
||||
syslog(LOG_ERR, _("Error looking up %s port %s: %s\n"), address, port, gai_strerror(err));
|
||||
cp_trace();
|
||||
raise(SIGFPE);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
result = *(sockaddr_t *)ai->ai_addr;
|
||||
freeaddrinfo(ai);
|
||||
cp
|
||||
return result;
|
||||
}
|
||||
|
||||
void sockaddr2str(sockaddr_t *sa, char **addrstr, char **portstr)
|
||||
{
|
||||
char address[NI_MAXHOST];
|
||||
char port[NI_MAXSERV];
|
||||
char *scopeid;
|
||||
int err;
|
||||
cp
|
||||
if((err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV)))
|
||||
{
|
||||
syslog(LOG_ERR, _("Error while translating addresses: %s"), gai_strerror(err));
|
||||
cp_trace();
|
||||
raise(SIGFPE);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINUX
|
||||
if((scopeid = strchr(address, '%')))
|
||||
*scopeid = '\0'; /* Descope. */
|
||||
#endif
|
||||
|
||||
*addrstr = xstrdup(address);
|
||||
*portstr = xstrdup(port);
|
||||
cp
|
||||
}
|
||||
|
||||
char *sockaddr2hostname(sockaddr_t *sa)
|
||||
{
|
||||
char *str;
|
||||
char address[NI_MAXHOST] = "unknown";
|
||||
char port[NI_MAXSERV] = "unknown";
|
||||
int err;
|
||||
cp
|
||||
if((err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), hostnames?0:(NI_NUMERICHOST|NI_NUMERICSERV))))
|
||||
{
|
||||
syslog(LOG_ERR, _("Error while looking up hostname: %s"), gai_strerror(err));
|
||||
}
|
||||
|
||||
asprintf(&str, _("%s port %s"), address, port);
|
||||
cp
|
||||
return str;
|
||||
}
|
||||
|
||||
int sockaddrcmp(sockaddr_t *a, sockaddr_t *b)
|
||||
{
|
||||
int result;
|
||||
cp
|
||||
result = a->sa.sa_family - b->sa.sa_family;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
switch(a->sa.sa_family)
|
||||
{
|
||||
case AF_UNSPEC:
|
||||
return 0;
|
||||
case AF_INET:
|
||||
result = memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr));
|
||||
if(result)
|
||||
return result;
|
||||
return memcmp(&a->in.sin_port, &b->in.sin_port, sizeof(a->in.sin_port));
|
||||
case AF_INET6:
|
||||
result = memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr));
|
||||
if(result)
|
||||
return result;
|
||||
return memcmp(&a->in6.sin6_port, &b->in6.sin6_port, sizeof(a->in6.sin6_port));
|
||||
default:
|
||||
syslog(LOG_ERR, _("sockaddrcmp() was called with unknown address family %d, exitting!"), a->sa.sa_family);
|
||||
cp_trace();
|
||||
raise(SIGFPE);
|
||||
exit(0);
|
||||
}
|
||||
cp
|
||||
}
|
||||
|
||||
void sockaddrunmap(sockaddr_t *sa)
|
||||
{
|
||||
if(sa->sa.sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sa->in6.sin6_addr))
|
||||
{
|
||||
sa->in.sin_addr.s_addr = ((uint32_t *)&sa->in6.sin6_addr)[3];
|
||||
sa->in.sin_family = AF_INET;
|
||||
}
|
||||
}
|
||||
|
||||
/* Subnet mask handling */
|
||||
|
||||
int maskcmp(char *a, char *b, int masklen, int len)
|
||||
{
|
||||
int i, m, result;
|
||||
cp
|
||||
for(m = masklen, i = 0; m >= 8; m -= 8, i++)
|
||||
if((result = a[i] - b[i]))
|
||||
return result;
|
||||
|
||||
if(m)
|
||||
return (a[i] & (0x100 - (1 << (8 - m)))) - (b[i] & (0x100 - (1 << (8 - m))));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mask(char *a, int masklen, int len)
|
||||
{
|
||||
int i;
|
||||
cp
|
||||
i = masklen / 8;
|
||||
masklen %= 8;
|
||||
|
||||
if(masklen)
|
||||
a[i++] &= (0x100 - (1 << masklen));
|
||||
|
||||
for(; i < len; i++)
|
||||
a[i] = 0;
|
||||
}
|
||||
|
||||
void maskcpy(char *a, char *b, int masklen, int len)
|
||||
{
|
||||
int i, m;
|
||||
cp
|
||||
for(m = masklen, i = 0; m >= 8; m -= 8, i++)
|
||||
a[i] = b[i];
|
||||
|
||||
if(m)
|
||||
{
|
||||
a[i] = b[i] & (0x100 - (1 << m));
|
||||
i++;
|
||||
}
|
||||
|
||||
for(; i < len; i++)
|
||||
a[i] = 0;
|
||||
}
|
||||
|
||||
int maskcheck(char *a, int masklen, int len)
|
||||
{
|
||||
int i;
|
||||
cp
|
||||
i = masklen / 8;
|
||||
masklen %= 8;
|
||||
|
||||
if(masklen)
|
||||
if(a[i++] & (char)~(0x100 - (1 << masklen)))
|
||||
return -1;
|
||||
|
||||
for(; i < len; i++)
|
||||
if(a[i] != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
188
lib/node.c
188
lib/node.c
|
@ -1,188 +0,0 @@
|
|||
/*
|
||||
node.c -- node tree management
|
||||
Copyright (C) 2001-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2001-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
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: node.c,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
#include "node.h"
|
||||
#include "netutl.h"
|
||||
#include "net.h"
|
||||
#include <utils.h>
|
||||
#include <xalloc.h>
|
||||
#include <hooks.h>
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
avl_tree_t *node_tree; /* Known nodes, sorted by name */
|
||||
avl_tree_t *node_udp_tree; /* Known nodes, sorted by address and port */
|
||||
|
||||
node_t *myself;
|
||||
|
||||
int node_compare(node_t *a, node_t *b)
|
||||
{
|
||||
return strcmp(a->name, b->name);
|
||||
}
|
||||
|
||||
int node_udp_compare(node_t *a, node_t *b)
|
||||
{
|
||||
int result;
|
||||
cp
|
||||
result = sockaddrcmp(&a->address, &b->address);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
return (a->name && b->name)?strcmp(a->name, b->name):0;
|
||||
}
|
||||
|
||||
void init_nodes(void)
|
||||
{
|
||||
cp
|
||||
node_tree = avl_alloc_tree((avl_compare_t)node_compare, NULL);
|
||||
node_udp_tree = avl_alloc_tree((avl_compare_t)node_udp_compare, NULL);
|
||||
cp
|
||||
}
|
||||
|
||||
void exit_nodes(void)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(node_tree);
|
||||
avl_delete_tree(node_udp_tree);
|
||||
cp
|
||||
}
|
||||
|
||||
node_t *new_node(void)
|
||||
{
|
||||
node_t *n = (node_t *)xmalloc_and_zero(sizeof(*n));
|
||||
cp
|
||||
n->subnet_tree = new_subnet_tree();
|
||||
n->edge_tree = new_edge_tree();
|
||||
n->queue = list_alloc((list_action_t)free);
|
||||
cp
|
||||
return n;
|
||||
}
|
||||
|
||||
void free_node(node_t *n)
|
||||
{
|
||||
cp
|
||||
if(n->queue)
|
||||
list_delete_list(n->queue);
|
||||
if(n->name)
|
||||
free(n->name);
|
||||
if(n->hostname)
|
||||
free(n->hostname);
|
||||
if(n->key)
|
||||
free(n->key);
|
||||
if(n->subnet_tree)
|
||||
free_subnet_tree(n->subnet_tree);
|
||||
if(n->edge_tree)
|
||||
free_edge_tree(n->edge_tree);
|
||||
free(n);
|
||||
cp
|
||||
}
|
||||
|
||||
void node_add(node_t *n)
|
||||
{
|
||||
cp
|
||||
avl_insert(node_tree, n);
|
||||
avl_insert(node_udp_tree, n);
|
||||
|
||||
run_hooks("node-add", n);
|
||||
cp
|
||||
}
|
||||
|
||||
void node_del(node_t *n)
|
||||
{
|
||||
avl_node_t *node, *next;
|
||||
edge_t *e;
|
||||
subnet_t *s;
|
||||
cp
|
||||
for(node = n->subnet_tree->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
s = (subnet_t *)node->data;
|
||||
subnet_del(n, s);
|
||||
}
|
||||
|
||||
for(node = n->subnet_tree->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
e = (edge_t *)node->data;
|
||||
edge_del(e);
|
||||
}
|
||||
cp
|
||||
avl_delete(node_tree, n);
|
||||
avl_delete(node_udp_tree, n);
|
||||
|
||||
run_hooks("node-del", n);
|
||||
cp
|
||||
}
|
||||
|
||||
node_t *lookup_node(char *name)
|
||||
{
|
||||
node_t n;
|
||||
cp
|
||||
n.name = name;
|
||||
return avl_search(node_tree, &n);
|
||||
}
|
||||
|
||||
node_t *lookup_node_udp(sockaddr_t *sa)
|
||||
{
|
||||
node_t n;
|
||||
cp
|
||||
n.address = *sa;
|
||||
n.name = NULL;
|
||||
|
||||
return avl_search(node_udp_tree, &n);
|
||||
}
|
||||
|
||||
void dump_nodes(void)
|
||||
{
|
||||
avl_node_t *node;
|
||||
node_t *n;
|
||||
cp
|
||||
log(0, TLOG_DEBUG,
|
||||
_("Nodes:"));
|
||||
|
||||
for(node = node_tree->head; node; node = node->next)
|
||||
{
|
||||
n = (node_t *)node->data;
|
||||
#ifdef USE_OPENSSL
|
||||
syslog(LOG_DEBUG, _(" %s at %s cipher %d digest %d maclength %d compression %d options %lx status %04x nexthop %s via %s"),
|
||||
n->name, n->hostname, n->cipher?n->cipher->nid:0, n->digest?n->digest->type:0, n->maclength, n->compression, n->options,
|
||||
n->status, n->nexthop?n->nexthop->name:"-", n->via?n->via->name:"-");
|
||||
#endif
|
||||
#ifdef USE_GCRYPT
|
||||
syslog(LOG_DEBUG, _(" %s at %s cipher %d digest %d maclength %d compression %d options %lx status %04x nexthop %s via %s"),
|
||||
n->name, n->hostname, n->cipher?-1:0, n->digest?-1:0, n->maclength, n->compression, n->options,
|
||||
n->status, n->nexthop?n->nexthop->name:"-", n->via?n->via->name:"-");
|
||||
#endif
|
||||
}
|
||||
|
||||
syslog(LOG_DEBUG, _("End of nodes."));
|
||||
cp
|
||||
}
|
106
lib/node.h
106
lib/node.h
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
node.h -- header for node.c
|
||||
Copyright (C) 2001-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2001-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
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: node.h,v 1.2 2002/05/02 11:50:07 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_NODE_H__
|
||||
#define __TINC_NODE_H__
|
||||
|
||||
#ifdef USE_GCRYPT
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
|
||||
#include <avl_tree.h>
|
||||
|
||||
#include "subnet.h"
|
||||
#include "connection.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 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 */
|
||||
int unused:26;
|
||||
} node_status_t;
|
||||
|
||||
typedef struct node_t {
|
||||
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 */
|
||||
char *hostname; /* the hostname of its real ip */
|
||||
|
||||
struct node_status_t status;
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
const EVP_CIPHER *cipher; /* Cipher type for UDP packets */
|
||||
#endif
|
||||
#ifdef USE_GCRYPT
|
||||
GCRY_CIPHER_HD cipher; /* Cipher type for UDP packets */
|
||||
#endif
|
||||
|
||||
char *key; /* Cipher key and iv */
|
||||
int keylength; /* Cipher key and iv length*/
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
const EVP_MD *digest; /* Digest type for MAC */
|
||||
#endif
|
||||
#ifdef USE_GCRYPT
|
||||
GCRY_MD_HD digest; /* Digest type for MAC */
|
||||
#endif
|
||||
|
||||
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 *via; /* next hop for UDP packets */
|
||||
|
||||
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 */
|
||||
|
||||
struct connection_t *connection; /* Connection associated with this node (if a direct connection exists) */
|
||||
|
||||
unsigned int sent_seqno; /* Sequence number last sent to this node */
|
||||
unsigned int received_seqno; /* Sequence number last received from this node */
|
||||
|
||||
void *data; /* Interface details */
|
||||
} node_t;
|
||||
|
||||
extern struct node_t *myself;
|
||||
extern avl_tree_t *node_tree;
|
||||
extern avl_tree_t *node_udp_tree;
|
||||
|
||||
extern void init_nodes(void);
|
||||
extern void exit_nodes(void);
|
||||
extern node_t *new_node(void);
|
||||
extern void free_node(node_t *);
|
||||
extern void node_add(node_t *);
|
||||
extern void node_del(node_t *);
|
||||
extern node_t *lookup_node(char *);
|
||||
extern node_t *lookup_node_udp(sockaddr_t *);
|
||||
extern void dump_nodes(void);
|
||||
|
||||
#endif /* __TINC_NODE_H__ */
|
|
@ -25,16 +25,9 @@
|
|||
* First version (v0.2) released
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include "system.h"
|
||||
|
||||
#ifndef HAVE_MINGW
|
||||
/* read_pid
|
||||
*
|
||||
* Reads the specified pidfile and returns the read pid.
|
||||
|
@ -135,4 +128,4 @@ int remove_pid (char *pidfile)
|
|||
{
|
||||
return unlink (pidfile);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_MINGW
|
||||
/* read_pid
|
||||
*
|
||||
* Reads the specified pidfile and returns the read pid.
|
||||
|
@ -48,3 +49,4 @@ int write_pid (char *pidfile);
|
|||
* is returned
|
||||
*/
|
||||
int remove_pid (char *pidfile);
|
||||
#endif
|
||||
|
|
596
lib/rbl.c
596
lib/rbl.c
|
@ -1,596 +0,0 @@
|
|||
/*
|
||||
rbl.c -- red-black tree + linked list convenience
|
||||
Copyright (C) 2000 Ivo Timmermans <itimmermans@bigfoot.com>,
|
||||
2000 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
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: rbl.c,v 1.2 2002/04/09 15:26:00 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <xalloc.h>
|
||||
|
||||
#include "rbl.h"
|
||||
#include <system.h>
|
||||
|
||||
/* Allocate a new rbl node */
|
||||
rbl_t *new_rbl()
|
||||
{
|
||||
return (rbl_t *)xmalloc_and_zero(sizeof(rbl_t));
|
||||
}
|
||||
|
||||
/* Free a rbl node */
|
||||
void free_rbl(rbl_t *rbl)
|
||||
{
|
||||
if(rbl->data && rbl->tree->delete)
|
||||
rbl->tree->delete(rbl->data);
|
||||
free(rbl);
|
||||
}
|
||||
|
||||
/* Allocate a new rbltree header */
|
||||
rbltree_t *new_rbltree(rbl_compare_t compare, rbl_action_t delete)
|
||||
{
|
||||
rbltree_t *tree;
|
||||
|
||||
tree = (rbltree_t *)xmalloc_and_zero(sizeof(rbltree_t));
|
||||
if(tree)
|
||||
{
|
||||
tree->compare = compare;
|
||||
tree->delete = delete;
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
/* Free a rbltree header */
|
||||
void free_rbltree(rbltree_t *tree)
|
||||
{
|
||||
free(tree);
|
||||
}
|
||||
|
||||
/* Search closest match in the tree */
|
||||
rbl_t *rbl_search_closest_rbl(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl, *next;
|
||||
int result;
|
||||
|
||||
next = rbl = tree->top;
|
||||
|
||||
while(next)
|
||||
{
|
||||
rbl = next;
|
||||
|
||||
result = tree->compare(data, rbl->data);
|
||||
|
||||
if(result < 0)
|
||||
next = rbl->left;
|
||||
else if(result > 0)
|
||||
next = rbl->right;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return rbl;
|
||||
}
|
||||
|
||||
/* Search closest match in the tree */
|
||||
rbl_t *rbl_search_closest_greater_rbl(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_closest_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
{
|
||||
if(tree->compare(data, rbl->data) > 0)
|
||||
rbl = rbl->next;
|
||||
}
|
||||
|
||||
return rbl;
|
||||
}
|
||||
|
||||
/* Search closest match in the tree */
|
||||
rbl_t *rbl_search_closest_smaller_rbl(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_closest_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
{
|
||||
if(tree->compare(data, rbl->data) < 0)
|
||||
rbl = rbl->next;
|
||||
}
|
||||
|
||||
return rbl;
|
||||
}
|
||||
|
||||
void *rbl_search_closest(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_closest_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
return rbl->data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *rbl_search_closest_greater(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_closest_greater_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
return rbl->data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *rbl_search_closest_smaller(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_closest_smaller_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
return rbl->data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Search exact match or return NULL pointer */
|
||||
rbl_t *rbl_search_rbl(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
int result;
|
||||
|
||||
rbl = tree->top;
|
||||
|
||||
while(rbl)
|
||||
{
|
||||
result = tree->compare(data, rbl->data);
|
||||
|
||||
if(result < 0)
|
||||
rbl = rbl->left;
|
||||
else if(result > 0)
|
||||
rbl = rbl->right;
|
||||
else
|
||||
return rbl;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *rbl_search(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
return rbl->data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Red-black tree operations taken from Introduction to Algorithms,
|
||||
Cormen, Leiserson & Rivest, chapter 14.
|
||||
*/
|
||||
|
||||
void rbl_left_rotate(rbl_t *x)
|
||||
{
|
||||
rbl_t *y;
|
||||
|
||||
y = x->right;
|
||||
x->right = y->left;
|
||||
|
||||
if(y->left)
|
||||
y->left->parent = x;
|
||||
|
||||
y->parent = x->parent;
|
||||
|
||||
if(!x->parent)
|
||||
x->tree->top = y;
|
||||
else
|
||||
if(x == x->parent->left)
|
||||
x->parent->left = y;
|
||||
else
|
||||
x->parent->right = y;
|
||||
|
||||
y->left = x;
|
||||
x->parent = y;
|
||||
}
|
||||
|
||||
void rbl_right_rotate(rbl_t *y)
|
||||
{
|
||||
rbl_t *x;
|
||||
|
||||
x = y->left;
|
||||
y->left = x->right;
|
||||
|
||||
if(x->right)
|
||||
x->right->parent = y;
|
||||
|
||||
x->parent = y->parent;
|
||||
|
||||
if(!y->parent)
|
||||
y->tree->top = x;
|
||||
else
|
||||
if(y == y->parent->right)
|
||||
y->parent->right = x;
|
||||
else
|
||||
y->parent->left = x;
|
||||
|
||||
x->right = y;
|
||||
y->parent = x;
|
||||
}
|
||||
|
||||
/* Insert a node into the rbl tree */
|
||||
rbl_t *rbl_insert_rbl(rbltree_t *tree, rbl_t *rbl)
|
||||
{
|
||||
rbl_t *closest, *x, *y;
|
||||
int result;
|
||||
|
||||
rbl->tree = tree;
|
||||
|
||||
/* Binary tree and linked list insert */
|
||||
|
||||
if(tree->top)
|
||||
{
|
||||
closest = rbl_search_closest_rbl(tree, rbl->data);
|
||||
result = tree->compare(rbl->data, closest->data);
|
||||
if(result < 0)
|
||||
{
|
||||
closest->left = rbl;
|
||||
|
||||
rbl->prev = closest->prev;
|
||||
rbl->next = closest;
|
||||
closest->prev = rbl;
|
||||
|
||||
if(rbl->prev)
|
||||
rbl->prev->next = rbl;
|
||||
else
|
||||
tree->head = rbl;
|
||||
}
|
||||
else if(result > 0)
|
||||
{
|
||||
closest->right = rbl;
|
||||
|
||||
rbl->next = closest->next;
|
||||
rbl->prev = closest;
|
||||
closest->next = rbl;
|
||||
|
||||
if(rbl->next)
|
||||
rbl->next->prev = rbl;
|
||||
else
|
||||
tree->tail = rbl;
|
||||
}
|
||||
else
|
||||
return closest; /* Ofcourse, we cannot add two identical things */
|
||||
|
||||
rbl->parent = closest;
|
||||
}
|
||||
else
|
||||
{
|
||||
tree->top = rbl;
|
||||
tree->head = rbl;
|
||||
tree->tail = rbl;
|
||||
}
|
||||
|
||||
/* Red-black part of insert */
|
||||
|
||||
x = rbl;
|
||||
x->color = RBL_RED;
|
||||
|
||||
while(x != tree->top && x->parent->color == RBL_RED)
|
||||
{
|
||||
if(x->parent == x->parent->parent->left)
|
||||
{
|
||||
y = x->parent->parent->right;
|
||||
if(y && y->color == RBL_RED)
|
||||
{
|
||||
x->parent->color = RBL_BLACK;
|
||||
y->color = RBL_BLACK;
|
||||
x->parent->parent->color = RBL_RED;
|
||||
x = x->parent->parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(x == x->parent->right)
|
||||
{
|
||||
x = x->parent;
|
||||
rbl_left_rotate(x);
|
||||
}
|
||||
x->parent->color = RBL_BLACK;
|
||||
x->parent->parent->color = RBL_RED;
|
||||
rbl_right_rotate(x->parent->parent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
y = x->parent->parent->left;
|
||||
if(y && y->color == RBL_RED)
|
||||
{
|
||||
x->parent->color = RBL_BLACK;
|
||||
y->color = RBL_BLACK;
|
||||
x->parent->parent->color = RBL_RED;
|
||||
x = x->parent->parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(x == x->parent->left)
|
||||
{
|
||||
x = x->parent;
|
||||
rbl_right_rotate(x);
|
||||
}
|
||||
x->parent->color = RBL_BLACK;
|
||||
x->parent->parent->color = RBL_RED;
|
||||
rbl_left_rotate(x->parent->parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tree->top->color = RBL_BLACK;
|
||||
return rbl;
|
||||
}
|
||||
|
||||
/* Create a new node and insert it into the tree */
|
||||
rbl_t *rbl_insert(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = new_rbl();
|
||||
rbl->data = data;
|
||||
|
||||
if(rbl_insert_rbl(tree, rbl) == rbl)
|
||||
return rbl;
|
||||
else
|
||||
{
|
||||
free_rbl(rbl);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore red-black property after violation due to a deletion */
|
||||
void rbl_delete_fixup(rbl_t *x)
|
||||
{
|
||||
rbl_t *w;
|
||||
|
||||
while(x != x->tree->top && x->color == RBL_BLACK)
|
||||
{
|
||||
if(x == x->parent->left)
|
||||
{
|
||||
w = x->parent->right;
|
||||
if(w->color == RBL_RED)
|
||||
{
|
||||
w->color = RBL_BLACK;
|
||||
x->parent->color = RBL_RED;
|
||||
rbl_left_rotate(x->parent);
|
||||
w = x->parent->right;
|
||||
}
|
||||
if(w->left->color == RBL_BLACK && w->right->color == RBL_BLACK)
|
||||
{
|
||||
w->color = RBL_RED;
|
||||
x = x->parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(w->right->color == RBL_BLACK)
|
||||
{
|
||||
w->left->color = RBL_BLACK;
|
||||
w->color = RBL_RED;
|
||||
rbl_right_rotate(w);
|
||||
w = x->parent->right;
|
||||
}
|
||||
w->color = x->parent->color;
|
||||
x->parent->color = RBL_BLACK;
|
||||
w->right->color = RBL_BLACK;
|
||||
rbl_left_rotate(x->parent);
|
||||
x = x->tree->top;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
w = x->parent->left;
|
||||
if(w->color == RBL_RED)
|
||||
{
|
||||
w->color = RBL_BLACK;
|
||||
x->parent->color = RBL_RED;
|
||||
rbl_right_rotate(x->parent);
|
||||
w = x->parent->left;
|
||||
}
|
||||
if(w->right->color == RBL_BLACK && w->left->color == RBL_BLACK)
|
||||
{
|
||||
w->color = RBL_RED;
|
||||
x = x->parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(w->left->color == RBL_BLACK)
|
||||
{
|
||||
w->right->color = RBL_BLACK;
|
||||
w->color = RBL_RED;
|
||||
rbl_left_rotate(w);
|
||||
w = x->parent->left;
|
||||
}
|
||||
w->color = x->parent->color;
|
||||
x->parent->color = RBL_BLACK;
|
||||
w->left->color = RBL_BLACK;
|
||||
rbl_right_rotate(x->parent);
|
||||
x = x->tree->top;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x->color = RBL_BLACK;
|
||||
}
|
||||
|
||||
/* Unlink node from the tree, but keep the node intact. */
|
||||
rbl_t *rbl_unlink_rbl(rbl_t *rbl)
|
||||
{
|
||||
rbl_t *x, *y;
|
||||
|
||||
/* Binary tree delete */
|
||||
|
||||
if(rbl->left && rbl->right)
|
||||
y = rbl->next;
|
||||
else
|
||||
y = rbl;
|
||||
|
||||
if(y->left)
|
||||
x = y->left;
|
||||
else
|
||||
x = y->right;
|
||||
|
||||
if(x)
|
||||
x->parent = y->parent;
|
||||
|
||||
if(!y->parent)
|
||||
rbl->tree->top = x;
|
||||
else
|
||||
if(y == y->parent->left)
|
||||
y->parent->left = x;
|
||||
else
|
||||
y->parent->right = x;
|
||||
|
||||
if(y != rbl)
|
||||
{
|
||||
y->left = rbl->left;
|
||||
y->right = rbl->right;
|
||||
y->parent = rbl->parent;
|
||||
if(rbl == rbl->parent->left)
|
||||
rbl->parent->left = y;
|
||||
else
|
||||
rbl->parent->right = y;
|
||||
}
|
||||
|
||||
/* Linked list delete */
|
||||
|
||||
if(rbl->prev)
|
||||
rbl->prev->next = rbl->next;
|
||||
else
|
||||
rbl->tree->head = rbl->next;
|
||||
|
||||
if(rbl->next)
|
||||
rbl->next->prev = rbl->prev;
|
||||
else
|
||||
rbl->tree->tail = rbl->prev;
|
||||
|
||||
/* Red-black part of delete */
|
||||
|
||||
if(y->color == RBL_BLACK && x)
|
||||
rbl_delete_fixup(x);
|
||||
|
||||
return rbl;
|
||||
}
|
||||
|
||||
/* Search node in tree and unlink it */
|
||||
rbl_t *rbl_unlink(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
rbl_unlink_rbl(rbl);
|
||||
|
||||
return rbl;
|
||||
}
|
||||
|
||||
/* Unlink node and free it */
|
||||
void rbl_delete_rbl(rbl_t *rbl)
|
||||
{
|
||||
rbl_unlink_rbl(rbl);
|
||||
free_rbl(rbl);
|
||||
}
|
||||
|
||||
/* Search node in tree, unlink and free it */
|
||||
void rbl_delete(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_unlink(tree, data);
|
||||
|
||||
if(rbl)
|
||||
free_rbl(rbl);
|
||||
}
|
||||
|
||||
/* Optimized unlinking for a complete tree */
|
||||
void rbl_unlink_rbltree(rbltree_t *tree)
|
||||
{
|
||||
rbl_t *rbl, *next;
|
||||
|
||||
for(rbl = tree->head; rbl; rbl = next)
|
||||
{
|
||||
next = rbl->next;
|
||||
rbl->tree = NULL;
|
||||
rbl->parent = NULL;
|
||||
rbl->left = NULL;
|
||||
rbl->right = NULL;
|
||||
rbl->prev = NULL;
|
||||
rbl->next = NULL;
|
||||
}
|
||||
|
||||
tree->top = NULL;
|
||||
tree->head = NULL;
|
||||
tree->tail = NULL;
|
||||
}
|
||||
|
||||
/* Optimized deletion for a complete tree */
|
||||
void rbl_delete_rbltree(rbltree_t *tree)
|
||||
{
|
||||
rbl_t *rbl, *next;
|
||||
|
||||
for(rbl = tree->head; rbl; rbl = next)
|
||||
{
|
||||
next = rbl->next;
|
||||
free_rbl(rbl);
|
||||
}
|
||||
|
||||
tree->top = NULL;
|
||||
tree->head = NULL;
|
||||
tree->tail = NULL;
|
||||
}
|
||||
|
||||
/* Do action for each list entry (in order)
|
||||
Deletion of entry for which action is called is allowed.
|
||||
*/
|
||||
void rbl_foreach(rbltree_t *tree, rbl_action_t action)
|
||||
{
|
||||
rbl_t *rbl, *next;
|
||||
|
||||
for(rbl = tree->head; rbl; rbl = next)
|
||||
{
|
||||
next = rbl->next;
|
||||
action(rbl->data);
|
||||
}
|
||||
}
|
||||
|
||||
void rbl_foreach_rbl(rbltree_t *tree, rbl_action_rbl_t action)
|
||||
{
|
||||
rbl_t *rbl, *next;
|
||||
|
||||
for(rbl = tree->head; rbl; rbl = next)
|
||||
{
|
||||
next = rbl->next;
|
||||
action(rbl);
|
||||
}
|
||||
}
|
104
lib/rbl.h
104
lib/rbl.h
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
rbl.h -- header file for rbl.c
|
||||
Copyright (C) 2000 Ivo Timmermans <itimmermans@bigfoot.com>,
|
||||
2000 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
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: rbl.h,v 1.2 2002/04/09 15:26:00 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __RBL_H__
|
||||
#define __RBL_H__
|
||||
|
||||
#define RBL_FOREACH(tree,rbl) for(rbl = tree->head; rbl; rbl = rbl->next)
|
||||
|
||||
typedef struct rbl_t
|
||||
{
|
||||
/* 'red-black tree' part */
|
||||
|
||||
struct rbltree_t *tree;
|
||||
|
||||
int color;
|
||||
|
||||
struct rbl_t *parent;
|
||||
struct rbl_t *left;
|
||||
struct rbl_t *right;
|
||||
|
||||
/* 'linked list' part */
|
||||
|
||||
struct rbl_t *prev;
|
||||
struct rbl_t *next;
|
||||
|
||||
/* payload */
|
||||
|
||||
void *data;
|
||||
|
||||
} rbl_t;
|
||||
|
||||
typedef int (*rbl_compare_t) (const void *, const void *);
|
||||
typedef void (*rbl_action_t) (const void *);
|
||||
typedef void (*rbl_action_rbl_t) (const struct rbl_t *);
|
||||
|
||||
typedef struct rbltree_t
|
||||
{
|
||||
/* callback functions */
|
||||
|
||||
rbl_compare_t compare;
|
||||
rbl_action_t delete;
|
||||
|
||||
/* tree part */
|
||||
|
||||
struct rbl_t *top;
|
||||
|
||||
/* linked list */
|
||||
|
||||
struct rbl_t *head;
|
||||
struct rbl_t *tail;
|
||||
|
||||
} rbltree_t;
|
||||
|
||||
enum color
|
||||
{
|
||||
RBL_RED,
|
||||
RBL_BLACK
|
||||
} color;
|
||||
|
||||
extern rbltree_t *new_rbltree(rbl_compare_t, rbl_action_t);
|
||||
extern void free_rbltree(rbltree_t *);
|
||||
extern rbl_t *new_rbl(void);
|
||||
extern void free_rbl(rbl_t *);
|
||||
|
||||
extern void *rbl_search(rbltree_t *, void *);
|
||||
extern void *rbl_search_closest(rbltree_t *, void *);
|
||||
extern void *rbl_search_closest_greater(rbltree_t *, void *);
|
||||
extern void *rbl_search_closest_smaller(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_search_rbl(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_search_closest_rbl(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_search_closest_greater_rbl(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_search_closest_smaller_rbl(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_insert(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_unlink(rbltree_t *, void *);
|
||||
extern void rbl_delete(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_insert_rbl(rbltree_t *, rbl_t *);
|
||||
extern rbl_t *rbl_unlink_rbl(rbl_t *);
|
||||
extern void rbl_delete_rbl(rbl_t *);
|
||||
extern void rbl_unlink_rbltree(rbltree_t *);
|
||||
extern void rbl_delete_rbltree(rbltree_t *);
|
||||
|
||||
extern void rbl_foreach(rbltree_t *, rbl_action_t);
|
||||
extern void rbl_foreach_rbl(rbltree_t *, rbl_action_rbl_t);
|
||||
|
||||
#endif /* __RBL_H__ */
|
399
lib/subnet.c
399
lib/subnet.c
|
@ -1,399 +0,0 @@
|
|||
/*
|
||||
subnet.c -- handle subnet lookups and lists
|
||||
Copyright (C) 2000-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2000-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
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: subnet.c,v 1.1 2002/04/28 12:46:26 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <hooks.h>
|
||||
#include <utils.h>
|
||||
#include <xalloc.h>
|
||||
#include <avl_tree.h>
|
||||
|
||||
#include "conf.h"
|
||||
#include "net.h"
|
||||
#include "node.h"
|
||||
#include "subnet.h"
|
||||
#include "netutl.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
/* lists type of subnet */
|
||||
|
||||
avl_tree_t *subnet_tree;
|
||||
|
||||
/* Subnet comparison */
|
||||
|
||||
int subnet_compare_mac(subnet_t *a, subnet_t *b)
|
||||
{
|
||||
cp
|
||||
return memcmp(&a->net.mac.address, &b->net.mac.address, sizeof(mac_t));
|
||||
}
|
||||
|
||||
int subnet_compare_ipv4(subnet_t *a, subnet_t *b)
|
||||
{
|
||||
int result;
|
||||
cp
|
||||
result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t));
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
return a->net.ipv4.prefixlength - b->net.ipv4.prefixlength;
|
||||
}
|
||||
|
||||
int subnet_compare_ipv6(subnet_t *a, subnet_t *b)
|
||||
{
|
||||
int result;
|
||||
cp
|
||||
result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t));
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
return a->net.ipv6.prefixlength - b->net.ipv6.prefixlength;
|
||||
}
|
||||
|
||||
int subnet_compare(subnet_t *a, subnet_t *b)
|
||||
{
|
||||
int result;
|
||||
cp
|
||||
result = a->type - b->type;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
switch(a->type)
|
||||
{
|
||||
case SUBNET_MAC:
|
||||
return subnet_compare_mac(a, b);
|
||||
case SUBNET_IPV4:
|
||||
return subnet_compare_ipv4(a, b);
|
||||
case SUBNET_IPV6:
|
||||
return subnet_compare_ipv6(a, b);
|
||||
default:
|
||||
syslog(LOG_ERR, _("subnet_compare() was called with unknown subnet type %d, exitting!"), a->type);
|
||||
cp_trace();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialising trees */
|
||||
|
||||
void init_subnets(void)
|
||||
{
|
||||
cp
|
||||
subnet_tree = avl_alloc_tree((avl_compare_t)subnet_compare, (avl_action_t)free_subnet);
|
||||
cp
|
||||
}
|
||||
|
||||
void exit_subnets(void)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(subnet_tree);
|
||||
cp
|
||||
}
|
||||
|
||||
avl_tree_t *new_subnet_tree(void)
|
||||
{
|
||||
cp
|
||||
return avl_alloc_tree((avl_compare_t)subnet_compare, NULL);
|
||||
cp
|
||||
}
|
||||
|
||||
void free_subnet_tree(avl_tree_t *subnet_tree)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(subnet_tree);
|
||||
cp
|
||||
}
|
||||
|
||||
/* Allocating and freeing space for subnets */
|
||||
|
||||
subnet_t *new_subnet(void)
|
||||
{
|
||||
cp
|
||||
return (subnet_t *)xmalloc(sizeof(subnet_t));
|
||||
}
|
||||
|
||||
void free_subnet(subnet_t *subnet)
|
||||
{
|
||||
cp
|
||||
free(subnet);
|
||||
}
|
||||
|
||||
/* Adding and removing subnets */
|
||||
|
||||
void subnet_add(node_t *n, subnet_t *subnet)
|
||||
{
|
||||
cp
|
||||
subnet->owner = n;
|
||||
|
||||
avl_insert(subnet_tree, subnet);
|
||||
cp
|
||||
avl_insert(n->subnet_tree, subnet);
|
||||
|
||||
run_hooks("subnet-add", subnet);
|
||||
cp
|
||||
}
|
||||
|
||||
void subnet_del(node_t *n, subnet_t *subnet)
|
||||
{
|
||||
cp
|
||||
avl_delete(n->subnet_tree, subnet);
|
||||
cp
|
||||
avl_delete(subnet_tree, subnet);
|
||||
|
||||
run_hooks("subnet-del", subnet);
|
||||
cp
|
||||
}
|
||||
|
||||
/* Ascii representation of subnets */
|
||||
|
||||
subnet_t *str2net(char *subnetstr)
|
||||
{
|
||||
int i, l;
|
||||
subnet_t *subnet;
|
||||
unsigned short int x[8];
|
||||
cp
|
||||
subnet = new_subnet();
|
||||
cp
|
||||
if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d",
|
||||
&x[0], &x[1], &x[2], &x[3],
|
||||
&l) == 5)
|
||||
{
|
||||
subnet->type = SUBNET_IPV4;
|
||||
subnet->net.ipv4.prefixlength = l;
|
||||
for(i = 0; i < 4; i++)
|
||||
subnet->net.ipv4.address.x[i] = x[i];
|
||||
return subnet;
|
||||
}
|
||||
|
||||
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d",
|
||||
&x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
|
||||
&l) == 9)
|
||||
{
|
||||
subnet->type = SUBNET_IPV6;
|
||||
subnet->net.ipv6.prefixlength = l;
|
||||
for(i = 0; i < 8; i++)
|
||||
subnet->net.ipv6.address.x[i] = htons(x[i]);
|
||||
return subnet;
|
||||
}
|
||||
|
||||
if(sscanf(subnetstr, "%hu.%hu.%hu.%hu",
|
||||
&x[0], &x[1], &x[2], &x[3]) == 4)
|
||||
{
|
||||
subnet->type = SUBNET_IPV4;
|
||||
subnet->net.ipv4.prefixlength = 32;
|
||||
for(i = 0; i < 4; i++)
|
||||
subnet->net.ipv4.address.x[i] = x[i];
|
||||
return subnet;
|
||||
}
|
||||
|
||||
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
|
||||
&x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7]) == 8)
|
||||
{
|
||||
subnet->type = SUBNET_IPV6;
|
||||
subnet->net.ipv6.prefixlength = 128;
|
||||
for(i = 0; i < 8; i++)
|
||||
subnet->net.ipv6.address.x[i] = htons(x[i]);
|
||||
return subnet;
|
||||
}
|
||||
|
||||
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx",
|
||||
&x[0], &x[1], &x[2], &x[3], &x[4], &x[5]) == 6)
|
||||
{
|
||||
subnet->type = SUBNET_MAC;
|
||||
for(i = 0; i < 6; i++)
|
||||
subnet->net.mac.address.x[i] = x[i];
|
||||
return subnet;
|
||||
}
|
||||
|
||||
free(subnet);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *net2str(subnet_t *subnet)
|
||||
{
|
||||
char *netstr;
|
||||
cp
|
||||
switch(subnet->type)
|
||||
{
|
||||
case SUBNET_MAC:
|
||||
asprintf(&netstr, "%hx:%hx:%hx:%hx:%hx:%hx",
|
||||
subnet->net.mac.address.x[0],
|
||||
subnet->net.mac.address.x[1],
|
||||
subnet->net.mac.address.x[2],
|
||||
subnet->net.mac.address.x[3],
|
||||
subnet->net.mac.address.x[4],
|
||||
subnet->net.mac.address.x[5]);
|
||||
break;
|
||||
case SUBNET_IPV4:
|
||||
asprintf(&netstr, "%hu.%hu.%hu.%hu/%d",
|
||||
subnet->net.ipv4.address.x[0],
|
||||
subnet->net.ipv4.address.x[1],
|
||||
subnet->net.ipv4.address.x[2],
|
||||
subnet->net.ipv4.address.x[3],
|
||||
subnet->net.ipv4.prefixlength);
|
||||
break;
|
||||
case SUBNET_IPV6:
|
||||
asprintf(&netstr, "%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]),
|
||||
ntohs(subnet->net.ipv6.address.x[3]),
|
||||
ntohs(subnet->net.ipv6.address.x[4]),
|
||||
ntohs(subnet->net.ipv6.address.x[5]),
|
||||
ntohs(subnet->net.ipv6.address.x[6]),
|
||||
ntohs(subnet->net.ipv6.address.x[7]),
|
||||
subnet->net.ipv6.prefixlength);
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_ERR, _("net2str() was called with unknown subnet type %d, exitting!"), subnet->type);
|
||||
cp_trace();
|
||||
exit(0);
|
||||
}
|
||||
cp
|
||||
return netstr;
|
||||
}
|
||||
|
||||
/* Subnet lookup routines */
|
||||
|
||||
subnet_t *lookup_subnet(node_t *owner, subnet_t *subnet)
|
||||
{
|
||||
cp
|
||||
return avl_search(owner->subnet_tree, subnet);
|
||||
}
|
||||
|
||||
subnet_t *lookup_subnet_mac(mac_t *address)
|
||||
{
|
||||
subnet_t subnet, *p;
|
||||
cp
|
||||
subnet.type = SUBNET_MAC;
|
||||
memcpy(&subnet.net.mac.address, address, sizeof(mac_t));
|
||||
|
||||
p = (subnet_t *)avl_search(subnet_tree, &subnet);
|
||||
cp
|
||||
return p;
|
||||
}
|
||||
|
||||
subnet_t *lookup_subnet_ipv4(ipv4_t *address)
|
||||
{
|
||||
subnet_t subnet, *p;
|
||||
cp
|
||||
subnet.type = SUBNET_IPV4;
|
||||
memcpy(&subnet.net.ipv4.address, address, sizeof(ipv4_t));
|
||||
subnet.net.ipv4.prefixlength = 32;
|
||||
|
||||
do
|
||||
{
|
||||
/* Go find subnet */
|
||||
|
||||
p = (subnet_t *)avl_search_closest_smaller(subnet_tree, &subnet);
|
||||
|
||||
/* Check if the found subnet REALLY matches */
|
||||
cp
|
||||
if(p)
|
||||
{
|
||||
if(p->type != SUBNET_IPV4)
|
||||
{
|
||||
p = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!maskcmp((char *)address, (char *)&p->net.ipv4.address, p->net.ipv4.prefixlength, sizeof(ipv4_t)))
|
||||
break;
|
||||
else
|
||||
{
|
||||
/* Otherwise, see if there is a bigger enclosing subnet */
|
||||
|
||||
subnet.net.ipv4.prefixlength = p->net.ipv4.prefixlength - 1;
|
||||
maskcpy((char *)&subnet.net.ipv4.address, (char *)&p->net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(ipv4_t));
|
||||
}
|
||||
}
|
||||
} while (p);
|
||||
cp
|
||||
return p;
|
||||
}
|
||||
|
||||
subnet_t *lookup_subnet_ipv6(ipv6_t *address)
|
||||
{
|
||||
subnet_t subnet, *p;
|
||||
cp
|
||||
subnet.type = SUBNET_IPV6;
|
||||
memcpy(&subnet.net.ipv6.address, address, sizeof(ipv6_t));
|
||||
subnet.net.ipv6.prefixlength = 128;
|
||||
|
||||
do
|
||||
{
|
||||
/* Go find subnet */
|
||||
|
||||
p = (subnet_t *)avl_search_closest_smaller(subnet_tree, &subnet);
|
||||
|
||||
/* Check if the found subnet REALLY matches */
|
||||
|
||||
cp
|
||||
if(p)
|
||||
{
|
||||
if(p->type != SUBNET_IPV6)
|
||||
return NULL;
|
||||
|
||||
if (!maskcmp((char *)address, (char *)&p->net.ipv6.address, p->net.ipv6.prefixlength, sizeof(ipv6_t)))
|
||||
break;
|
||||
else
|
||||
{
|
||||
/* Otherwise, see if there is a bigger enclosing subnet */
|
||||
|
||||
subnet.net.ipv6.prefixlength = p->net.ipv6.prefixlength - 1;
|
||||
maskcpy((char *)&subnet.net.ipv6.address, (char *)&p->net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(ipv6_t));
|
||||
}
|
||||
}
|
||||
} while (p);
|
||||
cp
|
||||
return p;
|
||||
}
|
||||
|
||||
void dump_subnets(void)
|
||||
{
|
||||
char *netstr;
|
||||
subnet_t *subnet;
|
||||
avl_node_t *node;
|
||||
cp
|
||||
syslog(LOG_DEBUG, _("Subnet list:"));
|
||||
for(node = subnet_tree->head; node; node = node->next)
|
||||
{
|
||||
subnet = (subnet_t *)node->data;
|
||||
netstr = net2str(subnet);
|
||||
syslog(LOG_DEBUG, _(" %s owner %s"), netstr, subnet->owner->name);
|
||||
free(netstr);
|
||||
}
|
||||
syslog(LOG_DEBUG, _("End of subnet list."));
|
||||
cp
|
||||
}
|
90
lib/subnet.h
90
lib/subnet.h
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
subnet.h -- header for subnet.c
|
||||
Copyright (C) 2000,2001 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
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: subnet.h,v 1.1 2002/04/28 12:46:26 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_SUBNET_H__
|
||||
#define __TINC_SUBNET_H__
|
||||
|
||||
#include "net.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SUBNET_MAC = 0,
|
||||
SUBNET_IPV4,
|
||||
SUBNET_IPV6,
|
||||
SUBNET_TYPES /* Guardian */
|
||||
};
|
||||
|
||||
typedef struct subnet_mac_t
|
||||
{
|
||||
mac_t address;
|
||||
time_t lastseen;
|
||||
} subnet_mac_t;
|
||||
|
||||
typedef struct subnet_ipv4_t
|
||||
{
|
||||
ipv4_t address;
|
||||
int prefixlength;
|
||||
} subnet_ipv4_t;
|
||||
|
||||
typedef struct subnet_ipv6_t
|
||||
{
|
||||
ipv6_t address;
|
||||
int prefixlength;
|
||||
} subnet_ipv6_t;
|
||||
|
||||
#include "node.h"
|
||||
|
||||
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 */
|
||||
|
||||
int type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */
|
||||
|
||||
/* And now for the actual subnet: */
|
||||
|
||||
union net
|
||||
{
|
||||
subnet_mac_t mac;
|
||||
subnet_ipv4_t ipv4;
|
||||
subnet_ipv6_t ipv6;
|
||||
} net;
|
||||
|
||||
void *data; /* Interface details */
|
||||
} subnet_t;
|
||||
|
||||
extern subnet_t *new_subnet(void);
|
||||
extern void free_subnet(subnet_t *);
|
||||
extern void init_subnets(void);
|
||||
extern void exit_subnets(void);
|
||||
extern avl_tree_t *new_subnet_tree(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(subnet_t *);
|
||||
extern subnet_t *str2net(char *);
|
||||
extern subnet_t *lookup_subnet(struct node_t *, subnet_t *);
|
||||
extern subnet_t *lookup_subnet_mac(mac_t *);
|
||||
extern subnet_t *lookup_subnet_ipv4(ipv4_t *);
|
||||
extern subnet_t *lookup_subnet_ipv6(ipv6_t *);
|
||||
extern void dump_subnets(void);
|
||||
|
||||
#endif /* __TINC_SUBNET_H__ */
|
97
lib/utils.c
97
lib/utils.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
utils.c -- gathering of some stupid small functions
|
||||
Copyright (C) 1999-2001 Ivo Timmermans <zarq@iname.com>
|
||||
2000,2001 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 1999-2003 Ivo Timmermans <zarq@iname.com>
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -18,15 +18,10 @@
|
|||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "system.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <utils.h>
|
||||
#include <syslog.h>
|
||||
#include <xalloc.h>
|
||||
#include "../src/logger.h"
|
||||
#include "utils.h"
|
||||
|
||||
#ifdef ENABLE_TRACING
|
||||
volatile int (cp_line[]) = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
@ -38,50 +33,70 @@ char *hexadecimals = "0123456789ABCDEF";
|
|||
|
||||
int charhex2bin(char c)
|
||||
{
|
||||
if(isdigit(c))
|
||||
return c - '0';
|
||||
else
|
||||
return toupper(c) - 'A' + 10;
|
||||
if(isdigit(c))
|
||||
return c - '0';
|
||||
else
|
||||
return toupper(c) - 'A' + 10;
|
||||
}
|
||||
|
||||
|
||||
void hex2bin(char *src, char *dst, int length)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<length; i++)
|
||||
dst[i] = charhex2bin(src[i*2])*16 + charhex2bin(src[i*2+1]);
|
||||
int i;
|
||||
for(i = 0; i < length; i++)
|
||||
dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]);
|
||||
}
|
||||
|
||||
void bin2hex(char *src, char *dst, int length)
|
||||
{
|
||||
int i;
|
||||
for(i=length-1; i>=0; i--)
|
||||
{
|
||||
dst[i*2+1] = hexadecimals[(unsigned char)src[i] & 15];
|
||||
dst[i*2] = hexadecimals[(unsigned char)src[i]>>4];
|
||||
}
|
||||
int i;
|
||||
for(i = length - 1; i >= 0; i--) {
|
||||
dst[i * 2 + 1] = hexadecimals[(unsigned char) src[i] & 15];
|
||||
dst[i * 2] = hexadecimals[(unsigned char) src[i] >> 4];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_TRACING
|
||||
void cp_trace()
|
||||
{
|
||||
syslog(LOG_DEBUG, "Checkpoint trace: %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d...",
|
||||
cp_file[(cp_index+15)%16], cp_line[(cp_index+15)%16],
|
||||
cp_file[(cp_index+14)%16], cp_line[(cp_index+14)%16],
|
||||
cp_file[(cp_index+13)%16], cp_line[(cp_index+13)%16],
|
||||
cp_file[(cp_index+12)%16], cp_line[(cp_index+12)%16],
|
||||
cp_file[(cp_index+11)%16], cp_line[(cp_index+11)%16],
|
||||
cp_file[(cp_index+10)%16], cp_line[(cp_index+10)%16],
|
||||
cp_file[(cp_index+9)%16], cp_line[(cp_index+9)%16],
|
||||
cp_file[(cp_index+8)%16], cp_line[(cp_index+8)%16],
|
||||
cp_file[(cp_index+7)%16], cp_line[(cp_index+7)%16],
|
||||
cp_file[(cp_index+6)%16], cp_line[(cp_index+6)%16],
|
||||
cp_file[(cp_index+5)%16], cp_line[(cp_index+5)%16],
|
||||
cp_file[(cp_index+4)%16], cp_line[(cp_index+4)%16],
|
||||
cp_file[(cp_index+3)%16], cp_line[(cp_index+3)%16],
|
||||
cp_file[(cp_index+2)%16], cp_line[(cp_index+2)%16],
|
||||
cp_file[(cp_index+1)%16], cp_line[(cp_index+1)%16],
|
||||
cp_file[cp_index], cp_line[cp_index]
|
||||
);
|
||||
logger(LOG_DEBUG, "Checkpoint trace: %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d...",
|
||||
cp_file[(cp_index + 15) % 16], cp_line[(cp_index + 15) % 16],
|
||||
cp_file[(cp_index + 14) % 16], cp_line[(cp_index + 14) % 16],
|
||||
cp_file[(cp_index + 13) % 16], cp_line[(cp_index + 13) % 16],
|
||||
cp_file[(cp_index + 12) % 16], cp_line[(cp_index + 12) % 16],
|
||||
cp_file[(cp_index + 11) % 16], cp_line[(cp_index + 11) % 16],
|
||||
cp_file[(cp_index + 10) % 16], cp_line[(cp_index + 10) % 16],
|
||||
cp_file[(cp_index + 9) % 16], cp_line[(cp_index + 9) % 16],
|
||||
cp_file[(cp_index + 8) % 16], cp_line[(cp_index + 8) % 16],
|
||||
cp_file[(cp_index + 7) % 16], cp_line[(cp_index + 7) % 16],
|
||||
cp_file[(cp_index + 6) % 16], cp_line[(cp_index + 6) % 16],
|
||||
cp_file[(cp_index + 5) % 16], cp_line[(cp_index + 5) % 16],
|
||||
cp_file[(cp_index + 4) % 16], cp_line[(cp_index + 4) % 16],
|
||||
cp_file[(cp_index + 3) % 16], cp_line[(cp_index + 3) % 16],
|
||||
cp_file[(cp_index + 2) % 16], cp_line[(cp_index + 2) % 16],
|
||||
cp_file[(cp_index + 1) % 16], cp_line[(cp_index + 1) % 16],
|
||||
cp_file[cp_index], cp_line[cp_index]
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_MINGW) || defined(HAVE_CYGWIN)
|
||||
#ifdef HAVE_CYGWIN
|
||||
#include <w32api/windows.h>
|
||||
#endif
|
||||
|
||||
char *winerror(int err) {
|
||||
static char buf[1024], *newline;
|
||||
|
||||
if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, sizeof(buf), NULL)) {
|
||||
strncpy(buf, _("(unable to format errormessage)"), sizeof(buf));
|
||||
};
|
||||
|
||||
if((newline = strchr(buf, '\r')))
|
||||
*newline = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
25
lib/utils.h
25
lib/utils.h
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
utils.h -- header file for utils.c
|
||||
Copyright (C) 1999-2002 Ivo Timmermans <ivo@o2w.nl>
|
||||
2000-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 1999-2003 Ivo Timmermans <zarq@iname.com>
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,25 +21,26 @@
|
|||
#ifndef __TINC_UTILS_H__
|
||||
#define __TINC_UTILS_H__
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#define min(a,b) (((a)<(b))?(a):(b))
|
||||
|
||||
#ifdef ENABLE_TRACING
|
||||
extern volatile int cp_line[];
|
||||
extern volatile char *cp_file[];
|
||||
extern volatile int cp_index;
|
||||
extern void cp_trace(void);
|
||||
|
||||
#define cp { cp_line[cp_index] = __LINE__; cp_file[cp_index] = __FILE__; cp_index++; cp_index %= 16; }
|
||||
#define ecp { fprintf(stderr, "Explicit checkpoint in %s line %d\n", __FILE__, __LINE__); }
|
||||
#define cp() { cp_line[cp_index] = __LINE__; cp_file[cp_index] = __FILE__; cp_index++; cp_index %= 16; }
|
||||
#define ecp() { fprintf(stderr, "Explicit checkpoint in %s line %d\n", __FILE__, __LINE__); }
|
||||
#else
|
||||
#define cp
|
||||
#define ecp
|
||||
#define cp_trace()
|
||||
#define cp()
|
||||
#define ecp()
|
||||
#define cp_trace()
|
||||
#endif
|
||||
|
||||
extern void hex2bin(char *src, char *dst, int length);
|
||||
extern void bin2hex(char *src, char *dst, int length);
|
||||
|
||||
#endif /* __TINC_UTILS_H__ */
|
||||
#ifdef HAVE_MINGW
|
||||
extern char *winerror(int);
|
||||
#define strerror(x) ((x)>0?strerror(x):winerror(GetLastError()))
|
||||
#endif
|
||||
|
||||
#endif /* __TINC_UTILS_H__ */
|
||||
|
|
|
@ -18,9 +18,9 @@ extern char *const xalloc_msg_memory_exhausted;
|
|||
/* FIXME: describe */
|
||||
extern void (*xalloc_fail_func) ();
|
||||
|
||||
void *xmalloc PARAMS ((size_t n));
|
||||
void *xmalloc_and_zero PARAMS ((size_t n));
|
||||
void *xmalloc PARAMS ((size_t n)) __attribute__ ((__malloc__));
|
||||
void *xmalloc_and_zero PARAMS ((size_t n)) __attribute__ ((__malloc__));
|
||||
void *xcalloc PARAMS ((size_t n, size_t s));
|
||||
void *xrealloc PARAMS ((void *p, size_t n));
|
||||
void *xrealloc PARAMS ((void *p, size_t n)) __attribute__ ((__malloc__));
|
||||
|
||||
char *xstrdup PARAMS ((const char *s));
|
||||
char *xstrdup PARAMS ((const char *s)) __attribute__ ((__malloc__));
|
||||
|
|
|
@ -32,15 +32,7 @@ void *realloc ();
|
|||
void free ();
|
||||
#endif
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(Text) gettext (Text)
|
||||
#else
|
||||
# define textdomain(Domain)
|
||||
# define _(Text) Text
|
||||
#endif
|
||||
#define N_(Text) Text
|
||||
|
||||
#include "gettext.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
#ifndef EXIT_FAILURE
|
||||
|
|
25
m4/attribute.m4
Normal file
25
m4/attribute.m4
Normal file
|
@ -0,0 +1,25 @@
|
|||
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_CACHE_CHECK([for working $1 attribute], tinc_cv_attribute_$1,
|
||||
[
|
||||
tempcflags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Wall -Werror"
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_SOURCE(
|
||||
[void test(void) __attribute__ (($1));
|
||||
void test(void) { return; }
|
||||
],
|
||||
)],
|
||||
[tinc_cv_attribute_$1=yes],
|
||||
[tinc_cv_attribute_$1=no]
|
||||
)
|
||||
CFLAGS="$tempcflags"
|
||||
])
|
||||
|
||||
if test ${tinc_cv_attribute_$1} = no; then
|
||||
AC_DEFINE([$1], [], [Defined if the $1 attribute is not supported.])
|
||||
fi
|
||||
])
|
39
m4/lzo.m4
Normal file
39
m4/lzo.m4
Normal file
|
@ -0,0 +1,39 @@
|
|||
dnl Check to find the lzo headers/libraries
|
||||
|
||||
AC_DEFUN(tinc_LZO,
|
||||
[
|
||||
tinc_ac_save_CPPFLAGS="$CPPFLAGS"
|
||||
|
||||
AC_ARG_WITH(lzo,
|
||||
AC_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"]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(lzo-include,
|
||||
AC_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]),
|
||||
[lzo_lib="$withval"
|
||||
LIBS="$LIBS -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.")]
|
||||
)
|
||||
])
|
|
@ -20,8 +20,7 @@ AC_DEFUN(jm_FUNC_MALLOC,
|
|||
fi
|
||||
dnl xmalloc.c requires that this symbol be defined so it doesn't
|
||||
dnl mistakenly use a broken malloc -- as it might if this test were omitted.
|
||||
ac_kludge=HAVE_DONE_WORKING_MALLOC_CHECK
|
||||
AC_DEFINE_UNQUOTED($ac_kludge)
|
||||
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([
|
||||
|
@ -38,7 +37,8 @@ AC_DEFUN(jm_FUNC_MALLOC,
|
|||
jm_cv_func_working_malloc=no)
|
||||
])
|
||||
if test $jm_cv_func_working_malloc = no; then
|
||||
LIBOBJS="$LIBOBJS malloc.o"
|
||||
AC_DEFINE_UNQUOTED(malloc, rpl_malloc)
|
||||
dnl This was: LIBOBJS="$LIBOBJS malloc.$ac_objext"
|
||||
AC_LIBOBJ([malloc])
|
||||
AC_DEFINE(malloc, rpl_malloc, [Replacement malloc()])
|
||||
fi
|
||||
])
|
||||
|
|
|
@ -4,48 +4,63 @@ AC_DEFUN(tinc_OPENSSL,
|
|||
[
|
||||
tinc_ac_save_CPPFLAGS="$CPPFLAGS"
|
||||
|
||||
AC_ARG_WITH(openssl,
|
||||
AC_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"]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(openssl-include,
|
||||
[ --with-openssl-include=DIR OpenSSL headers directory (without trailing /openssl)],
|
||||
AC_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,
|
||||
[ --with-openssl-lib=DIR OpenSSL library directory],
|
||||
AC_HELP_STRING([--with-openssl-lib=DIR], [OpenSSL library directory]),
|
||||
[openssl_lib="$withval"
|
||||
LIBS="$LIBS -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]
|
||||
[AC_MSG_ERROR([OpenSSL header files not found.]); break]
|
||||
)
|
||||
|
||||
CPPFLAGS="$tinc_ac_save_CPPFLAGS"
|
||||
|
||||
AC_CHECK_LIB(crypto, SHA1_version,
|
||||
[LIBS="$LIBS -lcrypto"],
|
||||
[AC_MSG_ERROR("OpenSSL libraries not found.")]
|
||||
)
|
||||
|
||||
AC_CHECK_FUNCS(RAND_pseudo_bytes)
|
||||
|
||||
AC_CHECK_FUNC(OpenSSL_add_all_algorithms,
|
||||
[],
|
||||
AC_CHECK_FUNC(SSLeay_add_all_algorithms,
|
||||
[AC_DEFINE(HAVE_SSLEAY_ADD_ALL_ALGORITHMS)],
|
||||
[AC_MSG_ERROR("Missing required OpenSSL functionality!")]
|
||||
case $host_os in
|
||||
*mingw*)
|
||||
AC_CHECK_LIB(crypto, SHA1_version,
|
||||
[LIBS="$LIBS -lcrypto -lgdi32"],
|
||||
[AC_MSG_ERROR([OpenSSL libraries not found.])]
|
||||
)
|
||||
)
|
||||
|
||||
AC_CHECK_FUNC(dlopen,
|
||||
[],
|
||||
AC_CHECK_LIB(dl, dlopen,
|
||||
[LIBS="$LIBS -ldl"],
|
||||
[AC_MSG_ERROR("OpenSSL depends on libdl.")]
|
||||
;;
|
||||
*)
|
||||
AC_CHECK_LIB(crypto, SHA1_version,
|
||||
[LIBS="$LIBS -lcrypto"],
|
||||
[AC_MSG_ERROR([OpenSSL libraries not found.])]
|
||||
)
|
||||
|
||||
AC_CHECK_FUNC(dlopen,
|
||||
[],
|
||||
[AC_CHECK_LIB(dl, dlopen,
|
||||
[LIBS="$LIBS -ldl"],
|
||||
[AC_MSG_ERROR([OpenSSL depends on libdl.]); break]
|
||||
)]
|
||||
)
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_CHECK_FUNCS([RAND_pseudo_bytes EVP_EncryptInit_ex], ,
|
||||
[AC_MSG_ERROR([Missing OpenSSL functionality, make sure you have installed the latest version.]); break],
|
||||
)
|
||||
|
||||
found_openssl=1
|
||||
AC_CHECK_DECL([OpenSSL_add_all_algorithms], ,
|
||||
[AC_MSG_ERROR([Missing OpenSSL functionality, make sure you have installed the latest version.]); break],
|
||||
[#include <openssl/evp.h>]
|
||||
)
|
||||
])
|
||||
|
|
39
m4/perl.m4
39
m4/perl.m4
|
@ -1,39 +0,0 @@
|
|||
#serial 1
|
||||
|
||||
dnl From Jim Meyering.
|
||||
dnl Find a new-enough version of Perl.
|
||||
dnl
|
||||
|
||||
AC_DEFUN(jm_PERL,
|
||||
[
|
||||
dnl FIXME: don't hard-code 5.003
|
||||
dnl FIXME: should we cache the result?
|
||||
AC_MSG_CHECKING([for perl5.003 or newer])
|
||||
if test "${PERL+set}" = set; then
|
||||
# `PERL' is set in the user's environment.
|
||||
candidate_perl_names="$PERL"
|
||||
perl_specified=yes
|
||||
else
|
||||
candidate_perl_names='perl perl5'
|
||||
perl_specified=no
|
||||
fi
|
||||
|
||||
found=no
|
||||
AC_SUBST(PERL)
|
||||
PERL="$missing_dir/missing perl"
|
||||
for perl in $candidate_perl_names; do
|
||||
# Run test in a subshell; some versions of sh will print an error if
|
||||
# an executable is not found, even if stderr is redirected.
|
||||
if ( $perl -e 'require 5.003' ) > /dev/null 2>&1; then
|
||||
PERL=$perl
|
||||
found=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
AC_MSG_RESULT($found)
|
||||
test $found = no && AC_MSG_WARN([
|
||||
*** You don't seem to have perl5.003 or newer installed.
|
||||
*** Because of that, you may be unable to regenerate certain files
|
||||
*** if you modify the sources from which they are derived.] )
|
||||
])
|
|
@ -20,8 +20,7 @@ AC_DEFUN(jm_FUNC_REALLOC,
|
|||
fi
|
||||
dnl xmalloc.c requires that this symbol be defined so it doesn't
|
||||
dnl mistakenly use a broken realloc -- as it might if this test were omitted.
|
||||
ac_kludge=HAVE_DONE_WORKING_REALLOC_CHECK
|
||||
AC_DEFINE_UNQUOTED($ac_kludge)
|
||||
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([
|
||||
|
@ -38,7 +37,8 @@ AC_DEFUN(jm_FUNC_REALLOC,
|
|||
jm_cv_func_working_realloc=no)
|
||||
])
|
||||
if test $jm_cv_func_working_realloc = no; then
|
||||
LIBOBJS="$LIBOBJS realloc.o"
|
||||
AC_DEFINE_UNQUOTED(realloc, rpl_realloc)
|
||||
dnl This was: LIBOBJS="$LIBOBJS realloc.$ac_objext"
|
||||
AC_LIBOBJ([realloc])
|
||||
AC_DEFINE(realloc, rpl_realloc, [Replacement realloc()])
|
||||
fi
|
||||
])
|
||||
|
|
63
m4/tuntap.m4
63
m4/tuntap.m4
|
@ -2,38 +2,37 @@ dnl Check to find out whether the running kernel has support for TUN/TAP
|
|||
|
||||
AC_DEFUN(tinc_TUNTAP,
|
||||
[
|
||||
AC_ARG_WITH(kernel,
|
||||
[ --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_ARG_WITH(kernel,
|
||||
AC_HELP_STRING([--with-kernel=DIR], [give the directory with kernel sources (default: /usr/src/linux)]),
|
||||
kerneldir="$withval",
|
||||
kerneldir="/usr/src/linux"
|
||||
)
|
||||
|
||||
if test $if_tun_h = no; then
|
||||
tinc_cv_linux_if_tun_h=none
|
||||
else
|
||||
tinc_cv_linux_if_tun_h="$if_tun_h"
|
||||
|
||||
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"
|
||||
)]
|
||||
)
|
||||
|
||||
if test $if_tun_h = no; then
|
||||
tinc_cv_linux_if_tun_h=none
|
||||
else
|
||||
tinc_cv_linux_if_tun_h="$if_tun_h"
|
||||
fi
|
||||
])
|
||||
|
||||
if test $tinc_cv_linux_if_tun_h != none; then
|
||||
AC_DEFINE(HAVE_TUNTAP, 1, [Universal tun/tap driver present])
|
||||
if test $tinc_cv_linux_if_tun_h != default; then
|
||||
AC_DEFINE_UNQUOTED(LINUX_IF_TUN_H, $tinc_cv_linux_if_tun_h, [Location of if_tun.h])
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
if test $tinc_cv_linux_if_tun_h != none; then
|
||||
AC_DEFINE(HAVE_TUNTAP)
|
||||
if test $tinc_cv_linux_if_tun_h != default; then
|
||||
AC_DEFINE_UNQUOTED(LINUX_IF_TUN_H, $tinc_cv_linux_if_tun_h)
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(LINUX_IF_TUN_H)
|
||||
AC_SUBST(HAVE_TUNTAP)
|
||||
AC_SUBST(LINUX_IF_TUN_H)
|
||||
AC_SUBST(HAVE_TUNTAP)
|
||||
])
|
||||
|
|
12
m4/zlib.m4
12
m4/zlib.m4
|
@ -4,15 +4,23 @@ AC_DEFUN(tinc_ZLIB,
|
|||
[
|
||||
tinc_ac_save_CPPFLAGS="$CPPFLAGS"
|
||||
|
||||
AC_ARG_WITH(zlib,
|
||||
AC_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"]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(zlib-include,
|
||||
[ --with-zlib-include=DIR zlib headers directory],
|
||||
AC_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,
|
||||
[ --with-zlib-lib=DIR zlib library directory],
|
||||
AC_HELP_STRING([--with-zlib-lib=DIR], [zlib library directory]),
|
||||
[zlib_lib="$withval"
|
||||
LIBS="$LIBS -L$withval"]
|
||||
)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Makefile Makefile.in
|
|
@ -1 +0,0 @@
|
|||
EXTRA_DIST = tinc tinc.spec
|
|
@ -1,14 +0,0 @@
|
|||
To make tinc RPMs:
|
||||
|
||||
copy tinc-???.tar.gz to /usr/src/redhat/SOURCES/ and run
|
||||
|
||||
rpm -ba tinc.spec
|
||||
|
||||
- and tinc.spec can be found in this directory.
|
||||
|
||||
The rpm's will be placed in /usr/src/redhat/RPMS/i386 (e.g.).
|
||||
|
||||
|
||||
Happy Hacking!
|
||||
|
||||
Mads Kiilerich <mads@kiilerich.com>
|
337
redhat/tinc
337
redhat/tinc
|
@ -1,337 +0,0 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# tinc tincd VPN setup script
|
||||
#
|
||||
# chkconfig: 2345 46 54
|
||||
#
|
||||
# version: 1.0.8
|
||||
# authors: Lubomir Bulej <pallas@kadan.cz>
|
||||
# Mads Kiilerich <mads@kiilerich.com>
|
||||
#
|
||||
# description: This script parses tinc configuration files for networks given \
|
||||
# in /etc/tinc/nets.boot and for each of the networks it sets up \
|
||||
# the interface and static routes and starts the tinc daemon.
|
||||
#
|
||||
# processname: tincd
|
||||
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
# Source networking configuration.
|
||||
. /etc/sysconfig/network
|
||||
|
||||
# Check that networking is up.
|
||||
[ ${NETWORKING} = "no" ] && exit 0
|
||||
|
||||
#############################################################################
|
||||
# configuration & sanity checks
|
||||
|
||||
TINCD=/usr/sbin/tincd
|
||||
TCONF=/etc/tinc
|
||||
TPIDS=/var/run
|
||||
#DEBUG=-dddd
|
||||
|
||||
NETSFILE=$TCONF/nets.boot
|
||||
|
||||
# Check the daemon
|
||||
if [ ! -x $TINCD ]; then
|
||||
echo "**tinc: $TINCD does not exist or is not executable!" >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
# Check if ip-route is installed
|
||||
if [ ! -f /sbin/ip ]; then
|
||||
echo "**tinc: ip-route utilities not installed!" >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
# Check the kernel
|
||||
if ! ip addr &> /dev/null; then
|
||||
echo "**tinc: kernel not configured for use with ip-route!" >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
# Check the configuration directory
|
||||
if [ ! -d $TCONF ]; then
|
||||
echo "**tinc: configuration directory ($TCONF) not found!" >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
# Check nets.boot
|
||||
if [ ! -f $NETSFILE ]; then
|
||||
echo "**tinc: file with list of VPNs to start ($NETSFILE) not found!" >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
# Load names of networks to be started
|
||||
NETS="$(sed -e 's/#.*//; s/[[:space:]]//g; /^$/ d' $NETSFILE)"
|
||||
|
||||
|
||||
##############################################################################
|
||||
# prefix_to_mask Converts prefix length to netmask
|
||||
# eg. 17 -> 255.255.128.0
|
||||
# $1 ... prefix
|
||||
|
||||
prefix_to_mask () {
|
||||
_MSK=""; _len="$1"
|
||||
for _dot in "." "." "." " "; do
|
||||
if [ ${_len} -ge 8 ]; then
|
||||
_fld=8
|
||||
else
|
||||
_fld="${_len}"
|
||||
fi
|
||||
|
||||
_MSK="${_MSK}$((255 & (255 << (8 - _fld))))${_dot}"
|
||||
_len=$((_len - _fld))
|
||||
done
|
||||
|
||||
echo ${_MSK}
|
||||
}
|
||||
|
||||
|
||||
##############################################################################
|
||||
# mask_to_prefix Converts netmask to prefix length
|
||||
# eg. 255.255.192.0 -> 18
|
||||
# $1 ... netmask
|
||||
|
||||
mask_to_prefix () {
|
||||
_LEN=0; _msk="$1"
|
||||
for _tmp in 1 2 3 4; do
|
||||
_fld=${_msk%%.*}
|
||||
_msk=${_msk#*.}
|
||||
|
||||
while [ ${_fld} -ne 0 ]; do
|
||||
_fld=$(((_fld << 1) & 255))
|
||||
_LEN=$((_LEN + 1))
|
||||
done
|
||||
done
|
||||
|
||||
echo ${_LEN}
|
||||
}
|
||||
|
||||
|
||||
##############################################################################
|
||||
# vpn_load () Loads VPN configuration
|
||||
#
|
||||
# $1 ... VPN to load
|
||||
|
||||
vpn_load () {
|
||||
CFG="$TCONF/$1/tinc.conf"
|
||||
[ -f $CFG ] || { MSG="$CFG does not exist!"; return 1; }
|
||||
|
||||
# load TINCD config
|
||||
DEV="$(grep -i -e '^[[:space:]]*TapDevice' $CFG | sed 's/[[:space:]]//g; s/^.*=//g')"
|
||||
VPN="$(grep -i -e '^[[:space:]]*(MyOwnVPNIP|MyVirtualIP)' -E $CFG | sed 's/[[:space:]]//g; s/^.*=//g')"
|
||||
IFM="$(grep -i -e '^[[:space:]]*VPNMask' $CFG | sed 's/[[:space:]]//g; s/^.*=//g')"
|
||||
|
||||
# TapDevice syntax validation
|
||||
[ -z "$DEV" ] && \
|
||||
{ MSG="TapDevice required!"; return 1; }
|
||||
[ $(echo $DEV | wc -l) -gt 1 ] && \
|
||||
{ MSG="multiple TapDevice entries not allowed!"; return 1; }
|
||||
echo $DEV | grep -q -x -E '/dev/tap[[:digit:]]+' ||
|
||||
{ MSG="TapDevice should be in form /dev/tapX!"; return 1; }
|
||||
|
||||
# MyOwnVPNIP/MyVirtualIP syntax validation
|
||||
[ -z "$VPN" ] && \
|
||||
{ MSG="MyOwnVPNIP/MyVirtualIP required!"; return 1; }
|
||||
[ $(echo $VPN | wc -l) -gt 1 ] && \
|
||||
{ MSG="multiple MyOwnVPNIP/MyVirtualIP entries not allowed!"; return 1; }
|
||||
echo $VPN | grep -q -x -E \
|
||||
'([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}/[[:digit:]]{1,2}' || \
|
||||
{ MSG="badly formed MyOwnVPNIP/MyVirtualIP address $VPN!"; return 1; }
|
||||
|
||||
# VPNMask syntax validation
|
||||
[ $(echo $IFM | wc -l) -gt 1 ] && \
|
||||
{ MSG="multiple VPNMask entries not allowed!"; return 1; }
|
||||
|
||||
|
||||
# device & IP address extraction
|
||||
TAP=${DEV##*/}
|
||||
NUM=${TAP#tap}
|
||||
ADR=${VPN%%/*}
|
||||
|
||||
# netmask is calculated from MyVirtualIP netmask prefix length, except when
|
||||
# VPNMask is specified, in which case it is used instead of default prefix
|
||||
|
||||
# VPNMask not specified
|
||||
if [ -z "$IFM" ]; then
|
||||
LEN=${VPN##*/}
|
||||
MSK=$(prefix_to_mask $LEN)
|
||||
|
||||
# VPNMask is prefix length, convert it to netmask for MSK
|
||||
elif echo $IFM | grep -q -x -E '[[:digit:]]{1,2}'; then
|
||||
VPN="$ADR/$IFM"
|
||||
MSK=$(prefix_to_mask $IFM)
|
||||
|
||||
# VPNMask is netmask, convert it to prefix length for VPN
|
||||
elif echo $IFM | grep -q -x -E '([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}'; then
|
||||
VPN="$ADR/$(mask_to_prefix $IFM)"
|
||||
MSK="$IFM"
|
||||
|
||||
else
|
||||
MSG="badly formed interface netmask (VPNMask=$IFM)!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
# Network & broadcast addresses
|
||||
BRD=$(ipcalc --broadcast $ADR $MSK | cut -d"=" -f2)
|
||||
NET=$(ipcalc --network $ADR $MSK | cut -d"=" -f2)
|
||||
|
||||
# MAC address
|
||||
MAC=$(printf "fe:fd:%0.2x:%0.2x:%0.2x:%0.2x" $(echo $ADR | { IFS=. ; read a b c d; echo $a $b $c $d; }))
|
||||
|
||||
# debugging
|
||||
# echo >&2
|
||||
# echo "VPN $VPN TAP $TAP NUM $NUM MAC $MAC IFM $IFM" >&2
|
||||
# echo "ADR $ADR MSK $MSK NET $NET BRD $BRD" >&2
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
##############################################################################
|
||||
# vpn_start () starts specified VPN
|
||||
#
|
||||
# $1 ... VPN to start
|
||||
|
||||
vpn_start () {
|
||||
MSG=""; ERR=""
|
||||
vpn_load $1 || return 1
|
||||
|
||||
# create device file
|
||||
if [ ! -c $DEV ]; then
|
||||
[ -e $DEV ] && rm -f $DEV
|
||||
mknod --mode=0600 $DEV c 36 $((16 + NUM))
|
||||
fi
|
||||
|
||||
# load device module
|
||||
ERR="$(insmod ethertap -o "ethertap$NUM" unit="$NUM" 2>&1 1> /dev/null)" ||
|
||||
{ MSG="could not insmod ethertap as unit $NUM!"; return 2; }
|
||||
|
||||
# configure the interface
|
||||
ERR="$(ip link set $TAP address $MAC 2>&1)" ||
|
||||
{ MSG="could not set address for device $TAP!"; return 3; }
|
||||
|
||||
ERR="$(ip link set $TAP up 2>&1)" ||
|
||||
{ MSG="could not bring up device $TAP!"; return 3; }
|
||||
|
||||
ERR="$(ip addr add $VPN brd $BRD dev $TAP 2>&1)" ||
|
||||
{ MSG="could not set IP address for device $TAP!"; return 3; }
|
||||
|
||||
# start tincd
|
||||
$TINCD --net="$1" $DEBUG || \
|
||||
{ MSG="could not start daemon for network $1"; return 3; }
|
||||
|
||||
# setup custom static routes
|
||||
/etc/sysconfig/network-scripts/ifup-routes $TAP
|
||||
|
||||
return 0
|
||||
} # vpn_start
|
||||
|
||||
|
||||
##############################################################################
|
||||
# vpn_stop () Stops specified VPN
|
||||
#
|
||||
# $1 ... VPN to stop
|
||||
|
||||
vpn_stop () {
|
||||
MSG=""; ERR=""
|
||||
vpn_load $1 || return 1
|
||||
|
||||
# kill the tincd daemon
|
||||
PID="$TPIDS/tinc.$1.pid"
|
||||
if [ -f $PID ]; then
|
||||
$TINCD --net="$1" --kill &> /dev/null
|
||||
RET=$?
|
||||
|
||||
if [ $RET -eq 0 ]; then
|
||||
dly=0
|
||||
while [ $dly -le 5 ]; do
|
||||
[ -f $PID ] || break
|
||||
sleep 1; dly=$((dly + 1))
|
||||
done
|
||||
fi
|
||||
|
||||
# remove stale PID file
|
||||
[ -f $PID ] && rm -f $PID
|
||||
fi
|
||||
|
||||
# bring the interface down
|
||||
ip addr flush dev $TAP &> /dev/null
|
||||
ip link set $TAP down &> /dev/null
|
||||
|
||||
# remove ethertap module
|
||||
rmmod "ethertap$NUM" &> /dev/null
|
||||
|
||||
return 0
|
||||
} # vpn_stop
|
||||
|
||||
|
||||
# Check if there is anything to start
|
||||
if [ ! -z "$1" -a "$1" != "status" -a -z "$NETS" ]; then
|
||||
echo "**tinc: no networks found in $NETSFILE!" >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start)
|
||||
for vpn in $NETS; do
|
||||
echo -n "Bringing up TINC network $vpn: "
|
||||
vpn_start $vpn && \
|
||||
success "startup of network $vpn" || \
|
||||
failure "startup of network $vpn"
|
||||
echo
|
||||
|
||||
if [ ! -z "$MSG" ]; then
|
||||
[ ! -z "$ERR" ] && echo "$ERR" >&2
|
||||
echo "**tinc: $MSG" >&2
|
||||
fi
|
||||
done
|
||||
|
||||
touch /var/lock/subsys/tinc
|
||||
;;
|
||||
|
||||
stop)
|
||||
for vpn in $NETS; do
|
||||
echo -n "Shutting down TINC network $vpn: "
|
||||
vpn_stop $vpn && \
|
||||
success "shutdown of network $vpn" || \
|
||||
failure "shutdown of network $vpn"
|
||||
echo
|
||||
|
||||
if [ ! -z "$MSG" ]; then
|
||||
[ ! -z "$ERR" ] && echo "$ERR" >&2
|
||||
echo "**tinc: $MSG" >&2
|
||||
fi
|
||||
done
|
||||
|
||||
rm -f /var/lock/subsys/tinc
|
||||
;;
|
||||
|
||||
status)
|
||||
echo -n "Configured VPNs: "
|
||||
for vpn in $NETS; do
|
||||
PID="$TPIDS/tinc.$vpn.pid"
|
||||
|
||||
[ -f $PID ] && PID="$(cat $PID)" || PID="-dead-"
|
||||
ps ax | grep "^[[:space:]]*$PID" && STS="OK" || STS="DEAD"
|
||||
echo -n "$vpn:$STS "
|
||||
done
|
||||
echo
|
||||
;;
|
||||
|
||||
restart)
|
||||
$0 stop
|
||||
$0 start
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: tinc {start|stop|status|restart}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit 0
|
113
redhat/tinc.spec
113
redhat/tinc.spec
|
@ -1,113 +0,0 @@
|
|||
Summary: tinc Virtual Private Network daemon
|
||||
Name: tinc
|
||||
Version: 1.0pre3
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: System Environment/Daemons
|
||||
URL: http://tinc.nl.linux.org/
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
Buildroot: /var/tmp/%{name}-%{version}-%{release}
|
||||
Requires: iproute
|
||||
# for building the package the following is required:
|
||||
# /usr/bin/texi2html /usr/bin/patch
|
||||
|
||||
%description
|
||||
# taken from doc/tinc.texi
|
||||
tinc is a Virtual Private Network (VPN) daemon that uses tunneling and
|
||||
encryption to create a secure private network between hosts on the
|
||||
Internet.
|
||||
|
||||
Because the tunnel appears to the IP level network code as a normal
|
||||
network device, there is no need to adapt any existing software.
|
||||
|
||||
This tunneling allows VPN sites to share information with each other
|
||||
over the Internet without exposing any information to others.
|
||||
|
||||
See http://tinc.nl.linux.org/
|
||||
|
||||
%prep
|
||||
|
||||
%setup -q -n %{name}-%{version}
|
||||
|
||||
%build
|
||||
./configure --prefix=/usr --sysconfdir=/etc
|
||||
make
|
||||
/usr/bin/texi2html doc/tinc.texi
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make install DESTDIR=$RPM_BUILD_ROOT
|
||||
gzip $RPM_BUILD_ROOT/usr/info/tinc.info
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d/
|
||||
cp redhat/tinc $RPM_BUILD_ROOT/etc/rc.d/init.d/
|
||||
|
||||
ME=my.vpn.ip.number
|
||||
PEER=peer.vpn.ip.number
|
||||
PEEREAL=peer.real.ip.number
|
||||
|
||||
umask 077
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/tinc/$PEER/passphrases
|
||||
cat <<END >$RPM_BUILD_ROOT/etc/tinc/$PEER/tinc.conf
|
||||
# Sample tinc configuration.
|
||||
# Insert your own ip numbers instead of the placeholders,
|
||||
# and be sure to use your own passphrases.
|
||||
# See man tinc.conf(5) tincd(8) genauth(8), info tinc and
|
||||
# /usr/doc/%{name}-%{version}/tinc.conf.sample
|
||||
TapDevice = /dev/tap0
|
||||
ConnectTo = $PEEREAL
|
||||
MyVirtualIP = $ME/32
|
||||
AllowConnect = no
|
||||
END
|
||||
cat <<END >$RPM_BUILD_ROOT/etc/tinc/$PEER/passphrases/local
|
||||
1024 c1da5b633b428d783fec96ac89bb6bd4ed97ac673942706ba2240cde977158b7cd5f4055b7db70a7365d1f8df6a1a7c9dbb73f4e2bf8484fc14aee68d0f950e2bce82dd2a6386f040546a61e77cd1c25265ce03182e4e2c9a00ae0ea2f1f89ac04a10f7b67312187b5d2d74618803974ba6f053116b1460bc194c652dc28c84a
|
||||
END
|
||||
cat <<END >$RPM_BUILD_ROOT/etc/tinc/$PEER/passphrases/$PEER
|
||||
1024 9dff58799827c3ae73699d9d4029cf80ee4cfd3a8408495cdb68c78dec602c46f362aedeea80928384254bc7d0bfbf9756c0783b5ec9943161863530a8861947147d124286e8c46fd98af988c96ba65c63acefc01f6c03b6b8f7d9897acb02c083adb7416ee5ccbc19610a8b9ade2599d8f66e94c715f2e1a15054a78a3f3260
|
||||
END
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%pre
|
||||
%post
|
||||
|
||||
/sbin/chkconfig --add tinc
|
||||
|
||||
grep -q '^tinc[[:space:]]' /etc/services || patch -s /etc/services << END
|
||||
*** services.org Tue Apr 18 13:22:22 2000
|
||||
--- services Tue Apr 18 13:24:19 2000
|
||||
***************
|
||||
*** 145,148 ****
|
||||
--- 145,150 ----
|
||||
hmmp-ind 612/tcp dqs313_intercell# HMMP Indication / DQS
|
||||
hmmp-ind 612/udp dqs313_intercell# HMMP Indication / DQS
|
||||
+ tinc 655/tcp TINC # tinc vpn
|
||||
+ tinc 655/udp TINC # http://tinc.nl.linux.org/
|
||||
#
|
||||
# UNIX specific services
|
||||
END
|
||||
|
||||
grep -q '^alias tap0' /etc/conf.modules || cat >> /etc/conf.modules << END
|
||||
# tinc uses ethertap/netlink
|
||||
alias tap0 ethertap
|
||||
alias char-major-36 netlink_dev
|
||||
END
|
||||
/sbin/install-info /usr/info/tinc.info.gz /usr/info/dir
|
||||
|
||||
%preun
|
||||
/sbin/install-info --delete /usr/info/tinc.info.gz /usr/info/dir
|
||||
|
||||
%postun
|
||||
|
||||
%files
|
||||
%doc AUTHORS ChangeLog NEWS README THANKS *.html doc/tinc.conf.sample
|
||||
%config /etc/tinc/
|
||||
%attr(0755,root,root) /etc/rc.d/init.d/tinc
|
||||
/usr/sbin/genauth
|
||||
/usr/sbin/tincd
|
||||
/usr/lib/tinc/
|
||||
/usr/man/man5/tinc.conf.5
|
||||
/usr/man/man8/genauth.8
|
||||
/usr/man/man8/tincd.8
|
||||
/usr/info/tinc.info.gz
|
|
@ -1,33 +1,31 @@
|
|||
## Produce this file with automake to get Makefile.in
|
||||
# $Id: Makefile.am,v 1.12 2002/05/02 13:11:55 zarq Exp $
|
||||
|
||||
SUBDIRS = pokey
|
||||
# $Id: Makefile.am,v 1.13 2003/08/24 20:38:23 guus Exp $
|
||||
|
||||
sbin_PROGRAMS = tincd
|
||||
|
||||
EXTRA_DIST = linux/device.c freebsd/device.c openbsd/device.c solaris/device.c
|
||||
EXTRA_DIST = linux/device.c freebsd/device.c openbsd/device.c solaris/device.c netbsd/device.c darwin/device.c cygwin/device.c mingw/device.c raw_socket/device.c
|
||||
|
||||
tincd_SOURCES = read_conf.c device.c meta.c net_packet.c net_setup.c \
|
||||
net_socket.c process.c protocol.c protocol_auth.c protocol_edge.c protocol_misc.c \
|
||||
protocol_key.c protocol_subnet.c route.c tincd.c net.c callbacks.c
|
||||
tincd_SOURCES = conf.c connection.c edge.c event.c graph.c logger.c meta.c net.c net_packet.c net_setup.c \
|
||||
net_socket.c netutl.c node.c process.c protocol.c protocol_auth.c protocol_edge.c protocol_misc.c \
|
||||
protocol_key.c protocol_subnet.c route.c subnet.c tincd.c
|
||||
|
||||
INCLUDES = @INCLUDES@ -I$(top_builddir) -I$(top_srcdir)/lib -I$(top_srcdir)/intl
|
||||
nodist_tincd_SOURCES = device.c
|
||||
|
||||
noinst_HEADERS = read_conf.h device.h meta.h process.h \
|
||||
protocol.h route.h callbacks.h
|
||||
DEFAULT_INCLUDES =
|
||||
|
||||
LIBS = @LIBS@ @INTLLIBS@
|
||||
INCLUDES = @INCLUDES@ -I$(top_builddir) -I$(top_srcdir)/lib
|
||||
|
||||
noinst_HEADERS = conf.h connection.h device.h edge.h event.h graph.h logger.h meta.h net.h netutl.h node.h process.h \
|
||||
protocol.h route.h subnet.h
|
||||
|
||||
LIBS = @LIBS@ @LIBINTL@
|
||||
|
||||
tincd_LDADD = \
|
||||
$(top_builddir)/lib/libtinc.a -lgcrypt
|
||||
$(top_builddir)/lib/libvpn.a
|
||||
|
||||
localedir = $(datadir)/locale
|
||||
|
||||
CFLAGS = @CFLAGS@ -DPKGLIBDIR=$(pkglibdir) -DCONFDIR=\"$(sysconfdir)\" \
|
||||
-DLOCALEDIR=\"$(localedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\"
|
||||
AM_CFLAGS = @CFLAGS@ -DCONFDIR=\"$(sysconfdir)\" -DLOCALEDIR=\"$(localedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\"
|
||||
|
||||
dist-hook:
|
||||
rm -f `find . -type l`
|
||||
|
||||
lint: $(tincd_SOURCES)
|
||||
lclint -nullassign -nullret +trytorecover +posixlib -skipansiheaders -skipposixheaders +gnuextensions -I/usr/include -I/usr/lib/gcc-lib/i386-linux/2.95.2/include -I. -I/home/zarq/p/tinc/cvs/cabal/src -I.. -I.. -I/home/zarq/p/tinc/cvs/cabal/lib -I/home/zarq/p/tinc/cvs/cabal/intl -D_POSIX_SOURCE -D__ELF__ -Dunix -D__i386__ -Dlinux -DHAVE_CONFIG_H -DPKGLIBDIR=/usr/local/lib/tinc -DCONFDIR=\"/usr/local/etc\" -DLOCALEDIR=\"/usr/local/share/locale\" $^
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <hooks.h>
|
||||
#include <node.h>
|
||||
|
||||
#include "callbacks.h"
|
||||
#include "process.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
void hook_node_visible(const char *hooktype, va_list ap)
|
||||
{
|
||||
char *name;
|
||||
node_t *n;
|
||||
|
||||
n = va_arg(ap, node_t*);
|
||||
asprintf(&name, "hosts/%s-down", n->name);
|
||||
execute_script(name);
|
||||
free(name);
|
||||
}
|
||||
|
||||
void hook_node_invisible(const char *hooktype, va_list ap)
|
||||
{
|
||||
char *name;
|
||||
node_t *n;
|
||||
|
||||
n = va_arg(ap, node_t*);
|
||||
asprintf(&name, "hosts/%s-up", n->name);
|
||||
execute_script(name);
|
||||
free(name);
|
||||
}
|
||||
|
||||
void init_callbacks(void)
|
||||
{
|
||||
add_hook("node-visible", hook_node_visible);
|
||||
add_hook("node-invisible", hook_node_invisible);
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
|
||||
#ifndef __TINC_CALLBACKS_H__
|
||||
#define __TINC_CALLBACKS_H__
|
||||
|
||||
extern void init_callbacks(void);
|
||||
|
||||
#endif /* __TINC_CALLBACKS_H__ */
|
489
src/conf.c
Normal file
489
src/conf.c
Normal file
|
@ -0,0 +1,489 @@
|
|||
/*
|
||||
conf.c -- configuration code
|
||||
Copyright (C) 1998 Robert van der Meulen
|
||||
1998-2003 Ivo Timmermans <ivo@o2w.nl>
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
2000 Cris van Pelt <tribbel@arise.dhs.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
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: conf.c,v 1.14 2003/08/24 20:38:24 guus Exp $
|
||||
*/
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "avl_tree.h"
|
||||
#include "conf.h"
|
||||
#include "logger.h"
|
||||
#include "netutl.h" /* for str2address */
|
||||
#include "utils.h" /* for cp */
|
||||
#include "xalloc.h"
|
||||
|
||||
avl_tree_t *config_tree;
|
||||
|
||||
int pingtimeout = 0; /* seconds before timeout */
|
||||
char *confbase = NULL; /* directory in which all config files are */
|
||||
char *netname = NULL; /* name of the vpn network */
|
||||
|
||||
static int config_compare(const config_t *a, const config_t *b)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = strcasecmp(a->variable, b->variable);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = a->line - b->line;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
else
|
||||
return strcmp(a->file, b->file);
|
||||
}
|
||||
|
||||
void init_configuration(avl_tree_t ** config_tree)
|
||||
{
|
||||
cp();
|
||||
|
||||
*config_tree = avl_alloc_tree((avl_compare_t) config_compare, (avl_action_t) free_config);
|
||||
}
|
||||
|
||||
void exit_configuration(avl_tree_t ** config_tree)
|
||||
{
|
||||
cp();
|
||||
|
||||
avl_delete_tree(*config_tree);
|
||||
*config_tree = NULL;
|
||||
}
|
||||
|
||||
config_t *new_config(void)
|
||||
{
|
||||
cp();
|
||||
|
||||
return (config_t *) xmalloc_and_zero(sizeof(config_t));
|
||||
}
|
||||
|
||||
void free_config(config_t *cfg)
|
||||
{
|
||||
cp();
|
||||
|
||||
if(cfg->variable)
|
||||
free(cfg->variable);
|
||||
|
||||
if(cfg->value)
|
||||
free(cfg->value);
|
||||
|
||||
if(cfg->file)
|
||||
free(cfg->file);
|
||||
|
||||
free(cfg);
|
||||
}
|
||||
|
||||
void config_add(avl_tree_t *config_tree, config_t *cfg)
|
||||
{
|
||||
cp();
|
||||
|
||||
avl_insert(config_tree, cfg);
|
||||
}
|
||||
|
||||
config_t *lookup_config(const avl_tree_t *config_tree, char *variable)
|
||||
{
|
||||
config_t cfg, *found;
|
||||
|
||||
cp();
|
||||
|
||||
cfg.variable = variable;
|
||||
cfg.file = "";
|
||||
cfg.line = 0;
|
||||
|
||||
found = avl_search_closest_greater(config_tree, &cfg);
|
||||
|
||||
if(!found)
|
||||
return NULL;
|
||||
|
||||
if(strcasecmp(found->variable, variable))
|
||||
return NULL;
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
config_t *lookup_config_next(const avl_tree_t *config_tree, const config_t *cfg)
|
||||
{
|
||||
avl_node_t *node;
|
||||
config_t *found;
|
||||
|
||||
cp();
|
||||
|
||||
node = avl_search_node(config_tree, cfg);
|
||||
|
||||
if(node) {
|
||||
if(node->next) {
|
||||
found = (config_t *) node->next->data;
|
||||
|
||||
if(!strcasecmp(found->variable, cfg->variable))
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool get_config_bool(const config_t *cfg, bool *result)
|
||||
{
|
||||
cp();
|
||||
|
||||
if(!cfg)
|
||||
return false;
|
||||
|
||||
if(!strcasecmp(cfg->value, "yes")) {
|
||||
*result = true;
|
||||
return true;
|
||||
} else if(!strcasecmp(cfg->value, "no")) {
|
||||
*result = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
logger(LOG_ERR, _("\"yes\" or \"no\" expected for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool get_config_int(const config_t *cfg, int *result)
|
||||
{
|
||||
cp();
|
||||
|
||||
if(!cfg)
|
||||
return false;
|
||||
|
||||
if(sscanf(cfg->value, "%d", result) == 1)
|
||||
return true;
|
||||
|
||||
logger(LOG_ERR, _("Integer expected for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool get_config_string(const config_t *cfg, char **result)
|
||||
{
|
||||
cp();
|
||||
|
||||
if(!cfg)
|
||||
return false;
|
||||
|
||||
*result = xstrdup(cfg->value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_config_address(const config_t *cfg, struct addrinfo **result)
|
||||
{
|
||||
struct addrinfo *ai;
|
||||
|
||||
cp();
|
||||
|
||||
if(!cfg)
|
||||
return false;
|
||||
|
||||
ai = str2addrinfo(cfg->value, NULL, 0);
|
||||
|
||||
if(ai) {
|
||||
*result = ai;
|
||||
return true;
|
||||
}
|
||||
|
||||
logger(LOG_ERR, _("Hostname or IP address expected for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool get_config_subnet(const config_t *cfg, subnet_t ** result)
|
||||
{
|
||||
subnet_t *subnet;
|
||||
|
||||
cp();
|
||||
|
||||
if(!cfg)
|
||||
return false;
|
||||
|
||||
subnet = str2net(cfg->value);
|
||||
|
||||
if(!subnet) {
|
||||
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)))) {
|
||||
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;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Read exactly one line and strip the trailing newline if any. If the
|
||||
file was on EOF, return NULL. Otherwise, return all the data in a
|
||||
dynamically allocated buffer.
|
||||
|
||||
If line is non-NULL, it will be used as an initial buffer, to avoid
|
||||
unnecessary mallocing each time this function is called. If buf is
|
||||
given, and buf needs to be expanded, the var pointed to by buflen
|
||||
will be increased.
|
||||
*/
|
||||
static char *readline(FILE * fp, char **buf, size_t *buflen)
|
||||
{
|
||||
char *newline = NULL;
|
||||
char *p;
|
||||
char *line; /* The array that contains everything that has been read so far */
|
||||
char *idx; /* Read into this pointer, which points to an offset within line */
|
||||
size_t size, newsize; /* The size of the current array pointed to by line */
|
||||
size_t maxlen; /* Maximum number of characters that may be read with fgets. This is newsize - oldsize. */
|
||||
|
||||
if(feof(fp))
|
||||
return NULL;
|
||||
|
||||
if(buf && buflen) {
|
||||
size = *buflen;
|
||||
line = *buf;
|
||||
} else {
|
||||
size = 100;
|
||||
line = xmalloc(size);
|
||||
}
|
||||
|
||||
maxlen = size;
|
||||
idx = line;
|
||||
*idx = 0;
|
||||
|
||||
for(;;) {
|
||||
errno = 0;
|
||||
p = fgets(idx, maxlen, fp);
|
||||
|
||||
if(!p) { /* EOF or error */
|
||||
if(feof(fp))
|
||||
break;
|
||||
|
||||
/* otherwise: error; let the calling function print an error message if applicable */
|
||||
free(line);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
newline = strchr(p, '\n');
|
||||
|
||||
if(!newline) { /* We haven't yet read everything to the end of the line */
|
||||
newsize = size << 1;
|
||||
line = xrealloc(line, newsize);
|
||||
idx = &line[size - 1];
|
||||
maxlen = newsize - size + 1;
|
||||
size = newsize;
|
||||
} else {
|
||||
*newline = '\0'; /* kill newline */
|
||||
break; /* yay */
|
||||
}
|
||||
}
|
||||
|
||||
if(buf && buflen) {
|
||||
*buflen = size;
|
||||
*buf = line;
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
Parse a configuration file and put the results in the configuration tree
|
||||
starting at *base.
|
||||
*/
|
||||
int read_config_file(avl_tree_t *config_tree, const char *fname)
|
||||
{
|
||||
int err = -2; /* Parse error */
|
||||
FILE *fp;
|
||||
char *buffer, *line;
|
||||
char *variable, *value;
|
||||
int lineno = 0;
|
||||
int len;
|
||||
bool ignore = false;
|
||||
config_t *cfg;
|
||||
size_t bufsize;
|
||||
|
||||
cp();
|
||||
|
||||
fp = fopen(fname, "r");
|
||||
|
||||
if(!fp) {
|
||||
logger(LOG_ERR, _("Cannot open config file %s: %s"), fname,
|
||||
strerror(errno));
|
||||
return -3;
|
||||
}
|
||||
|
||||
bufsize = 100;
|
||||
buffer = xmalloc(bufsize);
|
||||
|
||||
for(;;) {
|
||||
line = readline(fp, &buffer, &bufsize);
|
||||
|
||||
if(!line) {
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(feof(fp)) {
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
lineno++;
|
||||
|
||||
if(!*line || *line == '#')
|
||||
continue;
|
||||
|
||||
if(ignore) {
|
||||
if(!strncmp(line, "-----END", 8))
|
||||
ignore = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!strncmp(line, "-----BEGIN", 10)) {
|
||||
ignore = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
variable = value = line;
|
||||
|
||||
len = strcspn(value, "\t =");
|
||||
value += len;
|
||||
value += strspn(value, "\t ");
|
||||
if(*value == '=') {
|
||||
value++;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
cfg = new_config();
|
||||
cfg->variable = xstrdup(variable);
|
||||
cfg->value = xstrdup(value);
|
||||
cfg->file = xstrdup(fname);
|
||||
cfg->line = lineno;
|
||||
|
||||
config_add(config_tree, cfg);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
fclose(fp);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
bool read_server_config()
|
||||
{
|
||||
char *fname;
|
||||
int x;
|
||||
|
||||
cp();
|
||||
|
||||
asprintf(&fname, "%s/tinc.conf", confbase);
|
||||
x = read_config_file(config_tree, fname);
|
||||
|
||||
if(x == -1) { /* System error: complain */
|
||||
logger(LOG_ERR, _("Failed to read `%s': %s"), fname, strerror(errno));
|
||||
}
|
||||
|
||||
free(fname);
|
||||
|
||||
return x == 0;
|
||||
}
|
||||
|
||||
FILE *ask_and_open(const char *filename, const char *what, const char *mode)
|
||||
{
|
||||
FILE *r;
|
||||
char *directory;
|
||||
char *fn;
|
||||
|
||||
/* Check stdin and stdout */
|
||||
if(!isatty(0) || !isatty(1)) {
|
||||
/* Argh, they are running us from a script or something. Write
|
||||
the files to the current directory and let them burn in hell
|
||||
for ever. */
|
||||
fn = xstrdup(filename);
|
||||
} else {
|
||||
/* Ask for a file and/or directory name. */
|
||||
fprintf(stdout, _("Please enter a file to save %s to [%s]: "),
|
||||
what, filename);
|
||||
fflush(stdout);
|
||||
|
||||
fn = readline(stdin, NULL, NULL);
|
||||
|
||||
if(!fn) {
|
||||
fprintf(stderr, _("Error while reading stdin: %s\n"),
|
||||
strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!strlen(fn))
|
||||
/* User just pressed enter. */
|
||||
fn = xstrdup(filename);
|
||||
}
|
||||
|
||||
#ifdef HAVE_MINGW
|
||||
if(fn[0] != '\\' && fn[0] != '/' && !strchr(fn, ':')) {
|
||||
#else
|
||||
if(fn[0] != '/') {
|
||||
#endif
|
||||
/* The directory is a relative path or a filename. */
|
||||
char *p;
|
||||
|
||||
directory = get_current_dir_name();
|
||||
asprintf(&p, "%s/%s", directory, fn);
|
||||
free(fn);
|
||||
free(directory);
|
||||
fn = p;
|
||||
}
|
||||
|
||||
umask(0077); /* Disallow everything for group and other */
|
||||
|
||||
/* Open it first to keep the inode busy */
|
||||
|
||||
r = fopen(fn, mode);
|
||||
|
||||
if(!r) {
|
||||
fprintf(stderr, _("Error opening file `%s': %s\n"),
|
||||
fn, strerror(errno));
|
||||
free(fn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(fn);
|
||||
|
||||
return r;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
conf.h -- header for conf.c
|
||||
Copyright (C) 1998-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 1998-2003 Ivo Timmermans <ivo@o2w.nl>
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -17,49 +17,47 @@
|
|||
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.1 2002/04/28 12:46:25 zarq Exp $
|
||||
$Id: conf.h,v 1.11 2003/08/24 20:38:24 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_CONF_H__
|
||||
#define __TINC_CONF_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
#include "net.h"
|
||||
#include "subnet.h"
|
||||
#include "avl_tree.h"
|
||||
|
||||
typedef struct config_t {
|
||||
char *variable;
|
||||
char *value;
|
||||
char *file;
|
||||
int line;
|
||||
char *variable;
|
||||
char *value;
|
||||
char *file;
|
||||
int line;
|
||||
} config_t;
|
||||
|
||||
#include "subnet.h"
|
||||
|
||||
extern avl_tree_t *config_tree;
|
||||
|
||||
extern int pingtimeout;
|
||||
extern int maxtimeout;
|
||||
extern int bypass_security;
|
||||
extern bool bypass_security;
|
||||
extern char *confbase;
|
||||
extern char *netname;
|
||||
|
||||
extern void init_configuration(avl_tree_t **);
|
||||
extern void exit_configuration(avl_tree_t **);
|
||||
extern config_t *new_config(void);
|
||||
extern config_t *new_config(void) __attribute__ ((__malloc__));
|
||||
extern void free_config(config_t *);
|
||||
extern void config_add(avl_tree_t *, config_t *);
|
||||
extern config_t *lookup_config(avl_tree_t *, char *);
|
||||
extern config_t *lookup_config_next(avl_tree_t *, config_t *);
|
||||
extern int get_config_bool(config_t *, int *);
|
||||
extern int get_config_int(config_t *, int *);
|
||||
extern int get_config_port(config_t *, port_t *);
|
||||
extern int get_config_string(config_t *, char **);
|
||||
extern int get_config_address(config_t *, struct addrinfo **);
|
||||
struct subnet_t; /* Needed for next line. */
|
||||
extern int get_config_subnet(config_t *, struct subnet_t **);
|
||||
extern config_t *lookup_config(const avl_tree_t *, char *);
|
||||
extern config_t *lookup_config_next(const avl_tree_t *, const config_t *);
|
||||
extern bool get_config_bool(const config_t *, bool *);
|
||||
extern bool get_config_int(const config_t *, int *);
|
||||
extern bool get_config_string(const config_t *, char **);
|
||||
extern bool get_config_address(const config_t *, struct addrinfo **);
|
||||
extern bool get_config_subnet(const config_t *, struct subnet_t **);
|
||||
|
||||
#endif /* __TINC_CONF_H__ */
|
||||
extern int read_config_file(avl_tree_t *, const char *);
|
||||
extern bool read_server_config(void);
|
||||
extern FILE *ask_and_open(const char *, const char *, const char *);
|
||||
extern bool is_safe_path(const char *);
|
||||
|
||||
#endif /* __TINC_CONF_H__ */
|
143
src/connection.c
Normal file
143
src/connection.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
connection.c -- connection list management
|
||||
Copyright (C) 2000-2003 Guus Sliepen <guus@sliepen.eu.org>,
|
||||
2000-2003 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: connection.c,v 1.4 2003/08/24 20:38:24 guus Exp $
|
||||
*/
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "avl_tree.h"
|
||||
#include "conf.h"
|
||||
#include "list.h"
|
||||
#include "logger.h"
|
||||
#include "net.h" /* Don't ask. */
|
||||
#include "netutl.h"
|
||||
#include "subnet.h"
|
||||
#include "utils.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
avl_tree_t *connection_tree; /* Meta connections */
|
||||
connection_t *broadcast;
|
||||
|
||||
static int connection_compare(const connection_t *a, const connection_t *b)
|
||||
{
|
||||
return (void *)a - (void *)b;
|
||||
}
|
||||
|
||||
void init_connections(void)
|
||||
{
|
||||
cp();
|
||||
|
||||
connection_tree = avl_alloc_tree((avl_compare_t) connection_compare, NULL);
|
||||
broadcast = new_connection();
|
||||
broadcast->name = xstrdup(_("everyone"));
|
||||
broadcast->hostname = xstrdup(_("BROADCAST"));
|
||||
}
|
||||
|
||||
void exit_connections(void)
|
||||
{
|
||||
cp();
|
||||
|
||||
avl_delete_tree(connection_tree);
|
||||
free_connection(broadcast);
|
||||
}
|
||||
|
||||
connection_t *new_connection(void)
|
||||
{
|
||||
connection_t *c;
|
||||
|
||||
cp();
|
||||
|
||||
c = (connection_t *) xmalloc_and_zero(sizeof(connection_t));
|
||||
|
||||
if(!c)
|
||||
return NULL;
|
||||
|
||||
gettimeofday(&c->start, NULL);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void free_connection(connection_t *c)
|
||||
{
|
||||
cp();
|
||||
|
||||
if(c->hostname)
|
||||
free(c->hostname);
|
||||
|
||||
if(c->inkey)
|
||||
free(c->inkey);
|
||||
|
||||
if(c->outkey)
|
||||
free(c->outkey);
|
||||
|
||||
if(c->mychallenge)
|
||||
free(c->mychallenge);
|
||||
|
||||
if(c->hischallenge)
|
||||
free(c->hischallenge);
|
||||
|
||||
free(c);
|
||||
}
|
||||
|
||||
void connection_add(connection_t *c)
|
||||
{
|
||||
cp();
|
||||
|
||||
avl_insert(connection_tree, c);
|
||||
}
|
||||
|
||||
void connection_del(connection_t *c)
|
||||
{
|
||||
cp();
|
||||
|
||||
avl_delete(connection_tree, c);
|
||||
}
|
||||
|
||||
void dump_connections(void)
|
||||
{
|
||||
avl_node_t *node;
|
||||
connection_t *c;
|
||||
|
||||
cp();
|
||||
|
||||
logger(LOG_DEBUG, _("Connections:"));
|
||||
|
||||
for(node = connection_tree->head; node; node = node->next) {
|
||||
c = (connection_t *) 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);
|
||||
}
|
||||
|
||||
logger(LOG_DEBUG, _("End of connections."));
|
||||
}
|
||||
|
||||
bool read_connection_config(connection_t *c)
|
||||
{
|
||||
char *fname;
|
||||
int x;
|
||||
|
||||
cp();
|
||||
|
||||
asprintf(&fname, "%s/hosts/%s", confbase, c->name);
|
||||
x = read_config_file(c->config_tree, fname);
|
||||
free(fname);
|
||||
|
||||
return x == 0;
|
||||
}
|
110
src/connection.h
Normal file
110
src/connection.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
connection.h -- header for connection.c
|
||||
Copyright (C) 2000-2003 Guus Sliepen <guus@sliepen.eu.org>,
|
||||
2000-2003 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: connection.h,v 1.4 2003/08/24 20:38:24 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_CONNECTION_H__
|
||||
#define __TINC_CONNECTION_H__
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "avl_tree.h"
|
||||
|
||||
#define OPTION_INDIRECT 0x0001
|
||||
#define OPTION_TCPONLY 0x0002
|
||||
|
||||
typedef struct connection_status_t {
|
||||
int pinged:1; /* sent ping */
|
||||
int active:1; /* 1 if active.. */
|
||||
int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */
|
||||
int termreq:1; /* the termination of this connection was requested */
|
||||
int remove:1; /* Set to 1 if you want this connection removed */
|
||||
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;
|
||||
} connection_status_t;
|
||||
|
||||
#include "edge.h"
|
||||
#include "list.h"
|
||||
#include "net.h"
|
||||
#include "node.h"
|
||||
|
||||
typedef struct connection_t {
|
||||
char *name; /* name he claims to have */
|
||||
|
||||
union sockaddr_t address; /* his real (internet) ip */
|
||||
char *hostname; /* the hostname of its real ip */
|
||||
int protocol_version; /* used protocol */
|
||||
|
||||
int socket; /* socket used for this connection */
|
||||
long int options; /* options for this connection */
|
||||
struct connection_status_t status; /* status info */
|
||||
int estimated_weight; /* estimation for the weight of the edge for this connection */
|
||||
struct timeval start; /* time this connection was started, used for above estimation */
|
||||
struct outgoing_t *outgoing; /* used to keep track of outgoing connections */
|
||||
|
||||
struct node_t *node; /* node associated with the other end */
|
||||
struct edge_t *edge; /* edge associated with this connection */
|
||||
|
||||
RSA *rsa_key; /* his public/private key */
|
||||
const EVP_CIPHER *incipher; /* Cipher he will use to send data to us */
|
||||
const EVP_CIPHER *outcipher; /* Cipher we will use to send data to him */
|
||||
EVP_CIPHER_CTX *inctx; /* Context of encrypted meta data that will come from him to us */
|
||||
EVP_CIPHER_CTX *outctx; /* Context of encrypted meta data that will be sent from us to him */
|
||||
char *inkey; /* His symmetric meta key + iv */
|
||||
char *outkey; /* Our symmetric meta key + iv */
|
||||
int inkeylength; /* Length of his key + iv */
|
||||
int outkeylength; /* Length of our key + iv */
|
||||
const EVP_MD *indigest;
|
||||
const EVP_MD *outdigest;
|
||||
int inmaclength;
|
||||
int outmaclength;
|
||||
int incompression;
|
||||
int outcompression;
|
||||
char *mychallenge; /* challenge we received from him */
|
||||
char *hischallenge; /* challenge we sent to him */
|
||||
|
||||
char buffer[MAXBUFSIZE]; /* metadata input buffer */
|
||||
int buflen; /* bytes read into buffer */
|
||||
int reqlen; /* length of incoming request */
|
||||
int tcplen; /* length of incoming TCPpacket */
|
||||
int allow_request; /* defined if there's only one request possible */
|
||||
|
||||
time_t last_ping_time; /* last time we saw some activity from the other end */
|
||||
|
||||
avl_tree_t *config_tree; /* Pointer to configuration tree belonging to him */
|
||||
} connection_t;
|
||||
|
||||
extern avl_tree_t *connection_tree;
|
||||
extern connection_t *broadcast;
|
||||
|
||||
extern void init_connections(void);
|
||||
extern void exit_connections(void);
|
||||
extern connection_t *new_connection(void) __attribute__ ((__malloc__));
|
||||
extern void free_connection(connection_t *);
|
||||
extern void connection_add(connection_t *);
|
||||
extern void connection_del(connection_t *);
|
||||
extern void dump_connections(void);
|
||||
extern bool read_connection_config(connection_t *);
|
||||
|
||||
#endif /* __TINC_CONNECTION_H__ */
|
290
src/cygwin/device.c
Normal file
290
src/cygwin/device.c
Normal file
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
device.c -- Interaction with Windows tap driver in a Cygwin environment
|
||||
Copyright (C) 2002-2003 Ivo Timmermans <ivo@o2w.nl>,
|
||||
2002-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
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: device.c,v 1.2 2003/08/24 20:38:29 guus Exp $
|
||||
*/
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include <w32api/windows.h>
|
||||
#include <w32api/winioctl.h>
|
||||
|
||||
#include "conf.h"
|
||||
#include "logger.h"
|
||||
#include "net.h"
|
||||
#include "route.h"
|
||||
#include "utils.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
#define REG_CONTROL_NET "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
|
||||
|
||||
#define USERMODEDEVICEDIR "\\\\.\\"
|
||||
#define USERDEVICEDIR "\\??\\"
|
||||
#define TAPSUFFIX ".tap"
|
||||
|
||||
#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)
|
||||
|
||||
int device_fd = -1;
|
||||
static HANDLE device_handle = INVALID_HANDLE_VALUE;
|
||||
char *device = NULL;
|
||||
char *iface = NULL;
|
||||
char *device_info = NULL;
|
||||
|
||||
int device_total_in = 0;
|
||||
int device_total_out = 0;
|
||||
|
||||
pid_t reader_pid;
|
||||
int sp[2];
|
||||
|
||||
bool setup_device(void)
|
||||
{
|
||||
HKEY key, key2;
|
||||
int i;
|
||||
|
||||
char regpath[1024];
|
||||
char adapterid[1024];
|
||||
char adaptername[1024];
|
||||
char tapname[1024];
|
||||
char gelukt = 0;
|
||||
long len;
|
||||
|
||||
bool found = false;
|
||||
|
||||
cp();
|
||||
|
||||
get_config_string(lookup_config(config_tree, "Device"), &device);
|
||||
get_config_string(lookup_config(config_tree, "Interface"), &iface);
|
||||
|
||||
/* Open registry and look for network adapters */
|
||||
|
||||
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CONTROL_NET, 0, KEY_READ, &key)) {
|
||||
logger(LOG_ERR, _("Unable to read registry: %s"), winerror(GetLastError()));
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; ; i++) {
|
||||
len = sizeof(adapterid);
|
||||
if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL))
|
||||
break;
|
||||
|
||||
/* Find out more about this adapter */
|
||||
|
||||
snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", REG_CONTROL_NET, adapterid);
|
||||
|
||||
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2))
|
||||
continue;
|
||||
|
||||
len = sizeof(adaptername);
|
||||
err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len);
|
||||
|
||||
RegCloseKey(key2);
|
||||
|
||||
if(err)
|
||||
continue;
|
||||
|
||||
if(device) {
|
||||
if(!strcmp(device, adapterid)) {
|
||||
found = true;
|
||||
break;
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
|
||||
if(iface) {
|
||||
if(!strcmp(iface, adaptername)) {
|
||||
found = true;
|
||||
break;
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
|
||||
snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid);
|
||||
device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
||||
if(device_handle != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(device_handle);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(key);
|
||||
|
||||
if(!found) {
|
||||
logger(LOG_ERR, _("No Windows tap device found!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!device)
|
||||
device = xstrdup(adapterid);
|
||||
|
||||
if(!iface)
|
||||
iface = xstrdup(adaptername);
|
||||
|
||||
snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device);
|
||||
|
||||
/* Now we are going to open this device twice: once for reading and once for writing.
|
||||
We do this because apparently it isn't possible to check for activity in the select() loop.
|
||||
Furthermore I don't really know how to do it the "Windows" way. */
|
||||
|
||||
if(socketpair(AF_UNIX, SOCK_DGRAM, PF_UNIX, sp)) {
|
||||
logger(LOG_DEBUG, _("System call `%s' failed: %s"), "socketpair", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* The parent opens the tap device for writing. */
|
||||
|
||||
device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM , 0);
|
||||
|
||||
if(device_handle == INVALID_HANDLE_VALUE) {
|
||||
logger(LOG_ERR, _("Could not open Windows tap device %s (%s) for writing: %s"), device, iface, winerror(GetLastError()));
|
||||
return false;
|
||||
}
|
||||
|
||||
device_fd = sp[0];
|
||||
|
||||
/* Get MAC address from tap device */
|
||||
|
||||
if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) {
|
||||
logger(LOG_ERR, _("Could not get MAC address from Windows tap device %s (%s): %s"), device, iface, winerror(GetLastError()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(routing_mode == RMODE_ROUTER) {
|
||||
overwrite_mac = 1;
|
||||
}
|
||||
|
||||
/* Now we start the child */
|
||||
|
||||
reader_pid = fork();
|
||||
|
||||
if(reader_pid == -1) {
|
||||
logger(LOG_DEBUG, _("System call `%s' failed: %s"), "fork", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!reader_pid) {
|
||||
/* The child opens the tap device for reading, blocking.
|
||||
It passes everything it reads to the socket. */
|
||||
|
||||
char buf[MTU];
|
||||
long lenin;
|
||||
|
||||
CloseHandle(device_handle);
|
||||
|
||||
device_handle = CreateFile(tapname, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
||||
|
||||
if(device_handle == INVALID_HANDLE_VALUE) {
|
||||
logger(LOG_ERR, _("Could not open Windows tap device %s (%s) for reading: %s"), device, iface, winerror(GetLastError()));
|
||||
buf[0] = 0;
|
||||
write(sp[1], buf, 1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
logger(LOG_DEBUG, _("Tap reader forked and running."));
|
||||
|
||||
/* Notify success */
|
||||
|
||||
buf[0] = 1;
|
||||
write(sp[1], buf, 1);
|
||||
|
||||
/* Pass packets */
|
||||
|
||||
for(;;) {
|
||||
ReadFile(device_handle, buf, MTU, &lenin, NULL);
|
||||
write(sp[1], buf, lenin);
|
||||
}
|
||||
}
|
||||
|
||||
read(device_fd, &gelukt, 1);
|
||||
if(gelukt != 1) {
|
||||
logger(LOG_DEBUG, _("Tap reader failed!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
device_info = _("Windows tap device");
|
||||
|
||||
logger(LOG_INFO, _("%s (%s) is a %s"), device, iface, device_info);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void close_device(void)
|
||||
{
|
||||
cp();
|
||||
|
||||
close(sp[0]);
|
||||
close(sp[1]);
|
||||
CloseHandle(device_handle);
|
||||
|
||||
kill(reader_pid, SIGKILL);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet)
|
||||
{
|
||||
int lenin;
|
||||
|
||||
cp();
|
||||
|
||||
if((lenin = read(sp[0], packet->data, MTU)) <= 0) {
|
||||
logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info,
|
||||
device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
packet->len = lenin;
|
||||
|
||||
device_total_in += packet->len;
|
||||
|
||||
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len,
|
||||
device_info);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool write_packet(vpn_packet_t *packet)
|
||||
{
|
||||
long lenout;
|
||||
|
||||
cp();
|
||||
|
||||
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"),
|
||||
packet->len, device_info);
|
||||
|
||||
if(!WriteFile (device_handle, packet->data, packet->len, &lenout, NULL)) {
|
||||
logger(LOG_ERR, _("Error while writing to %s %s: %s"), device_info, device, winerror(GetLastError()));
|
||||
return false;
|
||||
}
|
||||
|
||||
device_total_out += packet->len;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dump_device_stats(void)
|
||||
{
|
||||
cp();
|
||||
|
||||
logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
|
||||
logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in);
|
||||
logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out);
|
||||
}
|
118
src/darwin/device.c
Normal file
118
src/darwin/device.c
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
device.c -- Interaction with MacOS/X tun device
|
||||
Copyright (C) 2001-2003 Ivo Timmermans <ivo@o2w.nl>,
|
||||
2001-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
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: device.c,v 1.2 2003/08/24 20:38:29 guus Exp $
|
||||
*/
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "conf.h"
|
||||
#include "logger.h"
|
||||
#include "net.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define DEFAULT_DEVICE "/dev/tun0"
|
||||
|
||||
int device_fd = -1;
|
||||
char *device;
|
||||
char *iface;
|
||||
char *device_info;
|
||||
int device_total_in = 0;
|
||||
int device_total_out = 0;
|
||||
|
||||
bool setup_device(void)
|
||||
{
|
||||
cp();
|
||||
|
||||
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
|
||||
device = DEFAULT_DEVICE;
|
||||
|
||||
if(!get_config_string(lookup_config(config_tree, "Interface"), &iface))
|
||||
iface = rindex(device, '/') ? rindex(device, '/') + 1 : device;
|
||||
|
||||
if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) {
|
||||
logger(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
device_info = _("MacOS/X tun device");
|
||||
|
||||
logger(LOG_INFO, _("%s is a %s"), device, device_info);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void close_device(void)
|
||||
{
|
||||
cp();
|
||||
|
||||
close(device_fd);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet)
|
||||
{
|
||||
int lenin;
|
||||
|
||||
cp();
|
||||
|
||||
if((lenin = read(device_fd, packet->data + 14, MTU - 14)) <= 0) {
|
||||
logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info,
|
||||
device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
packet->data[12] = 0x08;
|
||||
packet->data[13] = 0x00;
|
||||
|
||||
packet->len = lenin + 14;
|
||||
|
||||
device_total_in += packet->len;
|
||||
|
||||
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"),
|
||||
packet->len, device_info);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool write_packet(vpn_packet_t *packet)
|
||||
{
|
||||
cp();
|
||||
|
||||
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"),
|
||||
packet->len, device_info);
|
||||
|
||||
if(write(device_fd, packet->data + 14, packet->len - 14) < 0) {
|
||||
logger(LOG_ERR, _("Error while writing to %s %s: %s"), device_info,
|
||||
device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
device_total_out += packet->len;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dump_device_stats(void)
|
||||
{
|
||||
cp();
|
||||
|
||||
logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
|
||||
logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in);
|
||||
logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out);
|
||||
}
|
19
src/device.h
19
src/device.h
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
net.h -- generic header for device.c
|
||||
Copyright (C) 2001-2002 Ivo Timmermans <zarq@iname.com>
|
||||
2001-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 2001-2003 Ivo Timmermans <zarq@iname.com>
|
||||
2001-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -17,20 +17,23 @@
|
|||
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.2 2002/04/09 15:26:00 zarq Exp $
|
||||
$Id: device.h,v 1.3 2003/08/24 20:38:24 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_DEVICE_H__
|
||||
#define __TINC_DEVICE_H__
|
||||
|
||||
#include "net.h"
|
||||
|
||||
extern int device_fd;
|
||||
extern char *device;
|
||||
extern char *interface;
|
||||
|
||||
extern int setup_device(void);
|
||||
extern char *iface;
|
||||
|
||||
extern bool setup_device(void);
|
||||
extern void close_device(void);
|
||||
extern int read_packet(vpn_packet_t *);
|
||||
extern int write_packet(vpn_packet_t *);
|
||||
extern bool read_packet(struct vpn_packet_t *);
|
||||
extern bool write_packet(struct vpn_packet_t *);
|
||||
extern void dump_device_stats(void);
|
||||
|
||||
#endif /* __TINC_DEVICE_H__ */
|
||||
#endif /* __TINC_DEVICE_H__ */
|
||||
|
|
162
src/edge.c
Normal file
162
src/edge.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
edge.c -- edge tree management
|
||||
Copyright (C) 2000-2003 Guus Sliepen <guus@sliepen.eu.org>,
|
||||
2000-2003 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: edge.c,v 1.4 2003/08/24 20:38:24 guus Exp $
|
||||
*/
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "avl_tree.h"
|
||||
#include "edge.h"
|
||||
#include "logger.h"
|
||||
#include "netutl.h"
|
||||
#include "node.h"
|
||||
#include "utils.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
avl_tree_t *edge_weight_tree; /* Tree with all edges, sorted on weight */
|
||||
|
||||
static int edge_compare(const edge_t *a, const edge_t *b)
|
||||
{
|
||||
return strcmp(a->to->name, b->to->name);
|
||||
}
|
||||
|
||||
static int edge_weight_compare(const edge_t *a, const edge_t *b)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = a->weight - b->weight;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = strcmp(a->from->name, b->from->name);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
return strcmp(a->to->name, b->to->name);
|
||||
}
|
||||
|
||||
void init_edges(void)
|
||||
{
|
||||
cp();
|
||||
|
||||
edge_weight_tree = avl_alloc_tree((avl_compare_t) edge_weight_compare, NULL);
|
||||
}
|
||||
|
||||
avl_tree_t *new_edge_tree(void)
|
||||
{
|
||||
cp();
|
||||
|
||||
return avl_alloc_tree((avl_compare_t) edge_compare, (avl_action_t) free_edge);
|
||||
}
|
||||
|
||||
void free_edge_tree(avl_tree_t *edge_tree)
|
||||
{
|
||||
cp();
|
||||
|
||||
avl_delete_tree(edge_tree);
|
||||
}
|
||||
|
||||
void exit_edges(void)
|
||||
{
|
||||
cp();
|
||||
|
||||
avl_delete_tree(edge_weight_tree);
|
||||
}
|
||||
|
||||
/* Creation and deletion of connection elements */
|
||||
|
||||
edge_t *new_edge(void)
|
||||
{
|
||||
cp();
|
||||
|
||||
return (edge_t *) xmalloc_and_zero(sizeof(edge_t));
|
||||
}
|
||||
|
||||
void free_edge(edge_t *e)
|
||||
{
|
||||
cp();
|
||||
|
||||
sockaddrfree(&e->address);
|
||||
|
||||
free(e);
|
||||
}
|
||||
|
||||
void edge_add(edge_t *e)
|
||||
{
|
||||
cp();
|
||||
|
||||
avl_insert(edge_weight_tree, e);
|
||||
avl_insert(e->from->edge_tree, e);
|
||||
|
||||
e->reverse = lookup_edge(e->to, e->from);
|
||||
|
||||
if(e->reverse)
|
||||
e->reverse->reverse = e;
|
||||
}
|
||||
|
||||
void edge_del(edge_t *e)
|
||||
{
|
||||
cp();
|
||||
|
||||
if(e->reverse)
|
||||
e->reverse->reverse = NULL;
|
||||
|
||||
avl_delete(edge_weight_tree, e);
|
||||
avl_delete(e->from->edge_tree, e);
|
||||
}
|
||||
|
||||
edge_t *lookup_edge(node_t *from, node_t *to)
|
||||
{
|
||||
edge_t v;
|
||||
|
||||
cp();
|
||||
|
||||
v.from = from;
|
||||
v.to = to;
|
||||
|
||||
return avl_search(from->edge_tree, &v);
|
||||
}
|
||||
|
||||
void dump_edges(void)
|
||||
{
|
||||
avl_node_t *node, *node2;
|
||||
node_t *n;
|
||||
edge_t *e;
|
||||
char *address;
|
||||
|
||||
cp();
|
||||
|
||||
logger(LOG_DEBUG, _("Edges:"));
|
||||
|
||||
for(node = node_tree->head; node; node = node->next) {
|
||||
n = (node_t *) node->data;
|
||||
for(node2 = n->edge_tree->head; node2; node2 = node2->next) {
|
||||
e = (edge_t *) 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);
|
||||
free(address);
|
||||
}
|
||||
}
|
||||
|
||||
logger(LOG_DEBUG, _("End of edges."));
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
edge.h -- header for edge.c
|
||||
Copyright (C) 2001-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2001-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
Copyright (C) 2001-2003 Guus Sliepen <guus@sliepen.eu.org>,
|
||||
2001-2003 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
|
||||
|
@ -17,48 +17,40 @@
|
|||
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.1 2002/04/28 12:46:25 zarq Exp $
|
||||
$Id: edge.h,v 1.4 2003/08/24 20:38:24 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_EDGE_H__
|
||||
#define __TINC_EDGE_H__
|
||||
|
||||
#include <avl_tree.h>
|
||||
|
||||
#include "avl_tree.h"
|
||||
#include "connection.h"
|
||||
#include "net.h"
|
||||
#include "node.h"
|
||||
#include "connection.h"
|
||||
|
||||
typedef struct halfconnection_t {
|
||||
struct node_t *node; /* node associated with this end of the connection */
|
||||
/* sockaddr_t tcpaddress; */ /* real (internet) ip on this end of the meta connection */
|
||||
sockaddr_t udpaddress; /* real (internet) ip on this end of the vpn connection */
|
||||
} halfconnection_t;
|
||||
|
||||
typedef struct edge_t {
|
||||
struct halfconnection_t from;
|
||||
struct halfconnection_t to;
|
||||
struct node_t *from;
|
||||
struct node_t *to;
|
||||
sockaddr_t address;
|
||||
|
||||
long int options; /* options turned on for this edge */
|
||||
int weight; /* weight of this edge */
|
||||
|
||||
struct connection_t *connection; /* connection associated with this edge, if available */
|
||||
long int options; /* options turned on for this edge */
|
||||
int weight; /* weight of this edge */
|
||||
|
||||
void *if_data; /* Interface data */
|
||||
struct connection_t *connection; /* connection associated with this edge, if available */
|
||||
struct edge_t *reverse; /* edge in the opposite direction, if available */
|
||||
} edge_t;
|
||||
|
||||
extern avl_tree_t *edge_tree; /* Tree with all known edges (replaces active_tree) */
|
||||
extern avl_tree_t *edge_weight_tree; /* Tree with all known edges sorted on weight */
|
||||
extern avl_tree_t *edge_weight_tree; /* Tree with all known edges sorted on weight */
|
||||
|
||||
extern void init_edges(void);
|
||||
extern void exit_edges(void);
|
||||
extern edge_t *new_edge(void);
|
||||
extern edge_t *new_edge(void) __attribute__ ((__malloc__));
|
||||
extern void free_edge(edge_t *);
|
||||
extern avl_tree_t *new_edge_tree(void);
|
||||
extern avl_tree_t *new_edge_tree(void) __attribute__ ((__malloc__));
|
||||
extern void free_edge_tree(avl_tree_t *);
|
||||
extern void edge_add(edge_t *);
|
||||
extern void edge_del(edge_t *);
|
||||
extern edge_t *lookup_edge(struct node_t *, struct node_t *);
|
||||
extern void dump_edges(void);
|
||||
|
||||
#endif /* __TINC_EDGE_H__ */
|
||||
#endif /* __TINC_EDGE_H__ */
|
358
src/encr.c
358
src/encr.c
|
@ -1,358 +0,0 @@
|
|||
/*
|
||||
encr.c -- everything that deals with encryption
|
||||
Copyright (C) 1998,1999,2000 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
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: encr.c,v 1.13 2000/10/18 20:12:08 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef HAVE_GMP_H
|
||||
# include <gmp.h>
|
||||
#else
|
||||
# ifdef HAVE_GMP2_GMP_H
|
||||
# include <gmp2/gmp.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <utils.h>
|
||||
#include <xalloc.h>
|
||||
|
||||
#include <cipher.h>
|
||||
|
||||
#include "conf.h"
|
||||
#include "encr.h"
|
||||
#include "net.h"
|
||||
#include "protocol.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#define ENCR_GENERATOR "0xd"
|
||||
#define ENCR_PRIME "0x7fffffffffffffffffffffffffffffff" /* Mersenne :) */
|
||||
|
||||
char text_key[1000];
|
||||
char *my_public_key_base36;
|
||||
int key_inited = 0, encryption_keylen;
|
||||
mpz_t my_private_key, my_public_key, generator, shared_prime;
|
||||
int my_key_expiry = (time_t)(-1);
|
||||
|
||||
char* mypassphrase;
|
||||
int mypassphraselen;
|
||||
|
||||
int char_hex_to_bin(int c)
|
||||
{
|
||||
if(isdigit(c))
|
||||
return c - '0';
|
||||
else
|
||||
return tolower(c) - 'a' + 10;
|
||||
}
|
||||
|
||||
int str_hex_to_bin(unsigned char *bin, unsigned char *hex)
|
||||
{
|
||||
int i = 0, j = 0, l = strlen(hex);
|
||||
cp
|
||||
if(l&1)
|
||||
{
|
||||
i = j = 1;
|
||||
bin[0] = char_hex_to_bin(hex[0]);
|
||||
}
|
||||
for(; i < l; i+=2, j++)
|
||||
bin[j] = (char_hex_to_bin(hex[i]) << 4) + char_hex_to_bin(hex[i+1]);
|
||||
cp
|
||||
return j&1?j+1:j;
|
||||
}
|
||||
|
||||
int read_passphrase(char *which, char **out)
|
||||
{
|
||||
FILE *f;
|
||||
config_t const *cfg;
|
||||
char *filename;
|
||||
int size;
|
||||
extern char *confbase;
|
||||
char *pp;
|
||||
cp
|
||||
if((cfg = get_config_val(passphrasesdir)) == NULL)
|
||||
{
|
||||
asprintf(&filename, "%spassphrases/%s", confbase, which);
|
||||
}
|
||||
else
|
||||
{
|
||||
asprintf(&filename, "%s/%s", (char*)cfg->data.ptr, which);
|
||||
}
|
||||
|
||||
if((f = fopen(filename, "rb")) == NULL)
|
||||
{
|
||||
if(debug_lvl > 1)
|
||||
syslog(LOG_ERR, _("Could not open %s: %m"), filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fscanf(f, "%d ", &size);
|
||||
if(size < 1 || size > (1<<15))
|
||||
{
|
||||
syslog(LOG_ERR, _("Illegal passphrase in %s; size would be %d"), filename, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Hmz... hackish... strange +1 and +2 stuff... I really like more comments on those alignment thingies! */
|
||||
|
||||
pp = xmalloc(size/4 + 1); /* Allocate enough for fgets */
|
||||
fgets(pp, size/4 + 1, f); /* Read passhrase and reserve one byte for end-of-string */
|
||||
fclose(f);
|
||||
|
||||
*out = xmalloc(size/8 + 2); /* Allocate enough bytes, +1 for rounding if bits%8 != 0, +1 for 2-byte alignment */
|
||||
cp
|
||||
return str_hex_to_bin(*out, pp);
|
||||
}
|
||||
|
||||
int read_my_passphrase(void)
|
||||
{
|
||||
cp
|
||||
if((mypassphraselen = read_passphrase("local", &mypassphrase)) < 0)
|
||||
return -1;
|
||||
cp
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generate_private_key(void)
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
char *s;
|
||||
config_t const *cfg;
|
||||
cp
|
||||
if((cfg = get_config_val(keyexpire)) == NULL)
|
||||
my_key_expiry = (time_t)(time(NULL) + 3600);
|
||||
else
|
||||
my_key_expiry = (time_t)(time(NULL) + cfg->data.val);
|
||||
|
||||
if(debug_lvl > 1)
|
||||
syslog(LOG_NOTICE, _("Generating %d bits keys"), PRIVATE_KEY_BITS);
|
||||
|
||||
if((f = fopen("/dev/urandom", "r")) == NULL)
|
||||
{
|
||||
syslog(LOG_ERR, _("Opening /dev/urandom failed: %m"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
s = xmalloc((2 * PRIVATE_KEY_LENGTH) + 1);
|
||||
|
||||
for(i = 0; i < PRIVATE_KEY_LENGTH; i++)
|
||||
sprintf(&s[i << 1], "%02x", fgetc(f));
|
||||
|
||||
s[2 * PRIVATE_KEY_LENGTH] = '\0';
|
||||
|
||||
mpz_set_str(my_private_key, s, 16);
|
||||
cp
|
||||
return 0;
|
||||
}
|
||||
|
||||
void calculate_public_key(void)
|
||||
{
|
||||
cp
|
||||
mpz_powm(my_public_key, generator, my_private_key, shared_prime);
|
||||
my_public_key_base36 = mpz_get_str(NULL, 36, my_public_key);
|
||||
cp
|
||||
}
|
||||
|
||||
unsigned char static_key[] = { 0x9c, 0xbf, 0x36, 0xa9, 0xce, 0x20, 0x1b, 0x8b, 0x67, 0x56, 0x21, 0x5d, 0x27, 0x1b, 0xd8, 0x7a };
|
||||
|
||||
int security_init(void)
|
||||
{
|
||||
cp
|
||||
mpz_init(my_private_key);
|
||||
mpz_init(my_public_key);
|
||||
mpz_init_set_str(shared_prime, ENCR_PRIME, 0);
|
||||
mpz_init_set_str(generator, ENCR_GENERATOR, 0);
|
||||
|
||||
if(read_my_passphrase() < 0)
|
||||
return -1;
|
||||
if(generate_private_key() < 0)
|
||||
return -1;
|
||||
|
||||
if(cipher_init(CIPHER_BLOWFISH) < 0)
|
||||
return -1;
|
||||
|
||||
calculate_public_key();
|
||||
cp
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_shared_key(char *almost_key)
|
||||
{
|
||||
char *tmp;
|
||||
int len;
|
||||
mpz_t ak, our_shared_key;
|
||||
cp
|
||||
mpz_init_set_str(ak, almost_key, 36);
|
||||
mpz_init(our_shared_key);
|
||||
mpz_powm(our_shared_key, ak, my_private_key, shared_prime);
|
||||
|
||||
tmp = mpz_get_str(NULL, 16, our_shared_key);
|
||||
len = str_hex_to_bin(text_key, tmp);
|
||||
|
||||
cipher_set_key(&encryption_key, len, text_key);
|
||||
key_inited = 1;
|
||||
encryption_keylen = len;
|
||||
|
||||
if(debug_lvl > 2)
|
||||
syslog(LOG_INFO, _("Encryption key set to %s"), tmp);
|
||||
|
||||
free(tmp);
|
||||
mpz_clear(ak);
|
||||
mpz_clear(our_shared_key);
|
||||
cp
|
||||
}
|
||||
|
||||
|
||||
void encrypt_passphrase(passphrase_t *pp)
|
||||
{
|
||||
char key[1000];
|
||||
char tmp[1000];
|
||||
unsigned char phrase[1000];
|
||||
int keylen;
|
||||
int i;
|
||||
BF_KEY bf_key;
|
||||
|
||||
cp
|
||||
mpz_get_str(tmp, 16, my_public_key);
|
||||
keylen = str_hex_to_bin(key, tmp);
|
||||
|
||||
cipher_set_key(&bf_key, keylen, key);
|
||||
|
||||
low_crypt_key(mypassphrase, phrase, &bf_key, mypassphraselen, BF_ENCRYPT);
|
||||
pp->len = ((mypassphraselen - 1) | 7) + 1;
|
||||
pp->phrase = xmalloc((pp->len << 1) + 1);
|
||||
|
||||
for(i = 0; i < pp->len; i++)
|
||||
snprintf(&(pp->phrase)[i << 1], 3, "%02x", (int)phrase[i]);
|
||||
|
||||
pp->phrase[(pp->len << 1) + 1] = '\0';
|
||||
|
||||
if(key_inited)
|
||||
cipher_set_key(&encryption_key, encryption_keylen, text_key);
|
||||
cp
|
||||
}
|
||||
|
||||
int verify_passphrase(conn_list_t *cl, unsigned char *his_pubkey)
|
||||
{
|
||||
char key[1000];
|
||||
char *tmp;
|
||||
unsigned char phrase[1000];
|
||||
int keylen, pplen;
|
||||
mpz_t pk;
|
||||
unsigned char *out;
|
||||
BF_KEY bf_key;
|
||||
char *which;
|
||||
char *meuk;
|
||||
cp
|
||||
mpz_init_set_str(pk, his_pubkey, 36);
|
||||
tmp = mpz_get_str(NULL, 16, pk);
|
||||
keylen = str_hex_to_bin(key, tmp);
|
||||
out = xmalloc((cl->pp->len >> 1) + 3);
|
||||
pplen = str_hex_to_bin(phrase, cl->pp->phrase);
|
||||
|
||||
cipher_set_key(&bf_key, keylen, key);
|
||||
low_crypt_key(phrase, out, &bf_key, pplen, BF_DECRYPT);
|
||||
if(key_inited)
|
||||
cipher_set_key(&encryption_key, encryption_keylen, text_key);
|
||||
|
||||
asprintf(&which, IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
|
||||
if((pplen = read_passphrase(which, &meuk)) < 0)
|
||||
return -1;
|
||||
|
||||
if(memcmp(meuk, out, pplen))
|
||||
return -1;
|
||||
cp
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *make_shared_key(char *pk)
|
||||
{
|
||||
mpz_t tmp, res;
|
||||
char *r;
|
||||
cp
|
||||
mpz_init_set_str(tmp, pk, 36);
|
||||
mpz_init(res);
|
||||
mpz_powm(res, tmp, my_private_key, shared_prime);
|
||||
|
||||
r = mpz_get_str(NULL, 36, res);
|
||||
|
||||
mpz_clear(res);
|
||||
mpz_clear(tmp);
|
||||
cp
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
free a key after overwriting it
|
||||
*/
|
||||
void free_key(enc_key_t *k)
|
||||
{
|
||||
cp
|
||||
if(!k)
|
||||
return;
|
||||
if(k->key)
|
||||
{
|
||||
memset(k->key, (char)(-1), k->length);
|
||||
free(k->key);
|
||||
}
|
||||
free(k);
|
||||
cp
|
||||
}
|
||||
|
||||
void recalculate_encryption_keys(void)
|
||||
{
|
||||
conn_list_t *p;
|
||||
char *ek;
|
||||
cp
|
||||
for(p = conn_list; p != NULL; p = p->next)
|
||||
{
|
||||
if(!p->public_key || !p->public_key->key)
|
||||
/* We haven't received a key from this host (yet). */
|
||||
continue;
|
||||
ek = make_shared_key(p->public_key->key);
|
||||
free_key(p->datakey);
|
||||
p->datakey = xmalloc(sizeof(*p->datakey));
|
||||
p->datakey->length = strlen(ek);
|
||||
p->datakey->expiry = p->public_key->expiry;
|
||||
p->datakey->key = xmalloc(strlen(ek) + 1);
|
||||
strcpy(p->datakey->key, ek);
|
||||
}
|
||||
cp
|
||||
}
|
||||
|
||||
void regenerate_keys(void)
|
||||
{
|
||||
cp
|
||||
generate_private_key();
|
||||
calculate_public_key();
|
||||
send_key_changed_all();
|
||||
recalculate_encryption_keys();
|
||||
cp
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue