How to get mac on linux

How to get MAC address of your machine using a C program?

I am working on Ubuntu. How can I get MAC address of my machine or an interface say eth0 using C program.

12 Answers 12

Much nicer than all this socket or shell madness is simply using sysfs for this:

the file /sys/class/net/eth0/address carries your mac adress as simple string you can read with fopen() / fscanf() / fclose() . Nothing easier than that.

And if you want to support other network interfaces than eth0 (and you probably want), then simply use opendir() / readdir() / closedir() on /sys/class/net/ .

Good answer, but not applicable in all situations. e.g. embedded systems (especially older ones, such as old versions of busybox, that don’t have sysfs nor can support it because the system itself may be too old)

@CharlesSalvia opening and reading a system file still seems like a C solution. as long as you know what your target system provides! Granted, your program will be tied to that type of system. But just compiling a program ties it to a system’s architecture. I think this answer will help in many (but not all) situations.

You need to iterate over all the available interfaces on your machine, and use ioctl with SIOCGIFHWADDR flag to get the mac address. The mac address will be obtained as a 6-octet binary array. You also want to skip the loopback interface.

#include #include #include #include #include int main() < struct ifreq ifr; struct ifconf ifc; char buf[1024]; int success = 0; int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock == -1) < /* handle error*/ >; ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) < /* handle error */ >struct ifreq* it = ifc.ifc_req; const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq)); for (; it != end; ++it) < strcpy(ifr.ifr_name, it->ifr_name); if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) < if (! (ifr.ifr_flags & IFF_LOOPBACK)) < // don't count loopback if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) < success = 1; break; >> > else < /* handle error */ >> unsigned char mac_address[6]; if (success) memcpy(mac_address, ifr.ifr_hwaddr.sa_data, 6); > 

Why does this not need struct in front if ifreq and ifconf? Were typedefs for these structs removed in more recent kernels, that existed in 2009 when this was written?

I think it should be noted that OpenVZ containers do not have a MAC address and therefore, none of these solutions would work. The MAC address is (assumed to be) 00:00:00:00:00:00

It only works if there is link on eth0. It doesn’t work if the network cable is unplugged (on Ubuntu).

You want to take a look at the getifaddrs(3) manual page. There is an example in C in the manpage itself that you can use. You want to get the address with the type AF_LINK .

in the manpage of getifaddrs linked the type AF_LINK is not described. Perhaps this is superseded by AF_PACKET ?

Читайте также:  Установка принтера canon lbp 2900 linux mint

According to stackoverflow.com/a/26038501/5230867 it seems that AF_LINK is macOS/BSD-specific, while AF_PACKET is the Linux equivalent.

#include #include #include #include #include #include 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; > 

Using getifaddrs you can get MAC address from the family AF_PACKET .

In order to display the MAC address to each interface, you can proceed like this:

#include #include #include int main (int argc, const char * argv[]) < struct ifaddrs *ifaddr=NULL; struct ifaddrs *ifa = NULL; int i = 0; if (getifaddrs(&ifaddr) == -1) < perror("getifaddrs"); >else < for ( ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) < if ( (ifa->ifa_addr) && (ifa->ifa_addr->sa_family == AF_PACKET) ) < struct sockaddr_ll *s = (struct sockaddr_ll*)ifa->ifa_addr; printf("%-8s ", ifa->ifa_name); for (i=0; i sll_halen; i++) < printf("%02x%c", (s->sll_addr[i]), (i+1!=s->sll_halen)?':':'\n'); > > > freeifaddrs(ifaddr); > return 0; > 

I have just write one and test it on gentoo in virtualbox.

// get_mac.c #include //printf #include //strncpy #include #include #include //ifreq #include //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; > 

Assuming that c++ code (c++11) is okay as well and the interface is known.

#include #include #include #include using namespace std; uint64_t getIFMAC(const string &ifname) < ifstream iface("/sys/class/net/" + ifname + "/address"); string str((istreambuf_iterator(iface)), istreambuf_iterator()); if (str.length() > 0) < string hex = regex_replace(str, std::regex(":"), ""); return stoull(hex, 0, 16); >else < return 0; >> int main()
  1. On Linux, use the service of «Network Manager» over the DBus.
  2. There is also good’ol shell program which can be invoke and the result grabbed (use an exec function under C):

$ /sbin/ifconfig | grep HWaddr

A very portable way is to parse the output of this command.

Provided ifconfig can be run as the current user (usually can) and awk is installed (it often is). This will give you the mac address of the machine.

It’s not very portable at all. It gives nothing on Mac OS X. The output of ifconfig does not contain the text HWaddr .

Using shell scripts, even one as tiny as yours is far from portable. There is a joke that goes that a shell is easier to port than a shell script :p

Expanding on the answer given by @user175104 .

std::vector 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 GetAllMacAddresses() < std::vectormacs; std::string address; // from: https://stackoverflow.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 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; > 

netlink socket is possible

Читайте также:  Linux headers not found

man netlink(7) netlink(3) rtnetlink(7) rtnetlink(3)

#include #include #include #include #include #define SZ 8192 int main() < // Send typedef struct < struct nlmsghdr nh; struct ifinfomsg ifi; >Req_getlink; assert(NLMSG_LENGTH(sizeof(struct ifinfomsg))==sizeof(Req_getlink)); int fd=-1; fd=socket(AF_NETLINK,SOCK_RAW,NETLINK_ROUTE); assert(0==bind(fd,(struct sockaddr*)(&(struct sockaddr_nl)< .nl_family=AF_NETLINK, .nl_pad=0, .nl_pid=getpid(), .nl_groups=0 >),sizeof(struct sockaddr_nl))); assert(sizeof(Req_getlink)==send(fd,&(Req_getlink)< .nh=< .nlmsg_len=NLMSG_LENGTH(sizeof(struct ifinfomsg)), .nlmsg_type=RTM_GETLINK, .nlmsg_flags=NLM_F_REQUEST|NLM_F_ROOT, .nlmsg_seq=0, .nlmsg_pid=0 >, .ifi= < .ifi_family=AF_UNSPEC, // .ifi_family=AF_INET, .ifi_type=0, .ifi_index=0, .ifi_flags=0, .ifi_change=0, >>,sizeof(Req_getlink),0)); // Receive char recvbuf[SZ]=<>; int len=0; for(char *p=recvbuf;;)< const int seglen=recv(fd,p,sizeof(recvbuf)-len,0); assert(seglen>=1); len += seglen; if(((struct nlmsghdr*)p)->nlmsg_type==NLMSG_DONE||((struct nlmsghdr*)p)->nlmsg_type==NLMSG_ERROR) break; p += seglen; > struct nlmsghdr *nh=(struct nlmsghdr*)recvbuf; for(;NLMSG_OK(nh,len);nh=NLMSG_NEXT(nh,len))< if(nh->nlmsg_type==NLMSG_DONE) break; struct ifinfomsg *ifm=(struct ifinfomsg*)NLMSG_DATA(nh); printf("#%d ",ifm->ifi_index); #ifdef _NET_IF_H #pragma GCC error "include instead of " #endif // Part 3 rtattr struct rtattr *rta=IFLA_RTA(ifm); // /usr/include/linux/if_link.h int rtl=RTM_PAYLOAD(nh); for(;RTA_OK(rta,rtl);rta=RTA_NEXT(rta,rtl))switch(rta->rta_type) < case IFLA_IFNAME:printf("%s ",(const char*)RTA_DATA(rta));break; case IFLA_ADDRESS: printf("hwaddr "); for(int i=0;i<5;++i) printf("%02X:",*((unsigned char*)RTA_DATA(rta)+i)); printf("%02X ",*((unsigned char*)RTA_DATA(rta)+5)); break; case IFLA_BROADCAST: printf("bcast "); for(int i=0;i<5;++i) printf("%02X:",*((unsigned char*)RTA_DATA(rta)+i)); printf("%02X ",*((unsigned char*)RTA_DATA(rta)+5)); break; case IFLA_PERM_ADDRESS: printf("perm "); for(int i=0;i<5;++i) printf("%02X:",*((unsigned char*)RTA_DATA(rta)+i)); printf("%02X ",*((unsigned char*)RTA_DATA(rta)+5)); break; >printf("\n"); > close(fd); fd=-1; return 0; > 
#1 lo hwaddr 00:00:00:00:00:00 bcast 00:00:00:00:00:00 #2 eth0 hwaddr 57:da:52:45:5b:1a bcast ff:ff:ff:ff:ff:ff perm 57:da:52:45:5b:1a #3 wlan0 hwaddr 3c:7f:46:47:58:c2 bcast ff:ff:ff:ff:ff:ff perm 3c:7f:46:47:58:c2 

Источник

How to Find Network MAC Address in Linux System

The term MAC Address is a derived abbreviation for Media Access Control Address. The network interface controller (NIC) uses the MAC address as its assigned unique identifier within an existing network segment.

To practically relate to or understand what a MAC address is, think of it as the postal or physical address to a house. The house in this case is the network interface controller (NIC).

There is a key difference between MAC address and IP address and therefore we should not confuse the two. MAC address identifies the device you are using since it is imprinted on the device hardware whereas IP address identifies the connection status among devices seeking to communicate on an existing/configured network.

The MAC address of any device is represented by a 12-digit hexadecimal number. Its display includes a colon or hyphen after every two MAC address digits for easy readability.

For instance, a MAC address can be represented in the following manner.

aa:bb:cc:dd:ee:ff or gg-hh-ii-jj-kk-ll

Approaches to Finding MAC Address in Linux

Depending on the number of network interfaces on your Linux machine like Wi-Fi built-in and Ethernet port, your computer can be associated with more than one MAC Address.

1. Find Linux System Mac Address Using IP Command

The ip command is part of the iproute2 package and can be used to display both the MAC address and IP address of your Linux-powered machine using either of the following commands.

$ ip addr or $ ip address or $ ip address show

Find Linux System MAC Address

Depending on the network adapter or interface present, we can see the availed MAC addresses. In the above screen capture, three distinct MAC addresses can be identified from the ip address command.

Another useful command is the ip link which only focuses on the MAC address and does not display the IP addresses.

Show Linux System MAC Address

2. Find Linux System Mac Address Using Ifconfig Command

The ifconfig command is another effective approach to identifying the MAC address of your Linux machine. We however need to install it first since it is a member of the net-tools package and not installed on Linux by default.

$ sudo apt install net-tools [On Debian, Ubuntu and Mint] $ sudo yum install net-tools [On RHEL/CentOS/Fedora and Rocky Linux/AlmaLinux] $ sudo emerge -a sys-apps/net-tools [On Gentoo Linux] $ sudo pacman -S net-tools [On Arch Linux] $ sudo zypper install net-tools [On OpenSUSE]

Once installed, run the ifconfig command to find the IP address and MAC address of your Linux system.

Check Linux System MAC Address

Different network interfaces or adapters showcase different MAC addresses as highlighted in the above screen capture.

We have successfully defined and understood how to get the MAC address(es) on our Linux machines.

Источник

Как узнать MAC-адрес в Linux

В те времена, когда только проектировался Ethernet, предусматривалось применение уникального номера каждой сетевой карте, подключённой к нему. Назначался он при изготовлении платы. MAC-адрес используется для определения получателя и отправителя информации в Сети. И в этой статье речь пойдёт о том, как узнать MAC адрес в Linux.

Практически во всех операционных системах на основе ядра Linux используется две консольные утилиты, с помощью которых можно узнать аппаратный адрес карты: ifconfig и ip. Различные графические приложения этого типа используют их данные.

Как узнать MAC-адрес с помощью ifconfig

Одной из первых сетевых программ в истории Linux является ifconfig. В некоторых дистрибутивах она запускается только от имени администратора, а где-то вообще не установлена. Рассмотрим её инсталляцию и использование в Manjaro Linux.

Пакет, содержащий в себе некоторые сетевые утилиты (в том числе и ifconfig), в Manjaro- и Arch-подобных системах называется net-tools. Установим его.

А в Ubuntu- и Debian-подобных системах:

sudo apt install net-tools

Чтобы узнать MAC-адрес Linux, сначала смотрим список интерфейсов:

ifconfig -a

Доступных интерфейсов два: enp0s7 (в вашем случае он может называться по другому) и lo (он же локальный хост, который одинаков практически для всех компьютеров). Нам нужен enp0s7.

MAC-адрес устройства виден уже сейчас в поле ether, но чтобы отобразить только его, воспользуемся такой командой:

ifconfig -a | grep ether | gawk »

MAC

Здесь grep принимает на вход то, что вывела команда ifconfig -a, находит строку, где есть ether, и передаёт на вход команде gawk, которая выбирает второе слово в принятой строке.

Как посмотреть MAC-адрес с помощью ip

Более новой в системах GNU/Linux (относительно ifconfig) является программа ip. Её принцип работы практически такой же. Отличается синтаксисом и выводимой информацией. И она установлена по умолчанию для всех систем. Для отображения сетевых интерфейсов нужно ввести команду:

ip -a

Здесь lo и enp0s7 расположены в обратном порядке.

Чтобы узнать MAC адрес сетевой карты Linux, вводим ту же самую конструкцию, только для этой команды:

ip MAC

Выводы

За то, как узнать MAC адрес в Linux, отвечают две консольные утилиты — ifconfig и ip. Первая может запускаться от имени администратора в некоторых дистрибутивах (например в Debian), а где-то вообще не быть установленной (Manjaro). Это связано с её отходом на второй план, поскольку ip является более новой программой и устанавливается по умолчанию во всех системах.

Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.

Источник

Оцените статью
Adblock
detector