Under Construction
MAC-Adresse für ein Netzwerk-Interface abfragen (SIOCGIFHWADDR)
Für die Abfrage der unterliegenden Hardware-Adresse (meistens Ethernet MAC-Adresse) kann unter AIX der Request Code SIOCGIFHWADDR verwendet werden. Die Information wird über die Struktur ifhwaddr_req aus /usr/include/net/if.h zurückgeliefert:
#define MAX_HWADDR_LEN 64
/* ifreq structure for SIOCGIFHWADDR */
struct ifhwaddr_req {
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" or "ib0" */
char ifr_hwaddr[MAX_HWADDR_LEN]; /* device hardware address */
int addr_len;
};
Die Struktur ifhwaddr_req unterstützt Adressen mit einer Länge von bis zu 64 Bytes. Im Feld addr_len wird die Länge der Hardware-Adresse zurückgeliefert, für Ethernet Adressen sind das 6 Bytes. Die Hardware-Adresse selbst wird im Array ifr_hwaddr abgelegt. Vor dem Aufruf des ioctl(2) muss der Name des Netzwerk-Interfaces in ifr_name abgelegt werden.
Das folgende Beispiel-Programm zeigt die Verwendung von SIOCGIFHWADDR mit der Struktur ifhwaddr_req:
$ cat get_mac.c
/*
* Copyright (c) 2022 by PowerCampus 01 GmbH
*/
#include <sys/ioctl.h> // SIOCGIFADDR
#include <sys/socket.h> // socket()
#include <net/if.h> // ifhwaddr_req
#include <arpa/inet.h> // ether_ntoa()
#include <errno.h> // errno, perror()
#include <unistd.h> // ioctl(), close()
#include <stdio.h> // fprintf()
#include <stdlib.h> // exit()
#include <string.h> // strncpy()
int main( int argc , char** argv )
{
int sd;
int ret;
struct ether_addr* addr;
// 1. Provide buffer for the request.
struct ifhwaddr_req req;
// 2. Store interface name in ifr_name.
strncpy(req.ifr_name,argv[1],IFNAMSIZ);
// 3. Create datagram socket for address family Inet.
sd = socket(AF_INET,SOCK_DGRAM,0);
if ( sd == -1 )
{
perror("get_mac");
exit(errno);
}
// 4. Call ioctl with command SIOCGIFHWADDR.
ret = ioctl(sd,SIOCGIFHWADDR,&req);
if ( ret == -1 )
{
perror("get_mac");
exit(errno);
}
// 5. Print MAC-Address.
addr = (struct ether_addr*)&(req.ifr_hwaddr);
printf("MAC: %s\n",ether_ntoa(addr));
// 6. Close socket descriptor
close(sd);
return 0;
}
$
Das Programm erwartet als Argument beim Aufruf den Namen eines Netzwerk-Interfaces und gibt dann für dieses Interface die MAC-Adresse aus.
Das Programm kann z.B. mit dem GNU C-Compiler übersetzt werden:
$ gcc -o get_mac get_mac.c
$
Ein kleiner Test für das Netzwerk-Interface en0 zeigt wie gewünscht die MAC-Adresse des Interfaces:
$ get_mac en0
MAC: 32:7e:ba:40:74:5
$
Allerdings unterstützt nicht jedes Netzwerk-Interface den ioctl(2) mit Request-Code SIOGIFHWADDR. Das Loopback-Interface lo0 beispielsweise, besitzt keine Hardware-Adresse und unterstützt die Abfrage entsprechend auch nicht:
$ get_mac lo0
get_mac: Invalid argument
$
Der ioctl(2) liefert in diesem Fall den Fehler EINVAL (Fehler 22: invalid argument) zurück