| 602 | |
| 603 | |
| 604 | class HTTP(Packet): |
| 605 | name = "HTTP 1" |
| 606 | fields_desc = [] |
| 607 | show_indent = 0 |
| 608 | clsreq = HTTPRequest |
| 609 | clsresp = HTTPResponse |
| 610 | hdr = b"HTTP" |
| 611 | reqmethods = b"|".join( |
| 612 | [ |
| 613 | b"OPTIONS", |
| 614 | b"GET", |
| 615 | b"HEAD", |
| 616 | b"POST", |
| 617 | b"PUT", |
| 618 | b"DELETE", |
| 619 | b"TRACE", |
| 620 | b"CONNECT", |
| 621 | ] |
| 622 | ) |
| 623 | |
| 624 | @classmethod |
| 625 | def dispatch_hook(cls, _pkt=None, *args, **kargs): |
| 626 | if _pkt and len(_pkt) >= 9: |
| 627 | from scapy.contrib.http2 import _HTTP2_types, H2Frame |
| 628 | |
| 629 | # To detect a valid HTTP2, we check that the type is correct |
| 630 | # that the Reserved bit is set and length makes sense. |
| 631 | while _pkt: |
| 632 | if len(_pkt) < 9: |
| 633 | # Invalid total length |
| 634 | return cls |
| 635 | if ord(_pkt[3:4]) not in _HTTP2_types: |
| 636 | # Invalid type |
| 637 | return cls |
| 638 | length = struct.unpack("!I", b"\0" + _pkt[:3])[0] + 9 |
| 639 | if length > len(_pkt): |
| 640 | # Invalid length |
| 641 | return cls |
| 642 | sid = struct.unpack("!I", _pkt[5:9])[0] |
| 643 | if sid >> 31 != 0: |
| 644 | # Invalid Reserved bit |
| 645 | return cls |
| 646 | _pkt = _pkt[length:] |
| 647 | return H2Frame |
| 648 | return cls |
| 649 | |
| 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): |
no test coverage detected