Class: PacketGen::Header::IPv6

Inherits:
Base show all
Defined in:
lib/packetgen/header/ipv6.rb

Overview

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'

Author:

  • Sylvain Daubert

Defined Under Namespace

Classes: Addr

Constant Summary collapse

ETHERTYPE =

IPv6 Ether type

0x86dd

Instance Attribute Summary collapse

Attributes inherited from Base

#packet

Instance Method Summary collapse

Methods inherited from Base

bind_header, #header_id, inherited, #ip_header, known_headers, #protocol_name

Methods inherited from Types::Fields

#[], #[]=, define_bit_fields_on, define_field, define_field_after, define_field_before, #fields, #force_binary, inherited, #initialize, #read, #sz, #to_h, #to_s

Constructor Details

This class inherits a constructor from PacketGen::Types::Fields

Instance Attribute Details

#bodyTypes::String, Header::Base



146
# File 'lib/packetgen/header/ipv6.rb', line 146

define_field :body, Types::String

#dstAddr

IPv6 destination address



143
# File 'lib/packetgen/header/ipv6.rb', line 143

define_field :dst, Addr, default: '::1'

#flow_labelInteger



154
# File 'lib/packetgen/header/ipv6.rb', line 154

define_bit_fields_on :u32, :version, 4, :traffic_class, 8, :flow_label, 20

#hopInteger

8-bit IPv6 hop limit



135
# File 'lib/packetgen/header/ipv6.rb', line 135

define_field :hop, Types::Int8, default: 64

#lengthInteger

16-bit word of IPv6 payload length



127
# File 'lib/packetgen/header/ipv6.rb', line 127

define_field :length, Types::Int16

#nextInteger

8-bit IPv6 next payload value



131
# File 'lib/packetgen/header/ipv6.rb', line 131

define_field :next, Types::Int8

#srcAddr

IPv6 source address



139
# File 'lib/packetgen/header/ipv6.rb', line 139

define_field :src, Addr, default: '::1'

#traffic_classInteger



154
# File 'lib/packetgen/header/ipv6.rb', line 154

define_bit_fields_on :u32, :version, 4, :traffic_class, 8, :flow_label, 20

#u32Integer

First 32-bit word of IPv6 header



123
# File 'lib/packetgen/header/ipv6.rb', line 123

define_field :u32, Types::Int32, default: 0x6000_0000

#versionInteger



154
# File 'lib/packetgen/header/ipv6.rb', line 154

define_bit_fields_on :u32, :version, 4, :traffic_class, 8, :flow_label, 20

Instance Method Details

#calc_lengthInteger

Compute length and set len field



158
159
160
# File 'lib/packetgen/header/ipv6.rb', line 158

def calc_length
  self.length = body.sz
end

#inspectString



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/packetgen/header/ipv6.rb', line 202

def inspect
  str = Inspect.dashed_line(self.class, 2)
  to_h.each do |attr, value|
    next if attr == :body
    str << Inspect.inspect_attribute(attr, value, 2)
    if attr == :u32
      shift = Inspect.shift_level(2)
      str << shift + Inspect::INSPECT_FMT_ATTR % ['', 'version', version]
      tclass = Inspect.int_dec_hex(traffic_class, 2)
      str << shift + Inspect::INSPECT_FMT_ATTR % ['', 'tclass', tclass]
      fl_value = Inspect.int_dec_hex(flow_label, 5)
      str << shift + Inspect::INSPECT_FMT_ATTR % ['', 'flow_label', fl_value]
    end
  end
  str
end

#parse?Boolean

Check version field

See Also:

  • PacketGen::Header::IPv6.[Base[Base#parse?]


221
222
223
# File 'lib/packetgen/header/ipv6.rb', line 221

def parse?
  version == 6
end

#pseudo_header_checksumInteger

Get IPv6 part of pseudo header checksum.



164
165
166
167
168
169
# File 'lib/packetgen/header/ipv6.rb', line 164

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

#to_w(iface = nil) ⇒ void

This method returns an undefined value.

Send IPv6 packet on wire.

When sending packet at IPv6 level, version, flow_label and length fields are set by kernel. Source address should be a unicast address assigned to the host. To set any of this fields, use Eth#to_w.

Raises:



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/packetgen/header/ipv6.rb', line 178

def to_w(iface=nil)
  sock = Socket.new(Socket::AF_INET6, Socket::SOCK_RAW, self.next)
  sockaddrin = Socket.sockaddr_in(0, dst)

  # IPv6 RAW sockets don't have IPHDRINCL option to send IPv6 header.
  # So, header must be built using ancillary data.
  # Only src address, traffic_class and hop_limit can be set this way.
  hop_limit = Socket::AncillaryData.int(Socket::AF_INET6,
                                        Socket::IPPROTO_IPV6,
                                        Socket::IPV6_HOPLIMIT, hop)
  tc = Socket::AncillaryData.int(Socket::AF_INET6,
                                 Socket::IPPROTO_IPV6,
                                 Socket::IPV6_TCLASS,
                                 traffic_class)

  # src address is set through PKT_INFO, which needs interface index.
  ifaddr = Socket.getifaddrs.find { |ia| ia.name == iface }
  raise WireError, "unknown #{iface} interface" if ifaddr.nil?
  pkt_info = Socket::AncillaryData.ipv6_pktinfo(Addrinfo.ip(src), ifaddr.ifindex)

  sock.sendmsg body.to_s, 0, sockaddrin, hop_limit, tc, pkt_info
end