IPAddress::getInterfaceBroadcastAddress for ipv4/Win32

Hi!

Here an implementation proposal for missing IPAddress::getInterfaceBroadcastAddress on Win32.

This now only support ipv4.

Hopping this can helps:

struct ConvertLengthToIpv4MaskHelper
{
  bool callConvertLengthToIpv4Mask(ULONG maskLength)
  {
    DynamicLibrary dll("iphlpapi.dll");
    JUCE_LOAD_WINAPI_FUNCTION(dll, ConvertLengthToIpv4Mask, convertLengthToIpv4Mask, NETIO_STATUS, (ULONG, PULONG))

      if (convertLengthToIpv4Mask == nullptr)
        return false;

    return convertLengthToIpv4Mask(maskLength, &mask) == NO_ERROR;
  }

  ULONG mask;
};

IPAddress IPAddress::getInterfaceBroadcastAddress (const IPAddress& interfaceAddress)
{
    if (interfaceAddress == IPAddress()) // null ip address (0.0.0.0, 0:0:0:0:0:0:0:0 or ::)
      return broadcast(); // return broadcast for any interface 
    if (interfaceAddress == local(false))
      return local(false);
    if (interfaceAddress == local(true))
      return local(true);

    // TODO IPv6

    GetAdaptersAddressesHelper addressesHelper;

    if (addressesHelper.callGetAdaptersAddresses())
    {
      for (PIP_ADAPTER_ADDRESSES adapter = addressesHelper.adaptersAddresses; adapter != nullptr; adapter = adapter->Next)
      {
        for (auto addr = adapter->FirstUnicastAddress; addr != nullptr; addr = addr->Next)
        {
          if (addr->Address.lpSockaddr->sa_family == AF_INET && MACAddressHelpers::createAddress((sockaddr_in*)addr->Address.lpSockaddr) == interfaceAddress)
          {
            ConvertLengthToIpv4MaskHelper convertLengthToIpv4MaskHelper;

            if (convertLengthToIpv4MaskHelper.callConvertLengthToIpv4Mask(addr->OnLinkPrefixLength))
            {
              ULONG mask = ~convertLengthToIpv4MaskHelper.mask;
              IPAddress maskIp = IPAddress(reinterpret_cast<const juce::uint8* >(&mask));

              IPAddress res = interfaceAddress;
              for (size_t i = 0; i < 4; ++i)
                res.address[i] |= maskIp.address[i];
              return res;
            }
          }
        }
      }
    }

    return {};
}

Intersting.

I had to do the same a couple weeks ago and already opened a pull request too.

Curious that this hasn’t been implemented yet, doesn’t seem like a big deal to me (at least I don’t have any problems with my implementation, works as expected and yours seems to do the job too… and i have no idea what I’m doing when it’s on a lower leven than juce). Or am I wrong and there are intricacies to this that I don’t see?

Hi benediktsailer,

Indeed your implementation seems to do the jobs too.
Just note that GetAdaptersInfo is deprecated in favor of GetAdaptersAddresses.

I think no one is impacted by this missing function except juce::NetworkServiceDiscovery, that should not works properly on Win32.

My Win32 software need getInterfaceBroadcastAddress, that is why I implement it.

May be Ipv6 support should be done to grant a Juce merge…
RFC.

All the best.

NB2: Your implementation do not iterate on pAdapter->IpAddressList.IpAddress.Next->
So you will miss adapter IP alias defined like that:

All the best

1 Like

Awesome, thanks for the hint! Software is about to ship soon, i didn’t catch that yet :slight_smile:

Also yes, the NetworkServiceDiscovery is impacted for sure. That’s how i found out this was missing :slight_smile:

1 Like