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.

Methods
I
N
O
R
T
Included Modules
Class Public methods
new(args={})
# 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
octet_array(addr)

Translate various formats of IPv4 Addresses to an array of digits.

# 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 Public methods
ip_calc_id()

Retrieve the IP ID

# File lib/packetfu/protos/ip.rb, line 219
                def ip_calc_id
                        @random_id
                end
ip_calc_len()

Calulcate the true length of the packet.

# File lib/packetfu/protos/ip.rb, line 192
                def ip_calc_len
                        (ip_hl * 4) + body.to_s.length
                end
ip_calc_sum()

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.)

# 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()

Returns a more readable IP destination address.

This method is also aliased as ip_dst_readable
# File lib/packetfu/protos/ip.rb, line 241
                def ip_daddr
                        self[:ip_dst].to_x
                end
ip_daddr=(addr)

Sets a more readable IP address.

# File lib/packetfu/protos/ip.rb, line 236
                def ip_daddr=(addr)
                        self[:ip_dst].read_quad(addr)
                end
ip_dst()

Getter for the destination IP address.

# File lib/packetfu/protos/ip.rb, line 189
                def ip_dst; self[:ip_dst].to_i; end
ip_dst=(i)

Setter for the destination IP address.

# File lib/packetfu/protos/ip.rb, line 178
                def ip_dst=(i)
                        case i
                        when Numeric
                                self[:ip_dst] = Octets.new.read([i].pack("N"))
                        when Octets
                                self[:ip_dst] = i
                        else
                                typecast i
                        end
                end
ip_dst_readable()

Alias for ip_daddr

ip_frag()

Getter for the fragmentation ID.

# File lib/packetfu/protos/ip.rb, line 151
                def ip_frag; self[:ip_frag].to_i; end
ip_frag=(i)

Setter for the fragmentation ID.

# File lib/packetfu/protos/ip.rb, line 149
                def ip_frag=(i); typecast i; end
ip_hl()

Getter for the header length (multiply by 4)

# File lib/packetfu/protos/ip.rb, line 135
                def ip_hl; self[:ip_hl].to_i; end
ip_hl=(i)

Setter for the header length (divide by 4)

# File lib/packetfu/protos/ip.rb, line 133
                def ip_hl=(i); self[:ip_hl] = i.to_i; end
ip_hlen()

Return the claimed header length

# File lib/packetfu/protos/ip.rb, line 197
                def ip_hlen
                        (ip_hl * 4)
                end
ip_id()

Getter for the identication number.

# File lib/packetfu/protos/ip.rb, line 147
                def ip_id; self[:ip_id].to_i; end
ip_id=(i)

Setter for the identication number.

# File lib/packetfu/protos/ip.rb, line 145
                def ip_id=(i); typecast i; end
ip_id_readable()
# File lib/packetfu/protos/ip.rb, line 287
                def ip_id_readable
                        "0x%04x" % ip_id
                end
ip_len()

Getter for total length.

# File lib/packetfu/protos/ip.rb, line 143
                def ip_len; self[:ip_len].to_i; end
ip_len=(i)

Setter for total length.

# File lib/packetfu/protos/ip.rb, line 141
                def ip_len=(i); typecast i; end
ip_proto()

Getter for the protocol number.

# File lib/packetfu/protos/ip.rb, line 159
                def ip_proto; self[:ip_proto].to_i; end
ip_proto=(i)

Setter for the protocol number.

# File lib/packetfu/protos/ip.rb, line 157
                def ip_proto=(i); typecast i; end
ip_recalc(arg=:all)

Recalculate the calculated IP fields. Valid arguments are:

  :all
  :ip_len
  :ip_sum
  :ip_id
# 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()

Returns a more readable IP source address.

This method is also aliased as ip_src_readable
# File lib/packetfu/protos/ip.rb, line 231
                def ip_saddr
                        self[:ip_src].to_x
                end
ip_saddr=(addr)

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.

# File lib/packetfu/protos/ip.rb, line 226
                def ip_saddr=(addr)
                        self[:ip_src].read_quad(addr)
                end
ip_src()

Getter for the source IP address.

# File lib/packetfu/protos/ip.rb, line 176
                def ip_src; self[:ip_src].to_i; end
ip_src=(i)

Setter for the source IP address.

# File lib/packetfu/protos/ip.rb, line 165
                def ip_src=(i)
                        case i
                        when Numeric
                                self[:ip_src] = Octets.new.read([i].pack("N"))
                        when Octets
                                self[:ip_src] = i
                        else
                                typecast i
                        end
                end
ip_src_readable()

Alias for ip_saddr

ip_sum()

Getter for the checksum.

# File lib/packetfu/protos/ip.rb, line 163
                def ip_sum; self[:ip_sum].to_i; end
ip_sum=(i)

Setter for the checksum.

# File lib/packetfu/protos/ip.rb, line 161
                def ip_sum=(i); typecast i; end
ip_sum_readable()
# File lib/packetfu/protos/ip.rb, line 291
                def ip_sum_readable
                        "0x%04x" % ip_sum
                end
ip_tos()

Getter for the differentiated services

# File lib/packetfu/protos/ip.rb, line 139
                def ip_tos; self[:ip_tos].to_i; end
ip_tos=(i)

Setter for the differentiated services

# File lib/packetfu/protos/ip.rb, line 137
                def ip_tos=(i); typecast i; end
ip_ttl()

Getter for the time to live.

# File lib/packetfu/protos/ip.rb, line 155
                def ip_ttl; self[:ip_ttl].to_i; end
ip_ttl=(i)

Setter for the time to live.

# File lib/packetfu/protos/ip.rb, line 153
                def ip_ttl=(i); typecast i; end
ip_v()

Getter for the version.

# File lib/packetfu/protos/ip.rb, line 131
                def ip_v; self[:ip_v].to_i; end
ip_v=(i)

Setter for the version.

# File lib/packetfu/protos/ip.rb, line 129
                def ip_v=(i); self[:ip_v] = i.to_i; end
read(str)

Reads a string to populate the object.

# 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()

Returns the object in string form.

# 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