ipadmin 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +143 -99
- data/lib/ip_admin.rb +555 -86
- data/tests/cidr_table_test.rb +29 -1
- data/tests/cidr_test.rb +5 -2
- data/tests/dns_test.rb +68 -0
- data/tests/functions_test.rb +28 -1
- data/tests/ipaddr_test.rb +7 -4
- metadata +3 -2
data/README
CHANGED
@@ -15,106 +15,140 @@
|
|
15
15
|
=Examples:
|
16
16
|
|
17
17
|
|
18
|
+
#!/usr/bin/ruby
|
19
|
+
|
18
20
|
require 'rubygems'
|
19
21
|
require_gem 'ipadmin'
|
20
|
-
|
21
|
-
|
22
|
+
|
22
23
|
#============================================================================#
|
23
24
|
# IPAdmin::IPAddr
|
24
25
|
#============================================================================#
|
25
26
|
puts "IPAdmin::IPAddr"
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
exit
|
36
|
-
end
|
37
|
-
|
27
|
+
|
28
|
+
# new
|
29
|
+
ip4 = IPAdmin::IPAddr.new(:IPAddr => '192.168.1.1/24')
|
30
|
+
ip4 = IPAdmin::IPAddr.new(:IPAddr => '192.168.1.1',
|
31
|
+
:Netmask => '255.255.255.0',
|
32
|
+
:Tag => {'test' => 'ip4 tag'})
|
33
|
+
ip6 = IPAdmin::IPAddr.new(:IPAddr => 'fec0::1/64')
|
34
|
+
|
35
|
+
# reader/writer
|
38
36
|
puts ip4.tag['test']
|
39
37
|
ip4.tag['test'] = 'modified ip4 tag'
|
40
38
|
puts ip4.tag['test']
|
41
|
-
|
42
|
-
puts "base addr #{ip4.base()}"
|
43
|
-
puts "base addr #{ip6.base()}"
|
44
39
|
|
45
|
-
|
40
|
+
# base
|
41
|
+
puts "ip4 base addr #{ip4.base()}"
|
42
|
+
puts "ip6 base addr #{ip6.base()}"
|
46
43
|
|
47
|
-
|
48
|
-
puts "
|
44
|
+
# broadcast
|
45
|
+
puts "ip4 bcast addr #{ip4.broadcast()}"
|
49
46
|
|
50
|
-
|
51
|
-
puts "
|
47
|
+
# desc
|
48
|
+
puts "ip4 description #{ip4.desc()}"
|
49
|
+
puts "ip6 description #{ip6.desc()}"
|
52
50
|
|
53
|
-
|
54
|
-
puts "
|
51
|
+
# extended masks
|
52
|
+
puts "ip4 extended hostmask #{ip4.hostmask_ext()}"
|
53
|
+
puts "ip6 extended netmask #{ip4.netmask_ext()}"
|
55
54
|
|
56
|
-
|
57
|
-
puts "
|
55
|
+
# ip
|
56
|
+
puts "ip4 ip addr #{ip4.ip()}"
|
57
|
+
puts "ip6 ip addr #{ip6.ip()}"
|
58
|
+
|
59
|
+
# netmask
|
60
|
+
puts "ip4 netmask in CIDR format #{ip4.netmask()}"
|
61
|
+
puts "ip6 netmask in CIDR format #{ip6.netmask()}"
|
62
|
+
|
63
|
+
# bits
|
64
|
+
puts "ip4 netmask in bits #{ip4.bits()}"
|
65
|
+
puts "ip6 netmask in bits #{ip6.bits()}"
|
58
66
|
|
59
67
|
print "\n\n\n"
|
60
68
|
#=====================================#
|
61
|
-
#
|
69
|
+
#
|
62
70
|
#=====================================#
|
63
71
|
|
64
|
-
|
65
72
|
#============================================================================#
|
66
73
|
# IPAdmin::CIDR
|
67
74
|
#============================================================================#
|
68
75
|
puts "IPAdmin::CIDR"
|
69
76
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
exit
|
79
|
-
end
|
80
|
-
|
77
|
+
# new
|
78
|
+
cidr4 = IPAdmin::CIDR.new(:CIDR => '192.168.1.0/24')
|
79
|
+
cidr4 = IPAdmin::CIDR.new(:CIDR => '192.168.1.0',
|
80
|
+
:Netmask => '255.255.255.0',
|
81
|
+
:Tag => {'test' => 'cidr4 tag'})
|
82
|
+
cidr6 = IPAdmin::CIDR.new(:CIDR => 'fec0::0/64')
|
83
|
+
|
84
|
+
# attr reader/writer
|
81
85
|
puts cidr4.tag['test']
|
82
86
|
cidr4.tag['test'] = 'modified cidr4 tag'
|
83
87
|
puts cidr4.tag['test']
|
84
88
|
|
85
|
-
|
86
|
-
puts "
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
puts "
|
92
|
-
|
93
|
-
|
94
|
-
puts "
|
95
|
-
puts "
|
96
|
-
|
97
|
-
|
98
|
-
puts "
|
99
|
-
|
100
|
-
puts "1st ip is #{cidr4.nth(:Index => 1)}"
|
101
|
-
puts "1st ip is #{(cidr6.nth(:Index => 1, :Objectify => 1)).desc}"
|
89
|
+
# contains
|
90
|
+
puts "#{cidr4.desc} contains #{ip4.desc}" if ( cidr4.contains(ip4) )
|
91
|
+
puts "#{cidr6.desc} contains #{ip6.desc}" if ( cidr6.contains(ip6) )
|
92
|
+
|
93
|
+
# desc
|
94
|
+
puts "cidr4 description #{cidr4.desc()}"
|
95
|
+
puts "cidr6 description #{cidr6.desc()}"
|
96
|
+
|
97
|
+
# extended masks
|
98
|
+
puts "cidr4 extended hostmask #{cidr4.hostmask_ext()}"
|
99
|
+
puts "cidr4 extended netmask #{cidr4.netmask_ext()}"
|
100
|
+
|
101
|
+
# netmask
|
102
|
+
puts "cidr4 netmask in CIDR format #{cidr4.netmask()}"
|
103
|
+
puts "cidr6 netmask in CIDR format #{cidr6.netmask()}"
|
102
104
|
|
105
|
+
# bits
|
106
|
+
puts "cidr4 netmask in bits #{cidr4.bits()}"
|
107
|
+
puts "cidr6 netmask in bits #{cidr6.bits()}"
|
108
|
+
|
109
|
+
# network
|
110
|
+
puts "cidr4 network address #{cidr4.network()}"
|
111
|
+
puts "cidr6 network address #{cidr6.network()}"
|
112
|
+
|
113
|
+
# nth
|
114
|
+
puts "cidr4 1st ip is #{cidr4.nth(:Index => 1)}"
|
115
|
+
puts "cidr6 1st ip is #{(cidr6.nth(:Index => 1, :Objectify => 1)).desc}"
|
116
|
+
|
117
|
+
# size
|
103
118
|
puts "cidr4 size is #{cidr4.size()}"
|
104
119
|
puts "cidr6 size is #{cidr6.size()}"
|
120
|
+
|
121
|
+
# enumerate
|
122
|
+
puts "first 4 cidr4 addresses (bitstep 32)"
|
123
|
+
list4 = cidr4.enumerate(:Limit => 4, :Bitstep => 32)
|
124
|
+
list4.each do |addr|
|
125
|
+
puts " #{addr}"
|
126
|
+
end
|
105
127
|
|
106
|
-
|
107
|
-
cidr6.enumerate(:Limit => 4, :Bitstep => 32, :Objectify => 1)
|
128
|
+
puts "first 4 cidr6 addresses (bitstep 32)"
|
129
|
+
list6 = cidr6.enumerate(:Limit => 4, :Bitstep => 32, :Objectify => 1)
|
130
|
+
list6.each do |addr|
|
131
|
+
puts " #{addr.desc}"
|
132
|
+
end
|
108
133
|
|
109
|
-
|
110
|
-
|
134
|
+
# subnet
|
135
|
+
puts "cidr4 subnetted into at least 3 /28 ranges"
|
136
|
+
sn4 = cidr4.subnet(:Subnet => 28, :MinCount => 3)
|
137
|
+
sn4.each do |cidr|
|
138
|
+
puts " #{cidr.desc()}"
|
139
|
+
end
|
111
140
|
|
112
|
-
|
141
|
+
puts "cidr6 subnetted into at least 4 /66 ranges"
|
142
|
+
sn6 = cidr6.subnet(:Subnet => 66, :MinCount => 4)
|
143
|
+
sn6.each do |cidr|
|
144
|
+
puts " #{cidr.desc()}"
|
145
|
+
end
|
146
|
+
|
147
|
+
print "\n\n\n"
|
113
148
|
#=====================================#
|
114
|
-
#
|
149
|
+
#
|
115
150
|
#=====================================#
|
116
151
|
|
117
|
-
|
118
152
|
#============================================================================#
|
119
153
|
# IPAdmin::CIDRTable
|
120
154
|
#============================================================================#
|
@@ -127,20 +161,17 @@
|
|
127
161
|
cidr4_5 = IPAdmin::CIDR.new(:CIDR => '192.168.1.64/26')
|
128
162
|
cidr4_6 = IPAdmin::CIDR.new(:CIDR => '192.168.1.128/26')
|
129
163
|
cidr4_7 = IPAdmin::CIDR.new(:CIDR => '192.168.1.192/26')
|
130
|
-
|
164
|
+
|
131
165
|
cidr6_1 = IPAdmin::CIDR.new(:CIDR => 'fec0::/10')
|
132
166
|
cidr6_2 = IPAdmin::CIDR.new(:CIDR => 'fe80::/10')
|
133
167
|
cidr6_3 = IPAdmin::CIDR.new(:CIDR => 'fec0::/64')
|
134
168
|
cidr6_4 =IPAdmin::CIDR.new(:CIDR => 'fec0::/126')
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
exit
|
142
|
-
end
|
143
|
-
|
169
|
+
|
170
|
+
# new
|
171
|
+
table4 = IPAdmin::CIDRTable.new(4)
|
172
|
+
table6 = IPAdmin::CIDRTable.new(6)
|
173
|
+
|
174
|
+
# add_cidr
|
144
175
|
table4.add_cidr(cidr4_1)
|
145
176
|
table4.add_cidr(cidr4_2)
|
146
177
|
table4.add_cidr(cidr4_3)
|
@@ -148,92 +179,105 @@
|
|
148
179
|
table4.add_cidr(cidr4_5)
|
149
180
|
table4.add_cidr(cidr4_6)
|
150
181
|
table4.add_cidr(cidr4_7)
|
151
|
-
|
182
|
+
|
152
183
|
table6.add_cidr(cidr6_1)
|
153
184
|
table6.add_cidr(cidr6_2)
|
154
185
|
table6.add_cidr(cidr6_3)
|
155
186
|
table6.add_cidr(cidr6_4)
|
156
187
|
|
157
|
-
|
158
|
-
puts "
|
159
|
-
|
188
|
+
# find_ip
|
189
|
+
puts "#{ip4.desc} belongs in #{table4.find_ip(ip4).desc}"
|
190
|
+
puts "#{ip6.desc} belongs in #{table6.find_ip(ip6).desc}"
|
191
|
+
|
192
|
+
# find_space
|
160
193
|
puts "all blocks that can hold a /27"
|
161
194
|
list4 = table4.find_space(:Size => 27)
|
162
195
|
list4.each do |cidr|
|
163
196
|
puts " #{cidr.desc()}"
|
164
197
|
end
|
165
|
-
|
198
|
+
|
166
199
|
puts "first block that can hold a /64"
|
167
200
|
list6 = table6.find_space(:Size => 64, :Limit => 1)
|
168
201
|
list6.each do |cidr|
|
169
202
|
puts " #{cidr.desc()}"
|
170
203
|
end
|
171
|
-
|
172
|
-
|
204
|
+
|
205
|
+
# dump
|
173
206
|
puts 'dump table4...'
|
174
|
-
dump4 = table4.dump
|
207
|
+
dump4 = table4.dump
|
175
208
|
dump4.each do |cidr|
|
176
209
|
puts " #{cidr.desc}"
|
177
210
|
end
|
178
211
|
puts 'dump table6...'
|
179
|
-
dump6 = table6.dump
|
212
|
+
dump6 = table6.dump
|
180
213
|
dump6.each do |cidr|
|
181
214
|
puts " #{cidr.desc}"
|
182
215
|
end
|
216
|
+
|
217
|
+
puts "remove 192.168.1.0/26 from table4"
|
218
|
+
table4.rem_cidr(cidr4_3)
|
219
|
+
dump4 = table4.dump
|
220
|
+
dump4.each do |cidr|
|
221
|
+
puts " #{cidr.desc}"
|
222
|
+
end
|
183
223
|
|
184
224
|
print "\n\n\n"
|
185
225
|
#=====================================#
|
186
|
-
#
|
226
|
+
#
|
187
227
|
#=====================================#
|
188
228
|
|
189
|
-
|
190
229
|
#============================================================================#
|
191
|
-
# IPAdmin
|
230
|
+
# IPAdmin Methods
|
192
231
|
#============================================================================#
|
193
|
-
puts "
|
232
|
+
puts "IPAdmin Methods"
|
194
233
|
|
234
|
+
# validate ip
|
195
235
|
puts "192.168.1.0 is valid" if ( IPAdmin.validate_ipv4_addr('192.168.1.0') )
|
196
236
|
puts "192.168.1.0 is valid" if ( IPAdmin.validate_ipv6_addr('fec0::0') )
|
197
|
-
|
237
|
+
|
238
|
+
# validate netmask
|
198
239
|
puts "255.255.255.0 is valid" if (IPAdmin.validate_ipv4_netmask('255.255.255.0') )
|
199
240
|
puts "/24 is valid" if ( IPAdmin.validate_ipv4_netmask(24) )
|
200
241
|
puts "/64 is valid" if ( IPAdmin.validate_ipv6_netmask(64) )
|
201
|
-
|
242
|
+
|
202
243
|
cidr4_1 = IPAdmin::CIDR.new(:CIDR => '192.168.1.0/24')
|
203
244
|
cidr4_2 = IPAdmin::CIDR.new(:CIDR => '192.168.1.0/25')
|
204
245
|
cidr6_1 = IPAdmin::CIDR.new(:CIDR => 'fec0::0/10')
|
205
246
|
cidr6_2 = IPAdmin::CIDR.new(:CIDR => 'fec0::0/64')
|
206
|
-
|
247
|
+
|
248
|
+
# compare_cidr
|
207
249
|
comp1 = IPAdmin.compare_cidr(cidr4_1,cidr4_2)
|
208
250
|
comp2 = IPAdmin.compare_cidr(cidr6_1,cidr6_2)
|
209
251
|
puts "#{(comp1[0]).desc} is the supernet of #{(comp1[1]).desc}"
|
210
252
|
puts "#{(comp2[0]).desc} is the supernet of #{(comp2[1]).desc}"
|
211
|
-
|
253
|
+
|
212
254
|
cidr4_1 = IPAdmin::CIDR.new(:CIDR => '192.168.1.0/24')
|
213
255
|
cidr4_2 = IPAdmin::CIDR.new(:CIDR => '192.168.0.0/24')
|
214
256
|
cidr6_1 = IPAdmin::CIDR.new(:CIDR => 'fec0::0/128')
|
215
257
|
cidr6_2 = IPAdmin::CIDR.new(:CIDR => 'fec0::1/128')
|
216
|
-
|
258
|
+
|
259
|
+
# merge_cidr
|
217
260
|
puts "192.168.1.0/24 and 192.168.0.0/24 merge into #{IPAdmin.merge_cidr([cidr4_1,cidr4_2]).desc}"
|
218
261
|
puts "fec0::0/128 and fec0::1/128 merge into #{IPAdmin.merge_cidr([cidr6_1,cidr6_2]).desc}"
|
219
262
|
|
220
263
|
ip1 = IPAdmin::IPAddr.new(:IPAddr => '192.168.1.0')
|
221
264
|
ip2 = IPAdmin::IPAddr.new(:IPAddr => '192.168.1.50')
|
222
265
|
|
223
|
-
|
266
|
+
# range
|
224
267
|
list = IPAdmin.range(:Boundaries => [ip1,ip2], :Bitstep => 20 )
|
225
|
-
puts "ip's between #{ip1.desc} and #{ip2.desc}"
|
268
|
+
puts "ip's between #{ip1.desc} and #{ip2.desc} (bitstep of 20)"
|
226
269
|
list.each do |x|
|
227
270
|
puts " #{x}"
|
228
271
|
end
|
229
272
|
|
273
|
+
# make_arpa
|
274
|
+
puts "arpa for #{cidr4_1.desc()} is #{IPAdmin.make_arpa(cidr4_1)}"
|
275
|
+
puts "arpa for #{cidr6_1.desc()} is #{IPAdmin.make_arpa(cidr6_1)}"
|
230
276
|
|
277
|
+
# v6_short
|
278
|
+
puts "shorthand notation for #{cidr6_1.network()} is #{IPAdmin.v6_short(cidr6_1.network)}"
|
279
|
+
|
231
280
|
print "\n\n\n"
|
232
281
|
#=====================================#
|
233
|
-
#
|
282
|
+
#
|
234
283
|
#=====================================#
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
data/lib/ip_admin.rb
CHANGED
@@ -9,18 +9,23 @@ module IPAdmin
|
|
9
9
|
# Compare cidr addresses of two IPAdmin::CIDR objects.
|
10
10
|
# - Arguments:
|
11
11
|
# * Two IPAdmin::CIDR objects
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# - Returns:
|
14
14
|
# * if one object is a subnet of another, then return an array in order of
|
15
15
|
# [supernet,subnet]
|
16
16
|
# * if both are equal, return 1
|
17
17
|
# * if neither is a subnet of the other, return nil
|
18
18
|
#
|
19
|
+
# Example:
|
20
|
+
# supernet,subnet = IPAdmin.compare_cidr(cidr1,cidr2)
|
21
|
+
# puts "#{supernet.desc} is the supernet of #{subnet.desc}"
|
22
|
+
#
|
23
|
+
|
19
24
|
def compare_cidr(cidr1,cidr2)
|
20
25
|
|
21
26
|
# we only accept CIDR objects
|
22
27
|
unless ( (cidr1.kind_of? IPAdmin::CIDR)&&(cidr2.kind_of? IPAdmin::CIDR) )
|
23
|
-
raise "
|
28
|
+
raise ArgumentError, "Arguments shouldbe of type IPAdmin::CIDR."
|
24
29
|
end
|
25
30
|
|
26
31
|
# make sure both are same version
|
@@ -74,6 +79,84 @@ module_function :compare_cidr
|
|
74
79
|
|
75
80
|
|
76
81
|
|
82
|
+
#============================================================================#
|
83
|
+
# make_arpa()
|
84
|
+
#============================================================================#
|
85
|
+
|
86
|
+
# Given the address in the provided IPAdmin::IPAddr or IPAdmin::CIDR object,
|
87
|
+
# return either an in-addr.arpa. or ip6.arpa string. If an IPAdmin::CIDR
|
88
|
+
# object is provided, then its netmask will be used to determine the length
|
89
|
+
# of the returned arpa string.
|
90
|
+
#
|
91
|
+
# - Arguments:
|
92
|
+
# * IPAdmin::CIDR or IPAdmin::IPAddr object
|
93
|
+
#
|
94
|
+
# - Returns:
|
95
|
+
# * IP/CIDR address in in-addr.arpa or ip6.arpa format
|
96
|
+
#
|
97
|
+
# Example:
|
98
|
+
# arpa = IPAdmin.make_arpa(cidr)
|
99
|
+
#
|
100
|
+
def make_arpa(object)
|
101
|
+
|
102
|
+
if (object.kind_of? IPAdmin::CIDR)
|
103
|
+
base = object.network()
|
104
|
+
netmask = object.bits()
|
105
|
+
|
106
|
+
elsif (object.kind_of? IPAdmin::IPAddr)
|
107
|
+
base = object.ip()
|
108
|
+
|
109
|
+
else
|
110
|
+
raise ArgumentError, "Expected IPAdmin::CIDR or IPAdmin::IPAddr object, " +
|
111
|
+
"but #{object.class} provided."
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
if (object.version == 4)
|
116
|
+
net = base.split('.')
|
117
|
+
|
118
|
+
if (netmask)
|
119
|
+
while (netmask < 32)
|
120
|
+
net.pop
|
121
|
+
netmask = netmask + 8
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
arpa = net.reverse.join('.')
|
126
|
+
arpa << ".in-addr.arpa."
|
127
|
+
|
128
|
+
else
|
129
|
+
fields = base.split(':')
|
130
|
+
net = []
|
131
|
+
fields.each do |field|
|
132
|
+
(field.split("")).each do |x|
|
133
|
+
net.push(x)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
if (netmask)
|
138
|
+
while (netmask < 128)
|
139
|
+
net.pop
|
140
|
+
netmask = netmask + 4
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
arpa = net.reverse.join('.')
|
145
|
+
arpa << ".ip6.arpa."
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
return(arpa)
|
150
|
+
|
151
|
+
end
|
152
|
+
module_function :make_arpa
|
153
|
+
|
154
|
+
#=====================================#
|
155
|
+
#
|
156
|
+
#=====================================#
|
157
|
+
|
158
|
+
|
159
|
+
|
77
160
|
#============================================================================#
|
78
161
|
# merge_cidr()
|
79
162
|
#============================================================================#
|
@@ -87,11 +170,14 @@ module_function :compare_cidr
|
|
87
170
|
# - Returns:
|
88
171
|
# * IPAdmin::CIDR object
|
89
172
|
#
|
173
|
+
# Example:
|
174
|
+
# merged = IPAdmin.merge_cidr([cidr1,cidr2])
|
175
|
+
#
|
90
176
|
def merge_cidr(cidr_list)
|
91
177
|
|
92
178
|
# make sure we have an array with at least 2 objects
|
93
179
|
unless ( (cidr_list.kind_of? Array) && (cidr_list.length > 1) )
|
94
|
-
raise "Array of at least two IPAdmin::CIDR objects required."
|
180
|
+
raise ArgumentError, "Array of at least two IPAdmin::CIDR objects required."
|
95
181
|
end
|
96
182
|
|
97
183
|
|
@@ -99,7 +185,7 @@ def merge_cidr(cidr_list)
|
|
99
185
|
version = {}
|
100
186
|
cidr_list.each do |cidr|
|
101
187
|
unless (cidr.kind_of? IPAdmin::CIDR)
|
102
|
-
raise "Expected IPAdmin::CIDR, but #{
|
188
|
+
raise ArgumentError, "Expected IPAdmin::CIDR, but #{cidr.class} provided."
|
103
189
|
end
|
104
190
|
version[cidr.version] = 1
|
105
191
|
end
|
@@ -193,12 +279,15 @@ module_function :merge_cidr
|
|
193
279
|
#
|
194
280
|
# - Returns:
|
195
281
|
# * packed IPv4 address or exception on error.
|
282
|
+
#
|
283
|
+
# Example:
|
284
|
+
# packed = IPAdmin.pack_ipv4_addr('192.168.1.1')
|
196
285
|
#
|
197
286
|
def pack_ipv4_addr(ip)
|
198
287
|
|
199
288
|
# is this a string?
|
200
289
|
unless (ip.kind_of? String)
|
201
|
-
raise "Expected String, but #{ip.class} provided."
|
290
|
+
raise ArgumentError, "Expected String, but #{ip.class} provided."
|
202
291
|
end
|
203
292
|
|
204
293
|
# pack our ip
|
@@ -227,7 +316,7 @@ module_function :pack_ipv4_addr
|
|
227
316
|
# pack_ipv4_netmask()
|
228
317
|
#============================================================================#
|
229
318
|
|
230
|
-
# Pack IPv4 netmask into a single byte field.
|
319
|
+
# Pack IPv4 netmask into a single byte field. Only very basic validation
|
231
320
|
# is performed.
|
232
321
|
# - Arguments:
|
233
322
|
# * IPv4 netmask in cidr or extended notation
|
@@ -235,6 +324,10 @@ module_function :pack_ipv4_addr
|
|
235
324
|
# - Returns:
|
236
325
|
# * packed IPv4 netmask or exception on error.
|
237
326
|
#
|
327
|
+
# Example:
|
328
|
+
# packed = IPAdmin.pack_ipv4_netmask('255.255.255.0')
|
329
|
+
# packed = IPAdmin.pack_ipv4_netmask('24')
|
330
|
+
#
|
238
331
|
def pack_ipv4_netmask(netmask)
|
239
332
|
|
240
333
|
all_f = 2**32-1
|
@@ -247,10 +340,21 @@ def pack_ipv4_netmask(netmask)
|
|
247
340
|
packed_netmask = pack_ipv4_addr(netmask)
|
248
341
|
packed_hostmask = packed_netmask ^ all_f
|
249
342
|
rescue Exception
|
250
|
-
raise "#{netmask} is
|
343
|
+
raise "#{netmask} is not a valid IPv4 netmask."
|
251
344
|
end
|
252
345
|
|
253
|
-
|
346
|
+
else
|
347
|
+
# remove '/' if present
|
348
|
+
if (netmask =~ /^\// )
|
349
|
+
netmask[0] = " "
|
350
|
+
netmask.lstrip!
|
351
|
+
end
|
352
|
+
|
353
|
+
# check if we have any non numeric characters
|
354
|
+
if (netmask =~ /\D/)
|
355
|
+
raise "#{netmask} is not a valid IPv4 netmask."
|
356
|
+
end
|
357
|
+
|
254
358
|
if (netmask.kind_of? String)
|
255
359
|
netmask = netmask.to_i
|
256
360
|
end
|
@@ -258,9 +362,6 @@ def pack_ipv4_netmask(netmask)
|
|
258
362
|
packed_hostmask = all_f >> netmask
|
259
363
|
packed_netmask = all_f ^ packed_hostmask
|
260
364
|
|
261
|
-
else
|
262
|
-
raise "#{netmask} is unrecognized."
|
263
|
-
|
264
365
|
end
|
265
366
|
|
266
367
|
ret_vals = [packed_netmask,packed_hostmask]
|
@@ -287,11 +388,14 @@ module_function :pack_ipv4_netmask
|
|
287
388
|
# - Returns:
|
288
389
|
# * packed IPv6 address or exception on error.
|
289
390
|
#
|
391
|
+
# Example:
|
392
|
+
# packed = IPAdmin.pack_ipv4_netmask('fec0::0001')
|
393
|
+
#
|
290
394
|
def pack_ipv6_addr(ip)
|
291
395
|
|
292
396
|
# is this a string?
|
293
397
|
unless (ip.kind_of? String)
|
294
|
-
raise "Expected String, but #{ip.class} provided."
|
398
|
+
raise ArgumentError, "Expected String, but #{ip.class} provided."
|
295
399
|
end
|
296
400
|
|
297
401
|
|
@@ -351,7 +455,7 @@ module_function :pack_ipv6_addr
|
|
351
455
|
# pack_ipv6_netmask()
|
352
456
|
#============================================================================#
|
353
457
|
|
354
|
-
# Pack IPv6 netmask into a single byte field.
|
458
|
+
# Pack IPv6 netmask into a single byte field. Only very basic validation
|
355
459
|
# is performed.
|
356
460
|
# - Arguments:
|
357
461
|
# * IPv6 netmask in cidr notation
|
@@ -359,10 +463,18 @@ module_function :pack_ipv6_addr
|
|
359
463
|
# - Returns:
|
360
464
|
# * packed IPv6 netmask or exception on error.
|
361
465
|
#
|
466
|
+
# Example:
|
467
|
+
# packed = IPAdmin.pack_ipv4_netmask('64')
|
468
|
+
#
|
362
469
|
def pack_ipv6_netmask(netmask)
|
363
470
|
|
364
471
|
all_f = 2**128-1
|
365
472
|
|
473
|
+
# remove '/' if present
|
474
|
+
if (netmask =~ /^\// )
|
475
|
+
netmask[0] = " "
|
476
|
+
netmask.lstrip!
|
477
|
+
end
|
366
478
|
|
367
479
|
if (netmask !~ /\D/)
|
368
480
|
# pack
|
@@ -374,7 +486,7 @@ def pack_ipv6_netmask(netmask)
|
|
374
486
|
packed_netmask = all_f ^ packed_hostmask
|
375
487
|
|
376
488
|
else
|
377
|
-
raise "#{netmask} is
|
489
|
+
raise "#{netmask} is not a valid IPv6 netmask."
|
378
490
|
|
379
491
|
end
|
380
492
|
|
@@ -401,14 +513,17 @@ module_function :pack_ipv6_netmask
|
|
401
513
|
#
|
402
514
|
# - Arguments:
|
403
515
|
# * Hash with the following fields
|
404
|
-
#
|
405
|
-
#
|
406
|
-
#
|
407
|
-
#
|
516
|
+
# - :Bitstep -- enumerate in X sized steps
|
517
|
+
# - :Boundaries -- array of (2) IPAdmin::IPAddr objects
|
518
|
+
# - :Limit -- limit returned list to X number of items
|
519
|
+
# - :Objectify -- return IPAdmin::IPAddr objects
|
408
520
|
#
|
409
521
|
# - Returns:
|
410
522
|
# * array of IP addresses or IPAdmin::IPAddr objects
|
411
523
|
#
|
524
|
+
# Example:
|
525
|
+
# list = IPAdmin.range(:Boundaries => [ip1,ip2])
|
526
|
+
#
|
412
527
|
def range(options)
|
413
528
|
list = []
|
414
529
|
bitstep = 1
|
@@ -537,6 +652,9 @@ module_function :range
|
|
537
652
|
# - Returns:
|
538
653
|
# * IPv4 address.
|
539
654
|
#
|
655
|
+
# Example:
|
656
|
+
# unpacked = IPAdmin.unpack_ipv4_addr(packed)
|
657
|
+
#
|
540
658
|
def unpack_ipv4_addr(packed_ip)
|
541
659
|
|
542
660
|
octets = []
|
@@ -571,6 +689,9 @@ module_function :unpack_ipv4_addr
|
|
571
689
|
# - Returns:
|
572
690
|
# * IPv4 netmask as number of bits (cidr format).
|
573
691
|
#
|
692
|
+
# Example:
|
693
|
+
# unpacked = IPAdmin.unpack_ipv4_netmask(packed)
|
694
|
+
#
|
574
695
|
def unpack_ipv4_netmask(packed_mask)
|
575
696
|
|
576
697
|
mask = 32
|
@@ -604,6 +725,9 @@ module_function :unpack_ipv4_netmask
|
|
604
725
|
# - Returns:
|
605
726
|
# * IPv6 address.
|
606
727
|
#
|
728
|
+
# Example:
|
729
|
+
# unpacked = IPAdmin.unpack_ipv6_addr(packed)
|
730
|
+
#
|
607
731
|
def unpack_ipv6_addr(packed_ip)
|
608
732
|
hex_fields = []
|
609
733
|
(0..7).each do |x|
|
@@ -642,6 +766,9 @@ module_function :unpack_ipv6_addr
|
|
642
766
|
# - Returns:
|
643
767
|
# * IPv6 netmask as number of bits (cidr format).
|
644
768
|
#
|
769
|
+
# Example:
|
770
|
+
# unpacked = IPAdmin.unpack_ipv6_netmask(packed)
|
771
|
+
#
|
645
772
|
def unpack_ipv6_netmask(packed_mask)
|
646
773
|
|
647
774
|
mask = 128
|
@@ -663,22 +790,104 @@ module_function :unpack_ipv6_netmask
|
|
663
790
|
|
664
791
|
|
665
792
|
|
793
|
+
#============================================================================#
|
794
|
+
# v6_short()
|
795
|
+
#============================================================================#
|
796
|
+
|
797
|
+
# Take a standard IPv6 address, and format it in short-hand notation.
|
798
|
+
# Address should not contain a netmask.
|
799
|
+
# - Arguments:
|
800
|
+
# * IPv6 address
|
801
|
+
#
|
802
|
+
# - Returns:
|
803
|
+
# * IPv6 short-hand address.
|
804
|
+
#
|
805
|
+
# Example:
|
806
|
+
# short = IPAdmin.v6_short('fec0:0000:0000:0000:0000:0000:0000:0001')
|
807
|
+
#
|
808
|
+
def v6_short(addr)
|
809
|
+
|
810
|
+
# is this a string?
|
811
|
+
unless (addr.kind_of? String)
|
812
|
+
raise ArgumentError, "Expected String, but #{addr.class} provided."
|
813
|
+
end
|
814
|
+
|
815
|
+
validate_ipv6_addr(addr)
|
816
|
+
|
817
|
+
# make sure this isnt already shorthand
|
818
|
+
if (addr =~ /::/)
|
819
|
+
raise "#{addr} already appears to be in IPv6 shorthand notation."
|
820
|
+
end
|
821
|
+
|
822
|
+
|
823
|
+
# look for most 0 fields
|
824
|
+
found_zero = nil
|
825
|
+
pattern = ""
|
826
|
+
zero_fields = []
|
827
|
+
fields = addr.split(":")
|
828
|
+
|
829
|
+
(0..(fields.length-1)).each do |x|
|
830
|
+
fields[x] = fields[x].to_i(16)
|
831
|
+
|
832
|
+
if (fields[x] == 0)
|
833
|
+
if (!found_zero)
|
834
|
+
found_zero = 1
|
835
|
+
end
|
836
|
+
pattern << ":0"
|
837
|
+
else
|
838
|
+
if (found_zero)
|
839
|
+
found_zero = nil
|
840
|
+
pattern << ":"
|
841
|
+
zero_fields.push(pattern)
|
842
|
+
pattern = ""
|
843
|
+
end
|
844
|
+
end
|
845
|
+
|
846
|
+
fields[x] = fields[x].to_s(16)
|
847
|
+
end
|
848
|
+
|
849
|
+
|
850
|
+
# pattern should be the longest set of 0's in a row
|
851
|
+
zero_fields.push(pattern) if (pattern != "")
|
852
|
+
pattern = ""
|
853
|
+
zero_fields.each do |x|
|
854
|
+
pattern = x if (x.length > pattern.length)
|
855
|
+
end
|
856
|
+
|
857
|
+
|
858
|
+
|
859
|
+
short = fields.join(":")
|
860
|
+
short.sub!(pattern,"::")
|
861
|
+
|
862
|
+
return(short)
|
863
|
+
end
|
864
|
+
module_function :v6_short
|
865
|
+
|
866
|
+
#=====================================#
|
867
|
+
#
|
868
|
+
#=====================================#
|
869
|
+
|
870
|
+
|
871
|
+
|
666
872
|
#============================================================================#
|
667
873
|
# validate_ipv4_addr()
|
668
874
|
#============================================================================#
|
669
875
|
|
670
|
-
# Validate IPv4 addresses.
|
876
|
+
# Validate IPv4 addresses. Address should not contain a netmask.
|
671
877
|
# - Arguments:
|
672
878
|
# * IPv4 address
|
673
879
|
#
|
674
880
|
# - Returns:
|
675
881
|
# * 1 on valid IP or exception on error.
|
676
882
|
#
|
883
|
+
# Example:
|
884
|
+
# IPAdmin.validate_ipv4_addr('192.168.1.1')
|
885
|
+
#
|
677
886
|
def validate_ipv4_addr(ip)
|
678
887
|
|
679
888
|
# is this a string?
|
680
889
|
unless (ip.kind_of? String)
|
681
|
-
raise "Expected String, but #{ip.class} provided."
|
890
|
+
raise ArgumentError, "Expected String, but #{ip.class} provided."
|
682
891
|
end
|
683
892
|
octets = ip.split( /\./ )
|
684
893
|
|
@@ -686,14 +895,14 @@ def validate_ipv4_addr(ip)
|
|
686
895
|
|
687
896
|
# check validity of characters in the addr
|
688
897
|
if ( (ip =~ /\.{2,}?/ ) || (ip =~ /[^0-9\.]/) )
|
689
|
-
raise "#{ip} is
|
898
|
+
raise "#{ip} is not a valid IPv4 address."
|
690
899
|
end
|
691
900
|
|
692
901
|
|
693
902
|
|
694
903
|
# do we have 4 octets?
|
695
904
|
if (octets.length != 4)
|
696
|
-
raise "#{ip} is
|
905
|
+
raise "#{ip} is not a valid IPv4 address."
|
697
906
|
end
|
698
907
|
|
699
908
|
|
@@ -702,14 +911,14 @@ def validate_ipv4_addr(ip)
|
|
702
911
|
(0..3).each do |x|
|
703
912
|
octets[x] = octets[x].to_i
|
704
913
|
unless ( (octets[x] >= 0) && (octets[x] < 256 ) )
|
705
|
-
raise "#{ip} is
|
914
|
+
raise "#{ip} is not a valid IPv4 address."
|
706
915
|
end
|
707
916
|
end
|
708
917
|
|
709
918
|
|
710
919
|
# dont allow first octet to be 0
|
711
920
|
if (octets[0] == 0)
|
712
|
-
raise "#{ip} is
|
921
|
+
raise "#{ip} is not a valid IPv4 address."
|
713
922
|
end
|
714
923
|
|
715
924
|
return(1)
|
@@ -734,6 +943,12 @@ module_function :validate_ipv4_addr
|
|
734
943
|
# - Returns:
|
735
944
|
# * 1 on valid IP or exception on error.
|
736
945
|
#
|
946
|
+
# Example:
|
947
|
+
# IPAdmin.validate_ipv4_netmask('255.255.255.0')
|
948
|
+
# IPAdmin.validate_ipv4_netmask('24')
|
949
|
+
# IPAdmin.validate_ipv4_netmask('/24')
|
950
|
+
# IPAdmin.validate_ipv4_netmask(24)
|
951
|
+
#
|
737
952
|
def validate_ipv4_netmask(netmask)
|
738
953
|
|
739
954
|
all_f = (2**32)-1
|
@@ -747,7 +962,7 @@ def validate_ipv4_netmask(netmask)
|
|
747
962
|
packed_mask = pack_ipv4_addr(netmask)
|
748
963
|
|
749
964
|
rescue Exception
|
750
|
-
raise "#{netmask} is
|
965
|
+
raise "#{netmask} is not a valid IPv4 netmask."
|
751
966
|
end
|
752
967
|
|
753
968
|
# cycle through the bits of hostmask and compare
|
@@ -762,7 +977,7 @@ def validate_ipv4_netmask(netmask)
|
|
762
977
|
if ( check != 0)
|
763
978
|
hostmask = hostmask >> 1
|
764
979
|
unless ( (packed_mask ^ hostmask) == all_f)
|
765
|
-
raise "#{netmask} is
|
980
|
+
raise "#{netmask} is not a valid IPv4 netmask."
|
766
981
|
end
|
767
982
|
break
|
768
983
|
else
|
@@ -773,9 +988,15 @@ def validate_ipv4_netmask(netmask)
|
|
773
988
|
|
774
989
|
else
|
775
990
|
|
991
|
+
# remove '/' if present
|
992
|
+
if (netmask =~ /^\// )
|
993
|
+
netmask[0] = " "
|
994
|
+
netmask.lstrip!
|
995
|
+
end
|
996
|
+
|
776
997
|
# check if we have any non numeric characters
|
777
998
|
if (netmask =~ /\D/)
|
778
|
-
raise "#{netmask} is
|
999
|
+
raise "#{netmask} is not a valid IPv4 netmask."
|
779
1000
|
end
|
780
1001
|
|
781
1002
|
|
@@ -785,7 +1006,7 @@ def validate_ipv4_netmask(netmask)
|
|
785
1006
|
end
|
786
1007
|
|
787
1008
|
if ( (netmask > 32) || (netmask == 0) )
|
788
|
-
raise "#{netmask} is
|
1009
|
+
raise "#{netmask} is not a valid IPv4 netmask."
|
789
1010
|
end
|
790
1011
|
|
791
1012
|
end
|
@@ -805,24 +1026,27 @@ module_function :validate_ipv4_netmask
|
|
805
1026
|
# validate_ipv6_addr()
|
806
1027
|
#============================================================================#
|
807
1028
|
|
808
|
-
# Validate IPv6 addresses.
|
1029
|
+
# Validate IPv6 addresses. Address should not contain a netmask.
|
809
1030
|
# - Arguments:
|
810
1031
|
# * IPv6 address
|
811
1032
|
#
|
812
1033
|
# - Returns:
|
813
1034
|
# * 1 on valid IP or exception on error.
|
814
1035
|
#
|
1036
|
+
# Example:
|
1037
|
+
# IPAdmin.validate_ipv6_addr('fec0::')
|
1038
|
+
#
|
815
1039
|
def validate_ipv6_addr(ip)
|
816
1040
|
# is this a string?
|
817
1041
|
unless (ip.kind_of? String)
|
818
|
-
raise "Expected String, but #{ip.class} provided."
|
1042
|
+
raise ArgumentError, "Expected String, but #{ip.class} provided."
|
819
1043
|
end
|
820
1044
|
|
821
1045
|
|
822
1046
|
|
823
1047
|
# check validity of characters in the addr
|
824
1048
|
if ( (ip =~ /:{3,}?/ ) || (ip =~ /[^0-9a-fA-F:]/) )
|
825
|
-
raise "#{ip} is
|
1049
|
+
raise "#{ip} is not a valid IPv6 address."
|
826
1050
|
end
|
827
1051
|
|
828
1052
|
|
@@ -833,7 +1057,7 @@ def validate_ipv6_addr(ip)
|
|
833
1057
|
if (ip =~ /::/)
|
834
1058
|
shrthnd = ip.split( /::/ )
|
835
1059
|
unless ( (shrthnd.length > 0) && (shrthnd.length < 3) )
|
836
|
-
raise "#{ip} is
|
1060
|
+
raise "#{ip} is not a valid IPv6 address."
|
837
1061
|
end
|
838
1062
|
end
|
839
1063
|
|
@@ -848,7 +1072,7 @@ def validate_ipv6_addr(ip)
|
|
848
1072
|
elements.each {|x| hex_fields.push(x)}
|
849
1073
|
end
|
850
1074
|
if ( (hex_fields.length < 1) || (hex_fields.length > 7) )
|
851
|
-
raise "#{ip} is
|
1075
|
+
raise "#{ip} is not a valid IPv6 address."
|
852
1076
|
end
|
853
1077
|
|
854
1078
|
else
|
@@ -856,7 +1080,7 @@ def validate_ipv6_addr(ip)
|
|
856
1080
|
# have exactly 8 hex fields
|
857
1081
|
hex_fields = ip.split( /:/ )
|
858
1082
|
if (hex_fields.length != 8)
|
859
|
-
raise "#{ip} is
|
1083
|
+
raise "#{ip} is not a valid IPv6 address."
|
860
1084
|
end
|
861
1085
|
|
862
1086
|
end
|
@@ -867,7 +1091,7 @@ def validate_ipv6_addr(ip)
|
|
867
1091
|
# hex field
|
868
1092
|
hex_fields.each do |x|
|
869
1093
|
if (x.length > 4)
|
870
|
-
raise "#{ip} is
|
1094
|
+
raise "#{ip} is not a valid IPv6 address."
|
871
1095
|
end
|
872
1096
|
end
|
873
1097
|
|
@@ -893,11 +1117,22 @@ module_function :validate_ipv6_addr
|
|
893
1117
|
#
|
894
1118
|
# - Returns:
|
895
1119
|
# * 1 on valid IP or exception on error.
|
1120
|
+
#
|
1121
|
+
# Example:
|
1122
|
+
# IPAdmin.validate_ipv6_netmask('64')
|
1123
|
+
# IPAdmin.validate_ipv6_netmask('/64')
|
1124
|
+
# IPAdmin.validate_ipv6_netmask(64)
|
896
1125
|
#
|
897
1126
|
def validate_ipv6_netmask(netmask)
|
898
1127
|
|
1128
|
+
# remove '/' if present
|
1129
|
+
if (netmask =~ /^\// )
|
1130
|
+
netmask[0] = " "
|
1131
|
+
netmask.lstrip!
|
1132
|
+
end
|
1133
|
+
|
899
1134
|
if (netmask =~ /\D/)
|
900
|
-
raise "#{netmask} is
|
1135
|
+
raise "#{netmask} is not a valid IPv6 netmask."
|
901
1136
|
|
902
1137
|
else
|
903
1138
|
# are we between 1 and 128 inclusive
|
@@ -906,7 +1141,7 @@ def validate_ipv6_netmask(netmask)
|
|
906
1141
|
end
|
907
1142
|
|
908
1143
|
if ( (netmask > 128) || (netmask == 0) )
|
909
|
-
raise "#{netmask} is
|
1144
|
+
raise "#{netmask} is not a valid IPv6 netmask."
|
910
1145
|
end
|
911
1146
|
|
912
1147
|
end
|
@@ -942,17 +1177,20 @@ class CIDR
|
|
942
1177
|
#============================================================================#
|
943
1178
|
# attr_reader/attr_writer
|
944
1179
|
#============================================================================#
|
945
|
-
|
946
|
-
# @network - packed cidr network
|
947
|
-
# @netmask - packet cidr netmask
|
948
|
-
# @hostmask - inverse packed netmask
|
949
1180
|
|
950
1181
|
# ip version 4 or 6
|
951
1182
|
attr_reader :version
|
952
1183
|
|
953
1184
|
# hash of custom tags. should be in the format tag => value
|
954
1185
|
attr_reader :tag
|
955
|
-
|
1186
|
+
|
1187
|
+
# attr_writer - hash of custom tags. should be in the format tag => value
|
1188
|
+
def tag=(new_tag)
|
1189
|
+
unless (new_tag.kind_of? Hash)
|
1190
|
+
raise ArgumentError, "Expected Hash, but #{new_tag.class} provided."
|
1191
|
+
end
|
1192
|
+
@tag = new_tag
|
1193
|
+
end
|
956
1194
|
|
957
1195
|
#=====================================#
|
958
1196
|
#
|
@@ -966,14 +1204,21 @@ class CIDR
|
|
966
1204
|
|
967
1205
|
# - Arguments:
|
968
1206
|
# * Hash with the following fields:
|
969
|
-
# :CIDR -- IPv4 or IPv6 cidr block
|
970
|
-
# :Netmask -- IPv4 netmask in extended format (if not provided in :CIDR)
|
971
|
-
# :Tag -- Custom descriptor tag for object. Should be Hash (tag => value)
|
1207
|
+
# - :CIDR -- IPv4 or IPv6 cidr block
|
1208
|
+
# - :Netmask -- IPv4 netmask in extended format (if not provided in :CIDR)
|
1209
|
+
# - :Tag -- Custom descriptor tag for object. Should be Hash (tag => value)
|
1210
|
+
#
|
1211
|
+
# Example:
|
1212
|
+
# cidr4 = IPAdmin::CIDR.new(:CIDR => '192.168.1.0',
|
1213
|
+
# :Netmask => '255.255.255.0')
|
1214
|
+
# cidr6 = IPAdmin::CIDR.new(:CIDR => 'fec0::/64',
|
1215
|
+
# :Tag => {'interface' => 'g0/1'})
|
1216
|
+
#
|
972
1217
|
#
|
973
1218
|
def initialize(options)
|
974
1219
|
|
975
1220
|
unless (options.kind_of? Hash)
|
976
|
-
raise "Expected Hash, but #{options.class} provided."
|
1221
|
+
raise ArgumentError, "Expected Hash, but #{options.class} provided."
|
977
1222
|
end
|
978
1223
|
|
979
1224
|
|
@@ -1051,8 +1296,11 @@ class CIDR
|
|
1051
1296
|
|
1052
1297
|
|
1053
1298
|
# set tag if present
|
1054
|
-
if ( options.has_key?(:Tag) )
|
1299
|
+
if ( options.has_key?(:Tag) )
|
1055
1300
|
@tag = options[:Tag]
|
1301
|
+
unless (@tag.kind_of? Hash)
|
1302
|
+
raise "Expected Hash, but #{@tag.class} provided for option :Tag."
|
1303
|
+
end
|
1056
1304
|
end
|
1057
1305
|
|
1058
1306
|
|
@@ -1064,6 +1312,37 @@ class CIDR
|
|
1064
1312
|
|
1065
1313
|
|
1066
1314
|
|
1315
|
+
#============================================================================#
|
1316
|
+
# bits()
|
1317
|
+
#============================================================================#
|
1318
|
+
|
1319
|
+
# Provide number of bits of Netmask.
|
1320
|
+
#
|
1321
|
+
# - Arguments:
|
1322
|
+
# * none
|
1323
|
+
#
|
1324
|
+
# - Returns:
|
1325
|
+
# * Number of bits of Netmask.
|
1326
|
+
#
|
1327
|
+
# Example:
|
1328
|
+
# bits = cidr.bits()
|
1329
|
+
#
|
1330
|
+
def bits()
|
1331
|
+
if (@version == 4)
|
1332
|
+
bits = IPAdmin.unpack_ipv4_netmask(@netmask)
|
1333
|
+
else
|
1334
|
+
bits = IPAdmin.unpack_ipv6_netmask(@netmask)
|
1335
|
+
end
|
1336
|
+
|
1337
|
+
return(bits)
|
1338
|
+
end
|
1339
|
+
|
1340
|
+
#=====================================#
|
1341
|
+
#
|
1342
|
+
#=====================================#
|
1343
|
+
|
1344
|
+
|
1345
|
+
|
1067
1346
|
#============================================================================#
|
1068
1347
|
# contains()
|
1069
1348
|
#============================================================================#
|
@@ -1075,9 +1354,16 @@ class CIDR
|
|
1075
1354
|
#
|
1076
1355
|
# - Returns:
|
1077
1356
|
# * 1 on true, nil on false
|
1357
|
+
#
|
1358
|
+
# Example:
|
1359
|
+
# contains = cidr.contains(ip)
|
1078
1360
|
#
|
1079
1361
|
def contains(ip_obj)
|
1080
1362
|
|
1363
|
+
unless (ip_obj.kind_of? IPAdmin::IPAddr)
|
1364
|
+
raise ArgumentError, "Expected IPAdmin::IPAddr object, but #{ip_obj.class} provided."
|
1365
|
+
end
|
1366
|
+
|
1081
1367
|
if ( (ip_obj.version == 4) && (@version == 4) )
|
1082
1368
|
v4_all_f = (2**32)-1
|
1083
1369
|
hostmask = @netmask ^ v4_all_f
|
@@ -1117,6 +1403,9 @@ class CIDR
|
|
1117
1403
|
#
|
1118
1404
|
# - Returns:
|
1119
1405
|
# * Description in network/netmask format
|
1406
|
+
#
|
1407
|
+
# Example:
|
1408
|
+
# desc = cidr.desc()
|
1120
1409
|
#
|
1121
1410
|
def desc()
|
1122
1411
|
|
@@ -1147,12 +1436,15 @@ class CIDR
|
|
1147
1436
|
#
|
1148
1437
|
# - Arguments:
|
1149
1438
|
# * Hash with the following fields
|
1150
|
-
#
|
1151
|
-
#
|
1152
|
-
#
|
1439
|
+
# - :Bitstep -- enumerate in X sized steps
|
1440
|
+
# - :Objectify -- return IPAdmin::IPAddr objects
|
1441
|
+
# - :Limit -- limit returned list to X number of items
|
1153
1442
|
#
|
1154
1443
|
# - Returns:
|
1155
1444
|
# * array of IP addresses or IPAdmin::IPAddr objects
|
1445
|
+
#
|
1446
|
+
# Example:
|
1447
|
+
# ip_list = cidr.enumerate(:Bitstep => 2)
|
1156
1448
|
#
|
1157
1449
|
def enumerate(options=nil)
|
1158
1450
|
bitstep = 1
|
@@ -1265,6 +1557,9 @@ class CIDR
|
|
1265
1557
|
#
|
1266
1558
|
# - Returns:
|
1267
1559
|
# * Hostmask in extended (y.y.y.y) format.
|
1560
|
+
#
|
1561
|
+
# Example:
|
1562
|
+
# hostmask = cidr.hostmask_ext()
|
1268
1563
|
#
|
1269
1564
|
def hostmask_ext()
|
1270
1565
|
if (@version == 4)
|
@@ -1292,7 +1587,10 @@ class CIDR
|
|
1292
1587
|
# * none
|
1293
1588
|
#
|
1294
1589
|
# - Returns:
|
1295
|
-
# *
|
1590
|
+
# * Netmask in CIDR format.
|
1591
|
+
#
|
1592
|
+
# Example:
|
1593
|
+
# netmask = cidr.netmask()
|
1296
1594
|
#
|
1297
1595
|
def netmask()
|
1298
1596
|
if (@version == 4)
|
@@ -1301,7 +1599,7 @@ class CIDR
|
|
1301
1599
|
bits = IPAdmin.unpack_ipv6_netmask(@netmask)
|
1302
1600
|
end
|
1303
1601
|
|
1304
|
-
return(bits)
|
1602
|
+
return("/#{bits}")
|
1305
1603
|
end
|
1306
1604
|
|
1307
1605
|
#=====================================#
|
@@ -1321,13 +1619,16 @@ class CIDR
|
|
1321
1619
|
#
|
1322
1620
|
# - Returns:
|
1323
1621
|
# * Netmask in extended (y.y.y.y) format.
|
1622
|
+
#
|
1623
|
+
# Example:
|
1624
|
+
# netmask = cidr.netmask_ext()
|
1324
1625
|
#
|
1325
1626
|
def netmask_ext()
|
1326
1627
|
if (@version == 4)
|
1327
1628
|
netmask = IPAdmin.unpack_ipv4_addr(@netmask)
|
1328
1629
|
else
|
1329
1630
|
raise "IPv6 does not support extended netmask notation. " +
|
1330
|
-
"Use
|
1631
|
+
"Use netmask() method instead."
|
1331
1632
|
end
|
1332
1633
|
|
1333
1634
|
return(netmask)
|
@@ -1350,6 +1651,9 @@ class CIDR
|
|
1350
1651
|
#
|
1351
1652
|
# - Returns:
|
1352
1653
|
# * Base network address.
|
1654
|
+
#
|
1655
|
+
# Example:
|
1656
|
+
# network = cidr.network()
|
1353
1657
|
#
|
1354
1658
|
def network()
|
1355
1659
|
if (@version == 4)
|
@@ -1375,11 +1679,14 @@ class CIDR
|
|
1375
1679
|
#
|
1376
1680
|
# - Arguments:
|
1377
1681
|
# * Hash with the following fields
|
1378
|
-
#
|
1379
|
-
#
|
1682
|
+
# - :Index -- index number of the IP address to return
|
1683
|
+
# - :Objectify -- return IPAdmin::IPAddr objects
|
1380
1684
|
#
|
1381
1685
|
# - Returns:
|
1382
1686
|
# * IP address or IPAdmin::IPAddr object.
|
1687
|
+
#
|
1688
|
+
# Example:
|
1689
|
+
# first_ip = cidr.nth(:Index => 1)
|
1383
1690
|
#
|
1384
1691
|
def nth(options)
|
1385
1692
|
objectify = nil
|
@@ -1458,6 +1765,9 @@ class CIDR
|
|
1458
1765
|
#
|
1459
1766
|
# - Returns:
|
1460
1767
|
# * Byte-packed Hostmask.
|
1768
|
+
#
|
1769
|
+
# Example:
|
1770
|
+
# packed = cidr.packed_hostmask()
|
1461
1771
|
#
|
1462
1772
|
def packed_hostmask()
|
1463
1773
|
return(@hostmask)
|
@@ -1480,6 +1790,9 @@ class CIDR
|
|
1480
1790
|
#
|
1481
1791
|
# - Returns:
|
1482
1792
|
# * Byte-packed Netmask.
|
1793
|
+
#
|
1794
|
+
# Example:
|
1795
|
+
# packed = cidr.packed_netmask()
|
1483
1796
|
#
|
1484
1797
|
def packed_netmask()
|
1485
1798
|
return(@netmask)
|
@@ -1502,6 +1815,9 @@ class CIDR
|
|
1502
1815
|
#
|
1503
1816
|
# - Returns:
|
1504
1817
|
# * Byte-packed Network Address.
|
1818
|
+
#
|
1819
|
+
# Example:
|
1820
|
+
# packed = cidr.packed_network()
|
1505
1821
|
#
|
1506
1822
|
def packed_network()
|
1507
1823
|
return(@network)
|
@@ -1524,6 +1840,9 @@ class CIDR
|
|
1524
1840
|
#
|
1525
1841
|
# - Returns:
|
1526
1842
|
# * Number of IP addresses in this CIDR block.
|
1843
|
+
#
|
1844
|
+
# Example:
|
1845
|
+
# num_ip = cidr.size()
|
1527
1846
|
#
|
1528
1847
|
def size()
|
1529
1848
|
return(@hostmask + 1)
|
@@ -1544,16 +1863,19 @@ class CIDR
|
|
1544
1863
|
#
|
1545
1864
|
# - Arguments:
|
1546
1865
|
# * Hash with the following fields:
|
1547
|
-
# :Subnet -- number of bits of new subnet to create (24,26, etc...)
|
1548
|
-
# :MinCount -- minimum number of subnets of size :Subnet to return
|
1866
|
+
# - :Subnet -- number of bits of new subnet to create (24,26, etc...)
|
1867
|
+
# - :MinCount -- minimum number of subnets of size :Subnet to return
|
1549
1868
|
#
|
1550
1869
|
# - Returns:
|
1551
1870
|
# * array of IPAdmin::CIDR objects
|
1871
|
+
#
|
1872
|
+
# Example:
|
1873
|
+
# cidr_list = cidr4.subnet(:Subnet => 28, :MinCount => 3)
|
1552
1874
|
#
|
1553
1875
|
def subnet(options)
|
1554
1876
|
subnet = options[:Subnet]
|
1555
1877
|
min_count = options[:MinCount]
|
1556
|
-
mymask = self.
|
1878
|
+
mymask = self.bits
|
1557
1879
|
num_avail = 2**(subnet - mymask)
|
1558
1880
|
new_subnets = []
|
1559
1881
|
|
@@ -1698,12 +2020,15 @@ class CIDRTable
|
|
1698
2020
|
#============================================================================#
|
1699
2021
|
|
1700
2022
|
# - Arguments:
|
1701
|
-
# *
|
2023
|
+
# * IP version (4 or 6)
|
2024
|
+
#
|
2025
|
+
# Example:
|
2026
|
+
# table = IPAdmin::CIDRTable.new(4)
|
1702
2027
|
#
|
1703
2028
|
def initialize(version)
|
1704
2029
|
|
1705
2030
|
unless ( version.kind_of? Fixnum )
|
1706
|
-
raise "Expected Fixnum, but #{version.class} provided."
|
2031
|
+
raise ArgumentError, "Expected Fixnum, but #{version.class} provided."
|
1707
2032
|
end
|
1708
2033
|
|
1709
2034
|
unless ( version == 4 || version == 6 )
|
@@ -1730,10 +2055,17 @@ class CIDRTable
|
|
1730
2055
|
# * IPAdmin::CIDR object
|
1731
2056
|
#
|
1732
2057
|
# - Returns:
|
1733
|
-
# *
|
2058
|
+
# * nothing
|
2059
|
+
#
|
2060
|
+
# Example:
|
2061
|
+
# table.add_cidr(cidr)
|
1734
2062
|
#
|
1735
2063
|
def add_cidr(new_cidr)
|
1736
2064
|
|
2065
|
+
unless (new_cidr.kind_of? IPAdmin::CIDR)
|
2066
|
+
raise ArgumentError, "Expected IPAdmin::CIDR, but #{new_cidr.class} provided."
|
2067
|
+
end
|
2068
|
+
|
1737
2069
|
unless (new_cidr.version == @version )
|
1738
2070
|
raise "CIDR version #{new_cidr.version} is incompatible with " +
|
1739
2071
|
"CIDRTable version #{@version}."
|
@@ -1805,10 +2137,13 @@ class CIDRTable
|
|
1805
2137
|
# Dump contents of this table
|
1806
2138
|
#
|
1807
2139
|
# - Arguments:
|
1808
|
-
# *
|
2140
|
+
# * none
|
1809
2141
|
#
|
1810
2142
|
# - Returns:
|
1811
2143
|
# * ordered array of IPAdmin::CIDR objects within this table
|
2144
|
+
#
|
2145
|
+
# Example:
|
2146
|
+
# cidr_list = table.dump()
|
1812
2147
|
#
|
1813
2148
|
def dump()
|
1814
2149
|
|
@@ -1855,15 +2190,18 @@ class CIDRTable
|
|
1855
2190
|
#
|
1856
2191
|
# - Returns:
|
1857
2192
|
# * IPAdmin::CIDR object, or nil on no match
|
2193
|
+
#
|
2194
|
+
# Example:
|
2195
|
+
# cidr = table.find_ip(ip)
|
1858
2196
|
#
|
1859
2197
|
def find_ip(ip_obj)
|
1860
2198
|
|
1861
2199
|
unless (ip_obj.kind_of? IPAdmin::IPAddr)
|
1862
|
-
raise "Expected IPAdmin::IPAddr, but #{
|
2200
|
+
raise ArgumentError, "Expected IPAdmin::IPAddr, but #{ip_obj.class} provided."
|
1863
2201
|
end
|
1864
2202
|
|
1865
2203
|
unless (ip_obj.version == @version )
|
1866
|
-
raise "IPAddr version #{
|
2204
|
+
raise "IPAddr version #{ip_obj.version} is incompatible with " +
|
1867
2205
|
"CIDRTable version #{@version}."
|
1868
2206
|
end
|
1869
2207
|
|
@@ -1899,11 +2237,14 @@ class CIDRTable
|
|
1899
2237
|
#
|
1900
2238
|
# - Arguments:
|
1901
2239
|
# * Hash with the following fields:
|
1902
|
-
# :Size -- subnet size (number of bits)
|
1903
|
-
# :Limit -- max entries to return
|
2240
|
+
# - :Size -- subnet size (number of bits)
|
2241
|
+
# - :Limit -- max entries to return
|
1904
2242
|
#
|
1905
2243
|
# - Returns:
|
1906
2244
|
# * ordered array of IPAdmin::CIDR objects, or nil on no match
|
2245
|
+
#
|
2246
|
+
# Example:
|
2247
|
+
# cidr_list = table.find_space(:Size => 27)
|
1907
2248
|
#
|
1908
2249
|
def find_space(options)
|
1909
2250
|
limit = nil
|
@@ -1915,11 +2256,11 @@ class CIDRTable
|
|
1915
2256
|
|
1916
2257
|
# validate options
|
1917
2258
|
unless (options.kind_of? Hash)
|
1918
|
-
raise "Expected Hash, but #{options.class} provided."
|
2259
|
+
raise ArgumentError, "Expected Hash, but #{options.class} provided."
|
1919
2260
|
end
|
1920
2261
|
|
1921
2262
|
unless ( options.has_key?(:Size) )
|
1922
|
-
raise "Missing argument :Size."
|
2263
|
+
raise ArgumentError, "Missing argument :Size."
|
1923
2264
|
end
|
1924
2265
|
subnet_size = options[:Size]
|
1925
2266
|
|
@@ -1953,7 +2294,7 @@ class CIDRTable
|
|
1953
2294
|
# find space
|
1954
2295
|
sorted_parents.each do |key|
|
1955
2296
|
parent = parent_hash[key]
|
1956
|
-
if ( parent.
|
2297
|
+
if ( parent.bits() < subnet_size )
|
1957
2298
|
if (@cidr_table[parent] != 0)
|
1958
2299
|
child_list = []
|
1959
2300
|
child_list = (@cidr_table[parent]).find_space(:Size => subnet_size)
|
@@ -1970,7 +2311,7 @@ class CIDRTable
|
|
1970
2311
|
|
1971
2312
|
end
|
1972
2313
|
|
1973
|
-
elsif ( (parent_hash[key].
|
2314
|
+
elsif ( (parent_hash[key].bits() == subnet_size) &&
|
1974
2315
|
(@cidr_table[parent] == 0) )
|
1975
2316
|
list.push(parent)
|
1976
2317
|
|
@@ -1993,6 +2334,62 @@ class CIDRTable
|
|
1993
2334
|
|
1994
2335
|
|
1995
2336
|
|
2337
|
+
#============================================================================#
|
2338
|
+
# rem_cidr()
|
2339
|
+
#============================================================================#
|
2340
|
+
|
2341
|
+
# Remove an IPAdmin::CIDR object from this table
|
2342
|
+
#
|
2343
|
+
# - Arguments:
|
2344
|
+
# * IPAdmin::CIDR object
|
2345
|
+
#
|
2346
|
+
# - Returns:
|
2347
|
+
# * nothing
|
2348
|
+
#
|
2349
|
+
# Example:
|
2350
|
+
# table.rem_cidr(cidr)
|
2351
|
+
#
|
2352
|
+
def rem_cidr(cidr)
|
2353
|
+
|
2354
|
+
unless (cidr.kind_of? IPAdmin::CIDR)
|
2355
|
+
raise ArgumentError, "Expected IPAdmin::CIDR, but #{cidr.class} provided."
|
2356
|
+
end
|
2357
|
+
|
2358
|
+
unless (cidr.version == @version )
|
2359
|
+
raise "CIDR version #{cidr.version} is incompatible with " +
|
2360
|
+
"CIDRTable version #{@version}."
|
2361
|
+
end
|
2362
|
+
|
2363
|
+
# if cidr is part of this table
|
2364
|
+
if (@cidr_table.has_key?(cidr) )
|
2365
|
+
|
2366
|
+
if (@cidr_table[cidr] != 0)
|
2367
|
+
child_table = @cidr_table[cidr]
|
2368
|
+
child_table.cidr_table.each_key do |child|
|
2369
|
+
child_table.rem_cidr(child)
|
2370
|
+
end
|
2371
|
+
end
|
2372
|
+
@cidr_table.delete(cidr)
|
2373
|
+
|
2374
|
+
# else search @cidr_table to see if cidr is a child block
|
2375
|
+
else
|
2376
|
+
@cidr_table.each_key do |entry|
|
2377
|
+
parent,child = IPAdmin.compare_cidr(cidr,entry)
|
2378
|
+
|
2379
|
+
if (parent == entry)
|
2380
|
+
(@cidr_table[entry]).rem_cidr(cidr)
|
2381
|
+
end
|
2382
|
+
end
|
2383
|
+
end
|
2384
|
+
|
2385
|
+
end
|
2386
|
+
|
2387
|
+
#=====================================#
|
2388
|
+
#
|
2389
|
+
#=====================================#
|
2390
|
+
|
2391
|
+
|
2392
|
+
|
1996
2393
|
|
1997
2394
|
end
|
1998
2395
|
|
@@ -2031,17 +2428,19 @@ class IPAddr
|
|
2031
2428
|
# attr_reader/attr_writer
|
2032
2429
|
#============================================================================#
|
2033
2430
|
|
2034
|
-
# @ip - packed ip address
|
2035
|
-
# @netmask - packed netmask
|
2036
|
-
# @hostmask - inverse packed netmask
|
2037
|
-
|
2038
2431
|
# ip version 4 or 6
|
2039
2432
|
attr_reader :version
|
2040
2433
|
|
2041
2434
|
# hash of custom tags. should be in the format tag => value
|
2042
2435
|
attr_reader :tag
|
2043
|
-
|
2044
|
-
|
2436
|
+
|
2437
|
+
# attr_writer - hash of custom tags. should be in the format tag => value
|
2438
|
+
def tag=(new_tag)
|
2439
|
+
unless (new_tag.kind_of? Hash)
|
2440
|
+
raise ArgumentError, "Expected Hash, but #{new_tag.class} provided."
|
2441
|
+
end
|
2442
|
+
@tag = new_tag
|
2443
|
+
end
|
2045
2444
|
|
2046
2445
|
#=====================================#
|
2047
2446
|
#
|
@@ -2055,14 +2454,21 @@ class IPAddr
|
|
2055
2454
|
|
2056
2455
|
# - Arguments:
|
2057
2456
|
# * Hash with the following fields
|
2058
|
-
# :IPAddr -- IPv4 or IPv6 address (assume host address by default)
|
2059
|
-
# :Netmask -- IPv4 netmask in extended format ( if not part of IPAddr)
|
2060
|
-
# :Tag -- Custom descriptor tag for object. Should be Hash (tag => value)
|
2457
|
+
# - :IPAddr -- IPv4 or IPv6 address (assume host address by default)
|
2458
|
+
# - :Netmask -- IPv4 netmask in extended format ( if not part of IPAddr)
|
2459
|
+
# - :Tag -- Custom descriptor tag for object. Should be Hash (tag => value)
|
2460
|
+
#
|
2461
|
+
# Example:
|
2462
|
+
# ip4 = IPAdmin::IPAddr.new(:IPAddr => '192.168.1.1',
|
2463
|
+
# :Netmask => '255.255.255.0',
|
2464
|
+
# :Tag => {'desc' => 'FastEthernet0/1'})
|
2465
|
+
#
|
2466
|
+
# ip6 = IPAdmin::IPAddr.new(:IPAddr => 'fec0::/64')
|
2061
2467
|
#
|
2062
2468
|
def initialize(options)
|
2063
2469
|
|
2064
2470
|
unless (options.kind_of? Hash)
|
2065
|
-
raise "Expected Hash, but #{options.class} provided."
|
2471
|
+
raise ArgumentError, "Expected Hash, but #{options.class} provided."
|
2066
2472
|
end
|
2067
2473
|
|
2068
2474
|
if ( options.has_key?(:IPAddr) )
|
@@ -2144,10 +2550,12 @@ class IPAddr
|
|
2144
2550
|
|
2145
2551
|
|
2146
2552
|
# set tag if present
|
2147
|
-
if ( options.has_key?(:Tag) )
|
2553
|
+
if ( options.has_key?(:Tag) )
|
2148
2554
|
@tag = options[:Tag]
|
2555
|
+
unless (@tag.kind_of? Hash)
|
2556
|
+
raise "Expected Hash, but #{@tag.class} provided for option :Tag."
|
2557
|
+
end
|
2149
2558
|
end
|
2150
|
-
|
2151
2559
|
|
2152
2560
|
end
|
2153
2561
|
|
@@ -2170,6 +2578,9 @@ class IPAddr
|
|
2170
2578
|
#
|
2171
2579
|
# - Returns:
|
2172
2580
|
# * base network address.
|
2581
|
+
#
|
2582
|
+
# Example:
|
2583
|
+
# base = ip.base()
|
2173
2584
|
#
|
2174
2585
|
def base()
|
2175
2586
|
if (@version == 4)
|
@@ -2189,6 +2600,37 @@ class IPAddr
|
|
2189
2600
|
|
2190
2601
|
|
2191
2602
|
|
2603
|
+
#============================================================================#
|
2604
|
+
# bits()
|
2605
|
+
#============================================================================#
|
2606
|
+
|
2607
|
+
# Provide number of bits of Netmask.
|
2608
|
+
#
|
2609
|
+
# - Arguments:
|
2610
|
+
# * none
|
2611
|
+
#
|
2612
|
+
# - Returns:
|
2613
|
+
# * Number of bits of Netmask.
|
2614
|
+
#
|
2615
|
+
# Example:
|
2616
|
+
# bits = ip.bits()
|
2617
|
+
#
|
2618
|
+
def bits()
|
2619
|
+
if (@version == 4)
|
2620
|
+
bits = IPAdmin.unpack_ipv4_netmask(@netmask)
|
2621
|
+
else
|
2622
|
+
bits = IPAdmin.unpack_ipv6_netmask(@netmask)
|
2623
|
+
end
|
2624
|
+
|
2625
|
+
return(bits)
|
2626
|
+
end
|
2627
|
+
|
2628
|
+
#=====================================#
|
2629
|
+
#
|
2630
|
+
#=====================================#
|
2631
|
+
|
2632
|
+
|
2633
|
+
|
2192
2634
|
#============================================================================#
|
2193
2635
|
# broadcast()
|
2194
2636
|
#============================================================================#
|
@@ -2200,6 +2642,9 @@ class IPAddr
|
|
2200
2642
|
#
|
2201
2643
|
# - Returns:
|
2202
2644
|
# * broadcast address.
|
2645
|
+
#
|
2646
|
+
# Example:
|
2647
|
+
# bcast = ip.broadcast()
|
2203
2648
|
#
|
2204
2649
|
def broadcast()
|
2205
2650
|
if (@version == 4)
|
@@ -2230,6 +2675,9 @@ class IPAddr
|
|
2230
2675
|
#
|
2231
2676
|
# - Returns:
|
2232
2677
|
# * ip/netmask.
|
2678
|
+
#
|
2679
|
+
# Example:
|
2680
|
+
# desc = ip.desc()
|
2233
2681
|
#
|
2234
2682
|
def desc()
|
2235
2683
|
if (@version == 4)
|
@@ -2262,6 +2710,9 @@ class IPAddr
|
|
2262
2710
|
#
|
2263
2711
|
# - Returns:
|
2264
2712
|
# * IPv4 Hostmask in extended (y.y.y.y) format.
|
2713
|
+
#
|
2714
|
+
# Example:
|
2715
|
+
# hostmask = ip.hostmask_ext()
|
2265
2716
|
#
|
2266
2717
|
def hostmask_ext()
|
2267
2718
|
if (@version == 4)
|
@@ -2290,6 +2741,9 @@ class IPAddr
|
|
2290
2741
|
#
|
2291
2742
|
# - Returns:
|
2292
2743
|
# * IP address.
|
2744
|
+
#
|
2745
|
+
# Example:
|
2746
|
+
# addr = ip.ip()
|
2293
2747
|
#
|
2294
2748
|
def ip()
|
2295
2749
|
if (@version == 4)
|
@@ -2311,13 +2765,16 @@ class IPAddr
|
|
2311
2765
|
# netmask()
|
2312
2766
|
#============================================================================#
|
2313
2767
|
|
2314
|
-
# Provide Netmask
|
2768
|
+
# Provide Netmask in cidr format.
|
2315
2769
|
#
|
2316
2770
|
# - Arguments:
|
2317
2771
|
# * none
|
2318
2772
|
#
|
2319
2773
|
# - Returns:
|
2320
|
-
# *
|
2774
|
+
# * Netmask in CIDR format.
|
2775
|
+
#
|
2776
|
+
# Example:
|
2777
|
+
# netmask = ip.netmask()
|
2321
2778
|
#
|
2322
2779
|
def netmask()
|
2323
2780
|
if (@version == 4)
|
@@ -2326,7 +2783,7 @@ class IPAddr
|
|
2326
2783
|
bits = IPAdmin.unpack_ipv6_netmask(@netmask)
|
2327
2784
|
end
|
2328
2785
|
|
2329
|
-
return(bits)
|
2786
|
+
return("/#{bits}")
|
2330
2787
|
end
|
2331
2788
|
|
2332
2789
|
#=====================================#
|
@@ -2346,13 +2803,16 @@ class IPAddr
|
|
2346
2803
|
#
|
2347
2804
|
# - Returns:
|
2348
2805
|
# * IPv4 Netmask in extended (y.y.y.y) format.
|
2806
|
+
#
|
2807
|
+
# Example:
|
2808
|
+
# netmask = ip.netmask_ext()
|
2349
2809
|
#
|
2350
2810
|
def netmask_ext()
|
2351
2811
|
if (@version == 4)
|
2352
2812
|
netmask = IPAdmin.unpack_ipv4_addr(@netmask)
|
2353
2813
|
else
|
2354
2814
|
raise "IPv6 does not support extended netmask notation. " +
|
2355
|
-
"Use
|
2815
|
+
"Use netmask() method instead."
|
2356
2816
|
end
|
2357
2817
|
|
2358
2818
|
return(netmask)
|
@@ -2375,6 +2835,9 @@ class IPAddr
|
|
2375
2835
|
#
|
2376
2836
|
# - Returns:
|
2377
2837
|
# * byte-packed Hostmask.
|
2838
|
+
#
|
2839
|
+
# Example:
|
2840
|
+
# packed = ip.packed_hostmask()
|
2378
2841
|
#
|
2379
2842
|
def packed_hostmask()
|
2380
2843
|
return(@hostmask)
|
@@ -2397,6 +2860,9 @@ class IPAddr
|
|
2397
2860
|
#
|
2398
2861
|
# - Returns:
|
2399
2862
|
# * byte-packed IP address.
|
2863
|
+
#
|
2864
|
+
# Example:
|
2865
|
+
# packed = ip.packed_ip()
|
2400
2866
|
#
|
2401
2867
|
def packed_ip()
|
2402
2868
|
return(@ip)
|
@@ -2419,6 +2885,9 @@ class IPAddr
|
|
2419
2885
|
#
|
2420
2886
|
# - Returns:
|
2421
2887
|
# * byte-packed Netask.
|
2888
|
+
#
|
2889
|
+
# Example:
|
2890
|
+
# packed = ip.packed_netmask()
|
2422
2891
|
#
|
2423
2892
|
def packed_netmask()
|
2424
2893
|
return(@netmask)
|