plcfwd.c.html 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  1. <?xml version='1.0' encoding='iso-8859-1'?>
  2. <!doctype html public '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
  3. <html xmlns='http://www.w3c.org/1999/xhtml' lang='en-us'>
  4. <head>
  5. <title>
  6. plcfwd.c
  7. </title>
  8. <meta http-equiv='content-type' content='text/html;iso-8859-1'/>
  9. <meta name='generator' content='motley-tools 1.9.4 13:40:33 Feb 18 2015'/>
  10. <meta name='author' content='cmaier@cmassoc.net'/>
  11. <meta name='robots' content='noindex,nofollow'/>
  12. <link href='toolkit.css' rel='stylesheet' type='text/css'/>
  13. </head>
  14. <body>
  15. <div class='headerlink'>
  16. [<a href='plcdevs.c.html' title=' plcdevs.c '>PREV</a>]
  17. [<a href='toolkit.html' title=' Index '>HOME</a>]
  18. [<a href='plcget.c.html' title=' plcget.c '>NEXT</a>]
  19. </div>
  20. <pre>
  21. /*====================================================================*
  22. *
  23. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  24. *
  25. * All rights reserved.
  26. *
  27. * Redistribution and use in source and binary forms, with or
  28. * without modification, are permitted (subject to the limitations
  29. * in the disclaimer below) provided that the following conditions
  30. * are met:
  31. *
  32. * * Redistributions of source code must retain the above copyright
  33. * notice, this list of conditions and the following disclaimer.
  34. *
  35. * * Redistributions in binary form must reproduce the above
  36. * copyright notice, this list of conditions and the following
  37. * disclaimer in the documentation and/or other materials
  38. * provided with the distribution.
  39. *
  40. * * Neither the name of Qualcomm Atheros nor the names of
  41. * its contributors may be used to endorse or promote products
  42. * derived from this software without specific prior written
  43. * permission.
  44. *
  45. * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
  46. * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE
  47. * COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND ANY EXPRESS OR
  48. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  50. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  51. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  52. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  53. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  54. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  55. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  56. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  57. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59. *
  60. *--------------------------------------------------------------------*/
  61. /*====================================================================*
  62. *
  63. * plcfwd.c - Atheros PLC Forward Configuration Manager;
  64. *
  65. *
  66. *--------------------------------------------------------------------*/
  67. /*====================================================================*&quot;
  68. * system header files;
  69. *--------------------------------------------------------------------*/
  70. #include &lt;unistd.h&gt;
  71. #include &lt;stdlib.h&gt;
  72. #include &lt;stdint.h&gt;
  73. #include &lt;limits.h&gt;
  74. #include &lt;ctype.h&gt;
  75. /*====================================================================*
  76. * custom header files;
  77. *--------------------------------------------------------------------*/
  78. #include &quot;../tools/getoptv.h&quot;
  79. #include &quot;../tools/putoptv.h&quot;
  80. #include &quot;../tools/memory.h&quot;
  81. #include &quot;../tools/number.h&quot;
  82. #include &quot;../tools/symbol.h&quot;
  83. #include &quot;../tools/types.h&quot;
  84. #include &quot;../tools/flags.h&quot;
  85. #include &quot;../tools/files.h&quot;
  86. #include &quot;../tools/error.h&quot;
  87. #include &quot;../plc/plc.h&quot;
  88. /*====================================================================*
  89. * custom source files;
  90. *--------------------------------------------------------------------*/
  91. #ifndef MAKEFILE
  92. #include &quot;../plc/Confirm.c&quot;
  93. #include &quot;../plc/Display.c&quot;
  94. #include &quot;../plc/Failure.c&quot;
  95. #include &quot;../plc/Request.c&quot;
  96. #include &quot;../plc/ReadMME.c&quot;
  97. #include &quot;../plc/SendMME.c&quot;
  98. #include &quot;../plc/Devices.c&quot;
  99. #endif
  100. #ifndef MAKEFILE
  101. #include &quot;../tools/getoptv.c&quot;
  102. #include &quot;../tools/putoptv.c&quot;
  103. #include &quot;../tools/version.c&quot;
  104. #include &quot;../tools/uintspec.c&quot;
  105. #include &quot;../tools/basespec.c&quot;
  106. #include &quot;../tools/hexdump.c&quot;
  107. #include &quot;../tools/hexview.c&quot;
  108. #include &quot;../tools/hexencode.c&quot;
  109. #include &quot;../tools/hexdecode.c&quot;
  110. #include &quot;../tools/hexout.c&quot;
  111. #include &quot;../tools/todigit.c&quot;
  112. #include &quot;../tools/synonym.c&quot;
  113. #include &quot;../tools/binout.c&quot;
  114. #include &quot;../tools/error.c&quot;
  115. #endif
  116. #ifndef MAKEFILE
  117. #include &quot;../ether/openchannel.c&quot;
  118. #include &quot;../ether/closechannel.c&quot;
  119. #include &quot;../ether/readpacket.c&quot;
  120. #include &quot;../ether/sendpacket.c&quot;
  121. #include &quot;../ether/channel.c&quot;
  122. #endif
  123. #ifndef MAKEFILE
  124. #include &quot;../mme/MMECode.c&quot;
  125. #include &quot;../mme/EthernetHeader.c&quot;
  126. #include &quot;../mme/QualcommHeader.c&quot;
  127. #include &quot;../mme/UnwantedMessage.c&quot;
  128. #endif
  129. /*====================================================================*
  130. * program constants;
  131. *--------------------------------------------------------------------*/
  132. #define PLCFWD_VERBOSE (1 &lt;&lt; 0)
  133. #define PLCFWD_SILENCE (1 &lt;&lt; 1)
  134. #define PLCFWD_LENGTH 0
  135. #define PLCFWD_OFFSET 0
  136. #define PLCFWD_GET 0
  137. #define PLCFWD_ADD 1
  138. #define PLCFWD_REM 2
  139. #define PLCFWD_STO 3
  140. #define PLCFWD_CTL 4
  141. #define PLCFWD_SET 5
  142. #define PLCFWD_FWD 6
  143. #define PLCFWD_VER 0
  144. /*====================================================================*
  145. * program variables;
  146. *--------------------------------------------------------------------*/
  147. /*
  148. * this structure is only used in the VS_FORWARD_CONFIG message but
  149. * it is common to several variations of the message and is used in
  150. * arrays;
  151. */
  152. #ifndef __GNUC__
  153. #pragma pack (push,1)
  154. #endif
  155. typedef struct item
  156. {
  157. uint8_t MAC_ADDR [ETHER_ADDR_LEN];
  158. uint16_t NUM_VLANIDS;
  159. uint16_t VLANID [10];
  160. }
  161. item;
  162. #ifndef __GNUC__
  163. #pragma pack (pop)
  164. #endif
  165. /*
  166. * synonym table for options -M and -S;
  167. */
  168. #define STATES (sizeof (states) / sizeof (struct _term_))
  169. static const struct _term_ states [] =
  170. {
  171. {
  172. &quot;disable&quot;,
  173. &quot;0&quot;
  174. },
  175. {
  176. &quot;enable&quot;,
  177. &quot;1&quot;
  178. },
  179. {
  180. &quot;off&quot;,
  181. &quot;0&quot;
  182. },
  183. {
  184. &quot;on&quot;,
  185. &quot;1&quot;
  186. }
  187. };
  188. /*====================================================================*
  189. *
  190. * void readitem (struct item * item, char const * string);
  191. *
  192. * encode a slave structure with infomation specified by a string
  193. * specification has the following production:
  194. *
  195. * &lt;spec&gt; := &lt;mac_addr&gt;
  196. * &lt;spec&gt; := &lt;spec&gt;,&lt;vlan_id&gt;
  197. *
  198. * basically, encode slave-&gt;MAC_ADDR then encode slave-&gt;VLANID[]
  199. * with hexadecimal VLANID values; we allow 10 VLANID values but
  200. * only 8 are legal;
  201. *
  202. * the idea is to read multiple input strings and call this function
  203. * to initialize one or more slave structures; it is possible to fit
  204. * up to 128 slave structures in one message frame;
  205. *
  206. *
  207. *--------------------------------------------------------------------*/
  208. static void readitem (struct item * item, char const * string)
  209. {
  210. register uint8_t * origin = (uint8_t *)(item-&gt;MAC_ADDR);
  211. register uint8_t * offset = (uint8_t *)(item-&gt;MAC_ADDR);
  212. size_t extent = sizeof (item-&gt;MAC_ADDR);
  213. memset (item, 0, sizeof (* item));
  214. while ((extent) &amp;&amp; (*string))
  215. {
  216. unsigned radix = RADIX_HEX;
  217. unsigned field = sizeof (uint8_t) + sizeof (uint8_t);
  218. unsigned value = 0;
  219. unsigned digit = 0;
  220. if ((offset != origin) &amp;&amp; (*string == HEX_EXTENDER))
  221. {
  222. string++;
  223. }
  224. while (field--)
  225. {
  226. if ((digit = todigit (*string)) &lt; radix)
  227. {
  228. value *= radix;
  229. value += digit;
  230. string++;
  231. continue;
  232. }
  233. error (1, EINVAL, &quot;bad MAC address: ...[%s] (1)&quot;, string);
  234. }
  235. *offset = value;
  236. offset++;
  237. extent--;
  238. }
  239. if (extent)
  240. {
  241. error (1, EINVAL, &quot;bad MAC address: ...[%s] (2)&quot;, string);
  242. }
  243. while (isspace (*string))
  244. {
  245. string++;
  246. }
  247. if ((*string) &amp;&amp; (*string != ','))
  248. {
  249. error (1, EINVAL, &quot;bad MAC address: ...[%s] (3)&quot;, string);
  250. }
  251. while (*string == ',')
  252. {
  253. unsigned radix = RADIX_DEC;
  254. unsigned digit = 0;
  255. unsigned value = 0;
  256. do
  257. {
  258. string++;
  259. }
  260. while (isspace (*string));
  261. while ((digit = todigit (*string)) &lt; radix)
  262. {
  263. value *= radix;
  264. value += digit;
  265. string++;
  266. }
  267. while (isspace (*string))
  268. {
  269. string++;
  270. }
  271. if (item-&gt;NUM_VLANIDS &lt; (sizeof (item-&gt;VLANID) / sizeof (uint16_t)))
  272. {
  273. item-&gt;VLANID [item-&gt;NUM_VLANIDS++] = value;
  274. }
  275. }
  276. while (isspace (*string))
  277. {
  278. string++;
  279. }
  280. if (*string)
  281. {
  282. error (1, EINVAL, &quot;bad VLAN ID: ...[%s]&quot;, string);
  283. }
  284. return;
  285. }
  286. /*====================================================================*
  287. *
  288. * unsigned readlist (struct item list [], unsigned size);
  289. *
  290. * read one or more items from stdin; discard comments; assume one
  291. * item per line; permit multiple items on one line when separated
  292. * by semicolon; items cannot straddle lines; readitem () controls
  293. * what consitutes one item;
  294. *
  295. *--------------------------------------------------------------------*/
  296. static unsigned readlist (struct item list [], unsigned size)
  297. {
  298. struct item * item = list;
  299. char string [1024];
  300. char * sp = string;
  301. signed c;
  302. for (c = getc (stdin); c != EOF; c = getc (stdin))
  303. {
  304. if (isspace (c))
  305. {
  306. continue;
  307. }
  308. if (c == '#')
  309. {
  310. while ((c != '\n') &amp;&amp; (c != EOF))
  311. {
  312. c = getc (stdin);
  313. }
  314. continue;
  315. }
  316. sp = string;
  317. while ((c != ';') &amp;&amp; (c != '\n') &amp;&amp; (c != EOF))
  318. {
  319. *sp++ = (char)(c);
  320. c = getc (stdin);
  321. }
  322. *sp = (char)(0);
  323. if (size)
  324. {
  325. readitem (item++, string);
  326. size--;
  327. }
  328. }
  329. return ((unsigned)(item - list));
  330. }
  331. /*====================================================================*
  332. *
  333. * void showlist (struct item list [], unsigned items)
  334. *
  335. * print item list on stdout in a format suitable for input using
  336. * readlist (); this function may be commented out if it not used;
  337. *
  338. *
  339. *--------------------------------------------------------------------*/
  340. #if 0
  341. static void showlist (struct item list [], unsigned items)
  342. {
  343. while (items--)
  344. {
  345. uint16_t fields = list-&gt;NUM_VLANIDS;
  346. uint16_t * field = list-&gt;VLANID;
  347. hexout (list-&gt;MAC_ADDR, sizeof (list-&gt;MAC_ADDR), 0, 0, stdout);
  348. while (fields--)
  349. {
  350. printf (&quot;, %d&quot;, *field);
  351. field++;
  352. }
  353. printf (&quot;\n&quot;);
  354. list++;
  355. }
  356. return;
  357. }
  358. #endif
  359. /*====================================================================*
  360. *
  361. * signed ReadVLANIDs (struct plc * plc, uint32_t offset, uint32_t length);
  362. *
  363. *
  364. *--------------------------------------------------------------------*/
  365. static signed ReadVLANIDs (struct plc * plc, uint32_t offset, uint32_t length)
  366. {
  367. struct channel * channel = (struct channel *)(plc-&gt;channel);
  368. struct message * message = (struct message *)(plc-&gt;message);
  369. #ifndef __GNUC__
  370. #pragma pack (push,1)
  371. #endif
  372. struct __packed vs_forward_config_request
  373. {
  374. struct ethernet_hdr ethernet;
  375. struct qualcomm_hdr qualcomm;
  376. uint8_t RESERVED1;
  377. uint8_t MREQUEST;
  378. uint8_t MVERSION;
  379. uint32_t RESERVED2;
  380. uint32_t DATA_LENGTH;
  381. uint32_t DATA_OFFSET;
  382. uint16_t RESERVED3;
  383. }
  384. * request = (struct vs_forward_config_request *) (message);
  385. struct __packed vs_forward_config_confirm
  386. {
  387. struct ethernet_hdr ethernet;
  388. struct qualcomm_hdr qualcomm;
  389. uint8_t RESERVED1;
  390. uint8_t RESULTCODE;
  391. uint8_t OPERATION;
  392. uint8_t MVERSION;
  393. uint32_t RESERVED2;
  394. uint32_t DATA_LENGTH;
  395. uint32_t DATA_OFFSET;
  396. uint8_t DATA [PLC_MODULE_SIZE];
  397. }
  398. * confirm = (struct vs_forward_config_confirm *) (message);
  399. #ifndef __GNUC__
  400. #pragma pack (pop)
  401. #endif
  402. memset (message, 0, sizeof (* message));
  403. EthernetHeader (&amp;request-&gt;ethernet, channel-&gt;peer, channel-&gt;host, channel-&gt;type);
  404. QualcommHeader (&amp;request-&gt;qualcomm, 0, (VS_FORWARD_CONFIG | MMTYPE_REQ));
  405. request-&gt;MREQUEST = PLCFWD_GET;
  406. request-&gt;MVERSION = PLCFWD_VER;
  407. request-&gt;DATA_OFFSET = HTOLE32 (offset);
  408. request-&gt;DATA_LENGTH = HTOLE32 (length);
  409. plc-&gt;packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
  410. if (SendMME (plc) &lt;= 0)
  411. {
  412. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  413. return (-1);
  414. }
  415. while (ReadMME (plc, 0, (VS_FORWARD_CONFIG | MMTYPE_CNF)) &gt; 0)
  416. {
  417. if (confirm-&gt;RESULTCODE)
  418. {
  419. Failure (plc, PLC_WONTDOIT);
  420. continue;
  421. }
  422. hexview (confirm-&gt;DATA, LE32TOH (confirm-&gt;DATA_OFFSET), LE32TOH (confirm-&gt;DATA_LENGTH), stdout);
  423. }
  424. return (0);
  425. }
  426. /*====================================================================*
  427. *
  428. * signed AddVLANIDs (struct plc * plc, struct item list [], unsigned items);
  429. *
  430. *
  431. *--------------------------------------------------------------------*/
  432. static signed AddVLANIDs (struct plc * plc, struct item list [], unsigned items)
  433. {
  434. struct channel * channel = (struct channel *)(plc-&gt;channel);
  435. struct message * message = (struct message *)(plc-&gt;message);
  436. #ifndef __GNUC__
  437. #pragma pack (push,1)
  438. #endif
  439. struct __packed vs_forward_config_request
  440. {
  441. struct ethernet_hdr ethernet;
  442. struct qualcomm_hdr qualcomm;
  443. uint8_t RESERVED1;
  444. uint8_t MREQUEST;
  445. uint8_t MVERSION;
  446. uint32_t RESERVED2;
  447. uint16_t ITEMS;
  448. struct item LIST [1];
  449. }
  450. * request = (struct vs_forward_config_request *) (message);
  451. struct __packed vs_forward_config_confirm
  452. {
  453. struct ethernet_hdr ethernet;
  454. struct qualcomm_hdr qualcomm;
  455. uint8_t RESERVED1;
  456. uint8_t RESULTCODE;
  457. uint8_t OPERATION;
  458. uint8_t MVERSION;
  459. uint32_t RESERVED2;
  460. }
  461. * confirm = (struct vs_forward_config_confirm *) (message);
  462. #ifndef __GNUC__
  463. #pragma pack (pop)
  464. #endif
  465. struct item * item = request-&gt;LIST;
  466. memset (message, 0, sizeof (* message));
  467. EthernetHeader (&amp;request-&gt;ethernet, channel-&gt;peer, channel-&gt;host, channel-&gt;type);
  468. QualcommHeader (&amp;request-&gt;qualcomm, 0, (VS_FORWARD_CONFIG | MMTYPE_REQ));
  469. request-&gt;MREQUEST = PLCFWD_ADD;
  470. request-&gt;MVERSION = PLCFWD_VER;
  471. request-&gt;ITEMS = HTOLE16 (items);
  472. while (items--)
  473. {
  474. unsigned count;
  475. memcpy (item-&gt;MAC_ADDR, list-&gt;MAC_ADDR, sizeof (item-&gt;MAC_ADDR));
  476. item-&gt;NUM_VLANIDS = HTOLE16 (list-&gt;NUM_VLANIDS);
  477. for (count = 0; count &lt; list-&gt;NUM_VLANIDS; count++)
  478. {
  479. item-&gt;VLANID [count] = HTOLE16 (list-&gt;VLANID [count]);
  480. }
  481. // item++;
  482. item = (struct item *)(&amp;item-&gt;VLANID [count]);
  483. list++;
  484. }
  485. plc-&gt;packetsize = (signed)((uint8_t *)(item) - (uint8_t *)(request));
  486. if (SendMME (plc) &lt;= 0)
  487. {
  488. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  489. return (-1);
  490. }
  491. while (ReadMME (plc, 0, (VS_FORWARD_CONFIG | MMTYPE_CNF)) &gt; 0)
  492. {
  493. if (confirm-&gt;RESULTCODE)
  494. {
  495. Failure (plc, PLC_WONTDOIT);
  496. continue;
  497. }
  498. }
  499. return (0);
  500. }
  501. /*====================================================================*
  502. *
  503. * signed RemoveVLANIDs (struct plc * plc, struct item list [], unsigned items);
  504. *
  505. *
  506. *--------------------------------------------------------------------*/
  507. static signed RemoveVLANIDs (struct plc * plc, struct item list [], unsigned items)
  508. {
  509. struct channel * channel = (struct channel *)(plc-&gt;channel);
  510. struct message * message = (struct message *)(plc-&gt;message);
  511. #ifndef __GNUC__
  512. #pragma pack (push,1)
  513. #endif
  514. struct __packed vs_forward_config_request
  515. {
  516. struct ethernet_hdr ethernet;
  517. struct qualcomm_hdr qualcomm;
  518. uint8_t RESERVED1;
  519. uint8_t MREQUEST;
  520. uint8_t MVERSION;
  521. uint32_t RESERVED2;
  522. uint16_t ITEMS;
  523. struct item LIST [1];
  524. }
  525. * request = (struct vs_forward_config_request *) (message);
  526. struct __packed vs_forward_config_confirm
  527. {
  528. struct ethernet_hdr ethernet;
  529. struct qualcomm_hdr qualcomm;
  530. uint8_t RESERVED1;
  531. uint8_t RESULTCODE;
  532. uint8_t OPERATION;
  533. uint8_t MVERSION;
  534. uint32_t RESERVED2;
  535. }
  536. * confirm = (struct vs_forward_config_confirm *) (message);
  537. #ifndef __GNUC__
  538. #pragma pack (pop)
  539. #endif
  540. struct item * item = request-&gt;LIST;
  541. memset (message, 0, sizeof (* message));
  542. EthernetHeader (&amp;request-&gt;ethernet, channel-&gt;peer, channel-&gt;host, channel-&gt;type);
  543. QualcommHeader (&amp;request-&gt;qualcomm, 0, (VS_FORWARD_CONFIG | MMTYPE_REQ));
  544. request-&gt;MREQUEST = PLCFWD_REM;
  545. request-&gt;MVERSION = PLCFWD_VER;
  546. request-&gt;ITEMS = HTOLE16 (items);
  547. while (items--)
  548. {
  549. unsigned count;
  550. memcpy (item-&gt;MAC_ADDR, list-&gt;MAC_ADDR, sizeof (item-&gt;MAC_ADDR));
  551. item-&gt;NUM_VLANIDS = HTOLE16 (list-&gt;NUM_VLANIDS);
  552. for (count = 0; count &lt; list-&gt;NUM_VLANIDS; count++)
  553. {
  554. item-&gt;VLANID [count] = HTOLE16 (list-&gt;VLANID [count]);
  555. }
  556. // item++;
  557. item = (struct item *)(&amp;item-&gt;VLANID [count]);
  558. list++;
  559. }
  560. plc-&gt;packetsize = (signed)((uint8_t *)(item) - (uint8_t *)(request));
  561. if (SendMME (plc) &lt;= 0)
  562. {
  563. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  564. return (-1);
  565. }
  566. while (ReadMME (plc, 0, (VS_FORWARD_CONFIG | MMTYPE_CNF)) &gt; 0)
  567. {
  568. if (confirm-&gt;RESULTCODE)
  569. {
  570. Failure (plc, PLC_WONTDOIT);
  571. continue;
  572. }
  573. }
  574. return (0);
  575. }
  576. /*====================================================================*
  577. *
  578. * signed CommitVLANIDs (struct plc * plc);
  579. *
  580. *
  581. *--------------------------------------------------------------------*/
  582. static signed CommitVLANIDs (struct plc * plc)
  583. {
  584. struct channel * channel = (struct channel *)(plc-&gt;channel);
  585. struct message * message = (struct message *)(plc-&gt;message);
  586. #ifndef __GNUC__
  587. #pragma pack (push,1)
  588. #endif
  589. struct __packed vs_forward_config_request
  590. {
  591. struct ethernet_hdr ethernet;
  592. struct qualcomm_hdr qualcomm;
  593. uint8_t RESERVED1;
  594. uint8_t MREQUEST;
  595. uint8_t MVERSION;
  596. uint32_t RESERVED2;
  597. }
  598. * request = (struct vs_forward_config_request *) (message);
  599. struct __packed vs_forward_config_confirm
  600. {
  601. struct ethernet_hdr ethernet;
  602. struct qualcomm_hdr qualcomm;
  603. uint8_t RESERVED1;
  604. uint8_t RESULTCODE;
  605. uint8_t OPERATION;
  606. uint8_t MVERSION;
  607. uint32_t RESERVED2;
  608. }
  609. * confirm = (struct vs_forward_config_confirm *) (message);
  610. #ifndef __GNUC__
  611. #pragma pack (pop)
  612. #endif
  613. memset (message, 0, sizeof (* message));
  614. EthernetHeader (&amp;request-&gt;ethernet, channel-&gt;peer, channel-&gt;host, channel-&gt;type);
  615. QualcommHeader (&amp;request-&gt;qualcomm, 0, (VS_FORWARD_CONFIG | MMTYPE_REQ));
  616. request-&gt;MREQUEST = PLCFWD_STO;
  617. request-&gt;MVERSION = PLCFWD_VER;
  618. plc-&gt;packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
  619. if (SendMME (plc) &lt;= 0)
  620. {
  621. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  622. return (-1);
  623. }
  624. while (ReadMME (plc, 0, (VS_FORWARD_CONFIG | MMTYPE_CNF)) &gt; 0)
  625. {
  626. if (confirm-&gt;RESULTCODE)
  627. {
  628. Failure (plc, PLC_WONTDOIT);
  629. continue;
  630. }
  631. }
  632. return (0);
  633. }
  634. /*====================================================================*
  635. *
  636. * signed ControlVLANIDs (struct plc * plc);
  637. *
  638. *
  639. *--------------------------------------------------------------------*/
  640. static signed ControlVLANIDs (struct plc * plc)
  641. {
  642. struct channel * channel = (struct channel *)(plc-&gt;channel);
  643. struct message * message = (struct message *)(plc-&gt;message);
  644. #ifndef __GNUC__
  645. #pragma pack (push,1)
  646. #endif
  647. struct __packed vs_forward_config_request
  648. {
  649. struct ethernet_hdr ethernet;
  650. struct qualcomm_hdr qualcomm;
  651. uint8_t RESERVED1;
  652. uint8_t MREQUEST;
  653. uint8_t MVERSION;
  654. uint32_t RESERVED2;
  655. uint8_t ENABLE;
  656. uint8_t UPSTREAMCHECK;
  657. uint8_t RESERVED3;
  658. }
  659. * request = (struct vs_forward_config_request *) (message);
  660. struct __packed vs_forward_config_confirm
  661. {
  662. struct ethernet_hdr ethernet;
  663. struct qualcomm_hdr qualcomm;
  664. uint8_t RESERVED1;
  665. uint8_t RESULTCODE;
  666. uint8_t OPERATION;
  667. uint8_t MVERSION;
  668. uint32_t RESERVED2;
  669. }
  670. * confirm = (struct vs_forward_config_confirm *) (message);
  671. #ifndef __GNUC__
  672. #pragma pack (pop)
  673. #endif
  674. memset (message, 0, sizeof (* message));
  675. EthernetHeader (&amp;request-&gt;ethernet, channel-&gt;peer, channel-&gt;host, channel-&gt;type);
  676. QualcommHeader (&amp;request-&gt;qualcomm, 0, (VS_FORWARD_CONFIG | MMTYPE_REQ));
  677. request-&gt;MREQUEST = PLCFWD_CTL;
  678. request-&gt;MVERSION = PLCFWD_VER;
  679. request-&gt;ENABLE = plc-&gt;module;
  680. request-&gt;UPSTREAMCHECK = plc-&gt;pushbutton;
  681. plc-&gt;packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
  682. if (SendMME (plc) &lt;= 0)
  683. {
  684. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  685. return (-1);
  686. }
  687. while (ReadMME (plc, 0, (VS_FORWARD_CONFIG | MMTYPE_CNF)) &gt; 0)
  688. {
  689. if (confirm-&gt;RESULTCODE)
  690. {
  691. Failure (plc, PLC_WONTDOIT);
  692. continue;
  693. }
  694. }
  695. return (0);
  696. }
  697. /*====================================================================*
  698. *
  699. * signed DefaultVLANIDs (struct plc * plc);
  700. *
  701. *
  702. *--------------------------------------------------------------------*/
  703. static signed DefaultVLANIDs (struct plc * plc, struct item list [], unsigned items)
  704. {
  705. struct channel * channel = (struct channel *)(plc-&gt;channel);
  706. struct message * message = (struct message *)(plc-&gt;message);
  707. #ifndef __GNUC__
  708. #pragma pack (push,1)
  709. #endif
  710. struct __packed vs_forward_config_request
  711. {
  712. struct ethernet_hdr ethernet;
  713. struct qualcomm_hdr qualcomm;
  714. uint8_t RESERVED1;
  715. uint8_t MREQUEST;
  716. uint8_t MVERSION;
  717. uint32_t RESERVED2;
  718. uint16_t VLANID;
  719. uint16_t RESERVED3;
  720. }
  721. * request = (struct vs_forward_config_request *) (message);
  722. struct __packed vs_forward_config_confirm
  723. {
  724. struct ethernet_hdr ethernet;
  725. struct qualcomm_hdr qualcomm;
  726. uint8_t RESERVED1;
  727. uint8_t RESULTCODE;
  728. uint8_t OPERATION;
  729. uint8_t MVERSION;
  730. uint32_t RESERVED2;
  731. }
  732. * confirm = (struct vs_forward_config_confirm *) (message);
  733. #ifndef __GNUC__
  734. #pragma pack (pop)
  735. #endif
  736. memset (message, 0, sizeof (* message));
  737. EthernetHeader (&amp;request-&gt;ethernet, channel-&gt;peer, channel-&gt;host, channel-&gt;type);
  738. QualcommHeader (&amp;request-&gt;qualcomm, 0, (VS_FORWARD_CONFIG | MMTYPE_REQ));
  739. request-&gt;MREQUEST = PLCFWD_SET;
  740. request-&gt;MVERSION = PLCFWD_VER;
  741. request-&gt;VLANID = HTOLE16 (list [0].VLANID [0]);
  742. plc-&gt;packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
  743. if (SendMME (plc) &lt;= 0)
  744. {
  745. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  746. return (-1);
  747. }
  748. while (ReadMME (plc, 0, (VS_FORWARD_CONFIG | MMTYPE_CNF)) &gt; 0)
  749. {
  750. if (confirm-&gt;RESULTCODE)
  751. {
  752. Failure (plc, PLC_WONTDOIT);
  753. continue;
  754. }
  755. }
  756. return (0);
  757. }
  758. /*====================================================================*
  759. *
  760. * signed ForwardVLANIDs (struct plc * plc);
  761. *
  762. *
  763. *--------------------------------------------------------------------*/
  764. static signed ForwardVLANIDs (struct plc * plc)
  765. {
  766. struct channel * channel = (struct channel *)(plc-&gt;channel);
  767. struct message * message = (struct message *)(plc-&gt;message);
  768. #ifndef __GNUC__
  769. #pragma pack (push,1)
  770. #endif
  771. struct __packed vs_forward_config_request
  772. {
  773. struct ethernet_hdr ethernet;
  774. struct qualcomm_hdr qualcomm;
  775. uint8_t RESERVED1;
  776. uint8_t MREQUEST;
  777. uint8_t MVERSION;
  778. uint32_t RESERVED2;
  779. uint8_t ENABLED;
  780. uint16_t VLANID;
  781. uint16_t RESERVED3;
  782. struct item ITEM;
  783. }
  784. * request = (struct vs_forward_config_request *) (message);
  785. struct __packed vs_forward_config_confirm
  786. {
  787. struct ethernet_hdr ethernet;
  788. struct qualcomm_hdr qualcomm;
  789. uint8_t RESERVED1;
  790. uint8_t RESULTCODE;
  791. uint8_t OPERATION;
  792. uint8_t MVERSION;
  793. uint32_t RESERVED2;
  794. }
  795. * confirm = (struct vs_forward_config_confirm *) (message);
  796. #ifndef __GNUC__
  797. #pragma pack (pop)
  798. #endif
  799. memset (message, 0, sizeof (* message));
  800. EthernetHeader (&amp;request-&gt;ethernet, channel-&gt;peer, channel-&gt;host, channel-&gt;type);
  801. QualcommHeader (&amp;request-&gt;qualcomm, 0, (VS_FORWARD_CONFIG | MMTYPE_REQ));
  802. request-&gt;MREQUEST = PLCFWD_FWD;
  803. request-&gt;MVERSION = PLCFWD_VER;
  804. plc-&gt;packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
  805. if (SendMME (plc) &lt;= 0)
  806. {
  807. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  808. return (-1);
  809. }
  810. while (ReadMME (plc, 0, (VS_FORWARD_CONFIG | MMTYPE_CNF)) &gt; 0)
  811. {
  812. if (confirm-&gt;RESULTCODE)
  813. {
  814. Failure (plc, PLC_WONTDOIT);
  815. continue;
  816. }
  817. }
  818. return (0);
  819. }
  820. /*====================================================================*
  821. *
  822. * void function (struct plc * plc, struct item list [], unsigned items);
  823. *
  824. * perform the VLANID action specified by the action member
  825. * in struct plc as set in the main program; only one action
  826. * is performed;
  827. *
  828. *
  829. *--------------------------------------------------------------------*/
  830. static void function (struct plc * plc, uint32_t offset, uint32_t length, struct item * list, unsigned items)
  831. {
  832. if (plc-&gt;action == PLCFWD_GET)
  833. {
  834. ReadVLANIDs (plc, offset, length);
  835. return;
  836. }
  837. if (plc-&gt;action == PLCFWD_ADD)
  838. {
  839. AddVLANIDs (plc, list, items);
  840. return;
  841. }
  842. if (plc-&gt;action == PLCFWD_REM)
  843. {
  844. RemoveVLANIDs (plc, list, items);
  845. return;
  846. }
  847. if (plc-&gt;action == PLCFWD_STO)
  848. {
  849. CommitVLANIDs (plc);
  850. return;
  851. }
  852. if (plc-&gt;action == PLCFWD_CTL)
  853. {
  854. ControlVLANIDs (plc);
  855. return;
  856. }
  857. if (plc-&gt;action == PLCFWD_SET)
  858. {
  859. DefaultVLANIDs (plc, list, items);
  860. return;
  861. }
  862. if (plc-&gt;action == PLCFWD_FWD)
  863. {
  864. ForwardVLANIDs (plc);
  865. return;
  866. }
  867. return;
  868. }
  869. /*====================================================================*
  870. *
  871. * int main (int argc, char const * argv[]);
  872. *
  873. *
  874. *--------------------------------------------------------------------*/
  875. int main (int argc, char const * argv [])
  876. {
  877. extern struct channel channel;
  878. static char const * optv [] =
  879. {
  880. &quot;ACD:ef:i:l:M:o:qRS:t:vxz:&quot;,
  881. &quot;device [device] [...] [&gt; stdout]&quot;,
  882. &quot;Qualcomm Atheros VLANID Forward Configuration Manager&quot;,
  883. &quot;A\tadd VLAN ID of multiple slaves to memory&quot;,
  884. &quot;C\tcommit configuration to flash memory&quot;,
  885. &quot;D x\tset default VLAN ID&quot;,
  886. &quot;e\tredirect stderr to stdout&quot;,
  887. &quot;f s\tread VLANIDS from file (s)&quot;,
  888. #if defined (WINPCAP) || defined (LIBPCAP)
  889. &quot;i n\thost interface is (n) [&quot; LITERAL (CHANNEL_ETHNUMBER) &quot;]&quot;,
  890. #else
  891. &quot;i s\thost interface is (s) [&quot; LITERAL (CHANNEL_ETHDEVICE) &quot;]&quot;,
  892. #endif
  893. &quot;l n\tdata length in bytes [&quot; LITERAL (PLCFWD_LENGTH) &quot;]&quot;,
  894. &quot;M n\tenable VLANID forwarding on the master&quot;,
  895. &quot;o x\tdata offset in bytes [&quot; LITERAL (PLCFWD_OFFSET) &quot;]&quot;,
  896. &quot;q\tquiet mode&quot;,
  897. &quot;R\tremove VLAN ID of multiple slaves from memory&quot;,
  898. &quot;S n\tenable VLANID forwarding on all slaves&quot;,
  899. &quot;t n\ttimeout is (n) millisecond [&quot; LITERAL (CHANNEL_TIMEOUT) &quot;]&quot;,
  900. &quot;v\tverbose mode&quot;,
  901. &quot;x\texit on error&quot;,
  902. &quot;z s\tslavespec&quot;,
  903. (char const *) (0)
  904. };
  905. #include &quot;../plc/plc.c&quot;
  906. struct item list [128];
  907. unsigned size = sizeof (list) / sizeof (struct item);
  908. unsigned items = 0;
  909. uint32_t offset = 0;
  910. uint32_t length = 0;
  911. signed c;
  912. memset (&amp;list, 0, sizeof (list));
  913. if (getenv (PLCDEVICE))
  914. {
  915. channel.ifname = strdup (getenv (PLCDEVICE));
  916. }
  917. optind = 1;
  918. while ((c = getoptv (argc, argv, optv)) != -1)
  919. {
  920. switch (c)
  921. {
  922. case 'A':
  923. plc.action = PLCFWD_ADD;
  924. break;
  925. case 'C':
  926. plc.action = PLCFWD_STO;
  927. break;
  928. case 'D':
  929. plc.action = PLCFWD_SET;
  930. list [0].VLANID [0] = (uint16_t)(basespec (optarg, 10, sizeof (uint16_t)));
  931. break;
  932. case 'e':
  933. dup2 (STDOUT_FILENO, STDERR_FILENO);
  934. break;
  935. case 'f':
  936. if (!freopen (optarg, &quot;rb&quot;, stdin))
  937. {
  938. error (1, errno, &quot;%s&quot;, optarg);
  939. }
  940. items += readlist (&amp;list [items], size - items);
  941. break;
  942. case 'i':
  943. #if defined (WINPCAP) || defined (LIBPCAP)
  944. channel.ifindex = atoi (optarg);
  945. #else
  946. channel.ifname = optarg;
  947. #endif
  948. break;
  949. case 'M':
  950. plc.action = PLCFWD_CTL;
  951. plc.module = (uint8_t)(uintspec (synonym (optarg, states, STATES), 0, UCHAR_MAX));
  952. break;
  953. case 'l':
  954. length = (uint32_t) (basespec (optarg, 10, sizeof (length)));
  955. break;
  956. case 'o':
  957. offset = (uint32_t) (basespec (optarg, 10, sizeof (offset)));
  958. break;
  959. case 'q':
  960. _setbits (channel.flags, CHANNEL_SILENCE);
  961. _setbits (plc.flags, PLC_SILENCE);
  962. break;
  963. case 'R':
  964. plc.action = PLCFWD_REM;
  965. break;
  966. case 'S':
  967. plc.action = PLCFWD_CTL;
  968. plc.pushbutton = (uint8_t)(uintspec (synonym (optarg, states, STATES), 0, UCHAR_MAX));
  969. break;
  970. case 't':
  971. channel.timeout = (signed)(uintspec (optarg, 0, UINT_MAX));
  972. break;
  973. case 'v':
  974. _setbits (channel.flags, CHANNEL_VERBOSE);
  975. _setbits (plc.flags, PLC_VERBOSE);
  976. break;
  977. case 'x':
  978. _setbits (plc.flags, PLC_BAILOUT);
  979. break;
  980. case 'z':
  981. readitem (&amp;list [items++], optarg);
  982. break;
  983. default:
  984. break;
  985. }
  986. }
  987. argc -= optind;
  988. argv += optind;
  989. #if 0
  990. showlist (list, items);
  991. #endif
  992. openchannel (&amp;channel);
  993. if (!(plc.message = malloc (sizeof (* plc.message))))
  994. {
  995. error (1, errno, PLC_NOMEMORY);
  996. }
  997. if (!argc)
  998. {
  999. function (&amp;plc, offset, length, list, items);
  1000. }
  1001. while ((argc) &amp;&amp; (* argv))
  1002. {
  1003. if (!hexencode (channel.peer, sizeof (channel.peer), synonym (* argv, devices, SIZEOF (devices))))
  1004. {
  1005. error (1, errno, PLC_BAD_MAC, * argv);
  1006. }
  1007. function (&amp;plc, offset, length, list, items);
  1008. argv++;
  1009. argc--;
  1010. }
  1011. free (plc.message);
  1012. closechannel (&amp;channel);
  1013. return (0);
  1014. }
  1015. </pre>
  1016. <div class='footerlink'>
  1017. [<a href='plcdevs.c.html' title=' plcdevs.c '>PREV</a>]
  1018. [<a href='toolkit.html' title=' Index '>HOME</a>]
  1019. [<a href='plcget.c.html' title=' plcget.c '>NEXT</a>]
  1020. </div>
  1021. </body>
  1022. </html>