static void t_init(void) { return; }
-/* --- @t_create@ --- *
+/* --- @t_open@ --- *
*
- * Arguments: @peer *p@ = pointer to peer block
- * @char **ifn@ = where to put the interface name
+ * 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, char **ifn)
+static int t_open(char **ifn)
{
int fd;
- int f;
struct ifreq iff;
- tunnel *t;
if ((fd = open("/dev/net/tun", O_RDWR)) < 0) {
a_warn("TUN", "-", "linux",
- "open-error", "/dev/net/tun", "?ERRNO",
- A_END);
- return (0);
+ "open-error", "/dev/net/tun", "?ERRNO",
+ A_END);
+ return (-1);
}
- fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
memset(&iff, 0, sizeof(iff));
iff.ifr_name[0] = 0;
iff.ifr_flags = IFF_TUN | IFF_NO_PI;
- if ((f = ioctl(fd, TUNSETIFF, &iff)) < 0) {
+ if (ioctl(fd, TUNSETIFF, &iff) < 0) {
a_warn("TUN", "-", "linux", "config-error", "?ERRNO", A_END);
close(fd);
- return (0);
+ return (-1);
}
+ iff.ifr_name[IFNAMSIZ - 1] = 0;
+ *ifn = xstrdup(iff.ifr_name);
+ return (fd);
+}
+
+/* --- @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_linux;
t->p = p;
sel_initfile(&sel, &t->f, fd, SEL_READ, t_read, t);
sel_addfile(&t->f);
- iff.ifr_name[IFNAMSIZ - 1] = 0;
- *ifn = xstrdup(iff.ifr_name);
- T( trace(T_TUNNEL, "tun-linux: attached interface %s to peer `%s'",
- *ifn, p_name(p)); )
return (t);
}
const tunnel_ops tun_linux = {
"linux",
t_init,
+ t_open,
t_create,
0,
t_inject,