vshost-util-vserver

Build script and sources for util-vserver.
git clone https://ccx.te2000.cz/git/vshost-util-vserver
Log | Files | Refs

tunctl.c (6641B)


      1 // $Id$    --*- c -*--
      2 
      3 // Copyright (C) 2008 Daniel Hokka Zakrisson
      4 //  
      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.
      8 //  
      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.
     13 //  
     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.
     17 
     18 
     19 #ifdef HAVE_CONFIG_H
     20 #  include <config.h>
     21 #endif
     22 
     23 #include "util.h"
     24 
     25 #include <vserver.h>
     26 
     27 #include <getopt.h>
     28 #include <errno.h>
     29 #include <fcntl.h>
     30 #include <unistd.h>
     31 #include <sys/ioctl.h>
     32 #include <linux/if.h>
     33 #include <linux/if_tun.h>
     34 
     35 /* Make sure we have the necessary ioctls */
     36 #ifndef TUNSETNOCSUM
     37 #  define TUNSETNOCSUM		_IOW('T', 200, int)
     38 #endif
     39 #ifndef TUNSETIFF
     40 #  define TUNSETIFF		_IOW('T', 202, int)
     41 #endif
     42 #ifndef TUNSETPERSIST
     43 #  define TUNSETPERSIST		_IOW('T', 203, int)
     44 #endif
     45 #ifndef TUNSETOWNER
     46 #  define TUNSETOWNER		_IOW('T', 204, int)
     47 #endif
     48 #ifndef TUNSETLINK
     49 #  define TUNSETLINK		_IOW('T', 205, int)
     50 #endif
     51 #ifndef TUNSETGROUP
     52 #  define TUNSETGROUP		_IOW('T', 206, int)
     53 #endif
     54 #ifndef TUNSETNID
     55 #  define TUNSETNID		_IOW('T', 215, int)
     56 #endif
     57 
     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
     63 #include <wrappers.h>
     64 
     65 
     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)
     80 
     81 int		wrapper_exit_code  =  255;
     82 
     83 struct option const
     84 CMDLINE_OPTIONS[] = {
     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 },
     99   {0,0,0,0}
    100 };
    101 
    102 struct Arguments {
    103   unsigned int set;
    104   nid_t nid;
    105   char *device;
    106   unsigned persist : 1;
    107   unsigned checksum : 1;
    108   uid_t uid;
    109   gid_t gid;
    110   int linktype;
    111   int type;
    112 };
    113 
    114 static void
    115 showHelp(int fd, char const *cmd, int res)
    116 {
    117   WRITE_MSG(fd, "Usage: ");
    118   WRITE_STR(fd, cmd);
    119   WRITE_MSG(fd,
    120 	    " {--tun|--tap}\n"
    121 	    "    [--persist|--~persist] [--checksum|--~checksum]\n"
    122 	    "    [--nid <nid>] [--uid <uid>] [--gid <gid>] [--linktype <link type>]\n"
    123 	    "    <interface(s)>...\n"
    124 	    "\n"
    125 	    "Please report bugs to " PACKAGE_BUGREPORT "\n");
    126 
    127   exit(res);
    128 }
    129 
    130 static void
    131 showVersion()
    132 {
    133   WRITE_MSG(1,
    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);
    138   exit(0);
    139 }
    140 
    141 static void
    142 doTunctl(struct Arguments *args, char *interface)
    143 {
    144   int fd;
    145   struct ifreq ifr;
    146 
    147   fd = EopenD(args->device, O_RDWR, 0);
    148 
    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);
    153 
    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);
    163     else
    164       EioctlD(fd, TUNSETNID, (void *) (long) args->nid);
    165   }
    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);
    170 
    171   close(fd);
    172 }
    173 
    174 int main(int argc, char *argv[])
    175 {
    176   struct Arguments args = {
    177     .set = 0,
    178     .nid = VC_NOCTX,
    179     .device = "/dev/net/tun",
    180     .persist = 0,
    181     .checksum = 0,
    182     .uid = -1,
    183     .gid = -1,
    184     .linktype = -1,
    185     .type = IFF_TUN,
    186   };
    187   char **interface;
    188   
    189   while (1) {
    190     int		c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0);
    191     signed long tmp = 0;
    192     if (c==-1) break;
    193 
    194     switch (c) {
    195       case CMD_HELP	:  showHelp(1, argv[0], 0);
    196       case CMD_VERSION	:  showVersion();
    197 
    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;
    207       case CMD_UID	:
    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");
    212 	}
    213 	args.uid = (uid_t) tmp;
    214 	break;
    215       case CMD_GID	:
    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");
    220 	}
    221 	args.gid = (gid_t) tmp;
    222 	break;
    223       case CMD_LINKTYPE	:
    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");
    228 	}
    229 	args.linktype = (int) tmp;
    230 	break;
    231 
    232       default		:
    233 	WRITE_MSG(2, "Try '");
    234 	WRITE_STR(2, argv[0]);
    235 	WRITE_MSG(2, " --help' for more information.\n");
    236 	return 255;
    237 	break;
    238     }
    239 
    240     args.set |= c;
    241   }
    242 
    243   for (interface = argv + optind; *interface; interface++) {
    244     doTunctl(&args, *interface);
    245   }
    246 
    247   return EXIT_SUCCESS;
    248 }