From: Arran Cudbard-Bell Date: Mon, 21 Nov 2016 14:00:28 +0000 (-0500) Subject: Sort option 82 sub-sub-options correctly X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f821b021fa04953acbe77418cb83944d04b2bd7;p=thirdparty%2Ffreeradius-server.git Sort option 82 sub-sub-options correctly --- diff --git a/src/include/dhcp.h b/src/include/dhcp.h index 4060daa8e94..b84aca7177d 100644 --- a/src/include/dhcp.h +++ b/src/include/dhcp.h @@ -67,6 +67,8 @@ int fr_dhcp_send_raw_packet(int sockfd, struct sockaddr_ll *p_ll, RADIUS_PACKET RADIUS_PACKET *fr_dhcp_recv_raw_packet(int sockfd, struct sockaddr_ll *p_ll, RADIUS_PACKET *request); #endif +int dhcp_init(void); + /* * This is a horrible hack. */ diff --git a/src/modules/proto_dhcp/dhcp.c b/src/modules/proto_dhcp/dhcp.c index b66079d5076..019f09dd03f 100644 --- a/src/modules/proto_dhcp/dhcp.c +++ b/src/modules/proto_dhcp/dhcp.c @@ -59,6 +59,8 @@ RCSID("$Id$") # define INADDR_BROADCAST INADDR_NONE #endif +fr_dict_attr_t const *dhcp_option_82; + /* @todo: this is a hack */ # define DEBUG if (fr_debug_lvl && fr_log_fp) fr_printf_log @@ -1318,6 +1320,7 @@ int8_t fr_dhcp_attr_cmp(void const *a, void const *b) { VALUE_PAIR const *my_a = a; VALUE_PAIR const *my_b = b; + fr_dict_attr_t const *a_82, *b_82; VERIFY_VP(my_a); VERIFY_VP(my_b); @@ -1340,12 +1343,14 @@ int8_t fr_dhcp_attr_cmp(void const *a, void const *b) ((my_b->da->parent->type != PW_TYPE_TLV) && (my_b->da->attr == PW_DHCP_MESSAGE_TYPE))) return +1; /* - * Relay-Agent is last + * Relay-Agent is last. + * + * Check if either of the options are descended from option 82. */ - if ((my_a->da->parent->attr == PW_DHCP_OPTION_82) && - (my_b->da->parent->attr != PW_DHCP_OPTION_82)) return +1; - if ((my_a->da->parent->attr != PW_DHCP_OPTION_82) && - (my_b->da->parent->attr == PW_DHCP_OPTION_82)) return -1; + a_82 = fr_dict_parent_common(dhcp_option_82, my_a->da, true); + b_82 = fr_dict_parent_common(dhcp_option_82, my_b->da, true); + if (a_82 && !b_82) return +1; + if (!a_82 && !b_82) return -1; return fr_pair_cmp_by_parent_num_tag(my_a, my_b); } @@ -2226,3 +2231,20 @@ RADIUS_PACKET *fr_dhcp_recv_raw_packet(int sockfd, struct sockaddr_ll *link_laye return packet; } #endif + +/** Resolve/cache attributes in the DHCP dictionary + * + * @return + * - 0 on success. + * - -1 on failure. + */ +int dhcp_init(void) +{ + dhcp_option_82 = fr_dict_attr_by_num(NULL, DHCP_MAGIC_VENDOR, PW_DHCP_OPTION_82); + if (!dhcp_option_82) { + fr_strerror_printf("Missing dictionary attribute for DHCP-Option-82"); + return -1; + } + + return 0; +} diff --git a/src/modules/proto_dhcp/proto_dhcp.c b/src/modules/proto_dhcp/proto_dhcp.c index 1f3a6cd6430..762848ffd7f 100644 --- a/src/modules/proto_dhcp/proto_dhcp.c +++ b/src/modules/proto_dhcp/proto_dhcp.c @@ -1045,7 +1045,15 @@ static int dhcp_listen_compile(CONF_SECTION *server_cs, CONF_SECTION *listen_cs) static int dhcp_load(void) { - return fr_dict_read(main_config.dict, main_config.dictionary_dir, "dictionary.dhcp"); + int ret; + + ret = fr_dict_read(main_config.dict, main_config.dictionary_dir, "dictionary.dhcp"); + if (dhcp_init() < 0) { + ERROR("%s", fr_strerror()); + return -1; + } + + return ret; } diff --git a/src/modules/proto_dhcp/rlm_dhcp.c b/src/modules/proto_dhcp/rlm_dhcp.c index 3226fa91fce..36f35cfef8a 100644 --- a/src/modules/proto_dhcp/rlm_dhcp.c +++ b/src/modules/proto_dhcp/rlm_dhcp.c @@ -193,6 +193,18 @@ static int mod_bootstrap(UNUSED CONF_SECTION *conf, void *instance) return 0; } +static int dhcp_load(void) +{ + int ret; + + ret = fr_dict_read(main_config.dict, main_config.dictionary_dir, "dictionary.dhcp"); + if (dhcp_init() < 0) { + ERROR("%s", fr_strerror()); + return -1; + } + + return ret; +} /* * The module name should be the only globally exported symbol. @@ -208,5 +220,7 @@ rad_module_t rlm_dhcp = { .magic = RLM_MODULE_INIT, .name = "dhcp", .inst_size = sizeof(rlm_dhcp_t), + + .load = dhcp_load, .bootstrap = mod_bootstrap, };