subnet_calc 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/subnet_calc.rb +320 -2
- data.tar.gz.sig +0 -0
- metadata +1 -1
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc90d91915916592cdf05424c9aee5f9448f2257
|
4
|
+
data.tar.gz: ed2a21fbea8a6836dbf688698e911ad1edc59484
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e7a93085e84393136d93c27f85a583442e49f564125d479f9ef36bcda69b3280e7dfeefa5cfa3a5bc586825f8fc32053120f4e1d011867c2333db1633025d0d
|
7
|
+
data.tar.gz: a4aaab7e14df16e5a6c30a2a519c1ed343b27984e0240d0b21f8074278e88d360381b014b726e9adb61e185b061945c46309846ba2634152f6dfe659f2d2f511
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/lib/subnet_calc.rb
CHANGED
@@ -161,6 +161,324 @@ class SubnetCalc
|
|
161
161
|
first_ip = (ip + [subnets.first.first]).join('.')
|
162
162
|
last_ip = (ip + [subnets.first.last]).join('.')
|
163
163
|
|
164
|
+
subnet_bits = (subnet_mask.split('.')[class_n]).to_i.to_s(2).count("1")
|
165
|
+
|
166
|
+
result = {
|
167
|
+
class_type: class_type.upcase,
|
168
|
+
magic_number: magic_number,
|
169
|
+
hosts: hosts_per_subnet - 2,
|
170
|
+
subnet_mask: subnet_mask,
|
171
|
+
subnet_bitmask: subnet_mask.split('.').map \
|
172
|
+
{|x| ('0' * 7 + x.to_i.to_s(2))[-8..-1]},
|
173
|
+
prefix: prefix,
|
174
|
+
subnets: subnets,
|
175
|
+
range: "%s-%s" % [first_ip, last_ip],
|
176
|
+
subnet_bits: subnet_bits,
|
177
|
+
max_subnets: 2 ** (subnet_bits)
|
178
|
+
}
|
179
|
+
|
180
|
+
@octet_n = octet_n
|
181
|
+
@h = result
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
def to_s()
|
186
|
+
|
187
|
+
tfo = TableFormatter.new
|
188
|
+
|
189
|
+
tfo.source = @h[:subnets].map.with_index do |x,i|
|
190
|
+
([i+1] + x.to_h.values).map(&:to_s)
|
191
|
+
end
|
192
|
+
|
193
|
+
tfo.labels = %w(index Network 1st last broadcast)
|
194
|
+
full_subnets_table = tfo.display(markdown: true).to_s
|
195
|
+
|
196
|
+
subnets_table = if full_subnets_table.lines.length > 14 then
|
197
|
+
(full_subnets_table.lines[0..13] + ["\n ... "]).join
|
198
|
+
else
|
199
|
+
full_subnets_table
|
200
|
+
end
|
201
|
+
|
202
|
+
# octet broken down
|
203
|
+
|
204
|
+
tfo2 = TableFormatter.new
|
205
|
+
|
206
|
+
prefixes = @prefixes[@octet_n].map {|x| '/' + x.to_s}
|
207
|
+
tfo2.source = [@h[:subnet_bitmask][@octet_n].chars, prefixes]
|
208
|
+
tfo2.labels = 8.times.map {|n| (2 ** n).to_s }.reverse
|
209
|
+
octet_table = tfo2.display(markdown: true).to_s
|
210
|
+
|
211
|
+
<<EOF
|
212
|
+
|
213
|
+
|
214
|
+
Subnet calculator
|
215
|
+
=================
|
216
|
+
|
217
|
+
Inputs:
|
218
|
+
|
219
|
+
#{Kvx.new(@inputs).to_s.lines.map {|x| ' ' * 2 + x}.join}
|
220
|
+
|
221
|
+
Summary
|
222
|
+
-------
|
223
|
+
|
224
|
+
* Network class: #{@h[:class_type]}
|
225
|
+
* magic number: #{@h[:magic_number]}
|
226
|
+
* hosts per subnet: #{@h[:hosts]}
|
227
|
+
* subnet mask: #{@h[:subnet_mask]}
|
228
|
+
* subnet bitmask: #{@h[:subnet_bitmask].join('.')}
|
229
|
+
* prefix bit-length: #{@h[:prefix]}
|
230
|
+
* range: #{@h[:range]}
|
231
|
+
|
232
|
+
* subnet_bits: #{@h[:subnet_bits]}
|
233
|
+
* maximum subnets: #{@h[:max_subnets]}
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
Breakdown
|
238
|
+
---------
|
239
|
+
|
240
|
+
#{(@octet_n + 1).ordinal} octet:
|
241
|
+
|
242
|
+
#{indent octet_table}
|
243
|
+
|
244
|
+
### Subnets
|
245
|
+
|
246
|
+
|
247
|
+
#{indent subnets_table}
|
248
|
+
|
249
|
+
-----------------------------------------------
|
250
|
+
|
251
|
+
EOF
|
252
|
+
|
253
|
+
end
|
254
|
+
|
255
|
+
def to_h()
|
256
|
+
@h
|
257
|
+
end
|
258
|
+
|
259
|
+
private
|
260
|
+
|
261
|
+
def class_subnets(n, block_size)
|
262
|
+
|
263
|
+
i = 0
|
264
|
+
|
265
|
+
subnets = n.times.inject([]) do |r,n|
|
266
|
+
|
267
|
+
broadcast = i + block_size - 1
|
268
|
+
first = i + 1
|
269
|
+
last = broadcast - 1
|
270
|
+
|
271
|
+
h = if block_given? then
|
272
|
+
yield(i,first,last,broadcast)
|
273
|
+
else
|
274
|
+
{ network: i, first: first, last: last, broadcast: broadcast }
|
275
|
+
end
|
276
|
+
i += block_size
|
277
|
+
|
278
|
+
r << OpenStruct.new(h)
|
279
|
+
|
280
|
+
end
|
281
|
+
|
282
|
+
end
|
283
|
+
|
284
|
+
def class_b_subnets(n, block_size)
|
285
|
+
|
286
|
+
class_subnets(n, block_size) do |network, first, last, broadcast|
|
287
|
+
|
288
|
+
{
|
289
|
+
network: [network, 0].join('.'),
|
290
|
+
first: [network, 1].join('.'),
|
291
|
+
last: [broadcast, 254].join('.'),
|
292
|
+
broadcast: [broadcast, 255].join('.')
|
293
|
+
}
|
294
|
+
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|
298
|
+
|
299
|
+
def class_a_subnets(n, block_size)
|
300
|
+
|
301
|
+
class_subnets(n, block_size) do |network, first, last, broadcast|
|
302
|
+
|
303
|
+
{
|
304
|
+
network: [network, 0, 0].join('.'),
|
305
|
+
first: [network, 1, 1].join('.'),
|
306
|
+
last: [broadcast, 255, 254].join('.'),
|
307
|
+
broadcast: [broadcast, 255, 255].join('.')
|
308
|
+
}
|
309
|
+
|
310
|
+
end
|
311
|
+
|
312
|
+
end
|
313
|
+
|
314
|
+
def indent(s, i=2)
|
315
|
+
s.lines.map{|x| ' ' * i + x}.join
|
316
|
+
end
|
317
|
+
end#!/usr/bin/env ruby
|
318
|
+
|
319
|
+
# file: subnet_calc.rb
|
320
|
+
|
321
|
+
|
322
|
+
require 'kvx'
|
323
|
+
require 'ostruct'
|
324
|
+
require 'table-formatter'
|
325
|
+
|
326
|
+
|
327
|
+
module Ordinals
|
328
|
+
|
329
|
+
refine Fixnum do
|
330
|
+
def ordinal
|
331
|
+
self.to_s + ( (10...20).include?(self) ? 'th' :
|
332
|
+
%w{ th st nd rd th th th th th th }[self % 10] )
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
class SubnetCalc
|
338
|
+
|
339
|
+
using Ordinals
|
340
|
+
|
341
|
+
attr_reader :to_h, :octets
|
342
|
+
|
343
|
+
def initialize(inputs={})
|
344
|
+
|
345
|
+
@inputs = inputs
|
346
|
+
default_inputs = {hosts: nil, ip: '192.168.0.0', prefix: nil}.merge(inputs)
|
347
|
+
|
348
|
+
# Using the input(s) supplied:
|
349
|
+
|
350
|
+
hosts, prefix = %i(hosts prefix).map {|x| default_inputs[x]}
|
351
|
+
|
352
|
+
|
353
|
+
@prefixes = 1.upto(32).each_slice(8).to_a
|
354
|
+
|
355
|
+
=begin
|
356
|
+
#=> [
|
357
|
+
[1, 2, 3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15, 16],
|
358
|
+
[17, 18, 19, 20, 21, 22, 23, 24], [25, 26, 27, 28, 29, 30, 31, 32]
|
359
|
+
]
|
360
|
+
=end
|
361
|
+
|
362
|
+
|
363
|
+
octets = @prefixes.map.with_index do |octet, j|
|
364
|
+
|
365
|
+
a = octet.map.with_index do |prefix, i|
|
366
|
+
|
367
|
+
decimal = 2 ** (octet.length - 1 - i )
|
368
|
+
|
369
|
+
h = {
|
370
|
+
prefix: prefix,
|
371
|
+
decimal: decimal,
|
372
|
+
hosts_per_subnet: (2 ** 8) ** (@prefixes.length - 1 - j) * decimal
|
373
|
+
}
|
374
|
+
|
375
|
+
OpenStruct.new h
|
376
|
+
|
377
|
+
end
|
378
|
+
|
379
|
+
OpenStruct.new mask: nil, bits: a
|
380
|
+
|
381
|
+
end
|
382
|
+
|
383
|
+
@octets = octets
|
384
|
+
|
385
|
+
|
386
|
+
# ------------------------------------
|
387
|
+
|
388
|
+
|
389
|
+
octet_n, col, class_type = if hosts then
|
390
|
+
|
391
|
+
hosts_per_subnet = octets.flat_map.with_index do |octet,i|
|
392
|
+
octet.bits.map.with_index {|y,j| [i, j, y.hosts_per_subnet] }
|
393
|
+
end
|
394
|
+
|
395
|
+
# find the smallest decimal value to match the
|
396
|
+
# required number of hosts on a network
|
397
|
+
|
398
|
+
*r, _ = hosts_per_subnet.reverse.detect {|x| x.last > hosts + 1}
|
399
|
+
|
400
|
+
network = case hosts
|
401
|
+
when 1..254
|
402
|
+
'c'
|
403
|
+
when 255..65534
|
404
|
+
'b'
|
405
|
+
else
|
406
|
+
'a'
|
407
|
+
end
|
408
|
+
|
409
|
+
(r + [network])
|
410
|
+
|
411
|
+
elsif prefix
|
412
|
+
|
413
|
+
prefixes = @prefixes.flat_map.with_index do |octet,i|
|
414
|
+
octet.map.with_index {|x,j| [i, j, x]}
|
415
|
+
end
|
416
|
+
|
417
|
+
*r, _ = prefixes.detect {|x| x.last == prefix}
|
418
|
+
|
419
|
+
network = case prefix
|
420
|
+
when 24..32
|
421
|
+
'c'
|
422
|
+
when 16..23
|
423
|
+
'b'
|
424
|
+
else
|
425
|
+
'a'
|
426
|
+
end
|
427
|
+
|
428
|
+
(r + [network])
|
429
|
+
end
|
430
|
+
|
431
|
+
|
432
|
+
# Identify the network bits and the host bits
|
433
|
+
|
434
|
+
classes = ('a'..'d')
|
435
|
+
|
436
|
+
# identify the initial network bits for a class *a,b or c*
|
437
|
+
|
438
|
+
class_n = (classes.to_a.index(class_type) + 1)
|
439
|
+
|
440
|
+
network_bits = class_n.times.map {|x| Array.new(8, 1)}
|
441
|
+
host_bits = (classes.to_a.length - class_n).times.map {|x| Array.new(8, 0)}
|
442
|
+
address_bits = network_bits + host_bits
|
443
|
+
|
444
|
+
# add the mask to each octet
|
445
|
+
|
446
|
+
octets.each.with_index do |octet, i|
|
447
|
+
octet.mask = address_bits[i].join.to_i(2)
|
448
|
+
end
|
449
|
+
|
450
|
+
|
451
|
+
bit = octets[octet_n].bits[col]
|
452
|
+
|
453
|
+
magic_number, hosts_per_subnet, prefix = bit.decimal,
|
454
|
+
bit.hosts_per_subnet, bit.prefix
|
455
|
+
|
456
|
+
no_of_subnets = (2 ** 8.0) / bit.hosts_per_subnet
|
457
|
+
|
458
|
+
segments = (no_of_subnets >= 1 ? no_of_subnets : (1 / no_of_subnets)).to_i
|
459
|
+
n = col
|
460
|
+
|
461
|
+
# add the new mask to the octet
|
462
|
+
|
463
|
+
octets[octet_n].mask = octets[octet_n].bits.map(&:decimal)[0..n].inject(:+)
|
464
|
+
subnet_mask = octets.map(&:mask).join('.')
|
465
|
+
|
466
|
+
subnets = case class_type
|
467
|
+
when 'c'
|
468
|
+
class_subnets(segments, hosts_per_subnet)
|
469
|
+
when 'b'
|
470
|
+
class_b_subnets(256 / segments, bit.decimal)
|
471
|
+
when 'a'
|
472
|
+
class_a_subnets(256 ** 2 / segments, bit.decimal)
|
473
|
+
end
|
474
|
+
|
475
|
+
ip = (default_inputs[:ip] + ' ') .split('.')[0..octet_n-1]
|
476
|
+
|
477
|
+
first_ip = (ip + [subnets.first.first]).join('.')
|
478
|
+
last_ip = (ip + [subnets.first.last]).join('.')
|
479
|
+
|
480
|
+
subnet_bits = (subnet_mask.split('.')[class_n]).to_i.to_s(2).count("1")
|
481
|
+
|
164
482
|
result = {
|
165
483
|
class_type: class_type.upcase,
|
166
484
|
magic_number: magic_number,
|
@@ -171,8 +489,8 @@ class SubnetCalc
|
|
171
489
|
prefix: prefix,
|
172
490
|
subnets: subnets,
|
173
491
|
range: "%s-%s" % [first_ip, last_ip],
|
174
|
-
subnet_bits:
|
175
|
-
max_subnets:
|
492
|
+
subnet_bits: subnet_bits,
|
493
|
+
max_subnets: 2 ** (subnet_bits)
|
176
494
|
}
|
177
495
|
|
178
496
|
@octet_n = octet_n
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
metadata.gz.sig
CHANGED
Binary file
|