aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/dhcpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp/dhcpc.c')
-rw-r--r--networking/udhcp/dhcpc.c168
1 files changed, 112 insertions, 56 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 3d4c397ff..2f2016cd5 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -29,7 +29,7 @@
29#include <netpacket/packet.h> 29#include <netpacket/packet.h>
30#include <linux/filter.h> 30#include <linux/filter.h>
31 31
32/* struct client_config_t client_config is in bb_common_bufsiz1 */ 32/* "struct client_config_t client_config" is in bb_common_bufsiz1 */
33 33
34 34
35#if ENABLE_LONG_OPTS 35#if ENABLE_LONG_OPTS
@@ -46,7 +46,6 @@ static const char udhcpc_longopts[] ALIGN1 =
46 "request\0" Required_argument "r" 46 "request\0" Required_argument "r"
47 "script\0" Required_argument "s" 47 "script\0" Required_argument "s"
48 "timeout\0" Required_argument "T" 48 "timeout\0" Required_argument "T"
49 "version\0" No_argument "v"
50 "retries\0" Required_argument "t" 49 "retries\0" Required_argument "t"
51 "tryagain\0" Required_argument "A" 50 "tryagain\0" Required_argument "A"
52 "syslog\0" No_argument "S" 51 "syslog\0" No_argument "S"
@@ -124,24 +123,6 @@ static int sprint_nip(char *dest, const char *pre, const uint8_t *ip)
124 return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); 123 return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]);
125} 124}
126 125
127static int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip)
128{
129 char hexstrbuf[16 * 2];
130 bin2hex(hexstrbuf, (void*)ip, 16);
131 return sprintf(dest, /* "%s" */
132 "%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s",
133 /* pre, */
134 hexstrbuf + 0 * 4,
135 hexstrbuf + 1 * 4,
136 hexstrbuf + 2 * 4,
137 hexstrbuf + 3 * 4,
138 hexstrbuf + 4 * 4,
139 hexstrbuf + 5 * 4,
140 hexstrbuf + 6 * 4,
141 hexstrbuf + 7 * 4
142 );
143}
144
145/* really simple implementation, just count the bits */ 126/* really simple implementation, just count the bits */
146static int mton(uint32_t mask) 127static int mton(uint32_t mask)
147{ 128{
@@ -154,6 +135,63 @@ static int mton(uint32_t mask)
154 return i; 135 return i;
155} 136}
156 137
138/* Check if a given label represents a valid DNS label
139 * Return pointer to the first character after the label upon success,
140 * NULL otherwise.
141 * See RFC1035, 2.3.1
142 */
143/* We don't need to be particularly anal. For example, allowing _, hyphen
144 * at the end, or leading and trailing dots would be ok, since it
145 * can't be used for attacks. (Leading hyphen can be, if someone uses
146 * cmd "$hostname"
147 * in the script: then hostname may be treated as an option)
148 */
149static const char *valid_domain_label(const char *label)
150{
151 unsigned char ch;
152 unsigned pos = 0;
153
154 for (;;) {
155 ch = *label;
156 if ((ch|0x20) < 'a' || (ch|0x20) > 'z') {
157 if (pos == 0) {
158 /* label must begin with letter */
159 return NULL;
160 }
161 if (ch < '0' || ch > '9') {
162 if (ch == '\0' || ch == '.')
163 return label;
164 /* DNS allows only '-', but we are more permissive */
165 if (ch != '-' && ch != '_')
166 return NULL;
167 }
168 }
169 label++;
170 pos++;
171 //Do we want this?
172 //if (pos > 63) /* NS_MAXLABEL; labels must be 63 chars or less */
173 // return NULL;
174 }
175}
176
177/* Check if a given name represents a valid DNS name */
178/* See RFC1035, 2.3.1 */
179static int good_hostname(const char *name)
180{
181 //const char *start = name;
182
183 for (;;) {
184 name = valid_domain_label(name);
185 if (!name)
186 return 0;
187 if (!name[0])
188 return 1;
189 //Do we want this?
190 //return ((name - start) < 1025); /* NS_MAXDNAME */
191 name++;
192 }
193}
194
157/* Create "opt_name=opt_value" string */ 195/* Create "opt_name=opt_value" string */
158static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_optflag *optflag, const char *opt_name) 196static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_optflag *optflag, const char *opt_name)
159{ 197{
@@ -206,8 +244,11 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
206 * the case of list of options. 244 * the case of list of options.
207 */ 245 */
208 case OPTION_STRING: 246 case OPTION_STRING:
247 case OPTION_STRING_HOST:
209 memcpy(dest, option, len); 248 memcpy(dest, option, len);
210 dest[len] = '\0'; 249 dest[len] = '\0';
250 if (type == OPTION_STRING_HOST && !good_hostname(dest))
251 safe_strncpy(dest, "bad", len);
211 return ret; 252 return ret;
212 case OPTION_STATIC_ROUTES: { 253 case OPTION_STATIC_ROUTES: {
213 /* Option binary format: 254 /* Option binary format:
@@ -387,6 +428,7 @@ static char **fill_envp(struct dhcp_packet *packet)
387 /* +1 element for each option, +2 for subnet option: */ 428 /* +1 element for each option, +2 for subnet option: */
388 if (packet) { 429 if (packet) {
389 /* note: do not search for "pad" (0) and "end" (255) options */ 430 /* note: do not search for "pad" (0) and "end" (255) options */
431//TODO: change logic to scan packet _once_
390 for (i = 1; i < 255; i++) { 432 for (i = 1; i < 255; i++) {
391 temp = udhcp_get_option(packet, i); 433 temp = udhcp_get_option(packet, i);
392 if (temp) { 434 if (temp) {
@@ -499,9 +541,6 @@ static void udhcp_run_script(struct dhcp_packet *packet, const char *name)
499 char **envp, **curr; 541 char **envp, **curr;
500 char *argv[3]; 542 char *argv[3];
501 543
502 if (client_config.script == NULL)
503 return;
504
505 envp = fill_envp(packet); 544 envp = fill_envp(packet);
506 545
507 /* call script */ 546 /* call script */
@@ -598,6 +637,12 @@ static void add_client_options(struct dhcp_packet *packet)
598// if (client_config.boot_file) 637// if (client_config.boot_file)
599// strncpy((char*)packet->file, client_config.boot_file, sizeof(packet->file) - 1); 638// strncpy((char*)packet->file, client_config.boot_file, sizeof(packet->file) - 1);
600 } 639 }
640
641 // This will be needed if we remove -V VENDOR_STR in favor of
642 // -x vendor:VENDOR_STR
643 //if (!udhcp_find_option(packet.options, DHCP_VENDOR))
644 // /* not set, set the default vendor ID */
645 // ...add (DHCP_VENDOR, "udhcp "BB_VER) opt...
601} 646}
602 647
603/* RFC 2131 648/* RFC 2131
@@ -742,7 +787,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
742#if ENABLE_FEATURE_UDHCPC_ARPING 787#if ENABLE_FEATURE_UDHCPC_ARPING
743/* Broadcast a DHCP decline message */ 788/* Broadcast a DHCP decline message */
744/* NOINLINE: limit stack usage in caller */ 789/* NOINLINE: limit stack usage in caller */
745static NOINLINE int send_decline(uint32_t xid, uint32_t server, uint32_t requested) 790static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t requested)
746{ 791{
747 struct dhcp_packet packet; 792 struct dhcp_packet packet;
748 793
@@ -751,12 +796,14 @@ static NOINLINE int send_decline(uint32_t xid, uint32_t server, uint32_t request
751 */ 796 */
752 init_packet(&packet, DHCPDECLINE); 797 init_packet(&packet, DHCPDECLINE);
753 798
799#if 0
754 /* RFC 2131 says DHCPDECLINE's xid is randomly selected by client, 800 /* RFC 2131 says DHCPDECLINE's xid is randomly selected by client,
755 * but in case the server is buggy and wants DHCPDECLINE's xid 801 * but in case the server is buggy and wants DHCPDECLINE's xid
756 * to match the xid which started entire handshake, 802 * to match the xid which started entire handshake,
757 * we use the same xid we used in initial DHCPDISCOVER: 803 * we use the same xid we used in initial DHCPDISCOVER:
758 */ 804 */
759 packet.xid = xid; 805 packet.xid = xid;
806#endif
760 /* DHCPDECLINE uses "requested ip", not ciaddr, to store offered IP */ 807 /* DHCPDECLINE uses "requested ip", not ciaddr, to store offered IP */
761 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); 808 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
762 809
@@ -794,7 +841,6 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd)
794 struct ip_udp_dhcp_packet packet; 841 struct ip_udp_dhcp_packet packet;
795 uint16_t check; 842 uint16_t check;
796 843
797 memset(&packet, 0, sizeof(packet));
798 bytes = safe_read(fd, &packet, sizeof(packet)); 844 bytes = safe_read(fd, &packet, sizeof(packet));
799 if (bytes < 0) { 845 if (bytes < 0) {
800 log1("Packet read error, ignoring"); 846 log1("Packet read error, ignoring");
@@ -852,7 +898,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd)
852 return -2; 898 return -2;
853 } 899 }
854 900
855 log1("Got valid DHCP packet"); 901 log1("Received a packet");
856 udhcp_dump_packet(&packet.data); 902 udhcp_dump_packet(&packet.data);
857 903
858 bytes -= sizeof(packet.ip) + sizeof(packet.udp); 904 bytes -= sizeof(packet.ip) + sizeof(packet.udp);
@@ -1004,7 +1050,7 @@ static void perform_renew(void)
1004 } 1050 }
1005} 1051}
1006 1052
1007static void perform_release(uint32_t requested_ip, uint32_t server_addr) 1053static void perform_release(uint32_t server_addr, uint32_t requested_ip)
1008{ 1054{
1009 char buffer[sizeof("255.255.255.255")]; 1055 char buffer[sizeof("255.255.255.255")];
1010 struct in_addr temp_addr; 1056 struct in_addr temp_addr;
@@ -1053,7 +1099,7 @@ static void client_background(void)
1053//usage:#endif 1099//usage:#endif
1054//usage:#define udhcpc_trivial_usage 1100//usage:#define udhcpc_trivial_usage
1055//usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"oCRB] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n" 1101//usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"oCRB] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n"
1056//usage: " [-H HOSTNAME] [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]") 1102//usage: " [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]")
1057//usage:#define udhcpc_full_usage "\n" 1103//usage:#define udhcpc_full_usage "\n"
1058//usage: IF_LONG_OPTS( 1104//usage: IF_LONG_OPTS(
1059//usage: "\n -i,--interface IFACE Interface to use (default eth0)" 1105//usage: "\n -i,--interface IFACE Interface to use (default eth0)"
@@ -1086,7 +1132,6 @@ static void client_background(void)
1086//usage: "\n -x lease:3600 - option 51 (lease time)" 1132//usage: "\n -x lease:3600 - option 51 (lease time)"
1087//usage: "\n -x 0x3d:0100BEEFC0FFEE - option 61 (client id)" 1133//usage: "\n -x 0x3d:0100BEEFC0FFEE - option 61 (client id)"
1088//usage: "\n -F,--fqdn NAME Ask server to update DNS mapping for NAME" 1134//usage: "\n -F,--fqdn NAME Ask server to update DNS mapping for NAME"
1089//usage: "\n -H,-h,--hostname NAME Send NAME as client hostname (default none)"
1090//usage: "\n -V,--vendorclass VENDOR Vendor identifier (default 'udhcp VERSION')" 1135//usage: "\n -V,--vendorclass VENDOR Vendor identifier (default 'udhcp VERSION')"
1091//usage: "\n -C,--clientid-none Don't send MAC as client identifier" 1136//usage: "\n -C,--clientid-none Don't send MAC as client identifier"
1092//usage: IF_UDHCP_VERBOSE( 1137//usage: IF_UDHCP_VERBOSE(
@@ -1124,7 +1169,6 @@ static void client_background(void)
1124//usage: "\n -x lease:3600 - option 51 (lease time)" 1169//usage: "\n -x lease:3600 - option 51 (lease time)"
1125//usage: "\n -x 0x3d:0100BEEFC0FFEE - option 61 (client id)" 1170//usage: "\n -x 0x3d:0100BEEFC0FFEE - option 61 (client id)"
1126//usage: "\n -F NAME Ask server to update DNS mapping for NAME" 1171//usage: "\n -F NAME Ask server to update DNS mapping for NAME"
1127//usage: "\n -H,-h NAME Send NAME as client hostname (default none)"
1128//usage: "\n -V VENDOR Vendor identifier (default 'udhcp VERSION')" 1172//usage: "\n -V VENDOR Vendor identifier (default 'udhcp VERSION')"
1129//usage: "\n -C Don't send MAC as client identifier" 1173//usage: "\n -C Don't send MAC as client identifier"
1130//usage: IF_UDHCP_VERBOSE( 1174//usage: IF_UDHCP_VERBOSE(
@@ -1132,8 +1176,8 @@ static void client_background(void)
1132//usage: ) 1176//usage: )
1133//usage: ) 1177//usage: )
1134//usage: "\nSignals:" 1178//usage: "\nSignals:"
1135//usage: "\n USR1 Renew current lease" 1179//usage: "\n USR1 Renew lease"
1136//usage: "\n USR2 Release current lease" 1180//usage: "\n USR2 Release lease"
1137 1181
1138 1182
1139int udhcpc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1183int udhcpc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@@ -1150,16 +1194,13 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1150 int discover_retries = 3; 1194 int discover_retries = 3;
1151 uint32_t server_addr = server_addr; /* for compiler */ 1195 uint32_t server_addr = server_addr; /* for compiler */
1152 uint32_t requested_ip = 0; 1196 uint32_t requested_ip = 0;
1153 uint32_t xid = 0; 1197 uint32_t xid = xid; /* for compiler */
1154 uint32_t lease_seconds = 0; /* can be given as 32-bit quantity */
1155 int packet_num; 1198 int packet_num;
1156 int timeout; /* must be signed */ 1199 int timeout; /* must be signed */
1157 unsigned already_waited_sec; 1200 unsigned already_waited_sec;
1158 unsigned opt; 1201 unsigned opt;
1159 int max_fd; 1202 int max_fd;
1160 int retval; 1203 int retval;
1161 struct timeval tv;
1162 struct dhcp_packet packet;
1163 fd_set rfds; 1204 fd_set rfds;
1164 1205
1165 /* Default options */ 1206 /* Default options */
@@ -1186,9 +1227,12 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1186 , &list_x 1227 , &list_x
1187 IF_FEATURE_UDHCP_PORT(, &str_P) 1228 IF_FEATURE_UDHCP_PORT(, &str_P)
1188 IF_UDHCP_VERBOSE(, &dhcp_verbose) 1229 IF_UDHCP_VERBOSE(, &dhcp_verbose)
1189 ); 1230 );
1190 if (opt & (OPT_h|OPT_H)) 1231 if (opt & (OPT_h|OPT_H)) {
1232 //msg added 2011-11
1233 bb_error_msg("option -h NAME is deprecated, use -x hostname:NAME");
1191 client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0); 1234 client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0);
1235 }
1192 if (opt & OPT_F) { 1236 if (opt & OPT_F) {
1193 /* FQDN option format: [0x51][len][flags][0][0]<fqdn> */ 1237 /* FQDN option format: [0x51][len][flags][0][0]<fqdn> */
1194 client_config.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3); 1238 client_config.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3);
@@ -1249,8 +1293,16 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1249 clientid_mac_ptr = client_config.clientid + OPT_DATA+1; 1293 clientid_mac_ptr = client_config.clientid + OPT_DATA+1;
1250 memcpy(clientid_mac_ptr, client_config.client_mac, 6); 1294 memcpy(clientid_mac_ptr, client_config.client_mac, 6);
1251 } 1295 }
1252 if (str_V[0] != '\0') 1296 if (str_V[0] != '\0') {
1297 // can drop -V, str_V, client_config.vendorclass,
1298 // but need to add "vendor" to the list of recognized
1299 // string opts for this to work;
1300 // and need to tweak add_client_options() too...
1301 // ...so the question is, should we?
1302 //bb_error_msg("option -V VENDOR is deprecated, use -x vendor:VENDOR");
1253 client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0); 1303 client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0);
1304 }
1305
1254#if !BB_MMU 1306#if !BB_MMU
1255 /* on NOMMU reexec (i.e., background) early */ 1307 /* on NOMMU reexec (i.e., background) early */
1256 if (!(opt & OPT_f)) { 1308 if (!(opt & OPT_f)) {
@@ -1288,6 +1340,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1288 * "continue" statements in code below jump to the top of the loop. 1340 * "continue" statements in code below jump to the top of the loop.
1289 */ 1341 */
1290 for (;;) { 1342 for (;;) {
1343 struct timeval tv;
1344 struct dhcp_packet packet;
1291 /* silence "uninitialized!" warning */ 1345 /* silence "uninitialized!" warning */
1292 unsigned timestamp_before_wait = timestamp_before_wait; 1346 unsigned timestamp_before_wait = timestamp_before_wait;
1293 1347
@@ -1335,7 +1389,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1335 NULL, 1389 NULL,
1336 client_config.client_mac) 1390 client_config.client_mac)
1337 ) { 1391 ) {
1338 return 1; /* iface is gone? */ 1392 goto ret0; /* iface is gone? */
1339 } 1393 }
1340 if (clientid_mac_ptr) 1394 if (clientid_mac_ptr)
1341 memcpy(clientid_mac_ptr, client_config.client_mac, 6); 1395 memcpy(clientid_mac_ptr, client_config.client_mac, 6);
@@ -1472,13 +1526,11 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1472 timeout = 0; 1526 timeout = 0;
1473 continue; 1527 continue;
1474 case SIGUSR2: 1528 case SIGUSR2:
1475 perform_release(requested_ip, server_addr); 1529 perform_release(server_addr, requested_ip);
1476 timeout = INT_MAX; 1530 timeout = INT_MAX;
1477 continue; 1531 continue;
1478 case SIGTERM: 1532 case SIGTERM:
1479 bb_info_msg("Received SIGTERM"); 1533 bb_info_msg("Received SIGTERM");
1480 if (opt & OPT_R) /* release on quit */
1481 perform_release(requested_ip, server_addr);
1482 goto ret0; 1534 goto ret0;
1483 } 1535 }
1484 1536
@@ -1531,7 +1583,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1531 1583
1532 switch (state) { 1584 switch (state) {
1533 case INIT_SELECTING: 1585 case INIT_SELECTING:
1534 /* Must be a DHCPOFFER to one of our xid's */ 1586 /* Must be a DHCPOFFER */
1535 if (*message == DHCPOFFER) { 1587 if (*message == DHCPOFFER) {
1536/* What exactly is server's IP? There are several values. 1588/* What exactly is server's IP? There are several values.
1537 * Example DHCP offer captured with tchdump: 1589 * Example DHCP offer captured with tchdump:
@@ -1575,6 +1627,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1575 case RENEW_REQUESTED: 1627 case RENEW_REQUESTED:
1576 case REBINDING: 1628 case REBINDING:
1577 if (*message == DHCPACK) { 1629 if (*message == DHCPACK) {
1630 uint32_t lease_seconds;
1631 struct in_addr temp_addr;
1632
1578 temp = udhcp_get_option(&packet, DHCP_LEASE_TIME); 1633 temp = udhcp_get_option(&packet, DHCP_LEASE_TIME);
1579 if (!temp) { 1634 if (!temp) {
1580 bb_error_msg("no lease time with ACK, using 1 hour lease"); 1635 bb_error_msg("no lease time with ACK, using 1 hour lease");
@@ -1583,9 +1638,11 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1583 /* it IS unaligned sometimes, don't "optimize" */ 1638 /* it IS unaligned sometimes, don't "optimize" */
1584 move_from_unaligned32(lease_seconds, temp); 1639 move_from_unaligned32(lease_seconds, temp);
1585 lease_seconds = ntohl(lease_seconds); 1640 lease_seconds = ntohl(lease_seconds);
1586 lease_seconds &= 0x0fffffff; /* paranoia: must not be prone to overflows */ 1641 /* paranoia: must not be too small and not prone to overflows */
1587 if (lease_seconds < 10) /* and not too small */ 1642 if (lease_seconds < 0x10)
1588 lease_seconds = 10; 1643 lease_seconds = 0x10;
1644 if (lease_seconds >= 0x10000000)
1645 lease_seconds = 0x0fffffff;
1589 } 1646 }
1590#if ENABLE_FEATURE_UDHCPC_ARPING 1647#if ENABLE_FEATURE_UDHCPC_ARPING
1591 if (opt & OPT_a) { 1648 if (opt & OPT_a) {
@@ -1606,7 +1663,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1606 ) { 1663 ) {
1607 bb_info_msg("Offered address is in use " 1664 bb_info_msg("Offered address is in use "
1608 "(got ARP reply), declining"); 1665 "(got ARP reply), declining");
1609 send_decline(xid, server_addr, packet.yiaddr); 1666 send_decline(/*xid,*/ server_addr, packet.yiaddr);
1610 1667
1611 if (state != REQUESTING) 1668 if (state != REQUESTING)
1612 udhcp_run_script(NULL, "deconfig"); 1669 udhcp_run_script(NULL, "deconfig");
@@ -1623,20 +1680,15 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1623#endif 1680#endif
1624 /* enter bound state */ 1681 /* enter bound state */
1625 timeout = lease_seconds / 2; 1682 timeout = lease_seconds / 2;
1626 { 1683 temp_addr.s_addr = packet.yiaddr;
1627 struct in_addr temp_addr; 1684 bb_info_msg("Lease of %s obtained, lease time %u",
1628 temp_addr.s_addr = packet.yiaddr; 1685 inet_ntoa(temp_addr), (unsigned)lease_seconds);
1629 bb_info_msg("Lease of %s obtained, lease time %u",
1630 inet_ntoa(temp_addr), (unsigned)lease_seconds);
1631 }
1632 requested_ip = packet.yiaddr; 1686 requested_ip = packet.yiaddr;
1633 udhcp_run_script(&packet, state == REQUESTING ? "bound" : "renew"); 1687 udhcp_run_script(&packet, state == REQUESTING ? "bound" : "renew");
1634 1688
1635 state = BOUND; 1689 state = BOUND;
1636 change_listen_mode(LISTEN_NONE); 1690 change_listen_mode(LISTEN_NONE);
1637 if (opt & OPT_q) { /* quit after lease */ 1691 if (opt & OPT_q) { /* quit after lease */
1638 if (opt & OPT_R) /* release on quit */
1639 perform_release(requested_ip, server_addr);
1640 goto ret0; 1692 goto ret0;
1641 } 1693 }
1642 /* future renew failures should not exit (JM) */ 1694 /* future renew failures should not exit (JM) */
@@ -1648,6 +1700,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1648 opt = ((opt & ~OPT_b) | OPT_f); 1700 opt = ((opt & ~OPT_b) | OPT_f);
1649 } 1701 }
1650#endif 1702#endif
1703 /* make future renew packets use different xid */
1704 /* xid = random_xid(); ...but why bother? */
1651 already_waited_sec = 0; 1705 already_waited_sec = 0;
1652 continue; /* back to main loop */ 1706 continue; /* back to main loop */
1653 } 1707 }
@@ -1674,6 +1728,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1674 } /* for (;;) - main loop ends */ 1728 } /* for (;;) - main loop ends */
1675 1729
1676 ret0: 1730 ret0:
1731 if (opt & OPT_R) /* release on quit */
1732 perform_release(server_addr, requested_ip);
1677 retval = 0; 1733 retval = 0;
1678 ret: 1734 ret:
1679 /*if (client_config.pidfile) - remove_pidfile has its own check */ 1735 /*if (client_config.pidfile) - remove_pidfile has its own check */