Class: PacketFu::IPHeader
- Includes:
- StructFu
- Defined in:
- lib/packetfu/protos/ip.rb
Overview
IPHeader is a complete IP struct, used in IPPacket. Most traffic on most networks today is IP-based.
For more on IP packets, see www.networksorcery.com/enp/protocol/ip.htm
Header Definition
Fixnum (4 bits) :ip_v, Default: 4
Fixnum (4 bits) :ip_hl, Default: 5
Int8 :ip_tos, Default: 0 # TODO: Break out the bits
Int16 :ip_len, Default: calculated
Int16 :ip_id, Default: calculated # IRL, hardly random.
Int16 :ip_frag, Default: 0 # TODO: Break out the bits
Int8 :ip_ttl, Default: 0xff # Changes per flavor
Int8 :ip_proto, Default: 0x01 # TCP: 0x06, UDP 0x11, ICMP 0x01
Int16 :ip_sum, Default: calculated
Octets :ip_src
Octets :ip_dst
String :body
Note that IPPackets will always be somewhat incorrect upon initalization, and want an IPHeader#recalc() to become correct before a Packet#to_f or Packet#to_w.
Instance Attribute Summary collapse
-
#body ⇒ Object
Returns the value of attribute body.
-
#ip_dst ⇒ Object
Getter for the destination IP address.
-
#ip_frag ⇒ Object
Getter for the fragmentation ID.
-
#ip_hl ⇒ Object
Getter for the header length (multiply by 4).
-
#ip_id ⇒ Object
Getter for the identication number.
-
#ip_len ⇒ Object
Getter for total length.
-
#ip_proto ⇒ Object
Getter for the protocol number.
-
#ip_src ⇒ Object
Getter for the source IP address.
-
#ip_sum ⇒ Object
Getter for the checksum.
-
#ip_tos ⇒ Object
Getter for the differentiated services.
-
#ip_ttl ⇒ Object
Getter for the time to live.
-
#ip_v ⇒ Object
Getter for the version.
Class Method Summary collapse
-
.octet_array(addr) ⇒ Object
Translate various formats of IPv4 Addresses to an array of digits.
Instance Method Summary collapse
-
#initialize(args = {}) ⇒ IPHeader
constructor
A new instance of IPHeader.
-
#ip_calc_id ⇒ Object
Retrieve the IP ID.
-
#ip_calc_len ⇒ Object
Calulcate the true length of the packet.
-
#ip_calc_sum ⇒ Object
Calculate the true checksum of the packet.
-
#ip_daddr ⇒ Object
(also: #ip_dst_readable)
Returns a more readable IP destination address.
-
#ip_daddr=(addr) ⇒ Object
Sets a more readable IP address.
-
#ip_hlen ⇒ Object
Return the claimed header length.
- #ip_id_readable ⇒ Object
-
#ip_recalc(arg = :all) ⇒ Object
Recalculate the calculated IP fields.
-
#ip_saddr ⇒ Object
(also: #ip_src_readable)
Returns a more readable IP source address.
-
#ip_saddr=(addr) ⇒ Object
Sets a more readable IP address.
- #ip_sum_readable ⇒ Object
-
#read(str) ⇒ Object
Reads a string to populate the object.
-
#to_s ⇒ Object
Returns the object in string form.
Methods included from StructFu
#clone, #set_endianness, #sz, #typecast
Methods inherited from Struct
Constructor Details
#initialize(args = {}) ⇒ IPHeader
Returns a new instance of IPHeader.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/packetfu/protos/ip.rb', line 85 def initialize(args={}) @random_id = rand(0xffff) super( (args[:ip_v] || 4), (args[:ip_hl] || 5), Int8.new(args[:ip_tos]), Int16.new(args[:ip_len] || 20), Int16.new(args[:ip_id] || ip_calc_id), Int16.new(args[:ip_frag]), Int8.new(args[:ip_ttl] || 32), Int8.new(args[:ip_proto]), Int16.new(args[:ip_sum] || ip_calc_sum), Octets.new.read(args[:ip_src] || "\x00\x00\x00\x00"), Octets.new.read(args[:ip_dst] || "\x00\x00\x00\x00"), StructFu::String.new.read(args[:body]) ) end |
Instance Attribute Details
#body ⇒ Object
Returns the value of attribute body
80 81 82 |
# File 'lib/packetfu/protos/ip.rb', line 80 def body @body end |
#ip_dst ⇒ Object
Getter for the destination IP address.
80 81 82 |
# File 'lib/packetfu/protos/ip.rb', line 80 def ip_dst @ip_dst end |
#ip_frag ⇒ Object
Getter for the fragmentation ID.
80 81 82 |
# File 'lib/packetfu/protos/ip.rb', line 80 def ip_frag @ip_frag end |
#ip_hl ⇒ Object
Getter for the header length (multiply by 4)
80 81 82 |
# File 'lib/packetfu/protos/ip.rb', line 80 def ip_hl @ip_hl end |
#ip_id ⇒ Object
Getter for the identication number.
80 81 82 |
# File 'lib/packetfu/protos/ip.rb', line 80 def ip_id @ip_id end |
#ip_len ⇒ Object
Getter for total length.
80 81 82 |
# File 'lib/packetfu/protos/ip.rb', line 80 def ip_len @ip_len end |
#ip_proto ⇒ Object
Getter for the protocol number.
80 81 82 |
# File 'lib/packetfu/protos/ip.rb', line 80 def ip_proto @ip_proto end |
#ip_src ⇒ Object
Getter for the source IP address.
80 81 82 |
# File 'lib/packetfu/protos/ip.rb', line 80 def ip_src @ip_src end |
#ip_sum ⇒ Object
Getter for the checksum.
80 81 82 |
# File 'lib/packetfu/protos/ip.rb', line 80 def ip_sum @ip_sum end |
#ip_tos ⇒ Object
Getter for the differentiated services
80 81 82 |
# File 'lib/packetfu/protos/ip.rb', line 80 def ip_tos @ip_tos end |
#ip_ttl ⇒ Object
Getter for the time to live.
80 81 82 |
# File 'lib/packetfu/protos/ip.rb', line 80 def ip_ttl @ip_ttl end |
#ip_v ⇒ Object
Getter for the version.
80 81 82 |
# File 'lib/packetfu/protos/ip.rb', line 80 def ip_v @ip_v end |
Class Method Details
.octet_array(addr) ⇒ Object
Translate various formats of IPv4 Addresses to an array of digits.
246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/packetfu/protos/ip.rb', line 246 def self.octet_array(addr) if addr.class == String oa = addr.split('.').collect {|x| x.to_i} elsif addr.class == Fixnum oa = IPAddr.new(addr, Socket::AF_INET).to_s.split('.') elsif addr.class == Bignum oa = IPAddr.new(addr, Socket::AF_INET).to_s.split('.') elsif addr.class == Array oa = addr else raise ArgumentError, "IP Address should be a dotted quad string, an array of ints, or a bignum" end end |
Instance Method Details
#ip_calc_id ⇒ Object
Retrieve the IP ID
219 220 221 |
# File 'lib/packetfu/protos/ip.rb', line 219 def ip_calc_id @random_id end |
#ip_calc_len ⇒ Object
Calulcate the true length of the packet.
192 193 194 |
# File 'lib/packetfu/protos/ip.rb', line 192 def ip_calc_len (ip_hl * 4) + body.to_s.length end |
#ip_calc_sum ⇒ Object
Calculate the true checksum of the packet. (Yes, this is the long way to do it, but it’s e-z-2-read for mathtards like me.)
203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/packetfu/protos/ip.rb', line 203 def ip_calc_sum checksum = (((self.ip_v << 4) + self.ip_hl) << 8) + self.ip_tos checksum += self.ip_len checksum += self.ip_id checksum += self.ip_frag checksum += (self.ip_ttl << 8) + self.ip_proto checksum += (self.ip_src >> 16) checksum += (self.ip_src & 0xffff) checksum += (self.ip_dst >> 16) checksum += (self.ip_dst & 0xffff) checksum = checksum % 0xffff checksum = 0xffff - checksum checksum == 0 ? 0xffff : checksum end |
#ip_daddr ⇒ Object Also known as: ip_dst_readable
Returns a more readable IP destination address.
241 242 243 |
# File 'lib/packetfu/protos/ip.rb', line 241 def ip_daddr self[:ip_dst].to_x end |
#ip_daddr=(addr) ⇒ Object
Sets a more readable IP address.
236 237 238 |
# File 'lib/packetfu/protos/ip.rb', line 236 def ip_daddr=(addr) self[:ip_dst].read_quad(addr) end |
#ip_hlen ⇒ Object
Return the claimed header length
197 198 199 |
# File 'lib/packetfu/protos/ip.rb', line 197 def ip_hlen (ip_hl * 4) end |
#ip_id_readable ⇒ Object
287 288 289 |
# File 'lib/packetfu/protos/ip.rb', line 287 def ip_id_readable "0x%04x" % ip_id end |
#ip_recalc(arg = :all) ⇒ Object
Recalculate the calculated IP fields. Valid arguments are:
:all
:ip_len
:ip_sum
:ip_id
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/packetfu/protos/ip.rb', line 265 def ip_recalc(arg=:all) case arg when :ip_len self.ip_len=ip_calc_len when :ip_sum self.ip_sum=ip_calc_sum when :ip_id @random_id = rand(0xffff) when :all self.ip_id= ip_calc_id self.ip_len= ip_calc_len self.ip_sum= ip_calc_sum else raise ArgumentError, "No such field `#{arg}'" end end |
#ip_saddr ⇒ Object Also known as: ip_src_readable
Returns a more readable IP source address.
231 232 233 |
# File 'lib/packetfu/protos/ip.rb', line 231 def ip_saddr self[:ip_src].to_x end |
#ip_saddr=(addr) ⇒ Object
Sets a more readable IP address. If you wants to manipulate individual octets, (eg, for host scanning in one network), it would be better use ip_src.o1 through ip_src.o4 instead.
226 227 228 |
# File 'lib/packetfu/protos/ip.rb', line 226 def ip_saddr=(addr) self[:ip_src].read_quad(addr) end |
#ip_sum_readable ⇒ Object
291 292 293 |
# File 'lib/packetfu/protos/ip.rb', line 291 def ip_sum_readable "0x%04x" % ip_sum end |
#read(str) ⇒ Object
Reads a string to populate the object.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/packetfu/protos/ip.rb', line 110 def read(str) force_binary(str) return self if str.nil? self[:ip_v] = str[0,1].unpack("C").first >> 4 self[:ip_hl] = str[0,1].unpack("C").first.to_i & 0x0f self[:ip_tos].read(str[1,1]) self[:ip_len].read(str[2,2]) self[:ip_id].read(str[4,2]) self[:ip_frag].read(str[6,2]) self[:ip_ttl].read(str[8,1]) self[:ip_proto].read(str[9,1]) self[:ip_sum].read(str[10,2]) self[:ip_src].read(str[12,4]) self[:ip_dst].read(str[16,4]) self[:body].read(str[20,str.size]) if str.size > 20 self end |
#to_s ⇒ Object
Returns the object in string form.
104 105 106 107 |
# File 'lib/packetfu/protos/ip.rb', line 104 def to_s byte_v_hl = [(self.ip_v << 4) + self.ip_hl].pack("C") byte_v_hl + (self.to_a[2,10].map {|x| x.to_s}.join) end |