mirror of
https://github.com/halleysfifthinc/AVCLAN-Mockingboard.git
synced 2026-08-19 20:22:51 +00:00
97 lines
2.4 KiB
Julia
97 lines
2.4 KiB
Julia
"""
|
|
Reads pcap data from an array of bytes.
|
|
"""
|
|
mutable struct PcapBufferReader <: PcapReader
|
|
data::Vector{UInt8}
|
|
raw_header::Vector{UInt8}
|
|
header::PcapHeader
|
|
offset::Int64
|
|
mark::Int64
|
|
usec_mul::Int64
|
|
bswapped::Bool
|
|
|
|
@doc """
|
|
PcapBufferReader(data::Vector{UInt8})
|
|
|
|
Create reader over `data`. Will read and process pcap header,
|
|
and yield records through `read(::PcapBufferReader)`.
|
|
"""
|
|
function PcapBufferReader(data::Vector{UInt8})
|
|
length(data) < sizeof(PcapHeader) && throw(EOFError())
|
|
rh = data[1:sizeof(PcapHeader)]
|
|
h = unsafe_load(Ptr{PcapHeader}(pointer(data)))
|
|
h, bswapped, nanotime = process_header(h)
|
|
new(data, rh, h, sizeof(h), -1, nanotime ? 1 : 1000, bswapped)
|
|
end
|
|
end
|
|
|
|
"""
|
|
PcapBufferReader(path::AbstractString)
|
|
|
|
Memory map file in `path` and create PcapBufferReader over its content.
|
|
"""
|
|
function PcapBufferReader(path::AbstractString)
|
|
io = open(path)
|
|
data = Mmap.mmap(io)
|
|
PcapBufferReader(data)
|
|
end
|
|
|
|
function Base.close(x::PcapBufferReader)
|
|
x.data = UInt8[]
|
|
x.offset = 0
|
|
nothing
|
|
end
|
|
|
|
Base.length(x::PcapBufferReader) = length(x.data)
|
|
Base.position(x::PcapBufferReader) = x.offset
|
|
Base.seek(x::PcapBufferReader, pos) = x.offset = pos; nothing
|
|
|
|
function Base.mark(x::PcapBufferReader)
|
|
x.mark = x.offset
|
|
x.mark
|
|
end
|
|
|
|
function Base.unmark(x::PcapBufferReader)
|
|
if x.mark >= 0
|
|
x.mark = -1
|
|
true
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
Base.ismarked(x::PcapBufferReader) = x.mark >= 0
|
|
|
|
function Base.reset(x::PcapBufferReader)
|
|
!ismarked(x) && error("PcapBufferReader not marked")
|
|
x.offset = x.mark
|
|
x.mark = -1
|
|
x.offset
|
|
end
|
|
|
|
Base.eof(x::PcapBufferReader) = (length(x) - x.offset) < sizeof(RecordHeader)
|
|
|
|
"""
|
|
read(x::PcapBufferReader) -> PcapRecord
|
|
|
|
Read one record from pcap data.
|
|
Throws `EOFError` if no more data available.
|
|
"""
|
|
@inline function Base.read(x::PcapBufferReader)
|
|
eof(x) && throw(EOFError())
|
|
record_offset = x.offset
|
|
p = pointer(x.data) + record_offset
|
|
GC.@preserve x begin
|
|
h = unsafe_load(Ptr{RecordHeader}(p))
|
|
end
|
|
if x.bswapped
|
|
h = bswap(h)
|
|
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)))
|
|
x.offset += sizeof(RecordHeader) + h.incl_len
|
|
x.offset > length(x) && error("Insufficient data in pcap record")
|
|
PcapRecord(h, t, x.data, record_offset)
|
|
end
|