README
IP lookup, with longest prefix match, for IPv4, IPv6 prefixes (and others).
Iptrie manages multiple Radix
trees, one for each type of
Pfx.t/0
prefix used as determined by their maxlen
property. That way,
IPv4 prefixes (maxlen: 32
) use a different radix tree as opposed to e.g. IPv6
(maxlen: 128
).
Iptrie has a bias towards IPv4 and IPv6 since it uses Pfx
to convert
arguments to a Pfx.t/0
struct. So, doing other types of prefixes will
require the actual Pfx.t/0
structs as arguments for the various Iptrie
functions.
Like Pfx
, Iptrie tries to mirror the representation of results to the
argument(s) given, if possible.
IPv4/IPv6
iex> ipt = new()
...> |> put("1.2.3.0/24", "v4")
...> |> put("128.0.0.0/8", "v4-128")
...> |> put("acdc:1975::/32", "T.N.T")
...> |> put("acdc:1978::/32", "Powerage")
...> |> put("0.0.0.0/0", "v4 default")
...> |> put("::/0", "no dynamite")
iex>
iex> lookup(ipt, "1.2.3.128")
{"1.2.3.0/24", "v4"}
iex> lookup(ipt, "acdc:1975::")
{"acdc:1975:0:0:0:0:0:0/32", "T.N.T"}
iex>
iex> # separate trees, separate default routes
iex> lookup(ipt, "10.11.12.13")
{"0.0.0.0/0", "v4 default"}
iex> lookup(ipt, "abba::")
{"0:0:0:0:0:0:0:0/0", "no dynamite"}
iex>
iex> # visualize the IPv4 & IPv6 radix trees
iex> kv32 = fn {k, v} -> "#{Pfx.new(k, 32)}<br/>#{v}" end
iex> radix(ipt, 32)
...> |> Radix.dot(label: "IPv4", kv_tostr: kv32)
...> |> (&File.write("img/ipv4.dot", &1)).()
iex> kv128 = fn {k, v} -> "#{Pfx.new(k, 128)}<br/>#{v}" end
iex> radix(ipt, 128)
...> |> Radix.dot(label: "IPv6", kv_tostr: kv128)
...> |> (&File.write("img/ipv6.dot", &1)).()
Where the radix trees for the IP prefixes look like:
Others
Iptrie can also be used to do longest prefix match lookup for other types of prefixes, like e.g. MAC addresses:
iex> ipt = new()
...> |> put(%Pfx{bits: <<0x00, 0x22, 0x72>>, maxlen: 48}, "American Micro-Fuel Device")
...> |> put(%Pfx{bits: <<0x00, 0xd0, 0xef>>, maxlen: 48}, "IGT")
...> |> put(%Pfx{bits: <<0x08, 0x61, 0x95>>, maxlen: 48}, "Rockwell Automation")
iex>
iex> lookup(ipt, %Pfx{bits: <<0x00, 0xd0, 0xef, 0xaa, 0xbb>>, maxlen: 48})
{%Pfx{bits: <<0x00, 0xd0, 0xef>>, maxlen: 48}, "IGT"}
iex>
iex> # longest match for partial prefix
iex> lookup(ipt, %Pfx{bits: <<0x08, 0x61, 0x95, 0x01>>, maxlen: 48}) |> elem(1)
"Rockwell Automation"
iex>
iex> kv48 = fn {_k, v} -> "#{v}" end
iex> radix(ipt, 48)
...> |> Radix.dot(label: "MAC OUI", kv_tostr: kv48)
...> |> (&File.write("img/mac.dot", &1)).()
Iptrie
does not automatically recognize MAC addresses in string format (like
00-D0-EF-AA-BB-CC-DD-EE
or 00:D0:EF:AA:BB:CC:DD:EE
), so the actual
Pfx.t/0
structs must be used in the various IPtrie functions.
Since prefixes are stored in specific radix trees based on the maxlen
of
given prefix, you could also mix IPv4, IPv6 and MAC prefixes and possibly
others, in a single Iptrie.
Installation
Iptrie can be installed by adding iptrie
to your
list of dependencies in mix.exs
:
def deps do
[
{:iptrie, "~> 0.3.0"}
]
end
Repositiory is on github.