Beispiel #1
0
struct netdriverdata *uaenet_enumerate (struct netdriverdata **out, const TCHAR *name)
{
	static int done;
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_if_t *alldevs, *d;
	int cnt;
	HMODULE hm;
	LPADAPTER lpAdapter = 0;
	PPACKET_OID_DATA OidData;
	struct netdriverdata *tc, *tcp;
	pcap_t *fp;
	int val;
	TCHAR *ss;

	if (enumerated) {
		if (out)
			*out = tds;
		return enumit (name);
	}
	tcp = tds;
	hm = LoadLibrary (L"wpcap.dll");
	if (hm == NULL) {
		write_log (L"uaenet: winpcap not installed (wpcap.dll)\n");
		return NULL;
	}
	FreeLibrary (hm);
	hm = LoadLibrary (L"packet.dll");
	if (hm == NULL) {
		write_log (L"uaenet: winpcap not installed (packet.dll)\n");
		return NULL;
	}
	FreeLibrary (hm);
	if (!isdllversion (L"wpcap.dll", 4, 0, 0, 0)) {
		write_log (L"uaenet: too old winpcap, v4 or newer required\n");
		return NULL;
	}

	ss = au (pcap_lib_version ());
	if (!done)
		write_log (L"uaenet: %s\n", ss);
	xfree (ss);

	if (pcap_findalldevs_ex (PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) {
		ss = au (errbuf);
		write_log (L"uaenet: failed to get interfaces: %s\n", ss);
		xfree (ss);
		return NULL;
	}

	if (!done)
		write_log (L"uaenet: detecting interfaces\n");
	for(cnt = 0, d = alldevs; d != NULL; d = d->next) {
		char *n2;
		TCHAR *ss2;
		tc = tcp + cnt;
		if (cnt >= MAX_TOTAL_NET_DEVICES) {
			write_log (L"buffer overflow\n");
			break;
		}
		ss = au (d->name);
		ss2 = d->description ? au (d->description) : L"(no description)";
		write_log (L"%s\n- %s\n", ss, ss2);
		xfree (ss2);
		xfree (ss);
		n2 = d->name;
		if (strlen (n2) <= strlen (PCAP_SRC_IF_STRING)) {
			write_log (L"- corrupt name\n");
			continue;
		}
		fp = pcap_open (d->name, 65536, 0, 0, NULL, errbuf);
		if (!fp) {
			ss = au (errbuf);
			write_log (L"- pcap_open() failed: %s\n", ss);
			xfree (ss);
			continue;
		}
		val = pcap_datalink (fp);
		pcap_close (fp);
		if (val != DLT_EN10MB) {
			if (!done)
				write_log (L"- not an ethernet adapter (%d)\n", val);
			continue;
		}

		lpAdapter = PacketOpenAdapter (n2 + strlen (PCAP_SRC_IF_STRING));
		if (lpAdapter == NULL) {
			if (!done)
				write_log (L"- PacketOpenAdapter() failed\n");
			continue;
		}
		OidData = (PPACKET_OID_DATA)xcalloc (uae_u8, 6 + sizeof(PACKET_OID_DATA));
		if (OidData) {
			OidData->Length = 6;
			OidData->Oid = OID_802_3_CURRENT_ADDRESS;
			if (PacketRequest (lpAdapter, FALSE, OidData)) {
				memcpy (tc->mac, OidData->Data, 6);
				if (!done)
					write_log (L"- MAC %02X:%02X:%02X:%02X:%02X:%02X (%d)\n",
					tc->mac[0], tc->mac[1], tc->mac[2],
					tc->mac[3], tc->mac[4], tc->mac[5], cnt++);
				tc->active = 1;
				tc->mtu = 1522;
				tc->name = au (d->name);
				tc->desc = au (d->description);
			} else {
				write_log (L" - failed to get MAC\n");
			}
			xfree (OidData);
		}
		PacketCloseAdapter (lpAdapter);
	}
	if (!done)
		write_log (L"uaenet: end of detection\n");
	done = 1;
	pcap_freealldevs (alldevs);
	enumerated = 1;
	if (out)
		*out = tds;
	return enumit (name);
}
Beispiel #2
0
struct netdriverdata *uaenet_enumerate (const TCHAR *name)
{
	static int done;
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_if_t *alldevs, *d;
	int cnt;
	LPADAPTER lpAdapter = 0;
	PPACKET_OID_DATA OidData;
	struct netdriverdata *tc, *tcp;
	pcap_t *fp;
	int val;
	TCHAR *ss;
	bool npcap = true;
	TCHAR sname[MAX_DPATH];
	int isdll;

	if (enumerated) {
		return enumit (name);
	}
	tcp = tds;

	int len = GetSystemDirectory(sname, MAX_DPATH);
	if (len) {
		_tcscat(sname, _T("\\Npcap"));
		SetDllDirectory(sname);
	}
	wpcap = LoadLibrary(_T("wpcap.dll"));
	packet = LoadLibrary(_T("packet.dll"));
	isdll = isdllversion(_T("wpcap.dll"), 4, 0, 0, 0);
	SetDllDirectory(_T(""));
	if (wpcap == NULL) {
		FreeLibrary(packet);
		int err = GetLastError();
		wpcap = LoadLibrary (_T("wpcap.dll"));
		packet = LoadLibrary(_T("packet.dll"));
		isdll = isdllversion(_T("wpcap.dll"), 4, 0, 0, 0);
		if (wpcap == NULL) {
			write_log (_T("uaenet: npcap/winpcap not installed (wpcap.dll)\n"));
			return NULL;
		}
		npcap = false;
	}
	if (packet == NULL) {
		write_log (_T("uaenet: npcap/winpcap not installed (packet.dll)\n"));
		FreeLibrary(wpcap);
		wpcap = NULL;
		return NULL;
	}

	if (!isdll) {
		write_log (_T("uaenet: too old npcap/winpcap, v4 or newer required\n"));
		return NULL;
	}

	ppcap_lib_version = (PCAP_LIB_VERSION)GetProcAddress(wpcap, "pcap_lib_version");
	ppcap_findalldevs_ex = (PCAP_FINDALLDEVS_EX)GetProcAddress(wpcap, "pcap_findalldevs_ex");
	ppcap_freealldevs = (PCAP_FREEALLDEVS)GetProcAddress(wpcap, "pcap_freealldevs");
	ppcap_open = (PCAP_OPEN)GetProcAddress(wpcap, "pcap_open");
	ppcap_close = (PCAP_CLOSE)GetProcAddress(wpcap, "pcap_close");
	ppcap_datalink = (PCAP_DATALINK)GetProcAddress(wpcap, "pcap_datalink");

	ppcap_sendpacket = (PCAP_SENDPACKET)GetProcAddress(wpcap, "pcap_sendpacket");
	ppcap_next_ex = (PCAP_NEXT_EX)GetProcAddress(wpcap, "pcap_next_ex");

	pPacketOpenAdapter = (PACKETOPENADAPTER)GetProcAddress(packet, "PacketOpenAdapter");
	pPacketCloseAdapter = (PACKETCLOSEADAPTER)GetProcAddress(packet, "PacketCloseAdapter");
	pPacketRequest = (PACKETREQUEST)GetProcAddress(packet, "PacketRequest");

	ss = au (ppcap_lib_version());
	if (!done)
		write_log (_T("uaenet: %s\n"), ss);
	xfree (ss);

	if (ppcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) {
		ss = au (errbuf);
		write_log (_T("uaenet: failed to get interfaces: %s\n"), ss);
		xfree (ss);
		return NULL;
	}


	PIP_ADAPTER_ADDRESSES aa = NULL;
	DWORD aasize = 0;
	DWORD err = GetAdaptersAddresses(AF_UNSPEC,
		GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER,
		NULL, NULL, &aasize);
	if (err == ERROR_BUFFER_OVERFLOW) {
		aa = (IP_ADAPTER_ADDRESSES*)xcalloc(uae_u8, aasize);
		if (GetAdaptersAddresses(AF_UNSPEC,
			GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER,
			NULL, aa, &aasize) != ERROR_SUCCESS)  {
			xfree(aa);
			aa = NULL;
		}
	}

	OidData = (PPACKET_OID_DATA)xcalloc(uae_u8, 6 + sizeof(PACKET_OID_DATA));
	OidData->Length = 6;
	OidData->Oid = OID_802_3_CURRENT_ADDRESS;

	if (!done)
		write_log (_T("uaenet: detecting interfaces\n"));
	for(cnt = 0, d = alldevs; d != NULL; d = d->next) {
		char *n2;
		TCHAR *ss2;
		tc = tcp + cnt;
		if (cnt >= MAX_TOTAL_NET_DEVICES) {
			write_log (_T("buffer overflow\n"));
			break;
		}
		ss = au (d->name);
		ss2 = d->description ? au (d->description) : _T("(no description)");
		write_log (_T("%s\n- %s\n"), ss, ss2);
		xfree (ss2);
		xfree (ss);
		n2 = d->name;
		if (strlen (n2) <= strlen (PCAP_SRC_IF_STRING)) {
			write_log (_T("- corrupt name\n"));
			continue;
		}
		fp = ppcap_open(d->name, 65536, 0, 0, NULL, errbuf);
		if (!fp) {
			ss = au (errbuf);
			write_log (_T("- pcap_open() failed: %s\n"), ss);
			xfree (ss);
			continue;
		}
		val = ppcap_datalink(fp);
		ppcap_close (fp);
		if (val != DLT_EN10MB) {
			if (!done)
				write_log (_T("- not an ethernet adapter (%d)\n"), val);
			continue;
		}

		lpAdapter = pPacketOpenAdapter(n2 + strlen (PCAP_SRC_IF_STRING));
		if (lpAdapter == NULL) {
			if (!done)
				write_log (_T("- PacketOpenAdapter() failed\n"));
			continue;
		}
		memset(tc->originalmac, 0, sizeof tc->originalmac);
		memcpy(tc->mac, uaemac, 6);
		if (pPacketRequest (lpAdapter, FALSE, OidData)) {
			memcpy(tc->mac, OidData->Data, 6);
			memcpy(tc->originalmac, tc->mac, 6);
		} else {
			PIP_ADAPTER_ADDRESSES aap = aa;
			while (aap) {
				char *name1 = aap->AdapterName;
				char *name2 = d->name;
				while (*name2 && *name2 != '{')
					name2++;
				if (*name2 && !stricmp(name1, name2)) {
					memcpy(tc->mac, aap->PhysicalAddress, 6);
					memcpy(tc->originalmac, tc->mac, 6);
					break;
				}
				aap = aap->Next;
			}
		}
		if (!done)
			write_log(_T("- MAC %02X:%02X:%02X:%02X:%02X:%02X -> %02X:%02X:%02X:%02X:%02X:%02X\n"),
				tc->mac[0], tc->mac[1], tc->mac[2], tc->mac[3], tc->mac[4], tc->mac[5],
				uaemac[0], uaemac[1], uaemac[2], tc->mac[3], tc->mac[4], tc->mac[5]);
		memcpy(tc->mac, uaemac, 3);
		tc->type = UAENET_PCAP;
		tc->active = 1;
		tc->mtu = 1522;
		tc->name = au(d->name);
		tc->desc = au(d->description);
		cnt++;
		pPacketCloseAdapter(lpAdapter);
	}
	if (!done)
		write_log (_T("uaenet: end of detection, %d devices found.\n"), cnt);
	done = 1;
	ppcap_freealldevs(alldevs);
	xfree(OidData);
	xfree(aa);
	enumerated = 1;
	return enumit (name);
}