리눅스 네트워크 프로그래밍 - 네트워크 인터페이스 MAC 주소 확인하기
- 프로그래밍/리눅스 프로그래밍
- 2020. 2. 15.
반응형
본 글에서는 리눅스 시스템의 네트워크 인터페이스에 할당되어 있는 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#
파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음
'프로그래밍 > 리눅스 프로그래밍' 카테고리의 다른 글
리눅스 네트워크 프로그래밍 - CAN(Controller Area Network) 통신 (2) | 2020.04.27 |
---|---|
리눅스 네트워크 프로그래밍 - UDP6(UDP over IPv6) 송수신 (0) | 2020.03.04 |
리눅스 네트워크 프로그래밍 - 네트워크 인터페이스 비활성화하기 (0) | 2020.02.16 |
리눅스 네트워크 프로그래밍 - 네트워크 인터페이스 활성화하기 (0) | 2020.02.15 |
리눅스 네트워크 프로그래밍 - 네트워크 인터페이스 MAC 주소 설정하기 (0) | 2020.02.15 |
리눅스 네트워크 프로그래밍 - inet_ntop() : IPv6 주소를 문자열로 변환 (0) | 2020.02.12 |
리눅스 네트워크 프로그래밍 - 네트워크 인터페이스 IPv6 주소 설정하기 (0) | 2020.02.09 |
리눅스 네트워크 프로그래밍 - 네트워크 인터페이스 IPv6 주소 확인하기 (0) | 2020.02.08 |