|
|
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);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.