Find DNS HostName from IP Address in LAN - c#

Hey all. I have written a program that sequentially scans certain parts of a LAN for computers (code will be provided). However, when I run this code, it only returns the DNS HostName of the computer it is running on. I looked into using WMI, but I cannot, as I will not always have priveleges to the computers being found. Is there any other way to find a local computers HostName?
using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
namespace CheckLocalNetwork
{
class PingCheck
{
public static string fullip;
public void CheckSequentialIP()
{
IPHostEntry IpEntry = Dns.GetHostEntry(fullip);
Ping pingSender = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;
string data = "a";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 120;
PingReply reply = pingSender.Send(fullip, timeout, buffer, options);
if (reply.Status == IPStatus.Success)
{
Console.WriteLine("Address: {0}", reply.Address.ToString());
Console.WriteLine("Host Name: {0}", IpEntry.HostName);
Console.WriteLine("RoundTrip time: {0}", reply.RoundtripTime);
Console.WriteLine("Time to live: {0}", reply.Options.Ttl);
Console.WriteLine("Don't fragment: {0}", reply.Options.DontFragment);
Console.WriteLine("Buffer size: {0}", reply.Buffer.Length);
Console.WriteLine("");
}
}
static void Main(string[] args)
{
Console.WriteLine("Press enter to search for ip adresses that begin with 192.168.1");
Console.ReadLine();
for (int endofip = 1; endofip < 101; endofip++)
{
fullip = "192.168.1." + Convert.ToString(endofip);
PingCheck checkfullip = new PingCheck();
checkfullip.CheckSequentialIP();
}
Console.ReadLine();
}
All help is much appreciated.

Hmm - your code sample behaves as expected on my machine - i.e. it returns the hostname of the machine being scanned.
To investigate your problem deeper, have you tried using nslookup to check the ip addresses resolve?
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Users\Rob>nslookup <-- type this at a command prompt
Default Server: mydns.mydomain.co.uk <--- these two lines indicate the dns server being used to resolve your queries
Address: 192.168.0.1 <----|
> 192.168.0.5 <---- type in the ip address of one of the machines in question
Server: mydns.mydomain.co.uk
Address: 192.168.0.1
Name: myworkstation.mydomain.co.uk <---- this is the hostname, as reported by the DNS using a reverse lookup
Address: 192.168.0.5
If this doesn't return the machine name, then you may have a name resolution issue that is not related to your code.
If this all looks ok, then it might also be worth enumerating the IpEntry.Aliases collection. Are there any entries here, and do they make sense?
Finally - is the code you have above exactly the code that is going wrong for you, or is it a "distilled" example? The reason I ask is that the documentation for Dns.GetHostEntry states
"When an empty string is passed as the
host name, this method returns the
IPv4 addresses of the local host."
I also notice you're holding "fullip" in a static. If this is not the exact code that is causing the problem, especially if this runs multithreaded, is there a chance you are not initialising "fullip" before the Dns.GetHostEntry is called?
I may be way off, but I thought is was worth giving a brain dump of what occured to me as I looked at your problem :)
[EDIT:] - your comment to kdt has clarified something I misunderstood. I thought you were saying you always got back the hostname for your local machine, no matter which machine you "scanned" - which is very odd behaviour. In fact I think you are saying you just get back IP addresses for other machines (their IP address), and only get a hostname for your local. Disregard my last bit about the threading and the empty argument.
This is far more easily explained - your machine is almost certainly just not able to resolve the machine names - I expect my nslookup test I suggested will not return the machine names either.
In order to resolve these IP's to host names, your machine needs a DNS that has entries for these machines, or to have them in its local hosts file; your machine isn't actually asking the remote machine for its name when you do this call so it won;t be able to find it out without help from one of its usual name resolution paths.
It works for me, because my local DNS really does have entries for all the machines on my network, resolving their host names to ip addresses and vice-versa.

Related

Meaning of PingException "No such host is known"

I wrote a Windows Service which monitors devices on our LAN by (among other things) pinging them (using Ping.Send(); .NET 4.6.1). For a small number of PCs (3), I "occasionally" (once/day?) will get a PingException from Send(<ipaddr>, 5000), with InnerException.Message == "No such host is known". The next time the Send() is executed (~60 seconds later), it succeeds. I am using an IP address, as opposed to a name, so it's not a DNS issue.
I talked to the network admins about this issue, but they don't believe anything is wrong with the physical hardware. What other problems could this error be indicating?
Ping.Send() has various parameters which includes a parameter type of string than can either be a valid IP address or valid host-name. I suspect that your using one of the string parameters and sometimes passing an invalid IP (extra space, invalid IP etc...) and the Send() method conditionally resolves that you must be passing a host-name hence the exception regarding DNS.
Rather than send a string, why not utilize the parameter of type IPAddress as you've already stated that it should always be an IP. You can do this by attempting to parse the string into an IPAddress as shown below:
if (IPAddress.TryParse("**IP String**", out var ip))
{
using (var pong = new Ping())
{
pong.Send(ip);
//Etc...
}
}
Note that you will still need to fix your invalid data whichever way you look at it.

Can't find all machine name on local network

We're trying to obtain all ip addresses and hostnames of machines on local network, we have a display box(BrightSign box) which is connected to local network and we want to have all information about that box. We can find ip address of it, but cannot get host name. So we can't determine which ip adresses is assigned to that box. (We can learn the ip address of the box by using its own program; but we want to detect automatically)
here the code we use in c#
`
public void scan(string subnet)
{
Ping myping;
PingReply reply;
IPAddress addr;
IPHostEntry host;
for (int i = 1; i < 255; i++)
{
string subnetn = "." + i.ToString();
myping = new Ping();
//string data = "aa";
//byte[] buffer = Encoding.ASCII.GetBytes(data);
//PingOptions optionss = new PingOptions(64, true);
int timeout = 1000;
reply = myping.Send(subnet + subnetn);
if (reply.Status == IPStatus.Success)
{
try {
addr = IPAddress.Parse(subnet+subnetn);
host = Dns.GetHostEntry(addr);
txtHosts.AppendText(subnet + subnetn + host.HostName.ToString()+"\n");
}
catch {
}
}
}
}`
if we use this code, system can detect all ip but not host names belongs to telephone and the box i mentioned.
Briefly, we need to have all machine name and ip addresses on local network.
So, do you guys have any idea what's the problem and what can we do to solve this issue. We made some research and tried some ways. We tried to send ping the ip address which we cannot take the hostname and we realized that if ttl of machine is set to 64, we cannot take the hostname, but if its ttl is 128, we can manage to learn the hostname, i also adjusted ping settings to test this challenge, but i still have problem.
I am looking forward to hearing your response.
Thank you all.
Machine name could be DNS or NETBIOS or something else. I recommend you check out NMAP and see what it can do. If you want to emulate that, you can ask about a specific requirement. For example, getting a DNS name means querying the DNS server, a computer wont reply with a name just from an ICMP ping. If the computer security settings allow it, you can do a netbios query, or use WMI, or if you are in a domain, query the domain server.
I don't know what brightsign is, but there is no law that says a device must have a DNS name, some appliances just use IP address and thats it. Also there's no law that says a device must respond to ping or any other protocol.

Attempt to Disable IPv6 Messes Up Imports

I'm creating an application for Minecraft Classic to send "Heartbeats" to an external website and my application wants to send IPv6 heartbeats rather than IPv4 heartbeats if both IPv6 and IPv4 are present on the system.
Here's what I've tried (through looking through Google search):
Ipv6Element DisableIPv6 = null;
DisableIPv6.enabled = false;
The issue here is that when I add the System.Net.Configuration import, my other portions of code from a .dll won't work anymore because I've attempted to use this method of disabling IPv6.
Here's an example of the .cs file where the heartbeat is sent to the external website (Either Minecraft.net or ClassiCube.net. Since Minecraft.net only supports IPv4 for its Classic servers, the software works fine, but since ClassiCube accepts both 4 and 6, if the machine the server is running has both, it will only take 6, but my software doesn't support IPv6 yet. The .cs file is here. (the Pastebin link expires in 2 weeks)
I've been trying to disable IPv6 if this is the case, but now that I realize that IPv6 will someday replace IPv4, I know I need to support IPv6 now before it is too late
I want to be able to support IPv6 in the application. How can I fix my code to support both IPv4 and 6?
Disclaimer
This code, in fact, is Visual C#, not java. The software has been created in Visual Studio 2013. This program is used to host Minecraft Classic Servers, (Not Premium). Many people don't believe the program was writen in C#, but I'm going to state that now so there is no confusion down the road.
Under the salt initialization:
// Dns lookup, to make sure that IPv4 is preferred for heartbeats
static readonly Dictionary<string, IPAddress> TargetAddresses = new Dictionary<string, IPAddress>();
static DateTime nextDnsLookup = DateTime.MinValue;
static readonly TimeSpan DnsRefreshInterval = TimeSpan.FromMinutes(30);
static IPAddress RefreshTargetAddress([NotNull] Uri requestUri)
{
if (requestUri == null) throw new ArgumentNullException("requestUri");
string hostName = requestUri.Host.ToLowerInvariant();
IPAddress targetAddress;
if (!TargetAddresses.TryGetValue(hostName, out targetAddress) || DateTime.UtcNow >= nextDnsLookup)
{
try
{
// Perform a DNS lookup on given host. Throws SocketException if no host found.
IPAddress[] allAddresses = Dns.GetHostAddresses(requestUri.Host);
// Find a suitable IPv4 address. Throws InvalidOperationException if none found.
targetAddress = allAddresses.First(ip => ip.AddressFamily == AddressFamily.InterNetwork);
}
catch (SocketException ex)
{
Logger.Log(LogType.Error,
"Heartbeat.RefreshTargetAddress: Error looking up heartbeat server URLs: {0}",
ex);
}
catch (InvalidOperationException)
{
Logger.Log(LogType.Warning,
"Heartbeat.RefreshTargetAddress: {0} does not have an IPv4 address!", requestUri.Host);
}
TargetAddresses[hostName] = targetAddress;
nextDnsLookup = DateTime.UtcNow + DnsRefreshInterval;
}
return targetAddress;
}
And then, within static HttpWebRequest CreateRequest, under request.UserAgent, insert
if (uri.Scheme == "http")
{
request.Proxy = new WebProxy("http://" + RefreshTargetAddress(uri) + ":" + uri.Port);
}
That should work, I have no way of testing it. Hopefully you or someone else has ipv6 so they can test. All of this code was basically taken from fCraft by the way, all credit to them. http://www.fcraft.net

How do I determine local IP address which can connect to a given remote IP/DNS Address

Using C# Winforms I am trying to automatically detect the local machines IP address through which it can connect to a particular remote DNS/IP address.
One senario is running over a VPN, with the remote address being 10.8.0.1 and local address being 10.8.0.6, netmask of 255.255.255.252
Iterating through the local addresses and checking if the remote and local are on the same subnet obviously fails and I am unsure of how else to do this.
Here is some sample code that should get you the information you're looking for. It creates a UDP socket and calls Connect() on it (effectively a NOOP), and then checks the local address.
static EndPoint GetLocalEndPointFor(IPAddress remote)
{
using (Socket s = new Socket(remote.AddressFamily,
SocketType.Dgram,
ProtocolType.IP))
{
// Just picked a random port, you could make this application
// specific if you want, but I don't think it really matters
s.Connect(new IPEndPoint(remote, 35353));
return s.LocalEndPoint;
}
}
static void Main(string[] args)
{
IPAddress remoteAddress = IPAddress.Parse("10.8.0.1");
IPEndPoint localEndPoint = GetLocalEndPointFor(remoteAddress) as IPEndPoint;
if (localEndPoint == null)
Console.WriteLine("Couldn't find local address");
else
Console.WriteLine(localEndPoint.Address);
Console.ReadKey();
}
Note that this is effectively an implementation of this answer, but in C#.
The routing table determines which local port to use. I don't know of a way from C# to get it other than to run the route print CLI command. If there is a network match it uses that port, otherwise it uses the default route.
http://www.csharp-examples.net/local-ip/
Give that a shot.

How to get the MAC address prior to connection?

I have a situation where I ping a range of IPs in the network. Then, I try to connect to the successful pings.
My aim is to connect to specific equipment that has a specific MAC prefix. For example, when I ping a range of 100 IPs, I might get 20 replies. These replies include computers, printers, and possibly the hardware I am trying to connect.
Currently what happens is that when I try to connect to anything other than the hardware I would like (i.e computer, printer) I get a timeout connection.
This is fine, however, it is not efficient. I would like to filter out the successful ping list by using the MAC address, however, I have not yet been able to find a solution that allows me to seek a MAC address prior to connecting the hardware.
I have looked through most the MAC questions on here, but none fit my needs.
Any ideas??
I was able to find the solution here: http://pinvoke.net/default.aspx/iphlpapi/SendARP.html
The following method returns the MAC
internal static string GetMAC(string ip)
{
IPAddress dst = IPAddress.Parse(ip); // the destination IP address Note:Can Someone give the code to get the IP address of the server
byte[] macAddr = new byte[6];
uint macAddrLen = (uint)macAddr.Length;
if (SendARP((int)dst.Address, 0, macAddr, ref macAddrLen) != 0)
throw new InvalidOperationException("SendARP failed.");
string[] str = new string[(int)macAddrLen];
for (int i = 0; i < macAddrLen; i++)
str[i] = macAddr[i].ToString("x2");
return string.Join(":", str);
//Console.WriteLine(string.Join(":", str));
}

Categories