IP Helper 是一套用於管理本網設定的API。使用這一套API可以方便的改變電腦的網路設定或者提取有關的資訊。而且它還提供了一種訊息機制,能夠在本地計算 機的網路設定發生改變時通知應用程式。實際上,它不僅僅能夠提取原生網路設定資訊,還能夠獲得網路上其它電腦的IP使用方式和MAC地址。
從最簡單的開始
最簡單的是查看電腦上的網路設定是什麼而不修改。
提取網卡資訊
hInst=LoadLibrary("iphlpapi.dll");
if(!hInst)
cout<<"iphlpapi.dll not supported in this platform!\n";
這三行代碼的作用是載入iphlpapi庫檔案,
下面的幾行代碼顯示了調用DLL中函數的過程:
pGAInfo=(PGAINFO)GetProcAddress(hInst,"GetAdaptersInfo");
ULONG ulSize=0;
pGAInfo(pInfo,&ulSize);
pInfo=(PIP_ADAPTER_INFO)new(char[ulSize]);
pGAInfo(pInfo,&ulSize);
第 一行代碼是獲得函數GetAdaptersInfo的入口地址,以便在後面通過指標調用函數。這個函數的功能是提取網卡的資訊,並接收兩個參數,第一個參 數是用來儲存網卡資訊的記憶體緩衝的首地址,而第二個參數是這個緩衝的大小。由於事先不知道本地機器上有多少張網卡,所以也就沒法知道應該分配多大的緩衝。 好在GetAdaptersInfo函數在緩衝的大小不夠時會在第二個參數也就是ulSize中填入應該分配的緩衝的大小。這樣,就可以調用兩次 GetAdaptersInfo,第一次是擷取緩衝區的大小,然後分配這個緩衝以後再次調用它以獲得實際的網卡資訊。
GetAdaptersInfo通過pInfo返回的資訊是以鏈表的方式組織的,下面就是訪問鏈表的代碼:
while(pInfo)
{
//訪問網卡資料
//將當前指標移向下一個結點
pInfo=pInfo->Next;
}
為了說明問題,省略了其中的代碼。
下面看看GetAdaptersInfo都返回了些什麼樣的資訊,下面是對pInfo所指向的資料結構的解釋:
typedef struct _IP_ADAPTER_INFO {
struct _IP_ADAPTER_INFO* Next;//鏈表指標域,通過這個來遍曆靜態鍵表
DWORD ComboIndex;//保留未用
char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];//網卡名
char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];//對網卡的描述
UINT AddressLength;//物理地址的長度,通過這個顯示下面數組中的物理地址
BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];//物理地址,每個位元組存放一個十六進位的數值,配合上一個資料域在printf中用x格式把每個位元組輸出。
DWORD Index;//網卡索引號
UINT Type;//網卡類型
UINT DhcpEnabled;//是否啟用了DHCP動態IP分配
PIP_ADDR_STRING CurrentIpAddress;//當前使用的IP地址
IP_ADDR_STRING IpAddressList;//綁定到此網卡的IP地址鏈表,重要項目
IP_ADDR_STRING GatewayList;//網關地址鏈表,重要項目
IP_ADDR_STRING DhcpServer;//DHCP伺服器位址,只有在DhcpEnabled==TRUE的情況下才有效
BOOL HaveWins;//是否啟用了WINS
IP_ADDR_STRING PrimaryWinsServer;//主WINS地址
IP_ADDR_STRING SecondaryWinsServer;//輔WINS地址
time_t LeaseObtained;//當前DHCP租借擷取的時間
time_t LeaseExpires;//當前DHCP租借失效時間。這兩個資料結構只有在啟用了DHCP時才有用。
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
這個資料結構中的幾個IP地址字串IpAddressList、GatewayList等等都是以鏈表的方式組織的。實際上所有資料都可以在控制台|網路|屬性|TCP/IP的屬性頁面的進階選項裡看見
提取網路介面資訊
其 中最主要的兩個函數是GetNumberOfInterfaces和GetInterfaceInfo,前者指出網路介面的個數,後者提取網路介面的信 息。對於第一個函數要說明的一點,據MSDN描述:一個網路介面是網卡的邏輯抽象,它們是一對一的關係。實際上,因為每個系統都附加有一個調試用的網路接 口,這個介面的IP地址是127.0.0.1子網路遮罩是255.0.0.0。由GetInterfaceInfo返回的 IP_INTERFACE_INFO結構中也有一個NumAdapters整型的資料域記錄了正確的網卡。然後對於GetInterfaceInfo要注
意的是它也必須被調用兩次,第一次擷取緩衝大小,第二次才是取值。GetInterfaceInfo返回的IP_INTERFACE_INFO不象上面的 結構是用鏈表,而是用的動態數組的方法,所以遍曆其中每一個元素的代碼變成:
for(int i=0;iNumAdapters;i++)
{
cout<<"Adapter index:"<<Adapter[i].Index<<Adapter[i].Name<<endl;
}
IP_INTERFACE_INFO結構的解釋如下:
typedef struct _IP_INTERFACE_INFO {
LONG NumAdapters;// 動態數組中網路介面元素的個數,通過它來遍曆數組
IP_ADAPTER_INDEX_MAP Adapter[1];// 網路介面資料數組
} IP_INTERFACE_INFO,*PIP_INTERFACE_INFO;
其中的IP_ADAPTER_INDEX_MAP結構如下:
typedef struct _IP_ADAPTER_INDEX_MAP {
ULONG Index;// 網卡索引
WCHAR Name[MAX_ADAPTER_NAME];// 網卡名
} IP_ADAPTER_INDEX_MAP, * PIP_ADAPTER_INDEX_MAP;
提取IP資訊
這部分提取網路介面資訊部分是相同的。
設定本網
設定的過程與提取過程類似。
其它的API函數
這 些函數能夠察看或者設定網路資料報文方面的資訊。比方GetIpStatistics、GetIcmpStatistics函數能夠查看當前IP資料報和 ICMP資料報的流量,以及廢棄的資料報數量等等。使用這些函數可以構建網路監控程式檢查網路中的故障。也可以使用SetIpStatistics 函數來設定相應的IP協議棧屬性,縮短或者延長IP資料報的預設TTL值。也可以使用GetIpForwardTable、 CreateIpForwardEntry 、DeleteIpForwardEntry、SetIpForwardEntry來分別擷取IP路由表的資訊,建立路由表項,刪除路由表項和修改路由表
項。也可以用GetBestRoute、 GetBestInterface獲得到達指定IP的最好的路由點和網路介面。
事實上,通過這些函數可以得到許多MIB變數(《使用TCP/IP協議實現網際互聯》第二卷),通過這些MIB變數,可以非常快速的製作一個網路管理軟體。
IP Helper API中SendARP函數。它能夠簡單的發送ARP資料包並返回目標機器的MAC地址。
這套API提供的當網路設定改變時嚮應用程式發出訊息的非同步通知功能。因為它們非常簡單,與WINSOCK中WSAAsyncSelect的使用方法是一樣的,就不再說明了。