summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/dhcpv4.c24
-rw-r--r--src/dhcpv4.h1
-rw-r--r--src/odhcpd.h2
-rw-r--r--src/ubus.c10
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);
}
diff --git a/src/ubus.c b/src/ubus.c
index b2e48cf..1bb8237 100644
--- a/src/ubus.c
+++ b/src/ubus.c
@@ -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");