class Scriptroute::IPv4
Constants
- IPPROTO_ICMP
Attributes
@return [IPaddress]
@return [Fixnum]
@return [Fixnum]
@return [Fixnum]
@return [Fixnum]
@return [Array<IPv4option>]
@return [Fixnum]
@return [IPaddress]
@return [Fixnum]
@return [Fixnum]
@return [Fixnum]
@return [Fixnum]
Public Class Methods
invoke a factory(?) to create a TCP/UDP/ICMP as appropriate, then unmarshal the IPv4
header contents. @param [String] str the bytes of the packet to unpack.
# File lib/scriptroute/packets.rb, line 355 def IPv4.creator(str) ip_vhl, ip_tos, ip_len, ip_id, ip_off, ip_ttl, ip_p, ip_sum, ip_src, ip_dst = str.unpack("ccn" + "nn" + "ccn" + "N" + "N"); ip_v = ((ip_vhl & 0xf0) >> 4) if(ip_v == 4) then ip_hl = ip_vhl & 0xf; if(@@creators[ip_p]) then pkt = (@@creators[ip_p]).call(str[(ip_hl * 4) .. ip_len]) pkt.ipv4_unmarshal(str) pkt else raise "unknown IPv4 protocol #%d in %s" % [ ip_p, str.unpack("C*").map { |c| "%x" % c }.join(' ') ] end elsif(ip_v == 6) then # probably should do this someplace above IPv4 creator. puts "received v6 packet %s" % [ str.unpack("H*") ] str else raise "unknown IP version #%d in %s" % [ ip_v, str.unpack("C*").map { |c| "%x" % c }.join(' ') ] end end
This method is probably only useful for calling from subclasses. @param p [Fixnum] the protocol, either Scriptroute::IPv4::IPPROTO_ICMP
, IPPROTO_TCP, or IPPROTO_UDP
# File lib/scriptroute/packets.rb, line 331 def initialize(p) if(p.is_a?(Fixnum)) then @ip_v = 4 @ip_tos = 0 @ip_id = 11 @ip_off = 0 @ip_ttl = 64 @ip_p = p @ip_sum = 0 @ip_src = 0 @ip_dst = 0 @ip_options = Array.new calculate_packet_len else raise "need a protocol number to instantiate an ipv4 packet" end end
Public Instance Methods
@param opt [IPv4option] add a record route or timestamp option. @return [void]
# File lib/scriptroute/packets.rb, line 324 def add_option(opt) opt.is_a?(IPv4option) or raise "can add only IPv4options" @ip_options.push(opt) calculate_header_len end
sets ip_hl
, should not be necessary to call this explicitly. @return [void]
# File lib/scriptroute/packets.rb, line 313 def calculate_header_len @ip_hl = [ 5 + ((ip_options.map { |o| o.ipt_len }.sum)/4.0).ceil, 15 ].min # at most 15 end
@return [void]
# File lib/scriptroute/packets.rb, line 317 def calculate_packet_len calculate_header_len # ensures @ip_hl is set properly raise "ip_payload_len not calculated" unless ip_payload_len @ip_len = ip_payload_len + (@ip_hl * 4) end
@param [String,IPaddress] destination_address the destination of this packet.
# File lib/scriptroute/packets.rb, line 292 def ip_dst=(destination_address) @ip_dst = IPaddress.new(destination_address) end
@return [Fixnum] the length of the payload, intended to be implemented by subclasses. @raise [RuntimeError] if invoked directly instead of being overloaded.
# File lib/scriptroute/packets.rb, line 308 def ip_payload_len raise "ip_payload_len is a pure virtual function in IPv4" end
unpack the ipv4 component of the packet, even if we’re unmarshaling an instance of a subclass. @param [String] str The string from which to unpack. @return [void]
# File lib/scriptroute/packets.rb, line 383 def ipv4_unmarshal(str) ip_vhl, @ip_tos, @ip_len, @ip_id, @ip_off, @ip_ttl, @ip_p, @ip_sum, ip_src, ip_dst = str.unpack("CCn" + "nn" + "CCn" + "N" + "N"); @ip_src, @ip_dst = [ip_src, ip_dst].map { |addr| IPaddress.new(addr) } @ip_hl = ip_vhl & 0xf; @ip_v = (ip_vhl & 0xf0) >> 4; @ip_options = Array.new if(@ip_hl > 5) then add_option(IPv4option.creator(str[20 .. (@ip_hl*4)])) end end
@return [String]
# File lib/scriptroute/packets.rb, line 398 def to_s "%s > %s ttl%d" % [ @ip_src, @ip_dst, @ip_ttl ] + @ip_options.map { |o| o.to_s }.join(", ") end
Private Instance Methods
@return [String] The packet in string form
# File lib/scriptroute/packets.rb, line 297 def marshal calculate_packet_len [ (@ip_v << 4) + @ip_hl, @ip_tos, @ip_len, @ip_id, @ip_off, @ip_ttl, @ip_p, @ip_sum, @ip_src.to_i, @ip_dst.to_i ].pack("ccn" + "nn" + "ccn" + "N" + "N") + @ip_options.map { |o| o.marshal }.join end