metasploit-framework/lib/packetfu/ipv6.rb

138 lines
3.8 KiB
Ruby
Raw Normal View History

module PacketFu
# AddrIpv6 handles addressing for IPv6Header
#
# ==== Header Definition
#
#
# uint32be :a1
# uint32be :a2
# uint32be :a3
# uint32be :a4
class AddrIpv6 < BinData::MultiValue
uint32be :a1
uint32be :a2
uint32be :a3
uint32be :a4
end
# IPv6Header is complete IPv6 struct, used in IPv6Packet.
#
# ==== Header Definition
#
# bit4 :ipv6_v, :initial_value => 6 # Versiom
# bit8 :ipv6_class # Class
# bit20 :ipv6_label # Label
# uint16be :ipv6_len, :initial_value => lambda { ipv6_calc_len } # Payload length
# uint8 :ipv6_next # Next Header
# uint8 :ipv6_hop, :initial_value => 0xff # Hop limit
# addr_ipv6 :ipv6_src
# addr_ipv6 :ipv6_dst
# rest :body
class IPv6Header < BinData::MultiValue
bit4 :ipv6_v, :initial_value => 6 # Versiom
bit8 :ipv6_class # Class
bit20 :ipv6_label # Label
uint16be :ipv6_len, :initial_value => lambda { ipv6_calc_len } # Payload length
uint8 :ipv6_next # Next Header
uint8 :ipv6_hop, :initial_value => 0xff # Hop limit
addr_ipv6 :ipv6_src
addr_ipv6 :ipv6_dst
rest :body
def ipv6_calc_len
ipv6_len = self.body.size
end
def ipv6_recalc(arg=:all)
case arg
when :ipv6_len
ipv6_calc_len
when :all
ipv6_recalc(:len)
end
end
# Presents in a more readable form.
def ipv6_saddr
addr = [self.ipv6_src.a1,self.ipv6_src.a2,self.ipv6_src.a3,self.ipv6_src.a4].pack("NNNN")
addr.unpack("H*")[0].scan(/.{8}/).collect {|x| x.sub(/^0*([0-9a-f])/,"\\1")}.join(":")
end
# Takes in a more readable form. Leading zero compression is fine, but that's it. :(
def ipv6_saddr=(str)
arr = str.split(':').collect {|x| x.to_i(16)}
self.ipv6_src.a1 = arr[0]
self.ipv6_src.a2 = arr[1]
self.ipv6_src.a3 = arr[2]
self.ipv6_src.a4 = arr[3]
end
# Presents in a more readable form.
def ipv6_daddr
addr = [self.ipv6_dst.a1,self.ipv6_dst.a2,self.ipv6_dst.a3,self.ipv6_dst.a4].pack("NNNN")
addr.unpack("H*")[0].scan(/.{8}/).collect {|x| x.sub(/^0*([0-9a-f])/,"\\1")}.join(":")
end
# Takes in a more readable form. Leading zero compression is fine, but that's it. :(
def ipv6_daddr=(str)
arr = str.split(':').collect {|x| x.to_i(16)}
self.ipv6_dst.a1 = arr[0]
self.ipv6_dst.a2 = arr[1]
self.ipv6_dst.a3 = arr[2]
self.ipv6_dst.a4 = arr[3]
end
end # class IPv6Header
# IPv6Packet is used to construct IPv6 Packets. They contain an EthHeader and an IPv6Header, and in
# the distant, unknowable future, will take interesting IPv6ish payloads.
#
# This mostly complete, but not very useful. It's intended primarily as an example protocol.
#
# == Parameters
#
# :eth
# A pre-generated EthHeader object.
# :ip
# A pre-generated IPHeader object.
# :flavor
# TODO: Sets the "flavor" of the IPv6 packet. No idea what this will look like, haven't done much IPv6 fingerprinting.
# :config
# A hash of return address details, often the output of Utils.whoami?
class IPv6Packet < Packet
attr_accessor :eth_header, :ipv6_header
def ethernet?; true; end
def ipv6?; true; end
def initialize(args={})
@eth_header = (args[:eth] || EthHeader.new)
@ipv6_header = (args[:ipv6] || IPv6Header.new)
@eth_header.eth_proto = 0x86dd
@eth_header.body=@ipv6_header
@headers = [@eth_header, @arp_header]
super
end
# Peek provides summary data on packet contents.
def peek(args={})
peek_data = ["6 "]
peek_data << "%-5d" % self.to_s.size
peek_data << self.ipv6_saddr
peek_data << "->"
peek_data << self.ipv6_daddr
peek_data << " N:"
peek_data << self.ipv6_next.to_s(16)
peek_data.join
end
end # class IPv6Packet
end # module PacketFu