rest_router: Ensure that usage of icmp.dest_unreach and icmp.TimeExceeded complies with RFC 4884
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 <vjo@duke.edu> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
8f7d302fd5
commit
28cb1d59d9
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user