/*======================================================================
                    N E T I N F O . C 
                    doc: Fri Jan 17 13:35:38 1992
                    dlm: Fri Jul 23 16:56:22 1993
                    (c) 1992 ant@julia
                    uE-Info: 20 19 T 0 0 72 2 2 8 ofnI
======================================================================*/

/*
   Note: Most of the stuff done in here can be found in manpage if(4n)
   	 If not, try if_tcp(7)
 */
 
#define ICBUFS	(1 + 10 * sizeof(struct ifreq))	/* interface request bufs */

#include	<stdio.h>
#include 	<sys/types.h>
#include	<sys/socket.h>
#include	<sys/ioctl.h>
#ifndef SIOCGIFCONF
#include	<sys/sockio.h>
#endif
#include	<net/if.h>
#include	<netinet/in.h>
#include	<arpa/inet.h>
#include	<stdio.h>
#include	<string.h>

main ()
{
	int 	sock,on=1,nif,i,found=0;
	char	icBuf[ICBUFS];
	struct	ifconf 	    ifc;
	struct 	ifreq	    *ifr;
	struct 	sockaddr_in sin;

	/* get udp socket */
	if ((sock = socket(AF_INET,SOCK_DGRAM,0)) < 0) {
		perror("socket");
		exit(1);
	}
	/* prepare for broadcast */
	if (setsockopt(sock,SOL_SOCKET,SO_BROADCAST,&on,sizeof(int)) < 0) {
		perror("setsockopt");
		exit(1);
	}
	/* get ALL interface configs */
	ifc.ifc_len = ICBUFS;
	ifc.ifc_buf = icBuf;
	if (ioctl(sock,SIOCGIFCONF,(char *)&ifc) < 0) {
		perror("ioctl");
		exit(1);
	}
	if (ifc.ifc_len == ICBUFS-1) 
		printf("Warning: buffer full; some interfaces may not be reported!\n");
	nif = ifc.ifc_len/sizeof(struct ifreq);
	
	/* now extract values */
	for (i=0,ifr = ifc.ifc_req; i<nif; i++,ifr++) {
		/* Only INET */
		if (ifr->ifr_addr.sa_family != AF_INET) continue;
		/* Get Flags */
		if (ioctl(sock,SIOCGIFFLAGS,(char *)ifr) < 0) {
			perror("ioctl");
			exit(1);
		}
		/* Skip worthless interfaces */
		if (((ifr->ifr_flags & IFF_UP) == 0) ||
		    ((ifr->ifr_flags & IFF_LOOPBACK) != 0) ||
		    ((ifr->ifr_flags &
			(IFF_BROADCAST | IFF_POINTOPOINT)) == 0)) continue;
		found++;
		memcpy((char *)&sin,
		       (char *)&ifr->ifr_addr,
		       sizeof sin);
		printf("Interface <%s>:\n",ifr->ifr_name);
		printf("\tLocal Address: %s\n",
			inet_ntoa(sin.sin_addr));
		/* bcast interface */
		if (ifr->ifr_flags & IFF_BROADCAST) {
			if (ioctl(sock,SIOCGIFBRDADDR,(char *)ifr) < 0) {
				perror("ioctl");
				exit(1);
			}
			found++;
	                memcpy((char *)&sin,
			       (char *)&ifr->ifr_addr,
	                       sizeof sin);
			printf("\tBroadcast Address: %s\n",
				inet_ntoa(sin.sin_addr));
                }
	}
	close(sock);
}

