This patch fixes parser error if there is no NDP option, and support
the class to handle the NDP option.

I have implemented only the option type = 1 and 2. We also need to
implement other type, but this is enough in mininet for now.

> Traceback (most recent call last):
> (...)
>   File 
> "/usr/local/lib/python2.7/dist-packages/ryu-1.6-py2.7.egg/ryu/lib/packet/icmpv6.py",
>  line 87, in parser
>     msg.data = cls_.parser(buf, offset)
>   File 
> "/usr/local/lib/python2.7/dist-packages/ryu-1.6-py2.7.egg/ryu/lib/packet/icmpv6.py",
>  line 134, in parser
>     buf, offset)
> error: unpack_from requires a buffer of at least 28 bytes

Signed-off-by: HIYAMA Manabu <[email protected]>
---
 ryu/lib/packet/icmpv6.py |   68 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 59 insertions(+), 9 deletions(-)

diff --git a/ryu/lib/packet/icmpv6.py b/ryu/lib/packet/icmpv6.py
index 3f8ab2f..eef450f 100644
--- a/ryu/lib/packet/icmpv6.py
+++ b/ryu/lib/packet/icmpv6.py
@@ -116,23 +116,74 @@ class icmpv6(packet_base.PacketBase):
 
 
 @icmpv6.register_icmpv6_type(ND_NEIGHBOR_SOLICIT, ND_NEIGHBOR_ADVERT)
-class nd_s(object):
-    _PACK_STR = '!I16sBB6s'
+class nd_neighbor(object):
+    _PACK_STR = '!I16s'
     _MIN_LEN = struct.calcsize(_PACK_STR)
+    _ND_OPTION_TYPES = {}
 
-    def __init__(self, res, dst, type_, length, hw_src, data=None):
+    # ND option type
+    ND_OPTION_SLA = 1  # Source Link-Layer Address
+    ND_OPTION_TLA = 2  # Target Link-Layer Address
+    ND_OPTION_PI = 3   # Prefix Information
+    ND_OPTION_RH = 4   # Redirected Header
+    ND_OPTION_MTU = 5  # MTU
+
+    @staticmethod
+    def register_nd_option_type(*args):
+        def _register_nd_option_type(cls):
+            for type_ in args:
+                nd_neighbor._ND_OPTION_TYPES[type_] = cls
+            return cls
+        return _register_nd_option_type
+
+    def __init__(self, res, dst, type_=None, length=None, data=None):
         self.res = res << 29
         self.dst = dst
         self.type_ = type_
         self.length = length
+        self.data = data
+
+    @classmethod
+    def parser(cls, buf, offset):
+        (res, dst) = struct.unpack_from(cls._PACK_STR, buf, offset)
+        msg = cls(res, dst)
+        offset += cls._MIN_LEN
+        if len(buf) > offset:
+            (msg.type_, msg.length) = struct.unpack_from('!BB', buf, offset)
+            cls_ = cls._ND_OPTION_TYPES.get(msg.type_, None)
+            if cls_:
+                msg.data = cls_.parser(buf, offset)
+            else:
+                msg.data = buf[offset:]
+
+        return msg
+
+    def serialize(self):
+        hdr = bytearray(struct.pack(nd_neighbor._PACK_STR, self.res, self.dst))
+
+        if self.type_ is not None:
+            hdr += bytearray(struct.pack('!BB', self.type_, self.length))
+            if self.type_ in nd_neighbor._ND_OPTION_TYPES:
+                hdr += self.data.serialize()
+            elif self.data is not None:
+                hdr += bytearray(self.data)
+
+        return hdr
+
+
+@nd_neighbor.register_nd_option_type(nd_neighbor.ND_OPTION_SLA, 
nd_neighbor.ND_OPTION_TLA)
+class nd_option_la(object):
+    _PACK_STR = '!6s'
+    _MIN_LEN = struct.calcsize(_PACK_STR)
+
+    def __init__(self, hw_src, data=None):
         self.hw_src = hw_src
         self.data = data
 
     @classmethod
     def parser(cls, buf, offset):
-        (res, dst, type_, length, hw_src) = struct.unpack_from(cls._PACK_STR,
-                                                               buf, offset)
-        msg = cls(res, dst, type_, length, hw_src)
+        (hw_src, ) = struct.unpack_from(cls._PACK_STR, buf, offset)
+        msg = cls(hw_src)
         offset += cls._MIN_LEN
         if len(buf) > offset:
             msg.data = buf[offset:]
@@ -140,11 +191,10 @@ class nd_s(object):
         return msg
 
     def serialize(self):
-        hdr = bytearray(struct.pack(nd_s._PACK_STR, self.res, self.dst,
-                                    self.type_, self.length, self.hw_src))
+        hdr = bytearray(struct.pack(self._PACK_STR, self.hw_src))
 
         if self.data is not None:
-            hdr += self.data
+            hdr += bytearray(self.data)
 
         return hdr
 
-- 
1.7.9.5



------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to