?? print-nfs.c
字號:
/* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may 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. */#ifndef lintstatic const char rcsid[] = "@(#) $Header: print-nfs.c,v 1.65 97/08/17 13:24:22 leres Exp $ (LBL)";#endif#ifndef WIN32
#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#else
#include <winsock.h>
#define u_int32_t unsigned int
#endif
#if __STDC__struct mbuf;struct rtentry;#endif#include <net/if.h>#ifndef WIN32
#include <netinet/in.h>
#endif
#include <netinet/if_ether.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <netinet/ip_var.h>#ifndef WIN32
#include <rpc/rpc.h>
#else
#include <rpc.h>
#include <rpc/rpc_cut.h>
#endif
#include <ctype.h>#include <pcap.h>#include <stdio.h>
#include <string.h>#include "interface.h"#include "addrtoname.h"#include "nfsv2.h"#include "nfsfh.h"static void nfs_printfh(const u_int32_t *);static void xid_map_enter(const struct rpc_msg *, const struct ip *);static u_int32_t xid_map_find(const struct rpc_msg *, const struct ip *, u_int32_t *);static void interp_reply(const struct rpc_msg *, u_int32_t, u_int);static int nfserr; /* true if we error rather than trunc */voidnfsreply_print(register const u_char *bp, u_int length, register const u_char *bp2){ register const struct rpc_msg *rp; register const struct ip *ip; u_int32_t proc; nfserr = 0; /* assume no error */ rp = (const struct rpc_msg *)bp; ip = (const struct ip *)bp2; if (!nflag) (void)printf("%s.nfs > %s.%u: reply %s %d", ipaddr_string(&ip->ip_src), ipaddr_string(&ip->ip_dst), (u_int32_t)ntohl(rp->rm_xid), ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED? "ok":"ERR", length); else (void)printf("%s.%u > %s.%u: reply %s %d", ipaddr_string(&ip->ip_src), NFS_PORT, ipaddr_string(&ip->ip_dst), (u_int32_t)ntohl(rp->rm_xid), ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED? "ok":"ERR", length); if (xid_map_find(rp, ip, &proc)) interp_reply(rp, proc, length);}/* * Return a pointer to the first file handle in the packet. * If the packet was truncated, return 0. */static const u_int32_t *parsereq(register const struct rpc_msg *rp, register u_int length){ register const u_int32_t *dp; register u_int len; /* * find the start of the req data (if we captured it) */ dp = (u_int32_t *)&rp->rm_call.cb_cred; TCHECK(dp[1]); len = ntohl(dp[1]); if (len < length) { dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); TCHECK(dp[1]); len = ntohl(dp[1]); if (len < length) { dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); TCHECK2(dp[0], 0); return (dp); } }trunc: return (NULL);}/* * Print out an NFS file handle and return a pointer to following word. * If packet was truncated, return 0. */static const u_int32_t *parsefh(register const u_int32_t *dp){ if (dp + 8 <= (u_int32_t *)snapend) { nfs_printfh(dp); return (dp + 8); } return (NULL);}/* * Print out a file name and return pointer to 32-bit word past it. * If packet was truncated, return 0. */static const u_int32_t *parsefn(register const u_int32_t *dp){ register u_int32_t len; register const u_char *cp; /* Bail if we don't have the string length */ if ((u_char *)dp > snapend - sizeof(*dp)) return (NULL); /* Fetch string length; convert to host order */ len = *dp++; NTOHL(len); cp = (u_char *)dp; /* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */ dp += ((len + 3) & ~3) / sizeof(*dp); if ((u_char *)dp > snapend) return (NULL); /* XXX seems like we should be checking the length */ putchar('"'); (void) fn_printn(cp, len, NULL); putchar('"'); return (dp);}/* * Print out file handle and file name. * Return pointer to 32-bit word past file name. * If packet was truncated (or there was some other error), return 0. */static const u_int32_t *parsefhn(register const u_int32_t *dp){ dp = parsefh(dp); if (dp == NULL) return (NULL); putchar(' '); return (parsefn(dp));}voidnfsreq_print(register const u_char *bp, u_int length, register const u_char *bp2){ register const struct rpc_msg *rp; register const struct ip *ip; register const u_int32_t *dp; nfserr = 0; /* assume no error */ rp = (const struct rpc_msg *)bp; ip = (const struct ip *)bp2; if (!nflag) (void)printf("%s.%u > %s.nfs: %d", ipaddr_string(&ip->ip_src), (u_int32_t)ntohl(rp->rm_xid), ipaddr_string(&ip->ip_dst), length); else (void)printf("%s.%u > %s.%u: %d", ipaddr_string(&ip->ip_src), (u_int32_t)ntohl(rp->rm_xid), ipaddr_string(&ip->ip_dst), NFS_PORT, length); xid_map_enter(rp, ip); /* record proc number for later on */ switch (ntohl(rp->rm_call.cb_proc)) {#ifdef NFSPROC_NOOP case NFSPROC_NOOP: printf(" nop"); return;#else#define NFSPROC_NOOP -1#endif case NFSPROC_NULL: printf(" null"); return; case NFSPROC_GETATTR: printf(" getattr"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp) != NULL) return; break; case NFSPROC_SETATTR: printf(" setattr"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp) != NULL) return; break;#if NFSPROC_ROOT != NFSPROC_NOOP case NFSPROC_ROOT: printf(" root"); break;#endif case NFSPROC_LOOKUP: printf(" lookup"); if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp) != NULL) return; break; case NFSPROC_READLINK: printf(" readlink"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp) != NULL) return; break; case NFSPROC_READ: printf(" read"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp)) != NULL) { TCHECK2(dp[0], 3 * sizeof(*dp)); printf(" %u bytes @ %u", (u_int32_t)ntohl(dp[1]), (u_int32_t)ntohl(dp[0])); return; } break;#if NFSPROC_WRITECACHE != NFSPROC_NOOP case NFSPROC_WRITECACHE: printf(" writecache"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp)) != NULL) { TCHECK2(dp[0], 4 * sizeof(*dp)); printf(" %u (%u) bytes @ %u (%u)", (u_int32_t)ntohl(dp[3]), (u_int32_t)ntohl(dp[2]), (u_int32_t)ntohl(dp[1]), (u_int32_t)ntohl(dp[0])); return; } break;#endif case NFSPROC_WRITE: printf(" write"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp)) != NULL) { TCHECK2(dp[0], 4 * sizeof(*dp)); printf(" %u (%u) bytes @ %u (%u)", (u_int32_t)ntohl(dp[3]), (u_int32_t)ntohl(dp[2]), (u_int32_t)ntohl(dp[1]), (u_int32_t)ntohl(dp[0])); return; } break; case NFSPROC_CREATE: printf(" create"); if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp) != NULL) return; break; case NFSPROC_REMOVE: printf(" remove"); if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp) != NULL) return; break; case NFSPROC_RENAME: printf(" rename"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefhn(dp)) != NULL) { fputs(" ->", stdout); if (parsefhn(dp) != NULL) return; } break; case NFSPROC_LINK: printf(" link"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp)) != NULL) { fputs(" ->", stdout); if (parsefhn(dp) != NULL) return; } break; case NFSPROC_SYMLINK: printf(" symlink"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefhn(dp)) != NULL) { fputs(" -> ", stdout); if (parsefn(dp) != NULL) return; } break; case NFSPROC_MKDIR: printf(" mkdir"); if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp) != NULL) return; break; case NFSPROC_RMDIR: printf(" rmdir"); if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp) != NULL) return; break; case NFSPROC_READDIR: printf(" readdir"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp)) != NULL) { TCHECK2(dp[0], 2 * sizeof(*dp)); /* * Print the offset as signed, since -1 is common, * but offsets > 2^31 aren't. */ printf(" %u bytes @ %d", (u_int32_t)ntohl(dp[1]), (u_int32_t)ntohl(dp[0])); return; } break; case NFSPROC_STATFS: printf(" statfs"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp) != NULL) return; break; default: printf(" proc-%u", (u_int32_t)ntohl(rp->rm_call.cb_proc)); return; }trunc: if (!nfserr) fputs(" [|nfs]", stdout);}/* * Print out an NFS file handle. * We assume packet was not truncated before the end of the * file handle pointed to by dp. * * Note: new version (using portable file-handle parser) doesn't produce * generation number. It probably could be made to do that, with some * additional hacking on the parser code. */static voidnfs_printfh(register const u_int32_t *dp){ my_fsid fsid; ino_t ino; char *sfsname = NULL; Parse_fh((caddr_t *)dp, &fsid, &ino, NULL, &sfsname, 0); if (sfsname) { /* file system ID is ASCII, not numeric, for this server OS */ static char temp[NFS_FHSIZE+1]; /* Make sure string is null-terminated */ strncpy(temp, sfsname, NFS_FHSIZE); /* Remove trailing spaces */ sfsname = strchr(temp, ' '); if (sfsname) *sfsname = 0; (void)printf(" fh %s/%u", temp, (u_int32_t)ino); } else { (void)printf(" fh %u,%u/%u", fsid.Fsid_dev.Major, fsid.Fsid_dev.Minor, (u_int32_t)ino); }}/* * Maintain a small cache of recent client.XID.server/proc pairs, to allow * us to match up replies with requests and thus to know how to parse * the reply. */struct xid_map_entry { u_int32_t xid; /* transaction ID (net order) */ struct in_addr client; /* client IP address (net order) */ struct in_addr server; /* server IP address (net order) */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -