Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

ioctl() - control sockets

&pagelevel(4)&pagelevel

#include <stropts.h>
#include <sys/filio.h>
#include <sys/sockio.h>
#include <net/if.h>

int ioctl(int s, unsigned long request, char *arg);

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

int

Enable/disable blocking mode

FIONREAD

int

Get message length

FIOSETOWN

int

Set process ID

FIOGETOWN

int

Get process ID

SIOCSPGRP

like FIOSETOWN

SIOCGPGRP

like FIOGETOWN

SIOCGLIFNUM

struct lifnum

Get number of interfaces

SIOCGLIFCONF

struct lifconf

Get interface configuration

SIOCGLIFADDR

struct lifreq

Get Internet address of the interface

SIOCGLIFINDEX

struct lifreq

Get index of the interface

SIOCGLIFBRDADDR

struct lifreq

Get broadcast address of the interface

SIOCGLIFNETMASK

struct lifreq

Get subnetwork mask of the interface

SIOCGLIFFLAGS

struct lifreq

Get flags of the interface

SIOCGIFNUM

int

Get interface number (only IPv4)

SIOCGIFCONF

struct ifconf

Get interface configuration (only IPv4)

SIOCGIFADDR

struct ifreq

Get interface Internet address (only IPv4)

SIOCGIFINDEX

struct ifreq

Get index of the interface (only IPv4)

SIOCGIFBRDADDR

struct ifreq

Get interface broadcast address (only IPv4)

SIOCGIFNETMASK

struct ifreq

Get subnetwork mask of the interface (only IPv4)

SIOCGIFFLAGS

struct ifreq

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.

ifconf.c
#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
$