Question about host, gethostbyname and getaddress

V

Vladimir Fekete

Hi *,

Could you pleas help me with following problem ?

I need to get FQDN of host as well as it's IP. So I need same result as
"host" command gives me in *nix OSes. I found out these (suitable) functions:

Socket.getaddrinfo
IPSocket.getaddress
TCPSocket.gethostbyname

which can do the job (partialy). My problem is that non of them gives me
back FQDN. Eg. let's say that I have myserver.mydomain.com which is FQDN and
it's alias is myserver.

My problem is that when I use any of those functions with "myserver"
attribiute I always get as set of aliases ["myserver"] array only (e.g. no
myserver.mydomain.com).

Is there any way how to find out FQDN via some ruby function ? Thanks!

Regards,

V.
 
A

Alan Johnson

Hi *,

Could you pleas help me with following problem ?

I need to get FQDN of host as well as it's IP. So I need same result as
"host" command gives me in *nix OSes. I found out these (suitable) functions:

Socket.getaddrinfo
IPSocket.getaddress
TCPSocket.gethostbyname

which can do the job (partialy). My problem is that non of them gives me
back FQDN. Eg. let's say that I have myserver.mydomain.com which is FQDN and
it's alias is myserver.

My problem is that when I use any of those functions with "myserver"
attribiute I always get as set of aliases ["myserver"] array only (e.g. no
myserver.mydomain.com).

Is there any way how to find out FQDN via some ruby function ? Thanks!

Regards,

V.

gethostbyname and gethostbyaddr both return the "canonical name" in the first
element of the output array. If you are dealing with IP addresses gethostbyaddr
can do a reverse lookup for you (but not gethostbyname).

One tricky bit is that gethostbyaddr expects a struct in_addr packed into a
Ruby string. See inet_ntoa below to help with that.

Examples:

require 'socket'
def inet_aton(ip)
ip.split('.').inject(String.new) { |str, q| str << q.to_i }
end

p Socket.gethostbyname('www.google.com')[0]
p Socket.gethostbyaddr(inet_aton("127.0.0.1"))[0]
 
V

Vladimir Fekete

Hello Alan,

I think we don't understand each other. I don't need reverse DNS (I would use
resolv.rb for it instead). What I need is:

you have machine with fully qualified domain name (FQDN)
a.b.c.d.e
It's hostname is
a
It's IP is
v.x.y.z

I'm looking for function which could give me back fully qualified domain
name and IP when I pass hostname as argument.

Probably I don't understand what is canonical name I thought it should be FQDN
but it is not.

because this code:

puts "getaddress : " + IPSocket.getaddress("a").inspect
puts "gethostbyname : " + TCPSocket.gethostbyname("a").inspect

has result:

getaddress : "10.0.2.1"
gethostbyname : ["a", [], 2, "10.0.2.1"]

and what i need is result like this:

gethostbyname : ["a.b.c.d.e", ["a"], 2, "10.0.2.1"]

I hope it's more clear now. (or maybe I completely did not get what you
wanted to tell me)

Cheers,

V.

Hi *,

Could you pleas help me with following problem ?

I need to get FQDN of host as well as it's IP. So I need same result as
"host" command gives me in *nix OSes. I found out these (suitable) functions:

Socket.getaddrinfo
IPSocket.getaddress
TCPSocket.gethostbyname

which can do the job (partialy). My problem is that non of them gives me
back FQDN. Eg. let's say that I have myserver.mydomain.com which is FQDN and
it's alias is myserver.

My problem is that when I use any of those functions with "myserver"
attribiute I always get as set of aliases ["myserver"] array only (e.g. no
myserver.mydomain.com).

Is there any way how to find out FQDN via some ruby function ? Thanks!

Regards,

V.

gethostbyname and gethostbyaddr both return the "canonical name" in the first
element of the output array. If you are dealing with IP addresses gethostbyaddr
can do a reverse lookup for you (but not gethostbyname).

One tricky bit is that gethostbyaddr expects a struct in_addr packed into a
Ruby string. See inet_ntoa below to help with that.

Examples:

require 'socket'
def inet_aton(ip)
ip.split('.').inject(String.new) { |str, q| str << q.to_i }
end

p Socket.gethostbyname('www.google.com')[0]
p Socket.gethostbyaddr(inet_aton("127.0.0.1"))[0]
 
A

Alan Johnson

Hello Alan,

I think we don't understand each other. I don't need reverse DNS (I would use
resolv.rb for it instead). What I need is:

you have machine with fully qualified domain name (FQDN)
a.b.c.d.e
It's hostname is
a
It's IP is
v.x.y.z

I'm looking for function which could give me back fully qualified domain
name and IP when I pass hostname as argument.

Probably I don't understand what is canonical name I thought it should be FQDN
but it is not.

because this code:

puts "getaddress : " + IPSocket.getaddress("a").inspect
puts "gethostbyname : " + TCPSocket.gethostbyname("a").inspect

has result:

getaddress : "10.0.2.1"
gethostbyname : ["a", [], 2, "10.0.2.1"]

and what i need is result like this:

gethostbyname : ["a.b.c.d.e", ["a"], 2, "10.0.2.1"]

I hope it's more clear now. (or maybe I completely did not get what you
wanted to tell me)

Cheers,

V.

TCPSocket.gethostbyname is confusingly inconsistent with Socket.gethostbyname.
I suggest always using the Socket version. I think it will work the way you
want it to.

Alternatively, the getaddrinfo method may do what you are looking for.
Technically getaddrinfo obsoletes gethostbyname, anyway. It looks like:
Socket.getaddrinfo(host, port [, family] [, socktype] [, protocol] [,
flags]) => resultsArray

The rules for using it are pretty complicated but you'll probably want to do
something like:

include Socket::Constants
p Socket.getaddrinfo('myhost', nil, AF_INET, SOCK_STREAM)

Note that in either case your reverse DNS lookup must be configured correctly
or all you will get is an ip address. You can test this using the nslookup
command from a command prompt in Linux or Windows.
 
V

Vladimir Fekete

Hello Alan,

I have to say you are not right. And if you are, then there is somwhere
huge problem, because it behaves in completely different way as it should.
I tried to use getaddrinfo aswell, but the result was same (no canonical
name). Performance was terrible (17 times slower than getaddress and approx.
4 times slower than gethostbyname).

Next thing is, that I don't have to have reverse dns set up, in fact I
don't. Reason why I believe this is true is, that "host" command works
perfectly withouth correct reverse dns. I thought that it is due to line in
/etc/hosts where I assigned IP to conanical name and aliases, but when I
commented out this line it worked as good as before.

result of command host a :
a.b.c.d.e.f.g has address 10.0.2.1

result of nslookup 10.0.2.1 :

Server: v.x.y.z
Address: v.x.y.z#53

** server can't find 1.2.0.10.in-addr.arpa: NXDOMAIN


So if "host" command works and all ruby's functions don't I assume there is
some problem in ruby.

Regards,

V.


Hello Alan,

I think we don't understand each other. I don't need reverse DNS (I would use
resolv.rb for it instead). What I need is:

you have machine with fully qualified domain name (FQDN)
a.b.c.d.e
It's hostname is
a
It's IP is
v.x.y.z

I'm looking for function which could give me back fully qualified domain
name and IP when I pass hostname as argument.

Probably I don't understand what is canonical name I thought it should be FQDN
but it is not.

because this code:

puts "getaddress : " + IPSocket.getaddress("a").inspect
puts "gethostbyname : " + TCPSocket.gethostbyname("a").inspect

has result:

getaddress : "10.0.2.1"
gethostbyname : ["a", [], 2, "10.0.2.1"]

and what i need is result like this:

gethostbyname : ["a.b.c.d.e", ["a"], 2, "10.0.2.1"]

I hope it's more clear now. (or maybe I completely did not get what you
wanted to tell me)

Cheers,

V.

TCPSocket.gethostbyname is confusingly inconsistent with Socket.gethostbyname.
I suggest always using the Socket version. I think it will work the way you
want it to.

Alternatively, the getaddrinfo method may do what you are looking for.
Technically getaddrinfo obsoletes gethostbyname, anyway. It looks like:
Socket.getaddrinfo(host, port [, family] [, socktype] [, protocol] [,
flags]) => resultsArray

The rules for using it are pretty complicated but you'll probably want to do
something like:

include Socket::Constants
p Socket.getaddrinfo('myhost', nil, AF_INET, SOCK_STREAM)

Note that in either case your reverse DNS lookup must be configured correctly
or all you will get is an ip address. You can test this using the nslookup
command from a command prompt in Linux or Windows.
 
V

Vladimir Fekete

Hi,

From: Vladimir Fekete [mailto:[email protected]]
# ... why I believe this is true is, that "host" command works
# perfectly withouth correct reverse dns....


try resolv.

eg,
require 'resolv'
=> true
Resolv.getname "10.2.10.123"
=> "bg-mis-pbot.delmonte-phil.com"

i believe that is my pc ;)
Resolv.getname "10.2.10.23"
=> "bgmissappm00.delmonte-phil.com"

this does not work either.
Code:
#!/usr/bin/env ruby

require 'resolv'

puts Resolv.getname("10.0.2.1").to_s


result:

/usr/lib/ruby/1.8/resolv.rb:128:in `getname': no name for 10.0.2.1
/(Resolv::ResolvError)
from /usr/lib/ruby/1.8/resolv.rb:64:in `getname'
from ./test.rb:6

so as I said before, I don't have reverse dns (e.g. to get in-addr.arpa
from dns) and host command works, rubys' commands dont. :-( I guess I will
have to use `host` insted of pure ruby code.

regards,

V.
 
P

Peña, Botp

From: Vladimir Fekete [mailto:[email protected]]=20
# so as I said before, I don't have reverse dns (e.g. to get=20
# in-addr.arpa from dns)

oops, yes, just read the thread sorry.

try,

Socket.do_not_reverse_lookup=3Dtrue
 
V

Vladimir Fekete

Hi,

From: Vladimir Fekete [mailto:[email protected]]
# so as I said before, I don't have reverse dns (e.g. to get
# in-addr.arpa from dns)

oops, yes, just read the thread sorry.

try,

Socket.do_not_reverse_lookup=true

no, not helped, result is still same - no canonical name in array :-(


V.
 
A

Alan Johnson

Hello Alan,

I have to say you are not right.

Ugh. I am very sorry. I've discovered why we are getting different results.
I submitted a patch last night that changes the way gethostbyname/gethostbyaddr
work. You see, right now they use a combination of several calls to functions
in the underlying OS and combine the output of them into the results you see.
I changed them to just faithfully call the underlying OS version of
gethostbyname/gethostbyaddr. See http://redmine.ruby-lang.org/issues/show/743
if you care about more details.

Somewhere along the way this patched version worked its way ahead of the stock
version in my path. I name the executables differently to avoid this sort of
confusion, but apparently I messed up somewhere.

So, the bad news is once I fixed the error and tested with ruby 1.8, I'm
getting similar results to you. The good news is that if that patch is
accepted then this problem will go away in the future (not that that helps you
any right now).

Apologies for any frustrations I've caused you.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top