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);
}
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.