Unix Programming - How to read the MAC Address out of /proc or /sys

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > February 2005 > How to read the MAC Address out of /proc or /sys





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author How to read the MAC Address out of /proc or /sys
Niko Schwarz

2005-01-23, 5:50 pm

Hello,

I'm writing a little obstacle for users to mass-copy programs my
university wrote.
It works fine already, I do it through the MAC address, which I read
from /sbin/ifconfig.

But: How can I read the MAC Address out of /proc? I seeked it a
little, but the file put out in the manual, /proc/net/socket doesn't
exist.
In /sys I don't find anything either. The only useful thing I found
was the ip6 address, which seems to contain the MAC Address.

Please don't tell me how unsafe all this is - I know it perfectly. And
I don't care much, it's not for me, I'd probably just rely on the
user's honesty.

Thanks in advance,

niko
Average Joe

2005-01-28, 2:47 am

Niko Schwarz wrote:
> Hello,
>
> I'm writing a little obstacle for users to mass-copy programs my
> university wrote. It works fine already, I do it through the MAC
> address, which I read from /sbin/ifconfig.



This isn't through /proc, but it's just another way to do it without:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <net/if.h>
#include <arpa/inet.h>

int main(void)
{
int sfd;
unsigned char *u;
struct ifreq ifr;
struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.ifr_addr;

memset(&ifr, 0, sizeof ifr);

if (0 > (sfd = socket(AF_INET, SOCK_STREAM, 0))) {
perror("socket()");
exit(EXIT_FAILURE);
}

strcpy(ifr.ifr_name, "eth0");
sin->sin_family = AF_INET;

if (0 == ioctl(sfd, SIOCGIFADDR, &ifr)) {
printf("%s: %s\n", ifr.ifr_name, inet_ntoa(sin->sin_addr));
}


if (0 > ioctl(sfd, SIOCGIFHWADDR, &ifr)) {
return EXIT_FAILURE;
}

u = (unsigned char *) &ifr.ifr_addr.sa_data;

if (u[0] + u[1] + u[2] + u[3] + u[4] + u[5]) {
printf("HW Address: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
u[0], u[1], u[2], u[3], u[4], u[5]);
}

return EXIT_SUCCESS;
}

--
Average Joe
Ilkka

2005-02-18, 4:40 am

Hi, that seems to work fine but you wouldn't happen to know how to get the MAC if you only know the IP of the interface?

I've tried it like this:

char mac[14];
char* a_ip_addr = "10.1.1.1";
struct ifreq ifr;
struct sockaddr_in* sin = (struct sockaddr_in*)&ifr.ifr_ifru.ifru_addr;
int sd = 0;
in_addr_t addr = inet_addr(a_ip_addr);

memset(&ifr, 0, sizeof ifr);
if ((sd=socket(PF_INET, SOCK_STREAM, 0))>0) {
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = addr;
if (0==ioctl(sd, SIOCGIFNAME, &ifr)) {
printf("%s: %s\n", inet_ntoa(sin->sin_addr), ifr.ifr_name);
}
ioctl(sd, SIOCGIFHWADDR, &ifr);
memcpy(mac, &ifr.ifr_ifru.ifru_hwaddr.sa_data, 14);

}

The trouble is that after the first ioctl, ifr.ifr_name always contains the name "eth0" no matter what interface's IP there was in sin->sin_addr. Also, mac contains the MAC of eth0. So what else do I need to do to get the MAC based on only the IP?
Ilkka

2005-02-18, 5:14 am

Well, it seems that it's pretty much impossible to do that with ioctls, since 'man 7 netdevice' helpfully says:

quote:
SIOCGIFNAME
Given the ifr_ifindex, return the name of the interface in
ifr_name. This is the only ioctl which returns its result in
ifr_name.

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com