Annotation of /trunk/mkinitrd-magellan/busybox/networking/tunctl.c
Parent Directory | Revision Log
Revision 984 -
(hide annotations)
(download)
Sun May 30 11:32:42 2010 UTC (14 years ago) by niro
File MIME type: text/plain
File size: 3372 byte(s)
Sun May 30 11:32:42 2010 UTC (14 years ago) by niro
File MIME type: text/plain
File size: 3372 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
1 | niro | 984 | /* 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:" IF_FEATURE_TUNCTL_UG("u:g:b"), | ||
52 | &opt_device, &opt_name, &opt_name | ||
53 | IF_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 |