AUTOMAKE_OPTIONS = gnu
-SUBDIRS = m4 src doc gui test
+SUBDIRS = m4 src doc test
ACLOCAL_AMFLAGS = -I m4
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
;;
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"],
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
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'
# 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) $? > $@
+++ /dev/null
-.Dd 2011-06-26
-.Dt TINC-GUI 8
-.\" Manual page created by:
-.\" Guus Sliepen <guus@tinc-vpn.org>
-.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!
+++ /dev/null
-.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!
+++ /dev/null
-.Dd 2014-01-29
-.Dt TINC.CONF 5
-.\" Manual page created by:
-.\" Ivo Timmermans
-.\" Guus Sliepen <guus@tinc-vpn.org>
-.Sh NAME
-.Nm tinc.conf
-.Nd tinc daemon configuration
-.Sh DESCRIPTION
-The files in the
-.Pa @sysconfdir@/tinc/
-directory contain runtime and security information for the tinc daemon.
-.Sh NETWORKS
-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.
+++ /dev/null
-.Dd 2013-01-14
-.Dt TINCD 8
-.\" Manual page created by:
-.\" Ivo Timmermans
-.\" Guus Sliepen <guus@tinc-vpn.org>
-.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!
+++ /dev/null
-dist_bin_SCRIPTS = tinc-gui
-
-extra_DIST = README.gui
+++ /dev/null
-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.
+++ /dev/null
-#!/usr/bin/python
-
-# tinc-gui -- GUI for controlling a running tincd
-# Copyright (C) 2009-2014 Guus Sliepen <guus@tinc-vpn.org>
-# 2014 Dennis Joachimsthaler <dennis@efjot.de>
-#
-# 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()
+++ /dev/null
-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)
-])
+++ /dev/null
-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.])]
- )
-])
+++ /dev/null
-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)
-])
## 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
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 \
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 \
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 \
protocol_key.c \
protocol_misc.c \
protocol_subnet.c \
- raw_socket_device.c \
route.c route.h \
rsa.h \
rsagen.h \
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 \
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)\"
+++ /dev/null
-/*
- device.c -- Interaction BSD tun/tap device
- Copyright (C) 2001-2005 Ivo Timmermans,
- 2001-2013 Guus Sliepen <guus@tinc-vpn.org>
- 2009 Grzegorz Dymarek <gregd72002@googlemail.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 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,
-};
+++ /dev/null
-/*
- * tunemu - Tun device emulation for Darwin
- * Copyright (C) 2009 Friedrich Schöller <friedrich.schoeller@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "tunemu.h"
-
-#include <sys/socket.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <memory.h>
-#include <util.h>
-#include <pcap.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <stdint.h>
-#include <stdint.h>
-#include <ctype.h>
-#include <fcntl.h>
-
-#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;
-}
+++ /dev/null
-/*
- * tunemu - Tun device emulation for Darwin
- * Copyright (C) 2009 Friedrich Schöller <friedrich.schoeller@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#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
+++ /dev/null
-/*
- device.c -- Interaction with Windows tap driver in a Cygwin environment
- Copyright (C) 2002-2005 Ivo Timmermans,
- 2002-2013 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "../system.h"
-
-#include <w32api/windows.h>
-#include <w32api/winioctl.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"
-
-#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,
-};
+++ /dev/null
-/*
- device.h -- generic header for device.c
- Copyright (C) 2001-2005 Ivo Timmermans
- 2001-2012 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 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__ */
+++ /dev/null
-/*
- device.c -- Dummy device
- Copyright (C) 2011-2012 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 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,
-};
+++ /dev/null
-/*
- cipher.c -- Symmetric block cipher handling
- Copyright (C) 2007-2012 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 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;
-}
+++ /dev/null
-/*
- cipher.h -- header file cipher.c
- Copyright (C) 2007-2009 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_CIPHER_H__
-#define __TINC_CIPHER_H__
-
-#include <gcrypt.h>
-
-#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
+++ /dev/null
-/*
- crypto.c -- Cryptographic miscellaneous functions and initialisation
- Copyright (C) 2007 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#include <gcrypt.h>
-
-#include "crypto.h"
-
-void crypto_init() {
-}
-
-void crypto_exit() {
-}
-
-void randomize(void *out, size_t outlen) {
- gcry_create_nonce(out, outlen);
-}
+++ /dev/null
-/*
- crypto.h -- header for crypto.c
- Copyright (C) 2007-2009 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 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
+++ /dev/null
-/*
- digest.c -- Digest handling
- Copyright (C) 2007-2012 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 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;
-}
+++ /dev/null
-/*
- digest.h -- header file digest.c
- Copyright (C) 2007-2009 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_DIGEST_H__
-#define __TINC_DIGEST_H__
-
-#include <gcrypt.h>
-
-#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
+++ /dev/null
-/*
- ecdh.c -- Diffie-Hellman key exchange handling
- Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 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) {
-}
+++ /dev/null
-/*
- ecdsa.c -- ECDSA key handling
- Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 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) {
-}
+++ /dev/null
-/*
- ecdsagen.c -- ECDSA key generation and export
- Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 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;
-}
+++ /dev/null
-/*
- prf.c -- Pseudo-Random Function for key material generation
- Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 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;
-}
+++ /dev/null
-/*
- rsa.c -- RSA key handling
- Copyright (C) 2007-2012 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#include <gcrypt.h>
-
-#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;
-}
+++ /dev/null
-/*
- rsa.h -- RSA key handling
- Copyright (C) 2007 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_RSA_H__
-#define __TINC_RSA_H__
-
-#include <gcrypt.h>
-
-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
+++ /dev/null
-/*
- rsagen.c -- RSA key generation and export
- Copyright (C) 2008-2012 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#include <gcrypt.h>
-
-#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;
-}
+++ /dev/null
-/*
- rsagen.h -- RSA key generation and export
- Copyright (C) 2008 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 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
#include "system.h"
#include "connection.h"
-#include "device.h"
#include "edge.h"
#include "graph.h"
#include "list.h"
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);
+++ /dev/null
-/*
- device.c -- Interaction with Linux ethertap and tun/tap device
- Copyright (C) 2001-2005 Ivo Timmermans,
- 2001-2013 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "../system.h"
-
-#include <linux/if_tun.h>
-#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,
-};
+++ /dev/null
-/*
- * 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"
+++ /dev/null
-/*
- device.c -- Interaction with Windows tap driver in a MinGW environment
- Copyright (C) 2002-2005 Ivo Timmermans,
- 2002-2013 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "../system.h"
-
-#include <windows.h>
-#include <winioctl.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"
-
-#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,
-};
+++ /dev/null
-/*
- device.c -- multicast socket
- Copyright (C) 2002-2005 Ivo Timmermans,
- 2002-2013 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 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,
-};
#include "utils.h"
#include "conf.h"
#include "connection.h"
-#include "device.h"
#include "graph.h"
#include "logger.h"
#include "meta.h"
#include "connection.h"
#include "crypto.h"
#include "digest.h"
-#include "device.h"
#include "ethernet.h"
#include "graph.h"
#include "logger.h"
memcpy(packet->data, mymac.x, ETH_ALEN);
n->out_packets++;
n->out_bytes += packet->len;
- devops.write(packet);
+ // TODO: send to application
return;
}
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);
-// }
-//}
#include "conf.h"
#include "connection.h"
#include "control.h"
-#include "device.h"
#include "digest.h"
#include "ecdsa.h"
#include "graph.h"
#include "xalloc.h"
char *myport;
-static io_t device_io;
-devops_t devops;
char *proxyhost;
char *proxyport;
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);
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();
for(int i = 0; i < 4; i++)
free(envp[i]);
- devops.close();
-
exit_control();
return;
#include "conf.h"
#include "connection.h"
#include "control.h"
-#include "device.h"
#include "edge.h"
#include "event.h"
#include "logger.h"
#include "control_common.h"
#include "cipher.h"
#include "crypto.h"
-#include "device.h"
#include "digest.h"
#include "ecdsa.h"
#include "edge.h"
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);
+++ /dev/null
-/*
- device.c -- raw socket
- Copyright (C) 2002-2005 Ivo Timmermans,
- 2002-2012 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#ifdef HAVE_NETPACKET_PACKET_H
-#include <netpacket/packet.h>
-#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
+++ /dev/null
-/*
- device.c -- Interaction with Solaris tun device
- Copyright (C) 2001-2005 Ivo Timmermans,
- 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
- 2001-2013 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-
-#include "../system.h"
-
-#include <sys/stropts.h>
-#include <sys/sockio.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"
-
-#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,
-};
#include "splay_tree.h"
#include "control_common.h"
-#include "device.h"
#include "hash.h"
#include "logger.h"
#include "names.h"
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) {
#include "conf.h"
#include "control.h"
#include "crypto.h"
-#include "device.h"
#include "logger.h"
#include "names.h"
#include "net.h"
}
#endif
- /* Setup sockets and open device. */
+ /* Setup sockets. */
if(!setup_network())
goto end;
+++ /dev/null
-/*
- device.c -- UML network socket
- Copyright (C) 2002-2005 Ivo Timmermans,
- 2002-2013 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#include <sys/un.h>
-
-#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,
-};
+++ /dev/null
-/*
- device.c -- VDE plug
- Copyright (C) 2013 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#include <libvdeplug_dyn.h>
-
-#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,
-};