ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi group,
I would like, from a C program, find the hardware MAC address of the default route path. With BASH I can do a 'route' find 'default and then an ifconfig and grep for 'HWaddr'. Are there C calls to do the same??
If you don’t want to use the special network interface socket ioctls, all the information you want is already available in the /proc or /sys virtual filesystem. You can read /proc/net/route to get the interface for the default route, and later read /sys/class/net/%s/address, where you put in the name of the interface you found earlier.
If you don’t want to use the special network interface socket ioctls, all the information you want is already available in the /proc or /sys virtual filesystem. You can read /proc/net/route to get the interface for the default route, and later read /sys/class/net/%s/address, where you put in the name of the interface you found earlier.
There really isn’t any portable way to do MAC address enumeration. In fact, ioctl() is not “pure C” but rather POSIX. Moreover the various socket ioctls are not standardized in their name or arguments (interface naming itself is not portable). In various unices, you might use SIOCGIFHWADDR, SIOCGIFMAC, SIOCRPHYSADDR, or something else entirely like the function getifaddrs().
I believe in linux, the preferred method is not to use the ioctl() at all (this has been somewhat deprecated), but to use a netlink socket.
I just presented my solution (which, btw happens to be implementable in “pure C” with fopen() and fread()) because it was in line with the OP’s original idea of getting the default route interface from a procfile.
Any real world code to find a MAC address portably will be riddled with #ifdefs.
The program serves me well, but does anyone here suggest a better alternative to ioctl() with SIOCSIFHWADDR?
IMO ioctl() is fine for such uses (when you know the interface name, and only want to find its MAC address).
In other, more complicated cases, and alternative would be to use netlink sockets with the NETLINK_ROUTE protocol. Using netlink to get the MAC address when you already know the interface name is like killing a fly with a sledgehammer.
In other cases (perhaps one relevant to the OP), you are most likely doing more than one MAC address lookup if you have some network device code. Here, using netlink makes more sense, because instead of using disparate methods to get your information (e.g., reading from /proc/net/route and then using SIOCSIFHWADDR), you have a single, more robust method.
If I have time later I will post an example where it is better (or at least more elegant) to use netlink rather than socket ioctls.
Well, um, no, that's not the thrust of my question. SIOCSIFHWADDR is used to set the MAC address, not to find it. :)
I misread the S as a G :D. In any case, the statement still stands. There are (basically) two methods of changing the MAC address: using the socket ioctl and using rtnetlink. In most situations, the second case is like using a sledgehammer to kill a fly (it works but is way more than needed).
So I would recommend to stick with SIOCSIFHWADDR, unless your program makes extensive use of low-level network maniuplation, which can be encompassed in rtnetlink calls.
As you can see, using the socket ioctl is very short and clean. However, you must use an entirely separate type of operation to find the name of the default route interface (namely the reading and parsing the procfile).
The rtnetlink method is long and bulky (requiring separate functions to simplify the logic). It could possibly be refactored (to reduce some of the code duplication) but not by much. However, if your code makes more extensive use of the routing table or other rtnetlink interfaces, it might end up being more elegant than an equivalent reading/parsing or the procfile.
Bottom line, most of the time socket ioctls are the best choice, but it all depends on what else your program is supposed to do.
Last edited by osor; 05-19-2009 at 04:01 PM.
Reason: removed 3 lines of unneccesary code
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.