class PacketGen::Header::IPv6

IPv6 ({tools.ietf.org/html/rfc8200 RFC 8200})

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| Traffic Class |           Flow Label                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Payload Length        |  Next Header  |   Hop Limit   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                         Source Address                        +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                      Destination Address                      +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

A IPv6 header consists of:

Create a IPv6 header

# standalone
ipv6 = PacketGen::Header::IPv6.new
# in a packet
pkt = PacketGen.gen('IPv6')
# access to IPv6 header
pkt.ipv6   # => PacketGen::Header::IPv6

IPv6 attributes

ipv6.u32 = 0x60280001
# the same as
ipv6.version = 6
ipv6.traffic_class = 2
ipv6.flow_label = 0x80001

ipv6.length = 0x43
ipv6.hop = 0x40
ipv6.next = 6
ipv6.src = '::1'
ipv6.src                # => "::1"
ipv6[:src]              # => PacketGen::Header::IPv6::Addr
ipv6.dst = '2001:1234:5678:abcd::123'
ipv6.body.read 'this is a body'

Add IPv6 extensions

In IPv6, optional extensions are encoded in separate headers that may be placed between the IPv6 header and the upper-layer header.

In PacketGen, a IPv6 extension is processedf as a classical header:

pkt = PacketGen.gen('IPv6')
# Add a HopByHop extension
pkt.add('IPv6::HopByHop')
pkt.ipv6_hopbyhop.options << { type: 'router_alert', value: [0].pack('n') }
# Add another header
pkt.add('UDP')

@author Sylvain Daubert

Constants

ETHERTYPE

IPv6 Ether type

Option

@!parse

# Option for {HopByHop} IPv6 extension header.
# @since 3.1.0 subclass of {Types::AbstractTLV}
class Option <AbstractTLV; end

@private

Public Class Methods

bind(header_klass, args={}) click to toggle source

Bind a upper header to IPv6 and its defined extension headers. @see Base.bind

# File lib/packetgen/header/ipv6.rb, line 205
def bind(header_klass, args={})
  IPv6.old_bind header_klass, args
  [IPv6::HopByHop].each do |klass|
    klass.bind header_klass, args
  end
end
Also aliased as: old_bind
old_bind(header_klass, args={})
Alias for: bind

Public Instance Methods

calc_length() click to toggle source

Compute length and set len field @return [Integer]

# File lib/packetgen/header/ipv6.rb, line 132
def calc_length
  Base.calculate_and_set_length self, header_in_size: false
end
inspect() click to toggle source

@return [String]

Calls superclass method
# File lib/packetgen/header/ipv6.rb, line 157
def inspect
  super do |attr|
    next unless attr == :u32

    str = Inspect.inspect_attribute(attr, self[attr])
    shift = Inspect.shift_level
    str << shift + Inspect::FMT_ATTR % ['', 'version', version]
    tclass = Inspect.int_dec_hex(traffic_class, 2)
    str << shift + Inspect::FMT_ATTR % ['', 'tclass', tclass]
    fl_value = Inspect.int_dec_hex(flow_label, 5)
    str << shift + Inspect::FMT_ATTR % ['', 'flow_label', fl_value]
  end
end
parse?() click to toggle source

Check version field @see [Base#parse?]

# File lib/packetgen/header/ipv6.rb, line 173
def parse?
  version == 6
end
pseudo_header_checksum() click to toggle source

Get IPv6 part of pseudo header checksum. @return [Integer]

# File lib/packetgen/header/ipv6.rb, line 138
def pseudo_header_checksum
  sum = 0
  self[:src].to_a.each { |word| sum += word.to_i }
  self[:dst].to_a.each { |word| sum += word.to_i }
  sum
end
reply!() click to toggle source

Invert source and destination addresses @return [self] @since 2.7.0

# File lib/packetgen/header/ipv6.rb, line 180
def reply!
  self[:src], self[:dst] = self[:dst], self[:src]
  self
end
to_w(_iface=nil) click to toggle source

Send IPv6 packet on wire. All fields may be set (even {#version}). @param [String] _iface interface name (not used) @return [void] @since 3.0.0 no more limitations on flow_label, length and src fields.

# File lib/packetgen/header/ipv6.rb, line 149
def to_w(_iface=nil)
  sock = Socket.new(Socket::AF_INET6, Socket::SOCK_RAW, Socket::IPPROTO_RAW)
  sockaddrin = Socket.sockaddr_in(0, dst)
  sock.send to_s, 0, sockaddrin
  sock.close
end