Ady Wicaksono Daily Activities

Detecting MAC Address using C application

with 10 comments

I got this code long time ago from somewhere (off course from internet), using this C code it’s now simpler for you to create application that needs to detect MAC address.

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#ifdef Linux
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/if.h>
#endif

#ifdef HPUX
#include <netio.h>
#endif

#ifdef AIX
#include <sys/ndd_var.h>
#include <sys/kinfo.h>
#endif

long mac_addr_sys ( u_char *addr)
{
/* implementation for Linux */
#ifdef Linux
    struct ifreq ifr;
    struct ifreq *IFR;
    struct ifconf ifc;
    char buf[1024];
    int s, i;
    int ok = 0;

    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;
    for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; IFR++) {

        strcpy(ifr.ifr_name, IFR->ifr_name);
        if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) {
            if (! (ifr.ifr_flags & IFF_LOOPBACK)) {
                if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0) {
                    ok = 1;
                    break;
                }
            }
        }
    }

    close(s);
    if (ok) {
        bcopy( ifr.ifr_hwaddr.sa_data, addr, 6);
    }
    else {
        return -1;
    }
    return 0;
#endif

/* implementation for HP-UX */
#ifdef HPUX

#define LAN_DEV0 "/dev/lan0"

    intfd;
    struct fisiocnt_block;
    inti;
    charnet_buf[sizeof(LAN_DEV0)+1];
    char*p;

    (void)sprintf(net_buf, "%s", LAN_DEV0);
    p = net_buf + strlen(net_buf) - 1;

    /*
     * Get 802.3 address from card by opening the driver and interrogating it.
     */
    for (i = 0; i < 10; i++, (*p)++) {
        if ((fd = open (net_buf, O_RDONLY)) != -1) {
iocnt_block.reqtype = LOCAL_ADDRESS;
ioctl (fd, NETSTAT, &iocnt_block);
close (fd);

            if (iocnt_block.vtype == 6)
                break;
        }
    }

    if (fd == -1 || iocnt_block.vtype != 6) {
        return -1;
    }

bcopy( &iocnt_block.value.s[0], addr, 6);
return 0;

#endif /* HPUX */

/* implementation for AIX */
#ifdef AIX

    int size;
    struct kinfo_ndd *nddp;

    size = getkerninfo(KINFO_NDD, 0, 0, 0);
    if (size <= 0) {
        return -1;
    }
    nddp = (struct kinfo_ndd *)malloc(size);
        
    if (!nddp) {
        return -1;
    }
    if (getkerninfo(KINFO_NDD, nddp, &size, 0) < 0) {
        free(nddp);
        return -1;
    }
    bcopy(nddp->ndd_addr, addr, 6);
    free(nddp);
    return 0;
#endif

/* Not implemented platforms */
return -1;
}

/***********************************************************************/
/*
 * Main (only for testing)
 */
#ifdef MAIN
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]);
        }
        printf( "\n");
    }
    else {
        fprintf( stderr, "can't get MAC address\n");
        exit( 1);
    }
    return 0;
}
#endif

E.g you want to use on Linux, save it as file.c simply compile like this:

   gcc -O2 -DMAIN -DLinux file.c -o file

And run it

./file
MAC address = 0008c7e9e386

Compare with /sbin/ifconfig result:

/sbin/ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:08:C7:E9:E3:86
          inet addr:***.***.***.***  Bcast:***.***.***.***  Mask:255.255.255.0
          inet6 addr: ********************* Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:265555947 errors:0 dropped:0 overruns:0 frame:0
          TX packets:50507373 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:4090310752 (3.8 GiB)  TX bytes:1085018636 (1.0 GiB)

It’s the same :)

About these ads

Written by adywicaksono

November 8, 2007 at 9:29 am

Posted in C/C++, Linux

10 Responses

Subscribe to comments with RSS.

  1. Hello

    i tried to run the code for detecting MAC address that you had published here using Microsoft Visual C++ but then i had many errors after compiling. I have added all the header files that is required but it seems that this code could not run under VC++. What type of SDK that is suitable to run this code or do you have any other options that could detect MAC address using VC++? Thank you.

    Hello this function is for *NIX based OS, currently I have no information on similar function on VC++. Thanks

    Hazwan Halim

    November 11, 2007 at 5:10 am

  2. The for loop within the Linux code looks wrong to me since the i variable is never modified. Am I missing something?

    Doug

    June 17, 2008 at 2:37 pm

  3. It is modified right in the for statement by “–i”

    vk

    July 21, 2008 at 10:33 pm

  4. May I know why is that -O2 needed?

    lesterc

    August 22, 2008 at 5:16 am

  5. nothing is coming in HP UX .

    ashna

    September 1, 2008 at 9:38 am

  6. I was spending hours trying to cover the ifconfig source code for doing the same until I searched again out of frustration and found this.

    Thank you for the function :)

    Harsh

    March 20, 2009 at 6:02 pm

  7. Hello thanks for this code it is running in my dabian linux I got the eth0 MAC address , How can I get the eth1 MAC address . can I send the driver name in command prompt so according to driver it will give it’s mac address..???
    waiting for response

    Thanks..

    Dwijesh

    April 24, 2009 at 6:50 am

  8. Is there a method to know Mac-Id if the PC is not in network? The above solution fails to read Mac-Id for a computer if eth0 is down while ifconfig shows it even then???

    Another Geek

    June 16, 2009 at 9:20 am

  9. Big thanks

    vkjr

    July 17, 2009 at 11:29 am

  10. please, create a code from the windows.
    #ifdef WIN32

    big thanks

    Vinicius Reinehr

    March 12, 2010 at 8:26 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: