übersicht - Wie bekomme ich die MAC-Adresse Ihrer Maschine mit einem C-Programm?




title tag definition (7)

Ich arbeite an Ubuntu. Wie kann ich die MAC-Adresse meiner Maschine oder einer Schnittstelle sagen eth0 mit C-Programm.

https://code.i-harness.com


  1. Unter Linux verwenden Sie den Dienst "Network Manager" über den DBus.

  2. Es gibt auch ein good'ol Shell-Programm, das aufgerufen und das Ergebnis abgerufen werden kann (verwenden Sie eine Exec- Funktion unter C):

$ /sbin/ifconfig | grep HWaddr


Angenommen, dass C ++ - Code (C ++ 11) ebenfalls in Ordnung ist und die Schnittstelle bekannt ist.

#include <cstdint>
#include <fstream>
#include <streambuf>
#include <regex>

using namespace std;

uint64_t getIFMAC(const string &ifname) {
  ifstream iface("/sys/class/net/"+ifname+"/address");
  string str((istreambuf_iterator<char>(iface)), istreambuf_iterator<char>());
  string hex = regex_replace(str, std::regex(":"), "");
  return stoull(hex, 0, 16);
}
int main()
{
  string iface="eth0";
  printf("%s: mac=%016lX\n", iface.c_str(), getIFMAC(iface));
}

Erweiterung der Antwort von @ user175104 ...

std::vector<std::string> GetAllFiles(const std::string& folder, bool recursive = false)
{
  // uses opendir, readdir, and struct dirent.
  // left as an exercise to the reader, as it isn't the point of this OP and answer.
}

bool ReadFileContents(const std::string& folder, const std::string& fname, std::string& contents)
{
  // uses ifstream to read entire contents
  // left as an exercise to the reader, as it isn't the point of this OP and answer.
}

std::vector<std::string> GetAllMacAddresses()
{
  std::vector<std::string> macs;
  std::string address;

  // from: https://.com/questions/9034575/c-c-linux-mac-address-of-all-interfaces
  //  ... just read /sys/class/net/eth0/address

  // NOTE: there may be more than one: /sys/class/net/*/address
  //  (1) so walk /sys/class/net/* to find the names to read the address of.

  std::vector<std::string> nets = GetAllFiles("/sys/class/net/", false);
  for (auto it = nets.begin(); it != nets.end(); ++it)
  {
    // we don't care about the local loopback interface
    if (0 == strcmp((*it).substr(-3).c_str(), "/lo"))
      continue;
    address.clear();
    if (ReadFileContents(*it, "address", address))
    {
      if (!address.empty())
      {
        macs.push_back(address);
      }
    }
  }
  return macs;
}

Ich habe gerade einen geschrieben und es auf gentoo in der virtualbox getestet.

// get_mac.c
#include <stdio.h>    //printf
#include <string.h>   //strncpy
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>   //ifreq
#include <unistd.h>   //close

int main()
{
    int fd;
    struct ifreq ifr;
    char *iface = "enp0s3";
    unsigned char *mac = NULL;

    memset(&ifr, 0, sizeof(ifr));

    fd = socket(AF_INET, SOCK_DGRAM, 0);

    ifr.ifr_addr.sa_family = AF_INET;
    strncpy(ifr.ifr_name , iface , IFNAMSIZ-1);

    if (0 == ioctl(fd, SIOCGIFHWADDR, &ifr)) {
        mac = (unsigned char *)ifr.ifr_hwaddr.sa_data;

        //display mac address
        printf("Mac : %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n" , mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    }

    close(fd);

    return 0;
}

Sie möchten sich die Handbuchseite von getifaddrs(3) ansehen. In der Manpage selbst gibt es ein Beispiel in C, das Sie verwenden können. Sie möchten die Adresse mit dem Typ AF_LINK .


Viel schöner als all diese Sockel- oder Shell-Wahnsinn ist einfach sysfs dafür zu verwenden:

Die Datei /sys/class/net/eth0/address trägt Ihre mac-Adresse als einfache Zeichenfolge, die Sie mit fopen() / fscanf() / fclose() lesen können. Nichts einfacher als das.

Und wenn Sie andere Netzwerkschnittstellen als eth0 unterstützen möchten (und Sie wahrscheinlich wollen), dann verwenden Sie einfach opendir() / readdir() / closedir() auf /sys/class/net/ .


#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>

int main()
{
  struct ifreq s;
  int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);

  strcpy(s.ifr_name, "eth0");
  if (0 == ioctl(fd, SIOCGIFHWADDR, &s)) {
    int i;
    for (i = 0; i < 6; ++i)
      printf(" %02x", (unsigned char) s.ifr_addr.sa_data[i]);
    puts("\n");
    return 0;
  }
  return 1;
}




mac-address