package vtun tags 292582 + patch thanks Fair enough, my initial remarks were not entirely relevant, but the recent #581552 shows that 'vtund' is indeed broken in environments with activated IPv6.
Instead, this message makes a patch available that does
implement vtun to use IPv4 and IPv6 as transport medium.
This is verified to work with IPv4 and IPv6 as tunnel
content! Observe the distinction between 'transport medium'
and 'tunnel content'. The former was only possible using
IPv4, without my patching.
Attached is an NMU-diff against vtun_3.0.2-2. It works
correctly for i386 and amd64.
Mats Erik Andersson, fil. dr
2459 41E9 C420 3F6D F68B 2E88 F768 4541 F25B 5D41
Subscribes to: debian-mentors, debian-devel-games, debian-perl,
debian-ipv6, debian-qa
diff -u vtun-3.0.2/debian/rules vtun-3.0.2/debian/rules
--- vtun-3.0.2/debian/rules
+++ vtun-3.0.2/debian/rules
@@ -64,6 +64,8 @@
> $(CURDIR)/debian/tmp/vtund-server.conf
sed -n '/#.*CUT HERE.*Client config/,/#.*CUT HERE.*End/p' vtund.conf \
> $(CURDIR)/debian/tmp/vtund-client.conf
+ # Remove a policy violating directory
+ rm -Rf $(CURDIR)/debian/vtun/var/lock
# Build architecture-independent files here.
binary-indep: build install
diff -u vtun-3.0.2/debian/control vtun-3.0.2/debian/control
--- vtun-3.0.2/debian/control
+++ vtun-3.0.2/debian/control
@@ -10,7 +10,7 @@
Package: vtun
Architecture: any
-Depends: ${shlibs:Depends}
+Depends: ${shlibs:Depends}, ${misc:Depends}
Description: virtual tunnel over TCP/IP networks
VTun is the easiest way to create virtual tunnels over TCP/IP networks
with traffic shaping and compression.
diff -u vtun-3.0.2/debian/examples vtun-3.0.2/debian/examples
--- vtun-3.0.2/debian/examples
+++ vtun-3.0.2/debian/examples
@@ -4,0 +5,2 @@
+debian/vtund-ipv6-client.conf
+debian/vtund-ipv6-server.conf
diff -u vtun-3.0.2/debian/copyright vtun-3.0.2/debian/copyright
--- vtun-3.0.2/debian/copyright
+++ vtun-3.0.2/debian/copyright
@@ -24,7 +24,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
On Debian systems, the complete text of the GNU General
-Public License can be found in `/usr/share/common-licenses/GPL'.
+Public License can be found in `/usr/share/common-licenses/GPL-2'.
The Debian packaging is © 2006-2008, MartÃn Ferrari <[email protected]>
and is licensed under the GPL, see above.
diff -u vtun-3.0.2/debian/init.d vtun-3.0.2/debian/init.d
--- vtun-3.0.2/debian/init.d
+++ vtun-3.0.2/debian/init.d
@@ -17,6 +17,7 @@
DESC="virtual tunnel daemon"
CONFFILE=/etc/vtund.conf
PIDPREFIX=/var/run/vtund
+LOCKDIR=/var/lock/vtund
test -f $DAEMON || exit 0
test -f $CONFFILE || exit 0
@@ -28,6 +29,9 @@
. /etc/default/$NAME
fi
+# Create a lock directory if necessary
+[ -d $LOCKDIR ] || mkdir -p $LOCKDIR
+
case "$1" in
start)
if [ -f /etc/vtund-start.conf ]; then
diff -u vtun-3.0.2/debian/changelog vtun-3.0.2/debian/changelog
--- vtun-3.0.2/debian/changelog
+++ vtun-3.0.2/debian/changelog
@@ -1,3 +1,21 @@
+vtun (3.0.2-2.1) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * debian/control: Binary package needs ${misc:Depends}
+ * Format "1.0" registered:
+ + debian/source/format: New file.
+ * debian/copyright: Use a file system reference to 'GPL-2'.
+ * Support IPv6 transports:
+ + debian/patches/06-dual-family-transport.patch: New file.
+ * Two tested example configurations related to IPv6:
+ + debian/vtund-ipv6-client.conf: New file.
+ + debian/vtund-ipv6-server.conf: New file.
+ * [lintian] Error 'dir-or-file-in-var-lock':
+ + debian/rules: Remove 'debian/tmp/var/lock' in install target.
+ + debian/init.d: Create '/var/lock/vtund' at each run.
+
+ -- Mats Erik Andersson <[email protected]> Sat, 15 May 2010 16:51:52 +0200
+
vtun (3.0.2-2) unstable; urgency=low
* Acknowledging NMU. Thanks Aurélien.
diff -u vtun-3.0.2/debian/patches/series vtun-3.0.2/debian/patches/series
--- vtun-3.0.2/debian/patches/series
+++ vtun-3.0.2/debian/patches/series
@@ -6,0 +7 @@
+06-dual-family-transport.patch
only in patch2:
unchanged:
--- vtun-3.0.2.orig/debian/vtund-ipv6-server.conf
+++ vtun-3.0.2/debian/vtund-ipv6-server.conf
@@ -0,0 +1,56 @@
+#
+# Functionality verified by Mats Erik Andersson
+# for tunnels wrapping in IPv4 and in IPv6.
+#
+options {
+ port 5000;
+
+ syslog user;
+
+ ifconfig /sbin/ifconfig;
+ ip /sbin/ip;
+ route /sbin/route;
+ firewall /sbin/iptables;
+}
+
+default {
+ compress no;
+ encrypt no;
+ speed 0;
+ keepalive yes;
+ stat yes;
+}
+
+big-buck-bunny {
+ passwd blender;
+ type tun;
+ proto udp;
+ compress yes;
+ encrypt yes;
+
+ up {
+ ip "link set %d up multicast off mtu 1450";
+ ip "-4 addr add 10.3.0.1 peer 10.3.0.2 dev %d";
+ };
+
+ down {
+ ip "link set %d down";
+ };
+}
+
+big-buck-bunny-ipv6 {
+ passwd blender;
+ type tun;
+ proto udp;
+ compress yes;
+ encrypt yes;
+
+ up {
+ ip "-6 link set %d up multicast off mtu 1450";
+ ip "-6 addr add fc00:170:0:6a::1/112 dev %d";
+ };
+
+ down {
+ ip "-6 link set %d down";
+ };
+}
only in patch2:
unchanged:
--- vtun-3.0.2.orig/debian/vtund-ipv6-client.conf
+++ vtun-3.0.2/debian/vtund-ipv6-client.conf
@@ -0,0 +1,56 @@
+#
+# Functionality verified by Mats Erik Andersson
+# for tunnels wrapping in IPv4 and in IPv6.
+#
+options {
+ port 5000;
+
+ syslog user;
+
+ ifconfig /sbin/ifconfig;
+ ip /sbin/ip;
+ route /sbin/route;
+ firewall /sbin/iptables;
+}
+
+default {
+ compress no;
+ encrypt no;
+ speed 0;
+ keepalive yes;
+ stat yes;
+}
+
+big-buck-bunny {
+ passwd blender;
+ type tun;
+ proto udp;
+ compress yes;
+ encrypt yes;
+
+ up {
+ ip "link set %d up multicast off mtu 1450";
+ ip "-4 addr add 10.3.0.2 peer 10.3.0.1 dev %d";
+ };
+
+ down {
+ ip "link set %d down";
+ };
+}
+
+big-buck-bunny-ipv6 {
+ passwd blender;
+ type tun;
+ proto udp;
+ compress yes;
+ encrypt yes;
+
+ up {
+ ip "-6 link set %d up multicast off mtu 1450";
+ ip "-6 addr add fc00:170:0:6a::2/112 dev %d";
+ };
+
+ down {
+ ip "-6 link set %d down";
+ };
+}
only in patch2:
unchanged:
--- vtun-3.0.2.orig/debian/patches/06-dual-family-transport.patch
+++ vtun-3.0.2/debian/patches/06-dual-family-transport.patch
@@ -0,0 +1,623 @@
+Description: Enable transport in IPv4 and in IPv6 tunnels.
+ A migration to use 'struct sockaddr_storage' makes it possible
+ to establish a carrier tunnel using either IPv4 or IPv6.
+ .
+ Command line options '-4' and '-6' determines these.
+ The default is to use IPv4. Observe that either family
+ can be tunneled inside the tunnel, independently of
+ the wrapping address family.
+ .
+ It is by intention the carrier is of one kind for each
+ server instance. The options section can use 'ipv4' and
+ 'ipv6' to choose either.
+Author: Mats Erik Andersson <[email protected]>
+Forwarded: no
+Last-Update: 2010-05-15
+--- vtun-3.0.2.debian/vtun.h
++++ vtun-3.0.2/vtun.h
+@@ -23,6 +23,7 @@
+ #ifndef _VTUN_H
+ #define _VTUN_H
+
++#include <sys/socket.h> /* We need 'sa_family_t'. */
+ #include "llist.h"
+
+ /* Default VTUN port */
+@@ -207,6 +208,7 @@ struct vtun_opts {
+ char *fwall; /* Command to configure FireWall */
+ char *iproute; /* iproute command */
+
++ sa_family_t transport_af; /* Preferred address family for transport. */
+ char *svr_name; /* Server's host name */
+ char *svr_addr; /* Server's address (string) */
+ struct vtun_addr bind_addr; /* Server should listen on this address */
+--- vtun-3.0.2.debian/main.c
++++ vtun-3.0.2/main.c
+@@ -64,6 +64,7 @@ int main(int argc, char *argv[], char *e
+ vtun.persist = -1;
+ vtun.timeout = -1;
+ vtun.sslauth = -1;
++ vtun.transport_af = AF_INET;
+
+ /* Dup strings because parser will try to free them */
+ vtun.ppp = strdup("/usr/sbin/pppd");
+@@ -95,7 +96,7 @@ int main(int argc, char *argv[], char *e
+ /* Start logging to syslog and stderr */
+ openlog("vtund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
+
+- while( (opt=getopt(argc,argv,"misf:P:L:t:np")) != EOF ){
++ while( (opt=getopt(argc,argv,"misf:P:L:t:np46")) != EOF ){
+ switch(opt){
+ case 'm':
+ if (mlockall(MCL_CURRENT | MCL_FUTURE) < 0) {
+@@ -126,6 +127,12 @@ int main(int argc, char *argv[], char *e
+ case 't':
+ vtun.timeout = atoi(optarg);
+ break;
++ case '4':
++ vtun.transport_af = AF_INET;
++ break;
++ case '6':
++ vtun.transport_af = AF_INET6;
++ break;
+ default:
+ usage();
+ exit(1);
+--- vtun-3.0.2.debian/netlib.h
++++ vtun-3.0.2/netlib.h
+@@ -32,12 +32,14 @@
+ #include <netinet/in.h>
+ #endif
+
+-unsigned long getifaddr(char * ifname);
++int getifaddr(struct sockaddr_storage *addr, char * ifname, sa_family_t af);
+ int connect_t(int s, struct sockaddr *svr, time_t timeout);
+ int udp_session(struct vtun_host *host);
+
+-int local_addr(struct sockaddr_in *addr, struct vtun_host *host, int con);
+-int server_addr(struct sockaddr_in *addr, struct vtun_host *host);
+-int generic_addr(struct sockaddr_in *addr, struct vtun_addr *vaddr);
++int local_addr(struct sockaddr_storage *addr, struct vtun_host *host, int con);
++int server_addr(struct sockaddr_storage *addr, struct vtun_host *host);
++int generic_addr(struct sockaddr_storage *addr, struct vtun_addr *vaddr);
++in_port_t get_port(struct sockaddr_storage *addr);
++void set_port(struct sockaddr_storage *addr, in_port_t port);
+
+ #endif /* _VTUN_NETDEV_H */
+--- vtun-3.0.2.debian/netlib.c
++++ vtun-3.0.2/netlib.c
+@@ -38,6 +38,7 @@
+ #include <sys/ioctl.h>
+ #include <net/if.h>
+ #include <errno.h>
++#include <ifaddrs.h>
+
+ #ifdef HAVE_SYS_SOCKIO_H
+ #include <sys/sockio.h>
+@@ -81,7 +82,7 @@ int connect_t(int s, struct sockaddr *sv
+ #if defined(VTUN_SOCKS) && VTUN_SOCKS == 2
+ /* Some SOCKS implementations don't support
+ * non blocking connect */
+- return connect(s,svr,sizeof(struct sockaddr));
++ return connect(s,svr,sizeof(struct sockaddr_storage));
+ #else
+ int sock_flags;
+ fd_set fdset;
+@@ -93,7 +94,7 @@ int connect_t(int s, struct sockaddr *sv
+ if( fcntl(s,F_SETFL,O_NONBLOCK) < 0 )
+ return -1;
+
+- if( connect(s,svr,sizeof(struct sockaddr)) < 0 && errno != EINPROGRESS)
++ if( connect(s,svr,sizeof(struct sockaddr_storage)) < 0 && errno != EINPROGRESS)
+ return -1;
+
+ FD_ZERO(&fdset);
+@@ -114,28 +115,78 @@ int connect_t(int s, struct sockaddr *sv
+ #endif
+ }
+
++/* Get port number, independently of address family. */
++in_port_t get_port(struct sockaddr_storage *addr)
++{
++ switch (addr->ss_family) {
++ case AF_INET6:
++ return ntohs(((struct sockaddr_in6 *) addr)->sin6_port);
++ break;
++ case AF_INET:
++ return ntohs(((struct sockaddr_in *) addr)->sin_port);
++ break;
++ default:
++ return 0;
++ }
++} /* get_port(struct sockaddr_storage *) */
++
++/* Set port number, independently of address family. */
++void set_port(struct sockaddr_storage *addr, in_port_t port)
++{
++ switch (addr->ss_family) {
++ case AF_INET6:
++ ((struct sockaddr_in6 *) addr)->sin6_port = htons(port);
++ break;
++ case AF_INET:
++ ((struct sockaddr_in *) addr)->sin_port = htons(port);
++ default:
++ break;
++ }
++} /* set_port(struct sockaddr_storage *, in_port_t) */
++
+ /* Get interface address */
+-unsigned long getifaddr(char * ifname)
++int getifaddr(struct sockaddr_storage *addr, char * ifname, sa_family_t af)
+ {
+- struct sockaddr_in addr;
+- struct ifreq ifr;
+- int s;
++ struct ifaddrs *ifas, *ifa;
+
+- if( (s = socket(AF_INET, SOCK_DGRAM, 0)) == -1 )
++ if( getifaddrs(&ifas) < 0 )
+ return -1;
+
+- strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)-1);
+- ifr.ifr_name[sizeof(ifr.ifr_name)-1]='\0';
++ for (ifa = ifas; ifa; ifa = ifa->ifa_next) {
++ if( ifa->ifa_addr->sa_family != af ||
++ strcmp(ifname, ifa->ifa_name) )
++ continue;
++
++ /* Correct address family and interface name!
++ * Locate a useful candidate. */
++
++ /* For IPv4, the first address works. */
++ if( (ifa->ifa_addr->sa_family == AF_INET) &&
++ (ifa->ifa_flags & IFF_UP) )
++ break; /* Good address. */
++
++ /* IPv6 needs some obvious exceptions. */
++ if( ifa->ifa_addr->sa_family == AF_INET6 ) {
++ if( IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr)
++ || IN6_IS_ADDR_SITELOCAL(&((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr) )
++ continue;
++ else
++ /* Successful search at this point, which
++ * only standard IPv6 can reach. */
++ break;
++ }
++ }
+
+- if( ioctl(s, SIOCGIFADDR, &ifr) < 0 ){
+- close(s);
++ if( ifa == NULL ) {
++ freeifaddrs(ifas);
+ return -1;
+ }
+- close(s);
+
+- addr = *((struct sockaddr_in *) &ifr.ifr_addr);
++ /* Copy the found address. */
++ memcpy(addr, ifa->ifa_addr, sizeof(*addr));
++ freeifaddrs(ifas);
+
+- return addr.sin_addr.s_addr;
++ return 0;
+ }
+
+ /*
+@@ -144,12 +195,15 @@ unsigned long getifaddr(char * ifname)
+ */
+ int udp_session(struct vtun_host *host)
+ {
+- struct sockaddr_in saddr;
++ struct sockaddr_storage saddr;
+ short port;
+ int s;
+ socklen_t opt;
+
+- if( (s=socket(AF_INET,SOCK_DGRAM,0))== -1 ){
++ /* Set local address and port */
++ local_addr(&saddr, host, 1);
++
++ if( (s=socket(saddr.ss_family,SOCK_DGRAM,0))== -1 ){
+ vtun_syslog(LOG_ERR,"Can't create socket");
+ return -1;
+ }
+@@ -157,8 +211,6 @@ int udp_session(struct vtun_host *host)
+ opt=1;
+ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+
+- /* Set local address and port */
+- local_addr(&saddr, host, 1);
+ if( bind(s,(struct sockaddr *)&saddr,sizeof(saddr)) ){
+ vtun_syslog(LOG_ERR,"Can't bind to the socket");
+ return -1;
+@@ -171,7 +223,7 @@ int udp_session(struct vtun_host *host)
+ }
+
+ /* Write port of the new UDP socket */
+- port = saddr.sin_port;
++ port = get_port(&saddr);
+ if( write_n(host->rmt_fd,(char *)&port,sizeof(short)) < 0 ){
+ vtun_syslog(LOG_ERR,"Can't write port number");
+ return -1;
+@@ -190,7 +242,7 @@ int udp_session(struct vtun_host *host)
+ return -1;
+ }
+
+- saddr.sin_port = port;
++ set_port(&saddr, port);
+ if( connect(s,(struct sockaddr *)&saddr,sizeof(saddr)) ){
+ vtun_syslog(LOG_ERR,"Can't connect socket");
+ return -1;
+@@ -206,85 +258,102 @@ int udp_session(struct vtun_host *host)
+ }
+
+ /* Set local address */
+-int local_addr(struct sockaddr_in *addr, struct vtun_host *host, int con)
++int local_addr(struct sockaddr_storage *addr, struct vtun_host *host, int con)
+ {
+ socklen_t opt;
++ char *ip = (char *) calloc(INET6_ADDRSTRLEN, sizeof(char));
++
++ memset(addr, '\0', sizeof(*addr));
+
+ if( con ){
+ /* Use address of the already connected socket. */
+- opt = sizeof(struct sockaddr_in);
++ opt = sizeof(*addr);
+ if( getsockname(host->rmt_fd, (struct sockaddr *)addr, &opt) < 0 ){
+ vtun_syslog(LOG_ERR,"Can't get local socket address");
+ return -1;
+ }
+ } else {
++ addr->ss_family = vtun.transport_af;
+ if (generic_addr(addr, &host->src_addr) < 0)
+ return -1;
+ }
+
+- host->sopt.laddr = strdup(inet_ntoa(addr->sin_addr));
++ getnameinfo((struct sockaddr *) addr, sizeof(*addr),
++ ip, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
++ host->sopt.laddr = ip;
+
+ return 0;
+ }
+
+-int server_addr(struct sockaddr_in *addr, struct vtun_host *host)
++int server_addr(struct sockaddr_storage *addr, struct vtun_host *host)
+ {
+- struct hostent * hent;
++ struct addrinfo hints, *aiptr;
++ char *ip, portstr[12];
++
++ ip = (char *) calloc(INET6_ADDRSTRLEN, sizeof(char));
+
+- memset(addr,0,sizeof(struct sockaddr_in));
+- addr->sin_family = AF_INET;
+- addr->sin_port = htons(vtun.bind_addr.port);
++ memset(addr, '\0', sizeof(*addr));
++
++ memset(&hints, '\0', sizeof(hints));
++ hints.ai_family = vtun.transport_af;
++ hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
++
++ snprintf(portstr, sizeof(portstr), "%u", vtun.bind_addr.port);
+
+ /* Lookup server's IP address.
+ * We do it on every reconnect because server's IP
+ * address can be dynamic.
+ */
+- if( !(hent = gethostbyname(vtun.svr_name)) ){
+- vtun_syslog(LOG_ERR, "Can't resolv server address: %s", vtun.svr_name);
+- return -1;
++ if (getaddrinfo(vtun.svr_name, portstr, &hints, &aiptr)) {
++ vtun_syslog(LOG_ERR, "Can't resolv server address: %s", vtun.svr_name);
++ return -1;
+ }
+- addr->sin_addr.s_addr = *(unsigned long *)hent->h_addr;
+
+- host->sopt.raddr = strdup(inet_ntoa(addr->sin_addr));
++ memcpy(addr, aiptr->ai_addr, aiptr->ai_addrlen);
++ freeaddrinfo(aiptr);
++ getnameinfo((struct sockaddr *) addr, sizeof(*addr),
++ ip, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
++ host->sopt.raddr = ip;
+ host->sopt.rport = vtun.bind_addr.port;
+
+ return 0;
+ }
+
+ /* Set address by interface name, ip address or hostname */
+-int generic_addr(struct sockaddr_in *addr, struct vtun_addr *vaddr)
++int generic_addr(struct sockaddr_storage *addr, struct vtun_addr *vaddr)
+ {
+- struct hostent *hent;
+- memset(addr, 0, sizeof(struct sockaddr_in));
+-
+- addr->sin_family = AF_INET;
++ sa_family_t use_af = addr->ss_family;
++ struct addrinfo hints, *aiptr;
++
++ memset(addr, '\0', sizeof(*addr)); /* Implicitly setting INADDR_ANY. */
+
+ switch (vaddr->type) {
+ case VTUN_ADDR_IFACE:
+- if (!(addr->sin_addr.s_addr =
+- getifaddr(vaddr->name))) {
+- vtun_syslog(LOG_ERR,
+- "Can't get address of interface %s",
+- vaddr->name);
+- return -1;
+- }
+- break;
++ if (getifaddr(addr, vaddr->name, use_af)) {
++ vtun_syslog(LOG_ERR, "Can't get address of interface %s", vaddr->name);
++ return -1;
++ }
++ break;
+ case VTUN_ADDR_NAME:
+- if (!(hent = gethostbyname(vaddr->name))) {
+- vtun_syslog(LOG_ERR,
+- "Can't resolv local address %s",
+- vaddr->name);
+- return -1;
+- }
+- addr->sin_addr.s_addr = *(unsigned long *) hent->h_addr;
+- break;
+- default:
+- addr->sin_addr.s_addr = INADDR_ANY;
+- break;
++ memset(&hints, '\0', sizeof(hints));
++ hints.ai_family = use_af;
++ hints.ai_flags = AI_ADDRCONFIG;
++
++ if (getaddrinfo(vaddr->name, NULL, &hints, &aiptr)) {
++ vtun_syslog(LOG_ERR, "Can't resolv local address %s", vaddr->name);
++ return -1;
++ }
++ memcpy(addr, aiptr->ai_addr, aiptr->ai_addrlen);
++ freeaddrinfo(aiptr);
++ break;
++ default:
++ /* INADDR_ANY has already been implicitly set, when erasing. */
++ addr->ss_family = use_af;
++ break;
+ }
+
+ if (vaddr->port)
+- addr->sin_port = htons(vaddr->port);
++ set_port(addr, vaddr->port);
+
+ return 0;
+ }
+--- vtun-3.0.2.debian/client.c
++++ vtun-3.0.2/client.c
+@@ -55,7 +55,7 @@ static void sig_term(int sig)
+
+ void client(struct vtun_host *host)
+ {
+- struct sockaddr_in my_addr,svr_addr;
++ struct sockaddr_storage my_addr,svr_addr;
+ struct sigaction sa;
+ int s, opt, reconnect;
+
+@@ -101,7 +101,7 @@ void client(struct vtun_host *host)
+ * we want to connect, since STREAM sockets
+ * can be successfully connected only once.
+ */
+- if( (s = socket(AF_INET,SOCK_STREAM,0))==-1 ){
++ if( (s = socket(my_addr.ss_family,SOCK_STREAM,0))==-1 ){
+ vtun_syslog(LOG_ERR,"Can't create socket. %s(%d)",
+ strerror(errno), errno);
+ continue;
+@@ -136,9 +136,7 @@ void client(struct vtun_host *host)
+ vtun_syslog(LOG_INFO,"Session %s[%s] opened",host->host,vtun.svr_name);
+
+ host->rmt_fd = s;
+-
+- /* Start the tunnel */
+- client_term = tunnel(host);
++/* Start the tunnel */ client_term = tunnel(host);
+
+ vtun_syslog(LOG_INFO,"Session %s[%s] closed",host->host,vtun.svr_name);
+ } else {
+--- vtun-3.0.2.debian/server.c
++++ vtun-3.0.2/server.c
+@@ -30,6 +30,7 @@
+ #include <fcntl.h>
+ #include <syslog.h>
+ #include <sys/socket.h>
++#include <netdb.h>
+
+ #ifdef HAVE_NETINET_IN_H
+ #include <netinet/in.h>
+@@ -60,24 +61,30 @@ static void sig_term(int sig)
+
+ void connection(int sock)
+ {
+- struct sockaddr_in my_addr, cl_addr;
++ struct sockaddr_storage my_addr, cl_addr;
+ struct vtun_host *host;
+ struct sigaction sa;
+- char *ip;
++ char *cl_ip, *my_ip;
+ socklen_t opt;
+
+- opt = sizeof(struct sockaddr_in);
++ cl_ip = calloc(INET6_ADDRSTRLEN, sizeof(char));
++ my_ip = calloc(INET6_ADDRSTRLEN, sizeof(char));
++
++ opt = sizeof(cl_addr);
+ if( getpeername(sock, (struct sockaddr *) &cl_addr, &opt) ){
+ vtun_syslog(LOG_ERR, "Can't get peer name");
+ exit(1);
+ }
+- opt = sizeof(struct sockaddr_in);
++ opt = sizeof(my_addr);
+ if( getsockname(sock, (struct sockaddr *) &my_addr, &opt) < 0 ){
+ vtun_syslog(LOG_ERR, "Can't get local socket address");
+ exit(1);
+ }
+
+- ip = strdup(inet_ntoa(cl_addr.sin_addr));
++ getnameinfo((struct sockaddr *) &cl_addr, sizeof(cl_addr),
++ cl_ip, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
++ getnameinfo((struct sockaddr *) &my_addr, sizeof(my_addr),
++ my_ip, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
+
+ io_init();
+
+@@ -86,14 +93,14 @@ void connection(int sock)
+ sa.sa_flags=SA_NOCLDWAIT;;
+ sigaction(SIGHUP,&sa,NULL);
+
+- vtun_syslog(LOG_INFO,"Session %s[%s:%d] opened", host->host, ip,
+- ntohs(cl_addr.sin_port) );
++ vtun_syslog(LOG_INFO,"Session %s[%s:%d] opened", host->host, cl_ip,
++ get_port(&cl_addr) );
+ host->rmt_fd = sock;
+
+- host->sopt.laddr = strdup(inet_ntoa(my_addr.sin_addr));
++ host->sopt.laddr = my_ip;
+ host->sopt.lport = vtun.bind_addr.port;
+- host->sopt.raddr = strdup(ip);
+- host->sopt.rport = ntohs(cl_addr.sin_port);
++ host->sopt.raddr = strdup(cl_ip);
++ host->sopt.rport = get_port(&cl_addr);
+
+ /* Start tunnel */
+ tunnel(host);
+@@ -103,8 +110,8 @@ void connection(int sock)
+ /* Unlock host. (locked in auth_server) */
+ unlock_host(host);
+ } else {
+- vtun_syslog(LOG_INFO,"Denied connection from %s:%d", ip,
+- ntohs(cl_addr.sin_port) );
++ vtun_syslog(LOG_INFO,"Denied connection from %s:%d", cl_ip,
++ get_port(&cl_addr) );
+ }
+ close(sock);
+
+@@ -114,21 +121,22 @@ void connection(int sock)
+ void listener(void)
+ {
+ struct sigaction sa;
+- struct sockaddr_in my_addr, cl_addr;
++ struct sockaddr_storage my_addr, cl_addr;
+ int s, s1;
+ socklen_t opt;
+
+ memset(&my_addr, 0, sizeof(my_addr));
+- my_addr.sin_family = AF_INET;
+
+ /* Set listen address */
++ my_addr.ss_family = vtun.transport_af;
++
+ if( generic_addr(&my_addr, &vtun.bind_addr) < 0)
+ {
+ vtun_syslog(LOG_ERR, "Can't fill in listen socket");
+ exit(1);
+ }
+
+- if( (s=socket(AF_INET,SOCK_STREAM,0))== -1 ){
++ if( (s=socket(my_addr.ss_family,SOCK_STREAM,0))== -1 ){
+ vtun_syslog(LOG_ERR,"Can't create socket");
+ exit(1);
+ }
+@@ -187,7 +195,7 @@ void server(int sock)
+ sigaction(SIGUSR1,&sa,NULL);
+
+ vtun_syslog(LOG_INFO,"VTUN server ver %s (%s)", VTUN_VER,
+- vtun.svr_type == VTUN_INETD ? "inetd" : "stand" );
++ vtun.svr_type == VTUN_INETD ? "inetd" : "standalone" );
+
+ switch( vtun.svr_type ){
+ case VTUN_STAND_ALONE:
+--- vtun-3.0.2.debian/vtund.8
++++ vtun-3.0.2/vtund.8
+@@ -13,6 +13,9 @@ vtund \- VTun(Virtual Tunnel) daemon.
+ <
+ .I -s
+ >
++{
++.IR -4 | -6
++}
+ [
+ .I -i
+ ]
+@@ -27,6 +30,9 @@ vtund \- VTun(Virtual Tunnel) daemon.
+ ]
+ .LP
+ .B vtund
++{
++.IR -4 | -6
++}
+ [
+ .I -f file
+ ]
+@@ -68,6 +74,14 @@ to any kernel parts.
+
+ .SH OPTIONS
+ .TP
++.I -4
++Use \fBIPv4\fR for transport, and for listening socket. This is the default choice.
++Any of the addressing modes IPv4 or IPv6 can passed inside the tunnel.
++The decision to use either is made by the \fIifconfig\fR and \fIip\fR commands.
++.TP
++.I -6
++Choose \fBIPv6\fR as transport layer, and server listening socket.
++.TP
+ .I -f file
+ Read config information from the
+ .I file
+--- vtun-3.0.2.debian/cfg_kwords.h
++++ vtun-3.0.2/cfg_kwords.h
+@@ -32,6 +32,8 @@ struct kword cfg_keyword[] = {
+ { "default", K_DEFAULT },
+ { "up", K_UP },
+ { "down", K_DOWN },
++ { "ipv4", K_IPV4 },
++ { "ipv6", K_IPV6 },
+ { "port", K_PORT },
+ { "srcaddr", K_SRCADDR },
+ { "addr", K_ADDR },
+--- vtun-3.0.2.debian/cfg_file.y
++++ vtun-3.0.2/cfg_file.y
+@@ -73,7 +73,7 @@ int yyerror(char *s);
+
+ %token K_OPTIONS K_DEFAULT K_PORT K_BINDADDR K_PERSIST K_TIMEOUT
+ %token K_PASSWD K_PROG K_PPP K_SPEED K_IFCFG K_FWALL K_ROUTE K_DEVICE
+-%token K_MULTI K_SRCADDR K_IFACE K_ADDR
++%token K_MULTI K_SRCADDR K_IFACE K_ADDR K_IPV4 K_IPV6
+ %token K_TYPE K_PROT K_COMPRESS K_ENCRYPT K_KALIVE K_STAT K_SSLAUTH
+ %token K_UP K_DOWN K_SYSLOG K_IPROUTE
+
+@@ -190,6 +190,14 @@ option: '\n'
+
+ | K_SYSLOG syslog_opt
+
++ | K_IPV4 {
++ vtun.transport_af = AF_INET;
++ }
++
++ | K_IPV6 {
++ vtun.transport_af = AF_INET6;
++ }
++
+ | K_ERROR {
+ cfg_error("Unknown option '%s'",$1);
+ YYABORT;
+--- vtun-3.0.2.debian/vtund.conf.5
++++ vtun-3.0.2/vtund.conf.5
+@@ -51,6 +51,12 @@ server type. \fBvtund\fR(8) can operate
+ mode (\fBstand\fR), that is the default, or be invoked from
+ .BR inetd (8).
+
++.IP \fBipv4\fR
++use IPv4 as transport medium. This is the default. Inside the tunnel other types are of course usable.
++
++.IP \fBipv6\fR
++use IPv6 as transport medium.
++
+ .IP \fBport\ \fIportnumber\fR
+ server port number to listen on or connect to.
+ By default, \fBvtund\fR(8) uses port 5000.
only in patch2:
unchanged:
--- vtun-3.0.2.orig/debian/source/format
+++ vtun-3.0.2/debian/source/format
@@ -0,0 +1 @@
+1.0
signature.asc
Description: Digital signature

