{ NULL }
};
+size_t const fr_dhcpv4_attr_sizes[FR_TYPE_MAX + 1][2] = {
+ [FR_TYPE_NULL] = {~0, 0},
+
+ [FR_TYPE_STRING] = {0, ~0},
+ [FR_TYPE_OCTETS] = {0, ~0},
+
+ [FR_TYPE_IPV4_ADDR] = {4, 4},
+ [FR_TYPE_IPV4_PREFIX] = {1, 5}, //!< Zero length prefix still requires one byte for prefix len.
+ [FR_TYPE_IPV6_ADDR] = {16, 16},
+ [FR_TYPE_IPV6_PREFIX] = {1, 17}, //!< Zero length prefix still requires one byte for prefix len.
+ [FR_TYPE_IFID] = {8, 8},
+ [FR_TYPE_ETHERNET] = {6, 6},
+
+ [FR_TYPE_BOOL] = {1, 1},
+ [FR_TYPE_UINT8] = {1, 1},
+ [FR_TYPE_UINT16] = {2, 2},
+ [FR_TYPE_UINT32] = {4, 4},
+ [FR_TYPE_UINT64] = {8, 8},
+
+ [FR_TYPE_TLV] = {2, ~0},
+ [FR_TYPE_STRUCT] = {1, ~0},
+
+ [FR_TYPE_MAX] = {~0, 0} //!< Ensure array covers all types.
+};
+
/*
* INADDR_ANY : 68 -> INADDR_BROADCAST : 67 DISCOVER
* INADDR_BROADCAST : 68 <- SERVER_IP : 67 OFFER
return fr_pair_cmp_by_parent_num(my_a, my_b);
}
+/** Return the on-the-wire length of an attribute value
+ *
+ * @param[in] vp to return the length of.
+ * @return the length of the attribute.
+ */
+size_t fr_dhcpv4_option_len(fr_pair_t const *vp)
+{
+ switch (vp->vp_type) {
+ case FR_TYPE_VARIABLE_SIZE:
+#ifndef NDEBUG
+ if (!vp->da->flags.extra &&
+ (vp->da->flags.subtype == FLAG_ENCODE_DNS_LABEL)) {
+ fr_assert_fail("DNS labels MUST be encoded/decoded with their own function, and not with generic 'string' functions");
+ return 0;
+ }
+#endif
+
+ if (vp->da->flags.length) return vp->da->flags.length; /* Variable type with fixed length */
+
+ /*
+ * Arrays get maxed at 2^8 - 1
+ */
+ if (vp->da->flags.array && ((vp->vp_type == FR_TYPE_STRING) || (vp->vp_type == FR_TYPE_OCTETS))) {
+ if (vp->vp_length > 255) return 255;
+ }
+
+ return vp->vp_length;
+
+ case FR_TYPE_DATE:
+ case FR_TYPE_TIME_DELTA:
+ if (vp->data.enumv->flags.length) return vp->data.enumv->flags.length;
+ return sizeof(uint32_t);
+
+ case FR_TYPE_STRUCTURAL:
+ fr_assert_fail(NULL);
+ return 0;
+
+ default:
+ return fr_dhcpv4_attr_sizes[vp->vp_type][0];
+ }
+}
+
/** Check received DHCP request is valid and build fr_radius_packet_t structure if it is
*
* @param data pointer to received packet.
#include <freeradius-devel/util/packet.h>
#include <freeradius-devel/protocol/dhcpv4/rfc2131.h>
+extern size_t const fr_dhcpv4_attr_sizes[FR_TYPE_MAX + 1][2];
+
#define DHCP_CHADDR_LEN (16)
#define DHCP_SNAME_LEN (64)
#define DHCP_FILE_LEN (128)
*/
int8_t fr_dhcpv4_attr_cmp(void const *a, void const *b);
+size_t fr_dhcpv4_option_len(fr_pair_t const *vp);
bool fr_dhcpv4_ok(uint8_t const *data, ssize_t data_len, uint8_t *message_type, uint32_t *xid);
fr_radius_packet_t *fr_dhcpv4_packet_alloc(uint8_t const *data, ssize_t data_len);
bool fr_dhcpv4_is_encodable(void const *item, void const *uctx);