ipadmin 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +147 -61
- data/lib/cidr.rb +88 -25
- data/lib/eui.rb +381 -0
- data/lib/ip_admin.rb +2 -1
- data/lib/methods.rb +75 -735
- data/tests/cidr_test.rb +26 -0
- data/tests/eui_test.rb +50 -0
- data/tests/methods_test.rb +13 -1
- metadata +24 -18
data/lib/eui.rb
ADDED
@@ -0,0 +1,381 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
Copyright (c) 2006 Dustin Spinhirne -
|
3
|
+
Licensed under the same terms as Ruby, No Warranty is provided.
|
4
|
+
=end
|
5
|
+
|
6
|
+
|
7
|
+
module IPAdmin
|
8
|
+
class EUI
|
9
|
+
|
10
|
+
# instance variables
|
11
|
+
# @type - eui-48 or eui-64
|
12
|
+
# @oui - Organizationally Unique Identifier
|
13
|
+
# @ei - Extention Identifier
|
14
|
+
|
15
|
+
#==============================================================================#
|
16
|
+
# initialize()
|
17
|
+
#==============================================================================#
|
18
|
+
|
19
|
+
# - Arguments:
|
20
|
+
# * Hash with the following fields:
|
21
|
+
# - :EUI -- Extended Unique Identifier - String (optional)
|
22
|
+
# - :PackedEUI -- Integer representing an Extended Unique Identifier (optional)
|
23
|
+
# - :Length -- bit length of PackedEUI - Integer (optional)
|
24
|
+
#
|
25
|
+
# - Note:
|
26
|
+
# * At a minimum, EUI or PackedEUI must be provided.
|
27
|
+
# * PackedEUI takes precedence over EUI.
|
28
|
+
# * Length is only needed when using PackedEUI
|
29
|
+
#
|
30
|
+
# Example:
|
31
|
+
# addr = IPAdmin::EUI.new(:EUI => 'aa-bb-cc-dd-ee-ff')
|
32
|
+
# addr = IPAdmin::EUI.new(:EUI => 'aa:bb:cc:dd:ee:ff')
|
33
|
+
# addr = IPAdmin::EUI.new(:EUI => 'aabb.ccdd.eeff')
|
34
|
+
# addr = IPAdmin::EUI.new(:EUI => 'aa-bb-cc-dd-ee-ff-00-01')
|
35
|
+
#
|
36
|
+
def initialize(options)
|
37
|
+
if (!options.kind_of? Hash)
|
38
|
+
raise ArgumentError, "Expected Hash, but #{options.class} provided."
|
39
|
+
end
|
40
|
+
|
41
|
+
if (options.has_key?(:PackedEUI))
|
42
|
+
packed_eui = options[:PackedEUI]
|
43
|
+
|
44
|
+
if (options.has_key?(:Length) && options[:Length].kind_of?(Integer))
|
45
|
+
@type = options[:Length]
|
46
|
+
@type = 48 if (@type != 48 && @type != 64)
|
47
|
+
else
|
48
|
+
@type = 48
|
49
|
+
end
|
50
|
+
|
51
|
+
if (packed_eui.kind_of?(Integer))
|
52
|
+
if (@type == 48)
|
53
|
+
@oui = packed_eui >> 24
|
54
|
+
@ei = packed_eui & 0xffffff
|
55
|
+
else
|
56
|
+
@oui = packed_eui >> 40
|
57
|
+
@ei = packed_eui & 0xffffffffff
|
58
|
+
end
|
59
|
+
else
|
60
|
+
raise ArgumentError, "Expected Integer, but #{eui.class} " +
|
61
|
+
"provided for argument :PackedEUI."
|
62
|
+
end
|
63
|
+
|
64
|
+
elsif(options.has_key?(:EUI))
|
65
|
+
eui = options[:EUI]
|
66
|
+
|
67
|
+
if (eui.kind_of?(String))
|
68
|
+
# validate
|
69
|
+
IPAdmin.validate_eui(:EUI => eui)
|
70
|
+
|
71
|
+
# remove formatting characters
|
72
|
+
eui.gsub!(/[\.\:\-]/, '')
|
73
|
+
|
74
|
+
# check if eui-48 or eui-64
|
75
|
+
if (eui.length == 12)
|
76
|
+
@type = 48
|
77
|
+
elsif (eui.length == 16)
|
78
|
+
@type = 64
|
79
|
+
else
|
80
|
+
raise "#{eui} is invalid (address is neither EUI-48 nor EUI-64)."
|
81
|
+
end
|
82
|
+
|
83
|
+
# split into oui & ei, pack, and store
|
84
|
+
@oui = eui.slice!(0..5).to_i(16)
|
85
|
+
@ei = eui.to_i(16)
|
86
|
+
|
87
|
+
else
|
88
|
+
raise ArgumentError, "Expected String, but #{eui.class} " +
|
89
|
+
"provided for argument :EUI."
|
90
|
+
end
|
91
|
+
|
92
|
+
else
|
93
|
+
raise ArgumentError, "Missing argument: [EUI|PackedEUI]."
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
#======================================#
|
99
|
+
#
|
100
|
+
#======================================#
|
101
|
+
|
102
|
+
|
103
|
+
#==============================================================================#
|
104
|
+
# address()
|
105
|
+
#==============================================================================#
|
106
|
+
|
107
|
+
# Returns EUI address.
|
108
|
+
#
|
109
|
+
# - Arguments:
|
110
|
+
# * Optional hash with the following fields:
|
111
|
+
# - :Delimiter -- delimitation character. valid values are (-,:,and .) (optional)
|
112
|
+
#
|
113
|
+
# - Returns:
|
114
|
+
# * String
|
115
|
+
#
|
116
|
+
# Example:
|
117
|
+
# puts addr.address(:Delimiter => '.') --> 'aabb.ccdd.eeff'
|
118
|
+
#
|
119
|
+
def address(options=nil)
|
120
|
+
delimiter = '-'
|
121
|
+
|
122
|
+
octets = []
|
123
|
+
octets.concat(unpack_oui)
|
124
|
+
octets.concat(unpack_ei)
|
125
|
+
|
126
|
+
if (options)
|
127
|
+
if (!options.kind_of? Hash)
|
128
|
+
raise ArgumentError, "Expected Hash, but #{options.class} provided."
|
129
|
+
end
|
130
|
+
|
131
|
+
if (options.has_key?(:Delimiter))
|
132
|
+
delimiter = options[:Delimiter]
|
133
|
+
delimiter = '-' if (delimiter != '-' && delimiter != ':' && delimiter != '.' )
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
if (delimiter == '-' || delimiter == ':')
|
138
|
+
address = octets.join(delimiter)
|
139
|
+
elsif (delimiter == '.')
|
140
|
+
toggle = 0
|
141
|
+
octets.each do |x|
|
142
|
+
if (!address)
|
143
|
+
address = x
|
144
|
+
toggle = 1
|
145
|
+
elsif (toggle == 0)
|
146
|
+
address = address << '.' << x
|
147
|
+
toggle = 1
|
148
|
+
else
|
149
|
+
address = address << x
|
150
|
+
toggle = 0
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
return(address)
|
157
|
+
end
|
158
|
+
|
159
|
+
#======================================#
|
160
|
+
#
|
161
|
+
#======================================#
|
162
|
+
|
163
|
+
|
164
|
+
#==============================================================================#
|
165
|
+
# ei()
|
166
|
+
#==============================================================================#
|
167
|
+
|
168
|
+
# Returns Extended Identifier portion of an EUI address (the vendor assigned ID).
|
169
|
+
#
|
170
|
+
# - Arguments:
|
171
|
+
# * Optional hash with the following fields:
|
172
|
+
# - :Delimiter -- delimitation character. valid values are (-, and :) (optional)
|
173
|
+
#
|
174
|
+
# - Returns:
|
175
|
+
# * String
|
176
|
+
#
|
177
|
+
# Example:
|
178
|
+
# puts addr.ei(:Delimiter => '-') --> 'aa-bb-cc'
|
179
|
+
#
|
180
|
+
def ei(options=nil)
|
181
|
+
octets = unpack_ei()
|
182
|
+
delimiter = '-'
|
183
|
+
|
184
|
+
if (options)
|
185
|
+
if (!options.kind_of? Hash)
|
186
|
+
raise ArgumentError, "Expected Hash, but #{options.class} provided."
|
187
|
+
end
|
188
|
+
|
189
|
+
if (options.has_key?(:Delimiter))
|
190
|
+
if (options[:Delimiter] == ':')
|
191
|
+
delimiter = options[:Delimiter]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
ei = octets.join(delimiter)
|
196
|
+
|
197
|
+
return(ei)
|
198
|
+
end
|
199
|
+
|
200
|
+
#======================================#
|
201
|
+
#
|
202
|
+
#======================================#
|
203
|
+
|
204
|
+
|
205
|
+
#==============================================================================#
|
206
|
+
# link_local()
|
207
|
+
#==============================================================================#
|
208
|
+
|
209
|
+
# Provide an IPv6 Link Local address based on the current EUI address.
|
210
|
+
#
|
211
|
+
# - Arguments:
|
212
|
+
# * Optional hash with the following fields:
|
213
|
+
# - :Short -- if true, return IPv6 addresses in short-hand notation (optional)
|
214
|
+
# - :Objectify -- if true, return CIDR objects (optional)
|
215
|
+
#
|
216
|
+
# - Returns:
|
217
|
+
# * String
|
218
|
+
#
|
219
|
+
# Example:
|
220
|
+
# puts addr.link_local() --> fe80:0000:0000:0000:aabb:ccff:fedd:eeff
|
221
|
+
#
|
222
|
+
def link_local(options=nil)
|
223
|
+
objectify = false
|
224
|
+
short = false
|
225
|
+
|
226
|
+
if (options)
|
227
|
+
if (!options.kind_of? Hash)
|
228
|
+
raise ArgumentError, "Expected Hash, but #{options.class} provided."
|
229
|
+
end
|
230
|
+
|
231
|
+
if (options.has_key?(:Objectify) && options[:Objectify] == true)
|
232
|
+
objectify = true
|
233
|
+
end
|
234
|
+
|
235
|
+
if (options.has_key?(:Short) && options[:Short] == true)
|
236
|
+
short = true
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
if (@type == 48)
|
241
|
+
link_local = @ei | 0xfffe000000 | (@oui << 40)
|
242
|
+
else
|
243
|
+
link_local = @ei | (@oui << 40)
|
244
|
+
end
|
245
|
+
link_local = link_local | (0xfe80 << 112)
|
246
|
+
|
247
|
+
if (!objectify)
|
248
|
+
link_local = IPAdmin.unpack_ip_addr(:Integer => link_local, :Version => 6)
|
249
|
+
link_local = IPAdmin.shorten(link_local) if (short)
|
250
|
+
else
|
251
|
+
link_local = IPAdmin::CIDR.new(:PackedIP => link_local,
|
252
|
+
:Version => 6)
|
253
|
+
end
|
254
|
+
|
255
|
+
return(link_local)
|
256
|
+
end
|
257
|
+
|
258
|
+
#======================================#
|
259
|
+
#
|
260
|
+
#======================================#
|
261
|
+
|
262
|
+
|
263
|
+
#==============================================================================#
|
264
|
+
# oui()
|
265
|
+
#==============================================================================#
|
266
|
+
|
267
|
+
# Returns Organizationally Unique Identifier portion of an EUI address (the vendor ID).
|
268
|
+
#
|
269
|
+
# - Arguments:
|
270
|
+
# * Optional hash with the following fields:
|
271
|
+
# - :Delimiter -- delimitation character. valid values are (-, and :) (optional)
|
272
|
+
#
|
273
|
+
# - Returns:
|
274
|
+
# * String
|
275
|
+
#
|
276
|
+
# Example:
|
277
|
+
# puts addr.oui(:Delimiter => '-') --> 'dd-ee-ff'
|
278
|
+
#
|
279
|
+
def oui(options=nil)
|
280
|
+
octets = unpack_oui()
|
281
|
+
delimiter = '-'
|
282
|
+
|
283
|
+
if (options)
|
284
|
+
if (!options.kind_of? Hash)
|
285
|
+
raise ArgumentError, "Expected Hash, but #{options.class} provided."
|
286
|
+
end
|
287
|
+
|
288
|
+
if (options.has_key?(:Delimiter))
|
289
|
+
if (options[:Delimiter] == ':')
|
290
|
+
delimiter = options[:Delimiter]
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
oui = octets.join(delimiter)
|
295
|
+
|
296
|
+
return(oui)
|
297
|
+
end
|
298
|
+
|
299
|
+
#======================================#
|
300
|
+
#
|
301
|
+
#======================================#
|
302
|
+
|
303
|
+
|
304
|
+
#==============================================================================#
|
305
|
+
# type()
|
306
|
+
#==============================================================================#
|
307
|
+
|
308
|
+
# Provide address type (EUI-48 or EUI-64).
|
309
|
+
#
|
310
|
+
# - Arguments:
|
311
|
+
# * none
|
312
|
+
#
|
313
|
+
# - Returns:
|
314
|
+
# * String
|
315
|
+
#
|
316
|
+
# Example:
|
317
|
+
# puts addr.type --> EUI-48
|
318
|
+
#
|
319
|
+
def type()
|
320
|
+
if (@type == 48)
|
321
|
+
return('EUI-48')
|
322
|
+
else
|
323
|
+
return('EUI-64')
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
#======================================#
|
328
|
+
#
|
329
|
+
#======================================#
|
330
|
+
|
331
|
+
|
332
|
+
|
333
|
+
# PRIVATE METHODS
|
334
|
+
private
|
335
|
+
|
336
|
+
#==============================================================================#
|
337
|
+
# unpack_ei()
|
338
|
+
#==============================================================================#
|
339
|
+
|
340
|
+
def unpack_ei()
|
341
|
+
hex = @ei
|
342
|
+
octets = []
|
343
|
+
loop_count = (@type - 24)/8
|
344
|
+
loop_count.times do
|
345
|
+
octet = (hex & 0xff).to_s(16)
|
346
|
+
octet = '0' << octet if (octet.length != 2)
|
347
|
+
octets.unshift(octet)
|
348
|
+
hex = hex >> 8
|
349
|
+
end
|
350
|
+
return(octets)
|
351
|
+
end
|
352
|
+
|
353
|
+
#======================================#
|
354
|
+
#
|
355
|
+
#======================================#
|
356
|
+
|
357
|
+
|
358
|
+
#==============================================================================#
|
359
|
+
# unpack_oui()
|
360
|
+
#==============================================================================#
|
361
|
+
|
362
|
+
def unpack_oui()
|
363
|
+
hex = @oui
|
364
|
+
octets = []
|
365
|
+
3.times do
|
366
|
+
octet = (hex & 0xff).to_s(16)
|
367
|
+
octet = '0' << octet if (octet.length != 2)
|
368
|
+
octets.unshift(octet)
|
369
|
+
hex = hex >> 8
|
370
|
+
end
|
371
|
+
return(octets)
|
372
|
+
end
|
373
|
+
|
374
|
+
#======================================#
|
375
|
+
#
|
376
|
+
#======================================#
|
377
|
+
|
378
|
+
end
|
379
|
+
|
380
|
+
end # module IPAdmin
|
381
|
+
__END__
|
data/lib/ip_admin.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin rdoc
|
2
|
-
Copyright (c) 2006 Dustin Spinhirne
|
2
|
+
Copyright (c) 2006 Dustin Spinhirne -
|
3
3
|
Licensed under the same terms as Ruby, No Warranty is provided.
|
4
4
|
=end
|
5
5
|
|
@@ -7,5 +7,6 @@
|
|
7
7
|
require File.join(File.dirname(__FILE__), 'methods.rb')
|
8
8
|
require File.join(File.dirname(__FILE__), 'cidr.rb')
|
9
9
|
require File.join(File.dirname(__FILE__), 'tree.rb')
|
10
|
+
require File.join(File.dirname(__FILE__), 'eui.rb')
|
10
11
|
|
11
12
|
__END__
|
data/lib/methods.rb
CHANGED
@@ -154,6 +154,12 @@ module_function :create_net_struct
|
|
154
154
|
# - Returns:
|
155
155
|
# * Array of CIDR or NetStruct objects
|
156
156
|
#
|
157
|
+
# - Notes:
|
158
|
+
# * I have designed this with enough flexibility that you can pass in CIDR
|
159
|
+
# addresses that arent even related (ex. 192.168.1.0/26, 192.168.1.64/26,
|
160
|
+
# 10.1.0.0/26, 10.1.0.64/26) and they will be merged properly (ie 192.168.1.0/25,
|
161
|
+
# and 10.1.0.0/25 would be returned).
|
162
|
+
#
|
157
163
|
# Example:
|
158
164
|
# supernets = IPAdmin.merge(:List => list)
|
159
165
|
#
|
@@ -171,11 +177,11 @@ def merge(options)
|
|
171
177
|
raise ArgumentError, "Missing argument: List."
|
172
178
|
end
|
173
179
|
|
174
|
-
if (options.has_key?(:Short))
|
180
|
+
if (options.has_key?(:Short) && options[:Short] == true)
|
175
181
|
short = true
|
176
182
|
end
|
177
183
|
|
178
|
-
if (options.has_key?(:Objectify))
|
184
|
+
if (options.has_key?(:Objectify) && options[:Objectify] == true)
|
179
185
|
objectify = true
|
180
186
|
end
|
181
187
|
|
@@ -685,11 +691,11 @@ def range(options)
|
|
685
691
|
bitstep = options[:Bitstep]
|
686
692
|
end
|
687
693
|
|
688
|
-
if( options.has_key?(:Objectify) )
|
694
|
+
if( options.has_key?(:Objectify) && options[:Objectify] == true )
|
689
695
|
objectify = true
|
690
696
|
end
|
691
697
|
|
692
|
-
if( options.has_key?(:Short) )
|
698
|
+
if( options.has_key?(:Short) && options[:Short] == true )
|
693
699
|
short = true
|
694
700
|
end
|
695
701
|
|
@@ -1115,6 +1121,71 @@ module_function :unshorten
|
|
1115
1121
|
#======================================#
|
1116
1122
|
|
1117
1123
|
|
1124
|
+
#==============================================================================#
|
1125
|
+
# validate_eui()
|
1126
|
+
#==============================================================================#
|
1127
|
+
|
1128
|
+
# Validate an EUI-48 or EUI-64 address.
|
1129
|
+
#
|
1130
|
+
# - Arguments
|
1131
|
+
# * Hash with the following fields:
|
1132
|
+
# - :EUI -- Address to validate - String
|
1133
|
+
#
|
1134
|
+
# - Returns:
|
1135
|
+
# * True
|
1136
|
+
#
|
1137
|
+
# - Example:
|
1138
|
+
# * IPAdmin.validate_eui(:EUI => '01-00-5e-12-34-56')
|
1139
|
+
#
|
1140
|
+
def validate_eui(options)
|
1141
|
+
if (!options.kind_of? Hash)
|
1142
|
+
raise ArgumentError, "Expected Hash, but #{options.class} provided."
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
if (!options.has_key?(:EUI))
|
1146
|
+
raise ArgumentError, "Missing argument: EUI."
|
1147
|
+
end
|
1148
|
+
eui = options[:EUI]
|
1149
|
+
|
1150
|
+
if (eui.kind_of?(String))
|
1151
|
+
# check for invalid characters
|
1152
|
+
if (eui =~ /[^0-9a-fA-f\.\-\:]/)
|
1153
|
+
raise "#{eui} is invalid (contains invalid characters)."
|
1154
|
+
end
|
1155
|
+
|
1156
|
+
# split on formatting characters & check lengths
|
1157
|
+
if (eui =~ /\-/)
|
1158
|
+
fields = eui.split('-')
|
1159
|
+
if (fields.length != 6 && fields.length != 8)
|
1160
|
+
raise "#{eui} is invalid (unrecognized formatting)."
|
1161
|
+
end
|
1162
|
+
elsif (eui =~ /\:/)
|
1163
|
+
fields = eui.split(':')
|
1164
|
+
if (fields.length != 6 && fields.length != 8)
|
1165
|
+
raise "#{eui} is invalid (unrecognized formatting)."
|
1166
|
+
end
|
1167
|
+
elsif (eui =~ /\./)
|
1168
|
+
fields = eui.split('.')
|
1169
|
+
if (fields.length != 3 && fields.length != 4)
|
1170
|
+
raise "#{eui} is invalid (unrecognized formatting)."
|
1171
|
+
end
|
1172
|
+
else
|
1173
|
+
raise "#{eui} is invalid (unrecognized formatting)."
|
1174
|
+
end
|
1175
|
+
|
1176
|
+
else
|
1177
|
+
raise ArgumentError, "Expected String, but #{eui.class} " +
|
1178
|
+
"provided for argument :EUI."
|
1179
|
+
end
|
1180
|
+
return(true)
|
1181
|
+
end
|
1182
|
+
module_function :validate_eui
|
1183
|
+
|
1184
|
+
#======================================#
|
1185
|
+
#
|
1186
|
+
#======================================#
|
1187
|
+
|
1188
|
+
|
1118
1189
|
#==============================================================================#
|
1119
1190
|
# validate_ip_addr()
|
1120
1191
|
#==============================================================================#
|
@@ -1432,737 +1503,6 @@ NetStruct = Struct.new(:network, :netmask, :version, :object, :subnets)
|
|
1432
1503
|
#======================================#
|
1433
1504
|
|
1434
1505
|
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
# DEPRICATED
|
1439
|
-
|
1440
|
-
#==============================================================================#
|
1441
|
-
# arpa()
|
1442
|
-
#==============================================================================#
|
1443
|
-
|
1444
|
-
# DEPRICATED - USE CIDR.arpa:
|
1445
|
-
# Using the provided CIDR object,
|
1446
|
-
# return either an in-addr.arpa. or ip6.arpa. string. The netmask will be used
|
1447
|
-
# to determine the length of the returned arpa string.
|
1448
|
-
#
|
1449
|
-
# - Arguments:
|
1450
|
-
# * CIDR object
|
1451
|
-
#
|
1452
|
-
# - Returns:
|
1453
|
-
# * String
|
1454
|
-
#
|
1455
|
-
# - Notes:
|
1456
|
-
# * IPAdmin.arpa will use the original IP address passed during the initialization
|
1457
|
-
# of the CIDR objects. This IP can be found using the CIDR.ip() method.
|
1458
|
-
#
|
1459
|
-
# Example:
|
1460
|
-
# arpa = IPAdmin.arpa(cidr)
|
1461
|
-
#
|
1462
|
-
def arpa(object)
|
1463
|
-
|
1464
|
-
if (!object.kind_of? IPAdmin::CIDR)
|
1465
|
-
raise ArgumentError, "Expected IPAdmin::CIDR object, " +
|
1466
|
-
"but #{object.class} provided."
|
1467
|
-
end
|
1468
|
-
|
1469
|
-
base = object.ip()
|
1470
|
-
netmask = object.bits()
|
1471
|
-
|
1472
|
-
if (object.version == 4)
|
1473
|
-
net = base.split('.')
|
1474
|
-
|
1475
|
-
if (netmask)
|
1476
|
-
while (netmask < 32)
|
1477
|
-
net.pop
|
1478
|
-
netmask = netmask + 8
|
1479
|
-
end
|
1480
|
-
end
|
1481
|
-
|
1482
|
-
arpa = net.reverse.join('.')
|
1483
|
-
arpa << ".in-addr.arpa."
|
1484
|
-
|
1485
|
-
elsif (object.version == 6)
|
1486
|
-
fields = base.split(':')
|
1487
|
-
net = []
|
1488
|
-
fields.each do |field|
|
1489
|
-
(field.split("")).each do |x|
|
1490
|
-
net.push(x)
|
1491
|
-
end
|
1492
|
-
end
|
1493
|
-
|
1494
|
-
if (netmask)
|
1495
|
-
while (netmask < 128)
|
1496
|
-
net.pop
|
1497
|
-
netmask = netmask + 4
|
1498
|
-
end
|
1499
|
-
end
|
1500
|
-
|
1501
|
-
arpa = net.reverse.join('.')
|
1502
|
-
arpa << ".ip6.arpa."
|
1503
|
-
|
1504
|
-
end
|
1505
|
-
|
1506
|
-
return(arpa)
|
1507
|
-
end
|
1508
|
-
module_function :arpa
|
1509
|
-
|
1510
|
-
#======================================#
|
1511
|
-
#
|
1512
|
-
#======================================#
|
1513
|
-
|
1514
|
-
#==============================================================================#
|
1515
|
-
# validate_ipv4_addr()
|
1516
|
-
#==============================================================================#
|
1517
|
-
|
1518
|
-
# DEPRICATED - USE validate_ip_addr INSTEAD
|
1519
|
-
# Validate IPv4 addresses. The address should not contain a netmask.
|
1520
|
-
#
|
1521
|
-
# - Arguments:
|
1522
|
-
# * IPv4 address
|
1523
|
-
#
|
1524
|
-
# - Returns:
|
1525
|
-
# * packed IP on valid, or exception on error.
|
1526
|
-
#
|
1527
|
-
# Example:
|
1528
|
-
# IPAdmin.validate_ipv4_addr('192.168.1.1')
|
1529
|
-
#
|
1530
|
-
def validate_ipv4_addr(ip)
|
1531
|
-
|
1532
|
-
# is this a string?
|
1533
|
-
unless (ip.kind_of? String)
|
1534
|
-
raise ArgumentError, "Expected String, but #{ip.class} provided."
|
1535
|
-
end
|
1536
|
-
|
1537
|
-
# check validity of characters in the addr
|
1538
|
-
if ( (ip =~ /\.{2,}?/ ) || (ip =~ /[^0-9\.]/) )
|
1539
|
-
raise "#{ip} is not a valid IPv4 address."
|
1540
|
-
end
|
1541
|
-
|
1542
|
-
# do we have 4 octets?
|
1543
|
-
octets = ip.split( /\./ ).reverse
|
1544
|
-
if (octets.length != 4)
|
1545
|
-
raise "#{ip} is not a valid IPv4 address."
|
1546
|
-
end
|
1547
|
-
|
1548
|
-
# are octets in range 0..255?
|
1549
|
-
packed_ip = 0
|
1550
|
-
(0..3).each do |x|
|
1551
|
-
octets[x] = octets[x].to_i
|
1552
|
-
unless ( (octets[x] >= 0) && (octets[x] < 256 ) )
|
1553
|
-
raise "#{ip} is not a valid IPv4 address."
|
1554
|
-
end
|
1555
|
-
octets[x] = octets[x] << 8*x
|
1556
|
-
packed_ip = packed_ip | octets[x]
|
1557
|
-
end
|
1558
|
-
|
1559
|
-
# dont allow first octet to be 0
|
1560
|
-
if (octets[3] == 0)
|
1561
|
-
raise "#{ip} is not a valid IPv4 address."
|
1562
|
-
end
|
1563
|
-
|
1564
|
-
return(packed_ip)
|
1565
|
-
|
1566
|
-
end
|
1567
|
-
module_function :validate_ipv4_addr
|
1568
|
-
|
1569
|
-
#======================================#
|
1570
|
-
#
|
1571
|
-
#======================================#
|
1572
|
-
|
1573
|
-
|
1574
|
-
#==============================================================================#
|
1575
|
-
# validate_ipv4_netmask()
|
1576
|
-
#==============================================================================#
|
1577
|
-
|
1578
|
-
# DEPRICATED - USE validate_ip_netmask INSTEAD
|
1579
|
-
# Validate IPv4 Netmask.
|
1580
|
-
#
|
1581
|
-
# - Arguments:
|
1582
|
-
# * IPv4 netmask in cidr or extended notation
|
1583
|
-
#
|
1584
|
-
# - Returns:
|
1585
|
-
# * packed netmask on valid, or exception on error.
|
1586
|
-
#
|
1587
|
-
# Example:
|
1588
|
-
# IPAdmin.validate_ipv4_netmask('255.255.255.0')
|
1589
|
-
# IPAdmin.validate_ipv4_netmask('24')
|
1590
|
-
# IPAdmin.validate_ipv4_netmask('/24')
|
1591
|
-
# IPAdmin.validate_ipv4_netmask(24)
|
1592
|
-
#
|
1593
|
-
def validate_ipv4_netmask(netmask)
|
1594
|
-
all_f = 2**32 - 1
|
1595
|
-
packed_mask = nil
|
1596
|
-
|
1597
|
-
# is this a CIDR or Extended mask?
|
1598
|
-
if(netmask =~ /\./)
|
1599
|
-
# validate & pack extended mask
|
1600
|
-
begin
|
1601
|
-
validate_ipv4_addr(netmask)
|
1602
|
-
packed_netmask = pack_ipv4_addr(netmask)
|
1603
|
-
|
1604
|
-
rescue Exception
|
1605
|
-
raise "#{netmask} is not a valid IPv4 netmask."
|
1606
|
-
end
|
1607
|
-
|
1608
|
-
# cycle through the bits of hostmask and compare
|
1609
|
-
# with packed_mask. when we hit the firt '1' within
|
1610
|
-
# packed_mask (our netmask boundary), xor hostmask and
|
1611
|
-
# packed_mask. the result should be all 1's. this whole
|
1612
|
-
# process is in place to make sure that we dont have
|
1613
|
-
# and crazy masks such as 255.254.255.0
|
1614
|
-
hostmask = 1
|
1615
|
-
32.times do
|
1616
|
-
check = packed_netmask & hostmask
|
1617
|
-
if ( check != 0)
|
1618
|
-
hostmask = hostmask >> 1
|
1619
|
-
unless ( (packed_netmask ^ hostmask) == all_f)
|
1620
|
-
raise "#{netmask} is not a valid IPv4 netmask."
|
1621
|
-
end
|
1622
|
-
break
|
1623
|
-
else
|
1624
|
-
hostmask = hostmask << 1
|
1625
|
-
hostmask = hostmask | 1
|
1626
|
-
end
|
1627
|
-
end
|
1628
|
-
|
1629
|
-
else
|
1630
|
-
# remove '/' if present
|
1631
|
-
if (netmask =~ /^\// )
|
1632
|
-
netmask[0] = " "
|
1633
|
-
netmask.lstrip!
|
1634
|
-
end
|
1635
|
-
|
1636
|
-
# check if we have any non numeric characters
|
1637
|
-
if (netmask =~ /\D/)
|
1638
|
-
raise "#{netmask} is not a valid IPv4 netmask."
|
1639
|
-
end
|
1640
|
-
|
1641
|
-
# are we between 1 and 32 inclusive
|
1642
|
-
if (netmask.kind_of? String)
|
1643
|
-
netmask = netmask.to_i
|
1644
|
-
end
|
1645
|
-
|
1646
|
-
if ( (netmask > 32) || (netmask == 0) )
|
1647
|
-
raise "#{netmask} is not a valid IPv4 netmask."
|
1648
|
-
end
|
1649
|
-
|
1650
|
-
packed_netmask = all_f ^ (all_f >> netmask)
|
1651
|
-
end
|
1652
|
-
|
1653
|
-
return(packed_netmask)
|
1654
|
-
end
|
1655
|
-
module_function :validate_ipv4_netmask
|
1656
|
-
|
1657
|
-
#======================================#
|
1658
|
-
#
|
1659
|
-
#======================================#
|
1660
|
-
|
1661
|
-
|
1662
|
-
#==============================================================================#
|
1663
|
-
# validate_ipv6_addr()
|
1664
|
-
#==============================================================================#
|
1665
|
-
|
1666
|
-
# DEPRICATED - USE validate_ip_addr INSTEAD
|
1667
|
-
# Validate IPv6 addresses. The address should not contain a netmask.
|
1668
|
-
#
|
1669
|
-
# - Arguments:
|
1670
|
-
# * IPv6 address
|
1671
|
-
#
|
1672
|
-
# - Returns:
|
1673
|
-
# * packed IP on valid, or exception on error.
|
1674
|
-
#
|
1675
|
-
# Example:
|
1676
|
-
# IPAdmin.validate_ipv6_addr('fec0::')
|
1677
|
-
#
|
1678
|
-
def validate_ipv6_addr(ip)
|
1679
|
-
# is this a string?
|
1680
|
-
unless (ip.kind_of? String)
|
1681
|
-
raise ArgumentError, "Expected String, but #{ip.class} provided."
|
1682
|
-
end
|
1683
|
-
|
1684
|
-
# check validity of characters in the addr
|
1685
|
-
if ( (ip =~ /:{3,}?/ ) || (ip =~ /[^0-9a-fA-F:]/) )
|
1686
|
-
raise "#{ip} is not a valid IPv6 address."
|
1687
|
-
end
|
1688
|
-
|
1689
|
-
# look for a '::' to see if this address is in shorthand
|
1690
|
-
# if found, split on it & make sure that we have at most
|
1691
|
-
# two elements
|
1692
|
-
if (ip =~ /::/)
|
1693
|
-
shrthnd = ip.split( /::/ )
|
1694
|
-
unless ( (shrthnd.length > 0) && (shrthnd.length < 3) )
|
1695
|
-
raise "#{ip} is not a valid IPv6 address."
|
1696
|
-
end
|
1697
|
-
end
|
1698
|
-
|
1699
|
-
if (shrthnd)
|
1700
|
-
# if shorthand, we should have between 1 and 7
|
1701
|
-
# hex fields
|
1702
|
-
hex_fields = []
|
1703
|
-
shrthnd.each do |x|
|
1704
|
-
elements = x.split( /:/ )
|
1705
|
-
elements.each {|x| hex_fields.push(x)}
|
1706
|
-
end
|
1707
|
-
if ( (hex_fields.length < 1) || (hex_fields.length > 7) )
|
1708
|
-
raise "#{ip} is not a valid IPv6 address."
|
1709
|
-
end
|
1710
|
-
|
1711
|
-
else
|
1712
|
-
# since no shorthand notation was detected we should
|
1713
|
-
# have exactly 8 hex fields
|
1714
|
-
hex_fields = ip.split( /:/ )
|
1715
|
-
if (hex_fields.length != 8)
|
1716
|
-
raise "#{ip} is not a valid IPv6 address."
|
1717
|
-
end
|
1718
|
-
|
1719
|
-
end
|
1720
|
-
|
1721
|
-
# check that we have no more than 4 characters in each
|
1722
|
-
# hex field
|
1723
|
-
hex_fields.each do |x|
|
1724
|
-
if (x.length > 4)
|
1725
|
-
raise "#{ip} is not a valid IPv6 address."
|
1726
|
-
end
|
1727
|
-
end
|
1728
|
-
|
1729
|
-
packed_ip = IPAdmin.pack_ipv6_addr(ip)
|
1730
|
-
return(packed_ip)
|
1731
|
-
end
|
1732
|
-
module_function :validate_ipv6_addr
|
1733
|
-
|
1734
|
-
#======================================#
|
1735
|
-
#
|
1736
|
-
#======================================#
|
1737
|
-
|
1738
|
-
|
1739
|
-
#==============================================================================#
|
1740
|
-
# validate_ipv6_netmask()
|
1741
|
-
#==============================================================================#
|
1742
|
-
|
1743
|
-
# DEPRICATED - USE validate_ip_netmask INSTEAD
|
1744
|
-
# Validate IPv6 netmask.
|
1745
|
-
#
|
1746
|
-
# - Arguments:
|
1747
|
-
# * IPv6 netmask in cidr notation
|
1748
|
-
#
|
1749
|
-
# - Returns:
|
1750
|
-
# * packed netmask on valid, or exception on error.
|
1751
|
-
#
|
1752
|
-
# Example:
|
1753
|
-
# IPAdmin.validate_ipv6_netmask('64')
|
1754
|
-
# IPAdmin.validate_ipv6_netmask('/64')
|
1755
|
-
# IPAdmin.validate_ipv6_netmask(64)
|
1756
|
-
#
|
1757
|
-
def validate_ipv6_netmask(netmask)
|
1758
|
-
all_f = 2**128 -1
|
1759
|
-
|
1760
|
-
# remove '/' if present
|
1761
|
-
if (netmask =~ /^\// )
|
1762
|
-
netmask[0] = " "
|
1763
|
-
netmask.lstrip!
|
1764
|
-
end
|
1765
|
-
|
1766
|
-
if (netmask =~ /\D/)
|
1767
|
-
raise "#{netmask} is not a valid IPv6 netmask."
|
1768
|
-
|
1769
|
-
else
|
1770
|
-
# are we between 1 and 128 inclusive
|
1771
|
-
if (netmask.kind_of? String)
|
1772
|
-
netmask = netmask.to_i
|
1773
|
-
end
|
1774
|
-
|
1775
|
-
if ( (netmask > 128) || (netmask == 0) )
|
1776
|
-
raise "#{netmask} is not a valid IPv6 netmask."
|
1777
|
-
end
|
1778
|
-
|
1779
|
-
end
|
1780
|
-
|
1781
|
-
packed_netmask = all_f ^ (all_f >> netmask)
|
1782
|
-
return(packed_netmask)
|
1783
|
-
end
|
1784
|
-
module_function :validate_ipv6_netmask
|
1785
|
-
|
1786
|
-
#======================================#
|
1787
|
-
#
|
1788
|
-
#======================================#
|
1789
|
-
|
1790
|
-
|
1791
|
-
#==============================================================================#
|
1792
|
-
# pack_ipv4_addr()
|
1793
|
-
#==============================================================================#
|
1794
|
-
|
1795
|
-
# DEPRICATED - USE pack_ip_addr INSTEAD
|
1796
|
-
# Convert IPv4 addresses into an integer. No attempt at
|
1797
|
-
# validation is performed.
|
1798
|
-
#
|
1799
|
-
# - Arguments:
|
1800
|
-
# * IPv4 address
|
1801
|
-
#
|
1802
|
-
# - Returns:
|
1803
|
-
# * packed IPv4 address or exception on error.
|
1804
|
-
#
|
1805
|
-
# Example:
|
1806
|
-
# packed = IPAdmin.pack_ipv4_addr('192.168.1.1')
|
1807
|
-
#
|
1808
|
-
def pack_ipv4_addr(ip)
|
1809
|
-
|
1810
|
-
# is this a string?
|
1811
|
-
unless (ip.kind_of? String)
|
1812
|
-
raise ArgumentError, "Expected String, but #{ip.class} provided."
|
1813
|
-
end
|
1814
|
-
|
1815
|
-
# pack our ip
|
1816
|
-
octets = ip.split( /\./ ).reverse
|
1817
|
-
packed_ip = 0
|
1818
|
-
|
1819
|
-
(0..3).each do |x|
|
1820
|
-
octets[x] = (octets[x]).to_i
|
1821
|
-
octets[x] = octets[x] << 8*x
|
1822
|
-
packed_ip = packed_ip | octets[x]
|
1823
|
-
end
|
1824
|
-
|
1825
|
-
return(packed_ip)
|
1826
|
-
end
|
1827
|
-
module_function :pack_ipv4_addr
|
1828
|
-
|
1829
|
-
#======================================#
|
1830
|
-
#
|
1831
|
-
#======================================#
|
1832
|
-
|
1833
|
-
|
1834
|
-
#==============================================================================#
|
1835
|
-
# pack_ipv4_netmask()
|
1836
|
-
#==============================================================================#
|
1837
|
-
|
1838
|
-
# DEPRICATED - USE pack_ip_netmask INSTEAD
|
1839
|
-
# Convert IPv4 netmask into an integer. Only very basic
|
1840
|
-
# validation is performed.
|
1841
|
-
#
|
1842
|
-
# - Arguments:
|
1843
|
-
# * IPv4 netmask in cidr or extended notation
|
1844
|
-
#
|
1845
|
-
# - Returns:
|
1846
|
-
# * packed IPv4 netmask or exception on error.
|
1847
|
-
#
|
1848
|
-
# Example:
|
1849
|
-
# packed = IPAdmin.pack_ipv4_netmask('255.255.255.0')
|
1850
|
-
# packed = IPAdmin.pack_ipv4_netmask('24')
|
1851
|
-
# packed = IPAdmin.pack_ipv4_netmask('/24')
|
1852
|
-
# packed = IPAdmin.pack_ipv4_netmask(24)
|
1853
|
-
#
|
1854
|
-
def pack_ipv4_netmask(netmask)
|
1855
|
-
all_f = 2**32-1
|
1856
|
-
|
1857
|
-
# is this a CIDR or Extended mask?
|
1858
|
-
if(netmask =~ /\./)
|
1859
|
-
# pack extended mask
|
1860
|
-
begin
|
1861
|
-
packed_netmask = pack_ipv4_addr(netmask)
|
1862
|
-
rescue Exception
|
1863
|
-
raise "#{netmask} is not a valid IPv4 netmask."
|
1864
|
-
end
|
1865
|
-
|
1866
|
-
else
|
1867
|
-
# remove '/' if present
|
1868
|
-
if (netmask =~ /^\// )
|
1869
|
-
netmask[0] = " "
|
1870
|
-
netmask.lstrip!
|
1871
|
-
end
|
1872
|
-
|
1873
|
-
# check if we have any non numeric characters
|
1874
|
-
if (netmask =~ /\D/)
|
1875
|
-
raise "#{netmask} is not a valid IPv4 netmask."
|
1876
|
-
end
|
1877
|
-
|
1878
|
-
if (netmask.kind_of? String)
|
1879
|
-
netmask = netmask.to_i
|
1880
|
-
end
|
1881
|
-
|
1882
|
-
packed_netmask = all_f ^ (all_f >> netmask)
|
1883
|
-
end
|
1884
|
-
|
1885
|
-
return(packed_netmask)
|
1886
|
-
end
|
1887
|
-
module_function :pack_ipv4_netmask
|
1888
|
-
|
1889
|
-
#======================================#
|
1890
|
-
#
|
1891
|
-
#======================================#
|
1892
|
-
|
1893
|
-
|
1894
|
-
#==============================================================================#
|
1895
|
-
# pack_ipv6_addr()
|
1896
|
-
#==============================================================================#
|
1897
|
-
|
1898
|
-
# DEPRICATED - USE pack_ip_addr INSTEAD
|
1899
|
-
# Convert IPv6 addresses into an integer. No attempt at
|
1900
|
-
# validation is performed.
|
1901
|
-
#
|
1902
|
-
# - Arguments:
|
1903
|
-
# * IPv6 address
|
1904
|
-
#
|
1905
|
-
# - Returns:
|
1906
|
-
# * packed IPv6 address or exception on error.
|
1907
|
-
#
|
1908
|
-
# Example:
|
1909
|
-
# packed = IPAdmin.pack_ipv6_addr('fec0::1')
|
1910
|
-
#
|
1911
|
-
def pack_ipv6_addr(ip)
|
1912
|
-
# is this a string?
|
1913
|
-
unless (ip.kind_of? String)
|
1914
|
-
raise ArgumentError, "Expected String, but #{ip.class} provided."
|
1915
|
-
end
|
1916
|
-
|
1917
|
-
# look for a '::' to see if this address is in shorthand
|
1918
|
-
# if found, split on it
|
1919
|
-
hex_fields = []
|
1920
|
-
if (ip =~ /::/)
|
1921
|
-
shrthnd = ip.split( /::/ )
|
1922
|
-
if (ip =~ /^::/)
|
1923
|
-
sec_half = shrthnd[1].split( /:/ )
|
1924
|
-
zero_pads = 8 - sec_half.length
|
1925
|
-
(1..zero_pads).each {hex_fields.push('0')}
|
1926
|
-
sec_half.each {|field| hex_fields.push(field)}
|
1927
|
-
elsif (ip =~ /::$/)
|
1928
|
-
hex_fields = shrthnd[0].split( /:/ )
|
1929
|
-
zero_pads = 8 - hex_fields.length
|
1930
|
-
(1..zero_pads).each {hex_fields.push('0')}
|
1931
|
-
else
|
1932
|
-
first_half = shrthnd[0].split( /:/ )
|
1933
|
-
sec_half = shrthnd[1].split( /:/ )
|
1934
|
-
zero_pads = 8 - (first_half.length + sec_half.length)
|
1935
|
-
first_half.each {|field| hex_fields.push(field)}
|
1936
|
-
(1..zero_pads).each {hex_fields.push('0')}
|
1937
|
-
sec_half.each {|field| hex_fields.push(field)}
|
1938
|
-
end
|
1939
|
-
|
1940
|
-
else
|
1941
|
-
hex_fields = ip.split( /:/ )
|
1942
|
-
end
|
1943
|
-
|
1944
|
-
# pack
|
1945
|
-
hex_fields.reverse!
|
1946
|
-
packed_ip = 0
|
1947
|
-
(0..7).each do |x|
|
1948
|
-
hex = hex_fields[x]
|
1949
|
-
base16 = hex.to_i(16)
|
1950
|
-
|
1951
|
-
base16 = base16 << 16*x
|
1952
|
-
packed_ip = packed_ip | base16
|
1953
|
-
end
|
1954
|
-
|
1955
|
-
|
1956
|
-
return(packed_ip)
|
1957
1506
|
end
|
1958
|
-
module_function :pack_ipv6_addr
|
1959
|
-
|
1960
|
-
#======================================#
|
1961
|
-
#
|
1962
|
-
#======================================#
|
1963
|
-
|
1964
|
-
|
1965
|
-
#==============================================================================#
|
1966
|
-
# pack_ipv6_netmask()
|
1967
|
-
#==============================================================================#
|
1968
|
-
|
1969
|
-
# DEPRICATED - USE pack_ip_netmask INSTEAD
|
1970
|
-
# Convert IPv6 netmask into an integer. Only very basic
|
1971
|
-
# validation is performed.
|
1972
|
-
#
|
1973
|
-
# - Arguments:
|
1974
|
-
# * IPv6 netmask in cidr notation
|
1975
|
-
#
|
1976
|
-
# - Returns:
|
1977
|
-
# * packed IPv6 netmask or exception on error.
|
1978
|
-
#
|
1979
|
-
# Example:
|
1980
|
-
# packed = IPAdmin.pack_ipv6_netmask('64')
|
1981
|
-
# packed = IPAdmin.pack_ipv6_netmask('/64')
|
1982
|
-
# packed = IPAdmin.pack_ipv6_netmask(64)
|
1983
|
-
#
|
1984
|
-
def pack_ipv6_netmask(netmask)
|
1985
|
-
all_f = 2**128-1
|
1986
|
-
|
1987
|
-
# remove '/' if present
|
1988
|
-
if (netmask =~ /^\// )
|
1989
|
-
netmask[0] = " "
|
1990
|
-
netmask.lstrip!
|
1991
|
-
end
|
1992
|
-
|
1993
|
-
if (netmask !~ /\D/)
|
1994
|
-
# pack
|
1995
|
-
if (netmask.kind_of? String)
|
1996
|
-
netmask = netmask.to_i
|
1997
|
-
end
|
1998
|
-
|
1999
|
-
packed_netmask = all_f ^ (all_f >> netmask)
|
2000
|
-
|
2001
|
-
else
|
2002
|
-
raise "#{netmask} is not a valid IPv6 netmask."
|
2003
|
-
|
2004
|
-
end
|
2005
|
-
|
2006
|
-
return(packed_netmask)
|
2007
|
-
end
|
2008
|
-
module_function :pack_ipv6_netmask
|
2009
|
-
|
2010
|
-
#======================================#
|
2011
|
-
#
|
2012
|
-
#======================================#
|
2013
|
-
|
2014
|
-
|
2015
|
-
#==============================================================================#
|
2016
|
-
# unpack_ipv4_addr()
|
2017
|
-
#==============================================================================#
|
2018
|
-
|
2019
|
-
# DEPRICATED - USE unpack_ip_addr INSTEAD
|
2020
|
-
# Unack a packed IPv4 address back into a printable string. No attempt at
|
2021
|
-
# validation is performed.
|
2022
|
-
#
|
2023
|
-
# - Arguments:
|
2024
|
-
# * Byte-packed IPv4 address
|
2025
|
-
#
|
2026
|
-
# - Returns:
|
2027
|
-
# * IPv4 address.
|
2028
|
-
#
|
2029
|
-
# Example:
|
2030
|
-
# unpacked = IPAdmin.unpack_ipv4_addr(packed)
|
2031
|
-
#
|
2032
|
-
def unpack_ipv4_addr(packed_ip)
|
2033
|
-
octets = []
|
2034
|
-
(0..3).each do |x|
|
2035
|
-
octets[x] = packed_ip & 0xFF
|
2036
|
-
octets[x] = (octets[x]).to_s
|
2037
|
-
packed_ip = packed_ip >> 8
|
2038
|
-
end
|
2039
|
-
|
2040
|
-
octets.reverse!
|
2041
|
-
ip = octets.join('.')
|
2042
|
-
|
2043
|
-
return(ip)
|
2044
|
-
end
|
2045
|
-
module_function :unpack_ipv4_addr
|
2046
|
-
|
2047
|
-
#======================================#
|
2048
|
-
#
|
2049
|
-
#======================================#
|
2050
|
-
|
2051
|
-
|
2052
|
-
#==============================================================================#
|
2053
|
-
# unpack_ipv4_netmask()
|
2054
|
-
#==============================================================================#
|
2055
|
-
|
2056
|
-
# DEPRICATED - USE unpack_ip_netmask INSTEAD
|
2057
|
-
# Unack a packed IPv4 netmask into a integer representing the number of
|
2058
|
-
# bits in the CIDR mask. No attempt at validation is performed.
|
2059
|
-
#
|
2060
|
-
# - Arguments:
|
2061
|
-
# * Byte-packed IPv4 netmask
|
2062
|
-
#
|
2063
|
-
# - Returns:
|
2064
|
-
# * IPv4 netmask as number of bits (cidr format).
|
2065
|
-
#
|
2066
|
-
# Example:
|
2067
|
-
# unpacked = IPAdmin.unpack_ipv4_netmask(packed)
|
2068
|
-
#
|
2069
|
-
def unpack_ipv4_netmask(packed_mask)
|
2070
|
-
mask = 32
|
2071
|
-
32.times do
|
2072
|
-
if ( (packed_mask & 1) != 0)
|
2073
|
-
break
|
2074
|
-
end
|
2075
|
-
packed_mask = packed_mask >> 1
|
2076
|
-
mask = mask - 1
|
2077
|
-
end
|
2078
|
-
|
2079
|
-
return(mask)
|
2080
|
-
end
|
2081
|
-
module_function :unpack_ipv4_netmask
|
2082
|
-
|
2083
|
-
#======================================#
|
2084
|
-
#
|
2085
|
-
#======================================#
|
2086
|
-
|
2087
|
-
|
2088
|
-
#==============================================================================#
|
2089
|
-
# unpack_ipv6_addr()
|
2090
|
-
#==============================================================================#
|
2091
|
-
|
2092
|
-
# DEPRICATED - USE unpack_ip_addr INSTEAD
|
2093
|
-
# Unack a packed IPv6 address back into a printable string. No attempt at
|
2094
|
-
# validation is performed.
|
2095
|
-
#
|
2096
|
-
# - Arguments:
|
2097
|
-
# * Byte-packed IPv6 address
|
2098
|
-
#
|
2099
|
-
# - Returns:
|
2100
|
-
# * IPv6 address.
|
2101
|
-
#
|
2102
|
-
# Example:
|
2103
|
-
# unpacked = IPAdmin.unpack_ipv6_addr(packed)
|
2104
|
-
#
|
2105
|
-
def unpack_ipv6_addr(packed_ip)
|
2106
|
-
hex_fields = []
|
2107
|
-
(0..7).each do |x|
|
2108
|
-
hex_fields[x] = packed_ip & 0xFFFF
|
2109
|
-
hex_fields[x] = (hex_fields[x]).to_s(16)
|
2110
|
-
packed_ip = packed_ip >> 16
|
2111
|
-
|
2112
|
-
# if hex_fields[x] < 4 characters, then pad with 0's
|
2113
|
-
(4 - hex_fields[x].length).times do
|
2114
|
-
hex_fields[x] = '0' << hex_fields[x]
|
2115
|
-
end
|
2116
|
-
end
|
2117
|
-
|
2118
|
-
hex_fields.reverse!
|
2119
|
-
ip = hex_fields.join(':')
|
2120
|
-
|
2121
|
-
return(ip)
|
2122
|
-
end
|
2123
|
-
module_function :unpack_ipv6_addr
|
2124
|
-
|
2125
|
-
#======================================#
|
2126
|
-
#
|
2127
|
-
#======================================#
|
2128
|
-
|
2129
|
-
|
2130
|
-
#==============================================================================#
|
2131
|
-
# unpack_ipv6_netmask()
|
2132
|
-
#==============================================================================#
|
2133
|
-
|
2134
|
-
# DEPRICATED - USE unpack_ip_netmask INSTEAD
|
2135
|
-
# Unack a packed IPv6 netmask into a integer representing the number of
|
2136
|
-
# bits in the CIDR mask. No attempt at validation is performed.
|
2137
|
-
#
|
2138
|
-
# - Arguments:
|
2139
|
-
# * Byte-packed IPv6 netmask
|
2140
|
-
#
|
2141
|
-
# - Returns:
|
2142
|
-
# * IPv6 netmask as number of bits (cidr format).
|
2143
|
-
#
|
2144
|
-
# Example:
|
2145
|
-
# unpacked = IPAdmin.unpack_ipv6_netmask(packed)
|
2146
|
-
#
|
2147
|
-
def unpack_ipv6_netmask(packed_mask)
|
2148
|
-
|
2149
|
-
mask = 128
|
2150
|
-
128.times do
|
2151
|
-
if ( (packed_mask & 1) == 1)
|
2152
|
-
break
|
2153
|
-
end
|
2154
|
-
mask = mask - 1
|
2155
|
-
packed_mask = packed_mask >> 1
|
2156
|
-
end
|
2157
|
-
|
2158
|
-
return(mask)
|
2159
|
-
end
|
2160
|
-
module_function :unpack_ipv6_netmask
|
2161
|
-
|
2162
|
-
#======================================#
|
2163
|
-
#
|
2164
|
-
#======================================#
|
2165
|
-
|
2166
|
-
end # module IPAdmin
|
2167
1507
|
__END__
|
2168
1508
|
|