implemented support of nodes with dynamic IPs
authorVictor Kirhenshtein <victor@netxms.org>
Mon, 5 Sep 2011 15:54:51 +0000 (15:54 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Mon, 5 Sep 2011 15:54:51 +0000 (15:54 +0000)
23 files changed:
ChangeLog
include/netxms-version.h
include/netxmsdb.h
include/nms_cscp.h
include/nxclapi.h
include/nxevent.h
include/nxsnmp.h
sql/events.in
src/java/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java
src/java/netxms-client/src/main/java/org/netxms/client/NXCObjectCreationData.java
src/java/netxms-client/src/main/java/org/netxms/client/NXCObjectModificationData.java
src/java/netxms-client/src/main/java/org/netxms/client/NXCSession.java
src/java/netxms-client/src/main/java/org/netxms/client/objects/Node.java
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/CreateNode.java
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/dialogs/CreateNodeDialog.java
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/Communication.java
src/java/netxms-eclipse/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/elements/GeneralInfo.java
src/libnxcl/objects.cpp
src/server/core/node.cpp
src/server/core/session.cpp
src/server/include/nms_objects.h
src/server/libnxsrv/ndd.cpp
src/server/tools/nxdbmgr/upgrade.cpp

index 34583b3..9cc4552 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,9 @@
 - Implemented named parameters for events
 - Added integration script for HP EVA disk arrays
 - Added driver for Netscreen firewalls
+- Usage of DNS names instead of IP address for defining primary
+  communication address is now supported (for better support of nodes with
+  dynamic IPs)
 - New MIBs added: ATM-TC-MIB, CISCO-BRIDGE-EXT-MIB, CISCO-IF-EXTENSION-MIB,
   CISCO-L2L3-INTERFACE-CONFIG-MIB, CISCO-PRIVATE-VLAN-MIB,
   CISCO-VLAN-IFTABLE-RELATIONSHIP-MIB, DVMRP-MIB, IGMP-MIB, IPV6-TC,
index 143a194..35168b6 100644 (file)
@@ -39,7 +39,7 @@
 // Current client-server protocol version
 //
 
-#define CLIENT_PROTOCOL_VERSION     27
+#define CLIENT_PROTOCOL_VERSION     28
 
 
 #endif
index b25fffb..ce6fc91 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxmsdb_h
 #define _netxmsdb_h
 
-#define DB_FORMAT_VERSION   238
+#define DB_FORMAT_VERSION   239
 
 #endif
index f762596..b58e3db 100644 (file)
@@ -875,6 +875,7 @@ typedef struct
 #define VID_UPTIME_DAY              ((DWORD)394)
 #define VID_UPTIME_WEEK             ((DWORD)395)
 #define VID_UPTIME_MONTH            ((DWORD)396)
+#define VID_PRIMARY_NAME            ((DWORD)397)
 
 // Base variabe for single threshold in message
 #define VID_THRESHOLD_BASE          ((DWORD)0x00800000)
index 59e28b1..7edd610 100644 (file)
@@ -528,6 +528,7 @@ enum
 #define OBJ_UPDATE_AUTO_APPLY       ((QWORD)_ULL(0x0800000000))
 #define OBJ_UPDATE_AUTO_BIND        ((QWORD)_ULL(0x1000000000))
 #define OBJ_UPDATE_SNMP_PORT        ((QWORD)_ULL(0x2000000000))
+#define OBJ_UPDATE_PRIMARY_NAME     ((QWORD)_ULL(0x4000000000))
 
 
 //
@@ -1092,6 +1093,7 @@ struct __nxc_object_iface
 
 struct __nxc_object_node
 {
+       TCHAR szPrimaryName[MAX_DNS_NAME];
    DWORD dwFlags;
        DWORD dwRuntimeFlags;
    DWORD dwNodeType;
@@ -1251,6 +1253,7 @@ typedef struct
    QWORD qwFlags;
    DWORD dwObjectId;
    const TCHAR *pszName;
+       const TCHAR *pszPrimaryName;
    int iAgentPort;
    int iAuthType;
    const TCHAR *pszSecret;
@@ -1518,6 +1521,7 @@ typedef struct
    {
       struct
       {
+                       const TCHAR *pszPrimaryName;
          DWORD dwIpAddr;
          DWORD dwNetMask;
          DWORD dwCreationFlags;
index 1f09157..dd1bbfc 100644 (file)
 #define EVENT_DCI_UNSUPPORTED             53
 #define EVENT_DCI_DISABLED                54
 #define EVENT_DCI_ACTIVE                  55
+#define EVENT_IP_ADDRESS_CHANGED          56
 
 #define EVENT_SNMP_UNMATCHED_TRAP         500
 #define EVENT_SNMP_COLD_START             501
index 5c24b01..12b6fed 100644 (file)
@@ -645,9 +645,9 @@ private:
    DWORD m_dwBufferPos;
    BYTE *m_pBuffer;
 
-   DWORD preParsePDU(void);
+   DWORD preParsePDU();
    int recvData(DWORD dwTimeout, struct sockaddr *pSender, socklen_t *piAddrSize);
-   void clearBuffer(void);
+   void clearBuffer();
 
 public:
    SNMP_UDPTransport();
index 8f9d8a7..9531eb3 100644 (file)
@@ -608,6 +608,17 @@ INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description)
                '   4) DCI Origin code#0D#0A' CONCAT
                '   5) DCI Origin name'
        );
+INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
+       (
+               EVENT_IP_ADDRESS_CHANGED, 'SYS_IP_ADDRESS_CHANGED',
+               EVENT_SEVERITY_WARNING, 1,
+               'Primary IP address changed from %2 to %1',
+               'Generated when primary IP address changed (usually because of primary name change or DNS change).#0D#0A' CONCAT
+               'Parameters:#0D#0A' CONCAT
+               '   1) New IP address#0D#0A' CONCAT
+               '   2) Old IP address#0D#0A' CONCAT
+               '   3) Primary host name'
+       );
 
 
 /*
index 9fdec1b..fb2e1f2 100644 (file)
@@ -679,6 +679,7 @@ public final class NXCPCodes
        public static final long VID_UPTIME_DAY              = 394;\r
        public static final long VID_UPTIME_WEEK             = 395;\r
        public static final long VID_UPTIME_MONTH            = 396;\r
+       public static final long VID_PRIMARY_NAME            = 397;\r
 \r
        public static final long VID_ACL_USER_BASE            = 0x00001000L;\r
        public static final long VID_ACL_USER_LAST            = 0x00001FFFL;\r
index a203ce1..536954b 100644 (file)
@@ -41,6 +41,7 @@ public class NXCObjectCreationData
        private long parentId;\r
        private String comments;\r
        private int creationFlags;\r
+       private String primaryName;\r
        private InetAddress ipAddress;\r
        private InetAddress ipNetMask;\r
        private long agentProxyId;\r
@@ -78,6 +79,7 @@ public class NXCObjectCreationData
                {\r
                }\r
                \r
+               primaryName = null;\r
                comments = null;\r
                creationFlags = 0;\r
                agentProxyId = 0;\r
@@ -380,4 +382,20 @@ public class NXCObjectCreationData
        {\r
                this.linkedNodeId = linkedNodeId;\r
        }\r
+\r
+       /**\r
+        * @return the primaryName\r
+        */\r
+       public String getPrimaryName()\r
+       {\r
+               return primaryName;\r
+       }\r
+\r
+       /**\r
+        * @param primaryName the primaryName to set\r
+        */\r
+       public void setPrimaryName(String primaryName)\r
+       {\r
+               this.primaryName = primaryName;\r
+       }\r
 }\r
index c075cbd..ec9ac41 100644 (file)
@@ -88,10 +88,12 @@ public class NXCObjectModificationData
        public static final long MODIFY_IFXTABLE_POLICY    = 0x040000000000L;\r
        public static final long MODIFY_REPORT_DEFINITION  = 0x080000000000L;\r
        public static final long MODIFY_CLUSTER_RESOURCES  = 0x100000000000L;\r
+       public static final long MODIFY_PRIMARY_NAME       = 0x200000000000L;\r
        \r
        private long flags;             // Flags which indicates what object's data should be modified\r
        private long objectId;\r
        private String name;\r
+       private String primaryName;\r
        private AccessListElement[] acl;\r
        private boolean inheritAccessRights;\r
        private Map<String, String> customAttributes;\r
@@ -1127,4 +1129,21 @@ public class NXCObjectModificationData
                this.resourceList = resourceList;\r
                flags |= MODIFY_CLUSTER_RESOURCES;\r
        }\r
+\r
+       /**\r
+        * @return the primaryName\r
+        */\r
+       public String getPrimaryName()\r
+       {\r
+               return primaryName;\r
+       }\r
+\r
+       /**\r
+        * @param primaryName the primaryName to set\r
+        */\r
+       public void setPrimaryName(String primaryName)\r
+       {\r
+               this.primaryName = primaryName;\r
+               flags |= MODIFY_PRIMARY_NAME;\r
+       }\r
 }\r
index 25b7971..e1374a8 100644 (file)
@@ -137,7 +137,7 @@ public class NXCSession implements Session, ScriptLibraryManager, UserManager, S
 {\r
        // Various public constants\r
        public static final int DEFAULT_CONN_PORT = 4701;\r
-       public static final int CLIENT_PROTOCOL_VERSION = 27;\r
+       public static final int CLIENT_PROTOCOL_VERSION = 28;\r
 \r
        // Authentication types\r
        public static final int AUTH_TYPE_PASSWORD = 0;\r
@@ -2596,6 +2596,8 @@ public class NXCSession implements Session, ScriptLibraryManager, UserManager, S
                switch(data.getObjectClass())\r
                {\r
                        case GenericObject.OBJECT_NODE:\r
+                               if (data.getPrimaryName() != null)\r
+                                       msg.setVariable(NXCPCodes.VID_PRIMARY_NAME, data.getPrimaryName());\r
                                msg.setVariable(NXCPCodes.VID_IP_ADDRESS, data.getIpAddress());\r
                                msg.setVariable(NXCPCodes.VID_IP_NETMASK, data.getIpNetMask());\r
                                msg.setVariableInt32(NXCPCodes.VID_CREATION_FLAGS, data.getCreationFlags());\r
@@ -2956,6 +2958,11 @@ public class NXCSession implements Session, ScriptLibraryManager, UserManager, S
                        }\r
                }\r
                \r
+               if ((flags & NXCObjectModificationData.MODIFY_PRIMARY_NAME) != 0)\r
+               {\r
+                       msg.setVariable(NXCPCodes.VID_PRIMARY_NAME, data.getPrimaryName());\r
+               }\r
+               \r
                sendMessage(msg);\r
                waitForRCC(msg.getMessageId());\r
        }\r
index 85e84a5..90f9cda 100644 (file)
@@ -75,6 +75,7 @@ public class Node extends GenericObject
        public static final int IFXTABLE_ENABLED        = 1;\r
        public static final int IFXTABLE_DISABLED       = 2;\r
        \r
+       private String primaryName;\r
        private int flags;\r
        private int runtimeFlags;\r
        private int nodeType;\r
@@ -112,6 +113,7 @@ public class Node extends GenericObject
        {\r
                super(msg, session);\r
 \r
+               primaryName = msg.getVariableAsString(NXCPCodes.VID_PRIMARY_NAME);\r
                flags = msg.getVariableAsInteger(NXCPCodes.VID_FLAGS);\r
                runtimeFlags = msg.getVariableAsInteger(NXCPCodes.VID_RUNTIME_FLAGS);\r
                nodeType = msg.getVariableAsInteger(NXCPCodes.VID_NODE_TYPE);\r
@@ -448,4 +450,12 @@ public class Node extends GenericObject
        {\r
                return ifXTablePolicy;\r
        }\r
+\r
+       /**\r
+        * @return the primaryName\r
+        */\r
+       public String getPrimaryName()\r
+       {\r
+               return primaryName;\r
+       }\r
 }\r
index 5d1a11b..0c3e6dc 100644 (file)
@@ -72,9 +72,9 @@ public class CreateNode implements IObjectActionDelegate
                        protected void runInternal(IProgressMonitor monitor) throws Exception\r
                        {\r
                                NXCSession session = (NXCSession)ConsoleSharedData.getSession();\r
-                               NXCObjectCreationData cd = new NXCObjectCreationData(GenericObject.OBJECT_NODE, dlg.getName(), parentId);\r
+                               NXCObjectCreationData cd = new NXCObjectCreationData(GenericObject.OBJECT_NODE, dlg.getObjectName(), parentId);\r
                                cd.setCreationFlags(dlg.getCreationFlags());\r
-                               cd.setIpAddress(dlg.getIpAddress());\r
+                               cd.setPrimaryName(dlg.getHostName());\r
                                cd.setAgentProxyId(dlg.getAgentProxy());\r
                                cd.setSnmpProxyId(dlg.getSnmpProxy());\r
                                cd.setZoneId(dlg.getZoneId());\r
@@ -84,7 +84,7 @@ public class CreateNode implements IObjectActionDelegate
                        @Override\r
                        protected String getErrorMessage()\r
                        {\r
-                               return "Cannot create node object \"" + dlg.getName() + "\"";\r
+                               return "Cannot create node object \"" + dlg.getObjectName() + "\"";\r
                        }\r
                }.start();\r
        }\r
index fca2d4e..5d0c439 100644 (file)
@@ -20,7 +20,6 @@ package org.netxms.ui.eclipse.objectmanager.dialogs;
 \r
 import java.net.Inet4Address;\r
 import java.net.InetAddress;\r
-import java.net.UnknownHostException;\r
 \r
 import org.eclipse.core.runtime.IProgressMonitor;\r
 import org.eclipse.jface.dialogs.Dialog;\r
@@ -56,8 +55,8 @@ public class CreateNodeDialog extends Dialog
 {\r
        private NXCSession session;\r
        \r
-       private LabeledText nameField;\r
-       private LabeledText ipAddrField;\r
+       private LabeledText objectNameField;\r
+       private LabeledText hostNameField;\r
        private Button checkUnmanaged;\r
        private Button checkDisableAgent;\r
        private Button checkDisableSNMP;\r
@@ -66,8 +65,8 @@ public class CreateNodeDialog extends Dialog
        private ObjectSelector snmpProxySelector;\r
        private ObjectSelector zoneSelector;\r
        \r
-       private String name;\r
-       private InetAddress ipAddress;\r
+       private String objectName;\r
+       private String hostName;\r
        private int creationFlags;\r
        private long agentProxy;\r
        private long snmpProxy;\r
@@ -107,14 +106,14 @@ public class CreateNodeDialog extends Dialog
                layout.marginWidth = WidgetHelper.DIALOG_WIDTH_MARGIN;\r
                dialogArea.setLayout(layout);\r
                \r
-               nameField = new LabeledText(dialogArea, SWT.NONE);\r
-               nameField.setLabel("Name");\r
-               nameField.getTextControl().setTextLimit(255);\r
+               objectNameField = new LabeledText(dialogArea, SWT.NONE);\r
+               objectNameField.setLabel("Name");\r
+               objectNameField.getTextControl().setTextLimit(255);\r
                GridData gd = new GridData();\r
                gd.horizontalAlignment = SWT.FILL;\r
                gd.grabExcessHorizontalSpace = true;\r
                gd.widthHint = 300;\r
-               nameField.setLayoutData(gd);\r
+               objectNameField.setLayoutData(gd);\r
                \r
                final Composite ipAddrGroup = new Composite(dialogArea, SWT.NONE);\r
                layout = new GridLayout();\r
@@ -127,13 +126,13 @@ public class CreateNodeDialog extends Dialog
                gd.grabExcessHorizontalSpace = true;\r
                ipAddrGroup.setLayoutData(gd);\r
                \r
-               ipAddrField = new LabeledText(ipAddrGroup, SWT.NONE);\r
-               ipAddrField.setLabel("Primary IP address");\r
-               ipAddrField.getTextControl().setTextLimit(255);\r
+               hostNameField = new LabeledText(ipAddrGroup, SWT.NONE);\r
+               hostNameField.setLabel("Primary host name or IP address");\r
+               hostNameField.getTextControl().setTextLimit(255);\r
                gd = new GridData();\r
                gd.horizontalAlignment = SWT.FILL;\r
                gd.grabExcessHorizontalSpace = true;\r
-               ipAddrField.setLayoutData(gd);\r
+               hostNameField.setLayoutData(gd);\r
                \r
                final Button resolve = new Button(ipAddrGroup, SWT.PUSH);\r
                resolve.setText("&Resolve");\r
@@ -211,19 +210,19 @@ public class CreateNodeDialog extends Dialog
        @Override\r
        protected void okPressed()\r
        {\r
-               try\r
+               // Validate primary name\r
+               hostName = hostNameField.getText().trim();\r
+               if (hostName.isEmpty())\r
+                       hostName = objectNameField.getText().trim();\r
+               if (!hostName.matches("^([A-Za-z0-9\\-]+\\.)*[A-Za-z0-9\\-]+$"))\r
                {\r
-                       ipAddress = InetAddress.getByName(ipAddrField.getText());\r
-               }\r
-               catch(UnknownHostException e)\r
-               {\r
-                       MessageDialog.openWarning(getShell(), "Warning", "Invalid IP address or host name");\r
+                       MessageDialog.openWarning(getShell(), "Warning", "String \"" + hostName + "\" is not a valid host name or IP address. Please enter valid host name or IP address as primary host name");\r
                        return;\r
                }\r
                \r
-               name = nameField.getText().trim();\r
-               if (name.isEmpty())\r
-                       name = ipAddrField.getText();\r
+               objectName = objectNameField.getText().trim();\r
+               if (objectName.isEmpty())\r
+                       objectName = hostName;\r
                \r
                creationFlags = 0;\r
                if (checkUnmanaged.getSelection())\r
@@ -255,7 +254,7 @@ public class CreateNodeDialog extends Dialog
         */\r
        private void resolveName()\r
        {\r
-               final String name = nameField.getText();\r
+               final String name = objectNameField.getText();\r
                new ConsoleJob("Resolve host name", null, Activator.PLUGIN_ID, null) {\r
                        @Override\r
                        protected void runInternal(IProgressMonitor monitor) throws Exception\r
@@ -265,7 +264,7 @@ public class CreateNodeDialog extends Dialog
                                        @Override\r
                                        public void run()\r
                                        {\r
-                                               ipAddrField.setText(addr.getHostAddress());\r
+                                               hostNameField.setText(addr.getHostAddress());\r
                                        }\r
                                });\r
                        }\r
@@ -281,17 +280,17 @@ public class CreateNodeDialog extends Dialog
        /**\r
         * @return the name\r
         */\r
-       public String getName()\r
+       public String getObjectName()\r
        {\r
-               return name;\r
+               return objectName;\r
        }\r
 \r
        /**\r
-        * @return the ipAddress\r
+        * @return the hostName\r
         */\r
-       public InetAddress getIpAddress()\r
+       public String getHostName()\r
        {\r
-               return ipAddress;\r
+               return hostName;\r
        }\r
 \r
        /**\r
index d3ad59d..9a43ab1 100644 (file)
@@ -21,6 +21,8 @@ package org.netxms.ui.eclipse.objectmanager.propertypages;
 import org.eclipse.core.runtime.IProgressMonitor;\r
 import org.eclipse.jface.dialogs.MessageDialog;\r
 import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
 import org.eclipse.swt.events.SelectionEvent;\r
 import org.eclipse.swt.events.SelectionListener;\r
 import org.eclipse.swt.layout.FormAttachment;\r
@@ -39,7 +41,6 @@ import org.netxms.client.NXCObjectModificationData;
 import org.netxms.client.NXCSession;\r
 import org.netxms.client.objects.Node;\r
 import org.netxms.ui.eclipse.jobs.ConsoleJob;\r
-import org.netxms.ui.eclipse.objectbrowser.widgets.IPAddressSelector;\r
 import org.netxms.ui.eclipse.objectbrowser.widgets.ObjectSelector;\r
 import org.netxms.ui.eclipse.objectmanager.Activator;\r
 import org.netxms.ui.eclipse.shared.ConsoleSharedData;\r
@@ -53,7 +54,7 @@ import org.netxms.ui.eclipse.widgets.LabeledText;
 public class Communication extends PropertyPage\r
 {\r
        private Node node;\r
-       private IPAddressSelector primaryIpAddress;\r
+       private LabeledText primaryName;\r
        private LabeledText agentPort;\r
        private LabeledText agentSharedSecret;\r
        private Combo agentAuthMethod;\r
@@ -67,6 +68,7 @@ public class Communication extends PropertyPage
        private LabeledText snmpAuthName;\r
        private LabeledText snmpAuthPassword;\r
        private LabeledText snmpPrivPassword;\r
+       private boolean primaryNameChanged = false;\r
        \r
        /* (non-Javadoc)\r
         * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)\r
@@ -92,13 +94,20 @@ public class Communication extends PropertyPage
                GridLayout generalGroupLayout = new GridLayout();\r
                generalGroup.setLayout(generalGroupLayout);\r
                \r
-               primaryIpAddress = new IPAddressSelector(generalGroup, SWT.NONE);\r
-               primaryIpAddress.setLabel("Primary IP address");\r
-               primaryIpAddress.setNode(node);\r
+               primaryName = new LabeledText(generalGroup, SWT.NONE);\r
+               primaryName.setLabel("Primary host name");\r
+               primaryName.setText(node.getPrimaryName());\r
                gd = new GridData();\r
                gd.horizontalAlignment = SWT.FILL;\r
                gd.grabExcessHorizontalSpace = true;\r
-               primaryIpAddress.setLayoutData(gd);\r
+               primaryName.setLayoutData(gd);\r
+               primaryName.getTextControl().addModifyListener(new ModifyListener() {\r
+                       @Override\r
+                       public void modifyText(ModifyEvent e)\r
+                       {\r
+                               primaryNameChanged = true;\r
+                       }\r
+               });\r
                \r
                // Agent\r
                Group agentGroup = new Group(dialogArea, SWT.NONE);\r
@@ -327,12 +336,22 @@ public class Communication extends PropertyPage
         */\r
        protected boolean applyChanges(final boolean isApply)\r
        {\r
-               if (isApply)\r
-                       setValid(false);\r
-               \r
                final NXCObjectModificationData md = new NXCObjectModificationData(node.getObjectId());\r
                \r
-               md.setPrimaryIpAddress(primaryIpAddress.getAddress());\r
+               if (primaryNameChanged)\r
+               {\r
+                       // Validate primary name\r
+                       final String hostName = primaryName.getText().trim();\r
+                       if (!hostName.matches("^([A-Za-z0-9\\-]+\\.)*[A-Za-z0-9\\-]+$"))\r
+                       {\r
+                               MessageDialog.openWarning(getShell(), "Warning", "String \"" + hostName + "\" is not a valid host name or IP address. Please enter valid host name or IP address as primary host name");\r
+                               return false;\r
+                       }\r
+                       md.setPrimaryName(hostName);\r
+               }\r
+                       \r
+               if (isApply)\r
+                       setValid(false);\r
                \r
                try\r
                {\r
index 607a011..f756744 100644 (file)
@@ -79,6 +79,7 @@ public class GeneralInfo extends TableElement
                                Node node = (Node)object;\r
                                if (((NXCSession)ConsoleSharedData.getSession()).isZoningEnabled())\r
                                        addPair("Zone ID", Long.toString(node.getZoneId()));\r
+                               addPair("Primary Host Name", node.getPrimaryName());\r
                                addPair("Primary IP Address", node.getPrimaryIP().getHostAddress());\r
                                if (node.hasAgent())\r
                                        addPair("NetXMS Agent Version", node.getAgentVersion());\r
index 7722a63..2d6ac6a 100644 (file)
@@ -279,6 +279,7 @@ static NXC_OBJECT *NewObjectFromMsg(CSCPMessage *pMsg)
                        pObject->iface.wRequiredPollCount = pMsg->GetVariableShort(VID_REQUIRED_POLLS);
          break;
       case OBJECT_NODE:
+                       pMsg->GetVariableStr(VID_PRIMARY_NAME, pObject->node.szPrimaryName, MAX_DNS_NAME);
          pObject->node.dwFlags = pMsg->GetVariableLong(VID_FLAGS);
          pObject->node.dwRuntimeFlags = pMsg->GetVariableLong(VID_RUNTIME_FLAGS);
          pObject->node.dwNodeType = pMsg->GetVariableLong(VID_NODE_TYPE);
@@ -842,6 +843,8 @@ DWORD LIBNXCL_EXPORTABLE NXCModifyObject(NXC_SESSION hSession, NXC_OBJECT_UPDATE
    msg.SetVariable(VID_OBJECT_ID, pUpdate->dwObjectId);
    if (pUpdate->qwFlags & OBJ_UPDATE_NAME)
       msg.SetVariable(VID_OBJECT_NAME, pUpdate->pszName);
+   if (pUpdate->qwFlags & OBJ_UPDATE_PRIMARY_NAME)
+      msg.SetVariable(VID_PRIMARY_NAME, pUpdate->pszPrimaryName);
    if (pUpdate->qwFlags & OBJ_UPDATE_AGENT_PORT)
       msg.SetVariable(VID_AGENT_PORT, (WORD)pUpdate->iAgentPort);
    if (pUpdate->qwFlags & OBJ_UPDATE_AGENT_AUTH)
@@ -1057,6 +1060,8 @@ DWORD LIBNXCL_EXPORTABLE NXCCreateObject(NXC_SESSION hSession,
    switch(pCreateInfo->iClass)
    {
       case OBJECT_NODE:
+                       if (pCreateInfo->cs.node.pszPrimaryName != NULL)
+                               msg.SetVariable(VID_PRIMARY_NAME, pCreateInfo->cs.node.pszPrimaryName);
          msg.SetVariable(VID_IP_ADDRESS, pCreateInfo->cs.node.dwIpAddr);
          msg.SetVariable(VID_IP_NETMASK, pCreateInfo->cs.node.dwNetMask);
          msg.SetVariable(VID_CREATION_FLAGS, pCreateInfo->cs.node.dwCreationFlags);
index 94dcea0..bf23f3a 100644 (file)
@@ -27,8 +27,7 @@
 // Node class default constructor
 //
 
-Node::Node()
-     :Template()
+Node::Node() : Template()
 {
        m_primaryName[0] = 0;
    m_iStatus = STATUS_UNKNOWN;
@@ -89,8 +88,7 @@ Node::Node()
 // Constructor for new node object
 //
 
-Node::Node(DWORD dwAddr, DWORD dwFlags, DWORD dwProxyNode, DWORD dwSNMPProxy, DWORD dwZone)
-     :Template()
+Node::Node(DWORD dwAddr, DWORD dwFlags, DWORD dwProxyNode, DWORD dwSNMPProxy, DWORD dwZone) : Template()
 {
        IpToStr(dwAddr, m_primaryName);
    m_iStatus = STATUS_UNKNOWN;
@@ -1333,6 +1331,28 @@ void Node::checkAgentPolicyBinding(AgentConnection *conn)
 
 
 //
+// Update primary IP address from primary name
+//
+
+void Node::updatePrimaryIpAddr()
+{
+       if (m_primaryName[0] == 0)
+               return;
+
+       DWORD ipAddr = ntohl(ResolveHostName(m_primaryName));
+       if ((ipAddr != m_dwIpAddr) && (ipAddr != INADDR_ANY) && (ipAddr != INADDR_NONE))
+       {
+               TCHAR buffer1[32], buffer2[32];
+
+               DbgPrintf(4, _T("IP address for node %s [%d] changed from %s to %s"), 
+                       m_szName, (int)m_dwId, IpToStr(m_dwIpAddr, buffer1), IpToStr(ipAddr, buffer2));
+               PostEvent(EVENT_IP_ADDRESS_CHANGED, m_dwId, "aa", ipAddr, m_dwIpAddr);
+               m_dwIpAddr = ipAddr;
+       }
+}
+
+
+//
 // Walker callback for print MIB
 //
 
@@ -1387,6 +1407,8 @@ void Node::configurationPoll(ClientSession *pSession, DWORD dwRqId,
    }
    else
    {
+               updatePrimaryIpAddr();
+
       // Check node's capabilities
       SetPollerInfo(nPoller, _T("capability check"));
       SendPollerMsg(dwRqId, _T("Checking node's capabilities...\r\n"));
@@ -2710,6 +2732,7 @@ void Node::queueItemsForPolling(Queue *pPollerQueue)
 void Node::CreateMessage(CSCPMessage *pMsg)
 {
    Template::CreateMessage(pMsg);
+       pMsg->SetVariable(VID_PRIMARY_NAME, m_primaryName);
    pMsg->SetVariable(VID_FLAGS, m_dwFlags);
    pMsg->SetVariable(VID_RUNTIME_FLAGS, m_dwDynamicFlags);
    pMsg->SetVariable(VID_AGENT_PORT, m_wAgentPort);
@@ -2778,8 +2801,21 @@ DWORD Node::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked)
       }
 
       m_dwIpAddr = dwIpAddr;
+
+               // Update primary name if it is not set with the same message
+               if (!pRequest->IsVariableExist(VID_PRIMARY_NAME))
+               {
+                       IpToStr(m_dwIpAddr, m_primaryName);
+               }
    }
 
+   // Change primary IP address
+   if (pRequest->IsVariableExist(VID_PRIMARY_NAME))
+   {
+               pRequest->GetVariableStr(VID_PRIMARY_NAME, m_primaryName, MAX_DNS_NAME);
+               m_dwDynamicFlags |= NDF_FORCE_CONFIGURATION_POLL | NDF_RECHECK_CAPABILITIES;
+       }
+
    // Poller node ID
    if (pRequest->IsVariableExist(VID_POLLER_NODE_ID))
    {
index f6c0e11..8ff20e1 100644 (file)
@@ -3744,7 +3744,7 @@ void ClientSession::createObject(CSCPMessage *pRequest)
    CSCPMessage msg;
    NetObj *pObject, *pParent;
    int iClass, iServiceType;
-   TCHAR szObjectName[MAX_OBJECT_NAME];
+   TCHAR szObjectName[MAX_OBJECT_NAME], nodePrimaryName[MAX_DNS_NAME];
    TCHAR *pszRequest, *pszResponse, *pszComments;
    DWORD dwIpAddr, zoneId, nodeId;
    WORD wIpProto, wIpPort;
@@ -3761,7 +3761,16 @@ void ClientSession::createObject(CSCPMessage *pRequest)
    pParent = FindObjectById(pRequest->GetVariableLong(VID_PARENT_ID));
    if (iClass == OBJECT_NODE)
    {
-      dwIpAddr = pRequest->GetVariableLong(VID_IP_ADDRESS);
+               if (pRequest->IsVariableExist(VID_PRIMARY_NAME))
+               {
+                       pRequest->GetVariableStr(VID_PRIMARY_NAME, nodePrimaryName, MAX_DNS_NAME);
+                       dwIpAddr = ntohl(ResolveHostName(nodePrimaryName));
+               }
+               else
+               {
+                       dwIpAddr = pRequest->GetVariableLong(VID_IP_ADDRESS);
+                       IpToStr(dwIpAddr, nodePrimaryName);
+               }
       if ((pParent == NULL) && (dwIpAddr != 0))
       {
          pParent = FindSubnetForNode(zoneId, dwIpAddr);
@@ -3805,6 +3814,10 @@ void ClientSession::createObject(CSCPMessage *pRequest)
                                                                                                                         pRequest->GetVariableLong(VID_SNMP_PROXY),
                                                                                                                         (pParent != NULL) ? ((pParent->Type() == OBJECT_CLUSTER) ? (Cluster *)pParent : NULL) : NULL,
                                                                                                                         zoneId);
+                                                               if (pObject != NULL)
+                                                               {
+                                                                       ((Node *)pObject)->setPrimaryName(nodePrimaryName);
+                                                               }
                                                                break;
                                                        case OBJECT_CONTAINER:
                                                                pObject = new Container(szObjectName, pRequest->GetVariableLong(VID_CATEGORY));
index 0120cab..0ce33b2 100644 (file)
@@ -760,6 +760,7 @@ protected:
    void checkInterfaceNames(InterfaceList *pIfList);
        void checkSubnetBinding(InterfaceList *pIfList);
        void checkAgentPolicyBinding(AgentConnection *conn);
+       void updatePrimaryIpAddr();
 
        void ApplySystemTemplates();
        void ApplyUserTemplates();
@@ -814,6 +815,7 @@ public:
                                                                        DWORD slot = 0, DWORD port = 0, bool physPort = false);
    void deleteInterface(Interface *pInterface);
 
+       void setPrimaryName(const TCHAR *name) { nx_strncpy(m_primaryName, name, MAX_DNS_NAME); }
    void changeIPAddress(DWORD dwIpAddr);
        void changeZone(DWORD newZone);
 
index 77ecfb6..242e93f 100644 (file)
@@ -96,8 +96,7 @@ static DWORD HandlerIndex(DWORD dwVersion, SNMP_Variable *pVar, SNMP_Transport *
 // Handler for enumerating IP addresses\r
 //\r
 \r
-static DWORD HandlerIpAddr(DWORD dwVersion, SNMP_Variable *pVar,\r
-                           SNMP_Transport *pTransport, void *pArg)\r
+static DWORD HandlerIpAddr(DWORD dwVersion, SNMP_Variable *pVar, SNMP_Transport *pTransport, void *pArg)\r
 {\r
    DWORD dwIndex, dwNetMask, dwNameLen, dwResult;\r
    DWORD oidName[MAX_OID_LEN];\r
@@ -107,7 +106,15 @@ static DWORD HandlerIpAddr(DWORD dwVersion, SNMP_Variable *pVar,
    oidName[dwNameLen - 5] = 3;  // Retrieve network mask for this IP\r
    dwResult = SnmpGet(dwVersion, pTransport, NULL, oidName, dwNameLen, &dwNetMask, sizeof(DWORD), 0);\r
    if (dwResult != SNMP_ERR_SUCCESS)\r
-      return dwResult;\r
+       {\r
+               TCHAR buffer[1024];\r
+               DbgPrintf(6, _T("NetworkDeviceDriver::getInterfaces(%p): SNMP GET %s failed (error %d)"), \r
+                       pTransport, SNMPConvertOIDToText(dwNameLen, oidName, buffer, 1024), (int)dwResult);\r
+               // Continue walk even if we get error for some IP address\r
+               // For example, some Cisco ASA versions reports IP when walking, but does not\r
+               // allow to SNMP GET appropriate entry\r
+      return SNMP_ERR_SUCCESS;\r
+       }\r
 \r
    oidName[dwNameLen - 5] = 2;  // Retrieve interface index for this IP\r
    dwResult = SnmpGet(dwVersion, pTransport, NULL, oidName, dwNameLen, &dwIndex, sizeof(DWORD), 0);\r
@@ -116,6 +123,7 @@ static DWORD HandlerIpAddr(DWORD dwVersion, SNMP_Variable *pVar,
                InterfaceList *ifList = (InterfaceList *)pArg;\r
 \r
                for(int i = 0; i < ifList->getSize(); i++)\r
+               {\r
          if (ifList->get(i)->dwIndex == dwIndex)\r
          {\r
             if (ifList->get(i)->dwIpAddr != 0)\r
@@ -135,7 +143,15 @@ static DWORD HandlerIpAddr(DWORD dwVersion, SNMP_Variable *pVar,
                                }\r
             break;\r
          }\r
+               }\r
    }\r
+       else\r
+       {\r
+               TCHAR buffer[1024];\r
+               DbgPrintf(6, _T("NetworkDeviceDriver::getInterfaces(%p): SNMP GET %s failed (error %d)"), \r
+                       pTransport, SNMPConvertOIDToText(dwNameLen, oidName, buffer, 1024), (int)dwResult);\r
+               dwResult = SNMP_ERR_SUCCESS;    // continue walk\r
+       }\r
    return dwResult;\r
 }\r
 \r
@@ -154,10 +170,15 @@ InterfaceList *NetworkDeviceDriver::getInterfaces(SNMP_Transport *snmp, StringMa
    InterfaceList *pIfList = NULL;\r
    BOOL bSuccess = FALSE;\r
 \r
+       DbgPrintf(6, _T("NetworkDeviceDriver::getInterfaces(%p,%d,%s)"), snmp, useAliases, useIfXTable ? _T("true") : _T("false"));\r
+\r
    // Get number of interfaces\r
        if (SnmpGet(snmp->getSnmpVersion(), snmp, _T(".1.3.6.1.2.1.2.1.0"), NULL, 0,\r
                 &iNumIf, sizeof(LONG), 0) != SNMP_ERR_SUCCESS)\r
+       {\r
+               DbgPrintf(6, _T("NetworkDeviceDriver::getInterfaces(%p): SNMP GET .1.3.6.1.2.1.2.1.0 failed"), snmp);\r
       return NULL;\r
+       }\r
 \r
        // Some devices may return completely insane values here\r
        // (for example, DLink DGS-3612 can return negative value)\r
@@ -274,13 +295,22 @@ InterfaceList *NetworkDeviceDriver::getInterfaces(SNMP_Transport *snmp, StringMa
       {\r
          bSuccess = TRUE;\r
       }\r
+               else\r
+               {\r
+                       DbgPrintf(6, _T("NetworkDeviceDriver::getInterfaces(%p): SNMP WALK .1.3.6.1.2.1.4.20.1.1 failed"), snmp);\r
+               }\r
    }\r
+       else\r
+       {\r
+               DbgPrintf(6, _T("NetworkDeviceDriver::getInterfaces(%p): SNMP WALK .1.3.6.1.2.1.2.2.1.1 failed"), snmp);\r
+       }\r
 \r
    if (!bSuccess)\r
    {\r
       delete_and_null(pIfList);\r
    }\r
 \r
+       DbgPrintf(6, _T("NetworkDeviceDriver::getInterfaces(%p): completed, ifLIst=%p"), snmp, pIfList);\r
    return pIfList;\r
 }\r
 \r
index 77bf3e4..cc77b93 100644 (file)
@@ -253,6 +253,23 @@ static BOOL SetColumnNullable(const TCHAR *table, const TCHAR *column, const TCH
 
 
 //
+// Upgrade from V238 to V239
+//
+
+static BOOL H_UpgradeFromV238(int currVersion, int newVersion)
+{
+       CHK_EXEC(SQLQuery(
+               _T("INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES ")
+               _T("(56,'SYS_IP_ADDRESS_CHANGED',1,1,'Primary IP address changed from %2 to %1',")
+               _T("'Generated when primary IP address changed (usually because of primary name change or DNS change).#0D#0A")
+               _T("Parameters:#0D#0A   1) New IP address#0D#0A   2) Old IP address#0D#0A   3) Primary host name')")));
+
+       CHK_EXEC(SQLQuery(_T("UPDATE metadata SET var_value='239' WHERE var_name='SchemaVersion'")));
+   return TRUE;
+}
+
+
+//
 // Upgrade from V237 to V238
 //
 
@@ -5572,6 +5589,7 @@ static struct
        { 235, 236, H_UpgradeFromV235 },
        { 236, 237, H_UpgradeFromV236 },
        { 237, 238, H_UpgradeFromV237 },
+       { 238, 239, H_UpgradeFromV238 },
    { 0, NULL }
 };