From: "Henkel, Michael" <michael.hen...@hp.com>

Signed-off-by: FUJITA Tomonori <fujita.tomon...@lab.ntt.co.jp>
---
 ryu/lib/packet/icmp6.py |  179 +++++++++++++++++++++++++++++++++++++++++++++++
 ryu/lib/packet/ipv6.py  |    2 +
 2 files changed, 181 insertions(+)
 create mode 100644 ryu/lib/packet/icmp6.py

diff --git a/ryu/lib/packet/icmp6.py b/ryu/lib/packet/icmp6.py
new file mode 100644
index 0000000..72e1248
--- /dev/null
+++ b/ryu/lib/packet/icmp6.py
@@ -0,0 +1,179 @@
+# 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
+import socket
+import sys
+import array
+import binascii
+from . import packet_base
+from . import packet_utils
+from ryu.lib.mac import haddr_to_bin, haddr_to_str
+
+ICMP6_DST_UNREACH = 1       # dest unreachable, codes:
+ICMP6_PACKET_TOO_BIG = 2       # packet too big
+ICMP6_TIME_EXCEEDED = 3       # time exceeded, code:
+ICMP6_PARAM_PROB = 4       # ip6 header bad
+
+ICMP6_ECHO_REQUEST = 128     # echo service
+ICMP6_ECHO_REPLY = 129     # echo reply
+MLD_LISTENER_QUERY = 130     # multicast listener query
+MLD_LISTENER_REPOR = 131     # multicast listener report
+MLD_LISTENER_DONE = 132     # multicast listener done
+
+# RFC2292 decls
+ICMP6_MEMBERSHIP_QUERY = 130     # group membership query
+ICMP6_MEMBERSHIP_REPORT = 131     # group membership report
+ICMP6_MEMBERSHIP_REDUCTION = 132     # group membership termination
+
+ND_ROUTER_SOLICIT = 133     # router solicitation
+ND_ROUTER_ADVERT = 134     # router advertisment
+ND_NEIGHBOR_SOLICIT = 135     # neighbor solicitation
+ND_NEIGHBOR_ADVERT = 136     # neighbor advertisment
+ND_REDIREC = 137     # redirect
+
+ICMP6_ROUTER_RENUMBERING = 138     # router renumbering
+
+ICMP6_WRUREQUEST = 139     # who are you request
+ICMP6_WRUREPLY = 140     # who are you reply
+ICMP6_FQDN_QUERY = 139     # FQDN query
+ICMP6_FQDN_REPLY = 140     # FQDN reply
+ICMP6_NI_QUERY = 139     # node information request
+ICMP6_NI_REPLY = 140     # node information reply
+
+ICMP6_MAXTYPE = 201
+
+
+class icmp6(packet_base.PacketBase):
+    _PACK_STR = '!BBH'
+    _MIN_LEN = struct.calcsize(_PACK_STR)
+    _ICMP6_TYPES = {}
+
+    @staticmethod
+    def register_icmp6_type(*args):
+        def _register_icmp6_type(cls):
+            for type_ in args:
+                icmp6._ICMP6_TYPES[type_] = cls
+            return cls
+        return _register_icmp6_type
+
+    def __init__(self, type_, code, csum, data=None):
+        super(icmp6, self).__init__()
+        self.type_ = type_
+        self.code = code
+        self.csum = csum
+        self.data = data
+
+    @classmethod
+    def parser(cls, buf):
+        (type_, code, csum) = struct.unpack_from(cls._PACK_STR, buf)
+        msg = cls(type_, code, csum)
+        offset = cls._MIN_LEN
+        if len(buf) > offset:
+            cls_ = cls._ICMP6_TYPES.get(type_, None)
+            if cls_:
+                msg.data = cls_.parser(buf, offset)
+            else:
+                msg.data = buf[offset:]
+
+        return msg, None
+
+    def serialize(self, payload, prev):
+        hdr = bytearray(struct.pack(icmp6._PACK_STR, self.type_,
+                                    self.code, self.csum))
+
+        if self.data is not None:
+            if self.type_ in icmp6._ICMP6_TYPES:
+                hdr += self.data.serialize()
+            else:
+                hdr += self.data
+        src = prev.src
+        dst = prev.dst
+        nxt = prev.nxt
+        if self.csum == 0:
+            length = len(str(hdr))
+            ph = struct.pack('!16s16sBBH', prev.src, prev.dst, 0, prev.nxt,
+                             length)
+            f = ph + hdr + payload
+            if len(f) % 2:
+                f += '\x00'
+            self.csum = socket.htons(packet_utils.checksum(f))
+            struct.pack_into('!H', hdr, 2, self.csum)
+
+        return hdr
+
+
+@icmp6.register_icmp6_type(ND_NEIGHBOR_SOLICIT, ND_NEIGHBOR_ADVERT)
+class nd_s(object):
+    _PACK_STR = '!I16sBB6s'
+    _MIN_LEN = struct.calcsize(_PACK_STR)
+
+    def __init__(self, res, dst, type_, length, hw_src, data=None):
+        self.res = res << 29
+        self.dst = dst
+        self.type_ = type_
+        self.length = length
+        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)
+        offset += cls._MIN_LEN
+        if len(buf) > offset:
+            msg.data = buf[offset:]
+
+        return msg
+
+    def serialize(self):
+        hdr = bytearray(struct.pack(nd_s._PACK_STR, self.res, self.dst,
+                                    self.type_, self.length, self.hw_src))
+
+        if self.data is not None:
+            hdr += self.data
+
+        return hdr
+
+
+@icmp6.register_icmp6_type(ICMP6_ECHO_REPLY, ICMP6_ECHO_REQUEST)
+class echo(object):
+    _PACK_STR = '!HH'
+    _MIN_LEN = struct.calcsize(_PACK_STR)
+
+    def __init__(self, id_, seq, data=None):
+        self.id = id_
+        self.seq = seq
+        self.data = data
+
+    @classmethod
+    def parser(cls, buf, offset):
+        (id_, seq) = struct.unpack_from(cls._PACK_STR, buf, offset)
+        msg = cls(id_, seq)
+        offset += cls._MIN_LEN
+
+        if len(buf) > offset:
+            msg.data = buf[offset:]
+
+        return msg
+
+    def serialize(self):
+        hdr = bytearray(struct.pack(echo._PACK_STR, self.id,
+                                    self.seq))
+        if self.data is not None:
+            hdr += bytearray(self.data)
+
+        return hdr
diff --git a/ryu/lib/packet/ipv6.py b/ryu/lib/packet/ipv6.py
index 8fc9d0d..4f1325e 100644
--- a/ryu/lib/packet/ipv6.py
+++ b/ryu/lib/packet/ipv6.py
@@ -17,6 +17,7 @@ import struct
 import socket
 from . import packet_base
 from . import packet_utils
+from . import icmp6
 from . import tcp
 from ryu.ofproto import inet
 
@@ -64,4 +65,5 @@ class ipv6(packet_base.PacketBase):
                          self.src, self.dst)
         return hdr
 
+ipv6.register_packet_type(icmp6.icmp6, inet.IPPROTO_ICMP6)
 ipv6.register_packet_type(tcp.tcp, inet.IPPROTO_TCP)
-- 
1.7.10.4


------------------------------------------------------------------------------
Free Next-Gen Firewall Hardware Offer
Buy your Sophos next-gen firewall before the end March 2013 
and get the hardware for free! Learn more.
http://p.sf.net/sfu/sophos-d2d-feb
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to