Як отримати 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.