Is there any way to detect the message IP conflict? I will be using this in a thread in my program.
If your problem is locating the alert window saying there is a duplicate IP on the network, I suggest your use the API to enumerate all windows and see if the alert window is there.
You may be helped by Visual Studio tool Spy++ to see the characteritics of the window.
The question is not particular precise and old but I'll give it a go anyways because I wondered what I can do about such problems since I'm writing an app that manipulates IP addresses on the PC in order to launch applications which are dependent on specific addresses.
If anyone else has the same question I suggest trying to avoid any conflicts in the first place.
The thing is that setting an IP address is an administrative task and should only be done "free-handed" by people who know what they are doing. If you are setting IP addresses via code is is your task as a developer to check if the address to set is valid and not already known on the network.
First: Query DNS if this address belongs to a host other than the one the app runs on
Second: If DNS doesn't know about the address, send Ping requests to the address.
See: Check Local Ip Address
public static bool IsLocalIpAddress(string host)
{
try
{
// get host IP addresses
IPAddress[] hostIPs = Dns.GetHostAddresses(host);
// get local IP addresses
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
// test if any host IP equals to any local IP or to localhost
foreach (IPAddress hostIP in hostIPs)
{
// is localhost
if (IPAddress.IsLoopback(hostIP)) return true;
// is local address
foreach (IPAddress localIP in localIPs)
{
if (hostIP.Equals(localIP)) return true;
}
}
}
catch { }
return false;
}
If you want to "listen" for conflicts, the WMI and EventLog is the way to go. The EventLog is pretty much the first place where such conflicts surface and it is easy to monitor.
Related
In my program I am getting the local machine's public IP address like this
public static IPAddress getIPAddress()
{
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
foreach (IPAddress addr in localIPs)
{
if (addr.AddressFamily == AddressFamily.InterNetwork)
{
return addr;
}
}
return null;
}
and it worked fine where I live.
Right now I am at a friend's house, and I am connected to internet via Wi-Fi, and this code does not give me my external IP address, it has probably something to do with the router settings, but I am not very familiar with networks...
The router is TP-LINK, and I can access its settings like this
By the way, the 8080 port is exactly the one I need, I only need to be able to access my public IP. How can I do it?
You can make a request to a site like http://icanhazip.com/ to get your external IP address
var request = WebRequest.Create("http://ipv4.icanhazip.com/");
var response = request.GetResponse();
var dataStream = response.GetResponseStream();
var reader = new StreamReader (dataStream);
string myIPAddress = reader.ReadToEnd();
More info here: https://msdn.microsoft.com/en-us/library/456dfw4f%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
There is no sure-fire way to do this that will work 100% of the time. However, there are two methods that will work most of the time.
The first is to use an external STUN server. It's relatively easy to add a configuration entry to your software to allow the user to change the STUN server if this server ever changes or goes down, they can choose another one.. there are many of them out there. A STUN server returns the users IP address back to the caller and is used by most VOIP devices.
The second is to use the built-in Universal Plug-n-Play framework (UPnP) to ask the router for its IP Address. This one, however, depends on the router supporting UPnP and it not being disabled. Additionally, UPnP may not work within a corporate network as there are several layers of routers and firewalls usually. Still, for home users this is typically a good option. There is a .NET based UPnP library here that utilizes the built-in COM based UPnP components in Windows:
http://managedupnp.codeplex.com/
I don't have any examples of how to implement this, but it supposedly has a good documentation library.
What you want is not possible. A router is a proxy of sorts, whereby all traffic must pass through it. The external IP address for all internal devices (including PCs, laptops, tablets, etc), will be the same--the internal IP address what is different. The only way for a device to know its external IP address is either to query the router (which might not be possible), or to query an external source. The port forwarding page you have in your post only shows the router where to redirect incoming traffic on that port, but it will tell the PC nothing as to what its external IP address is--because, generally, to the PC the external IP address is irrelevant.
I'm trying to get mac address from the client's machine that browse my web site, I've been used this:
using System.Management;
class Sample_ManagementClass
{
public static int Main(string[] args)
{
ManagementClass objMC = new
ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if (!(bool)objMO["ipEnabled"])
continue;
Console.WriteLine((string)objMO["MACAddress"]);
}
}
}
But it is not recognized Management Namespace, so what should I do?
it's unfortunately not possible to reliably get the mac address of the client machine due to firewalls, proxies and ISP generic addresses being given. However, you can make a stab at getting the ip address by using:
var remoteIpAddress = Request.UserHostAddress;
However, this may or may not actually represent the client machine and is more likely the ISP gateway or some other ip address. It's a well known problem and one that even google have found hard to crack using clientside javascript (the idea here being that you get the actual local ip address via a js library and pass that over to your server function).
[edit] - might be worth taking a look at the following for inspiration/confirmation of the issue:
http://www.dotnetfunda.com/forums/thread2088-how-to-get-mac-address-of-client-machine.aspx
It is usually not possible for a person to get the MAC address of a computer from its IP address alone. These two addresses originate from different sources. Simply stated, a computer's own hardware configuration determines its MAC address while the configuration of the network it is connected to determines its IP address.
However, computers connected to the same TCP/IP local network can determine each other's MAC addresses. The technology called ARP - Address Resolution Protocol included with TCP/IP makes it possible. Using ARP, each computer maintains a list of both IP and MAC addresses for each device it has recently communicated with.
Src
I'd like the user to be able to enter the MAC of a computer on the network. Once they've done that, it'll add it to a list. The program will then ping all of those MACs on the list every time the class is called (I know this isn't necessarily possible, but read on).
Normally I'd simply use IP addresses, but they aren't static, and there are a -lot- of devices on the network that I don't care about the connectivity of for this program. If they don't respond, I'd like it to pop up a message box.
NOW, that being said, the only part I'm having trouble with is the actual part where I ping something. I know that an actual "ping" is not possible when it comes to MAC addresses, so how could I check for something like that? Alternatively, if it's easier, I could also accept pinging something based on the computer name.
EDIT: I'd prefer not to have to use things like arp to find the IP addresses of the devices I want. Like I said though, I'm also interested in whether or not it's possible to search for devices by name. Would that work?
If you have a properly administered environment, you should be using names. By properly administered environment, I'm primarily meaning having a DNS server on your local network.
I have something similar running that pings industrial ethernet devices. These are statically assigned addresses, so they don't register themselves with DNS as a DHCP client would. I had our DNS administrator create records for them so I can just use their name. You'll be better off in the long run as two years from now you're going to have NO idea what that mac address in your list was referring to. When creating names, you can make them as descriptive as necessary.
EDIT: Here's a function that takes a name as a string, looks up the associated IP from DNS, then pings. If DNS resolution fails or the ping doesn't report success, the function returns false. It returns true otherwise. You should also log the exceptions for troubleshooting later, BTW.
public bool Check(string Name)
{
//try dns resolution, if fails, quit reporting error
IPAddress[] addresses = null;
try
{
addresses = Dns.GetHostAddresses(Name);
}
catch (SocketException)
{
return false;
}
//ping remote address
PingReply reply = ping.Send(addresses[0]);
switch (reply.Status)
{
case IPStatus.Success:
return true;
break;
default:
return false;
break;
}
}
EDIT 2: Here are the namespaces I'm using in this project. Not sure what's where exactly, but adding these three will get everything going.
using System.Net.NetworkInformation;
using System.Net;
using System.Net.Sockets;
You need to use RARP http://en.wikipedia.org/wiki/Reverse_Address_Resolution_Protocol
and
MAC address to IP Address on Same LAN in C#
Depending on the network, you may be able to use the arp cache to look up the IP of a given MAC address (even if your network is set up such that you could do this, it will only work if the MAC address of the other machine is in the cache at the time of the request). You can read about arp on Wikipedia
If you have the MAC address you can get the IP address and machine name using MAC address. Once you have the IP you can simply ping the machine.
See this code for an example of how to get IP address from MAC address
I have a program in C# that I want to get a news feed from a server I setup in my basement. I also want to setup this program so it can work locally. To do this I THINK I need to compare the resolved ip of my dyndns.biz hostname to my router's public ip (I have dynamic ip and a client on my server updating the ip of the hostname) and thus determine if the hostname needs to be used or the local ip of the server (192.168.0.100) or the hostname. I already have code to connect to the ftp server assuming I can get the right usage of the hostname versus the localized IP.
Edit: Anyways, in summary because I realized this might not look like a question, how can I determine a) the resolved IP of the hostname and b) the public IP of my router in a C# app
You're overcomplicating this.
Just open your hosts file (found in C:\Windows\System32\drivers\etc) and add your dyndns hostname routing it to loopback. That way you don't have to add any workaround code to your final application to prevent it from even asking your DNS or router:
127.0.0.1 yourhostname.dyndns.biz
To obtain the IP address of a hostname, use the following code:
IPAddress[] addresses = System.Net.Dns.GetHostAddresses("www.cnn.com");
To obtain your public IP address of your router or local network, you need to talk to an outside system that can tell you that part, and unfortunately I don't know if there is any such system that is free to use as well as easy to use from a program.
What is the easiest way to find the next unused IP address on a local adaptors subnet?
IPAddress GetNextFreeIP(NetworkInterface intface)
{
...?
}
Update
I've written a BOOTP/TFTP server that could be used in many different scenarios (cross-over cable, small private network, large corporate network). I have to give the small embedded system I'm updating an IP address and would like to find a spare one for it to use...
If you have DHCP-managed IP ranges, you have an instance you can talk to - the DHCP server (like David recommended)
If you don't have managed IP ranges and no other instance you can talk to, there is no reliable way to tell if an IP is used or unused. IP does not offer such a service itself.
Apart from asking the DHCP-server, I guess you could do a broadcast ping on the subnet and collect the responses from all computers and simply sort the IP-addresses to find the next one. This assumes, of course, that all devices are on-line and responds to broadcasts. So in a pretty controlled environment, this could work.
The short answer is you can't, as Thorsten79 just said.
A slightly longer answer:
It depends on your network's configuration: how the admin has decided to allocate ip addresses. Usually there's a mix of manually assigned ip addresses for servers, routers etc, and a set of dhcp assigned ip addresses for workstations and such.
If you can talk to the dhcp server you might find out which addresses in the reserved range are free, but for the rest of the addresses you cannot find out.
The more interesting question is what you are trying to accomplish? Perhaps it can be realized in a different manner?
From what I've seen of embedded devices with a TFTP server, they boot up with a hard coded IP Address that is documented. After a set period of time (~3-10 seconds), the boot loader transfers control to the application that reads its configuration and sets the IP Address.
If someone wants to use the boot loader to load new firmware, then they need to read the documentation, make sure that IP Address is reachable (on the same subnet), reboot the device, and TFTP the application to the device.
You are all technically right when you say there is no way to ensure an IP isn't being used. But I've decided to rely on this for now...
public static IPAddress FindNextFree(this IPAddress address)
{
IPAddress workingAddress = address;
Ping pingSender = new Ping();
while (true)
{
byte[] localBytes = workingAddress.GetAddressBytes();
localBytes[3]++;
if (localBytes[3] > 254)
localBytes[3] = 1;
workingAddress = new IPAddress(localBytes);
if (workingAddress.Equals(address))
throw new TimeoutException("Could not find free IP address");
PingReply reply = pingSender.Send(workingAddress, 1000);
if (reply.Status != IPStatus.Success)
{
return workingAddress;
}
}
}