在很多系统软件的开发中,需要使用一些系统的唯一性信息。所以,得到主机的CPUID、硬盘序列号及网卡的MAC地址,就成个一件很重要的应用。
需要的准备知识有:
- 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的声明有
<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>