xref: /aosp_15_r20/external/tcpdump/parsenfsfh.c (revision 05b00f6010a2396e3db2409989fc67270046269f)
1*05b00f60SXin Li /*
2*05b00f60SXin Li  * Copyright (c) 1993, 1994 Jeffrey C. Mogul, Digital Equipment Corporation,
3*05b00f60SXin Li  * Western Research Laboratory. All rights reserved.
4*05b00f60SXin Li  * Copyright (c) 2001 Compaq Computer Corporation. All rights reserved.
5*05b00f60SXin Li  *
6*05b00f60SXin Li  *  Permission to use, copy, and modify this software and its
7*05b00f60SXin Li  *  documentation is hereby granted only under the following terms and
8*05b00f60SXin Li  *  conditions.  Both the above copyright notice and this permission
9*05b00f60SXin Li  *  notice must appear in all copies of the software, derivative works
10*05b00f60SXin Li  *  or modified versions, and any portions thereof, and both notices
11*05b00f60SXin Li  *  must appear in supporting documentation.
12*05b00f60SXin Li  *
13*05b00f60SXin Li  *  Redistribution and use in source and binary forms, with or without
14*05b00f60SXin Li  *  modification, are permitted provided that the following conditions
15*05b00f60SXin Li  *  are met:
16*05b00f60SXin Li  *    1. Redistributions of source code must retain the above copyright
17*05b00f60SXin Li  *    notice, this list of conditions and the following disclaimer.
18*05b00f60SXin Li  *    2. Redistributions in binary form must reproduce the above copyright
19*05b00f60SXin Li  *    notice, this list of conditions and the following disclaimer in
20*05b00f60SXin Li  *    the documentation and/or other materials provided with the
21*05b00f60SXin Li  *    distribution.
22*05b00f60SXin Li  *
23*05b00f60SXin Li  *  THE SOFTWARE IS PROVIDED "AS IS" AND COMPAQ COMPUTER CORPORATION
24*05b00f60SXin Li  *  DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
25*05b00f60SXin Li  *  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.   IN NO
26*05b00f60SXin Li  *  EVENT SHALL COMPAQ COMPUTER CORPORATION BE LIABLE FOR ANY
27*05b00f60SXin Li  *  SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
28*05b00f60SXin Li  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
29*05b00f60SXin Li  *  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
30*05b00f60SXin Li  *  OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
31*05b00f60SXin Li  *  SOFTWARE.
32*05b00f60SXin Li  */
33*05b00f60SXin Li 
34*05b00f60SXin Li /*
35*05b00f60SXin Li  * parsenfsfh.c - portable parser for NFS file handles
36*05b00f60SXin Li  *			uses all sorts of heuristics
37*05b00f60SXin Li  *
38*05b00f60SXin Li  * Jeffrey C. Mogul
39*05b00f60SXin Li  * Digital Equipment Corporation
40*05b00f60SXin Li  * Western Research Laboratory
41*05b00f60SXin Li  */
42*05b00f60SXin Li 
43*05b00f60SXin Li #ifdef HAVE_CONFIG_H
44*05b00f60SXin Li #include <config.h>
45*05b00f60SXin Li #endif
46*05b00f60SXin Li 
47*05b00f60SXin Li #include "netdissect-stdinc.h"
48*05b00f60SXin Li 
49*05b00f60SXin Li #include <stdio.h>
50*05b00f60SXin Li #include <string.h>
51*05b00f60SXin Li 
52*05b00f60SXin Li #include "netdissect-ctype.h"
53*05b00f60SXin Li 
54*05b00f60SXin Li #include "netdissect.h"
55*05b00f60SXin Li #include "extract.h"
56*05b00f60SXin Li #include "nfsfh.h"
57*05b00f60SXin Li 
58*05b00f60SXin Li /*
59*05b00f60SXin Li  * This routine attempts to parse a file handle (in network byte order),
60*05b00f60SXin Li  * using heuristics to guess what kind of format it is in.  See the
61*05b00f60SXin Li  * file "fhandle_layouts" for a detailed description of the various
62*05b00f60SXin Li  * patterns we know about.
63*05b00f60SXin Li  *
64*05b00f60SXin Li  * The file handle is parsed into our internal representation of a
65*05b00f60SXin Li  * file-system id, and an internal representation of an inode-number.
66*05b00f60SXin Li  */
67*05b00f60SXin Li 
68*05b00f60SXin Li #define	FHT_UNKNOWN	0
69*05b00f60SXin Li #define	FHT_AUSPEX	1
70*05b00f60SXin Li #define	FHT_DECOSF	2
71*05b00f60SXin Li #define	FHT_IRIX4	3
72*05b00f60SXin Li #define	FHT_IRIX5	4
73*05b00f60SXin Li #define	FHT_SUNOS3	5
74*05b00f60SXin Li #define	FHT_SUNOS4	6
75*05b00f60SXin Li #define	FHT_ULTRIX	7
76*05b00f60SXin Li #define	FHT_VMSUCX	8
77*05b00f60SXin Li #define	FHT_SUNOS5	9
78*05b00f60SXin Li #define	FHT_AIX32	10
79*05b00f60SXin Li #define	FHT_HPUX9	11
80*05b00f60SXin Li #define	FHT_BSD44	12
81*05b00f60SXin Li 
82*05b00f60SXin Li static int is_UCX(netdissect_options *, const unsigned char *, u_int);
83*05b00f60SXin Li 
84*05b00f60SXin Li void
Parse_fh(netdissect_options * ndo,const unsigned char * fh,u_int len,my_fsid * fsidp,uint32_t * inop,const char ** osnamep,const char ** fsnamep,int ourself)85*05b00f60SXin Li Parse_fh(netdissect_options *ndo, const unsigned char *fh, u_int len,
86*05b00f60SXin Li 	 my_fsid *fsidp, uint32_t *inop,
87*05b00f60SXin Li 	 const char **osnamep, /* if non-NULL, return OS name here */
88*05b00f60SXin Li 	 const char **fsnamep, /* if non-NULL, return server fs name here (for VMS) */
89*05b00f60SXin Li 	 int ourself)	/* true if file handle was generated on this host */
90*05b00f60SXin Li {
91*05b00f60SXin Li 	const unsigned char *fhp = fh;
92*05b00f60SXin Li 	uint32_t temp;
93*05b00f60SXin Li 	int fhtype = FHT_UNKNOWN;
94*05b00f60SXin Li 	u_int i;
95*05b00f60SXin Li 
96*05b00f60SXin Li 	/*
97*05b00f60SXin Li 	 * Require at least 16 bytes of file handle; it's variable-length
98*05b00f60SXin Li 	 * in NFSv3.  "len" is in units of 32-bit words, not bytes.
99*05b00f60SXin Li 	 */
100*05b00f60SXin Li 	if (len < 16/4)
101*05b00f60SXin Li 		fhtype = FHT_UNKNOWN;
102*05b00f60SXin Li 	else {
103*05b00f60SXin Li 		if (ourself) {
104*05b00f60SXin Li 		    /* File handle generated on this host, no need for guessing */
105*05b00f60SXin Li #if	defined(IRIX40)
106*05b00f60SXin Li 		    fhtype = FHT_IRIX4;
107*05b00f60SXin Li #endif
108*05b00f60SXin Li #if	defined(IRIX50)
109*05b00f60SXin Li 		    fhtype = FHT_IRIX5;
110*05b00f60SXin Li #endif
111*05b00f60SXin Li #if	defined(IRIX51)
112*05b00f60SXin Li 		    fhtype = FHT_IRIX5;
113*05b00f60SXin Li #endif
114*05b00f60SXin Li #if	defined(SUNOS4)
115*05b00f60SXin Li 		    fhtype = FHT_SUNOS4;
116*05b00f60SXin Li #endif
117*05b00f60SXin Li #if	defined(SUNOS5)
118*05b00f60SXin Li 		    fhtype = FHT_SUNOS5;
119*05b00f60SXin Li #endif
120*05b00f60SXin Li #if	defined(ultrix)
121*05b00f60SXin Li 		    fhtype = FHT_ULTRIX;
122*05b00f60SXin Li #endif
123*05b00f60SXin Li #if	defined(__osf__)
124*05b00f60SXin Li 		    fhtype = FHT_DECOSF;
125*05b00f60SXin Li #endif
126*05b00f60SXin Li #if	defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) \
127*05b00f60SXin Li      || defined(__OpenBSD__)
128*05b00f60SXin Li 		    fhtype = FHT_BSD44;
129*05b00f60SXin Li #endif
130*05b00f60SXin Li 		}
131*05b00f60SXin Li 		/*
132*05b00f60SXin Li 		 * This is basically a big decision tree
133*05b00f60SXin Li 		 */
134*05b00f60SXin Li 		else if ((GET_U_1(fhp) == 0) && (GET_U_1(fhp + 1) == 0)) {
135*05b00f60SXin Li 		    /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */
136*05b00f60SXin Li 		    /* probably rules out HP-UX, AIX unless they allow major=0 */
137*05b00f60SXin Li 		    if ((GET_U_1(fhp + 2) == 0) && (GET_U_1(fhp + 3) == 0)) {
138*05b00f60SXin Li 			/* bytes[2,3] == (0,0); must be Auspex */
139*05b00f60SXin Li 			/* XXX or could be Ultrix+MASSBUS "hp" disk? */
140*05b00f60SXin Li 			fhtype = FHT_AUSPEX;
141*05b00f60SXin Li 		    }
142*05b00f60SXin Li 		    else {
143*05b00f60SXin Li 			/*
144*05b00f60SXin Li 			 * bytes[2,3] != (0,0); rules out Auspex, could be
145*05b00f60SXin Li 			 * DECOSF, SUNOS4, or IRIX4
146*05b00f60SXin Li 			 */
147*05b00f60SXin Li 			if ((GET_U_1(fhp + 4) != 0) && (GET_U_1(fhp + 5) == 0) &&
148*05b00f60SXin Li 				(GET_U_1(fhp + 8) == 12) && (GET_U_1(fhp + 9) == 0)) {
149*05b00f60SXin Li 			    /* seems to be DECOSF, with minor == 0 */
150*05b00f60SXin Li 			    fhtype = FHT_DECOSF;
151*05b00f60SXin Li 			}
152*05b00f60SXin Li 			else {
153*05b00f60SXin Li 			    /* could be SUNOS4 or IRIX4 */
154*05b00f60SXin Li 			    /* XXX the test of fhp[5] == 8 could be wrong */
155*05b00f60SXin Li 			    if ((GET_U_1(fhp + 4) == 0) && (GET_U_1(fhp + 5) == 8) && (GET_U_1(fhp + 6) == 0) &&
156*05b00f60SXin Li 			        (GET_U_1(fhp + 7) == 0)) {
157*05b00f60SXin Li 				/* looks like a length, not a file system typecode */
158*05b00f60SXin Li 				fhtype = FHT_IRIX4;
159*05b00f60SXin Li 			    }
160*05b00f60SXin Li 			    else {
161*05b00f60SXin Li 				/* by elimination */
162*05b00f60SXin Li 				fhtype = FHT_SUNOS4;
163*05b00f60SXin Li 			    }
164*05b00f60SXin Li 			}
165*05b00f60SXin Li 		    }
166*05b00f60SXin Li 		}
167*05b00f60SXin Li 		else {
168*05b00f60SXin Li 		    /*
169*05b00f60SXin Li 		     * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4
170*05b00f60SXin Li 		     * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5
171*05b00f60SXin Li 		     * could be AIX, HP-UX
172*05b00f60SXin Li 		     */
173*05b00f60SXin Li 		    if ((GET_U_1(fhp + 2) == 0) && (GET_U_1(fhp + 3) == 0)) {
174*05b00f60SXin Li 			/*
175*05b00f60SXin Li 			 * bytes[2,3] == (0,0); rules out OSF, probably not UCX
176*05b00f60SXin Li 			 * (unless the exported device name is just one letter!),
177*05b00f60SXin Li 			 * could be Ultrix, IRIX5, AIX, or SUNOS5
178*05b00f60SXin Li 			 * might be HP-UX (depends on their values for minor devs)
179*05b00f60SXin Li 			 */
180*05b00f60SXin Li 			if ((GET_U_1(fhp + 6) == 0) && (GET_U_1(fhp + 7) == 0)) {
181*05b00f60SXin Li 			    fhtype = FHT_BSD44;
182*05b00f60SXin Li 			}
183*05b00f60SXin Li 			/*XXX we probably only need to test of these two bytes */
184*05b00f60SXin Li 			else if ((len >= 24/4) && (GET_U_1(fhp + 21) == 0) && (GET_U_1(fhp + 23) == 0)) {
185*05b00f60SXin Li 			    fhtype = FHT_ULTRIX;
186*05b00f60SXin Li 			}
187*05b00f60SXin Li 			else {
188*05b00f60SXin Li 			    /* Could be SUNOS5/IRIX5, maybe AIX */
189*05b00f60SXin Li 			    /* XXX no obvious difference between SUNOS5 and IRIX5 */
190*05b00f60SXin Li 			    if (GET_U_1(fhp + 9) == 10)
191*05b00f60SXin Li 				fhtype = FHT_SUNOS5;
192*05b00f60SXin Li 			    /* XXX what about AIX? */
193*05b00f60SXin Li 			}
194*05b00f60SXin Li 		    }
195*05b00f60SXin Li 		    else {
196*05b00f60SXin Li 			/*
197*05b00f60SXin Li 			 * bytes[2,3] != (0,0); rules out Ultrix, could be
198*05b00f60SXin Li 			 * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, or UCX
199*05b00f60SXin Li 			 */
200*05b00f60SXin Li 			if ((GET_U_1(fhp + 8) == 12) && (GET_U_1(fhp + 9) == 0)) {
201*05b00f60SXin Li 			    fhtype = FHT_DECOSF;
202*05b00f60SXin Li 			}
203*05b00f60SXin Li 			else if ((GET_U_1(fhp + 8) == 0) && (GET_U_1(fhp + 9) == 10)) {
204*05b00f60SXin Li 			    /* could be SUNOS5/IRIX5, AIX, HP-UX */
205*05b00f60SXin Li 			    if ((GET_U_1(fhp + 7) == 0) && (GET_U_1(fhp + 6) == 0) &&
206*05b00f60SXin Li 				(GET_U_1(fhp + 5) == 0) && (GET_U_1(fhp + 4) == 0)) {
207*05b00f60SXin Li 				/* XXX is this always true of HP-UX? */
208*05b00f60SXin Li 				fhtype = FHT_HPUX9;
209*05b00f60SXin Li 			    }
210*05b00f60SXin Li 			    else if (GET_U_1(fhp + 7) == 2) {
211*05b00f60SXin Li 				/* This would be MNT_NFS on AIX, which is impossible */
212*05b00f60SXin Li 				fhtype = FHT_SUNOS5;	/* or maybe IRIX5 */
213*05b00f60SXin Li 			    }
214*05b00f60SXin Li 			    else {
215*05b00f60SXin Li 				/*
216*05b00f60SXin Li 				 * XXX Could be SUNOS5/IRIX5 or AIX.  I don't
217*05b00f60SXin Li 				 * XXX see any way to disambiguate these, so
218*05b00f60SXin Li 				 * XXX I'm going with the more likely guess.
219*05b00f60SXin Li 				 * XXX Sorry, Big Blue.
220*05b00f60SXin Li 				 */
221*05b00f60SXin Li 				fhtype = FHT_SUNOS5;	/* or maybe IRIX5 */
222*05b00f60SXin Li 			    }
223*05b00f60SXin Li 		        }
224*05b00f60SXin Li 			else {
225*05b00f60SXin Li 			    if (is_UCX(ndo, fhp, len)) {
226*05b00f60SXin Li 				fhtype = FHT_VMSUCX;
227*05b00f60SXin Li 			    }
228*05b00f60SXin Li 			    else {
229*05b00f60SXin Li 				fhtype = FHT_UNKNOWN;
230*05b00f60SXin Li 			    }
231*05b00f60SXin Li 			}
232*05b00f60SXin Li 		    }
233*05b00f60SXin Li 		}
234*05b00f60SXin Li 	}
235*05b00f60SXin Li 
236*05b00f60SXin Li 	/* XXX still needs to handle SUNOS3 */
237*05b00f60SXin Li 
238*05b00f60SXin Li 	switch (fhtype) {
239*05b00f60SXin Li 	case FHT_AUSPEX:
240*05b00f60SXin Li 	    fsidp->Fsid_dev.Minor = GET_U_1(fhp + 7);
241*05b00f60SXin Li 	    fsidp->Fsid_dev.Major = GET_U_1(fhp + 6);
242*05b00f60SXin Li 	    fsidp->fsid_code = 0;
243*05b00f60SXin Li 
244*05b00f60SXin Li 	    *inop = GET_BE_U_4(fhp + 12);
245*05b00f60SXin Li 
246*05b00f60SXin Li 	    if (osnamep)
247*05b00f60SXin Li 		*osnamep = "Auspex";
248*05b00f60SXin Li 	    break;
249*05b00f60SXin Li 
250*05b00f60SXin Li 	case FHT_BSD44:
251*05b00f60SXin Li 	    fsidp->Fsid_dev.Minor = GET_U_1(fhp);
252*05b00f60SXin Li 	    fsidp->Fsid_dev.Major = GET_U_1(fhp + 1);
253*05b00f60SXin Li 	    fsidp->fsid_code = 0;
254*05b00f60SXin Li 
255*05b00f60SXin Li 	    *inop = GET_LE_U_4(fhp + 12);
256*05b00f60SXin Li 
257*05b00f60SXin Li 	    if (osnamep)
258*05b00f60SXin Li 		*osnamep = "BSD 4.4";
259*05b00f60SXin Li 	    break;
260*05b00f60SXin Li 
261*05b00f60SXin Li 	case FHT_DECOSF:
262*05b00f60SXin Li 	    fsidp->fsid_code = GET_LE_U_4(fhp + 4);
263*05b00f60SXin Li 			/* XXX could ignore 3 high-order bytes */
264*05b00f60SXin Li 
265*05b00f60SXin Li 	    temp = GET_LE_U_4(fhp);
266*05b00f60SXin Li 	    fsidp->Fsid_dev.Minor = temp & 0xFFFFF;
267*05b00f60SXin Li 	    fsidp->Fsid_dev.Major = (temp>>20) & 0xFFF;
268*05b00f60SXin Li 
269*05b00f60SXin Li 	    *inop = GET_LE_U_4(fhp + 12);
270*05b00f60SXin Li 	    if (osnamep)
271*05b00f60SXin Li 		*osnamep = "OSF";
272*05b00f60SXin Li 	    break;
273*05b00f60SXin Li 
274*05b00f60SXin Li 	case FHT_IRIX4:
275*05b00f60SXin Li 	    fsidp->Fsid_dev.Minor = GET_U_1(fhp + 3);
276*05b00f60SXin Li 	    fsidp->Fsid_dev.Major = GET_U_1(fhp + 2);
277*05b00f60SXin Li 	    fsidp->fsid_code = 0;
278*05b00f60SXin Li 
279*05b00f60SXin Li 	    *inop = GET_BE_U_4(fhp + 8);
280*05b00f60SXin Li 
281*05b00f60SXin Li 	    if (osnamep)
282*05b00f60SXin Li 		*osnamep = "IRIX4";
283*05b00f60SXin Li 	    break;
284*05b00f60SXin Li 
285*05b00f60SXin Li 	case FHT_IRIX5:
286*05b00f60SXin Li 	    fsidp->Fsid_dev.Minor = GET_BE_U_2(fhp + 2);
287*05b00f60SXin Li 	    fsidp->Fsid_dev.Major = GET_BE_U_2(fhp);
288*05b00f60SXin Li 	    fsidp->fsid_code = GET_BE_U_4(fhp + 4);
289*05b00f60SXin Li 
290*05b00f60SXin Li 	    *inop = GET_BE_U_4(fhp + 12);
291*05b00f60SXin Li 
292*05b00f60SXin Li 	    if (osnamep)
293*05b00f60SXin Li 		*osnamep = "IRIX5";
294*05b00f60SXin Li 	    break;
295*05b00f60SXin Li 
296*05b00f60SXin Li #ifdef notdef
297*05b00f60SXin Li 	case FHT_SUNOS3:
298*05b00f60SXin Li 	    /*
299*05b00f60SXin Li 	     * XXX - none of the heuristics above return this.
300*05b00f60SXin Li 	     * Are there any SunOS 3.x systems around to care about?
301*05b00f60SXin Li 	     */
302*05b00f60SXin Li 	    if (osnamep)
303*05b00f60SXin Li 		*osnamep = "SUNOS3";
304*05b00f60SXin Li 	    break;
305*05b00f60SXin Li #endif
306*05b00f60SXin Li 
307*05b00f60SXin Li 	case FHT_SUNOS4:
308*05b00f60SXin Li 	    fsidp->Fsid_dev.Minor = GET_U_1(fhp + 3);
309*05b00f60SXin Li 	    fsidp->Fsid_dev.Major = GET_U_1(fhp + 2);
310*05b00f60SXin Li 	    fsidp->fsid_code = GET_BE_U_4(fhp + 4);
311*05b00f60SXin Li 
312*05b00f60SXin Li 	    *inop = GET_BE_U_4(fhp + 12);
313*05b00f60SXin Li 
314*05b00f60SXin Li 	    if (osnamep)
315*05b00f60SXin Li 		*osnamep = "SUNOS4";
316*05b00f60SXin Li 	    break;
317*05b00f60SXin Li 
318*05b00f60SXin Li 	case FHT_SUNOS5:
319*05b00f60SXin Li 	    temp = GET_BE_U_2(fhp);
320*05b00f60SXin Li 	    fsidp->Fsid_dev.Major = (temp>>2) &  0x3FFF;
321*05b00f60SXin Li 	    temp = GET_BE_U_3(fhp + 1);
322*05b00f60SXin Li 	    fsidp->Fsid_dev.Minor = temp & 0x3FFFF;
323*05b00f60SXin Li 	    fsidp->fsid_code = GET_BE_U_4(fhp + 4);
324*05b00f60SXin Li 
325*05b00f60SXin Li 	    *inop = GET_BE_U_4(fhp + 12);
326*05b00f60SXin Li 
327*05b00f60SXin Li 	    if (osnamep)
328*05b00f60SXin Li 		*osnamep = "SUNOS5";
329*05b00f60SXin Li 	    break;
330*05b00f60SXin Li 
331*05b00f60SXin Li 	case FHT_ULTRIX:
332*05b00f60SXin Li 	    fsidp->fsid_code = 0;
333*05b00f60SXin Li 	    fsidp->Fsid_dev.Minor = GET_U_1(fhp);
334*05b00f60SXin Li 	    fsidp->Fsid_dev.Major = GET_U_1(fhp + 1);
335*05b00f60SXin Li 
336*05b00f60SXin Li 	    temp = GET_LE_U_4(fhp + 4);
337*05b00f60SXin Li 	    *inop = temp;
338*05b00f60SXin Li 	    if (osnamep)
339*05b00f60SXin Li 		*osnamep = "Ultrix";
340*05b00f60SXin Li 	    break;
341*05b00f60SXin Li 
342*05b00f60SXin Li 	case FHT_VMSUCX:
343*05b00f60SXin Li 	    /* No numeric file system ID, so hash on the device-name */
344*05b00f60SXin Li 	    if (sizeof(*fsidp) >= 14) {
345*05b00f60SXin Li 		if (sizeof(*fsidp) > 14)
346*05b00f60SXin Li 		    memset((char *)fsidp, 0, sizeof(*fsidp));
347*05b00f60SXin Li 		/* just use the whole thing */
348*05b00f60SXin Li 		memcpy((char *)fsidp, (const char *)fh, 14);
349*05b00f60SXin Li 	    }
350*05b00f60SXin Li 	    else {
351*05b00f60SXin Li 		uint32_t tempa[4];	/* at least 16 bytes, maybe more */
352*05b00f60SXin Li 
353*05b00f60SXin Li 		memset((char *)tempa, 0, sizeof(tempa));
354*05b00f60SXin Li 		memcpy((char *)tempa, (const char *)fh, 14); /* ensure alignment */
355*05b00f60SXin Li 		fsidp->Fsid_dev.Minor = tempa[0] + (tempa[1]<<1);
356*05b00f60SXin Li 		fsidp->Fsid_dev.Major = tempa[2] + (tempa[3]<<1);
357*05b00f60SXin Li 		fsidp->fsid_code = 0;
358*05b00f60SXin Li 	    }
359*05b00f60SXin Li 
360*05b00f60SXin Li 	    /* VMS file ID is: (RVN, FidHi, FidLo) */
361*05b00f60SXin Li 	    *inop = (((uint32_t) GET_U_1(fhp + 26)) << 24) |
362*05b00f60SXin Li 		    (((uint32_t) GET_U_1(fhp + 27)) << 16) |
363*05b00f60SXin Li 		    (GET_LE_U_2(fhp + 22) << 0);
364*05b00f60SXin Li 
365*05b00f60SXin Li 	    /* Caller must save (and null-terminate?) this value */
366*05b00f60SXin Li 	    if (fsnamep)
367*05b00f60SXin Li 		*fsnamep = (const char *)(fhp + 1);
368*05b00f60SXin Li 
369*05b00f60SXin Li 	    if (osnamep)
370*05b00f60SXin Li 		*osnamep = "VMS";
371*05b00f60SXin Li 	    break;
372*05b00f60SXin Li 
373*05b00f60SXin Li 	case FHT_AIX32:
374*05b00f60SXin Li 	    fsidp->Fsid_dev.Minor = GET_BE_U_2(fhp + 2);
375*05b00f60SXin Li 	    fsidp->Fsid_dev.Major = GET_BE_U_2(fhp);
376*05b00f60SXin Li 	    fsidp->fsid_code = GET_BE_U_4(fhp + 4);
377*05b00f60SXin Li 
378*05b00f60SXin Li 	    *inop = GET_BE_U_4(fhp + 12);
379*05b00f60SXin Li 
380*05b00f60SXin Li 	    if (osnamep)
381*05b00f60SXin Li 		*osnamep = "AIX32";
382*05b00f60SXin Li 	    break;
383*05b00f60SXin Li 
384*05b00f60SXin Li 	case FHT_HPUX9:
385*05b00f60SXin Li 	    fsidp->Fsid_dev.Major = GET_U_1(fhp);
386*05b00f60SXin Li 	    temp = GET_BE_U_3(fhp + 1);
387*05b00f60SXin Li 	    fsidp->Fsid_dev.Minor = temp;
388*05b00f60SXin Li 	    fsidp->fsid_code = GET_BE_U_4(fhp + 4);
389*05b00f60SXin Li 
390*05b00f60SXin Li 	    *inop = GET_BE_U_4(fhp + 12);
391*05b00f60SXin Li 
392*05b00f60SXin Li 	    if (osnamep)
393*05b00f60SXin Li 		*osnamep = "HPUX9";
394*05b00f60SXin Li 	    break;
395*05b00f60SXin Li 
396*05b00f60SXin Li 	case FHT_UNKNOWN:
397*05b00f60SXin Li #ifdef DEBUG
398*05b00f60SXin Li 	    /* XXX debugging */
399*05b00f60SXin Li 	    for (i = 0; i < len*4; i++)
400*05b00f60SXin Li 		(void)fprintf(stderr, "%x.", GET_U_1(fhp + i));
401*05b00f60SXin Li 	    (void)fprintf(stderr, "\n");
402*05b00f60SXin Li #endif
403*05b00f60SXin Li 	    /* Save the actual handle, so it can be display with -u */
404*05b00f60SXin Li 	    for (i = 0; i < len*4 && i*2 < sizeof(fsidp->Opaque_Handle) - 1; i++)
405*05b00f60SXin Li 		(void)snprintf(&(fsidp->Opaque_Handle[i*2]), 3, "%.2X",
406*05b00f60SXin Li 			       GET_U_1(fhp + i));
407*05b00f60SXin Li 	    fsidp->Opaque_Handle[i*2] = '\0';
408*05b00f60SXin Li 
409*05b00f60SXin Li 	    /* XXX for now, give "bogus" values to aid debugging */
410*05b00f60SXin Li 	    fsidp->fsid_code = 0;
411*05b00f60SXin Li 	    fsidp->Fsid_dev.Minor = 257;
412*05b00f60SXin Li 	    fsidp->Fsid_dev.Major = 257;
413*05b00f60SXin Li 	    *inop = 1;
414*05b00f60SXin Li 
415*05b00f60SXin Li 	    /* display will show this string instead of (257,257) */
416*05b00f60SXin Li 	    if (fsnamep)
417*05b00f60SXin Li 		*fsnamep = "Unknown";
418*05b00f60SXin Li 
419*05b00f60SXin Li 	    if (osnamep)
420*05b00f60SXin Li 		*osnamep = "Unknown";
421*05b00f60SXin Li 	    break;
422*05b00f60SXin Li 
423*05b00f60SXin Li 	}
424*05b00f60SXin Li }
425*05b00f60SXin Li 
426*05b00f60SXin Li /*
427*05b00f60SXin Li  * Is this a VMS UCX file handle?
428*05b00f60SXin Li  *	Check for:
429*05b00f60SXin Li  *	(1) leading code byte	[XXX not yet]
430*05b00f60SXin Li  *	(2) followed by string of printing chars & spaces
431*05b00f60SXin Li  *	(3) followed by string of nulls
432*05b00f60SXin Li  */
433*05b00f60SXin Li static int
is_UCX(netdissect_options * ndo,const unsigned char * fhp,u_int len)434*05b00f60SXin Li is_UCX(netdissect_options *ndo, const unsigned char *fhp, u_int len)
435*05b00f60SXin Li {
436*05b00f60SXin Li 	u_int i;
437*05b00f60SXin Li 	int seen_null = 0;
438*05b00f60SXin Li 
439*05b00f60SXin Li 	/*
440*05b00f60SXin Li 	 * Require at least 28 bytes of file handle; it's variable-length
441*05b00f60SXin Li 	 * in NFSv3.  "len" is in units of 32-bit words, not bytes.
442*05b00f60SXin Li 	 */
443*05b00f60SXin Li 	if (len < 28/4)
444*05b00f60SXin Li 		return(0);
445*05b00f60SXin Li 
446*05b00f60SXin Li 	for (i = 1; i < 14; i++) {
447*05b00f60SXin Li 	    if (ND_ASCII_ISPRINT(GET_U_1(fhp + i))) {
448*05b00f60SXin Li 		if (seen_null)
449*05b00f60SXin Li 		   return(0);
450*05b00f60SXin Li 		else
451*05b00f60SXin Li 		   continue;
452*05b00f60SXin Li 	    }
453*05b00f60SXin Li 	    else if (GET_U_1(fhp + i) == 0) {
454*05b00f60SXin Li 		seen_null = 1;
455*05b00f60SXin Li 		continue;
456*05b00f60SXin Li 	    }
457*05b00f60SXin Li 	    else
458*05b00f60SXin Li 		return(0);
459*05b00f60SXin Li 	}
460*05b00f60SXin Li 
461*05b00f60SXin Li 	return(1);
462*05b00f60SXin Li }
463