Click here to Skip to main content
15,881,746 members
Articles / Desktop Programming / MFC
Article

MonitorIPScanner

Rate me:
Please Sign up or sign in to vote.
4.57/5 (13 votes)
24 Apr 20074 min read 58.6K   5.4K   57   5
Article to control and monitor system features.

Screenshot - MonitorIPScanner.jpg

Overview

"Monitor IP Scanner" is a tool used to monitor the system resources and perform some of its basic functionalities. It is intended for both system administrators and general users to monitor and manage their networks.

Monitor IP Scanner can be used to monitor: memory usage, IP configurations, network configuration details with IP statistics, routing tables and ARP table information. You can also check if a network computer is alive or not using the IP address or domain name. You can even send messages between the computers on a network by establishing client / server connectivity. Therefore, the server would support a greater number of client connections. This will also be used to get the information from other PCs which are on the same network. Things like - getting the routing table, IP statistics, ARP table information from another computer and displaying it in another computer by establishing a TCP connection using the IP address which displays in a TCP routing table or user-defined IP address - are all possibilities.

Components

Monitor IP Scanner supports some of the following major features:

  1. Host Config
  2. IP Config
  3. MonAdmin config
  4. Network Config
  5. Ping Config
  6. Send Message

A walkthrough in Monitor IP and its components.

HOST config

This will display your system's information such as memory usage and host name. Memory usage details like: Page file usage, virtual size usage and Page fault count and etc., this information is retrieved using "ZwQuerySystemInformation" API which imported from the NTDLL.Lib file. This API is used to get all the currently running process information of the PC. The retrieving global structure contains the memory usage information.

C++
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
                         );

At the bottom of this panel, there is a button called, "System Info . . .", that gives you information on: what drives are available on your system, processors, processor speed, etc.

C++
...
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 config

This displays your all the NIC/adapter card's information which are available in your PC, with the local IP address, MAC address, Subnet mask, Default gateway and other information which is configured to the particular NIC/adapter card. This will also display DNS and DHCP information.

To Get the Adapter Information with IP addresses, MAC address, Subnet Mask and default Gateway:

C++
...
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 config

Here you can get information like the Protocol statistics, Routing tables and ARP table information from any other computer that is running Monitor IP at the same time as you. You can do this by: Selecting the IP address in the TCP connection table that you would want information from and select the type of information to retrieve, and then click on the "Retrieve Info" button. If the IP you're looking for is not in the TCP connection table, then click on the "Other IP's" button and manually type it. After the progress bar is finished, the Information will appear in the "Retrieved Info" box.

C++
Structure and API used to get TCP Connection Table
PMIB_TCPTABLE pTcpTable;
GetTcpTable(pTcpTable, &dwSize, TRUE)
...

NETWORK config

This displays your NIC/adapter's networking activities and shows how many bytes have been sent, the number of bytes that have been discarded, how many bytes are errors, and how many are included with unicast packet details since the NIC/adapter has been activated. It also displays routing table, protocol statistics, and ARP table information.

Code to retrieve network activities...

C++
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 config

This gives the ability to check if a connection between you and another computer is up or down. The usage is basically self-explanatory, but if it is not ... you have the option of pinging by domain names or IP address and you can set timeout, TTL, and the number of packets to send.

Ping Configuration code...

C++
...
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<icmp_echo_reply*>(pReply);

DWORD nRecvPackets = IcmpSendEcho(hIP, addr, pBuf,
                                  PingOption.m_wDataRequestSize, &OptionInfo, 
                                  pReply, dwReplySize, PingOption.m_dwTimeout);
...</icmp_echo_reply*>

SEND MESSAGE

To Send Messages, a server must be created for clients to connect to. If a server is already created, then you must create a client and connect to a server. Either way, when connected you will be able to talk to a maximum of three other clients connected to that server. Using a user name is optional.

Here are instructions to use the send message option:

  1. Create a server by entering the port number (remember this port number).
  2. Press "Start Server" button.
  3. Create a Client by entering the address and port number of the server you have created.
  4. Press the "Start Client" button. (NOTE: If all of this is being done off of the same computer, then the only address you will be using is the loopback address (127.0.0.1)).
  5. Once the connection is established. A user name is generated automatically with the prefix "Client #" followed with connection number.
  6. A successful greeting on the client window as well in server window will be getting displayed.
  7. Now the data can be exchanged between the client and server by click the "send message button".
  8. Before sending message from server every time, the client name should be selected from user list to which the data has to be send.

Send Message Code Implementation...

C++
{
    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;
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Architect Luxoft
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionLinker Error Pin
sh_nasir17-Feb-09 18:10
sh_nasir17-Feb-09 18:10 
QuestionGlobal IP address Pin
dijesh_ka29-Sep-07 10:23
dijesh_ka29-Sep-07 10:23 
QuestionRe: Global IP address Pin
behrang yousefasr26-May-09 21:02
behrang yousefasr26-May-09 21:02 
Questiondll problem Pin
jorgening12-Aug-07 6:53
jorgening12-Aug-07 6:53 
AnswerRe: dll problem Pin
Shanmuga Sundar.V13-Aug-07 1:12
Shanmuga Sundar.V13-Aug-07 1:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.