29RCSIDH(dhcpv6_h,
"$Id: 0273f1c832021e550123dd15d70ce57aaf948ce8 $")
31#include <freeradius-devel/util/dict.h>
33#include <freeradius-devel/protocol/dhcpv6/dictionary.h>
35#define DHCPV6_MSG_TYPE_LEN 1U
37#define DHCPV6_TRANSACTION_ID_LEN 3U
39#define DHCPV6_HOP_COUNT_LEN 1U
40#define DHCPV6_LINK_ADDRESS_LEN 16U
41#define DHCPV6_PEER_ADDRESS_LEN 16U
43#define DHCPV6_HDR_LEN (DHCPV6_MSG_TYPE_LEN + DHCPV6_TRANSACTION_ID_LEN)
44#define DHCPV6_RELAY_HDR_LEN (DHCPV6_MSG_TYPE_LEN + DHCPV6_HOP_COUNT_LEN + DHCPV6_LINK_ADDRESS_LEN + DHCPV6_PEER_ADDRESS_LEN)
45#define DHCPV6_OPT_HDR_LEN (sizeof(uint16_t) * 2)
47#define DHCPV6_GET_OPTION_NUM(_x) fr_nbo_to_uint16(_x)
48#define DHCPV6_GET_OPTION_LEN(_x) fr_nbo_to_uint16((_x) + 2)
50#define DHCPV6_MAX_RELAY_NESTING 10
52#define DHCPV6_MAX_ATTRIBUTES 1024
57#define IN6ADDR_ALL_DHCP_RELAY_AGENTS_AND_SERVERS "FF02::1:2"
58#define IN6ADDR_ALL_DHCP_RELAY_AGENTS_AND_SERVERS_INIT {{{ 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,1,2}}}
59#define IN6ADDR_ALL_DHCP_SERVERS "FF05::1:3"
60#define IN6ADDR_ALL_DHCP_SERVERS_INIT {{{ 0xff,0x05,0,0,0,0,0,0,0,0,0,0,0,0,1,3}}}
107#define FR_DHCPV6_PACKET_CODE_VALID(_code) (((_code) > 0) && ((_code) < FR_DHCPV6_CODE_MAX))
114typedef struct CC_HINT(__packed__) {
124#define DHCPV6_DATE_OFFSET (946684800)
160 "%s is not a DHCPv6 attribute, it is from the \"%s\" dictionary",
164 if (!
fr_cond_assert_msg(flags,
"%s is not a DHCPv6 attribute, it has no protocol extension",
165 da->name))
return &no_flags;
222 uint8_t const *
data,
size_t data_len,
void *decode_ctx);
static int packet_ctx
the tests pass only the address of packet_ctx
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
uint32_t transaction_id
previous transaction ID
fr_dict_attr_t const * root
Root attribute of the dictionary.
void * fr_dhcpv6_next_encodable(fr_dcursor_t *cursor, void *current, void *uctx)
DHCPV6-specific iterator.
void fr_dhcpv6_global_free(void)
fr_dict_protocol_t libfreeradius_dhcpv6_dict_protocol
static bool fr_dhcpv6_flag_dns_label(fr_dict_attr_t const *da)
ssize_t fr_dhcpv6_decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *decode_ctx)
Create a "normal" fr_pair_t from the given data.
static bool fr_dhcpv6_flag_partial_dns_label(fr_dict_attr_t const *da)
bool fr_dhcpv6_ok(uint8_t const *packet, size_t packet_len, uint32_t max_attributes)
See if the data pointed to by PTR is a valid DHCPv6 packet.
uint8_t const * fr_dhcpv6_option_find(uint8_t const *start, uint8_t const *end, unsigned int option)
int fr_dhcpv6_global_init(void)
@ FR_DHCPV6_ACTIVE_LEASE_QUERY
@ FR_DHCPV6_DO_NOT_RESPOND
@ FR_DHCPV6_LEASE_QUERY_DATA
@ FR_DHCPV6_POOL_RESPONSE
@ FR_DHCPV6_RECONFIGURE_REPLY
@ FR_DHCPV6_DHCPV4_RESPONSE
@ FR_DHCPV6_RECONFIGURE_REQUEST
@ FR_DHCPV6_UPDATE_REQUEST_ALL
@ FR_DHCPV6_CONNECT_REPLY
@ FR_DHCPV6_INFORMATION_REQUEST
@ FR_DHCPV6_LEASE_QUERY_DONE
@ FR_DHCPV6_RELAY_FORWARD
@ FR_DHCPV6_LEASE_QUERY_REPLY
@ FR_DHCPV6_UPDATE_REQUEST
uint8_t const * duid
the expected DUID, in wire format
ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *packet, size_t packet_len)
Decode a DHCPv6 packet.
char const * fr_dhcpv6_packet_names[FR_DHCPV6_CODE_MAX]
static bool fr_dhcpv6_flag_any_dns_label(fr_dict_attr_t const *da)
uint8_t const * original
original packet
ssize_t fr_dhcpv6_encode_option(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *encode_ctx)
Encode a DHCPv6 option and any sub-options.
size_t original_length
length of the original packet
bool fr_dhcpv6_verify(uint8_t const *packet, size_t packet_len, fr_dhcpv6_decode_ctx_t const *packet_ctx, bool from_server)
Verify the packet under some various circumstances.
void fr_dhcpv6_print_hex(FILE *fp, uint8_t const *packet, size_t packet_len)
Print a raw DHCP packet as hex.
size_t duid_len
length of the expected DUID
static fr_dhcpv6_attr_flags_t const * fr_dhcpv6_attr_flags(fr_dict_attr_t const *da)
Return DHCPv6-specific flags for a given attribute.
TALLOC_CTX * tmp_ctx
for temporary things cleaned up during decoding
ssize_t fr_dhcpv6_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len)
ssize_t fr_dhcpv6_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t const *list)
ssize_t fr_dhcpv6_encode(fr_dbuff_t *dbuff, uint8_t const *original, size_t length, int msg_type, fr_pair_list_t *vps)
Encode a DHCPv6 packet.
subtype values for DHCPv4 and DHCPv6
@ FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC
Protocol specific extensions.
fr_dict_protocol_t const * fr_dict_protocol(fr_dict_t const *dict)
Return the protocol descriptor for the dictionary.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Protocol-specific callbacks in libfreeradius-PROTOCOL.
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
static fr_internal_encode_ctx_t encode_ctx
void * fr_dhcpv6_next_encodable(fr_dcursor_t *cursor, void *current, void *uctx)
DHCPV6-specific iterator.
void fr_dhcpv6_global_free(void)
fr_dict_protocol_t libfreeradius_dhcpv6_dict_protocol
bool fr_dhcpv6_ok(uint8_t const *packet, size_t packet_len, uint32_t max_attributes)
See if the data pointed to by PTR is a valid DHCPv6 packet.
uint8_t const * fr_dhcpv6_option_find(uint8_t const *start, uint8_t const *end, unsigned int option)
int fr_dhcpv6_global_init(void)
ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *packet, size_t packet_len)
Decode a DHCPv6 packet.
bool fr_dhcpv6_verify(uint8_t const *packet, size_t packet_len, fr_dhcpv6_decode_ctx_t const *packet_ctx, bool from_server)
Verify the packet under some various circumstances.
void fr_dhcpv6_print_hex(FILE *fp, uint8_t const *packet, size_t packet_len)
Print a raw DHCP packet as hex.
ssize_t fr_dhcpv6_encode(fr_dbuff_t *dbuff, uint8_t const *original, size_t length, int msg_type, fr_pair_list_t *vps)
Encode a DHCPv6 packet.
ssize_t fr_dhcpv6_decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *decode_ctx)
Create a "normal" fr_pair_t from the given data.
ssize_t fr_dhcpv6_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len)
static fr_sbuff_err_t char ** out