[prev in list] [next in list] [prev in thread] [next in thread]
List: busybox
Subject: [PATCH] udhcpc: add support for sending DHCPINFORM requests
From: Sinan Kaya <okaya () kernel ! org>
Date: 2022-04-20 18:34:35
Message-ID: c25c9f0d-dbdf-1bc8-e427-8d6577e103ea () kernel ! org
[Download RAW message or body]
From b906997217b363c459fdbd2824bfe6c5ac69607e Mon Sep 17 00:00:00 2001
From: Sinan Kaya <okaya@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@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;
--
2.17.1
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic