A stream ERF Ethernet writer with more control than wrerf()
| 2826 | |
| 2827 | |
| 2828 | class ERFEthernetWriter(PcapWriter): |
| 2829 | """A stream ERF Ethernet writer with more control than wrerf()""" |
| 2830 | |
| 2831 | def __init__(self, |
| 2832 | filename, # type: Union[IO[bytes], str] |
| 2833 | gz=False, # type: bool |
| 2834 | append=False, # type: bool |
| 2835 | sync=False, # type: bool |
| 2836 | ): |
| 2837 | # type: (...) -> None |
| 2838 | """ |
| 2839 | :param filename: the name of the file to write packets to, or an open, |
| 2840 | writable file-like object. |
| 2841 | :param gz: compress the capture on the fly |
| 2842 | :param append: append packets to the capture file instead of |
| 2843 | truncating it |
| 2844 | :param sync: do not bufferize writes to the capture file |
| 2845 | """ |
| 2846 | super(ERFEthernetWriter, self).__init__(filename, |
| 2847 | gz=gz, |
| 2848 | append=append, |
| 2849 | sync=sync) |
| 2850 | |
| 2851 | def write(self, pkt): # type: ignore |
| 2852 | # type: (_PacketIterable) -> None |
| 2853 | """ |
| 2854 | Writes a Packet, a SndRcvList object, or bytes to a ERF file. |
| 2855 | |
| 2856 | :param pkt: Packet(s) to write (one record for each Packet) |
| 2857 | :type pkt: iterable[scapy.packet.Packet], scapy.packet.Packet |
| 2858 | """ |
| 2859 | # Import here to avoid circular dependency |
| 2860 | from scapy.supersocket import IterSocket |
| 2861 | for p in IterSocket(pkt).iter: |
| 2862 | self.write_packet(p) |
| 2863 | |
| 2864 | def write_packet(self, pkt): # type: ignore |
| 2865 | # type: (Packet) -> None |
| 2866 | |
| 2867 | if hasattr(pkt, "time"): |
| 2868 | sec = int(pkt.time) |
| 2869 | usec = int((int(round((pkt.time - sec) * 10**9)) << 32) / 10**9) |
| 2870 | t = (sec << 32) + usec |
| 2871 | else: |
| 2872 | t = int(time.time()) << 32 |
| 2873 | |
| 2874 | # There are 16 bytes of headers + 2 bytes of padding before the packets |
| 2875 | # payload. |
| 2876 | rlen = len(pkt) + 18 |
| 2877 | |
| 2878 | if hasattr(pkt, "wirelen"): |
| 2879 | wirelen = pkt.wirelen |
| 2880 | if wirelen is None: |
| 2881 | wirelen = rlen |
| 2882 | |
| 2883 | self.f.write(struct.pack("<Q", t)) |
| 2884 | self.f.write(struct.pack(">BBHHHH", 2, 0, rlen, 0, wirelen, 0)) |
| 2885 | self.f.write(bytes(pkt)) |