summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIWASE Yusuke <iwase.yusuke0@gmail.com>2016-11-07 16:04:19 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-11-14 12:14:27 +0900
commit9e92d60427750495f073747f24b56e607ca750ac (patch)
tree461d299a5b90daecc0c8c8fdcc1f3461193a3d9f
parent48f577d1f8e4163ae75ae316b319dffa5f4e168e (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.py45
-rw-r--r--ryu/tests/unit/lib/test_ip.py54
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)