26 RCSID(
"$Id: a20686cb62483681bc3055353d4544b2d073b541 $")
28 #include <freeradius-devel/dhcpv4/dhcpv4.h>
29 #include <freeradius-devel/util/net.h>
30 #include <freeradius-devel/util/proto.h>
145 #define DHCP_MAX_MESSAGE_TYPE (NUM_ELEMENTS(dhcp_message_types))
191 {
L(
"dns_label"), { .func = dict_flag_dns_label } },
192 {
L(
"exists"), { .func = dict_flag_exists } },
262 if ((hlen != 0) && (hlen != 6)) {
267 memcpy(&magic,
data + 236, 4);
268 magic = ntohl(magic);
275 if (!code || (code[1] == 0)) {
291 if (message_type) *message_type = code[2];
294 memcpy(&magic,
data + 4, 4);
326 if (c->
da->dict !=
dict || c->
da->flags.internal)
continue;
362 if (
vp && (
vp->vp_uint32 > mms)) {
381 }
else if (original) {
393 }
else if (original) {
405 }
else if (original) {
427 }
else if (original) {
464 }
else if (original) {
476 }
else if (original) {
610 for (i = 1; i < 255; i++) {
620 attr->name, &
value,
true,
false) < 0) {
658 static char const tabs[] =
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
660 for (i = 0; i < attrlen; i++) {
661 if ((i > 0) && ((i & 0x0f) == 0x00))
663 fprintf(fp,
"%02x ", ptr[i]);
664 if ((i & 0x0f) == 0x0f) fprintf(fp,
"\n");
666 if ((i & 0x0f) != 0) fprintf(fp,
"\n");
677 end = packet + packet_len;
680 for (i = 0; i < 14; i++) {
686 fprintf(fp,
"\tmagic:\t%02x %02x %02x %02x\n", attr[0], attr[1], attr[2], attr[3]);
689 fprintf(fp,
"\toptions\n");
693 fprintf(fp,
"%02x %02x ", attr[0], attr[1]);
700 if (attr[0] == 255)
break;
715 da->flags.is_known_width =
true;
732 if (da->flags.extra || !da->flags.subtype)
return true;
735 fr_strerror_const(
"The 'dns_label' flag can only be used with attributes of type 'string'");
741 fr_strerror_const(
"The 'prefix=...' flag can only be used with attributes of type 'ipv4prefix'");
746 fr_strerror_const(
"The 'exists' flag can only be used with attributes of type 'bool'");
756 .default_type_size = 1,
757 .default_type_length = 1,
static int const char char buffer[256]
#define L(_str)
Helper for initialising arrays of string literals.
#define fr_dbuff_used(_dbuff_or_marker)
Return the number of bytes remaining between the start of the dbuff or marker and the current positio...
#define FR_DBUFF_MEMSET_RETURN(_dbuff_or_marker, _c, _inlen)
Set _inlen bytes of a dbuff or marker to _c returning if there is insufficient space.
#define FR_DBUFF_IN_MEMCPY_RETURN(_dbuff_or_marker, _in, _inlen)
Copy exactly _inlen bytes into dbuff or marker returning if there's insufficient space.
#define FR_DBUFF_IN_RETURN(_dbuff_or_marker, _in)
Copy data from a fixed sized C type into a dbuff returning if there is insufficient space.
#define FR_DBUFF(_dbuff_or_marker)
Create a new dbuff pointing to the same underlying buffer.
#define FR_DBUFF_IN_BYTES_RETURN(_dbuff_or_marker,...)
Copy a byte sequence into a dbuff or marker returning if there's insufficient space.
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
fr_dcursor_eval_t void const * uctx
fr_dcursor_iter_t void * current
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
static void * fr_dcursor_current(fr_dcursor_t *cursor)
Return the item the cursor current points to.
#define DEFAULT_PACKET_SIZE
#define fr_dhcpv4_flag_dns_label(_da)
ssize_t fr_dhcpv4_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t const *list)
fr_dhcpv4_attr_flags_prefix_t prefix
fr_dhcpv4_attr_flags_prefix_t
@ DHCPV4_FLAG_PREFIX_INVALID
@ DHCPV4_FLAG_PREFIX_SPLIT
@ DHCPV4_FLAG_PREFIX_BITS
#define fr_dhcpv4_flag_prefix(_da)
#define fr_dhcpv4_flag_exists(_da)
#define DHCP_OPTION_MAGIC_NUMBER
uint8_t const * fr_dhcpv4_packet_get_option(dhcp_packet_t const *packet, size_t packet_size, fr_dict_attr_t const *da)
Retrieve a DHCP option from a raw packet buffer.
ssize_t fr_dhcpv4_encode_option(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *encode_ctx)
Encode a DHCP option and any sub-options.
uint8_t chaddr[DHCP_CHADDR_LEN]
@ FLAG_LENGTH_UINT8
string / octets type is prefixed by uint8 of length
@ FLAG_LENGTH_UINT16
string / octets type is prefixed by uint16 of length
int fr_dict_enum_add_name(fr_dict_attr_t *da, char const *name, fr_value_box_t const *value, bool coerce, bool replace)
Add a value name.
fr_dict_attr_t * fr_dict_attr_unconst(fr_dict_attr_t const *da)
Coerce to non-const.
#define fr_dict_autofree(_to_free)
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
@ FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC
Protocol specific extensions.
#define fr_dict_autoload(_to_load)
fr_dict_attr_t const * fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Check if a child attribute exists in a parent using an attribute number.
char const * name
name of this protocol
#define FR_DICT_ATTR_FLAG_FUNC(_struct, _name)
Define a flag setting function, which sets one bit in a fr_dict_attr_flags_t.
static int8_t fr_dict_attr_cmp(fr_dict_attr_t const *a, fr_dict_attr_t const *b)
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
Protocol specific custom flag definitnion.
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 void * fr_dlist_next(fr_dlist_head_t const *list_head, void const *ptr)
Get the next item in a list.
Head of a doubly linked list.
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_ETHERNET
48 Bit Mac-Address.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_IPV4_PREFIX
IPv4 Prefix.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_OCTETS
Raw octets.
static uint8_t depth(fr_minmax_heap_index_t i)
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
fr_dict_attr_t const * attr_dhcp_opcode
fr_dict_autoload_t dhcpv4_dict[]
#define DHCP_MAX_MESSAGE_TYPE
fr_dict_attr_t const * attr_dhcp_gateway_ip_address
fr_dict_protocol_t libfreeradius_dhcpv4_dict_protocol
char const * dhcp_message_types[]
fr_dict_attr_t const * attr_dhcp_server_ip_address
uint8_t eth_bcast[ETH_ADDR_LEN]
fr_dict_attr_t const * attr_dhcp_dhcp_maximum_msg_size
fr_dict_attr_t const * attr_dhcp_relay_link_selection
fr_dict_attr_t const * attr_dhcp_vendor_class_identifier
bool fr_dhcpv4_ok(uint8_t const *data, ssize_t data_len, uint8_t *message_type, uint32_t *xid)
Check received DHCP request is valid and build fr_packet_t structure if it is.
size_t dhcp_header_attrs_len
fr_dict_attr_t const * attr_dhcp_hop_count
fr_dict_attr_t const * attr_dhcp_parameter_request_list
int fr_dhcpv4_global_init(void)
Resolve/cache attributes in the DHCP dictionary.
fr_dict_attr_autoload_t dhcpv4_dict_attr[]
static int dict_flag_prefix(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)
static void print_hex_data(FILE *fp, uint8_t const *ptr, int attrlen, int depth)
fr_dict_attr_t const * attr_dhcp_server_host_name
fr_dict_attr_t const * attr_dhcp_hardware_address_length
fr_dict_attr_t const * attr_dhcp_transaction_id
static uint32_t instance_count
fr_dict_attr_t const * attr_dhcp_message_type
int8_t fr_dhcpv4_attr_cmp(void const *a, void const *b)
static bool attr_valid(fr_dict_attr_t *da)
fr_dict_attr_t const * attr_dhcp_boot_filename
fr_dict_attr_t const * attr_dhcp_overload
static fr_dict_flag_parser_t const dhcpv4_flags[]
fr_dict_attr_t const * attr_dhcp_subnet_selection_option
ssize_t fr_dhcpv4_encode_dbuff(fr_dbuff_t *dbuff, dhcp_packet_t *original, int code, uint32_t xid, fr_pair_list_t *vps)
fr_dict_t const * dict_dhcpv4
fr_dict_attr_t const * attr_dhcp_network_subnet
fr_dict_attr_t const * attr_dhcp_option_82
fr_dict_attr_t const * attr_dhcp_flags
void fr_dhcpv4_global_free(void)
fr_dict_attr_t const * attr_dhcp_hardware_type
fr_dict_attr_t const * attr_dhcp_your_ip_address
void * fr_dhcpv4_next_encodable(fr_dlist_head_t *list, void *current, void *uctx)
DHCPV4-specific iterator.
fr_dict_attr_t const * attr_dhcp_client_ip_address
fr_dict_attr_t const * attr_dhcp_interface_mtu_size
fr_dict_attr_t const * attr_dhcp_client_hardware_address
fr_dict_attr_t const * attr_dhcp_number_of_seconds
ssize_t fr_dhcpv4_encode(uint8_t *buffer, size_t buflen, dhcp_packet_t *original, int code, uint32_t xid, fr_pair_list_t *vps)
bool fr_dhcpv4_is_encodable(void const *item, UNUSED void const *uctx)
Evaluation function for DCHPV4-encodability.
fr_dict_attr_t const ** dhcp_header_attrs[]
static char const * short_header_names[]
void fr_dhcpv4_print_hex(FILE *fp, uint8_t const *packet, size_t packet_len)
Print a raw DHCP packet as hex.
ssize_t fr_dhcpv4_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len)
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
An element in a lexicographically sorted array of name to num mappings.
#define fr_pair_dcursor_iter_init(_cursor, _list, _iter, _uctx)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
void fr_pair_list_sort(fr_pair_list_t *list, fr_cmp_t cmp)
Sort a doubly linked list of fr_pair_ts using merge sort.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
return fr_dbuff_set(dbuff, &our_dbuff)
#define fr_box_uint8(_val)