25-Oct-85 16:15:29-MDT,6354;000000000001
Return-Path: <[email protected]>
Received: from BRL-TGR.ARPA by SIMTEL20.ARPA with TCP; Fri 25 Oct 85 16:15:05-MDT
Received: from usenet by TGR.BRL.ARPA id a009691; 25 Oct 85 17:40 EDT
From: Dennis Bednar <[email protected]>
Newsgroups: net.unix-wizards,net.sources
Subject: RE: Ethernet Problems
Message-ID: <[email protected]>
Date: 25 Oct 85 05:51:26 GMT
Xref: seismo net.unix-wizards:15493 net.sources:3725
To:       [email protected]


The arpdump.c program posted by Barry Shien, has been enhanced
to also print Timer and Flags for the ARP entries.
All of the mods I made are ifdefed by CCI and DPB.

Here is the new version:

-------------- arpdump.c ---------------------
#define CCI     /* CCI needs this because of nlist() problems */
#define DPB     /* new personal mods added to the original */

#ifdef DPB
/*
*      arpdump.c
*      Barry Shein, Boston University original 10 21 85
*      Dennis Bednar, CCI Reston VA, added options, Timer, Flags, 10 25 85
*
*      usage: arpdump [-a] [-v] [seconds]
*              -a = print old timed-out slots too
*                      ie slots containing non-zero etheraddr && IP addr == 0
*              -v = verbose, prints every entry in the table
*              seconds = decimal seconds to print again
*
*/
#else
/*
       usage: arpdump [seconds]
Newsgroups: net.unix-wizards
Subject: Re: Re: Ethernet problems


Re: Hedrick's suggestion that the problem may be with your ARP tables:

Here's a hack I use to examine the arp tables on my systems, I think
half of it or more is from something else, but it seems to do the job
(4.2bsd):

*/
#endif

#include <stdio.h>
#include <nlist.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

char *fcore = "/dev/kmem", *fnlist = "/vmunix" ;
struct nlist nl[] = {
#define ARPTAB  0
       { "_arptab" },
       { "" },
} ;
#ifdef DPB
/*      The arptab structure is defined in netinet/if_ether.h           */
#endif
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 */
#ifdef DPB
/*      The at_flags are defined in net/if.h            */
#endif
#define ATF_INUSE       1               /* entry in use */
#define ATF_COM         2               /* completed entry (enaddr valid) */
#ifdef DPB
#define ATF_PERM        4       /* permanent entry */
#define ATF_PUBL        8       /* publish entry (respond for other host) */
#endif

#ifdef DPB
/*      bucket stuff defined in netinet/if_ether.c      */
#endif
#define ARPTAB_BSIZ     5               /* bucket size */
#define ARPTAB_NB       19              /* number of buckets */
#define ARPTAB_SIZE     (ARPTAB_BSIZ * ARPTAB_NB)

struct  arptab *arptab, atab ;

#ifdef DPB
int     verbose;        /* -v verbose flag */
int     allflag;        /* -a to print all timed out ones */
#endif

main(argc,argv) int argc ; char **argv ;
{
       int fc ;
       int i,j ;
       int secs ;
       char *ap ;
       struct hostent *gethostbyaddr(), *hp ;

       if((fc = open(fcore,0)) < 0)
       {
               perror(fcore) ;
               exit(1) ;
       }
#ifdef CCI
       if (nlist(fnlist, nl) == -1)
               {
               fprintf(stderr, "arptab: nlist on %s returned error\n", fnlist);
               exit(1);
               }
#else
       nlist(fnlist,nl) ;
#endif
       arptab = (struct arptab *) nl[ARPTAB].n_value ;
#ifdef CCI
       if (nl[0].n_value == 0)
#else
       if(nl[0].n_type == 0)
#endif
       {
               fprintf(stderr,"No name list %s\n",fnlist) ;
               exit(1) ;
       }
#ifdef DPB
       secs = 0;
       /* primitive error checking on arguments */
       for (i = 1; i < argc; ++i)
               if (strcmp(argv[i], "-a") == 0)
                       ++allflag;
               else if (strcmp(argv[i], "-v") == 0)
                       ++verbose;
               else
                       secs = atoi(argv[i]);
#else
       if(argc > 1) secs = atoi(argv[1]) ;
       else secs = 0 ;
#endif
       printf("\t\tACTIVE ARP TABLE DUMP\n") ;
loop:
#ifdef DPB
       printf("Index\tIP Addr\t\tEthernet Interface\tHostName\tTimer\tFlags\n") ;
#else
       printf("Index\tAddr\t\tEthernet Interface\tHostName\n") ;
#endif
       lseek(fc,(int) arptab,0) ;
#ifdef DPB
       ap = (char *) &atab;
#else
       /* old way requires that at_iaddr be first */
       ap = (char *) &atab.at_iaddr ;
#endif
       for(i=0 ; i < ARPTAB_SIZE ; i++)
       {
               if(read(fc,&atab,sizeof atab) != (sizeof atab))
               {
                       fprintf(stderr,"Error reading arp table\n") ;
                       exit(1) ;
               }
#ifdef DPB
               if (verbose)
                       goto printslot; /* print every slot it */

               if (allflag)    /* print old timed out "half-filled" slots */
                       if ( inet_netof(atab.at_iaddr) != 0 ||
                               atab.at_flags != 0 ||
                               ge_addr(&atab.at_enaddr[0]) != 0)
                               ;       /* print slot below */
                       else
                               continue;
               else            /* print only entries with IP addresses */
                       if (inet_netof(atab.at_iaddr) != 0)
                               ;       /* print slot below */
                       else
                               continue;
printslot:
#else
               if(inet_netof(atab.at_iaddr) == 0) continue ;
#endif
               printf("%2d:\t",i) ;
               printf("%s\t",ap = (char *) inet_ntoa(atab.at_iaddr)) ;
#ifdef DPB
               /* kludgy way to align columns because IP addr is var len */
               if (strlen(ap)<8) printf("\t");
#endif
               for(j=0 ; j < 6 ; j++)
                       printf("%02x",atab.at_enaddr[j]) ;
               if((hp = gethostbyaddr(&atab.at_iaddr.s_addr,
                                       sizeof atab.at_iaddr.s_addr,
                                       AF_INET)) == NULL)
#ifdef DPB
               /* save ptr to host name printed for strlen later */
                       printf(ap = "\t\t(unknown)") ;
               else printf("\t\t%s",ap = hp->h_name) ;
#else
                       printf("\t\t(unknown)") ;
               else printf("\t\t%s",hp->h_name) ;
#endif
#ifdef DPB
               /* again kludgy way to align columns because hostname var len */
               if (strlen(ap)<8) printf("\t");
               printf("\t%3d", atab.at_timer);
               printf("\t");
               if (atab.at_flags & ATF_INUSE) printf("U");
               if (atab.at_flags & ATF_COM)   printf("C");
               if (atab.at_flags & ATF_PERM)  printf("P");
               if (atab.at_flags & ATF_PUBL)  printf("R"); /* responding */
#endif
               printf("\n") ;
       }
       if(secs <= 0) exit(0) ;
       sleep(secs) ;
       goto loop ;
}
/*
       -Barry Shein, Boston University
*/

#ifdef DPB
/*
* get ethernet address
* returns 0 iff 6 byte ethernet address is all zeros
*/
ge_addr(addr)
       register        char    *addr;
{
       register        int     i;

       for (i = 0; i < 6; ++i, ++addr)
               if (*addr)
                       return  1;      /* found a non-zero byte */

       return 0;                       /* all bytes were zero */
}
#endif
--
Dennis Bednar   Computer Consoles Inc.  Reston VA       703-648-3300
{decvax,ihnp4,harpo,allegra}!seismo!rlgvax!dennis