[comp.unix.wizards] Determining one's own IP address.

davem@bmers58.UUCP (Dave Mielke) (12/07/89)

How can one determine his own IP address without looking it up in the
hosts file? It must be in memory somewhere but there is no obvious
system call to retrieve it. I would appreciate any assistance that
anyone can give.

leadley@uhura.cc.rochester.edu (Scott Leadley) (12/09/89)

In article <601@bmers58.UUCP> davem@bnr-public.UUCP () writes:
>How can one determine his own IP address without looking it up in the
>hosts file?

	Assuming (a lot of things, but primarily that) you wish to do this from
the shell command line and that you know the network interface name:

	% ifconfig de0
		   ^^^ VAX-ism, substitute the correct name here
	de0: flags=63<UP,BROADCAST,NOTRAILERS,RUNNING>
		inet xxx.xxx.xxx.xxx netmask ffffff00 broadcast xxx.xxx.xxx.xxx

If you don't know what interfaces are connected to the machine try:

	% netstat -i
	Name  Mtu   Network     Address      Ipkts   Ierrs Opkts   O...
	de0   1500  x-net       x-machine    15890511 4     14812969...
	lo0   1536  127         localhost    134349  0     134349  0...
-- 
					Scott Leadley - leadley@cc.rochester.edu

envbvs@epb2.lbl.gov (Brian V. Smith) (12/10/89)

In article <4429@ur-cc.UUCP> leadley@uhura.cc.rochester.edu (Scott Leadley) writes:
< In article <601@bmers58.UUCP> davem@bnr-public.UUCP () writes:
< >How can one determine his own IP address without looking it up in the
< >hosts file?
< 
< 	Assuming (a lot of things, but primarily that) you wish to do this from
< the shell command line and that you know the network interface name:
< 
< 	% ifconfig de0
< 		   ^^^ VAX-ism, substitute the correct name here
[ more involved stuff deleted ]

If you have only one interface, how about:  arp `hostname`

--
_____________________________________
Brian V. Smith    (bvsmith@lbl.gov)
Lawrence Berkeley Laboratory
I don't speak for LBL, these non-opinions are all mine.

davem@bmers58.UUCP (Dave Mielke) (12/11/89)

In article <4429@ur-cc.UUCP> leadley@uhura.cc.rochester.edu (Scott Leadley) writes:
>	Assuming (a lot of things, but primarily that) you wish to do this from
>the shell command line and that you know the network interface name:
 
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.

mfg@castle.ed.ac.uk (M Gordon) (12/12/89)

In article <604@bmers58.UUCP> davem@bmers58.UUCP (Dave Mielke) writes:
>In article <4429@ur-cc.UUCP> leadley@uhura.cc.rochester.edu (Scott Leadley) writes:
>>	Assuming (a lot of things, but primarily that) you wish to do this from
>>the shell command line and that you know the network interface name:
> 
>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 shortened version of a program I wrote (This bit is very similar to
ifconfig). It prints out the addresses for all a machines interfaces. You
should have no trouble modifying it for what you want.

--------------------------------------------------------------------------------
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <stdio.h>

#define MAX_INTERFACES 10

main(argc,argv)
int argc;
char *argv[];
{
    struct ifconf ifc;
    struct ifreq *ifreq;
    struct sockaddr_in addr;
    char ifbuf[MAX_INTERFACES*sizeof(struct ifreq)];
    int s,n,i;

    s=socket(AF_INET,SOCK_STREAM,0);

    ifc.ifc_len=sizeof(ifbuf);
    ifc.ifc_buf=ifbuf;

    if (ioctl(s,SIOCGIFCONF,&ifc)==-1)
	exit(1);

    for (n=ifc.ifc_len/sizeof(struct ifreq),ifreq=ifc.ifc_req;n>0;n--,ifreq++)
    {
        bcopy(ifreq->ifr_addr.sa_data,&addr.sin_port,14);
        printf("%s at %-18s ",ifreq->ifr_name,inet_ntoa(addr.sin_addr));
    }
}
--------------------------------------------------------------------------------


Michael
-- 
Michael Gordon - mfg@uk.ac.ed.castle OR mfg@uk.ac.ed.ee

You can't have everything - where would you put it? -- Steven Wright 

parmelee@wayback.cs.cornell.edu (Larry Parmelee) (12/12/89)

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

mb@rex.cs.tulane.edu (Mark Benard) (12/12/89)

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.

There is a library function gethostbyname() that will provide what you
want.  Below is a sample (but, sorry, undocumented) short C program that
uses to get the IP address given a full domain name.  You can shorten it
and hard-code your own host name into it.

Mark
----

/* gethostbyname : to get the IP address of the host */
/*          m. benard 11/88                          */

#include <stdio.h>
#include <netdb.h>

extern int h_errno;    /* needed for Pyramid OSx */

main(argc, argv)
int argc;
char *argv[];
{
    struct hostent *entp;
    unsigned char a, b, c, d;

    if (argc == 1) {
	printf ("Usage: gethostbyname host-name\n");
	exit();
	}
    entp = gethostbyname (argv[1]);
    if (entp <= 0) {
	if (h_errno == HOST_NOT_FOUND) {
	    printf ("Host not found\n");
	    exit();
	    }
	else if (h_errno == TRY_AGAIN) {
		printf ("No response from Internet nameserver.  Try again later.\n");
		exit();
		}
	     else {
		 printf ("Error %d\n", h_errno);
		 exit();
		 }
	}
    a = *((entp->h_addr)+0);
    b = *((entp->h_addr)+1);
    c = *((entp->h_addr)+2);
    d = *((entp->h_addr)+3);
    printf ("IP address: %u.%u.%u.%u\n", a, b, c, d);
    }
-- 
Mark Benard
Department of Computer Science     INTERNET & BITNET: mb@cs.tulane.edu
Tulane University                  USENET:   rex!mb
New Orleans, LA 70118

chris@mimsy.umd.edu (Chris Torek) (12/13/89)

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.

Since your machine might have anywhere from zero to several hundred
official IP addresses, this is not possible.

The closest thing there is to `myself' is 127.0.0.1, which (I think)
has now been officially reserved to mean `loopback' or `connect to
myself'.

4BSD provides a `gethostid' call, but what you get is not necessarily
a valid IP address.  Since we had never set our hostid under 4.2BSD
(setting it to zero, in effect), I am fairly sure that nothing in 4.2BSD
actually used it.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

archer@elysium.sgi.com (Archer Sully) (12/13/89)

> example using gethostbyname(3) deleted <

gethostbyname(3) consults /etc/hosts (and yp if you have it), so it isn't what
the original poster wanted.

Archer Sully 	  | A Mind is a Terrible thing to Taste
(archer@sgi.com)  |		- Ministry

terryl@tekcrl.LABS.TEK.COM (12/13/89)

In article <604@bmers58.UUCP> davem@bmers58.UUCP (Dave Mielke) writes:
>In article <4429@ur-cc.UUCP> leadley@uhura.cc.rochester.edu (Scott Leadley) writes:
>>	Assuming (a lot of things, but primarily that) you wish to do this from
>>the shell command line and that you know the network interface name:
> 
>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.


     Well, as they say (whoever THEY are!! (-:), RTFM (at least for a BSD
system):

	sethostid(2), gethostid(2), hostid(1)

steved@longs.LANCE.ColoState.Edu (Steve Dempsey) (12/13/89)

 
> > 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...

[Larry's program deleted]

If you have a decent RPC implementation on your system, you can use
get_myaddress().  This works on Ultrix3.[01], HPUX 6.[25], SunOS4.0,
and 4.3BSD (at least):


#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

main()
{
struct sockaddr_in me;

    get_myaddress(&me);

    fprintf(stderr,"local IP address = %u.%u.%u.%u\n",
        ((unsigned char*)  & me.sin_addr.s_addr)[0],
        ((unsigned char*)  & me.sin_addr.s_addr)[1],
        ((unsigned char*)  & me.sin_addr.s_addr)[2],
        ((unsigned char*)  & me.sin_addr.s_addr)[3]);
}

Of course you only get one interface address, usually the first one to be
configured via ifconfig(8).

> parmelee@cs.cornell.edu

        Steve Dempsey,  Center for Computer Assisted Engineering
  Colorado State University, Fort Collins, CO  80523    +1 303 491 0630
INET: steved@longs.LANCE.ColoState.Edu, dempsey@handel.CS.ColoState.Edu
UUCP: boulder!ccncsu!longs.LANCE.ColoState.Edu!steved, ...!ncar!handel!dempsey

gnb@bby.oz.au (Gregory N. Bond) (12/13/89)

In article <5215@tekcrl.LABS.TEK.COM> terryl@tekcrl.LABS.TEK.COM writes:

	Well, as they say (whoever THEY are!! (-:), RTFM (at least for a BSD
   system):

	   sethostid(2), gethostid(2), hostid(1)

Not on suns.  The hostid is set in a prom, and has nothing to do with
ip address.  Things like mathematica use it for compy protection.

Greg.
--
Gregory Bond, Burdett Buckeridge & Young Ltd, Melbourne, Australia
Internet: gnb@melba.bby.oz.au    non-MX: gnb%melba.bby.oz@uunet.uu.net
Uucp: {uunet,pyramid,ubc-cs,ukc,mcvax,prlb2,nttlab...}!munnari!melba.bby.oz!gnb

jonathan@cs.keele.ac.uk (Jonathan Knight) (12/13/89)

From article <5215@tekcrl.LABS.TEK.COM>, by terryl@tekcrl.LABS.TEK.COM:
> 
>      Well, as they say (whoever THEY are!! (-:), RTFM (at least for a BSD
> system):
> 
> 	sethostid(2), gethostid(2), hostid(1)

Ok, I did 'man hostid' and it says...

                      This numeric value is expected to be unique
     across all hosts and is normally set to the host's Internet
     address.

Note that it says 'normally' so you can't assume it will be.  This is
for an Ultrix 1.2 vax.  A sun of course is different, the hostid is
encoded in the ROM at the factory and can't be changed, so it's just
a "number that's unique accross all sun hosts." (sun manual)

The program 'ifconfig' will give you the IP address for your host.
The output formats vary a little, but it seems consistent for getting
the IP address out.  (e.g.  'ifconfig qe0' or 'ifconfig le0' or
'ifconfig ie0' depending on your interface name)

I have never tried to get the IP address for an interface from within
a C program however here are a few manual pages that should put you on
the right track.

On Sun.
	man 4n if
	man 4n routing

On Ultrix
	man 4n intro
-- 
  ______    JANET :jonathan@uk.ac.keele.cs     Jonathan Knight,
    /       BITNET:jonathan%cs.kl.ac.uk@ukacrl Department of Computer Science
   / _   __ other :jonathan@cs.keele.ac.uk     University of Keele, Keele,
(_/ (_) / / UUCP  :...!ukc!kl-cs!jonathan      Staffordshire.  ST5 5BG.  U.K.

terryl@tekcrl.LABS.TEK.COM (12/14/89)

In article <GNB.89Dec13170734@baby.bby.oz.au> gnb@bby.oz.au (Gregory N. Bond) writes:
>In article <5215@tekcrl.LABS.TEK.COM> terryl@tekcrl.LABS.TEK.COM writes:
>
>	Well, as they say (whoever THEY are!! (-:), RTFM (at least for a BSD
>   system):
>
>	   sethostid(2), gethostid(2), hostid(1)
>
>Not on suns.  The hostid is set in a prom, and has nothing to do with
>ip address.  Things like mathematica use it for compy protection.


     Guilty as charged. I have never used a Sun in my life (gotta toe the
company line and use our own workstations, ya know!!! (-:), and probably
never will use a Sun.....

Help
Stamp
Out
Fascist
News
Software
!!!!
!!!!

cmf@obie.cis.pitt.edu (Carl M. Fongheiser) (12/14/89)

In article <4429@ur-cc.UUCP> leadley@uhura.cc.rochester.edu (Scott Leadley) writes:
>If you don't know what interfaces are connected to the machine try:
>
>	% netstat -i
>	Name  Mtu   Network     Address      Ipkts   Ierrs Opkts   O...
>	de0   1500  x-net       x-machine    15890511 4     14812969...
>	lo0   1536  127         localhost    134349  0     134349  0...

Yep, and if you do "netstat -in", you won't even need to run ifconfig,
since netstat will print out the address without turning it into a name.

				Carl Fongheiser
				cmf@unix.cis.pitt.edu
				cmf@pittunix.BITNET
>-- 
>					Scott Leadley - leadley@cc.rochester.edu

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (12/14/89)

In article <21146@unix.cis.pitt.edu> cmf@obie.cis.pitt.edu (Carl M. Fongheiser) writes:
: Yep, and if you do "netstat -in", you won't even need to run ifconfig,
: since netstat will print out the address without turning it into a name.

Truncated for your convenience to 12 chars.

Larry Wall
lwall@jpl-devvax.jpl.nasa.gov

micky@cunixc.cc.columbia.edu (Micky Liu) (12/14/89)

I have to admit that I have not been following the whole story here, but
if you are attempting to determine the IP address of a machine, then I think
the correct method is to use an ioctl() call to request information on all
of the connected network interfaces (since a machine can be multi-homed).
The next step is to examine the list of interfaces returned and look for
the IP address assigned to each physical network interface.  I have only
had experience with Sun's so this may be machine specific, but I think
conceptually it should be the same on all Unix machines...

The important structures are:

     struct ifconf ifc;
     struct ifreq  *ifr;

both of which I think can be found in /usr/include/net/if.h.  The particular
ioctl() call looks like:

     ioctl(socket,SIOCGIFCONF,(char*)&ifc)

Then there will be a list of structures that can accesses with

     ifr = ifc.ifc_req;

Much of this information can be found in the SunOS 4.x Network Programmer's
Manual, Chapter 9 -- An Advanced Socket-Based Interprocess Communications
Tutorial.  The example they use will find broadcast addresses for each
network interface, but the method can be readily adapted to find the
IP address of each interface.

Good Luck!

Micky

internet: micky@cunixc.cc.columbia.edu
  usenet: ...!rutgers!columbia!cunixc!micky
  bitnet: micky@cunixc.bitnet

davem@bmers58.UUCP (Dave Mielke) (12/15/89)

I thank you all for your responses and mail. The solution that works,
i.e. the one which yields the local IP address without looking in the
hosts file or yp is as follows:
     
    struct sockaddr_in address;
    get_myaddress(&address);
    return address.sin_addr;

cmf@obie.cis.pitt.edu (Carl M. Fongheiser) (12/16/89)

In article <6591@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:
>In article <21146@unix.cis.pitt.edu> cmf@obie.cis.pitt.edu (Carl M. Fongheiser) writes:
>: Yep, and if you do "netstat -in", you won't even need to run ifconfig,
>: since netstat will print out the address without turning it into a name.
>
>Truncated for your convenience to 12 chars.

Yikes.  Well, *mine* doesn't truncate to 12 chars.  So, for the benefit
for those who may care, *if* you are running Ultrix 3.0 or 3.1 on
a Vax (don't have a PMAX handy), "netstat -in" will show your IP address
without truncating.  Others probably better check their output, and use
ifconfig if necessary.

					Carl Fongheiser
					cmf@unix.cis.pitt.edu