Skip to content

#native results in incorrect mask, breaking #prefix #27

Description

@zarqman

Calling native leaves the internal @mask_addr as its ipv6 mask instead of converting it to an ipv4 mask. This is most easily seen when calling prefix, but also breaks to_range and possibly other methods.

IPAddr.new('::ffff:1.2.3.4/127')
# => #<IPAddr: IPv6:0000:0000:0000:0000:0000:ffff:0102:0304/ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe> 
IPAddr.new('::ffff:1.2.3.4/127').prefix
# => 127 
IPAddr.new('::ffff:1.2.3.4/127').native
# => #<IPAddr: IPv4:1.2.3.4/255.255.255.254> 
IPAddr.new('::ffff:1.2.3.4/127').native.prefix
# => -96                <-- should be 31
IPAddr.new('1.2.3.4/31').prefix
# => 31 
IPAddr.new('::ffff:1.2.3.4/127').native.instance_variable_get :@mask_addr
# => 340282366920938463463374607431768211454       <-- root issue

Similarly, ipv4_mapped and ipv4_compat also fail to adjust @mask_addr the other direction.

IPAddr.new('1.2.3.4/31').ipv4_mapped
# => #<IPAddr: IPv6:0000:0000:0000:0000:0000:ffff:0102:0304/0000:0000:0000:0000:0000:0000:ffff:fffe> 
IPAddr.new('1.2.3.4/31').ipv4_mapped.prefix
# => 0                  <-- should be 127
IPAddr.new('1.2.3.4/31').ipv4_mapped.instance_variable_get :@mask_addr
# => 4294967294 

IPAddr.new('1.2.3.4/31').ipv4_compat
# => #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0102:0304/0000:0000:0000:0000:0000:0000:ffff:fffe> 
IPAddr.new('1.2.3.4/31').ipv4_compat.prefix
# => 0 
IPAddr.new('1.2.3.4/31').ipv4_compat.instance_variable_get :@mask_addr
# => 4294967294 

Activity

  1. hanazuki commented on Nov 28, 2023

    @hanazuki
    Contributor

    #34 fixed #native.
    #31 fixed #ipv4_mapped.

    #ipv4_compat still returns an inconsistent mask. As it's been deprecated (in IETF and in this library), I don't think we need to maintain it.
    However, this violation in object invariant ("the netmask must be consecutive 1s followed by consecutive 0s") may cause other problems and I'd propose fixing it like #ipv4_mapped if we cannot remove #ipv4_compat now.

  2. hanazuki commented on Nov 28, 2023

    @hanazuki
    Contributor

    #18 also tried to resolve this issue regarding netmask conversion in a consistent way.

  3. taketo1113 commented on Sep 26, 2025

    @taketo1113
    Collaborator

    #34 fixed #native. #31 fixed #ipv4_mapped.

    #ipv4_compat still returns an inconsistent mask. As it's been deprecated (in IETF and in this library), I don't think we need to maintain it. However, this violation in object invariant ("the netmask must be consecutive 1s followed by consecutive 0s") may cause other problems and I'd propose fixing it like #ipv4_mapped if we cannot remove #ipv4_compat now.

    #ipv4_mapped was also fixed in #86.

    The current behavior is as follows:

     IPAddr.new('1.2.3.4/31').ipv4_compat
    => #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0102:0304/ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe>
    
    IPAddr.new('1.2.3.4/31').ipv4_compat.prefix
    => 127
    
    IPAddr.new('1.2.3.4/31').ipv4_compat.instance_variable_get :@mask_addr
    => 340282366920938463463374607431768211454
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions