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
64 #define CMD_NID_FAILURE_OK (0x0800 | CMD_NID)
66 int wrapper_exit_code = 255;
70 { "help", no_argument, 0, CMD_HELP },
71 { "version", no_argument, 0, CMD_VERSION },
72 { "nid", required_argument, 0, CMD_NID },
73 { "device", required_argument, 0, CMD_DEVICE },
74 { "persist", no_argument, 0, CMD_PERSIST },
75 { "~persist", no_argument, 0, CMD_NOPERSIST },
76 { "checksum", no_argument, 0, CMD_CSUM },
77 { "~checksum", no_argument, 0, CMD_NOCSUM },
78 { "uid", required_argument, 0, CMD_UID },
79 { "gid", required_argument, 0, CMD_GID },
80 { "linktype", required_argument, 0, CMD_LINKTYPE },
81 { "tun", no_argument, 0, CMD_TUN },
82 { "tap", no_argument, 0, CMD_TAP },
83 { "nid-failure-ok", required_argument, 0, CMD_NID_FAILURE_OK },
92 unsigned checksum : 1;
100 showHelp(int fd, char const *cmd, int res)
102 WRITE_MSG(fd, "Usage: ");
106 " [--persist|--~persist] [--checksum|--~checksum]\n"
107 " [--nid <nid>] [--uid <uid>] [--gid <gid>] [--linktype <link type>]\n"
108 " <interface(s)>...\n"
110 "Please report bugs to " PACKAGE_BUGREPORT "\n");
119 "tunctl " VERSION " -- controls TUN/TAP devices\n"
120 "This program is part of " PACKAGE_STRING "\n\n"
121 "Copyright (C) 2008 Daniel Hokka Zakrisson\n"
122 VERSION_COPYRIGHT_DISCLAIMER);
127 doTunctl(struct Arguments *args, char *interface)
132 fd = EopenD(args->device, O_RDWR, 0);
134 strncpy(ifr.ifr_name, interface, IFNAMSIZ);
135 ifr.ifr_name[IFNAMSIZ-1] = '\0';
136 ifr.ifr_flags = args->type;
137 EioctlD(fd, TUNSETIFF, &ifr);
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 if (args->set & CMD_NID_FAILURE_OK)
147 ioctl(fd, TUNSETNID, (void *) (long) args->nid);
149 EioctlD(fd, TUNSETNID, (void *) (long) args->nid);
151 if (args->set & CMD_LINKTYPE)
152 EioctlD(fd, TUNSETLINK, (void *) (long) args->linktype);
153 if (args->set & (CMD_PERSIST|CMD_NOPERSIST))
154 EioctlD(fd, TUNSETPERSIST, (void *) (long) args->persist);
159 int main(int argc, char *argv[])
161 struct Arguments args = {
164 .device = "/dev/net/tun",
175 int c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0);
180 case CMD_HELP : showHelp(1, argv[0], 0);
181 case CMD_VERSION : showVersion();
183 case CMD_NID_FAILURE_OK:
184 case CMD_NID : args.nid = Evc_nidopt2nid(optarg, true); break;
185 case CMD_DEVICE : args.device = optarg; break;
186 case CMD_PERSIST : args.persist = 1; break;
187 case CMD_NOPERSIST: args.persist = 0; break;
188 case CMD_CSUM : args.checksum = 1; break;
189 case CMD_NOCSUM : args.checksum = 0; break;
190 case CMD_TUN : args.type = IFF_TUN; break;
191 case CMD_TAP : args.type = IFF_TAP; break;
193 if (!isNumber(optarg, &tmp, true)) {
194 WRITE_MSG(2, "Uid '");
195 WRITE_STR(2, optarg);
196 WRITE_MSG(2, "' is not an integer.\n");
198 args.uid = (uid_t) tmp;
201 if (!isNumber(optarg, &tmp, true)) {
202 WRITE_MSG(2, "Gid '");
203 WRITE_STR(2, optarg);
204 WRITE_MSG(2, "' is not an integer.\n");
206 args.gid = (gid_t) tmp;
209 if (!isNumber(optarg, &tmp, true)) {
210 WRITE_MSG(2, "Link-type '");
211 WRITE_STR(2, optarg);
212 WRITE_STR(2, "' is not an integer.\n");
214 args.linktype = (int) tmp;
218 WRITE_MSG(2, "Try '");
219 WRITE_STR(2, argv[0]);
220 WRITE_MSG(2, " --help' for more information.\n");
228 for (interface = argv + optind; *interface; interface++) {
229 doTunctl(&args, *interface);