When I used the DhcpGetClientInfoV6
function in dhcpsapi.h
, it returned code 2. After searching, I found the content, but I couldn't understand it.
$ .\Err_6.4.5.exe 2
# for hex 0x2 / decimal 2
BTH_ERROR_NO_CONNECTION bthdef.h
DEVICE_QUEUE_NOT_BUSY bugcodes.h
CDERR_INITIALIZATION cderr.h
CR_OUT_OF_MEMORY cfgmgr32.h
DHCP_DROP_NOMEM dhcpssdk.h
MD_ERROR_SUB400_INVALID_DEPTH iiscnfg.h
MD_ERROR_SUB401_LOGON_CONFIG iiscnfg.h
MD_ERROR_SUB403_READ_ACCESS_DENIED iiscnfg.h
MD_ERROR_SUB404_DENIED_BY_POLICY iiscnfg.h
MD_ERROR_SUB423_NO_CONFLICTING_LOCK iiscnfg.h
MD_ERROR_SUB502_PREMATURE_EXIT iiscnfg.h
MD_ERROR_SUB503_APP_CONCURRENT iiscnfg.h
IME_RS_NOIME ime.h
# IME is not installed
RSVP_Err_POLICY lpmapi.h
RSVP_Erv_Bandwidth lpmapi.h
# /* Insufficient bandwidth */
RSVP_Erv_No_Serv lpmapi.h
# /* Unknown Service */
RSVP_Erv_API lpmapi.h
# /* API logic error */
POLICY_ERRV_UNSUPPORTED_CREDENTIAL_TYPE lpmapi.h
POLICY_ERRV_GLOBAL_GRP_FLOW_COUNT lpmapi.h
MSIDBERROR_REQUIRED msiquery.h
# non-nullable column no null values allowed
NMERR_INVALID_HFILTER netmon.h
SMART_INVALID_FLAG ntdddisk.h
# Invalid command flag
DS_NAME_ERROR_NOT_FOUND ntdsapi.h
STATUS_WAIT_2 ntstatus.h
ODBC_ERROR_INVALID_BUFF_LEN odbcinst.h
MSDRI_S_MMI_PENDING pbdaerrors.h
MFE_NOT_FORWARDING routprot.h
# not fwding for an unspecified reason
SCESTATUS_RECORD_NOT_FOUND scesvc.h
SE_ERR_FNF shellapi.h
# file not found
SNMP_ERRORSTATUS_NOSUCHNAME snmp.h
SNMP_GENERICTRAP_LINKDOWN snmp.h
ICERR_NEWPALETTE vfw.h
WDSMCCLIENT_CATEGORY wdsmcerr.h
# WDS Multicast Client
WINBIO_FP_TOO_LOW winbio_err.h
# Position your finger higher on the fingerprint reader.
CMC_STATUS_FAILED wincrypt.h
CMC_FAIL_BAD_REQUEST wincrypt.h
DRM_S_MORE_DATA windowsplayready.h
ERROR_FILE_NOT_FOUND winerror.h
# The system cannot find the file specified.
ERROR_LABEL_QUESTIONABLE winioctl.h
# Label could be invalid due to unit attention condition.
LDAP_PROTOCOL_ERROR winldap.h
SNMP_ERROR_NOSUCHNAME winsnmp.h
# as an HRESULT: Severity: SUCCESS (0), FACILITY_NONE (0x0), Code 0x2
# for hex 0x2 / decimal 2
WINBIO_FP_TOO_LOW winbio_err.h
# Position your finger higher on the fingerprint reader.
# as an HRESULT: Severity: SUCCESS (0), FACILITY_NULL (0x0), Code 0x2
ERROR_FILE_NOT_FOUND winerror.h
# The system cannot find the file specified.
# 43 matches found for "2"
The possible code is ERROR_FILE_NOT_FOUND
in winerror.h
.
However, after I changed the corresponding code in winerror.h
and recompiled, the return code was still 2. I can't determine where the problem occurred. Please help.
This my code:
std::string LookupIPv6(const std::string& ip) {
struct in6_addr addr;
if (inet_pton(AF_INET6, ip.c_str(), &addr) != 1) {
throw std::invalid_argument("Invalid IPv6 address");
}
DHCP_SEARCH_INFO_V6 query;
ZeroMemory(&query, sizeof(query));
query.SearchType = Dhcpv6ClientIpAddress;
memcpy(&query.SearchInfo.ClientIpAddress, &addr, sizeof(addr));
LPDHCP_CLIENT_INFO_V6 result = nullptr;
DWORD ret = DhcpGetClientInfoV6(nullptr, &query, &result);
if (ret != ERROR_SUCCESS || !result) {
FreeClientInfoMemoryV6(result);
throw std::runtime_error("Failed to get DHCP client info, error code: " + std::to_string(ret));
}
char mac[64];
BYTE* macData = result->ClientDUID.Data;
snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
macData[0], macData[1], macData[2], macData[3], macData[4], macData[5]);
FreeClientInfoMemoryV6(result);
return std::string(mac);
}
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.