Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a method to convert from IPAddr to IP #19

Open
madis opened this issue Oct 20, 2015 · 2 comments
Open

Add a method to convert from IPAddr to IP #19

madis opened this issue Oct 20, 2015 · 2 comments

Comments

@madis
Copy link

madis commented Oct 20, 2015

I find the ruby-ip functionality much better than the standard library's IPAddr but for example Rails converts ip adddresses automatically to IPAddr. It would be very useful if this gem had a way to convert from IPAddr to IP.

E.g. something like

a = IP.from_ipaddr(IPAddr.new('192.168.0.1/22'))
# or
b = IP.new(IPAddr.new('192.168.0.1/22'))
@madis madis changed the title Add a method to ocnvert from IPAddr to IP Add a method to convert from IPAddr to IP Oct 20, 2015
@martin-schmidt
Copy link

I wrote some methods making this possible. The pull is pending but you can give it a try here: https://github.com/martin-schmidt/ruby-ip/tree/feature-to_hton

I need the code to store IPs in a database, but it can also be used to convert from IPAddr to IP and the other way around:

# new IPAddr
ipaddr = IPAddr.new('192.168.2.1')
# => #<IPAddr: IPv4:192.168.2.1/255.255.255.255>

# convert it to IP
ip_from_ipaddr = IP.new_ntoh(ipaddr.hton)
# => <IP::V4 192.168.2.1>

# and back to IPAddr, because we can
ipaddr_from_ip = IPAddr.new_ntoh(ip_from_ipaddr.hton)
# => #<IPAddr: IPv4:192.168.2.1/255.255.255.255>

@candlerb
Copy link
Contributor

candlerb commented Nov 5, 2015

I don't like the names "ntoh" and "hton", as these have different and widely-known meanings in the socket world. ("ntoh" means convert from network byte order to host byte order, and "hton" is the opposite).

However if the IPAddr library already new_ntoh and hton methods, then maybe we are stuck with this bad naming to be consistent.

You can already do the following:

>> ipaddr = IPAddr.new('192.168.2.1')
=> #<IPAddr: IPv4:192.168.2.1/255.255.255.255>

>> ip_from_ipaddr = IP::V4.new(ipaddr.to_i)
=> #<IP::V4 192.168.2.1>

>> ipaddr_from_ip = IPAddr.new(ip_from_ipaddr, Socket::AF_INET)
=> #<IPAddr: IPv4:192.168.2.1/255.255.255.255>

But this requires you to know the address family.

So it seems what you are really suggesting is two things:

  1. Add a new export/import format which is a raw binary byte sequence. I have no problem with that.
  2. Make ruby-ip guess the address family based on the length of the byte sequence: if it's 4 bytes then IPv4, if it's 16 bytes then IPv6. It seems that's what IPAddr does:
>> RUBY_VERSION
=> "2.2.3"
>> require 'ipaddr'
=> true
>> IPAddr.new_ntoh("\x00\x01\x02\x03")
=> #<IPAddr: IPv4:0.1.2.3/255.255.255.255>
>> IPAddr.new_ntoh("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f")=> #<IPAddr: IPv6:0001:0203:0405:0607:0809:0a0b:0c0d:0e0f/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>

Looking at source, IPAddr.new_ntoh(addr) just calls IPAddr.new(IPAddr::ntop(addr)). That is, it converts the byte sequence to a human-readable form, then parses the printable form.

For ruby-ip I'd want a new version of parse which reads a byte string and directly packs it, returning nil if the string is the wrong length, for consistency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants