Class: PacketFu::UDPPacket

Inherits:
Packet
  • Object
show all
Includes:
EthHeaderMixin, IPHeaderMixin, UDPHeaderMixin
Defined in:
lib/packetfu/protos/udp.rb

Overview

UDPPacket is used to construct UDP Packets. They contain an EthHeader, an IPHeader, and a UDPHeader.

Example

udp_pkt = PacketFu::UDPPacket.new
udp_pkt.udp_src=rand(0xffff-1024) + 1024
udp_pkt.udp_dst=53

udp_pkt.ip_saddr="1.2.3.4"
udp_pkt.ip_daddr="10.20.30.40"

udp_pkt.recalc
udp_pkt.to_f('/tmp/udp.pcap')

Parameters

:eth
  A pre-generated EthHeader object.
:ip
  A pre-generated IPHeader object.
:flavor
  TODO: Sets the "flavor" of the UDP packet. UDP packets don't tend have a lot of
  flavor, but their underlying ip headers do.
:config
 A hash of return address details, often the output of Utils.whoami?

Instance Attribute Summary collapse

Attributes inherited from Packet

#flavor, #headers, #iface, #inspect_style

Class Method Summary collapse

Instance Method Summary collapse

Methods included from UDPHeaderMixin

#udp_calc_len, #udp_dport, #udp_dport=, #udp_dst, #udp_dst=, #udp_len, #udp_len=, #udp_sport, #udp_sport=, #udp_src, #udp_src=, #udp_sum, #udp_sum=, #udp_sum_readable

Methods included from IPHeaderMixin

#ip_calc_id, #ip_calc_len, #ip_calc_sum, #ip_daddr, #ip_daddr=, #ip_dst, #ip_dst=, #ip_dst_readable, #ip_frag, #ip_frag=, #ip_hl, #ip_hl=, #ip_hlen, #ip_id, #ip_id=, #ip_id_readable, #ip_len, #ip_len=, #ip_proto, #ip_proto=, #ip_recalc, #ip_saddr, #ip_saddr=, #ip_src, #ip_src=, #ip_src_readable, #ip_sum, #ip_sum=, #ip_sum_readable, #ip_tos, #ip_tos=, #ip_ttl, #ip_ttl=, #ip_v, #ip_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, #recalc, #respond_to?, #size, #to_f, #to_pcap, #to_s, #to_w, #write

Constructor Details

#initialize(args = {}) ⇒ UDPPacket

Returns a new instance of UDPPacket


64
65
66
67
68
69
70
71
72
73
74
# File 'lib/packetfu/protos/udp.rb', line 64

def initialize(args={})
  @eth_header = EthHeader.new(args).read(args[:eth])
  @ip_header = IPHeader.new(args).read(args[:ip])
  @ip_header.ip_proto=0x11
  @udp_header = UDPHeader.new(args).read(args[:icmp])
  @ip_header.body = @udp_header
  @eth_header.body = @ip_header
  @headers = [@eth_header, @ip_header, @udp_header]
  super
  udp_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


43
44
45
# File 'lib/packetfu/protos/udp.rb', line 43

def eth_header
  @eth_header
end

#ip_headerObject

Returns the value of attribute ip_header


43
44
45
# File 'lib/packetfu/protos/udp.rb', line 43

def ip_header
  @ip_header
end

#udp_headerObject

Returns the value of attribute udp_header


43
44
45
# File 'lib/packetfu/protos/udp.rb', line 43

def udp_header
  @udp_header
end

Class Method Details

.can_parse?(str) ⇒ Boolean

Returns:

  • (Boolean)

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

def self.can_parse?(str)
  return false unless str.size >= 28
  return false unless EthPacket.can_parse? str
  return false unless IPPacket.can_parse? str
  return false unless str[23,1] == "\x11"
  return true
end

Instance Method Details

#peek_formatObject

Peek provides summary data on packet contents.


128
129
130
131
132
133
134
135
136
137
# File 'lib/packetfu/protos/udp.rb', line 128

def peek_format
  peek_data = ["U  "]
  peek_data << "%-5d" % self.to_s.size
  peek_data << "%-21s" % "#{self.ip_saddr}:#{self.udp_sport}"
  peek_data << "->"
  peek_data << "%21s" % "#{self.ip_daddr}:#{self.udp_dport}"
  peek_data << "%23s" % "I:"
  peek_data << "%04x" % self.ip_id
  peek_data.join
end

#read(str = nil, args = {}) ⇒ Object


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

def read(str=nil, args={})
  raise "Cannot parse `#{str}'" unless self.class.can_parse?(str)
  @eth_header.read(str)
  if args[:strip]
    udp_body_len = self.ip_len - self.ip_hlen - 8
    @udp_header.body.read(@udp_header.body.to_s[0,udp_body_len])
  end
  super(args)
  self
end

#udp_calc_sumObject

udp_calc_sum() computes the UDP checksum, and is called upon intialization. It usually should be called just prior to dropping packets to a file or on the wire.


78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/packetfu/protos/udp.rb', line 78

def udp_calc_sum
  # This is /not/ delegated down to @udp_header since we need info
  # from the IP header, too.
  checksum = (ip_src.to_i >> 16)
  checksum += (ip_src.to_i & 0xffff)
  checksum += (ip_dst.to_i >> 16)
  checksum += (ip_dst.to_i & 0xffff)
  checksum += 0x11
  checksum += udp_len.to_i
  checksum += udp_src.to_i
  checksum += udp_dst.to_i
  checksum += udp_len.to_i
  if udp_len.to_i >= 8
    # For IP trailers. This isn't very reliable. :/
    real_udp_payload = payload.to_s[0,(udp_len.to_i-8)] 
  else
    # I'm not going to mess with this right now.
    real_udp_payload = payload 
  end
  chk_payload = (real_udp_payload.size % 2 == 0 ? real_udp_payload : real_udp_payload + "\x00")
  chk_payload.unpack("n*").each {|x| checksum = checksum+x}
  checksum = checksum % 0xffff
  checksum = 0xffff - checksum
  checksum == 0 ? 0xffff : checksum
  @udp_header.udp_sum = checksum
end

#udp_recalc(args = :all) ⇒ Object

udp_recalc() recalculates various fields of the UDP packet. Valid arguments are:

:all
  Recomputes all calculated fields.
:udp_sum
  Recomputes the UDP checksum.
:udp_len
  Recomputes the UDP length.

113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/packetfu/protos/udp.rb', line 113

def udp_recalc(args=:all)
  case args
  when :udp_len
    @udp_header.udp_recalc
  when :udp_sum
    udp_calc_sum
  when :all
    @udp_header.udp_recalc
    udp_calc_sum
  else
    raise ArgumentError, "No such field `#{arg}'"
  end
end