我已在Windows7中成功配置了NIC的IP地址。但拔出网线后,我无法从API和ipconfig获取IP地址,但我可以在“网络连接”中查看。如果我再次插入电缆,那么我可以再次获得该地址。
当NIC断开连接时,如何获取或更改NIC的IP地址?我使用过“GetAdaptersInfo”“GetIpAddrTable”或WMI类。以上所有方法都为此类NIC返回0.0.0.0 ipaddress。
我的平台是Windows7,我希望该方法适用于其他Windows平台。
谢谢!
答案 0 :(得分:1)
有人建议我更改注册表项,这将关闭媒体检测。
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\DisableDHCPMediaSense
Type: REG_DWORD
Value: 1
我已经测试了这个方法,但它仍然返回0.0.0.0,但我可以从reg中读取未插入的NIC的IP地址:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\[NIC_GUID]}\Parameters\Tcpip]
EnableDHCP
IPAddress
SubnetMask
DefaultGateway
答案 1 :(得分:1)
IP地址不是NIC固有的属性。它变为断开连接的瞬间就失去了它的IP。 IP由DHCP服务器分配,或者在实际连接时由您的OS静态分配。
答案 2 :(得分:1)
要从断开连接的NIC获取IP,请尝试使用netsh interface dump,例如:
netsh interface ipv4 dump name="Wireless Network Connection"
输出就像:
#----------------------------------
# IPv4 Configuration
# ----------------------------------
pushd interface ipv4
reset
set global icmpredirects=enabled
add address name="Wireless Network Connection" address=192.168.229.2 mask=255.255.255.0
popd
# End of IPv4 configuration
答案 3 :(得分:0)
如sshannin所述,仅在连接接口的情况下分配IP。如果您不想解析netsh的输出(如dmitry所述),则可以在以下位置检查注册表中的设置:
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\<GUID>
要分配给接口的IP地址在IPaddress
REG_MULTI_SZ
值中,该值是多个IP的字符串列表。
如果没有连接电缆,则有关DHCP的信息可能无效,因此请检查DisableDhcpOnConnect
。
以下代码输出找到的每个网络适配器的第一个IP地址(没有完整的错误处理):
#define WINNT 0x501
#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include <sstream>
#include <list>
#include <map>
#include <algorithm>
#include <iomanip>
#include <ws2ipdef.h>
#include <iphlpapi.h>
#undef __IPHLPAPI_H__
#include <winternl.h>
#include <netioapi.h> // In my SDK iphlpapi.h does not include netioapi.h !!!
#pragma comment (lib, "ws2_32")
#pragma comment (lib, "iphlpapi")
using namespace std;
class IP
{
public:
IP(unsigned long _ip = 0) : ip(ntohl(_ip)) {}
unsigned long ip;
};
wostream &operator<<(wostream &str, IP ip)
{
wostringstream o; o << ((ip.ip&0xff000000)>>24) << L"." << ((ip.ip&0xff0000)>>16) << L"." << ((ip.ip&0xff00)>>8) << L"." << (ip.ip&0xff);
return str << o.str();
}
typedef DWORD (__stdcall *fnGetIfTable2)(PMIB_IF_TABLE2*);
struct AdapterInfo
{
enum eCable {
connected,
disconnected,
unknown
} cable;
wstring FriendlyName;
wstring Description;
IP IpAddr;
IP Subnet;
bool dhcp;
unsigned char MAC[MAX_ADAPTER_ADDRESS_LENGTH];
ULONG64 speed;
AdapterInfo() : speed(0), cable(unknown) { memset(MAC, 0, sizeof(MAC)); };
};
map<unsigned long, AdapterInfo> Adapters;
int main()
{
WSADATA wsaData;
WSAStartup(MAKEWORD( 2, 2 ), &wsaData);
// 1. Gather the relevant interfaces (no loopback or IPv6)
// -------------------------------------------------------
list<unsigned long> Indices;
PIP_INTERFACE_INFO pIfTable = 0;
ULONG dwIfTableSize = 0;
while (GetInterfaceInfo(pIfTable, &dwIfTableSize) == ERROR_INSUFFICIENT_BUFFER) {
if (pIfTable)
free(pIfTable);
pIfTable = (PIP_INTERFACE_INFO)malloc(dwIfTableSize);
}
for (int i= 0; i < pIfTable->NumAdapters; ++i)
Indices.push_back(pIfTable->Adapter[i].Index);
free(pIfTable);
// 2. Get the IP address (only one per adapter)
// --------------------------------------------
PMIB_IPADDRTABLE pIPAddrTable = 0;
DWORD dwSize = 0;
while (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
if (pIPAddrTable)
free( pIPAddrTable );
pIPAddrTable = (PMIB_IPADDRTABLE) malloc( dwSize );
}
for (unsigned i = 0; i<pIPAddrTable->dwNumEntries; ++i)
{
if (find(Indices.begin(), Indices.end(), pIPAddrTable->table[i].dwIndex) == Indices.end())
continue; // Any interface which is not relevant (probably loopback)
Adapters[pIPAddrTable->table[i].dwIndex].IpAddr = pIPAddrTable->table[i].dwAddr;
Adapters[pIPAddrTable->table[i].dwIndex].Subnet = pIPAddrTable->table[i].dwMask;
}
// 3. Get the name of the interface
// --------------------------------
IP_ADAPTER_ADDRESSES *AdapterAddresses = 0;
ULONG OutBufferLength = 0;
while (GetAdaptersAddresses(AF_INET, 0,NULL, AdapterAddresses, &OutBufferLength) == ERROR_BUFFER_OVERFLOW) {
if (AdapterAddresses)
free(AdapterAddresses);
AdapterAddresses = (PIP_ADAPTER_ADDRESSES) malloc(OutBufferLength);
}
PIP_ADAPTER_ADDRESSES AdapterList = AdapterAddresses;
while (AdapterList) {
if (find(Indices.begin(), Indices.end(), AdapterList->IfIndex) != Indices.end())
{
Adapters[AdapterList->IfIndex].FriendlyName = AdapterList->FriendlyName;
Adapters[AdapterList->IfIndex].Description = AdapterList->Description;
Adapters[AdapterList->IfIndex].dhcp = ((AdapterList->Flags&IP_ADAPTER_DHCP_ENABLED)!=0);
Adapters[AdapterList->IfIndex].speed = min(AdapterList->TransmitLinkSpeed, AdapterList->ReceiveLinkSpeed);
if (Adapters[AdapterList->IfIndex].speed == -1)
Adapters[AdapterList->IfIndex].speed = 0;
memcpy(Adapters[AdapterList->IfIndex].MAC, AdapterList->PhysicalAddress, min(AdapterList->PhysicalAddressLength, MAX_ADAPTER_ADDRESS_LENGTH));
}
AdapterList = AdapterList->Next;
}
// 4. Check if cable connected
fnGetIfTable2 pGetIfTable2 = 0;
HMODULE hModule = LoadLibraryA("Iphlpapi");
if (hModule)
{
pGetIfTable2 = (fnGetIfTable2)GetProcAddress(hModule,"GetIfTable2");
FreeLibrary(hModule);
}
if (pGetIfTable2)
{
PMIB_IF_TABLE2 table;
if (pGetIfTable2(&table) == NO_ERROR)
{
for (ULONG i = 0; i < table->NumEntries; ++i)
{
if (Adapters.find(table->Table[i].InterfaceIndex) != Adapters.end())
{
switch(table->Table[i].MediaConnectState)
{
case MediaConnectStateUnknown: Adapters[table->Table[i].InterfaceIndex].cable = AdapterInfo::unknown; break;
case MediaConnectStateConnected: Adapters[table->Table[i].InterfaceIndex].cable = AdapterInfo::connected; break;
case MediaConnectStateDisconnected: Adapters[table->Table[i].InterfaceIndex].cable = AdapterInfo::disconnected;
if (Adapters[table->Table[i].InterfaceIndex].IpAddr.ip == 0 &&
!Adapters[table->Table[i].InterfaceIndex].dhcp)
{
// Check Registry for the IP of the unconnected NIC
GUID *pGuid = &table->Table[i].InterfaceGuid;
char sKey[256];
sprintf(sKey, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
pGuid->Data1, pGuid->Data2, pGuid->Data3,
pGuid->Data4[0], pGuid->Data4[1], pGuid->Data4[2], pGuid->Data4[3], pGuid->Data4[4], pGuid->Data4[5], pGuid->Data4[6], pGuid->Data4[7]);
HKEY hKey;
LONG res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, sKey, 0, KEY_QUERY_VALUE|KEY_WOW64_64KEY, &hKey);
if (res == ERROR_SUCCESS)
{
if (Adapters[table->Table[i].InterfaceIndex].dhcp)
{
DWORD type, disableDHCP, size = sizeof(disableDHCP);
DWORD res = RegGetValueA(hKey,"", "DisableDhcpOnConnect", RRF_RT_REG_DWORD, &type, &disableDHCP, &size);
if (res == ERROR_SUCCESS && type == REG_DWORD)
Adapters[table->Table[i].InterfaceIndex].dhcp = disableDHCP == 0;
}
if (!Adapters[table->Table[i].InterfaceIndex].dhcp)
{
char IPAddress[512], SubnetMask[512];
DWORD type, size1 = sizeof(IPAddress), size2 = sizeof(SubnetMask);
DWORD res = RegGetValueA(hKey,"", "IPAddress", RRF_RT_REG_MULTI_SZ, &type, IPAddress, &size1);
if (res == ERROR_SUCCESS && type == REG_MULTI_SZ)
{
res = RegGetValueA(hKey,"", "SubnetMask", RRF_RT_REG_MULTI_SZ, &type, SubnetMask, &size2);
if (res == ERROR_SUCCESS && type == REG_MULTI_SZ)
{
Adapters[table->Table[i].InterfaceIndex].IpAddr = IP(inet_addr(IPAddress)); // String list, taking first element
Adapters[table->Table[i].InterfaceIndex].Subnet = IP(inet_addr(SubnetMask)); // String list, taking first element
}
}
}
RegCloseKey(hKey);
}
}
break;
}
}
}
}
}
// Output everything...
// --------------------
map<unsigned long, AdapterInfo>::iterator it = Adapters.begin(), end = Adapters.end();
while (it != end)
{
wcout << L"Adapter \"" << it->second.FriendlyName << L"\"\n";
wcout << L" DHCP: " << (it->second.dhcp?L"yes":L"no") << endl;
if (it->second.IpAddr.ip)
wcout << L" IP : " << it->second.IpAddr << endl;
if (it->second.Subnet.ip)
wcout << L" Subnet: " << it->second.Subnet << endl;
if (it->second.MAC[0] || it->second.MAC[1] || it->second.MAC[2] || it->second.MAC[3] || it->second.MAC[4] || it->second.MAC[5])
wcout << L" MAC: " << hex << setfill(L'0') << setw(2) << (unsigned)it->second.MAC[0] << L"-" << setw(2) << (unsigned)it->second.MAC[1] << L"-" << setw(2) << (unsigned)it->second.MAC[2] << L"-" << setw(2) << (unsigned)it->second.MAC[3] << L"-" << setw(2) << (unsigned)it->second.MAC[4] << L"-" << setw(2) << (unsigned)it->second.MAC[5] << dec << endl;
if (it->second.speed)
wcout << L" Speed: " << it->second.speed << endl;
if (!it->second.Description.empty())
wcout << L" Descr. \"" << it->second.Description << L"\"" << endl;
if (it->second.cable != AdapterInfo::unknown)
{
switch(it->second.cable)
{
case AdapterInfo::connected: wcout << " Cable: connected"; break;
case AdapterInfo::disconnected: wcout << " Cable: disconnected"; break;
}
}
wcout << endl;
++it;
}
}