ruby / ipaddr

A class to manipulate an IP address

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

unsupported address family

marek22k opened this issue · comments

Hello,

I do not understand the following behavior:

3.2.2 :001 > require "ipaddr"
 => true 
3.2.2 :002 > x = IPAddr.new("172.20.222.160")
 => #<IPAddr: IPv4:172.20.222.160/255.255.255.255> 
3.2.2 :003 > IPAddr.ntop(x.hton)
 => "172.20.222.160" 
3.2.2 :004 > x.hton
 => "\xAC\x14\xDE\xA0" 
3.2.2 :005 > IPAddr.ntop("\xAC\x14\xDE\xA0")
/home/marek/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/ipaddr.rb:120:in `ntop': unsupported address family (IPAddr::AddressFamilyError)

      raise AddressFamilyError, "unsupported address family"
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	from (irb):5:in `<main>'
	from /home/marek/.rvm/gems/ruby-3.2.2/gems/irb-1.6.4/exe/irb:9:in `<top (required)>'
	from /home/marek/.rvm/gems/ruby-3.2.2/bin/irb:25:in `load'
	from /home/marek/.rvm/gems/ruby-3.2.2/bin/irb:25:in `<main>'
	from /home/marek/.rvm/gems/ruby-3.2.2/bin/ruby_executable_hooks:22:in `eval'
	from /home/marek/.rvm/gems/ruby-3.2.2/bin/ruby_executable_hooks:22:in `<main>'
3.2.2 :006 > y = x.hton
 => "\xAC\x14\xDE\xA0" 
3.2.2 :007 > IPAddr.ntop(y)
 => "172.20.222.160" 
3.2.2 :008 > y.class
 => String 
3.2.2 :001 > require "ipaddr"
 => true 
3.2.2 :002 > File.write("test", IPAddr.new("172.20.222.160").hton)
 => 4 
3.2.2 :003 > IPAddr.ntop(File.read("test"))
/home/marek/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/ipaddr.rb:120:in `ntop': unsupported address family (IPAddr::AddressFamilyError)

      raise AddressFamilyError, "unsupported address family"
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	from (irb):3:in `<main>'
	from /home/marek/.rvm/gems/ruby-3.2.2/gems/irb-1.6.4/exe/irb:9:in `<top (required)>'
	from /home/marek/.rvm/gems/ruby-3.2.2/bin/irb:25:in `load'
	from /home/marek/.rvm/gems/ruby-3.2.2/bin/irb:25:in `<main>'
	from /home/marek/.rvm/gems/ruby-3.2.2/bin/ruby_executable_hooks:22:in `eval'
	from /home/marek/.rvm/gems/ruby-3.2.2/bin/ruby_executable_hooks:22:in `<main>'

If I try to pass the binary string as a string, an error is returned, but if I do not pass the string as a variable, it works.
This error also occurred when I tried to read an IP address from an MRT file. I then had the string displayed and tried it manually (see above). But I also got the same error.

Actually, it is not appropriate to pass a non-binary string. A string literal written in source code is encoded in the default encoding, which is usually UTF-8.

require "ipaddr"

x = IPAddr.new("172.20.222.160")
p x.hton #=> "\xAC\x14\xDE\xA0"
p x.hton.encoding #=> #<Encoding:ASCII-8BIT>
# It properly round-trips.
p IPAdd.ntoh(x.hton) #=> "172.20.222.160"

p "\xAC\x14\xDE\xA0".encoding #=> #<Encoding::UTF-8>
# ntop does not take a non-binary string
p IPAddr.ntop("\xAC\x14\xDE\xA0") rescue $! #=> #<IPAddr::AddressFamilyError: unsupported address family>

# The correct way
p IPAddr.ntop("\xAC\x14\xDE\xA0".b) #=> "172.20.222.160"

Thanks for the explanation!