Question How should I handle getting a pc's mac address since the machine is not always under the family name "eth0"

Status
Not open for further replies.

FredRdr88

Honorable
May 26, 2017
206
1
10,695
The program runs fine and gets me my hardware address. I'll post it sometime sorry, it's on another Linux machine, and I have to clean some commented out code, like 5 lines first.

But here's my question: I have to supply the & family and I had wanted "eth0" but I now realize that not all of my Linux machines store the address for "eth0" in a family with that name. It always starts with an e, but has a different set of characters after that. Could be that way for wlan too not sure. So using the ioctl system calls (wrappers over kernel) seems to be kind of superfluous. I seem to be doing most of the work because I first have to go out and get the weirder names of the address family I'm looking for. So should I just go back to a file fopen approach or does my approach have some advantages? I don't really care which method I use. Any opinions appreciated, thank you.
 
  • Like
Reactions: Neo-ConTrai

kanewolf

Titan
Moderator
The program runs fine and gets me my hardware address. I'll post it sometime sorry, it's on another Linux machine, and I have to clean some commented out code, like 5 lines first.

But here's my question: I have to supply the & family and I had wanted "eth0" but I now realize that not all of my Linux machines store the address for "eth0" in a family with that name. It always starts with an e, but has a different set of characters after that. Could be that way for wlan too not sure. So using the ioctl system calls (wrappers over kernel) seems to be kind of superfluous. I seem to be doing most of the work because I first have to go out and get the weirder names of the address family I'm looking for. So should I just go back to a file fopen approach or does my approach have some advantages? I don't really care which method I use. Any opinions appreciated, thank you.
Do you have multiple interfaces with IP addresses? If not the look at all the interfaces and get the one with an IP address that is not the loopback address.
 

FredRdr88

Honorable
May 26, 2017
206
1
10,695
Hi, thanks, in order to get an interface in the first place, I have to supply the correct address family which is in the /sys/class/net directory so I guess just fopen and read the names, then find the ones that aren't lo and aren't networking. But I have to supply the address family of each one I send to the ioctl command that I'm using. This will work, but is it overkill? I guess it's good to classify each one as MAC, Loopback, or Network. My function has to work in general. Most of my machines seem to have only those three types: MAC, Loopback or Network. Networks don't start with an e or an lo.

Hold on: I think I might know what the problem is: I might be confusing the name in the sys/class/net folder with the family name which has a #define. Maybe that's the problem, that's all.

Maybe I should family it with ARPHRD_ETHER and use the actual names that I've iterated from fopen? I think I've been using the name for the family and it works for some reason. Ah, wait a minute, for sa_family I used AF_INET (you could use PF_INET too I guess);
 
Last edited:

kanewolf

Titan
Moderator
Hi, thanks, in order to get an interface in the first place, I have to supply the correct address family which is in the /sys/class/net directory so I guess just fopen and read the names, then find the ones that aren't lo and aren't networking. But I have to supply the address family of each one I send to the ioctl command that I'm using. This will work, but is it overkill? I guess it's good to classify each one as MAC, Loopback, or Network. My function has to work in general. Most of my machines seem to have only those three types: MAC, Loopback or Network. Networks don't start with an e or an lo.

Hold on: I think I might know what the problem is: I might be confusing the name in the sys/class/net folder with the family name which has a #define. Maybe that's the problem, that's all.

Maybe I should family it with ARPHRD_ETHER and use the actual names that I've iterated from fopen? I think I've been using the name for the family and it works for some reason. Ah, wait a minute, for sa_family I used AF_INET (you could use PF_INET too I guess);
What language are you trying to do this with?
 

FredRdr88

Honorable
May 26, 2017
206
1
10,695
Last edited:

kanewolf

Titan
Moderator
It lists a lot but only gives version 6 info if the linux supports netlink. So I'll have to see if I can use it - namely, is it general and comprehesive?

https://man7.org/linux/man-pages/man7/address_families.7.html

I had never seen that function, looks interesting.
I didn't build that specific code, but I think you need to have code that will behave similar to ifconfig and provide a list of interfaces. Then iterate over that list and find all the interfaces that have a valid IP address. Report those MAC addresses, skipping the loopback address.
 

FredRdr88

Honorable
May 26, 2017
206
1
10,695
Here is some code to find all network interfaces -- https://www.cyberithub.com/list-network-interfaces/
Should be able to use that as a list to iterate over.

I will need to change a few things in the function as I need a different set of information but at least I have it running? The use of \t in one of the functions isn't working right for some reason and I also need the local machine address. On my machine, it doesn't even find that one. So I still cannot replace my own method.
Bascially, the method does NOT work.
 

FredRdr88

Honorable
May 26, 2017
206
1
10,695
Here's the basic piece of code I now have which gives use the names in the /sys/class/net directory.

I can then use those names in my ioctl piece of code, so it's coming along nicely now.
The only difference in my program is I'm not using EXIT_FAILURE tag.

Keep in mind though that the below code must be supplemented with some minor additional recursing down through
the name which is a directory and then get to the address file and read it in general. At that point, I likely would not even
need the ioctl calls anymore.

I might need to use the ifc_req field

I need to have code that works even if the network cable is unplugged. The socket will not work as a true socket on Ubuntu.

#include <sys/types.h> // readdir
#include <dirent.h> // opendir, readdir, closedir

DIR *dir;
struct dirent *ent;
if ((dir = opendir ("/sys/class/net")) != NULL) {
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL) {
printf ("%s\n", ent->d_name);
}
closedir (dir);
} else {
/* could not open directory */
perror ("");
return EXIT_FAILURE;
}
 
Last edited:

FredRdr88

Honorable
May 26, 2017
206
1
10,695
Here's one that's really nice.

#include <stdio.h>
#include <ifaddrs.h>
#include <netpacket/packet.h>

int main (int argc, const char * argv[])
{
struct ifaddrs *ifaddr=NULL;
struct ifaddrs *ifa = NULL;
int i = 0;

if (getifaddrs(&ifaddr) == -1)
{
perror("getifaddrs");
}
else
{
for ( ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
if ( (ifa->ifa_addr) && (ifa->ifa_addr->sa_family == AF_PACKET) )
{
struct sockaddr_ll s = (struct sockaddr_ll)ifa->ifa_addr;
printf("%-8s ", ifa->ifa_name);
for (i=0; i <s->sll_halen; i++)
{
printf("%02x%c", (s->sll_addr), (i+1!=s->sll_halen)?':':'\n');
}
}
}
freeifaddrs(ifaddr);
}
return 0;
}
 

kanewolf

Titan
Moderator
Here's one that's really nice.

#include <stdio.h>
#include <ifaddrs.h>
#include <netpacket/packet.h>

int main (int argc, const char * argv[])
{
struct ifaddrs *ifaddr=NULL;
struct ifaddrs *ifa = NULL;
int i = 0;

if (getifaddrs(&ifaddr) == -1)
{
perror("getifaddrs");
}
else
{
for ( ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
if ( (ifa->ifa_addr) && (ifa->ifa_addr->sa_family == AF_PACKET) )
{
struct sockaddr_ll s = (struct sockaddr_ll)ifa->ifa_addr;
printf("%-8s ", ifa->ifa_name);
for (i=0; i <s->sll_halen; i++)
{
printf("%02x%c", (s->sll_addr), (i+1!=s->sll_halen)?':':'\n');
}
}
}
freeifaddrs(ifaddr);
}
return 0;
}
The code example I referenced uses getifaddrs() also. That is the better implementation rather than using the /sys/ directory.
 

FredRdr88

Honorable
May 26, 2017
206
1
10,695
The code example I referenced uses getifaddrs() also. That is the better implementation rather than using the /sys/ directory.

I still have it running, I'll have to fix the bugs in it. The problem is just that it has bugs. So no Sys huh? Actually, the new one I have does NOT use/sys. It's ok, you can have the credit, but I'll keep my code.
 
Status
Not open for further replies.