Thursday, August 28, 2008
This afternoon I learned of a few APIs that I was completely unaware of (that would have made my life a lot easier on some earlier projects).  3 hours later, We have this fully implemented:

radios.PNG

Usage looks like this:

Radios radios = Radios.GetRadios();

Debug.WriteLine("\nBefore\r\n--------");
foreach (IRadio radio in radios)
{
  Debug.WriteLine(string.Format("Name: {0}, Type: {1}, State: {2}", radio.DeviceName, radio.RadioType.ToString(), radio.RadioState.ToString()));

  // toggle all radio states
  radio.RadioState = (radio.RadioState == RadioState.On) ? RadioState.Off : RadioState.On;
}

// give the radios enough time to change state - some (like BT) seem to be slow
Thread.Sleep(1000);

radios.Refresh();

// display again
Debug.WriteLine("\r\nAfter\r\n--------");
foreach (IRadio radio in radios)
{
  Debug.WriteLine(string.Format("Name: {0}, Type: {1}, State: {2}", radio.DeviceName, radio.RadioType.ToString(), radio.RadioState.ToString()));
}
Debug.WriteLine("\r\n\n");
Thread.Sleep(100);


The only down side is that they are WinMo 5.0 and later only, so sorry CE devs.

I'm going to add it to the SDF source tree so it will be in the next release (soon, I promise).

8/28/2008 5:25:21 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0]  | 
 Friday, February 15, 2008

So, you want network statistics for your Windows CE or Windows Mobile device?  I think the new Smart Device Framework 2.2's NetworkInformation namespace might just give you what you're after.  It's got almost everything the desktop gives, plus we even provide access to the ARP and routing tables (something you *don't* get on the desktop).  Here's a complete sample on getting the supported statistics:

IPGlobalProperties globalProps = IPGlobalProperties.GetIPGlobalProperties();
Debug.WriteLine("\r\nGlobal IP Properties\r\n====================");
Debug.WriteLine(string.Format(" Host Name: {0}", globalProps.HostName));
Debug.WriteLine(string.Format(" Domain Name: {0}", globalProps.DomainName));
Debug.WriteLine(string.Format(" DHCP Scope Name: {0}", globalProps.DhcpScopeName));

IPGlobalStatistics globalStatsv4 = globalProps.GetIPv4GlobalStatistics();
Debug.WriteLine("\r\nGlobal IPv4 Statistics\r\n====================");
Debug.WriteLine(string.Format(" Packets Received: {0}", globalStatsv4.ReceivedPackets));
Debug.WriteLine(string.Format(" Packets Delivered: {0}", globalStatsv4.ReceivedPacketsDelivered));
Debug.WriteLine(string.Format(" Packets Discarded: {0}", globalStatsv4.ReceivedPacketsDiscarded));
Debug.WriteLine(string.Format(" Packets Forwarded: {0}", globalStatsv4.ReceivedPacketsForwarded));
Debug.WriteLine(string.Format(" Packets Received w/ Address Errors: {0}", globalStatsv4.ReceivedPacketsWithAddressErrors));
Debug.WriteLine(string.Format(" Packets Received w/ Header Errors: {0}", globalStatsv4.ReceivedPacketsWithHeadersErrors));
Debug.WriteLine(string.Format(" Packets Received w/ Protocol Errors: {0}", globalStatsv4.ReceivedPacketsWithUnknownProtocol));
Debug.WriteLine(string.Format(" Default TTL: {0}", globalStatsv4.DefaultTtl));
Debug.WriteLine(string.Format(" Forwarding {0} Enabled", globalStatsv4.ForwardingEnabled ? "IS" : "IS NOT"));
Debug.WriteLine(string.Format(" Interfaces: {0}", globalStatsv4.NumberOfInterfaces));
Debug.WriteLine(string.Format(" IP Addresses: {0}", globalStatsv4.NumberOfIPAddresses));
Debug.WriteLine(string.Format(" Routes: {0}", globalStatsv4.NumberOfRoutes));
Debug.WriteLine(string.Format(" Output Packet Requests: {0}", globalStatsv4.OutputPacketRequests));
Debug.WriteLine(string.Format(" Output Routing Discards: {0}", globalStatsv4.OutputPacketRoutingDiscards));
Debug.WriteLine(string.Format(" Output Packet Discards: {0}", globalStatsv4.OutputPacketsDiscarded));
Debug.WriteLine(string.Format(" Output Packets w/o Route: {0}", globalStatsv4.OutputPacketsWithNoRoute));
Debug.WriteLine(string.Format(" Fragmented Packets: {0}", globalStatsv4.PacketsFragmented));
Debug.WriteLine(string.Format(" Fragment Failures: {0}", globalStatsv4.PacketFragmentFailures));
Debug.WriteLine(string.Format(" Reassemblies Required: {0}", globalStatsv4.PacketReassembliesRequired));
Debug.WriteLine(string.Format(" Reassemblies Succeeded: {0}", globalStatsv4.PacketsReassembled));
Debug.WriteLine(string.Format(" Reassembly Failures: {0}", globalStatsv4.PacketReassemblyFailures));
Debug.WriteLine(string.Format(" Reassembly Timeouts: {0}", globalStatsv4.PacketReassemblyTimeout));

#region --- IPv6 stats ---
try
{
    Debug.WriteLine("\r\nGlobal IPv6 Statistics\r\n====================");
    IPGlobalStatistics globalStatsv6 = globalProps.GetIPv6GlobalStatistics();
    Debug.WriteLine(string.Format(" Packets Received: {0}", globalStatsv6.ReceivedPackets));
    Debug.WriteLine(string.Format(" Packets Delivered: {0}", globalStatsv6.ReceivedPacketsDelivered));
    Debug.WriteLine(string.Format(" Packets Discarded: {0}", globalStatsv6.ReceivedPacketsDiscarded));
    Debug.WriteLine(string.Format(" Packets Forwarded: {0}", globalStatsv6.ReceivedPacketsForwarded));
    Debug.WriteLine(string.Format(" Packets Received w/ Address Errors: {0}", globalStatsv6.ReceivedPacketsWithAddressErrors));
    Debug.WriteLine(string.Format(" Packets Received w/ Header Errors: {0}", globalStatsv6.ReceivedPacketsWithHeadersErrors));
    Debug.WriteLine(string.Format(" Packets Received w/ Protocol Errors: {0}", globalStatsv6.ReceivedPacketsWithUnknownProtocol));
    Debug.WriteLine(string.Format(" Default TTL: {0}", globalStatsv6.DefaultTtl));
    Debug.WriteLine(string.Format(" Forwarding {0} Enabled", globalStatsv6.ForwardingEnabled ? "IS" : "IS NOT"));
    Debug.WriteLine(string.Format(" Interfaces: {0}", globalStatsv6.NumberOfInterfaces));
    Debug.WriteLine(string.Format(" IP Addresses: {0}", globalStatsv6.NumberOfIPAddresses));
    Debug.WriteLine(string.Format(" Routes: {0}", globalStatsv6.NumberOfRoutes));
    Debug.WriteLine(string.Format(" Output Packet Requests: {0}", globalStatsv6.OutputPacketRequests));
    Debug.WriteLine(string.Format(" Output Routing Discards: {0}", globalStatsv6.OutputPacketRoutingDiscards));
    Debug.WriteLine(string.Format(" Output Packet Discards: {0}", globalStatsv6.OutputPacketsDiscarded));
    Debug.WriteLine(string.Format(" Output Packets w/o Route: {0}", globalStatsv6.OutputPacketsWithNoRoute));
    Debug.WriteLine(string.Format(" Fragmented Packets: {0}", globalStatsv6.PacketsFragmented));
    Debug.WriteLine(string.Format(" Fragment Failures: {0}", globalStatsv6.PacketFragmentFailures));
    Debug.WriteLine(string.Format(" Reassemblies Required: {0}", globalStatsv6.PacketReassembliesRequired));
    Debug.WriteLine(string.Format(" Reassemblies Succeeded: {0}", globalStatsv6.PacketsReassembled));
    Debug.WriteLine(string.Format(" Reassembly Failures: {0}", globalStatsv6.PacketReassemblyFailures));
    Debug.WriteLine(string.Format(" Reassembly Timeouts: {0}", globalStatsv6.PacketReassemblyTimeout));
    Debug.WriteLine(string.Format(" Packets Received: {0}", globalStatsv6.ReceivedPackets));
}
catch (PlatformNotSupportedException)
{
    Debug.WriteLine(" IPv6 Not supported");
}
#endregion

#region --- Icmpv4 stats ---
IcmpV4Statistics icmpstats = globalProps.GetIcmpV4Statistics();
Debug.WriteLine("\r\nICMPv4 Statistics\r\n====================");
Debug.WriteLine(string.Format(" Address Mask Requests Received: {0}", icmpstats.AddressMaskRequestsReceived));
Debug.WriteLine(string.Format(" Address Mask Requests Sent: {0}", icmpstats.AddressMaskRequestsSent));
Debug.WriteLine(string.Format(" Address Mask Replies Received: {0}", icmpstats.AddressMaskRepliesReceived));
Debug.WriteLine(string.Format(" Address Mask Replies Sent: {0}", icmpstats.AddressMaskRepliesSent));
Debug.WriteLine(string.Format(" Dest Unreachable Messages Received: {0}", icmpstats.DestinationUnreachableMessagesReceived));
Debug.WriteLine(string.Format(" Dest Unreachable Messages Sent: {0}", icmpstats.DestinationUnreachableMessagesSent));
Debug.WriteLine(string.Format(" Echo Replies Received: {0}", icmpstats.EchoRepliesReceived));
Debug.WriteLine(string.Format(" Echo Replies Sent: {0}", icmpstats.EchoRepliesSent));
Debug.WriteLine(string.Format(" Echo Requests Received: {0}", icmpstats.EchoRequestsReceived));
Debug.WriteLine(string.Format(" Echo Requests Sent: {0}", icmpstats.EchoRequestsSent));
Debug.WriteLine(string.Format(" Errors Received: {0}", icmpstats.ErrorsReceived));
Debug.WriteLine(string.Format(" Errors Sent: {0}", icmpstats.ErrorsSent));
Debug.WriteLine(string.Format(" Messages Received: {0}", icmpstats.MessagesReceived));
Debug.WriteLine(string.Format(" Messages Sent: {0}", icmpstats.MessagesSent));
Debug.WriteLine(string.Format(" Parameter Problems Received: {0}", icmpstats.ParameterProblemsReceived));
Debug.WriteLine(string.Format(" Parameter Problems Sent: {0}", icmpstats.ParameterProblemsSent));
Debug.WriteLine(string.Format(" Redirects Received: {0}", icmpstats.RedirectsReceived));
Debug.WriteLine(string.Format(" Redirects Sent: {0}", icmpstats.RedirectsSent));
Debug.WriteLine(string.Format(" Source Quenches Received: {0}", icmpstats.SourceQuenchesReceived));
Debug.WriteLine(string.Format(" Source Quenches Sent: {0}", icmpstats.SourceQuenchesSent));
Debug.WriteLine(string.Format(" Time Exceeded Messages Received: {0}", icmpstats.TimeExceededMessagesReceived));
Debug.WriteLine(string.Format(" Time Exceeded Messages Sent: {0}", icmpstats.TimeExceededMessagesSent));
Debug.WriteLine(string.Format(" Timestamp Replies Received: {0}", icmpstats.TimestampRepliesReceived));
Debug.WriteLine(string.Format(" Timestamp Replies Sent: {0}", icmpstats.TimestampRepliesSent));
Debug.WriteLine(string.Format(" Timestamp Requests Received: {0}", icmpstats.TimestampRequestsReceived));
Debug.WriteLine(string.Format(" Timestamp Requests Sent: {0}", icmpstats.TimestampRequestsSent));
#endregion

#region --- TCPIPv4 stats ---
TcpStatistics tcpstats = globalProps.GetTcpIPv4Statistics();
Debug.WriteLine("\r\nTCP/IP v4 Statistics\r\n====================");
Debug.WriteLine(string.Format(" Connections Accepted: {0}", tcpstats.ConnectionsAccepted));
Debug.WriteLine(string.Format(" Connections Initiated: {0}", tcpstats.ConnectionsInitiated));
Debug.WriteLine(string.Format(" Cumulative Connections: {0}", tcpstats.CumulativeConnections));
Debug.WriteLine(string.Format(" Current Connections: {0}", tcpstats.CurrentConnections));
Debug.WriteLine(string.Format(" Errors Received: {0}", tcpstats.ErrorsReceived));
Debug.WriteLine(string.Format(" Failed Connection Attempts: {0}", tcpstats.FailedConnectionAttempts));
Debug.WriteLine(string.Format(" Maximum Connections: {0}", tcpstats.MaximumConnections));
Debug.WriteLine(string.Format(" Max Transmission Timeout: {0}", tcpstats.MaximumTransmissionTimeout));
Debug.WriteLine(string.Format(" Min Transmission Timeout: {0}", tcpstats.MinimumTransmissionTimeout));
Debug.WriteLine(string.Format(" Reset Connections: {0}", tcpstats.ResetConnections));
Debug.WriteLine(string.Format(" Resets Sent: {0}", tcpstats.ResetsSent));
Debug.WriteLine(string.Format(" Segments Received: {0}", tcpstats.SegmentsReceived));
Debug.WriteLine(string.Format(" Segments Resent: {0}", tcpstats.SegmentsResent));
Debug.WriteLine(string.Format(" Connections Sent: {0}", tcpstats.SegmentsSent));
#endregion

#region --- TCPIPv6 stats ---
Debug.WriteLine("\r\nTCP/IP v6 Statistics\r\n====================");
try
{
    tcpstats = globalProps.GetTcpIPv6Statistics();
    Debug.WriteLine(string.Format(" Connections Accepted: {0}", tcpstats.ConnectionsAccepted));
    Debug.WriteLine(string.Format(" Connections Initiated: {0}", tcpstats.ConnectionsInitiated));
    Debug.WriteLine(string.Format(" Cumulative Connections: {0}", tcpstats.CumulativeConnections));
    Debug.WriteLine(string.Format(" Current Connections: {0}", tcpstats.CurrentConnections));
    Debug.WriteLine(string.Format(" Errors Received: {0}", tcpstats.ErrorsReceived));
    Debug.WriteLine(string.Format(" Failed Connection Attempts: {0}", tcpstats.FailedConnectionAttempts));
    Debug.WriteLine(string.Format(" Maximum Connections: {0}", tcpstats.MaximumConnections));
    Debug.WriteLine(string.Format(" Max Transmission Timeout: {0}", tcpstats.MaximumTransmissionTimeout));
    Debug.WriteLine(string.Format(" Min Transmission Timeout: {0}", tcpstats.MinimumTransmissionTimeout));
    Debug.WriteLine(string.Format(" Reset Connections: {0}", tcpstats.ResetConnections));
    Debug.WriteLine(string.Format(" Resets Sent: {0}", tcpstats.ResetsSent));
    Debug.WriteLine(string.Format(" Segments Received: {0}", tcpstats.SegmentsReceived));
    Debug.WriteLine(string.Format(" Segments Resent: {0}", tcpstats.SegmentsResent));
    Debug.WriteLine(string.Format(" Connections Sent: {0}", tcpstats.SegmentsSent));
}
catch (PlatformNotSupportedException)
{
    Debug.WriteLine(" IPv6 Not supported");
}
#endregion

#region --- UDPv4 stats ---
UdpStatistics udpstats = globalProps.GetUdpIPv4Statistics();
Debug.WriteLine("\r\nUDP v4 Statistics\r\n====================");
Debug.WriteLine(string.Format(" UDP Listeners: {0}", udpstats.UdpListeners));
Debug.WriteLine(string.Format(" Datagrams Received: {0}", udpstats.DatagramsReceived));
Debug.WriteLine(string.Format(" Datagrams Sent: {0}", udpstats.DatagramsSent));
Debug.WriteLine(string.Format(" Datagrams Discarded: {0}", udpstats.IncomingDatagramsDiscarded));
Debug.WriteLine(string.Format(" Datagrams with Errors: {0}", udpstats.IncomingDatagramsWithErrors));
#endregion

#region --- UDPv6 stats ---
Debug.WriteLine("\r\nUDP v6 Statistics\r\n====================");
try
{
    udpstats = globalProps.GetUdpIPv6Statistics();
    Debug.WriteLine(string.Format(" UDP Listeners: {0}", udpstats.UdpListeners));
    Debug.WriteLine(string.Format(" Datagrams Received: {0}", udpstats.DatagramsReceived));
    Debug.WriteLine(string.Format(" Datagrams Sent: {0}", udpstats.DatagramsSent));
    Debug.WriteLine(string.Format(" Datagrams Discarded: {0}", udpstats.IncomingDatagramsDiscarded));
    Debug.WriteLine(string.Format(" Datagrams with Errors: {0}", udpstats.IncomingDatagramsWithErrors));
}
catch (PlatformNotSupportedException)
{
    Debug.WriteLine(" IPv6 Not supported");
}
#endregion

ArpTable table = ArpTable.GetArpTable();
if (table.Count > 0)
{
    Debug.WriteLine("\r\n*ARP Table\r\n====================");
    Debug.WriteLine(string.Format("{0}{1}{2}{3}",
   
"[Interface]".PadRight(16),
    "[Type]".PadLeft(10),
    "[IP Address]".PadLeft(17),
    "[MAC Address]".PadLeft(22)));
    foreach (ArpEntry entry in table)
    {
        Debug.WriteLine(string.Format("{0}{1}{2}{3}"
            entry.NetworkInterface.Name.PadRight(16), 
            entry.ArpEntryType.ToString().PadLeft(10), 
            entry.IPAddress.ToString().PadLeft(17), 
            entry.PhysicalAddress.ToString().PadLeft(22)));
    }
}
else
{
    Debug.WriteLine(" No ARP table entries");
}

IPRoutingTable routingTable = IPRoutingTable.GetRoutingTable();
if(routingTable.Count > 0)
{
    Debug.WriteLine("\r\n*IP Routing Table\r\n====================");
    Debug.WriteLine(string.Format("{0}{1}{2}{3}{4}",
        "[Interface]".PadRight(16),
        "[Type]".PadRight(12),
        "[Destination]".PadLeft(17),
        "[NetMask]".PadLeft(17),
        "[Next Hop]".PadLeft(17)));
    foreach (IPForwardEntry entry in routingTable)
    {
        string intfname = entry.NetworkInterface == null ? intfname = "{Loopback}" : entry.NetworkInterface.Name;
        Debug.WriteLine(string.Format("{0}{1}{2}{3}{4}",
        intfname.PadRight(16),
        entry.RouteType.ToString().PadRight(12),
        entry.Destination.ToString().PadLeft(17),
        entry.SubnetMask.ToString().PadLeft(17),
        entry.NextHop.ToString().PadLeft(17))); 
    }
}
else
{
    Debug.WriteLine(" No IP Routing table entries");
}

TcpConnectionInformation[] connections = globalProps.GetActiveTcpConnections();
if (connections.Length > 0)
{
    Debug.WriteLine("\r\nActive TCP Connections\r\n====================");
    Debug.WriteLine(string.Format("{0}:{1}<---->{2}{3}[{4}]",
        "[local IP]".PadLeft(16),
        "[port]".PadRight(6),
        "[remote IP]".PadLeft(16),
        "[port]".PadRight(6),
        "[state]"));
    foreach (TcpConnectionInformation info in connections)
    {
        Debug.WriteLine(string.Format("{0}:{1}<---->{2}:{3}[{4}]",
        info.LocalEndPoint.Address.ToString().PadLeft(16),
        info.LocalEndPoint.Port.ToString().PadRight(6),
        info.RemoteEndPoint.Address.ToString().PadLeft(16),
        info.RemoteEndPoint.Port.ToString().PadRight(6),
        info.State.ToString()));
    }
}
else
{
    Debug.WriteLine(" No active TCP connections");
}

2/15/2008 11:57:23 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 

Smart Device Framework 2.2 refactored a lot of our network interface classes.  Yes, it's likely to casue some angst with people that used the older stuff, but it really is for the best.  I never liked the older mechanism that exposed things like SSID for network interfaces that weren't even wireless.  The new model is much friendlier and object-oriented.  Here's a quick (and very thorough) example of how to use the new classes.  As you can see, there's *nothing* to be known about the interface that isn't exposed.

NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
WirelessZeroConfigNetworkInterface wzcInterface = null;

foreach (NetworkInterface ni in interfaces)
{
    Debug.WriteLine(string.Format("===========\r\nInterface {0}\r\n===========", ni.Id));
    Debug.WriteLine(string.Format(" Type: {0}", ni.GetType().Name));
    Debug.WriteLine(string.Format(" Name: {0}", ni.Name));
    Debug.WriteLine(string.Format(" Description: {0}", ni.Description));
    Debug.WriteLine(string.Format(" Network Interface Type: {0}", ni.NetworkInterfaceType.ToString()));
    PhysicalAddress address = ni.GetPhysicalAddress();
    Debug.WriteLine(string.Format(" MAC: {0}", address == null ? "{none}" : address.ToString()));
    Debug.WriteLine(string.Format(" Operational Status: {0}", ni.OperationalStatus.ToString()));
    Debug.WriteLine(string.Format(" Speed: {0}bps", ni.Speed));
    Debug.WriteLine(string.Format(" *Interface Operational Status: {0}", ni.InterfaceOperationalStatus.ToString()));
    Debug.WriteLine(string.Format(" *Current IP: {0}", ni.CurrentIpAddress.ToString()));
    Debug.WriteLine(string.Format(" *Current Subnet: {0}", ni.CurrentSubnetMask.ToString()));

    IPInterfaceProperties ipProps = ni.GetIPProperties();
    Debug.WriteLine("\r\n IP Properties\r\n -------------");

#region
--- Server Lists ---
    if (ipProps.DhcpServerAddresses.Count > 0)
    {
        for (int i = 0; i < ipProps.DhcpServerAddresses.Count; i++)
        {
            Debug.WriteLine(string.Format(" DHCP Server {0}: {1}", i, ipProps.DhcpServerAddresses[i].ToString()));
        }
    }
    else
    {
        Debug.WriteLine(" No DHCP Servers");
    }

    if (ipProps.DnsAddresses.Count > 0)
    {
        for (int i = 0; i < ipProps.DnsAddresses.Count; i++)
        {
            Debug.WriteLine(string.Format(" DNS Server {0}: {1}", i, ipProps.DnsAddresses[i].ToString()));
        }
    }
    else
    {
        Debug.WriteLine(" No DNS Servers");
    }

    if (ipProps.GatewayAddresses.Count > 0)
    {
        for (int i = 0; i < ipProps.GatewayAddresses.Count; i++)
        {
            Debug.WriteLine(string.Format(" Gateway {0}: {1}", i, ipProps.GatewayAddresses[i].Address.ToString()));
        }
    }
    else
    {
        Debug.WriteLine(" No Gateways");
    }
    
    if (ipProps.WinsServersAddresses.Count > 0)
    {
        for (int i = 0; i < ipProps.WinsServersAddresses.Count; i++)
        {
            Debug.WriteLine(string.Format(" WINS Server {0}: {1}", i, ipProps.WinsServersAddresses[i].ToString()));
        }
    }
    else
    {
        Debug.WriteLine(" No WINS Servers");
    }
#endregion

#region --- Unicast Addresses ---
    if (ipProps.UnicastAddresses.Count > 0)
    {
        for (int i = 0; i < ipProps.UnicastAddresses.Count; i++)
        {
            Debug.WriteLine(string.Format(" Unicast address {0}: {1}", i, ipProps.UnicastAddresses[i].Address.ToString()));
            Debug.WriteLine(string.Format(" Address Family: {0}", ipProps.UnicastAddresses[i].Address.AddressFamily));
            if (ipProps.UnicastAddresses[i].Address.AddressFamily == AddressFamily.InterNetworkV6)
            {
                Debug.WriteLine(string.Format(" Scope ID: {0}", ipProps.UnicastAddresses[i].Address.ScopeId));
            }
            else // ipv4
            {
                Debug.WriteLine(string.Format(" IPv4 Mask: {0}", ipProps.UnicastAddresses[i].IPv4Mask == null 
                        ? "{none}" : ipProps.UnicastAddresses[i].IPv4Mask.ToString()));
            }
            Debug.WriteLine(string.Format(" Preferred Limetime: {0}", ipProps.UnicastAddresses[i].AddressPreferredLifetime));
            Debug.WriteLine(string.Format(" Valid Limetime: {0}", ipProps.UnicastAddresses[i].AddressValidLifetime));
            Debug.WriteLine(string.Format(" DHCP Lease Limetime: {0}", ipProps.UnicastAddresses[i].DhcpLeaseLifetime));
            Debug.WriteLine(string.Format(" DAD State: {0}", ipProps.UnicastAddresses[i].DuplicateAddressDetectionState));
            Debug.WriteLine(string.Format(" {0} DNS Eligible", ipProps.UnicastAddresses[i].IsDnsEligible ? "IS" : "IS NOT"));
            Debug.WriteLine(string.Format(" {0} Transient", ipProps.UnicastAddresses[i].IsTransient ? "IS" : "IS NOT"));
            Debug.WriteLine(string.Format(" Prefix Origin: {0}", ipProps.UnicastAddresses[i].PrefixOrigin.ToString()));
            Debug.WriteLine(string.Format(" Suffix Origin: {0}", ipProps.UnicastAddresses[i].SuffixOrigin.ToString()));
        }
    }
    else
    {
        Debug.WriteLine(" No Unicast addresses");
    }
#endregion

#region
--- Anycast Addresses ---
    if (ipProps.AnycastAddresses.Count > 0)
    {
        for (int i = 0; i < ipProps.AnycastAddresses.Count; i++)
        {
            Debug.WriteLine(string.Format(" Anycast address {0}: {1}", i, ipProps.AnycastAddresses[i].Address.ToString()));
            Debug.WriteLine(string.Format(" Address Family: {0}", ipProps.AnycastAddresses[i].Address.AddressFamily));
            if (ipProps.AnycastAddresses[i].Address.AddressFamily == AddressFamily.InterNetworkV6)
            {
                Debug.WriteLine(string.Format(" Scope ID: {0}", ipProps.AnycastAddresses[i].Address.ScopeId));
            }
            Debug.WriteLine(string.Format(" {0} DNS Eligible", ipProps.UnicastAddresses[i].IsDnsEligible ? "IS" : "IS NOT"));
            Debug.WriteLine(string.Format(" {0} Transient", ipProps.UnicastAddresses[i].IsTransient ? "IS" : "IS NOT"));
        }
    }
    else
    {
        Debug.WriteLine(" No Anycast addresses");
    }
#endregion

#region --- Multicast Addresses ---
    if (ipProps.MulticastAddresses.Count > 0)
    {
        for (int i = 0; i < ipProps.MulticastAddresses.Count; i++)
        {
            Debug.WriteLine(string.Format(" Anycast address {0}: {1}", i, ipProps.MulticastAddresses[i].Address.ToString()));
            Debug.WriteLine(string.Format(" Address Family: {0}", ipProps.MulticastAddresses[i].Address.AddressFamily));
            if (ipProps.MulticastAddresses[i].Address.AddressFamily == AddressFamily.InterNetworkV6)
            {
                Debug.WriteLine(string.Format(" Scope ID: {0}", ipProps.MulticastAddresses[i].Address.ScopeId));
            }
            Debug.WriteLine(string.Format(" {0} DNS Eligible", ipProps.MulticastAddresses[i].IsDnsEligible ? "IS" : "IS NOT"));
            Debug.WriteLine(string.Format(" {0} Transient", ipProps.MulticastAddresses[i].IsTransient ? "IS" : "IS NOT"));
        }
    }
    else
    {
        Debug.WriteLine(" No Multicast addresses");
    }
#endregion

#region --- IPv4 Stats ---
    IPv4InterfaceStatistics ipstats = ni.GetIPv4Statistics();
    Debug.WriteLine("\r\n IPv4 Statistics\r\n -------------");
    Debug.WriteLine(string.Format(" Bytes Received: {0}", ipstats.BytesReceived));
    Debug.WriteLine(string.Format(" Bytes Sent: {0}", ipstats.BytesSent));
    Debug.WriteLine(string.Format(" Incoming Packets Discarded: {0}", ipstats.IncomingPacketsDiscarded));
    Debug.WriteLine(string.Format(" Incoming Packets with errors: {0}", ipstats.IncomingPacketsWithErrors));
    Debug.WriteLine(string.Format(" Incoming Packets Unk. Protocol: {0}", ipstats.IncomingUnknownProtocolPackets));
    Debug.WriteLine(string.Format(" Non Unicast Packets Received: {0}", ipstats.NonUnicastPacketsReceived));
    Debug.WriteLine(string.Format(" Non Unicast Packets Sent: {0}", ipstats.NonUnicastPacketsSent));
    Debug.WriteLine(string.Format(" Outgoing Packets Discarded: {0}", ipstats.OutgoingPacketsDiscarded));
    Debug.WriteLine(string.Format(" Outgoing Packets With Errors: {0}", ipstats.OutgoingPacketsWithErrors));
    Debug.WriteLine(string.Format(" Output Queue Length: {0}", ipstats.OutputQueueLength));
    Debug.WriteLine(string.Format(" Unicast Packets Received: {0}", ipstats.UnicastPacketsReceived));
    Debug.WriteLine(string.Format(" Unicast Packets Sent: {0}", ipstats.UnicastPacketsSent));
#endregion

#region --- IPv4 Properties ---
    IPv4InterfaceProperties ipv4props = ipProps.GetIPv4Properties();
    Debug.WriteLine("\r\n IPv4 Properties\r\n -------------");
    Debug.WriteLine(string.Format(" Index: {0}", ipv4props.Index));
    Debug.WriteLine(string.Format(" Auto Addressing {0}", ipv4props.IsAutomaticPrivateAddressingActive 
        ? "ACTIVE" : "INACTIVE"));
    Debug.WriteLine(string.Format(" Auto Addressing {0}", ipv4props.IsAutomaticPrivateAddressingEnabled 
        ? "ENABLED" : "DISABLED"));
    Debug.WriteLine(string.Format(" DHCP {0}", ipv4props.IsDhcpEnabled ? "ENABLED" : "DISABLED"));
    Debug.WriteLine(string.Format(" MTU: {0}", ipv4props.Mtu));
    Debug.WriteLine(string.Format(" {0} use WINS", ipv4props.UsesWins ? "DOES" : "DOES NOT"));
#endregion

    if (ni is WirelessZeroConfigNetworkInterface)
    {
        WirelessZeroConfigNetworkInterface wzc = (WirelessZeroConfigNetworkInterface)ni;

        // save for later operations
        wzcInterface = wzc;

        Debug.WriteLine("\r\n *WZC Properties\r\n -------------");
        Debug.WriteLine(string.Format(" *Associated AP: {0}", wzc.AssociatedAccessPoint));
        Debug.WriteLine(string.Format(" *Associated AP MAC: {0}", wzc.AssociatedAccessPointMAC));
        Debug.WriteLine(string.Format(" *Authentication Mode: {0}", wzc.AuthenticationMode.ToString()));
        Debug.WriteLine(string.Format(" *WZC Fallback Enabled: {0}", wzc.FallbackEnabled));
        Debug.WriteLine(string.Format(" *WEP Status: {0}", wzc.WEPStatus));
        Debug.WriteLine(string.Format(" *Signal Strength: {0}db ({1})", wzc.SignalStrength.Decibels, 
                wzc.SignalStrength.Strength.ToString()));
        Debug.WriteLine(string.Format(" *Authentication Mode: {0}", wzc.AuthenticationMode.ToString()));
        Debug.WriteLine(string.Format(" *Infrastructure Mode: {0}", wzc.InfrastructureMode.ToString()));
        Debug.WriteLine(string.Format(" *WEP Status: {0}", wzc.WEPStatus.ToString()));
        foreach (int rate in wzc.SupportedRates)
        {
            Debug.WriteLine(string.Format(" *Supports {0}kbps", rate));
        }
        Debug.WriteLine(string.Format(" *Radio ATIM Window: {0}Kµsec", wzc.RadioConfiguration.ATIMWindow));
        Debug.WriteLine(string.Format(" *Radio beacon Period: {0}Kµsec", wzc.RadioConfiguration.BeaconPeriod));
        Debug.WriteLine(string.Format(" *Radio Frequency: {0}kHz", wzc.RadioConfiguration.Frequency));
        Debug.WriteLine(string.Format(" *Radio Frequency Hop Dwell Time: {0}Kµsec",         
                wzc.RadioConfiguration.FrequencyHopDwellTime));
        Debug.WriteLine(string.Format(" *Radio Frequency Hop Pattern: {0}", wzc.RadioConfiguration.FrequencyHopPattern));
        Debug.WriteLine(string.Format(" *Radio Frequency Hop Set: {0}", wzc.RadioConfiguration.FrequencyHopSet));

#region --- Preferred APs ---
        if (wzc.PreferredAccessPoints.Count > 0)
        {
            Debug.WriteLine("\r\n *Preferred APs\r\n -------------");
            foreach (AccessPoint ap in wzc.PreferredAccessPoints)
            {
                Debug.WriteLine(string.Format(" *SSID: {0}", ap.Name));
                Debug.WriteLine(string.Format(