MonitorIPScanner






4.57/5 (12投票s)
2007年4月24日
4分钟阅读

59554

5471
用于控制和监控系统功能的文章。
概述
"Monitor IP Scanner" 是一款用于监控系统资源并执行其基本功能的工具。它面向系统管理员和普通用户,用于监控和管理他们的网络。
Monitor IP Scanner 可用于监控:内存使用情况、IP 配置、包含 IP 统计信息的网络配置详细信息、路由表和 ARP 表信息。您还可以使用 IP 地址或域名检查网络计算机是否处于活动状态。您甚至可以通过建立客户端/服务器连接在网络上的计算机之间发送消息。因此,服务器将支持更多的客户端连接。这还将用于从同一网络上的其他 PC 获取信息。例如:获取路由表、IP 统计信息、其他计算机的 ARP 表信息,并通过使用显示在 TCP 路由表中的 IP 地址或用户定义的 IP 地址建立 TCP 连接,将这些信息显示在另一台计算机上——这些都是可能的。
Components
Monitor IP Scanner 支持以下一些主要功能:
- 主机配置
- IP 配置
- MonAdmin 配置
- 网络配置
- Ping 配置
- 发送消息
Monitor IP 及其组件的演练。
主机配置
这将显示您系统的相关信息,例如内存使用情况和主机名。内存使用情况详细信息,如:页面文件使用情况、虚拟内存使用情况和页面错误计数等,这些信息是通过从 NTDLL.Lib 文件导入的 "ZwQuerySystemInformation" API 检索的。此 API 用于获取 PC 当前所有正在运行的进程信息。检索到的全局结构包含内存使用情况信息。
typedef struct _VM_COUNTERS {
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
} VM_COUNTERS;
typedef struct _SYSTEM_THREAD_INFORMATION {
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
LONG State;
LONG WaitReason;
} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
SYSTEM_THREAD_INFORMATION Threads[1];
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;
extern "C"
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
IN UINT SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
在此面板的底部,有一个名为“系统信息...”的按钮,它会为您提供有关以下信息:您系统上可用的驱动器、处理器、处理器速度等。
...
if(GetSystemInfo(m_SysInfo))
{
UINT Res = (UINT) ::ShellExecute(GetSafeHwnd(), _T("open"),
m_SysInfo, NULL, NULL, SW_SHOWNORMAL);
if( Res <= HINSTANCE_ERROR )
{
AfxMessageBox( _T( "Error Executing \"MsInfo32.exe\" !" ),
MB_OK | MB_ICONEXCLAMATION );
}
}
...
IP 配置
这将显示您 PC 中所有可用的网卡/适配器卡的信息,包括本地 IP 地址、MAC 地址、子网掩码、默认网关以及为特定网卡/适配器卡配置的其他信息。这还将显示 DNS 和 DHCP 信息。
获取带有 IP 地址、MAC 地址、子网掩码和默认网关的适配器信息
...
PIP_ADAPTER_INFO pAdapter = NULL;
dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen);
DNS information is retrieved using...
PFIXED_INFO pFixedInfo;
m_dwResult = GetNetworkParams((PFIXED_INFO)m_pBuffer,&m_ulSize);
MonAdmin 配置
在这里,您可以从任何同时运行 Monitor IP 的其他计算机获取协议统计信息、路由表和 ARP 表信息。您可以通过以下方式执行此操作:在 TCP 连接表中选择您想要获取信息的 IP 地址,然后选择要检索的信息类型,接着单击“检索信息”按钮。如果您要查找的 IP 不在 TCP 连接表中,则单击“其他 IP”按钮并手动输入。进度条完成后,信息将显示在“检索到的信息”框中。
Structure and API used to get TCP Connection Table
PMIB_TCPTABLE pTcpTable;
GetTcpTable(pTcpTable, &dwSize, TRUE)
...
网络配置
这将显示您网卡/适配器的网络活动,并显示自激活网卡/适配器以来已发送的字节数、已丢弃的字节数、错误的字节数以及包含单播数据包详细信息的字节数。它还显示路由表、协议统计信息和 ARP 表信息。
检索网络活动的 कोड...
MIB_IFTABLE *m_pTable;
pGetIfTable=(TGetIfTable)GetProcAddress(LoadLibrary
("Iphlpapi.dll"), "GetIfTable");
pGetNumberOfInterfaces=(TGetNumberOfInterfaces)GetProcAddress
(LoadLibrary("Iphlpapi.dll"),"GetNumberOfInterfaces");
m_pTable=NULL;
if (!pGetIfTable || !pGetNumberOfInterfaces)
{
AfxMessageBox("Error loading Iphlpapi.dll");
return;
}
ULONG uRetCode = pGetIfTable(m_pTable,&m_dwAdapters,TRUE);
m_pTable=new MIB_IFTABLE[m_dwAdapters];
pGetIfTable(m_pTable,&m_dwAdapters,TRUE);
...
// Code to retrieve Protocol Statistics information ...
MIB_IPSTATS IPStats;
m_dwResult = GetIpStatistics(&IPStats);
// Code to retrieve Routing Table information ...
MIB_IPFORWARDROW IPForwardRow;
m_dwResult = GetBestRoute(inet_addr(_T("207.219.70.31")), 0,
&IPForwardRow);
...
// Code to retrieve ARP Table information
PMIB_IPNETTABLE pMib = (PMIB_IPNETTABLE)
malloc(sizeof(MIB_IPNETTABLE)+sizeof(MIB_IPNETROW)*nSize);
DWORD dwRet = GetIpNetTable(pMib,&nSize,TRUE);
...
Ping 配置
这使得能够检查您与另一台计算机之间的连接是已建立还是已断开。用法基本上是不言自明的,但如果不是……您可以通过域名或 IP 地址进行 ping 操作,并且可以设置超时、TTL 和要发送的数据包数量。
Ping 配置代码...
...
HANDLE hIP = IcmpCreateFile();
IP_OPTION_INFORMATION OptionInfo;
OptionInfo.Ttl = PingOption.m_nTTL;
OptionInfo.Tos = PingOption.m_nTOS;
if (PingOption.m_bDontFragment)
OptionInfo.Flags = IP_FLAG_DF;
Set up the data which will be sent
unsigned char* pBuf = new unsigned
char[PingOption.m_wDataRequestSize];
memset(pBuf, 'S', PingOption.m_wDataRequestSize);
Do the actual Ping
DWORD dwReplySize = sizeof(ICMP_ECHO_REPLY) +
max(PingOption.m_wDataRequestSize, 8);
unsigned char* pReply = new unsigned char[dwReplySize];
ICMP_ECHO_REPLY* pEchoReply =
reinterpret_cast(pReply);
DWORD nRecvPackets = IcmpSendEcho(hIP, addr, pBuf,
PingOption.m_wDataRequestSize, &OptionInfo,
pReply, dwReplySize, PingOption.m_dwTimeout);
...
发送消息
要发送消息,必须创建一个服务器供客户端连接。如果已创建服务器,则必须创建一个客户端并连接到服务器。无论哪种方式,连接后您最多可以与连接到该服务器的三个其他客户端进行通信。使用用户名是可选的。
以下是使用发送消息选项的说明:
- 通过输入端口号(请记住此端口号)创建服务器。
- 按“启动服务器”按钮。
- 通过输入您创建的服务器的地址和端口号来创建客户端。
- 按“启动客户端”按钮。(注意:如果所有这些操作都在同一台计算机上进行,那么您唯一使用的地址将是环回地址 (127.0.0.1))。
- 一旦建立连接。将自动生成一个用户名,前缀为“Client #”,后跟连接号。
- 客户端窗口和服务器窗口将显示成功的问候语。
- 现在,可以通过单击“发送消息按钮”在客户端和服务器之间交换数据。
- 在每次从服务器发送消息之前,应从用户列表中选择要发送数据的客户端名称。
发送消息代码实现...
{
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
...
Server_Addr.sin_port = htons(m_PortNo);
Server_Addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
Server_Addr.sin_family = AF_INET;
addlen = sizeof(Server_Addr);
Sock = socket(AF_INET, SOCK_STREAM, NULL);
...
if(bind(Sock, (const sockaddr *) &Server_Addr, addlen))
...
if(listen(Sock, 5))
...
AfxBeginThread(&ServerThread, NULL, 0, 0, 0, NULL);
}
UINT ServerThread(LPVOID lpVoid)
{
m_Socket = accept(SendMsgDlg->Sock,(SOCKADDR *)
&SendMsgDlg->Server_Addr, &SendMsgDlg->addlen);
...
AfxBeginThread(&ServerThread, NULL, 0, 0, 0, NULL);
...
while((Res = recv(m_Socket, RecvBuffer, sizeof(RecvBuffer),
0)) != SOCKET_ERROR)
{
...
}
send(m_Socket, "Disconnected", 100, 0);
...
::closesocket(m_Socket);
::AfxEndThread(0);
return TRUE;
}