diff --git a/scapy/contrib/tcpros.py b/scapy/contrib/tcpros.py index 90773d32a7b..ec0dcefc2b7 100644 --- a/scapy/contrib/tcpros.py +++ b/scapy/contrib/tcpros.py @@ -25,6 +25,28 @@ from scapy.config import conf +def tcpros_iter_field_lengths(data, start=0): + """Iterate over the lengths of the ``[4-byte length + value]`` fields. + + The fields are read in place with ``struct.unpack_from``: slicing the + buffer for every field copies the whole remainder, which makes the + traversal quadratic in the number of fields. + + Args: + data: buffer holding the field list. + start: offset of the first field length in ``data``. + + Yields: + the length of each field, in order. + """ + end = len(data) + offset = start + while offset < end: + field_len = struct.unpack_from(" len(payload) - offset - 4: # print("BREAKING - int(field_len_bytes) != len(current)") flag_encoding_format_subfields = False break + offset += 4 + field_len if ( "callerid" in string_payload and @@ -214,14 +234,9 @@ def pre_dissect(self, s): print("total_length: " + str(total_length)) print("total_header_length: " + str(total_header_length)) remain = raw(s)[4:total_header_length] - while remain: - field_len_bytes = struct.unpack("\n") assert(p[XMLRPCCall].methodcall_opentag == b'\n') assert(p[XMLRPCCall].methodname == b'shutdown') assert(p[XMLRPCCall].params == b'\n/rosparam-92418\n\n\nBOOM\n\n') + ++ Test TCPROS field list parsing += Test field lengths traversal +from struct import pack +from scapy.contrib.tcpros import tcpros_iter_field_lengths + +field_list = pack("