//---------------------------------------------------------------------
// This file is part of the Microsoft .NET Framework SDK Code Samples.
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//This source code is intended only as a supplement to Microsoft
//Development Tools and/or on-line documentation. See these other
//materials for detailed information regarding Microsoft code samples.
//
//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//PARTICULAR PURPOSE.
//---------------------------------------------------------------------
namespace Microsoft.Samples.NetStatTool
{
using System;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Globalization;
[Flags]
public enum ProtocolTypes
{
None = 0x0000,
Tcp = 0x0001,
Udp = 0x0002,
TcpV6 = 0x0004,
UdpV6 = 0x0008,
IP = 0x0010,
IPv6 = 0x0020,
Icmp = 0x0040,
IcmpV6 = 0x0080
}
static class NetStatTool
{
private static bool showNumeric;
private static bool showListening;
private static bool showProtocolStatistics;
private static bool showInterfaceStatistics;
private static int interval = -1;
private static ProtocolTypes selectedProtocols = ProtocolTypes.None;
private const string connectionFormatString =
"\t{0,-12}{1, -16}{2, -28}{3}";
private const string equalsFormatString =
"\t{0, -32} = {1}";
private const string sendReceiveFormatString =
"\t{0, -32}{1, -16}{2}";
private const string errorFormatString =
"\tStatistics not available for {0}: {1}";
static void Main(string[] args)
{
if (ParseArguments(args))
{
while (true)
{
if (showInterfaceStatistics)
DisplayInterfaceStatistics();
if (showProtocolStatistics)
DisplayProtocolStatistics();
if (!showInterfaceStatistics && !showProtocolStatistics)
DisplayConnections();
if (interval <= 0)
break;
else
System.Threading.Thread.Sleep(interval * 1000);
}
}
else
{
Usage();
System.Environment.Exit(0);
}
}
// Helper function display the all possible command line options and
// their purpose for this tool.
private static void Usage()
{
Console.WriteLine();
Console.WriteLine("NETSTATTOOL [-?] [-a] [-e] [-n] [-s] [-p protocol] [interval]");
Console.WriteLine();
Console.WriteLine("(default) Displays open connection information.");
Console.WriteLine("-? Displays this help message.");
Console.WriteLine("-e Displays NIC statistics. May be combined with -s.");
Console.WriteLine("-s Displays per-protocol statistics. By default, statistics are");
Console.WriteLine(" shown for TCP. The -p and -a options may be used to specify");
Console.WriteLine(" other protocols to display.");
Console.WriteLine("-p protocol Display information for the protocol specified.");
Console.WriteLine(" May be any of: IP, IPv6, ICMP, ICMPv6, TCP, TCPv6, UDP,");
Console.WriteLine(" or UDPv6TCP. Connections can only be shown for TCP,");
Console.WriteLine(" UDP, TCPv6, or UDPv6.");
Console.WriteLine("-a Display information for all protocals.");
Console.WriteLine("-n Displays addresses and port numbers in numerical form.");
Console.WriteLine("interval Redisplays selected statistics, pausing interval seconds");
Console.WriteLine(" between each display. Press CTRL+C to stop.");
}
// Parse the command line arguments and set appropriate properties as
// per requested user options.
private static bool ParseArguments(string[] args)
{
for (int i = 0; i < args.Length; i++)
{
string arg = args[i].ToLower(CultureInfo.CurrentCulture);
if (arg.Length < 2 || (arg[0] != '/' && arg[0] != '-'))
{
try
{
interval =
Convert.ToInt32(arg, NumberFormatInfo.CurrentInfo);
}
catch (FormatException)
{
return false;
}
catch (OverflowException)
{
return false;
}
}
else
{
switch (arg[1])
{
// Just display the help message
case '?':
return false;
case 'n':
showNumeric = true;
break;
case 'e':
showInterfaceStatistics = true;
break;
case 'a':
selectedProtocols =
ProtocolTypes.Tcp | ProtocolTypes.Udp |
ProtocolTypes.IP | ProtocolTypes.Icmp |
ProtocolTypes.TcpV6 | ProtocolTypes.UdpV6 |
ProtocolTypes.IPv6 | ProtocolTypes.IcmpV6;
showListening = true;
break;
case 's':
showProtocolStatistics = true;
break;
case 'p':
if (args.Length < i + 1)
{
return false; // invalid parameters
}
else
{
i++;
AddSelectedProtocol(
args[i].ToLower(
CultureInfo.CurrentCulture));
}
break;
default:
return false;
}
}
}
if (selectedProtocols == ProtocolTypes.None)
{
// User wants Tcp as default.
selectedProtocols = selectedProtocols | ProtocolTypes.Tcp;
}
return true;
}
// Get the display string for localIPEndPoint, either numric or full
// name format.
private static String GetLocalAddressAsString(IPEndPoint ipe)
{
string displayString = ipe.ToString();
if (!showNumeric)
{
displayString =
Dns.GetHostName() + ":" + GetPortNameMapping(ipe.Port);
}
return displayString;
}
// Get the display string for Remote IPEndPoint, either numric or full
// name format.
private static String GetRemoteAddressAsString(IPEndPoint ipe)
{
string displayString = ipe.ToString();
if (!showNumeric)
{
try
{
displayString =
Dns.GetHostEntry(ipe.Address).HostName + ":" +
GetPortNameMapping(ipe.Port);
}
catch (SocketException)
{
}
}
return displayString;
}
private static void AddSelectedProtocol(string protocol)
{
switch (protocol)
{
case "tcp":
selectedProtocols = selectedProtocols | ProtocolTypes.Tcp;
break;
case "udp":
selectedProtocols = selectedProtocols | ProtocolTypes.Udp;
break;
case "ip":
selectedProtocols = selectedProtocols | ProtocolTypes.IP;
break;
case "icmp":
selectedProtocols = selectedProtocols | ProtocolTypes.Icmp;
break;
case "tcpv6":
selectedProtocols =
selectedProtocols | ProtocolTypes.TcpV6;
break;
case "udpv6":
selectedProtocols =
selectedProtocols | ProtocolTypes.UdpV6;
break;
case "ipv6":
selectedProtocols = selectedProtocols | ProtocolTypes.IPv6;
break;
case "icmpv6":
selectedProtocols =
selectedProtocols | ProtocolTypes.IcmpV6;
break;
}
}
// Return the displaystring for known protocol ports
private static string GetPortNameMapping(int Port)
{
string Portname = Port.ToString(NumberFormatInfo.CurrentInfo);
switch (Port)
{
case 21:
Portname = "ftp";
break;
case 25:
Portname = "smtp";
break;
case 80:
Portname = "http";
break;
case 135:
Portname = "epmap";
break;
case 137:
Portname = "netbios-ns";
break;
case 138:
Portname = "netbios-dgm";
break;
case 139:
Portname = "netbios-ssn";
break;
case 443:
Portname = "ssl";
break;
case 445:
Portname = "microsoft-ds";
break;
case 500:
Portname = "isakmp";
break;
}
return Portname;
}
private static string GetProtocolString(ProtocolTypes type)
{
switch (type)
{
case ProtocolTypes.Icmp: return "ICMP";
case ProtocolTypes.IcmpV6: return "ICMP V6";
case ProtocolTypes.IP: return "IP";
case ProtocolTypes.IPv6: return "IP V6";
case ProtocolTypes.Tcp: return "TCP";
case ProtocolTypes.TcpV6: return "TCP V6";
case ProtocolTypes.Udp: return "UDP";
case ProtocolTypes.UdpV6: return "UDP V6";
default: return "Unknown";
}
}
// Display the list of connections on console.
private static void DisplayConnections()
{
IPGlobalProperties ipGlobal =
IPGlobalProperties.GetIPGlobalProperties();
Console.WriteLine();
Console.WriteLine("Connections");
Console.WriteLine(
connectionFormatString, "Protocol", "State", "Local", "Remote");
if ((selectedProtocols & ProtocolTypes.Tcp) == ProtocolTypes.Tcp)
{
TcpConnectionInformation[] tcpInfoList =
ipGlobal.GetActiveTcpConnections();
foreach (TcpConnectionInformation tcpInfo in tcpInfoList)
{
if (tcpInfo.State == TcpState.Listen && !showListening)
{
// Skip listening port unless user requested all.
continue;
}
else
{
Console.WriteLine(
connectionFormatString,
"TCP",
tcpInfo.State,
GetLocalAddressAsString(tcpInfo.LocalEndPoint),
GetRemoteAddressAsString(tcpInfo.RemoteEndPoint));
}
}
}
if ((selectedProtocols & ProtocolTypes.Udp) == ProtocolTypes.Udp)
{
IPEndPoint[] udpInfoList = ipGlobal.GetActiveUdpListeners();
foreach (IPEndPoint udpInfo in udpInfoList)
{
Console.WriteLine(
connectionFormatString,
"UDP",
"(None)",
GetLocalAddressAsString(udpInfo),
"*:*");
}
}
}
// Display the interface statisitics of all interfaces on console.
private static void DisplayInterfaceStatistics()
{
NetworkInterface[] networkInterfaceList =
NetworkInterface.GetAllNetworkInterfaces();
Console.WriteLine();
Console.WriteLine("Interface Statistics");
foreach (NetworkInterface nic in networkInterfaceList)
{
IPv4InterfaceStatistics interfaceStatistics =
nic.GetIPv4Statistics();
Console.WriteLine(
sendReceiveFormatString, nic.Name, "Received", "Sent");
Console.WriteLine(
sendReceiveFormatString,
"Bytes",
interfaceStatistics.BytesReceived,
interfaceStatistics.BytesSent);
Console.WriteLine(
sendReceiveFormatString,
"Unicast packets",
interfaceStatistics.UnicastPacketsReceived,
interfaceStatistics.UnicastPacketsSent);
Console.WriteLine(
sendReceiveFormatString,
"Non-unicast packets",
interfaceStatistics.NonUnicastPacketsReceived,
interfaceStatistics.NonUnicastPacketsSent);
Console.WriteLine(
sendReceiveFormatString,
"Discards",
interfaceStatistics.IncomingPacketsDiscarded,
interfaceStatistics.OutgoingPacketsDiscarded);
Console.WriteLine(
sendReceiveFormatString,
"Errors",
interfaceStatistics.IncomingPacketsWithErrors,
interfaceStatistics.OutgoingPacketsWithErrors);
Console.WriteLine(
sendReceiveFormatString,
"Unknown protocols",
interfaceStatistics.IncomingUnknownProtocolPackets,
"");
Console.WriteLine();
}
}
// Display the protocol statisitics of requested protocols.
private static void DisplayProtocolStatistics()
{
IPGlobalProperties ipGlobal =
IPGlobalProperties.GetIPGlobalProperties();
if ((selectedProtocols & ProtocolTypes.IP) ==
ProtocolTypes.IP)
DisplayIPv4Statistics(ipGlobal);
if ((selectedProtocols & ProtocolTypes.Tcp) ==
ProtocolTypes.Tcp)
DisplayTcpV4Statistics(ipGlobal);
if ((selectedProtocols & ProtocolTypes.Udp) ==
ProtocolTypes.Udp)
DisplayUdpV4Statistics(ipGlobal);
if ((selectedProtocols & ProtocolTypes.Icmp) ==
ProtocolTypes.Icmp)
DisplayIcmpV4Statistics(ipGlobal);
if ((selectedProtocols & ProtocolTypes.UdpV6) ==
ProtocolTypes.UdpV6)
DisplayUdpV6Statistics(ipGlobal);
if ((selectedProtocols & ProtocolTypes.TcpV6) ==
ProtocolTypes.TcpV6)
DisplayTcpV6Statistics(ipGlobal);
if ((selectedProtocols & ProtocolTypes.IPv6) ==
ProtocolTypes.IPv6)
DisplayIPv6Statistics(ipGlobal);
if ((selectedProtocols & ProtocolTypes.IcmpV6) ==
ProtocolTypes.IcmpV6)
DisplayIcmpV6Statistics(ipGlobal);
}
// Display the data for given IcmpV4Statistics object.
private static void DisplayIcmpV4Statistics(
IPGlobalProperties ipGlobal)
{
string protocol = GetProtocolString(ProtocolTypes.Icmp);
Console.WriteLine();
Console.WriteLine("{0} Statistics", protocol);
try
{
IcmpV4Statistics icmpStat = ipGlobal.GetIcmpV4Statistics();
Console.WriteLine(sendReceiveFormatString, "", "Received", "Sent");
Console.WriteLine(
sendReceiveFormatString,
"Messages",
icmpStat.MessagesReceived,
icmpStat.MessagesSent);
Console.WriteLine(
sendReceiveFormatString,
"Errors",
icmpStat.ErrorsReceived,
icmpStat.ErrorsSent);
Console.WriteLine(
sendReceiveFormatString,
"Destination Unreachable",
icmpStat.DestinationUnreachableMessagesReceived,
icmpStat.DestinationUnreachableMessagesSent);
Console.WriteLine(
sendReceiveFormatString,
"Time Exceeded",
icmpStat.TimeExceededMessagesReceived,
icmpStat.TimeExceededMessagesSent);
Console.WriteLine(
sendReceiveFormatString,
"Parameter Problems",
icmpStat.ParameterProblemsReceived,
icmpStat.ParameterProblemsSent);
Console.WriteLine(
sendReceiveFormatString,
"Source Quenches",
icmpStat.SourceQuenchesReceived,
icmpStat.SourceQuenchesSent);
Console.WriteLine(
sendReceiveFormatString,
"Redirects",
icmpStat.RedirectsReceived,
icmpStat.RedirectsSent);
Console.WriteLine(
sendReceiveFormatString,
"Echos",
icmpStat.EchoRequestsReceived,
icmpStat.EchoRequestsSent);
Console.WriteLine(
sendReceiveFormatString,
"Echo Replies",
icmpStat.EchoRepliesReceived,
icmpStat.EchoRepliesSent);
Console.WriteLine(
sendReceiveFormatString,
"Timestamps",
icmpStat.TimestampRequestsReceived,
icmpStat.TimestampRequestsSent);
Console.WriteLine(
sendReceiveFormatString,
"Timestamp Replies",
icmpStat.TimestampRepliesReceived,
icmpStat.TimestampRepliesSent);
Console.WriteLine(
sendReceiveFormatString,
"Address Masks",
icmpStat.AddressMaskRequestsReceived,
icmpStat.AddressMaskRequestsSent);
Console.WriteLine(
sendReceiveFormatString,
"Address Mask Replies",
icmpStat.AddressMaskRepliesReceived,
icmpStat.AddressMaskRepliesSent);
}
catch (NetworkInformationException ex)
{
Console.WriteLine(errorFormatString, protocol, ex.Message);
}
}
// Display the data for given IcmpV6Statistics object.
private static void DisplayIcmpV6Statistics(
IPGlobalProperties ipGlobal)
{
string protocol = GetProtocolString(ProtocolTypes.IcmpV6);
Console.WriteLine();
Console.WriteLine("{0} Statistics", protocol);
try
{
IcmpV6Statistics icmpStat = ipGlobal.GetIcmpV6Statistics();
Console.WriteLine(sendReceiveFormatString, "", "Received", "Sent");
Console.WriteLine(
sendReceiveFormatString,
"Messages",
icmpStat.MessagesReceived,
icmpStat.MessagesSent);
Console.WriteLine(
sendReceiveFormatString,
"Errors",
icmpStat.ErrorsReceived,
icmpStat.ErrorsSent);
Console.WriteLine(
sendReceiveFormatString,
"Destination Unreachable",
icmpStat.DestinationUnreachableMessagesReceived,
icmpStat.DestinationUnreachableMessagesSent);
Console.WriteLine(
sendReceiveFormatString,
"Time Exceeded",
icmpStat.TimeExceededMessagesReceived,
icmpStat.TimeExceededMessagesSent);
Console.WriteLine(
sendReceiveFormatString,
"Parameter Problems",
icmpStat.ParameterProblemsReceived,
icmpStat.ParameterProblemsSent);
Console.WriteLine(
sendReceiveFormatString,
"Redirects",
icmpStat.RedirectsReceived,
icmpStat.RedirectsSent);
Console.WriteLine(
sendReceiveFormatString,
"Echos",
icmpStat.EchoRepliesReceived,
icmpStat.EchoRepliesSent);
Console.WriteLine(
sendReceiveFormatString,
"Echo Replies",
icmpStat.EchoRepliesReceived,
icmpStat.EchoRepliesSent);
Console.WriteLine(
sendReceiveFormatString,
"Membership Queries",
icmpStat.MembershipQueriesReceived,
icmpStat.MembershipQueriesSent);
Console.WriteLine(
sendReceiveFormatString,
"Membership Reductios",
icmpStat.MembershipReductionsReceived,
icmpStat.MembershipReductionsSent);
Console.WriteLine(
sendReceiveFormatString,
"Membership Reports",
icmpStat.MembershipReportsReceived,
icmpStat.MembershipReportsSent);
Console.WriteLine(
sendReceiveFormatString,
"Neighbour Advertisements",
icmpStat.NeighborAdvertisementsReceived,
icmpStat.NeighborAdvertisementsSent);
Console.WriteLine(
sendReceiveFormatString,
"Neighbour Solicit",
icmpStat.NeighborSolicitsReceived,
icmpStat.NeighborSolicitsSent);
Console.WriteLine(
sendReceiveFormatString,
"Packets Too Large",
icmpStat.PacketTooBigMessagesReceived,
icmpStat.PacketTooBigMessagesSent);
Console.WriteLine(
sendReceiveFormatString,
"Redirects",
icmpStat.RedirectsReceived,
icmpStat.RedirectsSent);
Console.WriteLine(
sendReceiveFormatString,
"Router Advertisements",
icmpStat.RouterAdvertisementsReceived,
icmpStat.RouterAdvertisementsSent);
Console.WriteLine(
sendReceiveFormatString,
"Router Solicits",
icmpStat.RouterSolicitsReceived,
icmpStat.RouterSolicitsSent);
}
catch (NetworkInformationException ex)
{
Console.WriteLine(errorFormatString, protocol, ex.Message);
}
}
private static void DisplayUdpV4Statistics(IPGlobalProperties ipGlobal)
{
string protocol = GetProtocolString(ProtocolTypes.Udp);
Console.WriteLine();
Console.WriteLine("{0} Statistics", protocol);
try
{
DisplayUdpStatistics(ipGlobal.GetUdpIPv4Statistics());
}
catch (NetworkInformationException ex)
{
Console.WriteLine(errorFormatString, protocol, ex.Message);
}
}
private static void DisplayUdpV6Statistics(IPGlobalProperties ipGlobal)
{
string protocol = GetProtocolString(ProtocolTypes.UdpV6);
Console.WriteLine();
Console.WriteLine("{0} Statistics", protocol);
try
{
DisplayUdpStatistics(ipGlobal.GetUdpIPv6Statistics());
}
catch (NetworkInformationException ex)
{
Console.WriteLine(errorFormatString, protocol, ex.Message);
}
}
// Display the data for given UdpStatistics object.
private static void DisplayUdpStatistics(UdpStatistics udpStat)
{
Console.WriteLine(
equalsFormatString,
"Datagrams Received",
udpStat.DatagramsReceived);
Console.WriteLine(
equalsFormatString,
"No Ports",
udpStat.IncomingDatagramsDiscarded);
Console.WriteLine(
equalsFormatString,
"Receive Errors",
udpStat.IncomingDatagramsWithErrors);
Console.WriteLine(
equalsFormatString, "Datagrams Sent", udpStat.DatagramsSent);
}
private static void DisplayTcpV4Statistics(IPGlobalProperties ipGlobal)
{
string protocol = GetProtocolString(ProtocolTypes.Tcp);
Console.WriteLine();
Console.WriteLine("{0} Statistics", protocol);
try
{
DisplayTcpStatistics(ipGlobal.GetTcpIPv4Statistics());
}
catch (NetworkInformationException ex)
{
Console.WriteLine(errorFormatString, protocol, ex.Message);
}
}
private static void DisplayTcpV6Statistics(IPGlobalProperties ipGlobal)
{
string protocol = GetProtocolString(ProtocolTypes.TcpV6);
Console.WriteLine();
Console.WriteLine("{0} Statistics", protocol);
try
{
DisplayTcpStatistics(ipGlobal.GetTcpIPv6Statistics());
}
catch (NetworkInformationException ex)
{
Console.WriteLine(errorFormatString, protocol, ex.Message);
}
}
// Display the data for given TcpStatistics object.
private static void DisplayTcpStatistics(TcpStatistics tcpStat)
{
Console.WriteLine(
equalsFormatString,
"Active Opens",
tcpStat.ConnectionsInitiated);
Console.WriteLine(
equalsFormatString,
"Passive Opens",
tcpStat.ConnectionsAccepted);
Console.WriteLine(
equalsFormatString,
"Failed Connection Attempts",
tcpStat.FailedConnectionAttempts);
Console.WriteLine(
equalsFormatString,
"Reset Connections",
tcpStat.ResetConnections);
Console.WriteLine(
equalsFormatString,
"Current Connections",
tcpStat.CurrentConnections);
Console.WriteLine(
equalsFormatString,
"Segments Received",
tcpStat.SegmentsReceived);
Console.WriteLine(
equalsFormatString,
"Segments Sent",
tcpStat.SegmentsSent);
Console.WriteLine(
equalsFormatString,
"Segments Retransmitted",
tcpStat.SegmentsResent);
}
private static void DisplayIPv4Statistics(IPGlobalProperties ipGlobal)
{
string protocol = GetProtocolString(ProtocolTypes.IP);
Console.WriteLine();
Console.WriteLine("{0} Statistics", protocol);
try
{
DisplayIPStatistics(ipGlobal.GetIPv4GlobalStatistics());
}
catch (NetworkInformationException ex)
{
Console.WriteLine(errorFormatString, protocol, ex.Message);
}
}
private static void DisplayIPv6Statistics(IPGlobalProperties ipGlobal)
{
string protocol = GetProtocolString(ProtocolTypes.IPv6);
Console.WriteLine();
Console.WriteLine("{0} Statistics", protocol);
try
{
DisplayIPStatistics(ipGlobal.GetIPv6GlobalStatistics());
}
catch (NetworkInformationException ex)
{
Console.WriteLine(errorFormatString, protocol, ex.Message);
}
}
// Display the global IP statisitcs for given IPGlobalStatistics
// object.
private static void DisplayIPStatistics(IPGlobalStatistics ipStat)
{
Console.WriteLine(
equalsFormatString,
"Packets Received",
ipStat.ReceivedPackets);
Console.WriteLine(
equalsFormatString,
"Received Header Errors",
ipStat.ReceivedPacketsWithHeadersErrors);
Console.WriteLine(
equalsFormatString,
"Received Address Errors",
ipStat.ReceivedPacketsWithAddressErrors);
Console.WriteLine(
equalsFormatString,
"Datagrams Forwarded",
ipStat.ReceivedPacketsForwarded);
Console.WriteLine(
equalsFormatString,
"Unknown Protocols Received",
ipStat.ReceivedPacketsWithUnknownProtocol);
Console.WriteLine(
equalsFormatString,
"Received Packets Discarded",
ipStat.ReceivedPacketsDiscarded);
Console.WriteLine(
equalsFormatString,
"Received Packets Delivered",
ipStat.ReceivedPacketsDelivered);
Console.WriteLine(
equalsFormatString,
"Output Requests",
ipStat.OutputPacketRequests);
Console.WriteLine(
equalsFormatString,
"Routing Discards",
ipStat.OutputPacketRoutingDiscards);
Console.WriteLine(
equalsFormatString,
"Discarded Output Packets",
ipStat.OutputPacketsDiscarded);
Console.WriteLine(
equalsFormatString,
"Output Packet No Route",
ipStat.OutputPacketsWithNoRoute);
Console.WriteLine(
equalsFormatString,
"Reassembly Required",
ipStat.PacketReassembliesRequired);
Console.WriteLine(
equalsFormatString,
"Reassembly Successful",
ipStat.PacketsReassembled);
Console.WriteLine(
equalsFormatString,
"Reassembly Failures",
ipStat.PacketReassemblyFailures);
Console.WriteLine(
equalsFormatString,
"Datagrams Successfuly Fragmented",
ipStat.PacketsFragmented);
Console.WriteLine(
equalsFormatString,
"Datagrams Failing Fragmentation",
ipStat.PacketFragmentFailures);
Console.WriteLine(
equalsFormatString,
"Fragments Created",
ipStat.PacketsFragmented);
}
}
}