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
Related
I am trying to convert a VBScript COM component based Reverse/Forward IP checking system to C#.
This system was created to prevent the banning of SERPs like Googlebot using what was back then (becoming) the standard way of checking an IP was who it said it belonged to e.g a reverse/forward DNS check.
Although we have lists of SERP IP Ranges so we don't ban them if they come in - even with hack vectors - we cannot keep up with new ranges being added all the time.
The process is based around this short example.
It is explained simply here > http://ipadmin.junkemailfilter.com/rdns.php
This has been working fine for ages in VBScript but now I am converting to .NET I am having issues where people have set their IP to resolve to "localhost" like this one 113.168.154.182 as you just get back your own DNS server, Virgin media, or if I run it from my PC with c# I get my own computer name. The IP is from Vietnam > http://www.geoiptool.com/en/?ip=113.168.154.182
Now I am trying to use .NET and this code.
But as I am using this code to do get the hostname
IPHostEntry DNSHostIP = Dns.GetHostEntry("113.168.154.182");
hostname = DNSHostIP.HostName;
When I output the value of hostname I get my own computers name e.g std36w7.metal.mycompany.co.uk not localhost.
Then when I try and do a forward DNS check to get the list of IP addresses with this hostname I get my own IP addresses (one IPv6 one IPv4).
If I could get back "localhost" then I could have a check to skip it as a spoof along with anything starting with 10 or 192 etc.
However at the moment I cannot do this.
What is the best way of doing reverse/forward DNS checks which I thought was becoming the standard way of checking for spoofers nowadays in .NET?
And how can I handle people who have set (or some mistake might be causing it) their IP to be localhost.
Thanks
Simple. Your LOCAL DNS (guessing your router unless you have your own DNS server) is resolving it - upstream to it's INTERNET DNS server. Also if you really want it to return LOCALHOST, you'd have to literally edit your local HOSTS file and add an entry since no system ever returns the name LOCALHOST when you look up your ip even from a local DNS server. I believe the ONLY example is if you completely eliminate a DNS server to fallback on your local HOSTS file.
Final edit for clarity - In my environment, DNS will only store one record per client. If a client has multiple NICs, or changes subnets, the original IP is registered in DNS until the corresponding DHCP record expires (this is an AD environment where DHCP registers DNS addresses).
In this scenario DNS has one, incorrect, record for the client. I want to query DHCP by client name, to see all IPs that are leased to it.
The only possible solution I have found is to dump all subnet info from DHCP (supported by the below API) then query against that, but that is not feasible in my environment, since multiple people would use this application, and I don't want the additional strain on DHCP.
I cannot change any configuration for DNS or DHCP.
Thanks,
This is similar to this question, but with the referenced API (here), I can only query via IP. Is it possible with this API, or any other, to query DHCP by hostname? (The issue being, DNS gives me an old IP for MachineA, I want to retrieve any other IPs being leased by MachineA from the DHCP server).
Edit: To clarify, I want to write a program that I can type in a hostname, it will then query a DHCP server for all IPs for that hostname in any subnet administered by that DHCP server. This is to workaround the issue of a machine with multiple NICs registering an IP that is useless to me (wireless), so for instance the DNS result may be NICA (wireless) but I want NICB (wired).
From what I can tell, you've encountered the age-old problem of which IP address to use. Now-a-days many computers have multiple NICs, some virtual, some local-only, some with internet access, etc... For the application to choose is very difficult. Most of the time I simply make the IP by which the application hosts things like sockets a configuration item--simply because the application is incapable of really choosing which is the right ip address to use. e.g. two NICs both with the same network access, which do you choose? If you run the application twice, maybe one should use NIC 1 and the other should use NIC 2--how would the app make that determination? (i.e. it can't).
Having said that, depending your needs, you can go looking for the best NIC and get it's IP address. For example, if you want an IPv4 address on a non-wireless NIC, you can do something like:
var ips = from ni
in NetworkInterface.GetAllNetworkInterfaces()
where ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet
from ip in ni.GetIPProperties().UnicastAddresses
where ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && ip.IsDnsEligible
select ip;
IPAddress address = ips.First().Address;
...error checking omitted for readability--apply whatever error checking suitable for your requirements.
You can even go so far as to check whether the address is link local (i.e. can communicate out of the local network segment--which usually means an address automatically assigned by Windows instead of DNS/DHCP) by seeing if the first two bytes of an IPv4 address are 169 and 254.
But, you need to specifically define what your requirements are. simply to say "undesirable wireless IP" doesn't provide unambiguous and verifiable criteria to tell what solution will always work for your needs.
If you are trying to locate a machine on the network, then querying DNS is probably what you want to do first. i.e. Think of a machine that has a static ip address on the network. It would register its name with the name service only, it would not show up in DHCP att all if the machine's IP stack is configured with the static address only.
I'm not sure how long it should take for a new machine or a recently changed IP address to show up in DNS. But if you want to see if DHCP has something different(newer), then query DHCP after trying it from DNS first.
i've written a simple local messenger with c# for use of myself. now it works over a local network(lan,wifi) and works fine.
now i want to give it to my friend and use it over internet but have no idea how to use different ip except local host.
i'd be grateful for any help.
thanks in advance.
private void InitializeConnection()
{
ipAddr = IPAddress.Parse(txtIp.Text);
tcpServer = new TcpClient();
tcpServer.Connect(ipAddr, 1986);
Connected = true;
UserName = txtUser.Text;
txtIp.Enabled = false;
txtUser.Enabled = false;
txtMessage.Enabled = true;
btnSend.Enabled = true;
btnConnect.Text = "Disconnect";
swSender = new StreamWriter(tcpServer.GetStream());
swSender.WriteLine(txtUser.Text);
swSender.Flush();
thrMessaging = new Thread(new ThreadStart(ReceiveMessages));
thrMessaging.Start();
}
this the client part
public ChatServer(IPAddress address)
{
ipAddress = address;
}
private Thread thrListener;
private TcpListener tlsClient;
bool ServRunning = false;
public static void AddUser(TcpClient tcpUser, string strUsername)
{
ChatServer.htUsers.Add(strUsername, tcpUser);
ChatServer.htConnections.Add(tcpUser, strUsername);
SendAdminMessage(htConnections[tcpUser] + " has joined us");
}
and this server part.
Intro
To be able to get another user to connect to a computer of yours, there are a quite a few things you are going to have to do. Hopefully, this should work but networking can get complex in general and not all networks run alike. I assume you are running this behind some sort of router that you have access to. Networking is complex and that really is why this answer is so awfully long (if you are questioning yourself on reading the rest of it). For the most part it is pretty straight and forward, but might take some time.
And before you get started, just a:
Forewarning
Thinking security wise, like almost everything on computers and with networking in general, there is not really something called "entirely safe" (at least as far as I know). As with networking, opening ports is not entirely safe. I'm not a top notch security expert, but by doing this, you are allowing other computers to send and receive data with your computer. This should be safe in your case of just having a simple text chat, but in other cases this might not be the same. With more complex and important cases such as dealing with SSH and FTP, there is more security involved. Just as a warning, make sure to take care when messing with your network, or with computers in general.
Getting Started
Anyways, (if I have not scared you off yet) these are the steps that I had to take to get something like your chat server working:
Forwarding the port on your router
The first thing you are going to have to do is forward or open the port on your router. Well, before you can even do this, there are several things you need to understand about networking:
Basically, your router is what connects your network of computers to the internet and allows connections to be be made through ports. If you don't understand what a port is, it is what is used for internet connections to be made and basically acts like the house number to a street address. It tells where on that street the house it and is more specific than just the street address. In terms of networking, this is a number which tells the specific place the communication is going. The port number ("the house number") is telling where on the computer's IP address ("the street address") to connect.
Specifically, the port number is an 16-bit unsigned integer ranging from 0 to 65535 (but port number 0 actually cannot be used according to Wikipedia) Even though this is a 16-bit unsigned integer which would be a ushort or a UInt16 in C#, when using a TcpClient or a TcpListener, they instead use a signed 32-bit integer instead which is the standard int or a Int32. Also, The port is generally denoted after an IP address with a colon (":"), for example 123.45.67.89:80 but might be different in other cases. This is using IPv4 but there is also IPv6 which I have not yet worked with.
Now, what about forwarding the port and why do you need to do that? What forwarding the port does is forward connections to a certain port on the router to a computer which is behind the router instead. There is not always a simple, straight and forward way to do this since router companies have different ways of accomplishing this. Generally, to figure this out, you can Google for instructions on how to forward the port on your particular router, so for example you can search for "forward port on router company's name router" to find it. To do this, you are probably also going to need a few things before getting started with that:
You are going to need your routers admin user name and password which is generally not (and probably should not be) what is used to connect to it with. If you don't know what it is, whoever setup your router should know. Once you have got this working you are ready to move on.
You are also probably going to need the your computer's local IP address which is used to address the computers in the router's network. To find this, your router will probably tell you what it is, but here are the steps to do it on Windows if you can't seem to find it.
Open up command prompt
Open the run dialog by going to Start >> Run... or by pressing Win+R
Type cmd and press enter
Run ipconfig by typing it in and pressing enter to find your computers IP address
You should see a list of network interface connections
To find the one we are looking for, you want to find the network connection you are using to connect to the internet through your router. It is probably different on computer but in my case its named Wireless LAN adapter Wireless Network Connection since I'm using a laptop. The name, I would assume, probably has LAN in it.
This should not have: Media State . . . . . . . . . . . : Media disconnected listed under it since you need to be connected to your router. If you are not then simply do so.
Instead, there should be IPv4 Address. . . . . . . . . . . : with the IP address of your actual computer listed next to it. This is the IP address of the computer whose port you want to forward. Of course, this might be different if you are using a router using IPv6.
Also, in the process of doing this, your port number that were using may be taken by another process or service. This is okay and easy to fix; you just have to change the port number. You are going to want to trying a high number such as 8500 for example until you find one that works. Once you have that number, just update the port number in your code. To make this even easier it, is much easier to have a constant that stores this such as:
const int Port = 8500;
So then you can have the client connect with:
tcpClient.Connect(ipAddress, Port)
And then have the server listen with
TcpListener tcpListener = new TcpListener(ipAddress, Port);
As with other global variables such as the port number that you might have, it may be better to create a global variable class, but at the same time, that may also introduce other issues by using it such as with global properties with threading. Just a suggestion and a heads up.
Though, once you have managed to complete forwarding the port, you can move on to the much simpler part of getting your friend to actually connect to your server.
Geting your router's IP address
Once you have managed to do all of that, you probably should give your a pat on the back because that is the real actual part of getting your router to cooperate with what you were trying to do. Now you just have you give your IP address, port number, and of course your client program to your friend, so he or she can connect to the server. To get your router's public IP address you can go over to the ironically called website at http://www.whatismyip.com/. Here you can get your public IP address but also make sure that it says "No Proxy Detected" below it. If you are using a proxy, hopefully you know what that is and can connect to the internet without to get your IP address. (Trust me, you don't want me to explain want a proxy is for now)
Now once you have got that, you are going to want to send that IP and also your port number to your friend. To be smart about it, you don't want this publicly displayed as you probably don't want a bunch of random people trying to break into your network. Sending it over IM or email should (hopefully) be fine as long as your friend does not publicly display it. So when sending your IP address, just be smart about it.
Once you have done that, just don't forget to actually start your server! Without your server running, there is no way to communicate to the clients and accept incoming connections. This will save a lot of frustration from accidentally forgetting to.
Conclusion
Hopefully, this will help you be able to create a cool chat program and also understand a few other things in the process. I really wish this was not so long, but networking is really just complicated in for the most part.
Hope this helps you quite a bit!
I have two standalone exe's Parent.exe and Child.exe.
Parent.exe opens Child.exe and some operation are performed in child.exe by user then
child.exe sends back some processed data to Parent.exe. Both exe's stays on same machine
The communication between Child.Exe and Parent.Exe is being done through TCP IP (Socket Programming). For this we need to calculate the Local IP Address, we used to calculate it in the following way :-
string hostname = Dns.GetHostName();
IPHostEntry ipEntry = Dns.GetHostEntry(hostname);
IPAddress[] addr = ipEntry.AddressList;
string FinalIpAddrs = addr[0]
Everything worked fine at XP but with Windows 7 we are facing problem. The below line return Mac Address what is the right way to do it, so that it works on XP and Win7 both?
string FinalIpAddrs = addr[0]
Oh, those wh program and do not know.
You do NOT need to know an IP Address, use 127.0.0.1, which is a local loopback address. SImple like that - it is there for exactly that reason.
Consider being efficient. If that is all same machine, the usage of TCP is bad. Use named pipes, which are a windows integrated commmunciation mechanism that CAN work cross machine, but on the same machine it uses shared memory which is a LOT more efficient than TCP.
Why not just use IPAddress.Loopback (or IPv6Loopback)?
The loopback addresses are designed for communications entirely on the same host.
I'm also guessing that where you say:
The below line return Mac Address
What you actually mean is that it's returning an IPv6 address. There's no way that that code should be able to return a MAC Address.
Is there a specific requirement NOT to use 127.0.0.1? If no, then I'd just use it without any calculations.
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.