getpib.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. /*====================================================================*
  2. *
  3. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  4. *
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or
  8. * without modification, are permitted (subject to the limitations
  9. * in the disclaimer below) provided that the following conditions
  10. * are met:
  11. *
  12. * * Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * * Redistributions in binary form must reproduce the above
  16. * copyright notice, this list of conditions and the following
  17. * disclaimer in the documentation and/or other materials
  18. * provided with the distribution.
  19. *
  20. * * Neither the name of Qualcomm Atheros nor the names of
  21. * its contributors may be used to endorse or promote products
  22. * derived from this software without specific prior written
  23. * permission.
  24. *
  25. * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
  26. * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE
  27. * COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
  28. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  29. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  30. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  31. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  32. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  33. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  34. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  36. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  37. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  38. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. *--------------------------------------------------------------------*/
  41. /*====================================================================*
  42. *
  43. * getpib.c - PIB Data Extractor
  44. *
  45. * Contributor(s):
  46. * Charles Maier
  47. *
  48. *--------------------------------------------------------------------*/
  49. /*====================================================================*
  50. * system header files;
  51. *--------------------------------------------------------------------*/
  52. #include <unistd.h>
  53. #include <stdlib.h>
  54. #include <limits.h>
  55. #include <string.h>
  56. #include <ctype.h>
  57. #include <inttypes.h>
  58. /*====================================================================*
  59. * custom header files;
  60. *--------------------------------------------------------------------*/
  61. #include "../tools/getoptv.h"
  62. #include "../tools/memory.h"
  63. #include "../tools/number.h"
  64. #include "../tools/error.h"
  65. #include "../tools/types.h"
  66. #include "../tools/flags.h"
  67. #include "../tools/files.h"
  68. #include "../pib/pib.h"
  69. #include "../nvm/nvm.h"
  70. /*====================================================================*
  71. * custom source files;
  72. *--------------------------------------------------------------------*/
  73. #ifndef MAKEFILE
  74. #include "../tools/getoptv.c"
  75. #include "../tools/putoptv.c"
  76. #include "../tools/version.c"
  77. #include "../tools/uintspec.c"
  78. #include "../tools/basespec.c"
  79. #include "../tools/todigit.c"
  80. #include "../tools/hexout.c"
  81. #include "../tools/error.c"
  82. #include "../tools/checksum32.c"
  83. #include "../tools/fdchecksum32.c"
  84. #endif
  85. #ifndef MAKEFILE
  86. #include "../nvm/nvmseek2.c"
  87. #endif
  88. /*====================================================================*
  89. * constants;
  90. *--------------------------------------------------------------------*/
  91. #define GETPIB_COMMA ' '
  92. #define GETPIB_TOOBIG "object '%s' exceeds extent of " SIZE_T_SPEC " bytes"
  93. #define GETPIB_NOSIZE "object '%s' has no length"
  94. #define GETPIB_VERBOSE (1 << 0)
  95. #define GETPIB_SILENCE (1 << 1)
  96. #define GETPIB_NEWLINE (1 << 2)
  97. /*====================================================================*
  98. *
  99. * void getmemory (byte const * memory, size_t extent, char const * object, size_t length);
  100. *
  101. *--------------------------------------------------------------------*/
  102. static void getmemory (byte const * memory, size_t extent, char const * object, size_t length)
  103. {
  104. if (length > extent)
  105. {
  106. error (1, ECANCELED, GETPIB_TOOBIG, object, length);
  107. }
  108. hexout (memory, length, ':', '\0', stdout);
  109. return;
  110. }
  111. /*====================================================================*
  112. *
  113. * void getstring (byte const * memory, size_t extent, char const * object, size_t length);
  114. *
  115. *--------------------------------------------------------------------*/
  116. static void getstring (byte const * memory, size_t extent, char const * object, size_t length)
  117. {
  118. char const * string = (char const *) (memory);
  119. if (length > extent)
  120. {
  121. error (1, ECANCELED, GETPIB_TOOBIG, object, length);
  122. }
  123. while (isprint (* string) && (length--))
  124. {
  125. putc (* string++, stdout);
  126. }
  127. return;
  128. }
  129. /*====================================================================*
  130. *
  131. * void snatch (int argc, char const * argv [], byte const * memory, size_t extent, char comma);
  132. *
  133. * extract and print the specified data objects from memory; comma
  134. * delimits consecutive objects on output;
  135. *
  136. *--------------------------------------------------------------------*/
  137. static void snatch (int argc, char const * argv [], byte const * memory, size_t extent, char comma)
  138. {
  139. size_t length = 0;
  140. size_t offset = 0;
  141. if (! (argc) || ! (* argv))
  142. {
  143. error (1, ECANCELED, "Need an offset");
  144. }
  145. offset = (size_t) (basespec (* argv, 16, sizeof (uint32_t)));
  146. if (offset > extent)
  147. {
  148. error (1, ECANCELED, "offset " SIZE_T_SPEC " exceeds extent of " SIZE_T_SPEC " bytes", offset, extent);
  149. }
  150. memory += offset;
  151. extent -= offset;
  152. argc--;
  153. argv++;
  154. while ((argc) && (* argv))
  155. {
  156. char const * object = * argv;
  157. argc--;
  158. argv++;
  159. if (! strcmp (object, "byte"))
  160. {
  161. uint8_t * number = (uint8_t *) (memory);
  162. if (sizeof (* number) > extent)
  163. {
  164. error (1, ECANCELED, GETPIB_TOOBIG, object, extent);
  165. }
  166. printf ("%" PRIu8, * number);
  167. memory += sizeof (* number);
  168. extent -= sizeof (* number);
  169. }
  170. else if (! strcmp (object, "word"))
  171. {
  172. uint16_t * number = (uint16_t *) (memory);
  173. if (sizeof (* number) > extent)
  174. {
  175. error (1, ECANCELED, GETPIB_TOOBIG, object, extent);
  176. }
  177. printf ("%" PRIu16, LE16TOH (* number));
  178. memory += sizeof (* number);
  179. extent -= sizeof (* number);
  180. }
  181. else if (! strcmp (object, "long"))
  182. {
  183. uint32_t * number = (uint32_t *) (memory);
  184. if (sizeof (* number) > extent)
  185. {
  186. error (1, ECANCELED, GETPIB_TOOBIG, object, extent);
  187. }
  188. printf ("%" PRIu32, LE32TOH (* number));
  189. memory += sizeof (* number);
  190. extent -= sizeof (* number);
  191. }
  192. else if (! strcmp (object, "huge"))
  193. {
  194. uint64_t * number = (uint64_t *) (memory);
  195. if (sizeof (* number) > extent)
  196. {
  197. error (1, ECANCELED, GETPIB_TOOBIG, object, extent);
  198. }
  199. printf ("%" PRIu64, LE64TOH (* number));
  200. memory += sizeof (* number);
  201. extent -= sizeof (* number);
  202. }
  203. #if 1
  204. else if (! strcmp (object, "xbyte"))
  205. {
  206. uint8_t * number = (uint8_t *) (memory);
  207. if (sizeof (* number) > extent)
  208. {
  209. error (1, ECANCELED, GETPIB_TOOBIG, object, extent);
  210. }
  211. printf ("0x%02" PRIX8, * number);
  212. memory += sizeof (* number);
  213. extent -= sizeof (* number);
  214. }
  215. else if (! strcmp (object, "xword"))
  216. {
  217. uint16_t * number = (uint16_t *) (memory);
  218. if (sizeof (* number) > extent)
  219. {
  220. error (1, ECANCELED, GETPIB_TOOBIG, object, extent);
  221. }
  222. printf ("0x%04" PRIX16, LE16TOH (* number));
  223. memory += sizeof (* number);
  224. extent -= sizeof (* number);
  225. }
  226. else if (! strcmp (object, "xlong"))
  227. {
  228. uint32_t * number = (uint32_t *) (memory);
  229. if (sizeof (* number) > extent)
  230. {
  231. error (1, ECANCELED, GETPIB_TOOBIG, object, extent);
  232. }
  233. printf ("0x%08" PRIX32, LE32TOH (* number));
  234. memory += sizeof (* number);
  235. extent -= sizeof (* number);
  236. }
  237. else if (! strcmp (object, "xhuge"))
  238. {
  239. uint64_t * number = (uint64_t *) (memory);
  240. if (sizeof (* number) > extent)
  241. {
  242. error (1, ECANCELED, GETPIB_TOOBIG, object, extent);
  243. }
  244. printf ("0x%016" PRIX64, LE64TOH (* number));
  245. memory += sizeof (* number);
  246. extent -= sizeof (* number);
  247. }
  248. #endif
  249. else if (! strcmp (object, "mac"))
  250. {
  251. length = ETHER_ADDR_LEN;
  252. if (length > extent)
  253. {
  254. error (1, ECANCELED, GETPIB_TOOBIG, object, extent);
  255. }
  256. getmemory (memory, extent, object, length);
  257. memory += length;
  258. extent -= length;
  259. }
  260. else if (! strcmp (object, "key"))
  261. {
  262. length = PIB_KEY_LEN;
  263. if (length > extent)
  264. {
  265. error (1, ECANCELED, GETPIB_TOOBIG, object, extent);
  266. }
  267. getmemory (memory, extent, object, length);
  268. memory += length;
  269. extent -= length;
  270. }
  271. else if (! strcmp (object, "hfid"))
  272. {
  273. length = PIB_HFID_LEN;
  274. if (length > extent)
  275. {
  276. error (1, ECANCELED, GETPIB_TOOBIG, object, extent);
  277. }
  278. getstring (memory, extent, object, length);
  279. memory += length;
  280. extent -= length;
  281. }
  282. #if 1
  283. else if (! strcmp (object, "adminusername") || ! strcmp (object, "adminpassword") || ! strcmp (object, "accessusername"))
  284. {
  285. length = PIB_NAME_LEN + 1;
  286. if (length > extent)
  287. {
  288. error (1, ECANCELED, GETPIB_TOOBIG, object, extent);
  289. }
  290. getstring (memory, extent, object, length);
  291. memory += length;
  292. extent -= length;
  293. }
  294. else if (! strcmp (object, "accesspassword"))
  295. {
  296. length = PIB_HFID_LEN + 1;
  297. if (length > extent)
  298. {
  299. error (1, ECANCELED, GETPIB_TOOBIG, object, extent);
  300. }
  301. getstring (memory, extent, object, length);
  302. memory += length;
  303. extent -= length;
  304. }
  305. else if (! strcmp (object, "username") || ! strcmp (object, "password") || ! strcmp (object, "url"))
  306. {
  307. length = PIB_TEXT_LEN + 1;
  308. getstring (memory, extent, object, length);
  309. memory += length;
  310. extent -= length;
  311. }
  312. #endif
  313. else if (! strcmp (object, "data"))
  314. {
  315. if (! * argv)
  316. {
  317. error (1, EINVAL, GETPIB_NOSIZE, object);
  318. }
  319. length = (unsigned) (uintspec (* argv, 1, extent));
  320. hexout (memory, length, 0, 0, stdout);
  321. memory += length;
  322. extent -= length;
  323. argc--;
  324. argv++;
  325. }
  326. else if (! strcmp (object, "text"))
  327. {
  328. if (! * argv)
  329. {
  330. error (1, EINVAL, GETPIB_NOSIZE, object);
  331. }
  332. length = (unsigned) (uintspec (* argv, 1, extent));
  333. getstring (memory, extent, object, length);
  334. memory += length;
  335. extent -= length;
  336. argc--;
  337. argv++;
  338. }
  339. else if (! strcmp (object, "skip"))
  340. {
  341. if (! * argv)
  342. {
  343. error (1, EINVAL, GETPIB_NOSIZE, object);
  344. }
  345. length = (unsigned) (uintspec (* argv, 1, extent));
  346. memory += length;
  347. extent -= length;
  348. argc--;
  349. argv++;
  350. continue;
  351. }
  352. else
  353. {
  354. error (1, ENOTSUP, "%s", object);
  355. }
  356. if ((argc) && (* argv))
  357. {
  358. putc (comma, stdout);
  359. }
  360. }
  361. return;
  362. }
  363. /*====================================================================*
  364. *
  365. * signed pibimage1 (int argc, char const * argv [], char comma);
  366. *
  367. * read an entire flat parameter file into memory, edit it, save
  368. * it and display it;
  369. *
  370. * Contributor(s):
  371. * Charles Maier
  372. *
  373. *--------------------------------------------------------------------*/
  374. static signed pibimage1 (int argc, char const * argv [], char comma)
  375. {
  376. signed fd;
  377. off_t extent;
  378. byte * memory;
  379. if ((fd = open (* argv, O_BINARY | O_RDWR)) == - 1)
  380. {
  381. error (1, errno, FILE_CANTOPEN, * argv);
  382. }
  383. if ((extent = lseek (fd, 0, SEEK_END)) == - 1)
  384. {
  385. error (1, errno, FILE_CANTSIZE, * argv);
  386. }
  387. if (lseek (fd, 0, SEEK_SET))
  388. {
  389. error (1, errno, FILE_CANTHOME, * argv);
  390. }
  391. if (! (memory = malloc (extent)))
  392. {
  393. error (1, errno, FILE_CANTLOAD, * argv);
  394. }
  395. if (read (fd, memory, extent) != extent)
  396. {
  397. error (1, errno, FILE_CANTREAD, * argv);
  398. }
  399. close (fd);
  400. snatch (argc - 1, argv + 1, memory, extent, comma);
  401. free (memory);
  402. return (0);
  403. }
  404. /*====================================================================*
  405. *
  406. * signed pibimage2 (int argc, char const * argv [], char comma);
  407. *
  408. * read an entire flat parameter file into memory, edit it, save
  409. * it and display it;
  410. *
  411. * Contributor(s):
  412. * Charles Maier
  413. *
  414. *--------------------------------------------------------------------*/
  415. static signed pibimage2 (int argc, char const * argv [], char comma)
  416. {
  417. struct nvm_header2 header;
  418. signed fd;
  419. off_t extent;
  420. byte * memory;
  421. if ((fd = open (* argv, O_BINARY | O_RDWR)) == - 1)
  422. {
  423. error (1, errno, FILE_CANTOPEN, * argv);
  424. }
  425. if (nvmseek2 (fd, * argv, & header, NVM_IMAGE_PIB))
  426. {
  427. error (1, errno, "Can't find PIB image in %s", * argv);
  428. }
  429. extent = LE32TOH (header.ImageLength);
  430. if (! (memory = malloc (extent)))
  431. {
  432. error (1, errno, FILE_CANTLOAD, * argv);
  433. }
  434. if (read (fd, memory, extent) != extent)
  435. {
  436. error (1, errno, FILE_CANTREAD, * argv);
  437. }
  438. close (fd);
  439. snatch (argc - 1, argv + 1, memory, extent, comma);
  440. free (memory);
  441. return (0);
  442. }
  443. /*====================================================================*
  444. *
  445. * signed function (int argc, char const * argv [], char comma);
  446. *
  447. * call an appropriate parameter edit function based on the file
  448. * header;
  449. *
  450. * older parameter files are flat with their own header; newer ones
  451. * are image chains where one of image contains the parameter block;
  452. *
  453. *
  454. * Contributor(s):
  455. * Charles Maier
  456. *
  457. *--------------------------------------------------------------------*/
  458. static signed function (int argc, char const * argv [], char comma)
  459. {
  460. uint32_t version;
  461. signed status;
  462. signed fd;
  463. if ((fd = open (* argv, O_BINARY | O_RDWR)) == - 1)
  464. {
  465. error (1, errno, FILE_CANTOPEN, * argv);
  466. }
  467. if (read (fd, & version, sizeof (version)) != sizeof (version))
  468. {
  469. error (1, errno, FILE_CANTREAD, * argv);
  470. }
  471. close (fd);
  472. if (LE32TOH (version) == 0x00010001)
  473. {
  474. status = pibimage2 (argc, argv, comma);
  475. }
  476. else
  477. {
  478. status = pibimage1 (argc, argv, comma);
  479. }
  480. return (status);
  481. }
  482. /*====================================================================*
  483. *
  484. * int main (int argc, char const * argv []);
  485. *
  486. *
  487. *--------------------------------------------------------------------*/
  488. int main (int argc, char const * argv [])
  489. {
  490. static char const * optv [] =
  491. {
  492. "c:qvn",
  493. "file offset type [size]\n\n\tstandard-length types are 'byte'|'word'|'long'|'huge'|'hfid'|'mac'|'key'\n\tvariable-length types are 'data'|'text'|'skip' and need a size",
  494. "PIB Data Extractor",
  495. "c c\tobject separator is (c) [" LITERAL (GETPIB_COMMA) "]",
  496. "n\tappend newline",
  497. "q\tquiet mode",
  498. "v\tverbose mode",
  499. (char const *) (0)
  500. };
  501. flag_t flags = (flag_t) (0);
  502. char comma = GETPIB_COMMA;
  503. signed c;
  504. optind = 1;
  505. opterr = 1;
  506. while (~ (c = getoptv (argc, argv, optv)))
  507. {
  508. switch (c)
  509. {
  510. case 'c':
  511. comma = * optarg;
  512. break;
  513. case 'n':
  514. _setbits (flags, GETPIB_NEWLINE);
  515. break;
  516. case 'q':
  517. _setbits (flags, GETPIB_SILENCE);
  518. break;
  519. case 'v':
  520. _setbits (flags, GETPIB_VERBOSE);
  521. break;
  522. default:
  523. break;
  524. }
  525. }
  526. argc -= optind;
  527. argv += optind;
  528. if ((argc) && (* argv))
  529. {
  530. function (argc, argv, comma);
  531. if (_anyset (flags, GETPIB_NEWLINE))
  532. {
  533. putc ('\n', stdout);
  534. }
  535. }
  536. return (0);
  537. }