본문 바로가기
IT/programming

[C/C++] C언어 MAC 주소 읽기 구현, get mac address

by 어느해겨울 2022. 1. 16.

C언어 MAC 주소 읽기 구현

MAC 주소를 얻는 소스 코드를 구현한다.

네트워크 관련 처리를 하다보면 MAC 주소가 필요한 경우가 자주 발생한다.

이 역시 shell 명령을 통해 MAC 주소를 얻는거보다 소스코드로 구현하는게 깔끔하고 빠르다.

 


소스코드

이 역시 C언어로 변경하여 사용할 수 있다. 단지 return type을 string으로 받고 싶어 cpp로 했을 뿐. 

C언어 타입으로 변경하려면 cpp 요소만 제거하여 사용하자.

* 이더넷 인터페이스가 많은 경우 count_if 항목에서 req->ifr_name 의 인터페이스명을 보고 판단하여 mac 주소를 획득하면 된다. 물론 한번에 다 얻을 수 도 있으니 활용하자.

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <netinet/ether.h>
#include <net/if.h>
#include <sys/ioctl.h>

#include <string>

using namespace std;

string get_mac_address(void) {
    int socket_fd;
    int count_if;

    struct ifreq  *t_if_req;
    struct ifconf  t_if_conf;

    char arr_mac_addr[17] = {0x00, };

    memset(&t_if_conf, 0, sizeof(t_if_conf));

    t_if_conf.ifc_ifcu.ifcu_req = NULL;
    t_if_conf.ifc_len = 0;

    if( (socket_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0 ) {
        return "";
    }

    if( ioctl(socket_fd, SIOCGIFCONF, &t_if_conf) < 0 ) {
        return "";
    }

    if( (t_if_req = (ifreq *)malloc(t_if_conf.ifc_len)) == NULL ) {
        close(socket_fd);
        free(t_if_req);
        return "";

    } else {
        t_if_conf.ifc_ifcu.ifcu_req = t_if_req;
        if( ioctl(socket_fd, SIOCGIFCONF, &t_if_conf) < 0 ) {
            close(socket_fd);
            free(t_if_req);
            return "";
        }

        count_if = t_if_conf.ifc_len / sizeof(struct ifreq);
        for( int idx = 0; idx < count_if; idx++ ) {
            struct ifreq *req = &t_if_req[idx];

            if( !strcmp(req->ifr_name, "lo") ) {
                continue;
            }

            if( ioctl(socket_fd, SIOCGIFHWADDR, req) < 0 ) {
                break;
            }

            sprintf(arr_mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x",
                    (unsigned char)req->ifr_hwaddr.sa_data[0],
                    (unsigned char)req->ifr_hwaddr.sa_data[1],
                    (unsigned char)req->ifr_hwaddr.sa_data[2],
                    (unsigned char)req->ifr_hwaddr.sa_data[3],
                    (unsigned char)req->ifr_hwaddr.sa_data[4],
                    (unsigned char)req->ifr_hwaddr.sa_data[5]);
            break;
        }
    }

    close(socket_fd);
    free(t_if_req);

    return arr_mac_addr;
}


int main(int _argc, char *_argv[]) {
    printf("MAC address : [%s]\n", get_mac_address().c_str());

    return 0;
}

 

컴파일 및 결과

muabow@muabow:~/dev/cpp_file$ g++ -o mac_addr mac_addr.cpp ; ./mac_addr
MAC address : [XX:XX:XX:e3:f5:d3]

MAC 주소의 앞 3자리는 XX로 감췄다. 어쨌든 잘 나오는 것을 확인 할 수 있다.

 

끝.

 

 

댓글