summaryrefslogtreecommitdiff
path: root/networking/ifupdown.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2003-04-02 10:13:26 +0000
committerEric Andersen <andersen@codepoet.org>2003-04-02 10:13:26 +0000
commit8320b425a3016e0610dee2970b24a0ebcad0d943 (patch)
tree4c0a605806b3a6ca61986084d7b18edce5c6ba80 /networking/ifupdown.c
parenta71c7047cfd1cf79ed0e8e8a7f0cde2019f79ae4 (diff)
downloadbusybox-w32-8320b425a3016e0610dee2970b24a0ebcad0d943.tar.gz
busybox-w32-8320b425a3016e0610dee2970b24a0ebcad0d943.tar.bz2
busybox-w32-8320b425a3016e0610dee2970b24a0ebcad0d943.zip
Yet another rather large face lift. It now works for me as expected.
-Erik
Diffstat (limited to 'networking/ifupdown.c')
-rw-r--r--networking/ifupdown.c974
1 files changed, 486 insertions, 488 deletions
diff --git a/networking/ifupdown.c b/networking/ifupdown.c
index 9bbb90496..fedae8dd6 100644
--- a/networking/ifupdown.c
+++ b/networking/ifupdown.c
@@ -1,6 +1,8 @@
1/* vi: set sw=4 ts=4: */
1/* 2/*
2 * ifupdown for busybox 3 * ifupdown for busybox
3 * Copyright (c) 2002 Glenn McGrath <bug1@optushome.com.au> 4 * Copyright (c) 2002 Glenn McGrath <bug1@optushome.com.au>
5 * Copyright (c) 2003 Erik Andersen <andersen@codepoet.org>
4 * 6 *
5 * Based on ifupdown v 0.6.4 by Anthony Towns 7 * Based on ifupdown v 0.6.4 by Anthony Towns
6 * Copyright (c) 1999 Anthony Towns <aj@azure.humbug.org.au> 8 * Copyright (c) 1999 Anthony Towns <aj@azure.humbug.org.au>
@@ -47,25 +49,59 @@
47#define EUNDEFVAR 10002 49#define EUNDEFVAR 10002
48#define EUNBALPER 10000 50#define EUNBALPER 10000
49 51
50typedef struct interface_defn_s interface_defn_t; 52
53#if 0
54#define debug_noise(fmt, args...) printf(fmt, ## args)
55#else
56#define debug_noise(fmt, args...)
57#endif
58
59/* Forward declaration */
60struct interface_defn_t;
51 61
52typedef int (execfn)(char *command); 62typedef int (execfn)(char *command);
53typedef int (command_set)(interface_defn_t *ifd, execfn *e); 63typedef int (command_set)(struct interface_defn_t *ifd, execfn *e);
64
65extern llist_t *llist_add_to_end(llist_t *list_head, char *data)
66{
67 llist_t *new_item, *tmp, *prev;
68
69 new_item = xmalloc(sizeof(llist_t));
70 new_item->data = data;
71 new_item->link = NULL;
72
73 prev = NULL;
74 tmp = list_head;
75 while(tmp) {
76 prev = tmp;
77 tmp = tmp->link;
78 }
79 if (prev) {
80 prev->link = new_item;
81 } else {
82 list_head = new_item;
83 }
54 84
55typedef struct method_s { 85 return(list_head);
86}
87
88struct method_t
89{
56 char *name; 90 char *name;
57 command_set *up; 91 command_set *up;
58 command_set *down; 92 command_set *down;
59} method_t; 93};
60 94
61typedef struct address_family_s { 95struct address_family_t
96{
62 char *name; 97 char *name;
63 int n_methods; 98 int n_methods;
64 method_t *method; 99 struct method_t *method;
65} address_family_t; 100};
66 101
67typedef struct mapping_defn_s { 102struct mapping_defn_t
68 struct mapping_defn_s *next; 103{
104 struct mapping_defn_t *next;
69 105
70 int max_matches; 106 int max_matches;
71 int n_matches; 107 int n_matches;
@@ -76,60 +112,61 @@ typedef struct mapping_defn_s {
76 int max_mappings; 112 int max_mappings;
77 int n_mappings; 113 int n_mappings;
78 char **mapping; 114 char **mapping;
79} mapping_defn_t; 115};
80 116
81typedef struct variable_s { 117struct variable_t
118{
82 char *name; 119 char *name;
83 char *value; 120 char *value;
84} variable_t; 121};
85 122
86struct interface_defn_s { 123struct interface_defn_t
87 struct interface_defn_s *next; 124{
125 struct interface_defn_t *prev;
126 struct interface_defn_t *next;
88 127
89 char *iface; 128 char *iface;
90 address_family_t *address_family; 129 struct address_family_t *address_family;
91 method_t *method; 130 struct method_t *method;
92 131
93 int automatic; 132 int automatic;
94 133
95 int max_options; 134 int max_options;
96 int n_options; 135 int n_options;
97 variable_t *option; 136 struct variable_t *option;
98}; 137};
99 138
100typedef struct interfaces_file_s { 139struct interfaces_file_t
140{
101 llist_t *autointerfaces; 141 llist_t *autointerfaces;
102 interface_defn_t *ifaces; 142 llist_t *ifaces;
103 mapping_defn_t *mappings; 143 struct mapping_defn_t *mappings;
104} interfaces_file_t; 144};
105 145
106static char no_act = 0; 146static char no_act = 0;
107static char verbose = 0; 147static char verbose = 0;
108static char **environ = NULL; 148static char **environ = NULL;
109 149
110#ifdef CONFIG_FEATURE_IFUPDOWN_IP 150#ifdef CONFIG_FEATURE_IFUPDOWN_IP
151
152static unsigned int count_bits(unsigned int a)
153{
154 unsigned int result;
155 result = (a & 0x55) + ((a >> 1) & 0x55);
156 result = (result & 0x33) + ((result >> 2) & 0x33);
157 return((result & 0x0F) + ((result >> 4) & 0x0F));
158}
159
111static int count_netmask_bits(char *dotted_quad) 160static int count_netmask_bits(char *dotted_quad)
112{ 161{
113 unsigned int a, b, c, d; 162 unsigned int result, a, b, c, d;
114 unsigned int res, result;
115 /* Found a netmask... Check if it is dotted quad */ 163 /* Found a netmask... Check if it is dotted quad */
116 if (sscanf(dotted_quad, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) 164 if (sscanf(dotted_quad, "%u.%u.%u.%u", &a, &b, &c, &d) != 4)
117 return -1; 165 return -1;
118 res = (a & 0x55) + ((a >> 1) & 0x55); 166 result = count_bits(a);
119 res = (res & 0x33) + ((res >> 2) & 0x33); 167 result += count_bits(b);
120 result = (res & 0x0F) + ((res >> 4) & 0x0F); 168 result += count_bits(c);
121 169 result += count_bits(d);
122 res = (b & 0x55) + ((b >> 1) & 0x55);
123 res = (res & 0x33) + ((res >> 2) & 0x33);
124 result += (res & 0x0F) + ((res >> 4) & 0x0F);
125
126 res = (c & 0x55) + ((c >> 1) & 0x55);
127 res = (res & 0x33) + ((res >> 2) & 0x33);
128 result += (res & 0x0F) + ((res >> 4) & 0x0F);
129
130 res = (d & 0x55) + ((d >> 1) & 0x55);
131 res = (res & 0x33) + ((res >> 2) & 0x33);
132 result += (res & 0x0F) + ((res >> 4) & 0x0F);
133 return ((int)result); 170 return ((int)result);
134} 171}
135#endif 172#endif
@@ -162,11 +199,21 @@ static int strncmpz(char *l, char *r, size_t llen)
162 } 199 }
163} 200}
164 201
165static char *get_var(char *id, size_t idlen, interface_defn_t *ifd) 202static char *get_var(char *id, size_t idlen, struct interface_defn_t *ifd)
166{ 203{
167 int i; 204 int i;
168 205
169 if (strncmpz(id, "iface", idlen) == 0) { 206 if (strncmpz(id, "iface", idlen) == 0) {
207 char *result;
208 static char label_buf[20];
209 strncpy(label_buf, ifd->iface, 19);
210 label_buf[19]=0;
211 result = strchr(label_buf, ':');
212 if (result) {
213 *result=0;
214 }
215 return( label_buf);
216 } else if (strncmpz(id, "label", idlen) == 0) {
170 return (ifd->iface); 217 return (ifd->iface);
171 } else { 218 } else {
172 for (i = 0; i < ifd->n_options; i++) { 219 for (i = 0; i < ifd->n_options; i++) {
@@ -179,7 +226,7 @@ static char *get_var(char *id, size_t idlen, interface_defn_t *ifd)
179 return(NULL); 226 return(NULL);
180} 227}
181 228
182static char *parse(char *command, interface_defn_t *ifd) 229static char *parse(char *command, struct interface_defn_t *ifd)
183{ 230{
184 231
185 char *result = NULL; 232 char *result = NULL;
@@ -191,82 +238,82 @@ static char *parse(char *command, interface_defn_t *ifd)
191 while (*command) { 238 while (*command) {
192 switch (*command) { 239 switch (*command) {
193 240
194 default: 241 default:
195 addstr(&result, &len, &pos, command, 1);
196 command++;
197 break;
198 case '\\':
199 if (command[1]) {
200 addstr(&result, &len, &pos, command + 1, 1);
201 command += 2;
202 } else {
203 addstr(&result, &len, &pos, command, 1); 242 addstr(&result, &len, &pos, command, 1);
204 command++; 243 command++;
205 } 244 break;
206 break; 245 case '\\':
207 case '[': 246 if (command[1]) {
208 if (command[1] == '[' && opt_depth < MAX_OPT_DEPTH) { 247 addstr(&result, &len, &pos, command + 1, 1);
209 old_pos[opt_depth] = pos; 248 command += 2;
210 okay[opt_depth] = 1; 249 } else {
211 opt_depth++; 250 addstr(&result, &len, &pos, command, 1);
212 command += 2; 251 command++;
213 } else {
214 addstr(&result, &len, &pos, "[", 1);
215 command++;
216 }
217 break;
218 case ']':
219 if (command[1] == ']' && opt_depth > 1) {
220 opt_depth--;
221 if (!okay[opt_depth]) {
222 pos = old_pos[opt_depth];
223 result[pos] = '\0';
224 } 252 }
225 command += 2; 253 break;
226 } else { 254 case '[':
227 addstr(&result, &len, &pos, "]", 1); 255 if (command[1] == '[' && opt_depth < MAX_OPT_DEPTH) {
228 command++; 256 old_pos[opt_depth] = pos;
229 } 257 okay[opt_depth] = 1;
230 break; 258 opt_depth++;
231 case '%': 259 command += 2;
232 { 260 } else {
233 char *nextpercent; 261 addstr(&result, &len, &pos, "[", 1);
234 char *varvalue; 262 command++;
235 263 }
236 command++; 264 break;
237 nextpercent = strchr(command, '%'); 265 case ']':
238 if (!nextpercent) { 266 if (command[1] == ']' && opt_depth > 1) {
239 errno = EUNBALPER; 267 opt_depth--;
240 free(result); 268 if (!okay[opt_depth]) {
241 return (NULL); 269 pos = old_pos[opt_depth];
242 } 270 result[pos] = '\0';
271 }
272 command += 2;
273 } else {
274 addstr(&result, &len, &pos, "]", 1);
275 command++;
276 }
277 break;
278 case '%':
279 {
280 char *nextpercent;
281 char *varvalue;
282
283 command++;
284 nextpercent = strchr(command, '%');
285 if (!nextpercent) {
286 errno = EUNBALPER;
287 free(result);
288 return (NULL);
289 }
243 290
244 varvalue = get_var(command, nextpercent - command, ifd); 291 varvalue = get_var(command, nextpercent - command, ifd);
245 292
246 if (varvalue) { 293 if (varvalue) {
247 addstr(&result, &len, &pos, varvalue, bb_strlen(varvalue)); 294 addstr(&result, &len, &pos, varvalue, bb_strlen(varvalue));
248 } else { 295 } else {
249#ifdef CONFIG_FEATURE_IFUPDOWN_IP 296#ifdef CONFIG_FEATURE_IFUPDOWN_IP
250 /* Sigh... Add a special case for 'ip' to convert from 297 /* Sigh... Add a special case for 'ip' to convert from
251 * dotted quad to bit count style netmasks. */ 298 * dotted quad to bit count style netmasks. */
252 if (strncmp(command, "bnmask", 6)==0) { 299 if (strncmp(command, "bnmask", 6)==0) {
253 int res; 300 int res;
254 varvalue = get_var("netmask", 7, ifd); 301 varvalue = get_var("netmask", 7, ifd);
255 if (varvalue && (res=count_netmask_bits(varvalue)) > 0) { 302 if (varvalue && (res=count_netmask_bits(varvalue)) > 0) {
256 char argument[255]; 303 char argument[255];
257 sprintf(argument, "%d", res); 304 sprintf(argument, "%d", res);
258 addstr(&result, &len, &pos, argument, bb_strlen(argument)); 305 addstr(&result, &len, &pos, argument, bb_strlen(argument));
259 command = nextpercent + 1; 306 command = nextpercent + 1;
260 break; 307 break;
261 } 308 }
262 } 309 }
263#endif 310#endif
264 okay[opt_depth - 1] = 0; 311 okay[opt_depth - 1] = 0;
265 } 312 }
266 313
267 command = nextpercent + 1; 314 command = nextpercent + 1;
268 } 315 }
269 break; 316 break;
270 } 317 }
271 } 318 }
272 319
@@ -285,7 +332,7 @@ static char *parse(char *command, interface_defn_t *ifd)
285 return(result); 332 return(result);
286} 333}
287 334
288static int execute(char *command, interface_defn_t *ifd, execfn *exec) 335static int execute(char *command, struct interface_defn_t *ifd, execfn *exec)
289{ 336{
290 char *out; 337 char *out;
291 int ret; 338 int ret;
@@ -294,149 +341,110 @@ static int execute(char *command, interface_defn_t *ifd, execfn *exec)
294 if (!out) { 341 if (!out) {
295 return(0); 342 return(0);
296 } 343 }
297
298 ret = (*exec) (out); 344 ret = (*exec) (out);
299 345
300 free(out); 346 free(out);
301 return(ret); 347 return(1);
302} 348}
303 349
304#ifdef CONFIG_FEATURE_IFUPDOWN_IPX 350#ifdef CONFIG_FEATURE_IFUPDOWN_IPX
305static int static_up_ipx(interface_defn_t *ifd, execfn *exec) 351static int static_up_ipx(struct interface_defn_t *ifd, execfn *exec)
306{ 352{
307 if (!execute("ipx_interface add %iface% %frame% %netnum%", ifd, exec)) { 353 return(execute("ipx_interface add %iface% %frame% %netnum%", ifd, exec));
308 return(0);
309 }
310 return(1);
311} 354}
312 355
313static int static_down_ipx(interface_defn_t *ifd, execfn *exec) 356static int static_down_ipx(struct interface_defn_t *ifd, execfn *exec)
314{ 357{
315 if (!execute("ipx_interface del %iface% %frame%", ifd, exec)) { 358 return(execute("ipx_interface del %iface% %frame%", ifd, exec));
316 return(0);
317 }
318 return(1);
319} 359}
320 360
321static int dynamic_up(interface_defn_t *ifd, execfn *exec) 361static int dynamic_up(struct interface_defn_t *ifd, execfn *exec)
322{ 362{
323 if (!execute("ipx_interface add %iface% %frame%", ifd, exec)) { 363 return(execute("ipx_interface add %iface% %frame%", ifd, exec));
324 return(0);
325 }
326 return(1);
327} 364}
328 365
329static int dynamic_down(interface_defn_t *ifd, execfn *exec) 366static int dynamic_down(struct interface_defn_t *ifd, execfn *exec)
330{ 367{
331 if (!execute("ipx_interface del %iface% %frame%", ifd, exec)) { 368 return(execute("ipx_interface del %iface% %frame%", ifd, exec));
332 return(0);
333 }
334 return(1);
335} 369}
336 370
337static method_t methods_ipx[] = { 371static struct method_t methods_ipx[] = {
338 { "dynamic", dynamic_up, dynamic_down, }, 372 { "dynamic", dynamic_up, dynamic_down, },
339 { "static", static_up_ipx, static_down_ipx, }, 373 { "static", static_up_ipx, static_down_ipx, },
340}; 374};
341 375
342address_family_t addr_ipx = { 376struct address_family_t addr_ipx = {
343 "ipx", 377 "ipx",
344 sizeof(methods_ipx) / sizeof(method_t), 378 sizeof(methods_ipx) / sizeof(struct method_t),
345 methods_ipx 379 methods_ipx
346}; 380};
347#endif /* IFUP_FEATURE_IPX */ 381#endif /* IFUP_FEATURE_IPX */
348 382
349#ifdef CONFIG_FEATURE_IFUPDOWN_IPV6 383#ifdef CONFIG_FEATURE_IFUPDOWN_IPV6
350static int loopback_up6(interface_defn_t *ifd, execfn *exec) 384static int loopback_up6(struct interface_defn_t *ifd, execfn *exec)
351{ 385{
352#ifdef CONFIG_FEATURE_IFUPDOWN_IP 386#ifdef CONFIG_FEATURE_IFUPDOWN_IP
353 if (!execute("ip link set %iface% up", ifd, exec)) 387 int result;
354 return(0); 388 result = execute("ip link set %iface% up", ifd, exec);
355 if (!execute("ip addr add ::1 dev %iface%", ifd, exec)) 389 result +=execute("ip addr add ::1 dev %iface% label %label%", ifd, exec);
356 return(0); 390 return( result);
357#else 391#else
358 if (!execute("ifconfig %iface% add ::1", ifd, exec)) 392 return( execute("ifconfig %iface% add ::1", ifd, exec));
359 return(0);
360#endif 393#endif
361 return(1);
362} 394}
363 395
364static int loopback_down6(interface_defn_t *ifd, execfn *exec) 396static int loopback_down6(struct interface_defn_t *ifd, execfn *exec)
365{ 397{
366#ifdef CONFIG_FEATURE_IFUPDOWN_IP 398#ifdef CONFIG_FEATURE_IFUPDOWN_IP
367 if (!execute("ip link set %iface% down", ifd, exec)) 399 return(execute("ip link set %iface% down", ifd, exec));
368 return(0);
369#else 400#else
370 if (!execute("ifconfig %iface% del ::1", ifd, exec)) 401 return(execute("ifconfig %iface% del ::1", ifd, exec));
371 return(0);
372#endif 402#endif
373 return(1);
374} 403}
375 404
376static int static_up6(interface_defn_t *ifd, execfn *exec) 405static int static_up6(struct interface_defn_t *ifd, execfn *exec)
377{ 406{
407 int result;
378#ifdef CONFIG_FEATURE_IFUPDOWN_IP 408#ifdef CONFIG_FEATURE_IFUPDOWN_IP
379 if (!execute("ip link set %iface% up", ifd, exec)) 409 result = execute("ip link set %iface% up", ifd, exec);
380 return(0); 410 result += execute("ip addr add %address%/%netmask% dev %iface% label %label%", ifd, exec);
381 if (!execute("ip addr add %address%/%netmask% dev %iface%", ifd, exec)) 411 result += execute("[[ ip route add ::/0 via %gateway% ]]", ifd, exec);
382 return(0);
383 if (!execute("[[ ip route add ::/0 via %gateway% ]]", ifd, exec))
384 return(0);
385#else 412#else
386 if (!execute("ifconfig %iface% [[media %media%]] [[hw %hwaddress%]] [[mtu %mtu%]] up", ifd, exec)) { 413 result = execute("ifconfig %iface% [[media %media%]] [[hw %hwaddress%]] [[mtu %mtu%]] up", ifd, exec);
387 return(0); 414 result += execute("ifconfig %iface% add %address%/%netmask%", ifd, exec);
388 } 415 result += execute("[[ route -A inet6 add ::/0 gw %gateway% ]]", ifd, exec);
389 if (!execute("ifconfig %iface% add %address%/%netmask%", ifd, exec)) {
390 return(0);
391 }
392 if (!execute("[[ route -A inet6 add ::/0 gw %gateway% ]]", ifd, exec)) {
393 return(0);
394 }
395#endif 416#endif
396 return(1); 417 return( result);
397} 418}
398 419
399static int static_down6(interface_defn_t *ifd, execfn *exec) 420static int static_down6(struct interface_defn_t *ifd, execfn *exec)
400{ 421{
401#ifdef CONFIG_FEATURE_IFUPDOWN_IP 422#ifdef CONFIG_FEATURE_IFUPDOWN_IP
402 if (!execute("ip link set %iface% down", ifd, exec)) 423 return(execute("ip link set %iface% down", ifd, exec));
403 return(0);
404#else 424#else
405 if (!execute("ifconfig %iface% down", ifd, exec)) { 425 return(execute("ifconfig %iface% down", ifd, exec));
406 return(0);
407 }
408#endif 426#endif
409 return(1);
410} 427}
411 428
412#ifdef CONFIG_FEATURE_IFUPDOWN_IP 429#ifdef CONFIG_FEATURE_IFUPDOWN_IP
413static int v4tunnel_up(interface_defn_t *ifd, execfn *exec) 430static int v4tunnel_up(struct interface_defn_t *ifd, execfn *exec)
414{ 431{
415 if (!execute("ip tunnel add %iface% mode sit remote %endpoint% [[local %local%]] [[ttl %ttl%]]", ifd, exec)) { 432 int result;
416 return(0); 433 result = execute("ip tunnel add %iface% mode sit remote "
417 } 434 "%endpoint% [[local %local%]] [[ttl %ttl%]]", ifd, exec);
418 if (!execute("ip link set %iface% up", ifd, exec)) { 435 result += execute("ip link set %iface% up", ifd, exec);
419 return(0); 436 result += execute("ip addr add %address%/%netmask% dev %iface% label %label%", ifd, exec);
420 } 437 result += execute("[[ ip route add ::/0 via %gateway% ]]", ifd, exec);
421 if (!execute("ip addr add %address%/%netmask% dev %iface%", ifd, exec)) { 438 return( result);
422 return(0);
423 }
424 if (!execute("[[ ip route add ::/0 via %gateway% ]]", ifd, exec)) {
425 return(0);
426 }
427 return(1);
428} 439}
429 440
430static int v4tunnel_down(interface_defn_t * ifd, execfn * exec) 441static int v4tunnel_down(struct interface_defn_t * ifd, execfn * exec)
431{ 442{
432 if (!execute("ip tunnel del %iface%", ifd, exec)) { 443 return( execute("ip tunnel del %iface%", ifd, exec));
433 return(0);
434 }
435 return(1);
436} 444}
437#endif 445#endif
438 446
439static method_t methods6[] = { 447static struct method_t methods6[] = {
440#ifdef CONFIG_FEATURE_IFUPDOWN_IP 448#ifdef CONFIG_FEATURE_IFUPDOWN_IP
441 { "v4tunnel", v4tunnel_up, v4tunnel_down, }, 449 { "v4tunnel", v4tunnel_up, v4tunnel_down, },
442#endif 450#endif
@@ -444,83 +452,67 @@ static method_t methods6[] = {
444 { "loopback", loopback_up6, loopback_down6, }, 452 { "loopback", loopback_up6, loopback_down6, },
445}; 453};
446 454
447address_family_t addr_inet6 = { 455struct address_family_t addr_inet6 = {
448 "inet6", 456 "inet6",
449 sizeof(methods6) / sizeof(method_t), 457 sizeof(methods6) / sizeof(struct method_t),
450 methods6 458 methods6
451}; 459};
452#endif /* CONFIG_FEATURE_IFUPDOWN_IPV6 */ 460#endif /* CONFIG_FEATURE_IFUPDOWN_IPV6 */
453 461
454#ifdef CONFIG_FEATURE_IFUPDOWN_IPV4 462#ifdef CONFIG_FEATURE_IFUPDOWN_IPV4
455static int loopback_up(interface_defn_t *ifd, execfn *exec) 463static int loopback_up(struct interface_defn_t *ifd, execfn *exec)
456{ 464{
457#ifdef CONFIG_FEATURE_IFUPDOWN_IP 465#ifdef CONFIG_FEATURE_IFUPDOWN_IP
458 if (!execute("ip link set %iface% up", ifd, exec)) 466 int result;
459 return(0); 467 result += execute("ip link set %iface% up", ifd, exec);
460 if (!execute("ip addr add 127.0.0.1/8 dev %iface%", ifd, exec)) 468 result += execute("ip addr add 127.0.0.1/8 dev %iface% label %label%", ifd, exec);
461 return(0); 469 return(result);
462#else 470#else
463 if (!execute("ifconfig %iface% 127.0.0.1 up", ifd, exec)) { 471 return( execute("ifconfig %iface% 127.0.0.1 up", ifd, exec));
464 return(0);
465 }
466#endif 472#endif
467 return(1);
468} 473}
469 474
470static int loopback_down(interface_defn_t *ifd, execfn *exec) 475static int loopback_down(struct interface_defn_t *ifd, execfn *exec)
471{ 476{
472#ifdef CONFIG_FEATURE_IFUPDOWN_IP 477#ifdef CONFIG_FEATURE_IFUPDOWN_IP
473 if (!execute("ip addr flush dev %iface%", ifd, exec)) 478 int result;
474 return(0); 479 result = execute("ip addr flush dev %iface%", ifd, exec);
475 if (!execute("ip link set %iface% down", ifd, exec)) 480 result += execute("ip link set %iface% down", ifd, exec);
476 return(0); 481 return(result);
477#else 482#else
478 if (!execute("ifconfig %iface% 127.0.0.1 down", ifd, exec)) { 483 return( execute("ifconfig %iface% 127.0.0.1 down", ifd, exec));
479 return(0);
480 }
481#endif 484#endif
482 return(1);
483} 485}
484 486
485static int static_up(interface_defn_t *ifd, execfn *exec) 487static int static_up(struct interface_defn_t *ifd, execfn *exec)
486{ 488{
489 int result;
487#ifdef CONFIG_FEATURE_IFUPDOWN_IP 490#ifdef CONFIG_FEATURE_IFUPDOWN_IP
488 if (!execute("ip link set %iface% up", ifd, exec)) 491 result = execute("ip link set %iface% up", ifd, exec);
489 return(0); 492 result += execute("ip addr add %address%/%bnmask% [[broadcast %broadcast%]] "
490 if (!execute("ip addr add %address%/%bnmask% [[broadcast %broadcast%]] dev %iface%", ifd, exec)) 493 "dev %iface% label %label%", ifd, exec);
491 return(0); 494 result += execute("[[ ip route add default via %gateway% dev %iface% ]]", ifd, exec);
492 if (!execute("[[ ip route add default via %gateway% dev %iface% ]]", ifd, exec))
493 return(0);
494#else 495#else
495 if (!execute("ifconfig %iface% %address% netmask %netmask% [[broadcast %broadcast%]] [[pointopoint %pointopoint%]] [[media %media%]] [[mtu %mtu%]] [[hw %hwaddress%]] up", 496 result = execute("ifconfig %iface% %address% netmask %netmask% "
496 ifd, exec)) { 497 "[[broadcast %broadcast%]] [[pointopoint %pointopoint%]] "
497 return(0); 498 "[[media %media%]] [[mtu %mtu%]] [[hw %hwaddress%]] up",
498 } 499 ifd, exec);
499 if (!execute("[[ route add default gw %gateway% %iface% ]]", ifd, exec)) { 500 result += execute("[[ route add default gw %gateway% %iface% ]]", ifd, exec);
500 return(0);
501 }
502#endif 501#endif
503 return(1); 502 return(result);
504} 503}
505 504
506static int static_down(interface_defn_t *ifd, execfn *exec) 505static int static_down(struct interface_defn_t *ifd, execfn *exec)
507{ 506{
507 int result;
508#ifdef CONFIG_FEATURE_IFUPDOWN_IP 508#ifdef CONFIG_FEATURE_IFUPDOWN_IP
509 //if (!execute("[[ ip route del default via %gateway% dev %iface% ]]", ifd, exec)) 509 result = execute("ip addr flush dev %iface%", ifd, exec);
510 // return(0); 510 result += execute("ip link set %iface% down", ifd, exec);
511 if (!execute("ip addr flush dev %iface%", ifd, exec))
512 return(0);
513 if (!execute("ip link set %iface% down", ifd, exec))
514 return(0);
515#else 511#else
516 if (!execute("[[ route del default gw %gateway% %iface% ]]", ifd, exec)) { 512 result = execute("[[ route del default gw %gateway% %iface% ]]", ifd, exec);
517 return(0); 513 result += execute("ifconfig %iface% down", ifd, exec);
518 }
519 if (!execute("ifconfig %iface% down", ifd, exec)) {
520 return(0);
521 }
522#endif 514#endif
523 return(1); 515 return(result);
524} 516}
525 517
526static int execable(char *program) 518static int execable(char *program)
@@ -534,102 +526,75 @@ static int execable(char *program)
534 return(0); 526 return(0);
535} 527}
536 528
537static int dhcp_up(interface_defn_t *ifd, execfn *exec) 529static int dhcp_up(struct interface_defn_t *ifd, execfn *exec)
538{ 530{
539 if (execable("/sbin/dhclient")) { 531 if (execable("/sbin/udhcpc")) {
540 if (!execute("dhclient -pf /var/run/dhclient.%iface%.pid %iface%", ifd, exec)) { 532 return( execute("udhcpc -n -p /var/run/udhcpc.%iface%.pid -i "
541 return(0); 533 "%iface% [[-H %hostname%]] [[-c %clientid%]]", ifd, exec));
542 }
543 } else if (execable("/sbin/pump")) { 534 } else if (execable("/sbin/pump")) {
544 if (!execute("pump -i %iface% [[-h %hostname%]] [[-l %leasehours%]]", ifd, exec)) { 535 return( execute("pump -i %iface% [[-h %hostname%]] [[-l %leasehours%]]", ifd, exec));
545 return(0); 536 } else if (execable("/sbin/dhclient")) {
546 } 537 return( execute("dhclient -pf /var/run/dhclient.%iface%.pid %iface%", ifd, exec));
547 } else if (execable("/sbin/udhcpc")) {
548 if (!execute("udhcpc -n -p /var/run/udhcpc.%iface%.pid -i %iface% [[-H %hostname%]] [[-c %clientid%]]", ifd, exec)) {
549 return 0;
550 }
551 } else if (execable("/sbin/dhcpcd")) { 538 } else if (execable("/sbin/dhcpcd")) {
552 if (!execute("dhcpcd [[-h %hostname%]] [[-i %vendor%]] [[-I %clientid%]] [[-l %leasetime%]] %iface%", ifd, exec)) { 539 return( execute("dhcpcd [[-h %hostname%]] [[-i %vendor%]] [[-I %clientid%]] "
553 return(0); 540 "[[-l %leasetime%]] %iface%", ifd, exec));
554 }
555 } 541 }
556 return(1); 542 return(0);
557} 543}
558 544
559static int dhcp_down(interface_defn_t *ifd, execfn *exec) 545static int dhcp_down(struct interface_defn_t *ifd, execfn *exec)
560{ 546{
561 if (execable("/sbin/dhclient")) { 547 int result;
562 if (!execute("kill -9 `cat /var/run/udhcpc.%iface%.pid`", ifd, exec)) { 548 if (execable("/sbin/udhcpc")) {
563 return(0); 549 execute("kill -9 `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", ifd, exec);
564 } 550 result = 0;
565 } else if (execable("/sbin/pump")) { 551 } else if (execable("/sbin/pump")) {
566 if (!execute("pump -i %iface% -k", ifd, exec)) { 552 result = execute("pump -i %iface% -k", ifd, exec);
567 return(0); 553 } else if (execable("/sbin/dhclient")) {
568 } 554 execute("kill -9 `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", ifd, exec);
569 } else if (execable("/sbin/udhcpc")) { 555 result = 0;
570 if (!execute("kill -9 `cat /var/run/udhcpc.%iface%.pid`", ifd, exec)) {
571 return(0);
572 }
573 } else if (execable("/sbin/dhcpcd")) { 556 } else if (execable("/sbin/dhcpcd")) {
574 if (!execute("dhcpcd -k %iface%", ifd, exec)) { 557 result = execute("dhcpcd -k %iface%", ifd, exec);
575 return(0);
576 }
577 }
578 if (!execute("ifconfig %iface% down", ifd, exec)) {
579 return(0);
580 } 558 }
581 return(1); 559 return (result || execute("ifconfig %iface% down", ifd, exec));
582} 560}
583 561
584static int bootp_up(interface_defn_t *ifd, execfn *exec) 562static int bootp_up(struct interface_defn_t *ifd, execfn *exec)
585{ 563{
586 if (!execute("bootpc [[--bootfile %bootfile%]] --dev %iface% [[--server %server%]] [[--hwaddr %hwaddr%]] --returniffail --serverbcast", ifd, exec)) { 564 return( execute("bootpc [[--bootfile %bootfile%]] --dev %iface% "
587 return 0; 565 "[[--server %server%]] [[--hwaddr %hwaddr%]] "
588 } 566 "--returniffail --serverbcast", ifd, exec));
589 return 1;
590} 567}
591 568
592static int bootp_down(interface_defn_t *ifd, execfn *exec) 569static int bootp_down(struct interface_defn_t *ifd, execfn *exec)
593{ 570{
594 if (!execute("ifconfig down %iface%", ifd, exec)) { 571 return( execute("ifconfig down %iface%", ifd, exec));
595 return 0;
596 }
597 return 1;
598} 572}
599 573
600static int ppp_up(interface_defn_t *ifd, execfn *exec) 574static int ppp_up(struct interface_defn_t *ifd, execfn *exec)
601{ 575{
602 if (!execute("pon [[%provider%]]", ifd, exec)) { 576 return( execute("pon [[%provider%]]", ifd, exec));
603 return 0;
604 }
605 return 1;
606} 577}
607 578
608static int ppp_down(interface_defn_t *ifd, execfn *exec) 579static int ppp_down(struct interface_defn_t *ifd, execfn *exec)
609{ 580{
610 if (!execute("poff [[%provider%]]", ifd, exec)) { 581 return( execute("poff [[%provider%]]", ifd, exec));
611 return 0;
612 }
613 return 1;
614} 582}
615 583
616static int wvdial_up(interface_defn_t *ifd, execfn *exec) 584static int wvdial_up(struct interface_defn_t *ifd, execfn *exec)
617{ 585{
618 if (!execute("/sbin/start-stop-daemon --start -x /usr/bin/wvdial -p /var/run/wvdial.%iface% -b -m -- [[ %provider% ]]", ifd, exec)) { 586 return( execute("/sbin/start-stop-daemon --start -x /usr/bin/wvdial "
619 return 0; 587 "-p /var/run/wvdial.%iface% -b -m -- [[ %provider% ]]", ifd, exec));
620 }
621 return 1;
622} 588}
623 589
624static int wvdial_down(interface_defn_t *ifd, execfn *exec) 590static int wvdial_down(struct interface_defn_t *ifd, execfn *exec)
625{ 591{
626 if (!execute ("/sbin/start-stop-daemon --stop -x /usr/bin/wvdial -p /var/run/wvdial.%iface% -s 2", ifd, exec)) { 592 return( execute("/sbin/start-stop-daemon --stop -x /usr/bin/wvdial "
627 return 0; 593 "-p /var/run/wvdial.%iface% -s 2", ifd, exec));
628 }
629 return 1;
630} 594}
631 595
632static method_t methods[] = { 596static struct method_t methods[] =
597{
633 { "wvdial", wvdial_up, wvdial_down, }, 598 { "wvdial", wvdial_up, wvdial_down, },
634 { "ppp", ppp_up, ppp_down, }, 599 { "ppp", ppp_up, ppp_down, },
635 { "static", static_up, static_down, }, 600 { "static", static_up, static_down, },
@@ -638,9 +603,10 @@ static method_t methods[] = {
638 { "loopback", loopback_up, loopback_down, }, 603 { "loopback", loopback_up, loopback_down, },
639}; 604};
640 605
641address_family_t addr_inet = { 606struct address_family_t addr_inet =
607{
642 "inet", 608 "inet",
643 sizeof(methods) / sizeof(method_t), 609 sizeof(methods) / sizeof(struct method_t),
644 methods 610 methods
645}; 611};
646 612
@@ -670,7 +636,7 @@ static char *next_word(char **buf)
670 return word; 636 return word;
671} 637}
672 638
673static address_family_t *get_address_family(address_family_t *af[], char *name) 639static struct address_family_t *get_address_family(struct address_family_t *af[], char *name)
674{ 640{
675 int i; 641 int i;
676 642
@@ -682,7 +648,7 @@ static address_family_t *get_address_family(address_family_t *af[], char *name)
682 return NULL; 648 return NULL;
683} 649}
684 650
685static method_t *get_method(address_family_t *af, char *name) 651static struct method_t *get_method(struct address_family_t *af, char *name)
686{ 652{
687 int i; 653 int i;
688 654
@@ -694,7 +660,7 @@ static method_t *get_method(address_family_t *af, char *name)
694 return(NULL); 660 return(NULL);
695} 661}
696 662
697static int duplicate_if(interface_defn_t *ifa, interface_defn_t *ifb) 663static int duplicate_if(struct interface_defn_t *ifa, struct interface_defn_t *ifb)
698{ 664{
699 if (strcmp(ifa->iface, ifb->iface) != 0) { 665 if (strcmp(ifa->iface, ifb->iface) != 0) {
700 return(0); 666 return(0);
@@ -716,27 +682,27 @@ static const llist_t *find_list_string(const llist_t *list, const char *string)
716 return(NULL); 682 return(NULL);
717} 683}
718 684
719static interfaces_file_t *read_interfaces(char *filename) 685static struct interfaces_file_t *read_interfaces(char *filename)
720{ 686{
721#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING 687#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING
722 mapping_defn_t *currmap = NULL; 688 struct mapping_defn_t *currmap = NULL;
723#endif 689#endif
724 interface_defn_t *currif = NULL; 690 struct interface_defn_t *currif = NULL;
725 interfaces_file_t *defn; 691 struct interfaces_file_t *defn;
726 FILE *f; 692 FILE *f;
727 char *firstword; 693 char *firstword;
728 char *buf; 694 char *buf;
729 695
730 enum { NONE, IFACE, MAPPING } currently_processing = NONE; 696 enum { NONE, IFACE, MAPPING } currently_processing = NONE;
731 697
732 defn = xmalloc(sizeof(interfaces_file_t)); 698 defn = xmalloc(sizeof(struct interfaces_file_t));
733 defn->autointerfaces = NULL; 699 defn->autointerfaces = NULL;
734 defn->mappings = NULL; 700 defn->mappings = NULL;
735 defn->ifaces = NULL; 701 defn->ifaces = NULL;
736 702
737 f = bb_xfopen(filename, "r"); 703 f = bb_xfopen(filename, "r");
738 704
739 while ((buf = bb_get_line_from_file(f)) != NULL) { 705 while ((buf = bb_get_chomped_line_from_file(f)) != NULL) {
740 char *buf_ptr = buf; 706 char *buf_ptr = buf;
741 707
742 /* Ignore comments */ 708 /* Ignore comments */
@@ -751,7 +717,7 @@ static interfaces_file_t *read_interfaces(char *filename)
751 717
752 if (strcmp(firstword, "mapping") == 0) { 718 if (strcmp(firstword, "mapping") == 0) {
753#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING 719#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING
754 currmap = xmalloc(sizeof(mapping_defn_t)); 720 currmap = xmalloc(sizeof(struct mapping_defn_t));
755 currmap->max_matches = 0; 721 currmap->max_matches = 0;
756 currmap->n_matches = 0; 722 currmap->n_matches = 0;
757 currmap->match = NULL; 723 currmap->match = NULL;
@@ -769,13 +735,14 @@ static interfaces_file_t *read_interfaces(char *filename)
769 currmap->mapping = NULL; 735 currmap->mapping = NULL;
770 currmap->script = NULL; 736 currmap->script = NULL;
771 { 737 {
772 mapping_defn_t **where = &defn->mappings; 738 struct mapping_defn_t **where = &defn->mappings;
773 while (*where != NULL) { 739 while (*where != NULL) {
774 where = &(*where)->next; 740 where = &(*where)->next;
775 } 741 }
776 *where = currmap; 742 *where = currmap;
777 currmap->next = NULL; 743 currmap->next = NULL;
778 } 744 }
745 debug_noise("Added mapping\n");
779#endif 746#endif
780 currently_processing = MAPPING; 747 currently_processing = MAPPING;
781 } else if (strcmp(firstword, "iface") == 0) { 748 } else if (strcmp(firstword, "iface") == 0) {
@@ -783,7 +750,7 @@ static interfaces_file_t *read_interfaces(char *filename)
783 char *iface_name; 750 char *iface_name;
784 char *address_family_name; 751 char *address_family_name;
785 char *method_name; 752 char *method_name;
786 address_family_t *addr_fams[] = { 753 struct address_family_t *addr_fams[] = {
787#ifdef CONFIG_FEATURE_IFUPDOWN_IPV4 754#ifdef CONFIG_FEATURE_IFUPDOWN_IPV4
788 &addr_inet, 755 &addr_inet,
789#endif 756#endif
@@ -796,7 +763,7 @@ static interfaces_file_t *read_interfaces(char *filename)
796 NULL 763 NULL
797 }; 764 };
798 765
799 currif = xmalloc(sizeof(interface_defn_t)); 766 currif = xmalloc(sizeof(struct interface_defn_t));
800 iface_name = next_word(&buf_ptr); 767 iface_name = next_word(&buf_ptr);
801 address_family_name = next_word(&buf_ptr); 768 address_family_name = next_word(&buf_ptr);
802 method_name = next_word(&buf_ptr); 769 method_name = next_word(&buf_ptr);
@@ -830,21 +797,22 @@ static interfaces_file_t *read_interfaces(char *filename)
830 currif->n_options = 0; 797 currif->n_options = 0;
831 currif->option = NULL; 798 currif->option = NULL;
832 799
833
834 { 800 {
835 interface_defn_t **where = &defn->ifaces; 801 struct interface_defn_t *tmp;
836 802 llist_t *iface_list;
837 while (*where != NULL) { 803 iface_list = defn->ifaces;
838 if (duplicate_if(*where, currif)) { 804 while (iface_list) {
839 bb_error_msg("duplicate interface \"%s\"", buf); 805 tmp = (struct interface_defn_t *) iface_list->data;
806 if (duplicate_if(tmp, currif)) {
807 bb_error_msg("duplicate interface \"%s\"", tmp->iface);
840 return NULL; 808 return NULL;
841 } 809 }
842 where = &(*where)->next; 810 iface_list = iface_list->link;
843 } 811 }
844 812
845 *where = currif; 813 defn->ifaces = llist_add_to_end(defn->ifaces, (char*)currif);
846 currif->next = NULL;
847 } 814 }
815 debug_noise("iface %s %s %s\n", currif->iface, address_family_name, method_name);
848 } 816 }
849 currently_processing = IFACE; 817 currently_processing = IFACE;
850 } else if (strcmp(firstword, "auto") == 0) { 818 } else if (strcmp(firstword, "auto") == 0) {
@@ -856,77 +824,80 @@ static interfaces_file_t *read_interfaces(char *filename)
856 } 824 }
857 825
858 /* Add the interface to the list */ 826 /* Add the interface to the list */
859 defn->autointerfaces = llist_add_to(defn->autointerfaces, strdup(firstword)); 827 defn->autointerfaces = llist_add_to_end(defn->autointerfaces, strdup(firstword));
828 debug_noise("\nauto %s\n", firstword);
860 } 829 }
861 currently_processing = NONE; 830 currently_processing = NONE;
862 } else { 831 } else {
863 switch (currently_processing) { 832 switch (currently_processing) {
864 case IFACE: 833 case IFACE:
865 { 834 {
866 int i; 835 int i;
867
868 if (bb_strlen(buf_ptr) == 0) {
869 bb_error_msg("option with empty value \"%s\"", buf);
870 return NULL;
871 }
872 836
873 if (strcmp(firstword, "up") != 0 837 if (bb_strlen(buf_ptr) == 0) {
874 && strcmp(firstword, "down") != 0 838 bb_error_msg("option with empty value \"%s\"", buf);
875 && strcmp(firstword, "pre-up") != 0
876 && strcmp(firstword, "post-down") != 0) {
877 for (i = 0; i < currif->n_options; i++) {
878 if (strcmp(currif->option[i].name, firstword) == 0) {
879 bb_error_msg("duplicate option \"%s\"", buf);
880 return NULL; 839 return NULL;
881 } 840 }
841
842 if (strcmp(firstword, "up") != 0
843 && strcmp(firstword, "down") != 0
844 && strcmp(firstword, "pre-up") != 0
845 && strcmp(firstword, "post-down") != 0) {
846 for (i = 0; i < currif->n_options; i++) {
847 if (strcmp(currif->option[i].name, firstword) == 0) {
848 bb_error_msg("duplicate option \"%s\"", buf);
849 return NULL;
850 }
851 }
852 }
882 } 853 }
883 } 854 if (currif->n_options >= currif->max_options) {
884 } 855 struct variable_t *opt;
885 if (currif->n_options >= currif->max_options) {
886 variable_t *opt;
887 856
888 currif->max_options = currif->max_options + 10; 857 currif->max_options = currif->max_options + 10;
889 opt = xrealloc(currif->option, sizeof(*opt) * currif->max_options); 858 opt = xrealloc(currif->option, sizeof(*opt) * currif->max_options);
890 currif->option = opt; 859 currif->option = opt;
891 } 860 }
892 currif->option[currif->n_options].name = bb_xstrdup(firstword); 861 currif->option[currif->n_options].name = bb_xstrdup(firstword);
893 currif->option[currif->n_options].value = bb_xstrdup(next_word(&buf_ptr)); 862 currif->option[currif->n_options].value = bb_xstrdup(buf_ptr);
894 if (!currif->option[currif->n_options].name) { 863 if (!currif->option[currif->n_options].name) {
895 perror(filename); 864 perror(filename);
896 return NULL; 865 return NULL;
897 } 866 }
898 if (!currif->option[currif->n_options].value) { 867 if (!currif->option[currif->n_options].value) {
899 perror(filename); 868 perror(filename);
900 return NULL;
901 }
902 currif->n_options++;
903 break;
904 case MAPPING:
905#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING
906 if (strcmp(firstword, "script") == 0) {
907 if (currmap->script != NULL) {
908 bb_error_msg("duplicate script in mapping \"%s\"", buf);
909 return NULL; 869 return NULL;
910 } else {
911 currmap->script = bb_xstrdup(next_word(&buf_ptr));
912 } 870 }
913 } else if (strcmp(firstword, "map") == 0) { 871 debug_noise("\t%s=%s\n", currif->option[currif->n_options].name,
914 if (currmap->max_mappings == currmap->n_mappings) { 872 currif->option[currif->n_options].value);
915 currmap->max_mappings = currmap->max_mappings * 2 + 1; 873 currif->n_options++;
916 currmap->mapping = xrealloc(currmap->mapping, sizeof(char *) * currmap->max_mappings); 874 break;
875 case MAPPING:
876#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING
877 if (strcmp(firstword, "script") == 0) {
878 if (currmap->script != NULL) {
879 bb_error_msg("duplicate script in mapping \"%s\"", buf);
880 return NULL;
881 } else {
882 currmap->script = bb_xstrdup(next_word(&buf_ptr));
883 }
884 } else if (strcmp(firstword, "map") == 0) {
885 if (currmap->max_mappings == currmap->n_mappings) {
886 currmap->max_mappings = currmap->max_mappings * 2 + 1;
887 currmap->mapping = xrealloc(currmap->mapping, sizeof(char *) * currmap->max_mappings);
888 }
889 currmap->mapping[currmap->n_mappings] = bb_xstrdup(next_word(&buf_ptr));
890 currmap->n_mappings++;
891 } else {
892 bb_error_msg("misplaced option \"%s\"", buf);
893 return NULL;
917 } 894 }
918 currmap->mapping[currmap->n_mappings] = bb_xstrdup(next_word(&buf_ptr)); 895#endif
919 currmap->n_mappings++; 896 break;
920 } else { 897 case NONE:
898 default:
921 bb_error_msg("misplaced option \"%s\"", buf); 899 bb_error_msg("misplaced option \"%s\"", buf);
922 return NULL; 900 return NULL;
923 }
924#endif
925 break;
926 case NONE:
927 default:
928 bb_error_msg("misplaced option \"%s\"", buf);
929 return NULL;
930 } 901 }
931 } 902 }
932 free(buf); 903 free(buf);
@@ -965,7 +936,7 @@ static char *setlocalenv(char *format, char *name, char *value)
965 return result; 936 return result;
966} 937}
967 938
968static void set_environ(interface_defn_t *iface, char *mode) 939static void set_environ(struct interface_defn_t *iface, char *mode)
969{ 940{
970 char **environend; 941 char **environend;
971 int i; 942 int i;
@@ -986,9 +957,9 @@ static void set_environ(interface_defn_t *iface, char *mode)
986 957
987 for (i = 0; i < iface->n_options; i++) { 958 for (i = 0; i < iface->n_options; i++) {
988 if (strcmp(iface->option[i].name, "up") == 0 959 if (strcmp(iface->option[i].name, "up") == 0
989 || strcmp(iface->option[i].name, "down") == 0 960 || strcmp(iface->option[i].name, "down") == 0
990 || strcmp(iface->option[i].name, "pre-up") == 0 961 || strcmp(iface->option[i].name, "pre-up") == 0
991 || strcmp(iface->option[i].name, "post-down") == 0) { 962 || strcmp(iface->option[i].name, "post-down") == 0) {
992 continue; 963 continue;
993 } 964 }
994 *(environend++) = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value); 965 *(environend++) = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value);
@@ -1010,7 +981,7 @@ static void set_environ(interface_defn_t *iface, char *mode)
1010static int doit(char *str) 981static int doit(char *str)
1011{ 982{
1012 if (verbose || no_act) { 983 if (verbose || no_act) {
1013 bb_error_msg("%s", str); 984 printf("%s\n", str);
1014 } 985 }
1015 if (!no_act) { 986 if (!no_act) {
1016 pid_t child; 987 pid_t child;
@@ -1018,11 +989,11 @@ static int doit(char *str)
1018 989
1019 fflush(NULL); 990 fflush(NULL);
1020 switch (child = fork()) { 991 switch (child = fork()) {
1021 case -1: /* failure */ 992 case -1: /* failure */
1022 return 0; 993 return 0;
1023 case 0: /* child */ 994 case 0: /* child */
1024 execle("/bin/sh", "/bin/sh", "-c", str, NULL, environ); 995 execle("/bin/sh", "/bin/sh", "-c", str, NULL, environ);
1025 exit(127); 996 exit(127);
1026 } 997 }
1027 waitpid(child, &status, 0); 998 waitpid(child, &status, 0);
1028 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 999 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
@@ -1032,7 +1003,7 @@ static int doit(char *str)
1032 return (1); 1003 return (1);
1033} 1004}
1034 1005
1035static int execute_all(interface_defn_t *ifd, execfn *exec, const char *opt) 1006static int execute_all(struct interface_defn_t *ifd, execfn *exec, const char *opt)
1036{ 1007{
1037 int i; 1008 int i;
1038 char *buf; 1009 char *buf;
@@ -1052,35 +1023,30 @@ static int execute_all(interface_defn_t *ifd, execfn *exec, const char *opt)
1052 return (1); 1023 return (1);
1053} 1024}
1054 1025
1055static int iface_up(interface_defn_t *iface) 1026static int check(char *str) {
1027 return str != NULL;
1028}
1029
1030static int iface_up(struct interface_defn_t *iface)
1056{ 1031{
1032 int result;
1033 if (!iface->method->up(iface,check)) return -1;
1057 set_environ(iface, "start"); 1034 set_environ(iface, "start");
1058 if (!execute_all(iface, doit, "pre-up")) { 1035 result = execute_all(iface, doit, "pre-up");
1059 return (0); 1036 result += iface->method->up(iface, doit);
1060 } 1037 result += execute_all(iface, doit, "up");
1061 if (!iface->method->up(iface, doit)) { 1038 return(result);
1062 return (0);
1063 }
1064 if (!execute_all(iface, doit, "up")) {
1065 return (0);
1066 }
1067
1068 return (1);
1069} 1039}
1070 1040
1071static int iface_down(interface_defn_t *iface) 1041static int iface_down(struct interface_defn_t *iface)
1072{ 1042{
1043 int result;
1044 if (!iface->method->down(iface,check)) return -1;
1073 set_environ(iface, "stop"); 1045 set_environ(iface, "stop");
1074 if (!execute_all(iface, doit, "down")) { 1046 result = execute_all(iface, doit, "down");
1075 return (0); 1047 result += iface->method->down(iface, doit);
1076 } 1048 result += execute_all(iface, doit, "post-down");
1077 if (!iface->method->down(iface, doit)) { 1049 return(result);
1078 return (0);
1079 }
1080 if (!execute_all(iface, doit, "post-down")) {
1081 return (0);
1082 }
1083 return (1);
1084} 1050}
1085 1051
1086#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING 1052#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING
@@ -1112,32 +1078,32 @@ static int popen2(FILE **in, FILE **out, char *command, ...)
1112 1078
1113 fflush(NULL); 1079 fflush(NULL);
1114 switch (pid = fork()) { 1080 switch (pid = fork()) {
1115 case -1: /* failure */ 1081 case -1: /* failure */
1116 close(infd[0]); 1082 close(infd[0]);
1117 close(infd[1]); 1083 close(infd[1]);
1118 close(outfd[0]); 1084 close(outfd[0]);
1119 close(outfd[1]); 1085 close(outfd[1]);
1120 return 0; 1086 return 0;
1121 case 0: /* child */ 1087 case 0: /* child */
1122 dup2(infd[0], 0); 1088 dup2(infd[0], 0);
1123 dup2(outfd[1], 1); 1089 dup2(outfd[1], 1);
1124 close(infd[0]); 1090 close(infd[0]);
1125 close(infd[1]); 1091 close(infd[1]);
1126 close(outfd[0]); 1092 close(outfd[0]);
1127 close(outfd[1]); 1093 close(outfd[1]);
1128 execvp(command, argv); 1094 execvp(command, argv);
1129 exit(127); 1095 exit(127);
1130 default: /* parent */ 1096 default: /* parent */
1131 *in = fdopen(infd[1], "w"); 1097 *in = fdopen(infd[1], "w");
1132 *out = fdopen(outfd[0], "r"); 1098 *out = fdopen(outfd[0], "r");
1133 close(infd[0]); 1099 close(infd[0]);
1134 close(outfd[1]); 1100 close(outfd[1]);
1135 return pid; 1101 return pid;
1136 } 1102 }
1137 /* unreached */ 1103 /* unreached */
1138} 1104}
1139 1105
1140static int run_mapping(char *physical, char *logical, int len, mapping_defn_t * map) 1106static int run_mapping(char *physical, char *logical, int len, struct mapping_defn_t * map)
1141{ 1107{
1142 FILE *in, *out; 1108 FILE *in, *out;
1143 int i, status; 1109 int i, status;
@@ -1174,7 +1140,7 @@ static llist_t *find_iface_state(llist_t *state_list, const char *iface)
1174 1140
1175 while (search) { 1141 while (search) {
1176 if ((strncmp(search->data, iface, iface_len) == 0) && 1142 if ((strncmp(search->data, iface, iface_len) == 0) &&
1177 (search->data[iface_len] == '=')) { 1143 (search->data[iface_len] == '=')) {
1178 return(search); 1144 return(search);
1179 } 1145 }
1180 search = search->link; 1146 search = search->link;
@@ -1184,8 +1150,8 @@ static llist_t *find_iface_state(llist_t *state_list, const char *iface)
1184 1150
1185extern int ifupdown_main(int argc, char **argv) 1151extern int ifupdown_main(int argc, char **argv)
1186{ 1152{
1187 int (*cmds) (interface_defn_t *) = NULL; 1153 int (*cmds) (struct interface_defn_t *) = NULL;
1188 interfaces_file_t *defn; 1154 struct interfaces_file_t *defn;
1189 FILE *state_fp = NULL; 1155 FILE *state_fp = NULL;
1190 llist_t *state_list = NULL; 1156 llist_t *state_list = NULL;
1191 llist_t *target_list = NULL; 1157 llist_t *target_list = NULL;
@@ -1208,36 +1174,37 @@ extern int ifupdown_main(int argc, char **argv)
1208 } 1174 }
1209 1175
1210#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING 1176#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING
1211 while ((i = getopt(argc, argv, "i:hvnamf")) != -1) { 1177 while ((i = getopt(argc, argv, "i:hvnamf")) != -1)
1212#else 1178#else
1213 while ((i = getopt(argc, argv, "i:hvnaf")) != -1) { 1179 while ((i = getopt(argc, argv, "i:hvnaf")) != -1)
1214#endif 1180#endif
1215 switch (i) { 1181 {
1216 case 'i': /* interfaces */ 1182 switch (i) {
1217 interfaces = bb_xstrdup(optarg); 1183 case 'i': /* interfaces */
1218 break; 1184 interfaces = bb_xstrdup(optarg);
1219 case 'v': /* verbose */ 1185 break;
1220 verbose = 1; 1186 case 'v': /* verbose */
1221 break; 1187 verbose = 1;
1222 case 'a': /* all */ 1188 break;
1223 do_all = 1; 1189 case 'a': /* all */
1224 break; 1190 do_all = 1;
1225 case 'n': /* no-act */ 1191 break;
1226 no_act = 1; 1192 case 'n': /* no-act */
1227 break; 1193 no_act = 1;
1194 break;
1228#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING 1195#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING
1229 case 'm': /* no-mappings */ 1196 case 'm': /* no-mappings */
1230 run_mappings = 0; 1197 run_mappings = 0;
1231 break; 1198 break;
1232#endif 1199#endif
1233 case 'f': /* force */ 1200 case 'f': /* force */
1234 force = 1; 1201 force = 1;
1235 break; 1202 break;
1236 default: 1203 default:
1237 bb_show_usage(); 1204 bb_show_usage();
1238 break; 1205 break;
1206 }
1239 } 1207 }
1240 }
1241 1208
1242 if (argc - optind > 0) { 1209 if (argc - optind > 0) {
1243 if (do_all) { 1210 if (do_all) {
@@ -1249,7 +1216,9 @@ extern int ifupdown_main(int argc, char **argv)
1249 } 1216 }
1250 } 1217 }
1251 1218
1219 debug_noise("reading %s file:\n", interfaces);
1252 defn = read_interfaces(interfaces); 1220 defn = read_interfaces(interfaces);
1221 debug_noise("\ndone reading %s\n\n", interfaces);
1253 1222
1254 if (no_act) { 1223 if (no_act) {
1255 state_fp = fopen(statefile, "r"); 1224 state_fp = fopen(statefile, "r");
@@ -1259,22 +1228,47 @@ extern int ifupdown_main(int argc, char **argv)
1259 if (do_all) { 1228 if (do_all) {
1260 if (cmds == iface_up) { 1229 if (cmds == iface_up) {
1261 target_list = defn->autointerfaces; 1230 target_list = defn->autointerfaces;
1262 } else if (cmds == iface_down) { 1231 } else {
1232#if 0
1233 /* iface_down */
1234 llist_t *new_item;
1263 const llist_t *list = state_list; 1235 const llist_t *list = state_list;
1264 while (list) { 1236 while (list) {
1265 target_list = llist_add_to(target_list, strdup(list->data)); 1237 new_item = xmalloc(sizeof(llist_t));
1238 new_item->data = strdup(list->data);
1239 new_item->link = NULL;
1240 list = target_list;
1241 if (list == NULL)
1242 target_list = new_item;
1243 else {
1244 while (list->link) {
1245 list = list->link;
1246 }
1247 list = new_item;
1248 }
1266 list = list->link; 1249 list = list->link;
1267 } 1250 }
1268 target_list = defn->autointerfaces; 1251 target_list = defn->autointerfaces;
1269 } 1252#else
1253
1254 /* iface_down */
1255 const llist_t *list = state_list;
1256 while (list) {
1257 target_list = llist_add_to_end(target_list, strdup(list->data));
1258 list = list->link;
1259 }
1260 target_list = defn->autointerfaces;
1261#endif
1262 }
1270 } else { 1263 } else {
1271 target_list = llist_add_to(target_list, argv[optind]); 1264 target_list = llist_add_to_end(target_list, argv[optind]);
1272 } 1265 }
1273 1266
1274 1267
1275 /* Update the interfaces */ 1268 /* Update the interfaces */
1276 while (target_list) { 1269 while (target_list) {
1277 interface_defn_t *currif; 1270 llist_t *iface_list;
1271 struct interface_defn_t *currif;
1278 char *iface; 1272 char *iface;
1279 char *liface; 1273 char *liface;
1280 char *pch; 1274 char *pch;
@@ -1311,7 +1305,7 @@ extern int ifupdown_main(int argc, char **argv)
1311 1305
1312#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING 1306#ifdef CONFIG_FEATURE_IFUPDOWN_MAPPING
1313 if ((cmds == iface_up) && run_mappings) { 1307 if ((cmds == iface_up) && run_mappings) {
1314 mapping_defn_t *currmap; 1308 struct mapping_defn_t *currmap;
1315 1309
1316 for (currmap = defn->mappings; currmap; currmap = currmap->next) { 1310 for (currmap = defn->mappings; currmap; currmap = currmap->next) {
1317 1311
@@ -1319,7 +1313,7 @@ extern int ifupdown_main(int argc, char **argv)
1319 if (fnmatch(currmap->match[i], liface, 0) != 0) 1313 if (fnmatch(currmap->match[i], liface, 0) != 0)
1320 continue; 1314 continue;
1321 if (verbose) { 1315 if (verbose) {
1322 bb_error_msg("Running mapping script %s on %s", currmap->script, liface); 1316 printf("Running mapping script %s on %s\n", currmap->script, liface);
1323 } 1317 }
1324 run_mapping(iface, liface, sizeof(liface), currmap); 1318 run_mapping(iface, liface, sizeof(liface), currmap);
1325 break; 1319 break;
@@ -1328,30 +1322,34 @@ extern int ifupdown_main(int argc, char **argv)
1328 } 1322 }
1329#endif 1323#endif
1330 1324
1331 for (currif = defn->ifaces; currif; currif = currif->next) { 1325
1326 iface_list = defn->ifaces;
1327 while (iface_list) {
1328 currif = (struct interface_defn_t *) iface_list->data;
1332 if (strcmp(liface, currif->iface) == 0) { 1329 if (strcmp(liface, currif->iface) == 0) {
1333 char *oldiface = currif->iface; 1330 char *oldiface = currif->iface;
1334 1331
1335 okay = 1; 1332 okay = 1;
1336 currif->iface = iface; 1333 currif->iface = iface;
1337 1334
1338 if (verbose) { 1335 debug_noise("\nConfiguring interface %s (%s)\n", liface, currif->address_family->name);
1339 bb_error_msg("Configuring interface %s=%s (%s)", iface, liface, currif->address_family->name);
1340 }
1341 1336
1342 /* Call the cmds function pointer, does either iface_up() or iface_down() */ 1337 /* Call the cmds function pointer, does either iface_up() or iface_down() */
1343 if (cmds(currif) == -1) { 1338 if (cmds(currif) == -1) {
1344 printf 1339 bb_error_msg("Don't seem to be have all the variables for %s/%s.",
1345 ("Don't seem to be have all the variables for %s/%s.\n", 1340 liface, currif->address_family->name);
1346 liface, currif->address_family->name);
1347 } 1341 }
1348 1342
1349 currif->iface = oldiface; 1343 currif->iface = oldiface;
1350 } 1344 }
1345 iface_list = iface_list->link;
1346 }
1347 if (verbose) {
1348 printf("\n");
1351 } 1349 }
1352 1350
1353 if (!okay && !force) { 1351 if (!okay && !force) {
1354 bb_error_msg("Ignoring unknown interface %s=%s.", iface, liface); 1352 bb_error_msg("Ignoring unknown interface %s", liface);
1355 } else { 1353 } else {
1356 llist_t *iface_state = find_iface_state(state_list, iface); 1354 llist_t *iface_state = find_iface_state(state_list, iface);
1357 1355
@@ -1359,7 +1357,7 @@ extern int ifupdown_main(int argc, char **argv)
1359 char *newiface = xmalloc(bb_strlen(iface) + 1 + bb_strlen(liface) + 1); 1357 char *newiface = xmalloc(bb_strlen(iface) + 1 + bb_strlen(liface) + 1);
1360 sprintf(newiface, "%s=%s", iface, liface); 1358 sprintf(newiface, "%s=%s", iface, liface);
1361 if (iface_state == NULL) { 1359 if (iface_state == NULL) {
1362 state_list = llist_add_to(state_list, newiface); 1360 state_list = llist_add_to_end(state_list, newiface);
1363 } else { 1361 } else {
1364 free(iface_state->data); 1362 free(iface_state->data);
1365 iface_state->data = newiface; 1363 iface_state->data = newiface;