std/ip

IPv4, IPv6, socket addresses and subnets as values, read from text and shown as text, with no natives and no capability - std/network and std/uri both use them.

Diese Seite gibt es noch nicht auf Deutsch, deshalb steht sie hier auf Englisch. Zur englischen Seite

Die generierte Referenz von std/ip zeigt jede öffentliche Deklaration mit Signatur, Doc-Kommentar und Beispielen.

std/ip holds the addresses of the Internet Protocol as values: an IPv4 address, an IPv6 address, an address of either version, a socket address - an address and a port - and a subnet, a network as address/prefix. It touches nothing: it has no natives and needs no capability, so a package that only names an address - a URI whose host is an IP literal, a configuration file - does not claim the network by importing it. std/network connects to these addresses and re-exports every name of this package, so use SocketAddress from "std/network" and use SocketAddress from "std/ip" name the same type (see docs/design/URI.md section 8a). It is not in the prelude.

Import#

use IpAddress, Ipv4Address, Ipv6Address, SocketAddress, Subnet, AddressError from "std/ip"
use IpAddress, Ipv6Address, SocketAddress, Subnet from "std/ip"

const local = SocketAddress IpAddress.loopback, 8080
print local
match Subnet.tryFrom("10.0.0.0/8") {
  Ok(network) => print network.contains(IpAddress.loopback)
  Fail(problem) => print problem
}
match Ipv6Address.tryFrom("2001:DB8:0:0:0:0:0:1") {
  Ok(address) => print address
  Fail(problem) => print problem
}

Declarations#

type Ipv4Address with Show, Equals, Hash, Compare, TryFrom<String, AddressError> {
  static loopback = Self 2130706433
  static unspecified = Self 0
  static fn of(first: UInt8, second: UInt8, third: UInt8, fourth: UInt8): Self
  fn number(): Int
  fn octets(): List<Int>
  fn isLoopback(): Bool
  fn isUnspecified(): Bool
  fn isPrivate(): Bool
  fn isLinkLocal(): Bool
  fn isMulticast(): Bool
  fn show(): String
  fn compare(other: Self): Ordering
  static fn tryFrom(text: String): Result<Self, AddressError>
}
type Ipv6Address with Show, Equals, Hash, Compare, TryFrom<String, AddressError> {
  static loopback = Self 0, 1
  static unspecified = Self 0, 0
  static fn of(segments: List<Int>): Result<Self, AddressError>
  static fn ofHalves(high: Int, low: Int): Self
  fn high(): Int
  fn low(): Int
  fn segments(): List<Int>
  fn isLoopback(): Bool
  fn isUnspecified(): Bool
  fn isLinkLocal(): Bool
  fn isUniqueLocal(): Bool
  fn isMulticast(): Bool
  fn mappedVersion4(): Ipv4Address?
  fn show(): String
  fn compare(other: Self): Ordering
  static fn tryFrom(text: String): Result<Self, AddressError>
}
type IpAddress with Show, Equals, Hash, Compare, TryFrom<String, AddressError> {
  case Version4(address: Ipv4Address)
  case Version6(address: Ipv6Address)
  static loopback = Self.Version4 Ipv4Address.loopback
  fn isLoopback(): Bool
  fn isUnspecified(): Bool
  fn version(): Int
  fn show(): String
  fn compare(other: Self): Ordering
  static fn tryFrom(text: String): Result<Self, AddressError>
}
type SocketAddress with Show, Equals, Hash, TryFrom<String, AddressError> {
  address: IpAddress
  port: Int
  fn show(): String
  static fn tryFrom(text: String): Result<Self, AddressError>
}
type Subnet with Show, Equals, Hash, TryFrom<String, AddressError> {
  static fn of(address: IpAddress, prefixLength: Int): Result<Self, AddressError>
  fn address(): IpAddress
  fn prefixLength(): Int
  fn contains(address: IpAddress): Bool
  fn show(): String
  static fn tryFrom(text: String): Result<Self, AddressError>
}
type AddressError with Show, Error {
  text: String
  reason: String
  fn show(): String
}

Values like any other, read from text with tryFrom and shown as text. An IPv4 address is four decimal parts from 0 to 255; a part with a leading zero is refused, because some systems read 010 as octal. An IPv6 address shows in the RFC 5952 form: lower case, no leading zeros, the longest run of zero segments collapsed to ::, and an IPv4-mapped address with its IPv4 part (::ffff:192.0.2.1). A zone (fe80::1%eth0) is not part of an address and is refused. Ipv4Address.loopback, Ipv6Address.loopback, IpAddress.loopback and the unspecified addresses are constants, and isLoopback(), isPrivate(), isLinkLocal(), isMulticast() answer what they say. A SocketAddress shows as 127.0.0.1:8080 or [::1]:8080. IpAddress orders every IPv4 address before every IPv6 address.

A Subnet is a network, 10.0.0.0/8 or fe80::/64: the address of its first host and the number of leading bits every address in it shares. It is always a network - the bits of the address after the prefix are zero - so 192.168.1.23/24 is refused instead of being rounded down, and 192.168.1.0/24 is the value. Subnet is a capsule: its fields are private, so no Subnet can hold a prefix the address does not fit or host bits that are set; Subnet.of and tryFrom are the ways in, and address() and prefixLength() the two reads. Both refuse a prefix outside 0..32 (version 4) or 0..128 (version 6) and an address with host bits set; tryFrom also refuses a missing /, a prefix that is empty, signed, has a leading zero or is not a number, and a zone on the address, like it is for an IpAddress. show() is the address in its own text form, a / and the prefix, and tryFrom(show()) gives the value back.

contains(address) is true for every address that shares the prefix, the first and the last of the network included. /0 holds every address of its own version and none of the other, /32 and /128 exactly one. An address of the other version is never in a subnet, and an IPv4-mapped IPv6 address is not matched against a version 4 subnet either: map it with mappedVersion4() first if that is what you mean.

use AddressError, IpAddress, Subnet from "std/ip"

fn main(): Result<Void, AddressError> {
  const office = Subnet.tryFrom("192.168.1.0/24")?
  print office.contains(IpAddress.tryFrom("192.168.1.255")?)
  print office.contains(IpAddress.tryFrom("192.168.2.0")?)
  match Subnet.tryFrom("192.168.1.23/24") {
    Ok(network) => print network
    Fail(problem) => print problem
  }
  Ok void
}
  • std/network - resolving names into these addresses, and connecting to them.
  • std/uri - a URI whose host is an IP literal holds one of these, and answers a SocketAddress.
  • The standard library - the other packages.
Esc