]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Sort option 82 sub-sub-options correctly
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 21 Nov 2016 14:00:28 +0000 (09:00 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 21 Nov 2016 14:00:28 +0000 (09:00 -0500)
src/include/dhcp.h
src/modules/proto_dhcp/dhcp.c
src/modules/proto_dhcp/proto_dhcp.c
src/modules/proto_dhcp/rlm_dhcp.c

index 4060daa8e946b236f96a375bb177fe5a5a9dd13d..b84aca7177dbe49480278f4ca3025c89a2a89239 100644 (file)
@@ -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.
  */
index b66079d5076efde93245451eeab981862ca143a0..019f09dd03f9934fedec63d2ceb7be4548d4302b 100644 (file)
@@ -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;
+}
index 1f3a6cd64308cc34569188fbdc32504cc167d72d..762848ffd7f1abea0516386733a254755a1ae967 100644 (file)
@@ -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;
 }
 
 
index 3226fa91fcecc4f4d0102862cfe6b6d599dc4e22..36f35cfef8aa2598f995e6c63cf8bd5831a25fb4 100644 (file)
@@ -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,
 };