리눅스 네트워크 프로그래밍 - 네트워크 인터페이스 MAC 주소 확인하기

반응형

본 글에서는 리눅스 시스템의 네트워크 인터페이스에 할당되어 있는 MAC 주소를 확인하는 프로그램을 작성하는 방법에 대해 설명한다. 

 

프로그램 상에서 네트워크 인터페이스의 MAC 주소를 확인하는 기본 절차는 다음과 같다.

 

  • socket() 함수로 네트워크 인터페이스에 대한 소켓 파일 디스크립터를 연다.
  • struct ifreq 구조체 변수에 확인할 네트워크 인터페이스의 이름(예: eth0)을 저장한다.
  • ioctl() 함수의 SIOCGIFHWADDR 명령을 통해 네트워크 인터페이스의 MAC 주소를 읽는다.

 

다음은 C 언어로 작성된 예제 프로그램의 소스 코드이다.

#include <net/if.h>
#include <net/if_arp.h>
#include <sys/ioctl.h> 
#include <sys/socket.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>


/// MAC 주소 길이
#define MAC_ALEN 6

/// MAC 주소 출력 매크로
#define MAC_ADDR_FMT "%02X:%02X:%02X:%02X:%02X:%02X" 
#define MAC_ADDR_FMT_ARGS(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]


/**
 * @brief 네트워크 인터페이스의 MAC 주소를 확인한다.
 *
 * @param[in] ifname        네트워크 인터페이스 이름
 * @param[in] mac_addr      MAC 주소가 저장될 버퍼 (6바이트 길이)
 * 
 * @retval  0: 성공
 * @retval  -1: 실패
 */
int GetInterfaceMacAddress(const char *ifname, uint8_t *mac_addr)
{
  struct ifreq ifr;
  int sockfd, ret;

  printf("Get interface(%s) MAC address\n", ifname);

  /*
   * 네트워크 인터페이스 소켓을 연다.
   */
  sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  if(sockfd < 0) {
    printf("Fail to get interface MAC address - socket() failed - %m\n");
    return -1;
  }

  /*
   * 네트워크 인터페이스의 MAC 주소를 확인한다.
   */
  strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
  ret = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
  if (ret < 0) {
    printf("Fail to get interface MAC address - ioctl(SIOCSIFHWADDR) failed - %m\n");
    close(sockfd);
    return -1;
  }
  memcpy(mac_addr, ifr.ifr_hwaddr.sa_data, MAC_ALEN);

  /*
   * 네트워크 인터페이스 소켓을 닫는다.
   */
  close(sockfd);

  printf("Success to get interface(%s) MAC address as "MAC_ADDR_FMT"\n", ifname, MAC_ADDR_FMT_ARGS(mac_addr));
  return 0;
}


/**
 * 테스트 어플리케이션
 */ 
int main(int argc, char *argv[])
{
  const char *ifname = "eth0";
  uint8_t mac_addr[MAC_ALEN];

  return GetInterfaceMacAddress(ifname, mac_addr);
}

 

 

 

위 코드를 빌드 후 실행하면 다음과 같이 eth0 인터페이스의 MAC 주소를 확인할 수 있다.

참고로 위 프로그램은 네트워크 디바이스에 접근하므로 관리자 권한으로 실행되어야 한다.
예를 들어, 도커 컨테이너는 privileged 모드로 실행되어야 한다.
root@e2c40a2260ab:/workspace# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:15 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1186 (1.1 KB)  TX bytes:0 (0.0 B)

root@e2c40a2260ab:/workspace#
root@e2c40a2260ab:/workspace# ./GetInterfaceMacAddress
Get interface(eth0) MAC address
Success to get interface(eth0) MAC address as 02:42:AC:11:00:02
root@e2c40a2260ab:/workspace#

 

파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음

 

댓글

Designed by JB FACTORY