]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add preliminary RADIUS MIB
authorAlan T. DeKok <aland@freeradius.org>
Mon, 12 Jan 2026 19:51:38 +0000 (14:51 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 12 Jan 2026 20:31:30 +0000 (15:31 -0500)
./scripts/bin/radict -F struct -M -p radius mib-2.radiusAuthServ

which doesn't have the client table, but it's a start.  And the
resulting structure isn't too bad.

Todo:

* have callbacks for specific fields.  e.g. uptime.
  * Those callbacks should be defined globally, and passed a uctx.
  * the callback can then update the field before it's copied out
    to the caller

share/dictionary/radius/dictionary
share/dictionary/radius/dictionary.stats [new file with mode: 0644]
src/bin/radict.c

index b2015ef35c7ab800fea39090e99a01c16be6e48e..ea6b40da7930ad8956554dea1779cdddb0a90d05 100644 (file)
@@ -159,7 +159,6 @@ $INCLUDE dictionary.fortinet
 $INCLUDE dictionary.foundry
 $INCLUDE dictionary.freeradius
 $INCLUDE dictionary.freeradius.evs5
-$INCLUDE dictionary.freeradius.internal
 $INCLUDE dictionary.freeswitch
 $INCLUDE dictionary.gandalf
 $INCLUDE dictionary.garderos
@@ -292,4 +291,10 @@ $INCLUDE dictionary.zeus
 $INCLUDE dictionary.zte
 $INCLUDE dictionary.zyxel
 
+#
+#  Internal attributes used by the server.
+#
+$INCLUDE dictionary.freeradius.internal
+$INCLUDE dictionary.stats
+
 END-PROTOCOL RADIUS
diff --git a/share/dictionary/radius/dictionary.stats b/share/dictionary/radius/dictionary.stats
new file mode 100644 (file)
index 0000000..1c601bf
--- /dev/null
@@ -0,0 +1,42 @@
+# -*- text -*-
+# Copyright (C) 2026 The FreeRADIUS Server project and contributors
+# This work is licensed under CC-BY version 4.0 https://creativecommons.org/licenses/by/4.0
+# Version $Id$
+#
+DEFINE mib-2                                           tlv     internal
+
+BEGIN mib-2
+ATTRIBUTE      radiusMIB                               67      tlv
+
+ATTRIBUTE      radiusAuthentication                    67.1    tlv
+ATTRIBUTE      radiusAuthServMIB                       67.1.1  tlv
+ATTRIBUTE      radiusAuthServMIBObjects                67.1.1.1        tlv
+ATTRIBUTE      radiusAuthServ                          67.1.1.1.1      tlv
+
+#
+#  These names are huge and long.  They also have most of the "full path" in them.
+#  we arguably want to convert these to more RADIUS style names, especially for
+#  the C structure names.
+#
+#  i.e. get rid of the "radiusAuthServ" prefix, and change mashed camel case to
+#  camel case with dashes.
+#
+ATTRIBUTE      radiusAuthServIdent                     .1      string
+ATTRIBUTE      radiusAuthServUpTime                    .2      time_delta precision=centiseconds
+ATTRIBUTE      radiusAuthServResetTime                 .3      time_delta precision=centiseconds
+ATTRIBUTE      radiusAuthServConfigReset               .4      uint32
+ATTRIBUTE      radiusAuthServTotalAccessRequests       .5      uint32 counter
+ATTRIBUTE      radiusAuthServTotalInvalidRequests      .6      uint32 counter
+ATTRIBUTE      radiusAuthServTotalDupAccessRequests    .7      uint32 counter
+ATTRIBUTE      radiusAuthServTotalAccessAccepts        .8      uint32 counter
+ATTRIBUTE      radiusAuthServTotalAccessRejects        .9      uint32 counter
+ATTRIBUTE      radiusAuthServTotalAccessChallenges     .10     uint32 counter
+ATTRIBUTE      radiusAuthServTotalMalformedAccessRequests .11  uint32 counter
+ATTRIBUTE      radiusAuthServTotalBadAuthenticators    .12     uint32 counter
+ATTRIBUTE      radiusAuthServTotalPacketsDropped       .13     uint32 counter
+ATTRIBUTE      radiusAuthServTotalUnknownTypes         .14     uint32 counter
+#ATTRIBUTE     radiusAuthClientTable                   .15     tlv
+
+ALIAS          radiusAuthServ                          .radiusMIB.radiusAuthentication.radiusAuthServMIB.radiusAuthServMIBObjects.radiusAuthServ
+
+END mib-2
index 9029918f0795d286e6c5bdf473db0529cce6ea8d..165853a933dddfd197d6ebb08375bce6b9b2ec9d 100644 (file)
@@ -51,6 +51,7 @@ static fr_dict_t *dicts[255];
 static bool print_values = false;
 static bool print_headers = false;
 static bool print_recursive = false;
+static bool mibs = false;
 static radict_out_t output_format = RADICT_OUT_FANCY;
 static fr_dict_t **dict_end = dicts;
 
@@ -71,6 +72,7 @@ static void usage(void)
        fprintf(stderr, "  -E               Export dictionary definitions.\n");
        fprintf(stderr, "  -h               Print help text.\n");
        fprintf(stderr, "  -H               Show the headers of each field.\n");
+       fprintf(stderr, "  -M               Mangle names for MIBs.\n");
        fprintf(stderr, "  -p <protocol>    Set protocol by name\n");
        fprintf(stderr, "  -r               Write out attributes recursively.\n");
        fprintf(stderr, "  -V               Write out all attribute values.\n");
@@ -288,8 +290,9 @@ static char const *type_to_c_type[] = {
 
        [FR_TYPE_IPV4_ADDR]                     = "struct in_addr",
        [FR_TYPE_IPV6_ADDR]                     = "struct in6_addr",
-       [FR_TYPE_IFID]                          = "fr_ifid_t",
-       [FR_TYPE_ETHERNET]                      = "fr_ethernet_t",
+
+//     [FR_TYPE_IFID]                          = "fr_ifid_t",
+//     [FR_TYPE_ETHERNET]                      = "fr_ethernet_t",
 
        [FR_TYPE_UINT8]                         = "uint8_t",
        [FR_TYPE_UINT16]                        = "uint16_t",
@@ -301,6 +304,9 @@ static char const *type_to_c_type[] = {
        [FR_TYPE_INT32]                         = "int32_t",
        [FR_TYPE_INT64]                         = "int64_t",
 
+       [FR_TYPE_DATE]                          = "fr_time_t",
+       [FR_TYPE_TIME_DELTA]                    = "fr_time_delta_t",
+
        [FR_TYPE_MAX]                           = 0     //!< Ensure array covers all types.
 };
 
@@ -312,12 +318,40 @@ static char const *length_to_c_type[] = {
 
 static void da_normalize_name(fr_dict_attr_t const *da, char buffer[static FR_DICT_ATTR_MAX_NAME_LEN + 1])
 {
+       char const *start = da->name;
        char const *p;
-       char *q;
+       char    *q;
+       bool    mangle = false;
+
+       /*
+        *      The RADIUS MIBs have lots of repetition.  So we do some simple mangling of the names to make
+        *      them easier to understand.
+        */
+       if (mibs && da->parent) {
+               size_t  len;
+
+               len = strlen(da->parent->name);
+       
+               /*
+                *      "radiusAuthServer" and "radiusAuthServTotalAccessRejects"
+                *      to "total_access_rejects"
+                *
+                *      Otherwise "radiusAuthServer" in the "RADIUS" dictionary, to "auth_server"
+                */
+               mangle = (strncmp(da->parent->name, da->name, len) == 0);
+               if (!mangle) {
+                       fr_dict_attr_t const *root = fr_dict_root(da->dict);
+
+                       len = strlen(root->name);
+                       mangle = (strncasecmp(root->name, da->name, len) == 0);
+               }
+
+               if (mangle) start += len;
+       }
 
        q = buffer;
 
-       for (p = da->name; *p != '\0'; p++) {
+       for (p = start; *p != '\0'; p++) {
                if ((*p >= '0') && (*p <= '9')) {
                        *q++ = *p;
                        continue;
@@ -329,6 +363,10 @@ static void da_normalize_name(fr_dict_attr_t const *da, char buffer[static FR_DI
                }
 
                if (isupper((unsigned int) *p)) {
+                       if (mangle && (p > start)) {
+                               *(q++) = '_';
+                       }
+
                        *q++ = tolower((unsigned int)*p);
                        continue;
                }
@@ -696,7 +734,7 @@ int main(int argc, char *argv[])
        fr_debug_lvl = 1;
        fr_log_fp = stdout;
 
-       while ((c = getopt(argc, argv, "AcfF:ED:p:rVxhH")) != -1) switch (c) {
+       while ((c = getopt(argc, argv, "AcfF:ED:Mp:rVxhH")) != -1) switch (c) {
                case 'A':
                        alias = true;
                        break;
@@ -749,6 +787,10 @@ int main(int argc, char *argv[])
                        dict_dir = optarg;
                        break;
 
+               case 'M':
+                       mibs = true;
+                       break;
+
                case 'p':
                        protocol = optarg;
                        break;