VC++实现获取本地主机网卡信息

我们在进行网络编程的时候,经常需要获取本地主机,网卡的信息,我们代码实现如下。



#include "../common/initsock.h"

#include <windows.h>
#include <stdio.h>
#include <Iphlpapi.h>

#include "protoutils.h"
#include "ProtoPacket.h"


#pragma comment(lib, "Iphlpapi.lib")


DWORD WINAPI SendThread(LPVOID lpParam);
BOOL GetGlobalData();

/////////////////////////////////////////
// 全局数据
u_char	g_ucLocalMac[6];	// 本地MAC地址
DWORD	g_dwGatewayIP;		// 网关IP地址
DWORD	g_dwLocalIP;		// 本地IP地址
DWORD	g_dwMask;			// 子网掩码

CInitSock theSock;

int main()
{
	// 获取全局数据
	GetGlobalData();
	// 启动服务
	if(!ProtoStartService())
	{
		printf(" ProtoStartService() failed %d \n", ::GetLastError());
		return -1;
	}
	// 打开控制设备对象
	HANDLE hControlDevice = ProtoOpenControlDevice();
	if(hControlDevice == INVALID_HANDLE_VALUE)
	{
		printf(" ProtoOpenControlDevice() failed() %d \n", ::GetLastError());
		ProtoStopService();
		return -1;
	}
	// 枚举绑定的下层适配器
	CPROTOAdapters adapters;
	if(!adapters.EnumAdapters(hControlDevice))
	{
		printf(" Enume adapter failed \n");
		ProtoStopService();
		return -1;
	}

	CAdapter adapter;
	// 默认使用第一个适配器
	if(!adapter.OpenAdapter(adapters.m_pwszSymbolicLink[0], TRUE))
	{
		printf(" OpenAdapter failed \n");
		ProtoStopService();
		return -1;
	}

	CArpPacket arp(&adapter);

	////////////////////////////////////////////////////////////////////////
	// 下面开始进行LAN扫描

	// 提供当前线程(接收数据的线程)的优先级,避免丢失到来的数据贞
	::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
	// 创建发送线程,开始发送ARP请求
	::CloseHandle(::CreateThread(NULL, 0, SendThread, &arp, 0, NULL));

	// 接收ARP应答
	u_char *p;
	PARPHeader pArph;
	printf(" 开始扫描LAN中的计算机... \n");
	while(TRUE)
	{
		pArph = arp.WaitReply();
		if(pArph != NULL)
		{

			printf(" \n ------------------------------------------- \n");

			p = pArph->smac;
			printf("	Mac地址:	%02X-%02X-%02X-%02X-%02X-%02X \n", p[0], p[1], p[2], p[3], p[4], p[5]);
			p = (u_char*)&pArph->saddr;
			printf("	 IP地址:	%d.%d.%d.%d  \n ", p[0], p[1], p[2], p[3]);
	//		HOSTENT *pHost = ::gethostbyaddr((char*)&pArph->saddr, 4, AF_INET);
	//		if(pHost != NULL)
	//			printf("	 主机名:	%s \n", pHost->h_name);
		}
		else
		{
			break;
		}
	}
	printf("\n\n 扫描完毕 \n");

	ProtoStopService();

	getchar();

	return 0;
}


DWORD WINAPI SendThread(LPVOID lpParam)
{
	CArpPacket *pArp = (CArpPacket *)lpParam;
	// 取得LAN中IP地址空间的大小
	DWORD dwMask = ::ntohl(g_dwMask);
	int nMaxHosts = ~dwMask;

	// 设置以太头中目标MAC地址。发送ARP请求时,应该将它设为广播地址
	u_char destmacEther[6];
	memset(destmacEther, 0xff, 6);
	// ARP头中的目标MAC地址
	u_char destmacArp[6] = { 0 }; 
	// 向地址空间中的每个IP地址发送ARP请求
	DWORD dwTemp = ::ntohl(g_dwGatewayIP & g_dwMask) + 1;
	for(int i=1; i<nMaxHosts; i++, dwTemp++)
	{
		DWORD dwIP = ::htonl(dwTemp);
		if(dwIP != g_dwLocalIP)
		{
			if(!pArp->SendPacket(destmacEther, g_ucLocalMac, ARPOP_REQUEST, 
										destmacArp, dwIP, g_ucLocalMac, g_dwLocalIP))
			{
				printf(" SendPacket() failed \n");
				break;
			}
		}
	}
	return 0;
}

BOOL GetGlobalData()
{
	PIP_ADAPTER_INFO pAdapterInfo = NULL;
	ULONG ulLen = 0;

	// 为适配器结构申请内存
	::GetAdaptersInfo(pAdapterInfo,&ulLen);
	pAdapterInfo = (PIP_ADAPTER_INFO)::GlobalAlloc(GPTR, ulLen);

	// 取得本地适配器结构信息
	if(::GetAdaptersInfo(pAdapterInfo,&ulLen) ==  ERROR_SUCCESS)
	{
		if(pAdapterInfo != NULL)
		{
			memcpy(g_ucLocalMac, pAdapterInfo->Address, 6);
			g_dwGatewayIP = ::inet_addr(pAdapterInfo->GatewayList.IpAddress.String);
			g_dwLocalIP = ::inet_addr(pAdapterInfo->IpAddressList.IpAddress.String);
			g_dwMask = ::inet_addr(pAdapterInfo->IpAddressList.IpMask.String);
		}
	}	
	::GlobalFree(pAdapterInfo);

	printf(" \n -------------------- 本地主机信息 -----------------------\n\n");
	in_addr in;
	in.S_un.S_addr = g_dwLocalIP;
	printf("      IP Address : %s \n", ::inet_ntoa(in));

	in.S_un.S_addr = g_dwMask;
	printf("     Subnet Mask : %s \n", ::inet_ntoa(in));

	in.S_un.S_addr = g_dwGatewayIP;
	printf(" Default Gateway : %s \n", ::inet_ntoa(in));

	u_char *p = g_ucLocalMac;
	printf("     MAC Address : %02X-%02X-%02X-%02X-%02X-%02X \n", p[0], p[1], p[2], p[3], p[4], p[5]);

	printf(" \n \n ");



	return TRUE;
}


posted on 2012-09-04 18:10  三少爷的剑123  阅读(312)  评论(0编辑  收藏  举报

导航