linux获取机器cpuid地址函数,Linux下获取CPUID、硬盘序列号与MAC地址
在很多系统软件的开发中,需要使用一些系统的唯一性信息。所以,得到主机的CPUID、硬盘序列号及网卡的MAC地址,就成个一件很重要的应用。
本人经过一番google即自己的钻研,基本上实现了这几个功能。需要的准备知识有:
GCC的嵌入汇编,具体的GCC嵌入汇编知识,请参考相关手册
ioctl系统调用,具体的调用方法,请查看手册页
获取CPUID
按照网上提供的说明,CPUID并不是所有的Intel CPU都支持的。如果支持,汇编调用为:eax置0000_0003,调用cpuid。
以下为实现代码(在我的CPU上,并没有得到):
#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;
}
获取硬盘序列号
这个的实现,采用的是读取/etc/mtab文件,找到/(即根目录)挂载的设备文件,然后打开它,再用系统调用ioctl来实现的。
ioctl第二个参数为HDIO_GET_IDENTITY, 获得指定文件描述符的标志号
ioctl的第三个参数为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为硬盘的序列号。如果此项为0,则为没有提供。
思路明确了,以下为实现代码:
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地址
通过创建一个socket,然后bind特定的IP地址,就可以通过ioctl得到这个套按地绑定的网络接口名称。然后再通过网络接口名称,得到MAC地址。
如果ioctl的第二个参数为SIOCGIFNAME, 则获得指定网络接口的名称;如果ioctl的第二个参数为SIOCGIFHWADDR,则获得指定网络接口的MAC地址
ioctl的第三个参数为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为网络接口的名称,ifr_ifru.ifru_hwaddr为网络接口的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;
}
【编辑推荐】
【责任编辑:faya TEL:(010)68476606】
linux获取机器cpuid地址函数,Linux下获取CPUID、硬盘序列号与MAC地址相关推荐
- JAVA获取CPUID、主板序列号、硬盘序列号、MAC地址
最近在修改公司licence程序,需要获取到更多的硬件唯一标识,以便加密使用. 网上看了很多大神的博客,思路大概整理了一下,根据系统类型分为两种方式: 一.windows 通过创建vbs脚本,然后使用 ...
- 一键获取电脑的系统安装时间、硬盘序列号、MAC地址、补丁安装信息
查询Windows电脑的操作系统安装时间.硬盘序列号.MAC地址.补丁安装数量.和最新补丁安装时间,都有相应的命令行查询命令.但是一个一个查询有点麻烦,用Python写了一个一键查询的方法. 可将如下 ...
- java MacBook air,macbook pro 与 macbook air 的区别!(前者是高配?java中如何读取主板序列号、硬盘序列号、MAC地址...
所以我想问的重点是?(本人使用苹果①向用于上网?整体性能呢:air那么薄,那么轻,请问它的硬盘对比pro有什么利弊,对于air我①直用macbook pro,②年换①次,今年由于①③寸的并没有使用i系 ...
- Linux下获取CPUID、硬盘序列号与MAC地址
ioctl系统调用,具体的调用方法,请查看手册页 获取CPUID 按照网上提供的说明,CPUID并不是所有的Intel CPU都支持的.如果支持,汇编调用为:eax置0000_0003,调用cpuid ...
- cpuid linux,Linux下获取CPUID、硬盘序列号与MAC地址(2)
思路明确了,以下为实现代码: static int getdiskid (char *id, size_t max) { int fd; struct hd_driveid hid; FILE *fp ...
- win10查看设备序列号、硬盘序列号、mac地址
1. 设备序列号 wmic bios get serialnumber 2. 查看硬盘序列号 wmic diskdrive get serialnumber 3. mac地址 控制面板\网络和 Int ...
- windows系统硬盘序列号、MAC地址查询方法
硬盘序列号查询方法 进入命令行(cmd+R). 输入diskpart回车进入diskpart命令行. 输入list disk,列出所有磁盘和它们的磁盘号. 输入select disk ${磁盘号},选 ...
- linux查看设备和硬盘序列号 ip mac地址
最近公司查设备,记录一下相关的命令,方便以后使用. 主要针对centos,ubuntu加上"sudo"应该就可以 : 几个命令都可以用 大家可以对比查看核对. 1 设备序列号 查看 ...
- 我们发现您的应用在用户同意隐私政策前申请获取用户个人信息(IMEI, 设备ID, 用户应用安装列表, MAC地址用户数据)
一.需求 解决应用上架问题 过度获取用户信息 我们发现您的应用在用户同意隐私政策前申请获取用户个人信息(IMEI, 设备ID, 用户应用安装列表, MAC地址用户数据) 自"滴滴" ...
最新文章
- LabVIEW设计自定义滚动条
- Word中的字体大小
- 智能合约重构社会契约 (1)李嘉图合约
- 计算机专业伦理总结,《计算机伦理学》节译实践报告
- 内涵!!!程序猿才懂的动图...
- ASP.NET中使用C#文件下载四方法
- 俗语:“生不睡柳,死不睡杨”,有什么道理?
- [转]恢复 git reset -hard 的误操作
- uwsgi怎么启动停止
- DigitalFilmTools Rays 2.1.2汉化版|丁达尔光束耶稣光滤镜插件
- java QQ向另一个QQ发信息(可以是好友,也可以是非好友)
- 微信开发者工具封装request请求
- H5 App实现热更新,不需要重新安装app
- Android自定义控件--仿安全卫士中的一键加速【圆形进度条】
- Unity透明度不叠加
- Unity3D-设置地形
- 年底不要慌,这个EXCEL模板帮你打赢Q4收官战
- 线阵ccd模块LCAMV8-S11639-01/S11638高灵敏线阵图像传感器模组、驱动板
- Caused by: java.lang.IllegalArgumentException报错
- 数据库(My SQL 、SQL Server)的数据类型