xref: /386bsd/usr/src/usr.sbin/tcpdump/print-nfs.c (revision a2142627)
1 /*
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that: (1) source code distributions
7  * retain the above copyright notice and this paragraph in its entirety, (2)
8  * distributions including binary code include the above copyright notice and
9  * this paragraph in its entirety in the documentation or other materials
10  * provided with the distribution, and (3) all advertising materials mentioning
11  * features or use of this software display the following acknowledgement:
12  * ``This product includes software developed by the University of California,
13  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14  * the University nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior
16  * written permission.
17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20  */
21 
22 #ifndef lint
23 static char rcsid[] =
24     "@(#) $Header: print-nfs.c,v 1.17 91/05/06 00:54:21 mccanne Exp $ (LBL)";
25 #endif
26 
27 #include <sys/param.h>
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <net/if.h>
31 #include <netinet/in.h>
32 #include <netinet/if_ether.h>
33 #include <netinet/in_systm.h>
34 #include <netinet/ip.h>
35 #include <netinet/ip_var.h>
36 
37 #include <sys/time.h>
38 #include <errno.h>
39 #include <rpc/types.h>
40 #include <rpc/auth.h>
41 #include <rpc/auth_unix.h>
42 #include <rpc/svc.h>
43 #include <rpc/xdr.h>
44 #include <rpc/rpc_msg.h>
45 
46 #include <ctype.h>
47 
48 #include "interface.h"
49 /* These must come after interface.h for BSD. */
50 #if BSD >= 199006
51 #include <nfs/nfsv2.h>
52 #endif
53 #include <nfs/nfs.h>
54 
55 #include "addrtoname.h"
56 #include "extract.h"
57 
58 static void printfh(), nfs_printfn();
59 
60 void
nfsreply_print(rp,length,ip)61 nfsreply_print(rp, length, ip)
62 	register struct rpc_msg *rp;
63 	int length;
64 	register struct ip *ip;
65 {
66 #if	BYTE_ORDER == LITTLE_ENDIAN
67 	bswap(rp, sizeof(*rp));
68 #endif
69 	if (!nflag)
70 		(void)printf("%s.nfs > %s.%x: reply %s %d",
71 			     ipaddr_string(&ip->ip_src),
72 			     ipaddr_string(&ip->ip_dst),
73 			     rp->rm_xid,
74 			     rp->rm_reply.rp_stat == MSG_ACCEPTED? "ok":"ERR",
75 			     length);
76 	else
77 		(void)printf("%s.%x > %s.%x: reply %s %d",
78 			     ipaddr_string(&ip->ip_src),
79 			     NFS_PORT,
80 			     ipaddr_string(&ip->ip_dst),
81 			     rp->rm_xid,
82 			     rp->rm_reply.rp_stat == MSG_ACCEPTED? "ok":"ERR",
83 			     length);
84 }
85 
86 void
nfsreq_print(rp,length,ip)87 nfsreq_print(rp, length, ip)
88 	register struct rpc_msg *rp;
89 	int length;
90 	register struct ip *ip;
91 {
92 	register u_long *dp;
93 	register u_long *ep = (u_long *)snapend;
94 
95 #if	BYTE_ORDER == LITTLE_ENDIAN
96 	bswap(rp, sizeof(*rp));
97 #endif
98 
99 	if (!nflag)
100 		(void)printf("%s.%x > %s.nfs: %d",
101 			     ipaddr_string(&ip->ip_src),
102 			     rp->rm_xid,
103 			     ipaddr_string(&ip->ip_dst),
104 			     length);
105 	else
106 		(void)printf("%s.%x > %s.%x: %d",
107 			     ipaddr_string(&ip->ip_src),
108 			     rp->rm_xid,
109 			     ipaddr_string(&ip->ip_dst),
110 			     NFS_PORT,
111 			     length);
112 
113 
114 	/* find the start of the req data(if we captured it) */
115 	dp = (u_long *)(&rp->rm_call.cb_cred);
116 	if (dp < ep && dp[1] < length) {
117 		dp += (dp[1] + (2*sizeof(u_long) + 3)) / sizeof(u_long);
118 		if ((dp < ep) && (dp[1] < length)) {
119 			dp += (dp[1] + (2*sizeof(u_long) + 3)) /
120 				sizeof(u_long);
121 			if (dp >= ep)
122 				dp = 0;
123 		} else
124 			dp = 0;
125 	} else
126 		dp = 0;
127 
128 	switch (rp->rm_call.cb_proc) {
129 	case RFS_NULL:
130 		printf(" null");
131 		break;
132 	case RFS_GETATTR:
133 		printf(" getattr");
134 		if (dp)
135 			printfh(dp);
136 		break;
137 	case RFS_SETATTR:
138 		printf(" setattr");
139 		if (dp)
140 			printfh(dp);
141 		break;
142 	case RFS_ROOT:
143 		printf(" root");
144 		break;
145 	case RFS_LOOKUP:
146 		printf(" lookup");
147 		if (dp) {
148 			printfh(dp);
149 			putchar(' ');
150 			nfs_printfn(&dp[8]);
151 		}
152 		break;
153 	case RFS_READLINK:
154 		printf(" readlink");
155 		if (dp)
156 			printfh(dp);
157 		break;
158 	case RFS_READ:
159 		printf(" read");
160 		if (dp) {
161 			printfh(dp);
162  			printf(" %d (%d) bytes @ %d",
163  				ntohl(dp[9]), ntohl(dp[10]), ntohl(dp[8]));
164 		}
165 		break;
166 	case RFS_WRITECACHE:
167 		printf(" writecache");
168 		if (dp) {
169 			printfh(dp);
170 			printf(" %d (%d) bytes @ %d (%d)",
171  				ntohl(dp[11]), ntohl(dp[10]),
172  				ntohl(dp[9]), ntohl(dp[8]));
173 		}
174 		break;
175 	case RFS_WRITE:
176 		printf(" write");
177 		if (dp) {
178 			printfh(dp);
179 			printf(" %d (%d) bytes @ %d (%d)",
180  				ntohl(dp[11]), ntohl(dp[10]),
181  				ntohl(dp[9]), ntohl(dp[8]));
182 		}
183 		break;
184 	case RFS_CREATE:
185 		printf(" create");
186 		if (dp) {
187 			printfh(dp);
188 			putchar(' ');
189 			nfs_printfn(&dp[8]);
190 		}
191 		break;
192 	case RFS_REMOVE:
193 		printf(" remove");
194 		if (dp) {
195 			printfh(dp);
196 			putchar(' ');
197 			nfs_printfn(&dp[8]);
198 		}
199 		break;
200 	case RFS_RENAME:
201 		printf(" rename");
202 		if (dp) {
203 			printfh(dp);
204 			putchar(' ');
205 			nfs_printfn(&dp[8]);
206 		}
207 		break;
208 	case RFS_LINK:
209 		printf(" link");
210 		if (dp)
211 			printfh(dp);
212 		break;
213 	case RFS_SYMLINK:
214 		printf(" symlink");
215 		if (dp) {
216 			printfh(dp);
217 			putchar(' ');
218 			nfs_printfn(&dp[8]);
219 		}
220 		break;
221 	case RFS_MKDIR:
222 		printf(" mkdir");
223 		if (dp) {
224 			printfh(dp);
225 			putchar(' ');
226 			nfs_printfn(&dp[8]);
227 		}
228 		break;
229 	case RFS_RMDIR:
230 		printf(" rmdir");
231 		if (dp) {
232 			printfh(dp);
233 			putchar(' ');
234 			nfs_printfn(&dp[8]);
235 		}
236 		break;
237 	case RFS_READDIR:
238 		printf(" readdir");
239 		if (dp) {
240 			printfh(dp);
241 			printf(" %d bytes @ %d", ntohl(dp[9]), ntohl(dp[8]));
242 		}
243 		break;
244 	case RFS_STATFS:
245 		printf(" statfs");
246 		if (dp)
247 			printfh(dp);
248 		break;
249 	default:
250 		printf(" proc-%d", rp->rm_call.cb_proc);
251 		break;
252 	}
253 }
254 
255 static void
printfh(dp)256 printfh(dp)
257 	register u_long *dp;
258 {
259 	/*
260 	 * take a wild guess at the structure of file handles.
261 	 * On sun 3s, there are 2 longs of fsid, a short
262 	 * len == 8, a long of inode & a long of generation number.
263 	 * On sun 4s, the len == 10 & there are 2 bytes of
264 	 * padding immediately following it.
265 	 */
266 	if (dp[2] == 0xa0000) {
267 		if (dp[1])
268 			(void) printf(" fh %d.%d.%d", dp[0], dp[1], dp[3]);
269 		else
270 			(void) printf(" fh %d.%d", dp[0], dp[3]);
271 	} else if ((dp[2] >> 16) == 8)
272 		/*
273 		 * 'dp' is longword aligned, so we must use the extract
274 		 * macros below for dp+10 which cannot possibly be aligned.
275 		 */
276 		if (dp[1])
277 			(void) printf(" fh %d.%d.%d", dp[0], dp[1],
278 				      EXTRACT_LONG((u_char *)dp + 10));
279 		else
280 			(void) printf(" fh %d.%d", dp[0],
281 				      EXTRACT_LONG((u_char *)dp + 10));
282 	/* On Ultrix pre-4.0, three longs: fsid, fno, fgen and then zeros */
283 	else if (dp[3] == 0) {
284 		(void)printf(" fh %d,%d/%d.%d", major(dp[0]), minor(dp[0]),
285 			     dp[1], dp[2]);
286 	}
287 	/*
288 	 * On Ultrix 4.0,
289 	 * five longs: fsid, fno, fgen, eno, egen and then zeros
290 	 */
291 	else if (dp[5] == 0) {
292 		(void)printf(" fh %d,%d/%d.%d", major(dp[0]), minor(dp[0]),
293 			     dp[1], dp[2]);
294 		if (vflag) {
295 			/* print additional info */
296 			(void)printf("[%d.%d]", dp[3], dp[4]);
297 		}
298 	}
299 	else
300 		(void) printf(" fh %x.%x.%x.%x", dp[0], dp[1], dp[2], dp[3]);
301 }
302 
303 static void
nfs_printfn(dp)304 nfs_printfn(dp)
305 	u_long *dp;
306 {
307 	register u_int i = *dp++;
308 	register u_char *cp = (u_char *)dp;
309 	register char c;
310 
311 	i = ntohl(i);
312 	if (i == 0) {	/* otherwise we decrement to MAXINT before testing i */
313 	    putchar('"');
314     	    putchar('"');
315 	    return;
316 	}
317 	if (i < 64) {	/* sanity */
318 		putchar('"');
319 		do {
320 			c = toascii(*cp++);
321 			if (!isascii(c)) {
322 				c = toascii(c);
323 				putchar('M');
324 				putchar('-');
325 			}
326 			if (!isprint(c)) {
327 				c ^= 0x40; /* DEL to ?, others to alpha */
328 				putchar('^');
329 			}
330 			putchar(c);
331 		} while (--i);
332 		putchar('"');
333 	}
334 }
335 
336 #if	BYTE_ORDER == LITTLE_ENDIAN
337 /* assumes input is long-aligned and N*sizeof(long) bytes */
bswap(bp,len)338 static bswap(bp, len)
339 long *bp;
340 int len;
341 {
342 	int i;
343 	len = len/sizeof(long);
344 
345 	for (i = 0; i < len; i++)
346 		bp[i] = ntohl(bp[i]);
347 }
348 #endif
349