File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / usr / src / etc / nstat / arptab.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:24:30 2019 UTC (7 years ago) by root
Branches: bsd, MAIN
CVS tags: v121, HEAD
Power 6/32 Unix version 1.21

#ifndef lint
static char sccsid[] = "@(#)if.c	4.4 82/11/14";
#endif

#include <sys/types.h>
#include <sys/socket.h>

#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <tahoeif/if_enp.h>
#include <tahoeif/if_acereg.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <strings.h>
#include <errno.h>
#include <nlist.h>

#include <stdio.h>
#include "nstat.h"


/*
 * Internet to ethernet address resolution table.
 */
struct	arptab {
	struct	in_addr at_iaddr;	/* internet address */
	u_char	at_enaddr[6];		/* ethernet address */
	struct	mbuf *at_hold;		/* last packet until resolved/timeout */
	u_char	at_timer;		/* minutes since last reference */
	u_char	at_flags;		/* flags */
};
/* at_flags field values */
#define	ATF_INUSE	1		/* entry in use */
#define ATF_COM		2		/* completed entry (enaddr valid) */

#define	ARPTAB_BSIZ	5		/* bucket size */
#define	ARPTAB_NB	19		/* number of buckets */
#define	ARPTAB_SIZE	(ARPTAB_BSIZ * ARPTAB_NB)

#define ACE	0			/* ace driver type	*/
#define ENP	1			/* enp driver type	*/


struct	nlist	arptabnl[] = {
#				define	N_ARPTAB	0
	{ "_arptab" },
#				define	N_NUMACE	1
	{ "_numace" },
#				define	N_NUMENP	2
	{ "_numenp" },
#				define	N_ACESOFTC	3
	{ "_ace_softc" },
#				define	N_ENPSOFTC	4
	{ "_enp_softc" },
	{ "" },
};
extern	int	kmem;
extern	char	*system;
extern	struct	ace_softc	acesoftc[];
extern	struct	enp_softc	enpsoftc[];
extern	int	s;				/* socket id	*/
char	what_host[] = "NOT in /etc/hosts";

/*
 * Print a description of the network interfaces.
 */

arptab()
{
	static  off_t	arptabaddr,
			numaceaddr,
			numenpaddr,
			enpsoftcaddr,
			acesoftcaddr;

	struct arptab arp_tab[ARPTAB_SIZE];
	struct arptab *at = arp_tab;
    	struct hostent *h;
	char	hostname[64];
	static	int getvm = 0;
	int i, num, dontrepeat = 0;


	if (!getvm) {
		nlist(system, arptabnl);
		arptabaddr = arptabnl[N_ARPTAB].n_value;
		numaceaddr = arptabnl[N_NUMACE].n_value;
		numenpaddr = arptabnl[N_NUMENP].n_value;
		acesoftcaddr = arptabnl[N_ACESOFTC].n_value;
		enpsoftcaddr = arptabnl[N_ENPSOFTC].n_value;
		if (arptabaddr == 0 || numaceaddr == 0 || numenpaddr == 0 ||
	    	    acesoftcaddr == 0 || enpsoftcaddr == 0) {
		    printf("arptab: symbol not defined\n");
		    return;
	        }
		++getvm;
	}
	printf("%-20s %-15.10s %-10.10s","Hostname","Internet","Ethernet");
	putchar('\n');

/* Search for its own Ethernet Addresses	*/

	klseek(kmem, numaceaddr, 0);
	read(kmem, (char *)&num, sizeof (int));
	if ( num ) { 	/* if there is any ace	*/
		klseek(kmem, acesoftcaddr, 0);
		read(kmem, acesoftc, sizeof (struct ace_softc)*num);
		while (--num >= 0) {
			struct ace_softc *is = &acesoftc[num];
			struct ifnet	*ifp = &is->is_if;

			if (ifp->if_flags & IFF_RUNNING) {/*is it operating ?*/

        		   gethostname(hostname, sizeof(hostname));
  			   h = gethostbyname(hostname);
		    	   output(h, h->h_addr, is->is_addr); 
			   if (ifp->if_flags & IFF_NOARP) 
					continue;
			   if (dontrepeat < 5) {
			   	whoisup(ifp);
				dontrepeat++;
			   }
			}
		}	
	} 

	klseek(kmem, numenpaddr, 0);
	read(kmem, (char *)&num, sizeof (int));

	if ( num ) { 	/* if there is any enp	*/
		klseek(kmem, enpsoftcaddr, 0);
		read(kmem, enpsoftc, sizeof(struct enp_softc)*num);
		while (--num >= 0) {
			struct enp_softc *es = &enpsoftc[num];
			struct ifnet	*ifp = &es->es_if;

			if (ifp->if_flags & IFF_RUNNING) {/*is it up ?*/

        		   gethostname(hostname, sizeof(hostname));
  			   h = gethostbyname(hostname);
		    	   output(h, h->h_addr, es->es_enaddr);
			   if (ifp->if_flags & IFF_NOARP) 
					continue;
			   if (dontrepeat < 5) {
			   	whoisup(ifp);
				dontrepeat++;
			   }
			}
		}	

	}  


/* And then, foreign hosts' Ethernet Addresses	*/

	klseek(kmem, arptabaddr, 0);
	read(kmem, (char *)arp_tab, sizeof (struct arptab)*ARPTAB_SIZE);
        gethostname(hostname, sizeof(hostname));
	for (i = 0; i < ARPTAB_SIZE; i++, at++) {
		if (at->at_flags) {  /* if entry not empty */
			struct hostent *h;

			/* Read /etc/hosts to find out hostname */
			h = gethostbyaddr(&at->at_iaddr,sizeof(struct in_addr),
					  AF_INET);
			/* Print hostname and internet addr, excluding
			   local host entries that are already printed 
			*/
			if (strcmp(h->h_name, hostname))
				output(h, &at->at_iaddr, at->at_enaddr);
		}
	}
}



output(hent, inaddr, enaddr)
struct hostent	*hent;
struct in_addr	*inaddr;
u_char		*enaddr;
{
	char	line[20], *h_name;
	u_char *ucp = (u_char *)inaddr;
	int j, lna;

	lna = inet_lnaof( *inaddr );
	if (lna != INADDR_ANY) {
		sprintf(line, "%u.%u.%u.%u", ucp[0], ucp[1], ucp[2], ucp[3]);

		if (hent == NULL)
			h_name = what_host;
		else
			h_name = hent->h_name;

		printf("%-20s %-10.10s      ", h_name, line);
		for (j = 0 ; j < ETHADDR_SIZE-1; j++) 
	    		printf("%x.", (enaddr[j] & 0xff));
		printf("%x\n", (enaddr[j] & 0xff));
	}
}


/* probe around to see who is up & then ask for its ethernet addr */

whoisup(ifp)
struct ifnet *ifp;
{
	register struct ifreq	ifr;
	register struct hostent *p;
	struct 	in_addr in;
	int	net;
	char	*cp;

	klseek(kmem, (off_t)ifp->if_name, 0);
	read(kmem, ifr.ifr_name, sizeof(ifr.ifr_name));
	ifr.ifr_name[IFNAMSIZ] = '\0';
	cp = index(ifr.ifr_name, '\0');
	*cp++ = '0' + ifp->if_unit;
	*cp = 0;
	sethostent(0);

	while (p = gethostent()) { 
		net = inet_netof(*(struct in_addr *)p->h_addr);
		if (net == ifp->if_net) {
			ifr.ifr_data = p->h_addr;
			if (ioctl(s, SIOCGETETADDR, (caddr_t)&ifr) < 0) {
				Perror("ioctl (SIOCGETETADDR)");
				exit(1);
			}
		}
	}
	endhostent();
	return;		/* at this point arptab is updated & ready for nstat */
}

Perror(cmd)
	char *cmd;
{
	extern int errno;

	fprintf(stderr, "arptab: ");
	switch (errno) {

	case ENXIO:
		fprintf(stderr, "%s: ", cmd);
		fprintf(stderr, "no such interface\n");
		break;

	case EPERM:
		fprintf(stderr, "%s: permission denied\n", cmd);
		break;

	default:
		perror(cmd);
	}
	exit(1);
}


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.