From 5db09725a3ba8b50990313953d2acb0ce74f1167 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 27 Oct 2020 02:56:28 +0000 Subject: [PATCH] martians: overhaul - Use the XML files instead of the CSV - Separate output in inbound and outbound tables - Add script for producing all the outputs --- utils/openbsd/pf-martians/generate-tables.sh | 17 + .../iana-ip-special-registry-parser.py | 125 ++++-- .../iana-ipv4-special-registry-1.csv | 25 -- .../iana-ipv4-special-registry.xml | 359 ++++++++++++++++++ .../iana-ipv6-special-registry-1.csv | 23 -- .../iana-ipv6-special-registry.xml | 323 ++++++++++++++++ 6 files changed, 793 insertions(+), 79 deletions(-) create mode 100644 utils/openbsd/pf-martians/generate-tables.sh delete mode 100644 utils/openbsd/pf-martians/iana-ipv4-special-registry-1.csv create mode 100644 utils/openbsd/pf-martians/iana-ipv4-special-registry.xml delete mode 100644 utils/openbsd/pf-martians/iana-ipv6-special-registry-1.csv create mode 100644 utils/openbsd/pf-martians/iana-ipv6-special-registry.xml diff --git a/utils/openbsd/pf-martians/generate-tables.sh b/utils/openbsd/pf-martians/generate-tables.sh new file mode 100644 index 0000000..c7f4436 --- /dev/null +++ b/utils/openbsd/pf-martians/generate-tables.sh @@ -0,0 +1,17 @@ +#!/bin/sh +script=iana-ip-special-registry-parser.py + +process_xml() +{ + v=$1 + dir=$2 + in=iana-ip$v-special-registry.xml + out=martians-$v-${dir%bound}.txt + + python3 "$script" "$dir" <"$in" >"$out" +} + +process_xml v4 inbound +process_xml v4 outbound +process_xml v6 inbound +process_xml v6 outbound diff --git a/utils/openbsd/pf-martians/iana-ip-special-registry-parser.py b/utils/openbsd/pf-martians/iana-ip-special-registry-parser.py index 87d729b..5c4faff 100644 --- a/utils/openbsd/pf-martians/iana-ip-special-registry-parser.py +++ b/utils/openbsd/pf-martians/iana-ip-special-registry-parser.py @@ -1,38 +1,101 @@ #!/usr/bin/env python3 -import csv -import re +import argparse +from enum import Enum import sys +import xml.sax -REGEX_FOOTNOTES = re.compile(r" \[\d+\]") -REGEX_WHITESPACES = re.compile(r"\s+") -def parse_iana_csv(csvfile): - reader = csv.DictReader(csvfile) - for row in reader: - fmt = "" - reachable = row["Globally Reachable"] - if reachable == "": - continue - if "False" in reachable: - fmt = "{}" - elif "True" in reachable: - fmt = "!{}" - elif "N/A" in reachable: - fmt = "#{}" - else: - fmt = "#[" + reachable + "]: {}" - blocks = row["Address Block"] - blocks = REGEX_FOOTNOTES.sub("", blocks) - blocks = REGEX_WHITESPACES.sub("", blocks) - for block in blocks.split(","): - print(fmt.format(block)) +class ParserState(Enum): + NOOP = 0 + DISCARD = 1 + CAPTURE = 2 + + +class IPDisallowedHandler(xml.sax.ContentHandler): + TRANSITIONS = { + "address": ParserState.CAPTURE, + "source": ParserState.CAPTURE, + "destination": ParserState.CAPTURE, + "global": ParserState.CAPTURE, + } + + def __init__(self): + self._reset() + + def _reset(self): + self._state = ParserState.NOOP + self._address = None + self._source = None + self._destination = None + self._global = None + self._content = "" + + def _processElement(self, name): + pass + + def startElement(self, name, attrs): + if name == "record": + self._state = ParserState.DISCARD + return + if self._state == ParserState.NOOP: + return + + self._state = self.TRANSITIONS.get(name, ParserState.DISCARD) + + def endElement(self, name): + if name == "record": + if self._address is not None: + self._processElement() + self._reset() + if self._state == ParserState.NOOP: + return + + if self._content == "": + return + self._content = self._content.strip() + if name == "address": + self._address = self._content.split(", ") + if name == "source": + self._source = self._content == "True" + if name == "destination": + self._destination = self._content == "True" + if name == "global": + self._global = self._content == "True" + self._content = "" + self._state = ParserState.DISCARD + + def characters(self, content): + if self._state != ParserState.CAPTURE: + return + self._content += content + + +class IPDisallowedInboundHandler(IPDisallowedHandler): + def _processElement(self): + if not self._source: + for address in self._address: + print(address) + + +class IPDisallowedOutboundHandler(IPDisallowedHandler): + def _processElement(self): + # Document states: + # > If the value of "Destination" is FALSE, the values of + # > "Forwardable" and "Globally Reachable" must also be false. + # So, `self._destination == False` implies `self._global == + # False.` For this reason, it's enough to test for + # `self._global == False`. + if not self._global: + for address in self._address: + print(address) if __name__ == "__main__": - def usage(): - print("Usage: {}".format(sys.argv[1]), file=sys.stderr) - sys.exit(1) + parser = argparse.ArgumentParser() + parser.add_argument("direction", choices=["inbound", "outbound"]) + args = parser.parse_args() - if len(sys.argv) != 1: - usage() - - parse_iana_csv(sys.stdin) + if args.direction == "inbound": + handler = IPDisallowedInboundHandler() + else: + handler = IPDisallowedOutboundHandler() + xml.sax.parse(sys.stdin, handler) diff --git a/utils/openbsd/pf-martians/iana-ipv4-special-registry-1.csv b/utils/openbsd/pf-martians/iana-ipv4-special-registry-1.csv deleted file mode 100644 index 356f37f..0000000 --- a/utils/openbsd/pf-martians/iana-ipv4-special-registry-1.csv +++ /dev/null @@ -1,25 +0,0 @@ -Address Block,Name,RFC,Allocation Date,Termination Date,Source,Destination,Forwardable,Globally Reachable,Reserved-by-Protocol -0.0.0.0/8,"""This host on this network""","[RFC1122], Section 3.2.1.3",1981-09,N/A,True,False,False,False,True -10.0.0.0/8,Private-Use,[RFC1918],1996-02,N/A,True,True,True,False,False -100.64.0.0/10,Shared Address Space,[RFC6598],2012-04,N/A,True,True,True,False,False -127.0.0.0/8,Loopback,"[RFC1122], Section 3.2.1.3",1981-09,N/A,False [1],False [1],False [1],False [1],True -169.254.0.0/16,Link Local,[RFC3927],2005-05,N/A,True,True,False,False,True -172.16.0.0/12,Private-Use,[RFC1918],1996-02,N/A,True,True,True,False,False -192.0.0.0/24 [2],IETF Protocol Assignments,"[RFC6890], Section 2.1",2010-01,N/A,False,False,False,False,False -192.0.0.0/29,IPv4 Service Continuity Prefix,[RFC7335],2011-06,N/A,True,True,True,False,False -192.0.0.8/32,IPv4 dummy address,[RFC7600],2015-03,N/A,True,False,False,False,False -192.0.0.9/32,Port Control Protocol Anycast,[RFC7723],2015-10,N/A,True,True,True,True,False -192.0.0.10/32,Traversal Using Relays around NAT Anycast,[RFC8155],2017-02,N/A,True,True,True,True,False -"192.0.0.170/32, 192.0.0.171/32",NAT64/DNS64 Discovery,"[RFC-cheshire-sudn-ipv4only-dot-arpa-17][RFC7050], Section 2.2",2013-02,N/A,False,False,False,False,True -192.0.2.0/24,Documentation (TEST-NET-1),[RFC5737],2010-01,N/A,False,False,False,False,False -192.31.196.0/24,AS112-v4,[RFC7535],2014-12,N/A,True,True,True,True,False -192.52.193.0/24,AMT,[RFC7450],2014-12,N/A,True,True,True,True,False -192.88.99.0/24,Deprecated (6to4 Relay Anycast),[RFC7526],2001-06,2015-03,,,,, -192.168.0.0/16,Private-Use,[RFC1918],1996-02,N/A,True,True,True,False,False -192.175.48.0/24,Direct Delegation AS112 Service,[RFC7534],1996-01,N/A,True,True,True,True,False -198.18.0.0/15,Benchmarking,[RFC2544],1999-03,N/A,True,True,True,False,False -198.51.100.0/24,Documentation (TEST-NET-2),[RFC5737],2010-01,N/A,False,False,False,False,False -203.0.113.0/24,Documentation (TEST-NET-3),[RFC5737],2010-01,N/A,False,False,False,False,False -240.0.0.0/4,Reserved,"[RFC1112], Section 4",1989-08,N/A,False,False,False,False,True -255.255.255.255/32,Limited Broadcast,"[RFC8190] - [RFC919], Section 7",1984-10,N/A,False,True,False,False,True diff --git a/utils/openbsd/pf-martians/iana-ipv4-special-registry.xml b/utils/openbsd/pf-martians/iana-ipv4-special-registry.xml new file mode 100644 index 0000000..fe28a89 --- /dev/null +++ b/utils/openbsd/pf-martians/iana-ipv4-special-registry.xml @@ -0,0 +1,359 @@ + + + + + IANA IPv4 Special-Purpose Address Registry + Internet Protocol version 4 (IPv4) Address Space + 2009-08-19 + 2020-09-04 + + + + + IANA IPv4 Special-Purpose Address Registry + + + + IETF Review + The IETF has reserved the address block of 192.0.0.0/24 for use for +special purposes relating to protocol assignments. This registry +contains the current assignments made by the IETF from this address +block. + +Address prefixes listed in the Special-Purpose Address Registry are +not guaranteed routability in any particular local or global context. + +The IPv4 and IPv6 Special-Purpose Address Registries maintain the +following information regarding each entry: + + o Address Block - A block of IPv4 or IPv6 addresses that has been + registered for a special purpose. + + o Name - A descriptive name for the special-purpose address block. + + o RFC - The RFC through which the special-purpose address block was + requested. + + o Allocation Date - The date upon which the special-purpose address + block was allocated. + + o Termination Date - The date upon which the allocation is to be + terminated. This field is applicable for limited-use allocations + only. + + o Source - A boolean value indicating whether an address from the + allocated special-purpose address block is valid when used as the + source address of an IP datagram that transits two devices. + + o Destination - A boolean value indicating whether an address from + the allocated special-purpose address block is valid when used as + the destination address of an IP datagram that transits two + devices. + + o Forwardable - A boolean value indicating whether a router may + forward an IP datagram whose destination address is drawn from the + allocated special-purpose address block between external + interfaces. + + o Globally Reachable - A boolean value indicating whether an IP + datagram whose destination address is drawn from the allocated + special-purpose address block is forwardable beyond a specified + administrative domain. + + o Reserved-by-Protocol - A boolean value indicating whether the + special-purpose address block is reserved by IP, itself. This + value is "TRUE" if the RFC that created the special-purpose + address block requires all compliant IP implementations to behave + in a special way when processing packets either to or from + addresses contained by the address block. + + If the value of "Destination" is FALSE, the values of "Forwardable" + and "Globally Reachable" must also be false. + + + +
0.0.0.0/8
+ "This host on this network" + , Section 3.2.1.3 + 1981-09 + True + False + False + False + True +
+ + +
10.0.0.0/8
+ Private-Use + + 1996-02 + True + True + True + False + False +
+ + +
100.64.0.0/10
+ Shared Address Space + + 2012-04 + True + True + True + False + False +
+ + +
127.0.0.0/8
+ Loopback + , Section 3.2.1.3 + 1981-09 + False + False + False + False + True +
+ + +
169.254.0.0/16
+ Link Local + + 2005-05 + True + True + False + False + True +
+ + +
172.16.0.0/12
+ Private-Use + + 1996-02 + True + True + True + False + False +
+ + +
192.0.0.0/24
+ IETF Protocol Assignments + , Section 2.1 + 2010-01 + False + False + False + False + False +
+ + +
192.0.0.0/29
+ IPv4 Service Continuity Prefix + + 2011-06 + True + True + True + False + False +
+ + +
192.0.0.8/32
+ IPv4 dummy address + + 2015-03 + True + False + False + False + False +
+ + +
192.0.0.9/32
+ Port Control Protocol Anycast + + 2015-10 + True + True + True + True + False +
+ + +
192.0.0.10/32
+ Traversal Using Relays around NAT Anycast + + 2017-02 + True + True + True + True + False +
+ + +
192.0.0.170/32, 192.0.0.171/32
+ NAT64/DNS64 Discovery + , Section 2.2 + 2013-02 + False + False + False + False + True +
+ + +
192.0.2.0/24
+ Documentation (TEST-NET-1) + + 2010-01 + False + False + False + False + False +
+ + +
192.31.196.0/24
+ AS112-v4 + + 2014-12 + True + True + True + True + False +
+ + +
192.52.193.0/24
+ AMT + + 2014-12 + True + True + True + True + False +
+ + +
192.88.99.0/24
+ Deprecated (6to4 Relay Anycast) + + 2001-06 + 2015-03 + + + + + +
+ + +
192.168.0.0/16
+ Private-Use + + 1996-02 + True + True + True + False + False +
+ + +
192.175.48.0/24
+ Direct Delegation AS112 Service + + 1996-01 + True + True + True + True + False +
+ + +
198.18.0.0/15
+ Benchmarking + + 1999-03 + True + True + True + False + False +
+ + +
198.51.100.0/24
+ Documentation (TEST-NET-2) + + 2010-01 + False + False + False + False + False +
+ + +
203.0.113.0/24
+ Documentation (TEST-NET-3) + + 2010-01 + False + False + False + False + False +
+ + +
240.0.0.0/4
+ Reserved + , Section 4 + 1989-08 + False + False + False + False + True +
+ + +
255.255.255.255/32
+ Limited Broadcast + + , Section 7 + 1984-10 + False + True + False + False + True +
+ +
+ + Several protocols have been granted exceptions to this rule. +For examples, see and . + Not useable unless by virtue of a more specific reservation. + + +
diff --git a/utils/openbsd/pf-martians/iana-ipv6-special-registry-1.csv b/utils/openbsd/pf-martians/iana-ipv6-special-registry-1.csv deleted file mode 100644 index cab0a19..0000000 --- a/utils/openbsd/pf-martians/iana-ipv6-special-registry-1.csv +++ /dev/null @@ -1,23 +0,0 @@ -Address Block,Name,RFC,Allocation Date,Termination Date,Source,Destination,Forwardable,Globally Reachable,Reserved-by-Protocol -::1/128,Loopback Address,[RFC4291],2006-02,N/A,False,False,False,False,True -::/128,Unspecified Address,[RFC4291],2006-02,N/A,True,False,False,False,True -::ffff:0:0/96,IPv4-mapped Address,[RFC4291],2006-02,N/A,False,False,False,False,True -64:ff9b::/96,IPv4-IPv6 Translat.,[RFC6052],2010-10,N/A,True,True,True,True,False -64:ff9b:1::/48,IPv4-IPv6 Translat.,[RFC8215],2017-06,N/A,True,True,True,False,False -100::/64,Discard-Only Address Block,[RFC6666],2012-06,N/A,True,True,True,False,False -2001::/23,IETF Protocol Assignments,[RFC2928],2000-09,N/A,False [1],False [1],False [1],False [1],False -2001::/32,TEREDO,"[RFC4380] - [RFC8190]",2006-01,N/A,True,True,True,N/A [2],False -2001:1::1/128,Port Control Protocol Anycast,[RFC7723],2015-10,N/A,True,True,True,True,False -2001:1::2/128,Traversal Using Relays around NAT Anycast,[RFC8155],2017-02,N/A,True,True,True,True,False -2001:2::/48,Benchmarking,[RFC5180][RFC Errata 1752],2008-04,N/A,True,True,True,False,False -2001:3::/32,AMT,[RFC7450],2014-12,N/A,True,True,True,True,False -2001:4:112::/48,AS112-v6,[RFC7535],2014-12,N/A,True,True,True,True,False -2001:10::/28,Deprecated (previously ORCHID),[RFC4843],2007-03,2014-03,,,,, -2001:20::/28,ORCHIDv2,[RFC7343],2014-07,N/A,True,True,True,True,False -2001:db8::/32,Documentation,[RFC3849],2004-07,N/A,False,False,False,False,False -2002::/16 [3],6to4,[RFC3056],2001-02,N/A,True,True,True,N/A [3],False -2620:4f:8000::/48,Direct Delegation AS112 Service,[RFC7534],2011-05,N/A,True,True,True,True,False -fc00::/7,Unique-Local,"[RFC4193] - [RFC8190]",2005-10,N/A,True,True,True,False [4],False -fe80::/10,Link-Local Unicast,[RFC4291],2006-02,N/A,True,True,False,False,True diff --git a/utils/openbsd/pf-martians/iana-ipv6-special-registry.xml b/utils/openbsd/pf-martians/iana-ipv6-special-registry.xml new file mode 100644 index 0000000..cfbd8e5 --- /dev/null +++ b/utils/openbsd/pf-martians/iana-ipv6-special-registry.xml @@ -0,0 +1,323 @@ + + + + + IANA IPv6 Special-Purpose Address Registry + Internet Protocol version 6 (IPv6) Global Unicast Allocations + 2006-01-10 + 2019-09-13 + + + + + IANA IPv6 Special-Purpose Address Registry + + + + IETF Review + Address prefixes listed in the Special-Purpose Address Registry are +not guaranteed routability in any particular local or global context. + +The IPv4 and IPv6 Special-Purpose Address Registries maintain the following +information regarding each entry: + + o Address Block - A block of IPv4 or IPv6 addresses that has been + registered for a special purpose. + + o Name - A descriptive name for the special-purpose address block. + + o RFC - The RFC through which the special-purpose address block was + requested. + + o Allocation Date - The date upon which the special-purpose address + block was allocated. + + o Termination Date - The date upon which the allocation is to be + terminated. This field is applicable for limited-use allocations + only. + + o Source - A boolean value indicating whether an address from the + allocated special-purpose address block is valid when used as the + source address of an IP datagram that transits two devices. + + o Destination - A boolean value indicating whether an address from + the allocated special-purpose address block is valid when used as + the destination address of an IP datagram that transits two + devices. + + o Forwardable - A boolean value indicating whether a router may + forward an IP datagram whose destination address is drawn from the + allocated special-purpose address block between external + interfaces. + + o Globally Reachable - A boolean value indicating whether an IP + datagram whose destination address is drawn from the allocated + special-purpose address block is forwardable beyond a specified + administrative domain. + + o Reserved-by-Protocol - A boolean value indicating whether the + special-purpose address block is reserved by IP, itself. This + value is "TRUE" if the RFC that created the special-purpose + address block requires all compliant IP implementations to behave + in a special way when processing packets either to or from + addresses contained by the address block. + +If the value of "Destination" is FALSE, the values of "Forwardable" and +"Globally Reachable" must also be false. + + + + +
::1/128
+ Loopback Address + + 2006-02 + False + False + False + False + True +
+ + +
::/128
+ Unspecified Address + + 2006-02 + True + False + False + False + True +
+ + +
::ffff:0:0/96
+ IPv4-mapped Address + + 2006-02 + False + False + False + False + True +
+ + +
64:ff9b::/96
+ IPv4-IPv6 Translat. + + 2010-10 + True + True + True + True + False +
+ + +
64:ff9b:1::/48
+ IPv4-IPv6 Translat. + + 2017-06 + True + True + True + False + False +
+ + +
100::/64
+ Discard-Only Address Block + + 2012-06 + True + True + True + False + False +
+ + +
2001::/23
+ IETF Protocol Assignments + + 2000-09 + False + False + False + False + False +
+ + +
2001::/32
+ TEREDO + + + 2006-01 + True + True + True + N/A + False +
+ + +
2001:1::1/128
+ Port Control Protocol Anycast + + 2015-10 + True + True + True + True + False +
+ + +
2001:1::2/128
+ Traversal Using Relays around NAT Anycast + + 2017-02 + True + True + True + True + False +
+ + +
2001:2::/48
+ Benchmarking + + 2008-04 + True + True + True + False + False +
+ + +
2001:3::/32
+ AMT + + 2014-12 + True + True + True + True + False +
+ + +
2001:4:112::/48
+ AS112-v6 + + 2014-12 + True + True + True + True + False +
+ + +
2001:10::/28
+ Deprecated (previously ORCHID) + + 2007-03 + 2014-03 + + + + + +
+ + +
2001:20::/28
+ ORCHIDv2 + + 2014-07 + True + True + True + True + False +
+ + +
2001:db8::/32
+ Documentation + + 2004-07 + False + False + False + False + False +
+ + +
2002::/16
+ 6to4 + + 2001-02 + True + True + True + N/A + False +
+ + +
2620:4f:8000::/48
+ Direct Delegation AS112 Service + + 2011-05 + True + True + True + True + False +
+ + +
fc00::/7
+ Unique-Local + + + 2005-10 + True + True + True + False + False +
+ + +
fe80::/10
+ Link-Local Unicast + + 2006-02 + True + True + False + False + True +
+ +
+ + + + Unless allowed by a more specific allocation. + See Section 5 of for details. + See for details. + See for more details on the routability of Unique-Local addresses. The Unique-Local prefix is +drawn from the IPv6 Global Unicast Address range, but is specified as not globally routed. + +