im currently working on a new protocol layer for scapy. unfortunately the tcp_reassembly gives me a headache.
the protocol i dissect uses a bundle_len field that specifies how long a bundle is. if the packet is exactly as long as the bundle len everything works. if it is to large i split off one packet and return the rest to the queue (i think) if the packet is less then the bundle_len im sure i would have to wait for additional packets or prepend the rest of the previous (to long) packet.
i know what the problem is but can't figure out how to use the tcp_reassembly function correctly.
here some example code:
def tcp_reassemble(cls, data, metadata):
"""[called by sniff(session=TCPSession),
reassembles the tcp stream if packet spans over multiple TCP packets]
Args:
data ([Packet]): [a raw packed strippt by the TCP Layer]
metadata ([dict]): [stores partial streams]
Returns:
[Packet]: [reassembled Packet]
"""
#pylint: disable=unused-argument
length = struct.unpack("<I", data[24:28])[0] # get bundle_len, not readable if offset wrong or not a bundle
if length > 10000: # desaster containment, not good.
length = 64
if len(data) > length: # got to much
# return OWN_PROTOCOL bundle up to bundle_len
pkt = OWN_PROTOCOL(data[:length])
if hasattr(pkt.payload, "tcp_reassemble"): # not sure if needed or what it does
if pkt.payload.tcp_reassemble(data[length:], metadata):
return pkt
else:
return pkt
elif len(data) < length: # got less, not working
print(
f"### Got LESS actual len: {len(data)} proposed bundle_len: {length} ###")
return None # push rest back to queue
else:
return OWN_PROTOCOL(data) # got exactly one bundle in one packet