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>