[PATCH] udhcpc: add support for sending DHCPINFORM requests
Sinan Kaya
Okaya at kernel.org
Tue Jun 28 13:45:50 UTC 2022
+Luca
On 4/20/22 14:34, Sinan Kaya wrote:
> From b906997217b363c459fdbd2824bfe6c5ac69607e Mon Sep 17 00:00:00 2001
> From: Sinan Kaya <okaya at kernel.org>
> Date: Tue, 19 Apr 2022 13:47:19 +0000
> Subject: [PATCH] udhcpc: add support for sending DHCPINFORM requests
>
> It is useful for applications to be able to query DHCP options
> without renewing IP address.
>
> Tested-with: -I: for unknown DHCP server
> -I: for a specific DHCP server --server 1.2.3.4
>
> Signed-off-by: Sinan Kaya <okaya at kernel.org>
> ---
> networking/udhcp/dhcpc.c | 68 ++++++++++++++++++++++++++++++----------
> 1 file changed, 52 insertions(+), 16 deletions(-)
>
> diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
> index c757fb37c..e788613fd 100644
> --- a/networking/udhcp/dhcpc.c
> +++ b/networking/udhcp/dhcpc.c
> @@ -75,6 +75,8 @@ static const char udhcpc_longopts[] ALIGN1 =
> "background\0" No_argument "b"
> )
> "broadcast\0" No_argument "B"
> + "inform\0" No_argument "I"
> + "server\0" Required_argument "e"
> IF_FEATURE_UDHCPC_ARPING("arping\0" Optional_argument "a")
> IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P")
> ;
> @@ -100,8 +102,10 @@ enum {
> OPT_x = 1 << 16,
> OPT_f = 1 << 17,
> OPT_B = 1 << 18,
> + OPT_I = 1 << 19,
> + OPT_e = 1 << 20,
> /* The rest has variable bit positions, need to be clever */
> - OPTBIT_B = 18,
> + OPTBIT_e = 20,
> USE_FOR_MMU( OPTBIT_b,)
> IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,)
> IF_FEATURE_UDHCP_PORT( OPTBIT_P,)
> @@ -742,14 +746,15 @@ static NOINLINE int send_discover(uint32_t
> requested)
>
> /* Broadcast a DHCP request message */
> /* RFC 2131 3.1 paragraph 3:
> - * "The client _broadcasts_ a DHCPREQUEST message..."
> + * "The client _broadcasts_ a DHCPREQUEST/INFORM message..."
> */
> /* NOINLINE: limit stack usage in caller */
> -static NOINLINE int send_select(uint32_t server, uint32_t requested)
> +static NOINLINE int send_select(uint32_t server, uint32_t requested,
> int inform)
> {
> struct dhcp_packet packet;
> struct in_addr temp_addr;
> char server_str[sizeof("255.255.255.255")];
> + const char *direction;
>
> /*
> * RFC 2131 4.3.2 DHCPREQUEST message
> @@ -766,11 +771,12 @@ static NOINLINE int send_select(uint32_t server,
> uint32_t requested)
> /* Fill in: op, htype, hlen, cookie, chaddr fields,
> * xid field, message type option:
> */
> - init_packet(&packet, DHCPREQUEST);
> + init_packet(&packet, inform ? DHCPINFORM: DHCPREQUEST);
>
> udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
>
> - udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
> + if (server)
> + udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
>
> /* Add options: maxsize,
> * "param req" option according to -O, options specified with -x
> @@ -780,11 +786,19 @@ static NOINLINE int send_select(uint32_t server,
> uint32_t requested)
> temp_addr.s_addr = server;
> strcpy(server_str, inet_ntoa(temp_addr));
> temp_addr.s_addr = requested;
> - bb_info_msg("broadcasting select for %s, server %s",
> - inet_ntoa(temp_addr),
> - server_str
> + if (server)
> + direction = "unicasting";
> + else
> + direction = "broadcasting";
> +
> + bb_info_msg("%s select for %s, server %s",
> + direction,
> + inet_ntoa(temp_addr),
> + server_str
> );
> - return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY);
> +
> + // return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY);
> + return bcast_or_ucast(&packet, requested, server);
> }
>
> /* Unicast or broadcast a DHCP renew message */
> @@ -1161,9 +1175,9 @@ static void client_background(void)
> //usage:# define IF_UDHCP_VERBOSE(...)
> //usage:#endif
> //usage:#define udhcpc_trivial_usage
> -//usage: "[-fbq"IF_UDHCP_VERBOSE("v")"RB]"IF_FEATURE_UDHCPC_ARPING("
> [-a[MSEC]]")" [-t N] [-T SEC] [-A SEC|-n]\n"
> +//usage: "[-fbq"IF_UDHCP_VERBOSE("v")"RBI]"IF_FEATURE_UDHCPC_ARPING("
> [-a[MSEC]]")" [-t N] [-T SEC] [-A SEC|-n]\n"
> //usage: " [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")"
> [-s PROG] [-p PIDFILE]\n"
> -//usage: " [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x
> OPT:VAL]... [-O OPT]..."
> +//usage: " [-oC] [-r IP] [-e IP] [-V VENDOR] [-F NAME] [-x
> OPT:VAL]... [-O OPT]..."
> //usage:#define udhcpc_full_usage "\n"
> //usage: "\n -i IFACE Interface to use (default
> "CONFIG_UDHCPC_DEFAULT_INTERFACE")"
> //usage: IF_FEATURE_UDHCP_PORT(
> @@ -1172,6 +1186,7 @@ static void client_background(void)
> //usage: "\n -s PROG Run PROG at DHCP events (default
> "CONFIG_UDHCPC_DEFAULT_SCRIPT")"
> //usage: "\n -p FILE Create pidfile"
> //usage: "\n -B Request broadcast replies"
> +//usage: "\n -I Request using inform"
> //usage: "\n -t N Send up to N discover packets
> (default 3)"
> //usage: "\n -T SEC Pause between packets (default 3)"
> //usage: "\n -A SEC Wait if lease is not obtained
> (default 20)"
> @@ -1187,6 +1202,7 @@ static void client_background(void)
> //usage: "\n -a[MSEC] Validate offered address with ARP ping"
> //usage: )
> //usage: "\n -r IP Request this IP address"
> +//usage: "\n -e IP Request this server IP address"
> //usage: "\n -o Don't request any options (unless -O is
> given)"
> //usage: "\n -O OPT Request option OPT from server
> (cumulative)"
> //usage: "\n -x OPT:VAL Include option OPT in sent packets
> (cumulative)"
> @@ -1209,7 +1225,7 @@ int udhcpc_main(int argc, char **argv)
> MAIN_EXTERNALLY_VISIBLE;
> int udhcpc_main(int argc UNUSED_PARAM, char **argv)
> {
> uint8_t *message;
> - const char *str_V, *str_F, *str_r;
> + const char *str_V, *str_F, *str_r, *str_e;
> IF_FEATURE_UDHCPC_ARPING(const char *str_a = "2000";)
> IF_FEATURE_UDHCP_PORT(char *str_P;)
> uint8_t *clientid_mac_ptr;
> @@ -1218,7 +1234,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
> int tryagain_timeout = 20;
> int discover_timeout = 3;
> int discover_retries = 3;
> - uint32_t server_id = server_id; /* for compiler */
> + int use_inform = 0;
> + uint32_t server_id = 0;
> uint32_t requested_ip = 0;
> int packet_num;
> int timeout; /* must be signed */
> @@ -1244,7 +1261,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
> /* Parse command line */
> opt = getopt32long(argv, "^"
> /* O,x: list; -T,-t,-A take numeric param */
> - "CV:F:i:np:qRr:s:T:+t:+SA:+O:*ox:*fB"
> + "CV:F:i:np:qRr:s:T:+t:+SA:+O:*ox:*fBIe:"
> USE_FOR_MMU("b")
> IF_FEATURE_UDHCPC_ARPING("a::")
> IF_FEATURE_UDHCP_PORT("P:")
> @@ -1258,10 +1275,15 @@ int udhcpc_main(int argc UNUSED_PARAM, char
> **argv)
> , &discover_timeout, &discover_retries, &tryagain_timeout /*
> T,t,A */
> , &list_O
> , &list_x
> + , &str_e /* e */
> IF_FEATURE_UDHCPC_ARPING(, &str_a)
> IF_FEATURE_UDHCP_PORT(, &str_P)
> IF_UDHCP_VERBOSE(, &dhcp_verbose)
> );
> +
> + if (opt & OPT_I)
> + use_inform = 1;
> +
> if (opt & OPT_F) {
> char *p;
> unsigned len;
> @@ -1283,6 +1305,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
> /*p[OPT_DATA + 2] = 0; */
> memcpy(p + OPT_DATA + 3, str_F, len); /* do not store NUL
> byte */
> }
> + if (opt & OPT_e)
> + if (!inet_aton(str_e, (void*)&server_id))
> + bb_show_usage();
> if (opt & OPT_r)
> if (!inet_aton(str_r, (void*)&requested_ip))
> bb_show_usage();
> @@ -1368,12 +1393,23 @@ int udhcpc_main(int argc UNUSED_PARAM, char
> **argv)
> /* We want random_xid to be random... */
> srand(monotonic_us());
>
> - client_data.state = INIT_SELECTING;
> + if (use_inform) {
> + bb_simple_info_msg("using inform");
> + client_data.state = REQUESTING;
> + } else {
> + client_data.state = INIT_SELECTING;
> + }
> +
> d4_run_script_deconfig();
> packet_num = 0;
> timeout = 0;
> lease_remaining = 0;
>
> + if (use_inform) {
> + change_listen_mode(LISTEN_RAW);
> + client_data.xid = random_xid();
> + }
> +
> /* Main event loop. select() waits on signal pipe and possibly
> * on sockfd.
> * "continue" statements in code below jump to the top of the loop.
> @@ -1482,7 +1518,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
> case REQUESTING:
> if (packet_num < 3) {
> /* send broadcast select packet */
> - send_select(server_id, requested_ip);
> + send_select(server_id, requested_ip, use_inform);
> timeout = discover_timeout;
> packet_num++;
> continue;
More information about the busybox
mailing list