add pcap code for Linux. fix bugs.

This commit is contained in:
StapleButter 2019-03-26 02:53:17 +01:00
parent f86782cc2e
commit c43574207a
4 changed files with 89 additions and 34 deletions

View File

@ -168,7 +168,7 @@ void Open()
} }
LAN_Socket::Init(); LAN_Socket::Init();
haspcap = LAN_PCap::Init(); haspcap = LAN_PCap::Init(false);
opened = true; opened = true;
win = uiNewWindow("Wifi settings - melonDS", 400, 100, 0, 0, 0); win = uiNewWindow("Wifi settings - melonDS", 400, 100, 0, 0, 0);
@ -253,10 +253,10 @@ void Open()
} }
uiComboboxSetSelected(cmAdapterList, sel); uiComboboxSetSelected(cmAdapterList, sel);
UpdateAdapterInfo(); UpdateAdapterInfo();
UpdateAdapterControls();
uiCheckboxSetChecked(cbDirectLAN, Config::DirectLAN); uiCheckboxSetChecked(cbDirectLAN, Config::DirectLAN);
if (!haspcap) uiControlDisable(uiControl(cbDirectLAN)); if (!haspcap) uiControlDisable(uiControl(cbDirectLAN));
UpdateAdapterControls();
uiControlShow(uiControl(win)); uiControlShow(uiControl(win));
} }

View File

@ -30,7 +30,10 @@
#ifdef __WIN32__ #ifdef __WIN32__
#include <iphlpapi.h> #include <iphlpapi.h>
#else #else
// Linux includes go here #include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <linux/if_packet.h>
#endif #endif
@ -101,40 +104,42 @@ bool TryLoadPCap(void* lib)
return true; return true;
} }
bool Init() bool Init(bool open_adapter)
{ {
// TODO: how to deal with cases where an adapter is unplugged or changes config?? // TODO: how to deal with cases where an adapter is unplugged or changes config??
if (PCapLib) return true; if (!PCapLib)
{
PCapLib = NULL;
for (int i = 0; PCapLibNames[i]; i++)
{
void* lib = SDL_LoadObject(PCapLibNames[i]);
if (!lib) continue;
if (!TryLoadPCap(lib))
{
SDL_UnloadObject(lib);
continue;
}
printf("PCap: lib %s, init successful\n", PCapLibNames[i]);
PCapLib = lib;
break;
}
if (PCapLib == NULL)
{
printf("PCap: init failed\n");
return false;
}
}
PCapLib = NULL;
PCapAdapter = NULL; PCapAdapter = NULL;
PacketLen = 0; PacketLen = 0;
RXNum = 0; RXNum = 0;
NumAdapters = 0; NumAdapters = 0;
for (int i = 0; PCapLibNames[i]; i++)
{
void* lib = SDL_LoadObject(PCapLibNames[i]);
if (!lib) continue;
if (!TryLoadPCap(lib))
{
SDL_UnloadObject(lib);
continue;
}
printf("PCap: lib %s, init successful\n", PCapLibNames[i]);
PCapLib = lib;
break;
}
if (PCapLib == NULL)
{
printf("PCap: init failed\n");
return false;
}
char errbuf[PCAP_ERRBUF_SIZE]; char errbuf[PCAP_ERRBUF_SIZE];
int ret; int ret;
@ -158,11 +163,19 @@ bool Init()
{ {
adata->Internal = dev; adata->Internal = dev;
#ifdef __WIN32__
// hax // hax
int len = strlen(dev->name); int len = strlen(dev->name);
len -= 12; if (len > 127) len = 127; len -= 12; if (len > 127) len = 127;
strncpy(adata->DeviceName, &dev->name[12], len); strncpy(adata->DeviceName, &dev->name[12], len);
adata->DeviceName[len] = '\0'; adata->DeviceName[len] = '\0';
#else
strncpy(adata->DeviceName, dev->name, 127);
adata->DeviceName[127] = '\0';
strncpy(adata->FriendlyName, adata->DeviceName, 127);
adata->FriendlyName[127] = '\0';
#endif // __WIN32__
dev = dev->next; dev = dev->next;
adata++; adata++;
@ -181,7 +194,7 @@ bool Init()
} }
if (uret != ERROR_SUCCESS) if (uret != ERROR_SUCCESS)
{ {
printf("GetAdaptersAddresses() shat itself: %08X\n", ret); printf("GetAdaptersAddresses() shat itself: %08X\n", uret);
return false; return false;
} }
@ -217,7 +230,7 @@ bool Init()
if (sa->sa_family == AF_INET) if (sa->sa_family == AF_INET)
{ {
struct in_addr sa4 = ((sockaddr_in*)sa)->sin_addr; struct in_addr sa4 = ((sockaddr_in*)sa)->sin_addr;
memcpy(adata->IP_v4, &sa4.S_un.S_addr, 4); memcpy(adata->IP_v4, &sa4, 4);
} }
ipaddr = ipaddr->Next; ipaddr = ipaddr->Next;
@ -231,10 +244,52 @@ bool Init()
#else #else
// TODO struct ifaddrs* addrs;
if (getifaddrs(&addrs) != 0)
{
printf("getifaddrs() shat itself :(\n");
return false;
}
for (int i = 0; i < NumAdapters; i++)
{
adata = &Adapters[i];
struct ifaddrs* curaddr = addrs;
while (curaddr)
{
if (strcmp(curaddr->ifa_name, adata->DeviceName))
{
curaddr = curaddr->ifa_next;
continue;
}
if (!curaddr->ifa_addr) continue;
u16 af = curaddr->ifa_addr->sa_family;
if (af == AF_INET)
{
struct sockaddr_in* sa = (sockaddr_in*)curaddr->ifa_addr;
memcpy(adata->IP_v4, &sa->sin_addr, 4);
}
else if (af == AF_PACKET)
{
struct sockaddr_ll* sa = (sockaddr_ll*)curaddr->ifa_addr;
if (sa->sll_halen != 6)
printf("weird MAC length %d for %s\n", sa->sll_halen, curaddr->ifa_name);
else
memcpy(adata->MAC, sa->sll_addr, 6);
}
curaddr = curaddr->ifa_next;
}
}
freeifaddrs(addrs);
#endif // __WIN32__ #endif // __WIN32__
if (!open_adapter) return true;
if (PCapAdapter) pcap_close(PCapAdapter);
// open pcap device // open pcap device
PCapAdapterData = &Adapters[0]; PCapAdapterData = &Adapters[0];
for (int i = 0; i < NumAdapters; i++) for (int i = 0; i < NumAdapters; i++)
@ -247,7 +302,7 @@ bool Init()
PCapAdapter = pcap_open_live(dev->name, 2048, PCAP_OPENFLAG_PROMISCUOUS, 1, errbuf); PCapAdapter = pcap_open_live(dev->name, 2048, PCAP_OPENFLAG_PROMISCUOUS, 1, errbuf);
if (!PCapAdapter) if (!PCapAdapter)
{ {
printf("PCap: failed to open adapter\n"); printf("PCap: failed to open adapter %s\n", errbuf);
return false; return false;
} }

View File

@ -42,7 +42,7 @@ extern AdapterData* Adapters;
extern int NumAdapters; extern int NumAdapters;
bool Init(); bool Init(bool open_adapter);
void DeInit(); void DeInit();
int SendPacket(u8* data, int len); int SendPacket(u8* data, int len);

View File

@ -264,7 +264,7 @@ bool LAN_Init()
{ {
if (Config::DirectLAN) if (Config::DirectLAN)
{ {
if (!LAN_PCap::Init()) if (!LAN_PCap::Init(true))
return false; return false;
} }
else else