tobit
tobit

Reputation: 33

ipaddress module and IPv6 reverse pointer

i'll try to explain my problem with examples: when i'm using ipv6calc to build a reverse domain this is what i want to get:

$ ipv6calc --out revnibbles.arpa 2001:0db8:85a3::/48
No input type specified, try autodetection...found type: ipv6addr
3.a.5.8.8.b.d.0.1.0.0.2.ip6.arpa.
.

heres an example w/o given prefix (128 default) to see the difference

$  ipv6calc --out revnibbles.arpa 2001:0db8:85a3::
No input type specified, try autodetection...found type: ipv6addr
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.a.5.8.8.b.d.0.1.0.0.2.ip6.arpa.

now im trying to build the reverse domain in python with the ipaddress module and with a given prefix like above (important)

import ipaddress
print(ipaddress.IPv6Network(u"2001:0db8:85a3::/48").reverse_pointer)

output is

8.4./.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.a.5.8.8.b.d.0.1.0.0.2.ip6.arpa

Seems like the module did not consider that. I have also tried the module IPy, but its buggy as hell and not usable in my opinion. Does anyone have an idea how to solve that? i would prefer one without the usage of shell commands (ipv6calc).

Thank you in advance

Upvotes: 2

Views: 712

Answers (1)

Patrick Mevzek
Patrick Mevzek

Reputation: 12515

The reverse_pointer is implemented that way:

    def _reverse_pointer(self):
        """Return the reverse DNS pointer name for the IPv6 address.
        This implements the method described in RFC3596 2.5.
        """
        reverse_chars = self.exploded[::-1].replace(':', '')
        return '.'.join(reverse_chars) + '.ip6.arpa'

So it clearly will not take into account the prefix. Note that it specifically speaks about IPv6 address, not network/prefix.

First you will have a better answer by doing:

print(ipaddress.IPv6Network(u"2001:0db8:85a3::/48").network_address.reverse_pointer)

which gives: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.a.5.8.8.b.d.0.1.0.0.2.ip6.arpa which is proper version, even if not what you want.

You either need to subclass IPv6Network and rewrite _reverse_pointer to your liking or muck directly with its current result as the following, that could work but has edge cases:

print(ipaddress.IPv6Network(u"2001:0db8:85a3::/48").network_address.reverse_pointer[(2*(128-48)/4):])
3.a.5.8.8.b.d.0.1.0.0.2.ip6.arpa

because the full result is 32 nibbles (hexadecimal digit) separated by a dot (besides the final .ip6.arpa), and 128-48 is the number of bits for the non prefix part, and since the previous is in bits, you need to count bytes in hexadecimal so /4 but *2 because each nibble is present with a following dot.

Upvotes: 2

Related Questions