Oberon || Library || Module Index || Search Engine || Definition || Module

Ulm's Oberon Library:


HostPorts - support of host/port tuple specifications according to RFCs 2373, 2396, and 2732


TYPE HostPort = POINTER TO HostPortRec;
TYPE HostPortRec =
      port: INTEGER;
      host: DNSRecords.Name;
TYPE IPv4HostPort = POINTER TO IPv4HostPortRec;
TYPE IPv4HostPortRec =
      address: IPv4Addresses.SocketAddress;
TYPE IPv6HostPort = POINTER TO IPv6HostPortRec;
TYPE IPv6HostPortRec =
      address: IPv6Addresses.SocketAddress;

TYPE AddIPv4Address = PROCEDURE (service: Disciplines.Object; address: IPv4Addresses.SocketAddress) : BOOLEAN; TYPE AddIPv6Address = PROCEDURE (service: Disciplines.Object; address: IPv6Addresses.SocketAddress) : BOOLEAN; TYPE Interface = POINTER TO InterfaceRec; TYPE InterfaceRec = RECORD (Objects.ObjectRec) addIPv4Address: AddIPv4Address; addIPv6Address: AddIPv6Address; END;

CONST unexpectedEOF = 0; CONST closingBracketMissing = 1; CONST hostnameTooLong = 2; CONST tooManyDots = 3; CONST invalidPort = 4; CONST errors = 5; TYPE ErrorCode = SHORTINT; (* unexpectedEOF... *) TYPE ErrorEvent = POINTER TO ErrorEventRec; TYPE ErrorEventRec = RECORD (Events.EventRec) errorcode: ErrorCode; END; VAR errormsg: ARRAY errors OF Events.Message; VAR error: Events.EventType;

PROCEDURE SetDefaultPort(s: Streams.Stream; port: INTEGER); PROCEDURE SetPort(s: Streams.Stream; port: INTEGER);

PROCEDURE ReadText(s: Streams.Stream; VAR hostport: HostPort) : BOOLEAN; PROCEDURE WriteText(s: Streams.Stream; hostport: HostPort);

PROCEDURE CreateAddress(VAR address: Networks.Address; hostport: HostPort);

PROCEDURE ReadAddress(s: Streams.Stream; VAR address: Networks.Address) : BOOLEAN;

PROCEDURE Init(service: Disciplines.Object; if: Interface); PROCEDURE Add(service: Disciplines.Object; hostport: HostPort) : BOOLEAN; PROCEDURE ReadAndAdd(s: Streams.Stream; service: Disciplines.Object) : BOOLEAN;


HostPorts supports the textual specification of hosts, either in domain style or as numerical IP address, and an optional port number. The term hostport was coined within RFC 2396 which provides the generic syntax for Uniform Resource Identifiers (URI). This syntax was extended by RFC 2732 to support IPv6 addresses which were already specified in RFC 2373. There exist other modules to parse and convert domain names (DNSResolvers, and InetResolver), and numeric IP addresses (IPv4Addresses, IPv6Addresses). The goal of this module is to provide a uniform interface for all these variants which allow to specify a host/port tuple by giving

Following syntax is given by RFCs 2396 and 2732:

= host [ ":" port ]
= hostname | IPv4address | IPv6reference
= *( domainlabel "." ) toplabel [ "." ]
= alphanum | alphanum *( alphanum | "-" ) alphanum
= alpha | alpha *( alphanum | "-" ) alphanum
= 1*digit "." 1*digit "." 1*digit "." 1*digit
= *digit
= "[" IPv6address "]"
= see RFC 2373
Note that the colon is used as separator between the host and the port specification but also as delimiter within IPv6 addresses. For this reason, RFC 2732 requires numeric IPv6 addresses to be enclosed in brackets. HostPorts allows the brackets to be omitted if the port number is no longer part of the address. This can be achieved by invoking SetPort for the input stream before calling ReadText.

SetDefaultPort sets the default port of a specification for the given input stream if the port is omitted. SetPort causes ReadText not to look for a port in the input specification and to take the given value instead.

Read host/port tuples are represented by HostPort objects which come in two extensions: IPv4HostPort and IPv6HostPort. The common fields host and port are close to the actual input seen by ReadText, i.e. if a numerical IP address was given, host provides the corresponding text represenation (without the brackets in case of IPv6 addresses). The extensions provide the associated address specifications which can be passed on to IPv4TCPSockets, IPv6TCPSockets, InetTCP, Inet6TCP, or, after a conversion to the internal format, to SysSockets. HostPort objects are to be created only by ReadText.

ReadText parses a hostport specification from the given input specification, and, if successful, creates a HostPort object for it. WriteText prints a textual representation of hostport to s which is close to the original input.

CreateAddress uses InetTCP or Inet6TCP to create an abstract network address object of Networks. ReadAddress combines ReadText and CreateAddress.

To ease the specification of IPv4 or IPv6 addresses to other modules, an interface is provided which allows Add to pass on the address to the corresponding procedure. For this to work, the module that accepts addresses has to define an interface consisting of addIPv4Address and addIPv6Address and to associate it with its newly created object using Init. Afterwards, client modules are free to use Add or ReadAndAdd to pass hostport specifications to an object.


Following code snippet demonstrates how hostport specifications out of command line arguments can be forwarded to a server object that supports the interface that is required by ReadAndAdd:
RelatedEvents.Forward(args, server);
HostPorts.SetDefaultPort(args, 53);
IF ~HostPorts.ReadAndAdd(args, server) THEN
   Conclusions.Conclude(server, Errors.fatal, "");


Error events can be generated by the underlying modules (including IPv4Addresses and IPv6Addresses). In addition, following errors can be raised by ReadText:
the input stream ended before a complete hostport specification could be read
an bracketed IPv6 address was given but the closing bracket is missing
the hostname part was longer than permitted by RFC 1035
more dots were found in the hostname specification that permitted by the corresponding syntax, i.e. consecutive or leading dots were found
an invalid port was specified which was outside the range of [0,65535].


parsing of IPv4 addresses
IPv4 TCP sockets
parsing of IPv6 addresses
IPv6 TCP sockets

Edited by: borchert, last change: 2006/08/11, revision: 1.1, converted to HTML: 2006/08/11

Oberon || Library || Module Index || Search Engine || Definition || Module