aboutsummaryrefslogtreecommitdiff
path: root/networking/zcip.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/zcip.c')
-rw-r--r--networking/zcip.c30
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 {
87struct globals { 88struct 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 */
101static uint32_t pick(void) 103static 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;