diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 03:01:46 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 03:01:46 +0000 |
commit | f8fe689a81f906d1b91bb3220acde2a4ecb14c5b (patch) | |
tree | 26484e9d7e2c67806c2d1760196ff01aaa858e8c /src/apps/tunctl/tunctl.c | |
parent | Initial commit. (diff) | |
download | virtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.tar.xz virtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.zip |
Adding upstream version 6.0.4-dfsg.upstream/6.0.4-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/apps/tunctl/tunctl.c')
-rw-r--r-- | src/apps/tunctl/tunctl.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/apps/tunctl/tunctl.c b/src/apps/tunctl/tunctl.c new file mode 100644 index 00000000..f2cabc5d --- /dev/null +++ b/src/apps/tunctl/tunctl.c @@ -0,0 +1,156 @@ +/* Copyright 2002 Jeff Dike + * Licensed under the GPL + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <pwd.h> +#include <grp.h> +#include <net/if.h> +#include <sys/ioctl.h> +#include <linux/if_tun.h> + +/* TUNSETGROUP appeared in 2.6.23 */ +#ifndef TUNSETGROUP +#define TUNSETGROUP _IOW('T', 206, int) +#endif + +static void Usage(char *name) +{ + fprintf(stderr, "Create: %s [-b] [-u owner] [-g group] [-t device-name] " + "[-f tun-clone-device]\n", name); + fprintf(stderr, "Delete: %s -d device-name [-f tun-clone-device]\n\n", + name); + fprintf(stderr, "The default tun clone device is /dev/net/tun - some systems" + " use\n/dev/misc/net/tun instead\n\n"); + fprintf(stderr, "-b will result in brief output (just the device name)\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + struct ifreq ifr; + struct passwd *pw; + struct group *gr; + uid_t owner = -1; + gid_t group = -1; + int tap_fd, opt, delete = 0, brief = 0; + char *tun = "", *file = "/dev/net/tun", *name = argv[0], *end; + + while((opt = getopt(argc, argv, "bd:f:t:u:g:")) > 0){ + switch(opt) { + case 'b': + brief = 1; + break; + case 'd': + delete = 1; + tun = optarg; + break; + case 'f': + file = optarg; + break; + case 'u': + pw = getpwnam(optarg); + if(pw != NULL){ + owner = pw->pw_uid; + break; + } + owner = strtol(optarg, &end, 0); + if(*end != '\0'){ + fprintf(stderr, "'%s' is neither a username nor a numeric uid.\n", + optarg); + Usage(name); + } + break; + case 'g': + gr = getgrnam(optarg); + if(gr != NULL){ + group = gr->gr_gid; + break; + } + group = strtol(optarg, &end, 0); + if(*end != '\0'){ + fprintf(stderr, "'%s' is neither a groupname nor a numeric group.\n", + optarg); + Usage(name); + } + break; + + case 't': + tun = optarg; + break; + case 'h': + default: + Usage(name); + } + } + + argv += optind; + argc -= optind; + + if(argc > 0) + Usage(name); + + if((tap_fd = open(file, O_RDWR)) < 0){ + fprintf(stderr, "Failed to open '%s' : ", file); + perror(""); + exit(1); + } + + memset(&ifr, 0, sizeof(ifr)); + + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + strncpy(ifr.ifr_name, tun, sizeof(ifr.ifr_name) - 1); + if(ioctl(tap_fd, TUNSETIFF, (void *) &ifr) < 0){ + perror("TUNSETIFF"); + exit(1); + } + + if(delete){ + if(ioctl(tap_fd, TUNSETPERSIST, 0) < 0){ + perror("disabling TUNSETPERSIST"); + exit(1); + } + printf("Set '%s' nonpersistent\n", ifr.ifr_name); + } + else { + /* emulate behaviour prior to TUNSETGROUP */ + if(owner == (uid_t)-1 && group == (gid_t)-1) { + owner = geteuid(); + } + + if(owner != (uid_t)-1) { + if(ioctl(tap_fd, TUNSETOWNER, owner) < 0){ + perror("TUNSETOWNER"); + exit(1); + } + } + if(group != (gid_t)-1) { + if(ioctl(tap_fd, TUNSETGROUP, group) < 0){ + perror("TUNSETGROUP"); + exit(1); + } + } + + if(ioctl(tap_fd, TUNSETPERSIST, 1) < 0){ + perror("enabling TUNSETPERSIST"); + exit(1); + } + + if(brief) + printf("%s\n", ifr.ifr_name); + else { + printf("Set '%s' persistent and owned by", ifr.ifr_name); + if(owner != (uid_t)-1) + printf(" uid %d", owner); + if(group != (gid_t)-1) + printf(" gid %d", group); + printf("\n"); + } + } + return(0); +} |