Class: PacketFu::IPHeader
- Includes:
- StructFu
- Defined in:
- lib/packetfu/protos/ip/header.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
Integer (4 bits) :ip_v, Default: 4
Integer (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: 64 # https://www.iana.org/assignments/ip-parameters/ip-parameters.xml
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.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/packetfu/protos/ip/header.rb', line 125 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] || 64), 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
120 121 122 |
# File 'lib/packetfu/protos/ip/header.rb', line 120 def body @body end |
#ip_dst ⇒ Object
Getter for the destination IP address.
120 121 122 |
# File 'lib/packetfu/protos/ip/header.rb', line 120 def ip_dst @ip_dst end |
#ip_frag ⇒ Object
Getter for the fragmentation ID.
120 121 122 |
# File 'lib/packetfu/protos/ip/header.rb', line 120 def ip_frag @ip_frag end |
#ip_hl ⇒ Object
Getter for the header length (multiply by 4)
120 121 122 |
# File 'lib/packetfu/protos/ip/header.rb', line 120 def ip_hl @ip_hl end |
#ip_id ⇒ Object
Getter for the identication number.
120 121 122 |
# File 'lib/packetfu/protos/ip/header.rb', line 120 def ip_id @ip_id end |
#ip_len ⇒ Object
Getter for total length.
120 121 122 |
# File 'lib/packetfu/protos/ip/header.rb', line 120 def ip_len @ip_len end |
#ip_proto ⇒ Object
Getter for the protocol number.
120 121 122 |
# File 'lib/packetfu/protos/ip/header.rb', line 120 def ip_proto @ip_proto end |
#ip_src ⇒ Object
Getter for the source IP address.
120 121 122 |
# File 'lib/packetfu/protos/ip/header.rb', line 120 def ip_src @ip_src end |
#ip_sum ⇒ Object
Getter for the checksum.
120 121 122 |
# File 'lib/packetfu/protos/ip/header.rb', line 120 def ip_sum @ip_sum end |
#ip_tos ⇒ Object
Getter for the differentiated services
120 121 122 |
# File 'lib/packetfu/protos/ip/header.rb', line 120 def ip_tos @ip_tos end |
#ip_ttl ⇒ Object
Getter for the time to live.
120 121 122 |
# File 'lib/packetfu/protos/ip/header.rb', line 120 def ip_ttl @ip_ttl end |
#ip_v ⇒ Object
Getter for the version.
120 121 122 |
# File 'lib/packetfu/protos/ip/header.rb', line 120 def ip_v @ip_v end |
Class Method Details
.octet_array(addr) ⇒ Object
Translate various formats of IPv4 Addresses to an array of digits.
286 287 288 289 290 291 292 293 294 295 296 |
# File 'lib/packetfu/protos/ip/header.rb', line 286 def self.octet_array(addr) if addr.class == String oa = addr.split('.').collect {|x| x.to_i} elsif addr.kind_of? Integer oa = IPAddr.new(addr, Socket::AF_INET).to_s.split('.') elsif addr.kind_of? 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
259 260 261 |
# File 'lib/packetfu/protos/ip/header.rb', line 259 def ip_calc_id @random_id end |
#ip_calc_len ⇒ Object
Calulcate the true length of the packet.
232 233 234 |
# File 'lib/packetfu/protos/ip/header.rb', line 232 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.)
243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/packetfu/protos/ip/header.rb', line 243 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.
281 282 283 |
# File 'lib/packetfu/protos/ip/header.rb', line 281 def ip_daddr self[:ip_dst].to_x end |
#ip_daddr=(addr) ⇒ Object
Sets a more readable IP address.
276 277 278 |
# File 'lib/packetfu/protos/ip/header.rb', line 276 def ip_daddr=(addr) self[:ip_dst].read_quad(addr) end |
#ip_hlen ⇒ Object
Return the claimed header length
237 238 239 |
# File 'lib/packetfu/protos/ip/header.rb', line 237 def ip_hlen (ip_hl * 4) end |
#ip_id_readable ⇒ Object
325 326 327 |
# File 'lib/packetfu/protos/ip/header.rb', line 325 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
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
# File 'lib/packetfu/protos/ip/header.rb', line 303 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.
271 272 273 |
# File 'lib/packetfu/protos/ip/header.rb', line 271 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.
266 267 268 |
# File 'lib/packetfu/protos/ip/header.rb', line 266 def ip_saddr=(addr) self[:ip_src].read_quad(addr) end |
#ip_sum_readable ⇒ Object
329 330 331 |
# File 'lib/packetfu/protos/ip/header.rb', line 329 def ip_sum_readable "0x%04x" % ip_sum end |
#read(str) ⇒ Object
Reads a string to populate the object.
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/packetfu/protos/ip/header.rb', line 150 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.
144 145 146 147 |
# File 'lib/packetfu/protos/ip/header.rb', line 144 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 |