netaddr 1.5.3 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of netaddr might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/LICENSE +201 -0
- data/README.md +28 -8
- data/lib/eui48.rb +65 -0
- data/lib/eui64.rb +77 -0
- data/lib/ipv4.rb +77 -0
- data/lib/ipv4net.rb +245 -0
- data/lib/ipv6.rb +110 -0
- data/lib/ipv6net.rb +246 -0
- data/lib/mask128.rb +68 -0
- data/lib/mask32.rb +99 -0
- data/lib/netaddr.rb +104 -20
- data/lib/util.rb +310 -0
- data/test/eui48_test.rb +30 -0
- data/test/eui64_test.rb +32 -0
- data/test/examples.rb +137 -0
- data/test/ipv4_test.rb +54 -0
- data/test/ipv4net_test.rb +166 -0
- data/test/ipv6_test.rb +90 -0
- data/test/ipv6net_test.rb +146 -0
- data/test/mask128_test.rb +45 -0
- data/test/mask32_test.rb +51 -0
- data/test/netaddr_test.rb +127 -0
- data/test/run_all.rb +10 -0
- metadata +28 -22
- data/Errors +0 -7
- data/changelog +0 -52
- data/lib/cidr.rb +0 -2014
- data/lib/cidr_shortcuts.rb +0 -401
- data/lib/eui.rb +0 -402
- data/lib/ip_math.rb +0 -227
- data/lib/methods.rb +0 -1013
- data/lib/tree.rb +0 -816
- data/lib/validation_shortcuts.rb +0 -201
- data/license +0 -13
- data/test/cidr_test.rb +0 -545
- data/test/eui_test.rb +0 -101
- data/test/methods_test.rb +0 -331
- data/test/tree_test.rb +0 -347
data/lib/eui.rb
DELETED
@@ -1,402 +0,0 @@
|
|
1
|
-
module NetAddr
|
2
|
-
|
3
|
-
#=EUI - Extended Unique Identifier
|
4
|
-
#
|
5
|
-
#A class & series of methods for creating and manipulating Extended Unique Identifier
|
6
|
-
#(EUI) addresses. Two types of address formats are supported EUI-48 and EUI-64. The
|
7
|
-
#most common use for this class will be to manipulate MAC addresses (which are essentially
|
8
|
-
#a type of EUI-48 address).
|
9
|
-
#
|
10
|
-
#EUI addresses are separated into two parts, the
|
11
|
-
#Organizationally Unique Identifier (OUI) and the Extended Identifier (EI). The OUI
|
12
|
-
#is assigned by the IEEE and is used to identify a particular hardware manufacturer.
|
13
|
-
#The EI is assigned by the hardware manufacturer as a per device unique address.
|
14
|
-
#
|
15
|
-
#Probably the most useful feature of this class, and thus the reason it was created,
|
16
|
-
#is to help automate certain address assignments within IP. For example, IPv6
|
17
|
-
#Link Local addresses use MAC addresses for IP auto-assignment and multicast MAC addresses
|
18
|
-
#are determined based on the multicast IP address.
|
19
|
-
#
|
20
|
-
class EUI
|
21
|
-
|
22
|
-
private_class_method :new
|
23
|
-
|
24
|
-
#===Synopsis
|
25
|
-
# This method performs absolutely no error checking, and is meant to be used only by
|
26
|
-
# other internal methods for the sake of the speedier creation of EUI objects.
|
27
|
-
# Please consider using #create unless you know what you are doing with 100% certainty.
|
28
|
-
#
|
29
|
-
# Example:
|
30
|
-
# NetAddr::EUI48.new('aabbccddeeff')
|
31
|
-
#
|
32
|
-
#===Arguments:
|
33
|
-
#* EUI as a String or Integer. Strings should contain no formatting characters.
|
34
|
-
#
|
35
|
-
def initialize(eui)
|
36
|
-
|
37
|
-
if (eui.kind_of?(Integer))
|
38
|
-
@eui_i = eui
|
39
|
-
@eui = eui.to_s(16)
|
40
|
-
if ( self.kind_of?(NetAddr::EUI48) )
|
41
|
-
@eui = '0' * (12 - @eui.length) << @eui if (@eui.length < 12)
|
42
|
-
else
|
43
|
-
@eui = '0' * (16 - @eui.length) << @eui if (@eui.length < 16)
|
44
|
-
end
|
45
|
-
|
46
|
-
elsif(eui.kind_of?(String))
|
47
|
-
@eui = eui
|
48
|
-
@eui_i = eui.to_i(16)
|
49
|
-
else
|
50
|
-
raise ArgumentError, "Expected String or Integer, but #{eui.class} provided."
|
51
|
-
end
|
52
|
-
|
53
|
-
# set ei & oui
|
54
|
-
if ( self.kind_of?(NetAddr::EUI48) )
|
55
|
-
@ei = @eui.slice(6..11)
|
56
|
-
else
|
57
|
-
@ei = @eui.slice(6..15)
|
58
|
-
end
|
59
|
-
|
60
|
-
@oui = @eui.slice(0..5)
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
#===Synopsis
|
65
|
-
#Create a new EUI48 or EUI64 object.
|
66
|
-
#
|
67
|
-
# Example:
|
68
|
-
# addr = NetAddr::EUI.create('aa-bb-cc-dd-ee-ff')
|
69
|
-
# addr = NetAddr::EUI.create('aa:bb:cc:dd:ee:ff')
|
70
|
-
# addr = NetAddr::EUI.create('aabb.ccdd.eeff')
|
71
|
-
# addr = NetAddr::EUI.create('aa-bb-cc-dd-ee-ff-00-01')
|
72
|
-
#
|
73
|
-
#===Arguments
|
74
|
-
#* eui = EUI as a String
|
75
|
-
#
|
76
|
-
#===Returns
|
77
|
-
#* EUI48 or EUI64 object
|
78
|
-
#
|
79
|
-
def EUI.create(eui)
|
80
|
-
if (!eui.kind_of? String)
|
81
|
-
raise ArgumentError, "Expected String, but #{eui.class} provided."
|
82
|
-
end
|
83
|
-
|
84
|
-
# create local copy & validate
|
85
|
-
eui = eui.dup
|
86
|
-
NetAddr.validate_eui(eui)
|
87
|
-
|
88
|
-
# remove formatting characters
|
89
|
-
eui.gsub!(/[\.\:\-]/, '')
|
90
|
-
|
91
|
-
if (eui.length == 12)
|
92
|
-
eui = NetAddr::EUI48.new(eui)
|
93
|
-
else
|
94
|
-
eui = NetAddr::EUI64.new(eui)
|
95
|
-
end
|
96
|
-
|
97
|
-
return(eui)
|
98
|
-
end
|
99
|
-
|
100
|
-
#===Synopsis
|
101
|
-
# Returns EUI address. The default address format is xxxx.xxxx.xxxx
|
102
|
-
#
|
103
|
-
# Example:
|
104
|
-
# addr = NetAddr::EUI.create('aabb.ccdd.eeff')
|
105
|
-
# addr.address(:Delimiter => '-') => "aa-bb-cc-dd-ee-ff"
|
106
|
-
# addr.address(:Delimiter => ':') => "aa:bb:cc:dd:ee:ff"
|
107
|
-
#
|
108
|
-
#===Arguments:
|
109
|
-
#* options = Hash with the following fields:
|
110
|
-
# :Delimiter -- delimitation character. valid values are (- : .)
|
111
|
-
#
|
112
|
-
#===Returns:
|
113
|
-
#* String
|
114
|
-
#
|
115
|
-
def address(options=nil)
|
116
|
-
known_args = [:Delimiter]
|
117
|
-
delimiter = '-'
|
118
|
-
|
119
|
-
if (options)
|
120
|
-
if (!options.kind_of? Hash)
|
121
|
-
raise ArgumentError, "Expected Hash, but #{options.class} provided."
|
122
|
-
end
|
123
|
-
NetAddr.validate_args(options.keys,known_args)
|
124
|
-
|
125
|
-
if (options.has_key?(:Delimiter))
|
126
|
-
delimiter = options[:Delimiter]
|
127
|
-
delimiter = '-' if (delimiter != ':' && delimiter != '.')
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
if (delimiter == '-' || delimiter == ':')
|
132
|
-
addr = octets.join(delimiter)
|
133
|
-
elsif (delimiter == '.')
|
134
|
-
addr = octets.each_slice(2).to_a.map(&:join).join('.')
|
135
|
-
end
|
136
|
-
|
137
|
-
return(addr)
|
138
|
-
end
|
139
|
-
|
140
|
-
#===Synopsis
|
141
|
-
#Returns Extended Identifier portion of an EUI address (the vendor assigned ID).
|
142
|
-
#The default address format is xx-xx-xx
|
143
|
-
#
|
144
|
-
# Example:
|
145
|
-
# addr = NetAddr::EUI.create('aabb.ccdd.eeff')
|
146
|
-
# addr.ei(:Delimiter => '-') => "dd-ee-ff"
|
147
|
-
#
|
148
|
-
#===Arguments:
|
149
|
-
#* options = Hash with the following fields:
|
150
|
-
# :Delimiter -- delimitation character. valid values are (-, and :)
|
151
|
-
#
|
152
|
-
#===Returns:
|
153
|
-
#* String
|
154
|
-
#
|
155
|
-
def ei(options=nil)
|
156
|
-
known_args = [:Delimiter]
|
157
|
-
delimiter = '-'
|
158
|
-
|
159
|
-
if (options)
|
160
|
-
if (!options.kind_of? Hash)
|
161
|
-
raise ArgumentError, "Expected Hash, but #{options.class} provided."
|
162
|
-
end
|
163
|
-
NetAddr.validate_args(options.keys,known_args)
|
164
|
-
|
165
|
-
if (options.has_key?(:Delimiter))
|
166
|
-
if (options[:Delimiter] == ':')
|
167
|
-
delimiter = options[:Delimiter]
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
if ( self.kind_of?(NetAddr::EUI48) )
|
173
|
-
ei = octets[3..5].join(delimiter)
|
174
|
-
else
|
175
|
-
ei = octets[3..7].join(delimiter)
|
176
|
-
end
|
177
|
-
|
178
|
-
return(ei)
|
179
|
-
end
|
180
|
-
|
181
|
-
#===Synopsis
|
182
|
-
# Provide an IPv6 Link Local address based on the current EUI address.
|
183
|
-
#
|
184
|
-
# Example:
|
185
|
-
# addr = NetAddr::EUI.create('aabb.ccdd.eeff')
|
186
|
-
# addr.link_local() => "fe80:0000:0000:0000:aabb:ccff:fedd:eeff"
|
187
|
-
#
|
188
|
-
#===Arguments:
|
189
|
-
#* options = Hash with the following fields:
|
190
|
-
# :Short -- if true, return IPv6 addresses in short-hand notation
|
191
|
-
# :Objectify -- if true, return CIDR objects
|
192
|
-
#
|
193
|
-
#===Returns:
|
194
|
-
#* CIDR address String or an NetAddr::CIDR object
|
195
|
-
#
|
196
|
-
def link_local(options=nil)
|
197
|
-
return( self.to_ipv6('fe80::/64', options) )
|
198
|
-
end
|
199
|
-
|
200
|
-
#===Synopsis
|
201
|
-
#Returns Organizationally Unique Identifier portion of an EUI address (the vendor ID).
|
202
|
-
#The default address format is xx-xx-xx.
|
203
|
-
#
|
204
|
-
# Example:
|
205
|
-
# addr = NetAddr::EUI.create('aabb.ccdd.eeff')
|
206
|
-
# addr.oui(:Delimiter => '-') => "aa-bb-cc"
|
207
|
-
#
|
208
|
-
#===Arguments:
|
209
|
-
#* options = Hash with the following fields:
|
210
|
-
# :Delimiter -- delimitation character. valid values are (-, and :)
|
211
|
-
#
|
212
|
-
#===Returns:
|
213
|
-
#* String
|
214
|
-
#
|
215
|
-
def oui(options=nil)
|
216
|
-
known_args = [:Delimiter]
|
217
|
-
delimiter = '-'
|
218
|
-
|
219
|
-
if (options)
|
220
|
-
if (!options.kind_of? Hash)
|
221
|
-
raise ArgumentError, "Expected Hash, but #{options.class} provided."
|
222
|
-
end
|
223
|
-
NetAddr.validate_args(options.keys,known_args)
|
224
|
-
|
225
|
-
if (options.has_key?(:Delimiter))
|
226
|
-
if (options[:Delimiter] == ':')
|
227
|
-
delimiter = options[:Delimiter]
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
231
|
-
oui = octets[0..2].join(delimiter)
|
232
|
-
|
233
|
-
return(oui)
|
234
|
-
end
|
235
|
-
|
236
|
-
#===Synopsis
|
237
|
-
#Returns the EUI as an Integer.
|
238
|
-
#
|
239
|
-
# Example:
|
240
|
-
# addr = NetAddr::EUI.create('aabb.ccdd.eeff')
|
241
|
-
# addr.to_i => 187723572702975
|
242
|
-
#
|
243
|
-
#===Arguments:
|
244
|
-
#* none
|
245
|
-
#
|
246
|
-
#===Returns:
|
247
|
-
#* Integer
|
248
|
-
#
|
249
|
-
def to_i()
|
250
|
-
return(@eui_i)
|
251
|
-
end
|
252
|
-
|
253
|
-
#===Synopsis
|
254
|
-
# Given a valid IPv6 subnet, return an IPv6 address based on the current EUI.
|
255
|
-
#
|
256
|
-
# Example:
|
257
|
-
# addr = NetAddr::EUI.create('aabb.ccdd.eeff')
|
258
|
-
# addr.to_ipv6('3ffe::/64') => "3ffe:0000:0000:0000:a8bb:ccff:fedd:eeff"
|
259
|
-
#
|
260
|
-
#===Arguments:
|
261
|
-
#* options = Hash with the following fields:
|
262
|
-
# :Short -- if true, return IPv6 addresses in short-hand notation
|
263
|
-
# :Objectify -- if true, return CIDR objects
|
264
|
-
#
|
265
|
-
#===Returns:
|
266
|
-
#* IPv6 address String or an NetAddr::CIDRv6 object
|
267
|
-
#
|
268
|
-
def to_ipv6(cidr, options=nil)
|
269
|
-
known_args = [:Short, :Objectify]
|
270
|
-
objectify = false
|
271
|
-
short = false
|
272
|
-
|
273
|
-
if ( !cidr.kind_of?(NetAddr::CIDR) )
|
274
|
-
begin
|
275
|
-
cidr = NetAddr::CIDR.create(cidr)
|
276
|
-
rescue Exception => error
|
277
|
-
raise ArgumentError, "CIDR raised the following errors: #{error}"
|
278
|
-
end
|
279
|
-
elsif (cidr.kind_of?(NetAddr::CIDRv4) )
|
280
|
-
raise ArgumentError, "Expected CIDRv6, but #{cidr.class} provided."
|
281
|
-
end
|
282
|
-
|
283
|
-
if (cidr.bits > 64)
|
284
|
-
raise ValidationError, "Prefix length of provided CIDR must be /64 or less but was #{cidr.netmask}."
|
285
|
-
end
|
286
|
-
|
287
|
-
if (options)
|
288
|
-
if (!options.kind_of? Hash)
|
289
|
-
raise ArgumentError, "Expected Hash, but #{options.class} provided."
|
290
|
-
end
|
291
|
-
NetAddr.validate_args(options.keys,known_args)
|
292
|
-
|
293
|
-
if (options.has_key?(:Objectify) && options[:Objectify] == true)
|
294
|
-
objectify = true
|
295
|
-
end
|
296
|
-
|
297
|
-
if (options.has_key?(:Short) && options[:Short] == true)
|
298
|
-
short = true
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
# get integer equiv of addr. conver eui48 to eui64 if needed
|
303
|
-
if ( self.kind_of?(NetAddr::EUI48) )
|
304
|
-
eui_i = self.to_eui64.to_i
|
305
|
-
else
|
306
|
-
eui_i = self.to_i
|
307
|
-
end
|
308
|
-
|
309
|
-
# toggle u/l bit
|
310
|
-
eui_i = eui_i ^ 0x0200000000000000
|
311
|
-
|
312
|
-
# create ipv6 address
|
313
|
-
ipv6 = cidr.to_i | eui_i
|
314
|
-
|
315
|
-
if (!objectify)
|
316
|
-
ipv6 = NetAddr.i_to_ip(ipv6, :Version => 6)
|
317
|
-
ipv6 = NetAddr.shorten(ipv6) if (short)
|
318
|
-
else
|
319
|
-
ipv6 = NetAddr::CIDRv6.new(ipv6)
|
320
|
-
end
|
321
|
-
|
322
|
-
return(ipv6)
|
323
|
-
end
|
324
|
-
|
325
|
-
#===Synopsis
|
326
|
-
#Returns the EUI as an unformatted String.
|
327
|
-
#
|
328
|
-
# Example:
|
329
|
-
# addr = NetAddr::EUI.create('aabb.ccdd.eeff')
|
330
|
-
# addr.to_s => "aabbccddeeff"
|
331
|
-
#
|
332
|
-
#===Arguments:
|
333
|
-
#* none
|
334
|
-
#
|
335
|
-
#===Returns:
|
336
|
-
#* String
|
337
|
-
#
|
338
|
-
def to_s()
|
339
|
-
return(@eui)
|
340
|
-
end
|
341
|
-
|
342
|
-
private
|
343
|
-
|
344
|
-
#Returns array with each element representing a single octet of the eui.
|
345
|
-
#
|
346
|
-
def octets()
|
347
|
-
return(@octets) if (@octets)
|
348
|
-
|
349
|
-
@octets = []
|
350
|
-
str = ''
|
351
|
-
@eui.each_byte do |chr|
|
352
|
-
str = str << chr
|
353
|
-
if (str.length == 2)
|
354
|
-
@octets.push(str)
|
355
|
-
str = ''
|
356
|
-
end
|
357
|
-
end
|
358
|
-
|
359
|
-
return(@octets)
|
360
|
-
end
|
361
|
-
|
362
|
-
end
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
# EUI-48 Address - Inherits all methods from NetAddr::EUI.
|
367
|
-
# Addresses of this class have a 24-bit OUI and a 24-bit EI.
|
368
|
-
class EUI48 < EUI
|
369
|
-
|
370
|
-
public_class_method :new
|
371
|
-
|
372
|
-
#===Synopsis
|
373
|
-
#Return an EUI64 address based on the current EUI48 address.
|
374
|
-
#
|
375
|
-
# Example:
|
376
|
-
# addr = NetAddr::EUI.create('aabb.ccdd.eeff')
|
377
|
-
# addr.to_eui64 => NetAddr::EUI64
|
378
|
-
#
|
379
|
-
#===Arguments:
|
380
|
-
#* none
|
381
|
-
#
|
382
|
-
#===Returns:
|
383
|
-
#* NetAddr::EUI64 object
|
384
|
-
#
|
385
|
-
def to_eui64()
|
386
|
-
eui = @oui + 'fffe' + @ei
|
387
|
-
return( NetAddr::EUI64.new(eui.to_i(16)) )
|
388
|
-
end
|
389
|
-
|
390
|
-
end
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
# EUI-64 Address - Inherits all methods from NetAddr::EUI.
|
395
|
-
# Addresses of this class have a 24-bit OUI and a 40-bit EI.
|
396
|
-
class EUI64 < EUI
|
397
|
-
public_class_method :new
|
398
|
-
end
|
399
|
-
|
400
|
-
|
401
|
-
end # module NetAddr
|
402
|
-
__END__
|
data/lib/ip_math.rb
DELETED
@@ -1,227 +0,0 @@
|
|
1
|
-
module NetAddr
|
2
|
-
private
|
3
|
-
|
4
|
-
|
5
|
-
# IP MATH METHODS
|
6
|
-
|
7
|
-
# given an integer and number of bits to consider, return its binary mirror
|
8
|
-
#
|
9
|
-
def binary_mirror(num, bit_count)
|
10
|
-
mirror = 0
|
11
|
-
bit_count.times do # make mirror image of num by capturning lsb and left-shifting it onto mirror
|
12
|
-
mirror = mirror << 1
|
13
|
-
lsb = num & 1
|
14
|
-
num = num >> 1
|
15
|
-
mirror = mirror | lsb
|
16
|
-
end
|
17
|
-
return(mirror)
|
18
|
-
end
|
19
|
-
module_function :binary_mirror
|
20
|
-
|
21
|
-
# convert a netmask (in bits) to an integer mask
|
22
|
-
#
|
23
|
-
def bits_to_mask(netmask,version)
|
24
|
-
return(0) if (netmask == 0)
|
25
|
-
all_f = 2**32-1
|
26
|
-
all_f = 2**128-1 if (version == 6)
|
27
|
-
return( all_f ^ (all_f >> netmask) )
|
28
|
-
end
|
29
|
-
module_function :bits_to_mask
|
30
|
-
|
31
|
-
# determine the ip version from ip address string.
|
32
|
-
#
|
33
|
-
# return 4, 6, or nil
|
34
|
-
#
|
35
|
-
def detect_ip_version(ip)
|
36
|
-
version = nil
|
37
|
-
if ( ip =~ /\./ && ip !~ /:/ )
|
38
|
-
version = 4
|
39
|
-
elsif (ip =~ /:/)
|
40
|
-
version = 6
|
41
|
-
else
|
42
|
-
raise ValidationError, "Could not auto-detect IP version for '#{ip}'."
|
43
|
-
end
|
44
|
-
return(version)
|
45
|
-
end
|
46
|
-
module_function :detect_ip_version
|
47
|
-
|
48
|
-
# given an ip count, determine the most appropriate mask (in bits)
|
49
|
-
#
|
50
|
-
def ip_count_to_size(ipcount,version,extended=false)
|
51
|
-
address_len = 32
|
52
|
-
address_len = 128 if (version == 6 )
|
53
|
-
|
54
|
-
if (ipcount > 2**address_len)
|
55
|
-
raise BoundaryError, "Required IP count exceeds number of IP addresses available " +
|
56
|
-
"for IPv#{version}."
|
57
|
-
end
|
58
|
-
|
59
|
-
bits_needed = 0
|
60
|
-
until (2**bits_needed >= ipcount)
|
61
|
-
bits_needed += 1
|
62
|
-
end
|
63
|
-
subnet_bits = address_len - bits_needed
|
64
|
-
|
65
|
-
return( ip_int_to_str(bits_to_mask(subnet_bits, 4), 4) ) if (extended && version == 4)
|
66
|
-
return(subnet_bits)
|
67
|
-
end
|
68
|
-
module_function :ip_count_to_size
|
69
|
-
|
70
|
-
# unpack an int into an ip address string
|
71
|
-
#
|
72
|
-
def ip_int_to_str(ip_int, version, ipv4_mapped=nil)
|
73
|
-
ip = nil
|
74
|
-
version = 4 if (!version && ip_int < 2**32)
|
75
|
-
if (version == 4)
|
76
|
-
octets = []
|
77
|
-
4.times do
|
78
|
-
octet = ip_int & 0xFF
|
79
|
-
octets.unshift(octet.to_s)
|
80
|
-
ip_int = ip_int >> 8
|
81
|
-
end
|
82
|
-
ip = octets.join('.')
|
83
|
-
else
|
84
|
-
fields = []
|
85
|
-
if (!ipv4_mapped)
|
86
|
-
loop_count = 8
|
87
|
-
else
|
88
|
-
loop_count = 6
|
89
|
-
ipv4_int = ip_int & 0xffffffff
|
90
|
-
ipv4_addr = ip_int_to_str(ipv4_int, 4)
|
91
|
-
fields.unshift(ipv4_addr)
|
92
|
-
ip_int = ip_int >> 32
|
93
|
-
end
|
94
|
-
|
95
|
-
loop_count.times do
|
96
|
-
octet = ip_int & 0xFFFF
|
97
|
-
octet = octet.to_s(16)
|
98
|
-
ip_int = ip_int >> 16
|
99
|
-
|
100
|
-
# if octet < 4 characters, then pad with 0's
|
101
|
-
(4 - octet.length).times do
|
102
|
-
octet = '0' << octet
|
103
|
-
end
|
104
|
-
fields.unshift(octet)
|
105
|
-
end
|
106
|
-
ip = fields.join(':')
|
107
|
-
end
|
108
|
-
return(ip)
|
109
|
-
end
|
110
|
-
module_function :ip_int_to_str
|
111
|
-
|
112
|
-
# convert an ip string into an int
|
113
|
-
#
|
114
|
-
def ip_str_to_int(ip,version)
|
115
|
-
ip_int = 0
|
116
|
-
if ( version == 4)
|
117
|
-
octets = ip.split('.')
|
118
|
-
(0..3).each do |x|
|
119
|
-
octet = octets.pop.to_i
|
120
|
-
octet = octet << 8*x
|
121
|
-
ip_int = ip_int | octet
|
122
|
-
end
|
123
|
-
|
124
|
-
else
|
125
|
-
# if ipv4-mapped ipv6 addr
|
126
|
-
if (ip =~ /\./)
|
127
|
-
dotted_dec = true
|
128
|
-
end
|
129
|
-
|
130
|
-
# split up by ':'
|
131
|
-
fields = []
|
132
|
-
if (ip =~ /::/)
|
133
|
-
shrthnd = ip.split( /::/ )
|
134
|
-
if (shrthnd.length == 0)
|
135
|
-
return(0)
|
136
|
-
else
|
137
|
-
first_half = shrthnd[0].split( /:/ ) if (shrthnd[0])
|
138
|
-
sec_half = shrthnd[1].split( /:/ ) if (shrthnd[1])
|
139
|
-
first_half = [] if (!first_half)
|
140
|
-
sec_half = [] if (!sec_half)
|
141
|
-
end
|
142
|
-
missing_fields = 8 - first_half.length - sec_half.length
|
143
|
-
missing_fields -= 1 if dotted_dec
|
144
|
-
fields = fields.concat(first_half)
|
145
|
-
missing_fields.times {fields.push('0')}
|
146
|
-
fields = fields.concat(sec_half)
|
147
|
-
|
148
|
-
else
|
149
|
-
fields = ip.split(':')
|
150
|
-
end
|
151
|
-
|
152
|
-
if (dotted_dec)
|
153
|
-
ipv4_addr = fields.pop
|
154
|
-
ipv4_int = NetAddr.ip_to_i(ipv4_addr, :Version => 4)
|
155
|
-
octets = []
|
156
|
-
2.times do
|
157
|
-
octet = ipv4_int & 0xFFFF
|
158
|
-
octets.unshift(octet.to_s(16))
|
159
|
-
ipv4_int = ipv4_int >> 16
|
160
|
-
end
|
161
|
-
fields.concat(octets)
|
162
|
-
end
|
163
|
-
|
164
|
-
# pack
|
165
|
-
(0..7).each do |x|
|
166
|
-
field = fields.pop.to_i(16)
|
167
|
-
field = field << 16*x
|
168
|
-
ip_int = ip_int | field
|
169
|
-
end
|
170
|
-
|
171
|
-
end
|
172
|
-
return(ip_int)
|
173
|
-
end
|
174
|
-
module_function :ip_str_to_int
|
175
|
-
|
176
|
-
# convert integer into a cidr formatted netmask (bits)
|
177
|
-
#
|
178
|
-
def mask_to_bits(netmask_int)
|
179
|
-
return(netmask_int) if (netmask_int == 0)
|
180
|
-
|
181
|
-
mask = nil
|
182
|
-
if (netmask_int < 2**32)
|
183
|
-
mask = 32
|
184
|
-
validate_netmask_int(netmask_int, 4, true)
|
185
|
-
else
|
186
|
-
mask = 128
|
187
|
-
validate_netmask_int(netmask_int, 6, true)
|
188
|
-
end
|
189
|
-
|
190
|
-
mask.times do
|
191
|
-
if ( (netmask_int & 1) == 1)
|
192
|
-
break
|
193
|
-
end
|
194
|
-
netmask_int = netmask_int >> 1
|
195
|
-
mask = mask - 1
|
196
|
-
end
|
197
|
-
return(mask)
|
198
|
-
end
|
199
|
-
module_function :mask_to_bits
|
200
|
-
|
201
|
-
# convert string into integer mask
|
202
|
-
#
|
203
|
-
def netmask_str_to_int(netmask,version)
|
204
|
-
netmask_int = nil
|
205
|
-
all_f = 2**32-1
|
206
|
-
all_f = 2**128-1 if (version == 6)
|
207
|
-
if(netmask =~ /\./)
|
208
|
-
netmask_int = NetAddr.ip_to_i(netmask)
|
209
|
-
else
|
210
|
-
# remove '/' if present
|
211
|
-
if (netmask =~ /^\// )
|
212
|
-
netmask[0] = " "
|
213
|
-
netmask.lstrip!
|
214
|
-
end
|
215
|
-
netmask = netmask.to_i
|
216
|
-
netmask_int = all_f ^ (all_f >> netmask)
|
217
|
-
end
|
218
|
-
return(netmask_int)
|
219
|
-
end
|
220
|
-
module_function :netmask_str_to_int
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
end # module NetAddr
|
225
|
-
|
226
|
-
__END__
|
227
|
-
|