14edb46e9SPaul Traina /* 2699fc314SBill Fenner * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 34edb46e9SPaul Traina * The Regents of the University of California. All rights reserved. 44edb46e9SPaul Traina * 54edb46e9SPaul Traina * Redistribution and use in source and binary forms, with or without 64edb46e9SPaul Traina * modification, are permitted provided that: (1) source code distributions 74edb46e9SPaul Traina * retain the above copyright notice and this paragraph in its entirety, (2) 84edb46e9SPaul Traina * distributions including binary code include the above copyright notice and 94edb46e9SPaul Traina * this paragraph in its entirety in the documentation or other materials 104edb46e9SPaul Traina * provided with the distribution, and (3) all advertising materials mentioning 114edb46e9SPaul Traina * features or use of this software display the following acknowledgement: 124edb46e9SPaul Traina * ``This product includes software developed by the University of California, 134edb46e9SPaul Traina * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 144edb46e9SPaul Traina * the University nor the names of its contributors may be used to endorse 154edb46e9SPaul Traina * or promote products derived from this software without specific prior 164edb46e9SPaul Traina * written permission. 174edb46e9SPaul Traina * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 184edb46e9SPaul Traina * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 194edb46e9SPaul Traina * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20943ee2b1SBill Fenner * 21943ee2b1SBill Fenner * $FreeBSD$ 224edb46e9SPaul Traina */ 234edb46e9SPaul Traina 244edb46e9SPaul Traina #ifndef lint 25cc391cceSBruce M Simpson static const char rcsid[] _U_ = 26a5779b6eSRui Paulo "@(#) $Header: /tcpdump/master/tcpdump/print-nfs.c,v 1.110.2.1 2007-12-22 03:08:45 guy Exp $ (LBL)"; 27943ee2b1SBill Fenner #endif 28943ee2b1SBill Fenner 29943ee2b1SBill Fenner #ifdef HAVE_CONFIG_H 30943ee2b1SBill Fenner #include "config.h" 314edb46e9SPaul Traina #endif 324edb46e9SPaul Traina 33cc391cceSBruce M Simpson #include <tcpdump-stdinc.h> 344edb46e9SPaul Traina 352ebf6c05SBill Fenner #include <pcap.h> 364edb46e9SPaul Traina #include <stdio.h> 374edb46e9SPaul Traina #include <string.h> 384edb46e9SPaul Traina 394edb46e9SPaul Traina #include "interface.h" 404edb46e9SPaul Traina #include "addrtoname.h" 41cc391cceSBruce M Simpson #include "extract.h" 424edb46e9SPaul Traina 43647f50c3SDoug Rabson #include "nfs.h" 444edb46e9SPaul Traina #include "nfsfh.h" 454edb46e9SPaul Traina 46943ee2b1SBill Fenner #include "ip.h" 47943ee2b1SBill Fenner #ifdef INET6 48943ee2b1SBill Fenner #include "ip6.h" 49943ee2b1SBill Fenner #endif 50c1ad1296SSam Leffler #include "rpc_auth.h" 51c1ad1296SSam Leffler #include "rpc_msg.h" 52943ee2b1SBill Fenner 53943ee2b1SBill Fenner static void nfs_printfh(const u_int32_t *, const u_int); 54a5779b6eSRui Paulo static int xid_map_enter(const struct sunrpc_msg *, const u_char *); 55c1ad1296SSam Leffler static int32_t xid_map_find(const struct sunrpc_msg *, const u_char *, 56943ee2b1SBill Fenner u_int32_t *, u_int32_t *); 57c1ad1296SSam Leffler static void interp_reply(const struct sunrpc_msg *, u_int32_t, u_int32_t, int); 58647f50c3SDoug Rabson static const u_int32_t *parse_post_op_attr(const u_int32_t *, int); 59943ee2b1SBill Fenner static void print_sattr3(const struct nfsv3_sattr *sa3, int verbose); 60943ee2b1SBill Fenner static void print_nfsaddr(const u_char *, const char *, const char *); 612ebf6c05SBill Fenner 62647f50c3SDoug Rabson /* 63647f50c3SDoug Rabson * Mapping of old NFS Version 2 RPC numbers to generic numbers. 64647f50c3SDoug Rabson */ 65647f50c3SDoug Rabson u_int32_t nfsv3_procid[NFS_NPROCS] = { 66647f50c3SDoug Rabson NFSPROC_NULL, 67647f50c3SDoug Rabson NFSPROC_GETATTR, 68647f50c3SDoug Rabson NFSPROC_SETATTR, 69647f50c3SDoug Rabson NFSPROC_NOOP, 70647f50c3SDoug Rabson NFSPROC_LOOKUP, 71647f50c3SDoug Rabson NFSPROC_READLINK, 72647f50c3SDoug Rabson NFSPROC_READ, 73647f50c3SDoug Rabson NFSPROC_NOOP, 74647f50c3SDoug Rabson NFSPROC_WRITE, 75647f50c3SDoug Rabson NFSPROC_CREATE, 76647f50c3SDoug Rabson NFSPROC_REMOVE, 77647f50c3SDoug Rabson NFSPROC_RENAME, 78647f50c3SDoug Rabson NFSPROC_LINK, 79647f50c3SDoug Rabson NFSPROC_SYMLINK, 80647f50c3SDoug Rabson NFSPROC_MKDIR, 81647f50c3SDoug Rabson NFSPROC_RMDIR, 82647f50c3SDoug Rabson NFSPROC_READDIR, 83647f50c3SDoug Rabson NFSPROC_FSSTAT, 84647f50c3SDoug Rabson NFSPROC_NOOP, 85647f50c3SDoug Rabson NFSPROC_NOOP, 86647f50c3SDoug Rabson NFSPROC_NOOP, 87647f50c3SDoug Rabson NFSPROC_NOOP, 88647f50c3SDoug Rabson NFSPROC_NOOP, 89647f50c3SDoug Rabson NFSPROC_NOOP, 90647f50c3SDoug Rabson NFSPROC_NOOP, 91647f50c3SDoug Rabson NFSPROC_NOOP 92647f50c3SDoug Rabson }; 93647f50c3SDoug Rabson 94943ee2b1SBill Fenner /* 95943ee2b1SBill Fenner * NFS V2 and V3 status values. 96943ee2b1SBill Fenner * 97943ee2b1SBill Fenner * Some of these come from the RFCs for NFS V2 and V3, with the message 98943ee2b1SBill Fenner * strings taken from the FreeBSD C library "errlst.c". 99943ee2b1SBill Fenner * 100943ee2b1SBill Fenner * Others are errors that are not in the RFC but that I suspect some 101943ee2b1SBill Fenner * NFS servers could return; the values are FreeBSD errno values, as 102943ee2b1SBill Fenner * the first NFS server was the SunOS 2.0 one, and until 5.0 SunOS 103943ee2b1SBill Fenner * was primarily BSD-derived. 104943ee2b1SBill Fenner */ 105943ee2b1SBill Fenner static struct tok status2str[] = { 106943ee2b1SBill Fenner { 1, "Operation not permitted" }, /* EPERM */ 107943ee2b1SBill Fenner { 2, "No such file or directory" }, /* ENOENT */ 108943ee2b1SBill Fenner { 5, "Input/output error" }, /* EIO */ 109943ee2b1SBill Fenner { 6, "Device not configured" }, /* ENXIO */ 110943ee2b1SBill Fenner { 11, "Resource deadlock avoided" }, /* EDEADLK */ 111943ee2b1SBill Fenner { 12, "Cannot allocate memory" }, /* ENOMEM */ 112943ee2b1SBill Fenner { 13, "Permission denied" }, /* EACCES */ 113943ee2b1SBill Fenner { 17, "File exists" }, /* EEXIST */ 114943ee2b1SBill Fenner { 18, "Cross-device link" }, /* EXDEV */ 115943ee2b1SBill Fenner { 19, "Operation not supported by device" }, /* ENODEV */ 116943ee2b1SBill Fenner { 20, "Not a directory" }, /* ENOTDIR */ 117943ee2b1SBill Fenner { 21, "Is a directory" }, /* EISDIR */ 118943ee2b1SBill Fenner { 22, "Invalid argument" }, /* EINVAL */ 119943ee2b1SBill Fenner { 26, "Text file busy" }, /* ETXTBSY */ 120943ee2b1SBill Fenner { 27, "File too large" }, /* EFBIG */ 121943ee2b1SBill Fenner { 28, "No space left on device" }, /* ENOSPC */ 122943ee2b1SBill Fenner { 30, "Read-only file system" }, /* EROFS */ 123943ee2b1SBill Fenner { 31, "Too many links" }, /* EMLINK */ 124943ee2b1SBill Fenner { 45, "Operation not supported" }, /* EOPNOTSUPP */ 125943ee2b1SBill Fenner { 62, "Too many levels of symbolic links" }, /* ELOOP */ 126943ee2b1SBill Fenner { 63, "File name too long" }, /* ENAMETOOLONG */ 127943ee2b1SBill Fenner { 66, "Directory not empty" }, /* ENOTEMPTY */ 128943ee2b1SBill Fenner { 69, "Disc quota exceeded" }, /* EDQUOT */ 129943ee2b1SBill Fenner { 70, "Stale NFS file handle" }, /* ESTALE */ 130943ee2b1SBill Fenner { 71, "Too many levels of remote in path" }, /* EREMOTE */ 131943ee2b1SBill Fenner { 99, "Write cache flushed to disk" }, /* NFSERR_WFLUSH (not used) */ 132943ee2b1SBill Fenner { 10001, "Illegal NFS file handle" }, /* NFS3ERR_BADHANDLE */ 133943ee2b1SBill Fenner { 10002, "Update synchronization mismatch" }, /* NFS3ERR_NOT_SYNC */ 134943ee2b1SBill Fenner { 10003, "READDIR/READDIRPLUS cookie is stale" }, /* NFS3ERR_BAD_COOKIE */ 135943ee2b1SBill Fenner { 10004, "Operation not supported" }, /* NFS3ERR_NOTSUPP */ 136943ee2b1SBill Fenner { 10005, "Buffer or request is too small" }, /* NFS3ERR_TOOSMALL */ 137943ee2b1SBill Fenner { 10006, "Unspecified error on server" }, /* NFS3ERR_SERVERFAULT */ 138943ee2b1SBill Fenner { 10007, "Object of that type not supported" }, /* NFS3ERR_BADTYPE */ 139943ee2b1SBill Fenner { 10008, "Request couldn't be completed in time" }, /* NFS3ERR_JUKEBOX */ 140943ee2b1SBill Fenner { 0, NULL } 141943ee2b1SBill Fenner }; 142943ee2b1SBill Fenner 143943ee2b1SBill Fenner static struct tok nfsv3_writemodes[] = { 144943ee2b1SBill Fenner { 0, "unstable" }, 145943ee2b1SBill Fenner { 1, "datasync" }, 146943ee2b1SBill Fenner { 2, "filesync" }, 147943ee2b1SBill Fenner { 0, NULL } 148647f50c3SDoug Rabson }; 149647f50c3SDoug Rabson 150647f50c3SDoug Rabson static struct tok type2str[] = { 151647f50c3SDoug Rabson { NFNON, "NON" }, 152647f50c3SDoug Rabson { NFREG, "REG" }, 153647f50c3SDoug Rabson { NFDIR, "DIR" }, 154647f50c3SDoug Rabson { NFBLK, "BLK" }, 155647f50c3SDoug Rabson { NFCHR, "CHR" }, 156647f50c3SDoug Rabson { NFLNK, "LNK" }, 157647f50c3SDoug Rabson { NFFIFO, "FIFO" }, 158647f50c3SDoug Rabson { 0, NULL } 159647f50c3SDoug Rabson }; 160647f50c3SDoug Rabson 161943ee2b1SBill Fenner static void 162943ee2b1SBill Fenner print_nfsaddr(const u_char *bp, const char *s, const char *d) 163943ee2b1SBill Fenner { 164943ee2b1SBill Fenner struct ip *ip; 165943ee2b1SBill Fenner #ifdef INET6 166943ee2b1SBill Fenner struct ip6_hdr *ip6; 167943ee2b1SBill Fenner char srcaddr[INET6_ADDRSTRLEN], dstaddr[INET6_ADDRSTRLEN]; 168943ee2b1SBill Fenner #else 169943ee2b1SBill Fenner #ifndef INET_ADDRSTRLEN 170943ee2b1SBill Fenner #define INET_ADDRSTRLEN 16 171943ee2b1SBill Fenner #endif 172943ee2b1SBill Fenner char srcaddr[INET_ADDRSTRLEN], dstaddr[INET_ADDRSTRLEN]; 173943ee2b1SBill Fenner #endif 174943ee2b1SBill Fenner 175943ee2b1SBill Fenner srcaddr[0] = dstaddr[0] = '\0'; 176943ee2b1SBill Fenner switch (IP_V((struct ip *)bp)) { 177943ee2b1SBill Fenner case 4: 178943ee2b1SBill Fenner ip = (struct ip *)bp; 179943ee2b1SBill Fenner strlcpy(srcaddr, ipaddr_string(&ip->ip_src), sizeof(srcaddr)); 180943ee2b1SBill Fenner strlcpy(dstaddr, ipaddr_string(&ip->ip_dst), sizeof(dstaddr)); 181943ee2b1SBill Fenner break; 182943ee2b1SBill Fenner #ifdef INET6 183943ee2b1SBill Fenner case 6: 184943ee2b1SBill Fenner ip6 = (struct ip6_hdr *)bp; 185943ee2b1SBill Fenner strlcpy(srcaddr, ip6addr_string(&ip6->ip6_src), 186943ee2b1SBill Fenner sizeof(srcaddr)); 187943ee2b1SBill Fenner strlcpy(dstaddr, ip6addr_string(&ip6->ip6_dst), 188943ee2b1SBill Fenner sizeof(dstaddr)); 189943ee2b1SBill Fenner break; 190943ee2b1SBill Fenner #endif 191943ee2b1SBill Fenner default: 192943ee2b1SBill Fenner strlcpy(srcaddr, "?", sizeof(srcaddr)); 193943ee2b1SBill Fenner strlcpy(dstaddr, "?", sizeof(dstaddr)); 194943ee2b1SBill Fenner break; 195943ee2b1SBill Fenner } 196943ee2b1SBill Fenner 197943ee2b1SBill Fenner (void)printf("%s.%s > %s.%s: ", srcaddr, s, dstaddr, d); 198943ee2b1SBill Fenner } 199943ee2b1SBill Fenner 200647f50c3SDoug Rabson static const u_int32_t * 201647f50c3SDoug Rabson parse_sattr3(const u_int32_t *dp, struct nfsv3_sattr *sa3) 202647f50c3SDoug Rabson { 203943ee2b1SBill Fenner TCHECK(dp[0]); 204cc391cceSBruce M Simpson sa3->sa_modeset = EXTRACT_32BITS(dp); 205cc391cceSBruce M Simpson dp++; 206cc391cceSBruce M Simpson if (sa3->sa_modeset) { 207943ee2b1SBill Fenner TCHECK(dp[0]); 208cc391cceSBruce M Simpson sa3->sa_mode = EXTRACT_32BITS(dp); 209cc391cceSBruce M Simpson dp++; 210647f50c3SDoug Rabson } 211647f50c3SDoug Rabson 212943ee2b1SBill Fenner TCHECK(dp[0]); 213cc391cceSBruce M Simpson sa3->sa_uidset = EXTRACT_32BITS(dp); 214cc391cceSBruce M Simpson dp++; 215cc391cceSBruce M Simpson if (sa3->sa_uidset) { 216943ee2b1SBill Fenner TCHECK(dp[0]); 217cc391cceSBruce M Simpson sa3->sa_uid = EXTRACT_32BITS(dp); 218cc391cceSBruce M Simpson dp++; 219647f50c3SDoug Rabson } 220647f50c3SDoug Rabson 221943ee2b1SBill Fenner TCHECK(dp[0]); 222cc391cceSBruce M Simpson sa3->sa_gidset = EXTRACT_32BITS(dp); 223cc391cceSBruce M Simpson dp++; 224cc391cceSBruce M Simpson if (sa3->sa_gidset) { 225943ee2b1SBill Fenner TCHECK(dp[0]); 226cc391cceSBruce M Simpson sa3->sa_gid = EXTRACT_32BITS(dp); 227cc391cceSBruce M Simpson dp++; 228647f50c3SDoug Rabson } 229647f50c3SDoug Rabson 230943ee2b1SBill Fenner TCHECK(dp[0]); 231cc391cceSBruce M Simpson sa3->sa_sizeset = EXTRACT_32BITS(dp); 232cc391cceSBruce M Simpson dp++; 233cc391cceSBruce M Simpson if (sa3->sa_sizeset) { 234943ee2b1SBill Fenner TCHECK(dp[0]); 235cc391cceSBruce M Simpson sa3->sa_size = EXTRACT_32BITS(dp); 236cc391cceSBruce M Simpson dp++; 237647f50c3SDoug Rabson } 238647f50c3SDoug Rabson 239943ee2b1SBill Fenner TCHECK(dp[0]); 240cc391cceSBruce M Simpson sa3->sa_atimetype = EXTRACT_32BITS(dp); 241cc391cceSBruce M Simpson dp++; 242cc391cceSBruce M Simpson if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) { 243943ee2b1SBill Fenner TCHECK(dp[1]); 244cc391cceSBruce M Simpson sa3->sa_atime.nfsv3_sec = EXTRACT_32BITS(dp); 245cc391cceSBruce M Simpson dp++; 246cc391cceSBruce M Simpson sa3->sa_atime.nfsv3_nsec = EXTRACT_32BITS(dp); 247cc391cceSBruce M Simpson dp++; 248647f50c3SDoug Rabson } 249647f50c3SDoug Rabson 250943ee2b1SBill Fenner TCHECK(dp[0]); 251cc391cceSBruce M Simpson sa3->sa_mtimetype = EXTRACT_32BITS(dp); 252cc391cceSBruce M Simpson dp++; 253cc391cceSBruce M Simpson if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) { 254943ee2b1SBill Fenner TCHECK(dp[1]); 255cc391cceSBruce M Simpson sa3->sa_mtime.nfsv3_sec = EXTRACT_32BITS(dp); 256cc391cceSBruce M Simpson dp++; 257cc391cceSBruce M Simpson sa3->sa_mtime.nfsv3_nsec = EXTRACT_32BITS(dp); 258cc391cceSBruce M Simpson dp++; 259647f50c3SDoug Rabson } 260647f50c3SDoug Rabson 261647f50c3SDoug Rabson return dp; 262943ee2b1SBill Fenner trunc: 263943ee2b1SBill Fenner return NULL; 264647f50c3SDoug Rabson } 265647f50c3SDoug Rabson 266943ee2b1SBill Fenner static int nfserr; /* true if we error rather than trunc */ 267943ee2b1SBill Fenner 268943ee2b1SBill Fenner static void 269647f50c3SDoug Rabson print_sattr3(const struct nfsv3_sattr *sa3, int verbose) 270647f50c3SDoug Rabson { 271647f50c3SDoug Rabson if (sa3->sa_modeset) 272647f50c3SDoug Rabson printf(" mode %o", sa3->sa_mode); 273647f50c3SDoug Rabson if (sa3->sa_uidset) 274647f50c3SDoug Rabson printf(" uid %u", sa3->sa_uid); 275647f50c3SDoug Rabson if (sa3->sa_gidset) 276647f50c3SDoug Rabson printf(" gid %u", sa3->sa_gid); 277647f50c3SDoug Rabson if (verbose > 1) { 278647f50c3SDoug Rabson if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) 279647f50c3SDoug Rabson printf(" atime %u.%06u", sa3->sa_atime.nfsv3_sec, 280647f50c3SDoug Rabson sa3->sa_atime.nfsv3_nsec); 281647f50c3SDoug Rabson if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) 282647f50c3SDoug Rabson printf(" mtime %u.%06u", sa3->sa_mtime.nfsv3_sec, 283647f50c3SDoug Rabson sa3->sa_mtime.nfsv3_nsec); 284647f50c3SDoug Rabson } 285647f50c3SDoug Rabson } 2864edb46e9SPaul Traina 2874edb46e9SPaul Traina void 2884edb46e9SPaul Traina nfsreply_print(register const u_char *bp, u_int length, 2894edb46e9SPaul Traina register const u_char *bp2) 2904edb46e9SPaul Traina { 291c1ad1296SSam Leffler register const struct sunrpc_msg *rp; 292abf25193SMax Laier u_int32_t proc, vers, reply_stat; 293943ee2b1SBill Fenner char srcid[20], dstid[20]; /*fits 32bit*/ 294abf25193SMax Laier enum sunrpc_reject_stat rstat; 295abf25193SMax Laier u_int32_t rlow; 296abf25193SMax Laier u_int32_t rhigh; 297abf25193SMax Laier enum sunrpc_auth_stat rwhy; 2984edb46e9SPaul Traina 2992ebf6c05SBill Fenner nfserr = 0; /* assume no error */ 300c1ad1296SSam Leffler rp = (const struct sunrpc_msg *)bp; 3014edb46e9SPaul Traina 302a5779b6eSRui Paulo TCHECK(rp->rm_xid); 303943ee2b1SBill Fenner if (!nflag) { 304943ee2b1SBill Fenner strlcpy(srcid, "nfs", sizeof(srcid)); 305943ee2b1SBill Fenner snprintf(dstid, sizeof(dstid), "%u", 306cc391cceSBruce M Simpson EXTRACT_32BITS(&rp->rm_xid)); 307943ee2b1SBill Fenner } else { 308943ee2b1SBill Fenner snprintf(srcid, sizeof(srcid), "%u", NFS_PORT); 309943ee2b1SBill Fenner snprintf(dstid, sizeof(dstid), "%u", 310cc391cceSBruce M Simpson EXTRACT_32BITS(&rp->rm_xid)); 311943ee2b1SBill Fenner } 312943ee2b1SBill Fenner print_nfsaddr(bp2, srcid, dstid); 313a5779b6eSRui Paulo TCHECK(rp->rm_reply.rp_stat); 314abf25193SMax Laier reply_stat = EXTRACT_32BITS(&rp->rm_reply.rp_stat); 315abf25193SMax Laier switch (reply_stat) { 3164edb46e9SPaul Traina 317abf25193SMax Laier case SUNRPC_MSG_ACCEPTED: 318abf25193SMax Laier (void)printf("reply ok %u", length); 319943ee2b1SBill Fenner if (xid_map_find(rp, bp2, &proc, &vers) >= 0) 320647f50c3SDoug Rabson interp_reply(rp, proc, vers, length); 321abf25193SMax Laier break; 322abf25193SMax Laier 323abf25193SMax Laier case SUNRPC_MSG_DENIED: 324abf25193SMax Laier (void)printf("reply ERR %u: ", length); 325a5779b6eSRui Paulo TCHECK(rp->rm_reply.rp_reject.rj_stat); 326abf25193SMax Laier rstat = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_stat); 327abf25193SMax Laier switch (rstat) { 328abf25193SMax Laier 329abf25193SMax Laier case SUNRPC_RPC_MISMATCH: 330a5779b6eSRui Paulo TCHECK(rp->rm_reply.rp_reject.rj_vers.high); 331abf25193SMax Laier rlow = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_vers.low); 332abf25193SMax Laier rhigh = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_vers.high); 333abf25193SMax Laier (void)printf("RPC Version mismatch (%u-%u)", 334abf25193SMax Laier rlow, rhigh); 335abf25193SMax Laier break; 336abf25193SMax Laier 337abf25193SMax Laier case SUNRPC_AUTH_ERROR: 338a5779b6eSRui Paulo TCHECK(rp->rm_reply.rp_reject.rj_why); 339abf25193SMax Laier rwhy = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_why); 340abf25193SMax Laier (void)printf("Auth "); 341abf25193SMax Laier switch (rwhy) { 342abf25193SMax Laier 343abf25193SMax Laier case SUNRPC_AUTH_OK: 344abf25193SMax Laier (void)printf("OK"); 345abf25193SMax Laier break; 346abf25193SMax Laier 347abf25193SMax Laier case SUNRPC_AUTH_BADCRED: 348abf25193SMax Laier (void)printf("Bogus Credentials (seal broken)"); 349abf25193SMax Laier break; 350abf25193SMax Laier 351abf25193SMax Laier case SUNRPC_AUTH_REJECTEDCRED: 352abf25193SMax Laier (void)printf("Rejected Credentials (client should begin new session)"); 353abf25193SMax Laier break; 354abf25193SMax Laier 355abf25193SMax Laier case SUNRPC_AUTH_BADVERF: 356abf25193SMax Laier (void)printf("Bogus Verifier (seal broken)"); 357abf25193SMax Laier break; 358abf25193SMax Laier 359abf25193SMax Laier case SUNRPC_AUTH_REJECTEDVERF: 360abf25193SMax Laier (void)printf("Verifier expired or was replayed"); 361abf25193SMax Laier break; 362abf25193SMax Laier 363abf25193SMax Laier case SUNRPC_AUTH_TOOWEAK: 364abf25193SMax Laier (void)printf("Credentials are too weak"); 365abf25193SMax Laier break; 366abf25193SMax Laier 367abf25193SMax Laier case SUNRPC_AUTH_INVALIDRESP: 368abf25193SMax Laier (void)printf("Bogus response verifier"); 369abf25193SMax Laier break; 370abf25193SMax Laier 371abf25193SMax Laier case SUNRPC_AUTH_FAILED: 372abf25193SMax Laier (void)printf("Unknown failure"); 373abf25193SMax Laier break; 374abf25193SMax Laier 375abf25193SMax Laier default: 376abf25193SMax Laier (void)printf("Invalid failure code %u", 377abf25193SMax Laier (unsigned int)rwhy); 378abf25193SMax Laier break; 379abf25193SMax Laier } 380abf25193SMax Laier break; 381abf25193SMax Laier 382abf25193SMax Laier default: 383abf25193SMax Laier (void)printf("Unknown reason for rejecting rpc message %u", 384abf25193SMax Laier (unsigned int)rstat); 385abf25193SMax Laier break; 386abf25193SMax Laier } 387abf25193SMax Laier break; 388abf25193SMax Laier 389abf25193SMax Laier default: 390abf25193SMax Laier (void)printf("reply Unknown rpc response code=%u %u", 391abf25193SMax Laier reply_stat, length); 392abf25193SMax Laier break; 393abf25193SMax Laier } 394a5779b6eSRui Paulo return; 395a5779b6eSRui Paulo 396a5779b6eSRui Paulo trunc: 397a5779b6eSRui Paulo if (!nfserr) 398a5779b6eSRui Paulo fputs(" [|nfs]", stdout); 3994edb46e9SPaul Traina } 4004edb46e9SPaul Traina 4014edb46e9SPaul Traina /* 4024edb46e9SPaul Traina * Return a pointer to the first file handle in the packet. 403943ee2b1SBill Fenner * If the packet was truncated, return 0. 4044edb46e9SPaul Traina */ 4054edb46e9SPaul Traina static const u_int32_t * 406c1ad1296SSam Leffler parsereq(register const struct sunrpc_msg *rp, register u_int length) 4074edb46e9SPaul Traina { 4082ebf6c05SBill Fenner register const u_int32_t *dp; 4094edb46e9SPaul Traina register u_int len; 4104edb46e9SPaul Traina 4114edb46e9SPaul Traina /* 4124edb46e9SPaul Traina * find the start of the req data (if we captured it) 4134edb46e9SPaul Traina */ 4142ebf6c05SBill Fenner dp = (u_int32_t *)&rp->rm_call.cb_cred; 4152ebf6c05SBill Fenner TCHECK(dp[1]); 416cc391cceSBruce M Simpson len = EXTRACT_32BITS(&dp[1]); 4172ebf6c05SBill Fenner if (len < length) { 4182ebf6c05SBill Fenner dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); 4192ebf6c05SBill Fenner TCHECK(dp[1]); 420cc391cceSBruce M Simpson len = EXTRACT_32BITS(&dp[1]); 4212ebf6c05SBill Fenner if (len < length) { 4222ebf6c05SBill Fenner dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); 4232ebf6c05SBill Fenner TCHECK2(dp[0], 0); 4244edb46e9SPaul Traina return (dp); 4254edb46e9SPaul Traina } 4264edb46e9SPaul Traina } 4272ebf6c05SBill Fenner trunc: 4282ebf6c05SBill Fenner return (NULL); 4294edb46e9SPaul Traina } 4304edb46e9SPaul Traina 4314edb46e9SPaul Traina /* 4324edb46e9SPaul Traina * Print out an NFS file handle and return a pointer to following word. 433943ee2b1SBill Fenner * If packet was truncated, return 0. 4344edb46e9SPaul Traina */ 4354edb46e9SPaul Traina static const u_int32_t * 436647f50c3SDoug Rabson parsefh(register const u_int32_t *dp, int v3) 4374edb46e9SPaul Traina { 438cc391cceSBruce M Simpson u_int len; 439647f50c3SDoug Rabson 440647f50c3SDoug Rabson if (v3) { 4412ebf6c05SBill Fenner TCHECK(dp[0]); 442cc391cceSBruce M Simpson len = EXTRACT_32BITS(dp) / 4; 443647f50c3SDoug Rabson dp++; 444647f50c3SDoug Rabson } else 445647f50c3SDoug Rabson len = NFSX_V2FH / 4; 446647f50c3SDoug Rabson 4472ebf6c05SBill Fenner if (TTEST2(*dp, len * sizeof(*dp))) { 448647f50c3SDoug Rabson nfs_printfh(dp, len); 449647f50c3SDoug Rabson return (dp + len); 4504edb46e9SPaul Traina } 4512ebf6c05SBill Fenner trunc: 4522ebf6c05SBill Fenner return (NULL); 4534edb46e9SPaul Traina } 4544edb46e9SPaul Traina 4554edb46e9SPaul Traina /* 4564edb46e9SPaul Traina * Print out a file name and return pointer to 32-bit word past it. 457943ee2b1SBill Fenner * If packet was truncated, return 0. 4584edb46e9SPaul Traina */ 4594edb46e9SPaul Traina static const u_int32_t * 4604edb46e9SPaul Traina parsefn(register const u_int32_t *dp) 4614edb46e9SPaul Traina { 4624edb46e9SPaul Traina register u_int32_t len; 4634edb46e9SPaul Traina register const u_char *cp; 4644edb46e9SPaul Traina 4654edb46e9SPaul Traina /* Bail if we don't have the string length */ 466943ee2b1SBill Fenner TCHECK(*dp); 4674edb46e9SPaul Traina 4684edb46e9SPaul Traina /* Fetch string length; convert to host order */ 4694edb46e9SPaul Traina len = *dp++; 4704edb46e9SPaul Traina NTOHL(len); 4714edb46e9SPaul Traina 472943ee2b1SBill Fenner TCHECK2(*dp, ((len + 3) & ~3)); 473943ee2b1SBill Fenner 4744edb46e9SPaul Traina cp = (u_char *)dp; 4754edb46e9SPaul Traina /* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */ 4764edb46e9SPaul Traina dp += ((len + 3) & ~3) / sizeof(*dp); 4772ebf6c05SBill Fenner putchar('"'); 47829292c17SSam Leffler if (fn_printn(cp, len, snapend)) { 47929292c17SSam Leffler putchar('"'); 48029292c17SSam Leffler goto trunc; 48129292c17SSam Leffler } 4822ebf6c05SBill Fenner putchar('"'); 4834edb46e9SPaul Traina 4844edb46e9SPaul Traina return (dp); 485943ee2b1SBill Fenner trunc: 486943ee2b1SBill Fenner return NULL; 4874edb46e9SPaul Traina } 4884edb46e9SPaul Traina 4894edb46e9SPaul Traina /* 4904edb46e9SPaul Traina * Print out file handle and file name. 4914edb46e9SPaul Traina * Return pointer to 32-bit word past file name. 492943ee2b1SBill Fenner * If packet was truncated (or there was some other error), return 0. 4934edb46e9SPaul Traina */ 4944edb46e9SPaul Traina static const u_int32_t * 495647f50c3SDoug Rabson parsefhn(register const u_int32_t *dp, int v3) 4964edb46e9SPaul Traina { 497647f50c3SDoug Rabson dp = parsefh(dp, v3); 4982ebf6c05SBill Fenner if (dp == NULL) 4992ebf6c05SBill Fenner return (NULL); 5004edb46e9SPaul Traina putchar(' '); 5014edb46e9SPaul Traina return (parsefn(dp)); 5024edb46e9SPaul Traina } 5034edb46e9SPaul Traina 5044edb46e9SPaul Traina void 5054edb46e9SPaul Traina nfsreq_print(register const u_char *bp, u_int length, 5064edb46e9SPaul Traina register const u_char *bp2) 5074edb46e9SPaul Traina { 508c1ad1296SSam Leffler register const struct sunrpc_msg *rp; 5094edb46e9SPaul Traina register const u_int32_t *dp; 510943ee2b1SBill Fenner nfs_type type; 511943ee2b1SBill Fenner int v3; 512943ee2b1SBill Fenner u_int32_t proc; 513647f50c3SDoug Rabson struct nfsv3_sattr sa3; 514943ee2b1SBill Fenner char srcid[20], dstid[20]; /*fits 32bit*/ 5154edb46e9SPaul Traina 5162ebf6c05SBill Fenner nfserr = 0; /* assume no error */ 517c1ad1296SSam Leffler rp = (const struct sunrpc_msg *)bp; 518a5779b6eSRui Paulo 519a5779b6eSRui Paulo TCHECK(rp->rm_xid); 520943ee2b1SBill Fenner if (!nflag) { 521943ee2b1SBill Fenner snprintf(srcid, sizeof(srcid), "%u", 522cc391cceSBruce M Simpson EXTRACT_32BITS(&rp->rm_xid)); 523943ee2b1SBill Fenner strlcpy(dstid, "nfs", sizeof(dstid)); 524943ee2b1SBill Fenner } else { 525943ee2b1SBill Fenner snprintf(srcid, sizeof(srcid), "%u", 526cc391cceSBruce M Simpson EXTRACT_32BITS(&rp->rm_xid)); 527943ee2b1SBill Fenner snprintf(dstid, sizeof(dstid), "%u", NFS_PORT); 528943ee2b1SBill Fenner } 529943ee2b1SBill Fenner print_nfsaddr(bp2, srcid, dstid); 530943ee2b1SBill Fenner (void)printf("%d", length); 5314edb46e9SPaul Traina 532a5779b6eSRui Paulo if (!xid_map_enter(rp, bp2)) /* record proc number for later on */ 533a5779b6eSRui Paulo goto trunc; 5344edb46e9SPaul Traina 535cc391cceSBruce M Simpson v3 = (EXTRACT_32BITS(&rp->rm_call.cb_vers) == NFS_VER3); 536cc391cceSBruce M Simpson proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); 537647f50c3SDoug Rabson 538647f50c3SDoug Rabson if (!v3 && proc < NFS_NPROCS) 539647f50c3SDoug Rabson proc = nfsv3_procid[proc]; 540647f50c3SDoug Rabson 541647f50c3SDoug Rabson switch (proc) { 5424edb46e9SPaul Traina case NFSPROC_NOOP: 5434edb46e9SPaul Traina printf(" nop"); 5444edb46e9SPaul Traina return; 5454edb46e9SPaul Traina case NFSPROC_NULL: 5464edb46e9SPaul Traina printf(" null"); 5474edb46e9SPaul Traina return; 5484edb46e9SPaul Traina 5494edb46e9SPaul Traina case NFSPROC_GETATTR: 5504edb46e9SPaul Traina printf(" getattr"); 551943ee2b1SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 552943ee2b1SBill Fenner parsefh(dp, v3) != NULL) 5534edb46e9SPaul Traina return; 5544edb46e9SPaul Traina break; 5554edb46e9SPaul Traina 5564edb46e9SPaul Traina case NFSPROC_SETATTR: 5574edb46e9SPaul Traina printf(" setattr"); 558943ee2b1SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 559943ee2b1SBill Fenner parsefh(dp, v3) != NULL) 5604edb46e9SPaul Traina return; 5614edb46e9SPaul Traina break; 5624edb46e9SPaul Traina 5634edb46e9SPaul Traina case NFSPROC_LOOKUP: 5644edb46e9SPaul Traina printf(" lookup"); 565943ee2b1SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 566943ee2b1SBill Fenner parsefhn(dp, v3) != NULL) 5674edb46e9SPaul Traina return; 5684edb46e9SPaul Traina break; 5694edb46e9SPaul Traina 570647f50c3SDoug Rabson case NFSPROC_ACCESS: 571647f50c3SDoug Rabson printf(" access"); 5722ebf6c05SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 5732ebf6c05SBill Fenner (dp = parsefh(dp, v3)) != NULL) { 574943ee2b1SBill Fenner TCHECK(dp[0]); 575cc391cceSBruce M Simpson printf(" %04x", EXTRACT_32BITS(&dp[0])); 576647f50c3SDoug Rabson return; 577647f50c3SDoug Rabson } 578647f50c3SDoug Rabson break; 579647f50c3SDoug Rabson 5804edb46e9SPaul Traina case NFSPROC_READLINK: 5814edb46e9SPaul Traina printf(" readlink"); 582943ee2b1SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 583943ee2b1SBill Fenner parsefh(dp, v3) != NULL) 5844edb46e9SPaul Traina return; 5854edb46e9SPaul Traina break; 5864edb46e9SPaul Traina 5874edb46e9SPaul Traina case NFSPROC_READ: 5884edb46e9SPaul Traina printf(" read"); 5892ebf6c05SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 5902ebf6c05SBill Fenner (dp = parsefh(dp, v3)) != NULL) { 591647f50c3SDoug Rabson if (v3) { 592943ee2b1SBill Fenner TCHECK(dp[2]); 593c1ad1296SSam Leffler printf(" %u bytes @ %" PRIu64, 594c1ad1296SSam Leffler EXTRACT_32BITS(&dp[2]), 595c1ad1296SSam Leffler EXTRACT_64BITS(&dp[0])); 596647f50c3SDoug Rabson } else { 597943ee2b1SBill Fenner TCHECK(dp[1]); 598943ee2b1SBill Fenner printf(" %u bytes @ %u", 599cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[1]), 600cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[0])); 601647f50c3SDoug Rabson } 6024edb46e9SPaul Traina return; 6034edb46e9SPaul Traina } 6044edb46e9SPaul Traina break; 6054edb46e9SPaul Traina 6064edb46e9SPaul Traina case NFSPROC_WRITE: 6074edb46e9SPaul Traina printf(" write"); 6082ebf6c05SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 6092ebf6c05SBill Fenner (dp = parsefh(dp, v3)) != NULL) { 610647f50c3SDoug Rabson if (v3) { 611c1ad1296SSam Leffler TCHECK(dp[2]); 612c1ad1296SSam Leffler printf(" %u (%u) bytes @ %" PRIu64, 613c1ad1296SSam Leffler EXTRACT_32BITS(&dp[4]), 614c1ad1296SSam Leffler EXTRACT_32BITS(&dp[2]), 615c1ad1296SSam Leffler EXTRACT_64BITS(&dp[0])); 616647f50c3SDoug Rabson if (vflag) { 617647f50c3SDoug Rabson dp += 3; 618943ee2b1SBill Fenner TCHECK(dp[0]); 619647f50c3SDoug Rabson printf(" <%s>", 620943ee2b1SBill Fenner tok2str(nfsv3_writemodes, 621cc391cceSBruce M Simpson NULL, EXTRACT_32BITS(dp))); 622647f50c3SDoug Rabson } 623647f50c3SDoug Rabson } else { 624943ee2b1SBill Fenner TCHECK(dp[3]); 625943ee2b1SBill Fenner printf(" %u (%u) bytes @ %u (%u)", 626cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[3]), 627cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[2]), 628cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[1]), 629cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[0])); 630647f50c3SDoug Rabson } 6314edb46e9SPaul Traina return; 6324edb46e9SPaul Traina } 6334edb46e9SPaul Traina break; 6344edb46e9SPaul Traina 6354edb46e9SPaul Traina case NFSPROC_CREATE: 6364edb46e9SPaul Traina printf(" create"); 637943ee2b1SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 638943ee2b1SBill Fenner parsefhn(dp, v3) != NULL) 6394edb46e9SPaul Traina return; 6404edb46e9SPaul Traina break; 6414edb46e9SPaul Traina 642647f50c3SDoug Rabson case NFSPROC_MKDIR: 643647f50c3SDoug Rabson printf(" mkdir"); 644943ee2b1SBill Fenner if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp, v3) != 0) 645647f50c3SDoug Rabson return; 646647f50c3SDoug Rabson break; 647647f50c3SDoug Rabson 648647f50c3SDoug Rabson case NFSPROC_SYMLINK: 649647f50c3SDoug Rabson printf(" symlink"); 650943ee2b1SBill Fenner if ((dp = parsereq(rp, length)) != 0 && 651943ee2b1SBill Fenner (dp = parsefhn(dp, v3)) != 0) { 652647f50c3SDoug Rabson fputs(" ->", stdout); 653943ee2b1SBill Fenner if (v3 && (dp = parse_sattr3(dp, &sa3)) == 0) 654647f50c3SDoug Rabson break; 655943ee2b1SBill Fenner if (parsefn(dp) == 0) 656647f50c3SDoug Rabson break; 657647f50c3SDoug Rabson if (v3 && vflag) 658647f50c3SDoug Rabson print_sattr3(&sa3, vflag); 659647f50c3SDoug Rabson return; 660647f50c3SDoug Rabson } 661647f50c3SDoug Rabson break; 662647f50c3SDoug Rabson 663647f50c3SDoug Rabson case NFSPROC_MKNOD: 664647f50c3SDoug Rabson printf(" mknod"); 665943ee2b1SBill Fenner if ((dp = parsereq(rp, length)) != 0 && 666943ee2b1SBill Fenner (dp = parsefhn(dp, v3)) != 0) { 667943ee2b1SBill Fenner TCHECK(*dp); 668cc391cceSBruce M Simpson type = (nfs_type)EXTRACT_32BITS(dp); 669cc391cceSBruce M Simpson dp++; 670943ee2b1SBill Fenner if ((dp = parse_sattr3(dp, &sa3)) == 0) 671647f50c3SDoug Rabson break; 672647f50c3SDoug Rabson printf(" %s", tok2str(type2str, "unk-ft %d", type)); 673647f50c3SDoug Rabson if (vflag && (type == NFCHR || type == NFBLK)) { 674943ee2b1SBill Fenner TCHECK(dp[1]); 675943ee2b1SBill Fenner printf(" %u/%u", 676cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[0]), 677cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[1])); 678647f50c3SDoug Rabson dp += 2; 679647f50c3SDoug Rabson } 680647f50c3SDoug Rabson if (vflag) 681647f50c3SDoug Rabson print_sattr3(&sa3, vflag); 682647f50c3SDoug Rabson return; 683647f50c3SDoug Rabson } 684647f50c3SDoug Rabson break; 685647f50c3SDoug Rabson 6864edb46e9SPaul Traina case NFSPROC_REMOVE: 6874edb46e9SPaul Traina printf(" remove"); 688943ee2b1SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 689943ee2b1SBill Fenner parsefhn(dp, v3) != NULL) 690647f50c3SDoug Rabson return; 691647f50c3SDoug Rabson break; 692647f50c3SDoug Rabson 693647f50c3SDoug Rabson case NFSPROC_RMDIR: 694647f50c3SDoug Rabson printf(" rmdir"); 695943ee2b1SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 696943ee2b1SBill Fenner parsefhn(dp, v3) != NULL) 6974edb46e9SPaul Traina return; 6984edb46e9SPaul Traina break; 6994edb46e9SPaul Traina 7004edb46e9SPaul Traina case NFSPROC_RENAME: 7014edb46e9SPaul Traina printf(" rename"); 7022ebf6c05SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 7032ebf6c05SBill Fenner (dp = parsefhn(dp, v3)) != NULL) { 7044edb46e9SPaul Traina fputs(" ->", stdout); 7052ebf6c05SBill Fenner if (parsefhn(dp, v3) != NULL) 7064edb46e9SPaul Traina return; 7074edb46e9SPaul Traina } 7084edb46e9SPaul Traina break; 7094edb46e9SPaul Traina 7104edb46e9SPaul Traina case NFSPROC_LINK: 7114edb46e9SPaul Traina printf(" link"); 7122ebf6c05SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 7132ebf6c05SBill Fenner (dp = parsefh(dp, v3)) != NULL) { 7144edb46e9SPaul Traina fputs(" ->", stdout); 7152ebf6c05SBill Fenner if (parsefhn(dp, v3) != NULL) 7164edb46e9SPaul Traina return; 7174edb46e9SPaul Traina } 7184edb46e9SPaul Traina break; 7194edb46e9SPaul Traina 7204edb46e9SPaul Traina case NFSPROC_READDIR: 7214edb46e9SPaul Traina printf(" readdir"); 7222ebf6c05SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 7232ebf6c05SBill Fenner (dp = parsefh(dp, v3)) != NULL) { 724647f50c3SDoug Rabson if (v3) { 725943ee2b1SBill Fenner TCHECK(dp[4]); 7264edb46e9SPaul Traina /* 727647f50c3SDoug Rabson * We shouldn't really try to interpret the 728647f50c3SDoug Rabson * offset cookie here. 7294edb46e9SPaul Traina */ 730c1ad1296SSam Leffler printf(" %u bytes @ %" PRId64, 731c1ad1296SSam Leffler EXTRACT_32BITS(&dp[4]), 732c1ad1296SSam Leffler EXTRACT_64BITS(&dp[0])); 733647f50c3SDoug Rabson if (vflag) 7342ebf6c05SBill Fenner printf(" verf %08x%08x", dp[2], 735647f50c3SDoug Rabson dp[3]); 736647f50c3SDoug Rabson } else { 737943ee2b1SBill Fenner TCHECK(dp[1]); 738647f50c3SDoug Rabson /* 739647f50c3SDoug Rabson * Print the offset as signed, since -1 is 740647f50c3SDoug Rabson * common, but offsets > 2^31 aren't. 741647f50c3SDoug Rabson */ 742943ee2b1SBill Fenner printf(" %u bytes @ %d", 743cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[1]), 744cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[0])); 745647f50c3SDoug Rabson } 7464edb46e9SPaul Traina return; 7474edb46e9SPaul Traina } 7484edb46e9SPaul Traina break; 7494edb46e9SPaul Traina 750647f50c3SDoug Rabson case NFSPROC_READDIRPLUS: 751647f50c3SDoug Rabson printf(" readdirplus"); 7522ebf6c05SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 7532ebf6c05SBill Fenner (dp = parsefh(dp, v3)) != NULL) { 754943ee2b1SBill Fenner TCHECK(dp[4]); 755647f50c3SDoug Rabson /* 756647f50c3SDoug Rabson * We don't try to interpret the offset 757647f50c3SDoug Rabson * cookie here. 758647f50c3SDoug Rabson */ 759c1ad1296SSam Leffler printf(" %u bytes @ %" PRId64, 760c1ad1296SSam Leffler EXTRACT_32BITS(&dp[4]), 761c1ad1296SSam Leffler EXTRACT_64BITS(&dp[0])); 762c1ad1296SSam Leffler if (vflag) { 763c1ad1296SSam Leffler TCHECK(dp[5]); 764943ee2b1SBill Fenner printf(" max %u verf %08x%08x", 765cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[5]), dp[2], dp[3]); 766c1ad1296SSam Leffler } 767647f50c3SDoug Rabson return; 768647f50c3SDoug Rabson } 769647f50c3SDoug Rabson break; 770647f50c3SDoug Rabson 771647f50c3SDoug Rabson case NFSPROC_FSSTAT: 772647f50c3SDoug Rabson printf(" fsstat"); 773943ee2b1SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 774943ee2b1SBill Fenner parsefh(dp, v3) != NULL) 7754edb46e9SPaul Traina return; 7764edb46e9SPaul Traina break; 7774edb46e9SPaul Traina 778647f50c3SDoug Rabson case NFSPROC_FSINFO: 779647f50c3SDoug Rabson printf(" fsinfo"); 7800e0def19SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 7810e0def19SBill Fenner parsefh(dp, v3) != NULL) 7820e0def19SBill Fenner return; 783647f50c3SDoug Rabson break; 784647f50c3SDoug Rabson 785647f50c3SDoug Rabson case NFSPROC_PATHCONF: 786647f50c3SDoug Rabson printf(" pathconf"); 7870e0def19SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 7880e0def19SBill Fenner parsefh(dp, v3) != NULL) 7890e0def19SBill Fenner return; 790647f50c3SDoug Rabson break; 791647f50c3SDoug Rabson 792647f50c3SDoug Rabson case NFSPROC_COMMIT: 793647f50c3SDoug Rabson printf(" commit"); 7942ebf6c05SBill Fenner if ((dp = parsereq(rp, length)) != NULL && 7952ebf6c05SBill Fenner (dp = parsefh(dp, v3)) != NULL) { 796c1ad1296SSam Leffler TCHECK(dp[2]); 797c1ad1296SSam Leffler printf(" %u bytes @ %" PRIu64, 798c1ad1296SSam Leffler EXTRACT_32BITS(&dp[2]), 799c1ad1296SSam Leffler EXTRACT_64BITS(&dp[0])); 800647f50c3SDoug Rabson return; 801647f50c3SDoug Rabson } 802647f50c3SDoug Rabson break; 803647f50c3SDoug Rabson 8044edb46e9SPaul Traina default: 805cc391cceSBruce M Simpson printf(" proc-%u", EXTRACT_32BITS(&rp->rm_call.cb_proc)); 8064edb46e9SPaul Traina return; 8074edb46e9SPaul Traina } 808943ee2b1SBill Fenner 8094edb46e9SPaul Traina trunc: 8102ebf6c05SBill Fenner if (!nfserr) 8114edb46e9SPaul Traina fputs(" [|nfs]", stdout); 8124edb46e9SPaul Traina } 8134edb46e9SPaul Traina 8144edb46e9SPaul Traina /* 8154edb46e9SPaul Traina * Print out an NFS file handle. 8164edb46e9SPaul Traina * We assume packet was not truncated before the end of the 8174edb46e9SPaul Traina * file handle pointed to by dp. 8184edb46e9SPaul Traina * 8194edb46e9SPaul Traina * Note: new version (using portable file-handle parser) doesn't produce 8204edb46e9SPaul Traina * generation number. It probably could be made to do that, with some 8214edb46e9SPaul Traina * additional hacking on the parser code. 8224edb46e9SPaul Traina */ 8234edb46e9SPaul Traina static void 824943ee2b1SBill Fenner nfs_printfh(register const u_int32_t *dp, const u_int len) 8254edb46e9SPaul Traina { 8264edb46e9SPaul Traina my_fsid fsid; 8274edb46e9SPaul Traina ino_t ino; 828cc391cceSBruce M Simpson const char *sfsname = NULL; 829cc391cceSBruce M Simpson char *spacep; 8304edb46e9SPaul Traina 831cc391cceSBruce M Simpson if (uflag) { 832cc391cceSBruce M Simpson u_int i; 833cc391cceSBruce M Simpson char const *sep = ""; 834cc391cceSBruce M Simpson 835cc391cceSBruce M Simpson printf(" fh["); 836cc391cceSBruce M Simpson for (i=0; i<len; i++) { 837cc391cceSBruce M Simpson (void)printf("%s%x", sep, dp[i]); 838cc391cceSBruce M Simpson sep = ":"; 839cc391cceSBruce M Simpson } 840cc391cceSBruce M Simpson printf("]"); 841cc391cceSBruce M Simpson return; 842cc391cceSBruce M Simpson } 843cc391cceSBruce M Simpson 844cc391cceSBruce M Simpson Parse_fh((const u_char *)dp, len, &fsid, &ino, NULL, &sfsname, 0); 8454edb46e9SPaul Traina 8464edb46e9SPaul Traina if (sfsname) { 8474edb46e9SPaul Traina /* file system ID is ASCII, not numeric, for this server OS */ 848647f50c3SDoug Rabson static char temp[NFSX_V3FHMAX+1]; 8494edb46e9SPaul Traina 8504edb46e9SPaul Traina /* Make sure string is null-terminated */ 851647f50c3SDoug Rabson strncpy(temp, sfsname, NFSX_V3FHMAX); 852943ee2b1SBill Fenner temp[sizeof(temp) - 1] = '\0'; 8534edb46e9SPaul Traina /* Remove trailing spaces */ 854cc391cceSBruce M Simpson spacep = strchr(temp, ' '); 855cc391cceSBruce M Simpson if (spacep) 856cc391cceSBruce M Simpson *spacep = '\0'; 8574edb46e9SPaul Traina 858943ee2b1SBill Fenner (void)printf(" fh %s/", temp); 8592ebf6c05SBill Fenner } else { 860943ee2b1SBill Fenner (void)printf(" fh %d,%d/", 861943ee2b1SBill Fenner fsid.Fsid_dev.Major, fsid.Fsid_dev.Minor); 8624edb46e9SPaul Traina } 863943ee2b1SBill Fenner 864cc391cceSBruce M Simpson if(fsid.Fsid_dev.Minor == 257) 865943ee2b1SBill Fenner /* Print the undecoded handle */ 866943ee2b1SBill Fenner (void)printf("%s", fsid.Opaque_Handle); 867943ee2b1SBill Fenner else 868943ee2b1SBill Fenner (void)printf("%ld", (long) ino); 8694edb46e9SPaul Traina } 8704edb46e9SPaul Traina 8714edb46e9SPaul Traina /* 8724edb46e9SPaul Traina * Maintain a small cache of recent client.XID.server/proc pairs, to allow 8734edb46e9SPaul Traina * us to match up replies with requests and thus to know how to parse 8744edb46e9SPaul Traina * the reply. 8754edb46e9SPaul Traina */ 8764edb46e9SPaul Traina 8774edb46e9SPaul Traina struct xid_map_entry { 8784edb46e9SPaul Traina u_int32_t xid; /* transaction ID (net order) */ 879943ee2b1SBill Fenner int ipver; /* IP version (4 or 6) */ 880943ee2b1SBill Fenner #ifdef INET6 881943ee2b1SBill Fenner struct in6_addr client; /* client IP address (net order) */ 882943ee2b1SBill Fenner struct in6_addr server; /* server IP address (net order) */ 883943ee2b1SBill Fenner #else 8844edb46e9SPaul Traina struct in_addr client; /* client IP address (net order) */ 8854edb46e9SPaul Traina struct in_addr server; /* server IP address (net order) */ 886943ee2b1SBill Fenner #endif 8874edb46e9SPaul Traina u_int32_t proc; /* call proc number (host order) */ 888647f50c3SDoug Rabson u_int32_t vers; /* program version (host order) */ 8894edb46e9SPaul Traina }; 8904edb46e9SPaul Traina 8914edb46e9SPaul Traina /* 8924edb46e9SPaul Traina * Map entries are kept in an array that we manage as a ring; 8934edb46e9SPaul Traina * new entries are always added at the tail of the ring. Initially, 8944edb46e9SPaul Traina * all the entries are zero and hence don't match anything. 8954edb46e9SPaul Traina */ 8964edb46e9SPaul Traina 8974edb46e9SPaul Traina #define XIDMAPSIZE 64 8984edb46e9SPaul Traina 8994edb46e9SPaul Traina struct xid_map_entry xid_map[XIDMAPSIZE]; 9004edb46e9SPaul Traina 9014edb46e9SPaul Traina int xid_map_next = 0; 9024edb46e9SPaul Traina int xid_map_hint = 0; 9034edb46e9SPaul Traina 904a5779b6eSRui Paulo static int 905c1ad1296SSam Leffler xid_map_enter(const struct sunrpc_msg *rp, const u_char *bp) 9064edb46e9SPaul Traina { 907943ee2b1SBill Fenner struct ip *ip = NULL; 908943ee2b1SBill Fenner #ifdef INET6 909943ee2b1SBill Fenner struct ip6_hdr *ip6 = NULL; 910943ee2b1SBill Fenner #endif 9114edb46e9SPaul Traina struct xid_map_entry *xmep; 9124edb46e9SPaul Traina 913a5779b6eSRui Paulo if (!TTEST(rp->rm_call.cb_vers)) 914a5779b6eSRui Paulo return (0); 915943ee2b1SBill Fenner switch (IP_V((struct ip *)bp)) { 916943ee2b1SBill Fenner case 4: 917943ee2b1SBill Fenner ip = (struct ip *)bp; 918943ee2b1SBill Fenner break; 919943ee2b1SBill Fenner #ifdef INET6 920943ee2b1SBill Fenner case 6: 921943ee2b1SBill Fenner ip6 = (struct ip6_hdr *)bp; 922943ee2b1SBill Fenner break; 923943ee2b1SBill Fenner #endif 924943ee2b1SBill Fenner default: 925a5779b6eSRui Paulo return (1); 926943ee2b1SBill Fenner } 927943ee2b1SBill Fenner 9284edb46e9SPaul Traina xmep = &xid_map[xid_map_next]; 9294edb46e9SPaul Traina 9304edb46e9SPaul Traina if (++xid_map_next >= XIDMAPSIZE) 9314edb46e9SPaul Traina xid_map_next = 0; 9324edb46e9SPaul Traina 9334edb46e9SPaul Traina xmep->xid = rp->rm_xid; 934943ee2b1SBill Fenner if (ip) { 935943ee2b1SBill Fenner xmep->ipver = 4; 936943ee2b1SBill Fenner memcpy(&xmep->client, &ip->ip_src, sizeof(ip->ip_src)); 937943ee2b1SBill Fenner memcpy(&xmep->server, &ip->ip_dst, sizeof(ip->ip_dst)); 938943ee2b1SBill Fenner } 939943ee2b1SBill Fenner #ifdef INET6 940943ee2b1SBill Fenner else if (ip6) { 941943ee2b1SBill Fenner xmep->ipver = 6; 942943ee2b1SBill Fenner memcpy(&xmep->client, &ip6->ip6_src, sizeof(ip6->ip6_src)); 943943ee2b1SBill Fenner memcpy(&xmep->server, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); 944943ee2b1SBill Fenner } 945943ee2b1SBill Fenner #endif 946cc391cceSBruce M Simpson xmep->proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); 947cc391cceSBruce M Simpson xmep->vers = EXTRACT_32BITS(&rp->rm_call.cb_vers); 948a5779b6eSRui Paulo return (1); 9494edb46e9SPaul Traina } 9504edb46e9SPaul Traina 9512ebf6c05SBill Fenner /* 9522ebf6c05SBill Fenner * Returns 0 and puts NFSPROC_xxx in proc return and 9532ebf6c05SBill Fenner * version in vers return, or returns -1 on failure 9542ebf6c05SBill Fenner */ 955647f50c3SDoug Rabson static int 956c1ad1296SSam Leffler xid_map_find(const struct sunrpc_msg *rp, const u_char *bp, u_int32_t *proc, 957647f50c3SDoug Rabson u_int32_t *vers) 9584edb46e9SPaul Traina { 9594edb46e9SPaul Traina int i; 9604edb46e9SPaul Traina struct xid_map_entry *xmep; 9614edb46e9SPaul Traina u_int32_t xid = rp->rm_xid; 962943ee2b1SBill Fenner struct ip *ip = (struct ip *)bp; 963943ee2b1SBill Fenner #ifdef INET6 964943ee2b1SBill Fenner struct ip6_hdr *ip6 = (struct ip6_hdr *)bp; 965943ee2b1SBill Fenner #endif 966943ee2b1SBill Fenner int cmp; 9674edb46e9SPaul Traina 9684edb46e9SPaul Traina /* Start searching from where we last left off */ 9694edb46e9SPaul Traina i = xid_map_hint; 9704edb46e9SPaul Traina do { 9714edb46e9SPaul Traina xmep = &xid_map[i]; 972943ee2b1SBill Fenner cmp = 1; 973943ee2b1SBill Fenner if (xmep->ipver != IP_V(ip) || xmep->xid != xid) 974943ee2b1SBill Fenner goto nextitem; 975943ee2b1SBill Fenner switch (xmep->ipver) { 976943ee2b1SBill Fenner case 4: 977943ee2b1SBill Fenner if (memcmp(&ip->ip_src, &xmep->server, 978943ee2b1SBill Fenner sizeof(ip->ip_src)) != 0 || 979943ee2b1SBill Fenner memcmp(&ip->ip_dst, &xmep->client, 980943ee2b1SBill Fenner sizeof(ip->ip_dst)) != 0) { 981943ee2b1SBill Fenner cmp = 0; 982943ee2b1SBill Fenner } 983943ee2b1SBill Fenner break; 984943ee2b1SBill Fenner #ifdef INET6 985943ee2b1SBill Fenner case 6: 986943ee2b1SBill Fenner if (memcmp(&ip6->ip6_src, &xmep->server, 987943ee2b1SBill Fenner sizeof(ip6->ip6_src)) != 0 || 988943ee2b1SBill Fenner memcmp(&ip6->ip6_dst, &xmep->client, 989943ee2b1SBill Fenner sizeof(ip6->ip6_dst)) != 0) { 990943ee2b1SBill Fenner cmp = 0; 991943ee2b1SBill Fenner } 992943ee2b1SBill Fenner break; 993943ee2b1SBill Fenner #endif 994943ee2b1SBill Fenner default: 995943ee2b1SBill Fenner cmp = 0; 996943ee2b1SBill Fenner break; 997943ee2b1SBill Fenner } 998943ee2b1SBill Fenner if (cmp) { 9994edb46e9SPaul Traina /* match */ 10004edb46e9SPaul Traina xid_map_hint = i; 1001647f50c3SDoug Rabson *proc = xmep->proc; 1002647f50c3SDoug Rabson *vers = xmep->vers; 1003647f50c3SDoug Rabson return 0; 10044edb46e9SPaul Traina } 1005943ee2b1SBill Fenner nextitem: 10064edb46e9SPaul Traina if (++i >= XIDMAPSIZE) 10074edb46e9SPaul Traina i = 0; 10084edb46e9SPaul Traina } while (i != xid_map_hint); 10094edb46e9SPaul Traina 10104edb46e9SPaul Traina /* search failed */ 1011943ee2b1SBill Fenner return (-1); 10124edb46e9SPaul Traina } 10134edb46e9SPaul Traina 10144edb46e9SPaul Traina /* 10154edb46e9SPaul Traina * Routines for parsing reply packets 10164edb46e9SPaul Traina */ 10174edb46e9SPaul Traina 10184edb46e9SPaul Traina /* 10194edb46e9SPaul Traina * Return a pointer to the beginning of the actual results. 1020943ee2b1SBill Fenner * If the packet was truncated, return 0. 10214edb46e9SPaul Traina */ 10224edb46e9SPaul Traina static const u_int32_t * 1023c1ad1296SSam Leffler parserep(register const struct sunrpc_msg *rp, register u_int length) 10244edb46e9SPaul Traina { 10254edb46e9SPaul Traina register const u_int32_t *dp; 1026943ee2b1SBill Fenner u_int len; 1027c1ad1296SSam Leffler enum sunrpc_accept_stat astat; 10284edb46e9SPaul Traina 10294edb46e9SPaul Traina /* 10304edb46e9SPaul Traina * Portability note: 10314edb46e9SPaul Traina * Here we find the address of the ar_verf credentials. 10324edb46e9SPaul Traina * Originally, this calculation was 10334edb46e9SPaul Traina * dp = (u_int32_t *)&rp->rm_reply.rp_acpt.ar_verf 10344edb46e9SPaul Traina * On the wire, the rp_acpt field starts immediately after 10354edb46e9SPaul Traina * the (32 bit) rp_stat field. However, rp_acpt (which is a 10364edb46e9SPaul Traina * "struct accepted_reply") contains a "struct opaque_auth", 10374edb46e9SPaul Traina * whose internal representation contains a pointer, so on a 10384edb46e9SPaul Traina * 64-bit machine the compiler inserts 32 bits of padding 10394edb46e9SPaul Traina * before rp->rm_reply.rp_acpt.ar_verf. So, we cannot use 10404edb46e9SPaul Traina * the internal representation to parse the on-the-wire 10414edb46e9SPaul Traina * representation. Instead, we skip past the rp_stat field, 10424edb46e9SPaul Traina * which is an "enum" and so occupies one 32-bit word. 10434edb46e9SPaul Traina */ 10444edb46e9SPaul Traina dp = ((const u_int32_t *)&rp->rm_reply) + 1; 1045943ee2b1SBill Fenner TCHECK(dp[1]); 1046cc391cceSBruce M Simpson len = EXTRACT_32BITS(&dp[1]); 10474edb46e9SPaul Traina if (len >= length) 10482ebf6c05SBill Fenner return (NULL); 10494edb46e9SPaul Traina /* 10504edb46e9SPaul Traina * skip past the ar_verf credentials. 10514edb46e9SPaul Traina */ 10524edb46e9SPaul Traina dp += (len + (2*sizeof(u_int32_t) + 3)) / sizeof(u_int32_t); 10532ebf6c05SBill Fenner TCHECK2(dp[0], 0); 10544edb46e9SPaul Traina 10554edb46e9SPaul Traina /* 10564edb46e9SPaul Traina * now we can check the ar_stat field 10574edb46e9SPaul Traina */ 105829292c17SSam Leffler astat = (enum sunrpc_accept_stat) EXTRACT_32BITS(dp); 10594edb46e9SPaul Traina switch (astat) { 10604edb46e9SPaul Traina 1061c1ad1296SSam Leffler case SUNRPC_SUCCESS: 10624edb46e9SPaul Traina break; 10634edb46e9SPaul Traina 1064c1ad1296SSam Leffler case SUNRPC_PROG_UNAVAIL: 10654edb46e9SPaul Traina printf(" PROG_UNAVAIL"); 10662ebf6c05SBill Fenner nfserr = 1; /* suppress trunc string */ 10672ebf6c05SBill Fenner return (NULL); 10684edb46e9SPaul Traina 1069c1ad1296SSam Leffler case SUNRPC_PROG_MISMATCH: 10704edb46e9SPaul Traina printf(" PROG_MISMATCH"); 10712ebf6c05SBill Fenner nfserr = 1; /* suppress trunc string */ 10722ebf6c05SBill Fenner return (NULL); 10734edb46e9SPaul Traina 1074c1ad1296SSam Leffler case SUNRPC_PROC_UNAVAIL: 10754edb46e9SPaul Traina printf(" PROC_UNAVAIL"); 10762ebf6c05SBill Fenner nfserr = 1; /* suppress trunc string */ 10772ebf6c05SBill Fenner return (NULL); 10784edb46e9SPaul Traina 1079c1ad1296SSam Leffler case SUNRPC_GARBAGE_ARGS: 10804edb46e9SPaul Traina printf(" GARBAGE_ARGS"); 10812ebf6c05SBill Fenner nfserr = 1; /* suppress trunc string */ 10822ebf6c05SBill Fenner return (NULL); 10834edb46e9SPaul Traina 1084c1ad1296SSam Leffler case SUNRPC_SYSTEM_ERR: 10854edb46e9SPaul Traina printf(" SYSTEM_ERR"); 10862ebf6c05SBill Fenner nfserr = 1; /* suppress trunc string */ 10872ebf6c05SBill Fenner return (NULL); 10884edb46e9SPaul Traina 10894edb46e9SPaul Traina default: 10904edb46e9SPaul Traina printf(" ar_stat %d", astat); 10912ebf6c05SBill Fenner nfserr = 1; /* suppress trunc string */ 10922ebf6c05SBill Fenner return (NULL); 10934edb46e9SPaul Traina } 10944edb46e9SPaul Traina /* successful return */ 1095943ee2b1SBill Fenner TCHECK2(*dp, sizeof(astat)); 10964edb46e9SPaul Traina return ((u_int32_t *) (sizeof(astat) + ((char *)dp))); 10972ebf6c05SBill Fenner trunc: 1098943ee2b1SBill Fenner return (0); 10994edb46e9SPaul Traina } 11004edb46e9SPaul Traina 1101647f50c3SDoug Rabson static const u_int32_t * 1102647f50c3SDoug Rabson parsestatus(const u_int32_t *dp, int *er) 1103647f50c3SDoug Rabson { 1104943ee2b1SBill Fenner int errnum; 1105647f50c3SDoug Rabson 11062ebf6c05SBill Fenner TCHECK(dp[0]); 1107943ee2b1SBill Fenner 1108cc391cceSBruce M Simpson errnum = EXTRACT_32BITS(&dp[0]); 1109647f50c3SDoug Rabson if (er) 11102ebf6c05SBill Fenner *er = errnum; 11112ebf6c05SBill Fenner if (errnum != 0) { 11122ebf6c05SBill Fenner if (!qflag) 1113943ee2b1SBill Fenner printf(" ERROR: %s", 1114943ee2b1SBill Fenner tok2str(status2str, "unk %d", errnum)); 11152ebf6c05SBill Fenner nfserr = 1; 11164edb46e9SPaul Traina } 11174edb46e9SPaul Traina return (dp + 1); 11182ebf6c05SBill Fenner trunc: 1119943ee2b1SBill Fenner return NULL; 11204edb46e9SPaul Traina } 11214edb46e9SPaul Traina 11224edb46e9SPaul Traina static const u_int32_t * 1123647f50c3SDoug Rabson parsefattr(const u_int32_t *dp, int verbose, int v3) 11244edb46e9SPaul Traina { 1125647f50c3SDoug Rabson const struct nfs_fattr *fap; 11264edb46e9SPaul Traina 1127647f50c3SDoug Rabson fap = (const struct nfs_fattr *)dp; 1128685b49deSBill Fenner TCHECK(fap->fa_gid); 11294edb46e9SPaul Traina if (verbose) { 1130943ee2b1SBill Fenner printf(" %s %o ids %d/%d", 1131943ee2b1SBill Fenner tok2str(type2str, "unk-ft %d ", 1132cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa_type)), 1133cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa_mode), 1134cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa_uid), 1135cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa_gid)); 1136647f50c3SDoug Rabson if (v3) { 1137685b49deSBill Fenner TCHECK(fap->fa3_size); 1138c1ad1296SSam Leffler printf(" sz %" PRIu64, 1139c1ad1296SSam Leffler EXTRACT_64BITS((u_int32_t *)&fap->fa3_size)); 1140685b49deSBill Fenner } else { 1141685b49deSBill Fenner TCHECK(fap->fa2_size); 1142cc391cceSBruce M Simpson printf(" sz %d", EXTRACT_32BITS(&fap->fa2_size)); 1143647f50c3SDoug Rabson } 11444edb46e9SPaul Traina } 11454edb46e9SPaul Traina /* print lots more stuff */ 11464edb46e9SPaul Traina if (verbose > 1) { 1147647f50c3SDoug Rabson if (v3) { 1148685b49deSBill Fenner TCHECK(fap->fa3_ctime); 1149943ee2b1SBill Fenner printf(" nlink %d rdev %d/%d", 1150cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa_nlink), 1151cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa3_rdev.specdata1), 1152cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa3_rdev.specdata2)); 1153c1ad1296SSam Leffler printf(" fsid %" PRIx64, 1154c1ad1296SSam Leffler EXTRACT_64BITS((u_int32_t *)&fap->fa3_fsid)); 1155c1ad1296SSam Leffler printf(" fileid %" PRIx64, 1156c1ad1296SSam Leffler EXTRACT_64BITS((u_int32_t *)&fap->fa3_fileid)); 1157943ee2b1SBill Fenner printf(" a/m/ctime %u.%06u", 1158cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa3_atime.nfsv3_sec), 1159cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa3_atime.nfsv3_nsec)); 1160943ee2b1SBill Fenner printf(" %u.%06u", 1161cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_sec), 1162cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_nsec)); 1163943ee2b1SBill Fenner printf(" %u.%06u", 1164cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_sec), 1165cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_nsec)); 1166647f50c3SDoug Rabson } else { 1167685b49deSBill Fenner TCHECK(fap->fa2_ctime); 1168943ee2b1SBill Fenner printf(" nlink %d rdev %x fsid %x nodeid %x a/m/ctime", 1169cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa_nlink), 1170cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa2_rdev), 1171cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa2_fsid), 1172cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa2_fileid)); 1173943ee2b1SBill Fenner printf(" %u.%06u", 1174cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa2_atime.nfsv2_sec), 1175cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa2_atime.nfsv2_usec)); 1176943ee2b1SBill Fenner printf(" %u.%06u", 1177cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_sec), 1178cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_usec)); 1179943ee2b1SBill Fenner printf(" %u.%06u", 1180cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_sec), 1181cc391cceSBruce M Simpson EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_usec)); 11824edb46e9SPaul Traina } 1183647f50c3SDoug Rabson } 1184647f50c3SDoug Rabson return ((const u_int32_t *)((unsigned char *)dp + 1185647f50c3SDoug Rabson (v3 ? NFSX_V3FATTR : NFSX_V2FATTR))); 1186685b49deSBill Fenner trunc: 1187685b49deSBill Fenner return (NULL); 11884edb46e9SPaul Traina } 11894edb46e9SPaul Traina 11904edb46e9SPaul Traina static int 1191647f50c3SDoug Rabson parseattrstat(const u_int32_t *dp, int verbose, int v3) 11924edb46e9SPaul Traina { 1193647f50c3SDoug Rabson int er; 1194647f50c3SDoug Rabson 1195647f50c3SDoug Rabson dp = parsestatus(dp, &er); 11960e0def19SBill Fenner if (dp == NULL) 11974edb46e9SPaul Traina return (0); 11980e0def19SBill Fenner if (er) 11990e0def19SBill Fenner return (1); 12004edb46e9SPaul Traina 12012ebf6c05SBill Fenner return (parsefattr(dp, verbose, v3) != NULL); 12024edb46e9SPaul Traina } 12034edb46e9SPaul Traina 12044edb46e9SPaul Traina static int 12054edb46e9SPaul Traina parsediropres(const u_int32_t *dp) 12064edb46e9SPaul Traina { 1207647f50c3SDoug Rabson int er; 1208647f50c3SDoug Rabson 12090e0def19SBill Fenner if (!(dp = parsestatus(dp, &er))) 1210647f50c3SDoug Rabson return (0); 12110e0def19SBill Fenner if (er) 12120e0def19SBill Fenner return (1); 1213647f50c3SDoug Rabson 1214647f50c3SDoug Rabson dp = parsefh(dp, 0); 12154edb46e9SPaul Traina if (dp == NULL) 12164edb46e9SPaul Traina return (0); 12174edb46e9SPaul Traina 1218647f50c3SDoug Rabson return (parsefattr(dp, vflag, 0) != NULL); 12194edb46e9SPaul Traina } 12204edb46e9SPaul Traina 12214edb46e9SPaul Traina static int 1222647f50c3SDoug Rabson parselinkres(const u_int32_t *dp, int v3) 12234edb46e9SPaul Traina { 1224647f50c3SDoug Rabson int er; 12254edb46e9SPaul Traina 1226647f50c3SDoug Rabson dp = parsestatus(dp, &er); 12270e0def19SBill Fenner if (dp == NULL) 1228647f50c3SDoug Rabson return(0); 12290e0def19SBill Fenner if (er) 12300e0def19SBill Fenner return(1); 1231943ee2b1SBill Fenner if (v3 && !(dp = parse_post_op_attr(dp, vflag))) 1232647f50c3SDoug Rabson return (0); 12334edb46e9SPaul Traina putchar(' '); 12344edb46e9SPaul Traina return (parsefn(dp) != NULL); 12354edb46e9SPaul Traina } 12364edb46e9SPaul Traina 12374edb46e9SPaul Traina static int 1238647f50c3SDoug Rabson parsestatfs(const u_int32_t *dp, int v3) 12394edb46e9SPaul Traina { 1240647f50c3SDoug Rabson const struct nfs_statfs *sfsp; 1241647f50c3SDoug Rabson int er; 12424edb46e9SPaul Traina 1243647f50c3SDoug Rabson dp = parsestatus(dp, &er); 12440e0def19SBill Fenner if (dp == NULL) 12454edb46e9SPaul Traina return (0); 12460e0def19SBill Fenner if (!v3 && er) 12470e0def19SBill Fenner return (1); 12484edb46e9SPaul Traina 1249647f50c3SDoug Rabson if (qflag) 1250647f50c3SDoug Rabson return(1); 1251647f50c3SDoug Rabson 1252647f50c3SDoug Rabson if (v3) { 1253647f50c3SDoug Rabson if (vflag) 1254647f50c3SDoug Rabson printf(" POST:"); 1255943ee2b1SBill Fenner if (!(dp = parse_post_op_attr(dp, vflag))) 1256647f50c3SDoug Rabson return (0); 1257647f50c3SDoug Rabson } 1258647f50c3SDoug Rabson 12590e0def19SBill Fenner TCHECK2(*dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); 1260647f50c3SDoug Rabson 1261647f50c3SDoug Rabson sfsp = (const struct nfs_statfs *)dp; 1262647f50c3SDoug Rabson 1263647f50c3SDoug Rabson if (v3) { 1264c1ad1296SSam Leffler printf(" tbytes %" PRIu64 " fbytes %" PRIu64 " abytes %" PRIu64, 1265c1ad1296SSam Leffler EXTRACT_64BITS((u_int32_t *)&sfsp->sf_tbytes), 1266c1ad1296SSam Leffler EXTRACT_64BITS((u_int32_t *)&sfsp->sf_fbytes), 1267c1ad1296SSam Leffler EXTRACT_64BITS((u_int32_t *)&sfsp->sf_abytes)); 1268647f50c3SDoug Rabson if (vflag) { 1269c1ad1296SSam Leffler printf(" tfiles %" PRIu64 " ffiles %" PRIu64 " afiles %" PRIu64 " invar %u", 1270c1ad1296SSam Leffler EXTRACT_64BITS((u_int32_t *)&sfsp->sf_tfiles), 1271c1ad1296SSam Leffler EXTRACT_64BITS((u_int32_t *)&sfsp->sf_ffiles), 1272c1ad1296SSam Leffler EXTRACT_64BITS((u_int32_t *)&sfsp->sf_afiles), 1273cc391cceSBruce M Simpson EXTRACT_32BITS(&sfsp->sf_invarsec)); 1274647f50c3SDoug Rabson } 1275647f50c3SDoug Rabson } else { 1276943ee2b1SBill Fenner printf(" tsize %d bsize %d blocks %d bfree %d bavail %d", 1277cc391cceSBruce M Simpson EXTRACT_32BITS(&sfsp->sf_tsize), 1278cc391cceSBruce M Simpson EXTRACT_32BITS(&sfsp->sf_bsize), 1279cc391cceSBruce M Simpson EXTRACT_32BITS(&sfsp->sf_blocks), 1280cc391cceSBruce M Simpson EXTRACT_32BITS(&sfsp->sf_bfree), 1281cc391cceSBruce M Simpson EXTRACT_32BITS(&sfsp->sf_bavail)); 12824edb46e9SPaul Traina } 12834edb46e9SPaul Traina 12844edb46e9SPaul Traina return (1); 1285685b49deSBill Fenner trunc: 1286685b49deSBill Fenner return (0); 12874edb46e9SPaul Traina } 12884edb46e9SPaul Traina 12894edb46e9SPaul Traina static int 12904edb46e9SPaul Traina parserddires(const u_int32_t *dp) 12914edb46e9SPaul Traina { 1292647f50c3SDoug Rabson int er; 1293647f50c3SDoug Rabson 1294647f50c3SDoug Rabson dp = parsestatus(dp, &er); 12950e0def19SBill Fenner if (dp == NULL) 12964edb46e9SPaul Traina return (0); 12970e0def19SBill Fenner if (er) 12980e0def19SBill Fenner return (1); 1299647f50c3SDoug Rabson if (qflag) 1300647f50c3SDoug Rabson return (1); 1301647f50c3SDoug Rabson 1302685b49deSBill Fenner TCHECK(dp[2]); 1303943ee2b1SBill Fenner printf(" offset %x size %d ", 1304cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[0]), EXTRACT_32BITS(&dp[1])); 13054edb46e9SPaul Traina if (dp[2] != 0) 13064edb46e9SPaul Traina printf(" eof"); 13074edb46e9SPaul Traina 13084edb46e9SPaul Traina return (1); 1309685b49deSBill Fenner trunc: 1310685b49deSBill Fenner return (0); 1311647f50c3SDoug Rabson } 1312647f50c3SDoug Rabson 1313647f50c3SDoug Rabson static const u_int32_t * 1314647f50c3SDoug Rabson parse_wcc_attr(const u_int32_t *dp) 1315647f50c3SDoug Rabson { 1316c1ad1296SSam Leffler printf(" sz %" PRIu64, EXTRACT_64BITS(&dp[0])); 1317943ee2b1SBill Fenner printf(" mtime %u.%06u ctime %u.%06u", 1318cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[3]), 1319cc391cceSBruce M Simpson EXTRACT_32BITS(&dp[4]), EXTRACT_32BITS(&dp[5])); 1320647f50c3SDoug Rabson return (dp + 6); 1321647f50c3SDoug Rabson } 1322647f50c3SDoug Rabson 1323647f50c3SDoug Rabson /* 1324647f50c3SDoug Rabson * Pre operation attributes. Print only if vflag > 1. 1325647f50c3SDoug Rabson */ 1326647f50c3SDoug Rabson static const u_int32_t * 1327647f50c3SDoug Rabson parse_pre_op_attr(const u_int32_t *dp, int verbose) 1328647f50c3SDoug Rabson { 1329685b49deSBill Fenner TCHECK(dp[0]); 1330cc391cceSBruce M Simpson if (!EXTRACT_32BITS(&dp[0])) 1331647f50c3SDoug Rabson return (dp + 1); 1332647f50c3SDoug Rabson dp++; 13330e0def19SBill Fenner TCHECK2(*dp, 24); 1334647f50c3SDoug Rabson if (verbose > 1) { 1335647f50c3SDoug Rabson return parse_wcc_attr(dp); 1336647f50c3SDoug Rabson } else { 1337647f50c3SDoug Rabson /* If not verbose enough, just skip over wcc_attr */ 1338647f50c3SDoug Rabson return (dp + 6); 1339647f50c3SDoug Rabson } 1340685b49deSBill Fenner trunc: 1341685b49deSBill Fenner return (NULL); 1342647f50c3SDoug Rabson } 1343647f50c3SDoug Rabson 1344647f50c3SDoug Rabson /* 1345647f50c3SDoug Rabson * Post operation attributes are printed if vflag >= 1 1346647f50c3SDoug Rabson */ 1347647f50c3SDoug Rabson static const u_int32_t * 1348647f50c3SDoug Rabson parse_post_op_attr(const u_int32_t *dp, int verbose) 1349647f50c3SDoug Rabson { 1350685b49deSBill Fenner TCHECK(dp[0]); 1351cc391cceSBruce M Simpson if (!EXTRACT_32BITS(&dp[0])) 1352647f50c3SDoug Rabson return (dp + 1); 1353647f50c3SDoug Rabson dp++; 1354647f50c3SDoug Rabson if (verbose) { 1355647f50c3SDoug Rabson return parsefattr(dp, verbose, 1); 1356647f50c3SDoug Rabson } else 1357647f50c3SDoug Rabson return (dp + (NFSX_V3FATTR / sizeof (u_int32_t))); 1358685b49deSBill Fenner trunc: 1359685b49deSBill Fenner return (NULL); 1360647f50c3SDoug Rabson } 1361647f50c3SDoug Rabson 1362647f50c3SDoug Rabson static const u_int32_t * 1363647f50c3SDoug Rabson parse_wcc_data(const u_int32_t *dp, int verbose) 1364647f50c3SDoug Rabson { 1365647f50c3SDoug Rabson if (verbose > 1) 1366647f50c3SDoug Rabson printf(" PRE:"); 1367943ee2b1SBill Fenner if (!(dp = parse_pre_op_attr(dp, verbose))) 1368943ee2b1SBill Fenner return (0); 1369647f50c3SDoug Rabson 1370647f50c3SDoug Rabson if (verbose) 1371647f50c3SDoug Rabson printf(" POST:"); 1372647f50c3SDoug Rabson return parse_post_op_attr(dp, verbose); 1373647f50c3SDoug Rabson } 1374647f50c3SDoug Rabson 1375647f50c3SDoug Rabson static const u_int32_t * 1376647f50c3SDoug Rabson parsecreateopres(const u_int32_t *dp, int verbose) 1377647f50c3SDoug Rabson { 1378647f50c3SDoug Rabson int er; 1379647f50c3SDoug Rabson 1380943ee2b1SBill Fenner if (!(dp = parsestatus(dp, &er))) 1381943ee2b1SBill Fenner return (0); 1382647f50c3SDoug Rabson if (er) 1383647f50c3SDoug Rabson dp = parse_wcc_data(dp, verbose); 1384647f50c3SDoug Rabson else { 1385685b49deSBill Fenner TCHECK(dp[0]); 1386cc391cceSBruce M Simpson if (!EXTRACT_32BITS(&dp[0])) 1387647f50c3SDoug Rabson return (dp + 1); 1388647f50c3SDoug Rabson dp++; 1389943ee2b1SBill Fenner if (!(dp = parsefh(dp, 1))) 1390943ee2b1SBill Fenner return (0); 1391647f50c3SDoug Rabson if (verbose) { 1392943ee2b1SBill Fenner if (!(dp = parse_post_op_attr(dp, verbose))) 1393943ee2b1SBill Fenner return (0); 1394647f50c3SDoug Rabson if (vflag > 1) { 1395647f50c3SDoug Rabson printf(" dir attr:"); 1396647f50c3SDoug Rabson dp = parse_wcc_data(dp, verbose); 1397647f50c3SDoug Rabson } 1398647f50c3SDoug Rabson } 1399647f50c3SDoug Rabson } 1400647f50c3SDoug Rabson return (dp); 1401685b49deSBill Fenner trunc: 1402685b49deSBill Fenner return (NULL); 1403647f50c3SDoug Rabson } 1404647f50c3SDoug Rabson 1405647f50c3SDoug Rabson static int 1406647f50c3SDoug Rabson parsewccres(const u_int32_t *dp, int verbose) 1407647f50c3SDoug Rabson { 1408647f50c3SDoug Rabson int er; 1409647f50c3SDoug Rabson 1410943ee2b1SBill Fenner if (!(dp = parsestatus(dp, &er))) 1411647f50c3SDoug Rabson return (0); 1412943ee2b1SBill Fenner return parse_wcc_data(dp, verbose) != 0; 1413647f50c3SDoug Rabson } 1414647f50c3SDoug Rabson 1415647f50c3SDoug Rabson static const u_int32_t * 1416647f50c3SDoug Rabson parsev3rddirres(const u_int32_t *dp, int verbose) 1417647f50c3SDoug Rabson { 1418647f50c3SDoug Rabson int er; 1419647f50c3SDoug Rabson 1420943ee2b1SBill Fenner if (!(dp = parsestatus(dp, &er))) 1421943ee2b1SBill Fenner return (0); 1422647f50c3SDoug Rabson if (vflag) 1423647f50c3SDoug Rabson printf(" POST:"); 1424943ee2b1SBill Fenner if (!(dp = parse_post_op_attr(dp, verbose))) 1425943ee2b1SBill Fenner return (0); 1426647f50c3SDoug Rabson if (er) 1427647f50c3SDoug Rabson return dp; 1428647f50c3SDoug Rabson if (vflag) { 1429685b49deSBill Fenner TCHECK(dp[1]); 14302ebf6c05SBill Fenner printf(" verf %08x%08x", dp[0], dp[1]); 1431647f50c3SDoug Rabson dp += 2; 1432647f50c3SDoug Rabson } 1433647f50c3SDoug Rabson return dp; 1434685b49deSBill Fenner trunc: 1435685b49deSBill Fenner return (NULL); 1436647f50c3SDoug Rabson } 1437647f50c3SDoug Rabson 1438647f50c3SDoug Rabson static int 1439647f50c3SDoug Rabson parsefsinfo(const u_int32_t *dp) 1440647f50c3SDoug Rabson { 1441647f50c3SDoug Rabson struct nfsv3_fsinfo *sfp; 1442647f50c3SDoug Rabson int er; 1443647f50c3SDoug Rabson 1444943ee2b1SBill Fenner if (!(dp = parsestatus(dp, &er))) 1445647f50c3SDoug Rabson return (0); 1446647f50c3SDoug Rabson if (vflag) 1447647f50c3SDoug Rabson printf(" POST:"); 1448943ee2b1SBill Fenner if (!(dp = parse_post_op_attr(dp, vflag))) 1449647f50c3SDoug Rabson return (0); 1450647f50c3SDoug Rabson if (er) 1451647f50c3SDoug Rabson return (1); 1452647f50c3SDoug Rabson 1453647f50c3SDoug Rabson sfp = (struct nfsv3_fsinfo *)dp; 1454685b49deSBill Fenner TCHECK(*sfp); 1455943ee2b1SBill Fenner printf(" rtmax %u rtpref %u wtmax %u wtpref %u dtpref %u", 1456cc391cceSBruce M Simpson EXTRACT_32BITS(&sfp->fs_rtmax), 1457cc391cceSBruce M Simpson EXTRACT_32BITS(&sfp->fs_rtpref), 1458cc391cceSBruce M Simpson EXTRACT_32BITS(&sfp->fs_wtmax), 1459cc391cceSBruce M Simpson EXTRACT_32BITS(&sfp->fs_wtpref), 1460cc391cceSBruce M Simpson EXTRACT_32BITS(&sfp->fs_dtpref)); 1461647f50c3SDoug Rabson if (vflag) { 1462c1ad1296SSam Leffler printf(" rtmult %u wtmult %u maxfsz %" PRIu64, 1463cc391cceSBruce M Simpson EXTRACT_32BITS(&sfp->fs_rtmult), 1464c1ad1296SSam Leffler EXTRACT_32BITS(&sfp->fs_wtmult), 1465c1ad1296SSam Leffler EXTRACT_64BITS((u_int32_t *)&sfp->fs_maxfilesize)); 1466943ee2b1SBill Fenner printf(" delta %u.%06u ", 1467cc391cceSBruce M Simpson EXTRACT_32BITS(&sfp->fs_timedelta.nfsv3_sec), 1468cc391cceSBruce M Simpson EXTRACT_32BITS(&sfp->fs_timedelta.nfsv3_nsec)); 1469647f50c3SDoug Rabson } 1470943ee2b1SBill Fenner return (1); 14710e0def19SBill Fenner trunc: 14720e0def19SBill Fenner return (0); 1473647f50c3SDoug Rabson } 1474647f50c3SDoug Rabson 1475647f50c3SDoug Rabson static int 1476647f50c3SDoug Rabson parsepathconf(const u_int32_t *dp) 1477647f50c3SDoug Rabson { 1478647f50c3SDoug Rabson int er; 1479647f50c3SDoug Rabson struct nfsv3_pathconf *spp; 1480647f50c3SDoug Rabson 1481943ee2b1SBill Fenner if (!(dp = parsestatus(dp, &er))) 1482647f50c3SDoug Rabson return (0); 1483647f50c3SDoug Rabson if (vflag) 1484647f50c3SDoug Rabson printf(" POST:"); 1485943ee2b1SBill Fenner if (!(dp = parse_post_op_attr(dp, vflag))) 1486647f50c3SDoug Rabson return (0); 1487647f50c3SDoug Rabson if (er) 1488647f50c3SDoug Rabson return (1); 1489647f50c3SDoug Rabson 1490647f50c3SDoug Rabson spp = (struct nfsv3_pathconf *)dp; 1491685b49deSBill Fenner TCHECK(*spp); 1492647f50c3SDoug Rabson 1493943ee2b1SBill Fenner printf(" linkmax %u namemax %u %s %s %s %s", 1494cc391cceSBruce M Simpson EXTRACT_32BITS(&spp->pc_linkmax), 1495cc391cceSBruce M Simpson EXTRACT_32BITS(&spp->pc_namemax), 1496cc391cceSBruce M Simpson EXTRACT_32BITS(&spp->pc_notrunc) ? "notrunc" : "", 1497cc391cceSBruce M Simpson EXTRACT_32BITS(&spp->pc_chownrestricted) ? "chownres" : "", 1498cc391cceSBruce M Simpson EXTRACT_32BITS(&spp->pc_caseinsensitive) ? "igncase" : "", 1499cc391cceSBruce M Simpson EXTRACT_32BITS(&spp->pc_casepreserving) ? "keepcase" : ""); 1500943ee2b1SBill Fenner return (1); 15010e0def19SBill Fenner trunc: 15020e0def19SBill Fenner return (0); 15034edb46e9SPaul Traina } 15044edb46e9SPaul Traina 15054edb46e9SPaul Traina static void 1506c1ad1296SSam Leffler interp_reply(const struct sunrpc_msg *rp, u_int32_t proc, u_int32_t vers, int length) 15074edb46e9SPaul Traina { 15084edb46e9SPaul Traina register const u_int32_t *dp; 1509647f50c3SDoug Rabson register int v3; 1510647f50c3SDoug Rabson int er; 1511647f50c3SDoug Rabson 1512647f50c3SDoug Rabson v3 = (vers == NFS_VER3); 1513647f50c3SDoug Rabson 1514647f50c3SDoug Rabson if (!v3 && proc < NFS_NPROCS) 1515647f50c3SDoug Rabson proc = nfsv3_procid[proc]; 15164edb46e9SPaul Traina 15174edb46e9SPaul Traina switch (proc) { 15184edb46e9SPaul Traina 15194edb46e9SPaul Traina case NFSPROC_NOOP: 15204edb46e9SPaul Traina printf(" nop"); 15214edb46e9SPaul Traina return; 1522647f50c3SDoug Rabson 15234edb46e9SPaul Traina case NFSPROC_NULL: 15244edb46e9SPaul Traina printf(" null"); 15254edb46e9SPaul Traina return; 15264edb46e9SPaul Traina 15274edb46e9SPaul Traina case NFSPROC_GETATTR: 15284edb46e9SPaul Traina printf(" getattr"); 15294edb46e9SPaul Traina dp = parserep(rp, length); 15302ebf6c05SBill Fenner if (dp != NULL && parseattrstat(dp, !qflag, v3) != 0) 15314edb46e9SPaul Traina return; 15324edb46e9SPaul Traina break; 15334edb46e9SPaul Traina 15344edb46e9SPaul Traina case NFSPROC_SETATTR: 15354edb46e9SPaul Traina printf(" setattr"); 1536943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 15374edb46e9SPaul Traina return; 1538647f50c3SDoug Rabson if (v3) { 1539943ee2b1SBill Fenner if (parsewccres(dp, vflag)) 1540647f50c3SDoug Rabson return; 1541647f50c3SDoug Rabson } else { 1542647f50c3SDoug Rabson if (parseattrstat(dp, !qflag, 0) != 0) 1543647f50c3SDoug Rabson return; 1544647f50c3SDoug Rabson } 15454edb46e9SPaul Traina break; 15464edb46e9SPaul Traina 15474edb46e9SPaul Traina case NFSPROC_LOOKUP: 15484edb46e9SPaul Traina printf(" lookup"); 1549943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 15504edb46e9SPaul Traina break; 1551647f50c3SDoug Rabson if (v3) { 1552943ee2b1SBill Fenner if (!(dp = parsestatus(dp, &er))) 1553647f50c3SDoug Rabson break; 1554647f50c3SDoug Rabson if (er) { 1555647f50c3SDoug Rabson if (vflag > 1) { 1556647f50c3SDoug Rabson printf(" post dattr:"); 1557647f50c3SDoug Rabson dp = parse_post_op_attr(dp, vflag); 1558647f50c3SDoug Rabson } 1559647f50c3SDoug Rabson } else { 1560943ee2b1SBill Fenner if (!(dp = parsefh(dp, v3))) 1561647f50c3SDoug Rabson break; 1562943ee2b1SBill Fenner if ((dp = parse_post_op_attr(dp, vflag)) && 1563943ee2b1SBill Fenner vflag > 1) { 1564647f50c3SDoug Rabson printf(" post dattr:"); 1565647f50c3SDoug Rabson dp = parse_post_op_attr(dp, vflag); 1566647f50c3SDoug Rabson } 1567647f50c3SDoug Rabson } 1568943ee2b1SBill Fenner if (dp) 1569647f50c3SDoug Rabson return; 1570647f50c3SDoug Rabson } else { 1571647f50c3SDoug Rabson if (parsediropres(dp) != 0) 1572647f50c3SDoug Rabson return; 1573647f50c3SDoug Rabson } 1574647f50c3SDoug Rabson break; 1575647f50c3SDoug Rabson 1576647f50c3SDoug Rabson case NFSPROC_ACCESS: 1577647f50c3SDoug Rabson printf(" access"); 1578a1c2090eSBill Fenner if (!(dp = parserep(rp, length))) 1579a1c2090eSBill Fenner break; 1580943ee2b1SBill Fenner if (!(dp = parsestatus(dp, &er))) 1581647f50c3SDoug Rabson break; 1582647f50c3SDoug Rabson if (vflag) 1583647f50c3SDoug Rabson printf(" attr:"); 1584943ee2b1SBill Fenner if (!(dp = parse_post_op_attr(dp, vflag))) 1585647f50c3SDoug Rabson break; 1586647f50c3SDoug Rabson if (!er) 1587cc391cceSBruce M Simpson printf(" c %04x", EXTRACT_32BITS(&dp[0])); 1588647f50c3SDoug Rabson return; 15894edb46e9SPaul Traina 15904edb46e9SPaul Traina case NFSPROC_READLINK: 15914edb46e9SPaul Traina printf(" readlink"); 15924edb46e9SPaul Traina dp = parserep(rp, length); 15932ebf6c05SBill Fenner if (dp != NULL && parselinkres(dp, v3) != 0) 15944edb46e9SPaul Traina return; 15954edb46e9SPaul Traina break; 15964edb46e9SPaul Traina 15974edb46e9SPaul Traina case NFSPROC_READ: 15984edb46e9SPaul Traina printf(" read"); 1599943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 1600647f50c3SDoug Rabson break; 1601647f50c3SDoug Rabson if (v3) { 1602943ee2b1SBill Fenner if (!(dp = parsestatus(dp, &er))) 1603647f50c3SDoug Rabson break; 1604943ee2b1SBill Fenner if (!(dp = parse_post_op_attr(dp, vflag))) 1605647f50c3SDoug Rabson break; 1606647f50c3SDoug Rabson if (er) 16074edb46e9SPaul Traina return; 1608647f50c3SDoug Rabson if (vflag) { 1609943ee2b1SBill Fenner TCHECK(dp[1]); 1610cc391cceSBruce M Simpson printf(" %u bytes", EXTRACT_32BITS(&dp[0])); 1611cc391cceSBruce M Simpson if (EXTRACT_32BITS(&dp[1])) 1612647f50c3SDoug Rabson printf(" EOF"); 1613647f50c3SDoug Rabson } 1614647f50c3SDoug Rabson return; 1615647f50c3SDoug Rabson } else { 1616647f50c3SDoug Rabson if (parseattrstat(dp, vflag, 0) != 0) 1617647f50c3SDoug Rabson return; 1618647f50c3SDoug Rabson } 16194edb46e9SPaul Traina break; 16204edb46e9SPaul Traina 16214edb46e9SPaul Traina case NFSPROC_WRITE: 16224edb46e9SPaul Traina printf(" write"); 1623943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 1624647f50c3SDoug Rabson break; 1625647f50c3SDoug Rabson if (v3) { 1626943ee2b1SBill Fenner if (!(dp = parsestatus(dp, &er))) 1627647f50c3SDoug Rabson break; 1628943ee2b1SBill Fenner if (!(dp = parse_wcc_data(dp, vflag))) 1629647f50c3SDoug Rabson break; 1630647f50c3SDoug Rabson if (er) 16314edb46e9SPaul Traina return; 1632647f50c3SDoug Rabson if (vflag) { 1633943ee2b1SBill Fenner TCHECK(dp[0]); 1634cc391cceSBruce M Simpson printf(" %u bytes", EXTRACT_32BITS(&dp[0])); 1635647f50c3SDoug Rabson if (vflag > 1) { 1636943ee2b1SBill Fenner TCHECK(dp[1]); 1637647f50c3SDoug Rabson printf(" <%s>", 1638943ee2b1SBill Fenner tok2str(nfsv3_writemodes, 1639cc391cceSBruce M Simpson NULL, EXTRACT_32BITS(&dp[1]))); 1640647f50c3SDoug Rabson } 1641647f50c3SDoug Rabson return; 1642647f50c3SDoug Rabson } 1643647f50c3SDoug Rabson } else { 1644647f50c3SDoug Rabson if (parseattrstat(dp, vflag, v3) != 0) 1645647f50c3SDoug Rabson return; 1646647f50c3SDoug Rabson } 16474edb46e9SPaul Traina break; 16484edb46e9SPaul Traina 16494edb46e9SPaul Traina case NFSPROC_CREATE: 16504edb46e9SPaul Traina printf(" create"); 1651943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 1652647f50c3SDoug Rabson break; 1653647f50c3SDoug Rabson if (v3) { 1654943ee2b1SBill Fenner if (parsecreateopres(dp, vflag) != 0) 1655647f50c3SDoug Rabson return; 1656647f50c3SDoug Rabson } else { 1657647f50c3SDoug Rabson if (parsediropres(dp) != 0) 1658647f50c3SDoug Rabson return; 1659647f50c3SDoug Rabson } 1660647f50c3SDoug Rabson break; 1661647f50c3SDoug Rabson 1662647f50c3SDoug Rabson case NFSPROC_MKDIR: 1663647f50c3SDoug Rabson printf(" mkdir"); 1664943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 1665647f50c3SDoug Rabson break; 1666647f50c3SDoug Rabson if (v3) { 1667943ee2b1SBill Fenner if (parsecreateopres(dp, vflag) != 0) 1668647f50c3SDoug Rabson return; 1669647f50c3SDoug Rabson } else { 1670647f50c3SDoug Rabson if (parsediropres(dp) != 0) 1671647f50c3SDoug Rabson return; 1672647f50c3SDoug Rabson } 1673647f50c3SDoug Rabson break; 1674647f50c3SDoug Rabson 1675647f50c3SDoug Rabson case NFSPROC_SYMLINK: 1676647f50c3SDoug Rabson printf(" symlink"); 1677943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 1678647f50c3SDoug Rabson break; 1679647f50c3SDoug Rabson if (v3) { 1680943ee2b1SBill Fenner if (parsecreateopres(dp, vflag) != 0) 1681647f50c3SDoug Rabson return; 1682647f50c3SDoug Rabson } else { 1683943ee2b1SBill Fenner if (parsestatus(dp, &er) != 0) 1684647f50c3SDoug Rabson return; 1685647f50c3SDoug Rabson } 1686647f50c3SDoug Rabson break; 1687647f50c3SDoug Rabson 1688647f50c3SDoug Rabson case NFSPROC_MKNOD: 1689647f50c3SDoug Rabson printf(" mknod"); 1690943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 1691647f50c3SDoug Rabson break; 1692943ee2b1SBill Fenner if (parsecreateopres(dp, vflag) != 0) 16934edb46e9SPaul Traina return; 16944edb46e9SPaul Traina break; 16954edb46e9SPaul Traina 16964edb46e9SPaul Traina case NFSPROC_REMOVE: 16974edb46e9SPaul Traina printf(" remove"); 1698943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 16994edb46e9SPaul Traina break; 1700647f50c3SDoug Rabson if (v3) { 1701943ee2b1SBill Fenner if (parsewccres(dp, vflag)) 17024edb46e9SPaul Traina return; 1703647f50c3SDoug Rabson } else { 1704943ee2b1SBill Fenner if (parsestatus(dp, &er) != 0) 17054edb46e9SPaul Traina return; 1706647f50c3SDoug Rabson } 17074edb46e9SPaul Traina break; 17084edb46e9SPaul Traina 17094edb46e9SPaul Traina case NFSPROC_RMDIR: 17104edb46e9SPaul Traina printf(" rmdir"); 1711943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 1712647f50c3SDoug Rabson break; 1713647f50c3SDoug Rabson if (v3) { 1714943ee2b1SBill Fenner if (parsewccres(dp, vflag)) 17154edb46e9SPaul Traina return; 1716647f50c3SDoug Rabson } else { 1717943ee2b1SBill Fenner if (parsestatus(dp, &er) != 0) 1718647f50c3SDoug Rabson return; 1719647f50c3SDoug Rabson } 1720647f50c3SDoug Rabson break; 1721647f50c3SDoug Rabson 1722647f50c3SDoug Rabson case NFSPROC_RENAME: 1723647f50c3SDoug Rabson printf(" rename"); 1724943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 1725647f50c3SDoug Rabson break; 1726647f50c3SDoug Rabson if (v3) { 1727943ee2b1SBill Fenner if (!(dp = parsestatus(dp, &er))) 1728647f50c3SDoug Rabson break; 1729647f50c3SDoug Rabson if (vflag) { 1730647f50c3SDoug Rabson printf(" from:"); 1731943ee2b1SBill Fenner if (!(dp = parse_wcc_data(dp, vflag))) 1732647f50c3SDoug Rabson break; 1733647f50c3SDoug Rabson printf(" to:"); 1734943ee2b1SBill Fenner if (!(dp = parse_wcc_data(dp, vflag))) 1735647f50c3SDoug Rabson break; 1736647f50c3SDoug Rabson } 1737647f50c3SDoug Rabson return; 1738647f50c3SDoug Rabson } else { 1739943ee2b1SBill Fenner if (parsestatus(dp, &er) != 0) 1740647f50c3SDoug Rabson return; 1741647f50c3SDoug Rabson } 1742647f50c3SDoug Rabson break; 1743647f50c3SDoug Rabson 1744647f50c3SDoug Rabson case NFSPROC_LINK: 1745647f50c3SDoug Rabson printf(" link"); 1746943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 1747647f50c3SDoug Rabson break; 1748647f50c3SDoug Rabson if (v3) { 1749943ee2b1SBill Fenner if (!(dp = parsestatus(dp, &er))) 1750647f50c3SDoug Rabson break; 1751647f50c3SDoug Rabson if (vflag) { 1752647f50c3SDoug Rabson printf(" file POST:"); 1753943ee2b1SBill Fenner if (!(dp = parse_post_op_attr(dp, vflag))) 1754647f50c3SDoug Rabson break; 1755647f50c3SDoug Rabson printf(" dir:"); 1756943ee2b1SBill Fenner if (!(dp = parse_wcc_data(dp, vflag))) 1757647f50c3SDoug Rabson break; 1758647f50c3SDoug Rabson return; 1759647f50c3SDoug Rabson } 1760647f50c3SDoug Rabson } else { 1761943ee2b1SBill Fenner if (parsestatus(dp, &er) != 0) 1762647f50c3SDoug Rabson return; 1763647f50c3SDoug Rabson } 17644edb46e9SPaul Traina break; 17654edb46e9SPaul Traina 17664edb46e9SPaul Traina case NFSPROC_READDIR: 17674edb46e9SPaul Traina printf(" readdir"); 1768943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 1769647f50c3SDoug Rabson break; 1770647f50c3SDoug Rabson if (v3) { 1771943ee2b1SBill Fenner if (parsev3rddirres(dp, vflag)) 1772647f50c3SDoug Rabson return; 1773647f50c3SDoug Rabson } else { 1774647f50c3SDoug Rabson if (parserddires(dp) != 0) 1775647f50c3SDoug Rabson return; 1776647f50c3SDoug Rabson } 1777647f50c3SDoug Rabson break; 1778647f50c3SDoug Rabson 1779647f50c3SDoug Rabson case NFSPROC_READDIRPLUS: 1780647f50c3SDoug Rabson printf(" readdirplus"); 1781943ee2b1SBill Fenner if (!(dp = parserep(rp, length))) 1782647f50c3SDoug Rabson break; 1783943ee2b1SBill Fenner if (parsev3rddirres(dp, vflag)) 17844edb46e9SPaul Traina return; 17854edb46e9SPaul Traina break; 17864edb46e9SPaul Traina 1787647f50c3SDoug Rabson case NFSPROC_FSSTAT: 1788647f50c3SDoug Rabson printf(" fsstat"); 17894edb46e9SPaul Traina dp = parserep(rp, length); 1790943ee2b1SBill Fenner if (dp != NULL && parsestatfs(dp, v3) != 0) 1791647f50c3SDoug Rabson return; 1792647f50c3SDoug Rabson break; 1793647f50c3SDoug Rabson 1794647f50c3SDoug Rabson case NFSPROC_FSINFO: 1795647f50c3SDoug Rabson printf(" fsinfo"); 1796647f50c3SDoug Rabson dp = parserep(rp, length); 1797943ee2b1SBill Fenner if (dp != NULL && parsefsinfo(dp) != 0) 1798647f50c3SDoug Rabson return; 1799647f50c3SDoug Rabson break; 1800647f50c3SDoug Rabson 1801647f50c3SDoug Rabson case NFSPROC_PATHCONF: 1802647f50c3SDoug Rabson printf(" pathconf"); 1803647f50c3SDoug Rabson dp = parserep(rp, length); 18042ebf6c05SBill Fenner if (dp != NULL && parsepathconf(dp) != 0) 1805647f50c3SDoug Rabson return; 1806647f50c3SDoug Rabson break; 1807647f50c3SDoug Rabson 1808647f50c3SDoug Rabson case NFSPROC_COMMIT: 1809647f50c3SDoug Rabson printf(" commit"); 1810647f50c3SDoug Rabson dp = parserep(rp, length); 18112ebf6c05SBill Fenner if (dp != NULL && parsewccres(dp, vflag) != 0) 18124edb46e9SPaul Traina return; 18134edb46e9SPaul Traina break; 18144edb46e9SPaul Traina 18154edb46e9SPaul Traina default: 18162ebf6c05SBill Fenner printf(" proc-%u", proc); 18174edb46e9SPaul Traina return; 18184edb46e9SPaul Traina } 1819647f50c3SDoug Rabson trunc: 18202ebf6c05SBill Fenner if (!nfserr) 18214edb46e9SPaul Traina fputs(" [|nfs]", stdout); 18224edb46e9SPaul Traina } 1823