I tried this only about parsing vlan/non vlan ip packets but I've
finished the basic design. Let me know if you have any comment.

=
>From d4299053f34c4bd323962955de80c6123ac1c4d6 Mon Sep 17 00:00:00 2001
From: FUJITA Tomonori <[email protected]>
Date: Mon, 20 Aug 2012 23:29:12 +0900
Subject: [PATCH] add packet library

As discussed on the mailing list, there is no good packet library
(parses and build various protocol packets). dpkt isn't flexible
(can't handle vlan too). NOX's one is nice but released under GPL3.

So we need to write our own.

Signed-off-by: FUJITA Tomonori <[email protected]>
---
 ryu/lib/packet/arp.py         |   32 +++++++++++++++++++++++++++
 ryu/lib/packet/ethernet.py    |   47 +++++++++++++++++++++++++++++++++++++++++
 ryu/lib/packet/ipv4.py        |   32 +++++++++++++++++++++++++++
 ryu/lib/packet/packet.py      |   44 ++++++++++++++++++++++++++++++++++++++
 ryu/lib/packet/packet_base.py |   37 ++++++++++++++++++++++++++++++++
 ryu/lib/packet/vlan.py        |   44 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 236 insertions(+), 0 deletions(-)
 create mode 100644 ryu/lib/packet/__init__.py
 create mode 100644 ryu/lib/packet/arp.py
 create mode 100644 ryu/lib/packet/ethernet.py
 create mode 100644 ryu/lib/packet/ipv4.py
 create mode 100644 ryu/lib/packet/packet.py
 create mode 100644 ryu/lib/packet/packet_base.py
 create mode 100644 ryu/lib/packet/vlan.py

diff --git a/ryu/lib/packet/__init__.py b/ryu/lib/packet/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/ryu/lib/packet/arp.py b/ryu/lib/packet/arp.py
new file mode 100644
index 0000000..585d1a6
--- /dev/null
+++ b/ryu/lib/packet/arp.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import struct
+from . import packet_base
+
+
+class arp(packet_base.PacketBase):
+    pack_str = '!HHBBH6sI6sI'
+
+    def __init__(self):
+        super(arp, self).__init__()
+
+    @classmethod
+    def parser(cls, buf):
+        msg = super(arp, cls).parser()
+        (htype, ptype, hlen, plen, op, src_mac, src_ip,
+         dst_mac, dst_ip) = struct.unpack_from(cls.pack_str, buf)
+        msg.length = 28
+        return msg, None
diff --git a/ryu/lib/packet/ethernet.py b/ryu/lib/packet/ethernet.py
new file mode 100644
index 0000000..36e5ec3
--- /dev/null
+++ b/ryu/lib/packet/ethernet.py
@@ -0,0 +1,47 @@
+# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import struct
+from . import packet_base
+from . import vlan
+from ryu.ofproto import ether
+from ryu.ofproto.ofproto_parser import msg_pack_into
+
+
+class ethernet(packet_base.PacketBase):
+    pack_str = '!6s6sH'
+
+    def __init__(self):
+        super(ethernet, self).__init__()
+
+    @classmethod
+    def parser(cls, buf):
+        msg = super(ethernet, cls).parser()
+        dst, src, ethertype = struct.unpack_from(cls.pack_str, buf)
+        msg.dst = dst
+        msg.src = src
+        msg.ethertype = ethertype
+        msg.length = struct.calcsize(ethernet.pack_str)
+        return msg, ethernet.get_packet_type(ethertype)
+
+    def serialize(self, buf, offset):
+        msg_pack_into(ethernet.pack_str, buf, offset,
+                      self.dst, self.src, self.ethertype)
+        self.length = struct.calcsize(ethernet.pack_str)
+
+
+# copy vlan _TYPES
+ethernet._TYPES = vlan.vlan._TYPES
+ethernet.register_packet_type(vlan.vlan, ether.ETH_TYPE_8021Q)
diff --git a/ryu/lib/packet/ipv4.py b/ryu/lib/packet/ipv4.py
new file mode 100644
index 0000000..118cb43
--- /dev/null
+++ b/ryu/lib/packet/ipv4.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import struct
+from . import packet_base
+
+
+class ipv4(packet_base.PacketBase):
+    pack_str = '!BBHHHBBHII'
+
+    def __init__(self):
+        super(ipv4, self).__init__()
+
+    @classmethod
+    def parser(cls, buf):
+        msg = super(ipv4, cls).parser()
+        (ver, tos, length, seq, offset, ttl, proto, csum,
+         src, dst) = struct.unpack_from(cls.pack_str, buf)
+        msg.length = 20
+        return msg, ipv4.get_packet_type(proto)
diff --git a/ryu/lib/packet/packet.py b/ryu/lib/packet/packet.py
new file mode 100644
index 0000000..0c74391
--- /dev/null
+++ b/ryu/lib/packet/packet.py
@@ -0,0 +1,44 @@
+# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from . import ethernet
+
+
+class Packet(object):
+    def __init__(self, data=None):
+        super(Packet, self).__init__()
+        self.data = data
+        self.protocols = []
+        self.parsed_bytes = 0
+        if self.data:
+            # Do we need to handle non ethernet?
+            self.parser(ethernet.ethernet)
+
+    def parser(self, cls):
+        while cls:
+            proto, cls = cls.parser(self.data[self.parsed_bytes:])
+            if proto:
+                self.parsed_bytes += proto.length
+                self.protocols.append(proto)
+
+    def serialize(self):
+        offset = 0
+        self.data = bytearray().zfill(0)
+        for p in self.protocols:
+            p.serialize(self.data, offset)
+            offset += p.length
+
+    def add_protocol(self, proto):
+        self.protocols.append(proto)
diff --git a/ryu/lib/packet/packet_base.py b/ryu/lib/packet/packet_base.py
new file mode 100644
index 0000000..d321930
--- /dev/null
+++ b/ryu/lib/packet/packet_base.py
@@ -0,0 +1,37 @@
+# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+class PacketBase(object):
+    _TYPES = {}
+
+    @classmethod
+    def get_packet_type(cls, type_):
+        return cls._TYPES.get(type_)
+
+    @classmethod
+    def register_packet_type(cls, cls_, type_):
+        cls._TYPES[type_] = cls_
+
+    def __init__(self):
+        super(PacketBase, self).__init__()
+        self.length = 0
+
+    @classmethod
+    def parser(cls):
+        return cls()
+
+    def serialize(self):
+        pass
diff --git a/ryu/lib/packet/vlan.py b/ryu/lib/packet/vlan.py
new file mode 100644
index 0000000..d10f7f7
--- /dev/null
+++ b/ryu/lib/packet/vlan.py
@@ -0,0 +1,44 @@
+# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import struct
+from . import packet_base
+from . import arp
+from . import ipv4
+from ryu.ofproto import ether
+from ryu.ofproto.ofproto_parser import msg_pack_into
+
+
+class vlan(packet_base.PacketBase):
+    pack_str = "!HH"
+
+    def __init__(self):
+        super(vlan, self).__init__()
+
+    @classmethod
+    def parser(cls, buf):
+        msg = super(vlan, cls).parser()
+        vid, ethertype = struct.unpack_from(cls.pack_str, buf)
+        msg.ethertype = ethertype
+        msg.length = struct.calcsize(vlan.pack_str)
+        return msg, vlan.get_packet_type(ethertype)
+
+    def serialize(self, buf, offset):
+        msg_pack_into(vlan.pack_str, buf, offset,
+                      self.vid, self.ethertype)
+        self.length = struct.calcsize(vlan.pack_str)
+
+vlan.register_packet_type(arp.arp, ether.ETH_TYPE_ARP)
+vlan.register_packet_type(ipv4.ipv4, ether.ETH_TYPE_IP)
-- 
1.7.4.4


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to