1
0
mirror of https://github.com/halleysfifthinc/Toyota-AVC-LAN synced 2025-06-09 17:06:26 +00:00

64 lines
2.1 KiB
Julia

"""
Reads pcap data from a stream.
"""
mutable struct PcapStreamReader{Src <: IO} <: PcapReader
src::Src
raw_header::Vector{UInt8}
header::PcapHeader
usec_mul::Int64
bswapped::Bool
record_buffer::Vector{UInt8}
@doc """
PcapStreamReader(src::IO)
Create reader over `src`. Will read and process pcap header,
and yield records through `read(::PcapStreamReader)`.
"""
function PcapStreamReader(src::Src) where {Src <: IO}
raw_header = read(src, sizeof(PcapHeader))
length(raw_header) != sizeof(PcapHeader) && throw(EOFError())
h = GC.@preserve raw_header unsafe_load(Ptr{PcapHeader}(pointer(raw_header)))
header, bswapped, nanotime = process_header(h)
new{Src}(src, raw_header, header, nanotime ? 1 : 1000, bswapped, zeros(UInt8, 9000 + sizeof(RecordHeader)))
end
end
"""
PcapStreamReader(path)
Open file at `path` and create PcapStreamReader over its content.
"""
PcapStreamReader(path::AbstractString) = PcapStreamReader(open(path))
Base.close(x::PcapStreamReader) = close(x.src)
Base.position(x::PcapStreamReader) = position(x.src)
Base.seek(x::PcapStreamReader, pos) = seek(x.src, pos)
Base.mark(x::PcapStreamReader) = mark(x.src)
Base.unmark(x::PcapStreamReader) = unmark(x.src)
Base.ismarked(x::PcapStreamReader) = ismarked(x.src)
Base.reset(x::PcapStreamReader) = reset(x.src)
Base.eof(x::PcapStreamReader) = eof(x.src)
"""
read(x::PcapStreamReader) -> PcapRecord
Read one record from pcap data. Record is valid until next read().
Throws `EOFError` if no more data available.
"""
function Base.read(x::PcapStreamReader)
p = pointer(x.record_buffer)
GC.@preserve x begin
unsafe_read(x.src, p, sizeof(RecordHeader))
h = unsafe_load(Ptr{RecordHeader}(p))
if x.bswapped
h = bswap(h)
end
unsafe_read(x.src, p + sizeof(RecordHeader), h.incl_len)
end
t1 = (h.ts_sec + x.header.thiszone) * 1_000_000_000
t2 = Int64(h.ts_usec) * x.usec_mul
t = UnixTime(Dates.UTInstant(Nanosecond(t1 + t2)))
PcapRecord(h, t, x.record_buffer, 0)
end