HRESULT HostNetworkInterface::enableStaticIPConfigV6(const com::Utf8Str &aIPV6Address,
                                                     ULONG aIPV6NetworkMaskPrefixLength)
{
#ifndef VBOX_WITH_HOSTNETIF_API
    return E_NOTIMPL;
#else
    if (aIPV6NetworkMaskPrefixLength > 128)
        return E_INVALIDARG;

    int rc = S_OK;
    if (   m.realIPV6Address      != aIPV6Address
        || m.realIPV6PrefixLength != aIPV6NetworkMaskPrefixLength)
    {
        BSTR bstr;
        aIPV6Address.cloneTo(&bstr);
        if (aIPV6NetworkMaskPrefixLength == 0)
            aIPV6NetworkMaskPrefixLength = 64;
        rc = NetIfEnableStaticIpConfigV6(mVirtualBox, this, m.IPV6Address.raw(),
                                         bstr, aIPV6NetworkMaskPrefixLength);
        if (RT_FAILURE(rc))
        {
            LogRel(("Failed to EnableStaticIpConfigV6 with rc=%Rrc\n", rc));
            return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
        }
        else
        {
            m.realIPV6Address = aIPV6Address;
            m.realIPV6PrefixLength = aIPV6NetworkMaskPrefixLength;
            if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%ls/IPV6Address",
                                                         mInterfaceName.raw()).raw(),
                                                 Bstr(aIPV6Address).raw())))
                return E_FAIL;
            if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%ls/IPV6NetMask",
                                                         mInterfaceName.raw()).raw(),
                                                 BstrFmt("%u", aIPV6NetworkMaskPrefixLength).raw())))
                return E_FAIL;
        }

    }
    return S_OK;
#endif
}
STDMETHODIMP HostNetworkInterface::EnableStaticIpConfigV6 (IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
{
#ifndef VBOX_WITH_HOSTNETIF_API
    return E_NOTIMPL;
#else
    if (!aIPV6Address)
        return E_INVALIDARG;
    if (aIPV6MaskPrefixLength > 128)
        return E_INVALIDARG;

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    int rc = S_OK;
    if (m.realIPV6Address != aIPV6Address || m.realIPV6PrefixLength != aIPV6MaskPrefixLength)
    {
        if (aIPV6MaskPrefixLength == 0)
            aIPV6MaskPrefixLength = 64;
        rc = NetIfEnableStaticIpConfigV6(mVBox, this, m.IPV6Address.raw(), aIPV6Address, aIPV6MaskPrefixLength);
        if (RT_FAILURE(rc))
        {
            LogRel(("Failed to EnableStaticIpConfigV6 with rc=%Rrc\n", rc));
            return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
        }
        else
        {
            m.realIPV6Address = aIPV6Address;
            m.realIPV6PrefixLength = aIPV6MaskPrefixLength;
            if (FAILED(mVBox->SetExtraData(BstrFmt("HostOnly/%ls/IPV6Address", mInterfaceName.raw()).raw(),
                                           Bstr(aIPV6Address).raw())))
                return E_FAIL;
            if (FAILED(mVBox->SetExtraData(BstrFmt("HostOnly/%ls/IPV6NetMask", mInterfaceName.raw()).raw(),
                                           BstrFmt("%u", aIPV6MaskPrefixLength).raw())))
                return E_FAIL;
        }

    }
    return S_OK;
#endif
}
HRESULT HostNetworkInterface::enableStaticIPConfigV6(const com::Utf8Str &aIPV6Address,
                                                     ULONG aIPV6NetworkMaskPrefixLength)
{
#ifndef VBOX_WITH_HOSTNETIF_API
    return E_NOTIMPL;
#else
    if (aIPV6NetworkMaskPrefixLength > 128)
        return mVirtualBox->setErrorBoth(E_INVALIDARG, VERR_INVALID_PARAMETER,
                   "Invalid IPv6 prefix length");

    int rc;

    RTNETADDRIPV6 AddrOld, AddrNew;
    char *pszZoneIgnored;
    bool fAddrChanged;

    rc = RTNetStrToIPv6Addr(aIPV6Address.c_str(), &AddrNew, &pszZoneIgnored);
    if (RT_FAILURE(rc))
    {
        return mVirtualBox->setErrorBoth(E_INVALIDARG, rc, "Invalid IPv6 address");
    }

    rc = RTNetStrToIPv6Addr(com::Utf8Str(m.realIPV6Address).c_str(), &AddrOld, &pszZoneIgnored);
    if (RT_SUCCESS(rc))
    {
        fAddrChanged = (AddrNew.s.Lo != AddrOld.s.Lo || AddrNew.s.Hi != AddrOld.s.Hi);
    }
    else
    {
        fAddrChanged = true;
    }

    if (   fAddrChanged
        || m.realIPV6PrefixLength != aIPV6NetworkMaskPrefixLength)
    {
        if (aIPV6NetworkMaskPrefixLength == 0)
            aIPV6NetworkMaskPrefixLength = 64;
        rc = NetIfEnableStaticIpConfigV6(mVirtualBox, this, m.IPV6Address.c_str(),
                                         aIPV6Address.c_str(),
                                         aIPV6NetworkMaskPrefixLength);
        if (RT_FAILURE(rc))
        {
            LogRel(("Failed to EnableStaticIpConfigV6 with rc=%Rrc\n", rc));
            return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
        }
        else
        {
            m.realIPV6Address = aIPV6Address;
            m.realIPV6PrefixLength = aIPV6NetworkMaskPrefixLength;
#if defined(RT_OS_WINDOWS)
            saveAdapterConfigIPv6(Bstr(aIPV6Address).raw(), aIPV6NetworkMaskPrefixLength);
#else /* !defined(RT_OS_WINDOWS) */
            if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPV6Address",
                                                         mInterfaceName.c_str()).raw(),
                                                 Bstr(aIPV6Address).raw())))
                return E_FAIL;
            if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPV6NetMask",
                                                         mInterfaceName.c_str()).raw(),
                                                 BstrFmt("%u", aIPV6NetworkMaskPrefixLength).raw())))
#endif /* !defined(RT_OS_WINDOWS) */
                return E_FAIL;
        }

    }
    return S_OK;
#endif
}