From 3707586241f0c48d3c38987250d58a8cb7c62459 Mon Sep 17 00:00:00 2001 Message-Id: <3707586241f0c48d3c38987250d58a8cb7c62459.1714043350.git.mdw@distorted.org.uk> From: Mark Wooding Date: Sun, 6 Apr 2003 10:25:17 +0000 Subject: [PATCH] Support Linux TUN/TAP device. Fix some bugs. Organization: Straylight/Edgeware From: mdw --- admin.c | 7 +- configure.in | 27 ++++++-- doc/tripe.8 | 2 +- tripe.h | 17 ++++- tun-linux.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 222 insertions(+), 10 deletions(-) create mode 100644 tun-linux.c diff --git a/admin.c b/admin.c index 95e0e7cc..c1c2c128 100644 --- a/admin.c +++ b/admin.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: admin.c,v 1.7 2002/01/13 14:57:33 mdw Exp $ + * $Id: admin.c,v 1.8 2003/04/06 10:25:17 mdw Exp $ * * Admin interface for configuration * @@ -29,6 +29,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: admin.c,v $ + * Revision 1.8 2003/04/06 10:25:17 mdw + * Support Linux TUN/TAP device. Fix some bugs. + * * Revision 1.7 2002/01/13 14:57:33 mdw * Track @lbuf@ and @dstr_vputf@ changes in mLib. * @@ -276,7 +279,7 @@ void a_warn(const char *fmt, ...) if (flags & F_INIT) dstr_puts(&d, "WARN "); va_start(ap, fmt); - dstr_vputf(&d, fmt, ap); + dstr_vputf(&d, fmt, &ap); va_end(ap); if (!(flags & F_INIT)) moan("%s", d.buf); diff --git a/configure.in b/configure.in index de7f3acb..169907c3 100644 --- a/configure.in +++ b/configure.in @@ -1,6 +1,6 @@ dnl -*-fundamental-*- dnl -dnl $Id: configure.in,v 1.6 2001/06/19 22:13:57 mdw Exp $ +dnl $Id: configure.in,v 1.7 2003/04/06 10:25:17 mdw Exp $ dnl dnl Configuration script for TrIPE dnl @@ -28,6 +28,9 @@ dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. dnl ----- Revision history -------------------------------------------------- dnl dnl $Log: configure.in,v $ +dnl Revision 1.7 2003/04/06 10:25:17 mdw +dnl Support Linux TUN/TAP device. Fix some bugs. +dnl dnl Revision 1.6 2001/06/19 22:13:57 mdw dnl Version bump. dnl @@ -48,18 +51,32 @@ dnl Initial checkin. dnl AC_INIT(tripe.c) -AM_INIT_AUTOMAKE(tripe, 1.0.0pre2) +AM_INIT_AUTOMAKE(tripe, 1.0.0pre3) AM_CONFIG_HEADER(config.h) AC_CANONICAL_HOST AC_PROG_CC -mdw_GCC_FLAGS +mdw_GCC_FLAGS([-Wall]) mdw_OPT_TRACE +AC_ARG_WITH([linux-includes], +[ --with-linux-includes=DIR + search for Linux kernel includes in DIR], +[CFLAGS="$CFLAGS -I$withval"], +[:]) + case $host_os in linux*) - tun=unet - AC_DEFINE([TUN_TYPE], [TUN_UNET]) + case `uname -r` in + 2.[4-9].* | 2.??*.* | 3-9.* | ??*.*) + tun=linux + AC_DEFINE([TUN_TYPE], [TUN_LINUX]) + ;; + *) + tun=unet + AC_DEFINE([TUN_TYPE], [TUN_UNET]) + ;; + esac ;; *bsd*) tun=bsd diff --git a/doc/tripe.8 b/doc/tripe.8 index fd73144d..be81d559 100644 --- a/doc/tripe.8 +++ b/doc/tripe.8 @@ -264,7 +264,7 @@ files, and put the public key in .BR keyring.pub : .VS key extract param param -key extract \-f\-secret alice alice.pub +key extract \-f\-secret alice.pub alice key \-kkeyring.pub merge alice.pub .VE Send the files diff --git a/tripe.h b/tripe.h index 420a6fdf..069840e7 100644 --- a/tripe.h +++ b/tripe.h @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: tripe.h,v 1.11 2002/01/13 14:57:42 mdw Exp $ + * $Id: tripe.h,v 1.12 2003/04/06 10:25:17 mdw Exp $ * * Main header file for TrIPE * @@ -29,6 +29,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: tripe.h,v $ + * Revision 1.12 2003/04/06 10:25:17 mdw + * Support Linux TUN/TAP device. Fix some bugs. + * * Revision 1.11 2002/01/13 14:57:42 mdw * Fix crap typo. * @@ -101,6 +104,11 @@ #include #include +#if TUN_TYPE == TUN_LINUX +# include +# include +#endif + #include #include @@ -147,6 +155,7 @@ #define TUN_NOTDEF 0 #define TUN_UNET 1 #define TUN_BSD 2 +#define TUN_LINUX 3 /* --- Trace flags --- */ @@ -376,9 +385,13 @@ enum { */ typedef struct tunnel { -#if TUN_TYPE == TUN_UNET +#if TUN_TYPE == TUN_UNET sel_file f; /* Selector for Usernet device */ struct peer *p; /* Pointer to my peer */ +#elif TUN_TYPE == TUN_LINUX + sel_file f; /* Selector for TUN/TAP device */ + struct peer *p; /* Pointer to my peer */ + char ifn[IFNAMSIZ]; /* Interface name buffer */ #elif TUN_TYPE == TUN_BSD sel_file f; /* Selector for tunnel device */ struct peer *p; /* Pointer to my peer */ diff --git a/tun-linux.c b/tun-linux.c new file mode 100644 index 00000000..5ffd0ade --- /dev/null +++ b/tun-linux.c @@ -0,0 +1,179 @@ +/* -*-c-*- + * + * $Id: tun-linux.c,v 1.1 2003/04/06 10:25:17 mdw Exp $ + * + * Tunnel interface based on Linux TUN/TAP driver + * + * (c) 2003 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Trivial IP Encryption (TrIPE). + * + * TrIPE 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. + * + * TrIPE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with TrIPE; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/*----- Revision history --------------------------------------------------* + * + * $Log: tun-linux.c,v $ + * Revision 1.1 2003/04/06 10:25:17 mdw + * Support Linux TUN/TAP device. Fix some bugs. + * + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "tripe.h" + +#include + +/*----- Main code ---------------------------------------------------------*/ + +#if TUN_TYPE != TUN_LINUX +# error "Tunnel type mismatch: fix the Makefile" +#endif + +/* --- @t_read@ --- * + * + * Arguments: @int fd@ = file descriptor to read + * @unsigned mode@ = what's happened + * @void *v@ = pointer to tunnel block + * + * Returns: --- + * + * Use: Reads data from the tunnel. + */ + +static void t_read(int fd, unsigned mode, void *v) +{ + tunnel *t = v; + ssize_t n; + buf b; + + n = read(fd, buf_i, sizeof(buf_i)); + if (n < 0) { + a_warn("tunnel read failed (%s): %s", t->ifn, strerror(errno)); + return; + } + IF_TRACING(T_TUNNEL, { + trace(T_TUNNEL, "tunnel: packet arrived"); + trace_block(T_PACKET, "tunnel: packet contents", buf_i, n); + }) + buf_init(&b, buf_i, n); + p_tun(t->p, &b); +} + +/* --- @tun_init@ --- * + * + * Arguments: --- + * + * Returns: --- + * + * Use: Initializes the tunneling system. Maybe this will require + * opening file descriptors or something. + */ + +void tun_init(void) +{ + return; +} + +/* --- @tun_create@ --- * + * + * Arguments: @tunnel *t@ = pointer to tunnel block + * @peer *p@ = pointer to peer block + * + * Returns: Zero if it worked, nonzero on failure. + * + * Use: Initializes a new tunnel. + */ + +int tun_create(tunnel *t, peer *p) +{ + int fd; + int f; + struct ifreq iff; + + if ((fd = open("/dev/net/tun", O_RDWR)) < 0) { + a_warn("open `/dev/net/tun' failed: %s", strerror(errno)); + return (-1); + } + fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC); + iff.ifr_name[0] = 0; + iff.ifr_flags = IFF_TUN | IFF_NO_PI; + if ((f = ioctl(fd, TUNSETIFF, &iff)) < 0) { + a_warn("couldn't set configure new TUN/TAP interface: %s", + strerror(errno)); + close(fd); + return (-1); + } + t->p = p; + sel_initfile(&sel, &t->f, fd, SEL_READ, t_read, t); + sel_addfile(&t->f); + iff.ifr_name[IFNAMSIZ - 1] = 0; + strcpy(t->ifn, iff.ifr_name); + T( trace(T_TUNNEL, "tunnel: attached interface %s to peer `%s'", + t->ifn, p_name(p)); ) + return (0); +} + +/* --- @tun_ifname@ --- * + * + * Arguments: @tunnel *t@ = pointer to tunnel block + * + * Returns: A pointer to the tunnel's interface name. + */ + +const char *tun_ifname(tunnel *t) +{ + return (t->ifn); +} + +/* --- @tun_inject@ --- * + * + * Arguments: @tunnel *t@ = pointer to tunnel block + * @buf *b@ = buffer to send + * + * Returns: --- + * + * Use: Injects a packet into the local network stack. + */ + +void tun_inject(tunnel *t, buf *b) +{ + IF_TRACING(T_TUNNEL, { + trace(T_TUNNEL, "tunnel: inject decrypted packet"); + trace_block(T_PACKET, "tunnel: packet contents", BBASE(b), BLEN(b)); + }) + write(t->f.fd, BBASE(b), BLEN(b)); +} + +/* --- @tun_destroy@ --- * + * + * Arguments: @tunnel *t@ = pointer to tunnel block + * + * Returns: --- + * + * Use: Destroys a tunnel. + */ + +void tun_destroy(tunnel *t) +{ + sel_rmfile(&t->f); + close(t->f.fd); +} + +/*----- That's all, folks -------------------------------------------------*/ -- [mdw]