MFC-GetAdaptersAddresses obtains network card information

Requires: #pragma comment(lib, "IPHLPAPI.lib")

GetAdaptersAddresses function parameter description

	ULONG bufferSize = 0;
	ULONG  result = ::GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr, &bufferSize);
	/*
	参数1:ULONG Family 网络协议族,此参数须为下列值之一
			AF_UNSPEC=0       返回与启用了 IPv4 或 IPv6 的适配器关联的 IPv4 和 IPv6 地址
			AF_INET=2         仅返回与启用了 IPv4 的适配器关联的 IPv4 地址
			AF_INET6=23       仅返回与启用了 IPv6 的适配器关联的 IPv6 地址

	参数2:ULONG Flags  要检索的地址类型
			概念解释:
			单播(Unicast):单播地址是一对一的通信方式,它用于将数据包从源地址发送到目标地址。
					源地址指定发送者的唯一标识符,而目标地址指定接收者的唯一标识符。
					只有目标地址与接收者匹配时,数据包才会传送给接收者。
			广播(Broadcast):广播地址是一对多的通信方式,它用于将数据包发送给同一个网络中的所有设备。
					广播地址是一个特殊的地址,用于指示所有设备都应该接收该数据包。
					广播可以是有限的(局域网内)或无限的(所有网络都接收)。
			多播(Multicast):多播地址是一对多的通信方式,它用于将数据包发送给一组特定的设备,这组设备被称为多播组。
					多播地址也是一种特殊的地址,它表明数据包是按照多播方式进行传输的。只有加入该多播组的设备才会接收到数据包

			此参数是以下值的组合。 如果此参数为零,则将返回单播、任意广播和多播 IP 地址
					GAA_FLAG_SKIP_UNICAST=0x0001     不要返回单播地址
					GAA_FLAG_SKIP_ANYCAST=0x0002     不要返回 IPv6 任何广播地址
					GAA_FLAG_SKIP_MULTICAST=0x0004   不要返回多播地址
					GAA_FLAG_SKIP_DNS_SERVER=0x0008   不要返回 DNS 服务器的地址
					GAA_FLAG_INCLUDE_PREFIX=0x0010    返回此适配器上的 IP 地址前缀列表。 设置此标志后,将返回 IPv6 和 IPv4 地址的 IP 地址前缀。
					GAA_FLAG_SKIP_FRIENDLY_NAME=0x0020    不要返回适配器友好名称
					GAA_FLAG_INCLUDE_WINS_INFO=0x0040     返回Windows Internet名称服务的地址 (WINS) 服务器。
															Windows Vista 及更高版本支持此标志
					GAA_FLAG_INCLUDE_GATEWAYS=0x0080       返回默认网关的地址,Windows Vista 及更高版本支持此标志
					GAA_FLAG_INCLUDE_ALL_INTERFACES=0x0100   返回所有NDIS接口的地址
					GAA_FLAG_INCLUDE_ALL_COMPARTMENTS=0x0200   返回所有路由隔离舱中的地址。此标志当前不受支持,并保留供将来使用
					GAA_FLAG_INCLUDE_TUNNEL_BINDINGORDER=0x0400   返回按隧道绑定顺序排序的适配器地址

	参数3:PVOID Reserved  此参数当前未使用,但保留供将来系统使用。 调用应用程序应为此参数传递 NULL

	参数4:[in, out] PIP_ADAPTER_ADDRESSES AdapterAddresses  指向缓冲区的指针,该缓冲区包含成功返回时 IP_ADAPTER_ADDRESSES 结构的链接列表

	参数5:[in, out] PULONG SizePointer  指向变量的指针,该变量指定 AdapterAddresses 指向的缓冲区的大小

	返回值:如果函数成功,则返回值 ERROR_SUCCESS=0 (定义为 与 NO_ERROR)
			如果函数失败,则返回值为以下错误代码之一
					ERROR_ADDRESS_NOT_ASSOCIATED=1228   地址尚未与网络终结点关联。 DHCP 租约信息可用
					ERROR_BUFFER_OVERFLOW=111          SizePointer 参数指示的缓冲区大小太小,无法保存适配器信息或 AdapterAddresses 参数为 NULL
					ERROR_INVALID_PARAMETER=87   其中一个参数无效。
							对于以下任一情况,将返回此错误: SizePointer 参数为 NULL、 Address 参数不 AF_INET、 AF_INET6或 AF_UNSPEC,
							或者请求的参数的地址信息大于 ULONG_MAX。
					ERROR_NOT_ENOUGH_MEMORY=8     内存资源不足,无法完成操作
					ERROR_NO_DATA=232              找不到所请求参数的地址

	*/

	

GAA_FLAG_INCLUDE_PREFIX What is a prefix list?

The IP adapter's prefix refers to the network segment to which the IP address of the network interface belongs. For example, for an IPv4 address 192.168.1.100and subnet mask 255.255.255.0, its prefix is 192.168.1.0/24​​. All network devices in the same network segment can communicate with each other through IP addresses without going through a router.

Description of common fields in the IP_ADAPTER_ADDRESSES structure:

Next: 指向下一个 IP_ADAPTER_ADDRESSES 结构体的指针。用于遍历多个网络适配器的链表。

AdapterName: 网络适配器的名称,以字符串形式表示。

Description: 网络适配器的描述信息,以字符串形式表示。

FirstUnicastAddress: 指向一个 IP_ADAPTER_UNICAST_ADDRESS 结构体的指针,表示网卡的第一个单播地址(IPv4 或 IPv6)。

FirstAnycastAddress: 指向一个 IP_ADAPTER_ANYCAST_ADDRESS 结构体的指针,表示网卡的第一个任播地址(IPv6)。

FirstMulticastAddress: 指向一个 IP_ADAPTER_MULTICAST_ADDRESS 结构体的指针,表示网卡的第一个组播地址(IPv4 或 IPv6)。

FirstDnsServerAddress: 指向一个 IP_ADAPTER_DNS_SERVER_ADDRESS 结构体的指针,表示网卡的第一个 DNS 服务器地址。

DnsSuffix: DNS 后缀,以字符串形式表示。

PWCHAR FriendlyName: 网络适配器的友好名称,以字符串形式表示。

BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH] : 网卡的物理地址(MAC 地址),以字节数组形式表示。

ULONG PhysicalAddressLength: 物理地址的长度,以字节数表示

IfIndex: 网络适配器的索引号。

OperStatus: 网络适配器的操作状态,如 UP、DOWN 等。

IfType: 网络适配器的类型,比如以太网、无线网卡等。

Ipv6IfIndex: IPv6 协议的接口索引号。

这些字段提供了有关网络适配器的各种信息,如名称、描述、地址等。通过遍历 IP_ADAPTER_ADDRESSES 的链表,可以获取系统中所有的网络适配器的详细信息

illustrate:

PhysicalAddressLength

PhysicalAddressLengthRefers to the physical address length of the network card (or MAC address length). In network communication, each network card has a unique physical address, also called MAC address (Media Access Control Address).

A physical address is represented by a 48-bit (6-byte) hexadecimal number, usually using a colon or hyphen to separate each byte. For example, a physical address can be in the format of 00:1A:2B:3C:4D:5Eor 00-1A-2B-3C-4D-5E.

PhysicalAddressLengthThe variable represents the length of the physical address. Under normal circumstances, the physical address length is fixed, 6 bytes. Therefore, PhysicalAddressLengththe value of is usually 6. But depending on the specific network device or technology, other lengths of physical addresses may exist.

By getting the physical address length of the network card, we can allocate enough memory space for the physical address in the program and ensure that the physical address is parsed and processed correctly

Get the physical address (MAC address) of the network card

	CString str;
	char buff[100];
	DWORD bufflen = 100;
	ULONG outBufLen = 0;
	ULONG dwRetVal = 0;
	PIP_ADAPTER_ADDRESSES pAddresses = nullptr;
	dwRetVal = ::GetAdaptersAddresses(AF_UNSPEC, 0, NULL, nullptr, &outBufLen);
	/*
	第一次GetAdaptersAddresses,outBufLen=0,只是为了获取实际需要的大小
	*/
	//pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
	//根据实际空间大小申请空间

	pAddresses = static_cast<IP_ADAPTER_ADDRESSES*>(malloc(outBufLen)); // 分配足够的缓冲区空间


	dwRetVal = ::GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST, NULL, pAddresses, &outBufLen);
	/*
	AF_INET  仅返回与启用了 IPv4 的适配器关联的 IPv4 地址
	GAA_FLAG_SKIP_ANYCAST   不要返回 IPv6 任何广播地址

	*/

	if (dwRetVal == NO_ERROR) {

		str.Format(_T("网络适配器的友好名称:%s \n"), pAddresses->FriendlyName);
		//   【以太网】

		str.Format(_T("物理地址的长度:%d \n"), pAddresses->PhysicalAddressLength);
		//  【6】

		int n = sizeof(pAddresses->PhysicalAddress) / sizeof(pAddresses->PhysicalAddress[0]);  //网卡总数
		str.Format(_T("网卡总数:%d \n"), n);
		//  【8】

		for (int i = 0; i < n; i++) {
			str.Format(_T("网卡的物理地址(MAC 地址):n=%d    %x \n"), i, pAddresses->PhysicalAddress[i]);
			::OutputDebugString(str);

			/*
			网卡的物理地址(MAC 地址):n=0    74
			网卡的物理地址(MAC 地址):n=1    d0
			网卡的物理地址(MAC 地址):n=2    2b
			网卡的物理地址(MAC 地址):n=3    b7
			网卡的物理地址(MAC 地址):n=4    3e
			网卡的物理地址(MAC 地址):n=5    44
			网卡的物理地址(MAC 地址):n=6    0
			网卡的物理地址(MAC 地址):n=7    0
			*/

		}
		
	}

Guess you like

Origin blog.csdn.net/lm68140318/article/details/132844254