123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- #include <netinet/in.h>
- #include <net/if.h>
- #include <linux/if_tun.h>
- #include "libbb.h"
- #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,
- OPT_t = 1 << 1,
- OPT_d = 1 << 2,
- #if ENABLE_FEATURE_TUNCTL_UG
- OPT_u = 1 << 3,
- OPT_g = 1 << 4,
- OPT_b = 1 << 5,
- #endif
- };
- opts = getopt32(argv, "^"
- "f:t:d:" IF_FEATURE_TUNCTL_UG("u:g:b")
- "\0"
- "=0:t--d:d--t",
- &opt_device, &opt_name, &opt_name
- IF_FEATURE_TUNCTL_UG(, &opt_user, &opt_group)
- );
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
- strncpy_IFNAMSIZ(ifr.ifr_name, opt_name);
-
- fd = xopen(opt_device, O_RDWR);
- IOCTL(fd, TUNSETIFF, (void *)&ifr);
-
- if (opts & OPT_d) {
- IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)0);
- printf("Set '%s' nonpersistent\n", ifr.ifr_name);
- return EXIT_SUCCESS;
- }
-
- #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);
-
- #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
- 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,
- OPT_t = 1 << 1,
- OPT_d = 1 << 2,
- };
- opts = getopt32(argv, "^"
- "f:t:d:u:g:b"
- "\0"
- "=0:t--d:d--t",
- &opt_device, &opt_name, &opt_name, NULL, NULL
- );
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
- strncpy_IFNAMSIZ(ifr.ifr_name, opt_name);
-
- fd = xopen(opt_device, O_RDWR);
- IOCTL(fd, TUNSETIFF, (void *)&ifr);
-
- IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)(0 == (opts & OPT_d)));
- return EXIT_SUCCESS;
- }
- #endif
|