print-lldp.c 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661
  1. /*
  2. * Copyright (c) 1998-2007 The TCPDUMP project
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that: (1) source code
  6. * distributions retain the above copyright notice and this paragraph
  7. * in its entirety, and (2) distributions including binary code include
  8. * the above copyright notice and this paragraph in its entirety in
  9. * the documentation or other materials provided with the distribution.
  10. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
  11. * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
  12. * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13. * FOR A PARTICULAR PURPOSE.
  14. *
  15. * Original code by Hannes Gredler (hannes@gredler.at)
  16. * IEEE and TIA extensions by Carles Kishimoto <carles.kishimoto@gmail.com>
  17. * DCBX extensions by Kaladhar Musunuru <kaladharm@sourceforge.net>
  18. */
  19. /* \summary: IEEE 802.1ab Link Layer Discovery Protocol (LLDP) printer */
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include <netdissect-stdinc.h>
  24. #include <stdio.h>
  25. #include "netdissect.h"
  26. #include "extract.h"
  27. #include "addrtoname.h"
  28. #include "af.h"
  29. #include "oui.h"
  30. #define LLDP_EXTRACT_TYPE(x) (((x)&0xfe00)>>9)
  31. #define LLDP_EXTRACT_LEN(x) ((x)&0x01ff)
  32. /*
  33. * TLV type codes
  34. */
  35. #define LLDP_END_TLV 0
  36. #define LLDP_CHASSIS_ID_TLV 1
  37. #define LLDP_PORT_ID_TLV 2
  38. #define LLDP_TTL_TLV 3
  39. #define LLDP_PORT_DESCR_TLV 4
  40. #define LLDP_SYSTEM_NAME_TLV 5
  41. #define LLDP_SYSTEM_DESCR_TLV 6
  42. #define LLDP_SYSTEM_CAP_TLV 7
  43. #define LLDP_MGMT_ADDR_TLV 8
  44. #define LLDP_PRIVATE_TLV 127
  45. static const struct tok lldp_tlv_values[] = {
  46. { LLDP_END_TLV, "End" },
  47. { LLDP_CHASSIS_ID_TLV, "Chassis ID" },
  48. { LLDP_PORT_ID_TLV, "Port ID" },
  49. { LLDP_TTL_TLV, "Time to Live" },
  50. { LLDP_PORT_DESCR_TLV, "Port Description" },
  51. { LLDP_SYSTEM_NAME_TLV, "System Name" },
  52. { LLDP_SYSTEM_DESCR_TLV, "System Description" },
  53. { LLDP_SYSTEM_CAP_TLV, "System Capabilities" },
  54. { LLDP_MGMT_ADDR_TLV, "Management Address" },
  55. { LLDP_PRIVATE_TLV, "Organization specific" },
  56. { 0, NULL}
  57. };
  58. /*
  59. * Chassis ID subtypes
  60. */
  61. #define LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE 1
  62. #define LLDP_CHASSIS_INTF_ALIAS_SUBTYPE 2
  63. #define LLDP_CHASSIS_PORT_COMP_SUBTYPE 3
  64. #define LLDP_CHASSIS_MAC_ADDR_SUBTYPE 4
  65. #define LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE 5
  66. #define LLDP_CHASSIS_INTF_NAME_SUBTYPE 6
  67. #define LLDP_CHASSIS_LOCAL_SUBTYPE 7
  68. static const struct tok lldp_chassis_subtype_values[] = {
  69. { LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE, "Chassis component"},
  70. { LLDP_CHASSIS_INTF_ALIAS_SUBTYPE, "Interface alias"},
  71. { LLDP_CHASSIS_PORT_COMP_SUBTYPE, "Port component"},
  72. { LLDP_CHASSIS_MAC_ADDR_SUBTYPE, "MAC address"},
  73. { LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE, "Network address"},
  74. { LLDP_CHASSIS_INTF_NAME_SUBTYPE, "Interface name"},
  75. { LLDP_CHASSIS_LOCAL_SUBTYPE, "Local"},
  76. { 0, NULL}
  77. };
  78. /*
  79. * Port ID subtypes
  80. */
  81. #define LLDP_PORT_INTF_ALIAS_SUBTYPE 1
  82. #define LLDP_PORT_PORT_COMP_SUBTYPE 2
  83. #define LLDP_PORT_MAC_ADDR_SUBTYPE 3
  84. #define LLDP_PORT_NETWORK_ADDR_SUBTYPE 4
  85. #define LLDP_PORT_INTF_NAME_SUBTYPE 5
  86. #define LLDP_PORT_AGENT_CIRC_ID_SUBTYPE 6
  87. #define LLDP_PORT_LOCAL_SUBTYPE 7
  88. static const struct tok lldp_port_subtype_values[] = {
  89. { LLDP_PORT_INTF_ALIAS_SUBTYPE, "Interface alias"},
  90. { LLDP_PORT_PORT_COMP_SUBTYPE, "Port component"},
  91. { LLDP_PORT_MAC_ADDR_SUBTYPE, "MAC address"},
  92. { LLDP_PORT_NETWORK_ADDR_SUBTYPE, "Network Address"},
  93. { LLDP_PORT_INTF_NAME_SUBTYPE, "Interface Name"},
  94. { LLDP_PORT_AGENT_CIRC_ID_SUBTYPE, "Agent circuit ID"},
  95. { LLDP_PORT_LOCAL_SUBTYPE, "Local"},
  96. { 0, NULL}
  97. };
  98. /*
  99. * System Capabilities
  100. */
  101. #define LLDP_CAP_OTHER (1 << 0)
  102. #define LLDP_CAP_REPEATER (1 << 1)
  103. #define LLDP_CAP_BRIDGE (1 << 2)
  104. #define LLDP_CAP_WLAN_AP (1 << 3)
  105. #define LLDP_CAP_ROUTER (1 << 4)
  106. #define LLDP_CAP_PHONE (1 << 5)
  107. #define LLDP_CAP_DOCSIS (1 << 6)
  108. #define LLDP_CAP_STATION_ONLY (1 << 7)
  109. static const struct tok lldp_cap_values[] = {
  110. { LLDP_CAP_OTHER, "Other"},
  111. { LLDP_CAP_REPEATER, "Repeater"},
  112. { LLDP_CAP_BRIDGE, "Bridge"},
  113. { LLDP_CAP_WLAN_AP, "WLAN AP"},
  114. { LLDP_CAP_ROUTER, "Router"},
  115. { LLDP_CAP_PHONE, "Telephone"},
  116. { LLDP_CAP_DOCSIS, "Docsis"},
  117. { LLDP_CAP_STATION_ONLY, "Station Only"},
  118. { 0, NULL}
  119. };
  120. #define LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID 1
  121. #define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID 2
  122. #define LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME 3
  123. #define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY 4
  124. #define LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION 8
  125. #define LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION 9
  126. #define LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION 10
  127. #define LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION 11
  128. #define LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY 12
  129. #define LLDP_PRIVATE_8021_SUBTYPE_EVB 13
  130. #define LLDP_PRIVATE_8021_SUBTYPE_CDCP 14
  131. static const struct tok lldp_8021_subtype_values[] = {
  132. { LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID, "Port VLAN Id"},
  133. { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID, "Port and Protocol VLAN ID"},
  134. { LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME, "VLAN name"},
  135. { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY, "Protocol Identity"},
  136. { LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION, "Congestion Notification"},
  137. { LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION, "ETS Configuration"},
  138. { LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION, "ETS Recommendation"},
  139. { LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION, "Priority Flow Control Configuration"},
  140. { LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY, "Application Priority"},
  141. { LLDP_PRIVATE_8021_SUBTYPE_EVB, "EVB"},
  142. { LLDP_PRIVATE_8021_SUBTYPE_CDCP,"CDCP"},
  143. { 0, NULL}
  144. };
  145. #define LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT (1 << 1)
  146. #define LLDP_8021_PORT_PROTOCOL_VLAN_STATUS (1 << 2)
  147. static const struct tok lldp_8021_port_protocol_id_values[] = {
  148. { LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT, "supported"},
  149. { LLDP_8021_PORT_PROTOCOL_VLAN_STATUS, "enabled"},
  150. { 0, NULL}
  151. };
  152. #define LLDP_PRIVATE_8023_SUBTYPE_MACPHY 1
  153. #define LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER 2
  154. #define LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR 3
  155. #define LLDP_PRIVATE_8023_SUBTYPE_MTU 4
  156. static const struct tok lldp_8023_subtype_values[] = {
  157. { LLDP_PRIVATE_8023_SUBTYPE_MACPHY, "MAC/PHY configuration/status"},
  158. { LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER, "Power via MDI"},
  159. { LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR, "Link aggregation"},
  160. { LLDP_PRIVATE_8023_SUBTYPE_MTU, "Max frame size"},
  161. { 0, NULL}
  162. };
  163. #define LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES 1
  164. #define LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY 2
  165. #define LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID 3
  166. #define LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI 4
  167. #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV 5
  168. #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV 6
  169. #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV 7
  170. #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER 8
  171. #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME 9
  172. #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME 10
  173. #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID 11
  174. static const struct tok lldp_tia_subtype_values[] = {
  175. { LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES, "LLDP-MED Capabilities" },
  176. { LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY, "Network policy" },
  177. { LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID, "Location identification" },
  178. { LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI, "Extended power-via-MDI" },
  179. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Inventory - hardware revision" },
  180. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Inventory - firmware revision" },
  181. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Inventory - software revision" },
  182. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Inventory - serial number" },
  183. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Inventory - manufacturer name" },
  184. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Inventory - model name" },
  185. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Inventory - asset ID" },
  186. { 0, NULL}
  187. };
  188. #define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS 1
  189. #define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS 2
  190. static const struct tok lldp_tia_location_altitude_type_values[] = {
  191. { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS, "meters"},
  192. { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS, "floors"},
  193. { 0, NULL}
  194. };
  195. /* ANSI/TIA-1057 - Annex B */
  196. #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1 1
  197. #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2 2
  198. #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3 3
  199. #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4 4
  200. #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5 5
  201. #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6 6
  202. static const struct tok lldp_tia_location_lci_catype_values[] = {
  203. { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1, "national subdivisions (state,canton,region,province,prefecture)"},
  204. { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2, "county, parish, gun, district"},
  205. { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3, "city, township, shi"},
  206. { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4, "city division, borough, city district, ward chou"},
  207. { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5, "neighborhood, block"},
  208. { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6, "street"},
  209. { 0, NULL}
  210. };
  211. static const struct tok lldp_tia_location_lci_what_values[] = {
  212. { 0, "location of DHCP server"},
  213. { 1, "location of the network element believed to be closest to the client"},
  214. { 2, "location of the client"},
  215. { 0, NULL}
  216. };
  217. /*
  218. * From RFC 3636 - dot3MauType
  219. */
  220. #define LLDP_MAU_TYPE_UNKNOWN 0
  221. #define LLDP_MAU_TYPE_AUI 1
  222. #define LLDP_MAU_TYPE_10BASE_5 2
  223. #define LLDP_MAU_TYPE_FOIRL 3
  224. #define LLDP_MAU_TYPE_10BASE_2 4
  225. #define LLDP_MAU_TYPE_10BASE_T 5
  226. #define LLDP_MAU_TYPE_10BASE_FP 6
  227. #define LLDP_MAU_TYPE_10BASE_FB 7
  228. #define LLDP_MAU_TYPE_10BASE_FL 8
  229. #define LLDP_MAU_TYPE_10BROAD36 9
  230. #define LLDP_MAU_TYPE_10BASE_T_HD 10
  231. #define LLDP_MAU_TYPE_10BASE_T_FD 11
  232. #define LLDP_MAU_TYPE_10BASE_FL_HD 12
  233. #define LLDP_MAU_TYPE_10BASE_FL_FD 13
  234. #define LLDP_MAU_TYPE_100BASE_T4 14
  235. #define LLDP_MAU_TYPE_100BASE_TX_HD 15
  236. #define LLDP_MAU_TYPE_100BASE_TX_FD 16
  237. #define LLDP_MAU_TYPE_100BASE_FX_HD 17
  238. #define LLDP_MAU_TYPE_100BASE_FX_FD 18
  239. #define LLDP_MAU_TYPE_100BASE_T2_HD 19
  240. #define LLDP_MAU_TYPE_100BASE_T2_FD 20
  241. #define LLDP_MAU_TYPE_1000BASE_X_HD 21
  242. #define LLDP_MAU_TYPE_1000BASE_X_FD 22
  243. #define LLDP_MAU_TYPE_1000BASE_LX_HD 23
  244. #define LLDP_MAU_TYPE_1000BASE_LX_FD 24
  245. #define LLDP_MAU_TYPE_1000BASE_SX_HD 25
  246. #define LLDP_MAU_TYPE_1000BASE_SX_FD 26
  247. #define LLDP_MAU_TYPE_1000BASE_CX_HD 27
  248. #define LLDP_MAU_TYPE_1000BASE_CX_FD 28
  249. #define LLDP_MAU_TYPE_1000BASE_T_HD 29
  250. #define LLDP_MAU_TYPE_1000BASE_T_FD 30
  251. #define LLDP_MAU_TYPE_10GBASE_X 31
  252. #define LLDP_MAU_TYPE_10GBASE_LX4 32
  253. #define LLDP_MAU_TYPE_10GBASE_R 33
  254. #define LLDP_MAU_TYPE_10GBASE_ER 34
  255. #define LLDP_MAU_TYPE_10GBASE_LR 35
  256. #define LLDP_MAU_TYPE_10GBASE_SR 36
  257. #define LLDP_MAU_TYPE_10GBASE_W 37
  258. #define LLDP_MAU_TYPE_10GBASE_EW 38
  259. #define LLDP_MAU_TYPE_10GBASE_LW 39
  260. #define LLDP_MAU_TYPE_10GBASE_SW 40
  261. static const struct tok lldp_mau_types_values[] = {
  262. { LLDP_MAU_TYPE_UNKNOWN, "Unknown"},
  263. { LLDP_MAU_TYPE_AUI, "AUI"},
  264. { LLDP_MAU_TYPE_10BASE_5, "10BASE_5"},
  265. { LLDP_MAU_TYPE_FOIRL, "FOIRL"},
  266. { LLDP_MAU_TYPE_10BASE_2, "10BASE2"},
  267. { LLDP_MAU_TYPE_10BASE_T, "10BASET duplex mode unknown"},
  268. { LLDP_MAU_TYPE_10BASE_FP, "10BASEFP"},
  269. { LLDP_MAU_TYPE_10BASE_FB, "10BASEFB"},
  270. { LLDP_MAU_TYPE_10BASE_FL, "10BASEFL duplex mode unknown"},
  271. { LLDP_MAU_TYPE_10BROAD36, "10BROAD36"},
  272. { LLDP_MAU_TYPE_10BASE_T_HD, "10BASET hdx"},
  273. { LLDP_MAU_TYPE_10BASE_T_FD, "10BASET fdx"},
  274. { LLDP_MAU_TYPE_10BASE_FL_HD, "10BASEFL hdx"},
  275. { LLDP_MAU_TYPE_10BASE_FL_FD, "10BASEFL fdx"},
  276. { LLDP_MAU_TYPE_100BASE_T4, "100BASET4"},
  277. { LLDP_MAU_TYPE_100BASE_TX_HD, "100BASETX hdx"},
  278. { LLDP_MAU_TYPE_100BASE_TX_FD, "100BASETX fdx"},
  279. { LLDP_MAU_TYPE_100BASE_FX_HD, "100BASEFX hdx"},
  280. { LLDP_MAU_TYPE_100BASE_FX_FD, "100BASEFX fdx"},
  281. { LLDP_MAU_TYPE_100BASE_T2_HD, "100BASET2 hdx"},
  282. { LLDP_MAU_TYPE_100BASE_T2_FD, "100BASET2 fdx"},
  283. { LLDP_MAU_TYPE_1000BASE_X_HD, "1000BASEX hdx"},
  284. { LLDP_MAU_TYPE_1000BASE_X_FD, "1000BASEX fdx"},
  285. { LLDP_MAU_TYPE_1000BASE_LX_HD, "1000BASELX hdx"},
  286. { LLDP_MAU_TYPE_1000BASE_LX_FD, "1000BASELX fdx"},
  287. { LLDP_MAU_TYPE_1000BASE_SX_HD, "1000BASESX hdx"},
  288. { LLDP_MAU_TYPE_1000BASE_SX_FD, "1000BASESX fdx"},
  289. { LLDP_MAU_TYPE_1000BASE_CX_HD, "1000BASECX hdx"},
  290. { LLDP_MAU_TYPE_1000BASE_CX_FD, "1000BASECX fdx"},
  291. { LLDP_MAU_TYPE_1000BASE_T_HD, "1000BASET hdx"},
  292. { LLDP_MAU_TYPE_1000BASE_T_FD, "1000BASET fdx"},
  293. { LLDP_MAU_TYPE_10GBASE_X, "10GBASEX"},
  294. { LLDP_MAU_TYPE_10GBASE_LX4, "10GBASELX4"},
  295. { LLDP_MAU_TYPE_10GBASE_R, "10GBASER"},
  296. { LLDP_MAU_TYPE_10GBASE_ER, "10GBASEER"},
  297. { LLDP_MAU_TYPE_10GBASE_LR, "10GBASELR"},
  298. { LLDP_MAU_TYPE_10GBASE_SR, "10GBASESR"},
  299. { LLDP_MAU_TYPE_10GBASE_W, "10GBASEW"},
  300. { LLDP_MAU_TYPE_10GBASE_EW, "10GBASEEW"},
  301. { LLDP_MAU_TYPE_10GBASE_LW, "10GBASELW"},
  302. { LLDP_MAU_TYPE_10GBASE_SW, "10GBASESW"},
  303. { 0, NULL}
  304. };
  305. #define LLDP_8023_AUTONEGOTIATION_SUPPORT (1 << 0)
  306. #define LLDP_8023_AUTONEGOTIATION_STATUS (1 << 1)
  307. static const struct tok lldp_8023_autonegotiation_values[] = {
  308. { LLDP_8023_AUTONEGOTIATION_SUPPORT, "supported"},
  309. { LLDP_8023_AUTONEGOTIATION_STATUS, "enabled"},
  310. { 0, NULL}
  311. };
  312. #define LLDP_TIA_CAPABILITY_MED (1 << 0)
  313. #define LLDP_TIA_CAPABILITY_NETWORK_POLICY (1 << 1)
  314. #define LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION (1 << 2)
  315. #define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE (1 << 3)
  316. #define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD (1 << 4)
  317. #define LLDP_TIA_CAPABILITY_INVENTORY (1 << 5)
  318. static const struct tok lldp_tia_capabilities_values[] = {
  319. { LLDP_TIA_CAPABILITY_MED, "LLDP-MED capabilities"},
  320. { LLDP_TIA_CAPABILITY_NETWORK_POLICY, "network policy"},
  321. { LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION, "location identification"},
  322. { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE, "extended power via MDI-PSE"},
  323. { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD, "extended power via MDI-PD"},
  324. { LLDP_TIA_CAPABILITY_INVENTORY, "Inventory"},
  325. { 0, NULL}
  326. };
  327. #define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1 1
  328. #define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2 2
  329. #define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3 3
  330. #define LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY 4
  331. static const struct tok lldp_tia_device_type_values[] = {
  332. { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1, "endpoint class 1"},
  333. { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2, "endpoint class 2"},
  334. { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3, "endpoint class 3"},
  335. { LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY, "network connectivity"},
  336. { 0, NULL}
  337. };
  338. #define LLDP_TIA_APPLICATION_TYPE_VOICE 1
  339. #define LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING 2
  340. #define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE 3
  341. #define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING 4
  342. #define LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE 5
  343. #define LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING 6
  344. #define LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO 7
  345. #define LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING 8
  346. static const struct tok lldp_tia_application_type_values[] = {
  347. { LLDP_TIA_APPLICATION_TYPE_VOICE, "voice"},
  348. { LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING, "voice signaling"},
  349. { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE, "guest voice"},
  350. { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING, "guest voice signaling"},
  351. { LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE, "softphone voice"},
  352. { LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING, "video conferencing"},
  353. { LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO, "streaming video"},
  354. { LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING, "video signaling"},
  355. { 0, NULL}
  356. };
  357. #define LLDP_TIA_NETWORK_POLICY_X_BIT (1 << 5)
  358. #define LLDP_TIA_NETWORK_POLICY_T_BIT (1 << 6)
  359. #define LLDP_TIA_NETWORK_POLICY_U_BIT (1 << 7)
  360. static const struct tok lldp_tia_network_policy_bits_values[] = {
  361. { LLDP_TIA_NETWORK_POLICY_U_BIT, "Unknown"},
  362. { LLDP_TIA_NETWORK_POLICY_T_BIT, "Tagged"},
  363. { LLDP_TIA_NETWORK_POLICY_X_BIT, "reserved"},
  364. { 0, NULL}
  365. };
  366. #define LLDP_EXTRACT_NETWORK_POLICY_VLAN(x) (((x)&0x1ffe)>>1)
  367. #define LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(x) (((x)&0x01ff)>>6)
  368. #define LLDP_EXTRACT_NETWORK_POLICY_DSCP(x) ((x)&0x003f)
  369. #define LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED 1
  370. #define LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS 2
  371. #define LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN 3
  372. static const struct tok lldp_tia_location_data_format_values[] = {
  373. { LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED, "coordinate-based LCI"},
  374. { LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS, "civic address LCI"},
  375. { LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN, "ECS ELIN"},
  376. { 0, NULL}
  377. };
  378. #define LLDP_TIA_LOCATION_DATUM_WGS_84 1
  379. #define LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88 2
  380. #define LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW 3
  381. static const struct tok lldp_tia_location_datum_type_values[] = {
  382. { LLDP_TIA_LOCATION_DATUM_WGS_84, "World Geodesic System 1984"},
  383. { LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88, "North American Datum 1983 (NAVD88)"},
  384. { LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW, "North American Datum 1983 (MLLW)"},
  385. { 0, NULL}
  386. };
  387. #define LLDP_TIA_POWER_SOURCE_PSE 1
  388. #define LLDP_TIA_POWER_SOURCE_LOCAL 2
  389. #define LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL 3
  390. static const struct tok lldp_tia_power_source_values[] = {
  391. { LLDP_TIA_POWER_SOURCE_PSE, "PSE - primary power source"},
  392. { LLDP_TIA_POWER_SOURCE_LOCAL, "local - backup power source"},
  393. { LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL, "PSE+local - reserved"},
  394. { 0, NULL}
  395. };
  396. #define LLDP_TIA_POWER_PRIORITY_CRITICAL 1
  397. #define LLDP_TIA_POWER_PRIORITY_HIGH 2
  398. #define LLDP_TIA_POWER_PRIORITY_LOW 3
  399. static const struct tok lldp_tia_power_priority_values[] = {
  400. { LLDP_TIA_POWER_PRIORITY_CRITICAL, "critical"},
  401. { LLDP_TIA_POWER_PRIORITY_HIGH, "high"},
  402. { LLDP_TIA_POWER_PRIORITY_LOW, "low"},
  403. { 0, NULL}
  404. };
  405. #define LLDP_TIA_POWER_VAL_MAX 1024
  406. static const struct tok lldp_tia_inventory_values[] = {
  407. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Hardware revision" },
  408. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Firmware revision" },
  409. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Software revision" },
  410. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Serial number" },
  411. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Manufacturer name" },
  412. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Model name" },
  413. { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Asset ID" },
  414. { 0, NULL}
  415. };
  416. /*
  417. * From RFC 3636 - ifMauAutoNegCapAdvertisedBits
  418. */
  419. #define LLDP_MAU_PMD_OTHER (1 << 15)
  420. #define LLDP_MAU_PMD_10BASE_T (1 << 14)
  421. #define LLDP_MAU_PMD_10BASE_T_FD (1 << 13)
  422. #define LLDP_MAU_PMD_100BASE_T4 (1 << 12)
  423. #define LLDP_MAU_PMD_100BASE_TX (1 << 11)
  424. #define LLDP_MAU_PMD_100BASE_TX_FD (1 << 10)
  425. #define LLDP_MAU_PMD_100BASE_T2 (1 << 9)
  426. #define LLDP_MAU_PMD_100BASE_T2_FD (1 << 8)
  427. #define LLDP_MAU_PMD_FDXPAUSE (1 << 7)
  428. #define LLDP_MAU_PMD_FDXAPAUSE (1 << 6)
  429. #define LLDP_MAU_PMD_FDXSPAUSE (1 << 5)
  430. #define LLDP_MAU_PMD_FDXBPAUSE (1 << 4)
  431. #define LLDP_MAU_PMD_1000BASE_X (1 << 3)
  432. #define LLDP_MAU_PMD_1000BASE_X_FD (1 << 2)
  433. #define LLDP_MAU_PMD_1000BASE_T (1 << 1)
  434. #define LLDP_MAU_PMD_1000BASE_T_FD (1 << 0)
  435. static const struct tok lldp_pmd_capability_values[] = {
  436. { LLDP_MAU_PMD_10BASE_T, "10BASE-T hdx"},
  437. { LLDP_MAU_PMD_10BASE_T_FD, "10BASE-T fdx"},
  438. { LLDP_MAU_PMD_100BASE_T4, "100BASE-T4"},
  439. { LLDP_MAU_PMD_100BASE_TX, "100BASE-TX hdx"},
  440. { LLDP_MAU_PMD_100BASE_TX_FD, "100BASE-TX fdx"},
  441. { LLDP_MAU_PMD_100BASE_T2, "100BASE-T2 hdx"},
  442. { LLDP_MAU_PMD_100BASE_T2_FD, "100BASE-T2 fdx"},
  443. { LLDP_MAU_PMD_FDXPAUSE, "Pause for fdx links"},
  444. { LLDP_MAU_PMD_FDXAPAUSE, "Asym PAUSE for fdx"},
  445. { LLDP_MAU_PMD_FDXSPAUSE, "Sym PAUSE for fdx"},
  446. { LLDP_MAU_PMD_FDXBPAUSE, "Asym and Sym PAUSE for fdx"},
  447. { LLDP_MAU_PMD_1000BASE_X, "1000BASE-{X LX SX CX} hdx"},
  448. { LLDP_MAU_PMD_1000BASE_X_FD, "1000BASE-{X LX SX CX} fdx"},
  449. { LLDP_MAU_PMD_1000BASE_T, "1000BASE-T hdx"},
  450. { LLDP_MAU_PMD_1000BASE_T_FD, "1000BASE-T fdx"},
  451. { 0, NULL}
  452. };
  453. #define LLDP_MDI_PORT_CLASS (1 << 0)
  454. #define LLDP_MDI_POWER_SUPPORT (1 << 1)
  455. #define LLDP_MDI_POWER_STATE (1 << 2)
  456. #define LLDP_MDI_PAIR_CONTROL_ABILITY (1 << 3)
  457. static const struct tok lldp_mdi_values[] = {
  458. { LLDP_MDI_PORT_CLASS, "PSE"},
  459. { LLDP_MDI_POWER_SUPPORT, "supported"},
  460. { LLDP_MDI_POWER_STATE, "enabled"},
  461. { LLDP_MDI_PAIR_CONTROL_ABILITY, "can be controlled"},
  462. { 0, NULL}
  463. };
  464. #define LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL 1
  465. #define LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE 2
  466. static const struct tok lldp_mdi_power_pairs_values[] = {
  467. { LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL, "signal"},
  468. { LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE, "spare"},
  469. { 0, NULL}
  470. };
  471. #define LLDP_MDI_POWER_CLASS0 1
  472. #define LLDP_MDI_POWER_CLASS1 2
  473. #define LLDP_MDI_POWER_CLASS2 3
  474. #define LLDP_MDI_POWER_CLASS3 4
  475. #define LLDP_MDI_POWER_CLASS4 5
  476. static const struct tok lldp_mdi_power_class_values[] = {
  477. { LLDP_MDI_POWER_CLASS0, "class0"},
  478. { LLDP_MDI_POWER_CLASS1, "class1"},
  479. { LLDP_MDI_POWER_CLASS2, "class2"},
  480. { LLDP_MDI_POWER_CLASS3, "class3"},
  481. { LLDP_MDI_POWER_CLASS4, "class4"},
  482. { 0, NULL}
  483. };
  484. #define LLDP_AGGREGATION_CAPABILTIY (1 << 0)
  485. #define LLDP_AGGREGATION_STATUS (1 << 1)
  486. static const struct tok lldp_aggregation_values[] = {
  487. { LLDP_AGGREGATION_CAPABILTIY, "supported"},
  488. { LLDP_AGGREGATION_STATUS, "enabled"},
  489. { 0, NULL}
  490. };
  491. /*
  492. * DCBX protocol subtypes.
  493. */
  494. #define LLDP_DCBX_SUBTYPE_1 1
  495. #define LLDP_DCBX_SUBTYPE_2 2
  496. static const struct tok lldp_dcbx_subtype_values[] = {
  497. { LLDP_DCBX_SUBTYPE_1, "DCB Capability Exchange Protocol Rev 1" },
  498. { LLDP_DCBX_SUBTYPE_2, "DCB Capability Exchange Protocol Rev 1.01" },
  499. { 0, NULL}
  500. };
  501. #define LLDP_DCBX_CONTROL_TLV 1
  502. #define LLDP_DCBX_PRIORITY_GROUPS_TLV 2
  503. #define LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV 3
  504. #define LLDP_DCBX_APPLICATION_TLV 4
  505. /*
  506. * Interface numbering subtypes.
  507. */
  508. #define LLDP_INTF_NUMB_IFX_SUBTYPE 2
  509. #define LLDP_INTF_NUMB_SYSPORT_SUBTYPE 3
  510. static const struct tok lldp_intf_numb_subtype_values[] = {
  511. { LLDP_INTF_NUMB_IFX_SUBTYPE, "Interface Index" },
  512. { LLDP_INTF_NUMB_SYSPORT_SUBTYPE, "System Port Number" },
  513. { 0, NULL}
  514. };
  515. #define LLDP_INTF_NUM_LEN 5
  516. #define LLDP_EVB_MODE_NOT_SUPPORTED 0
  517. #define LLDP_EVB_MODE_EVB_BRIDGE 1
  518. #define LLDP_EVB_MODE_EVB_STATION 2
  519. #define LLDP_EVB_MODE_RESERVED 3
  520. static const struct tok lldp_evb_mode_values[]={
  521. { LLDP_EVB_MODE_NOT_SUPPORTED, "Not Supported"},
  522. { LLDP_EVB_MODE_EVB_BRIDGE, "EVB Bridge"},
  523. { LLDP_EVB_MODE_EVB_STATION, "EVB Staion"},
  524. { LLDP_EVB_MODE_RESERVED, "Reserved for future Standardization"},
  525. { 0, NULL},
  526. };
  527. #define NO_OF_BITS 8
  528. #define LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION_LENGTH 6
  529. #define LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION_LENGTH 25
  530. #define LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION_LENGTH 25
  531. #define LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION_LENGTH 6
  532. #define LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY_MIN_LENGTH 5
  533. #define LLDP_PRIVATE_8021_SUBTYPE_EVB_LENGTH 9
  534. #define LLDP_PRIVATE_8021_SUBTYPE_CDCP_MIN_LENGTH 8
  535. #define LLDP_IANA_SUBTYPE_MUDURL 1
  536. static const struct tok lldp_iana_subtype_values[] = {
  537. { LLDP_IANA_SUBTYPE_MUDURL, "MUD-URL" },
  538. { 0, NULL }
  539. };
  540. static void
  541. print_ets_priority_assignment_table(netdissect_options *ndo,
  542. const u_char *ptr)
  543. {
  544. ND_PRINT((ndo, "\n\t Priority Assignment Table"));
  545. ND_PRINT((ndo, "\n\t Priority : 0 1 2 3 4 5 6 7"));
  546. ND_PRINT((ndo, "\n\t Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d",
  547. ptr[0]>>4,ptr[0]&0x0f,ptr[1]>>4,ptr[1]&0x0f,ptr[2]>>4,
  548. ptr[2] & 0x0f, ptr[3] >> 4, ptr[3] & 0x0f));
  549. }
  550. static void
  551. print_tc_bandwidth_table(netdissect_options *ndo,
  552. const u_char *ptr)
  553. {
  554. ND_PRINT((ndo, "\n\t TC Bandwidth Table"));
  555. ND_PRINT((ndo, "\n\t TC%% : 0 1 2 3 4 5 6 7"));
  556. ND_PRINT((ndo, "\n\t Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d",
  557. ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]));
  558. }
  559. static void
  560. print_tsa_assignment_table(netdissect_options *ndo,
  561. const u_char *ptr)
  562. {
  563. ND_PRINT((ndo, "\n\t TSA Assignment Table"));
  564. ND_PRINT((ndo, "\n\t Traffic Class: 0 1 2 3 4 5 6 7"));
  565. ND_PRINT((ndo, "\n\t Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d",
  566. ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]));
  567. }
  568. /*
  569. * Print IEEE 802.1 private extensions. (802.1AB annex E)
  570. */
  571. static int
  572. lldp_private_8021_print(netdissect_options *ndo,
  573. const u_char *tptr, u_int tlv_len)
  574. {
  575. int subtype, hexdump = FALSE;
  576. u_int sublen;
  577. u_int tval;
  578. u_int i;
  579. if (tlv_len < 4) {
  580. return hexdump;
  581. }
  582. subtype = *(tptr+3);
  583. ND_PRINT((ndo, "\n\t %s Subtype (%u)",
  584. tok2str(lldp_8021_subtype_values, "unknown", subtype),
  585. subtype));
  586. switch (subtype) {
  587. case LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID:
  588. if (tlv_len < 6) {
  589. return hexdump;
  590. }
  591. ND_PRINT((ndo, "\n\t port vlan id (PVID): %u",
  592. EXTRACT_16BITS(tptr + 4)));
  593. break;
  594. case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID:
  595. if (tlv_len < 7) {
  596. return hexdump;
  597. }
  598. ND_PRINT((ndo, "\n\t port and protocol vlan id (PPVID): %u, flags [%s] (0x%02x)",
  599. EXTRACT_16BITS(tptr+5),
  600. bittok2str(lldp_8021_port_protocol_id_values, "none", *(tptr+4)),
  601. *(tptr + 4)));
  602. break;
  603. case LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME:
  604. if (tlv_len < 6) {
  605. return hexdump;
  606. }
  607. ND_PRINT((ndo, "\n\t vlan id (VID): %u", EXTRACT_16BITS(tptr + 4)));
  608. if (tlv_len < 7) {
  609. return hexdump;
  610. }
  611. sublen = *(tptr+6);
  612. if (tlv_len < 7+sublen) {
  613. return hexdump;
  614. }
  615. ND_PRINT((ndo, "\n\t vlan name: "));
  616. safeputs(ndo, tptr + 7, sublen);
  617. break;
  618. case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY:
  619. if (tlv_len < 5) {
  620. return hexdump;
  621. }
  622. sublen = *(tptr+4);
  623. if (tlv_len < 5+sublen) {
  624. return hexdump;
  625. }
  626. ND_PRINT((ndo, "\n\t protocol identity: "));
  627. safeputs(ndo, tptr + 5, sublen);
  628. break;
  629. case LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION:
  630. if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION_LENGTH){
  631. return hexdump;
  632. }
  633. tval=*(tptr+4);
  634. ND_PRINT((ndo, "\n\t Pre-Priority CNPV Indicator"));
  635. ND_PRINT((ndo, "\n\t Priority : 0 1 2 3 4 5 6 7"));
  636. ND_PRINT((ndo, "\n\t Value : "));
  637. for(i=0;i<NO_OF_BITS;i++)
  638. ND_PRINT((ndo, "%-2d ", (tval >> i) & 0x01));
  639. tval=*(tptr+5);
  640. ND_PRINT((ndo, "\n\t Pre-Priority Ready Indicator"));
  641. ND_PRINT((ndo, "\n\t Priority : 0 1 2 3 4 5 6 7"));
  642. ND_PRINT((ndo, "\n\t Value : "));
  643. for(i=0;i<NO_OF_BITS;i++)
  644. ND_PRINT((ndo, "%-2d ", (tval >> i) & 0x01));
  645. break;
  646. case LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION:
  647. if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION_LENGTH) {
  648. return hexdump;
  649. }
  650. tval=*(tptr+4);
  651. ND_PRINT((ndo, "\n\t Willing:%d, CBS:%d, RES:%d, Max TCs:%d",
  652. tval >> 7, (tval >> 6) & 0x02, (tval >> 3) & 0x07, tval & 0x07));
  653. /*Print Priority Assignment Table*/
  654. print_ets_priority_assignment_table(ndo, tptr + 5);
  655. /*Print TC Bandwidth Table*/
  656. print_tc_bandwidth_table(ndo, tptr + 9);
  657. /* Print TSA Assignment Table */
  658. print_tsa_assignment_table(ndo, tptr + 17);
  659. break;
  660. case LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION:
  661. if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION_LENGTH) {
  662. return hexdump;
  663. }
  664. ND_PRINT((ndo, "\n\t RES: %d", *(tptr + 4)));
  665. /*Print Priority Assignment Table */
  666. print_ets_priority_assignment_table(ndo, tptr + 5);
  667. /*Print TC Bandwidth Table */
  668. print_tc_bandwidth_table(ndo, tptr + 9);
  669. /* Print TSA Assignment Table */
  670. print_tsa_assignment_table(ndo, tptr + 17);
  671. break;
  672. case LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION:
  673. if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION_LENGTH) {
  674. return hexdump;
  675. }
  676. tval=*(tptr+4);
  677. ND_PRINT((ndo, "\n\t Willing: %d, MBC: %d, RES: %d, PFC cap:%d ",
  678. tval >> 7, (tval >> 6) & 0x01, (tval >> 4) & 0x03, (tval & 0x0f)));
  679. ND_PRINT((ndo, "\n\t PFC Enable"));
  680. tval=*(tptr+5);
  681. ND_PRINT((ndo, "\n\t Priority : 0 1 2 3 4 5 6 7"));
  682. ND_PRINT((ndo, "\n\t Value : "));
  683. for(i=0;i<NO_OF_BITS;i++)
  684. ND_PRINT((ndo, "%-2d ", (tval >> i) & 0x01));
  685. break;
  686. case LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY:
  687. if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY_MIN_LENGTH) {
  688. return hexdump;
  689. }
  690. ND_PRINT((ndo, "\n\t RES: %d", *(tptr + 4)));
  691. if(tlv_len<=LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY_MIN_LENGTH){
  692. return hexdump;
  693. }
  694. /* Length of Application Priority Table */
  695. sublen=tlv_len-5;
  696. if(sublen%3!=0){
  697. return hexdump;
  698. }
  699. i=0;
  700. ND_PRINT((ndo, "\n\t Application Priority Table"));
  701. while(i<sublen) {
  702. tval=*(tptr+i+5);
  703. ND_PRINT((ndo, "\n\t Priority: %u, RES: %u, Sel: %u, Protocol ID: %u",
  704. tval >> 5, (tval >> 3) & 0x03, (tval & 0x07),
  705. EXTRACT_16BITS(tptr + i + 5)));
  706. i=i+3;
  707. }
  708. break;
  709. case LLDP_PRIVATE_8021_SUBTYPE_EVB:
  710. if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_EVB_LENGTH){
  711. return hexdump;
  712. }
  713. ND_PRINT((ndo, "\n\t EVB Bridge Status"));
  714. tval=*(tptr+4);
  715. ND_PRINT((ndo, "\n\t RES: %d, BGID: %d, RRCAP: %d, RRCTR: %d",
  716. tval >> 3, (tval >> 2) & 0x01, (tval >> 1) & 0x01, tval & 0x01));
  717. ND_PRINT((ndo, "\n\t EVB Station Status"));
  718. tval=*(tptr+5);
  719. ND_PRINT((ndo, "\n\t RES: %d, SGID: %d, RRREQ: %d,RRSTAT: %d",
  720. tval >> 4, (tval >> 3) & 0x01, (tval >> 2) & 0x01, tval & 0x03));
  721. tval=*(tptr+6);
  722. ND_PRINT((ndo, "\n\t R: %d, RTE: %d, ",tval >> 5, tval & 0x1f));
  723. tval=*(tptr+7);
  724. ND_PRINT((ndo, "EVB Mode: %s [%d]",
  725. tok2str(lldp_evb_mode_values, "unknown", tval >> 6), tval >> 6));
  726. ND_PRINT((ndo, "\n\t ROL: %d, RWD: %d, ", (tval >> 5) & 0x01, tval & 0x1f));
  727. tval=*(tptr+8);
  728. ND_PRINT((ndo, "RES: %d, ROL: %d, RKA: %d", tval >> 6, (tval >> 5) & 0x01, tval & 0x1f));
  729. break;
  730. case LLDP_PRIVATE_8021_SUBTYPE_CDCP:
  731. if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_CDCP_MIN_LENGTH){
  732. return hexdump;
  733. }
  734. tval=*(tptr+4);
  735. ND_PRINT((ndo, "\n\t Role: %d, RES: %d, Scomp: %d ",
  736. tval >> 7, (tval >> 4) & 0x07, (tval >> 3) & 0x01));
  737. ND_PRINT((ndo, "ChnCap: %d", EXTRACT_16BITS(tptr + 6) & 0x0fff));
  738. sublen=tlv_len-8;
  739. if(sublen%3!=0) {
  740. return hexdump;
  741. }
  742. i=0;
  743. while(i<sublen) {
  744. tval=EXTRACT_24BITS(tptr+i+8);
  745. ND_PRINT((ndo, "\n\t SCID: %d, SVID: %d",
  746. tval >> 12, tval & 0x000fff));
  747. i=i+3;
  748. }
  749. break;
  750. default:
  751. hexdump = TRUE;
  752. break;
  753. }
  754. return hexdump;
  755. }
  756. /*
  757. * Print IEEE 802.3 private extensions. (802.3bc)
  758. */
  759. static int
  760. lldp_private_8023_print(netdissect_options *ndo,
  761. const u_char *tptr, u_int tlv_len)
  762. {
  763. int subtype, hexdump = FALSE;
  764. if (tlv_len < 4) {
  765. return hexdump;
  766. }
  767. subtype = *(tptr+3);
  768. ND_PRINT((ndo, "\n\t %s Subtype (%u)",
  769. tok2str(lldp_8023_subtype_values, "unknown", subtype),
  770. subtype));
  771. switch (subtype) {
  772. case LLDP_PRIVATE_8023_SUBTYPE_MACPHY:
  773. if (tlv_len < 9) {
  774. return hexdump;
  775. }
  776. ND_PRINT((ndo, "\n\t autonegotiation [%s] (0x%02x)",
  777. bittok2str(lldp_8023_autonegotiation_values, "none", *(tptr+4)),
  778. *(tptr + 4)));
  779. ND_PRINT((ndo, "\n\t PMD autoneg capability [%s] (0x%04x)",
  780. bittok2str(lldp_pmd_capability_values,"unknown", EXTRACT_16BITS(tptr+5)),
  781. EXTRACT_16BITS(tptr + 5)));
  782. ND_PRINT((ndo, "\n\t MAU type %s (0x%04x)",
  783. tok2str(lldp_mau_types_values, "unknown", EXTRACT_16BITS(tptr+7)),
  784. EXTRACT_16BITS(tptr + 7)));
  785. break;
  786. case LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER:
  787. if (tlv_len < 7) {
  788. return hexdump;
  789. }
  790. ND_PRINT((ndo, "\n\t MDI power support [%s], power pair %s, power class %s",
  791. bittok2str(lldp_mdi_values, "none", *(tptr+4)),
  792. tok2str(lldp_mdi_power_pairs_values, "unknown", *(tptr+5)),
  793. tok2str(lldp_mdi_power_class_values, "unknown", *(tptr + 6))));
  794. break;
  795. case LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR:
  796. if (tlv_len < 9) {
  797. return hexdump;
  798. }
  799. ND_PRINT((ndo, "\n\t aggregation status [%s], aggregation port ID %u",
  800. bittok2str(lldp_aggregation_values, "none", *(tptr+4)),
  801. EXTRACT_32BITS(tptr + 5)));
  802. break;
  803. case LLDP_PRIVATE_8023_SUBTYPE_MTU:
  804. if (tlv_len < 6) {
  805. return hexdump;
  806. }
  807. ND_PRINT((ndo, "\n\t MTU size %u", EXTRACT_16BITS(tptr + 4)));
  808. break;
  809. default:
  810. hexdump = TRUE;
  811. break;
  812. }
  813. return hexdump;
  814. }
  815. /*
  816. * Extract 34bits of latitude/longitude coordinates.
  817. */
  818. static uint64_t
  819. lldp_extract_latlon(const u_char *tptr)
  820. {
  821. uint64_t latlon;
  822. latlon = *tptr & 0x3;
  823. latlon = (latlon << 32) | EXTRACT_32BITS(tptr+1);
  824. return latlon;
  825. }
  826. /* objects defined in IANA subtype 00 00 5e
  827. * (right now there is only one)
  828. */
  829. static int
  830. lldp_private_iana_print(netdissect_options *ndo,
  831. const u_char *tptr, u_int tlv_len)
  832. {
  833. int subtype, hexdump = FALSE;
  834. if (tlv_len < 8) {
  835. return hexdump;
  836. }
  837. subtype = *(tptr+3);
  838. ND_PRINT((ndo, "\n\t %s Subtype (%u)",
  839. tok2str(lldp_iana_subtype_values, "unknown", subtype),
  840. subtype));
  841. switch (subtype) {
  842. case LLDP_IANA_SUBTYPE_MUDURL:
  843. ND_PRINT((ndo, "\n\t MUD-URL="));
  844. (void)fn_printn(ndo, tptr+4, tlv_len-4, NULL);
  845. break;
  846. default:
  847. hexdump=TRUE;
  848. }
  849. return hexdump;
  850. }
  851. /*
  852. * Print private TIA extensions.
  853. */
  854. static int
  855. lldp_private_tia_print(netdissect_options *ndo,
  856. const u_char *tptr, u_int tlv_len)
  857. {
  858. int subtype, hexdump = FALSE;
  859. uint8_t location_format;
  860. uint16_t power_val;
  861. u_int lci_len;
  862. uint8_t ca_type, ca_len;
  863. if (tlv_len < 4) {
  864. return hexdump;
  865. }
  866. subtype = *(tptr+3);
  867. ND_PRINT((ndo, "\n\t %s Subtype (%u)",
  868. tok2str(lldp_tia_subtype_values, "unknown", subtype),
  869. subtype));
  870. switch (subtype) {
  871. case LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES:
  872. if (tlv_len < 7) {
  873. return hexdump;
  874. }
  875. ND_PRINT((ndo, "\n\t Media capabilities [%s] (0x%04x)",
  876. bittok2str(lldp_tia_capabilities_values, "none",
  877. EXTRACT_16BITS(tptr + 4)), EXTRACT_16BITS(tptr + 4)));
  878. ND_PRINT((ndo, "\n\t Device type [%s] (0x%02x)",
  879. tok2str(lldp_tia_device_type_values, "unknown", *(tptr+6)),
  880. *(tptr + 6)));
  881. break;
  882. case LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY:
  883. if (tlv_len < 8) {
  884. return hexdump;
  885. }
  886. ND_PRINT((ndo, "\n\t Application type [%s] (0x%02x)",
  887. tok2str(lldp_tia_application_type_values, "none", *(tptr+4)),
  888. *(tptr + 4)));
  889. ND_PRINT((ndo, ", Flags [%s]", bittok2str(
  890. lldp_tia_network_policy_bits_values, "none", *(tptr + 5))));
  891. ND_PRINT((ndo, "\n\t Vlan id %u",
  892. LLDP_EXTRACT_NETWORK_POLICY_VLAN(EXTRACT_16BITS(tptr + 5))));
  893. ND_PRINT((ndo, ", L2 priority %u",
  894. LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(EXTRACT_16BITS(tptr + 6))));
  895. ND_PRINT((ndo, ", DSCP value %u",
  896. LLDP_EXTRACT_NETWORK_POLICY_DSCP(EXTRACT_16BITS(tptr + 6))));
  897. break;
  898. case LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID:
  899. if (tlv_len < 5) {
  900. return hexdump;
  901. }
  902. location_format = *(tptr+4);
  903. ND_PRINT((ndo, "\n\t Location data format %s (0x%02x)",
  904. tok2str(lldp_tia_location_data_format_values, "unknown", location_format),
  905. location_format));
  906. switch (location_format) {
  907. case LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED:
  908. if (tlv_len < 21) {
  909. return hexdump;
  910. }
  911. ND_PRINT((ndo, "\n\t Latitude resolution %u, latitude value %" PRIu64,
  912. (*(tptr + 5) >> 2), lldp_extract_latlon(tptr + 5)));
  913. ND_PRINT((ndo, "\n\t Longitude resolution %u, longitude value %" PRIu64,
  914. (*(tptr + 10) >> 2), lldp_extract_latlon(tptr + 10)));
  915. ND_PRINT((ndo, "\n\t Altitude type %s (%u)",
  916. tok2str(lldp_tia_location_altitude_type_values, "unknown",(*(tptr+15)>>4)),
  917. (*(tptr + 15) >> 4)));
  918. ND_PRINT((ndo, "\n\t Altitude resolution %u, altitude value 0x%x",
  919. (EXTRACT_16BITS(tptr+15)>>6)&0x3f,
  920. ((EXTRACT_32BITS(tptr + 16) & 0x3fffffff))));
  921. ND_PRINT((ndo, "\n\t Datum %s (0x%02x)",
  922. tok2str(lldp_tia_location_datum_type_values, "unknown", *(tptr+20)),
  923. *(tptr + 20)));
  924. break;
  925. case LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS:
  926. if (tlv_len < 6) {
  927. return hexdump;
  928. }
  929. lci_len = *(tptr+5);
  930. if (lci_len < 3) {
  931. return hexdump;
  932. }
  933. if (tlv_len < 7+lci_len) {
  934. return hexdump;
  935. }
  936. ND_PRINT((ndo, "\n\t LCI length %u, LCI what %s (0x%02x), Country-code ",
  937. lci_len,
  938. tok2str(lldp_tia_location_lci_what_values, "unknown", *(tptr+6)),
  939. *(tptr + 6)));
  940. /* Country code */
  941. safeputs(ndo, tptr + 7, 2);
  942. lci_len = lci_len-3;
  943. tptr = tptr + 9;
  944. /* Decode each civic address element */
  945. while (lci_len > 0) {
  946. if (lci_len < 2) {
  947. return hexdump;
  948. }
  949. ca_type = *(tptr);
  950. ca_len = *(tptr+1);
  951. tptr += 2;
  952. lci_len -= 2;
  953. ND_PRINT((ndo, "\n\t CA type \'%s\' (%u), length %u: ",
  954. tok2str(lldp_tia_location_lci_catype_values, "unknown", ca_type),
  955. ca_type, ca_len));
  956. /* basic sanity check */
  957. if ( ca_type == 0 || ca_len == 0) {
  958. return hexdump;
  959. }
  960. if (lci_len < ca_len) {
  961. return hexdump;
  962. }
  963. safeputs(ndo, tptr, ca_len);
  964. tptr += ca_len;
  965. lci_len -= ca_len;
  966. }
  967. break;
  968. case LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN:
  969. ND_PRINT((ndo, "\n\t ECS ELIN id "));
  970. safeputs(ndo, tptr + 5, tlv_len - 5);
  971. break;
  972. default:
  973. ND_PRINT((ndo, "\n\t Location ID "));
  974. print_unknown_data(ndo, tptr + 5, "\n\t ", tlv_len - 5);
  975. }
  976. break;
  977. case LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI:
  978. if (tlv_len < 7) {
  979. return hexdump;
  980. }
  981. ND_PRINT((ndo, "\n\t Power type [%s]",
  982. (*(tptr + 4) & 0xC0 >> 6) ? "PD device" : "PSE device"));
  983. ND_PRINT((ndo, ", Power source [%s]",
  984. tok2str(lldp_tia_power_source_values, "none", (*(tptr + 4) & 0x30) >> 4)));
  985. ND_PRINT((ndo, "\n\t Power priority [%s] (0x%02x)",
  986. tok2str(lldp_tia_power_priority_values, "none", *(tptr+4)&0x0f),
  987. *(tptr + 4) & 0x0f));
  988. power_val = EXTRACT_16BITS(tptr+5);
  989. if (power_val < LLDP_TIA_POWER_VAL_MAX) {
  990. ND_PRINT((ndo, ", Power %.1f Watts", ((float)power_val) / 10));
  991. } else {
  992. ND_PRINT((ndo, ", Power %u (Reserved)", power_val));
  993. }
  994. break;
  995. case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV:
  996. case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV:
  997. case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV:
  998. case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER:
  999. case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME:
  1000. case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME:
  1001. case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID:
  1002. ND_PRINT((ndo, "\n\t %s ",
  1003. tok2str(lldp_tia_inventory_values, "unknown", subtype)));
  1004. safeputs(ndo, tptr + 4, tlv_len - 4);
  1005. break;
  1006. default:
  1007. hexdump = TRUE;
  1008. break;
  1009. }
  1010. return hexdump;
  1011. }
  1012. /*
  1013. * Print DCBX Protocol fields (V 1.01).
  1014. */
  1015. static int
  1016. lldp_private_dcbx_print(netdissect_options *ndo,
  1017. const u_char *pptr, u_int len)
  1018. {
  1019. int subtype, hexdump = FALSE;
  1020. uint8_t tval;
  1021. uint16_t tlv;
  1022. uint32_t i, pgval, uval;
  1023. u_int tlen, tlv_type, tlv_len;
  1024. const u_char *tptr, *mptr;
  1025. if (len < 4) {
  1026. return hexdump;
  1027. }
  1028. subtype = *(pptr+3);
  1029. ND_PRINT((ndo, "\n\t %s Subtype (%u)",
  1030. tok2str(lldp_dcbx_subtype_values, "unknown", subtype),
  1031. subtype));
  1032. /* by passing old version */
  1033. if (subtype == LLDP_DCBX_SUBTYPE_1)
  1034. return TRUE;
  1035. tptr = pptr + 4;
  1036. tlen = len - 4;
  1037. while (tlen >= sizeof(tlv)) {
  1038. ND_TCHECK2(*tptr, sizeof(tlv));
  1039. tlv = EXTRACT_16BITS(tptr);
  1040. tlv_type = LLDP_EXTRACT_TYPE(tlv);
  1041. tlv_len = LLDP_EXTRACT_LEN(tlv);
  1042. hexdump = FALSE;
  1043. tlen -= sizeof(tlv);
  1044. tptr += sizeof(tlv);
  1045. /* loop check */
  1046. if (!tlv_type || !tlv_len) {
  1047. break;
  1048. }
  1049. ND_TCHECK2(*tptr, tlv_len);
  1050. if (tlen < tlv_len) {
  1051. goto trunc;
  1052. }
  1053. /* decode every tlv */
  1054. switch (tlv_type) {
  1055. case LLDP_DCBX_CONTROL_TLV:
  1056. if (tlv_len < 10) {
  1057. goto trunc;
  1058. }
  1059. ND_PRINT((ndo, "\n\t Control - Protocol Control (type 0x%x, length %d)",
  1060. LLDP_DCBX_CONTROL_TLV, tlv_len));
  1061. ND_PRINT((ndo, "\n\t Oper_Version: %d", *tptr));
  1062. ND_PRINT((ndo, "\n\t Max_Version: %d", *(tptr + 1)));
  1063. ND_PRINT((ndo, "\n\t Sequence Number: %d", EXTRACT_32BITS(tptr + 2)));
  1064. ND_PRINT((ndo, "\n\t Acknowledgement Number: %d",
  1065. EXTRACT_32BITS(tptr + 6)));
  1066. break;
  1067. case LLDP_DCBX_PRIORITY_GROUPS_TLV:
  1068. if (tlv_len < 17) {
  1069. goto trunc;
  1070. }
  1071. ND_PRINT((ndo, "\n\t Feature - Priority Group (type 0x%x, length %d)",
  1072. LLDP_DCBX_PRIORITY_GROUPS_TLV, tlv_len));
  1073. ND_PRINT((ndo, "\n\t Oper_Version: %d", *tptr));
  1074. ND_PRINT((ndo, "\n\t Max_Version: %d", *(tptr + 1)));
  1075. ND_PRINT((ndo, "\n\t Info block(0x%02X): ", *(tptr + 2)));
  1076. tval = *(tptr+2);
  1077. ND_PRINT((ndo, "Enable bit: %d, Willing bit: %d, Error Bit: %d",
  1078. (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0,
  1079. (tval & 0x20) ? 1 : 0));
  1080. ND_PRINT((ndo, "\n\t SubType: %d", *(tptr + 3)));
  1081. ND_PRINT((ndo, "\n\t Priority Allocation"));
  1082. /*
  1083. * Array of 8 4-bit priority group ID values; we fetch all
  1084. * 32 bits and extract each nibble.
  1085. */
  1086. pgval = EXTRACT_32BITS(tptr+4);
  1087. for (i = 0; i <= 7; i++) {
  1088. ND_PRINT((ndo, "\n\t PgId_%d: %d",
  1089. i, (pgval >> (28 - 4 * i)) & 0xF));
  1090. }
  1091. ND_PRINT((ndo, "\n\t Priority Group Allocation"));
  1092. for (i = 0; i <= 7; i++)
  1093. ND_PRINT((ndo, "\n\t Pg percentage[%d]: %d", i, *(tptr + 8 + i)));
  1094. ND_PRINT((ndo, "\n\t NumTCsSupported: %d", *(tptr + 8 + 8)));
  1095. break;
  1096. case LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV:
  1097. if (tlv_len < 6) {
  1098. goto trunc;
  1099. }
  1100. ND_PRINT((ndo, "\n\t Feature - Priority Flow Control"));
  1101. ND_PRINT((ndo, " (type 0x%x, length %d)",
  1102. LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV, tlv_len));
  1103. ND_PRINT((ndo, "\n\t Oper_Version: %d", *tptr));
  1104. ND_PRINT((ndo, "\n\t Max_Version: %d", *(tptr + 1)));
  1105. ND_PRINT((ndo, "\n\t Info block(0x%02X): ", *(tptr + 2)));
  1106. tval = *(tptr+2);
  1107. ND_PRINT((ndo, "Enable bit: %d, Willing bit: %d, Error Bit: %d",
  1108. (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0,
  1109. (tval & 0x20) ? 1 : 0));
  1110. ND_PRINT((ndo, "\n\t SubType: %d", *(tptr + 3)));
  1111. tval = *(tptr+4);
  1112. ND_PRINT((ndo, "\n\t PFC Config (0x%02X)", *(tptr + 4)));
  1113. for (i = 0; i <= 7; i++)
  1114. ND_PRINT((ndo, "\n\t Priority Bit %d: %s",
  1115. i, (tval & (1 << i)) ? "Enabled" : "Disabled"));
  1116. ND_PRINT((ndo, "\n\t NumTCPFCSupported: %d", *(tptr + 5)));
  1117. break;
  1118. case LLDP_DCBX_APPLICATION_TLV:
  1119. if (tlv_len < 4) {
  1120. goto trunc;
  1121. }
  1122. ND_PRINT((ndo, "\n\t Feature - Application (type 0x%x, length %d)",
  1123. LLDP_DCBX_APPLICATION_TLV, tlv_len));
  1124. ND_PRINT((ndo, "\n\t Oper_Version: %d", *tptr));
  1125. ND_PRINT((ndo, "\n\t Max_Version: %d", *(tptr + 1)));
  1126. ND_PRINT((ndo, "\n\t Info block(0x%02X): ", *(tptr + 2)));
  1127. tval = *(tptr+2);
  1128. ND_PRINT((ndo, "Enable bit: %d, Willing bit: %d, Error Bit: %d",
  1129. (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0,
  1130. (tval & 0x20) ? 1 : 0));
  1131. ND_PRINT((ndo, "\n\t SubType: %d", *(tptr + 3)));
  1132. tval = tlv_len - 4;
  1133. mptr = tptr + 4;
  1134. while (tval >= 6) {
  1135. ND_PRINT((ndo, "\n\t Application Value"));
  1136. ND_PRINT((ndo, "\n\t Application Protocol ID: 0x%04x",
  1137. EXTRACT_16BITS(mptr)));
  1138. uval = EXTRACT_24BITS(mptr+2);
  1139. ND_PRINT((ndo, "\n\t SF (0x%x) Application Protocol ID is %s",
  1140. (uval >> 22),
  1141. (uval >> 22) ? "Socket Number" : "L2 EtherType"));
  1142. ND_PRINT((ndo, "\n\t OUI: 0x%06x", uval & 0x3fffff));
  1143. ND_PRINT((ndo, "\n\t User Priority Map: 0x%02x", *(mptr + 5)));
  1144. tval = tval - 6;
  1145. mptr = mptr + 6;
  1146. }
  1147. break;
  1148. default:
  1149. hexdump = TRUE;
  1150. break;
  1151. }
  1152. /* do we also want to see a hex dump ? */
  1153. if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) {
  1154. print_unknown_data(ndo, tptr, "\n\t ", tlv_len);
  1155. }
  1156. tlen -= tlv_len;
  1157. tptr += tlv_len;
  1158. }
  1159. trunc:
  1160. return hexdump;
  1161. }
  1162. static char *
  1163. lldp_network_addr_print(netdissect_options *ndo, const u_char *tptr, u_int len)
  1164. {
  1165. uint8_t af;
  1166. static char buf[BUFSIZE];
  1167. const char * (*pfunc)(netdissect_options *, const u_char *);
  1168. if (len < 1)
  1169. return NULL;
  1170. len--;
  1171. af = *tptr;
  1172. switch (af) {
  1173. case AFNUM_INET:
  1174. if (len < 4)
  1175. return NULL;
  1176. /* This cannot be assigned to ipaddr_string(), which is a macro. */
  1177. pfunc = getname;
  1178. break;
  1179. case AFNUM_INET6:
  1180. if (len < 16)
  1181. return NULL;
  1182. /* This cannot be assigned to ip6addr_string(), which is a macro. */
  1183. pfunc = getname6;
  1184. break;
  1185. case AFNUM_802:
  1186. if (len < 6)
  1187. return NULL;
  1188. pfunc = etheraddr_string;
  1189. break;
  1190. default:
  1191. pfunc = NULL;
  1192. break;
  1193. }
  1194. if (!pfunc) {
  1195. snprintf(buf, sizeof(buf), "AFI %s (%u), no AF printer !",
  1196. tok2str(af_values, "Unknown", af), af);
  1197. } else {
  1198. snprintf(buf, sizeof(buf), "AFI %s (%u): %s",
  1199. tok2str(af_values, "Unknown", af), af, (*pfunc)(ndo, tptr+1));
  1200. }
  1201. return buf;
  1202. }
  1203. static int
  1204. lldp_mgmt_addr_tlv_print(netdissect_options *ndo,
  1205. const u_char *pptr, u_int len)
  1206. {
  1207. uint8_t mgmt_addr_len, intf_num_subtype, oid_len;
  1208. const u_char *tptr;
  1209. u_int tlen;
  1210. char *mgmt_addr;
  1211. tlen = len;
  1212. tptr = pptr;
  1213. if (tlen < 1) {
  1214. return 0;
  1215. }
  1216. mgmt_addr_len = *tptr++;
  1217. tlen--;
  1218. if (tlen < mgmt_addr_len) {
  1219. return 0;
  1220. }
  1221. mgmt_addr = lldp_network_addr_print(ndo, tptr, mgmt_addr_len);
  1222. if (mgmt_addr == NULL) {
  1223. return 0;
  1224. }
  1225. ND_PRINT((ndo, "\n\t Management Address length %u, %s",
  1226. mgmt_addr_len, mgmt_addr));
  1227. tptr += mgmt_addr_len;
  1228. tlen -= mgmt_addr_len;
  1229. if (tlen < LLDP_INTF_NUM_LEN) {
  1230. return 0;
  1231. }
  1232. intf_num_subtype = *tptr;
  1233. ND_PRINT((ndo, "\n\t %s Interface Numbering (%u): %u",
  1234. tok2str(lldp_intf_numb_subtype_values, "Unknown", intf_num_subtype),
  1235. intf_num_subtype,
  1236. EXTRACT_32BITS(tptr + 1)));
  1237. tptr += LLDP_INTF_NUM_LEN;
  1238. tlen -= LLDP_INTF_NUM_LEN;
  1239. /*
  1240. * The OID is optional.
  1241. */
  1242. if (tlen) {
  1243. oid_len = *tptr;
  1244. if (tlen < 1U + oid_len) {
  1245. return 0;
  1246. }
  1247. if (oid_len) {
  1248. ND_PRINT((ndo, "\n\t OID length %u", oid_len));
  1249. safeputs(ndo, tptr + 1, oid_len);
  1250. }
  1251. }
  1252. return 1;
  1253. }
  1254. void
  1255. lldp_print(netdissect_options *ndo,
  1256. register const u_char *pptr, register u_int len)
  1257. {
  1258. uint8_t subtype;
  1259. uint16_t tlv, cap, ena_cap;
  1260. u_int oui, tlen, hexdump, tlv_type, tlv_len;
  1261. const u_char *tptr;
  1262. char *network_addr;
  1263. tptr = pptr;
  1264. tlen = len;
  1265. ND_PRINT((ndo, "LLDP, length %u", len));
  1266. while (tlen >= sizeof(tlv)) {
  1267. ND_TCHECK2(*tptr, sizeof(tlv));
  1268. tlv = EXTRACT_16BITS(tptr);
  1269. tlv_type = LLDP_EXTRACT_TYPE(tlv);
  1270. tlv_len = LLDP_EXTRACT_LEN(tlv);
  1271. hexdump = FALSE;
  1272. tlen -= sizeof(tlv);
  1273. tptr += sizeof(tlv);
  1274. if (ndo->ndo_vflag) {
  1275. ND_PRINT((ndo, "\n\t%s TLV (%u), length %u",
  1276. tok2str(lldp_tlv_values, "Unknown", tlv_type),
  1277. tlv_type, tlv_len));
  1278. }
  1279. /* infinite loop check */
  1280. if (!tlv_type || !tlv_len) {
  1281. break;
  1282. }
  1283. ND_TCHECK2(*tptr, tlv_len);
  1284. if (tlen < tlv_len) {
  1285. goto trunc;
  1286. }
  1287. switch (tlv_type) {
  1288. case LLDP_CHASSIS_ID_TLV:
  1289. if (ndo->ndo_vflag) {
  1290. if (tlv_len < 2) {
  1291. goto trunc;
  1292. }
  1293. subtype = *tptr;
  1294. ND_PRINT((ndo, "\n\t Subtype %s (%u): ",
  1295. tok2str(lldp_chassis_subtype_values, "Unknown", subtype),
  1296. subtype));
  1297. switch (subtype) {
  1298. case LLDP_CHASSIS_MAC_ADDR_SUBTYPE:
  1299. if (tlv_len < 1+6) {
  1300. goto trunc;
  1301. }
  1302. ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr + 1)));
  1303. break;
  1304. case LLDP_CHASSIS_INTF_NAME_SUBTYPE: /* fall through */
  1305. case LLDP_CHASSIS_LOCAL_SUBTYPE:
  1306. case LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE:
  1307. case LLDP_CHASSIS_INTF_ALIAS_SUBTYPE:
  1308. case LLDP_CHASSIS_PORT_COMP_SUBTYPE:
  1309. safeputs(ndo, tptr + 1, tlv_len - 1);
  1310. break;
  1311. case LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE:
  1312. network_addr = lldp_network_addr_print(ndo, tptr+1, tlv_len-1);
  1313. if (network_addr == NULL) {
  1314. goto trunc;
  1315. }
  1316. ND_PRINT((ndo, "%s", network_addr));
  1317. break;
  1318. default:
  1319. hexdump = TRUE;
  1320. break;
  1321. }
  1322. }
  1323. break;
  1324. case LLDP_PORT_ID_TLV:
  1325. if (ndo->ndo_vflag) {
  1326. if (tlv_len < 2) {
  1327. goto trunc;
  1328. }
  1329. subtype = *tptr;
  1330. ND_PRINT((ndo, "\n\t Subtype %s (%u): ",
  1331. tok2str(lldp_port_subtype_values, "Unknown", subtype),
  1332. subtype));
  1333. switch (subtype) {
  1334. case LLDP_PORT_MAC_ADDR_SUBTYPE:
  1335. if (tlv_len < 1+6) {
  1336. goto trunc;
  1337. }
  1338. ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr + 1)));
  1339. break;
  1340. case LLDP_PORT_INTF_NAME_SUBTYPE: /* fall through */
  1341. case LLDP_PORT_LOCAL_SUBTYPE:
  1342. case LLDP_PORT_AGENT_CIRC_ID_SUBTYPE:
  1343. case LLDP_PORT_INTF_ALIAS_SUBTYPE:
  1344. case LLDP_PORT_PORT_COMP_SUBTYPE:
  1345. safeputs(ndo, tptr + 1, tlv_len - 1);
  1346. break;
  1347. case LLDP_PORT_NETWORK_ADDR_SUBTYPE:
  1348. network_addr = lldp_network_addr_print(ndo, tptr+1, tlv_len-1);
  1349. if (network_addr == NULL) {
  1350. goto trunc;
  1351. }
  1352. ND_PRINT((ndo, "%s", network_addr));
  1353. break;
  1354. default:
  1355. hexdump = TRUE;
  1356. break;
  1357. }
  1358. }
  1359. break;
  1360. case LLDP_TTL_TLV:
  1361. if (ndo->ndo_vflag) {
  1362. if (tlv_len < 2) {
  1363. goto trunc;
  1364. }
  1365. ND_PRINT((ndo, ": TTL %us", EXTRACT_16BITS(tptr)));
  1366. }
  1367. break;
  1368. case LLDP_PORT_DESCR_TLV:
  1369. if (ndo->ndo_vflag) {
  1370. ND_PRINT((ndo, ": "));
  1371. safeputs(ndo, tptr, tlv_len);
  1372. }
  1373. break;
  1374. case LLDP_SYSTEM_NAME_TLV:
  1375. /*
  1376. * The system name is also print in non-verbose mode
  1377. * similar to the CDP printer.
  1378. */
  1379. ND_PRINT((ndo, ": "));
  1380. safeputs(ndo, tptr, tlv_len);
  1381. break;
  1382. case LLDP_SYSTEM_DESCR_TLV:
  1383. if (ndo->ndo_vflag) {
  1384. ND_PRINT((ndo, "\n\t "));
  1385. safeputs(ndo, tptr, tlv_len);
  1386. }
  1387. break;
  1388. case LLDP_SYSTEM_CAP_TLV:
  1389. if (ndo->ndo_vflag) {
  1390. /*
  1391. * XXX - IEEE Std 802.1AB-2009 says the first octet
  1392. * if a chassis ID subtype, with the system
  1393. * capabilities and enabled capabilities following
  1394. * it.
  1395. */
  1396. if (tlv_len < 4) {
  1397. goto trunc;
  1398. }
  1399. cap = EXTRACT_16BITS(tptr);
  1400. ena_cap = EXTRACT_16BITS(tptr+2);
  1401. ND_PRINT((ndo, "\n\t System Capabilities [%s] (0x%04x)",
  1402. bittok2str(lldp_cap_values, "none", cap), cap));
  1403. ND_PRINT((ndo, "\n\t Enabled Capabilities [%s] (0x%04x)",
  1404. bittok2str(lldp_cap_values, "none", ena_cap), ena_cap));
  1405. }
  1406. break;
  1407. case LLDP_MGMT_ADDR_TLV:
  1408. if (ndo->ndo_vflag) {
  1409. if (!lldp_mgmt_addr_tlv_print(ndo, tptr, tlv_len)) {
  1410. goto trunc;
  1411. }
  1412. }
  1413. break;
  1414. case LLDP_PRIVATE_TLV:
  1415. if (ndo->ndo_vflag) {
  1416. if (tlv_len < 3) {
  1417. goto trunc;
  1418. }
  1419. oui = EXTRACT_24BITS(tptr);
  1420. ND_PRINT((ndo, ": OUI %s (0x%06x)", tok2str(oui_values, "Unknown", oui), oui));
  1421. switch (oui) {
  1422. case OUI_IEEE_8021_PRIVATE:
  1423. hexdump = lldp_private_8021_print(ndo, tptr, tlv_len);
  1424. break;
  1425. case OUI_IEEE_8023_PRIVATE:
  1426. hexdump = lldp_private_8023_print(ndo, tptr, tlv_len);
  1427. break;
  1428. case OUI_IANA:
  1429. hexdump = lldp_private_iana_print(ndo, tptr, tlv_len);
  1430. break;
  1431. case OUI_TIA:
  1432. hexdump = lldp_private_tia_print(ndo, tptr, tlv_len);
  1433. break;
  1434. case OUI_DCBX:
  1435. hexdump = lldp_private_dcbx_print(ndo, tptr, tlv_len);
  1436. break;
  1437. default:
  1438. hexdump = TRUE;
  1439. break;
  1440. }
  1441. }
  1442. break;
  1443. default:
  1444. hexdump = TRUE;
  1445. break;
  1446. }
  1447. /* do we also want to see a hex dump ? */
  1448. if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) {
  1449. print_unknown_data(ndo, tptr, "\n\t ", tlv_len);
  1450. }
  1451. tlen -= tlv_len;
  1452. tptr += tlv_len;
  1453. }
  1454. return;
  1455. trunc:
  1456. ND_PRINT((ndo, "\n\t[|LLDP]"));
  1457. }
  1458. /*
  1459. * Local Variables:
  1460. * c-style: whitesmith
  1461. * c-basic-offset: 4
  1462. * End:
  1463. */