diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-01-23 02:07:14 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-01-23 02:07:14 +0000 |
| commit | 39b681343bee81fb7c31fd06e4dc5343bcef1292 (patch) | |
| tree | 9f5896b38ed4c9069da747e1987eb5220677ade5 | |
| parent | f6107c7e885da0f952569252798b7fc6b4d46411 (diff) | |
| download | busybox-w32-39b681343bee81fb7c31fd06e4dc5343bcef1292.tar.gz busybox-w32-39b681343bee81fb7c31fd06e4dc5343bcef1292.tar.bz2 busybox-w32-39b681343bee81fb7c31fd06e4dc5343bcef1292.zip | |
tunctl: new applet by Vladimir
function old new delta
tunctl_main - 371 +371
packed_usage 25669 25799 +130
applet_names 1981 1988 +7
applet_main 1192 1196 +4
applet_nameofs 596 598 +2
applet_install_loc 149 150 +1
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 5/0 up/down: 515/0) Total: 515 bytes
| -rw-r--r-- | include/applets.h | 1 | ||||
| -rw-r--r-- | include/usage.h | 17 | ||||
| -rw-r--r-- | networking/Config.in | 14 | ||||
| -rw-r--r-- | networking/Kbuild | 1 | ||||
| -rw-r--r-- | networking/tunctl.c | 139 |
5 files changed, 172 insertions, 0 deletions
diff --git a/include/applets.h b/include/applets.h index 8d9d2a23b..63cc73867 100644 --- a/include/applets.h +++ b/include/applets.h | |||
| @@ -382,6 +382,7 @@ USE_TRACEROUTE(APPLET(traceroute, _BB_DIR_USR_BIN, _BB_SUID_MAYBE)) | |||
| 382 | USE_TRUE(APPLET_NOFORK(true, true, _BB_DIR_BIN, _BB_SUID_NEVER, true)) | 382 | USE_TRUE(APPLET_NOFORK(true, true, _BB_DIR_BIN, _BB_SUID_NEVER, true)) |
| 383 | USE_TTY(APPLET(tty, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 383 | USE_TTY(APPLET(tty, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
| 384 | USE_TTYSIZE(APPLET(ttysize, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 384 | USE_TTYSIZE(APPLET(ttysize, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
| 385 | USE_TUNCTL(APPLET(tunctl, _BB_DIR_SBIN, _BB_SUID_NEVER)) | ||
| 385 | //USE_TUNE2FS(APPLET(tune2fs, _BB_DIR_SBIN, _BB_SUID_NEVER)) | 386 | //USE_TUNE2FS(APPLET(tune2fs, _BB_DIR_SBIN, _BB_SUID_NEVER)) |
| 386 | USE_APP_UDHCPC(APPLET(udhcpc, _BB_DIR_SBIN, _BB_SUID_NEVER)) | 387 | USE_APP_UDHCPC(APPLET(udhcpc, _BB_DIR_SBIN, _BB_SUID_NEVER)) |
| 387 | USE_APP_UDHCPD(APPLET(udhcpd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) | 388 | USE_APP_UDHCPD(APPLET(udhcpd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) |
diff --git a/include/usage.h b/include/usage.h index 3b53602af..9ceb3664f 100644 --- a/include/usage.h +++ b/include/usage.h | |||
| @@ -4457,6 +4457,23 @@ | |||
| 4457 | #define ttysize_full_usage "\n\n" \ | 4457 | #define ttysize_full_usage "\n\n" \ |
| 4458 | "Print dimension(s) of standard input's terminal, on error return 80x25" | 4458 | "Print dimension(s) of standard input's terminal, on error return 80x25" |
| 4459 | 4459 | ||
| 4460 | #define tunctl_trivial_usage \ | ||
| 4461 | "[-f device] ([-t name] | -d name)" USE_FEATURE_TUNCTL_UG(" [-u owner] [-g group] [-b]") | ||
| 4462 | #define tunctl_full_usage "\n\n" \ | ||
| 4463 | "Create or delete tun interfaces" \ | ||
| 4464 | "\nOptions:" \ | ||
| 4465 | "\n -f name tun device (/dev/net/tun)" \ | ||
| 4466 | "\n -t name Create iface 'name'" \ | ||
| 4467 | "\n -d name Delete iface 'name'" \ | ||
| 4468 | USE_FEATURE_TUNCTL_UG( \ | ||
| 4469 | "\n -u owner Set iface owner" \ | ||
| 4470 | "\n -g group Set iface group" \ | ||
| 4471 | "\n -b Brief output" \ | ||
| 4472 | ) | ||
| 4473 | #define tunctl_example_usage \ | ||
| 4474 | "# tunctl\n" \ | ||
| 4475 | "# tunctl -d tun0\n" | ||
| 4476 | |||
| 4460 | #define tune2fs_trivial_usage \ | 4477 | #define tune2fs_trivial_usage \ |
| 4461 | "[-c max-mounts-count] [-e errors-behavior] [-g group] " \ | 4478 | "[-c max-mounts-count] [-e errors-behavior] [-g group] " \ |
| 4462 | "[-i interval[d|m|w]] [-j] [-J journal-options] [-l] [-s sparse-flag] " \ | 4479 | "[-i interval[d|m|w]] [-j] [-J journal-options] [-l] [-s sparse-flag] " \ |
diff --git a/networking/Config.in b/networking/Config.in index 00a07b479..b3d07e63c 100644 --- a/networking/Config.in +++ b/networking/Config.in | |||
| @@ -920,6 +920,20 @@ config TCPSVD | |||
| 920 | tcpsvd listens on a TCP port and runs a program for each new | 920 | tcpsvd listens on a TCP port and runs a program for each new |
| 921 | connection. | 921 | connection. |
| 922 | 922 | ||
| 923 | config TUNCTL | ||
| 924 | bool "tunctl" | ||
| 925 | default n | ||
| 926 | help | ||
| 927 | tunctl creates or deletes tun devices. | ||
| 928 | |||
| 929 | config FEATURE_TUNCTL_UG | ||
| 930 | bool "Support owner:group assignment" | ||
| 931 | default n | ||
| 932 | depends on TUNCTL | ||
| 933 | help | ||
| 934 | Allow to specify owner and group of newly created interface. | ||
| 935 | 340 bytes of pure bloat. Say no here. | ||
| 936 | |||
| 923 | config UDPSVD | 937 | config UDPSVD |
| 924 | bool "udpsvd" | 938 | bool "udpsvd" |
| 925 | default n | 939 | default n |
diff --git a/networking/Kbuild b/networking/Kbuild index 63d0745f8..77071269a 100644 --- a/networking/Kbuild +++ b/networking/Kbuild | |||
| @@ -36,6 +36,7 @@ lib-$(CONFIG_TELNETD) += telnetd.o | |||
| 36 | lib-$(CONFIG_TFTP) += tftp.o | 36 | lib-$(CONFIG_TFTP) += tftp.o |
| 37 | lib-$(CONFIG_TFTPD) += tftp.o | 37 | lib-$(CONFIG_TFTPD) += tftp.o |
| 38 | lib-$(CONFIG_TRACEROUTE) += traceroute.o | 38 | lib-$(CONFIG_TRACEROUTE) += traceroute.o |
| 39 | lib-$(CONFIG_TUNCTL) += tunctl.o | ||
| 39 | lib-$(CONFIG_VCONFIG) += vconfig.o | 40 | lib-$(CONFIG_VCONFIG) += vconfig.o |
| 40 | lib-$(CONFIG_WGET) += wget.o | 41 | lib-$(CONFIG_WGET) += wget.o |
| 41 | lib-$(CONFIG_ZCIP) += zcip.o | 42 | lib-$(CONFIG_ZCIP) += zcip.o |
diff --git a/networking/tunctl.c b/networking/tunctl.c new file mode 100644 index 000000000..a8e5270ad --- /dev/null +++ b/networking/tunctl.c | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | ||
| 2 | /* | ||
| 3 | * tun devices controller | ||
| 4 | * | ||
| 5 | * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com> | ||
| 6 | * | ||
| 7 | * Original code: | ||
| 8 | * Jeff Dike | ||
| 9 | * | ||
| 10 | * Licensed under GPLv2, see file LICENSE in this tarball for details. | ||
| 11 | */ | ||
| 12 | #include <netinet/in.h> | ||
| 13 | #include <net/if.h> | ||
| 14 | #include <linux/if_tun.h> | ||
| 15 | #include "libbb.h" | ||
| 16 | |||
| 17 | /* TUNSETGROUP appeared in 2.6.23 */ | ||
| 18 | #ifndef TUNSETGROUP | ||
| 19 | #define TUNSETGROUP _IOW('T', 206, int) | ||
| 20 | #endif | ||
| 21 | |||
| 22 | #define IOCTL(a, b, c) ioctl_or_perror_and_die(a, b, c, NULL) | ||
| 23 | |||
| 24 | #if 1 | ||
| 25 | |||
| 26 | int tunctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
| 27 | int tunctl_main(int argc UNUSED_PARAM, char **argv) | ||
| 28 | { | ||
| 29 | struct ifreq ifr; | ||
| 30 | int fd; | ||
| 31 | const char *opt_name = "tap%d"; | ||
| 32 | const char *opt_device = "/dev/net/tun"; | ||
| 33 | #if ENABLE_FEATURE_TUNCTL_UG | ||
| 34 | const char *opt_user, *opt_group; | ||
| 35 | long user = -1, group = -1; | ||
| 36 | #endif | ||
| 37 | unsigned opts; | ||
| 38 | |||
| 39 | enum { | ||
| 40 | OPT_f = 1 << 0, // control device name (/dev/net/tun) | ||
| 41 | OPT_t = 1 << 1, // create named interface | ||
| 42 | OPT_d = 1 << 2, // delete named interface | ||
| 43 | #if ENABLE_FEATURE_TUNCTL_UG | ||
| 44 | OPT_u = 1 << 3, // set new interface owner | ||
| 45 | OPT_g = 1 << 4, // set new interface group | ||
| 46 | OPT_b = 1 << 5, // brief output | ||
| 47 | #endif | ||
| 48 | }; | ||
| 49 | |||
| 50 | opt_complementary = "=0:t--d:d--t"; // no arguments; t ^ d | ||
| 51 | opts = getopt32(argv, "f:t:d:" USE_FEATURE_TUNCTL_UG("u:g:b"), | ||
| 52 | &opt_device, &opt_name, &opt_name | ||
| 53 | USE_FEATURE_TUNCTL_UG(, &opt_user, &opt_group)); | ||
| 54 | |||
| 55 | // select device | ||
| 56 | memset(&ifr, 0, sizeof(ifr)); | ||
| 57 | ifr.ifr_flags = IFF_TAP | IFF_NO_PI; | ||
| 58 | strncpy_IFNAMSIZ(ifr.ifr_name, opt_name); | ||
| 59 | |||
| 60 | // open device | ||
| 61 | fd = xopen(opt_device, O_RDWR); | ||
| 62 | IOCTL(fd, TUNSETIFF, (void *)&ifr); | ||
| 63 | |||
| 64 | // delete? | ||
| 65 | if (opts & OPT_d) { | ||
| 66 | IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)0); | ||
| 67 | bb_info_msg("Set '%s' %spersistent", ifr.ifr_name, "non"); | ||
| 68 | return EXIT_SUCCESS; | ||
| 69 | } | ||
| 70 | |||
| 71 | // create | ||
| 72 | #if ENABLE_FEATURE_TUNCTL_UG | ||
| 73 | if (opts & OPT_g) { | ||
| 74 | group = xgroup2gid(opt_group); | ||
| 75 | IOCTL(fd, TUNSETGROUP, (void *)(uintptr_t)group); | ||
| 76 | } else | ||
| 77 | user = geteuid(); | ||
| 78 | if (opts & OPT_u) | ||
| 79 | user = xuname2uid(opt_user); | ||
| 80 | IOCTL(fd, TUNSETOWNER, (void *)(uintptr_t)user); | ||
| 81 | #endif | ||
| 82 | IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)1); | ||
| 83 | |||
| 84 | // show info | ||
| 85 | #if ENABLE_FEATURE_TUNCTL_UG | ||
| 86 | if (opts & OPT_b) { | ||
| 87 | puts(ifr.ifr_name); | ||
| 88 | } else { | ||
| 89 | printf("Set '%s' %spersistent", ifr.ifr_name, ""); | ||
| 90 | printf(" and owned by uid %ld", user); | ||
| 91 | if (group != -1) | ||
| 92 | printf(" gid %ld", group); | ||
| 93 | bb_putchar('\n'); | ||
| 94 | } | ||
| 95 | #else | ||
| 96 | puts(ifr.ifr_name); | ||
| 97 | #endif | ||
| 98 | return EXIT_SUCCESS; | ||
| 99 | } | ||
| 100 | |||
| 101 | #else | ||
| 102 | |||
| 103 | /* -210 bytes: */ | ||
| 104 | |||
| 105 | int tunctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
| 106 | int tunctl_main(int argc UNUSED_PARAM, char **argv) | ||
| 107 | { | ||
| 108 | struct ifreq ifr; | ||
| 109 | int fd; | ||
| 110 | const char *opt_name = "tap%d"; | ||
| 111 | const char *opt_device = "/dev/net/tun"; | ||
| 112 | unsigned opts; | ||
| 113 | |||
| 114 | enum { | ||
| 115 | OPT_f = 1 << 0, // control device name (/dev/net/tun) | ||
| 116 | OPT_t = 1 << 1, // create named interface | ||
| 117 | OPT_d = 1 << 2, // delete named interface | ||
| 118 | }; | ||
| 119 | |||
| 120 | opt_complementary = "=0:t--d:d--t"; // no arguments; t ^ d | ||
| 121 | opts = getopt32(argv, "f:t:d:u:g:b", // u, g, b accepted and ignored | ||
| 122 | &opt_device, &opt_name, &opt_name, NULL, NULL); | ||
| 123 | |||
| 124 | // set interface name | ||
| 125 | memset(&ifr, 0, sizeof(ifr)); | ||
| 126 | ifr.ifr_flags = IFF_TAP | IFF_NO_PI; | ||
| 127 | strncpy_IFNAMSIZ(ifr.ifr_name, opt_name); | ||
| 128 | |||
| 129 | // open device | ||
| 130 | fd = xopen(opt_device, O_RDWR); | ||
| 131 | IOCTL(fd, TUNSETIFF, (void *)&ifr); | ||
| 132 | |||
| 133 | // create or delete interface | ||
| 134 | IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)(0 == (opts & OPT_d))); | ||
| 135 | |||
| 136 | return EXIT_SUCCESS; | ||
| 137 | } | ||
| 138 | |||
| 139 | #endif | ||
