IP (net_address v0.3.0) View Source

Elixir IP value tool suite.

Erlang provides a structured IP type, but the tooling around it is very squirelly, spread out over several disjoint modules, and not ergonomic with respect to structured programming.

Elixir gives us some better tools (like protocols and guards).

This module, and its related modules IP.Range and IP.Subnet provide a better view into operator-friendly, composable programming that interfaces well with erlang IP primitives.

Link to this section Summary

Types

any ip address, either v4 or v6

16-bit integers

ipv4 representation in erlang.

ipv6 representation in erlang.

Functions

Finds an ip address in a string, returning an ok or error tuple on failure.

Converts an ip address from a string.

true if the argument is either ipv6 or ipv4 datatype

true if the argument is an ipv4 datatype

true if the argument is an ipv6 datatype

returns the canonical ip address of localhost. Defaults to ipv4.

generates an ip mask with specified bit_length.

returns the next ip address.

generates an the subnet prefix for a given ip address.

returns the previous ip address.

picks a random ip address from a range or a subnet.

allows you to use the convenient ~i sigil to declare an IP address in its normal string form, instead of using the tuple form.

Converts an ip address to a string.

Link to this section Types

Specs

addr() :: v4() | v6()

any ip address, either v4 or v6

Specs

short() :: 0..65535

16-bit integers

Specs

v4() :: {byte(), byte(), byte(), byte()}

ipv4 representation in erlang.

Specs

v6() :: {short(), short(), short(), short(), short(), short(), short(), short()}

ipv6 representation in erlang.

Link to this section Functions

Specs

from_string(String.t()) :: {:ok, addr()} | {:error, :einval}

Finds an ip address in a string, returning an ok or error tuple on failure.

Specs

from_string!(String.t()) :: addr()

Converts an ip address from a string.

iex> IP.from_string!("255.255.255.255")
{255, 255, 255, 255}

true if the argument is either ipv6 or ipv4 datatype

usable in guards.

iex> IP.is_ip({0, 0, 0, 0, 0, 0, 0, 1})
true
iex> IP.is_ip({127, 0, 0, 1})
true

true if the argument is an ipv4 datatype

usable in guards.

iex> IP.is_ipv4({10, 0, 0, 1})
true
iex> IP.is_ipv4(:foo)
false
iex> IP.is_ipv4({256, 0, 0, 0})
false

true if the argument is an ipv6 datatype

usable in guards.

iex> IP.is_ipv6({0, 0, 0, 0, 0, 0, 0, 1})
true
iex> IP.is_ipv6(:foo)
false
iex> IP.is_ipv6({0x10000, 0, 0, 0, 0, 0, 0, 1})
false

Specs

localhost(:v4) :: v4()
localhost(:v6) :: v6()

returns the canonical ip address of localhost. Defaults to ipv4.

iex> IP.localhost()
{127, 0, 0, 1}

iex> IP.localhost(:v6)
{0, 0, 0, 0, 0, 0, 0, 1}
Link to this function

mask(bit_length, mode \\ :v4)

View Source

Specs

mask(0..32, :v4_int) :: 0..4_294_967_295
mask(0..32, :v4_bin) :: <<_::32>>
mask(0..32, :v4) :: v4()
mask(0..32, :v6_int) :: 0..340_282_366_920_938_463_463_374_607_431_768_211_455
mask(0..32, :v6_bin) :: <<_::128>>
mask(0..32, :v6) :: v6()

generates an ip mask with specified bit_length.

Can also generate raw integer or raw binary forms.

Defaults to IPv4.

iex> IP.mask(32, :v4_int)
0xFFFF_FFFF

iex> IP.mask(32, :v4_bin)
<<255, 255, 255, 255>>

iex> IP.mask(32, :v4)
{255, 255, 255, 255}

iex> IP.mask(24, :v4)
{255, 255, 255, 0}

iex> IP.mask(0)
{0, 0, 0, 0}

iex> IP.mask(128, :v6)
{0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}

iex> IP.mask(0, :v6)
{0, 0, 0, 0, 0, 0, 0, 0}

Specs

next(v4()) :: v4()
next(v6()) :: v6()

returns the next ip address.

iex> IP.next({10, 0, 0, 255})
{10, 0, 1, 0}
iex> IP.next({0, 0, 0, 0, 0, 0, 0, 0xFFFF})
{0, 0, 0, 0, 0, 0, 1, 0}

Specs

prefix(v4(), 0..32) :: v4()
prefix(v6(), 0..128) :: v6()

generates an the subnet prefix for a given ip address.

iex> IP.prefix({10, 0, 1, 23}, 24)
{10, 0, 1, 0}

Specs

prev(v4()) :: v4()
prev(v6()) :: v6()

returns the previous ip address.

iex> IP.prev({10, 0, 1, 0})
{10, 0, 0, 255}

iex> IP.prev({0, 0, 0, 0, 0, 0, 1, 0})
{0, 0, 0, 0, 0, 0, 0, 0xFFFF}
Link to this function

random(range_or_subnet, excludes \\ [])

View Source

picks a random ip address from a range or a subnet.

You may exclude individual ip addresses, ranges, or subnets to the excludes parameter and they won't be picked.

Note that subnets will pick the prefix and broadcast addresses, if you would like to exclude those, you must add them explicitly to the excludes parameter.

Warning: this algorithm is rather bad, so use only with blocks of less than about 1024.

Link to this macro

sigil_i(arg, list)

View Source (macro)

Specs

sigil_i(Macro.t(), [byte()]) :: Macro.t()

allows you to use the convenient ~i sigil to declare an IP address in its normal string form, instead of using the tuple form.

iex> import IP
iex> ~i"10.0.0.1"
{10, 0, 0, 1}

also works for cidr-form subnet blocks

iex> import IP
iex> ~i"10.0.0.0/24"
%IP.Subnet{routing_prefix: {10, 0, 0, 0}, bit_length: 24}

and generic IP ranges

iex> import IP
iex> ~i"10.0.0.3..10.0.0.7"
%IP.Range{first: {10, 0, 0, 3}, last: {10, 0, 0, 7}}

and socket addresses:

iex> import IP
iex> ~i"10.0.0.1:1234"
%IP.SockAddr{family: :inet, port: 1234, addr: {10, 0, 0, 1}}

and ip/subnet combinations for configuration:

iex> import IP
iex> ~i"10.0.0.4/24"config
{{10, 0, 0, 4}, %IP.Subnet{routing_prefix: {10, 0, 0, 0}, bit_length: 24}}

You can also use ~i for ip addresses and subnets with the m suffix in the context of matches.

iex> import IP
iex> fn -> ~i"10.0.x.3"m = {10, 0, 1, 3}; x end.()
1
Link to this function

to_string(ip_addr, style \\ :dots)

View Source

Specs

to_string(addr() | nil, :dots | :hyphens) :: String.t()

Converts an ip address to a string.

For some situations, like converting an ip address to a hostname you might want hyphens as delimiters instead, in which case you should pass :hyphens as the :style term.

Also takes, nil, in which case it emits an empty string.

iex> IP.to_string({255, 255, 255, 255})
"255.255.255.255"

iex> IP.to_string({255, 255, 255, 255}, :hyphens)
"255-255-255-255"

iex> IP.to_string({0, 0, 0, 0, 0, 0, 0, 1})
"::1"