Class: IP::Address::IPv4

Inherits:
IP::Address show all
Defined in:
lib/ip/address.rb

Overview

Support for IPv4

Instance Attribute Summary

Attributes inherited from IP::Address

#ip_address, #octets

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from IP::Address

#[]

Constructor Details

#initialize(ip_address) ⇒ IPv4

Constructs an IP::Address::IPv4 object.

This can take two types of input. Either a string that contains a dotted-quad formatted address, or an integer that contains the data. This integer is expected to be constructed in the way that IP::Address::Util.pack_ipv4 would generate such an integer.

This constructor will throw IP::AddressException on any parse errors.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/ip/address.rb', line 64

def initialize(ip_address)
  if ip_address.kind_of? Integer
    # unpack to generate a string, and parse that.
    # overwrites 'ip_address'
    # horribly inefficient, but general.

    raw = IP::Address::Util.raw_unpack(ip_address)[0..1]
    octets = []

    2.times do |x|
      octets.push(raw[x] & 0x00FF)
      octets.push((raw[x] & 0xFF00) >> 8)
    end

    ip_address = octets.reverse.join(".")
  end

  if ! ip_address.kind_of? String
    raise IP::AddressException.new("Fed IP address '#{ip_address}' is not String or Fixnum")
  end

  @ip_address = ip_address

  #
  # Unbeknowest by me, to_i will not throw an exception if the string
  # can't be converted cleanly - it just truncates, similar to atoi() and perl's int().
  #
  # Code below does a final sanity check.
  #

  octets = ip_address.split(/\./)
  octets_i = octets.collect { |x| x.to_i }

  0.upto(octets.length - 1) do |octet|
    if octets[octet] != octets_i[octet].to_s
      raise IP::AddressException.new("Integer conversion failed")
    end
  end

  @octets = octets_i

  # I made a design decision to allow 0.0.0.0 here.
  if @octets.length != 4 or @octets.find_all { |x| x > 255 }.length > 0
    raise IP::AddressException.new("IP address is improperly formed")
  end
end

Class Method Details

.parse(ip_address) ⇒ Object

Parses an IP address and stores it as the current address



49
50
51
# File 'lib/ip/address.rb', line 49

def IPv4.parse(ip_address)
  return IP::Address::IPv4.new(ip_address)
end

Instance Method Details

#==(other) ⇒ Object

An IP Address is equal if the ip address match



133
134
135
136
137
138
139
140
141
142
# File 'lib/ip/address.rb', line 133

def ==(other)
  case other
    when String,Integer,Bignum
      self.ip_address == self.class.new(other).ip_address
    when self.class
      self.ip_address == other.ip_address
    else
      false
  end
end

#packObject

Returns a 128-bit integer representing the address.



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/ip/address.rb', line 114

def pack
  # this routine does relatively little. all it does is ensure
  # that the IP address is of a certain size and has certain numeric limits.
  myip = self.octets
  packval = [0] * 6

  #
  # this ensures that the octets are 8 bit, and combines the octets in order to
  # form two 16-bit integers suitable for pushing into the last places in 'packval'
  #

  (0..3).step(2) { |x| packval.push(((myip[x] & 0xFF) << 8) | (myip[x+1] & 0xFF)) }

  return IP::Address::Util.raw_pack(packval)
end