subnet_calc 0.2.3 → 0.2.4
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.
- 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
|