]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
one more stupid format for IPv4 prefixes
authorAlan T. DeKok <aland@freeradius.org>
Fri, 18 Mar 2022 00:05:49 +0000 (20:05 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 18 Mar 2022 13:16:29 +0000 (09:16 -0400)
share/dictionary/dhcpv4/dictionary
share/dictionary/dhcpv4/dictionary.rfc2131
share/dictionary/dhcpv4/dictionary.rfc3442 [new file with mode: 0644]
src/protocols/dhcpv4/decode.c
src/protocols/dhcpv4/encode.c
src/tests/unit/protocols/dhcpv4/rfc3442.txt [new file with mode: 0644]

index f60b711ad4b679612ef2ddb084562a38041addde..3b50828e7fa30f6f3cae158a170d24225e7f70aa 100644 (file)
@@ -24,6 +24,7 @@ $INCLUDE dictionary.freeradius.internal
 # Fixme should be broken out into separate RFCs
 $INCLUDE dictionary.rfc2131
 $INCLUDE dictionary.rfc2610
+$INCLUDE dictionary.rfc3442
 $INCLUDE dictionary.rfc4280
 $INCLUDE dictionary.rfc4578
 $INCLUDE dictionary.rfc4776
index 450bdfd19919195bad02228cb061941828b661ff..670fdf860cd647a71c76cba3c248ce6849116eef 100644 (file)
@@ -212,8 +212,7 @@ ATTRIBUTE   Subnet-Selection-Option                 118     ipaddr
 ATTRIBUTE      Domain-Search                           119     octets # really compressed, concatenated, dns_label array
 # SIP-Servers DHCP Option
 ATTRIBUTE      SIP-Servers-Option                      120     octets
-# Classless Static Route Option
-ATTRIBUTE      Classless-Static-Route                  121     octets
+
 # CableLabs Client Configuration
 ATTRIBUTE      CCC                                     122     octets
 # 16 GeoConf Option
diff --git a/share/dictionary/dhcpv4/dictionary.rfc3442 b/share/dictionary/dhcpv4/dictionary.rfc3442
new file mode 100644 (file)
index 0000000..38057a7
--- /dev/null
@@ -0,0 +1,17 @@
+# -*- text -*-
+# Copyright (C) 2022 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$
+##############################################################################
+#
+#  RFC3442 - The Classless Static Route Option for DHCPv4
+#
+#  $Id$
+#
+##############################################################################
+
+ATTRIBUTE      Classless-Static-Route                  121     struct
+MEMBER         Destination-Descriptor                  struct  array
+MEMBER         Subnet                                  ipv4prefix prefix=bits
+MEMBER         Router-IP-Address                       ipv4addr
+
index 8721647bb13847db019a6975e5bcecff8b84f3c2..f894e882f8b285ebd51c0b89a33eb39f0016008c 100644 (file)
@@ -211,6 +211,51 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t
                        vp->vp_ipv4addr = htonl(ipaddr & mask);
                        break;
                }
+
+               if (da_is_bits_prefix(vp->da)) {
+                       uint32_t ipaddr, mask;
+
+                       if ((data_len == 0) || (*p > 32)) goto raw;
+
+                       if (exact && (data_len > 5)) goto raw;
+
+                       vp->vp_ip.prefix = *p;
+
+                       if (*p > 24) {
+                               if (data_len < 5) goto raw;
+                               ipaddr = fr_net_to_uint32(p + 1);
+                               p += 5;
+
+                       } else if (*p > 16) {
+                               if (data_len < 4) goto raw;
+                               ipaddr = fr_net_to_uint24(p + 1);
+                               ipaddr <<= 8;
+                               p += 4;
+
+                       } else if (*p > 8) {
+                               if (data_len < 3) goto raw;
+                               ipaddr = fr_net_to_uint16(p + 1);
+                               ipaddr <<= 16;
+                               p += 3;
+
+                       } else if (*p > 0) {
+                               if (data_len < 2) goto raw;
+                               ipaddr = p[1];
+                               ipaddr <<= 24;
+                               p += 2;
+
+                       } else {
+                               p++;
+                               ipaddr = 0;
+                       }
+
+                       mask = ~(uint32_t) 0;
+                       mask <<= (32 - vp->vp_ip.prefix);
+
+                       vp->vp_ipv4addr = htonl(ipaddr & mask);
+                       break;
+               }
+
                FALL_THROUGH;
 
        default:
index 6a88d6d3aa87b7c1b90382333dbf76556b1645ea..aa959eae545fc710b4864ed083c2bb46722d9048 100644 (file)
@@ -143,6 +143,21 @@ static ssize_t encode_value(fr_dbuff_t *dbuff,
                        fr_dbuff_in(&work_dbuff, mask);
                        break;
                }
+
+               if (da_is_bits_prefix(vp->da)) {
+                       int num_bytes = (vp->vp_ip.prefix + 0x07) >> 3;
+
+                       fr_dbuff_in(&work_dbuff, (uint8_t) vp->vp_ip.prefix);
+
+                       if (num_bytes) {
+                               FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff,
+                                                         (uint8_t const *)&vp->vp_ipv4addr,
+                                                         num_bytes);
+                       }
+
+                       break;
+               }
+
                goto from_network;
 
        case FR_TYPE_STRING:
diff --git a/src/tests/unit/protocols/dhcpv4/rfc3442.txt b/src/tests/unit/protocols/dhcpv4/rfc3442.txt
new file mode 100644 (file)
index 0000000..b82bb5f
--- /dev/null
@@ -0,0 +1,13 @@
+proto dhcpv4
+proto-dictionary dhcpv4
+fuzzer-out dhcpv4
+
+encode-pair Classless-Static-Route = { Destination-Descriptor = { Subnet = 127.0.0.0/8, Router-IP-Address = 127.0.0.1 }, Destination-Descriptor = { Subnet = 192.168.0.0/16, Router-IP-Address = 192.168.0.1 } }
+match 79 0d 08 7f 7f 00 00 01 10 c0 a8 c0 a8 00 01
+
+decode-pair -
+match Classless-Static-Route = { Destination-Descriptor = { Subnet = 127.0.0.0/8, Router-IP-Address = 127.0.0.1 }, Destination-Descriptor = { Subnet = 192.168.0.0/16, Router-IP-Address = 192.168.0.1 } }
+
+
+count
+match 7