lldp.go 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585
  1. // Copyright 2012 Google, Inc. All rights reserved.
  2. //
  3. // Use of this source code is governed by a BSD-style license
  4. // that can be found in the LICENSE file in the root of the source
  5. // tree.
  6. package layers
  7. import (
  8. "encoding/binary"
  9. "errors"
  10. "fmt"
  11. "github.com/google/gopacket"
  12. )
  13. // LLDPTLVType is the type of each TLV value in a LinkLayerDiscovery packet.
  14. type LLDPTLVType byte
  15. const (
  16. LLDPTLVEnd LLDPTLVType = 0
  17. LLDPTLVChassisID LLDPTLVType = 1
  18. LLDPTLVPortID LLDPTLVType = 2
  19. LLDPTLVTTL LLDPTLVType = 3
  20. LLDPTLVPortDescription LLDPTLVType = 4
  21. LLDPTLVSysName LLDPTLVType = 5
  22. LLDPTLVSysDescription LLDPTLVType = 6
  23. LLDPTLVSysCapabilities LLDPTLVType = 7
  24. LLDPTLVMgmtAddress LLDPTLVType = 8
  25. LLDPTLVOrgSpecific LLDPTLVType = 127
  26. )
  27. // LinkLayerDiscoveryValue is a TLV value inside a LinkLayerDiscovery packet layer.
  28. type LinkLayerDiscoveryValue struct {
  29. Type LLDPTLVType
  30. Length uint16
  31. Value []byte
  32. }
  33. func (c *LinkLayerDiscoveryValue) len() int {
  34. return 0
  35. }
  36. // LLDPChassisIDSubType specifies the value type for a single LLDPChassisID.ID
  37. type LLDPChassisIDSubType byte
  38. // LLDP Chassis Types
  39. const (
  40. LLDPChassisIDSubTypeReserved LLDPChassisIDSubType = 0
  41. LLDPChassisIDSubTypeChassisComp LLDPChassisIDSubType = 1
  42. LLDPChassisIDSubtypeIfaceAlias LLDPChassisIDSubType = 2
  43. LLDPChassisIDSubTypePortComp LLDPChassisIDSubType = 3
  44. LLDPChassisIDSubTypeMACAddr LLDPChassisIDSubType = 4
  45. LLDPChassisIDSubTypeNetworkAddr LLDPChassisIDSubType = 5
  46. LLDPChassisIDSubtypeIfaceName LLDPChassisIDSubType = 6
  47. LLDPChassisIDSubTypeLocal LLDPChassisIDSubType = 7
  48. )
  49. type LLDPChassisID struct {
  50. Subtype LLDPChassisIDSubType
  51. ID []byte
  52. }
  53. func (c *LLDPChassisID) serialize() []byte {
  54. var buf = make([]byte, c.serializedLen())
  55. idLen := uint16(LLDPTLVChassisID)<<9 | uint16(len(c.ID)+1) //id should take 7 bits, length should take 9 bits, +1 for subtype
  56. binary.BigEndian.PutUint16(buf[0:2], idLen)
  57. buf[2] = byte(c.Subtype)
  58. copy(buf[3:], c.ID)
  59. return buf
  60. }
  61. func (c *LLDPChassisID) serializedLen() int {
  62. return len(c.ID) + 3 // +2 for id and length, +1 for subtype
  63. }
  64. // LLDPPortIDSubType specifies the value type for a single LLDPPortID.ID
  65. type LLDPPortIDSubType byte
  66. // LLDP PortID types
  67. const (
  68. LLDPPortIDSubtypeReserved LLDPPortIDSubType = 0
  69. LLDPPortIDSubtypeIfaceAlias LLDPPortIDSubType = 1
  70. LLDPPortIDSubtypePortComp LLDPPortIDSubType = 2
  71. LLDPPortIDSubtypeMACAddr LLDPPortIDSubType = 3
  72. LLDPPortIDSubtypeNetworkAddr LLDPPortIDSubType = 4
  73. LLDPPortIDSubtypeIfaceName LLDPPortIDSubType = 5
  74. LLDPPortIDSubtypeAgentCircuitID LLDPPortIDSubType = 6
  75. LLDPPortIDSubtypeLocal LLDPPortIDSubType = 7
  76. )
  77. type LLDPPortID struct {
  78. Subtype LLDPPortIDSubType
  79. ID []byte
  80. }
  81. func (c *LLDPPortID) serialize() []byte {
  82. var buf = make([]byte, c.serializedLen())
  83. idLen := uint16(LLDPTLVPortID)<<9 | uint16(len(c.ID)+1) //id should take 7 bits, length should take 9 bits, +1 for subtype
  84. binary.BigEndian.PutUint16(buf[0:2], idLen)
  85. buf[2] = byte(c.Subtype)
  86. copy(buf[3:], c.ID)
  87. return buf
  88. }
  89. func (c *LLDPPortID) serializedLen() int {
  90. return len(c.ID) + 3 // +2 for id and length, +1 for subtype
  91. }
  92. // LinkLayerDiscovery is a packet layer containing the LinkLayer Discovery Protocol.
  93. // See http:http://standards.ieee.org/getieee802/download/802.1AB-2009.pdf
  94. // ChassisID, PortID and TTL are mandatory TLV's. Other values can be decoded
  95. // with DecodeValues()
  96. type LinkLayerDiscovery struct {
  97. BaseLayer
  98. ChassisID LLDPChassisID
  99. PortID LLDPPortID
  100. TTL uint16
  101. Values []LinkLayerDiscoveryValue
  102. }
  103. type IEEEOUI uint32
  104. // http://standards.ieee.org/develop/regauth/oui/oui.txt
  105. const (
  106. IEEEOUI8021 IEEEOUI = 0x0080c2
  107. IEEEOUI8023 IEEEOUI = 0x00120f
  108. IEEEOUI80211 IEEEOUI = 0x000fac
  109. IEEEOUI8021Qbg IEEEOUI = 0x0013BF
  110. IEEEOUICisco2 IEEEOUI = 0x000142
  111. IEEEOUIMedia IEEEOUI = 0x0012bb // TR-41
  112. IEEEOUIProfinet IEEEOUI = 0x000ecf
  113. IEEEOUIDCBX IEEEOUI = 0x001b21
  114. )
  115. // LLDPOrgSpecificTLV is an Organisation-specific TLV
  116. type LLDPOrgSpecificTLV struct {
  117. OUI IEEEOUI
  118. SubType uint8
  119. Info []byte
  120. }
  121. // LLDPCapabilities Types
  122. const (
  123. LLDPCapsOther uint16 = 1 << 0
  124. LLDPCapsRepeater uint16 = 1 << 1
  125. LLDPCapsBridge uint16 = 1 << 2
  126. LLDPCapsWLANAP uint16 = 1 << 3
  127. LLDPCapsRouter uint16 = 1 << 4
  128. LLDPCapsPhone uint16 = 1 << 5
  129. LLDPCapsDocSis uint16 = 1 << 6
  130. LLDPCapsStationOnly uint16 = 1 << 7
  131. LLDPCapsCVLAN uint16 = 1 << 8
  132. LLDPCapsSVLAN uint16 = 1 << 9
  133. LLDPCapsTmpr uint16 = 1 << 10
  134. )
  135. // LLDPCapabilities represents the capabilities of a device
  136. type LLDPCapabilities struct {
  137. Other bool
  138. Repeater bool
  139. Bridge bool
  140. WLANAP bool
  141. Router bool
  142. Phone bool
  143. DocSis bool
  144. StationOnly bool
  145. CVLAN bool
  146. SVLAN bool
  147. TMPR bool
  148. }
  149. type LLDPSysCapabilities struct {
  150. SystemCap LLDPCapabilities
  151. EnabledCap LLDPCapabilities
  152. }
  153. type IANAAddressFamily byte
  154. // LLDP Management Address Subtypes
  155. // http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml
  156. const (
  157. IANAAddressFamilyReserved IANAAddressFamily = 0
  158. IANAAddressFamilyIPV4 IANAAddressFamily = 1
  159. IANAAddressFamilyIPV6 IANAAddressFamily = 2
  160. IANAAddressFamilyNSAP IANAAddressFamily = 3
  161. IANAAddressFamilyHDLC IANAAddressFamily = 4
  162. IANAAddressFamilyBBN1822 IANAAddressFamily = 5
  163. IANAAddressFamily802 IANAAddressFamily = 6
  164. IANAAddressFamilyE163 IANAAddressFamily = 7
  165. IANAAddressFamilyE164 IANAAddressFamily = 8
  166. IANAAddressFamilyF69 IANAAddressFamily = 9
  167. IANAAddressFamilyX121 IANAAddressFamily = 10
  168. IANAAddressFamilyIPX IANAAddressFamily = 11
  169. IANAAddressFamilyAtalk IANAAddressFamily = 12
  170. IANAAddressFamilyDecnet IANAAddressFamily = 13
  171. IANAAddressFamilyBanyan IANAAddressFamily = 14
  172. IANAAddressFamilyE164NSAP IANAAddressFamily = 15
  173. IANAAddressFamilyDNS IANAAddressFamily = 16
  174. IANAAddressFamilyDistname IANAAddressFamily = 17
  175. IANAAddressFamilyASNumber IANAAddressFamily = 18
  176. IANAAddressFamilyXTPIPV4 IANAAddressFamily = 19
  177. IANAAddressFamilyXTPIPV6 IANAAddressFamily = 20
  178. IANAAddressFamilyXTP IANAAddressFamily = 21
  179. IANAAddressFamilyFcWWPN IANAAddressFamily = 22
  180. IANAAddressFamilyFcWWNN IANAAddressFamily = 23
  181. IANAAddressFamilyGWID IANAAddressFamily = 24
  182. IANAAddressFamilyL2VPN IANAAddressFamily = 25
  183. )
  184. type LLDPInterfaceSubtype byte
  185. // LLDP Interface Subtypes
  186. const (
  187. LLDPInterfaceSubtypeUnknown LLDPInterfaceSubtype = 1
  188. LLDPInterfaceSubtypeifIndex LLDPInterfaceSubtype = 2
  189. LLDPInterfaceSubtypeSysPort LLDPInterfaceSubtype = 3
  190. )
  191. type LLDPMgmtAddress struct {
  192. Subtype IANAAddressFamily
  193. Address []byte
  194. InterfaceSubtype LLDPInterfaceSubtype
  195. InterfaceNumber uint32
  196. OID string
  197. }
  198. // LinkLayerDiscoveryInfo represents the decoded details for a set of LinkLayerDiscoveryValues
  199. // Organisation-specific TLV's can be decoded using the various Decode() methods
  200. type LinkLayerDiscoveryInfo struct {
  201. BaseLayer
  202. PortDescription string
  203. SysName string
  204. SysDescription string
  205. SysCapabilities LLDPSysCapabilities
  206. MgmtAddress LLDPMgmtAddress
  207. OrgTLVs []LLDPOrgSpecificTLV // Private TLVs
  208. Unknown []LinkLayerDiscoveryValue // undecoded TLVs
  209. }
  210. /// IEEE 802.1 TLV Subtypes
  211. const (
  212. LLDP8021SubtypePortVLANID uint8 = 1
  213. LLDP8021SubtypeProtocolVLANID uint8 = 2
  214. LLDP8021SubtypeVLANName uint8 = 3
  215. LLDP8021SubtypeProtocolIdentity uint8 = 4
  216. LLDP8021SubtypeVDIUsageDigest uint8 = 5
  217. LLDP8021SubtypeManagementVID uint8 = 6
  218. LLDP8021SubtypeLinkAggregation uint8 = 7
  219. )
  220. // VLAN Port Protocol ID options
  221. const (
  222. LLDPProtocolVLANIDCapability byte = 1 << 1
  223. LLDPProtocolVLANIDStatus byte = 1 << 2
  224. )
  225. type PortProtocolVLANID struct {
  226. Supported bool
  227. Enabled bool
  228. ID uint16
  229. }
  230. type VLANName struct {
  231. ID uint16
  232. Name string
  233. }
  234. type ProtocolIdentity []byte
  235. // LACP options
  236. const (
  237. LLDPAggregationCapability byte = 1 << 0
  238. LLDPAggregationStatus byte = 1 << 1
  239. )
  240. // IEEE 802 Link Aggregation parameters
  241. type LLDPLinkAggregation struct {
  242. Supported bool
  243. Enabled bool
  244. PortID uint32
  245. }
  246. // LLDPInfo8021 represents the information carried in 802.1 Org-specific TLVs
  247. type LLDPInfo8021 struct {
  248. PVID uint16
  249. PPVIDs []PortProtocolVLANID
  250. VLANNames []VLANName
  251. ProtocolIdentities []ProtocolIdentity
  252. VIDUsageDigest uint32
  253. ManagementVID uint16
  254. LinkAggregation LLDPLinkAggregation
  255. }
  256. // IEEE 802.3 TLV Subtypes
  257. const (
  258. LLDP8023SubtypeMACPHY uint8 = 1
  259. LLDP8023SubtypeMDIPower uint8 = 2
  260. LLDP8023SubtypeLinkAggregation uint8 = 3
  261. LLDP8023SubtypeMTU uint8 = 4
  262. )
  263. // MACPHY options
  264. const (
  265. LLDPMACPHYCapability byte = 1 << 0
  266. LLDPMACPHYStatus byte = 1 << 1
  267. )
  268. // From IANA-MAU-MIB (introduced by RFC 4836) - dot3MauType
  269. const (
  270. LLDPMAUTypeUnknown uint16 = 0
  271. LLDPMAUTypeAUI uint16 = 1
  272. LLDPMAUType10Base5 uint16 = 2
  273. LLDPMAUTypeFOIRL uint16 = 3
  274. LLDPMAUType10Base2 uint16 = 4
  275. LLDPMAUType10BaseT uint16 = 5
  276. LLDPMAUType10BaseFP uint16 = 6
  277. LLDPMAUType10BaseFB uint16 = 7
  278. LLDPMAUType10BaseFL uint16 = 8
  279. LLDPMAUType10BROAD36 uint16 = 9
  280. LLDPMAUType10BaseT_HD uint16 = 10
  281. LLDPMAUType10BaseT_FD uint16 = 11
  282. LLDPMAUType10BaseFL_HD uint16 = 12
  283. LLDPMAUType10BaseFL_FD uint16 = 13
  284. LLDPMAUType100BaseT4 uint16 = 14
  285. LLDPMAUType100BaseTX_HD uint16 = 15
  286. LLDPMAUType100BaseTX_FD uint16 = 16
  287. LLDPMAUType100BaseFX_HD uint16 = 17
  288. LLDPMAUType100BaseFX_FD uint16 = 18
  289. LLDPMAUType100BaseT2_HD uint16 = 19
  290. LLDPMAUType100BaseT2_FD uint16 = 20
  291. LLDPMAUType1000BaseX_HD uint16 = 21
  292. LLDPMAUType1000BaseX_FD uint16 = 22
  293. LLDPMAUType1000BaseLX_HD uint16 = 23
  294. LLDPMAUType1000BaseLX_FD uint16 = 24
  295. LLDPMAUType1000BaseSX_HD uint16 = 25
  296. LLDPMAUType1000BaseSX_FD uint16 = 26
  297. LLDPMAUType1000BaseCX_HD uint16 = 27
  298. LLDPMAUType1000BaseCX_FD uint16 = 28
  299. LLDPMAUType1000BaseT_HD uint16 = 29
  300. LLDPMAUType1000BaseT_FD uint16 = 30
  301. LLDPMAUType10GBaseX uint16 = 31
  302. LLDPMAUType10GBaseLX4 uint16 = 32
  303. LLDPMAUType10GBaseR uint16 = 33
  304. LLDPMAUType10GBaseER uint16 = 34
  305. LLDPMAUType10GBaseLR uint16 = 35
  306. LLDPMAUType10GBaseSR uint16 = 36
  307. LLDPMAUType10GBaseW uint16 = 37
  308. LLDPMAUType10GBaseEW uint16 = 38
  309. LLDPMAUType10GBaseLW uint16 = 39
  310. LLDPMAUType10GBaseSW uint16 = 40
  311. LLDPMAUType10GBaseCX4 uint16 = 41
  312. LLDPMAUType2BaseTL uint16 = 42
  313. LLDPMAUType10PASS_TS uint16 = 43
  314. LLDPMAUType100BaseBX10D uint16 = 44
  315. LLDPMAUType100BaseBX10U uint16 = 45
  316. LLDPMAUType100BaseLX10 uint16 = 46
  317. LLDPMAUType1000BaseBX10D uint16 = 47
  318. LLDPMAUType1000BaseBX10U uint16 = 48
  319. LLDPMAUType1000BaseLX10 uint16 = 49
  320. LLDPMAUType1000BasePX10D uint16 = 50
  321. LLDPMAUType1000BasePX10U uint16 = 51
  322. LLDPMAUType1000BasePX20D uint16 = 52
  323. LLDPMAUType1000BasePX20U uint16 = 53
  324. LLDPMAUType10GBaseT uint16 = 54
  325. LLDPMAUType10GBaseLRM uint16 = 55
  326. LLDPMAUType1000BaseKX uint16 = 56
  327. LLDPMAUType10GBaseKX4 uint16 = 57
  328. LLDPMAUType10GBaseKR uint16 = 58
  329. LLDPMAUType10_1GBasePRX_D1 uint16 = 59
  330. LLDPMAUType10_1GBasePRX_D2 uint16 = 60
  331. LLDPMAUType10_1GBasePRX_D3 uint16 = 61
  332. LLDPMAUType10_1GBasePRX_U1 uint16 = 62
  333. LLDPMAUType10_1GBasePRX_U2 uint16 = 63
  334. LLDPMAUType10_1GBasePRX_U3 uint16 = 64
  335. LLDPMAUType10GBasePR_D1 uint16 = 65
  336. LLDPMAUType10GBasePR_D2 uint16 = 66
  337. LLDPMAUType10GBasePR_D3 uint16 = 67
  338. LLDPMAUType10GBasePR_U1 uint16 = 68
  339. LLDPMAUType10GBasePR_U3 uint16 = 69
  340. )
  341. // From RFC 3636 - ifMauAutoNegCapAdvertisedBits
  342. const (
  343. LLDPMAUPMDOther uint16 = 1 << 15
  344. LLDPMAUPMD10BaseT uint16 = 1 << 14
  345. LLDPMAUPMD10BaseT_FD uint16 = 1 << 13
  346. LLDPMAUPMD100BaseT4 uint16 = 1 << 12
  347. LLDPMAUPMD100BaseTX uint16 = 1 << 11
  348. LLDPMAUPMD100BaseTX_FD uint16 = 1 << 10
  349. LLDPMAUPMD100BaseT2 uint16 = 1 << 9
  350. LLDPMAUPMD100BaseT2_FD uint16 = 1 << 8
  351. LLDPMAUPMDFDXPAUSE uint16 = 1 << 7
  352. LLDPMAUPMDFDXAPAUSE uint16 = 1 << 6
  353. LLDPMAUPMDFDXSPAUSE uint16 = 1 << 5
  354. LLDPMAUPMDFDXBPAUSE uint16 = 1 << 4
  355. LLDPMAUPMD1000BaseX uint16 = 1 << 3
  356. LLDPMAUPMD1000BaseX_FD uint16 = 1 << 2
  357. LLDPMAUPMD1000BaseT uint16 = 1 << 1
  358. LLDPMAUPMD1000BaseT_FD uint16 = 1 << 0
  359. )
  360. // Inverted ifMauAutoNegCapAdvertisedBits if required
  361. // (Some manufacturers misinterpreted the spec -
  362. // see https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=1455)
  363. const (
  364. LLDPMAUPMDOtherInv uint16 = 1 << 0
  365. LLDPMAUPMD10BaseTInv uint16 = 1 << 1
  366. LLDPMAUPMD10BaseT_FDInv uint16 = 1 << 2
  367. LLDPMAUPMD100BaseT4Inv uint16 = 1 << 3
  368. LLDPMAUPMD100BaseTXInv uint16 = 1 << 4
  369. LLDPMAUPMD100BaseTX_FDInv uint16 = 1 << 5
  370. LLDPMAUPMD100BaseT2Inv uint16 = 1 << 6
  371. LLDPMAUPMD100BaseT2_FDInv uint16 = 1 << 7
  372. LLDPMAUPMDFDXPAUSEInv uint16 = 1 << 8
  373. LLDPMAUPMDFDXAPAUSEInv uint16 = 1 << 9
  374. LLDPMAUPMDFDXSPAUSEInv uint16 = 1 << 10
  375. LLDPMAUPMDFDXBPAUSEInv uint16 = 1 << 11
  376. LLDPMAUPMD1000BaseXInv uint16 = 1 << 12
  377. LLDPMAUPMD1000BaseX_FDInv uint16 = 1 << 13
  378. LLDPMAUPMD1000BaseTInv uint16 = 1 << 14
  379. LLDPMAUPMD1000BaseT_FDInv uint16 = 1 << 15
  380. )
  381. type LLDPMACPHYConfigStatus struct {
  382. AutoNegSupported bool
  383. AutoNegEnabled bool
  384. AutoNegCapability uint16
  385. MAUType uint16
  386. }
  387. // MDI Power options
  388. const (
  389. LLDPMDIPowerPortClass byte = 1 << 0
  390. LLDPMDIPowerCapability byte = 1 << 1
  391. LLDPMDIPowerStatus byte = 1 << 2
  392. LLDPMDIPowerPairsAbility byte = 1 << 3
  393. )
  394. type LLDPPowerType byte
  395. type LLDPPowerSource byte
  396. type LLDPPowerPriority byte
  397. const (
  398. LLDPPowerPriorityUnknown LLDPPowerPriority = 0
  399. LLDPPowerPriorityMedium LLDPPowerPriority = 1
  400. LLDPPowerPriorityHigh LLDPPowerPriority = 2
  401. LLDPPowerPriorityLow LLDPPowerPriority = 3
  402. )
  403. type LLDPPowerViaMDI8023 struct {
  404. PortClassPSE bool // false = PD
  405. PSESupported bool
  406. PSEEnabled bool
  407. PSEPairsAbility bool
  408. PSEPowerPair uint8
  409. PSEClass uint8
  410. Type LLDPPowerType
  411. Source LLDPPowerSource
  412. Priority LLDPPowerPriority
  413. Requested uint16 // 1-510 Watts
  414. Allocated uint16 // 1-510 Watts
  415. }
  416. // LLDPInfo8023 represents the information carried in 802.3 Org-specific TLVs
  417. type LLDPInfo8023 struct {
  418. MACPHYConfigStatus LLDPMACPHYConfigStatus
  419. PowerViaMDI LLDPPowerViaMDI8023
  420. LinkAggregation LLDPLinkAggregation
  421. MTU uint16
  422. }
  423. // IEEE 802.1Qbg TLV Subtypes
  424. const (
  425. LLDP8021QbgEVB uint8 = 0
  426. LLDP8021QbgCDCP uint8 = 1
  427. LLDP8021QbgVDP uint8 = 2
  428. LLDP8021QbgEVB22 uint8 = 13
  429. )
  430. // LLDPEVBCapabilities Types
  431. const (
  432. LLDPEVBCapsSTD uint16 = 1 << 7
  433. LLDPEVBCapsRR uint16 = 1 << 6
  434. LLDPEVBCapsRTE uint16 = 1 << 2
  435. LLDPEVBCapsECP uint16 = 1 << 1
  436. LLDPEVBCapsVDP uint16 = 1 << 0
  437. )
  438. // LLDPEVBCapabilities represents the EVB capabilities of a device
  439. type LLDPEVBCapabilities struct {
  440. StandardBridging bool
  441. ReflectiveRelay bool
  442. RetransmissionTimerExponent bool
  443. EdgeControlProtocol bool
  444. VSIDiscoveryProtocol bool
  445. }
  446. type LLDPEVBSettings struct {
  447. Supported LLDPEVBCapabilities
  448. Enabled LLDPEVBCapabilities
  449. SupportedVSIs uint16
  450. ConfiguredVSIs uint16
  451. RTEExponent uint8
  452. }
  453. // LLDPInfo8021Qbg represents the information carried in 802.1Qbg Org-specific TLVs
  454. type LLDPInfo8021Qbg struct {
  455. EVBSettings LLDPEVBSettings
  456. }
  457. type LLDPMediaSubtype uint8
  458. // Media TLV Subtypes
  459. const (
  460. LLDPMediaTypeCapabilities LLDPMediaSubtype = 1
  461. LLDPMediaTypeNetwork LLDPMediaSubtype = 2
  462. LLDPMediaTypeLocation LLDPMediaSubtype = 3
  463. LLDPMediaTypePower LLDPMediaSubtype = 4
  464. LLDPMediaTypeHardware LLDPMediaSubtype = 5
  465. LLDPMediaTypeFirmware LLDPMediaSubtype = 6
  466. LLDPMediaTypeSoftware LLDPMediaSubtype = 7
  467. LLDPMediaTypeSerial LLDPMediaSubtype = 8
  468. LLDPMediaTypeManufacturer LLDPMediaSubtype = 9
  469. LLDPMediaTypeModel LLDPMediaSubtype = 10
  470. LLDPMediaTypeAssetID LLDPMediaSubtype = 11
  471. )
  472. type LLDPMediaClass uint8
  473. // Media Class Values
  474. const (
  475. LLDPMediaClassUndefined LLDPMediaClass = 0
  476. LLDPMediaClassEndpointI LLDPMediaClass = 1
  477. LLDPMediaClassEndpointII LLDPMediaClass = 2
  478. LLDPMediaClassEndpointIII LLDPMediaClass = 3
  479. LLDPMediaClassNetwork LLDPMediaClass = 4
  480. )
  481. // LLDPMediaCapabilities Types
  482. const (
  483. LLDPMediaCapsLLDP uint16 = 1 << 0
  484. LLDPMediaCapsNetwork uint16 = 1 << 1
  485. LLDPMediaCapsLocation uint16 = 1 << 2
  486. LLDPMediaCapsPowerPSE uint16 = 1 << 3
  487. LLDPMediaCapsPowerPD uint16 = 1 << 4
  488. LLDPMediaCapsInventory uint16 = 1 << 5
  489. )
  490. // LLDPMediaCapabilities represents the LLDP Media capabilities of a device
  491. type LLDPMediaCapabilities struct {
  492. Capabilities bool
  493. NetworkPolicy bool
  494. Location bool
  495. PowerPSE bool
  496. PowerPD bool
  497. Inventory bool
  498. Class LLDPMediaClass
  499. }
  500. type LLDPApplicationType uint8
  501. const (
  502. LLDPAppTypeReserved LLDPApplicationType = 0
  503. LLDPAppTypeVoice LLDPApplicationType = 1
  504. LLDPappTypeVoiceSignaling LLDPApplicationType = 2
  505. LLDPappTypeGuestVoice LLDPApplicationType = 3
  506. LLDPappTypeGuestVoiceSignaling LLDPApplicationType = 4
  507. LLDPappTypeSoftphoneVoice LLDPApplicationType = 5
  508. LLDPappTypeVideoConferencing LLDPApplicationType = 6
  509. LLDPappTypeStreamingVideo LLDPApplicationType = 7
  510. LLDPappTypeVideoSignaling LLDPApplicationType = 8
  511. )
  512. type LLDPNetworkPolicy struct {
  513. ApplicationType LLDPApplicationType
  514. Defined bool
  515. Tagged bool
  516. VLANId uint16
  517. L2Priority uint16
  518. DSCPValue uint8
  519. }
  520. type LLDPLocationFormat uint8
  521. const (
  522. LLDPLocationFormatInvalid LLDPLocationFormat = 0
  523. LLDPLocationFormatCoordinate LLDPLocationFormat = 1
  524. LLDPLocationFormatAddress LLDPLocationFormat = 2
  525. LLDPLocationFormatECS LLDPLocationFormat = 3
  526. )
  527. type LLDPLocationAddressWhat uint8
  528. const (
  529. LLDPLocationAddressWhatDHCP LLDPLocationAddressWhat = 0
  530. LLDPLocationAddressWhatNetwork LLDPLocationAddressWhat = 1
  531. LLDPLocationAddressWhatClient LLDPLocationAddressWhat = 2
  532. )
  533. type LLDPLocationAddressType uint8
  534. const (
  535. LLDPLocationAddressTypeLanguage LLDPLocationAddressType = 0
  536. LLDPLocationAddressTypeNational LLDPLocationAddressType = 1
  537. LLDPLocationAddressTypeCounty LLDPLocationAddressType = 2
  538. LLDPLocationAddressTypeCity LLDPLocationAddressType = 3
  539. LLDPLocationAddressTypeCityDivision LLDPLocationAddressType = 4
  540. LLDPLocationAddressTypeNeighborhood LLDPLocationAddressType = 5
  541. LLDPLocationAddressTypeStreet LLDPLocationAddressType = 6
  542. LLDPLocationAddressTypeLeadingStreet LLDPLocationAddressType = 16
  543. LLDPLocationAddressTypeTrailingStreet LLDPLocationAddressType = 17
  544. LLDPLocationAddressTypeStreetSuffix LLDPLocationAddressType = 18
  545. LLDPLocationAddressTypeHouseNum LLDPLocationAddressType = 19
  546. LLDPLocationAddressTypeHouseSuffix LLDPLocationAddressType = 20
  547. LLDPLocationAddressTypeLandmark LLDPLocationAddressType = 21
  548. LLDPLocationAddressTypeAdditional LLDPLocationAddressType = 22
  549. LLDPLocationAddressTypeName LLDPLocationAddressType = 23
  550. LLDPLocationAddressTypePostal LLDPLocationAddressType = 24
  551. LLDPLocationAddressTypeBuilding LLDPLocationAddressType = 25
  552. LLDPLocationAddressTypeUnit LLDPLocationAddressType = 26
  553. LLDPLocationAddressTypeFloor LLDPLocationAddressType = 27
  554. LLDPLocationAddressTypeRoom LLDPLocationAddressType = 28
  555. LLDPLocationAddressTypePlace LLDPLocationAddressType = 29
  556. LLDPLocationAddressTypeScript LLDPLocationAddressType = 128
  557. )
  558. type LLDPLocationCoordinate struct {
  559. LatitudeResolution uint8
  560. Latitude uint64
  561. LongitudeResolution uint8
  562. Longitude uint64
  563. AltitudeType uint8
  564. AltitudeResolution uint16
  565. Altitude uint32
  566. Datum uint8
  567. }
  568. type LLDPLocationAddressLine struct {
  569. Type LLDPLocationAddressType
  570. Value string
  571. }
  572. type LLDPLocationAddress struct {
  573. What LLDPLocationAddressWhat
  574. CountryCode string
  575. AddressLines []LLDPLocationAddressLine
  576. }
  577. type LLDPLocationECS struct {
  578. ELIN string
  579. }
  580. // LLDP represents a physical location.
  581. // Only one of the embedded types will contain values, depending on Format.
  582. type LLDPLocation struct {
  583. Format LLDPLocationFormat
  584. Coordinate LLDPLocationCoordinate
  585. Address LLDPLocationAddress
  586. ECS LLDPLocationECS
  587. }
  588. type LLDPPowerViaMDI struct {
  589. Type LLDPPowerType
  590. Source LLDPPowerSource
  591. Priority LLDPPowerPriority
  592. Value uint16
  593. }
  594. // LLDPInfoMedia represents the information carried in TR-41 Org-specific TLVs
  595. type LLDPInfoMedia struct {
  596. MediaCapabilities LLDPMediaCapabilities
  597. NetworkPolicy LLDPNetworkPolicy
  598. Location LLDPLocation
  599. PowerViaMDI LLDPPowerViaMDI
  600. HardwareRevision string
  601. FirmwareRevision string
  602. SoftwareRevision string
  603. SerialNumber string
  604. Manufacturer string
  605. Model string
  606. AssetID string
  607. }
  608. type LLDPCisco2Subtype uint8
  609. // Cisco2 TLV Subtypes
  610. const (
  611. LLDPCisco2PowerViaMDI LLDPCisco2Subtype = 1
  612. )
  613. const (
  614. LLDPCiscoPSESupport uint8 = 1 << 0
  615. LLDPCiscoArchShared uint8 = 1 << 1
  616. LLDPCiscoPDSparePair uint8 = 1 << 2
  617. LLDPCiscoPSESparePair uint8 = 1 << 3
  618. )
  619. // LLDPInfoCisco2 represents the information carried in Cisco Org-specific TLVs
  620. type LLDPInfoCisco2 struct {
  621. PSEFourWirePoESupported bool
  622. PDSparePairArchitectureShared bool
  623. PDRequestSparePairPoEOn bool
  624. PSESparePairPoEOn bool
  625. }
  626. // Profinet Subtypes
  627. type LLDPProfinetSubtype uint8
  628. const (
  629. LLDPProfinetPNIODelay LLDPProfinetSubtype = 1
  630. LLDPProfinetPNIOPortStatus LLDPProfinetSubtype = 2
  631. LLDPProfinetPNIOMRPPortStatus LLDPProfinetSubtype = 4
  632. LLDPProfinetPNIOChassisMAC LLDPProfinetSubtype = 5
  633. LLDPProfinetPNIOPTCPStatus LLDPProfinetSubtype = 6
  634. )
  635. type LLDPPNIODelay struct {
  636. RXLocal uint32
  637. RXRemote uint32
  638. TXLocal uint32
  639. TXRemote uint32
  640. CableLocal uint32
  641. }
  642. type LLDPPNIOPortStatus struct {
  643. Class2 uint16
  644. Class3 uint16
  645. }
  646. type LLDPPNIOMRPPortStatus struct {
  647. UUID []byte
  648. Status uint16
  649. }
  650. type LLDPPNIOPTCPStatus struct {
  651. MasterAddress []byte
  652. SubdomainUUID []byte
  653. IRDataUUID []byte
  654. PeriodValid bool
  655. PeriodLength uint32
  656. RedPeriodValid bool
  657. RedPeriodBegin uint32
  658. OrangePeriodValid bool
  659. OrangePeriodBegin uint32
  660. GreenPeriodValid bool
  661. GreenPeriodBegin uint32
  662. }
  663. // LLDPInfoProfinet represents the information carried in Profinet Org-specific TLVs
  664. type LLDPInfoProfinet struct {
  665. PNIODelay LLDPPNIODelay
  666. PNIOPortStatus LLDPPNIOPortStatus
  667. PNIOMRPPortStatus LLDPPNIOMRPPortStatus
  668. ChassisMAC []byte
  669. PNIOPTCPStatus LLDPPNIOPTCPStatus
  670. }
  671. // LayerType returns gopacket.LayerTypeLinkLayerDiscovery.
  672. func (c *LinkLayerDiscovery) LayerType() gopacket.LayerType {
  673. return LayerTypeLinkLayerDiscovery
  674. }
  675. // SerializeTo serializes LLDP packet to bytes and writes on SerializeBuffer.
  676. func (c *LinkLayerDiscovery) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  677. chassIDLen := c.ChassisID.serializedLen()
  678. portIDLen := c.PortID.serializedLen()
  679. vb, err := b.AppendBytes(chassIDLen + portIDLen + 4) // +4 for TTL
  680. if err != nil {
  681. return err
  682. }
  683. copy(vb[:chassIDLen], c.ChassisID.serialize())
  684. copy(vb[chassIDLen:], c.PortID.serialize())
  685. ttlIDLen := uint16(LLDPTLVTTL)<<9 | uint16(2)
  686. binary.BigEndian.PutUint16(vb[chassIDLen+portIDLen:], ttlIDLen)
  687. binary.BigEndian.PutUint16(vb[chassIDLen+portIDLen+2:], c.TTL)
  688. vb, err = b.AppendBytes(2) // End Tlv, 2 bytes
  689. if err != nil {
  690. return err
  691. }
  692. binary.BigEndian.PutUint16(vb[len(vb)-2:], uint16(0)) //End tlv, 2 bytes, all zero
  693. return nil
  694. }
  695. func decodeLinkLayerDiscovery(data []byte, p gopacket.PacketBuilder) error {
  696. var vals []LinkLayerDiscoveryValue
  697. vData := data[0:]
  698. for len(vData) > 0 {
  699. nbit := vData[0] & 0x01
  700. t := LLDPTLVType(vData[0] >> 1)
  701. val := LinkLayerDiscoveryValue{Type: t, Length: uint16(nbit)<<8 + uint16(vData[1])}
  702. if val.Length > 0 {
  703. val.Value = vData[2 : val.Length+2]
  704. }
  705. vals = append(vals, val)
  706. if t == LLDPTLVEnd {
  707. break
  708. }
  709. if len(vData) < int(2+val.Length) {
  710. return errors.New("Malformed LinkLayerDiscovery Header")
  711. }
  712. vData = vData[2+val.Length:]
  713. }
  714. if len(vals) < 4 {
  715. return errors.New("Missing mandatory LinkLayerDiscovery TLV")
  716. }
  717. c := &LinkLayerDiscovery{}
  718. gotEnd := false
  719. for _, v := range vals {
  720. switch v.Type {
  721. case LLDPTLVEnd:
  722. gotEnd = true
  723. case LLDPTLVChassisID:
  724. if len(v.Value) < 2 {
  725. return errors.New("Malformed LinkLayerDiscovery ChassisID TLV")
  726. }
  727. c.ChassisID.Subtype = LLDPChassisIDSubType(v.Value[0])
  728. c.ChassisID.ID = v.Value[1:]
  729. case LLDPTLVPortID:
  730. if len(v.Value) < 2 {
  731. return errors.New("Malformed LinkLayerDiscovery PortID TLV")
  732. }
  733. c.PortID.Subtype = LLDPPortIDSubType(v.Value[0])
  734. c.PortID.ID = v.Value[1:]
  735. case LLDPTLVTTL:
  736. if len(v.Value) < 2 {
  737. return errors.New("Malformed LinkLayerDiscovery TTL TLV")
  738. }
  739. c.TTL = binary.BigEndian.Uint16(v.Value[0:2])
  740. default:
  741. c.Values = append(c.Values, v)
  742. }
  743. }
  744. if c.ChassisID.Subtype == 0 || c.PortID.Subtype == 0 || !gotEnd {
  745. return errors.New("Missing mandatory LinkLayerDiscovery TLV")
  746. }
  747. c.Contents = data
  748. p.AddLayer(c)
  749. info := &LinkLayerDiscoveryInfo{}
  750. p.AddLayer(info)
  751. for _, v := range c.Values {
  752. switch v.Type {
  753. case LLDPTLVPortDescription:
  754. info.PortDescription = string(v.Value)
  755. case LLDPTLVSysName:
  756. info.SysName = string(v.Value)
  757. case LLDPTLVSysDescription:
  758. info.SysDescription = string(v.Value)
  759. case LLDPTLVSysCapabilities:
  760. if err := checkLLDPTLVLen(v, 4); err != nil {
  761. return err
  762. }
  763. info.SysCapabilities.SystemCap = getCapabilities(binary.BigEndian.Uint16(v.Value[0:2]))
  764. info.SysCapabilities.EnabledCap = getCapabilities(binary.BigEndian.Uint16(v.Value[2:4]))
  765. case LLDPTLVMgmtAddress:
  766. if err := checkLLDPTLVLen(v, 9); err != nil {
  767. return err
  768. }
  769. mlen := v.Value[0]
  770. if err := checkLLDPTLVLen(v, int(mlen+7)); err != nil {
  771. return err
  772. }
  773. info.MgmtAddress.Subtype = IANAAddressFamily(v.Value[1])
  774. info.MgmtAddress.Address = v.Value[2 : mlen+1]
  775. info.MgmtAddress.InterfaceSubtype = LLDPInterfaceSubtype(v.Value[mlen+1])
  776. info.MgmtAddress.InterfaceNumber = binary.BigEndian.Uint32(v.Value[mlen+2 : mlen+6])
  777. olen := v.Value[mlen+6]
  778. if err := checkLLDPTLVLen(v, int(mlen+6+olen)); err != nil {
  779. return err
  780. }
  781. info.MgmtAddress.OID = string(v.Value[mlen+9 : mlen+9+olen])
  782. case LLDPTLVOrgSpecific:
  783. if err := checkLLDPTLVLen(v, 4); err != nil {
  784. return err
  785. }
  786. info.OrgTLVs = append(info.OrgTLVs, LLDPOrgSpecificTLV{IEEEOUI(binary.BigEndian.Uint32(append([]byte{byte(0)}, v.Value[0:3]...))), uint8(v.Value[3]), v.Value[4:]})
  787. }
  788. }
  789. return nil
  790. }
  791. func (l *LinkLayerDiscoveryInfo) Decode8021() (info LLDPInfo8021, err error) {
  792. for _, o := range l.OrgTLVs {
  793. if o.OUI != IEEEOUI8021 {
  794. continue
  795. }
  796. switch o.SubType {
  797. case LLDP8021SubtypePortVLANID:
  798. if err = checkLLDPOrgSpecificLen(o, 2); err != nil {
  799. return
  800. }
  801. info.PVID = binary.BigEndian.Uint16(o.Info[0:2])
  802. case LLDP8021SubtypeProtocolVLANID:
  803. if err = checkLLDPOrgSpecificLen(o, 3); err != nil {
  804. return
  805. }
  806. sup := (o.Info[0]&LLDPProtocolVLANIDCapability > 0)
  807. en := (o.Info[0]&LLDPProtocolVLANIDStatus > 0)
  808. id := binary.BigEndian.Uint16(o.Info[1:3])
  809. info.PPVIDs = append(info.PPVIDs, PortProtocolVLANID{sup, en, id})
  810. case LLDP8021SubtypeVLANName:
  811. if err = checkLLDPOrgSpecificLen(o, 2); err != nil {
  812. return
  813. }
  814. id := binary.BigEndian.Uint16(o.Info[0:2])
  815. info.VLANNames = append(info.VLANNames, VLANName{id, string(o.Info[3:])})
  816. case LLDP8021SubtypeProtocolIdentity:
  817. if err = checkLLDPOrgSpecificLen(o, 1); err != nil {
  818. return
  819. }
  820. l := int(o.Info[0])
  821. if l > 0 {
  822. info.ProtocolIdentities = append(info.ProtocolIdentities, o.Info[1:1+l])
  823. }
  824. case LLDP8021SubtypeVDIUsageDigest:
  825. if err = checkLLDPOrgSpecificLen(o, 4); err != nil {
  826. return
  827. }
  828. info.VIDUsageDigest = binary.BigEndian.Uint32(o.Info[0:4])
  829. case LLDP8021SubtypeManagementVID:
  830. if err = checkLLDPOrgSpecificLen(o, 2); err != nil {
  831. return
  832. }
  833. info.ManagementVID = binary.BigEndian.Uint16(o.Info[0:2])
  834. case LLDP8021SubtypeLinkAggregation:
  835. if err = checkLLDPOrgSpecificLen(o, 5); err != nil {
  836. return
  837. }
  838. sup := (o.Info[0]&LLDPAggregationCapability > 0)
  839. en := (o.Info[0]&LLDPAggregationStatus > 0)
  840. info.LinkAggregation = LLDPLinkAggregation{sup, en, binary.BigEndian.Uint32(o.Info[1:5])}
  841. }
  842. }
  843. return
  844. }
  845. func (l *LinkLayerDiscoveryInfo) Decode8023() (info LLDPInfo8023, err error) {
  846. for _, o := range l.OrgTLVs {
  847. if o.OUI != IEEEOUI8023 {
  848. continue
  849. }
  850. switch o.SubType {
  851. case LLDP8023SubtypeMACPHY:
  852. if err = checkLLDPOrgSpecificLen(o, 5); err != nil {
  853. return
  854. }
  855. sup := (o.Info[0]&LLDPMACPHYCapability > 0)
  856. en := (o.Info[0]&LLDPMACPHYStatus > 0)
  857. ca := binary.BigEndian.Uint16(o.Info[1:3])
  858. mau := binary.BigEndian.Uint16(o.Info[3:5])
  859. info.MACPHYConfigStatus = LLDPMACPHYConfigStatus{sup, en, ca, mau}
  860. case LLDP8023SubtypeMDIPower:
  861. if err = checkLLDPOrgSpecificLen(o, 3); err != nil {
  862. return
  863. }
  864. info.PowerViaMDI.PortClassPSE = (o.Info[0]&LLDPMDIPowerPortClass > 0)
  865. info.PowerViaMDI.PSESupported = (o.Info[0]&LLDPMDIPowerCapability > 0)
  866. info.PowerViaMDI.PSEEnabled = (o.Info[0]&LLDPMDIPowerStatus > 0)
  867. info.PowerViaMDI.PSEPairsAbility = (o.Info[0]&LLDPMDIPowerPairsAbility > 0)
  868. info.PowerViaMDI.PSEPowerPair = uint8(o.Info[1])
  869. info.PowerViaMDI.PSEClass = uint8(o.Info[2])
  870. if len(o.Info) >= 7 {
  871. info.PowerViaMDI.Type = LLDPPowerType((o.Info[3] & 0xc0) >> 6)
  872. info.PowerViaMDI.Source = LLDPPowerSource((o.Info[3] & 0x30) >> 4)
  873. if info.PowerViaMDI.Type == 1 || info.PowerViaMDI.Type == 3 {
  874. info.PowerViaMDI.Source += 128 // For Stringify purposes
  875. }
  876. info.PowerViaMDI.Priority = LLDPPowerPriority(o.Info[3] & 0x0f)
  877. info.PowerViaMDI.Requested = binary.BigEndian.Uint16(o.Info[4:6])
  878. info.PowerViaMDI.Allocated = binary.BigEndian.Uint16(o.Info[6:8])
  879. }
  880. case LLDP8023SubtypeLinkAggregation:
  881. if err = checkLLDPOrgSpecificLen(o, 5); err != nil {
  882. return
  883. }
  884. sup := (o.Info[0]&LLDPAggregationCapability > 0)
  885. en := (o.Info[0]&LLDPAggregationStatus > 0)
  886. info.LinkAggregation = LLDPLinkAggregation{sup, en, binary.BigEndian.Uint32(o.Info[1:5])}
  887. case LLDP8023SubtypeMTU:
  888. if err = checkLLDPOrgSpecificLen(o, 2); err != nil {
  889. return
  890. }
  891. info.MTU = binary.BigEndian.Uint16(o.Info[0:2])
  892. }
  893. }
  894. return
  895. }
  896. func (l *LinkLayerDiscoveryInfo) Decode8021Qbg() (info LLDPInfo8021Qbg, err error) {
  897. for _, o := range l.OrgTLVs {
  898. if o.OUI != IEEEOUI8021Qbg {
  899. continue
  900. }
  901. switch o.SubType {
  902. case LLDP8021QbgEVB:
  903. if err = checkLLDPOrgSpecificLen(o, 9); err != nil {
  904. return
  905. }
  906. info.EVBSettings.Supported = getEVBCapabilities(binary.BigEndian.Uint16(o.Info[0:2]))
  907. info.EVBSettings.Enabled = getEVBCapabilities(binary.BigEndian.Uint16(o.Info[2:4]))
  908. info.EVBSettings.SupportedVSIs = binary.BigEndian.Uint16(o.Info[4:6])
  909. info.EVBSettings.ConfiguredVSIs = binary.BigEndian.Uint16(o.Info[6:8])
  910. info.EVBSettings.RTEExponent = uint8(o.Info[8])
  911. }
  912. }
  913. return
  914. }
  915. func (l *LinkLayerDiscoveryInfo) DecodeMedia() (info LLDPInfoMedia, err error) {
  916. for _, o := range l.OrgTLVs {
  917. if o.OUI != IEEEOUIMedia {
  918. continue
  919. }
  920. switch LLDPMediaSubtype(o.SubType) {
  921. case LLDPMediaTypeCapabilities:
  922. if err = checkLLDPOrgSpecificLen(o, 3); err != nil {
  923. return
  924. }
  925. b := binary.BigEndian.Uint16(o.Info[0:2])
  926. info.MediaCapabilities.Capabilities = (b & LLDPMediaCapsLLDP) > 0
  927. info.MediaCapabilities.NetworkPolicy = (b & LLDPMediaCapsNetwork) > 0
  928. info.MediaCapabilities.Location = (b & LLDPMediaCapsLocation) > 0
  929. info.MediaCapabilities.PowerPSE = (b & LLDPMediaCapsPowerPSE) > 0
  930. info.MediaCapabilities.PowerPD = (b & LLDPMediaCapsPowerPD) > 0
  931. info.MediaCapabilities.Inventory = (b & LLDPMediaCapsInventory) > 0
  932. info.MediaCapabilities.Class = LLDPMediaClass(o.Info[2])
  933. case LLDPMediaTypeNetwork:
  934. if err = checkLLDPOrgSpecificLen(o, 4); err != nil {
  935. return
  936. }
  937. info.NetworkPolicy.ApplicationType = LLDPApplicationType(o.Info[0])
  938. b := binary.BigEndian.Uint16(o.Info[1:3])
  939. info.NetworkPolicy.Defined = (b & 0x8000) == 0
  940. info.NetworkPolicy.Tagged = (b & 0x4000) > 0
  941. info.NetworkPolicy.VLANId = (b & 0x1ffe) >> 1
  942. b = binary.BigEndian.Uint16(o.Info[2:4])
  943. info.NetworkPolicy.L2Priority = (b & 0x01c0) >> 6
  944. info.NetworkPolicy.DSCPValue = uint8(o.Info[3] & 0x3f)
  945. case LLDPMediaTypeLocation:
  946. if err = checkLLDPOrgSpecificLen(o, 1); err != nil {
  947. return
  948. }
  949. info.Location.Format = LLDPLocationFormat(o.Info[0])
  950. o.Info = o.Info[1:]
  951. switch info.Location.Format {
  952. case LLDPLocationFormatCoordinate:
  953. if err = checkLLDPOrgSpecificLen(o, 16); err != nil {
  954. return
  955. }
  956. info.Location.Coordinate.LatitudeResolution = uint8(o.Info[0]&0xfc) >> 2
  957. b := binary.BigEndian.Uint64(o.Info[0:8])
  958. info.Location.Coordinate.Latitude = (b & 0x03ffffffff000000) >> 24
  959. info.Location.Coordinate.LongitudeResolution = uint8(o.Info[5]&0xfc) >> 2
  960. b = binary.BigEndian.Uint64(o.Info[5:13])
  961. info.Location.Coordinate.Longitude = (b & 0x03ffffffff000000) >> 24
  962. info.Location.Coordinate.AltitudeType = uint8((o.Info[10] & 0x30) >> 4)
  963. b1 := binary.BigEndian.Uint16(o.Info[10:12])
  964. info.Location.Coordinate.AltitudeResolution = (b1 & 0xfc0) >> 6
  965. b2 := binary.BigEndian.Uint32(o.Info[11:15])
  966. info.Location.Coordinate.Altitude = b2 & 0x3fffffff
  967. info.Location.Coordinate.Datum = uint8(o.Info[15])
  968. case LLDPLocationFormatAddress:
  969. if err = checkLLDPOrgSpecificLen(o, 3); err != nil {
  970. return
  971. }
  972. //ll := uint8(o.Info[0])
  973. info.Location.Address.What = LLDPLocationAddressWhat(o.Info[1])
  974. info.Location.Address.CountryCode = string(o.Info[2:4])
  975. data := o.Info[4:]
  976. for len(data) > 1 {
  977. aType := LLDPLocationAddressType(data[0])
  978. aLen := int(data[1])
  979. if len(data) >= aLen+2 {
  980. info.Location.Address.AddressLines = append(info.Location.Address.AddressLines, LLDPLocationAddressLine{aType, string(data[2 : aLen+2])})
  981. data = data[aLen+2:]
  982. } else {
  983. break
  984. }
  985. }
  986. case LLDPLocationFormatECS:
  987. info.Location.ECS.ELIN = string(o.Info)
  988. }
  989. case LLDPMediaTypePower:
  990. if err = checkLLDPOrgSpecificLen(o, 3); err != nil {
  991. return
  992. }
  993. info.PowerViaMDI.Type = LLDPPowerType((o.Info[0] & 0xc0) >> 6)
  994. info.PowerViaMDI.Source = LLDPPowerSource((o.Info[0] & 0x30) >> 4)
  995. if info.PowerViaMDI.Type == 1 || info.PowerViaMDI.Type == 3 {
  996. info.PowerViaMDI.Source += 128 // For Stringify purposes
  997. }
  998. info.PowerViaMDI.Priority = LLDPPowerPriority(o.Info[0] & 0x0f)
  999. info.PowerViaMDI.Value = binary.BigEndian.Uint16(o.Info[1:3]) * 100 // 0 to 102.3 w, 0.1W increments
  1000. case LLDPMediaTypeHardware:
  1001. info.HardwareRevision = string(o.Info)
  1002. case LLDPMediaTypeFirmware:
  1003. info.FirmwareRevision = string(o.Info)
  1004. case LLDPMediaTypeSoftware:
  1005. info.SoftwareRevision = string(o.Info)
  1006. case LLDPMediaTypeSerial:
  1007. info.SerialNumber = string(o.Info)
  1008. case LLDPMediaTypeManufacturer:
  1009. info.Manufacturer = string(o.Info)
  1010. case LLDPMediaTypeModel:
  1011. info.Model = string(o.Info)
  1012. case LLDPMediaTypeAssetID:
  1013. info.AssetID = string(o.Info)
  1014. }
  1015. }
  1016. return
  1017. }
  1018. func (l *LinkLayerDiscoveryInfo) DecodeCisco2() (info LLDPInfoCisco2, err error) {
  1019. for _, o := range l.OrgTLVs {
  1020. if o.OUI != IEEEOUICisco2 {
  1021. continue
  1022. }
  1023. switch LLDPCisco2Subtype(o.SubType) {
  1024. case LLDPCisco2PowerViaMDI:
  1025. if err = checkLLDPOrgSpecificLen(o, 1); err != nil {
  1026. return
  1027. }
  1028. info.PSEFourWirePoESupported = (o.Info[0] & LLDPCiscoPSESupport) > 0
  1029. info.PDSparePairArchitectureShared = (o.Info[0] & LLDPCiscoArchShared) > 0
  1030. info.PDRequestSparePairPoEOn = (o.Info[0] & LLDPCiscoPDSparePair) > 0
  1031. info.PSESparePairPoEOn = (o.Info[0] & LLDPCiscoPSESparePair) > 0
  1032. }
  1033. }
  1034. return
  1035. }
  1036. func (l *LinkLayerDiscoveryInfo) DecodeProfinet() (info LLDPInfoProfinet, err error) {
  1037. for _, o := range l.OrgTLVs {
  1038. if o.OUI != IEEEOUIProfinet {
  1039. continue
  1040. }
  1041. switch LLDPProfinetSubtype(o.SubType) {
  1042. case LLDPProfinetPNIODelay:
  1043. if err = checkLLDPOrgSpecificLen(o, 20); err != nil {
  1044. return
  1045. }
  1046. info.PNIODelay.RXLocal = binary.BigEndian.Uint32(o.Info[0:4])
  1047. info.PNIODelay.RXRemote = binary.BigEndian.Uint32(o.Info[4:8])
  1048. info.PNIODelay.TXLocal = binary.BigEndian.Uint32(o.Info[8:12])
  1049. info.PNIODelay.TXRemote = binary.BigEndian.Uint32(o.Info[12:16])
  1050. info.PNIODelay.CableLocal = binary.BigEndian.Uint32(o.Info[16:20])
  1051. case LLDPProfinetPNIOPortStatus:
  1052. if err = checkLLDPOrgSpecificLen(o, 4); err != nil {
  1053. return
  1054. }
  1055. info.PNIOPortStatus.Class2 = binary.BigEndian.Uint16(o.Info[0:2])
  1056. info.PNIOPortStatus.Class3 = binary.BigEndian.Uint16(o.Info[2:4])
  1057. case LLDPProfinetPNIOMRPPortStatus:
  1058. if err = checkLLDPOrgSpecificLen(o, 18); err != nil {
  1059. return
  1060. }
  1061. info.PNIOMRPPortStatus.UUID = o.Info[0:16]
  1062. info.PNIOMRPPortStatus.Status = binary.BigEndian.Uint16(o.Info[16:18])
  1063. case LLDPProfinetPNIOChassisMAC:
  1064. if err = checkLLDPOrgSpecificLen(o, 6); err != nil {
  1065. return
  1066. }
  1067. info.ChassisMAC = o.Info[0:6]
  1068. case LLDPProfinetPNIOPTCPStatus:
  1069. if err = checkLLDPOrgSpecificLen(o, 54); err != nil {
  1070. return
  1071. }
  1072. info.PNIOPTCPStatus.MasterAddress = o.Info[0:6]
  1073. info.PNIOPTCPStatus.SubdomainUUID = o.Info[6:22]
  1074. info.PNIOPTCPStatus.IRDataUUID = o.Info[22:38]
  1075. b := binary.BigEndian.Uint32(o.Info[38:42])
  1076. info.PNIOPTCPStatus.PeriodValid = (b & 0x80000000) > 0
  1077. info.PNIOPTCPStatus.PeriodLength = b & 0x7fffffff
  1078. b = binary.BigEndian.Uint32(o.Info[42:46])
  1079. info.PNIOPTCPStatus.RedPeriodValid = (b & 0x80000000) > 0
  1080. info.PNIOPTCPStatus.RedPeriodBegin = b & 0x7fffffff
  1081. b = binary.BigEndian.Uint32(o.Info[46:50])
  1082. info.PNIOPTCPStatus.OrangePeriodValid = (b & 0x80000000) > 0
  1083. info.PNIOPTCPStatus.OrangePeriodBegin = b & 0x7fffffff
  1084. b = binary.BigEndian.Uint32(o.Info[50:54])
  1085. info.PNIOPTCPStatus.GreenPeriodValid = (b & 0x80000000) > 0
  1086. info.PNIOPTCPStatus.GreenPeriodBegin = b & 0x7fffffff
  1087. }
  1088. }
  1089. return
  1090. }
  1091. // LayerType returns gopacket.LayerTypeLinkLayerDiscoveryInfo.
  1092. func (c *LinkLayerDiscoveryInfo) LayerType() gopacket.LayerType {
  1093. return LayerTypeLinkLayerDiscoveryInfo
  1094. }
  1095. func getCapabilities(v uint16) (c LLDPCapabilities) {
  1096. c.Other = (v&LLDPCapsOther > 0)
  1097. c.Repeater = (v&LLDPCapsRepeater > 0)
  1098. c.Bridge = (v&LLDPCapsBridge > 0)
  1099. c.WLANAP = (v&LLDPCapsWLANAP > 0)
  1100. c.Router = (v&LLDPCapsRouter > 0)
  1101. c.Phone = (v&LLDPCapsPhone > 0)
  1102. c.DocSis = (v&LLDPCapsDocSis > 0)
  1103. c.StationOnly = (v&LLDPCapsStationOnly > 0)
  1104. c.CVLAN = (v&LLDPCapsCVLAN > 0)
  1105. c.SVLAN = (v&LLDPCapsSVLAN > 0)
  1106. c.TMPR = (v&LLDPCapsTmpr > 0)
  1107. return
  1108. }
  1109. func getEVBCapabilities(v uint16) (c LLDPEVBCapabilities) {
  1110. c.StandardBridging = (v & LLDPEVBCapsSTD) > 0
  1111. c.StandardBridging = (v & LLDPEVBCapsSTD) > 0
  1112. c.ReflectiveRelay = (v & LLDPEVBCapsRR) > 0
  1113. c.RetransmissionTimerExponent = (v & LLDPEVBCapsRTE) > 0
  1114. c.EdgeControlProtocol = (v & LLDPEVBCapsECP) > 0
  1115. c.VSIDiscoveryProtocol = (v & LLDPEVBCapsVDP) > 0
  1116. return
  1117. }
  1118. func (t LLDPTLVType) String() (s string) {
  1119. switch t {
  1120. case LLDPTLVEnd:
  1121. s = "TLV End"
  1122. case LLDPTLVChassisID:
  1123. s = "Chassis ID"
  1124. case LLDPTLVPortID:
  1125. s = "Port ID"
  1126. case LLDPTLVTTL:
  1127. s = "TTL"
  1128. case LLDPTLVPortDescription:
  1129. s = "Port Description"
  1130. case LLDPTLVSysName:
  1131. s = "System Name"
  1132. case LLDPTLVSysDescription:
  1133. s = "System Description"
  1134. case LLDPTLVSysCapabilities:
  1135. s = "System Capabilities"
  1136. case LLDPTLVMgmtAddress:
  1137. s = "Management Address"
  1138. case LLDPTLVOrgSpecific:
  1139. s = "Organisation Specific"
  1140. default:
  1141. s = "Unknown"
  1142. }
  1143. return
  1144. }
  1145. func (t LLDPChassisIDSubType) String() (s string) {
  1146. switch t {
  1147. case LLDPChassisIDSubTypeReserved:
  1148. s = "Reserved"
  1149. case LLDPChassisIDSubTypeChassisComp:
  1150. s = "Chassis Component"
  1151. case LLDPChassisIDSubtypeIfaceAlias:
  1152. s = "Interface Alias"
  1153. case LLDPChassisIDSubTypePortComp:
  1154. s = "Port Component"
  1155. case LLDPChassisIDSubTypeMACAddr:
  1156. s = "MAC Address"
  1157. case LLDPChassisIDSubTypeNetworkAddr:
  1158. s = "Network Address"
  1159. case LLDPChassisIDSubtypeIfaceName:
  1160. s = "Interface Name"
  1161. case LLDPChassisIDSubTypeLocal:
  1162. s = "Local"
  1163. default:
  1164. s = "Unknown"
  1165. }
  1166. return
  1167. }
  1168. func (t LLDPPortIDSubType) String() (s string) {
  1169. switch t {
  1170. case LLDPPortIDSubtypeReserved:
  1171. s = "Reserved"
  1172. case LLDPPortIDSubtypeIfaceAlias:
  1173. s = "Interface Alias"
  1174. case LLDPPortIDSubtypePortComp:
  1175. s = "Port Component"
  1176. case LLDPPortIDSubtypeMACAddr:
  1177. s = "MAC Address"
  1178. case LLDPPortIDSubtypeNetworkAddr:
  1179. s = "Network Address"
  1180. case LLDPPortIDSubtypeIfaceName:
  1181. s = "Interface Name"
  1182. case LLDPPortIDSubtypeAgentCircuitID:
  1183. s = "Agent Circuit ID"
  1184. case LLDPPortIDSubtypeLocal:
  1185. s = "Local"
  1186. default:
  1187. s = "Unknown"
  1188. }
  1189. return
  1190. }
  1191. func (t IANAAddressFamily) String() (s string) {
  1192. switch t {
  1193. case IANAAddressFamilyReserved:
  1194. s = "Reserved"
  1195. case IANAAddressFamilyIPV4:
  1196. s = "IPv4"
  1197. case IANAAddressFamilyIPV6:
  1198. s = "IPv6"
  1199. case IANAAddressFamilyNSAP:
  1200. s = "NSAP"
  1201. case IANAAddressFamilyHDLC:
  1202. s = "HDLC"
  1203. case IANAAddressFamilyBBN1822:
  1204. s = "BBN 1822"
  1205. case IANAAddressFamily802:
  1206. s = "802 media plus Ethernet 'canonical format'"
  1207. case IANAAddressFamilyE163:
  1208. s = "E.163"
  1209. case IANAAddressFamilyE164:
  1210. s = "E.164 (SMDS, Frame Relay, ATM)"
  1211. case IANAAddressFamilyF69:
  1212. s = "F.69 (Telex)"
  1213. case IANAAddressFamilyX121:
  1214. s = "X.121, X.25, Frame Relay"
  1215. case IANAAddressFamilyIPX:
  1216. s = "IPX"
  1217. case IANAAddressFamilyAtalk:
  1218. s = "Appletalk"
  1219. case IANAAddressFamilyDecnet:
  1220. s = "Decnet IV"
  1221. case IANAAddressFamilyBanyan:
  1222. s = "Banyan Vines"
  1223. case IANAAddressFamilyE164NSAP:
  1224. s = "E.164 with NSAP format subaddress"
  1225. case IANAAddressFamilyDNS:
  1226. s = "DNS"
  1227. case IANAAddressFamilyDistname:
  1228. s = "Distinguished Name"
  1229. case IANAAddressFamilyASNumber:
  1230. s = "AS Number"
  1231. case IANAAddressFamilyXTPIPV4:
  1232. s = "XTP over IP version 4"
  1233. case IANAAddressFamilyXTPIPV6:
  1234. s = "XTP over IP version 6"
  1235. case IANAAddressFamilyXTP:
  1236. s = "XTP native mode XTP"
  1237. case IANAAddressFamilyFcWWPN:
  1238. s = "Fibre Channel World-Wide Port Name"
  1239. case IANAAddressFamilyFcWWNN:
  1240. s = "Fibre Channel World-Wide Node Name"
  1241. case IANAAddressFamilyGWID:
  1242. s = "GWID"
  1243. case IANAAddressFamilyL2VPN:
  1244. s = "AFI for Layer 2 VPN"
  1245. default:
  1246. s = "Unknown"
  1247. }
  1248. return
  1249. }
  1250. func (t LLDPInterfaceSubtype) String() (s string) {
  1251. switch t {
  1252. case LLDPInterfaceSubtypeUnknown:
  1253. s = "Unknown"
  1254. case LLDPInterfaceSubtypeifIndex:
  1255. s = "IfIndex"
  1256. case LLDPInterfaceSubtypeSysPort:
  1257. s = "System Port Number"
  1258. default:
  1259. s = "Unknown"
  1260. }
  1261. return
  1262. }
  1263. func (t LLDPPowerType) String() (s string) {
  1264. switch t {
  1265. case 0:
  1266. s = "Type 2 PSE Device"
  1267. case 1:
  1268. s = "Type 2 PD Device"
  1269. case 2:
  1270. s = "Type 1 PSE Device"
  1271. case 3:
  1272. s = "Type 1 PD Device"
  1273. default:
  1274. s = "Unknown"
  1275. }
  1276. return
  1277. }
  1278. func (t LLDPPowerSource) String() (s string) {
  1279. switch t {
  1280. // PD Device
  1281. case 0:
  1282. s = "Unknown"
  1283. case 1:
  1284. s = "PSE"
  1285. case 2:
  1286. s = "Local"
  1287. case 3:
  1288. s = "PSE and Local"
  1289. // PSE Device (Actual value + 128)
  1290. case 128:
  1291. s = "Unknown"
  1292. case 129:
  1293. s = "Primary Power Source"
  1294. case 130:
  1295. s = "Backup Power Source"
  1296. default:
  1297. s = "Unknown"
  1298. }
  1299. return
  1300. }
  1301. func (t LLDPPowerPriority) String() (s string) {
  1302. switch t {
  1303. case 0:
  1304. s = "Unknown"
  1305. case 1:
  1306. s = "Critical"
  1307. case 2:
  1308. s = "High"
  1309. case 3:
  1310. s = "Low"
  1311. default:
  1312. s = "Unknown"
  1313. }
  1314. return
  1315. }
  1316. func (t LLDPMediaSubtype) String() (s string) {
  1317. switch t {
  1318. case LLDPMediaTypeCapabilities:
  1319. s = "Media Capabilities "
  1320. case LLDPMediaTypeNetwork:
  1321. s = "Network Policy"
  1322. case LLDPMediaTypeLocation:
  1323. s = "Location Identification"
  1324. case LLDPMediaTypePower:
  1325. s = "Extended Power-via-MDI"
  1326. case LLDPMediaTypeHardware:
  1327. s = "Hardware Revision"
  1328. case LLDPMediaTypeFirmware:
  1329. s = "Firmware Revision"
  1330. case LLDPMediaTypeSoftware:
  1331. s = "Software Revision"
  1332. case LLDPMediaTypeSerial:
  1333. s = "Serial Number"
  1334. case LLDPMediaTypeManufacturer:
  1335. s = "Manufacturer"
  1336. case LLDPMediaTypeModel:
  1337. s = "Model"
  1338. case LLDPMediaTypeAssetID:
  1339. s = "Asset ID"
  1340. default:
  1341. s = "Unknown"
  1342. }
  1343. return
  1344. }
  1345. func (t LLDPMediaClass) String() (s string) {
  1346. switch t {
  1347. case LLDPMediaClassUndefined:
  1348. s = "Undefined"
  1349. case LLDPMediaClassEndpointI:
  1350. s = "Endpoint Class I"
  1351. case LLDPMediaClassEndpointII:
  1352. s = "Endpoint Class II"
  1353. case LLDPMediaClassEndpointIII:
  1354. s = "Endpoint Class III"
  1355. case LLDPMediaClassNetwork:
  1356. s = "Network connectivity "
  1357. default:
  1358. s = "Unknown"
  1359. }
  1360. return
  1361. }
  1362. func (t LLDPApplicationType) String() (s string) {
  1363. switch t {
  1364. case LLDPAppTypeReserved:
  1365. s = "Reserved"
  1366. case LLDPAppTypeVoice:
  1367. s = "Voice"
  1368. case LLDPappTypeVoiceSignaling:
  1369. s = "Voice Signaling"
  1370. case LLDPappTypeGuestVoice:
  1371. s = "Guest Voice"
  1372. case LLDPappTypeGuestVoiceSignaling:
  1373. s = "Guest Voice Signaling"
  1374. case LLDPappTypeSoftphoneVoice:
  1375. s = "Softphone Voice"
  1376. case LLDPappTypeVideoConferencing:
  1377. s = "Video Conferencing"
  1378. case LLDPappTypeStreamingVideo:
  1379. s = "Streaming Video"
  1380. case LLDPappTypeVideoSignaling:
  1381. s = "Video Signaling"
  1382. default:
  1383. s = "Unknown"
  1384. }
  1385. return
  1386. }
  1387. func (t LLDPLocationFormat) String() (s string) {
  1388. switch t {
  1389. case LLDPLocationFormatInvalid:
  1390. s = "Invalid"
  1391. case LLDPLocationFormatCoordinate:
  1392. s = "Coordinate-based LCI"
  1393. case LLDPLocationFormatAddress:
  1394. s = "Address-based LCO"
  1395. case LLDPLocationFormatECS:
  1396. s = "ECS ELIN"
  1397. default:
  1398. s = "Unknown"
  1399. }
  1400. return
  1401. }
  1402. func (t LLDPLocationAddressType) String() (s string) {
  1403. switch t {
  1404. case LLDPLocationAddressTypeLanguage:
  1405. s = "Language"
  1406. case LLDPLocationAddressTypeNational:
  1407. s = "National subdivisions (province, state, etc)"
  1408. case LLDPLocationAddressTypeCounty:
  1409. s = "County, parish, district"
  1410. case LLDPLocationAddressTypeCity:
  1411. s = "City, township"
  1412. case LLDPLocationAddressTypeCityDivision:
  1413. s = "City division, borough, ward"
  1414. case LLDPLocationAddressTypeNeighborhood:
  1415. s = "Neighborhood, block"
  1416. case LLDPLocationAddressTypeStreet:
  1417. s = "Street"
  1418. case LLDPLocationAddressTypeLeadingStreet:
  1419. s = "Leading street direction"
  1420. case LLDPLocationAddressTypeTrailingStreet:
  1421. s = "Trailing street suffix"
  1422. case LLDPLocationAddressTypeStreetSuffix:
  1423. s = "Street suffix"
  1424. case LLDPLocationAddressTypeHouseNum:
  1425. s = "House number"
  1426. case LLDPLocationAddressTypeHouseSuffix:
  1427. s = "House number suffix"
  1428. case LLDPLocationAddressTypeLandmark:
  1429. s = "Landmark or vanity address"
  1430. case LLDPLocationAddressTypeAdditional:
  1431. s = "Additional location information"
  1432. case LLDPLocationAddressTypeName:
  1433. s = "Name"
  1434. case LLDPLocationAddressTypePostal:
  1435. s = "Postal/ZIP code"
  1436. case LLDPLocationAddressTypeBuilding:
  1437. s = "Building"
  1438. case LLDPLocationAddressTypeUnit:
  1439. s = "Unit"
  1440. case LLDPLocationAddressTypeFloor:
  1441. s = "Floor"
  1442. case LLDPLocationAddressTypeRoom:
  1443. s = "Room number"
  1444. case LLDPLocationAddressTypePlace:
  1445. s = "Place type"
  1446. case LLDPLocationAddressTypeScript:
  1447. s = "Script"
  1448. default:
  1449. s = "Unknown"
  1450. }
  1451. return
  1452. }
  1453. func checkLLDPTLVLen(v LinkLayerDiscoveryValue, l int) (err error) {
  1454. if len(v.Value) < l {
  1455. err = fmt.Errorf("Invalid TLV %v length %d (wanted mimimum %v", v.Type, len(v.Value), l)
  1456. }
  1457. return
  1458. }
  1459. func checkLLDPOrgSpecificLen(o LLDPOrgSpecificTLV, l int) (err error) {
  1460. if len(o.Info) < l {
  1461. err = fmt.Errorf("Invalid Org Specific TLV %v length %d (wanted minimum %v)", o.SubType, len(o.Info), l)
  1462. }
  1463. return
  1464. }