Wrap a stream socket into a layer 2 SuperSocket :param sock: the socket to wrap :param basecls: the base class packet to use to dissect the packet
| 455 | |
| 456 | |
| 457 | class StreamSocket(SimpleSocket): |
| 458 | """ |
| 459 | Wrap a stream socket into a layer 2 SuperSocket |
| 460 | |
| 461 | :param sock: the socket to wrap |
| 462 | :param basecls: the base class packet to use to dissect the packet |
| 463 | """ |
| 464 | desc = "transforms a stream socket into a layer 2" |
| 465 | |
| 466 | def __init__(self, |
| 467 | sock, # type: socket.socket |
| 468 | basecls=None, # type: Optional[Type[Packet]] |
| 469 | ): |
| 470 | # type: (...) -> None |
| 471 | from scapy.sessions import streamcls |
| 472 | self.rcvcls = streamcls(basecls or conf.raw_layer) |
| 473 | self.metadata: Dict[str, Any] = {} |
| 474 | self.streamsession: Dict[str, Any] = {} |
| 475 | self._buf = b"" |
| 476 | super(StreamSocket, self).__init__(sock, basecls=basecls) |
| 477 | |
| 478 | def recv(self, x=None, **kwargs): |
| 479 | # type: (Optional[int], Any) -> Optional[Packet] |
| 480 | if x is None: |
| 481 | x = MTU |
| 482 | # Block but in PEEK mode |
| 483 | data = self.ins.recv(x, socket.MSG_PEEK) |
| 484 | if data == b"": |
| 485 | raise EOFError |
| 486 | x = len(data) |
| 487 | pkt = self.rcvcls(self._buf + data, self.metadata, self.streamsession) |
| 488 | if pkt is None: # Incomplete packet. |
| 489 | self._buf += self.ins.recv(x) |
| 490 | return self.recv(x) |
| 491 | self.metadata.clear() |
| 492 | # Strip any madding |
| 493 | pad = pkt.getlayer(conf.padding_layer) |
| 494 | if pad is not None and pad.underlayer is not None: |
| 495 | del pad.underlayer.payload |
| 496 | while pad is not None and not isinstance(pad, NoPayload): |
| 497 | x -= len(pad.load) |
| 498 | pad = pad.payload |
| 499 | # Only receive the packet length |
| 500 | self.ins.recv(x) |
| 501 | self._buf = b"" |
| 502 | return pkt |
| 503 | |
| 504 | |
| 505 | class StreamSocketPeekless(StreamSocket): |
no outgoing calls
no test coverage detected