Skip to content

Commit

Permalink
is_private and is_global (#20)
Browse files Browse the repository at this point in the history
* Add is_private and is_global for classification of IP addresses.

* Set version to 1.1.0.
  • Loading branch information
fredrikekre authored Jul 1, 2021
1 parent 9f9befc commit 92a9364
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "IPNets"
uuid = "66763231-799b-5fff-8662-389acfc33a85"
version = "1.0.0"
version = "1.1.0"

[deps]
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
Expand Down
62 changes: 61 additions & 1 deletion src/IPNets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module IPNets

using Sockets: IPAddr, IPv4, IPv6

export IPNet, IPv4Net, IPv6Net
export IPNet, IPv4Net, IPv6Net, is_private, is_global

abstract type IPNet end

Expand Down Expand Up @@ -168,4 +168,64 @@ end
inttype(::IPv4Net) = UInt32
inttype(::IPv6Net) = UInt128

###############################
## IP address classification ##
###############################

# See https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
# and https://github.com/python/cpython/blob/67b3a9995368f89b7ce4a995920b2a83a81c599b/Lib/ipaddress.py#L1543-L1558
const _private_ipv4_nets = IPv4Net[
IPv4Net("0.0.0.0/8"),
IPv4Net("10.0.0.0/8"),
IPv4Net("127.0.0.0/8"),
IPv4Net("169.254.0.0/16"),
IPv4Net("172.16.0.0/12"),
IPv4Net("192.0.0.0/29"),
IPv4Net("192.0.0.170/31"),
IPv4Net("192.0.2.0/24"),
IPv4Net("192.168.0.0/16"),
IPv4Net("198.18.0.0/15"),
IPv4Net("198.51.100.0/24"),
IPv4Net("203.0.113.0/24"),
IPv4Net("240.0.0.0/4"),
IPv4Net("255.255.255.255/32"),
]

# See https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
# and https://github.com/python/cpython/blob/67b3a9995368f89b7ce4a995920b2a83a81c599b/Lib/ipaddress.py#L2258-L2269
const _private_ipv6_nets = IPv6Net[
IPv6Net("::1/128"),
IPv6Net("::/128"),
IPv6Net("::ffff:0:0/96"),
IPv6Net("100::/64"),
IPv6Net("2001::/23"),
IPv6Net("2001:2::/48"),
IPv6Net("2001:db8::/32"),
IPv6Net("2001:10::/28"),
IPv6Net("fc00::/7"),
IPv6Net("fe80::/10"),
]

"""
is_private(ip::Union{IPv4,IPv6})
Return `true` if the IP adress is allocated for private networks.
See [iana-ipv4-special-registry](https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml) (IPv4)
and [iana-ipv6-special-registry](https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml) (IPv6).
"""
is_private(::Union{IPv4,IPv6})
is_private(ip::IPv4) = any(ip in net for net in _private_ipv4_nets)
is_private(ip::IPv6) = any(ip in net for net in _private_ipv6_nets)

"""
is_global(ip::Union{IPv4,IPv6})
Return `true` if the IP adress is allocated for public networks.
See [iana-ipv4-special-registry](https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml) (IPv4)
and [iana-ipv6-special-registry](https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml) (IPv6).
"""
is_global(ip::Union{IPv4,IPv6}) = !is_private(ip)

end # module
9 changes: 9 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ using IPNets, Test, Sockets
@test_throws BoundsError ipnet[256]
@test_throws BoundsError ipnet[-1:2]

@test is_private(ip"127.0.0.1")
@test !is_global(ip"127.0.0.1")
@test !is_private(ip"1.1.1.1")
@test is_global(ip"1.1.1.1")

#############
## IPv6Net ##
Expand Down Expand Up @@ -128,4 +132,9 @@ using IPNets, Test, Sockets
@test_throws BoundsError ipnet[-1]
@test_throws BoundsError ipnet[65536]
@test_throws BoundsError ipnet[-1:2]

@test is_private(ip"::1")
@test !is_global(ip"::1")
@test !is_private(ip"2606:4700:4700::1111")
@test is_global(ip"2606:4700:4700::1111")
end

2 comments on commit 92a9364

@fredrikekre
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/40033

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.1.0 -m "<description of version>" 92a9364b4f12b4762ecfa3d6d233ab27aee6c5c4
git push origin v1.1.0

Please sign in to comment.