diff options
author | Jeff Dike <jdike@x86_64.user-mode-linux.org> | 2010-08-05 11:29:35 -0400 |
---|---|---|
committer | Richard Purdie <rpurdie@linux.intel.com> | 2010-08-20 16:20:09 +0100 |
commit | e4bc3e36e455e7fca48ccc5431c6bb83f531fab6 (patch) | |
tree | 1482f2609a2ac08b14ee892cfed384664517b3e2 /meta/packages/qemu/qemu-helper/tunctl.c | |
parent | d9aa25a3379c21a999bd39e78702f932ead7b840 (diff) | |
download | poky-e4bc3e36e455e7fca48ccc5431c6bb83f531fab6.tar.gz |
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 <jdike@linux.intel.com>
Signed-off-by: Scott Garman <scott.a.garman@intel.com>
Diffstat (limited to 'meta/packages/qemu/qemu-helper/tunctl.c')
-rw-r--r-- | meta/packages/qemu/qemu-helper/tunctl.c | 156 |
1 files changed, 156 insertions, 0 deletions
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 @@ | |||
1 | /* Copyright 2002 Jeff Dike | ||
2 | * Licensed under the GPL | ||
3 | */ | ||
4 | |||
5 | #include <stdio.h> | ||
6 | #include <stdlib.h> | ||
7 | #include <string.h> | ||
8 | #include <errno.h> | ||
9 | #include <fcntl.h> | ||
10 | #include <unistd.h> | ||
11 | #include <pwd.h> | ||
12 | #include <grp.h> | ||
13 | #include <net/if.h> | ||
14 | #include <sys/ioctl.h> | ||
15 | #include <linux/if_tun.h> | ||
16 | |||
17 | /* TUNSETGROUP appeared in 2.6.23 */ | ||
18 | #ifndef TUNSETGROUP | ||
19 | #define TUNSETGROUP _IOW('T', 206, int) | ||
20 | #endif | ||
21 | |||
22 | static void Usage(char *name) | ||
23 | { | ||
24 | fprintf(stderr, "Create: %s [-b] [-u owner] [-g group] [-t device-name] " | ||
25 | "[-f tun-clone-device]\n", name); | ||
26 | fprintf(stderr, "Delete: %s -d device-name [-f tun-clone-device]\n\n", | ||
27 | name); | ||
28 | fprintf(stderr, "The default tun clone device is /dev/net/tun - some systems" | ||
29 | " use\n/dev/misc/net/tun instead\n\n"); | ||
30 | fprintf(stderr, "-b will result in brief output (just the device name)\n"); | ||
31 | exit(1); | ||
32 | } | ||
33 | |||
34 | int main(int argc, char **argv) | ||
35 | { | ||
36 | struct ifreq ifr; | ||
37 | struct passwd *pw; | ||
38 | struct group *gr; | ||
39 | uid_t owner = -1; | ||
40 | gid_t group = -1; | ||
41 | int tap_fd, opt, delete = 0, brief = 0; | ||
42 | char *tun = "", *file = "/dev/net/tun", *name = argv[0], *end; | ||
43 | |||
44 | while((opt = getopt(argc, argv, "bd:f:t:u:g:")) > 0){ | ||
45 | switch(opt) { | ||
46 | case 'b': | ||
47 | brief = 1; | ||
48 | break; | ||
49 | case 'd': | ||
50 | delete = 1; | ||
51 | tun = optarg; | ||
52 | break; | ||
53 | case 'f': | ||
54 | file = optarg; | ||
55 | break; | ||
56 | case 'u': | ||
57 | pw = getpwnam(optarg); | ||
58 | if(pw != NULL){ | ||
59 | owner = pw->pw_uid; | ||
60 | break; | ||
61 | } | ||
62 | owner = strtol(optarg, &end, 0); | ||
63 | if(*end != '\0'){ | ||
64 | fprintf(stderr, "'%s' is neither a username nor a numeric uid.\n", | ||
65 | optarg); | ||
66 | Usage(name); | ||
67 | } | ||
68 | break; | ||
69 | case 'g': | ||
70 | gr = getgrnam(optarg); | ||
71 | if(gr != NULL){ | ||
72 | group = gr->gr_gid; | ||
73 | break; | ||
74 | } | ||
75 | group = strtol(optarg, &end, 0); | ||
76 | if(*end != '\0'){ | ||
77 | fprintf(stderr, "'%s' is neither a groupname nor a numeric group.\n", | ||
78 | optarg); | ||
79 | Usage(name); | ||
80 | } | ||
81 | break; | ||
82 | |||
83 | case 't': | ||
84 | tun = optarg; | ||
85 | break; | ||
86 | case 'h': | ||
87 | default: | ||
88 | Usage(name); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | argv += optind; | ||
93 | argc -= optind; | ||
94 | |||
95 | if(argc > 0) | ||
96 | Usage(name); | ||
97 | |||
98 | if((tap_fd = open(file, O_RDWR)) < 0){ | ||
99 | fprintf(stderr, "Failed to open '%s' : ", file); | ||
100 | perror(""); | ||
101 | exit(1); | ||
102 | } | ||
103 | |||
104 | memset(&ifr, 0, sizeof(ifr)); | ||
105 | |||
106 | ifr.ifr_flags = IFF_TAP | IFF_NO_PI; | ||
107 | strncpy(ifr.ifr_name, tun, sizeof(ifr.ifr_name) - 1); | ||
108 | if(ioctl(tap_fd, TUNSETIFF, (void *) &ifr) < 0){ | ||
109 | perror("TUNSETIFF"); | ||
110 | exit(1); | ||
111 | } | ||
112 | |||
113 | if(delete){ | ||
114 | if(ioctl(tap_fd, TUNSETPERSIST, 0) < 0){ | ||
115 | perror("disabling TUNSETPERSIST"); | ||
116 | exit(1); | ||
117 | } | ||
118 | printf("Set '%s' nonpersistent\n", ifr.ifr_name); | ||
119 | } | ||
120 | else { | ||
121 | /* emulate behaviour prior to TUNSETGROUP */ | ||
122 | if(owner == -1 && group == -1) { | ||
123 | owner = geteuid(); | ||
124 | } | ||
125 | |||
126 | if(owner != -1) { | ||
127 | if(ioctl(tap_fd, TUNSETOWNER, owner) < 0){ | ||
128 | perror("TUNSETOWNER"); | ||
129 | exit(1); | ||
130 | } | ||
131 | } | ||
132 | if(group != -1) { | ||
133 | if(ioctl(tap_fd, TUNSETGROUP, group) < 0){ | ||
134 | perror("TUNSETGROUP"); | ||
135 | exit(1); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | if(ioctl(tap_fd, TUNSETPERSIST, 1) < 0){ | ||
140 | perror("enabling TUNSETPERSIST"); | ||
141 | exit(1); | ||
142 | } | ||
143 | |||
144 | if(brief) | ||
145 | printf("%s\n", ifr.ifr_name); | ||
146 | else { | ||
147 | printf("Set '%s' persistent and owned by", ifr.ifr_name); | ||
148 | if(owner != -1) | ||
149 | printf(" uid %d", owner); | ||
150 | if(group != -1) | ||
151 | printf(" gid %d", group); | ||
152 | printf("\n"); | ||
153 | } | ||
154 | } | ||
155 | return(0); | ||
156 | } | ||