fix(lldp): локальный порт из индекса OID + lldpLocPortDesc для таблицы связей
Made-with: Cursor
This commit is contained in:
@@ -259,6 +259,11 @@ func lldpRemRowsFromWalk(rows map[string]*lldpRemAggRow, pduName string, val any
|
||||
case "9":
|
||||
r.sysName = v
|
||||
}
|
||||
// Индекс lldpRemEntry: { timeMark, localPortNum, remIndex } — часть прошивок не отдаёт колонку 2, но порт есть в суффиксе OID.
|
||||
idx := parts[1:]
|
||||
if len(idx) >= 3 && strings.TrimSpace(r.localPort) == "" {
|
||||
r.localPort = idx[1]
|
||||
}
|
||||
}
|
||||
|
||||
// probeLLDPViaRemTableWalk один раз обходит всю lldpRemTable (стандарт IEEE 802.1AB).
|
||||
@@ -395,9 +400,13 @@ func probeLLDPViaColumnWalks(client *gosnmp.GoSNMP, ip string, checkedAt time.Ti
|
||||
|
||||
out := make([]LLDPResult, 0, len(keys))
|
||||
for k := range keys {
|
||||
lp := strings.TrimSpace(ports[k])
|
||||
if lp == "" {
|
||||
lp = lldpRemIndexLocalPortFromKey(k)
|
||||
}
|
||||
item := LLDPResult{
|
||||
IP: ip,
|
||||
LocalPortNum: ports[k],
|
||||
LocalPortNum: lp,
|
||||
RemoteChassisID: chassis[k],
|
||||
RemotePortID: remotePorts[k],
|
||||
RemoteSysName: sysNames[k],
|
||||
@@ -419,9 +428,65 @@ func probeLLDP(client *gosnmp.GoSNMP, ip string, checkedAt time.Time) []LLDPResu
|
||||
if len(out) == 0 {
|
||||
out = probeLLDPViaGetNextRemTable(client, ip, checkedAt)
|
||||
}
|
||||
return enrichLLDPLocalPortLabels(client, out)
|
||||
}
|
||||
|
||||
// lldpRemIndexLocalPortFromKey суффикс ключа walk: timeMark.localPortNum.remIndex (IEEE LLDP remTable).
|
||||
func lldpRemIndexLocalPortFromKey(key string) string {
|
||||
parts := strings.Split(key, ".")
|
||||
if len(parts) >= 3 {
|
||||
return parts[1]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// lldpLocPortDescOIDs — lldpLocPortDesc по номеру порта (RFC 4502 и встречающийся в поле вариант).
|
||||
var lldpLocPortDescOIDs = []string{
|
||||
".1.0.8802.1.1.2.1.2.1.7.1.3",
|
||||
".1.0.8802.1.1.2.1.3.7.1.3",
|
||||
}
|
||||
|
||||
func probeLLDPLocPortDescByPortNum(client *gosnmp.GoSNMP) map[string]string {
|
||||
out := make(map[string]string)
|
||||
for _, base := range lldpLocPortDescOIDs {
|
||||
for k, v := range walkAsMap(client, base) {
|
||||
v = strings.TrimSpace(v)
|
||||
if v != "" {
|
||||
out[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func formatLocalPortLabel(portNum, ifDescr string) string {
|
||||
portNum = strings.TrimSpace(portNum)
|
||||
ifDescr = strings.TrimSpace(ifDescr)
|
||||
if ifDescr != "" && portNum != "" && ifDescr != portNum {
|
||||
return portNum + " — " + ifDescr
|
||||
}
|
||||
if ifDescr != "" {
|
||||
return ifDescr
|
||||
}
|
||||
return portNum
|
||||
}
|
||||
|
||||
// enrichLLDPLocalPortLabels подставляет lldpLocPortDesc (как в CLI) к номеру локального порта.
|
||||
func enrichLLDPLocalPortLabels(client *gosnmp.GoSNMP, items []LLDPResult) []LLDPResult {
|
||||
if len(items) == 0 {
|
||||
return items
|
||||
}
|
||||
descByPort := probeLLDPLocPortDescByPortNum(client)
|
||||
if len(descByPort) == 0 {
|
||||
return items
|
||||
}
|
||||
for i := range items {
|
||||
num := strings.TrimSpace(items[i].LocalPortNum)
|
||||
items[i].LocalPortNum = formatLocalPortLabel(num, descByPort[num])
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
func snmpOIDTrim(s string) string {
|
||||
return strings.TrimPrefix(strings.TrimSpace(s), ".")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user