diff options
author | Hans Dedecker <dedeckeh@gmail.com> | 2019-02-13 11:07:38 +0100 |
---|---|---|
committer | Hans Dedecker <dedeckeh@gmail.com> | 2019-02-13 12:01:26 +0100 |
commit | 1ae316e330acb49d3fb3279be4452fd3e1b732c4 (patch) | |
tree | eb09e6b5382e2fbe7d99735139f015ae2713974e /src | |
parent | 80157e185f63dfdb1194e7da2492574892d8b900 (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>
Diffstat (limited to 'src')
-rw-r--r-- | src/dhcpv6.c | 28 |
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 || |