79264239

Date: 2024-12-09 08:17:08
Score: 1
Natty:
Report link

Invalid IPv6 Format Provided

I found the issue: the IPv6 address I was using for the query was incorrect. After fixing it, the following code worked as expected:

int main() {
    DHCP_CLIENT_INFO_V6 clientInfo = { 0 };
    DHCP_IPV6_ADDRESS clientAddress = { 0 };

    // Correct IPv6 address: 2022::74c0:f5e6:feca:3fb3
    clientAddress.HighOrderBits = 0x2022000000000000;
    clientAddress.LowOrderBits = 0x74c0f5e6feca3fb3;
    clientInfo.ClientIpAddress = clientAddress;

    DHCP_SEARCH_INFO_V6 query{};
    query.SearchType = Dhcpv6ClientIpAddress;
    query.SearchInfo.ClientIpAddress = clientAddress;

    LPDHCP_CLIENT_INFO_V6 result{ 0 };
    DWORD ret = DhcpGetClientInfoV6(L"WIN-QI9RF26NQVN", &query, &result);

    if (ret == ERROR_SUCCESS) {
        //
        // Process the result...
        //
    } else {
        std::cout << std::to_string(ret) << std::endl;
    }
}

To make the implementation more robust, I wrote a helper function to convert IN6_ADDR to DHCP_IPV6_ADDRESS:

// Converts IN6_ADDR to DHCP_IPV6_ADDRESS
static void convertToDHCPIPv6(const IN6_ADDR* in6Addr, DHCP_IPV6_ADDRESS* dhcpAddr) {
    if (!in6Addr || !dhcpAddr) return;

    dhcpAddr->HighOrderBits = 0;
    dhcpAddr->LowOrderBits = 0;
    for (size_t i = 0; i < 4; i++) {
        dhcpAddr->HighOrderBits = (dhcpAddr->HighOrderBits << 16) | ntohs(in6Addr->u.Word[i]);
    }
    for (size_t i = 4; i < 8; i++) {
        dhcpAddr->LowOrderBits = (dhcpAddr->LowOrderBits << 16) | ntohs(in6Addr->u.Word[i]);
    }
}

Here’s the complete, improved implementation:

static std::string LookupIPv6(const std::string& ip) {
    IN6_ADDR addr{};
    if (inet_pton(AF_INET6, ip.c_str(), &addr) != 1) {
        throw std::invalid_argument("Invalid IPv6 address");
    }

    DHCP_IPV6_ADDRESS clientIp;
    convertToDHCPIPv6(&addr, &clientIp);

    DHCP_SEARCH_INFO_V6 query{};
    query.SearchType = Dhcpv6ClientIpAddress;
    query.SearchInfo.ClientIpAddress = clientIp;

    LPDHCP_CLIENT_INFO_V6 result{ 0 };
    DWORD ret = DhcpGetClientInfoV6(DHCPSERVER, &query, &result);

    if (ret != ERROR_SUCCESS || !result) {
        std::string msg;
        switch (ret) {
        case ERROR_DHCP_JET_ERROR:
        case ERROR_DHCP_INVALID_DHCP_CLIENT:
            msg = "DHCP client not found.";
            break;
        default:
            msg = "Failed to get DHCP client info, error code : " + std::to_string(ret);
            break;
        }
        FreeClientInfoMemoryV6(result);
        throw std::runtime_error(msg);
    }

    char mac[128]{};
    BYTE* macData = result->ClientDUID.Data;
    size_t macLength = result->ClientDUID.DataLength;

    size_t len = macLength < sizeof(mac) / 3 ? macLength : sizeof(mac) / 3;

    char* macPtr = mac;
    for (size_t i = 0; i < len; i++) {
        int printed = (i == len - 1) ?
            snprintf(macPtr, sizeof(mac) - (macPtr - mac), "%02x", macData[i]) :
            snprintf(macPtr, sizeof(mac) - (macPtr - mac), "%02x:", macData[i]);
        macPtr += printed;
    }
    FreeClientInfoMemoryV6(result);

    return std::string(mac);
}

Issue: Status Code Returns 2

Although this code now works correctly, I am still unsure why the status code returns 2. If anyone can provide insights into this specific error code, it would be much appreciated.

Reasons:
  • Blacklisted phrase (1): appreciated
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: haiyang tao