udhcpc6: support stateless DHCPv6
-l will send Information-Request to request configuration parameters function old new delta packed_usage 33114 33180 +66 send_d6_info_request - 62 +62 udhcpc6_main 2534 2593 +59 udhcpc6_longopts 199 211 +12 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 3/0 up/down: 199/0) Total: 199 bytes Signed-off-by: Eivind Versvik <versvikeivind@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
ac78f2ac96
commit
22a6339627
@ -123,6 +123,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"
|
||||
)
|
||||
@ -147,9 +148,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,)
|
||||
@ -544,6 +546,46 @@ static int d6_mcast_from_client_data_ifindex(struct d6_packet *packet, uint8_t *
|
||||
);
|
||||
}
|
||||
|
||||
/* 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_request(uint32_t xid)
|
||||
{
|
||||
struct d6_packet packet;
|
||||
uint8_t *opt_ptr;
|
||||
|
||||
/* Fill in: msg type, client id */
|
||||
opt_ptr = init_d6_packet(&packet, D6_MSG_INFORMATION_REQUEST, xid);
|
||||
|
||||
/* Add options:
|
||||
* "param req" option according to -O, options specified with -x
|
||||
*/
|
||||
opt_ptr = add_d6_client_options(opt_ptr);
|
||||
|
||||
bb_error_msg("sending %s", "info request");
|
||||
return d6_mcast_from_client_data_ifindex(&packet, opt_ptr);
|
||||
}
|
||||
|
||||
/* Milticast a DHCPv6 Solicit packet to the network, with an optionally requested IP.
|
||||
*
|
||||
* RFC 3315 17.1.1. Creation of Solicit Messages
|
||||
@ -1129,6 +1171,8 @@ static void client_background(void)
|
||||
//usage: "\n -o Don't request any options (unless -O is given)"
|
||||
//usage: "\n -r IPv6 Request this address ('no' to not request any IP)"
|
||||
//usage: "\n -d Request prefix"
|
||||
//usage: "\n -l Send 'information request' instead of 'solicit'"
|
||||
//usage: "\n (used for servers which do not assign IPv6 addresses)"
|
||||
//usage: "\n -x OPT:VAL Include option OPT in sent packets (cumulative)"
|
||||
//usage: "\n Examples of string, numeric, and hex byte opts:"
|
||||
//usage: "\n -x hostname:bbox - option 12"
|
||||
@ -1181,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:")
|
||||
@ -1198,15 +1242,20 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
|
||||
);
|
||||
requested_ipv6 = NULL;
|
||||
option_mask32 |= OPT_r;
|
||||
if (opt & OPT_r) {
|
||||
if (opt & OPT_l) {
|
||||
/* for -l, do not require IPv6 assignment from server */
|
||||
option_mask32 &= ~OPT_r;
|
||||
} else if (opt & OPT_r) {
|
||||
/* explicit "-r ARG" given */
|
||||
if (strcmp(str_r, "no") == 0) {
|
||||
option_mask32 -= OPT_r;
|
||||
option_mask32 &= ~OPT_r;
|
||||
} else {
|
||||
if (inet_pton(AF_INET6, str_r, &ipv6_buf) <= 0)
|
||||
bb_error_msg_and_die("bad IPv6 address '%s'", str_r);
|
||||
requested_ipv6 = &ipv6_buf;
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_FEATURE_UDHCP_PORT
|
||||
if (opt & OPT_P) {
|
||||
CLIENT_PORT6 = xatou16(str_P);
|
||||
@ -1353,7 +1402,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_request(xid);
|
||||
else
|
||||
send_d6_discover(xid, requested_ipv6);
|
||||
timeout = discover_timeout;
|
||||
packet_num++;
|
||||
continue;
|
||||
@ -1418,7 +1470,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_request(xid);
|
||||
else
|
||||
send_d6_renew(xid, &srv6_buf, requested_ipv6);
|
||||
timeout >>= 1;
|
||||
continue;
|
||||
}
|
||||
@ -1432,8 +1487,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_request(xid);
|
||||
else /* send a broadcast renew request */
|
||||
send_d6_renew(xid, /*server_ipv6:*/ NULL, requested_ipv6);
|
||||
timeout >>= 1;
|
||||
continue;
|
||||
}
|
||||
@ -1740,6 +1797,12 @@ 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) {
|
||||
/* TODO: request OPTION_INFORMATION_REFRESH_TIME (32)
|
||||
* and use its value instead of the default 1 day.
|
||||
*/
|
||||
timeout = 24 * 60 * 60;
|
||||
}
|
||||
/* paranoia: must not be too small */
|
||||
/* timeout > 60 - ensures at least one unicast renew attempt */
|
||||
if (timeout < 61)
|
||||
|
Loading…
Reference in New Issue
Block a user