+Luca

On 4/20/22 14:34, Sinan Kaya wrote:
From b906997217b363c459fdbd2824bfe6c5ac69607e Mon Sep 17 00:00:00 2001
From: Sinan Kaya <ok...@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 <ok...@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;
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to