From 4aca87515a5083ae0e31ce3177189fd43b6d05ac Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 3 Jan 2015 13:58:15 +0100 Subject: patch to Vanilla Tomato 1.28 --- release/src/router/busybox/networking/tunctl.c | 139 +++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 release/src/router/busybox/networking/tunctl.c (limited to 'release/src/router/busybox/networking/tunctl.c') diff --git a/release/src/router/busybox/networking/tunctl.c b/release/src/router/busybox/networking/tunctl.c new file mode 100644 index 00000000..a8e5270a --- /dev/null +++ b/release/src/router/busybox/networking/tunctl.c @@ -0,0 +1,139 @@ +/* vi: set sw=4 ts=4: */ +/* + * tun devices controller + * + * Copyright (C) 2008 by Vladimir Dronnikov + * + * Original code: + * Jeff Dike + * + * Licensed under GPLv2, see file LICENSE in this tarball for details. + */ +#include +#include +#include +#include "libbb.h" + +/* TUNSETGROUP appeared in 2.6.23 */ +#ifndef TUNSETGROUP +#define TUNSETGROUP _IOW('T', 206, int) +#endif + +#define IOCTL(a, b, c) ioctl_or_perror_and_die(a, b, c, NULL) + +#if 1 + +int tunctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int tunctl_main(int argc UNUSED_PARAM, char **argv) +{ + struct ifreq ifr; + int fd; + const char *opt_name = "tap%d"; + const char *opt_device = "/dev/net/tun"; +#if ENABLE_FEATURE_TUNCTL_UG + const char *opt_user, *opt_group; + long user = -1, group = -1; +#endif + unsigned opts; + + enum { + OPT_f = 1 << 0, // control device name (/dev/net/tun) + OPT_t = 1 << 1, // create named interface + OPT_d = 1 << 2, // delete named interface +#if ENABLE_FEATURE_TUNCTL_UG + OPT_u = 1 << 3, // set new interface owner + OPT_g = 1 << 4, // set new interface group + OPT_b = 1 << 5, // brief output +#endif + }; + + opt_complementary = "=0:t--d:d--t"; // no arguments; t ^ d + opts = getopt32(argv, "f:t:d:" USE_FEATURE_TUNCTL_UG("u:g:b"), + &opt_device, &opt_name, &opt_name + USE_FEATURE_TUNCTL_UG(, &opt_user, &opt_group)); + + // select device + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + strncpy_IFNAMSIZ(ifr.ifr_name, opt_name); + + // open device + fd = xopen(opt_device, O_RDWR); + IOCTL(fd, TUNSETIFF, (void *)&ifr); + + // delete? + if (opts & OPT_d) { + IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)0); + bb_info_msg("Set '%s' %spersistent", ifr.ifr_name, "non"); + return EXIT_SUCCESS; + } + + // create +#if ENABLE_FEATURE_TUNCTL_UG + if (opts & OPT_g) { + group = xgroup2gid(opt_group); + IOCTL(fd, TUNSETGROUP, (void *)(uintptr_t)group); + } else + user = geteuid(); + if (opts & OPT_u) + user = xuname2uid(opt_user); + IOCTL(fd, TUNSETOWNER, (void *)(uintptr_t)user); +#endif + IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)1); + + // show info +#if ENABLE_FEATURE_TUNCTL_UG + if (opts & OPT_b) { + puts(ifr.ifr_name); + } else { + printf("Set '%s' %spersistent", ifr.ifr_name, ""); + printf(" and owned by uid %ld", user); + if (group != -1) + printf(" gid %ld", group); + bb_putchar('\n'); + } +#else + puts(ifr.ifr_name); +#endif + return EXIT_SUCCESS; +} + +#else + +/* -210 bytes: */ + +int tunctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int tunctl_main(int argc UNUSED_PARAM, char **argv) +{ + struct ifreq ifr; + int fd; + const char *opt_name = "tap%d"; + const char *opt_device = "/dev/net/tun"; + unsigned opts; + + enum { + OPT_f = 1 << 0, // control device name (/dev/net/tun) + OPT_t = 1 << 1, // create named interface + OPT_d = 1 << 2, // delete named interface + }; + + opt_complementary = "=0:t--d:d--t"; // no arguments; t ^ d + opts = getopt32(argv, "f:t:d:u:g:b", // u, g, b accepted and ignored + &opt_device, &opt_name, &opt_name, NULL, NULL); + + // set interface name + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + strncpy_IFNAMSIZ(ifr.ifr_name, opt_name); + + // open device + fd = xopen(opt_device, O_RDWR); + IOCTL(fd, TUNSETIFF, (void *)&ifr); + + // create or delete interface + IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)(0 == (opts & OPT_d))); + + return EXIT_SUCCESS; +} + +#endif -- cgit v1.2.3-54-g00ecf