netstat.c

来自「一个类似windows」· C语言 代码 · 共 643 行 · 第 1/2 页

C
643
字号
/*
 * PROJECT:     ReactOS netstat utility
 * LICENSE:     GPL - See COPYING in the top level directory
 * FILE:        apps/utils/net/netstat/netstat.c
 * PURPOSE:     display IP stack statistics
 * COPYRIGHT:   Copyright 2005 Ged Murphy <gedmurphy@gmail.com>
 */
/*
 * TODO:
 * sort function return values.
 * implement -b, -o and -v
 * clean up GetIpHostName
 * command line parser needs more work
 */

#include <windows.h>
#include <winsock.h>
#include <tchar.h>
#include <stdio.h>
#include <iphlpapi.h>
#include "netstat.h"


enum ProtoType {IP, TCP, UDP, ICMP} Protocol;
DWORD Interval; /* time to pause between printing output */

/* TCP endpoint states */
TCHAR TcpState[][32] = {
    _T("???"),
    _T("CLOSED"),
    _T("LISTENING"),
    _T("SYN_SENT"),
    _T("SYN_RCVD"),
    _T("ESTABLISHED"),
    _T("FIN_WAIT1"),
    _T("FIN_WAIT2"),
    _T("CLOSE_WAIT"),
    _T("CLOSING"),
    _T("LAST_ACK"),
    _T("TIME_WAIT"),
    _T("DELETE_TCB")
};


/*
 * format message string and display output
 */
DWORD DoFormatMessage(DWORD ErrorCode)
{
    LPVOID lpMsgBuf;
    DWORD RetVal;

    if ((RetVal = FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            ErrorCode,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
            (LPTSTR) &lpMsgBuf,
            0,
            NULL )))
    {
        _tprintf(_T("%s"), (LPTSTR)lpMsgBuf);

        LocalFree(lpMsgBuf);
        /* return number of TCHAR's stored in output buffer
         * excluding '\0' - as FormatMessage does*/
        return RetVal;
    }
    else
        return 0;
}


/*
 *
 * Parse command line parameters and set any options
 *
 */
BOOL ParseCmdline(int argc, char* argv[])
{
    INT i;

    TCHAR Proto[5];

    if ((argc == 1) || (_istdigit(*argv[1])))
        bNoOptions = TRUE;

    /* Parse command line for options we have been given. */
    for (i = 1; i < argc; i++)
    {
        if ( (argc > 1)&&(argv[i][0] == '-') )
        {
            TCHAR c;

            while ((c = *++argv[i]) != '\0')
            {
                switch (tolower(c))
                {
                    case 'a' :
                        bDoShowAllCons = TRUE;
                        break;
                    case 'b' :
                        bDoShowProcName = TRUE;
                        break;
                    case 'e' :
                        bDoShowEthStats = TRUE;
                        break;
                    case 'n' :
                        bDoShowNumbers = TRUE;
                        break;
                    case 's' :
                        bDoShowProtoStats = TRUE;
                        break;
                    case 'p' :
                        bDoShowProtoCons = TRUE;

                        strncpy(Proto, (++argv)[i], sizeof(Proto));
                        if (!_tcsicmp( "IP", Proto ))
                            Protocol = IP;
                        else if (!_tcsicmp( "ICMP", Proto ))
                            Protocol = ICMP;
                        else if (!_tcsicmp( "TCP", Proto ))
                            Protocol = TCP;
                        else if (!_tcsicmp( "UDP", Proto ))
                            Protocol = UDP;
                        else
                        {
                            Usage();
                            return EXIT_FAILURE;
                        }
                        --i; /* move pointer back down to previous argv */
                        break;
                    case 'r' :
                        bDoShowRouteTable = TRUE;
                        break;
                    case 'v' :
                        _tprintf(_T("got v\n"));
                        bDoDispSeqComp = TRUE;
                        break;
                    default :
                        Usage();
                        return EXIT_FAILURE;
                }
            }
        }
        else if (_istdigit(*argv[i]))
        {
            if (_stscanf(argv[i], "%lu", &Interval) != EOF)
                bLoopOutput = TRUE;
            else
                return EXIT_FAILURE;
        }
//        else
//        {
//            Usage();
//            EXIT_FAILURE;
//        }
    }

    return EXIT_SUCCESS;
}


/*
 * Simulate Microsofts netstat utility output
 */
BOOL DisplayOutput()
{
    if (bNoOptions)
    {
        _tprintf(_T("\n  Proto  Local Address          Foreign Address        State\n"));
        ShowTcpTable();
        return EXIT_SUCCESS;
    }

    if (bDoShowRouteTable)
    {
        /* mingw doesn't have lib for _tsystem */
        if (system("route print") == -1)
        {
            _tprintf(_T("cannot find 'route.exe'\n"));
            return EXIT_FAILURE;
        }
        return EXIT_SUCCESS;
    }

    if (bDoShowEthStats)
    {
        ShowEthernetStatistics();
        return EXIT_SUCCESS;
    }

    if (bDoShowProtoCons)
    {
        switch (Protocol)
        {
                case IP :
                    if (bDoShowProtoStats)
                    {
                        ShowIpStatistics();
                        return EXIT_SUCCESS;
                    }
                    break;
                case ICMP :
                    if (bDoShowProtoStats)
                    {
                        ShowIcmpStatistics();
                        return EXIT_SUCCESS;
                    }
                    break;
                case TCP :
                    if (bDoShowProtoStats)
                        ShowTcpStatistics();
                    _tprintf(_T("\nActive Connections\n"));
                    _tprintf(_T("\n  Proto  Local Address          Foreign Address        State\n"));
                    ShowTcpTable();
                    break;
                case UDP :
                    if (bDoShowProtoStats)
                        ShowUdpStatistics();
                    _tprintf(_T("\nActive Connections\n"));
                    _tprintf(_T("\n  Proto  Local Address          Foreign Address        State\n"));
                    ShowUdpTable();
                    break;
                default :
                    break;
        }
    }
    else if (bDoShowProtoStats)
    {
        ShowIpStatistics();
        ShowIcmpStatistics();
        ShowTcpStatistics();
        ShowUdpStatistics();
        return EXIT_SUCCESS;
    }
    else //if (bDoShowAllCons)
    {
        _tprintf(_T("\nActive Connections\n"));
        _tprintf(_T("\n  Proto  Local Address          Foreign Address        State\n"));
        ShowTcpTable();
        ShowUdpTable();
    }
    return EXIT_SUCCESS;
}




VOID ShowIpStatistics()
{
    PMIB_IPSTATS pIpStats;
    DWORD dwRetVal;

    pIpStats = (MIB_IPSTATS*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_IPSTATS));

    if ((dwRetVal = GetIpStatistics(pIpStats)) == NO_ERROR)
    {
        _tprintf(_T("\nIPv4 Statistics\n\n"));
        _tprintf(_T("  %-34s = %lu\n"), _T("Packets Recieved"), pIpStats->dwInReceives);
        _tprintf(_T("  %-34s = %lu\n"), _T("Received Header Errors"), pIpStats->dwInHdrErrors);
        _tprintf(_T("  %-34s = %lu\n"), _T("Received Address Errors"), pIpStats->dwInAddrErrors);
        _tprintf(_T("  %-34s = %lu\n"), _T("Datagrams Forwarded"), pIpStats->dwForwDatagrams);
        _tprintf(_T("  %-34s = %lu\n"), _T("Unknown Protocols Recieved"), pIpStats->dwInUnknownProtos);
        _tprintf(_T("  %-34s = %lu\n"), _T("Received Packets Discarded"), pIpStats->dwInDiscards);
        _tprintf(_T("  %-34s = %lu\n"), _T("Recieved Packets Delivered"), pIpStats->dwInDelivers);
        _tprintf(_T("  %-34s = %lu\n"), _T("Output Requests"), pIpStats->dwOutRequests);
        _tprintf(_T("  %-34s = %lu\n"), _T("Routing Discards"), pIpStats->dwRoutingDiscards);
        _tprintf(_T("  %-34s = %lu\n"), _T("Discarded Output Packets"), pIpStats->dwOutDiscards);
        _tprintf(_T("  %-34s = %lu\n"), _T("Output Packets No Route"), pIpStats->dwOutNoRoutes);
        _tprintf(_T("  %-34s = %lu\n"), _T("Reassembly Required"), pIpStats->dwReasmReqds);
        _tprintf(_T("  %-34s = %lu\n"), _T("Reassembly Succesful"), pIpStats->dwReasmOks);
        _tprintf(_T("  %-34s = %lu\n"), _T("Reassembly Failures"), pIpStats->dwReasmFails);
       // _tprintf(_T("  %-34s = %lu\n"), _T("Datagrams succesfully fragmented"), NULL); /* FIXME: what is this one? */
        _tprintf(_T("  %-34s = %lu\n"), _T("Datagrams Failing Fragmentation"), pIpStats->dwFragFails);
        _tprintf(_T("  %-34s = %lu\n"), _T("Fragments Created"), pIpStats->dwFragCreates);
    }
    else
        DoFormatMessage(dwRetVal);

    HeapFree(GetProcessHeap(), 0, pIpStats);
}

VOID ShowIcmpStatistics()
{
    PMIB_ICMP pIcmpStats;
    DWORD dwRetVal;

    pIcmpStats = (MIB_ICMP*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_ICMP));

    if ((dwRetVal = GetIcmpStatistics(pIcmpStats)) == NO_ERROR)
    {
        _tprintf(_T("\nICMPv4 Statistics\n\n"));
        _tprintf(_T("                            Received    Sent\n"));
        _tprintf(_T("  %-25s %-11lu %lu\n"), _T("Messages"),
            pIcmpStats->stats.icmpInStats.dwMsgs, pIcmpStats->stats.icmpOutStats.dwMsgs);
        _tprintf(_T("  %-25s %-11lu %lu\n"), _T("Errors"),
            pIcmpStats->stats.icmpInStats.dwErrors, pIcmpStats->stats.icmpOutStats.dwErrors);
        _tprintf(_T("  %-25s %-11lu %lu\n"), _T("Destination Unreachable"),
            pIcmpStats->stats.icmpInStats.dwDestUnreachs, pIcmpStats->stats.icmpOutStats.dwDestUnreachs);
        _tprintf(_T("  %-25s %-11lu %lu\n"), _T("Time Exceeded"),
            pIcmpStats->stats.icmpInStats.dwTimeExcds, pIcmpStats->stats.icmpOutStats.dwTimeExcds);
        _tprintf(_T("  %-25s %-11lu %lu\n"), _T("Parameter Problems"),
            pIcmpStats->stats.icmpInStats.dwParmProbs, pIcmpStats->stats.icmpOutStats.dwParmProbs);
        _tprintf(_T("  %-25s %-11lu %lu\n"), _T("Source Quenches"),
            pIcmpStats->stats.icmpInStats.dwSrcQuenchs, pIcmpStats->stats.icmpOutStats.dwSrcQuenchs);
        _tprintf(_T("  %-25s %-11lu %lu\n"), _T("Redirects"),
            pIcmpStats->stats.icmpInStats.dwRedirects, pIcmpStats->stats.icmpOutStats.dwRedirects);
        _tprintf(_T("  %-25s %-11lu %lu\n"), _T("Echos"),
            pIcmpStats->stats.icmpInStats.dwEchos, pIcmpStats->stats.icmpOutStats.dwEchos);
        _tprintf(_T("  %-25s %-11lu %lu\n"), _T("Echo Replies"),
            pIcmpStats->stats.icmpInStats.dwEchoReps, pIcmpStats->stats.icmpOutStats.dwEchoReps);
        _tprintf(_T("  %-25s %-11lu %lu\n"), _T("Timestamps"),
            pIcmpStats->stats.icmpInStats.dwTimestamps, pIcmpStats->stats.icmpOutStats.dwTimestamps);
        _tprintf(_T("  %-25s %-11lu %lu\n"), _T("Timestamp Replies"),
            pIcmpStats->stats.icmpInStats.dwTimestampReps, pIcmpStats->stats.icmpOutStats.dwTimestampReps);
        _tprintf(_T("  %-25s %-11lu %lu\n"), _T("Address Masks"),
            pIcmpStats->stats.icmpInStats.dwAddrMasks, pIcmpStats->stats.icmpOutStats.dwAddrMasks);
        _tprintf(_T("  %-25s %-11lu %lu\n"), _T("Address Mask Replies"),
            pIcmpStats->stats.icmpInStats.dwAddrMaskReps, pIcmpStats->stats.icmpOutStats.dwAddrMaskReps);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?