Skip to content

Instantly share code, notes, and snippets.

@gangelo
Last active January 7, 2022 00:17
Show Gist options
  • Select an option

  • Save gangelo/d215f9e7b51a3dc3c9a72191916bd9f4 to your computer and use it in GitHub Desktop.

Select an option

Save gangelo/d215f9e7b51a3dc3c9a72191916bd9f4 to your computer and use it in GitHub Desktop.

Revisions

  1. gangelo revised this gist Mar 8, 2020. 1 changed file with 46 additions and 6 deletions.
    52 changes: 46 additions & 6 deletions network.rb
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,6 @@
    # Examples:
    #
    # Hacking::Networking.network_info_for(ip: '192.168.114.32/27')
    # Hacking::Networking.network_info_for(ip: '192.168.33.12', mask: '255.255.224.0')
    # => {:ip=>[192, 168, 33, 12], :mask=>[255, 255, 224, 0], :cidr_info=>{:cidr=>19, :network=>"192.168.32.0", :cidr_notation=>"192.168.32.0/19"}, :network=>"192.168.32.0", :host=>"0.0.1.12", :total_hosts=>8192}
    # Hacking::Networking.network_for(ip: '192.168.33.12', mask: '255.255.224.0') # => "192.168.32.0"
    @@ -8,24 +10,41 @@
    # Hacking::Networking.to_binary('255.255.224.0') # => "11111111.11111111.11100000.00000000"
    # Hacking::Networking.mask_for(cidr: 23) => "255.255.254.0"


    mmodule Hacking
    module Hacking
    module Networking
    CIDR_TOTAL_BITS = 32

    module_function

    def network_info_for(ip:, mask:)
    def network_info_for(ip:, mask: nil)
    if mask.nil?
    puts 'Mask is nil?'
    ip, cidr = split_cidr(ip: ip)
    mask = mask_for(cidr: cidr)
    end

    ip = octets_for(ip) unless octets?(ip)
    mask = octets_for(mask) unless octets?(mask)

    total_hosts = total_hosts_for(mask: mask)
    cidr_info = cidr_for(ip: ip, mask: mask)

    {
    ip: ip,
    mask: mask,
    cidr_info: cidr_for(ip: ip, mask: mask),
    cidr: cidr_info[:cidr],
    cidr_notation: cidr_info[:cidr_notation],
    network: network_for(ip: ip, mask: mask),
    host: host_for(ip: ip, mask: mask),
    total_hosts: total_hosts_for(mask: mask),
    total_hosts: total_hosts,
    # Subtract 2 for Network (first address) and Broadcast (last address)
    total_hosts_actual: total_hosts - 2,
    binary_representations:
    {
    ip: to_binary(ip),
    mask: to_binary(mask),
    mask_inverted: to_binary(invert(mask)),
    },
    }
    end

    @@ -75,16 +94,32 @@ def cidr_for(ip:, mask:)
    }
    end

    def mask_for(cidr:)
    ones_count = cidr
    zeroes_count = CIDR_TOTAL_BITS - cidr
    binary_mask = ('1' * ones_count + '0' * zeroes_count).scan(/.{8}/)
    octets = binary_mask.map { |binary_byte| to_integer(binary: binary_byte) }
    join_octets(octets)
    end

    # Takes an ip address or mask and converts it to binary ip notation.
    # If invert is true, the result will be inverted.
    def to_binary(ip)
    octets = octets_for(ip).each.map { |octet| '%0*b' % [8, octet] }
    join_octets(octets)
    end

    # Takes a binary string and returns the integer equivalent (e.g.) to_integer(binary: '11111110')
    # # => 254
    def to_integer(binary:)
    Integer("0b#{binary}")
    end

    # Takes an ip address or mask string, and returns the octets in an Array.
    def octets_for(ip)
    ip.split('.').map do |octet|
    ip = ip.join('.') if octets?(ip)

    ip.split('.').map do |octet|
    octet = octet.to_i
    octet = yield octet if block_given?
    octet
    @@ -124,6 +159,11 @@ def join_octets(octets)
    octets.join('.')
    end

    def split_cidr(ip:)
    ip, cidr =ip.split('/')
    return ip, cidr.to_i
    end

    private_class_method :invert, :bits_on_for, :octets?, :join_octets
    end
    end
  2. gangelo revised this gist Mar 8, 2020. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions network.rb
    Original file line number Diff line number Diff line change
    @@ -6,6 +6,8 @@
    # Hacking::Networking.total_hosts_for(mask: '255.255.224.0') # => 8192
    # Hacking::Networking.to_binary('192.168.33.12') # => "11000000.10101000.00100001.00001100"
    # Hacking::Networking.to_binary('255.255.224.0') # => "11111111.11111111.11100000.00000000"
    # Hacking::Networking.mask_for(cidr: 23) => "255.255.254.0"


    mmodule Hacking
    module Networking
  3. gangelo revised this gist Mar 8, 2020. 1 changed file with 6 additions and 4 deletions.
    10 changes: 6 additions & 4 deletions network.rb
    Original file line number Diff line number Diff line change
    @@ -1,14 +1,16 @@
    # Examples:
    # Hacking::Networking.network_info_for(ip: '192.168.33.12', mask: '255.255.224.0')
    # => {:ip=>[192, 168, 33, 12], :mask=>[255, 255, 224, 0], :cidr_info=>{:cidr=>13, :network=>"192.168.32.0", :cidr_notation=>"192.168.32.0/13"}, :network=>"192.168.32.0", :host=>"0.0.1.12", :total_hosts=>8192}
    # => {:ip=>[192, 168, 33, 12], :mask=>[255, 255, 224, 0], :cidr_info=>{:cidr=>19, :network=>"192.168.32.0", :cidr_notation=>"192.168.32.0/19"}, :network=>"192.168.32.0", :host=>"0.0.1.12", :total_hosts=>8192}
    # Hacking::Networking.network_for(ip: '192.168.33.12', mask: '255.255.224.0') # => "192.168.32.0"
    # Hacking::Networking.host_for(ip: '192.168.33.12', mask: '255.255.224.0') # => "0.0.1.12"
    # Hacking::Networking.total_hosts_for(mask: '255.255.224.0') # => 8192
    # Hacking::Networking.to_binary('192.168.33.12') # => "11000000.10101000.00100001.00001100"
    # Hacking::Networking.to_binary('255.255.224.0') # => "11111111.11111111.11100000.00000000"

    module Hacking
    mmodule Hacking
    module Networking
    CIDR_TOTAL_BITS = 32

    module_function

    def network_info_for(ip:, mask:)
    @@ -62,7 +64,7 @@ def cidr_for(ip:, mask:)
    ip = octets_for(ip) unless octets?(ip)
    mask = octets_for(mask) unless octets?(mask)

    cidr = bits_on_for(mask: join_octets(mask))
    cidr = CIDR_TOTAL_BITS - bits_on_for(mask: join_octets(mask))
    network = network_for(ip: ip, mask: mask)
    {
    cidr: cidr,
    @@ -122,4 +124,4 @@ def join_octets(octets)

    private_class_method :invert, :bits_on_for, :octets?, :join_octets
    end
    end
    end
  4. gangelo revised this gist Mar 8, 2020. 1 changed file with 40 additions and 4 deletions.
    44 changes: 40 additions & 4 deletions network.rb
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,6 @@
    # Examples:
    # Hacking::Networking.network_info_for(ip: '192.168.33.12', mask: '255.255.224.0')
    # => {:ip=>[192, 168, 33, 12], :mask=>[255, 255, 224, 0], :cidr_info=>{:cidr=>13, :network=>"192.168.32.0", :cidr_notation=>"192.168.32.0/13"}, :network=>"192.168.32.0", :host=>"0.0.1.12", :total_hosts=>8192}
    # Hacking::Networking.network_for(ip: '192.168.33.12', mask: '255.255.224.0') # => "192.168.32.0"
    # Hacking::Networking.host_for(ip: '192.168.33.12', mask: '255.255.224.0') # => "0.0.1.12"
    # Hacking::Networking.total_hosts_for(mask: '255.255.224.0') # => 8192
    @@ -9,10 +11,25 @@ module Hacking
    module Networking
    module_function

    def network_info_for(ip:, mask:)
    ip = octets_for(ip) unless octets?(ip)
    mask = octets_for(mask) unless octets?(mask)

    {
    ip: ip,
    mask: mask,
    cidr_info: cidr_for(ip: ip, mask: mask),
    network: network_for(ip: ip, mask: mask),
    host: host_for(ip: ip, mask: mask),
    total_hosts: total_hosts_for(mask: mask),
    }
    end

    # Returns the network ip address (as a string) for the given ip address and mask.
    def network_for(ip:, mask:)
    ip = octets_for(ip) unless octets?(ip)
    mask = octets_for(mask) unless octets?(mask)

    network_part_octets = []
    ip.each_with_index do |octet, index|
    network_part_octets << (octet & mask[index])
    @@ -23,8 +40,9 @@ def network_for(ip:, mask:)
    # Returns the host ip address (as a string) for the given ip address and mask.
    def host_for(ip:, mask:)
    ip = octets_for(ip) unless octets?(ip)
    mask = join_octets(mask.join) if octets?(mask)
    mask = invert(mask)
    mask = octets_for(mask) unless octets?(mask)

    mask = invert(join_octets(mask))
    host_octets = []
    ip.each_with_index do |octet, index|
    host_octets << (octet & mask[index])
    @@ -34,9 +52,25 @@ def host_for(ip:, mask:)

    # Returns the maximum number of host addresses this network can support.
    def total_hosts_for(mask:)
    mask = join_octets(mask) if octets?(mask)

    2 ** bits_on_for(mask: mask)
    end

    # Returns the cidr notation given the mask.
    def cidr_for(ip:, mask:)
    ip = octets_for(ip) unless octets?(ip)
    mask = octets_for(mask) unless octets?(mask)

    cidr = bits_on_for(mask: join_octets(mask))
    network = network_for(ip: ip, mask: mask)
    {
    cidr: cidr,
    network: network,
    cidr_notation: "#{network}/#{cidr}",
    }
    end

    # Takes an ip address or mask and converts it to binary ip notation.
    # If invert is true, the result will be inverted.
    def to_binary(ip)
    @@ -66,6 +100,8 @@ def invert(ip)
    # Returns the total number of bits on for this mask; mask is inverted prior to counting tbe
    # number of bits. No consideration is taken into account for validity of the mask.
    def bits_on_for(mask:)
    raise "Argument mask (#{mask}) must respond_to? :split" unless mask.respond_to?(:split)

    inverted_mask = join_octets(invert(mask))
    to_binary(inverted_mask).count('1')
    end
    @@ -79,11 +115,11 @@ def octets?(object)

    # Joins the Array of octets and returns an ip address or mask (e.g. "192.168.1.1").
    def join_octets(octets)
    raise 'Argument octets does not respond_to? :join' unless octets.respond_to?(:join)
    raise "Argument octets (#{octets}) does not respond_to? :join" unless octets.respond_to?(:join)

    octets.join('.')
    end

    private_class_method :invert, :bits_on_for, :octets?, :join_octets
    end
    end
    end
  5. gangelo revised this gist Mar 8, 2020. 1 changed file with 43 additions and 25 deletions.
    68 changes: 43 additions & 25 deletions network.rb
    Original file line number Diff line number Diff line change
    @@ -1,49 +1,50 @@
    # Examples:
    # Hacking::Networking.network_for(ip: '192.168.33.12', mask: '255.255.224.0') # => "192.168.32.0"
    # Hacking::Networking.host_for(ip: '192.168.33.12', mask: '255.255.224.0') # => "0.0.1.12"
    # Hacking::Networking.total_hosts_for(mask: '255.255.224.0') # => 13
    # Hacking::Networking.total_addresses_for(mask: '255.255.224.0') # => 8192
    # Hacking::Networking.total_hosts_for(mask: '255.255.224.0') # => 8192
    # Hacking::Networking.to_binary('192.168.33.12') # => "11000000.10101000.00100001.00001100"
    # Hacking::Networking.to_binary('255.255.224.0') # => "11111111.11111111.11100000.00000000"

    module Hacking
    module Networking
    module_function

    # Returns the network ip address (as a string) for the given ip address and mask
    # Returns the network ip address (as a string) for the given ip address and mask.
    def network_for(ip:, mask:)
    ip = octets_for(ip)
    mask = octets_for(mask)
    ip = octets_for(ip) unless octets?(ip)
    mask = octets_for(mask) unless octets?(mask)
    network_part_octets = []
    ip.each_with_index do |octet, index|
    network_part_octets << (octet & mask[index])
    end
    network_part_octets.join('.')
    join_octets(network_part_octets)
    end

    # Returns the host ip address (as a string) for the given ip address and mask
    # Returns the host ip address (as a string) for the given ip address and mask.
    def host_for(ip:, mask:)
    ip = octets_for(ip)
    ip = octets_for(ip) unless octets?(ip)
    mask = join_octets(mask.join) if octets?(mask)
    mask = invert(mask)
    host_octets = []
    ip.each_with_index do |octet, index|
    host_octets << (octet & mask[index])
    end
    host_octets.join('.')
    join_octets(host_octets)
    end

    # Returns the total number of hosts supported by this network
    # Returns the maximum number of host addresses this network can support.
    def total_hosts_for(mask:)
    to_binary(invert(mask).join('.')).count('1')
    2 ** bits_on_for(mask: mask)
    end

    # Returns the total number of addresses this network can accomodate for all hosts supported
    # by this network
    def total_addresses_for(mask:)
    2 ** total_hosts_for(mask: mask)
    # Takes an ip address or mask and converts it to binary ip notation.
    # If invert is true, the result will be inverted.
    def to_binary(ip)
    octets = octets_for(ip).each.map { |octet| '%0*b' % [8, octet] }
    join_octets(octets)
    end

    # Takes an ip address or mask, and returns the octets in an Array
    # Takes an ip address or mask string, and returns the octets in an Array.
    def octets_for(ip)
    ip.split('.').map do |octet|
    octet = octet.to_i
    @@ -52,20 +53,37 @@ def octets_for(ip)
    end
    end

    # Takes an ip address or mask, inverts it, and returns an Array of octets
    # Expects a Fixnum and returns the octet with the bits flipped.
    def flip_bits(octet)
    octet ^ 0xff
    end

    # Takes an ip address or mask, inverts it, and returns an Array of octets.
    def invert(ip)
    octets_for(ip) { |octet| flip_bits(octet) }
    end

    # Expects a Fixnum and returns the octet with the bits flipped
    def flip_bits(octet)
    octet ^ 0xff
    # Returns the total number of bits on for this mask; mask is inverted prior to counting tbe
    # number of bits. No consideration is taken into account for validity of the mask.
    def bits_on_for(mask:)
    inverted_mask = join_octets(invert(mask))
    to_binary(inverted_mask).count('1')
    end

    # Takes an ip address or mask and converts it to binary ip notation.
    # If invert is true, the result will be inverted.
    def to_binary(ip)
    octets_for(ip).each.map { |octet| '%0*b' % [8, octet] }.join('.')
    # Returns true if object is an Array, assuming it is an Array of octets (integers).
    def octets?(object)
    return false if object.nil?

    object.is_a?(Array)
    end

    # Joins the Array of octets and returns an ip address or mask (e.g. "192.168.1.1").
    def join_octets(octets)
    raise 'Argument octets does not respond_to? :join' unless octets.respond_to?(:join)

    octets.join('.')
    end

    private_class_method :invert, :bits_on_for, :octets?, :join_octets
    end
    end
    end
  6. gangelo revised this gist Mar 8, 2020. 1 changed file with 65 additions and 11 deletions.
    76 changes: 65 additions & 11 deletions network.rb
    Original file line number Diff line number Diff line change
    @@ -1,17 +1,71 @@
    # Examples:
    # Hacking::Networking.network_for(ip: '192.168.33.12', mask: '255.255.224.0') # => "192.168.32.0"
    # Hacking::Networking.host_for(ip: '192.168.33.12', mask: '255.255.224.0') # => "0.0.1.12"
    # Hacking::Networking.total_hosts_for(mask: '255.255.224.0') # => 13
    # Hacking::Networking.total_addresses_for(mask: '255.255.224.0') # => 8192
    # Hacking::Networking.to_binary('192.168.33.12') # => "11000000.10101000.00100001.00001100"
    # Hacking::Networking.to_binary('255.255.224.0') # => "11111111.11111111.11100000.00000000"

    module Hacking
    module Networking
    # Hacking::Hetworking.network_part_for('192.168.33.12', '255.255.224.0')
    # => Network is 192.168.32.0
    # => "192.168.32.0"
    def self.network_part_for(ip, mask)
    ip = ip.split('.').map { |octet| octet.to_i }
    mask = mask.split('.').map { |octet| octet.to_i }
    network_part = []
    module_function

    # Returns the network ip address (as a string) for the given ip address and mask
    def network_for(ip:, mask:)
    ip = octets_for(ip)
    mask = octets_for(mask)
    network_part_octets = []
    ip.each_with_index do |octet, index|
    network_part << (octet & mask[index])
    network_part_octets << (octet & mask[index])
    end
    puts "Network is #{network_part.join('.')}"
    network_part
    network_part_octets.join('.')
    end

    # Returns the host ip address (as a string) for the given ip address and mask
    def host_for(ip:, mask:)
    ip = octets_for(ip)
    mask = invert(mask)
    host_octets = []
    ip.each_with_index do |octet, index|
    host_octets << (octet & mask[index])
    end
    host_octets.join('.')
    end

    # Returns the total number of hosts supported by this network
    def total_hosts_for(mask:)
    to_binary(invert(mask).join('.')).count('1')
    end

    # Returns the total number of addresses this network can accomodate for all hosts supported
    # by this network
    def total_addresses_for(mask:)
    2 ** total_hosts_for(mask: mask)
    end

    # Takes an ip address or mask, and returns the octets in an Array
    def octets_for(ip)
    ip.split('.').map do |octet|
    octet = octet.to_i
    octet = yield octet if block_given?
    octet
    end
    end

    # Takes an ip address or mask, inverts it, and returns an Array of octets
    def invert(ip)
    octets_for(ip) { |octet| flip_bits(octet) }
    end

    # Expects a Fixnum and returns the octet with the bits flipped
    def flip_bits(octet)
    octet ^ 0xff
    end

    # Takes an ip address or mask and converts it to binary ip notation.
    # If invert is true, the result will be inverted.
    def to_binary(ip)
    octets_for(ip).each.map { |octet| '%0*b' % [8, octet] }.join('.')
    end
    end
    end
    end
  7. gangelo revised this gist Mar 7, 2020. No changes.
  8. gangelo revised this gist Mar 7, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion network.rb
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    module Hacking
    module Networking
    # network_part_for('192.168.33.12', '255.255.224.0')
    # Hacking::Hetworking.network_part_for('192.168.33.12', '255.255.224.0')
    # => Network is 192.168.32.0
    # => "192.168.32.0"
    def self.network_part_for(ip, mask)
  9. gangelo revised this gist Mar 7, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion network.rb
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@ module Networking
    # network_part_for('192.168.33.12', '255.255.224.0')
    # => Network is 192.168.32.0
    # => "192.168.32.0"
    def network_part_for(ip, mask)
    def self.network_part_for(ip, mask)
    ip = ip.split('.').map { |octet| octet.to_i }
    mask = mask.split('.').map { |octet| octet.to_i }
    network_part = []
  10. gangelo revised this gist Mar 7, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion network.rb
    Original file line number Diff line number Diff line change
    @@ -14,4 +14,4 @@ def network_part_for(ip, mask)
    network_part
    end
    end
    end
    end
  11. gangelo revised this gist Mar 7, 2020. 1 changed file with 16 additions and 12 deletions.
    28 changes: 16 additions & 12 deletions network.rb
    Original file line number Diff line number Diff line change
    @@ -1,13 +1,17 @@

    def network_part_for(ip, mask)
    ip = ip.split('.').map { |octet| octet.to_i }
    mask = mask.split('.').map { |octet| octet.to_i }
    network_part = []
    ip.each_with_index do |octet, index|
    network_part << (octet & mask[index])
    module Hacking
    module Networking
    # network_part_for('192.168.33.12', '255.255.224.0')
    # => Network is 192.168.32.0
    # => "192.168.32.0"
    def network_part_for(ip, mask)
    ip = ip.split('.').map { |octet| octet.to_i }
    mask = mask.split('.').map { |octet| octet.to_i }
    network_part = []
    ip.each_with_index do |octet, index|
    network_part << (octet & mask[index])
    end
    puts "Network is #{network_part.join('.')}"
    network_part
    end
    end
    puts "Network is #{network_part.join('.')}"
    network_part
    end
    # network_part_for('192.168.33.12', '255.255.224.0')
    # => Network is 192.168.32.0
    end
  12. gangelo created this gist Mar 7, 2020.
    13 changes: 13 additions & 0 deletions network.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@

    def network_part_for(ip, mask)
    ip = ip.split('.').map { |octet| octet.to_i }
    mask = mask.split('.').map { |octet| octet.to_i }
    network_part = []
    ip.each_with_index do |octet, index|
    network_part << (octet & mask[index])
    end
    puts "Network is #{network_part.join('.')}"
    network_part
    end
    # network_part_for('192.168.33.12', '255.255.224.0')
    # => Network is 192.168.32.0