zone ID can be set in agnet config to correctly mark proxied SNMP traps
authorVictor Kirhenshtein <victor@netxms.org>
Mon, 8 Aug 2016 08:38:00 +0000 (11:38 +0300)
committerVictor Kirhenshtein <victor@netxms.org>
Mon, 8 Aug 2016 08:38:00 +0000 (11:38 +0300)
ChangeLog
src/agent/core/nxagentd.cpp
src/agent/core/nxagentd.h
src/agent/core/snmptrapproxy.cpp
src/server/core/agent.cpp
src/server/core/snmptrap.cpp

index 2a35d89..ebdb1f0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,7 @@
 - Agent data reconciliation block size and timeout can be configured
 - New agent parameters System.CPU.CurrentUsage and System.CPU.CurrentUsage(*)
 - SSH subagent (for collecting data and executing actions via SSH)
+- Zone ID can be set for agent in SNMP proxy mode
 - Management console
        - New editors for Agent Config Policy and Log Parser Policy. 
        - DCI summary tables with empty menu path not shown in object context menu
index c3ce74d..5eb8e1f 100644 (file)
@@ -166,6 +166,7 @@ UINT32 g_longRunningQueryThreshold = 250;
 UINT32 g_dcReconciliationBlockSize = 1024;
 UINT32 g_dcReconciliationTimeout = 15000;
 UINT32 g_dcMaxCollectorPoolSize = 64;
+UINT32 g_zoneId = 0;
 #ifdef _WIN32
 UINT16 g_sessionAgentPort = 28180;
 #else
@@ -284,6 +285,7 @@ static NX_CFG_TEMPLATE m_cfgTemplate[] =
    { _T("SubAgent"), CT_STRING_LIST, '\n', 0, 0, 0, &m_pszSubagentList, NULL },
    { _T("TimeOut"), CT_IGNORE, 0, 0, 0, 0, NULL, NULL },
    { _T("WaitForProcess"), CT_STRING, 0, 0, MAX_PATH, 0, s_processToWaitFor, NULL },
+   { _T("ZoneId"), CT_LONG, 0, 0, 0, 0, &g_zoneId, NULL },
    { _T(""), CT_END_OF_LIST, 0, 0, 0, 0, NULL, NULL }
 };
 
index 5312d20..b1a9931 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ** NetXMS multiplatform core agent
-** Copyright (C) 2003-2015 Victor Kirhenshtein
+** Copyright (C) 2003-2016 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
@@ -642,6 +642,7 @@ extern UINT32 g_dwSNMPTimeout;
 extern UINT32 g_dwSNMPTrapPort;
 extern UINT32 g_longRunningQueryThreshold;
 extern UINT16 g_sessionAgentPort;
+extern UINT32 g_zoneId;
 
 extern Config *g_config;
 
index deb7aa7..8eab909 100644 (file)
@@ -155,6 +155,7 @@ THREAD_RESULT THREAD_CALL SNMPTrapSender(void *pArg)
       msg->setField(VID_PORT, pdu->port);
       msg->setField(VID_PDU_SIZE, pdu->lenght);
       msg->setField(VID_PDU, pdu->rawMessage, pdu->lenght);
+      msg->setField(VID_ZONE_ID, g_zoneId);
 
       if (g_dwFlags & AF_SUBAGENT_LOADER)
       {
index 0b4aa3b..e070ab8 100644 (file)
@@ -25,7 +25,7 @@
 /**
  * Externals
  */
-void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Transport *pTransport, SNMP_Engine *localEngine, bool isInformRq);
+void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, UINT32 zoneId, int srcPort, SNMP_Transport *pTransport, SNMP_Engine *localEngine, bool isInformRq);
 
 /**
  * Destructor for extended agent connection class
@@ -351,7 +351,8 @@ void AgentConnectionEx::onSnmpTrap(NXCPMessage *msg)
          UINT32 pduLenght = msg->getFieldAsUInt32(VID_PDU_SIZE);
          BYTE *pduBytes = (BYTE*)malloc(pduLenght);
          msg->getFieldAsBinary(VID_PDU, pduBytes, pduLenght);
-         Node *originNode = FindNodeByIP(0, originSenderIP);
+         UINT32 zoneId = IsZoningEnabled() ? msg->getFieldAsUInt32(VID_ZONE_ID) : 0;
+         Node *originNode = FindNodeByIP(zoneId, originSenderIP);
          if ((originNode != NULL) || ConfigReadInt(_T("LogAllSNMPTraps"), FALSE))
          {
             SNMP_PDU *pdu = new SNMP_PDU;
@@ -367,7 +368,7 @@ void AgentConnectionEx::onSnmpTrap(NXCPMessage *msg)
                      SNMP_SecurityContext *context = snmpTransport->getSecurityContext();
                      context->setAuthoritativeEngine(localEngine);
                   }
-                  ProcessTrap(pdu, originSenderIP, msg->getFieldAsUInt16(VID_PORT), snmpTransport, &localEngine, isInformRequest);
+                  ProcessTrap(pdu, originSenderIP, zoneId, msg->getFieldAsUInt16(VID_PORT), snmpTransport, &localEngine, isInformRequest);
                   delete snmpTransport;
                }
                else if ((pdu->getVersion() == SNMP_VERSION_3) && (pdu->getCommand() == SNMP_GET_REQUEST) && (pdu->getAuthoritativeEngine().getIdLen() == 0))
index 1e2530e..abf3876 100644 (file)
@@ -258,12 +258,11 @@ static void BroadcastNewTrap(ClientSession *pSession, void *pArg)
 /**
  * Process trap
  */
-void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Transport *snmpTransport, SNMP_Engine *localEngine, bool isInformRq)
+void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, UINT32 zoneId, int srcPort, SNMP_Transport *snmpTransport, SNMP_Engine *localEngine, bool isInformRq)
 {
    UINT32 dwBufPos, dwBufSize, dwMatchLen, dwMatchIdx;
    TCHAR *pszTrapArgs, szBuffer[4096];
    SNMP_Variable *pVar;
-   Node *pNode;
        BOOL processed = FALSE;
    int iResult;
 
@@ -285,10 +284,10 @@ void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Tr
        }
 
    // Match IP address to object
-   pNode = FindNodeByIP((g_flags & AF_TRAP_SOURCES_IN_ALL_ZONES) ? ALL_ZONES : 0, srcAddr);
+   Node *node = FindNodeByIP((g_flags & AF_TRAP_SOURCES_IN_ALL_ZONES) ? ALL_ZONES : zoneId, srcAddr);
 
    // Write trap to log if required
-   if (m_bLogAllTraps || (pNode != NULL))
+   if (m_bLogAllTraps || (node != NULL))
    {
       NXCPMessage msg;
       TCHAR szQuery[8192], oidText[1024];
@@ -313,7 +312,7 @@ void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Tr
                                 _T("ip_addr,object_id,trap_oid,trap_varlist) VALUES ")
                                 _T("(") INT64_FMT _T(",%d,'%s',%d,'%s',%s)"),
                  m_qnTrapId, dwTimeStamp, srcAddr.toString(szBuffer),
-                 (pNode != NULL) ? pNode->getId() : (UINT32)0, pdu->getTrapId()->toString(oidText, 1024),
+                 (node != NULL) ? node->getId() : (UINT32)0, pdu->getTrapId()->toString(oidText, 1024),
                  (const TCHAR *)DBPrepareString(g_dbDriver, pszTrapArgs));
       QueueSQLRequest(szQuery);
 
@@ -324,7 +323,7 @@ void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Tr
       msg.setField(VID_TRAP_LOG_MSG_BASE, (QWORD)m_qnTrapId);
       msg.setField(VID_TRAP_LOG_MSG_BASE + 1, dwTimeStamp);
       msg.setField(VID_TRAP_LOG_MSG_BASE + 2, srcAddr);
-      msg.setField(VID_TRAP_LOG_MSG_BASE + 3, (pNode != NULL) ? pNode->getId() : (UINT32)0);
+      msg.setField(VID_TRAP_LOG_MSG_BASE + 3, (node != NULL) ? node->getId() : (UINT32)0);
       msg.setField(VID_TRAP_LOG_MSG_BASE + 4, pdu->getTrapId()->toString(oidText, 1024));
       msg.setField(VID_TRAP_LOG_MSG_BASE + 5, pszTrapArgs);
       EnumerateClientSessions(BroadcastNewTrap, &msg);
@@ -334,11 +333,11 @@ void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Tr
    }
 
    // Process trap if it is coming from host registered in database
-   if (pNode != NULL)
+   if (node != NULL)
    {
-      DbgPrintf(4, _T("ProcessTrap: trap matched to node %s [%d]"), pNode->getName(), pNode->getId());
-      pNode->incSnmpTrapCount();
-      if ((pNode->getStatus() != STATUS_UNMANAGED) || (g_flags & AF_TRAPS_FROM_UNMANAGED_NODES))
+      DbgPrintf(4, _T("ProcessTrap: trap matched to node %s [%d]"), node->getName(), node->getId());
+      node->incSnmpTrapCount();
+      if ((node->getStatus() != STATUS_UNMANAGED) || (g_flags & AF_TRAPS_FROM_UNMANAGED_NODES))
       {
          UINT32 i;
 
@@ -349,7 +348,7 @@ void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Tr
             {
                if (g_pModuleList[i].pfTrapHandler != NULL)
                {
-                  if (g_pModuleList[i].pfTrapHandler(pdu, pNode))
+                  if (g_pModuleList[i].pfTrapHandler(pdu, node))
                                      {
                                              processed = TRUE;
                      break;   // Trap was processed by the module
@@ -386,7 +385,7 @@ void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Tr
 
          if (dwMatchLen > 0)
          {
-            GenerateTrapEvent(pNode->getId(), dwMatchIdx, pdu, srcPort);
+            GenerateTrapEvent(node->getId(), dwMatchIdx, pdu, srcPort);
          }
          else     // Process unmatched traps
          {
@@ -411,7 +410,7 @@ void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Tr
 
                // Generate default event for unmatched traps
                const TCHAR *names[3] = { _T("oid"), NULL, _T("sourcePort") };
-               PostEventWithNames(EVENT_SNMP_UNMATCHED_TRAP, pNode->getId(), "ssd", names,
+               PostEventWithNames(EVENT_SNMP_UNMATCHED_TRAP, node->getId(), "ssd", names,
                   pdu->getTrapId()->toString(oidText, 1024), pszTrapArgs, srcPort);
                free(pszTrapArgs);
             }
@@ -420,13 +419,13 @@ void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Tr
       }
       else
       {
-         DbgPrintf(4, _T("ProcessTrap: Node %s [%d] is in UNMANAGED state, trap ignored"), pNode->getName(), pNode->getId());
+         DbgPrintf(4, _T("ProcessTrap: Node %s [%d] is in UNMANAGED state, trap ignored"), node->getName(), node->getId());
       }
    }
    else if (g_flags & AF_SNMP_TRAP_DISCOVERY)  // unknown node, discovery enabled
    {
       DbgPrintf(4, _T("ProcessTrap: trap not matched to node, adding new IP address %s for discovery"), srcAddr.toString(szBuffer));
-      Subnet *subnet = FindSubnetForNode(0, srcAddr);
+      Subnet *subnet = FindSubnetForNode(zoneId, srcAddr);
       if (subnet != NULL)
       {
          if (!subnet->getIpAddress().equals(srcAddr) && !srcAddr.isSubnetBroadcast(subnet->getIpAddress().getMaskBits()))
@@ -436,7 +435,7 @@ void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Tr
             pInfo = (NEW_NODE *)malloc(sizeof(NEW_NODE));
             pInfo->ipAddr = srcAddr;
             pInfo->ipAddr.setMaskBits(subnet->getIpAddress().getMaskBits());
-                               pInfo->zoneId = 0;      /* FIXME: add correct zone ID */
+                               pInfo->zoneId = zoneId;
                                pInfo->ignoreFilter = FALSE;
                                memset(pInfo->bMacAddr, 0, MAC_ADDR_LENGTH);
             g_nodePollerQueue.put(pInfo);
@@ -448,7 +447,7 @@ void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Tr
 
          pInfo = (NEW_NODE *)malloc(sizeof(NEW_NODE));
          pInfo->ipAddr = srcAddr;
-                       pInfo->zoneId = 0;      /* FIXME: add correct zone ID */
+                       pInfo->zoneId = zoneId;
                        pInfo->ignoreFilter = FALSE;
                        memset(pInfo->bMacAddr, 0, MAC_ADDR_LENGTH);
          g_nodePollerQueue.put(pInfo);
@@ -668,7 +667,7 @@ THREAD_RESULT THREAD_CALL SNMPTrapReceiver(void *pArg)
                                           SNMP_SecurityContext *context = transport->getSecurityContext();
                                           context->setAuthoritativeEngine(localEngine);
                                   }
-               ProcessTrap(pdu, sourceAddr, ntohs(SA_PORT(&addr)), transport, &localEngine, pdu->getCommand() == SNMP_INFORM_REQUEST);
+               ProcessTrap(pdu, sourceAddr, 0, ntohs(SA_PORT(&addr)), transport, &localEngine, pdu->getCommand() == SNMP_INFORM_REQUEST);
                           }
                           else if ((pdu->getVersion() == SNMP_VERSION_3) && (pdu->getCommand() == SNMP_GET_REQUEST) && (pdu->getAuthoritativeEngine().getIdLen() == 0))
                           {