--- tcpdump-3.4/parsenfsfh.c.orig Thu Mar 18 09:39:14 1999 +++ tcpdump-3.4/parsenfsfh.c Thu Mar 18 10:06:52 1999 @@ -47,6 +47,8 @@ #define FHT_SUNOS5 9 #define FHT_AIX32 10 #define FHT_HPUX9 11 +#define FHT_LINUX_LE 12 /* Linux puts fh components in server byteorder */ +#define FHT_LINUX_BE 13 #ifdef ultrix /* Nasty hack to keep the Ultrix C compiler from emitting bogus warnings */ @@ -88,6 +90,7 @@ register unsigned char *fhp = (unsigned char *)fh; u_int32_t temp; int fhtype = FHT_UNKNOWN; + int endian = 1; if (ourself) { /* File handle generated on this host, no need for guessing */ @@ -112,6 +115,12 @@ #if defined(__osf__) fhtype = FHT_DECOSF; #endif +#if defined(__linux__) + if (*(char *)&endian) + fhtype = FHT_LINUX_LE; + else + fhtype = FHT_LINUX_BE; +#endif } /* * This is basically a big decision tree @@ -119,6 +128,7 @@ else if ((fhp[0] == 0) && (fhp[1] == 0)) { /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */ /* probably rules out HP-UX, AIX unless they allow major=0 */ + /* probably rules out Linux, unless there's a NULL dentry */ if ((fhp[2] == 0) && (fhp[3] == 0)) { /* bytes[2,3] == (0,0); must be Auspex */ /* XXX or could be Ultrix+MASSBUS "hp" disk? */ @@ -153,9 +163,17 @@ /* * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4 * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5 - * could be AIX, HP-UX + * could be AIX, HP-UX, Linux */ - if ((fhp[2] == 0) && (fhp[3] == 0)) { + + /* This magic is a definite hit on a new-style Linux FH */ + if (fhp[0] == 0xfe && fhp[1] == 0xeb && + fhp[2] == 0xba && fhp[3] == 0xca) + fhtype = FHT_LINUX_BE; + else if (fhp[0] == 0xca && fhp[1] == 0xba && + fhp[2] == 0xeb && fhp[3] == 0xfe) + fhtype = FHT_LINUX_LE; + else if ((fhp[2] == 0) && (fhp[3] == 0)) { /* * bytes[2,3] == (0,0); rules out OSF, probably not UCX * (unless the exported device name is just one letter!), @@ -217,6 +235,23 @@ /* XXX still needs to handle SUNOS3 */ switch (fhtype) { + case FHT_LINUX_LE: + case FHT_LINUX_BE: + if (fhtype == FHT_LINUX_LE) { + *inop = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); + fsidp->Fsid_dev.Minor = fhp[16]; + fsidp->Fsid_dev.Major = fhp[17]; + } else { + *inop = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + fsidp->Fsid_dev.Minor = fhp[19]; + fsidp->Fsid_dev.Major = fhp[18]; + } + + if (osnamep) + *osnamep = "Linux"; + + break; + case FHT_AUSPEX: fsidp->Fsid_dev.Minor = fhp[7]; fsidp->Fsid_dev.Major = fhp[6];