[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

system/1540: tcpdump incorrectly print port numbers when parsing NFS packets.




>Number:         1540
>Category:       system
>Synopsis:       tcpdump incorrectly print port numbers when parsing NFS packets.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Dec  2 12:30:01 MST 2000
>Last-Modified:
>Originator:     Grigoriy Orlov
>Organization:
>Release:        2.8-current
>Environment:
	System      : OpenBSD 2.8-current 20.11.2000
	Architecture: OpenBSD.i386
	Machine     : i686
>Description:

tcpdump incorrectly print port numbers for nfs packets.

Part of "tcpdump -n" output from mount session:
20:36:04.468431 x.x.x.x.938 > y.y.y.y.111:  udp 56
20:36:04.468482 y.y.y.y.111 > x.x.x.x.938:  udp 28
20:36:04.469588 x.x.x.x.3a2f2a94 > y.y.y.y.801: 40 null
20:36:04.469645 y.y.y.y.801 > x.x.x.x.3a2f2a94: reply ok 24 null

801 is nfs port in hex (0x0801 = 2049)
3a2f2a94 is xid - transaction identifier.

The same part of "tcpdump -n" output from patched tcpdump:
22:17:02.144416 x.x.x.x.907 > y.y.y.y.111:  udp 56
22:17:02.144465 y.y.y.y.111 > x.x.x.x.907:  udp 28
22:17:02.145569 x.x.x.x.908 > y.y.y.y.2049: xid 0x3a2c44ff 40 null
22:17:02.145626 y.y.y.y.2049 > x.x.x.x.908: xid 0x3a2c44ff reply ok 24 null

>How-To-Repeat:

run "tcpdump -n" and mount NFS-exported partition.

>Fix:

Index: print-nfs.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/print-nfs.c,v
retrieving revision 1.8
diff -u -r1.8 print-nfs.c
--- print-nfs.c	2000/10/03 14:31:58	1.8
+++ print-nfs.c	2000/12/02 17:19:24
@@ -75,24 +75,9 @@
 	rp = (const struct rpc_msg *)bp;
 	ip = (const struct ip *)bp2;
 
-	if (!nflag)
-		(void)printf("%s.nfs > %s.%x: reply %s %d",
-			     ipaddr_string(&ip->ip_src),
-			     ipaddr_string(&ip->ip_dst),
-			     (u_int32_t)ntohl(rp->rm_xid),
-			     ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED?
-				     "ok":"ERR",
-			     length);
-	else
-		(void)printf("%s.%x > %s.%x: reply %s %d",
-			     ipaddr_string(&ip->ip_src),
-			     NFS_PORT,
-			     ipaddr_string(&ip->ip_dst),
-			     (u_int32_t)ntohl(rp->rm_xid),
-			     ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED?
-			     	"ok":"ERR",
-			     length);
-
+	printf("xid 0x%x reply %s %d", (u_int32_t)ntohl(rp->rm_xid),
+		ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED ? "ok":"ERR",
+		length);
 	if (xid_map_find(rp, ip, &proc))
 		interp_reply(rp, proc, length);
 }
@@ -198,19 +183,7 @@
 	nfserr = 0;		/* assume no error */
 	rp = (const struct rpc_msg *)bp;
 	ip = (const struct ip *)bp2;
-	if (!nflag)
-		(void)printf("%s.%x > %s.nfs: %d",
-			     ipaddr_string(&ip->ip_src),
-			     (u_int32_t)ntohl(rp->rm_xid),
-			     ipaddr_string(&ip->ip_dst),
-			     length);
-	else
-		(void)printf("%s.%x > %s.%x: %d",
-			     ipaddr_string(&ip->ip_src),
-			     (u_int32_t)ntohl(rp->rm_xid),
-			     ipaddr_string(&ip->ip_dst),
-			     NFS_PORT,
-			     length);
+	printf("xid 0x%x %d", (u_int32_t)ntohl(rp->rm_xid), length);
 
 	xid_map_enter(rp, ip);	/* record proc number for later on */
 
Index: print-sunrpc.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/print-sunrpc.c,v
retrieving revision 1.9
diff -u -r1.9 print-sunrpc.c
--- print-sunrpc.c	2000/10/03 14:31:58	1.9
+++ print-sunrpc.c	2000/12/02 17:19:25
@@ -80,19 +80,7 @@
 	rp = (struct rpc_msg *)bp;
 	ip = (struct ip *)bp2;
 
-	if (!nflag)
-		(void)printf("%s.%x > %s.sunrpc: %d",
-			     ipaddr_string(&ip->ip_src),
-			     (u_int32_t)ntohl(rp->rm_xid),
-			     ipaddr_string(&ip->ip_dst),
-			     length);
-	else
-		(void)printf("%s.%x > %s.%x: %d",
-			     ipaddr_string(&ip->ip_src),
-			     (u_int32_t)ntohl(rp->rm_xid),
-			     ipaddr_string(&ip->ip_dst),
-			     PMAPPORT,
-			     length);
+	printf("xid 0x%x %d", (u_int32_t)ntohl(rp->rm_xid), length);
 	printf(" %s", tok2str(proc2str, " proc #%u",
 	    (u_int32_t)ntohl(rp->rm_call.cb_proc)));
 	x = ntohl(rp->rm_call.cb_rpcvers);
Index: print-tcp.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/print-tcp.c,v
retrieving revision 1.12
diff -u -r1.12 print-tcp.c
--- print-tcp.c	2000/10/03 14:21:56	1.12
+++ print-tcp.c	2000/12/02 17:19:25
@@ -205,26 +205,6 @@
 	urp = ntohs(tp->th_urp);
 	hlen = tp->th_off * 4;
 
-	/*
-	 * If data present and NFS port used, assume NFS.
-	 * Pass offset of data plus 4 bytes for RPC TCP msg length
-	 * to NFS print routines.
-	 */
-	if (!qflag) {
-		u_int len = length - hlen;
-		if ((u_char *)tp + 4 + sizeof(struct rpc_msg) <= snapend &&
-		    dport == NFS_PORT) {
-			nfsreq_print((u_char *)tp + hlen + 4, len,
-				     (u_char *)ip);
-			return;
-		}
-		else if ((u_char *)tp + 4 + sizeof(struct rpc_msg) <= snapend &&
-		    sport == NFS_PORT) {
-			nfsreply_print((u_char *)tp + hlen + 4, len,
-				       (u_char *)ip);
-			return;
-		}
-	}
 
 #ifdef INET6
 	if (ip6) {
@@ -256,6 +236,24 @@
 	if (qflag) {
 		(void)printf("tcp %d", length - tp->th_off * 4);
 		return;
+	} else {
+		/*
+		 * If data present and NFS port used, assume NFS.
+		 * Pass offset of data plus 4 bytes for RPC TCP msg length
+		 * to NFS print routines.
+		 */
+		u_int len = length - hlen;
+		if ((u_char *)tp + 4 + sizeof(struct rpc_msg) <= snapend &&
+		    dport == NFS_PORT) {
+			nfsreq_print((u_char *)tp + hlen + 4, len,
+				     (u_char *)ip);
+			return;
+		} else if ((u_char *)tp + 4 + 
+		    sizeof(struct rpc_msg) <= snapend && sport == NFS_PORT) {
+			nfsreply_print((u_char *)tp + hlen + 4, len,
+				       (u_char *)ip);
+			return;
+		}
 	}
 	if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH|
 				      TH_ECNECHO|TH_CWR)) {
Index: print-udp.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/print-udp.c,v
retrieving revision 1.14
diff -u -r1.14 print-udp.c
--- print-udp.c	2000/10/03 14:21:57	1.14
+++ print-udp.c	2000/12/02 17:19:27
@@ -423,6 +423,11 @@
 			break;
 
 		case PT_RPC:
+			(void)printf("%s.%s > %s.%s: ",
+				ipaddr_string(&ip->ip_src),
+				udpport_string(sport),
+				ipaddr_string(&ip->ip_dst),
+				udpport_string(dport));
 			rp = (struct rpc_msg *)(up + 1);
 			direction = (enum msg_type)ntohl(rp->rm_direction);
 			if (direction == CALL)
@@ -466,17 +471,32 @@
 		if (TTEST(rp->rm_direction)) {
 			direction = (enum msg_type)ntohl(rp->rm_direction);
 			if (dport == NFS_PORT && direction == CALL) {
+				(void)printf("%s.%s > %s.%s: ",
+					ipaddr_string(&ip->ip_src),
+					udpport_string(sport),
+					ipaddr_string(&ip->ip_dst),
+					udpport_string(dport));
 				nfsreq_print((u_char *)rp, length,
 				    (u_char *)ip);
 				return;
 			}
 			if (sport == NFS_PORT && direction == REPLY) {
+				(void)printf("%s.%s > %s.%s: ",
+					ipaddr_string(&ip->ip_src),
+					udpport_string(sport),
+					ipaddr_string(&ip->ip_dst),
+					udpport_string(dport));
 				nfsreply_print((u_char *)rp, length,
 				    (u_char *)ip);
 				return;
 			}
 #ifdef notdef
 			if (dport == SUNRPC_PORT && direction == CALL) {
+				(void)printf("%s.%s > %s.%s: ",
+					ipaddr_string(&ip->ip_src),
+					udpport_string(sport),
+					ipaddr_string(&ip->ip_dst),
+					udpport_string(dport));
 				sunrpcrequest_print((u_char *)rp, length, (u_char *)ip);
 				return;
 			}

>Audit-Trail:
>Unformatted: