dhcp6: use unaligned read/write helpers
This commit is contained in:
@@ -24,31 +24,37 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "sparse-endian.h"
|
||||
#include "unaligned.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "dhcp6-internal.h"
|
||||
#include "dhcp6-protocol.h"
|
||||
|
||||
#define DHCP6_OPTION_HDR_LEN 4
|
||||
#define DHCP6_OPTION_IA_NA_LEN 12
|
||||
#define DHCP6_OPTION_IA_TA_LEN 4
|
||||
|
||||
typedef struct DHCP6Option {
|
||||
be16_t code;
|
||||
be16_t len;
|
||||
uint8_t data[];
|
||||
} DHCP6Option;
|
||||
|
||||
static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode,
|
||||
size_t optlen) {
|
||||
DHCP6Option *option = (DHCP6Option*) *buf; /* unaligned! */
|
||||
|
||||
assert_return(buf, -EINVAL);
|
||||
assert_return(*buf, -EINVAL);
|
||||
assert_return(buflen, -EINVAL);
|
||||
|
||||
if (optlen > 0xffff || *buflen < optlen + DHCP6_OPTION_HDR_LEN)
|
||||
if (optlen > 0xffff || *buflen < optlen + sizeof(DHCP6Option))
|
||||
return -ENOBUFS;
|
||||
|
||||
(*buf)[0] = optcode >> 8;
|
||||
(*buf)[1] = optcode & 0xff;
|
||||
(*buf)[2] = optlen >> 8;
|
||||
(*buf)[3] = optlen & 0xff;
|
||||
unaligned_write_be16(&option->code, optcode);
|
||||
unaligned_write_be16(&option->len, (uint16_t) optlen);
|
||||
|
||||
*buf += DHCP6_OPTION_HDR_LEN;
|
||||
*buflen -= DHCP6_OPTION_HDR_LEN;
|
||||
*buf += sizeof(DHCP6Option);
|
||||
*buflen -= sizeof(DHCP6Option);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -100,8 +106,8 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
|
||||
ia_hdr = *buf;
|
||||
ia_buflen = *buflen;
|
||||
|
||||
*buf += DHCP6_OPTION_HDR_LEN;
|
||||
*buflen -= DHCP6_OPTION_HDR_LEN;
|
||||
*buf += sizeof(DHCP6Option);
|
||||
*buflen -= sizeof(DHCP6Option);
|
||||
|
||||
memcpy(*buf, &ia->id, len);
|
||||
|
||||
@@ -119,7 +125,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
|
||||
*buf += sizeof(addr->iaaddr);
|
||||
*buflen -= sizeof(addr->iaaddr);
|
||||
|
||||
ia_addrlen += DHCP6_OPTION_HDR_LEN + sizeof(addr->iaaddr);
|
||||
ia_addrlen += sizeof(DHCP6Option) + sizeof(addr->iaaddr);
|
||||
}
|
||||
|
||||
r = option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
|
||||
@@ -130,23 +136,24 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
|
||||
}
|
||||
|
||||
|
||||
static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *opt,
|
||||
static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *optcode,
|
||||
size_t *optlen) {
|
||||
DHCP6Option *option = (DHCP6Option*) *buf; /* unaligned! */
|
||||
uint16_t len;
|
||||
|
||||
assert_return(buf, -EINVAL);
|
||||
assert_return(opt, -EINVAL);
|
||||
assert_return(optcode, -EINVAL);
|
||||
assert_return(optlen, -EINVAL);
|
||||
|
||||
if (*buflen < 4)
|
||||
if (*buflen < sizeof(DHCP6Option))
|
||||
return -ENOMSG;
|
||||
|
||||
len = (*buf)[2] << 8 | (*buf)[3];
|
||||
len = unaligned_read_be16(&option->len);
|
||||
|
||||
if (len > *buflen)
|
||||
return -ENOMSG;
|
||||
|
||||
*opt = (*buf)[0] << 8 | (*buf)[1];
|
||||
*optcode = unaligned_read_be16(&option->code);
|
||||
*optlen = len;
|
||||
|
||||
*buf += 4;
|
||||
@@ -190,7 +197,7 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
|
||||
switch (iatype) {
|
||||
case DHCP6_OPTION_IA_NA:
|
||||
|
||||
if (*buflen < DHCP6_OPTION_IA_NA_LEN + DHCP6_OPTION_HDR_LEN +
|
||||
if (*buflen < DHCP6_OPTION_IA_NA_LEN + sizeof(DHCP6Option) +
|
||||
sizeof(addr->iaaddr)) {
|
||||
r = -ENOBUFS;
|
||||
goto error;
|
||||
@@ -212,7 +219,7 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
|
||||
break;
|
||||
|
||||
case DHCP6_OPTION_IA_TA:
|
||||
if (*buflen < DHCP6_OPTION_IA_TA_LEN + DHCP6_OPTION_HDR_LEN +
|
||||
if (*buflen < DHCP6_OPTION_IA_TA_LEN + sizeof(DHCP6Option) +
|
||||
sizeof(addr->iaaddr)) {
|
||||
r = -ENOBUFS;
|
||||
goto error;
|
||||
|
||||
Reference in New Issue
Block a user