HP OpenVMS Systems Documentation |
HP TCP/IP Services for OpenVMS
|
Previous | Contents | Index |
Applications that use the inet_addr() function must be changed to use the getaddrinfo() function, as follows:
AF_INET Call | AF_INET6 Call |
---|---|
result=inet_addr( &string) |
err=getaddrinfo(
nodename,
servname,
&hints,
&res);
. . . freeaddrinfo( &ai); |
Make the following change to your application, as needed:
In addition to the name changes, you should review your code for
specific uses of IP address information and variables.
8.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 8.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 |
---|---|
(addr1->s_addr == addr2->s_addr) | (memcmp(addr1, addr2, sizeof(struct in6_addr)) == 0) |
AF_INET Code | AF_INET6 Code |
---|---|
(addr1->s_addr == addr2->s_addr) | IN6_ARE_ADDR_EQUAL(addr1, addr2) |
If your application compares an IP address to the wildcard address, the in6_addr structure changes (see Section 8.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) |
AF_INET Code | AF_INET6 Code |
---|---|
(addr->s_addr == INADDR_ANY) | (memcmp(addr, in6addr_any, sizeof(struct in6_addr)) == 0) |
If your application uses int data types to hold IP addresses, the in6_addr structure changes (see Section 8.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; |
If your application uses functions that return IP addresses as int data types, the in6_addr structure changes (see Section 8.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); |
If your application uses IPv4 IP-level socket options, change them to
the corresponding IPv6 options.
8.6 Sample Client/Server Programs
This section contains sample client and server programs that demonstrate the differences between IPv4 and IPv6 coding conventions:
To build the examples, use the following commands:
$ CC/DEFINE=(_SOCKADDR_LEN)/INCLUDE=TCPIP$EXAMPLES: client.c $ LINK client, TCPIP$LIBRARY:TCPIP$LIB/LIBRARY $ CC/DEFINE=(_SOCKADDR_LEN)/INCLUDE=TCPIP$EXAMPLES: server.c $ LINK server, TCPIP$LIBRARY:TCPIP$LIB/LIBRARY |
This section contains a client and a server program that use AF_INET
sockets.
8.6.1.1 Client Program
The following is a sample client program that you can build, compile and run on your system. The program sends a request to and receives a response from the system specified on the command line.
#include <in.h> /* define internet related constants, */ /* functions, and structures */ #include <inet.h> /* define network address info */ #include <netdb.h> /* define network database library info */ #include <socket.h> /* define BSD 4.x socket api */ #include <stdio.h> /* define standard i/o functions */ #include <stdlib.h> /* define standard library functions */ #include <string.h> /* define string handling functions */ #include <unixio.h> /* define unix i/o */ #define BUFSZ 1024 /* user input buffer size */ #define SERV_PORTNUM 12345 /* server port number */ int main( void ); /* client main */ void get_serv_addr( void * );(1) /* get server host address */ int main( void ) { int sockfd; /* connection socket descriptor */ char buf[512]; /* client data buffer */ struct sockaddr_in serv_addr;(2) /* server socket address structure */ memset( &serv_addr, 0, sizeof(serv_addr) );(3) serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons( SERV_PORTNUM ); get_serv_addr( &serv_addr.sin_addr );(4) if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )(5) { perror( "Failed to create socket" ); exit( EXIT_FAILURE ); } printf( "Initiated connection to host: %s, port: %d\n", inet_ntoa(serv_addr.sin_addr), ntohs(serv_addr.sin_port)(6) ); if ( connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 )(7) { perror( "Failed to connect to server" ); exit( EXIT_FAILURE ); } if ( recv(sockfd, buf, sizeof(buf), 0) < 0 ) { perror( "Failed to read data from server connection" ); exit( EXIT_FAILURE ); } printf( "Data received: %s\n", buf ); /* output client's data buffer */ if ( shutdown(sockfd, 2) < 0 ) { perror( "Failed to shutdown server connection" ); exit( EXIT_FAILURE ); } if ( close(sockfd) < 0 ) { perror( "Failed to close socket" ); exit( EXIT_FAILURE ); } exit( EXIT_SUCCESS ); } void get_serv_addr( void *addrptr )(8) { char buf[BUFSZ]; /* input data buffer */ struct in_addr val; /* remote host address structure */ struct hostent *host; /* remote host hostent structure */ while ( TRUE ) { printf( "Enter remote host: " ); if ( fgets(buf, sizeof(buf), stdin) == NULL ) { printf( "Failed to read User input\n" ); exit( EXIT_FAILURE ); } buf[strlen(buf)-1] = 0; val.s_addr = inet_addr( buf ); if ( val.s_addr != INADDR_NONE ) { memcpy( addrptr, &val, sizeof(struct in_addr) ); break; } if ( (host = gethostbyname(buf)) )(9) { memcpy( addrptr, host->h_addr, sizeof(struct in_addr) ); break; } } } |
The following is a sample server program that you can build, compile, and run on your system. The program receives requests from and sends responses to client programs on other systems.
#include <in.h> /* define internet related constants, */ /* functions, and structures */ #include <inet.h> /* define network address info */ #include <netdb.h> /* define network database library info */ #include <socket.h> /* define BSD 4.x socket api */ #include <stdio.h> /* define standard i/o functions */ #include <stdlib.h> /* define standard library functions */ #include <string.h> /* define string handling functions */ #include <unixio.h> /* define unix i/o */ #define SERV_BACKLOG 1 /* server backlog */ #define SERV_PORTNUM 12345 /* server port number */ int main( void ); /* server main */ int main( void ) { int optval = 1; /* SO_REUSEADDR'S option value (on) */ int conn_sockfd; /* connection socket descriptor */ int listen_sockfd; /* listen socket descriptor */ unsigned int client_addrlen; /* returned length of client socket */ /* address structure */ struct sockaddr_in client_addr;(1) /* client socket address structure */ struct sockaddr_in serv_addr; /* server socket address structure */ struct hostent *host;(2) /* host name structure */ char buf[] = "Hello, world!"; /* server data buffer */ memset( &client_addr, 0, sizeof(client_addr) ); memset( &serv_addr, 0, sizeof(serv_addr) );(3) serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons( SERV_PORTNUM ); serv_addr.sin_addr.s_addr = INADDR_ANY; if ( (listen_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )(4) { perror( "Failed to create socket" ); exit( EXIT_FAILURE ); } if ( setsockopt(listen_sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0 ) { perror( "Failed to set socket option" ); exit( EXIT_FAILURE ); } if ( bind(listen_sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) { perror( "Failed to bind socket" ); exit( EXIT_FAILURE ); } if ( listen(listen_sockfd, SERV_BACKLOG) < 0 ) { perror( "Failed to set socket passive" ); exit( EXIT_FAILURE ); } printf( "Waiting for a client connection on port: %d\n", ntohs(serv_addr.sin_port) ); client_addrlen = sizeof(client_addr); conn_sockfd = accept( listen_sockfd, (struct sockaddr *) &client_addr, &client_addrlen ); if ( conn_sockfd < 0 ) { perror( "Failed to accept client connection" ); exit( EXIT_FAILURE ); } host = gethostbyaddr( (char *)&client_addr.sin_addr.s_addr, sizeof(client_addr.sin_addr.s_addr), AF_INET(5) ); if ( host == NULL ) { perror( "Failed to translate client address\n" ); exit( EXIT_FAILURE ); } printf( "Accepted connection from host: %s (%s), port: %d\n", host->h_name, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port) ); if ( send(conn_sockfd, buf, sizeof(buf), 0) < 0 ) { perror( "Failed to write data to client connection" ); exit( EXIT_FAILURE ); } printf( "Data sent: %s\n", buf ); /* output server's data buffer */ if ( shutdown(conn_sockfd, 2) < 0 ) { perror( "Failed to shutdown client connection" ); exit( EXIT_FAILURE ); } if ( close(conn_sockfd) < 0 ) { perror( "Failed to close socket" ); exit( EXIT_FAILURE ); } if ( close(listen_sockfd) < 0 ) { perror( "Failed to close socket" ); exit( EXIT_FAILURE ); } exit( EXIT_SUCCESS ); } |
This section contains a client and a server program that use AF_INET6
sockets.
8.6.2.1 Client Program
The following is a sample client program that you can build, compile and run on your system. The program sends a request to and receives a response from the system specified on the command line.
#include <in.h> /* define internet related constants, */ /* functions, and structures */ #include <inet.h> /* define network address info */ #include <netdb.h> /* define network database library info */ #include <socket.h> /* define BSD 4.x socket api */ #include <stdio.h> /* define standard i/o functions */ #include <stdlib.h> /* define standard library functions */ #include <string.h> /* define string handling functions */ #include <unixio.h> /* define unix i/o */ #define BUFSZ 1024 /* user input buffer size */ #define SERV_PORTNUM "12345" /* server port number string */ int main( void ); /* client main */ void get_serv_addr( struct addrinfo *hints, struct addrinfo **res );(1) /* get server host address */ int main( void ) { int sockfd; /* connection socket descriptor */ char buf[512]; /* client data buffer */ struct addrinfo hints; /* input values to direct operation */ struct addrinfo *res;(2) /* linked list of addrinfo structs */ memset( &hints, 0, sizeof(hints) );(3) hints.ai_family = AF_INET6; hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED | AI_CANONNAME; hints.ai_protocol = IPPROTO_TCP; hints.ai_socktype = SOCK_STREAM; get_serv_addr( &hints, &res );(4) if ( (sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0 )(5) { perror( "Failed to create socket" ); exit( EXIT_FAILURE ); } printf( "Initiated connection to host: %s, port: %d\n", res->ai_canonname, htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_port)(6) ); if ( connect(sockfd, res->ai_addr, res->ai_addrlen) < 0 )(7) { perror( "Failed to connect to server" ); exit( EXIT_FAILURE ); } if ( recv(sockfd, buf, sizeof(buf), 0) < 0 ) { perror( "Failed to read data from server connection" ); exit( EXIT_FAILURE ); } printf( "Data received: %s\n", buf ); /* output client's data buffer */ if ( shutdown(sockfd, 2) < 0 ) { perror( "Failed to shutdown server connection" ); exit( EXIT_FAILURE ); } if ( close(sockfd) < 0 ) { perror( "Failed to close socket" ); exit( EXIT_FAILURE ); } exit( EXIT_SUCCESS ); } void get_serv_addr( struct addrinfo *hints, struct addrinfo **res )(8) { int gai_error; /* return value of getaddrinfo() */ char buf[BUFSZ]; /* input data buffer */ const char *port = SERV_PORTNUM; /* server port number */ while ( TRUE ) { printf( "Enter remote host: " ); if ( fgets(buf, sizeof(buf), stdin) == NULL ) { printf( "Failed to read User input\n" ); exit( EXIT_FAILURE ); } buf[strlen(buf)-1] = 0; gai_error = getaddrinfo( buf, port, hints, res );(9) if ( gai_error ) printf( "Failed to resolve name or address: %s\n", gai_strerror(gai_error)(10) ); else break; } } |
The following is a sample server program that you can build, compile, and run on your system. The program receives requests from and sends responses to client programs on other systems.
#include <in.h> /* define internet related constants, /* functions, and structures */ #include <inet.h> /* define network address info */ #include <netdb.h> /* define network database library info */ #include <socket.h> /* define BSD 4.x socket api */ #include <stdio.h> /* define standard i/o functions */ #include <stdlib.h> /* define standard library functions */ #include <string.h> /* define string handling functions */ #include <unixio.h> /* define unix i/o */ #define SERV_BACKLOG 1 /* server backlog */ #define SERV_PORTNUM 12345 /* server port number */ int main( void ); /* server main */ int main( void ) { int optval = 1; /* SO_REUSEADDR'S option value (on) */ int conn_sockfd; /* connection socket descriptor */ int listen_sockfd; /* listen socket descriptor */ int gni_error;(1) /* return status for getnameinfo() */ unsigned int client_addrlen; /* returned length of client socket */ /* address structure */ struct sockaddr_in6 client_addr; /* client socket address structure */ struct sockaddr_in6 serv_addr;(2) /* server socket address structure */ char buf[] = "Hello, world!"; /* server data buffer */ char node[NI_MAXHOST];(3) /* buffer to receive node name */ char port[NI_MAXHOST]; /* buffer to receive port number */ char addrbuf[INET6_ADDRSTRLEN]; /* buffer to receive host's address */ memset( &client_addr, 0, sizeof(client_addr) ); memset( &serv_addr, 0, sizeof(serv_addr) );(4) serv_addr.sin6_family = AF_INET6; serv_addr.sin6_port = htons( SERV_PORTNUM ); serv_addr.sin6_addr = in6addr_any; if ( (listen_sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0 )(5) { perror( "Failed to create socket" ); exit( EXIT_FAILURE ); } if ( setsockopt(listen_sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0 ) { perror( "Failed to set socket option" ); exit( EXIT_FAILURE ); } if ( bind(listen_sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) { perror( "Failed to bind socket" ); exit( EXIT_FAILURE ); } if ( listen(listen_sockfd, SERV_BACKLOG) < 0 ) { perror( "Failed to set socket passive" ); exit( EXIT_FAILURE ); } printf( "Waiting for a client connection on port: %d\n", ntohs(serv_addr.sin6_port) ); client_addrlen = sizeof(client_addr); conn_sockfd = accept( listen_sockfd, (struct sockaddr *) &client_addr, &client_addrlen ); if ( conn_sockfd < 0 ) { perror( "Failed to accept client connection" ); exit( EXIT_FAILURE ); } gni_error = getnameinfo( (struct sockaddr *)&client_addr, client_addrlen, (6) node, sizeof(node), NULL, 0, NI_NAMEREQD ); if ( gni_error ) { printf( "Failed to translate client address: %s\n", gai_strerror(gni_error) (7) ); exit( EXIT_FAILURE ); } gni_error = getnameinfo( (struct sockaddr *)&client_addr, client_addrlen, addrbuf, sizeof(addrbuf), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV (8) ); if ( gni_error ) { printf( "Failed to translate client address and/or port: %s\n", gai_strerror(gni_error) ); exit( EXIT_FAILURE ); } printf( "Accepted connection from host: %s (%s), port: %s\n", node, addrbuf, port ); if ( send(conn_sockfd, buf, sizeof(buf), 0) < 0 ) { perror( "Failed to write data to client connection" ); exit( EXIT_FAILURE ); } printf( "Data sent: %s\n", buf ); /* output server's data buffer */ if ( shutdown(conn_sockfd, 2) < 0 ) { perror( "Failed to shutdown client connection" ); exit( EXIT_FAILURE ); } if ( close(conn_sockfd) < 0 ) { perror( "Failed to close socket" ); exit( EXIT_FAILURE ); } if ( close(listen_sockfd) < 0 ) { perror( "Failed to close socket" ); exit( EXIT_FAILURE ); } exit( EXIT_SUCCESS ); } |
Previous | Next | Contents | Index |