Class: PacketGen::Header::IPv6

Inherits:
Base show all
Defined in:
lib/packetgen/header/ipv6.rb,
lib/packetgen/header/ipv6.rb,
lib/packetgen/header/ipv6.rb,
lib/packetgen/header/ipv6/addr.rb,
lib/packetgen/header/ipv6/extension.rb,
lib/packetgen/header/ipv6/hop_by_hop.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'

Defined Under Namespace

Classes: Addr, ArrayOfAddr, Extension, HopByHop, Option, Options, Pad1

Constant Summary collapse

ETHERTYPE =

IPv6 Ether type

0x86dd

Instance Attribute Summary collapse

Attributes inherited from Base

#packet

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#added_to_packet, calculate_and_set_length, #header_id, inherited, #ip_header, known_headers, #ll_header, #method_name, protocol_name, #protocol_name

Methods inherited from Types::Fields

#[], #[]=, define_bit_fields_on, define_field, define_field_after, define_field_before, delete_field, #fields, #force_binary, inherited, #initialize, #is_optional?, #is_present?, #optional_fields, #read, #sz, #to_h, #to_s

Constructor Details

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

Instance Attribute Details

#bodyTypes::String, Header::Base



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

define_field :body, Types::String

#dstAddr

IPv6 destination address



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

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

#flow_labelInteger



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

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

#hopInteger

8-bit IPv6 hop limit



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

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

#lengthInteger

16-bit word of IPv6 payload length



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

define_field :length, Types::Int16

#nextInteger

8-bit IPv6 next payload value



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

define_field :next, Types::Int8

#srcAddr

IPv6 source address



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

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

#traffic_classInteger



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

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

#u32Integer

First 32-bit word of IPv6 header



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

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

#versionInteger



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

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

Class Method Details

.bind(header_klass, args = {}) ⇒ Object

Bind a upper header to IPv6 and its defined extension headers.

See Also:



190
191
192
193
194
195
# File 'lib/packetgen/header/ipv6.rb', line 190

def bind(header_klass, args={})
  IPv6.old_bind header_klass, args
  [IPv6::HopByHop].each do |klass|
    klass.bind header_klass, args
  end
end

.bind_header(header_klass, args = {}) ⇒ Object

Deprecated.

USe bind.

Bind a upper header to IPv6 and its defined extension headers.

See Also:



199
200
201
202
# File 'lib/packetgen/header/ipv6.rb', line 199

def bind_header(header_klass, args={})
  Deprecation.deprecated(self, __method__, 'bind', klass_method: true)
  bind header_klass, args
end

.old_bindObject



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

alias old_bind bind

Instance Method Details

#calc_lengthInteger

Compute length and set len field



94
95
96
# File 'lib/packetgen/header/ipv6.rb', line 94

def calc_length
  Base.calculate_and_set_length self, header_in_size: false
end

#inspectString



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/packetgen/header/ipv6.rb', line 139

def inspect
  str = Inspect.dashed_line(self.class, 2)
  fields.each do |attr|
    next if attr == :body
    str << Inspect.inspect_attribute(attr, self[attr], 2)
    if attr == :u32
      shift = Inspect.shift_level(2)
      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
  str
end

#parse?Boolean

Check version field

See Also:

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


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

def parse?
  version == 6
end

#pseudo_header_checksumInteger

Get IPv6 part of pseudo header checksum.



100
101
102
103
104
105
# File 'lib/packetgen/header/ipv6.rb', line 100

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!self

Invert source and destination addresses

Since:

  • 2.7.0



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

def reply!
  self[:src], self[:dst] = self[:dst], self[:src]
  self
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:



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/packetgen/header/ipv6.rb', line 114

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
  sock.close
end