mirror of https://github.com/jetkvm/kvm.git
fix(ui): use source in LLDP neighbor key
This commit is contained in:
parent
8957a65cae
commit
15484f889e
|
|
@ -0,0 +1,131 @@
|
|||
package lldp
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/google/gopacket/layers"
|
||||
)
|
||||
|
||||
var (
|
||||
capabilityMap = map[string]uint16{
|
||||
"other": layers.LLDPCapsOther,
|
||||
"repeater": layers.LLDPCapsRepeater,
|
||||
"bridge": layers.LLDPCapsBridge,
|
||||
"wlanap": layers.LLDPCapsWLANAP,
|
||||
"router": layers.LLDPCapsRouter,
|
||||
"phone": layers.LLDPCapsPhone,
|
||||
"docsis": layers.LLDPCapsDocSis,
|
||||
"station_only": layers.LLDPCapsStationOnly,
|
||||
"cvlan": layers.LLDPCapsCVLAN,
|
||||
"svlan": layers.LLDPCapsSVLAN,
|
||||
"tmpr": layers.LLDPCapsTmpr,
|
||||
}
|
||||
)
|
||||
|
||||
func tlvMgmtAddressToBytes(m *layers.LLDPMgmtAddress) []byte {
|
||||
var b []byte
|
||||
b = append(b, byte(len(m.Address))+1) // TLV Length
|
||||
b = append(b, byte(m.Subtype)) // Address Subtype
|
||||
b = append(b, m.Address...) // Address
|
||||
b = append(b, byte(m.InterfaceSubtype)) // Interface Subtype
|
||||
|
||||
ifIndex := make([]byte, 4) // 4 bytes for the interface number
|
||||
binary.BigEndian.PutUint32(ifIndex, m.InterfaceNumber)
|
||||
b = append(b, ifIndex...)
|
||||
|
||||
b = append(b, 0) // OID type
|
||||
return b
|
||||
}
|
||||
|
||||
func tlvMgmtAddress(m *layers.LLDPMgmtAddress) layers.LinkLayerDiscoveryValue {
|
||||
return layers.LinkLayerDiscoveryValue{
|
||||
Type: layers.LLDPTLVMgmtAddress,
|
||||
Value: tlvMgmtAddressToBytes(m),
|
||||
Length: uint16(len(tlvMgmtAddressToBytes(m))),
|
||||
}
|
||||
}
|
||||
|
||||
// if err := checkLLDPTLVLen(v, 9); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// mlen := v.Value[0]
|
||||
// if err := checkLLDPTLVLen(v, int(mlen+7)); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// info.MgmtAddress.Subtype = IANAAddressFamily(v.Value[1])
|
||||
// info.MgmtAddress.Address = v.Value[2 : mlen+1]
|
||||
// info.MgmtAddress.InterfaceSubtype = LLDPInterfaceSubtype(v.Value[mlen+1])
|
||||
// info.MgmtAddress.InterfaceNumber = binary.BigEndian.Uint32(v.Value[mlen+2 : mlen+6])
|
||||
// olen := v.Value[mlen+6]
|
||||
// if err := checkLLDPTLVLen(v, int(mlen+7+olen)); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// info.MgmtAddress.OID = string(v.Value[mlen+7 : mlen+7+olen])
|
||||
|
||||
func checkLLDPTLVLen(v layers.LinkLayerDiscoveryValue, l int) (err error) {
|
||||
if len(v.Value) < l {
|
||||
err = fmt.Errorf("invalid TLV %v length %d (wanted mimimum %v)", v.Type, len(v.Value), l)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// parseTlvMgmtAddress parses the Management Address TLV and returns the Management Address
|
||||
// structure.
|
||||
// we don't parse the OID here, as it's not needed for the neighbor cache
|
||||
func parseTlvMgmtAddress(v layers.LinkLayerDiscoveryValue) *layers.LLDPMgmtAddress {
|
||||
if err := checkLLDPTLVLen(v, 9); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mlen := v.Value[0]
|
||||
if err := checkLLDPTLVLen(v, int(mlen+7)); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &layers.LLDPMgmtAddress{
|
||||
Subtype: layers.IANAAddressFamily(v.Value[1]),
|
||||
Address: v.Value[2 : mlen+1],
|
||||
InterfaceSubtype: layers.LLDPInterfaceSubtype(v.Value[mlen+1]),
|
||||
InterfaceNumber: binary.BigEndian.Uint32(v.Value[mlen+2 : mlen+6]),
|
||||
}
|
||||
}
|
||||
|
||||
func lldpMgmtAddressToSerializable(m *layers.LLDPMgmtAddress) ManagementAddress {
|
||||
var addrString string
|
||||
switch m.Subtype {
|
||||
case layers.IANAAddressFamilyIPV4:
|
||||
addrString = net.IP(m.Address).String()
|
||||
case layers.IANAAddressFamilyIPV6:
|
||||
addrString = net.IP(m.Address).String()
|
||||
default:
|
||||
addrString = string(m.Address)
|
||||
}
|
||||
|
||||
return ManagementAddress{
|
||||
AddressFamily: m.Subtype.String(),
|
||||
Address: addrString,
|
||||
InterfaceSubtype: m.InterfaceSubtype.String(),
|
||||
InterfaceNumber: m.InterfaceNumber,
|
||||
}
|
||||
}
|
||||
|
||||
func tlvStringValue(tlvType layers.LLDPTLVType, value string) layers.LinkLayerDiscoveryValue {
|
||||
return layers.LinkLayerDiscoveryValue{
|
||||
Type: tlvType,
|
||||
Value: []byte(value),
|
||||
Length: uint16(len(value)),
|
||||
}
|
||||
}
|
||||
|
||||
func toLLDPCapabilitiesBytes(capabilities []string) uint16 {
|
||||
r := uint16(0)
|
||||
for _, capability := range capabilities {
|
||||
mask, ok := capabilityMap[capability]
|
||||
if ok {
|
||||
r |= mask
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
|
@ -37,7 +37,8 @@ export default function LLDPNeighborsCard({
|
|||
<div className="space-y-3 pt-2">
|
||||
{neighbors.map(neighbor => {
|
||||
const displayName = neighbor.system_name || neighbor.port_description || neighbor.mac;
|
||||
return <div className="space-y-3" key={neighbor.mac}>
|
||||
const key = `${neighbor.mac}-${neighbor.source}`;
|
||||
return <div className="space-y-3" key={key}>
|
||||
<h4 className="text-sm font-semibold font-mono">{displayName}</h4>
|
||||
<div
|
||||
className="rounded-md rounded-l-none border border-slate-500/10 border-l-blue-700/50 bg-white p-4 pl-4 backdrop-blur-sm dark:bg-transparent"
|
||||
|
|
|
|||
Loading…
Reference in New Issue