因开发需要获取有线网卡的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;
- }