minor optimizations
[util-vserver.git] / util-vserver / vserver-start / interface-add.c
1 // $Id$    --*- 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                          buf[sizeof("255.255.255.255/") + sizeof(unsigned int)*3 + 1];
52   char *                        tmp = inet_ntoa(*reinterpret_cast(struct in_addr *)(&iface->addr.ipv4.ip));
53   size_t                        l   = strlen(tmp);
54   char *                        ptr;
55
56   if (l>=sizeof("255.255.255.255")) {
57     abort();
58     return false;
59   }
60   ptr    = Xmemcpy(buf, tmp, l);
61   *ptr++ = '/';
62   l      = utilvserver_fmt_uint(ptr, prefix);
63   ptr[l] = '\0';
64
65   Command_init(&cmd, 5);
66   Command_appendParameter(&cmd, "/bin/echo");
67   Command_appendParameter(&cmd, PROG_IP);
68   Command_appendParameter(&cmd, buf);
69   Command_appendParameter(&cmd, "broadcast");
70   if (iface->addr.ipv4.bcast!=0)
71     Command_appendParameter(&cmd, inet_ntoa(*reinterpret_cast(struct in_addr *)(&iface->addr.ipv4.bcast)));
72   else
73     Command_appendParameter(&cmd, "+");
74
75   size_t                        l1 = strlen(iface->dev);
76   size_t                        l2 = iface->name ? strlen(iface->name) : 0;
77   char                          devlabel[l1 + l2 + sizeof(":")];
78   
79   if (iface->name) {
80     ptr    = Xmemcpy(devlabel, iface->dev,  l1);
81     *ptr++ = ':';
82     ptr    = Xmemcpy(ptr,      iface->name, l2);
83     *ptr   = '\0';
84     
85     Command_appendParameter(&cmd, "label");
86     Command_appendParameter(&cmd, devlabel);
87   }
88
89   Command_appendParameter(&cmd, "dev");
90   Command_appendParameter(&cmd, iface->dev);
91
92   if (!Command_exec(&cmd, true) ||
93       !Command_wait(&cmd, true))
94     return false;
95
96   Command_free(&cmd);
97   
98   return true;
99 }
100
101 static bool
102 addVLAN(struct Interface const *iface)
103 {
104   abort();      // TODO: implement me
105 }
106
107 static bool
108 addIndirect(struct Interface const *iface)
109 {
110   abort();      // TODO: implement me
111 }
112
113 static bool
114 addIP(struct Interface const *iface)
115 {
116   return invokeIpAddr(iface);
117     //invokeIpLink(iface);
118 }
119
120 bool
121 Iface_add(struct Interface const *iface)
122 {
123   if (iface->nodev)               return true;
124   if (strchr(iface->dev, '.')!=0) return addVLAN(iface);
125   if (!iface->direct)             return addIndirect(iface);
126   return addIP(iface);
127 }