parmelee@wayback.cs.cornell.edu (Larry Parmelee) (12/12/89)
Archive-name: iflist Original-posting-by: parmelee@wayback.cs.cornell.edu (Larry Parmelee) Original-subject: Re: Determining one's own IP address. Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti) [This is an experimental alt.sources re-posting from the newsgroup(s) comp.unix.wizards. Comments on this service to emv@math.lsa.umich.edu (Edward Vielmetti).] In article <604@bmers58.UUCP> davem@bmers58.UUCP (Dave Mielke) writes: > I would like to be able to determine my local IP address without > involving a hosts file or yp lookup, i.e. from memory, from within a c > program. Here's a little program that should do it for 4.3BSD systems. Enjoy. -Larry Parmelee parmelee@cs.cornell.edu -----Cut here----- #include <stdio.h> #include <sys/types.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <net/route.h> #include <net/if.h> #include <netinet/in.h> #include <arpa/inet.h> #ifdef vax #include <netns/ns.h> extern char *ns_ntoa(); #endif extern int errno; extern int sys_nerr; extern char *sys_errlist[]; #define ERR_TXT(z) (z<sys_nerr?sys_errlist[z]:"Unknown error") #define ERRMSG ERR_TXT(errno) extern char *malloc(); #define MAXIF 20 /* Maximum number of interfaces expected */ struct ifreq * getiflist() { register int sd; register char *buf; struct ifconf ifc; register struct ifreq *rval = (struct ifreq *)0; #define SIZE (MAXIF * sizeof (struct ifreq)) if ((sd = socket(PF_INET,SOCK_DGRAM,0)) < 0) (void) fprintf(stderr,"getiflist: socket: %s\n",ERRMSG); else { if ( !(buf = malloc(SIZE+4))) (void) fprintf (stderr,"getiflist: malloc(%d) failed\n", SIZE+4); else { ifc.ifc_len = SIZE; ifc.ifc_buf = buf; if (ioctl(sd,SIOCGIFCONF,(char *) &ifc) == -1) { (void)fprintf (stderr, "getiflist: ioctl(SIOCGIFCONF): %s\n", ERRMSG); free(buf); } else { rval=ifc.ifc_req; buf = (char *) rval + ifc.ifc_len; bzero(buf,4); /* set end marker */ } } (void) close(sd); } return rval; } /* From /usr/include/sys/socket.h */ char *af_txt[] = { "AF_UNSPEC: unspecified", "AF_UNIX: local to host (pipes, portals)", "AF_INET: internetwork: UDP, TCP, etc.", "AF_IMPLINK: arpanet imp addresses", "AF_PUP: pup protocols: e.g. BSP", "AF_CHAOS: mit CHAOS protocols", "AF_NS: XEROX NS protocols", "AF_NBS: nbs protocols", "AF_ECMA: european computer manufacturers", "AF_DATAKIT: datakit protocols", "AF_CCITT: CCITT protocols, X.25 etc", "AF_SNA: IBM SNA", "AF_DECnet: DECnet", "AF_DLI: Direct data link interface", "AF_LAT: LAT", "AF_HYLINK: NSC Hyperchannel", "AF_APPLETALK: Apple Talk", /* AF_MAX */ "Address family: Value out of range" }; #define AF_TXT(z) (af_txt[((unsigned)z<AF_MAX)?(unsigned)z:AF_MAX]) /* * Putsockaddr: Print formatted info about a "struct sockaddr". */ void putsockaddr(sock) struct sockaddr *sock; { (void)printf (" address family %d %s\n",sock->sa_family, AF_TXT(sock->sa_family)); switch (sock->sa_family) { case AF_UNSPEC: break; case AF_INET: { struct sockaddr_in *sin = (struct sockaddr_in *) sock; (void)printf (" %s\tport %d\t", inet_ntoa(sin->sin_addr), htons(sin->sin_port)); if (sin->sin_addr.s_addr == htonl((u_long)INADDR_LOOPBACK)) (void)printf("(INADDR_LOOPBACK)"); else if (sin->sin_addr.s_addr == htonl((u_long)INADDR_ANY)) (void)printf("(INADDR_ANY)"); else if (sin->sin_addr.s_addr == htonl((u_long)INADDR_BROADCAST)) (void)printf("(INADDR_BROADCAST)"); (void)printf ("\n"); } break; #ifdef vax case AF_NS: { struct sockaddr_ns *sns = (struct sockaddr_ns *) sock; (void)printf (" %s\n", ns_ntoa(sns->sns_addr)); } break; #endif default: (void)printf ("Don't know how to format this type sockaddr.\n"); } } void putiflist(ifr) register struct ifreq *ifr; { for ( ; *ifr->ifr_name; ifr++) { (void)printf("interface %s\n",ifr->ifr_name); putsockaddr(&ifr->ifr_addr); (void)printf("\n"); } } main() { struct ifreq *rval; rval=getiflist(); if (rval != 0) { putiflist(rval); free((char *) rval); } }