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