Sigh. Brown paper bag re-submit, to cover an "off-by-one."

When using the icmp.dest_unreach and icmp.TimeExceeded classes, we should 
ensure that it is in compliance with RFC 4884.
As such, the data_len parameter passed to the constructor of each should be 
interpreted in 32 bit units.
Furthermore - any data that is passed in must be zero padded to a 32 bit 
boundary.

The only sample application known to use either of these types is rest_router.
This patch corrects its use of these classes.

Signed-off-by: Victor J. Orlikowski <v...@duke.edu>

diff --git a/ryu/app/rest_router.py b/ryu/app/rest_router.py
index 30812a7..a0132c1 100644
--- a/ryu/app/rest_router.py
+++ b/ryu/app/rest_router.py
@@ -1523,18 +1523,37 @@ class OfCtl(object):
         eth = protocol_list[ETHERNET]
         e = ethernet.ethernet(eth.src, eth.dst, ether_proto)
 
+        ip = protocol_list[IPV4]
+
         if icmp_data is None and msg_data is not None:
-            ip_datagram = msg_data[offset:]
+            # RFC 4884 says that we should send "at least 128 octets"
+            # if we are using the ICMP Extension Structure.
+            # We're not using the extension structure, but let's send
+            # up to 128 bytes of the original msg_data.
+            #
+            # RFC 4884 also states that the length field is interpreted in
+            # 32 bit units, so the length calculated in bytes needs to first
+            # be divided by 4, then increased by 1 if the modulus is non-zero.
+            #
+            # Finally, RFC 4884 says, if we're specifying the length, we MUST
+            # zero pad to the next 32 bit boundary.
+            end_of_data = offset + len(ip) + 128
+            ip_datagram = bytearray()
+            ip_datagram += msg_data[offset:end_of_data]
+            data_len = int(len(ip_datagram) / 4)
+            length_modulus = int(len(ip_datagram) % 4)
+            if length_modulus:
+                data_len += 1
+                ip_datagram += bytearray([0]*(4 - length_modulus))
             if icmp_type == icmp.ICMP_DEST_UNREACH:
-                icmp_data = icmp.dest_unreach(data_len=len(ip_datagram),
+                icmp_data = icmp.dest_unreach(data_len=data_len,
                                               data=ip_datagram)
             elif icmp_type == icmp.ICMP_TIME_EXCEEDED:
-                icmp_data = icmp.TimeExceeded(data_len=len(ip_datagram),
+                icmp_data = icmp.TimeExceeded(data_len=data_len,
                                               data=ip_datagram)
 
         ic = icmp.icmp(icmp_type, icmp_code, csum, data=icmp_data)
 
-        ip = protocol_list[IPV4]
         if src_ip is None:
             src_ip = ip.dst
         ip_total_length = ip.header_length * 4 + ic._MIN_LEN


Best,
Victor
--
Victor J. Orlikowski <> vjo@[cs.]duke.edu


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to