---
networking/udhcp/d6_dhcpc.c | 79 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 71 insertions(+), 8 deletions(-)
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index 3c61292..d0f8593 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -125,6 +125,7 @@ static const char udhcpc6_longopts[] ALIGN1 =
"request-option\0" Required_argument "O"
"no-default-options\0" No_argument "o"
"foreground\0" No_argument "f"
+ "stateless\0" No_argument "l"
USE_FOR_MMU(
"background\0" No_argument "b"
)
@@ -149,9 +150,10 @@ enum {
OPT_o = 1 << 12,
OPT_x = 1 << 13,
OPT_f = 1 << 14,
- OPT_d = 1 << 15,
+ OPT_l = 1 << 15,
+ OPT_d = 1 << 16,
/* The rest has variable bit positions, need to be clever */
- OPTBIT_d = 15,
+ OPTBIT_d = 16,
USE_FOR_MMU( OPTBIT_b,)
///IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,)
IF_FEATURE_UDHCP_PORT( OPTBIT_P,)
@@ -841,6 +843,45 @@ int send_d6_release(struct in6_addr *server_ipv6, struct
in6_addr *our_cur_ipv6)
);
}
+/* RFC 3315 18.1.5. Creation and Transmission of Information-request Messages
+
+ The client uses an Information-request message to obtain
+ configuration information without having addresses assigned to it.
+
+ The client sets the "msg-type" field to INFORMATION-REQUEST. The
+ client generates a transaction ID and inserts this value in the
+ "transaction-id" field.
+
+ The client SHOULD include a Client Identifier option to identify
+ itself to the server. If the client does not include a Client
+ Identifier option, the server will not be able to return any client-
+ specific options to the client, or the server may choose not to
+ respond to the message at all. The client MUST include a Client
+ Identifier option if the Information-Request message will be
+ authenticated.
+
+ The client MUST include an Option Request option (see section 22.7)
+ to indicate the options the client is interested in receiving. The
+ client MAY include options with data values as hints to the server
+ about parameter values the client would like to have returned.
+*/
+
+/* NOINLINE: limit stack usage in caller */
+static NOINLINE int send_d6_info(uint32_t xid)
+{
+ struct d6_packet packet;
+ uint8_t *opt_ptr;
+ unsigned len;
+
+ /* Fill in: msg type, client id */
+ opt_ptr = init_d6_packet(&packet, D6_MSG_INFORMATION_REQUEST, xid);
+
+ opt_ptr = add_d6_client_options(opt_ptr);
+
+ bb_error_msg("sending %s", "info");
+ return d6_mcast_from_client_config_ifindex(&packet, opt_ptr);
+}
+
/* Returns -1 on errors that are fatal for the socket, -2 for those that
aren't */
/* NOINLINE: limit stack usage in caller */
static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6, struct
d6_packet *d6_pkt, int fd)
@@ -1117,6 +1158,7 @@ static void client_background(void)
//usage: "\n -T N Pause between packets (default 3
seconds)"
//usage: "\n -A N Wait N seconds (default 20) after
failure"
//usage: "\n -f Run in foreground"
+//usage: "\n -l Use stateless mode, only send
informational request and dont request ip"
//usage: USE_FOR_MMU(
//usage: "\n -b Background if lease is not obtained"
//usage: )
@@ -1159,6 +1201,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
int tryagain_timeout = 20;
int discover_timeout = 3;
int discover_retries = 3;
+ int stateless_timeout = 86400;
struct in6_addr srv6_buf;
struct in6_addr ipv6_buf;
struct in6_addr *requested_ipv6;
@@ -1182,7 +1225,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
/* Parse command line */
opt = getopt32long(argv, "^"
/* O,x: list; -T,-t,-A take numeric param */
- "i:np:qRr:s:T:+t:+SA:+O:*ox:*fd"
+ "i:np:qRr:s:T:+t:+SA:+O:*ox:*fld"
USE_FOR_MMU("b")
///IF_FEATURE_UDHCPC_ARPING("a")
IF_FEATURE_UDHCP_PORT("P:")
@@ -1208,6 +1251,11 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
requested_ipv6 = &ipv6_buf;
}
}
+
+ if (opt & OPT_l) {
+ /* no ip request when stateless */
+ option_mask32 = option_mask32 & ~OPT_r;
+ }
#if ENABLE_FEATURE_UDHCP_PORT
if (opt & OPT_P) {
CLIENT_PORT6 = xatou16(str_P);
@@ -1358,7 +1406,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
if (packet_num == 0)
xid = random_xid();
/* multicast */
- send_d6_discover(xid, requested_ipv6);
+ if(opt & OPT_l)
+ send_d6_info(xid);
+ else
+ send_d6_discover(xid,
requested_ipv6);
timeout = discover_timeout;
packet_num++;
continue;
@@ -1401,7 +1452,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
/* 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);
+ if(opt & OPT_l)
+ change_listen_mode(LISTEN_RAW);
+ else
+ change_listen_mode(LISTEN_KERNEL);
log1("entering renew state");
/* fall right through */
case RENEW_REQUESTED: /* manual (SIGUSR1) renew */
@@ -1417,7 +1471,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
* Anyway, it does recover by eventually failing through
* into INIT_SELECTING state.
*/
- send_d6_renew(xid, &srv6_buf,
requested_ipv6);
+ if(opt & OPT_l)
+ send_d6_info(xid);
+ else
+ send_d6_renew(xid, &srv6_buf,
requested_ipv6);
timeout >>= 1;
continue;
}
@@ -1431,8 +1488,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
/* Lease is *really* about to run out,
* try to find DHCP server using broadcast */
if (timeout > 0) {
- /* send a broadcast renew request */
- send_d6_renew(xid, /*server_ipv6:*/
NULL, requested_ipv6);
+ if(opt & OPT_l)
+ send_d6_info(xid);
+ else /* send a broadcast renew request
*/
+ send_d6_renew(xid,
/*server_ipv6:*/ NULL, requested_ipv6);
timeout >>= 1;
continue;
}
@@ -1739,6 +1798,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
prefix_timeout = address_timeout;
/* note: "int timeout" will not overflow even
with 0xffffffff inputs here: */
timeout = (prefix_timeout < address_timeout ?
prefix_timeout : address_timeout) / 2;
+
+ if(opt & OPT_l) /* no lease timeout will be
received, use stateless timeout */
+ timeout = stateless_timeout;
+
/* paranoia: must not be too small */
/* timeout > 60 - ensures at least one unicast
renew attempt */
if (timeout < 61)
--
2.7.4
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox