It is still missing extension headers.

Signed-off-by: Baptiste Jonglez <[email protected]>
---
 ryu/lib/packet/utp.py | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 ryu/lib/packet/utp.py

diff --git a/ryu/lib/packet/utp.py b/ryu/lib/packet/utp.py
new file mode 100644
index 0000000..19309aa
--- /dev/null
+++ b/ryu/lib/packet/utp.py
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+
+import struct
+
+from ryu.lib.packet import packet_base
+from ryu.lib.packet import packet_utils
+
+
+class utp(packet_base.PacketBase):
+    """µTP header encoder/decoder class, see 
http://www.bittorrent.org/beps/bep_0029.html
+
+    An instance has the following attributes at least.
+    Most of them are same to the on-wire counterparts but in host byte order.
+
+    This does not currently implement extension headers.
+
+    ==============                    ====================
+    Attribute                         Description
+    ==============                    ====================
+    type                              Type of the packet
+    version                           Version of the protocol
+    extension                         Type of the next extension header
+    connection_id                     Connection ID for all packets of this 
flow
+    timestamp_microseconds            Timestamp set by the sender
+    timestamp_difference_microseconds Latest one-way-delay from remote to local
+    wnd_size                          Advertised receive window
+    seq_nr                            Sequence number (in packets)
+    ack_nr                            Sequence number of the last received 
packet
+    ==============                    ====================
+    """
+
+    # Type and version are 4 bits each, so group them together...
+    _PACK_STR = '!BBHIiIHH'
+    _MIN_LEN = struct.calcsize(_PACK_STR)
+
+    def __init__(self, type=4, version=1, extension=0, connection_id=0,
+                 timestamp_microseconds=0, timestamp_difference_microseconds=0,
+                 wnd_size=0, seq_nr=0, ack_nr=0):
+        super(utp, self).__init__()
+        self.type = type
+        self.version = version
+        self.extension = extension
+        self.connection_id = connection_id
+        self.timestamp_microseconds = timestamp_microseconds
+        self.timestamp_difference_microseconds = 
timestamp_difference_microseconds
+        self.wnd_size = wnd_size
+        self.seq_nr = seq_nr
+        self.ack_nr = ack_nr
+
+    @classmethod
+    def detect_utp(cls, payload):
+        """Detection heuristic for the µTP protocol, inspired from wireshark 
(BT-uTP).
+        Note that the heuristic is somewhat weak and will produce false
+        positive.  For instance, it will match random packets with
+        probability 4/256.
+        """
+        if len(payload) < 20:
+            return False
+        (type_version,) = struct.unpack_from("!B", payload, 0)
+        type = type_version >> 4
+        version = type_version & 0x0F
+        if (version != 1):
+            return False
+        if (type < 0 or type > 4):
+            return False
+        return True
+
+    @classmethod
+    def parser(cls, buf):
+        (type_version, extension, connection_id, timestamp_microseconds,
+         timestamp_difference_microseconds, wnd_size, seq_nr,
+         ack_nr) = struct.unpack_from( cls._PACK_STR, buf)
+        type = type_version >> 4
+        version = type_version & 0x0F
+        msg = cls(type, version, extension, connection_id, 
timestamp_microseconds,
+                  timestamp_difference_microseconds, wnd_size, seq_nr, ack_nr)
+        # TODO: parse options
+        length = msg._MIN_LEN
+        return msg, None, buf[length:]
+
+    def serialize(self, payload, prev):
+        type_version = (self.type << 4) | self.version
+        h = struct.pack(utp._PACK_STR, type_version, self.extension,
+                        self.connection_id, self.timestamp_microseconds,
+                        self.timestamp_difference_microseconds, self.wnd_size,
+                        self.seq_nr, self.ack_nr)
+        return h
-- 
2.6.4


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

Reply via email to