?? print-nfs.c
字號:
u_int32_t proc; /* call proc number (host order) */};/* * Map entries are kept in an array that we manage as a ring; * new entries are always added at the tail of the ring. Initially, * all the entries are zero and hence don't match anything. */#define XIDMAPSIZE 64struct xid_map_entry xid_map[XIDMAPSIZE];int xid_map_next = 0;int xid_map_hint = 0;static voidxid_map_enter(const struct rpc_msg *rp, const struct ip *ip){ struct xid_map_entry *xmep; xmep = &xid_map[xid_map_next]; if (++xid_map_next >= XIDMAPSIZE) xid_map_next = 0; xmep->xid = rp->rm_xid; xmep->client = ip->ip_src; xmep->server = ip->ip_dst; xmep->proc = ntohl(rp->rm_call.cb_proc);}/* Returns true and sets proc success or false on failure */static u_int32_txid_map_find(const struct rpc_msg *rp, const struct ip *ip, u_int32_t *proc){ int i; struct xid_map_entry *xmep; u_int32_t xid = rp->rm_xid; u_int32_t clip = ip->ip_dst.s_addr; u_int32_t sip = ip->ip_src.s_addr; /* Start searching from where we last left off */ i = xid_map_hint; do { xmep = &xid_map[i]; if (xmep->xid == xid && xmep->client.s_addr == clip && xmep->server.s_addr == sip) { /* match */ xid_map_hint = i; *proc = xmep->proc; return (1); } if (++i >= XIDMAPSIZE) i = 0; } while (i != xid_map_hint); /* search failed */ return (0);}/* * Routines for parsing reply packets *//* * Return a pointer to the beginning of the actual results. * If the packet was truncated, return 0. */static const u_int32_t *parserep(register const struct rpc_msg *rp, register u_int length){ register const u_int32_t *dp; u_int len; enum accept_stat astat; /* * Portability note: * Here we find the address of the ar_verf credentials. * Originally, this calculation was * dp = (u_int32_t *)&rp->rm_reply.rp_acpt.ar_verf * On the wire, the rp_acpt field starts immediately after * the (32 bit) rp_stat field. However, rp_acpt (which is a * "struct accepted_reply") contains a "struct opaque_auth", * whose internal representation contains a pointer, so on a * 64-bit machine the compiler inserts 32 bits of padding * before rp->rm_reply.rp_acpt.ar_verf. So, we cannot use * the internal representation to parse the on-the-wire * representation. Instead, we skip past the rp_stat field, * which is an "enum" and so occupies one 32-bit word. */ dp = ((const u_int32_t *)&rp->rm_reply) + 1; TCHECK2(dp[0], 1); len = ntohl(dp[1]); if (len >= length) return (NULL); /* * skip past the ar_verf credentials. */ dp += (len + (2*sizeof(u_int32_t) + 3)) / sizeof(u_int32_t); TCHECK2(dp[0], 0); /* * now we can check the ar_stat field */ astat = ntohl(*(enum accept_stat *)dp); switch (astat) { case SUCCESS: break; case PROG_UNAVAIL: printf(" PROG_UNAVAIL"); nfserr = 1; /* suppress trunc string */ return (NULL); case PROG_MISMATCH: printf(" PROG_MISMATCH"); nfserr = 1; /* suppress trunc string */ return (NULL); case PROC_UNAVAIL: printf(" PROC_UNAVAIL"); nfserr = 1; /* suppress trunc string */ return (NULL); case GARBAGE_ARGS: printf(" GARBAGE_ARGS"); nfserr = 1; /* suppress trunc string */ return (NULL); case SYSTEM_ERR: printf(" SYSTEM_ERR"); nfserr = 1; /* suppress trunc string */ return (NULL); default: printf(" ar_stat %d", astat); nfserr = 1; /* suppress trunc string */ return (NULL); } /* successful return */ if ((sizeof(astat) + ((u_char *)dp)) < snapend) return ((u_int32_t *) (sizeof(astat) + ((char *)dp)));trunc: return (NULL);}static const u_int32_t *parsestatus(const u_int32_t *dp){ register int errnum; TCHECK(dp[0]); errnum = ntohl(dp[0]); if (errnum != 0) { if (!qflag) printf(" ERROR: %s", pcap_strerror(errnum)); nfserr = 1; /* suppress trunc string */ return (NULL); } return (dp + 1);trunc: return (NULL);}static struct tok type2str[] = { { NFNON, "NON" }, { NFREG, "REG" }, { NFDIR, "DIR" }, { NFBLK, "BLK" }, { NFCHR, "CHR" }, { NFLNK, "LNK" }, { 0, NULL }};static const u_int32_t *parsefattr(const u_int32_t *dp, int verbose){ const struct nfsv2_fattr *fap; fap = (const struct nfsv2_fattr *)dp; if (verbose) { TCHECK(fap->fa_nfssize); printf(" %s %o ids %u/%u sz %u ", tok2str(type2str, "unk-ft %d ", (u_int32_t)ntohl(fap->fa_type)), (u_int32_t)ntohl(fap->fa_mode), (u_int32_t)ntohl(fap->fa_uid), (u_int32_t)ntohl(fap->fa_gid), (u_int32_t)ntohl(fap->fa_nfssize)); } /* print lots more stuff */ if (verbose > 1) { TCHECK(fap->fa_nfsfileid); printf("nlink %u rdev %x fsid %x nodeid %x a/m/ctime ", (u_int32_t)ntohl(fap->fa_nlink), (u_int32_t)ntohl(fap->fa_nfsrdev), (u_int32_t)ntohl(fap->fa_nfsfsid), (u_int32_t)ntohl(fap->fa_nfsfileid)); TCHECK(fap->fa_nfsatime); printf("%u.%06u ", (u_int32_t)ntohl(fap->fa_nfsatime.nfs_sec), (u_int32_t)ntohl(fap->fa_nfsatime.nfs_usec)); TCHECK(fap->fa_nfsmtime); printf("%u.%06u ", (u_int32_t)ntohl(fap->fa_nfsmtime.nfs_sec), (u_int32_t)ntohl(fap->fa_nfsmtime.nfs_usec)); TCHECK(fap->fa_nfsctime); printf("%u.%06u ", (u_int32_t)ntohl(fap->fa_nfsctime.nfs_sec), (u_int32_t)ntohl(fap->fa_nfsctime.nfs_usec)); } return ((const u_int32_t *)&fap[1]);trunc: return (NULL);}static intparseattrstat(const u_int32_t *dp, int verbose){ dp = parsestatus(dp); if (dp == NULL) return (0); return (parsefattr(dp, verbose) != NULL);}static intparsediropres(const u_int32_t *dp){ dp = parsestatus(dp); if (dp == NULL) return (0); dp = parsefh(dp); if (dp == NULL) return (0); return (parsefattr(dp, vflag) != NULL);}static intparselinkres(const u_int32_t *dp){ dp = parsestatus(dp); if (dp == NULL) return (0); putchar(' '); return (parsefn(dp) != NULL);}static intparsestatfs(const u_int32_t *dp){ const struct nfsv2_statfs *sfsp; dp = parsestatus(dp); if (dp == NULL) return (0); if (!qflag) { sfsp = (const struct nfsv2_statfs *)dp; TCHECK(sfsp->sf_bavail); printf(" tsize %u bsize %u blocks %u bfree %u bavail %u", (u_int32_t)ntohl(sfsp->sf_tsize), (u_int32_t)ntohl(sfsp->sf_bsize), (u_int32_t)ntohl(sfsp->sf_blocks), (u_int32_t)ntohl(sfsp->sf_bfree), (u_int32_t)ntohl(sfsp->sf_bavail)); } return (1);trunc: return (0);}static intparserddires(const u_int32_t *dp){ dp = parsestatus(dp); if (dp == NULL) return (0); if (!qflag) { TCHECK(dp[0]); printf(" offset %x", (u_int32_t)ntohl(dp[0])); TCHECK(dp[1]); printf(" size %u", (u_int32_t)ntohl(dp[1])); TCHECK(dp[2]); if (dp[2] != 0) printf(" eof"); } return (1);trunc: return (0);}static voidinterp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int length){ register const u_int32_t *dp; switch (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"); dp = parserep(rp, length); if (dp != NULL && parseattrstat(dp, !qflag) != 0) return; break; case NFSPROC_SETATTR: printf(" setattr"); dp = parserep(rp, length); if (dp != NULL && parseattrstat(dp, !qflag) != 0) return; break;#if NFSPROC_ROOT != NFSPROC_NOOP case NFSPROC_ROOT: printf(" root"); break;#endif case NFSPROC_LOOKUP: printf(" lookup"); dp = parserep(rp, length); if (dp != NULL && parsediropres(dp) != 0) return; break; case NFSPROC_READLINK: printf(" readlink"); dp = parserep(rp, length); if (dp != NULL && parselinkres(dp) != 0) return; break; case NFSPROC_READ: printf(" read"); dp = parserep(rp, length); if (dp != NULL && parseattrstat(dp, vflag) != 0) return; break;#if NFSPROC_WRITECACHE != NFSPROC_NOOP case NFSPROC_WRITECACHE: printf(" writecache"); break;#endif case NFSPROC_WRITE: printf(" write"); dp = parserep(rp, length); if (dp != NULL && parseattrstat(dp, vflag) != 0) return; break; case NFSPROC_CREATE: printf(" create"); dp = parserep(rp, length); if (dp != NULL && parsediropres(dp) != 0) return; break; case NFSPROC_REMOVE: printf(" remove"); dp = parserep(rp, length); if (dp != NULL && parsestatus(dp) != 0) return; break; case NFSPROC_RENAME: printf(" rename"); dp = parserep(rp, length); if (dp != NULL && parsestatus(dp) != 0) return; break; case NFSPROC_LINK: printf(" link"); dp = parserep(rp, length); if (dp != NULL && parsestatus(dp) != 0) return; break; case NFSPROC_SYMLINK: printf(" symlink"); dp = parserep(rp, length); if (dp != NULL && parsestatus(dp) != 0) return; break; case NFSPROC_MKDIR: printf(" mkdir"); dp = parserep(rp, length); if (dp != NULL && parsediropres(dp) != 0) return; break; case NFSPROC_RMDIR: printf(" rmdir"); dp = parserep(rp, length); if (dp != NULL && parsestatus(dp) != 0) return; break; case NFSPROC_READDIR: printf(" readdir"); dp = parserep(rp, length); if (dp != NULL && parserddires(dp) != 0) return; break; case NFSPROC_STATFS: printf(" statfs"); dp = parserep(rp, length); if (dp != NULL && parsestatfs(dp) != 0) return; break; default: printf(" proc-%u", proc); return; } if (!nfserr) fputs(" [|nfs]", stdout);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -