26 #include <freeradius-devel/util/pair.h>
27 #include <freeradius-devel/util/rand.h>
28 #include <freeradius-devel/protocol/dhcpv4/rfc2131.h>
50 while (where < size) {
51 if (
data[0] == 0)
return NULL;
57 size =
sizeof(packet->
file);
64 size =
sizeof(packet->
sname);
75 if ((where + 2) > size) {
81 if ((where + 2 +
data[1]) > size) {
87 if (
data[0] == da->attr)
return data;
89 if ((
data[0] == 52) && (
data[1] > 0)) {
120 if (!packet_ctx)
return -1;
139 switch (
vp->vp_type) {
161 if ((
data[1] != 1) || (
data[2] != 6)) {
166 memcpy(
vp->vp_ether, p,
sizeof(
vp->vp_ether));
191 end = p + (data_len - 240);
210 *code =
vp->vp_uint8;
220 if ((
vp->vp_uint8 & 1) == 1) {
229 p, end - p, packet_ctx);
230 if (len <= 0)
goto fail;
235 if ((
vp->vp_uint8 & 2) == 2) {
243 p, end - p, packet_ctx);
244 if (len <= 0)
goto fail;
260 memcpy(&giaddr,
data + 24,
sizeof(giaddr));
261 if (giaddr == htonl(INADDR_ANY)) {
266 if (
vp &&
vp->vp_uint8 == 1) {
271 if (
vp && (
vp->vp_length == 7) && (memcmp(
vp->vp_strvalue,
"MSFT 98", 7) == 0)) {
277 if (
vp)
vp->vp_uint16 |= 0x8000;
316 }
else if (giaddr != htonl(INADDR_ANY)) {
343 fr_strerror_const(
"Client says MTU is smaller than minimum permitted by the specification");
356 if (maxms && mtu && (maxms->vp_uint16 > mtu->vp_uint16)) maxms->vp_uint16 = mtu->vp_uint16;
372 if (packet->
data)
return 0;
382 packet->
id =
vp->vp_uint32;
388 if (len < 0)
return -1;
402 if (!code)
return NULL;
416 memcpy(&magic,
data + 4, 4);
419 packet->
code = code[2];
420 packet->
id = ntohl(magic);
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
static fr_dict_attr_t const * attr_dhcp_message_type
Implementation of the DHCPv4 protocol.
TALLOC_CTX * tmp_ctx
for temporary things cleaned up during decoding
#define DEFAULT_PACKET_SIZE
#define DHCP_OPTION_FIELD
uint8_t options[DHCP_VEND_LEN]
uint8_t file[DHCP_FILE_LEN]
uint8_t sname[DHCP_SNAME_LEN]
fr_packet_t * fr_packet_alloc(TALLOC_CTX *ctx, bool new_vector)
Allocate a new fr_packet_t.
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_ETHERNET
48 Bit Mac-Address.
@ FR_TYPE_STRING
String of printable characters.
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_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
int fr_pair_delete_by_da(fr_pair_list_t *list, fr_dict_attr_t const *da)
Delete matching pairs from the specified list.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
int fr_pair_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Copy data into a "string" type value pair.
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find a pair with a matching fr_dict_attr_t, by walking the nested fr_dict_attr_t tree.
HIDDEN fr_dict_attr_t const * attr_dhcp_overload
HIDDEN fr_dict_attr_t const * attr_dhcp_boot_filename
HIDDEN fr_dict_attr_t const * attr_dhcp_opcode
HIDDEN fr_dict_attr_t const * attr_dhcp_interface_mtu_size
HIDDEN fr_dict_attr_t const * attr_dhcp_subnet_selection_option
HIDDEN fr_dict_attr_t const * attr_dhcp_network_subnet
HIDDEN fr_dict_attr_t const * attr_dhcp_relay_link_selection
HIDDEN fr_dict_attr_t const * attr_dhcp_transaction_id
HIDDEN fr_dict_attr_t const * attr_dhcp_dhcp_maximum_msg_size
HIDDEN fr_dict_attr_t const * attr_dhcp_vendor_class_identifier
HIDDEN fr_dict_attr_t const * attr_dhcp_flags
HIDDEN fr_dict_attr_t const * attr_dhcp_server_host_name
size_t dhcp_header_attrs_len
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)
fr_dict_attr_t const ** dhcp_header_attrs[]
ssize_t fr_dhcpv4_decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *decode_ctx)
Decode DHCP option.
fr_packet_t * fr_dhcpv4_packet_alloc(uint8_t const *data, ssize_t data_len)
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.
int fr_dhcpv4_packet_encode(fr_packet_t *packet, fr_pair_list_t *list)
int fr_dhcpv4_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, unsigned int *code)
uint32_t fr_rand(void)
Return a 32-bit random number.
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.
unsigned int code
Packet code (type).
int id
Packet ID (used to link requests/responses).
uint8_t * data
Packet data (body).
size_t data_len
Length of packet data.
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const_push(_msg)
#define fr_strerror_const(_msg)
ssize_t fr_value_box_from_network(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv, fr_dbuff_t *dbuff, size_t len, bool tainted)
Decode a fr_value_box_t from serialized binary data.
int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert one type of fr_value_box_t to another.
static size_t char ** out