chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
zsh-completion: remove duplicate function
[elogind.git]
/
src
/
libsystemd-network
/
dhcp6-option.c
diff --git
a/src/libsystemd-network/dhcp6-option.c
b/src/libsystemd-network/dhcp6-option.c
index f488832cf919ca4406c3a192ee124b9b05cb8323..ea863f45e4ea13a400461949a62cbce71c913379 100644
(file)
--- a/
src/libsystemd-network/dhcp6-option.c
+++ b/
src/libsystemd-network/dhcp6-option.c
@@
-24,32
+24,37
@@
#include <string.h>
#include "sparse-endian.h"
#include <string.h>
#include "sparse-endian.h"
+#include "unaligned.h"
#include "util.h"
#include "dhcp6-internal.h"
#include "dhcp6-protocol.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
#define DHCP6_OPTION_IA_NA_LEN 12
#define DHCP6_OPTION_IA_TA_LEN 4
-#define DHCP6_OPTION_IAADDR_LEN 24
+
+typedef struct DHCP6Option {
+ be16_t code;
+ be16_t len;
+ uint8_t data[];
+} _packed_ DHCP6Option;
static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode,
size_t optlen) {
static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode,
size_t optlen) {
+ DHCP6Option *option = (DHCP6Option*) *buf;
+
assert_return(buf, -EINVAL);
assert_return(*buf, -EINVAL);
assert_return(buflen, -EINVAL);
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;
return -ENOBUFS;
- (*buf)[0] = optcode >> 8;
- (*buf)[1] = optcode & 0xff;
- (*buf)[2] = optlen >> 8;
- (*buf)[3] = optlen & 0xff;
+ option->code = htobe16(optcode);
+ option->len = htobe16(optlen);
- *buf +=
DHCP6_OPTION_HDR_LEN
;
- *buflen -=
DHCP6_OPTION_HDR_LEN
;
+ *buf +=
sizeof(DHCP6Option)
;
+ *buflen -=
sizeof(DHCP6Option)
;
return 0;
}
return 0;
}
@@
-58,13
+63,14
@@
int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
size_t optlen, const void *optval) {
int r;
size_t optlen, const void *optval) {
int r;
- assert_return(optval, -EINVAL);
+ assert_return(optval
|| optlen == 0
, -EINVAL);
r = option_append_hdr(buf, buflen, code, optlen);
if (r < 0)
return r;
r = option_append_hdr(buf, buflen, code, optlen);
if (r < 0)
return r;
- memcpy(*buf, optval, optlen);
+ if (optval)
+ memcpy(*buf, optval, optlen);
*buf += optlen;
*buflen -= optlen;
*buf += optlen;
*buflen -= optlen;
@@
-100,8
+106,8
@@
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
ia_hdr = *buf;
ia_buflen = *buflen;
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);
memcpy(*buf, &ia->id, len);
@@
-110,16
+116,16
@@
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
LIST_FOREACH(addresses, addr, ia->addresses) {
r = option_append_hdr(buf, buflen, DHCP6_OPTION_IAADDR,
LIST_FOREACH(addresses, addr, ia->addresses) {
r = option_append_hdr(buf, buflen, DHCP6_OPTION_IAADDR,
-
DHCP6_OPTION_IAADDR_LEN
);
+
sizeof(addr->iaaddr)
);
if (r < 0)
return r;
if (r < 0)
return r;
- memcpy(*buf, &addr->
address, DHCP6_OPTION_IAADDR_LEN
);
+ memcpy(*buf, &addr->
iaaddr, sizeof(addr->iaaddr)
);
- *buf +=
DHCP6_OPTION_IAADDR_LEN
;
- *buflen -=
DHCP6_OPTION_IAADDR_LEN
;
+ *buf +=
sizeof(addr->iaaddr)
;
+ *buflen -=
sizeof(addr->iaaddr)
;
- ia_addrlen +=
DHCP6_OPTION_HDR_LEN + DHCP6_OPTION_IAADDR_LEN
;
+ ia_addrlen +=
sizeof(DHCP6Option) + sizeof(addr->iaaddr)
;
}
r = option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
}
r = option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
@@
-130,23
+136,23
@@
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
,
- size_t *optlen) {
+static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *opt
code, size_t *optlen) {
+ DHCP6Option *option = (DHCP6Option*) *buf;
uint16_t len;
assert_return(buf, -EINVAL);
uint16_t len;
assert_return(buf, -EINVAL);
- assert_return(opt, -EINVAL);
+ assert_return(opt
code
, -EINVAL);
assert_return(optlen, -EINVAL);
assert_return(optlen, -EINVAL);
- if (*buflen <
4
)
+ if (*buflen <
sizeof(DHCP6Option)
)
return -ENOMSG;
return -ENOMSG;
- len =
(*buf)[2] << 8 | (*buf)[3]
;
+ len =
be16toh(option->len)
;
if (len > *buflen)
return -ENOMSG;
if (len > *buflen)
return -ENOMSG;
- *opt
= (*buf)[0] << 8 | (*buf)[1]
;
+ *opt
code = be16toh(option->code)
;
*optlen = len;
*buf += 4;
*optlen = len;
*buf += 4;
@@
-190,8
+196,8
@@
int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
switch (iatype) {
case DHCP6_OPTION_IA_NA:
switch (iatype) {
case DHCP6_OPTION_IA_NA:
- if (*buflen < DHCP6_OPTION_IA_NA_LEN +
DHCP6_OPTION_HDR_LEN
+
-
DHCP6_OPTION_IAADDR_LEN
) {
+ if (*buflen < DHCP6_OPTION_IA_NA_LEN +
sizeof(DHCP6Option)
+
+
sizeof(addr->iaaddr)
) {
r = -ENOBUFS;
goto error;
}
r = -ENOBUFS;
goto error;
}
@@
-212,8
+218,8
@@
int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
break;
case DHCP6_OPTION_IA_TA:
break;
case DHCP6_OPTION_IA_TA:
- if (*buflen < DHCP6_OPTION_IA_TA_LEN +
DHCP6_OPTION_HDR_LEN
+
-
DHCP6_OPTION_IAADDR_LEN
) {
+ if (*buflen < DHCP6_OPTION_IA_TA_LEN +
sizeof(DHCP6Option)
+
+
sizeof(addr->iaaddr)
) {
r = -ENOBUFS;
goto error;
}
r = -ENOBUFS;
goto error;
}
@@
-249,10
+255,10
@@
int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
LIST_INIT(addresses, addr);
LIST_INIT(addresses, addr);
- memcpy(&addr->
address, *buf, DHCP6_OPTION_IAADDR_LEN
);
+ memcpy(&addr->
iaaddr, *buf, sizeof(addr->iaaddr)
);
- lt_valid = be32toh(addr->lifetime_valid);
- lt_pref = be32toh(addr->lifetime_valid);
+ lt_valid = be32toh(addr->
iaaddr.
lifetime_valid);
+ lt_pref = be32toh(addr->
iaaddr.
lifetime_valid);
if (!lt_valid || lt_pref > lt_valid) {
log_dhcp6_client(client, "IA preferred %ds > valid %ds",
if (!lt_valid || lt_pref > lt_valid) {
log_dhcp6_client(client, "IA preferred %ds > valid %ds",