Class: PacketFu::UDPPacket
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
-
#eth_header ⇒ Object
Returns the value of attribute eth_header.
-
#ip_header ⇒ Object
Returns the value of attribute ip_header.
-
#udp_header ⇒ Object
Returns the value of attribute udp_header.
Attributes inherited from Packet
#flavor, #headers, #iface, #inspect_style
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(args = {}) ⇒ UDPPacket
constructor
A new instance of UDPPacket.
-
#peek_format ⇒ Object
Peek provides summary data on packet contents.
- #read(str = nil, args = {}) ⇒ Object
-
#udp_calc_sum ⇒ Object
udp_calc_sum() computes the UDP checksum, and is called upon intialization.
-
#udp_recalc(args = :all) ⇒ Object
udp_recalc() recalculates various fields of the UDP packet.
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.
161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/packetfu/protos/udp.rb', line 161 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_header ⇒ Object
Returns the value of attribute eth_header.
135 136 137 |
# File 'lib/packetfu/protos/udp.rb', line 135 def eth_header @eth_header end |
#ip_header ⇒ Object
Returns the value of attribute ip_header.
135 136 137 |
# File 'lib/packetfu/protos/udp.rb', line 135 def ip_header @ip_header end |
#udp_header ⇒ Object
Returns the value of attribute udp_header.
135 136 137 |
# File 'lib/packetfu/protos/udp.rb', line 135 def udp_header @udp_header end |
Class Method Details
.can_parse?(str) ⇒ Boolean
137 138 139 140 141 142 143 |
# File 'lib/packetfu/protos/udp.rb', line 137 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_format ⇒ Object
Peek provides summary data on packet contents.
225 226 227 228 229 230 231 232 233 234 |
# File 'lib/packetfu/protos/udp.rb', line 225 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
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/packetfu/protos/udp.rb', line 145 def read(str=nil, args={}) raise "Cannot parse `#{str}'" unless self.class.can_parse?(str) @eth_header.read(str) @ip_header.read(str[14,str.size]) @eth_header.body = @ip_header if args[:strip] udp_len = str[16,2].unpack("n")[0] - 20 @udp_header.read(str[14+(@ip_header.ip_hlen),udp_len]) else @udp_header.read(str[14+(@ip_header.ip_hlen),str.size]) end @ip_header.body = @udp_header super(args) self end |
#udp_calc_sum ⇒ Object
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.
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/packetfu/protos/udp.rb', line 175 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.
210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/packetfu/protos/udp.rb', line 210 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 |