aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/usage.h48
-rw-r--r--networking/udhcp/Config.in10
-rw-r--r--networking/udhcp/Kbuild6
-rw-r--r--networking/udhcp/arpping.c29
-rw-r--r--networking/udhcp/clientpacket.c16
-rw-r--r--networking/udhcp/common.h2
-rw-r--r--networking/udhcp/dhcpc.c65
-rw-r--r--networking/udhcp/dhcpc.h7
-rw-r--r--networking/udhcp/signalpipe.c2
9 files changed, 138 insertions, 47 deletions
diff --git a/include/usage.h b/include/usage.h
index d0eecdb4a..3c8762ee1 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -2183,8 +2183,8 @@
2183 "and * (run both after creating and before deleting). The commands run in\n" \ 2183 "and * (run both after creating and before deleting). The commands run in\n" \
2184 "the /dev directory, and use system() which calls /bin/sh.\n\n" \ 2184 "the /dev directory, and use system() which calls /bin/sh.\n\n" \
2185 ) \ 2185 ) \
2186 "Config file parsing stops on the first matching line. If no config\n"\ 2186 "Config file parsing stops on the first matching line. If no config\n" \
2187 "entry is matched, devices are created with default 0:0 660. (Make\n"\ 2187 "entry is matched, devices are created with default 0:0 660. (Make\n" \
2188 "the last line match .* to override this.)\n\n" \ 2188 "the last line match .* to override this.)\n\n" \
2189 ) 2189 )
2190 2190
@@ -3843,44 +3843,50 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when
3843 " [-p pidfile] [-r IP] [-s script]" 3843 " [-p pidfile] [-r IP] [-s script]"
3844#define udhcpc_full_usage \ 3844#define udhcpc_full_usage \
3845 USE_GETOPT_LONG( \ 3845 USE_GETOPT_LONG( \
3846 " -V,--vendorclass=CLASSID Set vendor class identifier" \ 3846 " -V,--vendorclass=CLASSID Vendor class identifier" \
3847 "\n -i,--interface=INTERFACE Interface to use (default: eth0)" \ 3847 "\n -i,--interface=INTERFACE Interface to use (default eth0)" \
3848 "\n -H,-h,--hostname=HOSTNAME Client hostname" \ 3848 "\n -H,-h,--hostname=HOSTNAME Client hostname" \
3849 "\n -c,--clientid=CLIENTID Set client identifier" \ 3849 "\n -c,--clientid=CLIENTID Client identifier" \
3850 "\n -C,--clientid-none Suppress default client identifier" \ 3850 "\n -C,--clientid-none Suppress default client identifier" \
3851 "\n -p,--pidfile=file Store process ID of daemon in file" \ 3851 "\n -p,--pidfile=file Create pidfile" \
3852 "\n -r,--request=IP IP address to request" \ 3852 "\n -r,--request=IP IP address to request" \
3853 "\n -s,--script=file Run file at dhcp events (default: /usr/share/udhcpc/default.script)" \ 3853 "\n -s,--script=file Run file at dhcp events (default: /usr/share/udhcpc/default.script)" \
3854 "\n -t,--retries=N Send up to N request packets"\ 3854 "\n -t,--retries=N Send up to N request packets" \
3855 "\n -T,--timeout=N Try to get a lease for N seconds (default: 3)"\ 3855 "\n -T,--timeout=N Try to get a lease for N seconds (default 3)" \
3856 "\n -A,--tryagain=N Wait N seconds (default: 60) after failure"\ 3856 "\n -A,--tryagain=N Wait N seconds (default 60) after failure" \
3857 "\n -f,--foreground Run in foreground" \ 3857 "\n -f,--foreground Run in foreground" \
3858 "\n -b,--background Background if lease cannot be immediately negotiated" \ 3858 "\n -b,--background Background if lease is not immediately obtained" \
3859 "\n -S,--syslog Log to syslog too" \ 3859 "\n -S,--syslog Log to syslog too" \
3860 "\n -n,--now Exit with failure if lease cannot be immediately negotiated" \ 3860 "\n -n,--now Exit with failure if lease is not immediately obtained" \
3861 "\n -q,--quit Quit after obtaining lease" \ 3861 "\n -q,--quit Quit after obtaining lease" \
3862 "\n -R,--release Release IP on quit" \ 3862 "\n -R,--release Release IP on quit" \
3863 "\n -v,--version Display version" \ 3863 USE_FEATURE_UDHCPC_ARPING( \
3864 "\n -a,--arping Use arping to validate offered address" \
3865 "\n -W,--wait=N Wait N seconds after declining (default 10)" \
3866 ) \
3864 ) \ 3867 ) \
3865 SKIP_GETOPT_LONG( \ 3868 SKIP_GETOPT_LONG( \
3866 " -V CLASSID Set vendor class identifier" \ 3869 " -V CLASSID Vendor class identifier" \
3867 "\n -i INTERFACE Interface to use (default: eth0)" \ 3870 "\n -i INTERFACE Interface to use (default: eth0)" \
3868 "\n -H,-h HOSTNAME Client hostname" \ 3871 "\n -H,-h HOSTNAME Client hostname" \
3869 "\n -c CLIENTID Set client identifier" \ 3872 "\n -c CLIENTID Client identifier" \
3870 "\n -C Suppress default client identifier" \ 3873 "\n -C Suppress default client identifier" \
3871 "\n -p file Store process ID of daemon in file" \ 3874 "\n -p file Create pidfile" \
3872 "\n -r IP IP address to request" \ 3875 "\n -r IP IP address to request" \
3873 "\n -s file Run file at dhcp events (default: /usr/share/udhcpc/default.script)" \ 3876 "\n -s file Run file at dhcp events (default: /usr/share/udhcpc/default.script)" \
3874 "\n -t N Send up to N request packets"\ 3877 "\n -t N Send up to N request packets" \
3875 "\n -T N Try to get a lease for N seconds (default: 3)"\ 3878 "\n -T N Try to get a lease for N seconds (default 3)" \
3876 "\n -A N Wait N seconds (default: 60) after failure"\ 3879 "\n -A N Wait N seconds (default 60) after failure" \
3877 "\n -f Run in foreground" \ 3880 "\n -f Run in foreground" \
3878 "\n -b Background if lease cannot be immediately negotiated" \ 3881 "\n -b Background if lease is not immediately obtained" \
3879 "\n -S Log to syslog too" \ 3882 "\n -S Log to syslog too" \
3880 "\n -n Exit with failure if lease cannot be immediately negotiated" \ 3883 "\n -n Exit with failure if lease is not immediately obtained" \
3881 "\n -q Quit after obtaining lease" \ 3884 "\n -q Quit after obtaining lease" \
3882 "\n -R Release IP on quit" \ 3885 "\n -R Release IP on quit" \
3883 "\n -v Display version" \ 3886 USE_FEATURE_UDHCPC_ARPING( \
3887 "\n -a Use arping to validate offered address" \
3888 "\n -W N Wait N seconds after declining (default 10)" \
3889 ) \
3884 ) 3890 )
3885 3891
3886#define udhcpd_trivial_usage \ 3892#define udhcpd_trivial_usage \
diff --git a/networking/udhcp/Config.in b/networking/udhcp/Config.in
index 76b078001..734db65cc 100644
--- a/networking/udhcp/Config.in
+++ b/networking/udhcp/Config.in
@@ -54,6 +54,16 @@ config APP_UDHCPC
54 54
55 See http://udhcp.busybox.net for further details. 55 See http://udhcp.busybox.net for further details.
56 56
57config FEATURE_UDHCPC_ARPING
58 bool "Ask udhcpc to verify that the offered address is free, using arpping"
59 default y
60 depends on APP_UDHCPC
61 help
62 If selected, udhcpc will use arpping to make sure the offered address
63 is really available. The client will DHCPDECLINE the offer if the
64 address is in use, and restart the discover process.
65
66
57config FEATURE_UDHCP_DEBUG 67config FEATURE_UDHCP_DEBUG
58 bool "Compile udhcp with noisy debugging messages" 68 bool "Compile udhcp with noisy debugging messages"
59 default n 69 default n
diff --git a/networking/udhcp/Kbuild b/networking/udhcp/Kbuild
index aed40b98c..7d4747083 100644
--- a/networking/udhcp/Kbuild
+++ b/networking/udhcp/Kbuild
@@ -10,10 +10,16 @@ lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o \
10 signalpipe.o socket.o 10 signalpipe.o socket.o
11lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o \ 11lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o \
12 signalpipe.o socket.o 12 signalpipe.o socket.o
13
13lib-$(CONFIG_APP_UDHCPC) += dhcpc.o clientpacket.o clientsocket.o \ 14lib-$(CONFIG_APP_UDHCPC) += dhcpc.o clientpacket.o clientsocket.o \
14 script.o 15 script.o
16
17UDHCPC_NEEDS_ARPING-$(CONFIG_FEATURE_UDHCPC_ARPING) = y
18lib-$(UDHCPC_NEEDS_ARPING) += arpping.o
19
15lib-$(CONFIG_APP_UDHCPD) += dhcpd.o arpping.o files.o leases.o \ 20lib-$(CONFIG_APP_UDHCPD) += dhcpd.o arpping.o files.o leases.o \
16 serverpacket.o static_leases.o 21 serverpacket.o static_leases.o
22
17lib-$(CONFIG_APP_DUMPLEASES) += dumpleases.o 23lib-$(CONFIG_APP_DUMPLEASES) += dumpleases.o
18lib-$(CONFIG_APP_DHCPRELAY) += dhcprelay.o 24lib-$(CONFIG_APP_DHCPRELAY) += dhcprelay.o
19lib-$(CONFIG_FEATURE_RFC3397) += domain_codec.o 25lib-$(CONFIG_FEATURE_RFC3397) += domain_codec.o
diff --git a/networking/udhcp/arpping.c b/networking/udhcp/arpping.c
index 7b702d8f3..45597c04b 100644
--- a/networking/udhcp/arpping.c
+++ b/networking/udhcp/arpping.c
@@ -32,12 +32,16 @@ struct arpMsg {
32 uint8_t pad[18]; /* 2a pad for min. ethernet payload (60 bytes) */ 32 uint8_t pad[18]; /* 2a pad for min. ethernet payload (60 bytes) */
33} ATTRIBUTE_PACKED; 33} ATTRIBUTE_PACKED;
34 34
35enum {
36 ARP_MSG_SIZE = 0x2a
37};
38
35 39
36/* Returns 1 if no reply received */ 40/* Returns 1 if no reply received */
37 41
38int arpping(uint32_t test_ip, uint32_t from_ip, uint8_t *from_mac, const char *interface) 42int arpping(uint32_t test_ip, uint32_t from_ip, uint8_t *from_mac, const char *interface)
39{ 43{
40 int timeout_ms = 2000; 44 int timeout_ms;
41 struct pollfd pfd[1]; 45 struct pollfd pfd[1];
42#define s (pfd[0].fd) /* socket */ 46#define s (pfd[0].fd) /* socket */
43 int rv = 1; /* "no reply received" yet */ 47 int rv = 1; /* "no reply received" yet */
@@ -51,7 +55,7 @@ int arpping(uint32_t test_ip, uint32_t from_ip, uint8_t *from_mac, const char *i
51 } 55 }
52 56
53 if (setsockopt_broadcast(s) == -1) { 57 if (setsockopt_broadcast(s) == -1) {
54 bb_perror_msg("cannot setsocketopt on raw socket"); 58 bb_perror_msg("cannot enable bcast on raw socket");
55 goto ret; 59 goto ret;
56 } 60 }
57 61
@@ -67,28 +71,35 @@ int arpping(uint32_t test_ip, uint32_t from_ip, uint8_t *from_mac, const char *i
67 arp.operation = htons(ARPOP_REQUEST); /* ARP op code */ 71 arp.operation = htons(ARPOP_REQUEST); /* ARP op code */
68 memcpy(arp.sHaddr, from_mac, 6); /* source hardware address */ 72 memcpy(arp.sHaddr, from_mac, 6); /* source hardware address */
69 memcpy(arp.sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */ 73 memcpy(arp.sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */
70 /* tHaddr */ /* target hardware address */ 74 /* tHaddr is zero-fiiled */ /* target hardware address */
71 memcpy(arp.tInaddr, &test_ip, sizeof(test_ip)); /* target IP address */ 75 memcpy(arp.tInaddr, &test_ip, sizeof(test_ip)); /* target IP address */
72 76
73 memset(&addr, 0, sizeof(addr)); 77 memset(&addr, 0, sizeof(addr));
74 safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data)); 78 safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data));
75 if (sendto(s, &arp, sizeof(arp), 0, &addr, sizeof(addr)) < 0) 79 if (sendto(s, &arp, sizeof(arp), 0, &addr, sizeof(addr)) < 0) {
80 // TODO: error message? caller didn't expect us to fail,
81 // just returning 1 "no reply received" misleads it.
76 goto ret; 82 goto ret;
83 }
77 84
78 /* wait for arp reply, and check it */ 85 /* wait for arp reply, and check it */
86 timeout_ms = 2000;
79 do { 87 do {
80 int r; 88 int r;
81 unsigned prevTime = monotonic_us(); 89 unsigned prevTime = monotonic_us();
82 90
83 pfd[0].events = POLLIN; 91 pfd[0].events = POLLIN;
84 r = safe_poll(pfd, 1, timeout_ms); 92 r = safe_poll(pfd, 1, timeout_ms);
85 if (r < 0) { 93 if (r < 0)
86 break; 94 break;
87 } else if (r) { 95 if (r) {
88 if (read(s, &arp, sizeof(arp)) < 0) 96 r = read(s, &arp, sizeof(arp));
97 if (r < 0)
89 break; 98 break;
90 if (arp.operation == htons(ARPOP_REPLY) 99 if (r >= ARP_MSG_SIZE
91 && memcmp(arp.tHaddr, from_mac, 6) == 0 100 && arp.operation == htons(ARPOP_REPLY)
101 /* don't check it: Linux doesn't return proper tHaddr (fixed in 2.6.24?) */
102 /* && memcmp(arp.tHaddr, from_mac, 6) == 0 */
92 && *((uint32_t *) arp.sInaddr) == test_ip 103 && *((uint32_t *) arp.sInaddr) == test_ip
93 ) { 104 ) {
94 rv = 0; 105 rv = 0;
diff --git a/networking/udhcp/clientpacket.c b/networking/udhcp/clientpacket.c
index 42b4895e5..e7eeb58b1 100644
--- a/networking/udhcp/clientpacket.c
+++ b/networking/udhcp/clientpacket.c
@@ -69,6 +69,22 @@ static void add_requests(struct dhcpMessage *packet)
69 69
70} 70}
71 71
72#if ENABLE_FEATURE_UDHCPC_ARPING
73/* Unicast a DHCP decline message */
74int send_decline(uint32_t xid, uint32_t server)
75{
76 struct dhcpMessage packet;
77
78 init_packet(&packet, DHCPDECLINE);
79 packet.xid = xid;
80 add_requests(&packet);
81
82 bb_info_msg("Sending decline...");
83
84 return udhcp_raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST,
85 SERVER_PORT, MAC_BCAST_ADDR, client_config.ifindex);
86}
87#endif
72 88
73/* Broadcast a DHCP discover packet to the network, with an optionally requested IP */ 89/* Broadcast a DHCP discover packet to the network, with an optionally requested IP */
74int send_discover(uint32_t xid, uint32_t requested) 90int send_discover(uint32_t xid, uint32_t requested)
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index 4864c8565..179c21fdb 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -76,7 +76,7 @@ void udhcp_run_script(struct dhcpMessage *packet, const char *name);
76 76
77void udhcp_sp_setup(void); 77void udhcp_sp_setup(void);
78int udhcp_sp_fd_set(fd_set *rfds, int extra_fd); 78int udhcp_sp_fd_set(fd_set *rfds, int extra_fd);
79int udhcp_sp_read(fd_set *rfds); 79int udhcp_sp_read(const fd_set *rfds);
80int raw_socket(int ifindex); 80int raw_socket(int ifindex);
81int read_interface(const char *interface, int *ifindex, uint32_t *addr, uint8_t *arp); 81int read_interface(const char *interface, int *ifindex, uint32_t *addr, uint8_t *arp);
82int listen_socket(/*uint32_t ip,*/ int port, const char *inf); 82int listen_socket(/*uint32_t ip,*/ int port, const char *inf);
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index c6f9fe42d..b3b89459e 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -145,6 +145,13 @@ int udhcpc_main(int argc, char **argv)
145{ 145{
146 uint8_t *temp, *message; 146 uint8_t *temp, *message;
147 char *str_c, *str_V, *str_h, *str_F, *str_r, *str_T, *str_A, *str_t; 147 char *str_c, *str_V, *str_h, *str_F, *str_r, *str_T, *str_A, *str_t;
148 int tryagain_timeout = 60;
149 int discover_timeout = 3;
150 int discover_retries = 3;
151#if ENABLE_FEATURE_UDHCPC_ARPING
152 int decline_wait = 10;
153 char *str_W;
154#endif
148 uint32_t xid = 0; 155 uint32_t xid = 0;
149 uint32_t lease = 0; /* can be given as 32-bit quantity */ 156 uint32_t lease = 0; /* can be given as 32-bit quantity */
150 unsigned t1 = 0, t2 = 0; /* what a wonderful names */ 157 unsigned t1 = 0, t2 = 0; /* what a wonderful names */
@@ -180,6 +187,10 @@ int udhcpc_main(int argc, char **argv)
180 OPT_v = 1 << 17, 187 OPT_v = 1 << 17,
181 OPT_S = 1 << 18, 188 OPT_S = 1 << 18,
182 OPT_A = 1 << 19, 189 OPT_A = 1 << 19,
190#if ENABLE_FEATURE_UDHCPC_ARPING
191 OPT_a = 1 << 20,
192 OPT_W = 1 << 21,
193#endif
183 }; 194 };
184#if ENABLE_GETOPT_LONG 195#if ENABLE_GETOPT_LONG
185 static const char udhcpc_longopts[] ALIGN1 = 196 static const char udhcpc_longopts[] ALIGN1 =
@@ -203,14 +214,15 @@ int udhcpc_main(int argc, char **argv)
203 "retries\0" Required_argument "t" 214 "retries\0" Required_argument "t"
204 "tryagain\0" Required_argument "A" 215 "tryagain\0" Required_argument "A"
205 "syslog\0" No_argument "S" 216 "syslog\0" No_argument "S"
217#if ENABLE_FEATURE_UDHCPC_ARPING
218 "arping\0" No_argument "a"
219 "wait\0" Required_argument "W"
220#endif
206 ; 221 ;
207#endif 222#endif
208 /* Default options. */ 223 /* Default options. */
209 client_config.interface = "eth0"; 224 client_config.interface = "eth0";
210 client_config.script = DEFAULT_SCRIPT; 225 client_config.script = DEFAULT_SCRIPT;
211 client_config.retries = 3;
212 client_config.timeout = 3;
213 client_config.tryagain = 60;
214 226
215 /* Parse command line */ 227 /* Parse command line */
216 opt_complementary = "c--C:C--c" // mutually exclusive 228 opt_complementary = "c--C:C--c" // mutually exclusive
@@ -218,10 +230,12 @@ int udhcpc_main(int argc, char **argv)
218#if ENABLE_GETOPT_LONG 230#if ENABLE_GETOPT_LONG
219 applet_long_options = udhcpc_longopts; 231 applet_long_options = udhcpc_longopts;
220#endif 232#endif
221 opt = getopt32(argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:vSA:", 233 opt = getopt32(argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:vSA:"
222 &str_c, &str_V, &str_h, &str_h, &str_F, 234 USE_FEATURE_UDHCPC_ARPING("aW:")
235 , &str_c, &str_V, &str_h, &str_h, &str_F,
223 &client_config.interface, &client_config.pidfile, &str_r, 236 &client_config.interface, &client_config.pidfile, &str_r,
224 &client_config.script, &str_T, &str_t, &str_A 237 &client_config.script, &str_T, &str_t, &str_A
238 USE_FEATURE_UDHCPC_ARPING(, &str_W)
225 ); 239 );
226 240
227 if (opt & OPT_c) 241 if (opt & OPT_c)
@@ -259,11 +273,11 @@ int udhcpc_main(int argc, char **argv)
259 requested_ip = inet_addr(str_r); 273 requested_ip = inet_addr(str_r);
260 // if (opt & OPT_s) client_config.script = ... 274 // if (opt & OPT_s) client_config.script = ...
261 if (opt & OPT_T) 275 if (opt & OPT_T)
262 client_config.timeout = xatoi_u(str_T); 276 discover_timeout = xatoi_u(str_T);
263 if (opt & OPT_t) 277 if (opt & OPT_t)
264 client_config.retries = xatoi_u(str_t); 278 discover_retries = xatoi_u(str_t);
265 if (opt & OPT_A) 279 if (opt & OPT_A)
266 client_config.tryagain = xatoi_u(str_A); 280 tryagain_timeout = xatoi_u(str_A);
267 if (opt & OPT_v) { 281 if (opt & OPT_v) {
268 puts("version "BB_VER); 282 puts("version "BB_VER);
269 return 0; 283 return 0;
@@ -274,6 +288,11 @@ int udhcpc_main(int argc, char **argv)
274 logmode |= LOGMODE_SYSLOG; 288 logmode |= LOGMODE_SYSLOG;
275 } 289 }
276 290
291#if ENABLE_FEATURE_UDHCPC_ARPING
292 if (opt & OPT_W)
293 decline_wait = xatou_range(str_W, 10, INT_MAX);
294#endif
295
277 if (read_interface(client_config.interface, &client_config.ifindex, 296 if (read_interface(client_config.interface, &client_config.ifindex,
278 NULL, client_config.arp)) 297 NULL, client_config.arp))
279 return 1; 298 return 1;
@@ -339,14 +358,14 @@ int udhcpc_main(int argc, char **argv)
339 /* timeout dropped to zero */ 358 /* timeout dropped to zero */
340 switch (state) { 359 switch (state) {
341 case INIT_SELECTING: 360 case INIT_SELECTING:
342 if (packet_num < client_config.retries) { 361 if (packet_num < discover_retries) {
343 if (packet_num == 0) 362 if (packet_num == 0)
344 xid = random_xid(); 363 xid = random_xid();
345 364
346 /* send discover packet */ 365 /* send discover packet */
347 send_discover(xid, requested_ip); /* broadcast */ 366 send_discover(xid, requested_ip); /* broadcast */
348 367
349 timeout = now + client_config.timeout; 368 timeout = now + discover_timeout;
350 packet_num++; 369 packet_num++;
351 } else { 370 } else {
352 udhcp_run_script(NULL, "leasefail"); 371 udhcp_run_script(NULL, "leasefail");
@@ -360,12 +379,12 @@ int udhcpc_main(int argc, char **argv)
360 } 379 }
361 /* wait to try again */ 380 /* wait to try again */
362 packet_num = 0; 381 packet_num = 0;
363 timeout = now + client_config.tryagain; 382 timeout = now + tryagain_timeout;
364 } 383 }
365 break; 384 break;
366 case RENEW_REQUESTED: 385 case RENEW_REQUESTED:
367 case REQUESTING: 386 case REQUESTING:
368 if (packet_num < client_config.retries) { 387 if (packet_num < discover_retries) {
369 /* send request packet */ 388 /* send request packet */
370 if (state == RENEW_REQUESTED) 389 if (state == RENEW_REQUESTED)
371 send_renew(xid, server_addr, requested_ip); /* unicast */ 390 send_renew(xid, server_addr, requested_ip); /* unicast */
@@ -491,6 +510,28 @@ int udhcpc_main(int argc, char **argv)
491 lease = ntohl(lease); 510 lease = ntohl(lease);
492 } 511 }
493 512
513#if ENABLE_FEATURE_UDHCPC_ARPING
514 if (opt & OPT_a) {
515 if (!arpping(packet.yiaddr,
516 (uint32_t) 0,
517 client_config.arp,
518 client_config.interface)
519 ) {
520 bb_info_msg("offered address is in use,"
521 " declining");
522 send_decline(xid, server_addr);
523
524 if (state != REQUESTING)
525 udhcp_run_script(NULL, "deconfig");
526 state = INIT_SELECTING;
527 requested_ip = 0;
528 packet_num = 0;
529 change_mode(LISTEN_RAW);
530 timeout = now + decline_wait;
531 break;
532 }
533 }
534#endif
494 /* enter bound state */ 535 /* enter bound state */
495 t1 = lease / 2; 536 t1 = lease / 2;
496 537
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h
index 72a8bd94f..c0172a84f 100644
--- a/networking/udhcp/dhcpc.h
+++ b/networking/udhcp/dhcpc.h
@@ -1,5 +1,6 @@
1/* vi: set sw=4 ts=4: */ 1/* vi: set sw=4 ts=4: */
2/* dhcpc.h */ 2/* dhcpc.h */
3
3#ifndef _DHCPC_H 4#ifndef _DHCPC_H
4#define _DHCPC_H 5#define _DHCPC_H
5 6
@@ -28,9 +29,6 @@ struct client_config_t {
28 uint8_t *hostname; /* Optional hostname to use */ 29 uint8_t *hostname; /* Optional hostname to use */
29 uint8_t *fqdn; /* Optional fully qualified domain name to use */ 30 uint8_t *fqdn; /* Optional fully qualified domain name to use */
30 int ifindex; /* Index number of the interface to use */ 31 int ifindex; /* Index number of the interface to use */
31 int retries; /* Max number of request packets */
32 int timeout; /* Number of seconds to try to get a lease */
33 int tryagain; /* Number of seconds to try to get a lease */
34 uint8_t arp[6]; /* Our arp address */ 32 uint8_t arp[6]; /* Our arp address */
35}; 33};
36 34
@@ -42,6 +40,9 @@ struct client_config_t {
42uint32_t random_xid(void); 40uint32_t random_xid(void);
43int send_discover(uint32_t xid, uint32_t requested); 41int send_discover(uint32_t xid, uint32_t requested);
44int send_selecting(uint32_t xid, uint32_t server, uint32_t requested); 42int send_selecting(uint32_t xid, uint32_t server, uint32_t requested);
43#if ENABLE_FEATURE_UDHCPC_ARPING
44int send_decline(uint32_t xid, uint32_t server);
45#endif
45int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr); 46int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr);
46int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr); 47int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr);
47int send_release(uint32_t server, uint32_t ciaddr); 48int send_release(uint32_t server, uint32_t ciaddr);
diff --git a/networking/udhcp/signalpipe.c b/networking/udhcp/signalpipe.c
index fafd2082a..845aa3a9a 100644
--- a/networking/udhcp/signalpipe.c
+++ b/networking/udhcp/signalpipe.c
@@ -66,7 +66,7 @@ int udhcp_sp_fd_set(fd_set *rfds, int extra_fd)
66/* Read a signal from the signal pipe. Returns 0 if there is 66/* Read a signal from the signal pipe. Returns 0 if there is
67 * no signal, -1 on error (and sets errno appropriately), and 67 * no signal, -1 on error (and sets errno appropriately), and
68 * your signal on success */ 68 * your signal on success */
69int udhcp_sp_read(fd_set *rfds) 69int udhcp_sp_read(const fd_set *rfds)
70{ 70{
71 unsigned char sig; 71 unsigned char sig;
72 72