From aa2b5a054ce05ba3735e26310e1e84115493f105 Mon Sep 17 00:00:00 2001 From: Yuichi Ito Date: Tue, 22 Oct 2013 14:56:21 +0900 Subject: [PATCH] packet lib: sctp: fix problems about padding Signed-off-by: Yuichi Ito Signed-off-by: FUJITA Tomonori --- ryu/lib/packet/sctp.py | 38 ++++++++++++++++---- ryu/tests/unit/packet/test_sctp.py | 57 +++++++++++++++--------------- 2 files changed, 59 insertions(+), 36 deletions(-) diff --git a/ryu/lib/packet/sctp.py b/ryu/lib/packet/sctp.py index f007b551..e935c63a 100644 --- a/ryu/lib/packet/sctp.py +++ b/ryu/lib/packet/sctp.py @@ -1138,7 +1138,10 @@ class cause(stringify.StringifyMixin): pass def __len__(self): - return self.length + length = self.length + if length % 4: + length += 4 - length % 4 + return length class cause_with_value(cause): @@ -1163,6 +1166,9 @@ class cause_with_value(cause): self._PACK_STR, self.cause_code(), self.length)) if self.value: buf.extend(self.value) + if len(buf) % 4: + padsize = 4 - len(buf) % 4 + buf.extend(bytearray(padsize)) return str(buf) @@ -1263,6 +1269,9 @@ class cause_missing_param(cause): self._PACK_STR, self.cause_code(), self.length, self.num)) for one in self.types: buf.extend(struct.pack('!H', one)) + if len(buf) % 4: + padsize = 4 - len(buf) % 4 + buf.extend(bytearray(padsize)) return str(buf) @@ -1389,6 +1398,9 @@ class cause_unresolvable_addr(cause_with_value): self._PACK_STR, self.cause_code(), self.length)) if self.value: buf.extend(self.value.serialize()) + if len(buf) % 4: + padsize = 4 - len(buf) % 4 + buf.extend(bytearray(padsize)) return str(buf) @@ -1621,6 +1633,9 @@ class cause_restart_with_new_addr(cause_with_value): self._PACK_STR, self.cause_code(), self.length)) for one in self.value: buf.extend(one.serialize()) + if len(buf) % 4: + padsize = 4 - len(buf) % 4 + buf.extend(bytearray(padsize)) return str(buf) @@ -1714,10 +1729,16 @@ class param(stringify.StringifyMixin): self._PACK_STR, self.param_type(), self.length)) if self.value: buf.extend(self.value) + if len(buf) % 4: + padsize = 4 - len(buf) % 4 + buf.extend(bytearray(padsize)) return str(buf) def __len__(self): - return self.length + length = self.length + if length % 4: + length += 4 - length % 4 + return length @chunk_heartbeat.register_param_type @@ -1866,6 +1887,11 @@ class param_ecn(param): def param_type(cls): return PTYPE_ECN + def __init__(self, length, value): + super(param_ecn, self).__init__(length, value) + assert 4 == length + assert None is value + @chunk_init.register_param_type @chunk_init_ack.register_param_type @@ -1932,8 +1958,6 @@ class param_supported_addr(param): for one in value: assert isinstance(one, int) self.length = length - if len(value) % 2: - value.append(0) self.value = value @classmethod @@ -1952,11 +1976,11 @@ class param_supported_addr(param): self._PACK_STR, self.param_type(), self.length)) for one in self.value: buf.extend(struct.pack(param_supported_addr._VALUE_STR, one)) + if len(buf) % 4: + padsize = 4 - len(buf) % 4 + buf.extend(bytearray(padsize)) return str(buf) - def __len__(self): - return self.length if 0 == self.length % 4 else self.length + 2 - @chunk_init.register_param_type @chunk_init_ack.register_param_type diff --git a/ryu/tests/unit/packet/test_sctp.py b/ryu/tests/unit/packet/test_sctp.py index 810db669..09bcd336 100644 --- a/ryu/tests/unit/packet/test_sctp.py +++ b/ryu/tests/unit/packet/test_sctp.py @@ -79,11 +79,11 @@ class Test_sctp(unittest.TestCase): self.p_ipv6 = sctp.param_ipv6(20, 'fe80::647e:1aff:fec4:8284') self.p_cookie_preserve = sctp.param_cookie_preserve(8, 5000) self.p_ecn = sctp.param_ecn(4, None) - self.p_host_addr = sctp.param_host_addr(16, 'test host\x00\x00\x00') + self.p_host_addr = sctp.param_host_addr(14, 'test host\x00') self.p_support_type = sctp.param_supported_addr( - 16, + 14, [sctp.PTYPE_IPV4, sctp.PTYPE_IPV6, sctp.PTYPE_COOKIE_PRESERVE, - sctp.PTYPE_ECN, sctp.PTYPE_HOST_ADDR, sctp.PTYPE_SUPPORTED_ADDR]) + sctp.PTYPE_ECN, sctp.PTYPE_HOST_ADDR]) self.init = sctp.chunk_init( self.flags, self.length, self.init_tag, self.a_rwnd, @@ -105,10 +105,10 @@ class Test_sctp(unittest.TestCase): '\x64\x7e\x1a\xff\xfe\xc4\x82\x84' + \ '\x00\x09\x00\x08\x00\x00\x13\x88' + \ '\x80\x00\x00\x04' + \ - '\x00\x0b\x00\x10' + \ + '\x00\x0b\x00\x0e' + \ '\x74\x65\x73\x74\x20\x68\x6f\x73\x74\x00\x00\x00' + \ - '\x00\x0c\x00\x10\x00\x05\x00\x06\x00\x09\x80\x00' + \ - '\x00\x0b\x00\x0c' + '\x00\x0c\x00\x0e\x00\x05\x00\x06\x00\x09\x80\x00' + \ + '\x00\x0b\x00\x00' def setUp_with_init_ack(self): self.flags = 0 @@ -120,13 +120,13 @@ class Test_sctp(unittest.TestCase): self.i_tsn = 123456 self.p_state_cookie = sctp.param_state_cookie( - 8, '\x01\x02\x03\x04') + 7, '\x01\x02\x03') self.p_ipv4 = sctp.param_ipv4(8, '192.168.1.1') self.p_ipv6 = sctp.param_ipv6(20, 'fe80::647e:1aff:fec4:8284') self.p_unrecognized_param = sctp.param_unrecognized_param( 8, '\xff\xff\x00\x04') self.p_ecn = sctp.param_ecn(4, None) - self.p_host_addr = sctp.param_host_addr(16, 'test host\x00\x00\x00') + self.p_host_addr = sctp.param_host_addr(14, 'test host\x00') self.init_ack = sctp.chunk_init_ack( self.flags, self.length, self.init_tag, self.a_rwnd, @@ -142,14 +142,14 @@ class Test_sctp(unittest.TestCase): self.buf += '\x02\x00\x00\x54\x00\x01\xe2\x40\x00\x00\x26\x94' + \ '\x00\x03\x00\x03\x00\x01\xe2\x40' + \ - '\x00\x07\x00\x08\x01\x02\x03\x04' + \ + '\x00\x07\x00\x07\x01\x02\x03\x00' + \ '\x00\x05\x00\x08\xc0\xa8\x01\x01' + \ '\x00\x06\x00\x14' + \ '\xfe\x80\x00\x00\x00\x00\x00\x00' + \ '\x64\x7e\x1a\xff\xfe\xc4\x82\x84' + \ '\x00\x08\x00\x08\xff\xff\x00\x04' + \ '\x80\x00\x00\x04' + \ - '\x00\x0b\x00\x10' + \ + '\x00\x0b\x00\x0e' + \ '\x74\x65\x73\x74\x20\x68\x6f\x73\x74\x00\x00\x00' def setUp_with_sack(self): @@ -231,7 +231,7 @@ class Test_sctp(unittest.TestCase): self.c_stale_cookie = sctp.cause_stale_cookie(8, '\x00\x00\x13\x88') self.c_out_of_resource = sctp.cause_out_of_resource(4) self.c_unresolvable_addr = sctp.cause_unresolvable_addr( - 20, sctp.param_host_addr(16, 'test host\x00\x00\x00')) + 20, sctp.param_host_addr(14, 'test host\x00')) self.c_unrecognized_chunk = sctp.cause_unrecognized_chunk( 8, '\xff\x00\x00\x04') self.c_invalid_param = sctp.cause_invalid_param(4) @@ -242,7 +242,7 @@ class Test_sctp(unittest.TestCase): self.c_restart_with_new_addr = sctp.cause_restart_with_new_addr( 12, sctp.param_ipv4(8, '192.168.1.1')) self.c_user_initiated_abort = sctp.cause_user_initiated_abort( - 20, 'Key Interrupt.\x00\x00') + 19, 'Key Interrupt.\x00') self.c_protocol_violation = sctp.cause_protocol_violation( 20, 'Unknown reason.\x00') @@ -270,7 +270,7 @@ class Test_sctp(unittest.TestCase): '\x00\x03\x00\x08\x00\x00\x13\x88' + \ '\x00\x04\x00\x04' + \ '\x00\x05\x00\x14' + \ - '\x00\x0b\x00\x10' + \ + '\x00\x0b\x00\x0e' + \ '\x74\x65\x73\x74\x20\x68\x6f\x73\x74\x00\x00\x00' + \ '\x00\x06\x00\x08\xff\x00\x00\x04' + \ '\x00\x07\x00\x04' + \ @@ -279,7 +279,7 @@ class Test_sctp(unittest.TestCase): '\x00\x0a\x00\x04' + \ '\x00\x0b\x00\x0c' + \ '\x00\x05\x00\x08\xc0\xa8\x01\x01' + \ - '\x00\x0c\x00\x14' + \ + '\x00\x0c\x00\x13' + \ '\x4b\x65\x79\x20\x49\x6e\x74\x65' + \ '\x72\x72\x75\x70\x74\x2e\x00\x00' + \ '\x00\x0d\x00\x14' + \ @@ -745,16 +745,16 @@ class Test_sctp(unittest.TestCase): buf = buf[4:] res5 = struct.unpack_from(sctp.param_host_addr._PACK_STR, buf) eq_(sctp.param_host_addr.param_type(), res5[0]) - eq_(16, res5[1]) - eq_('test host\x00\x00\x00', + eq_(14, res5[1]) + eq_('test host\x00', buf[sctp.param_host_addr._MIN_LEN: - sctp.param_host_addr._MIN_LEN + 12]) + sctp.param_host_addr._MIN_LEN + 10]) buf = buf[16:] res6 = struct.unpack_from(sctp.param_supported_addr._PACK_STR, buf) res6 = list(res6) eq_(sctp.param_supported_addr.param_type(), res6[0]) - eq_(16, res6[1]) + eq_(14, res6[1]) buf = buf[sctp.param_supported_addr._MIN_LEN:] offset = 0 tmplist = [] @@ -768,7 +768,6 @@ class Test_sctp(unittest.TestCase): eq_(sctp.PTYPE_COOKIE_PRESERVE, res6[4]) eq_(sctp.PTYPE_ECN, res6[5]) eq_(sctp.PTYPE_HOST_ADDR, res6[6]) - eq_(sctp.PTYPE_SUPPORTED_ADDR, res6[7]) def test_serialize_with_init_ack(self): self.setUp_with_init_ack() @@ -786,10 +785,10 @@ class Test_sctp(unittest.TestCase): buf = buf[sctp.chunk_init_ack._MIN_LEN:] res1 = struct.unpack_from(sctp.param_state_cookie._PACK_STR, buf) eq_(sctp.param_state_cookie.param_type(), res1[0]) - eq_(8, res1[1]) - eq_('\x01\x02\x03\x04', + eq_(7, res1[1]) + eq_('\x01\x02\x03', buf[sctp.param_state_cookie._MIN_LEN: - sctp.param_state_cookie._MIN_LEN + 4]) + sctp.param_state_cookie._MIN_LEN + 3]) buf = buf[8:] res2 = struct.unpack_from(sctp.param_ipv4._PACK_STR, buf) @@ -822,10 +821,10 @@ class Test_sctp(unittest.TestCase): buf = buf[4:] res6 = struct.unpack_from(sctp.param_host_addr._PACK_STR, buf) eq_(sctp.param_host_addr.param_type(), res6[0]) - eq_(16, res6[1]) - eq_('test host\x00\x00\x00', + eq_(14, res6[1]) + eq_('test host\x00', buf[sctp.param_host_addr._MIN_LEN: - sctp.param_host_addr._MIN_LEN + 12]) + sctp.param_host_addr._MIN_LEN + 10]) def test_serialize_with_sack(self): self.setUp_with_sack() @@ -935,7 +934,7 @@ class Test_sctp(unittest.TestCase): sctp.cause_unresolvable_addr._PACK_STR, buf) eq_(sctp.cause_unresolvable_addr.cause_code(), res5[0]) eq_(20, res5[1]) - eq_('\x00\x0b\x00\x10\x74\x65\x73\x74' + + eq_('\x00\x0b\x00\x0e\x74\x65\x73\x74' + '\x20\x68\x6f\x73\x74\x00\x00\x00', buf[sctp.cause_unresolvable_addr._MIN_LEN: sctp.cause_unresolvable_addr._MIN_LEN + 16]) @@ -990,10 +989,10 @@ class Test_sctp(unittest.TestCase): res12 = struct.unpack_from( sctp.cause_user_initiated_abort._PACK_STR, buf) eq_(sctp.cause_user_initiated_abort.cause_code(), res12[0]) - eq_(20, res12[1]) - eq_('Key Interrupt.\x00\x00', + eq_(19, res12[1]) + eq_('Key Interrupt.\x00', buf[sctp.cause_user_initiated_abort._MIN_LEN: - sctp.cause_user_initiated_abort._MIN_LEN + 16]) + sctp.cause_user_initiated_abort._MIN_LEN + 15]) buf = buf[20:] res13 = struct.unpack_from(