ipadmin 0.2.2 → 0.3.0
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 +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
|
|