https://github.com/ynadji/netaddr
A network address manipulation library for Common Lisp
https://github.com/ynadji/netaddr
cidr common-lisp ipv4 ipv6 netaddr network networking subnet
Last synced: 3 months ago
JSON representation
A network address manipulation library for Common Lisp
- Host: GitHub
- URL: https://github.com/ynadji/netaddr
- Owner: ynadji
- License: mit
- Created: 2024-08-23T13:36:38.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-04-26T02:00:20.000Z (12 months ago)
- Last Synced: 2025-04-26T02:56:03.186Z (12 months ago)
- Topics: cidr, common-lisp, ipv4, ipv6, netaddr, network, networking, subnet
- Language: Common Lisp
- Homepage: http://yacin.nadji.us/netaddr/
- Size: 182 KB
- Stars: 7
- Watchers: 1
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-cl - netaddr - A network address manipulation library for Common Lisp. MIT. (Interfaces to other package managers / Isomorphic web frameworks)
README
# netaddr
NETADDR is a Common Lisp library for manipulating IP addresses, subnets, ranges,
and sets. It is inspired by its namesake library in Python,
[netaddr](https://github.com/netaddr/netaddr). NETADDR supports/provides:
* IPv4 and IPv6 addresses, subnets, and ranges.
* Shorthand syntax for the above with a reader macro `#I`. See the [IP
Syntax](#IP-syntax) section for details.
* Helper lookup functions for reserved space, e.g., `PRIVATE?`, `RESERVED?`, and
`PUBLIC?`.
* An `IP-SET` data structure for working with sets of addresses, subnets, and
ranges. See `MAKE-IP-SET`.
* Set operations on the above like union, intersection, difference, and
symmetric difference.
* Membership checks of IPs against subnets, ranges, and sets using `CONTAINS?`.
## Class Hierarchy
```
┌ ─ ─ ─ ┐
┌─────── IP+ ────────┐
│ └ ─ ─ ─ ┘ │
│ │
│ │
│ │
▼ ▼
┌ ─ ─ ─ ┐ ┌──────────┐
IP-LIKE ◀─ ─ set of─ ─│ IP-SET │
└ ─ ─ ─ ┘ └──────────┘
│
├──────┐
┌────────────┘ ▼
│ ┌ ─ ─ ─ ┐
│ ┌─ IP-PAIR ──┐
▼ ▼ └ ─ ─ ─ ┘ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│IP-ADDRESS│ │IP-NETWORK│ │ IP-RANGE │
└──────────┘ └──────────┘ └──────────┘
```
Users of this library will only instantiate the leaf classes in the tree above,
using their respective `MAKE-*` functions, or in the case of the three that
inherit from `IP-LIKE`, the short-hand `#I` notation. `IP-SET`s are comprised of
a set of `IP-LIKE`s. Most operations will expect either `IP-LIKE`s as arguments
and/or `IP+`s. For example, `CONTAINS?` takes an `IP+` as its first argument and
an `IP-LIKE` as its second argument because:
* An `IP-ADDRESS` `CONTAINS?` itself.
* An `IP-NETWORK` and an `IP-RANGE` `CONTAINS?` themselves, any subset of those
networks or ranges, and any `IP-ADDRESS` that is a member of the network or
range.
* An `IP-SET` `CONTAINS?` any of its member `IP-LIKE`s, and so on.
## Equality
There are two equality operators for `IP+` subclasses:
* `IP-EQUAL` (aliased to `IP=`)
* `IP-EQUALP`
Similar to Common Lisp's EQUAL and EQUALP, `IP-EQUAL` is more specific than
`IP-EQUALP`. The former considers different classes to always be unequal, while
the latter allows comparisons across all leaf classes described in the [Class
Hierarchy](#Class-Hierarchy). For example:
```
NETADDR> (ip-equal #I("1.1.1.1") #I("1.1.1.1/32"))
NIL
NETADDR> (ip-equalp #I("1.1.1.1") #I("1.1.1.1/32"))
T
NETADDR> (ip-equalp #I("1.1.1.1") #I("1.1.1.1/31"))
NIL
NETADDR> (ip-equal #I("1.0.0.0/8") #I("1.0.0.0-1.255.255.255"))
NIL
NETADDR> (ip-equalp #I("1.0.0.0/8") #I("1.0.0.0-1.255.255.255"))
T
NETADDR> (ip-equal (make-ip-set (list #I("1.1.1.1"))) (make-ip-set (list #I("1.1.1.1/32"))))
NIL
NETADDR> (ip-equalp (make-ip-set (list #I("1.1.1.1"))) (make-ip-set (list #I("1.1.1.1/32"))))
T
```
`IP-EQUAL` always returns NIL if classes are different. However, `IP-EQUALP`
returns T if the underlying object refers to the same set of IP addresses,
regardless of the concrete object type. In general, if you are comparing
individual `IP-LIKE`s, you'll want to use `IP-EQUAL`. If you are comparing
`IP-SET`s, which may contain a mixture of classes internally, or `IP-NETWORK`s
and `IP-RANGE`s, you'll want to use `IP-EQUALP`.
## IP Syntax
NETADDR provides a shorthand syntax for defining `IP-LIKE`s from strings with
the reader macro `#I` that can be enabled by first calling `ENABLE-IP-SYNTAX`.
If a single argument is provided, a single object is returned. If multiple
arguments are provided, a list of objects is returned. Example usage is shown
below:
```
NETADDR> #I("1.2.3.4")
#
NETADDR> #I("192.168.1.0/24")
#
NETADDR> #I("::-ffff::")
#
NETADDR> #I("0.0.0.0" "1.1.1.1")
(# #)
NETADDR> (multiple-value-bind (x y z) (values "1.1.1.1" "::/96" "10.20.30.40-11.20.30.40")
#I(x y z))
(# # #)
```