xref: /freebsd/contrib/tcpdump/parsenfsfh.c (revision ee67461e)
14edb46e9SPaul Traina /*
2a1c2090eSBill Fenner  * Copyright (c) 1993, 1994 Jeffrey C. Mogul, Digital Equipment Corporation,
3a1c2090eSBill Fenner  * Western Research Laboratory. All rights reserved.
4a1c2090eSBill Fenner  * Copyright (c) 2001 Compaq Computer Corporation. All rights reserved.
5a1c2090eSBill Fenner  *
6a1c2090eSBill Fenner  *  Permission to use, copy, and modify this software and its
7a1c2090eSBill Fenner  *  documentation is hereby granted only under the following terms and
8a1c2090eSBill Fenner  *  conditions.  Both the above copyright notice and this permission
9a1c2090eSBill Fenner  *  notice must appear in all copies of the software, derivative works
10a1c2090eSBill Fenner  *  or modified versions, and any portions thereof, and both notices
11a1c2090eSBill Fenner  *  must appear in supporting documentation.
12a1c2090eSBill Fenner  *
13a1c2090eSBill Fenner  *  Redistribution and use in source and binary forms, with or without
14a1c2090eSBill Fenner  *  modification, are permitted provided that the following conditions
15a1c2090eSBill Fenner  *  are met:
16a1c2090eSBill Fenner  *    1. Redistributions of source code must retain the above copyright
17a1c2090eSBill Fenner  *    notice, this list of conditions and the following disclaimer.
18a1c2090eSBill Fenner  *    2. Redistributions in binary form must reproduce the above copyright
19a1c2090eSBill Fenner  *    notice, this list of conditions and the following disclaimer in
20a1c2090eSBill Fenner  *    the documentation and/or other materials provided with the
21a1c2090eSBill Fenner  *    distribution.
22a1c2090eSBill Fenner  *
23a1c2090eSBill Fenner  *  THE SOFTWARE IS PROVIDED "AS IS" AND COMPAQ COMPUTER CORPORATION
24a1c2090eSBill Fenner  *  DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
25a1c2090eSBill Fenner  *  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.   IN NO
26a1c2090eSBill Fenner  *  EVENT SHALL COMPAQ COMPUTER CORPORATION BE LIABLE FOR ANY
27a1c2090eSBill Fenner  *  SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
28a1c2090eSBill Fenner  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
29a1c2090eSBill Fenner  *  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
30a1c2090eSBill Fenner  *  OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
31a1c2090eSBill Fenner  *  SOFTWARE.
32a1c2090eSBill Fenner  */
33a1c2090eSBill Fenner 
34a1c2090eSBill Fenner /*
354edb46e9SPaul Traina  * parsenfsfh.c - portable parser for NFS file handles
364edb46e9SPaul Traina  *			uses all sorts of heuristics
374edb46e9SPaul Traina  *
384edb46e9SPaul Traina  * Jeffrey C. Mogul
394edb46e9SPaul Traina  * Digital Equipment Corporation
404edb46e9SPaul Traina  * Western Research Laboratory
414edb46e9SPaul Traina  */
424edb46e9SPaul Traina 
43a88113a8SBill Fenner #ifdef HAVE_CONFIG_H
44ee67461eSJoseph Mingrone #include <config.h>
452ebf6c05SBill Fenner #endif
462ebf6c05SBill Fenner 
47ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
484edb46e9SPaul Traina 
494edb46e9SPaul Traina #include <stdio.h>
504edb46e9SPaul Traina #include <string.h>
514edb46e9SPaul Traina 
52ee67461eSJoseph Mingrone #include "netdissect-ctype.h"
53ee67461eSJoseph Mingrone 
543340d773SGleb Smirnoff #include "netdissect.h"
55ee67461eSJoseph Mingrone #include "extract.h"
564edb46e9SPaul Traina #include "nfsfh.h"
574edb46e9SPaul Traina 
584edb46e9SPaul Traina /*
594edb46e9SPaul Traina  * This routine attempts to parse a file handle (in network byte order),
604edb46e9SPaul Traina  * using heuristics to guess what kind of format it is in.  See the
614edb46e9SPaul Traina  * file "fhandle_layouts" for a detailed description of the various
624edb46e9SPaul Traina  * patterns we know about.
634edb46e9SPaul Traina  *
644edb46e9SPaul Traina  * The file handle is parsed into our internal representation of a
654edb46e9SPaul Traina  * file-system id, and an internal representation of an inode-number.
664edb46e9SPaul Traina  */
674edb46e9SPaul Traina 
684edb46e9SPaul Traina #define	FHT_UNKNOWN	0
694edb46e9SPaul Traina #define	FHT_AUSPEX	1
704edb46e9SPaul Traina #define	FHT_DECOSF	2
714edb46e9SPaul Traina #define	FHT_IRIX4	3
724edb46e9SPaul Traina #define	FHT_IRIX5	4
734edb46e9SPaul Traina #define	FHT_SUNOS3	5
744edb46e9SPaul Traina #define	FHT_SUNOS4	6
754edb46e9SPaul Traina #define	FHT_ULTRIX	7
764edb46e9SPaul Traina #define	FHT_VMSUCX	8
774edb46e9SPaul Traina #define	FHT_SUNOS5	9
784edb46e9SPaul Traina #define	FHT_AIX32	10
794edb46e9SPaul Traina #define	FHT_HPUX9	11
80abf25193SMax Laier #define	FHT_BSD44	12
814edb46e9SPaul Traina 
82ee67461eSJoseph Mingrone static int is_UCX(netdissect_options *, const unsigned char *, u_int);
834edb46e9SPaul Traina 
844edb46e9SPaul Traina 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)85ee67461eSJoseph Mingrone Parse_fh(netdissect_options *ndo, const unsigned char *fh, u_int len,
86ee67461eSJoseph Mingrone 	 my_fsid *fsidp, uint32_t *inop,
873c602fabSXin LI 	 const char **osnamep, /* if non-NULL, return OS name here */
883c602fabSXin LI 	 const char **fsnamep, /* if non-NULL, return server fs name here (for VMS) */
893c602fabSXin LI 	 int ourself)	/* true if file handle was generated on this host */
904edb46e9SPaul Traina {
91ee67461eSJoseph Mingrone 	const unsigned char *fhp = fh;
923c602fabSXin LI 	uint32_t temp;
934edb46e9SPaul Traina 	int fhtype = FHT_UNKNOWN;
943340d773SGleb Smirnoff 	u_int i;
954edb46e9SPaul Traina 
963340d773SGleb Smirnoff 	/*
973340d773SGleb Smirnoff 	 * Require at least 16 bytes of file handle; it's variable-length
983340d773SGleb Smirnoff 	 * in NFSv3.  "len" is in units of 32-bit words, not bytes.
993340d773SGleb Smirnoff 	 */
1003340d773SGleb Smirnoff 	if (len < 16/4)
1013340d773SGleb Smirnoff 		fhtype = FHT_UNKNOWN;
1023340d773SGleb Smirnoff 	else {
1034edb46e9SPaul Traina 		if (ourself) {
1044edb46e9SPaul Traina 		    /* File handle generated on this host, no need for guessing */
1054edb46e9SPaul Traina #if	defined(IRIX40)
1064edb46e9SPaul Traina 		    fhtype = FHT_IRIX4;
1074edb46e9SPaul Traina #endif
1084edb46e9SPaul Traina #if	defined(IRIX50)
1094edb46e9SPaul Traina 		    fhtype = FHT_IRIX5;
1104edb46e9SPaul Traina #endif
1114edb46e9SPaul Traina #if	defined(IRIX51)
1124edb46e9SPaul Traina 		    fhtype = FHT_IRIX5;
1134edb46e9SPaul Traina #endif
1144edb46e9SPaul Traina #if	defined(SUNOS4)
1154edb46e9SPaul Traina 		    fhtype = FHT_SUNOS4;
1164edb46e9SPaul Traina #endif
1174edb46e9SPaul Traina #if	defined(SUNOS5)
1184edb46e9SPaul Traina 		    fhtype = FHT_SUNOS5;
1194edb46e9SPaul Traina #endif
1204edb46e9SPaul Traina #if	defined(ultrix)
1214edb46e9SPaul Traina 		    fhtype = FHT_ULTRIX;
1224edb46e9SPaul Traina #endif
1234edb46e9SPaul Traina #if	defined(__osf__)
1244edb46e9SPaul Traina 		    fhtype = FHT_DECOSF;
1254edb46e9SPaul Traina #endif
126abf25193SMax Laier #if	defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) \
127abf25193SMax Laier      || defined(__OpenBSD__)
128abf25193SMax Laier 		    fhtype = FHT_BSD44;
129abf25193SMax Laier #endif
1304edb46e9SPaul Traina 		}
1314edb46e9SPaul Traina 		/*
1324edb46e9SPaul Traina 		 * This is basically a big decision tree
1334edb46e9SPaul Traina 		 */
134ee67461eSJoseph Mingrone 		else if ((GET_U_1(fhp) == 0) && (GET_U_1(fhp + 1) == 0)) {
1354edb46e9SPaul Traina 		    /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */
1364edb46e9SPaul Traina 		    /* probably rules out HP-UX, AIX unless they allow major=0 */
137ee67461eSJoseph Mingrone 		    if ((GET_U_1(fhp + 2) == 0) && (GET_U_1(fhp + 3) == 0)) {
1384edb46e9SPaul Traina 			/* bytes[2,3] == (0,0); must be Auspex */
1394edb46e9SPaul Traina 			/* XXX or could be Ultrix+MASSBUS "hp" disk? */
1404edb46e9SPaul Traina 			fhtype = FHT_AUSPEX;
1414edb46e9SPaul Traina 		    }
1424edb46e9SPaul Traina 		    else {
1434edb46e9SPaul Traina 			/*
1444edb46e9SPaul Traina 			 * bytes[2,3] != (0,0); rules out Auspex, could be
1454edb46e9SPaul Traina 			 * DECOSF, SUNOS4, or IRIX4
1464edb46e9SPaul Traina 			 */
147ee67461eSJoseph Mingrone 			if ((GET_U_1(fhp + 4) != 0) && (GET_U_1(fhp + 5) == 0) &&
148ee67461eSJoseph Mingrone 				(GET_U_1(fhp + 8) == 12) && (GET_U_1(fhp + 9) == 0)) {
1494edb46e9SPaul Traina 			    /* seems to be DECOSF, with minor == 0 */
1504edb46e9SPaul Traina 			    fhtype = FHT_DECOSF;
1514edb46e9SPaul Traina 			}
1524edb46e9SPaul Traina 			else {
1534edb46e9SPaul Traina 			    /* could be SUNOS4 or IRIX4 */
1544edb46e9SPaul Traina 			    /* XXX the test of fhp[5] == 8 could be wrong */
155ee67461eSJoseph Mingrone 			    if ((GET_U_1(fhp + 4) == 0) && (GET_U_1(fhp + 5) == 8) && (GET_U_1(fhp + 6) == 0) &&
156ee67461eSJoseph Mingrone 			        (GET_U_1(fhp + 7) == 0)) {
1574edb46e9SPaul Traina 				/* looks like a length, not a file system typecode */
1584edb46e9SPaul Traina 				fhtype = FHT_IRIX4;
1594edb46e9SPaul Traina 			    }
1604edb46e9SPaul Traina 			    else {
1614edb46e9SPaul Traina 				/* by elimination */
1624edb46e9SPaul Traina 				fhtype = FHT_SUNOS4;
1634edb46e9SPaul Traina 			    }
1644edb46e9SPaul Traina 			}
1654edb46e9SPaul Traina 		    }
1664edb46e9SPaul Traina 		}
1674edb46e9SPaul Traina 		else {
1684edb46e9SPaul Traina 		    /*
1694edb46e9SPaul Traina 		     * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4
1704edb46e9SPaul Traina 		     * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5
1714edb46e9SPaul Traina 		     * could be AIX, HP-UX
1724edb46e9SPaul Traina 		     */
173ee67461eSJoseph Mingrone 		    if ((GET_U_1(fhp + 2) == 0) && (GET_U_1(fhp + 3) == 0)) {
1744edb46e9SPaul Traina 			/*
1754edb46e9SPaul Traina 			 * bytes[2,3] == (0,0); rules out OSF, probably not UCX
1764edb46e9SPaul Traina 			 * (unless the exported device name is just one letter!),
1774edb46e9SPaul Traina 			 * could be Ultrix, IRIX5, AIX, or SUNOS5
1784edb46e9SPaul Traina 			 * might be HP-UX (depends on their values for minor devs)
1794edb46e9SPaul Traina 			 */
180ee67461eSJoseph Mingrone 			if ((GET_U_1(fhp + 6) == 0) && (GET_U_1(fhp + 7) == 0)) {
181abf25193SMax Laier 			    fhtype = FHT_BSD44;
182abf25193SMax Laier 			}
1834edb46e9SPaul Traina 			/*XXX we probably only need to test of these two bytes */
184ee67461eSJoseph Mingrone 			else if ((len >= 24/4) && (GET_U_1(fhp + 21) == 0) && (GET_U_1(fhp + 23) == 0)) {
1854edb46e9SPaul Traina 			    fhtype = FHT_ULTRIX;
1864edb46e9SPaul Traina 			}
1874edb46e9SPaul Traina 			else {
1884edb46e9SPaul Traina 			    /* Could be SUNOS5/IRIX5, maybe AIX */
1894edb46e9SPaul Traina 			    /* XXX no obvious difference between SUNOS5 and IRIX5 */
190ee67461eSJoseph Mingrone 			    if (GET_U_1(fhp + 9) == 10)
1914edb46e9SPaul Traina 				fhtype = FHT_SUNOS5;
1924edb46e9SPaul Traina 			    /* XXX what about AIX? */
1934edb46e9SPaul Traina 			}
1944edb46e9SPaul Traina 		    }
1954edb46e9SPaul Traina 		    else {
1964edb46e9SPaul Traina 			/*
1974edb46e9SPaul Traina 			 * bytes[2,3] != (0,0); rules out Ultrix, could be
1984edb46e9SPaul Traina 			 * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, or UCX
1994edb46e9SPaul Traina 			 */
200ee67461eSJoseph Mingrone 			if ((GET_U_1(fhp + 8) == 12) && (GET_U_1(fhp + 9) == 0)) {
2014edb46e9SPaul Traina 			    fhtype = FHT_DECOSF;
2024edb46e9SPaul Traina 			}
203ee67461eSJoseph Mingrone 			else if ((GET_U_1(fhp + 8) == 0) && (GET_U_1(fhp + 9) == 10)) {
2044edb46e9SPaul Traina 			    /* could be SUNOS5/IRIX5, AIX, HP-UX */
205ee67461eSJoseph Mingrone 			    if ((GET_U_1(fhp + 7) == 0) && (GET_U_1(fhp + 6) == 0) &&
206ee67461eSJoseph Mingrone 				(GET_U_1(fhp + 5) == 0) && (GET_U_1(fhp + 4) == 0)) {
2074edb46e9SPaul Traina 				/* XXX is this always true of HP-UX? */
2084edb46e9SPaul Traina 				fhtype = FHT_HPUX9;
2094edb46e9SPaul Traina 			    }
210ee67461eSJoseph Mingrone 			    else if (GET_U_1(fhp + 7) == 2) {
2114edb46e9SPaul Traina 				/* This would be MNT_NFS on AIX, which is impossible */
2124edb46e9SPaul Traina 				fhtype = FHT_SUNOS5;	/* or maybe IRIX5 */
2134edb46e9SPaul Traina 			    }
2144edb46e9SPaul Traina 			    else {
2154edb46e9SPaul Traina 				/*
2164edb46e9SPaul Traina 				 * XXX Could be SUNOS5/IRIX5 or AIX.  I don't
2174edb46e9SPaul Traina 				 * XXX see any way to disambiguate these, so
2184edb46e9SPaul Traina 				 * XXX I'm going with the more likely guess.
2194edb46e9SPaul Traina 				 * XXX Sorry, Big Blue.
2204edb46e9SPaul Traina 				 */
2214edb46e9SPaul Traina 				fhtype = FHT_SUNOS5;	/* or maybe IRIX5 */
2224edb46e9SPaul Traina 			    }
2234edb46e9SPaul Traina 		        }
2244edb46e9SPaul Traina 			else {
225ee67461eSJoseph Mingrone 			    if (is_UCX(ndo, fhp, len)) {
2264edb46e9SPaul Traina 				fhtype = FHT_VMSUCX;
2274edb46e9SPaul Traina 			    }
2284edb46e9SPaul Traina 			    else {
2294edb46e9SPaul Traina 				fhtype = FHT_UNKNOWN;
2304edb46e9SPaul Traina 			    }
2314edb46e9SPaul Traina 			}
2324edb46e9SPaul Traina 		    }
2334edb46e9SPaul Traina 		}
2343340d773SGleb Smirnoff 	}
2354edb46e9SPaul Traina 
2364edb46e9SPaul Traina 	/* XXX still needs to handle SUNOS3 */
2374edb46e9SPaul Traina 
2384edb46e9SPaul Traina 	switch (fhtype) {
2394edb46e9SPaul Traina 	case FHT_AUSPEX:
240ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Minor = GET_U_1(fhp + 7);
241ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Major = GET_U_1(fhp + 6);
2424edb46e9SPaul Traina 	    fsidp->fsid_code = 0;
2434edb46e9SPaul Traina 
244ee67461eSJoseph Mingrone 	    *inop = GET_BE_U_4(fhp + 12);
2454edb46e9SPaul Traina 
2464edb46e9SPaul Traina 	    if (osnamep)
2474edb46e9SPaul Traina 		*osnamep = "Auspex";
2484edb46e9SPaul Traina 	    break;
2494edb46e9SPaul Traina 
250abf25193SMax Laier 	case FHT_BSD44:
251ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Minor = GET_U_1(fhp);
252ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Major = GET_U_1(fhp + 1);
253abf25193SMax Laier 	    fsidp->fsid_code = 0;
254abf25193SMax Laier 
255ee67461eSJoseph Mingrone 	    *inop = GET_LE_U_4(fhp + 12);
256abf25193SMax Laier 
257abf25193SMax Laier 	    if (osnamep)
258abf25193SMax Laier 		*osnamep = "BSD 4.4";
259abf25193SMax Laier 	    break;
260abf25193SMax Laier 
2614edb46e9SPaul Traina 	case FHT_DECOSF:
262ee67461eSJoseph Mingrone 	    fsidp->fsid_code = GET_LE_U_4(fhp + 4);
2634edb46e9SPaul Traina 			/* XXX could ignore 3 high-order bytes */
2644edb46e9SPaul Traina 
265ee67461eSJoseph Mingrone 	    temp = GET_LE_U_4(fhp);
2662ebf6c05SBill Fenner 	    fsidp->Fsid_dev.Minor = temp & 0xFFFFF;
2672ebf6c05SBill Fenner 	    fsidp->Fsid_dev.Major = (temp>>20) & 0xFFF;
2684edb46e9SPaul Traina 
269ee67461eSJoseph Mingrone 	    *inop = GET_LE_U_4(fhp + 12);
2704edb46e9SPaul Traina 	    if (osnamep)
2714edb46e9SPaul Traina 		*osnamep = "OSF";
2724edb46e9SPaul Traina 	    break;
2734edb46e9SPaul Traina 
2744edb46e9SPaul Traina 	case FHT_IRIX4:
275ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Minor = GET_U_1(fhp + 3);
276ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Major = GET_U_1(fhp + 2);
2774edb46e9SPaul Traina 	    fsidp->fsid_code = 0;
2784edb46e9SPaul Traina 
279ee67461eSJoseph Mingrone 	    *inop = GET_BE_U_4(fhp + 8);
2804edb46e9SPaul Traina 
2814edb46e9SPaul Traina 	    if (osnamep)
2824edb46e9SPaul Traina 		*osnamep = "IRIX4";
2834edb46e9SPaul Traina 	    break;
2844edb46e9SPaul Traina 
2854edb46e9SPaul Traina 	case FHT_IRIX5:
286ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Minor = GET_BE_U_2(fhp + 2);
287ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Major = GET_BE_U_2(fhp);
288ee67461eSJoseph Mingrone 	    fsidp->fsid_code = GET_BE_U_4(fhp + 4);
2894edb46e9SPaul Traina 
290ee67461eSJoseph Mingrone 	    *inop = GET_BE_U_4(fhp + 12);
2914edb46e9SPaul Traina 
2924edb46e9SPaul Traina 	    if (osnamep)
2934edb46e9SPaul Traina 		*osnamep = "IRIX5";
2944edb46e9SPaul Traina 	    break;
2954edb46e9SPaul Traina 
296abf25193SMax Laier #ifdef notdef
2974edb46e9SPaul Traina 	case FHT_SUNOS3:
298abf25193SMax Laier 	    /*
299abf25193SMax Laier 	     * XXX - none of the heuristics above return this.
300abf25193SMax Laier 	     * Are there any SunOS 3.x systems around to care about?
301abf25193SMax Laier 	     */
3024edb46e9SPaul Traina 	    if (osnamep)
3034edb46e9SPaul Traina 		*osnamep = "SUNOS3";
3044edb46e9SPaul Traina 	    break;
305abf25193SMax Laier #endif
3064edb46e9SPaul Traina 
3074edb46e9SPaul Traina 	case FHT_SUNOS4:
308ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Minor = GET_U_1(fhp + 3);
309ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Major = GET_U_1(fhp + 2);
310ee67461eSJoseph Mingrone 	    fsidp->fsid_code = GET_BE_U_4(fhp + 4);
3114edb46e9SPaul Traina 
312ee67461eSJoseph Mingrone 	    *inop = GET_BE_U_4(fhp + 12);
3134edb46e9SPaul Traina 
3144edb46e9SPaul Traina 	    if (osnamep)
3154edb46e9SPaul Traina 		*osnamep = "SUNOS4";
3164edb46e9SPaul Traina 	    break;
3174edb46e9SPaul Traina 
3184edb46e9SPaul Traina 	case FHT_SUNOS5:
319ee67461eSJoseph Mingrone 	    temp = GET_BE_U_2(fhp);
3202ebf6c05SBill Fenner 	    fsidp->Fsid_dev.Major = (temp>>2) &  0x3FFF;
321ee67461eSJoseph Mingrone 	    temp = GET_BE_U_3(fhp + 1);
3222ebf6c05SBill Fenner 	    fsidp->Fsid_dev.Minor = temp & 0x3FFFF;
323ee67461eSJoseph Mingrone 	    fsidp->fsid_code = GET_BE_U_4(fhp + 4);
3244edb46e9SPaul Traina 
325ee67461eSJoseph Mingrone 	    *inop = GET_BE_U_4(fhp + 12);
3264edb46e9SPaul Traina 
3274edb46e9SPaul Traina 	    if (osnamep)
3284edb46e9SPaul Traina 		*osnamep = "SUNOS5";
3294edb46e9SPaul Traina 	    break;
3304edb46e9SPaul Traina 
3314edb46e9SPaul Traina 	case FHT_ULTRIX:
3324edb46e9SPaul Traina 	    fsidp->fsid_code = 0;
333ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Minor = GET_U_1(fhp);
334ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Major = GET_U_1(fhp + 1);
3354edb46e9SPaul Traina 
336ee67461eSJoseph Mingrone 	    temp = GET_LE_U_4(fhp + 4);
3374edb46e9SPaul Traina 	    *inop = temp;
3384edb46e9SPaul Traina 	    if (osnamep)
3394edb46e9SPaul Traina 		*osnamep = "Ultrix";
3404edb46e9SPaul Traina 	    break;
3414edb46e9SPaul Traina 
3424edb46e9SPaul Traina 	case FHT_VMSUCX:
3434edb46e9SPaul Traina 	    /* No numeric file system ID, so hash on the device-name */
3444edb46e9SPaul Traina 	    if (sizeof(*fsidp) >= 14) {
3454edb46e9SPaul Traina 		if (sizeof(*fsidp) > 14)
3464edb46e9SPaul Traina 		    memset((char *)fsidp, 0, sizeof(*fsidp));
347699fc314SBill Fenner 		/* just use the whole thing */
3483340d773SGleb Smirnoff 		memcpy((char *)fsidp, (const char *)fh, 14);
3494edb46e9SPaul Traina 	    }
3504edb46e9SPaul Traina 	    else {
3513c602fabSXin LI 		uint32_t tempa[4];	/* at least 16 bytes, maybe more */
3524edb46e9SPaul Traina 
3534edb46e9SPaul Traina 		memset((char *)tempa, 0, sizeof(tempa));
3543340d773SGleb Smirnoff 		memcpy((char *)tempa, (const char *)fh, 14); /* ensure alignment */
3552ebf6c05SBill Fenner 		fsidp->Fsid_dev.Minor = tempa[0] + (tempa[1]<<1);
3562ebf6c05SBill Fenner 		fsidp->Fsid_dev.Major = tempa[2] + (tempa[3]<<1);
3574edb46e9SPaul Traina 		fsidp->fsid_code = 0;
3584edb46e9SPaul Traina 	    }
3594edb46e9SPaul Traina 
3604edb46e9SPaul Traina 	    /* VMS file ID is: (RVN, FidHi, FidLo) */
361ee67461eSJoseph Mingrone 	    *inop = (((uint32_t) GET_U_1(fhp + 26)) << 24) |
362ee67461eSJoseph Mingrone 		    (((uint32_t) GET_U_1(fhp + 27)) << 16) |
363ee67461eSJoseph Mingrone 		    (GET_LE_U_2(fhp + 22) << 0);
3644edb46e9SPaul Traina 
3654edb46e9SPaul Traina 	    /* Caller must save (and null-terminate?) this value */
3664edb46e9SPaul Traina 	    if (fsnamep)
367ee67461eSJoseph Mingrone 		*fsnamep = (const char *)(fhp + 1);
3684edb46e9SPaul Traina 
3694edb46e9SPaul Traina 	    if (osnamep)
3704edb46e9SPaul Traina 		*osnamep = "VMS";
3714edb46e9SPaul Traina 	    break;
3724edb46e9SPaul Traina 
3734edb46e9SPaul Traina 	case FHT_AIX32:
374ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Minor = GET_BE_U_2(fhp + 2);
375ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Major = GET_BE_U_2(fhp);
376ee67461eSJoseph Mingrone 	    fsidp->fsid_code = GET_BE_U_4(fhp + 4);
3774edb46e9SPaul Traina 
378ee67461eSJoseph Mingrone 	    *inop = GET_BE_U_4(fhp + 12);
3794edb46e9SPaul Traina 
3804edb46e9SPaul Traina 	    if (osnamep)
3814edb46e9SPaul Traina 		*osnamep = "AIX32";
3824edb46e9SPaul Traina 	    break;
3834edb46e9SPaul Traina 
3844edb46e9SPaul Traina 	case FHT_HPUX9:
385ee67461eSJoseph Mingrone 	    fsidp->Fsid_dev.Major = GET_U_1(fhp);
386ee67461eSJoseph Mingrone 	    temp = GET_BE_U_3(fhp + 1);
3872ebf6c05SBill Fenner 	    fsidp->Fsid_dev.Minor = temp;
388ee67461eSJoseph Mingrone 	    fsidp->fsid_code = GET_BE_U_4(fhp + 4);
3894edb46e9SPaul Traina 
390ee67461eSJoseph Mingrone 	    *inop = GET_BE_U_4(fhp + 12);
3914edb46e9SPaul Traina 
3924edb46e9SPaul Traina 	    if (osnamep)
3934edb46e9SPaul Traina 		*osnamep = "HPUX9";
3944edb46e9SPaul Traina 	    break;
3954edb46e9SPaul Traina 
3964edb46e9SPaul Traina 	case FHT_UNKNOWN:
3974edb46e9SPaul Traina #ifdef DEBUG
3984edb46e9SPaul Traina 	    /* XXX debugging */
3993340d773SGleb Smirnoff 	    for (i = 0; i < len*4; i++)
400ee67461eSJoseph Mingrone 		(void)fprintf(stderr, "%x.", GET_U_1(fhp + i));
4014edb46e9SPaul Traina 	    (void)fprintf(stderr, "\n");
4024edb46e9SPaul Traina #endif
403943ee2b1SBill Fenner 	    /* Save the actual handle, so it can be display with -u */
4043340d773SGleb Smirnoff 	    for (i = 0; i < len*4 && i*2 < sizeof(fsidp->Opaque_Handle) - 1; i++)
405ee67461eSJoseph Mingrone 		(void)snprintf(&(fsidp->Opaque_Handle[i*2]), 3, "%.2X",
406ee67461eSJoseph Mingrone 			       GET_U_1(fhp + i));
4073340d773SGleb Smirnoff 	    fsidp->Opaque_Handle[i*2] = '\0';
408943ee2b1SBill Fenner 
409a1c2090eSBill Fenner 	    /* XXX for now, give "bogus" values to aid debugging */
4104edb46e9SPaul Traina 	    fsidp->fsid_code = 0;
4112ebf6c05SBill Fenner 	    fsidp->Fsid_dev.Minor = 257;
4122ebf6c05SBill Fenner 	    fsidp->Fsid_dev.Major = 257;
4134edb46e9SPaul Traina 	    *inop = 1;
4144edb46e9SPaul Traina 
4154edb46e9SPaul Traina 	    /* display will show this string instead of (257,257) */
4164edb46e9SPaul Traina 	    if (fsnamep)
4174edb46e9SPaul Traina 		*fsnamep = "Unknown";
4184edb46e9SPaul Traina 
4194edb46e9SPaul Traina 	    if (osnamep)
4204edb46e9SPaul Traina 		*osnamep = "Unknown";
4214edb46e9SPaul Traina 	    break;
4224edb46e9SPaul Traina 
4234edb46e9SPaul Traina 	}
4244edb46e9SPaul Traina }
4254edb46e9SPaul Traina 
4264edb46e9SPaul Traina /*
4274edb46e9SPaul Traina  * Is this a VMS UCX file handle?
4284edb46e9SPaul Traina  *	Check for:
4294edb46e9SPaul Traina  *	(1) leading code byte	[XXX not yet]
4304edb46e9SPaul Traina  *	(2) followed by string of printing chars & spaces
4314edb46e9SPaul Traina  *	(3) followed by string of nulls
4324edb46e9SPaul Traina  */
4334edb46e9SPaul Traina static int
is_UCX(netdissect_options * ndo,const unsigned char * fhp,u_int len)434ee67461eSJoseph Mingrone is_UCX(netdissect_options *ndo, const unsigned char *fhp, u_int len)
4354edb46e9SPaul Traina {
436ee67461eSJoseph Mingrone 	u_int i;
4374edb46e9SPaul Traina 	int seen_null = 0;
4384edb46e9SPaul Traina 
4393340d773SGleb Smirnoff 	/*
4403340d773SGleb Smirnoff 	 * Require at least 28 bytes of file handle; it's variable-length
4413340d773SGleb Smirnoff 	 * in NFSv3.  "len" is in units of 32-bit words, not bytes.
4423340d773SGleb Smirnoff 	 */
4433340d773SGleb Smirnoff 	if (len < 28/4)
4443340d773SGleb Smirnoff 		return(0);
4453340d773SGleb Smirnoff 
4464edb46e9SPaul Traina 	for (i = 1; i < 14; i++) {
447ee67461eSJoseph Mingrone 	    if (ND_ASCII_ISPRINT(GET_U_1(fhp + i))) {
4484edb46e9SPaul Traina 		if (seen_null)
4494edb46e9SPaul Traina 		   return(0);
4504edb46e9SPaul Traina 		else
4514edb46e9SPaul Traina 		   continue;
4524edb46e9SPaul Traina 	    }
453ee67461eSJoseph Mingrone 	    else if (GET_U_1(fhp + i) == 0) {
4544edb46e9SPaul Traina 		seen_null = 1;
4554edb46e9SPaul Traina 		continue;
4564edb46e9SPaul Traina 	    }
4574edb46e9SPaul Traina 	    else
4584edb46e9SPaul Traina 		return(0);
4594edb46e9SPaul Traina 	}
4604edb46e9SPaul Traina 
4614edb46e9SPaul Traina 	return(1);
4624edb46e9SPaul Traina }
463