package ifmib import ( "fmt" "log" "sync" "github.com/posteo/go-agentx" "github.com/posteo/go-agentx/pdu" "github.com/posteo/go-agentx/value" "go.fd.io/govpp/api" ) // IF-MIB OID base: 1.3.6.1.2.1.31.1.1.1 // ifXTable entries: // ifName .1 - DisplayString // ifInMulticastPkts .2 - Counter32 // ifInBroadcastPkts .3 - Counter32 // ifOutMulticastPkts .4 - Counter32 // ifOutBroadcastPkts .5 - Counter32 // ifHCInOctets .6 - Counter64 // ifHCInUcastPkts .7 - Counter64 // ifHCInMulticastPkts .8 - Counter64 // ifHCInBroadcastPkts .9 - Counter64 // ifHCOutOctets .10 - Counter64 // ifHCOutUcastPkts .11 - Counter64 // ifHCOutMulticastPkts .12 - Counter64 // ifHCOutBroadcastPkts .13 - Counter64 const ifXTableOID = "1.3.6.1.2.1.31.1.1.1" type InterfaceMIB struct { mutex sync.RWMutex handler *agentx.ListHandler session *agentx.Session stats map[uint32]*api.InterfaceCounters // indexed by interface index indexOffset int } func NewInterfaceMIB(indexOffset int) *InterfaceMIB { return &InterfaceMIB{ handler: &agentx.ListHandler{}, stats: make(map[uint32]*api.InterfaceCounters), indexOffset: indexOffset, } } func (m *InterfaceMIB) GetHandler() *agentx.ListHandler { return m.handler } func (m *InterfaceMIB) UpdateStats(interfaceStats *api.InterfaceStats) { m.mutex.Lock() defer m.mutex.Unlock() log.Printf("Updating IF-MIB with %d interfaces", len(interfaceStats.Interfaces)) // Clear existing entries m.handler = &agentx.ListHandler{} m.stats = make(map[uint32]*api.InterfaceCounters) // Add new entries for _, iface := range interfaceStats.Interfaces { log.Printf("Processing interface %d (%s)", iface.InterfaceIndex, iface.InterfaceName) m.stats[iface.InterfaceIndex] = &iface m.addInterfaceToMIB(&iface) } // Update the session with the new handler if m.session != nil { m.session.Handler = m.handler log.Printf("Updated session handler with new IF-MIB data") } log.Printf("IF-MIB now contains %d interfaces", len(m.stats)) } func (m *InterfaceMIB) addInterfaceToMIB(iface *api.InterfaceCounters) { idx := int(iface.InterfaceIndex) + m.indexOffset // ifName (.1) item := m.handler.Add(fmt.Sprintf("%s.1.%d", ifXTableOID, idx)) item.Type = pdu.VariableTypeOctetString item.Value = iface.InterfaceName // ifInMulticastPkts (.2) item = m.handler.Add(fmt.Sprintf("%s.2.%d", ifXTableOID, idx)) item.Type = pdu.VariableTypeCounter32 item.Value = uint32(iface.RxMulticast.Packets) // ifInBroadcastPkts (.3) item = m.handler.Add(fmt.Sprintf("%s.3.%d", ifXTableOID, idx)) item.Type = pdu.VariableTypeCounter32 item.Value = uint32(iface.RxBroadcast.Packets) // ifOutMulticastPkts (.4) item = m.handler.Add(fmt.Sprintf("%s.4.%d", ifXTableOID, idx)) item.Type = pdu.VariableTypeCounter32 item.Value = uint32(iface.TxMulticast.Packets) // ifOutBroadcastPkts (.5) item = m.handler.Add(fmt.Sprintf("%s.5.%d", ifXTableOID, idx)) item.Type = pdu.VariableTypeCounter32 item.Value = uint32(iface.TxBroadcast.Packets) // ifHCInOctets (.6) item = m.handler.Add(fmt.Sprintf("%s.6.%d", ifXTableOID, idx)) item.Type = pdu.VariableTypeCounter64 item.Value = iface.Rx.Bytes // ifHCInUcastPkts (.7) item = m.handler.Add(fmt.Sprintf("%s.7.%d", ifXTableOID, idx)) item.Type = pdu.VariableTypeCounter64 item.Value = iface.RxUnicast.Packets // ifHCInMulticastPkts (.8) item = m.handler.Add(fmt.Sprintf("%s.8.%d", ifXTableOID, idx)) item.Type = pdu.VariableTypeCounter64 item.Value = iface.RxMulticast.Packets // ifHCInBroadcastPkts (.9) item = m.handler.Add(fmt.Sprintf("%s.9.%d", ifXTableOID, idx)) item.Type = pdu.VariableTypeCounter64 item.Value = iface.RxBroadcast.Packets // ifHCOutOctets (.10) item = m.handler.Add(fmt.Sprintf("%s.10.%d", ifXTableOID, idx)) item.Type = pdu.VariableTypeCounter64 item.Value = iface.Tx.Bytes // ifHCOutUcastPkts (.11) item = m.handler.Add(fmt.Sprintf("%s.11.%d", ifXTableOID, idx)) item.Type = pdu.VariableTypeCounter64 item.Value = iface.TxUnicast.Packets // ifHCOutMulticastPkts (.12) item = m.handler.Add(fmt.Sprintf("%s.12.%d", ifXTableOID, idx)) item.Type = pdu.VariableTypeCounter64 item.Value = iface.TxMulticast.Packets // ifHCOutBroadcastPkts (.13) item = m.handler.Add(fmt.Sprintf("%s.13.%d", ifXTableOID, idx)) item.Type = pdu.VariableTypeCounter64 item.Value = iface.TxBroadcast.Packets log.Printf("Added interface %d (%s) to IF-MIB with SNMP index %d", iface.InterfaceIndex, iface.InterfaceName, idx) } func (m *InterfaceMIB) RegisterWithSession(session *agentx.Session) error { m.mutex.Lock() defer m.mutex.Unlock() m.session = session session.Handler = m.handler // Register at the ifXTable level err := session.Register(127, value.MustParseOID(ifXTableOID)) if err != nil { return fmt.Errorf("failed to register IF-MIB: %v", err) } log.Printf("Registered IF-MIB at OID %s", ifXTableOID) return nil }