Programmatically retrieve disconnected network adapter information in .NET - c#

I have an application written in C# that needs to retrieve information like IP address, subnet mask from a disconnected network adapter.
I've tried using various methods such as WMI and the .NET NetworkAdapter class but they don't return any useful data when the network adapter is disconnected. I'm pretty sure Windows keeps this information somewhere, since I can apply network settings using netsh and it appears correctly in the Control Panel.
One thing that worked for me in XP was to parse the output of the netsh tool and it would return information even for a disconnected adapter. However, this doesn't seem to work on Windows 7.
Win XP output:
Configuration for interface "Local Area Connection 5"
DHCP enabled: No
IP Address: 169.254.0.128
SubnetMask: 255.255.255.0
InterfaceMetric: 0
Win7 output:
Configuration for interface "Local Area Connection 2"
DHCP enabled: No
InterfaceMetric: 5
Any ideas?

NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);
and/or
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\*
- List Interfaces
and then
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\\*\Parameters\Tcpip
current settings parameters
if DHCP - ON then only NetworkChange.NetworkAddressChanged because current IP is impossible to define

Related

Kestrel unable to start

When specifying a port to bind to with .UseKestrel() I get the errors listed below.. but if I remove the kestrel options everything works normally if I check the API from my browser.
I've tried binding to the port that my application defaults to with no ports chosen and I've tried checking netstat to actively avoid any ports that are in use. Nothing works but removing the options entirely. This is not replicated on my Mac or another Windows 10 machine. This device is Windows 10.
.UseKestrel(options =>
{
options.Listen(IPAddress.Loopback, 50470);
options.Listen(IPAddress.Any, 80);
})
: Microsoft.AspNetCore.Server.Kestrel[0]
Overriding address(es) 'http://localhost:50470/'. Binding to endpoints defined
in UseKestrel() instead.
crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
System.Net.Sockets.SocketException (10013): An attempt was made to access a
socket in a way forbidden by its access permissions
at
System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException
(SocketError error, String callerName)
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress
socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransport.
BindAsync() at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.
<>c__DisplayClass21_01.<<StartAsync>g__OnBind|0>d.MoveNext() `
Also check Darkthread's answer here: https://superuser.com/questions/1486417/unable-to-start-kestrel-getting-an-attempt-was-made-to-access-a-socket-in-a-way
We discovered that a port we had been using for a long time wasn't acccessible anymore because it had been reserved by Windows! You may wish to check reserved ports using this command:
netsh interface ipv4 show excludedportrange protocol=tcp
After Windows Update, some ports are reserved by Windows and applications cannot bind to these ports. please check this command for forbiden port on Os
netsh interface ipv4 show excludedportrange protocol=tcp
In my case, Removing invalid local IP and Port address combinations from the app's launchSettings.json did it.
The additional binding of port 80 in ".UseKestrel(options => { options.Listen(...) })" was causing the issue in my case.
When you run an ASP.NET Core application directly through Kestrel, without an additional reverse proxy like IIS or nginx, you will need to configure the hosting URL properly.
The problem was because, you did not follow Port sharing limitation in Kestrel web server.
When you to use the Kestrel web server, you should set unique port to app. (if you use the port 80, make sure no apps use this port).
and your app has enough permissions, too.
more info:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.2
I hope is useful.
Try Updating The Https Certificate
with this command. It worked for me!!
dotnet dev-certs https
The problem was with the additional binding of port 80, updating this corrected the problem.

Connect to webserver from outside LAN raspberry pi 3 windowsiot

I ran a tutorial including HTTP server app for raspberry pi 3.
Link here: https://incredibits.io/project/windows-10-iot-internet-of-things-tips/windows-10-iot-raspberry-pi-web-server
In my local network everything works perfectly. I run server, type in browser local IP of my raspberry (192.168.x.x) and "hello world" appears - great. But, I have an issue when i want reach my HTTP server outside from my LAN.
What i did:
1. forwarded port 80 in my router
2. opened port 80 in raspberry pi with below commands in PowerShell
netsh advfirewall firewall add rule name="Open 80" dir=in action=allow protocol=TCP localport=80
netsh advfirewall firewall add rule name="Open 80" dir=out action=allow protocol=TCP localport=80
checked if above commands works by typing
netsh advfirewall firewall show rule name="Open 80"
and i get that response:
Rule Name: Open 80
----------------------------------------------------------------------
Enabled: Yes
Direction: Out
Profiles: Domain,Private,Public
Grouping:
LocalIP: Any
RemoteIP: Any
Protocol: TCP
LocalPort: 80
RemotePort: Any
Edge traversal: No
Action: Allow
Rule Name: Open 80
----------------------------------------------------------------------
Enabled: Yes
Direction: In
Profiles: Domain,Private,Public
Grouping:
LocalIP: Any
RemoteIP: Any
Protocol: TCP
LocalPort: 80
RemotePort: Any
Edge traversal: No
Action: Allow
Ok.
checked if my port is visible as open with http://www.yougetsignal.com/tools/open-ports/ - it was CLOSED (ofcourse with server app run
ran exactly the same app in my notebook (with windows 10 ofcourse). I forwarded port 80 in router into my netbook, i checked if port is open - and it was OPEN. I type my external IP into browser and it works. I even try to do it from my smartphone to be sure and it also works.
I think that is a proof that a problem is in my raspberry - its settings
Make sure you have the "Internet (Client & Server)" capability selected in your app manifest. You can find this setting by opening the Package.appxmanifest file and clicking the Capabilities tab.
I solved it.
The problem was in my router setup. I have two NAT options (Virtual Server Setup and Port Triggering Setup) and i had settings like below:
Removing "web" setting in NAT - Port Triggering Setup solved my problem. My HTTP server running on raspberry pi became visible for outside world.
I don't know why this settings didnt block HTTP server running on laptop but this is different story. Problem with raspberry pi server - solved.

force WCF channel to ip address

I have two computers and they are connected via ethernet, i have set up an WCF connection and this all works ok, however when i host the same wcf on the local pc as the one i want to comunicate to and then do a wcf request via a channel, the request does not go to the remote pc but to my local pc. Is there a way to force a wcf request from a channel to go trough a specific ipaddress and not just go to any?
i'll try to explain how i use this:
there are two computers they are both similar and have two network adapters who have the same ipaddess and run thesame wcf software. so for example ipaddress for adapter 1 is: 10.10.10.1 and the other adapter is 10.10.10.2 on the same pc, and the other pc is similar. now these two pc need to communicate so i wire the two network adapters in cross example: pc 1 network adapter one goes to pc 2 network adapter 2. this so they are connected in 2 ways. so if i want to communicate with a simple socket from one to the other and back over the second adapter this all goes ok becouse i can bind a socket to a ipaddress and it will send it via the adapter it is bound to. but this does not seem to work with WCF. if i have two hosts on one pc, one for adapter 10.10.10.1 and one on 10.10.10.2 for the other adapter and i send a message to 10.10.10.2 that is on the remote pc, it will go in via the second network adapeter.
PC1 network adapter 1 (10.10.10.1) <--direct patch cable connection--> PC2 network adapter 2 (10.10.10.2)
PC1 network adapter 2 (10.10.10.2) <--direct patch cable connection--> PC2 network adapter 1 (10.10.10.1)
These connection arrows are direct connection patch cables!
all network adapters have a wcf hosted, and the software on both pc's is thesame.
this is all done for redundancy, more then two pc can be connected in a chain with this.
this is a little example of how i setup a request to the remote host:
public void Test()
{
string endPoint = "net.tcp://10.10.10.2:9985/connection";
NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
binding.ListenBacklog = 2000;
binding.MaxConnections = 2000;
binding.TransferMode = TransferMode.Buffered;
binding.MaxReceivedMessageSize = 104857600;
binding.SendTimeout = new TimeSpan(0, 1, 0);
binding.CloseTimeout = new TimeSpan(0, 0, 1);
binding.OpenTimeout = new TimeSpan(0, 0, 1);
binding.ReceiveTimeout = new TimeSpan(0, 1, 0);
//binding.HostNameComparisonMode = HostNameComparisonMode.Exact;
//binding.PortSharingEnabled = false;
ChannelFactory<Connection> pipeFactory = new ChannelFactory<Connection>(binding, new EndpointAddress(endPoint));
var pipeProxy = this.ChannelFactory.CreateChannel();
//fictional method: pipeProxy.SendRequestTunnelTo("10.10.10.1"); //this is the ipaddress that it should go out to however it goes out to "10.10.10.2"
//and this is another network adapter also on the local mashine and here is also a wcf host on
((IClientChannel)pipeProxy).AllowOutputBatching = true;
((IClientChannel)pipeProxy).Open();
pipeProxy.SystemRequest(); //do function
}
Ok, the issue here is routing. If windows thinks it can deliver the traffic directly to the other IP Address, it will do so.
In this case, it can't differentiate between the local 10.10.10.2 that it knows about and one that's on another network hidden behind a NAT.
The preferred solution is to not use the same subnet (so have 10.10.10.2 and 10.11.10.2 or similar), however that can sometimes require significant changes.
The next best option is to use the IP address of the NAT and have it port forward.
Say you have a setup like this (where the boxes with 2 ip addresses are NATing routers with both public and internal IPs)...
10.10.10.2 --- [10.10.10.1 | 1.2.3.4] --- Internet --- [5.6.7.8 | 10.10.10.1] -- 10.10.10.2
Then the machine on the left should try to connect to 5.6.7.8 which should forward connections to the machine on the right (and vice-versa with the right machine connecting to 1.2.3.4).
If you've got a WAN setup that makes the machines appear to be in the same network, that's as much of a problem as being on the same network. None of the routers on the network will be able to determine which 10.10.10.2 you mean,
If you weren't using exactly the same IP address, you might be able to force the issue using routing tables on your windows box. This can allow you to specify preferential routes so that all traffic for a given IP address goes out over the specified NIC. Unfortunately, beyond that point it's out of your control and entirely up to the network hardware how the packets are routed. If you have the ability to configure routing on the intermediate hardware, you could fix the route the whole way to the destination but this is usually an awful lot of work and likely to be broken when kit is updated/replaced as it's non-standard.
If you decide to look into forcing routes, start with the Windows route command
Edit: Re: Forcing routing over an interface...
the syntax is route add target mask gateway costmetric interfaceid
run route print at a command prompt and make a note of the interface id you want to use form the top of the output
then add a route like this:
route add 10.10.10.2 255.255.255.255 10.10.10.2 1 [interface id from above]
on my machine that would be
route add 10.10.10.2 255.255.255.255 10.10.10.2 1 11
Note that in this case we're telling it to use 10.0.0.2 as a gateway. I have no idea what the consequences of doing this will be as software attempting to access itself via a locally bound port might get very confused. Last caveat: I don't have a pair of physical machines to hand that I can test this on, and VMs don't really count as their networking is slightly different.
We're providing a cost metric of 1. This should give it a very high priority meaning it should be chosen above all other routes to that IP address.
The route will be lost when the system reboots. You can use a -p flag after route add to make the route persistent. I suggest you don't do this until you're sure it's working as intended.
2nd Edit: I think you're heading down a rabbit hole here. While it may be possible to trick the system into working this way, it's definitely not a common usage and I haven't been able to find anything that says it's supported.
It seems like your fundamental problem is that you've got no way to negotiate before assigning IP addresses as you have no network connectivity.
Some thoughts...
Sharing the IP is not going to be robust, so decouple from it. Instead of using a fixed IP in the url, determine the other IP address programatically.
You could have two builds, one which uses .1/.2 and the other which uses .3/.4. Any build1 could then talk to any build2 but not 1-1 or 2-2. This is a bit awkward but would work with little effort on your part.
Better would be to assign unique IPs to every machine you build, then provide a way to detect the other machine's address. Service location protocol is a likely candidate for this approach. Once you know the IP address you need to communicate with, configuring WCF should be trivial.
If assigning unique IPs is problematic, you could potentially have DHCP servers on all nodes but only turn them on if another one doesn't exist on that network (pair). That way, every machine would end up with valid IP addresses with no prior configuration.
Your endpoint address needs to identify the IP address you are targetting.

WinCE 6.0, work with GPRS/WiFi

I'm working on a project, which should connect to servers through wifi/gprs. Project is an application for Windows CE 6.0 device, I'm writing in Visual Studio 2008 on C#.
I have two severs to work with. The first I have to connect via wifi, second - via gprs. So I need to know, how can I change the method of connecting between wifi and gprs?
I found and tried this way: I turn on both wifi and gprs on my device. So I work via wifi because it has a higher priority. When I need to work via gprs, I turn off wifi (SetDevicePower function). But when I turn wifi on, it doesn't connect back to my Preferred Network.
Also I heard about the way to change priority between gprs/wifi in OS priority table programmatically, but I didn't find any information about how to do this.
I hope you can help me.
I would use the route command from a shell.
lets assume
server1 ip: 123.123.123.1
server2 ip: 123.123.123.2
wifi ip : 192.168.1.101
gateway: 192.168.1.1
gprs ip : 10.1.2.3
gateway: 10.1.1.1
Now you can excute in a command prompt
route add 123.123.123.1 MASK 255.255.255.255 192.168.1.1
and
route add: 123.123.123.2 MASK 255.255.255.255 10.1.1.1
This should route all trafic to server 1 over wifi and to server 2 over gprs, without changing a single line of code in your app.
You can verify it worked with
tracert 123.123.123.1
tracert 123.123.123.2
However, you could use your app to periodically perform this task (I assume gprs ip could change from time to time) with Process.Start(...)
- delete route 1
- add route 1
- delete route 2
- add route 2
You even could specify the interface with the IF 2 switch (route list prints the interface id for your network cards).
Another interesting post to read is this one: http://ce4all.blogspot.com/2007/05/routing-ip-traffic-via-specified.html
The author uses the GetAdapterAddresses() and CreateIpForwardEntry() P/Invokes:
http://msdn.microsoft.com/en-us/library/ms927384.aspx
http://msdn.microsoft.com/en-us/library/ee495149%28v=winembedded.60%29.aspx

No response from sever on external IP in client-server IM app

I'm following a tutorial # http://www.geekpedia.com/tutorial239_Csharp-Chat-Part-1---Building-the-Chat-Client.html to try and gather the basics of networking. For those not wanting to hit the jump, it's a quick tut demonstrating how to program a simple client-server-model chat application.
When I try and run the code in the tut, it works fine as long as both the client and the server are on the same network, but the second I try and do it externally (getting a mate to run the client app, and running the server app my side), it all goes to pot. The fact that the code works when in the same network leads me to believe that it's not a coding issue, but an issue with the way my network is set up.
I'm trying to run the server on my IP address at port 21719, which I have opened, but still other people can't connect to my server, not able to get any form of response at all.
The code (from the tut) that is being used for the server to listen to connections is:
public void StartListening()
{
IPAddress ipaLocal = ipAddress; //ipAddress is parsed from txtIP
tlsClient = new TcpListener(ipaLocal, 21719);
tlsClient.Start();
ServRunning = true; //for the running loop
// Start the new tread that hosts the listener
thrListener = new Thread(KeepListening);
thrListener.Start();
}
Now, the tutorial does actually point out that
IPAddress ipaLocal = ipAddress;
Will cause issues on some configurations, and I'm beginning to fear that my configuration may be included in that.
So, does anyone have any solution for me?
Thanks,
Sam
What is the local IP address that you're using? (ipAddress) If it's 127.0.0.1, that's not correct (I don't know how it would work internally either, but Windows seems to use magic from time to time). Also, if you have multiple NICs in your local machine, maybe the port forwarding is only set up to forward to one of them, and you're using the IP of the other?
If that's not the problem, here are a few generic suggestions:
Grab a copy of netcat. It's a small network testing util whose only job is to form a simple TCP connection. That will allow you to eliminate your code as a variable in all this. If netcat can form a connection, then you know the problem is your code. If not, you've confirmed that it's your router.
You can use WireShark (or TShark) to look for ICMP packets. Capture ICMP packets on the remote machine. If you get "Destination Unreachable" from the router, you've again proved that it's your router.
As Spencer said you need to make sure Port Forwarding is setup on your router, to forward all packets that come in on port 21719 to your internal machine. As for exactly how to do that, it's hard to say without knowing what type of router.
Are you having people use your external (internet) IP address? (See yours here.)
Have you pinholed your router to forward all communications from port 21719 to your server?
Some tips:
What kind of operating system are you using? Please check the Scope and/or Profiles (under Advanced tab) of your firewall rule.
While your friend is trying to telnet to the port (connect to the im server) monitor the traffic using Wireshark or Network Monitor (Wireshark have problems with Vista and Win 7). If you don't see anything hitting your machine the problem is probably on the router side. Double check the settings - you said you set the forward rule (NAT) but did it also set the rule on firewall of your router?

Categories