implemented "expected state" functionality for interfaces; individual poll count...
authorVictor Kirhenshtein <victor@netxms.org>
Fri, 13 Apr 2012 15:45:00 +0000 (15:45 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Fri, 13 Apr 2012 15:45:00 +0000 (15:45 +0000)
33 files changed:
.gitattributes
ChangeLog
include/netxms-version.h
include/netxmsdb.h
include/nms_cscp.h
include/nxclapi.h
include/nxdbapi.h
include/nxevent.h
sql/events.in
sql/policy.in
sql/schema.in
src/db/libnxdb/session.cpp
src/java/netxms-base/src/main/java/org/netxms/base/NXCPCodes.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/Interface.java
src/java/netxms-eclipse/ObjectManager/plugin.xml
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/InterfacePolling.java [new file with mode: 0644]
src/java/netxms-eclipse/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/elements/GeneralInfo.java
src/libnetxms/tools.cpp
src/libnxcl/libnxcl.h
src/libnxcl/objects.cpp
src/server/core/interface.cpp
src/server/core/node.cpp
src/server/core/nxsl_classes.cpp
src/server/core/snmp.cpp
src/server/core/syncer.cpp
src/server/include/nms_core.h
src/server/include/nms_objects.h
src/server/libnxsrv/Makefile.am
src/server/libnxsrv/libnxsrv.vcproj
src/server/libnxsrv/license.cpp [deleted file]
src/server/tools/nxdbmgr/upgrade.cpp

index aca620a..76e2dbc 100644 (file)
@@ -1435,6 +1435,7 @@ src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/pr
 src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/ConditionScript.java -text
 src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/CustomAttributes.java -text
 src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/General.java -text
+src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/InterfacePolling.java -text
 src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/Location.java -text
 src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/MapAppearance.java -text
 src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/NetworkServicePolling.java -text
index a3dc5c8..7b34dcc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,8 @@
 * 1.2.0
 *
 
+- Number of polls required for status change can be set individually
+  for each interface
 - Added new NXSL functions and object properties for accessing topology information
 - New NXSL function FindObject
 - Java console:
index 11e8119..d86fdc4 100644 (file)
@@ -32,7 +32,7 @@
 #define NETXMS_VERSION_MINOR        2
 #define NETXMS_VERSION_BUILD        0
 #define NETXMS_VERSION_HOTFIX       0
-#define NETXMS_VERSION_STRING       _T("1.2.0-rc1")
+#define NETXMS_VERSION_STRING       _T("1.2.0")
 
 
 //
index 9db6518..ac363ca 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxmsdb_h
 #define _netxmsdb_h
 
-#define DB_FORMAT_VERSION   251
+#define DB_FORMAT_VERSION   252
 
 #endif
index f9e1840..9b32238 100644 (file)
@@ -888,6 +888,9 @@ typedef struct
 #define VID_DCOBJECT_TYPE           ((DWORD)411)
 #define VID_INSTANCE_COLUMN         ((DWORD)412)
 #define VID_DATA_COLUMN             ((DWORD)413)
+#define VID_ADMIN_STATE             ((DWORD)414)
+#define VID_OPER_STATE              ((DWORD)415)
+#define VID_EXPECTED_STATE          ((DWORD)416)
 
 // Base variabe for single threshold in message
 #define VID_THRESHOLD_BASE          ((DWORD)0x00800000)
index de5033c..a7d585b 100644 (file)
@@ -259,6 +259,36 @@ typedef void * NXC_SESSION;
 #define IF_EXCLUDE_FROM_TOPOLOGY 0x00000004
 #define IF_LOOPBACK              0x00000008
 #define IF_CREATED_MANUALLY      0x00000010
+#define IF_EXPECTED_STATE_MASK   0x30000000    /* 2-bit field holding expected interface state */
+
+
+//
+// Expected interface states
+//
+
+#define IF_EXPECTED_STATE_UP     0
+#define IF_EXPECTED_STATE_DOWN   1
+#define IF_EXPECTED_STATE_IGNORE 2
+
+
+//
+// Interface administrative states
+//
+
+#define IF_ADMIN_STATE_UNKNOWN   0
+#define IF_ADMIN_STATE_UP        1
+#define IF_ADMIN_STATE_DOWN      2
+#define IF_ADMIN_STATE_TESTING   3
+
+
+//
+// Interface operational states
+//
+
+#define IF_OPER_STATE_UNKNOWN    0
+#define IF_OPER_STATE_UP         1
+#define IF_OPER_STATE_DOWN       2
+#define IF_OPER_STATE_TESTING    3
 
 
 //
@@ -1150,6 +1180,8 @@ struct __nxc_object_iface
        DWORD dwPort;                   // Port number
    BYTE bMacAddr[MAC_ADDR_LENGTH];
        WORD wRequiredPollCount;
+       BYTE adminState;
+       BYTE operState;
 };
 
 struct __nxc_object_node
index 09cb43c..d3f1758 100644 (file)
@@ -143,6 +143,8 @@ double LIBNXDB_EXPORTABLE DBGetFieldDouble(DB_RESULT hResult, int iRow, int iCol
 DWORD LIBNXDB_EXPORTABLE DBGetFieldIPAddr(DB_RESULT hResult, int iRow, int iColumn);\r
 BOOL LIBNXDB_EXPORTABLE DBGetFieldByteArray(DB_RESULT hResult, int iRow, int iColumn,\r
                                              int *pnArray, int nSize, int nDefault);\r
+BOOL LIBNXDB_EXPORTABLE DBGetFieldByteArray2(DB_RESULT hResult, int iRow, int iColumn,
+                                             BYTE *data, int nSize, int nDefault);
 BOOL LIBNXDB_EXPORTABLE DBGetFieldGUID(DB_RESULT hResult, int iRow,\r
                                         int iColumn, uuid_t guid);\r
 \r
index 698ae40..fe8a584 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS - Network Management System
-** Copyright (C) 2003, 2004, 2005, 2006, 2007 Victor Kirhenshtein
+** Copyright (C) 2003-2012 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
 #define EVENT_8021X_PAE_FORCE_UNAUTH      59
 #define EVENT_8021X_AUTH_FAILED           60
 #define EVENT_8021X_AUTH_TIMEOUT          61
+#define EVENT_INTERFACE_UNEXPECTED_UP     62
+#define EVENT_INTERFACE_EXPECTED_DOWN     63
 
 #define EVENT_SNMP_UNMATCHED_TRAP         500
 #define EVENT_SNMP_COLD_START             501
index e13b659..9a9ffb6 100644 (file)
@@ -116,6 +116,34 @@ INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description)
        );
 INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
        (
+               EVENT_INTERFACE_UNEXPECTED_UP, 'SYS_IF_UNEXPECTED_UP',
+               EVENT_SEVERITY_MAJOR, 1,
+               'Interface "%2" unexpectedly changed state to UP (IP Addr: %3/%4, IfIndex: %5)',
+               'Generated when interface goes up but it''s expected state set to DOWN.#0D#0A' CONCAT
+               'Please note that source of event is node, not an interface itself.#0D#0A' CONCAT
+               'Parameters:#0D#0A' CONCAT
+               '   1) Interface object ID#0D#0A' CONCAT
+               '   2) Interface name#0D#0A' CONCAT
+               '   3) Interface IP address#0D#0A' CONCAT
+               '   4) Interface netmask#0D#0A' CONCAT
+               '   5) Interface index'
+       );
+INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
+       (
+               EVENT_INTERFACE_EXPECTED_DOWN, 'SYS_IF_EXPECTED_DOWN',
+               EVENT_SEVERITY_NORMAL, 1,
+               'Interface "%2" with expected state DOWN changed state to DOWN (IP Addr: %3/%4, IfIndex: %5)',
+               'Generated when interface goes down and it''s expected state is DOWN.#0D#0A' CONCAT
+               'Please note that source of event is node, not an interface itself.#0D#0A' CONCAT
+               'Parameters:#0D#0A' CONCAT
+               '   1) Interface object ID#0D#0A' CONCAT
+               '   2) Interface name#0D#0A' CONCAT
+               '   3) Interface IP address#0D#0A' CONCAT
+               '   4) Interface netmask#0D#0A' CONCAT
+               '   5) Interface index'
+       );
+INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
+       (
                EVENT_NODE_NORMAL, 'SYS_NODE_NORMAL',
                EVENT_SEVERITY_NORMAL, 1,
                'Node status changed to NORMAL',
index 5210b86..95a3174 100644 (file)
@@ -7,41 +7,61 @@
 INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
        VALUES (0,7944,'Show alarm when node is down',
                '%m',5,'NODE_DOWN_%i','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
 INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
        VALUES (1,7944,'Acknowlege node down alarms when node is up',
                '%m',6,'NODE_DOWN_%i','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
 INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
        VALUES (2,7944,'Show alarm when network service is down or in unknown state',
                '%m',5,'SERVICE_DOWN_%i_%2','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
 INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
        VALUES (3,7944,'Acknowlege network service down/unknown alarms when service is up',
                '%m',6,'SERVICE_DOWN_%i_%2','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
 INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
        VALUES (4,7944,'Show alarm when interface is down',
                '%m',5,'IF_DOWN_%i_%1','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
 INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
        VALUES (5,7944,'Acknowlege interface down alarms when interface is up',
                '%m',6,'IF_DOWN_%i_%1','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
 INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
-       VALUES (6,7944,'Generate alarm when incorrect network mask detected on interface',
+       VALUES (6,7944,'Show alarm when interface is unexpectedly up',
+               '%m',5,'IF_UNEXP_UP_%i_%1','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
+INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
+       VALUES (7,7944,'Acknowlege interface unexpectedly up alarms when interface goes down',
+               '%m',6,'IF_UNEXP_UP_%i_%1','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
+INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
+       VALUES (8,7944,'Generate alarm when incorrect network mask detected on interface',
                '%m',2,'BAD_NETMASK_%i_%2','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
 INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
-       VALUES (7,7944,'Generate alarm when MAC address change detected on interface',
+       VALUES (9,7944,'Generate alarm when MAC address change detected on interface',
                '%m',1,'#00','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
 INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
-       VALUES (8,7944,'Generate alarm when server enconters NXSL script execution error',
+       VALUES (10,7944,'Generate alarm when server enconters NXSL script execution error',
                '%m',2,'SCRIPT_ERR_%1_%2','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
 INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
-       VALUES (9,7944,'Show alarm when connection with backend database is lost',
+       VALUES (11,7944,'Show alarm when connection with backend database is lost',
                '%m',4,'DB_CONN','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
 INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
-       VALUES (10,7944,'Acknowlege DB connection loss alarm when connection restored',
+       VALUES (12,7944,'Acknowlege DB connection loss alarm when connection restored',
                '%m',6,'DB_CONN','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
 INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
-       VALUES (11,7944,'Show alarm when DCI status changes to DISABLED or UNSUPPORTED',
+       VALUES (13,7944,'Show alarm when DCI status changes to DISABLED or UNSUPPORTED',
                '%m',5,'DCI_STATUS_%i_%1','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
+               
 INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)
-       VALUES (12,7944,'Acknowlege DCI status alarms when DCI status returns to ACTIVE',
+       VALUES (14,7944,'Acknowlege DCI status alarms when DCI status returns to ACTIVE',
                '%m',6,'DCI_STATUS_%i_%1','#00',0,EVENT_ALARM_TIMEOUT,0,'#00');
 
 INSERT INTO policy_event_list (rule_id,event_code) VALUES (0,EVENT_NODE_DOWN);
@@ -51,11 +71,13 @@ INSERT INTO policy_event_list (rule_id,event_code) VALUES (2,EVENT_SERVICE_UNKNO
 INSERT INTO policy_event_list (rule_id,event_code) VALUES (3,EVENT_SERVICE_UP);
 INSERT INTO policy_event_list (rule_id,event_code) VALUES (4,EVENT_INTERFACE_DOWN);
 INSERT INTO policy_event_list (rule_id,event_code) VALUES (5,EVENT_INTERFACE_UP);
-INSERT INTO policy_event_list (rule_id,event_code) VALUES (6,EVENT_INCORRECT_NETMASK);
-INSERT INTO policy_event_list (rule_id,event_code) VALUES (7,EVENT_MAC_ADDR_CHANGED);
-INSERT INTO policy_event_list (rule_id,event_code) VALUES (8,EVENT_SCRIPT_ERROR);
-INSERT INTO policy_event_list (rule_id,event_code) VALUES (9,EVENT_DB_CONNECTION_LOST);
-INSERT INTO policy_event_list (rule_id,event_code) VALUES (10,EVENT_DB_CONNECTION_RESTORED);
-INSERT INTO policy_event_list (rule_id,event_code) VALUES (11,EVENT_DCI_DISABLED);
-INSERT INTO policy_event_list (rule_id,event_code) VALUES (11,EVENT_DCI_UNSUPPORTED);
-INSERT INTO policy_event_list (rule_id,event_code) VALUES (12,EVENT_DCI_ACTIVE);
+INSERT INTO policy_event_list (rule_id,event_code) VALUES (6,EVENT_INTERFACE_UNEXPECTED_UP);
+INSERT INTO policy_event_list (rule_id,event_code) VALUES (7,EVENT_INTERFACE_EXPECTED_DOWN);
+INSERT INTO policy_event_list (rule_id,event_code) VALUES (8,EVENT_INCORRECT_NETMASK);
+INSERT INTO policy_event_list (rule_id,event_code) VALUES (9,EVENT_MAC_ADDR_CHANGED);
+INSERT INTO policy_event_list (rule_id,event_code) VALUES (10,EVENT_SCRIPT_ERROR);
+INSERT INTO policy_event_list (rule_id,event_code) VALUES (11,EVENT_DB_CONNECTION_LOST);
+INSERT INTO policy_event_list (rule_id,event_code) VALUES (12,EVENT_DB_CONNECTION_RESTORED);
+INSERT INTO policy_event_list (rule_id,event_code) VALUES (13,EVENT_DCI_DISABLED);
+INSERT INTO policy_event_list (rule_id,event_code) VALUES (13,EVENT_DCI_UNSUPPORTED);
+INSERT INTO policy_event_list (rule_id,event_code) VALUES (14,EVENT_DCI_ACTIVE);
index 59f8a7b..1fe5652 100644 (file)
@@ -316,6 +316,8 @@ CREATE TABLE interfaces
        peer_if_id integer not null,
        mac_addr varchar(15) not null,
        required_polls integer not null,
+       admin_state integer not null,
+       oper_state integer not null,
        dot1x_pae_state integer not null,
        dot1x_backend_state integer not null,
        description varchar(255),
index c162ac4..fe075df 100644 (file)
@@ -548,7 +548,7 @@ DWORD LIBNXDB_EXPORTABLE DBGetFieldIPAddr(DB_RESULT hResult, int iRow, int iColu
 //
 
 BOOL LIBNXDB_EXPORTABLE DBGetFieldByteArray(DB_RESULT hResult, int iRow, int iColumn,
-                                             int *pnArray, int nSize, int nDefault)
+                                            int *pnArray, int nSize, int nDefault)
 {
    char pbBytes[128];
    BOOL bResult;
@@ -575,6 +575,28 @@ BOOL LIBNXDB_EXPORTABLE DBGetFieldByteArray(DB_RESULT hResult, int iRow, int iCo
    return bResult;
 }
 
+BOOL LIBNXDB_EXPORTABLE DBGetFieldByteArray2(DB_RESULT hResult, int iRow, int iColumn,
+                                             BYTE *data, int nSize, int nDefault)
+{
+   BOOL bResult;
+   TCHAR *pszVal, szBuffer[256];
+
+   pszVal = DBGetField(hResult, iRow, iColumn, szBuffer, 256);
+   if (pszVal != NULL)
+   {
+      int bytes = (int)StrToBin(pszVal, data, nSize);
+               if (bytes < nSize)
+                       memset(&data[bytes], 0, nSize - bytes);
+      bResult = TRUE;
+   }
+   else
+   {
+               memset(data, nDefault, nSize);
+      bResult = FALSE;
+   }
+   return bResult;
+}
+
 
 //
 // Get field's value as GUID
@@ -1308,7 +1330,7 @@ static TCHAR m_szSpecialChars[] = _T("\x01\x02\x03\x04\x05\x06\x07\x08")
                                   _T("\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10")
                                   _T("\x11\x12\x13\x14\x15\x16\x17\x18")
                                   _T("\x19\x1A\x1B\x1C\x1D\x1E\x1F")
-                                  _T("#%\"\\'\x7F");
+                                  _T("#%\\'\x7F");
 
 
 //
index 8c71a77..8b2951c 100644 (file)
@@ -705,6 +705,9 @@ public final class NXCPCodes
        public static final long VID_DCOBJECT_TYPE           = 411;\r
        public static final long VID_INSTANCE_COLUMN         = 412;\r
        public static final long VID_DATA_COLUMN             = 413;\r
+       public static final long VID_ADMIN_STATE             = 414;\r
+       public static final long VID_OPER_STATE              = 415;\r
+       public static final long VID_EXPECTED_STATE          = 416;\r
 \r
        public static final long VID_ACL_USER_BASE            = 0x00001000L;\r
        public static final long VID_ACL_USER_LAST            = 0x00001FFFL;\r
index 34e9334..81edb5d 100644 (file)
@@ -36,10 +36,7 @@ import org.netxms.client.objects.ClusterResource;
 import org.netxms.client.objects.ClusterSyncNetwork;\r
 \r
 /**\r
- * @author Victor\r
- * \r
  * This class is used to hold data for NXCSession.modifyObject()\r
- *\r
  */\r
 public class NXCObjectModificationData\r
 {\r
@@ -92,6 +89,7 @@ public class NXCObjectModificationData
        public static final long MODIFY_PRIMARY_NAME       = 0x00200000000000L;\r
        public static final long MODIFY_STATUS_CALCULATION = 0x00400000000000L;\r
        public static final long MODIFY_CLUSTER_NETWORKS   = 0x00800000000000L;\r
+       public static final long MODIFY_EXPECTED_STATE     = 0x01000000000000L;\r
        \r
        private long flags;             // Flags which indicates what object's data should be modified\r
        private long objectId;\r
@@ -160,6 +158,7 @@ public class NXCObjectModificationData
        private int[] statusTransformation;\r
        private int statusSingleThreshold;\r
        private int[] statusThresholds;\r
+       private int expectedState;\r
        \r
        /**\r
         * Constructor for creating modification data for given object\r
@@ -1303,4 +1302,21 @@ public class NXCObjectModificationData
                this.statusThresholds = statusThresholds;\r
                flags |= MODIFY_STATUS_CALCULATION;\r
        }\r
+\r
+       /**\r
+        * @return the expectedState\r
+        */\r
+       public int getExpectedState()\r
+       {\r
+               return expectedState;\r
+       }\r
+\r
+       /**\r
+        * @param expectedState the expectedState to set\r
+        */\r
+       public void setExpectedState(int expectedState)\r
+       {\r
+               this.expectedState = expectedState;\r
+               flags |= MODIFY_EXPECTED_STATE;\r
+       }\r
 }\r
index c1624a9..7ff7b82 100644 (file)
@@ -3284,6 +3284,11 @@ public class NXCSession implements Session, ScriptLibraryManager, UserManager, S
              msg.setVariableInt16(NXCPCodes.VID_STATUS_THRESHOLD_4, thresholds[3]);\r
                }\r
                \r
+               if ((flags & NXCObjectModificationData.MODIFY_EXPECTED_STATE) != 0)\r
+               {\r
+                       msg.setVariableInt16(NXCPCodes.VID_EXPECTED_STATE, data.getExpectedState());\r
+               }\r
+               \r
                sendMessage(msg);\r
                waitForRCC(msg.getMessageId());\r
        }\r
index bec8115..181a3fc 100644 (file)
@@ -29,8 +29,22 @@ import org.netxms.client.NXCSession;
 public class Interface extends GenericObject\r
 {\r
        // Interface flags\r
-       public static final int IF_SYNTHETIC_MASK = 0x00000001;\r
-       public static final int IF_PHYSICAL_PORT  = 0x00000002;\r
+       public static final int IF_SYNTHETIC_MASK         = 0x00000001;\r
+       public static final int IF_PHYSICAL_PORT          = 0x00000002;\r
+       public static final int IF_EXCLUDE_FROM_TOPOLOGY  = 0x00000004;\r
+       public static final int IF_LOOPBACK               = 0x00000008;\r
+       public static final int IF_CREATED_MANUALLY       = 0x00000010;\r
+       public static final int IF_EXPECTED_STATE_MASK    = 0x30000000;\r
+       \r
+       public static final int ADMIN_STATE_UNKNOWN      = 0;\r
+       public static final int ADMIN_STATE_UP           = 0;\r
+       public static final int ADMIN_STATE_DOWN         = 0;\r
+       public static final int ADMIN_STATE_TESTING      = 0;\r
+       \r
+       public static final int OPER_STATE_UNKNOWN       = 0;\r
+       public static final int OPER_STATE_UP            = 0;\r
+       public static final int OPER_STATE_DOWN          = 0;\r
+       public static final int OPER_STATE_TESTING       = 0;\r
        \r
        public static final int PAE_STATE_UNKNOWN        = 0;\r
        public static final int PAE_STATE_INITIALIZE     = 1;\r
@@ -54,6 +68,13 @@ public class Interface extends GenericObject
        public static final int BACKEND_STATE_INITIALIZE = 7;\r
        public static final int BACKEND_STATE_IGNORE     = 8;\r
        \r
+       private static final String[] stateText =\r
+               {\r
+                       "UNKNOWN",\r
+                       "UP",\r
+                       "DOWN",\r
+                       "TESTING"\r
+               };\r
        private static final String[] paeStateText =\r
                {\r
                        "UNKNOWN",\r
@@ -93,6 +114,8 @@ public class Interface extends GenericObject
        private long peerInterfaceId;\r
        private long zoneId;\r
        private String description;\r
+       private int adminState;\r
+       private int operState;\r
        private int dot1xPaeState;\r
        private int dot1xBackendState;\r
        \r
@@ -115,6 +138,8 @@ public class Interface extends GenericObject
                peerInterfaceId = msg.getVariableAsInt64(NXCPCodes.VID_PEER_INTERFACE_ID);\r
                zoneId = msg.getVariableAsInt64(NXCPCodes.VID_ZONE_ID);\r
                description = msg.getVariableAsString(NXCPCodes.VID_DESCRIPTION);\r
+               adminState = msg.getVariableAsInteger(NXCPCodes.VID_ADMIN_STATE);\r
+               operState = msg.getVariableAsInteger(NXCPCodes.VID_OPER_STATE);\r
                dot1xPaeState = msg.getVariableAsInteger(NXCPCodes.VID_DOT1X_PAE_STATE);\r
                dot1xBackendState = msg.getVariableAsInteger(NXCPCodes.VID_DOT1X_BACKEND_STATE);\r
        }\r
@@ -296,4 +321,60 @@ public class Interface extends GenericObject
                        return backendStateText[BACKEND_STATE_UNKNOWN];\r
                }\r
        }\r
+\r
+       /**\r
+        * @return the adminState\r
+        */\r
+       public int getAdminState()\r
+       {\r
+               return adminState;\r
+       }\r
+\r
+       /**\r
+        * @return the adminState\r
+        */\r
+       public String getAdminStateAsText()\r
+       {\r
+               try\r
+               {\r
+                       return stateText[adminState];\r
+               }\r
+               catch(ArrayIndexOutOfBoundsException e)\r
+               {\r
+                       return stateText[ADMIN_STATE_UNKNOWN];\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @return the operState\r
+        */\r
+       public int getOperState()\r
+       {\r
+               return operState;\r
+       }\r
+       \r
+       /**\r
+        * @return the operState\r
+        */\r
+       public String getOperStateAsText()\r
+       {\r
+               try\r
+               {\r
+                       return stateText[operState];\r
+               }\r
+               catch(ArrayIndexOutOfBoundsException e)\r
+               {\r
+                       return stateText[OPER_STATE_UNKNOWN];\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Get interface expected state\r
+        * \r
+        * @return\r
+        */\r
+       public int getExpectedState()\r
+       {\r
+               return (flags & IF_EXPECTED_STATE_MASK) >> 28;\r
+       }\r
 }\r
index 219577e..2a13667 100644 (file)
               </instanceof>\r
            </enabledWhen>\r
         </page>\r
+        <page\r
+              class="org.netxms.ui.eclipse.objectmanager.propertypages.InterfacePolling"\r
+              id="org.netxms.ui.eclipse.objectmanager.propertypages.InterfacePolling#20"\r
+              name="Polling">\r
+           <enabledWhen>\r
+              <instanceof\r
+                    value="org.netxms.client.objects.Interface">\r
+              </instanceof>\r
+           </enabledWhen>\r
+        </page>\r
   </extension>\r
 \r
    <extension\r
diff --git a/src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/InterfacePolling.java b/src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/InterfacePolling.java
new file mode 100644 (file)
index 0000000..afa6e7b
--- /dev/null
@@ -0,0 +1,149 @@
+/**\r
+ * NetXMS - open source network management system\r
+ * Copyright (C) 2003-2012 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.objectmanager.propertypages;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Combo;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Spinner;\r
+import org.eclipse.ui.dialogs.PropertyPage;\r
+import org.netxms.client.NXCObjectModificationData;\r
+import org.netxms.client.NXCSession;\r
+import org.netxms.client.objects.Interface;\r
+import org.netxms.ui.eclipse.jobs.ConsoleJob;\r
+import org.netxms.ui.eclipse.objectmanager.Activator;\r
+import org.netxms.ui.eclipse.shared.ConsoleSharedData;\r
+import org.netxms.ui.eclipse.tools.WidgetHelper;\r
+\r
+/**\r
+ * "Polling" property page for NetMS interface objects \r
+ */\r
+public class InterfacePolling extends PropertyPage\r
+{\r
+       private Spinner pollCount;\r
+       private Combo expectedState;\r
+       private Interface object;\r
+       private int currentPollCount;\r
+       private int currentExpectedState;\r
+       \r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       protected Control createContents(Composite parent)\r
+       {\r
+               Composite dialogArea = new Composite(parent, SWT.NONE);\r
+               \r
+               object = (Interface)getElement().getAdapter(Interface.class);\r
+               if (object == null)     // Paranoid check\r
+                       return dialogArea;\r
+               \r
+               currentPollCount = object.getRequiredPollCount();\r
+               currentExpectedState = object.getExpectedState();\r
+               \r
+               GridLayout layout = new GridLayout();\r
+               layout.verticalSpacing = WidgetHelper.OUTER_SPACING;\r
+               layout.marginWidth = 0;\r
+               layout.marginHeight = 0;\r
+               layout.numColumns = 2;\r
+      dialogArea.setLayout(layout);\r
+\r
+      pollCount = WidgetHelper.createLabeledSpinner(dialogArea, SWT.BORDER, "Required poll count", 0, 1000, WidgetHelper.DEFAULT_LAYOUT_DATA);\r
+      pollCount.setSelection(object.getRequiredPollCount());\r
+      \r
+      expectedState = WidgetHelper.createLabeledCombo(dialogArea, SWT.BORDER | SWT.READ_ONLY, "Expected state", WidgetHelper.DEFAULT_LAYOUT_DATA);\r
+      expectedState.add("UP");\r
+      expectedState.add("DOWN");\r
+      expectedState.add("IGNORE");\r
+      expectedState.select(object.getExpectedState());\r
+      \r
+               return dialogArea;\r
+       }\r
+       \r
+       /**\r
+        * Apply changes\r
+        * \r
+        * @param isApply true if update operation caused by "Apply" button\r
+        */\r
+       protected void applyChanges(final boolean isApply)\r
+       {\r
+               if ((expectedState.getSelectionIndex() == currentExpectedState) && (pollCount.getSelection() == currentPollCount))\r
+                       return; // nothing to change \r
+               \r
+               if (isApply)\r
+                       setValid(false);\r
+               \r
+               final NXCSession session = (NXCSession)ConsoleSharedData.getSession();\r
+               final NXCObjectModificationData data = new NXCObjectModificationData(object.getObjectId());\r
+               data.setExpectedState(expectedState.getSelectionIndex());\r
+               data.setRequiredPolls(pollCount.getSelection());\r
+               new ConsoleJob("Rename object", null, Activator.PLUGIN_ID, null) {\r
+                       @Override\r
+                       protected void runInternal(IProgressMonitor monitor) throws Exception\r
+                       {\r
+                               session.modifyObject(data);\r
+                       }\r
+\r
+                       @Override\r
+                       protected String getErrorMessage()\r
+                       {\r
+                               return "Cannot modify object";\r
+                       }\r
+\r
+                       @Override\r
+                       protected void jobFinalize()\r
+                       {\r
+                               if (isApply)\r
+                               {\r
+                                       runInUIThread(new Runnable() {\r
+                                               @Override\r
+                                               public void run()\r
+                                               {\r
+                                                       currentExpectedState = data.getExpectedState();\r
+                                                       currentPollCount = data.getRequiredPolls();\r
+                                                       InterfacePolling.this.setValid(true);\r
+                                               }\r
+                                       });\r
+                               }\r
+                       }\r
+               }.start();\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.jface.preference.PreferencePage#performOk()\r
+        */\r
+       @Override\r
+       public boolean performOk()\r
+       {\r
+               applyChanges(false);\r
+               return true;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.jface.preference.PreferencePage#performApply()\r
+        */\r
+       @Override\r
+       protected void performApply()\r
+       {\r
+               applyChanges(true);\r
+       }\r
+}\r
index 65aad6a..c79a476 100644 (file)
@@ -1,6 +1,6 @@
 /**\r
  * NetXMS - open source network management system\r
- * Copyright (C) 2003-2011 Victor Kirhenshtein\r
+ * Copyright (C) 2003-2012 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
@@ -40,6 +40,10 @@ import org.netxms.ui.eclipse.shared.ConsoleSharedData;
  */\r
 public class GeneralInfo extends TableElement\r
 {\r
+       /**\r
+        * @param parent\r
+        * @param object\r
+        */\r
        public GeneralInfo(Composite parent, GenericObject object)\r
        {\r
                super(parent, object);\r
@@ -66,6 +70,8 @@ public class GeneralInfo extends TableElement
                                addPair("Interface Index", Integer.toString(iface.getIfIndex()));\r
                                addPair("Interface Type", Integer.toString(iface.getIfType()));\r
                                addPair("Description", iface.getDescription());\r
+                               addPair("Administrative State", iface.getAdminStateAsText());\r
+                               addPair("Operational State", iface.getOperStateAsText());\r
                                addPair("MAC Address", iface.getMacAddress().toString());\r
                                if ((iface.getFlags() & Interface.IF_PHYSICAL_PORT) != 0)\r
                                {\r
index b83f53b..738700d 100644 (file)
@@ -588,6 +588,7 @@ TCHAR LIBNETXMS_EXPORTABLE *BinToStr(const BYTE *pData, DWORD dwSize, TCHAR *pSt
 
 //
 // Convert string of hexadecimal digits to byte array
+// Returns number of bytes written to destination
 //
 
 DWORD LIBNETXMS_EXPORTABLE StrToBin(const TCHAR *pStr, BYTE *pData, DWORD dwSize)
@@ -600,8 +601,11 @@ DWORD LIBNETXMS_EXPORTABLE StrToBin(const TCHAR *pStr, BYTE *pData, DWORD dwSize
    {
       pData[i] = hex2bin(*pCurr) << 4;
       pCurr++;
-      pData[i] |= hex2bin(*pCurr);
-      pCurr++;
+               if (*pCurr != 0)
+               {
+                       pData[i] |= hex2bin(*pCurr);
+                       pCurr++;
+               }
    }
    return i;
 }
index 9ef96fa..8f55675 100644 (file)
@@ -1,7 +1,7 @@
 /* 
 ** NetXMS - Network Management System
 ** Client Library
-** Copyright (C) 2003-2011 Victor Kirhenshtein
+** Copyright (C) 2003-2012 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU Lesser General Public License as published by
@@ -38,7 +38,7 @@
 // Constants
 //
 
-#define OBJECT_CACHE_MAGIC 0x20110607
+#define OBJECT_CACHE_MAGIC 0x20120413
 
 #define MAX_SERVER_NAME    64
 #define MAX_LOGIN_NAME     64
index 101c088..316701b 100644 (file)
@@ -1,7 +1,7 @@
 /* 
 ** NetXMS - Network Management System
 ** Client Library
-** Copyright (C) 2003-2011 Victor Kirhenshtein
+** Copyright (C) 2003-2012 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU Lesser General Public License as published by
@@ -277,6 +277,8 @@ static NXC_OBJECT *NewObjectFromMsg(CSCPMessage *pMsg)
          pObject->iface.dwPort = pMsg->GetVariableLong(VID_IF_PORT);
          pMsg->GetVariableBinary(VID_MAC_ADDR, pObject->iface.bMacAddr, MAC_ADDR_LENGTH);
                        pObject->iface.wRequiredPollCount = pMsg->GetVariableShort(VID_REQUIRED_POLLS);
+                       pObject->iface.adminState = (BYTE)pMsg->GetVariableShort(VID_ADMIN_STATE);
+                       pObject->iface.operState = (BYTE)pMsg->GetVariableShort(VID_OPER_STATE);
          break;
       case OBJECT_NODE:
                        pMsg->GetVariableStr(VID_PRIMARY_NAME, pObject->node.szPrimaryName, MAX_DNS_NAME);
index 12a074f..d428044 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS - Network Management System
-** Copyright (C) 2003-2011 Victor Kirhenshtein
+** Copyright (C) 2003-2012 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
@@ -135,10 +135,6 @@ Interface::~Interface()
 
 BOOL Interface::CreateFromDB(DWORD dwId)
 {
-   TCHAR szQuery[256], szBuffer[MAX_DB_STRING];
-   DB_RESULT hResult;
-   DWORD dwNodeId;
-   NetObj *pObject;
    BOOL bResult = FALSE;
 
    m_dwId = dwId;
@@ -146,13 +142,21 @@ BOOL Interface::CreateFromDB(DWORD dwId)
    if (!loadCommonProperties())
       return FALSE;
 
-   _sntprintf(szQuery, 256, _T("SELECT ip_addr,ip_netmask,if_type,if_index,node_id,")
-                            _T("mac_addr,flags,required_polls,bridge_port,phy_slot,")
-                                                                        _T("phy_port,peer_node_id,peer_if_id,description,")
-                                                                        _T("dot1x_pae_state,dot1x_backend_state FROM interfaces WHERE id=%d"), (int)dwId);
-   hResult = DBSelect(g_hCoreDB, szQuery);
+       DB_STATEMENT hStmt = DBPrepare(g_hCoreDB, 
+               _T("SELECT ip_addr,ip_netmask,if_type,if_index,node_id,")
+               _T("mac_addr,flags,required_polls,bridge_port,phy_slot,")
+               _T("phy_port,peer_node_id,peer_if_id,description,")
+               _T("dot1x_pae_state,dot1x_backend_state,admin_state,oper_state FROM interfaces WHERE id=?"));
+       if (hStmt == NULL)
+               return FALSE;
+       DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_dwId);
+
+       DB_RESULT hResult = DBSelectPrepared(hStmt);
    if (hResult == NULL)
+       {
+               DBFreeStatement(hStmt);
       return FALSE;     // Query failed
+       }
 
    if (DBGetNumRows(hResult) != 0)
    {
@@ -160,8 +164,8 @@ BOOL Interface::CreateFromDB(DWORD dwId)
       m_dwIpNetMask = DBGetFieldIPAddr(hResult, 0, 1);
       m_dwIfType = DBGetFieldULong(hResult, 0, 2);
       m_dwIfIndex = DBGetFieldULong(hResult, 0, 3);
-      dwNodeId = DBGetFieldULong(hResult, 0, 4);
-      StrToBin(DBGetField(hResult, 0, 5, szBuffer, MAX_DB_STRING), m_bMacAddr, MAC_ADDR_LENGTH);
+      DWORD nodeId = DBGetFieldULong(hResult, 0, 4);
+               DBGetFieldByteArray2(hResult, 0, 5, m_bMacAddr, MAC_ADDR_LENGTH, 0);
                m_flags = DBGetFieldULong(hResult, 0, 6);
       m_iRequiredPollCount = DBGetFieldLong(hResult, 0, 7);
                m_bridgePortNumber = DBGetFieldULong(hResult, 0, 8);
@@ -172,24 +176,26 @@ BOOL Interface::CreateFromDB(DWORD dwId)
                DBGetField(hResult, 0, 13, m_description, MAX_DB_STRING);
                m_dot1xPaeAuthState = (WORD)DBGetFieldLong(hResult, 0, 14);
                m_dot1xBackendAuthState = (WORD)DBGetFieldLong(hResult, 0, 15);
+               m_adminState = (WORD)DBGetFieldLong(hResult, 0, 16);
+               m_operState = (WORD)DBGetFieldLong(hResult, 0, 17);
 
       // Link interface to node
       if (!m_bIsDeleted)
       {
-         pObject = FindObjectById(dwNodeId);
-         if (pObject == NULL)
+         NetObj *object = FindObjectById(nodeId);
+         if (object == NULL)
          {
-            nxlog_write(MSG_INVALID_NODE_ID, EVENTLOG_ERROR_TYPE, "dd", dwId, dwNodeId);
+            nxlog_write(MSG_INVALID_NODE_ID, EVENTLOG_ERROR_TYPE, "dd", dwId, nodeId);
          }
-         else if (pObject->Type() != OBJECT_NODE)
+         else if (object->Type() != OBJECT_NODE)
          {
-            nxlog_write(MSG_NODE_NOT_NODE, EVENTLOG_ERROR_TYPE, "dd", dwId, dwNodeId);
+            nxlog_write(MSG_NODE_NOT_NODE, EVENTLOG_ERROR_TYPE, "dd", dwId, nodeId);
          }
          else
          {
-            pObject->AddChild(this);
-            AddParent(pObject);
-                               m_zoneId = ((Node *)pObject)->getZoneId();
+            object->AddChild(this);
+            AddParent(object);
+                               m_zoneId = ((Node *)object)->getZoneId();
             bResult = TRUE;
          }
       }
@@ -200,6 +206,7 @@ BOOL Interface::CreateFromDB(DWORD dwId)
    }
 
    DBFreeResult(hResult);
+       DBFreeStatement(hStmt);
 
    // Load access list
    loadACLFromDB();
@@ -218,29 +225,19 @@ BOOL Interface::CreateFromDB(DWORD dwId)
 
 BOOL Interface::SaveToDB(DB_HANDLE hdb)
 {
-   TCHAR szQuery[2048], szMacStr[16], szIpAddr[16], szNetMask[16];
-   BOOL bNewObject = TRUE;
-   Node *pNode;
+   TCHAR szMacStr[16], szIpAddr[16], szNetMask[16];
    DWORD dwNodeId;
-   DB_RESULT hResult;
 
-   // Lock object's access
    LockData();
 
-   saveCommonProperties(hdb);
-
-   // Check for object's existence in database
-   _sntprintf(szQuery, 1024, _T("SELECT id FROM interfaces WHERE id=%d"), m_dwId);
-   hResult = DBSelect(hdb, szQuery);
-   if (hResult != 0)
-   {
-      if (DBGetNumRows(hResult) > 0)
-         bNewObject = FALSE;
-      DBFreeResult(hResult);
-   }
+   if (!saveCommonProperties(hdb))
+       {
+               UnlockData();
+               return FALSE;
+       }
 
    // Determine owning node's ID
-   pNode = getParentNode();
+   Node *pNode = getParentNode();
    if (pNode != NULL)
       dwNodeId = pNode->Id();
    else
@@ -248,42 +245,63 @@ BOOL Interface::SaveToDB(DB_HANDLE hdb)
 
    // Form and execute INSERT or UPDATE query
    BinToStr(m_bMacAddr, MAC_ADDR_LENGTH, szMacStr);
-   if (bNewObject)
-      _sntprintf(szQuery, 2048, _T("INSERT INTO interfaces (id,ip_addr,")
-                       _T("ip_netmask,node_id,if_type,if_index,mac_addr,flags,required_polls,")
-                                                         _T("bridge_port,phy_slot,phy_port,peer_node_id,peer_if_id,description,")
-                       _T("dot1x_pae_state,dot1x_backend_state) ")
-                                                         _T("VALUES (%d,'%s','%s',%d,%d,%d,'%s',%d,%d,%d,%d,%d,%d,%d,%s,%d,%d)"),
-              m_dwId, IpToStr(m_dwIpAddr, szIpAddr),
-              IpToStr(m_dwIpNetMask, szNetMask), dwNodeId,
-                                 m_dwIfType, m_dwIfIndex, szMacStr, (int)m_flags,
-                                 m_iRequiredPollCount, (int)m_bridgePortNumber, (int)m_slotNumber,
-                                 (int)m_portNumber, (int)m_peerNodeId, (int)m_peerInterfaceId,
-                                 (const TCHAR *)DBPrepareString(hdb, m_description),
-                                 (int)m_dot1xPaeAuthState, (int)m_dot1xBackendAuthState);
+       DB_STATEMENT hStmt;
+   if (IsDatabaseRecordExist(hdb, _T("interfaces"), _T("id"), m_dwId))
+       {
+               hStmt = DBPrepare(hdb,
+                       _T("UPDATE interfaces SET ip_addr=?,ip_netmask=?,")
+         _T("node_id=?,if_type=?,if_index=?,mac_addr=?,flags=?,")
+                       _T("required_polls=?,bridge_port=?,phy_slot=?,phy_port=?,")
+                       _T("peer_node_id=?,peer_if_id=?,description=?,admin_state=?,")
+                       _T("oper_state=?,dot1x_pae_state=?,dot1x_backend_state=? WHERE id=?"));
+       }
    else
-      _sntprintf(szQuery, 2048, _T("UPDATE interfaces SET ip_addr='%s',ip_netmask='%s',")
-                       _T("node_id=%d,if_type=%d,if_index=%d,mac_addr='%s',flags=%d,")
-                                                         _T("required_polls=%d,bridge_port=%d,phy_slot=%d,phy_port=%d,")
-                                                         _T("peer_node_id=%d,peer_if_id=%d,description=%s,")
-                                                         _T("dot1x_pae_state=%d,dot1x_backend_state=%d WHERE id=%d"),
-              IpToStr(m_dwIpAddr, szIpAddr),
-              IpToStr(m_dwIpNetMask, szNetMask), dwNodeId,
-                                 m_dwIfType, m_dwIfIndex, szMacStr, (int)m_flags,
-                                 m_iRequiredPollCount, (int)m_bridgePortNumber, (int)m_slotNumber,
-                                 (int)m_portNumber, (int)m_peerNodeId, (int)m_peerInterfaceId,
-                                 (const TCHAR *)DBPrepareString(hdb, m_description), 
-                                 (int)m_dot1xPaeAuthState, (int)m_dot1xBackendAuthState, (int)m_dwId);
-   DBQuery(hdb, szQuery);
+       {
+               hStmt = DBPrepare(hdb,
+                       _T("INSERT INTO interfaces (ip_addr,ip_netmask,node_id,if_type,if_index,mac_addr,")
+                       _T("flags,required_polls,bridge_port,phy_slot,phy_port,peer_node_id,peer_if_id,description,")
+         _T("admin_state,oper_state,dot1x_pae_state,dot1x_backend_state,id) ")
+                       _T("VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
+       }
+       if (hStmt == NULL)
+       {
+               UnlockData();
+               return FALSE;
+       }
+
+       DBBind(hStmt, 1, DB_SQLTYPE_VARCHAR, IpToStr(m_dwIpAddr, szIpAddr), DB_BIND_STATIC);
+       DBBind(hStmt, 2, DB_SQLTYPE_VARCHAR, IpToStr(m_dwIpNetMask, szNetMask), DB_BIND_STATIC);
+       DBBind(hStmt, 3, DB_SQLTYPE_INTEGER, dwNodeId);
+       DBBind(hStmt, 4, DB_SQLTYPE_INTEGER, m_dwIfType);
+       DBBind(hStmt, 5, DB_SQLTYPE_INTEGER, m_dwIfIndex);
+       DBBind(hStmt, 6, DB_SQLTYPE_VARCHAR, szMacStr, DB_BIND_STATIC);
+       DBBind(hStmt, 7, DB_SQLTYPE_INTEGER, m_flags);
+       DBBind(hStmt, 8, DB_SQLTYPE_INTEGER, (LONG)m_iRequiredPollCount);
+       DBBind(hStmt, 9, DB_SQLTYPE_INTEGER, m_bridgePortNumber);
+       DBBind(hStmt, 10, DB_SQLTYPE_INTEGER, m_slotNumber);
+       DBBind(hStmt, 11, DB_SQLTYPE_INTEGER, m_portNumber);
+       DBBind(hStmt, 12, DB_SQLTYPE_INTEGER, m_peerNodeId);
+       DBBind(hStmt, 13, DB_SQLTYPE_INTEGER, m_peerInterfaceId);
+       DBBind(hStmt, 14, DB_SQLTYPE_VARCHAR, m_description, DB_BIND_STATIC);
+       DBBind(hStmt, 15, DB_SQLTYPE_INTEGER, (DWORD)m_adminState);
+       DBBind(hStmt, 16, DB_SQLTYPE_INTEGER, (DWORD)m_operState);
+       DBBind(hStmt, 17, DB_SQLTYPE_INTEGER, (DWORD)m_dot1xPaeAuthState);
+       DBBind(hStmt, 18, DB_SQLTYPE_INTEGER, (DWORD)m_dot1xBackendAuthState);
+       DBBind(hStmt, 19, DB_SQLTYPE_INTEGER, m_dwId);
+
+       BOOL success = DBExecute(hStmt);
+       DBFreeStatement(hStmt);
 
    // Save access list
-   saveACLToDB(hdb);
+       if (success)
+               success = saveACLToDB(hdb);
 
    // Clear modifications flag and unlock object
-   m_bIsModified = FALSE;
+       if (success)
+               m_bIsModified = FALSE;
    UnlockData();
 
-   return TRUE;
+   return success;
 }
 
 
@@ -314,13 +332,8 @@ void Interface::StatusPoll(ClientSession *pSession, DWORD dwRqId,
                                                                        Queue *pEventQueue, BOOL bClusterSync,
                                                                        SNMP_Transport *pTransport)
 {
-   int oldStatus = m_iStatus, newStatus;
-   DWORD dwPingStatus;
-   BOOL bNeedPoll = TRUE;
-   Node *pNode;
-
    m_pPollRequestor = pSession;
-   pNode = getParentNode();
+   Node *pNode = getParentNode();
    if (pNode == NULL)
    {
       m_iStatus = STATUS_UNKNOWN;
@@ -330,14 +343,18 @@ void Interface::StatusPoll(ClientSession *pSession, DWORD dwRqId,
    SendPollerMsg(dwRqId, _T("   Starting status poll on interface %s\r\n"), m_szName);
    SendPollerMsg(dwRqId, _T("      Current interface status is %s\r\n"), g_szStatusText[m_iStatus]);
 
+       int adminState = IF_ADMIN_STATE_UNKNOWN;
+       int operState = IF_OPER_STATE_UNKNOWN;
+   BOOL bNeedPoll = TRUE;
+
    // Poll interface using different methods
    if ((pNode->getFlags() & NF_IS_NATIVE_AGENT) &&
        (!(pNode->getFlags() & NF_DISABLE_NXCP)) && (!(pNode->getRuntimeFlags() & NDF_AGENT_UNREACHABLE)))
    {
       SendPollerMsg(dwRqId, _T("      Retrieving interface status from NetXMS agent\r\n"));
-      newStatus = pNode->getInterfaceStatusFromAgent(m_dwIfIndex);
-               DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): new status from NetXMS agent %d"), m_dwId, m_szName, newStatus);
-      if (newStatus != STATUS_UNKNOWN)
+      pNode->getInterfaceStatusFromAgent(m_dwIfIndex, &adminState, &operState);
+               DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): new state from NetXMS agent: adinState=%d operState=%d"), m_dwId, m_szName, adminState, operState);
+               if ((adminState != IF_ADMIN_STATE_UNKNOWN) && (operState != IF_OPER_STATE_UNKNOWN))
                {
                        SendPollerMsg(dwRqId, POLLER_INFO _T("      Interface status retrieved from NetXMS agent\r\n"));
          bNeedPoll = FALSE;
@@ -353,9 +370,9 @@ void Interface::StatusPoll(ClientSession *pSession, DWORD dwRqId,
                 (pTransport != NULL))
    {
       SendPollerMsg(dwRqId, _T("      Retrieving interface status from SNMP agent\r\n"));
-      newStatus = pNode->getInterfaceStatusFromSNMP(pTransport, m_dwIfIndex);
-               DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): new status from SNMP %d"), m_dwId, m_szName, newStatus);
-      if (newStatus != STATUS_UNKNOWN)
+      pNode->getInterfaceStatusFromSNMP(pTransport, m_dwIfIndex, &adminState, &operState);
+               DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): new state from SNMP: adminState=%d operState=%d"), m_dwId, m_szName, adminState, operState);
+               if ((adminState != IF_ADMIN_STATE_UNKNOWN) && (operState != IF_OPER_STATE_UNKNOWN))
                {
                        SendPollerMsg(dwRqId, POLLER_INFO _T("      Interface status retrieved from SNMP agent\r\n"));
          bNeedPoll = FALSE;
@@ -374,7 +391,6 @@ void Interface::StatusPoll(ClientSession *pSession, DWORD dwRqId,
                        // Interface doesn't have an IP address, so we can't ping it
                        SendPollerMsg(dwRqId, POLLER_WARNING _T("      Interface status cannot be determined\r\n"));
                        DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): cannot use ping for status check"), m_dwId, m_szName);
-         newStatus = STATUS_UNKNOWN;
       }
       else
       {
@@ -392,7 +408,6 @@ void Interface::StatusPoll(ClientSession *pSession, DWORD dwRqId,
 
                        if (icmpProxy != 0)
                        {
-                               newStatus = STATUS_UNKNOWN;     // Set interface status to unknown in case of any error
                                Node *proxyNode = (Node *)g_idxNodeById.get(icmpProxy);
                                if ((proxyNode != NULL) && proxyNode->isNativeAgent() && !proxyNode->isDown())
                                {
@@ -408,7 +423,16 @@ void Interface::StatusPoll(ClientSession *pSession, DWORD dwRqId,
                                                        long value = _tcstol(buffer, &eptr, 10);
                                                        if ((*eptr == 0) && (value >= 0))
                                                        {
-                                                               newStatus = (value < 10000) ? STATUS_NORMAL : STATUS_CRITICAL;
+                                                               if (value < 10000)
+                                                               {
+                                                                       adminState = IF_ADMIN_STATE_UP;
+                                                                       operState = IF_OPER_STATE_UP;
+                                                               }
+                                                               else
+                                                               {
+                                                                       adminState = IF_ADMIN_STATE_UNKNOWN;
+                                                                       operState = IF_OPER_STATE_DOWN;
+                                                               }
                                                        }
                                                }
                                                conn->disconnect();
@@ -420,15 +444,60 @@ void Interface::StatusPoll(ClientSession *pSession, DWORD dwRqId,
                        {
                                SendPollerMsg(dwRqId, _T("      Starting ICMP ping\r\n"));
                                DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): calling IcmpPing(0x%08X,3,1500,NULL,%d)"), m_dwId, m_szName, htonl(m_dwIpAddr), g_dwPingSize);
-                               dwPingStatus = IcmpPing(htonl(m_dwIpAddr), 3, 1500, NULL, g_dwPingSize);
+                               DWORD dwPingStatus = IcmpPing(htonl(m_dwIpAddr), 3, 1500, NULL, g_dwPingSize);
                                if (dwPingStatus == ICMP_RAW_SOCK_FAILED)
                                        nxlog_write(MSG_RAW_SOCK_FAILED, EVENTLOG_WARNING_TYPE, NULL);
-                               newStatus = (dwPingStatus == ICMP_SUCCESS) ? STATUS_NORMAL : STATUS_CRITICAL;
-                               DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): ping result %d, new status %d"), m_dwId, m_szName, dwPingStatus, newStatus);
+                               if (dwPingStatus == ICMP_SUCCESS)
+                               {
+                                       adminState = IF_ADMIN_STATE_UP;
+                                       operState = IF_OPER_STATE_UP;
+                               }
+                               else
+                               {
+                                       adminState = IF_ADMIN_STATE_UNKNOWN;
+                                       operState = IF_OPER_STATE_DOWN;
+                               }
+                               DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): ping result %d, adminState=%d, operState=%d"), m_dwId, m_szName, dwPingStatus, adminState, operState);
                        }
       }
    }
 
+       // Calculate interface object status based on admin state, oper state, and expected state
+   int oldStatus = m_iStatus;
+       int newStatus;
+       int expectedState = (m_flags & IF_EXPECTED_STATE_MASK) >> 28;
+       switch(adminState)
+       {
+               case IF_ADMIN_STATE_UP:
+               case IF_ADMIN_STATE_UNKNOWN:
+                       switch(operState)
+                       {
+                               case IF_OPER_STATE_UP:
+                                       newStatus = ((expectedState == IF_EXPECTED_STATE_DOWN) ? STATUS_CRITICAL : STATUS_NORMAL);
+                                       break;
+                               case IF_OPER_STATE_DOWN:
+                                       newStatus = ((expectedState == IF_EXPECTED_STATE_UP) ? STATUS_CRITICAL : STATUS_NORMAL);
+                                       break;
+                               case IF_OPER_STATE_TESTING:
+                                       newStatus = STATUS_TESTING;
+                                       break;
+                               default:
+                                       newStatus = STATUS_UNKNOWN;
+                                       break;
+                       }
+                       break;
+               case IF_ADMIN_STATE_DOWN:
+                       newStatus = STATUS_DISABLED;
+                       break;
+               case IF_ADMIN_STATE_TESTING:
+                       newStatus = STATUS_TESTING;
+                       break;
+               default:
+                       newStatus = STATUS_UNKNOWN;
+                       break;
+       }
+
+       // Check 802.1x state
        if ((pNode->getFlags() & NF_IS_8021X) && isPhysicalPort())
        {
                DbgPrintf(5, _T("StatusPoll(%s): Checking 802.1x state for interface %s"), pNode->Name(), m_szName);
@@ -454,7 +523,7 @@ void Interface::StatusPoll(ClientSession *pSession, DWORD dwRqId,
        DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): newStatus=%d oldStatus=%d pollCount=%d requiredPolls=%d"),
                  m_dwId, m_szName, newStatus, oldStatus, m_iPollCount, requiredPolls);
 
-   if ((newStatus != oldStatus) && (m_iPollCount >= requiredPolls))
+   if ((newStatus != oldStatus) && (m_iPollCount >= requiredPolls) && (expectedState != IF_EXPECTED_STATE_IGNORE))
    {
                static DWORD statusToEvent[] =
                {
@@ -468,20 +537,44 @@ void Interface::StatusPoll(ClientSession *pSession, DWORD dwRqId,
                        EVENT_INTERFACE_DISABLED, // Disabled
                        EVENT_INTERFACE_TESTING   // Testing
                };
+               static DWORD statusToEventInverted[] =
+               {
+                       EVENT_INTERFACE_EXPECTED_DOWN, // Normal
+                       EVENT_INTERFACE_EXPECTED_DOWN, // Warning
+                       EVENT_INTERFACE_EXPECTED_DOWN, // Minor
+                       EVENT_INTERFACE_UNEXPECTED_UP, // Major
+                       EVENT_INTERFACE_UNEXPECTED_UP, // Critical
+                       EVENT_INTERFACE_UNKNOWN,  // Unknown
+                       EVENT_INTERFACE_UNKNOWN,  // Unmanaged
+                       EVENT_INTERFACE_DISABLED, // Disabled
+                       EVENT_INTERFACE_TESTING   // Testing
+               };
 
                DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): status changed from %d to %d"), m_dwId, m_szName, m_iStatus, newStatus);
                m_iStatus = newStatus;
                m_iPendingStatus = -1;  // Invalidate pending status
                SendPollerMsg(dwRqId, _T("      Interface status changed to %s\r\n"), g_szStatusText[m_iStatus]);
                PostEventEx(pEventQueue, 
-                                               statusToEvent[m_iStatus],
-                                               pNode->Id(), "dsaad", m_dwId, m_szName, m_dwIpAddr, m_dwIpNetMask,
-                                               m_dwIfIndex);
-               LockData();
-               Modify();
-               UnlockData();
+                           (expectedState == IF_EXPECTED_STATE_DOWN) ? statusToEventInverted[m_iStatus] : statusToEvent[m_iStatus],
+                                               pNode->Id(), "dsaad", m_dwId, m_szName, m_dwIpAddr, m_dwIpNetMask, m_dwIfIndex);
    }
-   SendPollerMsg(dwRqId, _T("      Interface status after poll is %s\r\n"), g_szStatusText[m_iStatus]);
+       else if (expectedState == IF_EXPECTED_STATE_IGNORE)
+       {
+               m_iStatus = (newStatus <= STATUS_CRITICAL) ? STATUS_NORMAL : newStatus;
+               if (m_iStatus != oldStatus)
+                       m_iPendingStatus = -1;  // Invalidate pending status
+       }
+
+       LockData();
+       if ((m_iStatus != oldStatus) || (adminState != (int)m_adminState) || (operState != (int)m_operState))
+       {
+               m_adminState = (WORD)adminState;
+               m_operState = (WORD)operState;
+               Modify();
+       }
+       UnlockData();
+       
+       SendPollerMsg(dwRqId, _T("      Interface status after poll is %s\r\n"), g_szStatusText[m_iStatus]);
        SendPollerMsg(dwRqId, _T("   Finished status poll on interface %s\r\n"), m_szName);
 }
 
@@ -594,6 +687,8 @@ void Interface::CreateMessage(CSCPMessage *pMsg)
        pMsg->SetVariable(VID_PEER_NODE_ID, m_peerNodeId);
        pMsg->SetVariable(VID_PEER_INTERFACE_ID, m_peerInterfaceId);
        pMsg->SetVariable(VID_DESCRIPTION, m_description);
+       pMsg->SetVariable(VID_ADMIN_STATE, m_adminState);
+       pMsg->SetVariable(VID_OPER_STATE, m_operState);
        pMsg->SetVariable(VID_DOT1X_PAE_STATE, m_dot1xPaeAuthState);
        pMsg->SetVariable(VID_DOT1X_BACKEND_STATE, m_dot1xBackendAuthState);
 }
@@ -612,6 +707,14 @@ DWORD Interface::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked)
    if (pRequest->IsVariableExist(VID_REQUIRED_POLLS))
       m_iRequiredPollCount = (int)pRequest->GetVariableShort(VID_REQUIRED_POLLS);
 
+       // Expected interface state
+       if (pRequest->IsVariableExist(VID_EXPECTED_STATE))
+       {
+      DWORD expectedState = pRequest->GetVariableShort(VID_EXPECTED_STATE);
+               m_flags &= ~IF_EXPECTED_STATE_MASK;
+               m_flags |= expectedState << 28;
+       }
+
    return NetObj::ModifyFromMessage(pRequest, TRUE);
 }
 
index 083d647..73843c9 100644 (file)
@@ -3024,9 +3024,9 @@ DWORD Node::wakeUp()
 // Get status of interface with given index from SNMP agent
 //
 
-int Node::getInterfaceStatusFromSNMP(SNMP_Transport *pTransport, DWORD dwIndex)
+void Node::getInterfaceStatusFromSNMP(SNMP_Transport *pTransport, DWORD dwIndex, int *adminState, int *operState)
 {
-   return SnmpGetInterfaceStatus(m_snmpVersion, pTransport, dwIndex);
+   SnmpGetInterfaceStatus(m_snmpVersion, pTransport, dwIndex, adminState, operState);
 }
 
 
@@ -3034,50 +3034,48 @@ int Node::getInterfaceStatusFromSNMP(SNMP_Transport *pTransport, DWORD dwIndex)
 // Get status of interface with given index from native agent
 //
 
-int Node::getInterfaceStatusFromAgent(DWORD dwIndex)
+void Node::getInterfaceStatusFromAgent(DWORD dwIndex, int *adminState, int *operState)
 {
    TCHAR szParam[128], szBuffer[32];
-   DWORD dwAdminStatus, dwLinkState;
-   int iStatus;
 
    // Get administrative status
    _sntprintf(szParam, 128, _T("Net.Interface.AdminStatus(%u)"), dwIndex);
    if (GetItemFromAgent(szParam, 32, szBuffer) == DCE_SUCCESS)
    {
-      dwAdminStatus = _tcstoul(szBuffer, NULL, 0);
+      *adminState = _tcstol(szBuffer, NULL, 0);
 
-      switch(dwAdminStatus)
+      switch(*adminState)
       {
-         case 3:
-            iStatus = STATUS_TESTING;
+         case IF_ADMIN_STATE_TESTING:
+                               *operState = IF_OPER_STATE_UNKNOWN;
             break;
-         case 2:
+         case IF_ADMIN_STATE_DOWN:
          case 0:     // Agents before 0.2.1 may return 0 instead of 2
-            iStatus = STATUS_DISABLED;
+                               *operState = IF_OPER_STATE_DOWN;
             break;
-         case 1:     // Interface administratively up, check link state
+         case IF_ADMIN_STATE_UP:     // Interface administratively up, check link state
             _sntprintf(szParam, 128, _T("Net.Interface.Link(%u)"), dwIndex);
             if (GetItemFromAgent(szParam, 32, szBuffer) == DCE_SUCCESS)
             {
-               dwLinkState = _tcstoul(szBuffer, NULL, 0);
-               iStatus = (dwLinkState == 0) ? STATUS_CRITICAL : STATUS_NORMAL;
+               DWORD dwLinkState = _tcstoul(szBuffer, NULL, 0);
+               *operState = (dwLinkState == 0) ? IF_OPER_STATE_DOWN : IF_OPER_STATE_UP;
             }
             else
             {
-               iStatus = STATUS_UNKNOWN;
+                                       *operState = IF_OPER_STATE_UNKNOWN;
             }
             break;
          default:
-            iStatus = STATUS_UNKNOWN;
+                               *adminState = IF_ADMIN_STATE_UNKNOWN;
+                               *operState = IF_OPER_STATE_UNKNOWN;
             break;
       }
    }
    else
    {
-      iStatus = STATUS_UNKNOWN;
+               *adminState = IF_ADMIN_STATE_UNKNOWN;
+               *operState = IF_OPER_STATE_UNKNOWN;
    }
-
-   return iStatus;
 }
 
 
index cf59455..af61460 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS - Network Management System
-** Copyright (C) 2003-2011 Victor Kirhenshtein
+** Copyright (C) 2003-2012 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
@@ -267,6 +267,22 @@ NXSL_Value *NXSL_InterfaceClass::getAttr(NXSL_Object *pObject, const TCHAR *pszA
    {
                pValue = new NXSL_Value(iface->getBridgePortNumber());
    }
+   else if (!_tcscmp(pszAttr, _T("adminState")))
+   {
+               pValue = new NXSL_Value((LONG)iface->getAdminState());
+   }
+   else if (!_tcscmp(pszAttr, _T("operState")))
+   {
+               pValue = new NXSL_Value((LONG)iface->getOperState());
+   }
+   else if (!_tcscmp(pszAttr, _T("dot1xPaeAuthState")))
+   {
+               pValue = new NXSL_Value((LONG)iface->getDot1xPaeAuthState());
+   }
+   else if (!_tcscmp(pszAttr, _T("dot1xBackendAuthState")))
+   {
+               pValue = new NXSL_Value((LONG)iface->getDot1xBackendAuthState());
+   }
    else if (!_tcscmp(pszAttr, _T("node")))
        {
                Node *parentNode = iface->getParentNode();
index c103fa2..726d6f9 100644 (file)
@@ -83,13 +83,11 @@ ARP_CACHE *SnmpGetArpCache(DWORD dwVersion, SNMP_Transport *pTransport)
 
 //
 // Get interface status via SNMP
-// Possible return values can be NORMAL, CRITICAL, DISABLED, TESTING and UNKNOWN
 //
 
-int SnmpGetInterfaceStatus(DWORD dwVersion, SNMP_Transport *pTransport, DWORD dwIfIndex)
+void SnmpGetInterfaceStatus(DWORD dwVersion, SNMP_Transport *pTransport, DWORD dwIfIndex, int *adminState, int *operState)
 {
    DWORD dwAdminStatus = 0, dwOperStatus = 0;
-   int iStatus;
    TCHAR szOid[256];
 
    // Interface administrative status
@@ -98,37 +96,37 @@ int SnmpGetInterfaceStatus(DWORD dwVersion, SNMP_Transport *pTransport, DWORD dw
 
    switch(dwAdminStatus)
    {
-      case 3:
-         iStatus = STATUS_TESTING;
+               case IF_ADMIN_STATE_DOWN:
+                       *adminState = IF_ADMIN_STATE_DOWN;
+                       *operState = IF_OPER_STATE_DOWN;
          break;
-      case 2:
-         iStatus = STATUS_DISABLED;
-         break;
-      case 1:     // Interface administratively up, check operational status
+      case IF_ADMIN_STATE_UP:
+               case IF_ADMIN_STATE_TESTING:
+                       *adminState = (int)dwAdminStatus;
          // Get interface operational status
          _sntprintf(szOid, 256, _T(".1.3.6.1.2.1.2.2.1.8.%d"), dwIfIndex);
          SnmpGet(dwVersion, pTransport, szOid, NULL, 0, &dwOperStatus, sizeof(DWORD), 0);
          switch(dwOperStatus)
          {
             case 3:
-               iStatus = STATUS_TESTING;
+                                       *operState = IF_OPER_STATE_TESTING;
                break;
             case 2:  // Interface is down
-               iStatus = STATUS_CRITICAL;
+                                       *operState = IF_OPER_STATE_DOWN;
                break;
             case 1:
-               iStatus = STATUS_NORMAL;
+                                       *operState = IF_OPER_STATE_UP;
                break;
             default:
-               iStatus = STATUS_UNKNOWN;
+                                       *operState = IF_OPER_STATE_UNKNOWN;
                break;
          }
          break;
       default:
-         iStatus = STATUS_UNKNOWN;
+                       *adminState = IF_ADMIN_STATE_UNKNOWN;
+                       *operState = IF_OPER_STATE_UNKNOWN;
          break;
    }
-   return iStatus;
 }
 
 
index 068fd89..0af26e3 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS - Network Management System
-** Copyright (C) 2003-2010 Victor Kirhenshtein
+** Copyright (C) 2003-2012 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
index 4d2102a..a0fdeb9 100644 (file)
@@ -726,7 +726,7 @@ ARP_CACHE *GetLocalArpCache();
 ARP_CACHE *SnmpGetArpCache(DWORD dwVersion, SNMP_Transport *pTransport);
 
 InterfaceList *GetLocalInterfaceList();
-int SnmpGetInterfaceStatus(DWORD dwVersion, SNMP_Transport *pTransport, DWORD dwIfIndex);
+void SnmpGetInterfaceStatus(DWORD dwVersion, SNMP_Transport *pTransport, DWORD dwIfIndex, int *adminState, int *operState);
 
 ROUTING_TABLE *SnmpGetRoutingTable(DWORD dwVersion, SNMP_Transport *pTransport);
 
index 7069733..2be1613 100644 (file)
@@ -597,6 +597,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_adminState;                              // interface administrative state
+       WORD m_operState;                                       // interface operational state
        WORD m_dot1xPaeAuthState;               // 802.1x port auth state
        WORD m_dot1xBackendAuthState;   // 802.1x backend auth state
    QWORD m_qwLastDownEventId;
@@ -629,6 +631,10 @@ public:
        DWORD getPortNumber() { return m_portNumber; }
        DWORD getPeerNodeId() { return m_peerNodeId; }
        DWORD getPeerInterfaceId() { return m_peerInterfaceId; }
+       int getAdminState() { return (int)m_adminState; }
+       int getOperState() { return (int)m_operState; }
+       int getDot1xPaeAuthState() { return (int)m_dot1xPaeAuthState; }
+       int getDot1xBackendAuthState() { return (int)m_dot1xBackendAuthState; }
        const TCHAR *getDescription() { return m_description; }
    const BYTE *getMacAddr() { return m_bMacAddr; }
        bool isSyntheticMask() { return (m_flags & IF_SYNTHETIC_MASK) ? true : false; }
@@ -892,8 +898,8 @@ public:
        Interface *findInterfaceBySlotAndPort(DWORD slot, DWORD port);
        Interface *findBridgePort(DWORD bridgePortNumber);
        BOOL isMyIP(DWORD dwIpAddr);
-   int getInterfaceStatusFromSNMP(SNMP_Transport *pTransport, DWORD dwIndex);
-   int getInterfaceStatusFromAgent(DWORD dwIndex);
+   void getInterfaceStatusFromSNMP(SNMP_Transport *pTransport, DWORD dwIndex, int *adminState, int *operState);
+   void getInterfaceStatusFromAgent(DWORD dwIndex, int *adminState, int *operState);
    ROUTING_TABLE *getRoutingTable();
    ROUTING_TABLE *getCachedRoutingTable() { return m_pRoutingTable; }
        LinkLayerNeighbors *getLinkLayerNeighbors();
index a1ad865..4c3a3f2 100644 (file)
@@ -2,8 +2,7 @@ INCLUDES=-I@top_srcdir@/include -I@top_srcdir@/src/server/include
 
 lib_LTLIBRARIES = libnxsrv.la
 libnxsrv_la_SOURCES = messages.c agent.cpp apinfo.cpp iflist.cpp isc.cpp \
-                      license.cpp main.cpp ndd.cpp snmp.cpp snmpproxy.cpp \
-                      vlan.cpp
+                      main.cpp ndd.cpp snmp.cpp snmpproxy.cpp vlan.cpp
 libnxsrv_la_LDFLAGS = -version-info $(NETXMS_LIBRARY_VERSION)
 libnxsrv_la_LIBADD = ../../libnetxms/libnetxms.la ../../snmp/libnxsnmp/libnxsnmp.la
 
index 163795c..773e652 100644 (file)
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath=".\license.cpp"\r
-                               >\r
-                       </File>\r
-                       <File\r
                                RelativePath=".\main.cpp"\r
                                >\r
                        </File>\r
diff --git a/src/server/libnxsrv/license.cpp b/src/server/libnxsrv/license.cpp
deleted file mode 100644 (file)
index ef09a7c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* 
-** NetXMS - Network Management System
-** Copyright (C) 2003-2010 Victor Kirhenshtein
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU Lesser General Public License as published by
-** the Free Software Foundation; either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-**
-** File: license.cpp
-**
-**/
-
-#include "libnxsrv.h"
-
-
-//
-// Request license from licensing server
-//
-
index 5011153..859b168 100644 (file)
@@ -279,6 +279,78 @@ static BOOL CreateEventTemplate(int code, const TCHAR *name, int severity, int f
 
 
 //
+// Upgrade from V251 to V252
+//
+
+static BOOL H_UpgradeFromV251(int currVersion, int newVersion)
+{
+       static TCHAR batch[] = 
+               _T("ALTER TABLE interfaces ADD admin_state integer\n")
+               _T("ALTER TABLE interfaces ADD oper_state integer\n")
+               _T("UPDATE interfaces SET admin_state=0,oper_state=0\n")
+               _T("<END>");
+
+       CHK_EXEC(SQLBatch(batch));
+
+       CHK_EXEC(CreateEventTemplate(EVENT_INTERFACE_UNEXPECTED_UP, _T("SYS_IF_UNEXPECTED_UP"), EVENT_SEVERITY_MAJOR, 1,
+                                    _T("Interface \"%2\" unexpectedly changed state to UP (IP Addr: %3/%4, IfIndex: %5)"), 
+                                                                                 _T("Generated when interface goes up but it's expected state set to DOWN.\r\n")
+                                                                                 _T("Please note that source of event is node, not an interface itself.\r\n")
+                                    _T("Parameters:#\r\n")
+                                                                                 _T("   1) Interface object ID\r\n")
+                                                                                 _T("   2) Interface name\r\n")
+                                                                                 _T("   3) Interface IP address\r\n")
+                                                                                 _T("   4) Interface netmask\r\n")
+                                                                                 _T("   5) Interface index")
+                                                                                 ));
+
+       CHK_EXEC(CreateEventTemplate(EVENT_INTERFACE_EXPECTED_DOWN, _T("SYS_IF_EXPECTED_DOWN"), EVENT_SEVERITY_NORMAL, 1,
+                                    _T("Interface \"%2\" with expected state DOWN changed state to DOWN (IP Addr: %3/%4, IfIndex: %5)"), 
+                                                                                 _T("Generated when interface goes down and it's expected state is DOWN.\r\n")
+                                                                                 _T("Please note that source of event is node, not an interface itself.\r\n")
+                                    _T("Parameters:#\r\n")
+                                                                                 _T("   1) Interface object ID\r\n")
+                                                                                 _T("   2) Interface name\r\n")
+                                                                                 _T("   3) Interface IP address\r\n")
+                                                                                 _T("   4) Interface netmask\r\n")
+                                                                                 _T("   5) Interface index")
+                                                                                 ));
+
+       // Create rule pair in event processing policy
+       int ruleId = 0;
+       DB_RESULT hResult = SQLSelect(_T("SELECT max(rule_id) FROM event_policy"));
+       if (hResult != NULL)
+       {
+               ruleId = DBGetFieldLong(hResult, 0, 0) + 1;
+               DBFreeResult(hResult);
+       }
+
+       TCHAR query[1024];
+       _sntprintf(query, 1024, 
+               _T("INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,")
+               _T("script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)   VALUES ")
+               _T("(%d,7944,'Show alarm when interface is unexpectedly up','%%m',5,'IF_UNEXP_UP_%%i_%%1',")
+               _T("'#00',0,%d,0,'#00')"), ruleId, EVENT_ALARM_TIMEOUT);
+       CHK_EXEC(SQLQuery(query));
+       _sntprintf(query, 1024, _T("INSERT INTO policy_event_list (rule_id,event_code) VALUES (%d,%d)"), ruleId, EVENT_INTERFACE_UNEXPECTED_UP);
+       CHK_EXEC(SQLQuery(query));
+       ruleId++;
+
+       _sntprintf(query, 1024, 
+               _T("INSERT INTO event_policy (rule_id,flags,comments,alarm_message,alarm_severity,alarm_key,")
+               _T("script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance)   VALUES ")
+               _T("(%d,7944,'Acknowlege interface unexpectedly up alarms when interface goes down','%%m',")
+               _T("6,'IF_UNEXP_UP_%%i_%%1','#00',0,%d,0,'#00')"), ruleId, EVENT_ALARM_TIMEOUT);
+       CHK_EXEC(SQLQuery(query));
+       _sntprintf(query, 1024, _T("INSERT INTO policy_event_list (rule_id,event_code) VALUES (%d,%d)"), ruleId, EVENT_INTERFACE_EXPECTED_DOWN);
+       CHK_EXEC(SQLQuery(query));
+
+       CHK_EXEC(SQLQuery(_T("UPDATE metadata SET var_value='252' WHERE var_name='SchemaVersion'")));
+   return TRUE;
+}
+
+
+//
 // Upgrade from V250 to V251
 //
 
@@ -6168,6 +6240,7 @@ static struct
        { 248, 249, H_UpgradeFromV248 },
        { 249, 250, H_UpgradeFromV249 },
        { 250, 251, H_UpgradeFromV250 },
+       { 251, 252, H_UpgradeFromV251 },
    { 0, 0, NULL }
 };