Signed-off-by: Shinpei Muraoka <[email protected]>
---
 ryu/lib/packet/packet.py | 39 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/ryu/lib/packet/packet.py b/ryu/lib/packet/packet.py
index 85e826f..043dae7 100644
--- a/ryu/lib/packet/packet.py
+++ b/ryu/lib/packet/packet.py
@@ -14,14 +14,32 @@
 # limitations under the License.
 
 import inspect
-import six
 import struct
+import base64
+
+import six
 
 from . import packet_base
 from . import ethernet
 
+from ryu import utils
+from ryu.lib.stringify import StringifyMixin
+
+
+# Packet class dictionary
+mod = inspect.getmembers(utils.import_module("ryu.lib.packet"),
+                         lambda cls: (inspect.ismodule(cls)))
+cls_list = []
+for _, m in mod:
+    cl = inspect.getmembers(m,
+                            lambda cls: (
+                                inspect.isclass(cls) and
+                                issubclass(cls, packet_base.PacketBase)))
+    cls_list.extend(list(cl))
+PKT_CLS_DICT = dict(cls_list)
 
-class Packet(object):
+
+class Packet(StringifyMixin):
     """A packet decoder/encoder class.
 
     An instance is used to either decode or encode a single packet.
@@ -35,6 +53,9 @@ class Packet(object):
     *data* should be omitted when encoding a packet.
     """
 
+    # Ignore data field when outputting json representation.
+    _base_attributes = ['data']
+
     def __init__(self, data=None, protocols=None, parse_cls=ethernet.ethernet):
         super(Packet, self).__init__()
         self.data = data
@@ -77,6 +98,20 @@ class Packet(object):
                 data = six.binary_type(p)
             self.data = bytearray(data + self.data)
 
+    @classmethod
+    def from_jsondict(cls, dict_, decode_string=base64.b64decode,
+                      **additional_args):
+        protocols = []
+        for proto in dict_['protocols']:
+            for key, value in proto.items():
+                if key in PKT_CLS_DICT:
+                    pkt_cls = PKT_CLS_DICT[key]
+                    protocols.append(pkt_cls.from_jsondict(value))
+                else:
+                    raise ValueError('unknown protocol name %s' % key)
+
+        return cls(protocols=protocols)
+
     def add_protocol(self, proto):
         """Register a protocol *proto* for this packet.
 
-- 
2.7.4


------------------------------------------------------------------------------
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to