/* getip.c
	This is a function to take an interface name and return just the	IP address.
*/
#define SUCCESS 0

#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h> /* for the ifreq sturct */
#include <stdlib.h>
#include <string.h>
#include <netdb.h>

int getip( char *, char *, size_t );

int getip( char *interface, char *ipaddr, size_t len )
{
/* init local stuff */
	int s, io, getname;
	struct ifreq flags;
	char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
	struct sockaddr *addr;
	
/* open a socket to do an ioctl on */
	s = socket( AF_INET, SOCK_DGRAM, 0 );
	if (s < 0) {
		perror( "socket failed" );
		return EXIT_FAILURE;
	}
/* set the interface name */
	strncpy( flags.ifr_name, interface, sizeof( flags.ifr_name ) );
/* now get the info */
	io = ioctl( s, SIOCGIFADDR, &flags );
	if (io < 0) {
		perror( "ioctl failed" );
		return EXIT_FAILURE;
	}
	
	addr = &flags.ifr_addr;
	getname = getnameinfo( addr, addr->sa_len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST );
	if (getname == 0) {
		strncpy( ipaddr, hbuf, len );
		return SUCCESS;
	} else {
		fprintf( stderr, "getnameinfo failed %s", gai_strerror(getname) );
		return getname;
	}
}

int main( int argc, char *argv[] ) {
	char addy[NI_MAXHOST]; /* ip addresses are this big */
	int ret; /* return code */

/* check for the correct number of inputs */
	if ( (argc > 2) || (argc == 1) ) {
		printf( "%s%s%s\n", "Usage: ", argv[0], " ifN" );
		return 1;
	}	
	ret = getip( argv[1], addy, sizeof(addy) );
	if ( ret == 0 ) {
		printf( "%s\n", addy );
		return ret;
	} else {
		perror( "problems with getip()" );
		return ret;
	}
}
