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 TUNSETGROUP _IOW('T', 206, int)
40 # define TUNSETNID _IOW('T', 215, int)
43 #define ENSC_WRAPPERS_PREFIX "tunctl: "
44 #define ENSC_WRAPPERS_UNISTD 1
45 #define ENSC_WRAPPERS_VSERVER 1
46 #define ENSC_WRAPPERS_FCNTL 1
47 #define ENSC_WRAPPERS_IOCTL 1
51 #define CMD_HELP 0x1000
52 #define CMD_VERSION 0x1001
53 #define CMD_NID 0x0001
54 #define CMD_DEVICE 0x0002
55 #define CMD_PERSIST 0x0004
56 #define CMD_NOPERSIST 0x0008
57 #define CMD_CSUM 0x0010
58 #define CMD_NOCSUM 0x0020
59 #define CMD_UID 0x0040
60 #define CMD_GID 0x0080
61 #define CMD_LINKTYPE 0x0100
62 #define CMD_TUN 0x0200
63 #define CMD_TAP 0x0400
65 int wrapper_exit_code = 255;
69 { "help", no_argument, 0, CMD_HELP },
70 { "version", no_argument, 0, CMD_VERSION },
71 { "nid", required_argument, 0, CMD_NID },
72 { "device", required_argument, 0, CMD_DEVICE },
73 { "persist", no_argument, 0, CMD_PERSIST },
74 { "~persist", no_argument, 0, CMD_NOPERSIST },
75 { "checksum", no_argument, 0, CMD_CSUM },
76 { "~checksum", no_argument, 0, CMD_NOCSUM },
77 { "uid", required_argument, 0, CMD_UID },
78 { "gid", required_argument, 0, CMD_GID },
79 { "linktype", required_argument, 0, CMD_LINKTYPE },
80 { "tun", no_argument, 0, CMD_TUN },
81 { "tap", no_argument, 0, CMD_TAP },
90 unsigned checksum : 1;
98 showHelp(int fd, char const *cmd, int res)
100 WRITE_MSG(fd, "Usage: ");
104 " [--persist|--~persist] [--checksum|--~checksum]\n"
105 " [--nid <nid>] [--uid <uid>] [--gid <gid>] [--linktype <link type>]\n"
106 " <interface(s)>...\n"
108 "Please report bugs to " PACKAGE_BUGREPORT "\n");
117 "tunctl " VERSION " -- controls TUN/TAP devices\n"
118 "This program is part of " PACKAGE_STRING "\n\n"
119 "Copyright (C) 2008 Daniel Hokka Zakrisson\n"
120 VERSION_COPYRIGHT_DISCLAIMER);
125 doTunctl(struct Arguments *args, char *interface)
130 fd = EopenD(args->device, O_RDWR, 0);
132 strncpy(ifr.ifr_name, interface, IFNAMSIZ);
133 ifr.ifr_name[IFNAMSIZ-1] = '\0';
134 ifr.ifr_flags = args->type;
135 EioctlD(fd, TUNSETIFF, &ifr);
137 if (args->set & (CMD_PERSIST|CMD_NOPERSIST))
138 EioctlD(fd, TUNSETPERSIST, (void *) (long) args->persist);
139 if (args->set & (CMD_CSUM|CMD_NOCSUM))
140 EioctlD(fd, TUNSETNOCSUM, (void *) (long) !args->checksum);
141 if (args->set & CMD_UID)
142 EioctlD(fd, TUNSETOWNER, (void *) (long) args->uid);
143 if (args->set & CMD_GID)
144 EioctlD(fd, TUNSETGROUP, (void *) (long) args->gid);
145 if (args->set & CMD_NID)
146 EioctlD(fd, TUNSETNID, (void *) (long) args->nid);
147 if (args->set & CMD_LINKTYPE)
148 EioctlD(fd, TUNSETLINK, (void *) (long) args->linktype);
153 int main(int argc, char *argv[])
155 struct Arguments args = {
158 .device = "/dev/net/tun",
169 int c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0);
174 case CMD_HELP : showHelp(1, argv[0], 0);
175 case CMD_VERSION : showVersion();
177 case CMD_NID : args.nid = Evc_nidopt2nid(optarg, true); break;
178 case CMD_DEVICE : args.device = optarg; break;
179 case CMD_PERSIST : args.persist = 1; break;
180 case CMD_NOPERSIST: args.persist = 0; break;
181 case CMD_CSUM : args.checksum = 1; break;
182 case CMD_NOCSUM : args.checksum = 0; break;
183 case CMD_TUN : args.type = IFF_TUN; break;
184 case CMD_TAP : args.type = IFF_TAP; break;
186 if (!isNumber(optarg, &tmp, true)) {
187 WRITE_MSG(2, "Uid '");
188 WRITE_STR(2, optarg);
189 WRITE_MSG(2, "' is not an integer.\n");
191 args.uid = (uid_t) tmp;
194 if (!isNumber(optarg, &tmp, true)) {
195 WRITE_MSG(2, "Gid '");
196 WRITE_STR(2, optarg);
197 WRITE_MSG(2, "' is not an integer.\n");
199 args.gid = (gid_t) tmp;
202 if (!isNumber(optarg, &tmp, true)) {
203 WRITE_MSG(2, "Link-type '");
204 WRITE_STR(2, optarg);
205 WRITE_STR(2, "' is not an integer.\n");
207 args.linktype = (int) tmp;
211 WRITE_MSG(2, "Try '");
212 WRITE_STR(2, argv[0]);
213 WRITE_MSG(2, " --help' for more information.\n");
221 for (interface = argv + optind; *interface; interface++) {
222 doTunctl(&args, *interface);