v01i037: Ethernet tools for SunOS 3.X, Part02/02
Charles Mcgrew
mcgrew at dartagnan.rutgers.edu
Thu Jun 22 03:54:15 AEST 1989
Submitted-by: budd at bu-it.bu.edu
Posting-number: Volume 1, Issue 37
Archive-name: ethertools-3.X/part02
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 2 (of 2)."
# Contents: ctp.c if_ctp.c nit.c packet.h rlog.c
# Wrapped by budd at buita on Sat Aug 13 01:14:42 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f ctp.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"ctp.c\"
else
echo shar: Extracting \"ctp.c\" \(10642 characters\)
sed "s/^X//" >ctp.c <<'END_OF_ctp.c'
X/*
X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University
X * All Rights Reserved
X *
X * Permission is granted to any individual or institution to use, copy,
X * or redistribute this software so long as it is not sold for profit,
X * provided that this notice and the original copyright notices are
X * retained. Boston University makes no representations about the
X * suitability of this software for any purpose. It is provided "as is"
X * without express or implied warranty.
X */
X/*
X * CTP -- Ethernet v2 Configuration Test Protocol User Process
X * Philip L. Budne @ Boston University / Distributed Systems
X *
X */
X
X# include <sys/types.h>
X# include <sys/time.h>
X# include <net/nit.h>
X# include <signal.h>
X# include <stdio.h>
X# include "ctp.h"
X
X/*
X * SIGH. Move sender to child?
X * print loss.
X * print variance.
X */
X
X# define SHM
X
Xtypedef u_char ea_t[6]; /* ethernet address type */
X
X# ifdef SHM
X# include <sys/ipc.h>
X# include <sys/shm.h>
X
Xint shmid;
Xchar *shmaddr, *shmat();
X
X# define NCOUNTS 8
X# define NCOUNT (1<<(NCOUNTS))
Xstruct stats {
X int total; /* total count */
X int highseq; /* highest seq seen */
X int outofseq; /* number recvd out of sequence */
X int min, max; /* min and max times */
X int sum, sumsq; /* sum of times, sum of squares */
X int counts[ NCOUNT ];
X /* array of addrs? */
X};
X
Xint lastseq = 0;
Xint nsent = 0;
X# endif /* SHM defined */
X
Xint seq = 0;
X
Xstruct packet { /* CTP packet layout */
X ea_t p_dst; /* Ethernet dest */
X ea_t p_src; /* Ethernet src */
X u_short p_type; /* Ethernet type (802 length) */
X u_short p_skip; /* CTP skip */
X u_char p_data[ 2048 ]; /* ... */
X};
X
Xstruct ctp_forward { /* forward subpacket */
X u_short cf_function; /* CTP_FWD */
X ea_t cf_addr;
X};
X
Xstruct ctp_reply { /* reply subpacket */
X u_short cr_function; /* CTP_REP */
X /* The following is data that we use for own purposes */
X u_short cr_pid; /* pid of sender -- not swapped */
X u_short cr_seq; /* sequence number -- not swapped */
X struct timeval cr_sendt; /* time packet was sent */
X /* more data here.. */
X};
X
Xea_t localaddr; /* our ethernet address */
X
X# define MAXPATH 200 /* !! (more than can fit in a packet) */
Xea_t path[ MAXPATH]; /* path list */
Xint pathcount = 0; /* length of path list */
X
X# define MINPACK 60 /* minimum ether packet */
X# define MAXPACK 1516 /* maximum ether packet */
X
Xint count = -1; /* number of packets to send */
Xchar ifbuf[ 100 ];
Xchar *interface = ifbuf; /* interface to use */
Xint verbose = 0; /* extra output */
Xint noreturn = 0; /* don't force final forward back */
Xint debug = 0; /* don't fork */
Xint packlen = MINPACK; /* default total packet length */
Xint slptim = 1000; /* sleep time in ms */
X
Xint pid; /* parent pid */
Xint child; /* child pid */
X
Xmain(argc, argv)
X int argc;
X char *argv[];
X{
X extern char *optarg;
X extern int optind, opterr;
X int s, c, errs;
X void nit_input(); /* forward */
X
X errs = 0;
X while( (c = getopt( argc, argv, "c:di:l:ns:v" )) != EOF ) {
X switch( c ) {
X case 'c':
X count = atoi( optarg );
X break;
X case 'd':
X debug ^= 1;
X break;
X case 'i':
X interface = optarg;
X break;
X case 'l':
X packlen = atoi( optarg );
X if( packlen < MINPACK )
X packlen = MINPACK;
X else if( packlen > MAXPACK )
X packlen = MAXPACK;
X break;
X case 'n':
X noreturn ^= 1;
X break;
X case 's':
X slptim = atoi( optarg );
X break;
X case 'v':
X verbose ^= 1;
X break;
X default:
X errs++;
X } /* switch */
X } /* while getopt */
X if( errs > 0 ) {
X fprintf( stderr, "Usage: %s [-c count] [-d] [-i ifn] ", argv[0] );
X fprintf( stderr, "[-l len] [-n] [-s sleep] [-v] [addr ...]\n");
X fprintf( stderr, "addr <- ether-addr | ipaddr | iphost | ");
X fprintf( stderr, "etherhost | 'BCAST' | 'MCAST'\n" );
X exit( 1 );
X }
X
X pid = getpid(); /* get parent pid */
X s = nit_open( interface, ETHERTYPE_CTP, localaddr, 0 );
X printf("%s address ", interface );
X petaddr( localaddr );
X puts( "" );
X
X pathcount = 0;
X while( optind < argc && pathcount < MAXPATH && argv[optind] != NULL ) {
X if( strcmp( argv[optind], "MCAST" ) == 0 ) { /* CTP mcast addr */
X register u_char *ea;
X ea = path[pathcount];
X *ea++ = 0XCF;
X *ea++ = 0x00;
X *ea++ = 0x00;
X *ea++ = 0x00;
X *ea++ = 0x00;
X *ea = 0x00;
X }
X else if( !htoea( argv[ optind ], path[pathcount] ) ) {
X fprintf( stderr, "%s: unknown host %s\n",
X argv[0], argv[optind] );
X exit( 1 );
X } /* bad host */
X pathcount++;
X optind++;
X } /* while hosts */
X
X if( pathcount == 0 ) { /* if no hosts */
X bcopy( bcast, path[0], sizeof( ea_t ) ); /* broadcast */
X pathcount++; /* fake count */
X } /* empty path */
X
X if( debug )
X ctp_send( s ); /* just send */
X else {
X# ifdef SHM
X void gotint(), die(), poop();
X struct stats *sp;
X
X signal( SIGINT, gotint );
X signal( SIGHUP, die );
X signal( SIGKILL, die );
X
X shmid = shmget( IPC_PRIVATE, sizeof( struct stats ), 0600 );
X shmaddr = shmat( shmid, 0, 0 );
X sp = (struct stats *)shmaddr;
X bzero( sp, sizeof( struct stats ) );
X sp->min = 100000;
X sp->max = -1;
X# endif /* SHM defined */
X
X switch( (child = fork()) ) {
X case -1:
X perror( "fork" );
X exit( 1 );
X /* NOTREACHED */
X
X case 0:
X# ifdef SHM
X signal( SIGINT, poop );
X signal( SIGHUP, poop );
X signal( SIGKILL, poop );
X# endif /* SHM defined */
X nit_loop( s, nit_input ); /* input in child */
X /* NOTREACHED */
X
X default:
X ctp_send(s); /* output in parent */
X /* NOTREACHED */
X } /* switch */
X }
X} /* main */
X
X# ifdef SHM
Xvoid
Xdie() {
X (void) shmdt( shmaddr );
X (void) shmctl( shmid, IPC_RMID, 0 );
X exit( 0 );
X}
X
Xvoid
Xpoop() {
X exit( 1 );
X}
X
Xvoid
Xstats() {
X register struct stats *sp;
X
X sp = (struct stats *) shmaddr;
X printf("----CTP statistics----\n");
X printf("%d Packet%s Sent, %d Recieved\n",
X nsent, (nsent == 1 ? "" : "s"), sp->total );
X if( sp->total > 0 )
X printf("round-trip (ms) min/avg/max = %d/%d/%d var=%d\n",
X sp->min, sp->sum / sp->total, sp->max,
X 0 );
X} /* stats */
X
Xvoid
Xgotint() {
X puts("");
X stats();
X die();
X}
X
X# endif /* SHM defined */
X
X/****************************************************************/
X
Xvoid
Xnit_input( s, nh )
X int s;
X struct nit_hdr *nh;
X{
X int l;
X u_char *p2;
X int len, l2, ms;
X short f, skip, seq;
X struct packet *pp;
X struct ctp_reply *cr;
X# ifdef SHM
X register struct stats *sp;
X sp = (struct stats *) shmaddr;
X# endif /* SHM defined */
X
X l = nh->nh_datalen;
X pp = (struct packet *) (((u_char *)nh) + sizeof( struct nit_hdr ));
X
X skip = pp->p_skip; /* fetch skip */
X skip = SSWAP( skip ); /* swap it */
X
X if( skip & 1 )
X return; /* skip must not be odd */
X
X p2 = (u_char *) pp->p_data + skip;
X len = l - 14 - skip - 2; /* length of data */
X
X if( len < 2 ) /* no room for function */
X return;
X
X cr = (struct ctp_reply *) p2; /* get reply struct */
X f = CTP_SHORT( p2 ); /* get function */
X p2 += 2; /* advance past function */
X len -= 2; /* account for function length */
X switch( f ) {
X case CTP_REP: /* reply */
X break;
X
X case CTP_FWD:
X return; /* we are a client. */
X break;
X
X default:
X/* printf(" fncn %d. data: ", f ); /* !! */
X return;
X }
X
X if( cr->cr_pid != pid ) /* check for parent pid */
X return;
X
X p2 += 2; /* advance past pid */
X len -= 4; /* pid, seq */
X
X printf("%d bytes from ", l );
X petaddr( pp->p_src );
X seq = CTP_SHORT( p2 );
X ms = delta( &nh->nh_timestamp, &cr->cr_sendt );
X printf(": seq %2d. time=%dms\n", seq, ms );
X
X# ifdef SHM
X sp->total++;
X if( seq != lastseq && seq != lastseq+1 )
X sp->outofseq++;
X lastseq = seq;
X if( ms > sp->max )
X sp->max = ms;
X if( ms < sp->min )
X sp->min = ms;
X if( seq > sp->highseq )
X sp->highseq = seq;
X sp->sum += ms;
X sp->sumsq = ms * ms;
X sp->counts[ seq & (NCOUNT-1) ]++;
X# endif /* SHM defined */
X} /* nit_input */
X
Xdelta( a, b )
X struct timeval *a, *b;
X{
X int usec, sec;
X usec = a->tv_usec - b->tv_usec;
X sec = a->tv_sec - b->tv_sec;
X
X if( usec < 0 ) {
X sec--;
X usec += 1000000;
X }
X usec += 999; /* round to ms */
X sec = sec * 1000 + usec / 1000; /* get ms */
X if( sec < 0 ) {
X printf("a: %d %d b: %d %d\n",
X a->tv_sec, a->tv_usec,
X b->tv_sec, b->tv_usec );
X return( 0 );
X } /* sec < 0 */
X return( sec );
X} /* delta */
X
X/****************************************************************/
X
Xctp_send( s )
X int s;
X{
X struct timezone tz;
X struct ctp_forward *cf;
X struct ctp_reply *cr, *ocr;
X struct packet p;
X u_char *cp;
X int i, c;
X
X printf("to ");
X for( i = 0; i < pathcount; i++ ) {
X if( i > 0 )
X printf(", ");
X petaddr( path[i] );
X }
X
X /* fill in ether packet header */
X bcopy( path[ 0 ], p.p_dst, sizeof( p.p_dst ) ); /* fill in initial dest */
X p.p_type = ETHERTYPE_CTP; /* fill in type */
X p.p_skip = SSWAP( 0 ); /* fill in initial CTP skip */
X
X cf = (struct ctp_forward *) p.p_data; /* get data pointer */
X for( i = 1; i < pathcount; i++ ) {
X cf->cf_function = SSWAP( CTP_FWD );
X bcopy( path[i], cf->cf_addr, sizeof( ea_t ) );
X cf++; /* advance pointer */
X }
X
X /* ensure packet gets back -- append forward to ourselves */
X if( !noreturn &&
X bcmp( path[pathcount-1], localaddr, sizeof( localaddr ) ) != 0 ) {
X cf->cf_function = SSWAP( CTP_FWD );
X bcopy( localaddr, cf->cf_addr, sizeof( localaddr ) );
X cf++;
X }
X
X /* create reply data */
X cr = (struct ctp_reply *) cf;
X cr->cr_function = SSWAP( CTP_REP );
X cr->cr_pid = pid; /* pid of parent */
X ocr = cr; /* save pointer for timestamp */
X cr++; /* advance past reply */
X
X cp = (u_char *) cr; /* get pointer to reply data */
X i = cp - (u_char *)&p; /* get length of packet so far */
X
X if( i > packlen )
X if( i > MAXPACK ) {
X fprintf( stderr, "Packet too large without data (%d)\n", i );
X exit( 1 );
X }
X else
X packlen = i;
X
X printf(": %d data bytes (%d total)\n", packlen - i, packlen );
X fflush( stdout );
X
X while( i < packlen )
X *cp++ = i++ & 0xff;
X
X slptim *= 1000; /* convert to usec */
X while( count != 0 ) {
X if( count > 0 )
X count--;
X ocr->cr_seq = SSWAP( seq );
X seq++; /* update sequence */
X gettimeofday( &ocr->cr_sendt, &tz );
X
X if( nit_output( s, &p, packlen ) < 0 )
X perror( "write" );
X else
X nsent++;
X usleep( slptim );
X }
X kill( child, SIGINT );
X stats();
X die();
X} /* ctp_send */
END_OF_ctp.c
if test 10642 -ne `wc -c <ctp.c`; then
echo shar: \"ctp.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f if_ctp.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"if_ctp.c\"
else
echo shar: Extracting \"if_ctp.c\" \(5585 characters\)
sed "s/^X//" >if_ctp.c <<'END_OF_if_ctp.c'
X/*
X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University
X * All Rights Reserved
X *
X * Permission is granted to any individual or institution to use, copy,
X * or redistribute this software so long as it is not sold for profit,
X * provided that this notice and the original copyright notices are
X * retained. Boston University makes no representations about the
X * suitability of this software for any purpose. It is provided "as is"
X * without express or implied warranty.
X */
X/*
X * if_ctp.c -- Ethernet Version 2 Configuation Test Protocol (CTP)
X *
X * DEC DEUNA does this at the controller level??
X */
X
X
X/*
X * Called from do_protocol in sunif/if_subr.c;
X *
X *#endif INET
X>*#ifdef ETHERPUP_CTPTYPE:
X>* case ETHERPUP_CTPTYPE:
X>* ctp_input( header, m, &ap->ac_if );
X>* break;
X>*#endif ETHERPUP_CTPTYPE:
X * default:
X */
X
X/*
X * add to /sys/conf/files;
X * sunif/if_ctp.c optional ether
X */
X
X/* add to netinet/if_ether.h;
X/* #define ETHERTYPE_CTP 0x9000 /* Config. Test Protocol */
X/* ... */
X/* #define ETHERPUP_CTPTYPE 0x9000 /* Config. Test Protocol */
X
X
X# include "ether.h"
X
X# if NETHER > 0
X# include "../h/param.h"
X# include "../h/systm.h"
X# include "../h/mbuf.h"
X# include "../h/socket.h"
X# include "../h/time.h"
X# include "../h/kernel.h"
X# include "../h/errno.h"
X# include "../h/ioctl.h"
X
X# include "../net/if.h"
X# include "../netinet/in.h" /* for if_ether */
X# include "../netinet/if_ether.h" /* for ether_header */
X
X# define DEBUG
X
X# define CTP_REP 1
X# define CTP_FWD 2
X
X# if defined(vax) || defined(ns32000) /* machine is a byteswapper? */
X# define SWAP(s) (s) /* CTP wants them swapped!! */
X# else /* not defined(vax) || defined(ns32000) */
X# define SWAP(s) ((((s)>>8) & 0xff) | (((s)<<8) & 0xff00))
X# endif /* not defined(vax) || defined(ns32000) */
X
X# ifndef ETHERTYPE_CTP
X# define ETHERTYPE_CTP 0x9000 /* 90-00 */
X# endif /* ETHERTYPE_CTP not defined */
X
X# define SP(s) ((u_short *)s)
X# define SS (sizeof(short))
X
Xint ctp_rawinput; /* total input */
Xint ctp_reply; /* replies to us */
Xint ctp_forward; /* packets forwarded */
Xint ctp_multicast; /* err: forward to multicast!! */
Xint ctp_badfunction; /* err: bad function */
Xint ctp_errs; /* other errs */
Xctp_input( h, m, myif )
X register struct ether_header *h;
X register struct mbuf *m;
X struct ifnet *myif;
X{
X ctp_rawinput++;
X
X if( !ctp_process( h, m ) ) /* no reply generated?? */
X m_freem(m); /* discard buffer */
X}
X
Xstatic ctp_process( h, m, myif )
X register struct ether_header *h;
X register struct mbuf *m;
X struct ifnet *myif;
X{
X register u_short func, skip;
X register u_char *cp;
X register int l;
X
X struct ether_header *eh;
X struct sockaddr sa;
X
X l = m->m_len; /* get data length */
X cp = mtod(m, u_char *); /* get data pointer */
X
X /****************************************************************
X * process skip
X */
X
X l -= SS;
X if( l < 0 ) {
X# ifdef DEBUG
X ctp_msg( h );
X printf("-- too short for skip\n", skip );
X# endif /* DEBUG defined */
X ctp_errs++;
X return( 0 ); /* no reply generated */
X }
X
X skip = *SP( cp ); /* get skip */
X skip = SWAP( skip ); /* byte swap if needed */
X cp += SS;
X
X if( skip & 1 ) {
X# ifdef DEBUG
X ctp_msg( h );
X printf("-- odd skip %d\n", skip );
X# endif /* DEBUG defined */
X ctp_errs++;
X return( 0 ); /* no reply generated */
X }
X
X /****************************************************************
X * process function
X */
X
X l -= skip;
X if( l < 0 ) {
X# ifdef DEBUG
X ctp_msg( h );
X printf("-- skip too large (%d.)\n", skip );
X# endif /* DEBUG defined */
X ctp_errs++;
X return( 0 ); /* no reply generated */
X }
X
X cp += skip; /* get address of function */
X
X func = *SP( cp ); /* get function */
X func = SWAP( func ); /* byte swap if needed */
X
X l -= SS; /* deduct function length */
X cp += SS; /* advance past function */
X
X switch( func ) {
X
X case CTP_REP: /* reply */
X# ifdef DEBUG
X ctp_msg( h );
X printf("-- reply, %d bytes\n", l);
X# endif /* DEBUG defined */
X /* create AF_CTP and pass up to users?? */
X ctp_reply++;
X return( 0 ); /* no reply generated */
X break;
X
X case CTP_FWD:
X l -= sizeof( struct ether_addr );
X if( l < 0 ) {
X# ifdef DEBUG
X ctp_msg( h );
X printf("-- forward too short\n");
X# endif /* DEBUG defined */
X ctp_errs++;
X return( 0 );
X }
X if( *cp & 1 ) { /* multicast bit */
X ctp_msg( h );
X printf(" -- forward to multicast address ");
X ether_print( cp );
X printf(" ignored\n");
X ctp_multicast++;
X return( 0 ); /* no reply generated */
X }
X# ifdef DEBUG
X ctp_msg( h );
X printf("-- forwarding %d bytes to ", l);
X ether_print( cp );
X# endif /* DEBUG defined */
X skip += SS + sizeof( struct ether_addr ); /* skip forward function */
X /* and address */
X *mtod(m, u_short *) = SWAP( skip ); /* update in packet */
X
X sa.sa_family = AF_UNSPEC; /* set family */
X eh = (struct ether_header *)sa.sa_data; /* get sockaddr */
X eh->ether_type = ETHERTYPE_CTP; /* set ether type */
X eh->ether_dhost = *(struct ether_addr *) cp; /* copy dest */
X (myif->if_output)( myif, m, &sa );
X
X ctp_forward++;
X return( 1 ); /* AH-HAH!! we generated a reply!! */
X break;
X
X default:
X# ifdef DEBUG
X ctp_msg( h );
X printf("-- bad function %d.\n", func );
X# endif /* DEBUG defined */
X ctp_badfunction++;
X return( 0 );
X break;
X }
X return( 0 ); /* just in case */
X} /* ctp_process */
X
Xctp_msg( h )
X register struct ether_header *h;
X{
X printf("CTP packet from ");
X ether_print( &h->ether_shost );
X} /* ctp_msg */
X
X# endif /* NETHER > 0 */
END_OF_if_ctp.c
if test 5585 -ne `wc -c <if_ctp.c`; then
echo shar: \"if_ctp.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f nit.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"nit.c\"
else
echo shar: Extracting \"nit.c\" \(5414 characters\)
sed "s/^X//" >nit.c <<'END_OF_nit.c'
X/*
X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University
X * All Rights Reserved
X *
X * Permission is granted to any individual or institution to use, copy,
X * or redistribute this software so long as it is not sold for profit,
X * provided that this notice and the original copyright notices are
X * retained. Boston University makes no representations about the
X * suitability of this software for any purpose. It is provided "as is"
X * without express or implied warranty.
X */
X# include <sys/types.h>
X# include <sys/time.h>
X# include <sys/socket.h>
X# include <sys/ioctl.h>
X# include <net/nit.h>
X# include <net/if.h>
X# include <stdio.h>
X
X# define GLOBAL
X
X# ifdef DEBUG
X# define IFDEB(x) (x)
X# else /* DEBUG not defined */
X# define IFDEB(x)
X# endif /* DEBUG not defined */
X
X# define ALIGNSIZE sizeof( int )
X# define ALIGN(a) (((a) + ALIGNSIZE - 1) & ~(ALIGNSIZE - 1))
X/* NITBUFSIZ == 1K */
X# define BUFSPACE (NITBUFSIZ * 256)
X# define CHUNKSIZE (NITBUFSIZ * 64)
X/****************************************************************/
X
X
XGLOBAL int nit_errors = 1; /* display errors */
XGLOBAL int nit_exit = 1; /* exit on errors */
XGLOBAL int nit_bufspace = BUFSPACE;
XGLOBAL int nit_chunksize = CHUNKSIZE;
XGLOBAL int nit_snaplen = 2000;
X
Xtypedef void (*FPTR)();
X
XGLOBAL int
Xnit_loop( s, input_handlr )
X int s;
X FPTR input_handlr;
X{
X for( ;; ) {
X static char buf[ BUFSPACE ];
X register char *pp;
X register struct nit_hdr *nh;
X char *pe;
X int cc;
X
X cc = read( s, buf, sizeof( buf ) );
X if( cc < sizeof( struct nit_hdr ) ) {
X if( nit_errors )
X fprintf(stderr, "nit_loop: short read (%d)\n", cc );
X if( nit_exit )
X exit( 1 );
X else
X return( -1 );
X } /* short read */
X
X pp = buf;
X pe = pp + cc;
X while( pp < pe ) {
X nh = (struct nit_hdr *) pp;
X cc = process_nh( s, nh, input_handlr );
X if( cc < 0 )
X break;
X else
X pp += ALIGN( sizeof( struct nit_hdr ) + cc );
X } /* while */
X } /* for ever */
X} /* nit_process */
X
Xstatic int
Xprocess_nh( s, nh, input_handlr )
X int s;
X struct nit_hdr *nh;
X FPTR input_handlr;
X{
X switch( nh->nh_state ) {
X case NIT_QUIET:
X IFDEB( fprintf(stderr, "quiet\n") );
X return( 0 );
X
X case NIT_CATCH:
X (*input_handlr)( s, nh );
X return( nh->nh_datalen );
X
X case NIT_NOMBUF:
X fprintf(stderr, "out of mbufs, dropped %d packets\n",
X nh->nh_dropped );
X return( 0 );
X
X case NIT_NOCLUSTER:
X fprintf(stderr, "out of mclusters, dropped %d packets\n",
X nh->nh_dropped );
X return( 0 );
X
X case NIT_NOSPACE:
X fprintf(stderr, "bufspace exceeded, dropped %d packets\n",
X nh->nh_dropped );
X return( 0 );
X
X case NIT_SEQNO:
X IFDEB( fprintf(stderr, "seqno %d\n", nh->nh_seqno ) );
X return( 0 );
X
X default:
X fprintf(stderr, "bad NIT state: %d\n", nh->nh_state );
X return( -1 );
X } /* switch */
X}
X
XGLOBAL int
Xnit_open( ifa, type, la, pro )
X char *ifa;
X unsigned int type;
X u_char *la;
X int pro;
X{
X struct sockaddr_nit snit;
X struct nit_ioc nioc;
X struct ifreq ifr;
X int s;
X
X if( ifa == NULL ) {
X if( nit_errors )
X fprintf( stderr, "nit_open: must have interface pointer\n" );
X if( nit_exit )
X exit( 1 );
X else
X return( -1 );
X } /* no ifa */
X
X if( (s = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW)) < 0 ) {
X if( nit_errors )
X perror( "socket" );
X if( nit_exit )
X exit( 1 );
X else
X return( -1 );
X } /* socket */
X
X if( *ifa == '\0' ) { /* no interface specified */
X struct ifconf ifc;
X char ifbuf[ 100 ];
X
X ifc.ifc_len = sizeof( ifbuf );
X ifc.ifc_buf = ifbuf;
X
X if( ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0 ) {
X if( nit_errors )
X perror( "ifconf ioctl");
X close( s );
X if( nit_exit )
X exit( 1 );
X else
X return( -1 );
X } /* ifconf failed */
X strcpy( ifa, ifc.ifc_req->ifr_name ); /* copy back to buffer */
X } /* try to find an interface */
X
X snit.snit_family = AF_NIT;
X strncpy( snit.snit_ifname, ifa, sizeof(snit.snit_ifname ) );
X if( bind(s, (struct sockaddr *)&snit, sizeof( snit ) ) < 0 ) {
X if( nit_errors )
X perror( ifa );
X close( s );
X if( nit_exit )
X exit( 1 );
X else
X return( -1 );
X } /* bind failed */
X
X bzero(&nioc, sizeof(nioc));
X nioc.nioc_bufspace = nit_bufspace;
X nioc.nioc_chunksize = nit_chunksize;
X nioc.nioc_typetomatch = type;
X nioc.nioc_snaplen = nit_snaplen;
X nioc.nioc_bufalign = ALIGNSIZE;
X nioc.nioc_bufoffset = 0;
X nioc.nioc_flags = (pro ? NF_PROMISC : 0 ) | NF_TIMEOUT;
X nioc.nioc_timeout.tv_sec = 1;
X nioc.nioc_timeout.tv_usec = 0;
X if (ioctl(s, SIOCSNIT, &nioc) != 0) {
X if( nit_errors )
X perror("nit ioctl");
X close( s );
X if( nit_exit )
X exit(1);
X else
X return( -1 );
X } /* nit ioctl */
X
X strncpy(ifr.ifr_name, ifa, sizeof ifr.ifr_name);
X if( ioctl(s, SIOCGIFADDR, (caddr_t) &ifr) < 0 ) {
X if( nit_errors )
X fprintf(stderr, "cannot find ether address for %s\n", ifa );
X close( s );
X if( nit_exit )
X exit( 1 );
X else
X return( -1 );
X } /* interface address ioctl */
X bcopy( ifr.ifr_addr.sa_data, la, 6 );
X return( s );
X} /* nit_open */
X
XGLOBAL int
Xnit_output(fd, buf, len)
X int fd, len;
X char *buf;
X{
X struct sockaddr sa;
X int offset = sizeof(sa.sa_data);
X int result;
X
X sa.sa_family = AF_UNSPEC;
X bcopy(buf, sa.sa_data, offset);
X result = sendto(fd, buf+offset, len-offset, 0, &sa, sizeof(sa));
X if( result < 0 )
X return( result );
X return( result+offset );
X} /* nit_output */
END_OF_nit.c
if test 5414 -ne `wc -c <nit.c`; then
echo shar: \"nit.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f packet.h -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"packet.h\"
else
echo shar: Extracting \"packet.h\" \(6347 characters\)
sed "s/^X//" >packet.h <<'END_OF_packet.h'
X/*
X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University
X * All Rights Reserved
X *
X * Permission is granted to any individual or institution to use, copy,
X * or redistribute this software so long as it is not sold for profit,
X * provided that this notice and the original copyright notices are
X * retained. Boston University makes no representations about the
X * suitability of this software for any purpose. It is provided "as is"
X * without express or implied warranty.
X */
Xtypedef unsigned char byte;
Xtypedef unsigned short u_short;
Xtypedef unsigned long ip_addr;
Xtypedef unsigned long u_long;
Xtypedef byte EA[6];
X
X/****************************************************************/
Xstruct ipheader {
X# ifdef SWAP
X int ip_ihl : 4; /* Internet header length in 32 bit words */
X int ip_ver : 4; /* Header version */
X# else /* SWAP not defined */
X int ip_ver : 4; /* Header version */
X int ip_ihl : 4; /* Internet header length in 32 bit words */
X# endif /* SWAP not defined */
X byte ip_tsrv; /* Type of service */
X u_short ip_len; /* Total packet length including header */
X u_short ip_id; /* ID for fragmentation */
X# ifdef SWAP
X u_short ip_foff : 13; /* Fragment offset */
X u_short ip_flgs : 3; /* flags */
X# else /* SWAP not defined */
X u_short ip_flgs : 3; /* flags */
X u_short ip_foff : 13; /* Fragment offset */
X# endif /* SWAP not defined */
X# define IP_FLG_DF 01
X# define IP_FLG_MF 02
X
X byte ip_ttl; /* Time to live (secs) */
X byte ip_prot; /* protocol */
X u_short ip_chksum; /* Header checksum */
X ip_addr ip_src; /* Source addrt */
X ip_addr ip_dst; /* Destination addr */
X byte ip_options[1]; /* options... */
X};
X /* from RFC990 */
X# define IP_PROT_ICMP 1 /* control messages */
X# define IP_PROT_GGP 2 /* gave vs gate */
X /* 5 - ST - stream */
X# define IP_PROT_TCP 6 /* tcp */
X# define IP_PROT_EGP 8 /* ext gateways */
X /* 9 - any igp */
X# define IP_PROT_PUP 12 /* pup */
X /* 13 - ARGUS */
X /* 14 - EMCON */
X /* 15 - XNET - cross net debugger */
X /* 16 - Chaos */
X# define IP_PROT_UDP 17 /* user datagrams */
X /* 18 - MUX - Multiplexing */
X /* 19 - DCN-MEAS */
X /* 20 - HMP host monitoring */
X /* 21 PRM */
X# define IP_PROT_IDP 22 /* xns idp */
X /* 23 TRUNK1 */
X /* 24 TRUNK2 */
X /* 25 LEAF1 */
X /* 26 LEAF2 */
X /* 27 RDP */
X /* 28 IRTP - reliable transaction */
X /* 29 ISO-TP4 */
X /* 30 NETBLT */
X /* 61 any host internal protocol */
X /* 62 CFTP */
X /* 63 any local network */
X /* 64 SAT-EXPAK */
X /* 65 MIT-SUBNET */
X /* 66 - RVD */
X /* 67 IPPC */
X /* 68 any DFS */
X /* 69 SAT-MON */
X /* 71 IPCV */
X /* 76 BR-SAT-MON */
X /* 78 WB-MON */
X /* 79 WB-EXPAK */
X# define IP_PROT_ND 77 /* net disk (SUN, unoff) */
X
X
X/****************************************************************/
Xstruct udpheader {
X u_short udp_srcp; /* source port */
X u_short udp_dstp; /* dest port */
X u_short udp_len; /* length of UDP packet */
X u_short udp_cksum; /* UDP checksum */
X};
X
X/****************************************************************/
Xstruct tcpheader { /* a tcp header */
X u_short tcp_srcp; /* source port */
X u_short tcp_dstp; /* dest port */
X u_long tcp_seq; /* sequence number */
X u_long tcp_ack; /* acknowledgement number */
X# if 0
X u_short tcp_flags;
X# define tcp_thl tcp_flags >> 12
X# define tcp_fin tcp_flags & 001
X# define tcp_syn tcp_flags & 002
X# define tcp_rst tcp_flags & 004
X# define tcp_psh tcp_flags & 010
X# define tcp_fack tcp_flags & 020
X# define tcp_furg tcp_flags & 040
X# else /* not 0 */
X unsigned tcp_thl : 4; /* tcp header length */
X unsigned tcp_uu1 : 6; /* unused */
X unsigned tcp_furg : 1; /* urgent ptr. valid */
X unsigned tcp_fack : 1; /* ack valid */
X unsigned tcp_psh : 1; /* push bit */
X unsigned tcp_rst : 1; /* reset bit */
X unsigned tcp_syn : 1; /* syn bit */
X unsigned tcp_fin : 1; /* fin bit */
X# endif /* not 0 */
X u_short tcp_win; /* window */
X u_short tcp_cksum; /* checksum */
X u_short tcp_urg; /* urgent pointer */
X};
X
X/****************************************************************/
Xstruct ndpacket {
X byte nd_op, nd_dev, nd_err, nd_ver;
X u_long nd_seq, nd_blk, nd_count, nd_res, nd_off, nd_data;
X};
X
X/****************************************************************/
Xstruct arppacket {
X u_short arp_hw; /* should be 1 */
X u_short arp_pro;
X byte arp_hln; /* hdw addr len */
X byte arp_pln; /* proto addr len */
X u_short arp_op; /* arp opcode */
X byte arp_data[1]; /* data... */
X/* EA arp_xsha; /* sender hardware address */
X/* ip_addr arp_xspa; /* sender protocol address */
X/* EA arp_xtha; /* target hardware address */
X/* ip_addr arp_xtpa; /* target protocol address */
X};
X
X# define ARP_REQUEST 1 /* request to resolve address */
X# define ARP_REPLY 2 /* response to previous request */
X# define RARP_REQUEST 3 /* request to resolve address */
X# define RARP_REPLY 4 /* response to previous request */
X
X/* as of rfc990 */
X# define ARP_HW_ETHER 1 /* 10mb ether */
X# define ARP_HW_XETHER 2 /* 3mb ether */
X# define ARP_HW_AX25 3 /* amateur radio */
X# define ARP_HW_PRONET 4
X# define ARP_HW_CHAOS 5
X# define ARP_HW_IEEE802 6
X
X/****************************************************************/
Xstruct puppacket {
X u_short pup_len;
X byte pup_transport;
X byte pup_type;
X u_long pup_id;
X struct {
X byte pup_port_net;
X byte pup_port_host; /* swapped? */
X u_short pup_port_sock1, pup_port_sock2;
X } pup_src, pup_dst;
X};
X
X/****************************************************************/
Xstruct xns_addr {
X byte xnsa_net[4];
X byte xnsa_host[6];
X u_short xnsa_port;
X};
X
Xstruct xnspacket { /* xns idp */
X u_short xns_sum, xns_len; /* cksum, len */
X byte xns_tc, xns_pt; /* hops(transport), packet type */
X struct xns_addr xns_dst;
X struct xns_addr xns_src;
X};
X/****************************************************************/
X
Xunion {
X byte p_bytes[ 2000 ];
X struct etherpacket {
X EA e_dst;
X EA e_src;
X u_short e_type;
X union {
X byte d_bytes[1];
X struct ipheader d_ip;
X struct arppacket d_arp;
X struct puppacket d_pup;
X struct xnspacket d_xns;
X } e_data;
X } p_ether;
X} packet;
END_OF_packet.h
if test 6347 -ne `wc -c <packet.h`; then
echo shar: \"packet.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rlog.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"rlog.c\"
else
echo shar: Extracting \"rlog.c\" \(20469 characters\)
sed "s/^X//" >rlog.c <<'END_OF_rlog.c'
X/*
X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University
X * All Rights Reserved
X *
X * Permission is granted to any individual or institution to use, copy,
X * or redistribute this software so long as it is not sold for profit,
X * provided that this notice and the original copyright notices are
X * retained. Boston University makes no representations about the
X * suitability of this software for any purpose. It is provided "as is"
X * without express or implied warranty.
X */
X# include <stdio.h>
X# include <ctype.h>
X# include "packet.h"
X
X# define EP_PUP 0x0200
X# define EP_XNS 0x0600
X# define EP_IP 0x0800
X# define EP_CHAOS 0x0804
X# define EP_ARP 0x0806
X# define EP_TRAIL 0x1000 /* TO DO! */
X# define EP_RARP 0x8035 /* TO DO! */
X# define EP_CTP 0x9000
X
Xint dumpdata = 1;
Xint indent = 0;
X
X/* counts: */
Xint count = 0;
Xint ipcount = 0;
Xint icmpcount = 0;
Xint tcpcount = 0;
Xint udpcount = 0;
Xint ndcount = 0;
Xint ippupcount = 0;
Xint ipidpcount = 0;
Xint egpcount = 0;
Xint ggpcount = 0;
Xint ipfragcount = 0;
Xint ipothercount = 0;
Xint ipbadvercount = 0;
Xint arpcount = 0;
Xint rarpcount = 0;
Xint ieeecount = 0;
Xint pupcount = 0;
Xint xnscount = 0;
Xint othercount = 0;
Xint ctpcount = 0;
X
X/****************************************************************/
X# include "protocol.h"
Xint pr_count[ NPROTO ];
X/****************************************************************/
X
Xint pc; /* packet byte count */
X
Xmain() {
X char line[ 4096 ];
X register byte *pp;
X register char *lp;
X
X pc = 0;
X pp = packet.p_bytes;
X while( gets( line ) ) {
X if( line[0] == ' ' || line[0] == '*' || line[0] == '\0' ) {
X if( pc > 0 )
X process();
X pp = packet.p_bytes;
X pc = 0;
X continue;
X }
X
X for( lp = line; *lp; lp++ ) {
X if( isspace( *lp ) )
X continue;
X else if( isxdigit( *lp ) && isxdigit( lp[1] ) ) {
X *pp++ = xval( *lp, lp[1] );
X lp++;
X pc++;
X }
X else
X fprintf( stderr, "you lose: %s\n", lp );
X }
X }
X if( pc > 0 )
X process();
X dump_stats();
X}
X
Xprocess() {
X register struct etherpacket *e = (struct etherpacket *) &packet;
X u_short type;
X
X count++;
X
X terpri();
X printf("Packet #%d\n", count );
X
X type = packet.p_ether.e_type;
X printf("Ether type %02X-%02X len %d ",
X (type >> 8) & 255, type & 255, pc );
X
X
X petaddr( e->e_src );
X putchar(' ');
X putchar('>');
X putchar(' ');
X petaddr( e->e_dst );
X terpri();
X
X switch( type ) {
X case EP_PUP:
X process_pup();
X break;
X case EP_IP:
X process_ip( 1, &packet.p_ether.e_data.d_ip );
X break;
X case EP_ARP:
X process_arp();
X break;
X case EP_RARP:
X process_rarp();
X break;
X case EP_XNS:
X process_xns();
X break;
X case EP_CTP:
X process_ctp();
X break;
X default:
X# ifdef IEEE
X if( packet.p_ether.e_type < 0x0600 )
X process_ieee( type );
X else
X# endif /* IEEE defined */
X process_other( type );
X break;
X }
X fflush( stdout );
X fflush( stderr );
X}
X
Xprocess_ip( live, i )
X int live; /* true if a real packet */
X /* false for icmp sent headers */
X register struct ipheader *i;
X{
X register byte *d, *op;
X int size;
X
X if( live)
X ipcount++;
X
X if( i->ip_ver != 4 ) {
X printf("IP version not 4 (%d)", i->ip_ver );
X terpri();
X ipbadvercount++;
X return;
X }
X
X printf("IP ");
X pipaddr( 1, i->ip_src );
X printf(" > ");
X pipaddr( 1, i->ip_dst );
X
X printf(" len %d",i->ip_len );
X
X if( i->ip_flgs & IP_FLG_DF ) /* don't frag */
X printf(" df");
X
X if( i->ip_flgs & IP_FLG_MF ) /* more frags/last frag */
X printf(" mf");
X
X/* if( i->ip_ttl != 0 && i->ip_ttl != 255 ) /**/
X printf(" ttl %d", i->ip_ttl );
X
X if( i->ip_tsrv != 0 ) {
X if( (i->ip_tsrv>>5) & 07 )
X printf(" prec %d", ((i->ip_tsrv>>5) & 07) );
X if( i->ip_tsrv & 020 )
X printf(" low_delay");
X if( i->ip_tsrv & 010 )
X printf(" hi_thruput");
X if( i->ip_tsrv & 04 )
X printf(" hi_rely");
X }
X
X /* more frags or offset? */
X printf(" id %d", i->ip_id );
X printf(" off %d", i->ip_foff << 3 );
X
X if( (i->ip_flgs & (IP_FLG_MF|IP_FLG_DF)) || i->ip_foff != 0 ) {
X if( i->ip_foff ) {
X if( live )
X ipfragcount++;
X }
X }
X terpri();
X
X d = ((byte *)(i)) + (i->ip_ihl << 2); /* point to data */
X
X /* options processing!! never tested */
X op = i->ip_options;
X while( op < d ) {
X if( *op & 0200 )
X printf(" copy");
X
X switch( ((*op)>>5)&03 ) { /* print option class */
X /* perhaps only for unkn types? */
X case 0:
X printf(" control");
X break;
X case 2:
X printf(" debug/meas");
X break;
X case 1:
X printf(" reserved1");
X break;
X case 3:
X printf(" reserved3");
X break;
X }
X
X switch( (*op) & 017 ) {
X case 0: /* end of list */
X goto end_of_options;
X
X case 1:
X printf(" noop");
X op++;
X break;
X
X case 2:
X printf(" security %02X %02X", op[2], op[3] );
X op += op[1]; /* should be 11 */
X break;
X
X case 3:
X printf(" LS+RR"); /* loose source */
X /* print more info! */
X op += op[1];
X break;
X
X case 4:
X printf(" TIMESTAMP");
X switch( op[3] &0xf ) {
X case 0:
X break; /* time stamps only */
X case 1:
X printf("+ADDRESS");
X break;
X
X case 2:
X printf(" ?flag 2?");
X break;
X
X case 3:
X printf(" (prespec)");
X break;
X }
X
X if( op[3] & 0xf0 )
X printf(" %d overflows", (op[3]>>4)&0xf );
X
X op += op[1];
X break;
X
X case 7:
X printf(" RR");
X /* print more info! */
X op += op[1];
X break;
X
X case 8:
X printf(" SATNET_Stream_ID");
X /* print more info! */
X op += op[1]; /* should be 4 */
X break;
X
X case 9:
X printf(" SS+RR"); /* strict source */
X /* print more info! */
X op += op[1];
X break;
X
X default:
X printf(" option %d.", *op&017 );
X op += op[1];
X break;
X } /* switch on option number */
X terpri();
X } /* while op */
X
Xend_of_options: ;
X
X if( i->ip_foff != 0 && live ) {
X printf(" FRAGMENT (proto %d.)", i->ip_prot );
X terpri();
X return; /* ?? */
X }
X
X size = pc - (d - packet.p_bytes);
X
X switch( i->ip_prot ) {
X case IP_PROT_UDP:
X if( live )
X udpcount++;
X process_ip_udp( d, size );
X break;
X case IP_PROT_TCP:
X if( live )
X tcpcount++;
X process_ip_tcp( d, size );
X break;
X case IP_PROT_ND:
X if( live )
X ndcount++;
X process_ip_nd( d, size );
X break;
X case IP_PROT_ICMP:
X if( live )
X icmpcount++;
X process_ip_icmp( d );
X break;
X case IP_PROT_GGP:
X printf("GGP");
X terpri();
X if( live )
X ggpcount++;
X /* process?? */
X break;
X case IP_PROT_EGP:
X printf("EGP");
X terpri();
X if( live )
X egpcount++;
X /* process?? */
X break;
X case IP_PROT_PUP:
X printf("PUP-IP");
X terpri();
X if( live )
X ippupcount++;
X break;
X case IP_PROT_IDP: /* xns idp */
X printf("IDP-IP (xns)");
X terpri();
X if( live )
X ipidpcount++;
X /* process?? */
X break;
X default:
X printf(" ipproto %d", i->ip_prot );
X terpri();
X if( live )
X ipothercount++;
X }
X}
X
Xprocess_ip_udp( d )
Xbyte *d;
X{
X register struct udpheader *u = (struct udpheader *) d;
X printf("UDP srcp: %d destp: %d", u->udp_srcp, u->udp_dstp );
X terpri();
X}
X
Xprocess_ip_tcp( d, size )
Xbyte *d;
X{
X register struct tcpheader *t = (struct tcpheader *) d;
X register byte *o, *td;
X int c, l;
X
X printf("TCP srcp: %d destp: %d", t->tcp_srcp, t->tcp_dstp );
X
X if( t->tcp_furg )
X printf(" urg %#x", t->tcp_urg );
X if( t->tcp_fack )
X printf(" ack %#x", t->tcp_ack );
X if( t->tcp_psh )
X printf(" psh");
X if( t->tcp_rst )
X printf(" rst");
X if( t->tcp_syn )
X printf(" syn");
X if( t->tcp_fin )
X printf(" fin");
X printf(" window %d.", t->tcp_win );
X
X c = ((t->tcp_thl) << 2); /* get tcp data offset */
X
X size -= c; /* get size of data */
X td = d + c; /* start of tcp data */
X
X printf(" data %d.", size );
X
X o = d + sizeof( struct tcpheader ); /* get start of options */
X c -= sizeof( struct tcpheader ); /* get size of options */
X
X while( c > 0 ) { /* process tcp options */
X switch( *o ) {
X case 0: /* end of list */
X goto break_options_loop;
X
X case 1: /* nop */
X l = 1;
X break;
X
X case 2: /* mss */
X l = o[1];
X if( l != 4 ) {
X printf("BAD_mss");
X }
X else
X printf(" mss %d", *((u_short *)(&o[2])) );
X break;
X
X default:
X l = o[1];
X printf(" option %d. (len %d.)", *o, l );
X break;
X } /* switch */
X o += l;
X c -= l;
X } /* tcp options loop */
X break_options_loop:;
X
X terpri();
X
X if( dumpdata ) {
X while( size-- > 0 )
X putbyte( *td++ );
X terpri();
X }
X} /* process_ip_tcp */
X
Xputbyte( c ) {
X if( c >= ' ' && c <= 0176 )
X putchar( c );
X else
X switch( c ) {
X case '\n':
X printf("\\n");
X break;
X case '\r':
X printf("\\r");
X break;
X case '\f':
X printf("\\f");
X break;
X /* ** MORE ESCAPES ** @@ */
X default:
X printf("\\%#o", c & 0xff );
X break;
X } /* switch */
X} /* putbyte */
X
Xprocess_ip_icmp( d )
Xbyte *d;
X{
X register struct icmppacket {
X byte icmp_type, icmp_code;
X u_short icmp_cksum;
X union {
X u_short id_short[2];
X u_long id_long[1];
X byte id_byte[4];
X } icmp_data;
X struct ipheader icmp_ip;
X } *i = (struct icmppacket *) d;
X
X static char *icmp_unreach_names[] = {
X "net", "host", "proto", "port", "need frag", "srcroute failed" };
X# define N_ICMP_UNREACH_NAMES (sizeof( icmp_unreach_names ) / sizeof( char * ))
X
X printf("ICMP ");
X switch( i->icmp_type ) {
X case 0: /* ECHOREPLY */
X case 8: /* ECHO */
X printf("echo");
X if( i->icmp_type == 0 )
X printf(" reply");
X printf(" id %d seq %d data: ",
X i->icmp_data.id_short[0], i->icmp_data.id_short[1] );
X pbytes( &i->icmp_data.id_byte[4], 16 );
X terpri();
X return;
X break;
X
X case 3: /* ICMP_UNREACH */
X if( i->icmp_code < N_ICMP_UNREACH_NAMES )
X printf("unreachable %s", icmp_unreach_names[ i->icmp_code ] );
X else
X printf("unreachable (code %d)", i->icmp_code );
X break;
X
X case 4:
X printf("source quench");
X break;
X
X case 5: /* ICMP_REDIRECT */
X printf("redirect");
X if( i->icmp_code == 0 )
X printf(" net");
X else if( i->icmp_code == 1 )
X printf(" host");
X else if( i->icmp_code == 2 )
X printf(" tos/net");
X else if( i->icmp_code == 3 )
X printf(" tos/host");
X else
X printf(" (code %d)", i->icmp_code );
X printf(" to ");
X pipaddr( 1, i->icmp_data.id_long[0] );
X break;
X
X case 11:
X switch( i->icmp_code ) {
X case 0:
X printf("ttl exceeded");
X break;
X case 1:
X printf("reassembly ttl exceeded");
X break;
X default:
X printf("time exceeded code %d", i->icmp_code );
X break;
X }
X break;
X
X case 12:
X printf("parmeter problem at %d", i->icmp_data.id_byte[0] );
X break;
X
X case 13:
X case 14:
X printf("timestamp");
X if( i->icmp_type == 14 )
X printf(" reply");
X printf(" id %d seq %d",
X i->icmp_data.id_short[0], i->icmp_data.id_short[1] );
X terpri();
X printf("orig ");
X ptime( i->icmp_data.id_long[1] );
X
X if( i->icmp_type == 14 ) { /* reply */
X printf(" rcv ");
X ptime( i->icmp_data.id_long[2] );
X printf(" xmit ");
X ptime( i->icmp_data.id_long[3] );
X }
X terpri();
X return;
X break;
X
X case 15:
X printf("info request id %d seq %d",
X i->icmp_data.id_short[0], i->icmp_data.id_short[1] );
X terpri();
X return;
X break;
X
X case 16:
X printf("info reply id %d seq %d",
X i->icmp_data.id_short[0], i->icmp_data.id_short[1] );
X terpri();
X return;
X break;
X
X case 17:
X printf("mask request id %d seq %d",
X i->icmp_data.id_short[0], i->icmp_data.id_short[1] );
X terpri();
X return; /* no enacpsulated packet */
X break;
X
X case 18:
X printf("mask reply id %d seq %d ",
X i->icmp_data.id_short[0], i->icmp_data.id_short[1] );
X pipaddr( 0, i->icmp_data.id_long[1] );
X terpri();
X return; /* no enacpsulated packet */
X break;
X
X default:
X printf("type %d", i->icmp_type );
X if( i->icmp_code != 0 )
X printf(" (code %d)", i->icmp_code );
X printf(" data: ");
X pbytes( i->icmp_data.id_byte, 4 );
X terpri();
X return; /* no enacpsulated packet?? */
X break;
X }
X
X indent += 4;
X terpri();
X process_ip( 0, &i->icmp_ip ); /* RECURSE!! */
X indent -= 4;
X terpri();
X}
X
Xptime( t )
Xu_long t;
X{
X int h, m, s;
X if( t & 0x40000000 ) {
X printf( "%d.", t & 0xbfffffff );
X return;
X }
X s = t / 1000;
X m = s / 60;
X h = m / 60;
X
X m %= 60;
X s %= 60;
X t %= 1000;
X if( h > 0 )
X printf("%dh", h );
X if( m > 0 )
X printf("%dm", m );
X printf("%d.%03d", s, t );
X}
X
Xprocess_ip_nd( d )
Xbyte *d;
X{
X register struct ndpacket *n = (struct ndpacket *) d;
X
X printf("ND");
X
X switch( n->nd_op & 7 ) {
X case 1:
X printf(" read");
X break;
X case 2:
X printf(" write");
X break;
X case 3:
X printf(" error");
X break;
X default:
X printf(" op %d", n->nd_op & 7 );
X break;
X }
X if( n->nd_op & 010 )
X printf(" wait");
X if( n->nd_op & 020 )
X printf(" done");
X
X printf(" /dev/nd");
X if( n->nd_dev > 0177 )
X putchar('l');
X else if( n->nd_dev > 077 )
X putchar('p');
X printf("%d seq %d", n->nd_dev & 077, n->nd_seq );
X printf(" block %d count %d",
X n->nd_blk, n->nd_count);
X if( n->nd_res > 0 )
X printf(" resid %d", n->nd_res );
X if( n->nd_off > 0 )
X printf(" off %d",
X n->nd_off );
X if( n->nd_data > 0 )
X printf(" data %d",
X n->nd_data );
X terpri();
X}
X
Xprocess_arp() {
X arpcount++;
X printf("ARP");
X process_arp2(0);
X}
X
X# define EA_NZERO(p) ( (*(long *)p) != 0 && (*(short *)(p+4)) != 0 )
X
Xprocess_arp2(israrp) {
X register struct arppacket *a = &packet.p_ether.e_data.d_arp;
X register struct protocol *pp;
X int xsha, xspa, xtha, xtpa;
X ip_addr i;
X
X xsha = 0; /* sender hdw addr */
X xspa = a->arp_hln; /* sender proto addr */
X xtha = xspa + a->arp_pln; /* target hdw addr */
X xtpa = xtha + a->arp_hln; /* target proto addr */
X
X switch( a->arp_hw ) {
X case ARP_HW_ETHER:
X break;
X case ARP_HW_XETHER:
X printf(" 3Mb ether");
X break;
X case ARP_HW_AX25:
X printf(" AX.25");
X break;
X case ARP_HW_PRONET:
X printf(" PROnet");
X break;
X case ARP_HW_CHAOS:
X printf(" Chaos");
X break;
X case ARP_HW_IEEE802:
X printf(" IEEE 802");
X break;
X }
X
X switch( a->arp_pro ) {
X case EP_IP:
X case EP_TRAIL:
X printf(" IP");
X if( a->arp_pro == EP_TRAIL )
X printf(" trailers");
X if( a->arp_op == ARP_REQUEST )
X printf(" request ");
X else if( a->arp_op == RARP_REQUEST )
X printf(" reverse request ");
X else if( a->arp_op == RARP_REPLY )
X printf(" reverse reply ");
X else
X printf(" op %d ", a->arp_op );
X
X printf("source");
X if( EA_NZERO( a->arp_data + xsha ) ) {
X putchar(' ');
X petaddr( a->arp_data + xsha );
X }
X i = * (ip_addr *) (a->arp_data + xspa);
X if( i != 0 ) {
X putchar(' ');
X pipaddr( 1, i );
X }
X terpri();
X
X printf("target");
X if( EA_NZERO( a->arp_data + xtha ) ) {
X putchar(' ');
X petaddr( a->arp_data + xtha );
X }
X i = * (ip_addr *) (a->arp_data + xtpa);
X if( i != 0 ) {
X putchar(' ');
X pipaddr( 1, i );
X }
X terpri();
X return;
X
X case EP_CHAOS:
X printf(" CHAOS ");
X if( a->arp_op == ARP_REQUEST )
X printf(" request ");
X else if( a->arp_op == ARP_REPLY )
X printf(" reply to ");
X else
X printf("op %d ", a->arp_op );
X
X printf("source ");
X petaddr( a->arp_data + xsha );
X putchar( ' ' );
X printf("%#o ", * (u_short *) (a->arp_data + xspa) );
X terpri();
X
X printf("target ");
X petaddr( a->arp_data + xtha );
X putchar(' ');
X printf("%#o ", * (u_short *) (a->arp_data + xtpa) );
X terpri();
X
X return;
X
X default:
X for( pp = protocols; pp->pr_type != 0; pp++ )
X if( a->arp_pro == pp->pr_type ) {
X printf("%s ???", pp->pr_name );
X terpri();
X return;
X }
X printf("%02X-%02X ???", (a->arp_pro >> 8) & 255,
X a->arp_pro & 255 );
X terpri();
X }
X}
X
Xprocess_ieee( l )
Xu_short l;
X{
X ieeecount++;
X printf("IEEE len %d", l );
X terpri();
X}
X
Xprocess_pup() {
X register struct puppacket *p = &packet.p_ether.e_data.d_pup;
X pupcount++;
X printf("PUP len %d transport %d type %#o id %d",
X p->pup_len, p->pup_transport, p->pup_type );
X terpri();
X printf("src net %#o host %#o socket %#o",
X p->pup_src.pup_port_net,
X p->pup_src.pup_port_host,
X (p->pup_src.pup_port_sock1) << 16 +
X p->pup_src.pup_port_sock2 );
X terpri();
X printf("dst net %#o host %#o socket %#o",
X p->pup_dst.pup_port_net,
X p->pup_dst.pup_port_host,
X (p->pup_dst.pup_port_sock1) << 16 +
X p->pup_dst.pup_port_sock2 );
X terpri();
X}
X
Xprocess_rarp() {
X rarpcount++;
X printf("RARP");
X process_arp2(1);
X}
X
X# define CTP_REP 1
X# define CTP_FWD 2
X# define CTP_SHORT(sp) (*sp | (sp[1]<<8))
X
Xprocess_ctp() {
X byte *p2, *p = packet.p_ether.e_data.d_bytes;
X short f, skip;
X int len, l2;
X
X ctpcount++;
X skip = CTP_SHORT(p);
X p2 = p + skip + 2; /* point to data (skip skip!) */
X len = pc - 14 - skip - 2; /* length of data */
X
X printf("CTP skip %d.", skip );
X terpri();
X for( ; ; ) {
X if( len < 2 )
X return;
X
X f = CTP_SHORT( p2 ); /* get function */
X p2 += 2; /* advance past function */
X len -= 2; /* account for function length */
X switch( f ) {
X case CTP_REP: /* reply */
X printf(" REPLY data: ");
X goto break_for;
X break;
X
X case CTP_FWD: /* forward */
X if( len < 6 ) {
X printf("Too little data for FORWARD packet");
X terpri();
X return;
X }
X printf(" FORWARD to: ");
X petaddr( p2 ); /* print ether addr */
X terpri();
X p2 += 6; /* advance data */
X len -=6; /* account for len */
X break;
X
X default:
X printf(" fncn %d. data: ", f );
X goto break_for;
X }
X }
X break_for: ;
X l2 = len;
X if( l2 > 32 )
X l2 = 32;
X pbytes( p2, l2 );
X if( len > 32 )
X printf("...");
X terpri();
X}
X
Xprocess_xns() {
X register struct xnspacket *x = &packet.p_ether.e_data.d_xns;
X xnscount++;
X printf("XNS IDP len %d transport %d type %d",
X x->xns_len, x->xns_tc, x->xns_pt );
X terpri();
X printf("src: ");
X pxnsaddr( &x->xns_src );
X terpri();
X
X printf("dst: ");
X pxnsaddr( &x->xns_dst );
X terpri();
X}
X
Xpxnsaddr( xa )
X register struct xns_addr *xa;
X{
X pbytes( xa->xnsa_net, 4 );
X putchar(':');
X pbytes( xa->xnsa_host, 6 );
X printf(" port %d", xa->xnsa_port );
X}
X
Xprocess_other( type )
Xint type;
X{
X register struct protocol *pp;
X register int i;
X
X for( i = 0, pp = protocols; pp->pr_type != 0; i++, pp++ )
X if( type == pp->pr_type ) {
X printf( "%s", pp->pr_name );
X terpri();
X pr_count[ i ]++;
X pbytes( packet.p_ether.e_data.d_bytes, 32 );
X printf("...");
X terpri();
X return;
X }
X else if( type < pp->pr_type )
X break;
X pbytes( packet.p_ether.e_data.d_bytes, 32 );
X printf("...");
X terpri();
X othercount++;
X}
X
Xdump_stats() {
X register struct protocol *pp;
X int i;
X
X if( count > 0 )
X fprintf( stderr, "count: %d\n", count );
X if( ipcount > 0 )
X fprintf( stderr, " ipcount: %d\n", ipcount );
X if( icmpcount > 0 )
X fprintf( stderr, " icmpcount: %d\n", icmpcount );
X if( tcpcount > 0 )
X fprintf( stderr, " tcpcount: %d\n", tcpcount );
X if( udpcount > 0 )
X fprintf( stderr, " udpcount: %d\n", udpcount );
X if( ndcount > 0 )
X fprintf( stderr, " ndcount: %d\n", ndcount );
X if( egpcount > 0 )
X fprintf( stderr, " egpcount: %d\n", egpcount );
X if( ggpcount > 0 )
X fprintf( stderr, " ggpcount: %d\n", ggpcount );
X if( ippupcount > 0 )
X fprintf( stderr, " ippupcount: %d\n", ippupcount );
X if( ipidpcount > 0 )
X fprintf( stderr, " ipidpcount: %d\n", ipidpcount );
X if( ipfragcount > 0 )
X fprintf( stderr, " ipfragcount: %d\n", ipfragcount );
X if( ipothercount > 0 )
X fprintf( stderr, " ipothercount: %d\n", ipothercount );
X if( ipbadvercount > 0 )
X fprintf( stderr, " ipbadvercount: %d\n", ipbadvercount );
X if( arpcount > 0 )
X fprintf( stderr, " arpcount: %d\n", arpcount );
X if( rarpcount > 0 )
X fprintf( stderr, " rarpcount: %d\n", rarpcount );
X if( ieeecount > 0 )
X fprintf( stderr, " ieeecount: %d\n", ieeecount );
X if( pupcount > 0 )
X fprintf( stderr, " pupcount: %d\n", pupcount );
X if( xnscount > 0 )
X fprintf( stderr, " xnscount: %d\n", xnscount );
X if( ctpcount > 0 )
X fprintf( stderr, " ctpcount: %d\n", ctpcount );
X
X for( i = 0, pp = protocols; pp->pr_type != 0; i++, pp++ )
X if( pr_count[i] > 0 )
X fprintf( stderr, " %s: %d\n", pp->pr_name, pr_count[i] );
X
X if( othercount > 0 )
X fprintf( stderr, " othercount: %d\n", othercount );
X}
X
Xterpri() {
X register int i = indent;
X putchar( '\n' );
X while( i-- > 0 )
X putchar( ' ' );
X}
END_OF_rlog.c
if test 20469 -ne `wc -c <rlog.c`; then
echo shar: \"rlog.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked both archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
More information about the Comp.sources.sun
mailing list