Question

Perl: gethostbyaddr() vs NSLOOKUP results

Asked by: jlw

I have a perl script that uses the gethostbyaddr() function to resolve an IP address to its appropriate DNS name, if any.

I have found that occasionally (and consistently) some IP addresses resolve to the wrong DNS name.

Using NSLOOKUP on the SAME MACHINE resolves to the correct DNS name.

Why would this be, and how can I make the perl script get the same results as the NSLOOKUP does?

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2007-06-19 at 11:13:38ID22643954
Tags

perl

,

nslookup

,

gethostbyaddr

Topics

Unix Networking

,

Perl Programming Language

,

Domain Name Service (DNS)

Participating Experts
4
Points
125
Comments
34

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. nslookup
    Hello, This script part should return the hostname. The input is the IP address of the host. $Address = "192.168.0.1"; $Address =~ s!\Aaddr=!!; if ($Address) { if ($Address =~ m!(\d+)\.(\d+)\.(\d+)\.(\d+)!) { $Hostname = (gethostbyaddr(pack('C4', $1...
  2. nslookup
    When I use nslookup I get DNS timed out messages before it displays the following information: Can't find server name for 192.168.1.2 : Timed out Default Serve unknown Address: 192.168.1.2 However when I type in my computer name I get Server: unknown Address: 192...
  3. nslookup and perl
    don't know if this is possible or where to start, maybe with a perl script. I have a list of domains, severl hundred long and need to do a nslookup lookup on them to be able to get various info from. Is there a way to use a txt file of a list of domains and to a nsl...
  4. nslookup
    Hi I know we can use nslookup on various websites that offer this facility. However i was wondering how can we use nslookup on localhost to send DNS queries to various DNS servers thru coman prompt.I have tcp/ip installed. What are the various "types" available in ...
  5. No Nslookup
    Ok I think this is an easy fix. If I want to do an nslookup on an IP address in my domain I get a Non-existent domain. >nslookup 10.1.10.3 Server: domain.DNS.com Address: 10.1.10.98 *** domain.dns.com can't find 10.1.10.3: Non-existent domain however if i ping ...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: nociPosted on 2007-06-19 at 13:38:12ID: 19319642

gethost by address is driven using the (nsswitch.conf file on most systems  or equivalnet)

and also takes into account a /etc/hosts file or even different sources (ldap, nis, yp etc.).

nslookup uses dns first.


You get the perl script to use the nslookup itself and cature the output and parse that....
or use the 'host' command if available (part of the bind tools)

output should be something along:

host xyz
xyz.my.domain has address 192.168.x.y


host 192.168.x.y
y.x.168.192.in-addr.arpa domain name pointer xyz.my.domain.

In perl you can this data by:


$var = `host xyz`;

and equivalent funtions.

 

by: jlwPosted on 2007-06-19 at 13:50:31ID: 19319782

The script will be processing 500+ lines of IP addresses; not something I want to spawn out to do an
NSLOOKUP or HOST command for each one, really....

The /etc/nsswitch.conf file here specifies only  "hosts:  files dns", and the IP addresses in question do not appear in the /etc/hosts file, so it should be getting the information from DNS just like NSLOOKUP and, presumably, HOST would get it from  anyway, right?   (HOST doesn't appear to be available, either.   The OS is Solaris 9, eventually Solaris 10).

In fact I've already discussed this much so far with colleages.  We're baffled as to why, in this situation, we consistantly get different results for a big chunk (maybe 15%) of the IP addresses in the file using gethostbyaddr() as with NSLOOKUP.

 

by: nociPosted on 2007-06-19 at 14:06:26ID: 19319945

this line tells to FIRST lookup /etc/hosts and then do a dns lookup.
to not lookup /etc/hosts at all remove the files part from the hosts: line.

It will then ignore /etc/hosts files for ALL gethost by address or gethostbyname requests... (also for ping etc.)

Also you can remove offending address/name pairs from the /etc/hosts file

 

by: TintinPosted on 2007-06-19 at 14:31:07ID: 19320169

As a sanity check, could you please post the relevant lines of Perl where you are doing the lookup.

 

by: jlwPosted on 2007-06-19 at 15:30:59ID: 19320710

In my earlier messages I said that the offending IP addresses do NOT appear in the /etc/hosts file.   So there's nothing to remove, and with them not being found there, DNS should be consulted.   In fact, it seems to me that gethostbyaddr() is actually doing a DNS lookup, but going to the WRONG DNS server.   Any way to find out which one it's using?

I've also moved this entire script to another Solaris box, the one holding the primary DNS server, and confirmed identical results there.

 

by: TintinPosted on 2007-06-19 at 16:09:23ID: 19320946

Do you have just a single name server defined in /etc/resolv.conf?

 

by: jlwPosted on 2007-06-20 at 05:25:02ID: 19323901

There are 3 nameservers cited.    First is our primary DNS server inhouse, 2nd is our secondary, and 3rd is the University's nameserver.

There is a "search" directive naming, first, the fully-qualified DNS name of a server within our own local network, a name which due to history is not defined in our two inhouse servers but instead in the University's DNS server (it belongs to their domain, not ours).

The second name on the "search" directive is the domain name of the first two name servers cited in the 3 nameserver directives.

 

by: jlwPosted on 2007-06-20 at 05:26:12ID: 19323904

My Perl code for the lookup:

$ipaddr contains a text dotted-decimal IP address.

            $name = gethostbyaddr (inet_aton($ipaddr), AF_INET)
                    or $name="";

 

by: tbeardenPosted on 2007-06-20 at 09:24:02ID: 19325987

I would run wireshark while the script is running.  After it finishes, identify a host with an incorrect ip, and then try to find the dns lookup in wireshark.  That will tell you if the result is coming from dns or something else, and what dns server it is coming from.

 

by: jlwPosted on 2007-06-20 at 09:57:42ID: 19326256

Wireshark?   Never heard of it....  Oh.  Ethereal.   Heard of that.   But to use it on my Solaris box I'd have to download it from source and create it.   Beyond my capacity here.

 

by: tbeardenPosted on 2007-06-20 at 10:35:13ID: 19326550

how about snoop.  You can snoop/tcpdump to a file, and then open that up with ethereal/wireshark.

 

by: jlwPosted on 2007-06-20 at 10:38:30ID: 19326578

Maybe.   It's been a year and a half since I used snoop, and that was exclusively in a class.   Machine where this runs has 1000's of connections going on, so the file will be huge.   Have to look.

 

by: tbeardenPosted on 2007-06-20 at 11:07:30ID: 19326835

you should be able to do "tcpdump -s0 -o /tmp/output.pcap port 53".  You will have to verify the output switch, and I don't remember the exact filter string, but that should capture only dns traffic.  You may also have to give it and interface switch if you have multiple nic's.  tcpdump --help should show you.  The options are pretty similar if snoop is all you have.

 

by: TintinPosted on 2007-06-20 at 14:55:53ID: 19328678

My only guess is that your DNS servers are not consistent.  It's possible the lookup in the Perl script is referencing a one of the other name servers compared to the nslookup/host commands.

 

by: jlwPosted on 2007-06-20 at 18:41:58ID: 19329890

This brings us back to what was the implied question in the first place.

Is there any way one can forcibly select a specific server for Perl's gethostbyaddr() to depend upon?

 

by: TintinPosted on 2007-06-20 at 18:58:32ID: 19329982

It's not Perl's gethostbyaddr, is the system's gethostbyaddr.

Depending on what Linux/Unix flavour you're on, I'd run

strace host <address>

to get more clues as to what it does and the same on the Perl script.

Note strace is for Linux systems.  The Solaris equivalent is truss, not sure about other flavours.

 

by: nociPosted on 2007-06-20 at 23:59:25ID: 19331052

gethostbyaddr is part of the resolver libraries.  (get*by* or get*ent routines)
You may have a program on your system that only uses these funtions (getent)
'getent hosts X'  is equivalent to asking gethostbyname(X) or gethostbyaddr(X)

Depending on the nsswitch.conf files (name varies to unix/linux) there is a list of functions below this.
(if a cache daemon is available the question is asked to the cache daemon that walks the nsswitch.conf list, otherwise
each process does its own work, independedly)

The files set of routines looks up info in /etc/hosts, /etc/passwd etc.
the ldap set of routines looks up info in an ldap directory
the nis set of routines looks up info in a nis server.  etc.

the dns set of routines, reads the /etc/resolv.conf
  stores the domain and search string
  and for each nameserver mentioned
      queries it for the bare name supplied and with each search string appended until a match
      occurs.

perl just uses the OS supplied routines AFAIK.

maybe you can ask nslookup to query explicitely each of the servers mentioned.
$ nslookup
server i.p.adr.1
query
server i.p.addr.2
query


etc.
to see if the each supplied servers gives the same answer.
nslookup queries the dns only

Also to ask pure DNS queries to your dns nameservers there is the dig program
part of the bind nameserver toolset.
This program shows the exact query asked, and the exact answer supplied (with all the information)
use dig -x <address> for reverse lookups. Als dig can help identify problems with dns by letting it trace a query.
'dig +trace' or ask a query to a specific server 'dig @nameserver'  etc.

 

by: tbeardenPosted on 2007-06-21 at 06:03:24ID: 19332632

If you want it to do only dns lookups you can use something like Net::DNS, but as far as I know there is no way to tell gethostbyaddr to only use dns.

 

by: jlwPosted on 2007-06-21 at 08:48:37ID: 19334173

Again, gethostbyaddr() looking at files (i.e., /etc/hosts) is NOT the problem; as far as I can tell that is...  it's
making sure that gethostbyaddr(), when it falls thru and uses DNS, that it uses the same DNS that NSLOOKUP is using.   NSLOOKUP is clearly getting the correct resolution of the IP addresses while
gethostbyaddr() is getting a corrupted resolution.  

I'll have to look into this Net::DNS module; not sure if it's installed on my system or not and if it isn't, it may take a little while to get it there (approvals, time to do it, etc).

 

by: tbeardenPosted on 2007-06-21 at 09:24:42ID: 19334626

You might also consider using the batch option in dig.  I know you said you didn't want to start spawning a lot of dns lookups, but if you write all your ip's to a file, you can spawn one dig process and have it query all the ip's in that file.  Check the dig man page for the -f option.  http://www.die.net/doc/linux/man/man1/dig.1.html  

I am not really sure if it would slow you down much, but I wouldn't think it would.  The only difficulty would probably be parsing the output.

 

by: Adam314Posted on 2007-06-21 at 09:37:47ID: 19334725

Spawning another pocess a bunch of times might be the easiest way to get the results you want.  Why do you not want to do this?  Is this time critical?  If it is only being done once, and the results saved somewhere, then the added time will be minimal.

 

by: jlwPosted on 2007-06-21 at 10:13:56ID: 19335005

It'll be done hourly, 24x7.   The results of each run will be compared to the results of the previous run, and if changes occured, our email system will be restarted to make use of the changes.    Yes, it's not something I want to be triggering a spawn out for 500+ different checks every hour.

 

by: Adam314Posted on 2007-06-21 at 10:29:34ID: 19335118

Okay... I wasn't sure if this was a one-time thing though.

 

by: tbeardenPosted on 2007-06-21 at 10:54:30ID: 19335332

Have you identified the dns server that is giving the bad result?  You could nslookup against each server manually until you find it, and then either fix the DNS entry, or remove that server from resolv.conf.

 

by: jlwPosted on 2007-06-21 at 10:58:17ID: 19335376

We're not even sure that different DNS servers ARE giving different results; have to look at that to see, but at present it's almost like, for some IP addresses (consistantly) the server isn't any of the ones in our resolve.conf file, but some random one that pipes up ;-P

 

by: jlwPosted on 2007-06-21 at 11:22:05ID: 19335577

To demonstrate the due diligence alluded to in my last comment, here's my trials looking up one of the consistantly offensive IP addresses against each of my DNS servers cited in my /etc/resolv.conf file:

#  !  Let's try it without any DNS server selection....
# nslookup 146.186.120.073
Server:  namesrv1.dlt.psu.edu
Address:  128.118.88.200

Name:    yamada.libraries.psu.edu
Address:  146.186.120.73
Aliases:  73.120.186.146.in-addr.arpa

# ! OK, now let's explicitly choose our default/primary DNS server
# nslookup 146.186.120.073 128.118.88.200
Server:  namesrv1.dlt.psu.edu
Address:  128.118.88.200

Name:    yamada.libraries.psu.edu
Address:  146.186.120.73
Aliases:  73.120.186.146.in-addr.arpa

# ! Good, same (correct) results again.   Now, our secondary server...
# nslookup 146.186.120.073 128.118.88.225
Server:  namesrv2.dlt.psu.edu
Address:  128.118.88.225

*** namesrv2.dlt.psu.edu can't find 146.186.120.073: Server failed

#  ! OK, that failed.   I guess that's OK, because if it fails there we should try others...
#  ! Try the last host in our /etc/resolv.conf file:
# nslookup 146.186.120.073 128.118.25.3  
Server:  otc2.psu.edu
Address:  128.118.25.3

Name:    yamada.libraries.psu.edu
Address:  146.186.120.73
Aliases:  73.120.186.146.in-addr.arpa

# ! OK, and that last try finds the same results as our 1st server offered.  That's good.

 

by: jlwPosted on 2007-06-21 at 11:23:27ID: 19335598

What gethostbyaddr() gives me for that same address, however, is "eshop.moc.psu.edu" -- not "yamada.libraries.psu.edu" like the DNS servers do.

 

by: tbeardenPosted on 2007-06-21 at 11:51:05ID: 19335836

is eshop.moc.psu.edu another name you are looking up?  Could the results be getting misaligned by your loop?  If not, thats really wierd :)

 

by: jlwPosted on 2007-06-21 at 11:57:25ID: 19335895

Absolutely not, no.   It's possible that at one time, "eshop.moc.psu.edu" would have been the correct response to the IP address, but not for some time.   It's like we're looking at a long-unsynchronized DNS server whenever we look at this IP address, and there are a multitude of others, too, in this 500+ IP address sample.

My "DNS Expert" looked at these results and said that the 88.225 response should have been
the same as the 88.200 response.   So he's got something hosed up in DNS, we suspect.    Maybe his Net::DNS module, if I have it or can get it loaded, will let me restrict my queries to the default 88.200 server.

 

by: jlwPosted on 2007-06-21 at 12:07:37ID: 19335982

OK, I've got Net::DNS installed on this system it seems.   So, given my current gethostbyaddr() Perl source, where:

$ipaddr contains a text dotted-decimal IP address.

            $name = gethostbyaddr (inet_aton($ipaddr), AF_INET)
                    or $name="";

What's the equivalent using Net::DNS, such that I restrict myself to a specific DNS server which I know returns the correct results to an NSLOOKUP query?

 

by: nociPosted on 2007-06-21 at 12:37:49ID: 19336203

I solved you problem.....

the query you ask is: 146.186.120.073
the query you should have asked: 146.186.120.73

The 0 prefix means taht you meant an octal number  => 073 = 8*7 +3 = 59
lest find out what: 146.186.120.59 gives:

dig -x 146.186.120.59
; <<>> DiG 9.4.1 <<>> -x 146.186.120.59
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50886
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 0

;; QUESTION SECTION:
;59.120.186.146.in-addr.arpa.   IN      PTR

;; ANSWER SECTION:
59.120.186.146.in-addr.arpa. 42547 IN   CNAME   59.0-26.120.186.146.in-addr.arpa.
59.0-26.120.186.146.in-addr.arpa. 85747 IN PTR  eshop.moc.psu.edu.

;; AUTHORITY SECTION:
0-26.120.186.146.in-addr.arpa. 85747 IN NS      r02a07.cac.psu.edu.
0-26.120.186.146.in-addr.arpa. 85747 IN NS      r02n10-fddi.cac.psu.edu.
0-26.120.186.146.in-addr.arpa. 85747 IN NS      r02n08-fddi.cac.psu.edu.

;; Query time: 16 msec
;; SERVER: 192.168.6.1#53(192.168.6.1)
;; WHEN: Thu Jun 21 21:31:01 2007
;; MSG SIZE  rcvd: 175

Voila, eshop.moc.psu.edu.....


073  <> 73!!!!

Now about Net::DNS..

Have you actual looked at: perldoc Net::DNS
or at the source (the module itself) it's plain ascii and the documentation is inside it.
(perldoc is a way to show it in a different way).
Net::DNS isn't the quickets way...

Probably you just want to remote prefix 0.....

 

by: tbeardenPosted on 2007-06-21 at 12:42:16ID: 19336238

use Net::DNS;
  my $res   = Net::DNS::Resolver->new( nameservers => [qw(10.1.1.1)] );
  my $query = $res->search($ipaddr);
 
  if ($query) {
      foreach my $rr ($query->answer) {
          next unless $rr->type eq "A";
          $name = $rr->address, "\n";
      }
  } else {
      warn "query failed: ", $res->errorstring, "\n";
  }

You will just need to change the nameserver ip, and then add from "my $query" on into your loop.

 

by: jlwPosted on 2007-06-21 at 12:59:15ID: 19336379

Oh, my.   Prefixing "0" in the dotted decimal tuples, that's interesting.   Quick, a regular expression to use to strip leading zeros from each tuple of the string in $ipaddr ?

 

by: jlwPosted on 2007-06-21 at 13:22:42ID: 19336594

So my code NOW reads:

            @i = split (/\./,$ipaddr);
            $ipaddr = sprintf("%d.%d.%d.%d", @i[0],@i[1],@i[2],@i[3]);
            $name = gethostbyaddr (inet_aton($ipaddr), AF_INET)
                    or $name="";

Yeah, I can probably do it a lot cleaner than that, but it gets the job done.

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...