nxapush can push data on behalf of other nodes
[public/netxms.git] / src / server / core / agent.cpp
CommitLineData
5039dede
AK
1/*
2** NetXMS - Network Management System
df94e0ce 3** Copyright (C) 2003-2012 Victor Kirhenshtein
5039dede
AK
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18**
19** File: agent.cpp
20**
21**/
22
23#include "nxcore.h"
24
d1c1c522
VK
25/**
26 * Destructor for extended agent connection class
27 */
5039dede
AK
28AgentConnectionEx::~AgentConnectionEx()
29{
30}
31
d1c1c522
VK
32/**
33 * Trap processor
34 */
f480bdd4 35void AgentConnectionEx::onTrap(CSCPMessage *pMsg)
5039dede 36{
967893bb 37 UINT32 dwEventCode;
5039dede 38 int i, iNumArgs;
d1c1c522 39 Node *pNode = NULL;
5039dede 40 TCHAR *pszArgList[32], szBuffer[32];
35f836fe 41 char szFormat[] = "ssssssssssssssssssssssssssssssss";
5039dede 42
d1c1c522
VK
43 DbgPrintf(3, _T("AgentConnectionEx::onTrap(): Received trap message from agent at %s, node ID %d"), IpToStr(getIpAddr(), szBuffer), m_nodeId);
44 if (m_nodeId != 0)
45 pNode = (Node *)FindObjectById(m_nodeId, OBJECT_NODE);
46 if (pNode == NULL)
47 pNode = FindNodeByIP(0, getIpAddr());
5039dede
AK
48 if (pNode != NULL)
49 {
fed33789
VK
50 // Check for duplicate traps - only accept traps with ID
51 // higher than last received
52 // agents prior to 1.1.6 will not send trap id
53 // we should accept trap in that case to maintain compatibility
54 bool acceptTrap;
55 QWORD trapId = pMsg->GetVariableInt64(VID_TRAP_ID);
56 if (trapId != 0)
57 {
58 acceptTrap = pNode->checkAgentTrapId(trapId);
59 DbgPrintf(5, _T("AgentConnectionEx::onTrap(): trapID is%s valid"), acceptTrap ? _T("") : _T(" not"));
60 }
61 else
62 {
63 acceptTrap = true;
64 DbgPrintf(5, _T("AgentConnectionEx::onTrap(): trap ID not provided"));
65 }
66
67 if (acceptTrap)
68 {
69 dwEventCode = pMsg->GetVariableLong(VID_EVENT_CODE);
2dd24569
VK
70 if ((dwEventCode == 0) && pMsg->IsVariableExist(VID_EVENT_NAME))
71 {
72 TCHAR eventName[256];
73 pMsg->GetVariableStr(VID_EVENT_NAME, eventName, 256);
74 dwEventCode = EventCodeFromName(eventName, 0);
75 }
fed33789
VK
76 iNumArgs = (int)pMsg->GetVariableShort(VID_NUM_ARGS);
77 if (iNumArgs > 32)
78 iNumArgs = 32;
79 for(i = 0; i < iNumArgs; i++)
80 pszArgList[i] = pMsg->GetVariableStr(VID_EVENT_ARG_BASE + i);
81 DbgPrintf(3, _T("Event from trap: %d"), dwEventCode);
5039dede 82
fed33789
VK
83 // Following call is not very good, but I'm too lazy now
84 // to change PostEvent()
85 szFormat[iNumArgs] = 0;
86 PostEvent(dwEventCode, pNode->Id(), (iNumArgs > 0) ? szFormat : NULL,
87 pszArgList[0], pszArgList[1], pszArgList[2], pszArgList[3],
88 pszArgList[4], pszArgList[5], pszArgList[6], pszArgList[7],
89 pszArgList[8], pszArgList[9], pszArgList[10], pszArgList[11],
90 pszArgList[12], pszArgList[13], pszArgList[14], pszArgList[15],
91 pszArgList[16], pszArgList[17], pszArgList[18], pszArgList[19],
92 pszArgList[20], pszArgList[21], pszArgList[22], pszArgList[23],
93 pszArgList[24], pszArgList[25], pszArgList[26], pszArgList[27],
94 pszArgList[28], pszArgList[29], pszArgList[30], pszArgList[31]);
95
96 // Cleanup
97 for(i = 0; i < iNumArgs; i++)
98 free(pszArgList[i]);
99 }
5039dede
AK
100 }
101 else
102 {
7c521895 103 DbgPrintf(3, _T("Cannot find node for IP address %s"), IpToStr(getIpAddr(), szBuffer));
5039dede
AK
104 }
105}
45d84f8a 106
d1c1c522
VK
107/**
108 * Handler for data push
109 */
f480bdd4
VK
110void AgentConnectionEx::onDataPush(CSCPMessage *msg)
111{
112 TCHAR name[MAX_PARAM_NAME], value[MAX_RESULT_LENGTH];
113
114 msg->GetVariableStr(VID_NAME, name, MAX_PARAM_NAME);
115 msg->GetVariableStr(VID_VALUE, value, MAX_RESULT_LENGTH);
116
4e46505f
VK
117 Node *sender = FindNodeByIP(0, getIpAddr()); /* FIXME: is it possible to receive push data form other zones? */
118 if (sender != NULL)
f480bdd4 119 {
4e46505f
VK
120 Node *target;
121 UINT32 objectId = msg->GetVariableLong(VID_OBJECT_ID);
122 if (objectId != 0)
123 {
124 // push on behalf of other node
125 target = (Node *)FindObjectById(objectId, OBJECT_NODE);
126 if (target != NULL)
127 {
128 if (target->isTrustedNode(sender->Id()))
129 {
130 DbgPrintf(5, _T("%s: agent data push: target set to %s [%d]"), sender->Name(), target->Name(), target->Id());
131 }
132 else
133 {
134 DbgPrintf(5, _T("%s: agent data push: not in trusted node list for target %s [%d]"), sender->Name(), target->Name(), target->Id());
135 target = NULL;
136 }
137 }
138 }
139 else
140 {
141 target = sender;
142 }
143
144 if (target != NULL)
145 {
146 DbgPrintf(5, _T("%s: agent data push: %s=%s"), target->Name(), name, value);
147 DCObject *dci = target->getDCObjectByName(name);
148 if ((dci != NULL) && (dci->getType() == DCO_TYPE_ITEM) && (dci->getDataSource() == DS_PUSH_AGENT) && (dci->getStatus() == ITEM_STATUS_ACTIVE))
149 {
150 DbgPrintf(5, _T("%s: agent data push: found DCI %d"), target->Name(), dci->getId());
151 time_t t = time(NULL);
152 target->processNewDCValue(dci, t, value);
153 dci->setLastPollTime(t);
154 }
155 else
156 {
157 DbgPrintf(5, _T("%s: agent data push: DCI not found for %s"), target->Name(), name);
158 }
159 }
160 else
161 {
162 DbgPrintf(5, _T("%s: agent data push: target node not found or not accessible"), sender->Name());
163 }
f480bdd4
VK
164 }
165}
166
d1c1c522
VK
167/**
168 * Deploy policy to agent
169 */
967893bb 170UINT32 AgentConnectionEx::deployPolicy(AgentPolicy *policy)
45d84f8a 171{
967893bb 172 UINT32 rqId, rcc;
45d84f8a
VK
173 CSCPMessage msg(getProtocolVersion());
174
175 rqId = generateRequestId();
176 msg.SetId(rqId);
177 msg.SetCode(CMD_DEPLOY_AGENT_POLICY);
8051849b
VK
178 if (policy->createDeploymentMessage(&msg))
179 {
7c521895 180 if (sendMessage(&msg))
8051849b 181 {
7c521895 182 rcc = waitForRCC(rqId, getCommandTimeout());
8051849b
VK
183 }
184 else
185 {
186 rcc = ERR_CONNECTION_BROKEN;
187 }
188 }
189 else
190 {
191 rcc = ERR_INTERNAL_ERROR;
192 }
45d84f8a
VK
193 return rcc;
194}
93599cfd 195
d1c1c522
VK
196/**
197 * Uninstall policy from agent
198 */
967893bb 199UINT32 AgentConnectionEx::uninstallPolicy(AgentPolicy *policy)
93599cfd 200{
967893bb 201 UINT32 rqId, rcc;
93599cfd
VK
202 CSCPMessage msg(getProtocolVersion());
203
204 rqId = generateRequestId();
205 msg.SetId(rqId);
206 msg.SetCode(CMD_UNINSTALL_AGENT_POLICY);
207 if (policy->createUninstallMessage(&msg))
208 {
7c521895 209 if (sendMessage(&msg))
93599cfd 210 {
7c521895 211 rcc = waitForRCC(rqId, getCommandTimeout());
93599cfd
VK
212 }
213 else
214 {
215 rcc = ERR_CONNECTION_BROKEN;
216 }
217 }
218 else
219 {
220 rcc = ERR_INTERNAL_ERROR;
221 }
222 return rcc;
223}