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

在很多系统软件的开发中,需要使用一些系统的唯一性信息。所以,得到主机的CPUID、硬盘序列号及网卡的MAC地址,就成个一件很重要的应用。

需要的准备知识有:

  1. GCC的嵌入汇编,具体的GCC嵌入汇编知识,请参考相关手册
  2. 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的声明有

<em>struct hd_driveid {
	unsigned short	config;		/</em> 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,则为没有提供。

思路明确了,以下为实现代码:

#include <string.h>

#include<stdio.h>

    #include <sys/ioctl.h>
    #include <linux/hdreg.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include<ctype.h>

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声明如下:

<em>struct ifreq
{
#define IFHWADDRLEN	6
	union
	{
		char	ifrn_name[IFNAMSIZ];		/</em> 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;
}
第二种方法:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <arpa/inet.h>
#include <errno.h>

#define ETH_NAME	"eth0"

int main()
{
int sock;
struct sockaddr_in sin;
struct sockaddr sa;
struct ifreq ifr;
unsigned char mac[6];

sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1)
{
perror("socket");
return -1;		
}

strncpy(ifr.ifr_name, ETH_NAME, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ - 1] = 0;

if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
{
perror("ioctl");
return -1;
}

memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
fprintf(stdout, "%s ip: %s\n", ETH_NAME, inet_ntoa(sin.sin_addr));

memset(mac, 0, sizeof(mac));
if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0)
{
perror("ioctl");
return -1;
}

memcpy(&sa, &ifr.ifr_addr, sizeof(sin));
memcpy(mac, sa.sa_data, sizeof(mac));
fprintf(stdout, "%s mac: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", ETH_NAME, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return 0;
}
第三种***:
<div class="line number8 index7 alt1"><code class="cpp preprocessor">#include <stdio.h> </code></div><div class="line number9 index8 alt2"><code class="cpp preprocessor">#include <fcntl.h> </code></div><div class="line number10 index9 alt1"><code class="cpp preprocessor">#include <stdlib.h> </code></div><div class="line number11 index10 alt2"><code class="cpp preprocessor">#include <string.h> </code></div><div class="line number12 index11 alt1"><code class="cpp preprocessor">#include <unistd.h> </code></div><div class="line number13 index12 alt2"><code class="cpp spaces"> </code> </div><div class="line number14 index13 alt1"><code class="cpp preprocessor">#include <sys/ioctl.h> </code></div><div class="line number15 index14 alt2"><code class="cpp preprocessor">#include <sys/types.h> </code></div><div class="line number16 index15 alt1"><code class="cpp preprocessor">#include <sys/socket.h> </code></div><div class="line number17 index16 alt2"><code class="cpp preprocessor">#include <netinet/in.h> </code></div><div class="line number18 index17 alt1"><code class="cpp preprocessor">#include <linux/if.h> </code></div><div class="line number19 index18 alt2"><code class="cpp spaces"> </code> </div><div class="line number20 index19 alt1"><code class="cpp preprocessor">#define IFNAMSIZ 16 </code></div><div class="line number21 index20 alt2"><code class="cpp spaces"> </code> </div><div class="line number22 index21 alt1"><code class="cpp comments">// data structs to store interface name list </code></div><div class="line number23 index22 alt2"><code class="cpp color1 bold">char</code> <code class="cpp plain">ifname_buf[2048]; </code></div><div class="line number24 index23 alt1"><code class="cpp color1 bold">char</code> <code class="cpp plain">*ifnames = ifname_buf; </code></div><div class="line number25 index24 alt2"><code class="cpp color1 bold">int</code> <code class="cpp plain">count = 0; </code></div><div class="line number26 index25 alt1"><code class="cpp spaces"> </code> </div><div class="line number27 index26 alt2"><code class="cpp keyword bold">void</code> <code class="cpp plain">add_interface_name(</code><code class="cpp keyword bold">const</code> <code class="cpp color1 bold">char</code> <code class="cpp plain">* name) </code></div><div class="line number28 index27 alt1"><code class="cpp plain">{ </code></div><div class="line number29 index28 alt2"><code class="cpp spaces">    </code><code class="cpp color1 bold">int</code> <code class="cpp plain">i; </code></div><div class="line number30 index29 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">for</code> <code class="cpp plain">(i=0;i<count;i++) </code></div><div class="line number31 index30 alt2"><code class="cpp spaces">    </code><code class="cpp plain">{ </code></div><div class="line number32 index31 alt1"><code class="cpp spaces">        </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(!</code><code class="cpp functions bold">strcmp</code><code class="cpp plain">(ifnames+i*IFNAMSIZ, name)) </code></div><div class="line number33 index32 alt2"><code class="cpp spaces">            </code><code class="cpp keyword bold">return</code><code class="cpp plain">; </code></div><div class="line number34 index33 alt1"><code class="cpp spaces">    </code><code class="cpp plain">} </code></div><div class="line number35 index34 alt2"><code class="cpp spaces">    </code><code class="cpp functions bold">strncpy</code><code class="cpp plain">(ifnames+(count++)*IFNAMSIZ, name, IFNAMSIZ-1); </code></div><div class="line number36 index35 alt1"><code class="cpp plain">} </code></div><div class="line number37 index36 alt2"><code class="cpp spaces"> </code> </div><div class="line number38 index37 alt1"><code class="cpp color1 bold">char</code> <code class="cpp plain">* get_name(</code><code class="cpp color1 bold">char</code> <code class="cpp plain">*name, </code><code class="cpp color1 bold">char</code> <code class="cpp plain">*p) </code></div><div class="line number39 index38 alt2"><code class="cpp plain">{ </code></div><div class="line number40 index39 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">while</code> <code class="cpp plain">(</code><code class="cpp functions bold">isspace</code><code class="cpp plain">(*p)) </code></div><div class="line number41 index40 alt2"><code class="cpp spaces">    </code><code class="cpp plain">p++; </code></div><div class="line number42 index41 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">while</code> <code class="cpp plain">(*p) { </code></div><div class="line number43 index42 alt2"><code class="cpp spaces">    </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(</code><code class="cpp functions bold">isspace</code><code class="cpp plain">(*p)) </code></div><div class="line number44 index43 alt1"><code class="cpp spaces">        </code><code class="cpp keyword bold">break</code><code class="cpp plain">; </code></div><div class="line number45 index44 alt2"><code class="cpp spaces">    </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(*p == </code><code class="cpp string">':'</code><code class="cpp plain">) {    </code><code class="cpp comments">/* could be an alias */</code></div><div class="line number46 index45 alt1"><code class="cpp spaces">        </code><code class="cpp color1 bold">char</code> <code class="cpp plain">*dot = p, *dotname = name; </code></div><div class="line number47 index46 alt2"><code class="cpp spaces">        </code><code class="cpp plain">*name++ = *p++; </code></div><div class="line number48 index47 alt1"><code class="cpp spaces">        </code><code class="cpp keyword bold">while</code> <code class="cpp plain">(</code><code class="cpp functions bold">isdigit</code><code class="cpp plain">(*p)) </code></div><div class="line number49 index48 alt2"><code class="cpp spaces">        </code><code class="cpp plain">*name++ = *p++; </code></div><div class="line number50 index49 alt1"><code class="cpp spaces">        </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(*p != </code><code class="cpp string">':'</code><code class="cpp plain">) {    </code><code class="cpp comments">/* it wasn't, backup */</code></div><div class="line number51 index50 alt2"><code class="cpp spaces">        </code><code class="cpp plain">p = dot; </code></div><div class="line number52 index51 alt1"><code class="cpp spaces">        </code><code class="cpp plain">name = dotname; </code></div><div class="line number53 index52 alt2"><code class="cpp spaces">        </code><code class="cpp plain">} </code></div><div class="line number54 index53 alt1"><code class="cpp spaces">        </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(*p == </code><code class="cpp string">'\0'</code><code class="cpp plain">) </code></div><div class="line number55 index54 alt2"><code class="cpp spaces">        </code><code class="cpp keyword bold">return</code> <code class="cpp plain">NULL; </code></div><div class="line number56 index55 alt1"><code class="cpp spaces">        </code><code class="cpp plain">p++; </code></div><div class="line number57 index56 alt2"><code class="cpp spaces">        </code><code class="cpp keyword bold">break</code><code class="cpp plain">; </code></div><div class="line number58 index57 alt1"><code class="cpp spaces">    </code><code class="cpp plain">} </code></div><div class="line number59 index58 alt2"><code class="cpp spaces">    </code><code class="cpp plain">*name++ = *p++; </code></div><div class="line number60 index59 alt1"><code class="cpp spaces">    </code><code class="cpp plain">} </code></div><div class="line number61 index60 alt2"><code class="cpp spaces">    </code><code class="cpp plain">*name++ = </code><code class="cpp string">'\0'</code><code class="cpp plain">; </code></div><div class="line number62 index61 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">return</code> <code class="cpp plain">p; </code></div><div class="line number63 index62 alt2"><code class="cpp plain">} </code></div><div class="line number64 index63 alt1"><code class="cpp spaces"> </code> </div><div class="line number65 index64 alt2"><code class="cpp comments">// get /proc/net/dev interface name list into buffer </code></div><div class="line number66 index65 alt1"><code class="cpp comments">// return 0 if success </code></div><div class="line number67 index66 alt2"><code class="cpp color1 bold">int</code> <code class="cpp plain">get_procnet_list() </code></div><div class="line number68 index67 alt1"><code class="cpp plain">{ </code></div><div class="line number69 index68 alt2"><code class="cpp spaces">    </code><code class="cpp color1 bold">FILE</code> <code class="cpp plain">*fh; </code></div><div class="line number70 index69 alt1"><code class="cpp spaces">    </code><code class="cpp color1 bold">char</code> <code class="cpp plain">buf[512]; </code></div><div class="line number71 index70 alt2"><code class="cpp spaces">    </code><code class="cpp plain">fh = </code><code class="cpp functions bold">fopen</code><code class="cpp plain">(</code><code class="cpp string">"/proc/net/dev"</code><code class="cpp plain">, </code><code class="cpp string">"r"</code><code class="cpp plain">); </code></div><div class="line number72 index71 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(!fh) </code></div><div class="line number73 index72 alt2"><code class="cpp spaces">        </code><code class="cpp keyword bold">return</code> <code class="cpp plain">-1; </code></div><div class="line number74 index73 alt1"><code class="cpp spaces"> </code> </div><div class="line number75 index74 alt2"><code class="cpp spaces">    </code><code class="cpp functions bold">fgets</code><code class="cpp plain">(buf, </code><code class="cpp keyword bold">sizeof</code> <code class="cpp plain">buf, fh); </code><code class="cpp comments">/* eat title lines */</code></div><div class="line number76 index75 alt1"><code class="cpp spaces">    </code><code class="cpp functions bold">fgets</code><code class="cpp plain">(buf, </code><code class="cpp keyword bold">sizeof</code> <code class="cpp plain">buf, fh); </code></div><div class="line number77 index76 alt2"><code class="cpp spaces">    </code><code class="cpp keyword bold">while</code> <code class="cpp plain">(</code><code class="cpp functions bold">fgets</code><code class="cpp plain">(buf, </code><code class="cpp keyword bold">sizeof</code> <code class="cpp plain">buf, fh)) </code></div><div class="line number78 index77 alt1"><code class="cpp spaces">    </code><code class="cpp plain">{ </code></div><div class="line number79 index78 alt2"><code class="cpp spaces">        </code><code class="cpp color1 bold">char</code> <code class="cpp plain">name[IFNAMSIZ]; </code></div><div class="line number80 index79 alt1"><code class="cpp spaces">        </code><code class="cpp plain">get_name(name, buf); </code></div><div class="line number81 index80 alt2"><code class="cpp spaces">        </code><code class="cpp plain">add_interface_name(name); </code></div><div class="line number82 index81 alt1"><code class="cpp spaces">    </code><code class="cpp plain">} </code></div><div class="line number83 index82 alt2"><code class="cpp spaces">    </code><code class="cpp functions bold">fclose</code><code class="cpp plain">(fh); </code></div><div class="line number84 index83 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">return</code> <code class="cpp plain">0; </code></div><div class="line number85 index84 alt2"><code class="cpp plain">} </code></div><div class="line number86 index85 alt1"><code class="cpp spaces"> </code> </div><div class="line number87 index86 alt2"><code class="cpp color1 bold">long</code> <code class="cpp plain">mac_addr_sys ( u_char *addr) </code></div><div class="line number88 index87 alt1"><code class="cpp plain">{ </code></div><div class="line number89 index88 alt2"><code class="cpp comments">/* implementation for Linux */</code></div><div class="line number90 index89 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">struct</code> <code class="cpp plain">ifreq ifr; </code></div><div class="line number91 index90 alt2"><code class="cpp spaces">    </code><code class="cpp keyword bold">struct</code> <code class="cpp plain">ifreq *IFR; </code></div><div class="line number92 index91 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">struct</code> <code class="cpp plain">ifconf ifc; </code></div><div class="line number93 index92 alt2"><code class="cpp spaces">    </code><code class="cpp color1 bold">char</code> <code class="cpp plain">buf[1024]; </code></div><div class="line number94 index93 alt1"><code class="cpp spaces">    </code><code class="cpp color1 bold">int</code> <code class="cpp plain">s, i; </code></div><div class="line number95 index94 alt2"><code class="cpp spaces">    </code><code class="cpp color1 bold">int</code> <code class="cpp plain">ok = 0; </code></div><div class="line number96 index95 alt1"><code class="cpp spaces"> </code> </div><div class="line number97 index96 alt2"><code class="cpp spaces">    </code><code class="cpp comments">// clear buffer </code></div><div class="line number98 index97 alt1"><code class="cpp spaces">    </code><code class="cpp functions bold">memset</code><code class="cpp plain">(ifname_buf, 0, </code><code class="cpp keyword bold">sizeof</code><code class="cpp plain">(ifname_buf)); </code></div><div class="line number99 index98 alt2"><code class="cpp spaces"> </code> </div><div class="line number100 index99 alt1"><code class="cpp spaces"> </code> </div><div class="line number101 index100 alt2"><code class="cpp spaces">    </code><code class="cpp plain">s = socket(AF_INET, SOCK_DGRAM, 0); </code></div><div class="line number102 index101 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(s==-1) { </code></div><div class="line number103 index102 alt2"><code class="cpp spaces">        </code><code class="cpp keyword bold">return</code> <code class="cpp plain">-1; </code></div><div class="line number104 index103 alt1"><code class="cpp spaces">    </code><code class="cpp plain">} </code></div><div class="line number105 index104 alt2"><code class="cpp spaces"> </code> </div><div class="line number106 index105 alt1"><code class="cpp spaces">    </code><code class="cpp plain">ifc.ifc_len = </code><code class="cpp keyword bold">sizeof</code><code class="cpp plain">(buf); </code></div><div class="line number107 index106 alt2"><code class="cpp spaces">    </code><code class="cpp plain">ifc.ifc_buf = buf; </code></div><div class="line number108 index107 alt1"><code class="cpp spaces">    </code><code class="cpp plain">ioctl(s, SIOCGIFCONF, &ifc); </code></div><div class="line number109 index108 alt2"><code class="cpp spaces"> </code> </div><div class="line number110 index109 alt1"><code class="cpp spaces">    </code><code class="cpp plain">IFR = ifc.ifc_req; </code></div><div class="line number111 index110 alt2"><code class="cpp spaces">    </code><code class="cpp comments">// put the ioctl interface names in the list </code></div><div class="line number112 index111 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">for</code> <code class="cpp plain">(i = ifc.ifc_len / </code><code class="cpp keyword bold">sizeof</code><code class="cpp plain">(</code><code class="cpp keyword bold">struct</code> <code class="cpp plain">ifreq); --i >= 0; IFR++) { </code></div><div class="line number113 index112 alt2"><code class="cpp spaces">            </code><code class="cpp plain">add_interface_name(IFR->ifr_name); </code></div><div class="line number114 index113 alt1"><code class="cpp spaces">    </code><code class="cpp plain">} </code></div><div class="line number115 index114 alt2"><code class="cpp spaces">    </code><code class="cpp comments">// put the /proc/net/dev interface names in the list </code></div><div class="line number116 index115 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(get_procnet_list()) </code></div><div class="line number117 index116 alt2"><code class="cpp spaces">        </code><code class="cpp keyword bold">return</code> <code class="cpp plain">-1; </code></div><div class="line number118 index117 alt1"><code class="cpp spaces"> </code> </div><div class="line number119 index118 alt2"><code class="cpp spaces">    </code><code class="cpp comments">// get the first mac address of eth* device hardware address </code></div><div class="line number120 index119 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">for</code> <code class="cpp plain">(i = 0; i < count; i++) { </code></div><div class="line number121 index120 alt2"><code class="cpp spaces">        </code><code class="cpp functions bold">strcpy</code><code class="cpp plain">(ifr.ifr_name, ifnames + i*IFNAMSIZ); </code></div><div class="line number122 index121 alt1"><code class="cpp spaces">        </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(!</code><code class="cpp functions bold">strncmp</code><code class="cpp plain">(ifr.ifr_name, </code><code class="cpp string">"eth"</code><code class="cpp plain">, 3)) </code></div><div class="line number123 index122 alt2"><code class="cpp spaces">            </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(ioctl(s, SIOCGIFFLAGS, &ifr) == 0) { </code></div><div class="line number124 index123 alt1"><code class="cpp spaces">                </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(! (ifr.ifr_flags & IFF_LOOPBACK)) { </code></div><div class="line number125 index124 alt2"><code class="cpp spaces">                    </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(ioctl(s, SIOCGIFHWADDR, &ifr) == 0) { </code></div><div class="line number126 index125 alt1"><code class="cpp spaces">                        </code><code class="cpp color1 bold">char</code> <code class="cpp plain">*p = (</code><code class="cpp color1 bold">char</code> <code class="cpp plain">*)ifr.ifr_hwaddr.sa_data; </code></div><div class="line number127 index126 alt2"><code class="cpp spaces">                        </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(!*((</code><code class="cpp color1 bold">int</code> <code class="cpp plain">*)p) && !*((</code><code class="cpp color1 bold">int</code> <code class="cpp plain">*)(p+2)) ) </code></div><div class="line number128 index127 alt1"><code class="cpp spaces">                            </code><code class="cpp keyword bold">continue</code><code class="cpp plain">; </code></div><div class="line number129 index128 alt2"><code class="cpp spaces">                        </code><code class="cpp comments">// if not 00:00:00:00:00:00, yes, we get the real mac addr </code></div><div class="line number130 index129 alt1"><code class="cpp spaces">                        </code><code class="cpp plain">ok = 1; </code></div><div class="line number131 index130 alt2"><code class="cpp spaces">                        </code><code class="cpp keyword bold">break</code><code class="cpp plain">; </code></div><div class="line number132 index131 alt1"><code class="cpp spaces">                    </code><code class="cpp plain">} </code></div><div class="line number133 index132 alt2"><code class="cpp spaces">                </code><code class="cpp plain">} </code></div><div class="line number134 index133 alt1"><code class="cpp spaces">            </code><code class="cpp plain">} </code></div><div class="line number135 index134 alt2"><code class="cpp spaces">    </code><code class="cpp plain">} </code></div><div class="line number136 index135 alt1"><code class="cpp spaces"> </code> </div><div class="line number137 index136 alt2"><code class="cpp spaces">    </code><code class="cpp plain">close(s); </code></div><div class="line number138 index137 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(ok) { </code></div><div class="line number139 index138 alt2"><code class="cpp spaces">        </code><code class="cpp plain">bcopy( ifr.ifr_hwaddr.sa_data, addr, 6); </code></div><div class="line number140 index139 alt1"><code class="cpp spaces">    </code><code class="cpp plain">} </code></div><div class="line number141 index140 alt2"><code class="cpp spaces">    </code><code class="cpp keyword bold">else</code> <code class="cpp plain">{ </code></div><div class="line number142 index141 alt1"><code class="cpp spaces">        </code><code class="cpp keyword bold">return</code> <code class="cpp plain">-1; </code></div><div class="line number143 index142 alt2"><code class="cpp spaces">    </code><code class="cpp plain">} </code></div><div class="line number144 index143 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">return</code> <code class="cpp plain">0; </code></div><div class="line number145 index144 alt2"><code class="cpp plain">} </code></div><div class="line number146 index145 alt1"><code class="cpp spaces"> </code> </div><div class="line number147 index146 alt2"><code class="cpp comments">/***********************************************************************/</code></div><div class="line number148 index147 alt1"><code class="cpp comments">/* </code></div><div class="line number149 index148 alt2"><code class="cpp spaces"> </code><code class="cpp comments">* Main (only for testing) </code></div><div class="line number150 index149 alt1"><code class="cpp spaces"> </code><code class="cpp comments">*/</code></div><div class="line number151 index150 alt2"><code class="cpp color1 bold">int</code> <code class="cpp plain">main( </code><code class="cpp color1 bold">int</code> <code class="cpp plain">argc, </code><code class="cpp color1 bold">char</code> <code class="cpp plain">**argv) </code></div><div class="line number152 index151 alt1"><code class="cpp plain">{ </code></div><div class="line number153 index152 alt2"><code class="cpp spaces">    </code><code class="cpp color1 bold">long</code> <code class="cpp plain">stat; </code></div><div class="line number154 index153 alt1"><code class="cpp spaces">    </code><code class="cpp color1 bold">int</code> <code class="cpp plain">i; </code></div><div class="line number155 index154 alt2"><code class="cpp spaces">    </code><code class="cpp plain">u_char addr[6]; </code></div><div class="line number156 index155 alt1"><code class="cpp spaces"> </code> </div><div class="line number157 index156 alt2"><code class="cpp spaces">    </code><code class="cpp plain">stat = mac_addr_sys( addr); </code></div><div class="line number158 index157 alt1"><code class="cpp spaces">    </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(0 == stat) { </code></div><div class="line number159 index158 alt2"><code class="cpp spaces">        </code><code class="cpp functions bold">printf</code><code class="cpp plain">( </code><code class="cpp string">"MAC address = "</code><code class="cpp plain">); </code></div><div class="line number160 index159 alt1"><code class="cpp spaces">        </code><code class="cpp keyword bold">for</code> <code class="cpp plain">(i=0; i<6; ++i) { </code></div><div class="line number161 index160 alt2"><code class="cpp spaces">            </code><code class="cpp functions bold">printf</code><code class="cpp plain">(</code><code class="cpp string">"%2.2x"</code><code class="cpp plain">, addr[i]); </code></div><div class="line number162 index161 alt1"><code class="cpp spaces">            </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(i<5) </code></div><div class="line number163 index162 alt2"><code class="cpp spaces">                </code><code class="cpp functions bold">printf</code><code class="cpp plain">(</code><code class="cpp string">":"</code><code class="cpp plain">); </code></div><div class="line number164 index163 alt1"><code class="cpp spaces">        </code><code class="cpp plain">} </code></div><div class="line number165 index164 alt2"><code class="cpp spaces">        </code><code class="cpp functions bold">printf</code><code class="cpp plain">( </code><code class="cpp string">"\n"</code><code class="cpp plain">); </code></div><div class="line number166 index165 alt1"><code class="cpp spaces">    </code><code class="cpp plain">} </code></div><div class="line number167 index166 alt2"><code class="cpp spaces">    </code><code class="cpp keyword bold">else</code> <code class="cpp plain">{ </code></div><div class="line number168 index167 alt1"><code class="cpp spaces">        </code><code class="cpp functions bold">fprintf</code><code class="cpp plain">( stderr, </code><code class="cpp string">"can't get MAC address\n"</code><code class="cpp plain">); </code></div><div class="line number169 index168 alt2"><code class="cpp spaces">        </code><code class="cpp functions bold">exit</code><code class="cpp plain">( 1); </code></div><div class="line number170 index169 alt1"><code class="cpp spaces">    </code><code class="cpp plain">} </code></div><div class="line number171 index170 alt2"><code class="cpp spaces">    </code><code class="cpp keyword bold">return</code> <code class="cpp plain">0; </code></div><div class="line number172 index171 alt1"><code class="cpp plain">}</code></div>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C语言可以通过使用Windows和Linux操作系统提供的相关 API 来获取本机的 CPUIDMAC 地址。 首先,我们可以通过Windows API函数`GetSystemInfo()`获取CPUID。示例代码如下: ```c #include <stdio.h> #include <windows.h> void main() { SYSTEM_INFO sys_info; GetSystemInfo(&sys_info); printf("CPU ID: %x %x %x %x\n", sys_info.dwProcessorType, sys_info.dwPageSize, sys_info.dwActiveProcessorMask, sys_info.dwNumberOfProcessors); } ``` 然后,我们可以通过使用Windows API函数`GetAdaptersInfo()`来获取本机的 MAC 地址。示例代码如下: ```c #include <stdio.h> #include <windows.h> #include <iphlpapi.h> #pragma comment(lib, "iphlpapi.lib") void main() { IP_ADAPTER_INFO adapter_info[16]; DWORD buf_len = sizeof(adapter_info); if (GetAdaptersInfo(adapter_info, &buf_len) == ERROR_SUCCESS) { PIP_ADAPTER_INFO curr_adapter = adapter_info; while (curr_adapter != NULL) { printf("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", curr_adapter->Address[0], curr_adapter->Address[1], curr_adapter->Address[2], curr_adapter->Address[3], curr_adapter->Address[4], curr_adapter->Address[5]); curr_adapter = curr_adapter->Next; } } } ``` 对于Linux操作系统,我们可以使用`sys/sysinfo.h`和`ifaddrs.h`头文件来获取 CPUIDMAC 地址。示例代码如下: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/sysinfo.h> #include <ifaddrs.h> #include <netinet/in.h> #include <arpa/inet.h> #include <net/if.h> #include <string.h> void main() { struct sysinfo sys_info; if (sysinfo(&sys_info) == 0) { printf("CPU ID: %08x\n", (unsigned int)sys_info.processor_id[0]); } struct ifaddrs* ifaddr, *ifa; if (getifaddrs(&ifaddr) == 0) { for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_PACKET) continue; struct sockaddr_ll* s = (struct sockaddr_ll*)ifa->ifa_addr; unsigned char mac[6]; memcpy(mac, s->sll_addr, 6); printf("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } freeifaddrs(ifaddr); } } ``` 需要注意的是,在使用这些API函数时,可能需要添加某些特定的库文件或在编译选项中指定相关的库文件,具体需要根据不同的操作系统和编译环境来进行调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值