Доброго времени...Кто знает, как в FreeBSD программно определить MAC-адрес интерфейса(ов) компьютера. Может быть очень простой вопрос, но я так и не могу понять, как это сделать. Под линукс есть запрос через ioctl для этого, но во Фре не нашёл ничего подобного.
Заранее благодарен.
>Доброго времени...
>
>Кто знает, как в FreeBSD программно определить MAC-адрес интерфейса(ов) компьютера. Может быть
>очень простой вопрос, но я так и не могу понять, как
>это сделать. Под линукс есть запрос через ioctl для этого, но
>во Фре не нашёл ничего подобного.
>
>Заранее благодарен.ifconfig fxp0 |grep ether|awk '{print $2}'
>>Под линукс есть запрос через ioctl для этого, но
>>во Фре не нашёл ничего подобного.
>>
>>Заранее благодарен.
>
>ifconfig fxp0 |grep ether|awk '{print $2}'В крайнем случае, можно посмотреть исходник местного ifconfig.
>>ifconfig fxp0 |grep ether|awk '{print $2}'Спасибо за ответ, так я и сделал пока :). Оно конечно работает, но должны ж быть какие-то возможности через API это сделать.
>В крайнем случае, можно посмотреть исходник местного ifconfig.
Там смотрел. Код не простой для меня. Разбираю потихоньку, но думал, может кто уже делал...
Если пойму - выложу код.
>но должны ж быть какие-то возможности через API это сделать.Скачай http://www.unpbook.com/unpv13e.tar.gz и посмотри на примеры
lib/get_ifi_info.c (используется ioctl)
и
route/get_ifi_info.c (используется sysctl, фактически код в libroute/*.c)
>Кто знает, как в FreeBSD программно определить MAC-адрес интерфейса(ов) компьютера. Может быть
>очень простой вопрос, но я так и не могу понять, как
>это сделать. Под линукс есть запрос через ioctl для этого, но
>во Фре не нашёл ничего подобного.Исходники ifconfig посмотри + man netintro.
Что-то рядом с man getifaddrs
Спасибо всем за ответы.Действительно, есть функция getifaddrs, возвращающая все адреса (и МАКи) для всех интерфейсов. И как я понимаю, она использует всё тот-же ioctl с запросом SIOCGIFADDR (или что-то вроде).
Кому нужно, вот пример:
#include <sys/types.h> // библиотека различных "макротипов"
#include <sys/socket.h> // библиотека для работы с сокетами
#include <net/if_dl.h> // библиотека для работы с Link Layer адресами
#include <ifaddrs.h> // библиотека для работы с адресами интерфейсов
#include <string.h> // библиотека работы со строками/* Функция получения MAC-адреса, возвращает структуру типа ether_addr (ethernet.h)*/
struct ether_addr *GetMyMAC(
char *ifname // входной параметр - имя интерфейса
){
struct ifaddrs *ifa, *ifap; // структуры (ifaddrs.h) для получения адресов интерфейсов
struct sockaddr_dl *sdl; // структура (if_dl.h) содержит MAC-адресс (и не только)/* получение всех адресов (Ethernet, IP, IP6 ... ) всех интерфейсов */
if(getifaddrs(&ifap)<0 ) return (NULL);
for(ifa = ifap; ifa; ifa = ifa->ifa_next){
/* поиск нужного интерфейса и адреса */
if( (ifa->ifa_addr->sa_family != AF_LINK) || // поиск по типу адреса Link Layer
(strcmp(ifa->ifa_name,ifname) != 0) ) { // поиск по имени интерфейса
continue;
}
freeifaddrs(ifap); // очистка памяти - необязательно
return (struct ether_addr *)
(LLADDR((struct sockaddr_dl *)ifa->ifa_addr)); // возврат MAC-адресa
}
freeifaddrs(ifap); // очистка памяти
return(NULL); // возврат ошибки
}int main(){
struct ether_addr *MAC = GetMyMAC("bge0");
if(MAC != NULL) printf("My MAC is %s\n", ether_ntoa(MAC));
else printf("Can't get MAC\n");
}
>
>Кому нужно, вот пример:
>
> freeifaddrs(ifap); // очистка памяти - необязательно
> return (struct ether_addr *)...Во-первых, таки обязательно. Кто же еще очистит?
Во-вторых, после этого к освобожденной памяти нельзя обращаться, а ты не просто обращаешься, а и возвращаешь указатель на структуру внутри нее.