summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatrio2015-06-15 14:22:46 +0300
committerNatrio2015-06-15 14:22:46 +0300
commit8ef8f2a02f4bcb9b5a1334c2f7cc24193e0d95f4 (patch)
tree4ce578cd61b7b3ba864e0283e4087a1b06442fb2
downloadaur-8ef8f2a02f4bcb9b5a1334c2f7cc24193e0d95f4.tar.gz
Initial import
-rw-r--r--.SRCINFO55
-rw-r--r--00-sslauth.patch272
-rw-r--r--01-pidfile.patch89
-rw-r--r--02-dumpfile.patch20
-rw-r--r--03-signedness-warnings.patch217
-rw-r--r--04-implicit-pointer-conversions.patch122
-rw-r--r--05-unix98pty.patch81
-rw-r--r--06-ipv6.patch73
-rw-r--r--07-dual-family-transport.patch635
-rw-r--r--PKGBUILD67
-rw-r--r--README.tun-cfg105
-rw-r--r--android-dev.patch12
-rw-r--r--cvs-2013.patch1240
-rw-r--r--openlog.patch11
-rw-r--r--tun-cat.c288
-rwxr-xr-xtun-cfg466
-rw-r--r--tun-cfg.conf8
-rw-r--r--vtun.install13
-rw-r--r--vtund-ipv6-client.conf56
-rw-r--r--vtund-ipv6-server.conf56
20 files changed, 3886 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..098ea6f5a348
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,55 @@
+pkgbase = vtun
+ pkgdesc = The easiest way to create Virtual Tunnels over TCP/IP networks with traffic shaping, compression, encryption and IPv6 support.
+ pkgver = 3.0.3.2013.d
+ pkgrel = 5
+ url = http://vtun.sourceforge.net/
+ install = vtun.install
+ arch = i686
+ arch = x86_64
+ arch = armv7h
+ arch = armv6h
+ license = GPL
+ depends = openssl
+ depends = zlib
+ depends = lzo2
+ backup = etc/vtund.conf
+ backup = etc/tun-cfg.conf
+ source = http://downloads.sourceforge.net/project/vtun/vtun/3.0.3/vtun-3.0.3.tar.gz
+ source = cvs-2013.patch
+ source = openlog.patch
+ source = 00-sslauth.patch
+ source = 01-pidfile.patch
+ source = 02-dumpfile.patch
+ source = 03-signedness-warnings.patch
+ source = 04-implicit-pointer-conversions.patch
+ source = 05-unix98pty.patch
+ source = 06-ipv6.patch
+ source = 07-dual-family-transport.patch
+ source = vtund-ipv6-client.conf
+ source = vtund-ipv6-server.conf
+ source = android-dev.patch
+ source = tun-cat.c
+ source = tun-cfg
+ source = tun-cfg.conf
+ source = README.tun-cfg
+ sha512sums = 5fa789d08b556f97492b89515a89c2322c4b0a8fa95bd1035f5ed19061b3654a6a36a9911792096ac872ae9ae5451848cab87d0343dc0ffc064affea1f7d0d54
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+ sha512sums = SKIP
+
+pkgname = vtun
+
diff --git a/00-sslauth.patch b/00-sslauth.patch
new file mode 100644
index 000000000000..920bb8fd09ba
--- /dev/null
+++ b/00-sslauth.patch
@@ -0,0 +1,272 @@
+00-sslauth.patch by Artur R. Czechowski <arturcz@hell.pl>
+http://sourceforge.net/support/tracker.php?aid=1744566
+
+ This patch allows ssl-enabled clients to connect to
+ non-ssl-enabled servers and vice versa. It also enables use
+ of /dev/random based encryption instead of C's built-in
+ (and rather weak) rand() function.
+
+Index: vtun-3.0.3/auth.c
+===================================================================
+--- vtun-3.0.3.orig/auth.c 2012-10-07 20:22:53.425321705 +0200
++++ vtun-3.0.3/auth.c 2012-10-07 20:41:25.545351485 +0200
+@@ -23,6 +23,10 @@
+ /*
+ * Challenge based authentication.
+ * Thanx to Chris Todd<christ@insynq.com> for the good idea.
++ *
++ * Artur R. Czechowski <arturcz@hell.pl>, 02/17/2002
++ * Add support for connectin ssl to non-ssl vtuns (sslauth option)
++ * Use /dev/random in non-ssl gen_chal (if possible)
+ */
+
+ #include "config.h"
+@@ -55,34 +59,57 @@
+ #include "lock.h"
+ #include "auth.h"
+
+-/* Encryption and Decryption of the challenge key */
+ #ifdef HAVE_SSL
+
+ #include <openssl/md5.h>
+ #include <openssl/blowfish.h>
+ #include <openssl/rand.h>
+
++#endif /* HAVE_SSL */
++
++/* Okay, start the "blue-wire" non-ssl auth patch stuff */
++static void nonssl_encrypt_chal(char *chal, char *pwd)
++{
++ char *xor_msk = pwd;
++ register int i, xor_len = strlen(xor_msk);
++
++ syslog(LOG_INFO, "Use nonSSL-aware challenge/response");
++ for(i=0; i < VTUN_CHAL_SIZE; i++)
++ chal[i] ^= xor_msk[i%xor_len];
++}
++
++static inline void nonssl_decrypt_chal(char *chal, char *pwd)
++{
++ nonssl_encrypt_chal(chal, pwd);
++}
++/* Mostly ended here, other than a couple replaced #ifdefs */
++
++/* Encryption and Decryption of the challenge-key */
++#ifdef HAVE_SSL
++
+ static void gen_chal(char *buf)
+ {
+ RAND_bytes(buf, VTUN_CHAL_SIZE);
+ }
+
+-static void encrypt_chal(char *chal, char *pwd)
++static void ssl_encrypt_chal(char *chal, char *pwd)
+ {
+ register int i;
+ BF_KEY key;
+
++ syslog(LOG_INFO, "Use SSL-aware challenge/response");
+ BF_set_key(&key, 16, MD5(pwd,strlen(pwd),NULL));
+
+ for(i=0; i < VTUN_CHAL_SIZE; i += 8 )
+ BF_ecb_encrypt(chal + i, chal + i, &key, BF_ENCRYPT);
+ }
+
+-static void decrypt_chal(char *chal, char *pwd)
++static void ssl_decrypt_chal(char *chal, char *pwd)
+ {
+ register int i;
+ BF_KEY key;
+
++ syslog(LOG_INFO, "Use SSL-aware challenge/response");
+ BF_set_key(&key, 16, MD5(pwd,strlen(pwd),NULL));
+
+ for(i=0; i < VTUN_CHAL_SIZE; i += 8 )
+@@ -91,30 +118,43 @@
+
+ #else /* HAVE_SSL */
+
+-static void encrypt_chal(char *chal, char *pwd)
+-{
+- char * xor_msk = pwd;
+- register int i, xor_len = strlen(xor_msk);
+-
+- for(i=0; i < VTUN_CHAL_SIZE; i++)
+- chal[i] ^= xor_msk[i%xor_len];
+-}
+-
+-static void inline decrypt_chal(char *chal, char *pwd)
+-{
+- encrypt_chal(chal, pwd);
+-}
+-
+ /* Generate PSEUDO random challenge key. */
+ static void gen_chal(char *buf)
+ {
+ register int i;
+-
+- srand(time(NULL));
++ unsigned int seed;
++ char *pseed;
++ int fd,cnt,len;
++
++ if((fd=open("/dev/random",O_RDONLY))!=-1) {
++ pseed=(char *)&seed;
++ len=cnt=sizeof(seed);
++ while(cnt>0) {
++ cnt=read(fd,pseed,len);
++ len=len-cnt;
++ pseed=pseed+cnt;
++ }
++ } else {
++ seed=time(NULL);
++ }
++ srand(seed);
+
+ for(i=0; i < VTUN_CHAL_SIZE; i++)
+ buf[i] = (unsigned int)(255.0 * rand()/RAND_MAX);
+ }
++
++static void ssl_encrypt_chal(char *chal, char *pwd)
++{
++ syslog(LOG_ERR,"Cannot use `sslauth yes' without SSL support - fallback to `sslauth no'");
++ nonssl_encrypt_chal(chal,pwd);
++}
++
++static void ssl_decrypt_chal(char *chal, char *pwd)
++{
++ syslog(LOG_ERR,"Cannot use `sslauth yes' without SSL support - fallback to `sslauth no'");
++ nonssl_decrypt_chal(chal,pwd);
++}
++
+ #endif /* HAVE_SSL */
+
+ /*
+@@ -358,7 +398,11 @@
+ if( !(h = find_host(host)) )
+ break;
+
+- decrypt_chal(chal_res, h->passwd);
++ if (h->sslauth) {
++ ssl_decrypt_chal(chal_res, h->passwd);
++ } else {
++ nonssl_decrypt_chal(chal_res, h->passwd);
++ }
+
+ if( !memcmp(chal_req, chal_res, VTUN_CHAL_SIZE) ){
+ /* Auth successeful. */
+@@ -410,7 +454,11 @@
+ if( !strncmp(buf,"OK",2) && cs2cl(buf,chal)){
+ stage = ST_CHAL;
+
+- encrypt_chal(chal,host->passwd);
++ if (host->sslauth) {
++ ssl_encrypt_chal(chal,host->passwd);
++ } else {
++ nonssl_encrypt_chal(chal,host->passwd);
++ }
+ print_p(fd,"CHAL: %s\n", cl2cs(chal));
+
+ continue;
+Index: vtun-3.0.3/cfg_file.y
+===================================================================
+--- vtun-3.0.3.orig/cfg_file.y 2012-10-07 20:22:53.425321705 +0200
++++ vtun-3.0.3/cfg_file.y 2012-10-07 20:41:25.545351485 +0200
+@@ -74,7 +74,7 @@
+ %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_TYPE K_PROT K_NAT_HACK K_COMPRESS K_ENCRYPT K_KALIVE K_STAT
++%token K_TYPE K_PROT K_NAT_HACK K_COMPRESS K_ENCRYPT K_KALIVE K_STAT K_SSLAUTH
+ %token K_UP K_DOWN K_SYSLOG K_IPROUTE
+
+ %token <str> K_HOST K_ERROR
+@@ -284,6 +284,13 @@
+ }
+ compress
+
++ | K_SSLAUTH NUM {
++ parse_host->sslauth = $2;
++
++ if(vtun.sslauth == -1)
++ vtun.sslauth = $2;
++ }
++
+ | K_ENCRYPT NUM {
+ if( $2 ){
+ parse_host->flags |= VTUN_ENCRYPT;
+Index: vtun-3.0.3/cfg_kwords.h
+===================================================================
+--- vtun-3.0.3.orig/cfg_kwords.h 2012-10-07 20:22:53.425321705 +0200
++++ vtun-3.0.3/cfg_kwords.h 2012-10-07 20:41:25.545351485 +0200
+@@ -37,6 +37,7 @@
+ { "addr", K_ADDR },
+ { "iface", K_IFACE },
+ { "bindaddr", K_BINDADDR },
++ { "sslauth", K_SSLAUTH },
+ { "persist", K_PERSIST },
+ { "multi", K_MULTI },
+ { "iface", K_IFACE },
+Index: vtun-3.0.3/main.c
+===================================================================
+--- vtun-3.0.3.orig/main.c 2012-10-07 20:22:53.425321705 +0200
++++ vtun-3.0.3/main.c 2012-10-07 20:41:25.549351485 +0200
+@@ -66,6 +66,7 @@
+ vtun.cfg_file = VTUN_CONFIG_FILE;
+ vtun.persist = -1;
+ vtun.timeout = -1;
++ vtun.sslauth = -1;
+
+ /* Dup strings because parser will try to free them */
+ vtun.ppp = strdup("/usr/sbin/pppd");
+@@ -88,6 +89,11 @@
+ default_host.ka_interval = 30;
+ default_host.ka_maxfail = 4;
+ default_host.loc_fd = default_host.rmt_fd = -1;
++#ifdef HAVE_SSL
++ default_host.sslauth = 1;
++#else /* HAVE_SSL */
++ default_host.sslauth = 0;
++#endif /* HAVE_SSL */
+
+ /* Start logging to syslog and stderr */
+ openlog("vtund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
+@@ -166,6 +172,16 @@
+ vtun.persist = 0;
+ if(vtun.timeout == -1)
+ vtun.timeout = VTUN_TIMEOUT;
++ /*
++ * Want to save behaviour from older version: stronger authentication
++ * if compiled with --enable-ssl, weaker otherwise
++ */
++ if(vtun.sslauth == -1)
++#ifdef HAVE_SSL
++ vtun.sslauth = 1;
++#else /* HAVE_SSL */
++ vtun.sslauth = 0;
++#endif /* HAVE_SSL */
+
+ switch( vtun.svr_type ){
+ case -1:
+Index: vtun-3.0.3/vtun.h
+===================================================================
+--- vtun-3.0.3.orig/vtun.h 2012-10-07 20:22:53.425321705 +0200
++++ vtun-3.0.3/vtun.h 2012-10-07 20:41:25.549351485 +0200
+@@ -99,6 +99,9 @@
+ int rmt_fd;
+ int loc_fd;
+
++ /* SSL strong auth */
++ int sslauth;
++
+ /* Persist mode */
+ int persist;
+
+@@ -204,6 +207,7 @@
+ struct vtun_opts {
+ int timeout;
+ int persist;
++ int sslauth;
+
+ char *cfg_file;
+
diff --git a/01-pidfile.patch b/01-pidfile.patch
new file mode 100644
index 000000000000..073e35ae892e
--- /dev/null
+++ b/01-pidfile.patch
@@ -0,0 +1,89 @@
+01-pidfile.patch by Morgon Kanter <morgon@surgo.net> and Martín Ferrari
+http://sourceforge.net/support/tracker.php?aid=762822
+
+<martin.ferrari@gmail.com>
+ This patch changes main.c so clients write their PID-file as
+ well as servers. It also allows a tag to be added to the filename.
+
+diff -pur 1/Makefile.in 2/Makefile.in
+--- 1/Makefile.in 2013-07-08 00:36:44.000000000 +0400
++++ 2/Makefile.in 2014-11-02 12:41:42.746487973 +0300
+@@ -39,12 +39,12 @@ MAN_DIR = @mandir@
+ ETC_DIR = @sysconfdir@
+ VAR_DIR = @localstatedir@
+
+-PID_FILE = ${VAR_DIR}/run/vtund.pid
++PID_DIR = ${VAR_DIR}/run
+ CFG_FILE = ${ETC_DIR}/vtund.conf
+ STAT_DIR = ${VAR_DIR}/log/vtund
+ LOCK_DIR = ${VAR_DIR}/lock/vtund
+
+-DEFS = -DVTUN_CONFIG_FILE=\"$(CFG_FILE)\" -DVTUN_PID_FILE=\"$(PID_FILE)\" \
++DEFS = -DVTUN_CONFIG_FILE=\"$(CFG_FILE)\" -DVTUN_PID_DIR=\"$(PID_DIR)\" \
+ -DVTUN_STAT_DIR=\"$(STAT_DIR)\" -DVTUN_LOCK_DIR=\"$(LOCK_DIR)\"
+
+ OBJS = main.o cfg_file.tab.o cfg_file.lex.o server.o client.o lib.o \
+diff -pur 1/main.c 2/main.c
+--- 1/main.c 2014-11-02 12:56:00.021701942 +0300
++++ 2/main.c 2014-11-02 12:53:57.520368795 +0300
+@@ -50,7 +50,7 @@
+ struct vtun_opts vtun;
+ struct vtun_host default_host;
+
+-static void write_pid(void);
++static void write_pid(char *, char *);
+ static void reread_config(int sig);
+ static void usage(void);
+
+@@ -240,7 +240,7 @@ int main(int argc, char *argv[], char *e
+
+ if( vtun.svr_type == VTUN_STAND_ALONE ){
+ #ifdef HAVE_WORKING_FORK
+- write_pid();
++ write_pid("server", NULL);
+ #else
+ vtun_syslog(LOG_ERR,"Standalone server is not supported. Use -i");
+ exit(1);
+@@ -250,6 +250,7 @@ int main(int argc, char *argv[], char *e
+ server(sock);
+ } else {
+ init_title(argc,argv,env,"vtund[c]: ");
++ write_pid(host->host, vtun.svr_name);
+ client(host);
+ }
+
+@@ -260,15 +261,29 @@ int main(int argc, char *argv[], char *e
+
+ /*
+ * Very simple PID file creation function. Used by server.
+- * Overrides existing file.
++ * Overrides existing file. Optionally adds session name and host name to the
++ * pidfile name (this naming is very confusing, as the session is referred as
++ * host most of the time)
+ */
+-static void write_pid(void)
++static void write_pid(char *session, char *host)
+ {
++ char fn[1024];
+ FILE *f;
+
+- if( !(f=fopen(VTUN_PID_FILE,"w")) ){
+- vtun_syslog(LOG_ERR,"Can't write PID file");
+- return;
++ if(session != NULL && host != NULL) {
++ snprintf(fn, sizeof(fn), "%s/vtund.%s-%s.pid", VTUN_PID_DIR, session,
++ host);
++ } else if(session != NULL) {
++ snprintf(fn, sizeof(fn), "%s/vtund.%s.pid", VTUN_PID_DIR, session);
++ } else {
++ snprintf(fn, sizeof(fn), "%s/vtund.pid", VTUN_PID_DIR);
++ }
++ /* Make sure the PID file is not there before opening it for writing. */
++ unlink(fn);
++
++ if( !(f = fopen(fn, "w")) ) {
++ syslog(LOG_ERR, "Can't write PID file %s: %s", fn, strerror(errno));
++ return;
+ }
+
+ fprintf(f,"%d",(int)getpid());
diff --git a/02-dumpfile.patch b/02-dumpfile.patch
new file mode 100644
index 000000000000..5db3e9ba2396
--- /dev/null
+++ b/02-dumpfile.patch
@@ -0,0 +1,20 @@
+02-dumpfile.patch by Martín Ferrari <martin.ferrari@gmail.com>
+
+http://sourceforge.net/support/tracker.php?aid=1744569
+
+ Patch to add an extension to dump files, so they can be managed by
+ logrotate
+
+Index: vtun-3.0.3/linkfd.c
+===================================================================
+--- vtun-3.0.3.orig/linkfd.c 2012-10-07 20:42:53.000000000 +0200
++++ vtun-3.0.3/linkfd.c 2012-10-07 20:43:26.289354719 +0200
+@@ -415,7 +415,7 @@
+ sa.sa_handler=sig_usr1;
+ sigaction(SIGUSR1,&sa,NULL);
+
+- sprintf(file,"%s/%.20s", VTUN_STAT_DIR, host->host);
++ sprintf(file,"%s/%.20s.dump", VTUN_STAT_DIR, host->host);
+ if( (host->stat.file=fopen(file, "a")) ){
+ setvbuf(host->stat.file, NULL, _IOLBF, 0);
+ } else
diff --git a/03-signedness-warnings.patch b/03-signedness-warnings.patch
new file mode 100644
index 000000000000..d0809990873a
--- /dev/null
+++ b/03-signedness-warnings.patch
@@ -0,0 +1,217 @@
+03-signedness-warnings.dpatch by Martín Ferrari <martin.ferrari@gmail.com>
+
+http://sourceforge.net/support/tracker.php?aid=1744570
+
+ Various explicit casts to stop gcc from complaining. It'd be better to
+ fix the prototypes, but that's much more intrusive.
+
+Index: vtun-3.0.3/auth.c
+===================================================================
+--- vtun-3.0.3.orig/auth.c 2012-10-07 20:07:28.000000000 +0200
++++ vtun-3.0.3/auth.c 2012-10-07 20:09:57.853300935 +0200
+@@ -89,7 +89,7 @@
+
+ void gen_chal(char *buf)
+ {
+- RAND_bytes(buf, VTUN_CHAL_SIZE);
++ RAND_bytes((unsigned char *)buf, VTUN_CHAL_SIZE);
+ }
+
+ void ssl_encrypt_chal(char *chal, char *pwd)
+@@ -98,10 +98,10 @@
+ BF_KEY key;
+
+ syslog(LOG_INFO, "Use SSL-aware challenge/response");
+- BF_set_key(&key, 16, MD5(pwd,strlen(pwd),NULL));
++ BF_set_key(&key, 16, MD5((unsigned char *)pwd,strlen(pwd),NULL));
+
+ for(i=0; i < VTUN_CHAL_SIZE; i += 8 )
+- BF_ecb_encrypt(chal + i, chal + i, &key, BF_ENCRYPT);
++ BF_ecb_encrypt((unsigned char *)chal + i, (unsigned char *)chal + i, &key, BF_ENCRYPT);
+ }
+
+ void ssl_decrypt_chal(char *chal, char *pwd)
+@@ -110,10 +110,10 @@
+ BF_KEY key;
+
+ syslog(LOG_INFO, "Use SSL-aware challenge/response");
+- BF_set_key(&key, 16, MD5(pwd,strlen(pwd),NULL));
++ BF_set_key(&key, 16, MD5((unsigned char *)pwd,strlen(pwd),NULL));
+
+ for(i=0; i < VTUN_CHAL_SIZE; i += 8 )
+- BF_ecb_encrypt(chal + i, chal + i, &key, BF_DECRYPT);
++ BF_ecb_encrypt((unsigned char *)chal + i, (unsigned char *)chal + i, &key, BF_DECRYPT);
+ }
+
+ #else /* HAVE_SSL */
+Index: vtun-3.0.3/lfd_encrypt.c
+===================================================================
+--- vtun-3.0.3.orig/lfd_encrypt.c 2008-01-07 23:35:32.000000000 +0100
++++ vtun-3.0.3/lfd_encrypt.c 2012-10-07 20:09:57.853300935 +0200
+@@ -118,12 +118,12 @@
+ tmplen = strlen(host->passwd);
+ if (tmplen != 0) halflen = tmplen>>1;
+ else halflen = 0;
+- MD5(host->passwd, halflen, hashkey);
+- MD5((host->passwd)+halflen, tmplen-halflen, hashkey+16);
++ MD5((unsigned char *)host->passwd, halflen, (unsigned char *)hashkey);
++ MD5((unsigned char *)(host->passwd)+halflen, tmplen-halflen, (unsigned char *)hashkey+16);
+ }
+ else if (size == 16)
+ {
+- MD5(host->passwd,strlen(host->passwd), hashkey);
++ MD5((unsigned char *)host->passwd,strlen(host->passwd), (unsigned char *)hashkey);
+ }
+ else
+ {
+@@ -163,7 +163,7 @@
+ return -1;
+ }
+
+- RAND_bytes((char *)&sequence_num, 4);
++ RAND_bytes((unsigned char *)&sequence_num, 4);
+ gibberish = 0;
+ gib_time_start = 0;
+ phost = host;
+@@ -263,8 +263,8 @@
+ EVP_CIPHER_CTX_set_key_length(pctx_enc, keysize);
+ EVP_CIPHER_CTX_set_key_length(pctx_dec, keysize);
+ }
+- EVP_EncryptInit_ex(pctx_enc, NULL, NULL, pkey, NULL);
+- EVP_DecryptInit_ex(pctx_dec, NULL, NULL, pkey, NULL);
++ EVP_EncryptInit_ex(pctx_enc, NULL, NULL, (unsigned char *)pkey, NULL);
++ EVP_DecryptInit_ex(pctx_dec, NULL, NULL, (unsigned char *)pkey, NULL);
+ EVP_CIPHER_CTX_set_padding(pctx_enc, 0);
+ EVP_CIPHER_CTX_set_padding(pctx_dec, 0);
+ if (sb_init)
+@@ -317,8 +317,8 @@
+ memset(in_ptr+len, pad, pad);
+ outlen=len+pad;
+ if (pad == blocksize)
+- RAND_bytes(in_ptr+len, blocksize-1);
+- EVP_EncryptUpdate(&ctx_enc, out_ptr, &outlen, in_ptr, len+pad);
++ RAND_bytes((unsigned char *)in_ptr+len, blocksize-1);
++ EVP_EncryptUpdate(&ctx_enc, (unsigned char *)out_ptr, &outlen, (unsigned char *)in_ptr, len+pad);
+ *out = enc_buf;
+
+ sequence_num++;
+@@ -338,7 +338,7 @@
+
+ outlen=len;
+ if (!len) return 0;
+- EVP_DecryptUpdate(&ctx_dec, out_ptr, &outlen, in_ptr, len);
++ EVP_DecryptUpdate(&ctx_dec, (unsigned char *)out_ptr, &outlen, (unsigned char *)in_ptr, len);
+ recv_ib_mesg(&outlen, &out_ptr);
+ if (!outlen) return 0;
+ tmp_ptr = out_ptr + outlen; tmp_ptr--;
+@@ -430,8 +430,8 @@
+ EVP_EncryptInit_ex(&ctx_enc, cipher_type, NULL, NULL, NULL);
+ if (var_key)
+ EVP_CIPHER_CTX_set_key_length(&ctx_enc, keysize);
+- EVP_EncryptInit_ex(&ctx_enc, NULL, NULL, pkey, NULL);
+- EVP_EncryptInit_ex(&ctx_enc, NULL, NULL, NULL, iv);
++ EVP_EncryptInit_ex(&ctx_enc, NULL, NULL, (unsigned char *)pkey, NULL);
++ EVP_EncryptInit_ex(&ctx_enc, NULL, NULL, NULL, (unsigned char *)iv);
+ EVP_CIPHER_CTX_set_padding(&ctx_enc, 0);
+ if (enc_init_first_time)
+ {
+@@ -520,8 +520,8 @@
+ EVP_DecryptInit_ex(&ctx_dec, cipher_type, NULL, NULL, NULL);
+ if (var_key)
+ EVP_CIPHER_CTX_set_key_length(&ctx_dec, keysize);
+- EVP_DecryptInit_ex(&ctx_dec, NULL, NULL, pkey, NULL);
+- EVP_DecryptInit_ex(&ctx_dec, NULL, NULL, NULL, iv);
++ EVP_DecryptInit_ex(&ctx_dec, NULL, NULL, (unsigned char *)pkey, NULL);
++ EVP_DecryptInit_ex(&ctx_dec, NULL, NULL, NULL, (unsigned char *)iv);
+ EVP_CIPHER_CTX_set_padding(&ctx_dec, 0);
+ if (dec_init_first_time)
+ {
+@@ -542,7 +542,7 @@
+ case CIPHER_INIT:
+ in_ptr = in - blocksize*2;
+ iv = malloc(blocksize);
+- RAND_bytes(iv, blocksize);
++ RAND_bytes((unsigned char *)iv, blocksize);
+ strncpy(in_ptr,"ivec",4);
+ in_ptr += 4;
+ memcpy(in_ptr,iv,blocksize);
+@@ -550,12 +550,12 @@
+ cipher_enc_init(iv);
+
+ memset(iv,0,blocksize); free(iv); iv = NULL;
+- RAND_bytes(in_ptr, in - in_ptr);
++ RAND_bytes((unsigned char *)in_ptr, in - in_ptr);
+
+ in_ptr = in - blocksize*2;
+ outlen = blocksize*2;
+- EVP_EncryptUpdate(&ctx_enc_ecb, in_ptr,
+- &outlen, in_ptr, blocksize*2);
++ EVP_EncryptUpdate(&ctx_enc_ecb, (unsigned char *)in_ptr,
++ &outlen, (unsigned char *)in_ptr, blocksize*2);
+ *out = in_ptr;
+ len = outlen;
+ cipher_enc_state = CIPHER_SEQUENCE;
+@@ -581,7 +581,7 @@
+ in_ptr = in;
+ iv = malloc(blocksize);
+ outlen = blocksize*2;
+- EVP_DecryptUpdate(&ctx_dec_ecb, in_ptr, &outlen, in_ptr, blocksize*2);
++ EVP_DecryptUpdate(&ctx_dec_ecb, (unsigned char *)in_ptr, &outlen, (unsigned char *)in_ptr, blocksize*2);
+
+ if ( !strncmp(in_ptr, "ivec", 4) )
+ {
+Index: vtun-3.0.3/netlib.c
+===================================================================
+--- vtun-3.0.3.orig/netlib.c 2009-03-29 12:44:02.000000000 +0200
++++ vtun-3.0.3/netlib.c 2012-10-07 20:10:25.281301670 +0200
+@@ -99,7 +99,7 @@
+ FD_ZERO(&fdset);
+ FD_SET(s,&fdset);
+ if( select(s+1,NULL,&fdset,NULL,timeout?&tv:NULL) > 0 ){
+- int l=sizeof(errno);
++ socklen_t l=sizeof(errno);
+ errno=0;
+ getsockopt(s,SOL_SOCKET,SO_ERROR,&errno,&l);
+ } else
+@@ -146,7 +146,8 @@
+ {
+ struct sockaddr_in saddr;
+ short port;
+- int s,opt;
++ int s;
++ socklen_t opt;
+ extern int is_rmt_fd_connected;
+
+ if( (s=socket(AF_INET,SOCK_DGRAM,0))== -1 ){
+@@ -220,7 +221,7 @@
+ /* Set local address */
+ int local_addr(struct sockaddr_in *addr, struct vtun_host *host, int con)
+ {
+- int opt;
++ socklen_t opt;
+
+ if( con ){
+ /* Use address of the already connected socket. */
+Index: vtun-3.0.3/server.c
+===================================================================
+--- vtun-3.0.3.orig/server.c 2012-07-09 03:01:08.000000000 +0200
++++ vtun-3.0.3/server.c 2012-10-07 20:09:57.853300935 +0200
+@@ -64,7 +64,7 @@
+ struct vtun_host *host;
+ struct sigaction sa;
+ char *ip;
+- int opt;
++ socklen_t opt;
+
+ opt = sizeof(struct sockaddr_in);
+ if( getpeername(sock, (struct sockaddr *) &cl_addr, &opt) ){
+@@ -115,7 +115,8 @@
+ {
+ struct sigaction sa;
+ struct sockaddr_in my_addr, cl_addr;
+- int s, s1, opt;
++ int s, s1;
++ socklen_t opt;
+
+ memset(&my_addr, 0, sizeof(my_addr));
+ my_addr.sin_family = AF_INET;
diff --git a/04-implicit-pointer-conversions.patch b/04-implicit-pointer-conversions.patch
new file mode 100644
index 000000000000..4bdcc774c772
--- /dev/null
+++ b/04-implicit-pointer-conversions.patch
@@ -0,0 +1,122 @@
+04-implicit-pointer-conversions.dpatch by Martín Ferrari <martin.ferrari@gmail.com>
+
+http://sourceforge.net/support/tracker.php?aid=1744571
+
+ Patch for correct declaration of types and functions. Missing includes,
+ forward declarations and also I had to replace getpt with posix_openpt,
+ because for some obscure reason it was not being defined. Anyway,
+ posix_openpt is the portable way of doing it.
+
+@DPATCH@
+Index: vtun-3.0.3/generic/pty_dev.c
+===================================================================
+--- vtun-3.0.3.orig/generic/pty_dev.c 2008-01-07 23:36:13.000000000 +0100
++++ vtun-3.0.3/generic/pty_dev.c 2012-10-07 20:11:02.469302665 +0200
+@@ -19,7 +19,9 @@
+ /*
+ * $Id: pty_dev.c,v 1.4.2.2 2008/01/07 22:36:13 mtbishop Exp $
+ */
+-
++/* Althought differing from documentation, this is necessary to have
++ * posix_openpt in GNU libc */
++#define _XOPEN_SOURCE 600
+ #include "config.h"
+
+ #include <unistd.h>
+@@ -39,10 +41,10 @@
+ int pty_open(char *sl_name)
+ {
+ int mr_fd;
+-#if defined (HAVE_GETPT) && defined (HAVE_GRANTPT) && defined (HAVE_UNLOCKPT) && defined (HAVE_PTSNAME)
++#if defined (HAVE_POSIX_OPENPT) && defined (HAVE_GRANTPT) && defined (HAVE_UNLOCKPT) && defined (HAVE_PTSNAME)
+ char *ptyname;
+
+- if((mr_fd=getpt()) < 0)
++ if((mr_fd=posix_openpt(O_RDWR|O_NOCTTY)) < 0)
+ return -1;
+ if(grantpt(mr_fd) != 0)
+ return -1;
+Index: vtun-3.0.3/lfd_encrypt.c
+===================================================================
+--- vtun-3.0.3.orig/lfd_encrypt.c 2012-10-07 20:10:50.000000000 +0200
++++ vtun-3.0.3/lfd_encrypt.c 2012-10-07 20:11:02.469302665 +0200
+@@ -44,6 +44,7 @@
+ #include <strings.h>
+ #include <string.h>
+ #include <time.h>
++#include <arpa/inet.h>
+
+ #include "vtun.h"
+ #include "linkfd.h"
+@@ -101,6 +102,11 @@
+ static EVP_CIPHER_CTX ctx_enc_ecb; /* sideband ecb encrypt */
+ static EVP_CIPHER_CTX ctx_dec_ecb; /* sideband ecb decrypt */
+
++static int send_msg(int len, char *in, char **out);
++static int send_ib_mesg(int *len, char **in);
++static int recv_msg(int len, char *in, char **out);
++static int recv_ib_mesg(int *len, char **in);
++
+ static int prep_key(char **key, int size, struct vtun_host *host)
+ {
+ int tmplen, halflen;
+Index: vtun-3.0.3/lfd_lzo.c
+===================================================================
+--- vtun-3.0.3.orig/lfd_lzo.c 2012-07-09 03:01:08.000000000 +0200
++++ vtun-3.0.3/lfd_lzo.c 2012-10-07 20:12:15.517304622 +0200
+@@ -37,7 +37,6 @@
+
+ #include "lzoutil.h"
+ #include "lzo1x.h"
+-#include "lzoutil.h"
+
+ static lzo_byte *zbuf;
+ static lzo_voidp wmem;
+Index: vtun-3.0.3/lfd_shaper.c
+===================================================================
+--- vtun-3.0.3.orig/lfd_shaper.c 2008-01-07 23:35:36.000000000 +0100
++++ vtun-3.0.3/lfd_shaper.c 2012-10-07 20:11:02.469302665 +0200
+@@ -31,6 +31,7 @@
+ #include "vtun.h"
+ #include "linkfd.h"
+ #include "lib.h"
++#include <time.h>
+
+ /*
+ * Shaper module.
+Index: vtun-3.0.3/lib.c
+===================================================================
+--- vtun-3.0.3.orig/lib.c 2008-01-07 23:35:40.000000000 +0100
++++ vtun-3.0.3/lib.c 2012-10-07 20:11:02.469302665 +0200
+@@ -38,6 +38,7 @@
+ #include "vtun.h"
+ #include "linkfd.h"
+ #include "lib.h"
++#include <time.h>
+
+ volatile sig_atomic_t __io_canceled = 0;
+
+Index: vtun-3.0.3/lib.h
+===================================================================
+--- vtun-3.0.3.orig/lib.h 2008-01-07 23:35:41.000000000 +0100
++++ vtun-3.0.3/lib.h 2012-10-07 20:11:02.469302665 +0200
+@@ -23,6 +23,7 @@
+ #define _VTUN_LIB_H
+
+ #include "config.h"
++#include <unistd.h>
+ #include <sys/types.h>
+ #include <signal.h>
+ #include <errno.h>
+Index: vtun-3.0.3/lock.c
+===================================================================
+--- vtun-3.0.3.orig/lock.c 2008-01-07 23:35:50.000000000 +0100
++++ vtun-3.0.3/lock.c 2012-10-07 20:11:02.469302665 +0200
+@@ -37,6 +37,7 @@
+ #include "linkfd.h"
+ #include "lib.h"
+ #include "lock.h"
++#include <time.h>
+
+ int create_lock(char * file)
+ {
diff --git a/05-unix98pty.patch b/05-unix98pty.patch
new file mode 100644
index 000000000000..de31c2b7eb47
--- /dev/null
+++ b/05-unix98pty.patch
@@ -0,0 +1,81 @@
+05-unix98pty.patch by Christoph Thielecke <crissi99@gmx.de>
+
+http://sourceforge.net/tracker/index.php?func=detail&aid=1692526&group_id=2947&atid=102947
+
+DP: Patch to allow the use of unix 98 pts
+
+Index: vtun-3.0.3/generic/pty_dev.c
+===================================================================
+--- vtun-3.0.3.orig/generic/pty_dev.c 2012-10-07 20:12:25.000000000 +0200
++++ vtun-3.0.3/generic/pty_dev.c 2012-10-07 20:12:29.777305003 +0200
+@@ -31,6 +31,8 @@
+ #include <string.h>
+ #include <syslog.h>
+
++#include <pty.h>
++
+ #include "vtun.h"
+ #include "lib.h"
+
+@@ -57,31 +59,29 @@
+
+ #else
+
+- char ptyname[] = "/dev/ptyXY";
+- char ch[] = "pqrstuvwxyz";
+- char digit[] = "0123456789abcdefghijklmnopqrstuv";
++ char ptyname[1024];
+ int l, m;
++ int master, slave;
++
++ /* This algorithm works for UNIX98 PTS */
+
+- /* This algorithm should work for almost all standard Unices */
+- for(l=0; ch[l]; l++ ) {
+- for(m=0; digit[m]; m++ ) {
+- ptyname[8] = ch[l];
+- ptyname[9] = digit[m];
+- /* Open the master */
+- if( (mr_fd=open(ptyname, O_RDWR)) < 0 )
+- continue;
++ /* Open the master */
++ mr_fd = openpty(&master, &slave, ptyname, NULL, NULL);
++ if (mr_fd == -1)
++ {
++ printf("error open pty");
++ return -1;
++ }
++ else
++ {
+ /* Check the slave */
+- ptyname[5] = 't';
+ if( (access(ptyname, R_OK | W_OK)) < 0 ){
+- close(mr_fd);
+- ptyname[5] = 'p';
+- continue;
++ /* close(mr_fd); */
++ return -1;
+ }
+ strcpy(sl_name,ptyname);
+- return mr_fd;
+- }
+- }
+- return -1;
++ return master;
++ }
+ #endif
+ }
+
+Index: vtun-3.0.3/Makefile.in
+===================================================================
+--- vtun-3.0.3.orig/Makefile.in 2012-10-07 20:12:25.000000000 +0200
++++ vtun-3.0.3/Makefile.in 2012-10-07 20:14:08.745307653 +0200
+@@ -19,7 +19,7 @@
+ #
+ CC = @CC@
+ CFLAGS = @CFLAGS@ @CPPFLAGS@
+-LDFLAGS = @LDFLAGS@ @LIBS@
++LDFLAGS = @LDFLAGS@ @LIBS@ -lutil
+
+ YACC = @YACC@
+ YACCFLAGS = -d
diff --git a/06-ipv6.patch b/06-ipv6.patch
new file mode 100644
index 000000000000..374411e3107c
--- /dev/null
+++ b/06-ipv6.patch
@@ -0,0 +1,73 @@
+Description: Replace gethostbyname() with getaddrinfo().
+ In recent versions of glibc, a call to gethostbyname()
+ will be default return an IPv6 reference as first entry.
+ This completely breaks communication between the vtund
+ server instance and the vtund client instance.
+ .
+ The solution to this clash is to migrate the code in
+ 'netlib.c' to use getaddrinfo(), since this function
+ can easily be configured to only return IPv4 addresses.
+Author: Mats Erik Andersson <debian@gisladisker.se>
+Forwarded: no
+Last-Update: 2010-05-13
+--- vtun-3.0.2.debian/netlib.c
++++ vtun-3.0.2/netlib.c
+@@ -229,21 +229,23 @@ int local_addr(struct sockaddr_in *addr,
+
+ int server_addr(struct sockaddr_in *addr, struct vtun_host *host)
+ {
+- struct hostent * hent;
++ struct addrinfo hints, *aiptr;
+
+ memset(addr,0,sizeof(struct sockaddr_in));
+- addr->sin_family = AF_INET;
+- addr->sin_port = htons(vtun.bind_addr.port);
++ memset(&hints, '\0', sizeof(hints));
++ hints.ai_family = AF_INET;
+
+ /* 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)) ){
++ if( getaddrinfo(vtun.svr_name, NULL, &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;
++ memcpy(addr, aiptr->ai_addr, aiptr->ai_addrlen);
++ addr->sin_port = htons(vtun.bind_addr.port);
++ freeaddrinfo(aiptr);
+
+ host->sopt.raddr = strdup(inet_ntoa(addr->sin_addr));
+ host->sopt.rport = vtun.bind_addr.port;
+@@ -254,8 +256,11 @@ int server_addr(struct sockaddr_in *addr
+ /* Set address by interface name, ip address or hostname */
+ int generic_addr(struct sockaddr_in *addr, struct vtun_addr *vaddr)
+ {
+- struct hostent *hent;
++ struct addrinfo hints, *aiptr;
++
+ memset(addr, 0, sizeof(struct sockaddr_in));
++ memset(&hints, '\0', sizeof(hints));
++ hints.ai_family = AF_INET;
+
+ addr->sin_family = AF_INET;
+
+@@ -270,13 +275,14 @@ int generic_addr(struct sockaddr_in *add
+ }
+ break;
+ case VTUN_ADDR_NAME:
+- if (!(hent = gethostbyname(vaddr->name))) {
++ if( getaddrinfo(vaddr->name, NULL, &hints, &aiptr) ){
+ vtun_syslog(LOG_ERR,
+ "Can't resolv local address %s",
+ vaddr->name);
+ return -1;
+ }
+- addr->sin_addr.s_addr = *(unsigned long *) hent->h_addr;
++ memcpy(addr, aiptr->ai_addr, aiptr->ai_addrlen);
++ freeaddrinfo(aiptr);
+ break;
+ default:
+ addr->sin_addr.s_addr = INADDR_ANY;
diff --git a/07-dual-family-transport.patch b/07-dual-family-transport.patch
new file mode 100644
index 000000000000..88d5ab30bbba
--- /dev/null
+++ b/07-dual-family-transport.patch
@@ -0,0 +1,635 @@
+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 <debian@gisladisker.se>
+Forwarded: no
+Last-Update: 2010-05-15
+diff -pur 1/vtun.h 2/vtun.h
+--- 1/vtun.h 2014-11-02 13:23:20.578322446 +0300
++++ 2/vtun.h 2014-11-02 13:19:39.268602630 +0300
+@@ -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 */
+@@ -219,6 +220,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 */
+diff -pur 1/main.c 2/main.c
+--- 1/main.c 2014-11-02 13:23:29.111516450 +0300
++++ 2/main.c 2014-11-02 13:21:20.713612915 +0300
+@@ -39,7 +39,7 @@
+ #include "lib.h"
+ #include "compat.h"
+
+-#define OPTSTRING "mif:P:L:t:npq"
++#define OPTSTRING "mif:P:L:t:npq46"
+ #ifdef HAVE_WORKING_FORK
+ # define SERVOPT_STRING "s"
+ #else
+@@ -80,6 +80,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");
+@@ -147,6 +148,12 @@ int main(int argc, char *argv[], char *e
+ case 'q':
+ vtun.quiet = 1;
+ break;
++ case '4':
++ vtun.transport_af = AF_INET;
++ break;
++ case '6':
++ vtun.transport_af = AF_INET6;
++ break;
+ default:
+ usage();
+ exit(1);
+diff -pur 1/netlib.h 2/netlib.h
+--- 1/netlib.h 2008-01-08 01:35:58.000000000 +0300
++++ 2/netlib.h 2014-11-02 13:19:39.268602630 +0300
+@@ -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 */
+diff -pur 1/netlib.c 2/netlib.c
+--- 1/netlib.c 2014-11-02 13:24:05.370924411 +0300
++++ 2/netlib.c 2014-11-02 13:19:39.271935909 +0300
+@@ -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,13 +195,16 @@ 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;
+ extern int is_rmt_fd_connected;
+
+- 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;
+ }
+@@ -158,8 +212,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;
+@@ -172,7 +224,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;
+@@ -191,7 +243,7 @@ int udp_session(struct vtun_host *host)
+ return -1;
+ }
+
+- saddr.sin_port = port;
++ set_port(&saddr, port);
+
+ /* if the config says to delay the UDP connection, we wait for an
+ incoming packet and then force a connection back. We need to
+@@ -219,91 +271,103 @@ 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 addrinfo hints, *aiptr;
++ char *ip, portstr[12];
++
++ ip = (char *) calloc(INET6_ADDRSTRLEN, sizeof(char));
++
++ memset(addr, '\0', sizeof(*addr));
+
+- memset(addr,0,sizeof(struct sockaddr_in));
+ memset(&hints, '\0', sizeof(hints));
+- hints.ai_family = AF_INET;
++ 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( getaddrinfo(vtun.svr_name, NULL, &hints, &aiptr) ){
+- 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;
+ }
++
+ memcpy(addr, aiptr->ai_addr, aiptr->ai_addrlen);
+- addr->sin_port = htons(vtun.bind_addr.port);
+ freeaddrinfo(aiptr);
+-
+- host->sopt.raddr = strdup(inet_ntoa(addr->sin_addr));
++ 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)
+ {
++ sa_family_t use_af = addr->ss_family;
+ struct addrinfo hints, *aiptr;
+
+- memset(addr, 0, sizeof(struct sockaddr_in));
++ memset(addr, '\0', sizeof(*addr)); /* Implicitly setting INADDR_ANY. */
+ memset(&hints, '\0', sizeof(hints));
+- hints.ai_family = AF_INET;
+-
+- addr->sin_family = AF_INET;
+
+ 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( 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:
+- 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;
+ }
+diff -pur 1/client.c 2/client.c
+--- 1/client.c 2012-07-08 09:32:57.000000000 +0400
++++ 2/client.c 2014-11-02 13:19:39.271935909 +0300
+@@ -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;
+@@ -138,9 +138,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 {
+diff -pur 1/server.c 2/server.c
+--- 1/server.c 2014-11-02 13:23:39.974672411 +0300
++++ 2/server.c 2014-11-02 13:19:39.271935909 +0300
+@@ -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)
+
+ static 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 @@ static 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 @@ static 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);
+
+@@ -115,21 +122,22 @@ static void connection(int sock)
+ static 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);
+ }
+@@ -189,7 +197,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:
+diff -pur 1/vtund.8 2/vtund.8
+--- 1/vtund.8 2012-07-08 09:32:57.000000000 +0400
++++ 2/vtund.8 2014-11-02 13:19:39.271935909 +0300
+@@ -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
+ ]
+@@ -71,6 +77,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
+diff -pur 1/cfg_kwords.h 2/cfg_kwords.h
+--- 1/cfg_kwords.h 2014-11-02 13:23:20.578322446 +0300
++++ 2/cfg_kwords.h 2014-11-02 13:19:39.271935909 +0300
+@@ -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 },
+diff -pur 1/cfg_file.y 2/cfg_file.y
+--- 1/cfg_file.y 2014-11-02 13:23:20.578322446 +0300
++++ 2/cfg_file.y 2014-11-02 13:19:39.271935909 +0300
+@@ -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_NAT_HACK K_COMPRESS K_ENCRYPT K_KALIVE K_STAT K_SSLAUTH
+ %token K_UP K_DOWN K_SYSLOG K_IPROUTE
+
+@@ -191,6 +191,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;
+diff -pur 1/vtund.conf.5 2/vtund.conf.5
+--- 1/vtund.conf.5 2013-07-08 00:36:52.000000000 +0400
++++ 2/vtund.conf.5 2014-11-02 13:19:39.271935909 +0300
+@@ -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.
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..df12ec0e1b30
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,67 @@
+# Contributor: Sascha Weaver <wzyboies at gmail dot com>
+# Maintainer: Natrio <natrio list ru>
+
+pkgname=vtun
+pkgver=3.0.3.2013.d
+_pkgver=3.0.3
+pkgrel=5
+pkgdesc="The easiest way to create Virtual Tunnels over TCP/IP networks with traffic shaping, compression, encryption and IPv6 support."
+arch=('i686' 'x86_64' 'armv7h' 'armv6h')
+url="http://vtun.sourceforge.net/"
+license=('GPL')
+depends=('openssl' 'zlib' 'lzo2')
+backup=('etc/vtund.conf' 'etc/tun-cfg.conf')
+source=("http://downloads.sourceforge.net/project/${pkgname}/${pkgname}/${_pkgver}/${pkgname}-${_pkgver}.tar.gz" cvs-2013.patch openlog.patch 00-sslauth.patch 01-pidfile.patch 02-dumpfile.patch 03-signedness-warnings.patch 04-implicit-pointer-conversions.patch 05-unix98pty.patch 06-ipv6.patch 07-dual-family-transport.patch vtund-ipv6-client.conf vtund-ipv6-server.conf android-dev.patch tun-cat.c tun-cfg tun-cfg.conf README.tun-cfg)
+sha512sums=('5fa789d08b556f97492b89515a89c2322c4b0a8fa95bd1035f5ed19061b3654a6a36a9911792096ac872ae9ae5451848cab87d0343dc0ffc064affea1f7d0d54' SKIP SKIP SKIP SKIP SKIP SKIP SKIP SKIP SKIP SKIP SKIP SKIP SKIP SKIP SKIP SKIP SKIP)
+install=vtun.install
+
+prepare() {
+ cd "${srcdir}"
+ HELPSTR=/usr/bin/tun-cfg ./tun-cfg --help > README.tun-cfg
+ cd "${srcdir}/${pkgname}-${_pkgver}"
+ # adding latest CVS 3_X2 branch changes and patches ported from Debian Jessie
+ for p in cvs-2013.patch openlog.patch 00-sslauth.patch 01-pidfile.patch 02-dumpfile.patch 03-signedness-warnings.patch 04-implicit-pointer-conversions.patch 05-unix98pty.patch 06-ipv6.patch 07-dual-family-transport.patch; do
+ patch -p1 -i "${srcdir}/$p" || exit 1
+ done
+ [[ "$CARCH" =~ ^arm ]] && patch -p1 -i "${srcdir}/android-dev.patch"
+ grep -v setproctitle configure.in > tmp
+ mv tmp configure.in
+ autoreconf -f
+}
+
+build() {
+ cd "${srcdir}/${pkgname}-${_pkgver}"
+ ./configure \
+ --prefix=/usr \
+ --sbindir=/usr/bin \
+ --sysconfdir=/etc \
+ --localstatedir=/var \
+ --mandir=/usr/share/man
+ make
+ cd "${srcdir}"
+ gcc tun-cat.c -o tun-cat
+}
+
+package() {
+ cd "${srcdir}/${pkgname}-${_pkgver}"
+
+ make PREFIX=/usr/bin DESTDIR="${pkgdir}" install
+
+ install -Dm644 vtund.conf "${pkgdir}/usr/share/doc/vtun/examples/vtund.conf"
+ sed -n '/--- Client config ---/,$p' vtund.conf > vtund-client.conf
+ install -Dm600 vtund-client.conf "${pkgdir}/etc/vtund.conf"
+ install -Dm644 Credits "${pkgdir}/usr/share/doc/vtun/Credits"
+ install -Dm644 README.Setup "${pkgdir}/usr/share/doc/vtun/README.Setup"
+ install -Dm644 README.Shaper "${pkgdir}/usr/share/doc/vtun/README.Shaper"
+ install -Dm644 FAQ "${pkgdir}/usr/share/doc/vtun/FAQ"
+ install -Dm644 ChangeLog "${pkgdir}/usr/share/doc/vtun/ChangeLog"
+ cd "${pkgdir}"
+ rm -r var/run var/lock
+ cd "${srcdir}"
+ install -Dm644 vtund-ipv6-client.conf "${pkgdir}/usr/share/doc/vtun/examples/vtund-ipv6-client.conf"
+ install -Dm644 vtund-ipv6-server.conf "${pkgdir}/usr/share/doc/vtun/examples/vtund-ipv6-server.conf"
+ install -Dm755 tun-cat "${pkgdir}/usr/bin/tun-cat"
+ install -Dm755 tun-cfg "${pkgdir}/usr/bin/tun-cfg"
+ install -Dm644 tun-cfg.conf "${pkgdir}/etc/tun-cfg.conf"
+ install -Dm644 README.tun-cfg "${pkgdir}/usr/share/doc/vtun/README.tun-cfg"
+}
diff --git a/README.tun-cfg b/README.tun-cfg
new file mode 100644
index 000000000000..b142f575ecb9
--- /dev/null
+++ b/README.tun-cfg
@@ -0,0 +1,105 @@
+Tunnel-configurer version 1.6.1
+ Client-server IP tunnel configuration via the same IP tunnel.
+
+-- vtund.conf --
+ # ifconfig replacement by wrapper
+options {
+ ...
+ #ifconfig /sbin/ifconfig;
+ ifconfig /usr/bin/tun-cfg;
+ ...
+
+ # Usual ifconfig example (tun-cfg doesn't break it):
+ # On server
+host0 {
+ passwd K@bI$D0x;
+ up {
+ ifconfig "%d 10.10.0.1 pointopoint 10.10.8.8";
+ };
+}
+
+ # On client
+host0 {
+ passwd K@bI$D0x;
+ up {
+ ifconfig "%d 10.10.8.8 pointopoint 10.10.0.1";
+ ip "route add 10.10.10.0/24 dev %d";
+ ip "route add 10.10.0.0/24 dev %d";
+ };
+}
+
+ # And same one with parameters transmission:
+ # Server example #1, without tun-cfg.conf and names
+host1 {
+ passwd K@bI$D0x;
+ up {
+ ifconfig "-tun %d local 10.10.0.1 send 10.10.10.5 10.10.10.0/24 10.10.0.0/24";
+ };
+}
+
+ # Server example #2, with tun-cfg.conf and client's domain name
+host1 {
+ passwd K@bI$D0x;
+ up {
+ ifconfig "-tun %d send host1.vpn";
+ };
+}
+
+ # Client example, getting all parameters from server
+host1 {
+ passwd K@bI$D0x;
+ up {
+ ifconfig "-tun %d get metric 100";
+ };
+}
+
+-- Common definion's file /etc/tun-cfg.conf (useful for server) --
+ # defaults
+PORT=68
+MTU=1500
+TIMEOUT=10
+ # the address of server for all hosts (example)
+LOCAL=server.vpn
+ # routes for sending to clients (example)
+ROUTES='10.10.10.0/24 10.10.0.0/24'
+
+-- Command-line description --
+ifconfig wrapper:
+ tun-cfg <'ifconfig' options>
+Server:
+ tun-cfg -tun <interface> send|-s <client_addr> [OPTIONS] [<client-side routes>]
+Client:
+ tun-cfg -tun <interface> get|-g|listen [OPTIONS] [<'ip route' options>][-6|v6 <options>]
+
+Addresses of client and server may be specified by IP, by name, or by
+ comma-separated list of IPv4,IPv6,names with v4,v6,no4,no6 modifiers.
+ All names will be resolved on server side, and only first IPv4 and IPv6 will be used:
+
+ 10.1.0.1 -> 10.1.0.1
+ 10.1.0.1,fc00::1001:1 -> 10.1.0.1 fc00::1001:1
+ host.vpn -> 10.1.0.4 fc00::1001:4
+ host.vpn,v4 -> 10.1.0.4
+ host.vpn,v6 -> fc00::1001:4
+
+Routes may be specified by IPv4/mask, IPv6/mask,
+ default (for IPv4), defaultv6 or default6 (for IPv6).
+
+OPTIONS:
+ port|-P <port> : default=68
+ mtu|-m <MTU> : default=1500, 0=no change
+forcemtu|+m <MTU> : Don't get MTU from server (client only)
+ local|-l <addr>|-: Force/skip local address (server only)
+ noaddr|-a : Don't modify any IPv4 addresses on interface
+ no6addr|-A : Don't modify any IPv6 addresses on interface
+ nopeer|-p : Don't set peer address (IPv4)
+ peer|+p : Add a route to peer instead of peer address (IPv4)
+noroutes|-r : server - Don't send any routes from config
+ : client - Don't get IPv4 routes from server
+no6routes|-R : Don't get IPv6 routes from server (client only)
+ timeout|-t <sec> : default=10, 0=endless
+ nofork|-B | nobg | nobackground
+
+NOTE:
+ By default, tun-cfg forks to background to prevent vtund from endless waiting
+ for tun-cfg termination, if the connection fails during configuration progress.
+
diff --git a/android-dev.patch b/android-dev.patch
new file mode 100644
index 000000000000..c970b47125ca
--- /dev/null
+++ b/android-dev.patch
@@ -0,0 +1,12 @@
+diff -pur 1/linux/tun_dev.c 2/linux/tun_dev.c
+--- 1/linux/tun_dev.c 2008-01-08 01:36:22.000000000 +0300
++++ 2/linux/tun_dev.c 2013-07-04 20:04:33.630722649 +0400
+@@ -87,7 +87,7 @@ static int tun_open_common(char *dev, in
+ struct ifreq ifr;
+ int fd;
+
+- if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
++ if ( (fd = open("/dev/net/tun", O_RDWR)) < 0 && (fd = open("/dev/tun", O_RDWR)) < 0 )
+ return tun_open_common0(dev, istun);
+
+ memset(&ifr, 0, sizeof(ifr));
diff --git a/cvs-2013.patch b/cvs-2013.patch
new file mode 100644
index 000000000000..e9469f752211
--- /dev/null
+++ b/cvs-2013.patch
@@ -0,0 +1,1240 @@
+diff -purN vtun-3.0.3/auth.c vtun/auth.c
+--- vtun-3.0.3/auth.c 2009-05-15 11:23:39.000000000 +0400
++++ vtun/auth.c 2013-07-07 23:54:20.000000000 +0400
+@@ -17,7 +17,7 @@
+ */
+
+ /*
+- * $Id: auth.c,v 1.9.2.4 2009/04/24 09:15:33 mtbishop Exp $
++ * $Id: auth.c,v 1.9.2.5 2013/07/07 19:54:20 mtbishop Exp $
+ */
+
+ /*
+@@ -62,12 +62,12 @@
+ #include <openssl/blowfish.h>
+ #include <openssl/rand.h>
+
+-void gen_chal(char *buf)
++static void gen_chal(char *buf)
+ {
+ RAND_bytes(buf, VTUN_CHAL_SIZE);
+ }
+
+-void encrypt_chal(char *chal, char *pwd)
++static void encrypt_chal(char *chal, char *pwd)
+ {
+ register int i;
+ BF_KEY key;
+@@ -78,7 +78,7 @@ void encrypt_chal(char *chal, char *pwd)
+ BF_ecb_encrypt(chal + i, chal + i, &key, BF_ENCRYPT);
+ }
+
+-void decrypt_chal(char *chal, char *pwd)
++static void decrypt_chal(char *chal, char *pwd)
+ {
+ register int i;
+ BF_KEY key;
+@@ -91,7 +91,7 @@ void decrypt_chal(char *chal, char *pwd)
+
+ #else /* HAVE_SSL */
+
+-void encrypt_chal(char *chal, char *pwd)
++static void encrypt_chal(char *chal, char *pwd)
+ {
+ char * xor_msk = pwd;
+ register int i, xor_len = strlen(xor_msk);
+@@ -100,13 +100,13 @@ void encrypt_chal(char *chal, char *pwd)
+ chal[i] ^= xor_msk[i%xor_len];
+ }
+
+-void inline decrypt_chal(char *chal, char *pwd)
++static void inline decrypt_chal(char *chal, char *pwd)
+ {
+ encrypt_chal(chal, pwd);
+ }
+
+ /* Generate PSEUDO random challenge key. */
+-void gen_chal(char *buf)
++static void gen_chal(char *buf)
+ {
+ register int i;
+
+@@ -123,7 +123,7 @@ void gen_chal(char *buf)
+ * C - compression, S - speed for shaper and so on.
+ */
+
+-char *bf2cf(struct vtun_host *host)
++static char *bf2cf(struct vtun_host *host)
+ {
+ static char str[20], *ptr = str;
+
+@@ -187,7 +187,7 @@ char *bf2cf(struct vtun_host *host)
+ FLAGS: <TuE1>
+ */
+
+-int cf2bf(char *str, struct vtun_host *host)
++static int cf2bf(char *str, struct vtun_host *host)
+ {
+ char *ptr, *p;
+ int s;
+@@ -277,7 +277,7 @@ int cf2bf(char *str, struct vtun_host *h
+ * string format: <char_data>
+ */
+
+-char *cl2cs(char *chal)
++static char *cl2cs(char *chal)
+ {
+ static char str[VTUN_CHAL_SIZE*2+3], *chr="abcdefghijklmnop";
+ register char *ptr = str;
+@@ -295,7 +295,7 @@ char *cl2cs(char *chal)
+ return str;
+ }
+
+-int cs2cl(char *str, char *chal)
++static int cs2cl(char *str, char *chal)
+ {
+ register char *ptr = str;
+ register int i;
+diff -purN vtun-3.0.3/cfg_file.y vtun/cfg_file.y
+--- vtun-3.0.3/cfg_file.y 2012-07-09 05:01:08.000000000 +0400
++++ vtun/cfg_file.y 2013-07-08 00:36:33.000000000 +0400
+@@ -18,7 +18,7 @@
+ */
+
+ /*
+- * $Id: cfg_file.y,v 1.8.2.6 2012/07/09 01:01:08 mtbishop Exp $
++ * $Id: cfg_file.y,v 1.8.2.7 2013/07/07 20:36:33 mtbishop Exp $
+ */
+
+ #include "config.h"
+@@ -107,6 +107,7 @@ statement: '\n'
+ memcpy(parse_host, &default_host, sizeof(struct vtun_host));
+ parse_host->host = strdup($1);
+ parse_host->passwd = NULL;
++ parse_host->sopt.host = strdup($1);
+
+ /* Copy local address */
+ copy_addr(parse_host, &default_host);
+diff -purN vtun-3.0.3/ChangeLog vtun/ChangeLog
+--- vtun-3.0.3/ChangeLog 2012-07-09 05:10:17.000000000 +0400
++++ vtun/ChangeLog 2013-07-08 00:24:07.000000000 +0400
+@@ -1,3 +1,10 @@
++
++-.-.-
++ bug53 - Race condition in socket() vs syslog (AH)
++ patch23 - check for fork and work around lack (AM)
++ patch22 - static declarations where possible (AM)
++ patch21 - fix up configure.in for newer autoheader (AM)
++
+ 3.0.3:
+ rfe2636157 - Delayed UDP connection (dv)
+ rfe2149137 - makefile ignores LDFLAGS (sbk)
+diff -purN vtun-3.0.3/configure.in vtun/configure.in
+--- vtun-3.0.3/configure.in 2009-03-29 14:08:51.000000000 +0400
++++ vtun/configure.in 2013-07-07 23:54:28.000000000 +0400
+@@ -2,12 +2,12 @@ dnl
+ dnl VTun - Virtual Tunnel over TCP/IP network.
+ dnl Copyright (C) 1998-2006 Maxim Krasnyansky <max_mk@yahoo.com>
+ dnl
+-dnl $Id: configure.in,v 1.19.2.2 2009/03/29 10:08:51 mtbishop Exp $
++dnl $Id: configure.in,v 1.19.2.3 2013/07/07 19:54:28 mtbishop Exp $
+ dnl
+ dnl Process this file with autoconf to produce a configure script.
+ dnl
+
+-AC_INIT(lib.c)
++AC_INIT(vtun, 3) dnl this needs to change via variables as in the tail
+ AC_CONFIG_HEADER(config.h)
+
+ dnl Shapper support
+@@ -110,10 +110,13 @@ dnl Check for librt
+ AC_SEARCH_LIBS(nanosleep, rt posix4)
+
+ dnl Check for setproctitle in libutil
+-AC_SEARCH_LIBS(setproctitle, util bsd, AC_DEFINE(HAVE_SETPROC_TITLE) )
++AC_SEARCH_LIBS(setproctitle, util bsd, AC_DEFINE(HAVE_SETPROC_TITLE, [1], [Define to 1 if you have setproctitle() function]) )
++
++dnl Check for fork() (fallback to vfork() on non-MMU systems)
++AC_FUNC_FORK
+
+ if test "$SHAPER" = "yes"; then
+- AC_DEFINE(HAVE_SHAPER)
++ AC_DEFINE(HAVE_SHAPER, [1], [Define to 1 if you want to enable shaper module])
+ fi
+
+ if test "$ZLIB" = "yes"; then
+@@ -121,7 +124,7 @@ if test "$ZLIB" = "yes"; then
+ AC_CHECKING( for ZLIB Library and Header files ... )
+ AC_CHECK_LIB(z, deflate,
+ LIBS="$LIBS -lz"
+- AC_DEFINE(HAVE_ZLIB),
++ AC_DEFINE(HAVE_ZLIB, [1], [Define to 1 if you have zlib]),
+ AC_MSG_ERROR( Zlib library not found.)
+ )
+ fi
+@@ -148,7 +151,7 @@ if test "$LZO" = "yes"; then
+ AC_CHECK_LIB($I, lzo1x_decompress,
+ [
+ LIBS="$LIBS -l"$I
+- AC_DEFINE(HAVE_LZO)
++ AC_DEFINE(HAVE_LZO, [1], [Define to 1 if you have lzo])
+ havelzo=1
+ ]
+ )
+@@ -180,8 +183,8 @@ if test "$SSL" = "yes"; then
+ AC_CHECK_LIB(crypto, BF_set_key,
+ [
+ LIBS="$LIBS -lcrypto"
+- AC_DEFINE(HAVE_SSL)
+- AC_DEFINE(HAVE_SSL_BLOWFISH)
++ AC_DEFINE(HAVE_SSL, [1], [Define to 1 if you have openssl])
++ AC_DEFINE(HAVE_SSL_BLOWFISH, [1], [Define to 1 if you have blowfish in openssl])
+ ],
+ AC_MSG_ERROR( SSL library not found. )
+ ),
+@@ -196,7 +199,7 @@ if test "$SSL" = "yes"; then
+ $SSL_HDR_DIR /usr/include/ssl /usr/include/openssl /usr/include /usr/local/include /usr/local/ssl/include /usr/include/crypto,
+ AC_CHECK_LIB(crypto, AES_set_encrypt_key,
+ [
+- AC_DEFINE(HAVE_SSL_AES)
++ AC_DEFINE(HAVE_SSL_AES, [1], [Define to 1 if you have AES in openssl])
+ ],
+ AC_MSG_ERROR( AES library not found. )
+ ),
+@@ -211,7 +214,7 @@ if test "$SSL" = "yes"; then
+ $SSL_HDR_DIR /usr/include/ssl /usr/include/openssl /usr/include /usr/local/include /usr/local/ssl/include /usr/include/crypto,
+ AC_CHECK_LIB(crypto, EVP_EncryptInit,
+ [
+- AC_DEFINE(HAVE_SSL_EVP)
++ AC_DEFINE(HAVE_SSL_EVP, [1], [Define to 1 if you have EVP in openssl])
+ ],
+ AC_MSG_ERROR( EVP library not found. )
+ ),
+@@ -220,7 +223,7 @@ if test "$SSL" = "yes"; then
+ fi
+
+ if test "$NATHACK" = "yes"; then
+- AC_DEFINE(ENABLE_NAT_HACK)
++ AC_DEFINE(ENABLE_NAT_HACK, [1], [Define to 1 if you want to enable Nat Hack code])
+ fi
+
+ if test "$SOCKS" = "yes"; then
+@@ -274,6 +277,6 @@ changequote(<,>)
+ REL=`echo 'BRANCH-3_X' | tr -d '$: \-' | sed 's/^[A-Za-z]*//' | sed 's/\_/\./'`
+ changequote([,])
+
+-AC_DEFINE_UNQUOTED(VTUN_VER, "$REL `date '+%m/%d/%Y'`")
++AC_DEFINE_UNQUOTED(VTUN_VER, "$REL `date '+%m/%d/%Y'`", [Vtun version])
+
+ AC_OUTPUT(Makefile)
+diff -purN vtun-3.0.3/Credits vtun/Credits
+--- vtun-3.0.3/Credits 2012-07-08 09:32:07.000000000 +0400
++++ vtun/Credits 2013-07-08 00:24:11.000000000 +0400
+@@ -159,3 +159,11 @@ Eugene Berdnikov
+
+ Sean MacLennan
+ Reduce connection chatter
++
++Andrey Mazo <ahippo@sf>
++ Clean up Configure.in for autoheader
++ Static declarations where sensible
++ Check/handle no fork() for no-MMU client systems (eg blackfin)
++
++Alfred Heisner <aheisner@sf>
++ Race condition between syslog socket and vtun (bug53)
+diff -purN vtun-3.0.3/driver.h vtun/driver.h
+--- vtun-3.0.3/driver.h 2008-01-08 01:35:30.000000000 +0300
++++ vtun/driver.h 2013-07-08 00:36:37.000000000 +0400
+@@ -17,14 +17,14 @@
+ */
+
+ /*
+- * $Id: driver.h,v 1.4.2.2 2008/01/07 22:35:30 mtbishop Exp $
++ * $Id: driver.h,v 1.4.2.3 2013/07/07 20:36:37 mtbishop Exp $
+ */
+ #ifndef _DRIVER_H
+ #define _DRIVER_H
+
+ /* Definitions for device and protocol drivers
+ * Interface will be completely rewritten in
+- * version 3.0
++ * future versions.
+ */
+
+ extern int (*dev_write)(int fd, char *buf, int len);
+diff -purN vtun-3.0.3/lfd_encrypt.c vtun/lfd_encrypt.c
+--- vtun-3.0.3/lfd_encrypt.c 2008-01-08 01:35:32.000000000 +0300
++++ vtun/lfd_encrypt.c 2013-07-07 23:54:35.000000000 +0400
+@@ -64,16 +64,16 @@
+ #define ENC_BUF_SIZE VTUN_FRAME_SIZE + 128
+ #define ENC_KEY_SIZE 16
+
+-BF_KEY key;
+-char * enc_buf;
+-char * dec_buf;
++static BF_KEY key;
++static char * enc_buf;
++static char * dec_buf;
+
+ #define CIPHER_INIT 0
+ #define CIPHER_CODE 1
+ #define CIPHER_SEQUENCE 2
+ #define CIPHER_REQ_INIT 3
+
+-struct vtun_host *phost;
++static struct vtun_host *phost;
+
+ extern int send_a_packet;
+
+@@ -81,27 +81,32 @@ extern int send_a_packet;
+ #define MAX_GIBBERISH 10
+ #define MIN_GIBBERISH 1
+ #define MAX_GIBBERISH_TIME 2
+-int gibberish;
+-time_t gib_time_start;
++static int gibberish;
++static time_t gib_time_start;
+
+-int cipher_enc_state;
+-int cipher_dec_state;
+-int cipher;
+-int blocksize;
+-int keysize;
+-int enc_init_first_time;
+-int dec_init_first_time;
+-unsigned long sequence_num;
+-char * pkey;
+-char * iv_buf;
++static int cipher_enc_state;
++static int cipher_dec_state;
++static int cipher;
++static int blocksize;
++static int keysize;
++static int enc_init_first_time;
++static int dec_init_first_time;
++static unsigned long sequence_num;
++static char * pkey;
++static char * iv_buf;
++
++static EVP_CIPHER_CTX ctx_enc; /* encrypt */
++static EVP_CIPHER_CTX ctx_dec; /* decrypt */
++
++static EVP_CIPHER_CTX ctx_enc_ecb; /* sideband ecb encrypt */
++static EVP_CIPHER_CTX ctx_dec_ecb; /* sideband ecb decrypt */
++
++static int send_msg(int len, char *in, char **out);
++static int recv_msg(int len, char *in, char **out);
++static int send_ib_mesg(int *len, char **in);
++static int recv_ib_mesg(int *len, char **in);
+
+-EVP_CIPHER_CTX ctx_enc; /* encrypt */
+-EVP_CIPHER_CTX ctx_dec; /* decrypt */
+-
+-EVP_CIPHER_CTX ctx_enc_ecb; /* sideband ecb encrypt */
+-EVP_CIPHER_CTX ctx_dec_ecb; /* sideband ecb decrypt */
+-
+-int prep_key(char **key, int size, struct vtun_host *host)
++static int prep_key(char **key, int size, struct vtun_host *host)
+ {
+ int tmplen, halflen;
+ char *hashkey;
+@@ -136,12 +141,12 @@ int prep_key(char **key, int size, struc
+ return 0;
+ }
+
+-void free_key (char *key)
++static void free_key (char *key)
+ {
+ free(key);
+ }
+
+-int alloc_encrypt(struct vtun_host *host)
++static int alloc_encrypt(struct vtun_host *host)
+ {
+ int sb_init = 0;
+ int var_key = 0;
+@@ -282,7 +287,7 @@ int alloc_encrypt(struct vtun_host *host
+ return 0;
+ }
+
+-int free_encrypt()
++static int free_encrypt()
+ {
+ free_key(pkey); pkey = NULL;
+
+@@ -297,7 +302,7 @@ int free_encrypt()
+ return 0;
+ }
+
+-int encrypt_buf(int len, char *in, char **out)
++static int encrypt_buf(int len, char *in, char **out)
+ {
+ register int pad, p, msg_len;
+ int outlen;
+@@ -326,7 +331,7 @@ int encrypt_buf(int len, char *in, char
+ return outlen+msg_len;
+ }
+
+-int decrypt_buf(int len, char *in, char **out)
++static int decrypt_buf(int len, char *in, char **out)
+ {
+ register int pad;
+ char *tmp_ptr, *in_ptr, *out_ptr = dec_buf;
+@@ -351,7 +356,7 @@ int decrypt_buf(int len, char *in, char
+ return outlen - pad;
+ }
+
+-int cipher_enc_init(char * iv)
++static int cipher_enc_init(char * iv)
+ {
+ int var_key = 0;
+ const EVP_CIPHER *cipher_type;
+@@ -442,7 +447,7 @@ int cipher_enc_init(char * iv)
+ return 0;
+ }
+
+-int cipher_dec_init(char * iv)
++static int cipher_dec_init(char * iv)
+ {
+ int var_key = 0;
+ const EVP_CIPHER *cipher_type;
+@@ -532,7 +537,7 @@ int cipher_dec_init(char * iv)
+ return 0;
+ }
+
+-int send_msg(int len, char *in, char **out)
++static int send_msg(int len, char *in, char **out)
+ {
+ char * iv; char * in_ptr;
+ int outlen;
+@@ -570,7 +575,7 @@ int send_msg(int len, char *in, char **o
+ return len;
+ }
+
+-int recv_msg(int len, char *in, char **out)
++static int recv_msg(int len, char *in, char **out)
+ {
+ char * iv; char * in_ptr;
+ int outlen;
+@@ -645,7 +650,7 @@ int recv_msg(int len, char *in, char **o
+ }
+
+ /* Send In-Band Message */
+-int send_ib_mesg(int *len, char **in)
++static int send_ib_mesg(int *len, char **in)
+ {
+ char *in_ptr = *in;
+
+@@ -684,7 +689,7 @@ int send_ib_mesg(int *len, char **in)
+ }
+
+ /* Receive In-Band Message */
+-int recv_ib_mesg(int *len, char **in)
++static int recv_ib_mesg(int *len, char **in)
+ {
+ char *in_ptr = *in;
+
+@@ -747,7 +752,7 @@ struct lfd_mod lfd_encrypt = {
+
+ #else /* HAVE_SSL */
+
+-int no_encrypt(struct vtun_host *host)
++static int no_encrypt(struct vtun_host *host)
+ {
+ vtun_syslog(LOG_INFO, "Encryption is not supported");
+ return -1;
+diff -purN vtun-3.0.3/lfd_legacy_encrypt.c vtun/lfd_legacy_encrypt.c
+--- vtun-3.0.3/lfd_legacy_encrypt.c 2008-01-08 01:35:33.000000000 +0300
++++ vtun/lfd_legacy_encrypt.c 2013-07-07 23:54:41.000000000 +0400
+@@ -17,7 +17,7 @@
+ */
+
+ /*
+- * $Id: lfd_legacy_encrypt.c,v 1.1.4.2 2008/01/07 22:35:33 mtbishop Exp $
++ * $Id: lfd_legacy_encrypt.c,v 1.1.4.3 2013/07/07 19:54:41 mtbishop Exp $
+ * Code added wholesale temporarily from lfd_encrypt 1.2.2.8
+ */
+
+@@ -61,10 +61,10 @@
+ #define ENC_BUF_SIZE VTUN_FRAME_SIZE + 16
+ #define ENC_KEY_SIZE 16
+
+-BF_KEY key;
+-char * enc_buf;
++static BF_KEY key;
++static char * enc_buf;
+
+-int alloc_legacy_encrypt(struct vtun_host *host)
++static int alloc_legacy_encrypt(struct vtun_host *host)
+ {
+ if( !(enc_buf = lfd_alloc(ENC_BUF_SIZE)) ){
+ vtun_syslog(LOG_ERR,"Can't allocate buffer for legacy encryptor");
+@@ -77,13 +77,13 @@ int alloc_legacy_encrypt(struct vtun_hos
+ return 0;
+ }
+
+-int free_legacy_encrypt()
++static int free_legacy_encrypt()
+ {
+ lfd_free(enc_buf); enc_buf = NULL;
+ return 0;
+ }
+
+-int legacy_encrypt_buf(int len, char *in, char **out)
++static int legacy_encrypt_buf(int len, char *in, char **out)
+ {
+ register int pad, p;
+ register char *in_ptr = in, *out_ptr = enc_buf;
+@@ -105,7 +105,7 @@ int legacy_encrypt_buf(int len, char *in
+ return len + 8;
+ }
+
+-int legacy_decrypt_buf(int len, char *in, char **out)
++static int legacy_decrypt_buf(int len, char *in, char **out)
+ {
+ register int p;
+
+@@ -140,7 +140,7 @@ struct lfd_mod lfd_legacy_encrypt = {
+
+ #else /* HAVE_SSL */
+
+-int no_legacy_encrypt(struct vtun_host *host)
++static int no_legacy_encrypt(struct vtun_host *host)
+ {
+ vtun_syslog(LOG_INFO, "Encryption is not supported");
+ return -1;
+diff -purN vtun-3.0.3/lfd_lzo.c vtun/lfd_lzo.c
+--- vtun-3.0.3/lfd_lzo.c 2012-07-09 05:01:08.000000000 +0400
++++ vtun/lfd_lzo.c 2013-07-07 23:54:44.000000000 +0400
+@@ -17,7 +17,7 @@
+ */
+
+ /*
+- * $Id: lfd_lzo.c,v 1.5.2.5 2012/07/09 01:01:08 mtbishop Exp $
++ * $Id: lfd_lzo.c,v 1.5.2.6 2013/07/07 19:54:44 mtbishop Exp $
+ */
+
+ /* LZO compression module */
+@@ -44,7 +44,7 @@ static lzo_voidp wmem;
+ static int zbuf_size = VTUN_FRAME_SIZE * VTUN_FRAME_SIZE / 64 + 16 + 3;
+
+ /* Pointer to compress function */
+-int (*lzo1x_compress)(const lzo_byte *src, lzo_uint src_len,
++static int (*lzo1x_compress)(const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uint *dst_len,
+ lzo_voidp wrkmem);
+ /*
+@@ -52,7 +52,7 @@ int (*lzo1x_compress)(const lzo_byte *sr
+ * Allocate the buffers.
+ */
+
+-int alloc_lzo(struct vtun_host *host)
++static int alloc_lzo(struct vtun_host *host)
+ {
+ int zlevel = host->zlevel ? host->zlevel : 1;
+ lzo_uint mem;
+@@ -91,7 +91,7 @@ int alloc_lzo(struct vtun_host *host)
+ * Free the buffer.
+ */
+
+-int free_lzo()
++static int free_lzo()
+ {
+ lfd_free(zbuf); zbuf = NULL;
+ lzo_free(wmem); wmem = NULL;
+@@ -102,7 +102,7 @@ int free_lzo()
+ * This functions _MUST_ consume all incoming bytes in one pass,
+ * that's why we expand buffer dynamicly.
+ */
+-int comp_lzo(int len, char *in, char **out)
++static int comp_lzo(int len, char *in, char **out)
+ {
+ lzo_uint zlen = 0;
+ int err;
+@@ -116,7 +116,7 @@ int comp_lzo(int len, char *in, char **o
+ return zlen;
+ }
+
+-int decomp_lzo(int len, char *in, char **out)
++static int decomp_lzo(int len, char *in, char **out)
+ {
+ lzo_uint zlen = 0;
+ int err;
+@@ -144,7 +144,7 @@ struct lfd_mod lfd_lzo = {
+
+ #else /* HAVE_LZO */
+
+-int no_lzo(struct vtun_host *host)
++static int no_lzo(struct vtun_host *host)
+ {
+ vtun_syslog(LOG_INFO, "LZO compression is not supported");
+ return -1;
+diff -purN vtun-3.0.3/lfd_shaper.c vtun/lfd_shaper.c
+--- vtun-3.0.3/lfd_shaper.c 2008-01-08 01:35:36.000000000 +0300
++++ vtun/lfd_shaper.c 2013-07-07 23:54:48.000000000 +0400
+@@ -17,7 +17,7 @@
+ */
+
+ /*
+- * $Id: lfd_shaper.c,v 1.7.2.2 2008/01/07 22:35:36 mtbishop Exp $
++ * $Id: lfd_shaper.c,v 1.7.2.3 2013/07/07 19:54:48 mtbishop Exp $
+ */
+
+ #include "config.h"
+@@ -38,13 +38,13 @@
+
+ #ifdef HAVE_SHAPER
+
+-unsigned long bytes, max_speed;
+-struct timeval curr_time, last_time;
++static unsigned long bytes, max_speed;
++static struct timeval curr_time, last_time;
+
+ /*
+ * Initialization function.
+ */
+-int shaper_init(struct vtun_host *host)
++static int shaper_init(struct vtun_host *host)
+ {
+ /* Calculate max speed bytes/sec */
+ max_speed = host->spd_out / 8 * 1024;
+@@ -59,7 +59,7 @@ int shaper_init(struct vtun_host *host)
+ }
+
+ /* Shaper counter */
+-int shaper_counter(int len, char *in, char **out)
++static int shaper_counter(int len, char *in, char **out)
+ {
+ /* Just count incoming bytes */
+ bytes += len;
+@@ -69,7 +69,7 @@ int shaper_counter(int len, char *in, ch
+ }
+
+ /* Convert tv struct to milisec */
+-unsigned long inline tv2ms(struct timeval tv)
++static unsigned long inline tv2ms(struct timeval tv)
+ {
+ register unsigned long ms = (tv.tv_sec * 1000)+(tv.tv_usec / 1000);
+ return ms ? ms : 1;
+@@ -94,7 +94,7 @@ unsigned long inline tv2ms(struct timeva
+ * higher than maximal speed stop accepting input
+ * until the speed become lower or equal to maximal.
+ */
+-int shaper_avail(void)
++static int shaper_avail(void)
+ {
+ static struct timeval tv;
+ register unsigned long speed;
+@@ -144,7 +144,7 @@ struct lfd_mod lfd_shaper = {
+
+ #else /* HAVE_SHAPER */
+
+-int no_shaper(struct vtun_host *host)
++static int no_shaper(struct vtun_host *host)
+ {
+ vtun_syslog(LOG_INFO, "Traffic shaping is not supported");
+ return -1;
+diff -purN vtun-3.0.3/lfd_zlib.c vtun/lfd_zlib.c
+--- vtun-3.0.3/lfd_zlib.c 2008-01-08 01:35:38.000000000 +0300
++++ vtun/lfd_zlib.c 2013-07-07 23:54:52.000000000 +0400
+@@ -17,7 +17,7 @@
+ */
+
+ /*
+- * $Id: lfd_zlib.c,v 1.5.2.2 2008/01/07 22:35:38 mtbishop Exp $
++ * $Id: lfd_zlib.c,v 1.5.2.3 2013/07/07 19:54:52 mtbishop Exp $
+ */
+
+ /* ZLIB compression module */
+@@ -45,7 +45,7 @@ static int zbuf_size = VTUN_FRAME_SIZE +
+ * Initialize compressor/decompressor.
+ * Allocate the buffer.
+ */
+-int zlib_alloc(struct vtun_host *host)
++static int zlib_alloc(struct vtun_host *host)
+ {
+ int zlevel = host->zlevel ? host->zlevel : 1;
+
+@@ -78,7 +78,7 @@ int zlib_alloc(struct vtun_host *host)
+ * Free the buffer.
+ */
+
+-int zlib_free()
++static int zlib_free()
+ {
+ deflateEnd(&zd);
+ inflateEnd(&zi);
+@@ -104,7 +104,7 @@ static int expand_zbuf(z_stream *zs, int
+ * That's why we expand buffer dynamically.
+ * Practice shows that buffer will not grow larger that 16K.
+ */
+-int zlib_comp(int len, char *in, char **out)
++static int zlib_comp(int len, char *in, char **out)
+ {
+ int oavail, olen = 0;
+ int err;
+@@ -133,7 +133,7 @@ int zlib_comp(int len, char *in, char **
+ return olen;
+ }
+
+-int zlib_decomp(int len, char *in, char **out)
++static int zlib_decomp(int len, char *in, char **out)
+ {
+ int oavail = 0, olen = 0;
+ int err;
+@@ -175,7 +175,7 @@ struct lfd_mod lfd_zlib = {
+
+ #else /* HAVE_ZLIB */
+
+-int no_zlib(struct vtun_host *host)
++static int no_zlib(struct vtun_host *host)
+ {
+ vtun_syslog(LOG_INFO, "ZLIB compression is not supported");
+ return -1;
+diff -purN vtun-3.0.3/lib.c vtun/lib.c
+--- vtun-3.0.3/lib.c 2008-01-08 01:35:40.000000000 +0300
++++ vtun/lib.c 2013-07-08 00:21:20.000000000 +0400
+@@ -17,7 +17,7 @@
+ */
+
+ /*
+- * $Id: lib.c,v 1.9.2.2 2008/01/07 22:35:40 mtbishop Exp $
++ * $Id: lib.c,v 1.9.2.4 2013/07/07 20:21:20 mtbishop Exp $
+ */
+
+ #include "config.h"
+@@ -45,9 +45,9 @@ volatile sig_atomic_t __io_canceled = 0;
+ /* Functions to manipulate with program title */
+
+ extern char **environ;
+-char *title_start; /* start of the proc title space */
+-char *title_end; /* end of the proc title space */
+-int title_size;
++static char *title_start; /* start of the proc title space */
++static char *title_end; /* end of the proc title space */
++static int title_size;
+
+ void init_title(int argc,char *argv[], char *envp[], char *name)
+ {
+@@ -148,7 +148,7 @@ int readn_t(int fd, void *buf, size_t co
+ * Substitutes opt in place off '%X'.
+ * Returns new string.
+ */
+-char * subst_opt(char *str, struct vtun_sopt *opt)
++static char * subst_opt(char *str, struct vtun_sopt *opt)
+ {
+ register int slen, olen, sp, np;
+ register char *optr, *nstr, *tmp;
+@@ -185,6 +185,9 @@ char * subst_opt(char *str, struct vtun_
+ sprintf(buf,"%d",opt->rport);
+ optr=buf;
+ break;
++ case 'h':
++ optr=opt->host;
++ break;
+ default:
+ sp++;
+ continue;
+@@ -223,7 +226,7 @@ char * subst_opt(char *str, struct vtun_
+ * ' ' - group arguments
+ * Modifies original string.
+ */
+-void split_args(char *str, char **argv)
++static void split_args(char *str, char **argv)
+ {
+ register int i = 0;
+ int mode = 0;
+@@ -276,6 +279,7 @@ void split_args(char *str, char **argv)
+ argv[i]=NULL;
+ }
+
++#ifdef HAVE_WORKING_FORK
+ int run_cmd(void *d, void *opt)
+ {
+ struct vtun_cmd *cmd = d;
+@@ -324,6 +328,7 @@ int run_cmd(void *d, void *opt)
+ vtun_syslog(LOG_ERR,"Couldn't exec program %s", cmd->prog);
+ exit(1);
+ }
++#endif
+
+ void free_sopt( struct vtun_sopt *opt )
+ {
+@@ -355,6 +360,7 @@ void vtun_syslog (int priority, char *fo
+ va_start(ap, format);
+ vsnprintf(buf, sizeof(buf)-1, format, ap);
+ syslog(priority, "%s", buf);
++ closelog();
+ va_end(ap);
+
+ in_syslog = 0;
+diff -purN vtun-3.0.3/lib.h vtun/lib.h
+--- vtun-3.0.3/lib.h 2008-01-08 01:35:41.000000000 +0300
++++ vtun/lib.h 2013-07-07 23:55:00.000000000 +0400
+@@ -17,7 +17,7 @@
+ */
+
+ /*
+- * $Id: lib.h,v 1.7.2.2 2008/01/07 22:35:41 mtbishop Exp $
++ * $Id: lib.h,v 1.7.2.3 2013/07/07 19:55:00 mtbishop Exp $
+ */
+ #ifndef _VTUN_LIB_H
+ #define _VTUN_LIB_H
+@@ -46,7 +46,9 @@
+ int readn_t(int fd, void *buf, size_t count, time_t timeout);
+ int print_p(int f, const char *ftm, ...);
+
++#ifdef HAVE_WORKING_FORK
+ int run_cmd(void *d, void *opt);
++#endif
+ void free_sopt(struct vtun_sopt *opt);
+
+ /* IO cancelation */
+diff -purN vtun-3.0.3/linkfd.c vtun/linkfd.c
+--- vtun-3.0.3/linkfd.c 2012-07-08 09:31:44.000000000 +0400
++++ vtun/linkfd.c 2013-07-07 23:55:06.000000000 +0400
+@@ -17,7 +17,7 @@
+ */
+
+ /*
+- * $Id: linkfd.c,v 1.13.2.5 2012/07/07 07:14:17 mtbishop Exp $
++ * $Id: linkfd.c,v 1.13.2.6 2013/07/07 19:55:06 mtbishop Exp $
+ */
+
+ #include "config.h"
+@@ -56,14 +56,14 @@ int send_a_packet = 0;
+ /* Host we are working with.
+ * Used by signal handlers that's why it is global.
+ */
+-struct vtun_host *lfd_host;
++static struct vtun_host *lfd_host;
+
+-struct lfd_mod *lfd_mod_head = NULL, *lfd_mod_tail = NULL;
++static struct lfd_mod *lfd_mod_head = NULL, *lfd_mod_tail = NULL;
+
+ /* Modules functions*/
+
+ /* Add module to the end of modules list */
+-void lfd_add_mod(struct lfd_mod *mod)
++static void lfd_add_mod(struct lfd_mod *mod)
+ {
+ if( !lfd_mod_head ){
+ lfd_mod_head = lfd_mod_tail = mod;
+@@ -77,7 +77,7 @@ void lfd_add_mod(struct lfd_mod *mod)
+ }
+
+ /* Initialize and allocate each module */
+-int lfd_alloc_mod(struct vtun_host *host)
++static int lfd_alloc_mod(struct vtun_host *host)
+ {
+ struct lfd_mod *mod = lfd_mod_head;
+
+@@ -91,7 +91,7 @@ int lfd_alloc_mod(struct vtun_host *host
+ }
+
+ /* Free all modules */
+-int lfd_free_mod(void)
++static int lfd_free_mod(void)
+ {
+ struct lfd_mod *mod = lfd_mod_head;
+
+@@ -105,7 +105,7 @@ int lfd_free_mod(void)
+ }
+
+ /* Run modules down (from head to tail) */
+-inline int lfd_run_down(int len, char *in, char **out)
++static inline int lfd_run_down(int len, char *in, char **out)
+ {
+ register struct lfd_mod *mod;
+
+@@ -119,7 +119,7 @@ inline int lfd_run_down(int len, char *i
+ }
+
+ /* Run modules up (from tail to head) */
+-inline int lfd_run_up(int len, char *in, char **out)
++static inline int lfd_run_up(int len, char *in, char **out)
+ {
+ register struct lfd_mod *mod;
+
+@@ -133,7 +133,7 @@ inline int lfd_run_up(int len, char *in,
+ }
+
+ /* Check if modules are accepting the data(down) */
+-inline int lfd_check_down(void)
++static inline int lfd_check_down(void)
+ {
+ register struct lfd_mod *mod;
+ int err = 1;
+@@ -145,7 +145,7 @@ inline int lfd_check_down(void)
+ }
+
+ /* Check if modules are accepting the data(up) */
+-inline int lfd_check_up(void)
++static inline int lfd_check_up(void)
+ {
+ register struct lfd_mod *mod;
+ int err = 1;
+@@ -179,7 +179,7 @@ static void sig_hup(int sig)
+ static volatile sig_atomic_t ka_need_verify = 0;
+ static time_t stat_timer = 0, ka_timer = 0;
+
+-void sig_alarm(int sig)
++static void sig_alarm(int sig)
+ {
+ static time_t tm_old, tm = 0;
+ static char stm[20];
+@@ -215,7 +215,7 @@ static void sig_usr1(int sig)
+ lfd_host->stat.comp_in = lfd_host->stat.comp_out = 0;
+ }
+
+-int lfd_linker(void)
++static int lfd_linker(void)
+ {
+ int fd1 = lfd_host->rmt_fd;
+ int fd2 = lfd_host->loc_fd;
+diff -purN vtun-3.0.3/main.c vtun/main.c
+--- vtun-3.0.3/main.c 2012-07-08 09:32:57.000000000 +0400
++++ vtun/main.c 2013-07-08 00:31:22.000000000 +0400
+@@ -17,7 +17,7 @@
+ */
+
+ /*
+- * $Id: main.c,v 1.9.2.5 2012/07/08 05:32:57 mtbishop Exp $
++ * $Id: main.c,v 1.9.2.7 2013/07/07 20:31:22 mtbishop Exp $
+ */
+
+ #include "config.h"
+@@ -39,13 +39,20 @@
+ #include "lib.h"
+ #include "compat.h"
+
++#define OPTSTRING "mif:P:L:t:npq"
++#ifdef HAVE_WORKING_FORK
++# define SERVOPT_STRING "s"
++#else
++# define SERVOPT_STRING ""
++#endif
++
+ /* Global options for the server and client */
+ struct vtun_opts vtun;
+ struct vtun_host default_host;
+
+-void write_pid(void);
+-void reread_config(int sig);
+-void usage(void);
++static void write_pid(void);
++static void reread_config(int sig);
++static void usage(void);
+
+ extern int optind,opterr,optopt;
+ extern char *optarg;
+@@ -55,13 +62,19 @@ int is_rmt_fd_connected=1;
+
+ int main(int argc, char *argv[], char *env[])
+ {
+- int svr, daemon, sock, dofork, fd, opt;
++ int svr, daemon, sock, fd, opt;
++#if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
++ int dofork;
++#endif
+ struct vtun_host *host = NULL;
+ struct sigaction sa;
+ char *hst;
+
+ /* Configure default settings */
+- svr = 0; daemon = 1; sock = 0; dofork = 1;
++ svr = 0; daemon = 1; sock = 0;
++#if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
++ dofork = 1;
++#endif
+
+ vtun.cfg_file = VTUN_CONFIG_FILE;
+ vtun.persist = -1;
+@@ -92,7 +105,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:npq")) != EOF ){
++ while( (opt=getopt(argc,argv,OPTSTRING SERVOPT_STRING)) != EOF ){
+ switch(opt){
+ case 'm':
+ if (mlockall(MCL_CURRENT | MCL_FUTURE) < 0) {
+@@ -102,7 +115,9 @@ int main(int argc, char *argv[], char *e
+ break;
+ case 'i':
+ vtun.svr_type = VTUN_INETD;
++#ifdef HAVE_WORKING_FORK
+ case 's':
++#endif
+ svr = 1;
+ break;
+ case 'L':
+@@ -173,13 +188,20 @@ int main(int argc, char *argv[], char *e
+ break;
+ case VTUN_INETD:
+ sock = dup(0);
++#if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
+ dofork = 0;
++#endif
+ break;
+ }
+
+ if( daemon ){
++#ifdef HAVE_WORKING_FORK
+ if( dofork && fork() )
+ exit(0);
++#elif defined(HAVE_WORKING_VFORK)
++ if( dofork && vfork() )
++ exit(0);
++#endif
+
+ /* Direct stdin,stdout,stderr to '/dev/null' */
+ fd = open("/dev/null", O_RDWR);
+@@ -200,8 +222,14 @@ int main(int argc, char *argv[], char *e
+
+ init_title(argc,argv,env,"vtund[s]: ");
+
+- if( vtun.svr_type == VTUN_STAND_ALONE )
++ if( vtun.svr_type == VTUN_STAND_ALONE ){
++#ifdef HAVE_WORKING_FORK
+ write_pid();
++#else
++ vtun_syslog(LOG_ERR,"Standalone server is not supported. Use -i");
++ exit(1);
++#endif
++ }
+
+ server(sock);
+ } else {
+@@ -218,7 +246,7 @@ int main(int argc, char *argv[], char *e
+ * Very simple PID file creation function. Used by server.
+ * Overrides existing file.
+ */
+-void write_pid(void)
++static void write_pid(void)
+ {
+ FILE *f;
+
+@@ -231,7 +259,7 @@ void write_pid(void)
+ fclose(f);
+ }
+
+-void reread_config(int sig)
++static void reread_config(int sig)
+ {
+ if( !read_config(vtun.cfg_file) ){
+ vtun_syslog(LOG_ERR,"No hosts defined");
+@@ -239,14 +267,18 @@ void reread_config(int sig)
+ }
+ }
+
+-void usage(void)
++static void usage(void)
+ {
+ printf("VTun ver %s\n", VTUN_VER);
+ printf("Usage: \n");
+ printf(" Server:\n");
+- printf("\tvtund <-s> [-f file] [-P port] [-L local address]\n");
++#ifdef HAVE_WORKING_FORK
++ printf("\tvtund <-s|-i> [-f file] [-P port] [-L local address]\n");
++#else
++ printf("\tvtund <-i> [-f file] [-P port] [-L local address]\n");
++#endif
+ printf(" Client:\n");
+ /* I don't think these work. I'm disabling the suggestion - bish 20050601*/
+ printf("\tvtund [-f file] " /* [-P port] [-L local address] */
+- "[-p] [-m] [-t timeout] <host profile> <server address>\n");
++ "[-q] [-p] [-m] [-t timeout] <host profile> <server address>\n");
+ }
+diff -purN vtun-3.0.3/Makefile.in vtun/Makefile.in
+--- vtun-3.0.3/Makefile.in 2012-07-09 08:55:38.000000000 +0400
++++ vtun/Makefile.in 2013-07-08 00:36:44.000000000 +0400
+@@ -15,7 +15,7 @@
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ # GNU General Public License for more details.
+ #
+-# $Id: Makefile.in,v 1.11.2.6 2012/07/09 04:55:38 mtbishop Exp $
++# $Id: Makefile.in,v 1.11.2.7 2013/07/07 20:36:44 mtbishop Exp $
+ #
+ CC = @CC@
+ CFLAGS = @CFLAGS@ @CPPFLAGS@
+@@ -73,7 +73,7 @@ depend:
+ makedepend -- $(CFLAGS) -- *.c
+
+ clean:
+- rm -f core cfg_file.tab.* cfg_file.lex.* *.o *~ *.bak vtund
++ rm -f core cfg_file.tab.* cfg_file.lex.* *.o *~ .#* *.bak vtund
+
+ distclean: clean
+ rm -f $(CONFIGURE_FILES)
+diff -purN vtun-3.0.3/packages/vtun.spec vtun/packages/vtun.spec
+--- vtun-3.0.3/packages/vtun.spec 2012-07-08 14:30:27.000000000 +0400
++++ vtun/packages/vtun.spec 2013-07-07 22:03:49.000000000 +0400
+@@ -1,4 +1,4 @@
+-# $Id: vtun.spec,v 1.24.2.9 2012/07/08 10:30:27 mtbishop Exp $
++# $Id: vtun.spec,v 1.24.2.10 2013/07/07 18:03:49 mtbishop Exp $
+
+ # By default, builds without socks-support.
+ # To build with socks-support, issue:
+@@ -46,6 +46,8 @@ Summary: Virtual tunnel over TCP/IP net
+ Summary(pl): Wirtualne tunele poprzez sieci TCP/IP
+ Vendor: Maxim Krasnyansky <max_mk@yahoo.com>
+ Packager: Bishop Clark (LC957) <bishop@platypus.bc.ca>
++
++ # Remember this is ignored for recent distros (Backward Compatibility is dumb)
+ BuildRoot: %{?_tmppath:%{_tmppath}}%{!?_tmppath:%{tmpdir}}/%{name}-%{version}-root-%(id -u -n)
+ Obsoletes: vppp
+ BuildRequires: autoconf
+diff -purN vtun-3.0.3/server.c vtun/server.c
+--- vtun-3.0.3/server.c 2012-07-09 05:01:08.000000000 +0400
++++ vtun/server.c 2013-07-07 23:55:14.000000000 +0400
+@@ -17,7 +17,7 @@
+ */
+
+ /*
+- * $Id: server.c,v 1.9.2.3 2012/07/09 01:01:08 mtbishop Exp $
++ * $Id: server.c,v 1.9.2.4 2013/07/07 19:55:14 mtbishop Exp $
+ */
+
+ #include "config.h"
+@@ -58,7 +58,7 @@ static void sig_term(int sig)
+ server_term = VTUN_SIG_TERM;
+ }
+
+-void connection(int sock)
++static void connection(int sock)
+ {
+ struct sockaddr_in my_addr, cl_addr;
+ struct vtun_host *host;
+@@ -111,7 +111,8 @@ void connection(int sock)
+ exit(0);
+ }
+
+-void listener(void)
++#ifdef HAVE_WORKING_FORK
++static void listener(void)
+ {
+ struct sigaction sa;
+ struct sockaddr_in my_addr, cl_addr;
+@@ -172,6 +173,7 @@ void listener(void)
+ }
+ }
+ }
++#endif
+
+ void server(int sock)
+ {
+@@ -190,7 +192,11 @@ void server(int sock)
+
+ switch( vtun.svr_type ){
+ case VTUN_STAND_ALONE:
++#ifdef HAVE_WORKING_FORK
+ listener();
++#else
++ vtun_syslog(LOG_ERR,"Standalone server is not supported: fork() not available");
++#endif
+ break;
+ case VTUN_INETD:
+ connection(sock);
+diff -purN vtun-3.0.3/tunnel.c vtun/tunnel.c
+--- vtun-3.0.3/tunnel.c 2008-01-08 01:36:03.000000000 +0300
++++ vtun/tunnel.c 2013-07-07 23:55:17.000000000 +0400
+@@ -17,7 +17,7 @@
+ */
+
+ /*
+- * $Id: tunnel.c,v 1.14.2.2 2008/01/07 22:36:03 mtbishop Exp $
++ * $Id: tunnel.c,v 1.14.2.3 2013/07/07 19:55:17 mtbishop Exp $
+ */
+
+ #include "config.h"
+@@ -147,6 +147,7 @@ int tunnel(struct vtun_host *host)
+ break;
+ }
+
++#ifdef HAVE_WORKING_FORK
+ switch( (pid=fork()) ){
+ case -1:
+ vtun_syslog(LOG_ERR,"Couldn't fork()");
+@@ -187,6 +188,9 @@ int tunnel(struct vtun_host *host)
+
+ exit(0);
+ }
++#else
++ vtun_syslog(LOG_ERR,"Couldn't run up commands: fork() not available");
++#endif
+
+ switch( host->flags & VTUN_TYPE_MASK ){
+ case VTUN_TTY:
+@@ -222,8 +226,12 @@ int tunnel(struct vtun_host *host)
+
+ opt = linkfd(host);
+
++#ifdef HAVE_WORKING_FORK
+ set_title("%s running down commands", host->host);
+ llist_trav(&host->down, run_cmd, &host->sopt);
++#else
++ vtun_syslog(LOG_ERR,"Couldn't run down commands: fork() not available");
++#endif
+
+ if(! ( host->persist == VTUN_PERSIST_KEEPIF ) ) {
+ set_title("%s closing", host->host);
+diff -purN vtun-3.0.3/vtund.conf vtun/vtund.conf
+--- vtun-3.0.3/vtund.conf 2012-07-08 09:31:44.000000000 +0400
++++ vtun/vtund.conf 2013-07-08 00:36:48.000000000 +0400
+@@ -6,7 +6,7 @@
+ # Ted Rolle <ted@acacia.datacomm.com>
+ #
+ # Configuration file example
+-# $Id: vtund.conf,v 1.4.2.5 2012/07/07 07:14:17 mtbishop Exp $
++# $Id: vtund.conf,v 1.4.2.6 2013/07/07 20:36:48 mtbishop Exp $
+ #
+ #
+ # Lines which begin with '#' are comments
+@@ -227,6 +227,7 @@
+ # %P - Local TCP or UDP port
+ # %a - Remote IP address
+ # %p - Remote TCP or UDP port
++# %h - Host Profile Name in config
+ #
+ # wait - Wait for the program termination.
+ #
+diff -purN vtun-3.0.3/vtund.conf.5 vtun/vtund.conf.5
+--- vtun-3.0.3/vtund.conf.5 2012-07-08 09:31:44.000000000 +0400
++++ vtun/vtund.conf.5 2013-07-08 00:36:52.000000000 +0400
+@@ -1,5 +1,5 @@
+ .\" Manual page for vtund.conf
+-.\" $Id: vtund.conf.5,v 1.4.2.4 2012/07/07 07:14:17 mtbishop Exp $
++.\" $Id: vtund.conf.5,v 1.4.2.5 2013/07/07 20:36:52 mtbishop Exp $
+ .TH VTUND.CONF 5
+
+ .SH NAME
+@@ -315,6 +315,8 @@ Special characters that can be used insi
+ \fB%a\fR - Remote IP address
+ .br
+ \fB%p\fR - Remote TCP or UDP port
++.br
++\fB%h\fR - Host profile name
+ .IP \fBppp\ \fIarguments\fR
+ run program specified by \fBppp\fR statement in \fBoptions\fR section.
+ All special character described above are valid in \fIarguments\fR here.
+diff -purN vtun-3.0.3/vtun.h vtun/vtun.h
+--- vtun-3.0.3/vtun.h 2012-07-09 05:01:08.000000000 +0400
++++ vtun/vtun.h 2013-07-08 00:36:56.000000000 +0400
+@@ -17,7 +17,7 @@
+ */
+
+ /*
+- * $Id: vtun.h,v 1.12.2.7 2012/07/09 01:01:08 mtbishop Exp $
++ * $Id: vtun.h,v 1.12.2.8 2013/07/07 20:36:56 mtbishop Exp $
+ */
+
+ #ifndef _VTUN_H
+@@ -51,6 +51,7 @@ struct vtun_sopt {
+ int lport;
+ char *raddr;
+ int rport;
++ char *host;
+ };
+
+ struct vtun_stat {
diff --git a/openlog.patch b/openlog.patch
new file mode 100644
index 000000000000..f8d1644eaaca
--- /dev/null
+++ b/openlog.patch
@@ -0,0 +1,11 @@
+diff -pur vtun-3.0.3.orig/lib.c vtun-3.0.3/lib.c
+--- vtun-3.0.3.orig/lib.c 2014-11-07 12:20:42.853056115 +0300
++++ vtun-3.0.3/lib.c 2014-11-07 12:24:34.997563433 +0300
+@@ -362,6 +362,7 @@ void vtun_syslog (int priority, char *fo
+ vsnprintf(buf, sizeof(buf)-1, format, ap);
+ syslog(priority, "%s", buf);
+ closelog();
++ openlog("vtund", LOG_PID|LOG_NDELAY|LOG_PERROR, vtun.syslog);
+ va_end(ap);
+
+ in_syslog = 0;
diff --git a/tun-cat.c b/tun-cat.c
new file mode 100644
index 000000000000..f6e812d0fc10
--- /dev/null
+++ b/tun-cat.c
@@ -0,0 +1,288 @@
+/*
+Tunnel-cat - Transferring settings through a non-configured IP tunnel.
+
+Copyright (C) 2014 Natrio <natrio@list.ru>
+
+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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <netinet/in.h>
+#include <netpacket/packet.h>
+#include <signal.h>
+
+#define SEND_NUM 4
+#define SEND_INT 250000000 //(nanosec) 0.25 sec
+#define IF_ALIVE 200000 //(microsec) 0.2 sec
+#define DEF_TIMEOUT 10 //sec
+
+#define ROLE argv[1]
+#define INTERFACE argv[2]
+#define PORT atoi(argv[3])
+#define TIMEOUT atoi(argv[4])
+#define ARGP 4
+
+#define IPv (*raw & 0xF0) >> 4
+#define IP_HLEN (size_t)( (*raw & 0x0F) << 2 )
+#define IP_SRC *(u_int32_t*)(raw + 12)
+#define IP_DST *(u_int32_t*)(raw + 16)
+#define IP_PROTO *(raw + 9)
+#define UDP 0x11
+#define UDP_HLEN 8
+#define UDP_DPORT *(uint16_t*)(udp_header + 2)
+#define UDP_SUM *(uint16_t*)(udp_header + 6)
+#define OVERHEAD 28 // min IP+UDP headers size
+
+/* Start of get_sum() */
+uint16_t get_sum(char *hdr, int len, uint16_t *pshdr, int pslen) {
+
+ register int sum;
+ uint16_t answer;
+ register uint16_t *w;
+ register int nleft;
+
+ /*
+ * Our algorithm is simple, using a 32-bit accumulator (sum),
+ * we add sequential 16-bit words to it, and at the end, fold back
+ * all the carry bits from the top 16 bits into the lower 16 bits.
+ */
+
+ sum = 0;
+ w = pshdr;
+ nleft = pslen;
+ while (nleft > 1) {
+ sum += ntohs(*w++);
+ nleft -= 2;
+ }
+
+ w = (uint16_t*)hdr;
+ nleft = len;
+ while (nleft > 1) {
+ sum += ntohs(*w++);
+ nleft -= 2;
+ }
+
+ /* mop up an odd byte, if necessary */
+ answer = 0;
+ if (nleft == 1) {
+ *(u_char *)(&answer) = *(u_char *)w ;
+ sum += ntohs(answer);
+ }
+
+ /* add back carry outs from top 16 bits to low 16 bits */
+ sum = (sum >> 16) + (sum &0xffff); /* add hi 16 to low 16 */
+ sum += (sum >> 16); /* add carry */
+ answer = ~sum; /* truncate to 16 bits */
+ return(htons(answer));
+} /* End of get_sum() */
+
+void usage(void)
+{
+ fprintf( stderr,
+ " Tunnel-cat version 1.5\n"
+ "Transferring settings through a non-configured IP tunnel.\n\n"
+ " Usage:\ntun-cat send <interface> <port> ...\n"
+ "tun-cat listen <interface> <port> [<timeout>]\n" );
+ fclose(stderr);
+ exit(1);
+}
+
+void pr_error(int err, char *errpref)
+{
+ perror(errpref);
+ fclose(stderr);
+ exit(err);
+}
+
+char *net_ifname;
+int countdown;
+
+void net_gone()
+{
+ fprintf(stderr, "Network interface %s was gone\n", net_ifname);
+ fclose(stderr);
+ exit(3);
+}
+
+void alarm_handler(int sig)
+{
+ if(sig==SIGALRM && if_nametoindex(net_ifname)<=0)
+ net_gone();
+
+ if( countdown!=0 && --countdown <= 0)
+ {
+ fprintf(stderr, "The time is out.\n");
+ fclose(stderr);
+ exit(7);
+ }
+}
+
+int get_mtu(int s, char *ifname)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+ if( ioctl(s, SIOCGIFMTU, &ifr) <0 )
+ pr_error(6, "SIOCGIFMTU");
+
+ return ifr.ifr_mtu;
+}
+
+int main(int argc, char **argv)
+{
+ char header[] = "TUNcat";
+ char *msg, *addptr;
+ size_t msglen, added;
+ int i;
+ int true = 1;
+ struct timespec delay = {0,SEND_INT};
+ struct sockaddr_in addr;
+ int sock;
+ int mtu, mmu;
+
+ struct sockaddr_ll hwaddr;
+ char *raw, *data, *udp_header;
+ size_t raw_len, data_len, udp_len, udp_offset;
+ uint16_t udp_sum;
+ struct itimerval timer = { {0,IF_ALIVE}, {0,IF_ALIVE} };
+
+ struct pseudo_h {
+ u_int32_t sIP;
+ u_int32_t dIP;
+ char empty;
+ char proto;
+ uint16_t len;
+ };
+ struct pseudo_h pseudo = {0,0,0,UDP,0};
+
+ net_ifname = INTERFACE;
+
+ if (argc < ARGP) usage();
+
+ if(strcmp(ROLE, "send")==0)
+ {
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if(sock < 0) pr_error(2, "socket");
+
+ if( setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, net_ifname, strlen(net_ifname)) < 0 )
+ pr_error(3, "SO_BINDTODEVICE");
+
+ if( setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &true, sizeof(true)) < 0 )
+ pr_error(4, "SO_BROADCAST");
+
+ mtu = get_mtu(sock, net_ifname);
+ mmu = mtu - OVERHEAD;
+
+ msg = malloc(mmu+1);
+ msglen = sizeof(header);
+ memcpy(msg, header, msglen);
+ addptr = msg + msglen;
+
+ for(i=ARGP; i<argc; i++)
+ {
+ added = strlen(argv[i]) +1;
+ if( msglen + added <= mmu )
+ {
+ sprintf(addptr, "%s\n", argv[i]);
+ addptr += added;
+ msglen += added;
+ }
+ else
+ {
+ fprintf(stderr, "No space left for arg %d : %s\n", i, argv[i]);
+ break;
+ }
+ }
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(PORT);
+ addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
+
+ for(i=0; i < SEND_NUM; i++)
+ {
+ sendto(sock, msg, msglen, 0, (struct sockaddr *)&addr, sizeof(addr) );
+ nanosleep(&delay, NULL);
+ if(if_nametoindex(net_ifname)<=0)
+ net_gone();
+ }
+ free(msg);
+ }
+
+ else if(strcmp(ROLE, "listen")==0)
+ {
+ countdown = ( (argc>ARGP)?TIMEOUT:DEF_TIMEOUT ) * (int)(1000000/IF_ALIVE);
+
+ signal(SIGALRM, alarm_handler);
+ if( setitimer(ITIMER_REAL, &timer, 0) <0 )
+ pr_error(6, "setitimer");
+
+ sock = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL) );
+ if(sock < 0) pr_error(2, "socket");
+
+ memset(&hwaddr, sizeof(hwaddr), 0);
+ hwaddr.sll_family = AF_PACKET;
+ hwaddr.sll_protocol = htons(ETH_P_ALL);
+ if( ( hwaddr.sll_ifindex = if_nametoindex(net_ifname) )<=0 )
+ pr_error(3, "if_nametoindex");
+ if( bind(sock, (struct sockaddr *)&hwaddr, sizeof(hwaddr) ) <0 )
+ pr_error(5, "bind");
+
+ mtu = get_mtu(sock, net_ifname);
+ raw = malloc(mtu+1);
+
+ while(1)
+ {
+ raw_len = recv(sock, raw, mtu, 0);
+
+ if( IPv != 4 || IP_PROTO != UDP || raw_len <= OVERHEAD
+ || ( udp_offset = IP_HLEN ) >= raw_len - UDP_HLEN - sizeof(header) )
+ continue;
+
+ udp_header = raw + udp_offset;
+ udp_len = raw_len - udp_offset;
+ data = udp_header + UDP_HLEN;
+ data_len = udp_len - UDP_HLEN;
+
+ pseudo.sIP = IP_SRC;
+ pseudo.dIP = IP_DST;
+ pseudo.len = htons((uint16_t)udp_len);
+ udp_sum = UDP_SUM;
+ UDP_SUM = 0;
+ if( udp_sum != get_sum(udp_header, udp_len, (uint16_t*)&pseudo, sizeof(pseudo) )
+ || IP_DST != htonl(INADDR_BROADCAST)
+ || UDP_DPORT != htons(PORT) ) continue;
+
+ data[data_len] = '\0';
+ if( strcmp(data, header) != 0 ) continue;
+ printf("%s", data + sizeof(header));
+ fclose(stdout);
+ free(raw);
+ break;
+ }
+ }
+
+ else
+ usage();
+
+ close(sock);
+ return 0;
+}
diff --git a/tun-cfg b/tun-cfg
new file mode 100755
index 000000000000..c6fadf51f63d
--- /dev/null
+++ b/tun-cfg
@@ -0,0 +1,466 @@
+#!/bin/bash
+
+# Tunnel-configurer:
+# Client-server IP tunnel configuration via the same IP tunnel.
+#
+# Copyright (C) 2014 Natrio <natrio@list.ru>
+#
+# 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.
+
+PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+
+[[ "$1" =~ ^(-tun|-h|-help|--help|)$ ]] || exec ifconfig "$@"
+
+# config defaults
+PORT=68
+MTU=1500
+TIMEOUT=10
+CMD=tun-cat
+
+usage() {
+ [[ -n "$1" ]] && return 0
+ echo "Tunnel-configurer version 1.6.1
+ Client-server IP tunnel configuration via the same IP tunnel.
+
+-- vtund.conf --
+ # ifconfig replacement by wrapper
+options {
+ ...
+ #ifconfig /sbin/ifconfig;
+ ifconfig $HELPSTR;
+ ...
+
+ # Usual ifconfig example ($NAME doesn't break it):
+ # On server
+host0 {
+ passwd K@bI\$D0x;
+ up {
+ ifconfig \"%d 10.10.0.1 pointopoint 10.10.8.8\";
+ };
+}
+
+ # On client
+host0 {
+ passwd K@bI\$D0x;
+ up {
+ ifconfig \"%d 10.10.8.8 pointopoint 10.10.0.1\";
+ ip \"route add 10.10.10.0/24 dev %d\";
+ ip \"route add 10.10.0.0/24 dev %d\";
+ };
+}
+
+ # And same one with parameters transmission:
+ # Server example #1, without ${NAME}.conf and names
+host1 {
+ passwd K@bI\$D0x;
+ up {
+ ifconfig \"-tun %d local 10.10.0.1 send 10.10.10.5 10.10.10.0/24 10.10.0.0/24\";
+ };
+}
+
+ # Server example #2, with ${NAME}.conf and client's domain name
+host1 {
+ passwd K@bI\$D0x;
+ up {
+ ifconfig \"-tun %d send host1.vpn\";
+ };
+}
+
+ # Client example, getting all parameters from server
+host1 {
+ passwd K@bI\$D0x;
+ up {
+ ifconfig \"-tun %d get metric 100\";
+ };
+}
+
+-- Common definion's file /etc/${NAME}.conf (useful for server) --
+ # defaults
+PORT=68
+MTU=1500
+TIMEOUT=10
+ # the address of server for all hosts (example)
+LOCAL=server.vpn
+ # routes for sending to clients (example)
+ROUTES='10.10.10.0/24 10.10.0.0/24'
+
+-- Command-line description --
+ifconfig wrapper:
+ $NAME <'ifconfig' options>
+Server:
+ $NAME -tun <interface> send|-s <client_addr> [OPTIONS] [<client-side routes>]
+Client:
+ $NAME -tun <interface> get|-g|listen [OPTIONS] [<'ip route' options>][-6|v6 <options>]
+
+Addresses of client and server may be specified by IP, by name, or by
+ comma-separated list of IPv4,IPv6,names with v4,v6,no4,no6 modifiers.
+ All names will be resolved on server side, and only first IPv4 and IPv6 will be used:
+
+ 10.1.0.1 -> 10.1.0.1
+ 10.1.0.1,fc00::1001:1 -> 10.1.0.1 fc00::1001:1
+ host.vpn -> 10.1.0.4 fc00::1001:4
+ host.vpn,v4 -> 10.1.0.4
+ host.vpn,v6 -> fc00::1001:4
+
+Routes may be specified by IPv4/mask, IPv6/mask,
+ default (for IPv4), defaultv6 or default6 (for IPv6).
+
+OPTIONS:
+ port|-P <port> : default=68
+ mtu|-m <MTU> : default=1500, 0=no change
+forcemtu|+m <MTU> : Don't get MTU from server (client only)
+ local|-l <addr>|-: Force/skip local address (server only)
+ noaddr|-a : Don't modify any IPv4 addresses on interface
+ no6addr|-A : Don't modify any IPv6 addresses on interface
+ nopeer|-p : Don't set peer address (IPv4)
+ peer|+p : Add a route to peer instead of peer address (IPv4)
+noroutes|-r : server - Don't send any routes from config
+ : client - Don't get IPv4 routes from server
+no6routes|-R : Don't get IPv6 routes from server (client only)
+ timeout|-t <sec> : default=10, 0=endless
+ nofork|-B | nobg | nobackground
+
+NOTE:
+ By default, tun-cfg forks to background to prevent vtund from endless waiting
+ for tun-cfg termination, if the connection fails during configuration progress.
+"
+ exit $URET
+}
+
+log() {
+ echo $LPREF "$@" >&2
+}
+
+sec_up() {
+ local garb
+ IFS='. ' read "$1" garb < /proc/uptime
+}
+
+get46() {
+ if [[ -z "$IPv4" && "$1" =~ ^[0-9.]+$ ]] ; then IPv4="$1"
+ elif [[ -z "$IPv6" && "${1,,*}" =~ ^[0-9a-f.:]+$ ]] ; then IPv6="$1"
+ else return 1
+ fi
+ return 0
+}
+
+get_addr() {
+ local addr garb prev IFS skip i
+ [[ -z "$3" ]] && return 1
+ unset IPv4 IPv6
+ IFS=' ,'
+ for i in $3 ; do
+ case "${i,,*}" in
+ 6|v6|ip6|ipv6|no4|'-4') skip=4 ;;
+ 4|v4|ip4|ipv4|no6|'-6') skip=6 ;;
+ *)
+ get46 "$i" && continue
+ while IFS=' ' read addr garb ; do
+ [[ "$addr" = "$prev" ]] && continue
+ get46 "$addr"
+ [[ -n "$IPv4" && -n "$IPv6" ]] && break
+ prev="$addr"
+ done < <(RESOLV_MULTI=on exec getent ahosts "$i")
+ ;;
+ esac
+ done
+ [[ -n "$skip" ]] && unset IPv"$skip"
+
+ if [[ -z "$IPv4" && -z "$IPv6" ]] ; then
+ log "Can't resolve '$3' to $1 address"
+ exit 7
+ fi
+ export "$1=$IPv4" "$2=$IPv6"
+}
+
+set_addr() {
+ if [[ -z "$NOADDR" && -n "$1" ]] ; then
+ [[ -z "$NOPEER" && -n "$peer" ]] && PEER="peer $peer"
+ log $RPREF "address $1" $PEER
+ ip addr rep "$1" $PEER dev "$ifc" || exit 3
+ fi
+ shift
+ if [[ -n "$PLUS" && -n "$peer" ]] ; then
+ log $RPREF "peer route $peer" "$@"
+ ip route rep "$peer" dev "$ifc" "$@" || exit 5
+ fi
+}
+
+set_addr_v6() {
+ if [[ -z "$NO6ADDR" && -n "$1" ]] ; then
+ dis6="/proc/sys/net/ipv6/conf/$ifc/disable_ipv6"
+ [[ -f "$dis6" ]] && echo 0 > "$dis6"
+ log $RPREF "address $1"
+ ip -6 addr rep "$1" dev "$ifc" || exit 3
+ echo 0 > "$dis6"
+ fi
+ shift
+ if [[ -n "$peer_6" ]] ; then
+ log $RPREF "peer route $peer_6" "$@"
+ ip -6 route rep "$peer_6" dev "$ifc" "$@"
+ fi
+}
+
+addsend() {
+ local D LOG send
+ D="$1"
+ shift
+ case "$D" in
+ A4)
+ LOG="$1"
+ [[ -n "$2" ]] && LOG="$LOG peer $2"
+ send="$1:$2"
+ ;;
+ R4)
+ LOG="route $1"
+ send="$1"
+ ;;
+ MTU) LOG="mtu $1" ;;
+ A6) LOG="address $1" ;;
+ R6) LOG="route $1" ;;
+ esac
+ [[ -z "$send" ]] && send="$D:$1"
+ log "-> $LOG"
+ SEND[$((i++))]="$send"
+}
+
+main() {
+ case "$ROLE" in
+ send)
+ unset SEND; i=0
+ if [[ -n "$peer" ]] ; then
+ set_addr "$LOCAL"
+ addsend A4 "$peer" "$LOCAL"
+ fi
+ if [[ -n "$peer_6" ]] ; then
+ set_addr_v6 "$LOCAL6"
+ addsend A6 "$peer_6"
+ [[ -n "$LOCAL6" ]] && addsend R6 "$LOCAL6"
+ fi
+ read MTU < "/sys/class/net/$ifc/mtu"
+ addsend MTU "$MTU"
+ for R in $ROUTES $* ; do
+ [[ "${R,,*}" =~ ^defaultv?6$ ]] && R="::/0"
+ if [[ "$R" =~ : ]] ; then
+ [[ -n "$peer_6" ]] || continue
+ addsend R6 "$R"
+ else
+ [[ -n "$peer" ]] || continue
+ addsend R4 "$R"
+ fi
+ done
+
+ if [[ -n "$peer" ]] ; then
+ ping=ping; P="$peer"
+ elif [[ -n "$peer_6" ]] ; then
+ ping=ping6; P="$peer_6"
+ fi
+ sec_up START
+ log "sending ->"
+ while :; do
+ "$CMD" send "$ifc" "$PORT" "${SEND[@]}" || exit 4
+ "$ping" -q -c1 -W1 -I "$ifc" "$P" &> /dev/null && break
+ sec_up SEC
+ if ((TIMEOUT!=0)) && ((SEC > START+TIMEOUT)) ; then
+ log "Time is out."
+ exit 6
+ fi
+ done
+ log "Confirmed, $P is UP."
+ ;;
+
+ get)
+ if [[ "$*" =~ ^(.* |)(v6|-6)(| .*)$ ]] ; then
+ ROPTSv4="${BASH_REMATCH[1]}"
+ ROPTSv6="${BASH_REMATCH[3]}"
+ else
+ ROPTSv4="$*"
+ ROPTSv6="$*"
+ fi
+
+ RPREF='<-'
+ log "listening" $RPREF
+ exec < <(exec "$CMD" listen "$ifc" "$PORT" "$TIMEOUT")
+
+ FIRST=1
+ while IFS='=,: ' read A B; do
+ if [[ "$A" = A6 ]] ; then
+ set_addr_v6 "$B"
+
+ elif ((FIRST==1)) ; then
+ peer="$B"
+ set_addr "$A" $ROPTSv4
+
+ elif [[ "$A" = MTU && -n "$B" && -z "$FORCEMTU" ]] ; then
+ log $RPREF "mtu $B"
+ ip link set "$ifc" mtu "$B"
+
+ elif [[ "$A" = R6 && -n "$B" && -z "$NO6ROUTES" ]] ; then
+ log $RPREF "route $B" $ROPTSv6
+ ip -6 route rep "$B" dev "$ifc" $ROPTSv6
+
+ elif [[ -n "$A" && -z "$B" && -z "$NOROUTES" ]] ; then
+ log $RPREF "route $A" $ROPTSv4
+ ip route rep "$A" dev "$ifc" $ROPTSv4 || exit 5
+ fi
+ FIRST=0
+ done
+ log "Completed."
+ ;;
+ esac
+ }
+
+FILE=`readlink -f $0`
+FILENAME="${FILE##*/}"
+DIR="${FILE%/*}"
+
+CONFIG=/etc/${FILENAME}.conf
+[[ -f "$CONFIG" ]] && . "$CONFIG"
+
+[[ "$CMD" =~ ^/ ]] || CMD="$DIR/$CMD"
+
+[[ -z "$HELPSTR" ]] && HELPSTR="$FILE"
+NAME="${HELPSTR##*/}"
+
+URET=0
+[[ "$1" != '-tun' ]] && usage
+URET=1
+usage "$2"
+ifc="$2"
+shift 2
+
+unset ROLE PLUS PEER NO6ADDR NOADDR NOPEER FORCEMTU NOBG NOROUTES NO6ROUTES RPREF
+while (($#>0)) ; do
+ case "$1" in
+ -s|send)
+ usage "$2"
+ get_addr peer peer_6 "$2"
+ ROLE="send"
+ shift 2
+ ;;
+
+ -g|get|listen)
+ ROLE="get"
+ shift
+ ;;
+
+ -m|mtu)
+ usage "$2"
+ MTU="$2"
+ shift 2
+ ;;
+
+ +m|forcemtu)
+ usage "$2"
+ MTU="$2"
+ FORCEMTU=1
+ shift 2
+ ;;
+
+ -P|port)
+ usage "$2"
+ PORT="$2"
+ shift 2
+ ;;
+
+ -t|timeout)
+ usage "$2"
+ TIMEOUT="$2"
+ shift 2
+ ;;
+
+ -B|nobg|nobackground|nofork)
+ NOBG=1
+ shift
+ ;;
+
+ -l|local)
+ usage "$2"
+ LOCAL="$2"
+ [[ "$2" = '-' ]] && LOCAL=
+ shift 2
+ ;;
+
+ -a|noaddr)
+ NOADDR=1
+ shift
+ ;;
+
+ -A|no6addr)
+ NO6ADDR=1
+ shift
+ ;;
+
+ +p|peer)
+ NOPEER=1
+ PLUS=1
+ shift
+ ;;
+
+ -p|nopeer)
+ NOPEER=1
+ shift
+ ;;
+
+ -r|noroutes)
+ ROUTES=
+ NOROUTES=1
+ shift
+ ;;
+
+ -R|no6routes)
+ NO6ROUTES=1
+ shift
+ ;;
+
+ *)
+ break
+ ;;
+ esac
+done
+usage "$ROLE"
+
+[[ -z "$TIMEOUT" ]] && TIMEOUT=0
+LPREF="$FILENAME($ifc):"
+fd2="/proc/$$/fd/2"
+if [[ "$(readlink -e $fd2)" =~ ^(/dev/null)|($FILE)$ ]] ; then
+ exec 2>&-
+ exec 2> >(exec logger -t "${LPREF%:}" -p daemon.info)
+ LPREF=
+fi
+
+[[ "$MTU" =~ ^(0|auto)$ ]] && MTU=
+[[ -n "$MTU" ]] && mtu="mtu $MTU" || mtu=
+log "Setting $ifc UP" $mtu
+ip link set "$ifc" up $mtu || exit 2
+
+if [[ "$ROLE" = send ]] ; then
+ get_addr LOCAL LOCAL6 "$LOCAL"
+ [[ -z "$LOCAL" ]] && NOADDR=1
+ [[ -z "$LOCAL6" ]] && NO6ADDR=1
+fi
+
+if [[ -z "$NOADDR" ]] ; then
+ log "flushing IPv4 address"
+ ip -4 addr flush dev "$ifc" || exit 3
+fi
+
+if [[ -z "$NO6ADDR" ]] ; then
+ log "flushing IPv6 address"
+ ip -6 addr flush dev "$ifc" || exit 3
+ ip -6 route flush dev "$ifc"
+fi
+
+if [[ -n "$NOBG" ]] ; then
+ main "$@"
+else
+ main "$@" &
+fi
diff --git a/tun-cfg.conf b/tun-cfg.conf
new file mode 100644
index 000000000000..e915115cbf39
--- /dev/null
+++ b/tun-cfg.conf
@@ -0,0 +1,8 @@
+# defaults
+PORT=68
+MTU=1500
+TIMEOUT=10
+## the address of server for all hosts (example)
+#LOCAL=server.vpn
+## routes for sending to clients (example)
+#ROUTES='10.10.10.0/24 10.10.0.0/24'
diff --git a/vtun.install b/vtun.install
new file mode 100644
index 000000000000..1459f1c4ec90
--- /dev/null
+++ b/vtun.install
@@ -0,0 +1,13 @@
+_news_post() {
+ echo "This package contain the 'tun-cfg' util.
+ It can get client's IP/MTU/routes configuration from server.
+ See 'tun-cfg --help' or /usr/share/doc/vtun/README.tun-cfg"
+}
+
+post_install() {
+ _news_post
+}
+
+post_upgrade() {
+ _news_post
+}
diff --git a/vtund-ipv6-client.conf b/vtund-ipv6-client.conf
new file mode 100644
index 000000000000..df2ca2b90add
--- /dev/null
+++ b/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";
+ };
+}
diff --git a/vtund-ipv6-server.conf b/vtund-ipv6-server.conf
new file mode 100644
index 000000000000..19add65c3de5
--- /dev/null
+++ b/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";
+ };
+}