pibruin.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /*====================================================================*
  2. *
  3. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  4. *
  5. * All rights reserved.
  6. *
  7. *====================================================================*/
  8. /*====================================================================*
  9. *
  10. * pibruin.c - Qualcomm Atheros Classification Rule Insert Utility;
  11. *
  12. * Contributor(s):
  13. * Nathaniel Houghton <nhoughto@qca.qualcomm.com>
  14. * Charles Maier <cmaier@qca.qualcomm.com>
  15. *
  16. *--------------------------------------------------------------------*/
  17. /*====================================================================*
  18. * system header files;
  19. *--------------------------------------------------------------------*/
  20. #include <ctype.h>
  21. #include <stdio.h>
  22. #include <unistd.h>
  23. #include <stdlib.h>
  24. #include <stdint.h>
  25. #include <string.h>
  26. #include <netinet/in.h>
  27. #include <arpa/inet.h>
  28. /*====================================================================*
  29. * custom header files;
  30. *--------------------------------------------------------------------*/
  31. #include "../tools/getoptv.h"
  32. #include "../tools/memory.h"
  33. #include "../tools/number.h"
  34. #include "../tools/symbol.h"
  35. #include "../tools/chars.h"
  36. #include "../tools/types.h"
  37. #include "../tools/flags.h"
  38. #include "../tools/files.h"
  39. #include "../tools/error.h"
  40. #include "../plc/rules.h"
  41. #include "../nvm/nvm.h"
  42. #include "../pib/pib.h"
  43. /*====================================================================*
  44. * custom source files;
  45. *--------------------------------------------------------------------*/
  46. #ifndef MAKEFILE
  47. #include "../tools/getoptv.c"
  48. #include "../tools/putoptv.c"
  49. #include "../tools/version.c"
  50. #include "../tools/lookup.c"
  51. #include "../tools/reword.c"
  52. #include "../tools/hexstring.c"
  53. #include "../tools/hexdecode.c"
  54. #include "../tools/fdchecksum32.c"
  55. #include "../tools/checksum32.c"
  56. #include "../tools/memout.c"
  57. #include "../tools/assist.c"
  58. #include "../tools/bytespec.c"
  59. #include "../tools/basespec.c"
  60. #include "../tools/ipv4spec.c"
  61. #include "../tools/ipv6spec.c"
  62. #include "../tools/endian.c"
  63. #include "../tools/emalloc.c"
  64. #include "../tools/todigit.c"
  65. #include "../tools/codelist.c"
  66. #include "../tools/getargv.c"
  67. #include "../tools/error.c"
  68. #endif
  69. #ifndef MAKEFILE
  70. #include "../pib/lightning_pib_file.c"
  71. #include "../pib/lightning_pib_lock.c"
  72. #if defined (PRINT_RULES) || defined (PRINT_CLASSIFIERS)
  73. #include "../pib/ruledump.c"
  74. #endif
  75. #endif
  76. #ifndef MAKEFILE
  77. #include "../nvm/panther_nvm_seek.c"
  78. #endif
  79. #ifndef MAKEFILE
  80. #include "../plc/ParseRule.c"
  81. #include "../plc/rules.c"
  82. #endif
  83. /*====================================================================*
  84. * program constants;
  85. *--------------------------------------------------------------------*/
  86. #define PIB_OFFSET1 0x0228
  87. #define PIB_OFFSET2 0x0760
  88. /*====================================================================*
  89. *
  90. * signed pibimage1 (signed fd, char const * filename, unsigned offset, struct PIBClassifiers * classifiers);
  91. *
  92. * read thunderbolt/lightning parameter block into memory, edit it
  93. * and save it;
  94. *
  95. * Contributor(s):
  96. * Charles Maier <cmaier@qca.qualcomm.com>
  97. *
  98. *--------------------------------------------------------------------*/
  99. static signed pibimage1 (signed fd, char const * filename, unsigned offset, struct PIBClassifiers * classifiers)
  100. {
  101. struct pib_header * pib_header;
  102. off_t extent;
  103. void * memory;
  104. if ((extent = lseek (fd, 0, SEEK_END)) == - 1)
  105. {
  106. error (1, errno, FILE_CANTSIZE, filename);
  107. }
  108. if (! (memory = malloc (extent)))
  109. {
  110. error (1, errno, FILE_CANTLOAD, filename);
  111. }
  112. if (lseek (fd, 0, SEEK_SET))
  113. {
  114. error (1, errno, FILE_CANTHOME, filename);
  115. }
  116. if (read (fd, memory, extent) != extent)
  117. {
  118. error (1, errno, FILE_CANTREAD, filename);
  119. }
  120. if (lseek (fd, 0, SEEK_SET))
  121. {
  122. error (1, errno, FILE_CANTHOME, filename);
  123. }
  124. memcpy ((byte *) (memory) + offset, classifiers, sizeof (* classifiers));
  125. pib_header = (struct pib_header *) (memory);
  126. pib_header->CHECKSUM = checksum32 (memory, extent, pib_header->CHECKSUM);
  127. if (write (fd, memory, extent) != extent)
  128. {
  129. error (1, errno, FILE_CANTSAVE, filename);
  130. }
  131. if (lseek (fd, (off_t) (0) - extent, SEEK_CUR) == - 1)
  132. {
  133. error (1, errno, FILE_CANTHOME, filename);
  134. }
  135. free (memory);
  136. close (fd);
  137. return (0);
  138. }
  139. /*====================================================================*
  140. *
  141. * signed pibimage2 (signed fd, char const * filename, struct nvm_header2 * nvm_header, unsigned offset, struct PIBClassifiers * classifiers);
  142. *
  143. * read panther/lynx parameter block into memory, edit it and save
  144. * it;
  145. *
  146. * Contributor(s):
  147. * Charles Maier <cmaier@qca.qualcomm.com>
  148. *
  149. *--------------------------------------------------------------------*/
  150. static signed pibimage2 (signed fd, char const * filename, struct panther_nvm_header * header, unsigned offset, struct PIBClassifiers * classifiers)
  151. {
  152. void * memory;
  153. off_t extent = LE32TOH (header->ImageLength);
  154. if (! (memory = malloc (extent)))
  155. {
  156. error (1, errno, FILE_CANTLOAD, filename);
  157. }
  158. if (read (fd, memory, extent) != extent)
  159. {
  160. error (1, errno, FILE_CANTREAD, filename);
  161. }
  162. if (lseek (fd, (off_t) (0) - extent, SEEK_CUR) == - 1)
  163. {
  164. error (1, errno, FILE_CANTHOME, filename);
  165. }
  166. memcpy ((byte *) (memory) + offset, classifiers, sizeof (* classifiers));
  167. header->ImageChecksum = checksum32 (memory, extent, 0);
  168. if (write (fd, memory, extent) != extent)
  169. {
  170. error (1, errno, FILE_CANTSAVE, filename);
  171. }
  172. if (lseek (fd, (off_t) (0) - extent, SEEK_CUR) == - 1)
  173. {
  174. error (1, errno, FILE_CANTHOME, filename);
  175. }
  176. header->HeaderChecksum = checksum32 (header, sizeof (* header), header->HeaderChecksum);
  177. if (lseek (fd, (off_t) (0) - sizeof (* header), SEEK_CUR) == - 1)
  178. {
  179. error (1, errno, FILE_CANTHOME, filename);
  180. }
  181. if (write (fd, header, sizeof (* header)) != sizeof (* header))
  182. {
  183. error (1, errno, FILE_CANTSAVE, filename);
  184. }
  185. if (lseek (fd, (off_t) (0) - sizeof (* header), SEEK_CUR) == - 1)
  186. {
  187. error (1, errno, FILE_CANTHOME, filename);
  188. }
  189. free (memory);
  190. return (0);
  191. }
  192. /*====================================================================*
  193. *
  194. * void make_rule (int argc, char const * argv [], struct PIBClassifiers * classifiers);
  195. *
  196. * read argv [] and populate struct MMEClassifiers with QCA PLC
  197. * classifier rules; function ParseRule converts each rule to an
  198. * MMERule; we then convert that into one of two formats used to
  199. * store classifier rules in the PIB;
  200. *
  201. *--------------------------------------------------------------------*/
  202. static void make_rule (int argc, char const * argv [], struct PIBClassifiers * classifiers)
  203. {
  204. static char const * optv [] =
  205. {
  206. "T:V:",
  207. "",
  208. "Qualcomm Atheros Classification Rule Insert Utility",
  209. "T\ttag",
  210. "V\tversion",
  211. (char const *) (0)
  212. };
  213. struct MMERule rule;
  214. struct cspec cspec;
  215. signed c;
  216. optind = 1;
  217. memset (& rule, 0, sizeof (rule));
  218. memset (& cspec, 0, sizeof (cspec));
  219. while (~ (c = getoptv (argc, argv, optv)))
  220. {
  221. switch (c)
  222. {
  223. case 'T':
  224. cspec.VLAN_TAG = (uint32_t) (basespec (optarg, 16, sizeof (cspec.VLAN_TAG)));
  225. cspec.VLAN_TAG = htonl (cspec.VLAN_TAG);
  226. break;
  227. case 'V':
  228. cspec.CSPEC_VERSION = (uint16_t) (basespec (optarg, 10, sizeof (cspec.CSPEC_VERSION)));
  229. cspec.CSPEC_VERSION = HTOLE16 (cspec.CSPEC_VERSION);
  230. break;
  231. default:
  232. break;
  233. }
  234. }
  235. argc -= optind;
  236. argv += optind;
  237. #if defined (DUMP_RULE_ARGS)
  238. /*
  239. * print arguments on stdout;
  240. */
  241. for (c = 0; c < argc; c++)
  242. {
  243. printf ("argv [%d] = [%s]\n", c, argv [c]);
  244. }
  245. #endif
  246. if ((argc) && (* argv))
  247. {
  248. ParseRule (& argc, & argv, & rule, & cspec);
  249. #if defined (PRINT_RULES)
  250. /*
  251. * print MMERule set on stdout in human readable format; these rules are populated by ParseRule but members
  252. * are not PIB ready; they are not properly grouped, byte-aligned or endian-ized;
  253. */
  254. MMERuleDump (& rule);
  255. #endif
  256. if ((rule.NUM_CLASSIFIERS > 1) || (rule.MACTION == ACTION_STRIPTX) || (rule.MACTION == ACTION_STRIPRX) || (rule.MACTION == ACTION_TAGTX) || (classifiers->priority_count >= RULE_MAX_PRIORITY_MAPS))
  257. {
  258. struct auto_connection * auto_connection;
  259. if (classifiers->autoconn_count >= RULE_MAX_AUTOCONN)
  260. {
  261. error (1, ENOTSUP, "Too many auto connection rules");
  262. }
  263. auto_connection = & classifiers->auto_connection [classifiers->autoconn_count];
  264. auto_connection->MACTION = rule.MACTION;
  265. auto_connection->MOPERAND = rule.MOPERAND;
  266. auto_connection->NUM_CLASSIFIERS = HTOLE16 ((uint16_t) (rule.NUM_CLASSIFIERS));
  267. for (c = 0; c < RULE_MAX_CLASSIFIERS; c++)
  268. {
  269. auto_connection->CLASSIFIER [c].CR_PID = HTOLE32 ((uint32_t) (0xFF));
  270. auto_connection->CLASSIFIER [c].CR_OPERAND = HTOLE32 ((uint32_t) (0xFF));
  271. }
  272. for (c = 0; c < rule.NUM_CLASSIFIERS; c++)
  273. {
  274. auto_connection->CLASSIFIER [c].CR_PID = HTOLE32 ((uint32_t) (rule.CLASSIFIER [c].CR_PID));
  275. auto_connection->CLASSIFIER [c].CR_OPERAND = HTOLE32 ((uint32_t) (rule.CLASSIFIER [c].CR_OPERAND));
  276. memcpy (auto_connection->CLASSIFIER [c].CR_VALUE, rule.CLASSIFIER [c].CR_VALUE, sizeof (auto_connection->CLASSIFIER [c].CR_VALUE));
  277. }
  278. memcpy (& auto_connection->cspec, & rule.cspec, sizeof (auto_connection->cspec));
  279. classifiers->autoconn_count++;
  280. }
  281. else
  282. {
  283. struct classifier_priority_map * classifier_priority_map;
  284. if (classifiers->priority_count >= RULE_MAX_PRIORITY_MAPS)
  285. {
  286. error (1, ENOTSUP, "Too many priority map rules");
  287. }
  288. classifier_priority_map = & classifiers->classifier_priority_map [classifiers->priority_count];
  289. classifier_priority_map->Priority = HTOLE32 ((uint32_t) (rule.MACTION));
  290. classifier_priority_map->CLASSIFIER.CR_PID = HTOLE32 ((uint32_t) (rule.CLASSIFIER [0].CR_PID));
  291. classifier_priority_map->CLASSIFIER.CR_OPERAND = HTOLE32 ((uint32_t) (rule.CLASSIFIER [0].CR_OPERAND));
  292. memcpy (classifier_priority_map->CLASSIFIER.CR_VALUE, rule.CLASSIFIER [0].CR_VALUE, sizeof (classifier_priority_map->CLASSIFIER.CR_VALUE));
  293. classifiers->priority_count++;
  294. }
  295. }
  296. return;
  297. }
  298. /*====================================================================*
  299. *
  300. * int main (int argc, char const * argv[]);
  301. *
  302. *
  303. *--------------------------------------------------------------------*/
  304. int main (int argc, char const * argv [])
  305. {
  306. static char const * optv [] =
  307. {
  308. "eo:qv",
  309. "pibfile < rules",
  310. "Qualcomm Atheros Classification Rule Insert Utility",
  311. "e\tredirect stderr messages to stdout",
  312. "o x\talternate offset is (x)",
  313. "q\tquiet mode",
  314. "v\tverbose mode",
  315. (char const *) (0)
  316. };
  317. struct PIBClassifiers classifiers;
  318. char const * vector [24];
  319. uint32_t offset = 0;
  320. uint32_t version;
  321. signed fd;
  322. signed count;
  323. flag_t flags = (flag_t) (0);
  324. signed c;
  325. optind = 1;
  326. while (~ (c = getoptv (argc, argv, optv)))
  327. {
  328. switch (c)
  329. {
  330. case 'e':
  331. dup2 (STDOUT_FILENO, STDERR_FILENO);
  332. break;
  333. case 'o':
  334. offset = (unsigned) (basespec (optarg, 16, sizeof (offset)));
  335. break;
  336. case 'q':
  337. _setbits (flags, PIB_SILENCE);
  338. break;
  339. case 'v':
  340. _setbits (flags, PIB_VERBOSE);
  341. break;
  342. default:
  343. break;
  344. }
  345. }
  346. argc -= optind;
  347. argv += optind;
  348. memset (& classifiers, 0, sizeof (classifiers));
  349. while ((count = getargv (SIZEOF (vector), vector)))
  350. {
  351. make_rule (count, vector, & classifiers);
  352. }
  353. classifiers.priority_count = HTOLE32 (classifiers.priority_count);
  354. classifiers.autoconn_count = HTOLE32 (classifiers.autoconn_count);
  355. #if defined (PRINT_CLASSIFIERS)
  356. /*
  357. * print PIB-ready classification rules on stdout in human readable format; these rules are written
  358. * directly into the appropriate location in the PIB as a single block;
  359. */
  360. PIBClassifiersDump (& classifiers);
  361. #endif
  362. #if defined (WRITE_CLASSIFIERS)
  363. write (STDOUT_FILENO, & classifiers, sizeof (classifiers));
  364. #endif
  365. while ((argc) && (* argv))
  366. {
  367. if ((fd = open (* argv, O_BINARY | O_RDWR)) == - 1)
  368. {
  369. error (1, errno, "%s", * argv);
  370. }
  371. else if (read (fd, & version, sizeof (version)) != sizeof (version))
  372. {
  373. error (1, errno, FILE_CANTREAD, * argv);
  374. }
  375. else if (lseek (fd, 0, SEEK_SET))
  376. {
  377. error (1, errno, FILE_CANTHOME, * argv);
  378. }
  379. else if (LE32TOH (version) == 0x00010001)
  380. {
  381. struct panther_nvm_header header;
  382. if (! panther_nvm_seek (fd, * argv, & header, NVM_IMAGE_PIB))
  383. {
  384. pibimage2 (fd, * argv, & header, offset? offset: PIB_OFFSET2, & classifiers);
  385. }
  386. }
  387. else
  388. {
  389. pibimage1 (fd, * argv, offset? offset: PIB_OFFSET1, & classifiers);
  390. }
  391. close (fd);
  392. argc--;
  393. argv++;
  394. }
  395. exit (0);
  396. }