summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHans Dedecker <dedeckeh@gmail.com>2019-02-13 11:07:38 +0100
committerHans Dedecker <dedeckeh@gmail.com>2019-02-13 12:01:26 +0100
commit1ae316e330acb49d3fb3279be4452fd3e1b732c4 (patch)
treeeb09e6b5382e2fbe7d99735139f015ae2713974e
parent80157e185f63dfdb1194e7da2492574892d8b900 (diff)
dhcpv6: fix parsing of DHCPv6 relay messages
Commit 0db69b0b85c83fedd74ac77e850669a17c4e6617 broke parsing of DHCPv6 relay messages as the DHCPv6 client header pointer was not updated after parsing the nested relay forward message(s). Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
-rw-r--r--src/dhcpv6.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/src/dhcpv6.c b/src/dhcpv6.c
index 400e988..a40c353 100644
--- a/src/dhcpv6.c
+++ b/src/dhcpv6.c
@@ -176,9 +176,13 @@ enum {
};
static void handle_nested_message(uint8_t *data, size_t len,
- uint8_t **opts, uint8_t **end, struct iovec iov[IOV_TOTAL])
+ struct dhcpv6_client_header **c_hdr, uint8_t **opts,
+ uint8_t **end, struct iovec iov[IOV_TOTAL])
{
- struct dhcpv6_relay_header *hdr = (struct dhcpv6_relay_header*)data;
+ struct dhcpv6_relay_header *r_hdr = (struct dhcpv6_relay_header *)data;
+ uint16_t otype, olen;
+ uint8_t *odata;
+
if (iov[IOV_NESTED].iov_base == NULL) {
iov[IOV_NESTED].iov_base = data;
iov[IOV_NESTED].iov_len = len;
@@ -187,22 +191,20 @@ static void handle_nested_message(uint8_t *data, size_t len,
if (len < sizeof(struct dhcpv6_client_header))
return;
- if (hdr->msg_type != DHCPV6_MSG_RELAY_FORW) {
- iov[IOV_NESTED].iov_len = data - (uint8_t*)iov[IOV_NESTED].iov_base;
- struct dhcpv6_client_header *hdr = (void*)data;
- *opts = (uint8_t*)&hdr[1];
+ if (r_hdr->msg_type != DHCPV6_MSG_RELAY_FORW) {
+ iov[IOV_NESTED].iov_len = data - (uint8_t *)iov[IOV_NESTED].iov_base;
+ *c_hdr = (void *)data;
+ *opts = (uint8_t *)&(*c_hdr)[1];
*end = data + len;
return;
}
- uint16_t otype, olen;
- uint8_t *odata;
- dhcpv6_for_each_option(hdr->options, data + len, otype, olen, odata) {
+ dhcpv6_for_each_option(r_hdr->options, data + len, otype, olen, odata) {
if (otype == DHCPV6_OPT_RELAY_MSG) {
iov[IOV_RELAY_MSG].iov_base = odata + olen;
- iov[IOV_RELAY_MSG].iov_len = (((uint8_t*)iov[IOV_NESTED].iov_base) +
+ iov[IOV_RELAY_MSG].iov_len = (((uint8_t *)iov[IOV_NESTED].iov_base) +
iov[IOV_NESTED].iov_len) - (odata + olen);
- handle_nested_message(odata, olen, opts, end, iov);
+ handle_nested_message(odata, olen, c_hdr, opts, end, iov);
return;
}
}
@@ -346,7 +348,7 @@ static void handle_client_request(void *addr, void *data, size_t len,
uint8_t *opts = (uint8_t*)&hdr[1], *opts_end = (uint8_t*)data + len;
if (hdr->msg_type == DHCPV6_MSG_RELAY_FORW)
- handle_nested_message(data, len, &opts, &opts_end, iov);
+ handle_nested_message(data, len, &hdr, &opts, &opts_end, iov);
memcpy(dest.tr_id, hdr->transaction_id, sizeof(dest.tr_id));
@@ -421,7 +423,7 @@ static void handle_client_request(void *addr, void *data, size_t len,
}
if (hdr->msg_type != DHCPV6_MSG_INFORMATION_REQUEST) {
- ssize_t ialen = dhcpv6_ia_handle_IAs(pdbuf, sizeof(pdbuf), iface, addr, data, opts_end);
+ ssize_t ialen = dhcpv6_ia_handle_IAs(pdbuf, sizeof(pdbuf), iface, addr, (const void *)hdr, opts_end);
iov[IOV_PDBUF].iov_len = ialen;
if (ialen < 0 ||