Class: PacketFu::ICMPv6Packet

Inherits:
Packet
  • Object
show all
Includes:
EthHeaderMixin, ICMPv6HeaderMixin, IPv6HeaderMixin
Defined in:
lib/packetfu/protos/icmpv6.rb

Overview

ICMPv6Packet is used to construct ICMPv6 Packets. They contain an EthHeader, an IPv6Header, and a ICMPv6Header.

Example

icmpv6_pkt.new
icmpv6_pkt.icmpv6_type = 8
icmpv6_pkt.icmpv6_code = 0
icmpv6_pkt.payload = "ABC, easy as 123. As simple as do-re-mi. ABC, 123, baby, you and me!"

icmpv6_pkt.ipv6_saddr="2000::1234"
icmpv6_pkt.ipv6_daddr="2000::5678"

icmpv6_pkt.recalc
icmpv6_pkt.to_f('/tmp/icmpv6.pcap')

Parameters

:eth
   A pre-generated EthHeader object.
:ipv6
   A pre-generated IPv6Header object.
:icmpv6
   A pre-generated ICMPv6Header object.

Instance Attribute Summary collapse

Attributes inherited from Packet

#flavor, #headers, #iface, #inspect_style

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ICMPv6HeaderMixin

#icmpv6_code, #icmpv6_code=, #icmpv6_sum, #icmpv6_sum=, #icmpv6_sum_readable, #icmpv6_type, #icmpv6_type=

Methods included from IPv6HeaderMixin

#ipv6?, #ipv6_calc_len, #ipv6_calc_sum_on_addr, #ipv6_class, #ipv6_class=, #ipv6_daddr, #ipv6_daddr=, #ipv6_dst, #ipv6_dst=, #ipv6_dst_readable, #ipv6_hop, #ipv6_hop=, #ipv6_label, #ipv6_label=, #ipv6_len, #ipv6_len=, #ipv6_next, #ipv6_next=, #ipv6_recalc, #ipv6_saddr, #ipv6_saddr=, #ipv6_src, #ipv6_src=, #ipv6_src_readable, #ipv6_v, #ipv6_v=

Methods included from EthHeaderMixin

#eth_daddr, #eth_daddr=, #eth_dst, #eth_dst=, #eth_dst_readable, #eth_proto, #eth_proto=, #eth_proto_readable, #eth_saddr, #eth_saddr=, #eth_src, #eth_src=, #eth_src_readable

Methods inherited from Packet

#==, #clone, #dissect, #dissection_table, force_binary, #handle_is_identity, #hexify, inherited, #inspect, #inspect_hex, #kind_of?, #layer, layer, #layer_symbol, layer_symbol, #method_missing, #orig_kind_of?, parse, #payload, #payload=, #peek, #proto, #read, #recalc, #respond_to?, #size, #to_f, #to_pcap, #to_s, #to_w, #write

Constructor Details

#initialize(args = {}) ⇒ ICMPv6Packet

Returns a new instance of ICMPv6Packet.



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/packetfu/protos/icmpv6.rb', line 52

def initialize(args={})
  @eth_header = EthHeader.new(args).read(args[:eth])
  @ipv6_header = IPv6Header.new(args).read(args[:ipv6])
  @ipv6_header.ipv6_next = PacketFu::ICMPv6Header::PROTOCOL_NUMBER
  @icmpv6_header = ICMPv6Header.new(args).read(args[:icmpv6])

  @ipv6_header.body = @icmpv6_header
  @eth_header.body = @ipv6_header

  @headers = [@eth_header, @ipv6_header, @icmpv6_header]
  super
  icmpv6_calc_sum
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class PacketFu::Packet

Instance Attribute Details

#eth_headerObject

Returns the value of attribute eth_header.



42
43
44
# File 'lib/packetfu/protos/icmpv6.rb', line 42

def eth_header
  @eth_header
end

#icmpv6_headerObject

Returns the value of attribute icmpv6_header.



42
43
44
# File 'lib/packetfu/protos/icmpv6.rb', line 42

def icmpv6_header
  @icmpv6_header
end

#ipv6_headerObject

Returns the value of attribute ipv6_header.



42
43
44
# File 'lib/packetfu/protos/icmpv6.rb', line 42

def ipv6_header
  @ipv6_header
end

Class Method Details

.can_parse?(str) ⇒ Boolean

Returns:

  • (Boolean)


44
45
46
47
48
49
50
# File 'lib/packetfu/protos/icmpv6.rb', line 44

def self.can_parse?(str)
  return false unless str.size >= 58
  return false unless EthPacket.can_parse? str
  return false unless IPv6Packet.can_parse? str
  return false unless str[20,1] == [PacketFu::ICMPv6Header::PROTOCOL_NUMBER].pack('C')
  return true
end

Instance Method Details

#icmpv6_calc_sumObject

Calculates the checksum for the object.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/packetfu/protos/icmpv6.rb', line 67

def icmpv6_calc_sum
  checksum = ipv6_calc_sum_on_addr
  checksum += PacketFu::ICMPv6Header::PROTOCOL_NUMBER
  checksum += ipv6_len
  # Then compute it on ICMPv6 header + payload
  checksum += (icmpv6_type.to_i << 8) + icmpv6_code.to_i
  chk_body = (payload.to_s.size % 2 == 0 ? payload.to_s : payload.to_s + "\x00")
  if 1.respond_to? :ord
    chk_body.split("").each_slice(2).map { |x| (x[0].ord << 8) + x[1].ord }.
      each { |y| checksum += y }
  else
    chk_body.split("").each_slice(2).map { |x| (x[0] << 8) + x[1] }.
      each { |y| checksum += y }
  end
  checksum = checksum % 0xffff
  checksum = 0xffff - checksum
  checksum == 0 ? 0xffff : checksum
end

#icmpv6_recalc(arg = :all) ⇒ Object

Recalculates the calculatable fields for ICMPv6.



87
88
89
90
91
92
93
94
95
96
# File 'lib/packetfu/protos/icmpv6.rb', line 87

def icmpv6_recalc(arg = :all)
  case arg.to_sym
  when :icmpv6_sum
    self.icmpv6_sum = icmpv6_calc_sum
  when :all
    self.icmpv6_sum = icmpv6_calc_sum
  else
    raise ArgumentError, "No such field `#{arg}'"
  end
end

#peek_formatObject

Peek provides summary data on packet contents.



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/packetfu/protos/icmpv6.rb', line 99

def peek_format
  peek_data = ["6C "]
  peek_data << "%-5d" % self.to_s.size
  type = case self.icmpv6_type.to_i
         when 128
           "ping"
         when 129
           "pong"
         else
           "%02x-%02x" % [self.icmpv6_type, self.icmpv6_code]
         end
  peek_data << "%-21s" % "#{self.ipv6_saddr}:#{type}"
  peek_data << "->"
  peek_data << "%21s" % "#{self.ipv6_daddr}"
  peek_data.join
end