Determining one's own IP address.

Larry Parmelee parmelee at wayback.cs.cornell.edu
Wed Dec 13 01:32:18 AEST 1989


In article <604 at bmers58.UUCP> davem at 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 at 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);
	}
}



More information about the Comp.unix.wizards mailing list