diff options
author | Eric Andersen <andersen@codepoet.org> | 2003-04-02 10:13:26 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2003-04-02 10:13:26 +0000 |
commit | 8320b425a3016e0610dee2970b24a0ebcad0d943 (patch) | |
tree | 4c0a605806b3a6ca61986084d7b18edce5c6ba80 /networking/ifupdown.c | |
parent | a71c7047cfd1cf79ed0e8e8a7f0cde2019f79ae4 (diff) | |
download | busybox-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.c | 974 |
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 | ||
50 | typedef 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 */ | ||
60 | struct interface_defn_t; | ||
51 | 61 | ||
52 | typedef int (execfn)(char *command); | 62 | typedef int (execfn)(char *command); |
53 | typedef int (command_set)(interface_defn_t *ifd, execfn *e); | 63 | typedef int (command_set)(struct interface_defn_t *ifd, execfn *e); |
64 | |||
65 | extern 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 | ||
55 | typedef struct method_s { | 85 | return(list_head); |
86 | } | ||
87 | |||
88 | struct 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 | ||
61 | typedef struct address_family_s { | 95 | struct 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 | ||
67 | typedef struct mapping_defn_s { | 102 | struct 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 | ||
81 | typedef struct variable_s { | 117 | struct variable_t |
118 | { | ||
82 | char *name; | 119 | char *name; |
83 | char *value; | 120 | char *value; |
84 | } variable_t; | 121 | }; |
85 | 122 | ||
86 | struct interface_defn_s { | 123 | struct 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 | ||
100 | typedef struct interfaces_file_s { | 139 | struct 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 | ||
106 | static char no_act = 0; | 146 | static char no_act = 0; |
107 | static char verbose = 0; | 147 | static char verbose = 0; |
108 | static char **environ = NULL; | 148 | static char **environ = NULL; |
109 | 149 | ||
110 | #ifdef CONFIG_FEATURE_IFUPDOWN_IP | 150 | #ifdef CONFIG_FEATURE_IFUPDOWN_IP |
151 | |||
152 | static 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 | |||
111 | static int count_netmask_bits(char *dotted_quad) | 160 | static 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 | ||
165 | static char *get_var(char *id, size_t idlen, interface_defn_t *ifd) | 202 | static 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 | ||
182 | static char *parse(char *command, interface_defn_t *ifd) | 229 | static 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 | ||
288 | static int execute(char *command, interface_defn_t *ifd, execfn *exec) | 335 | static 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 |
305 | static int static_up_ipx(interface_defn_t *ifd, execfn *exec) | 351 | static 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 | ||
313 | static int static_down_ipx(interface_defn_t *ifd, execfn *exec) | 356 | static 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 | ||
321 | static int dynamic_up(interface_defn_t *ifd, execfn *exec) | 361 | static 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 | ||
329 | static int dynamic_down(interface_defn_t *ifd, execfn *exec) | 366 | static 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 | ||
337 | static method_t methods_ipx[] = { | 371 | static 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 | ||
342 | address_family_t addr_ipx = { | 376 | struct 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 |
350 | static int loopback_up6(interface_defn_t *ifd, execfn *exec) | 384 | static 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 | ||
364 | static int loopback_down6(interface_defn_t *ifd, execfn *exec) | 396 | static 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 | ||
376 | static int static_up6(interface_defn_t *ifd, execfn *exec) | 405 | static 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 | ||
399 | static int static_down6(interface_defn_t *ifd, execfn *exec) | 420 | static 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 |
413 | static int v4tunnel_up(interface_defn_t *ifd, execfn *exec) | 430 | static 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 | ||
430 | static int v4tunnel_down(interface_defn_t * ifd, execfn * exec) | 441 | static 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 | ||
439 | static method_t methods6[] = { | 447 | static 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 | ||
447 | address_family_t addr_inet6 = { | 455 | struct 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 |
455 | static int loopback_up(interface_defn_t *ifd, execfn *exec) | 463 | static 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 | ||
470 | static int loopback_down(interface_defn_t *ifd, execfn *exec) | 475 | static 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 | ||
485 | static int static_up(interface_defn_t *ifd, execfn *exec) | 487 | static 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 | ||
506 | static int static_down(interface_defn_t *ifd, execfn *exec) | 505 | static 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 | ||
526 | static int execable(char *program) | 518 | static int execable(char *program) |
@@ -534,102 +526,75 @@ static int execable(char *program) | |||
534 | return(0); | 526 | return(0); |
535 | } | 527 | } |
536 | 528 | ||
537 | static int dhcp_up(interface_defn_t *ifd, execfn *exec) | 529 | static 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 | ||
559 | static int dhcp_down(interface_defn_t *ifd, execfn *exec) | 545 | static 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 | ||
584 | static int bootp_up(interface_defn_t *ifd, execfn *exec) | 562 | static 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 | ||
592 | static int bootp_down(interface_defn_t *ifd, execfn *exec) | 569 | static 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 | ||
600 | static int ppp_up(interface_defn_t *ifd, execfn *exec) | 574 | static 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 | ||
608 | static int ppp_down(interface_defn_t *ifd, execfn *exec) | 579 | static 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 | ||
616 | static int wvdial_up(interface_defn_t *ifd, execfn *exec) | 584 | static 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 | ||
624 | static int wvdial_down(interface_defn_t *ifd, execfn *exec) | 590 | static 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 | ||
632 | static method_t methods[] = { | 596 | static 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 | ||
641 | address_family_t addr_inet = { | 606 | struct 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 | ||
673 | static address_family_t *get_address_family(address_family_t *af[], char *name) | 639 | static 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 | ||
685 | static method_t *get_method(address_family_t *af, char *name) | 651 | static 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 | ||
697 | static int duplicate_if(interface_defn_t *ifa, interface_defn_t *ifb) | 663 | static 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 | ||
719 | static interfaces_file_t *read_interfaces(char *filename) | 685 | static 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 | ||
968 | static void set_environ(interface_defn_t *iface, char *mode) | 939 | static 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) | |||
1010 | static int doit(char *str) | 981 | static 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 | ||
1035 | static int execute_all(interface_defn_t *ifd, execfn *exec, const char *opt) | 1006 | static 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 | ||
1055 | static int iface_up(interface_defn_t *iface) | 1026 | static int check(char *str) { |
1027 | return str != NULL; | ||
1028 | } | ||
1029 | |||
1030 | static 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 | ||
1071 | static int iface_down(interface_defn_t *iface) | 1041 | static 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 | ||
1140 | static int run_mapping(char *physical, char *logical, int len, mapping_defn_t * map) | 1106 | static 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 | ||
1185 | extern int ifupdown_main(int argc, char **argv) | 1151 | extern 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; |