492effe92642b71c2aedacdc0215ad48ef6c3a27
[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("NODEADDR"), szBuffer, 5))
649 {
650 pArg = ExtractWord(pArg, szBuffer);
651 if (IsCommand(_T("ZONE"), szBuffer, 1))
652 {
653 ExtractWord(pArg, szBuffer);
654 Zone *zone = FindZoneByUIN(_tcstoul(szBuffer, NULL, 0));
655 if (zone != NULL)
656 {
657 zone->dumpNodeIndex(pCtx);
658 }
659 else
660 {
661 ConsoleWrite(pCtx, _T("ERROR: Invalid zone UIN\n\n"));
662 }
663 }
664 else if (szBuffer[0] == 0)
665 {
666 DumpIndex(pCtx, &g_idxNodeByAddr);
667 }
668 else
669 {
670 ConsoleWrite(pCtx, _T("ERROR: Invalid index modifier\n\n"));
671 }
672 }
673 else if (IsCommand(_T("NODEID"), szBuffer, 5))
674 {
675 DumpIndex(pCtx, &g_idxNodeById);
676 }
677 else if (IsCommand(_T("SUBNET"), szBuffer, 1))
678 {
679 pArg = ExtractWord(pArg, szBuffer);
680 if (IsCommand(_T("ZONE"), szBuffer, 1))
681 {
682 ExtractWord(pArg, szBuffer);
683 Zone *zone = FindZoneByUIN(_tcstoul(szBuffer, NULL, 0));
684 if (zone != NULL)
685 {
686 zone->dumpSubnetIndex(pCtx);
687 }
688 else
689 {
690 ConsoleWrite(pCtx, _T("ERROR: Invalid zone UIN\n\n"));
691 }
692 }
693 else if (szBuffer[0] == 0)
694 {
695 DumpIndex(pCtx, &g_idxSubnetByAddr);
696 }
697 else
698 {
699 ConsoleWrite(pCtx, _T("ERROR: Invalid index modifier\n\n"));
700 }
701 }
702 else if (IsCommand(_T("ZONE"), szBuffer, 1))
703 {
704 DumpIndex(pCtx, &g_idxZoneByUIN);
705 }
706 else
707 {
708 if (szBuffer[0] == 0)
709 ConsoleWrite(pCtx, _T("ERROR: Missing parameters\n")
710 _T("Syntax:\n SHOW INDEX name [ZONE uin]\n")
711 _T("Valid names are: CONDITION, ID, INTERFACE, NODEADDR, NODEID, SUBNET, ZONE\n\n"));
712 else
713 ConsoleWrite(pCtx, _T("ERROR: Invalid index name\n\n"));
714 }
715 }
716 else if (IsCommand(_T("LLDP"), szBuffer, 4))
717 {
718 // Get argument
719 ExtractWord(pArg, szBuffer);
720 UINT32 dwNode = _tcstoul(szBuffer, NULL, 0);
721 if (dwNode != 0)
722 {
723 NetObj *pObject = FindObjectById(dwNode);
724 if (pObject != NULL)
725 {
726 if (pObject->getObjectClass() == OBJECT_NODE)
727 {
728 ((Node *)pObject)->showLLDPInfo(pCtx);
729 }
730 else
731 {
732 ConsoleWrite(pCtx, _T("ERROR: Object is not a node\n\n"));
733 }
734 }
735 else
736 {
737 ConsolePrintf(pCtx, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode);
738 }
739 }
740 else
741 {
742 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing node ID\n\n"));
743 }
744 }
745 else if (IsCommand(_T("MODULES"), szBuffer, 3))
746 {
747 ConsoleWrite(pCtx, _T("Loaded server modules:\n"));
748 for(UINT32 i = 0; i < g_dwNumModules; i++)
749 {
750 ConsolePrintf(pCtx, _T(" %s\n"), g_pModuleList[i].szName);
751 }
752 ConsolePrintf(pCtx, _T("%d modules loaded\n"), g_dwNumModules);
753 }
754 else if (IsCommand(_T("MSGWQ"), szBuffer, 2))
755 {
756 String text = MsgWaitQueue::getDiagInfo();
757 ConsoleWrite(pCtx, text);
758 ConsoleWrite(pCtx, _T("\n"));
759 }
760 else if (IsCommand(_T("OBJECTS"), szBuffer, 1))
761 {
762 // Get filter
763 ExtractWord(pArg, szBuffer);
764 StrStrip(szBuffer);
765 DumpObjects(pCtx, (szBuffer[0] != 0) ? szBuffer : NULL);
766 }
767 else if (IsCommand(_T("PE"), szBuffer, 2))
768 {
769 ShowPredictionEngines(pCtx);
770 }
771 else if (IsCommand(_T("POLLERS"), szBuffer, 2))
772 {
773 ShowPollers(pCtx);
774 }
775 else if (IsCommand(_T("QUEUES"), szBuffer, 1))
776 {
777 ShowThreadPoolPendingQueue(pCtx, g_dataCollectorThreadPool, _T("Data collector"));
778 ShowQueueStats(pCtx, &g_dciCacheLoaderQueue, _T("DCI cache loader"));
779 ShowQueueStats(pCtx, &g_templateUpdateQueue, _T("Template updates"));
780 ShowQueueStats(pCtx, g_dbWriterQueue, _T("Database writer"));
781 ShowQueueStats(pCtx, g_dciDataWriterQueue, _T("Database writer (IData)"));
782 ShowQueueStats(pCtx, g_dciRawDataWriterQueue, _T("Database writer (raw DCI values)"));
783 ShowQueueStats(pCtx, g_pEventQueue, _T("Event processor"));
784 ShowThreadPoolPendingQueue(pCtx, g_pollerThreadPool, _T("Poller"));
785 ShowQueueStats(pCtx, &g_nodePollerQueue, _T("Node discovery poller"));
786 ShowQueueStats(pCtx, &g_syslogProcessingQueue, _T("Syslog processing"));
787 ShowQueueStats(pCtx, &g_syslogWriteQueue, _T("Syslog writer"));
788 ShowThreadPoolPendingQueue(pCtx, g_schedulerThreadPool, _T("Scheduler"));
789 ConsolePrintf(pCtx, _T("\n"));
790 }
791 else if (IsCommand(_T("ROUTING-TABLE"), szBuffer, 1))
792 {
793 UINT32 dwNode;
794 NetObj *pObject;
795
796 ExtractWord(pArg, szBuffer);
797 dwNode = _tcstoul(szBuffer, NULL, 0);
798 if (dwNode != 0)
799 {
800 pObject = FindObjectById(dwNode);
801 if (pObject != NULL)
802 {
803 if (pObject->getObjectClass() == OBJECT_NODE)
804 {
805 ROUTING_TABLE *pRT;
806 TCHAR szIpAddr[16];
807 int i;
808
809 ConsolePrintf(pCtx, _T("Routing table for node %s:\n\n"), pObject->getName());
810 pRT = ((Node *)pObject)->getCachedRoutingTable();
811 if (pRT != NULL)
812 {
813 for(i = 0; i < pRT->iNumEntries; i++)
814 {
815 _sntprintf(szBuffer, 256, _T("%s/%d"), IpToStr(pRT->pRoutes[i].dwDestAddr, szIpAddr),
816 BitsInMask(pRT->pRoutes[i].dwDestMask));
817 ConsolePrintf(pCtx, _T("%-18s %-15s %-6d %d\n"), szBuffer,
818 IpToStr(pRT->pRoutes[i].dwNextHop, szIpAddr),
819 pRT->pRoutes[i].dwIfIndex, pRT->pRoutes[i].dwRouteType);
820 }
821 ConsoleWrite(pCtx, _T("\n"));
822 }
823 else
824 {
825 ConsoleWrite(pCtx, _T("Node doesn't have cached routing table\n\n"));
826 }
827 }
828 else
829 {
830 ConsoleWrite(pCtx, _T("ERROR: Object is not a node\n\n"));
831 }
832 }
833 else
834 {
835 ConsolePrintf(pCtx, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode);
836 }
837 }
838 else
839 {
840 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing node ID\n\n"));
841 }
842 }
843 else if (IsCommand(_T("SESSIONS"), szBuffer, 2))
844 {
845 ConsoleWrite(pCtx, _T("\x1b[1mCLIENT SESSIONS\x1b[0m\n============================================================\n"));
846 DumpClientSessions(pCtx);
847 ConsoleWrite(pCtx, _T("\n\x1b[1mMOBILE DEVICE SESSIONS\x1b[0m\n============================================================\n"));
848 DumpMobileDeviceSessions(pCtx);
849 }
850 else if (IsCommand(_T("STATS"), szBuffer, 2))
851 {
852 ShowServerStats(pCtx);
853 }
854 else if (IsCommand(_T("THREADS"), szBuffer, 2))
855 {
856 ShowThreadPool(pCtx, g_mainThreadPool);
857 ShowThreadPool(pCtx, g_pollerThreadPool);
858 ShowThreadPool(pCtx, g_dataCollectorThreadPool);
859 ShowThreadPool(pCtx, g_schedulerThreadPool);
860 ShowThreadPool(pCtx, g_agentConnectionThreadPool);
861 }
862 else if (IsCommand(_T("TOPOLOGY"), szBuffer, 1))
863 {
864 ExtractWord(pArg, szBuffer);
865 UINT32 nodeId = _tcstoul(szBuffer, NULL, 0);
866 if (nodeId != 0)
867 {
868 Node *node = (Node *)FindObjectById(nodeId, OBJECT_NODE);
869 if (node != NULL)
870 {
871 LinkLayerNeighbors *nbs = BuildLinkLayerNeighborList(node);
872 if (nbs != NULL)
873 {
874 ConsolePrintf(pCtx, _T("Proto | PtP | ifLocal | ifRemote | Peer\n")
875 _T("--------+-----+---------+----------+------------------------------------\n"));
876 for(int i = 0; i < nbs->size(); i++)
877 {
878 LL_NEIGHBOR_INFO *ni = nbs->getConnection(i);
879 TCHAR peer[256];
880 if (ni->objectId != 0)
881 {
882 NetObj *object = FindObjectById(ni->objectId);
883 if (object != NULL)
884 _sntprintf(peer, 256, _T("%s [%d]"), object->getName(), ni->objectId);
885 else
886 _sntprintf(peer, 256, _T("[%d]"), ni->objectId);
887 }
888 else
889 {
890 peer[0] = 0;
891 }
892 ConsolePrintf(pCtx, _T("%-7s | %c | %7d | %7d | %s\n"),
893 GetLinkLayerProtocolName(ni->protocol), ni->isPtToPt ? _T('Y') : _T('N'), ni->ifLocal, ni->ifRemote, peer);
894 }
895 nbs->decRefCount();
896 }
897 else
898 {
899 ConsoleWrite(pCtx, _T("ERROR: call to BuildLinkLayerNeighborList failed\n\n"));
900 }
901 }
902 else
903 {
904 ConsolePrintf(pCtx, _T("ERROR: Node with ID %d does not exist\n\n"), nodeId);
905 }
906 }
907 else
908 {
909 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing node ID\n\n"));
910 }
911 }
912 else if (IsCommand(_T("TUNNELS"), szBuffer, 2))
913 {
914 ShowAgentTunnels(pCtx);
915 }
916 else if (IsCommand(_T("USERS"), szBuffer, 1))
917 {
918 DumpUsers(pCtx);
919 }
920 else if (IsCommand(_T("VLANS"), szBuffer, 1))
921 {
922 UINT32 dwNode;
923 NetObj *pObject;
924
925 ExtractWord(pArg, szBuffer);
926 dwNode = _tcstoul(szBuffer, NULL, 0);
927 if (dwNode != 0)
928 {
929 pObject = FindObjectById(dwNode);
930 if (pObject != NULL)
931 {
932 if (pObject->getObjectClass() == OBJECT_NODE)
933 {
934 VlanList *vlans = ((Node *)pObject)->getVlans();
935 if (vlans != NULL)
936 {
937 ConsoleWrite(pCtx, _T("\x1b[1mVLAN\x1b[0m | \x1b[1mName\x1b[0m | \x1b[1mPorts\x1b[0m\n")
938 _T("-----+------------------+-----------------------------------------------------------------\n"));
939 for(int i = 0; i < vlans->size(); i++)
940 {
941 VlanInfo *vlan = vlans->get(i);
942 ConsolePrintf(pCtx, _T("%4d | %-16s |"), vlan->getVlanId(), vlan->getName());
943 for(int j = 0; j < vlan->getNumPorts(); j++)
944 ConsolePrintf(pCtx, _T(" %d.%d"), (int)(vlan->getPorts()[j] >> 16), (int)(vlan->getPorts()[j] & 0xFFFF));
945 ConsolePrintf(pCtx, _T("\n"));
946 }
947 ConsolePrintf(pCtx, _T("\n"));
948 vlans->decRefCount();
949 }
950 else
951 {
952 ConsoleWrite(pCtx, _T("\x1b[31mNode doesn't have VLAN information\x1b[0m\n\n"));
953 }
954 }
955 else
956 {
957 ConsoleWrite(pCtx, _T("\x1b[31mERROR: Object is not a node\x1b[0m\n\n"));
958 }
959 }
960 else
961 {
962 ConsolePrintf(pCtx, _T("\x1b[31mERROR: Object with ID %d does not exist\x1b[0m\n\n"), dwNode);
963 }
964 }
965 else
966 {
967 ConsoleWrite(pCtx, _T("\x1b[31mERROR: Invalid or missing node ID\x1b[0m\n\n"));
968 }
969 }
970 else if (IsCommand(_T("WATCHDOG"), szBuffer, 1))
971 {
972 WatchdogPrintStatus(pCtx);
973 ConsoleWrite(pCtx, _T("\n"));
974 }
975 else
976 {
977 if (szBuffer[0] == 0)
978 ConsoleWrite(pCtx, _T("ERROR: Missing subcommand\n\n"));
979 else
980 ConsoleWrite(pCtx, _T("ERROR: Invalid SHOW subcommand\n\n"));
981 }
982 }
983 else if (IsCommand(_T("SNAPSHOT"), szBuffer, 4))
984 {
985 // create access snapshot
986 ExtractWord(pArg, szBuffer);
987 UINT32 userId = _tcstoul(szBuffer, NULL, 0);
988 bool success = CreateObjectAccessSnapshot(userId, OBJECT_NODE);
989 ConsolePrintf(pCtx, _T("Object access snapshot creation for user %d %s\n\n"), userId, success ? _T("successful") : _T("failed"));
990 }
991 else if (IsCommand(_T("EXEC"), szBuffer, 3))
992 {
993 pArg = ExtractWord(pArg, szBuffer);
994
995 bool libraryLocked = true;
996 bool destroyCompiledScript = false;
997 NXSL_Library *scriptLibrary = GetServerScriptLibrary();
998 scriptLibrary->lock();
999
1000 NXSL_Program *compiledScript = scriptLibrary->findNxslProgram(szBuffer);
1001 if (compiledScript == NULL)
1002 {
1003 scriptLibrary->unlock();
1004 libraryLocked = false;
1005 destroyCompiledScript = true;
1006 char *script;
1007 UINT32 fileSize;
1008 if ((script = (char *)LoadFile(szBuffer, &fileSize)) != NULL)
1009 {
1010 const int errorMsgLen = 512;
1011 TCHAR errorMsg[errorMsgLen];
1012 #ifdef UNICODE
1013 WCHAR *wscript = WideStringFromMBString(script);
1014 compiledScript = NXSLCompile(wscript, errorMsg, errorMsgLen, NULL);
1015 free(wscript);
1016 #else
1017 compiledScript = NXSLCompile(script, errorMsg, errorMsgLen, NULL);
1018 #endif
1019 free(script);
1020 if (compiledScript == NULL)
1021 {
1022 ConsolePrintf(pCtx, _T("ERROR: Script compilation error: %s\n\n"), errorMsg);
1023 }
1024 }
1025 else
1026 {
1027 ConsolePrintf(pCtx, _T("ERROR: Script \"%s\" not found\n\n"), szBuffer);
1028 }
1029 }
1030
1031 if (compiledScript != NULL)
1032 {
1033 NXSL_ServerEnv *pEnv = new NXSL_ServerEnv;
1034 pEnv->setConsole(pCtx);
1035
1036 NXSL_VM *vm = new NXSL_VM(pEnv);
1037 if (vm->load(compiledScript))
1038 {
1039 if (libraryLocked)
1040 {
1041 scriptLibrary->unlock();
1042 libraryLocked = false;
1043 }
1044
1045 NXSL_Value *argv[32];
1046 int argc = 0;
1047 while(argc < 32)
1048 {
1049 pArg = ExtractWord(pArg, szBuffer);
1050 if (szBuffer[0] == 0)
1051 break;
1052 argv[argc++] = new NXSL_Value(szBuffer);
1053 }
1054
1055 if (vm->run(argc, argv))
1056 {
1057 NXSL_Value *pValue = vm->getResult();
1058 int retCode = pValue->getValueAsInt32();
1059 ConsolePrintf(pCtx, _T("INFO: Script finished with rc=%d\n\n"), retCode);
1060 }
1061 else
1062 {
1063 ConsolePrintf(pCtx, _T("ERROR: Script finished with error: %s\n\n"), vm->getErrorText());
1064 }
1065 }
1066 else
1067 {
1068 ConsolePrintf(pCtx, _T("ERROR: VM creation failed: %s\n\n"), vm->getErrorText());
1069 }
1070 delete vm;
1071 if (destroyCompiledScript)
1072 delete compiledScript;
1073 }
1074 if (libraryLocked)
1075 scriptLibrary->unlock();
1076 }
1077 else if (IsCommand(_T("TRACE"), szBuffer, 1))
1078 {
1079 UINT32 dwNode1, dwNode2;
1080 NetObj *pObject1, *pObject2;
1081 NetworkPath *pTrace;
1082 TCHAR szNextHop[16];
1083 int i;
1084
1085 // Get arguments
1086 pArg = ExtractWord(pArg, szBuffer);
1087 dwNode1 = _tcstoul(szBuffer, NULL, 0);
1088
1089 ExtractWord(pArg, szBuffer);
1090 dwNode2 = _tcstoul(szBuffer, NULL, 0);
1091
1092 if ((dwNode1 != 0) && (dwNode2 != 0))
1093 {
1094 pObject1 = FindObjectById(dwNode1);
1095 if (pObject1 == NULL)
1096 {
1097 ConsolePrintf(pCtx, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode1);
1098 }
1099 else
1100 {
1101 pObject2 = FindObjectById(dwNode2);
1102 if (pObject2 == NULL)
1103 {
1104 ConsolePrintf(pCtx, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode2);
1105 }
1106 else
1107 {
1108 if ((pObject1->getObjectClass() == OBJECT_NODE) && (pObject2->getObjectClass() == OBJECT_NODE))
1109 {
1110 pTrace = TraceRoute((Node *)pObject1, (Node *)pObject2);
1111 if (pTrace != NULL)
1112 {
1113 TCHAR sourceIp[32];
1114 ConsolePrintf(pCtx, _T("Trace from %s to %s (%d hops, %s, source IP %s):\n"),
1115 pObject1->getName(), pObject2->getName(), pTrace->getHopCount(),
1116 pTrace->isComplete() ? _T("complete") : _T("incomplete"),
1117 pTrace->getSourceAddress().toString(sourceIp));
1118 for(i = 0; i < pTrace->getHopCount(); i++)
1119 {
1120 HOP_INFO *hop = pTrace->getHopInfo(i);
1121 ConsolePrintf(pCtx, _T("[%d] %s %s %s %d\n"),
1122 hop->object->getId(),
1123 hop->object->getName(),
1124 hop->nextHop.toString(szNextHop),
1125 hop->isVpn ? _T("VPN Connector ID:") : _T("Interface Index: "),
1126 hop->ifIndex);
1127 }
1128 delete pTrace;
1129 ConsolePrintf(pCtx, _T("\n"));
1130 }
1131 else
1132 {
1133 ConsoleWrite(pCtx, _T("ERROR: Call to TraceRoute() failed\n\n"));
1134 }
1135 }
1136 else
1137 {
1138 ConsoleWrite(pCtx, _T("ERROR: Object is not a node\n\n"));
1139 }
1140 }
1141 }
1142 }
1143 else
1144 {
1145 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing node id(s)\n\n"));
1146 }
1147 }
1148 else if (IsCommand(_T("TUNNEL"), szBuffer, 2))
1149 {
1150 pArg = ExtractWord(pArg, szBuffer);
1151 if (IsCommand(_T("BIND"), szBuffer, 1))
1152 {
1153 pArg = ExtractWord(pArg, szBuffer);
1154 UINT32 tunnelId = _tcstoul(szBuffer, NULL, 0);
1155
1156 ExtractWord(pArg, szBuffer);
1157 UINT32 nodeId = _tcstoul(szBuffer, NULL, 0);
1158
1159 if ((tunnelId != 0) && (nodeId != 0))
1160 {
1161 UINT32 rcc = BindAgentTunnel(tunnelId, nodeId);
1162 ConsolePrintf(pCtx, _T("Bind tunnel %d to node %d: RCC = %d\n\n"), tunnelId, nodeId, rcc);
1163 }
1164 else
1165 {
1166 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing argument(s)\n\n"));
1167 }
1168 }
1169 else if (IsCommand(_T("UNBIND"), szBuffer, 1))
1170 {
1171 ExtractWord(pArg, szBuffer);
1172 UINT32 nodeId = _tcstoul(szBuffer, NULL, 0);
1173
1174 if (nodeId != 0)
1175 {
1176 UINT32 rcc = UnbindAgentTunnel(nodeId);
1177 ConsolePrintf(pCtx, _T("Unbind tunnel from node %d: RCC = %d\n\n"), nodeId, rcc);
1178 }
1179 else
1180 {
1181 ConsoleWrite(pCtx, _T("ERROR: Invalid or missing argument(s)\n\n"));
1182 }
1183 }
1184 else
1185 {
1186 ConsoleWrite(pCtx, _T("ERROR: Invalid TUNNEL subcommand\n\n"));
1187 }
1188 }
1189 else if (IsCommand(_T("HELP"), szBuffer, 2) || IsCommand(_T("?"), szBuffer, 1))
1190 {
1191 ConsoleWrite(pCtx,
1192 _T("Valid commands are:\n")
1193 _T(" at +<sec> <script> [<params>] - Schedule one time script execution task\n")
1194 _T(" at <schedule> <script> [<params>] - Schedule repeated script execution task\n")
1195 _T(" debug [<level>|off] - Set debug level (valid range is 0..9)\n")
1196 _T(" down - Shutdown NetXMS server\n")
1197 _T(" exec <script> [<params>] - Executes NXSL script from script library\n")
1198 _T(" exit - Exit from remote session\n")
1199 _T(" kill <session> - Kill client session\n")
1200 _T(" get <variable> - Get value of server configuration variable\n")
1201 _T(" help - Display this help\n")
1202 _T(" hkrun - Run housekeeper immediately\n")
1203 _T(" ldapsync - Synchronize ldap users with local user database\n")
1204 _T(" log <text> - Write given text to server log file\n")
1205 _T(" logmark - Write marker ******* MARK ******* to server log file\n")
1206 _T(" ping <address> - Send ICMP echo request to given IP address\n")
1207 _T(" poll <type> <node> - Initiate node poll\n")
1208 _T(" raise <exception> - Raise exception\n")
1209 _T(" set <variable> <value> - Set value of server configuration variable\n")
1210 _T(" show components <node> - Show physical components of given node\n")
1211 _T(" show dbcp - Show active sessions in database connection pool\n")
1212 _T(" show dbstats - Show DB library statistics\n")
1213 _T(" show fdb <node> - Show forwarding database for node\n")
1214 _T(" show flags - Show internal server flags\n")
1215 _T(" show heap - Show heap information\n")
1216 _T(" show index <index> - Show internal index\n")
1217 _T(" show modules - Show loaded server modules\n")
1218 _T(" show msgwq - Show message wait queues information\n")
1219 _T(" show objects [<filter>] - Dump network objects to screen\n")
1220 _T(" show pe - Show registered prediction engines\n")
1221 _T(" show pollers - Show poller threads state information\n")
1222 _T(" show queues - Show internal queues statistics\n")
1223 _T(" show routing-table <node> - Show cached routing table for node\n")
1224 _T(" show sessions - Show active client sessions\n")
1225 _T(" show stats - Show server statistics\n")
1226 _T(" show topology <node> - Collect and show link layer topology for node\n")
1227 _T(" show tunnels - Show active agent tunnels\n")
1228 _T(" show users - Show users\n")
1229 _T(" show vlans <node> - Show cached VLAN information for node\n")
1230 _T(" show watchdog - Display watchdog information\n")
1231 _T(" trace <node1> <node2> - Show network path trace between two nodes\n")
1232 _T(" tunnel bind <tunnel> <node> - Bind agent tunnel to node\n")
1233 _T(" tunnel unbind <node> - Unbind agent tunnel from node\n")
1234 _T("\nAlmost all commands can be abbreviated to 2 or 3 characters\n")
1235 _T("\n"));
1236 }
1237 else
1238 {
1239 ConsoleWrite(pCtx, _T("UNKNOWN COMMAND\n\n"));
1240 }
1241
1242 return nExitCode;
1243 }