Open kc2rxo opened 7 months ago
I think these new tags are a perfect fit for the ipaddress
module.
I've done a little bit of work on this, just to see how this could be done before integration and have come up with the following code:
import cbor2
import ipaddress
ip4a = ipaddress.IPv4Address("192.0.2.1")
ip4n = ipaddress.IPv4Network("192.0.2.0/24")
ip4n_pl = ip4n.prefixlen
ip4n_addr = ip4n.network_address.packed[:int(ip4n_pl / 8)]
ip4_addr = cbor2.CBORTag(52, ip4a.packed)
ip4_pfix = cbor2.CBORTag(52, [ip4n_pl, ip4n_addr])
ip4_iface = cbor2.CBORTag(52, [ip4a.packed, 24, 'eth0'])
print(ip4_addr)
print(ip4_pfix)
print(ip4_iface)
ip6a = ipaddress.IPv6Address("2001:0db8:1234:deed:beef:cafe:face:feed")
ip6n = ipaddress.IPv6Network("2001:db8:1234::/48")
ip6n_pl = ip6n.prefixlen
ip6n_addr = ip6n.network_address.packed[:int(ip6n_pl / 8)]
ip6_addr = cbor2.CBORTag(54, ip6a.packed)
ip6_pfix = cbor2.CBORTag(54, [ip6n_pl, ip6n_addr])
ip6_iface = cbor2.CBORTag(54, [ip6a.packed, 56, 'eth1'])
print(ip6_addr)
print(ip6_pfix)
print(ip6_iface)
It should be worth noting that the interface (ipX_iface
) definition the zone element (final element) can be either a string, integer or not present at all. The order of the array elements dictates the form you are encoding/decoding.
On the topic of the optional zone identifier, how would this be handled? It looks like the scope_id
of ipaddress.IPv6Address
is what would be expected but I have never seen or used this function before. The ipaddress
documentation doesn't even mention it for IPv4Address
. Perhaps it could be ignored for now and only the address and prefix forms of RFC9164 are supported?
To match the examples in RFC9164 I had to extract the address manually from the CIDR notation and perform a slice of the packed address to remove excess value not required in CBOR, thus resulting in the ipX_addr
values. This is probably bad practice but I do not see a clean way to get the value required from ipaddress
objects.
Obviously the CBORTag
's above would be used in a call of encode_semantic()
resulting in the desired bytes for the new tags.
Things to check first
Feature description
RFC9164 changes the semantic tags for IP Addresses and prefixes. See the RFC for specific details.
TLDR: Instead of 260 and 261 there is now semantic tags 52 (for IPv4) and 54 (for IPv6). Each tag supports a combination of full address and prefix forms. The originals are deprecated.
Use case
IANA has, per RFC9164, marked the original semantic tags as deprecated in favor of the RFC9164 tags.
While I am unsure of how much these new tags are used in the wild, I am currently proposing their use in various documents for the Drone Remote ID Protocol (DRIP). For some examples see this document, Section 9 and Appendix A.