MCPcopy Create free account
hub / github.com/secdev/scapy / tcp_reassemble

Method tcp_reassemble

scapy/layers/http.py:652–720  ·  view source on GitHub ↗
(cls, data, metadata, _)

Source from the content-addressed store, hash-verified

650 # tcp_reassemble is used by TCPSession in session.py
651 @classmethod
652 def tcp_reassemble(cls, data, metadata, _):
653 detect_end = metadata.get("detect_end", None)
654 is_unknown = metadata.get("detect_unknown", True)
655 # General idea of the following is explained at
656 # https://datatracker.ietf.org/doc/html/rfc2616#section-4.4
657 if not detect_end or is_unknown:
658 metadata["detect_unknown"] = False
659 http_packet = cls(data)
660 # Detect packing method
661 if not isinstance(http_packet.payload, _HTTPContent):
662 return http_packet
663 is_response = isinstance(http_packet.payload, cls.clsresp)
664 # Packets may have a Content-Length we must honnor
665 length = http_packet.Content_Length
666 if length:
667 # Parse the length as an integer
668 try:
669 length = int(length)
670 except ValueError:
671 length = None
672 if length is not None:
673 # The packet provides a Content-Length attribute: let's
674 # use it. When the total size of the frags is high enough,
675 # we have the packet
676
677 # Subtract the length of the "HTTP*" layer
678 if http_packet.payload.payload or length == 0:
679 http_length = len(data) - http_packet.payload._original_len
680 detect_end = lambda dat: len(dat) - http_length >= length
681 else:
682 # The HTTP layer isn't fully received.
683 if metadata.get("tcp_end", False):
684 # This was likely a HEAD response. Ugh
685 detect_end = lambda dat: True
686 else:
687 detect_end = lambda dat: False
688 metadata["detect_unknown"] = True
689 else:
690 # It's not Content-Length based. It could be chunked
691 encodings = http_packet[cls].payload._get_encodings()
692 chunked = "chunked" in encodings
693 if chunked:
694 detect_end = lambda dat: dat.endswith(b"0\r\n\r\n")
695 # HTTP Requests that do not have any content,
696 # end with a double CRLF. Same for HEAD responses
697 elif isinstance(http_packet.payload, cls.clsreq):
698 detect_end = lambda dat: dat.endswith(b"\r\n\r\n")
699 # In case we are handling a HTTP Request,
700 # we want to continue assessing the data,
701 # to handle requests with a body (POST)
702 metadata["detect_unknown"] = True
703 elif is_response and http_packet.Status_Code == b"101":
704 # If it's an upgrade response, it may also hold a
705 # different protocol data.
706 # make sure all headers are present
707 detect_end = lambda dat: dat.find(b"\r\n\r\n")
708 else:
709 # If neither Content-Length nor chunked is specified,

Callers

nothing calls this directly

Calls 3

_get_encodingsMethod · 0.80
findMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected