Skip to content

Commit

Permalink
Add matching.
Browse files Browse the repository at this point in the history
  • Loading branch information
c-rack committed Apr 26, 2015
1 parent 57a886f commit c58275a
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 5 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,34 @@

[Classless Inter-Domain Routing (CIDR)](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) for [Elixir](http://www.elixir-lang.org/)

## Setup

To use this library in your project, edit your mix.exs file and add cidr as a dependency:

```elixir
defp deps do
[
{ :cidr, "~> 0.1.0" }
]
end
```

## Usage

Parse an IP address / CIDR:
```elixir
iex(1)> cidr = "1.2.3.4/24" |> CIDR.parse
%CIDR{ip: {1, 2, 3, 4}, mask: 24}
```

Match against a CIDR:
```elixir
iex(2)> cidr |> CIDR.match({1,2,3,100})
true
iex(3)> cidr |> CIDR.match({1,2,4,1})
false
```

## License

[MIT License](LICENSE).
11 changes: 11 additions & 0 deletions lib/cidr.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
defmodule CIDR do

use Bitwise

@moduledoc """
Classless Inter-Domain Routing (CIDR)
"""
Expand All @@ -18,6 +20,15 @@ defmodule CIDR do
end
def is_cidr(_), do: false

@doc """
Checks if an IP address is in the provided CIDR.
"""
def match(%CIDR{ ip: { a0, b0, c0, d0 }, mask: mask } = cidr, { a1, b1, c1, d1 } = ip) do
cidr_value = (a0 <<< 24) ||| (b0 <<< 16) ||| (c0 <<< 8) ||| d0
ip_value = (a1 <<< 24) ||| (b1 <<< 16) ||| (c1 <<< 8) ||| d1
(cidr_value >>> (32 - mask)) == (ip_value >>> (32 - mask))
end

def to_cidr(string) when string |> is_bitstring do
tokens = String.split(string, "/")
if Enum.count(tokens) == 2 do
Expand Down
23 changes: 18 additions & 5 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ defmodule CIDR.Mixfile do
use Mix.Project

def project do
[app: :cidr,
version: "0.0.1",
elixir: "~> 1.0",
source_url: "https://github.com/c-rack/cidr-elixir",
deps: deps]
[
app: :cidr,
version: "0.1.0",
elixir: ">= 1.0.2",
source_url: "https://github.com/c-rack/cidr-elixir",
deps: deps,
description: "Classless Inter-Domain Routing (CIDR) for Elixir",
package: package
]
end

# Configuration for the OTP application
Expand All @@ -28,4 +32,13 @@ defmodule CIDR.Mixfile do
defp deps do
[]
end

defp package do
%{
contributors: ["Constantin Rack"],
licenses: ["MIT License"],
links: %{"Github" => "https://github.com/c-rack/cidr-elixir"}
}
end

end
17 changes: 17 additions & 0 deletions test/cidr_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,21 @@ defmodule CIDRTest do
assert "127.0.0.1/24" |> CIDR.parse |> CIDR.is_cidr
end

# Match

test "Matches exactly" do
assert ("1.2.3.4" |> CIDR.parse |> CIDR.match({1, 1, 1, 1})) == false
assert ("1.2.3.4" |> CIDR.parse |> CIDR.match({1, 2, 3, 3})) == false
assert "1.2.3.4" |> CIDR.parse |> CIDR.match({1, 2, 3, 4})
assert ("1.2.3.4" |> CIDR.parse |> CIDR.match({1, 2, 3, 5})) == false
assert ("1.2.3.4" |> CIDR.parse |> CIDR.match({255, 255, 255, 255})) == false
end

test "Matches /24" do
assert "1.2.3.4/24" |> CIDR.parse |> CIDR.match({1, 2, 3, 1})
assert "1.2.3.4/24" |> CIDR.parse |> CIDR.match({1, 2, 3, 100})
assert "1.2.3.4/24" |> CIDR.parse |> CIDR.match({1, 2, 3, 200})
assert "1.2.3.4/24" |> CIDR.parse |> CIDR.match({1, 2, 3, 255})
end

end

0 comments on commit c58275a

Please sign in to comment.