2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2017 Raden Solutions
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.
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.
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.
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
;
36 void ShowPredictionEngines(CONSOLE_CTX console
);
37 void ShowAgentTunnels(CONSOLE_CTX console
);
38 UINT32
BindAgentTunnel(UINT32 tunnelId
, UINT32 nodeId
);
39 UINT32
UnbindAgentTunnel(UINT32 nodeId
);
42 * Format string to show value of global flag
44 #define SHOW_FLAG_VALUE(x) _T(" %-38s = %d\n"), _T(#x), (g_flags & x) ? 1 : 0
47 * Compare given string to command template with abbreviation possibility
49 static bool IsCommand(const TCHAR
*cmdTemplate
, TCHAR
*pszString
, int iMinChars
)
53 // Convert given string to uppercase
56 for(i
= 0; pszString
[i
] != 0; i
++)
57 if (pszString
[i
] != cmdTemplate
[i
])
65 * Dump index callback (by IP address)
67 static void DumpIndexCallbackByInetAddr(const InetAddress
& addr
, NetObj
*object
, void *data
)
70 ConsolePrintf((CONSOLE_CTX
)data
, _T("%-40s %p %s [%d]\n"), addr
.toString(buffer
), object
, object
->getName(), (int)object
->getId());
74 * Dump index (by IP address)
76 void DumpIndex(CONSOLE_CTX pCtx
, InetAddressIndex
*index
)
78 index
->forEach(DumpIndexCallbackByInetAddr
, pCtx
);
82 * Dump index callback (by ID)
84 static void DumpIndexCallbackById(NetObj
*object
, void *data
)
86 ConsolePrintf((CONSOLE_CTX
)data
, _T("%08X %p %s\n"), object
->getId(), object
, object
->getName());
92 static void DumpIndex(CONSOLE_CTX pCtx
, ObjectIndex
*index
)
94 index
->forEach(DumpIndexCallbackById
, pCtx
);
98 * Process command entered from command line in standalone mode
99 * Return TRUE if command was _T("down")
101 int ProcessConsoleCommand(const TCHAR
*pszCmdLine
, CONSOLE_CTX pCtx
)
103 TCHAR szBuffer
[256], *eptr
;
104 int nExitCode
= CMD_EXIT_CONTINUE
;
107 const TCHAR
*pArg
= ExtractWord(pszCmdLine
, szBuffer
);
109 if (IsCommand(_T("AT"), szBuffer
, 2))
111 pArg
= ExtractWord(pArg
, szBuffer
);
112 if (szBuffer
[0] == _T('+'))
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
119 AddScheduledTask(_T("Execute.Script"), szBuffer
, pArg
, 0, 0, SYSTEM_ACCESS_FULL
); //TODO: change to correct user
122 else if (IsCommand(_T("DEBUG"), szBuffer
, 2))
124 StringList
*list
= ParseCommandLine(pArg
);
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);
132 if ((*eptr
== 0) && (level
>= -1) && (level
<= 9))
134 if (list
->size() == 1)
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
);
139 else if (list
->size() == 2)
141 nxlog_set_debug_level_tag(list
->get(0), level
);
143 ConsolePrintf(pCtx
, _T("Debug tag <%s> removed\n"), list
->get(0));
145 ConsolePrintf(pCtx
, _T("Debug level for tag <%s> set to %d\n"), list
->get(0), level
);
148 else if (IsCommand(_T("OFF"), szBuffer
, 2))
150 nxlog_set_debug_level(0);
151 ConsoleWrite(pCtx
, _T("Debug mode turned off\n"));
155 if (szBuffer
[0] == 0)
156 ConsoleWrite(pCtx
, _T("ERROR: Missing argument\n\n"));
158 ConsoleWrite(pCtx
, _T("ERROR: Invalid debug level\n\n"));
162 else if (IsCommand(_T("DOWN"), szBuffer
, 4))
164 ConsoleWrite(pCtx
, _T("Proceeding with server shutdown...\n"));
165 nExitCode
= CMD_EXIT_SHUTDOWN
;
167 else if (IsCommand(_T("DUMP"), szBuffer
, 4))
171 else if (IsCommand(_T("GET"), szBuffer
, 3))
173 ExtractWord(pArg
, szBuffer
);
174 if (szBuffer
[0] != 0)
176 TCHAR value
[MAX_CONFIG_VALUE
];
177 ConfigReadStr(szBuffer
, value
, MAX_CONFIG_VALUE
, _T(""));
178 ConsolePrintf(pCtx
, _T("%s = %s\n"), szBuffer
, value
);
182 ConsoleWrite(pCtx
, _T("Variable name missing\n"));
185 else if (IsCommand(_T("HKRUN"), szBuffer
, 2))
187 ConsoleWrite(pCtx
, _T("Starting housekeeper\n"));
190 else if (IsCommand(_T("LDAPSYNC"), szBuffer
, 4))
195 else if (IsCommand(_T("LOG"), szBuffer
, 3))
197 while(_istspace(*pArg
))
200 DbgPrintf(0, _T("%s"), pArg
);
202 else if (IsCommand(_T("LOGMARK"), szBuffer
, 4))
204 DbgPrintf(0, _T("******* MARK *******"));
206 else if (IsCommand(_T("RAISE"), szBuffer
, 5))
209 ExtractWord(pArg
, szBuffer
);
211 if (IsCommand(_T("ACCESS"), szBuffer
, 6))
213 ConsoleWrite(pCtx
, _T("Raising exception...\n"));
217 else if (IsCommand(_T("BREAKPOINT"), szBuffer
, 5))
220 ConsoleWrite(pCtx
, _T("Raising exception...\n"));
221 RaiseException(EXCEPTION_BREAKPOINT
, 0, 0, NULL
);
223 ConsoleWrite(pCtx
, _T("ERROR: Not supported on current platform\n"));
228 ConsoleWrite(pCtx
, _T("Invalid exception name; possible names are:\nACCESS BREAKPOINT\n"));
231 else if (IsCommand(_T("EXIT"), szBuffer
, 4))
233 if ((pCtx
->hSocket
!= -1) || (pCtx
->session
!= NULL
))
235 ConsoleWrite(pCtx
, _T("Closing session...\n"));
236 nExitCode
= CMD_EXIT_CLOSE_SESSION
;
240 ConsoleWrite(pCtx
, _T("Cannot exit from local server console\n"));
243 else if (IsCommand(_T("KILL"), szBuffer
, 4))
245 ExtractWord(pArg
, szBuffer
);
246 if (szBuffer
[0] != 0)
248 int id
= _tcstol(szBuffer
, &eptr
, 10);
251 if (KillClientSession(id
))
253 ConsoleWrite(pCtx
, _T("Session killed\n"));
257 ConsoleWrite(pCtx
, _T("Invalid session ID\n"));
262 ConsoleWrite(pCtx
, _T("Invalid session ID\n"));
267 ConsoleWrite(pCtx
, _T("Session ID missing\n"));
270 else if (IsCommand(_T("PING"), szBuffer
, 4))
272 ExtractWord(pArg
, szBuffer
);
273 if (szBuffer
[0] != 0)
275 InetAddress addr
= InetAddress::parse(szBuffer
);
279 UINT32 rc
= IcmpPing(addr
, 1, 2000, &rtt
, 128);
283 ConsolePrintf(pCtx
, _T("Success, RTT = %d ms\n"), (int)rtt
);
285 case ICMP_UNREACHEABLE
:
286 ConsolePrintf(pCtx
, _T("Destination unreachable\n"));
289 ConsolePrintf(pCtx
, _T("Request timeout\n"));
291 case ICMP_RAW_SOCK_FAILED
:
292 ConsolePrintf(pCtx
, _T("Cannot create raw socket\n"));
295 ConsolePrintf(pCtx
, _T("API error\n"));
298 ConsolePrintf(pCtx
, _T("ERROR %d\n"), (int)rc
);
304 ConsoleWrite(pCtx
, _T("Invalid IP address\n"));
309 ConsoleWrite(pCtx
, _T("Usage: PING <address>\n"));
312 else if (IsCommand(_T("POLL"), szBuffer
, 2))
314 pArg
= ExtractWord(pArg
, szBuffer
);
315 if (szBuffer
[0] != 0)
318 if (IsCommand(_T("CONFIGURATION"), szBuffer
, 1))
322 else if (IsCommand(_T("INSTANCE"), szBuffer
, 1))
326 else if (IsCommand(_T("ROUTING-TABLE"), szBuffer
, 1))
330 else if (IsCommand(_T("STATUS"), szBuffer
, 1))
334 else if (IsCommand(_T("TOPOLOGY"), szBuffer
, 1))
345 ExtractWord(pArg
, szBuffer
);
346 UINT32 id
= _tcstoul(szBuffer
, NULL
, 0);
349 NetObj
*object
= FindObjectById(id
);
350 if ((object
!= NULL
) && object
->isDataCollectionTarget())
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
)));
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
)));
367 if (object
->getObjectClass() == OBJECT_NODE
)
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
)));
376 ConsolePrintf(pCtx
, _T("ERROR: this poll type can only be initiated for node objects\n\n"));
380 if (object
->getObjectClass() == OBJECT_NODE
)
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
)));
389 ConsolePrintf(pCtx
, _T("ERROR: this poll type can only be initiated for node objects\n\n"));
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
)));
402 ConsolePrintf(pCtx
, _T("ERROR: data collection target with ID %d does not exist\n\n"), id
);
407 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing object ID\n\n"));
412 ConsoleWrite(pCtx
, _T("Usage POLL [CONFIGURATION|STATUS|TOPOLOGY|INSTANCE|ROUTING-TABLE] <object>\n"));
417 ConsoleWrite(pCtx
, _T("Usage POLL [CONFIGURATION|STATUS|TOPOLOGY|INSTANCE|ROUTING-TABLE] <node>\n"));
420 else if (IsCommand(_T("SET"), szBuffer
, 3))
422 pArg
= ExtractWord(pArg
, szBuffer
);
423 if (szBuffer
[0] != 0)
426 ExtractWord(pArg
, value
);
427 if (ConfigWriteStr(szBuffer
, value
, TRUE
, TRUE
, TRUE
))
429 ConsolePrintf(pCtx
, _T("Configuration variable %s updated\n"), szBuffer
);
433 ConsolePrintf(pCtx
, _T("ERROR: cannot update configuration variable %s\n"), szBuffer
);
438 ConsolePrintf(pCtx
, _T("Variable name missing\n"));
441 else if (IsCommand(_T("SHOW"), szBuffer
, 2))
444 pArg
= ExtractWord(pArg
, szBuffer
);
446 if (IsCommand(_T("COMPONENTS"), szBuffer
, 1))
449 ExtractWord(pArg
, szBuffer
);
450 UINT32 dwNode
= _tcstoul(szBuffer
, NULL
, 0);
453 NetObj
*pObject
= FindObjectById(dwNode
);
456 if (pObject
->getObjectClass() == OBJECT_NODE
)
458 ComponentTree
*components
= ((Node
*)pObject
)->getComponents();
459 if (components
!= NULL
)
461 components
->print(pCtx
);
462 components
->decRefCount();
466 ConsoleWrite(pCtx
, _T("ERROR: Node does not have physical component information\n\n"));
471 ConsoleWrite(pCtx
, _T("ERROR: Object is not a node\n\n"));
476 ConsolePrintf(pCtx
, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode
);
481 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing node ID\n\n"));
484 else if (IsCommand(_T("DBCP"), szBuffer
, 4))
486 ObjectArray
<PoolConnectionInfo
> *list
= DBConnectionPoolGetConnectionList();
487 for(int i
= 0; i
< list
->size(); i
++)
489 PoolConnectionInfo
*c
= list
->get(i
);
492 struct tm
*ltm
= localtime_r(&c
->lastAccessTime
, &tmbuffer
);
494 struct tm
*ltm
= localtime(&c
->lastAccessTime
);
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
);
500 ConsolePrintf(pCtx
, _T("%d database connections in use\n\n"), list
->size());
503 else if (IsCommand(_T("DBSTATS"), szBuffer
, 3))
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
);
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
);
519 else if (IsCommand(_T("FDB"), szBuffer
, 3))
522 ExtractWord(pArg
, szBuffer
);
523 UINT32 dwNode
= _tcstoul(szBuffer
, NULL
, 0);
526 NetObj
*pObject
= FindObjectById(dwNode
);
529 if (pObject
->getObjectClass() == OBJECT_NODE
)
531 ForwardingDatabase
*fdb
= ((Node
*)pObject
)->getSwitchForwardingDatabase();
534 fdb
->print(pCtx
, (Node
*)pObject
);
539 ConsoleWrite(pCtx
, _T("ERROR: Node does not have forwarding database information\n\n"));
544 ConsoleWrite(pCtx
, _T("ERROR: Object is not a node\n\n"));
549 ConsolePrintf(pCtx
, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode
);
554 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing node ID\n\n"));
557 else if (IsCommand(_T("FLAGS"), szBuffer
, 1))
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"));
596 else if (IsCommand(_T("HEAP"), szBuffer
, 1))
598 TCHAR
*text
= GetHeapInfo();
601 ConsoleWrite(pCtx
, text
);
602 ConsoleWrite(pCtx
, _T("\n"));
607 ConsoleWrite(pCtx
, _T("Error reading heap information\n"));
610 else if (IsCommand(_T("INDEX"), szBuffer
, 1))
613 pArg
= ExtractWord(pArg
, szBuffer
);
615 if (IsCommand(_T("CONDITION"), szBuffer
, 1))
617 DumpIndex(pCtx
, &g_idxConditionById
);
619 else if (IsCommand(_T("ID"), szBuffer
, 2))
621 DumpIndex(pCtx
, &g_idxObjectById
);
623 else if (IsCommand(_T("INTERFACE"), szBuffer
, 2))
625 pArg
= ExtractWord(pArg
, szBuffer
);
626 if (IsCommand(_T("ZONE"), szBuffer
, 1))
628 ExtractWord(pArg
, szBuffer
);
629 Zone
*zone
= FindZoneByUIN(_tcstoul(szBuffer
, NULL
, 0));
632 zone
->dumpInterfaceIndex(pCtx
);
636 ConsoleWrite(pCtx
, _T("ERROR: Invalid zone UIN\n\n"));
639 else if (szBuffer
[0] == 0)
641 DumpIndex(pCtx
, &g_idxInterfaceByAddr
);
645 ConsoleWrite(pCtx
, _T("ERROR: Invalid index modifier\n\n"));
648 else if (IsCommand(_T("NODEADDR"), szBuffer
, 5))
650 pArg
= ExtractWord(pArg
, szBuffer
);
651 if (IsCommand(_T("ZONE"), szBuffer
, 1))
653 ExtractWord(pArg
, szBuffer
);
654 Zone
*zone
= FindZoneByUIN(_tcstoul(szBuffer
, NULL
, 0));
657 zone
->dumpNodeIndex(pCtx
);
661 ConsoleWrite(pCtx
, _T("ERROR: Invalid zone UIN\n\n"));
664 else if (szBuffer
[0] == 0)
666 DumpIndex(pCtx
, &g_idxNodeByAddr
);
670 ConsoleWrite(pCtx
, _T("ERROR: Invalid index modifier\n\n"));
673 else if (IsCommand(_T("NODEID"), szBuffer
, 5))
675 DumpIndex(pCtx
, &g_idxNodeById
);
677 else if (IsCommand(_T("SUBNET"), szBuffer
, 1))
679 pArg
= ExtractWord(pArg
, szBuffer
);
680 if (IsCommand(_T("ZONE"), szBuffer
, 1))
682 ExtractWord(pArg
, szBuffer
);
683 Zone
*zone
= FindZoneByUIN(_tcstoul(szBuffer
, NULL
, 0));
686 zone
->dumpSubnetIndex(pCtx
);
690 ConsoleWrite(pCtx
, _T("ERROR: Invalid zone UIN\n\n"));
693 else if (szBuffer
[0] == 0)
695 DumpIndex(pCtx
, &g_idxSubnetByAddr
);
699 ConsoleWrite(pCtx
, _T("ERROR: Invalid index modifier\n\n"));
702 else if (IsCommand(_T("ZONE"), szBuffer
, 1))
704 DumpIndex(pCtx
, &g_idxZoneByUIN
);
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"));
713 ConsoleWrite(pCtx
, _T("ERROR: Invalid index name\n\n"));
716 else if (IsCommand(_T("LLDP"), szBuffer
, 4))
719 ExtractWord(pArg
, szBuffer
);
720 UINT32 dwNode
= _tcstoul(szBuffer
, NULL
, 0);
723 NetObj
*pObject
= FindObjectById(dwNode
);
726 if (pObject
->getObjectClass() == OBJECT_NODE
)
728 ((Node
*)pObject
)->showLLDPInfo(pCtx
);
732 ConsoleWrite(pCtx
, _T("ERROR: Object is not a node\n\n"));
737 ConsolePrintf(pCtx
, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode
);
742 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing node ID\n\n"));
745 else if (IsCommand(_T("MODULES"), szBuffer
, 3))
747 ConsoleWrite(pCtx
, _T("Loaded server modules:\n"));
748 for(UINT32 i
= 0; i
< g_dwNumModules
; i
++)
750 ConsolePrintf(pCtx
, _T(" %s\n"), g_pModuleList
[i
].szName
);
752 ConsolePrintf(pCtx
, _T("%d modules loaded\n"), g_dwNumModules
);
754 else if (IsCommand(_T("MSGWQ"), szBuffer
, 2))
756 String text
= MsgWaitQueue::getDiagInfo();
757 ConsoleWrite(pCtx
, text
);
758 ConsoleWrite(pCtx
, _T("\n"));
760 else if (IsCommand(_T("OBJECTS"), szBuffer
, 1))
763 ExtractWord(pArg
, szBuffer
);
765 DumpObjects(pCtx
, (szBuffer
[0] != 0) ? szBuffer
: NULL
);
767 else if (IsCommand(_T("PE"), szBuffer
, 2))
769 ShowPredictionEngines(pCtx
);
771 else if (IsCommand(_T("POLLERS"), szBuffer
, 2))
775 else if (IsCommand(_T("QUEUES"), szBuffer
, 1))
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"));
791 else if (IsCommand(_T("ROUTING-TABLE"), szBuffer
, 1))
796 ExtractWord(pArg
, szBuffer
);
797 dwNode
= _tcstoul(szBuffer
, NULL
, 0);
800 pObject
= FindObjectById(dwNode
);
803 if (pObject
->getObjectClass() == OBJECT_NODE
)
809 ConsolePrintf(pCtx
, _T("Routing table for node %s:\n\n"), pObject
->getName());
810 pRT
= ((Node
*)pObject
)->getCachedRoutingTable();
813 for(i
= 0; i
< pRT
->iNumEntries
; i
++)
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
);
821 ConsoleWrite(pCtx
, _T("\n"));
825 ConsoleWrite(pCtx
, _T("Node doesn't have cached routing table\n\n"));
830 ConsoleWrite(pCtx
, _T("ERROR: Object is not a node\n\n"));
835 ConsolePrintf(pCtx
, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode
);
840 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing node ID\n\n"));
843 else if (IsCommand(_T("SESSIONS"), szBuffer
, 2))
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
);
850 else if (IsCommand(_T("STATS"), szBuffer
, 2))
852 ShowServerStats(pCtx
);
854 else if (IsCommand(_T("THREADS"), szBuffer
, 2))
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
);
862 else if (IsCommand(_T("TOPOLOGY"), szBuffer
, 1))
864 ExtractWord(pArg
, szBuffer
);
865 UINT32 nodeId
= _tcstoul(szBuffer
, NULL
, 0);
868 Node
*node
= (Node
*)FindObjectById(nodeId
, OBJECT_NODE
);
871 LinkLayerNeighbors
*nbs
= BuildLinkLayerNeighborList(node
);
874 ConsolePrintf(pCtx
, _T("Proto | PtP | ifLocal | ifRemote | Peer\n")
875 _T("--------+-----+---------+----------+------------------------------------\n"));
876 for(int i
= 0; i
< nbs
->size(); i
++)
878 LL_NEIGHBOR_INFO
*ni
= nbs
->getConnection(i
);
880 if (ni
->objectId
!= 0)
882 NetObj
*object
= FindObjectById(ni
->objectId
);
884 _sntprintf(peer
, 256, _T("%s [%d]"), object
->getName(), ni
->objectId
);
886 _sntprintf(peer
, 256, _T("[%d]"), ni
->objectId
);
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
);
899 ConsoleWrite(pCtx
, _T("ERROR: call to BuildLinkLayerNeighborList failed\n\n"));
904 ConsolePrintf(pCtx
, _T("ERROR: Node with ID %d does not exist\n\n"), nodeId
);
909 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing node ID\n\n"));
912 else if (IsCommand(_T("TUNNELS"), szBuffer
, 2))
914 ShowAgentTunnels(pCtx
);
916 else if (IsCommand(_T("USERS"), szBuffer
, 1))
920 else if (IsCommand(_T("VLANS"), szBuffer
, 1))
925 ExtractWord(pArg
, szBuffer
);
926 dwNode
= _tcstoul(szBuffer
, NULL
, 0);
929 pObject
= FindObjectById(dwNode
);
932 if (pObject
->getObjectClass() == OBJECT_NODE
)
934 VlanList
*vlans
= ((Node
*)pObject
)->getVlans();
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
++)
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"));
947 ConsolePrintf(pCtx
, _T("\n"));
948 vlans
->decRefCount();
952 ConsoleWrite(pCtx
, _T("\x1b[31mNode doesn't have VLAN information\x1b[0m\n\n"));
957 ConsoleWrite(pCtx
, _T("\x1b[31mERROR: Object is not a node\x1b[0m\n\n"));
962 ConsolePrintf(pCtx
, _T("\x1b[31mERROR: Object with ID %d does not exist\x1b[0m\n\n"), dwNode
);
967 ConsoleWrite(pCtx
, _T("\x1b[31mERROR: Invalid or missing node ID\x1b[0m\n\n"));
970 else if (IsCommand(_T("WATCHDOG"), szBuffer
, 1))
972 WatchdogPrintStatus(pCtx
);
973 ConsoleWrite(pCtx
, _T("\n"));
977 if (szBuffer
[0] == 0)
978 ConsoleWrite(pCtx
, _T("ERROR: Missing subcommand\n\n"));
980 ConsoleWrite(pCtx
, _T("ERROR: Invalid SHOW subcommand\n\n"));
983 else if (IsCommand(_T("SNAPSHOT"), szBuffer
, 4))
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"));
991 else if (IsCommand(_T("EXEC"), szBuffer
, 3))
993 pArg
= ExtractWord(pArg
, szBuffer
);
995 bool libraryLocked
= true;
996 bool destroyCompiledScript
= false;
997 NXSL_Library
*scriptLibrary
= GetServerScriptLibrary();
998 scriptLibrary
->lock();
1000 NXSL_Program
*compiledScript
= scriptLibrary
->findNxslProgram(szBuffer
);
1001 if (compiledScript
== NULL
)
1003 scriptLibrary
->unlock();
1004 libraryLocked
= false;
1005 destroyCompiledScript
= true;
1008 if ((script
= (char *)LoadFile(szBuffer
, &fileSize
)) != NULL
)
1010 const int errorMsgLen
= 512;
1011 TCHAR errorMsg
[errorMsgLen
];
1013 WCHAR
*wscript
= WideStringFromMBString(script
);
1014 compiledScript
= NXSLCompile(wscript
, errorMsg
, errorMsgLen
, NULL
);
1017 compiledScript
= NXSLCompile(script
, errorMsg
, errorMsgLen
, NULL
);
1020 if (compiledScript
== NULL
)
1022 ConsolePrintf(pCtx
, _T("ERROR: Script compilation error: %s\n\n"), errorMsg
);
1027 ConsolePrintf(pCtx
, _T("ERROR: Script \"%s\" not found\n\n"), szBuffer
);
1031 if (compiledScript
!= NULL
)
1033 NXSL_ServerEnv
*pEnv
= new NXSL_ServerEnv
;
1034 pEnv
->setConsole(pCtx
);
1036 NXSL_VM
*vm
= new NXSL_VM(pEnv
);
1037 if (vm
->load(compiledScript
))
1041 scriptLibrary
->unlock();
1042 libraryLocked
= false;
1045 NXSL_Value
*argv
[32];
1049 pArg
= ExtractWord(pArg
, szBuffer
);
1050 if (szBuffer
[0] == 0)
1052 argv
[argc
++] = new NXSL_Value(szBuffer
);
1055 if (vm
->run(argc
, argv
))
1057 NXSL_Value
*pValue
= vm
->getResult();
1058 int retCode
= pValue
->getValueAsInt32();
1059 ConsolePrintf(pCtx
, _T("INFO: Script finished with rc=%d\n\n"), retCode
);
1063 ConsolePrintf(pCtx
, _T("ERROR: Script finished with error: %s\n\n"), vm
->getErrorText());
1068 ConsolePrintf(pCtx
, _T("ERROR: VM creation failed: %s\n\n"), vm
->getErrorText());
1071 if (destroyCompiledScript
)
1072 delete compiledScript
;
1075 scriptLibrary
->unlock();
1077 else if (IsCommand(_T("TRACE"), szBuffer
, 1))
1079 UINT32 dwNode1
, dwNode2
;
1080 NetObj
*pObject1
, *pObject2
;
1081 NetworkPath
*pTrace
;
1082 TCHAR szNextHop
[16];
1086 pArg
= ExtractWord(pArg
, szBuffer
);
1087 dwNode1
= _tcstoul(szBuffer
, NULL
, 0);
1089 ExtractWord(pArg
, szBuffer
);
1090 dwNode2
= _tcstoul(szBuffer
, NULL
, 0);
1092 if ((dwNode1
!= 0) && (dwNode2
!= 0))
1094 pObject1
= FindObjectById(dwNode1
);
1095 if (pObject1
== NULL
)
1097 ConsolePrintf(pCtx
, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode1
);
1101 pObject2
= FindObjectById(dwNode2
);
1102 if (pObject2
== NULL
)
1104 ConsolePrintf(pCtx
, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode2
);
1108 if ((pObject1
->getObjectClass() == OBJECT_NODE
) && (pObject2
->getObjectClass() == OBJECT_NODE
))
1110 pTrace
= TraceRoute((Node
*)pObject1
, (Node
*)pObject2
);
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
++)
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: "),
1129 ConsolePrintf(pCtx
, _T("\n"));
1133 ConsoleWrite(pCtx
, _T("ERROR: Call to TraceRoute() failed\n\n"));
1138 ConsoleWrite(pCtx
, _T("ERROR: Object is not a node\n\n"));
1145 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing node id(s)\n\n"));
1148 else if (IsCommand(_T("TUNNEL"), szBuffer
, 2))
1150 pArg
= ExtractWord(pArg
, szBuffer
);
1151 if (IsCommand(_T("BIND"), szBuffer
, 1))
1153 pArg
= ExtractWord(pArg
, szBuffer
);
1154 UINT32 tunnelId
= _tcstoul(szBuffer
, NULL
, 0);
1156 ExtractWord(pArg
, szBuffer
);
1157 UINT32 nodeId
= _tcstoul(szBuffer
, NULL
, 0);
1159 if ((tunnelId
!= 0) && (nodeId
!= 0))
1161 UINT32 rcc
= BindAgentTunnel(tunnelId
, nodeId
);
1162 ConsolePrintf(pCtx
, _T("Bind tunnel %d to node %d: RCC = %d\n\n"), tunnelId
, nodeId
, rcc
);
1166 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing argument(s)\n\n"));
1169 else if (IsCommand(_T("UNBIND"), szBuffer
, 1))
1171 ExtractWord(pArg
, szBuffer
);
1172 UINT32 nodeId
= _tcstoul(szBuffer
, NULL
, 0);
1176 UINT32 rcc
= UnbindAgentTunnel(nodeId
);
1177 ConsolePrintf(pCtx
, _T("Unbind tunnel from node %d: RCC = %d\n\n"), nodeId
, rcc
);
1181 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing argument(s)\n\n"));
1186 ConsoleWrite(pCtx
, _T("ERROR: Invalid TUNNEL subcommand\n\n"));
1189 else if (IsCommand(_T("HELP"), szBuffer
, 2) || IsCommand(_T("?"), szBuffer
, 1))
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")
1239 ConsoleWrite(pCtx
, _T("UNKNOWN COMMAND\n\n"));