rfe1744575 - cfg_file.y bugs (mf)

rfe1738167 - build on c5 still fails (bc)
More -kkv cleanup on cvs macros
This commit is contained in:
mtbishop 2007-06-29 05:25:45 +00:00
parent c241ca0b35
commit e971c621d2
44 changed files with 6990 additions and 4 deletions

View File

@ -1,3 +1,7 @@
3.0.2:
rfe1744575 - cfg_file.y bugs (mf)
rfe1738167 - build on c5 still fails (bc)
3.0.1: 3.0.1:
rfe1602625 - fix build for lzo2 (bc,db,ruzsi) rfe1602625 - fix build for lzo2 (bc,db,ruzsi)
rfe780607 - new debian rc scripts (surgo) rfe780607 - new debian rc scripts (surgo)

100
Makefile.in Normal file
View File

@ -0,0 +1,100 @@
#
# VTun - Virtual Tunnel over TCP/IP network.
#
# Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
#
# VTun has been derived from VPPP package by Maxim Krasnyansky.
#
# 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.
#
# $Id: Makefile.in,v 1.11.2.1 2007/06/29 05:26:33 mtbishop Exp $
#
CC = @CC@
CFLAGS = @CFLAGS@ @CPPFLAGS@
LDFLAGS = @LIBS@
YACC = @YACC@
YACCFLAGS = -d
LEX = @LEX@
LEXFLAGS = -t
INSTALL = @INSTALL@
INSTALL_OWNER = -o root -g 0
prefix = @prefix@
exec_prefix = @exec_prefix@
SBIN_DIR = @sbindir@
MAN_DIR = @mandir@
ETC_DIR = @sysconfdir@
VAR_DIR = @localstatedir@
PID_FILE = ${VAR_DIR}/run/vtund.pid
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)\" \
-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 \
llist.o auth.o tunnel.o lock.o netlib.o \
tun_dev.o tap_dev.o pty_dev.o pipe_dev.o \
tcp_proto.o udp_proto.o \
linkfd.o lfd_shaper.o lfd_zlib.o lfd_lzo.o lfd_encrypt.o
CONFIGURE_FILES = Makefile config.status config.cache config.h config.log
%.o: %.c vtun.h lib.h
$(CC) $(CFLAGS) $(DEFS) -c $<
vtund: $(OBJS)
$(CC) $(CFLAGS) -o vtund $(OBJS) $(LFD_OBJS) $(LDFLAGS)
cfg_file.tab.c: cfg_file.y cfg_kwords.h config.h
$(YACC) $(YACCFLAGS) -b cfg_file cfg_file.y
cfg_file.lex.c: cfg_file.l cfg_kwords.h config.h
$(LEX) $(LEXFLAGS) cfg_file.l > cfg_file.lex.c
depend:
makedepend -- $(CFLAGS) -- *.c
clean:
rm -f core cfg_file.tab.* cfg_file.lex.* *.o *~ *.bak vtund
distclean: clean
rm -f $(CONFIGURE_FILES)
rm -f `cat vtun.drivers`
install_man:
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(MAN_DIR)/man8
$(INSTALL) -m 644 $(INSTALL_OWNER) vtund.8 $(DESTDIR)$(MAN_DIR)/man8
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(MAN_DIR)/man5
$(INSTALL) -m 644 $(INSTALL_OWNER) vtund.conf.5 $(DESTDIR)$(MAN_DIR)/man5
rm -f $(DESTDIR)$(MAN_DIR)/man8/vtun.8
ln -s vtund.8 $(DESTDIR)$(MAN_DIR)/man8/vtun.8
install_config:
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(ETC_DIR)
if [ ! -f $(ETC_DIR)/vtund.conf ]; then \
$(INSTALL) -m 600 $(INSTALL_OWNER) vtund.conf $(DESTDIR)$(ETC_DIR); \
fi
install: vtund install_config install_man
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(VAR_DIR)/run
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(STAT_DIR)
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(LOCK_DIR)
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(SBIN_DIR)
$(INSTALL) -m 755 $(INSTALL_OWNER) vtund $(DESTDIR)$(SBIN_DIR)
# DO NOT DELETE THIS LINE -- make depend depends on it.

411
auth.c Normal file
View File

@ -0,0 +1,411 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: auth.c,v 1.9.2.1 2007/06/29 05:25:45 mtbishop Exp $
*/
/*
* Challenge based authentication.
* Thanx to Chris Todd<christ@insynq.com> for the good idea.
*
* Jim Yonan, 05/24/2001
* gen_chal rewrite to use better random number generator
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <syslog.h>
#include <time.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include "vtun.h"
#include "lib.h"
#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>
void gen_chal(char *buf)
{
RAND_bytes(buf, VTUN_CHAL_SIZE);
}
void encrypt_chal(char *chal, char *pwd)
{
register int i;
BF_KEY key;
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);
}
void decrypt_chal(char *chal, char *pwd)
{
register int i;
BF_KEY key;
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_DECRYPT);
}
#else /* HAVE_SSL */
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];
}
void inline decrypt_chal(char *chal, char *pwd)
{
encrypt_chal(chal, pwd);
}
/* Generate PSEUDO random challenge key. */
void gen_chal(char *buf)
{
register int i;
srand(time(NULL));
for(i=0; i < VTUN_CHAL_SIZE; i++)
buf[i] = (unsigned int)(255.0 * rand()/RAND_MAX);
}
#endif /* HAVE_SSL */
/*
* Functions to convert binary flags to character string.
* string format: <CS64>
* C - compression, S - speed for shaper and so on.
*/
char *bf2cf(struct vtun_host *host)
{
static char str[20], *ptr = str;
*(ptr++) = '<';
switch( host->flags & VTUN_PROT_MASK ){
case VTUN_TCP:
*(ptr++) = 'T';
break;
case VTUN_UDP:
*(ptr++) = 'U';
break;
}
switch( host->flags & VTUN_TYPE_MASK ){
case VTUN_TTY:
*(ptr++) = 't';
break;
case VTUN_PIPE:
*(ptr++) = 'p';
break;
case VTUN_ETHER:
*(ptr++) = 'e';
break;
case VTUN_TUN:
*(ptr++) = 'u';
break;
}
if( (host->flags & VTUN_SHAPE) /* && host->spd_in */)
ptr += sprintf(ptr,"S%d",host->spd_in);
if( host->flags & VTUN_ZLIB )
ptr += sprintf(ptr,"C%d", host->zlevel);
if( host->flags & VTUN_LZO )
ptr += sprintf(ptr,"L%d", host->zlevel);
if( host->flags & VTUN_KEEP_ALIVE )
*(ptr++) = 'K';
if( host->flags & VTUN_ENCRYPT )
ptr += sprintf(ptr,"E%d", host->cipher);
strcat(ptr,">");
return str;
}
/* return 1 on success, otherwise 0 */
int cf2bf(char *str, struct vtun_host *host)
{
char *ptr, *p;
int s;
if( (ptr = strchr(str,'<')) ){
ptr++;
while(*ptr){
switch(*ptr++){
case 't':
host->flags |= VTUN_TTY;
break;
case 'p':
host->flags |= VTUN_PIPE;
break;
case 'e':
host->flags |= VTUN_ETHER;
break;
case 'u':
host->flags |= VTUN_TUN;
break;
case 'U':
host->flags &= ~VTUN_PROT_MASK;
host->flags |= VTUN_UDP;
break;
case 'T':
host->flags &= ~VTUN_PROT_MASK;
host->flags |= VTUN_TCP;
break;
case 'K':
host->flags |= VTUN_KEEP_ALIVE;
break;
case 'C':
if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p)
return 0;
host->flags |= VTUN_ZLIB;
host->zlevel = s;
ptr = p;
break;
case 'L':
if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p)
return 0;
host->flags |= VTUN_LZO;
host->zlevel = s;
ptr = p;
break;
case 'E':
if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p)
return 0;
host->flags |= VTUN_ENCRYPT;
host->cipher = s;
ptr = p;
break;
case 'S':
if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p)
return 0;
if( s ){
host->flags |= VTUN_SHAPE;
host->spd_out = s;
}
ptr = p;
break;
case '>':
return 1;
default:
return 0;
}
}
}
return 0;
}
/*
* Functions to convert binary key data to character string.
* string format: <char_data>
*/
char *cl2cs(char *chal)
{
static char str[VTUN_CHAL_SIZE*2+3], *chr="abcdefghijklmnop";
register char *ptr = str;
register int i;
*(ptr++) = '<';
for(i=0; i<VTUN_CHAL_SIZE; i++){
*(ptr++) = chr[ ((chal[i] & 0xf0) >> 4) ];
*(ptr++) = chr[ (chal[i] & 0x0f) ];
}
*(ptr++) = '>';
*ptr = '\0';
return str;
}
int cs2cl(char *str, char *chal)
{
register char *ptr = str;
register int i;
if( !(ptr = strchr(str,'<')) )
return 0;
ptr++;
if( !strtok(ptr,">") || strlen(ptr) != VTUN_CHAL_SIZE*2 )
return 0;
for(i=0; i<VTUN_CHAL_SIZE && *ptr; i++, ptr+=2) {
chal[i] = (*ptr - 'a') << 4;
chal[i] |= *(ptr+1) - 'a';
}
return 1;
}
/* Authentication (Server side) */
struct vtun_host * auth_server(int fd)
{
char chal_req[VTUN_CHAL_SIZE], chal_res[VTUN_CHAL_SIZE];
char buf[VTUN_MESG_SIZE], *str1, *str2;
struct vtun_host *h = NULL;
char *host = NULL;
int stage;
set_title("authentication");
print_p(fd,"VTUN server ver %s\n",VTUN_VER);
stage = ST_HOST;
while( readn_t(fd, buf, VTUN_MESG_SIZE, vtun.timeout) > 0 ){
buf[sizeof(buf)-1]='\0';
strtok(buf,"\r\n");
if( !(str1=strtok(buf," :")) )
break;
if( !(str2=strtok(NULL," :")) )
break;
switch( stage ){
case ST_HOST:
if( !strcmp(str1,"HOST") ){
host = strdup(str2);
gen_chal(chal_req);
print_p(fd,"OK CHAL: %s\n", cl2cs(chal_req));
stage = ST_CHAL;
continue;
}
break;
case ST_CHAL:
if( !strcmp(str1,"CHAL") ){
if( !cs2cl(str2,chal_res) )
break;
if( !(h = find_host(host)) )
break;
decrypt_chal(chal_res, h->passwd);
if( !memcmp(chal_req, chal_res, VTUN_CHAL_SIZE) ){
/* Auth successeful. */
/* Lock host */
if( lock_host(h) < 0 ){
/* Multiple connections are denied */
h = NULL;
break;
}
print_p(fd,"OK FLAGS: %s\n", bf2cf(h));
} else
h = NULL;
}
break;
}
break;
}
if( host )
free(host);
if( !h )
print_p(fd,"ERR\n");
return h;
}
/* Authentication (Client side) */
int auth_client(int fd, struct vtun_host *host)
{
char buf[VTUN_MESG_SIZE], chal[VTUN_CHAL_SIZE];
int stage, success=0 ;
stage = ST_INIT;
while( readn_t(fd, buf, VTUN_MESG_SIZE, vtun.timeout) > 0 ){
buf[sizeof(buf)-1]='\0';
switch( stage ){
case ST_INIT:
if( !strncmp(buf,"VTUN",4) ){
stage = ST_HOST;
print_p(fd,"HOST: %s\n",host->host);
continue;
}
break;
case ST_HOST:
if( !strncmp(buf,"OK",2) && cs2cl(buf,chal)){
stage = ST_CHAL;
encrypt_chal(chal,host->passwd);
print_p(fd,"CHAL: %s\n", cl2cs(chal));
continue;
}
break;
case ST_CHAL:
if( !strncmp(buf,"OK",2) && cf2bf(buf,host) )
success = 1;
break;
}
break;
}
return success;
}

30
auth.h Normal file
View File

@ -0,0 +1,30 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: auth.h,v 1.3.2.1 2007/06/29 05:25:47 mtbishop Exp $
*/
#define VTUN_CHAL_SIZE 16
#define ST_INIT 0
#define ST_HOST 1
#define ST_CHAL 2
struct vtun_host * auth_server(int fd);
int auth_client(int fd, struct vtun_host *host);

195
cfg_file.l Normal file
View File

@ -0,0 +1,195 @@
%{
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: cfg_file.l,v 1.4.2.1 2007/06/29 05:25:49 mtbishop Exp $
*/
#include "config.h"
#include <string.h>
#include "vtun.h"
#include "cfg_file.tab.h"
#include "cfg_kwords.h"
/* static buffer for strings */
char str_buf[255];
int find_keyword(struct kword *kw, char *str);
#define ECHO {;}
#define YY_DECL int yylex(void)
/* Push and pop parser state */
static int stack[16];
static int ptr = 0;
#define PUSH_STATE() \
do { \
if( ptr == 16 ){ \
yyerror("To many pushes to parser's state stack"); \
return K_ERROR; \
} \
stack[ptr++] = YY_START; \
} while(0)
#define POP_STATE() \
do { \
if( !ptr ){ \
yyerror("To many pops from parser's state stack"); \
return K_ERROR; \
} \
BEGIN(stack[--ptr]); \
} while(0)
int cfg_error(const char *ftm, ...);
int yyerror(char *str);
%}
num [0-9]+
dnum {num}:{num}
word [A-Za-z0-9\-\_+=\!\$\#\%\&\*\^\@@\\\~\.]+
wordnm {word}:{num}
kword [A-Za-z0-9\_\-]+
comment \#.*\n
fname [A-Za-z0-9\_\.\-]+
path (\/{fname})+
string \".*\"
%x OPTION PARAM
%%
<*>[ \t] ; /* Skip spaces and tabs (All stages) */
<*>\n { lineno++; } /* (All stages) */
<INITIAL,OPTION>{comment} { lineno++; } /* Skip comments */
{kword} {
int kw = find_keyword(cfg_keyword,yytext);
if( kw != -1 )
return kw;
/* Keyword not found, means host definition. */
yylval.str = yytext;
return K_HOST;
}
{word} {
yylval.str = yytext;
return K_ERROR;
}
<*>\{ {
PUSH_STATE();
BEGIN(OPTION);
return *yytext;
}
<*>\} {
POP_STATE();
return *yytext;
}
<OPTION>{word} {
int kw = find_keyword(cfg_keyword,yytext);
if( kw != -1 ){
/* Option found, switch to PARAM stage */
PUSH_STATE();
BEGIN(PARAM);
return kw;
}
yylval.str = yytext;
return K_ERROR;
}
<PARAM>{string} {
if(yyleng > sizeof(str_buf)-1){
yyerror("string to long");
return 0;
}
strncpy(str_buf, yytext+1, yyleng-2);
str_buf[yyleng-2] = '\0';
yylval.str = str_buf;
return STRING;
}
<PARAM>{dnum} {
char *ptr = strchr(yytext,':') + 1;
yylval.dnum.num1 = atoi(yytext);
yylval.dnum.num2 = atoi(ptr);
return DNUM;
}
<PARAM>{num} {
yylval.num = atoi(yytext);
return NUM;
}
<PARAM>{word} {
int kw = find_keyword(cfg_param,yytext);
if( kw != -1 ){
/* Special parameter found (yes,no,etc) */
yylval.num = kw;
return NUM;
}
yylval.str = yytext;
return WORD;
}
<PARAM>{wordnm} {
char *ptr = strchr(yytext,':'); *ptr='\0';
yylval.dnum.num1 = find_keyword(cfg_param,yytext);
yylval.dnum.num2 = atoi(++ptr);
return DNUM;
}
<PARAM>{path} {
yylval.str = yytext;
return PATH;
}
<PARAM>\; {
POP_STATE();
}
<*>. { /* Garbage (All stages) */
cfg_error("Invalid character \'%s\'", yytext);
}
%%
int yywrap(void)
{
return 1;
}
int find_keyword(struct kword *kw, char *str)
{
while( kw->str ){
if( !strncmp(str,kw->str,20) )
return kw->type;
kw++;
}
return -1;
}

655
cfg_file.y Normal file
View File

@ -0,0 +1,655 @@
%{
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: cfg_file.y,v 1.8.2.1 2007/06/29 05:25:51 mtbishop Exp $
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <syslog.h>
#include "compat.h"
#include "vtun.h"
#include "lib.h"
int lineno = 1;
struct vtun_host *parse_host;
extern struct vtun_host default_host;
llist *parse_cmds;
struct vtun_cmd parse_cmd;
llist host_list;
int cfg_error(const char *fmt, ...);
int add_cmd(llist *cmds, char *prog, char *args, int flags);
void *cp_cmd(void *d, void *u);
int free_cmd(void *d, void *u);
void copy_addr(struct vtun_host *to, struct vtun_host *from);
int free_host(void *d, void *u);
void free_addr(struct vtun_host *h);
void free_host_list(void);
int parse_syslog(char *facility);
int yyparse(void);
int yylex(void);
int yyerror(char *s);
#define YYERROR_VERBOSE 1
%}
%union {
char *str;
int num;
struct { int num1; int num2; } dnum;
}
%expect 20
%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_COMPRESS K_ENCRYPT K_KALIVE K_STAT
%token K_UP K_DOWN K_SYSLOG K_IPROUTE
%token <str> K_HOST K_ERROR
%token <str> WORD PATH STRING
%token <num> NUM
%token <dnum> DNUM
%%
config:
| config statement
;
statement: '\n'
| K_OPTIONS '{' options '}'
| K_DEFAULT {
parse_host = &default_host;
}
'{' host_options '}'
| K_HOST {
if( !(parse_host = malloc(sizeof(struct vtun_host))) ){
yyerror("No memory for the host");
YYABORT;
}
/* Fill new host struct with default values.
* MUST dup strings to be able to reread config.
*/
memcpy(parse_host, &default_host, sizeof(struct vtun_host));
parse_host->host = strdup($1);
parse_host->passwd = NULL;
/* Copy local address */
copy_addr(parse_host, &default_host);
llist_copy(&default_host.up,&parse_host->up,cp_cmd,NULL);
llist_copy(&default_host.down,&parse_host->down,cp_cmd,NULL);
}
'{' host_options '}'
{
/* Check if session definition is complete */
if (!parse_host->passwd) {
cfg_error("Ignored incomplete session definition '%s'", parse_host->host);
free_host(parse_host, NULL);
free(parse_host);
} else {
/* Add host to the list */
llist_add(&host_list, (void *)parse_host);
}
}
| K_ERROR {
cfg_error("Invalid clause '%s'",$1);
YYABORT;
}
;
options:
option
| options option
;
/* Don't override command line options */
option: '\n'
| K_PORT NUM {
if(vtun.bind_addr.port == -1)
vtun.bind_addr.port = $2;
}
| K_BINDADDR '{' bindaddr_option '}'
| K_IFACE STRING {
if(vtun.svr_addr == NULL)
vtun.svr_addr = strdup($2);
}
| K_TYPE NUM {
if(vtun.svr_type == -1)
vtun.svr_type = $2;
}
| K_TIMEOUT NUM {
if(vtun.timeout == -1)
vtun.timeout = $2;
}
| K_PPP PATH {
free(vtun.ppp);
vtun.ppp = strdup($2);
}
| K_IFCFG PATH {
free(vtun.ifcfg);
vtun.ifcfg = strdup($2);
}
| K_ROUTE PATH {
free(vtun.route);
vtun.route = strdup($2);
}
| K_FWALL PATH {
free(vtun.fwall);
vtun.fwall = strdup($2);
}
| K_IPROUTE PATH {
free(vtun.iproute);
vtun.iproute = strdup($2);
}
| K_SYSLOG syslog_opt
| K_ERROR {
cfg_error("Unknown option '%s'",$1);
YYABORT;
}
;
bindaddr_option:
K_ADDR WORD {
vtun.bind_addr.name = strdup($2);
vtun.bind_addr.type = VTUN_ADDR_NAME;
}
| K_IFACE WORD {
vtun.bind_addr.name = strdup($2);
vtun.bind_addr.type = VTUN_ADDR_IFACE;
}
| K_IFACE STRING {
vtun.bind_addr.name = strdup($2);
vtun.bind_addr.type = VTUN_ADDR_IFACE;
}
| K_ERROR {
cfg_error("Unknown option '%s'",$1);
YYABORT;
}
;
syslog_opt:
NUM {
vtun.syslog = $1;
}
| WORD {
if (parse_syslog($1)) {
cfg_error("Unknown syslog facility '%s'", $1);
YYABORT;
}
}
| K_ERROR {
cfg_error("Unknown syslog option '%s'",$1);
YYABORT;
}
;
host_options:
host_option
| host_options host_option
;
/* Host options. Must free strings first, because they
* could be strduped from default_host */
host_option: '\n'
| K_PASSWD WORD {
free(parse_host->passwd);
parse_host->passwd = strdup($2);
}
| K_DEVICE WORD {
free(parse_host->dev);
parse_host->dev = strdup($2);
}
| K_MULTI NUM {
parse_host->multi = $2;
}
| K_TIMEOUT NUM {
parse_host->timeout = $2;
}
| K_SPEED NUM {
if( $2 ){
parse_host->spd_in = parse_host->spd_out = $2;
parse_host->flags |= VTUN_SHAPE;
} else
parse_host->flags &= ~VTUN_SHAPE;
}
| K_SPEED DNUM {
if( yylval.dnum.num1 || yylval.dnum.num2 ){
parse_host->spd_out = yylval.dnum.num1;
parse_host->spd_in = yylval.dnum.num2;
parse_host->flags |= VTUN_SHAPE;
} else
parse_host->flags &= ~VTUN_SHAPE;
}
| K_COMPRESS {
parse_host->flags &= ~(VTUN_ZLIB | VTUN_LZO);
}
compress
| K_ENCRYPT NUM {
if( $2 ){
parse_host->flags |= VTUN_ENCRYPT;
parse_host->cipher = $2;
} else
parse_host->flags &= ~VTUN_ENCRYPT;
}
| K_KALIVE {
parse_host->flags &= ~VTUN_KEEP_ALIVE;
}
keepalive
| K_STAT NUM {
if( $2 )
parse_host->flags |= VTUN_STAT;
else
parse_host->flags &= ~VTUN_STAT;
}
| K_PERSIST NUM {
parse_host->persist = $2;
if(vtun.persist == -1)
vtun.persist = $2;
}
| K_TYPE NUM {
parse_host->flags &= ~VTUN_TYPE_MASK;
parse_host->flags |= $2;
}
| K_PROT NUM {
parse_host->flags &= ~VTUN_PROT_MASK;
parse_host->flags |= $2;
}
| K_SRCADDR '{' srcaddr_options '}'
| K_UP {
parse_cmds = &parse_host->up;
llist_free(parse_cmds, free_cmd, NULL);
} '{' command_options '}'
| K_DOWN {
parse_cmds = &parse_host->down;
llist_free(parse_cmds, free_cmd, NULL);
} '{' command_options '}'
| K_ERROR {
cfg_error("Unknown option '%s'",$1);
YYABORT;
}
;
compress:
NUM {
if( $1 ){
parse_host->flags |= VTUN_ZLIB;
parse_host->zlevel = $1;
}
}
| DNUM {
parse_host->flags |= yylval.dnum.num1;
parse_host->zlevel = yylval.dnum.num2;
}
| K_ERROR {
cfg_error("Unknown compression '%s'",$1);
YYABORT;
}
;
keepalive:
NUM {
if( $1 )
parse_host->flags |= VTUN_KEEP_ALIVE;
}
| DNUM {
if( yylval.dnum.num1 ){
parse_host->flags |= VTUN_KEEP_ALIVE;
parse_host->ka_interval = yylval.dnum.num1;
parse_host->ka_failure = yylval.dnum.num2;
}
}
| K_ERROR {
cfg_error("Unknown keepalive option '%s'",$1);
YYABORT;
}
;
srcaddr_options: /* empty */
| srcaddr_option
| srcaddr_options srcaddr_option
;
srcaddr_option:
K_ADDR WORD {
free_addr(parse_host);
parse_host->src_addr.name = strdup($2);
parse_host->src_addr.type = VTUN_ADDR_NAME;
}
| K_IFACE WORD {
free_addr(parse_host);
parse_host->src_addr.name = strdup($2);
parse_host->src_addr.type = VTUN_ADDR_IFACE;
}
| K_IFACE STRING {
free_addr(parse_host);
parse_host->src_addr.name = strdup($2);
parse_host->src_addr.type = VTUN_ADDR_IFACE;
}
| K_PORT NUM {
parse_host->src_addr.port = $2;
}
| K_ERROR {
cfg_error("Unknown option '%s'",$1);
YYABORT;
}
;
command_options: /* empty */
| command_option
| command_options command_option
;
command_option: '\n'
| K_PROG {
memset(&parse_cmd, 0, sizeof(struct vtun_cmd));
}
prog_options {
add_cmd(parse_cmds, parse_cmd.prog,
parse_cmd.args, parse_cmd.flags);
}
| K_PPP STRING {
add_cmd(parse_cmds, strdup(vtun.ppp), strdup($2),
VTUN_CMD_DELAY);
}
| K_IFCFG STRING {
add_cmd(parse_cmds, strdup(vtun.ifcfg),strdup($2),
VTUN_CMD_WAIT);
}
| K_ROUTE STRING {
add_cmd(parse_cmds, strdup(vtun.route),strdup($2),
VTUN_CMD_WAIT);
}
| K_FWALL STRING {
add_cmd(parse_cmds, strdup(vtun.fwall),strdup($2),
VTUN_CMD_WAIT);
}
| K_IPROUTE STRING {
add_cmd(parse_cmds, strdup(vtun.iproute),strdup($2),
VTUN_CMD_WAIT);
}
| K_ERROR {
cfg_error("Unknown cmd '%s'",$1);
YYABORT;
}
;
prog_options:
prog_option
| prog_options prog_option
;
prog_option:
PATH {
parse_cmd.prog = strdup($1);
}
| STRING {
parse_cmd.args = strdup($1);
}
| NUM {
parse_cmd.flags = $1;
}
;
%%
int yyerror(char *s)
{
vtun_syslog(LOG_ERR, "%s line %d\n", s, lineno);
return 0;
}
int cfg_error(const char *fmt, ...)
{
char buf[255];
va_list ap;
/* print the argument string */
va_start(ap, fmt);
vsnprintf(buf,sizeof(buf),fmt,ap);
va_end(ap);
yyerror(buf);
return 0;
}
int add_cmd(llist *cmds, char *prog, char *args, int flags)
{
struct vtun_cmd *cmd;
if( !(cmd = malloc(sizeof(struct vtun_cmd))) ){
yyerror("No memory for the command");
return -1;
}
memset(cmd, 0, sizeof(struct vtun_cmd));
cmd->prog = prog;
cmd->args = args;
cmd->flags = flags;
llist_add(cmds, cmd);
return 0;
}
void *cp_cmd(void *d, void *u)
{
struct vtun_cmd *cmd = d, *cmd_copy;
if( !(cmd_copy = malloc(sizeof(struct vtun_cmd))) ){
yyerror("No memory to copy the command");
return NULL;
}
cmd_copy->prog = strdup(cmd->prog);
cmd_copy->args = strdup(cmd->args);
cmd_copy->flags = cmd->flags;
return cmd_copy;
}
int free_cmd(void *d, void *u)
{
struct vtun_cmd *cmd = d;
free(cmd->prog);
free(cmd->args);
free(cmd);
return 0;
}
void copy_addr(struct vtun_host *to, struct vtun_host *from)
{
if( from->src_addr.type ){
to->src_addr.type = from->src_addr.type;
to->src_addr.name = strdup(from->src_addr.name);
}
to->src_addr.port = from->src_addr.port;
}
void free_addr(struct vtun_host *h)
{
if( h->src_addr.type ){
h->src_addr.type = 0;
free(h->src_addr.name);
}
}
int free_host(void *d, void *u)
{
struct vtun_host *h = d;
if (u && !strcmp(h->host, u))
return 1;
free(h->host);
free(h->passwd);
llist_free(&h->up, free_cmd, NULL);
llist_free(&h->down, free_cmd, NULL);
free_addr(h);
return 0;
}
/* Find host in the hosts list.
* NOTE: This function can be called only once since it deallocates hosts list.
*/
inline struct vtun_host* find_host(char *host)
{
return (struct vtun_host *)llist_free(&host_list, free_host, host);
}
inline void free_host_list(void)
{
llist_free(&host_list, free_host, NULL);
}
static struct {
char *c_name;
int c_val;
} syslog_names[] = {
{ "auth", LOG_AUTH },
{ "cron", LOG_CRON },
{ "daemon", LOG_DAEMON },
{ "kern", LOG_KERN },
{ "lpr", LOG_LPR },
{ "mail", LOG_MAIL },
{ "news", LOG_NEWS },
{ "syslog", LOG_SYSLOG },
{ "user", LOG_USER },
{ "uucp", LOG_UUCP },
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
{ NULL, -1 }
};
int parse_syslog(char *facility)
{
int i;
for (i=0; syslog_names[i].c_name;i++) {
if (!strcmp(syslog_names[i].c_name, facility)) {
vtun.syslog = syslog_names[i].c_val;
return(0);
}
}
return -1;
}
/*
* Read config file.
*/
int read_config(char *file)
{
static int cfg_loaded = 0;
extern FILE *yyin;
if( cfg_loaded ){
free_host_list();
vtun_syslog(LOG_INFO,"Reloading configuration file");
}
cfg_loaded = 1;
llist_init(&host_list);
if( !(yyin = fopen(file,"r")) ){
vtun_syslog(LOG_ERR,"Can not open %s", file);
return -1;
}
yyparse();
free_host(&default_host, NULL);
fclose(yyin);
return !llist_empty(&host_list);
}

102
cfg_kwords.h Normal file
View File

@ -0,0 +1,102 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: cfg_kwords.h,v 1.6.2.1 2007/06/29 05:25:53 mtbishop Exp $
*/
extern int lineno;
struct kword {
char *str;
int type;
};
struct kword cfg_keyword[] = {
{ "options", K_OPTIONS },
{ "default", K_DEFAULT },
{ "up", K_UP },
{ "down", K_DOWN },
{ "port", K_PORT },
{ "srcaddr", K_SRCADDR },
{ "addr", K_ADDR },
{ "iface", K_IFACE },
{ "bindaddr", K_BINDADDR },
{ "persist", K_PERSIST },
{ "multi", K_MULTI },
{ "iface", K_IFACE },
{ "timeout", K_TIMEOUT },
{ "passwd", K_PASSWD },
{ "password", K_PASSWD },
{ "program", K_PROG },
{ "speed", K_SPEED },
{ "compress", K_COMPRESS },
{ "encrypt", K_ENCRYPT },
{ "type", K_TYPE },
{ "proto", K_PROT },
{ "device", K_DEVICE },
{ "ppp", K_PPP },
{ "ifconfig", K_IFCFG },
{ "ifcfg", K_IFCFG },
{ "firewall", K_FWALL },
{ "route", K_ROUTE },
{ "ip", K_IPROUTE },
{ "keepalive",K_KALIVE },
{ "stat", K_STAT },
{ "syslog", K_SYSLOG },
{ NULL , 0 }
};
struct kword cfg_param[] = {
{ "yes", 1 },
{ "no", 0 },
{ "allow", 1 },
{ "deny", 0 },
{ "enable", 1 },
{ "disable", 0 },
{ "tty", VTUN_TTY },
{ "pipe", VTUN_PIPE },
{ "ether", VTUN_ETHER },
{ "tun", VTUN_TUN },
{ "tcp", VTUN_TCP },
{ "udp", VTUN_UDP },
{ "lzo", VTUN_LZO },
{ "zlib", VTUN_ZLIB },
{ "wait", 1 },
{ "killold", VTUN_MULTI_KILL },
{ "inetd", VTUN_INETD },
{ "stand", VTUN_STAND_ALONE },
{ "keep", VTUN_PERSIST_KEEPIF },
{ "blowfish128ecb", VTUN_ENC_BF128ECB },
{ "blowfish128cbc", VTUN_ENC_BF128CBC },
{ "blowfish128cfb", VTUN_ENC_BF128CFB },
{ "blowfish128ofb", VTUN_ENC_BF128OFB },
{ "blowfish256ecb", VTUN_ENC_BF256ECB },
{ "blowfish256cbc", VTUN_ENC_BF256CBC },
{ "blowfish256cfb", VTUN_ENC_BF256CFB },
{ "blowfish256ofb", VTUN_ENC_BF256OFB },
{ "aes128ecb", VTUN_ENC_AES128ECB },
{ "aes128cbc", VTUN_ENC_AES128CBC },
{ "aes128cfb", VTUN_ENC_AES128CFB },
{ "aes128ofb", VTUN_ENC_AES128OFB },
{ "aes256ecb", VTUN_ENC_AES256ECB },
{ "aes256cbc", VTUN_ENC_AES256CBC },
{ "aes256cfb", VTUN_ENC_AES256CFB },
{ "aes256ofb", VTUN_ENC_AES256OFB },
{ NULL , 0 }
};

154
client.c Normal file
View File

@ -0,0 +1,154 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: client.c,v 1.11.2.1 2007/06/29 05:25:57 mtbishop Exp $
*/
#include "config.h"
#include "vtun_socks.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <syslog.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include "vtun.h"
#include "lib.h"
#include "llist.h"
#include "auth.h"
#include "compat.h"
#include "netlib.h"
static volatile sig_atomic_t client_term;
static void sig_term(int sig)
{
vtun_syslog(LOG_INFO,"Terminated");
client_term = VTUN_SIG_TERM;
}
void client(struct vtun_host *host)
{
struct sockaddr_in my_addr,svr_addr;
struct sigaction sa;
int s, opt, reconnect;
vtun_syslog(LOG_INFO,"VTun client ver %s started",VTUN_VER);
memset(&sa,0,sizeof(sa));
sa.sa_handler=SIG_IGN;
sa.sa_flags = SA_NOCLDWAIT;
sigaction(SIGHUP,&sa,NULL);
sigaction(SIGQUIT,&sa,NULL);
sigaction(SIGPIPE,&sa,NULL);
sigaction(SIGCHLD,&sa,NULL);
sa.sa_handler=sig_term;
sigaction(SIGTERM,&sa,NULL);
sigaction(SIGINT,&sa,NULL);
client_term = 0; reconnect = 0;
while( (!client_term) || (client_term == VTUN_SIG_HUP) ){
if( reconnect && (client_term != VTUN_SIG_HUP) ){
if( vtun.persist || host->persist ){
/* Persist mode. Sleep and reconnect. */
sleep(5);
} else {
/* Exit */
break;
}
} else {
reconnect = 1;
}
set_title("%s init initializing", host->host);
/* Set server address */
if( server_addr(&svr_addr, host) < 0 )
continue;
/* Set local address */
if( local_addr(&my_addr, host, 0) < 0 )
continue;
/* We have to create socket again every time
* we want to connect, since STREAM sockets
* can be successfully connected only once.
*/
if( (s = socket(AF_INET,SOCK_STREAM,0))==-1 ){
vtun_syslog(LOG_ERR,"Can't create socket. %s(%d)",
strerror(errno), errno);
continue;
}
/* Required when client is forced to bind to specific port */
opt=1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if( bind(s,(struct sockaddr *)&my_addr,sizeof(my_addr)) ){
vtun_syslog(LOG_ERR,"Can't bind socket. %s(%d)",
strerror(errno), errno);
continue;
}
/*
* Clear speed and flags which will be supplied by server.
*/
host->spd_in = host->spd_out = 0;
host->flags &= VTUN_CLNT_MASK;
io_init();
set_title("%s connecting to %s", host->host, vtun.svr_name);
vtun_syslog(LOG_INFO,"Connecting to %s", vtun.svr_name);
if( connect_t(s,(struct sockaddr *) &svr_addr, host->timeout) ){
vtun_syslog(LOG_INFO,"Connect to %s failed. %s(%d)", vtun.svr_name,
strerror(errno), errno);
} else {
if( auth_client(s, 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);
vtun_syslog(LOG_INFO,"Session %s[%s] closed",host->host,vtun.svr_name);
} else {
vtun_syslog(LOG_INFO,"Connection denied by %s",vtun.svr_name);
}
}
close(s);
free_sopt(&host->sopt);
}
vtun_syslog(LOG_INFO, "Exit");
return;
}

33
compat.h Normal file
View File

@ -0,0 +1,33 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: compat.h,v 1.3.2.1 2007/06/29 05:25:59 mtbishop Exp $
*/
#ifndef _VTUN_COMPAT_H
#define _VTUN_COMPAT_H
#ifndef LOG_PERROR
#define LOG_PERROR 0
#endif
#ifndef SA_NOCLDWAIT
#define SA_NOCLDWAIT 0
#endif
#endif /* _VTUN_COMPAT_H */

268
configure.in Normal file
View File

@ -0,0 +1,268 @@
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.1 2007/06/29 05:26:01 mtbishop Exp $
dnl
dnl Process this file with autoconf to produce a configure script.
dnl
AC_INIT(lib.c)
AC_CONFIG_HEADER(config.h)
dnl Shapper support
AC_ARG_ENABLE(shaper,
--disable-shaper Don not compile shaper module,
SHAPER=$enableval,
SHAPER=yes
)
dnl Encryption support
AC_ARG_ENABLE(ssl,
--disable-ssl Don not compile encryption module,
SSL=$enableval,
SSL=yes
)
dnl ZLIB support
AC_ARG_ENABLE(zlib,
--disable-zlib Don not compile ZLIB compression module,
ZLIB=$enableval,
ZLIB=yes
)
dnl LZO support
AC_ARG_ENABLE(lzo,
--disable-lzo Don not compile LZO compression module,
LZO=$enableval,
LZO=yes
)
dnl SOCKS support
AC_ARG_ENABLE(socks,
--enable-socks Compile with SOCKS support,
SOCKS=$enableval,
SOCKS=no
)
AC_ARG_WITH(ssl-headers,
--with-ssl-headers=DIR Crypto Include files location,
SSL_HDR_DIR="$withval"
CPPFLAGS="$CPPFLAGS -I$withval"
)
AC_ARG_WITH(ssl-lib,
--with-ssl-lib=DIR Crypto Library location,
LIBS="$LIBS -L$withval"
)
AC_ARG_WITH(lzo-headers,
--with-lzo-headers=DIR LZO Include files location,
LZO_HDR_DIR="$withval"
)
AC_ARG_WITH(lzo-lib,
--with-lzo-lib=DIR LZO Library location,
LIBS="$LIBS -L$withval"
)
AC_ARG_WITH(blowfish-headers,
--with-blowfish-headers=DIR Blowfish Include files location,
BLOWFISH_HDR_DIR="$withval"
)
AC_ARG_WITH(socks-lib,
--with-socks-lib=DIR SOCKS Library location,
LIBS="$LIBS -L$withval"
)
dnl Guess host type.
AC_CANONICAL_HOST
AC_CANONICAL_SYSTEM
dnl Check for programs.
AC_PROG_YACC
AC_PROG_LEX
AC_PROG_CC
AC_PROG_INSTALL
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
dnl Check for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(sys/resource.h netdb.h sched.h resolv.h arpa/inet.h)
AC_CHECK_HEADERS(netinet/ip.h netinet/in.h netinet/tcp.h netinet/in_systm.h)
AC_CHECK_HEADERS(libutil.h sys/sockio.h)
dnl Check for libsocket
AC_SEARCH_LIBS(socket, socket)
dnl Check for libnsl
AC_SEARCH_LIBS(inet_ntoa, nsl)
dnl Check for libresolv
AC_SEARCH_LIBS(gethostbyname, resolv nsl)
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) )
if test "$SHAPER" = "yes"; then
AC_DEFINE(HAVE_SHAPER)
fi
if test "$ZLIB" = "yes"; then
AC_MSG_RESULT()
AC_CHECKING( for ZLIB Library and Header files ... )
AC_CHECK_LIB(z, deflate,
LIBS="$LIBS -lz"
AC_DEFINE(HAVE_ZLIB),
AC_MSG_ERROR( Zlib library not found.)
)
fi
dnl very servicable code borrowed heavily from openvpn.
if test "$LZO" = "yes"; then
LZOCHK=""
AC_MSG_RESULT()
AC_CHECKING( for LZO Library and Header files ... )
AC_SEARCH_HEADERS(lzo_asm.h,
$LZO_HDR_DIR /usr/include/lzo "" /usr/local/include,
LZOCHK="lzo2 lzo",
AC_SEARCH_HEADERS(lzo1x.h,
$LZO_HDR_DIR /usr/include/lzo "" /usr/local/include,
LZOCHK="lzo",
AC_MSG_ERROR( LZO library not found. )
)
)
if test -n "$LZOCHK"; then
havelzo=0;
for I in $LZOCHK ; do
if test $havelzo = 0; then
AC_CHECK_LIB($I, lzo1x_decompress,
[
LIBS="$LIBS -l"$I
AC_DEFINE(HAVE_LZO)
havelzo=1
]
)
fi
done
if test $havelzo = 0; then
AC_MSG_ERROR( LZO library not found. )
fi
else
AC_MSG_ERROR( LZO headers not found. )
fi
fi
if test "$SSL" = "yes"; then
AC_MSG_RESULT()
AC_CHECKING( for md5 Library and Header files ... )
AC_SEARCH_HEADERS(md5.h,
$SSL_HDR_DIR /usr/include/openssl "" /usr/include /usr/include/ssl /usr/local/include /usr/local/ssl/include /usr/include/sys,
,
AC_MSG_ERROR( SSL headers not found. )
)
fi
if test "$SSL" = "yes"; then
AC_MSG_RESULT()
AC_CHECKING( for blowfish Library and Header files ... )
AC_SEARCH_HEADERS(blowfish.h,
$BLOWFISH_HDR_DIR /usr/include/ssl /usr/include/openssl /usr/include /usr/local/include /usr/local/ssl/include /usr/include/crypto,
AC_CHECK_LIB(crypto, BF_set_key,
[
LIBS="$LIBS -lcrypto"
AC_DEFINE(HAVE_SSL)
AC_DEFINE(HAVE_SSL_BLOWFISH)
],
AC_MSG_ERROR( SSL library not found. )
),
AC_MSG_ERROR( SSL headers not found. )
)
fi
if test "$SSL" = "yes"; then
AC_MSG_RESULT()
AC_CHECKING( for AES Library and Header files ... )
AC_SEARCH_HEADERS(aes.h,
$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_MSG_ERROR( AES library not found. )
),
AC_MSG_ERROR( AES headers not found. )
)
fi
if test "$SSL" = "yes"; then
AC_MSG_RESULT()
AC_CHECKING( for EVP Library and Header files ... )
AC_SEARCH_HEADERS(evp.h,
$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_MSG_ERROR( EVP library not found. )
),
AC_MSG_ERROR( EVP headers not found. )
)
fi
if test "$SOCKS" = "yes"; then
AC_MSG_RESULT()
AC_CHECKING( for SOCKS Library ... )
AC_CHECK_LIB(socks5, SOCKSconnect,
[
CFLAGS="$CFLAGS -DVTUN_SOCKS=1"
LIBS="$LIBS -lsocks5"
],
AC_CHECK_LIB(socks, Rconnect,
[
CFLAGS="$CFLAGS -DVTUN_SOCKS=2"
LIBS="$LIBS -lsocks"
],
AC_MSG_ERROR( SOCKS library not found. )
)
)
fi
AC_MSG_RESULT()
AC_CHECK_FUNCS([getpt grantpt unlockpt ptsname])
OS_REL=`uname -r | tr -d '[A-Za-z\-\_\.]'`
case $host_os in
*linux*)
OS_DIR="linux"
AC_CHECK_HEADERS(linux/if_tun.h)
;;
*solaris*)
OS_DIR="svr4"
;;
*freebsd*)
if test "$OS_REL" -ge "40"; then
OS_DIR="freebsd"
fi
;;
*openbsd*)
if test "$OS_REL" -ge "25"; then
OS_DIR="openbsd"
fi
;;
esac
AC_LINK_DRV(`cat vtun.drivers`, $OS_DIR)
AC_MSG_RESULT()
dnl Build release name
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_OUTPUT(Makefile)

60
driver.h Normal file
View File

@ -0,0 +1,60 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: driver.h,v 1.4.2.1 2007/06/29 05:26:03 mtbishop Exp $
*/
#ifndef _DRIVER_H
#define _DRIVER_H
/* Definitions for device and protocol drivers
* Interface will be completely rewritten in
* version 3.0
*/
extern int (*dev_write)(int fd, char *buf, int len);
extern int (*dev_read)(int fd, char *buf, int len);
extern int (*proto_write)(int fd, char *buf, int len);
extern int (*proto_read)(int fd, char *buf);
int tun_open(char *dev);
int tun_close(int fd, char *dev);
int tun_write(int fd, char *buf, int len);
int tun_read(int fd, char *buf, int len);
int tap_open(char *dev);
int tap_close(int fd, char *dev);
int tap_write(int fd, char *buf, int len);
int tap_read(int fd, char *buf, int len);
int pty_open(char *dev);
int pty_write(int fd, char *buf, int len);
int pty_read(int fd, char *buf, int len);
int pipe_open(int *fd);
int pipe_write(int fd, char *buf, int len);
int pipe_read(int fd, char *buf, int len);
int tcp_write(int fd, char *buf, int len);
int tcp_read(int fd, char *buf);
int udp_write(int fd, char *buf, int len);
int udp_read(int fd, char *buf);
#endif

83
freebsd/tun_dev.c Normal file
View File

@ -0,0 +1,83 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: tun_dev.c,v 1.5.2.1 2007/06/29 05:26:53 mtbishop Exp $
*/
#include "config.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <sys/ioctl.h>
#include <net/if_tun.h>
#include "vtun.h"
#include "lib.h"
/*
* Allocate TUN device, returns opened fd.
* Stores dev name in the first arg(must be large enough).
*/
int tun_open(char *dev)
{
char tunname[14];
int i, fd = -1;
if( *dev ){
sprintf(tunname, "/dev/%s", dev);
fd = open(tunname, O_RDWR);
} else {
for(i=0; i < 255; i++){
sprintf(tunname, "/dev/tun%d", i);
/* Open device */
if( (fd=open(tunname, O_RDWR)) > 0 ){
sprintf(dev, "tun%d", i);
break;
}
}
}
if( fd > -1 ){
i=0;
/* Disable extended modes */
ioctl(fd, TUNSLMODE, &i);
ioctl(fd, TUNSIFHEAD, &i);
}
return fd;
}
int tun_close(int fd, char *dev)
{
return close(fd);
}
/* Read/write frames from/to TUN device */
int tun_write(int fd, char *buf, int len)
{
return write(fd, buf, len);
}
int tun_read(int fd, char *buf, int len)
{
return read(fd, buf, len);
}

54
generic/pipe_dev.c Normal file
View File

@ -0,0 +1,54 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: pipe_dev.c,v 1.4.2.1 2007/06/29 05:26:55 mtbishop Exp $
*/
#include "config.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <sys/socket.h>
#include "vtun.h"
#include "lib.h"
/*
* Create pipe. Return open fd.
*/
int pipe_open(int *fd)
{
return socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
}
/* Write frames to pipe */
int pipe_write(int fd, char *buf, int len)
{
return write_n(fd, buf, len);
}
/* Read frames from pipe */
int pipe_read(int fd, char *buf, int len)
{
return read(fd, buf, len);
}

96
generic/pty_dev.c Normal file
View File

@ -0,0 +1,96 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: pty_dev.c,v 1.4.2.1 2007/06/29 05:26:57 mtbishop Exp $
*/
#include "config.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include "vtun.h"
#include "lib.h"
/*
* Allocate pseudo tty, returns master side fd.
* Stores slave name in the first arg(must be large enough).
*/
int pty_open(char *sl_name)
{
int mr_fd;
#if defined (HAVE_GETPT) && defined (HAVE_GRANTPT) && defined (HAVE_UNLOCKPT) && defined (HAVE_PTSNAME)
char *ptyname;
if((mr_fd=getpt()) < 0)
return -1;
if(grantpt(mr_fd) != 0)
return -1;
if(unlockpt(mr_fd) != 0)
return -1;
if ((ptyname = (char*)ptsname(mr_fd)) == NULL)
return -1;
strcpy(sl_name, ptyname);
return mr_fd;
#else
char ptyname[] = "/dev/ptyXY";
char ch[] = "pqrstuvwxyz";
char digit[] = "0123456789abcdefghijklmnopqrstuv";
int l, m;
/* 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;
/* Check the slave */
ptyname[5] = 't';
if( (access(ptyname, R_OK | W_OK)) < 0 ){
close(mr_fd);
ptyname[5] = 'p';
continue;
}
strcpy(sl_name,ptyname);
return mr_fd;
}
}
return -1;
#endif
}
/* Write frames to PTY device */
int pty_write(int fd, char *buf, int len)
{
return write_n(fd, buf, len);
}
/* Read frames from PTY device */
int pty_read(int fd, char *buf, int len)
{
return read(fd, buf, len);
}

75
generic/tap_dev.c Normal file
View File

@ -0,0 +1,75 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: tap_dev.c,v 1.5.2.1 2007/06/29 05:26:59 mtbishop Exp $
*/
#include "config.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include "vtun.h"
#include "lib.h"
/*
* Allocate Ether TAP device, returns opened fd.
* Stores dev name in the first arg(must be large enough).
*/
int tap_open(char *dev)
{
char tapname[14];
int i, fd;
if( *dev ) {
sprintf(tapname, "/dev/%s", dev);
return open(tapname, O_RDWR);
}
for(i=0; i < 255; i++) {
sprintf(tapname, "/dev/tap%d", i);
/* Open device */
if( (fd=open(tapname, O_RDWR)) > 0 ) {
sprintf(dev, "tap%d",i);
return fd;
}
}
return -1;
}
int tap_close(int fd, char *dev)
{
return close(fd);
}
/* Write frames to TAP device */
int tap_write(int fd, char *buf, int len)
{
return write(fd, buf, len);
}
/* Read frames from TAP device */
int tap_read(int fd, char *buf, int len)
{
return read(fd, buf, len);
}

99
generic/tcp_proto.c Normal file
View File

@ -0,0 +1,99 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: tcp_proto.c,v 1.7.2.1 2007/06/29 05:27:02 mtbishop Exp $
*/
#include "config.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <errno.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#include "vtun.h"
#include "lib.h"
int tcp_write(int fd, char *buf, int len)
{
register char *ptr;
ptr = buf - sizeof(short);
*((unsigned short *)ptr) = htons(len);
len = (len & VTUN_FSIZE_MASK) + sizeof(short);
return write_n(fd, ptr, len);
}
int tcp_read(int fd, char *buf)
{
unsigned short len, flen;
register int rlen;
/* Read frame size */
if( (rlen = read_n(fd, (char *)&len, sizeof(short)) ) <= 0)
return rlen;
len = ntohs(len);
flen = len & VTUN_FSIZE_MASK;
if( flen > VTUN_FRAME_SIZE + VTUN_FRAME_OVERHEAD ){
/* Oversized frame, drop it. */
while( flen ){
len = min(flen, VTUN_FRAME_SIZE);
if( (rlen = read_n(fd, buf, len)) <= 0 )
break;
flen -= rlen;
}
return VTUN_BAD_FRAME;
}
if( len & ~VTUN_FSIZE_MASK ){
/* Return flags */
return len;
}
/* Read frame */
return read_n(fd, buf, flen);
}

74
generic/tun_dev.c Normal file
View File

@ -0,0 +1,74 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: tun_dev.c,v 1.5.2.1 2007/06/29 05:27:06 mtbishop Exp $
*/
#include "config.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include "vtun.h"
#include "lib.h"
/*
* Allocate TUN device, returns opened fd.
* Stores dev name in the first arg(must be large enough).
*/
int tun_open(char *dev)
{
char tunname[14];
int i, fd;
if( *dev ) {
sprintf(tunname, "/dev/%s", dev);
return open(tunname, O_RDWR);
}
for(i=0; i < 255; i++){
sprintf(tunname, "/dev/tun%d", i);
/* Open device */
if( (fd=open(tunname, O_RDWR)) > 0 ){
sprintf(dev, "tun%d", i);
return fd;
}
}
return -1;
}
int tun_close(int fd, char *dev)
{
return close(fd);
}
/* Read/write frames from TUN device */
int tun_write(int fd, char *buf, int len)
{
return write(fd, buf, len);
}
int tun_read(int fd, char *buf, int len)
{
return read(fd, buf, len);
}

111
generic/udp_proto.c Normal file
View File

@ -0,0 +1,111 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: udp_proto.c,v 1.10.2.1 2007/06/29 05:27:09 mtbishop Exp $
*/
#include "config.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <errno.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/udp.h>
#endif
#include "vtun.h"
#include "lib.h"
/* Functions to read/write UDP frames. */
int udp_write(int fd, char *buf, int len)
{
register char *ptr;
register int wlen;
ptr = buf - sizeof(short);
*((unsigned short *)ptr) = htons(len);
len = (len & VTUN_FSIZE_MASK) + sizeof(short);
while( 1 ){
if( (wlen = write(fd, ptr, len)) < 0 ){
if( errno == EAGAIN || errno == EINTR )
continue;
if( errno == ENOBUFS )
return 0;
}
/* Even if we wrote only part of the frame
* we can't use second write since it will produce
* another UDP frame */
return wlen;
}
}
int udp_read(int fd, char *buf)
{
unsigned short hdr, flen;
struct iovec iv[2];
register int rlen;
/* Read frame */
iv[0].iov_len = sizeof(short);
iv[0].iov_base = (char *) &hdr;
iv[1].iov_len = VTUN_FRAME_SIZE + VTUN_FRAME_OVERHEAD;
iv[1].iov_base = buf;
while( 1 ){
if( (rlen = readv(fd, iv, 2)) < 0 ){
if( errno == EAGAIN || errno == EINTR )
continue;
else
return rlen;
}
hdr = ntohs(hdr);
flen = hdr & VTUN_FSIZE_MASK;
if( rlen < 2 || (rlen-2) != flen )
return VTUN_BAD_FRAME;
return hdr;
}
}

View File

@ -17,7 +17,7 @@
*/ */
/* /*
* lfd_lzo.c,v 1.1.1.2.2.7.2.1 2006/11/16 04:03:00 mtbishop Exp * $Id: lfd_lzo.c,v 1.5.2.2 2007/06/29 05:26:06 mtbishop Exp $
*/ */
/* LZO compression module */ /* LZO compression module */

158
lfd_shaper.c Normal file
View File

@ -0,0 +1,158 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: lfd_shaper.c,v 1.7.2.1 2007/06/29 05:26:10 mtbishop Exp $
*/
#include "config.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <syslog.h>
#include "vtun.h"
#include "linkfd.h"
#include "lib.h"
/*
* Shaper module.
*/
#ifdef HAVE_SHAPER
unsigned long bytes, max_speed;
struct timeval curr_time, last_time;
/*
* Initialization function.
*/
int shaper_init(struct vtun_host *host)
{
/* Calculate max speed bytes/sec */
max_speed = host->spd_out / 8 * 1024;
/* Compensation for delays, nanosleep and so on */
max_speed += 400;
bytes = 0;
vtun_syslog(LOG_INFO,"Traffic shaping(speed %dK) initialized.", host->spd_out);
return 0;
}
/* Shaper counter */
int shaper_counter(int len, char *in, char **out)
{
/* Just count incoming bytes */
bytes += len;
*out = in;
return len;
}
/* Convert tv struct to milisec */
unsigned long inline tv2ms(struct timeval tv)
{
register unsigned long ms = (tv.tv_sec * 1000)+(tv.tv_usec / 1000);
return ms ? ms : 1;
}
#ifndef timersub
/* Some includes doesn't contain this macro */
#define timersub(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((result)->tv_usec < 0) { \
--(result)->tv_sec; \
(result)->tv_usec += 1000000; \
} \
} while (0)
#endif
/*
* Main shaper function.
* Compute current speed in bytes/sec and if it is
* higher than maximal speed stop accepting input
* until the speed become lower or equal to maximal.
*/
int shaper_avail(void)
{
static struct timeval tv;
register unsigned long speed;
/* Let me know if you have faster and better time source. */
gettimeofday(&curr_time,NULL);
timersub(&curr_time,&last_time,&tv);
/* Calculate current speed bytes/sec.
* (tv2ms never returns 0) */
speed = bytes * 1000 / tv2ms(tv);
if( speed > max_speed ){
/*
* Sleep about 1 microsec(actual sleep might be longer).
* This is actually the hack to reduce CPU usage.
* Without this delay we will consume 100% CPU.
*/
static struct timespec ts = {0,1000};
nanosleep(&ts,NULL);
/* Don't accept input */
return 0;
}
if( curr_time.tv_sec > last_time.tv_sec ){
last_time = curr_time;
bytes = 0;
}
/* Accept input */
return 1;
}
struct lfd_mod lfd_shaper = {
"Shaper",
shaper_init,
shaper_counter,
shaper_avail,
NULL,
NULL,
NULL,
NULL,
NULL
};
#else /* HAVE_SHAPER */
int no_shaper(struct vtun_host *host)
{
vtun_syslog(LOG_INFO, "Traffic shaping is not supported");
return -1;
}
struct lfd_mod lfd_shaper = {
"Shaper",
no_shaper, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#endif /* HAVE_SHAPER */

189
lfd_zlib.c Normal file
View File

@ -0,0 +1,189 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: lfd_zlib.c,v 1.5.2.1 2007/06/29 05:26:13 mtbishop Exp $
*/
/* ZLIB compression module */
#include "config.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <syslog.h>
#include "vtun.h"
#include "linkfd.h"
#include "lib.h"
#ifdef HAVE_ZLIB
#include <zlib.h>
static z_stream zi, zd;
static unsigned char *zbuf;
static int zbuf_size = VTUN_FRAME_SIZE + 200;
/*
* Initialize compressor/decompressor.
* Allocate the buffer.
*/
int zlib_alloc(struct vtun_host *host)
{
int zlevel = host->zlevel ? host->zlevel : 1;
zd.zalloc = (alloc_func)0;
zd.zfree = (free_func)0;
zd.opaque = (voidpf)0;
zi.zalloc = (alloc_func)0;
zi.zfree = (free_func)0;
zi.opaque = (voidpf)0;
if( deflateInit(&zd, zlevel ) != Z_OK ){
vtun_syslog(LOG_ERR,"Can't initialize compressor");
return 1;
}
if( inflateInit(&zi) != Z_OK ){
vtun_syslog(LOG_ERR,"Can't initialize decompressor");
return 1;
}
if( !(zbuf = (void *) lfd_alloc(zbuf_size)) ){
vtun_syslog(LOG_ERR,"Can't allocate buffer for the compressor");
return 1;
}
vtun_syslog(LOG_INFO,"ZLIB compression[level %d] initialized.", zlevel);
return 0;
}
/*
* Deinitialize compressor/decompressor.
* Free the buffer.
*/
int zlib_free()
{
deflateEnd(&zd);
inflateEnd(&zi);
lfd_free(zbuf); zbuf = NULL;
return 0;
}
static int expand_zbuf(z_stream *zs, int len)
{
if( !(zbuf = lfd_realloc(zbuf,zbuf_size+len)) )
return -1;
zs->next_out = zbuf + zbuf_size;
zs->avail_out = len;
zbuf_size += len;
return 0;
}
/*
* This functions _MUST_ consume all incoming bytes in one pass,
* 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)
{
int oavail, olen = 0;
int err;
zd.next_in = (void *) in;
zd.avail_in = len;
zd.next_out = (void *) zbuf;
zd.avail_out = zbuf_size;
while(1) {
oavail = zd.avail_out;
if( (err=deflate(&zd, Z_SYNC_FLUSH)) != Z_OK ){
vtun_syslog(LOG_ERR,"Deflate error %d",err);
return -1;
}
olen += oavail - zd.avail_out;
if(!zd.avail_in)
break;
if( expand_zbuf(&zd,100) ) {
vtun_syslog( LOG_ERR, "Can't expand compression buffer");
return -1;
}
}
*out = (void *) zbuf;
return olen;
}
int zlib_decomp(int len, char *in, char **out)
{
int oavail = 0, olen = 0;
int err;
zi.next_in = (void *) in;
zi.avail_in = len;
zi.next_out = (void *) zbuf;
zi.avail_out = zbuf_size;
while(1) {
oavail = zi.avail_out;
if( (err=inflate(&zi, Z_SYNC_FLUSH)) != Z_OK ) {
vtun_syslog(LOG_ERR,"Inflate error %d len %d", err, len);
return -1;
}
olen += oavail - zi.avail_out;
if(!zi.avail_in)
break;
if( expand_zbuf(&zi,100) ) {
vtun_syslog( LOG_ERR, "Can't expand compression buffer");
return -1;
}
}
*out = (void *) zbuf;
return olen;
}
struct lfd_mod lfd_zlib = {
"ZLIB",
zlib_alloc,
zlib_comp,
NULL,
zlib_decomp,
NULL,
zlib_free,
NULL,
NULL
};
#else /* HAVE_ZLIB */
int no_zlib(struct vtun_host *host)
{
vtun_syslog(LOG_INFO, "ZLIB compression is not supported");
return -1;
}
struct lfd_mod lfd_zlib = {
"ZLIB",
no_zlib, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#endif /* HAVE_ZLIB */

362
lib.c Normal file
View File

@ -0,0 +1,362 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: lib.c,v 1.9.2.1 2007/06/29 05:26:15 mtbishop Exp $
*/
#include "config.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <syslog.h>
#include <errno.h>
#include "vtun.h"
#include "linkfd.h"
#include "lib.h"
volatile sig_atomic_t __io_canceled = 0;
#ifndef HAVE_SETPROC_TITLE
/* 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;
void init_title(int argc,char *argv[], char *envp[], char *name)
{
int i;
/*
* Move the environment so settitle can use the space at
* the top of memory.
*/
for (i = 0; envp[i]; i++);
environ = (char **) malloc(sizeof (char *) * (i + 1));
for(i = 0; envp[i]; i++)
environ[i] = strdup(envp[i]);
environ[i] = NULL;
/*
* Save start and extent of argv for set_title.
*/
title_start = argv[0];
/*
* Determine how much space we can use for set_title.
* Use all contiguous argv and envp pointers starting at argv[0]
*/
for(i=0; i<argc; i++)
if( !i || title_end == argv[i])
title_end = argv[i] + strlen(argv[i]) + 1;
for(i=0; envp[i]; i++)
if( title_end == envp[i] )
title_end = envp[i] + strlen(envp[i]) + 1;
strcpy(title_start, name);
title_start += strlen(name);
title_size = title_end - title_start;
}
void set_title(const char *fmt, ...)
{
char buf[255];
va_list ap;
memset(title_start,0,title_size);
/* print the argument string */
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
if( strlen(buf) > title_size - 1)
buf[title_size - 1] = '\0';
strcat(title_start, buf);
}
#endif /* HAVE_SETPROC_TITLE */
/*
* Print padded messages.
* Used by 'auth' function to force all messages
* to be the same len.
*/
int print_p(int fd,const char *fmt, ...)
{
char buf[VTUN_MESG_SIZE];
va_list ap;
memset(buf,0,sizeof(buf));
/* print the argument string */
va_start(ap, fmt);
vsnprintf(buf,sizeof(buf)-1, fmt, ap);
va_end(ap);
return write_n(fd, buf, sizeof(buf));
}
/* Read N bytes with timeout */
int readn_t(int fd, void *buf, size_t count, time_t timeout)
{
fd_set fdset;
struct timeval tv;
tv.tv_usec=0; tv.tv_sec=timeout;
FD_ZERO(&fdset);
FD_SET(fd,&fdset);
if( select(fd+1,&fdset,NULL,NULL,&tv) <= 0)
return -1;
return read_n(fd, buf, count);
}
/*
* Substitutes opt in place off '%X'.
* Returns new string.
*/
char * subst_opt(char *str, struct vtun_sopt *opt)
{
register int slen, olen, sp, np;
register char *optr, *nstr, *tmp;
char buf[10];
if( !str ) return NULL;
slen = strlen(str) + 1;
if( !(nstr = malloc(slen)) )
return str;
sp = np = 0;
while( str[sp] ){
switch( str[sp] ){
case '%':
optr = NULL;
/* Check supported opt */
switch( str[sp+1] ){
case '%':
case 'd':
optr=opt->dev;
break;
case 'A':
optr=opt->laddr;
break;
case 'P':
sprintf(buf,"%d",opt->lport);
optr=buf;
break;
case 'a':
optr=opt->raddr;
break;
case 'p':
sprintf(buf,"%d",opt->rport);
optr=buf;
break;
default:
sp++;
continue;
}
if( optr ){
/* Opt found substitute */
olen = strlen(optr);
slen = slen - 2 + olen;
if( !(tmp = realloc(nstr, slen)) ){
free(nstr);
return str;
}
nstr = tmp;
memcpy(nstr + np, optr, olen);
np += olen;
}
sp += 2;
continue;
case '\\':
nstr[np++] = str[sp++];
if( !nstr[sp] )
continue;
/* fall through */
default:
nstr[np++] = str[sp++];
break;
}
}
nstr[np] = '\0';
return nstr;
}
/*
* Split arguments string.
* ' ' - group arguments
* Modifies original string.
*/
void split_args(char *str, char **argv)
{
register int i = 0;
int mode = 0;
while( str && *str ){
switch( *str ){
case ' ':
if( mode == 1 ){
*str = '\0';
mode = 0;
i++;
}
break;
case '\'':
if( !mode ){
argv[i] = str+1;
mode = 2;
} else {
memmove(argv[i]+1, argv[i], str - argv[i]);
argv[i]++;
if( mode == 1 )
mode = 2;
else
mode = 1;
}
break;
case '\\':
if( mode ){
memmove(argv[i]+1, argv[i], str - argv[i]);
argv[i]++;
}
if( !*(++str) ) continue;
/*Fall through */
default:
if( !mode ){
argv[i] = str;
mode = 1;
}
break;
}
str++;
}
if( mode == 1 || mode == 2)
i++;
argv[i]=NULL;
}
int run_cmd(void *d, void *opt)
{
struct vtun_cmd *cmd = d;
char *argv[50], *args;
int pid, st;
switch( (pid=fork()) ){
case 0:
break;
case -1:
vtun_syslog(LOG_ERR,"Couldn't fork()");
return 0;
default:
if( cmd->flags & VTUN_CMD_WAIT ){
/* Wait for termination */
if( waitpid(pid,&st,0) > 0 && (WIFEXITED(st) && WEXITSTATUS(st)) )
vtun_syslog(LOG_INFO,"Command [%s %.20s] error %d",
cmd->prog ? cmd->prog : "sh",
cmd->args ? cmd->args : "",
WEXITSTATUS(st) );
}
if( cmd->flags & VTUN_CMD_DELAY ){
struct timespec tm = { VTUN_DELAY_SEC, 0 };
/* Small delay hack to sleep after pppd start.
* Until I have no good solution for solving
* PPP + route problem */
nanosleep(&tm, NULL);
}
return 0;
}
args = subst_opt(cmd->args, opt);
if( !cmd->prog ){
/* Run using shell */
cmd->prog = "/bin/sh";
argv[0] = "sh";
argv[1] = "-c";
argv[2] = args;
argv[3] = NULL;
} else {
argv[0] = cmd->prog;
split_args(args, argv + 1);
}
execv(cmd->prog, argv);
vtun_syslog(LOG_ERR,"Couldn't exec program %s", cmd->prog);
exit(1);
}
void free_sopt( struct vtun_sopt *opt )
{
if( opt->dev ){
free(opt->dev);
opt->dev = NULL;
}
if( opt->laddr ){
free(opt->laddr);
opt->laddr = NULL;
}
if( opt->raddr ){
free(opt->raddr);
opt->raddr = NULL;
}
}
void vtun_syslog (int priority, char *format, ...)
{
static volatile sig_atomic_t in_syslog= 0;
char buf[255];
va_list ap;
if(! in_syslog) {
in_syslog = 1;
va_start(ap, format);
vsnprintf(buf, sizeof(buf)-1, format, ap);
syslog(priority, "%s", buf);
va_end(ap);
in_syslog = 0;
}
}

105
lib.h Normal file
View File

@ -0,0 +1,105 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: lib.h,v 1.7.2.1 2007/06/29 05:26:17 mtbishop Exp $
*/
#ifndef _VTUN_LIB_H
#define _VTUN_LIB_H
#include "config.h"
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#ifdef HAVE_LIBUTIL_H
#include <libutil.h>
#endif
#ifndef HAVE_SETPROC_TITLE
void init_title(int argc,char *argv[],char *env[], char *name);
void set_title(const char *ftm, ...);
#else
#define init_title( a... )
#define set_title setproctitle
#endif /* HAVE_SETPROC_TITLE */
#ifndef min
#define min(a,b) ( (a)<(b) ? (a):(b) )
#endif
int readn_t(int fd, void *buf, size_t count, time_t timeout);
int print_p(int f, const char *ftm, ...);
int run_cmd(void *d, void *opt);
void free_sopt(struct vtun_sopt *opt);
/* IO cancelation */
extern volatile sig_atomic_t __io_canceled;
static inline void io_init(void)
{
__io_canceled = 0;
}
static inline void io_cancel(void)
{
__io_canceled = 1;
}
/* signal safe syslog function */
void vtun_syslog (int priority, char *format, ...);
/* Read exactly len bytes (Signal safe)*/
static inline int read_n(int fd, char *buf, int len)
{
register int t=0, w;
while (!__io_canceled && len > 0) {
if( (w = read(fd, buf, len)) < 0 ){
if( errno == EINTR || errno == EAGAIN )
continue;
return -1;
}
if( !w )
return 0;
len -= w; buf += w; t += w;
}
return t;
}
/* Write exactly len bytes (Signal safe)*/
static inline int write_n(int fd, char *buf, int len)
{
register int t=0, w;
while (!__io_canceled && len > 0) {
if( (w = write(fd, buf, len)) < 0 ){
if( errno == EINTR || errno == EAGAIN )
continue;
return -1;
}
if( !w )
return 0;
len -= w; buf += w; t += w;
}
return t;
}
#endif /* _VTUN_LIB_H */

419
linkfd.c Normal file
View File

@ -0,0 +1,419 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: linkfd.c,v 1.13.2.1 2007/06/29 05:26:19 mtbishop Exp $
*/
#include "config.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <syslog.h>
#include <time.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#ifdef HAVE_SCHED_H
#include <sched.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#include "vtun.h"
#include "linkfd.h"
#include "lib.h"
#include "driver.h"
/* used by lfd_encrypt */
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;
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)
{
if( !lfd_mod_head ){
lfd_mod_head = lfd_mod_tail = mod;
mod->next = mod->prev = NULL;
} else {
lfd_mod_tail->next = mod;
mod->prev = lfd_mod_tail;
mod->next = NULL;
lfd_mod_tail = mod;
}
}
/* Initialize and allocate each module */
int lfd_alloc_mod(struct vtun_host *host)
{
struct lfd_mod *mod = lfd_mod_head;
while( mod ){
if( mod->alloc && (mod->alloc)(host) )
return 1;
mod = mod->next;
}
return 0;
}
/* Free all modules */
int lfd_free_mod(void)
{
struct lfd_mod *mod = lfd_mod_head;
while( mod ){
if( mod->free && (mod->free)() )
return 1;
mod = mod->next;
}
lfd_mod_head = lfd_mod_tail = NULL;
return 0;
}
/* Run modules down (from head to tail) */
inline int lfd_run_down(int len, char *in, char **out)
{
register struct lfd_mod *mod;
*out = in;
for(mod = lfd_mod_head; mod && len > 0; mod = mod->next )
if( mod->encode ){
len = (mod->encode)(len, in, out);
in = *out;
}
return len;
}
/* Run modules up (from tail to head) */
inline int lfd_run_up(int len, char *in, char **out)
{
register struct lfd_mod *mod;
*out = in;
for(mod = lfd_mod_tail; mod && len > 0; mod = mod->prev )
if( mod->decode ){
len = (mod->decode)(len, in, out);
in = *out;
}
return len;
}
/* Check if modules are accepting the data(down) */
inline int lfd_check_down(void)
{
register struct lfd_mod *mod;
int err = 1;
for(mod = lfd_mod_head; mod && err > 0; mod = mod->next )
if( mod->avail_encode )
err = (mod->avail_encode)();
return err;
}
/* Check if modules are accepting the data(up) */
inline int lfd_check_up(void)
{
register struct lfd_mod *mod;
int err = 1;
for(mod = lfd_mod_tail; mod && err > 0; mod = mod->prev)
if( mod->avail_decode )
err = (mod->avail_decode)();
return err;
}
/********** Linker *************/
/* Termination flag */
static volatile sig_atomic_t linker_term;
static void sig_term(int sig)
{
vtun_syslog(LOG_INFO, "Closing connection");
io_cancel();
linker_term = VTUN_SIG_TERM;
}
static void sig_hup(int sig)
{
vtun_syslog(LOG_INFO, "Reestablishing connection");
io_cancel();
linker_term = VTUN_SIG_HUP;
}
/* Statistic dump */
void sig_alarm(int sig)
{
static time_t tm;
static char stm[20];
tm = time(NULL);
strftime(stm, sizeof(stm)-1, "%b %d %H:%M:%S", localtime(&tm));
fprintf(lfd_host->stat.file,"%s %lu %lu %lu %lu\n", stm,
lfd_host->stat.byte_in, lfd_host->stat.byte_out,
lfd_host->stat.comp_in, lfd_host->stat.comp_out);
alarm(VTUN_STAT_IVAL);
}
static void sig_usr1(int sig)
{
/* Reset statistic counters on SIGUSR1 */
lfd_host->stat.byte_in = lfd_host->stat.byte_out = 0;
lfd_host->stat.comp_in = lfd_host->stat.comp_out = 0;
}
int lfd_linker(void)
{
int fd1 = lfd_host->rmt_fd;
int fd2 = lfd_host->loc_fd;
register int len, fl;
struct timeval tv;
char *buf, *out;
fd_set fdset;
int maxfd, idle = 0, tmplen;
if( !(buf = lfd_alloc(VTUN_FRAME_SIZE + VTUN_FRAME_OVERHEAD)) ){
vtun_syslog(LOG_ERR,"Can't allocate buffer for the linker");
return 0;
}
proto_write(fd1, buf, VTUN_ECHO_REQ);
maxfd = (fd1 > fd2 ? fd1 : fd2) + 1;
linker_term = 0;
while( !linker_term ){
errno = 0;
/* Wait for data */
FD_ZERO(&fdset);
FD_SET(fd1, &fdset);
FD_SET(fd2, &fdset);
tv.tv_sec = lfd_host->ka_interval;
tv.tv_usec = 0;
if( (len = select(maxfd, &fdset, NULL, NULL, &tv)) < 0 ){
if( errno != EAGAIN && errno != EINTR )
break;
else
continue;
}
if (send_a_packet)
{
send_a_packet = 0;
tmplen = 1;
lfd_host->stat.byte_out += tmplen;
if( (tmplen=lfd_run_down(tmplen,buf,&out)) == -1 )
break;
if( tmplen && proto_write(fd1, out, tmplen) < 0 )
break;
lfd_host->stat.comp_out += tmplen;
}
if( !len ){
if (send_a_packet)
{
send_a_packet = 0;
tmplen = 1;
lfd_host->stat.byte_out += tmplen;
if( (tmplen=lfd_run_down(tmplen,buf,&out)) == -1 )
break;
if( tmplen && proto_write(fd1, out, tmplen) < 0 )
break;
lfd_host->stat.comp_out += tmplen;
}
/* We are idle, lets check connection */
if( lfd_host->flags & VTUN_KEEP_ALIVE ){
if( ++idle > lfd_host->ka_failure ){
vtun_syslog(LOG_INFO,"Session %s network timeout", lfd_host->host);
break;
}
/* Send ECHO request */
if( proto_write(fd1, buf, VTUN_ECHO_REQ) < 0 )
break;
}
continue;
}
/* Read frames from network(fd1), decode and pass them to
* the local device (fd2) */
if( FD_ISSET(fd1, &fdset) && lfd_check_up() ){
idle = 0;
if( (len=proto_read(fd1, buf)) <= 0 )
break;
/* Handle frame flags */
fl = len & ~VTUN_FSIZE_MASK;
len = len & VTUN_FSIZE_MASK;
if( fl ){
if( fl==VTUN_BAD_FRAME ){
vtun_syslog(LOG_ERR, "Received bad frame");
continue;
}
if( fl==VTUN_ECHO_REQ ){
/* Send ECHO reply */
if( proto_write(fd1, buf, VTUN_ECHO_REP) < 0 )
break;
continue;
}
if( fl==VTUN_ECHO_REP ){
/* Just ignore ECHO reply */
continue;
}
if( fl==VTUN_CONN_CLOSE ){
vtun_syslog(LOG_INFO,"Connection closed by other side");
break;
}
}
lfd_host->stat.comp_in += len;
if( (len=lfd_run_up(len,buf,&out)) == -1 )
break;
if( len && dev_write(fd2,out,len) < 0 ){
if( errno != EAGAIN && errno != EINTR )
break;
else
continue;
}
lfd_host->stat.byte_in += len;
}
/* Read data from the local device(fd2), encode and pass it to
* the network (fd1) */
if( FD_ISSET(fd2, &fdset) && lfd_check_down() ){
if( (len = dev_read(fd2, buf, VTUN_FRAME_SIZE)) < 0 ){
if( errno != EAGAIN && errno != EINTR )
break;
else
continue;
}
if( !len ) break;
lfd_host->stat.byte_out += len;
if( (len=lfd_run_down(len,buf,&out)) == -1 )
break;
if( len && proto_write(fd1, out, len) < 0 )
break;
lfd_host->stat.comp_out += len;
}
}
if( !linker_term && errno )
vtun_syslog(LOG_INFO,"%s (%d)", strerror(errno), errno);
if (linker_term == VTUN_SIG_TERM) {
lfd_host->persist = 0;
}
/* Notify other end about our close */
proto_write(fd1, buf, VTUN_CONN_CLOSE);
lfd_free(buf);
return 0;
}
/* Link remote and local file descriptors */
int linkfd(struct vtun_host *host)
{
struct sigaction sa, sa_oldterm, sa_oldint, sa_oldhup;
int old_prio;
lfd_host = host;
old_prio=getpriority(PRIO_PROCESS,0);
setpriority(PRIO_PROCESS,0,LINKFD_PRIO);
/* Build modules stack */
if(host->flags & VTUN_ZLIB)
lfd_add_mod(&lfd_zlib);
if(host->flags & VTUN_LZO)
lfd_add_mod(&lfd_lzo);
if(host->flags & VTUN_ENCRYPT)
lfd_add_mod(&lfd_encrypt);
if(host->flags & VTUN_SHAPE)
lfd_add_mod(&lfd_shaper);
if(lfd_alloc_mod(host))
return 0;
memset(&sa, 0, sizeof(sa));
sa.sa_handler=sig_term;
sigaction(SIGTERM,&sa,&sa_oldterm);
sigaction(SIGINT,&sa,&sa_oldint);
sa.sa_handler=sig_hup;
sigaction(SIGHUP,&sa,&sa_oldhup);
/* Initialize statstic dumps */
if( host->flags & VTUN_STAT ){
char file[40];
sa.sa_handler=sig_alarm;
sigaction(SIGALRM,&sa,NULL);
sa.sa_handler=sig_usr1;
sigaction(SIGUSR1,&sa,NULL);
sprintf(file,"%s/%.20s", VTUN_STAT_DIR, host->host);
if( (host->stat.file=fopen(file, "a")) ){
setvbuf(host->stat.file, NULL, _IOLBF, 0);
alarm(VTUN_STAT_IVAL);
} else
vtun_syslog(LOG_ERR, "Can't open stats file %s", file);
}
io_init();
lfd_linker();
if( host->flags & VTUN_STAT ){
alarm(0);
if (host->stat.file)
fclose(host->stat.file);
}
lfd_free_mod();
sigaction(SIGTERM,&sa_oldterm,NULL);
sigaction(SIGINT,&sa_oldint,NULL);
sigaction(SIGHUP,&sa_oldhup,NULL);
setpriority(PRIO_PROCESS,0,old_prio);
return linker_term;
}

92
linkfd.h Normal file
View File

@ -0,0 +1,92 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: linkfd.h,v 1.4.2.1 2007/06/29 05:26:21 mtbishop Exp $
*/
#ifndef _LINKFD_H
#define _LINKFD_H
/* Priority of the process in the link_fd function */
/* Never set the priority to -19 without stating a good reason.
*#define LINKFD_PRIO -19
* Since the likely intent was just to give vtun an edge,
* -1 will do nicely.
*/
#define LINKFD_PRIO -1
/* Frame alloc/free */
#define LINKFD_FRAME_RESERV 128
#define LINKFD_FRAME_APPEND 64
static inline void * lfd_alloc(size_t size)
{
register char * buf;
size += LINKFD_FRAME_RESERV + LINKFD_FRAME_APPEND;
if( !(buf = malloc(size)) )
return NULL;
return buf+LINKFD_FRAME_RESERV;
}
static inline void * lfd_realloc(void *buf, size_t size)
{
unsigned char *ptr = buf;
ptr -= LINKFD_FRAME_RESERV;
size += LINKFD_FRAME_RESERV;
if( !(ptr = realloc(ptr, size)) )
return NULL;
return ptr+LINKFD_FRAME_RESERV;
}
static inline void lfd_free(void *buf)
{
unsigned char *ptr = buf;
free(ptr-LINKFD_FRAME_RESERV);
}
int linkfd(struct vtun_host *host);
/* Module */
struct lfd_mod {
char *name;
int (*alloc)(struct vtun_host *host);
int (*encode)(int len, char *in, char **out);
int (*avail_encode)(void);
int (*decode)(int len, char *in, char **out);
int (*avail_decode)(void);
int (*free)(void);
struct lfd_mod *next;
struct lfd_mod *prev;
};
/* External LINKFD modules */
extern struct lfd_mod lfd_zlib;
extern struct lfd_mod lfd_lzo;
extern struct lfd_mod lfd_encrypt;
extern struct lfd_mod lfd_shaper;
#endif

102
llist.c Normal file
View File

@ -0,0 +1,102 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: llist.c,v 1.3.2.1 2007/06/29 05:26:23 mtbishop Exp $
*/
#include <stdlib.h>
#include "llist.h"
/* Function to work with the Linked Lists */
void llist_init(llist *l)
{
l->head = l->tail = NULL;
}
int llist_empty(llist *l)
{
return l->tail == NULL;
}
int llist_add(llist *l, void * d)
{
llist_elm *e;
if( !(e=malloc(sizeof(llist_elm))) )
return -1;
if( !l->head )
l->head = l->tail = e;
else
l->tail->next = e;
l->tail = e;
e->next = NULL;
e->data = d;
return 0;
}
/* Travel list from head to tail */
void * llist_trav(llist *l, int (*f)(void *d, void *u), void *u)
{
llist_elm *i = l->head;
while( i ){
if( f(i->data,u) ) return i->data;
i = i->next;
}
return NULL;
}
/* Copy list from (l) to (t) */
int llist_copy(llist *l, llist *t, void* (*f)(void *d, void *u), void *u)
{
llist_elm *i = l->head;
llist_init(t);
while( i ){
llist_add(t,f(i->data,u));
i = i->next;
}
return 0;
}
/* Travel list from head to tail, deallocate each element */
void * llist_free(llist *l, int (*f)(void *d, void *u), void *u)
{
llist_elm *i = l->head, *n;
void *ff = NULL;
while( i ){
n = i->next;
if( f(i->data,u) )
ff = i->data;
else
free(i);
i = n;
}
l->head = l->tail = NULL;
return ff;
}

47
llist.h Normal file
View File

@ -0,0 +1,47 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: llist.h,v 1.3.2.1 2007/06/29 05:26:25 mtbishop Exp $
*/
#ifndef _VTUN_LLIST_H
#define _VTUN_LLIST_H
struct llist_element {
struct llist_element * next;
void * data;
};
typedef struct llist_element llist_elm;
typedef struct {
llist_elm * head;
llist_elm * tail;
} llist;
void llist_init(llist *l);
int llist_add(llist *l, void *d);
int llist_empty(llist *l);
void * llist_trav(llist *l, int (*f)(void *d, void *u), void *u);
int llist_copy(llist *l, llist *t, void* (*f)(void *d, void *u), void *u);
void * llist_free(llist *l, int (*f)(void *d, void *u), void *u);
#endif /* _VTUN_LLIST_H */

163
lock.c Normal file
View File

@ -0,0 +1,163 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: lock.c,v 1.6.2.1 2007/06/29 05:26:27 mtbishop Exp $
*/
#include "config.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <syslog.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include "vtun.h"
#include "linkfd.h"
#include "lib.h"
#include "lock.h"
int create_lock(char * file)
{
char tmp_file[255], str[20];
int fd, pid, ret;
pid = getpid();
ret = 0;
/* Create temp file */
sprintf(tmp_file, "%s_%d_tmp\n", file, pid);
if( (fd = open(tmp_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0 ){
vtun_syslog(LOG_ERR, "Can't create temp lock file %s", file);
return -1;
}
pid = sprintf(str, "%d\n", pid);
if( write(fd, str, pid) == pid ){
/* Create lock file */
if( link(tmp_file, file) < 0 ){
/* Oops, already locked */
ret = -1;
}
} else {
vtun_syslog(LOG_ERR, "Can't write to %s", tmp_file);
ret = -1;
}
close(fd);
/* Remove temp file */
unlink(tmp_file);
return ret;
}
pid_t read_lock(char * file)
{
char str[20];
int fd, pid;
/* Read PID from existing lock */
if( (fd = open(file, O_RDONLY)) < 0)
return -1;
pid = read(fd,str,sizeof(str));
close(fd);
if( pid <= 0 )
return -1;
str[sizeof(str)-1]='\0';
pid = strtol(str, NULL, 10);
if( !pid || errno == ERANGE ){
/* Broken lock file */
if( unlink(file) < 0 )
vtun_syslog(LOG_ERR, "Unable to remove broken lock %s", file);
return -1;
}
/* Check if process is still alive */
if( kill(pid, 0) < 0 && errno == ESRCH ){
/* Process is dead. Remove stale lock. */
if( unlink(file) < 0 )
vtun_syslog(LOG_ERR, "Unable to remove stale lock %s", file);
return -1;
}
return pid;
}
int lock_host(struct vtun_host * host)
{
char lock_file[255];
struct timespec tm;
int pid, i;
if( host->multi == VTUN_MULTI_ALLOW )
return 0;
sprintf(lock_file, "%s/%s", VTUN_LOCK_DIR, host->host);
/* Check if lock already exists. */
if( (pid = read_lock(lock_file)) > 0 ){
/* Old process is alive */
switch( host->multi ){
case VTUN_MULTI_KILL:
vtun_syslog(LOG_INFO, "Killing old connection (process %d)", pid);
if( kill(pid, SIGTERM) < 0 && errno != ESRCH ){
vtun_syslog(LOG_ERR, "Can't kill process %d. %s",pid,strerror(errno));
return -1;
}
/* Give it a time(up to 5 secs) to terminate */
for(i=0; i < 10 && !kill(pid, 0); i++ ){
tm.tv_sec = 0; tm.tv_nsec = 500000000;
nanosleep(&tm, NULL);
}
/* Make sure it's dead */
if( !kill(pid, SIGKILL) ){
vtun_syslog(LOG_ERR, "Process %d ignored TERM, killed with KILL", pid);
/* Remove lock */
if( unlink(lock_file) < 0 )
vtun_syslog(LOG_ERR, "Unable to remove lock %s", lock_file);
}
break;
case VTUN_MULTI_DENY:
return -1;
}
}
return create_lock(lock_file);
}
void unlock_host(struct vtun_host *host)
{
char lock_file[255];
if( host->multi == VTUN_MULTI_ALLOW )
return;
sprintf(lock_file, "%s/%s", VTUN_LOCK_DIR, host->host);
if( unlink(lock_file) < 0 )
vtun_syslog(LOG_ERR, "Unable to remove lock %s", lock_file);
}

31
lock.h Normal file
View File

@ -0,0 +1,31 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: lock.h,v 1.3.2.1 2007/06/29 05:26:29 mtbishop Exp $
*/
#ifndef _VTUN_LOCK_H
#define _VTUN_LOCK_H
pid_t read_lock(char * host);
int create_lock(char * host);
int lock_host(struct vtun_host * host);
void unlock_host(struct vtun_host * host);
#endif /* _VTUN_LOCK_H */

244
main.c Normal file
View File

@ -0,0 +1,244 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: main.c,v 1.9.2.1 2007/06/29 05:26:31 mtbishop Exp $
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <syslog.h>
#include <sys/mman.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#include "vtun.h"
#include "lib.h"
#include "compat.h"
/* 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);
extern int optind,opterr,optopt;
extern char *optarg;
int main(int argc, char *argv[], char *env[])
{
int svr, daemon, sock, dofork, fd, opt;
struct vtun_host *host = NULL;
struct sigaction sa;
char *hst;
/* Configure default settings */
svr = 0; daemon = 1; sock = 0; dofork = 1;
vtun.cfg_file = VTUN_CONFIG_FILE;
vtun.persist = -1;
vtun.timeout = -1;
/* Dup strings because parser will try to free them */
vtun.ppp = strdup("/usr/sbin/pppd");
vtun.ifcfg = strdup("/sbin/ifconfig");
vtun.route = strdup("/sbin/route");
vtun.fwall = strdup("/sbin/ipchains");
vtun.iproute = strdup("/sbin/ip");
vtun.svr_name = NULL;
vtun.svr_addr = NULL;
vtun.bind_addr.port = -1;
vtun.svr_type = -1;
vtun.syslog = LOG_DAEMON;
/* Initialize default host options */
memset(&default_host, 0, sizeof(default_host));
default_host.flags = VTUN_TTY | VTUN_TCP;
default_host.multi = VTUN_MULTI_ALLOW;
default_host.timeout = VTUN_CONNECT_TIMEOUT;
default_host.ka_interval = 30;
default_host.ka_failure = 4;
default_host.loc_fd = default_host.rmt_fd = -1;
/* Start logging to syslog and stderr */
openlog("vtund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
while( (opt=getopt(argc,argv,"misf:P:L:t:np")) != EOF ){
switch(opt){
case 'm':
if (mlockall(MCL_CURRENT | MCL_FUTURE) < 0) {
perror("Unable to mlockall()");
exit(-1);
}
break;
case 'i':
vtun.svr_type = VTUN_INETD;
case 's':
svr = 1;
break;
case 'L':
vtun.svr_addr = strdup(optarg);
break;
case 'P':
vtun.bind_addr.port = atoi(optarg);
break;
case 'f':
vtun.cfg_file = strdup(optarg);
break;
case 'n':
daemon = 0;
break;
case 'p':
vtun.persist = 1;
break;
case 't':
vtun.timeout = atoi(optarg);
break;
default:
usage();
exit(1);
}
}
reread_config(0);
if (vtun.syslog != LOG_DAEMON) {
/* Restart logging to syslog using specified facility */
closelog();
openlog("vtund", LOG_PID|LOG_NDELAY|LOG_PERROR, vtun.syslog);
}
if(!svr){
if( argc - optind < 2 ){
usage();
exit(1);
}
hst = argv[optind++];
if( !(host = find_host(hst)) ){
vtun_syslog(LOG_ERR,"Host %s not found in %s", hst, vtun.cfg_file);
exit(1);
}
vtun.svr_name = strdup(argv[optind]);
}
/*
* Now fill uninitialized fields of the options structure
* with default values.
*/
if(vtun.bind_addr.port == -1)
vtun.bind_addr.port = VTUN_PORT;
if(vtun.persist == -1)
vtun.persist = 0;
if(vtun.timeout == -1)
vtun.timeout = VTUN_TIMEOUT;
switch( vtun.svr_type ){
case -1:
vtun.svr_type = VTUN_STAND_ALONE;
break;
case VTUN_INETD:
sock = dup(0);
dofork = 0;
break;
}
if( daemon ){
if( dofork && fork() )
exit(0);
/* Direct stdin,stdout,stderr to '/dev/null' */
fd = open("/dev/null", O_RDWR);
close(0); dup(fd);
close(1); dup(fd);
close(2); dup(fd);
close(fd);
setsid();
chdir("/");
}
if(svr){
memset(&sa,0,sizeof(sa));
sa.sa_handler=reread_config;
sigaction(SIGHUP,&sa,NULL);
init_title(argc,argv,env,"vtund[s]: ");
if( vtun.svr_type == VTUN_STAND_ALONE )
write_pid();
server(sock);
} else {
init_title(argc,argv,env,"vtund[c]: ");
client(host);
}
closelog();
return 0;
}
/*
* Very simple PID file creation function. Used by server.
* Overrides existing file.
*/
void write_pid(void)
{
FILE *f;
if( !(f=fopen(VTUN_PID_FILE,"w")) ){
vtun_syslog(LOG_ERR,"Can't write PID file");
return;
}
fprintf(f,"%d",(int)getpid());
fclose(f);
}
void reread_config(int sig)
{
if( !read_config(vtun.cfg_file) ){
vtun_syslog(LOG_ERR,"No hosts defined");
exit(1);
}
}
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");
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");
}

289
netlib.c Normal file
View File

@ -0,0 +1,289 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: netlib.c,v 1.11.2.1 2007/06/29 05:26:35 mtbishop Exp $
*/
#include "config.h"
#include "vtun_socks.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#ifdef HAVE_RESOLV_H
#include <resolv.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#include "vtun.h"
#include "lib.h"
#include "netlib.h"
/* Connect with timeout */
int connect_t(int s, struct sockaddr *svr, time_t timeout)
{
#if defined(VTUN_SOCKS) && VTUN_SOCKS == 2
/* Some SOCKS implementations don't support
* non blocking connect */
return connect(s,svr,sizeof(struct sockaddr));
#else
int sock_flags;
fd_set fdset;
struct timeval tv;
tv.tv_usec=0; tv.tv_sec=timeout;
sock_flags=fcntl(s,F_GETFL);
if( fcntl(s,F_SETFL,O_NONBLOCK) < 0 )
return -1;
if( connect(s,svr,sizeof(struct sockaddr)) < 0 && errno != EINPROGRESS)
return -1;
FD_ZERO(&fdset);
FD_SET(s,&fdset);
if( select(s+1,NULL,&fdset,NULL,timeout?&tv:NULL) > 0 ){
int l=sizeof(errno);
errno=0;
getsockopt(s,SOL_SOCKET,SO_ERROR,&errno,&l);
} else
errno=ETIMEDOUT;
fcntl(s,F_SETFL,sock_flags);
if( errno )
return -1;
return 0;
#endif
}
/* Get interface address */
unsigned long getifaddr(char * ifname)
{
struct sockaddr_in addr;
struct ifreq ifr;
int s;
if( (s = socket(AF_INET, SOCK_DGRAM, 0)) == -1 )
return -1;
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)-1);
ifr.ifr_name[sizeof(ifr.ifr_name)-1]='\0';
if( ioctl(s, SIOCGIFADDR, &ifr) < 0 ){
close(s);
return -1;
}
close(s);
addr = *((struct sockaddr_in *) &ifr.ifr_addr);
return addr.sin_addr.s_addr;
}
/*
* Establish UDP session with host connected to fd(socket).
* Returns connected UDP socket or -1 on error.
*/
int udp_session(struct vtun_host *host)
{
struct sockaddr_in saddr;
short port;
int s,opt;
if( (s=socket(AF_INET,SOCK_DGRAM,0))== -1 ){
vtun_syslog(LOG_ERR,"Can't create socket");
return -1;
}
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;
}
opt = sizeof(saddr);
if( getsockname(s,(struct sockaddr *)&saddr,&opt) ){
vtun_syslog(LOG_ERR,"Can't get socket name");
return -1;
}
/* Write port of the new UDP socket */
port = saddr.sin_port;
if( write_n(host->rmt_fd,(char *)&port,sizeof(short)) < 0 ){
vtun_syslog(LOG_ERR,"Can't write port number");
return -1;
}
host->sopt.lport = htons(port);
/* Read port of the other's end UDP socket */
if( readn_t(host->rmt_fd,&port,sizeof(short),host->timeout) < 0 ){
vtun_syslog(LOG_ERR,"Can't read port number %s", strerror(errno));
return -1;
}
opt = sizeof(saddr);
if( getpeername(host->rmt_fd,(struct sockaddr *)&saddr,&opt) ){
vtun_syslog(LOG_ERR,"Can't get peer name");
return -1;
}
saddr.sin_port = port;
if( connect(s,(struct sockaddr *)&saddr,sizeof(saddr)) ){
vtun_syslog(LOG_ERR,"Can't connect socket");
return -1;
}
host->sopt.rport = htons(port);
/* Close TCP socket and replace with UDP socket */
close(host->rmt_fd);
host->rmt_fd = s;
vtun_syslog(LOG_INFO,"UDP connection initialized");
return s;
}
/* Set local address */
int local_addr(struct sockaddr_in *addr, struct vtun_host *host, int con)
{
int opt;
if( con ){
/* Use address of the already connected socket. */
opt = sizeof(struct sockaddr_in);
if( getsockname(host->rmt_fd, (struct sockaddr *)addr, &opt) < 0 ){
vtun_syslog(LOG_ERR,"Can't get local socket address");
return -1;
}
} else {
if (generic_addr(addr, &host->src_addr) < 0)
return -1;
}
host->sopt.laddr = strdup(inet_ntoa(addr->sin_addr));
return 0;
}
int server_addr(struct sockaddr_in *addr, struct vtun_host *host)
{
struct hostent * hent;
memset(addr,0,sizeof(struct sockaddr_in));
addr->sin_family = AF_INET;
addr->sin_port = htons(vtun.bind_addr.port);
/* Lookup server's IP address.
* We do it on every reconnect because server's IP
* address can be dynamic.
*/
if( !(hent = gethostbyname(vtun.svr_name)) ){
vtun_syslog(LOG_ERR, "Can't resolv server address: %s", vtun.svr_name);
return -1;
}
addr->sin_addr.s_addr = *(unsigned long *)hent->h_addr;
host->sopt.raddr = strdup(inet_ntoa(addr->sin_addr));
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)
{
struct hostent *hent;
memset(addr, 0, sizeof(struct sockaddr_in));
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;
case VTUN_ADDR_NAME:
if (!(hent = gethostbyname(vaddr->name))) {
vtun_syslog(LOG_ERR,
"Can't resolv local address %s",
vaddr->name);
return -1;
}
addr->sin_addr.s_addr = *(unsigned long *) hent->h_addr;
break;
default:
addr->sin_addr.s_addr = INADDR_ANY;
break;
}
if (vaddr->port)
addr->sin_port = htons(vaddr->port);
return 0;
}

43
netlib.h Normal file
View File

@ -0,0 +1,43 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: netlib.h,v 1.5.2.1 2007/06/29 05:26:37 mtbishop Exp $
*/
#ifndef _VTUN_NETDEV_H
#define _VTUN_NETDEV_H
#include "config.h"
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
unsigned long getifaddr(char * ifname);
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);
#endif /* _VTUN_NETDEV_H */

100
openbsd/tun_dev.c Normal file
View File

@ -0,0 +1,100 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: tun_dev.c,v 1.6.2.1 2007/06/29 05:27:13 mtbishop Exp $
*/
#include "config.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if_tun.h>
#include "vtun.h"
#include "lib.h"
/*
* Allocate TUN device, returns opened fd.
* Stores dev name in the first arg(must be large enough).
*/
int tun_open(char *dev)
{
char tunname[14];
int i, fd = -1;
if( *dev ){
sprintf(tunname, "/dev/%s", dev);
fd = open(tunname, O_RDWR);
} else {
for(i=0; i < 255; i++){
sprintf(tunname, "/dev/tun%d", i);
/* Open device */
if( (fd=open(tunname, O_RDWR)) > 0 ){
sprintf(dev, "tun%d", i);
break;
}
}
}
return fd;
}
int tun_close(int fd, char *dev)
{
return close(fd);
}
/* Read/write frames from TUN device */
int tun_write(int fd, char *buf, int len)
{
u_int32_t type = htonl(AF_INET);
struct iovec iv[2];
iv[0].iov_base = &type;
iv[0].iov_len = sizeof(type);
iv[1].iov_base = buf;
iv[1].iov_len = len;
return writev(fd, iv, 2);
}
int tun_read(int fd, char *buf, int len)
{
struct iovec iv[2];
u_int32_t type;
register int rlen;
iv[0].iov_base = &type;
iv[0].iov_len = sizeof(type);
iv[1].iov_base = buf;
iv[1].iov_len = len;
if( (rlen = readv(fd, iv, 2)) > 0 )
return rlen - sizeof(type);
else
return rlen;
}

View File

@ -1,4 +1,4 @@
# $Id: vtun.spec,v 1.24.2.3 2007/06/06 08:48:19 mtbishop Exp $ # $Id: vtun.spec,v 1.24.2.4 2007/06/29 05:27:15 mtbishop Exp $
# By default, builds without socks-support. # By default, builds without socks-support.
# To build with socks-support, issue: # To build with socks-support, issue:
@ -183,11 +183,10 @@ sbin/insserv etc/init.d/vtund
%attr(755,root,root) %{_sbindir}/vtund %attr(755,root,root) %{_sbindir}/vtund
%attr(755,root,root) %dir %{log_dir} %attr(755,root,root) %dir %{log_dir}
%attr(755,root,root) %dir %{lock_dir} %attr(755,root,root) %dir %{lock_dir}
%{_mandir}/man8/vtund.8* %{_mandir}/man8/vtun*.8*
%{_mandir}/man5/vtund.conf.5* %{_mandir}/man5/vtund.conf.5*
/etc/xinetd.d/vtun /etc/xinetd.d/vtun
%if "%_dis" == "suse" %if "%_dis" == "suse"
%{_mandir}/man8/vtun.8*
%attr(755,root,root) %{_sbindir}/rcvtund %attr(755,root,root) %{_sbindir}/rcvtund
/var/adm/fillup-templates/rc.config.vtund /var/adm/fillup-templates/rc.config.vtund
%endif %endif

63
scripts/reroute Executable file
View File

@ -0,0 +1,63 @@
#!/bin/bash
#
# Maxim Krasnyansky <max_mk@yahoo.com>
# $Id: reroute,v 1.3.2.1 2007/06/29 05:27:18 mtbishop Exp $
#
IP=/sbin/ip
if [ $# -ne 3 ]; then
echo "Usage: reroute option Source_IP Destination_IP"
echo "Options:"
echo " -m - Move route Source_IP -> Destination_IP to table 100."
echo " Configure source based routing."
echo " -r - Restore route Source_IP -> Destination_IP to default table."
echo " Delete source based routing."
exit 1;
fi
MODE=$1
IP_S=$2
IP_D=$3
# Get original route
ROUTE=`$IP route get $IP_D from $IP_S | grep dev`
# Parse route
set - $ROUTE
while [ "$1" != "" ]; do
if [ "$1" = "src" ]; then
shift
O_SRC=$1
fi
if [ "$1" = "dev" ]; then
shift
O_DEV=$1
fi
if [ "$1" = "via" ]; then
shift
O_GW=$1
fi
shift
done
# Flush all routes, rules and cache for that IP
$IP route flush $IP_D table all >/dev/null 2>&1
$IP rule del from $IP_S to $IP_D >/dev/null 2>&1
case $MODE in
-m)
# Add route via orig device to table 100
$IP route add $ROUTE table 100 >/dev/null 2>&1
# Add source based routing
$IP rule add from $IP_S to $IP_D table 100 >/dev/null 2>&1
;;
-r)
# Add route via orig device to defaul table
$IP route add $ROUTE >/dev/null 2>&1
;;
esac
exit 0

198
server.c Normal file
View File

@ -0,0 +1,198 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: server.c,v 1.9.2.1 2007/06/29 05:26:39 mtbishop Exp $
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <syslog.h>
#include <sys/socket.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include "vtun.h"
#include "lib.h"
#include "lock.h"
#include "auth.h"
#include "compat.h"
static volatile sig_atomic_t server_term;
static void sig_term(int sig)
{
vtun_syslog(LOG_INFO,"Terminated");
server_term = VTUN_SIG_TERM;
}
void connection(int sock)
{
struct sockaddr_in my_addr, cl_addr;
struct vtun_host *host;
struct sigaction sa;
char *ip;
int opt;
opt = sizeof(struct sockaddr_in);
if( getpeername(sock, (struct sockaddr *) &cl_addr, &opt) ){
vtun_syslog(LOG_ERR, "Can't get peer name");
exit(1);
}
opt = sizeof(struct sockaddr_in);
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));
io_init();
if( (host=auth_server(sock)) ){
sa.sa_handler=SIG_IGN;
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) );
host->rmt_fd = sock;
host->sopt.laddr = strdup(inet_ntoa(my_addr.sin_addr));
host->sopt.lport = vtun.bind_addr.port;
host->sopt.raddr = strdup(ip);
host->sopt.rport = ntohs(cl_addr.sin_port);
/* Start tunnel */
tunnel(host);
vtun_syslog(LOG_INFO,"Session %s closed", host->host);
/* 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) );
}
close(sock);
exit(0);
}
void listener(void)
{
struct sigaction sa;
struct sockaddr_in my_addr, cl_addr;
int s, s1, opt;
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
/* Set listen address */
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 ){
vtun_syslog(LOG_ERR,"Can't create socket");
exit(1);
}
opt=1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if( bind(s,(struct sockaddr *)&my_addr,sizeof(my_addr)) ){
vtun_syslog(LOG_ERR,"Can't bind to the socket");
exit(1);
}
if( listen(s, 10) ){
vtun_syslog(LOG_ERR,"Can't listen on the socket");
exit(1);
}
memset(&sa,0,sizeof(sa));
sa.sa_flags = SA_NOCLDWAIT;
sa.sa_handler=sig_term;
sigaction(SIGTERM,&sa,NULL);
sigaction(SIGINT,&sa,NULL);
server_term = 0;
set_title("waiting for connections on port %d", vtun.bind_addr.port);
while( (!server_term) || (server_term == VTUN_SIG_HUP) ){
opt=sizeof(cl_addr);
if( (s1=accept(s,(struct sockaddr *)&cl_addr,&opt)) < 0 )
continue;
switch( fork() ){
case 0:
close(s);
connection(s1);
break;
case -1:
vtun_syslog(LOG_ERR, "Couldn't fork()");
default:
close(s1);
break;
}
}
}
void server(int sock)
{
struct sigaction sa;
sa.sa_handler=SIG_IGN;
sa.sa_flags=SA_NOCLDWAIT;;
sigaction(SIGINT,&sa,NULL);
sigaction(SIGQUIT,&sa,NULL);
sigaction(SIGCHLD,&sa,NULL);
sigaction(SIGPIPE,&sa,NULL);
sigaction(SIGUSR1,&sa,NULL);
vtun_syslog(LOG_INFO,"VTUN server ver %s (%s)", VTUN_VER,
vtun.svr_type == VTUN_INETD ? "inetd" : "stand" );
switch( vtun.svr_type ){
case VTUN_STAND_ALONE:
listener();
break;
case VTUN_INETD:
connection(sock);
break;
}
}

144
svr4/tap_dev.c Normal file
View File

@ -0,0 +1,144 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: tap_dev.c,v 1.4.2.1 2007/06/29 05:27:20 mtbishop Exp $
*/
#include "config.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <signal.h>
#include <stropts.h>
#include <net/if.h>
#include <net/if_tun.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#include "vtun.h"
#include "lib.h"
/*
* Allocate Ether TAP device, returns opened fd.
* Stores dev name in the first arg(must be large enough).
*/
int tap_open(char *dev)
{
int tap_fd, if_fd, ppa = -1;
static int ip_fd = 0;
char *ptr;
if( *dev ){
ptr = dev;
while( *ptr && !isdigit((int)*ptr) ) ptr++;
ppa = atoi(ptr);
}
/* Check if IP device was opened */
if( ip_fd )
close(ip_fd);
if( (ip_fd = open("/dev/ip", O_RDWR, 0)) < 0){
syslog(LOG_ERR, "Can't open /dev/ip");
return -1;
}
if( (tap_fd = open("/dev/tap", O_RDWR, 0)) < 0){
syslog(LOG_ERR, "Can't open /dev/tap");
return -1;
}
/* Assign a new PPA and get its unit number. */
if( (ppa = ioctl(tap_fd, TUNNEWPPA, ppa)) < 0){
syslog(LOG_ERR, "Can't assign new interface");
return -1;
}
if( (if_fd = open("/dev/tap", O_RDWR, 0)) < 0){
syslog(LOG_ERR, "Can't open /dev/tap (2)");
return -1;
}
if(ioctl(if_fd, I_PUSH, "ip") < 0){
syslog(LOG_ERR, "Can't push IP module");
return -1;
}
/* Assign ppa according to the unit number returned by tap device */
if(ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0){
syslog(LOG_ERR, "Can't set PPA %d", ppa);
return -1;
}
if(ioctl(ip_fd, I_LINK, if_fd) < 0){
syslog(LOG_ERR, "Can't link TAP device to IP");
return -1;
}
sprintf(dev, "tap%d", ppa);
return tap_fd;
}
int tap_close(int fd, char *dev)
{
return close(fd);
}
int tap_write(int fd, char *buf, int len)
{
struct strbuf sbuf;
sbuf.len = len;
sbuf.buf = buf;
return putmsg(fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
}
int tap_read(int fd, char *buf, int len)
{
struct strbuf sbuf;
int f = 0;
sbuf.maxlen = len;
sbuf.buf = buf;
return getmsg(fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
}

177
svr4/tun_dev.c Normal file
View File

@ -0,0 +1,177 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: tun_dev.c,v 1.5.2.1 2007/06/29 05:27:23 mtbishop Exp $
*/
#include "config.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <signal.h>
#include <stropts.h>
#include <net/if.h>
#include <net/if_tun.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#include "vtun.h"
#include "lib.h"
static int ip_fd = -1;
/*
* Allocate TUN device, returns opened fd.
* Stores dev name in the first arg(must be large enough).
*/
int tun_open(char *dev)
{
int tun_fd, if_fd, muxid, ppa = -1;
struct ifreq ifr;
char *ptr;
if( *dev ){
ptr = dev;
while( *ptr && !isdigit((int)*ptr) ) ptr++;
ppa = atoi(ptr);
}
if( (ip_fd = open("/dev/udp", O_RDWR, 0)) < 0){
syslog(LOG_ERR, "Can't open /dev/ip");
return -1;
}
if( (tun_fd = open("/dev/tun", O_RDWR, 0)) < 0){
syslog(LOG_ERR, "Can't open /dev/tun");
return -1;
}
/* Assign a new PPA and get its unit number. */
if( (ppa = ioctl(tun_fd, TUNNEWPPA, ppa)) < 0){
syslog(LOG_ERR, "Can't assign new interface");
return -1;
}
if( (if_fd = open("/dev/tun", O_RDWR, 0)) < 0){
syslog(LOG_ERR, "Can't open /dev/tun (2)");
return -1;
}
if(ioctl(if_fd, I_PUSH, "ip") < 0){
syslog(LOG_ERR, "Can't push IP module");
return -1;
}
/* Assign ppa according to the unit number returned by tun device */
if(ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0){
syslog(LOG_ERR, "Can't set PPA %d", ppa);
return -1;
}
if( (muxid = ioctl(ip_fd, I_PLINK, if_fd)) < 0){
syslog(LOG_ERR, "Can't link TUN device to IP");
return -1;
}
close(if_fd);
sprintf(dev, "tun%d", ppa);
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, dev);
ifr.ifr_ip_muxid = muxid;
if( ioctl(ip_fd, SIOCSIFMUXID, &ifr) < 0 ){
ioctl(ip_fd, I_PUNLINK, muxid);
syslog(LOG_ERR, "Can't set multiplexor id");
return -1;
}
return tun_fd;
}
/*
* Close TUN device.
*/
int tun_close(int fd, char *dev)
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, dev);
if( ioctl(ip_fd, SIOCGIFFLAGS, &ifr) < 0 ){
syslog(LOG_ERR, "Can't get iface flags");
return 0;
}
if( ioctl(ip_fd, SIOCGIFMUXID, &ifr) < 0 ){
syslog(LOG_ERR, "Can't get multiplexor id");
return 0;
}
if( ioctl(ip_fd, I_PUNLINK, ifr.ifr_ip_muxid) < 0 ){
syslog(LOG_ERR, "Can't unlink interface");
return 0;
}
close(ip_fd); close(fd);
return 0;
}
int tun_write(int fd, char *buf, int len)
{
struct strbuf sbuf;
sbuf.len = len;
sbuf.buf = buf;
return putmsg(fd, NULL, &sbuf, 0) >=0 ? sbuf.len : -1;
}
int tun_read(int fd, char *buf, int len)
{
struct strbuf sbuf;
int f = 0;
sbuf.maxlen = len;
sbuf.buf = buf;
return getmsg(fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
}

250
tunnel.c Normal file
View File

@ -0,0 +1,250 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: tunnel.c,v 1.14.2.1 2007/06/29 05:26:41 mtbishop Exp $
*/
#include "config.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <syslog.h>
#include <signal.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#include "vtun.h"
#include "linkfd.h"
#include "lib.h"
#include "netlib.h"
#include "driver.h"
int (*dev_write)(int fd, char *buf, int len);
int (*dev_read)(int fd, char *buf, int len);
int (*proto_write)(int fd, char *buf, int len);
int (*proto_read)(int fd, char *buf);
/* Initialize and start the tunnel.
Returns:
-1 - critical error
0 - normal close or noncritical error
*/
int tunnel(struct vtun_host *host)
{
int null_fd, pid, opt;
int fd[2]={-1, -1};
char dev[VTUN_DEV_LEN]="";
int interface_already_open = 0;
if ( (host->persist == VTUN_PERSIST_KEEPIF) &&
(host->loc_fd >= 0) )
interface_already_open = 1;
/* Initialize device. */
if( host->dev ){
strncpy(dev, host->dev, VTUN_DEV_LEN);
dev[VTUN_DEV_LEN-1]='\0';
}
if( ! interface_already_open ){
switch( host->flags & VTUN_TYPE_MASK ){
case VTUN_TTY:
if( (fd[0]=pty_open(dev)) < 0 ){
vtun_syslog(LOG_ERR,"Can't allocate pseudo tty. %s(%d)", strerror(errno), errno);
return -1;
}
break;
case VTUN_PIPE:
if( pipe_open(fd) < 0 ){
vtun_syslog(LOG_ERR,"Can't create pipe. %s(%d)", strerror(errno), errno);
return -1;
}
break;
case VTUN_ETHER:
if( (fd[0]=tap_open(dev)) < 0 ){
vtun_syslog(LOG_ERR,"Can't allocate tap device %s. %s(%d)", dev, strerror(errno), errno);
return -1;
}
break;
case VTUN_TUN:
if( (fd[0]=tun_open(dev)) < 0 ){
vtun_syslog(LOG_ERR,"Can't allocate tun device %s. %s(%d)", dev, strerror(errno), errno);
return -1;
}
break;
}
host->loc_fd = fd[0];
}
host->sopt.dev = strdup(dev);
/* Initialize protocol. */
switch( host->flags & VTUN_PROT_MASK ){
case VTUN_TCP:
opt=1;
setsockopt(host->rmt_fd,SOL_SOCKET,SO_KEEPALIVE,&opt,sizeof(opt) );
opt=1;
setsockopt(host->rmt_fd,IPPROTO_TCP,TCP_NODELAY,&opt,sizeof(opt) );
proto_write = tcp_write;
proto_read = tcp_read;
break;
case VTUN_UDP:
if( (opt = udp_session(host)) == -1){
vtun_syslog(LOG_ERR,"Can't establish UDP session");
close(fd[1]);
if( ! ( host->persist == VTUN_PERSIST_KEEPIF ) )
close(fd[0]);
return 0;
}
proto_write = udp_write;
proto_read = udp_read;
break;
}
switch( (pid=fork()) ){
case -1:
vtun_syslog(LOG_ERR,"Couldn't fork()");
if( ! ( host->persist == VTUN_PERSIST_KEEPIF ) )
close(fd[0]);
close(fd[1]);
return 0;
case 0:
/* do this only the first time when in persist = keep mode */
if( ! interface_already_open ){
switch( host->flags & VTUN_TYPE_MASK ){
case VTUN_TTY:
/* Open pty slave (becomes controlling terminal) */
if( (fd[1] = open(dev, O_RDWR)) < 0){
vtun_syslog(LOG_ERR,"Couldn't open slave pty");
exit(0);
}
/* Fall through */
case VTUN_PIPE:
null_fd = open("/dev/null", O_RDWR);
close(fd[0]);
close(0); dup(fd[1]);
close(1); dup(fd[1]);
close(fd[1]);
/* Route stderr to /dev/null */
close(2); dup(null_fd);
close(null_fd);
break;
case VTUN_ETHER:
case VTUN_TUN:
break;
}
}
/* Run list of up commands */
set_title("%s running up commands", host->host);
llist_trav(&host->up, run_cmd, &host->sopt);
exit(0);
}
switch( host->flags & VTUN_TYPE_MASK ){
case VTUN_TTY:
set_title("%s tty", host->host);
dev_read = pty_read;
dev_write = pty_write;
break;
case VTUN_PIPE:
/* Close second end of the pipe */
close(fd[1]);
set_title("%s pipe", host->host);
dev_read = pipe_read;
dev_write = pipe_write;
break;
case VTUN_ETHER:
set_title("%s ether %s", host->host, dev);
dev_read = tap_read;
dev_write = tap_write;
break;
case VTUN_TUN:
set_title("%s tun %s", host->host, dev);
dev_read = tun_read;
dev_write = tun_write;
break;
}
opt = linkfd(host);
set_title("%s running down commands", host->host);
llist_trav(&host->down, run_cmd, &host->sopt);
if(! ( host->persist == VTUN_PERSIST_KEEPIF ) ) {
set_title("%s closing", host->host);
/* Gracefully destroy interface */
switch( host->flags & VTUN_TYPE_MASK ){
case VTUN_TUN:
tun_close(fd[0], dev);
break;
case VTUN_ETHER:
tap_close(fd[0], dev);
break;
}
close(host->loc_fd);
}
/* Close all other fds */
close(host->rmt_fd);
close(fd[1]);
return opt;
}

221
vtun.h Normal file
View File

@ -0,0 +1,221 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: vtun.h,v 1.12.2.1 2007/06/29 05:26:49 mtbishop Exp $
*/
#ifndef _VTUN_H
#define _VTUN_H
#include "llist.h"
/* Default VTUN port */
#define VTUN_PORT 5000
/* Default VTUN connect timeout in sec */
#define VTUN_CONNECT_TIMEOUT 30
/* General VTUN timeout for several operations, in sec */
#define VTUN_TIMEOUT 30
/* Number of seconds for delay after pppd startup*/
#define VTUN_DELAY_SEC 10
/* Statistic interval in seconds */
#define VTUN_STAT_IVAL 5*60 /* 5 min */
/* Max lenght of device name */
#define VTUN_DEV_LEN 20
/* End of configurable part */
struct vtun_sopt {
char *dev;
char *laddr;
int lport;
char *raddr;
int rport;
};
struct vtun_stat {
unsigned long byte_in;
unsigned long byte_out;
unsigned long comp_in;
unsigned long comp_out;
FILE *file;
};
struct vtun_cmd {
char *prog;
char *args;
int flags;
};
/* Command flags */
#define VTUN_CMD_WAIT 0x01
#define VTUN_CMD_DELAY 0x02
#define VTUN_CMD_SHELL 0x04
struct vtun_addr {
char *name;
char *ip;
int port;
int type;
};
/* Address types */
#define VTUN_ADDR_IFACE 0x01
#define VTUN_ADDR_NAME 0x02
struct vtun_host {
char *host;
char *passwd;
char *dev;
llist up;
llist down;
int flags;
int timeout;
int spd_in;
int spd_out;
int zlevel;
int cipher;
int rmt_fd;
int loc_fd;
/* Persist mode */
int persist;
/* Multiple connections */
int multi;
/* Keep Alive */
int ka_interval;
int ka_failure;
/* Source address */
struct vtun_addr src_addr;
struct vtun_stat stat;
struct vtun_sopt sopt;
};
extern llist host_list;
/* Flags definitions */
#define VTUN_TTY 0x0100
#define VTUN_PIPE 0x0200
#define VTUN_ETHER 0x0400
#define VTUN_TUN 0x0800
#define VTUN_TYPE_MASK (VTUN_TTY | VTUN_PIPE | VTUN_ETHER | VTUN_TUN)
#define VTUN_TCP 0x0010
#define VTUN_UDP 0x0020
#define VTUN_PROT_MASK (VTUN_TCP | VTUN_UDP)
#define VTUN_KEEP_ALIVE 0x0040
#define VTUN_ZLIB 0x0001
#define VTUN_LZO 0x0002
#define VTUN_SHAPE 0x0004
#define VTUN_ENCRYPT 0x0008
/* Cipher options */
#define VTUN_ENC_BF128ECB 1
#define VTUN_ENC_BF128CBC 2
#define VTUN_ENC_BF128CFB 3
#define VTUN_ENC_BF128OFB 4
#define VTUN_ENC_BF256ECB 5
#define VTUN_ENC_BF256CBC 6
#define VTUN_ENC_BF256CFB 7
#define VTUN_ENC_BF256OFB 8
#define VTUN_ENC_AES128ECB 9
#define VTUN_ENC_AES128CBC 10
#define VTUN_ENC_AES128CFB 11
#define VTUN_ENC_AES128OFB 12
#define VTUN_ENC_AES256ECB 13
#define VTUN_ENC_AES256CBC 14
#define VTUN_ENC_AES256CFB 15
#define VTUN_ENC_AES256OFB 16
/* Mask to drop the flags which will be supplied by the server */
#define VTUN_CLNT_MASK 0xf000
#define VTUN_STAT 0x1000
#define VTUN_PERSIST 0x2000
/* Constants and flags for VTun protocol */
#define VTUN_FRAME_SIZE 2048
#define VTUN_FRAME_OVERHEAD 100
#define VTUN_FSIZE_MASK 0x0fff
#define VTUN_CONN_CLOSE 0x1000
#define VTUN_ECHO_REQ 0x2000
#define VTUN_ECHO_REP 0x4000
#define VTUN_BAD_FRAME 0x8000
/* Authentication message size */
#define VTUN_MESG_SIZE 50
/* Support for multiple connections */
#define VTUN_MULTI_DENY 0 /* no */
#define VTUN_MULTI_ALLOW 1 /* yes */
#define VTUN_MULTI_KILL 2
/* keep interface in persistant mode */
#define VTUN_PERSIST_KEEPIF 2
/* Values for the signal flag */
#define VTUN_SIG_TERM 1
#define VTUN_SIG_HUP 2
/* Global options */
struct vtun_opts {
int timeout;
int persist;
char *cfg_file;
char *shell; /* Shell */
char *ppp; /* Command to configure ppp devices */
char *ifcfg; /* Command to configure net devices */
char *route; /* Command to configure routing */
char *fwall; /* Command to configure FireWall */
char *iproute; /* iproute command */
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 */
int svr_type; /* Server mode */
int syslog; /* Facility to log messages to syslog under */
};
#define VTUN_STAND_ALONE 0
#define VTUN_INETD 1
extern struct vtun_opts vtun;
void server(int sock);
void client(struct vtun_host *host);
int tunnel(struct vtun_host *host);
int read_config(char *file);
struct vtun_host * find_host(char *host);
#endif

46
vtun_socks.h Normal file
View File

@ -0,0 +1,46 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky.
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.
*/
/*
* $Id: vtun_socks.h,v 1.3.2.1 2007/06/29 05:26:51 mtbishop Exp $
*/
#ifndef _VTUN_SOCKS_H
#define _VTUN_SOCKS_H
#if defined(VTUN_SOCKS)
/* Syscalls to SOCKS calls */
#if VTUN_SOCKS == 1
#define connect SOCKSconnect
#define bind SOCKSbind
#define select SOCKSselect
#define getsockname SOCKSgetsockname
#define getpeername SOCKSgetpeername
#define gethostbyname SOCKSgethostbyname
#else
#define connect Rconnect
#define bind Rbind
#define select Rselect
#define getsockname Rgetsockname
#define getpeername Rgetpeername
#define gethostbyname Rgethostbyname
#endif
#endif
#endif /* _VTUN_SOCKS_H */

151
vtund.8 Normal file
View File

@ -0,0 +1,151 @@
.\" Manual page for vtund
.\" $Id: vtund.8,v 1.6.2.1 2007/06/29 05:26:43 mtbishop Exp $
.\" SH section heading
.\" SS subsection heading
.\" LP paragraph
.\" IP indented paragraph
.\" TP hanging label
.TH VTUND 8
.SH NAME
vtund \- VTun(Virtual Tunnel) daemon.
.SH SYNOPSIS
.B vtund
<
.I -s
>
[
.I -i
]
[
.I -n
]
[
.I -f file
]
[
.I -P port
]
.LP
.B vtund
[
.I -f file
]
[
.I -P port
]
[
.I -p
]
[
.I -m
]
[
.I -t timeout
]
[
.I -n
]
<
.I session
>
<
.I server address
>
.SH DESCRIPTION
.LP
VTun provides the method for creating Virtual Tunnels over TCP/IP networks
and allows to shape, compress, encrypt traffic in that tunnels.
.LP
Supported type of tunnels are: PPP, IP, Ethernet and most of other serial
protocols and programs.
.LP
VTun is easily and highly configurable, it can be used for various network
task like VPN, Mobile IP, Shaped Internet access, IP address saving, etc.
.LP
It is completely user space implementation and does not require modification
to any kernel parts.
.SH OPTIONS
.TP
.I -f file
Read config information from the
.I file
(full path required). By default vtund uses /etc/vtund.conf
.TP
.I -n
Do not become daemon.
.SS Server mode:
.TP
.I -s
Run as the server.
.TP
.I -i
Run as the inetd server.
.TP
.I -P port
Listen for connection on the specified
.I port
By default vtund listens on TCP port 5000. This options is equivalent to
the 'port' option of config file.
.SS Client mode:
.TP
.I -P port
Connect to the server on the specified
.I port
By default vtund connects to TCP port 5000. This options is equivalent to
the 'port' option of config file.
.TP
.I -p
Reconnect to the server after connection termination. By default vtund will
exit if connection has been terminated. This options is equivalent to
the 'persist' option of config file.
.TP
.I -m
Force memory pages to be locked memory-resident to prevent potential VM deadlock. Useful with NFS traffic. This option has no config file equivalent.
.TP
.I -t timeout
Connect
.I timeout
Default is 30 seconds. This options is equivalent to the 'timeout' option of
config file.
.TP
.I session
Session name from the config file.
.TP
.I server
Address of the server to connect to. Either IP address or domain name can be
specified.
.SH FILES
.TP
.B /etc/vtund.conf
Main configuration file with sessions and other information.
See vtund.conf example provided with distribution and vtund.conf(5)
for more information.
.TP
.B /var/lock/vtund/
Session lock files.
.TP
.B /var/log/vtund/
Connection statistic log files.
.br
Format:
Date Uncomp_In Uncomp_Out Comp_In Comp_Out
.SH SIGNALS
.TP
.B SIGHUP
Server mode: Causes vtund to reread the config file.
.br
Client mode: Causes vtund to reestablish the connection.
.TP
.B SIGUSR1
This signal causes vtund to reset statistic counters.
.SH SEE ALSO
.TP
vtund.conf(5)
.SH NOTES
.LP
This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit. (http://www.openssl.org/)
.SH AUTHORS
Maxim Krasnyansky <max_mk@yahoo.com>

504
vtund.conf Normal file
View File

@ -0,0 +1,504 @@
#
# VTun - Virtual Tunnel over TCP/IP network.
# Copyright (C) 1998-2001 Maxim Krasnyansky <max_mk@yahoo.com>
#
# Cleanup of English and spelling by
# Ted Rolle <ted@acacia.datacomm.com>
#
# Configuration file example
# $Id: vtund.conf,v 1.4.2.1 2007/06/29 05:26:45 mtbishop Exp $
#
#
# Lines which begin with '#' are comments
#
# File format:
#
# XXXXX {
# option param; option param;
# option param;
# ......
# }
# Where XXXXX:
# options - General options.
# default - default session options.
# session - Session options.
#
# Options _must_ be grouped by curly braces '{' '}'.
# Each option _must_ end with ';'
#
# -----------
# General options:
#
# type - Server type.
# 'stand' - Stand alone server (default).
# 'inetd' - Started by inetd.
# Used only by the server.
#
# -----------
# port - Server TCP port number.
#
# -----------
# bindaddr - Server listen address. Used to force vtund to bind
# to the specific address and port in server mode.
# Format:
# bindaddr {
# option .....;
# };
#
# 'bindaddr' options:
#
# iface - Use interface address as the listen address.
# Format:
# iface if_name;
#
# addr - Listen address.
# Format:
# addr ip_address;
# addr host_name;
#
# -----------
# syslog - Syslog facility.
#
# -----------
# timeout - General VTun timeout.
#
# -----------
# ppp - Program for the ppp initialization.
#
# -----------
# ifconfig - Program for the net interface initialization.
#
# -----------
# route - Program for the routing table manipulation.
#
# -----------
# firewall - Program for the firewall setup.
#
# -----------
#
# Session options:
#
# passwd - Password for authentication.
#
# -----------
# type - Tunnel type.
# 'tun' - IP tunnel (No PPP,Ether,.. headers).
# 'ether' - Ethernet tunnel.
# 'tty' - Serial tunnel, PPP, SLIP, etc.
# 'pipe' - Pipe tunnel.
# Default type is 'tty'.
# Ignored by the client.
#
# -----------
# device - Network device.
# 'tapXX' - for 'ether'
# 'tunXX' - for 'tun'
# By default VTun will automatically select available
# device.
#
# -----------
# proto - Protocol.
# 'tcp' - TCP protocol.
# 'udp' - UDP protocol.
#
# 'tcp' is default for all tunnel types.
# 'udp' is recommended for 'ether' and 'tun' only.
#
# This option is ignored by the client.
#
# -----------
# persist - Persist mode.
# 'yes' - Reconnect to the server after connection
# termination.
# 'no' - Exit after connection termination (default).
# Used only by the client.
#
# -----------
# keepalive - Enable 'yes' or disable 'no' connection
# keep-alive. Ignored by the client.
#
# -----------
# timeout - Connect timeout.
#
# -----------
# compress - Enable 'yes' or disable 'no' compression.
# It is also possible to specify method:
# 'zlib' - ZLIB compression
# 'lzo' - LZO compression
# and level:
# from 1(best speed) to 9(best compression)
# separated by ':'. Default method is 'zlib:1'.
# Ignored by the client.
#
# -----------
# encrypt - Enable 'yes' or disable 'no' encryption.
# It is also possible to specify a method:
# 'blowfish128ecb' - Blowfish cipher, 128 bit key, mode ECB
# 'blowfish128cbc' - Blowfish cipher, 128 bit key, mode CBC
# 'blowfish128cfb' - Blowfish cipher, 128 bit key, mode CFB
# 'blowfish128ofb' - Blowfish cipher, 128 bit key, mode OFB
# 'blowfish256ecb' - Blowfish cipher, 256 bit key, mode ECB
# 'blowfish256cbc' - Blowfish cipher, 256 bit key, mode CBC
# 'blowfish256cfb' - Blowfish cipher, 256 bit key, mode CFB
# 'blowfish256ofb' - Blowfish cipher, 256 bit key, mode OFB
# 'aes128ecb' - AES cipher, 128 bit key, mode ECB
# 'aes128cbc' - AES cipher, 128 bit key, mode CBC
# 'aes128cfb' - AES cipher, 128 bit key, mode CFB
# 'aes128ofb' - AES cipher, 128 bit key, mode OFB
# 'aes256ecb' - AES cipher, 256 bit key, mode ECB
# 'aes256cbc' - AES cipher, 256 bit key, mode CBC
# 'aes256cfb' - AES cipher, 256 bit key, mode CFB
# 'aes256ofb' - AES cipher, 256 bit key, mode OFB
# Default method is 'blowfish128ecb'.
# Ignored by the client.
#
# -----------
# stat - Enable 'yes' or disable 'no' statistics.
# If enabled vtund will log statistic counters every
# 5 minutes.
#
# -----------
# speed - Speed of the connection in kilobits/second.
# 8,16,32,64,128,256,etc.
# 0 means maximum possible speed without shaping.
# You can specify speed in form IN:OUT.
# IN - to the client, OUT - from the client.
# Single number means same speed for IN and OUT.
# Ignored by the client.
#
# -----------
# up - List of programs to run after connection has been
# established. Used to initialize protocols, devices,
# routing and firewall.
# Format:
# up {
# option .....;
# option .....;
# };
#
# down - List of programs to run after connection has been
# terminated. Used to reset protocols, devices, routing
# and firewall.
# Format:
# down {
# option .....;
# option .....;
# };
#
# 'up' and 'down' options:
#
# program - Run specified program.
# Format:
# program path arguments wait;
#
# path - Full path to the program.
# '/bin/sh' will be used if path was omitted.
#
# arguments - Arguments to pass to the program.
# Must be enclosed in double quotes.
# Special characters and expansions:
# ' (single quotes) - group arguments
# \ (back slash) - escape character
# %%(double percent) - same as %d
# %d - TUN or TAP device or TTY port name
# %A - Local IP address
# %P - Local TCP or UDP port
# %a - Remote IP address
# %p - Remote TCP or UDP port
#
# wait - Wait for the program termination.
#
# ppp - Run program specified by 'ppp' statement in
# 'options' section.
# Format:
# ppp arguments;
#
# ifconfig - Run program specified by 'ifconfig' statement in
# 'options' section.
# Format:
# ifconfig arguments;
#
# route - Run program specified by 'route' statement in
# 'options' section.
# Format:
# route arguments;
#
# firewall - Run program specified by 'firewall' statement in
# 'options' section.
# Format:
# firewall arguments;
#
# -----------
# srcaddr - Local (source) address. Used to force vtund to bind
# to the specific address and port in client mode.
# Format:
# srcaddr {
# option .....;
# option .....;
# };
#
# 'srcaddr' options:
#
# iface - Use interface address as the Source address.
# Format:
# iface if_name;
#
# addr - Source address.
# Format:
# addr ip_address;
# addr host_name;
#
# port - Source port.
# Format:
# port port_no;
#
# -----------
# multi - Multiple connections.
# 'yes' or 'allow' - allow multiple connections.
# 'no' or 'deny' - deny multiple connections.
# 'killold' - allow new connection and kill old one.
# Ignored by the client.
#
# -----------
# Notes:
# Options 'Ignored by the client' are provided by server
# at the connection initialization.
#
# Option names cannot be abbreviated.
#
# ----- CUT HERE --- Server config --- CUT HERE -----
#
options {
port 5000; # Listen on this port.
bindaddr { iface lo; }; # Listen only on loopback device.
# Syslog facility
syslog daemon;
# Path to various programs
ppp /usr/sbin/pppd;
ifconfig /sbin/ifconfig;
route /sbin/route;
firewall /sbin/ipchains;
ip /sbin/ip;
}
# Default session options
default {
compress no; # Compression is off by default
speed 0; # By default maximum speed, NO shaping
}
# TUN example. Session 'cobra'.
cobra {
passwd Ma&^TU; # Password
type tun; # IP tunnel
proto udp; # UDP protocol
compress lzo:9; # LZO compression level 9
encrypt yes; # Encryption
keepalive yes; # Keep connection alive
up {
# Connection is Up
# 10.3.0.1 - local, 10.3.0.2 - remote
ifconfig "%% 10.3.0.1 pointopoint 10.3.0.2 mtu 1450";
};
}
# the same as above, but with iproute2 command
cobra {
passwd Ma&^TU; # Password
type tun; # IP tunnel
proto udp; # UDP protocol
compress lzo:9; # LZO compression level 9
encrypt yes; # Encryption
keepalive yes; # Keep connection alive
up {
# Connection is Up
# 10.3.0.1 - local, 10.3.0.2 - remote
ip "link set %% up multicast off mtu 1450";
ip "-family inet addr add 10.3.0.1 peer 10.3.0.2 dev %%";
};
}
# Ethernet example. Session 'lion'.
lion {
passwd Ma&^TU; # Password
type ether; # Ethernet tunnel
device tap0; # Device tap0
proto udp; # UDP protocol
compress lzo:1; # LZO compression level 1
encrypt yes; # Encryption
stat yes; # Log connection statistic
keepalive yes; # Keep connection alive
up {
# Connection is Up
# Assign IP address
ifconfig "%% 10.1.0.1 netmask 255.255.255.0";
# Add route to net 10.2.0.0/24
route "add -net 10.2.0.0 netmask 255.255.255.0 gw 10.1.0.2";
# Enable masquerading for net 10.2.0.0.0/24
firewall "-A forward -s 10.2.0.0/24 -d 0.0.0.0/0 -j MASQ";
};
down {
# Connection is Down
# Shutdown tap device.
ifconfig "%% down";
# Disable masquerading for net 10.2.0.0.0/24
firewall "-D forward -s 10.2.0.0/24 -d 0.0.0.0/0 -j MASQ";
};
}
# PPP example. Session 'viper'.
viper {
passwd TTT$bio; # Password
compress yes; # ZLIB compression level 1
encrypt yes; # Encryption
up {
# Connection is Up (established)
# Assign IP addresses 10.0.0.1 - local, 10.0.0.2 - remote
ppp "10.0.0.1:10.0.0.2 proxyarp";
};
}
# Pipe example. Session 'backup'.
backup {
passwd OnlyME; # Password
type pipe; # Pipe tunnel
speed 256:128; # Shaping speed 256K IN and 128K OUT.
encrypt yes; # Encryption
up {
# Connection is Up
# Start shell and tar '/etc' directory to
# the stdout (pipe tunnel).
program /bin/sh "-c 'tar cf - /etc/*'";
};
}
# TTY example. Session 'sz'.
# Silly example to show that VTun can tunnel ALMOST
# anything :-).
sz {
passwd OnlyME; # Password
type tty; # TTY tunnel
speed 64; # Shaping speed 64K IN/OUT
encrypt yes; # Encryption
up {
# Connection is Up
# Send '/etc/profile' via ZMODEM to the
# stdout(tty tunnel).
program /bin/sh "-c 'sz /etc/termcap'";
};
}
#
# ----- CUT HERE -------- End -------- CUT HERE -----
#
#
# ----- CUT HERE --- Client config --- CUT HERE -----
#
options {
port 5000; # Connect to this port.
timeout 60; # General timeout
# Path to various programs
ppp /usr/sbin/pppd;
ifconfig /sbin/ifconfig;
route /sbin/route;
firewall /sbin/ipchains;
ip /sbin/ip;
}
# TUN example. Session 'cobra'.
cobra {
passwd Ma&^TU; # Password
device tun1; # Device tun1
persist yes; # Persist mode
up {
# Connection is Up
# Assign IP addresses.
ifconfig "%% 10.3.0.2 pointopoint 10.3.0.1 mtu 1450";
};
}
# same as above, but with iproute2 command
cobra {
passwd Ma&^TU; # Password
device tun1; # Device tun1
persist yes; # Persist mode
up {
# Connection is Up
# Assign IP addresses.
ip "link set %% up multicast off mtu 1450";
ip "-family inet addr add 10.3.0.2 peer 10.3.0.1 dev %%";
};
}
# Ethernet example. Session 'lion'.
lion {
passwd Ma&^TU; # Password
type ether; # Ethernet tunnel
device tap1; # Device tap1
up {
# Connection is Up
# Assign IP address and netmask.
ifconfig "%% 10.1.0.2 netmask 255.255.255.0";
};
down {
# Connection is Down
# Shutdown tap device
ifconfig "%% down";
};
}
# PPP example. Session 'viper'.
viper {
passwd TTT$bio; # Password
up {
# Connection is Up
# IP address will be assigned by the server
ppp "noipdefault";
};
}
# Pipe example. Session 'backup'.
backup {
passwd OnlyME; # Password
up {
# Connection is Up
# Start shell and untar files from
# stdin(pipe tunnel).
program /bin/sh "-c 'cd /tmp; tar xf -";
};
}
# TTY example. Session 'sz'.
# Silly example to show that VTun can tunnel ALMOST
# anything :-).
sz {
passwd OnlyME; # Password
up {
# Receive file via ZMODEM from the
# stdin(tty tunnel).
program /bin/sh "-c 'cd /tmp; rz'";
};
}

285
vtund.conf.5 Normal file
View File

@ -0,0 +1,285 @@
.\" Manual page for vtund.conf
.\" $Id: vtund.conf.5,v 1.4.2.1 2007/06/29 05:26:47 mtbishop Exp $
.TH VTUND.CONF 5
.SH NAME
vtund.conf \- VTun(Virtual Tunnel) daemon configuration file.
.SH DESCRIPTION
Configuration file for
.BR vtund (8)
virtual tunnel daemon.
.LP
File consists of sections in the form:
.IP
.nf
.IR name " {"
.IR " keyword value" ;
.IR " keyword value" ;
..
}
.fi
.LP
Semicolon at the end of each keyword-value pair is required,
as well as grouping curly braces {}.
Lines which begin with '#' characters are comments.
.LP
Name of section (\fIname\fR) can be one of:
.IP \fBoptions\fR
this section specifies general options for vtund
.IP \fBdefault\fR
specifies default options for all sessions
.IP \fIsession\fR
(any other word except "options" and "default")
introduces new session and specifies options for it.
.LP
All keyword names can be abbreviated to a minimum of 4 characters.
.LP
.SH "GENERAL OPTIONS"
.LP
This section, named
.BR options ,
specifies general options to use by
.BR vtund (8).
Possible \fIkeyword\fRs are:
.IP \fBtype\fR\ \fBstand\fR|\fBinetd\fR
server type. \fBvtund\fR(8) can operate in standalone
mode (\fBstand\fR), that is the default, or be invoked from
.BR inetd (8).
.IP \fBport\ \fIportnumber\fR
server port number to listen on or connect to.
By default, \fBvtund\fR(8) uses port 5000.
.IP \fBbindaddr\ \fIlist\fR
server listen address. Used to force vtund to bind to the specific
address and port in server mode. Format:
.nf
\fBbindaddr\fR {
\fIoption \fIvalue\fR;
};
.fi
.IP
\fBbindaddr\fR options:
.RS
.IP \fBiface\ \fIif_name\fR
use interface address \fIif_name\fR as the bind address.
.IP \fBaddr\ \fIaddr\fR
bind address. Can be either IP address or host name.
.RE
.IP \fBtimeout\ \fIseconds\fR
General timeout.
.IP \fBpersist\fR\ \fByes\fR|\fBkeep\fR|\fBno\fR
persist mode. If \fByes\fR, the client will try to reconnect to the server
after connection termination. If \fBkeep\fR, the client will not remove
and re-add the \fBtun\fIXX\fR or \fBtap\fIXX\fR device when reconnecting.
If \fBno\fR, the client will exit (default).
This option is ignored by the server.
.IP \fBsyslog\fR\ \fBnumber\fR|\fBname\fR
syslog facility specification, either numeric or name (from syslog (3)).
.IP \fBppp\ \fIpath\fR
path to \fBpppd\fR(8) program. Can be used in session sections.
.IP \fBifconfig\ \fIpath\fR
path to \fBifconfig\fR(8) program. Can be used in session sections.
.IP \fBroute\ \fIpath\fR
path to \fBroute\fR(8) program. Can be used in session sections.
.IP \fBip\ \fIpath\fR
path to \fBiproute\fR(8) program. Can be used in session sections.
.IP \fBfirewall\ \fIpath\fR
program for the firewall setup.
.LP
All the \fBppp\fR, \fBifconfig\fR, \fBroute\fR and \fBfirewall\fR
parameters can specify a filename for corresponding program or
equivalent (or shell script). This parameters are used in session sections
to setup network interfaces.
.SH "SESSION OPTIONS"
.LP
Session options can be specified inside session section or
inside \fBdefault\fR section. Default parameters apply
to any session section but can be overwritten there.
Parameters are:
.IP \fBpasswd\ \fIsecret\fR
password for authentication. This should be the same in
client and server.
.IP \fBtype\ \fItype\fR
type of tunnel. Possible tunnel types are:
.RS
.IP \fBtun\fR
IP tunnel (no PPP, Ether etc headers)
.IP \fBether\fR
Ethernet tunnel
.IP \fBtty\fR
serial tunnel (PPP, SLIP etc)
.IP \fBpipe\fR
pipe tunnel
.RE
.IP
Default tunnel type is \fBtty\fR.
This option is ignored by client.
.IP \fBdevice\ \fIdev\fR
network device to use. You can choose
\fBtap\fIXX\fR for \fBether\fR tunnel
or \fBtun\fIXX\fR for \fBtun\fR tunnel.
By default \fBvtund\fR(8) will automatically select available device.
.IP \fBproto\ \fBtcp\fR|\fBudp\fR
protocol to use. By default, \fBvtund\fR(8) will use TCP protocol.
UDP is recommended for \fBether\fR and \fBtun\fR tunnels only.
This option is ignored by the client.
.IP \fBtimeout\ \fIsecounds\fR
Connect timeout.
.IP \fBcompress\ \fImethod\fR[\fB:\fIlevel\fR]
specifies compression method to use. Compression \fImethod\fRs includes:
.RS
.IP \fBno\fR
no compression
.IP \fByes\fR
default compression method
.IP \fBzlib\fR
ZLIB compression
.IP \fBlzo\fR
LZO compression (if compiled in)
.RE
.IP
You can also specify \fIlevel\fR of compression using one
digit (1 is best speed, 9 is best compression ratio).
This option ignored by the client.
.IP \fBencrypt\ \fByes\fR|\fBno\fR
enable or disable encryption. This option ignored by the client.
.IP \fBkeepalive\ \fByes\fR|\fBno\fR
enable or disable connection keep-alive.
This option is ignored by the client.
.IP \fBstat\ \fByes\fR|\fBno\fR
enable or disable statistics. If enabled \fBvtund\fR(8) will log
statistic counters to /var/log/vtund/session_X every 5 minutes.
.IP \fBspeed\ \fIkbps\fR
specifies speed of the connection in kilobits/second.
Valid values for \fIkbps\fR are 8,16,32,64,128,256,etc.
0 (the default) means maximum possible speed without shaping.
You can specify speed in form \fIin\fB:\fIout\fR, where
\fIin\fR is speed to client, \fIout\fR - from the client.
Single number means the same speed for in and out.
This option ignored by the client.
.IP \fBsrcaddr\ \fIlist\fR
local (source) address. Used to force vtund to bind to the specific
address and port. Format:
.nf
\fBsrcaddr\fR {
\fIoption \fIvalue\fR;
\fIoption \fIvalue\fR;
..
};
.fi
.IP
\fBsrcaddr\fR options:
.RS
.IP \fBiface\ \fIif_name\fR
use interface address \fIif_name\fR as the source address.
.IP \fBaddr\ \fIaddr\fR
source address. Can be either IP address or host name.
.IP \fBport\ \fIportnumber\fR
source port.
.RE
.IP \fBmulti\ \fIvalue\fR
control multiple connections. \fIvalue\fR can be
\fByes\fR or \fBallow\fR to allow multiple connections,
\fBno\fR or \fBdeny\fR to deny them or
\fBkillold\fR to allow new connection and kill old one.
Ignored by the client.
.IP \fBup\ \fIlist\fR
list of programs to run after connection has been established.
Used to initialize protocols, devices, routing and firewall.
This option looks like whole section inside of session section.
Format:
.nf
\fBup\fR {
\fIoption \fIvalue\fR;
\fIoption \fIvalue\fR;
..
};
.fi
.IP
Options inside \fBup\fR (and \fBdown\fR) blocks:
.RS
.IP \fBprogram\ \fIpath\ arguments\fR\ [\fBwait\fR]
run specified program. \fIpath\fR is the full path to the program,
\fIarguments\fR is all arguments to pass to it (enclosed in double quotes).
If \fIwait\fR specified, \fBvtund\fR will wait program termination.
Special characters that can be used inside \fIarguments\fR parameter:
.IP
\fB\'\fR (single quotes) - group arguments
.br
\fB\\\fR (back slash) - escape character
.br
\fB%d\fR - TUN or TAP device or TTY port name
.br
\fB%%\fR (double percent) - same as %d
.br
\fB%A\fR - Local IP address
.br
\fB%P\fR - Local TCP or UDP port
.br
\fB%a\fR - Remote IP address
.br
\fB%p\fR - Remote TCP or UDP port
.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.
.IP \fBifconfig\ \fIarguments\fR
run program specified by \fBifconfig\fR statement in \fBoptions\fR section.
.IP \fBroute\ \fIarguments\fR
run program specified by \fBroute\fR statement in \fBoptions\fR section.
.IP \fBip\ \fIarguments\fR
run program specified by \fBip\fR statement in \fBoptions\fR section.
.IP \fBfirewall\ \fIarguments\fR
run program specified by \fBfirewall\fR statement in \fBoptions\fR section.
.RE
.IP \fBdown\ \fIlist\fR
list of programs to run after connection has been terminated.
It is similar to \fBup\fR parameter above.
Format:
.nf
\fBdown\fR {
\fIoption \fIvalue\fR;
\fIoption \fIvalue\fR;
..
};
.fi
.SH NOTES
Options ignored by the client are supplied by the server at the run
time or are used only on the server side.
.SH "SEE ALSO"
.BR vtund (8),
.BR inetd (8),
.BR ifconfig (8),
.BR route (8),
.BR pppd (8),
.BR syslog (3),
.BR zlib (3).
.SH AUTHOR
Vtund written by Maxim Krasnyansky <max_mk@yahoo.com>.
This manual page was derived from comments in config file by
Michael Tokarev <mjt@tls.msk.ru>