diff options
author | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2016-11-07 16:04:19 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-11-14 12:14:27 +0900 |
commit | 9e92d60427750495f073747f24b56e607ca750ac (patch) | |
tree | 461d299a5b90daecc0c8c8fdcc1f3461193a3d9f | |
parent | 48f577d1f8e4163ae75ae316b319dffa5f4e168e (diff) |
lib/ip: Add method to convert IPv4/IPv6 to int
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/lib/ip.py | 45 | ||||
-rw-r--r-- | ryu/tests/unit/lib/test_ip.py | 54 |
2 files changed, 82 insertions, 17 deletions
diff --git a/ryu/lib/ip.py b/ryu/lib/ip.py index 130a844d..4db69cc2 100644 --- a/ryu/lib/ip.py +++ b/ryu/lib/ip.py @@ -13,9 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +import numbers import struct from ryu.lib import addrconv +from ryu.lib import type_desc def ipv4_to_bin(ip): @@ -39,7 +41,7 @@ def ipv4_to_int(ip): def ipv4_to_str(ip): """ Converts binary or int type representation to human readable IPv4 string. - :param str ip: binary or int type representation of IPv4 address + :param ip: binary or int type representation of IPv4 address :return: IPv4 address string """ if isinstance(ip, int): @@ -57,13 +59,25 @@ def ipv6_to_bin(ip): return addrconv.ipv6.text_to_bin(ip) +def ipv6_to_int(ip): + """ + Converts human readable IPv6 string to int type representation. + :param str ip: IPv6 address string + :returns: int type representation of IPv6 address + """ + return type_desc.Int16.to_user(addrconv.ipv6.text_to_bin(ip)) + + def ipv6_to_str(ip): """ - Converts binary representation to human readable IPv6 string. - :param str ip: binary representation of IPv6 address + Converts binary or int type representation to human readable IPv6 string. + :param ip: binary or int type representation of IPv6 address :return: IPv6 address string """ - return addrconv.ipv6.bin_to_text(ip) + if isinstance(ip, numbers.Integral): + return addrconv.ipv6.bin_to_text(type_desc.Int16.from_user(ip)) + else: + return addrconv.ipv6.bin_to_text(ip) def text_to_bin(ip): @@ -74,11 +88,22 @@ def text_to_bin(ip): """ if ':' not in ip: - data = addrconv.ipv4.text_to_bin(ip) + return ipv4_to_bin(ip) else: - data = addrconv.ipv6.text_to_bin(ip) + return ipv6_to_bin(ip) + - return data +def text_to_int(ip): + """ + Converts human readable IPv4 or IPv6 string to int type representation. + :param str ip: IPv4 or IPv6 address string + :return: int type representation of IPv4 or IPv6 address + """ + + if ':' not in ip: + return ipv4_to_int(ip) + else: + return ipv6_to_int(ip) def bin_to_text(ip): @@ -88,10 +113,8 @@ def bin_to_text(ip): :return: IPv4 or IPv6 address string """ if len(ip) == 4: - data = addrconv.ipv4.bin_to_text(ip) + return ipv4_to_str(ip) elif len(ip) == 16: - data = addrconv.ipv6.bin_to_text(ip) + return ipv6_to_str(ip) else: raise struct.error('Invalid ip address length: %s' % len(ip)) - - return data diff --git a/ryu/tests/unit/lib/test_ip.py b/ryu/tests/unit/lib/test_ip.py index 3fb78119..66d8f0c2 100644 --- a/ryu/tests/unit/lib/test_ip.py +++ b/ryu/tests/unit/lib/test_ip.py @@ -15,10 +15,12 @@ from __future__ import print_function -import unittest import logging import struct -from nose.tools import * +import unittest + +from nose.tools import eq_ +from nose.tools import raises from ryu.lib import ip @@ -78,13 +80,33 @@ class Test_ip(unittest.TestCase): res = ip.ipv6_to_bin(ipv6_str) eq_(val, res) - def test_ipv6_to_str(self): + def test_ipv6_to_int(self): + ipv6_str = '2013:da8:215:8f2:aa20:66ff:fe4c:9c3c' + val = 0x20130da8021508f2aa2066fffe4c9c3c + + res = ip.ipv6_to_int(ipv6_str) + eq_(val, res) + + def test_ipv6_to_int_with_shortcut(self): + ipv6_str = '3f:10::1:2' + val = 0x003f0010000000000000000000010002 + + res = ip.ipv6_to_int(ipv6_str) + eq_(val, res) + + def test_ipv6_to_str_from_bin(self): ipv6_bin = struct.pack('!8H', 0x2013, 0xda8, 0x215, 0x8f2, 0xaa20, 0x66ff, 0xfe4c, 0x9c3c) val = '2013:da8:215:8f2:aa20:66ff:fe4c:9c3c' res = ip.ipv6_to_str(ipv6_bin) - print('%s %s' % (val, res)) + eq_(val, res) + + def test_ipv6_to_str_from_int(self): + ipv6_int = 0x20130da8021508f2aa2066fffe4c9c3c + val = '2013:da8:215:8f2:aa20:66ff:fe4c:9c3c' + + res = ip.ipv6_to_str(ipv6_int) eq_(val, res) def test_text_to_bin_from_ipv4_text(self): @@ -100,15 +122,35 @@ class Test_ip(unittest.TestCase): res = ip.text_to_bin(ipv6_str) eq_(val, res) - def test_bin_to_text_from_ipv4_text(self): + def test_text_to_int_from_ipv4_text(self): + ipv4_str = '10.28.197.1' # 0a.1c.c5.01 + val = 0x0a1cc501 + + res = ip.text_to_int(ipv4_str) + eq_(val, res) + + def test_text_to_int_from_ipv6_text(self): + ipv6_str = '2013:da8:215:8f2:aa20:66ff:fe4c:9c3c' + val = 0x20130da8021508f2aa2066fffe4c9c3c + + res = ip.text_to_int(ipv6_str) + eq_(val, res) + + def test_bin_to_text_from_ipv4_bin(self): ipv4_bin = struct.pack('!4B', 10, 28, 197, 1) val = '10.28.197.1' res = ip.bin_to_text(ipv4_bin) eq_(val, res) - def test_bin_to_text_from_ipv6_text(self): + def test_bin_to_text_from_ipv6_bin(self): ipv6_bin = struct.pack('!8H', 0x2013, 0xda8, 0x215, 0x8f2, 0xaa20, 0x66ff, 0xfe4c, 0x9c3c) val = '2013:da8:215:8f2:aa20:66ff:fe4c:9c3c' res = ip.bin_to_text(ipv6_bin) eq_(val, res) + + @raises(struct.error) + def test_bin_to_text_with_invalid_bin(self): + invalid_bin = b'invalid' + + ip.bin_to_text(invalid_bin) |