← Commit list

ef21820dc

Laurent Bercot
Laurent Bercot
2025-02-09
SUCCESS Duration: 157s

Subject

udhcpc6: improvements

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

networking/udhcp/d6_dhcpc.c+63 -25
@@ -148,10 +148,11 @@ enum {
OPT_o = 1 << 12,
OPT_x = 1 << 13,
OPT_f = 1 << 14,
- OPT_l = 1 << 15,
- OPT_d = 1 << 16,
+ OPT_m = 1 << 15,
+ OPT_l = 1 << 16,
+ OPT_d = 1 << 17,
/* The rest has variable bit positions, need to be clever */
- OPTBIT_d = 16,
+ OPTBIT_d = 17,
USE_FOR_MMU( OPTBIT_b,)
///IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,)
IF_FEATURE_UDHCP_PORT( OPTBIT_P,)
@@ -268,6 +269,23 @@ static void option_to_env(const uint8_t *option, const uint8_t *option_end)
//case D6_OPT_SERVERID:
case D6_OPT_IA_NA:
case D6_OPT_IA_PD:
+/* 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | OPTION_IA_PD | option-length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IAID (4 octets) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | T1 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | T2 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * . .
+ * . IA_PD-options .
+ * . .
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ /* recurse to handle "IA_PD-options" field */
option_to_env(option + 16, option + 4 + option[3]);
break;
//case D6_OPT_IA_TA:
@@ -1131,12 +1149,11 @@ static void client_background(void)
//usage:#endif
//usage:#define udhcpc6_trivial_usage
//usage: "[-fbq"IF_UDHCP_VERBOSE("v")"R] [-t N] [-T SEC] [-A SEC|-n] [-i IFACE] [-s PROG]\n"
-//usage: " [-p PIDFILE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-ldo] [-r IPv6] [-x OPT:VAL]... [-O OPT]..."
+//usage: " [-p PIDFILE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-mldo] [-r IPv6] [-x OPT:VAL]... [-O OPT]..."
//usage:#define udhcpc6_full_usage "\n"
//usage: "\n -i IFACE Interface to use (default "CONFIG_UDHCPC_DEFAULT_INTERFACE")"
//usage: "\n -p FILE Create pidfile"
//usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC6_DEFAULT_SCRIPT")"
-//usage: "\n -B Request broadcast replies"
//usage: "\n -t N Send up to N discover packets"
//usage: "\n -T SEC Pause between packets (default 3)"
//usage: "\n -A SEC Wait if lease is not obtained (default 20)"
@@ -1154,6 +1171,7 @@ static void client_background(void)
////usage: IF_FEATURE_UDHCPC_ARPING(
////usage: "\n -a Use arping to validate offered address"
////usage: )
+//usage: "\n -m Send multicast renew requests rather than unicast ones"
//usage: "\n -l Send 'information request' instead of 'solicit'"
//usage: "\n (used for servers which do not assign IPv6 addresses)"
//usage: "\n -r IPv6 Request this address ('no' to not request any IP)"
@@ -1211,7 +1229,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:*fld"
+ "i:np:qRr:s:T:+t:+SA:+O:*ox:*fmld"
USE_FOR_MMU("b")
///IF_FEATURE_UDHCPC_ARPING("a")
IF_FEATURE_UDHCP_PORT("P:")
@@ -1464,7 +1482,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
if (opt & OPT_l)
send_d6_info_request();
else
- send_d6_renew(&srv6_buf, requested_ipv6);
+ send_d6_renew(OPT_m ? NULL : &srv6_buf, requested_ipv6);
timeout = discover_timeout;
packet_num++;
continue;
@@ -1617,8 +1635,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
address_timeout = 0;
prefix_timeout = 0;
option = d6_find_option(packet.d6_options, packet_end, D6_OPT_STATUS_CODE);
- if (option && (option->data[0] | option->data[1]) != 0) {
-///FIXME:
+ if (option) {
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | OPTION_STATUS_CODE | option-len |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -1626,21 +1643,28 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
// . status-message .
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// so why do we think it's NAK if data[0] is zero but data[1] is not? That's wrong...
-// we should also check that option->len is ok (i.e. not 0), right?
- /* return to init state */
- bb_info_msg("received DHCP NAK (%u)", option->data[4]);
- d6_run_script(packet.d6_options,
- packet_end, "nak");
- if (client_data.state != REQUESTING)
- d6_run_script_no_option("deconfig");
- sleep(3); /* avoid excessive network traffic */
- client_data.state = INIT_SELECTING;
- client_data.first_secs = 0; /* make secs field count from 0 */
- requested_ipv6 = NULL;
- timeout = 0;
- packet_num = 0;
- continue;
+ unsigned len, status;
+ len = ((unsigned)option->len_hi << 8) + option->len;
+ if (len < 2) {
+ bb_simple_error_msg("invalid OPTION_STATUS_CODE, ignoring packet");
+ continue;
+ }
+ status = ((unsigned)option->data[0] << 8) + option->data[1];
+ if (status != 0) {
+//TODO: handle status == 5 (UseMulticast)?
+ /* return to init state */
+ bb_info_msg("received DHCP NAK: %u '%.*s'", status, len - 2, option->data + 2);
+ d6_run_script(packet.d6_options, packet_end, "nak");
+ if (client_data.state != REQUESTING)
+ d6_run_script_no_option("deconfig");
+ sleep(3); /* avoid excessive network traffic */
+ client_data.state = INIT_SELECTING;
+ client_data.first_secs = 0; /* make secs field count from 0 */
+ requested_ipv6 = NULL;
+ timeout = 0;
+ packet_num = 0;
+ continue;
+ }
}
option = d6_copy_option(packet.d6_options, packet_end, D6_OPT_SERVERID);
if (!option) {
@@ -1661,7 +1685,6 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
packet_num = 0;
continue;
}
- /* It's a D6_MSG_REPLY */
/*
* RFC 3315 18.1.8. Receipt of Reply Messages
*
@@ -1790,6 +1813,21 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
free(client6_data.ia_pd);
client6_data.ia_pd = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_PD);
+// 0 1 2 3
+// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | OPTION_IA_PD | option-length |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | IAID (4 octets) |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | T1 |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | T2 |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// . .
+// . IA_PD-options .
+// . .
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
if (!client6_data.ia_pd) {
bb_info_msg("no %s option%s", "IA_PD", ", ignoring packet");
continue;
networking/udhcp/d6_packet.c+9 -7
@@ -153,13 +153,15 @@ int FAST_FUNC d6_send_kernel_packet_from_client_data_ifindex(
}
setsockopt_reuseaddr(fd);
- memset(&sa, 0, sizeof(sa));
- sa.sin6_family = AF_INET6;
- sa.sin6_port = htons(source_port);
- sa.sin6_addr = *src_ipv6; /* struct copy */
- if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
- msg = "bind(%s)";
- goto ret_close;
+ if (src_ipv6) {
+ memset(&sa, 0, sizeof(sa));
+ sa.sin6_family = AF_INET6;
+ sa.sin6_port = htons(source_port);
+ sa.sin6_addr = *src_ipv6; /* struct copy */
+ if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
+ msg = "bind(%s)";
+ goto ret_close;
+ }
}
memset(&sa, 0, sizeof(sa));