| 2731 | |
| 2732 | |
| 2733 | class ERFEthernetReader(PcapReader, |
| 2734 | metaclass=ERFEthernetReader_metaclass): |
| 2735 | |
| 2736 | def __init__(self, filename, fdesc=None): # type: ignore |
| 2737 | # type: (Union[IO[bytes], str], IO[bytes]) -> None |
| 2738 | self.filename = filename # type: ignore |
| 2739 | self.f = fdesc |
| 2740 | self.power = Decimal(10) ** Decimal(-9) |
| 2741 | |
| 2742 | # time is in 64-bits Endace's format which can be see here: |
| 2743 | # https://www.endace.com/erf-extensible-record-format-types.pdf |
| 2744 | def _convert_erf_timestamp(self, t): |
| 2745 | # type: (int) -> EDecimal |
| 2746 | sec = t >> 32 |
| 2747 | frac_sec = t & 0xffffffff |
| 2748 | frac_sec *= 10**9 |
| 2749 | frac_sec += (frac_sec & 0x80000000) << 1 |
| 2750 | frac_sec >>= 32 |
| 2751 | return EDecimal(sec + self.power * frac_sec) |
| 2752 | |
| 2753 | # The details of ERF Packet format can be see here: |
| 2754 | # https://www.endace.com/erf-extensible-record-format-types.pdf |
| 2755 | def read_packet(self, size=MTU, **kwargs): |
| 2756 | # type: (int, **Any) -> Packet |
| 2757 | |
| 2758 | # General ERF Header have exactly 16 bytes |
| 2759 | hdr = self.f.read(16) |
| 2760 | if len(hdr) < 16: |
| 2761 | raise EOFError |
| 2762 | |
| 2763 | # The timestamp is in little-endian byte-order. |
| 2764 | time = struct.unpack('<Q', hdr[:8])[0] |
| 2765 | # The rest is in big-endian byte-order. |
| 2766 | # Ignoring flags and lctr (loss counter) since they are ERF specific |
| 2767 | # header fields which Packet object does not support. |
| 2768 | type, _, rlen, _, wlen = struct.unpack('>BBHHH', hdr[8:]) |
| 2769 | # Check if the type != 0x02, type Ethernet |
| 2770 | if type & 0x02 == 0: |
| 2771 | raise Scapy_Exception("Invalid ERF Type (Not TYPE_ETH)") |
| 2772 | |
| 2773 | # If there are extended headers, ignore it because Packet object does |
| 2774 | # not support it. Extended headers size is 8 bytes before the payload. |
| 2775 | if type & 0x80: |
| 2776 | _ = self.f.read(8) |
| 2777 | s = self.f.read(rlen - 24) |
| 2778 | else: |
| 2779 | s = self.f.read(rlen - 16) |
| 2780 | |
| 2781 | # Ethernet has 2 bytes of padding containing `offset` and `pad`. Both |
| 2782 | # of the fields are disregarded by Endace. |
| 2783 | pb = s[2:size] |
| 2784 | from scapy.layers.l2 import Ether |
| 2785 | try: |
| 2786 | p = Ether(pb, **kwargs) # type: Packet |
| 2787 | except KeyboardInterrupt: |
| 2788 | raise |
| 2789 | except Exception: |
| 2790 | if conf.debug_dissector: |
no outgoing calls
no test coverage detected
searching dependent graphs…