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); }
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); }