dhcp6: Add function for DHCPv6 Status option
Factor out code to parse a DHCPv6 Status option using a common function.
This commit is contained in:
@@ -83,6 +83,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia);
|
||||
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
|
||||
int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
|
||||
size_t *optlen, uint8_t **optvalue);
|
||||
int dhcp6_option_parse_status(DHCP6Option *option);
|
||||
int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia);
|
||||
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
||||
struct in6_addr **addrs, size_t count,
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "dhcp6-internal.h"
|
||||
#include "dhcp6-lease-internal.h"
|
||||
#include "dhcp6-protocol.h"
|
||||
#include "dns-domain.h"
|
||||
#include "sparse-endian.h"
|
||||
@@ -33,6 +34,12 @@
|
||||
#include "unaligned.h"
|
||||
#include "util.h"
|
||||
|
||||
typedef struct DHCP6StatusOption {
|
||||
struct DHCP6Option option;
|
||||
be16_t status;
|
||||
char msg[];
|
||||
} _packed_ DHCP6StatusOption;
|
||||
|
||||
#define DHCP6_OPTION_IA_NA_LEN 12
|
||||
#define DHCP6_OPTION_IA_TA_LEN 4
|
||||
|
||||
@@ -207,6 +214,15 @@ int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dhcp6_option_parse_status(DHCP6Option *option) {
|
||||
DHCP6StatusOption *statusopt = (DHCP6StatusOption *)option;
|
||||
|
||||
if (be16toh(option->len) + sizeof(DHCP6Option) < sizeof(*statusopt))
|
||||
return -ENOBUFS;
|
||||
|
||||
return be16toh(statusopt->status);
|
||||
}
|
||||
|
||||
int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
|
||||
uint16_t iatype, optlen;
|
||||
size_t i, len;
|
||||
@@ -302,15 +318,14 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
|
||||
break;
|
||||
|
||||
case SD_DHCP6_OPTION_STATUS_CODE:
|
||||
if (optlen < sizeof(status)) {
|
||||
r = -ENOMSG;
|
||||
goto error;
|
||||
}
|
||||
|
||||
status = option->data[0] << 8 | option->data[1];
|
||||
status = dhcp6_option_parse_status(option);
|
||||
if (status) {
|
||||
log_dhcp6_client(client, "IA status %d",
|
||||
status);
|
||||
|
||||
dhcp6_lease_free_ia(ia);
|
||||
|
||||
r = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -740,7 +740,8 @@ static int client_parse_message(
|
||||
|
||||
while (pos < len) {
|
||||
DHCP6Option *option = (DHCP6Option *)&message->options[pos];
|
||||
uint16_t optcode, optlen, status;
|
||||
uint16_t optcode, optlen;
|
||||
int status;
|
||||
uint8_t *optval;
|
||||
be32_t iaid_lease;
|
||||
|
||||
@@ -795,14 +796,13 @@ static int client_parse_message(
|
||||
break;
|
||||
|
||||
case SD_DHCP6_OPTION_STATUS_CODE:
|
||||
if (optlen < 2)
|
||||
return -EINVAL;
|
||||
|
||||
status = optval[0] << 8 | optval[1];
|
||||
status = dhcp6_option_parse_status(option);
|
||||
if (status) {
|
||||
log_dhcp6_client(client, "%s Status %s",
|
||||
dhcp6_message_type_to_string(message->type),
|
||||
dhcp6_message_status_to_string(status));
|
||||
dhcp6_lease_free_ia(&lease->ia);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user