Forums

Skip to content

Advanced search
  • Quick links
    • Unanswered topics
    • Active topics
    • Search
  • FAQ
  • Login
  • Register
  • Board index Assistance Portage & Programming
  • Search

How do I get the MAC/physical/hardware address? (using C)

Problems with emerge or ebuilds? Have a basic programming question about C, PHP, Perl, BASH or something else?
Post Reply
Advanced search
5 posts • Page 1 of 1
Author
Message
sfp-a7x
n00b
n00b
Posts: 47
Joined: Tue Nov 16, 2004 1:20 am

How do I get the MAC/physical/hardware address? (using C)

  • Quote

Post by sfp-a7x » Mon Jun 26, 2006 1:02 am

Hi all,

I'm stumped on this one. I'm trying to write a C program for *nix (specifically Linux and BSD) that grabs the MAC address (a.k.a. physical or hardware address) for each network adapter on the machine.

I can get a pointer to the bytes that contain the hardware address, but the problem is I don't know how long the hardware address is. For Ethernet, I know that it's 6 bytes long, but other kinds of adapters have different hardware address lengths. I have the ARPHRD_* value (see <net/if_arp.h> ), which tells me what kind of adapter it is. How can I use this value to determine the number of bytes in the hardware address? Unfortunately, "man 7 netdevice" doesn't tell me what I need to know.

Here's some minimal code:

Code: Select all

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string.h>

int main(int argc, char** argv) {
     int sd;
     struct ifreq ifr;
     unsigned char* hw_address;
     int hw_address_len;
     int i;

     /* make socket */
     sd = socket(PF_INET, SOCK_DGRAM, 0);
     if (sd == -1) {
          /* insert freak-out code here */
     }

     /* set interface name (lo, eth0, eth1,..) */
     memset(&ifr, 0, sizeof(ifr));
     strncpy(ifr.ifr_name, "eth0", IFNAMSIZ);

     /* get interface hardware address */
     ioctl(sd, SIOCGIFHWADDR, &ifr);
     
     close(sd);
     
     /* get hardware address and length */
     hw_address = ifr.ifr_hwaddr.sa_data;
     hw_address_len = 6; /* <- what goes here to make it
                            non-Ethernet-specific? */

     /* print out the type of hardware */
     printf("ARPHRD_* value of device (see <net/if_arp.h>):  %i\n",
            ifr.ifr_hwaddr.sa_family);

     /* print out hardware address */
     printf("Hardware address:  ");
     for (i = 0; i < hw_address_len; i++) {
          printf("%.2x%s", hw_address[i], i==hw_address_len-1 ? "" : ":");
     }
     printf("\n");

     return(0);
}

Thanks!
Top
lorenb
Apprentice
Apprentice
User avatar
Posts: 207
Joined: Sat Aug 24, 2002 4:25 am
Location: Toronto, ON

  • Quote

Post by lorenb » Mon Jun 26, 2006 2:10 am

ifr_hwaddr is a sockaddr structure:

Code: Select all

struct sockaddr {
   u_char sa_len;                        /* total length */
   u_char sa_family;                   /* address family */
   char sa_data[14];                   /* address data */
}
Try the ifr.ifr_hwaddr.sa_len variable.
Top
sfp-a7x
n00b
n00b
Posts: 47
Joined: Tue Nov 16, 2004 1:20 am

  • Quote

Post by sfp-a7x » Mon Jun 26, 2006 3:14 am

lorenb wrote:Try the ifr.ifr_hwaddr.sa_len variable.
Thanks for the suggestion. I tried it out and got:

Code: Select all

error: structure has no member named `sa_len'
Looking in sys/socket.h (which leads me to bits/socket.h and bits/sockaddr.h), I see:

Code: Select all

struct sockaddr
  { 
    unsigned short int sa_family;
    char sa_data[14];
  };
I peeked at the two bytes in sa_family by doing this:

Code: Select all

fprintf(stderr, "Contents of sa_data:  ");
for (i = -2; i < 14; i++) {
    fprintf(stderr, "%2.2hhx%s", ifr.ifr_hwaddr.sa_data[i], i==13 ? "" : ":");
}
fprintf(stderr, "\n");
and got 01:00 for the first two bytes (the two before sa_data). Neither one can be length... Maybe I should have looked at the two bytes after sa_data? I'm not sure how it's stored in memory... ARPHRD_ETHER equals 1, so I imagine I got the correct two bytes (I'm on a little-endian machine with an Ethernet device).

Thoughts?

Thanks!
Top
lorenb
Apprentice
Apprentice
User avatar
Posts: 207
Joined: Sat Aug 24, 2002 4:25 am
Location: Toronto, ON

  • Quote

Post by lorenb » Mon Jun 26, 2006 4:16 am

Hmmm. Looking at net-tools-1.60 specifically at the ifconfig code it looks like they keep a table of known hardware types and the lengths. Then they reference it as needed. So maybe you can't determine it at runtime.

Take a look at:

Code: Select all

net-tools-1.60/lib/interface.c -- see the function ife_print_long
net-tools-1.60/lib/hw.c
net-tools-1.60/lib/net-support.h
Top
sfp-a7x
n00b
n00b
Posts: 47
Joined: Tue Nov 16, 2004 1:20 am

  • Quote

Post by sfp-a7x » Mon Jun 26, 2006 5:41 am

lorenb wrote:Hmmm. Looking at net-tools-1.60 specifically at the ifconfig code it looks like they keep a table of known hardware types and the lengths. Then they reference it as needed. So maybe you can't determine it at runtime.

<snip>
Thanks for the pointer! It's good to know that such a standard tool doesn't have a way to determine length at runtime because that means I can stop searching.

I'll examine the code and see if it's something I can easily incorporate into my code.

Thanks again!
Top
Post Reply

5 posts • Page 1 of 1

Return to “Portage & Programming”

Jump to
  • Assistance
  • ↳   News & Announcements
  • ↳   Frequently Asked Questions
  • ↳   Installing Gentoo
  • ↳   Multimedia
  • ↳   Desktop Environments
  • ↳   Networking & Security
  • ↳   Kernel & Hardware
  • ↳   Portage & Programming
  • ↳   Gamers & Players
  • ↳   Other Things Gentoo
  • ↳   Unsupported Software
  • Discussion & Documentation
  • ↳   Documentation, Tips & Tricks
  • ↳   Gentoo Chat
  • ↳   Gentoo Forums Feedback
  • ↳   Duplicate Threads
  • International Gentoo Users
  • ↳   中文 (Chinese)
  • ↳   Dutch
  • ↳   Finnish
  • ↳   French
  • ↳   Deutsches Forum (German)
  • ↳   Diskussionsforum
  • ↳   Deutsche Dokumentation
  • ↳   Greek
  • ↳   Forum italiano (Italian)
  • ↳   Forum di discussione italiano
  • ↳   Risorse italiane (documentazione e tools)
  • ↳   Polskie forum (Polish)
  • ↳   Instalacja i sprzęt
  • ↳   Polish OTW
  • ↳   Portuguese
  • ↳   Documentação, Ferramentas e Dicas
  • ↳   Russian
  • ↳   Scandinavian
  • ↳   Spanish
  • ↳   Other Languages
  • Architectures & Platforms
  • ↳   Gentoo on ARM
  • ↳   Gentoo on PPC
  • ↳   Gentoo on Sparc
  • ↳   Gentoo on Alternative Architectures
  • ↳   Gentoo on AMD64
  • ↳   Gentoo for Mac OS X (Portage for Mac OS X)
  • Board index
  • All times are UTC
  • Delete cookies

© 2001–2026 Gentoo Foundation, Inc.

Powered by phpBB® Forum Software © phpBB Limited

Privacy Policy