netstat.c

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

C
643
字号
    }
    else
        DoFormatMessage(dwRetVal);

    HeapFree(GetProcessHeap(), 0, pIcmpStats);

}

VOID ShowTcpStatistics()
{
    PMIB_TCPSTATS pTcpStats;
    DWORD dwRetVal;

    pTcpStats = (MIB_TCPSTATS*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_TCPSTATS));

    if ((dwRetVal = GetTcpStatistics(pTcpStats)) == NO_ERROR)
    {
        _tprintf(_T("\nTCP Statistics for IPv4\n\n"));
        _tprintf(_T("  %-35s = %lu\n"), _T("Active Opens"), pTcpStats->dwActiveOpens);
        _tprintf(_T("  %-35s = %lu\n"), _T("Passive Opens"), pTcpStats->dwPassiveOpens);
        _tprintf(_T("  %-35s = %lu\n"), _T("Failed Connection Attempts"), pTcpStats->dwAttemptFails);
        _tprintf(_T("  %-35s = %lu\n"), _T("Reset Connections"), pTcpStats->dwEstabResets);
        _tprintf(_T("  %-35s = %lu\n"), _T("Current Connections"), pTcpStats->dwCurrEstab);
        _tprintf(_T("  %-35s = %lu\n"), _T("Segments Recieved"), pTcpStats->dwInSegs);
        _tprintf(_T("  %-35s = %lu\n"), _T("Segments Sent"), pTcpStats->dwOutSegs);
        _tprintf(_T("  %-35s = %lu\n"), _T("Segments Retransmitted"), pTcpStats->dwRetransSegs);
    }
    else
        DoFormatMessage(dwRetVal);

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

VOID ShowUdpStatistics()
{
    PMIB_UDPSTATS pUdpStats;
    DWORD dwRetVal;

    pUdpStats = (MIB_UDPSTATS*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_UDPSTATS));

    if ((dwRetVal = GetUdpStatistics(pUdpStats)) == NO_ERROR)
    {
        _tprintf(_T("\nUDP Statistics for IPv4\n\n"));
        _tprintf(_T("  %-21s = %lu\n"), _T("Datagrams Recieved"), pUdpStats->dwInDatagrams);
        _tprintf(_T("  %-21s = %lu\n"), _T("No Ports"), pUdpStats->dwNoPorts);
        _tprintf(_T("  %-21s = %lu\n"), _T("Recieve Errors"), pUdpStats->dwInErrors);
        _tprintf(_T("  %-21s = %lu\n"), _T("Datagrams Sent"), pUdpStats->dwOutDatagrams);
    }
    else
        DoFormatMessage(dwRetVal);

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

VOID ShowEthernetStatistics()
{
    PMIB_IFTABLE pIfTable;
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;

    pIfTable = (MIB_IFTABLE*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_IFTABLE));

    if (GetIfTable(pIfTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
    {
        HeapFree(GetProcessHeap(), 0, pIfTable);
        pIfTable = (MIB_IFTABLE*) HeapAlloc(GetProcessHeap(), 0, dwSize);

        if ((dwRetVal = GetIfTable(pIfTable, &dwSize, 0)) == NO_ERROR)
        {
            _tprintf(_T("Interface Statistics\n\n"));
            _tprintf(_T("                           Received            Sent\n\n"));
            _tprintf(_T("%-20s %14lu %15lu\n"), _T("Bytes"),
                pIfTable->table[0].dwInOctets, pIfTable->table[0].dwOutOctets);
            _tprintf(_T("%-20s %14lu %15lu\n"), _T("Unicast packets"),
                pIfTable->table[0].dwInUcastPkts, pIfTable->table[0].dwOutUcastPkts);
            _tprintf(_T("%-20s %14lu %15lu\n"), _T("Non-unicast packets"),
                pIfTable->table[0].dwInNUcastPkts, pIfTable->table[0].dwOutNUcastPkts);
            _tprintf(_T("%-20s %14lu %15lu\n"), _T("Discards"),
                pIfTable->table[0].dwInDiscards, pIfTable->table[0].dwOutDiscards);
            _tprintf(_T("%-20s %14lu %15lu\n"), _T("Errors"),
                pIfTable->table[0].dwInErrors, pIfTable->table[0].dwOutErrors);
            _tprintf(_T("%-20s %14lu\n"), _T("Unknown Protocols"),
                pIfTable->table[0].dwInUnknownProtos);
        }
        else
            DoFormatMessage(dwRetVal);
    }
    HeapFree(GetProcessHeap(), 0, pIfTable);
}

VOID ShowTcpTable()
{
    PMIB_TCPTABLE tcpTable;
    DWORD error, dwSize;
    DWORD i;
    CHAR HostIp[HOSTNAMELEN], HostPort[PORTNAMELEN];
    CHAR RemoteIp[HOSTNAMELEN], RemotePort[PORTNAMELEN];
    CHAR Host[ADDRESSLEN];
    CHAR Remote[ADDRESSLEN];

    /* Get the table of TCP endpoints */
    dwSize = 0;
    error = GetTcpTable(NULL, &dwSize, TRUE);
    if (error != ERROR_INSUFFICIENT_BUFFER)
    {
        printf("Failed to snapshot TCP endpoints.\n");
        DoFormatMessage(error);
        exit(EXIT_FAILURE);
    }
    tcpTable = (PMIB_TCPTABLE) HeapAlloc(GetProcessHeap(), 0, dwSize);
    error = GetTcpTable(tcpTable, &dwSize, TRUE );
    if (error)
    {
        printf("Failed to snapshot TCP endpoints table.\n");
        DoFormatMessage(error);
        HeapFree(GetProcessHeap(), 0, tcpTable);
        exit(EXIT_FAILURE);
    }

    /* Dump the TCP table */
    for (i = 0; i < tcpTable->dwNumEntries; i++)
    {
        /* If we aren't showing all connections, only display established, close wait
         * and time wait. This is the default output for netstat */
        if (bDoShowAllCons || (tcpTable->table[i].dwState ==  MIB_TCP_STATE_ESTAB)
            || (tcpTable->table[i].dwState ==  MIB_TCP_STATE_CLOSE_WAIT)
            || (tcpTable->table[i].dwState ==  MIB_TCP_STATE_TIME_WAIT))
        {
            /* I've split this up so it's easier to follow */
            GetIpHostName(TRUE, tcpTable->table[i].dwLocalAddr, HostIp, HOSTNAMELEN);
            GetPortName(tcpTable->table[i].dwLocalPort, "tcp", HostPort, PORTNAMELEN);
            GetIpHostName(FALSE, tcpTable->table[i].dwRemoteAddr, RemoteIp, HOSTNAMELEN);
            GetPortName(tcpTable->table[i].dwRemotePort, "tcp", RemotePort, PORTNAMELEN);

            sprintf(Host, "%s:%s", HostIp, HostPort);
            sprintf(Remote, "%s:%s", RemoteIp, RemotePort);

            _tprintf(_T("  %-6s %-22s %-22s %s\n"), _T("TCP"),
            Host, Remote, TcpState[tcpTable->table[i].dwState]);
        }
    }
    HeapFree(GetProcessHeap(), 0, tcpTable);
}


VOID ShowUdpTable()
{
    PMIB_UDPTABLE udpTable;
    DWORD error, dwSize;
    DWORD i;
    CHAR HostIp[HOSTNAMELEN], HostPort[PORTNAMELEN];
    CHAR Host[ADDRESSLEN];

    /* Get the table of UDP endpoints */
    dwSize = 0;
    error = GetUdpTable(NULL, &dwSize, TRUE);
    if (error != ERROR_INSUFFICIENT_BUFFER)
    {
        printf("Failed to snapshot UDP endpoints.\n");
        DoFormatMessage(error);
        exit(EXIT_FAILURE);
    }
    udpTable = (PMIB_UDPTABLE) HeapAlloc(GetProcessHeap(), 0, dwSize);
    error = GetUdpTable(udpTable, &dwSize, TRUE);
    if (error)
    {
        printf("Failed to snapshot UDP endpoints table.\n");
        DoFormatMessage(error);
        HeapFree(GetProcessHeap(), 0, udpTable);
        exit(EXIT_FAILURE);
    }

    /* Dump the UDP table */
    for (i = 0; i < udpTable->dwNumEntries; i++)
    {

        /* I've split this up so it's easier to follow */
        GetIpHostName(TRUE, udpTable->table[i].dwLocalAddr, HostIp, HOSTNAMELEN);
        GetPortName(udpTable->table[i].dwLocalPort, "tcp", HostPort, PORTNAMELEN);

        sprintf(Host, "%s:%s", HostIp, HostPort);

        _tprintf(_T("  %-6s %-22s %-22s\n"), _T("UDP"), Host,  _T("*:*"));
    }

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


/*
 * Translate port numbers into their text equivalent if there is one
 */
PCHAR
GetPortName(UINT Port, PCSTR Proto, CHAR Name[], INT NameLen)
{
    struct servent *pSrvent;

    if (bDoShowNumbers)
    {
        sprintf(Name, "%d", htons((WORD)Port));
        return Name;
    }
    /* Try to translate to a name */
    if ((pSrvent = getservbyport(Port, Proto)))
        strcpy(Name, pSrvent->s_name );
    else
        sprintf(Name, "%d", htons((WORD)Port));
    return Name;
}


/*
 * convert addresses into dotted decimal or hostname
 */
PCHAR
GetIpHostName(BOOL Local, UINT IpAddr, CHAR Name[], int NameLen)
{
//  struct hostent *phostent;
    UINT nIpAddr;

    /* display dotted decimal */
    nIpAddr = htonl(IpAddr);
    if (bDoShowNumbers) {
        sprintf(Name, "%d.%d.%d.%d",
            (nIpAddr >> 24) & 0xFF,
            (nIpAddr >> 16) & 0xFF,
            (nIpAddr >> 8) & 0xFF,
            (nIpAddr) & 0xFF);
        return Name;
    }

    Name[0] = _T('\0');

    /* try to resolve the name */
    if (!IpAddr) {
        if (!Local) {
            sprintf(Name, "%d.%d.%d.%d",
                (nIpAddr >> 24) & 0xFF,
                (nIpAddr >> 16) & 0xFF,
                (nIpAddr >> 8) & 0xFF,
                (nIpAddr) & 0xFF);
        } else {
            if (gethostname(Name, NameLen) != 0)
                DoFormatMessage(WSAGetLastError());
        }
    } else if (IpAddr == 0x0100007f) {
        if (Local) {
            if (gethostname(Name, NameLen) != 0)
                DoFormatMessage(WSAGetLastError());
        } else {
            _tcsncpy(Name, _T("localhost"), 10);
        }
//  } else if (phostent = gethostbyaddr((char*)&ipaddr, sizeof(nipaddr), PF_INET)) {
//      strcpy(name, phostent->h_name);
    } else {
        sprintf(Name, "%d.%d.%d.%d",
            ((nIpAddr >> 24) & 0x000000FF),
            ((nIpAddr >> 16) & 0x000000FF),
            ((nIpAddr >> 8) & 0x000000FF),
            ((nIpAddr) & 0x000000FF));
    }
    return Name;
}

VOID Usage()
{
    _tprintf(_T("\nDisplays current TCP/IP protocol statistics and network connections.\n\n"
    "NETSTAT [-a] [-e] [-n] [-s] [-p proto] [-r] [interval]\n\n"
    "  -a            Displays all connections and listening ports.\n"
    "  -e            Displays Ethernet statistics. May be combined with -s\n"
    "                option\n"
    "  -n            Displays address and port numbers in numeric form.\n"
    "  -p proto      Shows connections for protocol 'proto' TCP or UDP.\n"
    "                If used with the -s option to display\n"
    "                per-protocol statistics, 'proto' may be TCP, UDP, or IP.\n"
    "  -r            Displays the current routing table.\n"
    "  -s            Displays per-protocol statistics. By default, Statistics are\n"
    "                shown for IP, ICMP, TCP and UDP;\n"
    "                the -p option may be used to specify a subset of the default.\n"
    "  interval      Redisplays selected statistics every 'interval' seconds.\n"
    "                Press CTRL+C to stop redisplaying. By default netstat will\n"
    "                print the current information only once.\n"));
}



/*
 *
 * Parse command line parameters and set any options
 * Run display output, looping over set intervals if a number is given
 *
 */
int main(int argc, char *argv[])
{
    WSADATA wsaData;

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        _tprintf(_T("WSAStartup() failed : %d\n"), WSAGetLastError());
        return -1;
    }

    if (ParseCmdline(argc, argv))
        return -1;

    if (bLoopOutput)
    {
        while (1)
        {
            if (DisplayOutput())
                return -1;
            Sleep(Interval*1000);
        }
    }

    if (DisplayOutput())
        return -1;
    else
        return 0;
}

⌨️ 快捷键说明

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