3 // Copyright (C) 2008 Daniel Hokka Zakrisson
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; version 2 of the License.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <sys/ioctl.h>
33 #include <linux/if_tun.h>
35 /* Make sure we have the necessary ioctls */
37 # define TUNSETNOCSUM _IOW('T', 200, int)
40 # define TUNSETIFF _IOW('T', 202, int)
43 # define TUNSETPERSIST _IOW('T', 203, int)
46 # define TUNSETOWNER _IOW('T', 204, int)
49 # define TUNSETLINK _IOW('T', 205, int)
52 # define TUNSETGROUP _IOW('T', 206, int)
55 # define TUNSETNID _IOW('T', 215, int)
58 #define ENSC_WRAPPERS_PREFIX "tunctl: "
59 #define ENSC_WRAPPERS_UNISTD 1
60 #define ENSC_WRAPPERS_VSERVER 1
61 #define ENSC_WRAPPERS_FCNTL 1
62 #define ENSC_WRAPPERS_IOCTL 1
66 #define CMD_HELP 0x1000
67 #define CMD_VERSION 0x1001
68 #define CMD_NID 0x0001
69 #define CMD_DEVICE 0x0002
70 #define CMD_PERSIST 0x0004
71 #define CMD_NOPERSIST 0x0008
72 #define CMD_CSUM 0x0010
73 #define CMD_NOCSUM 0x0020
74 #define CMD_UID 0x0040
75 #define CMD_GID 0x0080
76 #define CMD_LINKTYPE 0x0100
77 #define CMD_TUN 0x0200
78 #define CMD_TAP 0x0400
79 #define CMD_NID_FAILURE_OK (0x0800 | CMD_NID)
81 int wrapper_exit_code = 255;
85 { "help", no_argument, 0, CMD_HELP },
86 { "version", no_argument, 0, CMD_VERSION },
87 { "nid", required_argument, 0, CMD_NID },
88 { "device", required_argument, 0, CMD_DEVICE },
89 { "persist", no_argument, 0, CMD_PERSIST },
90 { "~persist", no_argument, 0, CMD_NOPERSIST },
91 { "checksum", no_argument, 0, CMD_CSUM },
92 { "~checksum", no_argument, 0, CMD_NOCSUM },
93 { "uid", required_argument, 0, CMD_UID },
94 { "gid", required_argument, 0, CMD_GID },
95 { "linktype", required_argument, 0, CMD_LINKTYPE },
96 { "tun", no_argument, 0, CMD_TUN },
97 { "tap", no_argument, 0, CMD_TAP },
98 { "nid-failure-ok", required_argument, 0, CMD_NID_FAILURE_OK },
106 unsigned persist : 1;
107 unsigned checksum : 1;
115 showHelp(int fd, char const *cmd, int res)
117 WRITE_MSG(fd, "Usage: ");
121 " [--persist|--~persist] [--checksum|--~checksum]\n"
122 " [--nid <nid>] [--uid <uid>] [--gid <gid>] [--linktype <link type>]\n"
123 " <interface(s)>...\n"
125 "Please report bugs to " PACKAGE_BUGREPORT "\n");
134 "tunctl " VERSION " -- controls TUN/TAP devices\n"
135 "This program is part of " PACKAGE_STRING "\n\n"
136 "Copyright (C) 2008 Daniel Hokka Zakrisson\n"
137 VERSION_COPYRIGHT_DISCLAIMER);
142 doTunctl(struct Arguments *args, char *interface)
147 fd = EopenD(args->device, O_RDWR, 0);
149 strncpy(ifr.ifr_name, interface, IFNAMSIZ);
150 ifr.ifr_name[IFNAMSIZ-1] = '\0';
151 ifr.ifr_flags = args->type;
152 EioctlD(fd, TUNSETIFF, &ifr);
154 if (args->set & (CMD_CSUM|CMD_NOCSUM))
155 EioctlD(fd, TUNSETNOCSUM, (void *) (long) !args->checksum);
156 if (args->set & CMD_UID)
157 EioctlD(fd, TUNSETOWNER, (void *) (long) args->uid);
158 if (args->set & CMD_GID)
159 EioctlD(fd, TUNSETGROUP, (void *) (long) args->gid);
160 if (args->set & CMD_NID) {
161 if (args->set & CMD_NID_FAILURE_OK)
162 ioctl(fd, TUNSETNID, (void *) (long) args->nid);
164 EioctlD(fd, TUNSETNID, (void *) (long) args->nid);
166 if (args->set & CMD_LINKTYPE)
167 EioctlD(fd, TUNSETLINK, (void *) (long) args->linktype);
168 if (args->set & (CMD_PERSIST|CMD_NOPERSIST))
169 EioctlD(fd, TUNSETPERSIST, (void *) (long) args->persist);
174 int main(int argc, char *argv[])
176 struct Arguments args = {
179 .device = "/dev/net/tun",
190 int c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0);
195 case CMD_HELP : showHelp(1, argv[0], 0);
196 case CMD_VERSION : showVersion();
198 case CMD_NID_FAILURE_OK:
199 case CMD_NID : args.nid = Evc_nidopt2nid(optarg, true); break;
200 case CMD_DEVICE : args.device = optarg; break;
201 case CMD_PERSIST : args.persist = 1; break;
202 case CMD_NOPERSIST: args.persist = 0; break;
203 case CMD_CSUM : args.checksum = 1; break;
204 case CMD_NOCSUM : args.checksum = 0; break;
205 case CMD_TUN : args.type = IFF_TUN; break;
206 case CMD_TAP : args.type = IFF_TAP; break;
208 if (!isNumber(optarg, &tmp, true)) {
209 WRITE_MSG(2, "Uid '");
210 WRITE_STR(2, optarg);
211 WRITE_MSG(2, "' is not an integer.\n");
213 args.uid = (uid_t) tmp;
216 if (!isNumber(optarg, &tmp, true)) {
217 WRITE_MSG(2, "Gid '");
218 WRITE_STR(2, optarg);
219 WRITE_MSG(2, "' is not an integer.\n");
221 args.gid = (gid_t) tmp;
224 if (!isNumber(optarg, &tmp, true)) {
225 WRITE_MSG(2, "Link-type '");
226 WRITE_STR(2, optarg);
227 WRITE_STR(2, "' is not an integer.\n");
229 args.linktype = (int) tmp;
233 WRITE_MSG(2, "Try '");
234 WRITE_STR(2, argv[0]);
235 WRITE_MSG(2, " --help' for more information.\n");
243 for (interface = argv + optind; *interface; interface++) {
244 doTunctl(&args, *interface);