class Mu::Pcap::Pkthdr

Constants

BSD_AF_INET6

See wiki.wireshark.org/NullLoopback and epan/aftypes.h in wireshark code.

FMT_NNNN
FMT_VVVV

Attributes

caplen[RW]
endian[RW]
len[RW]
pkt[RW]
pkt_raw[RW]
ts_sec[RW]
ts_usec[RW]

Public Class Methods

decode_en10mb(bytes) click to toggle source
# File lib/woolen_common/pcap/mu/pcap/pkthdr.rb, line 121
def self.decode_en10mb bytes
    return Ethernet.from_bytes(bytes)
end
decode_linux_sll(bytes) click to toggle source
# File lib/woolen_common/pcap/mu/pcap/pkthdr.rb, line 125
def self.decode_linux_sll bytes
    Pcap.assert bytes.length >= 16, 'Truncated PCAP packet header: ' +
        "expected at least 16 bytes, got #{bytes.length} bytes"
    packet_type, link_type, addr_len = bytes.unpack('nnn')
    type = bytes[14, 2].unpack('n')[0]
    bytes = bytes[16..-1]
    ethernet = Ethernet.new
    ethernet.type = type
    ethernet.src = '00:01:01:00:00:01'
    ethernet.dst = '00:01:01:00:00:02'
    ethernet.payload = ethernet.payload_raw = bytes
    begin
        case type
            when Ethernet::ETHERTYPE_IP
                ethernet.payload = IPv4.from_bytes ethernet.payload
            when Ethernet::ETHERTYPE_IP6
                ethernet.payload = IPv6.from_bytes ethernet.payload
        end
    rescue ParseError => e
        Pcap.warning e
    end
    return ethernet
end
decode_null(endian, bytes) click to toggle source
# File lib/woolen_common/pcap/mu/pcap/pkthdr.rb, line 86
def self.decode_null endian, bytes
    Pcap.assert bytes.length >= 4, 'Truncated PCAP packet header: ' +
        "expected at least 4 bytes, got #{bytes.length} bytes"
    if endian == BIG_ENDIAN
        format = 'N'
    elsif endian == LITTLE_ENDIAN
        format = 'V'
    end
    family = bytes[0, 4].unpack(format)[0]
    bytes = bytes[4..-1]
    ethernet = Ethernet.new
    ethernet.src = '00:01:01:00:00:01'
    ethernet.dst = '00:01:01:00:00:02'
    ethernet.payload = ethernet.payload_raw = bytes
    if family != Socket::AF_INET and family != Socket::AF_INET6 and
        not BSD_AF_INET6.include?(family)
        raise ParseError, "Unknown PCAP packet header family: #{family}"
    end
    begin
        case family
            when Socket::AF_INET
                ethernet.type = Ethernet::ETHERTYPE_IP
                ethernet.payload = IPv4.from_bytes ethernet.payload
            when Socket::AF_INET6, FREEBSD_AF_INET6, OPENBSD_AF_INET6, DARWIN_AF_INET6
                ethernet.type = Ethernet::ETHERTYPE_IP6
                ethernet.payload = IPv6.from_bytes ethernet.payload
            else
                raise NotImplementedError
        end
    rescue ParseError => e
        Pcap.warning e
    end
    return ethernet
end
new(endian=BIG_ENDIAN, ts_sec=0, ts_usec=0, caplen=0, len=0, pkt=nil) click to toggle source
# File lib/woolen_common/pcap/mu/pcap/pkthdr.rb, line 11
def initialize endian=BIG_ENDIAN, ts_sec=0, ts_usec=0, caplen=0, len=0, pkt=nil
    @endian = endian
    @ts_sec = ts_sec
    @ts_usec = ts_usec
    @caplen = caplen
    @len = len
    @pkt = pkt
    @pkt_raw = pkt
end
read(io, endian=BIG_ENDIAN) click to toggle source
# File lib/woolen_common/pcap/mu/pcap/pkthdr.rb, line 24
def self.read io, endian=BIG_ENDIAN
    if endian == BIG_ENDIAN
        format = FMT_NNNN
    elsif endian == LITTLE_ENDIAN
        format = FMT_VVVV
    end
    bytes = io.read 16
    if not bytes
        raise EOFError, 'Missing PCAP packet header'
    end
    if not bytes.length == 16
        raise ParseError, "Truncated PCAP packet header: expected 16 bytes, got #{bytes.length} bytes"
    end
    ts_sec, ts_usec, caplen, len = bytes.unpack format
    pkt = io.read(caplen)
    if not pkt
        raise ParseError, 'Missing PCAP packet header packet'
    end
    if not pkt.length == caplen
        raise ParseError, "Truncated PCAP packet header: expected #{pkthdr.caplen} bytes, got #{pkthdr.pkt.length} bytes"
    end
    pkthdr = Pkthdr.new endian, ts_sec, ts_usec, caplen, len, pkt
    return pkthdr
end

Public Instance Methods

==(other) click to toggle source
# File lib/woolen_common/pcap/mu/pcap/pkthdr.rb, line 149
def == other
    return self.class == other.class &&
        self.endian == other.endian &&
        self.ts_sec == other.ts_sec &&
        self.ts_usec == other.ts_usec &&
        self.caplen == other.caplen &&
        self.len == other.len &&
        self.pkt == other.pkt
end
decode!(endian, linktype) click to toggle source
# File lib/woolen_common/pcap/mu/pcap/pkthdr.rb, line 63
def decode! endian, linktype
    @pkt = case linktype
               when DLT_NULL;
                   Pkthdr.decode_null endian, @pkt
               when DLT_EN10MB;
                   Pkthdr.decode_en10mb @pkt
               when DLT_RAW;
                   raise NotImplementedError
               when DLT_LINUX_SLL;
                   Pkthdr.decode_linux_sll @pkt
               else
                   raise ParseError, "Unknown PCAP linktype: #{linktype}"
           end
end
write(io) click to toggle source
# File lib/woolen_common/pcap/mu/pcap/pkthdr.rb, line 49
def write io
    if @pkt.is_a? String
        pkt = @pkt
    else
        string_io = StringIO.new
        @pkt.write string_io
        pkt = string_io.string
    end
    len = pkt.length
    bytes = [@ts_sec, @ts_usec, len, len].pack FMT_NNNN
    io.write bytes
    io.write pkt
end