Moin,
ich muss in meinem Programm die MAC-Adressen aller Netzwerkkarten ermitteln. Dabei möchte ich eine saubere Lösung, die nicht über Kommandozeilen-Tools geht und mittels grep/awk/... die MAC raussucht. Wichtig ist dabei, dass keine Loop-Devices berücksichtigt werden.
Könnte mir jemand einen kleinen Denkanstoß geben?
MfG
bfeater
Ermitteln der Mac-Adresse
-
- prolinux-forum-admin
- Posts: 1444
- Joined: 26. Jun 2004 21:18
- Contact:
In irgend einer Kernelheaderdatei wird wohl eine Struktur herumschwirren. Da du *alle* Adressen haben möchtest, ist es am einfachsten den Descriptor des Kernels zu benutzen der auf eine Liste *aller* Adressen zeigt:
MfG, Klopskuchen
Code: Select all
FILE *fp;
char *dat = "/proc/net/arp";
if ( (fp = fopen( dat, "r" )) != NULL ){
hier dein code;
fclose(fp);
}
MfG, Klopskuchen
When all else fails, read the instructions .
Hallo,
Da ich nichts besseres während meiner Mittagspause zu tun hatte, hier ein Beispiel für das erste Interface. Loopback wird uebersprungen und die Were im char addr gespeichert:
Bitte beachte, dass das Beispiel keine Ueberpruefung der Returnwerte enthaelt. Also auf jeden Fall noch die Values ueberpruefen. Auch sollte bcopy nur gemacht werden, wenn "break" erreicht wurde. Compilieren mit "gcc name.c". Funktioniert auch nur unter Linux.
Gruss,
demon
Da ich nichts besseres während meiner Mittagspause zu tun hatte, hier ein Beispiel für das erste Interface. Loopback wird uebersprungen und die Were im char addr gespeichert:
Code: Select all
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if.h>
int main( int argc, char **argv)
{
struct ifreq ifr;
struct ifreq *IFR;
struct ifconf ifc;
char buf[1024];
u_char addr[6];
int sk, i;
/* getit */
sk = socket(AF_INET, SOCK_DGRAM, 0);
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
ioctl(sk, SIOCGIFCONF, &ifc);
IFR = ifc.ifc_req;
for (i = ifc.ifc_len / sizeof(struct ifreq); i-- >= 0; IFR++) {
strcpy(ifr.ifr_name, IFR->ifr_name);
if (ioctl(sk, SIOCGIFFLAGS, &ifr) == 0) {
if (! (ifr.ifr_flags & IFF_LOOPBACK)) {
if (ioctl(sk, SIOCGIFHWADDR, &ifr) == 0) {
/* OK. Addr complete */
break;
}
}
}
}
close(sk);
bcopy( ifr.ifr_hwaddr.sa_data, addr, 6);
/* Output */
printf( "Out address: ");
for (i=0; i<6; i++) {
printf("%2.2x", addr[i]);
}
printf( "\n");
return 0;
}
Gruss,
demon
Danke, aber ich habe schon eine passende Lösung gefunden. Die Funktion testet, ob die übergebene MAC beim aktuellen Rechner vorhanden ist:
Code: Select all
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_arp.h>
int
test_mac (unsigned char macaddr[6])
{
struct ifreq ifRequest; // request to the interface
struct if_nameindex* ifTmp = NULL; // tmp pointer
struct if_nameindex* ifList = NULL; // list of interfaces
int fh = -1; // handle for the socket
int status = 0;
int result = -1;
// open socket
if (status == 0) {
fh = socket (PF_INET, SOCK_STREAM, 0);
if (fh < 0) {
printf ("File %s, line %d: socket () failed\n", __FILE__, __LINE__);
status = -1;
}
}
// now get a list of all interfaces
if (status == 0) {
ifList = if_nameindex ();
if (!ifList) {
printf ("File %s, line %d: if_nameindex () failed\n", __FILE__, __LINE__);
status = -1;
}
}
// get mac address of all devices
if (status == 0) {
for (ifTmp = ifList; *(char*)ifTmp != 0; ifTmp++) {
// set request for ioctl and get mac
strncpy (ifRequest.ifr_name, ifTmp->if_name, IF_NAMESIZE);
if (ioctl (fh, SIOCGIFHWADDR, &ifRequest) == -1)
// error, skip this device
continue;
if ((ifRequest.ifr_addr.sa_family != ARPHRD_ETHER) &&
(ifRequest.ifr_addr.sa_family != ARPHRD_EETHER))
// skip, no ethernet device
continue;
// test for valid mac
if ((ifRequest.ifr_ifru.ifru_hwaddr.sa_data[0] == macaddr[0]) &&
(ifRequest.ifr_ifru.ifru_hwaddr.sa_data[1] == macaddr[1]) &&
(ifRequest.ifr_ifru.ifru_hwaddr.sa_data[2] == macaddr[2]) &&
(ifRequest.ifr_ifru.ifru_hwaddr.sa_data[3] == macaddr[3]) &&
(ifRequest.ifr_ifru.ifru_hwaddr.sa_data[4] == macaddr[4]) &&
(ifRequest.ifr_ifru.ifru_hwaddr.sa_data[5] == macaddr[5])) {
// found
result = 0;
break;
}
}
}
// clean up
if (fh >= 0)
close (fh);
if (ifList)
if_freenameindex (ifList);
return result;
}
int
main ...