X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/tripe/blobdiff_plain/410c8acf139e945dce28bbc0c8b17dcfd0815643..575e728f946cbe7f954a46bce8b86ddb022d404a:/tun-unet.c diff --git a/tun-unet.c b/tun-unet.c index d78c9a11..c93803ee 100644 --- a/tun-unet.c +++ b/tun-unet.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: tun-unet.c,v 1.1 2001/02/03 20:26:37 mdw Exp $ + * $Id$ * * Tunnel interface based on Linux Usernet * @@ -26,23 +26,51 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: tun-unet.c,v $ - * Revision 1.1 2001/02/03 20:26:37 mdw - * Initial checkin. - * - */ - /*----- Header files ------------------------------------------------------*/ +#define TUN_INTERNALS + #include "tripe.h" -#include -#include +#ifdef TUN_UNET +# include +# include +# include +#endif /*----- Main code ---------------------------------------------------------*/ +#ifdef TUN_UNET + +struct tunnel { + const tunnel_ops *ops; /* Pointer to operations */ + sel_file f; /* Selector for Usernet device */ + 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 -- %s", strerror(errno)); + return (""); + } + if (strlen(uni.uni_ifname) + 1 > sizeof(b)) { + a_warn("TUN - unet ifname-too-long"); + return (""); + } + strcpy(b, uni.uni_ifname); + return (b); +} + /* --- @t_read@ --- * * * Arguments: @int fd@ = file descriptor to read @@ -54,7 +82,7 @@ * Use: Reads data from the tunnel. */ -void t_read(int fd, unsigned mode, void *v) +static void t_read(int fd, unsigned mode, void *v) { tunnel *t = v; ssize_t n; @@ -62,18 +90,18 @@ void t_read(int fd, unsigned mode, void *v) n = read(fd, buf_i, sizeof(buf_i)); if (n < 0) { - a_warn("tunnel read failed (%s): %s", tun_ifname(t), strerror(errno)); + a_warn("TUN %s read-error -- %s", t_ifname(t), strerror(errno)); return; } IF_TRACING(T_TUNNEL, { - trace(T_TUNNEL, "tunnel: packet arrived"); - trace_block(T_PACKET, "tunnel: packet contents", buf_i, n); + trace(T_TUNNEL, "tun-unet: packet arrived"); + trace_block(T_PACKET, "tun-unet: packet contents", buf_i, n); }) buf_init(&b, buf_i, n); p_tun(t->p, &b); } -/* --- @tun_init@ --- * +/* --- @t_init@ --- * * * Arguments: --- * @@ -83,61 +111,46 @@ void t_read(int fd, unsigned mode, void *v) * opening file descriptors or something. */ -void tun_init(void) -{ - return; -} +static void t_init(void) { return; } -/* --- @tun_create@ --- * +/* --- @t_create@ --- * * * Arguments: @tunnel *t@ = pointer to tunnel block * @peer *p@ = pointer to peer block * - * Returns: Zero if it worked, nonzero on failure. + * Returns: A tunnel block if it worked, or null on failure. * * Use: Initializes a new tunnel. */ -int tun_create(tunnel *t, peer *p) +static tunnel *t_create(peer *p) { int fd; + tunnel *t; + int f; if ((fd = open("/dev/unet", O_RDWR)) < 0) { - a_warn("open `/dev/unet' failed: %s", strerror(errno)); - return (-1); + a_warn("TUN - open-error /dev/unet -- %s", strerror(errno)); + return (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 -- %s", strerror(errno)); + close(fd); + return (0); } + 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, "tunnel: attached interface %s to peer `%s'", - tun_ifname(t), p_name(p)); ) - return (0); + T( trace(T_TUNNEL, "tun-unet: attached interface %s to peer `%s'", + t_ifname(t), p_name(p)); ) + return (t); } -/* --- @tun_ifname@ --- * - * - * Arguments: @tunnel *t@ = pointer to tunnel block - * - * Returns: A pointer to the tunnel's interface name. - */ - -const char *tun_ifname(tunnel *t) -{ - static char b[UNET_NAMEMAX]; - struct unet_info uni; - if (ioctl(t->f.fd, UNIOCGINFO, &uni)) { - a_warn("ioctl(UNIOCGINFO) failed: %s", strerror(errno)); - return (""); - } - if (strlen(uni.uni_ifname) + 1 > sizeof(b)) { - a_warn("interface name too long!"); - return (""); - } - strcpy(b, uni.uni_ifname); - return (b); -} - -/* --- @tun_inject@ --- * +/* --- @t_inject@ --- * * * Arguments: @tunnel *t@ = pointer to tunnel block * @buf *b@ = buffer to send @@ -147,16 +160,16 @@ const char *tun_ifname(tunnel *t) * Use: Injects a packet into the local network stack. */ -void tun_inject(tunnel *t, buf *b) +static void t_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)); + trace(T_TUNNEL, "tun-unet: inject decrypted packet"); + trace_block(T_PACKET, "tun-unet: packet contents", BBASE(b), BLEN(b)); }) write(t->f.fd, BBASE(b), BLEN(b)); } -/* --- @tun_destroy@ --- * +/* --- @t_destroy@ --- * * * Arguments: @tunnel *t@ = pointer to tunnel block * @@ -165,10 +178,22 @@ void tun_inject(tunnel *t, buf *b) * Use: Destroys a tunnel. */ -void tun_destroy(tunnel *t) +static void t_destroy(tunnel *t) { sel_rmfile(&t->f); close(t->f.fd); + DESTROY(t); } +const tunnel_ops tun_unet = { + "unet", + t_init, + t_create, + t_ifname, + t_inject, + t_destroy +}; + +#endif + /*----- That's all, folks -------------------------------------------------*/