Як отримати MAC-адресу вашого комп'ютера за допомогою програми C?


77

Я працюю над Ubuntu. Як я можу отримати MAC-адресу своєї машини або інтерфейс, наприклад, eth0, використовуючи програму C.


Будь ласка , дивіться також пов'язаний з цим питання: stackoverflow.com/questions/4951257 / ...
— Keeely

Відповіді:


63

Вам потрібно перебрати всі доступні інтерфейси на вашій машині і використовувати ioctlз SIOCGIFHWADDRпрапором , щоб отримати адресу MAC. Мак-адресу буде отримано у вигляді двійкового масиву з 6 октетами. Ви також хочете пропустити інтерфейс зворотного зв'язку.


1
Чому для цього не потрібна структура спереду, якщо ifreq та ifconf? Чи були видалені typedefs для цих структур у більш пізніх ядрах, які існували в 2009 році, коли це було написано?
— Karl P

Я думаю, слід зазначити, що контейнери OpenVZ не мають MAC-адреси, а отже, жодне з цих рішень не буде працювати. MAC-адреса (вважається такою)00:00:00:00:00:00
— ub3rst4r

2
Це працює лише за наявності посилання на eth0. Це не працює, якщо мережевий кабель відключений (на Ubuntu).
— Florin Petriuc

5
Можливо, близько (носок)?
— Art Swri

@ArtSwri Я думаю, ти мав рацію, можливо помилка hanle перейти на LABLE і закрити (носок)
— J.Doe

136

Набагато приємніше, ніж усі ці божевілля сокетів або оболонок, просто використовувати для цього sysfs:

файл /sys/class/net/eth0/addressмістить вашу адресу mac як простий рядок, який ви можете прочитати за допомогою fopen()/ fscanf()/ fclose(). Нічого простіше, ніж це.

І якщо ви хочете підтримувати інші мережеві інтерфейси, крім eth0 (а ви, мабуть, хочете), тоді просто використовуйте opendir()/ readdir()/ closedir()on /sys/class/net/.


3
Хороша відповідь, але застосовується не у всіх ситуаціях. наприклад, вбудовані системи (особливо старі, такі як старі версії busybox, які не мають sysfs і не можуть її підтримувати, оскільки сама система може бути занадто старою)
— Алекс Маршалл,

3
Питання спеціально задавало рішення C
— Чарльз Сальвія

10
@CharlesSalvia відкриття та читання системного файлу все ще здається рішенням C ... до тих пір, поки ви знаєте, що забезпечує ваша цільова система! Звичайно, ваша програма буде прив’язана до такого типу систем. Але просто складання програми пов'язує її з архітектурою системи. Я думаю, що ця відповідь допоможе у багатьох (але не у всіх) ситуаціях.
— moodboom

(за допомогою похідного від Debian Бунзена у Wi-Fi) Див .: / sys / class / net / wlp2s0 / address
— AAAfarmclub

25

Ви хочете поглянути на сторінку керівництва getifaddrs (3) . Є приклад на мові C, який можна використати на самій сторінці. Ви хочете отримати адресу з типом AF_LINK.


2
на сторінках посилань getifaddrs тип AF_LINKне описаний. Можливо, це замінено AF_PACKET?
— mpromonet

3
За словами stackoverflow.com/a/26038501/5230867 , здається , що AF_LINK є MacOS / BSD конкретним, в той час як AF_PACKET є еквівалентом Linux.
— Манфред Урбан

20

Не забудьте перевірити помилку socket () і закрити сокет, якщо він успішно відкрився.
— Anonymouse

17

Використовуючи getifaddrs, ви можете отримати MAC-адресу від родини AF_PACKET.

Для відображення MAC-адреси на кожному інтерфейсі ви можете діяти так:

Ідеоне


11

Я просто написав один і протестував його на gentoo у virtualbox.


4

Якщо припустити, що код c ++ (c ++ 11) теж нормальний, а інтерфейс відомий.


1
  1. У Linux використовуйте службу "Менеджер мережі" над DBus.

  2. Існує також програма оболонки good'ol, яку можна викликати та захопити результат (використовуйте функцію exec під C):

$ /sbin/ifconfig | grep HWaddr


0

Дуже портативний спосіб - проаналізувати результати цієї команди.

За умови, що ifconfig можна запускати як поточний користувач (як правило, це можливо), так і awk (часто це відбувається). Це дасть вам мак-адресу машини.


4
Це зовсім не дуже портативно. Це нічого не дає на Mac OS X. Вихідні дані ifconfigне містять тексту HWaddr.
— dreamlax

Доводилося це робити на початку року на solaris, linux та hpux.
— Matt

1
Ну, концепція портативна. Текст може потребувати доопрацювання для інших платформ.
— Matt

2
Використовуючи сценарії оболонки, навіть такий маленький, як ваш, далеко не портативний. Існує жарт, згідно з яким оболонку легше
— перенести,

8
Крім того, це не збирається компілювати в жодному з відомих мені компіляторів.
— BobbyShaftoe

0

Розширення щодо відповіді, наданої @ user175104 ...


0

можливо розетку мережевого зв'язку

людина netlink(7) netlink(3) rtnetlink(7) rtnetlink(3)

Приклад


-1

Це рядок Bash, який друкує всі доступні mac-адреси, крім зворотного зв'язку:

Може виконуватися з програми C.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.