Added aditional debug options to console
[public/netxms.git] / src / server / core / console.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2017 Raden Solutions
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: console.cpp
20 **
21 **/
22
23 #include "nxcore.h"
24
25 /**
26 * Externals
27 */
28 extern Queue g_nodePollerQueue;
29 extern Queue g_dciCacheLoaderQueue;
30 extern Queue g_syslogProcessingQueue;
31 extern Queue g_syslogWriteQueue;
32 extern ThreadPool *g_pollerThreadPool;
33 extern ThreadPool *g_schedulerThreadPool;
34 extern ThreadPool *g_dataCollectorThreadPool;
35
36 void ShowPredictionEngines(CONSOLE_CTX console);
37 void ShowAgentTunnels(CONSOLE_CTX console);
38 UINT32 BindAgentTunnel(UINT32 tunnelId, UINT32 nodeId);
39 UINT32 UnbindAgentTunnel(UINT32 nodeId);
40
41 /**
42 * Format string to show value of global flag
43 */
44 #define SHOW_FLAG_VALUE(x) _T(" %-38s = %d\n"), _T(#x), (g_flags & x) ? 1 : 0
45
46 /**
47 * Compare given string to command template with abbreviation possibility
48 */
49 static bool IsCommand(const TCHAR *cmdTemplate, TCHAR *pszString, int iMinChars)
50 {
51 int i;
52
53 // Convert given string to uppercase
54 _tcsupr(pszString);
55
56 for(i = 0; pszString[i] != 0; i++)
57 if (pszString[i] != cmdTemplate[i])
58 return false;
59 if (i < iMinChars)
60 return false;
61 return true;
62 }
63
64 /**
65 * Dump index callback (by IP address)
66 */
67 static void DumpIndexCallbackByInetAddr(const InetAddress& addr, NetObj *object, void *data)
68 {
69 TCHAR buffer[64];
70 ConsolePrintf((CONSOLE_CTX)data, _T("%-40s %p %s [%d]\n"), addr.toString(buffer), object, object->getName(), (int)object->getId());
71 }
72
73 /**
74 * Dump index (by IP address)
75 */
76 void DumpIndex(CONSOLE_CTX pCtx, InetAddressIndex *index)
77 {
78 index->forEach(DumpIndexCallbackByInetAddr, pCtx);
79 }
80
81 /**
82 * Dump index callback (by ID)
83 */
84 static void DumpIndexCallbackById(NetObj *object, void *data)
85 {
86 ConsolePrintf((CONSOLE_CTX)data, _T("%08X %p %s\n"), object->getId(), object, object->getName());
87 }
88
89 /**
90 * Dump index (by ID)
91 */
92 static void DumpIndex(CONSOLE_CTX pCtx, ObjectIndex *index)
93 {
94 index->forEach(DumpIndexCallbackById, pCtx);
95 }
96
97 /**
98 * Process command entered from command line in standalone mode
99 * Return TRUE if command was _T("down")
100 */
101 int ProcessConsoleCommand(const TCHAR *pszCmdLine, CONSOLE_CTX pCtx)
102 {
103 TCHAR szBuffer[256], *eptr;
104 int nExitCode = CMD_EXIT_CONTINUE;
105
106 // Get command
107 const TCHAR *pArg = ExtractWord(pszCmdLine, szBuffer);
108
109 if (IsCommand(_T("AT"), szBuffer, 2))
110 {
111 pArg = ExtractWord(pArg, szBuffer);
112 if (szBuffer[0] == _T('+'))
113 {
114 int offset = _tcstoul(&szBuffer[1], NULL, 0);
115 AddOneTimeScheduledTask(_T("Execute.Script"), time(NULL) + offset, pArg, 0, 0, SYSTEM_ACCESS_FULL);//TODO: change to correct user
116 }
117 else
118 {
119 AddScheduledTask(_T("Execute.Script"), szBuffer, pArg, 0, 0, SYSTEM_ACCESS_FULL); //TODO: change to correct user
120 }
121 }
122 else if (IsCommand(_T("DEBUG"), szBuffer, 2))
123 {
124 StringList *list = ParseCommandLine(pArg);
125
126 int level;
127 if (list->size() == 1)
128 level = (int)_tcstol(list->get(0), &eptr, 0);
129 else if (list->size() == 2)
130 level = (int)_tcstol(list->get(1), &eptr, 0);
131
132 if ((*eptr == 0) && (level >= -1) && (level <= 9))
133 {
134 if (list->size() == 1)
135 {
136 nxlog_set_debug_level(level);
137 ConsolePrintf(pCtx, (level == 0) ? _T("Debug mode turned off\n") : _T("Debug level set to %d\n"), level);
138 }
139 else if (list->size() == 2)
140 {
141 nxlog_set_debug_level_tag(list->get(0), level);
142 if (level == -1)
143 ConsolePrintf(pCtx, _T("Debug tag <%s> removed\n"), list->get(0));
144 else
145 ConsolePrintf(pCtx, _T("Debug level for tag <%s> set to %d\n"), list->get(0), level);
146 }
147 }
148 else if (IsCommand(_T("OFF"), szBuffer, 2))
149 {
150 nxlog_set_debug_level(0);
151 ConsoleWrite(pCtx, _T("Debug mode turned off\n"));
152 }
153 else
154 {
155 if (szBuffer[0] == 0)
156 ConsoleWrite(pCtx, _T("ERROR: Missing argument\n\n"));
157 else
158 ConsoleWrite(pCtx, _T("ERROR: Invalid debug level\n\n"));
159 }
160 delete(list);
161 }
162 else if (IsCommand(_T("DOWN"), szBuffer, 4))
163 {
164 ConsoleWrite(pCtx, _T("Proceeding with server shutdown...\n"));
165 nExitCode = CMD_EXIT_SHUTDOWN;
166 }
167 else if (IsCommand(_T("DUMP"), szBuffer, 4))
168 {
169 DumpProcess(pCtx);
170 }
171 else if (IsCommand(_T("GET"), szBuffer, 3))
172 {
173 ExtractWord(pArg, szBuffer);
174 if (szBuffer[0] != 0)
175 {
176 TCHAR value[MAX_CONFIG_VALUE];
177 ConfigReadStr(szBuffer, value, MAX_CONFIG_VALUE, _T(""));
178 ConsolePrintf(pCtx, _T("%s = %s\n"), szBuffer, value);
179 }
180 else
181 {
182 ConsoleWrite(pCtx, _T("Variable name missing\n"));
183 }
184 }
185 else if (IsCommand(_T("HKRUN"), szBuffer, 2))
186 {
187 ConsoleWrite(pCtx, _T("Starting housekeeper\n"));
188 RunHouseKeeper();
189 }
190 else if (IsCommand(_T("LDAPSYNC"), szBuffer, 4))
191 {
192 LDAPConnection conn;
193 conn.syncUsers();
194 }
195 else if (IsCommand(_T("LOG"), szBuffer, 3))
196 {
197 while(_istspace(*pArg))
198 pArg++;
199 if (*pArg != 0)
200 DbgPrintf(0, _T("%s"), pArg);
201 }
202 else if (IsCommand(_T("LOGMARK"), szBuffer, 4))
203 {
204 DbgPrintf(0, _T("******* MARK *******"));
205 }
206 else if (IsCommand(_T("RAISE"), szBuffer, 5))
207 {
208 // Get argument
209 ExtractWord(pArg, szBuffer);
210
211 if (IsCommand(_T("ACCESS"), szBuffer, 6))
212 {
213 ConsoleWrite(pCtx, _T("Raising exception...\n"));
214 char *p = NULL;
215 *p = 0;
216 }
217 else if (IsCommand(_T("BREAKPOINT"), szBuffer, 5))
218 {
219 #ifdef _WIN32
220 ConsoleWrite(pCtx, _T("Raising exception...\n"));
221 RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);
222 #else
223 ConsoleWrite(pCtx, _T("ERROR: Not supported on current platform\n"));
224 #endif
225 }
226 else
227 {
228 ConsoleWrite(pCtx, _T("Invalid exception name; possible names are:\nACCESS BREAKPOINT\n"));
229 }
230 }
231 else if (IsCommand(_T("EXIT"), szBuffer, 4))
232 {
233 if ((pCtx->hSocket != -1) || (pCtx->session != NULL))
234 {
235 ConsoleWrite(pCtx, _T("Closing session...\n"));
236 nExitCode = CMD_EXIT_CLOSE_SESSION;
237 }
238 else
239 {
240 ConsoleWrite(pCtx, _T("Cannot exit from local server console\n"));
241 }
242 }
243 else if (IsCommand(_T("KILL"), szBuffer, 4))
244 {
245 ExtractWord(pArg, szBuffer);
246 if (szBuffer[0] != 0)
247 {
248 int id = _tcstol(szBuffer, &eptr, 10);
249 if (*eptr == 0)
250 {
251 if (KillClientSession(id))
252 {
253 ConsoleWrite(pCtx, _T("Session killed\n"));
254 }
255 else
256 {
257 ConsoleWrite(pCtx, _T("Invalid session ID\n"));
258 }
259 }
260 else
261 {
262 ConsoleWrite(pCtx, _T("Invalid session ID\n"));
263 }
264 }
265 else
266 {
267 ConsoleWrite(pCtx, _T("Session ID missing\n"));
268 }
269 }
270 else if (IsCommand(_T("PING"), szBuffer, 4))
271 {
272 ExtractWord(pArg, szBuffer);
273 if (szBuffer[0] != 0)
274 {
275 InetAddress addr = InetAddress::parse(szBuffer);
276 if (addr.isValid())
277 {
278 UINT32 rtt;
279 UINT32 rc = IcmpPing(addr, 1, 2000, &rtt, 128);
280 switch(rc)
281 {
282 case ICMP_SUCCESS:
283 ConsolePrintf(pCtx, _T("Success, RTT = %d ms\n"), (int)rtt);
284 break;
285 case ICMP_UNREACHEABLE:
286 ConsolePrintf(pCtx, _T("Destination unreachable\n"));
287 break;
288 case ICMP_TIMEOUT:
289 ConsolePrintf(pCtx, _T("Request timeout\n"));
290 break;
291 case ICMP_RAW_SOCK_FAILED:
292 ConsolePrintf(pCtx, _T("Cannot create raw socket\n"));
293 break;
294 case ICMP_API_ERROR:
295 ConsolePrintf(pCtx, _T("API error\n"));
296 break;
297 default:
298 ConsolePrintf(pCtx, _T("ERROR %d\n"), (int)rc);
299 break;
300 }
301 }
302 else
303 {
304 ConsoleWrite(pCtx, _T("Invalid IP address\n"));
305 }
306 }
307 else
308 {
309 ConsoleWrite(pCtx, _T("Usage: PING <address>\n"));
310 }
311 }
312 else if (IsCommand(_T("POLL"), szBuffer, 2))
313 {
314 pArg = ExtractWord(pArg, szBuffer);
315 if (szBuffer[0] != 0)
316 {
317 int pollType;
318 if (IsCommand(_T("CONFIGURATION"), szBuffer, 1))
319 {
320 pollType = 1;
321 }
322 else if (IsCommand(_T("INSTANCE"), szBuffer, 1))
323 {
324 pollType = 5;
325 }
326 else if (IsCommand(_T("ROUTING-TABLE"), szBuffer, 1))
327 {
328 pollType = 4;
329 }
330 else if (IsCommand(_T("STATUS"), szBuffer, 1))
331 {
332 pollType = 2;
333 }
334 else if (IsCommand(_T("TOPOLOGY"), szBuffer, 1))
335 {
336 pollType = 3;
337 }
338 else
339 {
340 pollType = 0;
341 }
342
343 if (pollType > 0)
344 {
345 ExtractWord(pArg, szBuffer);
346 UINT32 id = _tcstoul(szBuffer, NULL, 0);
347 if (id != 0)
348 {
349 NetObj *object = FindObjectById(id);
350 if ((object != NULL) && object->isDataCollectionTarget())
351 {
352 switch(pollType)
353 {
354 case 1:
355 static_cast<DataCollectionTarget*>(object)->lockForConfigurationPoll();
356 ThreadPoolExecute(g_pollerThreadPool, static_cast<DataCollectionTarget*>(object),
357 &DataCollectionTarget::configurationPollWorkerEntry,
358 RegisterPoller(POLLER_TYPE_CONFIGURATION, static_cast<DataCollectionTarget*>(object)));
359 break;
360 case 2:
361 static_cast<DataCollectionTarget*>(object)->lockForStatusPoll();
362 ThreadPoolExecute(g_pollerThreadPool, static_cast<DataCollectionTarget*>(object),
363 &DataCollectionTarget::statusPollWorkerEntry,
364 RegisterPoller(POLLER_TYPE_STATUS, static_cast<DataCollectionTarget*>(object)));
365 break;
366 case 3:
367 if (object->getObjectClass() == OBJECT_NODE)
368 {
369 static_cast<Node*>(object)->lockForTopologyPoll();
370 ThreadPoolExecute(g_pollerThreadPool, static_cast<Node*>(object),
371 &Node::topologyPollWorkerEntry,
372 RegisterPoller(POLLER_TYPE_TOPOLOGY, static_cast<Node*>(object)));
373 }
374 else
375 {
376 ConsolePrintf(pCtx, _T("ERROR: this poll type can only be initiated for node objects\n\n"));
377 }
378 break;
379 case 4:
380 if (object->getObjectClass() == OBJECT_NODE)
381 {
382 static_cast<Node*>(object)->lockForRoutePoll();
383 ThreadPoolExecute(g_pollerThreadPool, static_cast<Node*>(object),
384 &Node::routingTablePollWorkerEntry,
385 RegisterPoller(POLLER_TYPE_ROUTING_TABLE, static_cast<Node*>(object)));
386 }
387 else
388 {
389 ConsolePrintf(pCtx, _T("ERROR: this poll type can only be initiated for node objects\n\n"));
390 }
391 break;
392 case 5:
393 static_cast<DataCollectionTarget*>(object)->lockForInstancePoll();
394 ThreadPoolExecute(g_pollerThreadPool, static_cast<DataCollectionTarget*>(object),
395 &DataCollectionTarget::instanceDiscoveryPollWorkerEntry,
396 RegisterPoller(POLLER_TYPE_INSTANCE_DISCOVERY, static_cast<DataCollectionTarget*>(object)));
397 break;
398 }
399 }
400 else
401 {
402 ConsolePrintf(pCtx, _T("ERROR: data collection target with ID %d does not exist\n\n"), id);
403 }
404 }
405 else
406 {
407 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing object ID\n\n"));
408 }
409 }
410 else
411 {
412 ConsoleWrite(pCtx, _T("Usage POLL [CONFIGURATION|STATUS|TOPOLOGY|INSTANCE|ROUTING-TABLE] <object>\n"));
413 }
414 }
415 else
416 {
417 ConsoleWrite(pCtx, _T("Usage POLL [CONFIGURATION|STATUS|TOPOLOGY|INSTANCE|ROUTING-TABLE] <node>\n"));
418 }
419 }
420 else if (IsCommand(_T("SET"), szBuffer, 3))
421 {
422 pArg = ExtractWord(pArg, szBuffer);
423 if (szBuffer[0] != 0)
424 {
425 TCHAR value[256];
426 ExtractWord(pArg, value);
427 if (ConfigWriteStr(szBuffer, value, TRUE, TRUE, TRUE))
428 {
429 ConsolePrintf(pCtx, _T("Configuration variable %s updated\n"), szBuffer);
430 }
431 else
432 {
433 ConsolePrintf(pCtx, _T("ERROR: cannot update configuration variable %s\n"), szBuffer);
434 }
435 }
436 else
437 {
438 ConsolePrintf(pCtx, _T("Variable name missing\n"));
439 }
440 }
441 else if (IsCommand(_T("SHOW"), szBuffer, 2))
442 {
443 // Get argument
444 pArg = ExtractWord(pArg, szBuffer);
445
446 if (IsCommand(_T("COMPONENTS"), szBuffer, 1))
447 {
448 // Get argument
449 ExtractWord(pArg, szBuffer);
450 UINT32 dwNode = _tcstoul(szBuffer, NULL, 0);
451 if (dwNode != 0)
452 {
453 NetObj *pObject = FindObjectById(dwNode);
454 if (pObject != NULL)
455 {
456 if (pObject->getObjectClass() == OBJECT_NODE)
457 {
458 ComponentTree *components = ((Node *)pObject)->getComponents();
459 if (components != NULL)
460 {
461 components->print(pCtx);
462 components->decRefCount();
463 }
464 else
465 {
466 ConsoleWrite(pCtx, _T("ERROR: Node does not have physical component information\n\n"));
467 }
468 }
469 else
470 {
471 ConsoleWrite(pCtx, _T("ERROR: Object is not a node\n\n"));
472 }
473 }
474 else
475 {
476 ConsolePrintf(pCtx, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode);
477 }
478 }
479 else
480 {
481 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing node ID\n\n"));
482 }
483 }
484 else if (IsCommand(_T("DBCP"), szBuffer, 4))
485 {
486 ObjectArray<PoolConnectionInfo> *list = DBConnectionPoolGetConnectionList();
487 for(int i = 0; i < list->size(); i++)
488 {
489 PoolConnectionInfo *c = list->get(i);
490 #if HAVE_LOCALTIME_R
491 struct tm tmbuffer;
492 struct tm *ltm = localtime_r(&c->lastAccessTime, &tmbuffer);
493 #else
494 struct tm *ltm = localtime(&c->lastAccessTime);
495 #endif
496 TCHAR accessTime[64];
497 _tcsftime(accessTime, 64, _T("%d.%b.%Y %H:%M:%S"), ltm);
498 ConsolePrintf(pCtx, _T("%p %s %hs:%d\n"), c->handle, accessTime, c->srcFile, c->srcLine);
499 }
500 ConsolePrintf(pCtx, _T("%d database connections in use\n\n"), list->size());
501 delete list;
502 }
503 else if (IsCommand(_T("DBSTATS"), szBuffer, 3))
504 {
505 LIBNXDB_PERF_COUNTERS counters;
506 DBGetPerfCounters(&counters);
507 ConsolePrintf(pCtx, _T("SQL query counters:\n"));
508 ConsolePrintf(pCtx, _T(" Total .......... ") INT64_FMT _T("\n"), counters.totalQueries);
509 ConsolePrintf(pCtx, _T(" SELECT ......... ") INT64_FMT _T("\n"), counters.selectQueries);
510 ConsolePrintf(pCtx, _T(" Non-SELECT ..... ") INT64_FMT _T("\n"), counters.nonSelectQueries);
511 ConsolePrintf(pCtx, _T(" Long running ... ") INT64_FMT _T("\n"), counters.longRunningQueries);
512 ConsolePrintf(pCtx, _T(" Failed ......... ") INT64_FMT _T("\n"), counters.failedQueries);
513
514 ConsolePrintf(pCtx, _T("Background writer requests:\n"));
515 ConsolePrintf(pCtx, _T(" DCI data ....... ") INT64_FMT _T("\n"), g_idataWriteRequests);
516 ConsolePrintf(pCtx, _T(" DCI raw data ... ") INT64_FMT _T("\n"), g_rawDataWriteRequests);
517 ConsolePrintf(pCtx, _T(" Others ......... ") INT64_FMT _T("\n"), g_otherWriteRequests);
518 }
519 else if (IsCommand(_T("FDB"), szBuffer, 3))
520 {
521 // Get argument
522 ExtractWord(pArg, szBuffer);
523 UINT32 dwNode = _tcstoul(szBuffer, NULL, 0);
524 if (dwNode != 0)
525 {
526 NetObj *pObject = FindObjectById(dwNode);
527 if (pObject != NULL)
528 {
529 if (pObject->getObjectClass() == OBJECT_NODE)
530 {
531 ForwardingDatabase *fdb = ((Node *)pObject)->getSwitchForwardingDatabase();
532 if (fdb != NULL)
533 {
534 fdb->print(pCtx, (Node *)pObject);
535 fdb->decRefCount();
536 }
537 else
538 {
539 ConsoleWrite(pCtx, _T("ERROR: Node does not have forwarding database information\n\n"));
540 }
541 }
542 else
543 {
544 ConsoleWrite(pCtx, _T("ERROR: Object is not a node\n\n"));
545 }
546 }
547 else
548 {
549 ConsolePrintf(pCtx, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode);
550 }
551 }
552 else
553 {
554 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing node ID\n\n"));
555 }
556 }
557 else if (IsCommand(_T("FLAGS"), szBuffer, 1))
558 {
559 ConsolePrintf(pCtx, _T("Flags: 0x") UINT64X_FMT(_T("016")) _T("\n"), g_flags);
560 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_DAEMON));
561 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_USE_SYSLOG));
562 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_ENABLE_NETWORK_DISCOVERY));
563 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_ACTIVE_NETWORK_DISCOVERY));
564 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_LOG_SQL_ERRORS));
565 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_DELETE_EMPTY_SUBNETS));
566 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_ENABLE_SNMP_TRAPD));
567 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_ENABLE_ZONING));
568 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_SYNC_NODE_NAMES_WITH_DNS));
569 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_CHECK_TRUSTED_NODES));
570 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_ENABLE_NXSL_CONTAINER_FUNCS));
571 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_USE_FQDN_FOR_NODE_NAMES));
572 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_APPLY_TO_DISABLED_DCI_FROM_TEMPLATE));
573 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_DEBUG_CONSOLE_DISABLED));
574 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_ENABLE_OBJECT_TRANSACTIONS));
575 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_WRITE_FULL_DUMP));
576 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_RESOLVE_NODE_NAMES));
577 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_CATCH_EXCEPTIONS));
578 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_HELPDESK_LINK_ACTIVE));
579 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_DB_LOCKED));
580 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_DB_CONNECTION_LOST));
581 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_NO_NETWORK_CONNECTIVITY));
582 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_EVENT_STORM_DETECTED));
583 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_SNMP_TRAP_DISCOVERY));
584 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_TRAPS_FROM_UNMANAGED_NODES));
585 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_RESOLVE_IP_FOR_EACH_STATUS_POLL));
586 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_PERFDATA_STORAGE_DRIVER_LOADED));
587 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_BACKGROUND_LOG_WRITER));
588 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_CASE_INSENSITIVE_LOGINS));
589 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_TRAP_SOURCES_IN_ALL_ZONES));
590 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_SYSLOG_DISCOVERY));
591 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_ENABLE_LOCAL_CONSOLE));
592 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_SERVER_INITIALIZED));
593 ConsolePrintf(pCtx, SHOW_FLAG_VALUE(AF_SHUTDOWN));
594 ConsolePrintf(pCtx, _T("\n"));
595 }
596 else if (IsCommand(_T("HEAP"), szBuffer, 1))
597 {
598 TCHAR *text = GetHeapInfo();
599 if (text != NULL)
600 {
601 ConsoleWrite(pCtx, text);
602 ConsoleWrite(pCtx, _T("\n"));
603 free(text);
604 }
605 else
606 {
607 ConsoleWrite(pCtx, _T("Error reading heap information\n"));
608 }
609 }
610 else if (IsCommand(_T("INDEX"), szBuffer, 1))
611 {
612 // Get argument
613 pArg = ExtractWord(pArg, szBuffer);
614
615 if (IsCommand(_T("CONDITION"), szBuffer, 1))
616 {
617 DumpIndex(pCtx, &g_idxConditionById);
618 }
619 else if (IsCommand(_T("ID"), szBuffer, 2))
620 {
621 DumpIndex(pCtx, &g_idxObjectById);
622 }
623 else if (IsCommand(_T("INTERFACE"), szBuffer, 2))
624 {
625 pArg = ExtractWord(pArg, szBuffer);
626 if (IsCommand(_T("ZONE"), szBuffer, 1))
627 {
628 ExtractWord(pArg, szBuffer);
629 Zone *zone = FindZoneByUIN(_tcstoul(szBuffer, NULL, 0));
630 if (zone != NULL)
631 {
632 zone->dumpInterfaceIndex(pCtx);
633 }
634 else
635 {
636 ConsoleWrite(pCtx, _T("ERROR: Invalid zone UIN\n\n"));
637 }
638 }
639 else if (szBuffer[0] == 0)
640 {
641 DumpIndex(pCtx, &g_idxInterfaceByAddr);
642 }
643 else
644 {
645 ConsoleWrite(pCtx, _T("ERROR: Invalid index modifier\n\n"));
646 }
647 }
648 else if (IsCommand(_T("NETMAP"), szBuffer, 4))
649 {
650 DumpIndex(pCtx, &g_idxNetMapById);
651 }
652 else if (IsCommand(_T("NODEADDR"), szBuffer, 5))
653 {
654 pArg = ExtractWord(pArg, szBuffer);
655 if (IsCommand(_T("ZONE"), szBuffer, 1))
656 {
657 ExtractWord(pArg, szBuffer);
658 Zone *zone = FindZoneByUIN(_tcstoul(szBuffer, NULL, 0));
659 if (zone != NULL)
660 {
661 zone->dumpNodeIndex(pCtx);
662 }
663 else
664 {
665 ConsoleWrite(pCtx, _T("ERROR: Invalid zone UIN\n\n"));
666 }
667 }
668 else if (szBuffer[0] == 0)
669 {
670 DumpIndex(pCtx, &g_idxNodeByAddr);
671 }
672 else
673 {
674 ConsoleWrite(pCtx, _T("ERROR: Invalid index modifier\n\n"));
675 }
676 }
677 else if (IsCommand(_T("NODEID"), szBuffer, 5))
678 {
679 DumpIndex(pCtx, &g_idxNodeById);
680 }
681 else if (IsCommand(_T("SENSOR"), szBuffer, 2))
682 {
683 DumpIndex(pCtx, &g_idxSensorById);
684 }
685 else if (IsCommand(_T("SUBNET"), szBuffer, 2))
686 {
687 pArg = ExtractWord(pArg, szBuffer);
688 if (IsCommand(_T("ZONE"), szBuffer, 1))
689 {
690 ExtractWord(pArg, szBuffer);
691 Zone *zone = FindZoneByUIN(_tcstoul(szBuffer, NULL, 0));
692 if (zone != NULL)
693 {
694 zone->dumpSubnetIndex(pCtx);
695 }
696 else
697 {
698 ConsoleWrite(pCtx, _T("ERROR: Invalid zone UIN\n\n"));
699 }
700 }
701 else if (szBuffer[0] == 0)
702 {
703 DumpIndex(pCtx, &g_idxSubnetByAddr);
704 }
705 else
706 {
707 ConsoleWrite(pCtx, _T("ERROR: Invalid index modifier\n\n"));
708 }
709 }
710 else if (IsCommand(_T("ZONE"), szBuffer, 1))
711 {
712 DumpIndex(pCtx, &g_idxZoneByUIN);
713 }
714 else
715 {
716 if (szBuffer[0] == 0)
717 ConsoleWrite(pCtx, _T("ERROR: Missing parameters\n")
718 _T("Syntax:\n SHOW INDEX name [ZONE uin]\n")
719 _T("Valid names are: CONDITION, ID, INTERFACE, NODEADDR, NODEID, SUBNET, ZONE\n\n"));
720 else
721 ConsoleWrite(pCtx, _T("ERROR: Invalid index name\n\n"));
722 }
723 }
724 else if (IsCommand(_T("LLDP"), szBuffer, 4))
725 {
726 // Get argument
727 ExtractWord(pArg, szBuffer);
728 UINT32 dwNode = _tcstoul(szBuffer, NULL, 0);
729 if (dwNode != 0)
730 {
731 NetObj *pObject = FindObjectById(dwNode);
732 if (pObject != NULL)
733 {
734 if (pObject->getObjectClass() == OBJECT_NODE)
735 {
736 ((Node *)pObject)->showLLDPInfo(pCtx);
737 }
738 else
739 {
740 ConsoleWrite(pCtx, _T("ERROR: Object is not a node\n\n"));
741 }
742 }
743 else
744 {
745 ConsolePrintf(pCtx, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode);
746 }
747 }
748 else
749 {
750 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing node ID\n\n"));
751 }
752 }
753 else if (IsCommand(_T("MODULES"), szBuffer, 3))
754 {
755 ConsoleWrite(pCtx, _T("Loaded server modules:\n"));
756 for(UINT32 i = 0; i < g_dwNumModules; i++)
757 {
758 ConsolePrintf(pCtx, _T(" %s\n"), g_pModuleList[i].szName);
759 }
760 ConsolePrintf(pCtx, _T("%d modules loaded\n"), g_dwNumModules);
761 }
762 else if (IsCommand(_T("MSGWQ"), szBuffer, 2))
763 {
764 String text = MsgWaitQueue::getDiagInfo();
765 ConsoleWrite(pCtx, text);
766 ConsoleWrite(pCtx, _T("\n"));
767 }
768 else if (IsCommand(_T("OBJECTS"), szBuffer, 1))
769 {
770 // Get filter
771 ExtractWord(pArg, szBuffer);
772 StrStrip(szBuffer);
773 DumpObjects(pCtx, (szBuffer[0] != 0) ? szBuffer : NULL);
774 }
775 else if (IsCommand(_T("PE"), szBuffer, 2))
776 {
777 ShowPredictionEngines(pCtx);
778 }
779 else if (IsCommand(_T("POLLERS"), szBuffer, 2))
780 {
781 ShowPollers(pCtx);
782 }
783 else if (IsCommand(_T("QUEUES"), szBuffer, 1))
784 {
785 ShowThreadPoolPendingQueue(pCtx, g_dataCollectorThreadPool, _T("Data collector"));
786 ShowQueueStats(pCtx, &g_dciCacheLoaderQueue, _T("DCI cache loader"));
787 ShowQueueStats(pCtx, &g_templateUpdateQueue, _T("Template updates"));
788 ShowQueueStats(pCtx, g_dbWriterQueue, _T("Database writer"));
789 ShowQueueStats(pCtx, g_dciDataWriterQueue, _T("Database writer (IData)"));
790 ShowQueueStats(pCtx, g_dciRawDataWriterQueue, _T("Database writer (raw DCI values)"));
791 ShowQueueStats(pCtx, g_pEventQueue, _T("Event processor"));
792 ShowThreadPoolPendingQueue(pCtx, g_pollerThreadPool, _T("Poller"));
793 ShowQueueStats(pCtx, &g_nodePollerQueue, _T("Node discovery poller"));
794 ShowQueueStats(pCtx, &g_syslogProcessingQueue, _T("Syslog processing"));
795 ShowQueueStats(pCtx, &g_syslogWriteQueue, _T("Syslog writer"));
796 ShowThreadPoolPendingQueue(pCtx, g_schedulerThreadPool, _T("Scheduler"));
797 ConsolePrintf(pCtx, _T("\n"));
798 }
799 else if (IsCommand(_T("ROUTING-TABLE"), szBuffer, 1))
800 {
801 UINT32 dwNode;
802 NetObj *pObject;
803
804 ExtractWord(pArg, szBuffer);
805 dwNode = _tcstoul(szBuffer, NULL, 0);
806 if (dwNode != 0)
807 {
808 pObject = FindObjectById(dwNode);
809 if (pObject != NULL)
810 {
811 if (pObject->getObjectClass() == OBJECT_NODE)
812 {
813 ROUTING_TABLE *pRT;
814 TCHAR szIpAddr[16];
815 int i;
816
817 ConsolePrintf(pCtx, _T("Routing table for node %s:\n\n"), pObject->getName());
818 pRT = ((Node *)pObject)->getCachedRoutingTable();
819 if (pRT != NULL)
820 {
821 for(i = 0; i < pRT->iNumEntries; i++)
822 {
823 _sntprintf(szBuffer, 256, _T("%s/%d"), IpToStr(pRT->pRoutes[i].dwDestAddr, szIpAddr),
824 BitsInMask(pRT->pRoutes[i].dwDestMask));
825 ConsolePrintf(pCtx, _T("%-18s %-15s %-6d %d\n"), szBuffer,
826 IpToStr(pRT->pRoutes[i].dwNextHop, szIpAddr),
827 pRT->pRoutes[i].dwIfIndex, pRT->pRoutes[i].dwRouteType);
828 }
829 ConsoleWrite(pCtx, _T("\n"));
830 }
831 else
832 {
833 ConsoleWrite(pCtx, _T("Node doesn't have cached routing table\n\n"));
834 }
835 }
836 else
837 {
838 ConsoleWrite(pCtx, _T("ERROR: Object is not a node\n\n"));
839 }
840 }
841 else
842 {
843 ConsolePrintf(pCtx, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode);
844 }
845 }
846 else
847 {
848 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing node ID\n\n"));
849 }
850 }
851 else if (IsCommand(_T("SESSIONS"), szBuffer, 2))
852 {
853 ConsoleWrite(pCtx, _T("\x1b[1mCLIENT SESSIONS\x1b[0m\n============================================================\n"));
854 DumpClientSessions(pCtx);
855 ConsoleWrite(pCtx, _T("\n\x1b[1mMOBILE DEVICE SESSIONS\x1b[0m\n============================================================\n"));
856 DumpMobileDeviceSessions(pCtx);
857 }
858 else if (IsCommand(_T("STATS"), szBuffer, 2))
859 {
860 ShowServerStats(pCtx);
861 }
862 else if (IsCommand(_T("THREADS"), szBuffer, 2))
863 {
864 ShowThreadPool(pCtx, g_mainThreadPool);
865 ShowThreadPool(pCtx, g_pollerThreadPool);
866 ShowThreadPool(pCtx, g_dataCollectorThreadPool);
867 ShowThreadPool(pCtx, g_schedulerThreadPool);
868 ShowThreadPool(pCtx, g_agentConnectionThreadPool);
869 }
870 else if (IsCommand(_T("TOPOLOGY"), szBuffer, 1))
871 {
872 ExtractWord(pArg, szBuffer);
873 UINT32 nodeId = _tcstoul(szBuffer, NULL, 0);
874 if (nodeId != 0)
875 {
876 Node *node = (Node *)FindObjectById(nodeId, OBJECT_NODE);
877 if (node != NULL)
878 {
879 LinkLayerNeighbors *nbs = BuildLinkLayerNeighborList(node);
880 if (nbs != NULL)
881 {
882 ConsolePrintf(pCtx, _T("Proto | PtP | ifLocal | ifRemote | Peer\n")
883 _T("--------+-----+---------+----------+------------------------------------\n"));
884 for(int i = 0; i < nbs->size(); i++)
885 {
886 LL_NEIGHBOR_INFO *ni = nbs->getConnection(i);
887 TCHAR peer[256];
888 if (ni->objectId != 0)
889 {
890 NetObj *object = FindObjectById(ni->objectId);
891 if (object != NULL)
892 _sntprintf(peer, 256, _T("%s [%d]"), object->getName(), ni->objectId);
893 else
894 _sntprintf(peer, 256, _T("[%d]"), ni->objectId);
895 }
896 else
897 {
898 peer[0] = 0;
899 }
900 ConsolePrintf(pCtx, _T("%-7s | %c | %7d | %7d | %s\n"),
901 GetLinkLayerProtocolName(ni->protocol), ni->isPtToPt ? _T('Y') : _T('N'), ni->ifLocal, ni->ifRemote, peer);
902 }
903 nbs->decRefCount();
904 }
905 else
906 {
907 ConsoleWrite(pCtx, _T("ERROR: call to BuildLinkLayerNeighborList failed\n\n"));
908 }
909 }
910 else
911 {
912 ConsolePrintf(pCtx, _T("ERROR: Node with ID %d does not exist\n\n"), nodeId);
913 }
914 }
915 else
916 {
917 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing node ID\n\n"));
918 }
919 }
920 else if (IsCommand(_T("TUNNELS"), szBuffer, 2))
921 {
922 ShowAgentTunnels(pCtx);
923 }
924 else if (IsCommand(_T("USERS"), szBuffer, 1))
925 {
926 DumpUsers(pCtx);
927 }
928 else if (IsCommand(_T("VLANS"), szBuffer, 1))
929 {
930 UINT32 dwNode;
931 NetObj *pObject;
932
933 ExtractWord(pArg, szBuffer);
934 dwNode = _tcstoul(szBuffer, NULL, 0);
935 if (dwNode != 0)
936 {
937 pObject = FindObjectById(dwNode);
938 if (pObject != NULL)
939 {
940 if (pObject->getObjectClass() == OBJECT_NODE)
941 {
942 VlanList *vlans = ((Node *)pObject)->getVlans();
943 if (vlans != NULL)
944 {
945 ConsoleWrite(pCtx, _T("\x1b[1mVLAN\x1b[0m | \x1b[1mName\x1b[0m | \x1b[1mPorts\x1b[0m\n")
946 _T("-----+------------------+-----------------------------------------------------------------\n"));
947 for(int i = 0; i < vlans->size(); i++)
948 {
949 VlanInfo *vlan = vlans->get(i);
950 ConsolePrintf(pCtx, _T("%4d | %-16s |"), vlan->getVlanId(), vlan->getName());
951 for(int j = 0; j < vlan->getNumPorts(); j++)
952 ConsolePrintf(pCtx, _T(" %d.%d"), (int)(vlan->getPorts()[j] >> 16), (int)(vlan->getPorts()[j] & 0xFFFF));
953 ConsolePrintf(pCtx, _T("\n"));
954 }
955 ConsolePrintf(pCtx, _T("\n"));
956 vlans->decRefCount();
957 }
958 else
959 {
960 ConsoleWrite(pCtx, _T("\x1b[31mNode doesn't have VLAN information\x1b[0m\n\n"));
961 }
962 }
963 else
964 {
965 ConsoleWrite(pCtx, _T("\x1b[31mERROR: Object is not a node\x1b[0m\n\n"));
966 }
967 }
968 else
969 {
970 ConsolePrintf(pCtx, _T("\x1b[31mERROR: Object with ID %d does not exist\x1b[0m\n\n"), dwNode);
971 }
972 }
973 else
974 {
975 ConsoleWrite(pCtx, _T("\x1b[31mERROR: Invalid or missing node ID\x1b[0m\n\n"));
976 }
977 }
978 else if (IsCommand(_T("WATCHDOG"), szBuffer, 1))
979 {
980 WatchdogPrintStatus(pCtx);
981 ConsoleWrite(pCtx, _T("\n"));
982 }
983 else
984 {
985 if (szBuffer[0] == 0)
986 ConsoleWrite(pCtx, _T("ERROR: Missing subcommand\n\n"));
987 else
988 ConsoleWrite(pCtx, _T("ERROR: Invalid SHOW subcommand\n\n"));
989 }
990 }
991 else if (IsCommand(_T("SNAPSHOT"), szBuffer, 4))
992 {
993 // create access snapshot
994 ExtractWord(pArg, szBuffer);
995 UINT32 userId = _tcstoul(szBuffer, NULL, 0);
996 bool success = CreateObjectAccessSnapshot(userId, OBJECT_NODE);
997 ConsolePrintf(pCtx, _T("Object access snapshot creation for user %d %s\n\n"), userId, success ? _T("successful") : _T("failed"));
998 }
999 else if (IsCommand(_T("EXEC"), szBuffer, 3))
1000 {
1001 pArg = ExtractWord(pArg, szBuffer);
1002
1003 bool libraryLocked = true;
1004 bool destroyCompiledScript = false;
1005 NXSL_Library *scriptLibrary = GetServerScriptLibrary();
1006 scriptLibrary->lock();
1007
1008 NXSL_Program *compiledScript = scriptLibrary->findNxslProgram(szBuffer);
1009 if (compiledScript == NULL)
1010 {
1011 scriptLibrary->unlock();
1012 libraryLocked = false;
1013 destroyCompiledScript = true;
1014 char *script;
1015 UINT32 fileSize;
1016 if ((script = (char *)LoadFile(szBuffer, &fileSize)) != NULL)
1017 {
1018 const int errorMsgLen = 512;
1019 TCHAR errorMsg[errorMsgLen];
1020 #ifdef UNICODE
1021 WCHAR *wscript = WideStringFromMBString(script);
1022 compiledScript = NXSLCompile(wscript, errorMsg, errorMsgLen, NULL);
1023 free(wscript);
1024 #else
1025 compiledScript = NXSLCompile(script, errorMsg, errorMsgLen, NULL);
1026 #endif
1027 free(script);
1028 if (compiledScript == NULL)
1029 {
1030 ConsolePrintf(pCtx, _T("ERROR: Script compilation error: %s\n\n"), errorMsg);
1031 }
1032 }
1033 else
1034 {
1035 ConsolePrintf(pCtx, _T("ERROR: Script \"%s\" not found\n\n"), szBuffer);
1036 }
1037 }
1038
1039 if (compiledScript != NULL)
1040 {
1041 NXSL_ServerEnv *pEnv = new NXSL_ServerEnv;
1042 pEnv->setConsole(pCtx);
1043
1044 NXSL_VM *vm = new NXSL_VM(pEnv);
1045 if (vm->load(compiledScript))
1046 {
1047 if (libraryLocked)
1048 {
1049 scriptLibrary->unlock();
1050 libraryLocked = false;
1051 }
1052
1053 NXSL_Value *argv[32];
1054 int argc = 0;
1055 while(argc < 32)
1056 {
1057 pArg = ExtractWord(pArg, szBuffer);
1058 if (szBuffer[0] == 0)
1059 break;
1060 argv[argc++] = new NXSL_Value(szBuffer);
1061 }
1062
1063 if (vm->run(argc, argv))
1064 {
1065 NXSL_Value *pValue = vm->getResult();
1066 int retCode = pValue->getValueAsInt32();
1067 ConsolePrintf(pCtx, _T("INFO: Script finished with rc=%d\n\n"), retCode);
1068 }
1069 else
1070 {
1071 ConsolePrintf(pCtx, _T("ERROR: Script finished with error: %s\n\n"), vm->getErrorText());
1072 }
1073 }
1074 else
1075 {
1076 ConsolePrintf(pCtx, _T("ERROR: VM creation failed: %s\n\n"), vm->getErrorText());
1077 }
1078 delete vm;
1079 if (destroyCompiledScript)
1080 delete compiledScript;
1081 }
1082 if (libraryLocked)
1083 scriptLibrary->unlock();
1084 }
1085 else if (IsCommand(_T("TRACE"), szBuffer, 1))
1086 {
1087 UINT32 dwNode1, dwNode2;
1088 NetObj *pObject1, *pObject2;
1089 NetworkPath *pTrace;
1090 TCHAR szNextHop[16];
1091 int i;
1092
1093 // Get arguments
1094 pArg = ExtractWord(pArg, szBuffer);
1095 dwNode1 = _tcstoul(szBuffer, NULL, 0);
1096
1097 ExtractWord(pArg, szBuffer);
1098 dwNode2 = _tcstoul(szBuffer, NULL, 0);
1099
1100 if ((dwNode1 != 0) && (dwNode2 != 0))
1101 {
1102 pObject1 = FindObjectById(dwNode1);
1103 if (pObject1 == NULL)
1104 {
1105 ConsolePrintf(pCtx, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode1);
1106 }
1107 else
1108 {
1109 pObject2 = FindObjectById(dwNode2);
1110 if (pObject2 == NULL)
1111 {
1112 ConsolePrintf(pCtx, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode2);
1113 }
1114 else
1115 {
1116 if ((pObject1->getObjectClass() == OBJECT_NODE) && (pObject2->getObjectClass() == OBJECT_NODE))
1117 {
1118 pTrace = TraceRoute((Node *)pObject1, (Node *)pObject2);
1119 if (pTrace != NULL)
1120 {
1121 TCHAR sourceIp[32];
1122 ConsolePrintf(pCtx, _T("Trace from %s to %s (%d hops, %s, source IP %s):\n"),
1123 pObject1->getName(), pObject2->getName(), pTrace->getHopCount(),
1124 pTrace->isComplete() ? _T("complete") : _T("incomplete"),
1125 pTrace->getSourceAddress().toString(sourceIp));
1126 for(i = 0; i < pTrace->getHopCount(); i++)
1127 {
1128 HOP_INFO *hop = pTrace->getHopInfo(i);
1129 ConsolePrintf(pCtx, _T("[%d] %s %s %s %d\n"),
1130 hop->object->getId(),
1131 hop->object->getName(),
1132 hop->nextHop.toString(szNextHop),
1133 hop->isVpn ? _T("VPN Connector ID:") : _T("Interface Index: "),
1134 hop->ifIndex);
1135 }
1136 delete pTrace;
1137 ConsolePrintf(pCtx, _T("\n"));
1138 }
1139 else
1140 {
1141 ConsoleWrite(pCtx, _T("ERROR: Call to TraceRoute() failed\n\n"));
1142 }
1143 }
1144 else
1145 {
1146 ConsoleWrite(pCtx, _T("ERROR: Object is not a node\n\n"));
1147 }
1148 }
1149 }
1150 }
1151 else
1152 {
1153 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing node id(s)\n\n"));
1154 }
1155 }
1156 else if (IsCommand(_T("TUNNEL"), szBuffer, 2))
1157 {
1158 pArg = ExtractWord(pArg, szBuffer);
1159 if (IsCommand(_T("BIND"), szBuffer, 1))
1160 {
1161 pArg = ExtractWord(pArg, szBuffer);
1162 UINT32 tunnelId = _tcstoul(szBuffer, NULL, 0);
1163
1164 ExtractWord(pArg, szBuffer);
1165 UINT32 nodeId = _tcstoul(szBuffer, NULL, 0);
1166
1167 if ((tunnelId != 0) && (nodeId != 0))
1168 {
1169 UINT32 rcc = BindAgentTunnel(tunnelId, nodeId);
1170 ConsolePrintf(pCtx, _T("Bind tunnel %d to node %d: RCC = %d\n\n"), tunnelId, nodeId, rcc);
1171 }
1172 else
1173 {
1174 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing argument(s)\n\n"));
1175 }
1176 }
1177 else if (IsCommand(_T("UNBIND"), szBuffer, 1))
1178 {
1179 ExtractWord(pArg, szBuffer);
1180 UINT32 nodeId = _tcstoul(szBuffer, NULL, 0);
1181
1182 if (nodeId != 0)
1183 {
1184 UINT32 rcc = UnbindAgentTunnel(nodeId);
1185 ConsolePrintf(pCtx, _T("Unbind tunnel from node %d: RCC = %d\n\n"), nodeId, rcc);
1186 }
1187 else
1188 {
1189 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing argument(s)\n\n"));
1190 }
1191 }
1192 else
1193 {
1194 ConsoleWrite(pCtx, _T("ERROR: Invalid TUNNEL subcommand\n\n"));
1195 }
1196 }
1197 else if (IsCommand(_T("HELP"), szBuffer, 2) || IsCommand(_T("?"), szBuffer, 1))
1198 {
1199 ConsoleWrite(pCtx,
1200 _T("Valid commands are:\n")
1201 _T(" at +<sec> <script> [<params>] - Schedule one time script execution task\n")
1202 _T(" at <schedule> <script> [<params>] - Schedule repeated script execution task\n")
1203 _T(" debug [<level>|off] - Set debug level (valid range is 0..9)\n")
1204 _T(" down - Shutdown NetXMS server\n")
1205 _T(" exec <script> [<params>] - Executes NXSL script from script library\n")
1206 _T(" exit - Exit from remote session\n")
1207 _T(" kill <session> - Kill client session\n")
1208 _T(" get <variable> - Get value of server configuration variable\n")
1209 _T(" help - Display this help\n")
1210 _T(" hkrun - Run housekeeper immediately\n")
1211 _T(" ldapsync - Synchronize ldap users with local user database\n")
1212 _T(" log <text> - Write given text to server log file\n")
1213 _T(" logmark - Write marker ******* MARK ******* to server log file\n")
1214 _T(" ping <address> - Send ICMP echo request to given IP address\n")
1215 _T(" poll <type> <node> - Initiate node poll\n")
1216 _T(" raise <exception> - Raise exception\n")
1217 _T(" set <variable> <value> - Set value of server configuration variable\n")
1218 _T(" show components <node> - Show physical components of given node\n")
1219 _T(" show dbcp - Show active sessions in database connection pool\n")
1220 _T(" show dbstats - Show DB library statistics\n")
1221 _T(" show fdb <node> - Show forwarding database for node\n")
1222 _T(" show flags - Show internal server flags\n")
1223 _T(" show heap - Show heap information\n")
1224 _T(" show index <index> - Show internal index\n")
1225 _T(" show modules - Show loaded server modules\n")
1226 _T(" show msgwq - Show message wait queues information\n")
1227 _T(" show objects [<filter>] - Dump network objects to screen\n")
1228 _T(" show pe - Show registered prediction engines\n")
1229 _T(" show pollers - Show poller threads state information\n")
1230 _T(" show queues - Show internal queues statistics\n")
1231 _T(" show routing-table <node> - Show cached routing table for node\n")
1232 _T(" show sessions - Show active client sessions\n")
1233 _T(" show stats - Show server statistics\n")
1234 _T(" show topology <node> - Collect and show link layer topology for node\n")
1235 _T(" show tunnels - Show active agent tunnels\n")
1236 _T(" show users - Show users\n")
1237 _T(" show vlans <node> - Show cached VLAN information for node\n")
1238 _T(" show watchdog - Display watchdog information\n")
1239 _T(" trace <node1> <node2> - Show network path trace between two nodes\n")
1240 _T(" tunnel bind <tunnel> <node> - Bind agent tunnel to node\n")
1241 _T(" tunnel unbind <node> - Unbind agent tunnel from node\n")
1242 _T("\nAlmost all commands can be abbreviated to 2 or 3 characters\n")
1243 _T("\n"));
1244 }
1245 else
1246 {
1247 ConsoleWrite(pCtx, _T("UNKNOWN COMMAND\n\n"));
1248 }
1249
1250 return nExitCode;
1251 }