TLVPeek.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. /*====================================================================*
  2. *
  3. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  4. *
  5. * All rights reserved.
  6. *
  7. *====================================================================*/
  8. #ifndef TLVPEEK_SOURCE
  9. #define TLVPEEK_SOURCE
  10. #include <stdio.h>
  11. #include <stdint.h>
  12. #include <string.h>
  13. #include <errno.h>
  14. #include "../tools/types.h"
  15. #include "../tools/error.h"
  16. #include "../tools/memory.h"
  17. #include "../tools/format.h"
  18. #include "../lldp/lldp.h"
  19. /*====================================================================*
  20. *
  21. * void TLVPeek (void const * memory, size_t extent);
  22. *
  23. * lldp.h
  24. *
  25. * search an IEEE 802.1AB TLV list for known types and print the
  26. * values on stdout; runtime software will store values instead
  27. * printing them;
  28. *
  29. * this function handles Qualcomm Atheros Organizationally Specific
  30. * TLVs;
  31. *
  32. *--------------------------------------------------------------------*/
  33. static void TLVPeekOS (void const * memory, size_t extent)
  34. {
  35. static const byte localcast [] =
  36. {
  37. 0x00,
  38. 0xB0,
  39. 0x52
  40. };
  41. struct tlv_os * tlv_os = (struct tlv_os *) (memory);
  42. if (! memcmp (tlv_os->OUI, localcast, sizeof (tlv_os->OUI)))
  43. {
  44. char buffer [TLV_SIZE_MASK + 1] =
  45. {
  46. 0
  47. };
  48. uint16_t mysize = TLV_SIZE (tlv_os);
  49. switch (tlv_os->subtype)
  50. {
  51. case TLV_OS_MANUFACTURER:
  52. printf ("MFG %s\n", tlv_os->data);
  53. break;
  54. case TLV_OS_HARDWARE_MODEL:
  55. printf ("MDL %s\n", tlv_os->data);
  56. break;
  57. case TLV_OS_SERIAL_NUMBER:
  58. printf ("S/N %s\n", tlv_os->data);
  59. break;
  60. case TLV_OS_PLC_MAC:
  61. printf ("PLC MAC %s\n", hexstring (buffer, sizeof (buffer), tlv_os->data, mysize));
  62. break;
  63. case TLV_OS_HOST_MAC:
  64. printf ("HOST MAC %s\n", hexstring (buffer, sizeof (buffer), tlv_os->data, mysize));
  65. break;
  66. case TLV_OS_WIFI_MAC:
  67. printf ("WIFI MAC %s\n", hexstring (buffer, sizeof (buffer), tlv_os->data, mysize));
  68. break;
  69. case TLV_OS_WIFI_IP:
  70. printf ("WIFI IP %s\n", decstring (buffer, sizeof (buffer), tlv_os->data, mysize));
  71. break;
  72. default:
  73. break;
  74. }
  75. }
  76. fflush (stdout);
  77. return;
  78. }
  79. /*====================================================================*
  80. *
  81. * void ChassisID (void const * memory, ssize_t extent);
  82. *
  83. * decode Chassis ID TLV per IEEE 802.1AB, Clause 8.5.2;
  84. *
  85. * this code does not handle all possible option; users must add
  86. * missing code that they require;
  87. *
  88. * Contributor(s):
  89. * Charles Maier <cmaier@qca.qualcomm.com>
  90. *
  91. *--------------------------------------------------------------------*/
  92. static void ChassisID (void const * memory, ssize_t extent)
  93. {
  94. struct tlv_id * tlv_id = (struct tlv_id *) (memory);
  95. char buffer [TLV_SIZE_MASK + 1] =
  96. {
  97. 0
  98. };
  99. switch (tlv_id->subtype)
  100. {
  101. case 1:
  102. break;
  103. case 2:
  104. break;
  105. case 3:
  106. break;
  107. case 4:
  108. printf ("Chassis MAC: %s\n", hexstring (buffer, sizeof (buffer), tlv_id->data, 6));
  109. break;
  110. case 5:
  111. break;
  112. case 6:
  113. break;
  114. case 7:
  115. printf ("Chassis ID: %s\n", (char *) (tlv_id->data));
  116. break;
  117. default:
  118. error (0, EINVAL, "Unknown Chassis ID subtype (%d)", tlv_id->subtype);
  119. break;
  120. }
  121. return;
  122. }
  123. /*====================================================================*
  124. *
  125. * void PortID (void const * memory, ssize_t extent);
  126. *
  127. * decode Port ID TLV per IEEE 802.1AB, Clause 8.5.3;
  128. *
  129. * this code does not handle all possible option; users must add
  130. * missing code that they require;
  131. *
  132. * Contributor(s):
  133. * Charles Maier <cmaier@qca.qualcomm.com>
  134. *
  135. *--------------------------------------------------------------------*/
  136. static void PortID (void const * memory, ssize_t extent)
  137. {
  138. struct tlv_id * tlv_id = (struct tlv_id *) (memory);
  139. char buffer [TLV_SIZE_MASK + 1] =
  140. {
  141. 0
  142. };
  143. switch (tlv_id->subtype)
  144. {
  145. case 1:
  146. break;
  147. case 2:
  148. break;
  149. case 3:
  150. printf ("Port MAC: %s\n", hexstring (buffer, sizeof (buffer), tlv_id->data, 6));
  151. break;
  152. case 4:
  153. break;
  154. case 5:
  155. break;
  156. case 6:
  157. break;
  158. case 7:
  159. printf ("Port ID: %s\n", (char *) (tlv_id->data));
  160. break;
  161. default:
  162. error (0, EINVAL, "Unknown Port ID subtype (%d)", tlv_id->subtype);
  163. break;
  164. }
  165. return;
  166. }
  167. /*====================================================================*
  168. *
  169. * void TimeToLive (void const * memory, ssize_t extent);
  170. *
  171. * decode Time To Live TLV per IEEE 802.1AB, Clause 8.5.4; this
  172. * TLV is an unsigned 16-bit integer;
  173. *
  174. * Contributor(s):
  175. * Charles Maier <cmaier@qca.qualcomm.com>
  176. *
  177. *--------------------------------------------------------------------*/
  178. static void TimeToLive (void const * memory, ssize_t extent)
  179. {
  180. if (extent != sizeof (uint16_t))
  181. {
  182. error (0, EINVAL, "TTL Data Length Error");
  183. }
  184. printf ("TTL %d\n", BE16TOH (* (uint16_t *) (memory)));
  185. return;
  186. }
  187. /*====================================================================*
  188. *
  189. * void PortDescription (void const * memory, ssize_t extent);
  190. *
  191. * decode Port Description per IEEE 802.1AB, Clause 8.5.5; this
  192. * TLV is a string having up to 254 octets;
  193. *
  194. * Contributor(s):
  195. * Charles Maier <cmaier@qca.qualcomm.com>
  196. *
  197. *--------------------------------------------------------------------*/
  198. static void PortDescription (void const * memory, ssize_t extent)
  199. {
  200. if (extent > TLV_SIZE_MASK)
  201. {
  202. error (0, EINVAL, "Port Description Length Error");
  203. }
  204. printf ("Port Description: %s\n", (char *) (memory));
  205. return;
  206. }
  207. /*====================================================================*
  208. *
  209. * void SystemName (void const * memory, ssize_t extent);
  210. *
  211. * decode System Name per IEEE 802.1AB, Clause 8.5.6; this TLV is
  212. * a string having up to 254 octets;
  213. *
  214. * Contributor(s):
  215. * Charles Maier <cmaier@qca.qualcomm.com>
  216. *
  217. *--------------------------------------------------------------------*/
  218. static void SystemName (void const * memory, ssize_t extent)
  219. {
  220. if (extent > TLV_SIZE_MASK)
  221. {
  222. error (0, EINVAL, "System Name Length Error");
  223. }
  224. printf ("System Name: %s\n", (char *) (memory));
  225. return;
  226. }
  227. /*====================================================================*
  228. *
  229. * void SystemDescription (void const * memory, ssize_t extent);
  230. *
  231. * decode System Name per IEEE 802.1AB, Clause 8.5.7; this TLV is
  232. * a string having up to 254 octets;
  233. *
  234. * Contributor(s):
  235. * Charles Maier <cmaier@qca.qualcomm.com>
  236. *
  237. *--------------------------------------------------------------------*/
  238. static void SystemDescription (void const * memory, ssize_t extent)
  239. {
  240. if (extent > TLV_SIZE_MASK)
  241. {
  242. error (0, EINVAL, "System Description Length Error");
  243. }
  244. printf ("System Description: %s\n", (char *) (memory));
  245. return;
  246. }
  247. /*====================================================================*
  248. *
  249. * void SystemCapability (void const * memory, ssize_t extent);
  250. *
  251. * Contributor(s):
  252. * Charles Maier <cmaier@qca.qualcomm.com>
  253. *
  254. *--------------------------------------------------------------------*/
  255. static void SystemCapability (void const * memory, ssize_t extent)
  256. {
  257. struct cap
  258. {
  259. uint8_t subtype;
  260. uint16_t available;
  261. uint16_t enabled;
  262. }
  263. * cap = (struct cap *) (memory);
  264. char const * capabilities [] =
  265. {
  266. "Other",
  267. "Repeater",
  268. #if 0
  269. /*
  270. * Full capability names from IEEE 802.1AB-2009;
  271. */
  272. "MAC Bridge",
  273. "WLAN Access Point",
  274. "Router",
  275. "Telephone",
  276. "DOCSIS Cable Device",
  277. "Station Only",
  278. "C-VLAN Component of VLAN Bridge",
  279. "S-VLAN Component of VLAN Bridge",
  280. "Two-port MAC Relay (TPMR)",
  281. #else
  282. /*
  283. * Abbreviated capability names compact display;
  284. */
  285. "Bridge",
  286. "AP",
  287. "Router",
  288. "Voice",
  289. "DOCSIS",
  290. "Station",
  291. "C-VLAN",
  292. "S-VLAN",
  293. "TPMR",
  294. #endif
  295. (char const *) (0)
  296. };
  297. char buffer [TLV_SIZE_MASK + 1] =
  298. {
  299. 0
  300. };
  301. strfbits (buffer, sizeof (buffer), capabilities, ", ", BE16TOH (cap->available));
  302. printf ("Feature: %s\n", buffer);
  303. strfbits (buffer, sizeof (buffer), capabilities, ", ", BE16TOH (cap->available));
  304. printf ("Enabled: %s\n", buffer);
  305. return;
  306. }
  307. /*====================================================================*
  308. *
  309. * void ManagementAddress (void const * memory, ssize_t extent)
  310. *
  311. * Contributor(s):
  312. * Charles Maier <cmaier@qca.qualcomm.com>
  313. *
  314. *--------------------------------------------------------------------*/
  315. static void ManagementAddress (void const * memory, ssize_t extent)
  316. {
  317. printf ("MGMT URL: %s\n", (char *) (memory));
  318. return;
  319. }
  320. /*====================================================================*
  321. *
  322. * void TLVPeek (void const * memory, ssize_t extent);
  323. *
  324. * lldp.h
  325. *
  326. * search an IEEE 802.1AB TLV list for known types and print the
  327. * values on stdout; runtime software will store values instead
  328. * printing them;
  329. *
  330. * this function handles Qualcomm Atheros Organizationally Specific
  331. * TLVs;
  332. *
  333. *
  334. * Contributor(s):
  335. * Charles Maier <cmaier@qca.qualcomm.com>
  336. *
  337. *--------------------------------------------------------------------*/
  338. void TLVPeek (void const * memory, size_t extent)
  339. {
  340. byte * offset = (void *) (memory);
  341. while (extent > 0)
  342. {
  343. struct tlv * tlv = (struct tlv *) (offset);
  344. uint16_t mytype = TLV_TYPE (tlv);
  345. uint16_t mysize = TLV_SIZE (tlv);
  346. if (! tlv->head)
  347. {
  348. break;
  349. }
  350. switch (mytype)
  351. {
  352. case TLV_IEEE_CHASSIS_ID:
  353. ChassisID (tlv->data, mysize);
  354. break;
  355. case TLV_IEEE_PORT_ID:
  356. PortID (tlv->data, mysize);
  357. break;
  358. case TLV_IEEE_TIME_TO_LIVE:
  359. TimeToLive (tlv->data, mysize);
  360. break;
  361. case TLV_IEEE_PORT_DESCRIPTION:
  362. PortDescription (tlv->data, mysize);
  363. break;
  364. case TLV_IEEE_SYSTEM_NAME:
  365. SystemName (tlv->data, mysize);
  366. break;
  367. case TLV_IEEE_SYSTEM_DESCRIPTION:
  368. SystemDescription (tlv->data, mysize);
  369. break;
  370. case TLV_IEEE_SYSTEM_CAPABILITIES:
  371. SystemCapability (tlv->data, mysize);
  372. break;
  373. case TLV_IEEE_MANAGEMENT_ADDRESS:
  374. ManagementAddress (tlv->data, mysize);
  375. break;
  376. case TLV_IEEE_ORG_SPECIFIC:
  377. TLVPeekOS (offset, extent);
  378. mysize += 4;
  379. break;
  380. default:
  381. break;
  382. }
  383. offset += sizeof (* tlv) + mysize;
  384. extent -= sizeof (* tlv) + mysize;
  385. }
  386. printf ("\n");
  387. return;
  388. }
  389. #endif