|
Description
The ioctl() function also executes control functions for sockets.
s designates the socket descriptor.
The data type of the object passed as the current parameter for arg depends on the control function concerned and is a pointer to either an integer variable (int) or a special data structure. Type conversion to "pointer to char" is therefore required when calling ioctl().
More general information on this function is available in the manual "C Library Functions for POSIX Applications".
The following control functions are supported for sockets:
Request | *arg | Function |
FIONBIO |
| Enable/disable blocking mode |
FIONREAD |
| Get message length |
FIOSETOWN |
| Set process ID |
FIOGETOWN |
| Get process ID |
SIOCSPGRP | like FIOSETOWN | |
SIOCGPGRP | like FIOGETOWN | |
SIOCGLIFNUM |
| Get number of interfaces |
SIOCGLIFCONF |
| Get interface configuration |
SIOCGLIFADDR |
| Get Internet address of the interface |
SIOCGLIFINDEX |
| Get index of the interface |
SIOCGLIFBRDADDR |
| Get broadcast address of the interface |
SIOCGLIFNETMASK |
| Get subnetwork mask of the interface |
SIOCGLIFFLAGS |
| Get flags of the interface |
SIOCGIFNUM |
| Get interface number (only IPv4) |
SIOCGIFCONF |
| Get interface configuration (only IPv4) |
SIOCGIFADDR |
| Get interface Internet address (only IPv4) |
SIOCGIFINDEX |
| Get index of the interface (only IPv4) |
SIOCGIFBRDADDR |
| Get interface broadcast address (only IPv4) |
SIOCGIFNETMASK |
| Get subnetwork mask of the interface (only IPv4) |
SIOCGIFFLAGS |
| Get interface flags |
FIONBIO
This option affects the execution behavior of socket functions when data flow control is triggered.
*arg == 0:
Socket functions block until the function can be executed.
*arg != 0:
Socket functions return with the errno code EWOULDBLOCK if the function cannot be executed immediately due to data flow control.
FIONREAD
Returns the length of the message currently in the input buffer.
FIOSETOWN
The process ID will be set for the specified socket, causing a SIGIO signal to be sent to the process when a message arrives.
SIOCSPGRP
Like FIOSETOWN.
FIOGETOWN
Returns the process ID set for the socket.
SIOCGPGRP
Like FIOGETOWN.
SIOCGLIFNUM
The number of network interfaces is returned in the lifn_count member. Only the intefaces which belong to the adress family (AF_UNSPEC, AF_INET or AF_INET6) specified in the lifn_family member are counted.
SIOCGLIFCONF
A list of the network configuration is returned. For each interface belonging to the address family specified in the lifc_family member and for which the flags specified in the lifc_flags member are set, an entry of the type struct lifreq is written to the area which is addressed by the lifc_buf member. If the length of this area (lifc_len) is not sufficient, the EINVAL error is reported.
The lifconf and lifreq structures are defined in the include file <net/if.h>.
SIOCGLIFADDR
The Interface address is returned in the lifr_addr member for the interface specified with the lifr_name member.
SIOCGLIFINDEX
The index (the interface number) is returned in the lifr_index member for the interface specified with the lifr_name member.
SIOCGLIFBRDADDR
The broadcast address is returned in the lifr_broadaddr member for the interface specified with the lifr_name member. For IPv4 interfaces without broadcast capability and for IPv6 interfaces, the EADDRNOTAVAIL error is reported.
SICGLIFNETMASK
The subnetwork mask is returned in the lifr_addr member for the interface specified with the lifr_name member. For IPv6 interfaces the EADDRNOTAVAIL error is reported.
SIOCGLIFFLAGS
The interface flags are returned in the lifr_flags member for the interface specified with the lifr_name member. The possible flags are IFF_UP, IFF_LOOPBACK and IFF_BROADCAST.
The folllowing options are supported for reasons of compatibility. However, they only return information on IPv4 interfaces:
SIOCGIFNUM
The number of IPv4 interfaces is returned in the argument *arg.
SIOCGIFCONF
A list of the IPv4 network configuration is returned. For each IPv4 interface an entry of the type struct ifreq is written into the area which is addressed by the ifc_buf member. If the length of this area (ifc_len) is not sufficient, the EINVAL error is reported.
The ifconf and ifreq structures are defined in the include file <net/if.h>.
SIOCGIFADDR
The Internet address is returned in the ifr_addr member for the interface specified with the ifr_name member.
SIOCGIFINDEX
The index (the interface number) is returned in the ifr_index member for the interface specified with the ifr_name member.
SIOCGIFBRDADDR
The broadcast address is returned in the ifr_broadaddr member for the interface specified with the ifr_name member. If the interface does not have broadcast capability, the EADDRNOTAVAIL error is reported.
SIOCGIFNETMASK
The subnet mask is returned in the if_addr element for the interface specified with the ifr_name element.
SIOCGIFFLAGS
The interface flags are returned in the ifr_flags member for the interface specified with the ifr_name member. The possible flags are IFF_UP, IFF_LOOPBACK and IFF_BROADCAST.
Return value
0:
If successful.
-1:
If errors occur. errno is set to indicate the error.
Errors
EFAULT
The buffer to which arg points, lies outside the address range assigned to the process.
EINVAL
request or arg are not valid.
The interface name specified (in lifr_name or ifr_name) is not valid.
The address family specified (in lifn_family or lifc_family) is not valid.
The length of the output area (lifc_len or ifc_len) specified in SIOCGLIFCONF or SIOCGIFCONF is not large enough.
EIO
A physical input/output error occurred.
EOPNOTSUPP
request is not supported.
EADDRNOTAVAIL
request is not possible for this interface.
Example
Get all interface names and addresses with SIOCGLIFCONF.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stropts.h> #include <sys/filio.h> #include <sys/socket.h> #include <sys/sockio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <net/if.h> #include <netdb.h> #define err_exit(a) {perror((a)); exit(1);} int main(int argc, char **argv) { int soc, cnt, af; struct lifconf lifc; struct lifreq *plifr; struct lifnum lifn; char addr_str[INET6_ADDRSTRLEN + 1]; char af_str[64]; soc = socket(AF_INET, SOCK_DGRAM, 0); lifn.lifn_family = AF_UNSPEC; lifn.lifn_flags = 0; if (ioctl(soc, SIOCGLIFNUM, &lifn) < 0) { err_exit("ioctl(SIOCGLIFNUM)"); } lifc.lifc_len = lifn.lifn_count * sizeof(struct lifreq); lifc.lifc_buf = malloc(lifn.lifn_count * sizeof(struct lifreq)); if (lifc.lifc_buf == NULL) { err_exit("malloc"); } lifc.lifc_family = AF_UNSPEC; lifc.lifc_flags = 0; if (ioctl(soc, SIOCGLIFCONF, &lifc) < 0) { err_exit("ioctl(SIOCGLIFCONF)"); } plifr = lifc.lifc_req; cnt = lifc.lifc_len / sizeof (struct lifreq); for (; cnt>0; cnt--, plifr++) { af = plifr->lifr_addr.ss_family; switch (af) { case AF_INET: sprintf(af_str, "AF_INET"); inet_ntop(af, &((struct sockaddr_in *)&plifr->lifr_addr)->sin_addr, addr_str, INET6_ADDRSTRLEN); break; case AF_INET6: sprintf(af_str, "AF_INET6"); inet_ntop(af, &((struct sockaddr_in6 *)&plifr->lifr_addr)->sin6_addr, addr_str, INET6_ADDRSTRLEN); break; default: sprintf(af_str, "af=%d", af); strcpy(addr_str, "???"); } printf ("%-15s %-8s %s\n", plifr->lifr_name, af_str, addr_str); } free(lifc.lifc_buf); return 0; }
Compile and run the example program ifconf.c:
$ cc ifconf.c -lsocket -o ifconf $ ./ifconf IF000001 AF_INET 127.0.0.1 IF000002 AF_INET6 ::1 IF000003 AF_INET 192.168.138.33 IF000004 AF_INET 192.168.139.33 IF000005 AF_INET6 fe80::800:14ff:fe10:1021 IF000006 AF_INET6 fe80::800:14ff:fe10:2021 IF000007 AF_INET6 fe80::219:99ff:fe9c:7e8c IF000008 AF_INET6 fe80::219:99ff:fe9c:7ecc IF000009 AF_INET 172.17.65.67 IF000010 AF_INET 1.1.65.67 IF000011 AF_INET 192.168.151.33 IF000012 AF_INET 192.168.152.33 IF000013 AF_INET6 fe80::800:14ff:fe10:8021 IF000014 AF_INET6 fe80::800:14ff:fe10:9021 IF000015 AF_INET6 fd5e:5e5e:600:0:219:99ff:fe9c:7e8c IF000016 AF_INET6 fd5e:5e5e:600:0:219:99ff:fe9c:7ecc $