Date: Mon, 24 Nov 1997 19:17:59 -0800 From: Julian Elischer <julian@whistle.com> To: Jim Carroll <jim@carroll.com> Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: Retrieve ethernet mac address Message-ID: <347A4367.6201DD56@whistle.com> References: <Pine.BSD.3.91.971124201015.32350Y-100000@apollo.carroll.com>
index | next in thread | previous in thread | raw e-mail
[-- Attachment #1 --]
The following snippet dumps ALL the addresses of all the interfaces.
the LINK address contains the MAC address in there.
you'll have to dig it out..
Jim Carroll wrote:
>
> Could someone point me towards how to retrieve an ethernet mac address from
> user-land code ? If it matters, we are running 2.2.1
>
> If someone has a working snippet, I would be grateful. A good pointer
> towards a FAQ or doc would also be helpful.
>
> I have been staring at netstat and ifconfig source for a few hours, but am
> having trouble making heads or tails. netstat usese kvm() and ifconfig uses
> sysctl(). I can't find enough docs of either method to get my head around
> what is needed to just extract mac address.
>
> Thanks
>
> ---
> Jim C., President | C A R R O L L - N E T, Inc.
> 201-488-1332 | New Jersey's Premier Internet Service Provider
> www.carroll.com |
[-- Attachment #2 --]
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/syslog.h>
#include <sys/param.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void showbytes(unsigned char *cptr,int len)
{
int i,j;
for (j = 0 ;len > 0 ;j++) {
for ( i = 0; i < 16; i++) {
printf("0x%x ",*cptr++);
if (--len == 0) break;
}
printf("\n");
}
}
void print_sa (struct sockaddr *sap)
{
char buf[128];
printf("len=%d,",sap->sa_len);
switch(sap->sa_family) {
case AF_LINK:
printf(" family=LINK\n");
{
char *cptr;
struct sockaddr_dl *sdl = (struct sockaddr_dl *)sap;
cptr = sdl->sdl_data;
printf("index=%u, type=%u ",
sdl->sdl_index,
sdl->sdl_type);
printf("nlen=%u, alen=%u, slen=%u\n",
sdl->sdl_nlen,
sdl->sdl_alen,
sdl->sdl_slen);
if(sdl->sdl_nlen) {
bcopy(cptr,buf,sdl->sdl_nlen);
buf[sdl->sdl_nlen] = 0;
printf(" name = %s\n",buf);
cptr += sdl->sdl_nlen;
}
if(sdl->sdl_alen) {
printf(" address = ");
showbytes(cptr,sdl->sdl_alen);
cptr += sdl->sdl_alen;
}
if(sdl->sdl_slen) {
printf(" selector = ");
showbytes(cptr,sdl->sdl_slen);
cptr += sdl->sdl_slen;
}
}
break;
case AF_INET:
printf(" family=INET\n");
printf("[%s]",
inet_ntoa(((struct sockaddr_in *)sap)->sin_addr));
printf(".%hu\n",((struct sockaddr_in *)sap)->sin_port);
break;
default:
printf(" family=%d\n",sap->sa_family);
showbytes(sap->sa_data,sap->sa_len-2);
}
}
/*
* Get the configuration from the kernel. Only called if there's no
* configuration.
*/
void getifconf( void )
{
struct ifconf ifc;
struct ifreq ifrs[ 64 ], *ifr, *nextifr;
struct interface *iface, *niface;
int s;
struct sockaddr *sa_p;
int ifrsize = 0;
bzero(&ifc,sizeof(struct ifconf));
bzero(ifrs,sizeof(struct ifreq) * 64);
if (( s = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
perror( "socket" );
exit( 1 );
}
ifc.ifc_len = sizeof( ifrs );
ifc.ifc_buf = (caddr_t)ifrs;
if ( ioctl( s, SIOCGIFCONF, &ifc ) < 0 ) {
perror( "getifconf" );
exit( 1 );
}
for ( ifr = ifc.ifc_req; ifc.ifc_len >= sizeof( struct ifreq );
ifr = nextifr, ifc.ifc_len -= ifrsize) {
/*
* in BSD4.4, this returns an entry for every address
* Associated with the if. including physical.. they
* include a sockaddr which is VARIABLE LENGTH!
*
* Calculate the length of this entry.
*/
sa_p = &(ifr->ifr_addr);
print_sa(&(ifr->ifr_addr));
/* print_sa(&(ifr->ifr_dstaddr));
print_sa(&(ifr->ifr_broadaddr)); */
ifrsize = IFNAMSIZ + sa_p->sa_len;
nextifr = (struct ifreq *)((caddr_t)ifr + ifrsize);
/*
* Now get it's flags
*/
if ( ioctl( s, SIOCGIFFLAGS, ifr ) < 0 ) {
perror( ifr->ifr_name );
exit( 1 );
}
printf("FLAGS = 0x%x\n",(unsigned short)ifr->ifr_flags);
printf("\n");
}
if ( ifc.ifc_len != 0 ) {
fprintf( stderr, "Funky gifconf return.\n" );
exit( 1 );
}
(void)close( s );
return;
}
main()
{
getifconf();
exit(0);
}
[-- Attachment #3 --]
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/syslog.h>
#include <sys/param.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void showbytes(unsigned char *cptr,int len)
{
int i,j;
for (j = 0 ;len > 0 ;j++) {
for ( i = 0; i < 16; i++) {
printf("0x%x ",*cptr++);
if (--len == 0) break;
}
printf("\n");
}
}
void print_sa (struct sockaddr *sap)
{
char buf[128];
printf("len=%d,",sap->sa_len);
switch(sap->sa_family) {
case AF_LINK:
printf(" family=LINK\n");
{
char *cptr;
struct sockaddr_dl *sdl = (struct sockaddr_dl *)sap;
cptr = sdl->sdl_data;
printf("index=%u, type=%u ",
sdl->sdl_index,
sdl->sdl_type);
printf("nlen=%u, alen=%u, slen=%u\n",
sdl->sdl_nlen,
sdl->sdl_alen,
sdl->sdl_slen);
if(sdl->sdl_nlen) {
bcopy(cptr,buf,sdl->sdl_nlen);
buf[sdl->sdl_nlen] = 0;
printf(" name = %s\n",buf);
cptr += sdl->sdl_nlen;
}
if(sdl->sdl_alen) {
printf(" address = ");
showbytes(cptr,sdl->sdl_alen);
cptr += sdl->sdl_alen;
}
if(sdl->sdl_slen) {
printf(" selector = ");
showbytes(cptr,sdl->sdl_slen);
cptr += sdl->sdl_slen;
}
}
break;
case AF_INET:
printf(" family=INET\n");
printf("[%s]",
inet_ntoa(((struct sockaddr_in *)sap)->sin_addr));
printf(".%hu\n",((struct sockaddr_in *)sap)->sin_port);
break;
default:
printf(" family=%d\n",sap->sa_family);
showbytes(sap->sa_data,sap->sa_len-2);
}
}
/*
* Get the configuration from the kernel. Only called if there's no
* configuration.
*/
void getifconf( void )
{
struct ifconf ifc;
struct ifreq ifrs[ 64 ], *ifr, *nextifr;
struct interface *iface, *niface;
int s;
struct sockaddr *sa_p;
int ifrsize = 0;
bzero(&ifc,sizeof(struct ifconf));
bzero(ifrs,sizeof(struct ifreq) * 64);
if (( s = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
perror( "socket" );
exit( 1 );
}
ifc.ifc_len = sizeof( ifrs );
ifc.ifc_buf = (caddr_t)ifrs;
if ( ioctl( s, SIOCGIFCONF, &ifc ) < 0 ) {
perror( "getifconf" );
exit( 1 );
}
for ( ifr = ifc.ifc_req; ifc.ifc_len >= sizeof( struct ifreq );
ifr = nextifr, ifc.ifc_len -= ifrsize) {
/*
* in BSD4.4, this returns an entry for every address
* Associated with the if. including physical.. they
* include a sockaddr which is VARIABLE LENGTH!
*
* Calculate the length of this entry.
*/
sa_p = &(ifr->ifr_addr);
print_sa(&(ifr->ifr_addr));
/* print_sa(&(ifr->ifr_dstaddr));
print_sa(&(ifr->ifr_broadaddr)); */
ifrsize = IFNAMSIZ + sa_p->sa_len;
nextifr = (struct ifreq *)((caddr_t)ifr + ifrsize);
/*
* Now get it's flags
*/
if ( ioctl( s, SIOCGIFFLAGS, ifr ) < 0 ) {
perror( ifr->ifr_name );
exit( 1 );
}
printf("FLAGS = 0x%x\n",(unsigned short)ifr->ifr_flags);
printf("\n");
}
if ( ifc.ifc_len != 0 ) {
fprintf( stderr, "Funky gifconf return.\n" );
exit( 1 );
}
(void)close( s );
return;
}
main()
{
getifconf();
exit(0);
}
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?347A4367.6201DD56>
