fixed bugs in CDP-based topology discovery; implemented forced topology poll; many...
authorVictor Kirhenshtein <victor@netxms.org>
Fri, 8 Apr 2011 16:03:00 +0000 (16:03 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Fri, 8 Apr 2011 16:03:00 +0000 (16:03 +0000)
31 files changed:
.gitattributes
doc/internal/db_format_change.txt
include/netxmsdb.h
include/nxclapi.h
sql/schema.in
src/java/netxms-client/src/main/java/org/netxms/client/constants/NodePoller.java
src/java/netxms-client/src/main/java/org/netxms/client/objects/Interface.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/NetworkMap.java
src/java/netxms-eclipse/ObjectManager/plugin.xml
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/TopologyPoll.java [copied from src/java/netxms-client/src/main/java/org/netxms/client/constants/NodePoller.java with 67% similarity]
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/views/NodePollerView.java
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/ObjectToolsDynamicMenu.java
src/java/netxms-eclipse/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/elements/Capabilities.java
src/java/netxms-eclipse/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/elements/GeneralInfo.java
src/java/netxms-eclipse/Topology/src/org/netxms/ui/eclipse/topology/widgets/PortView.java
src/java/netxms-eclipse/Topology/src/org/netxms/ui/eclipse/topology/widgets/SlotView.java
src/server/core/cdp.cpp
src/server/core/import.cpp
src/server/core/interface.cpp
src/server/core/netobj.cpp
src/server/core/node.cpp
src/server/core/np.cpp
src/server/core/objects.cpp
src/server/core/poll.cpp
src/server/core/session.cpp
src/server/include/nms_objects.h
src/server/include/nxsrvapi.h
src/server/libnxsrv/agent.cpp
src/server/libnxsrv/ndd.cpp
src/server/tools/nxdbmgr/check.cpp
src/server/tools/nxdbmgr/upgrade.cpp

index 757f830..8f05d84 100644 (file)
@@ -937,6 +937,7 @@ src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/ac
 src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/MultipleObjectAction.java -text
 src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/RemoveClusterNode.java -text
 src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/StatusPoll.java -text
+src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/TopologyPoll.java -text
 src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/UnbindObject.java -text
 src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/Unmanage.java -text
 src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/dialogs/AttributeEditDialog.java -text
index 15fe9a7..bad2303 100644 (file)
@@ -1,4 +1,11 @@
 ***************
+* 224 ==> 225 *
+***************
+
+- Columns "description" added to table "interfaces"
+
+
+***************
 * 223 ==> 224 *
 ***************
 
index 56d33b9..c47c7ff 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxmsdb_h
 #define _netxmsdb_h
 
-#define DB_FORMAT_VERSION   224
+#define DB_FORMAT_VERSION   225
 
 #endif
index 47db71e..39c3e52 100644 (file)
@@ -126,6 +126,7 @@ typedef void * NXC_SESSION;
 #define POLL_STATUS           1
 #define POLL_CONFIGURATION    2
 #define POLL_INTERFACE_NAMES  3
+#define POLL_TOPOLOGY         4
 
 
 //
index a6bb798..f92cda3 100644 (file)
@@ -310,6 +310,7 @@ CREATE TABLE interfaces
        mac_addr varchar(15) not null,
        synthetic_mask integer not null,
        required_polls integer not null,
+       description varchar(255),
        PRIMARY KEY(id)
 ) TABLE_TYPE;
 
index 6903efd..a3f410e 100644 (file)
@@ -27,4 +27,5 @@ public final class NodePoller
        public static final int STATUS_POLL = 1;\r
        public static final int CONFIGURATION_POLL = 2;\r
        public static final int INTERFACE_POLL = 3;\r
+       public static final int TOPOLOGY_POLL = 4;\r
 }\r
index d017123..2c8d39f 100644 (file)
@@ -38,6 +38,7 @@ public class Interface extends GenericObject
        private long peerNodeId;\r
        private long peerInterfaceId;\r
        private long zoneId;\r
+       private String description;\r
        \r
        /**\r
         * @param msg\r
@@ -56,6 +57,7 @@ public class Interface extends GenericObject
                peerNodeId = msg.getVariableAsInt64(NXCPCodes.VID_PEER_NODE_ID);\r
                peerInterfaceId = msg.getVariableAsInt64(NXCPCodes.VID_PEER_INTERFACE_ID);\r
                zoneId = msg.getVariableAsInt64(NXCPCodes.VID_ZONE_ID);\r
+               description = msg.getVariableAsString(NXCPCodes.VID_DESCRIPTION);\r
        }\r
 \r
        /**\r
@@ -146,4 +148,12 @@ public class Interface extends GenericObject
        {\r
                return zoneId;\r
        }\r
+\r
+       /**\r
+        * @return the description\r
+        */\r
+       public String getDescription()\r
+       {\r
+               return description;\r
+       }\r
 }\r
index d0b6dc8..b383188 100644 (file)
@@ -545,25 +545,27 @@ public abstract class NetworkMap extends ViewPart implements ISelectionProvider,
 \r
        /**\r
         * Fill context menu for map object\r
-        * @param mgr Menu manager\r
+        * @param manager Menu manager\r
         */\r
-       protected void fillObjectContextMenu(IMenuManager mgr)\r
+       protected void fillObjectContextMenu(IMenuManager manager)\r
        {\r
-               mgr.add(new GroupMarker(IActionConstants.MB_OBJECT_CREATION));\r
-               mgr.add(new Separator());\r
-               mgr.add(new GroupMarker(IActionConstants.MB_OBJECT_MANAGEMENT));\r
-               mgr.add(new Separator());\r
-               mgr.add(new GroupMarker(IActionConstants.MB_OBJECT_BINDING));\r
-               mgr.add(new Separator());\r
-               mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));\r
-               mgr.add(new Separator());\r
-               mgr.add(new GroupMarker(IActionConstants.MB_DATA_COLLECTION));\r
+               manager.add(new GroupMarker(IActionConstants.MB_OBJECT_CREATION));\r
+               manager.add(new Separator());\r
+               manager.add(new GroupMarker(IActionConstants.MB_OBJECT_MANAGEMENT));\r
+               manager.add(new Separator());\r
+               manager.add(new GroupMarker(IActionConstants.MB_OBJECT_BINDING));\r
+               manager.add(new Separator());\r
+               manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));\r
+               manager.add(new Separator());\r
+               manager.add(new GroupMarker(IActionConstants.MB_TOPOLOGY));\r
+               manager.add(new Separator());\r
+               manager.add(new GroupMarker(IActionConstants.MB_DATA_COLLECTION));\r
                \r
                if (currentSelection.size() == 1)\r
                {\r
-                       mgr.add(new Separator());\r
-                       mgr.add(new GroupMarker(IActionConstants.MB_PROPERTIES));\r
-                       mgr.add(new PropertyDialogAction(getSite(), this));\r
+                       manager.add(new Separator());\r
+                       manager.add(new GroupMarker(IActionConstants.MB_PROPERTIES));\r
+                       manager.add(new PropertyDialogAction(getSite(), this));\r
                }\r
        }\r
        \r
index 92268e3..9554cc4 100644 (file)
                path="objectmgmt">\r
          </menu>\r
          <action\r
+               class="org.netxms.ui.eclipse.objectmanager.actions.TopologyPoll"\r
+               enablesFor="1"\r
+               id="org.netxms.ui.eclipse.objectmanager.popupActions.TopologyPoll"\r
+               label="&amp;Topology"\r
+               menubarPath="org.netxms.ui.eclipse.objectmanager.popupActions.PollMenu/additions"\r
+               style="push">\r
+         </action>\r
+         <action\r
                class="org.netxms.ui.eclipse.objectmanager.actions.InterfacePoll"\r
                enablesFor="1"\r
                id="org.netxms.ui.eclipse.objectmanager.popupActions.InterfacePoll"\r
  * along with this program; if not, write to the Free Software\r
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
  */\r
-package org.netxms.client.constants;\r
+package org.netxms.ui.eclipse.objectmanager.actions;\r
+\r
+import org.netxms.client.constants.NodePoller;\r
 \r
 /**\r
- * Constants for node poller\r
+ * Start status poll\r
  *\r
  */\r
-public final class NodePoller\r
+public class TopologyPoll extends AbstractNodePoll\r
 {\r
-       public static final int STATUS_POLL = 1;\r
-       public static final int CONFIGURATION_POLL = 2;\r
-       public static final int INTERFACE_POLL = 3;\r
+       /* (non-Javadoc)\r
+        * @see org.netxms.ui.eclipse.objectmanager.actions.AbstractNodePoll#getPollType()\r
+        */\r
+       @Override\r
+       protected int getPollType()\r
+       {\r
+               return NodePoller.TOPOLOGY_POLL;\r
+       }\r
 }\r
index 2fc296f..763de79 100644 (file)
@@ -60,7 +60,7 @@ public class NodePollerView extends ViewPart
 {\r
        public static final String ID = "org.netxms.ui.eclipse.objectmanager.views.NodePollerView";\r
        \r
-       private static final String[] POLL_NAME = { "", "Status Poll", "Configuration Poll", "Interface Poll" };\r
+       private static final String[] POLL_NAME = { "", "Status Poll", "Configuration Poll", "Interface Poll", "Topology Poll" };\r
        private static final Color COLOR_ERROR = new Color(Display.getDefault(), 192, 0, 0);\r
        private static final Color COLOR_WARNING = new Color(Display.getDefault(), 255, 128, 0);\r
        private static final Color COLOR_INFO = new Color(Display.getDefault(), 0, 128, 0);\r
index a4a79df..4be3f90 100644 (file)
@@ -152,7 +152,7 @@ public class ObjectToolsDynamicMenu extends ContributionItem implements IWorkben
                                        rootMenu = currMenu;\r
                                }\r
                                \r
-                               final MenuItem item = new MenuItem(rootMenu, SWT.CHECK);\r
+                               final MenuItem item = new MenuItem(rootMenu, SWT.PUSH);\r
                                item.setText(path[path.length - 1]);\r
                                item.setData(tools[i]);\r
                                item.addSelectionListener(new SelectionAdapter() {\r
index 4b2f080..a39612b 100644 (file)
@@ -59,6 +59,7 @@ public class Capabilities extends TableElement
                addFlag("isAgent", (node.getFlags() & Node.NF_IS_NATIVE_AGENT) != 0);\r
                addFlag("isBridge", (node.getFlags() & Node.NF_IS_BRIDGE) != 0);\r
                addFlag("isCDP", (node.getFlags() & Node.NF_IS_CDP) != 0);\r
+               addFlag("isDot1x", (node.getFlags() & Node.NF_IS_8021X) != 0);\r
                addFlag("isLLDP", (node.getFlags() & Node.NF_IS_LLDP) != 0);\r
                addFlag("isNDP", (node.getFlags() & Node.NF_IS_SONMP) != 0);\r
                addFlag("isPrinter", (node.getFlags() & Node.NF_IS_PRINTER) != 0);\r
index 2e16c73..96674a3 100644 (file)
@@ -54,6 +54,7 @@ public class GeneralInfo extends TableElement
                                Interface iface = (Interface)object;\r
                                addPair("Interface Index", Integer.toString(iface.getIfIndex()));\r
                                addPair("Interface Type", Integer.toString(iface.getIfType()));\r
+                               addPair("Description", iface.getDescription());\r
                                addPair("MAC Address", iface.getMacAddress().toString());\r
                                if ((iface.getSlot() != 0) && (iface.getPort() != 0))\r
                                        addPair("Slot/Port", Integer.toString(iface.getSlot()) + "/" + Integer.toString(iface.getPort()));\r
index 349d562..fbbe185 100644 (file)
@@ -35,6 +35,7 @@ import org.netxms.client.NXCSession;
 import org.netxms.client.objects.GenericObject;\r
 import org.netxms.client.objects.Interface;\r
 import org.netxms.client.objects.Node;\r
+import org.netxms.ui.eclipse.shared.ConsoleSharedData;\r
 import org.netxms.ui.eclipse.topology.widgets.helpers.PortInfo;\r
 \r
 /**\r
@@ -56,6 +57,8 @@ public class PortView extends Composite
        {\r
                super(parent, style);\r
                \r
+               session = (NXCSession)ConsoleSharedData.getSession();\r
+               \r
                RowLayout layout = new RowLayout();\r
                layout.type = SWT.VERTICAL;\r
                setLayout(layout);\r
index 1c40e24..95ca01c 100644 (file)
@@ -1,5 +1,20 @@
 /**\r
- * \r
+ * NetXMS - open source network management system\r
+ * Copyright (C) 2003-2011 Victor Kirhenshtein\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
  */\r
 package org.netxms.ui.eclipse.topology.widgets;\r
 \r
index 8825f74..f0e9d79 100644 (file)
 // Topology table walker's callback for CDP topology table\r
 //\r
 \r
-static DWORD CDPTopoHandler(DWORD dwVersion, SNMP_Variable *var, SNMP_Transport *pTransport, void *arg)\r
+static DWORD CDPTopoHandler(DWORD snmpVersion, SNMP_Variable *var, SNMP_Transport *transport, void *arg)\r
 {\r
        Node *node = (Node *)((LinkLayerNeighbors *)arg)->getData();\r
-\r
-   TCHAR szOid[MAX_OID_LEN * 4], szSuffix[MAX_OID_LEN * 4], ipAddrText[16];\r
+       SNMP_ObjectId *oid = var->GetName();\r
 \r
        DWORD remoteIp;\r
        var->getRawValue((BYTE *)&remoteIp, sizeof(DWORD));\r
        remoteIp = ntohl(remoteIp);\r
        \r
+   TCHAR ipAddrText[16];\r
        DbgPrintf(6, _T("CDP(%s [%d]): remote IP address %s"), node->Name(), node->Id(), IpToStr(remoteIp, ipAddrText));\r
        Node *remoteNode = FindNodeByIP(remoteIp);\r
        if (remoteNode == NULL)\r
@@ -46,36 +46,34 @@ static DWORD CDPTopoHandler(DWORD dwVersion, SNMP_Variable *var, SNMP_Transport
        }\r
        DbgPrintf(6, _T("CDP(%s [%d]): remote node is %s [%d]"), node->Name(), node->Id(), remoteNode->Name(), remoteNode->Id());\r
 \r
-   SNMP_ObjectId *pOid = var->GetName();\r
-   SNMPConvertOIDToText(pOid->Length() - 14, (DWORD *)&(pOid->GetValue())[14], szSuffix, MAX_OID_LEN * 4);\r
-\r
-       // Get interfaces\r
-   SNMP_PDU *pRqPDU = new SNMP_PDU(SNMP_GET_REQUEST, SnmpNewRequestId(), dwVersion);\r
-\r
-       _tcscpy(szOid, _T(".1.3.6.1.4.1.9.9.23.1.2.1.1.7"));    // Remote port name\r
-   _tcscat(szOid, szSuffix);\r
-       pRqPDU->bindVariable(new SNMP_Variable(szOid));\r
+       // Get additional info for current record\r
+       DWORD newOid[128];\r
+       memcpy(newOid, oid->GetValue(), oid->Length() * sizeof(DWORD));\r
+   SNMP_PDU *pRqPDU = new SNMP_PDU(SNMP_GET_REQUEST, SnmpNewRequestId(), snmpVersion);\r
 \r
-       _tcscpy(szOid, _T(".1.3.6.1.4.1.9.9.23.1.2.1.1.1"));    // Local interface index\r
-   _tcscat(szOid, szSuffix);\r
-       pRqPDU->bindVariable(new SNMP_Variable(szOid));\r
+       newOid[13] = 7; // cdpCacheDevicePort\r
+       pRqPDU->bindVariable(new SNMP_Variable(newOid, oid->Length()));\r
 \r
    SNMP_PDU *pRespPDU;\r
-   DWORD rcc = pTransport->doRequest(pRqPDU, &pRespPDU, g_dwSNMPTimeout, 3);\r
+   DWORD rcc = transport->doRequest(pRqPDU, &pRespPDU, g_dwSNMPTimeout, 3);\r
        delete pRqPDU;\r
 \r
        if (rcc == SNMP_ERR_SUCCESS)\r
    {\r
-               if (pRespPDU->getNumVariables() >= 2)\r
+               if (pRespPDU->getNumVariables() >= 1)\r
                {\r
                        TCHAR ifName[MAX_CONNECTOR_NAME] = _T("");\r
                        pRespPDU->getVariable(0)->GetValueAsString(ifName, 64);\r
+                       DbgPrintf(6, _T("CDP(%s [%d]): remote port is \"%s\""), node->Name(), node->Id(), ifName);\r
                        Interface *ifRemote = remoteNode->findInterface(ifName);\r
                        if (ifRemote != NULL)\r
                        {\r
+                               DbgPrintf(6, _T("CDP(%s [%d]): remote interface object is %s [%d]"), node->Name(), node->Id(), ifRemote->Name(), ifRemote->Id());\r
+               \r
                                LL_NEIGHBOR_INFO info;\r
 \r
-                               info.ifLocal = pRespPDU->getVariable(1)->GetValueAsUInt();\r
+                               // Index for cdpCacheTable is cdpCacheIfIndex, cdpCacheDeviceIndex\r
+                               info.ifLocal = oid->GetValue()[oid->Length() - 2];\r
                                info.ifRemote = ifRemote->getIfIndex();\r
                                info.objectId = remoteNode->Id();\r
                                info.isPtToPt = true;\r
index 430ccc5..91d919e 100644 (file)
@@ -398,7 +398,7 @@ DWORD ImportConfig(Config *config, DWORD flags)
                        NetObjInsert(object, TRUE);\r
                        object->AddParent(g_pTemplateRoot);\r
                        g_pTemplateRoot->AddChild(object);\r
-                       object->Unhide();\r
+                       object->unhide();\r
                }\r
        }\r
 \r
index 7bf29d8..1d1bbc9 100644 (file)
@@ -30,6 +30,7 @@
 Interface::Interface()
           : NetObj()
 {
+       nx_strncpy(m_description, m_szName, MAX_DB_STRING);
    m_dwIpNetMask = 0;
    m_dwIfIndex = 0;
    m_dwIfType = IFTYPE_OTHER;
@@ -38,6 +39,8 @@ Interface::Interface()
        m_portNumber = 0;
        m_peerNodeId = 0;
        m_peerInterfaceId = 0;
+       m_dot1xPaeAuthState = 0;
+       m_dot1xBackendAuthState = 0;
    m_qwLastDownEventId = 0;
        m_bSyntheticMask = false;
        m_iPendingStatus = -1;
@@ -54,6 +57,7 @@ Interface::Interface(DWORD dwAddr, DWORD dwNetMask, bool bSyntheticMask)
           : NetObj()
 {
    _tcscpy(m_szName, _T("unknown"));
+   _tcscpy(m_description, _T("unknown"));
    m_dwIpAddr = dwAddr;
    m_dwIpNetMask = dwNetMask;
    m_dwIfIndex = 1;
@@ -63,6 +67,8 @@ Interface::Interface(DWORD dwAddr, DWORD dwNetMask, bool bSyntheticMask)
        m_portNumber = 0;
        m_peerNodeId = 0;
        m_peerInterfaceId = 0;
+       m_dot1xPaeAuthState = 0;
+       m_dot1xBackendAuthState = 0;
    memset(m_bMacAddr, 0, MAC_ADDR_LENGTH);
    m_qwLastDownEventId = 0;
        m_bSyntheticMask = bSyntheticMask;
@@ -77,19 +83,22 @@ Interface::Interface(DWORD dwAddr, DWORD dwNetMask, bool bSyntheticMask)
 // Constructor for normal interface object
 //
 
-Interface::Interface(const TCHAR *szName, DWORD dwIndex, DWORD dwAddr, DWORD dwNetMask, DWORD dwType)
+Interface::Interface(const TCHAR *name, const TCHAR *descr, DWORD index, DWORD ipAddr, DWORD ipNetMask, DWORD ifType)
           : NetObj()
 {
-   nx_strncpy(m_szName, szName, MAX_OBJECT_NAME);
-   m_dwIfIndex = dwIndex;
-   m_dwIfType = dwType;
-   m_dwIpAddr = dwAddr;
-   m_dwIpNetMask = dwNetMask;
+   nx_strncpy(m_szName, name, MAX_OBJECT_NAME);
+   nx_strncpy(m_description, descr, MAX_DB_STRING);
+   m_dwIfIndex = index;
+   m_dwIfType = ifType;
+   m_dwIpAddr = ipAddr;
+   m_dwIpNetMask = ipNetMask;
        m_bridgePortNumber = 0;
        m_slotNumber = 0;
        m_portNumber = 0;
        m_peerNodeId = 0;
        m_peerInterfaceId = 0;
+       m_dot1xPaeAuthState = 0;
+       m_dot1xBackendAuthState = 0;
    memset(m_bMacAddr, 0, MAC_ADDR_LENGTH);
    m_qwLastDownEventId = 0;
        m_bSyntheticMask = false;
@@ -128,7 +137,7 @@ BOOL Interface::CreateFromDB(DWORD dwId)
 
    _sntprintf(szQuery, 256, _T("SELECT ip_addr,ip_netmask,if_type,if_index,node_id,")
                             _T("mac_addr,synthetic_mask,required_polls,bridge_port,phy_slot,")
-                                                                        _T("phy_port,peer_node_id,peer_if_id FROM interfaces WHERE id=%d"), dwId);
+                                                                        _T("phy_port,peer_node_id,peer_if_id,description FROM interfaces WHERE id=%d"), dwId);
    hResult = DBSelect(g_hCoreDB, szQuery);
    if (hResult == NULL)
       return FALSE;     // Query failed
@@ -148,6 +157,7 @@ BOOL Interface::CreateFromDB(DWORD dwId)
                m_portNumber = DBGetFieldULong(hResult, 0, 10);
                m_peerNodeId = DBGetFieldULong(hResult, 0, 11);
                m_peerInterfaceId = DBGetFieldULong(hResult, 0, 12);
+               DBGetField(hResult, 0, 13, m_description, MAX_DB_STRING);
 
       // Link interface to node
       if (!m_bIsDeleted)
@@ -189,7 +199,7 @@ BOOL Interface::CreateFromDB(DWORD dwId)
 
 BOOL Interface::SaveToDB(DB_HANDLE hdb)
 {
-   TCHAR szQuery[1024], szMacStr[16], szIpAddr[16], szNetMask[16];
+   TCHAR szQuery[2048], szMacStr[16], szIpAddr[16], szNetMask[16];
    BOOL bNewObject = TRUE;
    Node *pNode;
    DWORD dwNodeId;
@@ -220,26 +230,28 @@ BOOL Interface::SaveToDB(DB_HANDLE hdb)
    // Form and execute INSERT or UPDATE query
    BinToStr(m_bMacAddr, MAC_ADDR_LENGTH, szMacStr);
    if (bNewObject)
-      _sntprintf(szQuery, 1024, _T("INSERT INTO interfaces (id,ip_addr,")
+      _sntprintf(szQuery, 2048, _T("INSERT INTO interfaces (id,ip_addr,")
                        _T("ip_netmask,node_id,if_type,if_index,mac_addr,synthetic_mask,required_polls,")
-                                                         _T("bridge_port,phy_slot,phy_port,peer_node_id,peer_if_id) ")
-                       _T("VALUES (%d,'%s','%s',%d,%d,%d,'%s',%d,%d,%d,%d,%d,%d,%d)"),
+                                                         _T("bridge_port,phy_slot,phy_port,peer_node_id,peer_if_id,description) ")
+                       _T("VALUES (%d,'%s','%s',%d,%d,%d,'%s',%d,%d,%d,%d,%d,%d,%d,%s)"),
               m_dwId, IpToStr(m_dwIpAddr, szIpAddr),
               IpToStr(m_dwIpNetMask, szNetMask), dwNodeId,
                                  m_dwIfType, m_dwIfIndex, szMacStr, m_bSyntheticMask ? 1 : 0,
                                  m_iRequiredPollCount, (int)m_bridgePortNumber, (int)m_slotNumber,
-                                 (int)m_portNumber, (int)m_peerNodeId, (int)m_peerInterfaceId);
+                                 (int)m_portNumber, (int)m_peerNodeId, (int)m_peerInterfaceId,
+                                 DBPrepareString(hdb, m_description));
    else
-      _sntprintf(szQuery, 1024, _T("UPDATE interfaces SET ip_addr='%s',ip_netmask='%s',")
+      _sntprintf(szQuery, 2048, _T("UPDATE interfaces SET ip_addr='%s',ip_netmask='%s',")
                        _T("node_id=%d,if_type=%d,if_index=%d,")
                        _T("mac_addr='%s',synthetic_mask=%d,")
                                                          _T("required_polls=%d,bridge_port=%d,phy_slot=%d,phy_port=%d,")
-                                                         _T("peer_node_id=%d,peer_if_id=%d WHERE id=%d"),
+                                                         _T("peer_node_id=%d,peer_if_id=%d,description=%s WHERE id=%d"),
               IpToStr(m_dwIpAddr, szIpAddr),
               IpToStr(m_dwIpNetMask, szNetMask), dwNodeId,
                                  m_dwIfType, m_dwIfIndex, szMacStr, m_bSyntheticMask ? 1 : 0,
                                  m_iRequiredPollCount, (int)m_bridgePortNumber, (int)m_slotNumber,
-                                 (int)m_portNumber, (int)m_peerNodeId, (int)m_peerInterfaceId, m_dwId);
+                                 (int)m_portNumber, (int)m_peerNodeId, (int)m_peerInterfaceId,
+                                 DBPrepareString(hdb, m_description), m_dwId);
    DBQuery(hdb, szQuery);
 
    // Save access list
@@ -433,6 +445,7 @@ void Interface::CreateMessage(CSCPMessage *pMsg)
        pMsg->SetVariable(VID_REQUIRED_POLLS, (WORD)m_iRequiredPollCount);
        pMsg->SetVariable(VID_PEER_NODE_ID, m_peerNodeId);
        pMsg->SetVariable(VID_PEER_INTERFACE_ID, m_peerInterfaceId);
+       pMsg->SetVariable(VID_DESCRIPTION, m_description);
 }
 
 
index cfc8d24..0c4edea 100644 (file)
@@ -1140,13 +1140,13 @@ void NetObj::AddChildNodesToList(DWORD *pdwNumNodes, Node ***pppNodeList, DWORD
 // Hide object and all its childs
 //
 
-void NetObj::Hide(void)
+void NetObj::hide()
 {
    DWORD i;
 
    LockChildList(FALSE);
    for(i = 0; i < m_dwChildCount; i++)
-      m_pChildList[i]->Hide();
+      m_pChildList[i]->hide();
    UnlockChildList();
 
        LockData();
@@ -1159,7 +1159,7 @@ void NetObj::Hide(void)
 // Unhide object and all its childs
 //
 
-void NetObj::Unhide(void)
+void NetObj::unhide()
 {
    DWORD i;
 
@@ -1170,7 +1170,7 @@ void NetObj::Unhide(void)
 
    LockChildList(FALSE);
    for(i = 0; i < m_dwChildCount; i++)
-      m_pChildList[i]->Unhide();
+      m_pChildList[i]->unhide();
    UnlockChildList();
 }
 
index 81f0a6b..b035061 100644 (file)
@@ -613,7 +613,7 @@ Interface *Node::findInterface(DWORD dwIndex, DWORD dwHostAddr)
 
 
 //
-// Find interface by name
+// Find interface by name or description
 // Returns pointer to interface object or NULL if appropriate interface couldn't be found
 //
 
@@ -627,7 +627,7 @@ Interface *Node::findInterface(const TCHAR *name)
       if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
       {
          pInterface = (Interface *)m_pChildList[i];
-                       if (!_tcsicmp(pInterface->Name(), name))
+                       if (!_tcsicmp(pInterface->Name(), name) || !_tcsicmp(pInterface->getDescription(), name))
          {
             UnlockChildList();
             return pInterface;
@@ -799,7 +799,7 @@ BOOL Node::isMyIP(DWORD dwIpAddr)
 // Create new interface
 //
 
-void Node::createNewInterface(DWORD dwIpAddr, DWORD dwNetMask, const TCHAR *name, 
+void Node::createNewInterface(DWORD dwIpAddr, DWORD dwNetMask, const TCHAR *name, const TCHAR *descr,
                               DWORD dwIndex, DWORD dwType, BYTE *pbMacAddr, DWORD bridgePort, 
                                                                                DWORD slot, DWORD port)
 {
@@ -865,7 +865,7 @@ void Node::createNewInterface(DWORD dwIpAddr, DWORD dwNetMask, const TCHAR *name
 
    // Create interface object
    if (name != NULL)
-      pInterface = new Interface(name, dwIndex, dwIpAddr, dwNetMask, dwType);
+               pInterface = new Interface(name, (descr != NULL) ? descr : name, dwIndex, dwIpAddr, dwNetMask, dwType);
    else
       pInterface = new Interface(dwIpAddr, dwNetMask, bSyntheticMask);
    if (pbMacAddr != NULL)
@@ -878,7 +878,7 @@ void Node::createNewInterface(DWORD dwIpAddr, DWORD dwNetMask, const TCHAR *name
    NetObjInsert(pInterface, TRUE);
    addInterface(pInterface);
    if (!m_bIsHidden)
-      pInterface->Unhide();
+      pInterface->unhide();
    PostEvent(EVENT_INTERFACE_ADDED, m_dwId, "dsaad", pInterface->Id(),
              pInterface->Name(), pInterface->IpAddr(),
              pInterface->getIpNetMask(), pInterface->getIfIndex());
@@ -1919,6 +1919,10 @@ BOOL Node::updateInterfaceConfiguration(DWORD dwRqId, DWORD dwNetMask)
                   {
                      pInterface->setName(ifInfo->szName);
                   }
+                  if (_tcscmp(ifInfo->szDescription, pInterface->getDescription()))
+                  {
+                     pInterface->setDescription(ifInfo->szDescription);
+                  }
                                                if (ifInfo->dwBridgePortNumber != pInterface->getBridgePortNumber())
                                                {
                                                        pInterface->setBridgePortNumber(ifInfo->dwBridgePortNumber);
@@ -1949,6 +1953,7 @@ BOOL Node::updateInterfaceConfiguration(DWORD dwRqId, DWORD dwNetMask)
             createNewInterface(ifInfo->dwIpAddr, 
                                ifInfo->dwIpNetMask,
                                ifInfo->szName,
+                                                                                ifInfo->szDescription,
                                ifInfo->dwIndex,
                                ifInfo->dwType,
                                ifInfo->bMacAddr,
@@ -1991,7 +1996,7 @@ BOOL Node::updateInterfaceConfiguration(DWORD dwRqId, DWORD dwNetMask)
 
             // Create pseudo interface for NAT
             ConfigReadStr(_T("NATAdapterName"), szBuffer, MAX_OBJECT_NAME, _T("NetXMS NAT Adapter"));
-            createNewInterface(m_dwIpAddr, 0, szBuffer, 0x7FFFFFFF, IFTYPE_NETXMS_NAT_ADAPTER);
+            createNewInterface(m_dwIpAddr, 0, szBuffer, szBuffer, 0x7FFFFFFF, IFTYPE_NETXMS_NAT_ADAPTER);
             hasChanges = TRUE;
          }
       }
@@ -3799,15 +3804,20 @@ nxmap_ObjList *Node::BuildL2Topology(DWORD *pdwStatus)
 // Topology poller
 //
 
-void Node::topologyPoll(int nPoller)
+void Node::topologyPoll(ClientSession *pSession, DWORD dwRqId, int nPoller)
 {
        pollerLock();
+   m_pPollRequestor = pSession;
 
+   SendPollerMsg(dwRqId, _T("Starting topology poll for node %s\r\n"), m_szName);
        DbgPrintf(4, _T("Started topology poll for node %s [%d]"), m_szName, m_dwId);
 
        LinkLayerNeighbors *nbs = BuildLinkLayerNeighborList(this);
        if (nbs != NULL)
        {
+               SendPollerMsg(dwRqId, POLLER_INFO _T("Link layer topology retrieved (%d connections found)\r\n"), nbs->getSize());
+               DbgPrintf(4, _T("Link layer topology retrieved for node %s [%d] (%d connections found)"), m_szName, (int)m_dwId, nbs->getSize());
+
                MutexLock(m_mutexTopoAccess, INFINITE);
                if (m_linkLayerNeighbors != NULL)
                        m_linkLayerNeighbors->decRefCount();
@@ -3815,23 +3825,37 @@ void Node::topologyPoll(int nPoller)
                MutexUnlock(m_mutexTopoAccess);
 
                // Walk through interfaces and update peers
+          SendPollerMsg(dwRqId, _T("Updating peer information on interfaces\r\n"));
                for(int i = 0; i < nbs->getSize(); i++)
                {
                        LL_NEIGHBOR_INFO *ni = nbs->getConnection(i);
                        NetObj *object = FindObjectById(ni->objectId);
                        if ((object != NULL) && (object->Type() == OBJECT_NODE))
                        {
+                               DbgPrintf(5, _T("Node::topologyPoll(%s [%d]): found peer node %s [%d], localIfIndex=%d remoteIfIndex=%d"),
+                                         m_szName, m_dwId, object->Name(), object->Id(), ni->ifLocal, ni->ifRemote);
                                Interface *ifLocal = findInterface(ni->ifLocal, INADDR_ANY);
                                Interface *ifRemote = ((Node *)object)->findInterface(ni->ifRemote, INADDR_ANY);
+                               DbgPrintf(5, _T("Node::topologyPoll(%s [%d]): localIfObject=%s remoteIfObject=%s"), m_szName, m_dwId, 
+                                         (ifLocal != NULL) ? ifLocal->Name() : _T("(null)"),
+                                         (ifRemote != NULL) ? ifRemote->Name() : _T("(null)"));
                                if ((ifLocal != NULL) && (ifRemote != NULL))
                                {
                                        ifLocal->setPeer(ni->objectId, ifRemote->Id());
                                        ifRemote->setPeer(m_dwId, ifLocal->Id());
+                                       SendPollerMsg(dwRqId, _T("   Local interface %s linked to remote interface %s:%s\r\n"),
+                                                     ifLocal->Name(), object->Name(), ifRemote->Name());
+                                       DbgPrintf(5, _T("Local interface %s:%s linked to remote interface %s:%s"),
+                                                 m_szName, ifLocal->Name(), object->Name(), ifRemote->Name());
                                }
                        }
                }
-
-               DbgPrintf(4, _T("Link layer topology retrieved for node %s [%d]"), m_szName, m_dwId);
+          SendPollerMsg(dwRqId, _T("Link layer topology processed\r\n"));
+               DbgPrintf(4, _T("Link layer topology processed for node %s [%d]"), m_szName, m_dwId);
+       }
+       else
+       {
+          SendPollerMsg(dwRqId, POLLER_ERROR _T("Link layer topology retrieved\r\n"));
        }
 
        ForwardingDatabase *fdb = GetSwitchForwardingDatabase(this);
@@ -3841,7 +3865,15 @@ void Node::topologyPoll(int nPoller)
        m_fdb = fdb;
        MutexUnlock(m_mutexTopoAccess);
        if (fdb != NULL)
+       {
                DbgPrintf(4, _T("Switch forwarding database retrieved for node %s [%d]"), m_szName, m_dwId);
+          SendPollerMsg(dwRqId, POLLER_INFO _T("Switch forwarding database retrieved\r\n"));
+       }
+       else
+       {
+               DbgPrintf(4, _T("Failed to get switch forwarding database from node %s [%d]"), m_szName, m_dwId);
+          SendPollerMsg(dwRqId, POLLER_WARNING _T("Failed to get switch forwarding database\r\n"));
+       }
 
        if (m_driver != NULL)
        {
@@ -3850,6 +3882,7 @@ void Node::topologyPoll(int nPoller)
                MutexLock(m_mutexTopoAccess, INFINITE);
                if (vlanList != NULL)
                {
+                  SendPollerMsg(dwRqId, POLLER_INFO _T("VLAN list successfully retrieved from node\r\n"));
                        DbgPrintf(4, _T("VLAN list retrieved from node %s [%d]"), m_szName, m_dwId);
                        if (m_vlans != NULL)
                                m_vlans->decRefCount();
@@ -3857,6 +3890,7 @@ void Node::topologyPoll(int nPoller)
                }
                else
                {
+                  SendPollerMsg(dwRqId, POLLER_WARNING _T("Cannot get VLAN list\r\n"));
                        DbgPrintf(4, _T("Cannot retrieve VLAN list from node %s [%d]"), m_szName, m_dwId);
                        if (m_vlans != NULL)
                                m_vlans->decRefCount();
@@ -3875,9 +3909,13 @@ void Node::topologyPoll(int nPoller)
                UnlockData();
        }
 
+   SendPollerMsg(dwRqId, _T("Finished topology poll for node %s\r\n"), m_szName);
+
        m_tLastTopologyPoll = time(NULL);
    m_dwDynamicFlags &= ~NDF_QUEUED_FOR_TOPOLOGY_POLL;
        pollerUnlock();
+
+       DbgPrintf(4, _T("Finished topology poll for node %s [%d]"), m_szName, m_dwId);
 }
 
 
@@ -4034,6 +4072,11 @@ void Node::updateInterfaceNames(ClientSession *pSession, DWORD dwRqId)
                      pInterface->setName(pIfList->get(j)->szName);
                                                        SendPollerMsg(dwRqId, POLLER_WARNING _T("   Name of interface %d changed to %s\r\n"), pInterface->getIfIndex(), pIfList->get(j)->szName);
                   }
+                  if (_tcscmp(pIfList->get(j)->szDescription, pInterface->getDescription()))
+                  {
+                     pInterface->setDescription(pIfList->get(j)->szDescription);
+                                                       SendPollerMsg(dwRqId, POLLER_WARNING _T("   Description of interface %d changed to %s\r\n"), pInterface->getIfIndex(), pIfList->get(j)->szDescription);
+                  }
                   break;
                }
             }
index af14d06..243f13b 100644 (file)
@@ -179,7 +179,7 @@ Node *PollNewNode(DWORD dwIpAddr, DWORD dwNetMask, DWORD dwCreationFlags,
    {
       pNode->setMgmtStatus(FALSE);
    }
-   pNode->Unhide();
+   pNode->unhide();
    PostEvent(EVENT_NODE_ADDED, pNode->Id(), NULL);
 
    // Add default DCIs
index 16aa56d..1ccf2a2 100644 (file)
@@ -549,6 +549,28 @@ Interface NXCORE_EXPORTABLE *FindInterfaceByMAC(const BYTE *macAddr)
 
 
 //
+// Find interface by description
+//
+
+Interface NXCORE_EXPORTABLE *FindInterfaceByDescription(const TCHAR *description)
+{
+   Interface *pInterface = NULL;
+   RWLockReadLock(g_rwlockIdIndex, INFINITE);
+       for(DWORD i = 0; i < g_dwIdIndexSize; i++)
+       {
+               if ((((NetObj *)g_pIndexById[i].pObject)->Type() == OBJECT_INTERFACE) &&
+                   !_tcscmp(description, ((Interface *)g_pIndexById[i].pObject)->getDescription()))
+               {
+                       pInterface = ((Interface *)g_pIndexById[i].pObject);
+                       break;
+               }
+       }
+   RWLockUnlock(g_rwlockIdIndex);
+   return pInterface;
+}
+
+
+//
 // Find node by LLDP ID
 //
 
@@ -1005,8 +1027,8 @@ BOOL LoadObjects()
          }
          else     // Object load failed
          {
-            delete pInterface;
             nxlog_write(MSG_INTERFACE_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
+            delete pInterface;
          }
       }
       DBFreeResult(hResult);
@@ -1317,7 +1339,7 @@ BOOL LoadObjects()
                g_pTemplateRoot->AddChild(pTemplate);
                pTemplate->AddParent(g_pTemplateRoot);
                pTemplate->CalculateCompoundStatus();
-               pTemplate->Unhide();
+               pTemplate->unhide();
        }
        pTemplate->ValidateSystemTemplate();
 
index ed32186..7a953c0 100644 (file)
@@ -70,7 +70,7 @@ static void CreateManagementNode(DWORD ipAddr, DWORD netMask)
    NetObjInsert(pNode, TRUE);
        pNode->setName(GetLocalHostName(buffer, 256));
    pNode->configurationPoll(NULL, 0, -1, netMask);
-   pNode->Unhide();
+   pNode->unhide();
    g_dwMgmtNode = pNode->Id();   // Set local management node ID
    PostEvent(EVENT_NODE_ADDED, pNode->Id(), NULL);
 
@@ -545,7 +545,7 @@ static THREAD_RESULT THREAD_CALL TopologyPoller(void *arg)
 
       _sntprintf(szBuffer, MAX_OBJECT_NAME + 64, _T("poll: %s [%d]"), node->Name(), node->Id());
       SetPollerState((long)arg, szBuffer);
-               node->topologyPoll(CAST_FROM_POINTER(arg, int));
+               node->topologyPoll(NULL, 0, CAST_FROM_POINTER(arg, int));
       node->DecRefCount();
    }
    SetPollerState((long)arg, _T("finished"));
index 0cdb769..f92d6ed 100644 (file)
@@ -1839,7 +1839,7 @@ void ClientSession::sendAllObjects(CSCPMessage *pRequest)
    for(i = 0; i < g_dwIdIndexSize; i++)
       if ((((NetObj *)g_pIndexById[i].pObject)->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ)) &&
           (((NetObj *)g_pIndexById[i].pObject)->TimeStamp() >= dwTimeStamp) &&
-          (!(((NetObj *)g_pIndexById[i].pObject)->IsHidden())))
+          (!(((NetObj *)g_pIndexById[i].pObject)->isHidden())))
       {
          ((NetObj *)g_pIndexById[i].pObject)->CreateMessage(&msg);
          if (m_dwFlags & CSF_SYNC_OBJECT_COMMENTS)
@@ -1895,7 +1895,7 @@ void ClientSession::sendSelectedObjects(CSCPMessage *pRequest)
       if ((object != NULL) && 
                    object->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ) &&
           (object->TimeStamp() >= dwTimeStamp) &&
-          !object->IsHidden())
+          !object->isHidden())
       {
          object->CreateMessage(&msg);
          if (m_dwFlags & CSF_SYNC_OBJECT_COMMENTS)
@@ -3837,7 +3837,7 @@ void ClientSession::createObject(CSCPMessage *pRequest)
                                                if (pszComments != NULL)
                                                        pObject->setComments(pszComments);
 
-                  pObject->Unhide();
+                  pObject->unhide();
                   msg.SetVariable(VID_RCC, RCC_SUCCESS);
                   msg.SetVariable(VID_OBJECT_ID, pObject->Id());
                }
@@ -4467,6 +4467,7 @@ void ClientSession::ForcedNodePoll(CSCPMessage *pRequest)
       if ((pObject->Type() == OBJECT_NODE) &&
           ((pData->iPollType == POLL_STATUS) ||
                          (pData->iPollType == POLL_CONFIGURATION) ||
+                         (pData->iPollType == POLL_TOPOLOGY) ||
                          (pData->iPollType == POLL_INTERFACE_NAMES)))
       {
          // Check access rights
@@ -4540,6 +4541,9 @@ void ClientSession::pollerThread(Node *pNode, int iPollType, DWORD dwRqId)
                        pNode->setRecheckCapsFlag();
          pNode->configurationPoll(this, dwRqId, -1, 0);
          break;
+      case POLL_TOPOLOGY:
+         pNode->topologyPoll(this, dwRqId, -1);
+         break;
       case POLL_INTERFACE_NAMES:
          pNode->updateInterfaceNames(this, dwRqId);
          break;
index be4c600..4974237 100644 (file)
@@ -287,9 +287,9 @@ public:
 
    void Delete(BOOL bIndexLocked);     // Prepare object for deletion
 
-   BOOL IsHidden(void) { return m_bIsHidden; }
-   void Hide(void);
-   void Unhide(void);
+   BOOL isHidden() { return m_bIsHidden; }
+   void hide();
+   void unhide();
 
    virtual BOOL SaveToDB(DB_HANDLE hdb);
    virtual BOOL DeleteFromDB(void);
@@ -488,6 +488,7 @@ public:
 class NXCORE_EXPORTABLE Interface : public NetObj
 {
 protected:
+       TCHAR m_description[MAX_DB_STRING];     // Interface description - value of ifDescr for SNMP, equals to name for NetXMS agent
    DWORD m_dwIfIndex;
    DWORD m_dwIfType;
    DWORD m_dwIpNetMask;
@@ -497,8 +498,8 @@ protected:
        DWORD m_portNumber;                             // Vendor/device specific port number
        DWORD m_peerNodeId;                             // ID of peer node object, or 0 if unknown
        DWORD m_peerInterfaceId;                // ID of peer interface object, or 0 if unknown
-       WORD m_dot1xPaeAuthState;
-       WORD m_dot1xBackendAuthState;
+       WORD m_dot1xPaeAuthState;               // 802.1x port auth state
+       WORD m_dot1xBackendAuthState;   // 802.1x backend auth state
    QWORD m_qwLastDownEventId;
        bool m_bSyntheticMask;
        int m_iPendingStatus;
@@ -508,7 +509,7 @@ protected:
 public:
    Interface();
    Interface(DWORD dwAddr, DWORD dwNetMask, bool bSyntheticMask);
-   Interface(const TCHAR *szName, DWORD dwIndex, DWORD dwAddr, DWORD dwNetMask, DWORD dwType);
+   Interface(const TCHAR *name, const TCHAR *descr, DWORD index, DWORD ipAddr, DWORD ipNetMask, DWORD ifType);
    virtual ~Interface();
 
    virtual int Type() { return OBJECT_INTERFACE; }
@@ -526,6 +527,7 @@ public:
        DWORD getPortNumber() { return m_portNumber; }
        DWORD getPeerNodeId() { return m_peerNodeId; }
        DWORD getPeerInterfaceId() { return m_peerInterfaceId; }
+       const TCHAR *getDescription() { return m_description; }
    const BYTE *getMacAddr() { return m_bMacAddr; }
        bool isSyntheticMask() { return m_bSyntheticMask; }
    bool isFake() { return (m_dwIfIndex == 1) && 
@@ -543,6 +545,7 @@ public:
    void setSlotNumber(DWORD slot) { m_slotNumber = slot; Modify(); }
    void setPortNumber(DWORD port) { m_portNumber = port; Modify(); }
        void setPeer(DWORD nodeId, DWORD ifId) { m_peerNodeId = nodeId; m_peerInterfaceId = ifId; Modify(); }
+   void setDescription(const TCHAR *descr) { nx_strncpy(m_description, descr, MAX_DB_STRING); Modify(); }
 
    void StatusPoll(ClientSession *pSession, DWORD dwRqId, Queue *pEventQueue,
                        BOOL bClusterSync, SNMP_Transport *pTransport);
@@ -754,7 +757,7 @@ public:
    BOOL isDown() { return m_dwDynamicFlags & NDF_UNREACHABLE ? TRUE : FALSE; }
 
    void addInterface(Interface *pInterface) { AddChild(pInterface); pInterface->AddParent(this); }
-   void createNewInterface(DWORD dwAddr, DWORD dwNetMask, const TCHAR *name = NULL, 
+   void createNewInterface(DWORD dwAddr, DWORD dwNetMask, const TCHAR *name = NULL, const TCHAR *descr = NULL,
                            DWORD dwIndex = 0, DWORD dwType = 0, BYTE *pbMacAddr = NULL, DWORD bridgePort = 0,
                                                                        DWORD slot = 0, DWORD port = 0);
    void deleteInterface(Interface *pInterface);
@@ -783,7 +786,7 @@ public:
    void setDiscoveryPollTimeStamp();
    void statusPoll(ClientSession *pSession, DWORD dwRqId, int nPoller);
    void configurationPoll(ClientSession *pSession, DWORD dwRqId, int nPoller, DWORD dwNetMask);
-       void topologyPoll(int nPoller);
+       void topologyPoll(ClientSession *pSession, DWORD dwRqId, int nPoller);
        void updateInterfaceNames(ClientSession *pSession, DWORD dwRqId);
    void updateRoutingTable();
    bool isReadyForStatusPoll();
@@ -1411,6 +1414,7 @@ Node NXCORE_EXPORTABLE *FindNodeByIP(DWORD dwAddr);
 Node NXCORE_EXPORTABLE *FindNodeByMAC(const BYTE *macAddr);
 Node NXCORE_EXPORTABLE *FindNodeByLLDPId(const TCHAR *lldpId);
 Interface NXCORE_EXPORTABLE *FindInterfaceByMAC(const BYTE *macAddr);
+Interface NXCORE_EXPORTABLE *FindInterfaceByDescription(const TCHAR *description);
 Subnet NXCORE_EXPORTABLE *FindSubnetByIP(DWORD dwAddr);
 Subnet NXCORE_EXPORTABLE *FindSubnetForNode(DWORD dwNodeAddr);
 DWORD NXCORE_EXPORTABLE FindLocalMgmtNode(void);
index eb9cb8c..c8ab126 100644 (file)
@@ -203,7 +203,8 @@ typedef struct
 
 typedef struct
 {
-   TCHAR szName[MAX_DB_STRING];
+   TCHAR szName[MAX_DB_STRING];                        // Interface display name
+       TCHAR szDescription[MAX_DB_STRING];     // Value of ifDescr MIB variable for SNMP agents
    DWORD dwIndex;
    DWORD dwType;
        DWORD dwBridgePortNumber;
index 9732746..ec116c7 100644 (file)
@@ -623,8 +623,9 @@ InterfaceList *AgentConnection::getInterfaceList()
             pBuf = pChar + 1;
          }
 
-         // Name
-         nx_strncpy(iface.szName, pBuf, MAX_OBJECT_NAME - 1);
+         // Name (set description to name)
+         nx_strncpy(iface.szName, pBuf, MAX_DB_STRING);
+                       nx_strncpy(iface.szDescription, pBuf, MAX_DB_STRING);
 
                        pIfList->add(&iface);
       }
index c307f24..08f2b29 100644 (file)
@@ -171,6 +171,11 @@ InterfaceList *NetworkDeviceDriver::getInterfaces(SNMP_Transport *snmp, StringMa
       {\r
                        NX_INTERFACE_INFO *iface = pIfList->get(i);\r
 \r
+                       // Get interface description\r
+             _sntprintf(szOid, 128, _T(".1.3.6.1.2.1.2.2.1.2.%d"), iface->dwIndex);\r
+             if (SnmpGet(snmp->getSnmpVersion(), snmp, szOid, NULL, 0, iface->szDescription, MAX_DB_STRING, 0) != SNMP_ERR_SUCCESS)\r
+                break;\r
+\r
          // Get interface alias if needed\r
          if (useAliases > 0)\r
          {\r
@@ -186,14 +191,12 @@ InterfaceList *NetworkDeviceDriver::getInterfaces(SNMP_Transport *snmp, StringMa
                                }\r
          }\r
 \r
-                       // Try to get interface name from ifXTable, if unsuccessful or disabled, use ifTable\r
+                       // Try to get interface name from ifXTable, if unsuccessful or disabled, use ifDescr from ifTable\r
          _sntprintf(szOid, 128, _T(".1.3.6.1.2.1.31.1.1.1.1.%d"), iface->dwIndex);\r
          if (!useIfXTable ||\r
                                 (SnmpGet(snmp->getSnmpVersion(), snmp, szOid, NULL, 0, szBuffer, 256, 0) != SNMP_ERR_SUCCESS))\r
          {\r
-                     _sntprintf(szOid, 128, _T(".1.3.6.1.2.1.2.2.1.2.%d"), iface->dwIndex);\r
-                     if (SnmpGet(snmp->getSnmpVersion(), snmp, szOid, NULL, 0, szBuffer, 256, 0) != SNMP_ERR_SUCCESS)\r
-                        break;\r
+                     nx_strncpy(szBuffer, iface->szDescription, 256);\r
                   }\r
 \r
                        // Build full interface object name\r
index 3f2688f..ff9d72c 100644 (file)
@@ -235,14 +235,19 @@ static void CheckNodes()
                m_iNumErrors++;
                if (GetYesNo(_T("\rMissing node object %d properties. Create?"), dwId))
                {
+                                               uuid_t guid;
+
+                                               uuid_generate(guid);
                   _sntprintf(szQuery, 1024, 
-                             _T("INSERT INTO object_properties (object_id,name,")
-                             _T("status,is_deleted,inherit_access_rights,")
+                             _T("INSERT INTO object_properties (object_id,guid,name,")
+                             _T("status,is_deleted,is_system,inherit_access_rights,")
                              _T("last_modified,status_calc_alg,status_prop_alg,")
                              _T("status_fixed_val,status_shift,status_translation,")
-                             _T("status_single_threshold,status_thresholds) VALUES ")
-                             _T("(%d,'lost_node_%d',5,0,1,0,0,0,0,0,0,0,'00000000')"),
-                             dwId, dwId);
+                             _T("status_single_threshold,status_thresholds,location_type,")
+                                                                         _T("latitude,longitude,image) VALUES ")
+                             _T("(%d,'%s','lost_node_%d',5,0,0,1,0,0,0,0,0,0,0,'00000000',0,")
+                                                                         _T("'0.000000','0.000000','00000000-0000-0000-0000-000000000000')"),
+                                                                         (int)dwId, guid, (int)dwId);
                   if (SQLQuery(szQuery))
                      m_iNumFixes++;
                }
@@ -342,14 +347,19 @@ static void CheckComponents(const TCHAR *pszDisplayName, const TCHAR *pszTable)
                m_iNumErrors++;
                if (GetYesNo(_T("\rMissing %s object %d properties. Create?"), pszDisplayName, dwId))
                {
+                                               uuid_t guid;
+
+                                               uuid_generate(guid);
                   _sntprintf(szQuery, 1024, 
-                             _T("INSERT INTO object_properties (object_id,name,")
-                             _T("status,is_deleted,inherit_access_rights,")
+                             _T("INSERT INTO object_properties (object_id,guid,name,")
+                             _T("status,is_deleted,is_system,inherit_access_rights,")
                              _T("last_modified,status_calc_alg,status_prop_alg,")
                              _T("status_fixed_val,status_shift,status_translation,")
-                             _T("status_single_threshold,status_thresholds) VALUES ")
-                             _T("(%d,'lost_%s_%d',5,0,1,0,0,0,0,0,0,0,'00000000')"),
-                             dwId, pszDisplayName, dwId);
+                             _T("status_single_threshold,status_thresholds,location_type,")
+                                                                         _T("latitude,longitude,image) VALUES ")
+                             _T("(%d,'%s','lost_%s_%d',5,0,0,1,0,0,0,0,0,0,0,'00000000',0,")
+                                                                         _T("'0.000000','0.000000','00000000-0000-0000-0000-000000000000')"),
+                                                                         (int)dwId, guid, pszDisplayName, (int)dwId);
                   if (SQLQuery(szQuery))
                      m_iNumFixes++;
                   szName[0] = 0;
index 5c9fdda..6b4e117 100644 (file)
@@ -249,6 +249,24 @@ static BOOL SetColumnNullable(const TCHAR *table, const TCHAR *column, const TCH
 
 
 //
+// Upgrade from V224 to V225
+//
+
+static BOOL H_UpgradeFromV224(int currVersion, int newVersion)
+{
+       static TCHAR batch[] = 
+               _T("ALTER TABLE interfaces ADD description varchar(255)\n")
+               _T("UPDATE interfaces SET description=''\n")
+               _T("<END>");
+
+       CHK_EXEC(SQLBatch(batch));
+
+       CHK_EXEC(SQLQuery(_T("UPDATE metadata SET var_value='225' WHERE var_name='SchemaVersion'")));
+   return TRUE;
+}
+
+
+//
 // Upgrade from V223 to V224
 //
 
@@ -5141,6 +5159,7 @@ static struct
        { 221, 222, H_UpgradeFromV221 },
        { 222, 223, H_UpgradeFromV222 },
        { 223, 224, H_UpgradeFromV223 },
+       { 224, 225, H_UpgradeFromV224 },
    { 0, NULL }
 };