Class: PacketGen::Header::IPv6

Inherits:
Struct
  • Object
show all
Extended by:
HeaderClassMethods
Includes:
HeaderMethods, StructFu
Defined in:
lib/packetgen/header/ipv6.rb

Overview

IPv6 header class

Author:

  • Sylvain Daubert

Defined Under Namespace

Classes: Addr

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from HeaderClassMethods

bind_header, known_headers

Methods included from HeaderMethods

#header_id, #ip_header, #packet, #packet=

Methods included from StructFu

#clone, #set_endianness, #sz, #typecast

Methods inherited from Struct

#force_binary

Constructor Details

#initialize(options = {}) ⇒ IPv6

Returns a new instance of IPv6.

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :version (Integer)
  • :traffic_length (Integer)
  • :flow_label (Integer)
  • :length (Integer)

    payload length

  • :next (Integer)
  • :hop (Integer)
  • :src (String)

    colon-delimited source address

  • :dst (String)

    colon-delimited destination address

  • :body (String)

    binary string



97
98
99
100
101
102
103
104
105
106
107
# File 'lib/packetgen/header/ipv6.rb', line 97

def initialize(options={})
  super options[:version] || 6,
        options[:traffic_class] || 0,
        options[:flow_label] || 0,
        Int16.new(options[:length]),
        Int8.new(options[:next]),
        Int8.new(options[:hop] || 64),
        Addr.new.parse(options[:src] || '::1'),
        Addr.new.parse(options[:dst] || '::1'),
        StructFu::String.new.read(options[:body])
end

Instance Attribute Details

#bodyObject

Returns the value of attribute body

Returns:

  • (Object)

    the current value of body



9
10
11
# File 'lib/packetgen/header/ipv6.rb', line 9

def body
  @body
end

#dstString Also known as: destination

Getter for dst attribute

Returns:



9
10
11
# File 'lib/packetgen/header/ipv6.rb', line 9

def dst
  @dst
end

#flow_labelObject

Returns the value of attribute flow_label

Returns:

  • (Object)

    the current value of flow_label



9
10
11
# File 'lib/packetgen/header/ipv6.rb', line 9

def flow_label
  @flow_label
end

#hopInteger

Getter for hop attribute

Returns:

  • (Integer)


9
10
11
# File 'lib/packetgen/header/ipv6.rb', line 9

def hop
  @hop
end

#lengthInteger

Getter for length attribute

Returns:

  • (Integer)


9
10
11
# File 'lib/packetgen/header/ipv6.rb', line 9

def length
  @length
end

#nextInteger

Getter for next attribute

Returns:

  • (Integer)


9
10
11
# File 'lib/packetgen/header/ipv6.rb', line 9

def next
  @next
end

#srcString Also known as: source

Getter for src attribute

Returns:



9
10
11
# File 'lib/packetgen/header/ipv6.rb', line 9

def src
  @src
end

#traffic_classObject

Returns the value of attribute traffic_class

Returns:

  • (Object)

    the current value of traffic_class



9
10
11
# File 'lib/packetgen/header/ipv6.rb', line 9

def traffic_class
  @traffic_class
end

#versionObject

Returns the value of attribute version

Returns:

  • (Object)

    the current value of version



9
10
11
# File 'lib/packetgen/header/ipv6.rb', line 9

def version
  @version
end

Instance Method Details

#calc_lengthInteger

Compute length and set len field

Returns:

  • (Integer)


132
133
134
# File 'lib/packetgen/header/ipv6.rb', line 132

def calc_length
  self.length = body.sz
end

#pseudo_header_sumInteger

Get IPv6 part of pseudo header sum.

Returns:

  • (Integer)


214
215
216
217
218
219
# File 'lib/packetgen/header/ipv6.rb', line 214

def pseudo_header_sum
  sum = 0
  self[:src].each { |word| sum += word.to_i }
  self[:dst].each { |word| sum += word.to_i }
  sum
end

#read(str) ⇒ self

Read a IP header from a string

Parameters:

  • str (String)

    binary string

Returns:

  • (self)

Raises:



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/packetgen/header/ipv6.rb', line 112

def read(str)
  return self if str.nil?
  raise ParseError, 'string too short for Eth' if str.size < self.sz
  force_binary str
  first32 = str[0, 4].unpack('N').first
  self.version = first32 >> 28
  self.traffic_class = (first32 >> 20) & 0xff
  self.flow_label = first32 & 0xfffff

  self[:length].read str[4, 2]
  self[:next].read str[6, 1]
  self[:hop].read str[7, 1]
  self[:src].read str[8, 16]
  self[:dst].read str[24, 16]
  self[:body].read str[40..-1]
  self
end

#to_sString

Get binary string

Returns:



207
208
209
210
# File 'lib/packetgen/header/ipv6.rb', line 207

def to_s
  first32 = (version << 28) | (traffic_class << 20) | flow_label
  [first32].pack('N') << to_a[3..-1].map { |field| field.to_s }.join
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.

Parameters:

  • iface (String) (defaults to: nil)

    interface name

Raises:



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/packetgen/header/ipv6.rb', line 228

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