첫번째로 검색되는 NIC의 MAC 주소를 출력하는 코드(AF_INET이 아니거나 looback이면 skip)
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <net/if.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stropts.h>
#include <netinet/in.h>
#ifdef OS_LINUX
#include <linux/sockios.h>
#endif
#ifdef OS_SOLARIS
#include <sys/sockio.h>
#endif
#define MAX_NIC 10
char *
get_mac_addr(void)
{
int i, fd;
int numif;
char raw_mac[6];
static char mac[18];
struct ifconf ifc;
struct ifreq ifr[MAX_NIC];
struct ifreq ifreq;
struct in_addr addr;
ifc.ifc_len = sizeof(ifr);
ifc.ifc_req = ifr;
/* dummy socket 생성 */
if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
return NULL;
}
/* 모든 NIC의 정보를 가져옴 */
if(ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
close(fd);
return NULL;
}
numif = ifc.ifc_len / sizeof(struct ifreq);
for(i = 0; i < numif; i++) {
/* NIC이 AF_INET 패밀리가 아니면 skip */
if(ifc.ifc_req[i].ifr_addr.sa_family != AF_INET) {
continue;
}
/* loopback이면 skip */
addr = ((struct sockaddr_in *) &ifc.ifc_req[i].ifr_addr)->sin_addr;
if(addr.s_addr == htonl(0x7f000001)) {
continue;
}
/* MAC 주소 가져옴(어떤 NIC에서 가져올지 지정하기 위해 검색된 NIC 정보를 ifreq 버퍼에 넣어서 ioctl 실행)*/
memcpy(&ifreq, &ifc.ifc_req[i], sizeof(ifreq));
if(ioctl(fd, SIOCGIFHWADDR, &ifreq) < 0) {
close(fd);
return NULL;
}
/* MAC 출력 형식으로 변경 */
memcpy(raw_mac, &ifreq.ifr_hwaddr.sa_data, 6);
sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", raw_mac[0] & 0xff, raw_mac[1] & 0xff, raw_mac[2] & 0xff, raw_mac[3] & 0xff, raw_mac[4] & 0xff, raw_mac[5] & 0xff);
close(fd);
return mac;
}
close(fd);
return NULL;
}
int
main(void)
{
printf("%s\n", get_mac_addr());
return 0;
}
<컴파일 방법>
1. 리눅스
# gcc -Wall -g -DOS_LINUX -o get_mac get_mac.c
2. 솔라리스
# gcc -Wall -g -DOS_SOLARIS -o get_mac get_mac.c

comments
comments rss (+댓글 쓰러가기)