#!/usr/bin/env python
# ipv6calc 0.1
# simple utility to calculate pointer domain names for IPv6 prefixes
__author__="Damian Pasternok <my_forename at pasternok.org>"
__program__="ipv6calc"
__version__="0.1"
__date__ ="$2009-08-01 19:57:24$"
import re
import socket
import struct
import sys
class IPv6Parser:
def __init__(self, prefix):
self.prefix = prefix
def parse_netmask(self):
netmask = re.findall("\/(\d{1}|[1-9]\d|1[0-1]\d|12[0-8])$", self.prefix)
if netmask:
return int(netmask[0])
else:
return -1
def parse_addr6(self):
addr6 = re.findall("^(.*)/", self.prefix)
if addr6:
addr6 = addr6[0]
try:
addr6 = socket.inet_pton(socket.AF_INET6, addr6)
except:
return -1
return addr6
else:
return -1
def round_netmask(self, netmask):
while 1:
if netmask % 4:
netmask += 1
else:
return netmask
class IPv6Calc(IPv6Parser):
def __init__(self, prefix):
IPv6Parser.__init__(self, prefix)
if self.parse_netmask() == -1 or self.parse_addr6() == -1:
print "Wrong prefix. Please try again..."
help()
else:
self.__calculate_revdns()
def __calculate_revdns(self):
addr6 = self.parse_addr6()
netmask = self.parse_netmask()
addr6_tlist = []
addr6_list = []
for i in range(16): # 16 x 8 bits
# appends one-element tupple
addr6_tlist.append(struct.unpack("B", addr6[i])[0])
# upper nibble
unibble = re.findall("^0x([\da-f]{1,2})$",
str(hex(addr6_tlist[i] >> 4)))
# lower nibble
lnibble = re.findall("^0x([\da-f]{1,2})$",
str(hex(addr6_tlist[i] & 0x0f)))
addr6_list.append(unibble[0])
addr6_list.append(lnibble[0])
for i in range(32 - self.round_netmask(netmask) / 4):
addr6_list.pop()
addr6_list.reverse()
ipv6_rev = ""
for i in addr6_list:
ipv6_rev += i + "."
ipv6_rev += "ip6.arpa."
print ipv6_rev
def help():
print r"""Usage: %s <ipv6_prefix>
--version display version
Prefix examples:
::ffff:192.168.0.1/128
2001:05c0:1501:bb00::/56""" % sys.argv[0]
return
def version():
print r"""%s %s
Copyright (C) 2009 %s
This code is free software under the GPLv3+.""" % (__program__, __version__,
__author__)
return
def main():
if len(sys.argv) == 1:
help()
elif sys.argv[1] == "--version":
version()
else:
try:
IPv6Calc(sys.argv[1])
except:
help()
return
if __name__ == "__main__":
main()