Packages

A Decentralized failover and peer-to-peer node finder for Elixir. Allows Elixir nodes to find each other automatically. Once connected, they can coordinate to delegate roles and tasks between the nodes in the cluster. Written using only the Elixir and Erlang standard library.

Current section

Files

Jump to
beethoven lib beethoven ipv4.ex
Raw

lib/beethoven/ipv4.ex

defmodule Beethoven.Ipv4 do
@moduledoc """
Module to handle scanning IPV4 addresses within a network.
"""
require Logger
alias :inet, as: IP
alias Beethoven.Utils
#
#
#
@doc """
Retrieves the hosts IP address. Pulls Network and Netmask from the config.
"""
@spec get_host_network_addresses() :: list()
def get_host_network_addresses() do
# Get Cluster network from config
clusterNet = Utils.get_app_env(:cluster_net, "127.0.0.0")
# Gets cluster netmask
clusterNetMask = Utils.get_app_env(:cluster_net_mask, "29")
# Convert to IP Type
{:ok, clusterNetParse} = IP.parse_address(~c"#{clusterNet}")
# get all IPs in the network
get_hosts(clusterNetParse, clusterNetMask)
end
#
#
#
@doc """
Same as get_host_network_addresses/0 but works off provided network and netmask.
"""
@spec get_host_network_addresses({integer(), integer(), integer(), integer()}, integer()) ::
list()
def get_host_network_addresses(clusterNet, clusterNetMask) do
get_hosts(clusterNet, clusterNetMask)
end
#
#
#
@doc """
Gets the number of IPs within a netmask.
"""
@spec get_netmask_hosts(binary() | integer()) :: float()
def get_netmask_hosts(mask) when is_binary(mask) do
get_netmask_hosts(String.to_integer(mask))
end
def get_netmask_hosts(mask) when is_integer(mask) do
:math.pow(2, 32 - mask) - 2
end
#
#
#
@doc """
Generates a list of hosts with the network and netmask provided
"""
@spec get_hosts({integer(), integer(), integer(), integer()}, integer()) :: list()
def get_hosts(address, mask) do
# gets number of hosts within the network
numOfHosts = get_netmask_hosts(mask)
#
get_hosts(address, numOfHosts, [], 0)
end
# End loop
defp get_hosts(_address, numOfHosts, state, acc) when numOfHosts == acc do
state |> Enum.reverse()
end
# working loop
defp get_hosts(address, numOfHosts, state, acc) do
address = increment_ip(address)
get_hosts(address, numOfHosts, [address | state], acc + 1)
end
#
#
#
@doc """
Increments IP by one host.
"""
@spec increment_ip({integer(), integer(), integer(), integer()}) ::
{integer(), integer(), integer(), integer()}
def increment_ip({255, 255, 255, 255}) do
raise "Next IP address is not valid! 'input_ip: {254, 254, 254, 254}'"
end
def increment_ip({oct1, 255, 255, 255}) do
{oct1 + 1, 0, 0, 0}
end
def increment_ip({oct1, oct2, 255, 255}) do
{oct1, oct2 + 1, 0, 0}
end
def increment_ip({oct1, oct2, oct3, 255}) do
{oct1, oct2, oct3 + 1, 0}
end
def increment_ip({oct1, oct2, oct3, oct4}) do
{oct1, oct2, oct3, oct4 + 1}
end
end