2 ** NetXMS - Network Management System
3 ** NetXMS Foundation Library
4 ** Copyright (C) 2003-2015 Victor Kirhenshtein
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU Lesser General Public License as published
8 ** by the Free Software Foundation; either version 3 of the License, or
9 ** (at your option) any later version.
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
16 ** You should have received a copy of the GNU Lesser General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "libnetxms.h"
33 * Get symbolic name for message code
35 TCHAR LIBNETXMS_EXPORTABLE
*NXCPMessageCodeName(WORD code
, TCHAR
*pszBuffer
)
37 static const TCHAR
*pszMsgNames
[] =
42 _T("CMD_OPEN_HELPDESK_ISSUE"),
43 _T("CMD_GET_OBJECTS"),
45 _T("CMD_DELETE_OBJECT"),
46 _T("CMD_MODIFY_OBJECT"),
47 _T("CMD_OBJECT_LIST_END"),
48 _T("CMD_OBJECT_UPDATE"),
50 _T("CMD_EVENTLOG_RECORDS"),
51 _T("CMD_GET_CONFIG_VARLIST"),
52 _T("CMD_SET_CONFIG_VARIABLE"),
53 _T("CMD_GET_OBJECT_TOOLS"),
54 _T("CMD_EXECUTE_ACTION"),
55 _T("CMD_DELETE_CONFIG_VARIABLE"),
62 _T("CMD_EVENT_DB_UPDATE"),
63 _T("CMD_TRAP_CFG_UPDATE"),
64 _T("CMD_SET_EVENT_INFO"),
65 _T("CMD_EVENT_DB_RECORD"),
66 _T("CMD_LOAD_EVENT_DB"),
67 _T("CMD_REQUEST_COMPLETED"),
68 _T("CMD_LOAD_USER_DB"),
71 _T("CMD_USER_DB_EOF"),
72 _T("CMD_UPDATE_USER"),
73 _T("CMD_DELETE_USER"),
74 _T("CMD_CREATE_USER"),
75 _T("CMD_LOCK_USER_DB"),
76 _T("CMD_UNLOCK_USER_DB"),
77 _T("CMD_USER_DB_UPDATE"),
78 _T("CMD_SET_PASSWORD"),
79 _T("CMD_GET_NODE_DCI_LIST"),
81 _T("CMD_GET_LOG_DATA"),
82 _T("CMD_DELETE_NODE_DCI"),
83 _T("CMD_MODIFY_NODE_DCI"),
84 _T("CMD_UNLOCK_NODE_DCI_LIST"),
85 _T("CMD_SET_OBJECT_MGMT_STATUS"),
86 _T("CMD_CREATE_NEW_DCI"),
87 _T("CMD_GET_DCI_DATA"),
89 _T("CMD_GET_MIB_TIMESTAMP"),
91 _T("CMD_TEST_DCI_TRANSFORMATION"),
92 _T("CMD_GET_JOB_LIST"),
93 _T("CMD_CREATE_OBJECT"),
94 _T("CMD_GET_EVENT_NAMES"),
95 _T("CMD_EVENT_NAME_LIST"),
96 _T("CMD_BIND_OBJECT"),
97 _T("CMD_UNBIND_OBJECT"),
98 _T("CMD_UNINSTALL_AGENT_POLICY"),
99 _T("CMD_OPEN_SERVER_LOG"),
100 _T("CMD_CLOSE_SERVER_LOG"),
102 _T("CMD_AUTHENTICATE"),
103 _T("CMD_GET_PARAMETER"),
106 _T("CMD_GET_CURRENT_USER_ATTR"),
107 _T("CMD_SET_CURRENT_USER_ATTR"),
108 _T("CMD_GET_ALL_ALARMS"),
109 _T("CMD_GET_ALARM_COMMENTS"),
111 _T("CMD_ALARM_UPDATE"),
112 _T("CMD_ALARM_DATA"),
113 _T("CMD_DELETE_ALARM"),
114 _T("CMD_ADD_CLUSTER_NODE"),
115 _T("CMD_GET_POLICY_INVENTORY"),
116 _T("CMD_LOAD_ACTIONS"),
117 _T("CMD_ACTION_DB_UPDATE"),
118 _T("CMD_MODIFY_ACTION"),
119 _T("CMD_CREATE_ACTION"),
120 _T("CMD_DELETE_ACTION"),
121 _T("CMD_ACTION_DATA"),
122 _T("CMD_SETUP_AGENT_TUNNEL"),
128 _T("CMD_POLLING_INFO"),
130 _T("CMD_WAKEUP_NODE"),
131 _T("CMD_DELETE_EVENT_TEMPLATE"),
132 _T("CMD_GENERATE_EVENT_CODE"),
133 _T("CMD_FIND_NODE_CONNECTION"),
134 _T("CMD_FIND_MAC_LOCATION"),
135 _T("CMD_CREATE_TRAP"),
136 _T("CMD_MODIFY_TRAP"),
137 _T("CMD_DELETE_TRAP"),
138 _T("CMD_LOAD_TRAP_CFG"),
139 _T("CMD_TRAP_CFG_RECORD"),
140 _T("CMD_QUERY_PARAMETER"),
141 _T("CMD_GET_SERVER_INFO"),
142 _T("CMD_SET_DCI_STATUS"),
144 _T("CMD_TRANSFER_FILE"),
145 _T("CMD_UPGRADE_AGENT"),
146 _T("CMD_GET_PACKAGE_LIST"),
147 _T("CMD_PACKAGE_INFO"),
148 _T("CMD_REMOVE_PACKAGE"),
149 _T("CMD_INSTALL_PACKAGE"),
150 _T("CMD_LOCK_PACKAGE_DB"),
151 _T("CMD_UNLOCK_PACKAGE_DB"),
152 _T("CMD_ABORT_FILE_TRANSFER"),
153 _T("CMD_CHECK_NETWORK_SERVICE"),
154 _T("CMD_GET_AGENT_CONFIG"),
155 _T("CMD_UPDATE_AGENT_CONFIG"),
156 _T("CMD_GET_PARAMETER_LIST"),
157 _T("CMD_DEPLOY_PACKAGE"),
158 _T("CMD_INSTALLER_INFO"),
159 _T("CMD_GET_LAST_VALUES"),
160 _T("CMD_APPLY_TEMPLATE"),
161 _T("CMD_SET_USER_VARIABLE"),
162 _T("CMD_GET_USER_VARIABLE"),
163 _T("CMD_ENUM_USER_VARIABLES"),
164 _T("CMD_DELETE_USER_VARIABLE"),
165 _T("CMD_ADM_MESSAGE"),
166 _T("CMD_ADM_REQUEST"),
167 _T("CMD_GET_NETWORK_PATH"),
168 _T("CMD_REQUEST_SESSION_KEY"),
169 _T("CMD_ENCRYPTED_MESSAGE"),
170 _T("CMD_SESSION_KEY"),
171 _T("CMD_REQUEST_ENCRYPTION"),
172 _T("CMD_GET_ROUTING_TABLE"),
173 _T("CMD_EXEC_TABLE_TOOL"),
174 _T("CMD_TABLE_DATA"),
175 _T("CMD_CANCEL_JOB"),
176 _T("CMD_CHANGE_SUBSCRIPTION"),
177 _T("CMD_GET_SYSLOG"),
178 _T("CMD_SYSLOG_RECORDS"),
179 _T("CMD_JOB_CHANGE_NOTIFICATION"),
180 _T("CMD_DEPLOY_AGENT_POLICY"),
182 _T("CMD_GET_OBJECT_TOOL_DETAILS"),
183 _T("CMD_EXECUTE_SERVER_COMMAND"),
184 _T("CMD_UPLOAD_FILE_TO_AGENT"),
185 _T("CMD_UPDATE_OBJECT_TOOL"),
186 _T("CMD_DELETE_OBJECT_TOOL"),
187 _T("CMD_SETUP_PROXY_CONNECTION"),
188 _T("CMD_GENERATE_OBJECT_TOOL_ID"),
189 _T("CMD_GET_SERVER_STATS"),
190 _T("CMD_GET_SCRIPT_LIST"),
191 _T("CMD_GET_SCRIPT"),
192 _T("CMD_UPDATE_SCRIPT"),
193 _T("CMD_DELETE_SCRIPT"),
194 _T("CMD_RENAME_SCRIPT"),
195 _T("CMD_GET_SESSION_LIST"),
196 _T("CMD_KILL_SESSION"),
197 _T("CMD_GET_TRAP_LOG"),
198 _T("CMD_TRAP_LOG_RECORDS"),
199 _T("CMD_START_SNMP_WALK"),
200 _T("CMD_SNMP_WALK_DATA"),
201 _T("CMD_GET_MAP_LIST"),
204 _T("CMD_DELETE_MAP"),
205 _T("CMD_RESOLVE_MAP_NAME"),
206 _T("CMD_SUBMAP_DATA"),
207 _T("CMD_UPLOAD_SUBMAP_BK_IMAGE"),
208 _T("CMD_GET_SUBMAP_BK_IMAGE"),
209 _T("CMD_GET_MODULE_LIST"),
210 _T("CMD_UPDATE_MODULE_INFO"),
211 _T("CMD_COPY_USER_VARIABLE"),
212 _T("CMD_RESOLVE_DCI_NAMES"),
213 _T("CMD_GET_MY_CONFIG"),
214 _T("CMD_GET_AGENT_CFG_LIST"),
215 _T("CMD_OPEN_AGENT_CONFIG"),
216 _T("CMD_SAVE_AGENT_CONFIG"),
217 _T("CMD_DELETE_AGENT_CONFIG"),
218 _T("CMD_SWAP_AGENT_CONFIGS"),
219 _T("CMD_TERMINATE_ALARM"),
220 _T("CMD_GET_NXCP_CAPS"),
222 _T("CMD_GET_OBJECT_COMMENTS"),
223 _T("CMD_UPDATE_OBJECT_COMMENTS"),
224 _T("CMD_ENABLE_AGENT_TRAPS"),
225 _T("CMD_PUSH_DCI_DATA"),
226 _T("CMD_GET_ADDR_LIST"),
227 _T("CMD_SET_ADDR_LIST"),
228 _T("CMD_RESET_COMPONENT"),
229 _T("CMD_GET_DCI_EVENTS_LIST"),
230 _T("CMD_EXPORT_CONFIGURATION"),
231 _T("CMD_IMPORT_CONFIGURATION"),
232 _T("CMD_GET_TRAP_CFG_RO"),
233 _T("CMD_SNMP_REQUEST"),
234 _T("CMD_GET_DCI_INFO"),
235 _T("CMD_GET_GRAPH_LIST"),
236 _T("CMD_SAVE_GRAPH"),
237 _T("CMD_DELETE_GRAPH"),
238 _T("CMD_GET_PERFTAB_DCI_LIST"),
239 _T("CMD_ADD_CA_CERTIFICATE"),
240 _T("CMD_DELETE_CERTIFICATE"),
241 _T("CMD_GET_CERT_LIST"),
242 _T("CMD_UPDATE_CERT_COMMENTS"),
243 _T("CMD_QUERY_L2_TOPOLOGY"),
244 _T("CMD_AUDIT_RECORD"),
245 _T("CMD_GET_AUDIT_LOG"),
247 _T("CMD_GET_COMMUNITY_LIST"),
248 _T("CMD_UPDATE_COMMUNITY_LIST"),
249 _T("CMD_GET_SITUATION_LIST"),
250 _T("CMD_DELETE_SITUATION"),
251 _T("CMD_CREATE_SITUATION"),
252 _T("CMD_DEL_SITUATION_INSTANCE"),
253 _T("CMD_UPDATE_SITUATION"),
254 _T("CMD_SITUATION_DATA"),
255 _T("CMD_SITUATION_CHANGE"),
256 _T("CMD_CREATE_MAP"),
257 _T("CMD_UPLOAD_FILE"),
258 _T("CMD_DELETE_FILE"),
259 _T("CMD_DELETE_REPORT_RESULTS"),
260 _T("CMD_RENDER_REPORT"),
261 _T("CMD_EXECUTE_REPORT"),
262 _T("CMD_GET_REPORT_RESULTS"),
263 _T("CMD_CONFIG_SET_CLOB"),
264 _T("CMD_CONFIG_GET_CLOB"),
265 _T("CMD_RENAME_MAP"),
266 _T("CMD_CLEAR_DCI_DATA"),
267 _T("CMD_GET_LICENSE"),
268 _T("CMD_CHECK_LICENSE"),
269 _T("CMD_RELEASE_LICENSE"),
270 _T("CMD_ISC_CONNECT_TO_SERVICE"),
271 _T("CMD_REGISTER_AGENT"),
272 _T("CMD_GET_SERVER_FILE"),
273 _T("CMD_FORWARD_EVENT"),
274 _T("CMD_GET_USM_CREDENTIALS"),
275 _T("CMD_UPDATE_USM_CREDENTIALS"),
276 _T("CMD_GET_DCI_THRESHOLDS"),
278 _T("CMD_CREATE_IMAGE"),
279 _T("CMD_DELETE_IMAGE"),
280 _T("CMD_MODIFY_IMAGE"),
281 _T("CMD_LIST_IMAGES"),
282 _T("CMD_LIST_SERVER_FILES"),
284 _T("CMD_QUERY_TABLE"),
285 _T("CMD_OPEN_CONSOLE"),
286 _T("CMD_CLOSE_CONSOLE"),
287 _T("CMD_GET_SELECTED_OBJECTS"),
290 _T("CMD_UNHOLD_JOB"),
291 _T("CMD_CHANGE_ZONE"),
292 _T("CMD_GET_AGENT_FILE"),
293 _T("CMD_GET_FILE_DETAILS"),
294 _T("CMD_IMAGE_LIBRARY_UPDATE"),
295 _T("CMD_GET_NODE_COMPONENTS"),
296 _T("CMD_UPDATE_ALARM_COMMENT"),
298 _T("CMD_GET_TABLE_LAST_VALUES"),
299 _T("CMD_GET_TABLE_DCI_DATA"),
300 _T("CMD_GET_THRESHOLD_SUMMARY"),
301 _T("CMD_RESOLVE_ALARM"),
302 _T("CMD_FIND_IP_LOCATION"),
303 _T("CMD_REPORT_DEVICE_STATUS"),
304 _T("CMD_REPORT_DEVICE_INFO"),
305 _T("CMD_GET_ALARM_EVENTS"),
306 _T("CMD_GET_ENUM_LIST"),
307 _T("CMD_GET_TABLE_LIST"),
308 _T("CMD_GET_MAPPING_TABLE"),
309 _T("CMD_UPDATE_MAPPING_TABLE"),
310 _T("CMD_DELETE_MAPPING_TABLE"),
311 _T("CMD_LIST_MAPPING_TABLES"),
312 _T("CMD_GET_NODE_SOFTWARE"),
313 _T("CMD_GET_WINPERF_OBJECTS"),
314 _T("CMD_GET_WIRELESS_STATIONS"),
315 _T("CMD_GET_SUMMARY_TABLES"),
316 _T("CMD_MODIFY_SUMMARY_TABLE"),
317 _T("CMD_DELETE_SUMMARY_TABLE"),
318 _T("CMD_GET_SUMMARY_TABLE_DETAILS"),
319 _T("CMD_QUERY_SUMMARY_TABLE"),
322 _T("CMD_GET_SUBNET_ADDRESS_MAP"),
323 _T("CMD_FILE_MONITORING"),
324 _T("CMD_CANCEL_FILE_MONITORING"),
325 _T("CMD_CHANGE_OBJECT_TOOL_STATUS"),
326 _T("CMD_SET_ALARM_STATUS_FLOW"),
327 _T("CMD_DELETE_ALARM_COMMENT"),
328 _T("CMD_GET_EFFECTIVE_RIGHTS"),
329 _T("CMD_GET_DCI_VALUES"),
330 _T("CMD_GET_HELPDESK_URL"),
331 _T("CMD_UNLINK_HELPDESK_ISSUE"),
332 _T("CMD_GET_FOLDER_CONTENT"),
333 _T("CMD_FILEMGR_DELETE_FILE"),
334 _T("CMD_FILEMGR_RENAME_FILE"),
335 _T("CMD_FILEMGR_MOVE_FILE"),
336 _T("CMD_FILEMGR_UPLOAD"),
337 _T("CMD_GET_SWITCH_FDB"),
338 _T("CMD_COMMAND_OUTPUT"),
339 _T("CMD_GET_LOC_HISTORY"),
340 _T("CMD_TAKE_SCREENSHOT"),
341 _T("CMD_EXECUTE_SCRIPT"),
342 _T("CMD_EXECUTE_SCRIPT_UPDATE"),
343 _T("CMD_FILEMGR_CREATE_FOLDER"),
344 _T("CMD_QUERY_ADHOC_SUMMARY_TABLE"),
345 _T("CMD_GRAPH_UPDATE"),
346 _T("CMD_SET_SERVER_CAPABILITIES"),
347 _T("CMD_FORCE_DCI_POLL"),
348 _T("CMD_GET_DCI_SCRIPT_LIST"),
349 _T("CMD_DATA_COLLECTION_CONFIG"),
350 _T("CMD_SET_SERVER_ID"),
351 _T("CMD_GET_PUBLIC_CONFIG_VAR"),
352 _T("CMD_ENABLE_FILE_UPDATES"),
353 _T("CMD_DETACH_LDAP_USER"),
354 _T("CMD_VALIDATE_PASSWORD"),
355 _T("CMD_COMPILE_SCRIPT"),
356 _T("CMD_CLEAN_AGENT_DCI_CONF"),
357 _T("CMD_RESYNC_AGENT_DCI_CONF"),
358 _T("CMD_LIST_SCHEDULE_CALLBACKS"),
359 _T("CMD_LIST_SCHEDULES"),
360 _T("CMD_ADD_SCHEDULE"),
361 _T("CMD_UPDATE_SCHEDULE"),
362 _T("CMD_REMOVE_SCHEDULE"),
363 _T("CMD_ENTER_MAINT_MODE"),
364 _T("CMD_LEAVE_MAINT_MODE"),
365 _T("CMD_JOIN_CLUSTER"),
366 _T("CMD_CLUSTER_NOTIFY"),
367 _T("CMD_ZMQ_SUBSCRIBE_EVENT"),
368 _T("CMD_ZMQ_UNSUBSCRIBE_EVENT"),
369 _T("CMD_ZMQ_SUBSCRIBE_DATA"),
370 _T("CMD_ZMQ_UNSUBSCRIBE_DATA"),
371 _T("CMD_ZMQ_GET_EVT_SUBSCRIPTIONS"),
372 _T("CMD_ZMQ_GET_DATA_SUBSCRIPTIONS"),
373 _T("CMD_GET_REPOSITORIES"),
374 _T("CMD_ADD_REPOSITORY"),
375 _T("CMD_MODIFY_REPOSITORY"),
376 _T("CMD_DELETE_REPOSITORY")
379 if ((code
>= CMD_LOGIN
) && (code
<= CMD_DELETE_REPOSITORY
))
380 _tcscpy(pszBuffer
, pszMsgNames
[code
- CMD_LOGIN
]);
382 _sntprintf(pszBuffer
, 64, _T("CMD_0x%04X"), code
);
387 * Receive raw CSCP message from network
388 * If pMsg is NULL, temporary buffer will be re-initialized
389 * Returns message size on success or:
390 * 0 if connection is closed
391 * <0 on socket errors
392 * 1 if message is too large to fit in buffer (normal messages is at least 16
393 * bytes long, so we never get length of 1 for valid message)
394 * In this case, only message header will be copied into buffer
395 * 2 Message decryption failed
398 int LIBNETXMS_EXPORTABLE
RecvNXCPMessageEx(SOCKET hSocket
, NXCP_MESSAGE
**msgBuffer
,
399 NXCP_BUFFER
*nxcpBuffer
, UINT32
*bufferSize
,
400 NXCPEncryptionContext
**ppCtx
,
401 BYTE
**decryptionBuffer
, UINT32 dwTimeout
,
404 UINT32 dwMsgSize
= 0, dwBytesRead
= 0, dwBytesToCopy
;
406 BOOL bSkipMsg
= FALSE
;
408 // Initialize buffer if requested
409 if (msgBuffer
== NULL
)
411 nxcpBuffer
->bufferSize
= 0;
412 nxcpBuffer
->bufferPos
= 0;
416 // Check if we have something in buffer
417 if (nxcpBuffer
->bufferSize
> 0)
419 // Handle the case when entire message header have not been read into the buffer
420 if (nxcpBuffer
->bufferSize
< NXCP_HEADER_SIZE
)
422 // Most likely we are at the buffer end, so move content
424 memmove(nxcpBuffer
->buffer
, &nxcpBuffer
->buffer
[nxcpBuffer
->bufferPos
], nxcpBuffer
->bufferSize
);
425 nxcpBuffer
->bufferPos
= 0;
427 // Receive new portion of data from the network
428 // and append it to existing data in buffer
429 iErr
= RecvEx(hSocket
, &nxcpBuffer
->buffer
[nxcpBuffer
->bufferSize
],
430 NXCP_TEMP_BUF_SIZE
- nxcpBuffer
->bufferSize
, 0, dwTimeout
);
432 return (iErr
== -2) ? 3 : iErr
;
433 nxcpBuffer
->bufferSize
+= (UINT32
)iErr
;
436 // Get message size from message header and copy available
437 // message bytes from buffer
438 dwMsgSize
= ntohl(((NXCP_MESSAGE
*)(&nxcpBuffer
->buffer
[nxcpBuffer
->bufferPos
]))->size
);
439 if (dwMsgSize
> *bufferSize
)
441 if ((*bufferSize
>= maxMsgSize
) || (dwMsgSize
> maxMsgSize
))
443 bSkipMsg
= TRUE
; // Message is too large, will skip it
444 memcpy(*msgBuffer
, &nxcpBuffer
->buffer
[nxcpBuffer
->bufferPos
], NXCP_HEADER_SIZE
);
449 *bufferSize
= dwMsgSize
;
450 *msgBuffer
= (NXCP_MESSAGE
*)realloc(*msgBuffer
, *bufferSize
);
451 if (decryptionBuffer
!= NULL
)
452 *decryptionBuffer
= (BYTE
*)realloc(*decryptionBuffer
, *bufferSize
);
455 dwBytesRead
= min(dwMsgSize
, nxcpBuffer
->bufferSize
);
457 memcpy(*msgBuffer
, &nxcpBuffer
->buffer
[nxcpBuffer
->bufferPos
], dwBytesRead
);
458 nxcpBuffer
->bufferSize
-= dwBytesRead
;
459 nxcpBuffer
->bufferPos
= (nxcpBuffer
->bufferSize
> 0) ? (nxcpBuffer
->bufferPos
+ dwBytesRead
) : 0;
460 if (dwBytesRead
== dwMsgSize
)
461 goto decrypt_message
;
464 // Receive rest of message from the network
465 // Buffer is empty now
466 nxcpBuffer
->bufferSize
= 0;
467 nxcpBuffer
->bufferPos
= 0;
470 iErr
= RecvEx(hSocket
, &nxcpBuffer
->buffer
[nxcpBuffer
->bufferSize
],
471 NXCP_TEMP_BUF_SIZE
- nxcpBuffer
->bufferSize
, 0, dwTimeout
);
473 return (iErr
== -2) ? 3 : iErr
;
475 if (dwBytesRead
== 0) // New message?
477 if ((iErr
+ nxcpBuffer
->bufferSize
) < NXCP_HEADER_SIZE
)
479 // Header not received completely
480 nxcpBuffer
->bufferSize
+= iErr
;
483 iErr
+= nxcpBuffer
->bufferSize
;
484 nxcpBuffer
->bufferSize
= 0;
486 dwMsgSize
= ntohl(((NXCP_MESSAGE
*)(nxcpBuffer
->buffer
))->size
);
487 if (dwMsgSize
> *bufferSize
)
489 if ((*bufferSize
>= maxMsgSize
) || (dwMsgSize
> maxMsgSize
))
491 bSkipMsg
= TRUE
; // Message is too large, will skip it
492 memcpy(*msgBuffer
, nxcpBuffer
->buffer
, NXCP_HEADER_SIZE
);
497 *bufferSize
= dwMsgSize
;
498 *msgBuffer
= (NXCP_MESSAGE
*)realloc(*msgBuffer
, *bufferSize
);
499 if (decryptionBuffer
!= NULL
)
500 *decryptionBuffer
= (BYTE
*)realloc(*decryptionBuffer
, *bufferSize
);
504 dwBytesToCopy
= min((UINT32
)iErr
, dwMsgSize
- dwBytesRead
);
506 memcpy(((char *)(*msgBuffer
)) + dwBytesRead
, nxcpBuffer
->buffer
, dwBytesToCopy
);
507 dwBytesRead
+= dwBytesToCopy
;
509 while((dwBytesRead
< dwMsgSize
) || (dwBytesRead
< NXCP_HEADER_SIZE
));
511 // Check if we have something left in buffer
512 if (dwBytesToCopy
< (UINT32
)iErr
)
514 nxcpBuffer
->bufferPos
= dwBytesToCopy
;
515 nxcpBuffer
->bufferSize
= (UINT32
)iErr
- dwBytesToCopy
;
518 // Check for encrypted message
520 if ((!bSkipMsg
) && (ntohs((*msgBuffer
)->code
) == CMD_ENCRYPTED_MESSAGE
))
522 if ((*ppCtx
!= NULL
) && (*ppCtx
!= PROXY_ENCRYPTION_CTX
))
524 if ((*ppCtx
)->decryptMessage((NXCP_ENCRYPTED_MESSAGE
*)(*msgBuffer
), *decryptionBuffer
))
526 dwMsgSize
= ntohl((*msgBuffer
)->size
);
530 dwMsgSize
= 2; // Decryption failed
535 if (*ppCtx
!= PROXY_ENCRYPTION_CTX
)
540 return bSkipMsg
? 1 : (int)dwMsgSize
;
543 int LIBNETXMS_EXPORTABLE
RecvNXCPMessage(SOCKET hSocket
, NXCP_MESSAGE
*msgBuffer
,
544 NXCP_BUFFER
*nxcpBuffer
, UINT32 bufferSize
,
545 NXCPEncryptionContext
**ppCtx
,
546 BYTE
*decryptionBuffer
, UINT32 dwTimeout
)
548 NXCP_MESSAGE
*mb
= msgBuffer
;
549 UINT32 bs
= bufferSize
;
550 BYTE
*db
= decryptionBuffer
;
551 return RecvNXCPMessageEx(hSocket
, (msgBuffer
!= NULL
) ? &mb
: NULL
, nxcpBuffer
, &bs
, ppCtx
,
552 (decryptionBuffer
!= NULL
) ? &db
: NULL
, dwTimeout
, bufferSize
);
556 * Create NXCP message with raw data (MF_BINARY flag)
557 * If pBuffer is NULL, new buffer is allocated with malloc()
558 * Buffer should be of dwDataSize + NXCP_HEADER_SIZE + 8 bytes.
560 NXCP_MESSAGE LIBNETXMS_EXPORTABLE
*CreateRawNXCPMessage(WORD code
, UINT32 id
, WORD flags
,
561 UINT32 dwDataSize
, void *pData
,
562 NXCP_MESSAGE
*pBuffer
)
568 pMsg
= (NXCP_MESSAGE
*)malloc(dwDataSize
+ NXCP_HEADER_SIZE
+ 8);
572 // Message should be aligned to 8 bytes boundary
573 dwPadding
= (8 - ((dwDataSize
+ NXCP_HEADER_SIZE
) % 8)) & 7;
575 pMsg
->code
= htons(code
);
576 pMsg
->flags
= htons(MF_BINARY
| flags
);
577 pMsg
->id
= htonl(id
);
578 pMsg
->size
= htonl(dwDataSize
+ NXCP_HEADER_SIZE
+ dwPadding
);
579 pMsg
->numFields
= htonl(dwDataSize
); // numFields contains actual data size for binary message
580 memcpy(pMsg
->fields
, pData
, dwDataSize
);
586 * Send file over CSCP
588 BOOL LIBNETXMS_EXPORTABLE
SendFileOverNXCP(SOCKET hSocket
, UINT32 id
, const TCHAR
*pszFile
,
589 NXCPEncryptionContext
*pCtx
, long offset
,
590 void (* progressCallback
)(INT64
, void *), void *cbArg
,
591 MUTEX mutex
, NXCPCompressionMethod compressionMethod
)
594 INT64 bytesTransferred
= 0;
596 BOOL bResult
= FALSE
;
598 NXCP_ENCRYPTED_MESSAGE
*pEnMsg
;
600 StreamCompressor
*compressor
= (compressionMethod
!= NXCP_COMPRESSION_NONE
) ? StreamCompressor::create(compressionMethod
, true, FILE_BUFFER_SIZE
) : NULL
;
601 BYTE
*compBuffer
= (compressor
!= NULL
) ? (BYTE
*)malloc(FILE_BUFFER_SIZE
) : NULL
;
603 hFile
= _topen(pszFile
, O_RDONLY
| O_BINARY
);
607 NX_FSTAT(hFile
, &st
);
608 long fileSize
= (long)st
.st_size
;
609 if (labs(offset
) > fileSize
)
611 long bytesToRead
= (offset
< 0) ? (0 - offset
) : (fileSize
- offset
);
613 if (lseek(hFile
, offset
, (offset
< 0) ? SEEK_END
: SEEK_SET
) != -1)
615 // Allocate message and prepare it's header
616 pMsg
= (NXCP_MESSAGE
*)malloc(NXCP_HEADER_SIZE
+ 8 + ((compressor
!= NULL
) ? compressor
->compressBufferSize(FILE_BUFFER_SIZE
) + 4 : FILE_BUFFER_SIZE
));
617 pMsg
->id
= htonl(id
);
618 pMsg
->code
= htons(CMD_FILE_DATA
);
619 pMsg
->flags
= htons(MF_BINARY
| ((compressionMethod
!= NXCP_COMPRESSION_NONE
) ? MF_COMPRESSED
: 0));
623 if (compressor
!= NULL
)
625 iBytes
= read(hFile
, compBuffer
, min(FILE_BUFFER_SIZE
, bytesToRead
));
628 bytesToRead
-= iBytes
;
629 // Each compressed data block prepended with 4 bytes header
630 // First byte contains compression method, second is always 0,
631 // third and fourth contains uncompressed block size in network byte order
632 *((BYTE
*)pMsg
->fields
) = (BYTE
)compressionMethod
;
633 *((BYTE
*)pMsg
->fields
+ 1) = 0;
634 *((UINT16
*)((BYTE
*)pMsg
->fields
+ 2)) = htons((UINT16
)iBytes
);
635 iBytes
= (int)compressor
->compress(compBuffer
, iBytes
, (BYTE
*)pMsg
->fields
+ 4, compressor
->compressBufferSize(FILE_BUFFER_SIZE
)) + 4;
639 iBytes
= read(hFile
, pMsg
->fields
, min(FILE_BUFFER_SIZE
, bytesToRead
));
642 bytesToRead
-= iBytes
;
645 // Message should be aligned to 8 bytes boundary
646 dwPadding
= (8 - (((UINT32
)iBytes
+ NXCP_HEADER_SIZE
) % 8)) & 7;
647 pMsg
->size
= htonl((UINT32
)iBytes
+ NXCP_HEADER_SIZE
+ dwPadding
);
648 pMsg
->numFields
= htonl((UINT32
)iBytes
); // numFields contains actual data size for binary message
649 if (bytesToRead
<= 0)
650 pMsg
->flags
|= htons(MF_END_OF_FILE
);
654 pEnMsg
= pCtx
->encryptMessage(pMsg
);
657 SendEx(hSocket
, (char *)pEnMsg
, ntohl(pEnMsg
->size
), 0, mutex
);
663 if (SendEx(hSocket
, (char *)pMsg
, (UINT32
)iBytes
+ NXCP_HEADER_SIZE
+ dwPadding
, 0, mutex
) <= 0)
666 if (progressCallback
!= NULL
)
668 bytesTransferred
+= iBytes
;
669 progressCallback(bytesTransferred
, cbArg
);
672 if (bytesToRead
<= 0)
685 safe_free(compBuffer
);
688 // If file upload failed, send CMD_ABORT_FILE_TRANSFER
694 msg
.code
= htons(CMD_ABORT_FILE_TRANSFER
);
695 msg
.flags
= htons(MF_BINARY
);
697 msg
.size
= htonl(NXCP_HEADER_SIZE
);
700 pEnMsg
= pCtx
->encryptMessage(&msg
);
703 SendEx(hSocket
, (char *)pEnMsg
, ntohl(pEnMsg
->size
), 0, mutex
);
709 SendEx(hSocket
, (char *)&msg
, NXCP_HEADER_SIZE
, 0, mutex
);
717 * Get version of NXCP used by peer
719 BOOL LIBNETXMS_EXPORTABLE
NXCPGetPeerProtocolVersion(SOCKET hSocket
, int *pnVersion
, MUTEX mutex
)
722 NXCPEncryptionContext
*pDummyCtx
= NULL
;
723 NXCP_BUFFER
*pBuffer
;
729 msg
.size
= htonl(NXCP_HEADER_SIZE
);
730 msg
.code
= htons(CMD_GET_NXCP_CAPS
);
731 msg
.flags
= htons(MF_CONTROL
);
732 if (SendEx(hSocket
, &msg
, NXCP_HEADER_SIZE
, 0, mutex
) == NXCP_HEADER_SIZE
)
734 pBuffer
= (NXCP_BUFFER
*)malloc(sizeof(NXCP_BUFFER
));
735 RecvNXCPMessage(0, NULL
, pBuffer
, 0, NULL
, NULL
, 0);
736 nSize
= RecvNXCPMessage(hSocket
, &msg
, pBuffer
, NXCP_HEADER_SIZE
, &pDummyCtx
, NULL
, 30000);
737 if ((nSize
== NXCP_HEADER_SIZE
) &&
738 (ntohs(msg
.code
) == CMD_NXCP_CAPS
) &&
739 (ntohs(msg
.flags
) & MF_CONTROL
))
742 *pnVersion
= ntohl(msg
.numFields
) >> 24;
744 else if ((nSize
== 1) || (nSize
== 3) || (nSize
>= NXCP_HEADER_SIZE
))
746 // We don't receive any answer or receive invalid answer -
747 // assume that peer doesn't understand CMD_GET_NXCP_CAPS message
748 // and set version number to 1