コード例 #1
0
ファイル: utils.cpp プロジェクト: dong777/zkonvif
static bool get_all_netinfs(std::vector < NetInf > &nis)
{
	static bool first = true;
	static std::vector < NetInf > _nis;

#ifdef WIN32
	if (first) {
		first = false;
		nis.clear();

		ULONG len = 16 * 1024;
		IP_ADAPTER_ADDRESSES *adapter =
		    (IP_ADAPTER_ADDRESSES *) malloc(len);

		// 仅仅 ipv4
		DWORD rc = GetAdaptersAddresses(AF_INET, 0, 0, adapter, &len);
		if (rc == ERROR_BUFFER_OVERFLOW) {
			adapter =
			    (IP_ADAPTER_ADDRESSES *) realloc(adapter, len);
			rc = GetAdaptersAddresses(AF_INET, 0, 0, adapter, &len);
		}

		if (rc == 0) {
			IP_ADAPTER_ADDRESSES *p = adapter;
			while (p) {
				if ((p->IfType == IF_TYPE_ETHERNET_CSMACD
				     || p->IfType == IF_TYPE_IEEE80211)
				    && (p->OperStatus == IfOperStatusUp)) {
					// 仅仅考虑 ethernet 或者 wifi,并且活动的.
					// 不包括虚拟机的 mac.
					std::string mac =
					    conv_mac(p->PhysicalAddress,
						     p->PhysicalAddressLength);
					if (!is_vm_mac(mac.c_str())) {
						NetInf ni;
						ni.macaddr = mac;

						// FIXME: 到底用哪个 :( .... 这里真混乱 ....
						//ni.name = p->AdapterName;
						//ni.name = (char*)bstr_t(p->FriendlyName);
						ni.name =
						    (char *)bstr_t(p->
								   Description);

						IP_ADAPTER_UNICAST_ADDRESS *ip =
						    p->FirstUnicastAddress;
						while (ip) {
							assert(ip->Address.
							       lpSockaddr->
							       sa_family ==
							       AF_INET);
							sockaddr_in *addr =
							    (sockaddr_in *) ip->
							    Address.lpSockaddr;
							ni.ips.
							    push_back(inet_ntoa
								      (addr->
								       sin_addr));

							ip = ip->Next;
						}

						nis.push_back(ni);
					}
				}
				p = p->Next;
			}

			free(adapter);
		}

		_nis = nis;
	} else {
		nis = _nis;
	}
#endif				// win32

#ifdef __APPLE__
	struct ifaddrs *ifap, *ifa;
	std::map < std::string, Tmp > name_macs;
	std::map < std::string, Tmp >::iterator itf;

	if (getifaddrs(&ifap) == 0 && ifap) {
		for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
			if (ifa->ifa_flags & IFF_LOOPBACK)
				continue;
			if (!(ifa->ifa_flags & IFF_RUNNING))
				continue;

			if (strstr(ifa->ifa_name, "bridge"))	// 去除桥接网卡 .
				continue;

			if (ifa->ifa_addr
			    && ifa->ifa_addr->sa_family == AF_LINK) {
				/* Link layer interface */
				struct sockaddr_dl *dl =
				    (struct sockaddr_dl *)ifa->ifa_addr;
				unsigned char *p = (unsigned char *)LLADDR(dl);
				std::string mac = conv_mac(p, dl->sdl_alen);
				if (!is_vm_mac(mac.c_str())) {
					itf = name_macs.find(ifa->ifa_name);
					if (itf == name_macs.end()) {
						Tmp tmp;
						tmp.mac = mac;
						name_macs[ifa->ifa_name] = tmp;
					} else {
						itf->second.mac = mac;
					}
				}
			}

			if (ifa->ifa_addr
			    && ifa->ifa_addr->sa_family == AF_INET) {
				// IPV4
				struct sockaddr_in *sin =
				    (struct sockaddr_in *)ifa->ifa_addr;
				std::string ip = inet_ntoa(sin->sin_addr);
				itf = name_macs.find(ifa->ifa_name);
				if (itf == name_macs.end()) {
					Tmp tmp;
					tmp.ipv4 = ip;
					name_macs[ifa->ifa_name] = tmp;
				} else {
					itf->second.ipv4 = ip;
				}
			}
		}

		for (itf = name_macs.begin(); itf != name_macs.end(); ++itf) {
			Tmp & tmp = itf->second;
			if (!tmp.mac.empty() && !tmp.ipv4.empty()) {
				NetInf ni;
				ni.macaddr = tmp.mac;
				ni.ips.push_back(tmp.ipv4);

				nis.push_back(ni);
			}
		}

		freeifaddrs(ifap);
	}
#endif				// apple
#ifdef linux

	if (!first) {
		nis = _nis;
		return true;
	}

	char buf[8096];
	struct ifconf ifc;

	int fd = socket(AF_INET, SOCK_DGRAM, 0);
	if (fd == -1)
		return false;

	ifc.ifc_len = sizeof(buf);
	ifc.ifc_buf = buf;

	if (ioctl(fd, SIOCGIFCONF, &ifc) == -1)
		return false;

	int n = ifc.ifc_len / sizeof(ifreq);
	for (int i = 0; i < n; i++) {
		ifreq *req = (ifreq *) & buf[i * sizeof(ifreq)];
		const char *name = req->ifr_name;

		if (!strcmp(name, "lo"))
			continue;

		ioctl(fd, SIOCGIFFLAGS, (char *)req);
		if (!(req->ifr_flags & IFF_UP))
			continue;

		ioctl(fd, SIOCGIFHWADDR, (char *)req);
		std::string mac =
		    conv_mac((uint8_t *) req->ifr_hwaddr.sa_data, 6);

		ioctl(fd, SIOCGIFADDR, (char *)req);
		sockaddr_in *sin = (sockaddr_in *) & req->ifr_addr;

		if (sin->sin_family != AF_INET)
			continue;

		NetInf ni;
		ni.name = name;
		ni.macaddr = mac;
		ni.ips.push_back(inet_ntoa(sin->sin_addr));

		nis.push_back(ni);
	}

	close(fd);

	_nis = nis;
#endif

	return true;
}
コード例 #2
0
ファイル: util.cpp プロジェクト: FihlaTV/conference
/** 获取可用网卡配置,仅仅选择启动的 ipv4的,非虚拟机的,ethernet 
 */
bool get_all_netinfs(std::vector<NetInf> &nis)
{
	nis.clear();
#ifdef WIN32
	ULONG len = 16*1024;
	IP_ADAPTER_ADDRESSES *adapter = (IP_ADAPTER_ADDRESSES*)malloc(len);

	// 仅仅 ipv4
	DWORD rc = GetAdaptersAddresses(AF_INET, 0, 0, adapter, &len);
	if (rc == ERROR_BUFFER_OVERFLOW) {
		adapter = (IP_ADAPTER_ADDRESSES*)realloc(adapter, len);
		rc = GetAdaptersAddresses(AF_INET, 0, 0, adapter, &len);
	}

	if (rc == 0) {
		IP_ADAPTER_ADDRESSES *p = adapter;
		while (p) {
			if ((p->IfType == IF_TYPE_ETHERNET_CSMACD || p->IfType == IF_TYPE_IEEE80211) &&
				(p->OperStatus == IfOperStatusUp)) {
				// 仅仅考虑 ethernet 或者 wifi,并且活动的
				// 不包括虚拟机的 mac
				std::string mac = conv_mac(p->PhysicalAddress, p->PhysicalAddressLength);
				if (!is_vm_mac(mac.c_str())) {
					NetInf ni;
					ni.macaddr = mac;

					IP_ADAPTER_UNICAST_ADDRESS *ip = p->FirstUnicastAddress;
					while (ip) {
						assert(ip->Address.lpSockaddr->sa_family == AF_INET);
						sockaddr_in *addr = (sockaddr_in*)ip->Address.lpSockaddr;
						ni.ips.push_back(inet_ntoa(addr->sin_addr));

						ip = ip->Next;
					}

					nis.push_back(ni);
				}
			}
			p = p->Next;
		}

		free(adapter);
	}

#else
	char buffer[8192];
	struct ifconf ifc;
	struct ifreq ifr;

	int fd = socket(AF_INET, SOCK_DGRAM, 0);
	if(fd == -1)
		return false;

	ifc.ifc_len = sizeof(buffer);
	ifc.ifc_buf = buffer;

	if(ioctl(fd, SIOCGIFCONF, &ifc) == -1)
		return false;

	int count = ifc.ifc_len / sizeof(ifreq);

	struct ifreq *req = ifc.ifc_req;
	struct ifreq *end = req + count;
	for (; req != end; ++req) {
		strcpy(ifr.ifr_name, req->ifr_name);
		ioctl(fd, SIOCGIFFLAGS, &ifr);
		if (ifr.ifr_flags & IFF_LOOPBACK)
			continue;	// lo

		sockaddr_in sin;
		sin.sin_addr = ((sockaddr_in&)req->ifr_addr).sin_addr;

		ioctl(fd, SIOCGIFHWADDR, &ifr);
		unsigned char mac_addr[6];
		memcpy(mac_addr, ifr.ifr_hwaddr.sa_data, 6);

		NetInf ni;
		ni.ips.push_back(inet_ntoa(sin.sin_addr));
		ni.macaddr = conv_mac(mac_addr, 6);

		nis.push_back(ni);
	}
	close(fd);

#endif
	return true;
}