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

上传人:scccc 文档编号:12976705 上传时间:2021-12-09 格式:DOCX 页数:5 大小:19.85KB
返回 下载 相关 举报
Linux下获取CPUID、硬盘序列号与MAC地址.docx_第1页
第1页 / 共5页
Linux下获取CPUID、硬盘序列号与MAC地址.docx_第2页
第2页 / 共5页
Linux下获取CPUID、硬盘序列号与MAC地址.docx_第3页
第3页 / 共5页
Linux下获取CPUID、硬盘序列号与MAC地址.docx_第4页
第4页 / 共5页
亲,该文档总共5页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《Linux下获取CPUID、硬盘序列号与MAC地址.docx》由会员分享,可在线阅读,更多相关《Linux下获取CPUID、硬盘序列号与MAC地址.docx(5页珍藏版)》请在三一文库上搜索。

1、Linux 下获取 CPUID、硬盘序列号与 MAC地址在很多系 统软 件的开 发中,需要使用一些系统的唯一性信息。所以,得到主机的CPUID、硬 盘序列号及网卡的 MAC地址,就成个一件很重要的应用。本人经过一番 google 即自己的 钻研,基本上 实现了这几个功能。需要的准 备知识有:1. GCC的嵌入汇编,具体的 GCC嵌入汇编知识,请参考相关手册2. ioctl 系统调用,具体的 调用方法, 请查看手册页获取 CPUID按照网上提供的 说明, CPUID并不是所有的Intel CPU都支持的。如果支持, 汇编调用为:eax 置 0000_0003,调用 cpuid 。以下为实现代码(

2、在我的 CPU上,并没有得到):#define cpuid(in,a,b,c,d) asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in); static intgetcpuid (char *id, size_t max)int i;unsigned long li, maxi, maxei, ebx, ecx, edx, unused;cpuid (0, maxi, unused, unused, un

3、used);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: %sn", id); return 0;获取硬盘序列号这个的实现,采用的是 读取 /etc/mtab文件,找到开它,再用系 统调用 ioctl来实现的。/ (即根目 录)挂载的设备文件,然后打ioctli

4、octl第二个参数 为 HDIO_GET_IDENTITY,获得指定文件描述符的 标志号的第三个参数 为 struct hd_driveid *,在 linux/hdreg.h中, struct hd_driveid的声明有精选文库struct hd_driveid unsigned shortconfig;/* lots of obsolete bit flags */unsigned shortcyls;/* Obsolete, "physical" cyls */unsigned shortreserved2;/* reserved (word 2) */unsign

5、ed shortheads;/* Obsolete, "physical" heads */unsigned shorttrack_bytes;/* unformatted bytes per track */unsigned shortsector_bytes;/* unformatted bytes per sector */unsigned shortsectors;/* Obsolete, "physical" sectors per track */unsigned shortvendor0;/* vendor unique */unsigne

6、d shortvendor1;/* vendor unique */unsigned shortvendor2;/* Retired vendor unique */unsigned charserial_no20;/* 0 = not_specified */unsigned shortbuf_type;/* Retired */unsigned shortbuf_size;/* Retired, 512 byte increments* 0 = not_specified*/;, 这其中, serial_no为硬盘的序列号。如果此 项为 0,则为没有提供。思路明确了,以下 为实现代码:st

7、atic intgetdiskid (char *id, size_t max)int fd;struct hd_driveid hid;FILE *fp;char line0x100, *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 = strto

8、k (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'2精选文库fd = open (disk, O_RDONLY);break;fclose (fp);if (fd < 0)fprintf (stderr, &qu

9、ot;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: %sn", id);return 0;获取 MAC地

10、址通过创建一个 socket ,然后 bind 特定的 IP 地址,就可以通 过 ioctl得到这个套按地 绑定的网络接口名称。然后再通过网络接口名称,得到MAC地址。如果 ioctl的第二个参数 为 SIOCGIFNAME,则获得指定网 络接口的名称;如果ioctl的第二个参数为 SIOCGIFHWADDR,则获得指定网 络接口的 MAC地址ioctl的第三个参数 为 struct ifreq *,在 linux/if.h头文件里, struct ifreq声明如下:struct ifreq#define IFHWADDRLEN6unioncharifrn_nameIFNAMSIZ;/* i

11、f 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;shortifru_flags;intifru_ivalue;intifru_mtu;struct ifmap ifru_map;charifru_slaveIFNAMSIZ;/* Just fits the size

12、*/3精选文库charifru_newnameIFNAMSIZ;void * ifru_data;struct if_settings ifru_settings; ifr_ifru;, 其中, ifrn_name 为网络接口的名称, ifr_ifru.ifru_hwaddr为网络接口的 MAC地址。#ifndef MAX_IFINDEX# define MAX_IFINDEX 8 #endifstatic intgetmacaddr (const char *ip, char *id, size_t max)int i, sockfd;struct sockaddr_in *loc;stru

13、ct ifreq req1;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: %sn", strerror

14、(errno);continue;if (ioctl (sockfd, SIOCGIFADDR, req) < 0)fprintf (stderr, "ioctl interface index %d error: %sn", 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 %

15、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: %sn", strerror (errno);close (sockfd);return -1;4精选文库close (sockfd);snprintf (id,

16、max, "%02X%02X%02X%02X%02X%02X",req->ifr_hwaddr.sa_data0 & 0xff,req->ifr_hwaddr.sa_data1 & 0xff,req->ifr_hwaddr.sa_data2 & 0xff,req->ifr_hwaddr.sa_data3 & 0xff,req->ifr_hwaddr.sa_data4 & 0xff,req->ifr_hwaddr.sa_data5 & 0xff);fprintf (stdout, "MAC address of %s: %s.n", req->ifr_name, id);return 0;5

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1