I am trying to get the hostname by passing in the ip address. I use the following code.
System.Net.Dns.GetHostEntry("192.168.x.x").HostName
For some host the above code is returning correctly the hostname, but for few other host it throws an exception 'No Such host found'.
Could any one tell me why is this happening for some hosts?
I used the above code in an asp.net mvc application.
Not all IP's are setup properly with a reverse DNS entry. These IP's are typically end consumers on lazy ISP's who don't provide PTR records for their clients. If there's no reverse entry, you can bet there's no forward entry either. As such, these hosts have no hostname at all, hence the exception. You'll need to catch this exception for these hosts and use something else such as their IP as an identifier.
I'm using Dns.GetHostByAddress, even though it complains about being depreciated. (VS2010 targeting 3.5)
Dns.GetHostEntry seems to throw an exception if a the target host is not reachable even if DNS knows the hostname. There doesn't seem to be any .NET way around this except for using depreciated methods. :\
(edit: though the above answer is also true - some machines just don't have hostnames. my answer is just if you know it should have a hostname but GetHostEntry doesn't work)
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.
I have a Coherence cluster running on my local machine, and a C# application that is trying to connect to it. I am getting the error:
Could not establish a connection to one of the following addresses:
XXXX. Make sure the remote addresses element contains the IP address
and port of a running TcpAcceptor.
Here is the remote addresses section of my client config:
<socket-address>
<address>localhost</address>
<port>9099</port>
</socket-address>
I can't connect to this address or any of our other environments, which are working for other existing code. I confirmed that the cluster was running using a Coherence Console node. What are some possible causes other than the obvious incorrect IP address? What else can go wrong?
Is it possible to confirm that a "running TcpAcceptor" is on my machine?
Before I added the config file, it threw an exception saying that it was missing cache-config.xml. All our other code uses coherence-cache-config.xml instead; is this important?
Issue resolved. The problem: although I had coherence.xml and cache-config.xml in the project and they were being used, I was missing the POF config. I added a coherence section to my app.config explicitly referencing these files and it worked.
check if local-config.xml in your proxy node defined properly.
<tcp-acceptor>
<local-address>
<address>localhost</address>
<port>9099</port>
</local-address>
<suspect-buffer-size>1000000000</suspect-buffer-size>
</tcp-acceptor>
When using Dns.GetHostAddresses("fred") it returns only IPv4 addresses in response. How to get the IPv6 addresses as well? Is there different method I shall use?
Socket.OSSupportsIPv6 returns true and IPv6 connections work fine. The OS is Windows 2008 R2, .Net version is 3.5.
IPv6 still uses DNS to resolve addresses so in order for this to work you will need to add an IPv6 entry to your zone file for this domain name. It'll then resolve properly.
I suspect that Ping will fall back to IPv4 if an IPv6 is not available, not exactly what you'd hope once you've specified the '-6' flag.
In case anyone is still having this problem in 2021, the System.Net.Dns class has an undocumented behavior: it filters addresses it thinks are unreachable when your only IPv6 address besides loopback is link-local. This filtering is performed even if the domain name exclusively resolves to a v6 address (you can try with v6.localhost.ayra.ch), in which case an exception is thrown.
If you're located in an IPv4 only network but want the ability to resolve v6 addresses in .NET, you can cheat your way around this problem by manually assigning your device a custom IP. Assign your device the IPv6 address 2001:db8::1 with a prefix length of 32 and no default gateway. I haven't found anything that stopped working so far because of this, and .NET will now resolve IPv6.
Note that the suggested IPv6 address and range is reserved for use in documentations, which means you should never encounter this range on the internet at all. If you want to make sure your choice doesn't conflicts with the address of someone else that follows this instruction, I suggest you use your mac address for the last 3 address segments.
I made a page that generates these address either with your MAC or randomly: https://cable.ayra.ch/docmac/
I have the following code:
string ip = Request.ServerVariables["REMOTE_ADDR"];
Which, in the test environment does return the user IP addrress, but when we deploy the website to production, this variable has the IP of the server where the application is hosted. Any help?
My guess is that there is a proxy in the middle. Use HTTP_X_FORWARDED_FOR first, and if that's null, then use REMOTE_ADDR
From the MSDN article:
Although retrieving just the REMOTE_ADDR server variable should be enough, I found resources online that suggested that code like this should also check the HTTP_X_FORWARDED_FOR variable; if the request comes through a proxy server that translates the address, it's this variable that contains the correct address. If you request a server variable that doesn't exist, the ServerVariables property returns an empty string. Therefore, even though this property doesn't appear in my tests, attempting to retrieve its value doesn't cause trouble.
UPDATE:
If it's a load balancer that you have have settings changed on, you should ask to see if they can have the origination IP passed through. I know this can be done with Microsoft's ISA server.
If that's not an option, there are these other server variables that you can try and see if they produce a result:
"HTTP_X_COMING_FROM"
"HTTP_X_FORWARDED_FOR"
"HTTP_X_FORWARDED"
"HTTP_X_REAL_IP"
"HTTP_VIA"
"HTTP_COMING_FROM"
"HTTP_FORWARDED_FOR"
"HTTP_FORWARDED"
"HTTP_FROM"
"HTTP_PROXY_CONNECTION"
"CLIENT_IP"
"FORWARDED"
Why do you use old, VB-style server variables instead of Request.UserHostAddress?
See MSDN Library.
As the others have stated, you will get the IP address of the reverse proxy/SSL terminator if it doesn't make the requests look like they come from the original client (As is possible at least in ISA server, and probably in most other reverse proxies).
If not, you will get the public address of the client (which is probably a router address at the client site, as most LANs are NAT-ed).
How does your setup in the production environment differ from your test environment?
Are you actually getting the IP address of the Web server, or of some other server in the same network?
I see this is an old question but I ran across it and I think I know the answer. The answer is simpler than those above... I just ran into the same issue today. I bet you are trying to get the IP from a page being called by XMLHTTP which will return the server IP since it is the one making the request and not the user.
I'm just wondering if there can be a case where the hostname can be successfully resolved but the returned hostEntry.AddressList is empty.
Currently I'm doing something like this:
IPHostEntry hostEntry = Dns.GetHostEntry("some.hostname.tld");
if (hostEntry.AddressList.Count() < 1)
{
// can that ever happen?
throw new ArgumentException("hostName has no assigned IP-Address");
}
TcpClient client = new TcpClient(hostEntry.AddressList[0], 1234);
My assumption is that Dns.GetHostEntry either throws an exception if the hostname is not found or otherwise the AddressList is nonempty, but I'm not sure about that.
No, you'll not see an empty address list: even if you query a DNS label that does exist, but has no A or AAAA (IPv6) records, a SocketException ("No Such Host is Known") will be thrown.
You can verify this by looking at the function InternalGetHostByName(string hostName, bool includeIPv6) in DNS.cs from the .NET Reference Source release. With the exception of some platform-specific precautions, DNS lookups are a simple wrapper around the Winsock gethostbyname function.
Gethostbyname will either fail, or return an address list. An empty address list is never returned, because the function will fail with WSANO_DATA ("Valid name, no data record of requested type") in this case, which translates to the socket exception we already saw in .NET.
EDIT May 2012, prompted by responses stating that an empty list is returned anyway: do note that this answer only applies to Win32, and that platforms like WinCE may behave quite differently. If you're seeing 'empty list' behavior on Win32, and the request you're making is against a publicly available DNS server, please post your code...
Just for the records.
Thanks to mdb's accepted answer I took a look at the description of the WSANO_DATA error:
The requested name is valid and was found in the database, but it does
not have the correct associated data being resolved for. The usual example
for this is a host name-to-address translation attempt (using gethostbyname or
WSAAsyncGetHostByName) which uses the DNS (Domain Name Server). An MX record
is returned but no A record—indicating the host itself exists, but is not
directly reachable.
So this pretty much answers my question :)
You have three possible situations here:
The hostname exists (DNS has an A Record) and resolves to an IP Address
Condition is never hit
The hostname exists (DNS knows about the domain) however no A records exists.
This is an extremely unlikely scenario, and I think this can never happen in the first place.
The hostname doesn't exist
Exception is thrown, you never get there.
So no, I don't think that can ever happen.
The answer is YES.
The GetHostEntry method queries a DNS server for the IP addresses and aliases associated with an IP address.
IPv6 addresses are filtered from the results of the GetHostEntry method if the local computer does not have IPv6 installed. As a result, it is possible to get back an empty IPHostEntry instance if only IPv6 results where available for the address parameter.
The Aliases property of the IPHostEntry instance returned is not populated by this method and will always be empty.