C言語,MACアドレスを取得し、文字列に変換する

スポンサーリンク

鍛錬 439

C言語,MACアドレスを取得し、文字列に変換する

デバイスを制御する関数である ioctl を使用して、インタフェースのMACアドレスを取得し文字列に変換します。

スポンサーリンク

プログラム

以下は、インタフェースのMACアドレスを取得して文字列に変換するプログラム、get_mac.c です。

文字列への変換は、以下のパターンに対応しています。
(下記MACアドレスはダミーです。)

文字サイズ 区切り文字 MACアドレスの例
小文字 : 00:00:5e:00:53:ff
小文字 00-00-5e-00-53-ff
大文字 : 00:00:5E:00:53:FF
大文字 00-00-5E-00-53-FF

 

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

// preprocessor
// MACアドレスの区切り文字
#define DELIMITER_COLON  ':'
#define DELIMITER_HYPHEN '-'

// MACアドレス文字列のサイズ
#define FONT_LARGE 0  // 大文字
#define FONT_SMALL 1  // 小文字

// prototype
int GetMacAddress(char *interface_name, char mac_delimiter, int font_size,
				  unsigned char *mac_address);

// main
int main(void)
{
	char interface_name[256] = "";
	unsigned char mac_address[256] = "";
	char mac_delimiter;
	int font_size;
	int ret;
	
	// インタフェース名を格納
	strncpy(interface_name, "ens33", sizeof(interface_name) - 1);
	
	// MACアドレスの区切り文字を設定
	mac_delimiter = DELIMITER_COLON;
//	mac_delimiter = DELIMITER_HYPHEN;
	
	// MACアドレスの16進数における英語表記の大文字,小文字を設定
	font_size = FONT_LARGE;
//	font_size = FONT_SMALL;
	
	// MACアドレスを取得
	ret = GetMacAddress(interface_name, mac_delimiter, font_size,
						mac_address);
	if (ret == -1) {
		printf("ERROR,GetMacAddress(),ret=%d\n", ret);
		exit(EXIT_FAILURE);
	}
	
	printf("MAC address [%s]\n", mac_address);
	
	return 0;
}

// ====================================================
// @brief      MACアドレスを取得する
// @param[in]  interface_name  インタフェース名
// @param[in]  mac_delimiter   MACアドレスの区切り文字
// @param[in]  font_size       文字列のサイズ
// @param[out] mac_address     MACアドレス
// @return     0  -> 正常
// @return     -1 -> エラー
// @note       無し
// ====================================================
int GetMacAddress(char *interface_name, char mac_delimiter, int font_size,
				  unsigned char *mac_address)
{
	unsigned char *p;
	char tmp[256] = "";
	int soc;
	int p_mac;
	int ret;
	int i;
	
	struct ifreq ifreq;
	
	// ソケット作成(UDP)
	soc = socket(AF_INET, SOCK_DGRAM, 0);
	if (soc == -1) {
		perror("socket");
		return -1;
	}
	
	// インタフェース名を格納
	strcpy(ifreq.ifr_name, interface_name);
	
	// インタフェースの存在を確認
	ret = ioctl(soc, SIOCGIFFLAGS, &ifreq);
	if (ret == -1) {
		perror("ioctl");
		close(soc);
		return -1;
	}
	
	// MACアドレスを取得
	ret = ioctl(soc, SIOCGIFHWADDR, &ifreq);
	if (ret == -1) {
		perror("ioctl");
		close(soc);
		return -1;
	}
	else {
		p = (unsigned char *)&ifreq.ifr_hwaddr.sa_data;
		
		// debug
//		printf("debug[%02X:%02X:%02X:%02X:%02X:%02X]\n",
//			   p[0],p[1],p[2],p[3],p[4],p[5]);
		
		// MACアドレスを文字列に変換
		p_mac = 0;
		for (i = 0; i < 6; i++) {
			// 大文字,小文字の判定
			switch (font_size) {
				case FONT_SMALL:
					snprintf(tmp, sizeof(tmp) - 1, "%02x", p[i]);
					break;
				case FONT_LARGE:
					snprintf(tmp, sizeof(tmp) - 1, "%02X", p[i]);
					break;
				default:
					snprintf(tmp, sizeof(tmp) - 1, "%02X", p[i]);
					break;
			}
			memcpy(&mac_address[p_mac], tmp, 2);
			p_mac = p_mac + 2;
			mac_address[p_mac] = mac_delimiter;
			p_mac++;
		}
		p_mac--;
		mac_address[p_mac] = '\0';
	}
	
	// ソケットクローズ
	ret = close(soc);
	if (ret == -1) {
		perror("close");
		return -1;
	}
	
	return 0;
}
スポンサーリンク

実行結果

以下は、ip コマンドでMACアドレスを確認後に、プログラム get_mac.c を実行してMACアドレスを取得しています。

関連記事:Linux,ipコマンドでMACアドレスを確認する方法

***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu ***** qdisc noqueue state UNKNOWN mode DEFAULT group default qlen ****
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu **** qdisc fq_codel state UP mode DEFAULT group default qlen ****
    link/ether 00:00:5e:00:53:ff brd ff:ff:ff:ff:ff:ff
***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ gcc -Wall -Wextra get_mac.c -o get_mac
***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ ./get_mac
MAC address [00:00:5E:00:53:FF]

 
上記に示した通り、インタフェース名「ens33」のMACアドレスが、ip コマンドで確認した場合とプログラム get_mac.c で取得した場合で一致しました。
(上記MACアドレスはダミーです。)

タイトルとURLをコピーしました