PageRenderTime 50ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/parsenfsfh.c

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