This is a way to get MAC address of a network interface in C language.
Under GNU/Linux it can be done thanks to a RAW socket:
N.B.: All checks have been removed for better legibility, but it is very important to check returned code after each request.
// Consider a variable "networkInterfaceName" of type char * is defined ("eth0" for instance).
int sd;
struct ifreq ifr;
const unsigned char *hardwareAddress;
sd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
memset(&ifr, 0, sizeof(ifr));
setNameInIfreq(&ifr, networkInterfaceName);
hardwareAddress = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
close(sd);
Under Solaris, it begins to be less easy, we need to use DLPI code:
// Consider a variable "devicePath" of type char * is defined ("/dev/eth0" for instance).
int sd;
dl_phys_addr_req_t dlpareq;
dl_phys_addr_ack_t *dlpaack;
struct strbuf msg;
char buf[128];
int flags = 0;
const unsigned char *hardwareAddress;
sd = open(devicePath, O_RDWR));
dlpareq.dl_primitive = DL_PHYS_ADDR_REQ;
dlpareq.dl_addr_type = DL_CURR_PHYS_ADDR;
msg.buf = (char *)&dlpareq;
msg.len = DL_PHYS_ADDR_REQ_SIZE;
putmsg(sd, &msg, NULL, 0);
dlpaack = (dl_phys_addr_ack_t *)buf;
msg.buf = (char *)buf;
msg.len = 0;
msg.maxlen = sizeof (buf);
getmsg(sd, &msg, NULL, &flags);
memcpy(hardwareAddress, &buf[dlpaack->dl_addr_offset], dlpaack->dl_addr_length);
close(sd);
sharing knowledge earned into design/development/technical delicate and/or difficult situations ...
Labels
Gnu/Linux
(95)
Administration
(83)
StorageHardware
(17)
Programming
(16)
WebBrowser
(15)
General
(11)
GNU/Bash
(7)
Solaris
(7)
Virtualization
(7)
C
(6)
Domotics
(6)
Musics
(5)
Raspberry
(5)
Desktop
(4)
Java
(4)
VersionControlSystems
(4)
ArtificialIntelligence
(2)
Optimization
(2)
multimedia
(2)
Arduino
(1)
Electronics
(1)
LTS
(1)
MacOS
(1)
Mechanics
(1)
Processing
(1)
Robotics
(1)
Ubuntu
(1)
Upgrade
(1)
ez-robot
(1)
Hello! I hate to say this, but you are missing the vital lines of code that actually do something. You access the addr without ever having SET it. You must issue an ioctl command!
ReplyDeleteYou're right, there is no ioctl there.
ReplyDeleteUnder Solaris, the idea is to open a socket, to "put" a message thanks to a well defined structure and finally to get information from the message; there is no more need.
For GNU/Linux, I should have given the instructions of the setNameInIfreq function which set the structure. I'll update those explanations soonly.
Thanks for your remark.
Anyway, did those instructions help you ?