Add ICMP sub encoder/decoder class for Destination Unreachable Message.
and, add parser to TimeExceeded class.


Signed-off-by: WATANABE Fumitaka <watanabe.fumit...@nttcom.co.jp>
---
 ryu/lib/packet/icmp.py |  117 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 111 insertions(+), 6 deletions(-)

diff --git a/ryu/lib/packet/icmp.py b/ryu/lib/packet/icmp.py
index b049380..60f17ed 100644
--- a/ryu/lib/packet/icmp.py
+++ b/ryu/lib/packet/icmp.py
@@ -26,6 +26,11 @@ ICMP_REDIRECT = 5
 ICMP_ECHO_REQUEST = 8
 ICMP_TIME_EXCEEDED = 11

+ICMP_ECHO_REPLY_CODE = 0
+ICMP_HOST_UNREACH_CODE = 1
+ICMP_PORT_UNREACH_CODE = 3
+ICMP_TTL_EXPIRED_CODE = 0
+

 class icmp(packet_base.PacketBase):
     """ICMP (RFC 792) header encoder/decoder class.
@@ -42,10 +47,18 @@ class icmp(packet_base.PacketBase):
     csum           CheckSum \
                    (0 means automatically-calculate when encoding)
     data           Payload. \
-                   Either a bytearray or ryu.lib.packet.icmp.echo object. \
-                   NOTE: This includes "unused" 16 bits and the following \
+                   Either a bytearray, or \
+                   ryu.lib.packet.icmp.echo or \
+                   ryu.lib.packet.icmp.dest_unreach or \
+                   ryu.lib.packet.icmp.TimeExceeded object \
+                   NOTE for icmp.echo: \
+                   This includes "unused" 16 bits and the following \
                    "Internet Header + 64 bits of Original Data Datagram" of \
-                   the ICMP header.
+                   the ICMP header. \
+                   NOTE for icmp.dest_unreach and icmp.TimeExceeded: \
+                   This includes "unused" 8 or 24 bits and the following \
+                   "Internet Header + leading octets of original datagram" \
+                   of the original packet.
     ============== ====================
     """

@@ -124,6 +137,7 @@ class echo(object):
     _MIN_LEN = struct.calcsize(_PACK_STR)

     def __init__(self, id_, seq, data=None):
+        super(echo, self).__init__()
         self.id = id_
         self.seq = seq
         self.data = data
@@ -149,16 +163,107 @@ class echo(object):
         return hdr


+@icmp.register_icmp_type(ICMP_DEST_UNREACH)
+class dest_unreach(object):
+    """ICMP sub encoder/decoder class for Destination Unreachable Message.
+
+    This is used with ryu.lib.packet.icmp.icmp for
+    ICMP Destination Unreachable Message.
+
+    An instance has the following attributes at least.
+    Most of them are same to the on-wire counterparts but in host byte order.
+    __init__ takes the correspondig args in this order.
+
+    [RFC1191] reserves bits for the "Next-Hop MTU" field.
+    [RFC4884] introduced 8-bit data length attribute.
+
+    ============== ====================
+    Attribute      Description
+    ============== ====================
+    data_len       data length
+    mtu            Next-Hop MTU \
+                   NOTE: This field is required when icmp code is 4 \
+                    code 4 = fragmentation needed and DF set
+    data           Internet Header + leading octets of original datagram
+    ============== ====================
+    """
+
+    _PACK_STR = '!BBH'
+    _MIN_LEN = struct.calcsize(_PACK_STR)
+
+    def __init__(self, data_len=0, mtu=0, data=None):
+        super(dest_unreach, self).__init__()
+        self.data_len = data_len
+        self.mtu = mtu
+        self.data = data
+
+    @classmethod
+    def parser(cls, buf, offset):
+        (unused, data_len, mtu) = struct.unpack_from(cls._PACK_STR,
+                                                     buf, offset)
+        msg = cls(data_len, mtu)
+        offset += cls._MIN_LEN
+
+        if len(buf) > offset:
+            msg.data = buf[offset:]
+
+        return msg
+
+    def serialize(self):
+        unused = 0
+        hdr = bytearray(struct.pack(dest_unreach._PACK_STR,
+                         unused, self.data_len, self.mtu))
+
+        if self.data is not None:
+            hdr += self.data
+
+        return hdr
+
+
 @icmp.register_icmp_type(ICMP_TIME_EXCEEDED)
 class TimeExceeded(object):
-    _PACK_STR = '!4x'
+    """ICMP sub encoder/decoder class for Time Exceeded Message.
+
+    This is used with ryu.lib.packet.icmp.icmp for
+    ICMP Time Exceeded Message.
+
+    An instance has the following attributes at least.
+    Most of them are same to the on-wire counterparts but in host byte order.
+    __init__ takes the correspondig args in this order.
+
+    [RFC4884] introduced 8-bit data length attribute.
+
+    ============== ====================
+    Attribute      Description
+    ============== ====================
+    data_len       data length
+    data           Internet Header + leading octets of original datagram
+    ============== ====================
+    """
+
+    _PACK_STR = '!BBH'
     _MIN_LEN = struct.calcsize(_PACK_STR)

-    def __init__(self, data=None):
+    def __init__(self, data_len=0, data=None):
+        self.data_len = data_len
         self.data = data

+    @classmethod
+    def parser(cls, buf, offset):
+        (unused1, data_len, unused2) = struct.unpack_from(cls._PACK_STR,
+                                                          buf, offset)
+        msg = cls(data_len)
+        offset += cls._MIN_LEN
+
+        if len(buf) > offset:
+            msg.data = buf[offset:]
+
+        return msg
+
     def serialize(self):
-        hdr = bytearray(TimeExceeded._MIN_LEN)
+        unused = 0
+        hdr = bytearray(struct.pack(TimeExceeded._PACK_STR,
+                                     unused, self.data_len, unused))

         if self.data is not None:
             hdr += self.data
-- 1.7.10.4


------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to