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() - Sockets steuern

&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);

Beschreibung

Die Funktion ioctl() führt Steuerfunktionen auch für Sockets aus.

s bezeichnet den Socket-Deskriptor.

Der Datentyp des als aktueller Parameter für arg übergebenen Objekts hängt von der jeweiligen Steuerfunktion ab, ist jedoch entweder ein Zeiger auf eine Integer-Variable (int) oder auf eine spezielle Datenstruktur. Beim Aufruf von ioctl() ist deshalb eine Typanpassung an "Zeiger auf char" notwendig.

Weitere allgemeine Informationen zu dieser Funktion finden Sie im Handbuch "C-Bibliotheksfunktionen für POSIX-Anwendungen".

Folgende Steuerfunktionen werden für Sockets unterstützt:

request

*arg

Funktion

FIONBIO

int

Blocking-Modus ein- und ausschalten

FIONREAD

int

Nachrichtenlänge ermitteln

FIOSETOWN

int

Prozess-ID setzen

FIOGETOWN

int

Prozess-ID ermitteln

SIOCSPGRP

wie FIOSETOWN

SIOCGPGRP

wie FIOGETOWN

SIOCGLIFNUM

struct lifnum

Interface-Anzahl ermitteln

SIOCGLIFCONF

struct lifconf

Interface-Konfiguration ermitteln

SIOCGLIFADDR

struct lifreq

Internet-Adresse des Interface ermitteln

SIOCGLIFINDEX

struct lifreq

Index des Interface ermitteln

SIOCGLIFBRDADDR

struct lifreq

Broadcast-Adresse des Interface ermitteln

SIOCGLIFNETMASK

struct lifreq

Subnetzmaske des Interface ermitteln

SIOCGLIFFLAGS

struct lifreq

Flags des Interface ermitteln

SIOCGIFNUM

int

Interface-Anzahl ermitteln (nur IPv4)

SIOCGIFCONF

struct ifconf

Interface-Konfiguration ermitteln (nur IPv4)

SIOCGIFADDR

struct ifreq

Internet-Adresse des Interface ermitteln (nur IPv4)

SIOCGIFINDEX

struct ifreq

Index des Interface ermitteln (nur IPv4)

SIOCGIFBRDADDR

struct ifreq

Broadcast-Adresse des Interface ermitteln (nur IPv4)

SIOCGIFNETMASK

struct ifreq

Subnetzmaske des Interface ermitteln (nur IPv4)

SIOCGIFFLAGS

struct ifreq

Flags des Interface ermitteln (nur IPv4)

FIONBIO

Diese Option beeinflusst das Ausführungsverhalten von Socket-Funktionen bei Auftreten der Datenflusskontrolle.

*arg == 0:
Socket-Funktionen blockieren, bis die Funktion ausgeführt werden kann.

*arg != 0:

Socket-Funktionen kehren mit dem errno-Code EWOULDBLOCK zurück, wenn die Funktion auf Grund der Datenflusskontrolle nicht sofort ausgeführt werden kann.

FIONREAD

Die Länge der aktuell im Eingangspuffer vorhandenen Nachricht wird zurückgeliefert.

FIOSETOWN

Für den spezifizierten Socket wird die Prozess-ID gesetzt , wodurch bei Eintreffen einer Nachricht ein SIGIO-Signal an den Prozess gesendet wird.

SIOCSPGRP

Wie FIOSETOWN.

FIOGETOWN

Die für den Socket gesetzte Prozess-ID wird zurückgeliefert.

SIOCGPGRP

Wie FIOGETOWN.

SIOCGLIFNUM

Die Anzahl der Netzwerk-Interfaces wird im Element lifn_count zurückgeliefert. Es werden nur die Interfaces entsprechend der im Element lifn_family angegebenen Adressfamilie (AF_UNSPEC, AF_INET oder AF_INET6) gezählt.

SIOCGLIFCONF

Es wird eine Liste der Netzwerkkonfiguration geliefert. Für jedes Interface, das der im Element lifc_family angegebenen Adressfamilie angehört und bei dem die im Element lifc_flags angegebenen Flags gesetzt sind, wird ein Eintrag vom Typ struct lifreq in den Bereich geschrieben, der durch das Element lifc_buf adressiert wird. Wenn die Länge dieses Bereichs (lifc_len) nicht ausreichend groß ist, wird der Fehler EINVAL gemeldet.

Die Strukturen lifconf und lifreq sind in der Include-Datei <net/if.h> definiert.

SIOCGLIFADDR

Für das mit dem Element lifr_name spezifizierte Interface wird die Internet-Adresse im Element lifr_addr zurückgeliefert.

SIOCGLIFINDEX

Für das mit dem Element lifr_name spezifizierte Interface wird der Index (die Interface-Nummer) im Element lifr_index zurückgeliefert.

SIOCGLIFBRDADDR

Für das mit dem Element lifr_name spezifizierte Interface wird die Broadcast-Adresse im Element lifr_broadaddr zurückgeliefert. Für IPv4-Interfaces, die nicht Broadcast-fähig sind, und für IPv6-Interfaces wird der Fehler EADDRNOTAVAIL gemeldet.

SICGLIFNETMASK

Für das mit dem Element lifr_name spezifizierte Interface wird die Subnetzmaske im Element lifr_addr zurückgeliefert. Für IPv6-Interfaces wird der Fehler EADDRNOTAVAIL gemeldet.

SIOCGLIFFLAGS

Für das mit dem Element lifr_name spezifizierte Interface werden die Interface-Flags im Element lifr_flags zurückgeliefert. Mögliche Flags sind IFF_UP, IFF_LOOPBACK und IFF_BROADCAST.

Die folgenden Optionen werden aus Kompatibilitätsgründen unterstützt. Sie liefern aber nur Informationen über IPv4-Interfaces:

SIOCGIFNUM

Die Anzahl der IPv4-Interfaces wird im Argument *arg zurückgeliefert.

SIOCGIFCONF

Es wird eine Liste der IPv4-Netzwerkkonfiguration geliefert. Für jedes IPv4-Interface wird ein Eintrag vom Typ struct ifreq in den Bereich geschrieben, der durch das Element ifc_buf adressiert wird. Wenn die Länge dieses Bereichs (ifc_len) nicht ausreichend groß ist, wird der Fehler EINVAL gemeldet.

Die Strukturen ifconf und ifreq sind in der Include-Datei <net/if.h> definiert.

SIOCGIFADDR

Für das mit dem Element ifr_name spezifizierte Interface wird die Internet-Adresse im Element ifr_addr zurückgeliefert.

SIOCGIFINDEX

Für das mit dem Element ifr_name spezifizierte Interface wird der Index (die Interface-Nummer) im Element ifr_index zurückgeliefert.

SIOCGIFBRDADDR

Für das mit dem Element ifr_name spezifizierte Interface wird die Broadcast-Adresse im Element ifr_broadaddr zurückgeliefert. Falls das Interface nicht Broadcast-fähig ist, wird der Fehler EADDRNOTAVAIL gemeldet.

SIOCGIFNETMASK

Für das mit dem Element ifr_name spezifizierte Interface wird die Subnetzmaske im Element ifr_addr zurückgeliefert.

SIOCGIFFLAGS

Für das mit dem Element ifr_name spezifizierte Interface werden die Interface-Flags im Element ifr_flags zurückgeliefert. Mögliche Flags sind IFF_UP, IFF_LOOPBACK und IFF_BROADCAST.

Returnwert

0:

Bei Erfolg.

-1:

Bei Fehler. errno wird gesetzt, um den Fehler anzuzeigen.

Fehler

EFAULT

Der Puffer, auf den arg zeigt, liegt außerhalb des dem Prozess zugewiesenen Adressraums.

EINVAL

request oder arg sind nicht gültig.

Der angegebene Interface-Name (in lifr_name bzw. ifr_name) ist nicht gültig.
Die angegebene Adressfamilie (in lifn_family bzw. lifc_family) ist nicht gültig.
Die Länge des bei SIOCGLIFCONF bzw. SIOCGIFCONF angegebenen Ausgabebereichs (lifc_len bzw. ifc_len) ist zu klein.

EIO

Es ist ein physikalischer Ein-/Ausgabefehler aufgetreten.

EOPNOTSUPP

request wird nicht unterstützt.

EADDRNOTAVAIL

request ist für dieses Interface nicht möglich.

Beispiel

Ermitteln aller Interface-Namen und -Adressen mit 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;
}

Übersetzen und Ausführen des Beispielprogramms 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
$