# Compaq TCP/IP Services for OpenVMS
Guide to IPv6

Previous | Contents

# 6.4 Socket Options

To support IPv6, the `setsockopt` and `getsockopt` functions recognize a new IPPROTO_IPV6 level.

In addition, the `setsockopt` function defines the following new options:

Option | Function
--- | ---
IPV6_UNICAST_HOPS | Sets the hop limit for all subsequent unicast packets sent on a socket. You can also use this option with the `getsockopt` function to determine the current hop limit for a socket.
IPV6_MULTICAST_IF | Sets the interface to use for outgoing multicast packets.
IPV6_MULTICAST_HOPS | Sets the hop limit for outgoing multicast packets.
IPV6_MULTICAST_LOOP | Controls whether to deliver outgoing multicast packets back to the local application.
IPV6_JOIN_GROUP | Joins a multicast group on the specified interface.
IPV6_LEAVE_GROUP | Leaves a multicast group on the specified interface.

See RFC 2553 for more information on these socket options.

# 6.5 Library Functions

The following are the changes to the library functions to accommodate the IPv6 enhancements:

- Node name to address translation
- Address to node name translation
- Address conversion functions
- Address-testing macros

## 6.5.1 Node Name to Address Translation Functions

The following resolver options are available for node name to address translation:

Option | Function
--- | ---
`gethostbyname` | Existing function that returns IPv4 addresses.
`getaddrinfo` | New protocol-independent function for mapping names to addresses.
`freeaddrinfo` | New function that returns `addrinfo` structures and dynamic storage to the system.

The following sections describe these changes in detail.

### 6.5.1.1 getaddrinfo Function

The `getaddrinfo` function has the following syntax:

    #include <netdb.h>

    int getaddrinfo(
              const char *nodename,
              const char *servname,
              const struct addrinfo *hints,
              struct addrinfo **res);

Parameters

- nodename
  Points to a network node name, alias, or numeric host address (for example, an IPv4 dotted-decimal address or an IPv6 hexadecimal address). This is a null-terminated string or NULL. NULL means the service location is local to the caller. The nodename and servname parameters cannot both be NULL.
- servname
  Points to a network service name or port number. This is a null-terminated string or NULL; NULL returns network-level addresses for the specified nodename). The nodename and servname parameters cannot both be NULL.
- hints
  Points to an `addrinfo` structure that contains information about the type of socket the caller supports. The `<netdb.h>` header file defines the `addrinfo` structure. This is an optional parameter.

- res
  Points to a linked list of one or more `addrinfo` structures.

Description

The `getaddrinfo()` routine takes a service location (nodename) or a service name (servname), or both, and returns a pointer to a linked list of one or more structures of type `addrinfo` . Its members specify data obtained from either the local hosts database TCPIP$ETC:IPNODES.DAT file, local TCPIP$HOSTS.DAT file, or one of the files distributed by DNS/BIND.

The `<netdb.h>` header file defines the `addrinfo` structure.

If you specify the hints parameter, all `addrinfo` structure members other than the following members must be zero or a NULL pointer:

- `ai_flags`
  Controls the processing behavior of `getaddrinfo` . See Table 6-1 for a complete description of the flags.
- `ai_family`
  Specifies to return addresses for use with a specific protocol family.
  - If you specify a value of AF_UNSPEC, the routine returns addresses for any protocol family that can be used with nodename or servname.
  - If the value is not AF_UNSPEC and `ai_protocol` is not zero, the routine returns addresses for use only with the specified protocol family and protocol.
  - If the application handles only IPv4, set this member of the hints structure to PF_INET.
  - If `ai_family` is set to PF_INET6, the function looks only in the TCPIP$ETC:IPNODES.DAT file and the lookup fails in the BIND database.
- `ai_socktype`
  Specifies a socket type for the given service. If you specify a value of 0, you will accept any socket type. This resolves the service name for all socket types and returns all successful results.
- `ai_protocol`
  Specifies a network protocol. If you specify a value of 0, you will accept any protocol. If the application handles only TCP, set this member to IPPROTO_TCP.

If the hints parameter is a NULL pointer, this is identical to passing an `addrinfo` structure that has been initialized to zero, and the the `ai_family` member set to AF_UNSPEC.

Table 6-1 describes the `ai_flags` member values.

Table 6-1 ai_flags Member Values
Flag Value | Description |
--- | --- | ---
AI_V4MAPPED | If `af` value is AF_NET: | If `af` value is AF_INET6:
| Ignored. | Searches for AAAA records. The lookup sequence is LOCAL host database, TCPIP$ETC:IPNODES.DAT, BIND database. If AAAA records found, returns IPv6 records. If no AAAA records found, searches for A records. If A records found, returns IPv4-mapped IPv6 addresses. If no A records found, returns a NULL pointer.
AI_ALL | AI_V4MAPPED | If `af` value is AF_NET: | If `af` value is AF_INET6:
| Ignored. | Searches for AAAA records. The lookup sequence is LOCAL host database, TCPIP$ETC:IPNODES.DAT, BIND database. If AAAA records found, returns IPv6 records. If no AAAA records found, searches for A records. If A records found, returns IPv4-mapped IPv6 addresses. If no A records found, returns a NULL pointer.
AI_CANONNAME | If the nodename parameter is not NULL, the function searches for the specified node's canonical name. Upon successful completion, the `ai_canonname` member of the first `addrinfo` structure in the linked list points to a null-terminated string containing the canonical name of the specified node name. If the canonical name is not available, the `ai_canonname` member refers to the nodename parameter or to a string with the same contents. The `ai_flags` field contents are undefined.
AI_NUMERICHOST | A non-NULL node name string must be a numeric host address string. Resolution of the service name is not performed.
AI_NUMERICSERV | A non-NULL service name string must be a numeric port string. Resolution of the service name is not performed.
AI_PASSIVE | Returns a socket address structure that your application can use in a call to `bind()` . If the nodename parameter is a NULL pointer, the IP address portion of the socket address structure is set to INADDR_ANY (for an IPv4 address) or IN6ADDR_ANY_INIT (for an IPv6 address). If not set, returns a socket address structure that your application can use to call `connect()` (for a connection-oriented protocol) or either `connect()` , `sendto()` , or `sendmsg()` (for a connectionless protocol). If the nodename parameter is a NULL pointer, the IP address portion of the socket address structure is set to the loopback address.

You can use the flags in any combination to achieve finer control of the translation process. The AI_ADDRCONFIG flag is typically used in combination with other flags to modify the search based on the source address or addresses configured on the system. The following table describes how the AI_ADDRCONFIG flags works by itself.

Flag Value | If `af` Value is AF_NET | If `af` Value is AF_INET6
--- | --- | ---
AI_ADDRCONFIG | If an IPv4 source address is configured, searches for A records. | If an IPv6 source address is configured, searches for AAAA records.

Most applications will want to use the combination of the AI_ADDRCONFIG and AI_V4MAPPED flags to control their search. To simplify this for the programmer, the AI_DEFAULT symbol, which is a logical OR of AI_ADDRCONFIG and AI_V4MAPPED, is defined. The following table describes how AI_DEFAULT directs the search.

Flag Value | If `af` Value is AF_NET | If `af` Value is AF_INET6
--- | --- | ---
AI_DEFAULT | Searches for A records only if an IPv4 source address is configured on the system. If found, returns IPv4 addresses. If not, returns a NULL pointer. | Searches for AAAA records only if an IPv6 source address is configured on the system. If found, returns IPv6 addresses. If not and if an IPv4 address is configured on the system, searches for A records. If found, returns IPv4-mapped IPv6 addresses. If not, returns a NULL pointer.

These flags are defined in `<netdb.h>` .

addrinfo Structure Processing

Upon successful return, `getaddrinfo` returns a pointer to a linked list of one or more `addrinfo` structures. The application can process each `addrinfo` structure in the list by following the `ai_next` pointer until a NULL pointer is encountered. In each returned `addrinfo` structure, the `ai_family` , `ai_socktype` , and `ai_protocol` members are the corresponding arguments for a call to the `socket()` function. The `ai_addr` member points to a filled-in socket address structure whose length is specified by the `ai_addrlen` member.

Return values

Upon successful completion, the `getaddrinfo()` function returns a 0 (zero); upon failure, it returns a nonzero value.

## 6.5.2 Address to Node Name Translation Functions

The following functions are available for address to node name translation:

Option | Function
--- | ---
`gethostbyaddr` | Existing function that returns a node name for an IPv4 address.
`getnameinfo` | New protocol-independent function for mapping addresses to names.
`freeaddrinfo` | New function that returns addrinfo structures and dynamic storage to the system.

The following sections describe these changes.

### 6.5.2.1 getnameinfo Function

The `getnameinfo` function has the following syntax:

    int getnameinfo(
            const struct sockaddr *sa,
            socklen_t salen,
            char *host,
            size_t hostlen,
            char **serv,
            size_t servlen,
            int flags );

Parameters

- sa
  Points either to a `sockaddr_in` structure (for IPv4) or to a `sockaddr_in6` structure (for IPv6) that holds the IP address and port number.
- salen
  Specifies the length of either the `sockaddr_in` structure or the `sockaddr_in6` structure.
- node
  Points to a buffer in which to receive the null-terminated network node name or alias corresponding to the address contained in the sa. A NULL pointer instructs the routine not to return a node name. The node parameter and serv parameter cannot both be zero.

- nodelen
  Specifies the length of the node buffer. A value of zero instructs the routine not to return a node name.
- serv
  Points to a buffer in which to receive the null-terminated network service name associated with the port number contained in sa. A NULL pointer instructs the routine not to return a service name. The node parameter and serv parameter cannot both be zero.
- servlen
  Specifies the length of the serv buffer. A value of zero instructs the routine not to return a service name.
- flags
  Specifies changes to the routine's default actions. By default, the routine searches for the fully qualified domain name of the node in the host's database and returns it. See Table 6-2 for a list of flag bits and their meanings.

Description

The `getnameinfo()` routine looks up an IP address and port number in a `sockaddr` structure specified by sa and returns node name and service name text strings in the buffers pointed to by the node and serv parameters, respectively.

If the node name is not found, the routine returns the numeric form of the node address, regardless of the value of the flags parameter. If the service's name is not found, the routine returns the numeric form of the service's address (port number) regardless of the value of the flags parameter.

The application must provide buffers large enough to hold the fully qualified domain name and the service name, including the terminating null characters.

Flag bits

Table 6-2 describes the flag bits and, if set, their meanings.

Table 6-2 Flag Bits
Flag Value | Description
--- | ---
NI_DGRAM | Specifies that the service is a datagram service (SOCK_DGRAM). The default assumes a stream service (SOCK_STREAM). This is required for the few ports (512-514) that have different services for UDP and TCP.
NI_NAMEREQD | Returns an error if the host name cannot be located in the host's database.
NI_NOFQDN | Searches the host's database and returns the node name portion of the fully qualified domain name for local hosts.
NI_NUMERICHOST | Returns the numeric form of the host's address instead of its name. Resolution of the host name is not performed.
NI_NUMERICSERV | Returns the numeric form (port number) of the service address instead of its name. Resolution of the host name is not performed.

The two NI_NUMERIC* flags are required to support the `-n` flag that many commands provide. All flags are defined in `<netdb.h>` header file.

Return Values

Upon successful completion, the `getnameinfo()` function returns 0 (zero); upon failure, it returns a nonzero value.

### 6.5.2.2 freeaddrinfo Function

This new function frees system resources used by an address information structure.

The `freeaddrinfo()` routine frees one or more `addrinfo` structures and any dynamic storage associated with the structures. The process continues until the routine encounters a NULL `ai_next` pointer.

The `freeaddrinfo` function has the following syntax:

    #include <netdb.h>

    void freeaddrinfo(
              struct addrinfo *ai);

The ai parameter is a pointer to the `addrinfo` structure to be freed.

The `<netdb.h>` header file defines the `addrinfo` structure.

## 6.5.3 Address Conversion Functions

The following address conversion functions are new. They convert both IPv4 and IPv6 addresses.

Option | Function
--- | ---
`inet_pton` | Converts an address in its standard text presentation form to its numeric binary form, in network byte order.
`inet_ntop` | Converts a numeric address to a text string suitable for presentation.

### 6.5.3.1 inet_pton Function

This function has the following syntax:

    int inet_pton(
                  int af,
                  const char *src,
                  void *dst);

Parameters

- af
  Specifies the address family. Valid values are AF_INET for an IPv4 address and AF_INET6 for an IPv6 address.
- src
  Points to the address text string to be converted.
- dst
  Points to a buffer that is to contain the numeric address.

Description

The `inet_pton()` function converts a text string to a numeric value in Internet network byte order.

- If the af parameter is AF_INET, the function accepts a string in the standard IPv4 dotted-decimal format:

             ddd.ddd.ddd.ddd

  In this format, ddd is a one- to three-digit decimal number between 0 and 255.
- If the af parameter is AF_INET6, the function accepts a string in the following format:

             x:x:x:x:x:x:x:x

  In this format, x is the hexadecimal value of a 16-bit piece of the address.
  IPv6 addresses can contain long strings of zero (0) bits. To make it easier to write these addresses, you can use double-colon characters (::) one time in an address to represent 1 or more 16-bit groups of zeros.
- For mixed IPv4 and IPv6 environments, the following format is also accepted:

             x:x:x:x:x:x:ddd.ddd.ddd.ddd

  In this format, x is the hexadecimal value of a 16-bit piece of the address, and ddd is a one- to three-digit decimal value between 0 and 255 that represents the IPv4 address. See RFC 2373 for more information about IPv6 addressing formats.

The calling application is responsible for ensuring that the buffer referred to by the dst parameter is large enough to hold the numeric address. AF_INET addresses require 4 bytes and AF_INET6 addresses require 16 bytes.

Return values

Upon successful completion, the `inet_pton()` function returns a 1. If the input string is neither a valid IPv4 dotted-decimal string nor a valid IPv6 address string, the function returns a 0. If any other error occurs, the function returns a -1.

Errors

If the `inet_pton()` routine call fails, `errno` is set to the following value:

EAFNOSUPPORT | The address family specified in the af parameter is unknown.

Previous | Next | Contents