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:
-
a first 32-bit word ({#u32}, of {Types::Int32} type) composed of:
-
a 4-bit {#version} field,
-
a 8-bit {#traffic_class} field,
-
a 20-bit {#flow_label} field,
-
-
a payload length field ({#length}, {Types::Int16} type}),
-
a next header field ({#next}, {Types::Int8} type),
-
a hop-limit field ({#hop},
Int8
type), -
a source address field ({#src}, {IPv6::Addr} type),
-
a destination address field ({#dst},
IPv6::Addr
type), -
and a {#body} ({Types::String} type).
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 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
Public Instance Methods
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
@return [String]
# 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
Check version field @see [Base#parse?]
# File lib/packetgen/header/ipv6.rb, line 173 def parse? version == 6 end
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
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
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