dhcpv4: add support for Parameter Request List option 55
authorDainis Jonitis <dainis.jonitis@ubnt.com>
Mon, 26 Nov 2018 12:36:28 +0000 (14:36 +0200)
committerHans Dedecker <dedeckeh@gmail.com>
Thu, 2 May 2019 09:25:51 +0000 (11:25 +0200)
Add client "reqopts" in ubus "ipv4leases" output.

Signed-off-by: Roman Yeryomin <roman.yeryomin@ubnt.com>
Signed-off-by: Dainis Jonitis <dainis.jonitis@ubnt.com>
src/dhcpv4.c
src/dhcpv4.h
src/odhcpd.h
src/ubus.c

index 3fb59885b09fe631693965ec8a63df29e0486201..370e1b94e805666b2074b044bec9b02b7dab37e1 100644 (file)
@@ -51,7 +51,8 @@ static void handle_dhcpv4(void *addr, void *data, size_t len,
 static struct dhcp_assignment* dhcpv4_lease(struct interface *iface,
                enum dhcpv4_msg msg, const uint8_t *mac, const uint32_t reqaddr,
                uint32_t *leasetime, const char *hostname, const size_t hostname_len,
-               const bool accept_fr_nonce, bool *incl_fr_opt, uint32_t *fr_serverid);
+               const bool accept_fr_nonce, bool *incl_fr_opt, uint32_t *fr_serverid,
+               const char *reqopts, const size_t reqopts_len);
 
 static struct netevent_handler dhcpv4_netevent_handler = { .cb = dhcpv4_netevent_cb, };
 static struct uloop_timeout valid_until_timeout = {.cb = valid_until_cb};
@@ -634,7 +635,9 @@ static void handle_dhcpv4(void *addr, void *data, size_t len,
        uint32_t reqaddr = INADDR_ANY;
        uint32_t leasetime = 0;
        size_t hostname_len = 0;
+       size_t reqopts_len = 0;
        char hostname[256];
+       char reqopts[256];
        bool accept_fr_nonce = false;
        bool incl_fr_opt = false;
 
@@ -644,7 +647,11 @@ static void handle_dhcpv4(void *addr, void *data, size_t len,
        dhcpv4_for_each_option(start, end, opt) {
                if (opt->type == DHCPV4_OPT_MESSAGE && opt->len == 1)
                        reqmsg = opt->data[0];
-               else if (opt->type == DHCPV4_OPT_HOSTNAME && opt->len > 0) {
+               else if (opt->type == DHCPV4_OPT_REQOPTS && opt->len > 0) {
+                       reqopts_len = opt->len;
+                       memcpy(reqopts, opt->data, reqopts_len);
+                       reqopts[reqopts_len] = 0;
+               } else if (opt->type == DHCPV4_OPT_HOSTNAME && opt->len > 0) {
                        hostname_len = opt->len;
                        memcpy(hostname, opt->data, hostname_len);
                        hostname[hostname_len] = 0;
@@ -685,7 +692,8 @@ static void handle_dhcpv4(void *addr, void *data, size_t len,
        if (reqmsg != DHCPV4_MSG_INFORM)
                a = dhcpv4_lease(iface, reqmsg, req->chaddr, reqaddr,
                                 &leasetime, hostname, hostname_len,
-                                accept_fr_nonce, &incl_fr_opt, &fr_serverid);
+                                accept_fr_nonce, &incl_fr_opt, &fr_serverid,
+                                reqopts, reqopts_len);
 
        if (!a) {
                if (reqmsg == DHCPV4_MSG_REQUEST)
@@ -997,7 +1005,7 @@ static struct dhcp_assignment*
 dhcpv4_lease(struct interface *iface, enum dhcpv4_msg msg, const uint8_t *mac,
             const uint32_t reqaddr, uint32_t *leasetime, const char *hostname,
             const size_t hostname_len, const bool accept_fr_nonce, bool *incl_fr_opt,
-            uint32_t *fr_serverid)
+            uint32_t *fr_serverid, const char* reqopts, const size_t reqopts_len)
 {
        struct dhcp_assignment *a = find_assignment_by_hwaddr(iface, mac);
        struct lease *l = config_find_lease_by_mac(mac);
@@ -1089,6 +1097,14 @@ dhcpv4_lease(struct interface *iface, enum dhcpv4_msg msg, const uint8_t *mac,
                                        }
                                }
 
+                               if (reqopts_len > 0) {
+                                       a->reqopts = realloc(a->reqopts, reqopts_len + 1);
+                                       if (a->reqopts) {
+                                               memcpy(a->reqopts, reqopts, reqopts_len);
+                                               a->reqopts[reqopts_len] = 0;
+                                       }
+                               }
+
                                if (!(a->flags & OAF_BOUND)) {
                                        a->accept_fr_nonce = accept_fr_nonce;
                                        *incl_fr_opt = accept_fr_nonce;
index 505346f6b605d646d74da69e700e47d4061891b0..b378bc17165f65f44fa8eb48690f74240e64a10f 100644 (file)
@@ -50,6 +50,7 @@ enum dhcpv4_opt {
        DHCPV4_OPT_LEASETIME = 51,
        DHCPV4_OPT_MESSAGE = 53,
        DHCPV4_OPT_SERVERID = 54,
+       DHCPV4_OPT_REQOPTS = 55,
        DHCPV4_OPT_RENEW = 58,
        DHCPV4_OPT_REBIND = 59,
        DHCPV4_OPT_IPADDRESS = 50,
index 97d2113571326b06c287d49ee6dee38843ad39bf..9535e752a12c61d3f2a61323757a301e90f32916 100644 (file)
@@ -189,6 +189,7 @@ struct dhcp_assignment {
        unsigned int flags;
        uint32_t leasetime;
        char *hostname;
+       char *reqopts;
 #define hwaddr         mac
        uint8_t mac[6];
 
@@ -318,6 +319,7 @@ inline static void free_assignment(struct dhcp_assignment *a)
                a->dhcp_free_cb(a);
 
        free(a->hostname);
+       free(a->reqopts);
        free(a);
 }
 
index b2e48cf184ca69cdd1e5be5f42fb5d29b224672e..1bb8237eb42d9ce4b90a1d506a79cdce25f7c31c 100644 (file)
@@ -49,6 +49,16 @@ static int handle_dhcpv4_leases(struct ubus_context *ctx, _unused struct ubus_ob
                        blobmsg_add_string(&b, "hostname", (c->hostname) ? c->hostname : "");
                        blobmsg_add_u8(&b, "accept-reconf-nonce", c->accept_fr_nonce);
 
+                       if (c->reqopts) {
+                               int opt = 0;
+                               int chars = 0;
+                               buf = blobmsg_alloc_string_buffer(&b, "reqopts", strlen(c->reqopts) * 4 + 1);
+                               for(; c->reqopts[opt]; opt++)
+                                       chars += snprintf(buf + chars, 6, "%u,", (uint8_t)c->reqopts[opt]);
+                               buf[chars - 1] = '\0';
+                               blobmsg_add_string_buffer(&b);
+                       }
+
                        m = blobmsg_open_array(&b, "flags");
                        if (c->flags & OAF_BOUND)
                                blobmsg_add_string(&b, NULL, "bound");