diff options
-rw-r--r-- | src/dhcpv4.c | 24 | ||||
-rw-r--r-- | src/dhcpv4.h | 1 | ||||
-rw-r--r-- | src/odhcpd.h | 2 | ||||
-rw-r--r-- | src/ubus.c | 10 |
4 files changed, 33 insertions, 4 deletions
diff --git a/src/dhcpv4.c b/src/dhcpv4.c index 3fb5988..370e1b9 100644 --- a/src/dhcpv4.c +++ b/src/dhcpv4.c @@ -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; diff --git a/src/dhcpv4.h b/src/dhcpv4.h index 505346f..b378bc1 100644 --- a/src/dhcpv4.h +++ b/src/dhcpv4.h @@ -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, diff --git a/src/odhcpd.h b/src/odhcpd.h index 97d2113..9535e75 100644 --- a/src/odhcpd.h +++ b/src/odhcpd.h @@ -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); } @@ -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"); |