X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/tripe/blobdiff_plain/98fdb08d96bd62384e5f4f18d63bd2045c302e1f..42da2a58637902f3bba731a83538804e57e340bf:/tun-slip.c diff --git a/tun-slip.c b/tun-slip.c index b9914e43..2d94033b 100644 --- a/tun-slip.c +++ b/tun-slip.c @@ -28,8 +28,35 @@ /*----- Header files ------------------------------------------------------*/ +#define TUN_INTERNALS + #include "tripe.h" +/*----- Data structures ---------------------------------------------------*/ + +typedef struct slipif { + struct slipif *next; /* Next one in the list */ + int ifd, ofd; /* File descriptors to talk on */ + char *name; /* Interface name */ + pid_t kid; /* Child process id */ + unsigned f; /* Various flags */ +# define F_INUSE 1u /* Interface is in use */ +# define F_DYNAMIC 2u /* Interface found dynamically */ +} slipif; + +struct tunnel { + const tunnel_ops *ops; /* Pointer to operations */ + slipif *sl; /* My interface record */ + sel_file f; /* Selector for SLIP tty */ + struct peer *p; /* Pointer to my peer */ + unsigned st; /* Current parser state */ +# define ST_ESC 1u /* Last saw an escape character */ +# define ST_BAD 2u /* This packet is malformed */ +# define ST_EOF 4u /* File descriptor reported EOF */ + size_t n; /* Number of bytes used in buffer */ + octet buf[PKBUFSZ]; /* Buffer for incoming data */ +}; + /*----- Static variables --------------------------------------------------*/ static slipif *slipifs; /* List of available interfaces */ @@ -37,10 +64,6 @@ static const char *slipcmd; /* Script to make new interfaces */ /*----- Main code ---------------------------------------------------------*/ -#if TUN_TYPE != TUN_SLIP -# error "Tunnel type mismatch: fix the Makefile" -#endif - #define SL_END 0xc0 #define SL_ESC 0xdb #define SL_ESCEND 0xdc @@ -82,7 +105,7 @@ static void t_read(int fd, unsigned mode, void *v) } if (!n) { a_warn("TUN %s slip eof", t->sl->name); - t->st = SLIPST_EOF; + t->st = ST_EOF; sel_rmfile(&t->f); return; } @@ -100,9 +123,9 @@ static void t_read(int fd, unsigned mode, void *v) o = *p; switch (o) { case SL_END: - if (st & SLIPST_BAD) + if (st & ST_BAD) ; - else if (st & SLIPST_ESC) + else if (st & ST_ESC) a_warn("TUN %s slip escape-end", t->sl->name); else if (q == t->buf) { T( trace(T_TUNNEL, "tunnel: empty packet"); ) @@ -116,38 +139,38 @@ static void t_read(int fd, unsigned mode, void *v) p_tun(t->p, &b); } q = t->buf; - st &= ~(SLIPST_ESC | SLIPST_BAD); + st &= ~(ST_ESC | ST_BAD); break; case SL_ESC: - if ((st & SLIPST_ESC) && !(st & SLIPST_BAD)) { + if ((st & ST_ESC) && !(st & ST_BAD)) { a_warn("TUN %s slip bad-escape", t->sl->name); - st |= SLIPST_BAD; + st |= ST_BAD; } else - st |= SLIPST_ESC; + st |= ST_ESC; break; case SL_ESCEND: - if (st & SLIPST_ESC) + if (st & ST_ESC) o = SL_END; goto emit; case SL_ESCESC: - if (st & SLIPST_ESC) + if (st & ST_ESC) o = SL_ESC; goto emit; default: - if ((st & SLIPST_ESC) && !(st & SLIPST_BAD)) { + if ((st & ST_ESC) && !(st & ST_BAD)) { a_warn("TUN %s slip bad-escape", t->sl->name); - st |= SLIPST_BAD; + st |= ST_BAD; } emit: - if (!(st & SLIPST_BAD)) { + if (!(st & ST_BAD)) { if (q < ll) *q++ = o; else { a_warn("TUN %s slip overflow", t->sl->name); - st |= SLIPST_BAD; + st |= ST_BAD; } } - st &= ~SLIPST_ESC; + st &= ~ST_ESC; break; } } @@ -156,7 +179,7 @@ static void t_read(int fd, unsigned mode, void *v) t->st = st; } -/* --- @tun_init@ --- * +/* --- @t_init@ --- * * * Arguments: --- * @@ -166,7 +189,7 @@ static void t_read(int fd, unsigned mode, void *v) * opening file descriptors or something. */ -void tun_init(void) +static void t_init(void) { char *p, *q; dstr d = DSTR_INIT; @@ -175,7 +198,7 @@ void tun_init(void) size_t n; if ((p = getenv("TRIPE_SLIPIF")) == 0) - die(1, "no slip interfaces listed: set TRIPE_SLIPIF"); + return; /* --- Build the list of available interfaces --- */ @@ -224,32 +247,32 @@ void tun_init(void) return; whine: - die(1, "bad slip interface list"); + moan("bad slip interface list"); } -/* --- @tun_create@ --- * +/* --- @t_create@ --- * * - * Arguments: @tunnel *t@ = pointer to tunnel block - * @peer *p@ = pointer to peer block + * Arguments: @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) { slipif *sl = 0; int pin[2] = { -1, -1 }, pout[2] = { -1, -1 }; pid_t kid = -1; dstr d = DSTR_INIT; unsigned char ch; + tunnel *t; static const char end[] = { SL_END, SL_END }; /* --- Try to find a spare static interface --- */ for (sl = slipifs; sl; sl = sl->next) { - if (!(sl->f & SLIPIFF_INUSE)) { + if (!(sl->f & F_INUSE)) { T( trace(T_TUNNEL, "tunnel: %s using static slipif %s", p_name(p), sl->name); ) goto found; @@ -259,18 +282,18 @@ int tun_create(tunnel *t, peer *p) /* --- If no dynamic interfaces are available, give up --- */ if (!slipcmd) { - a_warn("TUN %s slip no-slip-interfaces", p_name(p)); + a_warn("TUN - slip no-slip-interfaces"); goto fail; } /* --- Fork off a child process to create a dynamic SLIP interface --- */ if (pipe(pin) || pipe(pout)) { - a_warn("TUN %s slip pipe-error -- %s", p_name(p), strerror(errno)); + a_warn("TUN - slip pipe-error -- %s", strerror(errno)); goto fail; } if ((kid = fork()) < 0) { - a_warn("TUN %s slip fork-error -- %s", p_name(p), strerror(errno)); + a_warn("TUN - slip fork-error -- %s", strerror(errno)); goto fail; } if (!kid) { @@ -290,8 +313,7 @@ int tun_create(tunnel *t, peer *p) for (;;) { errno = EIO; if (read(pout[0], &ch, 1) != 1 || ch == SL_END) { - a_warn("TUN %s slip read-ifname-failed -- %s", - p_name(p), strerror(errno)); + a_warn("TUN - slip read-ifname-failed -- %s", strerror(errno)); goto fail; } if (ch == '\n') @@ -304,7 +326,7 @@ int tun_create(tunnel *t, peer *p) sl->ofd = pin[1]; sl->kid = kid; sl->next = 0; - sl->f = SLIPIFF_DYNAMIC; + sl->f = F_DYNAMIC; T( trace(T_TUNNEL, "tunnel: %s using dynamic slipif %s", p_name(p), sl->name); ) fdflags(pout[0], O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC); @@ -313,16 +335,18 @@ int tun_create(tunnel *t, peer *p) /* --- Set up the new tunnel --- */ found: + t = CREATE(tunnel); + t->ops = &tun_slip; t->p = p; t->sl = sl; t->st = 0; t->n = 0; - sl->f |= SLIPIFF_INUSE; + sl->f |= F_INUSE; sel_initfile(&sel, &t->f, sl->ifd, SEL_READ, t_read, t); sel_addfile(&t->f); write(sl->ofd, end, sizeof(end)); dstr_destroy(&d); - return (0); + return (t); /* --- Tidy up after a failure --- */ @@ -332,21 +356,21 @@ fail: CLOSE(pin[1]); CLOSE(pout[1]); #undef CLOSE if (kid != -1) kill(kid, SIGTERM); - if (sl && (sl->f & SLIPIFF_DYNAMIC)) DESTROY(sl); + if (sl && (sl->f & F_DYNAMIC)) DESTROY(sl); dstr_destroy(&d); - return (-1); + return (0); } -/* --- @tun_ifname@ --- * +/* --- @t_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->sl->name); } +static const char *t_ifname(tunnel *t) { return (t->sl->name); } -/* --- @tun_inject@ --- * +/* --- @t_inject@ --- * * * Arguments: @tunnel *t@ = pointer to tunnel block * @buf *b@ = buffer to send @@ -356,7 +380,7 @@ const char *tun_ifname(tunnel *t) { return (t->sl->name); } * Use: Injects a packet into the local network stack. */ -void tun_inject(tunnel *t, buf *b) +static void t_inject(tunnel *t, buf *b) { octet buf[PKBUFSZ * 2 + 2]; const octet *p, *l; @@ -384,7 +408,7 @@ void tun_inject(tunnel *t, buf *b) write(t->sl->ofd, buf, q - buf); } -/* --- @tun_destroy@ --- * +/* --- @t_destroy@ --- * * * Arguments: @tunnel *t@ = pointer to tunnel block * @@ -393,17 +417,17 @@ void tun_inject(tunnel *t, buf *b) * Use: Destroys a tunnel. */ -void tun_destroy(tunnel *t) +static void t_destroy(tunnel *t) { slipif *sl = t->sl; /* --- If it reported EOF, leave it out-of-action --- */ - if (!(t->st & SLIPST_EOF)) { + if (!(t->st & ST_EOF)) { sel_rmfile(&t->f); - sl->f &= ~SLIPIFF_INUSE; + sl->f &= ~F_INUSE; } - if (sl && (sl->f & SLIPIFF_DYNAMIC)) { + if (sl && (sl->f & F_DYNAMIC)) { T( trace(T_TUNNEL, "tunnel: releasing dynamic slipif %s", sl->name); ) close(sl->ofd); close(sl->ifd); @@ -411,6 +435,16 @@ void tun_destroy(tunnel *t) xfree(sl->name); DESTROY(sl); } + DESTROY(t); } +const tunnel_ops tun_slip = { + "slip", + t_init, + t_create, + t_ifname, + t_inject, + t_destroy +}; + /*----- That's all, folks -------------------------------------------------*/