26 RCSID(
"$Id: 76c832f04ee6fffbc085bbf3850ea4adb4aafb11 $")
28 #include <freeradius-devel/dhcpv4/dhcpv4.h>
29 #include <freeradius-devel/util/net.h>
30 #include <freeradius-devel/util/proto.h>
143 #define DHCP_MAX_MESSAGE_TYPE (NUM_ELEMENTS(dhcp_message_types))
198 if (a_82 && !b_82)
return +1;
199 if (!a_82 && !b_82)
return -1;
237 if ((hlen != 0) && (hlen != 6)) {
242 memcpy(&magic,
data + 236, 4);
243 magic = ntohl(magic);
250 if (!code || (code[1] == 0)) {
266 if (message_type) *message_type = code[2];
269 memcpy(&magic,
data + 4, 4);
301 if (c->
da->dict !=
dict || c->
da->flags.internal)
continue;
337 if (
vp && (
vp->vp_uint32 > mms)) {
356 }
else if (original) {
368 }
else if (original) {
380 }
else if (original) {
437 }
else if (original) {
449 }
else if (original) {
583 for (i = 1; i < 255; i++) {
593 attr->name, &
value,
true,
false) < 0) {
631 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";
633 for (i = 0; i < attrlen; i++) {
634 if ((i > 0) && ((i & 0x0f) == 0x00))
636 fprintf(fp,
"%02x ", ptr[i]);
637 if ((i & 0x0f) == 0x0f) fprintf(fp,
"\n");
639 if ((i & 0x0f) != 0) fprintf(fp,
"\n");
650 end = packet + packet_len;
653 for (i = 0; i < 14; i++) {
659 fprintf(fp,
"\tmagic:\t%02x %02x %02x %02x\n", attr[0], attr[1], attr[2], attr[3]);
662 fprintf(fp,
"\toptions\n");
666 fprintf(fp,
"%02x %02x ", attr[0], attr[1]);
673 if (attr[0] == 255)
break;
717 fr_strerror_const(
"The 'dns_label' flag can only be used with attributes of type 'string'");
723 fr_strerror_const(
"The 'prefix=...' flag can only be used with attributes of type 'ipv4prefix'");
728 fr_strerror_const(
"The 'encode=exists' flag can only be used with attributes of type 'bool'");
738 .default_type_size = 1,
739 .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.
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
@ FLAG_ENCODE_SPLIT_PREFIX
encode IPv4 prefixes as Policy-Filter, split into IP/mask
@ FLAG_ENCODE_BOOL_EXISTS
bool as existence checks
@ FLAG_ENCODE_DNS_LABEL
encode as DNS label
@ FLAG_ENCODE_BITS_PREFIX
encode IPv4 prefixes as prefix bits, followed by IP.
#define da_is_bool_exists(_da)
ssize_t fr_dhcpv4_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t const *list)
#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]
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)
@ FLAG_LENGTH_UINT8
string / octets type is prefixed by uint8 of length
@ FLAG_LENGTH_UINT16
string / octets type is prefixed by uint16 of length
fr_dict_attr_t const * fr_dict_attr_common_parent(fr_dict_attr_t const *a, fr_dict_attr_t const *b, bool is_ancestor)
Find a common ancestor that two TLV type attributes share.
unsigned int array
Pack multiples into 1 attr.
unsigned int extra
really "subtype is used by dict, not by protocol"
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.
#define fr_dict_autoload(_to_load)
unsigned int is_known_width
is treated as if it has a known width for structs
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
uint8_t subtype
protocol-specific values, OR key fields
Specifies an attribute which must be present for the module to function.
Values of the encryption flags.
Specifies a dictionary which must be loaded/loadable for the module to function.
Protocol-specific callbacks in libfreeradius-PROTOCOL.
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.
static void * item(fr_lst_t const *lst, fr_lst_index_t idx)
@ 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.
int8_t fr_pair_cmp_by_parent_num(void const *a, void const *b)
Order attributes by their parent(s), attribute number, and tag.
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 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
fr_dict_attr_t const * dhcp_option_82
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)
fr_dict_attr_t const * attr_dhcp_boot_filename
fr_dict_attr_t const * attr_dhcp_overload
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_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
static bool attr_valid(UNUSED fr_dict_t *dict, UNUSED fr_dict_attr_t const *parent, UNUSED char const *name, UNUSED int attr, fr_type_t type, fr_dict_attr_flags_t *flags)
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
static fr_table_num_ordered_t const subtype_table[]
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)
static rc_request_t * current
fr_aka_sim_id_type_t type
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.
An element in an arbitrarily ordered 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)