From 2859741d971efaed279585e9d7ad3aafa49d936a Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20H=C3=A4rdeman?= Date: Sun, 11 Feb 2024 13:09:53 +0100 Subject: [PATCH] dhcpv4: store reqopts as uint8_t MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Storing request options as chars means that it's difficult to handle option codes > 127 due to the signedness of char (and options aren't chars, they're binary data). Signed-off-by: David Härdeman --- src/dhcpv4.c | 19 ++++++++++--------- src/odhcpd.h | 4 +++- src/ubus.c | 13 ++++++------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/dhcpv4.c b/src/dhcpv4.c index cb0484f..65a4b41 100644 --- a/src/dhcpv4.c +++ b/src/dhcpv4.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -53,7 +54,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, - const char *reqopts, const size_t reqopts_len); + const uint8_t *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}; @@ -654,10 +655,10 @@ void dhcpv4_handle_msg(void *addr, void *data, size_t len, uint32_t reqaddr = INADDR_ANY; uint32_t leasetime = 0; + char hostname[256]; size_t hostname_len = 0; + uint8_t *reqopts = NULL; size_t reqopts_len = 0; - char hostname[256]; - char reqopts[256]; bool accept_fr_nonce = false; bool incl_fr_opt = false; @@ -669,8 +670,8 @@ void dhcpv4_handle_msg(void *addr, void *data, size_t len, reqmsg = opt->data[0]; else if (opt->type == DHCPV4_OPT_REQOPTS && opt->len > 0) { reqopts_len = opt->len; + reqopts = alloca(reqopts_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); @@ -850,8 +851,8 @@ void dhcpv4_handle_msg(void *addr, void *data, size_t len, dhcpv4_put(&reply, &cookie, DHCPV4_OPT_DNSSERVER, 4 * iface->dhcpv4_dns_cnt, iface->dhcpv4_dns); - if (a && a->reqopts && iface->dhcpv4_ntp_cnt != 0) { - for(size_t opts = 0; a->reqopts[opts]; opts++) { + if (a && iface->dhcpv4_ntp_cnt != 0) { + for (size_t opts = 0; opts < a->reqopts_len; opts++) { if (a->reqopts[opts] == DHCPV4_OPT_NTPSERVER) { dhcpv4_put(&reply, &cookie, DHCPV4_OPT_NTPSERVER, 4 * iface->dhcpv4_ntp_cnt, iface->dhcpv4_ntp); @@ -1035,7 +1036,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, const char* reqopts, const size_t reqopts_len) + uint32_t *fr_serverid, const uint8_t *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); @@ -1127,10 +1128,10 @@ 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); + a->reqopts = realloc(a->reqopts, reqopts_len); if (a->reqopts) { memcpy(a->reqopts, reqopts, reqopts_len); - a->reqopts[reqopts_len] = 0; + a->reqopts_len = reqopts_len; } } diff --git a/src/odhcpd.h b/src/odhcpd.h index 7a82e98..156cec0 100644 --- a/src/odhcpd.h +++ b/src/odhcpd.h @@ -231,7 +231,9 @@ struct dhcp_assignment { unsigned int flags; uint32_t leasetime; char *hostname; - char *reqopts; + uint8_t *reqopts; + size_t reqopts_len; + #define hwaddr mac uint8_t mac[6]; diff --git a/src/ubus.c b/src/ubus.c index 45b29a4..be3deac 100644 --- a/src/ubus.c +++ b/src/ubus.c @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -49,13 +50,11 @@ 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'; + if (c->reqopts_len > 0) { + buf = blobmsg_alloc_string_buffer(&b, "reqopts", c->reqopts_len * 4 + 1); + for (size_t i = 0; i < c->reqopts_len; i++) + buf += snprintf(buf, 5, "%" PRIu8 ",", c->reqopts[i]); + buf[-1] = '\0'; blobmsg_add_string_buffer(&b); } -- 2.30.2