From: Shaun Crampton <[email protected]> Add support for ethernet padding.
* Add padding when serializing small packets. * Modify packet.py to support adding a footer as well as header in back-compatible way. If only header is returned, packet behaves as before. * When packets supply a total_length field, truncate the packet to that length in order to remove any additional padding. When no total_length is specified, act as before. Signed-off-by: Shaun Crampton <[email protected]> --- Our use case was to interoperate with a switch that included the ethernet padding when forwarding a packet to the controller. We needed to remove the padding before forwarding to our control plane software. ryu/lib/packet/ethernet.py | 9 +++++++-- ryu/lib/packet/icmp.py | 1 - ryu/lib/packet/packet.py | 20 +++++++++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/ryu/lib/packet/ethernet.py b/ryu/lib/packet/ethernet.py index 7bc18ef..0d9c2a9 100644 --- a/ryu/lib/packet/ethernet.py +++ b/ryu/lib/packet/ethernet.py @@ -51,8 +51,13 @@ class ethernet(packet_base.PacketBase): return cls(dst, src, ethertype), ethernet.get_packet_type(ethertype) def serialize(self, payload, prev): - return struct.pack(ethernet._PACK_STR, self.dst, self.src, - self.ethertype) + header = struct.pack(ethernet._PACK_STR, self.dst, self.src, + self.ethertype) + total_len = len(header) + len(payload) + # The minimum size of an ethernet frame is 64 bytes, including the + # 4-byte CRC, which is added by the hardware. Pad the packet. + pad_len = max(60 - total_len, 0) + return header, "\0" * pad_len # copy vlan _TYPES diff --git a/ryu/lib/packet/icmp.py b/ryu/lib/packet/icmp.py index e42fa40..819e9ab 100644 --- a/ryu/lib/packet/icmp.py +++ b/ryu/lib/packet/icmp.py @@ -79,7 +79,6 @@ class icmp(packet_base.PacketBase): msg.data = cls_.parser(buf, offset) else: msg.data = buf[offset:] - return msg, None def serialize(self, payload, prev): diff --git a/ryu/lib/packet/packet.py b/ryu/lib/packet/packet.py index f5fd82d..5602be2 100644 --- a/ryu/lib/packet/packet.py +++ b/ryu/lib/packet/packet.py @@ -44,6 +44,17 @@ class Packet(object): while cls: proto, cls = cls.parser(self.data[self.parsed_bytes:]) if proto: + try: + total_length = proto.total_length + except Exception: + pass + else: + if total_length + self.parsed_bytes < len(self.data): + # The data remaining is longer that the header of the + # packet says it should be. We likely have some + # ethernet padding added. Truncate it. + truncation_length = total_length + self.parsed_bytes + self.data = self.data[:truncation_length] self.parsed_bytes += proto.length self.protocols.append(proto) @@ -67,7 +78,14 @@ class Packet(object): data = p.serialize(self.data, prev) else: data = str(p) - self.data = data + self.data + try: + # Special-case: some protocols add a footer as well as a + # header. + prefix, suffix = data + except Exception: + prefix = data + suffix = "" + self.data = prefix + self.data + suffix def add_protocol(self, proto): """Register a protocol *proto* for this packet. -- 1.7.9.5 ------------------------------------------------------------------------------ Try New Relic Now & We'll Send You this Cool Shirt New Relic is the only SaaS-based application performance monitoring service that delivers powerful full stack analytics. Optimize and monitor your browser, app, & servers with just a few lines of code. Try New Relic and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_may _______________________________________________ Ryu-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ryu-devel
