extern fr_dict_attr_t const *attr_dhcp_parameter_request_list;
extern fr_dict_attr_t const *attr_dhcp_overload;
extern fr_dict_attr_t const *attr_dhcp_vendor_class_identifier;
+extern fr_dict_attr_t const *attr_dhcp_relay_link_selection;
+extern fr_dict_attr_t const *attr_dhcp_subnet_selection_option;
+extern fr_dict_attr_t const *attr_dhcp_network_ip_address;
fr_dict_attr_t const *attr_dhcp_parameter_request_list;
fr_dict_attr_t const *attr_dhcp_overload;
fr_dict_attr_t const *attr_dhcp_vendor_class_identifier;
+fr_dict_attr_t const *attr_dhcp_relay_link_selection;
+fr_dict_attr_t const *attr_dhcp_subnet_selection_option;
+fr_dict_attr_t const *attr_dhcp_network_ip_address;
extern fr_dict_attr_autoload_t dhcpv4_dict_attr[];
fr_dict_attr_autoload_t dhcpv4_dict_attr[] = {
{ .out = &attr_dhcp_parameter_request_list, .name = "DHCP-Parameter-Request-List", .type = FR_TYPE_UINT8, .dict = &dict_dhcpv4 },
{ .out = &attr_dhcp_overload, .name = "DHCP-Overload", .type = FR_TYPE_UINT8, .dict = &dict_dhcpv4 },
{ .out = &attr_dhcp_vendor_class_identifier, .name = "DHCP-Vendor-Class-Identifier", .type = FR_TYPE_OCTETS, .dict = &dict_dhcpv4 },
+ { .out = &attr_dhcp_relay_link_selection, .name = "DHCP-Relay-Link-Selection", .type = FR_TYPE_IPV4_ADDR, .dict = &dict_dhcpv4 },
+ { .out = &attr_dhcp_subnet_selection_option, .name = "DHCP-Subnet-Selection-Option", .type = FR_TYPE_IPV4_ADDR, .dict = &dict_dhcpv4 },
+ { .out = &attr_dhcp_network_ip_address, .name = "DHCP-Network-IP-Address", .type = FR_TYPE_IPV4_ADDR, .dict = &dict_dhcpv4 },
{ NULL }
};
uint32_t giaddr;
fr_cursor_t cursor;
VALUE_PAIR *head = NULL, *vp;
- VALUE_PAIR *maxms, *mtu;
+ VALUE_PAIR *maxms, *mtu, *netaddr;
fr_cursor_init(&cursor, &head);
}
}
+ /*
+ * Determine the address to use in looking up which subnet the
+ * client belongs to based on packet data. The sequence here
+ * is based on ISC DHCP behaviour and RFCs 3527 and 3011. We
+ * store the found address in an internal attribute of
+ * DHCP-Network-IP-Address.
+ */
+ vp = fr_pair_afrom_da(ctx, attr_dhcp_network_ip_address);
+ /*
+ * First look for Relay-Link-Selection
+ */
+ netaddr = fr_pair_find_by_da(head, attr_dhcp_relay_link_selection);
+ if (!netaddr) {
+ /*
+ * Next try Subnet-Selection-Option
+ */
+ netaddr = fr_pair_find_by_da(head, attr_dhcp_subnet_selection_option);
+ }
+ if (!netaddr) {
+ if (giaddr != htonl(INADDR_ANY)) {
+ /*
+ * Gateway address is set - use that one
+ */
+ fr_value_box_from_network(vp, &vp->data, vp->vp_type, vp->da,
+ data + 24, 4, true);
+ } else {
+ /*
+ * else, store client address whatever it is
+ */
+ fr_value_box_from_network(vp, &vp->data, vp->vp_type, vp->da,
+ data + 12, 4, true);
+ }
+ } else {
+ /*
+ * Store whichever address we found from options
+ */
+ fr_value_box_copy(vp, &vp->data, &netaddr->data);
+ }
+ fr_cursor_append(&cursor, vp);
+
/*
* Client can request a LARGER size, but not a smaller
* one. They also cannot request a size larger than MTU.