start to track Daniel's version
[util-vserver.git] / src / chbind.c
diff --git a/src/chbind.c b/src/chbind.c
deleted file mode 100644 (file)
index 8e87e51..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-// $Id: chbind.c 2588 2007-08-16 02:31:33Z dhozac $
-
-// Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
-// based on chbind.cc by Jacques Gelinas
-//  
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2, or (at your option)
-// any later version.
-//  
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//  
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include "vserver.h"
-#include "util.h"
-
-#include <lib/internal.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#define ENSC_WRAPPERS_PREFIX   "chbind: "
-#define ENSC_WRAPPERS_IO       1
-#define ENSC_WRAPPERS_UNISTD   1
-#define ENSC_WRAPPERS_VSERVER  1
-#include "wrappers.h"
-
-#define CMD_HELP       0x1000
-#define CMD_VERSION    0x1001
-
-#define CMD_SILENT     0x2000
-#define CMD_IP         0x2001
-#define CMD_BCAST      0x2002
-#define CMD_NID                0x2003
-
-int wrapper_exit_code = 255;
-
-
-static struct option const
-CMDLINE_OPTIONS[] = {
-  { "help",     no_argument,  0, CMD_HELP },
-  { "version",  no_argument,  0, CMD_VERSION },
-  { "silent",   no_argument,  0, CMD_SILENT },
-  { "ip",       required_argument, 0, CMD_IP },
-  { "bcast",    required_argument, 0, CMD_BCAST },
-  { "nid",     required_argument, 0, CMD_NID },
-  { 0,0,0,0 }
-};
-
-static void
-showHelp(int fd, char const *cmd, int res)
-{
-  WRITE_MSG(fd, "Usage:\n  ");
-  WRITE_STR(fd, cmd);
-  WRITE_MSG(fd,
-           " [--silent] [--nid <nid>] [--ip <ip_num>[/<mask>]] [--bcast <broadcast>] [--] <commands> <args>*\n\n"
-           "Please report bugs to " PACKAGE_BUGREPORT "\n");
-
-  exit(res);
-}
-
-static void
-showVersion()
-{
-  WRITE_MSG(1,
-           "chbind " VERSION " -- bind to an ip and execute a program\n"
-           "This program is part of " PACKAGE_STRING "\n\n"
-           "Copyright (C) 2003,2004 Enrico Scholz\n"
-           VERSION_COPYRIGHT_DISCLAIMER);
-  exit(0);
-}
-
-/*
-       Check if a network device exist in /proc/net/dev.
-       This is used because ifconfig_ioctl triggers modprobe if requesting
-       information about non existant devices.
-
-       Return != 0 if the device exist.
-*/
-static bool
-existsDevice(char const *dev_raw)
-{
-  size_t       buf_size=8192;
-  char         dev[strlen(dev_raw)+2];
-
-  strcpy(dev, dev_raw);
-  strcat(dev, ":");
-  for (;;) {
-    char       buf[buf_size];
-    char *     pos;
-    bool       too_small;
-    int                fd=open("/proc/net/dev", O_RDONLY);
-    
-    if (fd==-1) return false;
-    too_small = EreadAll(fd, buf, buf_size);
-    close(fd);
-
-    if (too_small) {
-      buf_size *= 2;
-      continue;
-    }
-
-    pos = strstr(buf, dev);
-    return (pos && (pos==buf || pos[-1]==' ' || pos[-1]=='\n'));
-  }
-}
-
-static int ifconfig_ioctl(
-       int fd,
-       const char *ifname,
-       int cmd,
-       struct ifreq *ifr)
-{
-       strcpy(ifr->ifr_name, ifname);
-       return ioctl(fd, cmd,ifr);
-}
-
-/*
-       Fetch the IP number of an interface from the kernel.
-       Assume the device is already available in the kernel
-       Return -1 if any error.
-*/
-int ifconfig_getaddr (
-       const char *ifname,
-       uint32_t *addr,
-       uint32_t *mask,
-       uint32_t *bcast)
-{
-       int ret = -1;
-       if (existsDevice(ifname)){
-               int skfd = socket(AF_INET, SOCK_DGRAM, 0);
-               *addr = 0;
-               *bcast = 0xffffffff;
-               if (skfd != -1){
-                       struct ifreq ifr;
-                       if (ifconfig_ioctl(skfd,ifname,SIOCGIFADDR, &ifr) >= 0){
-                               struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr;
-                               *addr = sin->sin_addr.s_addr;
-                               ret = 0;
-                       }
-                       if (ifconfig_ioctl(skfd,ifname,SIOCGIFNETMASK, &ifr) >= 0){
-                               struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr;
-                               *mask = sin->sin_addr.s_addr;
-                               ret = 0;
-                       }
-                       if (ifconfig_ioctl(skfd,ifname,SIOCGIFBRDADDR, &ifr) >= 0){
-                               struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr;
-                               *bcast = sin->sin_addr.s_addr;
-                               ret = 0;
-                       }
-                       close (skfd);
-               }
-       }
-       return ret;
-}
-
-static void
-readIP(char const *str, struct vc_ip_mask_pair *ip, uint32_t *bcast)
-{
-  if (ifconfig_getaddr(str, &ip->ip, &ip->mask, bcast)==-1) {
-    char               *pt;
-    char               tmpopt[strlen(str)+1];
-    struct hostent     *h;
-
-    strcpy(tmpopt,str);
-    pt = strchr(tmpopt,'/');
-    
-    if (pt==0)
-      ip->mask = ntohl(0xffffff00);
-    else {
-      *pt++ = '\0';
-
-      // Ok, we have a network size, not a netmask
-      if (strchr(pt,'.')==0) {
-       int             sz = atoi(pt);
-       ;
-       for (ip->mask = 0; sz>0; --sz) {
-         ip->mask >>= 1;
-         ip->mask  |= 0x80000000;
-       }
-       ip->mask = ntohl(ip->mask);
-      }
-      else { 
-       struct hostent *h = gethostbyname (pt);
-       if (h==0) {
-         WRITE_MSG(2, "Invalid netmask '");
-         WRITE_STR(2, pt);
-         WRITE_MSG(2, "'\n");
-         exit(wrapper_exit_code);
-       }
-
-       memcpy (&ip->mask, h->h_addr, sizeof(ip->mask));
-      }
-    }
-
-    h = gethostbyname (tmpopt);
-    if (h==0) {
-      WRITE_MSG(2, "Invalid IP number or host name '");
-      WRITE_STR(2, tmpopt);
-      WRITE_MSG(2, "'\n");
-      exit(wrapper_exit_code);
-    }
-
-    memcpy (&ip->ip, h->h_addr,sizeof(ip->ip));
-  }
-}
-
-static void
-readBcast(char const *str, uint32_t *bcast)
-{
-  uint32_t     tmp;
-  if (ifconfig_getaddr(str, &tmp, &tmp, bcast)==-1){
-    struct hostent *h = gethostbyname (str);
-    if (h==0){
-      WRITE_MSG(2, "Invalid broadcast number '");
-      WRITE_STR(2, optarg);
-      WRITE_MSG(2, "'\n");
-      exit(wrapper_exit_code);
-    }
-    memcpy (bcast, h->h_addr,sizeof(*bcast));
-  }
-}
-
-int main (int argc, char *argv[])
-{
-  size_t const                 nb_ipv4root = vc_get_nb_ipv4root();
-  bool                         is_silent   = false;
-  struct vc_ip_mask_pair       ips[nb_ipv4root];
-  size_t                       nbaddrs = 0;
-  uint32_t                     bcast   = 0xffffffff;
-  
-  while (1) {
-    int                c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0);
-    if (c==-1) break;
-
-    switch (c) {
-      case CMD_HELP            :  showHelp(1, argv[0], 0);
-      case CMD_VERSION         :  showVersion();
-      case CMD_SILENT          :  is_silent = true; break;
-      case CMD_BCAST           :  readBcast(optarg, &bcast); break;
-      case CMD_NID             :  WRITE_MSG(2, "WARNING: --nid is not supported by this version\n"); break;
-      case CMD_IP              :
-       if (nbaddrs>=nb_ipv4root) {
-         WRITE_MSG(2, "Too many IP numbers, max 16\n");
-         exit(wrapper_exit_code);
-       }
-       readIP(optarg, ips+nbaddrs, &bcast);
-       ++nbaddrs;
-       break;
-      default          :
-       WRITE_MSG(2, "Try '");
-       WRITE_STR(2, argv[0]);
-       WRITE_MSG(2, " --help' for more information.\n");
-       exit(wrapper_exit_code);
-       break;
-    }
-  }
-
-  if (optind==argc) {
-    WRITE_MSG(2, "No command given; try '--help' for more information\n");
-    exit(wrapper_exit_code);
-  }
-  
-#if !defined(VC_ENABLE_API_COMPAT) && !defined(VC_ENABLE_API_LEGACY)
-#  warning building a dummy chbind-compat with no available APIs
-#endif
-  
-#if defined(VC_ENABLE_API_COMPAT) || defined(VC_ENABLE_API_LEGACY)
-  if (vc_set_ipv4root(bcast,nbaddrs,ips)!=0) {
-    perror("chbind: vc_set_ipv4root()");
-    exit(wrapper_exit_code);
-  }
-#else
-  {
-    WRITE_MSG(2, "chbind: kernel does not provide network isolation\n");
-    exit(wrapper_exit_code);
-  }
-#endif
-
-  if (!is_silent) {
-    size_t             i;
-    
-    WRITE_MSG(1, "ipv4root is now");
-    for (i=0; i<nbaddrs; ++i) {
-      WRITE_MSG(1, " ");
-      WRITE_STR(1, inet_ntoa(*reinterpret_cast(struct in_addr *)(&ips[i].ip)));
-    }
-    WRITE_MSG(1, "\n");
-  }
-
-  Eexecvp (argv[optind],argv+optind);
-  return EXIT_SUCCESS;
-}
-
-#ifdef ENSC_TESTSUITE
-#include <assert.h>
-
-void test()
-{
-  struct vc_ip_mask_pair       ip;
-  uint32_t                     bcast;
-
-  bcast = 0;
-  readIP("1.2.3.4", &ip, &bcast);
-  assert(ip.ip==ntohl(0x01020304) && ip.mask==ntohl(0xffffff00) && bcast==0);
-
-  readIP("1.2.3.4/8", &ip, &bcast);
-  assert(ip.ip==ntohl(0x01020304) && ip.mask==ntohl(0xff000000) && bcast==0);
-
-  readIP("1.2.3.4/255.255.0.0", &ip, &bcast);
-  assert(ip.ip==ntohl(0x01020304) && ip.mask==ntohl(0xffff0000) && bcast==0);
-
-  readIP("localhost", &ip, &bcast);
-  assert(ip.ip==ntohl(0x7f000001) && ip.mask==ntohl(0xffffff00) && bcast==0);
-
-#if 0
-  if (ifconfig_getaddr("lo", &tmp, &tmp, &tmp)!=-1) {
-    readIP("lo", &ip, &bcast);
-    assert(ip.ip==ntohl(0x7f000001) && ip.mask==ntohl(0xff000000) && bcast==ntohl(0x7fffffff));
-  }
-#endif
-}
-#endif