From e4bc3e36e455e7fca48ccc5431c6bb83f531fab6 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Thu, 5 Aug 2010 11:29:35 -0400 Subject: tunctl: Added an tunctl which supports TUNSETGROUP TUNSETGROUP is needed in order to preconfigure a set of tap devices that can be used by non-root users. The requirement is that the qemu users be members of whatever group the tap devices are assigned to. Include tunctl in the qemu-helper package, and add a -native version. Signed-off-by: Jeff Dike Signed-off-by: Scott Garman --- meta/packages/qemu/qemu-helper-native_1.0.bb | 21 ++++ meta/packages/qemu/qemu-helper-nativesdk_1.0.bb | 6 +- meta/packages/qemu/qemu-helper/tunctl.c | 156 ++++++++++++++++++++++++ 3 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 meta/packages/qemu/qemu-helper-native_1.0.bb create mode 100644 meta/packages/qemu/qemu-helper/tunctl.c (limited to 'meta') diff --git a/meta/packages/qemu/qemu-helper-native_1.0.bb b/meta/packages/qemu/qemu-helper-native_1.0.bb new file mode 100644 index 0000000000..19fb6f4ff7 --- /dev/null +++ b/meta/packages/qemu/qemu-helper-native_1.0.bb @@ -0,0 +1,21 @@ +DESCRIPTION = "Qemu helper utilities from Poky" +LICENSE = "GPLv2" +RDEPENDS = "qemu-native" +PR = "r0" + +FILESPATH = "${FILE_DIRNAME}/qemu-helper" + +SRC_URI = "file://tunctl.c" + +S = "${WORKDIR}" + +inherit native + +do_compile() { + ${CC} tunctl.c -o tunctl +} + +do_install() { + install -d ${D}${bindir} + install tunctl ${D}${bindir}/ +} diff --git a/meta/packages/qemu/qemu-helper-nativesdk_1.0.bb b/meta/packages/qemu/qemu-helper-nativesdk_1.0.bb index a4294ef5cf..a764a0e28a 100644 --- a/meta/packages/qemu/qemu-helper-nativesdk_1.0.bb +++ b/meta/packages/qemu/qemu-helper-nativesdk_1.0.bb @@ -10,13 +10,16 @@ SRC_URI = "file://${POKYBASE}/scripts/poky-qemu \ file://${POKYBASE}/scripts/poky-addptable2image \ file://${POKYBASE}/scripts/poky-qemu-ifup \ file://${POKYBASE}/scripts/poky-qemu-ifdown \ - file://raw2flash.c" + file://tunctl.c \ + file://raw2flash.c \ + " S = "${WORKDIR}" inherit nativesdk do_compile() { + ${CC} tunctl.c -o tunctl ${CC} raw2flash.c -o raw2flash.spitz ${CC} raw2flash.c -o flash2raw.spitz -Dflash2raw } @@ -24,6 +27,7 @@ do_compile() { do_install() { install -d ${D}${bindir} install -m 0755 ${WORKDIR}${POKYBASE}/scripts/poky-* ${D}${bindir}/ + install tunctl ${D}${bindir}/ install raw2flash.spitz ${D}${bindir}/ install flash2raw.spitz ${D}${bindir}/ ln -fs raw2flash.spitz ${D}${bindir}/raw2flash.akita diff --git a/meta/packages/qemu/qemu-helper/tunctl.c b/meta/packages/qemu/qemu-helper/tunctl.c new file mode 100644 index 0000000000..16e24a2add --- /dev/null +++ b/meta/packages/qemu/qemu-helper/tunctl.c @@ -0,0 +1,156 @@ +/* Copyright 2002 Jeff Dike + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 == -1 && group == -1) { + owner = geteuid(); + } + + if(owner != -1) { + if(ioctl(tap_fd, TUNSETOWNER, owner) < 0){ + perror("TUNSETOWNER"); + exit(1); + } + } + if(group != -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 != -1) + printf(" uid %d", owner); + if(group != -1) + printf(" gid %d", group); + printf("\n"); + } + } + return(0); +} -- cgit v1.2.3-54-g00ecf