summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-03-12 05:37:54 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2011-03-12 05:37:54 +0100
commit9ac5596a5154d789964150737a784dc4db98265b (patch)
tree4a3e3906516ebf078729e056b3f2562cb3ba81ee
parentea684c6aaf23ead57fac74c3ceaa651c1ae625ec (diff)
udhcpc: emit "correct" secs field
In theory, sending secs set to constant zero should be ok too. But some bleeping servers can actually be configured to answer ONLY if secs is bigger than a preset value (!!) http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/bootpd.8.html grep for "reply_threshold_seconds" function old new delta udhcpc_main 2573 2623 +50 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/udhcp/dhcpc.c14
-rw-r--r--networking/udhcp/dhcpc.h3
2 files changed, 17 insertions, 0 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index e9a841204..ca82d37e6 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -407,11 +407,19 @@ static ALWAYS_INLINE uint32_t random_xid(void)
/* Initialize the packet with the proper defaults */
static void init_packet(struct dhcp_packet *packet, char type)
{
+ uint16_t secs;
+
/* Fill in: op, htype, hlen, cookie fields; message type option: */
udhcp_init_header(packet, type);
packet->xid = random_xid();
+ client_config.last_secs = monotonic_sec();
+ if (client_config.first_secs == 0)
+ client_config.first_secs = client_config.last_secs;
+ secs = client_config.last_secs - client_config.first_secs;
+ packet->secs = htons(secs);
+
memcpy(packet->chaddr, client_config.client_mac, 6);
if (client_config.clientid)
udhcp_add_binary_option(packet, client_config.clientid);
@@ -848,6 +856,7 @@ static void change_listen_mode(int new_mode)
/* else LISTEN_NONE: sockfd stays closed */
}
+/* Called only on SIGUSR1 */
static void perform_renew(void)
{
bb_info_msg("Performing a DHCP renew");
@@ -1260,6 +1269,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
case BOUND:
/* 1/2 lease passed, enter renewing state */
state = RENEWING;
+ client_config.first_secs = 0; /* make secs field count from 0 */
change_listen_mode(LISTEN_KERNEL);
log1("Entering renew state");
/* fall right through */
@@ -1299,6 +1309,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
bb_info_msg("Lease lost, entering init state");
udhcp_run_script(NULL, "deconfig");
state = INIT_SELECTING;
+ client_config.first_secs = 0; /* make secs field count from 0 */
/*timeout = 0; - already is */
packet_num = 0;
continue;
@@ -1315,6 +1326,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
/* note: udhcp_sp_read checks FD_ISSET before reading */
switch (udhcp_sp_read(&rfds)) {
case SIGUSR1:
+ client_config.first_secs = 0; /* make secs field count from 0 */
perform_renew();
if (state == RENEW_REQUESTED)
goto case_RENEW_REQUESTED;
@@ -1446,6 +1458,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
udhcp_run_script(NULL, "deconfig");
change_listen_mode(LISTEN_RAW);
state = INIT_SELECTING;
+ client_config.first_secs = 0; /* make secs field count from 0 */
requested_ip = 0;
timeout = tryagain_timeout;
packet_num = 0;
@@ -1493,6 +1506,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
change_listen_mode(LISTEN_RAW);
sleep(3); /* avoid excessive network traffic */
state = INIT_SELECTING;
+ client_config.first_secs = 0; /* make secs field count from 0 */
requested_ip = 0;
timeout = 0;
packet_num = 0;
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h
index 9ef053a1b..2b3599120 100644
--- a/networking/udhcp/dhcpc.h
+++ b/networking/udhcp/dhcpc.h
@@ -21,6 +21,9 @@ struct client_config_t {
uint8_t *vendorclass; /* Optional vendor class-id to use */
uint8_t *hostname; /* Optional hostname to use */
uint8_t *fqdn; /* Optional fully qualified domain name to use */
+
+ uint16_t first_secs;
+ uint16_t last_secs;
} FIX_ALIASING;
/* server_config sits in 1st half of bb_common_bufsiz1 */