commit a1417f4046affc5f761f3c7aac031482951d5555 Author: clerie Date: Tue Dec 12 18:30:30 2023 +0100 Init repo diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fcfc4a1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +result* diff --git a/README.md b/README.md new file mode 100644 index 0000000..87a2b58 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Juniper Vendor Specific Attributes comparison table + +[You can find the table in my Wiki](https://wiki.clerie.de/notiz/juniper-vendor-specific-attributes-freeradius-comparison) + +This is just a quick and dirty script to generate the comparison table. diff --git a/dictionary.juniper b/dictionary.juniper new file mode 100644 index 0000000..868d0b0 --- /dev/null +++ b/dictionary.juniper @@ -0,0 +1,156 @@ +# FreeRADIUS dictionary like representation of the official Juniper VSAs names +# sourced from https://www.juniper.net/documentation/us/en/software/junos/subscriber-mgmt-sessions/topics/topic-map/radius-std-attributes-vsas-support.html#id-juniper-networks-vsas-supported-by-the-aaa-service-framework +# +# This file just looks like FreeRADIUS dictionary syntax and needs modification +# if it should get used by FreeRADIUS + +VENDOR Juniper 4874 + +BEGIN-VENDOR Juniper + +ATTRIBUTE Virtual-Router 1 +ATTRIBUTE Primary-DNS 4 +ATTRIBUTE Secondary-DNS 5 +ATTRIBUTE Primary-WINS 6 +ATTRIBUTE Secondary-WINS 7 +ATTRIBUTE Tunnel-Virtual-Router 8 +ATTRIBUTE Tunnel-Password 9 +ATTRIBUTE Ingress-Policy-Name 10 +ATTRIBUTE Egress-Policy-Name 11 +ATTRIBUTE IGMP-Enable 23 +ATTRIBUTE PPPoE-Description 24 +ATTRIBUTE Redirect-VRouter-Name 25 +ATTRIBUTE Tunnel-Nas-Port-Method 30 +ATTRIBUTE Service-Bundle 31 +ATTRIBUTE Tunnel-Max-Sessions 33 +ATTRIBUTE Framed-IP-Route-Tag. 34 +ATTRIBUTE Input-Gigapackets 42 +ATTRIBUTE Output-Gigapackets 43 +ATTRIBUTE Ipv6-Primary-DNS 47 +ATTRIBUTE Ipv6-Secondary-DNS 48 +ATTRIBUTE Disconnect-Cause 51 +ATTRIBUTE DHCP-Options 55 +ATTRIBUTE DHCP-MAC-Address 56 +ATTRIBUTE DHCP-GI-Address 57 +ATTRIBUTE LI-Action 58 +ATTRIBUTE Med-Dev-Handle 59 +ATTRIBUTE Med-Ip-Address 60 +ATTRIBUTE Med-Port-Number 61 +ATTRIBUTE Interface-Desc 63 +ATTRIBUTE Tunnel-Group 64 +ATTRIBUTE Activate-Service 65 +ATTRIBUTE Deactivate-Service 66 +ATTRIBUTE Service-Volume 67 +ATTRIBUTE Service-Timeout 68 +ATTRIBUTE Service-Statistics 69 +ATTRIBUTE IGMP-Access-Name 71 +ATTRIBUTE IGMP-Access-Src-Name 72 +ATTRIBUTE MLD-Access-Name 74 +ATTRIBUTE MLD-Access-Src-Name 75 +ATTRIBUTE MLD-Version 77 +ATTRIBUTE IGMP-Version 78 +ATTRIBUTE Service-Session 83 +ATTRIBUTE Tunnel-Switch-Profile 91 +ATTRIBUTE L2C-Up-Stream-Data 92 +ATTRIBUTE L2C-Down-Stream-Data 93 +ATTRIBUTE Tunnel-Tx-Speed-Method 94 +ATTRIBUTE IGMP-Immediate-Leave 97 +ATTRIBUTE MLD-Immediate-Leave 100 +ATTRIBUTE IPv6-Ingress-Policy-Name 106 +ATTRIBUTE IPv6-Egress-Policy-Name 107 +ATTRIBUTE CoS-Parameter-Type 108 +ATTRIBUTE DHCP-Guided-Relay-Server 109 +ATTRIBUTE Acc-Loop-Cir-Id 110 +ATTRIBUTE Acc-Aggr-Cir-Id-Bin 111 +ATTRIBUTE Acc-Aggr-Cir-Id-Asc 112 +ATTRIBUTE Act-Data-Rate-Up 113 +ATTRIBUTE Act-Data-Rate-Dn 114 +ATTRIBUTE Min-Data-Rate-Up 115 +ATTRIBUTE Min-Data-Rate-Dn 116 +ATTRIBUTE Att-Data-Rate-Up 117 +ATTRIBUTE Att-Data-Rate-Dn 118 +ATTRIBUTE Max-Data-Rate-Up 119 +ATTRIBUTE Max-Data-Rate-Dn 120 +ATTRIBUTE Min-LP-Data-Rate-Up 121 +ATTRIBUTE Min-LP-Data-Rate-Dn 122 +ATTRIBUTE Max-Interlv-Delay-Up 123 +ATTRIBUTE Act-Interlv-Delay-Up 124 +ATTRIBUTE Max-Interlv-Delay-Dn 125 +ATTRIBUTE Act-Interlv-Delay-Dn 126 +ATTRIBUTE DSL-Line-State 127 +ATTRIBUTE DSL-Type 128 +ATTRIBUTE Qos-Set-Name 130 +ATTRIBUTE Service-Interim-Acct-Interval 140 +ATTRIBUTE Downstream-Calculated-QoS-Rate 141 +ATTRIBUTE Upstream-Calculated-QoS-Rate 142 +ATTRIBUTE Max-Clients-Per-Interface 143 +ATTRIBUTE CoS-Scheduler-Pmt-Type 146 +ATTRIBUTE IPv6-Acct-Input-Octets 151 +ATTRIBUTE IPv6-Acct-Output-Octets 152 +ATTRIBUTE IPv6-Acct-Input-Packets 153 +ATTRIBUTE IPv6-Acct-Output-Packets 154 +ATTRIBUTE IPv6-Acct-Input-Gigawords 155 +ATTRIBUTE IPv6-Acct-Output-Gigawords 156 +ATTRIBUTE PPPoE-Padn 158 +ATTRIBUTE Vlan-Map-Id 160 +ATTRIBUTE IPv6-Delegated-Pool-Name 161 +ATTRIBUTE Tx-Connect-Speed 162 +ATTRIBUTE Rx-Connect-Speed 163 +ATTRIBUTE IPv4-Release-Control 164 +ATTRIBUTE Service-Activate-Type 173 +ATTRIBUTE Client-Profile-Name 174 +ATTRIBUTE Cos-Shaping-Rate 177 +ATTRIBUTE Action-Reason 178 +ATTRIBUTE Service-Volume-Gigawords 179 +ATTRIBUTE Update-Service 180 +ATTRIBUTE DHCPv6-Guided-Relay-Server 181 +ATTRIBUTE Acc-Loop-Remote-Id 182 +ATTRIBUTE Acc-Loop-Encap 183 +ATTRIBUTE Inner-Vlan-Map-Id 184 +ATTRIBUTE Core-Facing-Interface 185 +ATTRIBUTE DHCP-First-Relay-IPv4-Address 189 +ATTRIBUTE DHCP-First-Relay-IPv6-Address 190 +ATTRIBUTE Input-Interface-Filter 191 +ATTRIBUTE Output-Interface-Filter 192 +ATTRIBUTE Pim-Enable 193 +ATTRIBUTE Bulk-CoA-Transaction-Id 194 +ATTRIBUTE Bulk-CoA-Identifier 195 +ATTRIBUTE IPv4-Input-Service-Set 196 +ATTRIBUTE IPv4-Output-Service-Set 197 +ATTRIBUTE IPv4-Input-Service-Filter 198 +ATTRIBUTE IPv4-Output-Service-Filter 199 +ATTRIBUTE IPv6-Input-Service-Set 200 +ATTRIBUTE IPv6-Output-Service-Set 201 +ATTRIBUTE IPv6-Input-Service-Filter 202 +ATTRIBUTE IPv6-Output-Service-Filter 203 +ATTRIBUTE Adv-Pcef-Profile-Name 204 +ATTRIBUTE Adv-Pcef-Rule-Name 205 +ATTRIBUTE Reauthentication-On-Renew 206 +ATTRIBUTE DHCPv6-Options 207 +ATTRIBUTE DHCP-Header 208 +ATTRIBUTE DHCPv6-Header 209 +ATTRIBUTE Acct-Request-Reason 210 +ATTRIBUTE Inner-Tag-Protocol-Id 211 +ATTRIBUTE Routing-Services 212 +ATTRIBUTE Interface-Set-Targeting-Weight 213 +ATTRIBUTE Interface-Targeting-Weight 214 +ATTRIBUTE Hybrid-Access-DSL-Downstream-Speed 216 +ATTRIBUTE Hybrid-Access-LTE-Downstream-Speed 217 +ATTRIBUTE Connection-Status-Message 218 +ATTRIBUTE PON-Access-Type 219 +ATTRIBUTE ONT/ONU-Average-Data-Rate-Downstream 220 +ATTRIBUTE ONT/ONU-Peak-Data-Rate-Downstream 221 +ATTRIBUTE ONT/ONU-Maximum-Data-Rate-Upstream 222 +ATTRIBUTE ONT/ONU-Assured-Data-Rate-Upstream 223 +ATTRIBUTE PON-Tree-Maximum-Data-Rate-Upstream 224 +ATTRIBUTE PON-Tree-Maximum-Data-Rate-Downstream 225 +ATTRIBUTE Expected-Throughput-Upstream 226 +ATTRIBUTE Expected-Throughput-Downstream 227 +ATTRIBUTE Attainable-Expected-Throughput-Upstream 228 +ATTRIBUTE Attainable-Expected-Throughput-Downstream 229 +ATTRIBUTE Gamma-Data-Rate-Upstream 230 +ATTRIBUTE Gamma-Data-Rate-Downstream 231 +ATTRIBUTE Attainable-Gamma-Data-Rate-Upstream 232 +ATTRIBUTE Attainable-Gamma-Data-Rate-Downstream 233 + +END-VENDOR Juniper diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..b332500 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1702151865, + "narHash": "sha256-9VAt19t6yQa7pHZLDbil/QctAgVsA66DLnzdRGqDisg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "666fc80e7b2afb570462423cb0e1cf1a3a34fedd", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..b8fc5ed --- /dev/null +++ b/flake.nix @@ -0,0 +1,25 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + outputs = { self, nixpkgs, ... }: { + packages.x86_64-linux = let + pkgs = import nixpkgs { + system = "x86_64-linux"; + }; + in { + juniper-radius-vsas = pkgs.python311Packages.buildPythonPackage rec { + pname = "juniper-radius-vsas"; + version = "0.0.1"; + + src = ./.; + + format = "pyproject"; + + buildInputs = [ pkgs.python311Packages.hatchling ]; + propagatedBuildInputs = with pkgs.python311Packages; [ requests ]; + }; + default = self.packages.x86_64-linux.juniper-radius-vsas; + }; + }; +} diff --git a/parse_freeradius_dictionary.py b/parse_freeradius_dictionary.py new file mode 100755 index 0000000..f998a53 --- /dev/null +++ b/parse_freeradius_dictionary.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 + +from pathlib import Path +import requests + + +def parse_freeradius_dictionary(text, freeradius4=False): + vendors = {} + current_vendor = None + avs = {} + + for line in text.splitlines(): + if line.startswith("VENDOR"): + elements = line.split("#")[0].split() + vendors[elements[1]] = int(elements[2]) + + elif line.startswith("BEGIN-VENDOR"): + elements = line.split("#")[0].split() + if elements[1] in vendors: + current_vendor = elements[1] + else: + raise Exception(f"Vendor {elements[1]} not declared") + + elif line.startswith("END-VENDOR"): + current_vendor = None + + elif line.startswith("ATTRIBUTE"): + elements = line.split("#")[0].split() + + avs[f"26.{vendors[current_vendor]}.{int(elements[2])}"] = elements[1] if not freeradius4 else f"Vendor-Specific.{current_vendor}.{elements[1]}" + + return avs + +def merge_avs(av_dicts): + merged_avs = {} + + for source, d in av_dicts.items(): + for attr, name in d.items(): + if attr not in merged_avs: + merged_avs[attr] = {} + + merged_avs[attr][source] = name + + + return merged_avs + +def sort_attribute_key(key): + a,b,c = key.split(".") + return f"{int(a):04d}.{int(b):08d}.{int(c):08d}" + +def to_dokuwiki(merged_avs): + out = "" + + cols = list(next(iter(merged_avs.items()))[1].keys()) + + out +="^ " + " ^ ".join( ["id"] + cols) + " ^\n" + + avs = sorted(list(merged_avs.keys()), key=sort_attribute_key) + + for av in avs: + line = [] + line.append(av) + + for col in cols: + if col in merged_avs[av]: + line.append(merged_avs[av][col]) + else: + line.append("") + + out += "| " + " | ".join(line) + " |\n" + + return out + + +if __name__ == "__main__": + + av_dicts = {} + + # Official Juniper VSAs + text = Path("dictionary.juniper").read_text() + av_dicts["juniper"] = parse_freeradius_dictionary(text) + + # v2.x.x + r = requests.get("https://raw.githubusercontent.com/FreeRADIUS/freeradius-server/v2.x.x/share/dictionary.erx") + r.raise_for_status() + av_dicts["freeradius_2.x.x"] = parse_freeradius_dictionary(r.text) + + # v3.0.x + r = requests.get("https://raw.githubusercontent.com/FreeRADIUS/freeradius-server/v3.0.x/share/dictionary.erx") + r.raise_for_status() + av_dicts["freeradius_3.0.x"] = parse_freeradius_dictionary(r.text) + + # v3.2.x + r = requests.get("https://raw.githubusercontent.com/FreeRADIUS/freeradius-server/v3.2.x/share/dictionary.erx") + r.raise_for_status() + av_dicts["freeradius_3.2.x"] = parse_freeradius_dictionary(r.text) + + # v4.0-alpha1 + r = requests.get("https://raw.githubusercontent.com/FreeRADIUS/freeradius-server/release_4_0_alpha1/share/dictionary/radius/dictionary.unisphere") + r.raise_for_status() + av_dicts["freeradius_4.0-alpha1"] = parse_freeradius_dictionary(r.text, freeradius4=True) + + print(to_dokuwiki(merge_avs(av_dicts))) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..2a340cc --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,18 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "juniper-radius-vsas" +version = "0.0.1" +authors = [ + { name="clerie", email="hallo@clerie.de" }, +] +description = "" +readme = "README.md" +requires-python = ">=3.11" + +dependencies = [ + "requests", +] +