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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c6269772bdd1895f45f3d245d545d2f1f38c0c0b
4
- data.tar.gz: 4b7c062156c81833fb15752a8f0546d6f7490632
3
+ metadata.gz: bc90d91915916592cdf05424c9aee5f9448f2257
4
+ data.tar.gz: ed2a21fbea8a6836dbf688698e911ad1edc59484
5
5
  SHA512:
6
- metadata.gz: e89aa0d80d8cd8e5777375d601bbf6950ed8ffdf6bd8ed9965b2a2fcd9319136fa203cb0d84ecc6fb19f344a0fcc2f63c224da6309252d698f300ace9b1fb607
7
- data.tar.gz: 52a283f8937e9ff97c31429e1881e218afe95cf71b79a3db338b00d51d94ffd434c670c258ccb3146d53a7c5efa534a368eba1bfc06de7959d3f122a4e33900f
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: n+1,
175
- max_subnets: segments
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
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: subnet_calc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Robertson
metadata.gz.sig CHANGED
Binary file