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