From: Saverio Proto Date: Sat, 12 Apr 2014 14:56:05 +0000 (+0200) Subject: Merge branch 'master' into dirtydebug X-Git-Url: http://git.meshlink.io/?a=commitdiff_plain;h=1c1ea3e501944f1e49cb65add689d9cd6dea8af6;hp=7f7b53dc2011fc8ceda1e0678d9f78b1dbd8c1d1;p=meshlink Merge branch 'master' into dirtydebug --- diff --git a/Makefile.am b/Makefile.am index 0a4faef3..b2b85828 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = gnu -SUBDIRS = m4 src doc gui test +SUBDIRS = m4 src doc test ACLOCAL_AMFLAGS = -I m4 @@ -10,18 +10,3 @@ EXTRA_DIST = COPYING.README README.android ChangeLog: git log > ChangeLog - -deb: - dpkg-buildpackage -rfakeroot - -rpm: dist - cp $(distdir).tar.gz /usr/src/redhat/SOURCES/ - cp redhat/tinc.spec /usr/src/redhat/SOURCES/ - cd /usr/src/redhat/SOURCES/ && rpm -bb tinc.spec - -release: - rm -f ChangeLog - $(MAKE) ChangeLog - echo "Please edit the NEWS file now..." - /usr/bin/editor NEWS - $(MAKE) dist diff --git a/configure.ac b/configure.ac index eac66278..223f554d 100644 --- a/configure.ac +++ b/configure.ac @@ -74,40 +74,6 @@ case $host_os in ;; esac -AC_ARG_ENABLE(uml, - AS_HELP_STRING([--enable-uml], [enable support for User Mode Linux]), - [ AS_IF([test "x$enable_uml" = "xyes"], - [ AC_DEFINE(ENABLE_UML, 1, [Support for UML]) - uml=true - ], - [uml=false]) - ], - [uml=false] -) - -AC_ARG_ENABLE(vde, - AS_HELP_STRING([--enable-vde], [enable support for Virtual Distributed Ethernet]), - [ AS_IF([test "x$enable_vde" = "xyes"], - [ AC_CHECK_HEADERS(libvdeplug_dyn.h, [], [AC_MSG_ERROR([VDE plug header files not found.]); break]) - AC_DEFINE(ENABLE_VDE, 1, [Support for VDE]) - vde=true - ], - [vde=false]) - ], - [vde=false] -) - -AC_ARG_ENABLE(tunemu, - AS_HELP_STRING([--enable-tunemu], [enable support for the tunemu driver]), - [ AS_IF([test "x$enable_tunemu" = "xyes"], - [ AC_DEFINE(ENABLE_TUNEMU, 1, [Support for tunemu]) - tunemu=true - ], - [tunemu=false]) - ], - [tunemu=false] -) - AC_ARG_WITH(windows2000, AS_HELP_STRING([--with-windows2000], [compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks.]), [ AS_IF([test "x$with_windows2000" = "xyes"], @@ -210,32 +176,11 @@ AC_CACHE_SAVE dnl These are defined in files in m4/ -dnl AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], []) - -tinc_CURSES -tinc_READLINE tinc_ZLIB tinc_LZO -if test -n "$with_libgcrypt"; then - gcrypt=true - tinc_LIBGCRYPT -else - openssl=true - tinc_OPENSSL -fi +tinc_OPENSSL -AM_CONDITIONAL(OPENSSL, test -n "$openssl") -AM_CONDITIONAL(GCRYPT, test -n "$gcrypt") - -dnl Check if support for jumbograms is requested -AC_ARG_ENABLE(jumbograms, - AS_HELP_STRING([--enable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]), - [ AS_IF([test "x$enable_jumbograms" = "xyes"], - [ AC_DEFINE(ENABLE_JUMBOGRAMS, 1, [Support for jumbograms (packets up to 9000 bytes)]) ]) - ] -) - -AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile m4/Makefile gui/Makefile test/Makefile]) +AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile m4/Makefile test/Makefile]) AC_OUTPUT diff --git a/doc/Makefile.am b/doc/Makefile.am index a666d3bb..56d81e32 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -2,11 +2,11 @@ info_TEXINFOS = tinc.texi -man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 +man_MANS = -EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz +EXTRA_DIST = tincinclude.texi.in -CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi +CLEANFILES = *.html tincinclude.texi # Use `ginstall' in the definition of man_MANS to avoid # confusion with the `install' target. The install rule transforms `ginstall' @@ -16,39 +16,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 --exclude .svn sample-config - -tincd.8.html: tincd.8 - w3mman2html $? > $@ - -tinc.8.html: tinc.8 - w3mman2html $? > $@ - -tinc-gui.8.html: tinc-gui.8 - w3mman2html $? > $@ - -tinc.conf.5.html: tinc.conf.5 - w3mman2html $? > $@ - substitute = sed \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \ -e s,'@VERSION\@',"$(VERSION)",g \ -e s,'@sysconfdir\@',"$(sysconfdir)",g \ -e s,'@localstatedir\@',"$(localstatedir)",g -tincd.8: tincd.8.in - $(substitute) $? > $@ - -tinc.8: tinc.8.in - $(substitute) $? > $@ - -tinc-gui.8: tinc-gui.8.in - $(substitute) $? > $@ - -tinc.conf.5: tinc.conf.5.in - $(substitute) $? > $@ - tincinclude.texi: tincinclude.texi.in $(substitute) $? > $@ diff --git a/doc/tinc-gui.8.in b/doc/tinc-gui.8.in deleted file mode 100644 index f5ebadb2..00000000 --- a/doc/tinc-gui.8.in +++ /dev/null @@ -1,57 +0,0 @@ -.Dd 2011-06-26 -.Dt TINC-GUI 8 -.\" Manual page created by: -.\" Guus Sliepen -.Sh NAME -.Nm tinc-gui -.Nd tinc GUI -.Sh SYNOPSIS -.Nm -.Op Fl n -.Op Fl -net Ns = Ns Ar NETNAME -.Op Fl -pidfile Ns = Ns Ar FILENAME -.Op Fl -help -.Sh DESCRIPTION -This is a Python/wxWidgets based graphical user interface for tinc, a secure virtual private network (VPN) project. -.Nm -communicates with -.Xr tincd 8 -to alter and inspect the running VPN's state. -It can show the current settings, the list of connections, nodes, subnets, and edges. -For now, the debug level can be changed from the GUI, and by right-clicking on a node in the list of connections, -a pop-up menu will appear that allows one to disconnect that node. -.Sh OPTIONS -.Bl -tag -width indent -.It Fl n, -net Ns = Ns Ar NETNAME -Communicate with tincd(8) connected with -.Ar NETNAME . -.It Fl -pidfile Ns = Ns Ar FILENAME -Use the cookie from -.Ar FILENAME -to authenticate with a running tinc daemon. -If unspecified, the default is -.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid. -.It Fl -help -Display short list of options. -.El -.Sh BUGS -The GUI is not finished yet, the final version will have much more functionality. -If you find any bugs, report them to tinc@tinc-vpn.org. -.Sh SEE ALSO -.Xr tincd 8 , -.Pa http://www.tinc-vpn.org/ . -.Pp -The full documentation for 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 -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" -.An "Guus Sliepen" Aq guus@tinc-vpn.org -.Pp -And thanks to many others for their contributions to tinc! diff --git a/doc/tinc.8.in b/doc/tinc.8.in deleted file mode 100644 index 74f182a9..00000000 --- a/doc/tinc.8.in +++ /dev/null @@ -1,303 +0,0 @@ -.Dd 2014-01-16 -.Dt TINCCTL 8 -.\" Manual page created by: -.\" Scott Lamb -.Sh NAME -.Nm tinc -.Nd tinc VPN control -.Sh SYNOPSIS -.Nm -.Op Fl cn -.Op Fl -config Ns = Ns Ar DIR -.Op Fl -net Ns = Ns Ar NETNAME -.Op Fl -pidfile Ns = Ns Ar FILENAME -.Op Fl -help -.Op Fl -version -.Op Ar COMMAND -.Sh DESCRIPTION -This is the control program of tinc, a secure virtual private network (VPN) -project. -.Nm -can start and stop -.Xr tincd 8 , -and can to alter and inspect the state of a running VPN. -It can also be used to change the configuration, -or to import or export host configuration files from other nodes. - -If -.Nm -is started with a -.Ar COMMAND , -this command is immediately executed, after which -.Nm -exits. -If no -.Ar COMMAND -is given, -.Nm -will act as a shell; -it will display a prompt, and commands can be entered on the prompt. -If -.Nm -is compiled with libreadline, history and command completion are available on the prompt. -One can also pipe a script containing commands through -.Nm . -In that case, lines starting with a # symbol will be ignored. -.Sh OPTIONS -.Bl -tag -width indent -.It Fl n, -net Ns = Ns Ar NETNAME -Communicate with tincd(8) connected with -.Ar NETNAME . -.It Fl -pidfile Ns = Ns Ar FILENAME -Use the cookie from -.Ar FILENAME -to authenticate with a running tinc daemon. -If unspecified, the default is -.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid. -.It Fl -help -Display short list of options. -.It Fl -version -Output version information and exit. -.El -.Sh ENVIRONMENT VARIABLES -.Bl -tag -width indent -.It Ev NETNAME -If no netname is specified on the command line with the -.Fl n -option, the value of this environment variable is used. -.El -.Sh COMMANDS -.Bl -tag -width indent -.It init Op Ar name -Create initial configuration files and RSA and ECDSA keypairs with default length. -If no -.Ar name -for this node is given, it will be asked for. -.It get Ar variable -Print the current value of configuration variable -.Ar variable . -If more than one variable with the same name exists, -the value of each of them will be printed on a separate line. -.It set Ar variable Ar value -Set configuration variable -.Ar variable -to the given -.Ar value . -All previously existing configuration variables with the same name are removed. -To set a variable for a specific host, use the notation -.Ar host Ns Li . Ns Ar variable . -.It add Ar variable Ar value -As above, but without removing any previously existing configuration variables. -.It del Ar variable Op Ar value -Remove configuration variables with the same name and -.Ar value . -If no -.Ar value -is given, all configuration variables with the same name will be removed. -.It edit Ar filename -Start an editor for the given configuration file. -You do not need to specify the full path to the file. -.It export -Export the host configuration file of the local node to standard output. -.It export-all -Export all host configuration files to standard output. -.It import Op Fl -force -Import host configuration data generated by the -.Nm -export command from standard input. -Already existing host configuration files are not overwritten unless the option -.Fl -force -is used. -.It exchange Op Fl -force -The same as export followed by import. -.It exchange-all Op Fl -force -The same as export-all followed by import. -.It invite Ar name -Prepares an invitation for a new node with the given -.Ar name , -and prints a short invitation URL that can be used with the join command. -.It join Op Ar URL -Join an existing VPN using an invitation URL created using the invite command. -If no -.Ar URL -is given, it will be read from standard input. -.It start Op tincd options -Start -.Xr tincd 8 , -optionally with the given extra options. -.It stop -Stop -.Xr tincd 8 . -.It restart Op tincd options -Restart -.Xr tincd 8 , -optionally with the given extra options. -.It reload -Partially rereads configuration files. Connections to hosts whose host -config files are removed are closed. New outgoing connections specified -in -.Xr tinc.conf 5 -will be made. -.It pid -Shows the PID of the currently running -.Xr tincd 8 . -.It generate-keys Op bits -Generate both RSA and ECDSA keypairs (see below) and exit. -.It generate-ecdsa-keys -Generate public/private ECDSA keypair and exit. -.It generate-rsa-keys Op bits -Generate public/private RSA keypair and exit. -If -.Ar bits -is omitted, the default length will be 2048 bits. -When saving keys to existing files, tinc will not delete the old keys; -you have to remove them manually. -.It dump [reachable] nodes -Dump a list of all known nodes in the VPN. -If the keyword reachable is used, only lists reachable nodes. -.It dump edges -Dump a list of all known connections in the VPN. -.It dump subnets -Dump a list of all known subnets in the VPN. -.It dump connections -Dump a list of all meta connections with ourself. -.It dump graph | digraph -Dump a graph of the VPN in -.Xr dotty 1 -format. -Nodes are colored according to their reachability: -red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable. -Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet. -.It info Ar node | subnet | address -Show information about a particular node, subnet or address. -If an address is given, any matching subnet will be shown. -.It purge -Purges all information remembered about unreachable nodes. -.It debug Ar N -Sets debug level to -.Ar N . -.It log Op Ar N -Capture log messages from a running tinc daemon. -An optional debug level can be given that will be applied only for log messages sent to -.Nm tinc . -.It retry -Forces -.Xr tincd 8 -to try to connect to all uplinks immediately. -Usually -.Xr tincd 8 -attempts to do this itself, -but increases the time it waits between the attempts each time it failed, -and if -.Xr tincd 8 -didn't succeed to connect to an uplink the first time after it started, -it defaults to the maximum time of 15 minutes. -.It disconnect Ar NODE -Closes the meta connection with the given -.Ar NODE . -.It top -If -.Nm -is compiled with libcurses support, this will display live traffic statistics -for all the known nodes, similar to the UNIX -.Xr top 1 -command. -See below for more information. -.It pcap -Dump VPN traffic going through the local tinc node in -.Xr pcap-savefile 5 -format to standard output, -from where it can be redirected to a file or piped through a program that can parse it directly, -such as -.Xr tcpdump 8 . -.It network Op Ar netname -If -.Ar netname -is given, switch to that network. -Otherwise, display a list of all networks for which configuration files exist. -.El -.Sh EXAMPLES -Examples of some commands: -.Bd -literal -offset indent -tinc -n vpn dump graph | circo -Txlib -tinc -n vpn pcap | tcpdump -r - -tinc -n vpn top -.Pp -.Ed -Examples of changing the configuration using -.Nm : -.Bd -literal -offset indent -tinc -n vpn init foo -tinc -n vpn add Subnet 192.168.1.0/24 -tinc -n vpn add bar.Address bar.example.com -tinc -n vpn add ConnectTo bar -tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com -.Ed -.Sh TOP -The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters. -It displays a list of all the known nodes in the left-most column, -and the amount of bytes and packets read from and sent to each node in the other columns. -By default, the information is updated every second. -The behaviour of the top command can be changed using the following keys: -.Bl -tag -.It Ic s -Change the interval between updates. -After pressing the -.Ic s -key, enter the desired interval in seconds, followed by enter. -Fractional seconds are honored. -Intervals lower than 0.1 seconds are not allowed. -.It Ic c -Toggle between displaying current traffic rates (in packets and bytes per second) -and cumulative traffic (total packets and bytes since the tinc daemon started). -.It Ic n -Sort the list of nodes by name. -.It Ic i -Sort the list of nodes by incoming amount of bytes. -.It Ic I -Sort the list of nodes by incoming amount of packets. -.It Ic o -Sort the list of nodes by outgoing amount of bytes. -.It Ic O -Sort the list of nodes by outgoing amount of packets. -.It Ic t -Sort the list of nodes by sum of incoming and outgoing amount of bytes. -.It Ic T -Sort the list of nodes by sum of incoming and outgoing amount of packets. -.It Ic b -Show amount of traffic in bytes. -.It Ic k -Show amount of traffic in kilobytes. -.It Ic M -Show amount of traffic in megabytes. -.It Ic G -Show amount of traffic in gigabytes. -.It Ic q -Quit. -.El -.Sh BUGS -If you find any bugs, report them to tinc@tinc-vpn.org. -.Sh SEE ALSO -.Xr tincd 8 , -.Xr tinc.conf 5 , -.Xr dotty 1 , -.Xr pcap-savefile 5 , -.Xr tcpdump 8 , -.Xr top 1 , -.Pa http://www.tinc-vpn.org/ , -.Pa http://www.cabal.org/ . -.Pp -The full documentation for 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 -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" -.An "Guus Sliepen" Aq guus@tinc-vpn.org -.Pp -And thanks to many others for their contributions to tinc! diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in deleted file mode 100644 index 28296fb4..00000000 --- a/doc/tinc.conf.5.in +++ /dev/null @@ -1,717 +0,0 @@ -.Dd 2014-01-29 -.Dt TINC.CONF 5 -.\" Manual page created by: -.\" Ivo Timmermans -.\" Guus Sliepen -.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 -To distinguish multiple instances of tinc running on one computer, -you can use the -.Fl n -option to assign a network name to each tinc daemon. -.Pp -The effect of this option 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 , -and on Linux, unless specified otherwise, the name of the virtual network interface will be the same as the network name. -.Pp -It is recommended that you use network names even if you run only one instance of tinc. -However, you can choose not to use the -.Fl n -option. -In this case, the network name would just be empty, and -.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/ . -.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. -However, you are only allowed to use alphanumerical characters (a-z, A-Z, and 0-9) and underscores (_) in the name. -.Sh INITIAL CONFIGURATION -If you have not configured tinc yet, you can easily create a basic configuration using the following command: -.Bd -literal -offset indent -.Nm tinc Fl n Ar NETNAME Li init Ar NAME -.Ed -.Pp -You can further change the configuration as needed either by manually editing the configuration files, -or by using -.Xr tinc 8 . -.Sh PUBLIC/PRIVATE KEYS -The -.Nm tinc Li init -command will have generated both RSA and ECDSA public/private keypairs. -The private keys should be stored in files named -.Pa rsa_key.priv -and -.Pa ecdsa_key.priv -in the directory -.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa / -The public keys should be stored in the host configuration file -.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Va NAME . -The RSA keys are used for backwards compatibility with tinc version 1.0. -If you are upgrading from version 1.0 to 1.1, you can keep the old configuration files, -but you will need to create ECDSA keys using the following command: -.Bd -literal -offset indent -.Nm tinc Fl n Ar NETNAME Li generate-ecdsa-keys -.Ed -.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 -The server configuration is complemented with host specific configuration (see the next section). -Although all configuration options for the local host listed in this document can also be put in -.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf , -it is recommended to put host specific configuration options in the host configuration file, -as this makes it easy to exchange with other nodes. -.Pp -You can edit the config file manually, but it is recommended that you use -.Xr tinc 8 -to change configuration variables for you. -.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 AutoConnect Li = Ar count Po 0 Pc Bq experimental -If set to a non-zero value, -.Nm -will try to only have -.Ar count -meta connections to other nodes, -by automatically making or breaking connections to known nodes. -Higher values increase redundancy but also increase meta data overhead. -When using this option, a good value is 3. -.It Va BindToAddress Li = Ar address Op Ar port -This is the same as -.Va ListenAddress , -however the address given with the -.Va BindToAddress -option will also be used for outgoing connections. This is useful if your -computer has more than one IPv4 or IPv6 address, and you want -.Nm tinc -to only use a specific one for outgoing packets. -.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. -Also, on some platforms it will not actually bind to an interface, -but rather to the address that the interface has at the moment a socket is created. -.It Va Broadcast Li = no | mst | direct Po mst Pc Bq experimental -This option selects the way broadcast packets are sent to other daemons. -NOTE: all nodes in a VPN must use the same -.Va Broadcast -mode, otherwise routing loops can form. -.Bl -tag -width indent -.It no -Broadcast packets are never sent to other nodes. -.It mst -Broadcast packets are sent and forwarded via the VPN's Minimum Spanning Tree. -This ensures broadcast packets reach all nodes. -.It direct -Broadcast packets are sent directly to all nodes that can be reached directly. -Broadcast packets received from other nodes are never forwarded. -If the IndirectData option is also set, broadcast packets will only be sent to nodes which we have a meta connection to. -.El -.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 DecrementTTL Li = yes | no Po no Pc Bq experimental -When enabled, -.Nm tinc -will decrement the Time To Live field in IPv4 packets, or the Hop Limit field in IPv6 packets, -before forwarding a received packet to the virtual network device or to another node, -and will drop packets that have a TTL value of zero, -in which case it will send an ICMP Time Exceeded packet back. -.Pp -Do not use this option if you use switch mode and want to use IPv6. -.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 DeviceType Li = Ar type Pq platform dependent -The type of the virtual network device. -Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used. -However, this option can be used to select one of the special interface types, if support for them is compiled in. -.Bl -tag -width indent -.It dummy -Use a dummy interface. -No packets are ever read or written to a virtual network device. -Useful for testing, or when setting up a node that only forwards packets for other nodes. -.It raw_socket -Open a raw socket, and bind it to a pre-existing -.Va Interface -(eth0 by default). -All packets are read from this interface. -Packets received for the local node are written to the raw socket. -However, at least on Linux, the operating system does not process IP packets destined for the local host. -.It multicast -Open a multicast UDP socket and bind it to the address and port (separated by spaces) and optionally a TTL value specified using -.Va Device . -Packets are read from and written to this multicast socket. -This can be used to connect to UML, QEMU or KVM instances listening on the same multicast address. -Do NOT connect multiple -.Nm tinc -daemons to the same multicast address, this will very likely cause routing loops. -Also note that this can cause decrypted VPN packets to be sent out on a real network if misconfigured. -.It uml Pq not compiled in by default -Create a UNIX socket with the filename specified by -.Va Device , -or -.Pa @localstatedir@/run/ Ns Ar NETNAME Ns Pa .umlsocket -if not specified. -.Nm tinc -will wait for a User Mode Linux instance to connect to this socket. -.It vde Pq not compiled in by default -Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch, -using the UNIX socket specified by -.Va Device , -or -.Pa @localstatedir@/run/vde.ctl -if not specified. -.El -Also, in case tinc does not seem to correctly interpret packets received from the virtual network device, -it can be used to change the way packets are interpreted: -.Bl -tag -width indent -.It tun Pq BSD and Linux -Set type to tun. -Depending on the platform, this can either be with or without an address family header (see below). -.It tunnohead Pq BSD -Set type to tun without an address family header. -Tinc will expect packets read from the virtual network device to start with an IP header. -On some platforms IPv6 packets cannot be read from or written to the device in this mode. -.It tunifhead Pq BSD -Set type to tun with an address family header. -Tinc will expect packets read from the virtual network device -to start with a four byte header containing the address family, -followed by an IP header. -This mode should support both IPv4 and IPv6 packets. -.It tap Pq BSD and Linux -Set type to tap. -Tinc will expect packets read from the virtual network device -to start with an Ethernet header. -.El -.It Va DirectOnly Li = yes | no Po no Pc Bq experimental -When this option is enabled, packets that cannot be sent directly to the destination node, -but which would have to be forwarded by an intermediate node, are dropped instead. -When combined with the IndirectData option, -packets for nodes for which we do not have a meta connection with are also dropped. -.It Va ECDSAPrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /ecdsa_key.priv Pc -The file in which the private ECDSA key of this tinc daemon resides. -This is only used if -.Va ExperimentalProtocol -is enabled. -.It Va ExperimentalProtocol Li = yes | no Pq yes -When this option is enabled, the SPTPS protocol will be used when connecting to nodes that also support it. -Ephemeral ECDH will be used for key exchanges, -and ECDSA will be used instead of RSA for authentication. -When enabled, an ECDSA key must have been generated before with -.Nm tinc generate-ecdsa-keys . -.It Va Forwarding Li = off | internal | kernel Po internal Pc Bq experimental -This option selects the way indirect packets are forwarded. -.Bl -tag -width indent -.It off -Incoming packets that are not meant for the local node, -but which should be forwarded to another node, are dropped. -.It internal -Incoming packets that are meant for another node are forwarded by tinc internally. -.Pp -This is the default mode, and unless you really know you need another forwarding mode, don't change it. -.It kernel -Incoming packets are always sent to the TUN/TAP device, even if the packets are not for the local node. -This is less efficient, but allows the kernel to apply its routing and firewall rules on them, -and can also help debugging. -.El -.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, but whether hostnames should be resolved while logging. -.It Va IffOneQueue Li = yes | no Po no Pc Bq experimental -(Linux only) Set IFF_ONE_QUEUE flag on TUN/TAP devices. -.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 ListenAddress Li = Ar address Op Ar port -If your computer has more than one IPv4 or IPv6 address, -.Nm tinc -will by default listen on all of them for incoming connections. -This option can be used to restrict which addresses tinc listens on. -Multiple -.Va ListenAddress -variables may be specified, -in which case listening sockets for each specified address are made. -.Pp -If no -.Ar port -is specified, the socket will listen on the port specified by the -.Va Port -option, or to port 655 if neither is given. -To only listen on a specific port but not on a specific address, use -.Li * -for the -.Ar address . -.It Va LocalDiscovery Li = yes | no Pq no -When enabled, -.Nm tinc -will try to detect peers that are on the same local network. -This will allow direct communication using LAN addresses, even if both peers are behind a NAT -and they only ConnectTo a third node outside the NAT, -which normally would prevent the peers from learning each other's LAN address. -.Pp -Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery. -This feature may not work in all possible situations. -.It Va LocalDiscoveryAddress Li = Ar address -If this variable is specified, local discovery packets are sent to the given -.Ar address . -.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 MaxConnectionBurst Li = Ar count Pq 100 -This option controls how many connections tinc accepts in quick succession. -If there are more connections than the given number in a short time interval, -tinc will reduce the number of accepted connections to only one per second, -until the burst has passed. -.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 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. -The Name may only consist of alphanumeric and underscore characters (a-z, A-Z, 0-9 and _), and is case sensitive. -If -.Va Name -starts with a -.Li $ , -then the contents of the environment variable that follows will be used. -In that case, invalid characters will be converted to underscores. -If -.Va Name -is -.Li $HOST , -but no such environment variable exist, the hostname will be read using the gethostname() system call. -.It Va PingInterval Li = Ar seconds Pq 60 -The number of seconds of inactivity that -.Nm tinc -will wait before sending a probe to the other end. -.It Va PingTimeout Li = Ar seconds Pq 5 -The number of seconds to wait for a response to pings or to allow meta -connections to block. If the other end doesn't respond within this 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. -.It Va ProcessPriority Li = low | normal | high -When this option is used the priority of the -.Nm tincd -process will be adjusted. -Increasing the priority may help to reduce latency and packet loss on the VPN. -.It Va Proxy Li = socks4 | socks5 | http | exec Ar ... Bq experimental -Use a proxy when making outgoing connections. -The following proxy types are currently supported: -.Bl -tag -width indent -.It socks4 Ar address Ar port Op Ar username -Connects to the proxy using the SOCKS version 4 protocol. -Optionally, a -.Ar username -can be supplied which will be passed on to the proxy server. -Only IPv4 connections can be proxied using SOCKS 4. -.It socks5 Ar address Ar port Op Ar username Ar password -Connect to the proxy using the SOCKS version 5 protocol. -If a -.Ar username -and -.Ar password -are given, basic username/password authentication will be used, -otherwise no authentication will be used. -.It http Ar address Ar port -Connects to the proxy and sends a HTTP CONNECT request. -.It exec Ar command -Executes the given -.Ar command -which should set up the outgoing connection. -The environment variables -.Ev NAME , -.Ev NODE , -.Ev REMOTEADDRES -and -.Ev REMOTEPORT -are available. -.El -.It Va ReplayWindow Li = Ar bytes Pq 16 -This is the size of the replay tracking window for each remote node, in bytes. -The window is a bitfield which tracks 1 packet per bit, so for example -the default setting of 16 will track up to 128 packets in the window. In high -bandwidth scenarios, setting this to a higher value can reduce packet loss from -the interaction of replay tracking with underlying real packet loss and/or -reordering. Setting this to zero will disable replay tracking completely and -pass all traffic, but leaves tinc vulnerable to replay-based attacks on your -traffic. -.It Va StrictSubnets Li = yes | no Po no Pc Bq experimental -When this option is enabled tinc will only use Subnet statements which are -present in the host config files in the local -.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ -directory. Subnets learned via connections to other nodes and which are not -present in the local host config files are ignored. -.It Va TunnelServer Li = yes | no Po no Pc Bq experimental -When this option is enabled tinc will no longer forward information between other tinc daemons, -and will only allow connections with nodes for which host config files are present in the local -.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ -directory. -Setting this options also implicitly sets StrictSubnets. -.It Va UDPRcvBuf Li = Ar bytes Pq OS default -Sets the socket receive buffer size for the UDP socket, in bytes. -If unset, the default buffer size will be used by the operating system. -.It Va UDPSndBuf Li = Ar bytes Pq OS default -Sets the socket send buffer size for the UDP socket, in bytes. -If unset, the default buffer size will be used by the operating system. -.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 Oo Ar port Oc Bq recommended -The IP address or hostname of this tinc daemon on the real network. -This will only be used when trying to make an outgoing connection to this tinc daemon. -Optionally, a port can be specified to use for this address. -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 is best to use only those ciphers which support CBC mode. -This option has no effect for connections between nodes using -.Va ExperimentalProtocol . -.It Va ClampMSS Li = yes | no Pq yes -This option specifies whether tinc should clamp the maximum segment size (MSS) -of TCP packets to the path MTU. This helps in situations where ICMP -Fragmentation Needed or Packet too Big messages are dropped by firewalls. -.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. -This option has no effect for connections between nodes using -.Va ExperimentalProtocol . -.It Va IndirectData Li = yes | no Pq no -When set to yes, other nodes which do not already have a meta connection to you -will not try to establish direct communication with you. -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. -This option has no effect for connections between nodes using -.Va ExperimentalProtocol . -.It Va PMTU Li = Ar mtu Po 1514 Pc -This option controls the initial path MTU to this node. -.It Va PMTUDiscovery Li = yes | no Po yes Pc -When this option is enabled, tinc will try to discover the path MTU to this node. -After the path MTU has been discovered, it will be enforced on the VPN. -.It Va Port Li = Ar port Pq 655 -The port number on which this tinc daemon is listening for incoming connections, -which is used if no port number is specified in an -.Va Address -statement. -.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 Ns Op Li # Ns Ar weight -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. -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::/64. -MAC addresses are notated like 0:1a:2b:3c:4d:5e. -.Pp -A Subnet can be given a weight to indicate its priority over identical Subnets -owned by different nodes. The default weight is 10. Lower values indicate -higher priority. Packets will be sent to the node with the highest priority, -unless that node is not reachable, in which case the node with the next highest -priority will be tried, and so on. -.It Va TCPOnly Li = yes | no Pq no Bq obsolete -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. -.Pp -Since version 1.0.10, tinc will automatically detect whether communication via -UDP is possible or not. -.It Va Weight Li = Ar weight -If this variable is set, it overrides the weight given to connections made with -another host. A higher -.Ar weight -means a lower priority is given to this connection when broadcasting or -forwarding packets. -.El -.Sh SCRIPTS -Apart from reading the server and host configuration files, -tinc can also run scripts at certain moments. -Under Windows (not Cygwin), the scripts should have the extension -.Pa .bat -or -.Pa cmd . -.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. -.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-up -This script is started when any host becomes reachable. -.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-down -This script is started when any host becomes unreachable. -.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-up -This script is started when a Subnet becomes reachable. -The Subnet and the node it belongs to are passed in environment variables. -.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-down -This script is started when a Subnet becomes unreachable. -.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitation-created -This script is started when a new invitation has been created. -.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitation-accepted -This script is started when an invitation has been used. -.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 -or -.Pa .cmd -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. -If a subnet becomes (un)reachable, this is set to the owner of that subnet. -.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. -.It Ev SUBNET -When a subnet becomes (un)reachable, this is set to the subnet. -.It Ev WEIGHT -When a subnet becomes (un)reachable, this is set to the subnet weight. -.It Ev INVITATION_FILE -When the -.Pa invitation-created -script is called, this is set to the file where the invitation details will be stored. -.It Ev INVITATION_URL -When the -.Pa invitation-created -script is called, this is set to the invitation URL that has been created. -.El -.Pp -Do not forget that under UNIX operating systems, you have to make the scripts executable, using the command -.Nm chmod Li a+x Pa script . -.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 /conf.d/ -Optional directory from which any .conf file will be loaded -.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 , -.Xr tinc 8 , -.Pa http://www.tinc-vpn.org/ , -.Pa http://www.tldp.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. diff --git a/doc/tincd.8.in b/doc/tincd.8.in deleted file mode 100644 index 3c5886b1..00000000 --- a/doc/tincd.8.in +++ /dev/null @@ -1,207 +0,0 @@ -.Dd 2013-01-14 -.Dt TINCD 8 -.\" Manual page created by: -.\" Ivo Timmermans -.\" Guus Sliepen -.Sh NAME -.Nm tincd -.Nd tinc VPN daemon -.Sh SYNOPSIS -.Nm -.Op Fl cdDKnoLRU -.Op Fl -config Ns = Ns Ar DIR -.Op Fl -no-detach -.Op Fl -debug Ns Op = Ns Ar LEVEL -.Op Fl -net Ns = Ns Ar NETNAME -.Op Fl -option Ns = Ns Ar [HOST.]KEY=VALUE -.Op Fl -mlock -.Op Fl -logfile Ns Op = Ns Ar FILE -.Op Fl -bypass-security -.Op Fl -chroot -.Op Fl -user Ns = Ns Ar USER -.Op Fl -help -.Op Fl -version -.Sh DESCRIPTION -This is the daemon of tinc, a secure virtual private network (VPN) project. -When started, -.Nm -will read it's configuration file to determine what virtual subnets it has to serve -and to what other tinc daemons it should connect. -It will connect to the ethertap or tun/tap device -and set up a socket for incoming connections. -Optionally a script will be executed to further configure the virtual device. -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 c, -config Ns = Ns 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 n, -net Ns = Ns Ar NETNAME -Connect to net -.Ar NETNAME . -This will let tinc read all configuration files from -.Pa @sysconfdir@/tinc/ Ar NETNAME . -Specifying -.Li . -for -.Ar NETNAME -is the same as not specifying any -.Ar NETNAME . -.It Fl o, -option Ns = Ns Ar [HOST.]KEY=VALUE -Without specifying a -.Ar HOST , -this will set server configuration variable -.Ar KEY -to -.Ar VALUE . -If specified as -.Ar HOST.KEY=VALUE , -this will set the host configuration variable -.Ar KEY -of the host named -.Ar HOST -to -.Ar VALUE . -This option can be used more than once to specify multiple configuration variables. -.It Fl L, -mlock -Lock tinc into main memory. -This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. -This option is not supported on all platforms. -.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 FILENAME -Store a cookie in -.Ar FILENAME -which allows -.Xr tinc 8 -to authenticate. -If -.Ar FILE -is omitted, the default is -.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid. -.It Fl -bypass-security -Disables encryption and authentication of the meta protocol. -Only useful for debugging. -.It Fl R, -chroot -With this option tinc chroots into the directory where network -config is located (@sysconfdir@/tinc/NETNAME if -n option is used, -or to the directory specified with -c option) after initialization. -This option is not supported on all platforms. -.It Fl U, -user Ns = Ns Ar USER -setuid to the specified -.Ar USER -after initialization. -This option is not supported on all platforms. -.It Fl -help -Display short list of options. -.It Fl -version -Output version information and exit. -.El -.Sh SIGNALS -.Bl -tag -width indent -.It ALRM -Forces -.Nm -to try to connect to all uplinks immediately. -Usually -.Nm -attempts to do this itself, -but increases the time it waits between the attempts each time it failed, -and if -.Nm -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 -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. -If the -.Fl -logfile -option is used, this will also close and reopen the log file, -useful when log rotation is used. -.El -.Sh DEBUG LEVELS -The tinc daemon can send a lot of messages to the syslog. -The higher the debug level, -the more messages it will log. -Each level inherits all messages of the previous level: -.Bl -tag -width indent -.It 0 -This will log a message indicating -.Nm -has started along with a version number. -It will also log 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 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. -.It 4 -This will log a copy of everything received on the meta socket. -.It 5 -This will log all network traffic over the virtual private network. -.El -.Sh FILES -.Bl -tag -width indent -.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. -.El -.Sh BUGS -The -.Va BindToInterface -option may not work correctly. -.Pp -.Sy The cryptography in tinc is not well tested yet. Use it at your own risk! -.Pp -If you find any bugs, report them to tinc@tinc-vpn.org. -.Sh TODO -A lot, especially security auditing. -.Sh SEE ALSO -.Xr tinc 8 , -.Xr tinc.conf 5 , -.Pa http://www.tinc-vpn.org/ , -.Pa http://www.cabal.org/ . -.Pp -The full documentation for 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 -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" -.An "Guus Sliepen" Aq guus@tinc-vpn.org -.Pp -And thanks to many others for their contributions to tinc! diff --git a/gui/Makefile.am b/gui/Makefile.am deleted file mode 100644 index 4f2c7fe8..00000000 --- a/gui/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -dist_bin_SCRIPTS = tinc-gui - -extra_DIST = README.gui diff --git a/gui/README.gui b/gui/README.gui deleted file mode 100644 index da09dfb4..00000000 --- a/gui/README.gui +++ /dev/null @@ -1,24 +0,0 @@ -This experimental GUI is written in Python with wxPython widgets. You need to -have both installed for it to work. After starting tinc with either tincd or -tincctl, you can start the gui: - -tincd -n vpn -tinc-gui -n vpn - -If the GUI cannot find the pid file (for example if it is not in -/var/run), you can specify its location manually: - -tinc-gui --pidfile /usr/local/var/run/tinc.vpn.pid - -The following things sort of work: - -- Changing the debug level from the settings page -- Viewing the list of connections, nodes, edges and subnets. These lists will - be refreshed once per second. -- Right-clicking on a connection brings up a popup menu, which allows you to - close a connection. - -Python was chosen to enable rapid application development, wxWidgets for its -cross-platform compatibility and platform-native widgets. Once the GUI is -matured, it will probably rewritten in C++ to allow static linking and easy -distribution, without needing to install both Python and wxWidgets. diff --git a/gui/tinc-gui b/gui/tinc-gui deleted file mode 100755 index f1a9bbfc..00000000 --- a/gui/tinc-gui +++ /dev/null @@ -1,620 +0,0 @@ -#!/usr/bin/python - -# tinc-gui -- GUI for controlling a running tincd -# Copyright (C) 2009-2014 Guus Sliepen -# 2014 Dennis Joachimsthaler -# -# 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., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -import string -import socket -import wx -import sys -import os -import platform -import time -from wx.lib.mixins.listctrl import ColumnSorterMixin -from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin - -if platform.system() == 'Windows': - import _winreg - -# Classes to interface with a running tinc daemon - -REQ_STOP = 0 -REQ_RELOAD = 1 -REQ_RESTART = 2 -REQ_DUMP_NODES = 3 -REQ_DUMP_EDGES = 4 -REQ_DUMP_SUBNETS = 5 -REQ_DUMP_CONNECTIONS = 6 -REQ_DUMP_GRAPH = 7 -REQ_PURGE = 8 -REQ_SET_DEBUG = 9 -REQ_RETRY = 10 -REQ_CONNECT = 11 -REQ_DISCONNECT = 12 - -ID = 0 -ACK = 4 -CONTROL = 18 - -class Node: - def parse(self, args): - self.name = args[0] - self.address = args[1] - self.port = args[3] - self.cipher = int(args[4]) - self.digest = int(args[5]) - self.maclength = int(args[6]) - self.compression = int(args[7]) - self.options = int(args[8], 0x10) - self.status = int(args[9], 0x10) - self.nexthop = args[10] - self.via = args[11] - self.distance = int(args[12]) - self.pmtu = int(args[13]) - self.minmtu = int(args[14]) - self.maxmtu = int(args[15]) - self.last_state_change = float(args[16]) - - self.subnets = {} - -class Edge: - def parse(self, args): - self.fr = args[0] - self.to = args[1] - self.address = args[2] - self.port = args[4] - self.options = int(args[5], 16) - self.weight = int(args[6]) - -class Subnet: - def parse(self, args): - if args[0].find('#') >= 0: - (address, self.weight) = args[0].split('#', 1) - else: - self.weight = 10 - address = args[0] - - if address.find('/') >= 0: - (self.address, self.prefixlen) = address.split('/', 1) - else: - self.address = address - self.prefixlen = '48' - - self.owner = args[1] - -class Connection: - def parse(self, args): - self.name = args[0] - self.address = args[1] - self.port = args[3] - self.options = int(args[4], 0x10) - self.socket = int(args[5]) - self.status = int(args[6], 0x10) - self.weight = 123 - -class VPN: - confdir = '/etc/tinc' - piddir = '/var/run/' - - def connect(self): - # read the pidfile - f = open(self.pidfile) - info = string.split(f.readline()) - f.close() - - # check if there is a UNIX socket as well - if self.pidfile.endswith(".pid"): - unixfile = self.pidfile.replace(".pid", ".socket"); - else: - unixfile = self.pidfile + ".socket"; - - if os.path.exists(unixfile): - # use it if it exists - print(unixfile + " exists!"); - s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - s.connect(unixfile) - else: - # otherwise connect via TCP - print(unixfile + " does not exist."); - if ':' in info[2]: - af = socket.AF_INET6 - else: - af = socket.AF_INET - s = socket.socket(af, socket.SOCK_STREAM) - s.connect((info[2], int(info[4]))) - - self.sf = s.makefile() - s.close() - hello = string.split(self.sf.readline()) - self.name = hello[1] - self.sf.write('0 ^' + info[1] + ' 17\r\n') - self.sf.flush() - resp = string.split(self.sf.readline()) - self.port = info[4] - self.nodes = {} - self.edges = {} - self.subnets = {} - self.connections = {} - self.refresh() - - def refresh(self): - self.sf.write('18 3\r\n18 4\r\n18 5\r\n18 6\r\n') - self.sf.flush() - - for node in self.nodes.values(): - node.visited = False - for edge in self.edges.values(): - edge.visited = False - for subnet in self.subnets.values(): - subnet.visited = False - for connections in self.connections.values(): - connections.visited = False - - while True: - resp = string.split(self.sf.readline()) - if len(resp) < 2: - break - if resp[0] != '18': - break - if resp[1] == '3': - if len(resp) < 19: - continue - node = self.nodes.get(resp[2]) or Node() - node.parse(resp[2:]) - node.visited = True - self.nodes[resp[2]] = node - elif resp[1] == '4': - if len(resp) < 9: - continue - edge = self.nodes.get((resp[2], resp[3])) or Edge() - edge.parse(resp[2:]) - edge.visited = True - self.edges[(resp[2], resp[3])] = edge - elif resp[1] == '5': - if len(resp) < 4: - continue - subnet = self.subnets.get((resp[2], resp[3])) or Subnet() - subnet.parse(resp[2:]) - subnet.visited = True - self.subnets[(resp[2], resp[3])] = subnet - self.nodes[subnet.owner].subnets[resp[2]] = subnet - elif resp[1] == '6': - if len(resp) < 9: - break - connection = self.connections.get((resp[2], resp[3], resp[5])) or Connection() - connection.parse(resp[2:]) - connection.visited = True - self.connections[(resp[2], resp[3], resp[5])] = connection - else: - break - - for key, subnet in self.subnets.items(): - if not subnet.visited: - del self.subnets[key] - - for key, edge in self.edges.items(): - if not edge.visited: - del self.edges[key] - - for key, node in self.nodes.items(): - if not node.visited: - del self.nodes[key] - else: - for key, subnet in node.subnets.items(): - if not subnet.visited: - del node.subnets[key] - - for key, connection in self.connections.items(): - if not connection.visited: - del self.connections[key] - - def close(self): - self.sf.close() - - def disconnect(self, name): - self.sf.write('18 12 ' + name + '\r\n') - self.sf.flush() - resp = string.split(self.sf.readline()) - - def debug(self, level = -1): - self.sf.write('18 9 ' + str(level) + '\r\n') - self.sf.flush() - resp = string.split(self.sf.readline()) - return int(resp[2]) - - def __init__(self, netname = None, pidfile = None): - if platform.system() == 'Windows': - sam = _winreg.KEY_READ - if platform.machine().endswith('64'): - sam = sam | _winreg.KEY_WOW64_64KEY - try: - reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - try: - key = _winreg.OpenKey(reg, "SOFTWARE\\tinc", 0, sam) - except WindowsError: - key = _winreg.OpenKey(reg, "SOFTWARE\\Wow6432Node\\tinc", 0, sam) - VPN.confdir = _winreg.QueryValue(key, None) - except WindowsError: - pass - - if netname: - self.netname = netname - self.confbase = os.path.join(VPN.confdir, netname) - else: - self.confbase = VPN.confdir - - self.tincconf = os.path.join(self.confbase, 'tinc.conf') - - if pidfile != None: - self.pidfile = pidfile - else: - if platform.system() == 'Windows': - self.pidfile = os.path.join(self.confbase, 'pid') - else: - if netname: - self.pidfile = os.path.join(VPN.piddir, 'tinc.' + netname + '.pid') - else: - self.pidfile = os.path.join(VPN.piddir, 'tinc.pid') - -# GUI starts here - -argv0 = sys.argv[0] -del sys.argv[0] -netname = None -pidfile = None - -def usage(exitcode = 0): - print('Usage: ' + argv0 + ' [options]') - print('\nValid options are:') - print(' -n, --net=NETNAME Connect to net NETNAME.') - print(' --pidfile=FILENAME Read control cookie from FILENAME.') - print(' --help Display this help and exit.') - print('\nReport bugs to tinc@tinc-vpn.org.') - sys.exit(exitcode) - -while sys.argv: - if sys.argv[0] in ('-n', '--net'): - del sys.argv[0] - netname = sys.argv[0] - elif sys.argv[0] in ('--pidfile'): - del sys.argv[0] - pidfile = sys.argv[0] - elif sys.argv[0] in ('--help'): - usage(0) - else: - print(argv0 + ': unrecognized option \'' + sys.argv[0] + '\'') - usage(1) - - del sys.argv[0] - -if netname == None: - netname = os.getenv("NETNAME") - -if netname == ".": - netname = None - -vpn = VPN(netname, pidfile) -vpn.connect() - -class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin): - def __init__(self, parent, style): - wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES) - ListCtrlAutoWidthMixin.__init__(self) - ColumnSorterMixin.__init__(self, 16) - - def GetListCtrl(self): - return self - - -class SettingsPage(wx.Panel): - def OnDebugLevel(self, event): - vpn.debug(self.debug.GetValue()) - - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - grid = wx.FlexGridSizer(cols = 2) - grid.AddGrowableCol(1, 1) - - namelabel = wx.StaticText(self, -1, 'Name:') - self.name = wx.TextCtrl(self, -1, vpn.name) - grid.Add(namelabel) - grid.Add(self.name, 1, wx.EXPAND) - - portlabel = wx.StaticText(self, -1, 'Port:') - self.port = wx.TextCtrl(self, -1, vpn.port) - grid.Add(portlabel) - grid.Add(self.port) - - debuglabel = wx.StaticText(self, -1, 'Debug level:') - self.debug = wx.SpinCtrl(self, min = 0, max = 5, initial = vpn.debug()) - self.debug.Bind(wx.EVT_SPINCTRL, self.OnDebugLevel) - grid.Add(debuglabel) - grid.Add(self.debug) - - modelabel = wx.StaticText(self, -1, 'Mode:') - self.mode = wx.ComboBox(self, -1, style = wx.CB_READONLY, value = 'Router', choices = ['Router', 'Switch', 'Hub']) - grid.Add(modelabel) - grid.Add(self.mode) - - self.SetSizer(grid) - -class ConnectionsPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - self.list = SuperListCtrl(self, id) - self.list.InsertColumn(0, 'Name') - self.list.InsertColumn(1, 'Address') - self.list.InsertColumn(2, 'Port') - self.list.InsertColumn(3, 'Options') - self.list.InsertColumn(4, 'Weight') - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add(self.list, 1, wx.EXPAND) - self.SetSizer(hbox) - self.refresh() - - class ContextMenu(wx.Menu): - def __init__(self, item): - wx.Menu.__init__(self) - - self.item = item - - disconnect = wx.MenuItem(self, -1, 'Disconnect') - self.AppendItem(disconnect) - self.Bind(wx.EVT_MENU, self.OnDisconnect, id=disconnect.GetId()) - - def OnDisconnect(self, event): - vpn.disconnect(self.item[0]) - - def OnContext(self, event): - i = event.GetIndex() - self.PopupMenu(self.ContextMenu(self.list.itemDataMap[event.GetIndex()]), event.GetPosition()) - - def refresh(self): - sortstate = self.list.GetSortState() - self.list.itemDataMap = {} - i = 0 - - for key, connection in vpn.connections.items(): - if self.list.GetItemCount() <= i: - self.list.InsertStringItem(i, connection.name) - else: - self.list.SetStringItem(i, 0, connection.name) - self.list.SetStringItem(i, 1, connection.address) - self.list.SetStringItem(i, 2, connection.port) - self.list.SetStringItem(i, 3, str(connection.options)) - self.list.SetStringItem(i, 4, str(connection.weight)) - self.list.itemDataMap[i] = (connection.name, connection.address, connection.port, connection.options, connection.weight) - self.list.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnContext) - self.list.SetItemData(i, i) - i += 1 - - while self.list.GetItemCount() > i: - self.list.DeleteItem(self.list.GetItemCount() - 1) - - self.list.SortListItems(sortstate[0], sortstate[1]) - -class NodesPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - self.list = SuperListCtrl(self, id) - self.list.InsertColumn( 0, 'Name') - self.list.InsertColumn( 1, 'Address') - self.list.InsertColumn( 2, 'Port') - self.list.InsertColumn( 3, 'Cipher') - self.list.InsertColumn( 4, 'Digest') - self.list.InsertColumn( 5, 'MACLength') - self.list.InsertColumn( 6, 'Compression') - self.list.InsertColumn( 7, 'Options') - self.list.InsertColumn( 8, 'Status') - self.list.InsertColumn( 9, 'Nexthop') - self.list.InsertColumn(10, 'Via') - self.list.InsertColumn(11, 'Distance') - self.list.InsertColumn(12, 'PMTU') - self.list.InsertColumn(13, 'Min MTU') - self.list.InsertColumn(14, 'Max MTU') - self.list.InsertColumn(15, 'Since') - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add(self.list, 1, wx.EXPAND) - self.SetSizer(hbox) - self.refresh() - - def refresh(self): - sortstate = self.list.GetSortState() - self.list.itemDataMap = {} - i = 0 - - for key, node in vpn.nodes.items(): - if self.list.GetItemCount() <= i: - self.list.InsertStringItem(i, node.name) - else: - self.list.SetStringItem(i, 0, node.name) - self.list.SetStringItem(i, 1, node.address) - self.list.SetStringItem(i, 2, node.port) - self.list.SetStringItem(i, 3, str(node.cipher)) - self.list.SetStringItem(i, 4, str(node.digest)) - self.list.SetStringItem(i, 5, str(node.maclength)) - self.list.SetStringItem(i, 6, str(node.compression)) - self.list.SetStringItem(i, 7, format(node.options, "x")) - self.list.SetStringItem(i, 8, format(node.status, "04x")) - self.list.SetStringItem(i, 9, node.nexthop) - self.list.SetStringItem(i, 10, node.via) - self.list.SetStringItem(i, 11, str(node.distance)) - self.list.SetStringItem(i, 12, str(node.pmtu)) - self.list.SetStringItem(i, 13, str(node.minmtu)) - self.list.SetStringItem(i, 14, str(node.maxmtu)) - if node.last_state_change: - since = time.strftime("%Y-%m-%d %H:%M", time.localtime(node.last_state_change)) - else: - since = "never" - self.list.SetStringItem(i, 15, since) - self.list.itemDataMap[i] = (node.name, node.address, node.port, node.cipher, node.digest, node.maclength, node.compression, node.options, node.status, node.nexthop, node.via, node.distance, node.pmtu, node.minmtu, node.maxmtu, since) - self.list.SetItemData(i, i) - i += 1 - - while self.list.GetItemCount() > i: - self.list.DeleteItem(self.list.GetItemCount() - 1) - - self.list.SortListItems(sortstate[0], sortstate[1]) - -class EdgesPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - self.list = SuperListCtrl(self, id) - self.list.InsertColumn(0, 'From') - self.list.InsertColumn(1, 'To') - self.list.InsertColumn(2, 'Address') - self.list.InsertColumn(3, 'Port') - self.list.InsertColumn(4, 'Options') - self.list.InsertColumn(5, 'Weight') - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add(self.list, 1, wx.EXPAND) - self.SetSizer(hbox) - self.refresh() - - def refresh(self): - sortstate = self.list.GetSortState() - self.list.itemDataMap = {} - i = 0 - - for key, edge in vpn.edges.items(): - if self.list.GetItemCount() <= i: - self.list.InsertStringItem(i, edge.fr) - else: - self.list.SetStringItem(i, 0, edge.fr) - self.list.SetStringItem(i, 1, edge.to) - self.list.SetStringItem(i, 2, edge.address) - self.list.SetStringItem(i, 3, edge.port) - self.list.SetStringItem(i, 4, format(edge.options, "x")) - self.list.SetStringItem(i, 5, str(edge.weight)) - self.list.itemDataMap[i] = (edge.fr, edge.to, edge.address, edge.port, edge.options, edge.weight) - self.list.SetItemData(i, i) - i += 1 - - while self.list.GetItemCount() > i: - self.list.DeleteItem(self.list.GetItemCount() - 1) - - self.list.SortListItems(sortstate[0], sortstate[1]) - -class SubnetsPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - self.list = SuperListCtrl(self, id) - self.list.InsertColumn(0, 'Subnet', wx.LIST_FORMAT_RIGHT) - self.list.InsertColumn(1, 'Weight', wx.LIST_FORMAT_RIGHT) - self.list.InsertColumn(2, 'Owner') - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add(self.list, 1, wx.EXPAND) - self.SetSizer(hbox) - self.refresh() - - def refresh(self): - sortstate = self.list.GetSortState() - self.list.itemDataMap = {} - i = 0 - - for key, subnet in vpn.subnets.items(): - if self.list.GetItemCount() <= i: - self.list.InsertStringItem(i, subnet.address + '/' + subnet.prefixlen) - else: - self.list.SetStringItem(i, 0, subnet.address + '/' + subnet.prefixlen) - self.list.SetStringItem(i, 1, subnet.weight) - self.list.SetStringItem(i, 2, subnet.owner) - self.list.itemDataMap[i] = (subnet.address + '/' + subnet.prefixlen, subnet.weight, subnet.owner) - self.list.SetItemData(i, i) - i += 1 - - while self.list.GetItemCount() > i: - self.list.DeleteItem(self.list.GetItemCount() - 1) - - self.list.SortListItems(sortstate[0], sortstate[1]) - -class StatusPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - -class GraphPage(wx.Window): - def __init__(self, parent, id): - wx.Window.__init__(self, parent, id) - -class NetPage(wx.Notebook): - def __init__(self, parent, id): - wx.Notebook.__init__(self, parent) - self.settings = SettingsPage(self, id) - self.connections = ConnectionsPage(self, id) - self.nodes = NodesPage(self, id) - self.edges = EdgesPage(self, id) - self.subnets = SubnetsPage(self, id) - self.graph = GraphPage(self, id) - self.status = StatusPage(self, id) - - self.AddPage(self.settings, 'Settings') - #self.AddPage(self.status, 'Status') - self.AddPage(self.connections, 'Connections') - self.AddPage(self.nodes, 'Nodes') - self.AddPage(self.edges, 'Edges') - self.AddPage(self.subnets, 'Subnets') - #self.AddPage(self.graph, 'Graph') - - -class MainWindow(wx.Frame): - def OnQuit(self, event): - app.ExitMainLoop() - - def OnTimer(self, event): - vpn.refresh() - self.np.nodes.refresh() - self.np.subnets.refresh() - self.np.edges.refresh() - self.np.connections.refresh() - - def __init__(self, parent, id, title): - wx.Frame.__init__(self, parent, id, title) - - menubar = wx.MenuBar() - file = wx.Menu() - file.Append(1, '&Quit\tCtrl-X', 'Quit tinc GUI') - menubar.Append(file, '&File') - - #nb = wx.Notebook(self, -1) - #nb.SetPadding((0, 0)) - self.np = NetPage(self, -1) - #nb.AddPage(np, 'VPN') - - self.timer = wx.Timer(self, -1) - self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) - self.timer.Start(1000) - self.Bind(wx.EVT_MENU, self.OnQuit, id=1) - self.SetMenuBar(menubar) - self.Show() - -app = wx.App() -mw = MainWindow(None, -1, 'Tinc GUI') - -#def OnTaskBarIcon(event): -# mw.Raise() -# -#icon = wx.Icon("tincgui.ico", wx.BITMAP_TYPE_PNG) -#taskbaricon = wx.TaskBarIcon() -#taskbaricon.SetIcon(icon, 'Tinc GUI') -#wx.EVT_TASKBAR_RIGHT_UP(taskbaricon, OnTaskBarIcon) - -app.MainLoop() -vpn.close() diff --git a/m4/curses.m4 b/m4/curses.m4 deleted file mode 100644 index 2e8d1510..00000000 --- a/m4/curses.m4 +++ /dev/null @@ -1,44 +0,0 @@ -dnl Check to find the curses headers/libraries - -AC_DEFUN([tinc_CURSES], -[ - AC_ARG_ENABLE([curses], - AS_HELP_STRING([--disable-curses], [disable curses support])) - AS_IF([test "x$enable_curses" != "xno"], [ - AC_DEFINE(HAVE_CURSES, 1, [have curses support]) - curses=true - AC_ARG_WITH(curses, - AS_HELP_STRING([--with-curses=DIR], [curses base directory, or:]), - [curses="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib"] - ) - - AC_ARG_WITH(curses-include, - AS_HELP_STRING([--with-curses-include=DIR], [curses headers directory]), - [curses_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval"] - ) - - AC_ARG_WITH(curses-lib, - AS_HELP_STRING([--with-curses-lib=DIR], [curses library directory]), - [curses_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval"] - ) - - AC_CHECK_HEADERS(curses.h, - [], - [AC_MSG_ERROR("curses header files not found."); break] - ) - - AC_CHECK_LIB(ncurses, initscr, - [CURSES_LIBS="-lncurses"], - [AC_CHECK_LIB(curses, initscr, - [CURSES_LIBS="-lcurses"], - [AC_MSG_ERROR("curses libraries not found.")] - )] - ) - ]) - - AC_SUBST(CURSES_LIBS) -]) diff --git a/m4/libgcrypt.m4 b/m4/libgcrypt.m4 deleted file mode 100644 index 01c7478f..00000000 --- a/m4/libgcrypt.m4 +++ /dev/null @@ -1,33 +0,0 @@ -dnl Check to find the libgcrypt headers/libraries - -AC_DEFUN([tinc_LIBGCRYPT], -[ - AC_ARG_WITH(libgcrypt, - AS_HELP_STRING([--with-libgcrypt=DIR], [libgcrypt base directory, or:]), - [libgcrypt="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib"] - ) - - AC_ARG_WITH(libgcrypt-include, - AS_HELP_STRING([--with-libgcrypt-include=DIR], [libgcrypt headers directory (without trailing /libgcrypt)]), - [libgcrypt_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval"] - ) - - AC_ARG_WITH(libgcrypt-lib, - AS_HELP_STRING([--with-libgcrypt-lib=DIR], [libgcrypt library directory]), - [libgcrypt_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval"] - ) - - AC_CHECK_HEADERS([gcrypt.h], - [], - [AC_MSG_ERROR([libgcrypt header files not found.]); break] - ) - - AC_CHECK_LIB(gcrypt, gcry_cipher_encrypt, - [LIBS="-lgcrypt $LIBS"], - [AC_MSG_ERROR([libgcrypt libraries not found.])] - ) -]) diff --git a/m4/readline.m4 b/m4/readline.m4 deleted file mode 100644 index f29e6924..00000000 --- a/m4/readline.m4 +++ /dev/null @@ -1,42 +0,0 @@ -dnl Check to find the readline headers/libraries - -AC_DEFUN([tinc_READLINE], -[ - AC_ARG_ENABLE([readline], - AS_HELP_STRING([--disable-readline], [disable readline support])) - AS_IF([test "x$enable_readline" != "xno"], [ - AC_DEFINE(HAVE_READLINE, 1, [have readline support]) - readline=true - AC_ARG_WITH(readline, - AS_HELP_STRING([--with-readline=DIR], [readline base directory, or:]), - [readline="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib"] - ) - - AC_ARG_WITH(readline-include, - AS_HELP_STRING([--with-readline-include=DIR], [readline headers directory]), - [readline_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval"] - ) - - AC_ARG_WITH(readline-lib, - AS_HELP_STRING([--with-readline-lib=DIR], [readline library directory]), - [readline_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval"] - ) - - AC_CHECK_HEADERS([readline/readline.h readline/history.h], - [], - [AC_MSG_ERROR("readline header files not found."); break] - ) - - AC_CHECK_LIB(readline, readline, - [READLINE_LIBS="-lreadline"], - [AC_MSG_ERROR("readline library not found.")], - [$CURSES_LIBS] - ) - ]) - - AC_SUBST(READLINE_LIBS) -]) diff --git a/src/Makefile.am b/src/Makefile.am index a2823017..25df72f4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ ## Produce this file with automake to get Makefile.in -sbin_PROGRAMS = tincd tinc sptps_test +sbin_PROGRAMS = sptps_test if LINUX sbin_PROGRAMS += sptps_speed @@ -8,87 +8,6 @@ endif DEFAULT_INCLUDES = -tincd_SOURCES = \ - buffer.c buffer.h \ - cipher.h \ - conf.c conf.h \ - connection.c connection.h \ - control.c control.h \ - control_common.h \ - crypto.h \ - device.h \ - digest.h \ - dropin.c dropin.h \ - dummy_device.c \ - ecdh.h \ - ecdsa.h \ - ecdsagen.h \ - edge.c edge.h \ - ethernet.h \ - event.c event.h \ - fake-gai-errnos.h \ - fake-getaddrinfo.c fake-getaddrinfo.h \ - fake-getnameinfo.c fake-getnameinfo.h \ - getopt.c getopt.h \ - getopt1.c \ - graph.c graph.h \ - hash.c hash.h \ - have.h \ - ipv4.h \ - ipv6.h \ - list.c list.h \ - logger.c logger.h \ - meta.c meta.h \ - multicast_device.c \ - names.c names.h \ - net.c net.h \ - net_packet.c \ - net_setup.c \ - net_socket.c \ - netutl.c netutl.h \ - node.c node.h \ - prf.h \ - process.c process.h \ - protocol.c protocol.h \ - protocol_auth.c \ - protocol_edge.c \ - protocol_key.c \ - protocol_misc.c \ - protocol_subnet.c \ - raw_socket_device.c \ - route.c route.h \ - rsa.h \ - rsagen.h \ - script.c script.h \ - splay_tree.c splay_tree.h \ - sptps.c sptps.h \ - subnet.c subnet.h \ - subnet_parse.c \ - system.h \ - tincd.c \ - utils.c utils.h \ - xalloc.h - -tincd_CFLAGS = -fPIC - -tinc_SOURCES = \ - dropin.c dropin.h \ - getopt.c getopt.h \ - getopt1.c \ - info.c info.h \ - invitation.c invitation.h \ - list.c list.h \ - names.c names.h \ - netutl.c netutl.h \ - script.c script.h \ - sptps.c sptps.h \ - subnet_parse.c subnet.h \ - tincctl.c tincctl.h \ - top.c top.h \ - utils.c utils.h - -tinc_CFLAGS = -fPIC - sptps_test_SOURCES = \ logger.c logger.h \ sptps.c sptps.h \ @@ -109,13 +28,9 @@ libmeshlink_la_SOURCES = \ cipher.h \ conf.c conf.h \ connection.c connection.h \ - control.c control.h \ - control_common.h \ crypto.h \ - device.h \ digest.h \ dropin.c dropin.h \ - dummy_device.c \ ecdh.h \ ecdsa.h \ ecdsagen.h \ @@ -135,8 +50,6 @@ libmeshlink_la_SOURCES = \ list.c list.h \ logger.c logger.h \ meta.c meta.h \ - multicast_device.c \ - names.c names.h \ net.c net.h \ net_packet.c \ net_setup.c \ @@ -144,22 +57,16 @@ libmeshlink_la_SOURCES = \ netutl.c netutl.h \ node.c node.h \ prf.h \ - process.c process.h \ protocol.c protocol.h \ protocol_auth.c \ protocol_edge.c \ protocol_key.c \ protocol_misc.c \ - protocol_subnet.c \ - raw_socket_device.c \ route.c route.h \ rsa.h \ rsagen.h \ - script.c script.h \ splay_tree.c splay_tree.h \ sptps.c sptps.h \ - subnet.c subnet.h \ - subnet_parse.c \ system.h \ tincd.c \ utils.c utils.h \ @@ -169,59 +76,6 @@ libmeshlink_la_CFLAGS = -fPIC libmeshlink_la_LIBADD = -lpthread -## Conditionally compile device drivers - -if LINUX -tincd_SOURCES += linux/device.c -libmeshlink_la_SOURCES +=linux/device.c -endif - -if BSD -tincd_SOURCES += bsd/device.c -if TUNEMU -tincd_SOURCES += bsd/tunemu.c bsd/tunemu.h -endif -endif - -if SOLARIS -tincd_SOURCES += solaris/device.c -endif - -if MINGW -tincd_SOURCES += mingw/device.c mingw/common.h -endif - -if CYGWIN -tincd_SOURCES += cygwin/device.c -endif - -if UML -tincd_SOURCES += uml_device.c -endif - -if VDE -tincd_SOURCES += vde_device.c -endif - -if OPENSSL -tincd_SOURCES += \ - openssl/cipher.c \ - openssl/crypto.c \ - openssl/digest.c openssl/digest.h \ - openssl/ecdh.c \ - openssl/ecdsa.c \ - openssl/prf.c \ - openssl/rsa.c -tinc_SOURCES += \ - openssl/cipher.c \ - openssl/crypto.c \ - openssl/digest.c openssl/digest.h \ - openssl/ecdh.c \ - openssl/ecdsa.c \ - openssl/ecdsagen.c \ - openssl/prf.c \ - openssl/rsa.c \ - openssl/rsagen.c libmeshlink_la_SOURCES += \ openssl/cipher.c \ openssl/crypto.c \ @@ -247,43 +101,9 @@ sptps_speed_SOURCES += \ openssl/ecdsa.c \ openssl/ecdsagen.c \ openssl/prf.c -endif -if GCRYPT -tincd_SOURCES += \ - gcrypt/cipher.c \ - gcrypt/crypto.c \ - gcrypt/digest.c gcrypt/digest.h \ - gcrypt/ecdh.c \ - gcrypt/ecdsa.c \ - gcrypt/prf.c \ - gcrypt/rsa.c -tinc_SOURCES += \ - gcrypt/cipher.c \ - gcrypt/crypto.c \ - gcrypt/digest.c gcrypt/digest.h \ - gcrypt/ecdh.c \ - gcrypt/ecdsa.c \ - gcrypt/ecdsagen.c \ - gcrypt/prf.c \ - gcrypt/rsa.c \ - gcrypt/rsagen.c -sptps_test_SOURCES += \ - gcrypt/cipher.c \ - gcrypt/crypto.c \ - gcrypt/digest.c gcrypt/digest.h \ - gcrypt/ecdh.c \ - gcrypt/ecdsa.c \ - gcrypt/prf.c -endif - -tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) sptps_speed_LDADD = -lrt LIBS = @LIBS@ -if TUNEMU -LIBS += -lpcap -endif - AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" diff --git a/src/bsd/device.c b/src/bsd/device.c deleted file mode 100644 index 145b79e5..00000000 --- a/src/bsd/device.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - device.c -- Interaction BSD tun/tap device - Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2013 Guus Sliepen - 2009 Grzegorz Dymarek - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include "../conf.h" -#include "../device.h" -#include "../logger.h" -#include "../names.h" -#include "../net.h" -#include "../route.h" -#include "../utils.h" -#include "../xalloc.h" - -#ifdef ENABLE_TUNEMU -#include "bsd/tunemu.h" -#endif - -#define DEFAULT_TUN_DEVICE "/dev/tun0" -#if defined(HAVE_FREEBSD) || defined(HAVE_NETBSD) -#define DEFAULT_TAP_DEVICE "/dev/tap0" -#else -#define DEFAULT_TAP_DEVICE "/dev/tun0" -#endif - -typedef enum device_type { - DEVICE_TYPE_TUN, - DEVICE_TYPE_TUNIFHEAD, - DEVICE_TYPE_TAP, -#ifdef ENABLE_TUNEMU - DEVICE_TYPE_TUNEMU, -#endif -} device_type_t; - -int device_fd = -1; -char *device = NULL; -char *iface = NULL; -static char *device_info = NULL; -#if defined(ENABLE_TUNEMU) -static device_type_t device_type = DEVICE_TYPE_TUNEMU; -#elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY) -static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD; -#else -static device_type_t device_type = DEVICE_TYPE_TUN; -#endif - -static bool setup_device(void) { - char *type; - - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - if(routing_mode == RMODE_ROUTER) - device = xstrdup(DEFAULT_TUN_DEVICE); - else - device = xstrdup(DEFAULT_TAP_DEVICE); - } - - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) - iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); - - if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { - if(!strcasecmp(type, "tun")) - /* use default */; -#ifdef ENABLE_TUNEMU - else if(!strcasecmp(type, "tunemu")) - device_type = DEVICE_TYPE_TUNEMU; -#endif - else if(!strcasecmp(type, "tunnohead")) - device_type = DEVICE_TYPE_TUN; - else if(!strcasecmp(type, "tunifhead")) - device_type = DEVICE_TYPE_TUNIFHEAD; - else if(!strcasecmp(type, "tap")) - device_type = DEVICE_TYPE_TAP; - else { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); - return false; - } - } else { - if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) - device_type = DEVICE_TYPE_TAP; - } - - switch(device_type) { -#ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: { - char dynamic_name[256] = ""; - device_fd = tunemu_open(dynamic_name); - } - break; -#endif - default: - device_fd = open(device, O_RDWR | O_NONBLOCK); - } - - if(device_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device, strerror(errno)); - return false; - } - -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif - - switch(device_type) { - default: - device_type = DEVICE_TYPE_TUN; - case DEVICE_TYPE_TUN: -#ifdef TUNSIFHEAD - { - const int zero = 0; - if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof zero) == -1) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); - return false; - } - } -#endif -#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) - { - const int mode = IFF_BROADCAST | IFF_MULTICAST; - ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); - } -#endif - - device_info = "Generic BSD tun device"; - break; - case DEVICE_TYPE_TUNIFHEAD: -#ifdef TUNSIFHEAD - { - const int one = 1; - if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof one) == -1) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); - return false; - } - } -#endif -#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) - { - const int mode = IFF_BROADCAST | IFF_MULTICAST; - ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); - } -#endif - - device_info = "Generic BSD tun device"; - break; - case DEVICE_TYPE_TAP: - if(routing_mode == RMODE_ROUTER) - overwrite_mac = true; - device_info = "Generic BSD tap device"; -#ifdef TAPGIFNAME - { - struct ifreq ifr; - if(ioctl(device_fd, TAPGIFNAME, (void*)&ifr) == 0) { - if(iface) - free(iface); - iface = xstrdup(ifr.ifr_name); - } - } - -#endif - break; -#ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - device_info = "BSD tunemu device"; - break; -#endif - } - - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - - return true; -} - -static void close_device(void) { - switch(device_type) { -#ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - tunemu_close(device_fd); - break; -#endif - default: - close(device_fd); - } - - free(device); - free(iface); -} - -static bool read_packet(vpn_packet_t *packet) { - int inlen; - - switch(device_type) { - case DEVICE_TYPE_TUN: -#ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - if(device_type == DEVICE_TYPE_TUNEMU) - inlen = tunemu_read(device_fd, packet->data + 14, MTU - 14); - else -#endif - inlen = read(device_fd, packet->data + 14, MTU - 14); - - if(inlen <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - switch(packet->data[14] >> 4) { - case 4: - packet->data[12] = 0x08; - packet->data[13] = 0x00; - break; - case 6: - packet->data[12] = 0x86; - packet->data[13] = 0xDD; - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown IP version %d while reading packet from %s %s", - packet->data[14] >> 4, device_info, device); - return false; - } - - memset(packet->data, 0, 12); - packet->len = inlen + 14; - break; - - case DEVICE_TYPE_TUNIFHEAD: { - u_int32_t type; - struct iovec vector[2] = {{&type, sizeof type}, {packet->data + 14, MTU - 14}}; - - if((inlen = readv(device_fd, vector, 2)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - switch (ntohl(type)) { - case AF_INET: - packet->data[12] = 0x08; - packet->data[13] = 0x00; - break; - - case AF_INET6: - packet->data[12] = 0x86; - packet->data[13] = 0xDD; - break; - - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown address family %x while reading packet from %s %s", - ntohl(type), device_info, device); - return false; - } - - memset(packet->data, 0, 12); - packet->len = inlen + 10; - break; - } - - case DEVICE_TYPE_TAP: - if((inlen = read(device_fd, packet->data, MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - packet->len = inlen; - break; - - default: - return false; - } - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", - packet->len, device_info); - - return true; -} - -static bool write_packet(vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); - - switch(device_type) { - case DEVICE_TYPE_TUN: - if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - break; - - case DEVICE_TYPE_TUNIFHEAD: { - u_int32_t type; - struct iovec vector[2] = {{&type, sizeof type}, {packet->data + 14, packet->len - 14}}; - int af; - - af = (packet->data[12] << 8) + packet->data[13]; - - switch (af) { - case 0x0800: - type = htonl(AF_INET); - break; - case 0x86DD: - type = htonl(AF_INET6); - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown address family %x while writing packet to %s %s", - af, device_info, device); - return false; - } - - if(writev(device_fd, vector, 2) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - break; - } - - case DEVICE_TYPE_TAP: - if(write(device_fd, packet->data, packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - break; - -#ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - if(tunemu_write(device_fd, packet->data + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - break; -#endif - - default: - return false; - } - - return true; -} - -const devops_t os_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, -}; diff --git a/src/bsd/tunemu.c b/src/bsd/tunemu.c deleted file mode 100644 index 1ce90074..00000000 --- a/src/bsd/tunemu.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * tunemu - Tun device emulation for Darwin - * Copyright (C) 2009 Friedrich Schöller - * - * 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 3 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, see . - * - */ - -#include "tunemu.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PPPPROTO_CTL 1 - -#define PPP_IP 0x21 -#define PPP_IPV6 0x57 - -#define SC_LOOP_TRAFFIC 0x00000200 - -#define PPPIOCNEWUNIT _IOWR('t', 62, int) -#define PPPIOCSFLAGS _IOW('t', 89, int) -#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) -#define PPPIOCATTCHAN _IOW('t', 56, int) -#define PPPIOCGCHAN _IOR('t', 55, int) -#define PPPIOCCONNECT _IOW('t', 58, int) -#define PPPIOCGUNIT _IOR('t', 86, int) - -struct sockaddr_ppp -{ - u_int8_t ppp_len; - u_int8_t ppp_family; - u_int16_t ppp_proto; - u_int32_t ppp_cookie; -}; - -enum NPmode -{ - NPMODE_PASS, - NPMODE_DROP, - NPMODE_ERROR, - NPMODE_QUEUE -}; - -struct npioctl -{ - int protocol; - enum NPmode mode; -}; - -#define PPP_KEXT_PATH "/System/Library/Extensions/PPP.kext" - -#define ERROR_BUFFER_SIZE 1024 - -char tunemu_error[ERROR_BUFFER_SIZE]; - -static int pcap_use_count = 0; -static pcap_t *pcap = NULL; - -static int data_buffer_length = 0; -static char *data_buffer = NULL; - -static void tun_error(char *format, ...) -{ - va_list vl; - va_start(vl, format); - vsnprintf(tunemu_error, ERROR_BUFFER_SIZE, format, vl); - va_end(vl); -} - -static void tun_noerror() -{ - *tunemu_error = 0; -} - -static void closeall() -{ - int fd = getdtablesize(); - while (fd--) - close(fd); - - open("/dev/null", O_RDWR, 0); - dup(0); - dup(0); -} - -static int ppp_load_kext() -{ - int pid = fork(); - if (pid < 0) - { - tun_error("fork for ppp kext: %s", strerror(errno)); - return -1; - } - - if (pid == 0) - { - closeall(); - execle("/sbin/kextload", "kextload", PPP_KEXT_PATH, NULL, NULL); - exit(1); - } - - int status; - while (waitpid(pid, &status, 0) < 0) - { - if (errno == EINTR) - continue; - - tun_error("waitpid for ppp kext: %s", strerror(errno)); - return -1; - } - - if (WEXITSTATUS(status) != 0) - { - tun_error("could not load ppp kext \"%s\"", PPP_KEXT_PATH); - return -1; - } - - tun_noerror(); - return 0; -} - -static int ppp_new_instance() -{ - // create ppp socket - int ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL); - if (ppp_sockfd < 0) - { - if (ppp_load_kext() < 0) - return -1; - - ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL); - if (ppp_sockfd < 0) - { - tun_error("creating ppp socket: %s", strerror(errno)); - return -1; - } - } - - // connect to ppp procotol - struct sockaddr_ppp pppaddr; - pppaddr.ppp_len = sizeof(struct sockaddr_ppp); - pppaddr.ppp_family = AF_PPP; - pppaddr.ppp_proto = PPPPROTO_CTL; - pppaddr.ppp_cookie = 0; - if (connect(ppp_sockfd, (struct sockaddr *)&pppaddr, sizeof(struct sockaddr_ppp)) < 0) - { - tun_error("connecting ppp socket: %s", strerror(errno)); - close(ppp_sockfd); - return -1; - } - - tun_noerror(); - return ppp_sockfd; -} - -static int ppp_new_unit(int *unit_number) -{ - int fd = ppp_new_instance(); - if (fd < 0) - return -1; - - // create ppp unit - if (ioctl(fd, PPPIOCNEWUNIT, unit_number) < 0) - { - tun_error("creating ppp unit: %s", strerror(errno)); - close(fd); - return -1; - } - - tun_noerror(); - return fd; -} - -static int ppp_setup_unit(int unit_fd) -{ - // send traffic to program - int flags = SC_LOOP_TRAFFIC; - if (ioctl(unit_fd, PPPIOCSFLAGS, &flags) < 0) - { - tun_error("setting ppp loopback mode: %s", strerror(errno)); - return -1; - } - - // allow packets - struct npioctl npi; - npi.protocol = PPP_IP; - npi.mode = NPMODE_PASS; - if (ioctl(unit_fd, PPPIOCSNPMODE, &npi) < 0) - { - tun_error("starting ppp unit: %s", strerror(errno)); - return -1; - } - - tun_noerror(); - return 0; -} - -static int open_pcap() -{ - if (pcap != NULL) - { - pcap_use_count++; - return 0; - } - - char errbuf[PCAP_ERRBUF_SIZE]; - pcap = pcap_open_live("lo0", BUFSIZ, 0, 1, errbuf); - pcap_use_count = 1; - - if (pcap == NULL) - { - tun_error("opening pcap: %s", errbuf); - return -1; - } - - tun_noerror(); - return 0; -} - -static void close_pcap() -{ - if (pcap == NULL) - return; - - pcap_use_count--; - if (pcap_use_count == 0) - { - pcap_close(pcap); - pcap = NULL; - } -} - -static void allocate_data_buffer(int size) -{ - if (data_buffer_length < size) - { - free(data_buffer); - data_buffer_length = size; - data_buffer = malloc(data_buffer_length); - } -} - -static void make_device_name(tunemu_device device, int unit_number) -{ - snprintf(device, sizeof(tunemu_device), "ppp%d", unit_number); -} - -static int check_device_name(tunemu_device device) -{ - if (strlen(device) < 4) - return -1; - - int unit_number = atoi(device + 3); - if (unit_number < 0 || unit_number > 999) - return -1; - - tunemu_device compare; - make_device_name(compare, unit_number); - - if (strcmp(device, compare) != 0) - return -1; - - return 0; -} - -int tunemu_open(tunemu_device device) -{ - int ppp_unit_number = -1; - if (device[0] != 0) - { - if (check_device_name(device) < 0) - { - tun_error("invalid device name \"%s\"", device); - return -1; - } - - ppp_unit_number = atoi(device + 3); - } - - int ppp_unit_fd = ppp_new_unit(&ppp_unit_number); - if (ppp_unit_fd < 0) - return -1; - - if (ppp_setup_unit(ppp_unit_fd) < 0) - { - close(ppp_unit_fd); - return -1; - } - - if (open_pcap() < 0) - { - close(ppp_unit_fd); - return -1; - } - - make_device_name(device, ppp_unit_number); - - return ppp_unit_fd; -} - -int tunemu_close(int ppp_sockfd) -{ - int ret = close(ppp_sockfd); - - if (ret == 0) - close_pcap(); - - return ret; -} - -int tunemu_read(int ppp_sockfd, char *buffer, int length) -{ - allocate_data_buffer(length + 2); - - length = read(ppp_sockfd, data_buffer, length + 2); - if (length < 0) - { - tun_error("reading packet: %s", strerror(errno)); - return length; - } - tun_noerror(); - - length -= 2; - if (length < 0) - return 0; - - memcpy(buffer, data_buffer + 2, length); - - return length; -} - -int tunemu_write(int ppp_sockfd, char *buffer, int length) -{ - allocate_data_buffer(length + 4); - - data_buffer[0] = 0x02; - data_buffer[1] = 0x00; - data_buffer[2] = 0x00; - data_buffer[3] = 0x00; - - memcpy(data_buffer + 4, buffer, length); - - if (pcap == NULL) - { - tun_error("pcap not open"); - return -1; - } - - length = pcap_inject(pcap, data_buffer, length + 4); - if (length < 0) - { - tun_error("injecting packet: %s", pcap_geterr(pcap)); - return length; - } - tun_noerror(); - - length -= 4; - if (length < 0) - return 0; - - return length; -} diff --git a/src/bsd/tunemu.h b/src/bsd/tunemu.h deleted file mode 100644 index e0452a8b..00000000 --- a/src/bsd/tunemu.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * tunemu - Tun device emulation for Darwin - * Copyright (C) 2009 Friedrich Schöller - * - * 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 3 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, see . - * - */ - -#ifndef TUNEMU_H -#define TUNEMU_H - -typedef char tunemu_device[7]; - -extern char tunemu_error[]; - -int tunemu_open(tunemu_device dev); -int tunemu_close(int fd); -int tunemu_read(int fd, char *buffer, int length); -int tunemu_write(int fd, char *buffer, int length); - -#endif diff --git a/src/conf.c b/src/conf.c index 95c07477..16247570 100644 --- a/src/conf.c +++ b/src/conf.c @@ -29,7 +29,6 @@ #include "conf.h" #include "list.h" #include "logger.h" -#include "names.h" #include "netutl.h" /* for str2address */ #include "protocol.h" #include "utils.h" /* for cp */ @@ -187,34 +186,6 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result) { return false; } -bool get_config_subnet(const config_t *cfg, subnet_t ** result) { - subnet_t subnet = {NULL}; - - if(!cfg) - return false; - - if(!str2net(&subnet, cfg->value)) { - logger(DEBUG_ALWAYS, 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 subnet.net.ipv4.address)) - || ((subnet.type == SUBNET_IPV6) - && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof subnet.net.ipv6.address))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); - return false; - } - - *(*result = new_subnet()) = subnet; - - return true; -} - /* Read exactly one line and strip the trailing newline if any. */ diff --git a/src/conf.h b/src/conf.h index 4f39b20a..17dcc595 100644 --- a/src/conf.h +++ b/src/conf.h @@ -31,8 +31,6 @@ typedef struct config_t { int line; } config_t; -#include "subnet.h" - extern splay_tree_t *config_tree; extern int pinginterval; @@ -52,7 +50,6 @@ 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 **); extern config_t *parse_config_line(char *, const char *, int); extern bool read_config_file(splay_tree_t *, const char *); diff --git a/src/connection.c b/src/connection.c index 496f6747..55a7c981 100644 --- a/src/connection.c +++ b/src/connection.c @@ -24,11 +24,10 @@ #include "list.h" #include "cipher.h" #include "conf.h" -#include "control_common.h" +#include "connection.h" #include "list.h" #include "logger.h" #include "rsa.h" -#include "subnet.h" #include "utils.h" #include "xalloc.h" @@ -90,14 +89,3 @@ void connection_add(connection_t *c) { void connection_del(connection_t *c) { list_delete(connection_list, c); } - -bool dump_connections(connection_t *cdump) { - for list_each(connection_t, c, connection_list) { - send_request(cdump, "%d %d %s %s %x %d %x", - CONTROL, REQ_DUMP_CONNECTIONS, - c->name, c->hostname, c->options, c->socket, - bitfield_to_int(&c->status, sizeof c->status)); - } - - return send_request(cdump, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS); -} diff --git a/src/connection.h b/src/connection.h index b5d3d18d..1410c5cc 100644 --- a/src/connection.h +++ b/src/connection.h @@ -110,6 +110,5 @@ 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 bool dump_connections(struct connection_t *); #endif /* __TINC_CONNECTION_H__ */ diff --git a/src/control.c b/src/control.c deleted file mode 100644 index 45627495..00000000 --- a/src/control.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - control.c -- Control socket handling. - Copyright (C) 2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" -#include "crypto.h" -#include "conf.h" -#include "control.h" -#include "control_common.h" -#include "graph.h" -#include "logger.h" -#include "meta.h" -#include "names.h" -#include "net.h" -#include "netutl.h" -#include "protocol.h" -#include "route.h" -#include "utils.h" -#include "xalloc.h" - -char controlcookie[65]; - -static bool control_return(connection_t *c, int type, int error) { - return send_request(c, "%d %d %d", CONTROL, type, error); -} - -static bool control_ok(connection_t *c, int type) { - return control_return(c, type, 0); -} - -bool control_h(connection_t *c, const char *request) { - int type; - - if(!c->status.control || c->allow_request != CONTROL) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unauthorized control request from %s (%s)", c->name, c->hostname); - return false; - } - - if(sscanf(request, "%*d %d", &type) != 1) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "CONTROL", c->name, c->hostname); - return false; - } - - switch (type) { - case REQ_STOP: - event_exit(); - return control_ok(c, REQ_STOP); - - case REQ_DUMP_NODES: - return dump_nodes(c); - - case REQ_DUMP_EDGES: - return dump_edges(c); - - case REQ_DUMP_SUBNETS: - return dump_subnets(c); - - case REQ_DUMP_CONNECTIONS: - return dump_connections(c); - - case REQ_PURGE: - purge(); - return control_ok(c, REQ_PURGE); - - case REQ_SET_DEBUG: { - int new_level; - if(sscanf(request, "%*d %*d %d", &new_level) != 1) - return false; - send_request(c, "%d %d %d", CONTROL, REQ_SET_DEBUG, debug_level); - if(new_level >= 0) - debug_level = new_level; - return true; - } - - case REQ_RETRY: - retry(); - return control_ok(c, REQ_RETRY); - - case REQ_RELOAD: - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got '%s' command", "reload"); - int result = reload_configuration(); - return control_return(c, REQ_RELOAD, result); - - case REQ_DISCONNECT: { - char name[MAX_STRING_SIZE]; - bool found = false; - - if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1) - return control_return(c, REQ_DISCONNECT, -1); - - for list_each(connection_t, other, connection_list) { - if(strcmp(other->name, name)) - continue; - terminate_connection(other, other->status.active); - found = true; - } - - return control_return(c, REQ_DISCONNECT, found ? 0 : -2); - } - - case REQ_DUMP_TRAFFIC: - return dump_traffic(c); - - case REQ_PCAP: - sscanf(request, "%*d %*d %d", &c->outmaclength); - c->status.pcap = true; - pcap = true; - return true; - - case REQ_LOG: - sscanf(request, "%*d %*d %d", &c->outcompression); - c->status.log = true; - logcontrol = true; - return true; - - default: - return send_request(c, "%d %d", CONTROL, REQ_INVALID); - } -} - -bool init_control(void) { - randomize(controlcookie, sizeof controlcookie / 2); - bin2hex(controlcookie, controlcookie, sizeof controlcookie / 2); - - mode_t mask = umask(0); - umask(mask | 077); - FILE *f = fopen(pidfilename, "w"); - umask(mask); - - if(!f) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot write control socket cookie file %s: %s", pidfilename, strerror(errno)); - return false; - } - - // Get the address and port of the first listening socket - - char *localhost = NULL; - sockaddr_t sa; - socklen_t len = sizeof sa; - - // Make sure we have a valid address, and map 0.0.0.0 and :: to 127.0.0.1 and ::1. - - if(getsockname(listen_socket[0].tcp.fd, (struct sockaddr *)&sa, &len)) { - xasprintf(&localhost, "127.0.0.1 port %s", myport); - } else { - if(sa.sa.sa_family == AF_INET) { - if(sa.in.sin_addr.s_addr == 0) - sa.in.sin_addr.s_addr = htonl(0x7f000001); - } else if(sa.sa.sa_family == AF_INET6) { - static const uint8_t zero[16] = {0}; - if(!memcmp(sa.in6.sin6_addr.s6_addr, zero, sizeof zero)) - sa.in6.sin6_addr.s6_addr[15] = 1; - } - - localhost = sockaddr2hostname(&sa); - } - - fprintf(f, "%d %s %s\n", (int)getpid(), controlcookie, localhost); - - free(localhost); - fclose(f); - -#ifndef HAVE_MINGW - int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if(unix_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(errno)); - return false; - } - - struct sockaddr_un sa_un; - sa_un.sun_family = AF_UNIX; - strncpy(sa_un.sun_path, unixsocketname, sizeof sa_un.sun_path); - - if(connect(unix_fd, (struct sockaddr *)&sa_un, sizeof sa_un) >= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "UNIX socket %s is still in use!", unixsocketname); - return false; - } - - unlink(unixsocketname); - - umask(mask | 077); - int result = bind(unix_fd, (struct sockaddr *)&sa_un, sizeof sa_un); - umask(mask); - - if(result < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind UNIX socket to %s: %s", unixsocketname, sockstrerror(errno)); - return false; - } - - if(listen(unix_fd, 3) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not listen on UNIX socket %s: %s", unixsocketname, sockstrerror(errno)); - return false; - } - - io_add(&unix_socket, handle_new_unix_connection, &unix_socket, unix_fd, IO_READ); -#endif - - return true; -} - -void exit_control(void) { -#ifndef HAVE_MINGW - unlink(unixsocketname); - io_del(&unix_socket); - close(unix_socket.fd); -#endif - - unlink(pidfilename); -} diff --git a/src/control.h b/src/control.h deleted file mode 100644 index ce8145a3..00000000 --- a/src/control.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - control.h -- header for control.c. - Copyright (C) 2007 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_CONTROL_H__ -#define __TINC_CONTROL_H__ - -extern bool init_control(); -extern void exit_control(); -extern char controlcookie[]; - -#endif diff --git a/src/control_common.h b/src/control_common.h deleted file mode 100644 index cd54889a..00000000 --- a/src/control_common.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - control_protocol.h -- control socket protocol. - Copyright (C) 2007 Scott Lamb - 2009-2012 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_CONTROL_PROTOCOL_H__ -#define __TINC_CONTROL_PROTOCOL_H__ - -#include "protocol.h" - -enum request_type { - REQ_INVALID = -1, - REQ_STOP = 0, - REQ_RELOAD, - REQ_RESTART, - REQ_DUMP_NODES, - REQ_DUMP_EDGES, - REQ_DUMP_SUBNETS, - REQ_DUMP_CONNECTIONS, - REQ_DUMP_GRAPH, - REQ_PURGE, - REQ_SET_DEBUG, - REQ_RETRY, - REQ_CONNECT, - REQ_DISCONNECT, - REQ_DUMP_TRAFFIC, - REQ_PCAP, - REQ_LOG, -}; - -#define TINC_CTL_VERSION_CURRENT 0 - -#endif diff --git a/src/cygwin/device.c b/src/cygwin/device.c deleted file mode 100644 index a110f7f2..00000000 --- a/src/cygwin/device.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - device.c -- Interaction with Windows tap driver in a Cygwin environment - Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#include - -#include "../conf.h" -#include "../device.h" -#include "../logger.h" -#include "../names.h" -#include "../net.h" -#include "../route.h" -#include "../utils.h" -#include "../xalloc.h" - -#include "../mingw/common.h" - -int device_fd = -1; -static HANDLE device_handle = INVALID_HANDLE_VALUE; -char *device = NULL; -char *iface = NULL; -static char *device_info = NULL; - -static pid_t reader_pid; -static int sp[2]; - -static bool setup_device(void) { - HKEY key, key2; - int i, err; - - char regpath[1024]; - char adapterid[1024]; - char adaptername[1024]; - char tapname[1024]; - char gelukt = 0; - long len; - - bool found = false; - - 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, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) { - logger(DEBUG_ALWAYS, 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", NETWORK_CONNECTIONS_KEY, 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(DEBUG_ALWAYS, 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(DEBUG_ALWAYS, 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(DEBUG_ALWAYS, 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(DEBUG_ALWAYS, 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(DEBUG_ALWAYS, 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 inlen; - - 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(DEBUG_ALWAYS, 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(DEBUG_ALWAYS, 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, &inlen, NULL); - write(sp[1], buf, inlen); - } - } - - read(device_fd, &gelukt, 1); - if(gelukt != 1) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader failed!"); - return false; - } - - device_info = "Windows tap device"; - - logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); - - return true; -} - -static void close_device(void) { - close(sp[0]); - close(sp[1]); - CloseHandle(device_handle); - - kill(reader_pid, SIGKILL); - - free(device); - free(iface); -} - -static bool read_packet(vpn_packet_t *packet) { - int inlen; - - if((inlen = read(sp[0], packet->data, MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - packet->len = inlen; - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); - - return true; -} - -static bool write_packet(vpn_packet_t *packet) { - long outlen; - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); - - if(!WriteFile (device_handle, packet->data, packet->len, &outlen, NULL)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); - return false; - } - - return true; -} - -const devops_t os_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, -}; diff --git a/src/device.h b/src/device.h deleted file mode 100644 index 85112ffc..00000000 --- a/src/device.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - device.h -- generic header for device.c - Copyright (C) 2001-2005 Ivo Timmermans - 2001-2012 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_DEVICE_H__ -#define __TINC_DEVICE_H__ - -#include "net.h" - -extern int device_fd; -extern char *device; -extern char *iface; - -extern uint64_t device_in_packets; -extern uint64_t device_in_bytes; -extern uint64_t device_out_packets; -extern uint64_t device_out_bytes; - -typedef struct devops_t { - bool (*setup)(void); - void (*close)(void); - bool (*read)(struct vpn_packet_t *); - bool (*write)(struct vpn_packet_t *); -} devops_t; - -extern const devops_t os_devops; -extern const devops_t dummy_devops; -extern const devops_t raw_socket_devops; -extern const devops_t multicast_devops; -extern const devops_t uml_devops; -extern const devops_t vde_devops; -extern devops_t devops; - -#endif /* __TINC_DEVICE_H__ */ diff --git a/src/dummy_device.c b/src/dummy_device.c deleted file mode 100644 index c43d5862..00000000 --- a/src/dummy_device.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - device.c -- Dummy device - Copyright (C) 2011-2012 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "device.h" -#include "logger.h" -#include "net.h" - -static char *device_info = "dummy device"; - -static bool setup_device(void) { - device = "dummy"; - iface = "dummy"; - logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); - return true; -} - -static void close_device(void) { -} - -static bool read_packet(vpn_packet_t *packet) { - return false; -} - -static bool write_packet(vpn_packet_t *packet) { - return true; -} - -const devops_t dummy_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, -}; diff --git a/src/edge.c b/src/edge.c index f185b4fe..56537a57 100644 --- a/src/edge.c +++ b/src/edge.c @@ -21,7 +21,6 @@ #include "system.h" #include "splay_tree.h" -#include "control_common.h" #include "edge.h" #include "logger.h" #include "netutl.h" @@ -105,18 +104,3 @@ edge_t *lookup_edge(node_t *from, node_t *to) { return splay_search(from->edge_tree, &v); } - -bool dump_edges(connection_t *c) { - for splay_each(node_t, n, node_tree) { - for splay_each(edge_t, e, n->edge_tree) { - char *address = sockaddr2hostname(&e->address); - send_request(c, "%d %d %s %s %s %x %d", - CONTROL, REQ_DUMP_EDGES, - e->from->name, e->to->name, address, - e->options, e->weight); - free(address); - } - } - - return send_request(c, "%d %d", CONTROL, REQ_DUMP_EDGES); -} diff --git a/src/edge.h b/src/edge.h index cbd9e5ac..c6afdf6e 100644 --- a/src/edge.h +++ b/src/edge.h @@ -49,6 +49,5 @@ extern void free_edge_tree(splay_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 bool dump_edges(struct connection_t *); #endif /* __TINC_EDGE_H__ */ diff --git a/src/gcrypt/cipher.c b/src/gcrypt/cipher.c deleted file mode 100644 index e9b32cf7..00000000 --- a/src/gcrypt/cipher.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - cipher.c -- Symmetric block cipher handling - Copyright (C) 2007-2012 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "cipher.h" -#include "logger.h" -#include "xalloc.h" - -static struct { - const char *name; - int algo; - int mode; - int nid; -} ciphertable[] = { - {"none", GCRY_CIPHER_NONE, GCRY_CIPHER_MODE_NONE, 0}, - - {NULL, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, 92}, - {"blowfish", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC, 91}, - {NULL, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB, 93}, - {NULL, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB, 94}, - - {NULL, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 418}, - {"aes", GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 419}, - {NULL, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CFB, 421}, - {NULL, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OFB, 420}, - - {NULL, GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB, 422}, - {"aes192", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC, 423}, - {NULL, GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB, 425}, - {NULL, GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB, 424}, - - {NULL, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB, 426}, - {"aes256", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, 427}, - {NULL, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB, 429}, - {NULL, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB, 428}, -}; - -static bool nametocipher(const char *name, int *algo, int *mode) { - size_t i; - - for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) { - if(ciphertable[i].name && !strcasecmp(name, ciphertable[i].name)) { - *algo = ciphertable[i].algo; - *mode = ciphertable[i].mode; - return true; - } - } - - return false; -} - -static bool nidtocipher(int nid, int *algo, int *mode) { - size_t i; - - for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) { - if(nid == ciphertable[i].nid) { - *algo = ciphertable[i].algo; - *mode = ciphertable[i].mode; - return true; - } - } - - return false; -} - -static bool ciphertonid(int algo, int mode, int *nid) { - size_t i; - - for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) { - if(algo == ciphertable[i].algo && mode == ciphertable[i].mode) { - *nid = ciphertable[i].nid; - return true; - } - } - - return false; -} - -static bool cipher_open(cipher_t *cipher, int algo, int mode) { - gcry_error_t err; - - if(!ciphertonid(algo, mode, &cipher->nid)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Cipher %d mode %d has no corresponding nid!", algo, mode); - return false; - } - - if((err = gcry_cipher_open(&cipher->handle, algo, mode, 0))) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unable to intialise cipher %d mode %d: %s", algo, mode, gcry_strerror(err)); - return false; - } - - cipher->keylen = gcry_cipher_get_algo_keylen(algo); - cipher->blklen = gcry_cipher_get_algo_blklen(algo); - cipher->key = xmalloc(cipher->keylen + cipher->blklen); - cipher->padding = mode == GCRY_CIPHER_MODE_ECB || mode == GCRY_CIPHER_MODE_CBC; - - return true; -} - -bool cipher_open_by_name(cipher_t *cipher, const char *name) { - int algo, mode; - - if(!nametocipher(name, &algo, &mode)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown cipher name '%s'!", name); - return false; - } - - return cipher_open(cipher, algo, mode); -} - -bool cipher_open_by_nid(cipher_t *cipher, int nid) { - int algo, mode; - - if(!nidtocipher(nid, &algo, &mode)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown cipher ID %d!", nid); - return false; - } - - return cipher_open(cipher, algo, mode); -} - -bool cipher_open_blowfish_ofb(cipher_t *cipher) { - return cipher_open(cipher, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB); -} - -void cipher_close(cipher_t *cipher) { - if(cipher->handle) { - gcry_cipher_close(cipher->handle); - cipher->handle = NULL; - } - - if(cipher->key) { - free(cipher->key); - cipher->key = NULL; - } -} - -size_t cipher_keylength(const cipher_t *cipher) { - return cipher->keylen + cipher->blklen; -} - -void cipher_get_key(const cipher_t *cipher, void *key) { - memcpy(key, cipher->key, cipher->keylen + cipher->blklen); -} - -bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { - memcpy(cipher->key, key, cipher->keylen + cipher->blklen); - - gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen); - gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); - - return true; -} - -bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encrypt) { - memcpy(cipher->key, key + len - cipher->keylen, cipher->keylen + cipher->blklen); - memcpy(cipher->key + cipher->keylen, key + len - cipher->keylen - cipher->blklen, cipher->blklen); - - gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen); - gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); - - return true; -} - -bool cipher_regenerate_key(cipher_t *cipher, bool encrypt) { - gcry_create_nonce(cipher->key, cipher->keylen + cipher->blklen); - - gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen); - gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); - - return true; -} - -bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { - gcry_error_t err; - uint8_t pad[cipher->blklen]; - - if(cipher->padding) { - if(!oneshot) - return false; - - size_t reqlen = ((inlen + cipher->blklen) / cipher->blklen) * cipher->blklen; - - if(*outlen < reqlen) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: not enough room for padding"); - return false; - } - - uint8_t padbyte = reqlen - inlen; - inlen = reqlen - cipher->blklen; - - for(int i = 0; i < cipher->blklen; i++) - if(i < cipher->blklen - padbyte) - pad[i] = ((uint8_t *)indata)[inlen + i]; - else - pad[i] = padbyte; - } - - if(oneshot) - gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); - - if((err = gcry_cipher_encrypt(cipher->handle, outdata, *outlen, indata, inlen))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); - return false; - } - - if(cipher->padding) { - if((err = gcry_cipher_encrypt(cipher->handle, outdata + inlen, cipher->blklen, pad, cipher->blklen))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); - return false; - } - - inlen += cipher->blklen; - } - - *outlen = inlen; - return true; -} - -bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { - gcry_error_t err; - - if(oneshot) - gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); - - if((err = gcry_cipher_decrypt(cipher->handle, outdata, *outlen, indata, inlen))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", gcry_strerror(err)); - return false; - } - - if(cipher->padding) { - if(!oneshot) - return false; - - uint8_t padbyte = ((uint8_t *)outdata)[inlen - 1]; - - if(padbyte == 0 || padbyte > cipher->blklen || padbyte > inlen) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: invalid padding"); - return false; - } - - size_t origlen = inlen - padbyte; - - for(int i = inlen - 1; i >= origlen; i--) - if(((uint8_t *)outdata)[i] != padbyte) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: invalid padding"); - return false; - } - - *outlen = origlen; - } else - *outlen = inlen; - - return true; -} - -int cipher_get_nid(const cipher_t *cipher) { - return cipher->nid; -} - -bool cipher_active(const cipher_t *cipher) { - return cipher->nid != 0; -} diff --git a/src/gcrypt/cipher.h b/src/gcrypt/cipher.h deleted file mode 100644 index 389bb115..00000000 --- a/src/gcrypt/cipher.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - cipher.h -- header file cipher.c - Copyright (C) 2007-2009 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_CIPHER_H__ -#define __TINC_CIPHER_H__ - -#include - -#define CIPHER_MAX_BLOCK_SIZE 32 -#define CIPHER_MAX_IV_SIZE 16 -#define CIPHER_MAX_KEY_SIZE 32 - -typedef struct cipher { - gcry_cipher_hd_t handle; - char *key; - int nid; - uint16_t keylen; - uint16_t blklen; - bool padding; -} cipher_t; - -extern bool cipher_open_by_name(struct cipher *, const char *); -extern bool cipher_open_by_nid(struct cipher *, int); -extern bool cipher_open_blowfish_ofb(struct cipher *); -extern void cipher_close(struct cipher *); -extern size_t cipher_keylength(const struct cipher *); -extern void cipher_get_key(const struct cipher *, void *); -extern bool cipher_set_key(struct cipher *, void *, bool); -extern bool cipher_set_key_from_rsa(struct cipher *, void *, size_t, bool); -extern bool cipher_regenerate_key(struct cipher *, bool); -extern bool cipher_encrypt(struct cipher *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot); -extern bool cipher_decrypt(struct cipher *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot); -extern int cipher_get_nid(const struct cipher *); -extern bool cipher_active(const struct cipher *); - -#endif diff --git a/src/gcrypt/crypto.c b/src/gcrypt/crypto.c deleted file mode 100644 index dc92b3e0..00000000 --- a/src/gcrypt/crypto.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - crypto.c -- Cryptographic miscellaneous functions and initialisation - Copyright (C) 2007 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include - -#include "crypto.h" - -void crypto_init() { -} - -void crypto_exit() { -} - -void randomize(void *out, size_t outlen) { - gcry_create_nonce(out, outlen); -} diff --git a/src/gcrypt/crypto.h b/src/gcrypt/crypto.h deleted file mode 100644 index 71df50c0..00000000 --- a/src/gcrypt/crypto.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - crypto.h -- header for crypto.c - Copyright (C) 2007-2009 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_CRYPTO_H__ -#define __TINC_CRYPTO_H__ - -extern void crypto_init(); -extern void crypto_exit(); -extern void randomize(void *, size_t); - -#endif diff --git a/src/gcrypt/digest.c b/src/gcrypt/digest.c deleted file mode 100644 index 4229b0c8..00000000 --- a/src/gcrypt/digest.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - digest.c -- Digest handling - Copyright (C) 2007-2012 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "digest.h" -#include "logger.h" - -static struct { - const char *name; - int algo; - int nid; -} digesttable[] = { - {"none", GCRY_MD_NONE, 0}, - {"sha1", GCRY_MD_SHA1, 64}, - {"sha256", GCRY_MD_SHA256, 672}, - {"sha384", GCRY_MD_SHA384, 673}, - {"sha512", GCRY_MD_SHA512, 674}, -}; - -static bool nametodigest(const char *name, int *algo) { - int i; - - for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) { - if(digesttable[i].name && !strcasecmp(name, digesttable[i].name)) { - *algo = digesttable[i].algo; - return true; - } - } - - return false; -} - -static bool nidtodigest(int nid, int *algo) { - int i; - - for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) { - if(nid == digesttable[i].nid) { - *algo = digesttable[i].algo; - return true; - } - } - - return false; -} - -static bool digesttonid(int algo, int *nid) { - int i; - - for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) { - if(algo == digesttable[i].algo) { - *nid = digesttable[i].nid; - return true; - } - } - - return false; -} - -static bool digest_open(digest_t *digest, int algo, int maclength) { - if(!digesttonid(algo, &digest->nid)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Digest %d has no corresponding nid!", algo); - return false; - } - - unsigned int len = gcry_md_get_algo_dlen(algo); - - if(maclength > len || maclength < 0) - digest->maclength = len; - else - digest->maclength = maclength; - - digest->algo = algo; - digest->hmac = NULL; - - return true; -} - -bool digest_open_by_name(digest_t *digest, const char *name, int maclength) { - int algo; - - if(!nametodigest(name, &algo)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest name '%s'!", name); - return false; - } - - return digest_open(digest, algo, maclength); -} - -bool digest_open_by_nid(digest_t *digest, int nid, int maclength) { - int algo; - - if(!nidtodigest(nid, &algo)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest ID %d!", nid); - return false; - } - - return digest_open(digest, algo, maclength); -} - -bool digest_open_sha1(digest_t *digest, int maclength) { - return digest_open(digest, GCRY_MD_SHA1, maclength); -} - -void digest_close(digest_t *digest) { - if(digest->hmac) - gcry_md_close(digest->hmac); - digest->hmac = NULL; -} - -bool digest_set_key(digest_t *digest, const void *key, size_t len) { - if(!digest->hmac) - gcry_md_open(&digest->hmac, digest->algo, GCRY_MD_FLAG_HMAC); - if(!digest->hmac) - return false; - - return !gcry_md_setkey(digest->hmac, key, len); -} - -bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) { - unsigned int len = gcry_md_get_algo_dlen(digest->algo); - - if(digest->hmac) { - char *tmpdata; - gcry_md_reset(digest->hmac); - gcry_md_write(digest->hmac, indata, inlen); - tmpdata = gcry_md_read(digest->hmac, digest->algo); - if(!tmpdata) - return false; - memcpy(outdata, tmpdata, digest->maclength); - } else { - char tmpdata[len]; - gcry_md_hash_buffer(digest->algo, tmpdata, indata, inlen); - memcpy(outdata, tmpdata, digest->maclength); - } - - return true; -} - -bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *cmpdata) { - unsigned int len = digest->maclength; - char outdata[len]; - - return digest_create(digest, indata, inlen, outdata) && !memcmp(cmpdata, outdata, len); -} - -int digest_get_nid(const digest_t *digest) { - return digest->nid; -} - -size_t digest_length(const digest_t *digest) { - return digest->maclength; -} - -bool digest_active(const digest_t *digest) { - return digest->algo != GCRY_MD_NONE; -} diff --git a/src/gcrypt/digest.h b/src/gcrypt/digest.h deleted file mode 100644 index 9f0d7d85..00000000 --- a/src/gcrypt/digest.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - digest.h -- header file digest.c - Copyright (C) 2007-2009 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_DIGEST_H__ -#define __TINC_DIGEST_H__ - -#include - -#define DIGEST_MAX_SIZE 64 - -typedef struct digest { - int algo; - int nid; - int maclength; - gcry_md_hd_t hmac; -} digest_t; - -extern bool digest_open_by_name(struct digest *, const char *name, int maclength); -extern bool digest_open_by_nid(struct digest *, int nid, int maclength); -extern bool digest_open_sha1(struct digest *, int maclength); -extern void digest_close(struct digest *); -extern bool digest_create(struct digest *, const void *indata, size_t inlen, void *outdata); -extern bool digest_verify(struct digest *, const void *indata, size_t inlen, const void *digestdata); -extern bool digest_set_key(struct digest *, const void *key, size_t len); -extern int digest_get_nid(const struct digest *); -extern size_t digest_length(const struct digest *); -extern bool digest_active(const struct digest *); - -#endif diff --git a/src/gcrypt/ecdh.c b/src/gcrypt/ecdh.c deleted file mode 100644 index 4e30733f..00000000 --- a/src/gcrypt/ecdh.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - ecdh.c -- Diffie-Hellman key exchange handling - Copyright (C) 2011-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include "../ecdh.h" -#include "../logger.h" -#include "../utils.h" -#include "../xalloc.h" - -ecdh_t *ecdh_generate_public(void *pubkey) { - logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); - return NULL; -} - -bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { - return false -} - -void ecdh_free(ecdh_t *ecdh) { -} diff --git a/src/gcrypt/ecdsa.c b/src/gcrypt/ecdsa.c deleted file mode 100644 index ee19aec3..00000000 --- a/src/gcrypt/ecdsa.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - ecdsa.c -- ECDSA key handling - Copyright (C) 2011-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include "../logger.h" -#include "../ecdsa.h" -#include "../utils.h" -#include "../xalloc.h" - -// Get and set ECDSA keys -// -ecdsa_t *ecdsa_set_base64_public_key(const char *p) { - logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); - return NULL; -} - -char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { - return NULL; -} - -// Read PEM ECDSA keys - -ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { - logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); - return NULL; -} - -ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { - logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); - return NULL; -} - -size_t ecdsa_size(ecdsa_t *ecdsa) { - return 0; -} - -bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { - return false; -} - -bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { - return false; -} - -bool ecdsa_active(ecdsa_t *ecdsa) { - return false; -} - -void ecdsa_free(ecdsa_t *ecdsa) { -} diff --git a/src/gcrypt/ecdsagen.c b/src/gcrypt/ecdsagen.c deleted file mode 100644 index 2d4912d5..00000000 --- a/src/gcrypt/ecdsagen.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - ecdsagen.c -- ECDSA key generation and export - Copyright (C) 2011-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include "../ecdsagen.h" -#include "../utils.h" -#include "../xalloc.h" - -// Generate ECDSA key - -ecdsa_t *ecdsa_generate(void) { - logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); - return NULL; -} - -// Write PEM ECDSA keys - -bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { - return false; -} - -bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { - return false; -} diff --git a/src/gcrypt/prf.c b/src/gcrypt/prf.c deleted file mode 100644 index f9a21121..00000000 --- a/src/gcrypt/prf.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - prf.c -- Pseudo-Random Function for key material generation - Copyright (C) 2011-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include "digest.h" -#include "../digest.h" -#include "../prf.h" - -bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { - logger(DEBUG_ALWAYS, LOG_ERR, "PRF support using libgcrypt not implemented"); - return false; -} diff --git a/src/gcrypt/rsa.c b/src/gcrypt/rsa.c deleted file mode 100644 index 751f7b6b..00000000 --- a/src/gcrypt/rsa.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - rsa.c -- RSA key handling - Copyright (C) 2007-2012 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include - -#include "logger.h" -#include "rsa.h" - -// Base64 decoding table - -static const uint8_t b64d[128] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, - 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, - 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, - 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, - 0xff, 0xff -}; - -// PEM encoding/decoding functions - -static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, size_t *outsize) { - bool decode = false; - char line[1024]; - uint16_t word = 0; - int shift = 10; - size_t i, j = 0; - - while(!feof(fp)) { - if(!fgets(line, sizeof line, fp)) - return false; - - if(!decode && !strncmp(line, "-----BEGIN ", 11)) { - if(!strncmp(line + 11, header, strlen(header))) - decode = true; - continue; - } - - if(decode && !strncmp(line, "-----END", 8)) { - break; - } - - if(!decode) - continue; - - for(i = 0; line[i] >= ' '; i++) { - if((signed char)line[i] < 0 || b64d[(int)line[i]] == 0xff) - break; - word |= b64d[(int)line[i]] << shift; - shift -= 6; - if(shift <= 2) { - if(j > size) { - errno = ENOMEM; - return false; - } - - buf[j++] = word >> 8; - word <<= 8; - shift += 8; - } - } - } - - if(outsize) - *outsize = j; - return true; -} - - -// BER decoding functions - -static int ber_read_id(unsigned char **p, size_t *buflen) { - if(*buflen <= 0) - return -1; - - if((**p & 0x1f) == 0x1f) { - int id = 0; - bool more; - while(*buflen > 0) { - id <<= 7; - id |= **p & 0x7f; - more = *(*p)++ & 0x80; - (*buflen)--; - if(!more) - break; - } - return id; - } else { - (*buflen)--; - return *(*p)++ & 0x1f; - } -} - -static size_t ber_read_len(unsigned char **p, size_t *buflen) { - if(*buflen <= 0) - return -1; - - if(**p & 0x80) { - size_t result = 0; - int len = *(*p)++ & 0x7f; - (*buflen)--; - if(len > *buflen) - return 0; - - while(len--) { - result <<= 8; - result |= *(*p)++; - (*buflen)--; - } - - return result; - } else { - (*buflen)--; - return *(*p)++; - } -} - - -static bool ber_read_sequence(unsigned char **p, size_t *buflen, size_t *result) { - int tag = ber_read_id(p, buflen); - size_t len = ber_read_len(p, buflen); - - if(tag == 0x10) { - if(result) - *result = len; - return true; - } else { - return false; - } -} - -static bool ber_read_mpi(unsigned char **p, size_t *buflen, gcry_mpi_t *mpi) { - int tag = ber_read_id(p, buflen); - size_t len = ber_read_len(p, buflen); - gcry_error_t err = 0; - - if(tag != 0x02 || len > *buflen) - return false; - - if(mpi) - err = gcry_mpi_scan(mpi, GCRYMPI_FMT_USG, *p, len, NULL); - - *p += len; - *buflen -= len; - - return mpi ? !err : true; -} - -bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) { - gcry_error_t err = 0; - - err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL) - ?: gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL); - - if(err) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); - return false; - } - - return true; -} - -bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) { - gcry_error_t err = 0; - - err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL) - ?: gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL) - ?: gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL); - - if(err) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); - return false; - } - - return true; -} - -// Read PEM RSA keys - -bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) { - uint8_t derbuf[8096], *derp = derbuf; - size_t derlen; - - if(!pem_decode(fp, "RSA PUBLIC KEY", derbuf, sizeof derbuf, &derlen)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", strerror(errno)); - return NULL; - } - - if(!ber_read_sequence(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, &rsa->n) - || !ber_read_mpi(&derp, &derlen, &rsa->e) - || derlen) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decoding RSA public key"); - return NULL; - } - - return true; -} - -bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) { - uint8_t derbuf[8096], *derp = derbuf; - size_t derlen; - - if(!pem_decode(fp, "RSA PRIVATE KEY", derbuf, sizeof derbuf, &derlen)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", strerror(errno)); - return NULL; - } - - if(!ber_read_sequence(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, &rsa->n) - || !ber_read_mpi(&derp, &derlen, &rsa->e) - || !ber_read_mpi(&derp, &derlen, &rsa->d) - || !ber_read_mpi(&derp, &derlen, NULL) // p - || !ber_read_mpi(&derp, &derlen, NULL) // q - || !ber_read_mpi(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, NULL) // u - || derlen) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decoding RSA private key"); - return NULL; - } - - return true; -} - -size_t rsa_size(rsa_t *rsa) { - return (gcry_mpi_get_nbits(rsa->n) + 7) / 8; -} - -/* Well, libgcrypt has functions to handle RSA keys, but they suck. - * So we just use libgcrypt's mpi functions, and do the math ourselves. - */ - -// TODO: get rid of this macro, properly clean up gcry_ structures after use -#define check(foo) { gcry_error_t err = (foo); if(err) {logger(DEBUG_ALWAYS, LOG_ERR, "gcrypt error %s/%s at %s:%d", gcry_strsource(err), gcry_strerror(err), __FILE__, __LINE__); return false; }} - -bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { - gcry_mpi_t inmpi; - check(gcry_mpi_scan(&inmpi, GCRYMPI_FMT_USG, in, len, NULL)); - - gcry_mpi_t outmpi = gcry_mpi_new(len * 8); - gcry_mpi_powm(outmpi, inmpi, rsa->e, rsa->n); - - int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8; - while(pad--) - *(char *)out++ = 0; - - check(gcry_mpi_print(GCRYMPI_FMT_USG, out,len, NULL, outmpi)); - - return true; -} - -bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { - gcry_mpi_t inmpi; - check(gcry_mpi_scan(&inmpi, GCRYMPI_FMT_USG, in, len, NULL)); - - gcry_mpi_t outmpi = gcry_mpi_new(len * 8); - gcry_mpi_powm(outmpi, inmpi, rsa->d, rsa->n); - - int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8; - while(pad--) - *(char *)out++ = 0; - - check(gcry_mpi_print(GCRYMPI_FMT_USG, out,len, NULL, outmpi)); - - return true; -} diff --git a/src/gcrypt/rsa.h b/src/gcrypt/rsa.h deleted file mode 100644 index 143f0153..00000000 --- a/src/gcrypt/rsa.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - rsa.h -- RSA key handling - Copyright (C) 2007 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_RSA_H__ -#define __TINC_RSA_H__ - -#include - -typedef struct rsa { - gcry_mpi_t n; - gcry_mpi_t e; - gcry_mpi_t d; -} rsa_t; - -extern bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e); -extern bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d); -extern bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp); -extern bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp); -extern size_t rsa_size(rsa_t *rsa); -extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out); -extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out); - -#endif diff --git a/src/gcrypt/rsagen.c b/src/gcrypt/rsagen.c deleted file mode 100644 index 36fb1044..00000000 --- a/src/gcrypt/rsagen.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - rsagen.c -- RSA key generation and export - Copyright (C) 2008-2012 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include - -#include "rsagen.h" - -#if 0 -// Base64 encoding table - -static const char b64e[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -// PEM encoding - -static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size) { - bool decode = false; - char line[1024]; - uint32_t word = 0; - int shift = 0; - size_t i, j = 0; - - fprintf(fp, "-----BEGIN %s-----\n", header); - - for(i = 0; i < size; i += 3) { - if(i <= size - 3) { - word = buf[i] << 16 | buf[i + 1] << 8 | buf[i + 2]; - } else { - word = buf[i] << 16; - if(i == size - 2) - word |= buf[i + 1] << 8; - } - - line[j++] = b64e[(word >> 18) ]; - line[j++] = b64e[(word >> 12) & 0x3f]; - line[j++] = b64e[(word >> 6) & 0x3f]; - line[j++] = b64e[(word ) & 0x3f]; - - if(j >= 64) { - line[j++] = '\n'; - line[j] = 0; - fputs(line, fp); - j = 0; - } - } - - if(size % 3 > 0) { - if(size % 3 > 1) - line[j++] = '='; - line[j++] = '='; - } - - if(j) { - line[j++] = '\n'; - line[j] = 0; - fputs(line, fp); - } - - fprintf(fp, "-----END %s-----\n", header); - - return true; -} - - -// BER encoding functions - -static bool ber_write_id(uint8_t **p, size_t *buflen, int id) { - if(*buflen <= 0) - return false; - - if(id >= 0x1f) { - while(id) { - if(*buflen <= 0) - return false; - - (*buflen)--; - **p = id & 0x7f; - id >>= 7; - if(id) - **p |= 0x80; - (*p)++; - } - } else { - (*buflen)--; - *(*p)++ = id; - } - - return true; -} - -static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) { - do { - if(*buflen <= 0) - return false; - - (*buflen)--; - **p = len & 0x7f; - len >>= 7; - if(len) - **p |= 0x80; - (*p)++; - } while(len); - - return true; -} - -static bool ber_write_sequence(uint8_t **p, size_t *buflen, uint8_t *seqbuf, size_t seqlen) { - if(!ber_write_id(p, buflen, 0x10) || !ber_write_len(p, buflen, seqlen) || *buflen < seqlen) - return false; - - memcpy(*p, seqbuf, seqlen); - *p += seqlen; - *buflen -= seqlen; - - return true; -} - -static bool ber_write_mpi(uint8_t **p, size_t *buflen, gcry_mpi_t mpi) { - uint8_t tmpbuf[1024]; - size_t tmplen = sizeof tmpbuf; - gcry_error_t err; - - err = gcry_mpi_aprint(GCRYMPI_FMT_USG, &tmpbuf, &tmplen, mpi); - if(err) - return false; - - if(!ber_write_id(p, buflen, 0x02) || !ber_write_len(p, buflen, tmplen) || *buflen < tmplen) - return false; - - memcpy(*p, tmpbuf, tmplen); - *p += tmplen; - *buflen -= tmplen; - - return true; -} - -// Write PEM RSA keys - -bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) { - uint8_t derbuf1[8096]; - uint8_t derbuf2[8096]; - uint8_t *derp1 = derbuf1; - uint8_t *derp2 = derbuf2; - size_t derlen1 = sizeof derbuf1; - size_t derlen2 = sizeof derbuf2; - - if(!ber_write_mpi(&derp1, &derlen1, &rsa->n) - || !ber_write_mpi(&derp1, &derlen1, &rsa->e) - || !ber_write_sequence(&derp2, &derlen2, derbuf1, derlen1)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA public key"); - return false; - } - - if(!pem_encode(fp, "RSA PUBLIC KEY", derbuf2, derlen2)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to write RSA public key: %s", strerror(errno)); - return false; - } - - return true; -} - -bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) { - uint8_t derbuf1[8096]; - uint8_t derbuf2[8096]; - uint8_t *derp1 = derbuf1; - uint8_t *derp2 = derbuf2; - size_t derlen1 = sizeof derbuf1; - size_t derlen2 = sizeof derbuf2; - - if(!ber_write_mpi(&derp1, &derlen1, &bits) - || ber_write_mpi(&derp1, &derlen1, &rsa->n) // modulus - || ber_write_mpi(&derp1, &derlen1, &rsa->e) // public exponent - || ber_write_mpi(&derp1, &derlen1, &rsa->d) // private exponent - || ber_write_mpi(&derp1, &derlen1, &p) - || ber_write_mpi(&derp1, &derlen1, &q) - || ber_write_mpi(&derp1, &derlen1, &exp1) - || ber_write_mpi(&derp1, &derlen1, &exp2) - || ber_write_mpi(&derp1, &derlen1, &coeff)) - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA private key"); - return false; - } - - if(!pem_encode(fp, "RSA PRIVATE KEY", derbuf2, derlen2)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to write RSA private key: %s", strerror(errno)); - return false; - } - - return true; -} -#endif - -bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) { - return false; -} - -bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) { - return false; -} - -bool rsa_generate(rsa_t *rsa, size_t bits, unsigned long exponent) { - fprintf(stderr, "Generating RSA keys with libgcrypt not implemented yet\n"); - return false; -} diff --git a/src/gcrypt/rsagen.h b/src/gcrypt/rsagen.h deleted file mode 100644 index 422d1560..00000000 --- a/src/gcrypt/rsagen.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - rsagen.h -- RSA key generation and export - Copyright (C) 2008 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_RSAGEN_H__ -#define __TINC_RSAGEN_H__ - -#include "rsa.h" - -extern bool rsa_generate(rsa_t *rsa, size_t bits, unsigned long exponent); -extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp); -extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp); - -#endif diff --git a/src/graph.c b/src/graph.c index 396e35a3..f8c906b0 100644 --- a/src/graph.c +++ b/src/graph.c @@ -45,17 +45,13 @@ #include "system.h" #include "connection.h" -#include "device.h" #include "edge.h" #include "graph.h" #include "list.h" #include "logger.h" -#include "names.h" #include "netutl.h" #include "node.h" #include "protocol.h" -#include "script.h" -#include "subnet.h" #include "utils.h" #include "xalloc.h" #include "graph.h" @@ -232,33 +228,7 @@ static void check_reachability(void) { timeout_del(&n->mtutimeout); - char *name; - char *address; - char *port; - char *envp[8] = {NULL}; - - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NODE=%s", n->name); - sockaddr2str(&n->address, &address, &port); - xasprintf(&envp[4], "REMOTEADDRESS=%s", address); - xasprintf(&envp[5], "REMOTEPORT=%s", port); - xasprintf(&envp[6], "NAME=%s", myself->name); - - execute_script(n->status.reachable ? "host-up" : "host-down", envp); - - xasprintf(&name, n->status.reachable ? "hosts/%s-up" : "hosts/%s-down", n->name); - execute_script(name, envp); - - free(name); - free(address); - free(port); - - for(int i = 0; i < 7; i++) - free(envp[i]); - - subnet_update(n, NULL, n->status.reachable); + //TODO: callback to application to inform of this node going up/down if(!n->status.reachable) { update_node_udp(n, NULL); @@ -277,7 +247,6 @@ static void check_reachability(void) { } void graph(void) { - subnet_cache_flush(); sssp_bfs(); check_reachability(); mst_kruskal(); diff --git a/src/graph.h b/src/graph.h index fa521f53..00912b96 100644 --- a/src/graph.h +++ b/src/graph.h @@ -22,6 +22,5 @@ #define __TINC_GRAPH_H__ extern void graph(void); -extern void dump_graph(void); #endif /* __TINC_GRAPH_H__ */ diff --git a/src/info.c b/src/info.c deleted file mode 100644 index af085bc3..00000000 --- a/src/info.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - info.c -- Show information about a node, subnet or address - Copyright (C) 2012-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "control_common.h" -#include "list.h" -#include "subnet.h" -#include "tincctl.h" -#include "info.h" -#include "xalloc.h" - -void logger(int level, int priority, const char *format, ...) { - va_list ap; - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); - fputc('\n', stderr); -} - -char *strip_weight(char *netstr) { - int len = strlen(netstr); - if(len >= 3 && !strcmp(netstr + len - 3, "#10")) - netstr[len - 3] = 0; - return netstr; -} - -static int info_node(int fd, const char *item) { - // Check the list of nodes - sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_NODES, item); - - bool found = false; - char line[4096]; - - char node[4096]; - char from[4096]; - char to[4096]; - char subnet[4096]; - char host[4096]; - char port[4096]; - char via[4096]; - char nexthop[4096]; - int code, req, cipher, digest, maclength, compression, distance; - short int pmtu, minmtu, maxmtu; - unsigned int options; - union { - node_status_t bits; - uint32_t raw; - } status_union; - node_status_t status; - long int last_state_change; - - while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s port %s %d %d %d %d %x %"PRIx32" %s %s %d %hd %hd %hd %ld", &code, &req, node, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); - - if(n == 2) - break; - - if(n != 18) { - fprintf(stderr, "Unable to parse node dump from tincd.\n"); - return 1; - } - - if(!strcmp(node, item)) { - found = true; - break; - } - } - - if(!found) { - fprintf(stderr, "Unknown node %s.\n", item); - return 1; - } - - while(recvline(fd, line, sizeof line)) { - if(sscanf(line, "%d %d %s", &code, &req, node) == 2) - break; - } - - printf("Node: %s\n", item); - printf("Address: %s port %s\n", host, port); - - char timestr[32] = "never"; - time_t lsc_time = last_state_change; - - if(last_state_change) - strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&lsc_time)); - - status = status_union.bits; - - if(status.reachable) - printf("Online since: %s\n", timestr); - else - printf("Last seen: %s\n", timestr); - - printf("Status: "); - if(status.validkey) - printf(" validkey"); - if(status.visited) - printf(" visited"); - if(status.reachable) - printf(" reachable"); - if(status.indirect) - printf(" indirect"); - if(status.sptps) - printf(" sptps"); - if(status.udp_confirmed) - printf(" udp_confirmed"); - printf("\n"); - - printf("Options: "); - if(options & OPTION_INDIRECT) - printf(" indirect"); - if(options & OPTION_TCPONLY) - printf(" tcponly"); - if(options & OPTION_PMTU_DISCOVERY) - printf(" pmtu_discovery"); - if(options & OPTION_CLAMP_MSS) - printf(" clamp_mss"); - printf("\n"); - printf("Protocol: %d.%d\n", PROT_MAJOR, OPTION_VERSION(options)); - printf("Reachability: "); - if(!strcmp(host, "MYSELF")) - printf("can reach itself\n"); - else if(!status.reachable) - printf("unreachable\n"); - else if(strcmp(via, item)) - printf("indirectly via %s\n", via); - else if(!status.validkey) - printf("unknown\n"); - else if(minmtu > 0) - printf("directly with UDP\nPMTU: %d\n", pmtu); - else if(!strcmp(nexthop, item)) - printf("directly with TCP\n"); - else - printf("none, forwarded via %s\n", nexthop); - - // List edges - printf("Edges: "); - sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_EDGES, item); - while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s", &code, &req, from, to); - if(n == 2) - break; - if(n != 4) { - fprintf(stderr, "Unable to parse edge dump from tincd.\n%s\n", line); - return 1; - } - if(!strcmp(from, item)) - printf(" %s", to); - } - printf("\n"); - - // List subnets - printf("Subnets: "); - sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); - while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s", &code, &req, subnet, from); - if(n == 2) - break; - if(n != 4) { - fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); - return 1; - } - if(!strcmp(from, item)) - printf(" %s", strip_weight(subnet)); - } - printf("\n"); - - return 0; -} - -static int info_subnet(int fd, const char *item) { - subnet_t subnet, find; - - if(!str2net(&find, item)) { - fprintf(stderr, "Could not parse subnet or address '%s'.\n", item); - return 1; - } - - bool address = !strchr(item, '/'); - bool weight = strchr(item, '#'); - bool found = false; - - char line[4096]; - char netstr[4096]; - char owner[4096]; - - int code, req; - - sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); - while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s", &code, &req, netstr, owner); - if(n == 2) - break; - - if(n != 4 || !str2net(&subnet, netstr)) { - fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); - return 1; - } - - if(find.type != subnet.type) - continue; - - if(weight) { - if(find.weight != subnet.weight) - continue; - } - - if(find.type == SUBNET_IPV4) { - if(address) { - if(maskcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, subnet.net.ipv4.prefixlength)) - continue; - } else { - if(find.net.ipv4.prefixlength != subnet.net.ipv4.prefixlength) - continue; - if(memcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, sizeof subnet.net.ipv4)) - continue; - } - } else if(find.type == SUBNET_IPV6) { - if(address) { - if(maskcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, subnet.net.ipv6.prefixlength)) - continue; - } else { - if(find.net.ipv6.prefixlength != subnet.net.ipv6.prefixlength) - continue; - if(memcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, sizeof subnet.net.ipv6)) - continue; - } - } if(find.type == SUBNET_MAC) { - if(memcmp(&find.net.mac.address, &subnet.net.mac.address, sizeof subnet.net.mac)) - continue; - } - - found = true; - printf("Subnet: %s\n", strip_weight(netstr)); - printf("Owner: %s\n", owner); - } - - if(!found) { - if(address) - fprintf(stderr, "Unknown address %s.\n", item); - else - fprintf(stderr, "Unknown subnet %s.\n", item); - return 1; - } - - return 0; -} - -int info(int fd, const char *item) { - if(check_id(item)) - return info_node(fd, item); - if(strchr(item, '.') || strchr(item, ':')) - return info_subnet(fd, item); - - fprintf(stderr, "Argument is not a node name, subnet or address.\n"); - return 1; -} diff --git a/src/info.h b/src/info.h deleted file mode 100644 index a3f387ff..00000000 --- a/src/info.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - info.h -- header for info.c. - Copyright (C) 2012 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_INFO_H__ -#define __TINC_INFO_H__ - -extern int info(int fd, const char *item); -extern char *strip_weight(char *); - -#endif - diff --git a/src/invitation.c b/src/invitation.c index cdef3d04..b6486c84 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -24,10 +24,8 @@ #include "ecdsa.h" #include "ecdsagen.h" #include "invitation.h" -#include "names.h" #include "netutl.h" #include "rsagen.h" -#include "script.h" #include "sptps.h" #include "tincctl.h" #include "utils.h" @@ -434,22 +432,6 @@ int cmd_invite(int argc, char *argv[]) { char *url; xasprintf(&url, "%s/%s%s", address, hash, cookie); - // Call the inviation-created script - char *envp[6] = {}; - xasprintf(&envp[0], "NAME=%s", myname); - xasprintf(&envp[1], "NETNAME=%s", netname); - xasprintf(&envp[2], "NODE=%s", argv[1]); - xasprintf(&envp[3], "INVITATION_FILE=%s", filename); - xasprintf(&envp[4], "INVITATION_URL=%s", url); - execute_script("invitation-created", envp); - for(int i = 0; i < 6 && envp[i]; i++) - free(envp[i]); - - puts(url); - free(url); - free(filename); - free(address); - return 0; } @@ -563,13 +545,6 @@ static bool finalize_join(void) { char temp_netname[32]; make_names: - if(!confbasegiven) { - free(confbase); - confbase = NULL; - } - - make_names(); - free(tinc_conf); free(hosts_dir); @@ -775,7 +750,6 @@ ask_netname: free(newbase); netname = line; - make_names(); } fprintf(stderr, "Configuration stored in: %s\n", confbase); @@ -836,11 +810,6 @@ int cmd_join(int argc, char *argv[]) { } // Make sure confbase exists and is accessible. - if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) { - fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno)); - return 1; - } - if(mkdir(confbase, 0777) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno)); return 1; diff --git a/src/libmeshlink.c b/src/libmeshlink.c index a1d23e53..c2fe1141 100644 --- a/src/libmeshlink.c +++ b/src/libmeshlink.c @@ -39,7 +39,6 @@ static bool do_mlock = false; */ bool setup_meshlink_network(void) { init_connections(); - init_subnets(); init_nodes(); init_edges(); init_requests(); @@ -63,13 +62,6 @@ bool setup_meshlink_network(void) { if(!setup_myself()) return false; - if(!init_control()) - return false; - - /* Run subnet-up scripts for our own subnets */ - - subnet_update(myself, NULL, true); - return true; } @@ -388,8 +380,7 @@ int check_port(char *name) { } //tinc_setup() should basically do what cmd_init() from src/tincctl.c does, except it doesn't have to generate a tinc-up script. bool tinc_setup(const char* confbaseapi, const char* name) { - confbase = confbaseapi; - make_names(); + confbase = xstrdup(confbaseapi); xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); if(!access(tinc_conf, F_OK)) { @@ -402,11 +393,6 @@ bool tinc_setup(const char* confbaseapi, const char* name) { return false; } - if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) { - fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno)); - return false; - } - if(mkdir(confbase, 0777) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno)); return false; @@ -445,15 +431,14 @@ return true; } bool tinc_main_thread(void * in) { + static bool status = false; -static bool status = false; - -/* If nonzero, write log entries to a separate file. */ -bool use_logfile = false; + /* If nonzero, write log entries to a separate file. */ + bool use_logfile = false; -confbase = (char*) in; + confbase = (char*) in; - openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR); + openlogger("tinc", LOGMODE_STDERR); init_configuration(&config_tree); @@ -540,7 +525,6 @@ end: exit_configuration(&config_tree); free(cmdline_conf); - free_names(); return status; diff --git a/src/libmeshlink.h b/src/libmeshlink.h index e99f8957..4c7c4a95 100644 --- a/src/libmeshlink.h +++ b/src/libmeshlink.h @@ -19,7 +19,6 @@ #include "system.h" #include "node.h" -#include "names.h" //#include "tincctl.h" #include "xalloc.h" #include "logger.h" diff --git a/src/linux/device.c b/src/linux/device.c deleted file mode 100644 index 6ed1622c..00000000 --- a/src/linux/device.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - device.c -- Interaction with Linux ethertap and tun/tap device - Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#define DEFAULT_DEVICE "/dev/net/tun" - -#include "../conf.h" -#include "../device.h" -#include "../logger.h" -#include "../names.h" -#include "../net.h" -#include "../route.h" -#include "../utils.h" -#include "../xalloc.h" -#include "../device.h" - -typedef enum device_type_t { - DEVICE_TYPE_TUN, - DEVICE_TYPE_TAP, -} device_type_t; - -int device_fd = -1; -static device_type_t device_type; -char *device = NULL; -char *iface = NULL; -static char *type = NULL; -static char ifrname[IFNAMSIZ]; -static char *device_info; - -static bool setup_device(void) { - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) - device = xstrdup(DEFAULT_DEVICE); - - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) - if(netname) - iface = xstrdup(netname); - - device_fd = open(device, O_RDWR | O_NONBLOCK); - - if(device_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device, strerror(errno)); - return false; - } - -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif - - struct ifreq ifr = {{{0}}}; - - get_config_string(lookup_config(config_tree, "DeviceType"), &type); - - if(type && strcasecmp(type, "tun") && strcasecmp(type, "tap")) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); - return false; - } - - if((type && !strcasecmp(type, "tun")) || (!type && routing_mode == RMODE_ROUTER)) { - ifr.ifr_flags = IFF_TUN; - device_type = DEVICE_TYPE_TUN; - device_info = "Linux tun/tap device (tun mode)"; - } else { - if (routing_mode == RMODE_ROUTER) - overwrite_mac = true; - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - device_type = DEVICE_TYPE_TAP; - device_info = "Linux tun/tap device (tap mode)"; - } - -#ifdef IFF_ONE_QUEUE - /* Set IFF_ONE_QUEUE flag... */ - - bool t1q = false; - if(get_config_bool(lookup_config(config_tree, "IffOneQueue"), &t1q) && t1q) - ifr.ifr_flags |= IFF_ONE_QUEUE; -#endif - - if(iface) - strncpy(ifr.ifr_name, iface, IFNAMSIZ); - - if(!ioctl(device_fd, TUNSETIFF, &ifr)) { - strncpy(ifrname, ifr.ifr_name, IFNAMSIZ); - free(iface); - iface = xstrdup(ifrname); - } - - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - - return true; -} - -static void close_device(void) { - close(device_fd); - - free(type); - free(device); - free(iface); -} - -static bool read_packet(vpn_packet_t *packet) { - int inlen; - - switch(device_type) { - case DEVICE_TYPE_TUN: - inlen = read(device_fd, packet->data + 10, MTU - 10); - - if(inlen <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", - device_info, device, strerror(errno)); - return false; - } - - memset(packet->data, 0, 12); - packet->len = inlen + 10; - break; - case DEVICE_TYPE_TAP: - inlen = read(device_fd, packet->data, MTU); - - if(inlen <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", - device_info, device, strerror(errno)); - return false; - } - - packet->len = inlen; - break; - default: - abort(); - } - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); - - return true; -} - -static bool write_packet(vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); - - switch(device_type) { - case DEVICE_TYPE_TUN: - packet->data[10] = packet->data[11] = 0; - if(write(device_fd, packet->data + 10, packet->len - 10) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - break; - case DEVICE_TYPE_TAP: - if(write(device_fd, packet->data, packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - break; - default: - abort(); - } - - return true; -} - -const devops_t os_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, -}; diff --git a/src/logger.c b/src/logger.c index 2b4c7e38..bceccbc6 100644 --- a/src/logger.c +++ b/src/logger.c @@ -22,22 +22,17 @@ #include "conf.h" #include "meta.h" -#include "names.h" #include "logger.h" #include "connection.h" -#include "control_common.h" #include "sptps.h" debug_t debug_level = DEBUG_NOTHING; static logmode_t logmode = LOGMODE_STDERR; static pid_t logpid; -static FILE *logfile = NULL; #ifdef HAVE_MINGW static HANDLE loghandle = NULL; #endif static const char *logident = NULL; -bool logcontrol = false; - static void real_logger(int level, int priority, const char *message) { char timestr[32] = ""; @@ -47,7 +42,7 @@ static void real_logger(int level, int priority, const char *message) { if(suppress) return; - if(!logcontrol && (level > debug_level || logmode == LOGMODE_NULL)) + if(level > debug_level || logmode == LOGMODE_NULL) return; if(level <= debug_level) { @@ -56,14 +51,6 @@ static void real_logger(int level, int priority, const char *message) { fprintf(stderr, "%s\n", message); fflush(stderr); break; - case LOGMODE_FILE: - if(!now.tv_sec) - gettimeofday(&now, NULL); - time_t now_sec = now.tv_sec; - strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now_sec)); - fprintf(logfile, "%s %s[%ld]: %s\n", timestr, logident, (long)logpid, message); - fflush(logfile); - break; case LOGMODE_SYSLOG: #ifdef HAVE_MINGW { @@ -80,22 +67,6 @@ static void real_logger(int level, int priority, const char *message) { break; } } - - if(logcontrol) { - suppress = true; - logcontrol = false; - for list_each(connection_t, c, connection_list) { - if(!c->status.log) - continue; - logcontrol = true; - if(level > (c->outcompression >= 0 ? c->outcompression : debug_level)) - continue; - int len = strlen(message); - if(send_request(c, "%d %d %d", CONTROL, REQ_LOG, len)) - send_meta(c, message, len); - } - suppress = false; - } } void logger(int level, int priority, const char *format, ...) { @@ -129,14 +100,6 @@ void openlogger(const char *ident, logmode_t mode) { case LOGMODE_STDERR: logpid = getpid(); break; - case LOGMODE_FILE: - logpid = getpid(); - logfile = fopen(logfilename, "a"); - if(!logfile) { - fprintf(stderr, "Could not open log file %s: %s\n", logfilename, strerror(errno)); - logmode = LOGMODE_NULL; - } - break; case LOGMODE_SYSLOG: #ifdef HAVE_MINGW loghandle = RegisterEventSource(NULL, logident); @@ -161,26 +124,8 @@ void openlogger(const char *ident, logmode_t mode) { sptps_log = sptps_log_quiet; } -void reopenlogger() { - if(logmode != LOGMODE_FILE) - return; - - fflush(logfile); - FILE *newfile = fopen(logfilename, "a"); - if(!newfile) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reopen log file %s: %s", logfilename, strerror(errno)); - return; - } - fclose(logfile); - logfile = newfile; -} - - void closelogger(void) { switch(logmode) { - case LOGMODE_FILE: - fclose(logfile); - break; case LOGMODE_SYSLOG: #ifdef HAVE_MINGW DeregisterEventSource(loghandle); diff --git a/src/logger.h b/src/logger.h index 637eef84..f417b783 100644 --- a/src/logger.h +++ b/src/logger.h @@ -37,7 +37,6 @@ typedef enum debug_t { typedef enum logmode_t { LOGMODE_NULL, LOGMODE_STDERR, - LOGMODE_FILE, LOGMODE_SYSLOG } logmode_t; @@ -68,7 +67,6 @@ enum { extern debug_t debug_level; extern bool logcontrol; extern void openlogger(const char *, logmode_t); -extern void reopenlogger(void); extern void logger(int, int, const char *, ...) __attribute__ ((__format__(printf, 3, 4))); extern void closelogger(void); diff --git a/src/mingw/common.h b/src/mingw/common.h deleted file mode 100644 index 6e5e75ce..00000000 --- a/src/mingw/common.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * TAP-Win32 -- A kernel driver to provide virtual tap device functionality - * on Windows. Originally derived from the CIPE-Win32 - * project by Damion K. Wilson, with extensive modifications by - * James Yonan. - * - * All source code which derives from the CIPE-Win32 project is - * Copyright (C) Damion K. Wilson, 2003, and is released under the - * GPL version 2 (see below). - * - * All other source code is Copyright (C) James Yonan, 2003-2004, - * and is released under the GPL version 2 (see below). - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -//=============================================== -// This file is included both by OpenVPN and -// the TAP-Win32 driver and contains definitions -// common to both. -//=============================================== - -//============= -// TAP IOCTLs -//============= - -#define TAP_CONTROL_CODE(request,method) \ - CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) - -#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) -#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) -#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) -#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) -#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) -#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) - -//================= -// Registry keys -//================= - -#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" - -#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" - -//====================== -// Filesystem prefixes -//====================== - -#define USERMODEDEVICEDIR "\\\\.\\Global\\" -#define SYSDEVICEDIR "\\Device\\" -#define USERDEVICEDIR "\\DosDevices\\Global\\" -#define TAPSUFFIX ".tap" - -//========================================================= -// TAP_COMPONENT_ID -- This string defines the TAP driver -// type -- different component IDs can reside in the system -// simultaneously. -//========================================================= - -#define TAP_COMPONENT_ID "tap0801" diff --git a/src/mingw/device.c b/src/mingw/device.c deleted file mode 100644 index 0642725f..00000000 --- a/src/mingw/device.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - device.c -- Interaction with Windows tap driver in a MinGW environment - Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#include - -#include "../conf.h" -#include "../device.h" -#include "../logger.h" -#include "../names.h" -#include "../net.h" -#include "../route.h" -#include "../utils.h" -#include "../xalloc.h" - -#include "common.h" - -int device_fd = -1; -static HANDLE device_handle = INVALID_HANDLE_VALUE; -char *device = NULL; -char *iface = NULL; -static char *device_info = NULL; - -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; - -extern char *myport; - -static DWORD WINAPI tapreader(void *bla) { - int status; - DWORD len; - OVERLAPPED overlapped; - vpn_packet_t packet; - - logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader running"); - - /* Read from tap device and send to parent */ - - overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - - for(;;) { - overlapped.Offset = 0; - overlapped.OffsetHigh = 0; - ResetEvent(overlapped.hEvent); - - status = ReadFile(device_handle, (void *)packet.data, MTU, &len, &overlapped); - - if(!status) { - if(GetLastError() == ERROR_IO_PENDING) { - WaitForSingleObject(overlapped.hEvent, INFINITE); - if(!GetOverlappedResult(device_handle, &overlapped, &len, FALSE)) - continue; - } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return -1; - } - } - - EnterCriticalSection(&mutex); - packet.len = len; - packet.priority = 0; - route(myself, &packet); - event_flush_output(); - LeaveCriticalSection(&mutex); - } -} - -static bool setup_device(void) { - HKEY key, key2; - int i; - - char regpath[1024]; - char adapterid[1024]; - char adaptername[1024]; - char tapname[1024]; - DWORD len; - unsigned long status; - - bool found = false; - - int err; - HANDLE thread; - - 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, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) { - logger(DEBUG_ALWAYS, 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", NETWORK_CONNECTIONS_KEY, adapterid); - - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) - continue; - - len = sizeof adaptername; - err = RegQueryValueEx(key2, "Name", 0, 0, (LPBYTE)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 | FILE_FLAG_OVERLAPPED, 0); - if(device_handle != INVALID_HANDLE_VALUE) { - found = true; - break; - } - } - - RegCloseKey(key); - - if(!found) { - logger(DEBUG_ALWAYS, LOG_ERR, "No Windows tap device found!"); - return false; - } - - if(!device) - device = xstrdup(adapterid); - - if(!iface) - iface = xstrdup(adaptername); - - /* Try to open the corresponding tap device */ - - if(device_handle == INVALID_HANDLE_VALUE) { - snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, device); - device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); - } - - if(device_handle == INVALID_HANDLE_VALUE) { - logger(DEBUG_ALWAYS, LOG_ERR, "%s (%s) is not a usable Windows tap device: %s", device, iface, winerror(GetLastError())); - return false; - } - - /* 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(DEBUG_ALWAYS, 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; - } - - /* Start the tap reader */ - - thread = CreateThread(NULL, 0, tapreader, NULL, 0, NULL); - - if(!thread) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "CreateThread", winerror(GetLastError())); - return false; - } - - /* Set media status for newer TAP-Win32 devices */ - - status = true; - DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); - - device_info = "Windows tap device"; - - logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); - - return true; -} - -static void close_device(void) { - CloseHandle(device_handle); - - free(device); - free(iface); -} - -static bool read_packet(vpn_packet_t *packet) { - return false; -} - -static bool write_packet(vpn_packet_t *packet) { - DWORD outlen; - OVERLAPPED overlapped = {0}; - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); - - if(!WriteFile(device_handle, packet->data, packet->len, &outlen, &overlapped)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); - return false; - } - - device_total_out += packet->len; - - return true; -} - -const devops_t os_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, -}; diff --git a/src/multicast_device.c b/src/multicast_device.c deleted file mode 100644 index 48e12003..00000000 --- a/src/multicast_device.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - device.c -- multicast socket - Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "conf.h" -#include "device.h" -#include "net.h" -#include "logger.h" -#include "netutl.h" -#include "utils.h" -#include "route.h" -#include "xalloc.h" - -static char *device_info; - -static struct addrinfo *ai = NULL; -static mac_t ignore_src = {{0}}; - -static bool setup_device(void) { - char *host = NULL; - char *port; - char *space; - int ttl = 1; - - device_info = "multicast socket"; - - get_config_string(lookup_config(config_tree, "Interface"), &iface); - - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Device variable required for %s", device_info); - goto error; - } - - host = xstrdup(device); - space = strchr(host, ' '); - if(!space) { - logger(DEBUG_ALWAYS, LOG_ERR, "Port number required for %s", device_info); - goto error; - } - - *space++ = 0; - port = space; - space = strchr(port, ' '); - - if(space) { - *space++ = 0; - ttl = atoi(space); - } - - ai = str2addrinfo(host, port, SOCK_DGRAM); - if(!ai) - goto error; - - device_fd = socket(ai->ai_family, SOCK_DGRAM, IPPROTO_UDP); - if(device_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Creating socket failed: %s", sockstrerror(sockerrno)); - goto error; - } - -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif - - static const int one = 1; - setsockopt(device_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof one); - - if(bind(device_fd, ai->ai_addr, ai->ai_addrlen)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s %s: %s", host, port, sockstrerror(sockerrno)); - goto error; - } - - switch(ai->ai_family) { -#ifdef IP_ADD_MEMBERSHIP - case AF_INET: { - struct ip_mreq mreq; - struct sockaddr_in in; - memcpy(&in, ai->ai_addr, sizeof in); - mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr; - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - if(setsockopt(device_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof mreq)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); - goto error; - } -#ifdef IP_MULTICAST_LOOP - setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof one); -#endif -#ifdef IP_MULTICAST_TTL - setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, sizeof ttl); -#endif - } break; -#endif - -#ifdef IPV6_JOIN_GROUP - case AF_INET6: { - struct ipv6_mreq mreq; - struct sockaddr_in6 in6; - memcpy(&in6, ai->ai_addr, sizeof in6); - memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof mreq.ipv6mr_multiaddr); - mreq.ipv6mr_interface = in6.sin6_scope_id; - if(setsockopt(device_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof mreq)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); - goto error; - } -#ifdef IPV6_MULTICAST_LOOP - setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof one); -#endif -#ifdef IPV6_MULTICAST_HOPS - setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&ttl, sizeof ttl); -#endif - } break; -#endif - - default: - logger(DEBUG_ALWAYS, LOG_ERR, "Multicast for address family %hx unsupported", ai->ai_family); - goto error; - } - - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - - return true; - -error: - if(device_fd >= 0) - closesocket(device_fd); - if(ai) - freeaddrinfo(ai); - free(host); - - return false; -} - -static void close_device(void) { - close(device_fd); - - free(device); - free(iface); - - if(ai) - freeaddrinfo(ai); -} - -static bool read_packet(vpn_packet_t *packet) { - int lenin; - - if((lenin = recv(device_fd, (void *)packet->data, MTU, 0)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - if(!memcmp(&ignore_src, packet->data + 6, sizeof ignore_src)) { - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Ignoring loopback packet of %d bytes from %s", lenin, device_info); - return false; - } - - packet->len = lenin; - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); - - return true; -} - -static bool write_packet(vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); - - if(sendto(device_fd, (void *)packet->data, packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - - memcpy(&ignore_src, packet->data + 6, sizeof ignore_src); - - return true; -} - -const devops_t multicast_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, -}; diff --git a/src/names.c b/src/names.c deleted file mode 100644 index 138c3cc0..00000000 --- a/src/names.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - names.c -- generate commonly used (file)names - Copyright (C) 1998-2005 Ivo Timmermans - 2000-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "logger.h" -#include "xalloc.h" - -char *netname = NULL; -char *confdir = NULL; /* base configuration directory */ -char *confbase = NULL; /* base configuration directory for this instance of tinc */ -bool confbase_given; -char *identname = NULL; /* program name for syslog */ -char *unixsocketname = NULL; /* UNIX socket location */ -char *logfilename = NULL; /* log file location */ -char *pidfilename = NULL; -char *program_name = NULL; - -/* - Set all files and paths according to netname -*/ -void make_names(void) { -#ifdef HAVE_MINGW - HKEY key; - char installdir[1024] = ""; - DWORD len = sizeof installdir; -#endif - confbase_given = confbase; - - if(netname && confbase) - logger(DEBUG_ALWAYS, LOG_INFO, "Both netname and configuration directory given, using the latter..."); - - if(netname) - xasprintf(&identname, "tinc.%s", netname); - else - identname = xstrdup("tinc"); - -#ifdef HAVE_MINGW - if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { - if(!RegQueryValueEx(key, NULL, 0, 0, (LPBYTE)installdir, &len)) { - confdir = xstrdup(installdir); - if(!logfilename) - xasprintf(&logfilename, "%s" SLASH "log" SLASH "%s.log", installdir, identname); - if(!confbase) { - if(netname) - xasprintf(&confbase, "%s" SLASH "%s", installdir, netname); - else - xasprintf(&confbase, "%s", installdir); - } - if(!pidfilename) - xasprintf(&pidfilename, "%s" SLASH "pid", confbase); - } - RegCloseKey(key); - } -#endif - if(!confdir) - confdir = xstrdup(CONFDIR SLASH "tinc"); - - if(!logfilename) - xasprintf(&logfilename, LOCALSTATEDIR SLASH "log" SLASH "%s.log", identname); - - if(!pidfilename) - xasprintf(&pidfilename, SLASH "tmp" SLASH "%s.pid", identname); - - if(!unixsocketname) { - int len = strlen(pidfilename); - unixsocketname = xmalloc(len + 8); - strcpy(unixsocketname, pidfilename); - if(len > 4 && !strcmp(pidfilename + len - 4, ".pid")) - strcpy(unixsocketname + len - 4, ".socket"); - else - strcpy(unixsocketname + len, ".socket"); - } - - if(!confbase) { - if(netname) - xasprintf(&confbase, CONFDIR SLASH "tinc" SLASH "%s", netname); - else - xasprintf(&confbase, CONFDIR SLASH "tinc"); - } -} - -void free_names(void) { - free(identname); - free(netname); - free(unixsocketname); - free(pidfilename); - free(logfilename); - free(confbase); - free(confdir); -} diff --git a/src/names.h b/src/names.h deleted file mode 100644 index 1163ff6e..00000000 --- a/src/names.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - names.h -- header for names.c - Copyright (C) 1998-2005 Ivo Timmermans - 2000-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_NAMES_H__ -#define __TINC_NAMES_H__ - -extern char *confdir; -extern char *confbase; -extern bool confbase_given; -extern char *netname; -extern char *identname; -extern char *unixsocketname; -extern char *logfilename; -extern char *pidfilename; -extern char *program_name; - -extern void make_names(void); -extern void free_names(void); - -#endif /* __TINC_NAMES_H__ */ diff --git a/src/net.c b/src/net.c index baf576d5..23dfc6a6 100644 --- a/src/net.c +++ b/src/net.c @@ -25,15 +25,12 @@ #include "utils.h" #include "conf.h" #include "connection.h" -#include "device.h" #include "graph.h" #include "logger.h" #include "meta.h" -#include "names.h" #include "net.h" #include "netutl.h" #include "protocol.h" -#include "subnet.h" #include "xalloc.h" int contradicting_add_edge = 0; @@ -43,23 +40,21 @@ time_t last_config_check = 0; static timeout_t pingtimer; static timeout_t periodictimer; -/* Purge edges and subnets of unreachable nodes. Use carefully. */ +//TODO: move this to a better place +char *confbase; +/* Purge edges of unreachable nodes. Use carefully. */ + +// TODO: remove void purge(void) { logger(DEBUG_PROTOCOL, LOG_DEBUG, "Purging unreachable nodes"); - /* Remove all edges and subnets owned by unreachable nodes. */ + /* Remove all edges owned by unreachable nodes. */ for splay_each(node_t, n, node_tree) { if(!n->status.reachable) { logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Purging node %s (%s)", n->name, n->hostname); - for splay_each(subnet_t, s, n->subnet_tree) { - send_del_subnet(everyone, s); - if(!strictsubnets) - subnet_del(n, s); - } - for splay_each(edge_t, e, n->edge_tree) { if(!tunnelserver) send_del_edge(everyone, e); @@ -75,10 +70,6 @@ void purge(void) { for splay_each(edge_t, e, edge_weight_tree) if(e->to == n) return; - - if(!autoconnect && (!strictsubnets || !n->subnet_tree->head)) - /* in strictsubnets mode do not delete nodes with subnets */ - node_del(n); } } } @@ -147,9 +138,6 @@ void terminate_connection(connection_t *c, bool report) { */ static void timeout_handler(void *data) { for list_each(connection_t, c, connection_list) { - if(c->status.control) - continue; - if(c->last_ping_time + pingtimeout <= now.tv_sec) { if(c->status.active) { if(c->status.pinged) { @@ -200,7 +188,7 @@ static void periodic_handler(void *data) { /* Count number of active connections */ int nc = 0; for list_each(connection_t, c, connection_list) { - if(c->status.active && !c->status.control) + if(c->status.active) nc++; } @@ -247,7 +235,7 @@ static void periodic_handler(void *data) { int i = 0; for list_each(connection_t, c, connection_list) { - if(!c->status.active || c->status.control) + if(!c->status.active) continue; if(i++ != r) @@ -294,25 +282,6 @@ void handle_meta_connection_data(connection_t *c) { } } -#ifndef HAVE_MINGW -static void sigterm_handler(void *data) { - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); - event_exit(); -} - -static void sighup_handler(void *data) { - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); - reopenlogger(); - if(reload_configuration()) - exit(1); -} - -static void sigalrm_handler(void *data) { - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); - retry(); -} -#endif - int reload_configuration(void) { char *fname = NULL; @@ -336,64 +305,6 @@ int reload_configuration(void) { setup_myself_reloadable(); - /* If StrictSubnet is set, expire deleted Subnets and read new ones in */ - - if(strictsubnets) { - for splay_each(subnet_t, subnet, subnet_tree) - subnet->expires = 1; - - load_all_subnets(); - - for splay_each(subnet_t, subnet, subnet_tree) { - if(subnet->expires == 1) { - send_del_subnet(everyone, subnet); - if(subnet->owner->status.reachable) - subnet_update(subnet->owner, subnet, false); - subnet_del(subnet->owner, subnet); - } else if(subnet->expires == -1) { - subnet->expires = 0; - } else { - send_add_subnet(everyone, subnet); - if(subnet->owner->status.reachable) - subnet_update(subnet->owner, subnet, true); - } - } - } else { /* Only read our own subnets back in */ - for splay_each(subnet_t, subnet, myself->subnet_tree) - if(!subnet->expires) - subnet->expires = 1; - - config_t *cfg = lookup_config(config_tree, "Subnet"); - - while(cfg) { - subnet_t *subnet, *s2; - - if(!get_config_subnet(cfg, &subnet)) - continue; - - if((s2 = lookup_subnet(myself, subnet))) { - if(s2->expires == 1) - s2->expires = 0; - - free_subnet(subnet); - } else { - subnet_add(myself, subnet); - send_add_subnet(everyone, subnet); - subnet_update(myself, subnet, true); - } - - cfg = lookup_config_next(config_tree, cfg); - } - - for splay_each(subnet_t, subnet, myself->subnet_tree) { - if(subnet->expires == 1) { - send_del_subnet(everyone, subnet); - subnet_update(myself, subnet, false); - subnet_del(myself, subnet); - } - } - } - /* Try to make outgoing connections */ try_outgoing_connections(); @@ -401,9 +312,6 @@ int reload_configuration(void) { /* Close connections to hosts that have a changed or deleted host config file */ for list_each(connection_t, c, connection_list) { - if(c->status.control) - continue; - xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); struct stat s; if(stat(fname, &s) || s.st_mtime > last_config_check) { @@ -443,33 +351,11 @@ int main_loop(void) { timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval){pingtimeout, rand() % 100000}); timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval){pingtimeout, rand() % 100000}); -#ifndef HAVE_MINGW - signal_t sighup = {0}; - signal_t sigterm = {0}; - signal_t sigquit = {0}; - signal_t sigint = {0}; - signal_t sigalrm = {0}; - - signal_add(&sighup, sighup_handler, &sighup, SIGHUP); - signal_add(&sigterm, sigterm_handler, &sigterm, SIGTERM); - signal_add(&sigquit, sigterm_handler, &sigquit, SIGQUIT); - signal_add(&sigint, sigterm_handler, &sigint, SIGINT); - signal_add(&sigalrm, sigalrm_handler, &sigalrm, SIGALRM); -#endif - if(!event_loop()) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", strerror(errno)); return 1; } -#ifndef HAVE_MINGW - signal_del(&sighup); - signal_del(&sigterm); - signal_del(&sigquit); - signal_del(&sigint); - signal_del(&sigalrm); -#endif - timeout_del(&periodictimer); timeout_del(&pingtimer); diff --git a/src/net.h b/src/net.h index 845fd758..f534efdd 100644 --- a/src/net.h +++ b/src/net.h @@ -130,7 +130,6 @@ extern sockaddr_t localdiscovery_address; extern listen_socket_t listen_socket[MAXSOCKETS]; extern int listen_sockets; -extern io_t unix_socket; extern int keylifetime; extern int udp_rcvbuf; extern int udp_sndbuf; @@ -169,7 +168,6 @@ extern void handle_incoming_vpn_data(void *, int); extern void finish_connecting(struct connection_t *); extern bool do_outgoing_connection(struct outgoing_t *); extern void handle_new_meta_connection(void *, int); -extern void handle_new_unix_connection(void *, int); extern int setup_listen_socket(const sockaddr_t *); extern int setup_vpn_in_socket(const sockaddr_t *); extern bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len); @@ -204,4 +202,7 @@ extern void load_all_nodes(void); extern CRITICAL_SECTION mutex; #endif +//TODO: move this to a better place +extern char *confbase; + #endif /* __TINC_NET_H__ */ diff --git a/src/net_packet.c b/src/net_packet.c index 41e303e2..30ad3e50 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -35,7 +35,6 @@ #include "connection.h" #include "crypto.h" #include "digest.h" -#include "device.h" #include "ethernet.h" #include "graph.h" #include "logger.h" @@ -893,7 +892,7 @@ void send_packet(node_t *n, vpn_packet_t *packet) { memcpy(packet->data, mymac.x, ETH_ALEN); n->out_packets++; n->out_bytes += packet->len; - devops.write(packet); + // TODO: send to application return; } @@ -1039,15 +1038,3 @@ void handle_incoming_vpn_data(void *data, int flags) { receive_udppacket(n, &pkt); } - -//void handle_device_data(void *data, int flags) { -// vpn_packet_t packet; -// -// packet.priority = 0; -// -// if(devops.read(&packet)) { -// myself->in_packets++; -// myself->in_bytes += packet.len; -// route(myself, &packet); -// } -//} diff --git a/src/net_setup.c b/src/net_setup.c index 67bcc8ac..35b301d8 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -25,27 +25,19 @@ #include "cipher.h" #include "conf.h" #include "connection.h" -#include "control.h" -#include "device.h" #include "digest.h" #include "ecdsa.h" #include "graph.h" #include "logger.h" -#include "names.h" #include "net.h" #include "netutl.h" -#include "process.h" #include "protocol.h" #include "route.h" #include "rsa.h" -#include "script.h" -#include "subnet.h" #include "utils.h" #include "xalloc.h" char *myport; -static io_t device_io; -devops_t devops; char *proxyhost; char *proxyport; @@ -55,9 +47,6 @@ proxytype_t proxytype; int autoconnect; bool disablebuggypeers; -char *scriptinterpreter; -char *scriptextension; - bool node_read_ecdsa_public_key(node_t *n) { if(ecdsa_active(n->ecdsa)) return true; @@ -195,7 +184,7 @@ static bool read_ecdsa_private_key(void) { if(!fp) { logger(DEBUG_ALWAYS, LOG_ERR, "Error reading ECDSA private key file `%s': %s", fname, strerror(errno)); if(errno == ENOENT) - logger(DEBUG_ALWAYS, LOG_INFO, "Create an ECDSA keypair with `tinc -n %s generate-ecdsa-keys'.", netname ?: "."); + logger(DEBUG_ALWAYS, LOG_INFO, "Create an ECDSA keypair with `tinc generate-ecdsa-keys'."); free(fname); return false; } @@ -313,62 +302,6 @@ void regenerate_key(void) { send_key_changed(); } -/* - Read Subnets from all host config files -*/ -void load_all_subnets(void) { - DIR *dir; - struct dirent *ent; - char *dname; - - xasprintf(&dname, "%s" SLASH "hosts", confbase); - dir = opendir(dname); - if(!dir) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno)); - free(dname); - return; - } - - while((ent = readdir(dir))) { - if(!check_id(ent->d_name)) - continue; - - node_t *n = lookup_node(ent->d_name); - #ifdef _DIRENT_HAVE_D_TYPE - //if(ent->d_type != DT_REG) - // continue; - #endif - - splay_tree_t *config_tree; - init_configuration(&config_tree); - read_config_options(config_tree, ent->d_name); - read_host_config(config_tree, ent->d_name); - - if(!n) { - n = new_node(); - n->name = xstrdup(ent->d_name); - node_add(n); - } - - for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { - subnet_t *s, *s2; - - if(!get_config_subnet(cfg, &s)) - continue; - - if((s2 = lookup_subnet(n, s))) { - s2->expires = -1; - } else { - subnet_add(n, s); - } - } - - exit_configuration(&config_tree); - } - - closedir(dir); -} - void load_all_nodes(void) { DIR *dir; struct dirent *ent; @@ -448,15 +381,6 @@ bool setup_myself_reloadable(void) { char *space; bool choice; - free(scriptinterpreter); - scriptinterpreter = NULL; - get_config_string(lookup_config(config_tree, "ScriptsInterpreter"), &scriptinterpreter); - - - free(scriptextension); - if(!get_config_string(lookup_config(config_tree, "ScriptsExtension"), &scriptextension)) - scriptextension = xstrdup(""); - get_config_string(lookup_config(config_tree, "Proxy"), &proxy); if(proxy) { if((space = strchr(proxy, ' '))) @@ -774,25 +698,12 @@ bool setup_myself(void) { sockaddr2str(&sa, NULL, &myport); } - /* Read in all the subnets specified in the host configuration file */ - - for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { - subnet_t *subnet; - - if(!get_config_subnet(cfg, &subnet)) - return false; - - subnet_add(myself, subnet); - } - /* Check some options */ if(!setup_myself_reloadable()) return false; - get_config_bool(lookup_config(config_tree, "StrictSubnets"), &strictsubnets); get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver); - strictsubnets |= tunnelserver; if(get_config_int(lookup_config(config_tree, "MaxConnectionBurst"), &max_connection_burst)) { if(max_connection_burst <= 0) { @@ -886,76 +797,32 @@ bool setup_myself(void) { graph(); - if(strictsubnets) - load_all_subnets(); - else if(autoconnect) + if(autoconnect) load_all_nodes(); /* Open sockets */ - if(!do_detach && getenv("LISTEN_FDS")) { - sockaddr_t sa; - socklen_t salen; + listen_sockets = 0; + int cfgs = 0; - listen_sockets = atoi(getenv("LISTEN_FDS")); -#ifdef HAVE_UNSETENV - unsetenv("LISTEN_FDS"); -#endif - - if(listen_sockets > MAXSOCKETS) { - logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets"); + for(config_t *cfg = lookup_config(config_tree, "BindToAddress"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + cfgs++; + get_config_string(cfg, &address); + if(!add_listen_address(address, true)) return false; - } - - for(int i = 0; i < listen_sockets; i++) { - salen = sizeof sa; - if(getsockname(i + 3, &sa.sa, &salen) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not get address of listen fd %d: %s", i + 3, sockstrerror(errno)); - return false; - } - -#ifdef FD_CLOEXEC - fcntl(i + 3, F_SETFD, FD_CLOEXEC); -#endif - - int udp_fd = setup_vpn_in_socket(&sa); - if(udp_fd < 0) - return false; - - io_add(&listen_socket[i].tcp, (io_cb_t)handle_new_meta_connection, &listen_socket[i], i + 3, IO_READ); - io_add(&listen_socket[i].udp, (io_cb_t)handle_incoming_vpn_data, &listen_socket[i], udp_fd, IO_READ); - - if(debug_level >= DEBUG_CONNECTIONS) { - hostname = sockaddr2hostname(&sa); - logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Listening on %s", hostname); - free(hostname); - } - - memcpy(&listen_socket[i].sa, &sa, salen); - } - } else { - listen_sockets = 0; - int cfgs = 0; - - for(config_t *cfg = lookup_config(config_tree, "BindToAddress"); cfg; cfg = lookup_config_next(config_tree, cfg)) { - cfgs++; - get_config_string(cfg, &address); - if(!add_listen_address(address, true)) - return false; - } - - for(config_t *cfg = lookup_config(config_tree, "ListenAddress"); cfg; cfg = lookup_config_next(config_tree, cfg)) { - cfgs++; - get_config_string(cfg, &address); - if(!add_listen_address(address, false)) - return false; - } + } - if(!cfgs) - if(!add_listen_address(address, NULL)) - return false; + for(config_t *cfg = lookup_config(config_tree, "ListenAddress"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + cfgs++; + get_config_string(cfg, &address); + if(!add_listen_address(address, false)) + return false; } + if(!cfgs) + if(!add_listen_address(address, NULL)) + return false; + if(!listen_sockets) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to create any listening socket!"); return false; @@ -989,7 +856,6 @@ bool setup_myself(void) { */ bool setup_network(void) { init_connections(); - init_subnets(); init_nodes(); init_edges(); init_requests(); @@ -1012,26 +878,6 @@ bool setup_network(void) { if(!setup_myself()) return false; - if(!init_control()) - return false; - - /* Run tinc-up script to further initialize the tap interface */ - - char *envp[5] = {NULL}; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NAME=%s", myself->name); - - execute_script("tinc-up", envp); - - for(int i = 0; i < 4; i++) - free(envp[i]); - - /* Run subnet-up scripts for our own subnets */ - - subnet_update(myself, NULL, true); - return true; } @@ -1042,9 +888,6 @@ void close_network_connections(void) { for(list_node_t *node = connection_list->head, *next; node; node = next) { next = node->next; connection_t *c = node->data; - /* Keep control connections open until the end, so they know when we really terminated */ - if(c->status.control) - c->socket = -1; c->outgoing = NULL; terminate_connection(c, false); } @@ -1053,7 +896,6 @@ void close_network_connections(void) { list_delete_list(outgoing_list); if(myself && myself->connection) { - subnet_update(myself, NULL, false); terminate_connection(myself->connection, false); free_connection(myself->connection); } @@ -1065,28 +907,12 @@ void close_network_connections(void) { close(listen_socket[i].udp.fd); } - char *envp[5] = {NULL}; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NAME=%s", myself->name); - exit_requests(); exit_edges(); - exit_subnets(); exit_nodes(); exit_connections(); - execute_script("tinc-down", envp); - if(myport) free(myport); - for(int i = 0; i < 4; i++) - free(envp[i]); - - devops.close(); - - exit_control(); - return; } diff --git a/src/net_socket.c b/src/net_socket.c index 072984bf..b8ed76d8 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -24,11 +24,9 @@ #include "conf.h" #include "connection.h" -#include "control_common.h" #include "list.h" #include "logger.h" #include "meta.h" -#include "names.h" #include "net.h" #include "netutl.h" #include "protocol.h" @@ -49,9 +47,6 @@ int max_connection_burst = 100; listen_socket_t listen_socket[MAXSOCKETS]; int listen_sockets; -#ifndef HAVE_MINGW -io_t unix_socket; -#endif list_t *outgoing_list = NULL; /* Setup sockets */ @@ -362,8 +357,6 @@ static void do_outgoing_pipe(connection_t *c, char *command) { setenv("REMOTEPORT", port, true); setenv("NODE", c->name, true); setenv("NAME", myself->name, true); - if(netname) - setenv("NETNAME", netname, true); int result = system(command); if(result < 0) @@ -703,45 +696,6 @@ void handle_new_meta_connection(void *data, int flags) { send_id(c); } -#ifndef HAVE_MINGW -/* - accept a new UNIX socket connection -*/ -void handle_new_unix_connection(void *data, int flags) { - io_t *io = data; - connection_t *c; - sockaddr_t sa; - int fd; - socklen_t len = sizeof sa; - - fd = accept(io->fd, &sa.sa, &len); - - if(fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); - return; - } - - sockaddrunmap(&sa); - - c = new_connection(); - c->name = xstrdup(""); - c->address = sa; - c->hostname = xstrdup("localhost port unix"); - c->socket = fd; - c->last_ping_time = now.tv_sec; - - logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); - - io_add(&c->io, handle_meta_io, c, c->socket, IO_READ); - - connection_add(c); - - c->allow_request = ID; - - send_id(c); -} -#endif - static void free_outgoing(outgoing_t *outgoing) { timeout_del(&outgoing->ev); diff --git a/src/node.c b/src/node.c index aab83ca7..28b77a41 100644 --- a/src/node.c +++ b/src/node.c @@ -20,7 +20,6 @@ #include "system.h" -#include "control_common.h" #include "hash.h" #include "logger.h" #include "net.h" @@ -53,7 +52,6 @@ node_t *new_node(void) { node_t *n = xzalloc(sizeof *n); if(replaywin) n->late = xzalloc(replaywin); - n->subnet_tree = new_subnet_tree(); n->edge_tree = new_edge_tree(); n->mtu = MTU; n->maxmtu = MTU; @@ -62,9 +60,6 @@ node_t *new_node(void) { } void free_node(node_t *n) { - if(n->subnet_tree) - free_subnet_tree(n->subnet_tree); - if(n->edge_tree) free_edge_tree(n->edge_tree); @@ -97,9 +92,6 @@ void node_add(node_t *n) { } void node_del(node_t *n) { - for splay_each(subnet_t, s, n->subnet_tree) - subnet_del(n, s); - for splay_each(edge_t, e, n->edge_tree) edge_del(e); @@ -141,22 +133,3 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { logger(DEBUG_PROTOCOL, LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname); } } - -bool dump_nodes(connection_t *c) { - for splay_each(node_t, n, node_tree) - send_request(c, "%d %d %s %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", CONTROL, REQ_DUMP_NODES, - n->name, n->hostname ?: "unknown port unknown", cipher_get_nid(n->outcipher), - digest_get_nid(n->outdigest), (int)digest_length(n->outdigest), n->outcompression, - n->options, bitfield_to_int(&n->status, sizeof n->status), n->nexthop ? n->nexthop->name : "-", - n->via ? n->via->name ?: "-" : "-", n->distance, n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change); - - return send_request(c, "%d %d", CONTROL, REQ_DUMP_NODES); -} - -bool dump_traffic(connection_t *c) { - for splay_each(node_t, n, node_tree) - send_request(c, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, CONTROL, REQ_DUMP_TRAFFIC, - n->name, n->in_packets, n->in_bytes, n->out_packets, n->out_bytes); - - return send_request(c, "%d %d", CONTROL, REQ_DUMP_TRAFFIC); -} diff --git a/src/node.h b/src/node.h index 1c9f230a..fa27bfd2 100644 --- a/src/node.h +++ b/src/node.h @@ -26,7 +26,6 @@ #include "connection.h" #include "digest.h" #include "event.h" -#include "subnet.h" typedef struct node_status_t { unsigned int unused_active:1; /* 1 if active (not used for nodes) */ @@ -70,8 +69,6 @@ typedef struct node_t { struct edge_t *prevedge; /* nearest node from him to us */ struct node_t *via; /* next hop for UDP packets */ - splay_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */ - splay_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) */ @@ -112,8 +109,6 @@ extern void node_add(node_t *); extern void node_del(node_t *); extern node_t *lookup_node(char *); extern node_t *lookup_node_udp(const sockaddr_t *); -extern bool dump_nodes(struct connection_t *); -extern bool dump_traffic(struct connection_t *); extern void update_node_udp(node_t *, const sockaddr_t *); #endif /* __TINC_NODE_H__ */ diff --git a/src/process.c b/src/process.c deleted file mode 100644 index c1038bcd..00000000 --- a/src/process.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - process.c -- process management functions - Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "conf.h" -#include "connection.h" -#include "control.h" -#include "device.h" -#include "edge.h" -#include "event.h" -#include "logger.h" -#include "names.h" -#include "net.h" -#include "node.h" -#include "process.h" -#include "subnet.h" -#include "utils.h" -#include "xalloc.h" - -/* If zero, don't detach from the terminal. */ -bool do_detach = true; -bool sigalrm = false; - -extern char **g_argv; -extern bool use_logfile; - -/* Some functions the less gifted operating systems might lack... */ - -#ifdef HAVE_MINGW -static SC_HANDLE manager = NULL; -static SC_HANDLE service = NULL; -static SERVICE_STATUS status = {0}; -static SERVICE_STATUS_HANDLE statushandle = 0; - -static bool install_service(void) { - char command[4096] = "\""; - SERVICE_DESCRIPTION description = {"Virtual Private Network daemon"}; - - manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); - if(!manager) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open service manager: %s", winerror(GetLastError())); - return false; - } - - if(!strchr(program_name, '\\')) { - GetCurrentDirectory(sizeof command - 1, command + 1); - strncat(command, "\\", sizeof command - strlen(command)); - } - - strncat(command, program_name, sizeof command - strlen(command)); - - strncat(command, "\"", sizeof command - strlen(command)); - - for(char **argp = g_argv + 1; *argp; argp++) { - char *space = strchr(*argp, ' '); - strncat(command, " ", sizeof command - strlen(command)); - - if(space) - strncat(command, "\"", sizeof command - strlen(command)); - - strncat(command, *argp, sizeof command - strlen(command)); - - if(space) - strncat(command, "\"", sizeof command - strlen(command)); - } - - service = CreateService(manager, identname, identname, - SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, - command, NULL, NULL, NULL, NULL, NULL); - - if(!service) { - DWORD lasterror = GetLastError(); - logger(DEBUG_ALWAYS, LOG_ERR, "Could not create %s service: %s", identname, winerror(lasterror)); - if(lasterror != ERROR_SERVICE_EXISTS) - return false; - } - - if(service) { - ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &description); - logger(DEBUG_ALWAYS, LOG_INFO, "%s service installed", identname); - } else { - service = OpenService(manager, identname, SERVICE_ALL_ACCESS); - } - - if(!StartService(service, 0, NULL)) - logger(DEBUG_ALWAYS, LOG_WARNING, "Could not start %s service: %s", identname, winerror(GetLastError())); - else - logger(DEBUG_ALWAYS, LOG_INFO, "%s service started", identname); - - return true; -} - -DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) { - switch(request) { - case SERVICE_CONTROL_INTERROGATE: - SetServiceStatus(statushandle, &status); - return NO_ERROR; - case SERVICE_CONTROL_STOP: - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_STOP"); - break; - case SERVICE_CONTROL_SHUTDOWN: - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_SHUTDOWN"); - break; - default: - logger(DEBUG_ALWAYS, LOG_WARNING, "Got unexpected request %d", (int)request); - return ERROR_CALL_NOT_IMPLEMENTED; - } - - event_exit(); - status.dwWaitHint = 30000; - status.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus(statushandle, &status); - return NO_ERROR; -} - -VOID WINAPI run_service(DWORD argc, LPTSTR* argv) { - extern int main2(int argc, char **argv); - - status.dwServiceType = SERVICE_WIN32; - status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; - status.dwWin32ExitCode = 0; - status.dwServiceSpecificExitCode = 0; - status.dwCheckPoint = 0; - - statushandle = RegisterServiceCtrlHandlerEx(identname, controlhandler, NULL); - - if (!statushandle) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "RegisterServiceCtrlHandlerEx", winerror(GetLastError())); - } else { - status.dwWaitHint = 30000; - status.dwCurrentState = SERVICE_START_PENDING; - SetServiceStatus(statushandle, &status); - - status.dwWaitHint = 0; - status.dwCurrentState = SERVICE_RUNNING; - SetServiceStatus(statushandle, &status); - - main2(argc, argv); - - status.dwWaitHint = 0; - status.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus(statushandle, &status); - } - - return; -} - -bool init_service(void) { - SERVICE_TABLE_ENTRY services[] = { - {identname, run_service}, - {NULL, NULL} - }; - - if(!StartServiceCtrlDispatcher(services)) { - if(GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { - return false; - } - else - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "StartServiceCtrlDispatcher", winerror(GetLastError())); - } - - return true; -} -#endif - -/* - Detach from current terminal -*/ -bool detach(void) { -#ifndef HAVE_MINGW - signal(SIGPIPE, SIG_IGN); - signal(SIGUSR1, SIG_IGN); - signal(SIGUSR2, SIG_IGN); - signal(SIGWINCH, SIG_IGN); - - closelogger(); -#endif - - if(do_detach) { -#ifndef HAVE_MINGW - if(daemon(0, 0)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Couldn't detach from terminal: %s", strerror(errno)); - return false; - } -#else - if(!statushandle) - exit(!install_service()); -#endif - } - - openlogger(identname, use_logfile?LOGMODE_FILE:(do_detach?LOGMODE_SYSLOG:LOGMODE_STDERR)); - - logger(DEBUG_ALWAYS, LOG_NOTICE, "tincd %s (%s %s) starting, debug level %d", - VERSION, __DATE__, __TIME__, debug_level); - - return true; -} - - diff --git a/src/process.h b/src/process.h deleted file mode 100644 index 4cdf711b..00000000 --- a/src/process.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - process.h -- header file for process.c - Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_PROCESS_H__ -#define __TINC_PROCESS_H__ - -extern bool do_detach; -extern bool sigalrm; - -extern void setup_signals(void); -extern bool detach(void); -extern bool kill_other(int); - -#ifdef HAVE_MINGW -extern bool init_service(void); -#endif - -#endif /* __TINC_PROCESS_H__ */ diff --git a/src/protocol.c b/src/protocol.c index 374c5229..65aabd81 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -29,7 +29,6 @@ #include "xalloc.h" bool tunnelserver = false; -bool strictsubnets = false; bool experimental = true; /* Jumptable for the request handlers */ @@ -38,9 +37,9 @@ static bool (*request_handlers[])(connection_t *, const char *) = { id_h, metakey_h, challenge_h, chal_reply_h, ack_h, status_h, error_h, termreq_h, ping_h, pong_h, - add_subnet_h, del_subnet_h, + NULL, NULL, //add_subnet_h, del_subnet_h, add_edge_h, del_edge_h, - key_changed_h, req_key_h, ans_key_h, tcppacket_h, control_h, + key_changed_h, req_key_h, ans_key_h, tcppacket_h, NULL, //control_h, }; /* Request names */ diff --git a/src/protocol.h b/src/protocol.h index e771c545..d6060650 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -58,7 +58,6 @@ typedef struct past_request_t { } past_request_t; extern bool tunnelserver; -extern bool strictsubnets; extern bool experimental; extern ecdsa_t *invitation_key; @@ -74,7 +73,6 @@ extern ecdsa_t *invitation_key; #include "edge.h" #include "net.h" #include "node.h" -#include "subnet.h" /* Basic functions */ @@ -100,8 +98,6 @@ extern bool send_error(struct connection_t *, int, const char *); extern bool send_termreq(struct connection_t *); extern bool send_ping(struct connection_t *); extern bool send_pong(struct connection_t *); -extern bool send_add_subnet(struct connection_t *, const struct subnet_t *); -extern bool send_del_subnet(struct connection_t *, const struct subnet_t *); extern bool send_add_edge(struct connection_t *, const struct edge_t *); extern bool send_del_edge(struct connection_t *, const struct edge_t *); extern void send_key_changed(void); @@ -121,14 +117,11 @@ extern bool error_h(struct connection_t *, const char *); extern bool termreq_h(struct connection_t *, const char *); extern bool ping_h(struct connection_t *, const char *); extern bool pong_h(struct connection_t *, const char *); -extern bool add_subnet_h(struct connection_t *, const char *); -extern bool del_subnet_h(struct connection_t *, const char *); extern bool add_edge_h(struct connection_t *, const char *); extern bool del_edge_h(struct connection_t *, const char *); extern bool key_changed_h(struct connection_t *, const char *); extern bool req_key_h(struct connection_t *, const char *); extern bool ans_key_h(struct connection_t *, const char *); extern bool tcppacket_h(struct connection_t *, const char *); -extern bool control_h(struct connection_t *, const char *); #endif /* __TINC_PROTOCOL_H__ */ diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 52afa096..4caaf203 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -22,25 +22,20 @@ #include "conf.h" #include "connection.h" -#include "control.h" -#include "control_common.h" #include "cipher.h" #include "crypto.h" -#include "device.h" #include "digest.h" #include "ecdsa.h" #include "edge.h" #include "graph.h" #include "logger.h" #include "meta.h" -#include "names.h" #include "net.h" #include "netutl.h" #include "node.h" #include "prf.h" #include "protocol.h" #include "rsa.h" -#include "script.h" #include "sptps.h" #include "utils.h" #include "xalloc.h" @@ -177,22 +172,7 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) logger(DEBUG_CONNECTIONS, LOG_INFO, "Key succesfully received from %s (%s)", c->name, c->hostname); - // Call invitation-accepted script - char *envp[7] = {NULL}; - char *address, *port; - - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NODE=%s", c->name); - sockaddr2str(&c->address, &address, &port); - xasprintf(&envp[4], "REMOTEADDRESS=%s", address); - xasprintf(&envp[5], "NAME=%s", myself->name); - - execute_script("invitation-accepted", envp); - - for(int i = 0; envp[i] && i < 7; i++) - free(envp[i]); + //TODO: callback to application to inform of an accepted invitation sptps_send_record(&c->sptps, 2, data, 0); return true; @@ -292,18 +272,7 @@ bool id_h(connection_t *c, const char *request) { return false; } - /* Check if this is a control connection */ - - if(name[0] == '^' && !strcmp(name + 1, controlcookie)) { - c->status.control = true; - c->allow_request = CONTROL; - c->last_ping_time = now.tv_sec + 3600; - - free(c->name); - c->name = xstrdup(""); - - return send_request(c, "%d %d %d", ACK, TINC_CTL_VERSION_CURRENT, getpid()); - } + /* Check if this is an invitation */ if(name[0] == '?') { if(!invitation_key) { @@ -681,6 +650,7 @@ bool send_ack(connection_t *c) { static void send_everything(connection_t *c) { /* Send all known subnets and edges */ + // TODO: remove this if(disablebuggypeers) { static struct { vpn_packet_t pkt; @@ -692,17 +662,7 @@ static void send_everything(connection_t *c) { send_tcppacket(c, &zeropkt.pkt); } - if(tunnelserver) { - for splay_each(subnet_t, s, myself->subnet_tree) - send_add_subnet(c, s); - - return; - } - for splay_each(node_t, n, node_tree) { - for splay_each(subnet_t, s, n->subnet_tree) - send_add_subnet(c, s); - for splay_each(edge_t, e, n->edge_tree) send_add_edge(c, e); } @@ -767,7 +727,7 @@ bool ack_h(connection_t *c, const char *request) { } terminate_connection(n->connection, false); - /* Run graph algorithm to purge key and make sure up/down scripts are rerun with new IP addresses and stuff */ + /* Run graph algorithm to keep things in sync */ graph(); } } diff --git a/src/protocol_subnet.c b/src/protocol_subnet.c deleted file mode 100644 index 06dafbc7..00000000 --- a/src/protocol_subnet.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - protocol_subnet.c -- handle the meta-protocol, subnets - Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2012 Guus Sliepen - 2009 Michael Tokarev - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "conf.h" -#include "connection.h" -#include "logger.h" -#include "net.h" -#include "netutl.h" -#include "node.h" -#include "protocol.h" -#include "subnet.h" -#include "utils.h" -#include "xalloc.h" - -bool send_add_subnet(connection_t *c, const subnet_t *subnet) { - char netstr[MAXNETSTR]; - - if(!net2str(netstr, sizeof netstr, subnet)) - return false; - - return send_request(c, "%d %x %s %s", ADD_SUBNET, rand(), subnet->owner->name, netstr); -} - -bool add_subnet_h(connection_t *c, const char *request) { - char subnetstr[MAX_STRING_SIZE]; - char name[MAX_STRING_SIZE]; - node_t *owner; - subnet_t s = {NULL}, *new, *old; - - if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_SUBNET", c->name, - c->hostname); - return false; - } - - /* Check if owner name is valid */ - - if(!check_id(name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, - c->hostname, "invalid name"); - return false; - } - - /* Check if subnet string is valid */ - - if(!str2net(&s, subnetstr)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, - c->hostname, "invalid subnet string"); - return false; - } - - if(seen_request(request)) - return true; - - /* Check if the owner of the new subnet is in the connection list */ - - owner = lookup_node(name); - - if(tunnelserver && owner != myself && owner != c->node) { - /* in case of tunnelserver, ignore indirect subnet registrations */ - logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); - return true; - } - - if(!owner) { - owner = new_node(); - owner->name = xstrdup(name); - node_add(owner); - } - - /* Check if we already know this subnet */ - - if(lookup_subnet(owner, &s)) - return true; - - /* If we don't know this subnet, but we are the owner, retaliate with a DEL_SUBNET */ - - if(owner == myself) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", - "ADD_SUBNET", c->name, c->hostname); - s.owner = myself; - send_del_subnet(c, &s); - return true; - } - - /* In tunnel server mode, we should already know all allowed subnets */ - - if(tunnelserver) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); - return true; - } - - /* Ignore if strictsubnets is true, but forward it to others */ - - if(strictsubnets) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); - forward_request(c, request); - return true; - } - - /* If everything is correct, add the subnet to the list of the owner */ - - *(new = new_subnet()) = s; - subnet_add(owner, new); - - if(owner->status.reachable) - subnet_update(owner, new, true); - - /* Tell the rest */ - - if(!tunnelserver) - forward_request(c, request); - - /* Fast handoff of roaming MAC addresses */ - - if(s.type == SUBNET_MAC && owner != myself && (old = lookup_subnet(myself, &s)) && old->expires) - old->expires = 1; - - return true; -} - -bool send_del_subnet(connection_t *c, const subnet_t *s) { - char netstr[MAXNETSTR]; - - if(!net2str(netstr, sizeof netstr, s)) - return false; - - return send_request(c, "%d %x %s %s", DEL_SUBNET, rand(), s->owner->name, netstr); -} - -bool del_subnet_h(connection_t *c, const char *request) { - char subnetstr[MAX_STRING_SIZE]; - char name[MAX_STRING_SIZE]; - node_t *owner; - subnet_t s = {NULL}, *find; - - if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "DEL_SUBNET", c->name, - c->hostname); - return false; - } - - /* Check if owner name is valid */ - - if(!check_id(name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, - c->hostname, "invalid name"); - return false; - } - - /* Check if subnet string is valid */ - - if(!str2net(&s, subnetstr)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, - c->hostname, "invalid subnet string"); - return false; - } - - if(seen_request(request)) - return true; - - /* Check if the owner of the subnet being deleted is in the connection list */ - - owner = lookup_node(name); - - if(tunnelserver && owner != myself && owner != c->node) { - /* in case of tunnelserver, ignore indirect subnet deletion */ - logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", - "DEL_SUBNET", c->name, c->hostname, subnetstr); - return true; - } - - if(!owner) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for %s which is not in our node tree", - "DEL_SUBNET", c->name, c->hostname, name); - return true; - } - - /* If everything is correct, delete the subnet from the list of the owner */ - - s.owner = owner; - - find = lookup_subnet(owner, &s); - - if(!find) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for %s which does not appear in his subnet tree", - "DEL_SUBNET", c->name, c->hostname, name); - if(strictsubnets) - forward_request(c, request); - return true; - } - - /* If we are the owner of this subnet, retaliate with an ADD_SUBNET */ - - if(owner == myself) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", - "DEL_SUBNET", c->name, c->hostname); - send_add_subnet(c, find); - return true; - } - - if(tunnelserver) - return true; - - /* Tell the rest */ - - if(!tunnelserver) - forward_request(c, request); - if(strictsubnets) - return true; - - /* Finally, delete it. */ - - if(owner->status.reachable) - subnet_update(owner, find, false); - - subnet_del(owner, find); - - return true; -} diff --git a/src/raw_socket_device.c b/src/raw_socket_device.c deleted file mode 100644 index 57df5b7a..00000000 --- a/src/raw_socket_device.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - device.c -- raw socket - Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2012 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#ifdef HAVE_NETPACKET_PACKET_H -#include -#endif - -#include "conf.h" -#include "device.h" -#include "net.h" -#include "logger.h" -#include "utils.h" -#include "route.h" -#include "xalloc.h" - -#if defined(PF_PACKET) && defined(ETH_P_ALL) && defined(AF_PACKET) && defined(SIOCGIFINDEX) -static char *device_info; - -static bool setup_device(void) { - struct ifreq ifr; - struct sockaddr_ll sa; - - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) - iface = xstrdup("eth0"); - - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) - device = xstrdup(iface); - - device_info = "raw socket"; - - if((device_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device_info, - strerror(errno)); - return false; - } - - memset(&ifr, 0, sizeof ifr); - -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif - - strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ); - if(ioctl(device_fd, SIOCGIFINDEX, &ifr)) { - close(device_fd); - logger(DEBUG_ALWAYS, LOG_ERR, "Can't find interface %s: %s", iface, - strerror(errno)); - return false; - } - - memset(&sa, '0', sizeof sa); - sa.sll_family = AF_PACKET; - sa.sll_protocol = htons(ETH_P_ALL); - sa.sll_ifindex = ifr.ifr_ifindex; - - if(bind(device_fd, (struct sockaddr *) &sa, (socklen_t) sizeof sa)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind %s to %s: %s", device, iface, strerror(errno)); - return false; - } - - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - - return true; -} - -static void close_device(void) { - close(device_fd); - - free(device); - free(iface); -} - -static bool read_packet(vpn_packet_t *packet) { - int inlen; - - if((inlen = read(device_fd, packet->data, MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - packet->len = inlen; - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); - - return true; -} - -static bool write_packet(vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); - - if(write(device_fd, packet->data, packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - - return true; -} - -const devops_t raw_socket_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, -}; - -#else - -static bool not_supported(void) { - logger(DEBUG_ALWAYS, LOG_ERR, "Raw socket device not supported on this platform"); - return false; -} - -const devops_t raw_socket_devops = { - .setup = not_supported, - .close = NULL, - .read = NULL, - .write = NULL, -}; -#endif diff --git a/src/route.c b/src/route.c index 00ba4c05..5d967dc3 100644 --- a/src/route.c +++ b/src/route.c @@ -20,17 +20,9 @@ #include "system.h" -#include "connection.h" -#include "control_common.h" -#include "ethernet.h" -#include "ipv4.h" -#include "ipv6.h" #include "logger.h" -#include "meta.h" #include "net.h" -#include "protocol.h" #include "route.h" -#include "subnet.h" #include "utils.h" rmode_t routing_mode = RMODE_ROUTER; @@ -44,43 +36,6 @@ bool overwrite_mac = false; mac_t mymac = {{0xFE, 0xFD, 0, 0, 0, 0}}; bool pcap = false; -/* Sizes of various headers */ - -static const size_t ether_size = sizeof(struct ether_header); -static const size_t arp_size = sizeof(struct ether_arp); -static const size_t ip_size = sizeof(struct ip); -static const size_t icmp_size = sizeof(struct icmp) - sizeof(struct ip); -static const size_t ip6_size = sizeof(struct ip6_hdr); -static const size_t icmp6_size = sizeof(struct icmp6_hdr); -static const size_t ns_size = sizeof(struct nd_neighbor_solicit); -static const size_t opt_size = sizeof(struct nd_opt_hdr); - -#ifndef MAX -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif - -static timeout_t age_subnets_timeout; - -/* RFC 1071 */ - -static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) { - uint16_t *p = data; - uint32_t checksum = prevsum ^ 0xFFFF; - - while(len >= 2) { - checksum += *p++; - len -= 2; - } - - if(len) - checksum += *(uint8_t *)p; - - while(checksum >> 16) - checksum = (checksum & 0xFFFF) + (checksum >> 16); - - return ~checksum; -} - static bool ratelimit(int frequency) { static time_t lasttime = 0; static int count = 0; @@ -105,891 +60,6 @@ static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) { return true; } -static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *packet) { - if(!source || !via || !(via->options & OPTION_CLAMP_MSS)) - return; - - uint16_t mtu = source->mtu; - if(via != myself && via->mtu < mtu) - mtu = via->mtu; - - /* Find TCP header */ - int start = ether_size; - uint16_t type = packet->data[12] << 8 | packet->data[13]; - - if(type == ETH_P_8021Q) { - start += 4; - type = packet->data[16] << 8 | packet->data[17]; - } - - if(type == ETH_P_IP && packet->data[start + 9] == 6) - start += (packet->data[start] & 0xf) * 4; - else if(type == ETH_P_IPV6 && packet->data[start + 6] == 6) - start += 40; - else - return; - - if(packet->len <= start + 20) - return; - - /* Use data offset field to calculate length of options field */ - int len = ((packet->data[start + 12] >> 4) - 5) * 4; - - if(packet->len < start + 20 + len) - return; - - /* Search for MSS option header */ - for(int i = 0; i < len;) { - if(packet->data[start + 20 + i] == 0) - break; - - if(packet->data[start + 20 + i] == 1) { - i++; - continue; - } - - if(i > len - 2 || i > len - packet->data[start + 21 + i]) - break; - - if(packet->data[start + 20 + i] != 2) { - if(packet->data[start + 21 + i] < 2) - break; - i += packet->data[start + 21 + i]; - continue; - } - - if(packet->data[start + 21] != 4) - break; - - /* Found it */ - uint16_t oldmss = packet->data[start + 22 + i] << 8 | packet->data[start + 23 + i]; - uint16_t newmss = mtu - start - 20; - uint16_t csum = packet->data[start + 16] << 8 | packet->data[start + 17]; - - if(oldmss <= newmss) - break; - - logger(DEBUG_TRAFFIC, LOG_INFO, "Clamping MSS of packet from %s to %s to %d", source->name, via->name, newmss); - - /* Update the MSS value and the checksum */ - packet->data[start + 22 + i] = newmss >> 8; - packet->data[start + 23 + i] = newmss & 0xff; - csum ^= 0xffff; - csum -= oldmss; - csum += newmss; - csum ^= 0xffff; - packet->data[start + 16] = csum >> 8; - packet->data[start + 17] = csum & 0xff; - break; - } -} - -static void swap_mac_addresses(vpn_packet_t *packet) { - mac_t tmp; - memcpy(&tmp, &packet->data[0], sizeof tmp); - memcpy(&packet->data[0], &packet->data[6], sizeof tmp); - memcpy(&packet->data[6], &tmp, sizeof tmp); -} - -static void age_subnets(void *data) { - bool left = false; - - for splay_each(subnet_t, s, myself->subnet_tree) { - if(s->expires && s->expires < now.tv_sec) { - if(debug_level >= DEBUG_TRAFFIC) { - char netstr[MAXNETSTR]; - if(net2str(netstr, sizeof netstr, s)) - logger(DEBUG_TRAFFIC, LOG_INFO, "Subnet %s expired", netstr); - } - - for list_each(connection_t, c, connection_list) - if(c->status.active) - send_del_subnet(c, s); - - subnet_del(myself, s); - } else { - if(s->expires) - left = true; - } - } - - if(left) - timeout_set(&age_subnets_timeout, &(struct timeval){10, rand() % 100000}); -} - -static void learn_mac(mac_t *address) { - subnet_t *subnet = lookup_subnet_mac(myself, address); - - /* If we don't know this MAC address yet, store it */ - - if(!subnet) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Learned new MAC address %hx:%hx:%hx:%hx:%hx:%hx", - address->x[0], address->x[1], address->x[2], address->x[3], - address->x[4], address->x[5]); - - subnet = new_subnet(); - subnet->type = SUBNET_MAC; - subnet->expires = now.tv_sec + macexpire; - subnet->net.mac.address = *address; - subnet->weight = 10; - subnet_add(myself, subnet); - subnet_update(myself, subnet, true); - - /* And tell all other tinc daemons it's our MAC */ - - for list_each(connection_t, c, connection_list) - if(c->status.active) - send_add_subnet(c, subnet); - - timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval){10, rand() % 100000}); - } else { - if(subnet->expires) - subnet->expires = now.tv_sec + macexpire; - } -} - -/* RFC 792 */ - -static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) { - struct ip ip = {0}; - struct icmp icmp = {0}; - - struct in_addr ip_src; - struct in_addr ip_dst; - uint32_t oldlen; - - if(ratelimit(3)) - return; - - /* Swap Ethernet source and destination addresses */ - - swap_mac_addresses(packet); - - /* Copy headers from packet into properly aligned structs on the stack */ - - memcpy(&ip, packet->data + ether_size, ip_size); - - /* Remember original source and destination */ - - ip_src = ip.ip_src; - ip_dst = ip.ip_dst; - - oldlen = packet->len - ether_size; - - if(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) - icmp.icmp_nextmtu = htons(packet->len - ether_size); - - if(oldlen >= IP_MSS - ip_size - icmp_size) - oldlen = IP_MSS - ip_size - icmp_size; - - /* Copy first part of original contents to ICMP message */ - - memmove(packet->data + ether_size + ip_size + icmp_size, packet->data + ether_size, oldlen); - - /* Fill in IPv4 header */ - - ip.ip_v = 4; - ip.ip_hl = ip_size / 4; - ip.ip_tos = 0; - ip.ip_len = htons(ip_size + icmp_size + oldlen); - ip.ip_id = 0; - ip.ip_off = 0; - ip.ip_ttl = 255; - ip.ip_p = IPPROTO_ICMP; - ip.ip_sum = 0; - ip.ip_src = ip_dst; - ip.ip_dst = ip_src; - - ip.ip_sum = inet_checksum(&ip, ip_size, ~0); - - /* Fill in ICMP header */ - - icmp.icmp_type = type; - icmp.icmp_code = code; - icmp.icmp_cksum = 0; - - icmp.icmp_cksum = inet_checksum(&icmp, icmp_size, ~0); - icmp.icmp_cksum = inet_checksum(packet->data + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum); - - /* Copy structs on stack back to packet */ - - memcpy(packet->data + ether_size, &ip, ip_size); - memcpy(packet->data + ether_size + ip_size, &icmp, icmp_size); - - packet->len = ether_size + ip_size + icmp_size + oldlen; - - send_packet(source, packet); -} - -/* RFC 791 */ - -static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t ether_size) { - struct ip ip; - vpn_packet_t fragment; - int len, maxlen, todo; - uint8_t *offset; - uint16_t ip_off, origf; - - memcpy(&ip, packet->data + ether_size, ip_size); - fragment.priority = packet->priority; - - if(ip.ip_hl != ip_size / 4) - return; - - todo = ntohs(ip.ip_len) - ip_size; - - if(ether_size + ip_size + todo != packet->len) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Length of packet (%d) doesn't match length in IPv4 header (%d)", packet->len, (int)(ether_size + ip_size + todo)); - return; - } - - logger(DEBUG_TRAFFIC, LOG_INFO, "Fragmenting packet of %d bytes to %s (%s)", packet->len, dest->name, dest->hostname); - - offset = packet->data + ether_size + ip_size; - maxlen = (dest->mtu - ether_size - ip_size) & ~0x7; - ip_off = ntohs(ip.ip_off); - origf = ip_off & ~IP_OFFMASK; - ip_off &= IP_OFFMASK; - - while(todo) { - len = todo > maxlen ? maxlen : todo; - memcpy(fragment.data + ether_size + ip_size, offset, len); - todo -= len; - offset += len; - - ip.ip_len = htons(ip_size + len); - ip.ip_off = htons(ip_off | origf | (todo ? IP_MF : 0)); - ip.ip_sum = 0; - ip.ip_sum = inet_checksum(&ip, ip_size, ~0); - memcpy(fragment.data, packet->data, ether_size); - memcpy(fragment.data + ether_size, &ip, ip_size); - fragment.len = ether_size + ip_size + len; - - send_packet(dest, &fragment); - - ip_off += len / 8; - } -} - -static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { - subnet_t *subnet; - node_t *via; - ipv4_t dest; - - memcpy(&dest, &packet->data[30], sizeof dest); - subnet = lookup_subnet_ipv4(&dest); - - if(!subnet) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv4 destination address %d.%d.%d.%d", - source->name, source->hostname, - dest.x[0], - dest.x[1], - dest.x[2], - dest.x[3]); - - route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN); - return; - } - - if(subnet->owner == source) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); - return; - } - - if(!subnet->owner->status.reachable) - return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); - - if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) - return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); - - if(priorityinheritance) - packet->priority = packet->data[15]; - - via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - - if(via == source) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname); - return; - } - - if(directonly && subnet->owner != via) - return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); - - if(via && packet->len > MAX(via->mtu, 590) && via != myself) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); - if(packet->data[20] & 0x40) { - packet->len = MAX(via->mtu, 590); - route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); - } else { - fragment_ipv4_packet(via, packet, ether_size); - } - - return; - } - - clamp_mss(source, via, packet); - - send_packet(subnet->owner, packet); -} - -static void route_ipv4(node_t *source, vpn_packet_t *packet) { - if(!checklength(source, packet, ether_size + ip_size)) - return; - - if(broadcast_mode && (((packet->data[30] & 0xf0) == 0xe0) || ( - packet->data[30] == 255 && - packet->data[31] == 255 && - packet->data[32] == 255 && - packet->data[33] == 255))) - broadcast_packet(source, packet); - else - route_ipv4_unicast(source, packet); -} - -/* RFC 2463 */ - -static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) { - struct ip6_hdr ip6; - struct icmp6_hdr icmp6 = {0}; - uint16_t checksum; - - struct { - struct in6_addr ip6_src; /* source address */ - struct in6_addr ip6_dst; /* destination address */ - uint32_t length; - uint32_t next; - } pseudo; - - if(ratelimit(3)) - return; - - /* Swap Ethernet source and destination addresses */ - - swap_mac_addresses(packet); - - /* Copy headers from packet to structs on the stack */ - - memcpy(&ip6, packet->data + ether_size, ip6_size); - - /* Remember original source and destination */ - - pseudo.ip6_src = ip6.ip6_dst; - pseudo.ip6_dst = ip6.ip6_src; - - pseudo.length = packet->len - ether_size; - - if(type == ICMP6_PACKET_TOO_BIG) - icmp6.icmp6_mtu = htonl(pseudo.length); - - if(pseudo.length >= IP_MSS - ip6_size - icmp6_size) - pseudo.length = IP_MSS - ip6_size - icmp6_size; - - /* Copy first part of original contents to ICMP message */ - - memmove(packet->data + ether_size + ip6_size + icmp6_size, packet->data + ether_size, pseudo.length); - - /* Fill in IPv6 header */ - - ip6.ip6_flow = htonl(0x60000000UL); - ip6.ip6_plen = htons(icmp6_size + pseudo.length); - ip6.ip6_nxt = IPPROTO_ICMPV6; - ip6.ip6_hlim = 255; - ip6.ip6_src = pseudo.ip6_src; - ip6.ip6_dst = pseudo.ip6_dst; - - /* Fill in ICMP header */ - - icmp6.icmp6_type = type; - icmp6.icmp6_code = code; - icmp6.icmp6_cksum = 0; - - /* Create pseudo header */ - - pseudo.length = htonl(icmp6_size + pseudo.length); - pseudo.next = htonl(IPPROTO_ICMPV6); - - /* Generate checksum */ - - checksum = inet_checksum(&pseudo, sizeof pseudo, ~0); - checksum = inet_checksum(&icmp6, icmp6_size, checksum); - checksum = inet_checksum(packet->data + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum); - - icmp6.icmp6_cksum = checksum; - - /* Copy structs on stack back to packet */ - - memcpy(packet->data + ether_size, &ip6, ip6_size); - memcpy(packet->data + ether_size + ip6_size, &icmp6, icmp6_size); - - packet->len = ether_size + ip6_size + ntohl(pseudo.length); - - send_packet(source, packet); -} - -static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { - subnet_t *subnet; - node_t *via; - ipv6_t dest; - - memcpy(&dest, &packet->data[38], sizeof dest); - subnet = lookup_subnet_ipv6(&dest); - - if(!subnet) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", - source->name, source->hostname, - ntohs(dest.x[0]), - ntohs(dest.x[1]), - ntohs(dest.x[2]), - ntohs(dest.x[3]), - ntohs(dest.x[4]), - ntohs(dest.x[5]), - ntohs(dest.x[6]), - ntohs(dest.x[7])); - - route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR); - return; - } - - if(subnet->owner == source) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); - return; - } - - if(!subnet->owner->status.reachable) - return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); - - if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) - return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); - - via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - - if(via == source) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname); - return; - } - - if(directonly && subnet->owner != via) - return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); - - if(via && packet->len > MAX(via->mtu, 1294) && via != myself) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); - packet->len = MAX(via->mtu, 1294); - route_ipv6_unreachable(source, packet, ether_size, ICMP6_PACKET_TOO_BIG, 0); - return; - } - - clamp_mss(source, via, packet); - - send_packet(subnet->owner, packet); -} - -/* RFC 2461 */ - -static void route_neighborsol(node_t *source, vpn_packet_t *packet) { - struct ip6_hdr ip6; - struct nd_neighbor_solicit ns; - struct nd_opt_hdr opt; - subnet_t *subnet; - uint16_t checksum; - bool has_opt; - - struct { - struct in6_addr ip6_src; - struct in6_addr ip6_dst; - uint32_t length; - uint32_t next; - } pseudo; - - if(!checklength(source, packet, ether_size + ip6_size + ns_size)) - return; - - has_opt = packet->len >= ether_size + ip6_size + ns_size + opt_size + ETH_ALEN; - - if(source != myself) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Got neighbor solicitation request from %s (%s) while in router mode!", source->name, source->hostname); - return; - } - - /* Copy headers from packet to structs on the stack */ - - memcpy(&ip6, packet->data + ether_size, ip6_size); - memcpy(&ns, packet->data + ether_size + ip6_size, ns_size); - if(has_opt) - memcpy(&opt, packet->data + ether_size + ip6_size + ns_size, opt_size); - - /* First, snatch the source address from the neighbor solicitation packet */ - - if(overwrite_mac) - memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN); - - /* Check if this is a valid neighbor solicitation request */ - - if(ns.nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT || - (has_opt && opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR)) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: received unknown type neighbor solicitation request"); - return; - } - - /* Create pseudo header */ - - pseudo.ip6_src = ip6.ip6_src; - pseudo.ip6_dst = ip6.ip6_dst; - if(has_opt) - pseudo.length = htonl(ns_size + opt_size + ETH_ALEN); - else - pseudo.length = htonl(ns_size); - pseudo.next = htonl(IPPROTO_ICMPV6); - - /* Generate checksum */ - - checksum = inet_checksum(&pseudo, sizeof pseudo, ~0); - checksum = inet_checksum(&ns, ns_size, checksum); - if(has_opt) { - checksum = inet_checksum(&opt, opt_size, checksum); - checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); - } - - if(checksum) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: checksum error for neighbor solicitation request"); - return; - } - - /* Check if the IPv6 address exists on the VPN */ - - subnet = lookup_subnet_ipv6((ipv6_t *) &ns.nd_ns_target); - - if(!subnet) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: neighbor solicitation request for unknown address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", - ntohs(((uint16_t *) &ns.nd_ns_target)[0]), - ntohs(((uint16_t *) &ns.nd_ns_target)[1]), - ntohs(((uint16_t *) &ns.nd_ns_target)[2]), - ntohs(((uint16_t *) &ns.nd_ns_target)[3]), - ntohs(((uint16_t *) &ns.nd_ns_target)[4]), - ntohs(((uint16_t *) &ns.nd_ns_target)[5]), - ntohs(((uint16_t *) &ns.nd_ns_target)[6]), - ntohs(((uint16_t *) &ns.nd_ns_target)[7])); - - return; - } - - /* Check if it is for our own subnet */ - - if(subnet->owner == myself) - return; /* silently ignore */ - - /* Create neighbor advertation reply */ - - memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ - packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ - - ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocoll address */ - ip6.ip6_src = ns.nd_ns_target; - - if(has_opt) - memcpy(packet->data + ether_size + ip6_size + ns_size + opt_size, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ - - ns.nd_ns_cksum = 0; - ns.nd_ns_type = ND_NEIGHBOR_ADVERT; - ns.nd_ns_reserved = htonl(0x40000000UL); /* Set solicited flag */ - opt.nd_opt_type = ND_OPT_TARGET_LINKADDR; - - /* Create pseudo header */ - - pseudo.ip6_src = ip6.ip6_src; - pseudo.ip6_dst = ip6.ip6_dst; - if(has_opt) - pseudo.length = htonl(ns_size + opt_size + ETH_ALEN); - else - pseudo.length = htonl(ns_size); - pseudo.next = htonl(IPPROTO_ICMPV6); - - /* Generate checksum */ - - checksum = inet_checksum(&pseudo, sizeof pseudo, ~0); - checksum = inet_checksum(&ns, ns_size, checksum); - if(has_opt) { - checksum = inet_checksum(&opt, opt_size, checksum); - checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); - } - - ns.nd_ns_hdr.icmp6_cksum = checksum; - - /* Copy structs on stack back to packet */ - - memcpy(packet->data + ether_size, &ip6, ip6_size); - memcpy(packet->data + ether_size + ip6_size, &ns, ns_size); - if(has_opt) - memcpy(packet->data + ether_size + ip6_size + ns_size, &opt, opt_size); - - send_packet(source, packet); -} - -static void route_ipv6(node_t *source, vpn_packet_t *packet) { - if(!checklength(source, packet, ether_size + ip6_size)) - return; - - if(packet->data[20] == IPPROTO_ICMPV6 && checklength(source, packet, ether_size + ip6_size + icmp6_size) && packet->data[54] == ND_NEIGHBOR_SOLICIT) { - route_neighborsol(source, packet); - return; - } - - if(broadcast_mode && packet->data[38] == 255) - broadcast_packet(source, packet); - else - route_ipv6_unicast(source, packet); -} - -/* RFC 826 */ - -static void route_arp(node_t *source, vpn_packet_t *packet) { - struct ether_arp arp; - subnet_t *subnet; - struct in_addr addr; - - if(!checklength(source, packet, ether_size + arp_size)) - return; - - if(source != myself) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Got ARP request from %s (%s) while in router mode!", source->name, source->hostname); - return; - } - - /* First, snatch the source address from the ARP packet */ - - if(overwrite_mac) - memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN); - - /* Copy headers from packet to structs on the stack */ - - memcpy(&arp, packet->data + ether_size, arp_size); - - /* Check if this is a valid ARP request */ - - if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP || - arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof addr || ntohs(arp.arp_op) != ARPOP_REQUEST) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: received unknown type ARP request"); - return; - } - - /* Check if the IPv4 address exists on the VPN */ - - subnet = lookup_subnet_ipv4((ipv4_t *) &arp.arp_tpa); - - if(!subnet) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: ARP request for unknown address %d.%d.%d.%d", - arp.arp_tpa[0], arp.arp_tpa[1], arp.arp_tpa[2], - arp.arp_tpa[3]); - return; - } - - /* Check if it is for our own subnet */ - - if(subnet->owner == myself) - return; /* silently ignore */ - - memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ - packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ - - memcpy(&addr, arp.arp_tpa, sizeof addr); /* save protocol addr */ - memcpy(arp.arp_tpa, arp.arp_spa, sizeof addr); /* swap destination and source protocol address */ - memcpy(arp.arp_spa, &addr, sizeof addr); /* ... */ - - memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */ - memcpy(arp.arp_sha, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ - arp.arp_op = htons(ARPOP_REPLY); - - /* Copy structs on stack back to packet */ - - memcpy(packet->data + ether_size, &arp, arp_size); - - send_packet(source, packet); -} - -static void route_mac(node_t *source, vpn_packet_t *packet) { - subnet_t *subnet; - mac_t dest; - - /* Learn source address */ - - if(source == myself) { - mac_t src; - memcpy(&src, &packet->data[6], sizeof src); - learn_mac(&src); - } - - /* Lookup destination address */ - - memcpy(&dest, &packet->data[0], sizeof dest); - subnet = lookup_subnet_mac(NULL, &dest); - - if(!subnet) { - broadcast_packet(source, packet); - return; - } - - if(subnet->owner == source) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); - return; - } - - if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) - return; - - uint16_t type = packet->data[12] << 8 | packet->data[13]; - - if(priorityinheritance && type == ETH_P_IP && packet->len >= ether_size + ip_size) - packet->priority = packet->data[15]; - - // Handle packets larger than PMTU - - node_t *via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - - if(directonly && subnet->owner != via) - return; - - if(via && packet->len > via->mtu && via != myself) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); - length_t ethlen = 14; - - if(type == ETH_P_8021Q) { - type = packet->data[16] << 8 | packet->data[17]; - ethlen += 4; - } - - if(type == ETH_P_IP && packet->len > 576 + ethlen) { - if(packet->data[6 + ethlen] & 0x40) { - packet->len = via->mtu; - route_ipv4_unreachable(source, packet, ethlen, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); - } else { - fragment_ipv4_packet(via, packet, ethlen); - } - return; - } else if(type == ETH_P_IPV6 && packet->len > 1280 + ethlen) { - packet->len = via->mtu; - route_ipv6_unreachable(source, packet, ethlen, ICMP6_PACKET_TOO_BIG, 0); - return; - } - } - - clamp_mss(source, via, packet); - - send_packet(subnet->owner, packet); -} - -static void send_pcap(vpn_packet_t *packet) { - pcap = false; - - for list_each(connection_t, c, connection_list) { - if(!c->status.pcap) - continue; - - pcap = true; - int len = packet->len; - if(c->outmaclength && c->outmaclength < len) - len = c->outmaclength; - - if(send_request(c, "%d %d %d", CONTROL, REQ_PCAP, len)) - send_meta(c, (char *)packet->data, len); - } -} - -static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { - uint16_t type = packet->data[12] << 8 | packet->data[13]; - length_t ethlen = ether_size; - - if(type == ETH_P_8021Q) { - type = packet->data[16] << 8 | packet->data[17]; - ethlen += 4; - } - - switch (type) { - case ETH_P_IP: - if(!checklength(source, packet, ethlen + ip_size)) - return false; - - if(packet->data[ethlen + 8] < 1) { - if(packet->data[ethlen + 11] != IPPROTO_ICMP || packet->data[ethlen + 32] != ICMP_TIME_EXCEEDED) - route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL); - return false; - } - - uint16_t old = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9]; - packet->data[ethlen + 8]--; - uint16_t new = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9]; - - uint32_t checksum = packet->data[ethlen + 10] << 8 | packet->data[ethlen + 11]; - checksum += old + (~new & 0xFFFF); - while(checksum >> 16) - checksum = (checksum & 0xFFFF) + (checksum >> 16); - packet->data[ethlen + 10] = checksum >> 8; - packet->data[ethlen + 11] = checksum & 0xff; - - return true; - - case ETH_P_IPV6: - if(!checklength(source, packet, ethlen + ip6_size)) - return false; - - if(packet->data[ethlen + 7] < 1) { - if(packet->data[ethlen + 6] != IPPROTO_ICMPV6 || packet->data[ethlen + 40] != ICMP6_TIME_EXCEEDED) - route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT); - return false; - } - - packet->data[ethlen + 7]--; - - return true; - - default: - return true; - } -} - void route(node_t *source, vpn_packet_t *packet) { - if(pcap) - send_pcap(packet); - - if(forwarding_mode == FMODE_KERNEL && source != myself) { - send_packet(myself, packet); - return; - } - - if(!checklength(source, packet, ether_size)) - return; - - if(decrement_ttl && source != myself) - if(!do_decrement_ttl(source, packet)) - return; - - uint16_t type = packet->data[12] << 8 | packet->data[13]; - - switch (routing_mode) { - case RMODE_ROUTER: - switch (type) { - case ETH_P_ARP: - route_arp(source, packet); - break; - - case ETH_P_IP: - route_ipv4(source, packet); - break; - - case ETH_P_IPV6: - route_ipv6(source, packet); - break; - - default: - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type); - break; - } - break; - - case RMODE_SWITCH: - route_mac(source, packet); - break; - - case RMODE_HUB: - broadcast_packet(source, packet); - break; - } + // TODO: route on name or key } diff --git a/src/script.c b/src/script.c deleted file mode 100644 index 9a43d531..00000000 --- a/src/script.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - script.c -- call an external script - Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "conf.h" -#include "logger.h" -#include "names.h" -#include "script.h" -#include "xalloc.h" - -bool execute_script(const char *name, char **envp) { -#ifdef HAVE_SYSTEM - char *scriptname; - char *command; - - xasprintf(&scriptname, "%s" SLASH "%s%s", confbase, name, scriptextension); - - /* First check if there is a script */ - -#ifdef HAVE_MINGW - if(!*scriptextension) { - const char *pathext = getenv("PATHEXT") ?: ".COM;.EXE;.BAT;.CMD"; - char fullname[strlen(scriptname) + strlen(pathext)]; - char *ext = fullname + strlen(scriptname); - strcpy(fullname, scriptname); - - const char *p = pathext; - bool found = false; - while(p && *p) { - const char *q = strchr(p, ';'); - if(q) { - memcpy(ext, p, q - p); - ext[q - p] = 0; - *q++; - } else { - strcpy(ext, p); - } - if((found = !access(fullname, F_OK))) - break; - p = q; - } - if(!found) { - free(scriptname); - return true; - } - } else -#endif - - if(access(scriptname, F_OK)) { - free(scriptname); - return true; - } - - logger(DEBUG_STATUS, LOG_INFO, "Executing script %s", name); - -#ifdef HAVE_PUTENV - /* Set environment */ - - for(int i = 0; envp[i]; i++) - putenv(envp[i]); -#endif - - if(scriptinterpreter) - xasprintf(&command, "%s \"%s\"", scriptinterpreter, scriptname); - else - xasprintf(&command, "\"%s\"", scriptname); - - int status = system(command); - - free(command); - free(scriptname); - - /* Unset environment */ - - for(int i = 0; envp[i]; i++) { - char *e = strchr(envp[i], '='); - if(e) { - char p[e - envp[i] + 1]; - strncpy(p, envp[i], e - envp[i]); - p[e - envp[i]] = '\0'; - putenv(p); - } - } - - if(status != -1) { -#ifdef WEXITSTATUS - if(WIFEXITED(status)) { /* Child exited by itself */ - if(WEXITSTATUS(status)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Script %s exited with non-zero status %d", - name, WEXITSTATUS(status)); - return false; - } - } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */ - logger(DEBUG_ALWAYS, LOG_ERR, "Script %s was killed by signal %d (%s)", - name, WTERMSIG(status), strsignal(WTERMSIG(status))); - return false; - } else { /* Something strange happened */ - logger(DEBUG_ALWAYS, LOG_ERR, "Script %s terminated abnormally", name); - return false; - } -#endif - } else { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno)); - return false; - } -#endif - return true; -} diff --git a/src/script.h b/src/script.h deleted file mode 100644 index 446a3b95..00000000 --- a/src/script.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - script.h -- header file for script.c - Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_SCRIPT_H__ -#define __TINC_SCRIPT_H__ - -extern bool execute_script(const char *, char **); - -#endif /* __TINC_SCRIPT_H__ */ diff --git a/src/solaris/device.c b/src/solaris/device.c deleted file mode 100644 index 4940ddb5..00000000 --- a/src/solaris/device.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - device.c -- Interaction with Solaris tun device - Copyright (C) 2001-2005 Ivo Timmermans, - 2002-2010 OpenVPN Technologies, Inc. - 2001-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include "../system.h" - -#include -#include - -#include "../conf.h" -#include "../device.h" -#include "../logger.h" -#include "../names.h" -#include "../net.h" -#include "../route.h" -#include "../utils.h" -#include "../xalloc.h" - -#ifndef TUNNEWPPA -#warning Missing net/if_tun.h, using hardcoded value for TUNNEWPPA -#define TUNNEWPPA (('T'<<16) | 0x0001) -#endif - -#define DEFAULT_TUN_DEVICE "/dev/tun" -#define DEFAULT_TAP_DEVICE "/dev/tap" - -static enum { - DEVICE_TYPE_TUN, - DEVICE_TYPE_TAP, -} device_type = DEVICE_TYPE_TUN; - -int device_fd = -1; -static int if_fd = -1; -static int ip_fd = -1; -char *device = NULL; -char *iface = NULL; -static char *device_info = NULL; - -static bool setup_device(void) { - char *type; - - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - if(routing_mode == RMODE_ROUTER) - device = xstrdup(DEFAULT_TUN_DEVICE); - else - device = xstrdup(DEFAULT_TAP_DEVICE); - } - - if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { - if(!strcasecmp(type, "tun")) - /* use default */; - else if(!strcasecmp(type, "tap")) - device_type = DEVICE_TYPE_TAP; - else { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); - return false; - } - } else { - if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) - device_type = DEVICE_TYPE_TAP; - } - - if(device_type == DEVICE_TYPE_TUN) - device_info = "Solaris tun device"; - else - device_info = "Solaris tap device"; - - /* The following is black magic copied from OpenVPN. */ - - if((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", "/dev/ip", strerror(errno)); - return false; - } - - if((device_fd = open(device, O_RDWR, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); - return false; - } - - /* Get unit number. */ - - char *ptr = device; - get_config_string(lookup_config(config_tree, "Interface"), &ptr); - - while(*ptr && !isdigit(*ptr)) - ptr++; - int ppa = atoi(ptr); - - /* Assign a new PPA and get its unit number. */ - - struct strioctl strioc_ppa = { - .ic_cmd = TUNNEWPPA, - .ic_len = sizeof ppa, - .ic_dp = (char *)&ppa, - }; - - if(!*ptr) { /* no number given, try dynamic */ - bool found = false; - while(!found && ppa < 64) { - int new_ppa = ioctl(device_fd, I_STR, &strioc_ppa); - if(new_ppa >= 0) { - ppa = new_ppa; - found = true; - break; - } - ppa++; - } - if(!found) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not find free PPA for %s %s!", device_info, device); - return false; - } - } else { /* try this particular one */ - if((ppa = ioctl(device_fd, I_STR, &strioc_ppa)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not assign PPA %d for %s %s!", ppa, device_info, device); - return false; - } - } - - if((if_fd = open(device, O_RDWR, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); - return false; - } - - if(ioctl(if_fd, I_PUSH, "ip") < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not push IP module onto %s %s!", device_info, device); - return false; - } - - xasprintf(&iface, "%s%d", device_type == DEVICE_TYPE_TUN ? "tun" : "tap", ppa); - - { - /* Remove muxes just in case they are left over from a crashed tincd */ - struct lifreq ifr = {}; - strncpy(ifr.lifr_name, iface, sizeof ifr.lifr_name); - if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) { - int muxid = ifr.lifr_arp_muxid; - ioctl(ip_fd, I_PUNLINK, muxid); - muxid = ifr.lifr_ip_muxid; - ioctl(ip_fd, I_PUNLINK, muxid); - } - } - - if(device_type == DEVICE_TYPE_TUN) { - /* Assign ppa according to the unit number returned by tun device */ - if(ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); - return false; - } - } - - int arp_fd = -1; - - if(device_type == DEVICE_TYPE_TAP) { - struct lifreq ifr = {}; - - if(ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not set flags on %s %s!", device_info, device); - return false; - } - - strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); - ifr.lifr_ppa = ppa; - - /* Assign ppa according to the unit number returned by tun device */ - if(ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); - return false; - } - if(ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not set flags on %s %s!", device_info, device); - return false; - } - - /* Push arp module to if_fd */ - if(ioctl(if_fd, I_PUSH, "arp") < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s %s!", device_info, device); - return false; - } - - /* Pop any modules on the stream */ - while(true) { - if(ioctl(ip_fd, I_POP, NULL) < 0) - break; - } - - /* Push arp module to ip_fd */ - if(ioctl(ip_fd, I_PUSH, "arp") < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s!", "/dev/ip"); - return false; - } - - /* Open arp_fd */ - if((arp_fd = open(device, O_RDWR, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); - return false; - } - - /* Push arp module to arp_fd */ - if(ioctl(arp_fd, I_PUSH, "arp") < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s %s!", device_info, device); - return false; - } - - /* Set ifname to arp */ - struct strioctl strioc_if = { - .ic_cmd = SIOCSLIFNAME, - .ic_len = sizeof ifr, - .ic_dp = (char *)&ifr, - }; - - if(ioctl(arp_fd, I_STR, &strioc_if) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not set ifname to %s %s", device_info, device); - return false; - } - } - - int ip_muxid, arp_muxid; - - if((ip_muxid = ioctl(ip_fd, I_PLINK, if_fd)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not link %s %s to IP", device_info, device); - return false; - } - - if(device_type == DEVICE_TYPE_TAP) { - if((arp_muxid = ioctl(ip_fd, I_PLINK, arp_fd)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not link %s %s to ARP", device_info, device); - return false; - } - close(arp_fd); - } - - struct lifreq ifr = {}; - strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); - ifr.lifr_ip_muxid = ip_muxid; - if(device_type == DEVICE_TYPE_TAP) { - ifr.lifr_arp_muxid = arp_muxid; - } - - if(ioctl(ip_fd, SIOCSLIFMUXID, &ifr) < 0) { - if(device_type == DEVICE_TYPE_TAP) { - ioctl(ip_fd, I_PUNLINK, arp_muxid); - } - ioctl(ip_fd, I_PUNLINK, ip_muxid); - logger(DEBUG_ALWAYS, LOG_ERR, "Could not set multiplexor id for %s %s", device_info, device); - return false; - } - - close(if_fd); - -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); - fcntl(ip_fd, F_SETFD, FD_CLOEXEC); -#endif - - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - - return true; -} - -static void close_device(void) { - if(iface) { - struct lifreq ifr = {}; - strncpy(ifr.lifr_name, iface, sizeof ifr.lifr_name); - if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) { - int muxid = ifr.lifr_arp_muxid; - ioctl(ip_fd, I_PUNLINK, muxid); - muxid = ifr.lifr_ip_muxid; - ioctl(ip_fd, I_PUNLINK, muxid); - } - } - - close(ip_fd); - close(device_fd); - - free(device); - free(iface); -} - -static bool read_packet(vpn_packet_t *packet) { - int inlen; - - switch(device_type) { - case DEVICE_TYPE_TUN: - if((inlen = read(device_fd, packet->data + 14, MTU - 14)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - return false; - } - - switch(packet->data[14] >> 4) { - case 4: - packet->data[12] = 0x08; - packet->data[13] = 0x00; - break; - case 6: - packet->data[12] = 0x86; - packet->data[13] = 0xDD; - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version %d while reading packet from %s %s", packet->data[14] >> 4, device_info, device); - return false; - } - - memset(packet->data, 0, 12); - packet->len = inlen + 14; - break; - - case DEVICE_TYPE_TAP: - if((inlen = read(device_fd, packet->data, MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - return false; - } - - packet->len = inlen + 14; - break; - - default: - abort(); - } - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); - - return true; -} - -static bool write_packet(vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); - - switch(device_type) { - case DEVICE_TYPE_TUN: - if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - return false; - } - break; - - case DEVICE_TYPE_TAP: - if(write(device_fd, packet->data, packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - return false; - } - break; - - default: - abort(); - } - - return true; -} - -const devops_t os_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, -}; diff --git a/src/subnet.c b/src/subnet.c deleted file mode 100644 index 7ff8f7aa..00000000 --- a/src/subnet.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - subnet.c -- handle subnet lookups and lists - Copyright (C) 2000-2013 Guus Sliepen , - 2000-2005 Ivo Timmermans - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "splay_tree.h" -#include "control_common.h" -#include "device.h" -#include "hash.h" -#include "logger.h" -#include "names.h" -#include "net.h" -#include "netutl.h" -#include "node.h" -#include "script.h" -#include "subnet.h" -#include "utils.h" -#include "xalloc.h" - -/* lists type of subnet */ - -splay_tree_t *subnet_tree; - -/* Subnet lookup cache */ - -hash_t *ipv4_cache; -hash_t *ipv6_cache; -hash_t *mac_cache; - -void subnet_cache_flush(void) { - hash_clear(ipv4_cache); - hash_clear(ipv6_cache); - hash_clear(mac_cache); -} - -/* Initialising trees */ - -void init_subnets(void) { - subnet_tree = splay_alloc_tree((splay_compare_t) subnet_compare, (splay_action_t) free_subnet); - - ipv4_cache = hash_alloc(0x100, sizeof(ipv4_t)); - ipv6_cache = hash_alloc(0x100, sizeof(ipv6_t)); - mac_cache = hash_alloc(0x100, sizeof(mac_t)); -} - -void exit_subnets(void) { - splay_delete_tree(subnet_tree); - - hash_free(ipv4_cache); - hash_free(ipv6_cache); - hash_free(mac_cache); -} - -splay_tree_t *new_subnet_tree(void) { - return splay_alloc_tree((splay_compare_t) subnet_compare, NULL); -} - -void free_subnet_tree(splay_tree_t *subnet_tree) { - splay_delete_tree(subnet_tree); -} - -/* Allocating and freeing space for subnets */ - -subnet_t *new_subnet(void) { - return xzalloc(sizeof(subnet_t)); -} - -void free_subnet(subnet_t *subnet) { - free(subnet); -} - -/* Adding and removing subnets */ - -void subnet_add(node_t *n, subnet_t *subnet) { - subnet->owner = n; - - splay_insert(subnet_tree, subnet); - splay_insert(n->subnet_tree, subnet); - - subnet_cache_flush(); -} - -void subnet_del(node_t *n, subnet_t *subnet) { - splay_delete(n->subnet_tree, subnet); - splay_delete(subnet_tree, subnet); - - subnet_cache_flush(); -} - -/* Subnet lookup routines */ - -subnet_t *lookup_subnet(const node_t *owner, const subnet_t *subnet) { - return splay_search(owner->subnet_tree, subnet); -} - -subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { - subnet_t *r = NULL; - - // Check if this address is cached - - if((r = hash_search(mac_cache, address))) - return r; - - // Search all subnets for a matching one - - for splay_each(subnet_t, p, owner ? owner->subnet_tree : subnet_tree) { - if(!p || p->type != SUBNET_MAC) - continue; - - if(!memcmp(address, &p->net.mac.address, sizeof *address)) { - r = p; - if(p->owner->status.reachable) - break; - } - } - - // Cache the result - - if(r) - hash_insert(mac_cache, address, r); - - return r; -} - -subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { - subnet_t *r = NULL; - - // Check if this address is cached - - if((r = hash_search(ipv4_cache, address))) - return r; - - // Search all subnets for a matching one - - for splay_each(subnet_t, p, subnet_tree) { - if(!p || p->type != SUBNET_IPV4) - continue; - - if(!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength)) { - r = p; - if(p->owner->status.reachable) - break; - } - } - - // Cache the result - - if(r) - hash_insert(ipv4_cache, address, r); - - return r; -} - -subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { - subnet_t *r = NULL; - - // Check if this address is cached - - if((r = hash_search(ipv6_cache, address))) - return r; - - // Search all subnets for a matching one - - for splay_each(subnet_t, p, subnet_tree) { - if(!p || p->type != SUBNET_IPV6) - continue; - - if(!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength)) { - r = p; - if(p->owner->status.reachable) - break; - } - } - - // Cache the result - - if(r) - hash_insert(ipv6_cache, address, r); - - return r; -} - -void subnet_update(node_t *owner, subnet_t *subnet, bool up) { - char netstr[MAXNETSTR]; - char *name, *address, *port; - char empty[] = ""; - - // Prepare environment variables to be passed to the script - - char *envp[10] = {NULL}; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NODE=%s", owner->name); - - if(owner != myself) { - sockaddr2str(&owner->address, &address, &port); - // 4 and 5 are reserved for SUBNET and WEIGHT - xasprintf(&envp[6], "REMOTEADDRESS=%s", address); - xasprintf(&envp[7], "REMOTEPORT=%s", port); - free(port); - free(address); - } - - xasprintf(&envp[8], "NAME=%s", myself->name); - - name = up ? "subnet-up" : "subnet-down"; - - if(!subnet) { - for splay_each(subnet_t, subnet, owner->subnet_tree) { - if(!net2str(netstr, sizeof netstr, subnet)) - continue; - - // Strip the weight from the subnet, and put it in its own environment variable - char *weight = strchr(netstr, '#'); - if(weight) - *weight++ = 0; - else - weight = empty; - - // Prepare the SUBNET and WEIGHT variables - if(envp[4]) - free(envp[4]); - if(envp[5]) - free(envp[5]); - xasprintf(&envp[4], "SUBNET=%s", netstr); - xasprintf(&envp[5], "WEIGHT=%s", weight); - - execute_script(name, envp); - } - } else { - if(net2str(netstr, sizeof netstr, subnet)) { - // Strip the weight from the subnet, and put it in its own environment variable - char *weight = strchr(netstr, '#'); - if(weight) - *weight++ = 0; - else - weight = empty; - - // Prepare the SUBNET and WEIGHT variables - xasprintf(&envp[4], "SUBNET=%s", netstr); - xasprintf(&envp[5], "WEIGHT=%s", weight); - - execute_script(name, envp); - } - } - - for(int i = 0; envp[i] && i < 9; i++) - free(envp[i]); -} - -bool dump_subnets(connection_t *c) { - for splay_each(subnet_t, subnet, subnet_tree) { - char netstr[MAXNETSTR]; - - if(!net2str(netstr, sizeof netstr, subnet)) - continue; - - send_request(c, "%d %d %s %s", - CONTROL, REQ_DUMP_SUBNETS, - netstr, subnet->owner->name); - } - - return send_request(c, "%d %d", CONTROL, REQ_DUMP_SUBNETS); -} diff --git a/src/subnet.h b/src/subnet.h deleted file mode 100644 index 9fd95b64..00000000 --- a/src/subnet.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - subnet.h -- header for subnet.c - Copyright (C) 2000-2012 Guus Sliepen , - 2000-2005 Ivo Timmermans - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_SUBNET_H__ -#define __TINC_SUBNET_H__ - -#include "net.h" - -typedef enum subnet_type_t { - SUBNET_MAC = 0, - SUBNET_IPV4, - SUBNET_IPV6, - SUBNET_TYPES /* Guardian */ -} subnet_type_t; - -typedef struct subnet_mac_t { - mac_t address; -} 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 */ - - subnet_type_t type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */ - time_t expires; /* expiry time */ - int weight; /* weight (higher value is higher priority) */ - - /* And now for the actual subnet: */ - - union net { - subnet_mac_t mac; - subnet_ipv4_t ipv4; - subnet_ipv6_t ipv6; - } net; -} subnet_t; - -#define MAXNETSTR 64 - -extern splay_tree_t *subnet_tree; - -extern int subnet_compare(const struct subnet_t *, const struct subnet_t *); -extern subnet_t *new_subnet(void) __attribute__ ((__malloc__)); -extern void free_subnet(subnet_t *); -extern void init_subnets(void); -extern void exit_subnets(void); -extern splay_tree_t *new_subnet_tree(void) __attribute__ ((__malloc__)); -extern void free_subnet_tree(splay_tree_t *); -extern void subnet_add(struct node_t *, subnet_t *); -extern void subnet_del(struct node_t *, subnet_t *); -extern void subnet_update(struct node_t *, subnet_t *, bool); -extern int maskcmp(const void *, const void *, int); -extern void maskcpy(void *, const void *, int, int); -extern void mask(void *, int, int); -extern bool maskcheck(const void *, int, int); -extern bool net2str(char *, int, const subnet_t *); -extern bool str2net(subnet_t *, const char *); -extern subnet_t *lookup_subnet(const struct node_t *, const subnet_t *); -extern subnet_t *lookup_subnet_mac(const struct node_t *, const mac_t *); -extern subnet_t *lookup_subnet_ipv4(const ipv4_t *); -extern subnet_t *lookup_subnet_ipv6(const ipv6_t *); -extern bool dump_subnets(struct connection_t *); -extern void subnet_cache_flush(void); - -#endif /* __TINC_SUBNET_H__ */ diff --git a/src/subnet_parse.c b/src/subnet_parse.c deleted file mode 100644 index f9801800..00000000 --- a/src/subnet_parse.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - subnet_parse.c -- handle subnet parsing - Copyright (C) 2000-2012 Guus Sliepen , - 2000-2005 Ivo Timmermans - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "logger.h" -#include "net.h" -#include "netutl.h" -#include "subnet.h" -#include "utils.h" -#include "xalloc.h" - -/* Subnet mask handling */ - -int maskcmp(const void *va, const void *vb, int masklen) { - int i, m, result; - const char *a = va; - const char *b = vb; - - for(m = masklen, i = 0; m >= 8; m -= 8, i++) { - result = a[i] - b[i]; - if(result) - return result; - } - - if(m) - return (a[i] & (0x100 - (1 << (8 - m)))) - - (b[i] & (0x100 - (1 << (8 - m)))); - - return 0; -} - -void mask(void *va, int masklen, int len) { - int i; - char *a = va; - - i = masklen / 8; - masklen %= 8; - - if(masklen) - a[i++] &= (0x100 - (1 << (8 - masklen))); - - for(; i < len; i++) - a[i] = 0; -} - -void maskcpy(void *va, const void *vb, int masklen, int len) { - int i, m; - char *a = va; - const char *b = vb; - - for(m = masklen, i = 0; m >= 8; m -= 8, i++) - a[i] = b[i]; - - if(m) { - a[i] = b[i] & (0x100 - (1 << (8 - m))); - i++; - } - - for(; i < len; i++) - a[i] = 0; -} - -bool maskcheck(const void *va, int masklen, int len) { - int i; - const char *a = va; - - i = masklen / 8; - masklen %= 8; - - if(masklen && a[i++] & (0xff >> masklen)) - return false; - - for(; i < len; i++) - if(a[i] != 0) - return false; - - return true; -} - -/* Subnet comparison */ - -static int subnet_compare_mac(const subnet_t *a, const subnet_t *b) { - int result; - - result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof a->net.mac.address); - - if(result) - return result; - - result = a->weight - b->weight; - - if(result || !a->owner || !b->owner) - return result; - - return strcmp(a->owner->name, b->owner->name); -} - -static int subnet_compare_ipv4(const subnet_t *a, const subnet_t *b) { - int result; - - result = b->net.ipv4.prefixlength - a->net.ipv4.prefixlength; - - if(result) - return result; - - result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t)); - - if(result) - return result; - - result = a->weight - b->weight; - - if(result || !a->owner || !b->owner) - return result; - - return strcmp(a->owner->name, b->owner->name); -} - -static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b) { - int result; - - result = b->net.ipv6.prefixlength - a->net.ipv6.prefixlength; - - if(result) - return result; - - result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t)); - - if(result) - return result; - - result = a->weight - b->weight; - - if(result || !a->owner || !b->owner) - return result; - - return strcmp(a->owner->name, b->owner->name); -} - -int subnet_compare(const subnet_t *a, const subnet_t *b) { - int result; - - 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: - logger(DEBUG_ALWAYS, LOG_ERR, "subnet_compare() was called with unknown subnet type %d, exitting!", a->type); - exit(1); - } - - return 0; -} - -/* Ascii representation of subnets */ - -bool str2net(subnet_t *subnet, const char *subnetstr) { - int i, l; - uint16_t x[8]; - int weight = 10; - - if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d#%d", - &x[0], &x[1], &x[2], &x[3], &l, &weight) >= 5) { - if(l < 0 || l > 32) - return false; - - subnet->type = SUBNET_IPV4; - subnet->net.ipv4.prefixlength = l; - subnet->weight = weight; - - for(int i = 0; i < 4; i++) { - if(x[i] > 255) - return false; - subnet->net.ipv4.address.x[i] = x[i]; - } - - return true; - } - - if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d#%d", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], - &l, &weight) >= 9) { - if(l < 0 || l > 128) - return false; - - subnet->type = SUBNET_IPV6; - subnet->net.ipv6.prefixlength = l; - subnet->weight = weight; - - for(i = 0; i < 8; i++) - subnet->net.ipv6.address.x[i] = htons(x[i]); - - return true; - } - - if(sscanf(subnetstr, "%hu.%hu.%hu.%hu#%d", &x[0], &x[1], &x[2], &x[3], &weight) >= 4) { - subnet->type = SUBNET_IPV4; - subnet->net.ipv4.prefixlength = 32; - subnet->weight = weight; - - for(i = 0; i < 4; i++) { - if(x[i] > 255) - return false; - subnet->net.ipv4.address.x[i] = x[i]; - } - - return true; - } - - 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], &weight) >= 8) { - subnet->type = SUBNET_IPV6; - subnet->net.ipv6.prefixlength = 128; - subnet->weight = weight; - - for(i = 0; i < 8; i++) - subnet->net.ipv6.address.x[i] = htons(x[i]); - - return true; - } - - if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx#%d", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &weight) >= 6) { - subnet->type = SUBNET_MAC; - subnet->weight = weight; - - for(i = 0; i < 6; i++) - subnet->net.mac.address.x[i] = x[i]; - - return true; - } - - // IPv6 short form - if(strstr(subnetstr, "::")) { - const char *p; - char *q; - int colons = 0; - - // Count number of colons - for(p = subnetstr; *p; p++) - if(*p == ':') - colons++; - - if(colons > 7) - return false; - - // Scan numbers before the double colon - p = subnetstr; - for(i = 0; i < colons; i++) { - if(*p == ':') - break; - x[i] = strtoul(p, &q, 0x10); - if(!q || p == q || *q != ':') - return false; - p = ++q; - } - - p++; - colons -= i; - if(!i) { - p++; - colons--; - } - - if(!*p || *p == '/' || *p == '#') - colons--; - - // Fill in the blanks - for(; i < 8 - colons; i++) - x[i] = 0; - - // Scan the remaining numbers - for(; i < 8; i++) { - x[i] = strtoul(p, &q, 0x10); - if(!q || p == q) - return false; - if(i == 7) { - p = q; - break; - } - if(*q != ':') - return false; - p = ++q; - } - - l = 128; - if(*p == '/') - sscanf(p, "/%d#%d", &l, &weight); - else if(*p == '#') - sscanf(p, "#%d", &weight); - - if(l < 0 || l > 128) - return false; - - subnet->type = SUBNET_IPV6; - subnet->net.ipv6.prefixlength = l; - subnet->weight = weight; - - for(i = 0; i < 8; i++) - subnet->net.ipv6.address.x[i] = htons(x[i]); - - return true; - } - - return false; -} - -bool net2str(char *netstr, int len, const subnet_t *subnet) { - if(!netstr || !subnet) { - logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with netstr=%p, subnet=%p!", netstr, subnet); - return false; - } - - switch (subnet->type) { - case SUBNET_MAC: - snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx#%d", - 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], - subnet->weight); - break; - - case SUBNET_IPV4: - snprintf(netstr, len, "%hu.%hu.%hu.%hu/%d#%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, - subnet->weight); - break; - - case SUBNET_IPV6: - snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d#%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, - subnet->weight); - break; - - default: - logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with unknown subnet type %d, exiting!", subnet->type); - exit(1); - } - - return true; -} diff --git a/src/tincctl.c b/src/tincctl.c index 81e7a7a2..a706f484 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -33,7 +33,6 @@ #include "ecdsagen.h" #include "info.h" #include "invitation.h" -#include "names.h" #include "rsagen.h" #include "utils.h" #include "tincctl.h" @@ -2098,7 +2097,6 @@ static int switch_network(char *name) { free(netname); netname = strcmp(name, ".") ? xstrdup(name) : NULL; - make_names(); xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); xasprintf(&prompt, "%s> ", identname); @@ -2414,7 +2412,6 @@ int main(int argc, char *argv[]) { if(!parse_options(argc, argv)) return 1; - make_names(); xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); diff --git a/src/tincd.c b/src/tincd.c index 56ed2f0c..8c4655cd 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -46,14 +46,10 @@ #include #include "conf.h" -#include "control.h" #include "crypto.h" -#include "device.h" #include "logger.h" -#include "names.h" #include "net.h" #include "netutl.h" -#include "process.h" #include "protocol.h" #include "utils.h" #include "xalloc.h" @@ -80,9 +76,6 @@ static bool do_chroot = false; static const char *switchuser = NULL; #endif -/* If nonzero, write log entries to a separate file. */ -bool use_logfile = false; - char **g_argv; /* a copy of the cmdline arguments */ static int status = 1; @@ -98,8 +91,6 @@ static struct option const long_options[] = { {"mlock", no_argument, NULL, 'L'}, {"chroot", no_argument, NULL, 'R'}, {"user", required_argument, NULL, 'U'}, - {"logfile", optional_argument, NULL, 4}, - {"pidfile", required_argument, NULL, 5}, {"option", required_argument, NULL, 'o'}, {NULL, 0, NULL, 0} }; @@ -112,10 +103,9 @@ int main2(int argc, char **argv); static void usage(bool status) { if(status) - fprintf(stderr, "Try `%s --help\' for more information.\n", - program_name); + fprintf(stderr, "Try `tincd --help\' for more information.\n"); else { - printf("Usage: %s [option]...\n\n", program_name); + printf("Usage: tincd [option]...\n\n"); printf( " -c, --config=DIR Read configuration options from DIR.\n" " -D, --no-detach Don't fork and detach.\n" " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" @@ -123,8 +113,6 @@ static void usage(bool status) { #ifdef HAVE_MLOCKALL " -L, --mlock Lock tinc into main memory.\n" #endif - " --logfile[=FILENAME] Write log entries to a logfile.\n" - " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n" " --bypass-security Disables meta protocol security, for debugging.\n" " -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n" #ifndef HAVE_MINGW @@ -154,10 +142,6 @@ static bool parse_options(int argc, char **argv) { confbase = xstrdup(optarg); break; - case 'D': /* no detach */ - do_detach = false; - break; - case 'L': /* no detach */ #ifndef HAVE_MLOCKALL logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]); @@ -176,10 +160,6 @@ static bool parse_options(int argc, char **argv) { debug_level++; break; - case 'n': /* net name given */ - netname = xstrdup(optarg); - break; - case 'o': /* option */ cfg = parse_config_line(optarg, NULL, ++lineno); if (!cfg) @@ -214,18 +194,6 @@ static bool parse_options(int argc, char **argv) { bypass_security = true; break; - case 4: /* write log entries to a file */ - use_logfile = true; - if(!optarg && optind < argc && *argv[optind] != '-') - optarg = argv[optind++]; - if(optarg) - logfilename = xstrdup(optarg); - break; - - case 5: /* open control socket here */ - pidfilename = xstrdup(optarg); - break; - case '?': /* wrong options */ usage(true); return false; @@ -241,21 +209,6 @@ static bool parse_options(int argc, char **argv) { return false; } - if(!netname && (netname = getenv("NETNAME"))) - netname = xstrdup(netname); - - /* netname "." is special: a "top-level name" */ - - if(netname && (!*netname || !strcmp(netname, "."))) { - free(netname); - netname = NULL; - } - - if(netname && (strpbrk(netname, "\\/") || *netname == '.')) { - fprintf(stderr, "Invalid character in netname!\n"); - return false; - } - return true; } @@ -311,13 +264,9 @@ static bool drop_privs(void) { #endif int main(int argc, char **argv) { - program_name = argv[0]; - if(!parse_options(argc, argv)) return 1; - make_names(); - if(show_version) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, VERSION, __DATE__, __TIME__, PROT_MAJOR, PROT_MINOR); @@ -342,16 +291,10 @@ int main(int argc, char **argv) { } #endif - openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR); + openlogger("tinc", LOGMODE_STDERR); g_argv = argv; - if(getenv("LISTEN_PID") && atoi(getenv("LISTEN_PID")) == getpid()) - do_detach = false; -#ifdef HAVE_UNSETENV - unsetenv("LISTEN_PID"); -#endif - init_configuration(&config_tree); /* Slllluuuuuuurrrrp! */ @@ -370,22 +313,8 @@ int main(int argc, char **argv) { } #endif -#ifdef HAVE_MINGW - if(!do_detach || !init_service()) - return main2(argc, argv); - else - return 1; -} - -int main2(int argc, char **argv) { - InitializeCriticalSection(&mutex); - EnterCriticalSection(&mutex); -#endif char *priority = NULL; - if(!detach()) - return 1; - #ifdef HAVE_MLOCKALL /* Lock all pages into memory if requested. * This has to be done after daemon()/fork() so it works for child. @@ -397,7 +326,7 @@ int main2(int argc, char **argv) { } #endif - /* Setup sockets and open device. */ + /* Setup sockets. */ if(!setup_network()) goto end; @@ -451,7 +380,6 @@ end: exit_configuration(&config_tree); free(cmdline_conf); - free_names(); return status; } diff --git a/src/top.c b/src/top.c deleted file mode 100644 index 2824261c..00000000 --- a/src/top.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - top.c -- Show real-time statistics from a running tincd - Copyright (C) 2011-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#ifdef HAVE_CURSES - -#include - -#include "control_common.h" -#include "list.h" -#include "names.h" -#include "tincctl.h" -#include "top.h" -#include "xalloc.h" - -typedef struct nodestats_t { - char *name; - int i; - uint64_t in_packets; - uint64_t in_bytes; - uint64_t out_packets; - uint64_t out_bytes; - float in_packets_rate; - float in_bytes_rate; - float out_packets_rate; - float out_bytes_rate; - bool known; -} nodestats_t; - -static const char *const sortname[] = { - "name", - "in pkts", - "in bytes", - "out pkts", - "out bytes", - "tot pkts", - "tot bytes", -}; - -static int sortmode = 0; -static bool cumulative = false; - -static list_t node_list; -static struct timeval cur, prev, diff; -static int delay = 1000; -static bool changed = true; -static const char *bunit = "bytes"; -static float bscale = 1; -static const char *punit = "pkts"; -static float pscale = 1; - -static bool update(int fd) { - if(!sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC)) - return false; - - gettimeofday(&cur, NULL); - - timersub(&cur, &prev, &diff); - prev = cur; - float interval = diff.tv_sec + diff.tv_usec * 1e-6; - - char line[4096]; - char name[4096]; - int code; - int req; - uint64_t in_packets; - uint64_t in_bytes; - uint64_t out_packets; - uint64_t out_bytes; - - for list_each(nodestats_t, ns, &node_list) - ns->known = false; - - while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes); - - if(n == 2) - return true; - - if(n != 7) - return false; - - nodestats_t *found = NULL; - - for list_each(nodestats_t, ns, &node_list) { - int result = strcmp(name, ns->name); - if(result > 0) { - continue; - } if(result == 0) { - found = ns; - break; - } else { - found = xzalloc(sizeof *found); - found->name = xstrdup(name); - list_insert_before(&node_list, node, found); - changed = true; - break; - } - } - - if(!found) { - found = xzalloc(sizeof *found); - found->name = xstrdup(name); - list_insert_tail(&node_list, found); - changed = true; - } - - found->known = true; - found->in_packets_rate = (in_packets - found->in_packets) / interval; - found->in_bytes_rate = (in_bytes - found->in_bytes) / interval; - found->out_packets_rate = (out_packets - found->out_packets) / interval; - found->out_bytes_rate = (out_bytes - found->out_bytes) / interval; - found->in_packets = in_packets; - found->in_bytes = in_bytes; - found->out_packets = out_packets; - found->out_bytes = out_bytes; - } - - return false; -} - -static int cmpfloat(float a, float b) { - if(a < b) - return -1; - else if(a > b) - return 1; - else - return 0; -} - -static int cmpu64(uint64_t a, uint64_t b) { - if(a < b) - return -1; - else if(a > b) - return 1; - else - return 0; -} - -static int sortfunc(const void *a, const void *b) { - const nodestats_t *na = *(const nodestats_t **)a; - const nodestats_t *nb = *(const nodestats_t **)b; - switch(sortmode) { - case 1: - if(cumulative) - return -cmpu64(na->in_packets, nb->in_packets) ?: na->i - nb->i; - else - return -cmpfloat(na->in_packets_rate, nb->in_packets_rate) ?: na->i - nb->i; - case 2: - if(cumulative) - return -cmpu64(na->in_bytes, nb->in_bytes) ?: na->i - nb->i; - else - return -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate) ?: na->i - nb->i; - case 3: - if(cumulative) - return -cmpu64(na->out_packets, nb->out_packets) ?: na->i - nb->i; - else - return -cmpfloat(na->out_packets_rate, nb->out_packets_rate) ?: na->i - nb->i; - case 4: - if(cumulative) - return -cmpu64(na->out_bytes, nb->out_bytes) ?: na->i - nb->i; - else - return -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate) ?: na->i - nb->i; - case 5: - if(cumulative) - return -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets) ?: na->i - nb->i; - else - return -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate) ?: na->i - nb->i; - case 6: - if(cumulative) - return -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes) ?: na->i - nb->i; - else - return -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate) ?: na->i - nb->i; - default: - return strcmp(na->name, nb->name) ?: na->i - nb->i; - } -} - -static void redraw(void) { - erase(); - - mvprintw(0, 0, "Tinc %-16s Nodes: %4d Sort: %-10s %s", netname ?: "", node_list.count, sortname[sortmode], cumulative ? "Cumulative" : "Current"); - attrset(A_REVERSE); - mvprintw(2, 0, "Node IN %s IN %s OUT %s OUT %s", punit, bunit, punit, bunit); - chgat(-1, A_REVERSE, 0, NULL); - - static nodestats_t **sorted = 0; - static int n = 0; - if(changed) { - n = 0; - sorted = xrealloc(sorted, node_list.count * sizeof *sorted); - for list_each(nodestats_t, ns, &node_list) - sorted[n++] = ns; - changed = false; - } - - for(int i = 0; i < n; i++) - sorted[i]->i = i; - - if(sorted) - qsort(sorted, n, sizeof *sorted, sortfunc); - - for(int i = 0, row = 3; i < n; i++, row++) { - nodestats_t *node = sorted[i]; - if(node->known) - if(node->in_packets_rate || node->out_packets_rate) - attrset(A_BOLD); - else - attrset(A_NORMAL); - else - attrset(A_DIM); - - if(cumulative) - mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f", - node->name, node->in_packets * pscale, node->in_bytes * bscale, node->out_packets * pscale, node->out_bytes * bscale); - else - mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f", - node->name, node->in_packets_rate * pscale, node->in_bytes_rate * bscale, node->out_packets_rate * pscale, node->out_bytes_rate * bscale); - } - - attrset(A_NORMAL); - move(1, 0); - - refresh(); -} - -void top(int fd) { - initscr(); - timeout(delay); - bool running = true; - - while(running) { - if(!update(fd)) - break; - - redraw(); - - switch(getch()) { - case 's': { - timeout(-1); - float input = delay * 1e-3; - mvprintw(1, 0, "Change delay from %.1fs to: ", input); - scanw("%f", &input); - if(input < 0.1) - input = 0.1; - delay = input * 1e3; - timeout(delay); - break; - } - case 'c': - cumulative = !cumulative; - break; - case 'n': - sortmode = 0; - break; - case 'i': - sortmode = 2; - break; - case 'I': - sortmode = 1; - break; - case 'o': - sortmode = 4; - break; - case 'O': - sortmode = 3; - break; - case 't': - sortmode = 6; - break; - case 'T': - sortmode = 5; - break; - case 'b': - bunit = "bytes"; - bscale = 1; - punit = "pkts"; - pscale = 1; - break; - case 'k': - bunit = "kbyte"; - bscale = 1e-3; - punit = "pkts"; - pscale = 1; - break; - case 'M': - bunit = "Mbyte"; - bscale = 1e-6; - punit = "kpkt"; - pscale = 1e-3; - break; - case 'G': - bunit = "Gbyte"; - bscale = 1e-9; - punit = "Mpkt"; - pscale = 1e-6; - break; - case 'q': - case KEY_BREAK: - running = false; - break; - default: - break; - } - } - - endwin(); -} - -#endif diff --git a/src/top.h b/src/top.h deleted file mode 100644 index b3a264da..00000000 --- a/src/top.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - top.h -- header for top.c. - Copyright (C) 2011 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_TOP_H__ -#define __TINC_TOP_H__ - -extern void top(int fd); - -#endif - diff --git a/src/uml_device.c b/src/uml_device.c deleted file mode 100644 index 5193fe98..00000000 --- a/src/uml_device.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - device.c -- UML network socket - Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include - -#include "conf.h" -#include "device.h" -#include "names.h" -#include "net.h" -#include "logger.h" -#include "utils.h" -#include "route.h" -#include "xalloc.h" - -static int listen_fd = -1; -static int request_fd = -1; -static int data_fd = -1; -static int write_fd = -1; -static int state = 0; -static char *device_info; - -enum request_type { REQ_NEW_CONTROL }; - -static struct request { - uint32_t magic; - uint32_t version; - enum request_type type; - struct sockaddr_un sock; -} request; - -static struct sockaddr_un data_sun; - -static bool setup_device(void) { - struct sockaddr_un listen_sun; - static const int one = 1; - struct { - char zero; - int pid; - int usecs; - } name; - struct timeval tv; - - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) - xasprintf(&device, LOCALSTATEDIR "/run/%s.umlsocket", identname); - - get_config_string(lookup_config(config_tree, "Interface"), &iface); - - device_info = "UML network socket"; - - if((write_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open write %s: %s", device_info, strerror(errno)); - event_exit(); - return false; - } - -#ifdef FD_CLOEXEC - fcntl(write_fd, F_SETFD, FD_CLOEXEC); -#endif - - setsockopt(write_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); - - if(fcntl(write_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); - event_exit(); - return false; - } - - if((data_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open data %s: %s", device_info, strerror(errno)); - event_exit(); - return false; - } - -#ifdef FD_CLOEXEC - fcntl(data_fd, F_SETFD, FD_CLOEXEC); -#endif - - setsockopt(data_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); - - if(fcntl(data_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); - event_exit(); - return false; - } - - name.zero = 0; - name.pid = getpid(); - gettimeofday(&tv, NULL); - name.usecs = tv.tv_usec; - data_sun.sun_family = AF_UNIX; - memcpy(&data_sun.sun_path, &name, sizeof name); - - if(bind(data_fd, (struct sockaddr *)&data_sun, sizeof data_sun) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind data %s: %s", device_info, strerror(errno)); - event_exit(); - return false; - } - - if((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device_info, - strerror(errno)); - return false; - } - -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif - - setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); - - if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); - return false; - } - - listen_sun.sun_family = AF_UNIX; - strncpy(listen_sun.sun_path, device, sizeof listen_sun.sun_path); - if(bind(listen_fd, (struct sockaddr *)&listen_sun, sizeof listen_sun) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind %s to %s: %s", device_info, device, strerror(errno)); - return false; - } - - if(listen(listen_fd, 1) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not listen on %s %s: %s", device_info, device, strerror(errno)); - return false; - } - - device_fd = listen_fd; - state = 0; - - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - - if(routing_mode == RMODE_ROUTER) - overwrite_mac = true; - - return true; -} - -void close_device(void) { - if(listen_fd >= 0) - close(listen_fd); - - if(request_fd >= 0) - close(request_fd); - - if(data_fd >= 0) - close(data_fd); - - if(write_fd >= 0) - close(write_fd); - - unlink(device); - - free(device); - if(iface) free(iface); -} - -static bool read_packet(vpn_packet_t *packet) { - int inlen; - - switch(state) { - case 0: { - struct sockaddr sa; - socklen_t salen = sizeof sa; - - request_fd = accept(listen_fd, &sa, &salen); - if(request_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not accept connection to %s %s: %s", device_info, device, strerror(errno)); - return false; - } - -#ifdef FD_CLOEXEC - fcntl(request_fd, F_SETFD, FD_CLOEXEC); -#endif - - if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); - event_exit(); - return false; - } - - close(listen_fd); - listen_fd = -1; - device_fd = request_fd; - state = 1; - - return false; - } - - case 1: { - if((inlen = read(request_fd, &request, sizeof request)) != sizeof request) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading request from %s %s: %s", device_info, - device, strerror(errno)); - event_exit(); - return false; - } - - if(request.magic != 0xfeedface || request.version != 3 || request.type != REQ_NEW_CONTROL) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s", - request.magic, request.version, request.type, device_info, device); - event_exit(); - return false; - } - - if(connect(write_fd, &request.sock, sizeof request.sock) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); - event_exit(); - return false; - } - - write(request_fd, &data_sun, sizeof data_sun); - device_fd = data_fd; - - logger(DEBUG_ALWAYS, LOG_INFO, "Connection with UML established"); - - state = 2; - return false; - } - - case 2: { - if((inlen = read(data_fd, packet->data, MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - event_exit(); - return false; - } - - packet->len = inlen; - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); - - return true; - } - - default: - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid value for state variable in " __FILE__); - abort(); - } -} - -static bool write_packet(vpn_packet_t *packet) { - if(state != 2) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Dropping packet of %d bytes to %s: not connected to UML yet", - packet->len, device_info); - return false; - } - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); - - if(write(write_fd, packet->data, packet->len) < 0) { - if(errno != EINTR && errno != EAGAIN) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - event_exit(); - } - - return false; - } - - return true; -} - -const devops_t uml_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, -}; diff --git a/src/vde_device.c b/src/vde_device.c deleted file mode 100644 index 1021f5d3..00000000 --- a/src/vde_device.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - device.c -- VDE plug - Copyright (C) 2013 Guus Sliepen - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include - -#include "conf.h" -#include "device.h" -#include "names.h" -#include "net.h" -#include "logger.h" -#include "utils.h" -#include "route.h" -#include "xalloc.h" - -static struct vdepluglib plug; -static struct vdeconn *conn = NULL; -static int port = 0; -static char *group = NULL; -static char *device_info; - -static bool setup_device(void) { - libvdeplug_dynopen(plug); - - if(!plug.dl_handle) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open libvdeplug library!"); - return false; - } - - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) - xasprintf(&device, LOCALSTATEDIR "/run/vde.ctl"); - - get_config_string(lookup_config(config_tree, "Interface"), &iface); - - get_config_int(lookup_config(config_tree, "VDEPort"), &port); - - get_config_string(lookup_config(config_tree, "VDEGroup"), &group); - - device_info = "VDE socket"; - - struct vde_open_args args = { - .port = port, - .group = group, - .mode = 0700, - }; - - conn = plug.vde_open(device, identname, &args); - if(!conn) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open VDE socket %s", device); - return false; - } - - device_fd = plug.vde_datafd(conn); - -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif - - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - - if(routing_mode == RMODE_ROUTER) - overwrite_mac = true; - - return true; -} - -static void close_device(void) { - if(conn) - plug.vde_close(conn); - - if(plug.dl_handle) - libvdeplug_dynclose(plug); - - free(device); - - free(iface); -} - -static bool read_packet(vpn_packet_t *packet) { - int lenin = (ssize_t)plug.vde_recv(conn, packet->data, MTU, 0); - if(lenin <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - event_exit(); - return false; - } - - packet->len = lenin; - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); - - return true; -} - -static bool write_packet(vpn_packet_t *packet) { - if((ssize_t)plug.vde_send(conn, packet->data, packet->len, 0) < 0) { - if(errno != EINTR && errno != EAGAIN) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - event_exit(); - } - - return false; - } - - return true; -} - -const devops_t vde_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, -};