const tunnel_ops *ops; /* Pointer to operations */
sel_file f; /* Selector for tunnel device */
struct peer *p; /* Pointer to my peer */
- unsigned n; /* Number of my tunnel device */
};
/* --- @t_read@ --- *
/* --- @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, char **ifn)
+static tunnel *t_create(peer *p, int fd, char **ifn)
{
- int fd;
- unsigned n;
tunnel *t;
- char buf[16];
-
- n = 0;
- for (;;) {
- sprintf(buf, "/dev/tun%u", n);
- if ((fd = open(buf, O_RDWR)) >= 0)
- break;
- switch (errno) {
- case EBUSY:
- T( trace(T_TUNNEL, "tunnel device %u busy: skipping", n); )
- break;
- case ENOENT:
- a_warn("TUN", "-", "bsd", "no-tunnel-devices", A_END);
- return (0);
- default:
- a_warn("TUN", "-", "open-error", "%s", buf, "?ERRNO", A_END);
- break;
- }
- n++;
- }
+ fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
t = CREATE(tunnel);
t->ops = &tun_bsd;
- fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
t->p = p;
- t->n = n;
sel_initfile(&sel, &t->f, fd, SEL_READ, t_read, t);
sel_addfile(&t->f);
- *ifn = xstrdup(buf + 5);
- T( trace(T_TUNNEL, "tun-bsd: attached interface %s to peer `%s'",
- *ifn, p_name(p)); )
return (t);
}
const tunnel_ops tun_bsd = {
"bsd",
+ TUNF_PRIVOPEN,
t_init,
t_create,
0,