How to properly look up hostnames from IP addresses
Looking up reverse DNS to determine the hostname of an IP address that you are talking to is one of those almost simple things that software keeps getting wrong. So here is how you do it, in two variants.
First, if you use DNS and have an (almost) empty
/etc/hosts or just
don't care about looking up something in it, is the simple version:
gethostbyaddr()the IP address. If it fails, you are done. Otherwise you have the claimed hostname.
(Technically you have a claimed hostname, since hosts may have multiple PTR records. Your
gethostbyaddr()equivalent may return multiple names in this case; if so, pick one.)
- check to make sure that the claimed hostname is not an IP address;
many systems will helpfully do successful hostname lookups on IP addresses.
If the claimed hostname is an IP address, fail the hostname lookup.
- Add a dot (
.) to the end of the claimed hostname, and
gethostbyname()the result. If it fails, you are done. Otherwise, check to see if any of the returned IP addresses is the original IP address.
The first two steps are the 'reverse lookup'; the third is the 'forward lookup'.
Adding a dot to the end of the claimed hostname forces a rooted DNS lookup without any use of your DNS search list of default domains. Without this, it's possible that a local host will block a successful check on an outside one because the local host has a short name that is the same as the full name of the outside host.
If you have an
/etc/hosts with short names, you need to add an extra
step at the end: if the forward lookup check has failed, try it again
without adding the trailing dot. This allows it to match a short name
/etc/hosts that may have been returned by the reverse lookup.
Depending on what you are using the hostname for, you may want to map it to a consistent (ASCII) case or preserve it as the reverse lookup gave it to you. (If you are presenting it to the user and you care, you may then want to worry about IDNA issues.)