|
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 |
| Blocking-Modus ein- und ausschalten |
FIONREAD |
| Nachrichtenlänge ermitteln |
FIOSETOWN |
| Prozess-ID setzen |
FIOGETOWN |
| Prozess-ID ermitteln |
SIOCSPGRP | wie FIOSETOWN | |
SIOCGPGRP | wie FIOGETOWN | |
SIOCGLIFNUM |
| Interface-Anzahl ermitteln |
SIOCGLIFCONF |
| Interface-Konfiguration ermitteln |
SIOCGLIFADDR |
| Internet-Adresse des Interface ermitteln |
SIOCGLIFINDEX |
| Index des Interface ermitteln |
SIOCGLIFBRDADDR |
| Broadcast-Adresse des Interface ermitteln |
SIOCGLIFNETMASK |
| Subnetzmaske des Interface ermitteln |
SIOCGLIFFLAGS |
| Flags des Interface ermitteln |
SIOCGIFNUM |
| Interface-Anzahl ermitteln (nur IPv4) |
SIOCGIFCONF |
| Interface-Konfiguration ermitteln (nur IPv4) |
SIOCGIFADDR |
| Internet-Adresse des Interface ermitteln (nur IPv4) |
SIOCGIFINDEX |
| Index des Interface ermitteln (nur IPv4) |
SIOCGIFBRDADDR |
| Broadcast-Adresse des Interface ermitteln (nur IPv4) |
SIOCGIFNETMASK |
| Subnetzmaske des Interface ermitteln (nur IPv4) |
SIOCGIFFLAGS |
| 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.
#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 $