Liking cljdoc? Tell your friends :D

com.dmo-t/ipaddress

A Clojure library designed to do operations with IP addresses and networks

Installation

Add the following in the :deps section of your deps.edn file

com.dmo-t/ipaddress {:mvn-version "RELEASE"}

Latest Version

Clojars Project

Usage

Introduction

In the NS com.dmo-t.ipaddress.core, 6 main types are defined:

  • IPv4Address,
  • IPv4Network,
  • IPv4Interface
  • IPv6Address
  • IPv6Network
  • IPv6Interface

These types try to mimics the behavior of the corresponding classes in ipaddressPython library.

Common Protocols / Interfaces

All three types implement the following Protocols / Interfaces

Comparable

So they can be used with the default compare function. The sort function will work as well without specifying a specific compare function.

  • IPv[46]Address: compare the addresses converted to int.
  • IPv[46]Network: will compare only the base-address (aka network address). If equality: compare the prefix length.
  • IPv[46]Interface: Arbitrary choice.
    • if same network (same base-address and same netmask): result of comparing the interface addresses
    • else: comparaison on networks.

IPScope

Custom protocol. Defines only the following predicates functions:

  • loopback?
  • private?
  • global?
  • reserved?
  • link-local?
  • multicast?
  • unspecified?

See the ipaddress Python Library for the meaning.

IPIter

Custom protocol. Implement only the next-one function.

  • IPv[46]Address: returns the next IPv[46]Address. Returns nil when no more IPv[46]Address.
  • IPv[46]Network: returns the next IPv[46]Network with the same IPv[46]Netmask. Returns nil when no more network.
  • IPv[46]Interface: returns the next IPv[46]Interface in the containing network. Returns nil when no more address available.

Note: (next-one nil) returns nil.

IPv[46]Address

To create an IPv[46]Address, always use the constructor make-ipv4address or make-ipv6address.

  • make-ipv4address: accepts a string or long/int as argument.
  • make-ipv6address: accepts a string or clojure.lang.BigInt as argument If the argument is invalid, an exception is raised.
clj                                                                     
Clojure 1.12.2
user=> (use 'com.dmo-t.ipaddress.core)
nil
user=> (def ip1 (make-ipv4address "192.0.2.1"))
#'user/ip1
user=> (to-int ip1)
3221225985
user=> (str ip1)
"192.0.2.1"
user=> (def ip2 (-> (to-int ip1) make-ipv4address))
#'user/ip2
user=> (compare ip1 ip2)
0
user=> (def ip3 (make-ipv4address "172.30.1.2"))
#'user/ip3
user=> (compare ip1 ip3)
1
user=> (private? ip1)
true
user=> (loopback? ip1)
false
user=> (-> (next-one ip1) str )
"192.0.2.2"
user=> (def net (make-ipv4network "192.0.2.0/24"))
#'user/net
user=> (in? ip1 net)
true
user=> (make-ipv4address "192.256.1.2")
Execution error (AssertionError) at com.dmo-t.ipaddress.core/make-ipv4address-from-str (core.clj:98).
Assert failed: (spec/valid? :com.dmo-t.ipaddress.specs/ipv4-address-spec ip)

IPv[46]Network

Always the constructor make-ipv4network to create an IPv4Network. The argument can be address/netmask or address/mask.

For IPv6Network: make-ipv6network. Only accept a string in address/prefixlen format.

NB: if the address part has host bits set, they will be automatically zeroed.

 clj                                                                     
Clojure 1.12.2
user=> (use 'com.dmo-t.ipaddress.core)
nil
user=> (def net1 (make-ipv4network "192.0.2.0/29"))
#'user/net1
user=> (def net2 (make-ipv4network "192.0.2.0/28"))
#'user/net2
user=> (compare net1 net2)
1
user=> (with-prefixlen net1)
"192.0.2.0/29"
user=> (with-netmask net1)
"192.0.2.0/255.255.255.248"
user=> (with-hostmask net1)
"192.0.2.0/0.0.0.7"
user=> (-> (base-address net1) str)
"192.0.2.0"
user=> (-> (broadcast-address net1) str)
"192.0.2.7"
user=> (prefixlen net1)
29
user=> (-> (netmask net1) str)
"255.255.255.248"
user=> (-> (hostmask net1) str)
"0.0.0.7"
user=> (->> (hosts net1) (map #(str %)))
("192.0.2.1" "192.0.2.2" "192.0.2.3" "192.0.2.4" "192.0.2.5" "192.0.2.6")
user=> (subnet-of? net1 net2)
true
user=> (supernet-of? net1 net2)
false
user=> (def ip1 (make-ipv4address "192.0.2.9"))
#'user/ip1
user=> (contains-ip? net1 ip1)
false
user=> (contains-ip? net2 ip1)
true
user=> (def net3 (make-ipv4network "192.0.2.7/32"))
#'user/net3
user=> (overlaps? net1 net3)
true
user=> (def net4 (make-ipv4network "192.0.2.0/27"))
#'user/net4
user=> (subnets net4 29)
user=> (->> (subnets net4 29) (map #(.with-prefixlen %)))
("192.0.2.0/29" "192.0.2.8/29" "192.0.2.16/29" "192.0.2.24/29")
user=> (def net5 (make-ipv4network "192.0.2.72/29"))
#'user/net5
user=> (-> (supernet net5 26) with-prefixlen)
"192.0.2.64/26"
user=> (num-addresses net5)
8
user=> (def net6 (make-ipv4network "192.0.2.64/26"))
#'user/net6
user=> (->> (address-exclude net6 net5) (map #(with-prefixlen %)))
("192.0.2.96/27" "192.0.2.80/28" "192.0.2.64/29")
user=> (-> (next-one net6) with-prefixlen)
"192.0.2.128/26"
user=>  (->> (to-seq net6) reverse (take 10) (map #(str % )))
("192.0.2.127" "192.0.2.126" "192.0.2.125" "192.0.2.124" "192.0.2.123" "192.0.2.122" "192.0.2.121" "192.0.2.120" "192.0.2.119" "192.0.2.118")
user=> (def net6-1 (make-ipv6network "2001::/23"))
#'user/net6-1
user=> (def net6-2 (make-ipv6network "2001:3::/32"))
#'user/net6-2
user=> (->> (.address-exclude net6-1 net6-2)
            sort
            (map #(str %)))
("2001::/31" "2001:2::/32" "2001:4::/30" "2001:8::/29" "2001:10::/28" "2001:20::/27" "2001:40::/26" "2001:80::/25" "2001:100::/24")

IPv[46]Interface

IPv4Interface: Always use the constructor make-ipv4interface. Argument: address/prefixlen or address/netmask

IPv6Interface: always use the constructor make-ipv6interface Argument: address/prefixlen

 clj                                                          
Clojure 1.12.2
user=> (use 'com.dmo-t.ipaddress.core)
nil
(def intf1 (make-ipv4interface "192.0.2.45/29"))
#'user/intf1
user=> (-> (network intf1) with-prefixlen )
"192.0.2.40/29"
user=> (->> (iterate next-one intf1)
(take-while identity)
(map #(with-prefixlen %)))
("192.0.2.45/29" "192.0.2.46/29" "192.0.2.47/29")
user=> (def intf2 (make-ipv4interface "192.0.2.45/29"))
#'user/intf2
user=>  (def intf3 (make-ipv4interface "192.0.2.46/28"))
#'user/intf3
user=> (def intf4 (make-ipv4interface "192.0.2.46/29"))
#'user/intf4
user=> (compare intf1 intf2)
0
user=> (compare intf1 intf3)
1
user=> (compare intf1 intf4)
-1
user=> (-> (address intf1) str)
"192.0.2.45"

License

Copyright © 2025 DMO Technologies

This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0.

This Source Code may also be made available under the following Secondary Licenses when the conditions for such availability set forth in the Eclipse Public License, v. 2.0 are satisfied: GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version, with the GNU Classpath Exception which is available at https://www.gnu.org/software/classpath/license.html.

Can you improve this documentation?Edit on GitLab

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close