getifaddrs()--Return All Interface Addresses
Syntax
#include <ifaddrs.h> int getifaddrs(struct ifaddrs **ifap)
Service Program Name: QSOSRV2
Default Public Authority: *USE
Threadsafe: Yes
The getifaddrs() function stores a reference to a linked list of ifaddrs structures, one structure per interface. The end of the linked list of structures is indicated by a structure with an ifa_next of NULL.
Parameters
- ifap
- (I/O) Reference to the pointer to the linked list of network interface structures that contain the following:
- The pointer to the next structure
- The interface name
- The interface flags
- The interface address
- The interface netmask
- The broadcast address or the address of the other end of the link
- The pointer to the address specific data
struct ifaddrs { struct ifaddrs *ifa_next; char *ifa_name; u_int ifa_flags; struct sockaddr *ifa_addr; struct sockaddr *ifa_netmask; union { struct sockaddr *ifu_broadaddr; struct sockaddr *ifu_dstaddr; } ifa_ifu; void *ifa_data; };
The ifa_next field contains a pointer to the next structure on the list. This field is NULL in the last structure on the list.
The ifa_name field contains the interface (line description) name.
The ifa_flags field contains flags that give some information about the interface.
The ifa_addr field references either the address of the interface or the link level address of the interface, if one exists; otherwise, it is NULL. (The sa_family field of the ifa_addr field should be consulted to determine the format of the ifa_addr address.)
The ifa_netmask field references the netmask associated with ifa_addr, if one is set; otherwise, it is NULL.
The ifa_ifu field is a union of the following:
- ifu_broadaddr, which should only be referenced for a non point-to-point interface, references the broadcast address associated with ifa_addr, if one exists; otherwise, it is NULL.
- ifu_dstaddr references the destination address on a point-to-point interface, if one exists; otherwise, it is NULL.
The ifa_data field is not used.
- The pointer to the next structure
Authorities
No authorization is required.
Return Value
getifaddrs() returns an integer. Possible values are:
- -1 (unsuccessful)
- 0 (successful)
Error Conditions
When getifaddrs() fails, errno can be set to one of the following:
[ENOMEM] | No memory available for the ifaddrs linked list. |
[ENXIO] | No interfaces exist. |
Usage Notes
- The interface (line description) name stored at ifa_name will be returned in the default coded character set identifier (CCSID) currently in effect for the job.
- For more information about the flags returned in ifa_flags, see <net/if.h>.
- A variant of sockaddr structure will be used for ifa_addr, ifa_netmask, ifa_broadaddr, and ifa_dstaddr. The sockaddr_in structure will be used for AF_INET addresses and sockaddr_in6 will be used for AF_INET6 addresses.
- The data returned by getifaddrs() is dynamically allocated and should be freed with freeifaddrs() when no longer needed.
Related Information
- freeifaddrs()--Free Dynamic Memory Allocated by getifaddrs()
Example
The following example shows how getifaddrs() is used.
Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.
#include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <net/if.h> #include <ifaddrs.h> #include <errno.h> #include <stdio.h> int main() { struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL; void *tempAddrPtr = NULL; int rc = 0; char addressOutputBuffer[INET6_ADDRSTRLEN]; rc = getifaddrs(&interfaceArray); /* retrieve the current interfaces */ if (rc == 0) { for(tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = tempIfAddr->ifa_next) { if(tempIfAddr->ifa_addr->sa_family == AF_INET) tempAddrPtr = &((struct sockaddr_in *)tempIfAddr->ifa_addr)->sin_addr; else tempAddrPtr = &((struct sockaddr_in6 *)tempIfAddr->ifa_addr)->sin6_addr; printf("Internet Address: %s \n", inet_ntop(tempIfAddr->ifa_addr->sa_family, tempAddrPtr, addressOutputBuffer, sizeof(addressOutputBuffer))); printf("LineDescription : %s \n", tempIfAddr->ifa_name); if(tempIfAddr->ifa_netmask != NULL) { if(tempIfAddr->ifa_netmask->sa_family == AF_INET) tempAddrPtr = &((struct sockaddr_in *)tempIfAddr->ifa_netmask)->sin_addr; else tempAddrPtr = &((struct sockaddr_in6 *)tempIfAddr->ifa_netmask)->sin6_addr; printf("Netmask : %s \n", inet_ntop(tempIfAddr->ifa_netmask->sa_family, tempAddrPtr, addressOutputBuffer, sizeof(addressOutputBuffer))); } if(tempIfAddr->ifa_ifu.ifu_broadaddr != NULL) { /* If the ifa_flags field indicates that this is a P2P interface */ if(tempIfAddr->ifa_flags & IFF_POINTOPOINT) { printf("Destination Addr: "); if(tempIfAddr->ifa_ifu.ifu_dstaddr->sa_family == AF_INET) tempAddrPtr = &((struct sockaddr_in *)tempIfAddr->ifa_ifu.ifu_dstaddr)->sin_addr; else tempAddrPtr = &((struct sockaddr_in6 *)tempIfAddr->ifa_ifu.ifu_dstaddr)->sin6_addr; } else { printf("Broadcast Addr : "); if(tempIfAddr->ifa_ifu.ifu_broadaddr->sa_family == AF_INET) tempAddrPtr = &((struct sockaddr_in *)tempIfAddr->ifa_ifu.ifu_broadaddr)->sin_addr; else tempAddrPtr = &((struct sockaddr_in6 *)tempIfAddr->ifa_ifu.ifu_broadaddr)->sin6_addr; } printf("%s \n", inet_ntop(tempIfAddr->ifa_ifu.ifu_broadaddr->sa_family, tempAddrPtr, addressOutputBuffer, sizeof(addressOutputBuffer))); } printf("\n"); } freeifaddrs(interfaceArray); /* free the dynamic memory */ interfaceArray = NULL; /* prevent use after free */ } else { printf("getifaddrs() failed with errno = %d %s \n", errno, strerror(errno)); return rc; } }
Output:
Assume the system has the following three interfaces configured:
- 9.5.139.105 (ETHVLINE)
- 127.0.0.1 (*LOOPBACK)
- ::1 (*LOOPBACK)
Internet Address: 9.5.139.105 LineDescription : ETHVLINE Netmask : 255.255.255.224 Broadcast Addr : 9.5.139.127 Internet Address: 127.0.0.1 LineDescription : *LOOPBACK Netmask : 255.0.0.0 Internet Address: ::1 LineDescription : *LOOPBACK Netmask : FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
API introduced: V6R1