class Mu::Pcap::IPv6

Constants

FORMAT

Attributes

hop_limit[RW]
next_header[RW]
proto[RW]
ttl[RW]

Public Class Methods

ah_header_from_bytes(ipv6, bytes, name) click to toggle source

Parse authentication header (whose length field is interpeted differently)

# File lib/woolen_common/pcap/mu/pcap/ipv6.rb, line 111
def self.ah_header_from_bytes ipv6, bytes, name
    Pcap.assert bytes.length >= 8, "Truncated IPv6 #{name} header"
    length = (bytes[1].ord + 2) * 4
    Pcap.assert bytes.length >= length, "Truncated IPv6 #{name} header"
    return payload_from_bytes(ipv6, bytes[0].ord, bytes[length..-1])
end
eight_byte_header_from_bytes(ipv6, bytes, name) click to toggle source

Parse extension header that's a multiple of 8 bytes

# File lib/woolen_common/pcap/mu/pcap/ipv6.rb, line 103
def self.eight_byte_header_from_bytes ipv6, bytes, name
    Pcap.assert bytes.length >= 8, "Truncated IPv6 #{name} header"
    length = (bytes[1].ord + 1) * 8
    Pcap.assert bytes.length >= length, "Truncated IPv6 #{name} header"
    return payload_from_bytes(ipv6, bytes[0].ord, bytes[length..-1])
end
from_bytes(bytes) click to toggle source
# File lib/woolen_common/pcap/mu/pcap/ipv6.rb, line 36
def self.from_bytes bytes
    Pcap.assert bytes.bytesize >= 40, 'Truncated IPv6 header: ' +
        "expected at least 40 bytes, got #{bytes.bytesize} bytes"

    vcl, length, next_header, hop_limit, src, dst =
        bytes[0, 40].unpack FORMAT
    version = vcl >> 28 & 0x0f
    traffic_class = vcl >> 20 & 0xff
    flow_label = vcl & 0xfffff

    Pcap.assert version == 6, "Wrong IPv6 version: got (#{version})"
    Pcap.assert bytes.length >= (40 + length), 'Truncated IPv6 header: ' +
        "expected #{length + 40} bytes, got #{bytes.length} bytes"

    ipv6 = IPv6.new
    ipv6.next_header = next_header
    ipv6.hop_limit = hop_limit
    ipv6.src = IPAddr.new_ntoh(src).to_s
    ipv6.dst = IPAddr.new_ntoh(dst).to_s

    ipv6.payload_raw = bytes[40..-1]
    ipv6.next_header, ipv6.payload =
        payload_from_bytes ipv6, ipv6.next_header, bytes[40...40+length]

    return ipv6
end
new() click to toggle source
Calls superclass method Mu::Pcap::IP::new
# File lib/woolen_common/pcap/mu/pcap/ipv6.rb, line 15
def initialize
    super
    @next_header = 0
    @hop_limit = 64
end
payload_from_bytes(ipv6, next_header, bytes) click to toggle source

Parse bytes and returns next_header and payload. Skips extension headers.

# File lib/woolen_common/pcap/mu/pcap/ipv6.rb, line 65
def self.payload_from_bytes ipv6, next_header, bytes
    begin
        case next_header
            when IPPROTO_TCP
                payload = TCP.from_bytes bytes
            when IPPROTO_UDP
                payload = UDP.from_bytes bytes
            when IPPROTO_SCTP
                payload = SCTP.from_bytes bytes
            when IPPROTO_HOPOPTS
                next_header, payload = eight_byte_header_from_bytes(ipv6,
                                                                    bytes, 'hop-by-hop options')
            when IPPROTO_ROUTING
                next_header, payload = eight_byte_header_from_bytes(ipv6,
                                                                    bytes, 'routing')
            when IPPROTO_DSTOPTS
                next_header, payload = eight_byte_header_from_bytes(ipv6,
                                                                    bytes, 'destination options')
            when IPPROTO_FRAGMENT
                Pcap.assert bytes.length >= 8,
                            "Truncated IPv6 fragment header"
                Pcap.assert false, 'IPv6 fragments are not supported'
            when IPPROTO_AH
                next_header, payload = ah_header_from_bytes(ipv6,
                                                            bytes, 'authentication header')
            when IPPROTO_NONE
                payload = ''
            else
                payload = bytes
        end
    rescue ParseError => e
        Pcap.warning e
        payload = bytes
    end
    return [next_header, payload]
end

Public Instance Methods

==(other) click to toggle source
Calls superclass method Mu::Pcap::IP#==
# File lib/woolen_common/pcap/mu/pcap/ipv6.rb, line 140
def == other
    return super &&
        self.next_header == other.next_header &&
        self.hop_limit == other.hop_limit
end
flow_id() click to toggle source
# File lib/woolen_common/pcap/mu/pcap/ipv6.rb, line 28
def flow_id
    if not @payload or @payload.is_a? String
        return [:ipv6, @next_header, @src, @dst]
    else
        return [:ipv6, @src, @dst, @payload.flow_id]
    end
end
pseudo_header(payload_length) click to toggle source
# File lib/woolen_common/pcap/mu/pcap/ipv6.rb, line 134
def pseudo_header payload_length
    return IPAddr.new(@src, Socket::AF_INET6).hton +
        IPAddr.new(@dst, Socket::AF_INET6).hton +
        [payload_length, '', @next_header].pack('Na3C')
end
v6?() click to toggle source
# File lib/woolen_common/pcap/mu/pcap/ipv6.rb, line 21
def v6?
    return true
end
write(io) click to toggle source
# File lib/woolen_common/pcap/mu/pcap/ipv6.rb, line 118
def write io
    if @payload.is_a? String
        payload = @payload
    else
        string_io = StringIO.new
        @payload.write string_io, self
        payload = string_io.string
    end
    src = IPAddr.new(@src, Socket::AF_INET6).hton
    dst = IPAddr.new(@dst, Socket::AF_INET6).hton
    header = [0x60000000, payload.bytesize, @next_header, @hop_limit,
              src, dst].pack FORMAT
    io.write header
    io.write payload
end