Get the properties of the current network connection - c#

How do you determine or examine the connection profile of the current network connection (if any)?
Specifically, I need to determine if the current connection is to a private or public network, and from there determine whether network discovery is turned on or off.
It seems like this information is readily available in a Windows Store app via the Windows.Networking.Connectivity.NetworkInformation.GetConnectionProfiles() or NetworkInformation.GetInternetConnectionProfile() functions, but this is a standard desktop app that must run on Win 7 and Server 2008 as well as Win 8 and Server 2012.
Enumerating the NICs on a machine is not a problem, but this doesn't solve my issue - I need to get the properties of the connection, not the physical device.
Is there an inbuilt way to do this with the .Net framework? Alternatively can it be done with WMI? Or as a crude alternative, can it be done by invoking the netsh command (although this seems to depend on the dot3svc and/or wlansvc services to be running)?

You can use Network List Manager API for that purpose, to use it from C# import Network List Manager Type Library.
Then you must enumerate all connected networks, because there can be more than one, for example right now I am connected to internet and VPN. Then for all connected networks call GetCategory() API, it returns NLM_NETWORK_CATEGORY (private, public or domain).
Here is the sample code (add using NETWORKLIST in use clauses) :
var manager = new NetworkListManager();
var connectedNetworks = manager.GetNetworks(NLM_ENUM_NETWORK.NLM_ENUM_NETWORK_CONNECTED).Cast<INetwork>();
foreach (var network in connectedNetworks)
{
Console.Write(network.GetName() + " ");
var cat = network.GetCategory();
if (cat == NLM_NETWORK_CATEGORY.NLM_NETWORK_CATEGORY_PRIVATE)
Console.WriteLine("[PRIVATE]");
else if (cat == NLM_NETWORK_CATEGORY.NLM_NETWORK_CATEGORY_PUBLIC)
Console.WriteLine("[PUBLIC]");
else if (cat == NLM_NETWORK_CATEGORY.NLM_NETWORK_CATEGORY_DOMAIN_AUTHENTICATED)
Console.WriteLine("[DOMAIN]");
}
Console.ReadKey();
For this to work one must add reference to COM Network List 1.0 Type Library, like this:
For Network Discovery you have to use Firewall API and reference COM library NetFwTypeLib and get INetFwProfile for active profile, then in services there are File sharing, Network Discovery and Remote Desktop services, and there is a bool flag if these are Enabled. Here is the example code : (just to warn you I didn't use below code in production I was just exploring this API)
Type objectType = Type.GetTypeFromCLSID(new Guid("{304CE942-6E39-40D8-943A-B913C40C9CD4}"));
var man = Activator.CreateInstance(objectType) as INetFwMgr;
/// get current profile
INetFwProfile prof = man.LocalPolicy.CurrentProfile;
Console.WriteLine("Current profile ");
ShowProfileServices(prof);
And the method that shows profile services.
private static void ShowProfileServices(INetFwProfile prof)
{
var services = prof.Services.Cast<INetFwService>();
var sharing = services.FirstOrDefault(sc => sc.Name == "File and Printer Sharing");
if (sharing != null)
Console.WriteLine(sharing.Name + " Enabled : " + sharing.Enabled.ToString());
else
Console.WriteLine("No sharing service !");
var discovery = services.FirstOrDefault(sc => sc.Name == "Network Discovery");
if (discovery != null)
Console.WriteLine(discovery.Name + " Enabled : " + discovery.Enabled.ToString());
else
Console.WriteLine("No network discovery service !");
var remoteDesktop = services.FirstOrDefault(sc => sc.Name == "Remote Desktop");
if (remoteDesktop != null)
Console.WriteLine(remoteDesktop.Name + " Enabled : " + remoteDesktop.Enabled.ToString());
else
Console.WriteLine("No remote desktop service !");
}

I know this question is super old, but I faced this problem recently - how to get Network Category (private or public) in C# using Windows.Network.Connectivity from Windows Runtime API.
There is almost everything related to networking but I could not find the Network Category.
The solution is NetworkTypes enum.
https://learn.microsoft.com/en-us/uwp/api/windows.networking.connectivity.networktypes?view=winrt-22000
Simply check if returned types has flag PrivateNetwork. If yes - then is't private, if not - it's public.
Example code below:
var adapters = NetworkInterface.GetAllNetworkInterfaces();
var upNetworkInterfaces = adapters.Where(x =>
x.Supports(NetworkInterfaceComponent.IPv4) &&
x.NetworkInterfaceType is NetworkInterfaceType.Ethernet or NetworkInterfaceType.Wireless80211);
foreach (var adapter in upNetworkInterfaces)
{
var hostname = NetworkInformation.GetHostNames()
.FirstOrDefault(x =>
x.IPInformation != null &&
string.Equals(x.IPInformation.NetworkAdapter.NetworkAdapterId.ToString(),
adapter.Id.Replace("{", string.Empty).Replace("}", string.Empty),
StringComparison.InvariantCultureIgnoreCase));
if (hostname is not null)
{
var networkTypes = hostname.IPInformation.NetworkAdapter.NetworkItem.GetNetworkTypes();
var privateNetwork = networkTypes.HasFlag(NetworkTypes.PrivateNetwork)
? NetworkAccessibilityLevel.Private
: NetworkAccessibilityLevel.Public;
}
}

Related

How do I determine which network adapter my computer is using?

I am using Pcat.Net. How do I determine which network adapter my computer is using C#, .Net, Pcat.net? GetMacAddress() extension method returns just the mac address of the network adapter, LivePacketDevice.AllLocalMachine also does not return information that can identify if the network adapter is being used by my computer.
You can try using NetworkInterface.GetAllNetworkInterfaces Method. You can get more details from below link:
https://msdn.microsoft.com/en-us/library/system.net.networkinformation.networkinterface.getallnetworkinterfaces(v=vs.110).aspx
I used the following code to determine if my computer was connected to the internet.
var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
var connectedNetworkInterfaces = networkInterfaces.Where(
counter=> counter.OperationalStatus == OperationalStatus.Up &&
(counter.NetworkInterfaceType != NetworkInterfaceType.Loopback || counter.NetworkInterfaceType != NetworkInterfaceType.Tunnel));
if(connectedNetworkInterfaces.Count() <1)
{
throw new Exception("The computer does not seem to be connected to the internet.");
}
var connectedNetworkInterface = connectedNetworkInterfaces.First();

MX records of a remote domain without NS information

I am building a SMTP diagnostics tool by using c# 4.0
If I know the IP Address of Primary NS of a domain, I can get MX,A and CNAME records.
So I can validate any email and run legal diagnostics commands. , if I can connect to mail server.
My problem is that I could not find a proper .NET solution to get Primary NS for a given domain.
I know there are some managed clients but I can not add them as reference to my solution or their source code is closed.
What is the differences of managed code and .NET for this issue , that managed code can query NS of a domain and .NET can not as stated here. ?
What is the proper way to implement such a kind of functionality ?
Regards
You can get the IP of your DNS server using IPInterfaceProperties.DnsAddresses. A code example can be found here: http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ipinterfaceproperties.dnsaddresses.aspx
You can then query that server using the component found here: http://www.codeproject.com/Articles/12072/C-NET-DNS-query-component
You can find the primary DNS server by querying for SOA records.
List<IPAddress> dnsServers = new List<IPAddress>();
NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface adapter in adapters)
{
IPInterfaceProperties adapterProperties = adapter.GetIPProperties();
IPAddressCollection adapterDnsServers = adapterProperties.DnsAddresses;
if (adapterDnsServers.Count > 0)
dnsServers.AddRange(adapterDnsServers);
}
foreach (IPAddress dnsServer in (from d in dnsServers
where d.AddressFamily == AddressFamily.InterNetwork
select d))
{
Console.WriteLine("Using server {0}", dnsServer);
// create a request
Request request = new Request();
// add the question
request.AddQuestion(new Question("stackoverflow.com", DnsType.MX, DnsClass.IN));
// send the query and collect the response
Response response = Resolver.Lookup(request, dnsServer);
// iterate through all the answers and display the output
foreach (Answer answer in response.Answers)
{
MXRecord record = (MXRecord)answer.Record;
Console.WriteLine("{0} ({1}), preference {2}", record.DomainName, Dns.GetHostAddresses(record.DomainName)[0], record.Preference);
}
Console.WriteLine();
}
Console.ReadLine();

Query Local IP Address

I have the need to know my actual local IP address (i.e. not the loopback address) from a Windows 8 WinRT/Metro app. There are several reasons I need this. The simplest is that in the UI of the app I'd like to show some text like "Your local network IP address is: [IP queried from code]".
We also use the address for some additional network comms. Those comms are perfectly valid because it all works if I look at the IP address in the Control Panel, then hard-code it into the app. Asking the user in a dialog to go look at the address and manually enter it is something I really, really want to avoid.
I would think it wouldn't be a complex task to get the address programmatically, but my search engine and StackOverflow skills are coming up empty.
At this point I'm starting to consider doing a UDP broadcast/listen loop to hear my own request and extract the address from that, but that really seems like a hackey kludge. Is there an API somewhere in the new WinRT stuff that will get me there?
Note that I said "WinRT app. That means the typical mechanisms like Dns.GetHostEntry or NetworkInterface.GetAllInterfaces() aren't going to work.
After much digging, I found the information you need using NetworkInformation and HostName.
NetworkInformation.GetInternetConnectionProfile retrieves the connection profile associated with the internet connection currently used by the local machine.
NetworkInformation.GetHostNames retrieves a list of host names. It's not obvious but this includes IPv4 and IPv6 addresses as strings.
Using this information we can get the IP address of the network adapter connected to the internet like this:
public string CurrentIPAddress()
{
var icp = NetworkInformation.GetInternetConnectionProfile();
if (icp != null && icp.NetworkAdapter != null)
{
var hostname =
NetworkInformation.GetHostNames()
.SingleOrDefault(
hn =>
hn.IPInformation != null && hn.IPInformation.NetworkAdapter != null
&& hn.IPInformation.NetworkAdapter.NetworkAdapterId
== icp.NetworkAdapter.NetworkAdapterId);
if (hostname != null)
{
// the ip address
return hostname.CanonicalName;
}
}
return string.Empty;
}
Note that HostName has properties CanonicalName, DisplayName and RawName, but they all seem to return the same string.
We can also get addresses for multiple adapters with code similar to this:
private IEnumerable<string> GetCurrentIpAddresses()
{
var profiles = NetworkInformation.GetConnectionProfiles().ToList();
// the Internet connection profile doesn't seem to be in the above list
profiles.Add(NetworkInformation.GetInternetConnectionProfile());
IEnumerable<HostName> hostnames =
NetworkInformation.GetHostNames().Where(h =>
h.IPInformation != null &&
h.IPInformation.NetworkAdapter != null).ToList();
return (from h in hostnames
from p in profiles
where h.IPInformation.NetworkAdapter.NetworkAdapterId ==
p.NetworkAdapter.NetworkAdapterId
select string.Format("{0}, {1}", p.ProfileName, h.CanonicalName)).ToList();
}
About the accepted answer, you just need this:
HostName localHostName = NetworkInformation.GetHostNames().FirstOrDefault(h =>
h.IPInformation != null &&
h.IPInformation.NetworkAdapter != null);
You can get the local IP Address this way:
string ipAddress = localHostName.RawName; //XXX.XXX.XXX.XXX
Namespaces used:
using System.Linq;
using Windows.Networking;
using Windows.Networking.Connectivity;

Hostname scanning in C#

Iv'e recently started a new job as an ICT Technician and im creating an Console application which will consists of stuff that will help our daily tools!
My first tool is a Network Scanner, Our system currently runs on Vanilla and Asset tags but the only way we can find the hostname / ip address is by going into the Windows Console tools and nslookup which to me can be improved
I want to create an application in which I enter a 6 digit number and the application will search the whole DNS for a possible match!
Our hostsnames are like so
ICTLN-D006609-edw.srv.internal the d 006609 would be the asset tag for that computer.
I wish to enter that into the Console Application and it search through every hostname and the ones that contain the entered asset tag within the string will be returned along with an ip and full computer name ready for VNC / Remote Desktop.
Firstly how would I go about building this, shall i start the project of as a console app or a WPF. can you provide an example of how I can scan the hostnames via C#, or if there's an opensource C# version can you provide a link.
Any information would be a great help as it will take out alot of issues in the workpalce as we have to ask the customer to go into there My Computer adn properties etc and then read the Computer name back to use which I find pointless.
Regards.
Updates:
*1 C# Version I made: http://pastebin.com/wBWxyyuh
I would actually go about this with PowerShell, since automating tasks is kinda its thing. In fact, here's a PowerShell script to list out all computers visible on the network. This is easily translatable into C# if you really want it there instead.
function Find-Computer( [string]$assetTag ) {
$searcher = New-Object System.DirectoryServices.DirectorySearcher;
$searcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry;
$searcher.SearchScope = 'Subtree';
$searcher.PageSize = 1000;
$searcher.Filter = '(objectCategory=computer)';
$results = $searcher.FindAll();
$computers = #();
foreach($result in $results) {
$computers += $result.GetDirectoryEntry();
}
$results.Dispose(); #Explicitly needed to free resources.
$computers |? { $_.Name -match $assetTag }
}
Here's a way you can accomplish this, although it's not the best. You might consider hitting Active Directory to find the legitimate machines on your network. The code below shows how you might resolve a machine name, and shows how to ping it:
static void Main()
{
for (int index = 0; index < 999999; index++)
{
string computerName = string.Format("ICTLN-D{0:000000}-edw.srv.internal", index);
string fqdn = computerName;
try
{
fqdn = Dns.GetHostEntry(computerName).HostName;
}
catch (SocketException exception)
{
Console.WriteLine(">>Computer not found: " + computerName + " - " + exception.Message);
}
using (Ping ping = new Ping())
{
PingReply reply = ping.Send(fqdn);
if (reply.Status == IPStatus.Success)
{
Console.WriteLine(">>Computer is alive: " + computerName);
}
else
{
Console.WriteLine(">>Computer did not respond to ping: " + computerName);
}
}
}
}
Hope that helps...

Get SSID of the wireless network I am connected to with C# .Net on Windows Vista

I'd like to know if there is any .Net class that allows me to know the SSID of the wireless network I'm connected to.
So far I only found the library linked below. Is the best I can get or should I use something else?
Managed WiFi (http://www.codeplex.com/managedwifi)
The method that exploits WMI works for Windows XP but is it not working anymore with Windows Vista.
I resolved using the library. It resulted to be quite easy to work with the classes provided:
First I had to create a WlanClient object
wlan = new WlanClient();
And then I can get the list of the SSIDs the PC is connected to with this code:
Collection<String> connectedSsids = new Collection<string>();
foreach (WlanClient.WlanInterface wlanInterface in wlan.Interfaces)
{
Wlan.Dot11Ssid ssid = wlanInterface.CurrentConnection.wlanAssociationAttributes.dot11Ssid;
connectedSsids.Add(new String(Encoding.ASCII.GetChars(ssid.SSID,0, (int)ssid.SSIDLength)));
}
We were using the managed wifi library, but it throws exceptions if the network is disconnected during a query.
Try:
var process = new Process
{
StartInfo =
{
FileName = "netsh.exe",
Arguments = "wlan show interfaces",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
process.Start();
var output = process.StandardOutput.ReadToEnd();
var line = output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(l => l.Contains("SSID") && !l.Contains("BSSID"));
if (line == null)
{
return string.Empty;
}
var ssid = line.Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[1].TrimStart();
return ssid;
It looks like this will do what you want:
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSNdis_80211_ServiceSetIdentifier");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("MSNdis_80211_ServiceSetIdentifier instance");
Console.WriteLine("-----------------------------------");
if(queryObj["Ndis80211SsId"] == null)
Console.WriteLine("Ndis80211SsId: {0}",queryObj["Ndis80211SsId"]);
else
{
Byte[] arrNdis80211SsId = (Byte[])
(queryObj["Ndis80211SsId"]);
foreach (Byte arrValue in arrNdis80211SsId)
{
Console.WriteLine("Ndis80211SsId: {0}", arrValue);
}
}
}
from http://bytes.com/groups/net-c/657473-wmi-wifi-discovery
there is some more information in How do I get the available wifi APs and their signal strength in .net?
(cross-posted in How to get currently connected wifi SSID in c# using WMI or System.Net.NetworkInformation windows 10?)
I found a rather old library dating back to 2014:
Microsoft.WindowsAPICodePack-Core version 1.1.0.2
Although it is not conforming to .NET Standard, this library integrates with my .NET Core 3.0 app, but obviously is not cross-platform.
Sample code:
var networks = NetworkListManager.GetNetworks(NetworkConnectivityLevels.Connected);
foreach (var network in networks) {
sConnected = ((network.IsConnected == true) ? " (connected)" : " (disconnected)");
Console.WriteLine("Network : " + network.Name + " - Category : " + network.Category.ToString() + sConnected);
}
You are going to have to use native WLAN API. There is a long discussion about it here. Apparently this is what Managed Wifi API uses, so it will be easier for you to use it if you do not have any restrictions to use LGPL code.
I wanted to do exactly this, and tried using ManagedWifi, as suggested in other answers. But that led to unresolvable Exceptions as per here:
Issues with using Managed WiFi (NativeWiFi API)
I solved this by switching to using SimpleWiFi entirely and ignored the ManagedWifi package.
Glancing at the source code, it looks like SW is a fixed reimplementation of some of the functionality in MW.

Categories