I have a component that (by part) uses an internet connection. I wrote some UnitTests to ensure that to component is working. However, I would like to test the behaviour of the component without internet connections.
So, my goal is to somehow temporary disable internet, or the whole internet connection, and reactivate after test.
I would disable\enable like here local are connection in test initialization
[ClassInitialize]
SelectQuery wmiQuery = new SelectQuery("SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionId != NULL");
ManagementObjectSearcher searchProcedure = new ManagementObjectSearcher(wmiQuery);
foreach (ManagementObject item in searchProcedure.Get())
{
if (((string)item["NetConnectionId"]) == "Local Network Connection")
{
item.InvokeMethod("Disable", null);
}
}
[ClassCleanup()]
// Enable local area connetcion
There are many ways in which the system could have "No Internet" and the answer really depends on what you mean.
As the accepted other answer suggests, you could simply disable the network interface. That guarantees you have no internet, but the computer also will know it has no network either.
A couple other options are
To remove your Default Gateway (this may require setting static IP settings in the control panel, though I'm sure you could do it programmatically as well)
This way, the computer still thinks it's connected, but it won't have any network access except on the local subnet
Remove DNS server settings, see above link.
This way, the computer has direct IP based access but to a regular user it would appear as if there was "no internet."
Whilst not a direct answer to your question I believe you may find some use in this tool - https://jagt.github.io/clumsy/download
I've used it at work to simulate different network conditions for an mobile app that I'm currently working on. It is possible to completely disable the network connection by setting packet drop to 100%.
Related
I'm trying to share internet over a network adapter on windows-7 using NetConLib.dll.
In order to do this, internet sharing should be disabled on all other network adapters.
In normal cases. I can iterate all the installed network adapters and disable sharing on them.
However, sometimes when the network device is unplugged, the adapter is hidden in windows.
But it's properties is still present inside windows registry.
I can't even find the adapter in Control Panel.
And off course, can't iterate it using the NetConlib library.
Possible scenarios.
The easiest way, would be using a windows command to disable internet
sharing on all the adapters. Regardless of their visibility.
Is that possible in anyway ?
The second solution is to recover the network adapter from hidden state, so that
NetConlib could iterate through it and disable it.
I tried to find the adapter's properties in windows registry and unhide it, But couldn't find anything.
Any solution?
#erm3nda.
Thank you for the informative answer. Although it didn't fix the problem I'm facing with NetConlib.
SC config correctly shuts down ICS service. But the shared network adapter continues on being flagged as Shared1. So ICS service being turned off doesn't seem to affect the adapters' settings.
Quite interestingly; when you try to share another adapter using windows GUI (Right click on adapter -> Properties -> Share), a message is prompted telling you
"there is another adapter being shared currently, your new adapter
will be shared instead". You click ok and it's done.
I've been digging the entire internet the whole afternoon to see if there are other solutions using CMD commands.
Maybe there could be a away to share an adapter with a command. This way windows would handle disabling other adapters. In a similar way as when the GUI is used.
1: Windows tells you which adapter is currently being shared in Control Panel\Network and Internet\Network Connections).
Possible solution 1: Disable ICS at all.
You can stop ICS service, so none of the connections will be at sharing status and will not conflict with NetConLib.dll. (Not sure about the hidden ones, you must try).
You can manage it from command line using:
net start SharedAccess or net stop SharedAccess
Also, if you need to disable it from reboot to, must disable service using:
sc config SharedAccess start= disabled
Notes and references:
Executing sc config will display "start= OPTIONS" and some other.
The space below = and option is mandatory. You can check result
running services.msc from Run or cmd.
Exec net to display OPTIONS. The name of service is on the
services.msc list under "Name of the service" label from ICS service.
netsh routing is not on Win7 anymore, so you only can
start/stop/enable/disable but not enable for a particular Interface.
You must set by handMouse... This not work under Win7 ICS into XP
system
Sc Config command was from this cool documentation i found
today.
Possible solution 2: Remove ghost interfaces?
I try also around Adapters and interfaces into registry and do not see anything about show/hid/ghost/enabled or similar. I also search here kb 314053 for registry conf.
I can suggeest try Possible solution 1 :) or directly delete hidden/ghost adapters.
You can do it by two ways. Devcon remove option will delete also drivers.
Device manager: Run set devmgr_show_nonpresent_devices=1 and run
devmgmt.msc. You must see over "See" a "Show hidden" option. The
show_nonpresent must reveal also hidden devices, not only inactive.
kb 269155 - You must click over #link named "Let me fix it
myself"
With devcon.exe utility: This is a device manager tool from Windows
with power moves. You will find a very big and helpfull guide
here.
Basic usage for find netcards devcon findall =net, also you can devcon findall =net *ndis* to list all ndis cards.
Basic usage for remove will be devcon remove =net *ndis* to remove all ndis card type.
I try also enable/disable commands but nothing has change into my network interfaces list.
I removed my own wifi card to test it :) Anyway, i didn't notice any option about "Unhide" feature for such devices from conections panel.
NEW EDIT (Too much verbose, right?)
I found a tool called ics-manager from this superuser post. - read answer #3
You can download directly from utapyngo's Git project page.
It's based on .Net Framework 4. Yo must download and run the build.bat to compile both exe's (You got also the C# source). The solution is to get only the compiled IcsManager.exe (command line version) with the only needed library IcsManagerLibrary.dll.
This app is using also NETCONLib.dll, so you can use it, or read the source to see wich is the correct function you need to do it and implement on your development.
If you got problems with the Ip range "192.168.137.1", you can set from Registry permanently, or run netsh interface ipv4 set address name="YOUR-INTERFACE" source=static addr=192.168.2.1 mask=255.255.255.0. You will got ugly errors from launch the netsh interface using tilde or accutes into interfaces name (Spanish default ethernet name is "Conexión de áreal local"... a joke).
Note: You can pack all at once, using first a Bat to call the IcsManager.exe' with the arguments needed, then launch the netsh configure command later from same batch to full configure.
Comment: About the prompt when try to overwrite an shared connection, it's surely because only one could be shared. I also see, they are configured as Public and Home to set the pair, but i can't find where's the registry key...Also make some exports from reg and using Diffs, no lucky. I got stuck at diffs and start to search "ICS C++ and C#" on Google, then found it.
Extra: I got the netsh it into a bat, and it's launched for Windows Task when a Ethernet cable is plugged (Here is the howto) in order to use with Android Reverse Tethering. As you can see, im too interesting into your question because it makes me research better and also learned a lot.
Sorry about my bad English. Im not.
Regards.
I found that by going into Device Manager, you can show the Hidden Devices and try to disable the internet sharing on the adapters.
Hopefully this is near what you are asking. Good luck!
Atm
Source: http://msdn.microsoft.com/en-us/library/windows/hardware/ff553955%28v=vs.85%29.aspx
I'm about 10 years late to the party, but the complete solution to this problem is nowhere else on the internet. In order to disable internet connection sharing for a device that is unplugged or uninstalled you will need to:
Clear the shared access registry
Clear the WMI sharing entry for the device
Disable sharing through the netcon library
Clearing the registry:
You need to set two registry keys to 0xFFFFFFFF:
HKLM:\Software\Microsoft\Windows\CurrentVersion\SharedAccess\PrivateIndex and
HKLM:\Software\Microsoft\Windows\CurrentVersion\SharedAccess\PublicIndex
For example in powershell:
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\SharedAccess" -Name "PrivateIndex" -Value 0xFFFFFFFF
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\SharedAccess" -Name "PublicIndex" -Value 0xFFFFFFFF
Clear the WMI sharing entry for the device:
For every HNet_ConnectionProperties you must ensure IsIcsPublic and IsIcsPrivate is set to false. You can view which interface has IsIcsPublic or IsIcsPrivate set in powershell:
Get-CimInstance -ClassName 'HNet_ConnectionProperties' -Namespace 'root\Microsoft\HomeNet' | Format-Table
Unfortunately, the Set-CimInstance cmdlet does not appear to work in this scenario, so we have to choose another language. Fortunately, code to set these values to false can be found online. For example, here is some C# that performs this task (attibuted to utapyngo)
public static void CleanupWMISharingEntries()
{
var scope = new ManagementScope("root\\Microsoft\\HomeNet");
scope.Connect();
var options = new PutOptions();
options.Type = PutType.UpdateOnly;
var query = new ObjectQuery("SELECT * FROM HNet_ConnectionProperties");
var srchr = new ManagementObjectSearcher(scope, query);
foreach (ManagementObject entry in srchr.Get())
{
if ((bool)entry["IsIcsPrivate"])
entry["IsIcsPrivate"] = false;
if ((bool)entry["IsIcsPublic"])
entry["IsIcsPublic"] = false;
entry.Put(options);
}
}
... and some vbscript (attributed to billchaison):
set WMI = GetObject("WinMgmts:\root\Microsoft\HomeNet")
set objs1 = WMI.ExecQuery("SELECT * FROM HNet_ConnectionProperties WHERE IsIcsPrivate = TRUE")
for each obj in objs1
obj.IsIcsPrivate = FALSE
obj.Put_
next
set objs2 = WMI.ExecQuery("SELECT * FROM HNet_ConnectionProperties WHERE IsIcsPublic = TRUE")
for each obj in objs2
obj.IsIcsPublic = FALSE
obj.Put_
next
Disable sharing through the netcon library:
This part you probably already know, but for completeness, here is some powershell that does it:
regsvr32.exe /s hnetcfg.dll
$NetShare = New-Object -ComObject HNetCfg.HNetShare
foreach ($RawConnection in $NetShare.EnumEveryConnection) {
$Sharing = $NetShare.INetSharingConfigurationForINetConnection.Invoke($RawConnection)
$Sharing.DisableSharing()
}
The documentation for the relevant COM APIs for netcon can be found on MSDN
is there any way to check internet connection status in linux using mono
If it's desktop app, you could query NetworkManager (which is the network connection manager on most Linux desktops) over d-bus, using the NDesk.DBus library.
See Banshee for an example: http://git.gnome.org/cgit/banshee/tree/src/Core/Banshee.Services/Banshee.Networking/NetworkManager.cs
Apart from what Michael already suggested for a desktop application, you can also do something like:
foreach (NetworkInterface ni in NetworkInformation.GetAllNetworkInterfaces ()) {
// Check that any or all of:
// -ni.OperationalStatus == OperationalStatus.Up
// -that ni.NetworkInterfaceType is ethernet or wireless80211
// -ni.GetIPProperties() has a gateway and a DNS server
// ...
}
No matter what you end up using, it won't be reliable.
I see it all the time with Windows Vista and 7 at home. I use a home network, so my computers are always "connected." However, they are not always connected to the Internet.
That said, I would recommend checking the network interfaces as Gonzalo said. It is your best bet.
I would not rely on NetworkManager being present. I hate that thing and turn it off whenever I can. It is huge, ungainly, has an ugly name, relies on junk like HAL and DBUS. Early versions permanently put me off because they didn't work unless you were logged in to a GUI. It also collected bug work-arounds for wifi that were completely ridiculous in an open-source operating system that should have just fixed the original bugs. That led to other wifi managers and the command-line not being able to work properly and people being told to use NetworkManager, only because no one ever bothered to fix the actual bug!
You could try to open your connection as it is needed. If that fails display an error message.
Alternatively, if you really need a general check (e.g. at application start) you could try to make HTTP requests to one or more omnipresent websites like google.com. (Or what ever protocol you mean by "internet").
Check out HttpWebRequest.
I have a web application that you can use to import information from another site by giving it a url. It's been pointed out that you could use this feature to access a private site that is hosted on the same web server.
So...
How can I check that a given url is publicly accessible (whether on the same web server or somewhere different)?
FIX:
I ended up doing this:
protected static bool IsHostWithinSegment(string Host)
{
Ping pinger = new Ping();
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
PingOptions options = new PingOptions();
options.Ttl = 1;
PingReply reply = pinger.Send(Host, 1000, buffer, options);
return reply.Status == IPStatus.Success;
}
private static Uri BindStringToURI(string value)
{
Uri uri;
if (Uri.TryCreate(value, UriKind.Absolute, out uri))
return uri;
// Try prepending default scheme
value = string.Format("{0}://{1}", "http", value);
if (Uri.TryCreate(value, UriKind.Absolute, out uri))
return uri;
return null;
}
The only requirement of mine that it doesn't fulfil is that some installations of our product will exist alongside each other and you won't be able to import information across them - I suspect this will require using a proxy server to get an extrenal view of things but as it's not a requirement for my project I'll leave it for someone else.
-- I've just realised that this does entirely solve my problem since all the publicly accessible urls resolve to virtual or routable ips meaning they hop.
Run a traceroute (a series of pings with short TTL's to the address, if the firewall(s) is(are) one of the hops then it's visible from outside the organisation so should be acceptable.
System.Net.NetworkInformation has a ping class that should give you enough information for a tracert like routine.
This does sound like a big hole though, another approach should probably be considered. Preventing the machine that runs this prog. from accessing any other machine on the internal network may be better - a kind of internal firewall.
I've added a simple traceroute, since you like the concept:-
class Program
{
static void Main(string[] args)
{
PingReply reply = null;
PingOptions options = new PingOptions();
options.DontFragment = true;
Ping p = new Ping();
for (int n = 1; n < 255 && (reply == null || reply.Status != IPStatus.Success); n++)
{
options.Ttl = n;
reply = p.Send("www.yahoo.com", 1000, new byte[1], options);
if (reply.Address != null)
Console.WriteLine(n.ToString() + " : " + reply.Address.ToString());
else
Console.WriteLine(n.ToString() + " : <null>");
}
Console.WriteLine("Done.");
System.Console.ReadKey();
}
}
Should be good enough for a reliable local network.
Only two things spring to mind.
Have a trusted external server verify the visibility of the address (like an HTTP Proxy)
Check the DNS record on the site -- if it resolves to something internal (127.0.0.1, 10.*, 192.168.*, etc) the reject it -- of course, this might not work depending on how your internal network is set up
Not knowing if this is on a 3rd-party hosting solution or inside your/your company's internal network makes it hard to say which solution would be best; good luck.
EDIT: On second thought, I've canceled the second suggestion as it would still leave you open to DNS rebinding. I'll leave this here for that purpose, but I don't think it's a good idea.
That said, if you have some ability to control the network makeup for this server, then it should probably live in its own world, dedicated, with nothing else on its private network.
Check the URL address, and see if it matches your server address?
edit: or check against a range of addresses...
But all this does not answer the question: could the client access it?
Maybe some script in the browser to check that the url is accessible, and informing the server of the result.
But the user could edit the page, or simulate the result...
Have the client read the url contents and send it back to the server, instead of having the server fetch it?
Don't worry about the public accessibility of anyone else's web assets, that question does not have a definite answer in all cases. Just try not to compromise the access policy to your own (or your customer's etc.) web assets.
Use the existing access control mechanisms to control the web application's access. Don't just consult the access control mechanisms in order to duplicate them in the web application. That would be relying on the web application to refrain from using its full access - a false reliance if the web application ever gets compromised or if it simply has a bug in the access control duplication functionality. See http://en.wikipedia.org/wiki/Confused_deputy_problem.
Since the web application acts as a deputy of external visitors, treat it if you can as if it resided outside the internal network. Put it in the DMZ perhaps. Note that I'm not claiming that the solution is one of network configuration, I'm just saying that the solution should be at the same level at which it is solved if the visitor would try to access the page directly.
Make the web application jump through the same hoops the external visitor would have to jump. Let it fail to access resources the external visitors would have failed to access, too. Provide an error page that does not let the external visitor distinguish between "page not found" and "access denied".
The wininet dll has a function InternetCheckConnection
Allso look at InternetGetConnectedState
You are asking the wrong question. You should be asking, how can I limit access to a given URL so that only people on a certain network can access it?
The fact is, that you cannot test in the way that you wanted, because you likely do not have access to other sites on the same web server, in order to run a script that attempts to retrieve a URL. It is better to deny all access except the access that you wish to allow.
Perhaps a firewall could do this for you, but if you want more finegrained control, so that some URLs are wide open, and others are restricted, then you probably either need help from the web server software or you need to code this into the application that serves the restricted URLs.
If you are worried that your web application might be used to transfer data that comes from other servers protected by the same firewall which protects you, then you should change the application to disallow any URLs where the domain name portion of the URL resolves to an IP address in the range which is protected by the firewall. You can get that address range information from the firewall administrator.
This is only really a concern on in-house systems because in 3rd party data centers there should not be any private servers that don't have their own protection. In other words, if it is at your company, they may expect their firewall to protect the whole data center and that is reasonable, if a bit risky. But when you rent hosting from a 3rd party with a data center on the Internet, you have to assume that everything inside that data center is equally as potentially hostile as the stuff outside.
I have a C# application that should only be used when the network is down, but am afraid users will just unplug the network cable in order to use it.
Is there a way to detect if the network cable has been unplugged?
Thanks
You could use IsNetworkAlive(). Although technically it doesn't check link state, it's probably better since it can detect wireless and dialup connectivity as well. Here's an example:
using System.Runtime.InteropServices;
class Program
{
[DllImport("sensapi.dll")]
static extern bool IsNetworkAlive(out int flags);
static void Main(string[] args)
{
int flags;
bool connected = IsNetworkAlive(out flags);
}
}
The flags param returns whether the connection is to the internet or just a LAN. I'm not 100% sure how it knows, but I'd bet it just looks to see if there is a default gateway set.
In my humble opinion, there is no certain way to distinguish between a network down and an unplugged cable. And even if there is a way, there is also a way to work around it.
Let's assume that you have a solution and let's look at some situations:
There is no network traffic, the cable is not unplugged from the computer: it may be unplugged at the other end.
There is no network traffic, the cable is unplugged: but this has always been the case, the laptop is connected via Wi-Fi, which is down at the moment.
There are several network interfaces, only the one connected to WAN is down: should your app work?
The network is actually down, in the sense you mean: someone has managed to reboot the router continuously for using your app.
You can use this
System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()
Some network drivers are able to detect this. However you'd need to use unmanaged code to access them from C# (which may be very difficult/impossible) and the solution may not be reliable for all network adapters.
The network card will report this as a state. Tools like ethtool can display this (Link up), but that is only available for Linux/Unix.
If you can enumerate the installed network cards with a Windows API, I'm sure you'll find the flag for "link up" somewhere in there.
You could register a delegate to the NetworkChange Class. When a network change occurs, it doesn't actually notify you what happened, so you could list all the network interfaces (Using NetworkInterface), filter the ones that concern you (By checking there properties) and check their operational status.
If I really wanted to use your application and whether it will work depends on something like this, I would always be able to find a way to trick your application. Are you sure there's no better solution?
How about pinging the default gateway?
There is some code here that gets the default gateway from the registry.
To detect 'Is network cable plugged in a machine?', below piece of code works.
class Program
{
private static void Main(string[] args)
{
bool isNetworkCableConnected = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
}
}
I wish to write a windows app which does something when I become disconnected from the internet. I was thinking of writing a very simple C#/Delphi app which simply polls every 20 seconds to see if I'm still connected.
If I have to poll I'd really like a solution other than trying to download a web page from the net. I can't assume that a download attempt failing means "not online" since there may be other apps eating up the internet bandwidth. Plus I'm sure constantly connecting/downloading from a particular site is going to get my IP blocked.
I'm sure there's a way to tell if you're online without downloading/connecting to a remote server but I'm not sure how.
Beware that connected to the Internet does not really mean anything: what if you are connected to your ISP, but the backbone is down, or all the sites you want to access are in a country that went off the grid like recently? Having a connection does not mean you can do what you want.
Anyway, as stated before you can use the InternetGetConnectedState API to test that you have a valid Internet connection configured.
As an example, the following routine told me correctly I had a LAN Connection, but failed to detect that I had my ZoneAlarm firewall set to block "All Internet Activity", which means that you effectively lost all Internet connectivity.
Delphi routine:
procedure IsConnected;
var
dwFlags: DWORD;
begin
if InternetGetConnectedState(#dwFlags, 0) then
begin
if (dwFlags and INTERNET_CONNECTION_MODEM) = INTERNET_CONNECTION_MODEM then
ShowMessage('Modem Connection')
else
if (dwFlags and INTERNET_CONNECTION_LAN) = INTERNET_CONNECTION_LAN then
ShowMessage('LAN Connection')
else
if (dwFlags and INTERNET_CONNECTION_PROXY) = INTERNET_CONNECTION_PROXY then
ShowMessage('Connection thru Proxy')
else
if (dwFlags and INTERNET_CONNECTION_OFFLINE) = INTERNET_CONNECTION_OFFLINE then
ShowMessage('Local system in offline mode')
else
if (dwFlags and INTERNET_CONNECTION_CONFIGURED) = INTERNET_CONNECTION_CONFIGURED then
ShowMessage('Valid connection exists, but might or might not be connected')
end
else
ShowMessage('Not Connected. Try to connect and risk of being prompted to dial into another Internet Service Provider.');
end;
Call the InternetGetConnectedState function. This knowledgebase article explains how to do it.
It looks like it can be done by using the method described here: http://www.csharphelp.com/archives3/archive499.html