99ccb8ff89
RFC: 8415 21.17. Vendor-specific Information Option This option is used by clients and servers to exchange vendor- specific information. The format of the Vendor-specific Information option is: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | OPTION_VENDOR_OPTS | option-len | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | enterprise-number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ . . . vendor-option-data . . . +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 30: Vendor-specific Information Option Format option-code OPTION_VENDOR_OPTS (17). option-len 4 + length of vendor-option-data field. enterprise-number The vendor's registered Enterprise Number as maintained by IANA [IANA-PEN]. A 4-octet field containing an unsigned integer. vendor-option-data Vendor options, interpreted by vendor-specific code on the clients and servers. A variable-length field (4 octets less than the value in the option-len field). The definition of the information carried in this option is vendor specific. The vendor is indicated in the enterprise-number field. Use of vendor-specific information allows enhanced operation, utilizing additional features in a vendor's DHCP implementation. A DHCP client that does not receive requested vendor-specific information will still configure the node's IPv6 stack to be functional. The vendor-option-data field MUST be encoded as a sequence of code/length/value fields of format identical to the DHCP options (see Section 21.1). The sub-option codes are defined by the vendor identified in the enterprise-number field and are not managed by IANA. Each of the sub-options is formatted as follows: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | sub-opt-code | sub-option-len | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ . . . sub-option-data . . . +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 31: Vendor-specific Options Format sub-opt-code The code for the sub-option. A 2-octet field. sub-option-len An unsigned integer giving the length of the sub-option-data field in this sub-option in octets. A 2-octet field. sub-option-data The data area for the sub-option. The length, in octets, is specified by sub-option-len. Multiple instances of the Vendor-specific Information option may appear in a DHCP message. Each instance of the option is interpreted according to the option codes defined by the vendor identified by the Enterprise Number in that option. Servers and clients MUST NOT send more than one instance of the Vendor-specific Information option with the same Enterprise Number. Each instance of the Vendor-specific Information option MAY contain multiple sub-options. A client that is interested in receiving a Vendor-specific Information option: - MUST specify the Vendor-specific Information option in an Option Request option. - MAY specify an associated Vendor Class option (see Section 21.16). - MAY specify the Vendor-specific Information option with appropriate data. Servers only return the Vendor-specific Information options if specified in Option Request options from clients and: - MAY use the Enterprise Numbers in the associated Vendor Class options to restrict the set of Enterprise Numbers in the Vendor-specific Information options returned. - MAY return all configured Vendor-specific Information options. - MAY use other information in the packet or in its configuration to determine which set of Enterprise Numbers in the Vendor-specific Information options to return.
123 lines
3.7 KiB
C
123 lines
3.7 KiB
C
/* SPDX-License-Identifier: LGPL-2.1+ */
|
|
#pragma once
|
|
|
|
/***
|
|
Copyright © 2014-2015 Intel Corporation. All rights reserved.
|
|
***/
|
|
|
|
#include <net/ethernet.h>
|
|
#include <netinet/in.h>
|
|
|
|
#include "sd-event.h"
|
|
|
|
#include "list.h"
|
|
#include "hashmap.h"
|
|
#include "macro.h"
|
|
#include "sparse-endian.h"
|
|
|
|
typedef struct sd_dhcp6_option {
|
|
unsigned n_ref;
|
|
|
|
uint32_t enterprise_identifier;
|
|
uint16_t option;
|
|
void *data;
|
|
size_t length;
|
|
} sd_dhcp6_option;
|
|
|
|
extern const struct hash_ops dhcp6_option_hash_ops;
|
|
|
|
/* Common option header */
|
|
typedef struct DHCP6Option {
|
|
be16_t code;
|
|
be16_t len;
|
|
uint8_t data[];
|
|
} _packed_ DHCP6Option;
|
|
|
|
/* Address option */
|
|
struct iaaddr {
|
|
struct in6_addr address;
|
|
be32_t lifetime_preferred;
|
|
be32_t lifetime_valid;
|
|
} _packed_;
|
|
|
|
/* Prefix Delegation Prefix option */
|
|
struct iapdprefix {
|
|
be32_t lifetime_preferred;
|
|
be32_t lifetime_valid;
|
|
uint8_t prefixlen;
|
|
struct in6_addr address;
|
|
} _packed_;
|
|
|
|
typedef struct DHCP6Address DHCP6Address;
|
|
|
|
struct DHCP6Address {
|
|
LIST_FIELDS(DHCP6Address, addresses);
|
|
|
|
union {
|
|
struct iaaddr iaaddr;
|
|
struct iapdprefix iapdprefix;
|
|
};
|
|
};
|
|
|
|
/* Non-temporary Address option */
|
|
struct ia_na {
|
|
be32_t id;
|
|
be32_t lifetime_t1;
|
|
be32_t lifetime_t2;
|
|
} _packed_;
|
|
|
|
/* Prefix Delegation option */
|
|
struct ia_pd {
|
|
be32_t id;
|
|
be32_t lifetime_t1;
|
|
be32_t lifetime_t2;
|
|
} _packed_;
|
|
|
|
/* Temporary Address option */
|
|
struct ia_ta {
|
|
be32_t id;
|
|
} _packed_;
|
|
|
|
struct DHCP6IA {
|
|
uint16_t type;
|
|
union {
|
|
struct ia_na ia_na;
|
|
struct ia_pd ia_pd;
|
|
struct ia_ta ia_ta;
|
|
};
|
|
|
|
LIST_HEAD(DHCP6Address, addresses);
|
|
};
|
|
|
|
typedef struct DHCP6IA DHCP6IA;
|
|
|
|
#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
|
|
#define log_dhcp6_client(p, fmt, ...) log_dhcp6_client_errno(p, 0, fmt, ##__VA_ARGS__)
|
|
|
|
int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
|
|
size_t optlen, const void *optval);
|
|
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
|
|
int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd, DHCP6Address *hint_pd_prefix);
|
|
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
|
|
int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char **user_class);
|
|
int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char **user_class);
|
|
int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHashmap *vendor_options);
|
|
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, size_t len);
|
|
int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code);
|
|
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
|
struct in6_addr **addrs, size_t count,
|
|
size_t *allocated);
|
|
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen,
|
|
char ***str_arr);
|
|
|
|
int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address);
|
|
int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
|
|
const void *packet, size_t len);
|
|
|
|
const char *dhcp6_message_type_to_string(int s) _const_;
|
|
int dhcp6_message_type_from_string(const char *s) _pure_;
|
|
const char *dhcp6_message_status_to_string(int s) _const_;
|
|
int dhcp6_message_status_from_string(const char *s) _pure_;
|