X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/tripe/blobdiff_plain/786989941b7b4504f0234c4a318f929802e981ad..eb5f3fea8a65306e424a353951208b11bd3aac22:/server/tun-unet.c diff --git a/server/tun-unet.c b/server/tun-unet.c index c2b6e771..88ce83d0 100644 --- a/server/tun-unet.c +++ b/server/tun-unet.c @@ -1,13 +1,11 @@ /* -*-c-*- - * - * $Id$ * * Tunnel interface based on Linux Usernet * * (c) 2001 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of Trivial IP Encryption (TrIPE). * @@ -15,12 +13,12 @@ * 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. @@ -48,29 +46,6 @@ struct tunnel { struct peer *p; /* Pointer to my peer */ }; -/* --- @t_ifname@ --- * - * - * Arguments: @tunnel *t@ = pointer to tunnel block - * - * Returns: A pointer to the tunnel's interface name. - */ - -static const char *t_ifname(tunnel *t) -{ - static char b[UNET_NAMEMAX]; - struct unet_info uni; - if (ioctl(t->f.fd, UNIOCGINFO, &uni)) { - a_warn("TUN", "-", "unet", "getinfo-error", "?ERRNO", A_END); - return (""); - } - if (strlen(uni.uni_ifname) + 1 > sizeof(b)) { - a_warn("TUN", "-", "unet", "ifname-too-long", A_END); - return (""); - } - strcpy(b, uni.uni_ifname); - return (b); -} - /* --- @t_read@ --- * * * Arguments: @int fd@ = file descriptor to read @@ -90,7 +65,7 @@ static void t_read(int fd, unsigned mode, void *v) n = read(fd, buf_i, sizeof(buf_i)); if (n < 0) { - a_warn("TUN", "%s", t_ifname(t), "read-error", "?ERRNO", A_END); + a_warn("TUN", "%s", p_ifname(t->p), "read-error", "?ERRNO", A_END); return; } IF_TRACING(T_TUNNEL, { @@ -113,40 +88,65 @@ static void t_read(int fd, unsigned mode, void *v) static void t_init(void) { return; } -/* --- @t_create@ --- * +/* --- @t_open@ --- * * - * Arguments: @tunnel *t@ = pointer to tunnel block - * @peer *p@ = pointer to peer block + * Arguments: @char **ifn@ = where to put the interface name * - * Returns: A tunnel block if it worked, or null on failure. + * Returns: A file descriptor, or @-1@ on failure. * - * Use: Initializes a new tunnel. + * Use: Opens a tunnel device. This will run with root privileges + * even if the rest of the server has dropped them. */ -static tunnel *t_create(peer *p) +static int t_open(char **ifn) { int fd; - tunnel *t; int f; + struct unet_info uni; if ((fd = open("/dev/unet", O_RDWR)) < 0) { a_warn("TUN", "-", "unet", "open-error", "/dev/unet", "?ERRNO", A_END); - return (0); + goto fail_0; } - fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC); if ((f = ioctl(fd, UNIOCGIFFLAGS)) < 0 || ioctl(fd, UNIOCSIFFLAGS, f | IFF_POINTOPOINT)) { a_warn("TUN", "-", "unet", "config-error", "?ERRNO", A_END); - close(fd); - return (0); + goto fail_1; + } + if (ioctl(t->f.fd, UNIOCGINFO, &uni)) { + a_warn("TUN", "-", "unet", "getinfo-error", "?ERRNO", A_END); + goto fail_1; } + *ifn = xstrdup(uni.uni_ifname); + return (fd); + +fail_1: + close(fd); +fail_0: + return (-1); +} + +/* --- @t_create@ --- * + * + * Arguments: @peer *p@ = pointer to peer block + * @int fd@ = file descriptor of tunnel device + * @char **ifn@ = where to put the interface name + * + * Returns: A tunnel block if it worked, or null on failure. + * + * Use: Initializes a new tunnel. + */ + +static tunnel *t_create(peer *p, int fd, char **ifn) +{ + tunnel *t; + + fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC); t = CREATE(tunnel); t->ops = &tun_unet; t->p = p; sel_initfile(&sel, &t->f, fd, SEL_READ, t_read, t); sel_addfile(&t->f); - T( trace(T_TUNNEL, "tun-unet: attached interface %s to peer `%s'", - t_ifname(t), p_name(p)); ) return (t); } @@ -179,17 +179,14 @@ static void t_inject(tunnel *t, buf *b) */ static void t_destroy(tunnel *t) -{ - sel_rmfile(&t->f); - close(t->f.fd); - DESTROY(t); -} + { sel_rmfile(&t->f); close(t->f.fd); DESTROY(t); } const tunnel_ops tun_unet = { "unet", t_init, + t_open, t_create, - t_ifname, + 0, t_inject, t_destroy };