z/OS Communications Server: IP Sockets Application Programming Interface Guide and Reference
Previous topic | Next topic | Contents | Contact z/OS | Library | PDF


GETADDRINFO

z/OS Communications Server: IP Sockets Application Programming Interface Guide and Reference
SC27-3660-00

Use the GETADDRINFO command to resolve host or service name information.

This command translates the name of a service location (host name) or a service name. The command returns a set of NAME strings and associated information; this information can be used to create a socket with which to address the specified service or to send a datagram to the specified service. For information about the format of the NAME string, see How structures are represented.

Guideline: Use the application to cycle through each NAME string until a successful connection is established. An example is provided in Code example.
Tip: You can use a resolver trace to determine why a resolver command failed. See z/OS Communications Server: IP Diagnosis Guide.

Format

Read syntax diagramSkip visual syntax diagram
>>-SOCKET--(--"GETADDRINFO"--,--node_service-------------------->

>--,--+-------+--,--+--------+---------------------------------->
      '-flags-'     '-family-'   

>--,--+----------+--,--+----------+--,--+--------+--)----------><
      '-socktype-'     '-protocol-'     '-eflags-'      

Parameters

node_service
This variable takes one of the following formats:
Read syntax diagramSkip visual syntax diagram
>>-node--,--+---------+----------------------------------------><
            '-service-'   

Read syntax diagramSkip visual syntax diagram
>>-+------+--,--service----------------------------------------><
   '-node-'               

where:
node
The host name or IP address. If the value of the node parameter is an IP address, you also must issue the AI_NUMERICHOST flag. The value of the node parameter can be up to 255 bytes in length.
Scope information can be appended to the host name, using the following format:
"node%scope information"
For example, you could set the node parameter to "MYNODE%23". For more information, see z/OS® Communication Server: IPv6 Network and Application Design Guide.
service
The TCP/IP service that is queried. If the value of the service parameter is a port number, you must specify the AI_NUMERICSERV flag. The value of the service parameter can be up to 32 bytes in length
flags
To specify multiple flags, code the flags parameter as a space-delimited string. The following flags are supported:
AI_PASSIVE
Specifies how to fill the returned socket NAME string. If this flag is set, the returned NAME string can be used with the BIND command to bind a socket for accepting new connection requests.
Rules:
  • If the AI_PASSIVE flag is specified and the node parameter is not specified, the IP address portion of the NAME string is set to either the IPv4 address (INADDR_ANY) or to the IPv6 unspecified address (in6addr_any).
  • If the AI_PASSIVE flag is not specified, then the returned NAME string can be used with the CONNECT or the SENDTO commands.
  • If the AI_PASSIVE flag is not specified and the node parameter is not specified, the IP address portion of the NAME string is set to the default loopback address: 127.0.0.1 (IPv4) or ::1 (IPv6).
If you issue the following command:
src = socket("GETADDRINFO",,54123,"AI_PASSIVE","AF_UNSPEC")
Then the following string is returned:
0 '' AF_INET6 54123 0 ::0 0 AF_INET 54123 0.0.0.0

See example 2 in Code example for one method of how to use this flag.

AI_CANONNAMEOK
Specifies that the canonical name that corresponds to the node parameter is returned. The node parameter must also be issued.
If you issue the following command:
src = socket("GETADDRINFO","chile",21,"AI_CANONNAMEOK")
Then the following string is returned:
0 host.department.com AF_INET 21 10.11.103.1
Tip: See Code example for examples of how to use this flag.
AI_NUMERICHOST
If you specify this flag, the node parameter must be specified as an IP address, for example, 10.11.103.1. Otherwise, the command fails with a 1 EAI_NONAME return code.
If you issue the following command:
src = socket("GETADDRINFO","10.11.103.1",,"AI_NUMERICHOST")
Then the following string is returned:
0 '' AF_INET 0 10.11.103.1
AI_NUMERICSERV
If you specify this flag, you must specify the service parameter as a port number, for example, 1821. Otherwise, the command fails with a 1 EAI_NONAME return code.
If you issue the following command
src = socket("GETADDRINFO",,23,"AI_NUMERICSERV")
Then the following string is returned.
0 '' AF_INET6 23 0 ::1 0 AF_INET 23 127.0.0.1
AI_V4MAPPED
If you specify this flag and the family is AF_INET6 or AF_UNSPEC, the caller accepts IPv4-mapped IPv6 addresses.
Rules:
  • When the AI_ALL flag is not specified and no IPv6 addresses are found, then a query is made for IPv4 addresses. Any IPv4 addresses that are found are returned as IPv4-mapped IPv6 addresses.
  • If the value of the family parameter is not AF_INET6 or AF_UNSPEC, and if IPv6 is not supported on the system, then this flag is ignored.
If you issue the following command:
src = socket("GETADDRINFO","CHILE",,"AI_V4MAPPED AI_CANONNAMEOK");
Then the following string is returned:
0 host.department.com AF_INET6 0 0 ::FFFF:10.11.103.1 0
AI_ALL
If you specify this flag, the NAME strings that are returned depend on the value of the family parameter.
Rules:
  • If this flag is specified and the value of the family parameter is AF_INET6, then the AI_V4MAPPED flag must also be set to indicate that both IPv4-mapped IPv6 addresses and IPv6-mapped IP addresses are acceptable.
  • If value of the family parameter is AF_UNSPEC and the system supports IPv6, then two queries are made. The first query is for IPv6 addresses; if any are found, they are returned. The second query is for IPv4 addresses. If the AI_V4MAPPED flag is not specified, the IPv4 addresses are returned as IPv4 addresses. If the AI_V4MAPPED flag is specified, theIPv4 addresses are returned as IPv4-mapped IPv6 addresses.
  • If the value of the family parameter is not AF_INET6 or AF_UNSPEC, and if the system supports IPv6, then this flag is ignored.
If you issue the following command:
src = socket("GETADDRINFO","CHILE",,,
"AI_ALL AI_V4MAPPED AI_CANONNAMEOK",,
"AF_UNSPEC");
The following string is returned (all on one line):
0 CHILE.department.com AF_INET6 0 0 ::FFFF:10.11.103.1 0 
				AF_INET6 0 0 2001:10:11:103::1 0
AI_ADDRCONFIG
If you specify this flag, the node is queried if the resolver determines that one of the following conditions is true:
  • The system is IPv6 enabled and has at least one IPv6 interface. In this case, the resolver makes a query for AAAA DNS records (IPv6).
  • The system is IPv4 enabled and has at least one IPv4 interface. In this case, the resolver makes a query for A DNS records (IPv4).
The loopback address is not a valid interface for this flag.
AI_EXTFLAGS
If you specify this flag, the extended form of the getaddrinfo function is requested. The extended form allows additional hints to be passed to the resolver to determine the order of destination addresses that are returned. This flag affects only the order of IPv6 addresses that are returned, if any. If AI_EXTFLAGS flag is specified, the eflags parameter must be specified.
family
Limits the returned information to a specific address family. The following families are supported:
AF_UNSPEC
Any protocol family. The value 0 is accepted also.
AF_INET
IPv4 families. The value 2 is accepted also.
AF_INET6
IPv6 families. The value 19 is accepted also.
socktype
Limits the returned information to a specific socket type. If no socket type is specified, the command returns address information for all types. The following socket types are supported:
Type name Decimal value Description
SOCK_STREAM 1 Stream socket
SOCK_DGRAM 2 Datagram socket
SOCK_RAW 3 Raw-protocol interface
Consider the following points:
  • If the value of the socktype parameter is set to any value other than SOCK_STREAM, SOCK_DGRAM, or SOCK_RAW, the GETADDRINFO command fails with a 9 EAI_SOCKTYPE return code.
  • If the value of the socktype parameter is SOCK_RAW, the value of the service parameter must be numeric.
  • If the value of the socktype parameter is set to SOCK_STREAM or SOCK_DGRAM, then the resolver searches the services file for a service name.
If the socktype and protocol parameters are both specified as 0, then the GETADDRINFO command is processed in the following way:
  • If the value of the service parameter is null or numeric, then any returned address information has the default socktype value of SOCK_STREAM.
  • If the value of the service parameter is a service name, for example, FTP, then the GETADDRINFO command searches the appropriate services file twice. The first search uses SOCK_STREAM as the protocol, and the second search uses SOCK_DGRAM as the protocol. There is no default socket-type provision in this case.
If both the socktype and protocol parameters are specified as nonzero values, then the values must be compatible, regardless of the value specified by the service parameter. In this case, compatible means one of the following combinations of parameters:
  • The socktype parameter is SOCK_STREAM and the protocol parameter is IPPROTO_TCP.
  • The socktype parameter is SOCK_DGRAM and the protocol parameter is IPPROTO_UDP.
  • The socktype parameter is SOCK_RAW, in which case the protocol parameter can have any value.
protocol
Limits the returned information to a specific protocol. The value 0 indicates that the caller accepts any protocol. The following protocols are supported:
Protocol name Decimal value Description
IPPROTO_TCP 6 TCP
IPPROTO_UDP 16 UDP

Consider the following points:

  • If the socktype parameter is 0 and the protocol parameter is not 0, the only acceptable input values for the protocol parameter are IPPROTO_TCP and IPPROTO_UDP. If any other values are issued for the protocol parameter, the GETADDRINFO command fails with a 7 EAI_BADFLAGS return code.
  • If the protocol and socktype parameters are both specified as 0, then the GETADDRINFO command is processed in the following way:
    • If the service parameter value is null or numeric, then any returned address information assumes that the socket type is SOCK_STREAM.
    • If the service parameter is specified as a service name, for example, FTP, then the GETADDRINFO command searches the applicable services file twice. The first search uses the protocol SOCK_STREAM, and the second search uses the protocol SOCK_DGRAM. There is no default socket type provision in this case.
  • If both the protocol and socktype parameters are specified as nonzero values, the values must be compatible, regardless of the value that is specified by the service parameter. In this context, compatible means one of the following combinations of parameters:
    • The socktype parameter is SOCK_STREAM and the protocol parameter is IPPROTO_TCP.
    • The socktype parameter is SOCK_DGRAM and the protocol parameter is IPPROTO_UDP.
    • The socktype parameter is SOCK_RAW, in which case the protocol parameter can have any value.
  • If the lookup for the value specified by the service parameter fails (for example, the service name does not appear in the applicable services file), then the GETADDRINFO command fails with the 8 EAI_SERVICE return code.
eflags
A fullword binary field that specifies the source IPv6 address selection preferences. If AI_EXTFLAGS flag is specified in FLAGS, this field is required. To specify multiple eflags, code the eflags parameter as a space-delimited string.

This field must have the value of 0 or of one or more of the following values:

IPV6_PREFER_SRC_HOME
Requests that resolver returns destination IPv6 addresses that can be reached by a home IPv6 source address before it returns destinations that can be reached by a care-of IPv6 source address. This is the default behavior if AI_EXTFLAGS flag is not specified.
IPV6_PREFER_SRC_COA
Requests that resolver returns destination IPv6 addresses that can be reached by a care-of IPv6 source address before it returns destinations that can be reached by a home IPv6 source address.
IPV6_PREFER_SRC_PUBLIC
Requests that resolver returns destination IPv6 addresses that can be reached by a public IPv6 source address before it returns destinations that can be reached by a temporary IPv6 source address.
IPV6_PREFER_SRC_TMP
Requests that the resolver returns destination IPv6 addresses that can be reached by a temporary IPv6 source address before it returns destinations that can be reached by a public IPv6 source address.
IPV6_PREFER_SRC_CGA
Requests that resolver returns destination IPv6 addresses that can be reached by a cryptographically generated IPv6 source address before it returns destinations that can be reached by a non-cryptographically generated IPv6 source address.
IPV6_PREFER_SRC_NONCGA
Requests that resolver returns destination IPv6 addresses that can be reached by a non-cryptographically generated IPv6 source address before it returns destinations that can be reached by a cryptographically generated IPv6 source address.
ZERO
No preferences are specified.

Any EFLAGS specification other than the value of 0 or one of the options listed above causes an EINVALIDRXSOCKETCALL error to be returned.

If contradictory EFLAGS, for example, IPV6_PREFER_SRC_TMP and IPV6_PREFER_SRC_PUBLIC, are specified, the GETADDRINFO call returns EINVALIDCOMBINATION.

Returned value

The command returns a string that contains the return code, canonical name, and a NAME string or list of NAME strings. The return code can be 0, a REXX socket API error number, or the REXX TCP/IP error number that is set by the socket command. The return code 0 indicates that the requested socket command was completed successfully.

The following string is an example of what is returned by the GETADDRINFO command:
0 RALEIGH.IBM.COM name1 name2 name3
In the example, 0 is the return code, RALEIGH.IBM.COM is the canonical name, and name1 name2 name3 is a list of NAME strings. Depending on the flags that were issued, these names can be IPv4 or IPv6 values.
Tip: For a description of the format of a socket name, see CONNECT or BIND.

See Socket call error return codes for additional information about the numeric error codes that are returned by this command.

The following REXX TCP/IP error numbers can be returned:
  • 1 EAI_NONAME
  • 2 EAI_AGAIN
  • 5 EAI_FAIMLY
  • 6 EAI_MEMORY
  • 7 EAI_BADFLAGS
  • 8 EAI_SERVICE
  • 9 EAI_SOCKTYPE
  • 9 EBADF
  • 35 EWOULDBLOCK
The following REXX socket API error numbers can be returned:
  • 2001 EINVALIDRXSOCKETCALL
  • 2005 ESUBTASKNOTACTIVE
  • 2006 ESOCKETNOTALLOCATED

LE C/C++ equivalent

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

Code example

/* REXX EZARXR05 */
/*
 * This sample demonstrates a use of the GETADDRINFO command.
 * It is possible that the GETADDRINFO command will return
 * more then one name address. The program shows one
 * technique that can be used to parse the information
 * returned. After a successful connection has been established
 * the program will sends data to a server listeneing on port
 * 54777.  The program then waits for a reply.
 *
 * HINT: The program code provided under the IOCTL command can
 * be used as a server for this sample.
 *
 * GUIDELINE: It is generally recommended that a program loop around
 *            the RECV command to ensure that all data is read off
 *            the socket. This sample does not follow the guideline.
 */
src = socket("INITIALIZE","MYSET01",10);
if perror(src,"INITIALIZE") = 0 then do
   src = socket("SOCKET","AF_INET6","SOCK_STREAM");
   if perror(src,"SOCKET") \= 0 then signal ENDPROGRAM
   parse var src l_retcode l_sockid
   /* ****************************************************
    * Issue GETADDRINFO command.  Request that all IPv6 address
    * information be returned, and if possible provide the
    * canon name. IPV4 addresses are to be mapped to
    * IPv6 mapped addresses. Names will be returned as AF_INET6
    * NAMES.
    * ****************************************************/
   src = socket("GETADDRINFO","MVS150",54777,,
             "AI_ALL AI_CANONNAMEOK AI_NUMERICSERV",
             "AI_V4MAPPED","AF_INET6","SOCK_STREAM",,
             "IPPROTO_TCP");
   if perror(src,"GETADDRINFO") = 0 then do
      parse var src l_retcode l_canonname l_names
      l_LOCName = "AF_INET6 0 0 IN6ADDR_ANY 0";
      src = socket("BIND", l_sockid, l_LOCname);
      if perror(src,"BIND") \= 0 then signal ENDPROGRAM
      /* **************************************************
       * It is possible that GETADDRINFO returned multiple
       * name structures.  Cycle through them until a
       * successful connection is achived or none are left.
       * **************************************************/
      l_done = "FALSE";
      l_connectOK = "FALSE";
      do while l_names \= '' | l_done = "FALSE"
         if word(l_names,1) = "AF_INET6" then do
            parse var l_names .  l_port l_flow l_addr,
                                   l_scope l_names
            l_RMTname = "AF_INET6 "l_port" "l_flow" "l_addr,
                        ||" "l_scope;
         end; /* AF_INET6 */
         else do
            parse var l_names .  l_port l_addr l_names
            l_RMTname = "AF_INET "l_port" "l_addr;
         end; /* AF_INET */
         Say "Attempting connection using RMT NAME: ",
             l_RMTname;
         src = socket("CONNECT",l_sockid,l_RMTname);
         if perror(src,"CONNECT") = 0 then do
            Say "...Connected";
            l_connectOK = "TRUE";
            l_done = "TRUE";
         end; /* CONNECT */
         else do
            l_done = "TRUE";
         end;
      end; /* DO LOOP */
      if l_connectOK = "TRUE" then do
         l_data = time() "**** **** **** **** ";
         src = socket("GETSOCKNAME",l_sockid);
         Say "GETSOCKNAME: "src;
         src = socket("SEND",l_sockid,l_data);
         if perror(src,"SEND") = 0 then do
            src = socket("RECV",l_sockid);
            if perror(src,"RECV") = 0 then do
               parse var src .  l_amtdata l_data
               Say "Received " l_amtdata " bytes from ",
                   l_addr " on" port " l_port";
               Say "The received data is: "l_data;
            end; /* RECV */
         end; /* SEND */
      end;  /* CONNECT OK */
      else do /* CONNECT not OK */
         say "No Connection to remote host could be",
             "establisthed";
      end;
   end; /* GETADDRINFO */
end; /* INITIALIZE */

ENDPROGRAM:
src=socket("CLOSE",l_sockid);
src=perror(src,"CLOSE");
src=socket("TERMINATE","MYSET01");
src=perror(src,"TERMINATE");
exit 0;

/* This routine returns -1 if the first word if arg 1 is not zero */
perror: if word(arg(1),1) = 0 then return 0; else
    Say arg(2) "Error : "arg(1);
    return -1;
/* REXX EZARXR32 */
/*
 * This example shows how to use the GETADDRINFO command
 * to obtain a list of NAME constructs suitable for
 * use with the BIND command using the well-known port 54123.
 * The addr fields of the NAME constructs returned will be
 * set to
 *
 * This example also shows how to use the SELECT command to
 * monitor listening sockets for for new connections.
 *
 * In the case of 2 name constructs being returned the
 * first successful bind will be used.
 *
 * HINT: To limit the NAME structures to a specific
 *       Address family change AF_UNSPEC to either
 *       AF_INET or AF_INET6
 *
 * HINT: Coding a hostname for the node paramter will result
 *       in the ipaddress fields of the NAME constructs to
 *       have a specific interface address assigned.
 *
 */

l_selectlist = '';
src = socket("INITIALIZE","MYSET01");
src = socket("GETADDRINFO",,54123,"AI_PASSIVE",
             "AI_CANONNAMEOK","AF_UNSPEC");
parse var src l_retcode l_canname l_names
l_bindok = "FALSE";
Say "Canonname returned is: "l_canname;
do while l_names \= ''
   select
      when word(l_names,1) = "AF_INET" then do
         l_SockName = word(l_names,1) word(l_names,2),
                      word(l_names,3)
         l_names = subword(l_names,4);
      end;
      when word(l_names,1) = "AF_INET6" then do
         l_SockName = word(l_names,1) word(l_names,2),
                      word(l_names,3) word(l_names,4),
                      word(l_names,5);
         l_names = subword(l_names,6);
      end;
      otherwise
         l_sockname = "unknown";
   end;
   src=socket("SOCKET",word(l_sockname,1),"STREAM");
   if word(src,1) = 0 then do
      l_socket = word(src,2);
      src = socket("BIND",l_socket1,l_sockname);
      if word(src,1) = 0 then do
         src = socket("LISTEN",l_socket);
         if word(src,1) = 0 then do
            Say "Listening on socket: "l_sockname;
            l_selectlist = l_selectlist" "l_socket;
            l_bindOK = "TRUE";
         end;
      end;
   end;
end;
if l_selectlist \= 0 then do
   Say "The following sockets will be monitored" l_selectlist;
   l_fdset = "READ "l_selectlist" WRITE EXCEPTION";
   src = socket("SELECT",l_fdset,0);
   if word(src,1) = 0 & word(src,2) \= 0 then do
      l_socklist = subword(src,3);
      do while l_socklist \= ''
         parse var l_socklist l_sockid l_socklist
         src = socket("ACCEPT",l_sockid);
         if word(src,1) = 0 then do
            l_newsock = word(src,2);
            /*
             * DO SOME STUFF WITH l_newsock
             *
             */
            src = socket("CLOSE",l_newsock);
         end;
      end;
   end;
   src = socket("CLOSE",word(l_selectlist,1));
   src = socket("CLOSE",word(l_selectlist,2));
end;
src = socket("TERMINATE","MYSET01");
exit word(src,1);

Go to the previous page Go to the next page




Copyright IBM Corporation 1990, 2014