= Subnetter
Brent Saner <bts@square-r00t.net>
Last rendered {localdatetime}
:doctype: book
:docinfo: shared
:data-uri:
:imagesdir: images
:sectlinks:
:sectnums:
:sectnumlevels: 7
:toc: preamble
:toc2: left
:idprefix:
:toclevels: 7
:source-highlighter: rouge
:docinfo: shared
:rfc: https://datatracker.ietf.org/doc/html/rfc
:arin_r: https://www.arin.net/participate/policy/nrpm/

[id="wat"]
== What is it?
A tool to assist in design of segregate/segment/split/subnet networks.

[id="out"]
== Output

* `PTP` refers to "Peer-to-Peer" (e.g. {rfc}3021[RFC 3021^]).
* `6rd` refers to "IPv6 Rapid Deployment", a derivation of 6to4 ({rfc}5569[RFC 5569^], {rfc}5969[RFC 5969^]).
* `LIR` refers to "Local Internet Registry" ({arin_r}#2-4-local-internet-registry-lir[ARIN^]).
* `RIR` refers to "Regional Internet Registry" ({arin_r}#2-2-regional-internet-registry-rir[ARIN^]).
* `Unicast` refers to "Global Unicast" ({rfc}1122[RFC 1122^], {rfc}4291#section-2.5.4[RFC 4291 § 2.5.4^], {rfc}4632[RFC 4632^]).
** For IPv6 addresses, it will be `true` for ULA (_Unique Local Addresses_) ({rfc}4193[RFC 4193^]) also.
** For IPv4 addresses, it will be `true` if the address is routable by external hosts (a unicast address), including private IP addresses ({rfc}1918[RFC 1918^]).
* `ILM` refers to "Interface-Local Multicast" ({rfc}4291#section-2.7[RFC 4291 § 2.7^], {rfc}7346[RFC 7346^]).
** It will always be `false` for IPv4 addresses.
* `LLM` refers to "Link-Local Multicast" ({rfc}4291#section-2.7[RFC 4291 § 2.7^], {rfc}7346[RFC 7346^]).
** For IPv4 addresses, it will be `true` if it is in the `224.0.0.0/4` range ({rfc}5735[RFC 5735^]).
* `LLU` refers to "Link-Local Unicast" ({rfc}4291#section-2.7[RFC 4291 § 2.7^], {rfc}7346[RFC 7346^]).
** For IPv4 addresses, it will be `true` if it is an APIPA (_Automatic Private IP Addressing_) address ({rfc}3927[RFC 3927^]) (in the `169.254.0.0/16` range).
* `First` and `Last` refer to the first and last "usable" ("host"/assignable) addresses in a subnet/network.
** Note that for IPv6, the first address (`x::`) in a subnet *may* or *may not* be assignable/"usable". If it is assigned to a device, that device *must* be a router for anycast. See {rfc}4291#section-2.6.1[RFC 4291 § 2.6.1^] for details. In the interest of convenience, `subnetter` will report this address as *not usable/addressable* in ranges for this reason as it is technically not a "host" address.
** Note that for IPv6, some subnetting calculators erroneously report the last address as usable. They are reserved in strictly RFC-compliant networks for anycast reasons (per {rfc}2526[RFC 2526^]). Subnetter follows RFC as closely as possible, and any deviation from RFC is considered a bug -- as such, the last address of IPv6 subnets is considered *not usable/addressable*.
** There are additional restrictions for /64 subnets, but they fall earlier in the range. These are *not explicitly excluded* in the usable host range, nor are they excluded from the total host count.
* Private networks ({rfc}1918[RFC 1918^]), ULA prefixes ({rfc}4193[RFC 4193^]), and documentation prefixes ({rfc}3849[RFC 3849^], {rfc}5737[RFC 5737^], {rfc}9637[RFC 9637^]) are treated as "normal" networks (in that it is allowed to subnet them).
* Various other reserved IPv4 and IPv6 addresses/networks will print warnings with their corresponding RFC(s) (unless `-R`/`--allow-reserved` is specified) if they are specified as/included in the initial prefix/network. ({rfc}6890[RFC 6890^] and its update via {rfc}8190[RFC 8190^] are useful summaries.) Note that for checking to function, an Internet connection is required as it pulls it directly from IANA live to ensure the data is accurate to standards. This may be cached locally if `-c`/`--cache-reservations` is specified, in which case a locally-cached copy will be used if present and populated then used if not.
** The cache directory may be specified by `-C`/`--cache-dir` (which can be specifically defaulted via the `SBNTR_RSVCACHE_DIR` environment variable). If it is not specified, the default (see below) will be used.
** This directory's default location determined by the following, and will be created if it doesn't exist:
*** For non-Windows systems (macOS, Linux, etc.)...
**** If https://specifications.freedesktop.org/basedir-spec/latest/#variables[the `XDG_CACHE_HOME` environment variable^] is present, it will be `${XDG_CACHE_HOME}/subnetter/`. (If XDG base dirs are enabled, this is usually `~/.cache/subnetter/` or, explicitly, `/home/<username>/.cache/subnetter/`)
**** If the `XDG_CACHE_HOME` environment variable is not present...
***** On macOS, an explicit fallback of `~/Library/Caches/subnetter/` will be used. (To my knowledge/understanding, this is the standard user cache directory and cannot be changed.) This usually evaluates to `/Users/<username>/Library/Caches/subnetter/`.
***** On all others, an explicit fallback of `~/.cache/subnetter` will be used.
****** On most non-macOS/*NIX-like systems , this is usually `/home/<username>/.cache/subetter/`, provided normal user homes. On http://p9f.org/[Plan9^] platforms (e.g. https://9p.io/plan9/index.html[Plan 9 4th Ed.^], https://9front.org/[9front^], http://9legacy.org/[9legacy^]), the `/env/home` environment variable (`$home`) will be used, the `./lib/` subdirectory under there (which typically/should already exist) will be appended to it, and that appended with `./cache/subnetter/` (this usually evaluates to `/usr/<username>/lib/cache/subnetter/`).
*** For Windows systems...
**** If https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid#constants[the `LOCALAPPDATA` environment variable^] is present, it will be `%LOCALAPPDATA%\Cache\subnetter\` (or `${env:LOCALAPPDATA}\Cache\subnetter\` in Powershell syntax). This usually evaluates to `C:\Users\<username>\AppData\Local\Cache\subnetter\`.

[id="ref"]
== References
This program in general draws inspiration from `ipcalc` (http://jodies.de/ipcalc[0^], https://github.com/kjokjo/ipcalc[1^], https://gitlab.com/ipcalc/ipcalc[2^]) and http://www.routemeister.net/projects/sipcalc/[`sipcalc`^].

The `table` subcommand is inspired by `iptab` from https://metacpan.org/pod/Net::IP[Perl Net-IP^].

Additional notes for certain contexts are primarily taken from https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing[the Wikipedia article on _Classless Inter-Domain Routing_^] (as of _Jan 28, 2025_).

Reservations are pulled/cached directly from the IANA registries (https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml[IPv4^], https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml[IPv6^]).