HP OpenVMS Systems Documentation

Content starts here

HP TCP/IP Services for OpenVMS
Sockets API and System Services Programming


Previous Contents Index


Appendix E
Porting Applications to IPv6

This appendix describes the changes you must make in your application code to operate in an IPv6 networking environment, including:

  • Name changes
  • Structure changes
  • Other changes

E.1 Using AF_INET6 Sockets

Figure E-1 shows a sample sequence of events for an application that uses an AF_INET socket to send IPv4 packets.

Figure E-1 Using AF_INET Socket for IPv4 Communications


  1. Application calls gethostbyname() and passes the host name, host1 .
  2. The search finds host1 in the hosts database and gethostbyname() returns the IPv4 address 1.2.3.4 .
  3. The application opens an AF_INET socket.
  4. The application sends information to the 1.2.3.4 address.
  5. The socket layer passes the information and address to the UDP module.
  6. The UDP module puts the 1.2.3.4 address into the packet header and passes the information to the IPv4 module for transmission.

Section E.6.1.1 contains sample program code that demonstrates these steps.

You can use the AF_INET6 socket for both IPv6 and IPv4 communications. For IPv4 communications, create an AF_INET6 socket and pass it a sockaddr_in6 structure that contains an IPv4-mapped IPv6 address (for example, ::ffff:1.2.3.4 ). Figure E-2 shows the sequence of events for an application that uses an AF_INET6 socket to send IPv4 packets.

Figure E-2 Using AF_INET6 Socket to Send IPv4 Communications


  1. Application calls getaddrinfo() and passes the host name ( host1 ), the AF_INET6 address family hint, and the (AI_V4MAPPED | AI_ADDRCONFIG) flag hint. The flag tells the function that if an IPv4 address is found for host1 , return the address as an IPv4-mapped IPv6 address.
  2. The search finds an IPv4 address, 1.2.3.4 , for host1 in the hosts database and getaddrinfo() returns the IPv4-mapped IPv6 address ::ffff:1.2.3.4 .
  3. The application opens an AF_INET6 socket.
  4. The application sends information to the ::ffff:1.2.3.4 address.
  5. The socket layer passes the information and address to the UDP module.
  6. The UDP module identifies the IPv4-mapped IPv6 address, puts the 1.2.3.4 address into the packet header, and passes the information to the IPv4 module for transmission.

AF_INET6 sockets can receive messages sent to either IPv4 or IPv6 addresses on the system. An AF_INET6 socket uses the IPv4-mapped IPv6 address format to represent IPv4 addresses. Figure E-3 shows the sequence of events for an application that uses an AF_INET6 socket to receive IPv4 packets.

Figure E-3 Using AF_INET6 Socket to Receive IPv4 Communications


  1. The application opens an AF_INET6 socket, binds to it, and listens on it.
  2. An IPv4 packet arrives and passes through the IPv4 module.
  3. The TCP layer strips off the packet header and passes the information and the IPv4-mapped IPv6 address ::ffff:1.2.3.4 to the socket layer.
  4. The application calls accept() and retrieves the information from the socket.
  5. The application calls getnameinfo() and passes the ::ffff:1.2.3.4 address and the NI_NAMEREQD flag. The flag tells the function to return the host name for the address. See Table 4-3 for a description of the flag bits and their meanings.
  6. The search finds the host name for the 1.2.3.4 address in the hosts database, and getnameinfo() returns the host name.

For IPv6 communications, create an AF_INET6 socket and pass it a sockaddr_in6 structure that contains an IPv6 address (for example, 3ffe:1200::a00:2bff:fe2d:02b2 ). Figure E-4 shows the sequence of events for an application that uses an AF_INET6 socket to send IPv6 packets.

Figure E-4 Using AF_INET6 Socket for IPv6 Communications


  1. Application calls getaddrinfo() and passes the host name ( host1 ), the AF_INET6 address family hint, and the (AI_V4MAPPED | AI_ADDRCONFIG) flag hint. The flag tells the function that if an IPv4 address is found for host1 , to return it.
  2. The search finds an IPv6 address for host1 in the hosts database, and getaddrinfo() returns the IPv6 address 3ffe:1200::a00:2bff:fe2d:02b2 .
  3. The application opens an AF_INET6 socket.
  4. The application sends information to the 3ffe:1200::a00:2bff:fe2d:02b2 address.
  5. The socket layer passes the information and address to the UDP module.
  6. The UDP module identifies the IPv6 address and puts the 3ffe:1200::a00:2bff:fe2d:02b2 address into the packet header and passes the information to the IPv6 module for transmission.

Section E.6.2.1 contains sample program code that demonstrates these steps.

The following sections describe how to convert an existing AF_INET application to an AF_INET6 application that is capable of communicating over both IPv4 and IPv6.

E.2 Name Changes

Most of the changes required are straightforward and mechanical, though some may require a bit of code restructuring. For example, a routine that returns an int data type holding an IPv4 address may need to be modified to take as an extra parameter a pointer to an in6_addr into which it writes the IPv6 address.

Table E-1 summarizes the changes you must make to your application's code.

Table E-1 Name Changes
Search file for Replace with Comments
AF_INET AF_INET6 Replace with IPv6 address family macro.
PF_INET PF_INET6 Replace with IPv6 protocol family macro.
INADDR_ANY in6addr_any Replace with IPv6 global variable.

E.3 Structure Changes

The structure names and field names have changed for the following structures:

  • in_addr
  • sockaddr_in
  • sockaddr
  • hostent

The following sections discuss these changes.

E.3.1 in_addr Structure

Applications that use the IPv4 in_addr structure must be changed to use the IPv6 in6_addr structure, as follows:

IPv4 Structure IPv6 Structure
struct in_addr
unsigned int s_addr
struct in6_addr
uint8_t s6_addr

Make the following changes to your application, as needed:

  1. Change the structure name in_addr to in6_addr .
  2. Change the data type from unsigned int to uint8_t and the field name s_addr to s6_addr .

E.3.2 sockaddr Structure

Applications that use the generic socket address structure ( sockaddr ) to hold an AF_INET socket address ( sockaddr_in ) must be changed to use the AF_INET6 sockaddr_in6 structure, as follows:

AF_INET Structure AF_INET6 Structure
struct sockaddr struct sockaddr_in6

Make the following change to your application, as needed:

  • Change structure name sockaddr to sockaddr_in6 .

    Note

    A sockaddr_in6 structure is larger than a sockaddr structure. For more information, see Section 3.2.14.

E.3.3 sockaddr_in Structure

Applications that use the BSD Version 4.4 IPv4 sockaddr_in structure must be changed to use the IPv6 sockaddr_in6 structure, as follows:

IPv4 Structure IPv6 Structure
struct sockaddr_in
unsigned char sin_len
sa_family_t sin_family
in_port_t sin_port
struct addr sin_addr
struct sockaddr_in6
uint8_t sin6_len
sa_family_t sin6_family
int_port_t sin6_port
struct in6_addr sin6_addr

Make the following changes to your application, as needed:

  1. Change structure name sockaddr_in to sockaddr_in6 . Initialize the entire sockaddr_in6 structure to zero after your structure declarations.
  2. Change the data type unsigned char to uint8_t and the field name sin_len to sin6_len .
  3. Change the field name sin_family to sin6_family .
  4. Change the field name sin_port to sin6_port .
  5. Change the field name sin_addr to sin6_addr .

E.3.4 hostent Structure

Applications that use the hostent structure must be changed to use the addrinfo structure, as follows:

AF_INET Structure AF_INET6 Structure
struct hostent struct addrinfo

Make the following change to your application, as needed:

  • Change the structure name hostent to addrinfo .

See also Section E.4.2 for related changes.

E.4 Function Changes

The names and parameters have changed for the following functions:

  • gethostbyaddr()
  • gethostbyname()
  • inet_aton()
  • inet_ntoa()
  • inet_addr()

The following sections discuss these changes.

E.4.1 gethostbyaddr() Function

Applications that use the IPv4 gethostbyaddr() function must be changed to use the IPv6 getnameinfo() function, as follows:

AF_INET Call AF_INET6 Call
gethostbyaddr( xxx,4,AF_INET) err=getnameinfo( &sa, salen, node, nodelen, service, servicelen, flags);

Make the following change to your application, as needed:

  • Change the function name from gethostbyaddr() to getnameinfo() and provide a pointer to the socket address structure, a character string for the returned node name, an integer for the length of the returned node name, a character string to receive the returned service name, an integer for the length of the returned service name, and an integer that specifies the type of address processing to be performed.

E.4.2 gethostbyname() Function

Applications that use the gethostbyname() function must be changed to use the getaddrinfo() function, as follows:

AF_INET Call AF_INET6 Call
gethostbyname( name) err=getaddrinfo( nodename, servname, &hints, &res); .
.
.

freeaddrinfo( &ai);

Make the following changes to your application, as needed:

  1. Change the function name from gethostbyname() to getaddrinfo() and provide a character string that contains the node name, a character string that contains the service name to use, a pointer to a hints structure that contains processing options, and a pointer to an addrinfo structure or structures for the returned address information.
  2. Add a call to the freeaddrinfo() function to free the addrinfo structure or structures when your application is finished using them.

E.4.3 inet_aton() Function

Applications that use the inet_aton() function must be changed to use the inet_pton() function, as follows:

AF_INET Call AF_INET6 Call
inet_aton( &string, &addr) inet_pton (AF_INET6,&src,&dst);

Make the following change to your application, as needed:

  • Change the function name from inet_aton() to inet_pton() and provide an integer for the address family, a pointer to an address string to be converted, and a pointer to a buffer that is to contain the numeric address.

E.4.4 inet_ntoa() Function

Applications that use the inet_ntoa() function must be changed to use the inet_ntop() function, as follows:

AF_INET Call AF_INET6 Call
inet_ntoa( addr) inet_ntop(AF_INET6,&src,&dst,size);

Make the following change to your application, as needed:

  • Change the function name from inet_ntoa() to inet_ntop() and provide an integer for the address family, a pointer to a buffer that contains the numeric internet address, a pointer to a buffer that is to contain the text string, and an integer for the size of the buffer pointed to by the dst parameter.

E.4.5 inet_addr() Function

Applications that use the inet_addr() function must be changed to use the inet_pton() function, as follows:

AF_INET Call AF_INET6 Call
result=inet_addr( &string) inet_pton (AF_INET6,&src,&dst);

Make the following change to your application, as needed:

  • Change the function name from inet_addr() to inet_pton() and provide an integer for the address family, a pointer to an address string to be converted, and a pointer to a buffer that is to contain the numeric address.

E.5 Other Application Changes

In addition to the name changes, you should review your code for specific uses of IP address information and variables.

E.5.1 Comparing IP Addresses

If your application compares IP addresses or tests IP addresses for equality, the in6_addr structure changes (see in Section E.3.1) will change the comparison of int quantities to a comparison of structures. This will break the code and cause compiler errors.

Make one of the following changes to your application, as needed:

AF_INET Code AF_INET6 Code
(addr1->s_addr == addr2->s_addr) (memcmp(addr1, addr2, sizeof(struct in6_addr)) == 0)
  • Change the equality expression to one that uses the memcmp (memory comparison) function.
AF_INET Code AF_INET6 Code
(addr1->s_addr == addr2->s_addr) IN6_ARE_ADDR_EQUAL(addr1, addr2)
  • Change the equality expression to one that uses the IN6_ARE_ADDR_EQUAL macro.

E.5.2 Comparing an IP Address to the Wildcard Address

If your application compares an IP address to the wildcard address, the in6_addr structure changes (see Section E.3.1) will change the comparison of int quantities to a comparison of structures. This will break the code and cause compiler errors.

Make either of the following changes to your application, as needed:

AF_INET Code AF_INET6 Code
(addr->s_addr == INADDR_ANY) IN6_IS_ADDR_UNSPECIFIED(addr)
  • Change the equality expression to one that uses the IN6_IS_ADDR_UNSPECIFIED macro.
AF_INET Code AF_INET6 Code
(addr->s_addr == INADDR_ANY) (memcmp(addr, in6addr_any, sizeof(struct in6_addr)) == 0)
  • Change the equality expression to one that uses the memcmp (memory comparison) function.

E.5.3 Using int Data Types to Hold IP Addresses

If your application uses int data types to hold IP addresses, the in6_addr structure changes (see Section E.3.1) will change the assignment. This will break the code and cause compiler errors.

Make the following changes to your application, as needed:

AF_INET Code AF_INET6 Code
struct in_addr foo;
int bar;
.
.
.
bar = foo.s_addr;
struct in6_addr foo;
struct in6_addr bar;
.
.
.
bar = foo;
  1. Change the data type for bar from int to a struct in6_addr .
  2. Change the assignment statement for bar to remove the s_addr field reference.

E.5.4 Using Functions that Return IP Addresses

If your application uses functions that return IP addresses as int data types, the in6_addr structure changes (see Section E.3.1) will change the destination of the return value from an int to an array of char . This will break the code and cause compiler errors.

Make the following changes to your application, as needed:

AF_INET Code AF_INET6 Code
struct in_addr *addr;
addr->s_addr = foo( xxx);
struct in6_addr * addr;
foo( xxx, addr);
  • Restructure the function to enable you to pass the address of the structure in the call. In addition, modify the function to write the return value into the structure pointed to by addr .


Previous Next Contents Index