cidrv6PrefixLength(mask: Maskv6): PrefixLengthv6
Recovers the prefix length from an IPv6 network mask given as a bigint.
Recovering prefix lengths from bigints
Recovering prefix lengths from bigints
import { assertEquals } from "@std/assert"; import { cidrv6PrefixLength } from "@hertzg/ip/cidrv6"; assertEquals(cidrv6PrefixLength(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFn), 128); assertEquals(cidrv6PrefixLength(0xFFFFFFFFFFFFFFFF0000000000000000n), 64); assertEquals(cidrv6PrefixLength(0xFFFFFFFFFFFF00000000000000000000n), 48); assertEquals(cidrv6PrefixLength(0xFFFFFFFF000000000000000000000000n), 32); assertEquals(cidrv6PrefixLength(0n), 0);
mask: Maskv6
The network mask as a bigint
The prefix length (0-128)
cidrv6PrefixLength(cidr: Cidrv6): PrefixLengthv6
Returns the prefix length of an IPv6 CIDR block.
A PrefixedCidrv6 gives back the prefix length it stores; a
MaskedCidrv6 has its mask converted, which is where this can
throw: a mask such as ffff:0:ffff:: describes no prefix length, so a
block storing one has no answer here (ADR 0006).
Both dialects yield the same prefix length
Both dialects yield the same prefix length
import { assertEquals } from "@std/assert"; import { cidrv6PrefixLength, parseCidrv6 } from "@hertzg/ip/cidrv6"; assertEquals(cidrv6PrefixLength(parseCidrv6("2001:db8::/32")), 32); assertEquals( cidrv6PrefixLength({ address: 0x20010db8n << 96n, mask: 0xFFFFFFFF000000000000000000000000n }), 32, );
cidr: Cidrv6
The CIDR block
The prefix length (0-128)
cidrv6PrefixLength(mask: string): PrefixLengthv6
Recovers the prefix length from an IPv6 network mask given in colon-hexadecimal notation.
The string is parsed with the same rules as parseAddressv6 and then interpreted as a mask rather than an address.
Note that IPv6 has no standard netmask notation. RFC 4291 section 2.3
defines exactly one way to write a prefix -- address/prefix-length --
and nothing equivalent to IPv4's dotted netmask. A string like
"ffff:ffff:ffff:ffff::" is a well-formed IPv6 address literal whose
128 bits are being read as a mask. It is accepted here because system
APIs do report masks that way: POSIX getifaddrs() fills ifa_netmask
with a sockaddr_in6, which is what Deno.networkInterfaces() surfaces
as netmask: "ffff:ffff:ffff:ffff::". Prefer the prefix length when a
source offers one -- those same APIs usually also report cidr.
Recovering prefix lengths from colon-hexadecimal
Recovering prefix lengths from colon-hexadecimal
import { assertEquals } from "@std/assert"; import { cidrv6PrefixLength } from "@hertzg/ip/cidrv6"; assertEquals(cidrv6PrefixLength("ffff:ffff:ffff:ffff::"), 64); assertEquals(cidrv6PrefixLength("ffff:ffff::"), 32); assertEquals(cidrv6PrefixLength("::"), 0);
The prefix length (0-128)
cidrv6PrefixLength(cidrOrMask: Cidrv6 | Maskv6 | string): PrefixLengthv6
Recovers the prefix length from an IPv6 CIDR block or network mask.
The inverse of cidrv6Mask. Accepts a Cidrv6 in either dialect, a bigint, or colon-hexadecimal notation.
A CIDR mask is a run of one bits from the most significant end followed by zeros; masks that do not have that shape describe no prefix length at all and are rejected rather than answered with a plausible-looking count of set bits. This is the one place a stored mask is checked, because it is the one call that has no answer for it (ADR 0006).
Both forms agree
Both forms agree
import { assertEquals } from "@std/assert"; import { cidrv6PrefixLength } from "@hertzg/ip/cidrv6"; assertEquals(cidrv6PrefixLength("ffff:ffff:ffff:ffff::"), 64); assertEquals(cidrv6PrefixLength(0xFFFFFFFFFFFFFFFF0000000000000000n), 64);
Non-contiguous masks throw, in either form
Non-contiguous masks throw, in either form
import { assertThrows } from "@std/assert"; import { cidrv6PrefixLength } from "@hertzg/ip/cidrv6"; assertThrows(() => cidrv6PrefixLength(0xFFFF0000FFFF00000000000000000000n), TypeError); assertThrows(() => cidrv6PrefixLength("ffff:0:ffff::"), TypeError); assertThrows(() => cidrv6PrefixLength("::ffff:ffff"), TypeError);
Round-trips with cidrv6Mask
Round-trips with cidrv6Mask
import { assertEquals } from "@std/assert"; import { cidrv6Mask, cidrv6PrefixLength } from "@hertzg/ip/cidrv6"; for (let prefixLength = 0; prefixLength <= 128; prefixLength++) { assertEquals(cidrv6PrefixLength(cidrv6Mask(prefixLength)), prefixLength); }
Error handling
Error handling
import { assertThrows } from "@std/assert"; import { cidrv6PrefixLength } from "@hertzg/ip/cidrv6"; // Wrong shape -- in range, but not a mask assertThrows(() => cidrv6PrefixLength(0xFFFF0000FFFF00000000000000000000n), TypeError); assertThrows(() => cidrv6PrefixLength("ffff:0:ffff::"), TypeError); // Malformed notation assertThrows(() => cidrv6PrefixLength("gggg::"), TypeError); // Wrong range -- not a 128-bit unsigned integer at all assertThrows(() => cidrv6PrefixLength(-1n), RangeError); assertThrows(() => cidrv6PrefixLength(1n << 128n), RangeError);
The prefix length (0-128)