getmac : Retrieve physical MAC address on Solaris without being root
Download: getmac.c
Author: paulie
License: n/a
Description:
- Uses libdlpi and arp to obtain the MAC address of a given network interface
- Written in C
Download: getmac.c
Author: paulie
License: n/a
Description:
- Uses libdlpi and arp to obtain the MAC address of a given network interface
- Written in C
/*
* getmac.c
* Retrieves the MAC address for a given network interface on Solaris
* platforms using two methods: arp and dlpi. Please note that dlpi
* requires root to retrieve an address.
* Compile
* gcc getmac.c -o getmac -lsocket -ldlpi
* Run
* ./getmac <interface_name>
* Ex: ./getmac e1000g0
*
* Written by Paul Johnson
* paulie@pauliesworld.org
*/
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <libdlpi.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sockio.h>
static char*
get_physical_address_arp(char* nicname)
{
int i, j, sock, nicount;
char octet[3];
char* finaladdress;
struct arpreq arpreq;
struct ifreq nicnumber[24];
struct ifconf ifconf;
if ((sock=socket(AF_INET,SOCK_DGRAM,0)) > -1) {
ifconf.ifc_buf = (caddr_t)nicnumber;
ifconf.ifc_len = sizeof(nicnumber);
} else {
return("Could not create socket.");
}
if (!ioctl(sock,SIOCGIFCONF,(char*)&ifconf)) {
nicount = ifconf.ifc_len/(sizeof(struct ifreq));
for (i=0; i<=nicount; i++) {
if (!strcmp(nicnumber[i].ifr_name,nicname)) {
break;
}
if (i == (nicount-1)) {
close(sock);
return("No such interface.");
}
}
} else {
close(sock);
return("ioctl error.");
}
((struct sockaddr_in*)&arpreq.arp_pa)->sin_addr.s_addr=
((struct sockaddr_in*)&nicnumber[i].ifr_addr)->sin_addr.s_addr;
if (!(ioctl(sock,SIOCGARP,(char*)&arpreq))) {
finaladdress = (char*)malloc(48);
for (j=0; j<=5; j++) {
snprintf(octet,sizeof(octet),"%02x",
(unsigned char)arpreq.arp_ha.sa_data[j]);
strcat (finaladdress,octet);
}
close (sock);
return (finaladdress);
} else {
return ("Could not determine MAC address.");
}
}
static char*
get_physical_address_dlpi(char* nicname)
{
int i, physaddrlen=DLPI_PHYSADDR_MAX;
char octet[3];
char physaddr[DLPI_PHYSADDR_MAX];
char* finaladdress;
dlpi_handle_t dh;
if (dlpi_open(nicname, &dh, 0) != DLPI_SUCCESS) {
return("dlpi failure, are you root?");
}
if (dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR, physaddr, &physaddrlen) !=
DLPI_SUCCESS) {
dlpi_close(dh);
return("Could not retrieve physical address.");
}
finaladdress = (char*)malloc(48);
for (i=0; i<physaddrlen; i++) {
snprintf(octet,sizeof(octet),"%02x",(unsigned char)physaddr[i]);
strcat(finaladdress,octet);
}
dlpi_close(dh);
return(finaladdress);
}
int
main(int argc, char** argv)
{
char* physaddress_arp;
char* physaddress_dlpi;
if (argc != 2) {
printf("./getmac <interface>\n\n");
return 0;
}
physaddress_arp = get_physical_address_arp(argv[1]);
physaddress_dlpi = get_physical_address_dlpi(argv[1]);
printf("arp:\t%s\ndlpi:\t%s\n",physaddress_arp,physaddress_dlpi);
return(0);
}
