Under Construction

Informationen für ein Netzwerk-Interface (KINFO_GET_IFNET)

Mit dem System-Call getkerninfo() können auch gezielt Informationen für ein bestimmtes Netzwerk-Interface abgefragt werden. Hierfür kann der Operations-Code KINFO_GET_IFNET verwendet werden. Das Netzwerk-Interface für das Informationen abgerufen werden soll, muss als viertes Argument angegeben werden. Die Informationen werden in Form einer kinfo_ifnet Struktur (definiert in /usr/include/net/if.h) zurückgegeben:

/*
* Structure returned by getkerninfo KINFO_GET_IFNET
*/
struct kinfo_ifnet {
        char    if_name[IFNAMSIZ];   /* name, e.g. ``en'' or ``lo'' */
        u_char  if_type;             /* ethernet, tokenring, etc */
        u_char  if_index;            /* numeric abbreviation for this if  */
        short   if_unit;             /* sub-unit for lower level driver */
        u_int32_t  if_mtu;           /* maximum transmission unit */
        u_int32_t  if_flag;          /* up/down, broadcast, etc. */
};

Es werden unter Anderem der Name (if_name), der Typ des Interfaces (if_type) und die MTU (if_mtu) für das Interface zurückgeliefert. Dementsprechend sollte als Puffer die Adresse einer kinfo_ifnet Struktur angegeben werden. Als Größe sollte dann sizeof(kinfo_ifnet) angegeben werden.

Der Name des Netzwerk-Interfaces wird in Form einer Zeichenkette (char*) angegeben, die auf den Typ int32long64_t des vierten Arguments gecastet werden muss, z.B.:

char name[] = „lo0“; // loopback interface
struct kinfo_ifnet info;
int size = sizeof(struct kinfo_ifnet);
int ret = getkerninfo(KINFO_GET_IFNET,(char*)&info,&size,(int32long64_t)name);

Bei einem erfolgreichen Aufruf wird der Wert 0 zurückgegeben, nicht die Anzahl der verfügbaren Bytes wie bei einigen anderen Operations-Codes. Im Fehlerfalle wird der Wert -1 zurückgegeben und die Variable errno gesetzt. Folgende Fehler können auftreten:

EINVAL – Puffer-Adresse (zweites Argument) ist ungültig

EINVAL – die angegebene Größe des Puffers (drittes Argument) ist kleiner als sizeof(struct kinfo_ifnet)

EINVAL – ungültiges viertes Argument, z.B. 0

ENXIO – das angegebene Device (vierte Argument) existiert nicht

Der Wert von size wird durch den Aufruf geändert. Er gibt an um wieviele Bytes der angegebene Puffer zu groß ist. Wurde die richtige Puffer-Größe (sizeof(struct kinfo_ifnet)) angegeben, dann hat size den Wert 0.

Das folgende kleine Beispiel-Programm liefert einige Informationen zu einem als Argument angegebenen Netzwerk-Interface:

$ cat kinfo_get_ifnet.c
#include <sys/kinfo.h>
#include <sys/ndd.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int getkerninfo(int operation, char *buffer, int *buffer_size, int32long64_t argument);

int main( int argc , char** argv )
{
        struct kinfo_ifnet info;
        int size = sizeof(struct kinfo_ifnet);
        int ret;

        // 1. get information about interface en0 from kernel
        if ( ( ret = getkerninfo(KINFO_GET_IFNET,(char*)&info,&size,(int32long64_t)argv[1]) ) == -1 )
        {
                perror("kinfo_get_ifnet");
                exit(errno);
        }
        printf("ret=%d size=%d\n",ret,size);

        // 2. use the data
        printf("interface: %s\n",info.if_name);
        printf("index: %d\n",info.if_index);
        printf("MTU: %d\n",info.if_mtu);

        return 0;
}

$

Das Programm kann mit einem C-Compiler übersetzt und dann gestartet werden. Beim Start des Programms muss der Name eines Netzwerk-Interfaces angegeben werden:

$ gcc -o kinfo_get_ifnet kinfo_get_ifnet.c
$ kinfo_get_ifnet lo0
ret=0 size=0
interface: lo0
index: 1
MTU: 16896
$ kinfo_get_ifnet en0
ret=0 size=0
interface: en0
index: 2
MTU: 1500
$ kinfo_get_ifnet en1
kinfo_get_ifnet: No such device or address
$