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. 204edb46e9SPaul Traina */ 214edb46e9SPaul Traina 223340d773SGleb Smirnoff /* \summary: Network File System (NFS) printer */ 233340d773SGleb Smirnoff 24943ee2b1SBill Fenner #ifdef HAVE_CONFIG_H 25*ee67461eSJoseph Mingrone #include <config.h> 264edb46e9SPaul Traina #endif 274edb46e9SPaul Traina 28*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h" 294edb46e9SPaul Traina 304edb46e9SPaul Traina #include <stdio.h> 314edb46e9SPaul Traina #include <string.h> 32*ee67461eSJoseph Mingrone #include <limits.h> 334edb46e9SPaul Traina 343340d773SGleb Smirnoff #include "netdissect.h" 354edb46e9SPaul Traina #include "addrtoname.h" 36cc391cceSBruce M Simpson #include "extract.h" 374edb46e9SPaul Traina 38647f50c3SDoug Rabson #include "nfs.h" 394edb46e9SPaul Traina #include "nfsfh.h" 404edb46e9SPaul Traina 41943ee2b1SBill Fenner #include "ip.h" 42943ee2b1SBill Fenner #include "ip6.h" 43c1ad1296SSam Leffler #include "rpc_auth.h" 44c1ad1296SSam Leffler #include "rpc_msg.h" 45943ee2b1SBill Fenner 463c602fabSXin LI 473c602fabSXin LI static void nfs_printfh(netdissect_options *, const uint32_t *, const u_int); 483c602fabSXin LI static int xid_map_enter(netdissect_options *, const struct sunrpc_msg *, const u_char *); 49*ee67461eSJoseph Mingrone static int xid_map_find(netdissect_options *, const struct sunrpc_msg *, const u_char *, uint32_t *, uint32_t *); 503c602fabSXin LI static void interp_reply(netdissect_options *, const struct sunrpc_msg *, uint32_t, uint32_t, int); 513c602fabSXin LI static const uint32_t *parse_post_op_attr(netdissect_options *, const uint32_t *, int); 522ebf6c05SBill Fenner 53647f50c3SDoug Rabson /* 54647f50c3SDoug Rabson * Mapping of old NFS Version 2 RPC numbers to generic numbers. 55647f50c3SDoug Rabson */ 563340d773SGleb Smirnoff static uint32_t nfsv3_procid[NFS_NPROCS] = { 57647f50c3SDoug Rabson NFSPROC_NULL, 58647f50c3SDoug Rabson NFSPROC_GETATTR, 59647f50c3SDoug Rabson NFSPROC_SETATTR, 60647f50c3SDoug Rabson NFSPROC_NOOP, 61647f50c3SDoug Rabson NFSPROC_LOOKUP, 62647f50c3SDoug Rabson NFSPROC_READLINK, 63647f50c3SDoug Rabson NFSPROC_READ, 64647f50c3SDoug Rabson NFSPROC_NOOP, 65647f50c3SDoug Rabson NFSPROC_WRITE, 66647f50c3SDoug Rabson NFSPROC_CREATE, 67647f50c3SDoug Rabson NFSPROC_REMOVE, 68647f50c3SDoug Rabson NFSPROC_RENAME, 69647f50c3SDoug Rabson NFSPROC_LINK, 70647f50c3SDoug Rabson NFSPROC_SYMLINK, 71647f50c3SDoug Rabson NFSPROC_MKDIR, 72647f50c3SDoug Rabson NFSPROC_RMDIR, 73647f50c3SDoug Rabson NFSPROC_READDIR, 74647f50c3SDoug Rabson NFSPROC_FSSTAT, 75647f50c3SDoug Rabson NFSPROC_NOOP, 76647f50c3SDoug Rabson NFSPROC_NOOP, 77647f50c3SDoug Rabson NFSPROC_NOOP, 78647f50c3SDoug Rabson NFSPROC_NOOP, 79647f50c3SDoug Rabson NFSPROC_NOOP, 80647f50c3SDoug Rabson NFSPROC_NOOP, 81647f50c3SDoug Rabson NFSPROC_NOOP, 82647f50c3SDoug Rabson NFSPROC_NOOP 83647f50c3SDoug Rabson }; 84647f50c3SDoug Rabson 853c602fabSXin LI static const struct tok nfsproc_str[] = { 863c602fabSXin LI { NFSPROC_NOOP, "nop" }, 873c602fabSXin LI { NFSPROC_NULL, "null" }, 883c602fabSXin LI { NFSPROC_GETATTR, "getattr" }, 893c602fabSXin LI { NFSPROC_SETATTR, "setattr" }, 903c602fabSXin LI { NFSPROC_LOOKUP, "lookup" }, 913c602fabSXin LI { NFSPROC_ACCESS, "access" }, 923c602fabSXin LI { NFSPROC_READLINK, "readlink" }, 933c602fabSXin LI { NFSPROC_READ, "read" }, 943c602fabSXin LI { NFSPROC_WRITE, "write" }, 953c602fabSXin LI { NFSPROC_CREATE, "create" }, 963c602fabSXin LI { NFSPROC_MKDIR, "mkdir" }, 973c602fabSXin LI { NFSPROC_SYMLINK, "symlink" }, 983c602fabSXin LI { NFSPROC_MKNOD, "mknod" }, 993c602fabSXin LI { NFSPROC_REMOVE, "remove" }, 1003c602fabSXin LI { NFSPROC_RMDIR, "rmdir" }, 1013c602fabSXin LI { NFSPROC_RENAME, "rename" }, 1023c602fabSXin LI { NFSPROC_LINK, "link" }, 1033c602fabSXin LI { NFSPROC_READDIR, "readdir" }, 1043c602fabSXin LI { NFSPROC_READDIRPLUS, "readdirplus" }, 1053c602fabSXin LI { NFSPROC_FSSTAT, "fsstat" }, 1063c602fabSXin LI { NFSPROC_FSINFO, "fsinfo" }, 1073c602fabSXin LI { NFSPROC_PATHCONF, "pathconf" }, 1083c602fabSXin LI { NFSPROC_COMMIT, "commit" }, 1093c602fabSXin LI { 0, NULL } 1103c602fabSXin LI }; 1113c602fabSXin LI 112943ee2b1SBill Fenner /* 113943ee2b1SBill Fenner * NFS V2 and V3 status values. 114943ee2b1SBill Fenner * 115943ee2b1SBill Fenner * Some of these come from the RFCs for NFS V2 and V3, with the message 116943ee2b1SBill Fenner * strings taken from the FreeBSD C library "errlst.c". 117943ee2b1SBill Fenner * 118943ee2b1SBill Fenner * Others are errors that are not in the RFC but that I suspect some 119943ee2b1SBill Fenner * NFS servers could return; the values are FreeBSD errno values, as 120943ee2b1SBill Fenner * the first NFS server was the SunOS 2.0 one, and until 5.0 SunOS 121943ee2b1SBill Fenner * was primarily BSD-derived. 122943ee2b1SBill Fenner */ 1233c602fabSXin LI static const struct tok status2str[] = { 124943ee2b1SBill Fenner { 1, "Operation not permitted" }, /* EPERM */ 125943ee2b1SBill Fenner { 2, "No such file or directory" }, /* ENOENT */ 126943ee2b1SBill Fenner { 5, "Input/output error" }, /* EIO */ 127943ee2b1SBill Fenner { 6, "Device not configured" }, /* ENXIO */ 128943ee2b1SBill Fenner { 11, "Resource deadlock avoided" }, /* EDEADLK */ 129943ee2b1SBill Fenner { 12, "Cannot allocate memory" }, /* ENOMEM */ 130943ee2b1SBill Fenner { 13, "Permission denied" }, /* EACCES */ 131943ee2b1SBill Fenner { 17, "File exists" }, /* EEXIST */ 132943ee2b1SBill Fenner { 18, "Cross-device link" }, /* EXDEV */ 133943ee2b1SBill Fenner { 19, "Operation not supported by device" }, /* ENODEV */ 134943ee2b1SBill Fenner { 20, "Not a directory" }, /* ENOTDIR */ 135943ee2b1SBill Fenner { 21, "Is a directory" }, /* EISDIR */ 136943ee2b1SBill Fenner { 22, "Invalid argument" }, /* EINVAL */ 137943ee2b1SBill Fenner { 26, "Text file busy" }, /* ETXTBSY */ 138943ee2b1SBill Fenner { 27, "File too large" }, /* EFBIG */ 139943ee2b1SBill Fenner { 28, "No space left on device" }, /* ENOSPC */ 140943ee2b1SBill Fenner { 30, "Read-only file system" }, /* EROFS */ 141943ee2b1SBill Fenner { 31, "Too many links" }, /* EMLINK */ 142943ee2b1SBill Fenner { 45, "Operation not supported" }, /* EOPNOTSUPP */ 143943ee2b1SBill Fenner { 62, "Too many levels of symbolic links" }, /* ELOOP */ 144943ee2b1SBill Fenner { 63, "File name too long" }, /* ENAMETOOLONG */ 145943ee2b1SBill Fenner { 66, "Directory not empty" }, /* ENOTEMPTY */ 146943ee2b1SBill Fenner { 69, "Disc quota exceeded" }, /* EDQUOT */ 147943ee2b1SBill Fenner { 70, "Stale NFS file handle" }, /* ESTALE */ 148943ee2b1SBill Fenner { 71, "Too many levels of remote in path" }, /* EREMOTE */ 149943ee2b1SBill Fenner { 99, "Write cache flushed to disk" }, /* NFSERR_WFLUSH (not used) */ 150943ee2b1SBill Fenner { 10001, "Illegal NFS file handle" }, /* NFS3ERR_BADHANDLE */ 151943ee2b1SBill Fenner { 10002, "Update synchronization mismatch" }, /* NFS3ERR_NOT_SYNC */ 152943ee2b1SBill Fenner { 10003, "READDIR/READDIRPLUS cookie is stale" }, /* NFS3ERR_BAD_COOKIE */ 153943ee2b1SBill Fenner { 10004, "Operation not supported" }, /* NFS3ERR_NOTSUPP */ 154943ee2b1SBill Fenner { 10005, "Buffer or request is too small" }, /* NFS3ERR_TOOSMALL */ 155943ee2b1SBill Fenner { 10006, "Unspecified error on server" }, /* NFS3ERR_SERVERFAULT */ 156943ee2b1SBill Fenner { 10007, "Object of that type not supported" }, /* NFS3ERR_BADTYPE */ 157943ee2b1SBill Fenner { 10008, "Request couldn't be completed in time" }, /* NFS3ERR_JUKEBOX */ 158943ee2b1SBill Fenner { 0, NULL } 159943ee2b1SBill Fenner }; 160943ee2b1SBill Fenner 1613c602fabSXin LI static const struct tok nfsv3_writemodes[] = { 162943ee2b1SBill Fenner { 0, "unstable" }, 163943ee2b1SBill Fenner { 1, "datasync" }, 164943ee2b1SBill Fenner { 2, "filesync" }, 165943ee2b1SBill Fenner { 0, NULL } 166647f50c3SDoug Rabson }; 167647f50c3SDoug Rabson 1683c602fabSXin LI static const struct tok type2str[] = { 169647f50c3SDoug Rabson { NFNON, "NON" }, 170647f50c3SDoug Rabson { NFREG, "REG" }, 171647f50c3SDoug Rabson { NFDIR, "DIR" }, 172647f50c3SDoug Rabson { NFBLK, "BLK" }, 173647f50c3SDoug Rabson { NFCHR, "CHR" }, 174647f50c3SDoug Rabson { NFLNK, "LNK" }, 175647f50c3SDoug Rabson { NFFIFO, "FIFO" }, 176647f50c3SDoug Rabson { 0, NULL } 177647f50c3SDoug Rabson }; 178647f50c3SDoug Rabson 1793c602fabSXin LI static const struct tok sunrpc_auth_str[] = { 1803c602fabSXin LI { SUNRPC_AUTH_OK, "OK" }, 1813c602fabSXin LI { SUNRPC_AUTH_BADCRED, "Bogus Credentials (seal broken)" }, 1823c602fabSXin LI { SUNRPC_AUTH_REJECTEDCRED, "Rejected Credentials (client should begin new session)" }, 1833c602fabSXin LI { SUNRPC_AUTH_BADVERF, "Bogus Verifier (seal broken)" }, 1843c602fabSXin LI { SUNRPC_AUTH_REJECTEDVERF, "Verifier expired or was replayed" }, 1853c602fabSXin LI { SUNRPC_AUTH_TOOWEAK, "Credentials are too weak" }, 1863c602fabSXin LI { SUNRPC_AUTH_INVALIDRESP, "Bogus response verifier" }, 1873c602fabSXin LI { SUNRPC_AUTH_FAILED, "Unknown failure" }, 1883c602fabSXin LI { 0, NULL } 1893c602fabSXin LI }; 1903c602fabSXin LI 1913c602fabSXin LI static const struct tok sunrpc_str[] = { 1923c602fabSXin LI { SUNRPC_PROG_UNAVAIL, "PROG_UNAVAIL" }, 1933c602fabSXin LI { SUNRPC_PROG_MISMATCH, "PROG_MISMATCH" }, 1943c602fabSXin LI { SUNRPC_PROC_UNAVAIL, "PROC_UNAVAIL" }, 1953c602fabSXin LI { SUNRPC_GARBAGE_ARGS, "GARBAGE_ARGS" }, 1963c602fabSXin LI { SUNRPC_SYSTEM_ERR, "SYSTEM_ERR" }, 1973c602fabSXin LI { 0, NULL } 1983c602fabSXin LI }; 1993c602fabSXin LI 200943ee2b1SBill Fenner static void 2013c602fabSXin LI print_nfsaddr(netdissect_options *ndo, 2023c602fabSXin LI const u_char *bp, const char *s, const char *d) 203943ee2b1SBill Fenner { 2043340d773SGleb Smirnoff const struct ip *ip; 2053340d773SGleb Smirnoff const struct ip6_hdr *ip6; 206943ee2b1SBill Fenner char srcaddr[INET6_ADDRSTRLEN], dstaddr[INET6_ADDRSTRLEN]; 207943ee2b1SBill Fenner 208943ee2b1SBill Fenner srcaddr[0] = dstaddr[0] = '\0'; 2093340d773SGleb Smirnoff switch (IP_V((const struct ip *)bp)) { 210943ee2b1SBill Fenner case 4: 2113340d773SGleb Smirnoff ip = (const struct ip *)bp; 212*ee67461eSJoseph Mingrone strlcpy(srcaddr, GET_IPADDR_STRING(ip->ip_src), sizeof(srcaddr)); 213*ee67461eSJoseph Mingrone strlcpy(dstaddr, GET_IPADDR_STRING(ip->ip_dst), sizeof(dstaddr)); 214943ee2b1SBill Fenner break; 215943ee2b1SBill Fenner case 6: 2163340d773SGleb Smirnoff ip6 = (const struct ip6_hdr *)bp; 217*ee67461eSJoseph Mingrone strlcpy(srcaddr, GET_IP6ADDR_STRING(ip6->ip6_src), 218943ee2b1SBill Fenner sizeof(srcaddr)); 219*ee67461eSJoseph Mingrone strlcpy(dstaddr, GET_IP6ADDR_STRING(ip6->ip6_dst), 220943ee2b1SBill Fenner sizeof(dstaddr)); 221943ee2b1SBill Fenner break; 222943ee2b1SBill Fenner default: 223943ee2b1SBill Fenner strlcpy(srcaddr, "?", sizeof(srcaddr)); 224943ee2b1SBill Fenner strlcpy(dstaddr, "?", sizeof(dstaddr)); 225943ee2b1SBill Fenner break; 226943ee2b1SBill Fenner } 227943ee2b1SBill Fenner 228*ee67461eSJoseph Mingrone ND_PRINT("%s.%s > %s.%s: ", srcaddr, s, dstaddr, d); 229943ee2b1SBill Fenner } 230943ee2b1SBill Fenner 231*ee67461eSJoseph Mingrone /* 232*ee67461eSJoseph Mingrone * NFS Version 3 sattr3 structure for the new node creation case. 233*ee67461eSJoseph Mingrone * This does not have a fixed layout on the network, so this 234*ee67461eSJoseph Mingrone * structure does not correspond to the layout of the data on 235*ee67461eSJoseph Mingrone * the network; it's used to store the data when the sattr3 236*ee67461eSJoseph Mingrone * is parsed for use when it's later printed. 237*ee67461eSJoseph Mingrone */ 238*ee67461eSJoseph Mingrone struct nfsv3_sattr { 239*ee67461eSJoseph Mingrone uint32_t sa_modeset; 240*ee67461eSJoseph Mingrone uint32_t sa_mode; 241*ee67461eSJoseph Mingrone uint32_t sa_uidset; 242*ee67461eSJoseph Mingrone uint32_t sa_uid; 243*ee67461eSJoseph Mingrone uint32_t sa_gidset; 244*ee67461eSJoseph Mingrone uint32_t sa_gid; 245*ee67461eSJoseph Mingrone uint32_t sa_sizeset; 246*ee67461eSJoseph Mingrone uint32_t sa_size; 247*ee67461eSJoseph Mingrone uint32_t sa_atimetype; 248*ee67461eSJoseph Mingrone struct { 249*ee67461eSJoseph Mingrone uint32_t nfsv3_sec; 250*ee67461eSJoseph Mingrone uint32_t nfsv3_nsec; 251*ee67461eSJoseph Mingrone } sa_atime; 252*ee67461eSJoseph Mingrone uint32_t sa_mtimetype; 253*ee67461eSJoseph Mingrone struct { 254*ee67461eSJoseph Mingrone uint32_t nfsv3_sec; 255*ee67461eSJoseph Mingrone uint32_t nfsv3_nsec; 256*ee67461eSJoseph Mingrone } sa_mtime; 257*ee67461eSJoseph Mingrone }; 258*ee67461eSJoseph Mingrone 2593c602fabSXin LI static const uint32_t * 2603c602fabSXin LI parse_sattr3(netdissect_options *ndo, 2613c602fabSXin LI const uint32_t *dp, struct nfsv3_sattr *sa3) 262647f50c3SDoug Rabson { 263*ee67461eSJoseph Mingrone sa3->sa_modeset = GET_BE_U_4(dp); 264cc391cceSBruce M Simpson dp++; 265cc391cceSBruce M Simpson if (sa3->sa_modeset) { 266*ee67461eSJoseph Mingrone sa3->sa_mode = GET_BE_U_4(dp); 267cc391cceSBruce M Simpson dp++; 268647f50c3SDoug Rabson } 269647f50c3SDoug Rabson 270*ee67461eSJoseph Mingrone sa3->sa_uidset = GET_BE_U_4(dp); 271cc391cceSBruce M Simpson dp++; 272cc391cceSBruce M Simpson if (sa3->sa_uidset) { 273*ee67461eSJoseph Mingrone sa3->sa_uid = GET_BE_U_4(dp); 274cc391cceSBruce M Simpson dp++; 275647f50c3SDoug Rabson } 276647f50c3SDoug Rabson 277*ee67461eSJoseph Mingrone sa3->sa_gidset = GET_BE_U_4(dp); 278cc391cceSBruce M Simpson dp++; 279cc391cceSBruce M Simpson if (sa3->sa_gidset) { 280*ee67461eSJoseph Mingrone sa3->sa_gid = GET_BE_U_4(dp); 281cc391cceSBruce M Simpson dp++; 282647f50c3SDoug Rabson } 283647f50c3SDoug Rabson 284*ee67461eSJoseph Mingrone sa3->sa_sizeset = GET_BE_U_4(dp); 285cc391cceSBruce M Simpson dp++; 286cc391cceSBruce M Simpson if (sa3->sa_sizeset) { 287*ee67461eSJoseph Mingrone sa3->sa_size = GET_BE_U_4(dp); 288cc391cceSBruce M Simpson dp++; 289647f50c3SDoug Rabson } 290647f50c3SDoug Rabson 291*ee67461eSJoseph Mingrone sa3->sa_atimetype = GET_BE_U_4(dp); 292cc391cceSBruce M Simpson dp++; 293cc391cceSBruce M Simpson if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) { 294*ee67461eSJoseph Mingrone sa3->sa_atime.nfsv3_sec = GET_BE_U_4(dp); 295cc391cceSBruce M Simpson dp++; 296*ee67461eSJoseph Mingrone sa3->sa_atime.nfsv3_nsec = GET_BE_U_4(dp); 297cc391cceSBruce M Simpson dp++; 298647f50c3SDoug Rabson } 299647f50c3SDoug Rabson 300*ee67461eSJoseph Mingrone sa3->sa_mtimetype = GET_BE_U_4(dp); 301cc391cceSBruce M Simpson dp++; 302cc391cceSBruce M Simpson if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) { 303*ee67461eSJoseph Mingrone sa3->sa_mtime.nfsv3_sec = GET_BE_U_4(dp); 304cc391cceSBruce M Simpson dp++; 305*ee67461eSJoseph Mingrone sa3->sa_mtime.nfsv3_nsec = GET_BE_U_4(dp); 306cc391cceSBruce M Simpson dp++; 307647f50c3SDoug Rabson } 308647f50c3SDoug Rabson 309647f50c3SDoug Rabson return dp; 310647f50c3SDoug Rabson } 311647f50c3SDoug Rabson 312943ee2b1SBill Fenner static void 3133c602fabSXin LI print_sattr3(netdissect_options *ndo, 3143c602fabSXin LI const struct nfsv3_sattr *sa3, int verbose) 315647f50c3SDoug Rabson { 316647f50c3SDoug Rabson if (sa3->sa_modeset) 317*ee67461eSJoseph Mingrone ND_PRINT(" mode %o", sa3->sa_mode); 318647f50c3SDoug Rabson if (sa3->sa_uidset) 319*ee67461eSJoseph Mingrone ND_PRINT(" uid %u", sa3->sa_uid); 320647f50c3SDoug Rabson if (sa3->sa_gidset) 321*ee67461eSJoseph Mingrone ND_PRINT(" gid %u", sa3->sa_gid); 322647f50c3SDoug Rabson if (verbose > 1) { 323647f50c3SDoug Rabson if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) 324*ee67461eSJoseph Mingrone ND_PRINT(" atime %u.%06u", sa3->sa_atime.nfsv3_sec, 325*ee67461eSJoseph Mingrone sa3->sa_atime.nfsv3_nsec); 326647f50c3SDoug Rabson if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) 327*ee67461eSJoseph Mingrone ND_PRINT(" mtime %u.%06u", sa3->sa_mtime.nfsv3_sec, 328*ee67461eSJoseph Mingrone sa3->sa_mtime.nfsv3_nsec); 329647f50c3SDoug Rabson } 330647f50c3SDoug Rabson } 3314edb46e9SPaul Traina 3324edb46e9SPaul Traina void 3333c602fabSXin LI nfsreply_print(netdissect_options *ndo, 334*ee67461eSJoseph Mingrone const u_char *bp, u_int length, 335*ee67461eSJoseph Mingrone const u_char *bp2) 3364edb46e9SPaul Traina { 337*ee67461eSJoseph Mingrone const struct sunrpc_msg *rp; 338943ee2b1SBill Fenner char srcid[20], dstid[20]; /*fits 32bit*/ 3394edb46e9SPaul Traina 340*ee67461eSJoseph Mingrone ndo->ndo_protocol = "nfs"; 341c1ad1296SSam Leffler rp = (const struct sunrpc_msg *)bp; 3424edb46e9SPaul Traina 3433c602fabSXin LI if (!ndo->ndo_nflag) { 344943ee2b1SBill Fenner strlcpy(srcid, "nfs", sizeof(srcid)); 345943ee2b1SBill Fenner snprintf(dstid, sizeof(dstid), "%u", 346*ee67461eSJoseph Mingrone GET_BE_U_4(rp->rm_xid)); 347943ee2b1SBill Fenner } else { 348943ee2b1SBill Fenner snprintf(srcid, sizeof(srcid), "%u", NFS_PORT); 349943ee2b1SBill Fenner snprintf(dstid, sizeof(dstid), "%u", 350*ee67461eSJoseph Mingrone GET_BE_U_4(rp->rm_xid)); 351943ee2b1SBill Fenner } 3523c602fabSXin LI print_nfsaddr(ndo, bp2, srcid, dstid); 3533c602fabSXin LI 354*ee67461eSJoseph Mingrone nfsreply_noaddr_print(ndo, bp, length, bp2); 3553c602fabSXin LI } 3563c602fabSXin LI 3573c602fabSXin LI void 358*ee67461eSJoseph Mingrone nfsreply_noaddr_print(netdissect_options *ndo, 359*ee67461eSJoseph Mingrone const u_char *bp, u_int length, 360*ee67461eSJoseph Mingrone const u_char *bp2) 3613c602fabSXin LI { 362*ee67461eSJoseph Mingrone const struct sunrpc_msg *rp; 3633c602fabSXin LI uint32_t proc, vers, reply_stat; 3643c602fabSXin LI enum sunrpc_reject_stat rstat; 3653c602fabSXin LI uint32_t rlow; 3663c602fabSXin LI uint32_t rhigh; 3673c602fabSXin LI enum sunrpc_auth_stat rwhy; 3683c602fabSXin LI 369*ee67461eSJoseph Mingrone ndo->ndo_protocol = "nfs"; 3703c602fabSXin LI rp = (const struct sunrpc_msg *)bp; 3713c602fabSXin LI 372*ee67461eSJoseph Mingrone ND_TCHECK_4(rp->rm_reply.rp_stat); 373*ee67461eSJoseph Mingrone reply_stat = GET_BE_U_4(&rp->rm_reply.rp_stat); 374abf25193SMax Laier switch (reply_stat) { 3754edb46e9SPaul Traina 376abf25193SMax Laier case SUNRPC_MSG_ACCEPTED: 377*ee67461eSJoseph Mingrone ND_PRINT("reply ok %u", length); 378*ee67461eSJoseph Mingrone if (xid_map_find(ndo, rp, bp2, &proc, &vers) >= 0) 3793c602fabSXin LI interp_reply(ndo, rp, proc, vers, length); 380abf25193SMax Laier break; 381abf25193SMax Laier 382abf25193SMax Laier case SUNRPC_MSG_DENIED: 383*ee67461eSJoseph Mingrone ND_PRINT("reply ERR %u: ", length); 384*ee67461eSJoseph Mingrone ND_TCHECK_4(rp->rm_reply.rp_reject.rj_stat); 385*ee67461eSJoseph Mingrone rstat = GET_BE_U_4(&rp->rm_reply.rp_reject.rj_stat); 386abf25193SMax Laier switch (rstat) { 387abf25193SMax Laier 388abf25193SMax Laier case SUNRPC_RPC_MISMATCH: 389*ee67461eSJoseph Mingrone ND_TCHECK_4(rp->rm_reply.rp_reject.rj_vers.high); 390*ee67461eSJoseph Mingrone rlow = GET_BE_U_4(&rp->rm_reply.rp_reject.rj_vers.low); 391*ee67461eSJoseph Mingrone rhigh = GET_BE_U_4(&rp->rm_reply.rp_reject.rj_vers.high); 392*ee67461eSJoseph Mingrone ND_PRINT("RPC Version mismatch (%u-%u)", rlow, rhigh); 393abf25193SMax Laier break; 394abf25193SMax Laier 395abf25193SMax Laier case SUNRPC_AUTH_ERROR: 396*ee67461eSJoseph Mingrone ND_TCHECK_4(rp->rm_reply.rp_reject.rj_why); 397*ee67461eSJoseph Mingrone rwhy = GET_BE_U_4(&rp->rm_reply.rp_reject.rj_why); 398*ee67461eSJoseph Mingrone ND_PRINT("Auth %s", tok2str(sunrpc_auth_str, "Invalid failure code %u", rwhy)); 399abf25193SMax Laier break; 400abf25193SMax Laier 401abf25193SMax Laier default: 402*ee67461eSJoseph Mingrone ND_PRINT("Unknown reason for rejecting rpc message %u", (unsigned int)rstat); 403abf25193SMax Laier break; 404abf25193SMax Laier } 405abf25193SMax Laier break; 406abf25193SMax Laier 407abf25193SMax Laier default: 408*ee67461eSJoseph Mingrone ND_PRINT("reply Unknown rpc response code=%u %u", reply_stat, length); 409abf25193SMax Laier break; 410abf25193SMax Laier } 411a5779b6eSRui Paulo return; 412a5779b6eSRui Paulo 413a5779b6eSRui Paulo trunc: 414*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 4154edb46e9SPaul Traina } 4164edb46e9SPaul Traina 4174edb46e9SPaul Traina /* 4184edb46e9SPaul Traina * Return a pointer to the first file handle in the packet. 419943ee2b1SBill Fenner * If the packet was truncated, return 0. 4204edb46e9SPaul Traina */ 4213c602fabSXin LI static const uint32_t * 4223c602fabSXin LI parsereq(netdissect_options *ndo, 423*ee67461eSJoseph Mingrone const struct sunrpc_msg *rp, u_int length) 4244edb46e9SPaul Traina { 425*ee67461eSJoseph Mingrone const uint32_t *dp; 426*ee67461eSJoseph Mingrone u_int len, rounded_len; 4274edb46e9SPaul Traina 4284edb46e9SPaul Traina /* 429*ee67461eSJoseph Mingrone * Find the start of the req data (if we captured it). 430*ee67461eSJoseph Mingrone * First, get the length of the credentials, and make sure 431*ee67461eSJoseph Mingrone * we have all of the opaque part of the credentials. 4324edb46e9SPaul Traina */ 4333340d773SGleb Smirnoff dp = (const uint32_t *)&rp->rm_call.cb_cred; 434*ee67461eSJoseph Mingrone if (length < 2 * sizeof(*dp)) 435*ee67461eSJoseph Mingrone goto trunc; 436*ee67461eSJoseph Mingrone len = GET_BE_U_4(dp + 1); 437*ee67461eSJoseph Mingrone rounded_len = roundup2(len, 4); 438*ee67461eSJoseph Mingrone ND_TCHECK_LEN(dp + 2, rounded_len); 439*ee67461eSJoseph Mingrone if (2 * sizeof(*dp) + rounded_len <= length) { 440*ee67461eSJoseph Mingrone /* 441*ee67461eSJoseph Mingrone * We have all of the credentials. Skip past them; they 442*ee67461eSJoseph Mingrone * consist of 4 bytes of flavor, 4 bytes of length, 443*ee67461eSJoseph Mingrone * and len-rounded-up-to-a-multiple-of-4 bytes of 444*ee67461eSJoseph Mingrone * data. 445*ee67461eSJoseph Mingrone */ 4462ebf6c05SBill Fenner dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); 447*ee67461eSJoseph Mingrone length -= 2 * sizeof(*dp) + rounded_len; 448*ee67461eSJoseph Mingrone 449*ee67461eSJoseph Mingrone /* 450*ee67461eSJoseph Mingrone * Now get the length of the verifier, and make sure 451*ee67461eSJoseph Mingrone * we have all of the opaque part of the verifier. 452*ee67461eSJoseph Mingrone */ 453*ee67461eSJoseph Mingrone if (length < 2 * sizeof(*dp)) 454*ee67461eSJoseph Mingrone goto trunc; 455*ee67461eSJoseph Mingrone len = GET_BE_U_4(dp + 1); 456*ee67461eSJoseph Mingrone rounded_len = roundup2(len, 4); 457*ee67461eSJoseph Mingrone ND_TCHECK_LEN(dp + 2, rounded_len); 458*ee67461eSJoseph Mingrone if (2 * sizeof(*dp) + rounded_len < length) { 459*ee67461eSJoseph Mingrone /* 460*ee67461eSJoseph Mingrone * We have all of the verifier. Skip past it; 461*ee67461eSJoseph Mingrone * it consists of 4 bytes of flavor, 4 bytes of 462*ee67461eSJoseph Mingrone * length, and len-rounded-up-to-a-multiple-of-4 463*ee67461eSJoseph Mingrone * bytes of data. 464*ee67461eSJoseph Mingrone */ 4652ebf6c05SBill Fenner dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); 4664edb46e9SPaul Traina return (dp); 4674edb46e9SPaul Traina } 4684edb46e9SPaul Traina } 4692ebf6c05SBill Fenner trunc: 4702ebf6c05SBill Fenner return (NULL); 4714edb46e9SPaul Traina } 4724edb46e9SPaul Traina 4734edb46e9SPaul Traina /* 4744edb46e9SPaul Traina * Print out an NFS file handle and return a pointer to following word. 475943ee2b1SBill Fenner * If packet was truncated, return 0. 4764edb46e9SPaul Traina */ 4773c602fabSXin LI static const uint32_t * 4783c602fabSXin LI parsefh(netdissect_options *ndo, 479*ee67461eSJoseph Mingrone const uint32_t *dp, int v3) 4804edb46e9SPaul Traina { 481cc391cceSBruce M Simpson u_int len; 482647f50c3SDoug Rabson 483647f50c3SDoug Rabson if (v3) { 484*ee67461eSJoseph Mingrone len = GET_BE_U_4(dp) / 4; 485647f50c3SDoug Rabson dp++; 486647f50c3SDoug Rabson } else 487647f50c3SDoug Rabson len = NFSX_V2FH / 4; 488647f50c3SDoug Rabson 489*ee67461eSJoseph Mingrone if (ND_TTEST_LEN(dp, len * sizeof(*dp))) { 4903c602fabSXin LI nfs_printfh(ndo, dp, len); 491647f50c3SDoug Rabson return (dp + len); 492*ee67461eSJoseph Mingrone } else 493*ee67461eSJoseph Mingrone return NULL; 4944edb46e9SPaul Traina } 4954edb46e9SPaul Traina 4964edb46e9SPaul Traina /* 4974edb46e9SPaul Traina * Print out a file name and return pointer to 32-bit word past it. 498943ee2b1SBill Fenner * If packet was truncated, return 0. 4994edb46e9SPaul Traina */ 5003c602fabSXin LI static const uint32_t * 5013c602fabSXin LI parsefn(netdissect_options *ndo, 502*ee67461eSJoseph Mingrone const uint32_t *dp) 5034edb46e9SPaul Traina { 504*ee67461eSJoseph Mingrone uint32_t len, rounded_len; 505*ee67461eSJoseph Mingrone const u_char *cp; 5064edb46e9SPaul Traina 507*ee67461eSJoseph Mingrone /* Fetch big-endian string length */ 508*ee67461eSJoseph Mingrone len = GET_BE_U_4(dp); 509*ee67461eSJoseph Mingrone dp++; 5104edb46e9SPaul Traina 511*ee67461eSJoseph Mingrone if (UINT_MAX - len < 3) { 512*ee67461eSJoseph Mingrone ND_PRINT("[cannot pad to 32-bit boundaries]"); 513*ee67461eSJoseph Mingrone nd_print_invalid(ndo); 514*ee67461eSJoseph Mingrone return NULL; 515*ee67461eSJoseph Mingrone } 5164edb46e9SPaul Traina 517*ee67461eSJoseph Mingrone rounded_len = roundup2(len, 4); 518*ee67461eSJoseph Mingrone ND_TCHECK_LEN(dp, rounded_len); 519943ee2b1SBill Fenner 5203340d773SGleb Smirnoff cp = (const u_char *)dp; 5214edb46e9SPaul Traina /* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */ 522*ee67461eSJoseph Mingrone dp += rounded_len / sizeof(*dp); 523*ee67461eSJoseph Mingrone ND_PRINT("\""); 524*ee67461eSJoseph Mingrone if (nd_printn(ndo, cp, len, ndo->ndo_snapend)) { 525*ee67461eSJoseph Mingrone ND_PRINT("\""); 52629292c17SSam Leffler goto trunc; 52729292c17SSam Leffler } 528*ee67461eSJoseph Mingrone ND_PRINT("\""); 5294edb46e9SPaul Traina 5304edb46e9SPaul Traina return (dp); 531943ee2b1SBill Fenner trunc: 532943ee2b1SBill Fenner return NULL; 5334edb46e9SPaul Traina } 5344edb46e9SPaul Traina 5354edb46e9SPaul Traina /* 5364edb46e9SPaul Traina * Print out file handle and file name. 5374edb46e9SPaul Traina * Return pointer to 32-bit word past file name. 538943ee2b1SBill Fenner * If packet was truncated (or there was some other error), return 0. 5394edb46e9SPaul Traina */ 5403c602fabSXin LI static const uint32_t * 5413c602fabSXin LI parsefhn(netdissect_options *ndo, 542*ee67461eSJoseph Mingrone const uint32_t *dp, int v3) 5434edb46e9SPaul Traina { 5443c602fabSXin LI dp = parsefh(ndo, dp, v3); 5452ebf6c05SBill Fenner if (dp == NULL) 5462ebf6c05SBill Fenner return (NULL); 547*ee67461eSJoseph Mingrone ND_PRINT(" "); 5483c602fabSXin LI return (parsefn(ndo, dp)); 5494edb46e9SPaul Traina } 5504edb46e9SPaul Traina 5514edb46e9SPaul Traina void 552*ee67461eSJoseph Mingrone nfsreq_noaddr_print(netdissect_options *ndo, 553*ee67461eSJoseph Mingrone const u_char *bp, u_int length, 554*ee67461eSJoseph Mingrone const u_char *bp2) 5554edb46e9SPaul Traina { 556*ee67461eSJoseph Mingrone const struct sunrpc_msg *rp; 557*ee67461eSJoseph Mingrone const uint32_t *dp; 558943ee2b1SBill Fenner nfs_type type; 559943ee2b1SBill Fenner int v3; 5603c602fabSXin LI uint32_t proc; 5613c602fabSXin LI uint32_t access_flags; 562647f50c3SDoug Rabson struct nfsv3_sattr sa3; 5634edb46e9SPaul Traina 564*ee67461eSJoseph Mingrone ndo->ndo_protocol = "nfs"; 565*ee67461eSJoseph Mingrone ND_PRINT("%u", length); 566c1ad1296SSam Leffler rp = (const struct sunrpc_msg *)bp; 567a5779b6eSRui Paulo 5683c602fabSXin LI if (!xid_map_enter(ndo, rp, bp2)) /* record proc number for later on */ 569a5779b6eSRui Paulo goto trunc; 5704edb46e9SPaul Traina 571*ee67461eSJoseph Mingrone v3 = (GET_BE_U_4(&rp->rm_call.cb_vers) == NFS_VER3); 572*ee67461eSJoseph Mingrone proc = GET_BE_U_4(&rp->rm_call.cb_proc); 573647f50c3SDoug Rabson 574647f50c3SDoug Rabson if (!v3 && proc < NFS_NPROCS) 575647f50c3SDoug Rabson proc = nfsv3_procid[proc]; 576647f50c3SDoug Rabson 577*ee67461eSJoseph Mingrone ND_PRINT(" %s", tok2str(nfsproc_str, "proc-%u", proc)); 578647f50c3SDoug Rabson switch (proc) { 5794edb46e9SPaul Traina 5804edb46e9SPaul Traina case NFSPROC_GETATTR: 5814edb46e9SPaul Traina case NFSPROC_SETATTR: 5823c602fabSXin LI case NFSPROC_READLINK: 5833c602fabSXin LI case NFSPROC_FSSTAT: 5843c602fabSXin LI case NFSPROC_FSINFO: 5853c602fabSXin LI case NFSPROC_PATHCONF: 586*ee67461eSJoseph Mingrone dp = parsereq(ndo, rp, length); 587*ee67461eSJoseph Mingrone if (dp == NULL) 588*ee67461eSJoseph Mingrone goto trunc; 589*ee67461eSJoseph Mingrone if (parsefh(ndo, dp, v3) == NULL) 590*ee67461eSJoseph Mingrone goto trunc; 5914edb46e9SPaul Traina break; 5924edb46e9SPaul Traina 5934edb46e9SPaul Traina case NFSPROC_LOOKUP: 5943c602fabSXin LI case NFSPROC_CREATE: 5953c602fabSXin LI case NFSPROC_MKDIR: 5963c602fabSXin LI case NFSPROC_REMOVE: 5973c602fabSXin LI case NFSPROC_RMDIR: 598*ee67461eSJoseph Mingrone dp = parsereq(ndo, rp, length); 599*ee67461eSJoseph Mingrone if (dp == NULL) 600*ee67461eSJoseph Mingrone goto trunc; 601*ee67461eSJoseph Mingrone if (parsefhn(ndo, dp, v3) == NULL) 602*ee67461eSJoseph Mingrone goto trunc; 6034edb46e9SPaul Traina break; 6044edb46e9SPaul Traina 605647f50c3SDoug Rabson case NFSPROC_ACCESS: 606*ee67461eSJoseph Mingrone dp = parsereq(ndo, rp, length); 607*ee67461eSJoseph Mingrone if (dp == NULL) 608*ee67461eSJoseph Mingrone goto trunc; 609*ee67461eSJoseph Mingrone dp = parsefh(ndo, dp, v3); 610*ee67461eSJoseph Mingrone if (dp == NULL) 611*ee67461eSJoseph Mingrone goto trunc; 612*ee67461eSJoseph Mingrone access_flags = GET_BE_U_4(dp); 61327df3f5dSRui Paulo if (access_flags & ~NFSV3ACCESS_FULL) { 61427df3f5dSRui Paulo /* NFSV3ACCESS definitions aren't up to date */ 615*ee67461eSJoseph Mingrone ND_PRINT(" %04x", access_flags); 61627df3f5dSRui Paulo } else if ((access_flags & NFSV3ACCESS_FULL) == NFSV3ACCESS_FULL) { 617*ee67461eSJoseph Mingrone ND_PRINT(" NFS_ACCESS_FULL"); 61827df3f5dSRui Paulo } else { 61927df3f5dSRui Paulo char separator = ' '; 62027df3f5dSRui Paulo if (access_flags & NFSV3ACCESS_READ) { 621*ee67461eSJoseph Mingrone ND_PRINT(" NFS_ACCESS_READ"); 62227df3f5dSRui Paulo separator = '|'; 62327df3f5dSRui Paulo } 62427df3f5dSRui Paulo if (access_flags & NFSV3ACCESS_LOOKUP) { 625*ee67461eSJoseph Mingrone ND_PRINT("%cNFS_ACCESS_LOOKUP", separator); 62627df3f5dSRui Paulo separator = '|'; 62727df3f5dSRui Paulo } 62827df3f5dSRui Paulo if (access_flags & NFSV3ACCESS_MODIFY) { 629*ee67461eSJoseph Mingrone ND_PRINT("%cNFS_ACCESS_MODIFY", separator); 63027df3f5dSRui Paulo separator = '|'; 63127df3f5dSRui Paulo } 63227df3f5dSRui Paulo if (access_flags & NFSV3ACCESS_EXTEND) { 633*ee67461eSJoseph Mingrone ND_PRINT("%cNFS_ACCESS_EXTEND", separator); 63427df3f5dSRui Paulo separator = '|'; 63527df3f5dSRui Paulo } 63627df3f5dSRui Paulo if (access_flags & NFSV3ACCESS_DELETE) { 637*ee67461eSJoseph Mingrone ND_PRINT("%cNFS_ACCESS_DELETE", separator); 63827df3f5dSRui Paulo separator = '|'; 63927df3f5dSRui Paulo } 64027df3f5dSRui Paulo if (access_flags & NFSV3ACCESS_EXECUTE) 641*ee67461eSJoseph Mingrone ND_PRINT("%cNFS_ACCESS_EXECUTE", separator); 642647f50c3SDoug Rabson } 643647f50c3SDoug Rabson break; 644647f50c3SDoug Rabson 6454edb46e9SPaul Traina case NFSPROC_READ: 646*ee67461eSJoseph Mingrone dp = parsereq(ndo, rp, length); 647*ee67461eSJoseph Mingrone if (dp == NULL) 648*ee67461eSJoseph Mingrone goto trunc; 649*ee67461eSJoseph Mingrone dp = parsefh(ndo, dp, v3); 650*ee67461eSJoseph Mingrone if (dp == NULL) 651*ee67461eSJoseph Mingrone goto trunc; 652647f50c3SDoug Rabson if (v3) { 653*ee67461eSJoseph Mingrone ND_PRINT(" %u bytes @ %" PRIu64, 654*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 2), 655*ee67461eSJoseph Mingrone GET_BE_U_8(dp)); 656647f50c3SDoug Rabson } else { 657*ee67461eSJoseph Mingrone ND_PRINT(" %u bytes @ %u", 658*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 1), 659*ee67461eSJoseph Mingrone GET_BE_U_4(dp)); 6604edb46e9SPaul Traina } 6614edb46e9SPaul Traina break; 6624edb46e9SPaul Traina 6634edb46e9SPaul Traina case NFSPROC_WRITE: 664*ee67461eSJoseph Mingrone dp = parsereq(ndo, rp, length); 665*ee67461eSJoseph Mingrone if (dp == NULL) 666*ee67461eSJoseph Mingrone goto trunc; 667*ee67461eSJoseph Mingrone dp = parsefh(ndo, dp, v3); 668*ee67461eSJoseph Mingrone if (dp == NULL) 669*ee67461eSJoseph Mingrone goto trunc; 670647f50c3SDoug Rabson if (v3) { 671*ee67461eSJoseph Mingrone ND_PRINT(" %u (%u) bytes @ %" PRIu64, 672*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 4), 673*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 2), 674*ee67461eSJoseph Mingrone GET_BE_U_8(dp)); 6753c602fabSXin LI if (ndo->ndo_vflag) { 676*ee67461eSJoseph Mingrone ND_PRINT(" <%s>", 677943ee2b1SBill Fenner tok2str(nfsv3_writemodes, 678*ee67461eSJoseph Mingrone NULL, GET_BE_U_4(dp + 3))); 679647f50c3SDoug Rabson } 680647f50c3SDoug Rabson } else { 681*ee67461eSJoseph Mingrone ND_PRINT(" %u (%u) bytes @ %u (%u)", 682*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 3), 683*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 2), 684*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 1), 685*ee67461eSJoseph Mingrone GET_BE_U_4(dp)); 6864edb46e9SPaul Traina } 6874edb46e9SPaul Traina break; 6884edb46e9SPaul Traina 689647f50c3SDoug Rabson case NFSPROC_SYMLINK: 690*ee67461eSJoseph Mingrone dp = parsereq(ndo, rp, length); 691*ee67461eSJoseph Mingrone if (dp == NULL) 692*ee67461eSJoseph Mingrone goto trunc; 693*ee67461eSJoseph Mingrone dp = parsefhn(ndo, dp, v3); 694*ee67461eSJoseph Mingrone if (dp == NULL) 695*ee67461eSJoseph Mingrone goto trunc; 696*ee67461eSJoseph Mingrone ND_PRINT(" ->"); 6973340d773SGleb Smirnoff if (v3 && (dp = parse_sattr3(ndo, dp, &sa3)) == NULL) 698*ee67461eSJoseph Mingrone goto trunc; 6993340d773SGleb Smirnoff if (parsefn(ndo, dp) == NULL) 700*ee67461eSJoseph Mingrone goto trunc; 7013c602fabSXin LI if (v3 && ndo->ndo_vflag) 7023c602fabSXin LI print_sattr3(ndo, &sa3, ndo->ndo_vflag); 703647f50c3SDoug Rabson break; 704647f50c3SDoug Rabson 705647f50c3SDoug Rabson case NFSPROC_MKNOD: 706*ee67461eSJoseph Mingrone dp = parsereq(ndo, rp, length); 707*ee67461eSJoseph Mingrone if (dp == NULL) 708*ee67461eSJoseph Mingrone goto trunc; 709*ee67461eSJoseph Mingrone dp = parsefhn(ndo, dp, v3); 710*ee67461eSJoseph Mingrone if (dp == NULL) 711*ee67461eSJoseph Mingrone goto trunc; 712*ee67461eSJoseph Mingrone type = (nfs_type) GET_BE_U_4(dp); 713cc391cceSBruce M Simpson dp++; 714*ee67461eSJoseph Mingrone dp = parse_sattr3(ndo, dp, &sa3); 715*ee67461eSJoseph Mingrone if (dp == NULL) 716*ee67461eSJoseph Mingrone goto trunc; 717*ee67461eSJoseph Mingrone ND_PRINT(" %s", tok2str(type2str, "unk-ft %u", type)); 7183c602fabSXin LI if (ndo->ndo_vflag && (type == NFCHR || type == NFBLK)) { 719*ee67461eSJoseph Mingrone ND_PRINT(" %u/%u", 720*ee67461eSJoseph Mingrone GET_BE_U_4(dp), 721*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 1)); 722647f50c3SDoug Rabson dp += 2; 723647f50c3SDoug Rabson } 7243c602fabSXin LI if (ndo->ndo_vflag) 7253c602fabSXin LI print_sattr3(ndo, &sa3, ndo->ndo_vflag); 726647f50c3SDoug Rabson break; 727647f50c3SDoug Rabson 7284edb46e9SPaul Traina case NFSPROC_RENAME: 729*ee67461eSJoseph Mingrone dp = parsereq(ndo, rp, length); 730*ee67461eSJoseph Mingrone if (dp == NULL) 731*ee67461eSJoseph Mingrone goto trunc; 732*ee67461eSJoseph Mingrone dp = parsefhn(ndo, dp, v3); 733*ee67461eSJoseph Mingrone if (dp == NULL) 734*ee67461eSJoseph Mingrone goto trunc; 735*ee67461eSJoseph Mingrone ND_PRINT(" ->"); 736*ee67461eSJoseph Mingrone if (parsefhn(ndo, dp, v3) == NULL) 737*ee67461eSJoseph Mingrone goto trunc; 7384edb46e9SPaul Traina break; 7394edb46e9SPaul Traina 7404edb46e9SPaul Traina case NFSPROC_LINK: 741*ee67461eSJoseph Mingrone dp = parsereq(ndo, rp, length); 742*ee67461eSJoseph Mingrone if (dp == NULL) 743*ee67461eSJoseph Mingrone goto trunc; 744*ee67461eSJoseph Mingrone dp = parsefh(ndo, dp, v3); 745*ee67461eSJoseph Mingrone if (dp == NULL) 746*ee67461eSJoseph Mingrone goto trunc; 747*ee67461eSJoseph Mingrone ND_PRINT(" ->"); 748*ee67461eSJoseph Mingrone if (parsefhn(ndo, dp, v3) == NULL) 749*ee67461eSJoseph Mingrone goto trunc; 7504edb46e9SPaul Traina break; 7514edb46e9SPaul Traina 7524edb46e9SPaul Traina case NFSPROC_READDIR: 753*ee67461eSJoseph Mingrone dp = parsereq(ndo, rp, length); 754*ee67461eSJoseph Mingrone if (dp == NULL) 755*ee67461eSJoseph Mingrone goto trunc; 756*ee67461eSJoseph Mingrone dp = parsefh(ndo, dp, v3); 757*ee67461eSJoseph Mingrone if (dp == NULL) 758*ee67461eSJoseph Mingrone goto trunc; 759647f50c3SDoug Rabson if (v3) { 7604edb46e9SPaul Traina /* 761647f50c3SDoug Rabson * We shouldn't really try to interpret the 762647f50c3SDoug Rabson * offset cookie here. 7634edb46e9SPaul Traina */ 764*ee67461eSJoseph Mingrone ND_PRINT(" %u bytes @ %" PRId64, 765*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 4), 766*ee67461eSJoseph Mingrone GET_BE_U_8(dp)); 767*ee67461eSJoseph Mingrone if (ndo->ndo_vflag) { 768*ee67461eSJoseph Mingrone /* 769*ee67461eSJoseph Mingrone * This displays the 8 bytes 770*ee67461eSJoseph Mingrone * of the verifier in order, 771*ee67461eSJoseph Mingrone * from the low-order byte 772*ee67461eSJoseph Mingrone * to the high-order byte. 773*ee67461eSJoseph Mingrone */ 774*ee67461eSJoseph Mingrone ND_PRINT(" verf %08x%08x", 775*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 2), 776*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 3)); 777*ee67461eSJoseph Mingrone } 778647f50c3SDoug Rabson } else { 779647f50c3SDoug Rabson /* 780647f50c3SDoug Rabson * Print the offset as signed, since -1 is 781647f50c3SDoug Rabson * common, but offsets > 2^31 aren't. 782647f50c3SDoug Rabson */ 783*ee67461eSJoseph Mingrone ND_PRINT(" %u bytes @ %u", 784*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 1), 785*ee67461eSJoseph Mingrone GET_BE_U_4(dp)); 7864edb46e9SPaul Traina } 7874edb46e9SPaul Traina break; 7884edb46e9SPaul Traina 789647f50c3SDoug Rabson case NFSPROC_READDIRPLUS: 790*ee67461eSJoseph Mingrone dp = parsereq(ndo, rp, length); 791*ee67461eSJoseph Mingrone if (dp == NULL) 792*ee67461eSJoseph Mingrone goto trunc; 793*ee67461eSJoseph Mingrone dp = parsefh(ndo, dp, v3); 794*ee67461eSJoseph Mingrone if (dp == NULL) 795*ee67461eSJoseph Mingrone goto trunc; 796647f50c3SDoug Rabson /* 797647f50c3SDoug Rabson * We don't try to interpret the offset 798647f50c3SDoug Rabson * cookie here. 799647f50c3SDoug Rabson */ 800*ee67461eSJoseph Mingrone ND_PRINT(" %u bytes @ %" PRId64, 801*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 4), 802*ee67461eSJoseph Mingrone GET_BE_U_8(dp)); 8033c602fabSXin LI if (ndo->ndo_vflag) { 804*ee67461eSJoseph Mingrone /* 805*ee67461eSJoseph Mingrone * This displays the 8 bytes 806*ee67461eSJoseph Mingrone * of the verifier in order, 807*ee67461eSJoseph Mingrone * from the low-order byte 808*ee67461eSJoseph Mingrone * to the high-order byte. 809*ee67461eSJoseph Mingrone */ 810*ee67461eSJoseph Mingrone ND_PRINT(" max %u verf %08x%08x", 811*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 5), 812*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 2), 813*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 3)); 814647f50c3SDoug Rabson } 815647f50c3SDoug Rabson break; 816647f50c3SDoug Rabson 817647f50c3SDoug Rabson case NFSPROC_COMMIT: 818*ee67461eSJoseph Mingrone dp = parsereq(ndo, rp, length); 819*ee67461eSJoseph Mingrone if (dp == NULL) 820*ee67461eSJoseph Mingrone goto trunc; 821*ee67461eSJoseph Mingrone dp = parsefh(ndo, dp, v3); 822*ee67461eSJoseph Mingrone if (dp == NULL) 823*ee67461eSJoseph Mingrone goto trunc; 824*ee67461eSJoseph Mingrone ND_PRINT(" %u bytes @ %" PRIu64, 825*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 2), 826*ee67461eSJoseph Mingrone GET_BE_U_8(dp)); 827647f50c3SDoug Rabson break; 828647f50c3SDoug Rabson 8294edb46e9SPaul Traina default: 830*ee67461eSJoseph Mingrone break; 8314edb46e9SPaul Traina } 832*ee67461eSJoseph Mingrone return; 833943ee2b1SBill Fenner 8344edb46e9SPaul Traina trunc: 835*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 8364edb46e9SPaul Traina } 8374edb46e9SPaul Traina 8384edb46e9SPaul Traina /* 8394edb46e9SPaul Traina * Print out an NFS file handle. 8404edb46e9SPaul Traina * We assume packet was not truncated before the end of the 8414edb46e9SPaul Traina * file handle pointed to by dp. 8424edb46e9SPaul Traina * 8434edb46e9SPaul Traina * Note: new version (using portable file-handle parser) doesn't produce 8444edb46e9SPaul Traina * generation number. It probably could be made to do that, with some 8454edb46e9SPaul Traina * additional hacking on the parser code. 8464edb46e9SPaul Traina */ 8474edb46e9SPaul Traina static void 8483c602fabSXin LI nfs_printfh(netdissect_options *ndo, 849*ee67461eSJoseph Mingrone const uint32_t *dp, const u_int len) 8504edb46e9SPaul Traina { 8514edb46e9SPaul Traina my_fsid fsid; 8523c602fabSXin LI uint32_t ino; 853cc391cceSBruce M Simpson const char *sfsname = NULL; 854cc391cceSBruce M Simpson char *spacep; 8554edb46e9SPaul Traina 8563c602fabSXin LI if (ndo->ndo_uflag) { 857cc391cceSBruce M Simpson u_int i; 858cc391cceSBruce M Simpson char const *sep = ""; 859cc391cceSBruce M Simpson 860*ee67461eSJoseph Mingrone ND_PRINT(" fh["); 861cc391cceSBruce M Simpson for (i=0; i<len; i++) { 862*ee67461eSJoseph Mingrone /* 863*ee67461eSJoseph Mingrone * This displays 4 bytes in big-endian byte 864*ee67461eSJoseph Mingrone * order. That's as good a choice as little- 865*ee67461eSJoseph Mingrone * endian, as there's no guarantee that the 866*ee67461eSJoseph Mingrone * server is big-endian or little-endian or 867*ee67461eSJoseph Mingrone * that the file handle contains 4-byte 868*ee67461eSJoseph Mingrone * integral fields, and is better than "the 869*ee67461eSJoseph Mingrone * byte order of the host running tcpdump", as 870*ee67461eSJoseph Mingrone * the latter means that different hosts 871*ee67461eSJoseph Mingrone * running tcpdump may show the same file 872*ee67461eSJoseph Mingrone * handle in different ways. 873*ee67461eSJoseph Mingrone */ 874*ee67461eSJoseph Mingrone ND_PRINT("%s%x", sep, GET_BE_U_4(dp + i)); 875cc391cceSBruce M Simpson sep = ":"; 876cc391cceSBruce M Simpson } 877*ee67461eSJoseph Mingrone ND_PRINT("]"); 878cc391cceSBruce M Simpson return; 879cc391cceSBruce M Simpson } 880cc391cceSBruce M Simpson 881*ee67461eSJoseph Mingrone Parse_fh(ndo, (const u_char *)dp, len, &fsid, &ino, NULL, &sfsname, 0); 8824edb46e9SPaul Traina 8834edb46e9SPaul Traina if (sfsname) { 8844edb46e9SPaul Traina /* file system ID is ASCII, not numeric, for this server OS */ 8850bff6a5aSEd Maste char temp[NFSX_V3FHMAX+1]; 8860bff6a5aSEd Maste u_int stringlen; 8874edb46e9SPaul Traina 8884edb46e9SPaul Traina /* Make sure string is null-terminated */ 8890bff6a5aSEd Maste stringlen = len; 8900bff6a5aSEd Maste if (stringlen > NFSX_V3FHMAX) 8910bff6a5aSEd Maste stringlen = NFSX_V3FHMAX; 8920bff6a5aSEd Maste strncpy(temp, sfsname, stringlen); 8930bff6a5aSEd Maste temp[stringlen] = '\0'; 8944edb46e9SPaul Traina /* Remove trailing spaces */ 895cc391cceSBruce M Simpson spacep = strchr(temp, ' '); 896cc391cceSBruce M Simpson if (spacep) 897cc391cceSBruce M Simpson *spacep = '\0'; 8984edb46e9SPaul Traina 899*ee67461eSJoseph Mingrone ND_PRINT(" fh %s/", temp); 9002ebf6c05SBill Fenner } else { 901*ee67461eSJoseph Mingrone ND_PRINT(" fh %u,%u/", 902*ee67461eSJoseph Mingrone fsid.Fsid_dev.Major, fsid.Fsid_dev.Minor); 9034edb46e9SPaul Traina } 904943ee2b1SBill Fenner 905cc391cceSBruce M Simpson if(fsid.Fsid_dev.Minor == 257) 906943ee2b1SBill Fenner /* Print the undecoded handle */ 907*ee67461eSJoseph Mingrone ND_PRINT("%s", fsid.Opaque_Handle); 908943ee2b1SBill Fenner else 909*ee67461eSJoseph Mingrone ND_PRINT("%u", ino); 9104edb46e9SPaul Traina } 9114edb46e9SPaul Traina 9124edb46e9SPaul Traina /* 9134edb46e9SPaul Traina * Maintain a small cache of recent client.XID.server/proc pairs, to allow 9144edb46e9SPaul Traina * us to match up replies with requests and thus to know how to parse 9154edb46e9SPaul Traina * the reply. 9164edb46e9SPaul Traina */ 9174edb46e9SPaul Traina 9184edb46e9SPaul Traina struct xid_map_entry { 9193c602fabSXin LI uint32_t xid; /* transaction ID (net order) */ 920943ee2b1SBill Fenner int ipver; /* IP version (4 or 6) */ 921*ee67461eSJoseph Mingrone nd_ipv6 client; /* client IP address (net order) */ 922*ee67461eSJoseph Mingrone nd_ipv6 server; /* server IP address (net order) */ 9233c602fabSXin LI uint32_t proc; /* call proc number (host order) */ 9243c602fabSXin LI uint32_t vers; /* program version (host order) */ 9254edb46e9SPaul Traina }; 9264edb46e9SPaul Traina 9274edb46e9SPaul Traina /* 9284edb46e9SPaul Traina * Map entries are kept in an array that we manage as a ring; 9294edb46e9SPaul Traina * new entries are always added at the tail of the ring. Initially, 9304edb46e9SPaul Traina * all the entries are zero and hence don't match anything. 9314edb46e9SPaul Traina */ 9324edb46e9SPaul Traina 9334edb46e9SPaul Traina #define XIDMAPSIZE 64 9344edb46e9SPaul Traina 9353340d773SGleb Smirnoff static struct xid_map_entry xid_map[XIDMAPSIZE]; 9364edb46e9SPaul Traina 9373340d773SGleb Smirnoff static int xid_map_next = 0; 9383340d773SGleb Smirnoff static int xid_map_hint = 0; 9394edb46e9SPaul Traina 940a5779b6eSRui Paulo static int 9413c602fabSXin LI xid_map_enter(netdissect_options *ndo, 9423c602fabSXin LI const struct sunrpc_msg *rp, const u_char *bp) 9434edb46e9SPaul Traina { 9443340d773SGleb Smirnoff const struct ip *ip = NULL; 9453340d773SGleb Smirnoff const struct ip6_hdr *ip6 = NULL; 9464edb46e9SPaul Traina struct xid_map_entry *xmep; 9474edb46e9SPaul Traina 948*ee67461eSJoseph Mingrone if (!ND_TTEST_4(rp->rm_call.cb_proc)) 949a5779b6eSRui Paulo return (0); 9503340d773SGleb Smirnoff switch (IP_V((const struct ip *)bp)) { 951943ee2b1SBill Fenner case 4: 9523340d773SGleb Smirnoff ip = (const struct ip *)bp; 953943ee2b1SBill Fenner break; 954943ee2b1SBill Fenner case 6: 9553340d773SGleb Smirnoff ip6 = (const struct ip6_hdr *)bp; 956943ee2b1SBill Fenner break; 957943ee2b1SBill Fenner default: 958a5779b6eSRui Paulo return (1); 959943ee2b1SBill Fenner } 960943ee2b1SBill Fenner 9614edb46e9SPaul Traina xmep = &xid_map[xid_map_next]; 9624edb46e9SPaul Traina 9634edb46e9SPaul Traina if (++xid_map_next >= XIDMAPSIZE) 9644edb46e9SPaul Traina xid_map_next = 0; 9654edb46e9SPaul Traina 9663c602fabSXin LI UNALIGNED_MEMCPY(&xmep->xid, &rp->rm_xid, sizeof(xmep->xid)); 967943ee2b1SBill Fenner if (ip) { 968943ee2b1SBill Fenner xmep->ipver = 4; 969*ee67461eSJoseph Mingrone UNALIGNED_MEMCPY(&xmep->client, ip->ip_src, 970*ee67461eSJoseph Mingrone sizeof(ip->ip_src)); 971*ee67461eSJoseph Mingrone UNALIGNED_MEMCPY(&xmep->server, ip->ip_dst, 972*ee67461eSJoseph Mingrone sizeof(ip->ip_dst)); 973943ee2b1SBill Fenner } 974943ee2b1SBill Fenner else if (ip6) { 975943ee2b1SBill Fenner xmep->ipver = 6; 976*ee67461eSJoseph Mingrone UNALIGNED_MEMCPY(&xmep->client, ip6->ip6_src, 977*ee67461eSJoseph Mingrone sizeof(ip6->ip6_src)); 978*ee67461eSJoseph Mingrone UNALIGNED_MEMCPY(&xmep->server, ip6->ip6_dst, 979*ee67461eSJoseph Mingrone sizeof(ip6->ip6_dst)); 980943ee2b1SBill Fenner } 981*ee67461eSJoseph Mingrone xmep->proc = GET_BE_U_4(&rp->rm_call.cb_proc); 982*ee67461eSJoseph Mingrone xmep->vers = GET_BE_U_4(&rp->rm_call.cb_vers); 983a5779b6eSRui Paulo return (1); 9844edb46e9SPaul Traina } 9854edb46e9SPaul Traina 9862ebf6c05SBill Fenner /* 9872ebf6c05SBill Fenner * Returns 0 and puts NFSPROC_xxx in proc return and 9882ebf6c05SBill Fenner * version in vers return, or returns -1 on failure 9892ebf6c05SBill Fenner */ 990647f50c3SDoug Rabson static int 991*ee67461eSJoseph Mingrone xid_map_find(netdissect_options *ndo, const struct sunrpc_msg *rp, 992*ee67461eSJoseph Mingrone const u_char *bp, uint32_t *proc, uint32_t *vers) 9934edb46e9SPaul Traina { 9944edb46e9SPaul Traina int i; 9954edb46e9SPaul Traina struct xid_map_entry *xmep; 9963340d773SGleb Smirnoff uint32_t xid; 9973340d773SGleb Smirnoff const struct ip *ip = (const struct ip *)bp; 9983340d773SGleb Smirnoff const struct ip6_hdr *ip6 = (const struct ip6_hdr *)bp; 999943ee2b1SBill Fenner int cmp; 10004edb46e9SPaul Traina 10013340d773SGleb Smirnoff UNALIGNED_MEMCPY(&xid, &rp->rm_xid, sizeof(xmep->xid)); 10024edb46e9SPaul Traina /* Start searching from where we last left off */ 10034edb46e9SPaul Traina i = xid_map_hint; 10044edb46e9SPaul Traina do { 10054edb46e9SPaul Traina xmep = &xid_map[i]; 1006943ee2b1SBill Fenner cmp = 1; 1007943ee2b1SBill Fenner if (xmep->ipver != IP_V(ip) || xmep->xid != xid) 1008943ee2b1SBill Fenner goto nextitem; 1009943ee2b1SBill Fenner switch (xmep->ipver) { 1010943ee2b1SBill Fenner case 4: 1011*ee67461eSJoseph Mingrone if (UNALIGNED_MEMCMP(ip->ip_src, &xmep->server, 1012943ee2b1SBill Fenner sizeof(ip->ip_src)) != 0 || 1013*ee67461eSJoseph Mingrone UNALIGNED_MEMCMP(ip->ip_dst, &xmep->client, 1014943ee2b1SBill Fenner sizeof(ip->ip_dst)) != 0) { 1015943ee2b1SBill Fenner cmp = 0; 1016943ee2b1SBill Fenner } 1017943ee2b1SBill Fenner break; 1018943ee2b1SBill Fenner case 6: 1019*ee67461eSJoseph Mingrone if (UNALIGNED_MEMCMP(ip6->ip6_src, &xmep->server, 1020943ee2b1SBill Fenner sizeof(ip6->ip6_src)) != 0 || 1021*ee67461eSJoseph Mingrone UNALIGNED_MEMCMP(ip6->ip6_dst, &xmep->client, 1022943ee2b1SBill Fenner sizeof(ip6->ip6_dst)) != 0) { 1023943ee2b1SBill Fenner cmp = 0; 1024943ee2b1SBill Fenner } 1025943ee2b1SBill Fenner break; 1026943ee2b1SBill Fenner default: 1027943ee2b1SBill Fenner cmp = 0; 1028943ee2b1SBill Fenner break; 1029943ee2b1SBill Fenner } 1030943ee2b1SBill Fenner if (cmp) { 10314edb46e9SPaul Traina /* match */ 10324edb46e9SPaul Traina xid_map_hint = i; 1033647f50c3SDoug Rabson *proc = xmep->proc; 1034647f50c3SDoug Rabson *vers = xmep->vers; 1035647f50c3SDoug Rabson return 0; 10364edb46e9SPaul Traina } 1037943ee2b1SBill Fenner nextitem: 10384edb46e9SPaul Traina if (++i >= XIDMAPSIZE) 10394edb46e9SPaul Traina i = 0; 10404edb46e9SPaul Traina } while (i != xid_map_hint); 10414edb46e9SPaul Traina 10424edb46e9SPaul Traina /* search failed */ 1043943ee2b1SBill Fenner return (-1); 10444edb46e9SPaul Traina } 10454edb46e9SPaul Traina 10464edb46e9SPaul Traina /* 10474edb46e9SPaul Traina * Routines for parsing reply packets 10484edb46e9SPaul Traina */ 10494edb46e9SPaul Traina 10504edb46e9SPaul Traina /* 10514edb46e9SPaul Traina * Return a pointer to the beginning of the actual results. 1052943ee2b1SBill Fenner * If the packet was truncated, return 0. 10534edb46e9SPaul Traina */ 10543c602fabSXin LI static const uint32_t * 10553c602fabSXin LI parserep(netdissect_options *ndo, 1056*ee67461eSJoseph Mingrone const struct sunrpc_msg *rp, u_int length, int *nfserrp) 10574edb46e9SPaul Traina { 1058*ee67461eSJoseph Mingrone const uint32_t *dp; 1059943ee2b1SBill Fenner u_int len; 1060c1ad1296SSam Leffler enum sunrpc_accept_stat astat; 10614edb46e9SPaul Traina 10624edb46e9SPaul Traina /* 10634edb46e9SPaul Traina * Portability note: 10644edb46e9SPaul Traina * Here we find the address of the ar_verf credentials. 10654edb46e9SPaul Traina * Originally, this calculation was 10663c602fabSXin LI * dp = (uint32_t *)&rp->rm_reply.rp_acpt.ar_verf 10674edb46e9SPaul Traina * On the wire, the rp_acpt field starts immediately after 10684edb46e9SPaul Traina * the (32 bit) rp_stat field. However, rp_acpt (which is a 10694edb46e9SPaul Traina * "struct accepted_reply") contains a "struct opaque_auth", 10704edb46e9SPaul Traina * whose internal representation contains a pointer, so on a 10714edb46e9SPaul Traina * 64-bit machine the compiler inserts 32 bits of padding 10724edb46e9SPaul Traina * before rp->rm_reply.rp_acpt.ar_verf. So, we cannot use 10734edb46e9SPaul Traina * the internal representation to parse the on-the-wire 10744edb46e9SPaul Traina * representation. Instead, we skip past the rp_stat field, 10754edb46e9SPaul Traina * which is an "enum" and so occupies one 32-bit word. 10764edb46e9SPaul Traina */ 10773c602fabSXin LI dp = ((const uint32_t *)&rp->rm_reply) + 1; 1078*ee67461eSJoseph Mingrone len = GET_BE_U_4(dp + 1); 10794edb46e9SPaul Traina if (len >= length) 10802ebf6c05SBill Fenner return (NULL); 10814edb46e9SPaul Traina /* 10824edb46e9SPaul Traina * skip past the ar_verf credentials. 10834edb46e9SPaul Traina */ 10843c602fabSXin LI dp += (len + (2*sizeof(uint32_t) + 3)) / sizeof(uint32_t); 10854edb46e9SPaul Traina 10864edb46e9SPaul Traina /* 10874edb46e9SPaul Traina * now we can check the ar_stat field 10884edb46e9SPaul Traina */ 1089*ee67461eSJoseph Mingrone astat = (enum sunrpc_accept_stat) GET_BE_U_4(dp); 10903c602fabSXin LI if (astat != SUNRPC_SUCCESS) { 1091*ee67461eSJoseph Mingrone ND_PRINT(" %s", tok2str(sunrpc_str, "ar_stat %u", astat)); 1092*ee67461eSJoseph Mingrone *nfserrp = 1; /* suppress trunc string */ 10932ebf6c05SBill Fenner return (NULL); 10944edb46e9SPaul Traina } 10954edb46e9SPaul Traina /* successful return */ 1096*ee67461eSJoseph Mingrone ND_TCHECK_LEN(dp, sizeof(astat)); 10973340d773SGleb Smirnoff return ((const uint32_t *) (sizeof(astat) + ((const char *)dp))); 10982ebf6c05SBill Fenner trunc: 1099943ee2b1SBill Fenner return (0); 11004edb46e9SPaul Traina } 11014edb46e9SPaul Traina 11023c602fabSXin LI static const uint32_t * 11033c602fabSXin LI parsestatus(netdissect_options *ndo, 1104*ee67461eSJoseph Mingrone const uint32_t *dp, u_int *er, int *nfserrp) 1105647f50c3SDoug Rabson { 1106*ee67461eSJoseph Mingrone u_int errnum; 1107647f50c3SDoug Rabson 1108*ee67461eSJoseph Mingrone errnum = GET_BE_U_4(dp); 1109647f50c3SDoug Rabson if (er) 11102ebf6c05SBill Fenner *er = errnum; 11112ebf6c05SBill Fenner if (errnum != 0) { 11123c602fabSXin LI if (!ndo->ndo_qflag) 1113*ee67461eSJoseph Mingrone ND_PRINT(" ERROR: %s", 1114*ee67461eSJoseph Mingrone tok2str(status2str, "unk %u", errnum)); 1115*ee67461eSJoseph Mingrone *nfserrp = 1; 11164edb46e9SPaul Traina } 11174edb46e9SPaul Traina return (dp + 1); 11184edb46e9SPaul Traina } 11194edb46e9SPaul Traina 11203c602fabSXin LI static const uint32_t * 11213c602fabSXin LI parsefattr(netdissect_options *ndo, 11223c602fabSXin LI const uint32_t *dp, int verbose, int v3) 11234edb46e9SPaul Traina { 1124647f50c3SDoug Rabson const struct nfs_fattr *fap; 11254edb46e9SPaul Traina 1126647f50c3SDoug Rabson fap = (const struct nfs_fattr *)dp; 1127*ee67461eSJoseph Mingrone ND_TCHECK_4(fap->fa_gid); 11284edb46e9SPaul Traina if (verbose) { 1129*ee67461eSJoseph Mingrone /* 1130*ee67461eSJoseph Mingrone * XXX - UIDs and GIDs are unsigned in NFS and in 1131*ee67461eSJoseph Mingrone * at least some UN*Xes, but we'll show them as 1132*ee67461eSJoseph Mingrone * signed because -2 has traditionally been the 1133*ee67461eSJoseph Mingrone * UID for "nobody", rather than 4294967294. 1134*ee67461eSJoseph Mingrone */ 1135*ee67461eSJoseph Mingrone ND_PRINT(" %s %o ids %d/%d", 1136*ee67461eSJoseph Mingrone tok2str(type2str, "unk-ft %u ", 1137*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa_type)), 1138*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa_mode), 1139*ee67461eSJoseph Mingrone GET_BE_S_4(fap->fa_uid), 1140*ee67461eSJoseph Mingrone GET_BE_S_4(fap->fa_gid)); 1141647f50c3SDoug Rabson if (v3) { 1142*ee67461eSJoseph Mingrone ND_PRINT(" sz %" PRIu64, 1143*ee67461eSJoseph Mingrone GET_BE_U_8(fap->fa3_size)); 1144685b49deSBill Fenner } else { 1145*ee67461eSJoseph Mingrone ND_PRINT(" sz %u", GET_BE_U_4(fap->fa2_size)); 1146647f50c3SDoug Rabson } 11474edb46e9SPaul Traina } 11484edb46e9SPaul Traina /* print lots more stuff */ 11494edb46e9SPaul Traina if (verbose > 1) { 1150647f50c3SDoug Rabson if (v3) { 1151*ee67461eSJoseph Mingrone ND_TCHECK_8(&fap->fa3_ctime); 1152*ee67461eSJoseph Mingrone ND_PRINT(" nlink %u rdev %u/%u", 1153*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa_nlink), 1154*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa3_rdev.specdata1), 1155*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa3_rdev.specdata2)); 1156*ee67461eSJoseph Mingrone ND_PRINT(" fsid %" PRIx64, 1157*ee67461eSJoseph Mingrone GET_BE_U_8(fap->fa3_fsid)); 1158*ee67461eSJoseph Mingrone ND_PRINT(" fileid %" PRIx64, 1159*ee67461eSJoseph Mingrone GET_BE_U_8(fap->fa3_fileid)); 1160*ee67461eSJoseph Mingrone ND_PRINT(" a/m/ctime %u.%06u", 1161*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa3_atime.nfsv3_sec), 1162*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa3_atime.nfsv3_nsec)); 1163*ee67461eSJoseph Mingrone ND_PRINT(" %u.%06u", 1164*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa3_mtime.nfsv3_sec), 1165*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa3_mtime.nfsv3_nsec)); 1166*ee67461eSJoseph Mingrone ND_PRINT(" %u.%06u", 1167*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa3_ctime.nfsv3_sec), 1168*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa3_ctime.nfsv3_nsec)); 1169647f50c3SDoug Rabson } else { 1170*ee67461eSJoseph Mingrone ND_TCHECK_8(&fap->fa2_ctime); 1171*ee67461eSJoseph Mingrone ND_PRINT(" nlink %u rdev 0x%x fsid 0x%x nodeid 0x%x a/m/ctime", 1172*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa_nlink), 1173*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa2_rdev), 1174*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa2_fsid), 1175*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa2_fileid)); 1176*ee67461eSJoseph Mingrone ND_PRINT(" %u.%06u", 1177*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa2_atime.nfsv2_sec), 1178*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa2_atime.nfsv2_usec)); 1179*ee67461eSJoseph Mingrone ND_PRINT(" %u.%06u", 1180*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa2_mtime.nfsv2_sec), 1181*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa2_mtime.nfsv2_usec)); 1182*ee67461eSJoseph Mingrone ND_PRINT(" %u.%06u", 1183*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa2_ctime.nfsv2_sec), 1184*ee67461eSJoseph Mingrone GET_BE_U_4(fap->fa2_ctime.nfsv2_usec)); 11854edb46e9SPaul Traina } 1186647f50c3SDoug Rabson } 11873340d773SGleb Smirnoff return ((const uint32_t *)((const unsigned char *)dp + 1188647f50c3SDoug Rabson (v3 ? NFSX_V3FATTR : NFSX_V2FATTR))); 1189685b49deSBill Fenner trunc: 1190685b49deSBill Fenner return (NULL); 11914edb46e9SPaul Traina } 11924edb46e9SPaul Traina 11934edb46e9SPaul Traina static int 11943c602fabSXin LI parseattrstat(netdissect_options *ndo, 1195*ee67461eSJoseph Mingrone const uint32_t *dp, int verbose, int v3, int *nfserrp) 11964edb46e9SPaul Traina { 1197*ee67461eSJoseph Mingrone u_int er; 1198647f50c3SDoug Rabson 1199*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, nfserrp); 12000e0def19SBill Fenner if (dp == NULL) 12014edb46e9SPaul Traina return (0); 12020e0def19SBill Fenner if (er) 12030e0def19SBill Fenner return (1); 12044edb46e9SPaul Traina 12053c602fabSXin LI return (parsefattr(ndo, dp, verbose, v3) != NULL); 12064edb46e9SPaul Traina } 12074edb46e9SPaul Traina 12084edb46e9SPaul Traina static int 12093c602fabSXin LI parsediropres(netdissect_options *ndo, 1210*ee67461eSJoseph Mingrone const uint32_t *dp, int *nfserrp) 12114edb46e9SPaul Traina { 1212*ee67461eSJoseph Mingrone u_int er; 1213647f50c3SDoug Rabson 1214*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, nfserrp); 1215*ee67461eSJoseph Mingrone if (dp == NULL) 1216647f50c3SDoug Rabson return (0); 12170e0def19SBill Fenner if (er) 12180e0def19SBill Fenner return (1); 1219647f50c3SDoug Rabson 12203c602fabSXin LI dp = parsefh(ndo, dp, 0); 12214edb46e9SPaul Traina if (dp == NULL) 12224edb46e9SPaul Traina return (0); 12234edb46e9SPaul Traina 12243c602fabSXin LI return (parsefattr(ndo, dp, ndo->ndo_vflag, 0) != NULL); 12254edb46e9SPaul Traina } 12264edb46e9SPaul Traina 12274edb46e9SPaul Traina static int 12283c602fabSXin LI parselinkres(netdissect_options *ndo, 1229*ee67461eSJoseph Mingrone const uint32_t *dp, int v3, int *nfserrp) 12304edb46e9SPaul Traina { 1231*ee67461eSJoseph Mingrone u_int er; 12324edb46e9SPaul Traina 1233*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, nfserrp); 12340e0def19SBill Fenner if (dp == NULL) 1235647f50c3SDoug Rabson return(0); 12360e0def19SBill Fenner if (er) 12370e0def19SBill Fenner return(1); 1238*ee67461eSJoseph Mingrone if (v3) { 1239*ee67461eSJoseph Mingrone dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); 1240*ee67461eSJoseph Mingrone if (dp == NULL) 1241647f50c3SDoug Rabson return (0); 1242*ee67461eSJoseph Mingrone } 1243*ee67461eSJoseph Mingrone ND_PRINT(" "); 12443c602fabSXin LI return (parsefn(ndo, dp) != NULL); 12454edb46e9SPaul Traina } 12464edb46e9SPaul Traina 12474edb46e9SPaul Traina static int 12483c602fabSXin LI parsestatfs(netdissect_options *ndo, 1249*ee67461eSJoseph Mingrone const uint32_t *dp, int v3, int *nfserrp) 12504edb46e9SPaul Traina { 1251647f50c3SDoug Rabson const struct nfs_statfs *sfsp; 1252*ee67461eSJoseph Mingrone u_int er; 12534edb46e9SPaul Traina 1254*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, nfserrp); 12550e0def19SBill Fenner if (dp == NULL) 12564edb46e9SPaul Traina return (0); 12570e0def19SBill Fenner if (!v3 && er) 12580e0def19SBill Fenner return (1); 12594edb46e9SPaul Traina 12603c602fabSXin LI if (ndo->ndo_qflag) 1261647f50c3SDoug Rabson return(1); 1262647f50c3SDoug Rabson 1263647f50c3SDoug Rabson if (v3) { 12643c602fabSXin LI if (ndo->ndo_vflag) 1265*ee67461eSJoseph Mingrone ND_PRINT(" POST:"); 1266*ee67461eSJoseph Mingrone dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); 1267*ee67461eSJoseph Mingrone if (dp == NULL) 1268647f50c3SDoug Rabson return (0); 1269647f50c3SDoug Rabson } 1270647f50c3SDoug Rabson 1271*ee67461eSJoseph Mingrone ND_TCHECK_LEN(dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); 1272647f50c3SDoug Rabson 1273647f50c3SDoug Rabson sfsp = (const struct nfs_statfs *)dp; 1274647f50c3SDoug Rabson 1275647f50c3SDoug Rabson if (v3) { 1276*ee67461eSJoseph Mingrone ND_PRINT(" tbytes %" PRIu64 " fbytes %" PRIu64 " abytes %" PRIu64, 1277*ee67461eSJoseph Mingrone GET_BE_U_8(sfsp->sf_tbytes), 1278*ee67461eSJoseph Mingrone GET_BE_U_8(sfsp->sf_fbytes), 1279*ee67461eSJoseph Mingrone GET_BE_U_8(sfsp->sf_abytes)); 12803c602fabSXin LI if (ndo->ndo_vflag) { 1281*ee67461eSJoseph Mingrone ND_PRINT(" tfiles %" PRIu64 " ffiles %" PRIu64 " afiles %" PRIu64 " invar %u", 1282*ee67461eSJoseph Mingrone GET_BE_U_8(sfsp->sf_tfiles), 1283*ee67461eSJoseph Mingrone GET_BE_U_8(sfsp->sf_ffiles), 1284*ee67461eSJoseph Mingrone GET_BE_U_8(sfsp->sf_afiles), 1285*ee67461eSJoseph Mingrone GET_BE_U_4(sfsp->sf_invarsec)); 1286647f50c3SDoug Rabson } 1287647f50c3SDoug Rabson } else { 1288*ee67461eSJoseph Mingrone ND_PRINT(" tsize %u bsize %u blocks %u bfree %u bavail %u", 1289*ee67461eSJoseph Mingrone GET_BE_U_4(sfsp->sf_tsize), 1290*ee67461eSJoseph Mingrone GET_BE_U_4(sfsp->sf_bsize), 1291*ee67461eSJoseph Mingrone GET_BE_U_4(sfsp->sf_blocks), 1292*ee67461eSJoseph Mingrone GET_BE_U_4(sfsp->sf_bfree), 1293*ee67461eSJoseph Mingrone GET_BE_U_4(sfsp->sf_bavail)); 12944edb46e9SPaul Traina } 12954edb46e9SPaul Traina 12964edb46e9SPaul Traina return (1); 1297685b49deSBill Fenner trunc: 1298685b49deSBill Fenner return (0); 12994edb46e9SPaul Traina } 13004edb46e9SPaul Traina 13014edb46e9SPaul Traina static int 13023c602fabSXin LI parserddires(netdissect_options *ndo, 1303*ee67461eSJoseph Mingrone const uint32_t *dp, int *nfserrp) 13044edb46e9SPaul Traina { 1305*ee67461eSJoseph Mingrone u_int er; 1306647f50c3SDoug Rabson 1307*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, nfserrp); 13080e0def19SBill Fenner if (dp == NULL) 13094edb46e9SPaul Traina return (0); 13100e0def19SBill Fenner if (er) 13110e0def19SBill Fenner return (1); 13123c602fabSXin LI if (ndo->ndo_qflag) 1313647f50c3SDoug Rabson return (1); 1314647f50c3SDoug Rabson 1315*ee67461eSJoseph Mingrone ND_PRINT(" offset 0x%x size %u ", 1316*ee67461eSJoseph Mingrone GET_BE_U_4(dp), GET_BE_U_4(dp + 1)); 1317*ee67461eSJoseph Mingrone if (GET_BE_U_4(dp + 2) != 0) 1318*ee67461eSJoseph Mingrone ND_PRINT(" eof"); 13194edb46e9SPaul Traina 13204edb46e9SPaul Traina return (1); 1321647f50c3SDoug Rabson } 1322647f50c3SDoug Rabson 13233c602fabSXin LI static const uint32_t * 13243c602fabSXin LI parse_wcc_attr(netdissect_options *ndo, 13253c602fabSXin LI const uint32_t *dp) 1326647f50c3SDoug Rabson { 13270bff6a5aSEd Maste /* Our caller has already checked this */ 1328*ee67461eSJoseph Mingrone ND_PRINT(" sz %" PRIu64, GET_BE_U_8(dp)); 1329*ee67461eSJoseph Mingrone ND_PRINT(" mtime %u.%06u ctime %u.%06u", 1330*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 2), GET_BE_U_4(dp + 3), 1331*ee67461eSJoseph Mingrone GET_BE_U_4(dp + 4), GET_BE_U_4(dp + 5)); 1332647f50c3SDoug Rabson return (dp + 6); 1333647f50c3SDoug Rabson } 1334647f50c3SDoug Rabson 1335647f50c3SDoug Rabson /* 1336647f50c3SDoug Rabson * Pre operation attributes. Print only if vflag > 1. 1337647f50c3SDoug Rabson */ 13383c602fabSXin LI static const uint32_t * 13393c602fabSXin LI parse_pre_op_attr(netdissect_options *ndo, 13403c602fabSXin LI const uint32_t *dp, int verbose) 1341647f50c3SDoug Rabson { 1342*ee67461eSJoseph Mingrone if (!GET_BE_U_4(dp)) 1343647f50c3SDoug Rabson return (dp + 1); 1344647f50c3SDoug Rabson dp++; 1345*ee67461eSJoseph Mingrone ND_TCHECK_LEN(dp, 24); 1346647f50c3SDoug Rabson if (verbose > 1) { 13473c602fabSXin LI return parse_wcc_attr(ndo, dp); 1348647f50c3SDoug Rabson } else { 1349647f50c3SDoug Rabson /* If not verbose enough, just skip over wcc_attr */ 1350647f50c3SDoug Rabson return (dp + 6); 1351647f50c3SDoug Rabson } 1352685b49deSBill Fenner trunc: 1353685b49deSBill Fenner return (NULL); 1354647f50c3SDoug Rabson } 1355647f50c3SDoug Rabson 1356647f50c3SDoug Rabson /* 1357647f50c3SDoug Rabson * Post operation attributes are printed if vflag >= 1 1358647f50c3SDoug Rabson */ 13593c602fabSXin LI static const uint32_t * 13603c602fabSXin LI parse_post_op_attr(netdissect_options *ndo, 13613c602fabSXin LI const uint32_t *dp, int verbose) 1362647f50c3SDoug Rabson { 1363*ee67461eSJoseph Mingrone if (!GET_BE_U_4(dp)) 1364647f50c3SDoug Rabson return (dp + 1); 1365647f50c3SDoug Rabson dp++; 1366647f50c3SDoug Rabson if (verbose) { 13673c602fabSXin LI return parsefattr(ndo, dp, verbose, 1); 1368647f50c3SDoug Rabson } else 13693c602fabSXin LI return (dp + (NFSX_V3FATTR / sizeof (uint32_t))); 1370647f50c3SDoug Rabson } 1371647f50c3SDoug Rabson 13723c602fabSXin LI static const uint32_t * 13733c602fabSXin LI parse_wcc_data(netdissect_options *ndo, 13743c602fabSXin LI const uint32_t *dp, int verbose) 1375647f50c3SDoug Rabson { 1376647f50c3SDoug Rabson if (verbose > 1) 1377*ee67461eSJoseph Mingrone ND_PRINT(" PRE:"); 1378*ee67461eSJoseph Mingrone dp = parse_pre_op_attr(ndo, dp, verbose); 1379*ee67461eSJoseph Mingrone if (dp == NULL) 1380943ee2b1SBill Fenner return (0); 1381647f50c3SDoug Rabson 1382647f50c3SDoug Rabson if (verbose) 1383*ee67461eSJoseph Mingrone ND_PRINT(" POST:"); 13843c602fabSXin LI return parse_post_op_attr(ndo, dp, verbose); 1385647f50c3SDoug Rabson } 1386647f50c3SDoug Rabson 13873c602fabSXin LI static const uint32_t * 13883c602fabSXin LI parsecreateopres(netdissect_options *ndo, 1389*ee67461eSJoseph Mingrone const uint32_t *dp, int verbose, int *nfserrp) 1390647f50c3SDoug Rabson { 1391*ee67461eSJoseph Mingrone u_int er; 1392647f50c3SDoug Rabson 1393*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, nfserrp); 1394*ee67461eSJoseph Mingrone if (dp == NULL) 1395943ee2b1SBill Fenner return (0); 1396647f50c3SDoug Rabson if (er) 13973c602fabSXin LI dp = parse_wcc_data(ndo, dp, verbose); 1398647f50c3SDoug Rabson else { 1399*ee67461eSJoseph Mingrone if (!GET_BE_U_4(dp)) 1400647f50c3SDoug Rabson return (dp + 1); 1401647f50c3SDoug Rabson dp++; 1402*ee67461eSJoseph Mingrone dp = parsefh(ndo, dp, 1); 1403*ee67461eSJoseph Mingrone if (dp == NULL) 1404943ee2b1SBill Fenner return (0); 1405647f50c3SDoug Rabson if (verbose) { 1406*ee67461eSJoseph Mingrone dp = parse_post_op_attr(ndo, dp, verbose); 1407*ee67461eSJoseph Mingrone if (dp == NULL) 1408943ee2b1SBill Fenner return (0); 14093c602fabSXin LI if (ndo->ndo_vflag > 1) { 1410*ee67461eSJoseph Mingrone ND_PRINT(" dir attr:"); 14113c602fabSXin LI dp = parse_wcc_data(ndo, dp, verbose); 1412647f50c3SDoug Rabson } 1413647f50c3SDoug Rabson } 1414647f50c3SDoug Rabson } 1415647f50c3SDoug Rabson return (dp); 1416647f50c3SDoug Rabson } 1417647f50c3SDoug Rabson 1418*ee67461eSJoseph Mingrone static const uint32_t * 14193c602fabSXin LI parsewccres(netdissect_options *ndo, 1420*ee67461eSJoseph Mingrone const uint32_t *dp, int verbose, int *nfserrp) 1421647f50c3SDoug Rabson { 1422*ee67461eSJoseph Mingrone u_int er; 1423647f50c3SDoug Rabson 1424*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, nfserrp); 1425*ee67461eSJoseph Mingrone if (dp == NULL) 1426647f50c3SDoug Rabson return (0); 1427*ee67461eSJoseph Mingrone return parse_wcc_data(ndo, dp, verbose); 1428647f50c3SDoug Rabson } 1429647f50c3SDoug Rabson 14303c602fabSXin LI static const uint32_t * 14313c602fabSXin LI parsev3rddirres(netdissect_options *ndo, 1432*ee67461eSJoseph Mingrone const uint32_t *dp, int verbose, int *nfserrp) 1433647f50c3SDoug Rabson { 1434*ee67461eSJoseph Mingrone u_int er; 1435647f50c3SDoug Rabson 1436*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, nfserrp); 1437*ee67461eSJoseph Mingrone if (dp == NULL) 1438943ee2b1SBill Fenner return (0); 14393c602fabSXin LI if (ndo->ndo_vflag) 1440*ee67461eSJoseph Mingrone ND_PRINT(" POST:"); 1441*ee67461eSJoseph Mingrone dp = parse_post_op_attr(ndo, dp, verbose); 1442*ee67461eSJoseph Mingrone if (dp == NULL) 1443943ee2b1SBill Fenner return (0); 1444647f50c3SDoug Rabson if (er) 1445647f50c3SDoug Rabson return dp; 14463c602fabSXin LI if (ndo->ndo_vflag) { 1447*ee67461eSJoseph Mingrone /* 1448*ee67461eSJoseph Mingrone * This displays the 8 bytes of the verifier in order, 1449*ee67461eSJoseph Mingrone * from the low-order byte to the high-order byte. 1450*ee67461eSJoseph Mingrone */ 1451*ee67461eSJoseph Mingrone ND_PRINT(" verf %08x%08x", 1452*ee67461eSJoseph Mingrone GET_BE_U_4(dp), GET_BE_U_4(dp + 1)); 1453647f50c3SDoug Rabson dp += 2; 1454647f50c3SDoug Rabson } 1455647f50c3SDoug Rabson return dp; 1456647f50c3SDoug Rabson } 1457647f50c3SDoug Rabson 1458647f50c3SDoug Rabson static int 14593c602fabSXin LI parsefsinfo(netdissect_options *ndo, 1460*ee67461eSJoseph Mingrone const uint32_t *dp, int *nfserrp) 1461647f50c3SDoug Rabson { 14623340d773SGleb Smirnoff const struct nfsv3_fsinfo *sfp; 1463*ee67461eSJoseph Mingrone u_int er; 1464647f50c3SDoug Rabson 1465*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, nfserrp); 1466*ee67461eSJoseph Mingrone if (dp == NULL) 1467647f50c3SDoug Rabson return (0); 14683c602fabSXin LI if (ndo->ndo_vflag) 1469*ee67461eSJoseph Mingrone ND_PRINT(" POST:"); 1470*ee67461eSJoseph Mingrone dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); 1471*ee67461eSJoseph Mingrone if (dp == NULL) 1472647f50c3SDoug Rabson return (0); 1473647f50c3SDoug Rabson if (er) 1474647f50c3SDoug Rabson return (1); 1475647f50c3SDoug Rabson 14763340d773SGleb Smirnoff sfp = (const struct nfsv3_fsinfo *)dp; 1477*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(sfp); 1478*ee67461eSJoseph Mingrone ND_PRINT(" rtmax %u rtpref %u wtmax %u wtpref %u dtpref %u", 1479*ee67461eSJoseph Mingrone GET_BE_U_4(sfp->fs_rtmax), 1480*ee67461eSJoseph Mingrone GET_BE_U_4(sfp->fs_rtpref), 1481*ee67461eSJoseph Mingrone GET_BE_U_4(sfp->fs_wtmax), 1482*ee67461eSJoseph Mingrone GET_BE_U_4(sfp->fs_wtpref), 1483*ee67461eSJoseph Mingrone GET_BE_U_4(sfp->fs_dtpref)); 14843c602fabSXin LI if (ndo->ndo_vflag) { 1485*ee67461eSJoseph Mingrone ND_PRINT(" rtmult %u wtmult %u maxfsz %" PRIu64, 1486*ee67461eSJoseph Mingrone GET_BE_U_4(sfp->fs_rtmult), 1487*ee67461eSJoseph Mingrone GET_BE_U_4(sfp->fs_wtmult), 1488*ee67461eSJoseph Mingrone GET_BE_U_8(sfp->fs_maxfilesize)); 1489*ee67461eSJoseph Mingrone ND_PRINT(" delta %u.%06u ", 1490*ee67461eSJoseph Mingrone GET_BE_U_4(sfp->fs_timedelta.nfsv3_sec), 1491*ee67461eSJoseph Mingrone GET_BE_U_4(sfp->fs_timedelta.nfsv3_nsec)); 1492647f50c3SDoug Rabson } 1493943ee2b1SBill Fenner return (1); 14940e0def19SBill Fenner trunc: 14950e0def19SBill Fenner return (0); 1496647f50c3SDoug Rabson } 1497647f50c3SDoug Rabson 1498647f50c3SDoug Rabson static int 14993c602fabSXin LI parsepathconf(netdissect_options *ndo, 1500*ee67461eSJoseph Mingrone const uint32_t *dp, int *nfserrp) 1501647f50c3SDoug Rabson { 1502*ee67461eSJoseph Mingrone u_int er; 15033340d773SGleb Smirnoff const struct nfsv3_pathconf *spp; 1504647f50c3SDoug Rabson 1505*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, nfserrp); 1506*ee67461eSJoseph Mingrone if (dp == NULL) 1507647f50c3SDoug Rabson return (0); 15083c602fabSXin LI if (ndo->ndo_vflag) 1509*ee67461eSJoseph Mingrone ND_PRINT(" POST:"); 1510*ee67461eSJoseph Mingrone dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); 1511*ee67461eSJoseph Mingrone if (dp == NULL) 1512647f50c3SDoug Rabson return (0); 1513647f50c3SDoug Rabson if (er) 1514647f50c3SDoug Rabson return (1); 1515647f50c3SDoug Rabson 15163340d773SGleb Smirnoff spp = (const struct nfsv3_pathconf *)dp; 1517*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(spp); 1518647f50c3SDoug Rabson 1519*ee67461eSJoseph Mingrone ND_PRINT(" linkmax %u namemax %u %s %s %s %s", 1520*ee67461eSJoseph Mingrone GET_BE_U_4(spp->pc_linkmax), 1521*ee67461eSJoseph Mingrone GET_BE_U_4(spp->pc_namemax), 1522*ee67461eSJoseph Mingrone GET_BE_U_4(spp->pc_notrunc) ? "notrunc" : "", 1523*ee67461eSJoseph Mingrone GET_BE_U_4(spp->pc_chownrestricted) ? "chownres" : "", 1524*ee67461eSJoseph Mingrone GET_BE_U_4(spp->pc_caseinsensitive) ? "igncase" : "", 1525*ee67461eSJoseph Mingrone GET_BE_U_4(spp->pc_casepreserving) ? "keepcase" : ""); 1526943ee2b1SBill Fenner return (1); 15270e0def19SBill Fenner trunc: 15280e0def19SBill Fenner return (0); 15294edb46e9SPaul Traina } 15304edb46e9SPaul Traina 15314edb46e9SPaul Traina static void 15323c602fabSXin LI interp_reply(netdissect_options *ndo, 1533*ee67461eSJoseph Mingrone const struct sunrpc_msg *rp, uint32_t proc, uint32_t vers, 1534*ee67461eSJoseph Mingrone int length) 15354edb46e9SPaul Traina { 1536*ee67461eSJoseph Mingrone const uint32_t *dp; 1537*ee67461eSJoseph Mingrone int v3; 1538*ee67461eSJoseph Mingrone u_int er; 1539*ee67461eSJoseph Mingrone int nfserr = 0; 1540647f50c3SDoug Rabson 1541647f50c3SDoug Rabson v3 = (vers == NFS_VER3); 1542647f50c3SDoug Rabson 1543647f50c3SDoug Rabson if (!v3 && proc < NFS_NPROCS) 1544647f50c3SDoug Rabson proc = nfsv3_procid[proc]; 15454edb46e9SPaul Traina 1546*ee67461eSJoseph Mingrone ND_PRINT(" %s", tok2str(nfsproc_str, "proc-%u", proc)); 15474edb46e9SPaul Traina switch (proc) { 15484edb46e9SPaul Traina 15494edb46e9SPaul Traina case NFSPROC_GETATTR: 1550*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1551*ee67461eSJoseph Mingrone if (dp == NULL) 1552*ee67461eSJoseph Mingrone goto trunc; 1553*ee67461eSJoseph Mingrone if (parseattrstat(ndo, dp, !ndo->ndo_qflag, v3, &nfserr) == 0) 1554*ee67461eSJoseph Mingrone goto trunc; 15554edb46e9SPaul Traina break; 15564edb46e9SPaul Traina 15574edb46e9SPaul Traina case NFSPROC_SETATTR: 1558*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1559*ee67461eSJoseph Mingrone if (dp == NULL) 1560*ee67461eSJoseph Mingrone goto trunc; 1561647f50c3SDoug Rabson if (v3) { 1562*ee67461eSJoseph Mingrone if (parsewccres(ndo, dp, ndo->ndo_vflag, &nfserr) == 0) 1563*ee67461eSJoseph Mingrone goto trunc; 1564647f50c3SDoug Rabson } else { 1565*ee67461eSJoseph Mingrone if (parseattrstat(ndo, dp, !ndo->ndo_qflag, 0, &nfserr) == 0) 1566*ee67461eSJoseph Mingrone goto trunc; 1567647f50c3SDoug Rabson } 15684edb46e9SPaul Traina break; 15694edb46e9SPaul Traina 15704edb46e9SPaul Traina case NFSPROC_LOOKUP: 1571*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1572*ee67461eSJoseph Mingrone if (dp == NULL) 1573*ee67461eSJoseph Mingrone goto trunc; 1574647f50c3SDoug Rabson if (v3) { 1575*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, &nfserr); 1576*ee67461eSJoseph Mingrone if (dp == NULL) 1577*ee67461eSJoseph Mingrone goto trunc; 1578647f50c3SDoug Rabson if (er) { 15793c602fabSXin LI if (ndo->ndo_vflag > 1) { 1580*ee67461eSJoseph Mingrone ND_PRINT(" post dattr:"); 15813c602fabSXin LI dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); 1582*ee67461eSJoseph Mingrone if (dp == NULL) 1583*ee67461eSJoseph Mingrone goto trunc; 1584647f50c3SDoug Rabson } 1585647f50c3SDoug Rabson } else { 1586*ee67461eSJoseph Mingrone dp = parsefh(ndo, dp, v3); 1587*ee67461eSJoseph Mingrone if (dp == NULL) 1588*ee67461eSJoseph Mingrone goto trunc; 15893c602fabSXin LI dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); 1590*ee67461eSJoseph Mingrone if (dp == NULL) 1591*ee67461eSJoseph Mingrone goto trunc; 1592*ee67461eSJoseph Mingrone if (ndo->ndo_vflag > 1) { 1593*ee67461eSJoseph Mingrone ND_PRINT(" post dattr:"); 1594*ee67461eSJoseph Mingrone dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); 1595*ee67461eSJoseph Mingrone if (dp == NULL) 1596*ee67461eSJoseph Mingrone goto trunc; 1597647f50c3SDoug Rabson } 1598647f50c3SDoug Rabson } 1599647f50c3SDoug Rabson } else { 1600*ee67461eSJoseph Mingrone if (parsediropres(ndo, dp, &nfserr) == 0) 1601*ee67461eSJoseph Mingrone goto trunc; 1602647f50c3SDoug Rabson } 1603647f50c3SDoug Rabson break; 1604647f50c3SDoug Rabson 1605647f50c3SDoug Rabson case NFSPROC_ACCESS: 1606*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1607*ee67461eSJoseph Mingrone if (dp == NULL) 1608*ee67461eSJoseph Mingrone goto trunc; 1609*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, &nfserr); 1610*ee67461eSJoseph Mingrone if (dp == NULL) 1611*ee67461eSJoseph Mingrone goto trunc; 16123c602fabSXin LI if (ndo->ndo_vflag) 1613*ee67461eSJoseph Mingrone ND_PRINT(" attr:"); 1614*ee67461eSJoseph Mingrone dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); 1615*ee67461eSJoseph Mingrone if (dp == NULL) 1616*ee67461eSJoseph Mingrone goto trunc; 16170bff6a5aSEd Maste if (!er) { 1618*ee67461eSJoseph Mingrone ND_PRINT(" c %04x", GET_BE_U_4(dp)); 16190bff6a5aSEd Maste } 1620*ee67461eSJoseph Mingrone break; 16214edb46e9SPaul Traina 16224edb46e9SPaul Traina case NFSPROC_READLINK: 1623*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1624*ee67461eSJoseph Mingrone if (dp == NULL) 1625*ee67461eSJoseph Mingrone goto trunc; 1626*ee67461eSJoseph Mingrone if (parselinkres(ndo, dp, v3, &nfserr) == 0) 1627*ee67461eSJoseph Mingrone goto trunc; 16284edb46e9SPaul Traina break; 16294edb46e9SPaul Traina 16304edb46e9SPaul Traina case NFSPROC_READ: 1631*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1632*ee67461eSJoseph Mingrone if (dp == NULL) 1633*ee67461eSJoseph Mingrone goto trunc; 1634647f50c3SDoug Rabson if (v3) { 1635*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, &nfserr); 1636*ee67461eSJoseph Mingrone if (dp == NULL) 1637*ee67461eSJoseph Mingrone goto trunc; 1638*ee67461eSJoseph Mingrone dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); 1639*ee67461eSJoseph Mingrone if (dp == NULL) 1640*ee67461eSJoseph Mingrone goto trunc; 1641*ee67461eSJoseph Mingrone if (!er) { 16423c602fabSXin LI if (ndo->ndo_vflag) { 1643*ee67461eSJoseph Mingrone ND_PRINT(" %u bytes", GET_BE_U_4(dp)); 1644*ee67461eSJoseph Mingrone if (GET_BE_U_4(dp + 1)) 1645*ee67461eSJoseph Mingrone ND_PRINT(" EOF"); 1646647f50c3SDoug Rabson } 1647*ee67461eSJoseph Mingrone } 1648647f50c3SDoug Rabson } else { 1649*ee67461eSJoseph Mingrone if (parseattrstat(ndo, dp, ndo->ndo_vflag, 0, &nfserr) == 0) 1650*ee67461eSJoseph Mingrone goto trunc; 1651647f50c3SDoug Rabson } 16524edb46e9SPaul Traina break; 16534edb46e9SPaul Traina 16544edb46e9SPaul Traina case NFSPROC_WRITE: 1655*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1656*ee67461eSJoseph Mingrone if (dp == NULL) 1657*ee67461eSJoseph Mingrone goto trunc; 1658647f50c3SDoug Rabson if (v3) { 1659*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, &nfserr); 1660*ee67461eSJoseph Mingrone if (dp == NULL) 1661*ee67461eSJoseph Mingrone goto trunc; 1662*ee67461eSJoseph Mingrone dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag); 1663*ee67461eSJoseph Mingrone if (dp == NULL) 1664*ee67461eSJoseph Mingrone goto trunc; 1665*ee67461eSJoseph Mingrone if (!er) { 16663c602fabSXin LI if (ndo->ndo_vflag) { 1667*ee67461eSJoseph Mingrone ND_PRINT(" %u bytes", GET_BE_U_4(dp)); 16683c602fabSXin LI if (ndo->ndo_vflag > 1) { 1669*ee67461eSJoseph Mingrone ND_PRINT(" <%s>", 1670943ee2b1SBill Fenner tok2str(nfsv3_writemodes, 1671*ee67461eSJoseph Mingrone NULL, GET_BE_U_4(dp + 1))); 1672*ee67461eSJoseph Mingrone 1673*ee67461eSJoseph Mingrone /* write-verf-cookie */ 1674*ee67461eSJoseph Mingrone ND_PRINT(" verf %" PRIx64, 1675*ee67461eSJoseph Mingrone GET_BE_U_8(dp + 2)); 1676*ee67461eSJoseph Mingrone } 1677647f50c3SDoug Rabson } 1678647f50c3SDoug Rabson } 167939e421e8SCy Schubert return; 1680647f50c3SDoug Rabson } else { 1681*ee67461eSJoseph Mingrone if (parseattrstat(ndo, dp, ndo->ndo_vflag, v3, &nfserr) == 0) 1682*ee67461eSJoseph Mingrone goto trunc; 1683647f50c3SDoug Rabson } 16844edb46e9SPaul Traina break; 16854edb46e9SPaul Traina 16864edb46e9SPaul Traina case NFSPROC_CREATE: 1687647f50c3SDoug Rabson case NFSPROC_MKDIR: 1688*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1689*ee67461eSJoseph Mingrone if (dp == NULL) 1690*ee67461eSJoseph Mingrone goto trunc; 1691647f50c3SDoug Rabson if (v3) { 1692*ee67461eSJoseph Mingrone if (parsecreateopres(ndo, dp, ndo->ndo_vflag, &nfserr) == NULL) 1693*ee67461eSJoseph Mingrone goto trunc; 1694647f50c3SDoug Rabson } else { 1695*ee67461eSJoseph Mingrone if (parsediropres(ndo, dp, &nfserr) == 0) 1696*ee67461eSJoseph Mingrone goto trunc; 1697647f50c3SDoug Rabson } 1698647f50c3SDoug Rabson break; 1699647f50c3SDoug Rabson 1700647f50c3SDoug Rabson case NFSPROC_SYMLINK: 1701*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1702*ee67461eSJoseph Mingrone if (dp == NULL) 1703*ee67461eSJoseph Mingrone goto trunc; 1704647f50c3SDoug Rabson if (v3) { 1705*ee67461eSJoseph Mingrone if (parsecreateopres(ndo, dp, ndo->ndo_vflag, &nfserr) == NULL) 1706*ee67461eSJoseph Mingrone goto trunc; 1707647f50c3SDoug Rabson } else { 1708*ee67461eSJoseph Mingrone if (parsestatus(ndo, dp, &er, &nfserr) == NULL) 1709*ee67461eSJoseph Mingrone goto trunc; 1710647f50c3SDoug Rabson } 1711647f50c3SDoug Rabson break; 1712647f50c3SDoug Rabson 1713647f50c3SDoug Rabson case NFSPROC_MKNOD: 1714*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1715*ee67461eSJoseph Mingrone if (dp == NULL) 1716*ee67461eSJoseph Mingrone goto trunc; 1717*ee67461eSJoseph Mingrone if (parsecreateopres(ndo, dp, ndo->ndo_vflag, &nfserr) == NULL) 1718*ee67461eSJoseph Mingrone goto trunc; 17194edb46e9SPaul Traina break; 17204edb46e9SPaul Traina 17214edb46e9SPaul Traina case NFSPROC_REMOVE: 17224edb46e9SPaul Traina case NFSPROC_RMDIR: 1723*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1724*ee67461eSJoseph Mingrone if (dp == NULL) 1725*ee67461eSJoseph Mingrone goto trunc; 1726647f50c3SDoug Rabson if (v3) { 1727*ee67461eSJoseph Mingrone if (parsewccres(ndo, dp, ndo->ndo_vflag, &nfserr) == NULL) 1728*ee67461eSJoseph Mingrone goto trunc; 1729647f50c3SDoug Rabson } else { 1730*ee67461eSJoseph Mingrone if (parsestatus(ndo, dp, &er, &nfserr) == NULL) 1731*ee67461eSJoseph Mingrone goto trunc; 1732647f50c3SDoug Rabson } 1733647f50c3SDoug Rabson break; 1734647f50c3SDoug Rabson 1735647f50c3SDoug Rabson case NFSPROC_RENAME: 1736*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1737*ee67461eSJoseph Mingrone if (dp == NULL) 1738*ee67461eSJoseph Mingrone goto trunc; 1739647f50c3SDoug Rabson if (v3) { 1740*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, &nfserr); 1741*ee67461eSJoseph Mingrone if (dp == NULL) 1742*ee67461eSJoseph Mingrone goto trunc; 17433c602fabSXin LI if (ndo->ndo_vflag) { 1744*ee67461eSJoseph Mingrone ND_PRINT(" from:"); 1745*ee67461eSJoseph Mingrone dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag); 1746*ee67461eSJoseph Mingrone if (dp == NULL) 1747*ee67461eSJoseph Mingrone goto trunc; 1748*ee67461eSJoseph Mingrone ND_PRINT(" to:"); 1749*ee67461eSJoseph Mingrone dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag); 1750*ee67461eSJoseph Mingrone if (dp == NULL) 1751*ee67461eSJoseph Mingrone goto trunc; 1752647f50c3SDoug Rabson } 1753647f50c3SDoug Rabson } else { 1754*ee67461eSJoseph Mingrone if (parsestatus(ndo, dp, &er, &nfserr) == NULL) 1755*ee67461eSJoseph Mingrone goto trunc; 1756647f50c3SDoug Rabson } 1757647f50c3SDoug Rabson break; 1758647f50c3SDoug Rabson 1759647f50c3SDoug Rabson case NFSPROC_LINK: 1760*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1761*ee67461eSJoseph Mingrone if (dp == NULL) 1762*ee67461eSJoseph Mingrone goto trunc; 1763647f50c3SDoug Rabson if (v3) { 1764*ee67461eSJoseph Mingrone dp = parsestatus(ndo, dp, &er, &nfserr); 1765*ee67461eSJoseph Mingrone if (dp == NULL) 1766*ee67461eSJoseph Mingrone goto trunc; 17673c602fabSXin LI if (ndo->ndo_vflag) { 1768*ee67461eSJoseph Mingrone ND_PRINT(" file POST:"); 1769*ee67461eSJoseph Mingrone dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); 1770*ee67461eSJoseph Mingrone if (dp == NULL) 1771*ee67461eSJoseph Mingrone goto trunc; 1772*ee67461eSJoseph Mingrone ND_PRINT(" dir:"); 1773*ee67461eSJoseph Mingrone dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag); 1774*ee67461eSJoseph Mingrone if (dp == NULL) 1775*ee67461eSJoseph Mingrone goto trunc; 1776647f50c3SDoug Rabson } 177739e421e8SCy Schubert return; 1778647f50c3SDoug Rabson } else { 1779*ee67461eSJoseph Mingrone if (parsestatus(ndo, dp, &er, &nfserr) == NULL) 1780*ee67461eSJoseph Mingrone goto trunc; 1781647f50c3SDoug Rabson } 17824edb46e9SPaul Traina break; 17834edb46e9SPaul Traina 17844edb46e9SPaul Traina case NFSPROC_READDIR: 1785*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1786*ee67461eSJoseph Mingrone if (dp == NULL) 1787*ee67461eSJoseph Mingrone goto trunc; 1788647f50c3SDoug Rabson if (v3) { 1789*ee67461eSJoseph Mingrone if (parsev3rddirres(ndo, dp, ndo->ndo_vflag, &nfserr) == NULL) 1790*ee67461eSJoseph Mingrone goto trunc; 1791647f50c3SDoug Rabson } else { 1792*ee67461eSJoseph Mingrone if (parserddires(ndo, dp, &nfserr) == 0) 1793*ee67461eSJoseph Mingrone goto trunc; 1794647f50c3SDoug Rabson } 1795647f50c3SDoug Rabson break; 1796647f50c3SDoug Rabson 1797647f50c3SDoug Rabson case NFSPROC_READDIRPLUS: 1798*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1799*ee67461eSJoseph Mingrone if (dp == NULL) 1800*ee67461eSJoseph Mingrone goto trunc; 1801*ee67461eSJoseph Mingrone if (parsev3rddirres(ndo, dp, ndo->ndo_vflag, &nfserr) == NULL) 1802*ee67461eSJoseph Mingrone goto trunc; 18034edb46e9SPaul Traina break; 18044edb46e9SPaul Traina 1805647f50c3SDoug Rabson case NFSPROC_FSSTAT: 1806*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1807*ee67461eSJoseph Mingrone if (dp == NULL) 1808*ee67461eSJoseph Mingrone goto trunc; 1809*ee67461eSJoseph Mingrone if (parsestatfs(ndo, dp, v3, &nfserr) == 0) 1810*ee67461eSJoseph Mingrone goto trunc; 1811647f50c3SDoug Rabson break; 1812647f50c3SDoug Rabson 1813647f50c3SDoug Rabson case NFSPROC_FSINFO: 1814*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1815*ee67461eSJoseph Mingrone if (dp == NULL) 1816*ee67461eSJoseph Mingrone goto trunc; 1817*ee67461eSJoseph Mingrone if (parsefsinfo(ndo, dp, &nfserr) == 0) 1818*ee67461eSJoseph Mingrone goto trunc; 1819647f50c3SDoug Rabson break; 1820647f50c3SDoug Rabson 1821647f50c3SDoug Rabson case NFSPROC_PATHCONF: 1822*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1823*ee67461eSJoseph Mingrone if (dp == NULL) 1824*ee67461eSJoseph Mingrone goto trunc; 1825*ee67461eSJoseph Mingrone if (parsepathconf(ndo, dp, &nfserr) == 0) 1826*ee67461eSJoseph Mingrone goto trunc; 1827647f50c3SDoug Rabson break; 1828647f50c3SDoug Rabson 1829647f50c3SDoug Rabson case NFSPROC_COMMIT: 1830*ee67461eSJoseph Mingrone dp = parserep(ndo, rp, length, &nfserr); 1831*ee67461eSJoseph Mingrone if (dp == NULL) 1832*ee67461eSJoseph Mingrone goto trunc; 1833*ee67461eSJoseph Mingrone dp = parsewccres(ndo, dp, ndo->ndo_vflag, &nfserr); 1834*ee67461eSJoseph Mingrone if (dp == NULL) 1835*ee67461eSJoseph Mingrone goto trunc; 1836*ee67461eSJoseph Mingrone if (ndo->ndo_vflag > 1) { 1837*ee67461eSJoseph Mingrone /* write-verf-cookie */ 1838*ee67461eSJoseph Mingrone ND_PRINT(" verf %" PRIx64, GET_BE_U_8(dp)); 1839*ee67461eSJoseph Mingrone } 18404edb46e9SPaul Traina break; 18414edb46e9SPaul Traina 18424edb46e9SPaul Traina default: 1843*ee67461eSJoseph Mingrone break; 18444edb46e9SPaul Traina } 1845*ee67461eSJoseph Mingrone return; 1846*ee67461eSJoseph Mingrone 1847647f50c3SDoug Rabson trunc: 18482ebf6c05SBill Fenner if (!nfserr) 1849*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 18504edb46e9SPaul Traina } 1851