added support for LLDP port type identifycation 7 (local)
authorVictor Kirhenshtein <victor@netxms.org>
Mon, 6 Aug 2012 12:27:39 +0000 (12:27 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Mon, 6 Aug 2012 12:27:39 +0000 (12:27 +0000)
src/server/core/alarm.cpp
src/server/core/lldp.cpp
src/server/core/lln.cpp
src/server/include/nms_topo.h
src/server/tools/nxconfig/nxconfig.cpp

index 199ffe8..88fb9da 100644 (file)
@@ -619,7 +619,7 @@ int AlarmManager::getMostCriticalStatusForObject(DWORD dwObjectId)
    for(i = 0; i < m_dwNumAlarms; i++)
    {
       if ((m_pAlarmList[i].dwSourceObject == dwObjectId) &&
-                        ((m_pAlarmList[i].nState & ALARM_STATE_MASK) < ALARM_STATE_RESOLVED)
+                        ((m_pAlarmList[i].nState & ALARM_STATE_MASK) < ALARM_STATE_RESOLVED) &&
           ((m_pAlarmList[i].nCurrentSeverity > iStatus) || (iStatus == STATUS_UNKNOWN)))
       {
          iStatus = (int)m_pAlarmList[i].nCurrentSeverity;
index 6f81643..1c6a3c0 100644 (file)
 
 #include "nxcore.h"
 
+/**
+ * Local port info
+ */
+struct LOCAL_PORT_INFO
+{
+       BYTE localId[256];
+       size_t localIdLen;
+       TCHAR ifDescr[192];
+};
 
-//
-// Find remote interface
-//
+struct LOCAL_PORT_INFO_CACHE
+{
+       int count;
+       int allocated;
+       LOCAL_PORT_INFO *ports;
+};
 
-static Interface *FindRemoteInterface(Node *node, DWORD idType, BYTE *id, size_t idLen)
+/**
+ * Handler for walking local port table
+ */
+static DWORD PortIdLookupHandler(DWORD snmpVersion, SNMP_Variable *var, SNMP_Transport *transport, void *arg)
+{
+       LOCAL_PORT_INFO_CACHE *pc = (LOCAL_PORT_INFO_CACHE *)arg;
+       if (pc->count == pc->allocated)
+       {
+               pc->allocated += 64;
+               pc->ports = (LOCAL_PORT_INFO *)realloc(pc->ports, sizeof(LOCAL_PORT_INFO) * pc->allocated);
+       }
+       
+       LOCAL_PORT_INFO *port = &pc->ports[pc->count++];
+       port->localIdLen = var->getRawValue(port->localId, 256);
+
+       SNMP_ObjectId *oid = var->GetName();
+       DWORD newOid[128];
+       memcpy(newOid, oid->getValue(), oid->getLength() * sizeof(DWORD));
+   SNMP_PDU *pRqPDU = new SNMP_PDU(SNMP_GET_REQUEST, SnmpNewRequestId(), snmpVersion);
+
+       newOid[oid->getLength() - 2] = 4;       // lldpLocPortDescr
+       pRqPDU->bindVariable(new SNMP_Variable(newOid, oid->getLength()));
+
+       SNMP_PDU *pRespPDU = NULL;
+   DWORD rcc = transport->doRequest(pRqPDU, &pRespPDU, g_dwSNMPTimeout, 3);
+       delete pRqPDU;
+       if (rcc == SNMP_ERR_SUCCESS)
+   {
+               pRespPDU->getVariable(0)->GetValueAsString(port->ifDescr, 192);
+               delete pRespPDU;
+       }
+       else
+       {
+               _tcscpy(port->ifDescr, _T("###error###"));
+       }
+
+       return SNMP_ERR_SUCCESS;
+}
+
+/**
+ * Lookup interface description from local ID
+ */
+static bool LookupInterfaceDescription(LinkLayerNeighbors *nbs, BYTE *id, size_t idLen, TCHAR *ifName)
+{
+       LOCAL_PORT_INFO_CACHE *pc = (LOCAL_PORT_INFO_CACHE *)nbs->getData(1);
+       if (pc == NULL)
+       {
+               // local port info not cached yet
+               pc = (LOCAL_PORT_INFO_CACHE *)malloc(sizeof(LOCAL_PORT_INFO_CACHE));
+               memset(pc, 0, sizeof(LOCAL_PORT_INFO_CACHE));
+               SNMP_Transport *snmp = (SNMP_Transport *)nbs->getData(2);
+               if (SnmpEnumerate(snmp->getSnmpVersion(), snmp, _T(".1.0.8802.1.1.2.1.3.7.1.3"), PortIdLookupHandler, pc, FALSE) != SNMP_ERR_SUCCESS)
+               {
+                       safe_free(pc->ports);
+                       free(pc);
+                       return false;
+               }
+               nbs->setData(1, pc);
+               Node *node = (Node *)nbs->getData();
+               DbgPrintf(5, _T("LLDP: local port table cached for node %s [%d]"), node->Name(), (int)node->Id());
+       }
+       
+       for(int i = 0; i < pc->count; i++)
+               if ((idLen == pc->ports[i].localIdLen) && !memcmp(id, pc->ports[i].localId, idLen))
+               {
+                       nx_strncpy(ifName, pc->ports[i].ifDescr, 130);
+                       return true;
+               }
+       return false;
+}
+
+/**
+ * Find remote interface
+ */
+static Interface *FindRemoteInterface(Node *node, DWORD idType, BYTE *id, size_t idLen, LinkLayerNeighbors *nbs)
 {
        TCHAR ifName[130];
        Interface *ifc;
@@ -66,16 +152,24 @@ static Interface *FindRemoteInterface(Node *node, DWORD idType, BYTE *id, size_t
                                ifc = node->findInterface(ifName);
                        }
                        return ifc;
+               case 7: // local identifier
+                       if (LookupInterfaceDescription(nbs, id, idLen, ifName))
+                       {
+                               ifc = node->findInterface(ifName);      /* TODO: find by cached ifName value */
+                       }
+                       else
+                       {
+                               ifc = NULL;
+                       }
+                       return ifc;
                default:
                        return NULL;
        }
 }
 
-
-//
-// Topology table walker's callback for LLDP topology table
-//
-
+/**
+ * Topology table walker's callback for LLDP topology table
+ */
 static DWORD LLDPTopoHandler(DWORD snmpVersion, SNMP_Variable *var, SNMP_Transport *transport, void *arg)
 {
        LinkLayerNeighbors *nbs = (LinkLayerNeighbors *)arg;
@@ -111,7 +205,7 @@ static DWORD LLDPTopoHandler(DWORD snmpVersion, SNMP_Variable *var, SNMP_Transpo
                {
                        BYTE remoteIfId[1024];
                        size_t remoteIfIdLen = pRespPDU->getVariable(1)->getRawValue(remoteIfId, 1024);
-                       Interface *ifRemote = FindRemoteInterface(remoteNode, pRespPDU->getVariable(2)->GetValueAsUInt(), remoteIfId, remoteIfIdLen);
+                       Interface *ifRemote = FindRemoteInterface(remoteNode, pRespPDU->getVariable(2)->GetValueAsUInt(), remoteIfId, remoteIfIdLen, nbs);
 
                        LL_NEIGHBOR_INFO info;
 
@@ -153,18 +247,23 @@ static DWORD LLDPTopoHandler(DWORD snmpVersion, SNMP_Variable *var, SNMP_Transpo
        return SNMP_ERR_SUCCESS;
 }
 
-
-//
-// Add LLDP-discovered neighbors
-//
-
+/**
+ * Add LLDP-discovered neighbors
+ */
 void AddLLDPNeighbors(Node *node, LinkLayerNeighbors *nbs)
 {
        if (!(node->getFlags() & NF_IS_LLDP))
                return;
 
        DbgPrintf(5, _T("LLDP: collecting topology information for node %s [%d]"), node->Name(), node->Id());
-       nbs->setData(node);
+       nbs->setData(0, node);
+       nbs->setData(1, NULL);  // local port info cache
        node->CallSnmpEnumerate(_T(".1.0.8802.1.1.2.1.4.1.1.5"), LLDPTopoHandler, nbs);
+       LOCAL_PORT_INFO_CACHE *pc = (LOCAL_PORT_INFO_CACHE *)nbs->getData(1);
+       if (pc != NULL)
+       {
+               safe_free(pc->ports);
+               free(pc);
+       }
        DbgPrintf(5, _T("LLDP: finished collecting topology information for node %s [%d]"), node->Name(), node->Id());
 }
index 97f002a..d02cf43 100644 (file)
@@ -32,7 +32,7 @@ LinkLayerNeighbors::LinkLayerNeighbors()
        m_connections = NULL;\r
        m_count = 0;\r
        m_allocated = 0;\r
-       m_data = NULL;\r
+       memset(m_data, 0, sizeof(m_data));\r
 }\r
 \r
 \r
index 07f46ff..6f9617a 100644 (file)
@@ -144,7 +144,7 @@ private:
        int m_count;
        int m_allocated;
        LL_NEIGHBOR_INFO *m_connections;
-       void *m_data;
+       void *m_data[4];
 
        bool isDuplicate(LL_NEIGHBOR_INFO *info);
 
@@ -155,8 +155,10 @@ public:
        void addConnection(LL_NEIGHBOR_INFO *info);
        LL_NEIGHBOR_INFO *getConnection(int index) { return ((index >= 0) && (index < m_count)) ? &m_connections[index] : NULL; }
 
-       void setData(void *data) { m_data = data; }
-       void *getData() { return m_data; }
+       void setData(int index, void *data) { if ((index >= 0) && (index < 4)) m_data[index] = data; }
+       void *getData(int index) { return ((index >= 0) && (index < 4)) ? m_data[index] : NULL; }
+       void setData(void *data) { setData(0, data); }
+       void *getData() { return getData(0); }
        int getSize() { return m_count; }
 };
 
index 9707759..d1fed77 100644 (file)
@@ -61,7 +61,6 @@ BOOL CNxconfigApp::InitInstance()
 {
    HKEY hKey;
    DWORD dwSize, dwData = 0;
-       TCHAR szCmd[1024];
 
        if (!AfxSocketInit())
        {