summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Halley <halley@dnspython.org>2014-05-31 11:17:38 -0700
committerBob Halley <halley@dnspython.org>2014-05-31 11:17:38 -0700
commit7a277cecc6227edf746a40dbad250503ef3f7d20 (patch)
treecb4b9282a7e2114eb653bdc662c760f46241b65f
parentc8e17fc02a2d3ebbee3e7c34cd7828858e13fe57 (diff)
downloaddnspython-7a277cecc6227edf746a40dbad250503ef3f7d20.tar.gz
Add dns.ipv6.is_mapped(); Reverse IPv6 mapped IPv4 into v4 space
-rw-r--r--ChangeLog8
-rw-r--r--dns/ipv6.py5
-rw-r--r--dns/reversename.py9
-rw-r--r--tests/test_name.py9
-rw-r--r--tests/test_ntoaaton.py8
5 files changed, 35 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index b413572..9ee3bf7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2014-05-31 Bob Halley <halley@dnspython.org>
+
+ * dns/ipv6.py: Add is_mapped()
+
+ * dns/reversename.py: Lookup IPv6 mapped IPv4 addresses in the v4
+ reverse namespace. Thanks to Devin Bayer. Yes, I finally fixed
+ this one :)
+
2014-04-11 Bob Halley <halley@dnspython.org>
* dns/zone.py: Do not put back an unescaped token. This was
diff --git a/dns/ipv6.py b/dns/ipv6.py
index 1ab00da..bf658af 100644
--- a/dns/ipv6.py
+++ b/dns/ipv6.py
@@ -161,3 +161,8 @@ def inet_aton(text):
return text.decode('hex_codec')
except TypeError:
raise dns.exception.SyntaxError
+
+_mapped_prefix = '\x00' * 10 + '\xff\xff'
+
+def is_mapped(address):
+ return address.startswith(_mapped_prefix)
diff --git a/dns/reversename.py b/dns/reversename.py
index 4925cfd..b80c60a 100644
--- a/dns/reversename.py
+++ b/dns/reversename.py
@@ -37,8 +37,13 @@ def from_address(text):
@rtype: dns.name.Name object
"""
try:
- parts = list(dns.ipv6.inet_aton(text).encode('hex_codec'))
- origin = ipv6_reverse_domain
+ v6 = dns.ipv6.inet_aton(text)
+ if dns.ipv6.is_mapped(v6):
+ parts = ['%d' % ord(byte) for byte in v6[12:]]
+ origin = ipv4_reverse_domain
+ else:
+ parts = list(v6.encode('hex_codec'))
+ origin = ipv6_reverse_domain
except:
parts = ['%d' % ord(byte) for byte in dns.ipv4.inet_aton(text)]
origin = ipv4_reverse_domain
diff --git a/tests/test_name.py b/tests/test_name.py
index e30e43d..894a1a4 100644
--- a/tests/test_name.py
+++ b/tests/test_name.py
@@ -25,7 +25,7 @@ import dns.e164
class NameTestCase(unittest.TestCase):
def setUp(self):
self.origin = dns.name.from_text('example.')
-
+
def testFromTextRel1(self):
n = dns.name.from_text('foo.bar')
self.failUnless(n.labels == ('foo', 'bar', ''))
@@ -352,7 +352,7 @@ class NameTestCase(unittest.TestCase):
n = dns.name.from_text('FOO.bar', None)
d = n.to_digestable(dns.name.root)
self.failUnless(d == '\x03foo\x03bar\x00')
-
+
def testBadDigestable(self):
def bad():
n = dns.name.from_text('FOO.bar', None)
@@ -659,6 +659,11 @@ class NameTestCase(unittest.TestCase):
n = dns.reversename.from_address('::1')
self.failUnless(e == n)
+ def testReverseIPv6MappedIpv4(self):
+ e = dns.name.from_text('1.0.0.127.in-addr.arpa.')
+ n = dns.reversename.from_address('::ffff:127.0.0.1')
+ self.failUnless(e == n)
+
def testBadReverseIPv4(self):
def bad():
n = dns.reversename.from_address('127.0.foo.1')
diff --git a/tests/test_ntoaaton.py b/tests/test_ntoaaton.py
index e93de2d..5e33a92 100644
--- a/tests/test_ntoaaton.py
+++ b/tests/test_ntoaaton.py
@@ -199,5 +199,13 @@ class NtoAAtoNTestCase(unittest.TestCase):
t1 = ntoa6(b1)
self.failUnless(t1 == addr)
+ def test_is_mapped(self):
+ t1 = '2001:db8:0:1:1:1:1:1'
+ t2 = '::ffff:127.0.0.1'
+ t3 = '1::ffff:127.0.0.1'
+ self.failIf(dns.ipv6.is_mapped(aton6(t1)))
+ self.failUnless(dns.ipv6.is_mapped(aton6(t2)))
+ self.failIf(dns.ipv6.is_mapped(aton6(t3)))
+
if __name__ == '__main__':
unittest.main()