IPv4 and IPv6 address parsing, stringifying, and CIDR utilities.

This module provides functions for working with IPv4 and IPv6 addresses and CIDR notation. IPv4 addresses are represented as numbers (32-bit), IPv6 as bigints (128-bit), enabling efficient arithmetic operations and range manipulation for network programming tasks.

Features

  • One Notation Grammar: address[%zoneId][/prefix], every parser a narrowing of it; zone IDs carried verbatim, masks accepted as a second CIDR dialect
  • Dual-Stack Support: Auto-unwrap IPv4-mapped IPv6 addresses from dual-stack sockets
  • IP Classification: Identify private, loopback, multicast, public, and other well-known ranges
  • CIDR Support: Parse CIDR notation, check containment, compute network boundaries; blocks carry a prefix length or a mask
  • Sorting: Version-first comparators for addresses and CIDR blocks, mixed lists included
  • IPv4 & IPv6 Parsing: Convert between standard notation and number/bigint for arithmetic
  • Address Generation: Lazily enumerate addresses in CIDR blocks
  • IPv4-Mapped Conversion: Convert between IPv4 and IPv4-mapped IPv6 addresses and CIDRs
  • Validation: Non-throwing validity checks for IP addresses and CIDR notation
  • Wire Bytes: Read and write addresses directly in packet buffers, no string round-trip
  • Reverse DNS: Build the in-addr.arpa / ip6.arpa pointer name of an address

SSRF Guard

Examples

Reject a fetch target that resolves inside your own network

import { assertEquals } from "@std/assert";
import { classifyAddress } from "@hertzg/ip";

// A guard that only checks loopback and link-local misses private, CGNAT,
// and multicast ranges; classification is one label from a closed set, so
// there's no list of booleans to keep in sync
function isSafeToFetch(host: string): boolean {
  const { classification } = classifyAddress(host); // v4, v6, or mapped, one call
  return classification === "public" || classification === "global-unicast";
}

assertEquals(isSafeToFetch("8.8.8.8"), true);
assertEquals(isSafeToFetch("2001:4860:4860::8888"), true);

assertEquals(isSafeToFetch("127.0.0.1"), false);
assertEquals(isSafeToFetch("10.0.0.1"), false);
assertEquals(isSafeToFetch("169.254.169.254"), false); // cloud metadata endpoint
assertEquals(isSafeToFetch("::ffff:127.0.0.1"), false); // mapped, unwrapped first

Trusted Network Allowlist

Check if a client IP is in a set of trusted CIDR blocks

import { assert, assertEquals } from "@std/assert";
import { cidrContains, parseCidr, parseAddress } from "@hertzg/ip";

// The list may mix IP versions; each entry is only ever compared against an
// address of its own version, and a mismatch is a miss rather than an error
const trustedRanges = [
  "10.0.0.0/8",
  "172.16.0.0/12",
  "192.168.0.0/16",
  "fd00::/8",
].map((s) => parseCidr(s));

function isTrusted(ip: string): boolean {
  const address = parseAddress(ip).address;
  return trustedRanges.some((cidr) => cidrContains(cidr, address));
}

assert(isTrusted("192.168.1.100"));
assert(isTrusted("10.0.0.1"));
assert(isTrusted("::ffff:172.16.5.1")); // parseAddress unwrapped this to IPv4 first
assert(isTrusted("fd00::1")); // matched the IPv6 entry, no conversion involved

assertEquals(isTrusted("8.8.8.8"), false);
assertEquals(isTrusted("2001:db8::1"), false);

Dual-Stack Server

Normalize client addresses from a dual-stack server

import { assertEquals } from "@std/assert";
import { classifyAddress, parseAddress, stringifyAddress } from "@hertzg/ip";

// Dual-stack servers (Deno, Node) report IPv4 clients as ::ffff:x.x.x.x
// parseAddress auto-unwraps mapped addresses to their IPv4 form
const remote1 = parseAddress("::ffff:192.168.1.50").address;
assertEquals(stringifyAddress(remote1), "192.168.1.50");

// Native IPv6 clients pass through unchanged
const remote2 = parseAddress("2001:db8::1").address;
assertEquals(stringifyAddress(remote2), "2001:db8::1");

// Classification works on both
assertEquals(classifyAddress(remote1).classification, "private");
assertEquals(classifyAddress(remote2).classification, "documentation");

IP Classification

Classify addresses for logging, analytics, or input validation

import { assertEquals } from "@std/assert";
import { classifyAddress } from "@hertzg/ip";

// Classify any IP — result includes kind, numeric value, and label
const result = classifyAddress("192.168.1.1");
assertEquals(result.kind, "ipv4");
assertEquals(result.classification, "private");

assertEquals(classifyAddress("127.0.0.1").classification, "loopback");
assertEquals(classifyAddress("8.8.8.8").classification, "public");
assertEquals(classifyAddress("169.254.1.1").classification, "link-local");

// Works with IPv6 too
assertEquals(classifyAddress("::1").classification, "loopback");
assertEquals(classifyAddress("fe80::1").classification, "link-local");
assertEquals(classifyAddress("fd00::1").classification, "unique-local");

// Use with Zod as a custom validator that accepts allowed classifications:
//
// import { type Classificationv4, type Classificationv6,
//   classifyAddress } from "@hertzg/ip";
//
// function ipClassification(
//   ...allowed: (Classificationv4 | Classificationv6)[]
// ) {
//   const set = new Set(allowed);
//   return z.string().refine(
//     (val) => set.has(classifyAddress(val).classification),
//     { message: `IP must be: ${allowed.join(", ")}` },
//   );
// }
//
// const publicIp = ipClassification("public", "global-unicast");
// publicIp.parse("8.8.8.8");       // ok
// publicIp.parse("192.168.1.1");   // throws: private
//
// const internalIp = ipClassification("private", "loopback");
// internalIp.parse("10.0.0.1");    // ok
// internalIp.parse("8.8.8.8");     // throws: public

Sorting

Sort a mixed dual-stack list of addresses and CIDR blocks

import { assertEquals } from "@std/assert";
import { compareCidr, compareAddress, parseCidr, parseAddress, stringifyAddress, stringifyCidr } from "@hertzg/ip";

// All IPv4 sorts before all IPv6, numerically ascending within each version
const clients = ["2001:db8::1", "10.0.0.10", "::1", "10.0.0.2"].map((s) => parseAddress(s).address);
assertEquals(clients.toSorted(compareAddress).map(stringifyAddress), [
  "10.0.0.2",
  "10.0.0.10",
  "::1",
  "2001:db8::1",
]);

// CIDR blocks tie-break on prefix length: the larger block comes first
const ranges = ["10.0.0.0/16", "2001:db8::/32", "10.0.0.0/8"].map((s) => parseCidr(s));
assertEquals(ranges.toSorted(compareCidr).map(stringifyCidr), [
  "10.0.0.0/8",
  "10.0.0.0/16",
  "2001:db8::/32",
]);

Parsing and Stringifying

Parse and stringify IPv4 and IPv6 addresses

import { assertEquals } from "@std/assert";
import { parseAddressv4, parseAddressv6, stringifyAddressv4, stringifyAddressv6 } from "@hertzg/ip";

// IPv4: string <-> 32-bit number
const v4 = parseAddressv4("192.168.1.1").address;
assertEquals(v4, 3232235777);
assertEquals(stringifyAddressv4(v4), "192.168.1.1");
assertEquals(stringifyAddressv4(v4 + 1), "192.168.1.2");

// IPv6: string <-> 128-bit bigint
const v6 = parseAddressv6("2001:db8::1").address;
assertEquals(v6, 42540766411282592856903984951653826561n);
assertEquals(stringifyAddressv6(v6), "2001:db8::1");
assertEquals(stringifyAddressv6(v6 + 1n), "2001:db8::2");

CIDR Network Boundaries

Compute network and broadcast addresses from CIDR

import { assertEquals } from "@std/assert";
import {
  cidrv4BroadcastAddress,
  cidrv4NetworkAddress,
  cidrv4Size,
  parseCidrv4,
  stringifyAddressv4,
} from "@hertzg/ip";

const cidr = parseCidrv4("192.168.1.0/24");

assertEquals(stringifyAddressv4(cidrv4NetworkAddress(cidr)), "192.168.1.0");
assertEquals(stringifyAddressv4(cidrv4BroadcastAddress(cidr)), "192.168.1.255");
assertEquals(cidrv4Size(cidr), 256);

Containment Checking

Check if IPs fall within a CIDR block

import { assert, assertEquals } from "@std/assert";
import { cidrv4Contains, parseCidrv4, parseAddressv4 } from "@hertzg/ip";

const cidr = parseCidrv4("10.0.0.0/8");

assert(cidrv4Contains(cidr, parseAddressv4("10.0.0.1").address));
assert(cidrv4Contains(cidr, parseAddressv4("10.255.255.255").address));
assertEquals(cidrv4Contains(cidr, parseAddressv4("11.0.0.0").address), false);

Address Enumeration

Generate addresses in a CIDR block

import { assertEquals } from "@std/assert";
import { cidrv4Addresses, parseCidrv4, stringifyAddressv4 } from "@hertzg/ip";

const cidr = parseCidrv4("10.0.0.0/29"); // 8 addresses

// Iterate all addresses
const all = Array.from(cidrv4Addresses(cidr));
assertEquals(all.map(stringifyAddressv4), [
  "10.0.0.0", "10.0.0.1", "10.0.0.2", "10.0.0.3",
  "10.0.0.4", "10.0.0.5", "10.0.0.6", "10.0.0.7",
]);

// Skip network address, take first 3 usable
const usable = Array.from(cidrv4Addresses(cidr, { offset: 1, count: 3 }));
assertEquals(usable.map(stringifyAddressv4), ["10.0.0.1", "10.0.0.2", "10.0.0.3"]);

Wire Bytes

Decode addresses straight out of a packet buffer

import { assertEquals } from "@std/assert";
import { addressv4FromBytes, addressv4ToBytes, stringifyAddressv4 } from "@hertzg/ip";

// deno-fmt-ignore
const packet = new Uint8Array([
  0x45, 0x00, 0x00, 0x54, 0x1c, 0x46, 0x40, 0x00,
  0x40, 0x06, 0x00, 0x00,
  10, 0, 0, 1,
  192, 168, 1, 1,
]);

// Read the source and destination fields in place
assertEquals(stringifyAddressv4(addressv4FromBytes(packet, 12)), "10.0.0.1");
assertEquals(stringifyAddressv4(addressv4FromBytes(packet, 16)), "192.168.1.1");

// Rewrite the destination in place; the return is only the bytes written
const written = addressv4ToBytes(addressv4FromBytes(packet, 12), packet, 16);
assertEquals(written, new Uint8Array([10, 0, 0, 1]));
assertEquals(stringifyAddressv4(addressv4FromBytes(packet, 16)), "10.0.0.1");

Reverse DNS

The names are relative -- no trailing dot. Append "." if a resolver requires an absolute name.

Build the name a PTR record lives at

import { assertEquals } from "@std/assert";
import { addressToArpa, parseAddress } from "@hertzg/ip";

assertEquals(addressToArpa(parseAddress("192.168.0.1").address), "1.0.168.192.in-addr.arpa");
assertEquals(
  addressToArpa(parseAddress("2001:db8::1").address),
  "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa",
);

API Reference

Universal (auto-detect IPv4/IPv6)

  • Address: An IP address of either version (number or bigint)
  • ParsedAddress: What parseAddress returns, the address plus an optional zone ID
  • ParseOptions: Options for the universal parsers, unmapToV4
  • parseAddress: Parse any IP address string, with an optional zone ID, to number (IPv4) or bigint (IPv6)
  • stringifyAddress: Convert an address, bare or parsed, to IP address string
  • Cidr: A CIDR block of either version, in either dialect (prefix length or mask)
  • ParsedCidr: What parseCidr returns, the block plus an optional zone ID
  • Mask: A network mask of either version (number or bigint)
  • PrefixLength: A prefix length of either version
  • parseCidr: Parse any CIDR notation string, in either dialect and with an optional zone ID
  • stringifyCidr: Convert a Cidr, parse result or address to CIDR notation string, in the dialect it stores
  • cidrSize: Get total number of addresses in a CIDR block
  • cidrFirstAddress: Get the first address of a CIDR block
  • cidrLastAddress: Get the last address of a CIDR block
  • cidrAddresses: Generate IP addresses in a CIDR block
  • cidrContains: Check if a CIDR block contains an address
  • cidrContainsCidr: Check if one CIDR fully contains another
  • cidrOverlaps: Check if two CIDRs share at least one address
  • cidrIntersect: Return the overlapping CIDR block, or null
  • cidrSubtract: Return CIDR blocks in A but not in B
  • cidrMerge: Merge CIDR blocks into the minimal covering set
  • compareAddress: Compare two IP addresses of either version for sorting
  • compareCidr: Compare two CIDR blocks of either version for sorting
  • isValidAddress: Check if a string is a valid plain IP address (IPv4 or IPv6)
  • isValidCidr: Check if a string is valid CIDR notation (IPv4 or IPv6)
  • addressVersion: Report which IP version an address string is written in, or undefined
  • cidrVersion: Report which IP version a CIDR string is written in, or undefined
  • IpVersion: An IP version number, 4 or 6
  • classifyAddress: Classify an IPv4 (number) or IPv6 (bigint) address
  • ClassifiedAddress: Discriminated union result with kind, value, and classification
  • ClassifiedAddressv4: Result type for IPv4 classification
  • ClassifiedAddressv6: Result type for IPv6 classification

Notation

  • splitNotation: Split address[%zoneId][/prefix] into its three slots without reading them
  • Notation: The three slots as slices
  • ZoneId: The zone ID after %, a string

IPv4

IPv4 CIDR

IPv6

IPv6 CIDR

IPv4 Classification

IPv6 Classification

IPv4-Mapped IPv6 Conversion (addressv6, cidrv6)

Universal Wire Byte Conversion (bytes)

IPv4 Wire Byte Conversion (bytesv4)

IPv6 Wire Byte Conversion (bytesv6)

Universal Reverse DNS Pointer Names (arpa)

  • addressToArpa: Build the pointer name of an address of either version

IPv4 Reverse DNS Pointer Names (arpav4)

IPv6 Reverse DNS Pointer Names (arpav6)

Submodules

Functions

f
addressFromBytes(bytes: Uint8Array): Address

Reads an IPv4 or IPv6 address from a buffer, picking the version from its length.

f
addressToArpa(address: Address): string

Builds the reverse DNS pointer name of an IP address of either version.

f
addressToBytes(
address: Address,
into?: Uint8Array,
offset?: number
): Uint8Array

Writes an IPv4 or IPv6 address, either into a fresh buffer or into one you supply.

f
addressv4FromBytes(
bytes: Uint8Array,
offset?: number
): number

Reads a 4-byte IPv4 address from a buffer.

f
addressv4ToArpa(address: number): string

Builds the reverse DNS pointer name of an IPv4 address.

f
addressv4ToBytes(
address: number,
into?: Uint8Array,
offset?: number
): Uint8Array

Writes a 4-byte IPv4 address, either into a fresh buffer or into one you supply.

f
addressv6FromBytes(
bytes: Uint8Array,
offset?: number
): bigint

Reads a 16-byte IPv6 address from a buffer.

f
addressv6ToArpa(address: bigint): string

Builds the reverse DNS pointer name of an IPv6 address.

f
addressv6ToBytes(
address: bigint,
into?: Uint8Array,
offset?: number
): Uint8Array

Writes a 16-byte IPv6 address, either into a fresh buffer or into one you supply.

f
addressVersion(address: string): IpVersion | undefined

Reports which IP version a plain address string is written in.

f
cidrContains(
cidr: Cidr,
address: Address
): boolean

Checks if a CIDR block contains an address.

f
cidrContainsCidr(
outer: Cidr,
inner: Cidr
): boolean
1 overloads

Checks if one CIDR block fully contains another.

f
cidrFirstAddress(cidr: Cidr): Address
1 overloads

Returns the first address of a CIDR block.

f
cidrIntersect(
a: Cidr,
b: Cidr
): Cidr | null
1 overloads

Returns the intersection of two CIDR blocks.

f
cidrLastAddress(cidr: Cidr): Address
1 overloads

Returns the last address of a CIDR block.

f
cidrMerge(cidrs: readonly Cidr[]): Cidr[]
1 overloads

Merges CIDR blocks into the minimal covering set.

f
cidrOverlaps(
a: Cidr,
b: Cidr
): boolean
1 overloads

Checks if two CIDR blocks overlap (share at least one address).

f
cidrSize(cidr: Cidr): number | bigint
1 overloads

Returns the total number of addresses in a CIDR block.

f
cidrSubtract(
a: Cidr,
b: Cidr
): Cidr[]
1 overloads

Subtracts one CIDR block from another.

f
cidrv4BroadcastAddress(cidr: Cidrv4): number

Returns the directed broadcast address of a CIDR block.

f
cidrv4Contains(
cidr: Cidrv4,
address: number
): boolean

Checks if an IPv4 address is contained within a CIDR block.

f
cidrv4ContainsCidr(
outer: Cidrv4,
inner: Cidrv4
): boolean

Checks if one IPv4 CIDR block fully contains another.

f
cidrv4FirstAddress(cidr: Cidrv4): number

Returns the first address of a CIDR block (network address).

f
cidrv4FirstUsableAddress(cidr: Cidrv4): number

Returns the first assignable address of a CIDR block.

f
cidrv4Intersect(
a: Cidrv4,
b: Cidrv4
): Cidrv4 | null

Returns the intersection of two IPv4 CIDR blocks.

f
cidrv4LastAddress(cidr: Cidrv4): number

Returns the last address of a CIDR block (broadcast address for IPv4).

f
cidrv4LastUsableAddress(cidr: Cidrv4): number

Returns the last assignable address of a CIDR block.

f
cidrv4Mask(cidrOrPrefixLength: Cidrv4 | PrefixLengthv4): Maskv4
3 overloads

Creates a network mask from an IPv4 prefix length.

f
cidrv4Merge(cidrs: readonly Cidrv4[]): Cidrv4[]

Merges IPv4 CIDR blocks into the minimal covering set.

f
cidrv4NetworkAddress(cidr: Cidrv4): number

Returns the network address of a CIDR block.

f
cidrv4Overlaps(
a: Cidrv4,
b: Cidrv4
): boolean

Checks if two IPv4 CIDR blocks overlap (share at least one address).

f
cidrv4PrefixLength(cidrOrMask: Cidrv4 | Maskv4 | string): PrefixLengthv4
4 overloads

Recovers the prefix length from an IPv4 network mask given as a 32-bit unsigned integer.

f
cidrv4Size(cidrOrPrefixLength: Cidrv4 | PrefixLengthv4): number
3 overloads

Returns the total number of IP addresses in a CIDR block.

f
cidrv4Subtract(
a: Cidrv4,
b: Cidrv4
): Cidrv4[]

Subtracts one IPv4 CIDR block from another.

f
cidrv4UsableAddresses(cidr: Cidrv4): Generator<number>

Generates every assignable address in a CIDR block, in ascending order.

f
cidrv4UsableSize(cidrOrPrefixLength: Cidrv4 | PrefixLengthv4): number
3 overloads

Returns the number of assignable addresses in a CIDR block.

f
cidrv6Contains(
cidr: Cidrv6,
address: bigint
): boolean

Checks if an IPv6 address is contained within a CIDR block.

f
cidrv6ContainsCidr(
outer: Cidrv6,
inner: Cidrv6
): boolean

Checks if one IPv6 CIDR block fully contains another.

f
cidrv6FirstAddress(cidr: Cidrv6): bigint

Returns the first address of a CIDR block.

f
cidrv6Intersect(
a: Cidrv6,
b: Cidrv6
): Cidrv6 | null

Returns the intersection of two IPv6 CIDR blocks.

f
cidrv6LastAddress(cidr: Cidrv6): bigint

Returns the last address of a CIDR block.

f
cidrv6Mask(cidrOrPrefixLength: Cidrv6 | PrefixLengthv6): Maskv6
3 overloads

Creates a network mask from an IPv6 prefix length.

f
cidrv6Merge(cidrs: readonly Cidrv6[]): Cidrv6[]

Merges IPv6 CIDR blocks into the minimal covering set.

f
cidrv6Overlaps(
a: Cidrv6,
b: Cidrv6
): boolean

Checks if two IPv6 CIDR blocks overlap (share at least one address).

f
cidrv6PrefixLength(cidrOrMask: Cidrv6 | Maskv6 | string): PrefixLengthv6
4 overloads

Recovers the prefix length from an IPv6 network mask given as a bigint.

f
cidrv6Size(cidrOrPrefixLength: Cidrv6 | PrefixLengthv6): bigint
3 overloads

Returns the total number of IP addresses in a CIDR block.

f
cidrv6Subtract(
a: Cidrv6,
b: Cidrv6
): Cidrv6[]

Subtracts one IPv6 CIDR block from another.

f
cidrVersion(cidr: string): IpVersion | undefined

Reports which IP version a CIDR notation string is written in.

f
classifyAddress(address: Address | string): ClassifiedAddress
4 overloads

Classifies an IPv4 address into its well-known range.

f
classifyAddressv4(address: number): Classificationv4

Classifies an IPv4 address into its well-known range.

f
classifyAddressv6(address: bigint): Classificationv6

Classifies an IPv6 address into its well-known range.

f
compareAddress(
a: Address,
b: Address
): -1 | 0 | 1

Compares two IP addresses of either version for sorting.

f
compareAddressv4(
a: Addressv4,
b: Addressv4
): -1 | 0 | 1

Compares two IPv4 addresses for sorting, numerically ascending.

f
compareAddressv6(
a: Addressv6,
b: Addressv6
): -1 | 0 | 1

Compares two IPv6 addresses for sorting, numerically ascending.

f
compareCidr(
a: Cidr,
b: Cidr
): -1 | 0 | 1

Compares two CIDR blocks of either version for sorting.

f
compareCidrv4(
a: Cidrv4,
b: Cidrv4
): -1 | 0 | 1

Compares two IPv4 CIDR blocks for sorting.

f
compareCidrv6(
a: Cidrv6,
b: Cidrv6
): -1 | 0 | 1

Compares two IPv6 CIDR blocks for sorting.

f
isAddressv4Benchmarking(address: number): boolean

Checks if an IPv4 address is in the benchmarking range (RFC 2544).

f
isAddressv4Broadcast(address: number): boolean

Checks if an IPv4 address is the limited broadcast address.

f
isAddressv4CgNat(address: number): boolean

Checks if an IPv4 address is in the Carrier-Grade NAT range (RFC 6598).

f
isAddressv4Documentation(address: number): boolean

Checks if an IPv4 address is in a documentation range (RFC 5737).

f
isAddressv4LinkLocal(address: number): boolean

Checks if an IPv4 address is a link-local address (RFC 3927).

f
isAddressv4Loopback(address: number): boolean

Checks if an IPv4 address is a loopback address (RFC 1122).

f
isAddressv4Multicast(address: number): boolean

Checks if an IPv4 address is a multicast address (RFC 5771).

f
isAddressv4Private(address: number): boolean

Checks if an IPv4 address is in a private range (RFC 1918).

f
isAddressv4Public(address: number): boolean

Checks if an IPv4 address is a public (globally routable) address.

f
isAddressv4Reserved(address: number): boolean

Checks if an IPv4 address is in the reserved range (RFC 1112).

f
isAddressv4ThisNetwork(address: number): boolean

Checks if an IPv4 address is in the "this network" range (RFC 791).

f
isAddressv6Benchmarking(address: bigint): boolean

Checks if an IPv6 address is in the benchmarking range (RFC 5180).

f
isAddressv6Documentation(address: bigint): boolean

Checks if an IPv6 address is in the documentation range (RFC 3849).

f
isAddressv6GlobalUnicast(address: bigint): boolean

Checks if an IPv6 address is a global unicast address (RFC 4291).

f
isAddressv6LinkLocal(address: bigint): boolean

Checks if an IPv6 address is a link-local address (RFC 4291).

f
isAddressv6Loopback(address: bigint): boolean

Checks if an IPv6 address is the loopback address (RFC 4291).

f
isAddressv6Mapped(address: bigint): boolean

Checks if an IPv6 address is an IPv4-mapped address (RFC 4291).

f
isAddressv6Multicast(address: bigint): boolean

Checks if an IPv6 address is a multicast address (RFC 4291).

f
isAddressv6Orchidv2(address: bigint): boolean

Checks if an IPv6 address is an ORCHIDv2 address (RFC 7343).

f
isAddressv6Teredo(address: bigint): boolean

Checks if an IPv6 address is a Teredo address (RFC 4380).

f
isAddressv6Translated(address: bigint): boolean

Checks if an IPv6 address is an IPv4-translated address (RFC 6052).

f
isAddressv6UniqueLocal(address: bigint): boolean

Checks if an IPv6 address is a unique local address (RFC 4193).

f
isAddressv6Unspecified(address: bigint): boolean

Checks if an IPv6 address is the unspecified address (RFC 4291).

f
isCidrv4(cidr: Cidr): cidr is Cidrv4

Type guard that checks whether a Cidr is an IPv4 CIDR block.

f
isCidrv6(cidr: Cidr): cidr is Cidrv6

Type guard that checks whether a Cidr is an IPv6 CIDR block.

f
isValidAddress(address: string): boolean

Checks if a string is a valid plain IP address (IPv4 or IPv6).

f
isValidAddressv4(address: string): boolean

Checks if a string is a valid IPv4 address in dotted decimal notation.

f
isValidAddressv6(address: string): boolean

Checks if a string is a valid IPv6 address in colon-hexadecimal notation.

f
isValidCidr(cidr: string): boolean

Checks if a string is valid IPv4 or IPv6 CIDR notation.

f
isValidCidrv4(cidr: string): boolean

Checks if a string is valid IPv4 CIDR notation.

f
isValidCidrv6(cidr: string): boolean

Checks if a string is valid IPv6 CIDR notation.

f
mapFromAddressv4(address: Addressv4): Addressv6

Converts an IPv4 address to its IPv4-mapped IPv6 representation.

f
mapFromCidrv4(cidr: Cidrv4): Cidrv6
3 overloads

Converts an IPv4 CIDR block with a prefix length to its IPv4-mapped IPv6 CIDR representation.

f
parseAddress(
address: string,
options?: ParseOptions
): ParsedAddress

Parses an IPv4 or IPv6 address string, with an optional zone ID, to its numeric value.

f
parseAddressv4(address: string): ParsedAddressv4

Parses an IPv4 address in dotted decimal notation, with an optional zone ID, to its numeric value.

f
parseAddressv6(address: string): ParsedAddressv6

Parses an IPv6 address in colon-hexadecimal notation, with an optional zone ID, to its numeric value.

f
parseCidr(
cidr: string,
options?: ParseOptions
): ParsedCidr

Parses IPv4 or IPv6 CIDR notation, in either dialect and with an optional zone ID.

f
parseCidrv4(cidr: string): ParsedCidrv4

Parses IPv4 CIDR notation, in either dialect and with an optional zone ID, to a ParsedCidrv4.

f
parseCidrv6(cidr: string): ParsedCidrv6

Parses IPv6 CIDR notation, in either dialect and with an optional zone ID, to a ParsedCidrv6.

f
splitNotation(notation: string): Notation

Splits an IP notation string into its address, zone ID and prefix slots.

f
stringifyAddress(address: Address | ParsedAddress): string

Stringifies an IPv4 (number) or IPv6 (bigint) address, bare or parsed, to its standard notation.

f
stringifyAddressv4(address: Addressv4 | ParsedAddressv4): string

Stringifies an IPv4 address to dotted decimal notation.

f
stringifyAddressv6(address: Addressv6 | ParsedAddressv6): string

Stringifies an IPv6 address to compressed colon-hexadecimal notation.

f
stringifyAddressv6Expanded(address: Addressv6 | ParsedAddressv6): string

Stringifies an IPv6 address to full uncompressed colon-hexadecimal notation.

f
stringifyCidr(cidr: Address | ParsedAddress | ParsedCidr): string

Stringifies a CIDR block of either version, or an address, to CIDR notation.

f
stringifyCidrv4(cidr: Addressv4 | ParsedAddressv4 | ParsedCidrv4): string

Stringifies an IPv4 CIDR block, or an address, to CIDR notation.

f
stringifyCidrv6(cidr: Addressv6 | ParsedAddressv6 | ParsedCidrv6): string

Stringifies an IPv6 CIDR block, or an address, to CIDR notation with the address compressed.

f
stringifyCidrv6Expanded(cidr: Addressv6 | ParsedAddressv6 | ParsedCidrv6): string

Stringifies an IPv6 CIDR block, or an address, to CIDR notation with the address written in full uncompressed colon-hexadecimal.

f
unmapToAddressv4(address: Addressv6): Addressv4

Extracts the IPv4 address from an IPv4-mapped IPv6 address.

f
unmapToCidrv4(cidr: Cidrv6): Cidrv4
3 overloads

Converts an IPv4-mapped IPv6 CIDR block with a prefix length to its IPv4 CIDR representation.

Type Aliases

T
Address = Addressv4 | Addressv6

A plain IP address of either IP version.

T
Addressv4 = number

An IPv4 address as a 32-bit unsigned integer, 0 to 4294967295. The primitive type is what carries the version: a number is IPv4, a bigint is IPv6 (ADR 0001).

T
Addressv6 = bigint

An IPv6 address as a 128-bit unsigned bigint, 0n to 2n ** 128n - 1n. The primitive type is what carries the version: a bigint is IPv6, a number is IPv4 (ADR 0001).

T
Cidr = Cidrv4 | Cidrv6

A CIDR block of either IP version.

T
Cidrv4 = PrefixedCidrv4 | MaskedCidrv4

Represents an IPv4 CIDR block.

T
Cidrv6 = PrefixedCidrv6 | MaskedCidrv6

Represents an IPv6 CIDR block.

T
ClassifiedAddress = ClassifiedAddressv4 | ClassifiedAddressv6

Result of classifying an IP address with version information and parsed value.

T
IpVersion = 4 | 6

An IP version number: 4 for IPv4, 6 for IPv6.

T
Mask = Maskv4 | Maskv6

A network mask of either IP version: a number for IPv4, a bigint for IPv6, the same split as Address.

T
MaskedCidrv4 = { readonly address: Addressv4; readonly mask: Maskv4; readonly prefixLength?: never; }

An IPv4 CIDR block written with a network mask, as in 10.0.0.0/255.0.0.0.

T
MaskedCidrv6 = { readonly address: Addressv6; readonly mask: Maskv6; readonly prefixLength?: never; }

An IPv6 CIDR block written with a network mask, as in 2001:db8::/ffff:ffff::.

T
Maskv4 = number

An IPv4 network mask as a 32-bit unsigned integer, e.g. 0xFFFFFF00 for /24.

T
Maskv6 = bigint

An IPv6 network mask as a 128-bit unsigned bigint, e.g. 0xFFFFFFFFFFFFFFFF0000000000000000n for /64.

T
Notation = { readonly address: string; readonly zoneId?: ZoneId; readonly prefix?: string; }

The three slots of an IP notation string, as slices of it, before any of them is read. Absent slots are absent, not empty: splitNotation rejects an empty slot rather than returning "".

T
ParsedAddress = ParsedAddressv4 | ParsedAddressv6

What parseAddress returns and what stringifyAddress accepts: a ParsedAddressv4 or a ParsedAddressv6. Read .address for the bare Address and narrow with typeof; the zone never touches the value, and no operation in this package reads it.

T
ParsedAddressv4 = { readonly address: Addressv4; readonly zoneId?: ZoneId; }

What parseAddressv4 returns and what stringifyAddressv4 accepts: the address, plus the zone ID if the notation had one. Read .address for the bare Addressv4; the zone never touches the value, and no operation in this package reads it.

T
ParsedAddressv6 = { readonly address: Addressv6; readonly zoneId?: ZoneId; }

What parseAddressv6 returns and what stringifyAddressv6 accepts: the address, plus the zone ID if the notation had one. Read .address for the bare Addressv6; the zone never touches the value, and no operation in this package reads it.

T
ParsedCidr = ParsedCidrv4 | ParsedCidrv6

What parseCidr returns and what stringifyCidr accepts: a ParsedCidrv4 or a ParsedCidrv6, the block in the dialect it was written in plus an optional zone ID. Assignable to Cidr, so a parse result goes straight into every cidr* operation; none of them reads the zone.

T
ParsedCidrv4 = Cidrv4 & { readonly zoneId?: ZoneId; }

What parseCidrv4 returns and what stringifyCidrv4 accepts: a Cidrv4 in the dialect it was written in, plus the zone ID if the notation had one (fe80::%ether1/64 has one; RouterOS emits that form for connected routes). Assignable to Cidrv4, so a parse result goes straight into every cidrv4* operation; none of them reads the zone.

T
ParsedCidrv6 = Cidrv6 & { readonly zoneId?: ZoneId; }

What parseCidrv6 returns and what stringifyCidrv6 accepts: a Cidrv6 in the dialect it was written in, plus the zone ID if the notation had one (fe80::%ether1/64, the form RouterOS and netstat -rn emit for link-local routes). Assignable to Cidrv6, so a parse result goes straight into every cidrv6* operation; none of them reads the zone.

T
ParseOptions = { readonly unmapToV4?: boolean; }

Options for the universal parsers, parseAddress and parseCidr. The version-specific parsers take none: they return their own version and nothing else.

  • unmapToV4: boolean

    Whether an IPv4-mapped IPv6 address (::ffff:a.b.c.d) is returned as the IPv4 value it carries. Defaults to true (ADR 0004): dual-stack listeners report IPv4 clients in the mapped form, and almost every caller wants the IPv4 view. Set to false to keep the bigint.

T
PrefixedCidrv4 = { readonly address: Addressv4; readonly prefixLength: PrefixLengthv4; readonly mask?: never; }

An IPv4 CIDR block written with a prefix length, as in 10.0.0.0/8.

T
PrefixedCidrv6 = { readonly address: Addressv6; readonly prefixLength: PrefixLengthv6; readonly mask?: never; }

An IPv6 CIDR block written with a prefix length, as in 2001:db8::/32.

T
PrefixLength = number

A prefix length of either IP version. Being a bare number it cannot say which version it belongs to, which is why there is no universal mask-from-prefix-length function: 24 is /24 in both, and the masks differ.

T
PrefixLengthv4 = number

An IPv4 prefix length, the 24 in /24. The range is 0 to 32; it is documented rather than encoded in the type, so prefixLength + 1 stays a PrefixLengthv4 (ADR 0002).

T
PrefixLengthv6 = number

An IPv6 prefix length, the 64 in /64. The range is 0 to 128; it is documented rather than encoded in the type, so prefixLength + 1 stays a PrefixLengthv6 (ADR 0002).

T
ZoneId = string

The zone ID of an address, the interface tail after % in fe80::1%eth0 (RFC 4007 section 11). Carried verbatim by the Parsed* types; never percent-decoded, so %25eth0 is the zone 25eth0.

Usage

import * as mod from "mod.ts";