Skip site navigation (1)Skip section navigation (2)
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>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.

--------------63DECDAD62319AC452BFA1D7
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

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         |

--------------63DECDAD62319AC452BFA1D7
Content-Type: text/plain; charset=us-ascii; name="dumpifs.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="dumpifs.c"

#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);
}

--------------63DECDAD62319AC452BFA1D7
Content-Type: text/plain; charset=us-ascii; name="dumpifs.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="dumpifs.c"

#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);
}

--------------63DECDAD62319AC452BFA1D7--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?347A4367.6201DD56>