diff options
Diffstat (limited to 'networking/zcip.c')
-rw-r--r-- | networking/zcip.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/networking/zcip.c b/networking/zcip.c index 45d1f7c1c..635d660b3 100644 --- a/networking/zcip.c +++ b/networking/zcip.c | |||
@@ -30,6 +30,7 @@ | |||
30 | //usage: "\n -f Run in foreground" | 30 | //usage: "\n -f Run in foreground" |
31 | //usage: "\n -q Quit after obtaining address" | 31 | //usage: "\n -q Quit after obtaining address" |
32 | //usage: "\n -r 169.254.x.x Request this address first" | 32 | //usage: "\n -r 169.254.x.x Request this address first" |
33 | //usage: "\n -l x.x.0.0 Use this range instead of 169.254" | ||
33 | //usage: "\n -v Verbose" | 34 | //usage: "\n -v Verbose" |
34 | //usage: "\n" | 35 | //usage: "\n" |
35 | //usage: "\nWith no -q, runs continuously monitoring for ARP conflicts," | 36 | //usage: "\nWith no -q, runs continuously monitoring for ARP conflicts," |
@@ -87,6 +88,7 @@ enum { | |||
87 | struct globals { | 88 | struct globals { |
88 | struct sockaddr saddr; | 89 | struct sockaddr saddr; |
89 | struct ether_addr eth_addr; | 90 | struct ether_addr eth_addr; |
91 | uint32_t localnet_ip; | ||
90 | } FIX_ALIASING; | 92 | } FIX_ALIASING; |
91 | #define G (*(struct globals*)&bb_common_bufsiz1) | 93 | #define G (*(struct globals*)&bb_common_bufsiz1) |
92 | #define saddr (G.saddr ) | 94 | #define saddr (G.saddr ) |
@@ -98,14 +100,14 @@ struct globals { | |||
98 | * Pick a random link local IP address on 169.254/16, except that | 100 | * Pick a random link local IP address on 169.254/16, except that |
99 | * the first and last 256 addresses are reserved. | 101 | * the first and last 256 addresses are reserved. |
100 | */ | 102 | */ |
101 | static uint32_t pick(void) | 103 | static uint32_t pick_nip(void) |
102 | { | 104 | { |
103 | unsigned tmp; | 105 | unsigned tmp; |
104 | 106 | ||
105 | do { | 107 | do { |
106 | tmp = rand() & IN_CLASSB_HOST; | 108 | tmp = rand() & IN_CLASSB_HOST; |
107 | } while (tmp > (IN_CLASSB_HOST - 0x0200)); | 109 | } while (tmp > (IN_CLASSB_HOST - 0x0200)); |
108 | return htonl((LINKLOCAL_ADDR + 0x0100) + tmp); | 110 | return htonl((G.localnet_ip + 0x0100) + tmp); |
109 | } | 111 | } |
110 | 112 | ||
111 | /** | 113 | /** |
@@ -197,6 +199,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
197 | { | 199 | { |
198 | int state; | 200 | int state; |
199 | char *r_opt; | 201 | char *r_opt; |
202 | const char *l_opt = "169.254.0.0"; | ||
200 | unsigned opts; | 203 | unsigned opts; |
201 | 204 | ||
202 | // ugly trick, but I want these zeroed in one go | 205 | // ugly trick, but I want these zeroed in one go |
@@ -231,7 +234,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
231 | // parse commandline: prog [options] ifname script | 234 | // parse commandline: prog [options] ifname script |
232 | // exactly 2 args; -v accumulates and implies -f | 235 | // exactly 2 args; -v accumulates and implies -f |
233 | opt_complementary = "=2:vv:vf"; | 236 | opt_complementary = "=2:vv:vf"; |
234 | opts = getopt32(argv, "fqr:v", &r_opt, &verbose); | 237 | opts = getopt32(argv, "fqr:l:v", &r_opt, &l_opt, &verbose); |
235 | #if !BB_MMU | 238 | #if !BB_MMU |
236 | // on NOMMU reexec early (or else we will rerun things twice) | 239 | // on NOMMU reexec early (or else we will rerun things twice) |
237 | if (!FOREGROUND) | 240 | if (!FOREGROUND) |
@@ -246,9 +249,18 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
246 | openlog(applet_name, 0, LOG_DAEMON); | 249 | openlog(applet_name, 0, LOG_DAEMON); |
247 | logmode |= LOGMODE_SYSLOG; | 250 | logmode |= LOGMODE_SYSLOG; |
248 | } | 251 | } |
252 | { // -l n.n.n.n | ||
253 | struct in_addr net; | ||
254 | if (inet_aton(l_opt, &net) == 0 | ||
255 | || (net.s_addr & htonl(IN_CLASSB_NET)) != net.s_addr | ||
256 | ) { | ||
257 | bb_error_msg_and_die("invalid network address"); | ||
258 | } | ||
259 | G.localnet_ip = ntohl(net.s_addr); | ||
260 | } | ||
249 | if (opts & 4) { // -r n.n.n.n | 261 | if (opts & 4) { // -r n.n.n.n |
250 | if (inet_aton(r_opt, &ip) == 0 | 262 | if (inet_aton(r_opt, &ip) == 0 |
251 | || (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR | 263 | || (ntohl(ip.s_addr) & IN_CLASSB_NET) != G.localnet_ip |
252 | ) { | 264 | ) { |
253 | bb_error_msg_and_die("invalid link address"); | 265 | bb_error_msg_and_die("invalid link address"); |
254 | } | 266 | } |
@@ -295,7 +307,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
295 | srand(t); | 307 | srand(t); |
296 | } | 308 | } |
297 | if (ip.s_addr == 0) | 309 | if (ip.s_addr == 0) |
298 | ip.s_addr = pick(); | 310 | ip.s_addr = pick_nip(); |
299 | 311 | ||
300 | // FIXME cases to handle: | 312 | // FIXME cases to handle: |
301 | // - zcip already running! | 313 | // - zcip already running! |
@@ -433,7 +445,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
433 | default: | 445 | default: |
434 | // Invalid, should never happen. Restart the whole protocol. | 446 | // Invalid, should never happen. Restart the whole protocol. |
435 | state = PROBE; | 447 | state = PROBE; |
436 | ip.s_addr = pick(); | 448 | ip.s_addr = pick_nip(); |
437 | timeout_ms = 0; | 449 | timeout_ms = 0; |
438 | nprobes = 0; | 450 | nprobes = 0; |
439 | nclaims = 0; | 451 | nclaims = 0; |
@@ -535,7 +547,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
535 | } | 547 | } |
536 | 548 | ||
537 | // restart the whole protocol | 549 | // restart the whole protocol |
538 | ip.s_addr = pick(); | 550 | ip.s_addr = pick_nip(); |
539 | timeout_ms = 0; | 551 | timeout_ms = 0; |
540 | nprobes = 0; | 552 | nprobes = 0; |
541 | nclaims = 0; | 553 | nclaims = 0; |
@@ -561,7 +573,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
561 | run(argv, "deconfig", &ip); | 573 | run(argv, "deconfig", &ip); |
562 | 574 | ||
563 | // restart the whole protocol | 575 | // restart the whole protocol |
564 | ip.s_addr = pick(); | 576 | ip.s_addr = pick_nip(); |
565 | timeout_ms = 0; | 577 | timeout_ms = 0; |
566 | nprobes = 0; | 578 | nprobes = 0; |
567 | nclaims = 0; | 579 | nclaims = 0; |
@@ -571,7 +583,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
571 | // Invalid, should never happen. Restart the whole protocol. | 583 | // Invalid, should never happen. Restart the whole protocol. |
572 | VDBG("invalid state -- starting over\n"); | 584 | VDBG("invalid state -- starting over\n"); |
573 | state = PROBE; | 585 | state = PROBE; |
574 | ip.s_addr = pick(); | 586 | ip.s_addr = pick_nip(); |
575 | timeout_ms = 0; | 587 | timeout_ms = 0; |
576 | nprobes = 0; | 588 | nprobes = 0; |
577 | nclaims = 0; | 589 | nclaims = 0; |