當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > Linux 中使用ioctl函數(shù)獲得Mac地址
Linux中的ioctl函數(shù)是與內(nèi)核交互的一種方法, 在驅(qū)動和網(wǎng)絡(luò)中的使用都非常的廣泛。
ioctl函數(shù)在網(wǎng)絡(luò)編程中有相當(dāng)多的選項,下邊我們就利用ioctl函數(shù)來獲得當(dāng)前系統(tǒng)中物理網(wǎng)卡的地址。
首先看一下ioctl函數(shù)的原型:
int ioctl(int d, int request, ...);
參數(shù):d, 表示要操作的文件描述符
request, 表示ioctl函數(shù)的操作選項,不同的選項具有不同的功能。
第三參數(shù),是一個void*的指針類型,要根據(jù)request參數(shù)來決定。
通過ioctl_list可以查看當(dāng)前ioctl函數(shù)在網(wǎng)絡(luò)中的常用選項,其中SIOCGIFHWADDR 選項用于獲得物理網(wǎng)卡的地址,并且第三個參數(shù)是struct ifreq的指針類型。
要想獲得物理網(wǎng)卡的地址,需要對struct ifreq的結(jié)構(gòu)體成員賦值,其中包括對ifreq.ifr_ifrn.ifrn_name成員賦值為要獲得那塊網(wǎng)卡的的名字,比如:strcpy(req.ifr_ifrn.ifrn_name, "eth0"),表示要獲得eth0的地址。當(dāng)執(zhí)行完ioctl函數(shù)之后,網(wǎng)卡的地址就會保存在ifreq.ifr_ifru.ifru_hwaddr.sa_data成員中,我們只需將得到的值進(jìn)行轉(zhuǎn)換即可。
代碼示例:
int main(int argc, const char *argv[])
{
int sockfd;
struct ifreq req;
char buf[32] = {0};
int i = 0;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("fail to create socket ..!");
exit(1);
}
strcpy(req.ifr_ifrn.ifrn_name, "eth0");
/* *獲得eth0的MAC地址 */
if (ioctl(sockfd, SIOCGIFHWADDR, &req) < 0) {
perror("fail to ioctl ");
close(sockfd);
exit(1);
}
close(sockfd);
memcpy(buf, req.ifr_ifru.ifru_hwaddr.sa_data, 6);
//strncpy(buf, req.ifr_ifru.ifru_hwaddr.sa_data, 6);
/* *按照xx:xx:xx:xx:xx:xx的格式顯示 */
for (i = 0; i < 6; i++)
printf("%02x:", buf[i] & 0xff);
puts("\b ");///后輸出不帶":"
return 0;
}