5

IMPORTANT EDIT: Back again on this subject. As you said there should be no default NIC, I'm trying to understand if there is a way to detect all the NICs that are actually connected.

Having the MAC address of my physical interface is there a programmatic way to get interface name/interface status/etc...

For example, my XP machine:

Device Realtek RTL8139 Family PCI Fast Ethernet NIC MAC XXXX-XXXX-XXXX

XXXX-XXXX-XXXX is what I know

Through this device I connect using "Local Area Connection" connection (with all the info related as gateway, subnet, ...)

So I'm searching for the link between XXXX-XXXX-XXXX and Local Area Connection.

Hope everything is clear now.

Thanks all! P.S. Sorry for the delay... +1 vote to all, for patience!


Old question


Hi all, I'd like to change the IP of "Local Area Connection" by using the command netsh.

My issue is is there a programmatic way to get the default connection name (i.e. exactly "Local Area Connection")?

Thanks

EDIT: I don't need the list of all the connection names but only the default one. Accessing the registry I get the list and it seems that the default is marked with a *. Unfortunately, printing them on a console I get kind of 10 different "Local Area Connection" like...

Local Area Connection* 13
6TO4 Adapter
VMware Network Adapter VMnet1
Wireless Network Connection 2
Reusable ISATAP Interface {483968F2-DBF9-4596-B8BE-725FAAB89F93}
Local Area Connection* 3
Local Area Connection* 2
Reusable Microsoft 6To4 Adapter
Local Area Connection* 7
VMware Network Adapter VMnet8
Local Area Connection* 8
isatap.replynet.prv
Local Area Connection* 9
Local Area Connection* 12
isatap.{FAA80CE0-D641-408A-83F8-5F9C394FFD76}
Bluetooth Network Connection
Local Area Connection* 4
isatap.{40156BF9-6599-4912-A315-62DE5342B452}
isatap.{7651F2F5-4888-4258-92C5-6822C506D726}
Local Area Connection* 5
isatap.{34F5F074-8AA7-4421-AE24-131BA2DC3458}
Local Area Connection*
Local Area Connection* 10
Local Area Connection
Local Area Connection* 6
Wireless Network Connection

and so on...

EDIT2: @ho1 running your code changing FriendlyName that doesn't exists with Name you'll get something like the list behind, unfortunately it doesn't seem to be the output expected

0 - WAN Miniport (SSTP)
1 - WAN Miniport (IKEv2)
2 - WAN Miniport (L2TP)
3 - WAN Miniport (PPTP)
4 - WAN Miniport (PPPOE)
5 - WAN Miniport (IPv6)
6 - WAN Miniport (Network Monitor)
7 - Realtek RTL8168C(P)/8111C(P) Family PCI-E Gigabit Ethernet NIC (NDIS 6.20)
8 - WAN Miniport (IP)
9 - Microsoft ISATAP Adapter
10 - RAS Async Adapter
11 - Broadcom 802.11g Network Adapter
12 - Microsoft 6to4 Adapter
13 - VMware Virtual Ethernet Adapter for VMnet1
14 - Microsoft ISATAP Adapter #3
15 - VMware Virtual Ethernet Adapter for VMnet8
16 - Microsoft ISATAP Adapter #2
17 - Microsoft ISATAP Adapter #4
18 - Microsoft Virtual WiFi Miniport Adapter
19 - Microsoft ISATAP Adapter #5
20 - Microsoft ISATAP Adapter
22 - Bluetooth Device (Personal Area Network)
23 - Microsoft 6to4 Adapter
24 - Microsoft 6to4 Adapter #3
25 - Microsoft 6to4 Adapter #2
Yahia
  • 69,653
  • 9
  • 115
  • 144
Mauro
  • 2,032
  • 3
  • 25
  • 47
  • 1
    Is it possible to set a default NIC in Windows 7? I know an OS isn't specified in this question, I just can't find the option... – fletcher Aug 11 '10 at 10:21
  • @fletcher: I guess there is not default NIC at all. There is default route which depends on request target, NICs addition order and routing table – abatishchev Aug 11 '10 at 10:26
  • @both sorry I intentionally left the OS specification in order to find the more OS-agnostic solution :) What do you think of the list of Networks I got from the registry (Win7)? – Mauro Aug 11 '10 at 10:34
  • @Mauro - I don't think there is a way to find a definitive default NIC. I think you will have to use one of the answers provided and filter the results based on the other information available in the object, e.g connection state to make your decision – fletcher Aug 11 '10 at 10:37
  • Updated my answer with better code (but not certain that it'll give you the "default" one). – Hans Olsson Aug 11 '10 at 10:40
  • 1
    Btw, rather than using an external tool for setting the IP (netsh), you could probably do that using `Win32_NetworkAdapterConfiguration.EnableStatic`, might be "neater". – Hans Olsson Aug 11 '10 at 10:50
  • @fletcher: the same thing I am wondering... – leppie Aug 11 '10 at 11:43

6 Answers6

5

As others have mentioned, there is no "Default" NIC adapter in Windows. The NIC used is chosen based on the destination network (address) and the metric.

For example, if you have two NICs and two different networks:

  10.1.10.1 - Local Area Connection (metric 20)
  10.1.50.1 - Local Area Connection 2 (metric 10)

And you want to connect to 10.1.10.15, Windows will choose Local Area Connection and route that way. Conversely, if you want to connect to 10.1.50.30, Windows will choose Local Area Connection 2.

Now, if you try to connect to 74.125.67.106 (google.com), Windows will choose Local Area Connection 2 because it has a lower metric value.

EDIT: Here is a great article explaining routing - http://www.windowsnetworking.com/articles_tutorials/Making-Sense-Windows-Routing-Tables.html
EDIT2: Spelling.

Hope this helps.

Jesse
  • 8,605
  • 7
  • 47
  • 57
3
using System.Linq;
using System.Net.NetworkInformation;

var nic = NetworkInterface
     .GetAllNetworkInterfaces()
     .FirstOrDefault(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback && i.NetworkInterfaceType != NetworkInterfaceType.Tunnel);
var name = nic.Name;

or more elegant solution:

.Where(i => !(
    new[] { NetworkInterfaceType.Loopback, NetworkInterfaceType.Tunnel }
    .Contains(i.NetworkInterfaceType)))

or if you want to practice in LINQ:

static IEnumerable<NetworkInterface> GetAllNetworkInterfaces(IEnumerable<NetworkInterfaceType> excludeTypes)
{
    var all = NetworkInterface.GetAllNetworkInterfaces();
    var exclude = all.Where(i => excludeTypes.Contains(i.NetworkInterfaceType));
    return all.Except(exclude);
}

Usage:

var nic = GetAllNetworkInterfaces(new[] { NetworkInterfaceType.Tunnel, NetworkInterfaceType.Loopback });
abatishchev
  • 98,240
  • 88
  • 296
  • 433
  • Am I wrong or FirstOrDefault will give, if I have more than one, the first of the list and NOT the default? – Mauro Aug 11 '10 at 10:08
  • @Mauro: `FirstOrDefault` returns first from a list. If list is empty then `default(T)` (`null` for reference types) – abatishchev Aug 11 '10 at 10:14
  • Yes I know :D The "Default" concept I use here means "the connection that is in use, i.e. is the default". – Mauro Aug 11 '10 at 10:17
  • @Mauro - What if several are in use? – fletcher Aug 11 '10 at 10:19
  • @Mauro: :) Yea, sorry, Just first but not system default. Because there is no system default nic. It can be a nic for default route, which depends on a target given and in general - on routing table – abatishchev Aug 11 '10 at 10:19
  • @Fletcher: you're right I should have only said "the default one"... as it seems by the registry starred connection name. What do you think? – Mauro Aug 11 '10 at 10:25
2

You can use the WMI class Win32_NetworkAdapter to enumerate all the adapters and it has an Index property which might mean that the one with 0 or 1 as the Index is the default one, or one of the other properties might help to find the default one.

Something like this maybe:

Edit: Fixed broken code (this is at least more likely to work). But following what abatishchev said I think you might need to use Win32_NetworkAdapterConfiguration.IPConnectionMetric to find the default adapter...

ManagementClass mc = new ManagementClass("Win32_NetworkAdapter");
foreach (ManagementObject mo in mc.GetInstances())
{
     int index = Convert.ToInt32(mo["Index"]);
     string name = mo["NetConnectionID"] as string;
     if (!string.IsNullOrEmpty(name))
          textBox1.Text += name + Environment.NewLine;
}
Hans Olsson
  • 54,199
  • 15
  • 94
  • 116
  • `var nic = new ManagementClass("Win32_NetworkAdapter").GetInstances().OfType().Select(mo => mo["NetConnectionID"] as string).Where(mo => !String.IsNullOrEmpty(mo)).FirstOrDefault();` – abatishchev Aug 11 '10 at 11:01
2

This is a dirty way of doing it as it can be optimized by incorporating LINQ, etc

using System.Net.NetworkInformation;

List<NetworkInterface> Interfaces = new List<NetworkInterface>();
foreach (var nic in NetworkInterface.GetAllNetworkInterfaces())
{
    if (nic.OperationalStatus == OperationalStatus.Up)
    {
        Interfaces.Add(nic);
    }
}


NetworkInterface result = null;
foreach (NetworkInterface nic in Interfaces)
{
    if (result == null)
    {
        result = nic;
    }
    else
    {
        if (nic.GetIPProperties().GetIPv4Properties() != null)
        {
            if (nic.GetIPProperties().GetIPv4Properties().Index < result.GetIPProperties().GetIPv4Properties().Index)
                result = nic;
        }
    }
}

Console.WriteLine(result.Name);

you'll probably want to tailor your results by using the results from nic.GetIPProperties() and nic.GetIPProperties().GetIPv4Properties()

Greg Buehler
  • 3,897
  • 3
  • 32
  • 39
  • Hi entens, thanks a lot. Last question is: is it possible to get the IPv4 SubnetMask (as is Windows Network Connection Details "window") form the NetworkInterface class? – Mauro Sep 09 '10 at 07:32
  • You can access the `UnicastAddresses` array. Relevant info should be at the first index. So to get the subnet mask you would access `result.GetIPProperties().UnicastAddresses[0].IPv4Mask` according to the code in the answer. You might need to iterate over it to get what your looking for though. – Greg Buehler Sep 09 '10 at 14:49
1

A friend of mine (Ciro D.A.) had same problem. Playing around a bit with c#, we seemed to find a way to skip virtual (not really connected Ip): we looked for gateaway discarding not only those that did not have it, but also those who had a dummy (0.0.0.0) one. On my machine, these last where exactly two Vm-Ware virtual adapters.

public static void DisplayIPAddresses()
    {

        Console.WriteLine("\r\n****************************");
        Console.WriteLine("     IPAddresses");
        Console.WriteLine("****************************");


        StringBuilder sb = new StringBuilder();
        // Get a list of all network interfaces (usually one per network card, dialup, and VPN connection)     
        NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

        foreach (NetworkInterface network in networkInterfaces)
        {

            if (network.OperationalStatus == OperationalStatus.Up )
            {
                if (network.NetworkInterfaceType == NetworkInterfaceType.Tunnel) continue;
                //GatewayIPAddressInformationCollection GATE = network.GetIPProperties().GatewayAddresses;
                // Read the IP configuration for each network   

                IPInterfaceProperties properties = network.GetIPProperties();
                //discard those who do not have a real gateaway 
                if (properties.GatewayAddresses.Count > 0)
                {
                    bool good = false;
                    foreach  (GatewayIPAddressInformation gInfo in properties.GatewayAddresses)
                    {
                        //not a true gateaway (VmWare Lan)
                        if (!gInfo.Address.ToString().Equals("0.0.0.0"))
                        {
                            sb.AppendLine(" GATEAWAY "+ gInfo.Address.ToString());
                            good = true;
                            break;
                        }
                    }
                    if (!good)
                    {
                        continue;
                    }
                }
                else {
                    continue;
                }
                // Each network interface may have multiple IP addresses       
                foreach (IPAddressInformation address in properties.UnicastAddresses)
                {
                    // We're only interested in IPv4 addresses for now       
                    if (address.Address.AddressFamily != AddressFamily.InterNetwork) continue;

                    // Ignore loopback addresses (e.g., 127.0.0.1)    
                    if (IPAddress.IsLoopback(address.Address)) continue;

                    if (!address.IsDnsEligible) continue;
                    if (address.IsTransient) continue; 

                    sb.AppendLine(address.Address.ToString() + " (" + network.Name + ") nType:" + network.NetworkInterfaceType.ToString()     );
                }
            }
        }
        Console.WriteLine(sb.ToString());
    }
Community
  • 1
  • 1
0

You can get a list of them, but not the default (perhaps you can assume it is the first entry).

static void Main(string[] args)
{
  foreach (var nc in NetworkInterface.GetAllNetworkInterfaces())
  {
    Console.WriteLine(nc.Name);
  }

  Console.ReadLine();
}
leppie
  • 115,091
  • 17
  • 196
  • 297
  • Please don't take it personal, as the default should be taken programmatically, the list won't do the trick. If you say it is not possible and prove it, than I can take yours as an answer. Peace – Mauro Aug 11 '10 at 10:13
  • @Mauro: IT all depends what defines the default. What makes 'Local Area Connection' the default? I have never seen such a setting in Windows. The closest thing I can think of is the routing metric on a per network basis. – leppie Aug 11 '10 at 11:41