日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

Linux下获取CPUID、硬盘序列号与MAC地址

發(fā)布時(shí)間:2025/3/15 linux 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux下获取CPUID、硬盘序列号与MAC地址 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

ioctl系統(tǒng)調(diào)用,具體的調(diào)用方法,請(qǐng)查看手冊(cè)頁(yè)

獲取CPUID

按照網(wǎng)上提供的說(shuō)明,CPUID并不是所有的Intel CPU都支持的。如果支持,匯編調(diào)用為:eax置0000_0003,調(diào)用cpuid。

以下為實(shí)現(xiàn)代碼(在我的CPU上,并沒(méi)有得到):

#define cpuid(in,a,b,c,d) asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));

static int

getcpuid (char *id, size_t max)

{

int i;

unsigned long li, maxi, maxei, ebx, ecx, edx, unused;

cpuid (0, maxi, unused, unused, unused);

maxi &= 0xffff;

if (maxi < 3)

{

return -1;

}

cpuid (3, eax, ebx, ecx, edx);

snprintf (id, max, "%08lx %08lx %08lx %08lx", eax, ebx, ecx, edx);

fprintf (stdout, "get cpu id: %s\n", id);

return 0;

}

獲取硬盤(pán)序列號(hào)

這個(gè)的實(shí)現(xiàn),采用的是讀取/etc/mtab文件,找到/(即根目錄)掛載的設(shè)備文件,然后打開(kāi)它,再用系統(tǒng)調(diào)用ioctl來(lái)實(shí)現(xiàn)的。

ioctl第二個(gè)參數(shù)為HDIO_GET_IDENTITY, 獲得指定文件描述符的標(biāo)志號(hào)

ioctl的第三個(gè)參數(shù)為struct hd_driveid ,在linux/hdreg.h中,struct hd_driveid的聲明有

struct hd_driveid {

unsigned short config; / lots of obsolete bit flags */

unsigned short cyls; /* Obsolete, "physical" cyls */

unsigned short reserved2; /* reserved (word 2) */

unsigned short heads; /* Obsolete, "physical" heads */

unsigned short track_bytes; /* unformatted bytes per track */

unsigned short sector_bytes; /* unformatted bytes per sector */

unsigned short sectors; /* Obsolete, "physical" sectors per track */

unsigned short vendor0; /* vendor unique */

unsigned short vendor1; /* vendor unique */

unsigned short vendor2; /* Retired vendor unique */

unsigned char serial_no[20]; /* 0 = not_specified */

unsigned short buf_type; /* Retired */

unsigned short buf_size; /* Retired, 512 byte increments

* 0 = not_specified

*/

……

};

,這其中,serial_no為硬盤(pán)的序列號(hào)。如果此項(xiàng)為0,則為沒(méi)有提供。

思路明確了,以下為實(shí)現(xiàn)代碼:

static int

getdiskid (char *id, size_t max)

{

int fd;

struct hd_driveid hid;

FILE *fp;

char line[0x100], *disk, *root, *p;

fp = fopen ("/etc/mtab", "r");

if (fp == NULL)

{

fprintf (stderr, "No /etc/mtab file.\n");

return -1;

}

fd = -1;

while (fgets (line, sizeof line, fp) != NULL)

{

disk = strtok (line, " ");

if (disk == NULL)

{

continue;

}

root = strtok (NULL, " ");

if (root == NULL)

{

continue;

}

if (strcmp (root, "/") == 0)

{

for (p = disk + strlen (disk) - 1; isdigit (*p); p --)

{

*p = '\0';

}

fd = open (disk, O_RDONLY);

break;

}

}

fclose (fp);

if (fd < 0)

{

fprintf (stderr, "open hard disk device failed.\n");

return -1;

}

if (ioctl (fd, HDIO_GET_IDENTITY, &hid) < 0)

{

fprintf (stderr, "ioctl error.\n");

return -1;

}

close (fd);

snprintf (id, max, "%s", hid.serial_no);

fprintf (stdout, "get hard disk serial number: %s\n", id);

return 0;

}

獲取MAC地址

通過(guò)創(chuàng)建一個(gè)socket,然后bind特定的IP地址,就可以通過(guò)ioctl得到這個(gè)套按地綁定的網(wǎng)絡(luò)接口名稱(chēng)。然后再通過(guò)網(wǎng)絡(luò)接口名稱(chēng),得到MAC地址。

如果ioctl的第二個(gè)參數(shù)為SIOCGIFNAME, 則獲得指定網(wǎng)絡(luò)接口的名稱(chēng);如果ioctl的第二個(gè)參數(shù)為SIOCGIFHWADDR,則獲得指定網(wǎng)絡(luò)接口的MAC地址

ioctl的第三個(gè)參數(shù)為struct ifreq ,在linux/if.h頭文件里,struct ifreq聲明如下:

struct ifreq

{

#define IFHWADDRLEN 6

union

{

char ifrn_name[IFNAMSIZ]; / if name, e.g. "en0" */

} ifr_ifrn;

union {

struct sockaddr ifru_addr;

struct sockaddr ifru_dstaddr;

struct sockaddr ifru_broadaddr;

struct sockaddr ifru_netmask;

struct sockaddr ifru_hwaddr;

short ifru_flags;

int ifru_ivalue;

int ifru_mtu;

struct ifmap ifru_map;

char ifru_slave[IFNAMSIZ]; /* Just fits the size */

char ifru_newname[IFNAMSIZ];

void * ifru_data;

struct if_settings ifru_settings;

} ifr_ifru;

}

?

其中,ifrn_name為網(wǎng)絡(luò)接口的名稱(chēng),ifr_ifru.ifru_hwaddr為網(wǎng)絡(luò)接口的MAC地址。

#ifndef MAX_IFINDEX

# define MAX_IFINDEX 8

#endif

static int

getmacaddr (const char *ip, char *id, size_t max)

{

int i, sockfd;

struct sockaddr_in *loc;

struct ifreq req[1];

sockfd = socket (AF_INET, SOCK_DGRAM, 0);

if (sockfd < 0)

{

fprintf (stderr, "Unable to create socket.\n");

return -1;

}

for (i = 0; i <= MAX_IFINDEX; ++ i)

{

req->ifr_ifindex = i;

if (ioctl (sockfd, SIOCGIFNAME, req) < 0)

{

fprintf (stderr, "ioctl error: %s\n", strerror (errno));

continue;

}

if (ioctl (sockfd, SIOCGIFADDR, req) < 0)

{

fprintf (stderr, "ioctl interface index [%d] error: %s\n", i, strerror (errno));

continue;

}

loc = (struct sockaddr_in *) (&(req->ifr_ifru.ifru_addr));

if (loc->sin_addr.s_addr == inet_addr (ip))

{

fprintf (stderr, "%s bind at %s.\n", ip, req->ifr_name);

break;

}

}

if (i > MAX_IFINDEX)

{

fprintf (stderr, "input IP error.\n");

close (sockfd);

return -1;

}

if (ioctl (sockfd, SIOCGIFHWADDR, req) < 0)

{

fprintf (stderr, "ioctl error: %s\n", strerror (errno));

close (sockfd);

return -1;

}

close (sockfd);

snprintf (id, max, "%02X%02X%02X%02X%02X%02X",

req->ifr_hwaddr.sa_data[0] & 0xff,

req->ifr_hwaddr.sa_data[1] & 0xff,

req->ifr_hwaddr.sa_data[2] & 0xff,

req->ifr_hwaddr.sa_data[3] & 0xff,

req->ifr_hwaddr.sa_data[4] & 0xff,

req->ifr_hwaddr.sa_data[5] & 0xff);

fprintf (stdout, "MAC address of %s: [%s].\n", req->ifr_name, id);

return 0;

}

轉(zhuǎn)載于:https://www.cnblogs.com/RichardLee/archive/2013/01/16/2862347.html

總結(jié)

以上是生活随笔為你收集整理的Linux下获取CPUID、硬盘序列号与MAC地址的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。