简体   繁体   中英

How to parse IP address blocks IPv4 / IPv6

I am creating an IP address class wrapper, and I want to differentiate the address types according to RFC 5735 Section 4 - Special Use IPv4 Addresses .

I want to

  • be able to test whether an address is within one of the blocks.
  • expand a block, so I get an array of IPAddress objects when returning.

If someone can help me by small sample code, or point me to existing code, I'd appreciate that. Sadly I find my brain can't wrap itself around the intricacy of this topic, that's why I am specifically asking for sample code. I know it's not polite to ask for source code like this, and I apologize.

When coming up with a unified IP address representation, it is important to realize that IPv4 addresses occupy 4 bytes and IPv6 addresses require 16 bytes. A naive wrapper implementation would use a union plus an enum discriminator to indicate the address type. Fortunately, this is not necessary because there exists an unambiguous representation of an IPv4 address within an IPv6 address. Keeping this in mind, your IP address wrapper class could look like this:

class address
{
  /// Top 96 bits of v4-mapped-addr.
  static std::array<uint8_t, 12> const v4_mapped_prefix =
    {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }};

public:
  address() = default;

  bool is_v4() const
  {
    return std::memcmp(&bytes_, &v4_mapped_prefix, 12) == 0;
  }

private:
  std::array<uint8_t, 16> bytes_;
};

Now to check whether you have a certain class of addresses, you can add member functions ad libitum. Here are examples for loopback, broadcast, and multicast:

bool is_loopback() const
{
  if (is_v4())
    return bytes_[12] == 127;
  else
    return ((bytes_[0] == 0) && (bytes_[1] == 0) &&
            (bytes_[2] == 0) && (bytes_[3] == 0) &&
            (bytes_[4] == 0) && (bytes_[5] == 0) &&
            (bytes_[6] == 0) && (bytes_[7] == 0) &&
            (bytes_[8] == 0) && (bytes_[9] == 0) &&
            (bytes_[10] == 0) && (bytes_[11] == 0) &&
            (bytes_[12] == 0) && (bytes_[13] == 0) &&
            (bytes_[14] == 0) && (bytes_[15] == 1));
}

bool is_broadcast() const
{
  return is_v4() &&
    bytes_[12] == 0xff && bytes_[13] == 0xff &&
    bytes_[14] == 0xff && bytes_[15] == 0xff;
}

bool is_multicast() const
{
  return is_v4() ? bytes_[12] == 224 : bytes_[0] == 0xff;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM