diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-25 12:40:56 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-25 12:40:56 +0000 |
commit | a09300a88c68f72bae2a4f25bb0f8620e560832c (patch) | |
tree | 0ab0ca379313c77979023f98470310e233f7bdd1 /networking/zcip.c | |
parent | 7c9d533a85a5c32478695e8e50fd9be23b11cfd4 (diff) | |
download | busybox-w32-a09300a88c68f72bae2a4f25bb0f8620e560832c.tar.gz busybox-w32-a09300a88c68f72bae2a4f25bb0f8620e560832c.tar.bz2 busybox-w32-a09300a88c68f72bae2a4f25bb0f8620e560832c.zip |
zcip: use low-order 4 bytes of MAC as random seed, not 4 high-order
arping: fix wrong roundtrip calculation
arping,zcip: cleanups and code shrink
run 389 402 +13
arp 195 188 -7
zcip_main 1524 1495 -29
arping_main 1874 1823 -51
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/3 up/down: 13/-87) Total: -74 bytes
text data bss dec hex filename
776587 929 9100 786616 c00b8 busybox_old
776499 929 9100 786528 c0060 busybox_unstripped
Diffstat (limited to 'networking/zcip.c')
-rw-r--r-- | networking/zcip.c | 153 |
1 files changed, 87 insertions, 66 deletions
diff --git a/networking/zcip.c b/networking/zcip.c index a16a6420c..129155fe5 100644 --- a/networking/zcip.c +++ b/networking/zcip.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #define MONOTONIC_US() ((unsigned)monotonic_us()) | 39 | #define MONOTONIC_US() ((unsigned)monotonic_us()) |
40 | 40 | ||
41 | struct arp_packet { | 41 | struct arp_packet { |
42 | struct ether_header hdr; | 42 | struct ether_header eth; |
43 | struct ether_arp arp; | 43 | struct ether_arp arp; |
44 | } ATTRIBUTE_PACKED; | 44 | } ATTRIBUTE_PACKED; |
45 | 45 | ||
@@ -69,8 +69,21 @@ enum { | |||
69 | DEFEND | 69 | DEFEND |
70 | }; | 70 | }; |
71 | 71 | ||
72 | #define VDBG(fmt,args...) \ | 72 | #define VDBG(...) do { } while (0) |
73 | do { } while (0) | 73 | |
74 | |||
75 | enum { | ||
76 | sock_fd = 3 | ||
77 | }; | ||
78 | |||
79 | struct globals { | ||
80 | char *intf; | ||
81 | struct sockaddr saddr; | ||
82 | }; | ||
83 | #define G (*(struct globals*)&bb_common_bufsiz1) | ||
84 | #define intf (G.intf ) | ||
85 | #define saddr (G.saddr) | ||
86 | |||
74 | 87 | ||
75 | /** | 88 | /** |
76 | * Pick a random link local IP address on 169.254/16, except that | 89 | * Pick a random link local IP address on 169.254/16, except that |
@@ -89,17 +102,17 @@ static void pick(struct in_addr *ip) | |||
89 | /** | 102 | /** |
90 | * Broadcast an ARP packet. | 103 | * Broadcast an ARP packet. |
91 | */ | 104 | */ |
92 | static void arp(int fd, struct sockaddr *saddr, int op, | 105 | static void arp(int op, |
93 | const struct ether_addr *source_addr, struct in_addr source_ip, | 106 | const struct ether_addr *source_eth, struct in_addr source_ip, |
94 | const struct ether_addr *target_addr, struct in_addr target_ip) | 107 | const struct ether_addr *target_eth, struct in_addr target_ip) |
95 | { | 108 | { |
96 | struct arp_packet p; | 109 | struct arp_packet p; |
97 | memset(&p, 0, sizeof(p)); | 110 | memset(&p, 0, sizeof(p)); |
98 | 111 | ||
99 | // ether header | 112 | // ether header |
100 | p.hdr.ether_type = htons(ETHERTYPE_ARP); | 113 | p.eth.ether_type = htons(ETHERTYPE_ARP); |
101 | memcpy(p.hdr.ether_shost, source_addr, ETH_ALEN); | 114 | memcpy(p.eth.ether_shost, source_eth, ETH_ALEN); |
102 | memset(p.hdr.ether_dhost, 0xff, ETH_ALEN); | 115 | memset(p.eth.ether_dhost, 0xff, ETH_ALEN); |
103 | 116 | ||
104 | // arp request | 117 | // arp request |
105 | p.arp.arp_hrd = htons(ARPHRD_ETHER); | 118 | p.arp.arp_hrd = htons(ARPHRD_ETHER); |
@@ -107,13 +120,13 @@ static void arp(int fd, struct sockaddr *saddr, int op, | |||
107 | p.arp.arp_hln = ETH_ALEN; | 120 | p.arp.arp_hln = ETH_ALEN; |
108 | p.arp.arp_pln = 4; | 121 | p.arp.arp_pln = 4; |
109 | p.arp.arp_op = htons(op); | 122 | p.arp.arp_op = htons(op); |
110 | memcpy(&p.arp.arp_sha, source_addr, ETH_ALEN); | 123 | memcpy(&p.arp.arp_sha, source_eth, ETH_ALEN); |
111 | memcpy(&p.arp.arp_spa, &source_ip, sizeof(p.arp.arp_spa)); | 124 | memcpy(&p.arp.arp_spa, &source_ip, sizeof(p.arp.arp_spa)); |
112 | memcpy(&p.arp.arp_tha, target_addr, ETH_ALEN); | 125 | memcpy(&p.arp.arp_tha, target_eth, ETH_ALEN); |
113 | memcpy(&p.arp.arp_tpa, &target_ip, sizeof(p.arp.arp_tpa)); | 126 | memcpy(&p.arp.arp_tpa, &target_ip, sizeof(p.arp.arp_tpa)); |
114 | 127 | ||
115 | // send it | 128 | // send it |
116 | xsendto(fd, &p, sizeof(p), saddr, sizeof(*saddr)); | 129 | xsendto(sock_fd, &p, sizeof(p), &saddr, sizeof(saddr)); |
117 | 130 | ||
118 | // Currently all callers ignore errors, that's why returns are | 131 | // Currently all callers ignore errors, that's why returns are |
119 | // commented out... | 132 | // commented out... |
@@ -123,21 +136,24 @@ static void arp(int fd, struct sockaddr *saddr, int op, | |||
123 | /** | 136 | /** |
124 | * Run a script. argv[2] is already NULL. | 137 | * Run a script. argv[2] is already NULL. |
125 | */ | 138 | */ |
126 | static int run(char *argv[3], const char *intf, struct in_addr *ip) | 139 | static int run(char *argv[3], struct in_addr *ip) |
127 | { | 140 | { |
128 | int status; | 141 | int status; |
142 | char *addr = addr; /* for gcc */ | ||
143 | const char *fmt = "%s %s %s" + 3; | ||
129 | 144 | ||
130 | VDBG("%s run %s %s\n", intf, argv[0], argv[1]); | 145 | VDBG("%s run %s %s\n", intf, argv[0], argv[1]); |
131 | 146 | ||
132 | if (ip) { | 147 | if (ip) { |
133 | char *addr = inet_ntoa(*ip); | 148 | addr = inet_ntoa(*ip); |
134 | setenv("ip", addr, 1); | 149 | setenv("ip", addr, 1); |
135 | bb_info_msg("%s %s %s", argv[1], intf, addr); | 150 | fmt -= 3; |
136 | } | 151 | } |
152 | bb_info_msg(fmt, argv[1], intf, addr); | ||
137 | 153 | ||
138 | status = wait4pid(spawn(argv)); | 154 | status = wait4pid(spawn(argv)); |
139 | if (status < 0) { | 155 | if (status < 0) { |
140 | bb_perror_msg("%s %s", argv[1], intf); | 156 | bb_perror_msg("%s %s %s" + 3, argv[1], intf); |
141 | return -errno; | 157 | return -errno; |
142 | } | 158 | } |
143 | if (status != 0) | 159 | if (status != 0) |
@@ -148,7 +164,7 @@ static int run(char *argv[3], const char *intf, struct in_addr *ip) | |||
148 | /** | 164 | /** |
149 | * Return milliseconds of random delay, up to "secs" seconds. | 165 | * Return milliseconds of random delay, up to "secs" seconds. |
150 | */ | 166 | */ |
151 | static unsigned ALWAYS_INLINE ms_rdelay(unsigned secs) | 167 | static unsigned ALWAYS_INLINE random_delay_ms(unsigned secs) |
152 | { | 168 | { |
153 | return rand() % (secs * 1000); | 169 | return rand() % (secs * 1000); |
154 | } | 170 | } |
@@ -160,10 +176,8 @@ int zcip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
160 | int zcip_main(int argc, char **argv) | 176 | int zcip_main(int argc, char **argv) |
161 | { | 177 | { |
162 | int state = PROBE; | 178 | int state = PROBE; |
163 | /* Prevent unaligned traps for ARM (see srand() below) */ | 179 | struct ether_addr eth_addr; |
164 | struct ether_addr eth_addr __attribute__(( aligned(sizeof(unsigned)) )); | ||
165 | const char *why; | 180 | const char *why; |
166 | int fd; | ||
167 | char *r_opt; | 181 | char *r_opt; |
168 | unsigned opts; | 182 | unsigned opts; |
169 | 183 | ||
@@ -171,10 +185,8 @@ int zcip_main(int argc, char **argv) | |||
171 | struct { | 185 | struct { |
172 | const struct in_addr null_ip; | 186 | const struct in_addr null_ip; |
173 | const struct ether_addr null_addr; | 187 | const struct ether_addr null_addr; |
174 | struct sockaddr saddr; | ||
175 | struct in_addr ip; | 188 | struct in_addr ip; |
176 | struct ifreq ifr; | 189 | struct ifreq ifr; |
177 | char *intf; | ||
178 | char *script_av[3]; | 190 | char *script_av[3]; |
179 | int timeout_ms; /* must be signed */ | 191 | int timeout_ms; /* must be signed */ |
180 | unsigned conflicts; | 192 | unsigned conflicts; |
@@ -185,10 +197,8 @@ int zcip_main(int argc, char **argv) | |||
185 | } L; | 197 | } L; |
186 | #define null_ip (L.null_ip ) | 198 | #define null_ip (L.null_ip ) |
187 | #define null_addr (L.null_addr ) | 199 | #define null_addr (L.null_addr ) |
188 | #define saddr (L.saddr ) | ||
189 | #define ip (L.ip ) | 200 | #define ip (L.ip ) |
190 | #define ifr (L.ifr ) | 201 | #define ifr (L.ifr ) |
191 | #define intf (L.intf ) | ||
192 | #define script_av (L.script_av ) | 202 | #define script_av (L.script_av ) |
193 | #define timeout_ms (L.timeout_ms) | 203 | #define timeout_ms (L.timeout_ms) |
194 | #define conflicts (L.conflicts ) | 204 | #define conflicts (L.conflicts ) |
@@ -231,29 +241,37 @@ int zcip_main(int argc, char **argv) | |||
231 | 241 | ||
232 | // initialize the interface (modprobe, ifup, etc) | 242 | // initialize the interface (modprobe, ifup, etc) |
233 | script_av[1] = (char*)"init"; | 243 | script_av[1] = (char*)"init"; |
234 | if (run(script_av, intf, NULL)) | 244 | if (run(script_av, NULL)) |
235 | return EXIT_FAILURE; | 245 | return EXIT_FAILURE; |
236 | 246 | ||
237 | // initialize saddr | 247 | // initialize saddr |
248 | // saddr is: { u16 sa_family; u8 sa_data[14]; } | ||
238 | //memset(&saddr, 0, sizeof(saddr)); | 249 | //memset(&saddr, 0, sizeof(saddr)); |
250 | //TODO: are we leaving sa_family == 0 (AF_UNSPEC)?! | ||
239 | safe_strncpy(saddr.sa_data, intf, sizeof(saddr.sa_data)); | 251 | safe_strncpy(saddr.sa_data, intf, sizeof(saddr.sa_data)); |
240 | 252 | ||
241 | // open an ARP socket | 253 | // open an ARP socket |
242 | fd = xsocket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)); | 254 | xmove_fd(xsocket(AF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)), sock_fd); |
243 | // bind to the interface's ARP socket | 255 | // bind to the interface's ARP socket |
244 | xbind(fd, &saddr, sizeof(saddr)); | 256 | xbind(sock_fd, &saddr, sizeof(saddr)); |
245 | 257 | ||
246 | // get the interface's ethernet address | 258 | // get the interface's ethernet address |
247 | //memset(&ifr, 0, sizeof(ifr)); | 259 | //memset(&ifr, 0, sizeof(ifr)); |
248 | strncpy(ifr.ifr_name, intf, sizeof(ifr.ifr_name)); | 260 | strncpy(ifr.ifr_name, intf, sizeof(ifr.ifr_name)); |
249 | xioctl(fd, SIOCGIFHWADDR, &ifr); | 261 | xioctl(sock_fd, SIOCGIFHWADDR, &ifr); |
250 | memcpy(ð_addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN); | 262 | memcpy(ð_addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN); |
251 | 263 | ||
252 | // start with some stable ip address, either a function of | 264 | // start with some stable ip address, either a function of |
253 | // the hardware address or else the last address we used. | 265 | // the hardware address or else the last address we used. |
266 | // we are taking low-order four bytes, as top-order ones | ||
267 | // aren't random enough. | ||
254 | // NOTE: the sequence of addresses we try changes only | 268 | // NOTE: the sequence of addresses we try changes only |
255 | // depending on when we detect conflicts. | 269 | // depending on when we detect conflicts. |
256 | srand(*(unsigned*)ð_addr); | 270 | { |
271 | uint32_t t; | ||
272 | memcpy(&t, (char*)ð_addr + 2, 4); | ||
273 | srand(t); | ||
274 | } | ||
257 | if (ip.s_addr == 0) | 275 | if (ip.s_addr == 0) |
258 | pick(&ip); | 276 | pick(&ip); |
259 | 277 | ||
@@ -281,18 +299,17 @@ int zcip_main(int argc, char **argv) | |||
281 | struct pollfd fds[1]; | 299 | struct pollfd fds[1]; |
282 | unsigned deadline_us; | 300 | unsigned deadline_us; |
283 | struct arp_packet p; | 301 | struct arp_packet p; |
302 | int source_ip_conflict; | ||
303 | int target_ip_conflict; | ||
284 | 304 | ||
285 | int source_ip_conflict = 0; | 305 | fds[0].fd = sock_fd; |
286 | int target_ip_conflict = 0; | ||
287 | |||
288 | fds[0].fd = fd; | ||
289 | fds[0].events = POLLIN; | 306 | fds[0].events = POLLIN; |
290 | fds[0].revents = 0; | 307 | fds[0].revents = 0; |
291 | 308 | ||
292 | // poll, being ready to adjust current timeout | 309 | // poll, being ready to adjust current timeout |
293 | if (!timeout_ms) { | 310 | if (!timeout_ms) { |
294 | timeout_ms = ms_rdelay(PROBE_WAIT); | 311 | timeout_ms = random_delay_ms(PROBE_WAIT); |
295 | // FIXME setsockopt(fd, SO_ATTACH_FILTER, ...) to | 312 | // FIXME setsockopt(sock_fd, SO_ATTACH_FILTER, ...) to |
296 | // make the kernel filter out all packets except | 313 | // make the kernel filter out all packets except |
297 | // ones we'd care about. | 314 | // ones we'd care about. |
298 | } | 315 | } |
@@ -302,6 +319,8 @@ int zcip_main(int argc, char **argv) | |||
302 | VDBG("...wait %d %s nprobes=%u, nclaims=%u\n", | 319 | VDBG("...wait %d %s nprobes=%u, nclaims=%u\n", |
303 | timeout_ms, intf, nprobes, nclaims); | 320 | timeout_ms, intf, nprobes, nclaims); |
304 | 321 | ||
322 | // FIXME: do we really receive ALL packets here?? | ||
323 | // if yes, set up filtering to get ARPs only!!! (see arping) | ||
305 | switch (safe_poll(fds, 1, timeout_ms)) { | 324 | switch (safe_poll(fds, 1, timeout_ms)) { |
306 | 325 | ||
307 | default: | 326 | default: |
@@ -319,11 +338,11 @@ int zcip_main(int argc, char **argv) | |||
319 | nprobes++; | 338 | nprobes++; |
320 | VDBG("probe/%u %s@%s\n", | 339 | VDBG("probe/%u %s@%s\n", |
321 | nprobes, intf, inet_ntoa(ip)); | 340 | nprobes, intf, inet_ntoa(ip)); |
322 | arp(fd, &saddr, ARPOP_REQUEST, | 341 | arp(ARPOP_REQUEST, |
323 | ð_addr, null_ip, | 342 | ð_addr, null_ip, |
324 | &null_addr, ip); | 343 | &null_addr, ip); |
325 | timeout_ms = PROBE_MIN * 1000; | 344 | timeout_ms = PROBE_MIN * 1000; |
326 | timeout_ms += ms_rdelay(PROBE_MAX - PROBE_MIN); | 345 | timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN); |
327 | } | 346 | } |
328 | else { | 347 | else { |
329 | // Switch to announce state. | 348 | // Switch to announce state. |
@@ -331,7 +350,7 @@ int zcip_main(int argc, char **argv) | |||
331 | nclaims = 0; | 350 | nclaims = 0; |
332 | VDBG("announce/%u %s@%s\n", | 351 | VDBG("announce/%u %s@%s\n", |
333 | nclaims, intf, inet_ntoa(ip)); | 352 | nclaims, intf, inet_ntoa(ip)); |
334 | arp(fd, &saddr, ARPOP_REQUEST, | 353 | arp(ARPOP_REQUEST, |
335 | ð_addr, ip, | 354 | ð_addr, ip, |
336 | ð_addr, ip); | 355 | ð_addr, ip); |
337 | timeout_ms = ANNOUNCE_INTERVAL * 1000; | 356 | timeout_ms = ANNOUNCE_INTERVAL * 1000; |
@@ -344,7 +363,7 @@ int zcip_main(int argc, char **argv) | |||
344 | nclaims = 0; | 363 | nclaims = 0; |
345 | VDBG("announce/%u %s@%s\n", | 364 | VDBG("announce/%u %s@%s\n", |
346 | nclaims, intf, inet_ntoa(ip)); | 365 | nclaims, intf, inet_ntoa(ip)); |
347 | arp(fd, &saddr, ARPOP_REQUEST, | 366 | arp(ARPOP_REQUEST, |
348 | ð_addr, ip, | 367 | ð_addr, ip, |
349 | ð_addr, ip); | 368 | ð_addr, ip); |
350 | timeout_ms = ANNOUNCE_INTERVAL * 1000; | 369 | timeout_ms = ANNOUNCE_INTERVAL * 1000; |
@@ -356,7 +375,7 @@ int zcip_main(int argc, char **argv) | |||
356 | nclaims++; | 375 | nclaims++; |
357 | VDBG("announce/%u %s@%s\n", | 376 | VDBG("announce/%u %s@%s\n", |
358 | nclaims, intf, inet_ntoa(ip)); | 377 | nclaims, intf, inet_ntoa(ip)); |
359 | arp(fd, &saddr, ARPOP_REQUEST, | 378 | arp(ARPOP_REQUEST, |
360 | ð_addr, ip, | 379 | ð_addr, ip, |
361 | ð_addr, ip); | 380 | ð_addr, ip); |
362 | timeout_ms = ANNOUNCE_INTERVAL * 1000; | 381 | timeout_ms = ANNOUNCE_INTERVAL * 1000; |
@@ -367,7 +386,7 @@ int zcip_main(int argc, char **argv) | |||
367 | // link is ok to use earlier | 386 | // link is ok to use earlier |
368 | // FIXME update filters | 387 | // FIXME update filters |
369 | script_av[1] = (char*)"config"; | 388 | script_av[1] = (char*)"config"; |
370 | run(script_av, intf, &ip); | 389 | run(script_av, &ip); |
371 | ready = 1; | 390 | ready = 1; |
372 | conflicts = 0; | 391 | conflicts = 0; |
373 | timeout_ms = -1; // Never timeout in the monitor state. | 392 | timeout_ms = -1; // Never timeout in the monitor state. |
@@ -395,7 +414,7 @@ int zcip_main(int argc, char **argv) | |||
395 | } // switch (state) | 414 | } // switch (state) |
396 | break; // case 0 (timeout) | 415 | break; // case 0 (timeout) |
397 | 416 | ||
398 | // packets arriving | 417 | // packets arriving, or link went down |
399 | case 1: | 418 | case 1: |
400 | // We need to adjust the timeout in case we didn't receive | 419 | // We need to adjust the timeout in case we didn't receive |
401 | // a conflicting packet. | 420 | // a conflicting packet. |
@@ -408,8 +427,7 @@ int zcip_main(int argc, char **argv) | |||
408 | timeout_ms = 0; | 427 | timeout_ms = 0; |
409 | } else { | 428 | } else { |
410 | VDBG("adjusting timeout\n"); | 429 | VDBG("adjusting timeout\n"); |
411 | timeout_ms = diff / 1000; | 430 | timeout_ms = (diff / 1000) | 1; /* never 0 */ |
412 | if (!timeout_ms) timeout_ms = 1; | ||
413 | } | 431 | } |
414 | } | 432 | } |
415 | 433 | ||
@@ -417,10 +435,10 @@ int zcip_main(int argc, char **argv) | |||
417 | if (fds[0].revents & POLLERR) { | 435 | if (fds[0].revents & POLLERR) { |
418 | // FIXME: links routinely go down; | 436 | // FIXME: links routinely go down; |
419 | // this shouldn't necessarily exit. | 437 | // this shouldn't necessarily exit. |
420 | bb_error_msg("%s: poll error", intf); | 438 | bb_error_msg("iface %s is down", intf); |
421 | if (ready) { | 439 | if (ready) { |
422 | script_av[1] = (char*)"deconfig"; | 440 | script_av[1] = (char*)"deconfig"; |
423 | run(script_av, intf, &ip); | 441 | run(script_av, &ip); |
424 | } | 442 | } |
425 | return EXIT_FAILURE; | 443 | return EXIT_FAILURE; |
426 | } | 444 | } |
@@ -428,21 +446,20 @@ int zcip_main(int argc, char **argv) | |||
428 | } | 446 | } |
429 | 447 | ||
430 | // read ARP packet | 448 | // read ARP packet |
431 | if (recv(fd, &p, sizeof(p), 0) < 0) { | 449 | if (safe_read(sock_fd, &p, sizeof(p)) < 0) { |
432 | why = "recv"; | 450 | why = "recv"; |
433 | goto bad; | 451 | goto bad; |
434 | } | 452 | } |
435 | if (p.hdr.ether_type != htons(ETHERTYPE_ARP)) | 453 | if (p.eth.ether_type != htons(ETHERTYPE_ARP)) |
436 | continue; | 454 | continue; |
437 | |||
438 | #ifdef DEBUG | 455 | #ifdef DEBUG |
439 | { | 456 | { |
440 | struct ether_addr * sha = (struct ether_addr *) p.arp.arp_sha; | 457 | struct ether_addr *sha = (struct ether_addr *) p.arp.arp_sha; |
441 | struct ether_addr * tha = (struct ether_addr *) p.arp.arp_tha; | 458 | struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha; |
442 | struct in_addr * spa = (struct in_addr *) p.arp.arp_spa; | 459 | struct in_addr *spa = (struct in_addr *) p.arp.arp_spa; |
443 | struct in_addr * tpa = (struct in_addr *) p.arp.arp_tpa; | 460 | struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa; |
444 | VDBG("%s recv arp type=%d, op=%d,\n", | 461 | VDBG("%s recv arp type=%d, op=%d,\n", |
445 | intf, ntohs(p.hdr.ether_type), | 462 | intf, ntohs(p.eth.ether_type), |
446 | ntohs(p.arp.arp_op)); | 463 | ntohs(p.arp.arp_op)); |
447 | VDBG("\tsource=%s %s\n", | 464 | VDBG("\tsource=%s %s\n", |
448 | ether_ntoa(sha), | 465 | ether_ntoa(sha), |
@@ -453,16 +470,21 @@ int zcip_main(int argc, char **argv) | |||
453 | } | 470 | } |
454 | #endif | 471 | #endif |
455 | if (p.arp.arp_op != htons(ARPOP_REQUEST) | 472 | if (p.arp.arp_op != htons(ARPOP_REQUEST) |
456 | && p.arp.arp_op != htons(ARPOP_REPLY)) | 473 | && p.arp.arp_op != htons(ARPOP_REPLY)) |
457 | continue; | 474 | continue; |
458 | 475 | ||
459 | if (memcmp(p.arp.arp_spa, &ip.s_addr, sizeof(struct in_addr)) == 0 && | 476 | source_ip_conflict = 0; |
460 | memcmp(ð_addr, &p.arp.arp_sha, ETH_ALEN) != 0) { | 477 | target_ip_conflict = 0; |
478 | |||
479 | if (memcmp(p.arp.arp_spa, &ip.s_addr, sizeof(struct in_addr)) == 0 | ||
480 | && memcmp(&p.arp.arp_sha, ð_addr, ETH_ALEN) != 0 | ||
481 | ) { | ||
461 | source_ip_conflict = 1; | 482 | source_ip_conflict = 1; |
462 | } | 483 | } |
463 | if (memcmp(p.arp.arp_tpa, &ip.s_addr, sizeof(struct in_addr)) == 0 && | 484 | if (p.arp.arp_op == htons(ARPOP_REQUEST) |
464 | p.arp.arp_op == htons(ARPOP_REQUEST) && | 485 | && memcmp(p.arp.arp_tpa, &ip.s_addr, sizeof(struct in_addr)) == 0 |
465 | memcmp(ð_addr, &p.arp.arp_tha, ETH_ALEN) != 0) { | 486 | && memcmp(&p.arp.arp_tha, ð_addr, ETH_ALEN) != 0 |
487 | ) { | ||
466 | target_ip_conflict = 1; | 488 | target_ip_conflict = 1; |
467 | } | 489 | } |
468 | 490 | ||
@@ -494,10 +516,9 @@ int zcip_main(int argc, char **argv) | |||
494 | VDBG("monitor conflict -- defending\n"); | 516 | VDBG("monitor conflict -- defending\n"); |
495 | state = DEFEND; | 517 | state = DEFEND; |
496 | timeout_ms = DEFEND_INTERVAL * 1000; | 518 | timeout_ms = DEFEND_INTERVAL * 1000; |
497 | arp(fd, &saddr, | 519 | arp(ARPOP_REQUEST, |
498 | ARPOP_REQUEST, | 520 | ð_addr, ip, |
499 | ð_addr, ip, | 521 | ð_addr, ip); |
500 | ð_addr, ip); | ||
501 | } | 522 | } |
502 | break; | 523 | break; |
503 | case DEFEND: | 524 | case DEFEND: |
@@ -507,7 +528,7 @@ int zcip_main(int argc, char **argv) | |||
507 | VDBG("defend conflict -- starting over\n"); | 528 | VDBG("defend conflict -- starting over\n"); |
508 | ready = 0; | 529 | ready = 0; |
509 | script_av[1] = (char*)"deconfig"; | 530 | script_av[1] = (char*)"deconfig"; |
510 | run(script_av, intf, &ip); | 531 | run(script_av, &ip); |
511 | 532 | ||
512 | // restart the whole protocol | 533 | // restart the whole protocol |
513 | pick(&ip); | 534 | pick(&ip); |
@@ -530,6 +551,6 @@ int zcip_main(int argc, char **argv) | |||
530 | } // switch poll | 551 | } // switch poll |
531 | } // while (1) | 552 | } // while (1) |
532 | bad: | 553 | bad: |
533 | bb_perror_msg("%s, %s", intf, why); | 554 | bb_perror_msg("%s: %s", intf, why); |
534 | return EXIT_FAILURE; | 555 | return EXIT_FAILURE; |
535 | } | 556 | } |