]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-nfs.c
Add changes in 4.2.1.
[tcpdump] / print-nfs.c
index 0674d1ea853fd94373902631dc967f9b57ac1453..4d17757f311457e72a5e12eb7847c67fdc52229f 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-nfs.c,v 1.109 2007-06-15 19:04:39 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-nfs.c,v 1.111 2007-12-22 03:08:04 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -49,7 +49,7 @@ static const char rcsid[] _U_ =
 #include "rpc_msg.h"
 
 static void nfs_printfh(const u_int32_t *, const u_int);
-static void xid_map_enter(const struct sunrpc_msg *, const u_char *);
+static int xid_map_enter(const struct sunrpc_msg *, const u_char *);
 static int32_t xid_map_find(const struct sunrpc_msg *, const u_char *,
                            u_int32_t *, u_int32_t *);
 static void interp_reply(const struct sunrpc_msg *, u_int32_t, u_int32_t, int);
@@ -287,7 +287,7 @@ nfsreply_print(register const u_char *bp, u_int length,
               register const u_char *bp2)
 {
        register const struct sunrpc_msg *rp;
-       u_int32_t proc, vers, reply;
+       u_int32_t proc, vers, reply_stat;
        char srcid[20], dstid[20];      /*fits 32bit*/
        enum sunrpc_reject_stat rstat;
        u_int32_t rlow;
@@ -297,6 +297,7 @@ nfsreply_print(register const u_char *bp, u_int length,
        nfserr = 0;             /* assume no error */
        rp = (const struct sunrpc_msg *)bp;
 
+       TCHECK(rp->rm_xid);
        if (!nflag) {
                strlcpy(srcid, "nfs", sizeof(srcid));
                snprintf(dstid, sizeof(dstid), "%u",
@@ -307,28 +308,32 @@ nfsreply_print(register const u_char *bp, u_int length,
                    EXTRACT_32BITS(&rp->rm_xid));
        }
        print_nfsaddr(bp2, srcid, dstid);
-       reply = EXTRACT_32BITS(&rp->rm_reply.rp_stat);
-       switch (reply) {
+       TCHECK(rp->rm_reply.rp_stat);
+       reply_stat = EXTRACT_32BITS(&rp->rm_reply.rp_stat);
+       switch (reply_stat) {
 
        case SUNRPC_MSG_ACCEPTED:
-               (void)printf("reply ok %d", length);
+               (void)printf("reply ok %u", length);
                if (xid_map_find(rp, bp2, &proc, &vers) >= 0)
                        interp_reply(rp, proc, vers, length);
                break;
 
        case SUNRPC_MSG_DENIED:
-               (void)printf("reply ERR %d: ", length);
+               (void)printf("reply ERR %u: ", length);
+               TCHECK(rp->rm_reply.rp_reject.rj_stat);
                rstat = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_stat);
                switch (rstat) {
 
                case SUNRPC_RPC_MISMATCH:
+                       TCHECK(rp->rm_reply.rp_reject.rj_vers.high);
                        rlow = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_vers.low);
                        rhigh = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_vers.high);
-                       (void)printf("RPC Version mismatch (%d-%d)",
-                           (int)rlow, (int)rhigh);
+                       (void)printf("RPC Version mismatch (%u-%u)",
+                           rlow, rhigh);
                        break;
 
                case SUNRPC_AUTH_ERROR:
+                       TCHECK(rp->rm_reply.rp_reject.rj_why);
                        rwhy = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_why);
                        (void)printf("Auth ");
                        switch (rwhy) {
@@ -366,24 +371,29 @@ nfsreply_print(register const u_char *bp, u_int length,
                                break;
 
                        default:
-                               (void)printf("Invalid failure code %d",
-                                   (int)rwhy);
+                               (void)printf("Invalid failure code %u",
+                                   (unsigned int)rwhy);
                                break;
                        }
                        break;
 
                default:
-                       (void)printf("Unknown reason for rejecting rpc message %d",
-                           (int)rstat);
+                       (void)printf("Unknown reason for rejecting rpc message %u",
+                           (unsigned int)rstat);
                        break;
                }
                break;
 
        default:
-               (void)printf("reply Unknown rpc response code=%u %d",
-                   reply, length);
+               (void)printf("reply Unknown rpc response code=%u %u",
+                   reply_stat, length);
                break;
        }
+       return;
+
+trunc:
+       if (!nfserr)
+               fputs(" [|nfs]", stdout);
 }
 
 /*
@@ -498,11 +508,14 @@ nfsreq_print(register const u_char *bp, u_int length,
        nfs_type type;
        int v3;
        u_int32_t proc;
+       u_int32_t access_flags;
        struct nfsv3_sattr sa3;
        char srcid[20], dstid[20];      /*fits 32bit*/
 
        nfserr = 0;             /* assume no error */
        rp = (const struct sunrpc_msg *)bp;
+
+       TCHECK(rp->rm_xid);
        if (!nflag) {
                snprintf(srcid, sizeof(srcid), "%u",
                    EXTRACT_32BITS(&rp->rm_xid));
@@ -515,7 +528,8 @@ nfsreq_print(register const u_char *bp, u_int length,
        print_nfsaddr(bp2, srcid, dstid);
        (void)printf("%d", length);
 
-       xid_map_enter(rp, bp2); /* record proc number for later on */
+       if (!xid_map_enter(rp, bp2))    /* record proc number for later on */
+               goto trunc;
 
        v3 = (EXTRACT_32BITS(&rp->rm_call.cb_vers) == NFS_VER3);
        proc = EXTRACT_32BITS(&rp->rm_call.cb_proc);
@@ -557,7 +571,37 @@ nfsreq_print(register const u_char *bp, u_int length,
                if ((dp = parsereq(rp, length)) != NULL &&
                    (dp = parsefh(dp, v3)) != NULL) {
                        TCHECK(dp[0]);
-                       printf(" %04x", EXTRACT_32BITS(&dp[0]));
+                       access_flags = EXTRACT_32BITS(&dp[0]);
+                       if (access_flags & ~NFSV3ACCESS_FULL) {
+                               /* NFSV3ACCESS definitions aren't up to date */
+                               printf(" %04x", access_flags);
+                       } else if ((access_flags & NFSV3ACCESS_FULL) == NFSV3ACCESS_FULL) {
+                               printf(" NFS_ACCESS_FULL");
+                       } else {
+                               char separator = ' ';
+                               if (access_flags & NFSV3ACCESS_READ) {
+                                       printf(" NFS_ACCESS_READ");
+                                       separator = '|';
+                               }
+                               if (access_flags & NFSV3ACCESS_LOOKUP) {
+                                       printf("%cNFS_ACCESS_LOOKUP", separator);
+                                       separator = '|';
+                               }
+                               if (access_flags & NFSV3ACCESS_MODIFY) {
+                                       printf("%cNFS_ACCESS_MODIFY", separator);
+                                       separator = '|';
+                               }
+                               if (access_flags & NFSV3ACCESS_EXTEND) {
+                                       printf("%cNFS_ACCESS_EXTEND", separator);
+                                       separator = '|';
+                               }
+                               if (access_flags & NFSV3ACCESS_DELETE) {
+                                       printf("%cNFS_ACCESS_DELETE", separator);
+                                       separator = '|';
+                               }
+                               if (access_flags & NFSV3ACCESS_EXECUTE)
+                                       printf("%cNFS_ACCESS_EXECUTE", separator);
+                       }
                        return;
                }
                break;
@@ -886,7 +930,7 @@ struct xid_map_entry xid_map[XIDMAPSIZE];
 int    xid_map_next = 0;
 int    xid_map_hint = 0;
 
-static void
+static int
 xid_map_enter(const struct sunrpc_msg *rp, const u_char *bp)
 {
        struct ip *ip = NULL;
@@ -895,6 +939,8 @@ xid_map_enter(const struct sunrpc_msg *rp, const u_char *bp)
 #endif
        struct xid_map_entry *xmep;
 
+       if (!TTEST(rp->rm_call.cb_vers))
+               return (0);
        switch (IP_V((struct ip *)bp)) {
        case 4:
                ip = (struct ip *)bp;
@@ -905,7 +951,7 @@ xid_map_enter(const struct sunrpc_msg *rp, const u_char *bp)
                break;
 #endif
        default:
-               return;
+               return (1);
        }
 
        xmep = &xid_map[xid_map_next];
@@ -928,6 +974,7 @@ xid_map_enter(const struct sunrpc_msg *rp, const u_char *bp)
 #endif
        xmep->proc = EXTRACT_32BITS(&rp->rm_call.cb_proc);
        xmep->vers = EXTRACT_32BITS(&rp->rm_call.cb_vers);
+       return (1);
 }
 
 /*