merge with 0.30.213
[util-vserver.git] / vserver-start / interface-add.c
1 // $Id: interface-add.c 1939 2005-03-19 02:07:40Z ensc $    --*- c -*--
2
3 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
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 "interface.h"
24 #include "pathconfig.h"
25
26 #include <lib_internal/command.h>
27 #include <lib_internal/util.h>
28 #include <ensc_fmt/fmt.h>
29
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32
33 unsigned int
34 Iface_getIPv4Prefix(struct Interface const *iface)
35 {
36   uint32_t      mask = iface->addr.ipv4.mask;
37   unsigned int  res  = 0;
38   while (mask!=0) {
39     res += mask & 1;
40     mask >>= 1;
41   }
42
43   return res;
44 }
45
46 static bool
47 invokeIpAddr(struct Interface const *iface)
48 {
49   struct Command                cmd;
50   unsigned int                  prefix = Iface_getIPv4Prefix(iface);
51   char *                        tmp = inet_ntoa(*reinterpret_cast(struct in_addr *)(&iface->addr.ipv4.ip));
52   size_t                        l   = strlen(tmp);
53   char                          addr[l + sizeof("/") + sizeof(unsigned int)*3 + 1];
54   char *                        ptr;
55   size_t                        l1 = strlen(iface->dev);
56   size_t                        l2 = iface->name ? strlen(iface->name) : 0;
57   char                          devlabel[l1 + l2 + sizeof(":")];
58   bool                          result = true;
59
60   ptr    = Xmemcpy(addr, tmp, l);
61   *ptr++ = '/';
62   l      = utilvserver_fmt_uint(ptr, prefix);
63   ptr[l] = '\0';
64
65   Command_init(&cmd);
66
67   size_t                idx    = 6;
68   char const *          argv[] = {
69     "/bin/echo",
70     PROG_IP, "addr", "add",
71     addr,
72     "broadcast", 0,
73     0, 0,       // label <name>
74     0, 0,       // dev   <dev>
75     0
76   };
77
78   if (iface->addr.ipv4.bcast!=0)
79     argv[idx++] = inet_ntoa(*reinterpret_cast(struct in_addr *)(&iface->addr.ipv4.bcast));
80   else
81     argv[idx++] = "+";
82   
83   if (iface->name) {
84     ptr    = Xmemcpy(devlabel, iface->dev,  l1);
85     *ptr++ = ':';
86     ptr    = Xmemcpy(ptr,      iface->name, l2);
87     *ptr   = '\0';
88     
89     argv[idx++] = "label";
90     argv[idx++] = devlabel;
91   }
92
93   argv[idx++] = "dev";
94   argv[idx++] = iface->dev;  
95
96   Command_setParams(&cmd, argv);
97   if (!Command_exec(&cmd, true) ||
98       !Command_wait(&cmd, true) ||
99       cmd.rc!=0)
100     result = false;
101
102   Command_free(&cmd);
103   
104   return result;
105 }
106
107 static bool
108 addVLAN(struct Interface const UNUSED *iface)
109 {
110   abort();      // TODO: implement me
111 }
112
113 static bool
114 addIndirect(struct Interface const UNUSED *iface)
115 {
116   abort();      // TODO: implement me
117 }
118
119 static bool
120 addIP(struct Interface const *iface)
121 {
122   return invokeIpAddr(iface);
123     //invokeIpLink(iface);
124 }
125
126 bool
127 Iface_add(struct Interface const *iface)
128 {
129   if (iface->nodev)               return true;
130   if (strchr(iface->dev, '.')!=0) return addVLAN(iface);
131   if (!iface->direct)             return addIndirect(iface);
132   return addIP(iface);
133 }