nfswatch-4.99.11/0000755000551200011300000000000011364243136012674 5ustar chrisludwignfswatch-4.99.11/nit.c0000644000551200011300000001057710177742445013654 0ustar chrisludwig/* * $Id: nit.c,v 1.2 2005/02/01 18:06:29 c4chris Exp $ */ #include "os.h" #ifdef USE_NIT /* * nit.c - routines for messing with the network interface tap. * * David A. Curry * Purdue University * Engineering Computer Network * 1285 Electrical Engineering Building * West Lafayette, IN 47907-1285 * davy@ecn.purdue.edu * */ #include #include #include #include #include #include #include #include #include #include #include #include "nfswatch.h" #include "externs.h" #if NOFILE <= 64 #define SUNOS40 1 #endif /* * setup_nit_dev - set up the network interface tap. */ int setup_nit_dev(device) char **device; { int n, s, fd; u_int chunksz; u_long if_flags; char buf[BUFSIZ]; struct ifconf ifc; struct strioctl si; struct timeval timeout; struct ifreq ifr, *ifrp; /* * If the interface device was not specified, * get the default one. */ if (*device == NULL) { /* * Grab a socket. */ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { error("socket"); finish(-1); } ifc.ifc_buf = buf; ifc.ifc_len = sizeof(buf); /* * See what devices we've got. */ if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) { error("ioctl: SIOCGIFCONF"); finish(-1); } /* * Take the first device we encounter. */ ifrp = ifc.ifc_req; for (n = ifc.ifc_len/sizeof(struct ifreq); n > 0; n--,ifrp++) { /* * Skip the loopback interface. */ if (strcmp(ifrp->ifr_name, "lo0") == 0) continue; *device = strdup(ifrp->ifr_name); break; } (void) close(s); } /* * We want the ethernet in promiscuous mode if we're looking * at nodes other than ourselves, and we want to know about * dropped packets. */ if (allflag || dstflag) if_flags = NI_DROPS | NI_PROMISC | NI_TIMESTAMP; else if_flags = NI_DROPS | NI_TIMESTAMP; /* * Open the network interface tap. */ if ((fd = open(NIT_DEV, O_RDONLY)) < 0) { error("nit: open"); finish(-1); } /* * Arrange to get discrete messages. */ if (ioctl(fd, I_SRDOPT, (char *) RMSGD) < 0) { error("ioctl: I_SRDOPT"); finish(-1); } /* * Push and configure the nit buffering module. */ if (ioctl(fd, I_PUSH, NIT_BUF) < 0) { error("ioctl: I_PUSH NIT_BUF"); finish(-1); } /* * Set the read timeout. */ timeout.tv_sec = 1; timeout.tv_usec = 0; si.ic_cmd = NIOCSTIME; si.ic_timout = INFTIM; si.ic_len = sizeof(timeout); si.ic_dp = (char *) &timeout; if (ioctl(fd, I_STR, (char *) &si) < 0) { error("ioctl: I_STR NIOCSTIME"); finish(-1); } /* * Set the chunk size. */ chunksz = NIT_CHUNKSIZE; si.ic_cmd = NIOCSCHUNK; si.ic_len = sizeof(chunksz); si.ic_dp = (char *) &chunksz; if (ioctl(fd, I_STR, (char *) &si) < 0) { error("ioctl: I_STR NIOCSCHUNK"); finish(-1); } /* * Configure the network interface tap by binding it * to the underlying interface, setting the snapshot * length, and setting the flags. */ (void) strncpy(ifr.ifr_name, *device, sizeof(ifr.ifr_name)); ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0'; si.ic_cmd = NIOCBIND; si.ic_len = sizeof(ifr); si.ic_dp = (char *) 𝔦 /* * If the bind fails, there's no such device. */ if (ioctl(fd, I_STR, (char *) &si) < 0) { close(fd); return(-1); } /* * SNAP is buggy on SunOS 4.0.x */ #ifndef SUNOS40 si.ic_cmd = NIOCSSNAP; si.ic_len = sizeof(truncation); si.ic_dp = (char *) &truncation; if (ioctl(fd, I_STR, (char *) &si) < 0) { error("ioctl: I_STR NIOCSSNAP"); finish(-1); } #endif si.ic_cmd = NIOCSFLAGS; si.ic_len = sizeof(if_flags); si.ic_dp = (char *) &if_flags; if (ioctl(fd, I_STR, (char *) &si) < 0) { error("ioctl: I_STR NIOCSFLAGS"); finish(-1); } return(fd); } /* * flush_nit - flush data from the nit. */ void flush_nit(fd) int fd; { if (ioctl(fd, I_FLUSH, (char *) FLUSHR) < 0) { error("ioctl: I_FLUSH"); finish(-1); } } /* * nit_devtype - determine the type of device we're looking at. */ int nit_devtype(device) char *device; { /* * This whole routine is a kludge. Ultrix does it the * right way; see pfilt.c. */ if (strncmp(device, "le", 2) == 0 || strncmp(device, "ie", 2) == 0) return(DLT_EN10MB); if (strncmp(device, "fddi", 4) == 0) return(DLT_FDDI); fprintf(stderr, "Unknown device type: %s -- assuming ethernet.\n", device); return(DLT_EN10MB); } #endif /* USE_NIT */ nfswatch-4.99.11/ipports.h0000644000551200011300000000271410177742444014560 0ustar chrisludwig/* * $Id: ipports.h,v 1.2 2005/02/01 18:06:28 c4chris Exp $ * * ipport.h - port definitions used by nfswatch, not provided by Ultrix * * Jeffrey Mogul * DECWRL * */ /* * In Ultrix and BSD, programs always use "getservbyname" to * do these translations, but I guess someone at Sun had to * build a case table at some point. */ #define IPPORT_ROUTESERVER 520 /* routing control protocol */ #define IPPORT_ECHO 7 /* packet echo server */ #define IPPORT_DISCARD 9 /* packet discard server */ #define IPPORT_SYSTAT 11 /* system stats */ #define IPPORT_DAYTIME 13 /* time of day server */ #define IPPORT_NETSTAT 15 /* network stats */ #define IPPORT_FTP 21 /* file transfer */ #define IPPORT_TELNET 23 /* remote terminal service */ #define IPPORT_SMTP 25 /* simple mail transfer protocol*/ #define IPPORT_TIMESERVER 37 /* network time synchronization */ #define IPPORT_NAMESERVER 53 /* domain name lookup */ #define IPPORT_WHOIS 43 /* white pages */ #define IPPORT_MTP 57 /* ??? */ #define IPPORT_TFTP 69 /* trivial file transfer */ #define IPPORT_RJE 77 /* remote job entry */ #define IPPORT_FINGER 79 /* finger */ #define IPPORT_TTYLINK 87 /* ??? */ #define IPPORT_SUPDUP 95 /* SUPDUP */ #define IPPORT_EXECSERVER 512 /* rsh */ #define IPPORT_LOGINSERVER 513 /* rlogin */ #define IPPORT_CMDSERVER 514 /* rcmd */ #define IPPORT_BIFFUDP 512 /* biff mail notification */ #define IPPORT_WHOSERVER 513 /* rwho */ nfswatch-4.99.11/logfile.c0000644000551200011300000001774510542251641014474 0ustar chrisludwig/* * $Id: logfile.c,v 1.4 2006/12/20 15:15:45 c4chris Exp $ */ #include "os.h" /* * logfile.c - routines for updating log and snapshot files * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ #include #include #include #include #include #include #include "nfswatch.h" #include "externs.h" #include "screen.h" #ifdef SUNOS5 static char *scrncpy(char *, chtype *, int); #endif /* * snapshot - take a snapshot of the screen. */ void snapshot(void) { FILE *fp; register int x, y; char buffer[BUFSIZ]; /* * We want to append to the snapshot file. */ if ((fp = fopen(snapshotfile, "a")) == NULL) { (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "could not open \"%s\"", snapshotfile); (void) refresh(); return; } #ifdef NCURSES_VERSION for (y = 0; y < LINES - 1; y++) { int lastnb = 0; for(x = 0; x < COLS; x++) { chtype ch = mvinch(y, x); buffer[x] = ch & A_CHARTEXT; if (buffer[x] != ' ') lastnb = x; } lastnb += 1; buffer[lastnb++] = '\n'; buffer[lastnb] = '\0'; fputs(buffer, fp); } #else /* * For all lines but the last one ... */ for (y = 0; y < LINES - 1; y++) { (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "dumping line %d", y + 1); (void) clrtoeol(); (void) refresh(); /* * Search backwards on each line for a non-space. * x is the count of significant characters. */ for (x = COLS - 1; x > 0; x--) { /* * Non-space found, increment Z and exit loop */ if (curscr->_y[y][x] != ' ') { x++; break; } } /* * Copy x characters and append a \n and \0 to the * string, then output it. */ #ifdef SUNOS5 (void) scrncpy(buffer, curscr->_y[y], x); #else (void) strncpy(buffer, curscr->_y[y], x); #endif buffer[x++] = '\n'; buffer[x] = '\0'; (void) fputs(buffer, fp); } (void) fputc('\014', fp); #endif (void) fclose(fp); /* * Tell them we're done. */ (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "screen dumped to \"%s\"", snapshotfile ); (void) refresh(); } /* * update_logfile - put out the information to the log file. */ void update_logfile(void) { char *tstr; char *ctime(); float percent; char buf[BUFSIZ]; struct timeval tv; register int i, j, nfstotal; long count, tot_count; double dcount, sumsqr, sum; static char nfsprocs_header[80] = " Procedure int pct total completed ave.resp var.resp max.resp"; (void) gettimeofday(&tv, (struct timezone *) 0); /* * Start a log entry. */ (void) fprintf(logfp, "#\n# begin\n#\n"); (void) fprintf(logfp, "Date: %.24s\n", ctime(&tv.tv_sec)); tv.tv_sec -= starttime.tv_sec; tstr = prtime(tv.tv_sec); (void) fprintf(logfp, "Cycle Time: %d\n", cycletime); (void) fprintf(logfp, "Elapsed Time: %.8s\n", tstr+11); /* * Print total packet counters. */ (void) fprintf(logfp, "#\n# total packets %8s %8s %8s\n#\n", "network", "to host", "dropped"); (void) fprintf(logfp, "Interval Packets: %8ld %8ld %8ld\n", int_pkt_total, int_dst_pkt_total, int_pkt_drops); (void) fprintf(logfp, "Total Packets: %8ld %8ld %8ld\n", pkt_total, dst_pkt_total, pkt_drops); /* * Put out a header for the packet counters. */ (void) fprintf(logfp, "#\n# packet counters %8s %8s %8s\n#\n", "int", "pct", "total"); /* * Print the packet counters. Percentage is calculated as * this interval counter over total packets this interval. */ for (i = 0; i < PKT_NCOUNTERS; i++) { if (int_dst_pkt_total) { percent = ((float) pkt_counters[i].pc_interval / (float) int_dst_pkt_total) * 100.0; } else { percent = 0.0; } (void) sprintf(buf, "%s:", pkt_counters[i].pc_name); (void) fprintf(logfp, "%-25s %8ld %7.0f%% %8ld\n", buf, pkt_counters[i].pc_interval, percent, pkt_counters[i].pc_total); } /* * Calculate the total number of NFS packets this * interval. */ nfstotal = pkt_counters[PKT_NFSWRITE].pc_interval + pkt_counters[PKT_NFSREAD].pc_interval; /* * Put out a header for the NFS counters. */ (void) fprintf(logfp, "#\n# nfs counters %8s %8s %8s\n#\n", "int", "pct", "total"); /* * Print the NFS counters. Percentage is calculated as * packets this interval over total NFS packets this * interval. */ for (i = 0; i < nnfscounters; i++) { if (nfstotal) { percent = ((float) nfs_counters[i].nc_interval / (float) nfstotal) * 100.0; } else { percent = 0.0; } (void) sprintf(buf, "%s:", nfs_counters[i].nc_name); (void) fprintf(logfp, "%-25s %8ld %7.0f%% %8ld\t", buf, nfs_counters[i].nc_interval, percent, nfs_counters[i].nc_total); /* * Print individual proc counters. */ (void) fputc('(', logfp); for (j = 0; j < MAXNFSPROC; j++) { if (j) (void) fputc('/', logfp); (void) fprintf(logfp, "%ld", nfs_counters[i].nc_proc[j]); } (void) fprintf(logfp, ")\n"); } /* * Put out a header for the individual file counters. */ (void) fprintf(logfp, "#\n# file counters %8s %8s %8s\n#\n", "int", "pct", "total"); /* * Print the individual file counters. Percentage is * calculated as packets this interval over total NFS * packets this interval. */ for (i = 0; i < nfilecounters; i++) { if (nfstotal) { percent = ((float) fil_counters[i].fc_interval / (float) nfstotal) * 100.0; } else { percent = 0.0; } (void) sprintf(buf, "%s:", fil_counters[i].fc_name); (void) fprintf(logfp, "%-25s %8ld %7.0f%% %8ld\t", buf, fil_counters[i].fc_interval, percent, fil_counters[i].fc_total); /* * Print individual proc counters. */ (void) fputc('(', logfp); for (j = 0; j < MAXNFSPROC; j++) { if (j) (void) fputc('/', logfp); (void) fprintf(logfp, "%ld", fil_counters[i].fc_proc[j]); } (void) fprintf(logfp, ")\n"); } /* * Put out a header for the NFS procs counters. */ if (showwhich == SHOWNFSPROCS || showwhich == SHOWNFS3PROCS) { int proto = NFSv2; int lim = MAXNFSPROC; if (showwhich == SHOWNFS3PROCS) { proto = NFSv3; lim = MAXNFS3PROC; } (void) fprintf(logfp, "#\n# nfs procs \n#\n"); (void) fprintf(logfp, "%s\n", nfsprocs_header); tot_count = 0; for (i = 0; i < lim; i++) { tot_count += prc_counters[proto][i].pr_interval; } for (i = 0; i < lim; i++) { if (tot_count) percent = (((float) prc_counters[proto][i].pr_interval) / ((float)tot_count)) * 100.0; else percent = 0.0; (void) fprintf(logfp, "%-17s %5ld %3.0f%% %8ld", nfs_procnams[proto][i], prc_counters[proto][i].pr_interval, percent, prc_counters[proto][i].pr_total); count = prc_counters[proto][i].pr_complete; if (count != 0) { dcount = (double) count; sum = prc_counters[proto][i].pr_response; sumsqr = prc_counters[proto][i].pr_respsqr; (void) fprintf(logfp, " %8ld %8.2f", count, sum /dcount); if (count > 1) { (void) fprintf(logfp, " %8.2f", sqrt((dcount * sumsqr - sum * sum) / (dcount * (dcount - 1.0)))); } else { (void) fprintf(logfp, " "); } (void) fprintf(logfp, " %8.2f", prc_counters[proto][i].pr_maxresp); } (void) fprintf(logfp, "\n"); } } /* * End the log entry. */ (void) fprintf(logfp, "#\n# end\n#\n"); (void) fflush(logfp); } #ifdef SUNOS5 /* * scrncpy - copy a curses array of chtype's (s2) to a character array (s1), * truncating or null padding to always copy n bytes. */ static char * scrncpy(char *s1, chtype *s2, int n) { register char *os1; os1 = s1; n++; while ((--n != 0) && ((*s1++ = *s2++) != '\0')) ; if (n != 0) { while (--n != 0) *s1++ = '\0'; } return(os1); } #endif /* SUNOS5 */ nfswatch-4.99.11/nfswatch.c0000644000551200011300000006402511173256260014664 0ustar chrisludwig/* * $Id: nfswatch.c,v 1.15 2009/04/21 05:42:08 c4chris Exp $ */ #include "os.h" /* * nfswatch - NFS server packet monitoring program. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ /* * TODO: implement count by interface if possible * */ #include #include #include #include #include #include #include #include #include #include #include #ifdef USE_DLPI #include #if defined(SVR4) && !defined(SUNOS5) char *devices[] = { "emd0", "emd1", "emd2", "emd3", "emd4", 0 }; #endif #ifdef SUNOS5 #include char *devices[] = { "le0", "le1", "le2", "le3", "le4", "ie0", "ie1", "ie2", "ie3", "ie4", "qe0", "qe1", "qe2", "qe3", "qe4", "qe5", "qe6", "qe7", "fddi0", "fddi1", "fddi2", "fddi3", "fddi4", "bf0", "bf1", 0 }; #endif #endif /* USE_DLPI */ #ifdef USE_NIT #include #include char *devices[] = { "le0", "le1", "le2", "le3", "le4", "ie0", "ie1", "ie2", "ie3", "ie4", "fddi0", "fddi1", "fddi2", "fddi3", "fddi4", "qe0", "qe1", "qe2", "qe3", "qe4", "qe5", "qe6", "qe7", "bf0", "bf1", 0 }; #endif /* USE_NIT */ #ifdef USE_PFILT #include char *devices[] = { "pf0", "pf1", "pf2", "pf3", "pf4", "pf5", "pf6", "pf7", "pf8", "pf9", 0 }; #endif /* USE_PFILT */ #ifdef USE_SNOOP #include #include #include #define ETHERHDRPAD RAW_HDRPAD(sizeof(struct ether_header)) char *devices[] = { "et0", "et1", "et2", "et3", "et4", "ec0", "ec1", "ec2", "ec3", "ec4", "fxp0", "fxp1", "fxp2", "fxp3", "fxp4", "enp0", "enp1", "enp2", "enp3", "enp4", "ipg0", "ipg1", "ipg2", "ipg3", "ipg4", 0 }; struct etherpacket { struct snoopheader snoop; char pad[ETHERHDRPAD]; struct ether_header ether; char data[ETHERMTU]; }; #endif /* USE_SNOOP */ #include "nfswatch.h" #include "externs.h" /* * Names of NFS procedures (MUST be kept in the right order) * two leading spaces make things look nicer */ char *nfs_procnams[NFSHIGHPROTO + 1][MAXNFS3PROC] = { { }, /* NULL PROTOCOL */ { }, /* NULL PROTOCOL */ { /* NFSv2 */ " NULLPROC", " GETATTR", " SETATTR", " GETROOT", " LOOKUP", " READLINK", " READ", " WCACHE", " WRITE", " CREATE", " REMOVE", " RENAME", " LINK", " SYMLINK", " MKDIR", " RMDIR", " READDIR", " STATFS" }, { /* NFSv3 */ " NULLPROC", " GETATTR", " SETATTR", " LOOKUP", " ACCESS", " READLINK", " READ", " WRITE", " CREATE", " MKDIR", " SYMLINK", " MKNOD", " REMOVE", " RMDIR", " RENAME", " LINK", " READDIR", " READDIRPLUS", " FSSTAT", " FSINFO", " PATHCONF", " COMMIT" }, { /* NFSv4 */ /* Nothing yet... */ } }; static void nfswatch(void); #ifdef USE_LINUX linux_socket_handle_t ls; #endif /* USE_LINUX */ char *pname; /* program name */ FILE *logfp; /* log file pointer */ Counter pkt_total = 0; /* total packets seen */ Counter pkt_drops = 0; /* total packets dropped*/ Counter int_pkt_total = 0; /* packets this interval*/ Counter int_pkt_drops = 0; /* dropped this interval*/ Counter dst_pkt_total = 0; /* total pkts to host */ Counter int_dst_pkt_total = 0; /* pkts to host this int*/ #ifndef USE_LINUX int if_fd[MAXINTERFACES]; /* LAN device file desc */ int if_dlt[MAXINTERFACES]; /* LAN data link type */ #endif int bgflag = 0; /* "-bg" specified */ int srcflag = 0; /* "-src" specified */ int dstflag = 0; /* "-dst" specified */ int allflag = 0; /* "-all" specified */ int allintf = 0; /* "-allif" specified */ int fhdebugf = 0; /* "-fhdebug" specified */ int logging = 0; /* 1 when logging on */ int learnfs = 0; /* learn other servers */ int do_update = 0; /* time to update screen*/ int showwhich = 0; /* show filesys or files*/ int serverflag = 0; /* "-server" specified */ int cycletime = CYCLETIME; /* update cycle time */ int totaltime = 0; /* total run time */ #if defined(SUNOS5) && !defined(SUNOS54) /* Avoid bug in 2.3 DLPI bufmod - BugID #1149065 */ unsigned int truncation = 1500; /* pkt trunc len - magic*/ #else unsigned int truncation = 200; /* pkt trunc len - magic*/ #endif int sortbyusage = 0; /* sort by usage counts */ int nnfscounters = 0; /* # of NFS counters */ int nfilecounters = 0; /* # of file counters */ int nauthcounters = 0; /* # of auth counters */ int nclientcounters = 0; /* # of client counters */ int screen_inited = 0; /* 1 when in curses */ struct timeval starttime; /* time we started */ #ifndef USE_LINUX int ninterfaces; /* number of interfaces */ #endif ipaddrt thisdst = 0; /* cached IP dst of pkt */ ipaddrt srcaddrs[MAXHOSTADDR]; /* src host net addrs */ ipaddrt dstaddrs[MAXHOSTADDR]; /* dst host net addrs */ ipaddrt serveraddrs[MAXHOSTADDR]; /* server host net addrs*/ char myhost[MAXHOSTNAMELEN]; /* local host name */ char srchost[MAXHOSTNAMELEN]; /* source host name */ char dsthost[MAXHOSTNAMELEN]; /* destination host name*/ char serverhost[MAXHOSTNAMELEN]; /* server host name */ char *prompt = PROMPT; /* prompt string */ char *filelist = NULL; /* list of files */ char *logfile = LOGFILE; /* log file name */ char *mapfile = NULL; /* map file name */ char *snapshotfile = SNAPSHOTFILE; /* snapshot file name */ NFSCounter nfs_counters[MAXEXPORT]; /* NFS request counters */ FileCounter fil_counters[MAXEXPORT]; /* file request counters*/ PacketCounter pkt_counters[PKT_NCOUNTERS]; /* packet counters */ ProcCounter prc_counters[NFSHIGHPROTO + 1][MAXNFS3PROC + 2]; /* procedure counters */ /* extra space simplifies sort_prc_counters */ int prc_countmap[NFSHIGHPROTO + 1][MAXNFS3PROC]; /* allows sorting */ ClientCounter clnt_counters[MAXCLIENTS]; /* per-client counters */ AuthCounter auth_counters[MAXAUTHS]; /* per-auth counters */ unsigned long *rpcPort; /* list of RPC ports */ unsigned int rpcPortCnt; /* count of RPC ports */ #ifdef ultrix void fpe_warn() { fprintf(stderr, "nfswatch: mystery bug encountered.\n"); finish(-1); } #endif int main(int argc, char **argv) { #ifndef USE_LINUX register int i; #endif char *device = NULL; pname = *argv; /* * Get our host name. The default destination * host is the one we're running on. */ if (gethostname(myhost, sizeof(myhost)) < 0) { error("gethostname"); finish(-1); } (void) strcpy(dsthost, myhost); /* * Process arguments. */ while (--argc) { if (**++argv != '-') usage(); /* * Set destination host. */ if (!strcmp(*argv, "-dst")) { if (--argc <= 0) usage(); (void) strcpy(dsthost, *++argv); dstflag++; continue; } /* * Set source host. */ if (!strcmp(*argv, "-src")) { if (--argc <= 0) usage(); (void) strcpy(srchost, *++argv); srcflag++; continue; } /* * Set server host. */ if (!strcmp(*argv, "-server")) { if (--argc <= 0) usage(); (void) strcpy(serverhost, *++argv); serverflag++; continue; } /* * Device to use. */ if (!strcmp(*argv, "-dev")) { if (--argc <= 0) usage(); device = *++argv; continue; } /* * Log file name. */ if (!strcmp(*argv, "-lf")) { if (--argc <= 0) usage(); logfile = *++argv; continue; } /* * Snapshot file name. */ if (!strcmp(*argv, "-sf")) { if (--argc <= 0) usage(); snapshotfile = *++argv; continue; } /* * List of files. */ if (!strcmp(*argv, "-f")) { if (--argc <= 0) usage(); if (showwhich == 0) showwhich = SHOWINDVFILES; filelist = *++argv; continue; } /* * Set map file. */ if (!strcmp(*argv, "-map")) { if (--argc <= 0) usage(); mapfile = *++argv; continue; } /* * Set total run time. */ if (!strcmp(*argv, "-T")) { if (--argc <= 0) usage(); totaltime = atoi(*++argv); continue; } /* * Change cycle time. */ if (!strcmp(*argv, "-t")) { if (--argc <= 0) usage(); cycletime = atoi(*++argv); continue; } /* * Show RPC authentication. */ if (!strcmp(*argv, "-auth")) { showwhich = SHOWAUTH; continue; } /* * Show file systems. */ if (!strcmp(*argv, "-fs")) { showwhich = SHOWFILESYSTEM; continue; } /* * Show individual files. */ if (!strcmp(*argv, "-if")) { showwhich = SHOWINDVFILES; continue; } /* * Show NFS procedures */ if (!strcmp(*argv, "-procs")) { showwhich = SHOWNFSPROCS; continue; } /* * Show NFS3 procedures */ if (!strcmp(*argv, "-procs3")) { showwhich = SHOWNFS3PROCS; continue; } /* * Show NFS clients */ if (!strcmp(*argv, "-clients")) { showwhich = SHOWCLIENTS; continue; } /* * Turn on logging. */ if (!strcmp(*argv, "-l")) { logging++; continue; } /* * Run in background mode. */ if (!strcmp(*argv, "-bg")) { logging++; bgflag++; continue; } /* * Watch all traffic. */ if (!strcmp(*argv, "-all")) { allflag++; continue; } /* * Use all interfaces. */ if (!strcmp(*argv, "-allif")) { allintf++; continue; } /* * Sort file systems by usage, not name. */ if (!strcmp(*argv, "-usage")) { sortbyusage++; continue; } if (!strcmp(*argv, "-fhdebug")) { fhdebugf++; continue; } usage(); } /* * Check what we're showing. */ switch (showwhich) { case 0: /* default */ showwhich = SHOWFILESYSTEM; break; case SHOWINDVFILES: if (filelist == NULL) { (void) fprintf(stderr, "%s: must specify file list with -fi.\n", pname); finish(-1); } break; } /* * Trap signals so we can clean up. */ (void) signal(SIGINT, finish); (void) signal(SIGQUIT, finish); (void) signal(SIGTERM, finish); #ifdef sgi /* * Kludge to prevent coredumps when the optimizer's on? */ (void) signal(SIGFPE, SIG_IGN); #endif #ifdef ultrix (void) signal(SIGFPE, fpe_warn); #endif #ifdef USE_DLPI /* * Set up the data link interface provider right away, * since we probably need super-user permission. */ if (allintf) { ninterfaces = 0; for (i=0; devices[i] != NULL; i++) { if_fd[ninterfaces] = setup_dlpi_dev(&devices[i]); if (if_fd[ninterfaces] >= 0) { if_dlt[ninterfaces] = dlpi_devtype(if_fd[ninterfaces]); ninterfaces++; } } } else { if_fd[0] = setup_dlpi_dev(&device); if (if_fd[0] < 0) { error(device); finish(-1); } if_dlt[0] = dlpi_devtype(if_fd[0]); ninterfaces = 1; } #endif /* USE_DLPI */ #ifdef USE_NIT /* * Set up the network interface tap right away, * since we probably need super-user permission. */ if (allintf) { ninterfaces = 0; for (i=0; devices[i] != NULL; i++) { if_fd[ninterfaces] = setup_nit_dev(&devices[i]); if (if_fd[ninterfaces] >= 0) { if_dlt[ninterfaces] = nit_devtype(devices[i]); ninterfaces++; } } } else { if_fd[0] = setup_nit_dev(&device); if (if_fd[0] < 0) { error(device); finish(-1); } if_dlt[0] = nit_devtype(device); ninterfaces = 1; } #endif /* USE_NIT */ #ifdef USE_PFILT /* * Set up the packet filter interface now, * although we don't need super-user permission. */ if (allintf) { ninterfaces = 0; for (i=0; devices[i] != NULL; i++) { if_fd[ninterfaces] = setup_pfilt_dev(&devices[i]); if (if_fd[ninterfaces] >= 0) { if_dlt[ninterfaces] = pfilt_devtype(if_fd[ninterfaces]); ninterfaces++; } } } else { if_fd[0] = setup_pfilt_dev(&device); if (if_fd[0] < 0) { error(device); finish(-1); } if_dlt[0] = pfilt_devtype(if_fd[0]); ninterfaces = 1; } #endif /* USE_PFILT */ #ifdef USE_SNOOP /* * Set up the snoop interface right away, * since we probably need super-user permission. */ if (allintf) { ninterfaces = 0; for (i=0; devices[i] != NULL; i++) { if_fd[ninterfaces] = setup_snoop_dev(&devices[i]); if (if_fd[ninterfaces] >= 0) { if_dlt[ninterfaces] = snoop_devtype(devices[i]); ninterfaces++; } } } else { if_fd[0] = setup_snoop_dev(&device); if (if_fd[0] < 0) { error(device); finish(-1); } if_dlt[0] = snoop_devtype(device); ninterfaces = 1; } #endif /* USE_SNOOP */ #ifdef USE_LINUX /* * Set up the snoop interface right away, * since we probably need super-user permission. */ if (allintf) { setup_linux_dev(NULL, &ls); } else { int res = setup_linux_dev(&device, &ls); if (res < 0) { error(device); finish(-1); } } if (ls.pcap == NULL) { fprintf(stderr, "%s: no valid interfaces.\n", pname); finish(-1); } #endif /* USE_LINUX */ /* * Now lose super-user permission, since we * don't need it for anything else. */ #ifdef SVR4 (void) setuid(getuid()); (void) seteuid(getuid()); #else (void) setreuid(getuid(), getuid()); #endif /* * Look up the network addresses of the source and * destination hosts. */ get_net_addrs(); /* * Get the list of RPC ports to watch. */ get_rpc_ports(); /* * Tell the user what's going on. */ (void) printf("NFSWATCH Version %s\n", VERSION); if (serverflag) { (void) printf("Watch packets to/from %s on ", serverhost); } else { (void) printf("Watch packets from %s to %s on ", (srcflag ? srchost : "all hosts"), dsthost); } if (allintf) #ifdef USE_LINUX (void) printf("all interfaces as %s;\n", pcap_datalink_val_to_description(ls.linktype)); #else (void) printf("all interfaces;\n"); #endif else { #ifdef USE_LINUX (void) printf("%s ", pcap_datalink_val_to_description(ls.linktype)); #else (void) printf("%s ", dlt_name(if_dlt[0])); #endif (void) printf("interface %s;\n", device); } (void) printf("log to \"%s\" (logging %s);\n", logfile, (logging ? "on" : "off")); if (bgflag) { (void) printf("cycle time %d seconds;\n", cycletime); (void) printf("running as a daemon in the background..."); } else { (void) printf("snapshots to \"%s\";\n", snapshotfile); (void) printf("cycle time %d seconds...", cycletime); } (void) fflush(stdout); /* * No more informational output, so fork and exit if in * background mode. */ if (bgflag) { int pid; if ((pid = fork()) < 0) { error("fork"); finish(-1); } if (pid != 0) { printf("pid = %d\n", pid); exit(0); } } if (fhdebugf) { /* Don't fork a daemon, but also don't update the screen */ bgflag++; (void) printf("\n"); (void) fflush(stdin); } /* * Set up a pseudo RPC server. */ setup_rpcxdr(); /* * Set up the screen. */ if (!bgflag) setup_screen(device); /* * Set up the packet counters. This must be done after * setup_screen because they use the LINES variable. */ setup_pkt_counters(); setup_nfs_counters(); setup_proc_counters(); setup_clnt_counters(); if (filelist) setup_fil_counters(); if (mapfile) setup_map_file(); /* * Now label the screen. */ if (!bgflag) label_screen(); /* * Open log file if logging is on. */ if (logging) { if ((logfp = fopen(logfile, "a")) == NULL) { error(logfile); finish(-1); } (void) fprintf(logfp, "#\n# startlog\n#\n"); (void) fprintf(logfp, "# NFSwatch log file\n"); (void) fprintf(logfp, "# Packets from: %s\n", (srcflag ? srchost : "all hosts")); (void) fprintf(logfp, "# Packets to: %s\n#\n", dsthost); } /* * Go watch packets. Never returns. */ nfswatch(); return 0; } /* * nfswatch - main packet reading loop. */ static void nfswatch(void) { #ifndef USE_LINUX int i; #endif int cc; fd_set readfds; struct timeval tv; struct itimerval itv; #ifdef USE_DLPI char *buf; int tdrops[MAXINTERFACES]; struct strbuf strdata; struct sb_hdr *hdrp; int flags; #endif #ifdef USE_NIT int tdrops[MAXINTERFACES]; struct nit_iftime *tstamp; struct nit_bufhdr *hdrp; struct nit_ifdrops *ndp; #endif #ifdef USE_PFILT struct enstamp stamp; int datalen; #endif #ifdef USE_SNOOP int tdrops[MAXINTERFACES]; struct etherpacket ep; struct rawstats rs; #endif #ifdef USE_DLPI /* * Allocate a buffer so it's properly aligned for * casting to structure types. */ if ((buf = malloc(DLPI_CHUNKSIZE)) == NULL) { (void) fprintf(stderr, "%s: out of memory.\n", pname); finish(-1); } strdata.len = 0; strdata.buf = buf; strdata.maxlen = DLPI_CHUNKSIZE; #endif #ifdef USE_NIT /* * Allocate a buffer so it's properly aligned for * casting to structure types. */ if ((buf = malloc(NIT_CHUNKSIZE)) == NULL) { (void) fprintf(stderr, "%s: out of memory.\n", pname); finish(-1); } #endif #ifdef USE_PFILT /* * Allocate a buffer so it's properly aligned for * casting to structure types. */ if ((buf = malloc(PFILT_CHUNKSIZE)) == NULL) { (void) fprintf(stderr, "%s: out of memory.\n", pname); finish(-1); } #endif /* * Set up the alarm handler. */ (void) signal(SIGALRM, wakeup); /* * Set up the alarm clock. */ (void) bzero((char *) &itv, sizeof(struct itimerval)); itv.it_interval.tv_sec = cycletime; itv.it_interval.tv_usec = 0; itv.it_value = itv.it_interval; (void) setitimer(ITIMER_REAL, &itv, (struct itimerval *) 0); /* * Set the start time. */ (void) gettimeofday(&starttime, (struct timezone *) 0); #ifdef USE_DLPI /* * Flush the read queue of any packets that accumulated * during setup time. */ for (i=0; i < ninterfaces; i++) { flush_dlpi(if_fd[i]); tdrops[i] = 0; } for (;;) { FD_ZERO(&readfds); for (i=0; i < ninterfaces; i++) FD_SET(if_fd[i], &readfds); /* * See which nets have packets to read. */ cc = select(NFDBITS, &readfds, (fd_set *) 0, (fd_set *) 0, 0); if ((cc < 0) && (errno != EINTR)) { error("select"); finish(-1); } if (cc == 0) { continue; } /* * For each interface... */ for (i=0; i < ninterfaces; i++) { char *bufstop, *bp; /* * Nothing to read. */ if (!FD_ISSET(if_fd[i], &readfds)) continue; /* * Now read packets from the dlpi device. */ flags = 0; strdata.len = 0; if (getmsg(if_fd[i], NULL, &strdata, &flags) != 0) continue; bufstop = buf + strdata.len; bp = buf; #ifdef SUNOS5 /* * Loop through the chunk, extracting packets. */ while (bp < bufstop) { char *cp = bp; #ifdef _LP64 struct timeval tv; #endif /* * Get the nit header. */ hdrp = (struct sb_hdr *) cp; cp += sizeof(struct sb_hdr); int_pkt_drops += hdrp->sbh_drops - tdrops[i]; pkt_drops += hdrp->sbh_drops - tdrops[i]; tdrops[i] = hdrp->sbh_drops; /* * Filter the packet. */ #ifdef _LP64 tv.tv_sec = hdrp->sbh_timestamp.tv_sec; tv.tv_usec = hdrp->sbh_timestamp.tv_usec; if (if_dlt[i] == DLT_FDDI) { pkt_filter_fddi(cp, hdrp->sbh_msglen, &tv); } else { pkt_filter_ether(cp, hdrp->sbh_msglen, &tv); } #else if (if_dlt[i] == DLT_FDDI) { pkt_filter_fddi(cp, hdrp->sbh_msglen, &hdrp->sbh_timestamp); } else { pkt_filter_ether(cp, hdrp->sbh_msglen, &hdrp->sbh_timestamp); } #endif /* * Skip over this packet. */ bp += hdrp->sbh_totlen; } #else /* SUNOS5 */ /* * It's just a packet, no buffering. */ if (strdata.len) { /* * Since we're not on SunOS5, that means we * don't have DLIOCRAW, so we don't have the * packet frame header. So, we need to * bypass that level of filtering. */ pkt_dispatch(bp, 0, htons(DLPI_DEFAULTSAP), 0); } #endif /* SUNOS5 */ } #endif /* USE_DLPI */ #ifdef USE_NIT /* * Flush the read queue of any packets that accumulated * during setup time. */ for (i=0; i < ninterfaces; i++) { flush_nit(if_fd[i]); tdrops[i] = 0; } for (;;) { FD_ZERO(&readfds); for (i=0; i < ninterfaces; i++) FD_SET(if_fd[i], &readfds); /* * See which nets have packets to read. */ cc = select(NFDBITS, &readfds, (fd_set *) 0, (fd_set *) 0, 0); if ((cc < 0) && (errno != EINTR)) { error("select"); finish(-1); } if (cc == 0) { continue; } /* * For each interface... */ for (i=0; i < ninterfaces; i++) { /* * Nothing to read. */ if (!FD_ISSET(if_fd[i], &readfds)) continue; /* * Now read packets from the nit device. */ if ((cc = read(if_fd[i], buf, NIT_CHUNKSIZE)) <= 0) continue; bufstop = buf + cc; bp = buf; /* * Loop through the chunk, extracting packets. */ while (bp < bufstop) { cp = bp; /* * Get the nit header. */ hdrp = (struct nit_bufhdr *) cp; cp += sizeof(struct nit_bufhdr); /* * Get the time stamp. */ tstamp = (struct nit_iftime *) cp; cp += sizeof(struct nit_iftime); /* * Get the number of dropped packets. */ ndp = (struct nit_ifdrops *) cp; cp += sizeof(struct nit_ifdrops); int_pkt_drops += ndp->nh_drops - tdrops[i]; pkt_drops += ndp->nh_drops - tdrops[i]; tdrops[i] = ndp->nh_drops; /* * Filter the packet. */ #ifdef notdef /* * This is how it *should* be. But the NIT * device rips off the FDDI packet header * and the 802.2 LLC header, and replaces * them with an ethernet packet header. */ if (if_dlt[i] == DLT_FDDI) { pkt_filter_fddi(cp, hdrp->nhb_msglen, &tstamp->nh_timestamp); } else { pkt_filter_ether(cp, hdrp->nhb_msglen, &tstamp->nh_timestamp); } #else /* * So... we just do this instead for both * ethernet and FDDI. Strange but true. */ pkt_filter_ether(cp, hdrp->nhb_msglen, &tstamp->nh_timestamp); #endif /* * Skip over this packet. */ bp += hdrp->nhb_totlen; } } #endif /* USE_NIT */ #ifdef USE_PFILT /* * Flush the read queue of any packets that accumulated * during setup time. */ for (i=0; i < ninterfaces; i++) flush_pfilt(if_fd[i]); for (;;) { FD_ZERO(&readfds); for (i=0; i < ninterfaces; i++) FD_SET(if_fd[i], &readfds); /* * See which interfaces have any packets to read. */ cc = select(NFDBITS, &readfds, (fd_set *) 0, (fd_set *) 0, 0); if ((cc < 0) && (errno != EINTR)) { error("select"); finish(-1); } if (cc == 0) { continue; } /* * Now read packets from the packet filter device. */ for (i=0; i < ninterfaces; i++) { if (!FD_ISSET(if_fd[i], &readfds)) continue; if ((cc = read(if_fd[i], buf, PFILT_CHUNKSIZE)) < 0) { lseek(if_fd[i], 0L, 0); /* * Might have read MAXINT bytes. Try again. */ if ((cc = read(if_fd[i], buf, PFILT_CHUNKSIZE)) < 0) { error("pfilt read"); finish(-1); } } bp = buf; /* * Loop through buffer, extracting packets. */ while (cc > 0) { /* * Avoid alignment issues. */ (void) bcopy(bp, &stamp, sizeof(stamp)); /* * Treat entire buffer as garbage. */ if (stamp.ens_stamplen != sizeof(stamp)) break; /* * Get the number of dropped packets. */ int_pkt_drops += stamp.ens_dropped; pkt_drops += stamp.ens_dropped; /* * Filter the packet. */ datalen = stamp.ens_count; if (datalen > truncation) datalen = truncation; if (if_dlt[i] == DLT_FDDI) { /* Weird Ultrix padding */ pkt_filter_fddi(&(bp[sizeof(stamp) + 3]), datalen, &stamp.ens_tstamp); } else pkt_filter_ether(&(bp[sizeof(stamp)]), datalen, &stamp.ens_tstamp); /* * Skip over this packet. */ if (cc == (datalen + sizeof(stamp))) break; datalen = ENALIGN(datalen); datalen += sizeof(stamp); cc -= datalen; bp += datalen; } } #endif /* USE_PFILT */ #ifdef USE_SNOOP /* * Flush the read queue of any packets that accumulated * during setup time. */ for (i=0; i < ninterfaces; i++) { flush_snoop(if_fd[i]); tdrops[i] = 0; } /* * Now read packets from the snooper. */ for (;;) { int dropped; FD_ZERO(&readfds); for (i=0; i < ninterfaces; i++) FD_SET(if_fd[i], &readfds); /* * See which nets have packets to read. */ cc = select(NFDBITS, &readfds, (fd_set *) 0, (fd_set *) 0, 0); if ((cc < 0) && (errno != EINTR)) { error("select"); finish(-1); } if (cc == 0) { continue; } /* * For each interface... */ for (i=0; i < ninterfaces; i++) { /* * Nothing to read. */ if (!FD_ISSET(if_fd[i], &readfds)) continue; /* * Now read packets from the nit device. */ if ((cc = read(if_fd[i], &ep, sizeof(ep))) <= 0) continue; if (do_update) { /* * Get the number of dropped packets. */ if (ioctl(if_fd[i], SIOCRAWSTATS, &rs) == 0) { dropped = rs.rs_snoop.ss_ifdrops + rs.rs_snoop.ss_sbdrops; int_pkt_drops += dropped - tdrops[i]; pkt_drops += dropped - tdrops[i]; tdrops[i] = dropped; } } /* * Filter the packet. */ if (if_dlt[i] == DLT_FDDI) { /* * This probably won't work. */ pkt_filter_fddi(&ep.ether, ep.snoop.snoop_packetlen, &ep.snoop.snoop_timestamp); } else { pkt_filter_ether(&ep.ether, ep.snoop.snoop_packetlen, &ep.snoop.snoop_timestamp); } } #endif /* USE_SNOOP */ #ifdef USE_LINUX /* * Read packets from the snooper. */ for (;;) { FD_ZERO(&readfds); FD_SET(ls.s, &readfds); /* * See which nets have packets to read. */ cc = select(NFDBITS, &readfds, (fd_set *) 0, (fd_set *) 0, 0); if ((cc < 0) && (errno != EINTR)) { error("select"); finish(-1); } if (cc == 0) { continue; } if (linux_read_packet(&ls) == 1) { if (ls.linktype == DLT_LINUX_SLL) pkt_filter_sll((char *) ls.bp, ls.len, &ls.ts); else pkt_filter_ether((char *) ls.bp, ls.len, &ls.ts); } #endif /* USE_LINUX */ tv.tv_sec = 0; tv.tv_usec = 0; FD_ZERO(&readfds); FD_SET(0, &readfds); /* * See if a command has been typed. */ if (!bgflag) { cc = select(NFDBITS, &readfds, (fd_set *) 0, (fd_set *) 0, &tv); if ((cc > 0) && FD_ISSET(0, &readfds)) command(); } } } nfswatch-4.99.11/xdr.c0000644000551200011300000001541510443765011013641 0ustar chrisludwig/* * $Id: xdr.c,v 1.9 2006/06/14 10:50:49 c4chris Exp $ */ #include "os.h" /* * xdr.c - XDR routines for decoding NFS packets. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ #include #include #ifdef SVR4 #include #endif #ifdef USE_LINUX /* This yucky hack is needed because glibc's headers are wrong wrt the * correct size needed in RPC stuff on 64-bit machines. There even is * a comment in to that effect... */ #define u_long uint32_t #endif #include #include #include #include #include #include #ifdef USE_LINUX #undef u_long #endif #include #include #include #define NFSSERVER 1 #ifdef sun #include #include #endif #ifdef ultrix #include #include #include #endif #ifdef sgi #include #ifdef IRIX6 #include #include #else #include "sgi.map.h" #endif #endif #ifdef __osf__ #include #include #include #include #endif #ifdef LINUX #include "linux.map.h" #endif #include "nfswatch.h" #include "rpcdefs.h" bool_t xdr_creatargs(XDR *xdrs, struct nfscreatargs *argp) { #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ argp->ca_sa = &argp->ca_sa_buf; if (xdr_diropargs(xdrs, &argp->ca_da) && xdr_sattr(xdrs, &argp->ca_sa_buf)) return(TRUE); #else if (xdr_diropargs(xdrs, &argp->ca_da) && xdr_sattr(xdrs, &argp->ca_sa)) return(TRUE); #endif return(FALSE); } bool_t xdr_diropargs(XDR *xdrs, struct nfsdiropargs *argp) { #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ argp->da_fhandle = &argp->da_fhandle_buf; if (xdr_fhandle(xdrs, &argp->da_fhandle_buf) && xdr_string(xdrs, &argp->da_name, NFS_MAXNAMLEN)) { free(argp->da_name); return(TRUE); } #else if (xdr_fhandle(xdrs, &argp->da_fhandle) && xdr_string(xdrs, &argp->da_name, NFS_MAXNAMLEN)) { free(argp->da_name); return(TRUE); } #endif return(FALSE); } bool_t xdr_fhandle(XDR *xdrs, fhandle_t *argp) { if (xdr_opaque(xdrs, (caddr_t) argp, NFS_FHSIZE)) return(TRUE); return(FALSE); } bool_t xdr_linkargs(XDR *xdrs, struct nfslinkargs *argp) { #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ argp->la_from = &argp->la_from_buf; if (xdr_fhandle(xdrs, &argp->la_from_buf) && xdr_diropargs(xdrs, &argp->la_to)) return(TRUE); #else if (xdr_fhandle(xdrs, &argp->la_from) && xdr_diropargs(xdrs, &argp->la_to)) return(TRUE); #endif return(FALSE); } bool_t xdr_rddirargs(XDR *xdrs, struct nfsrddirargs *argp) { if (xdr_fhandle(xdrs, &argp->rda_fh) && xdr_u_int(xdrs, (u_int32 *)&argp->rda_offset) && xdr_u_int(xdrs, (u_int32 *)&argp->rda_count)) return(TRUE); return(FALSE); } bool_t xdr_readargs(XDR *xdrs, struct nfsreadargs *argp) { if (xdr_fhandle(xdrs, &argp->ra_fhandle) && xdr_int(xdrs, (int32 *) &argp->ra_offset) && xdr_int(xdrs, (int32 *) &argp->ra_count) && xdr_int(xdrs, (int32 *) &argp->ra_totcount)) return(TRUE); return(FALSE); } bool_t xdr_rnmargs(XDR *xdrs, struct nfsrnmargs *argp) { if (xdr_diropargs(xdrs, &argp->rna_from) && xdr_diropargs(xdrs, &argp->rna_to)) return(TRUE); return(FALSE); } bool_t xdr_saargs(XDR *xdrs, struct nfssaargs *argp) { if (xdr_fhandle(xdrs, &argp->saa_fh) && xdr_sattr(xdrs, &argp->saa_sa)) return(TRUE); return(FALSE); } bool_t xdr_sattr(XDR *xdrs, struct nfssattr *argp) { if (xdr_u_int(xdrs, (u_int32 *)&argp->sa_mode) && xdr_u_int(xdrs, (u_int32 *)&argp->sa_uid) && xdr_u_int(xdrs, (u_int32 *)&argp->sa_gid) && xdr_u_int(xdrs, (u_int32 *)&argp->sa_size) && xdr_nfs2_timeval(xdrs, &argp->sa_atime) && xdr_nfs2_timeval(xdrs, &argp->sa_mtime)) return(TRUE); return(FALSE); } bool_t xdr_slargs(XDR *xdrs, struct nfsslargs *argp) { #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ argp->sla_sa = &argp->sla_sa_buf; if (xdr_diropargs(xdrs, &argp->sla_from) && xdr_string(xdrs, &argp->sla_tnm, (u_int) MAXPATHLEN) && xdr_sattr(xdrs, &argp->sla_sa_buf)) { free(argp->sla_tnm); return(TRUE); } #else if (xdr_diropargs(xdrs, &argp->sla_from) && xdr_string(xdrs, &argp->sla_tnm, (u_int) MAXPATHLEN) && xdr_sattr(xdrs, &argp->sla_sa)) { free(argp->sla_tnm); return(TRUE); } #endif return(FALSE); } bool_t xdr_nfs2_timeval(XDR *xdrs, struct nfs2_timeval *argp) { if (xdr_int(xdrs, (int32 *)&argp->tv_sec) && xdr_int(xdrs, (int32 *)&argp->tv_usec)) return(TRUE); return(FALSE); } bool_t xdr_writeargs(XDR *xdrs, struct nfswriteargs *argp) { #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ argp->wa_args = &argp->wa_args_buf; if (xdr_fhandle(xdrs, &argp->wa_fhandle) && xdr_int(xdrs, (int32 *) &argp->wa_begoff) && xdr_int(xdrs, (int32 *) &argp->wa_offset) && xdr_int(xdrs, (int32 *) &argp->wa_totcount)) return(TRUE); #else if (xdr_fhandle(xdrs, &argp->wa_fhandle) && xdr_int(xdrs, (int32 *) &argp->wa_begoff) && xdr_int(xdrs, (int32 *) &argp->wa_offset) && xdr_int(xdrs, (int32 *) &argp->wa_totcount)) return(TRUE); #endif return(FALSE); } bool_t xdr_nfs_fh3(XDR *xdrs, nfs_fh3 *argp) { if (!xdr_u_int(xdrs, &argp->fh3_length)) return(FALSE); if (argp->fh3_length == NFS_FHSIZE) { if (xdr_opaque(xdrs, (caddr_t) &argp->fh3_u.nfs_fh3_i.fh3_i, NFS_FHSIZE)) return(TRUE); } else { if (xdr_opaque(xdrs, (caddr_t) argp->fh3_u.data, NFS3_FHSIZE)) return(TRUE); } return(FALSE); } /* We have at most two diropargs3 as parameters... */ static char fn3_buf[2][1024]; static int fn3_toggle; bool_t xdr_diropargs3(XDR *xdrs, diropargs3 *argp) { fn3_toggle = (fn3_toggle + 1) & 1; argp->name = fn3_buf[fn3_toggle]; #if (defined(SUNOS5) && !defined(SUNOS58)) || defined(IRIX6) if (xdr_nfs_fh3(xdrs, &argp->dir) && xdr_string(xdrs, &argp->name, 1024)) return(TRUE); #else argp->flags = 0; argp->dirp = &argp->dir; if (xdr_nfs_fh3(xdrs, argp->dirp) && xdr_string(xdrs, &argp->name, 1024)) return(TRUE); #endif return(FALSE); } bool_t xdr_RENAME3args(XDR *xdrs, RENAME3args *argp) { if (xdr_diropargs3(xdrs, &argp->from) && xdr_diropargs3(xdrs, &argp->to)) return(TRUE); return(FALSE); } bool_t xdr_LINK3args(XDR *xdrs, LINK3args *argp) { if (xdr_nfs_fh3(xdrs, &argp->file) && xdr_diropargs3(xdrs, &argp->link)) return(TRUE); return(FALSE); } nfswatch-4.99.11/pktfilter.c0000644000551200011300000002720111173256260015046 0ustar chrisludwig/* * $Id: pktfilter.c,v 1.12 2009/04/21 05:42:08 c4chris Exp $ */ #include "os.h" /* * pktfilter.c - filters to count the packets. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ #include #include #include #if !defined(ultrix) && !defined(__osf__) #include #endif #include #include #include #include #include #include #ifndef LINUX #include #include #endif #include #include #include #include #include "nfswatch.h" #include "externs.h" #include "screen.h" #ifdef SUNOS4 #define NND 1 #include #endif #ifdef ultrix #include "ultrix.map.h" #include "ipports.h" #endif #ifdef __osf__ /* or perhaps "#if defined(__osf__) && defined(__alpha)"? */ #include "osf.map.h" #include "ipports.h" #endif #ifdef sgi #include #include "sgi.map.h" #include "ipports.h" #endif #ifdef LINUX #define uh_sport source #define uh_dport dest #define uh_ulen len #define uh_sum check #define th_sport source #define th_dport dest #define th_off doff #endif /* * Ethernet broadcast address. */ static struct ether_addr ether_broadcast = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; #ifndef SUNOS5 static void pkt_dispatch(char *, int, u_short, struct timeval *); #endif static void ip_filter(struct ip *, ipaddrt, ipaddrt, struct timeval *); static void tcp_filter(struct tcphdr *, u_int, ipaddrt, ipaddrt, struct timeval *); static void udp_filter(struct udphdr *, ipaddrt, ipaddrt, struct timeval *); static void icmp_filter(void); /* * pkt_filter_ether - Parse Ethernet header, * pass rest of packet to pkt_dispatch() */ void pkt_filter_ether(char *cp, u_int length, struct timeval *tstamp) { char packet[PACKETSIZE]; register int bdcst; struct ether_header eheader; /* * Extract the ethernet header. */ memcpy(&eheader, cp, sizeof(struct ether_header)); memcpy(packet, cp + sizeof(struct ether_header), length - sizeof(struct ether_header)); /* * See if it's a broadcast packet. */ #if defined(ultrix) || defined(sgi) || defined(__osf__) bdcst = !bcmp((char *) eheader.ether_dhost, (char *) ðer_broadcast, sizeof(struct ether_addr)); #else bdcst = !bcmp((char *) &eheader.ether_dhost, (char *) ðer_broadcast, sizeof(struct ether_addr)); #endif /* * Figure out what kind of packet it is, and pass * it off to the appropriate filter. */ pkt_dispatch(packet, bdcst, eheader.ether_type, tstamp); } #ifndef LLC_SNAP_LSAP #define LLC_UI 0x3 #define LLC_SNAP_LSAP 0xaa #endif /* * pkt_filter_fddi - Parse FDDI and LLC headers, * pass rest of packet to pkt_dispatch() */ void pkt_filter_fddi(char *cp, u_int length, struct timeval *tstamp) { char packet[PACKETSIZE]; register int bdcst; struct fddi_header { u_char fddi_fc; u_char fddi_dhost[6]; u_char fddi_shost[6]; } fheader; struct llc_header { u_char llc_dsap; u_char llc_ssap; u_char llc_control; u_char llc_org_code[3]; u_short llc_ether_type; } lheader; u_short etype; #define FDDI_LLC_LEN (sizeof(struct fddi_header) + sizeof(struct llc_header)) if (length <= FDDI_LLC_LEN) return; /* runt */ /* * Extract the FDDI and LLC headers. */ (void) bcopy(cp, (char *) &fheader, sizeof(struct fddi_header)); (void) bcopy(cp + sizeof(struct fddi_header), (char *) &lheader, sizeof(struct llc_header)); (void) bcopy(cp + FDDI_LLC_LEN, (char *) packet, (int) (length - FDDI_LLC_LEN)); /* Should check FDDI frame control ... */ /* * See if it's a broadcast packet. */ bdcst = !bcmp((char *) fheader.fddi_dhost, (char *) ðer_broadcast, sizeof(struct ether_addr)); /* * Check LLC encapsulation type, extract Ethernet type if SNAP */ if ((lheader.llc_dsap == LLC_SNAP_LSAP) && (lheader.llc_ssap == LLC_SNAP_LSAP) && (lheader.llc_control == LLC_UI) && (lheader.llc_org_code[0] == 0) && (lheader.llc_org_code[1] == 0) && (lheader.llc_org_code[2] == 0)) { etype = lheader.llc_ether_type; } else etype = 0; /* * Figure out what kind of packet it is, and pass * it off to the appropriate filter. */ pkt_dispatch(packet, bdcst, etype, tstamp); } #ifdef USE_LINUX /* * A DLT_LINUX_SLL fake link-layer header. */ #define SLL_HDR_LEN 16 /* total header length */ #define SLL_ADDRLEN 8 /* length of address field */ #define LINUX_SLL_HOST 0 #define LINUX_SLL_BROADCAST 1 #define LINUX_SLL_MULTICAST 2 #define LINUX_SLL_OTHERHOST 3 #define LINUX_SLL_OUTGOING 4 struct sll_header { u_int16_t sll_pkttype; /* packet type */ u_int16_t sll_hatype; /* link-layer address type */ u_int16_t sll_halen; /* link-layer address length */ u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ u_int16_t sll_protocol; /* protocol */ }; /* * pkt_filter_sll - Parse LINUX_SLL header, * pass rest of packet to pkt_dispatch() */ void pkt_filter_sll(char *cp, u_int length, struct timeval *tstamp) { char packet[PACKETSIZE]; register int bdcst; struct sll_header sheader; /* * Extract the SLL header. */ memcpy(&sheader, cp, sizeof(struct sll_header)); memcpy(packet, cp + sizeof(struct sll_header), length - sizeof(struct sll_header)); /* * See if it's a broadcast packet. */ bdcst = ntohs(sheader.sll_pkttype) == LINUX_SLL_BROADCAST; /* * Figure out what kind of packet it is, and pass * it off to the appropriate filter. */ pkt_dispatch(packet, bdcst, sheader.sll_protocol, tstamp); } #endif /* USE_LINUX */ /* * pkt_dispatch - count a packet, and pass it off to the appropriate filter. * Caller tells us the Ethernet type code and if the packet * was a broadcast. */ #ifdef SUNOS5 void #else static void #endif /* packet: address of IP or ARP header */ /* bdcst: was packet a LAN broadcast? */ /* etype: still in network byte-order */ pkt_dispatch(char *packet, int bdcst, u_short etype, struct timeval *tstamp) { struct ip *ip; struct ether_arp *arp; int sender, target; register int want; /* * Count this packet in the network totals. */ int_pkt_total++; pkt_total++; /* * See if it's a broadcast packet, and count it if it is. */ if (bdcst) { pkt_counters[PKT_BROADCAST].pc_interval++; pkt_counters[PKT_BROADCAST].pc_total++; } /* * Figure out what kind of packet it is, and pass * it off to the appropriate filter. */ switch (ntohs(etype)) { case ETHERTYPE_IP: /* IP packet */ ip = (struct ip *) packet; want = want_packet(ip->ip_src.s_addr, ip->ip_dst.s_addr); /* * If we want this packet, count it in the host * totals and pass it off. */ if (bdcst || want) { int_dst_pkt_total++; dst_pkt_total++; ip_filter(ip, ip->ip_src.s_addr, ip->ip_dst.s_addr, tstamp); } break; case ETHERTYPE_ARP: /* Address Resolution Protocol */ arp = (struct ether_arp *) packet; sender = (arp->arp_spa[0] << 24) + (arp->arp_spa[1] << 16) + (arp->arp_spa[2] << 8) + arp->arp_spa[3]; target = (arp->arp_tpa[0] << 24) + (arp->arp_tpa[1] << 16) + (arp->arp_tpa[2] << 8) + arp->arp_tpa[3]; want = want_packet(sender, target); /* * If we want this packet, count it in the host * totals and then count it in the packet * type counters. */ if (bdcst || want) { int_dst_pkt_total++; dst_pkt_total++; pkt_counters[PKT_ARP].pc_interval++; pkt_counters[PKT_ARP].pc_total++; } break; case ETHERTYPE_REVARP: /* Reverse Addr Resol Protocol */ arp = (struct ether_arp *) packet; sender = (arp->arp_spa[0] << 24) + (arp->arp_spa[1] << 16) + (arp->arp_spa[2] << 8) + arp->arp_spa[3]; target = (arp->arp_tpa[0] << 24) + (arp->arp_tpa[1] << 16) + (arp->arp_tpa[2] << 8) + arp->arp_tpa[3]; want = want_packet(sender, target); /* * If we want this packet, count it in the host * totals and then count it in the packet * type counters. */ if (bdcst || want) { int_dst_pkt_total++; dst_pkt_total++; pkt_counters[PKT_RARP].pc_interval++; pkt_counters[PKT_RARP].pc_total++; } break; #ifdef notdef case ETHERTYPE_PUP: /* Xerox PUP */ #endif default: /* who knows... */ int_dst_pkt_total++; dst_pkt_total++; pkt_counters[PKT_OTHER].pc_interval++; pkt_counters[PKT_OTHER].pc_total++; break; } } /* * ip_filter - strip off the IP header and pass off to the appropriate * filter. */ static void ip_filter(struct ip *ip, ipaddrt src, ipaddrt dst, struct timeval *tstamp) { register int *data; register int datalength; data = (int *) ip; data += ip->ip_hl; datalength = ntohs(ip->ip_len) - (4 * ip->ip_hl); /* * Figure out what kind of IP packet this is, and * pass it off to the appropriate filter. */ switch (ip->ip_p) { case IPPROTO_TCP: /* transmission control protocol*/ tcp_filter((struct tcphdr *) data, datalength, src, dst, tstamp); break; case IPPROTO_UDP: /* user datagram protocol */ udp_filter((struct udphdr *) data, src, dst, tstamp); break; case IPPROTO_ICMP: /* control message protocol */ icmp_filter(); break; #ifdef notdef case IPPROTO_IGMP: /* group message protocol */ case IPPROTO_GGP: /* gateway-gateway protocol */ case IPPROTO_EGP: /* exterior gateway protocol */ case IPPROTO_PUP: /* Xerox pup protocol */ case IPPROTO_IDP: /* XNS IDP */ #endif default: /* who knows... */ break; } } /* We should get this from the services database... */ #define NFS_PORT 2049 /* * tcp_filter - count TCP packets, pass RPC packets to the RPC filter. */ static void tcp_filter(struct tcphdr *tcp, u_int length, ipaddrt src, ipaddrt dst, struct timeval *tstamp) { unsigned short source = ntohs(tcp->th_sport); unsigned short dest = ntohs(tcp->th_dport); unsigned int hdr_len = tcp->th_off * 4; /* * Count as a TCP packet. */ pkt_counters[PKT_TCP].pc_interval++; pkt_counters[PKT_TCP].pc_total++; hdr_len += 4; /* For some reason... */ if (length < hdr_len) return; if (source == NFS_PORT || dest == NFS_PORT) { rpc_filter((char *) tcp + hdr_len, length - hdr_len, src, dst, tstamp); return; } if (rpcPortCnt > 0) { unsigned int i; for (i = 0; i < rpcPortCnt; i++) { if (dest == rpcPort[i]) { rpc_filter((char *) tcp + hdr_len, length - hdr_len, src, dst, tstamp); return; } } } } /* * udp_filter - count UDP packets, pass RPC packets to the RPC filter. */ static void udp_filter(struct udphdr *udp, ipaddrt src, ipaddrt dst, struct timeval *tstamp) { unsigned short source = ntohs(udp->uh_sport); unsigned short dest = ntohs(udp->uh_dport); /* * Count as a UDP packet. */ pkt_counters[PKT_UDP].pc_interval++; pkt_counters[PKT_UDP].pc_total++; if (source == IPPORT_ROUTESERVER || dest == IPPORT_ROUTESERVER) { pkt_counters[PKT_ROUTING].pc_interval++; pkt_counters[PKT_ROUTING].pc_total++; return; } if (source == NFS_PORT || dest == NFS_PORT) { rpc_filter((char *) udp + sizeof(struct udphdr), ntohs(udp->uh_ulen) - sizeof(struct udphdr), src, dst, tstamp); return; } if (rpcPortCnt > 0) { unsigned int i; for (i = 0; i < rpcPortCnt; i++) { if (dest == rpcPort[i]) { rpc_filter((char *) udp + sizeof(struct udphdr), ntohs(udp->uh_ulen) - sizeof(struct udphdr), src, dst, tstamp); return; } } } } /* * icmp_filter - count ICMP packets. */ static void icmp_filter(void) { pkt_counters[PKT_ICMP].pc_interval++; pkt_counters[PKT_ICMP].pc_total++; } nfswatch-4.99.11/README0000644000551200011300000003060611364242300013551 0ustar chrisludwig 23 Apr 2010 This is NFSWATCH Version 4.99.11. Changes from Version 4.99.10 are: - README file converted to utf8 - Fix compile issues on Solaris and Linux alpha machines - Add a ChangeLog file - Add TODO note about broken strict aliasing rule ------------------------------------------------------------------------------- 15 Apr 2009 This is NFSWATCH Version 4.99.10. Changes from Version 4.99.9 are: - use libpcap for packet capturing, thus allowing to monitor NFS traffic also on InfiniBand and other interconnects. - Add some TODO items... ------------------------------------------------------------------------------- 25 May 2007 This is NFSWATCH Version 4.99.9. Changes from Version 4.99.8 are: - Improve filehandle decoding on Linux. - Exclude known non-exports instead of guessing exports. - Do not handle the second argument of RENAME3 and LINK3, as it doesn't seem to work anyway. ------------------------------------------------------------------------------- 13 March 2007 This is NFSWATCH Version 4.99.8. Changes from Version 4.99.7 are: - Handle more Linux filehandle's fsid_type - Improve parsing of device name and instance number in dlpi ------------------------------------------------------------------------------- 30 January 2007 This is NFSWATCH Version 4.99.7. Changes from Version 4.99.6 are: - Make per-procedure statistics work for NFSv3 - Makefile cleanups ------------------------------------------------------------------------------- 14 June 2006 This is NFSWATCH Version 4.99.6. Changes from Version 4.99.5 are: - Fix buffer overflow problems - Compiler warnings cleanup - Allow compiling on IRIX (using GCC) ------------------------------------------------------------------------------- 22 November 2005 This is NFSWATCH Version 4.99.5. Changes from Version 4.99.4 are: - Analyze NFS on TCP - Improve total packet count display - Allow compiling for 64-bit Solaris - Allow compiling for older Solaris releases (5.6 and 5.7) - Compiler warnings cleanup ------------------------------------------------------------------------------- 13 July 2005 This is NFSWATCH Version 4.99.4. Changes from Version 4.99.3 are: - Fix NFS packet counting bug - Improve Linux filehandle parsing ------------------------------------------------------------------------------- 2 June 2005 This is NFSWATCH Version 4.99.3. Changes from Version 4.99.2 are: - Add xfs to the list of recognized filesystems ------------------------------------------------------------------------------- 22 April 2005 This is NFSWATCH Version 4.99.2. Changes from Version 4.99.1 are: - Cleanup spec file for Fedora Extras ------------------------------------------------------------------------------- 25 February 2005 This is NFSWATCH Version 4.99.1. Changes from Version 4.3 are: - Deal with NFSv3 and Linux filehandles ------------------------------------------------------------------------------- 12 February 1996 This is NFSWATCH Version 4.3. The only changes from Version 4.2 are: - Should now compile properly on Solaris 2.5 (SunOS 5.5). Thanks to Alexandre Oliva for the patch. As with Solaris 2.4, expect several warnings on xdr.c. - Added a patch to let is_exported() on SVR4 deal with symbolic links in /etc/dfs/dfstab. Thanks to Ronald Hello for the patch. - Added a patch to allow NFSWATCH to find out about more local file system types (XFS on IRIX, PCFS and HSFS on SunOS). Thanks to Andreas Stolcke for the patch. - Added a patch to allow NFSwatch to understand Network Appliance FAServer file handles. Thanks to Guy Harris for the patch. ------------------------------------------------------------------------------- 31 March 1995 This is NFSWATCH Version 4.2. The only changes from Version 4.1 are: - Should now compile properly on Solaris 2.4 (SunOS 5.4), although you should expect several warnings on xdr.c due to some annoying discrepancies between type definitions. - Added a workaround to a bug in Solaris 2.3 that causes screwed up packets when the snapshot length is small. - Added a patch to fix identification of file system devices in Solaris 2.x. - Added the "qeN" devices for Sun's SQE board (Quad Ethernet). ------------------------------------------------------------------------------- 1 December 1993 This is NFSWATCH Version 4.1. It lets you monitor NFS requests to any given machine, or the entire local network. It mostly monitors NFS client traffic (NFS requests); it also monitors the NFS reply traffic from a server in order to measure the response time for each RPC. This is primarily a release to fix bugs that were present in the previous release. The following changes and bug fixes have been made since NFSWATCH 4.0: - Compiles and runs under Solaris 2.2 and Solaris 2.3. - Compiles and runs under DEC OSF/1 V1.3 and later. - The NFS procedure display code has been fixed. - Now understands Auspex file handles (thanks to Guy Harris). - Now understands IRIX file handles (thanks to Jim Patterson). - Now saves "-procs" output in the log file (thanks to Gary Schaps). - The screendump feature now works properly on Solaris 2.x systems (thanks to Gerry Singleton). - The mechanism by which NFS file handles are parsed has been split out into a separate module and completely redesigned. It is now independent of the platform on which nfswatch is running, and uses a variety of heuristics to figure out what the file handle represents. Doubtless these heuristics will fail in some cases; we have not been able to test the code against all possible NFS servers. If you find that nfswatch is not properly decoding a file handle from one of your servers (say, foo.bar.com), you can help us out by doing % nfswatch -dst foo.bar.com -fhdebug and capturing a page or two of the output. Then mail it to us, and also tell us exactly what software is running on the server (e.g., "DEC OSF/1 V1.3"). We cannot promise to fix the problem, of course. The following features and bug fixes appeared in NFSWATCH 4.0: - NFSWATCH now runs on Sun SPARC machines under SunOS 5.x (Solaris 2.x) using the Data Link Provider Interface (DLPI), dlpi(7). - NFSWATCH now runs on Silicon Graphics machines under IRIX 4.0 using the snoop(7) interface. It should also work on versions 3.2 and 3.3 (you'll need "-lbsd" on 3.2). Thanks to Tim Hudson of Mincom Pty for the patches. - NFSWATCH "almost" works on System V Release 4 systems. There are some problems with the fact that Solaris 2.x uses DLPI 2.0 (good), but most SVR4s out there still use DLPI 1.3 (bad). I've had a few beta testers working on it, but they have not yet gotten it to work. If you manage to get it working, *please* send patches. - NFSWATCH now keeps track of timing information in the procedure display, showing how quickly NFS calls receive replies. Thanks to Peter Phillips of the University of British Columbia for the code. - NFSWATCH now has an authenticator display, which shows the username or user id of the originator of each packet. Thanks again to Peter Phillips for the code. - A first pass at support for FDDI interfaces has been added. The support is better on some systems than others, as described below: IRIX40: Has not been tested, and almost definitely will not work "as is". The packet header that's read into from snoop probably needs to be different. Send us patches if you get it to work. SUNOS4: Has been tested on a Sun-4/380 under SunOS 4.1.2. Works with the SunNet FDDI/DX boards. SUNOS5: Has not been tested, but "should" work. Send us patches if it doesn't. SVR4: Has not been tested, but "should" work. Send us patches if it doesn't. (And if you get the rest of it working; see above.) ULTRIX: Works with Ultrix V4.2 or later *only*. All flavors of Ultrix 4.2 (including 4.2A, 4.2B, 4.2C) require kernel patches before you can use the FDDI code. Obtain the patched versions of net_common.o and pfilt.o from your Customer Support Center. - A new option, "-server hostname" has been added to watch all the traffic between a server and its clients; this is equivalent to "src == hostname || dst == hostname", which is not specifiable using the other options. Thanks again to Peter Phillips for the patches. - A new option, "-map", is available to help translate file system device names to "english" names, e.g. "/usr" instead of "fs1(7,23)". Thanks yet again to Peter Phillips. - Two new options have been added to allow NFSWATCH to be run from cron, via rsh, etc. The "-bg" option tells NFSWATCH to run in the background, with no screen display. All information will be put into the logfile only. The "-T maxtime" option tells NFSWATCH to terminate execution after maxtime seconds. - A new interactive command has been added. The "n" command toggles the display of client names or client host numbers in client mode, so that foreign hosts can be identified. - The maximum number of client hosts for a single server has been increased to 512. The maximum number of internet addresses for a single host has been increased to 16. The maximum number of interfaces that can be watched at one time has been increased to 16. - The bug in which file matching did not work on Sun-3 systems has been fixed. - The bug in which the standard input got closed upon exit, making the curses routines screw up, has been fixed. - The bug causing miscompilation of nit.c on SunOS 4.0 has been fixed. - Note that due to limitations in the SVR4 DLPI, the ethernet broad- cast, arp, and rarp packet counters will not be supported. Also note that on SVR4s still using DLPI 1.3, which does not support promiscuous mode, the "-all" and "-dst" options to NFSWATCH will not work. NFSWATCH has been successfully compiled and at least minimally tested on the following architectures and operating systems: Architecture Operating System ------------ ---------------- Sun-3 (68000) SunOS 4.1.1 Sun-4 (SPARC) SunOS 4.1.1, 4.1.2, 4.1.3 Sun-4 (SPARC) SunOS 5.1, 5.2, 5.3 DEC VAX Ultrix 4.0, 4.1, 4.2 DEC RISC Ultrix 4.0, 4.1, 4.2 DEC Alpha AXP DEC OSF/1 V1.3 and later SGI Personal IRIS IRIX 4.0.1 SGI 4D/440 IRIX 4.0.5 To compile NFSWATCH, just say "make." The Makefile will use the "uname" command to determine what operating system should be compiled for. If for some reason this blows up in your face, say "make OS=foo" where "foo" is one of the following: Macro Value Operating System ----------- ---------------- IRIX40 Silicon Graphics IRIX 4.0 SUNOS4 Sun Microsystems SunOS 4.x SUNOS5 Sun Microsystems SunOS 5.x (Solaris 2.x) SVR4 AT&T System V Release 4 ULTRIX Digital Equipment Ultrix 4.x DECOSF Digital Equipment Corp. OSF/1 V1.3 & later On Sun systems, NFSWATCH needs to either be run as root, or made setuid root (this is safe; it setuids itself back after opening the needed device). On Ultrix systems, it does not need to be setuid root or run as root, but the super-user has to enable promiscuous mode operation using pfconfig(8). On SGI systems, it needs to be either run as root or made setuid to root. On SVR4 systems, it needs to be either run as root or made setuid to root. On pre-4.2 Ultrix systems, the enclosed "pfcopyall" program can be used to change the value of the "pfcopyall" variable in the kernel so that you can see packets sent by the host you are running on. Otherwise, these packets will not be included in the output of NFSWATCH. You can redistribute this program as much as you want. All we ask is that you give credit where credit is due. If you make modifications or bug fixes, please send them back to us, in "diff -c" format, so they can be incorporated into the next release. Original authors (email addresses out of date AFAIK): Dave Curry Jeff Mogul IBM Internet Security Services Digital Equipment Corp. Integrated Systems Solutions Corporation Western Research Laboratory Long Meadow Road, Mail Stop 223 250 University Avenue Sterling Forest, NY 10979 Palo Alto, CA 94301 davy@vnet.ibm.com mogul@wrl.dec.com Current Maintainer: Christian Iseli Ludwig Institute for Cancer Research and Swiss Institute of Bioinformatics Bâtiment Génopode, Université de Lausanne CH-1015 Lausanne, Switzerland c4chris@users.sourceforge.net nfswatch-4.99.11/nfslogsum.c0000644000551200011300000003361710267175676015105 0ustar chrisludwig/* * $Id: nfslogsum.c,v 1.4 2005/07/19 13:10:22 c4chris Exp $ */ #include "os.h" /* * nfslogsum - summarize nfswatch log file * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ #include #include #include #include #include "nfswatch.h" char *pname; /* program name */ char *logfile = LOGFILE; /* log file name */ int logentries; /* # of entries */ int verbose = 0; /* print more info */ int maxlogentries = -1; /* stop at this many */ Counter total_pkts; /* total pkts this time */ Counter tohost_pkts; /* total pkts to host */ Counter dropped_pkts; /* total dropped pkts */ char *startdate; /* time started */ char *enddate; /* time finished */ char srchost[MAXHOSTNAMELEN]; /* source host name */ char dsthost[MAXHOSTNAMELEN]; /* destination host name*/ NFSCounter nfs_counters[MAXEXPORT]; /* NFS pkt counters */ FileCounter fil_counters[MAXEXPORT]; /* file pkt counters */ PacketCounter pkt_counters[PKT_NCOUNTERS]; /* type pkt counters */ char *nfs_procs[] = { "NULLPROC", " GETATTR", " SETATTR", " GETROOT", " LOOKUP", "READLINK", " READ", " WCACHE", " WRITE", " CREATE", " REMOVE", " RENAME", " LINK", " SYMLINK", " MKDIR", " RMDIR", " READDIR", " STATFS", 0 }; char *index(); void dumpit(); void dumpit2(); void parsenfs(); void parsetop(); void parsefile(); void parsepkts(); void parseproc(); void clearvars(); void parsetotals(); static int findnfs(char *); static int findfile(char *); int main(int argc, char **argv) { FILE *logfp; int printed = 0; char line[BUFSIZ]; pname = *argv; /* * Process arguments. */ while (--argc) { if (**++argv != '-') { logfile = *argv; continue; } switch (*++*argv) { case 'v': verbose++; break; default: maxlogentries = atoi(*argv); break; } } /* * Open the log file. */ if ((logfp = fopen(logfile, "r")) == NULL) { (void) fprintf(stderr, "%s: cannot open \"%s\"\n", pname, logfile); (void) exit(1); } /* * Read lines... */ while (fgets(line, sizeof(line), logfp) != NULL) { /* * Skip blank comments. */ if (!strcmp(line, "#\n")) continue; /* * Start of a new log session. */ if (!strcmp(line, "# startlog\n")) { clearvars(); printed = 0; continue; } /* * Start of a new log entry. */ if (!strcmp(line, "# begin\n")) { parsetop(logfp); continue; } /* * End of a log entry. */ if (!strcmp(line, "# end\n")) { logentries++; /* * If we've read the max, we're done. */ if ((maxlogentries > 0) && (logentries >= maxlogentries)) { dumpit(); exit(0); } continue; } /* * End of log session. */ if (!strcmp(line, "# endlog\n")) { printed++; dumpit(); continue; } /* * Start of NFS counter section. */ if (!strncmp(line, "# nfs counters ", 15)) { parsenfs(logfp); continue; } /* * Start of file counter section. */ if (!strncmp(line, "# file counters ", 16)) { parsefile(logfp); continue; } /* * Start of total packet section. */ if (!strncmp(line, "# total packets ", 16)) { parsetotals(logfp); continue; } /* * Start of packet counter section. */ if (!strncmp(line, "# packet counters ", 18)) { parsepkts(logfp); continue; } /* * Source host. */ if (!strncmp(line, "# Packets from: ", 19)) { (void) strcpy(srchost, line + 19); continue; } /* * Destination host. */ if (!strncmp(line, "# Packets to: ", 19)) { (void) strcpy(dsthost, line + 19); continue; } } /* * In case there's no endlog (logfile in progress). */ if (!printed) dumpit(); (void) fclose(logfp); (void) exit(0); } /* * clearvars - clear variables between log sessions. */ void clearvars() { register int i; logentries = 0; total_pkts = 0; tohost_pkts = 0; dropped_pkts = 0; if (startdate != NULL) { (void) free(startdate); startdate = NULL; } if (enddate != NULL) { (void) free(enddate); enddate = NULL; } (void) bzero((char *) pkt_counters, PKT_NCOUNTERS * sizeof(PacketCounter)); /* * Set up the strings. */ pkt_counters[PKT_NFS3READ].pc_name = "NFS3 Read"; pkt_counters[PKT_NFS3WRITE].pc_name = "NFS3 Write"; pkt_counters[PKT_NFSREAD].pc_name = "NFS Read"; pkt_counters[PKT_NFSWRITE].pc_name = "NFS Write"; pkt_counters[PKT_NFSMOUNT].pc_name = "NFS Mount"; pkt_counters[PKT_PORTMAP].pc_name = "Port Mapper"; pkt_counters[PKT_RPCAUTH].pc_name = "RPC Authorization"; pkt_counters[PKT_OTHERRPC].pc_name = "Other RPC Packets"; pkt_counters[PKT_TCP].pc_name = "TCP Packets"; pkt_counters[PKT_UDP].pc_name = "UDP Packets"; pkt_counters[PKT_ICMP].pc_name = "ICMP Packets"; pkt_counters[PKT_ROUTING].pc_name = "Routing Control"; pkt_counters[PKT_ARP].pc_name = "Address Resolution"; pkt_counters[PKT_RARP].pc_name = "Reverse Addr Resol"; pkt_counters[PKT_BROADCAST].pc_name = "Ethernet Broadcast"; pkt_counters[PKT_OTHER].pc_name = "Other Packets"; for (i = 0; i < MAXEXPORT; i++) { if (nfs_counters[i].nc_name != NULL) { (void) free(nfs_counters[i].nc_name); nfs_counters[i].nc_name = NULL; } } (void) bzero((char *) nfs_counters, MAXEXPORT * sizeof(NFSCounter)); (void) bzero((char *) fil_counters, MAXEXPORT * sizeof(FileCounter)); } /* * parsetop - parse the top of the log session. */ void parsetop(fp) FILE *fp; { int nskip = 0; char line[BUFSIZ]; /* * Get lines... */ while (fgets(line, sizeof(line), fp) != NULL) { /* * Second blank comment terminates this section. */ if (!strcmp(line, "#\n")) { if (++nskip == 2) return; continue; } /* * Grab the date - first one is start, * otherwise end. */ if (!strncmp(line, "Date: ", 6)) { if (startdate == NULL) { startdate = strdup(line + 6); enddate = strdup(line + 6); } else { (void) strcpy(enddate, line + 6); } continue; } } } /* * parsetotals - parse the totals section. */ void parsetotals(fp) FILE *fp; { int x, y, z; int nskip = 0; char line[BUFSIZ]; /* * Get lines... */ while (fgets(line, sizeof(line), fp) != NULL) { /* * Seond blank comment terminates this section. */ if (!strcmp(line, "#\n")) { if (++nskip == 2) return; continue; } /* * Grab the interval packets and add them. */ if (!strncmp(line, "Interval Packets:", 17)) { (void) sscanf(line + 17, "%d %d %d", &x, &y, &z); total_pkts += x; tohost_pkts += y; dropped_pkts += z; continue; } } } /* * parsepkts - parse packet counter section. */ void parsepkts(fp) FILE *fp; { int x, y, z; int nskip = 0; register int i; register char *s; char line[BUFSIZ]; /* * Get lines... */ while (fgets(line, sizeof(line), fp) != NULL) { /* * Second blank comment terminates this section. */ if (!strcmp(line, "#\n")) { if (++nskip == 2) return; continue; } /* * Find the numbers. */ if ((s = index(line, ':')) == NULL) continue; *s++ = 0; /* * Find the type we need. */ for (i = 0; i < PKT_NCOUNTERS; i++) { if (!strcmp(line, pkt_counters[i].pc_name)) { (void) sscanf(s, "%d %d%% %d", &x, &y, &z); pkt_counters[i].pc_total += x; break; } } } } /* * parsenfs - parse the NFS counter section. */ void parsenfs(fp) FILE *fp; { int x, y, z; int nskip = 0; register int i; register char *s; char line[BUFSIZ]; /* * Get lines... */ while (fgets(line, sizeof(line), fp) != NULL) { /* * Second blank comment terminates this section. */ if (!strcmp(line, "#\n")) { if (++nskip == 2) return; continue; } /* * Find the numbers. */ if ((s = index(line, ':')) == NULL) continue; *s++ = 0; /* * Find the NFS counter we want. */ if ((i = findnfs(line)) < 0) continue; (void) sscanf(s, "%d %d%% %d", &x, &y, &z); nfs_counters[i].nc_total += x; if ((s = index(s, '(')) != NULL) parseproc(s, nfs_counters[i].nc_proc); } } /* * parsefile - parse the file counter section. */ void parsefile(fp) FILE *fp; { int x, y, z; int nskip = 0; register int i; register char *s; char line[BUFSIZ]; /* * Get lines... */ while (fgets(line, sizeof(line), fp) != NULL) { /* * Second blank comment terminates this section. */ if (!strcmp(line, "#\n")) { if (++nskip == 2) return; continue; } /* * Find the numbers. */ if ((s = index(line, ':')) == NULL) continue; *s++ = 0; /* * Find the file counter we want. */ if ((i = findfile(line)) < 0) continue; (void) sscanf(s, "%d %d%% %d", &x, &y, &z); fil_counters[i].fc_total += x; if ((s = index(s, '(')) != NULL) parseproc(s, fil_counters[i].fc_proc); } } /* * parseproc - parse the NFS procedure counters. */ void parseproc(line, ctrs) Counter *ctrs; char *line; { register int i; register char *s; s = line + 1; for (i = 0; i < MAXNFSPROC; i++) { ctrs[i] += atoi(s); if ((s = index(s, '/')) == NULL) return; s++; } } /* * dumpit - print out the information. */ void dumpit() { float percent; char buf[BUFSIZ]; register int i, nfstotal; (void) printf("NFSwatch logfile summary:\n"); (void) printf(" Log time: %.24s to %.24s\n", startdate, enddate); (void) printf(" Log entries: %d\n", logentries); (void) printf(" Packets from: %s", srchost); (void) printf(" Packets to: %s\n", dsthost); (void) printf("Total packets:\n"); (void) printf(" %8ld (network) %8ld (to host) %8ld (dropped)\n\n", total_pkts, tohost_pkts, dropped_pkts); (void) printf("Packet counters:\n"); /* * Print the packet counters. Percentage is calculated as * this counter over total packets. */ for (i = 0; i < PKT_NCOUNTERS; i++) { if (total_pkts) { percent = ((float) pkt_counters[i].pc_total / (float) tohost_pkts) * 100.0; } else { percent = 0.0; } (void) sprintf(buf, "%s:", pkt_counters[i].pc_name); (void) printf(" %-25s %8ld %7.0f%%\n", buf, pkt_counters[i].pc_total, percent); if (i == (PKT_NCOUNTERS/2 - 1)) (void) putchar('\n'); } /* * Calculate the total number of NFS packets. */ nfstotal = pkt_counters[PKT_NFSWRITE].pc_total + pkt_counters[PKT_NFSREAD].pc_total; if (nfs_counters[0].nc_name != NULL) (void) printf("\nNFS counters:\n"); /* * Print the NFS counters. Percentage is calculated as * packets this file system over total NFS packets. */ for (i = 0; i < MAXEXPORT; i++) { if (nfs_counters[i].nc_name == NULL) continue; if (nfstotal) { percent = ((float) nfs_counters[i].nc_total / (float) nfstotal) * 100.0; } else { percent = 0.0; } (void) sprintf(buf, "%s:", nfs_counters[i].nc_name); (void) printf(" %-25s %8ld %7.0f%%\n", buf, nfs_counters[i].nc_total, percent); } if (fil_counters[0].fc_name != NULL) (void) printf("\nFile counters:\n"); /* * Print the file counters. Percentage is calculated as * packets this file over total NFS packets. */ for (i = 0; i < MAXEXPORT; i++) { if (fil_counters[i].fc_name == NULL) continue; if (nfstotal) { percent = ((float) fil_counters[i].fc_total / (float) nfstotal) * 100.0; } else { percent = 0.0; } (void) sprintf(buf, "%s:", fil_counters[i].fc_name); (void) printf(" %-25s %8ld %7.0f%%\n", buf, fil_counters[i].fc_total, percent); } (void) putchar('\014'); /* * If needed, put out the extra info. */ if (verbose) dumpit2(); } /* * dumpit2 - dump even more information. */ void dumpit2() { register int i, j, k; /* * Print NFS procs in groups of 6. */ for (i = 0; i < MAXNFSPROC; i += 6) { /* * Print header. */ (void) printf("NFSwatch logfile summary:\n"); (void) printf(" Log time: %.24s to %.24s\n", startdate, enddate); (void) printf(" Log entries: %d\n", logentries); (void) printf(" Packets from: %s", srchost); (void) printf(" Packets to: %s\n", dsthost); (void) printf("NFS Procedure Call Summary (part %d):\n", ((i / 6) + 1)); (void) printf(" "); for (j = 0; j < 6; j++) (void) printf("%s ", nfs_procs[i+j]); (void) putchar('\n'); /* * Print NFS counters. */ for (j = 0; j < MAXEXPORT; j++) { if (nfs_counters[j].nc_name == NULL) continue; (void) printf("%-25s", nfs_counters[j].nc_name); for (k = 0; k < 6; k++) { (void) printf("%8ld ", nfs_counters[j].nc_proc[i+k]); } (void) putchar('\n'); } if (fil_counters[0].fc_name != NULL) (void) putchar('\n'); /* * Print file counters. */ for (j = 0; j < MAXEXPORT; j++) { if (fil_counters[j].fc_name == NULL) continue; (void) printf("%-25s", fil_counters[j].fc_name); for (k = 0; k < 6; k++) { (void) printf("%8ld ", fil_counters[j].fc_proc[i+k]); } (void) putchar('\n'); } (void) putchar('\014'); } } /* * findnfs - find the counter associated with name. */ static int findnfs(char *name) { register int i; /* * Look for it. */ for (i = 0; i < MAXEXPORT; i++) { /* * At end of list. */ if (nfs_counters[i].nc_name == NULL) break; /* * Found it. */ if (!strcmp(name, nfs_counters[i].nc_name)) return(i); } /* * If there's room, add it to the list. */ if (i < MAXEXPORT) { nfs_counters[i].nc_name = strdup(name); return(i); } return(-1); } /* * findfile - find the counter assopciated with name. */ static int findfile(char *name) { register int i; /* * Look for it. */ for (i = 0; i < MAXEXPORT; i++) { /* * At end of list. */ if (fil_counters[i].fc_name == NULL) break; /* * Found it. */ if (!strcmp(name, fil_counters[i].fc_name)) return(i); } /* * If there's room, add it to the list. */ if (i < MAXEXPORT) { fil_counters[i].fc_name = strdup(name); return(i); } return(-1); } nfswatch-4.99.11/ChangeLog0000644000551200011300000002062611364240741014453 0ustar chrisludwig2010-04-22 17:56 c4chris * rpcfilter.c: Fix build on alpha Linux. 2010-04-21 17:21 c4chris * ChangeLog: Add ChangeLog file. 2009-04-21 07:42 c4chris * nfswatch.c, pktfilter.c: Fix compile on non-Linux (patch from Helen Chao). 2009-04-15 18:26 c4chris * README: Convert to utf8. 2009-04-15 18:21 c4chris * netaddr.c: Add TODO item about broken strict aliasing rule. 2009-04-15 17:43 c4chris * nfswatch.spec: Update changelog. 2009-04-15 17:40 c4chris * README, nfswatch.spec: Bump version number to 4.99.10. 2009-02-18 13:24 c4chris * nfswatch.c: Add TODO item, count by interface. 2009-02-03 13:51 c4chris * externs.h, linux.c, nfswatch.c, pktfilter.c: Introduce pkt_filter_sll() and use it. 2009-02-02 20:14 c4chris * nfswatch.c: Print friendlier message. 2009-02-02 20:10 c4chris * linux.c: Attempt to properly grok LINUX_SLL packets. 2009-02-02 00:33 c4chris * Makefile, externs.h, linux.c, nfswatch.c, nfswatch.h, util.c: Use the pcap library for Linux. Still need to grok the LINUX_SLL link type... 2008-12-11 15:46 c4chris * netaddr.c, rpcfilter.c: Add TODO items. 2007-05-25 16:41 c4chris * nfswatch.spec: Update changelog. 2007-05-25 16:40 c4chris * README, nfswatch.h, nfswatch.spec: Bump version number to 4.99.9. 2007-05-18 18:03 c4chris * rpcfilter.c: Do not handle the second argument of RENAME3 and LINK3, as it doesn't seem to work anyway. 2007-03-28 23:50 c4chris * parsenfsfh.c: Add missing include to use ntohl(). 2007-03-28 23:43 c4chris * parsenfsfh.c, rpcfilter.c, util.c: Improve filehandle decoding on Linux. 2007-03-28 17:39 c4chris * util.c: Exclude known non-exports instead of guessing exports. 2007-03-28 16:45 c4chris * rpcfilter.c: Handle more Linux filehandle's fsid_type. 2007-03-13 14:27 c4chris * nfswatch.spec: Update changelog. 2007-03-13 14:25 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.8. 2007-03-13 14:18 c4chris * README: Bring README file up to date. 2007-03-12 19:32 c4chris * dlpi.c: More careful parsing of device name and instance number. 2007-03-12 18:03 c4chris * parsenfsfh.c: Handle more Linux filehandle's fsid_type. 2007-01-30 15:59 c4chris * nfswatch.spec: Update changelog. 2007-01-30 15:47 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.7. 2007-01-30 15:44 c4chris * nfswatch.spec: Use updated install target of Makefile. 2007-01-30 15:41 c4chris * Makefile: Put in system binaries. 2007-01-30 15:37 c4chris * Makefile: Render Makefile a bit more Linux friendly. 2006-12-20 16:15 c4chris * Makefile, externs.h, logfile.c, nfswatch.c, nfswatch.h, rpcfilter.c, screen.c, util.c: Add Nick Williams's patch to make the per-procedure statistics work for NFSv3. 2006-06-14 13:30 c4chris * nfswatch.spec: Update changelog. 2006-06-14 13:21 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.6. 2006-06-14 12:50 c4chris * Makefile, rpcdefs.h, rpcfilter.c, rpcutil.c, sgi.map.h, xdr.c: Fix to get things to compile on IRIX6. 2006-06-13 15:22 c4chris * rpcutil.c: Solaris has one additional field in struct xp_ops. 2006-06-13 15:14 c4chris * dlpi.c: The alarm call cannot return an error. 2006-06-13 15:12 c4chris * dlpi.c: Remove unused parameter. 2006-06-13 15:10 c4chris * dlpi.c: Fix signed vs unsigned comparison warnings. 2006-06-13 11:16 c4chris * Makefile, externs.h, nfswatch.c, pktfilter.c, rpcfilter.c, util.c: Cleanup unused parameters. 2006-06-13 10:47 c4chris * netaddr.c, pktfilter.c: Fix signed vs unsigned comparison warning. 2006-06-13 10:41 c4chris * nfswatch.h, rpcfilter.c: Fix way to handle long usernames. 2006-06-12 23:12 c4chris * rpcutil.c: Avoid warning about type-punned pointer. 2005-12-06 13:09 c4chris * rpcfilter.c: Special case empty filehandle in LINK3. 2005-12-05 15:34 c4chris * rpcfilter.c: Special case empty filehandle in RENAME3. 2005-11-29 21:45 c4chris * screen.c: Fix 32bit-ism. 2005-11-22 23:11 c4chris * nfswatch.spec: Update changelog. 2005-11-21 19:07 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.5. 2005-11-21 17:54 c4chris * Makefile, os.h, rpcdefs.h, rpcfilter.c, xdr.c: Allow to build on older (5.7 and below) Solaris. 2005-11-21 15:41 c4chris * dlpi.c, nfswatch.c: Allow 64-bit compiles on Solaris. 2005-11-21 14:46 c4chris * externs.h, linux.c, nfswatch.c, os.h, pktfilter.c, rpcfilter.c, screen.c, xdr.c: Cleanup some GCC warning messages on Linux. 2005-11-16 16:01 c4chris * pktfilter.c: Attempt to grab NFS over TCP. 2005-07-19 16:53 c4chris * logfile.c: Enable screendumps in ncurses. 2005-07-19 15:27 c4chris * rpcfilter.c: Print more debug info when length is strange. 2005-07-19 15:10 c4chris * nfslogsum.c, nfswatch.h, rpcfilter.c, util.c: Display portmap instead of NIS. 2005-07-19 15:03 c4chris * externs.h, nfswatch.c, pktfilter.c, rpcdefs.h, rpcfilter.c: Add and use call to portmapper. 2005-07-19 14:59 c4chris * screen.c, screen.h, util.c: Provide wider interval column. 2005-07-12 23:39 c4chris * nfswatch.spec: Update changelog. 2005-07-12 23:28 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.4. 2005-07-12 23:25 c4chris * parsenfsfh.c: Handle linux in Parse_fh(). 2005-07-12 23:24 c4chris * screen.c: Fix total NFS packets count. 2005-06-02 15:36 c4chris * nfswatch.spec: Update changelog. 2005-06-02 15:32 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.3. 2005-06-02 15:22 c4chris * util.c: Add xfs to the list of recognized filesystems. 2005-04-22 17:53 c4chris * nfswatch.spec: Update changelog. 2005-04-22 17:50 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.2. 2005-04-22 17:46 c4chris * nfswatch.spec: Fix spec file for Fedora Extras. 2005-04-22 17:30 c4chris * Makefile: Handle RPM_OPT_FLAGS in Makefile. 2005-02-25 22:54 c4chris * rpcfilter.c, rpcutil.c, xdr.c: Add a few comments. 2005-02-25 17:49 c4chris * nfswatch.spec: Update changelog. 2005-02-25 17:43 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.1. 2005-02-25 17:34 c4chris * nfswatch.h, util.c: Fix c_proc size in a couple structures. 2005-02-25 16:14 c4chris * nfswatch.8: Add Linux info to man page. 2005-02-25 15:09 c4chris * rpcutil.c: Fix xdr_callmsg usage on 64-bit Linux. 2005-02-25 10:52 c4chris * linux.map.h, netaddr.c, parsenfsfh.c, rpcfilter.c, util.c: Parse NFS file handles in Linux. 2005-02-23 23:50 c4chris * linux.map.h, nfswatch.c, nfswatch.h, rpcdefs.h, rpcfilter.c, screen.c, util.c: Get NFS3 to compile on Linux. Cleanup a bit. 2005-02-23 22:41 c4chris * Makefile, externs.h, rpcdefs.h, rpcfilter.c, xdr.c: Finish NFS3 setup for Solaris. 2005-02-23 16:11 c4chris * externs.h, nfswatch.c, nfswatch.h, rpcdefs.h, rpcfilter.c, screen.c, util.c, xdr.c: Started crude hack to get NFS3 working on Solaris. 2005-02-07 19:21 c4chris * linux.map.h, nfslogsum.c, nfswatch.h, osf.map.h, pktfilter.c, rpcfilter.c, sgi.map.h, ultrix.map.h, util.c: Start work on NFSv3. Remove ND (Sun's network disk) stuff. 2005-02-06 17:05 c4chris * nfswatch.spec: Fix pasto in nfswatch.spec. 2005-02-06 17:00 c4chris * LICENSE, nfswatch.h: Add LICENSE file. 2005-02-06 16:56 c4chris * nfswatch.spec: Add nfswatch.spec. 2005-02-02 11:23 c4chris * pktfilter.c: Remove leftover debug fprintf. 2005-02-02 00:30 c4chris * dlpi.c, externs.h, linux.map.h, nfswatch.c, pktfilter.c, rpcdefs.h, rpcfilter.c, rpcutil.c, screen.c, util.c, xdr.c: Get a clean compile on Solaris 9. 2005-02-01 22:38 c4chris * util.c: Remove malloc() declaration. 2005-02-01 19:06 c4chris * Makefile, dlpi.c, externs.h, ipports.h, logfile.c, netaddr.c, nfsfh.h, nfslogsum.8, nfslogsum.c, nfswatch.8, nfswatch.c, nfswatch.h, nit.c, os.h, osf.map.h, parsenfsfh.c, pfilt.c, pktfilter.c, rpcdefs.h, rpcfilter.c, rpcutil.c, screen.c, screen.h, sgi.map.h, snoop.c, ultrix.map.h, util.c, xdr.c, linux.c, linux.map.h: Hack with an axe so that it compiles and runs on Linux. 2005-02-01 18:40 c4chris * Makefile, README, dlpi.c, externs.h, fhandle_layouts, ipports.h, logfile.c, netaddr.c, nfsfh.h, nfslogsum.8, nfslogsum.c, nfswatch.8, nfswatch.c, nfswatch.h, nit.c, os.h, osf.map.h, parsenfsfh.c, pfilt.c, pfopen.c, pktfilter.c, rpcdefs.h, rpcfilter.c, rpcutil.c, screen.c, screen.h, sgi.map.h, snoop.c, ultrix.map.h, util.c, xdr.c: Hmmph. Moving files around... nfswatch-4.99.11/rpcfilter.c0000644000551200011300000007416111364070646015047 0ustar chrisludwig/*#define DEBUG 1 */ /* * $Id: rpcfilter.c,v 1.25 2010/04/22 15:56:22 c4chris Exp $ */ #include "os.h" /* * rpcfilter.c - filter RPC packets. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ /* * TODO: replace the gethostbyaddr() functions with getnameinfo() * */ #include #include #include #include #include #ifdef SVR4 #include #include #endif #ifdef USE_LINUX /* This yucky hack is needed because glibc's headers are wrong wrt the * correct size needed in RPC stuff on 64-bit machines. There even is * a comment in to that effect... */ #define u_long uint32_t #endif #include #include #include #include #include #include #include #include #ifdef USE_LINUX #undef u_long #endif #include #include #include #include #include #include #include #include #define NFSSERVER 1 #ifdef sun #include #include #endif #ifdef ultrix #include #include #include #endif #ifdef sgi #include #ifdef IRIX6 #include #include #else #include "sgi.map.h" #endif #include #endif #if defined(__alpha) && !defined(LINUX) #include #include #include #include #endif #ifdef LINUX #include "linux.map.h" #endif #include "nfswatch.h" #include "externs.h" #include "rpcdefs.h" #if defined(SUNOS54) /* SunOS 5.4 hides all of these behind #ifdef _KERNEL in */ bool_t xdr_creatargs(); bool_t xdr_diropargs(); bool_t xdr_fhandle(); bool_t xdr_linkargs(); bool_t xdr_rddirargs(); bool_t xdr_readargs(); bool_t xdr_rnmargs(); bool_t xdr_saargs(); bool_t xdr_slargs(); bool_t xdr_writeargs(); #endif /* * NFS procedure types and XDR argument decoding routines. */ static struct nfs_proc nfs_procs[] = { /* RFS_NULL (0) */ { NFS_READ, (xdrproc_t) xdr_void, 0 }, /* RFS_GETATTR (1) */ { NFS_READ, (xdrproc_t) xdr_fhandle, sizeof(fhandle_t) }, /* RFS_SETATTR (2) */ { NFS_WRITE, (xdrproc_t) xdr_saargs, sizeof(struct nfssaargs) }, /* RFS_ROOT (3) */ { NFS_READ, (xdrproc_t) xdr_void, 0 }, /* RFS_LOOKUP (4) */ { NFS_READ, (xdrproc_t) xdr_diropargs, sizeof(struct nfsdiropargs) }, /* RFS_READLINK (5) */ { NFS_READ, (xdrproc_t) xdr_fhandle, sizeof(fhandle_t) }, /* RFS_READ (6) */ { NFS_READ, (xdrproc_t) xdr_readargs, sizeof(struct nfsreadargs) }, /* RFS_WRITECACHE (7) */ { NFS_WRITE, (xdrproc_t) xdr_void, 0 }, /* RFS_WRITE (8) */ { NFS_WRITE, (xdrproc_t) xdr_writeargs, sizeof(struct nfswriteargs) }, /* RFS_CREATE (9) */ { NFS_WRITE, (xdrproc_t) xdr_creatargs, sizeof(struct nfscreatargs) }, /* RFS_REMOVE (10) */ { NFS_WRITE, (xdrproc_t) xdr_diropargs, sizeof(struct nfsdiropargs) }, /* RFS_RENAME (11) */ { NFS_WRITE, (xdrproc_t) xdr_rnmargs, sizeof(struct nfsrnmargs) }, /* RFS_LINK (12) */ { NFS_WRITE, (xdrproc_t) xdr_linkargs, sizeof(struct nfslinkargs) }, /* RFS_SYMLINK (13) */ { NFS_WRITE, (xdrproc_t) xdr_slargs, sizeof(struct nfsslargs) }, /* RFS_MKDIR (14) */ { NFS_WRITE, (xdrproc_t) xdr_creatargs, sizeof(struct nfscreatargs) }, /* RFS_RMDIR (15) */ { NFS_WRITE, (xdrproc_t) xdr_diropargs, sizeof(struct nfsdiropargs) }, /* RFS_READDIR (16) */ { NFS_READ, (xdrproc_t) xdr_rddirargs, sizeof(struct nfsrddirargs) }, /* RFS_STATFS (17) */ { NFS_READ, (xdrproc_t) xdr_fhandle, sizeof(fhandle_t) } }; /* * NFS3 procedure types and XDR argument decoding routines. */ static struct nfs_proc nfs3_procs[] = { /* NFSPROC3_NULL (0) */ { NFS_READ, (xdrproc_t) xdr_void, 0 }, /* NFSPROC3_GETATTR (1) */ { NFS_READ, (xdrproc_t) xdr_nfs_fh3, sizeof(nfs_fh3) }, /* NFSPROC3_SETATTR (2) */ { NFS_WRITE, (xdrproc_t) xdr_nfs_fh3, sizeof(nfs_fh3) }, /* NFSPROC3_LOOKUP (3) */ { NFS_READ, (xdrproc_t) xdr_diropargs3, sizeof(diropargs3) }, /* NFSPROC3_ACCESS (4) */ { NFS_READ, (xdrproc_t) xdr_nfs_fh3, sizeof(nfs_fh3) }, /* NFSPROC3_READLINK (5) */ { NFS_READ, (xdrproc_t) xdr_nfs_fh3, sizeof(nfs_fh3) }, /* NFSPROC3_READ (6) */ { NFS_READ, (xdrproc_t) xdr_nfs_fh3, sizeof(nfs_fh3) }, /* NFSPROC3_WRITE (7) */ { NFS_WRITE, (xdrproc_t) xdr_nfs_fh3, sizeof(nfs_fh3) }, /* NFSPROC3_CREATE (8) */ { NFS_WRITE, (xdrproc_t) xdr_diropargs3, sizeof(diropargs3) }, /* NFSPROC3_MKDIR (9) */ { NFS_WRITE, (xdrproc_t) xdr_diropargs3, sizeof(diropargs3) }, /* NFSPROC3_SYMLINK (10) */ { NFS_WRITE, (xdrproc_t) xdr_diropargs3, sizeof(diropargs3) }, /* NFSPROC3_MKNOD (11) */ { NFS_WRITE, (xdrproc_t) xdr_diropargs3, sizeof(diropargs3) }, /* NFSPROC3_REMOVE (12) */ { NFS_WRITE, (xdrproc_t) xdr_diropargs3, sizeof(diropargs3) }, /* NFSPROC3_RMDIR (13) */ { NFS_WRITE, (xdrproc_t) xdr_diropargs3, sizeof(diropargs3) }, /* NFSPROC3_RENAME (14) */ { NFS_WRITE, (xdrproc_t) xdr_RENAME3args, sizeof(RENAME3args) }, /* NFSPROC3_LINK (15) */ { NFS_WRITE, (xdrproc_t) xdr_LINK3args, sizeof(LINK3args) }, /* NFSPROC3_READDIR (16) */ { NFS_READ, (xdrproc_t) xdr_nfs_fh3, sizeof(nfs_fh3) }, /* NFSPROC3_READDIRPLUS (17) */ { NFS_READ, (xdrproc_t) xdr_nfs_fh3, sizeof(nfs_fh3) }, /* NFSPROC3_FSSTAT (18) */ { NFS_READ, (xdrproc_t) xdr_nfs_fh3, sizeof(nfs_fh3) }, /* NFSPROC3_FSINFO (19) */ { NFS_READ, (xdrproc_t) xdr_nfs_fh3, sizeof(nfs_fh3) }, /* NFSPROC3_PATHCONF (20) */ { NFS_READ, (xdrproc_t) xdr_nfs_fh3, sizeof(nfs_fh3) }, /* NFSPROC3_COMMIT (21) */ { NFS_WRITE, (xdrproc_t) xdr_nfs_fh3, sizeof(nfs_fh3) } }; NFSCall nfs_calls[NFSCALLHASHSIZE]; static void CountCallAuth(struct rpc_msg *); static void CountSrc(ipaddrt); static void rpc_callfilter(char *, u_int, ipaddrt, struct timeval *); static void rpc_replyfilter(char *, ipaddrt, struct timeval *); static void nfs_filter(char *, u_int, ipaddrt, struct timeval *); static void nfs_count(fhandle_t *, int); static void nfs3_count(nfs_fh3 *, int); static void nfs_hash_call(int proto, struct rpc_msg *, ipaddrt, struct timeval *); static void nfs_hash_reply(struct rpc_msg *, ipaddrt, struct timeval *); int udprpc_recv(char *, u_int, struct rpc_msg *, SVCXPRT **); static void nfs3_filter(char *, u_int, ipaddrt, struct timeval *); /* * rpc_filter - pass off RPC packets to other filters. */ void rpc_filter(char *data, u_int length, ipaddrt src, ipaddrt dst, struct timeval *tstamp) { register struct rpc_msg *msg; msg = (struct rpc_msg *) data; /* * See which "direction" the packet is going. We * can classify RPC CALLs, but we cannot classify * REPLYs, since they no longer have the RPC * program number in them (sigh). */ switch (ntohl(msg->rm_direction)) { case CALL: /* RPC call */ rpc_callfilter(data, length, src, tstamp); break; case REPLY: /* RPC reply */ rpc_replyfilter(data, dst, tstamp); break; default: /* probably not an RPC packet */ break; } } /* * rpc_callfilter - filter RPC call packets. */ static void rpc_callfilter(char *data, u_int length, ipaddrt src, struct timeval *tstamp) { struct rpc_msg *msg = (struct rpc_msg *) data; uint32_t prog = ntohl(msg->rm_call.cb_prog); /* * Decide what to do based on the program. */ switch (prog) { case RPC_NFSPROG: { int version = ntohl(msg->rm_call.cb_vers); if (version == 2) nfs_filter(data, length, src, tstamp); else if (version == 3) nfs3_filter(data, length, src, tstamp); else fprintf(stderr, "Unknown NFS version: %d\n", version); break; } case RPC_PMAPPROG: pkt_counters[PKT_PORTMAP].pc_interval++; pkt_counters[PKT_PORTMAP].pc_total++; break; case RPC_MOUNTPROG: pkt_counters[PKT_NFSMOUNT].pc_interval++; pkt_counters[PKT_NFSMOUNT].pc_total++; break; #ifdef notdef case RPC_YPPROG: case RPC_YPBINDPROG: case RPC_YPPASSWDPROG: case RPC_YPUPDATEPROG: case RPC_NIS: case RPC_CACHEPROG: case RPC_CB_PROG: case RPC_RSTATPROG: case RPC_RUSERSPROG: case RPC_DBXPROG: case RPC_WALLPROG: case RPC_ETHERSTATPROG: case RPC_RQUOTAPROG: case RPC_SPRAYPROG: case RPC_IBM3270PROG: case RPC_IBMRJEPROG: case RPC_SELNSVCPROG: case RPC_RDATABASEPROG: case RPC_REXECPROG: case RPC_ALICEPROG: case RPC_SCHEDPROG: case RPC_LOCKPROG: case RPC_NETLOCKPROG: case RPC_X25PROG: case RPC_STATMON1PROG: case RPC_STATMON2PROG: case RPC_SELNLIBPROG: case RPC_BOOTPARAMPROG: case RPC_MAZEPROG: case RPC_KEYSERVEPROG: case RPC_SECURECMDPROG: case RPC_NETFWDIPROG: case RPC_NETFWDTPROG: case RPC_SUNLINKMAP_PROG: case RPC_NETMONPROG: case RPC_DBASEPROG: case RPC_PWDAUTHPROG: case RPC_TFSPROG: case RPC_NSEPROG: case RPC_NSE_ACTIVATE_PROG: case RPC_PCNFSDPROG: case RPC_PYRAMIDLOCKINGPROG: case RPC_PYRAMIDSYS5: case RPC_CADDS_IMAGE: case RPC_ADT_RFLOCKPROG: #endif default: pkt_counters[PKT_OTHERRPC].pc_interval++; pkt_counters[PKT_OTHERRPC].pc_total++; break; } } /* * rpc_replyfilter - count RPC reply packets. */ static void rpc_replyfilter(char *data, ipaddrt dst, struct timeval *tstamp) { register struct rpc_msg *msg; msg = (struct rpc_msg *) data; pkt_counters[PKT_RPCAUTH].pc_interval++; pkt_counters[PKT_RPCAUTH].pc_total++; nfs_hash_reply(msg, dst, tstamp); } /* * nfs_filter - filter NFS packets. */ static void nfs_filter(char *data, u_int length, ipaddrt src, struct timeval *tstamp) { u_int proc; caddr_t args; SVCXPRT *xprt; struct rpc_msg msg; union nfs_rfsargs nfs_rfsargs; char cred_area[2*MAX_AUTH_BYTES]; msg.rm_call.cb_cred.oa_base = cred_area; msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]); /* * Act as if we received this packet through RPC. */ if (!udprpc_recv(data, length, &msg, &xprt)) return; /* * Get the NFS procedure number. */ proc = msg.rm_call.cb_proc; if (proc >= MAXNFSPROC) return; CountCallAuth(&msg); nfs_hash_call(NFSv2, &msg, src, tstamp); /* * Now decode the arguments to the procedure from * XDR format. */ args = (caddr_t) &nfs_rfsargs; (void) bzero(args, nfs_procs[proc].nfs_argsz); if (!SVC_GETARGS(xprt, nfs_procs[proc].nfs_xdrargs, args)) return; prc_counters[NFSv2][prc_countmap[NFSv2][proc]].pr_total++; prc_counters[NFSv2][prc_countmap[NFSv2][proc]].pr_interval++; CountSrc(src); /* * Now count the packet in the appropriate file system's * counters. */ switch (proc) { case RFS_NULL: break; case RFS_GETATTR: nfs_count(&nfs_rfsargs.fhandle, proc); break; case RFS_SETATTR: nfs_count(&nfs_rfsargs.nfssaargs.saa_fh, proc); break; case RFS_ROOT: break; case RFS_LOOKUP: #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ nfs_count(&nfs_rfsargs.nfsdiropargs.da_fhandle_buf, proc); #else nfs_count(&nfs_rfsargs.nfsdiropargs.da_fhandle, proc); #endif break; case RFS_READLINK: nfs_count(&nfs_rfsargs.fhandle, proc); break; case RFS_READ: nfs_count(&nfs_rfsargs.nfsreadargs.ra_fhandle, proc); break; case RFS_WRITECACHE: break; case RFS_WRITE: #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ nfs_count(&nfs_rfsargs.nfswriteargs.wa_args_buf.otw_wa_fhandle, proc); #else nfs_count(&nfs_rfsargs.nfswriteargs.wa_fhandle, proc); #endif break; case RFS_CREATE: #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ nfs_count(&nfs_rfsargs.nfscreatargs.ca_da.da_fhandle_buf, proc); #else nfs_count(&nfs_rfsargs.nfscreatargs.ca_da.da_fhandle, proc); #endif break; case RFS_REMOVE: #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ nfs_count(&nfs_rfsargs.nfsdiropargs.da_fhandle_buf, proc); #else nfs_count(&nfs_rfsargs.nfsdiropargs.da_fhandle, proc); #endif break; case RFS_RENAME: #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ nfs_count(&nfs_rfsargs.nfsrnmargs.rna_from.da_fhandle_buf, proc); #else nfs_count(&nfs_rfsargs.nfsrnmargs.rna_from.da_fhandle, proc); #endif break; case RFS_LINK: #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ nfs_count(&nfs_rfsargs.nfslinkargs.la_from_buf, proc); #else nfs_count(&nfs_rfsargs.nfslinkargs.la_from, proc); #endif break; case RFS_SYMLINK: #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ nfs_count(&nfs_rfsargs.nfsslargs.sla_from.da_fhandle_buf, proc); #else nfs_count(&nfs_rfsargs.nfsslargs.sla_from.da_fhandle, proc); #endif break; case RFS_MKDIR: #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ nfs_count(&nfs_rfsargs.nfscreatargs.ca_da.da_fhandle_buf, proc); #else nfs_count(&nfs_rfsargs.nfscreatargs.ca_da.da_fhandle, proc); #endif break; case RFS_RMDIR: #if defined(SUNOS5) && defined(DA_FREENAME) /* SunOS 2.2 and greater */ nfs_count(&nfs_rfsargs.nfsdiropargs.da_fhandle_buf, proc); #else nfs_count(&nfs_rfsargs.nfsdiropargs.da_fhandle, proc); #endif break; case RFS_READDIR: nfs_count(&nfs_rfsargs.nfsrddirargs.rda_fh, proc); break; case RFS_STATFS: nfs_count(&nfs_rfsargs.fhandle, proc); break; } /* * Decide whether it's a read or write process. */ switch (nfs_procs[proc].nfs_proctype) { case NFS_READ: pkt_counters[PKT_NFSREAD].pc_interval++; pkt_counters[PKT_NFSREAD].pc_total++; break; case NFS_WRITE: pkt_counters[PKT_NFSWRITE].pc_interval++; pkt_counters[PKT_NFSWRITE].pc_total++; break; } } /* * nfs_count - count an NFS reference to a specific file system. */ static NFSCounter *lastmatch = NULL; static void do_nfs_count(my_fsid fsid, ino_t ino, char *osname, char *sfsname, int proc) { int i, match1; /* * Run through the NFS counters looking for the matching * file system. */ match1 = 0; /* We use a 1-behind cache to speed the search */ if (lastmatch) { if (learnfs) { match1 = fsid_eq(lastmatch->nc_fsid, fsid); } else { match1 = dev_eq(lastmatch->nc_dev, fsid.fsid_dev); } if (allflag && match1) match1 = (thisdst == lastmatch->nc_ipaddr); } if (match1 == 0) { /* wasn't the same as the last packet, try the hard way */ for (i = 0; i < nnfscounters; i++) { NFSCounter *nfscp = &nfs_counters[i]; if (learnfs) { match1 = fsid_eq(nfscp->nc_fsid, fsid); } else { match1 = dev_eq(nfscp->nc_dev, fsid.fsid_dev); } /* * Check server address. */ if (allflag && match1) match1 = (thisdst == nfscp->nc_ipaddr); if (match1) { nfscp->nc_proc[proc]++; nfscp->nc_interval++; nfscp->nc_total++; lastmatch = nfscp; break; } } } else { lastmatch->nc_proc[proc]++; lastmatch->nc_interval++; lastmatch->nc_total++; } /* * We don't know about this file system, but we can * learn. */ if (!match1 && learnfs && (nnfscounters < MAXEXPORT)) { static char fsname[64], prefix[64]; #if defined(SVR4) || defined(LINUX) sighold(SIGALRM); #else int oldm; oldm = sigblock(sigmask(SIGALRM)); #endif /* no redisplay while unstable */ i = nnfscounters++; nfs_counters[i].nc_fsid = fsid; nfs_counters[i].nc_dev = fsid.fsid_dev; nfs_counters[i].nc_proc[proc]++; nfs_counters[i].nc_interval++; nfs_counters[i].nc_total++; *prefix = 0; if (allflag) { struct hostent *hp; nfs_counters[i].nc_ipaddr = thisdst; hp = gethostbyaddr((char *) &thisdst, sizeof(thisdst), AF_INET); if (hp) { char *index(); char *dotp; sprintf(prefix, "%s", hp->h_name); if ((dotp = index(prefix, '.')) != NULL) *dotp = 0; } else { struct in_addr ia; ia.s_addr = thisdst; sprintf(prefix, "%s", inet_ntoa(ia)); } } if (sfsname) { /* file system ID is ASCII, not numeric, for server OS */ static char temp[17]; /* Make sure string is null-terminated */ strncpy(temp, sfsname, 16); temp[16] = 0; sprintf(fsname, "%.8s:%s %s", prefix, temp, osname); } else { sprintf(fsname, "%.12s(%ld,%ld)%s", prefix, nfs_counters[i].nc_dev.Major, nfs_counters[i].nc_dev.Minor, osname); } if (mapfile) nfs_counters[i].nc_name = strdup(map_fs_name(fsname)); else nfs_counters[i].nc_name = strdup(fsname); sort_nfs_counters(); #if defined(SVR4) || defined(LINUX) sigrelse(SIGALRM); #else (void) sigsetmask(oldm); /* permit redisplay */ #endif } if (filelist == NULL) return; /* XXX could use a 1-behind cache here, too */ /* * Run through the file counters looking for the matching * file. */ for (i = 0; i < nfilecounters; i++) { FileCounter *fcp = &(fil_counters[i]); if (dev_eq(fcp->fc_dev, fsid.fsid_dev) && (fcp->fc_ino == ino)) { fcp->fc_proc[proc]++; fcp->fc_interval++; fcp->fc_total++; break; } } } static void nfs_count(fhandle_t *fh, int proc) { my_fsid fsid; ino_t ino; char *osname = ""; char *sfsname = NULL; /* Convert file handle to our internal representations */ #ifdef DEBUG Parse_fh((caddr_t *) fh, &fsid, &ino, &osname, &sfsname, to_self(thisdst)); #else Parse_fh((caddr_t *) fh, &fsid, &ino, NULL, &sfsname, to_self(thisdst)); #endif if (fhdebugf) { /* Print file handles for specified servers */ unsigned char *fhcp = (unsigned char *)fh; struct in_addr ia; int i; if (allflag) { /* print host name if not implicit */ ia.s_addr = thisdst; (void)printf("%s: ", inet_ntoa(ia)); } for (i = 0; i < NFS_FHSIZE; i++) (void)printf("%x.", fhcp[i]); (void)printf("\n"); } do_nfs_count(fsid, ino, osname, sfsname, proc); } static void nfs3_count(nfs_fh3 *fh, int proc) { if (fh == NULL) { fprintf(stderr, "fh is NULL for proc %d\n", proc); return; } if (fh->fh3_length == 32) nfs_count(&fh->fh3_u.nfs_fh3_i.fh3_i, proc); else { unsigned char *fhp = fh->fh3_u.data; if (fhp[0] == 1 && fhp[1] == 0) { my_fsid fsid; ino_t ino; memset(&fsid, 0, sizeof(fsid)); switch (fhp[2]) { case 0: /* 4 byte device id (ms-2-bytes major, ls-2-bytes minor), 4 byte inode number. */ fsid.fsid_dev.Major = (fhp[4] << 8) | fhp[5]; fsid.fsid_dev.Minor = (fhp[6] << 8) | fhp[7]; /* This is probably the inode number of the export point... Might want to grab the actual file's inode number. */ ino = (fhp[8] << 24) | (fhp[9] << 16) | (fhp[10] << 8) | fhp[11]; do_nfs_count(fsid, ino, "Linux", NULL, proc); return; case 1: /* 4 byte filesystem ID. */ fsid.fsid_dev.Minor = ntohl((fhp[4] << 24) | (fhp[5] << 16) | (fhp[6] << 8) | fhp[7]); do_nfs_count(fsid, 0, "Linux", NULL, proc); return; case 2: /* 4 byte device major, 4 byte device minor, 4 byte inode number. */ fsid.fsid_dev.Major = (fhp[4] << 24) | (fhp[5] << 16) | (fhp[6] << 8) | fhp[7]; fsid.fsid_dev.Minor = (fhp[8] << 24) | (fhp[9] << 16) | (fhp[10] << 8) | fhp[11]; /* This is probably the inode number of the export point... Might want to grab the actual file's inode number. */ ino = (fhp[12] << 24) | (fhp[13] << 16) | (fhp[14] << 8) | fhp[15]; do_nfs_count(fsid, ino, "Linux", NULL, proc); return; case 3: /* 4 byte encoded device info, 4 byte inode number. */ fsid.fsid_dev.Major = ((fhp[5] & 0xf) << 8 ) | fhp[6]; fsid.fsid_dev.Minor = (fhp[4] << 12) | ((fhp[5] & 0xf0) << 8) | fhp[7]; /* This is probably the inode number of the export point... Might want to grab the actual file's inode number. */ ino = (fhp[8] << 24) | (fhp[9] << 16) | (fhp[10] << 8) | fhp[11]; do_nfs_count(fsid, ino, "Linux", NULL, proc); return; } } fprintf(stderr, "nfs3_count: length is %08x, proc is %d\n" "%02x%02x%02x%02x\n" "%02x%02x%02x%02x\n" "%02x%02x%02x%02x\n", fh->fh3_length, proc, fh->fh3_u.data[0], fh->fh3_u.data[1], fh->fh3_u.data[2], fh->fh3_u.data[3], fh->fh3_u.data[4], fh->fh3_u.data[5], fh->fh3_u.data[6], fh->fh3_u.data[7], fh->fh3_u.data[8], fh->fh3_u.data[9], fh->fh3_u.data[10], fh->fh3_u.data[11]); } } /* * CountSrc uses a hash table to speed lookups. Hash function * uses high and low octect of IP address, so as to be * fast and byte-order independent. Table is organized * as a array of linked lists. */ #define HASHSIZE 0x100 #define HASH(addr) (((addr) & 0xFF) ^ (((addr) >> 24) & 0xFF)) ClientCounter *Addr_hashtable[HASHSIZE]; /* initially all NULL ptrs */ ClientCounter *cc_hint = clnt_counters; /* one-element cache */ static void CountSrc(ipaddrt src) { register ClientCounter *ccp; int hcode = HASH(src); /* See if this is the same client as last time */ if (cc_hint->cl_ipaddr == src) { cc_hint->cl_total++; cc_hint->cl_interval++; return; } /* Search hash table */ ccp = Addr_hashtable[hcode]; while (ccp) { if (ccp->cl_ipaddr == src) { ccp->cl_total++; ccp->cl_interval++; cc_hint = ccp; return; } ccp = ccp->cl_next; } /* new client */ if (nclientcounters < MAXCLIENTS) { struct hostent *hp; static char clnt_name[64]; #if defined(SVR4) || defined(LINUX) sighold(SIGALRM); #else int oldm; oldm = sigblock(sigmask(SIGALRM)); #endif /* no redisplay while unstable */ ccp = &(clnt_counters[nclientcounters]); nclientcounters++; /* Add to hash table */ ccp->cl_next = Addr_hashtable[hcode]; Addr_hashtable[hcode] = ccp; /* Fill in new ClientCounter */ ccp->cl_ipaddr = src; hp = gethostbyaddr((char *) &ccp->cl_ipaddr, sizeof(ccp->cl_ipaddr), AF_INET); if (hp) { char *index(); char *dotp; sprintf(clnt_name, "%s", hp->h_name); if ((dotp = index(clnt_name, '.')) != NULL) *dotp = 0; } else { struct in_addr ia; ia.s_addr = ccp->cl_ipaddr; sprintf(clnt_name, "%s", inet_ntoa(ia)); } ccp->cl_name = strdup(clnt_name); ccp->cl_total = 1; ccp->cl_interval = 1; sort_clnt_counters(); #if defined(SVR4) || defined(LINUX) sigrelse(SIGALRM); #else (void) sigsetmask(oldm); /* permit redisplay */ #endif } } /* * Must be called after sorting the clnt_counters[] table * Should put busiest ones at front of list, but doesn't */ void ClientHashRebuild(void) { register int i; register ClientCounter *ccp; int hcode; bzero(Addr_hashtable, sizeof(Addr_hashtable)); for (i = 0, ccp = clnt_counters; i < nclientcounters; i++, ccp++) { hcode = HASH(ccp->cl_ipaddr); ccp->cl_next = Addr_hashtable[hcode]; Addr_hashtable[hcode] = ccp; } } /* * Code to count authentication instances. */ #define UIDOFFSET 100000 /* add to a non-uid so it won't conflict with uids */ static void CountCallAuth(struct rpc_msg *msg) { int i, len, auth; struct passwd *pw; unsigned int *oauth; static char user_name[MAXUSERNAMELEN + 1] = {'\0'}; auth = msg->ru.RM_cmb.cb_cred.oa_flavor; if (auth != AUTH_UNIX) { auth += UIDOFFSET; } else { /* * Convert the opaque authorization into a uid. * Should use the XDR decoders. */ oauth = (unsigned int *) msg->ru.RM_cmb.cb_cred.oa_base; len = ntohl(oauth[1]); if ((len % 4) != 0) len = len + 4 - len % 4; auth = ntohl(oauth[2 + len / 4]); } for (i=0; i < nauthcounters; i++) { if (auth_counters[i].ac_uid == auth) { auth_counters[i].ac_interval++; auth_counters[i].ac_total++; return; } } if (nauthcounters < MAXAUTHS) { nauthcounters++; auth_counters[i].ac_uid = auth; auth_counters[i].ac_total = 1; auth_counters[i].ac_interval = 1; switch (auth) { case AUTH_NULL + UIDOFFSET: auth_counters[i].ac_name = "AUTH_NULL"; break; case AUTH_UNIX + UIDOFFSET: auth_counters[i].ac_name = "AUTH_UNIX"; break; case AUTH_SHORT + UIDOFFSET: auth_counters[i].ac_name = "AUTH_SHORT"; break; case AUTH_DES + UIDOFFSET: auth_counters[i].ac_name = "AUTH_DES"; break; default: if ((pw = getpwuid(auth)) != NULL) strncpy(user_name, pw->pw_name, MAXUSERNAMELEN); else snprintf(user_name, MAXUSERNAMELEN, "#%d", auth); auth_counters[i].ac_name = strdup(user_name); break; } sort_auth_counters(); } } /* * Some code to look at response times. */ static void nfs_hash_call(int proto, struct rpc_msg *msg, ipaddrt client, struct timeval *tstamp) { int i; if (tstamp == NULL) return; for (i=0; i < NFSCALLHASHSIZE; i++) { if (nfs_calls[i].proto == 0) { nfs_calls[i].proto = proto; nfs_calls[i].proc = msg->rm_call.cb_proc; nfs_calls[i].client = client; nfs_calls[i].xid = msg->rm_xid; nfs_calls[i].time_sec = tstamp->tv_sec; nfs_calls[i].time_usec = tstamp->tv_usec; return; } } } static void nfs_hash_reply(struct rpc_msg *msg, ipaddrt client, struct timeval *tstamp) { int i; double diff; u_int proc; u_int32 xid = ntohl(msg->rm_xid); if (tstamp == NULL) return; for (i=0; i < NFSCALLHASHSIZE; i++) { if (nfs_calls[i].proto == 0) continue; if (nfs_calls[i].client == client && nfs_calls[i].xid == xid) { int proto = nfs_calls[i].proto; proc = prc_countmap[proto][nfs_calls[i].proc]; diff = ((tstamp->tv_sec - nfs_calls[i].time_sec) * 1000000 + tstamp->tv_usec - nfs_calls[i].time_usec) / 1000.0; prc_counters[proto][proc].pr_complete++; prc_counters[proto][proc].pr_response += diff; prc_counters[proto][proc].pr_respsqr += diff * diff; if (diff > prc_counters[proto][proc].pr_maxresp) prc_counters[proto][proc].pr_maxresp = diff; nfs_calls[i].proto = 0; return; } } } /* * nfs3_filter - filter NFSv3 packets. */ static void nfs3_filter(char *data, u_int length, ipaddrt src, struct timeval *tstamp) { u_int proc; caddr_t args; SVCXPRT *xprt; struct rpc_msg msg; union nfs3_rfsargs nfs_rfsargs; char cred_area[2*MAX_AUTH_BYTES]; msg.rm_call.cb_cred.oa_base = cred_area; msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]); /* * Act as if we received this packet through RPC. */ if (!udprpc_recv(data, length, &msg, &xprt)) return; /* * Get the NFS procedure number. */ proc = msg.rm_call.cb_proc; if (proc >= MAXNFS3PROC) return; CountCallAuth(&msg); nfs_hash_call(NFSv3, &msg, src, tstamp); /* * Now decode the arguments to the procedure from * XDR format. */ args = (caddr_t) &nfs_rfsargs; (void) bzero(args, nfs3_procs[proc].nfs_argsz); if (!SVC_GETARGS(xprt, nfs3_procs[proc].nfs_xdrargs, args)) return; prc_counters[NFSv3][prc_countmap[NFSv3][proc]].pr_total++; prc_counters[NFSv3][prc_countmap[NFSv3][proc]].pr_interval++; CountSrc(src); /* * Now count the packet in the appropriate file system's * counters. */ switch (proc) { case NFSPROC3_NULL: break; case NFSPROC3_GETATTR: nfs3_count(&nfs_rfsargs.nfs_fh3_a, proc); break; case NFSPROC3_SETATTR: nfs3_count(&nfs_rfsargs.nfs_fh3_a, proc); break; case NFSPROC3_LOOKUP: #if (defined(SUNOS5) && !defined(SUNOS58)) || defined(IRIX6) nfs3_count(&nfs_rfsargs.diropargs3_a.dir, proc); #else nfs3_count(nfs_rfsargs.diropargs3_a.dirp, proc); #endif break; case NFSPROC3_ACCESS: nfs3_count(&nfs_rfsargs.nfs_fh3_a, proc); break; case NFSPROC3_READLINK: nfs3_count(&nfs_rfsargs.nfs_fh3_a, proc); break; case NFSPROC3_READ: nfs3_count(&nfs_rfsargs.nfs_fh3_a, proc); break; case NFSPROC3_WRITE: nfs3_count(&nfs_rfsargs.nfs_fh3_a, proc); break; case NFSPROC3_CREATE: #if (defined(SUNOS5) && !defined(SUNOS58)) || defined(IRIX6) nfs3_count(&nfs_rfsargs.diropargs3_a.dir, proc); #else nfs3_count(nfs_rfsargs.diropargs3_a.dirp, proc); #endif break; case NFSPROC3_MKDIR: #if (defined(SUNOS5) && !defined(SUNOS58)) || defined(IRIX6) nfs3_count(&nfs_rfsargs.diropargs3_a.dir, proc); #else nfs3_count(nfs_rfsargs.diropargs3_a.dirp, proc); #endif break; case NFSPROC3_SYMLINK: #if (defined(SUNOS5) && !defined(SUNOS58)) || defined(IRIX6) nfs3_count(&nfs_rfsargs.diropargs3_a.dir, proc); #else nfs3_count(nfs_rfsargs.diropargs3_a.dirp, proc); #endif break; case NFSPROC3_MKNOD: #if (defined(SUNOS5) && !defined(SUNOS58)) || defined(IRIX6) nfs3_count(&nfs_rfsargs.diropargs3_a.dir, proc); #else nfs3_count(nfs_rfsargs.diropargs3_a.dirp, proc); #endif break; case NFSPROC3_REMOVE: #if (defined(SUNOS5) && !defined(SUNOS58)) || defined(IRIX6) nfs3_count(&nfs_rfsargs.diropargs3_a.dir, proc); #else nfs3_count(nfs_rfsargs.diropargs3_a.dirp, proc); #endif break; case NFSPROC3_RMDIR: #if (defined(SUNOS5) && !defined(SUNOS58)) || defined(IRIX6) nfs3_count(&nfs_rfsargs.diropargs3_a.dir, proc); #else nfs3_count(nfs_rfsargs.diropargs3_a.dirp, proc); #endif break; case NFSPROC3_RENAME: #if (defined(SUNOS5) && !defined(SUNOS58)) || defined(IRIX6) nfs3_count(&nfs_rfsargs.RENAME3args_a.from.dir, proc); #else nfs3_count(nfs_rfsargs.RENAME3args_a.from.dirp, proc); #endif break; case NFSPROC3_LINK: nfs3_count(&nfs_rfsargs.LINK3args_a.file, proc); break; case NFSPROC3_READDIR: nfs3_count(&nfs_rfsargs.nfs_fh3_a, proc); break; case NFSPROC3_READDIRPLUS: nfs3_count(&nfs_rfsargs.nfs_fh3_a, proc); break; case NFSPROC3_FSSTAT: nfs3_count(&nfs_rfsargs.nfs_fh3_a, proc); break; case NFSPROC3_FSINFO: nfs3_count(&nfs_rfsargs.nfs_fh3_a, proc); break; case NFSPROC3_PATHCONF: nfs3_count(&nfs_rfsargs.nfs_fh3_a, proc); break; case NFSPROC3_COMMIT: nfs3_count(&nfs_rfsargs.nfs_fh3_a, proc); break; } /* * Decide whether it's a read or write process. */ switch (nfs3_procs[proc].nfs_proctype) { case NFS_READ: pkt_counters[PKT_NFS3READ].pc_interval++; pkt_counters[PKT_NFS3READ].pc_total++; break; case NFS_WRITE: pkt_counters[PKT_NFS3WRITE].pc_interval++; pkt_counters[PKT_NFS3WRITE].pc_total++; break; } } void get_rpc_ports(void) { struct sockaddr_in sai; int i; if (serverflag) return; memset(&sai, 0, sizeof(sai)); sai.sin_family = AF_INET; for (i = 0; (dstaddrs[i] != 0) && (i < MAXHOSTADDR); i++) { struct pmaplist *pml; sai.sin_addr.s_addr = dstaddrs[0]; pml = pmap_getmaps(&sai); while (pml != NULL) { struct pmaplist *cur = pml; pml = pml->pml_next; if (cur->pml_map.pm_prot == IPPROTO_UDP && cur->pml_map.pm_port != NFS_PORT) { int found = 0; unsigned int j; for (j = 0; j < rpcPortCnt; j++) if (rpcPort[j] == cur->pml_map.pm_port) { found = 1; break; } if (!found) { if ((rpcPort = realloc(rpcPort, (rpcPortCnt + 1) * sizeof(unsigned long))) == NULL) { perror("get_rpc_ports: realloc"); rpcPortCnt = 0; return; } rpcPort[rpcPortCnt++] = cur->pml_map.pm_port; } } free(cur); } } } nfswatch-4.99.11/fhandle_layouts0000644000551200011300000002266410177737456016030 0ustar chrisludwigUltrix: [little-endian] dev_t fsid; /* filesystem id (minor:8, major:8) */ /*short padding;*/ /* presumably zero */ u_long fno; /* file number */ u_long fgen; /* file generation */ u_long eno; /* file number */ u_long egen; /* file generation */ characteristic pattern in network order: byte 0 1 2 3 4 5 6 7 minor major pad pad fno fno fno fno 0..255 1..255 0 0 [ 4-byte field is non-zero ] [Note: byte 1 could be zero on a VAX with MASSBUS "hp" disks] byte 8 9 10 11 12 13 14 15 fgen fgen fgen fgen eno eno eno eno [ 4-byte field is non-zero ] byte 16 17 18 19 20 21 22 23 egen egen egen egen pad pad pad pad [ probably zero ] byte 24 25 26 27 28 29 30 31 pad pad pad pad pad pad pad pad [ probably zero ] [ probably zero ] /*****************************************************************************/ DEC OSF/1: [little-endian] fsid_t fh_fsid; /* filesystem id, 64 bits */ /* val[0] = (minor:20, major:12) */ /* val[1] = FS type (small integer) */ struct _fh_fid { u_short fid_len; /* = 12 */ u_short fid_reserved; char fid_data[8]; /* 32 bits of inode, 32 bits of gen */ } fh_fid; /* file ID */ struct _fh_fid fh_efid; /* export directory ID */ characteristic pattern in network order: byte 0 1 2 3 4 5 6 7 min0:8 min8:8 min16:4 maj4:4 FStype FStype FStype FStype maj0:4 0..255 0..255 1..255 0..255 1..10 0 0 0 byte 8 9 10 11 12 13 14 15 fid_len fid_len fid_res fid_res ino ino ino ino 12 0 0 0 [ 4-byte field is non-zero ] byte 16 17 18 19 20 21 22 23 fid_len fid_len fid_res fid_res ino ino ino ino 12 0 0 0 [ 4-byte field is non-zero ] /*****************************************************************************/ SunOS 4.X: [big-endian] /* XXX - little-endian on Sun386i? */ fsid_t fh_fsid; /* filesys id (minor:8, major:8), fstype:32 */ u_short fh_len; /* file number length = 10 */ char fh_data[8]; /* and data (ino:32, gen:32) */ u_short fh_xlen; /* export file number length */ char fh_xdata[8]; /* and data */ characteristic pattern in network order: byte 0 1 2 3 4 5 6 7 pad pad major minor FStype FStype FStype FStype 0 0 1..255 0..255 0 0 0 1..255 byte 8 9 10 11 12 13 14 15 fh_len fh_len pad pad ino ino ino ino 0 10 0 0 [ 4-byte field is non-zero ] byte 16 17 18 19 20 21 22 23 gen gen gen gen fh_xlen fh_xlen pad pad 0 10 0 0 byte 24 25 26 27 28 29 30 31 ino ino ino ino gen gen gen gen [ 4-byte field is non-zero ] /*****************************************************************************/ SunOS 5.X: [big-endian] /* XXX - little-endian on IBM-compatible PC? */ fsid_t fh_fsid; /* filesys id (minor:18, major:14),fstype:32 */ u_short fh_len; /* file number length = 10 */ char fh_data[8]; /* and data (ino:32, gen:32) */ u_short fh_xlen; /* export file number length */ char fh_xdata[8]; /* and data */ characteristic pattern in network order: byte 0 1 2 3 4 5 6 7 major major:6 minor minor FStype FStype FStype FStype minor:2 0..255 1..255 0..255 0..255 0 0 0 1..255 byte 8 9 10 11 12 13 14 15 fh_len fh_len pad pad ino ino ino ino 0 10 0 0 [ 4-byte field is non-zero ] byte 16 17 18 19 20 21 22 23 gen gen gen gen fh_xlen fh_xlen pad pad 0 10 0 0 byte 24 25 26 27 28 29 30 31 ino ino ino ino gen gen gen gen [ 4-byte field is non-zero ] /*****************************************************************************/ Auspex (if not like SunOS 4.x): [big-endian] fsid_t fh_fsid; /* zero:32, filesys id (minor:8, major:8) */ u_short fh_len; /* file number length = 8 */ char fh_data[8]; /* and data (ino:32, gen:32) */ u_short fh_xlen; /* export file number length */ char fh_xdata[8]; /* and data */ characteristic pattern in network order: byte 0 1 2 3 4 5 6 7 zero zero zero zero pad pad major minor 0 0 0 0 0 0 1..255 0..255 byte 8 9 10 11 12 13 14 15 fh_len fh_len pad pad ino ino ino ino 0 8 0 0 [ 4-byte field is non-zero ] byte 16 17 18 19 20 21 22 23 gen gen gen gen fh_xlen fh_xlen pad pad 0 10 0 0 byte 24 25 26 27 28 29 30 31 ino ino ino ino gen gen gen gen [ 4-byte field is non-zero ] /*****************************************************************************/ SGI IRIX4.x: [big-endian] fsid_t fh_fsid; /* filesys id (minor:8, major:8, pad: 16) */ u_short fh_len; /* file number length = 8? */ u_short padding; char fh_data[8]; /* and data (gen:32, ino:32?) */ u_short fh_xlen; /* export file number length = 8? */ char fh_xdata[8]; /* and data */ characteristic pattern in network order: byte 0 1 2 3 4 5 6 7 pad pad major minor fh_len fh_len pad pad 0 0 1..255 0..255 0 8? 0 0 byte 8 9 10 11 12 13 14 15 ino ino ino ino gen gen gen gen [ 4-byte field is non-zero ] byte 16 17 18 19 20 21 22 23 fh_xlen fh_xlen pad? pad? ino ino ino ino [ 4-byte field is non-zero ] byte 24 25 26 27 28 29 30 31 gen gen gen gen pad pad pad pad [ probably zero ] /*****************************************************************************/ SGI IRIX5.x: [big-endian] {seems identical to SunOS 5.X; is this SVR4 std?} fsid_t fh_fsid; /* filesys id (minor:18, major:14, fstype:32)*/ u_short fh_len; /* file number length = 10 */ char fh_data[8]; /* and data (ino:32, gen:32) */ u_short fh_xlen; /* export file number length */ char fh_xdata[8]; /* and data */ characteristic pattern in network order: byte 0 1 2 3 4 5 6 7 major major:6 minor minor FStype FStype FStype FStype minor:2 0..255 1..255 0..255 0..255 0 0 0 1..255 byte 8 9 10 11 12 13 14 15 fh_len fh_len pad pad ino ino ino ino 0 10 0 0 [ 4-byte field is non-zero ] byte 16 17 18 19 20 21 22 23 gen gen gen gen fh_xlen fh_xlen pad pad 0 10 0 0 byte 24 25 26 27 28 29 30 31 ino ino ino ino gen gen gen gen [ 4-byte field is non-zero ] /*****************************************************************************/ DEC VMS UCX: [little-endian] char DeviceIDsomething[1]; /* ?? */ char DeviceID[13]; /* in ASCII, actually "DEVLOCKNAM" */ char Flags[2]; /* binary bits */ char RootFID[6]; /* 48-bit field, identifies root */ /* Format: * fileIDlo:16 * generation:16 * relVolumeNumber:8 * fileIDhi:8 * Always (4,4,0,0) for VMS volume. * Otherwise, "container file system" */ char FileID[6]; /* 48-bit field */ /* * UCX constructs "nodeid" as * fileIDlo,fileIDhi,RVN */ char Inumber[4]; /* 32-bit number; * non-zero only for container FS */ characteristic pattern in network order: byte 0 1 2 3 4 5 6 7 code devid devid devid devid devid devid devid ?? byte 8 9 10 11 12 13 14 15 devid devid devid devid devid devid flags flags "devid" field starts with a string of printable characters, then spaces, then nulls? /*****************************************************************************/ AIX 3.2: [big-endian] fsid_t fh_fsid; /* filesys id (minor:16, major:16),fstype:32 */ u_short fh_len; /* file number length = 10 */ char fh_data[8]; /* and data (ino:32, gen:32) */ u_short fh_xlen; /* export file number length */ char fh_xdata[8]; /* and data */ characteristic pattern in network order: byte 0 1 2 3 4 5 6 7 major major minor minor FStype FStype FStype FStype 1..65535 0..255 0..255 0 0 0 0..255 byte 8 9 10 11 12 13 14 15 fh_len fh_len pad pad ino ino ino ino 0 10 0 0 [ 4-byte field is non-zero ] byte 16 17 18 19 20 21 22 23 gen gen gen gen fh_xlen fh_xlen pad pad 0 10 0 0 byte 24 25 26 27 28 29 30 31 ino ino ino ino gen gen gen gen [ 4-byte field is non-zero ] /*****************************************************************************/ HP-UX 9.01: [big-endian] char major; /* 8-bit major device number */ char minor[3]; /* 24-bit minor device number */ char something[4]; /* sometimes (always?) all zeros */ u_short fh_len; /* file number length = 10 */ char fh_data[8]; /* and data (ino:32, gen:32) */ u_short fh_xlen; /* export file number length */ char fh_xdata[8]; /* and data */ characteristic pattern in network order: byte 0 1 2 3 4 5 6 7 major minor minor minor FStype FStype FStype FStype 1..255 0..255 0..255 0..255 [ might be always zero? ] byte 8 9 10 11 12 13 14 15 fh_len fh_len pad pad ino ino ino ino 0 10 0 0 [ 4-byte field is non-zero ] byte 16 17 18 19 20 21 22 23 gen gen gen gen fh_xlen fh_xlen pad pad 0 10 0 0 byte 24 25 26 27 28 29 30 31 ino ino ino ino gen gen gen gen [ 4-byte field is non-zero ] /*****************************************************************************/ Network Appliance FAServer: [little-endian] typedef struct { ulong fileid; ulong generation; } nfs_Mount_point; nfs_Mount_point mount_pt; /* file ID and generation of mount point */ typedef struct { ushort flags; uchar snapid; uchar unused; ulong fileid; ulong generation; } wafl_File_handle; wafl_File_handle file_handle; /* file handle */ wafl_File_handle export_pt; /* export point file handle */ characteristic pattern in network order: byte 0 1 2 3 4 5 6 7 ino ino ino ino gen gen gen gen [ 4-byte field is non-zero ] byte 8 9 10 11 12 13 14 15 flags flags snapid unused ino ino ino ino 0..255 0..255 0..20 0 [ 4-byte field is non-zero ] byte 16 17 18 19 20 21 22 23 gen gen gen gen flags flags snapid unused [ 4-byte field is non-zero ] 0..255 0..255 0..20 0 byte 24 25 26 27 28 29 30 31 ino ino ino ino gen gen gen gen [ 4-byte field is non-zero ] nfswatch-4.99.11/nfswatch.spec0000644000551200011300000002164511364242300015365 0ustar chrisludwig# $Id: nfswatch.spec,v 1.25 2010/04/23 06:57:04 c4chris Exp $ Summary: An NFS traffic monitoring tool Name: nfswatch Version: 4.99.11 Release: 1%{?dist} License: BSD URL: http://nfswatch.sourceforge.net Group: Applications/Internet Source0: http://dl.sf.net/nfswatch/%{name}-%{version}.tar.gz Prefix: %{_prefix} BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: libpcap-devel ncurses-devel %description Nfswatch is a command-line tool for monitoring NFS traffic. Nfswatch can capture and analyze the NFS packets on a particular network interface or on all interfaces. Install nfswatch if you need a program to monitor NFS traffic. %prep %setup -q %build make %install rm -rf ${RPM_BUILD_ROOT} make STRIP= MANSUF=8 DESTDIR=${RPM_BUILD_ROOT} install %clean rm -rf ${RPM_BUILD_ROOT} %files %defattr(-,root,root) %doc LICENSE README %{_sbindir}/nfswatch %{_sbindir}/nfslogsum %{_mandir}/man8/* %changelog * Fri Apr 23 2010 Christian Iseli 4.99.11-1 - 2010-04-22 17:56 c4chris * rpcfilter.c: Fix build on alpha Linux. - 2010-04-21 17:21 c4chris * ChangeLog: Add ChangeLog file. - 2009-04-21 07:42 c4chris * nfswatch.c, pktfilter.c: Fix compile on non-Linux (patch from Helen Chao). - 2009-04-15 18:26 c4chris * README: Convert to utf8. - 2009-04-15 18:21 c4chris * netaddr.c: Add TODO item about broken strict aliasing rule. - 2009-04-15 17:43 c4chris * nfswatch.spec: Update changelog. * Wed Apr 15 2009 Christian Iseli 4.99.10-1 - 2009-04-15 17:40 c4chris * README, nfswatch.spec: Bump version number to 4.99.10. - 2009-02-18 13:24 c4chris * nfswatch.c: Add TODO item, count by interface. - 2009-02-03 13:51 c4chris * externs.h, linux.c, nfswatch.c, pktfilter.c: Introduce pkt_filter_sll() and use it. - 2009-02-02 20:14 c4chris * nfswatch.c: Print friendlier message. - 2009-02-02 20:10 c4chris * linux.c: Attempt to properly grok LINUX_SLL packets. - 2009-02-02 00:33 c4chris * Makefile, externs.h, linux.c, nfswatch.c, nfswatch.h, util.c: Use the pcap library for Linux. Still need to grok the LINUX_SLL link type... - 2008-12-11 15:46 c4chris * netaddr.c, rpcfilter.c: Add TODO items. - 2007-05-25 16:41 c4chris * nfswatch.spec: Update changelog. * Fri May 25 2007 Christian Iseli 4.99.9-1 - 2007-05-25 16:40 c4chris * README, nfswatch.h, nfswatch.spec: Bump version number to 4.99.9. - 2007-05-18 18:03 c4chris * rpcfilter.c: Do not handle the second argument of RENAME3 and LINK3, as it doesn't seem to work anyway. - 2007-03-28 23:50 c4chris * parsenfsfh.c: Add missing include to use ntohl(). - 2007-03-28 23:43 c4chris * parsenfsfh.c, rpcfilter.c, util.c: Improve filehandle decoding on Linux. - 2007-03-28 17:39 c4chris * util.c: Exclude known non-exports instead of guessing exports. - 2007-03-28 16:45 c4chris * rpcfilter.c: Handle more Linux filehandle's fsid_type. - 2007-03-13 14:27 c4chris * nfswatch.spec: Update changelog. * Tue Mar 13 2007 Christian Iseli 4.99.8-1 - 2007-03-13 14:25 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.8. - 2007-03-13 14:18 c4chris * README: Bring README file up to date. - 2007-03-12 19:32 c4chris * dlpi.c: More careful parsing of device name and instance number. - 2007-03-12 18:03 c4chris * parsenfsfh.c: Handle more Linux filehandle's fsid_type. - 2007-01-30 15:59 c4chris * nfswatch.spec: Update changelog. * Tue Jan 30 2007 Christian Iseli 4.99.7-1 - 2007-01-30 15:47 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.7. - 2007-01-30 15:44 c4chris * nfswatch.spec: Use updated install target of Makefile. - 2007-01-30 15:41 c4chris * Makefile: Put in system binaries. - 2007-01-30 15:37 c4chris * Makefile: Render Makefile a bit more Linux friendly. - 2006-12-20 16:15 c4chris * Makefile, externs.h, logfile.c, nfswatch.c, nfswatch.h, rpcfilter.c, screen.c, util.c: Add Nick Williams's patch to make the per-procedure statistics work for NFSv3. - 2006-06-14 13:30 c4chris * nfswatch.spec: Update changelog. * Wed Jun 14 2006 Christian Iseli 4.99.6-1 - 2006-06-14 13:21 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.6. - 2006-06-14 12:50 c4chris * Makefile, rpcdefs.h, rpcfilter.c, rpcutil.c, sgi.map.h, xdr.c: Fix to get things to compile on IRIX6. - 2006-06-13 15:22 c4chris * rpcutil.c: Solaris has one additional field in struct xp_ops. - 2006-06-13 15:14 c4chris * dlpi.c: The alarm call cannot return an error. - 2006-06-13 15:12 c4chris * dlpi.c: Remove unused parameter. - 2006-06-13 15:10 c4chris * dlpi.c: Fix signed vs unsigned comparison warnings. - 2006-06-13 11:16 c4chris * Makefile, externs.h, nfswatch.c, pktfilter.c, rpcfilter.c, util.c: Cleanup unused parameters. - 2006-06-13 10:47 c4chris * netaddr.c, pktfilter.c: Fix signed vs unsigned comparison warning. - 2006-06-13 10:41 c4chris * nfswatch.h, rpcfilter.c: Fix way to handle long usernames. - 2006-06-12 23:12 c4chris * rpcutil.c: Avoid warning about type-punned pointer. - 2005-12-06 13:09 c4chris * rpcfilter.c: Special case empty filehandle in LINK3. - 2005-12-05 15:34 c4chris * rpcfilter.c: Special case empty filehandle in RENAME3. - 2005-11-29 21:45 c4chris * screen.c: Fix 32bit-ism. - 2005-11-22 23:11 c4chris * nfswatch.spec: Update changelog. * Tue Nov 22 2005 Christian Iseli 4.99.5-1 - 2005-11-21 19:07 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.5. - 2005-11-21 17:54 c4chris * Makefile, os.h, rpcdefs.h, rpcfilter.c, xdr.c: Allow to build on older (5.7 and below) Solaris. - 2005-11-21 15:41 c4chris * dlpi.c, nfswatch.c: Allow 64-bit compiles on Solaris. - 2005-11-21 14:46 c4chris * externs.h, linux.c, nfswatch.c, os.h, pktfilter.c, rpcfilter.c, screen.c, xdr.c: Cleanup some GCC warning messages on Linux. - 2005-11-16 16:01 c4chris * pktfilter.c: Attempt to grab NFS over TCP. - 2005-07-19 16:53 c4chris * logfile.c: Enable screendumps in ncurses. - 2005-07-19 15:27 c4chris * rpcfilter.c: Print more debug info when length is strange. - 2005-07-19 15:10 c4chris * nfslogsum.c, nfswatch.h, rpcfilter.c, util.c: Display portmap instead of NIS. - 2005-07-19 15:03 c4chris * externs.h, nfswatch.c, pktfilter.c, rpcdefs.h, rpcfilter.c: Add and use call to portmapper. - 2005-07-19 14:59 c4chris * screen.c, screen.h, util.c: Provide wider interval column. - 2005-07-12 23:39 c4chris * nfswatch.spec: Update changelog. * Tue Jul 12 2005 Christian Iseli 4.99.4-1 - 2005-07-12 23:28 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.4. - 2005-07-12 23:25 c4chris * parsenfsfh.c: Handle linux in Parse_fh(). - 2005-07-12 23:24 c4chris * screen.c: Fix total NFS packets count. - 2005-06-02 15:36 c4chris * nfswatch.spec: Update changelog. * Thu Jun 2 2005 Christian Iseli 4.99.3-1 - 2005-06-02 15:32 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.3. - 2005-06-02 15:22 c4chris * util.c: Add xfs to the list of recognized filesystems. - 2005-04-22 17:53 c4chris * nfswatch.spec: Update changelog. * Fri Apr 22 2005 Christian Iseli 4.99.2-1 - 2005-04-22 17:50 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.2. - 2005-04-22 17:46 c4chris * nfswatch.spec: Fix spec file for Fedora Extras. - 2005-04-22 17:30 c4chris * Makefile: Handle RPM_OPT_FLAGS in Makefile. - 2005-02-25 22:54 c4chris * rpcfilter.c, rpcutil.c, xdr.c: Add a few comments. - 2005-02-25 17:49 c4chris * nfswatch.spec: Update changelog. * Fri Feb 25 2005 Christian Iseli 4.99.1-1 - 2005-02-25 17:43 c4chris * nfswatch.h, nfswatch.spec: Bump version number to 4.99.1. - 2005-02-25 17:34 c4chris * nfswatch.h, util.c: Fix c_proc size in a couple structures. - 2005-02-25 16:14 c4chris * nfswatch.8: Add Linux info to man page. - 2005-02-25 15:09 c4chris * rpcutil.c: Fix xdr_callmsg usage on 64-bit Linux. - 2005-02-25 10:52 c4chris * linux.map.h, netaddr.c, parsenfsfh.c, rpcfilter.c, util.c: Parse NFS file handles in Linux. - 2005-02-23 23:50 c4chris * linux.map.h, nfswatch.c, nfswatch.h, rpcdefs.h, rpcfilter.c, screen.c, util.c: Get NFS3 to compile on Linux. Cleanup a bit. - 2005-02-23 22:41 c4chris * Makefile, externs.h, rpcdefs.h, rpcfilter.c, xdr.c: Finish NFS3 setup for Solaris. - 2005-02-23 16:11 c4chris * externs.h, nfswatch.c, nfswatch.h, rpcdefs.h, rpcfilter.c, screen.c, util.c, xdr.c: Started crude hack to get NFS3 working on Solaris. - 2005-02-07 19:21 c4chris * linux.map.h, nfslogsum.c, nfswatch.h, osf.map.h, pktfilter.c, rpcfilter.c, sgi.map.h, ultrix.map.h, util.c: Start work on NFSv3. Remove ND (Sun's network disk) stuff. * Sun Feb 6 2005 Christian Iseli 4.99.0-1 - Create spec file. nfswatch-4.99.11/Makefile0000644000551200011300000001561211141430521014326 0ustar chrisludwig# # $Id: Makefile,v 1.11 2009/02/01 23:33:37 c4chris Exp $ # # Makefile for nfswatch. # # David A. Curry Jeffrey C. Mogul # Purdue University Digital Equipment Corporation # Engineering Computer Network Western Research Laboratory # 1285 Electrical Engineering Building 250 University Avenue # West Lafayette, IN 47907-1285 Palo Alto, CA 94301 # davy@ecn.purdue.edu mogul@decwrl.dec.com # # # Choose an appropriate value for "OS" from the ones below: # # IRIX40 Silicon Graphics IRIX 4.0 # IRIX51 Silicon Graphics IRIX 5.1 # SUNOS4 Sun Microsystems SunOS 4.x # SUNOS5 Sun Microsystems SunOS 5.x (Solaris 2.x) # SVR4 AT&T System V Release 4 # ULTRIX Digital Equipment Ultrix 4.x # DECOSF Digital Equipment OSF/1 V1.3 and later # OS= # # Set BINDIR, MANDIR, and MANSUF to appropriate values for your system. # DESTDIR= BINDIR= /usr/sbin MANDIR= /usr/share/man/man8 INSTALL=install MANSUF= 8.gz STRIP= -s IRIX40CFLAGS= -DIRIX40 -O -cckr IRIX51CFLAGS= -DIRIX51 -DIRIX40 -O -cckr -D_BSD_SIGNALS IRIX6CFLAGS= -DIRIX6 -DIRIX51 -DIRIX40 -O -D_BSD_SIGNALS SUNOS4CFLAGS= -DSUNOS4 -O SUNOS5CFLAGS= -DSUNOS5 -O SUNOS54CFLAGS= -DSUNOS54 -DSUNOS5 -O SUNOS55CFLAGS= -DSUNOS55 -DSUNOS5 -O -Wall SUNOS58CFLAGS= -DSUNOS58 -DSUNOS5 -O -Wall SVR4CFLAGS= -DSVR4 -O ULTRIXCFLAGS= -DULTRIX -O DECOSFCFLAGS= -DDECOSF -O LINUXCFLAGS= -DLINUX -O -Wall -W $(RPM_OPT_FLAGS) IRIX40LIBS= -lcurses -ltermcap -lsun -lm IRIX51LIBS= -lcurses -ltermcap -lm SUNOS4LIBS= -lcurses -ltermcap -lm SUNOS5LIBS= -lcurses -lnsl -lsocket -lm SUNOS54LIBS= -lcurses -lnsl -lsocket -lm SUNOS55LIBS= -lcurses -lnsl -lsocket -lm SUNOS58LIBS= -lcurses -lnsl -lsocket -lm SVR4LIBS= -lcurses -lnsl -lsocket -lm ULTRIXLIBS= -lcurses -ltermcap -lm #DECOSFLIBS= -lcurses -ltermcap -lm DECOSFLIBS= -lcurses -ltermcap -lm pfopen.c LINUXLIBS= -lpcap -lncurses -lm CFLAGS= LIBS= PRINT= enscript -r -G SHELL= /bin/sh HDRS= externs.h nfswatch.h rpcdefs.h screen.h SRCS= dlpi.c logfile.c netaddr.c nfswatch.c nit.c pfilt.c pktfilter.c \ rpcfilter.c rpcutil.c screen.c snoop.c util.c xdr.c nfslogsum.c \ parsenfsfh.c linux.c OBJS= dlpi.o logfile.o netaddr.o nfswatch.o nit.o pfilt.o pktfilter.o \ rpcfilter.o rpcutil.o screen.o snoop.o util.o xdr.o parsenfsfh.o \ linux.o all: os-nfswatch os-nfslogsum os-nfswatch: @if [ "$(OS)" = "" ]; then \ OS=`uname -s -r`; \ fi; \ case "$$OS" in \ LINUX\ *|Linux\ *) \ make CFLAGS="$(LINUXCFLAGS)" LIBS="$(LINUXLIBS)" nfswatch; \ ;; \ IRIX40|IRIX\ 4*) \ make CFLAGS="$(IRIX40CFLAGS)" LIBS="$(IRIX40LIBS)" nfswatch; \ ;; \ IRIX51|IRIX\ 5*) \ make CFLAGS="$(IRIX51CFLAGS)" LIBS="$(IRIX51LIBS)" nfswatch; \ ;; \ IRIX6|IRIX\ 6*) \ make CC=gcc CFLAGS="$(IRIX6CFLAGS)" LIBS="$(IRIX51LIBS)" nfswatch; \ ;; \ SUNOS4|SunOS\ 4*) \ make CFLAGS="$(SUNOS4CFLAGS)" LIBS="$(SUNOS4LIBS)" nfswatch; \ ;; \ SUNOS5|SunOS\ 5.[0123]) \ make CFLAGS="$(SUNOS5CFLAGS)" LIBS="$(SUNOS5LIBS)" nfswatch; \ ;; \ SUNOS54|SunOS\ 5.4) \ make CFLAGS="$(SUNOS54CFLAGS)" LIBS="$(SUNOS54LIBS)" nfswatch; \ ;; \ SUNOS55|SunOS\ 5.[567]) \ make CFLAGS="$(SUNOS55CFLAGS)" LIBS="$(SUNOS55LIBS)" nfswatch; \ ;; \ SUNOS58|SunOS\ 5.*) \ make CFLAGS="$(SUNOS58CFLAGS)" LIBS="$(SUNOS58LIBS)" nfswatch; \ ;; \ SVR4|System\ V\ Release\ 4*) \ make CFLAGS="$(SVR4CFLAGS)" LIBS="$(SVR4LIBS)" nfswatch; \ ;; \ ULTRIX\ *|Ultrix\ *|ultrix\ *) \ make CFLAGS="$(ULTRIXCFLAGS)" LIBS="$(ULTRIXLIBS)" nfswatch; \ ;; \ OSF1\ *|OSF\ *) \ make CFLAGS="$(DECOSFCFLAGS)" LIBS="$(DECOSFLIBS)" nfswatch; \ ;; \ *) \ echo "OS=$$OS is not a supported operating system."; \ exit 1; \ ;; \ esac os-nfslogsum: @if [ "$(OS)" = "" ]; then \ OS=`uname -s -r`; \ fi; \ case "$$OS" in \ LINUX|Linux\ *) \ make CFLAGS="$(LINUXCFLAGS)" LIBS="$(LINUXLIBS)" nfslogsum; \ ;; \ IRIX40|IRIX\ 4*) \ make CFLAGS="$(IRIX40CFLAGS)" LIBS="$(IRIX40LIBS)" nfslogsum; \ ;; \ IRIX51|IRIX\ 5*) \ make CFLAGS="$(IRIX51CFLAGS)" LIBS="$(IRIX51LIBS)" nfslogsum; \ ;; \ IRIX6|IRIX\ 6*) \ make CC=gcc CFLAGS="$(IRIX6CFLAGS)" LIBS="$(IRIX51LIBS)" nfslogsum; \ ;; \ SUNOS4|SunOS\ 4*) \ make CFLAGS="$(SUNOS4CFLAGS)" LIBS="$(SUNOS4LIBS)" nfslogsum; \ ;; \ SUNOS5|SunOS\ 5*) \ make CFLAGS="$(SUNOS5CFLAGS)" LIBS="$(SUNOS5LIBS)" nfslogsum; \ ;; \ SVR4|System\ V\ Release\ 4*) \ make CFLAGS="$(SVR4CFLAGS)" LIBS="$(SVR4LIBS)" nfslogsum; \ ;; \ ULTRIX\ *|Ultrix\ *|ultrix\ *) \ make CFLAGS="$(ULTRIXCFLAGS)" LIBS="$(ULTRIXLIBS)" nfslogsum; \ ;; \ OSF1\ *|OSF\ *) \ make CFLAGS="$(DECOSFCFLAGS)" LIBS="$(DECOSFLIBS)" nfslogsum; \ ;; \ *) \ echo "OS=$$OS is not a supported operating system."; \ exit 1; \ ;; \ esac nfswatch: nfswatch.o $(OBJS) $(CC) -o nfswatch $(OBJS) $(LIBS) nfslogsum: nfslogsum.o $(CC) -o nfslogsum nfslogsum.o install: bininstall maninstall bininstall: all mkdir -p $(DESTDIR)$(BINDIR) $(INSTALL) -c $(STRIP) nfswatch $(DESTDIR)$(BINDIR) $(INSTALL) -c $(STRIP) nfslogsum $(DESTDIR)$(BINDIR) maninstall: nfswatch-man nfslogsum-man nfswatch-man: $(DESTDIR)$(MANDIR)/nfswatch.$(MANSUF) $(DESTDIR)$(MANDIR)/nfswatch.$(MANSUF): nfswatch.8 mkdir -p $(DESTDIR)$(MANDIR) case "$(MANSUF)" in \ *.gz) \ SUF=`echo $(MANSUF)|sed 's/\.gz//'`; \ $(INSTALL) -c -m 0644 nfswatch.8 $(DESTDIR)$(MANDIR)/nfswatch.$$SUF; \ gzip --best $(DESTDIR)$(MANDIR)/nfswatch.$$SUF; \ ;; \ *) \ $(INSTALL) -c -m 0644 nfswatch.8 $(DESTDIR)$(MANDIR)/nfswatch.$(MANSUF); \ ;; \ esac nfslogsum-man: $(DESTDIR)$(MANDIR)/nfslogsum.$(MANSUF) $(DESTDIR)$(MANDIR)/nfslogsum.$(MANSUF): nfslogsum.8 mkdir -p $(DESTDIR)$(MANDIR) case "$(MANSUF)" in \ *.gz) \ SUF=`echo $(MANSUF)|sed 's/\.gz//'`; \ $(INSTALL) -c -m 0644 nfslogsum.8 $(DESTDIR)$(MANDIR)/nfslogsum.$$SUF; \ gzip --best $(DESTDIR)$(MANDIR)/nfslogsum.$$SUF; \ ;; \ *) \ $(INSTALL) -c -m 0644 nfslogsum.8 $(DESTDIR)$(MANDIR)/nfslogsum.$(MANSUF); \ ;; \ esac print: $(PRINT) Makefile $(HDRS) $(SRCS) clean: rm -f \#* a.out core nfswatch nfslogsum nfslogsum.o $(OBJS) rm -f *.BAK *.CKP dlpi.o: dlpi.c nfswatch.h externs.h os.h nfsfh.h logfile.o: logfile.c nfswatch.h externs.h screen.h os.h nfsfh.h netaddr.o: netaddr.c nfswatch.h externs.h os.h nfsfh.h nfslogsum.o: nfslogsum.c nfswatch.h os.h nfsfh.h nfswatch.o: nfswatch.c nfswatch.h os.h nfsfh.h nit.o: nit.c nfswatch.h externs.h os.h nfsfh.h pfilt.o: pfilt.c nfswatch.h externs.h os.h nfsfh.h pktfilter.o: pktfilter.c nfswatch.h externs.h os.h nfsfh.h rpcfilter.o: rpcfilter.c nfswatch.h externs.h rpcdefs.h os.h nfsfh.h rpcutil.o: rpcutil.c nfswatch.h externs.h rpcdefs.h os.h nfsfh.h screen.o: screen.c nfswatch.h externs.h screen.h os.h nfsfh.h snoop.o: snoop.c nfswatch.h externs.h os.h nfsfh.h linux.o: linux.c nfswatch.h externs.h os.h nfsfh.h util.o: util.c nfswatch.h externs.h screen.h os.h nfsfh.h xdr.o: xdr.c nfswatch.h os.h nfsfh.h parsenfsfh.o: parsenfsfh.c nfsfh.h nfswatch-4.99.11/snoop.c0000644000551200011300000000667010177742445014217 0ustar chrisludwig/* * $Id: snoop.c,v 1.2 2005/02/01 18:06:29 c4chris Exp $ */ #include "os.h" #ifdef USE_SNOOP /* * snoop.c - routines for snooping on network traffic via the SGI * provided snoop(7p) network monitoring protocol * -- works under IRIX 3.2.* and IRIX 3.3.[12] * * NOTE: must be "root" to use this * * Tim Hudson * Mincom Pty Ltd * Mincom Centre * Juliette Street * Greenslopes 4120 * Brisbane Australia * tjh@mincom.oz.au * */ #include #include #include #include #include #include #include #include #include #include #include #include #include "nfswatch.h" #include "externs.h" /* * setup_snoop_dev - set up the network interface tap. */ int setup_snoop_dev(device) char **device; { int n, s; int i, res; u_int chunksz; u_long if_flags; char buf[BUFSIZ]; struct ifconf ifc; struct snoopfilter sf; struct timeval timeout; struct ifreq ifr, *ifrp; struct sockaddr_raw sr, sn; /* * If the interface device was not specified, * get the default one. */ if (*device == NULL) { /* * Grab a socket. */ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { error("socket"); finish(-1); } ifc.ifc_buf = buf; ifc.ifc_len = sizeof(buf); /* * See what devices we've got. */ if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) { error("ioctl: SIOCGIFCONF"); finish(-1); } /* * Take the first device we encounter. */ ifrp = ifc.ifc_req; for (n = ifc.ifc_len/sizeof(struct ifreq); n > 0; n--,ifrp++) { /* * Skip the loopback interface. */ if (strcmp(ifrp->ifr_name, "lo0") == 0) continue; *device = strdup(ifrp->ifr_name); break; } (void) close(s); } /* * Make the raw socket. */ if ((s = socket(PF_RAW,SOCK_RAW,RAWPROTO_SNOOP)) < 0) { error("snoop: socket"); finish(-1); } /* * Set it up for the chosen interface. */ bzero((char *)&sr, sizeof(sr)); sr.sr_family = AF_RAW; sr.sr_port = 0; strncpy(sr.sr_ifname, *device, sizeof(sr.sr_ifname)); /* * If the bind fails, there's no such device. */ if (bind(s, &sr, sizeof(sr)) < 0) { close(s); return(-1); } /* * Set up NULL filter - this is not necessary ... */ bzero((char *)&sf, sizeof(sf)); if (ioctl(s, SIOCADDSNOOP, &sf) < 0) { error("snoop: add filter"); finish(-1); } /* * Beef up the socket buffer to minimise packet losses */ i = SNOOP_BUFFER_SIZE; if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&i, sizeof(i)) < 0) { error("snoop: set rcvbuf"); finish(-1); } return(s); } /* * flush_snoop - flush data from the snoop. */ void flush_snoop(fd) int fd; { int on = 1; int off = 0; /* * Off then on should do a flush methinks */ ioctl(fd, SIOCSNOOPING, &off); if (ioctl(fd, SIOCSNOOPING, &on) < 0) { error("snoop: snoop on"); finish(-1); } } /* * snoop_devtype - determine the type of device we're looking at. */ int snoop_devtype(device) char *device; { /* * This whole routine is a kludge. Ultrix does it the * right way; see pfilt.c. */ if (strncmp(device, "et", 2) == 0 || strncmp(device, "ec", 2) == 0 || strncmp(device, "fxp", 3) == 0 || strncmp(device, "enp", 3) == 0) return(DLT_EN10MB); if (strncmp(device, "ipg", 4) == 0) return(DLT_FDDI); fprintf(stderr, "Unknown device type: %s -- assuming ethernet.\n", device); return(DLT_EN10MB); } #endif /* USE_SNOOP */ nfswatch-4.99.11/screen.c0000644000551200011300000006576410542251642014337 0ustar chrisludwig/* * $Id: screen.c,v 1.10 2006/12/20 15:15:46 c4chris Exp $ */ #include "os.h" /* * screen.c - routines for updating the screen. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ #include #include #include #include #include #include #include #include #include #include #include "nfswatch.h" #include "externs.h" #include "screen.h" /* * Screen text items which are always displayed. */ static struct scrtxt scrtxts[] = { { SCR_HOST_X, SCR_HOST_Y, dsthost }, { SCR_ELAPS_X0, SCR_ELAPS_Y, "Elapsed time:" }, { SCR_ELAPS_X, SCR_ELAPS_Y, "00:00:00" }, { SCR_PKTINT_X0, SCR_PKTINT_Y, "Interval packets:" }, { SCR_PKTTOT_X0, SCR_PKTTOT_Y, "Total packets:" }, { SCR_PKTHDR_X, SCR_PKTHDR_Y, "int pct total" }, { SCR_PKTHDR_X+SCR_MIDDLE, SCR_PKTHDR_Y, "int pct total" }, { -1, -1, NULL } }; /* * Screen text items displayed when showing file systems * (showwhich == SHOWFILESYSTEM). */ static struct scrtxt fstxts[] = { { SCR_NFSHDR_X, SCR_NFSHDR_Y, "File Sys int pct total" }, { SCR_NFSHDR_X+SCR_MIDDLE, SCR_NFSHDR_Y, "File Sys int pct total" }, { -1, -1, NULL } }; /* * Screen text items displayed when showing individual files * (showwhich == SHOWINDVFILES). */ static struct scrtxt fitxts[] = { { SCR_NFSHDR_X, SCR_NFSHDR_Y, "File int pct total" }, { SCR_NFSHDR_X+SCR_MIDDLE, SCR_NFSHDR_Y, "File int pct total" }, { -1, -1, NULL } }; /* * Screen text items displayed when showing individual procedures * (showwhich == SHOWNFSPROCS). */ static struct scrtxt prtxts[] = { { 0, SCR_NFSHDR_Y, " Procedure int pct total completed avg(msec) std dev max resp"} , { -1, -1, NULL} }; /* * Screen text items displayed when showing individual clients * (showwhich == SHOWCLIENTS). */ static struct scrtxt cltxts[] = { { 0, SCR_NFSHDR_Y, "Client host int pct total" }, { SCR_MIDDLE, SCR_NFSHDR_Y, "Client host int pct total" }, { -1, -1, NULL} }; /* * Screen text items displayed when showing individual authenticators * (showwhich == SHOWAUTH). */ static struct scrtxt actxts[] = { { 0, SCR_NFSHDR_Y, "Authenticator int pct total" }, { SCR_MIDDLE, SCR_NFSHDR_Y, "Authenticator int pct total" }, { -1, -1, NULL } }; /* * Screen text items for help page (showwhich == SHOWHELP). */ #define SCR_HELPHDR_Y (SCR_NFSHDR_Y - 1) static struct scrtxt helptxts[] = { { 2, SCR_HELPHDR_Y+0, "^L\tRedraw screen" }, { 3, SCR_HELPHDR_Y+1, "a\tDisplay RPC authentication" }, { 3, SCR_HELPHDR_Y+2, "c\tDisplay NFS client hosts" }, { 3, SCR_HELPHDR_Y+3, "f\tDisplay file systems" }, { 3, SCR_HELPHDR_Y+4, "l\tToggle logging" }, { 3, SCR_HELPHDR_Y+5, "n\tToggle host numbers/names" }, { 3, SCR_HELPHDR_Y+6, "p\tDisplay NFS procedures" }, { 3, SCR_HELPHDR_Y+7, "P\tDisplay NFS3 procedures" }, { 3, SCR_HELPHDR_Y+8, "q\tQuit" }, { 3, SCR_HELPHDR_Y+9, "s\tWrite snapshot" }, { SCR_MIDDLE+3, SCR_HELPHDR_Y+0, "u\tToggle sort by %% usage" }, { SCR_MIDDLE+3, SCR_HELPHDR_Y+1, ">\tIncrease cycle time by one sec" }, { SCR_MIDDLE+3, SCR_HELPHDR_Y+2, "<\tDecrease cycle time by one sec" }, { SCR_MIDDLE+3, SCR_HELPHDR_Y+3, "+\tIncrease cycle time by 10 secs" }, { SCR_MIDDLE+3, SCR_HELPHDR_Y+4, "-\tDecrease cycle time by 10 secs" }, { SCR_MIDDLE+3, SCR_HELPHDR_Y+5, "=\tReset cycle time to 10 secs" }, { SCR_MIDDLE+3, SCR_HELPHDR_Y+6, "]\tScroll forward" }, { SCR_MIDDLE+3, SCR_HELPHDR_Y+7, "[\tScroll back" }, { SCR_MIDDLE, SCR_HELPHDR_Y+8, " \t*space bar resumes display*" }, { SCR_MIDDLE - 6, SCR_HELPHDR_Y+9, "--COMMANDS--" }, { -1, -1, NULL } }; static int showbyname = 1; /* show host names/numbers */ static int prev_showwhich = 0; /* used for resuming after help */ /* * scrolling offsets, one for each display type, in terms of displayed * items (i.e., lines skipped * 2) */ static int scroll_off[SHOW_MAXCODE+1]; /* * This array tells the scrolling mechanism how far a display can be scrolled; * NULL entries are not scrollable. */ static int maxnfsproc = MAXNFSPROC; static int maxnfs3proc = MAXNFS3PROC; static int *scroll_limit[SHOW_MAXCODE+1] = { NULL, &nfilecounters, &nnfscounters, &maxnfsproc, &maxnfs3proc, &nclientcounters, &nauthcounters, NULL }; static void HowMany(char *, int); /* * setup_screen - initialize the display screen. */ void setup_screen(char *device) { int len; char *tstr; char *ctime(); char buf[BUFSIZ]; struct timeval tv; register struct scrtxt *st; #ifdef ultrix struct winsize ws; /* * Get around the old version of curses Ultrix has. * -lcursesX would probably do this as well. */ if (ioctl(2, TIOCGWINSZ, &ws) >= 0) LINES = ws.ws_row; #endif /* * Initialize the screen. */ (void) initscr(); screen_inited = 1; /* * Turn echo off, cbreak on. */ (void) noecho(); #ifdef crmode (void) crmode(); #else (void) cbreak(); #endif /* * Clear the screen. */ (void) clear(); /* * Get the time of day. */ (void) gettimeofday(&tv, 0); tstr = ctime(&tv.tv_sec); (void) mvprintw(SCR_DATE_Y, SCR_DATE_X, "%.24s", tstr); /* * Now draw the various strings on the screen. */ for (st = scrtxts; st->s_text != NULL; st++) (void) mvprintw(st->s_y, st->s_x, "%s", st->s_text); if (allintf) (void) sprintf(buf, "Monitoring packets from all interfaces"); else (void) sprintf(buf, "Monitoring packets from interface %s", device); len = strlen(buf); (void) mvprintw(SCR_IF_Y, SCR_MIDDLE - (len/2), buf); (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X0, prompt); } /* * label_screen - put all packet counter labels on screen. */ void label_screen(void) { register int i; register struct scrtxt *st; register int soff = scroll_off[showwhich]; /* * Display packet counter labels. */ for (i = 0; i < PKT_NCOUNTERS; i++) { (void) mvprintw(pkt_counters[i].pc_namey, pkt_counters[i].pc_namex, "%.*s", SCR_PKTLEN, pkt_counters[i].pc_name); } /* * Clear NFS packet counter lines, since we may be * changing them. */ for (i = SCR_NFSHDR_Y; i < (LINES - 1); i++) { (void) move(i, 0); (void) clrtoeol(); } /* * Display the labels for the NFS packet counter lines. */ if (showwhich == SHOWFILESYSTEM) { for (st = fstxts; st->s_text != NULL; st++) (void) mvprintw(st->s_y, st->s_x, "%s", st->s_text); for (i = soff; (i < nnfscounters) && ((i - soff) < NFSLINES); i++) { (void) mvprintw(nfs_counters[i - soff].nc_namey, nfs_counters[i - soff].nc_namex, "%.*s", SCR_NFSLEN, nfs_counters[i].nc_name); } } else if (showwhich == SHOWNFSPROCS) { for (st = prtxts; st->s_text != NULL; st++) (void) mvprintw(st->s_y, st->s_x, "%s", st->s_text); for (i = soff; (i < MAXNFSPROC) && ((i - soff) < NFSPROCLINES); i++) { (void) mvprintw(prc_counters[NFSv2][i - soff].pr_namey, prc_counters[NFSv2][i - soff].pr_namex, "%.*s", SCR_NFSLEN, prc_counters[NFSv2][i].pr_name); } } else if (showwhich == SHOWNFS3PROCS) { for (st = prtxts; st->s_text != NULL; st++) (void) mvprintw(st->s_y, st->s_x, "%s", st->s_text); for (i = soff; (i < MAXNFS3PROC) && ((i - soff) < NFSPROCLINES); i++) { (void) mvprintw(prc_counters[NFSv3][i - soff].pr_namey, prc_counters[NFSv3][i - soff].pr_namex, "%.*s", SCR_NFSLEN, prc_counters[NFSv3][i].pr_name); } } else if (showwhich == SHOWCLIENTS) { for (st = cltxts; st->s_text != NULL; st++) (void) mvprintw(st->s_y, st->s_x, "%s", st->s_text); for (i = soff; (i < nclientcounters) && ((i - soff) < NFSLINES); i++) { if (showbyname) { (void) mvprintw(clnt_counters[i - soff].cl_namey, clnt_counters[i - soff].cl_namex, "%.*s", SCR_NFSLEN, clnt_counters[i].cl_name); } else { struct in_addr tmp; bcopy(&clnt_counters[i].cl_ipaddr, &tmp, sizeof(struct in_addr)); (void) mvprintw(clnt_counters[i - soff].cl_namey, clnt_counters[i - soff].cl_namex, "%.*s", SCR_NFSLEN, inet_ntoa(tmp)); } } } else if (showwhich == SHOWAUTH) { for (st = actxts; st->s_text != NULL; st++) (void) mvprintw(st->s_y, st->s_x, "%s", st->s_text); for (i = soff; (i < nauthcounters) && ((i - soff) < NFSLINES); i++) { (void) mvprintw(auth_counters[i - soff].ac_namey, auth_counters[i - soff].ac_namex, "%.*s", SCR_NFSLEN, auth_counters[i].ac_name); } } else if (showwhich == SHOWHELP) { /* We "stole" one line so we must clear it */ (void) move(SCR_HELPHDR_Y, 0); (void) clrtoeol(); for (st = helptxts; st->s_text != NULL; st++) (void) mvprintw(st->s_y, st->s_x, "%s", st->s_text); } else { for (st = fitxts; st->s_text != NULL; st++) (void) mvprintw(st->s_y, st->s_x, "%s", st->s_text); for (i = soff; (i < nfilecounters) && ((i - soff) < NFSLINES); i++) { (void) mvprintw(fil_counters[i - soff].fc_namey, fil_counters[i - soff].fc_namex, "%.*s", SCR_NFSLEN, fil_counters[i].fc_name); } } } /* * update_screen - update the screen with new information. */ void update_screen(void) { char *tstr; char *ctime(); float percent; struct timeval tv; register int i, nfstotal; register int soff = scroll_off[showwhich]; (void) gettimeofday(&tv, (struct timezone *) 0); (void) mvprintw(SCR_DATE_Y, SCR_DATE_X, "%.24s", ctime(&tv.tv_sec)); tv.tv_sec -= starttime.tv_sec; tstr = prtime(tv.tv_sec); /* * Print the headers. */ (void) mvprintw(SCR_ELAPS_Y, SCR_ELAPS_X, "%10s", tstr); (void) mvprintw(SCR_PKTINT_Y, SCR_PKTINT_X, "%10d (network) %10d (to host) %10d (dropped)", int_pkt_total, int_dst_pkt_total, int_pkt_drops); (void) mvprintw(SCR_PKTTOT_Y, SCR_PKTTOT_X, "%10d (network) %10d (to host) %10d (dropped)", pkt_total, dst_pkt_total, pkt_drops); /* * Print the packet counters. Percentage is calculated as * this interval counter over total packets this interval. */ for (i = 0; i < PKT_NCOUNTERS; i++) { if (int_dst_pkt_total) { percent = ((float) pkt_counters[i].pc_interval / (float) int_dst_pkt_total) * 100.0; } else { percent = 0.0; } (void) mvprintw(pkt_counters[i].pc_inty, pkt_counters[i].pc_intx, "%7d", pkt_counters[i].pc_interval); (void) mvprintw(pkt_counters[i].pc_pcty, pkt_counters[i].pc_pctx, "%3.0f%%", percent); (void) mvprintw(pkt_counters[i].pc_toty, pkt_counters[i].pc_totx, "%8d", pkt_counters[i].pc_total); } /* * Calculate the total number of NFS packets this * interval. */ nfstotal = pkt_counters[PKT_NFSWRITE].pc_interval + pkt_counters[PKT_NFSREAD].pc_interval + pkt_counters[PKT_NFS3WRITE].pc_interval + pkt_counters[PKT_NFS3READ].pc_interval; if (showwhich == SHOWFILESYSTEM) { /* * Print the NFS counters. Percentage is calculated as * packets this interval over total NFS packets this * interval. */ HowMany("file systems", nnfscounters); for (i = soff; (i < nnfscounters) && ((i - soff) < NFSLINES); i++) { if (nfstotal) { percent = ((float) nfs_counters[i].nc_interval / (float) nfstotal) * 100.0; } else { percent = 0.0; } (void) mvprintw(nfs_counters[i - soff].nc_inty, nfs_counters[i - soff].nc_intx, "%5d", nfs_counters[i].nc_interval); (void) mvprintw(nfs_counters[i - soff].nc_pcty, nfs_counters[i - soff].nc_pctx, "%3.0f%%", percent); (void) mvprintw(nfs_counters[i - soff].nc_toty, nfs_counters[i - soff].nc_totx, "%8d", nfs_counters[i].nc_total); } } else if (showwhich == SHOWNFSPROCS) { long count, tot_count; double dcount, sumsqr, sum; tot_count = 0; /* Sum up all over all the procedures */ for (i = 0; i < MAXNFSPROC; i++) { tot_count += prc_counters[NFSv2][i].pr_interval; } HowMany("NFS Procedures", MAXNFSPROC); for (i = soff; (i < MAXNFSPROC) && ((i - soff) < NFSPROCLINES); i++) { if (tot_count) percent = (((float) prc_counters[NFSv2][i].pr_interval) / ((float)tot_count)) * 100.0; else percent = 0.0; (void) mvprintw(prc_counters[NFSv2][i - soff].pr_inty, prc_counters[NFSv2][i - soff].pr_intx, "%5d", prc_counters[NFSv2][i].pr_interval); (void) mvprintw(prc_counters[NFSv2][i - soff].pr_pcty, prc_counters[NFSv2][i - soff].pr_pctx, "%3.0f%%", percent); (void) mvprintw(prc_counters[NFSv2][i - soff].pr_toty, prc_counters[NFSv2][i - soff].pr_totx, "%8d", prc_counters[NFSv2][i].pr_total); count = prc_counters[NFSv2][i].pr_complete; if (count != 0) { dcount = (double) count; sum = prc_counters[NFSv2][i].pr_response; sumsqr = prc_counters[NFSv2][i].pr_respsqr; (void) mvprintw(prc_counters[NFSv2][i - soff].pr_rmaxy, prc_counters[NFSv2][i - soff].pr_rmaxx, "%8.2f", prc_counters[NFSv2][i].pr_maxresp); (void) mvprintw(prc_counters[NFSv2][i - soff].pr_compy, prc_counters[NFSv2][i - soff].pr_compx, "%8d", count); (void) mvprintw(prc_counters[NFSv2][i - soff].pr_respy, prc_counters[NFSv2][i - soff].pr_respx, "%8.2f", sum / dcount); if (count > 1) { (void) mvprintw(prc_counters[NFSv2][i - soff].pr_rsqry, prc_counters[NFSv2][i - soff].pr_rsqrx, "%8.2f", sqrt((dcount * sumsqr - sum * sum) / (dcount * (dcount - 1.0)))); } } } } else if (showwhich == SHOWNFS3PROCS) { long count, tot_count; double dcount, sumsqr, sum; tot_count = 0; /* Sum up all over all the procedures */ for (i = 0; i < MAXNFS3PROC; i++) { tot_count += prc_counters[NFSv3][i].pr_interval; } HowMany("NFS Procedures", MAXNFS3PROC); for (i = soff; (i < MAXNFS3PROC) && ((i - soff) < NFSPROCLINES); i++) { if (tot_count) percent = (((float) prc_counters[NFSv3][i].pr_interval) / ((float)tot_count)) * 100.0; else percent = 0.0; (void) mvprintw(prc_counters[NFSv3][i - soff].pr_inty, prc_counters[NFSv3][i - soff].pr_intx, "%5d", prc_counters[NFSv3][i].pr_interval); (void) mvprintw(prc_counters[NFSv3][i - soff].pr_pcty, prc_counters[NFSv3][i - soff].pr_pctx, "%3.0f%%", percent); (void) mvprintw(prc_counters[NFSv3][i - soff].pr_toty, prc_counters[NFSv3][i - soff].pr_totx, "%8d", prc_counters[NFSv3][i].pr_total); count = prc_counters[NFSv3][i].pr_complete; if (count != 0) { dcount = (double) count; sum = prc_counters[NFSv3][i].pr_response; sumsqr = prc_counters[NFSv3][i].pr_respsqr; (void) mvprintw(prc_counters[NFSv3][i - soff].pr_rmaxy, prc_counters[NFSv3][i - soff].pr_rmaxx, "%8.2f", prc_counters[NFSv3][i].pr_maxresp); (void) mvprintw(prc_counters[NFSv3][i - soff].pr_compy, prc_counters[NFSv3][i - soff].pr_compx, "%8d", count); (void) mvprintw(prc_counters[NFSv3][i - soff].pr_respy, prc_counters[NFSv3][i - soff].pr_respx, "%8.2f", sum / dcount); if (count > 1) { (void) mvprintw(prc_counters[NFSv3][i - soff].pr_rsqry, prc_counters[NFSv3][i - soff].pr_rsqrx, "%8.2f", sqrt((dcount * sumsqr - sum * sum) / (dcount * (dcount - 1.0)))); } } } } else if (showwhich == SHOWCLIENTS) { long tot_count; tot_count = 0; /* Sum up all over all the clients */ for (i = 0; i < nclientcounters; i++) { tot_count += clnt_counters[i].cl_interval; } HowMany("client hosts", nclientcounters); for (i = soff; (i < nclientcounters) && ((i - soff) < NFSLINES); i++) { if (tot_count) percent = (((float) clnt_counters[i].cl_interval) / ((float)tot_count)) * 100.0; else percent = 0.0; (void) mvprintw(clnt_counters[i - soff].cl_inty, clnt_counters[i - soff].cl_intx, "%5d", clnt_counters[i].cl_interval); (void) mvprintw(clnt_counters[i - soff].cl_pcty, clnt_counters[i - soff].cl_pctx, "%3.0f%%", percent); (void) mvprintw(clnt_counters[i - soff].cl_toty, clnt_counters[i - soff].cl_totx, "%8d", clnt_counters[i].cl_total); } } else if (showwhich == SHOWAUTH) { long tot_count; tot_count = 0; /* * Sum up over all the authenticators. */ for (i=0; i < nauthcounters; i++) { tot_count += auth_counters[i].ac_interval; } HowMany("authenticators", nauthcounters); for (i = soff; (i < nauthcounters) && ((i - soff) < NFSLINES); i++) { if (tot_count) percent = (((float) auth_counters[i].ac_interval) / ((float) tot_count)) * 100.0; else percent = 0.0; (void) mvprintw(auth_counters[i - soff].ac_inty, auth_counters[i - soff].ac_intx, "%5d", auth_counters[i].ac_interval); (void) mvprintw(auth_counters[i - soff].ac_pcty, auth_counters[i - soff].ac_pctx, "%3.0f%%", percent); (void) mvprintw(auth_counters[i - soff].ac_toty, auth_counters[i - soff].ac_totx, "%8d", auth_counters[i].ac_total); } } else if (showwhich == SHOWHELP) { /* do nothing */ } else { /* * Print the file counters. Percentage is calculated as * packets this interval over total NFS packets this * interval. */ HowMany("files", nfilecounters); for (i = soff; (i < nfilecounters) && ((i - soff) < NFSLINES); i++) { if (nfstotal) { percent = ((float) fil_counters[i].fc_interval / (float) nfstotal) * 100.0; } else { percent = 0.0; } (void) mvprintw(fil_counters[i - soff].fc_inty, fil_counters[i - soff].fc_intx, "%5d", fil_counters[i].fc_interval); (void) mvprintw(fil_counters[i - soff].fc_pcty, fil_counters[i - soff].fc_pctx, "%3.0f%%", percent); (void) mvprintw(fil_counters[i - soff].fc_toty, fil_counters[i - soff].fc_totx, "%8d", fil_counters[i].fc_total); } } (void) move(SCR_PROMPT_Y, SCR_PROMPT_X); (void) clrtoeol(); (void) refresh(); } /* * HowMany - put up a label showing how many XXs known/not displayed */ static void HowMany(char *legend, int number) { static char message[80]; int mlen, nfslines; if (showwhich == SHOWNFSPROCS) nfslines = NFSPROCLINES; else nfslines = NFSLINES; if (number > nfslines) { sprintf(message, "%d %s [%d not displayed]", number, legend, number - nfslines); } else sprintf(message, "%d %s", number, legend); mlen = strlen(message); (void)move(SCR_NFSHDR_Y - 1, 0); (void)clrtoeol(); (void)mvprintw(SCR_NFSHDR_Y - 1, SCR_MIDDLE - (mlen/2), message); /* * Display scrolling information */ if (scroll_off[showwhich] > 0) (void)mvprintw(SCR_NFSHDR_Y - 1, 2, "<-more"); if (scroll_limit[showwhich]) { int slim = *scroll_limit[showwhich]; if ((scroll_off[showwhich] + nfslines) < slim) (void)mvprintw(SCR_NFSHDR_Y - 1, (SCR_MIDDLE * 2) - 8, "more->"); } } /* * command - process a command. */ void command(void) { register int c; struct itimerval itv; #if !defined(SVR4) && !defined(LINUX) int oldm; #endif int reset_prevshowwhich = 1; if ((c = getchar()) == EOF) finish(-1); c &= 0177; switch (c) { case '\014': /* redraw */ (void) clearok(curscr, TRUE); (void) refresh(); reset_prevshowwhich = 0; break; case 'a': /* show RPC authentication */ case 'A': showwhich = SHOWAUTH; (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "display RPC authenticators (starting next update)"); (void) clrtoeol(); (void) refresh(); /* * Change screen labels. */ label_screen(); break; case 'c': /* show NFS clients */ case 'C': showwhich = SHOWCLIENTS; (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "display NFS clients (starting next update)"); (void) clrtoeol(); (void) refresh(); /* * Change screen labels. */ label_screen(); break; case 'f': /* toggle what we show */ case 'F': switch (showwhich) { case SHOWFILESYSTEM: /* * Only do this if it makes sense. */ if (filelist == NULL) break; showwhich = SHOWINDVFILES; break; case SHOWINDVFILES: showwhich = SHOWFILESYSTEM; break; case SHOWNFSPROCS: case SHOWNFS3PROCS: case SHOWCLIENTS: case SHOWAUTH: case SHOWHELP: showwhich = SHOWFILESYSTEM; break; } (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "display %s (starting next update)", (showwhich == SHOWFILESYSTEM ? "file systems" : "individual files")); (void) clrtoeol(); (void) refresh(); /* * Change screen labels. */ label_screen(); break; case 'l': /* toggle logging */ case 'L': reset_prevshowwhich = 0; if (logging) { (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "logging turned off"); (void) fprintf(logfp, "#\n# endlog\n#\n"); (void) fclose(logfp); logging = 0; } else { if ((logfp = fopen(logfile, "a")) == NULL) { (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "could not open \"%s\"", logfile); } else { (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "logging to \"%s\"", logfile); (void) fprintf(logfp, "#\n# startlog\n#\n"); (void) fprintf(logfp, "# NFSwatch log file\n"); (void) fprintf(logfp, "# Packets from: %s\n", (srcflag ? srchost : "all hosts")); (void) fprintf(logfp, "# Packets to: %s\n#\n", dsthost); logging = 1; } } (void) clrtoeol(); (void) refresh(); break; case 'n': /* show numbers/names */ case 'N': showbyname = (!showbyname); (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "show host %s (starting next update)", showbyname ? "names" : "numbers"); (void) clrtoeol(); (void) refresh(); /* * Change screen labels. */ label_screen(); break; case 'p': /* show NFS procedures */ showwhich = SHOWNFSPROCS; (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "display NFS procedures (starting next update)"); (void) clrtoeol(); (void) refresh(); /* * Change screen labels. */ label_screen(); break; case 'P': showwhich = SHOWNFS3PROCS; (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "display NFS3 procedures (starting next update)"); (void) clrtoeol(); (void) refresh(); /* * Change screen labels. */ label_screen(); break; case 'q': /* quit */ case 'Q': (void) mvaddch(SCR_PROMPT_Y, SCR_PROMPT_X, c); (void) refresh(); finish(-1); break; case 's': /* snapshot */ case 'S': reset_prevshowwhich = 0; #if defined(SVR4) || defined(LINUX) sighold(SIGALRM); #else oldm = sigblock(sigmask(SIGALRM)); #endif /* no async redisplay while dumping */ snapshot(); #if defined(SVR4) || defined(LINUX) sigrelse(SIGALRM); #else (void) sigsetmask(oldm); /* permit async redisplay */ #endif break; case 'u': /* toggle sort method */ case 'U': reset_prevshowwhich = 0; sortbyusage = (!sortbyusage); (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "sort by %s (starting next update)", sortbyusage ? "percent usage" : "name"); (void) clrtoeol(); (void) refresh(); /* * Change the sort order now. */ #if defined(SVR4) || defined(LINUX) sighold(SIGALRM); #else oldm = sigblock(sigmask(SIGALRM)); #endif /* no redisplay while unstable */ sort_nfs_counters(); sort_prc_counters(); sort_clnt_counters(); sort_auth_counters(); #if defined(SVR4) || defined(LINUX) sigrelse(SIGALRM); #else (void) sigsetmask(oldm); /* permit redisplay */ #endif /* * Update screen labels and values. */ label_screen(); update_screen(); break; case '>': /* add 1 to cycle time */ reset_prevshowwhich = 0; cycletime++; (void) getitimer(ITIMER_REAL, &itv); itv.it_interval.tv_sec = cycletime; itv.it_interval.tv_usec = 0; (void) setitimer(ITIMER_REAL, &itv, (struct itimerval *) 0); (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "cycletime = %d seconds", cycletime); (void) clrtoeol(); (void) refresh(); break; case '<': /* subtract 1 from cycletime */ reset_prevshowwhich = 0; if (cycletime > 1) { cycletime--; (void) getitimer(ITIMER_REAL, &itv); itv.it_interval.tv_sec = cycletime; itv.it_interval.tv_usec = 0; (void) setitimer(ITIMER_REAL, &itv, (struct itimerval *) 0); (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "cycletime = %d seconds", cycletime); (void) clrtoeol(); (void) refresh(); } break; case '+': /* increase cycletime */ reset_prevshowwhich = 0; cycletime += CYCLETIME; (void) getitimer(ITIMER_REAL, &itv); itv.it_interval.tv_sec = cycletime; itv.it_interval.tv_usec = 0; (void) setitimer(ITIMER_REAL, &itv, (struct itimerval *) 0); (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "cycletime = %d seconds", cycletime); (void) clrtoeol(); (void) refresh(); break; case '-': /* decrease cycletime */ reset_prevshowwhich = 0; if (cycletime > CYCLETIME) { cycletime -= CYCLETIME; (void) getitimer(ITIMER_REAL, &itv); itv.it_interval.tv_sec = cycletime; itv.it_interval.tv_usec = 0; (void) setitimer(ITIMER_REAL, &itv, (struct itimerval *) 0); (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "cycletime = %d seconds", cycletime); (void) clrtoeol(); (void) refresh(); } break; case '=': /* reset cycletime */ reset_prevshowwhich = 0; cycletime = CYCLETIME; (void) getitimer(ITIMER_REAL, &itv); itv.it_interval.tv_sec = cycletime; itv.it_interval.tv_usec = 0; (void) setitimer(ITIMER_REAL, &itv, (struct itimerval *) 0); (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "cycletime reset to %d seconds", cycletime); (void) clrtoeol(); (void) refresh(); break; case ']': /* scroll forward */ reset_prevshowwhich = 0; { int slim; if (scroll_limit[showwhich] == NULL) break; slim = *(scroll_limit[showwhich]); if (showwhich == SHOWNFSPROCS || showwhich == SHOWNFS3PROCS) { if (slim <= NFSPROCLINES) break; scroll_off[showwhich] += NFSPROCLINES - 2; if (scroll_off[showwhich] > (slim - NFSPROCLINES)) { scroll_off[showwhich] = (slim - NFSPROCLINES); } } else { if (slim <= NFSLINES) break; scroll_off[showwhich] += NFSLINES - 2; if (scroll_off[showwhich] > (slim - NFSLINES)) { scroll_off[showwhich] = (slim - NFSLINES); } } } (void) clrtoeol(); label_screen(); update_screen(); (void) refresh(); break; case '[': /* scroll back */ reset_prevshowwhich = 0; if (showwhich == SHOWNFSPROCS || showwhich == SHOWNFS3PROCS) scroll_off[showwhich] -= NFSPROCLINES - 2; else scroll_off[showwhich] -= NFSLINES - 2; if (scroll_off[showwhich] < 0) scroll_off[showwhich] = 0; (void) clrtoeol(); label_screen(); update_screen(); (void) refresh(); break; case ' ': /* resume after help */ if (prev_showwhich > 0) { showwhich = prev_showwhich; label_screen(); update_screen(); (void) refresh(); break; } /* not set? drops through to "default" */ default: /* give them some help */ reset_prevshowwhich = 0; if (showwhich != SHOWHELP) /* save current display mode */ prev_showwhich = showwhich; showwhich = SHOWHELP; label_screen(); (void) refresh(); break; } if (reset_prevshowwhich) prev_showwhich = 0; } nfswatch-4.99.11/rpcdefs.h0000644000551200011300000001345510443765011014501 0ustar chrisludwig/* * $Id: rpcdefs.h,v 1.9 2006/06/14 10:50:49 c4chris Exp $ * * rpcdefs.h - definitions for RPC processing code. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ #define NFS_READ 0 #define NFS_WRITE 1 /* * RPC programs, from "Remote Procedure Call Programming Guide", * Revision A, 9 May 1988, pp. 64-65. */ #define RPC_PMAPPROG ((uint32_t) 100000) /* portmapper */ #define RPC_RSTATPROG ((uint32_t) 100001) /* remote stats */ #define RPC_RUSERSPROG ((uint32_t) 100002) /* remote users */ #define RPC_NFSPROG ((uint32_t) 100003) /* NFS */ #define RPC_YPPROG ((uint32_t) 100004) /* Yellow Pages */ #define RPC_MOUNTPROG ((uint32_t) 100005) /* mount daemon */ #define RPC_DBXPROG ((uint32_t) 100006) /* remote dbx */ #define RPC_YPBINDPROG ((uint32_t) 100007) /* yp binder */ #define RPC_WALLPROG ((uint32_t) 100008) /* shutdown msg */ #define RPC_YPPASSWDPROG ((uint32_t) 100009) /* yppasswd server */ #define RPC_ETHERSTATPROG ((uint32_t) 100010) /* ether stats */ #define RPC_RQUOTAPROG ((uint32_t) 100011) /* disk quotas */ #define RPC_SPRAYPROG ((uint32_t) 100012) /* spray packets */ #define RPC_IBM3270PROG ((uint32_t) 100013) /* 3270 mapper */ #define RPC_IBMRJEPROG ((uint32_t) 100014) /* RJE mapper */ #define RPC_SELNSVCPROG ((uint32_t) 100015) /* selection service */ #define RPC_RDATABASEPROG ((uint32_t) 100016) /* remote database access */ #define RPC_REXECPROG ((uint32_t) 100017) /* remote execution */ #define RPC_ALICEPROG ((uint32_t) 100018) /* Alice Office Automation */ #define RPC_SCHEDPROG ((uint32_t) 100019) /* scheduling service */ #define RPC_LOCKPROG ((uint32_t) 100020) /* local lock manager */ #define RPC_NETLOCKPROG ((uint32_t) 100021) /* network lock manager */ #define RPC_X25PROG ((uint32_t) 100022) /* X.25 inr protocol */ #define RPC_STATMON1PROG ((uint32_t) 100023) /* status monitor 1 */ #define RPC_STATMON2PROG ((uint32_t) 100024) /* status monitor 2 */ #define RPC_SELNLIBPROG ((uint32_t) 100025) /* selection library */ #define RPC_BOOTPARAMPROG ((uint32_t) 100026) /* boot parameters service */ #define RPC_MAZEPROG ((uint32_t) 100027) /* mazewars game */ #define RPC_YPUPDATEPROG ((uint32_t) 100028) /* yp update */ #define RPC_KEYSERVEPROG ((uint32_t) 100029) /* key server */ #define RPC_SECURECMDPROG ((uint32_t) 100030) /* secure login */ #define RPC_NETFWDIPROG ((uint32_t) 100031) /* NFS net forwarder init */ #define RPC_NETFWDTPROG ((uint32_t) 100032) /* NFS net forwarder trans */ #define RPC_SUNLINKMAP_PROG ((uint32_t) 100033) /* sunlink MAP */ #define RPC_NETMONPROG ((uint32_t) 100034) /* network monitor */ #define RPC_DBASEPROG ((uint32_t) 100035) /* lightweight database */ #define RPC_PWDAUTHPROG ((uint32_t) 100036) /* password authorization */ #define RPC_TFSPROG ((uint32_t) 100037) /* translucent file svc */ #define RPC_NSEPROG ((uint32_t) 100038) /* nse server */ #define RPC_NSE_ACTIVATE_PROG ((uint32_t) 100039) /* nse activate daemon */ #define RPC_NIS ((uint32_t) 100300) /* nis+ daemon */ #define RPC_CACHEPROG ((uint32_t) 100301) /* nis+ cache */ #define RPC_CB_PROG ((uint32_t) 100302) /* nis+ callback */ #define RPC_PCNFSDPROG ((uint32_t) 150001) /* pc passwd authorization */ #define RPC_PYRAMIDLOCKINGPROG ((uint32_t) 200000) /* Pyramid-locking */ #define RPC_PYRAMIDSYS5 ((uint32_t) 200001) /* Pyramid-sys5 */ #define RPC_CADDS_IMAGE ((uint32_t) 200002) /* CV cadds_image */ #define RPC_ADT_RFLOCKPROG ((uint32_t) 300001) /* ADT file locking */ #ifdef NFSSERVER /* * Classification of NFS procedures. */ struct nfs_proc { int nfs_proctype; xdrproc_t nfs_xdrargs; int nfs_argsz; }; /* * NFS procedure argument structures. */ union nfs_rfsargs { fhandle_t fhandle; struct nfssaargs nfssaargs; struct nfsdiropargs nfsdiropargs; struct nfsreadargs nfsreadargs; struct nfswriteargs nfswriteargs; struct nfscreatargs nfscreatargs; struct nfsrnmargs nfsrnmargs; struct nfslinkargs nfslinkargs; struct nfsslargs nfsslargs; struct nfsrddirargs nfsrddirargs; }; union nfs3_rfsargs { nfs_fh3 nfs_fh3_a; diropargs3 diropargs3_a; RENAME3args RENAME3args_a; LINK3args LINK3args_a; }; #if (defined(SUNOS5) && !defined(SUNOS58)) || defined(IRIX6) struct nfs2_timeval { uint32_t tv_sec; uint32_t tv_usec; }; #endif /* * Macros for use with RPC stuff. */ #define min(a, b) ((a) < (b) ? (a) : (b)) #define rpc_buffer(xprt) ((xprt)->xp_p1) #define su_data(xprt) ((struct svcudp_data *)((xprt)->xp_p2)) /* * UDP service data. */ struct svcudp_data { u_int su_iosz; /* byte size of send/recv buffer */ u_int su_xid; /* transaction id */ XDR su_xdrs; /* XDR handle */ char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */ }; #endif bool_t xdr_creatargs(XDR *, struct nfscreatargs *); bool_t xdr_diropargs(XDR *, struct nfsdiropargs *); bool_t xdr_fhandle(XDR *, fhandle_t *); bool_t xdr_linkargs(XDR *, struct nfslinkargs *); bool_t xdr_rddirargs(XDR *, struct nfsrddirargs *); bool_t xdr_readargs(XDR *, struct nfsreadargs *); bool_t xdr_rnmargs(XDR *, struct nfsrnmargs *); bool_t xdr_saargs(XDR *, struct nfssaargs *); bool_t xdr_sattr(XDR *, struct nfssattr *); bool_t xdr_slargs(XDR *, struct nfsslargs *); bool_t xdr_nfs2_timeval(XDR *, struct nfs2_timeval *); bool_t xdr_writeargs(XDR *, struct nfswriteargs *); /* NFS3 stuff. */ bool_t xdr_nfs_fh3(XDR *, nfs_fh3 *); bool_t xdr_diropargs3(XDR *, diropargs3 *); bool_t xdr_RENAME3args(XDR *, RENAME3args *); bool_t xdr_LINK3args(XDR *, LINK3args *); nfswatch-4.99.11/LICENSE0000644000551200011300000000155110201437433013675 0ustar chrisludwigLicense: BSD Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. nfswatch-4.99.11/nfsfh.h0000644000551200011300000000145210177742445014163 0ustar chrisludwig/* * $Id: nfsfh.h,v 1.2 2005/02/01 18:06:29 c4chris Exp $ * * nfsfh.h - NFS file handle definitions (for portable use) * * Jeffrey C. Mogul * Digital Equipment Corporation * Western Research Laboratory * */ /* * Internal representation of dev_t, because different NFS servers * that we might be spying upon use different external representations. */ typedef struct { u_long Minor; /* upper case to avoid clashing with macro names */ u_long Major; } my_devt; #define dev_eq(a,b) ((a.Minor == b.Minor) && (a.Major == b.Major)) /* * Many file servers now use a large file system ID. This is * our internal representation of that. */ typedef struct { my_devt fsid_dev; u_long fsid_code; } my_fsid; #define fsid_eq(a,b) ((a.fsid_code == b.fsid_code) &&\ dev_eq(a.fsid_dev, b.fsid_dev)) nfswatch-4.99.11/os.h0000644000551200011300000000255710340375652013501 0ustar chrisludwig/* * $Id: os.h,v 1.4 2005/11/21 16:54:02 c4chris Exp $ * * os.h - operating system definitions. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ #ifdef LINUX #ifndef USE_LINUX #define USE_LINUX 1 #endif #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif #endif #ifdef IRIX40 #ifndef USE_SNOOP #define USE_SNOOP 1 #endif #define signal sigset #define U_INT32_DECLARED_IN_AUTH 1 #endif #ifdef SUNOS4 #ifndef USE_NIT #define USE_NIT 1 #endif #define U_INT32_DECLARED_IN_AUTH 1 #endif #ifdef SUNOS5 #ifndef SVR4 #define SVR4 1 #endif #ifndef USE_DLPI #define USE_DLPI 1 #endif #define U_INT32_DECLARED_IN_AUTH 1 #endif #if defined(SUNOS55) || defined(SUNOS58) #ifndef SUNOS54 #define SUNOS54 1 #endif #undef U_INT32_DECLARED_IN_AUTH #endif #ifdef SVR4 #ifndef USE_DLPI #define USE_DLPI 1 #endif #define index strchr #define rindex strrchr #define signal sigset #define bzero(b,n) memset(b,0,n) #define bcmp(a,b,n) memcmp(a,b,n) #define bcopy(a,b,n) memcpy(b,a,n) #endif #ifdef ULTRIX #ifndef USE_PFILT #define USE_PFILT 1 #endif #endif #ifdef DECOSF #ifndef USE_PFILT #define USE_PFILT 1 #endif #endif nfswatch-4.99.11/netaddr.c0000644000551200011300000001570011171404624014461 0ustar chrisludwig/* * $Id: netaddr.c,v 1.6 2009/04/15 16:21:40 c4chris Exp $ */ #include "os.h" /* * netaddr.c - routines for working with network addresses. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ /* * TODO: * - replace the gethostbyname() functions with getaddrinfo() * - look at this broken strict aliasing warning: * In function 'setup_ouraddrs': * netaddr.c:338: warning: * dereferencing pointer 'sin' does break strict-aliasing rules * netaddr.c:322: note: initialized from here */ #include #include #include #include #include #include #ifdef SUNOS5 #include #endif /* SUNOS5 */ #include #include #include #include "nfswatch.h" #include "externs.h" #define MAXOURADDRS 32 ipaddrt ouraddrs[MAXOURADDRS]; static void setup_ouraddrs(void); /* * get_net_addrs - get network addresses of source and destination * hosts, along with official host names. */ void get_net_addrs(void) { register int n, i; register char **cp; struct hostent *hp; /* * Look up the local host. */ if ((hp = gethostbyname(myhost)) == NULL) { (void) fprintf(stderr, "%s: %s: unknown host.\n", pname, myhost); finish(-1); } setup_ouraddrs(); /* * Save the official host name. */ (void) strcpy(myhost, hp->h_name); /* * If one was specified, look up the destination host. * Otherwise, we can use what we have. */ if (allflag) { (void) sprintf(dsthost, "all hosts"); } else if (dstflag) { if ((hp = gethostbyname(dsthost)) == NULL) { (void) fprintf(stderr, "%s: %s: unknown host.\n", pname, dsthost); finish(-1); } /* * Save the official host name. */ (void) strcpy(dsthost, hp->h_name); } else { /* * Host name is the same as the local * host. */ (void) strcpy(dsthost, myhost); } /* Setup the dst addrs we are interested in. */ n = 0; memset(dstaddrs, 0, MAXHOSTADDR * sizeof(ipaddrt)); /* Add ouraddrs. */ for (i=0; (ouraddrs[i] != 0) && (i < MAXOURADDRS); i++) { dstaddrs[n++] = ouraddrs[i]; } /* * Copy destination host's network addresses. */ for (cp = hp->h_addr_list; *cp != NULL; cp++) { if (n >= MAXHOSTADDR) break; memcpy(&dstaddrs[n], *cp, hp->h_length); n++; } /* * If they specified a server host, get its addresses. */ if (serverflag) { if ((hp = gethostbyname(serverhost)) == NULL) { fprintf(stderr, "%s: %s: unknown host.\n", pname, serverhost); finish(-1); } /* * Save the official host name. */ (void) strcpy(serverhost, hp->h_name); /* * Copy the server's network addresses. */ n = 0; memset(serveraddrs, 0, MAXHOSTADDR * sizeof(ipaddrt)); for (cp = hp->h_addr_list; *cp != NULL; cp++) { if (n >= MAXHOSTADDR) break; memcpy(&serveraddrs[n], *cp, hp->h_length); n++; } } /* * If they didn't specify a source host, * we're done. */ if (!srcflag) return; /* * Look up the source host. */ if ((hp = gethostbyname(srchost)) == NULL) { (void) fprintf(stderr, "%s: %s: unknown host.\n", pname, srchost); finish(-1); } /* * Save the official host name. */ (void) strcpy(srchost, hp->h_name); /* * Copy source host's network addresses. */ n = 0; memset(srcaddrs, 0, MAXHOSTADDR * sizeof(ipaddrt)); for (cp = hp->h_addr_list; *cp != NULL; cp++) { if (n >= MAXHOSTADDR) break; memcpy(&srcaddrs[n], *cp, hp->h_length); n++; } } /* * want_packet - determine if we're interested in a packet by examining * its source and destination addresses. */ int want_packet(ipaddrt src, ipaddrt dst) { register int i, want; want = FALSE; thisdst = dst; /* * Check that the source or destination is the server. */ if (serverflag) { for (i=0; (serveraddrs[i] != 0) && (i < MAXHOSTADDR); i++) { if (!bcmp((char *) &src, (char *) &serveraddrs[i], sizeof(ipaddrt)) || !bcmp((char *) &dst, (char *) &serveraddrs[i], sizeof(ipaddrt))) { want = TRUE; break; } } return(want); } /* * Any source or destination is okay. */ if (allflag) { return(TRUE); } /* * Check source address first. */ if (srcflag) { for (i = 0; (srcaddrs[i] != 0) && (i < MAXHOSTADDR); i++) { if (!bcmp((char *) &src, (char *) &srcaddrs[i], sizeof(ipaddrt))) { want = TRUE; break; } } /* * If it's not from our source, we * don't even need to check the destination. */ if (!want) return(FALSE); } want = FALSE; /* * Check destination address. */ for (i = 0; (dstaddrs[i] != 0) && (i < MAXHOSTADDR); i++) { if (!bcmp((char *) &dst, (char *) &dstaddrs[i], sizeof(ipaddrt))) { want = TRUE; break; } } return(want); } /* * to_self - determine if packet destination is the local host */ int to_self(ipaddrt dst) { register int i; /* * Check if the destination is one of our addresses */ for (i=0; (ouraddrs[i] != 0) && (i < MAXOURADDRS); i++) { if (ouraddrs[i] == dst) { return(1); } } return(0); } /* Not all systems have IFF_LOOPBACK */ #ifdef IFF_LOOPBACK #define ISLOOPBACK(p) ((p)->ifr_flags & IFF_LOOPBACK) #else #define ISLOOPBACK(p) (strcmp((p)->ifr_name, "lo0") == 0) #endif /* * Make a list of our possible IP addresses * A lot of the code in setup_ouraddrs() was borrowed from tcpdump/ */ static void setup_ouraddrs(void) { struct ifreq ibuf[MAXOURADDRS], *ifrp, *ifend; struct ifconf ifc; int n; int fd; n = 0; memset(ouraddrs, 0, MAXOURADDRS * sizeof(ipaddrt)); fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { perror("socket"); finish(-1); } ifc.ifc_len = sizeof ibuf; ifc.ifc_buf = (caddr_t)ibuf; if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 || (unsigned int) ifc.ifc_len < sizeof(struct ifreq)) { perror("SIOCGIFCONF"); finish(-1); } ifrp = ibuf; ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len); while (ifrp < ifend) { struct ifreq ifr; struct sockaddr_in *sin = (struct sockaddr_in *)&ifrp->ifr_addr; /* * Need a temporary to preserve address info that is * used below to locate the next entry. (Otherwise, * SIOCGIFFLAGS stomps over it because the requests * are returned in a union.) */ memcpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { (void)fprintf(stderr, "SIOCGIFFLAGS: "); perror(ifrp->ifr_name); finish(-1); } if ((ifr.ifr_flags & IFF_UP) && !ISLOOPBACK(&ifr)) { if (n >= MAXOURADDRS) break; ouraddrs[n] = sin->sin_addr.s_addr; n++; } #if BSD >= 199006 n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name); if (n < sizeof(*ifrp)) ++ifrp; else ifrp = (struct ifreq *)((char *)ifrp + n); #else ++ifrp; #endif } close(fd); } nfswatch-4.99.11/nfswatch.80000644000551200011300000004540010207640273014603 0ustar chrisludwig.ig .\" $Id: nfswatch.8,v 1.3 2005/02/25 15:14:03 c4chris Exp $ .. .ds @N \s-1NFS\s0 .ds @n \s-1NFS v3\s0 .ds @R \s-1RPC\s0 .TH NFSWATCH 8 "25 February 2005" Lausanne/LICR .SH NAME nfswatch \- monitor an \*(@N server .SH SYNOPSIS .B nfswatch [ .B \-dst .I dsthost ] [ .B \-src .I srchost ] [ .B \-server .I serverhost ] [ .B \-all ] [ .B \-dev .I device ] [ .B \-allif ] [ .B \-f .I filelist ] [ .B \-lf .I logfile ] [ .B \-sf .I snapfile ] [ .B \-map .I mapfile ] [ .B \-T .I maxtime ] [ .B \-t .I timeout ] [ .B \-fs ] [ .B \-if ] [ .B \-auth ] [ .B \-procs ] [ .B \-procs3 ] [ .B \-clients ] [ .B \-usage ] [ .B \-l ] [ .B \-bg ] .SH DESCRIPTION .PP .I nfswatch monitors all incoming network traffic to an \*(@N file server and divides it into several categories. The number and percentage of packets received in each category is displayed on the screen in a continuously updated display. The screen is updated every ten seconds by default; this time period is called an .IR interval . .PP .BR "On Irix" : You must be the super-user to invoke .I nfswatch or it must be installed setuid to ``root.'' .BR "On SunOS 4.x and SunOS 5.x (Solaris 2.x)" : You must be the super-user to invoke .I nfswatch or it must be installed setuid to ``root.'' .BR "On System V Release 4" : You must be the super-user to invoke .I nfswatch or it must be installed setuid to ``root.'' .BR "On Ultrix or DEC OSF/1" : Any user can invoke .I nfswatch once the super-user has enabled promiscuous-mode operation using .IR pfconfig (8). (For example, "pfconfig +p +c \-a".) .BR "On Linux" : You must be the super-user to invoke .I nfswatch or it must be installed setuid to ``root.'' .PP By default, .I nfswatch monitors all packets destined for the current host. An alternate destination host to watch for may be specified using the .B \-dst argument. If a source host is specified with the .B \-src argument, then only packets arriving at the destination host which were sent by the source host are monitored. Traffic between a specific server and its clients may be watched by specifying the name of the server with the .B \-server argument. If the .B \-all argument is given, then all \*(@N traffic on the network is monitored. It is usually desirable to specify the .B \-all option whenever using the .B \-server option. .PP The .I nfswatch screen is divided into three parts. The first part, at the top of the screen, is made up of three lines. The first line displays the name of the host being monitored, the current date and time, and the time elapsed since the start of monitoring. The second line displays the total number of packets received during the most recent interval, and the third line displays the total number of packets received since monitoring started. These two lines display three numbers each: the total number of packets on the network, the total number of packets received by the destination host (possibly subject to being only from the specified source host), and the number of packets dropped by the monitoring interface due to buffer space limitations. Dropped packets are not included in the packet monitoring totals. .PP The second part of the screen divides the received packets into 16 categories. Each category is displayed with three numbers: the number of packets received this interval, the percentage this represents of all packets received by the host during this interval, and the total number of packets received since monitoring started. The packet categories are not mutually exclusive; some packets may be counted in more than one category (for example, \*(@N packets are also \s-1UDP\s0 packets). The categories in this section and their meanings are: .IP "\*(@N3 Read" \*(@n requests which primarily result in a file system read being performed (read file, read directory, etc.). .IP "\*(@N3 Write" \*(@n requests which primarily result in a file system write being performed (write file, rename file, create file, delete file, etc.). .IP "\*(@N Read" \*(@N requests which primarily result in a file system read being performed (read file, read directory, etc.). .IP "\*(@N Write" \*(@N requests which primarily result in a file system write being performed (write file, rename file, create file, delete file, etc.). .IP "\*(@N Mount" \*(@N mount requests. .IP "YP/NIS/NIS+" Sun NIS (Yellow Pages) and NIS+ requests. .IP "\*(@R Authorization" All \*(@R reply packets fall into this category, because \*(@R replies do not contain the protocol number, and thus cannot be classified as anything else. (If the .B \-all argument is given, then you will see all the \*(@R replies on the network in this category.) .IP "Other \*(@R Packets" All \*(@R requests which do not fall into one of the above categories. .IP "\s-1TCP\s0 Packets" Packets sent using the Transmission Control Protocol. .IP "\s-1UDP\s0 Packets" Packets sent using the User Datagram Protocol. .IP "\s-1ICMP\s0 Packets" Packets sent using the Internet Control Message Protocol. .IP "Routing Control" Routing Information Protocol (\s-1RIP\s0) packets. .IP "Address Resolution" Address Resolution Protocol (\s-1ARP\s0) packets. These packets are not counted on System V Release 4 systems (except for SunOS 5.x), due to limitations of the .IR dlpi (7) interface. .IP "Reverse Addr Resol" Reverse Address Resolution Protocol (\s-1RARP\s0) packets. These packets are not counted on System V Release 4 systems (except for SunOS 5.x), due to limitations of the .IR dlpi (7) interface. .IP "Ethernet/FDDI Bdcst" Ethernet (or FDDI) broadcast packets. These packets are destined for and received by all hosts on the local network. These packets are not counted on System V Release 4 systems (except for SunOS 5.x), due to limitations of the .IR dlpi (7) interface. .IP "Other Packets" A catch-all for any packets not counted in any of the above categories. .PP The third part of the display shows the mounted file systems exported by the file server for mounting through \*(@N. If .I nfswatch is monitoring the same host it is being run on, these file systems are listed by path name. Otherwise, the program attempts to decode the server's major and minor device numbers for the file system, and displays them in parentheses. (If the .B \-all argument is given, the name of the server is also shown.) With each file system, three numbers are displayed: the number of \*(@N requests for this file system received during the interval, the percentage this represents of all \*(@N requests received by the host, and the total number of \*(@N requests for this file system received since monitoring started. Up to 1024 file systems will be monitored by .I nfswatch and recorded in the log file, but only as many as will fit (2 * (\s-1LINES\s0 \- 16)) will be displayed on the screen. .PP If the .B \-map .I mapfile option is specified, .I nfswatch will read pairs of file system device specifications (as described above) and the proper names of the file systems from .IR mapfile . Each line should contain a string representing what .I nfswatch would normally print, and then separated from that by whitespace, the name that is preferred. For example, .LP .ce myhost(7,24)\ \ \ \ \ /homedirs .PP If the .B \-f .I filelist option is specified, a list of file names (one per line) is read from .IR filelist , and the traffic to these individual files is also monitored. The files must reside in file systems exported by the file server. When this option is specified, the third section of the screen will display counters for these files, instead of for the mounted file systems. Up to 1024 individual files will be monitored by .I nfswatch and recorded in the log file, but only as many as will fit (2 * (\s-1LINES\s0 \- 16)) will be displayed on the screen. .PP If the .B \-procs or .B \-procs3 option is specified, then instead of showing per-file or per-file system statistics, .I nfswatch shows the frequency of each \*(@N procedure (RPC call) (or as many as will fit on the screen). For each procedure, some timing statistics are also displayed; these include the number of completed operations (request and response seen) during the interval, the average response time during the interval (in milliseconds), the standard deviation from the average during the interval, and the maximum response time over all time. .PP If the .B \-clients option is specified, then instead of showing per-file or per-file system statistics, .I nfswatch shows the operation rate of each \*(@N client of the specified server(s) (or as many as will fit on the screen). .PP It should be noted here that only \*(@N .IR requests , made by client machines, are counted in the \*(@N packet monitoring area. The \*(@N traffic generated .I "by the server" in response to these requests is not counted. .PP If the .B \-auth option is specified, then the display will show packet counts divided up by user name (or user id, if the login name is not in the local password file). This information is decoded from the AUTH_UNIX authentication part of each RPC packet. .I nfswatch only decodes AUTH_UNIX authenticators, the other types of authentication (e.g., AUTH_DES) are lumped into a single bucket for each authentication type. .SH LOGFILE .PP When logging is on, .I nfswatch writes one entry to the log file each interval. The information printed to the log file is easily readable, and basically contains a copy of all information on the screen. Additionally, any \*(@N traffic to file systems or individual files which was not printed on the screen (due to space limitations) is printed in the log file. Finally, in the log file, the \*(@N traffic to file systems and individual files is further broken down into counts of how many times each specific \*(@N procedure was called. .PP The information in the .I nfswatch log file can be summarized easily using the .IR nfslogsum (8L) program. .SH COMMANDS .PP .I nfswatch also allows several commands to be entered at its prompt during execution. The prompt is displayed on the last line of the screen. For most commands, feedback describing the effect of the command is printed on the same line as the prompt. The commands are: .IP \fB^L\fP Clear and redraw the screen. .IP \fBa\fP Switches the display to show statistics on individual users. .IP \fBc\fP Switches the display to show statistics on \*(@N client hosts instead of per-file or per-filesystem information. .IP \fBf\fP Toggle the display of mounted file systems and the display of individual files in the \*(@N packet monitoring area. This command is only meaningful if the .B \-f .I filelist option was specified on the command line. (If the display is showing \*(@N procedures or clients, then this command switches the display to show file systems.) .IP \fBp\fP Switches the display to show statistics on \*(@N procedures instead of per-file or per-filesystem information. .IP \fBP\fP Switches the display to show statistics on \*(@n procedures instead of per-file or per-filesystem information. .IP \fBl\fP Toggle the logging feature. If logging is off it is (re)started; if logging is on, it is turned off. .IP \fBn\fP Toggle display of host names or host numbers in client mode. By default, client mode displays host names. However, this may not be sufficient for determining the names of unknown remote hosts, since domain names are not displayed. This command tells .I nfswatch to display host numbers instead, enabling each host to be uniquely identified. .IP \fBs\fP Take a ``snapshot'' of the current screen and save it to a file. This is useful to record occasional copies of the data when the logfile is not needed. .IP \fBu\fP Toggle the sort key for the display of mounted file systems in the \*(@N packet monitoring area. By default, these are sorted by file system name, but they can also be sorted in declining order of percent usage. .IP \fB\-\fP Decrease the cycle time (interval length) by ten seconds. This will take effect after the next screen update. .IP \fB+\fP Increase the cycle time (interval length) by ten seconds. This will take effect after the next screen update. .IP \fB<\fP Decrease the cycle time (interval length) by one second. This will take effect after the next screen update. .IP \fB>\fP Increase the cycle time (interval length) by one second. This will take effect after the next screen update. .IP \fB]\fP Scroll forward through the bottom part of the display, if there are files/file systems/clients/procedures not being displayed due to lack of space. .IP \fB[\fP Scroll back. .IP \fBq\fP Exit .IR nfswatch . Using the interrupt key will also cause .I nfswatch to exit. .PP Typing any other character will cause a help screen to be displayed. .SH OPTIONS .PP .I nfswatch can usually be run without arguments and will obtain useful results. However, for those occasions when the defaults are not good enough, the following options are provided: .IP "\fB\-dst\fP \fIdsthost\fP" Monitor packets destined for .I dsthost instead of the local host. .IP "\fB\-src\fP \fIsrchost\fP" Restrict packets being counted to those sent by .IR srchost . .IP "\fB\-server\fP \fIserverhost\fP" Restrict packets being counted to those sent to or from .IR serverhost . .IP "\fB\-all\fP" Monitor packets to and from all \*(@N servers on the local network. .IP "\fB\-dev\fP \fIdevice\fP" .BR "On non-DEC systems" : Use network interface device .I device to read packets from. By default, .I nfswatch will use the system's default network device for an Internet datagram. .BR "On Ultrix or DEC OSF/1" : .I device specifies the packet filter interface from which to read packets. You can specify interfaces either by their actual names (such as .IR ln0 ) or by their generic packet filter interface names .RI ( pfN, for .I N a small integer). By default, .I pf0 (the first configured interface that supports the packet filter) is used. .IP "\fB\-allif\fP" Read packets from all configured network interfaces, instead of a single device. .BR "On Irix" : The first five (0-4) of each of the following devices are checked: .IR ec , .IR et , .IR fxp , .IR enp , and .IR epg . If configured, they will be monitored. .BR "On SunOS" : The first five .I le (0-4) devices, the first five .I ie (0-4) devices, and the first five .I fddi (0-4) devices are checked, and if configured, will be monitored. .BR "On System V Release 4" : The first five .I emd (0-4) devices are checked, and if configured, will be monitored. .BR "On Ultrix and DEC OSF/1" : The first ten .I pf devices (0-9) are checked, and if configured, will be monitored. .IP "\fB\-f\fP \fIfilelist\fP" Read a list of file names (one per line) from .I filelist and monitor the \*(@N traffic to these files in addition to the normal monitoring of exported file systems. .IP "\fB\-lf\fP \fIlogfile\fP" When logging, write information to the file .IR logfile . The default is .IR nfswatch.log . .IP "\fB\-sf\fP \fIsnapfile\fP" Write snapshots to the file .IR snapfile . The default is .IR nfswatch.snap . .IP "\fB\-map\fP \fImapfile\fP" Read a list of device names and file system names (one pair per line) from .I mapfile and translate from one to the other when displaying file system names. .IP "\fB\-T\fP \fImaxtime\fP" Terminate execution after running for .I maxtime seconds. This is primarily for use with the .B \-bg option. .IP "\fB\-t\fP \fItimeout\fP" Set the cycle time (interval length) to .I timeout seconds. The default is 10. The cycle time may also be adjusted from the command prompt. .IP "\fB\-fs\fP" Display the file system \*(@N monitoring data instead of the individual file data. This option is only meaningful if the .B \-f .I filelist option was specified. The display may also be controlled from the command prompt. .IP "\fB\-if\fP" Display the individual file \*(@N monitoring data instead of the file system data. This option is only meaningful if the .B \-f .I filelist option was specified. The display may also be controlled from the command prompt. .IP "\fB\-auth\fP" Display statistics on authentication packets (individual users). .IP "\fB\-procs\fP" Display statistics on \*(@N procedures (RPC calls) instead of per-file or per-filesystem data. .IP "\fB\-procs3\fP" Display statistics on \*(@n procedures (RPC calls) instead of per-file or per-filesystem data. .IP "\fB\-client\fP" Display statistics on \*(@N client operation rates instead of per-file or per-filesystem data. .IP "\fB\-usage\fP" Set file system, procedure, or client display to be sorted in declining order of percent usage. By default, the display is sorted alphabetically. This may also be toggled from the command prompt. .IP "\fB\-l\fP Turn logging on at startup time. Logging is turned off by default, but may be enabled from the command prompt. .IP "\fB\-bg\fP" Start as a daemon, running in the background. No screen updates will be performed; all data will be written to the log file only. When started with this option, .I nfswatch will print the process id of the daemon process. To terminate .IR nfswatch , send the process a SIGTERM signal, or use the .B \-T option to set the maximum execution time. .SH BUGS .PP To monitor \*(@N traffic to files and file systems, .I nfswatch must extract information from the \*(@N file handle. The file handle is a server-specific item, and its contents vary from vendor to vendor and operating system to operating system. Unfortunately, there is no server-independent way to extract information from a file handle. .I nfswatch uses a set of heuristics to parse the file handle format used by many popular NFS servers, but in some cases there is no way to disambiguate the file handle format, and the program may get the wrong answer. It should, however, get the right answer for file handles generated by the host it is running on. .PP .I nfswatch uses the Snoop (\fIsnoop\fP(7)) network monitoring protocol under Irix 4.\fIx\fP, the Network Interface Tap (\fInit\fP(4)) under SunOS 4.\fIx\fP, the Data Link Provider Interface (\fIdlpi\fP(7)) under SunOS 5.\fIx\fP (Solaris 2.\fIx\fP) and System V Release 4, the Packet Filter {(\fIpacketfilter\fP(4)) under Ultrix (4.0 or later); (\fIpacketfilter\fP(7)) under DEC OSF/1 (V1.3 or later)}, and the packet interface (\fIpacket\fP(7)) under Linux. To run on other systems, code will have to be written to read packets from the network in promiscuous mode. .PP On Ultrix systems, FDDI is only supported under appropriately patched versions of Ultrix 4.2 (the kernel modules net_common.o and pfilt.o must be replaced; contact your Customer Support Center). Native FDDI support is standard in Ultrix 4.3 and later systems. .SH SEE ALSO .IR etherfind (8c), .IR dlpi (7), .IR nit (4), .IR nfslogsum (8L), .IR packetfilter (4/7), .IR snoop (1m), .IR snoop (7), .IR packet (7) .SH AUTHORS David A. Curry .br Purdue University .br Engineering Computer Network .br 1285 Electrical Engineering Building .br West Lafayette, \s-1IN\s0 47907-1285 .br davy@ecn.purdue.edu .PP Jeffrey C. Mogul .br Digital Equipment Corporation .br Western Research Laboratory .br 250 University Avenue .br Palo Alto, \s-1CA\s0 94301 .br mogul@wrl.dec.com .PP Christian Iseli .br Ludwig Institute for Cancer Research .br UNIL - BEP .br Lausanne, \s-1CH\s0-1015 .br Christian.Iseli@licr.org nfswatch-4.99.11/pfilt.c0000644000551200011300000000550210177742445014170 0ustar chrisludwig/* * $Id: pfilt.c,v 1.2 2005/02/01 18:06:29 c4chris Exp $ */ #include "os.h" #ifdef USE_PFILT /* * pfilt.c - routines for messing with the packet filter * * Jeffrey Mogul * DECWRL * */ #include #include #include #include #include #include #include #include #include #include "nfswatch.h" #include "externs.h" static struct ifreq ifr; /* holds interface name */ /* * setup_pfilt_dev - set up the packet filter */ int setup_pfilt_dev(device) char **device; { int fd; struct timeval timeout; short enmode; short backlog = -1; /* request the most */ struct enfilter Filter; /* * Open the packetfilter. If it fails, we're out of * devices. */ if ((fd = pfopen(*device, 0)) < 0) { return(-1); } /* * We want the ethernet in promiscuous mode */ enmode = ENBATCH|ENTSTAMP|ENNONEXCL|ENPROMISC; if (ioctl(fd, EIOCMBIS, &enmode) < 0) { error("ioctl: EIOCMBIS"); finish(-1); } #ifdef ENCOPYALL /* * Attempt to set "copyall" mode (see our own packets). * Okay if this fails. */ enmode = ENCOPYALL; (void) ioctl(fd, EIOCMBIS, &enmode); #endif /* * Set the read timeout. */ timeout.tv_sec = 1; timeout.tv_usec = 0; if (ioctl(fd, EIOCSRTIMEOUT, &timeout) < 0) { error("ioctl: EIOCSRTIMEOUT"); finish(-1); } /* set the backlog */ if (ioctl(fd, EIOCSETW, &backlog) < 0) { error("ioctl: EIOCSETW"); finish(-1); } /* set the truncation */ if (ioctl(fd, EIOCTRUNCATE, &truncation) < 0) { error("ioctl: EIOCTRUNCATE"); finish(-1); } /* find out the actual device name */ if (*device == NULL) { if (ioctl(fd, EIOCIFNAME, &ifr) >= 0) { *device = ifr.ifr_name; } else { *device = "pf0"; } } /* accept all packets */ Filter.enf_Priority = 37; /* anything > 2 */ Filter.enf_FilterLen = 0; /* means "always true" */ if (ioctl(fd, EIOCSETF, &Filter) < 0) { error("ioctl: EIOCSETF"); finish(-1); } return(fd); } /* * pfilt_devtype - return device type code for packet filter device */ int pfilt_devtype(fd) int fd; { struct endevp devparams; if (ioctl(fd, EIOCDEVP, &devparams) < 0) { error("ioctl: EIOCDEVP"); finish(-1); } switch (devparams.end_dev_type) { case ENDT_10MB: return(DLT_EN10MB); #ifdef ENDT_FDDI /* HACK: to compile prior to Ultrix 4.2 */ case ENDT_FDDI: return(DLT_FDDI); #endif default: /* * Currently, the Ultrix packet filter supports only * Ethernet and FDDI. */ fprintf(stderr, "Packet filter data-link type %d unknown\n", devparams.end_dev_type); fprintf(stderr, "Assuming Ethernet\n"); return(DLT_EN10MB); } } /* * flush_pfilt - flush data from the packet filter */ void flush_pfilt(fd) int fd; { if (ioctl(fd, EIOCFLUSH) < 0) { error("ioctl: EIOCFLUSH"); finish(-1); } } #endif /* USE_PFILT */ nfswatch-4.99.11/osf.map.h0000644000551200011300000000136410201730631014402 0ustar chrisludwig/* * $Id: osf.map.h,v 1.3 2005/02/07 18:21:13 c4chris Exp $ * * HISTORY * */ /* * @(#)$RCSfile: osf.map.h,v $ $Revision: 1.3 $ (DEC) $Date: 2005/02/07 18:21:13 $ */ /* * Cloned from ultrix.map.h, although this could really be a single * file. */ #ifndef ETHERTYPE_REVARP /* some systems don't define this */ #define ETHERTYPE_REVARP 0x8035 #define REVARP_REQUEST 3 #define REVARP_REPLY 4 #endif /* ETHERTYPE_REVARP */ /* Map protocol types */ #define ETHERPUP_IPTYPE ETHERTYPE_IP #define ETHERPUP_REVARPTYPE ETHERTYPE_REVARP #define ETHERPUP_ARPTYPE ETHERTYPE_ARP /* newish RIP commands */ #ifndef RIPCMD_POLL #define RIPCMD_POLL 5 #endif /* RIPCMD_POLL */ #ifndef RIPCMD_POLLENTRY #define RIPCMD_POLLENTRY 6 #endif /* RIPCMD_POLLENTRY */ nfswatch-4.99.11/linux.map.h0000644000551200011300000002732510207572503014767 0ustar chrisludwig/* * $Id: linux.map.h,v 1.5 2005/02/25 09:52:03 c4chris Exp $ */ /* DIRECT include of SunOS 4.1 as the IRIX * is in such a state as to be confusing/painful to use */ /* @(#)nfs.h 2.40 89/12/13 SMI */ #ifndef _nfs_nfs_h #define _nfs_nfs_h /* Maximum size of data portion of a remote request */ #define NFS_MAXDATA 8192 #define NFS_MAXNAMLEN 255 #define NFS_MAXPATHLEN 1024 /* * Rpc retransmission parameters */ #define NFS_TIMEO 11 /* initial timeout in tenths of a sec. */ #define NFS_RETRIES 5 /* times to retry request */ /* * maximum transfer size for different interfaces */ #define ECTSIZE 2048 #define IETSIZE 8192 /* * Error status * Should include all possible net errors. * For now we just cast errno into an enum nfsstat. */ enum nfsstat { NFS_OK = 0, /* no error */ NFSERR_PERM=EPERM, /* Not owner */ NFSERR_NOENT=ENOENT, /* No such file or directory */ NFSERR_IO=EIO, /* I/O error */ NFSERR_NXIO=ENXIO, /* No such device or address */ NFSERR_ACCES=EACCES, /* Permission denied */ NFSERR_EXIST=EEXIST, /* File exists */ NFSERR_NODEV=ENODEV, /* No such device */ NFSERR_NOTDIR=ENOTDIR, /* Not a directory */ NFSERR_ISDIR=EISDIR, /* Is a directory */ NFSERR_FBIG=EFBIG, /* File too large */ NFSERR_NOSPC=ENOSPC, /* No space left on device */ NFSERR_ROFS=EROFS, /* Read-only file system */ NFSERR_NAMETOOLONG=ENAMETOOLONG, /* File name too long */ NFSERR_NOTEMPTY=ENOTEMPTY, /* Directory not empty */ NFSERR_DQUOT=EDQUOT, /* Disc quota exceeded */ NFSERR_STALE=ESTALE, /* Stale NFS file handle */ NFSERR_WFLUSH /* write cache flushed */ }; #define puterrno(error) ((enum nfsstat)error) #define geterrno(status) ((int)status) /* * File types */ enum nfsftype { NFNON, NFREG, /* regular file */ NFDIR, /* directory */ NFBLK, /* block special */ NFCHR, /* character special */ NFLNK /* symbolic link */ }; /* * Special kludge for fifos (named pipes) [to adhere to NFS Protocol Spec] * * VFIFO is not in the protocol spec (VNON will be replaced by VFIFO) * so the over-the-wire representation is VCHR with a '-1' device number. * * NOTE: This kludge becomes unnecessary with the Protocol Revision, * but it may be necessary to support it (backwards compatibility). */ #define NFS_FIFO_TYPE NFCHR #define NFS_FIFO_MODE S_IFCHR #define NFS_FIFO_DEV (~0) /* identify fifo in nfs attributes */ #define NA_ISFIFO(NA) (((NA)->na_type == NFS_FIFO_TYPE) && \ ((NA)->na_rdev == NFS_FIFO_DEV)) /* set fifo in nfs attributes */ #define NA_SETFIFO(NA) { \ (NA)->na_type = NFS_FIFO_TYPE; \ (NA)->na_rdev = NFS_FIFO_DEV; \ (NA)->na_mode = ((NA)->na_mode&~S_IFMT)|NFS_FIFO_MODE; \ } /* * Size of an fhandle in bytes */ #define NFS_FHSIZE 32 /* * File access handle * This structure is the Sun server representation of a file. * It is handed out by a server for the client to use in further * file transactions. */ #ifdef NFSSERVER /* * This struct is only used to find the size of the data field in the * fhandle structure below. */ struct fhsize { fsid_t f1; u_short f2; char f3[4]; u_short f4; char f5[4]; }; #define NFS_FHMAXDATA ((NFS_FHSIZE - sizeof (struct fhsize) + 8) / 2) struct svcfh { fsid_t fh_fsid; /* filesystem id */ u_short fh_len; /* file number length */ char fh_data[NFS_FHMAXDATA]; /* and data */ u_short fh_xlen; /* export file number length */ char fh_xdata[NFS_FHMAXDATA]; /* and data */ }; typedef struct svcfh fhandle_t; #else /* * This is the client view of an fhandle */ typedef struct { char fh_data[NFS_FHSIZE]; /* opaque data */ } fhandle_t; #endif /* * Arguments to remote write and writecache */ struct nfswriteargs { fhandle_t wa_fhandle; /* handle for file */ u_int wa_begoff; /* beginning byte offset in file */ u_int wa_offset; /* current byte offset in file */ u_int wa_totcount; /* total write cnt (to this offset) */ u_int wa_count; /* size of this write */ char *wa_data; /* data to write (up to NFS_MAXDATA) */ struct mbuf *wa_mbuf; /* mbuf containing data */ }; struct nfs2_timeval { uint32_t tv_sec; uint32_t tv_usec; }; /* * File attributes */ struct nfsfattr { enum nfsftype na_type; /* file type */ u_int na_mode; /* protection mode bits */ u_int na_nlink; /* # hard links */ u_int na_uid; /* owner user id */ u_int na_gid; /* owner group id */ u_int na_size; /* file size in bytes */ u_int na_blocksize; /* prefered block size */ u_int na_rdev; /* special device # */ u_int na_blocks; /* Kb of disk used by file */ u_int na_fsid; /* device # */ u_int na_nodeid; /* inode # */ struct nfs2_timeval na_atime; /* time of last access */ struct nfs2_timeval na_mtime; /* time of last modification */ struct nfs2_timeval na_ctime; /* time of last change */ }; #define n2v_type(x) (NA_ISFIFO(x) ? VFIFO : (enum vtype)((x)->na_type)) #define n2v_rdev(x) (NA_ISFIFO(x) ? 0 : (x)->na_rdev) /* * Arguments to remote read */ struct nfsreadargs { fhandle_t ra_fhandle; /* handle for file */ u_int ra_offset; /* byte offset in file */ u_int ra_count; /* immediate read count */ u_int ra_totcount; /* total read cnt (from this offset) */ }; /* * Status OK portion of remote read reply */ struct nfsrrok { struct nfsfattr rrok_attr; /* attributes, need for pagin */ u_int rrok_count; /* bytes of data */ char *rrok_data; /* data (up to NFS_MAXDATA bytes) */ char *rrok_map; /* pointer to mapped data */ struct vnode *rrok_vp; /* vnode assoc. with mapping */ }; /* * Reply from remote read */ struct nfsrdresult { enum nfsstat rr_status; /* status of read */ union { struct nfsrrok rr_ok_u; /* attributes, need for pagin */ } rr_u; }; #define rr_ok rr_u.rr_ok_u #define rr_attr rr_u.rr_ok_u.rrok_attr #define rr_count rr_u.rr_ok_u.rrok_count #define rr_data rr_u.rr_ok_u.rrok_data #define rr_map rr_u.rr_ok_u.rrok_map #define rr_vp rr_u.rr_ok_u.rrok_vp /* * File attributes which can be set */ struct nfssattr { u_int sa_mode; /* protection mode bits */ u_int sa_uid; /* owner user id */ u_int sa_gid; /* owner group id */ u_int sa_size; /* file size in bytes */ struct nfs2_timeval sa_atime; /* time of last access */ struct nfs2_timeval sa_mtime; /* time of last modification */ }; /* * Reply status with file attributes */ struct nfsattrstat { enum nfsstat ns_status; /* reply status */ union { struct nfsfattr ns_attr_u; /* NFS_OK: file attributes */ } ns_u; }; #define ns_attr ns_u.ns_attr_u /* * NFS_OK part of read sym link reply union */ struct nfssrok { u_int srok_count; /* size of string */ char *srok_data; /* string (up to NFS_MAXPATHLEN bytes) */ }; /* * Result of reading symbolic link */ struct nfsrdlnres { enum nfsstat rl_status; /* status of symlink read */ union { struct nfssrok rl_srok_u; /* name of linked to */ } rl_u; }; #define rl_srok rl_u.rl_srok_u #define rl_count rl_u.rl_srok_u.srok_count #define rl_data rl_u.rl_srok_u.srok_data /* * Arguments to readdir */ struct nfsrddirargs { fhandle_t rda_fh; /* directory handle */ u_int rda_offset; /* offset in directory (opaque) */ u_int rda_count; /* number of directory bytes to read */ }; /* * NFS_OK part of readdir result */ struct nfsrdok { u_int rdok_offset; /* next offset (opaque) */ u_int rdok_size; /* size in bytes of entries */ bool_t rdok_eof; /* true if last entry is in result */ struct dirent *rdok_entries; /* variable number of entries */ }; /* * Readdir result */ struct nfsrddirres { u_int rd_bufsize; /* client request size (not xdr'ed) */ u_int rd_origreqsize; /* client request size */ enum nfsstat rd_status; union { struct nfsrdok rd_rdok_u; } rd_u; }; #define rd_rdok rd_u.rd_rdok_u #define rd_offset rd_u.rd_rdok_u.rdok_offset #define rd_size rd_u.rd_rdok_u.rdok_size #define rd_eof rd_u.rd_rdok_u.rdok_eof #define rd_entries rd_u.rd_rdok_u.rdok_entries /* * Arguments for directory operations */ struct nfsdiropargs { fhandle_t da_fhandle; /* directory file handle */ char *da_name; /* name (up to NFS_MAXNAMLEN bytes) */ }; /* * NFS_OK part of directory operation result */ struct nfsdrok { fhandle_t drok_fhandle; /* result file handle */ struct nfsfattr drok_attr; /* result file attributes */ }; /* * Results from directory operation */ struct nfsdiropres { enum nfsstat dr_status; /* result status */ union { struct nfsdrok dr_drok_u; /* NFS_OK result */ } dr_u; }; #define dr_drok dr_u.dr_drok_u #define dr_fhandle dr_u.dr_drok_u.drok_fhandle #define dr_attr dr_u.dr_drok_u.drok_attr /* * arguments to setattr */ struct nfssaargs { fhandle_t saa_fh; /* fhandle of file to be set */ struct nfssattr saa_sa; /* new attributes */ }; /* * arguments to create and mkdir */ struct nfscreatargs { struct nfsdiropargs ca_da; /* file name to create and parent dir */ struct nfssattr ca_sa; /* initial attributes */ }; /* * arguments to link */ struct nfslinkargs { fhandle_t la_from; /* old file */ struct nfsdiropargs la_to; /* new file and parent dir */ }; /* * arguments to rename */ struct nfsrnmargs { struct nfsdiropargs rna_from; /* old file and parent dir */ struct nfsdiropargs rna_to; /* new file and parent dir */ }; /* * arguments to symlink */ struct nfsslargs { struct nfsdiropargs sla_from; /* old file and parent dir */ char *sla_tnm; /* new name */ struct nfssattr sla_sa; /* attributes */ }; /* * NFS_OK part of statfs operation */ struct nfsstatfsok { u_int fsok_tsize; /* preferred transfer size in bytes */ u_int fsok_bsize; /* fundamental file system block size */ u_int fsok_blocks; /* total blocks in file system */ u_int fsok_bfree; /* free blocks in fs */ u_int fsok_bavail; /* free blocks avail to non-superuser */ }; /* * Results of statfs operation */ struct nfsstatfs { enum nfsstat fs_status; /* result status */ union { struct nfsstatfsok fs_fsok_u; /* NFS_OK result */ } fs_u; }; #define fs_fsok fs_u.fs_fsok_u #define fs_tsize fs_u.fs_fsok_u.fsok_tsize #define fs_bsize fs_u.fs_fsok_u.fsok_bsize #define fs_blocks fs_u.fs_fsok_u.fsok_blocks #define fs_bfree fs_u.fs_fsok_u.fsok_bfree #define fs_bavail fs_u.fs_fsok_u.fsok_bavail /* * Remote file service routines */ #define RFS_NULL 0 #define RFS_GETATTR 1 #define RFS_SETATTR 2 #define RFS_ROOT 3 #define RFS_LOOKUP 4 #define RFS_READLINK 5 #define RFS_READ 6 #define RFS_WRITECACHE 7 #define RFS_WRITE 8 #define RFS_CREATE 9 #define RFS_REMOVE 10 #define RFS_RENAME 11 #define RFS_LINK 12 #define RFS_SYMLINK 13 #define RFS_MKDIR 14 #define RFS_RMDIR 15 #define RFS_READDIR 16 #define RFS_STATFS 17 /* * remote file service numbers */ #define NFS_PROGRAM ((u_long)100003) #define NFS_VERSION ((u_long)2) #define NFS_PORT 2049 /* * NFS3 stuff */ #define NFS3_FHSIZE 64 typedef unsigned int uint_t; typedef char *filename3; struct nfs_fh3 { uint_t fh3_length; union nfs_fh3_u { struct nfs_fh3_i { fhandle_t fh3_i; } nfs_fh3_i; unsigned char data[NFS3_FHSIZE]; } fh3_u; }; typedef struct nfs_fh3 nfs_fh3; struct diropargs3 { nfs_fh3 *dirp; nfs_fh3 dir; filename3 name; int flags; }; typedef struct diropargs3 diropargs3; struct RENAME3args { diropargs3 from; diropargs3 to; }; typedef struct RENAME3args RENAME3args; struct LINK3args { nfs_fh3 file; diropargs3 link; }; typedef struct LINK3args LINK3args; #define NFSPROC3_NULL 0 #define NFSPROC3_GETATTR 1 #define NFSPROC3_SETATTR 2 #define NFSPROC3_LOOKUP 3 #define NFSPROC3_ACCESS 4 #define NFSPROC3_READLINK 5 #define NFSPROC3_READ 6 #define NFSPROC3_WRITE 7 #define NFSPROC3_CREATE 8 #define NFSPROC3_MKDIR 9 #define NFSPROC3_SYMLINK 10 #define NFSPROC3_MKNOD 11 #define NFSPROC3_REMOVE 12 #define NFSPROC3_RMDIR 13 #define NFSPROC3_RENAME 14 #define NFSPROC3_LINK 15 #define NFSPROC3_READDIR 16 #define NFSPROC3_READDIRPLUS 17 #define NFSPROC3_FSSTAT 18 #define NFSPROC3_FSINFO 19 #define NFSPROC3_PATHCONF 20 #define NFSPROC3_COMMIT 21 #endif /*!_nfs_nfs_h*/ nfswatch-4.99.11/linux.c0000644000551200011300000000565111142036746014207 0ustar chrisludwig/* * $Id: linux.c,v 1.5 2009/02/03 12:51:50 c4chris Exp $ * * Christian Iseli * Ludwig Institute for Cancer Research * UNIL - BEP * CH-1015 Lausanne * Switzerland * */ #include "os.h" #ifdef USE_LINUX #include #include #include #include #include #include #include #include #include #include #include #include #include #include "nfswatch.h" #include "externs.h" static void linux_get_def_dev(char **device) { int n, s; struct ifreq *ifrp; struct ifconf ifc; char buf[BUFSIZ]; /* * Grab a socket. */ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { error("socket"); finish(-1); } ifc.ifc_buf = buf; ifc.ifc_len = sizeof(buf); /* * See what devices we've got. */ if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) { error("ioctl: SIOCGIFCONF"); finish(-1); } /* * Take the first device we encounter. */ ifrp = ifc.ifc_req; for (n = ifc.ifc_len/sizeof(struct ifreq); n > 0; n--,ifrp++) { /* * Skip the loopback interface. */ if (strcmp(ifrp->ifr_name, "lo") == 0) continue; *device = strdup(ifrp->ifr_name); break; } (void) close(s); } /* * setup_linux_dev - set up the network interface tap. */ int setup_linux_dev(char **device, linux_socket_handle_p_t ls) { char errbuf[PCAP_ERRBUF_SIZE]; /* * If the interface device was not specified, * get the default one. */ if (device != NULL && *device == NULL) { linux_get_def_dev(device); if (*device == NULL) { error("linux: couldn't determine default device"); finish(-1); } } errbuf[0] = 0; if (device == NULL) { ls->pcap = pcap_open_live(NULL, 65536, 0, 10, errbuf); ls->device = "any"; } else { ls->pcap = pcap_open_live(*device, 65536, 1, 10, errbuf); ls->device = *device; } if (ls->pcap == NULL) { fprintf(stderr, "Failed to open device: %s\n", errbuf); finish(-1); } if (errbuf[0] != 0) fprintf(stderr, "Warning: %s\n", errbuf); ls->s = pcap_get_selectable_fd(ls->pcap); if (ls->s == -1) { fprintf(stderr, "Failed to get a selectable file descriptor\n"); finish(-1); } /* Determine link type. */ ls->linktype = pcap_datalink(ls->pcap); ls->offset = 2; /* Grab a big enough buffer. */ ls->bufsize = 65536; ls->buffer = (u_char *)malloc(ls->bufsize + ls->offset); if (ls->buffer == NULL) { perror("malloc"); finish(-1); } return(ls->s); } int linux_read_packet(linux_socket_handle_p_t ls) { u_char *bp; int res; struct pcap_pkthdr *hdr; const u_char *data; /* Receive a single packet from the kernel */ bp = ls->buffer + ls->offset; res = pcap_next_ex(ls->pcap, &hdr, &data); if (res == -1) { pcap_perror(ls->pcap, "Error reading packet: "); return -1; } if (res <= 0) return 0; memcpy(bp, data, hdr->caplen); ls->len = hdr->caplen; ls->ts = hdr->ts; ls->bp = bp; return 1; } #endif /* USE_LINUX */ nfswatch-4.99.11/nfslogsum.80000644000551200011300000001017710177742445015020 0ustar chrisludwig.ig .\" $Id: nfslogsum.8,v 1.2 2005/02/01 18:06:29 c4chris Exp $ .. .ds @N \s-1NFS\s0 .TH NFSLOGSUM 8L "January 1993" Purdue/DEC .SH NAME nfslogsum \- summarize \fBnfswatch\fP log file .SH SYNOPSIS .B nfslogsum [ .I \-n ] [ .B \-v ] [ .I logfile ] .SH DESCRIPTION .PP .I nfslogsum summarizes log files produced by the .I nfswatch program. By default the log file .I nfswatch.log is summarized; an alternate log file can be specified on the command line. .PP Each .I nfswatch log file may contain one or more log sessions, each indicated by a header which is printed when logging is turned on. For each log session, .I nfslogsum tallies up the interval packet totals and prints out a one-page summary of the log session. Total packets and percentages are tabulated for each category and displayed. .PP The .B \-n option tells .I nfslogsum to read only the first .I n entries in the log file. This is useful for summarizing log files in cumulative ``chunks''. .PP If the .B \-v option is given, .I nfslogsum will produce a ``verbose'' summary of the log file. In addition to the summary information printed as described above, a summary of how many calls to each \*(@N procedure were made on each file system and individual file will be printed. This summary information is divided into three sections of six columns each. The columns are headed by the names of the \*(@N procedures; these are described briefly below: .IP "\fB\s-1NULLPROC\s0\fP" Do nothing. This procedure is provided to allow server response testing and timing. .IP "\fB\s-1GETATTR\s0\fP" Get file attributes (type, mode, number of links, owner's uid, owner's gid, size, access, modification and change times, etc.). This procedure is used by the .IR stat (2) system call, as well as several others. .IP "\fB\s-1SETATTR\s0\fP" Set file attributes (mode, owner's uid, owner's gid, size in bytes, access and modification times). This procedure is used by system calls such as .IR chmod (2), .IR chown (2), .IR truncate (2), and so on. .IP "\fB\s-1GETROOT\s0\fP" Get file system root. This procedure is obsolete, and has been replaced by a \s-1MOUNT\s0 Protocol procedure. .IP "\fB\s-1LOOKUP\s0\fP" Look up file name. This procedure is used to obtain an initial file handle for use in current and future requests on that file, and is used by many different system calls. .IP "\fB\s-1READLINK\s0\fP" Read from symbolic link. This procedure is used by the .B readlink system call, and by the kernel. .IP "\fB\s-1READ\s0\fP" Read data from file. This procedure is used by the .IR read (2) system call. .IP "\fB\s-1WCACHE\s0\fP" Write to cache. Unused in the current \*(@N protocol revision. .IP "\fB\s-1WRITE\s0\fP" Write data to file. This procedure is used by the .IR write (2) system call. .IP "\fB\s-1CREATE\s0\fP" Create file. This procedure is used by the .IR creat (2) and .IR open (2) system calls. .IP "\fB\s-1REMOVE\s0\fP" Remove file. This procedure is used by the .IR unlink (2) system call. .IP "\fB\s-1RENAME\s0\fP" Rename file. This procedure is used by the .B rename system call. .IP "\fB\s-1LINK\s0\fP" Create link to file. This procedure is used by the .IR link (2) system call. .IP "\fB\s-1SYMLINK\s0\fP" Create symbolic link to file. This procedure is used by the .IR symlink (2) system call. .IP "\fB\s-1MKDIR\s0\fP" Create directory. This procedure is used by the .IR mkdir (2) system call. .IP "\fB\s-1RMDIR\s0\fP" Remove directory. This procedure is used by the .IR rmdir (2) system call. .IP "\fB\s-1READDIR\s0\fP" Read entries from directory. Generally only one \s-1READDIR\s0 call is needed per directory, since a variable number of entries can be returned. .IP "\fB\s-1STATFS\s0\fP" Get file system attributes (transfer size, block size, blocks in use, blocks free). This procedure is used by the .IR statfs (2) system call. .SH SEE ALSO .IR nfswatch (8L) .SH BUGS .PP .I nfslogsum is exteremely sensitive to the format of the log file produced by .IR nfswatch . The log file should not be edited or changed before feeding it to .IR nfslogsum . .SH AUTHOR David A. Curry .br Purdue University .br Engineering Computer Network .br 1285 Electrical Engineering Building .br West Lafayette, \s-1IN\s0 47907-1285 .br davy@ecn.purdue.edu nfswatch-4.99.11/rpcutil.c0000644000551200011300000001152210443765011014521 0ustar chrisludwig/* * $Id: rpcutil.c,v 1.8 2006/06/14 10:50:49 c4chris Exp $ */ #include "os.h" /* * rpcutil.c - routines for emulating RPC library functions without really * receiving packets. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ #include #include #ifdef SVR4 #include #endif #ifdef USE_LINUX /* This yucky hack is needed because glibc's headers are wrong wrt the * correct size needed in RPC stuff on 64-bit machines. There even is * a comment in to that effect... */ #define u_long uint32_t #endif #include #include #include #include #ifdef SVR4 #include #endif #include #include #ifdef USE_LINUX #undef u_long #endif #include #include #include #define NFSSERVER 1 #ifdef sun #include #include #endif #ifdef ultrix #include #include #include #endif #ifdef sgi #include #ifdef IRIX6 #include #include #else #include "sgi.map.h" #endif #endif #ifdef __osf__ #include #include #include #include #endif #ifdef LINUX #include "linux.map.h" #endif #include "nfswatch.h" #include "externs.h" #include "rpcdefs.h" /* get rpc arguments */ static bool_t rpcxdr_getargs(SVCXPRT *, xdrproc_t, caddr_t); /* * Operations on the SVCXPRT structure. We're only going to use * the one to get arguments from it. */ static struct xp_ops xp_ops = { NULL, NULL, rpcxdr_getargs, NULL, NULL, NULL #ifdef sun , NULL /* Solaris has an additional xp_control field... */ #endif }; static SVCXPRT *xprt; /* the service description */ /* * setup_rpcxdr - set up for decoding RPC XDR stuff. Sort of a svcudp_create * without the socket code. */ void setup_rpcxdr(void) { register struct svcudp_data *su; /* * Allocate the SVCXPRT structure. */ if ((xprt = (SVCXPRT *) malloc(sizeof(SVCXPRT))) == NULL) { (void) fprintf(stderr, "%s: out of memory.\n", pname); finish(-1); } /* * Allocate UDP service data. */ if ((su = (struct svcudp_data *) malloc(sizeof(struct svcudp_data))) == NULL) { (void) fprintf(stderr, "%s: out of memory.\n", pname); finish(-1); } /* * This is the maximum size of a packet. */ su->su_iosz = ((UDPMSGSIZE + 3) / 4) * 4; /* * Get a buffer to store stuff in. */ if ((rpc_buffer(xprt) = (char *) malloc(su->su_iosz)) == NULL) { (void) fprintf(stderr, "%s: out of memory.\n", pname); finish(-1); } /* * Fill in the SVCXPRT structure. This is a standard RPC routine. */ (void) xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE); xprt->xp_ops = &xp_ops; xprt->xp_p2 = (caddr_t) su; xprt->xp_verf.oa_base = su->su_verfbody; } #ifdef LINUX /* * Try with my version of xdr_callmsg(), because the one in glibc is * wrong on 64-bit machines. */ static bool_t my_xdr_callmsg(XDR *xdrs, struct rpc_msg *cmsg) { if (xdr_u_int (xdrs, &(cmsg->rm_xid)) && xdr_enum (xdrs, (void *) & (cmsg->rm_direction)) && (cmsg->rm_direction == CALL) && xdr_u_int (xdrs, &(cmsg->rm_call.cb_rpcvers)) && (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) && xdr_u_int (xdrs, &(cmsg->rm_call.cb_prog)) && xdr_u_int (xdrs, &(cmsg->rm_call.cb_vers)) && xdr_u_int (xdrs, &(cmsg->rm_call.cb_proc)) && xdr_opaque_auth (xdrs, &(cmsg->rm_call.cb_cred))) return xdr_opaque_auth (xdrs, &(cmsg->rm_call.cb_verf)); return FALSE; } #endif /* * udprpc_recv - pretend we've received an RPC packet - this is sort of like * svcudp_recv. */ int udprpc_recv(char *data, u_int length, struct rpc_msg *msg, SVCXPRT **xp) { register XDR *xdrs; register struct svcudp_data *su; su = su_data(xprt); xdrs = &(su->su_xdrs); /* * Too short. */ if (length < (4 * sizeof(u_int32))) return(FALSE); if (length > truncation) length = truncation; /* * Copy the data. */ (void) bcopy(data, rpc_buffer(xprt), min(length, su->su_iosz)); xdrs->x_op = XDR_DECODE; /* * Set the XDR routines to the start of the buffer. */ (void) XDR_SETPOS(xdrs, 0); /* * Decode the RPC message structure. */ #ifdef LINUX if (!my_xdr_callmsg(xdrs, msg)) return(FALSE); #else if (!xdr_callmsg(xdrs, msg)) return(FALSE); #endif su->su_xid = msg->rm_xid; *xp = xprt; return(TRUE); } /* * rpcxdr_getargs - called by SVC_GETARGS. */ static bool_t rpcxdr_getargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) { return((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr)); } nfswatch-4.99.11/ultrix.map.h0000644000551200011300000000361710201730631015145 0ustar chrisludwig/* * Copyright (c) 1988 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Lawrence Berkeley Laboratory, * Berkeley, CA. The name of the University may not be used to * endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * @(#) $Header: /cvsroot/nfswatch/nfswatch/ultrix.map.h,v 1.3 2005/02/07 18:21:13 c4chris Exp $ (LBL) */ /* * Cloned from sunos4.map.h, although this could really be a single * file. */ /* Arcane method for discovering if this is Ultrix 4.0 */ #include #ifndef ST_DS5100 #define ULTRIX40 #endif /* ST_DS5100 */ #ifndef ETHERTYPE_REVARP /* some systems don't define this */ #define ETHERTYPE_REVARP 0x8035 #define REVARP_REQUEST 3 #define REVARP_REPLY 4 #endif /* ETHERTYPE_REVARP */ #ifdef ULTRIX40 struct ether_addr { u_char ether_addr_octet[6]; }; #endif /* ULTRIX40 */ /* Map things in the ether_arp struct */ #define arp_xsha arp_sha #define arp_xspa arp_spa #define arp_xtha arp_tha #define arp_xtpa arp_tpa /* Map protocol types */ #define ETHERPUP_IPTYPE ETHERTYPE_IP #define ETHERPUP_REVARPTYPE ETHERTYPE_REVARP #define ETHERPUP_ARPTYPE ETHERTYPE_ARP /* newish RIP commands */ #ifndef RIPCMD_POLL #define RIPCMD_POLL 5 #endif /* RIPCMD_POLL */ #ifndef RIPCMD_POLLENTRY #define RIPCMD_POLLENTRY 6 #endif /* RIPCMD_POLLENTRY */ nfswatch-4.99.11/parsenfsfh.c0000644000551200011300000003751310602561460015205 0ustar chrisludwig/* * $Id: parsenfsfh.c,v 1.7 2007/03/28 21:50:40 c4chris Exp $ */ #include "os.h" /* * parsenfsfh.c - portable parser for NFS file handles * uses all sorts of heuristics * * Jeffrey C. Mogul * Digital Equipment Corporation * Western Research Laboratory * */ #include #include #include #include #include #include "nfsfh.h" /* * Make sure that we use 32-bit integers when necessary. The "x" * suffix is to avoid possible identifier conflicts. */ typedef int int32x; typedef unsigned int u_int32x; /* * This routine attempts to parse a file handle (in network byte order), * using heuristics to guess what kind of format it is in. See the * file "fhandle_layouts" for a detailed description of the various * patterns we know about. * * The file handle is parsed into our internal representation of a * file-system id, and an internal representation of an inode-number. */ #define FHT_UNKNOWN 0 #define FHT_AUSPEX 1 #define FHT_DECOSF 2 #define FHT_IRIX4 3 #define FHT_IRIX5 4 #define FHT_SUNOS3 5 #define FHT_SUNOS4 6 #define FHT_ULTRIX 7 #define FHT_VMSUCX 8 #define FHT_SUNOS5 9 #define FHT_AIX32 10 #define FHT_HPUX9 11 #define FHT_NETAPP 12 #define FHT_LINUX 13 #ifdef ultrix /* Nasty hack to keep the Ultrix C compiler from emitting bogus warnings */ #define XFF(x) ((unsigned long)(x)) #else #define XFF(x) (x) #endif #define make_uint32(msb,b,c,lsb)\ (XFF(lsb) + (XFF(c)<<8) + (XFF(b)<<16) + (XFF(msb)<<24)) #define make_uint24(msb,b, lsb)\ (XFF(lsb) + (XFF(b)<<8) + (XFF(msb)<<16)) #define make_uint16(msb,lsb)\ (XFF(lsb) + (XFF(msb)<<8)) /* * Is this a VMS UCX file handle? * Check for: * (1) leading code byte [XXX not yet] * (2) followed by string of printing chars & spaces * (3) followed by string of nulls */ static int is_UCX(unsigned char *fhp) { register int i; int seen_null = 0; for (i = 1; i < 14; i++) { if (isprint(fhp[i])) { if (seen_null) return(0); else continue; } else if (fhp[i] == 0) { seen_null = 1; continue; } else return(0); } return(1); } /* if osnamep is non-NULL, return OS name here */ /* if fsnamep is non-NULL, return server fs name here (for VMS) */ /* ourself is true if file handle was generated on this host */ void Parse_fh(caddr_t *fh, my_fsid *fsidp, ino_t *inop, char **osnamep, char **fsnamep, int ourself) { register unsigned char *fhp = (unsigned char *)fh; u_int32x temp; int fhtype = FHT_UNKNOWN; if (ourself) { /* File handle generated on this host, no need for guessing */ #if defined(IRIX40) fhtype = FHT_IRIX4; #endif #if defined(IRIX50) fhtype = FHT_IRIX5; #endif #if defined(IRIX51) fhtype = FHT_IRIX5; #endif #if defined(SUNOS4) fhtype = FHT_SUNOS4; #endif #if defined(SUNOS5) fhtype = FHT_SUNOS5; #endif #if defined(ultrix) fhtype = FHT_ULTRIX; #endif #if defined(__osf__) fhtype = FHT_DECOSF; #endif #if defined(LINUX) fhtype = FHT_LINUX; #endif } /* * This is basically a big decision tree */ else if ((fhp[0] == 0) && (fhp[1] == 0)) { /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */ /* probably rules out HP-UX, AIX unless they allow major=0 */ if ((fhp[2] == 0) && (fhp[3] == 0)) { /* bytes[2,3] == (0,0); must be Auspex */ /* XXX or could be Ultrix+MASSBUS "hp" disk? */ fhtype = FHT_AUSPEX; } else { /* * bytes[2,3] != (0,0); rules out Auspex, could be * DECOSF, SUNOS4, IRIX4, or NETAPP */ if ((fhp[4] != 0) && (fhp[5] == 0) && (fhp[8] == 12) && (fhp[9] == 0)) { /* seems to be DECOSF, with minor == 0 */ /* XXX - could be NETAPP */ fhtype = FHT_DECOSF; } else { /* could be SUNOS4 or IRIX4 */ /* XXX the test of fhp[5] == 8 could be wrong */ if ((fhp[4] == 0) && (fhp[5] == 8) && (fhp[6] == 0) && (fhp[7] == 0)) { /* looks like a length, not a file system typecode */ /* XXX - could be NETAPP */ fhtype = FHT_IRIX4; } else { /* by elimination */ /* XXX - could be NETAPP */ fhtype = FHT_SUNOS4; } } } } else { /* * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4 * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5 * could be AIX, HP-UX, or NETAPP */ if ((fhp[2] == 0) && (fhp[3] == 0)) { /* * bytes[2,3] == (0,0); rules out OSF, probably not UCX * (unless the exported device name is just one letter!), * could be Ultrix, IRIX5, AIX, SUNOS5, or NETAPP * might be HP-UX (depends on their values for minor devs) */ /*XXX we probably only need to test of these two bytes */ if ((fhp[21] == 0) && (fhp[23] == 0)) { /* XXX - could be NETAPP */ fhtype = FHT_ULTRIX; } else { /* * Could be SUNOS5/IRIX5, maybe AIX * XXX no obvious difference between SUNOS5 and IRIX5 * *Current* Netapp releases don't use that byte * of the flags. */ /* if (fhp[9] == 10) fhtype = FHT_SUNOS5; */ /* XXX what about AIX? */ } } else { /* * bytes[2,3] != (0,0); rules out Ultrix, could be * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, UCX, or NETAPP */ if ((fhp[8] == 12) && (fhp[9] == 0)) { /* XXX - could be NETAPP */ fhtype = FHT_DECOSF; } else if ((fhp[8] == 0) && (fhp[9] == 10)) { /* * Could be SUNOS5/IRIX5, AIX, HP-UX * *Current* Netapp releases don't use byte 9 * of the flags. */ if ((fhp[7] == 0) && (fhp[6] == 0) && (fhp[5] == 0) && (fhp[4] == 0)) { /* XXX is this always true of HP-UX? */ fhtype = FHT_HPUX9; } else if (fhp[7] == 2) { /* This would be MNT_NFS on AIX, which is impossible */ fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ } else { /* * XXX Could be SUNOS5/IRIX5 or AIX. I don't * XXX see any way to disambiguate these, so * XXX I'm going with the more likely guess. * XXX Sorry, Big Blue. */ fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ } } else { if (is_UCX(fhp)) { fhtype = FHT_VMSUCX; } else { fhtype = FHT_UNKNOWN; } } } } /* * Network Appliance file handles are a bit painful, as * they stuff inode and generation numbers in the first * 8 bytes; that means there can be just about anything * there, so we may get false hits. * * SUNOS4 and SUNOS5 file handles are one possible false hit * (although that's *currently* unlikely, as the low-order * byte of the file handle length of a SUNOS4 or SUNOS5 * file handle is a byte of flags that's not used in * current Netapp releases; we'll check anyway, because * we're paranoid). */ if (fhtype == FHT_SUNOS4 || fhtype == FHT_SUNOS5) { temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); if (temp > 32) { /* * Probably not a file system typecode for a little-endian * machine; might it be one for a big-endian machine? */ temp = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); if (temp > 32) { /* * Probably not a file system typecode for a * big-endian machine, either; assume it's a Netapp * box. */ fhtype = FHT_NETAPP; } } } /* * DECOSF file handles are another possible false hit. */ if (fhtype == FHT_DECOSF) { temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); if (temp > 32) { /* * Probably not a file system typecode for a little-endian * machine; assume it's a Netapp box. */ fhtype = FHT_NETAPP; } } /* * IRIX4 file handles are another possible false hit. */ if (fhtype == FHT_IRIX4) { if ((fhp[28] != 0) || (fhp[29] != 0) || (fhp[30] != 0) || (fhp[31] != 0)) { /* * Stuff that's padding on IRIX4 is non-zero; assume * it's a Netapp box. */ fhtype = FHT_NETAPP; } } /* * Ultrix file handles are another possible false hit. */ if (fhtype == FHT_ULTRIX) { if ((fhp[24] != 0) || (fhp[25] != 0) || ((fhp[26] != 0) && (fhp[27] != 0))) { /* * Stuff that's padding on Ultrix is non-zero; assume * it's a Netapp box. */ fhtype = FHT_NETAPP; } } /* * And sometimes something that doesn't look like anything * else could be from a Netapp box. * * Thus, if it's UNKNOWN, we'll see if it looks like a * NETAPP file handle. FAServers (currently) always * stuff 0 in byte 11, and stuff a snapshot ID, which * should be less than 21, in 10, so check for that. */ if (fhtype == FHT_UNKNOWN) { if ((fhp[11] == 0) && (fhp[10] < 21)) fhtype = FHT_NETAPP; } /* XXX still needs to handle SUNOS3 */ switch (fhtype) { case FHT_AUSPEX: fsidp->fsid_dev.Minor = fhp[7]; fsidp->fsid_dev.Major = fhp[6]; fsidp->fsid_code = 0; temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); *inop = temp; if (osnamep) *osnamep = "Auspex"; break; case FHT_DECOSF: fsidp->fsid_code = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); /* XXX could ignore 3 high-order bytes */ temp = make_uint32(fhp[3], fhp[2], fhp[1], fhp[0]); fsidp->fsid_dev.Minor = temp & 0xFFFFF; fsidp->fsid_dev.Major = (temp>>20) & 0xFFF; temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]); *inop = temp; if (osnamep) *osnamep = "OSF"; break; case FHT_IRIX4: fsidp->fsid_dev.Minor = fhp[3]; fsidp->fsid_dev.Major = fhp[2]; fsidp->fsid_code = 0; temp = make_uint32(fhp[8], fhp[9], fhp[10], fhp[11]); *inop = temp; if (osnamep) *osnamep = "IRIX4"; break; case FHT_IRIX5: temp = make_uint16(fhp[0], fhp[1]); fsidp->fsid_dev.Major = (temp>>2) & 0x3FFF; temp = make_uint24(fhp[1], fhp[2], fhp[3]); fsidp->fsid_dev.Minor = temp & 0x3FFFF; fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); *inop = temp; if (osnamep) *osnamep = "IRIX5"; break; case FHT_SUNOS3: if (osnamep) *osnamep = "SUNOS3"; break; case FHT_SUNOS4: /* * XXX - what about little-endian SUNOS4 boxes, such as * Sun386i's? */ fsidp->fsid_dev.Minor = fhp[3]; fsidp->fsid_dev.Major = fhp[2]; fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); *inop = temp; if (osnamep) *osnamep = "SUNOS4"; break; case FHT_SUNOS5: /* * XXX - what about little-endian SUNOS5 boxes, such as * IBM-compatible PC's? */ temp = make_uint16(fhp[0], fhp[1]); fsidp->fsid_dev.Major = (temp>>2) & 0x3FFF; temp = make_uint24(fhp[1], fhp[2], fhp[3]); fsidp->fsid_dev.Minor = temp & 0x3FFFF; fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); *inop = temp; if (osnamep) *osnamep = "SUNOS5"; break; case FHT_ULTRIX: fsidp->fsid_code = 0; fsidp->fsid_dev.Minor = fhp[0]; fsidp->fsid_dev.Major = fhp[1]; temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); *inop = temp; if (osnamep) *osnamep = "Ultrix"; break; case FHT_VMSUCX: /* No numeric file system ID, so hash on the device-name */ if (sizeof(*fsidp) >= 14) { if (sizeof(*fsidp) > 14) memset(fsidp, 0, sizeof(*fsidp)); memcpy(fsidp, fh, 14); /* just use the whole thing */ } else { u_long tempa[4]; /* at least 16 bytes, maybe more */ memset(tempa, 0, sizeof(tempa)); memcpy(tempa, fh, 14); /* ensure alignment */ fsidp->fsid_dev.Minor = tempa[0] + (tempa[1]<<1); fsidp->fsid_dev.Major = tempa[2] + (tempa[3]<<1); fsidp->fsid_code = 0; } /* VMS file ID is: (RVN, FidHi, FidLo) */ *inop = make_uint32(fhp[26], fhp[27], fhp[23], fhp[22]); /* Caller must save (and null-terminate?) this value */ if (fsnamep) *fsnamep = (char *)&(fhp[1]); if (osnamep) *osnamep = "VMS"; break; case FHT_AIX32: fsidp->fsid_dev.Minor = make_uint16(fhp[2], fhp[3]); fsidp->fsid_dev.Major = make_uint16(fhp[0], fhp[1]); fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); *inop = temp; if (osnamep) *osnamep = "AIX32"; break; case FHT_HPUX9: fsidp->fsid_dev.Major = fhp[0]; temp = make_uint24(fhp[1], fhp[2], fhp[3]); fsidp->fsid_dev.Minor = temp; fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); *inop = temp; if (osnamep) *osnamep = "HPUX9"; break; case FHT_NETAPP: /* * Only one file system per box.... */ fsidp->fsid_code = 0; fsidp->fsid_dev.Minor = 0; fsidp->fsid_dev.Major = 0; /* * ...and, for now, they're all little-endian. */ temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]); *inop = temp; if (osnamep) *osnamep = "FAServer"; break; case FHT_LINUX: if (osnamep) *osnamep = "Linux"; memset(fsidp, 0, sizeof(my_fsid)); if (fhp[0] == 1 && fhp[1] == 0) { /* Looks like Linux stuff. */ switch (fhp[2]) { case 0: { /* 4 byte device id (ms-2-bytes major, ls-2-bytes minor), 4 byte inode number. */ ino_t ino; fsidp->fsid_dev.Major = (fhp[4] << 8) | fhp[5]; fsidp->fsid_dev.Minor = (fhp[6] << 8) | fhp[7]; /* This is probably the inode number of the export point... Might want to grab the actual file's inode number. */ ino = (fhp[8] << 24) | (fhp[9] << 16) | (fhp[10] << 8) | fhp[11]; *inop = ino; } break; case 1: { /* 4 byte filesystem ID. */ fsidp->fsid_dev.Minor = ntohl((fhp[4] << 24) | (fhp[5] << 16) | (fhp[6] << 8) | fhp[7]); } break; case 2: { /* 4 byte device major, 4 byte device minor, 4 byte inode number. */ ino_t ino; fsidp->fsid_dev.Major = (fhp[4] << 24) | (fhp[5] << 16) | (fhp[6] << 8) | fhp[7]; fsidp->fsid_dev.Minor = (fhp[8] << 24) | (fhp[9] << 16) | (fhp[10] << 8) | fhp[11]; /* This is probably the inode number of the export point... Might want to grab the actual file's inode number. */ ino = (fhp[12] << 24) | (fhp[13] << 16) | (fhp[14] << 8) | fhp[15]; *inop = ino; } break; case 3: { /* 4 byte encoded device info, 4 byte inode number. */ ino_t ino; fsidp->fsid_dev.Major = ((fhp[5] & 0xf) << 8 ) | fhp[6]; fsidp->fsid_dev.Minor = (fhp[4] << 12) | ((fhp[5] & 0xf0) << 8) | fhp[7]; /* This is probably the inode number of the export point... Might want to grab the actual file's inode number. */ ino = (fhp[8] << 24) | (fhp[9] << 16) | (fhp[10] << 8) | fhp[11]; *inop = ino; } break; default: fprintf(stderr, "Unknown Linux fsid_type %u:\n", fhp[2]); { int i; for (i = 0; i < 8; i++) { fprintf(stderr, "%02x %02x %02x %02x\n", fhp[(i << 2)], fhp[(i << 2) + 1], fhp[(i << 2) + 2], fhp[(i << 2) + 3]); } fprintf(stderr, "\n"); } } break; } fprintf(stderr, "Unknown Linux stuff:\n"); { int i; for (i = 0; i < 8; i++) { fprintf(stderr, "%02x %02x %02x %02x\n", fhp[(i << 2)], fhp[(i << 2) + 1], fhp[(i << 2) + 2], fhp[(i << 2) + 3]); } fprintf(stderr, "\n"); } /* * try little-endian.... */ temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); *inop = temp; break; case FHT_UNKNOWN: #ifdef DEBUG { /* XXX debugging */ int i; for (i=0; i<32;i++) fprintf(stderr, "%x.", fhp[i]); fprintf(stderr, "\n"); } #endif /* XXX for now, give "bogus" values to aid debugging */ fsidp->fsid_code = 0; fsidp->fsid_dev.Minor = 257; fsidp->fsid_dev.Major = 257; *inop = 1; /* display will show this string instead of (257,257) */ if (fsnamep) *fsnamep = "Unknown"; if (osnamep) *osnamep = "Unknown"; break; } } nfswatch-4.99.11/screen.h0000644000551200011300000000464410267174507014342 0ustar chrisludwig/* * $Id: screen.h,v 1.3 2005/07/19 12:59:51 c4chris Exp $ * * screen.h - definitions for the display screen. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ #define NONNFSLINES 16 /* non-NFS counter lines */ #define NFSLINES (2 * (LINES-NONNFSLINES)) /* NFS counter lines */ #define NFSPROCLINES ((LINES-NONNFSLINES)) /* NFS proc counter lines */ #define SCR_MIDDLE 40 /* middle of screen, y coord */ #define SCR_PKTLEN 17 /* size of packet name field */ #define SCR_NFSLEN 20 /* size of file sys name field */ /* * X0 is the X location of the field name, X is the coordinate of the * field value. Y is the vertical coordinate of the field name and * value. */ #define SCR_IF_Y 3 #define SCR_HOST_X 0 /* destination host name */ #define SCR_HOST_Y 0 #define SCR_DATE_X 28 /* current date */ #define SCR_DATE_Y 0 #define SCR_ELAPS_X0 55 /* elapsed time */ #define SCR_ELAPS_X 69 #define SCR_ELAPS_Y 0 #define SCR_PKTINT_X0 0 /* packets this interval */ #define SCR_PKTINT_X 17 #define SCR_PKTINT_Y 1 #define SCR_PKTTOT_X0 0 /* total packets received */ #define SCR_PKTTOT_X 17 #define SCR_PKTTOT_Y 2 #define SCR_PROMPT_X0 0 /* prompt */ #define SCR_PROMPT_X 10 #define SCR_PROMPT_Y (LINES - 1) #define SCR_PKT_Y 5 /* start of packet counters */ #define SCR_PKTHDR_X 21 /* header coords */ #define SCR_PKTHDR_Y 4 #define SCR_PKT_INT_X 17 /* interval counter */ #define SCR_PKT_PCT_X 26 /* percentage */ #define SCR_PKT_TOT_X 31 /* total counter */ #define SCR_PKT_NAME_X 0 #define SCR_NFS_Y 15 /* start of nfs counters */ #define SCR_NFSHDR_X 5 /* header coords */ #define SCR_NFSHDR_Y 14 #define SCR_NFS_INT_X 19 /* interval counter */ #define SCR_NFS_PCT_X 26 /* percentage */ #define SCR_NFS_TOT_X 31 /* total counter */ #define SCR_NFS_COMP_X 41 /* completed replies */ #define SCR_NFS_RESP_X 51 /* time of replies */ #define SCR_NFS_RSQR_X 61 /* squared time of replies */ #define SCR_NFS_RMAX_X 71 /* max response time */ #define SCR_NFS_NAME_X 0 /* * Screen text items to be displayed. */ struct scrtxt { short s_x; /* x coordinate */ short s_y; /* y coordinate */ char *s_text; /* text to be displayed */ }; nfswatch-4.99.11/sgi.map.h0000644000551200011300000003013210443765011014400 0ustar chrisludwig/* * $Id: sgi.map.h,v 1.4 2006/06/14 10:50:49 c4chris Exp $ * * sgi.map.h - made up from various other header files * * Tim Hudson * Mincom Pty Ltd * Mincom Centre * Juliette Street * Greenslopes 4120 * Brisbane Australia * * tjh@mincom.oz.au * */ struct ether_addr { u_char ether_addr_octet[6]; }; #ifndef ETHERTYPE_REVARP /* some systems don't define this */ #define ETHERTYPE_REVARP 0x8035 #define REVARP_REQUEST 3 #define REVARP_REPLY 4 #endif /* ETHERTYPE_REVARP */ /* Map things in the ether_arp struct */ #define arp_xsha arp_sha #define arp_xspa arp_spa #define arp_xtha arp_tha #define arp_xtpa arp_tpa /* Map protocol types */ #define ETHERPUP_IPTYPE ETHERTYPE_IP #define ETHERPUP_REVARPTYPE ETHERTYPE_REVARP #define ETHERPUP_ARPTYPE ETHERTYPE_ARP /* newish RIP commands */ #ifndef RIPCMD_POLL #define RIPCMD_POLL 5 #endif /* RIPCMD_POLL */ #ifndef RIPCMD_POLLENTRY #define RIPCMD_POLLENTRY 6 #endif /* RIPCMD_POLLENTRY */ /* good old SGI bastards not putting all the definitions in the * include files ... this defn pulled from SunOS4.1 */ typedef struct { ushort val[2]; } fsid_t; /* DIRECT include of SunOS 4.1 as the IRIX * is in such a state as to be confusing/painful to use */ /* @(#)nfs.h 2.40 89/12/13 SMI */ #ifndef _nfs_nfs_h #define _nfs_nfs_h /* Maximum size of data portion of a remote request */ #define NFS_MAXDATA 8192 #define NFS_MAXNAMLEN 255 #define NFS_MAXPATHLEN 1024 /* * Rpc retransmission parameters */ #define NFS_TIMEO 11 /* initial timeout in tenths of a sec. */ #define NFS_RETRIES 5 /* times to retry request */ /* * maximum transfer size for different interfaces */ #define ECTSIZE 2048 #define IETSIZE 8192 /* * Error status * Should include all possible net errors. * For now we just cast errno into an enum nfsstat. */ enum nfsstat { NFS_OK = 0, /* no error */ NFSERR_PERM=EPERM, /* Not owner */ NFSERR_NOENT=ENOENT, /* No such file or directory */ NFSERR_IO=EIO, /* I/O error */ NFSERR_NXIO=ENXIO, /* No such device or address */ NFSERR_ACCES=EACCES, /* Permission denied */ NFSERR_EXIST=EEXIST, /* File exists */ NFSERR_NODEV=ENODEV, /* No such device */ NFSERR_NOTDIR=ENOTDIR, /* Not a directory */ NFSERR_ISDIR=EISDIR, /* Is a directory */ NFSERR_FBIG=EFBIG, /* File too large */ NFSERR_NOSPC=ENOSPC, /* No space left on device */ NFSERR_ROFS=EROFS, /* Read-only file system */ NFSERR_NAMETOOLONG=ENAMETOOLONG, /* File name too long */ NFSERR_NOTEMPTY=ENOTEMPTY, /* Directory not empty */ NFSERR_DQUOT=EDQUOT, /* Disc quota exceeded */ NFSERR_STALE=ESTALE, /* Stale NFS file handle */ NFSERR_WFLUSH /* write cache flushed */ }; #define puterrno(error) ((enum nfsstat)error) #define geterrno(status) ((int)status) /* * File types */ enum nfsftype { NFNON, NFREG, /* regular file */ NFDIR, /* directory */ NFBLK, /* block special */ NFCHR, /* character special */ NFLNK /* symbolic link */ }; /* * Special kludge for fifos (named pipes) [to adhere to NFS Protocol Spec] * * VFIFO is not in the protocol spec (VNON will be replaced by VFIFO) * so the over-the-wire representation is VCHR with a '-1' device number. * * NOTE: This kludge becomes unnecessary with the Protocol Revision, * but it may be necessary to support it (backwards compatibility). */ #define NFS_FIFO_TYPE NFCHR #define NFS_FIFO_MODE S_IFCHR #define NFS_FIFO_DEV (~0) /* identify fifo in nfs attributes */ #define NA_ISFIFO(NA) (((NA)->na_type == NFS_FIFO_TYPE) && \ ((NA)->na_rdev == NFS_FIFO_DEV)) /* set fifo in nfs attributes */ #define NA_SETFIFO(NA) { \ (NA)->na_type = NFS_FIFO_TYPE; \ (NA)->na_rdev = NFS_FIFO_DEV; \ (NA)->na_mode = ((NA)->na_mode&~S_IFMT)|NFS_FIFO_MODE; \ } /* * Size of an fhandle in bytes */ #define NFS_FHSIZE 32 /* * File access handle * This structure is the Sun server representation of a file. * It is handed out by a server for the client to use in further * file transactions. */ #ifdef NFSSERVER /* * This struct is only used to find the size of the data field in the * fhandle structure below. */ struct fhsize { fsid_t f1; u_short f2; char f3[4]; u_short f4; char f5[4]; }; #define NFS_FHMAXDATA ((NFS_FHSIZE - sizeof (struct fhsize) + 8) / 2) struct svcfh { fsid_t fh_fsid; /* filesystem id */ u_short fh_len; /* file number length */ char fh_data[NFS_FHMAXDATA]; /* and data */ u_short fh_xlen; /* export file number length */ char fh_xdata[NFS_FHMAXDATA]; /* and data */ }; typedef struct svcfh fhandle_t; #else /* * This is the client view of an fhandle */ typedef struct { char fh_data[NFS_FHSIZE]; /* opaque data */ } fhandle_t; #endif /* * Arguments to remote write and writecache */ struct nfswriteargs { fhandle_t wa_fhandle; /* handle for file */ u_long wa_begoff; /* beginning byte offset in file */ u_long wa_offset; /* current byte offset in file */ u_long wa_totcount; /* total write cnt (to this offset) */ u_long wa_count; /* size of this write */ char *wa_data; /* data to write (up to NFS_MAXDATA) */ struct mbuf *wa_mbuf; /* mbuf containing data */ }; /* * File attributes */ struct nfsfattr { enum nfsftype na_type; /* file type */ u_long na_mode; /* protection mode bits */ u_long na_nlink; /* # hard links */ u_long na_uid; /* owner user id */ u_long na_gid; /* owner group id */ u_long na_size; /* file size in bytes */ u_long na_blocksize; /* prefered block size */ u_long na_rdev; /* special device # */ u_long na_blocks; /* Kb of disk used by file */ u_long na_fsid; /* device # */ u_long na_nodeid; /* inode # */ struct timeval na_atime; /* time of last access */ struct timeval na_mtime; /* time of last modification */ struct timeval na_ctime; /* time of last change */ }; #define n2v_type(x) (NA_ISFIFO(x) ? VFIFO : (enum vtype)((x)->na_type)) #define n2v_rdev(x) (NA_ISFIFO(x) ? 0 : (x)->na_rdev) /* * Arguments to remote read */ struct nfsreadargs { fhandle_t ra_fhandle; /* handle for file */ u_long ra_offset; /* byte offset in file */ u_long ra_count; /* immediate read count */ u_long ra_totcount; /* total read cnt (from this offset) */ }; /* * Status OK portion of remote read reply */ struct nfsrrok { struct nfsfattr rrok_attr; /* attributes, need for pagin */ u_long rrok_count; /* bytes of data */ char *rrok_data; /* data (up to NFS_MAXDATA bytes) */ char *rrok_map; /* pointer to mapped data */ struct vnode *rrok_vp; /* vnode assoc. with mapping */ }; /* * Reply from remote read */ struct nfsrdresult { enum nfsstat rr_status; /* status of read */ union { struct nfsrrok rr_ok_u; /* attributes, need for pagin */ } rr_u; }; #define rr_ok rr_u.rr_ok_u #define rr_attr rr_u.rr_ok_u.rrok_attr #define rr_count rr_u.rr_ok_u.rrok_count #define rr_data rr_u.rr_ok_u.rrok_data #define rr_map rr_u.rr_ok_u.rrok_map #define rr_vp rr_u.rr_ok_u.rrok_vp /* * File attributes which can be set */ struct nfssattr { u_long sa_mode; /* protection mode bits */ u_long sa_uid; /* owner user id */ u_long sa_gid; /* owner group id */ u_long sa_size; /* file size in bytes */ struct timeval sa_atime; /* time of last access */ struct timeval sa_mtime; /* time of last modification */ }; /* * Reply status with file attributes */ struct nfsattrstat { enum nfsstat ns_status; /* reply status */ union { struct nfsfattr ns_attr_u; /* NFS_OK: file attributes */ } ns_u; }; #define ns_attr ns_u.ns_attr_u /* * NFS_OK part of read sym link reply union */ struct nfssrok { u_long srok_count; /* size of string */ char *srok_data; /* string (up to NFS_MAXPATHLEN bytes) */ }; /* * Result of reading symbolic link */ struct nfsrdlnres { enum nfsstat rl_status; /* status of symlink read */ union { struct nfssrok rl_srok_u; /* name of linked to */ } rl_u; }; #define rl_srok rl_u.rl_srok_u #define rl_count rl_u.rl_srok_u.srok_count #define rl_data rl_u.rl_srok_u.srok_data /* * Arguments to readdir */ struct nfsrddirargs { fhandle_t rda_fh; /* directory handle */ u_long rda_offset; /* offset in directory (opaque) */ u_long rda_count; /* number of directory bytes to read */ }; /* * NFS_OK part of readdir result */ struct nfsrdok { u_long rdok_offset; /* next offset (opaque) */ u_long rdok_size; /* size in bytes of entries */ bool_t rdok_eof; /* true if last entry is in result */ struct dirent *rdok_entries; /* variable number of entries */ }; /* * Readdir result */ struct nfsrddirres { u_long rd_bufsize; /* client request size (not xdr'ed) */ u_long rd_origreqsize; /* client request size */ enum nfsstat rd_status; union { struct nfsrdok rd_rdok_u; } rd_u; }; #define rd_rdok rd_u.rd_rdok_u #define rd_offset rd_u.rd_rdok_u.rdok_offset #define rd_size rd_u.rd_rdok_u.rdok_size #define rd_eof rd_u.rd_rdok_u.rdok_eof #define rd_entries rd_u.rd_rdok_u.rdok_entries /* * Arguments for directory operations */ struct nfsdiropargs { fhandle_t da_fhandle; /* directory file handle */ char *da_name; /* name (up to NFS_MAXNAMLEN bytes) */ }; /* * NFS_OK part of directory operation result */ struct nfsdrok { fhandle_t drok_fhandle; /* result file handle */ struct nfsfattr drok_attr; /* result file attributes */ }; /* * Results from directory operation */ struct nfsdiropres { enum nfsstat dr_status; /* result status */ union { struct nfsdrok dr_drok_u; /* NFS_OK result */ } dr_u; }; #define dr_drok dr_u.dr_drok_u #define dr_fhandle dr_u.dr_drok_u.drok_fhandle #define dr_attr dr_u.dr_drok_u.drok_attr /* * arguments to setattr */ struct nfssaargs { fhandle_t saa_fh; /* fhandle of file to be set */ struct nfssattr saa_sa; /* new attributes */ }; /* * arguments to create and mkdir */ struct nfscreatargs { struct nfsdiropargs ca_da; /* file name to create and parent dir */ struct nfssattr ca_sa; /* initial attributes */ }; /* * arguments to link */ struct nfslinkargs { fhandle_t la_from; /* old file */ struct nfsdiropargs la_to; /* new file and parent dir */ }; /* * arguments to rename */ struct nfsrnmargs { struct nfsdiropargs rna_from; /* old file and parent dir */ struct nfsdiropargs rna_to; /* new file and parent dir */ }; /* * arguments to symlink */ struct nfsslargs { struct nfsdiropargs sla_from; /* old file and parent dir */ char *sla_tnm; /* new name */ struct nfssattr sla_sa; /* attributes */ }; /* * NFS_OK part of statfs operation */ struct nfsstatfsok { u_long fsok_tsize; /* preferred transfer size in bytes */ u_long fsok_bsize; /* fundamental file system block size */ u_long fsok_blocks; /* total blocks in file system */ u_long fsok_bfree; /* free blocks in fs */ u_long fsok_bavail; /* free blocks avail to non-superuser */ }; /* * Results of statfs operation */ struct nfsstatfs { enum nfsstat fs_status; /* result status */ union { struct nfsstatfsok fs_fsok_u; /* NFS_OK result */ } fs_u; }; #define fs_fsok fs_u.fs_fsok_u #define fs_tsize fs_u.fs_fsok_u.fsok_tsize #define fs_bsize fs_u.fs_fsok_u.fsok_bsize #define fs_blocks fs_u.fs_fsok_u.fsok_blocks #define fs_bfree fs_u.fs_fsok_u.fsok_bfree #define fs_bavail fs_u.fs_fsok_u.fsok_bavail /* * XDR routines for handling structures defined above */ bool_t xdr_attrstat(); bool_t xdr_creatargs(); bool_t xdr_diropargs(); bool_t xdr_diropres(); bool_t xdr_drok(); bool_t xdr_fattr(); bool_t xdr_fhandle(); bool_t xdr_linkargs(); bool_t xdr_rddirargs(); bool_t xdr_putrddirres(); bool_t xdr_getrddirres(); bool_t xdr_rdlnres(); bool_t xdr_rdresult(); bool_t xdr_readargs(); bool_t xdr_rnmargs(); bool_t xdr_rrok(); bool_t xdr_saargs(); bool_t xdr_sattr(); bool_t xdr_slargs(); bool_t xdr_srok(); bool_t xdr_timeval(); bool_t xdr_writeargs(); bool_t xdr_statfs(); /* * Remote file service routines */ #define RFS_NULL 0 #define RFS_GETATTR 1 #define RFS_SETATTR 2 #define RFS_ROOT 3 #define RFS_LOOKUP 4 #define RFS_READLINK 5 #define RFS_READ 6 #define RFS_WRITECACHE 7 #define RFS_WRITE 8 #define RFS_CREATE 9 #define RFS_REMOVE 10 #define RFS_RENAME 11 #define RFS_LINK 12 #define RFS_SYMLINK 13 #define RFS_MKDIR 14 #define RFS_RMDIR 15 #define RFS_READDIR 16 #define RFS_STATFS 17 #define RFS_NPROC 18 /* * remote file service numbers */ #define NFS_PROGRAM ((u_long)100003) #define NFS_VERSION ((u_long)2) #define NFS_PORT 2049 #endif /*!_nfs_nfs_h*/ nfswatch-4.99.11/util.c0000644000551200011300000007014711141430521014013 0ustar chrisludwig/* * $Id: util.c,v 1.17 2009/02/01 23:33:37 c4chris Exp $ */ #include "os.h" /* * util.c - miscellaneous utility routines. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ #include #include #include #include #include #include #include #include #ifdef IRIX40 #include #include #endif #ifdef SUNOS4 #include #include #include #endif #ifdef ultrix #include #endif #ifdef __osf__ #include #endif #ifdef SVR4 #include #include #endif #ifdef LINUX #include #endif #include "nfswatch.h" #include "externs.h" #include "screen.h" static int auth_comp(const void *, const void *); static int is_exported(dev_t); static int nfs_comp(const void *, const void *); static int fil_comp(const void *, const void *); static int prc_comp(const void *, const void *); static int clnt_comp(const void *, const void *); /* * clear_vars - set interval counters to zero. */ static void clear_vars(void) { register int i; int_pkt_total = 0; int_pkt_drops = 0; int_dst_pkt_total = 0; for (i = 0; i < PKT_NCOUNTERS; i++) pkt_counters[i].pc_interval = 0; for (i = 0; i < nnfscounters; i++) { memset(nfs_counters[i].nc_proc, 0, MAXNFS3PROC * sizeof(Counter)); nfs_counters[i].nc_interval = 0; } for (i = 0; i < nfilecounters; i++) { memset(fil_counters[i].fc_proc, 0, MAXNFS3PROC * sizeof(Counter)); fil_counters[i].fc_interval = 0; } for (i = 0; i < MAXNFSPROC; i++) { prc_counters[NFSv2][i].pr_interval = 0; prc_counters[NFSv2][i].pr_complete = 0; prc_counters[NFSv2][i].pr_response = 0; prc_counters[NFSv2][i].pr_respsqr = 0; prc_counters[NFSv2][i].pr_maxresp = 0; } for (i = 0; i < MAXNFS3PROC; i++) { prc_counters[NFSv3][i].pr_interval = 0; prc_counters[NFSv3][i].pr_complete = 0; prc_counters[NFSv3][i].pr_response = 0; prc_counters[NFSv3][i].pr_respsqr = 0; prc_counters[NFSv3][i].pr_maxresp = 0; } for (i = 0; i < nclientcounters; i++) clnt_counters[i].cl_interval = 0; for (i = 0; i < nauthcounters; i++) auth_counters[i].ac_interval = 0; for (i = 0; i < NFSCALLHASHSIZE; i++) nfs_calls[i].proto = 0; } /* * prtime - convert a time to hh:mm:ss. */ char * prtime(time_t sec) { int hh, mm, ss; static char tbuf[16]; hh = sec / 3600; sec %= 3600; mm = sec / 60; sec %= 60; ss = sec; (void) sprintf(tbuf, "%02d:%02d:%02d", hh, mm, ss); return(tbuf); } /* * error - print an error message preceded by the program name. */ void error(char *str) { char buf[BUFSIZ]; (void) sprintf(buf, "%s: %s", pname, str); (void) perror(buf); } /* * finish - clean up and exit. */ void finish(int code) { #ifndef USE_LINUX int i; #endif /* * Close the nit device. */ #ifdef USE_LINUX if (ls.pcap != NULL) pcap_close(ls.pcap); #else for (i = 0; i < ninterfaces; i++) { if (if_fd[i] >= 0) (void) close(if_fd[i]); } #endif /* * End curses. */ if (screen_inited) { #ifdef nocrmode (void) nocrmode(); #else (void) nocbreak(); #endif (void) echo(); (void) move(SCR_PROMPT_Y, SCR_PROMPT_X0); (void) clrtoeol(); (void) refresh(); (void) endwin(); } if (logging) { (void) fprintf(logfp, "#\n# endlog\n#\n"); (void) fclose(logfp); } (void) putchar('\n'); if (code < 0) (void) exit(-code); (void) exit(0); } /* * setup_pkt_counters - set up packet counter screen coordinates. */ void setup_pkt_counters(void) { register int i, j; memset(pkt_counters, 0, PKT_NCOUNTERS * sizeof(PacketCounter)); /* * Set up the strings. */ /* Width 1 2 */ /* 12345678901234567890 */ pkt_counters[PKT_NFS3READ].pc_name = "NFS3 Read"; pkt_counters[PKT_NFS3WRITE].pc_name = "NFS3 Write"; pkt_counters[PKT_NFSREAD].pc_name = "NFS Read"; pkt_counters[PKT_NFSWRITE].pc_name = "NFS Write"; pkt_counters[PKT_NFSMOUNT].pc_name = "NFS Mount"; pkt_counters[PKT_PORTMAP].pc_name = "Port Mapper"; pkt_counters[PKT_RPCAUTH].pc_name = "RPC Authorization"; pkt_counters[PKT_OTHERRPC].pc_name = "Other RPC Packets"; pkt_counters[PKT_TCP].pc_name = "TCP Packets"; pkt_counters[PKT_UDP].pc_name = "UDP Packets"; pkt_counters[PKT_ICMP].pc_name = "ICMP Packets"; pkt_counters[PKT_ROUTING].pc_name = "Routing Control"; pkt_counters[PKT_ARP].pc_name = "Addr Resolution"; pkt_counters[PKT_RARP].pc_name = "Rev Addr Resol"; pkt_counters[PKT_BROADCAST].pc_name = "Ether/FDDI Bdcst"; pkt_counters[PKT_OTHER].pc_name = "Other Packets"; /* * Set screen coordinates for everything. */ for (i = 0, j = PKT_NCOUNTERS/2; i < PKT_NCOUNTERS/2; i++, j++) { pkt_counters[i].pc_namex = SCR_PKT_NAME_X; pkt_counters[j].pc_namex = SCR_PKT_NAME_X + SCR_MIDDLE; pkt_counters[i].pc_namey = SCR_PKT_Y + i; pkt_counters[j].pc_namey = SCR_PKT_Y + i; pkt_counters[i].pc_intx = SCR_PKT_INT_X; pkt_counters[j].pc_intx = SCR_PKT_INT_X + SCR_MIDDLE; pkt_counters[i].pc_inty = SCR_PKT_Y + i; pkt_counters[j].pc_inty = SCR_PKT_Y + i; pkt_counters[i].pc_totx = SCR_PKT_TOT_X; pkt_counters[j].pc_totx = SCR_PKT_TOT_X + SCR_MIDDLE; pkt_counters[i].pc_toty = SCR_PKT_Y + i; pkt_counters[j].pc_toty = SCR_PKT_Y + i; pkt_counters[i].pc_pctx = SCR_PKT_PCT_X; pkt_counters[j].pc_pctx = SCR_PKT_PCT_X + SCR_MIDDLE; pkt_counters[i].pc_pcty = SCR_PKT_Y + i; pkt_counters[j].pc_pcty = SCR_PKT_Y + i; } } /* * setup_nfs_counters- setup NFS counter screen coordinates, file system * names. */ void setup_nfs_counters(void) { #if defined(ultrix) || defined(__osf__) register int i, j; #endif FILE *fp; struct stat st; register NFSCounter *nc; #ifdef IRIX40 register struct mntent *mnt; #endif #ifdef SUNOS4 register struct mntent *mnt; #endif #ifdef SVR4 struct mnttab mnttab; register struct mnttab *mnt = &mnttab; #endif #ifdef ultrix int dummy, nmnts; static struct fs_data fsData[MAXEXPORT]; #endif #ifdef __osf__ int flags, nmnts; static struct statfs *mntbufp; #endif #ifdef LINUX struct mntent *mnt; #endif memset(nfs_counters, 0, MAXEXPORT * sizeof(NFSCounter)); /* * If we're not watching our own host, we can't look * for mounted file systems. */ if (strcmp(myhost, dsthost) != 0) { sort_nfs_counters(); learnfs = 1; return; } #ifdef IRIX40 /* * Open the list of mounted file systems. */ if ((fp = setmntent(MOUNTED, "r")) == NULL) { error(MOUNTED); finish(-1); } nc = nfs_counters; /* * Save the first MAXEXPORT file systems of type "4.2" * which have been exported. These are the ones which can * be mounted through NFS. */ while ((mnt = getmntent(fp)) != NULL) { if (strcmp(mnt->mnt_type, MNTTYPE_EFS) != 0 #ifdef MNTTYPE_XFS && strcmp(mnt->mnt_type, MNTTYPE_XFS) != 0 #endif #ifndef IRIX51 && strcmp(mnt->mnt_type, MNTTYPE_BELL) != 0 #endif ) continue; if (nnfscounters < MAXEXPORT) { if (stat(mnt->mnt_dir, &st) < 0) continue; /* * Not exported; skip it. */ if (!is_exported(st.st_dev)) continue; nc->nc_dev.Major = major(st.st_dev); nc->nc_dev.Minor = minor(st.st_dev); nc->nc_name = strdup(mnt->mnt_dir); nnfscounters++; nc++; } } (void) endmntent(fp); #endif /* IRIX40 */ #ifdef SUNOS4 /* * Open the list of mounted file systems. */ if ((fp = setmntent(MOUNTED, "r")) == NULL) { error(MOUNTED); finish(-1); } nc = nfs_counters; /* * Save the first MAXEXPORT file systems of type "4.2" * which have been exported. These are the ones which can * be mounted through NFS. */ while ((mnt = getmntent(fp)) != NULL) { if (strcmp(mnt->mnt_type, MNTTYPE_42) != 0 #ifdef MNTTYPE_PC && strcmp(mnt->mnt_type, MNTTYPE_PC) != 0 #endif && strcmp(mnt->mnt_type, "hsfs") != 0) continue; if (nnfscounters < MAXEXPORT) { if (stat(mnt->mnt_dir, &st) < 0) continue; /* * Not exported; skip it. */ if (!is_exported(st.st_dev)) continue; nc->nc_dev.Major = major(st.st_dev); nc->nc_dev.Minor = minor(st.st_dev); nc->nc_name = strdup(mnt->mnt_dir); nnfscounters++; nc++; } } (void) endmntent(fp); #endif /* SUNOS4 */ #ifdef SVR4 /* * Open the list of mounted file systems. */ if ((fp = fopen(MOUNTTABLE, "r")) == NULL) { error(MOUNTTABLE); finish(-1); } nc = nfs_counters; /* * Save the first MAXEXPORT file systems of type "ufs" or "sysv" * which have been shared. These are the ones which can * be mounted through NFS. */ while (getmntent(fp, mnt) == 0) { if (strcmp(mnt->mnt_fstype, "ufs") != 0 && strcmp(mnt->mnt_fstype, "hsfs") != 0 && strcmp(mnt->mnt_fstype, "pcfs") != 0 && strcmp(mnt->mnt_fstype, "sysv") != 0) continue; if (nnfscounters < MAXEXPORT) { if (stat(mnt->mnt_mountp, &st) < 0) continue; /* * Not exported; skip it. */ if (!is_exported(st.st_dev)) continue; #ifdef SUNOS5 nc->nc_dev.Major = getemajor(st.st_dev); nc->nc_dev.Minor = geteminor(st.st_dev); #else nc->nc_dev.Major = major(st.st_dev); nc->nc_dev.Minor = minor(st.st_dev); #endif nc->nc_name = strdup(mnt->mnt_mountp); nnfscounters++; nc++; } } (void) fclose(fp); #endif /* SVR4 */ #ifdef ultrix /* * Get the mounted file information. */ dummy = 0; nmnts = getmnt(&dummy, fsData, sizeof(fsData), NOSTAT_MANY, 0); if (nmnts < 0) { error("getmnt"); finish(-1); } nc = nfs_counters; /* * Save the first MAXEXPORT file systems which could have been * exported. These are what can be mounted through NFS. */ if (nmnts > MAXEXPORT) nmnts = MAXEXPORT; for (i=0; i < nmnts; i++) { if (fsData[i].fd_flags & M_LOCAL) { nc->nc_dev.Major = major(fsData[i].fd_dev); nc->nc_dev.Minor = minor(fsData[i].fd_dev); nc->nc_name = strdup(fsData[i].fd_path); nnfscounters++; nc++; } } #endif /* ultrix */ #ifdef __osf__ /* * Get the mounted file information. */ flags = MNT_NOWAIT; /* avoid hangups on dead NFS servers */ nmnts = getmntinfo(&mntbufp, flags); if (nmnts < 0) { error("getmntinfo"); finish(-1); } nc = nfs_counters; /* * Save the first MAXEXPORT file systems which could have been * exported. These are what can be mounted through NFS. */ for (i=0; i < nmnts; i++) { if (mntbufp[i].f_flags & M_LOCAL) { /* * This is cheating: fsid is "opaque" but we * know what it really holds ... */ u_long ldev; ldev = *(u_long *)&(mntbufp[i].f_fsid); nc->nc_dev.Major = major(ldev); nc->nc_dev.Minor = minor(ldev); nc->nc_name = strdup(mntbufp[i].f_mntonname); nnfscounters++; nc++; if ((nc - nfs_counters) > MAXEXPORT) break; } } #endif /* __osf__ */ #ifdef LINUX nc = nfs_counters; if (access("/var/lib/nfs/etab", R_OK) == 0) { char buf[PATH_MAX << 1]; /* * Open the list of exported file systems. */ if ((fp = fopen("/var/lib/nfs/etab", "r")) == NULL) { error("/var/lib/nfs/etab"); finish(-1); } while (fgets(buf, PATH_MAX << 1, fp) != NULL) { int i, j; char *s = strchr(buf, '\t'); if (s == NULL || buf[0] != '/') continue; *s = 0; for (i = 0; i < nnfscounters; i++) if (strcmp(buf, nfs_counters[i].nc_name) == 0) break; if (i < nnfscounters) continue; if ((s = strstr(s + 1, "fsid=")) != NULL) { /* I guess Major == 0 does not exist for a filesystem... */ nc->nc_dev.Minor = atoi(s + 5); nc->nc_name = strdup(buf); nnfscounters++; nc++; } else { if (stat(buf, &st) < 0) continue; /* * Not exported; skip it. */ if (!is_exported(st.st_dev)) continue; nc->nc_dev.Major = major(st.st_dev); nc->nc_dev.Minor = minor(st.st_dev); /* * Find common ancestor when Major and Minor are equal */ for (i = 0; i < nnfscounters; i++) if (nfs_counters[i].nc_dev.Major == nc->nc_dev.Major && nfs_counters[i].nc_dev.Minor == nc->nc_dev.Minor) break; if (i < nnfscounters) { j = 0; while (nfs_counters[i].nc_name[j] != 0 && buf[j] != 0 && nfs_counters[i].nc_name[j] == buf[j]) j += 1; while (nfs_counters[i].nc_name[j] != 0) if (j == 1 || nfs_counters[i].nc_name[j] == '/') nfs_counters[i].nc_name[j] = 0; else j -= 1; continue; } nc->nc_name = strdup(buf); nnfscounters++; nc++; } if (nnfscounters >= MAXEXPORT) break; } fclose(fp); } else { /* * Open the list of mounted file systems. */ if ((fp = setmntent(_PATH_MOUNTED, "r")) == NULL) { error(_PATH_MOUNTED); finish(-1); } while ((mnt = getmntent(fp)) != NULL) { if (strcmp(mnt->mnt_type, "proc") == 0 || strcmp(mnt->mnt_type, "devpts") == 0 || strcmp(mnt->mnt_type, "usbdevfs") == 0 || strcmp(mnt->mnt_type, "tmpfs") == 0) continue; if (nnfscounters < MAXEXPORT) { if (stat(mnt->mnt_dir, &st) < 0) continue; /* * Not exported; skip it. */ if (!is_exported(st.st_dev)) continue; nc->nc_dev.Major = major(st.st_dev); nc->nc_dev.Minor = minor(st.st_dev); nc->nc_name = strdup(mnt->mnt_dir); nnfscounters++; nc++; } } endmntent(fp); } #endif /* LINUX */ sort_nfs_counters(); } /* * sort_nfs_counters - sort and assign places on the screen */ void sort_nfs_counters(void) { register int i, j; (void) qsort(nfs_counters, nnfscounters, sizeof(NFSCounter), nfs_comp); /* * Set screen coordinates for the ones which will be * displayed. */ for (i = 0, j = NFSLINES/2; i < NFSLINES/2; i++, j++) { nfs_counters[i].nc_namex = SCR_NFS_NAME_X; nfs_counters[j].nc_namex = SCR_NFS_NAME_X + SCR_MIDDLE; nfs_counters[i].nc_namey = SCR_NFS_Y + i; nfs_counters[j].nc_namey = SCR_NFS_Y + i; nfs_counters[i].nc_intx = SCR_NFS_INT_X; nfs_counters[j].nc_intx = SCR_NFS_INT_X + SCR_MIDDLE; nfs_counters[i].nc_inty = SCR_NFS_Y + i; nfs_counters[j].nc_inty = SCR_NFS_Y + i; nfs_counters[i].nc_totx = SCR_NFS_TOT_X; nfs_counters[j].nc_totx = SCR_NFS_TOT_X + SCR_MIDDLE; nfs_counters[i].nc_toty = SCR_NFS_Y + i; nfs_counters[j].nc_toty = SCR_NFS_Y + i; nfs_counters[i].nc_pctx = SCR_NFS_PCT_X; nfs_counters[j].nc_pctx = SCR_NFS_PCT_X + SCR_MIDDLE; nfs_counters[i].nc_pcty = SCR_NFS_Y + i; nfs_counters[j].nc_pcty = SCR_NFS_Y + i; } } /* * setup_fil_counters- setup file counter stuff. */ void setup_fil_counters(void) { FILE *fp; struct stat st; register int i, j; char fname[MAXPATHLEN]; register FileCounter *fc; memset(fil_counters, 0, MAXEXPORT * sizeof(FileCounter)); /* * If we're not watching our own host, we can't look * for individual files. */ if (strcmp(myhost, dsthost) != 0) return; /* * Open the list of files to watch. */ if ((fp = fopen(filelist, "r")) == NULL) { error(filelist); finish(-1); } fc = fil_counters; /* * Save the first MAXEXPORT file systems of type "4.2" * which have been exported. These are the ones which can * be mounted through NFS. */ while (fgets(fname, sizeof(fname), fp) != NULL) { fname[strlen(fname)-1] = '\0'; if (nfilecounters < MAXEXPORT) { if (lstat(fname, &st) < 0) continue; #ifndef SVR4 /* * Not on an exported file system; skip it. */ if (!is_exported(st.st_dev)) { (void) fprintf(stderr, "warning: \"%s\" is not on an exported file system.\n", fname); continue; } #endif fc->fc_dev.Major = major(st.st_dev); fc->fc_dev.Minor = minor(st.st_dev); fc->fc_ino = st.st_ino; fc->fc_name = strdup(fname); nfilecounters++; fc++; } } (void) fclose(fp); (void) qsort(fil_counters, nfilecounters, sizeof(FileCounter), fil_comp); /* * Set screen coordinates for the ones which will be * displayed. */ for (i = 0, j = NFSLINES/2; i < NFSLINES/2; i++, j++) { fil_counters[i].fc_namex = SCR_NFS_NAME_X; fil_counters[j].fc_namex = SCR_NFS_NAME_X + SCR_MIDDLE; fil_counters[i].fc_namey = SCR_NFS_Y + i; fil_counters[j].fc_namey = SCR_NFS_Y + i; fil_counters[i].fc_intx = SCR_NFS_INT_X; fil_counters[j].fc_intx = SCR_NFS_INT_X + SCR_MIDDLE; fil_counters[i].fc_inty = SCR_NFS_Y + i; fil_counters[j].fc_inty = SCR_NFS_Y + i; fil_counters[i].fc_totx = SCR_NFS_TOT_X; fil_counters[j].fc_totx = SCR_NFS_TOT_X + SCR_MIDDLE; fil_counters[i].fc_toty = SCR_NFS_Y + i; fil_counters[j].fc_toty = SCR_NFS_Y + i; fil_counters[i].fc_pctx = SCR_NFS_PCT_X; fil_counters[j].fc_pctx = SCR_NFS_PCT_X + SCR_MIDDLE; fil_counters[i].fc_pcty = SCR_NFS_Y + i; fil_counters[j].fc_pcty = SCR_NFS_Y + i; } } /* * sort_prc_counters - sort and assign places on the screen */ void sort_prc_counters(void) { register int proto; register int i; register int numlines; (void) qsort(prc_counters[NFSv2], MAXNFSPROC, sizeof(ProcCounter), prc_comp); (void) qsort(prc_counters[NFSv3], MAXNFSPROC, sizeof(ProcCounter), prc_comp); /* Create indirection index */ for (proto = NFSv2; proto <= NFSHIGHPROTO; proto++) { for (i = 0; i < MAXNFSPROC; i++) { prc_countmap[proto][prc_counters[proto][i].pr_type] = i; } /* * Set screen coordinates for the ones which will be * displayed. * NOTE: Unlike other displays, this one has just one column! */ numlines = MAXNFS3PROC; /* pick the largest of all the protos */ if (NFSPROCLINES < numlines) numlines = NFSPROCLINES; for (i = 0; i < numlines; i++) { prc_counters[proto][i].pr_namex = SCR_NFS_NAME_X; prc_counters[proto][i].pr_namey = SCR_NFS_Y + i; prc_counters[proto][i].pr_intx = SCR_NFS_INT_X; prc_counters[proto][i].pr_inty = SCR_NFS_Y + i; prc_counters[proto][i].pr_totx = SCR_NFS_TOT_X; prc_counters[proto][i].pr_toty = SCR_NFS_Y + i; prc_counters[proto][i].pr_pctx = SCR_NFS_PCT_X; prc_counters[proto][i].pr_pcty = SCR_NFS_Y + i; prc_counters[proto][i].pr_compx = SCR_NFS_COMP_X; prc_counters[proto][i].pr_compy = SCR_NFS_Y + i; prc_counters[proto][i].pr_respx = SCR_NFS_RESP_X; prc_counters[proto][i].pr_respy = SCR_NFS_Y + i; prc_counters[proto][i].pr_rsqrx = SCR_NFS_RSQR_X; prc_counters[proto][i].pr_rsqry = SCR_NFS_Y + i; prc_counters[proto][i].pr_rmaxx = SCR_NFS_RMAX_X; prc_counters[proto][i].pr_rmaxy = SCR_NFS_Y + i; } } } /* * setup_proc_counters- setup procedure counter stuff. */ void setup_proc_counters(void) { register int i; memset(prc_counters, 0, MAXNFSPROC * sizeof(ProcCounter) * NFSHIGHPROTO); for (i = 0; i < MAXNFSPROC; i++) { prc_counters[NFSv2][i].pr_type = i; prc_counters[NFSv2][i].pr_name = nfs_procnams[NFSv2][i]; } for (i = 0; i < MAXNFS3PROC; i++) { prc_counters[NFSv3][i].pr_type = i; prc_counters[NFSv3][i].pr_name = nfs_procnams[NFSv3][i]; } sort_prc_counters(); } /* * sort_clnt_counters - sort and assign places on the screen */ void sort_clnt_counters(void) { register int i, j; register int numlines; (void) qsort(clnt_counters, nclientcounters, sizeof(ClientCounter), clnt_comp); ClientHashRebuild(); /* * Set screen coordinates for the ones which will be * displayed. */ numlines = nclientcounters; if (numlines & 1) /* round up to even number; nfswatch.h */ numlines++; /* must set MAXCLIENTS to even number */ if (NFSLINES < numlines) numlines = NFSLINES; for (i = 0, j = numlines/2; i < numlines/2; i++, j++) { clnt_counters[i].cl_namex = SCR_NFS_NAME_X; clnt_counters[j].cl_namex = SCR_NFS_NAME_X + SCR_MIDDLE; clnt_counters[i].cl_namey = SCR_NFS_Y + i; clnt_counters[j].cl_namey = SCR_NFS_Y + i; clnt_counters[i].cl_intx = SCR_NFS_INT_X; clnt_counters[j].cl_intx = SCR_NFS_INT_X + SCR_MIDDLE; clnt_counters[i].cl_inty = SCR_NFS_Y + i; clnt_counters[j].cl_inty = SCR_NFS_Y + i; clnt_counters[i].cl_totx = SCR_NFS_TOT_X; clnt_counters[j].cl_totx = SCR_NFS_TOT_X + SCR_MIDDLE; clnt_counters[i].cl_toty = SCR_NFS_Y + i; clnt_counters[j].cl_toty = SCR_NFS_Y + i; clnt_counters[i].cl_pctx = SCR_NFS_PCT_X; clnt_counters[j].cl_pctx = SCR_NFS_PCT_X + SCR_MIDDLE; clnt_counters[i].cl_pcty = SCR_NFS_Y + i; clnt_counters[j].cl_pcty = SCR_NFS_Y + i; } } /* * setup_clnt_counters- setup client counter stuff. */ void setup_clnt_counters(void) { memset(clnt_counters, 0, MAXCLIENTS * sizeof(ClientCounter)); sort_clnt_counters(); } /* * sort_auth_counters - sort and assign places on the screen. */ void sort_auth_counters(void) { register int i, j; register int numlines; (void) qsort(auth_counters, nauthcounters, sizeof(AuthCounter), auth_comp); /* * Set screen coordinates for the ones which will be displayed. */ numlines = nauthcounters; if (numlines & 1) numlines++; if (NFSLINES < numlines) numlines = NFSLINES; for (i = 0, j = numlines / 2; i < numlines / 2; i++, j++) { auth_counters[i].ac_namex = SCR_NFS_NAME_X; auth_counters[j].ac_namex = SCR_NFS_NAME_X + SCR_MIDDLE; auth_counters[i].ac_namey = SCR_NFS_Y + i; auth_counters[j].ac_namey = SCR_NFS_Y + i; auth_counters[i].ac_intx = SCR_NFS_INT_X; auth_counters[j].ac_intx = SCR_NFS_INT_X + SCR_MIDDLE; auth_counters[i].ac_inty = SCR_NFS_Y + i; auth_counters[j].ac_inty = SCR_NFS_Y + i; auth_counters[i].ac_totx = SCR_NFS_TOT_X; auth_counters[j].ac_totx = SCR_NFS_TOT_X + SCR_MIDDLE; auth_counters[i].ac_toty = SCR_NFS_Y + i; auth_counters[j].ac_toty = SCR_NFS_Y + i; auth_counters[i].ac_pctx = SCR_NFS_PCT_X; auth_counters[j].ac_pctx = SCR_NFS_PCT_X + SCR_MIDDLE; auth_counters[i].ac_pcty = SCR_NFS_Y + i; auth_counters[j].ac_pcty = SCR_NFS_Y + i; } } /* * auth_comp - compare authentication counters for qsort. */ static int auth_comp(const void *pa, const void *pb) { AuthCounter *a = (AuthCounter *) pa; AuthCounter *b = (AuthCounter *) pb; if (sortbyusage) { if ((long) b->ac_interval == (long) a->ac_interval) return((long) b->ac_total - (long) a->ac_total); else return((long) b->ac_interval - (long) a->ac_interval); } else { return(strcmp(a->ac_name, b->ac_name)); } } /* * is_exported - return whether or not a file system is exported. */ #ifdef SUNOS4 static int is_exported(dev_t dev) { FILE *fp; struct stat st; register dev_t *exp; static int nexported = -1; register struct exportent *xent; static dev_t exported[MAXEXPORT]; /* * First time through, read the export table and * save all the device numbers. */ if (nexported < 0) { /* * If there's no export file, it must * not be exported. */ if ((fp = setexportent(TABFILE)) == NULL) return(FALSE); nexported = 0; while ((xent = getexportent(fp)) != NULL) { if (stat(xent->xent_dirname, &st) < 0) continue; if (nexported < MAXEXPORT) exported[nexported++] = st.st_dev; } (void) endexportent(fp); } /* * Search the exported device numbers for this device number. */ for (exp = exported; exp < &exported[nexported]; exp++) { if (dev == *exp) return(TRUE); } return(FALSE); } #endif /* SUNOS4 */ #ifdef SVR4 static int is_exported(dev_t dev) { FILE *fp; register int i; struct stat st; static int nshared = -1; static dev_t shared[MAXEXPORT]; char line[BUFSIZ], path[BUFSIZ]; if (nshared < 0) { nshared = 0; if ((fp = fopen(SHARETAB, "r")) == NULL) return(0); while (fgets(line, sizeof(line), fp) != NULL) { if (*line == '#' || *line == '\n') continue; sscanf(line, "%s", path); if (stat(path, &st) < 0) continue; if (nshared < MAXEXPORT) shared[nshared++] = st.st_dev; } fclose(fp); } for (i=0; i < nshared; i++) { if (shared[i] == dev) return(1); } return(0); } #endif /* SVR4 */ #if defined(sgi) || defined(ultrix) || defined(__osf__) || defined(LINUX) static int is_exported(dev_t dev #if defined(__GNUC__) && !defined(__APPLE_CC__) __attribute__ ((unused)) #endif ) { return(TRUE); } #endif /* * nfs_comp - compare NFS counters for qsort. */ static int nfs_comp(const void *pa, const void *pb) { NFSCounter *a = (NFSCounter *) pa; NFSCounter *b = (NFSCounter *) pb; if (sortbyusage) { if (((long)b->nc_interval) == ((long)a->nc_interval)) return(((long)b->nc_total) - ((long)a->nc_total)); else return(((long)b->nc_interval) - ((long)a->nc_interval)); } else return(strcmp(a->nc_name, b->nc_name)); } /* * fil_comp = compare file counters for qsort. */ static int fil_comp(const void *pa, const void *pb) { FileCounter *a = (FileCounter *) pa; FileCounter *b = (FileCounter *) pb; if (sortbyusage) { if (((long)b->fc_interval) == ((long)a->fc_interval)) return(((long)b->fc_total) - ((long)a->fc_total)); else return(((long)b->fc_interval) - ((long)a->fc_interval)); } else return(strcmp(a->fc_name, b->fc_name)); } /* * prc_comp - compare procedure counters for qsort. */ static int prc_comp(const void *pa, const void *pb) { ProcCounter *a = (ProcCounter *) pa; ProcCounter *b = (ProcCounter *) pb; if (sortbyusage) { if (((long)b->pr_interval) == ((long)a->pr_interval)) return(((long)b->pr_total) - ((long)a->pr_total)); else return(((long)b->pr_interval) - ((long)a->pr_interval)); } else return(strcmp(a->pr_name, b->pr_name)); } /* * clnt_comp - compare client counters for qsort. */ static int clnt_comp(const void *pa, const void *pb) { ClientCounter *a = (ClientCounter *) pa; ClientCounter *b = (ClientCounter *) pb; if (sortbyusage) { if (((long)b->cl_interval) == ((long)a->cl_interval)) return(((long)b->cl_total) - ((long)a->cl_total)); else return(((long)b->cl_interval) - ((long)a->cl_interval)); } else return(strcmp(a->cl_name, b->cl_name)); } /* * usage - print a usage message and exit. */ void usage(void) { fprintf(stderr, "Usage: %s [-dst host] [-src host]", pname); fprintf(stderr, " [-server host] [-all] [-dev device]\n"); fprintf(stderr, " [-allif] [-f filelist] [-lf logfile] "); fprintf(stderr, " [-sf snapfile] [-map mapfile]\n"); fprintf(stderr, " [-T maxtime] [-t timeout] [-fs]"); fprintf(stderr, " [-if] [-auth] [-procs] [-procs3] [-clients]\n"); fprintf(stderr, " [-usage] [-l] [-bg]\n"); finish(-1); } /* * wakeup - wake up for a screen update. */ void wakeup(int sig #if defined(__GNUC__) && !defined(__APPLE_CC__) __attribute__ ((unused)) #endif ) { struct timeval tv; /* * See if we've exceeded the total time to run. */ gettimeofday(&tv, 0); if ((totaltime > 0) && ((tv.tv_sec - starttime.tv_sec) > totaltime)) finish(0); /* * Re-sort and re-do the labels. */ if (sortbyusage) { sort_nfs_counters(); sort_prc_counters(); sort_clnt_counters(); sort_auth_counters(); } if (!bgflag) { label_screen(); update_screen(); } if (logging) update_logfile(); clear_vars(); } /* * dlt_name - return string giving name for a data link type code */ char * dlt_name(int dlt) { switch(dlt) { case DLT_NULL: return("no link-layer encapsulation"); case DLT_EN10MB: return("Ethernet"); case DLT_EN3MB: return("Experimental Ethernet"); case DLT_AX25: return("Amateur Radio AX.25"); case DLT_PRONET: return("ProNET"); case DLT_CHAOS: return("Chaosnet"); case DLT_IEEE802: return("IEEE802"); case DLT_ARCNET: return("ARCNET"); case DLT_SLIP: return("SLIP"); case DLT_PPP: return("PPP"); case DLT_FDDI: return("FDDI"); default: return("[unknown LAN type]"); } } static int nummap = 0; static char *fs_maps[1024]; void setup_map_file(void) { int len; FILE *fp; char fs[BUFSIZ], alias[BUFSIZ]; char line[BUFSIZ], trans[BUFSIZ]; if ((fp = fopen(mapfile, "r")) == NULL) { error(mapfile); finish(-1); } while (fgets(line, sizeof(line), fp) != NULL) { if (sscanf(line, "%s %s", fs, alias) != 2) continue; strcpy(trans, fs); len = strlen(fs) + 1; strcpy(trans + len, alias); len += strlen(alias) + 1; if ((fs_maps[nummap] = malloc(len)) == NULL) { (void) fprintf(stderr, "%s: out of memory.\n", pname); finish(-1); } bcopy(trans, fs_maps[nummap], len); nummap++; } fclose(fp); } char * map_fs_name(char *fs) { int i; for (i=0; i < nummap; i++) { if (strcmp(fs, fs_maps[i]) == 0) return(fs_maps[i] + strlen(fs_maps[i]) + 1); } return(fs); } nfswatch-4.99.11/dlpi.c0000644000551200011300000002612110575316253013776 0ustar chrisludwig/* * $Id: dlpi.c,v 1.8 2007/03/12 18:32:11 c4chris Exp $ */ #include "os.h" #ifdef USE_DLPI /* * dpli.c - routines for messing with the Data Link Provider Interface. * * The code in this module is based in large part (especially the dl* * routines) on the example code provided with the document "How to Use * DLPI", by Neal Nuckolls of Sun Internet Engineering. Gotta give credit * where credit is due. If it weren't for Neal's excellent document, * this module just plain wouldn't exist. * * David A. Curry * Purdue University * Engineering Computer Network * 1285 Electrical Engineering Building * West Lafayette, IN 47907-1285 * davy@ecn.purdue.edu * */ #include #include #include #include #ifdef SUNOS5 #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "nfswatch.h" #include "externs.h" static void dlbindreq(); static void dlinforeq(); static void dlattachreq(); static void dlpromisconreq(); static void sigalrm(); static int dlokack(); static int dlinfoack(); static int dlbindack(); static int expecting(); static int strgetmsg(); /* * setup_dlpi_dev - set up the data link provider interface. */ int setup_dlpi_dev(device) char **device; { char *p; u_int chunksz; char cbuf[BUFSIZ]; struct ifconf ifc; struct ifreq *ifrp; struct strioctl si; char devname[BUFSIZ]; int n, s, fd, devppa; struct timeval timeout; long buf[DLPI_MAXDLBUF]; /* * If the interface device was not specified, * get the default one. */ if (*device == NULL) { /* * Grab a socket. */ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { error("socket"); finish(-1); } ifc.ifc_buf = cbuf; ifc.ifc_len = sizeof(cbuf); /* * See what devices we've got. */ if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) { error("ioctl: SIOCGIFCONF"); finish(-1); } /* * Take the first device we encounter. */ ifrp = ifc.ifc_req; for (n = ifc.ifc_len/sizeof(struct ifreq); n > 0; n--,ifrp++) { /* * Skip the loopback interface. */ if (strcmp(ifrp->ifr_name, "lo0") == 0) continue; *device = strdup(ifrp->ifr_name); break; } (void) close(s); } /* * Split the device name into type and unit number. */ p = *device + strlen(*device); while (p > *device && isdigit(*(p - 1))) p -= 1; if (p == *device) return(-1); strcpy(devname, DLPI_DEVDIR); strncat(devname, *device, p - *device); devppa = atoi(p); /* * Open the device. */ if ((fd = open(devname, O_RDWR)) < 0) { if (errno == ENOENT || errno == ENXIO) return(-1); error(devname); finish(-1); } /* * Attach to the device. If this fails, the device * does not exist. */ dlattachreq(fd, devppa); if (dlokack(fd, buf) < 0) { close(fd); return(-1); } /* * We want the ethernet in promiscuous mode if we're looking * at nodes other than ourselves. */ if (allflag || dstflag) { #ifdef DL_PROMISC_PHYS dlpromisconreq(fd, DL_PROMISC_PHYS); if (dlokack(fd, buf) < 0) { fprintf(stderr, "%s: DL_PROMISC_PHYS failed.\n", pname); finish(-1); } #else fprintf(stderr, "%s: DLPI 1.3 does not support promiscuous ", pname); fprintf(stderr, "mode operation.\n"); fprintf(stderr, "%s: cannot implement -all or -dst options.\n", pname); finish(-1); #endif } /* * Bind to the specific unit. */ dlbindreq(fd, DLPI_DEFAULTSAP, 0, DL_CLDLS, 0, 0); if (dlbindack(fd, buf) < 0) { fprintf(stderr, "%s: dlbindack failed.\n", pname); finish(-1); } #ifdef SUNOS5 /* * We really want all types of packets. However, the SVR4 DLPI does * not let you have the packet frame header, so we won't be able to * distinguish protocol types. But SunOS5 gives you the DLIOCRAW * ioctl to get the frame headers, so we can do this on SunOS5. */ dlpromisconreq(fd, DL_PROMISC_SAP); if (dlokack(fd, buf) < 0) { fprintf(stderr, "%s: DL_PROMISC_SAP failed.\n", pname); finish(-1); } /* * We want raw packets with the packet frame header. But we can * only get this in SunOS5 with the DLIOCRAW ioctl; it's not in * standard SVR4. */ si.ic_cmd = DLIOCRAW; si.ic_timout = -1; si.ic_len = 0; si.ic_dp = 0; if (ioctl(fd, I_STR, &si) < 0) { error("ioctl: I_STR DLIOCRAW"); finish(-1); } #endif /* SUNOS5 */ /* * Arrange to get discrete messages. */ if (ioctl(fd, I_SRDOPT, (char *) RMSGD) < 0) { error("ioctl: I_SRDOPT RMSGD"); finish(-1); } #ifdef SUNOS5 /* * Push and configure the streams buffering module. This is once * again SunOS-specific. */ if (ioctl(fd, I_PUSH, DLPI_BUFMOD) < 0) { error("ioctl: I_PUSH BUFMOD"); finish(-1); } /* * Set the read timeout. */ timeout.tv_sec = 1; timeout.tv_usec = 0; si.ic_cmd = SBIOCSTIME; si.ic_timout = INFTIM; si.ic_len = sizeof(timeout); si.ic_dp = (char *) &timeout; if (ioctl(fd, I_STR, (char *) &si) < 0) { error("ioctl: I_STR SBIOCSTIME"); finish(-1); } /* * Set the chunk size. */ chunksz = DLPI_CHUNKSIZE; si.ic_cmd = SBIOCSCHUNK; si.ic_len = sizeof(chunksz); si.ic_dp = (char *) &chunksz; if (ioctl(fd, I_STR, (char *) &si) < 0) { error("ioctl: I_STR SBIOCSCHUNK"); finish(-1); } /* * Set snapshot mode. */ si.ic_cmd = SBIOCSSNAP; si.ic_len = sizeof(truncation); si.ic_dp = (char *) &truncation; if (ioctl(fd, I_STR, (char *) &si) < 0) { error("ioctl: I_STR SBIOCSSNAP"); finish(-1); } #endif /* SUNOS5 */ return(fd); } /* * flush_dlpi - flush data from the dlpi. */ void flush_dlpi(fd) int fd; { if (ioctl(fd, I_FLUSH, (char *) FLUSHR) < 0) { error("ioctl: I_FLUSH"); finish(-1); } } /* * dlpi_devtype - determine the type of device we're looking at. */ int dlpi_devtype(fd) int fd; { long buf[DLPI_MAXDLBUF]; union DL_primitives *dlp; dlp = (union DL_primitives *) buf; dlinforeq(fd); if (dlinfoack(fd, buf) < 0) return(DLT_EN10MB); switch (dlp->info_ack.dl_mac_type) { case DL_CSMACD: case DL_ETHER: return(DLT_EN10MB); #ifdef DL_FDDI case DL_FDDI: return(DLT_FDDI); #endif default: fprintf(stderr, #ifdef _LP64 "%s: DLPI MACtype %d unknown, ", #else "%s: DLPI MACtype %ld unknown, ", #endif pname, dlp->info_ack.dl_mac_type); fprintf(stderr, "assuming ethernet.\n"); return(DLT_EN10MB); } } /* * dlinforeq - request information about the data link provider. */ static void dlinforeq(fd) int fd; { dl_info_req_t info_req; struct strbuf ctl; int flags; info_req.dl_primitive = DL_INFO_REQ; ctl.maxlen = 0; ctl.len = sizeof (info_req); ctl.buf = (char *) &info_req; flags = RS_HIPRI; if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) { error("putmsg"); finish(-1); } } /* * dlattachreq - send a request to attach. */ static void dlattachreq(fd, ppa) u_long ppa; int fd; { dl_attach_req_t attach_req; struct strbuf ctl; int flags; attach_req.dl_primitive = DL_ATTACH_REQ; attach_req.dl_ppa = ppa; ctl.maxlen = 0; ctl.len = sizeof (attach_req); ctl.buf = (char *) &attach_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) { error("putmsg"); finish(-1); } } #ifdef DL_PROMISCON_REQ /* * dlpromisconreq - send a request to turn promiscuous mode on. */ static void dlpromisconreq(fd, level) u_long level; int fd; { dl_promiscon_req_t promiscon_req; struct strbuf ctl; int flags; promiscon_req.dl_primitive = DL_PROMISCON_REQ; promiscon_req.dl_level = level; ctl.maxlen = 0; ctl.len = sizeof (promiscon_req); ctl.buf = (char *) &promiscon_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) { error("putmsg"); finish(-1); } } #endif /* DL_PROMISCON_REQ */ /* * dlbindreq - send a request to bind. */ static void dlbindreq(fd, sap, max_conind, service_mode, conn_mgmt, xidtest) u_long sap, max_conind, service_mode, conn_mgmt, xidtest; int fd; { dl_bind_req_t bind_req; struct strbuf ctl; int flags; bind_req.dl_primitive = DL_BIND_REQ; bind_req.dl_sap = sap; bind_req.dl_max_conind = max_conind; bind_req.dl_service_mode = service_mode; bind_req.dl_conn_mgmt = conn_mgmt; #ifdef DL_PROMISC_PHYS /* * DLPI 2.0 only? */ bind_req.dl_xidtest_flg = xidtest; #endif ctl.maxlen = 0; ctl.len = sizeof (bind_req); ctl.buf = (char *) &bind_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) { error("putmsg"); finish(-1); } } /* * dlokack - general acknowledgement reception. */ static int dlokack(fd, bufp) char *bufp; int fd; { union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = DLPI_MAXDLBUF; ctl.len = 0; ctl.buf = bufp; if (strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) return(-1); dlp = (union DL_primitives *) ctl.buf; if (expecting(DL_OK_ACK, dlp) < 0) return(-1); if ((unsigned int) ctl.len < sizeof (dl_ok_ack_t)) return(-1); if (flags != RS_HIPRI) return(-1); if ((unsigned int) ctl.len < sizeof (dl_ok_ack_t)) return(-1); return(0); } /* * dlinfoack - receive an ack to a dlinforeq. */ static int dlinfoack(fd, bufp) char *bufp; int fd; { union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = DLPI_MAXDLBUF; ctl.len = 0; ctl.buf = bufp; if (strgetmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) return(-1); dlp = (union DL_primitives *) ctl.buf; if (expecting(DL_INFO_ACK, dlp) < 0) return(-1); if ((unsigned int) ctl.len < sizeof (dl_info_ack_t)) return(-1); if (flags != RS_HIPRI) return(-1); if ((unsigned int) ctl.len < sizeof (dl_info_ack_t)) return(-1); return(0); } /* * dlbindack - receive an ack to a dlbindreq. */ static int dlbindack(fd, bufp) char *bufp; int fd; { union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = DLPI_MAXDLBUF; ctl.len = 0; ctl.buf = bufp; if (strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) return(-1); dlp = (union DL_primitives *) ctl.buf; if (expecting(DL_BIND_ACK, dlp) < 0) return(-1); if (flags != RS_HIPRI) return(-1); if ((unsigned int) ctl.len < sizeof (dl_bind_ack_t)) return(-1); return(0); } /* * expecting - see if we got what we wanted. */ static int expecting(prim, dlp) union DL_primitives *dlp; int prim; { if (dlp->dl_primitive != (u_long)prim) return(-1); return(0); } /* * strgetmsg - get a message from a stream, with timeout. */ static int strgetmsg(fd, ctlp, datap, flagsp) struct strbuf *ctlp, *datap; int *flagsp; int fd; { int rc; /* * Start timer. */ (void) sigset(SIGALRM, sigalrm); alarm(DLPI_MAXWAIT); /* * Set flags argument and issue getmsg(). */ *flagsp = 0; if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) { error("getmsg"); finish(-1); } /* * Stop timer. */ alarm(0); /* * Check for MOREDATA and/or MORECTL. */ if ((rc & (MORECTL | MOREDATA)) == (MORECTL | MOREDATA)) return(-1); if (rc & MORECTL) return(-1); if (rc & MOREDATA) return(-1); /* * Check for at least sizeof (long) control data portion. */ if ((unsigned int) (ctlp->len) < sizeof (long)) return(-1); return(0); } /* * sigalrm - handle alarms. */ static void sigalrm() { (void) fprintf(stderr, "dlpi: timeout\n"); } #endif /* USE_DLPI */ nfswatch-4.99.11/pfopen.c0000644000551200011300000000005710177737456014347 0ustar chrisludwig#include "/usr/examples/packetfilter/pfopen.c" nfswatch-4.99.11/externs.h0000644000551200011300000000730411142036746014542 0ustar chrisludwig/* * $Id: externs.h,v 1.11 2009/02/03 12:51:50 c4chris Exp $ * * externs.h - external definitons for nfswatch. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ extern char *pname; extern FILE *logfp; extern Counter pkt_total; extern Counter pkt_drops; extern Counter int_pkt_total; extern Counter int_pkt_drops; extern Counter dst_pkt_total; extern Counter int_dst_pkt_total; extern int errno; extern int bgflag; #ifdef USE_LINUX extern linux_socket_handle_t ls; #else extern int if_fd[]; #endif extern int allintf; extern int fhdebugf; extern int dstflag; extern int srcflag; extern int allflag; extern int logging; extern int learnfs; extern int if_dlt[]; extern int do_update; extern int cycletime; extern int totaltime; extern int showwhich; extern int serverflag; extern unsigned int truncation; #ifndef USE_LINUX extern int ninterfaces; #endif extern int sortbyusage; extern int nnfscounters; extern int nfilecounters; extern int nauthcounters; extern int screen_inited; extern int nclientcounters; extern ipaddrt thisdst; extern ipaddrt srcaddrs[]; extern ipaddrt dstaddrs[]; extern ipaddrt serveraddrs[]; extern struct timeval starttime; extern char myhost[]; extern char srchost[]; extern char dsthost[]; extern char serverhost[]; extern char *prompt; extern char *logfile; extern char *mapfile; extern char *filelist; extern char *snapshotfile; extern NFSCounter nfs_counters[]; extern FileCounter fil_counters[]; extern PacketCounter pkt_counters[]; extern ProcCounter prc_counters[NFSHIGHPROTO + 1][MAXNFS3PROC + 2]; extern int prc_countmap[NFSHIGHPROTO + 1][MAXNFS3PROC]; extern char* nfs_procnams[NFSHIGHPROTO + 1][MAXNFS3PROC]; extern ClientCounter clnt_counters[]; extern AuthCounter auth_counters[]; extern NFSCall nfs_calls[NFSCALLHASHSIZE]; extern unsigned long *rpcPort; extern unsigned int rpcPortCnt; int dlpi_devtype(); int nit_devtype(); int pfilt_devtype(); int setup_nit_dev(); int setup_dlpi_dev(); int setup_pfilt_dev(); int setup_snoop_dev(); int snoop_devtype(); void flush_nit(); void flush_dlpi(); void flush_pfilt(); void flush_snoop(); void setup_auth_counters(); void get_rpc_ports(void); #ifdef USE_LINUX int setup_linux_dev(char **, linux_socket_handle_p_t); int linux_read_packet(linux_socket_handle_p_t); #endif void ClientHashRebuild(void); void Parse_fh(caddr_t *, my_fsid *, ino_t *, char **, char **, int); char *map_fs_name(char *); void snapshot(void); void update_logfile(void); void get_net_addrs(void); int want_packet(ipaddrt, ipaddrt); int to_self(ipaddrt); #ifdef SUNOS5 void pkt_dispatch(char *, int, u_short, struct timeval *); #endif void pkt_filter_ether(char *, u_int, struct timeval *); void pkt_filter_fddi(char *, u_int, struct timeval *); void pkt_filter_sll(char *, u_int, struct timeval *); void rpc_filter(char *, u_int, ipaddrt, ipaddrt, struct timeval *); void setup_rpcxdr(void); void setup_screen(char *); void label_screen(void); void update_screen(void); void command(void); char *prtime(time_t); void error(char *); void finish(int); void setup_pkt_counters(void); void setup_nfs_counters(void); void sort_nfs_counters(void); void setup_fil_counters(void); void sort_prc_counters(void); void sort_prc3_counters(void); void setup_proc_counters(void); void sort_clnt_counters(void); void setup_clnt_counters(void); void sort_auth_counters(void); void usage(void); void wakeup(int); char *dlt_name(int); void setup_map_file(void); nfswatch-4.99.11/nfswatch.h0000644000551200011300000002436611364242300014665 0ustar chrisludwig/* * $Id: nfswatch.h,v 1.21 2010/04/23 06:57:04 c4chris Exp $ * * nfswatch.h - definitions for nfswatch. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * */ /* * Version number. */ #define VERSION "4.99.11 of 23 April 2010" /* * Stuff for representing NFS file handles */ #include "nfsfh.h" /* * General definitions. */ #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif /* * we waste some array space by leaving "holes" with these defines, * but it makes it cleaner */ #define NFSv2 2 #define NFSv3 3 #define NFSv4 4 #define NFSHIGHPROTO NFSv4 /* * Declarations of several data types that must be 32 bits wide, * no matter what machine we are running on. "long" is unsafe * because on DEC Alpha machines that means 64 bits. "int" is * unsafe because on some machines that means 16 bits. * * Use int32 or u_int32 whenever you mean "32 bits" and not * "some large number of bits". * * NEVER use int or int32 or u_int32 (or, for that matter, long) * when the variable might contain a pointer value. */ #if defined(pdp11) /* other 16-bit machines? */ typedef long int32; typedef unsigned long u_int32; #else /* works almost everywhere */ #if !defined(SUNOS54) /* SunOS 5.4 declares int32 in */ typedef int int32; #endif #if !defined(U_INT32_DECLARED_IN_AUTH) || !defined(AUTH_UNIX) /* SunOS declares u_int32 in */ typedef unsigned int u_int32; #endif #endif /* Define a specific type for representing IP addresses */ typedef u_int32 ipaddrt; #ifdef SVR4 #define MOUNTTABLE "/etc/mnttab" /* mounted file systems */ #define SHARETAB "/etc/dfs/sharetab" /* shared file systems */ #endif #define PROMPT "nfswatch>" /* prompt string */ #define LOGFILE "nfswatch.log" /* log file name */ #define MAXEXPORT 1024 /* max exported file systems */ #define CYCLETIME 10 /* screen update cycle time */ #define PACKETSIZE 65536 /* max size of a packet */ #define MAXNFSPROC 18 /* max number of NFS procedures */ #define MAXNFS3PROC 22 /* max number of NFS3 procedures */ #define MAXHOSTADDR 16 /* max. network addrs per host */ #define MAXCLIENTS 1024 /* max. # of client counters */ /* MUST be even number */ #define MAXAUTHS 1024 /* max. # of auth counters */ /* MUST be even number */ #define MAXINTERFACES 16 /* Max. number of interfaces */ #define SNAPSHOTFILE "nfswatch.snap" /* snapshot file name */ #define MAXUSERNAMELEN 128 /* max size of username */ #define SHOWINDVFILES 1 /* show individual files */ #define SHOWFILESYSTEM 2 /* show NFS file systems */ #define SHOWNFSPROCS 3 /* show NFS procedure counts */ #define SHOWNFS3PROCS 4 /* show NFS procedure counts */ #define SHOWCLIENTS 5 /* show client host names */ #define SHOWAUTH 6 /* show authorizations */ #define SHOWHELP 7 /* show help text */ #define SHOW_MAXCODE 7 /* number of different displays */ /* * Network Interface Tap (NIT) definitions. */ #ifdef USE_NIT #define NIT_DEV "/dev/nit" /* network interface tap device */ #define NIT_BUF "nbuf" /* nit stream buffering module */ #define NIT_CHUNKSIZE 8192 /* chunk size for grabbing pkts */ #endif /* * Pfilt definitions. */ #ifdef USE_PFILT #define PFILT_CHUNKSIZE 8192 /* chunk size for grabbing pkts */ #endif /* * Snoop definitions. */ #ifdef USE_SNOOP #define SNOOP_BUFFER_SIZE (55 * 1024) /* for grabbing packets */ #endif /* * Data Link Provider Interface (DLPI) definitions. */ #ifdef USE_DLPI #define DLPI_DEVDIR "/dev/" /* path to device dir */ #define DLPI_BUFMOD "bufmod" /* streams buffering */ #define DLPI_MAXWAIT 15 /* max timeout */ #define DLPI_MAXDLBUF 8192 /* buffer size */ #define DLPI_MAXDLADDR 1024 /* max address size */ #define DLPI_CHUNKSIZE (8192 * sizeof(long)) /* buffer size */ #define DLPI_DEFAULTSAP 0x0800 /* IP protocol */ #endif /* USE_DLPI */ /* * Packet counter definitions. */ #define PKT_NCOUNTERS 16 /* number of packet counters */ #define PKT_NFS3READ 0 /* NFS3 read requests */ #define PKT_NFS3WRITE 1 /* NFS3 write requests */ #define PKT_NFSREAD 2 /* NFS read requests */ #define PKT_NFSWRITE 3 /* NFS write requests */ #define PKT_NFSMOUNT 4 /* NFS mount requests */ #define PKT_PORTMAP 5 /* port mapper requests */ #define PKT_RPCAUTH 6 /* RPC authorization requests */ #define PKT_OTHERRPC 7 /* other RPC requests */ #define PKT_TCP 8 /* TCP packets */ #define PKT_UDP 9 /* UDP packets */ #define PKT_ICMP 10 /* ICMP packets */ #define PKT_ROUTING 11 /* routing control packets */ #define PKT_ARP 12 /* address resolution packets */ #define PKT_RARP 13 /* reverse addr resol packets */ #define PKT_BROADCAST 14 /* ethernet broadcast packets */ #define PKT_OTHER 15 /* none of the above packets */ typedef unsigned long Counter; /* * Packet counting structure. */ typedef struct { char *pc_name; /* name of counter */ Counter pc_interval; /* packets this interval */ Counter pc_total; /* packets since start */ short pc_intx, pc_inty; /* screen coords of pc_interval */ short pc_totx, pc_toty; /* screen coords of pc_total */ short pc_pctx, pc_pcty; /* screen coords of percentage */ short pc_namex, pc_namey; /* screen coords of pc_name */ } PacketCounter; /* * NFS request counting structure. */ typedef struct { my_devt nc_dev; /* device numbers of file sys */ my_fsid nc_fsid; /* for "learning" file systems */ ipaddrt nc_ipaddr; /* keep track of server address */ char *nc_name; /* name of file system */ Counter nc_total; /* requests since start */ Counter nc_interval; /* requests this interval */ Counter nc_proc[MAXNFS3PROC]; /* each nfs proc counters */ short nc_intx, nc_inty; /* screen coords of nc_interval */ short nc_totx, nc_toty; /* screen coords of nc_total */ short nc_pctx, nc_pcty; /* screen coords of percentage */ short nc_namex, nc_namey; /* screen coords of nc_name */ } NFSCounter; /* * Specific file request counting structure. */ typedef struct { my_devt fc_dev; /* device number of file sys */ ino_t fc_ino; /* inode number of file */ char *fc_name; /* file name */ Counter fc_total; /* requests since start */ Counter fc_interval; /* requests this interval */ Counter fc_proc[MAXNFS3PROC]; /* each nfs proc counters */ short fc_intx, fc_inty; /* screen coords of fc_interval */ short fc_totx, fc_toty; /* screen coords of fc_total */ short fc_pctx, fc_pcty; /* screen coords of percentage */ short fc_namex, fc_namey; /* screen coords of fc_name */ } FileCounter; /* * Per-procedure counting structure. */ typedef struct { int pr_type; /* procedure type */ char *pr_name; /* procedure name */ Counter pr_total; /* requests since start */ Counter pr_interval; /* requests this interval */ Counter pr_complete; /* requests with replies */ double pr_response; /* sum of all response times */ double pr_respsqr; /* sum of squares of resp times */ double pr_maxresp; /* maximum response time */ short pr_intx, pr_inty; /* screen coords of pr_interval */ short pr_totx, pr_toty; /* screen coords of pr_total */ short pr_pctx, pr_pcty; /* screen coords of percentage */ short pr_namex, pr_namey; /* screen coords of pr_name */ short pr_compx, pr_compy; /* screen coords of pr_complete */ short pr_respx, pr_respy; /* screen coords of pr_response */ short pr_rsqrx, pr_rsqry; /* screen coords of pr_respsqr */ short pr_rmaxx, pr_rmaxy; /* screen coords of pr_maxresp */ } ProcCounter; /* * NFS client counting structure. */ typedef struct _cl_ { ipaddrt cl_ipaddr; /* client IP address */ char *cl_name; /* name of client system */ Counter cl_total; /* requests since start */ Counter cl_interval; /* requests this interval */ short cl_intx, cl_inty; /* screen coords of cl_interval */ short cl_totx, cl_toty; /* screen coords of cl_total */ short cl_pctx, cl_pcty; /* screen coords of percentage */ short cl_namex, cl_namey; /* screen coords of cl_name */ struct _cl_ *cl_next; /* hash chain link */ } ClientCounter; /* * NFS authentication counting structure. */ typedef struct _ac_ { long ac_uid; /* authorization type */ char *ac_name; /* name of user id */ Counter ac_total; /* requests since start */ Counter ac_interval; /* requests this interval */ short ac_intx, ac_inty; /* screen coords of ac_interval */ short ac_totx, ac_toty; /* screen coords of ac_total */ short ac_pctx, ac_pcty; /* screen coords of percentage */ short ac_namex, ac_namey; /* screen coords of ac_name */ struct _ac_ *ac_next; /* hash chain link */ } AuthCounter; /* * NFS call structure, for remembering relevant timing information. */ #define NFSCALLHASHSIZE 255 typedef struct _nc_ { int proto; ipaddrt client; u_short clientport; u_int32 xid; u_int proc; u_int time_sec; u_int time_usec; } NFSCall; /* * Device type definitions (borrowed from the Berkeley Packet Filter) */ #ifndef DLT_NULL #define DLT_NULL 0 /* no link-layer encapsulation */ #define DLT_EN10MB 1 /* Ethernet (10Mb) */ #define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ #define DLT_AX25 3 /* Amateur Radio AX.25 */ #define DLT_PRONET 4 /* Proteon ProNET Token Ring */ #define DLT_CHAOS 5 /* Chaos */ #define DLT_IEEE802 6 /* IEEE 802 Networks */ #define DLT_ARCNET 7 /* ARCNET */ #define DLT_SLIP 8 /* Serial Line IP */ #define DLT_PPP 9 /* Point-to-point Protocol */ #define DLT_FDDI 10 /* FDDI */ #endif /* * Definitions for earlier systems which don't have these from 4.3BSD. */ #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 64 #endif #ifndef NFDBITS typedef long fd_mask; #define NFDBITS (sizeof(fd_mask) * NBBY) #define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) #define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) #define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) #define FD_ZERO(p) (void) bzero((char *)(p), sizeof(*(p))) #endif /* NFDBITS */ #ifdef USE_LINUX #include typedef struct _linux_socket_handle_t { char *device; u_char *buffer; u_char *bp; struct timeval ts; pcap_t *pcap; int s; int linktype; int bufsize; int offset; int len; } linux_socket_handle_t, *linux_socket_handle_p_t; #endif