From e6daaf2f3adeb2fd7eafdc36aadb5f46b06204c0 Mon Sep 17 00:00:00 2001 From: Seiichi Ikarashi Date: Fri, 10 Nov 2023 18:53:04 +0900 Subject: [PATCH 1/4] NFS: Add a minimum support for NFSv4 tcpdump does not support NFSv4 and prints out wrong NFS data which always be "getattr" for NFSv4, because both NFSv4 COMPOUND procedure and NFSv2/3 GETATTR procedure are the same value '1'. This is a minimum support for NFSv4, which detects NFSv4 and can print out NULL procedure or COMPOUND procedure at least. Log of current no-NFSv4 support: NFS4_OK case 18:03:38.718964 IP client.815 > server.nfs: Flags [P.], seq 192:312, ack 177, win 22430, options [nop,nop,TS val 2190058497 ecr 3789310763], length 120: NFS request xid 1660218411 116 getattr fh 0,1/53 18:03:38.719279 IP server.nfs > client.815: Flags [P.], seq 177:261, ack 312, win 3333, options [nop,nop,TS val 3789310764 ecr 2190058497], length 84: NFS reply xid 1660218411 reply ok 80 getattr NON 1 ids 0/159 sz -719751424 NFS4ERR_NOENT case 18:03:44.707900 IP client.815 > server.nfs: Flags [P.], seq 312:512, ack 261, win 22430, options [nop,nop,TS val 2190064486 ecr 3789310864], length 200: NFS request xid 1676995627 196 getattr fh 0,1/53 18:03:44.708575 IP server.nfs > client.815: Flags [P.], seq 261:361, ack 512, win 3333, options [nop,nop,TS val 3789316753 ecr 2190064486], length 100: NFS reply xid 1676995627 reply ok 96 getattr ERROR: No such file or directory Log of this minimum NFSv4 support: NFS4_OK case 18:06:18.975026 IP client.815 > server.nfs: Flags [P.], seq 488:608, ack 549, win 22430, options [nop,nop,TS val 2190218753 ecr 3789464067], length 120: NFS request xid 1861545003 116 v4 compound 18:06:18.975276 IP server.nfs > client.815: Flags [P.], seq 549:633, ack 608, win 3333, options [nop,nop,TS val 3789471020 ecr 2190218753], length 84: NFS reply xid 1861545003 reply ok 80 v4 compound NFS4ERR_NOENT case 17:51:08.684565 IP client.815 > server.nfs: Flags [P.], seq 432:632, ack 345, win 22430, options [nop,nop,TS val 2189308462 ecr 3788560729], length 200: NFS request xid 888466475 196 v4 compound 17:51:08.685081 IP server.nfs > client.815: Flags [P.], seq 345:445, ack 632, win 3333, options [nop,nop,TS val 3788560730 ecr 2189308462], length 100: NFS reply xid 888466475 reply ok 96 v4 compound ERROR: No such file or directory Signed-off-by: Seiichi Ikarashi --- nfs.h | 1 + print-nfs.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/nfs.h b/nfs.h index 87ba1a718..e13c83e49 100644 --- a/nfs.h +++ b/nfs.h @@ -53,6 +53,7 @@ #define NFS_PROG 100003 #define NFS_VER2 2 #define NFS_VER3 3 +#define NFS_VER4 4 #define NFS_V2MAXDATA 8192 #define NFS_MAXDGRAMDATA 16384 #define NFS_MAXDATA 32768 diff --git a/print-nfs.c b/print-nfs.c index bbce49536..4a8159ab3 100644 --- a/print-nfs.c +++ b/print-nfs.c @@ -571,6 +571,19 @@ nfsreq_noaddr_print(netdissect_options *ndo, v3 = (GET_BE_U_4(&rp->rm_call.cb_vers) == NFS_VER3); proc = GET_BE_U_4(&rp->rm_call.cb_proc); + if (GET_BE_U_4(&rp->rm_call.cb_vers) == NFS_VER4) { + ND_PRINT(" v4"); + switch (proc) { + case 0: + ND_PRINT(" null"); + break; + case 1: + ND_PRINT(" compound"); + break; + } + return; + } + if (!v3 && proc < NFS_NPROCS) proc = nfsv3_procid[proc]; @@ -1539,6 +1552,25 @@ interp_reply(netdissect_options *ndo, u_int er; int nfserr = 0; + if (vers == NFS_VER4) { + ND_PRINT(" v4"); + switch (proc) { + case 0: + ND_PRINT(" null"); + break; + case 1: + ND_PRINT(" compound"); + break; + } + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; + dp = parsestatus(ndo, dp, &er, &nfserr); + if (dp == NULL) + goto trunc; + return; + } + v3 = (vers == NFS_VER3); if (!v3 && proc < NFS_NPROCS) From 893e7b15b4dae2e17051e8f04a62d82945319efb Mon Sep 17 00:00:00 2001 From: Seiichi Ikarashi Date: Fri, 5 Jan 2024 18:29:52 +0900 Subject: [PATCH 2/4] NFS: Add a NFSv4 test A test for NFSv4 support. Signed-off-by: Seiichi Ikarashi --- tests/TESTLIST | 3 +++ tests/nfs-v4.out | 6 ++++++ tests/nfs-v4.pcap | Bin 0 -> 1164 bytes 3 files changed, 9 insertions(+) create mode 100644 tests/nfs-v4.out create mode 100644 tests/nfs-v4.pcap diff --git a/tests/TESTLIST b/tests/TESTLIST index f03e2250f..11c92b49a 100644 --- a/tests/TESTLIST +++ b/tests/TESTLIST @@ -837,6 +837,9 @@ nfs-seg-fault-1 nfs-seg-fault-1.pcapng nfs-seg-fault-1.out # NFS invalid nfs-cannot-pad-32-bit nfs-cannot-pad-32-bit.pcap nfs-cannot-pad-32-bit.out +# NFSv4 support +nfs-v4 nfs-v4.pcap nfs-v4.out + # DNS infinite loop tests # # See http://marc.info/?l=tcpdump-workers&m=95552439022555 diff --git a/tests/nfs-v4.out b/tests/nfs-v4.out new file mode 100644 index 000000000..5982c7a11 --- /dev/null +++ b/tests/nfs-v4.out @@ -0,0 +1,6 @@ + 1 08:48:53.854625 IP 192.168.200.177.671 > 192.168.200.1.2049: Flags [P.], seq 1022539785:1022539969, ack 556520858, win 1592, options [nop,nop,TS val 1549792688 ecr 1201363416], length 184: NFS request xid 1209063269 180 v4 compound + 2 08:48:53.855103 IP 192.168.200.1.2049 > 192.168.200.177.671: Flags [P.], seq 1:173, ack 184, win 1064, options [nop,nop,TS val 1201382193 ecr 1549792688], length 172: NFS reply xid 1209063269 reply ok 168 v4 compound + 3 08:48:53.855178 IP 192.168.200.177.671 > 192.168.200.1.2049: Flags [.], ack 173, win 1615, options [nop,nop,TS val 1549792689 ecr 1201382193], length 0 + 4 08:48:53.855490 IP 192.168.200.177.671 > 192.168.200.1.2049: Flags [P.], seq 184:376, ack 173, win 1615, options [nop,nop,TS val 1549792689 ecr 1201382193], length 192: NFS request xid 1225840485 188 v4 compound + 5 08:48:53.855747 IP 192.168.200.1.2049 > 192.168.200.177.671: Flags [P.], seq 173:273, ack 376, win 1078, options [nop,nop,TS val 1201382194 ecr 1549792689], length 100: NFS reply xid 1225840485 reply ok 96 v4 compound ERROR: No such file or directory + 6 08:48:53.896607 IP 192.168.200.177.671 > 192.168.200.1.2049: Flags [.], ack 273, win 1615, options [nop,nop,TS val 1549792730 ecr 1201382194], length 0 diff --git a/tests/nfs-v4.pcap b/tests/nfs-v4.pcap new file mode 100644 index 0000000000000000000000000000000000000000..e744b6ac4b481df6be3ce3b499328e99098f9662 GIT binary patch literal 1164 zcmb_aJxE(o82#>R8e{O;@P_gzLUoV`Az%|@tq2vtSP?8pmx2&$c|$>n5gf$jIVdRp zfF0WEAT}W4Af`A(aA=f*PA;vALJ?eq28Y-#y7--UO*HW#4n1)0`|fx1zWdI}`MLRR zULglv!$E>K{TrW*cW#x=xduDlP)97m>(-A^7c~>5ljDul=!_12U))MCg)-+74Vh$d zh40slsXObmV+u zBwD<3!cG<6VZl;{>JD}IQV@Vb04e||$*RFVr-b1UTHpgvx+{IL zJpSyjg(DZ0`3c(%H)Pg^IAOKgR4!ow_-qn&T{&WxFeCv$QbH(f5|&kImoQ5WzB;me YXELU&WK`$>k84AmjHQBP9B?uMm+4CIhX4Qo literal 0 HcmV?d00001 From ab18945ac66a814fc8fa754fd91c5e152306ac8b Mon Sep 17 00:00:00 2001 From: Seiichi Ikarashi Date: Thu, 15 Feb 2024 18:39:07 +0900 Subject: [PATCH 3/4] Add NFSv4 error support Support NFSv4 errors, and update "nfs-v4" test case to include NFSv4 NULL procedure. --- nfs.h | 124 ++++++++++++++++++++++++++++++++ print-nfs.c | 177 ++++++++++++++++++++++++++++++++++++++++------ tests/nfs-v4.out | 12 ++-- tests/nfs-v4.pcap | Bin 1164 -> 1392 bytes 4 files changed, 284 insertions(+), 29 deletions(-) diff --git a/nfs.h b/nfs.h index e13c83e49..c90d17077 100644 --- a/nfs.h +++ b/nfs.h @@ -416,3 +416,127 @@ struct nfsv3_pathconf { nd_uint32_t pc_caseinsensitive; nd_uint32_t pc_casepreserving; }; + +/* + * nfs definitions as per the Version 4 specs + */ + +#define NFSV4PROC_NULL 0 +#define NFSV4PROC_COMPOUND 1 + +/* RFC 7530 NFSv4 */ +#define NFS4_OK 0 +#define NFS4ERR_PERM 1 +#define NFS4ERR_NOENT 2 +#define NFS4ERR_IO 5 +#define NFS4ERR_NXIO 6 +#define NFS4ERR_ACCESS 13 +#define NFS4ERR_EXIST 17 +#define NFS4ERR_XDEV 18 +#define NFS4ERR_NOTDIR 20 +#define NFS4ERR_ISDIR 21 +#define NFS4ERR_INVAL 22 +#define NFS4ERR_FBIG 27 +#define NFS4ERR_NOSPC 28 +#define NFS4ERR_ROFS 30 +#define NFS4ERR_MLINK 31 +#define NFS4ERR_NAMETOOLONG 63 +#define NFS4ERR_NOTEMPTY 66 +#define NFS4ERR_DQUOT 69 +#define NFS4ERR_STALE 70 +#define NFS4ERR_BADHANDLE 10001 +#define NFS4ERR_BAD_COOKIE 10003 +#define NFS4ERR_NOTSUPP 10004 +#define NFS4ERR_TOOSMALL 10005 +#define NFS4ERR_SERVERFAULT 10006 +#define NFS4ERR_BADTYPE 10007 +#define NFS4ERR_DELAY 10008 +#define NFS4ERR_SAME 10009 +#define NFS4ERR_DENIED 10010 +#define NFS4ERR_EXPIRED 10011 +#define NFS4ERR_LOCKED 10012 +#define NFS4ERR_GRACE 10013 +#define NFS4ERR_FHEXPIRED 10014 +#define NFS4ERR_SHARE_DENIED 10015 +#define NFS4ERR_WRONGSEC 10016 +#define NFS4ERR_CLID_INUSE 10017 +#define NFS4ERR_RESOURCE 10018 +#define NFS4ERR_MOVED 10019 +#define NFS4ERR_NOFILEHANDLE 10020 +#define NFS4ERR_MINOR_VERS_MISMATCH 10021 +#define NFS4ERR_STALE_CLIENTID 10022 +#define NFS4ERR_STALE_STATEID 10023 +#define NFS4ERR_OLD_STATEID 10024 +#define NFS4ERR_BAD_STATEID 10025 +#define NFS4ERR_BAD_SEQID 10026 +#define NFS4ERR_NOT_SAME 10027 +#define NFS4ERR_LOCK_RANGE 10028 +#define NFS4ERR_SYMLINK 10029 +#define NFS4ERR_RESTOREFH 10030 +#define NFS4ERR_LEASE_MOVED 10031 +#define NFS4ERR_ATTRNOTSUPP 10032 +#define NFS4ERR_NO_GRACE 10033 +#define NFS4ERR_RECLAIM_BAD 10034 +#define NFS4ERR_RECLAIM_CONFLICT 10035 +#define NFS4ERR_BADXDR 10036 +#define NFS4ERR_LOCKS_HELD 10037 +#define NFS4ERR_OPENMODE 10038 +#define NFS4ERR_BADOWNER 10039 +#define NFS4ERR_BADCHAR 10040 +#define NFS4ERR_BADNAME 10041 +#define NFS4ERR_BAD_RANGE 10042 +#define NFS4ERR_LOCK_NOTSUPP 10043 +#define NFS4ERR_OP_ILLEGAL 10044 +#define NFS4ERR_DEADLOCK 10045 +#define NFS4ERR_FILE_OPEN 10046 +#define NFS4ERR_ADMIN_REVOKED 10047 +#define NFS4ERR_CB_PATH_DOWN 10048 + +/* RFC 8881 NFSv4.1 */ +#define NFS4ERR_BADIOMODE 10049 +#define NFS4ERR_BADLAYOUT 10050 +#define NFS4ERR_BAD_SESSION_DIGEST 10051 +#define NFS4ERR_BADSESSION 10052 +#define NFS4ERR_BADSLOT 10053 +#define NFS4ERR_COMPLETE_ALREADY 10054 +#define NFS4ERR_CONN_NOT_BOUND_TO_SESSION 10055 +#define NFS4ERR_DELEG_ALREADY_WANTED 10056 +#define NFS4ERR_BACK_CHAN_BUSY 10057 +#define NFS4ERR_LAYOUTTRYLATER 10058 +#define NFS4ERR_LAYOUTUNAVAILABLE 10059 +#define NFS4ERR_NOMATCHING_LAYOUT 10060 +#define NFS4ERR_RECALLCONFLICT 10061 +#define NFS4ERR_UNKNOWN_LAYOUTTYPE 10062 +#define NFS4ERR_SEQ_MISORDERED 10063 +#define NFS4ERR_SEQUENCE_POS 10064 +#define NFS4ERR_REQ_TOO_BIG 10065 +#define NFS4ERR_REP_TOO_BIG 10066 +#define NFS4ERR_REP_TOO_BIG_TO_CACHE 10067 +#define NFS4ERR_RETRY_UNCACHED_REP 10068 +#define NFS4ERR_UNSAFE_COMPOUND 10069 +#define NFS4ERR_TOO_MANY_OPS 10070 +#define NFS4ERR_OP_NOT_IN_SESSION 10071 +#define NFS4ERR_HASH_ALG_UNSUPP 10072 +#define NFS4ERR_CLIENTID_BUSY 10074 +#define NFS4ERR_PNFS_IO_HOLE 10075 +#define NFS4ERR_SEQ_FALSE_RETRY 10076 +#define NFS4ERR_BAD_HIGH_SLOT 10077 +#define NFS4ERR_DEADSESSION 10078 +#define NFS4ERR_ENCR_ALG_UNSUPP 10079 +#define NFS4ERR_PNFS_NO_LAYOUT 10080 +#define NFS4ERR_NOT_ONLY_OP 10081 +#define NFS4ERR_WRONG_CRED 10082 +#define NFS4ERR_WRONG_TYPE 10083 +#define NFS4ERR_DIRDELEG_UNAVAIL 10084 +#define NFS4ERR_REJECT_DELEG 10085 +#define NFS4ERR_RETURNCONFLICT 10086 +#define NFS4ERR_DELEG_REVOKED 10087 + +/* RFC 7862 NFSv4.2 */ +#define NFS4ERR_PARTNER_NOTSUPP 10088 +#define NFS4ERR_PARTNER_NO_AUTH 10089 +#define NFS4ERR_UNION_NOTSUPP 10090 +#define NFS4ERR_OFFLOAD_DENIED 10091 +#define NFS4ERR_WRONG_LFS 10092 +#define NFS4ERR_BADLABEL 10093 +#define NFS4ERR_OFFLOAD_NO_REQS 10094 diff --git a/print-nfs.c b/print-nfs.c index 4a8159ab3..e5c510aa3 100644 --- a/print-nfs.c +++ b/print-nfs.c @@ -50,6 +50,133 @@ static int xid_map_find(netdissect_options *, const struct sunrpc_msg *, const u static void interp_reply(netdissect_options *, const struct sunrpc_msg *, uint32_t, uint32_t, int); static const uint32_t *parse_post_op_attr(netdissect_options *, const uint32_t *, int); +/* + * NFS Version 4 Procedures. + */ +static const struct tok nfsv4proc_str[] = { + { NFSV4PROC_NULL, "null" }, + { NFSV4PROC_COMPOUND, "compound" }, + { 0, NULL } +}; + +static const struct tok status2strv4[] = { + /* RFC 7530 NFSv4 */ + { NFS4_OK, "NFS4_OK" }, + { NFS4ERR_PERM, "NFS4ERR_PERM" }, + { NFS4ERR_NOENT, "NFS4ERR_NOENT" }, + { NFS4ERR_IO, "NFS4ERR_IO" }, + { NFS4ERR_NXIO, "NFS4ERR_NXIO" }, + { NFS4ERR_ACCESS, "NFS4ERR_ACCESS" }, + { NFS4ERR_EXIST, "NFS4ERR_EXIST" }, + { NFS4ERR_XDEV, "NFS4ERR_XDEV" }, + { NFS4ERR_NOTDIR, "NFS4ERR_NOTDIR" }, + { NFS4ERR_ISDIR, "NFS4ERR_ISDIR" }, + { NFS4ERR_INVAL, "NFS4ERR_INVAL" }, + { NFS4ERR_FBIG, "NFS4ERR_FBIG" }, + { NFS4ERR_NOSPC, "NFS4ERR_NOSPC" }, + { NFS4ERR_ROFS, "NFS4ERR_ROFS" }, + { NFS4ERR_MLINK, "NFS4ERR_MLINK" }, + { NFS4ERR_NAMETOOLONG, "NFS4ERR_NAMETOOLONG" }, + { NFS4ERR_NOTEMPTY, "NFS4ERR_NOTEMPTY" }, + { NFS4ERR_DQUOT, "NFS4ERR_DQUOT" }, + { NFS4ERR_STALE, "NFS4ERR_STALE" }, + { NFS4ERR_BADHANDLE, "NFS4ERR_BADHANDLE" }, + { NFS4ERR_BAD_COOKIE, "NFS4ERR_BAD_COOKIE" }, + { NFS4ERR_NOTSUPP, "NFS4ERR_NOTSUPP" }, + { NFS4ERR_TOOSMALL, "NFS4ERR_TOOSMALL" }, + { NFS4ERR_SERVERFAULT, "NFS4ERR_SERVERFAULT" }, + { NFS4ERR_BADTYPE, "NFS4ERR_BADTYPE" }, + { NFS4ERR_DELAY, "NFS4ERR_DELAY" }, + { NFS4ERR_SAME, "NFS4ERR_SAME" }, + { NFS4ERR_DENIED, "NFS4ERR_DENIED" }, + { NFS4ERR_EXPIRED, "NFS4ERR_EXPIRED" }, + { NFS4ERR_LOCKED, "NFS4ERR_LOCKED" }, + { NFS4ERR_GRACE, "NFS4ERR_GRACE" }, + { NFS4ERR_FHEXPIRED, "NFS4ERR_FHEXPIRED" }, + { NFS4ERR_SHARE_DENIED, "NFS4ERR_SHARE_DENIED" }, + { NFS4ERR_WRONGSEC, "NFS4ERR_WRONGSEC" }, + { NFS4ERR_CLID_INUSE, "NFS4ERR_CLID_INUSE" }, + { NFS4ERR_RESOURCE, "NFS4ERR_RESOURCE" }, + { NFS4ERR_MOVED, "NFS4ERR_MOVED" }, + { NFS4ERR_NOFILEHANDLE, "NFS4ERR_NOFILEHANDLE" }, + { NFS4ERR_MINOR_VERS_MISMATCH, "NFS4ERR_MINOR_VERS_MISMATCH" }, + { NFS4ERR_STALE_CLIENTID, "NFS4ERR_STALE_CLIENTID" }, + { NFS4ERR_STALE_STATEID, "NFS4ERR_STALE_STATEID" }, + { NFS4ERR_OLD_STATEID, "NFS4ERR_OLD_STATEID" }, + { NFS4ERR_BAD_STATEID, "NFS4ERR_BAD_STATEID" }, + { NFS4ERR_BAD_SEQID, "NFS4ERR_BAD_SEQID" }, + { NFS4ERR_NOT_SAME, "NFS4ERR_NOT_SAME" }, + { NFS4ERR_LOCK_RANGE, "NFS4ERR_LOCK_RANGE" }, + { NFS4ERR_SYMLINK, "NFS4ERR_SYMLINK" }, + { NFS4ERR_RESTOREFH, "NFS4ERR_RESTOREFH" }, + { NFS4ERR_LEASE_MOVED, "NFS4ERR_LEASE_MOVED" }, + { NFS4ERR_ATTRNOTSUPP, "NFS4ERR_ATTRNOTSUPP" }, + { NFS4ERR_NO_GRACE, "NFS4ERR_NO_GRACE" }, + { NFS4ERR_RECLAIM_BAD, "NFS4ERR_RECLAIM_BAD" }, + { NFS4ERR_RECLAIM_CONFLICT, "NFS4ERR_RECLAIM_CONFLICT" }, + { NFS4ERR_BADXDR, "NFS4ERR_BADXDR" }, + { NFS4ERR_LOCKS_HELD, "NFS4ERR_LOCKS_HELD" }, + { NFS4ERR_OPENMODE, "NFS4ERR_OPENMODE" }, + { NFS4ERR_BADOWNER, "NFS4ERR_BADOWNER" }, + { NFS4ERR_BADCHAR, "NFS4ERR_BADCHAR" }, + { NFS4ERR_BADNAME, "NFS4ERR_BADNAME" }, + { NFS4ERR_BAD_RANGE, "NFS4ERR_BAD_RANGE" }, + { NFS4ERR_LOCK_NOTSUPP, "NFS4ERR_LOCK_NOTSUPP" }, + { NFS4ERR_OP_ILLEGAL, "NFS4ERR_OP_ILLEGAL" }, + { NFS4ERR_DEADLOCK, "NFS4ERR_DEADLOCK" }, + { NFS4ERR_FILE_OPEN, "NFS4ERR_FILE_OPEN" }, + { NFS4ERR_ADMIN_REVOKED, "NFS4ERR_ADMIN_REVOKED" }, + { NFS4ERR_CB_PATH_DOWN, "NFS4ERR_CB_PATH_DOWN" }, + /* RFC 8881 NFSv4.1 */ + { NFS4ERR_BADIOMODE, "NFS4ERR_BADIOMODE" }, + { NFS4ERR_BADLAYOUT, "NFS4ERR_BADLAYOUT" }, + { NFS4ERR_BAD_SESSION_DIGEST, "NFS4ERR_BAD_SESSION_DIGEST" }, + { NFS4ERR_BADSESSION, "NFS4ERR_BADSESSION" }, + { NFS4ERR_BADSLOT, "NFS4ERR_BADSLOT" }, + { NFS4ERR_COMPLETE_ALREADY, "NFS4ERR_COMPLETE_ALREADY" }, + { NFS4ERR_CONN_NOT_BOUND_TO_SESSION, "NFS4ERR_CONN_NOT_BOUND_TO_SESSION" }, + { NFS4ERR_DELEG_ALREADY_WANTED, "NFS4ERR_DELEG_ALREADY_WANTED" }, + { NFS4ERR_BACK_CHAN_BUSY, "NFS4ERR_BACK_CHAN_BUSY" }, + { NFS4ERR_LAYOUTTRYLATER, "NFS4ERR_LAYOUTTRYLATER" }, + { NFS4ERR_LAYOUTUNAVAILABLE, "NFS4ERR_LAYOUTUNAVAILABLE" }, + { NFS4ERR_NOMATCHING_LAYOUT, "NFS4ERR_NOMATCHING_LAYOUT" }, + { NFS4ERR_RECALLCONFLICT, "NFS4ERR_RECALLCONFLICT" }, + { NFS4ERR_UNKNOWN_LAYOUTTYPE, "NFS4ERR_UNKNOWN_LAYOUTTYPE" }, + { NFS4ERR_SEQ_MISORDERED, "NFS4ERR_SEQ_MISORDERED" }, + { NFS4ERR_SEQUENCE_POS, "NFS4ERR_SEQUENCE_POS" }, + { NFS4ERR_REQ_TOO_BIG, "NFS4ERR_REQ_TOO_BIG" }, + { NFS4ERR_REP_TOO_BIG, "NFS4ERR_REP_TOO_BIG" }, + { NFS4ERR_REP_TOO_BIG_TO_CACHE, "NFS4ERR_REP_TOO_BIG_TO_CACHE" }, + { NFS4ERR_RETRY_UNCACHED_REP, "NFS4ERR_RETRY_UNCACHED_REP" }, + { NFS4ERR_UNSAFE_COMPOUND, "NFS4ERR_UNSAFE_COMPOUND" }, + { NFS4ERR_TOO_MANY_OPS, "NFS4ERR_TOO_MANY_OPS" }, + { NFS4ERR_OP_NOT_IN_SESSION, "NFS4ERR_OP_NOT_IN_SESSION" }, + { NFS4ERR_HASH_ALG_UNSUPP, "NFS4ERR_HASH_ALG_UNSUPP" }, + { NFS4ERR_CLIENTID_BUSY, "NFS4ERR_CLIENTID_BUSY" }, + { NFS4ERR_PNFS_IO_HOLE, "NFS4ERR_PNFS_IO_HOLE" }, + { NFS4ERR_SEQ_FALSE_RETRY, "NFS4ERR_SEQ_FALSE_RETRY" }, + { NFS4ERR_BAD_HIGH_SLOT, "NFS4ERR_BAD_HIGH_SLOT" }, + { NFS4ERR_DEADSESSION, "NFS4ERR_DEADSESSION" }, + { NFS4ERR_ENCR_ALG_UNSUPP, "NFS4ERR_ENCR_ALG_UNSUPP" }, + { NFS4ERR_PNFS_NO_LAYOUT, "NFS4ERR_PNFS_NO_LAYOUT" }, + { NFS4ERR_NOT_ONLY_OP, "NFS4ERR_NOT_ONLY_OP" }, + { NFS4ERR_WRONG_CRED, "NFS4ERR_WRONG_CRED" }, + { NFS4ERR_WRONG_TYPE, "NFS4ERR_WRONG_TYPE" }, + { NFS4ERR_DIRDELEG_UNAVAIL, "NFS4ERR_DIRDELEG_UNAVAIL" }, + { NFS4ERR_REJECT_DELEG, "NFS4ERR_REJECT_DELEG" }, + { NFS4ERR_RETURNCONFLICT, "NFS4ERR_RETURNCONFLICT" }, + { NFS4ERR_DELEG_REVOKED, "NFS4ERR_DELEG_REVOKED" }, + /* RFC 7862 NFSv4.2 */ + { NFS4ERR_PARTNER_NOTSUPP, "NFS4ERR_PARTNER_NOTSUPP" }, + { NFS4ERR_PARTNER_NO_AUTH, "NFS4ERR_PARTNER_NO_AUTH" }, + { NFS4ERR_UNION_NOTSUPP, "NFS4ERR_UNION_NOTSUPP" }, + { NFS4ERR_OFFLOAD_DENIED, "NFS4ERR_OFFLOAD_DENIED" }, + { NFS4ERR_WRONG_LFS, "NFS4ERR_WRONG_LFS" }, + { NFS4ERR_BADLABEL, "NFS4ERR_BADLABEL" }, + { NFS4ERR_OFFLOAD_NO_REQS, "NFS4ERR_OFFLOAD_NO_REQS" }, + { 0, NULL } +}; + /* * Mapping of old NFS Version 2 RPC numbers to generic numbers. */ @@ -572,15 +699,7 @@ nfsreq_noaddr_print(netdissect_options *ndo, proc = GET_BE_U_4(&rp->rm_call.cb_proc); if (GET_BE_U_4(&rp->rm_call.cb_vers) == NFS_VER4) { - ND_PRINT(" v4"); - switch (proc) { - case 0: - ND_PRINT(" null"); - break; - case 1: - ND_PRINT(" compound"); - break; - } + ND_PRINT(" v4 %s", tok2str(nfsv4proc_str, "proc-%u", proc)); return; } @@ -1131,6 +1250,24 @@ parsestatus(netdissect_options *ndo, return (dp + 1); } +static const uint32_t * +parsestatusv4(netdissect_options *ndo, + const uint32_t *dp, u_int *er, int *nfserrp) +{ + u_int errnum; + + errnum = GET_BE_U_4(dp); + if (er) + *er = errnum; + if (errnum != NFS4_OK) { + if (!ndo->ndo_qflag) + ND_PRINT(" ERROR: %s", + tok2str(status2strv4, "unk %u", errnum)); + *nfserrp = 1; + } + return (dp + 1); +} + static const uint32_t * parsefattr(netdissect_options *ndo, const uint32_t *dp, int verbose, int v3) @@ -1553,21 +1690,15 @@ interp_reply(netdissect_options *ndo, int nfserr = 0; if (vers == NFS_VER4) { - ND_PRINT(" v4"); - switch (proc) { - case 0: - ND_PRINT(" null"); - break; - case 1: - ND_PRINT(" compound"); - break; + ND_PRINT(" v4 %s", tok2str(nfsv4proc_str, "proc-%u", proc)); + if (proc == NFSV4PROC_COMPOUND) { + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; + dp = parsestatusv4(ndo, dp, &er, &nfserr); + if (dp == NULL) + goto trunc; } - dp = parserep(ndo, rp, length, &nfserr); - if (dp == NULL) - goto trunc; - dp = parsestatus(ndo, dp, &er, &nfserr); - if (dp == NULL) - goto trunc; return; } diff --git a/tests/nfs-v4.out b/tests/nfs-v4.out index 5982c7a11..4fb336b04 100644 --- a/tests/nfs-v4.out +++ b/tests/nfs-v4.out @@ -1,6 +1,6 @@ - 1 08:48:53.854625 IP 192.168.200.177.671 > 192.168.200.1.2049: Flags [P.], seq 1022539785:1022539969, ack 556520858, win 1592, options [nop,nop,TS val 1549792688 ecr 1201363416], length 184: NFS request xid 1209063269 180 v4 compound - 2 08:48:53.855103 IP 192.168.200.1.2049 > 192.168.200.177.671: Flags [P.], seq 1:173, ack 184, win 1064, options [nop,nop,TS val 1201382193 ecr 1549792688], length 172: NFS reply xid 1209063269 reply ok 168 v4 compound - 3 08:48:53.855178 IP 192.168.200.177.671 > 192.168.200.1.2049: Flags [.], ack 173, win 1615, options [nop,nop,TS val 1549792689 ecr 1201382193], length 0 - 4 08:48:53.855490 IP 192.168.200.177.671 > 192.168.200.1.2049: Flags [P.], seq 184:376, ack 173, win 1615, options [nop,nop,TS val 1549792689 ecr 1201382193], length 192: NFS request xid 1225840485 188 v4 compound - 5 08:48:53.855747 IP 192.168.200.1.2049 > 192.168.200.177.671: Flags [P.], seq 173:273, ack 376, win 1078, options [nop,nop,TS val 1201382194 ecr 1549792689], length 100: NFS reply xid 1225840485 reply ok 96 v4 compound ERROR: No such file or directory - 6 08:48:53.896607 IP 192.168.200.177.671 > 192.168.200.1.2049: Flags [.], ack 273, win 1615, options [nop,nop,TS val 1549792730 ecr 1201382194], length 0 + 1 06:39:25.778133 IP 192.168.200.198.857 > 192.168.200.1.2049: Flags [P.], seq 3806116338:3806116382, ack 3240065782, win 229, options [nop,nop,TS val 190691472 ecr 193176172], length 44: NFS request xid 1710309038 40 v4 null + 2 06:39:25.778431 IP 192.168.200.1.2049 > 192.168.200.198.857: Flags [P.], seq 1:29, ack 44, win 227, options [nop,nop,TS val 193176172 ecr 190691472], length 28: NFS reply xid 1710309038 reply ok 24 v4 null + 3 06:39:25.778791 IP 192.168.200.198.857 > 192.168.200.1.2049: Flags [P.], seq 44:284, ack 29, win 229, options [nop,nop,TS val 190691473 ecr 193176172], length 240: NFS request xid 1727086254 236 v4 compound + 4 06:39:25.778965 IP 192.168.200.1.2049 > 192.168.200.198.857: Flags [P.], seq 29:133, ack 284, win 235, options [nop,nop,TS val 193176173 ecr 190691473], length 104: NFS reply xid 1727086254 reply ok 100 v4 compound + 5 06:39:35.254619 IP 192.168.200.198.857 > 192.168.200.1.2049: Flags [P.], seq 3584:3776, ack 3801, win 371, options [nop,nop,TS val 190700949 ecr 193185649], length 192: NFS request xid 2079407790 188 v4 compound + 6 06:39:35.254792 IP 192.168.200.1.2049 > 192.168.200.198.857: Flags [P.], seq 3801:3901, ack 3776, win 411, options [nop,nop,TS val 193185649 ecr 190700949], length 100: NFS reply xid 2079407790 reply ok 96 v4 compound ERROR: NFS4ERR_NOENT diff --git a/tests/nfs-v4.pcap b/tests/nfs-v4.pcap index e744b6ac4b481df6be3ce3b499328e99098f9662..fa7128bd10f80250001f9388bf73f53f462ae75f 100644 GIT binary patch literal 1392 zcmaJ>OGs2<6h8l`<2aL9V}*$5g(So1GIw&uvIrMVi&7IEf-+Oln~Br->V|2H3qs%` z&`Jn&Wg*g{=cX(|D;krqRp4TTm@x=)(}OlGrt{soqmGIP&i|it{?~WDbMCcgX4*@L zsPfo>T)}h9lvK(hUrXE7=B7?bkrkJ$U>6Za?32tn79+~wh?RYa#0q!s8KYRQ@OP$Z+dd}1FJ|mXA_a|%U?4EeSh^F`sNJqi^67i z)V~;V42%bKqW$X6`#h%_-i84SLpS^sGEK0dOk#y@fb)?O=-6)ACxz+MPud%M~lR0DEHcdHSrh@Uxx-ft0$3n*6P}>RnxHc@R%nk zov!nDg2?UD%i`ldU*oN>pG&K@6@BLrjtevzi=8!t)j~T&Eq0RMj_AP*b> literal 1164 zcmb_aJxE(o82#>R8e{O;@P_gzLUoV`Az%|@tq2vtSP?8pmx2&$c|$>n5gf$jIVdRp zfF0WEAT}W4Af`A(aA=f*PA;vALJ?eq28Y-#y7--UO*HW#4n1)0`|fx1zWdI}`MLRR zULglv!$E>K{TrW*cW#x=xduDlP)97m>(-A^7c~>5ljDul=!_12U))MCg)-+74Vh$d zh40slsXObmV+u zBwD<3!cG<6VZl;{>JD}IQV@Vb04e||$*RFVr-b1UTHpgvx+{IL zJpSyjg(DZ0`3c(%H)Pg^IAOKgR4!ow_-qn&T{&WxFeCv$QbH(f5|&kImoQ5WzB;me YXELU&WK`$>k84AmjHQBP9B?uMm+4CIhX4Qo From 11a41ae5ef4c9d10b5e6d1364f8ed69ad7b2fdc5 Mon Sep 17 00:00:00 2001 From: Seiichi Ikarashi Date: Fri, 16 Feb 2024 17:18:04 +0900 Subject: [PATCH 4/4] NFS: Show NFSv4 minor version and numops from the COMPOUND request Add support for showing NFSv4 minor version and numops from the COMPOUND request. Also fix some tab-indent bug in interp_reply(). --- print-nfs.c | 62 ++++++++++++++++++++++++++++++++++++++++++------ tests/nfs-v4.out | 4 ++-- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/print-nfs.c b/print-nfs.c index e5c510aa3..a3fe04c92 100644 --- a/print-nfs.c +++ b/print-nfs.c @@ -675,6 +675,46 @@ parsefhn(netdissect_options *ndo, return (parsefn(ndo, dp)); } +/* + * Print out the contents of an NFSv4 compound procedure. + * If packet was truncated, return 0. + */ +static const uint32_t * +parsecmp(netdissect_options *ndo, + const uint32_t *dp, uint32_t proc) +{ + uint32_t tag_length; + uint32_t minorversion; + uint32_t numops; + + if (!ND_TTEST_LEN(dp, 4)) + goto notag; + tag_length = GET_BE_U_4(dp++); + if (tag_length > 0) { + if (!ND_TTEST_LEN(dp, roundup2(tag_length + 1, 4))) + goto notag; + dp += (tag_length + 3) / sizeof(*dp); + } + + if (!ND_TTEST_LEN(dp, 4)) + goto nominorv; + minorversion = GET_BE_U_4(dp++); + + if (!ND_TTEST_LEN(dp, 4)) + goto nonumops; + numops = GET_BE_U_4(dp++); + + ND_PRINT(" v4.%d %s ops %d", minorversion, tok2str(nfsv4proc_str, "proc-%u", proc), numops); + return (dp); +nonumops: + ND_PRINT(" v4.%d %s", minorversion, tok2str(nfsv4proc_str, "proc-%u", proc)); + return (NULL); +notag: +nominorv: + ND_PRINT(" v4 %s", tok2str(nfsv4proc_str, "proc-%u", proc)); + return (NULL); +} + void nfsreq_noaddr_print(netdissect_options *ndo, const u_char *bp, u_int length, @@ -699,7 +739,15 @@ nfsreq_noaddr_print(netdissect_options *ndo, proc = GET_BE_U_4(&rp->rm_call.cb_proc); if (GET_BE_U_4(&rp->rm_call.cb_vers) == NFS_VER4) { - ND_PRINT(" v4 %s", tok2str(nfsv4proc_str, "proc-%u", proc)); + if (proc == NFSV4PROC_COMPOUND) { + dp = parsereq(ndo, rp, length); + if (dp == NULL) + goto trunc; + if (parsecmp(ndo, dp, proc) == NULL) + goto trunc; + } else { + ND_PRINT(" v4 %s", tok2str(nfsv4proc_str, "proc-%u", proc)); + } return; } @@ -1692,12 +1740,12 @@ interp_reply(netdissect_options *ndo, if (vers == NFS_VER4) { ND_PRINT(" v4 %s", tok2str(nfsv4proc_str, "proc-%u", proc)); if (proc == NFSV4PROC_COMPOUND) { - dp = parserep(ndo, rp, length, &nfserr); - if (dp == NULL) - goto trunc; - dp = parsestatusv4(ndo, dp, &er, &nfserr); - if (dp == NULL) - goto trunc; + dp = parserep(ndo, rp, length, &nfserr); + if (dp == NULL) + goto trunc; + dp = parsestatusv4(ndo, dp, &er, &nfserr); + if (dp == NULL) + goto trunc; } return; } diff --git a/tests/nfs-v4.out b/tests/nfs-v4.out index 4fb336b04..405b66e80 100644 --- a/tests/nfs-v4.out +++ b/tests/nfs-v4.out @@ -1,6 +1,6 @@ 1 06:39:25.778133 IP 192.168.200.198.857 > 192.168.200.1.2049: Flags [P.], seq 3806116338:3806116382, ack 3240065782, win 229, options [nop,nop,TS val 190691472 ecr 193176172], length 44: NFS request xid 1710309038 40 v4 null 2 06:39:25.778431 IP 192.168.200.1.2049 > 192.168.200.198.857: Flags [P.], seq 1:29, ack 44, win 227, options [nop,nop,TS val 193176172 ecr 190691472], length 28: NFS reply xid 1710309038 reply ok 24 v4 null - 3 06:39:25.778791 IP 192.168.200.198.857 > 192.168.200.1.2049: Flags [P.], seq 44:284, ack 29, win 229, options [nop,nop,TS val 190691473 ecr 193176172], length 240: NFS request xid 1727086254 236 v4 compound + 3 06:39:25.778791 IP 192.168.200.198.857 > 192.168.200.1.2049: Flags [P.], seq 44:284, ack 29, win 229, options [nop,nop,TS val 190691473 ecr 193176172], length 240: NFS request xid 1727086254 236 v4.1 compound ops 1 4 06:39:25.778965 IP 192.168.200.1.2049 > 192.168.200.198.857: Flags [P.], seq 29:133, ack 284, win 235, options [nop,nop,TS val 193176173 ecr 190691473], length 104: NFS reply xid 1727086254 reply ok 100 v4 compound - 5 06:39:35.254619 IP 192.168.200.198.857 > 192.168.200.1.2049: Flags [P.], seq 3584:3776, ack 3801, win 371, options [nop,nop,TS val 190700949 ecr 193185649], length 192: NFS request xid 2079407790 188 v4 compound + 5 06:39:35.254619 IP 192.168.200.198.857 > 192.168.200.1.2049: Flags [P.], seq 3584:3776, ack 3801, win 371, options [nop,nop,TS val 190700949 ecr 193185649], length 192: NFS request xid 2079407790 188 v4.1 compound ops 5 6 06:39:35.254792 IP 192.168.200.1.2049 > 192.168.200.198.857: Flags [P.], seq 3801:3901, ack 3776, win 411, options [nop,nop,TS val 193185649 ecr 190700949], length 100: NFS reply xid 2079407790 reply ok 96 v4 compound ERROR: NFS4ERR_NOENT