Date: Wed, 11 Dec 1996 12:16:05 -0800 From: Julian Elischer <julian@whistle.com> To: Rodrigo Ormonde <ormonde@trem.cnt.org.br> Cc: hackers@FreeBSD.ORG Subject: Re: Discovering network interfaces Message-ID: <32AF1685.41C67EA6@whistle.com> References: <9612111740.AA13674@trem.cnt.org.br>
next in thread | previous in thread | raw e-mail | index | archive | help
Rodrigo Ormonde wrote: > > Helo. > > I have to write a program to show the user the names of the currently > configured network interfaces. (something like netstat -in) > The problem is that I have no idea how this could be done inside a C program > (I don't want to execute a external program like netstat to do this. It'd be > nice if I could do it inside my C program). > > Does anybody know a function/system call which can be used to list the > network interfaces ? > > Any help will be apreciated. > > Please send answers to me, I'm not on the list. A Here's a little program that dumps out interfaces and their addresses (some of which you don't normally see) alter to your heart's content.. :) -cut here- #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); } /* EOF */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?32AF1685.41C67EA6>