因开发需要获取有线网卡的MAC地址,发现网上获取的方法多数只能获取联网网卡的MAC地址,因此重写了下Ubuntu 10下测试通过。
下面代码无论网卡是否连线,都可以获取MAC地址,稍作修改,可以输出系统所有的网卡硬件MAC地址,无论是否已经联网。 【6688电子商务网站 www.6688.cc 】
- /* * getmac.c
- * * Created on: 2010-11-4
- * Author: carl */
- #include <stdio.h>
- #include <fcntl.h> #include <stdlib.h>
- #include <string.h> #include <unistd.h>
- #include <sys/ioctl.h>
- #include <sys/types.h> #include <sys/socket.h>
- #include <netinet/in.h> #include <linux/if.h>
- #define IFNAMSIZ 16
- // data structs to store interface name list
- char ifname_buf[2048]; char *ifnames = ifname_buf;
- int count = 0;
- void add_interface_name(const char * name) {
- int i; for (i=0;i<count;i++)
- { if (!strcmp(ifnames+i*IFNAMSIZ, name))
- return; }
- strncpy(ifnames+(count++)*IFNAMSIZ, name, IFNAMSIZ-1); }
- char * get_name(char *name, char *p)
- { while (isspace(*p))
- p++; while (*p) {
- if (isspace(*p)) break;
- if (*p == ':') { /* could be an alias */ char *dot = p, *dotname = name;
- *name++ = *p++; while (isdigit(*p))
- *name++ = *p++; if (*p != ':') { /* it wasn't, backup */
- p = dot; name = dotname;
- } if (*p == '\0')
- return NULL; p++;
- break; }
- *name++ = *p++; }
- *name++ = '\0'; return p;
- }
- // get /proc/net/dev interface name list into buffer // return 0 if success
- int get_procnet_list() {
- FILE *fh; char buf[512];
- fh = fopen("/proc/net/dev", "r"); if (!fh)
- return -1;
- fgets(buf, sizeof buf, fh); /* eat title lines */ fgets(buf, sizeof buf, fh);
- while (fgets(buf, sizeof buf, fh)) {
- char name[IFNAMSIZ]; get_name(name, buf);
- add_interface_name(name); }
- fclose(fh); return 0;
- }
- long mac_addr_sys ( u_char *addr) {
- /* implementation for Linux */ struct ifreq ifr;
- struct ifreq *IFR; struct ifconf ifc;
- char buf[1024]; int s, i;
- int ok = 0;
- // clear buffer memset(ifname_buf, 0, sizeof(ifname_buf));
- s = socket(AF_INET, SOCK_DGRAM, 0); if (s==-1) {
- return -1; }
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = buf; ioctl(s, SIOCGIFCONF, &ifc);
- IFR = ifc.ifc_req;
- // put the ioctl interface names in the list for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; IFR++) {
- add_interface_name(IFR->ifr_name); }
- // put the /proc/net/dev interface names in the list if (get_procnet_list())
- return -1;
- // get the first mac address of eth* device hardware address for (i = 0; i < count; i++) {
- strcpy(ifr.ifr_name, ifnames + i*IFNAMSIZ); if (!strncmp(ifr.ifr_name, "eth", 3))
- if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) { if (! (ifr.ifr_flags & IFF_LOOPBACK)) {
- if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0) { char *p = (char *)ifr.ifr_hwaddr.sa_data;
- if (!*((int *)p) && !*((int *)(p+2)) ) continue;
- // if not 00:00:00:00:00:00, yes, we get the real mac addr ok = 1;
- break; }
- } }
- }
- close(s); if (ok) {
- bcopy( ifr.ifr_hwaddr.sa_data, addr, 6); }
- else { return -1;
- } return 0;
- }
- /***********************************************************************/ /*
- * Main (only for testing) */
- int main( int argc, char **argv) {
- long stat; int i;
- u_char addr[6];
- stat = mac_addr_sys( addr); if (0 == stat) {
- printf( "MAC address = "); for (i=0; i<6; ++i) {
- printf("%2.2x", addr[i]); if (i<5)
- printf(":"); }
- printf( "\n"); }
- else { fprintf( stderr, "can't get MAC address\n");
- exit( 1); }
- return 0; }