aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/google/gopacket/layers/cdp.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/google/gopacket/layers/cdp.go')
-rw-r--r--vendor/github.com/google/gopacket/layers/cdp.go651
1 files changed, 651 insertions, 0 deletions
diff --git a/vendor/github.com/google/gopacket/layers/cdp.go b/vendor/github.com/google/gopacket/layers/cdp.go
new file mode 100644
index 0000000..d67203e
--- /dev/null
+++ b/vendor/github.com/google/gopacket/layers/cdp.go
@@ -0,0 +1,651 @@
+// Copyright 2012 Google, Inc. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree.
+
+// Enum types courtesy of...
+// http://search.cpan.org/~mchapman/Net-CDP-0.09/lib/Net/CDP.pm
+// https://code.google.com/p/ladvd/
+// http://anonsvn.wireshark.org/viewvc/releases/wireshark-1.8.6/epan/dissectors/packet-cdp.c
+
+package layers
+
+import (
+ "encoding/binary"
+ "fmt"
+ "net"
+
+ "github.com/google/gopacket"
+)
+
+// CDPTLVType is the type of each TLV value in a CiscoDiscovery packet.
+type CDPTLVType uint16
+
+// CDPTLVType values.
+const (
+ CDPTLVDevID CDPTLVType = 0x0001
+ CDPTLVAddress CDPTLVType = 0x0002
+ CDPTLVPortID CDPTLVType = 0x0003
+ CDPTLVCapabilities CDPTLVType = 0x0004
+ CDPTLVVersion CDPTLVType = 0x0005
+ CDPTLVPlatform CDPTLVType = 0x0006
+ CDPTLVIPPrefix CDPTLVType = 0x0007
+ CDPTLVHello CDPTLVType = 0x0008
+ CDPTLVVTPDomain CDPTLVType = 0x0009
+ CDPTLVNativeVLAN CDPTLVType = 0x000a
+ CDPTLVFullDuplex CDPTLVType = 0x000b
+ CDPTLVVLANReply CDPTLVType = 0x000e
+ CDPTLVVLANQuery CDPTLVType = 0x000f
+ CDPTLVPower CDPTLVType = 0x0010
+ CDPTLVMTU CDPTLVType = 0x0011
+ CDPTLVExtendedTrust CDPTLVType = 0x0012
+ CDPTLVUntrustedCOS CDPTLVType = 0x0013
+ CDPTLVSysName CDPTLVType = 0x0014
+ CDPTLVSysOID CDPTLVType = 0x0015
+ CDPTLVMgmtAddresses CDPTLVType = 0x0016
+ CDPTLVLocation CDPTLVType = 0x0017
+ CDPTLVExternalPortID CDPTLVType = 0x0018
+ CDPTLVPowerRequested CDPTLVType = 0x0019
+ CDPTLVPowerAvailable CDPTLVType = 0x001a
+ CDPTLVPortUnidirectional CDPTLVType = 0x001b
+ CDPTLVEnergyWise CDPTLVType = 0x001d
+ CDPTLVSparePairPOE CDPTLVType = 0x001f
+)
+
+// CiscoDiscoveryValue is a TLV value inside a CiscoDiscovery packet layer.
+type CiscoDiscoveryValue struct {
+ Type CDPTLVType
+ Length uint16
+ Value []byte
+}
+
+// CiscoDiscovery is a packet layer containing the Cisco Discovery Protocol.
+// See http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm#31885
+type CiscoDiscovery struct {
+ BaseLayer
+ Version byte
+ TTL byte
+ Checksum uint16
+ Values []CiscoDiscoveryValue
+}
+
+// CDPCapability is the set of capabilities advertised by a CDP device.
+type CDPCapability uint32
+
+// CDPCapability values.
+const (
+ CDPCapMaskRouter CDPCapability = 0x0001
+ CDPCapMaskTBBridge CDPCapability = 0x0002
+ CDPCapMaskSPBridge CDPCapability = 0x0004
+ CDPCapMaskSwitch CDPCapability = 0x0008
+ CDPCapMaskHost CDPCapability = 0x0010
+ CDPCapMaskIGMPFilter CDPCapability = 0x0020
+ CDPCapMaskRepeater CDPCapability = 0x0040
+ CDPCapMaskPhone CDPCapability = 0x0080
+ CDPCapMaskRemote CDPCapability = 0x0100
+)
+
+// CDPCapabilities represents the capabilities of a device
+type CDPCapabilities struct {
+ L3Router bool
+ TBBridge bool
+ SPBridge bool
+ L2Switch bool
+ IsHost bool
+ IGMPFilter bool
+ L1Repeater bool
+ IsPhone bool
+ RemotelyManaged bool
+}
+
+// CDP Power-over-Ethernet values.
+const (
+ CDPPoEFourWire byte = 0x01
+ CDPPoEPDArch byte = 0x02
+ CDPPoEPDRequest byte = 0x04
+ CDPPoEPSE byte = 0x08
+)
+
+// CDPSparePairPoE provides information on PoE.
+type CDPSparePairPoE struct {
+ PSEFourWire bool // Supported / Not supported
+ PDArchShared bool // Shared / Independent
+ PDRequestOn bool // On / Off
+ PSEOn bool // On / Off
+}
+
+// CDPVLANDialogue encapsulates a VLAN Query/Reply
+type CDPVLANDialogue struct {
+ ID uint8
+ VLAN uint16
+}
+
+// CDPPowerDialogue encapsulates a Power Query/Reply
+type CDPPowerDialogue struct {
+ ID uint16
+ MgmtID uint16
+ Values []uint32
+}
+
+// CDPLocation provides location information for a CDP device.
+type CDPLocation struct {
+ Type uint8 // Undocumented
+ Location string
+}
+
+// CDPHello is a Cisco Hello message (undocumented, hence the "Unknown" fields)
+type CDPHello struct {
+ OUI []byte
+ ProtocolID uint16
+ ClusterMaster net.IP
+ Unknown1 net.IP
+ Version byte
+ SubVersion byte
+ Status byte
+ Unknown2 byte
+ ClusterCommander net.HardwareAddr
+ SwitchMAC net.HardwareAddr
+ Unknown3 byte
+ ManagementVLAN uint16
+}
+
+// CDPEnergyWiseSubtype is used within CDP to define TLV values.
+type CDPEnergyWiseSubtype uint32
+
+// CDPEnergyWiseSubtype values.
+const (
+ CDPEnergyWiseRole CDPEnergyWiseSubtype = 0x00000007
+ CDPEnergyWiseDomain CDPEnergyWiseSubtype = 0x00000008
+ CDPEnergyWiseName CDPEnergyWiseSubtype = 0x00000009
+ CDPEnergyWiseReplyTo CDPEnergyWiseSubtype = 0x00000017
+)
+
+// CDPEnergyWise is used by CDP to monitor and control power usage.
+type CDPEnergyWise struct {
+ EncryptedData []byte
+ Unknown1 uint32
+ SequenceNumber uint32
+ ModelNumber string
+ Unknown2 uint16
+ HardwareID string
+ SerialNum string
+ Unknown3 []byte
+ Role string
+ Domain string
+ Name string
+ ReplyUnknown1 []byte
+ ReplyPort []byte
+ ReplyAddress []byte
+ ReplyUnknown2 []byte
+ ReplyUnknown3 []byte
+}
+
+// CiscoDiscoveryInfo represents the decoded details for a set of CiscoDiscoveryValues
+type CiscoDiscoveryInfo struct {
+ BaseLayer
+ CDPHello
+ DeviceID string
+ Addresses []net.IP
+ PortID string
+ Capabilities CDPCapabilities
+ Version string
+ Platform string
+ IPPrefixes []net.IPNet
+ VTPDomain string
+ NativeVLAN uint16
+ FullDuplex bool
+ VLANReply CDPVLANDialogue
+ VLANQuery CDPVLANDialogue
+ PowerConsumption uint16
+ MTU uint32
+ ExtendedTrust uint8
+ UntrustedCOS uint8
+ SysName string
+ SysOID string
+ MgmtAddresses []net.IP
+ Location CDPLocation
+ PowerRequest CDPPowerDialogue
+ PowerAvailable CDPPowerDialogue
+ SparePairPoe CDPSparePairPoE
+ EnergyWise CDPEnergyWise
+ Unknown []CiscoDiscoveryValue
+}
+
+// LayerType returns gopacket.LayerTypeCiscoDiscovery.
+func (c *CiscoDiscovery) LayerType() gopacket.LayerType {
+ return LayerTypeCiscoDiscovery
+}
+
+func decodeCiscoDiscovery(data []byte, p gopacket.PacketBuilder) error {
+ c := &CiscoDiscovery{
+ Version: data[0],
+ TTL: data[1],
+ Checksum: binary.BigEndian.Uint16(data[2:4]),
+ }
+ if c.Version != 1 && c.Version != 2 {
+ return fmt.Errorf("Invalid CiscoDiscovery version number %d", c.Version)
+ }
+ var err error
+ c.Values, err = decodeCiscoDiscoveryTLVs(data[4:])
+ if err != nil {
+ return err
+ }
+ c.Contents = data[0:4]
+ c.Payload = data[4:]
+ p.AddLayer(c)
+ return p.NextDecoder(gopacket.DecodeFunc(decodeCiscoDiscoveryInfo))
+}
+
+// LayerType returns gopacket.LayerTypeCiscoDiscoveryInfo.
+func (c *CiscoDiscoveryInfo) LayerType() gopacket.LayerType {
+ return LayerTypeCiscoDiscoveryInfo
+}
+
+func decodeCiscoDiscoveryTLVs(data []byte) (values []CiscoDiscoveryValue, err error) {
+ for len(data) > 0 {
+ val := CiscoDiscoveryValue{
+ Type: CDPTLVType(binary.BigEndian.Uint16(data[:2])),
+ Length: binary.BigEndian.Uint16(data[2:4]),
+ }
+ if val.Length < 4 {
+ err = fmt.Errorf("Invalid CiscoDiscovery value length %d", val.Length)
+ break
+ }
+ val.Value = data[4:val.Length]
+ values = append(values, val)
+ data = data[val.Length:]
+ }
+ return
+}
+
+func decodeCiscoDiscoveryInfo(data []byte, p gopacket.PacketBuilder) error {
+ var err error
+ info := &CiscoDiscoveryInfo{BaseLayer: BaseLayer{Contents: data}}
+ p.AddLayer(info)
+ values, err := decodeCiscoDiscoveryTLVs(data)
+ if err != nil { // Unlikely, as parent decode will fail, but better safe...
+ return err
+ }
+ for _, val := range values {
+ switch val.Type {
+ case CDPTLVDevID:
+ info.DeviceID = string(val.Value)
+ case CDPTLVAddress:
+ if err = checkCDPTLVLen(val, 4); err != nil {
+ return err
+ }
+ info.Addresses, err = decodeAddresses(val.Value)
+ if err != nil {
+ return err
+ }
+ case CDPTLVPortID:
+ info.PortID = string(val.Value)
+ case CDPTLVCapabilities:
+ if err = checkCDPTLVLen(val, 4); err != nil {
+ return err
+ }
+ val := CDPCapability(binary.BigEndian.Uint32(val.Value[0:4]))
+ info.Capabilities.L3Router = (val&CDPCapMaskRouter > 0)
+ info.Capabilities.TBBridge = (val&CDPCapMaskTBBridge > 0)
+ info.Capabilities.SPBridge = (val&CDPCapMaskSPBridge > 0)
+ info.Capabilities.L2Switch = (val&CDPCapMaskSwitch > 0)
+ info.Capabilities.IsHost = (val&CDPCapMaskHost > 0)
+ info.Capabilities.IGMPFilter = (val&CDPCapMaskIGMPFilter > 0)
+ info.Capabilities.L1Repeater = (val&CDPCapMaskRepeater > 0)
+ info.Capabilities.IsPhone = (val&CDPCapMaskPhone > 0)
+ info.Capabilities.RemotelyManaged = (val&CDPCapMaskRemote > 0)
+ case CDPTLVVersion:
+ info.Version = string(val.Value)
+ case CDPTLVPlatform:
+ info.Platform = string(val.Value)
+ case CDPTLVIPPrefix:
+ v := val.Value
+ l := len(v)
+ if l%5 == 0 && l >= 5 {
+ for len(v) > 0 {
+ _, ipnet, _ := net.ParseCIDR(fmt.Sprintf("%d.%d.%d.%d/%d", v[0], v[1], v[2], v[3], v[4]))
+ info.IPPrefixes = append(info.IPPrefixes, *ipnet)
+ v = v[5:]
+ }
+ } else {
+ return fmt.Errorf("Invalid TLV %v length %d", val.Type, len(val.Value))
+ }
+ case CDPTLVHello:
+ if err = checkCDPTLVLen(val, 32); err != nil {
+ return err
+ }
+ v := val.Value
+ info.CDPHello.OUI = v[0:3]
+ info.CDPHello.ProtocolID = binary.BigEndian.Uint16(v[3:5])
+ info.CDPHello.ClusterMaster = v[5:9]
+ info.CDPHello.Unknown1 = v[9:13]
+ info.CDPHello.Version = v[13]
+ info.CDPHello.SubVersion = v[14]
+ info.CDPHello.Status = v[15]
+ info.CDPHello.Unknown2 = v[16]
+ info.CDPHello.ClusterCommander = v[17:23]
+ info.CDPHello.SwitchMAC = v[23:29]
+ info.CDPHello.Unknown3 = v[29]
+ info.CDPHello.ManagementVLAN = binary.BigEndian.Uint16(v[30:32])
+ case CDPTLVVTPDomain:
+ info.VTPDomain = string(val.Value)
+ case CDPTLVNativeVLAN:
+ if err = checkCDPTLVLen(val, 2); err != nil {
+ return err
+ }
+ info.NativeVLAN = binary.BigEndian.Uint16(val.Value[0:2])
+ case CDPTLVFullDuplex:
+ if err = checkCDPTLVLen(val, 1); err != nil {
+ return err
+ }
+ info.FullDuplex = (val.Value[0] == 1)
+ case CDPTLVVLANReply:
+ if err = checkCDPTLVLen(val, 3); err != nil {
+ return err
+ }
+ info.VLANReply.ID = uint8(val.Value[0])
+ info.VLANReply.VLAN = binary.BigEndian.Uint16(val.Value[1:3])
+ case CDPTLVVLANQuery:
+ if err = checkCDPTLVLen(val, 3); err != nil {
+ return err
+ }
+ info.VLANQuery.ID = uint8(val.Value[0])
+ info.VLANQuery.VLAN = binary.BigEndian.Uint16(val.Value[1:3])
+ case CDPTLVPower:
+ if err = checkCDPTLVLen(val, 2); err != nil {
+ return err
+ }
+ info.PowerConsumption = binary.BigEndian.Uint16(val.Value[0:2])
+ case CDPTLVMTU:
+ if err = checkCDPTLVLen(val, 4); err != nil {
+ return err
+ }
+ info.MTU = binary.BigEndian.Uint32(val.Value[0:4])
+ case CDPTLVExtendedTrust:
+ if err = checkCDPTLVLen(val, 1); err != nil {
+ return err
+ }
+ info.ExtendedTrust = uint8(val.Value[0])
+ case CDPTLVUntrustedCOS:
+ if err = checkCDPTLVLen(val, 1); err != nil {
+ return err
+ }
+ info.UntrustedCOS = uint8(val.Value[0])
+ case CDPTLVSysName:
+ info.SysName = string(val.Value)
+ case CDPTLVSysOID:
+ info.SysOID = string(val.Value)
+ case CDPTLVMgmtAddresses:
+ if err = checkCDPTLVLen(val, 4); err != nil {
+ return err
+ }
+ info.MgmtAddresses, err = decodeAddresses(val.Value)
+ if err != nil {
+ return err
+ }
+ case CDPTLVLocation:
+ if err = checkCDPTLVLen(val, 2); err != nil {
+ return err
+ }
+ info.Location.Type = uint8(val.Value[0])
+ info.Location.Location = string(val.Value[1:])
+
+ // case CDPTLVLExternalPortID:
+ // Undocumented
+ case CDPTLVPowerRequested:
+ if err = checkCDPTLVLen(val, 4); err != nil {
+ return err
+ }
+ info.PowerRequest.ID = binary.BigEndian.Uint16(val.Value[0:2])
+ info.PowerRequest.MgmtID = binary.BigEndian.Uint16(val.Value[2:4])
+ for n := 4; n < len(val.Value); n += 4 {
+ info.PowerRequest.Values = append(info.PowerRequest.Values, binary.BigEndian.Uint32(val.Value[n:n+4]))
+ }
+ case CDPTLVPowerAvailable:
+ if err = checkCDPTLVLen(val, 4); err != nil {
+ return err
+ }
+ info.PowerAvailable.ID = binary.BigEndian.Uint16(val.Value[0:2])
+ info.PowerAvailable.MgmtID = binary.BigEndian.Uint16(val.Value[2:4])
+ for n := 4; n < len(val.Value); n += 4 {
+ info.PowerAvailable.Values = append(info.PowerAvailable.Values, binary.BigEndian.Uint32(val.Value[n:n+4]))
+ }
+ // case CDPTLVPortUnidirectional
+ // Undocumented
+ case CDPTLVEnergyWise:
+ if err = checkCDPTLVLen(val, 72); err != nil {
+ return err
+ }
+ info.EnergyWise.EncryptedData = val.Value[0:20]
+ info.EnergyWise.Unknown1 = binary.BigEndian.Uint32(val.Value[20:24])
+ info.EnergyWise.SequenceNumber = binary.BigEndian.Uint32(val.Value[24:28])
+ info.EnergyWise.ModelNumber = string(val.Value[28:44])
+ info.EnergyWise.Unknown2 = binary.BigEndian.Uint16(val.Value[44:46])
+ info.EnergyWise.HardwareID = string(val.Value[46:49])
+ info.EnergyWise.SerialNum = string(val.Value[49:60])
+ info.EnergyWise.Unknown3 = val.Value[60:68]
+ tlvLen := binary.BigEndian.Uint16(val.Value[68:70])
+ tlvNum := binary.BigEndian.Uint16(val.Value[70:72])
+ data := val.Value[72:]
+ if len(data) < int(tlvLen) {
+ return fmt.Errorf("Invalid TLV length %d vs %d", tlvLen, len(data))
+ }
+ numSeen := 0
+ for len(data) > 8 {
+ numSeen++
+ if numSeen > int(tlvNum) { // Too many TLV's ?
+ return fmt.Errorf("Too many TLV's - wanted %d, saw %d", tlvNum, numSeen)
+ }
+ tType := CDPEnergyWiseSubtype(binary.BigEndian.Uint32(data[0:4]))
+ tLen := int(binary.BigEndian.Uint32(data[4:8]))
+ if tLen > len(data)-8 {
+ return fmt.Errorf("Invalid TLV length %d vs %d", tLen, len(data)-8)
+ }
+ data = data[8:]
+ switch tType {
+ case CDPEnergyWiseRole:
+ info.EnergyWise.Role = string(data[:])
+ case CDPEnergyWiseDomain:
+ info.EnergyWise.Domain = string(data[:])
+ case CDPEnergyWiseName:
+ info.EnergyWise.Name = string(data[:])
+ case CDPEnergyWiseReplyTo:
+ if len(data) >= 18 {
+ info.EnergyWise.ReplyUnknown1 = data[0:2]
+ info.EnergyWise.ReplyPort = data[2:4]
+ info.EnergyWise.ReplyAddress = data[4:8]
+ info.EnergyWise.ReplyUnknown2 = data[8:10]
+ info.EnergyWise.ReplyUnknown3 = data[10:14]
+ }
+ }
+ data = data[tLen:]
+ }
+ case CDPTLVSparePairPOE:
+ if err = checkCDPTLVLen(val, 1); err != nil {
+ return err
+ }
+ v := val.Value[0]
+ info.SparePairPoe.PSEFourWire = (v&CDPPoEFourWire > 0)
+ info.SparePairPoe.PDArchShared = (v&CDPPoEPDArch > 0)
+ info.SparePairPoe.PDRequestOn = (v&CDPPoEPDRequest > 0)
+ info.SparePairPoe.PSEOn = (v&CDPPoEPSE > 0)
+ default:
+ info.Unknown = append(info.Unknown, val)
+ }
+ }
+ return nil
+}
+
+// CDP Protocol Types
+const (
+ CDPProtocolTypeNLPID byte = 1
+ CDPProtocolType802_2 byte = 2
+)
+
+// CDPAddressType is used to define TLV values within CDP addresses.
+type CDPAddressType uint64
+
+// CDP Address types.
+const (
+ CDPAddressTypeCLNP CDPAddressType = 0x81
+ CDPAddressTypeIPV4 CDPAddressType = 0xcc
+ CDPAddressTypeIPV6 CDPAddressType = 0xaaaa030000000800
+ CDPAddressTypeDECNET CDPAddressType = 0xaaaa030000006003
+ CDPAddressTypeAPPLETALK CDPAddressType = 0xaaaa03000000809b
+ CDPAddressTypeIPX CDPAddressType = 0xaaaa030000008137
+ CDPAddressTypeVINES CDPAddressType = 0xaaaa0300000080c4
+ CDPAddressTypeXNS CDPAddressType = 0xaaaa030000000600
+ CDPAddressTypeAPOLLO CDPAddressType = 0xaaaa030000008019
+)
+
+func decodeAddresses(v []byte) (addresses []net.IP, err error) {
+ numaddr := int(binary.BigEndian.Uint32(v[0:4]))
+ if numaddr < 1 {
+ return nil, fmt.Errorf("Invalid Address TLV number %d", numaddr)
+ }
+ v = v[4:]
+ if len(v) < numaddr*8 {
+ return nil, fmt.Errorf("Invalid Address TLV length %d", len(v))
+ }
+ for i := 0; i < numaddr; i++ {
+ prottype := v[0]
+ if prottype != CDPProtocolTypeNLPID && prottype != CDPProtocolType802_2 { // invalid protocol type
+ return nil, fmt.Errorf("Invalid Address Protocol %d", prottype)
+ }
+ protlen := int(v[1])
+ if (prottype == CDPProtocolTypeNLPID && protlen != 1) ||
+ (prottype == CDPProtocolType802_2 && protlen != 3 && protlen != 8) { // invalid length
+ return nil, fmt.Errorf("Invalid Address Protocol length %d", protlen)
+ }
+ plen := make([]byte, 8)
+ copy(plen[8-protlen:], v[2:2+protlen])
+ protocol := CDPAddressType(binary.BigEndian.Uint64(plen))
+ v = v[2+protlen:]
+ addrlen := binary.BigEndian.Uint16(v[0:2])
+ ab := v[2 : 2+addrlen]
+ if protocol == CDPAddressTypeIPV4 && addrlen == 4 {
+ addresses = append(addresses, net.IPv4(ab[0], ab[1], ab[2], ab[3]))
+ } else if protocol == CDPAddressTypeIPV6 && addrlen == 16 {
+ addresses = append(addresses, net.IP(ab))
+ } else {
+ // only handle IPV4 & IPV6 for now
+ }
+ v = v[2+addrlen:]
+ if len(v) < 8 {
+ break
+ }
+ }
+ return
+}
+
+func (t CDPTLVType) String() (s string) {
+ switch t {
+ case CDPTLVDevID:
+ s = "Device ID"
+ case CDPTLVAddress:
+ s = "Addresses"
+ case CDPTLVPortID:
+ s = "Port ID"
+ case CDPTLVCapabilities:
+ s = "Capabilities"
+ case CDPTLVVersion:
+ s = "Software Version"
+ case CDPTLVPlatform:
+ s = "Platform"
+ case CDPTLVIPPrefix:
+ s = "IP Prefix"
+ case CDPTLVHello:
+ s = "Protocol Hello"
+ case CDPTLVVTPDomain:
+ s = "VTP Management Domain"
+ case CDPTLVNativeVLAN:
+ s = "Native VLAN"
+ case CDPTLVFullDuplex:
+ s = "Full Duplex"
+ case CDPTLVVLANReply:
+ s = "VoIP VLAN Reply"
+ case CDPTLVVLANQuery:
+ s = "VLANQuery"
+ case CDPTLVPower:
+ s = "Power consumption"
+ case CDPTLVMTU:
+ s = "MTU"
+ case CDPTLVExtendedTrust:
+ s = "Extended Trust Bitmap"
+ case CDPTLVUntrustedCOS:
+ s = "Untrusted Port CoS"
+ case CDPTLVSysName:
+ s = "System Name"
+ case CDPTLVSysOID:
+ s = "System OID"
+ case CDPTLVMgmtAddresses:
+ s = "Management Addresses"
+ case CDPTLVLocation:
+ s = "Location"
+ case CDPTLVExternalPortID:
+ s = "External Port ID"
+ case CDPTLVPowerRequested:
+ s = "Power Requested"
+ case CDPTLVPowerAvailable:
+ s = "Power Available"
+ case CDPTLVPortUnidirectional:
+ s = "Port Unidirectional"
+ case CDPTLVEnergyWise:
+ s = "Energy Wise"
+ case CDPTLVSparePairPOE:
+ s = "Spare Pair POE"
+ default:
+ s = "Unknown"
+ }
+ return
+}
+
+func (a CDPAddressType) String() (s string) {
+ switch a {
+ case CDPAddressTypeCLNP:
+ s = "Connectionless Network Protocol"
+ case CDPAddressTypeIPV4:
+ s = "IPv4"
+ case CDPAddressTypeIPV6:
+ s = "IPv6"
+ case CDPAddressTypeDECNET:
+ s = "DECnet Phase IV"
+ case CDPAddressTypeAPPLETALK:
+ s = "Apple Talk"
+ case CDPAddressTypeIPX:
+ s = "Novell IPX"
+ case CDPAddressTypeVINES:
+ s = "Banyan VINES"
+ case CDPAddressTypeXNS:
+ s = "Xerox Network Systems"
+ case CDPAddressTypeAPOLLO:
+ s = "Apollo"
+ default:
+ s = "Unknown"
+ }
+ return
+}
+
+func (t CDPEnergyWiseSubtype) String() (s string) {
+ switch t {
+ case CDPEnergyWiseRole:
+ s = "Role"
+ case CDPEnergyWiseDomain:
+ s = "Domain"
+ case CDPEnergyWiseName:
+ s = "Name"
+ case CDPEnergyWiseReplyTo:
+ s = "ReplyTo"
+ default:
+ s = "Unknown"
+ }
+ return
+}
+
+func checkCDPTLVLen(v CiscoDiscoveryValue, l int) (err error) {
+ if len(v.Value) < l {
+ err = fmt.Errorf("Invalid TLV %v length %d", v.Type, len(v.Value))
+ }
+ return
+}