mcgrew@dartagnan.rutgers.edu (Charles Mcgrew) (06/22/89)
Submitted-by: budd@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@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