pack your shit, kids, we're moving

This commit is contained in:
Arisotura 2019-02-21 01:32:28 +01:00
parent 2340be886c
commit 2d41291ee9
3 changed files with 155 additions and 133 deletions

View File

@ -16,12 +16,155 @@
with melonDS. If not, see http://www.gnu.org/licenses/. with melonDS. If not, see http://www.gnu.org/licenses/.
*/ */
// LAN interface. Currently powered by libpcap, may change.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL2/SDL.h>
#include <pcap/pcap.h>
#include "LAN.h" #include "LAN.h"
// welp
#ifndef PCAP_OPENFLAG_PROMISCUOUS
#define PCAP_OPENFLAG_PROMISCUOUS 1
#endif
#define DECL_PCAP_FUNC(ret, name, args, args2) \
typedef ret (*type_##name) args; \
type_##name ptr_##name = NULL; \
ret name args { return ptr_##name args2; }
DECL_PCAP_FUNC(int, pcap_findalldevs, (pcap_if_t** alldevs, char* errbuf), (alldevs,errbuf))
DECL_PCAP_FUNC(void, pcap_freealldevs, (pcap_if_t* alldevs), (alldevs))
DECL_PCAP_FUNC(pcap_t*, pcap_open_live, (const char* src, int snaplen, int flags, int readtimeout, char* errbuf), (src,snaplen,flags,readtimeout,errbuf))
DECL_PCAP_FUNC(void, pcap_close, (pcap_t* dev), (dev))
DECL_PCAP_FUNC(int, pcap_setnonblock, (pcap_t* dev, int nonblock, char* errbuf), (dev,nonblock,errbuf))
DECL_PCAP_FUNC(int, pcap_sendpacket, (pcap_t* dev, const u_char* data, int len), (dev,data,len))
DECL_PCAP_FUNC(int, pcap_dispatch, (pcap_t* dev, int num, pcap_handler callback, u_char* data), (dev,num,callback,data))
namespace LAN namespace LAN
{ {
// const char* PCapLibNames[] =
{
#ifdef __WIN32__
// TODO: name for npcap in non-WinPCap mode
"wpcap.dll",
#else
// Linux lib names
"libpcap.so.1",
"libpcap.so",
#endif
NULL
};
void* PCapLib = NULL;
pcap_t* PCapAdapter = NULL;
u8 PCapPacketBuffer[2048];
int PCapPacketLen;
int PCapRXNum;
#define LOAD_PCAP_FUNC(sym) \
ptr_##sym = (type_##sym)SDL_LoadFunction(lib, #sym); \
if (!ptr_##sym) return false;
bool TryLoadPCap(void* lib)
{
LOAD_PCAP_FUNC(pcap_findalldevs)
LOAD_PCAP_FUNC(pcap_freealldevs)
LOAD_PCAP_FUNC(pcap_open_live)
LOAD_PCAP_FUNC(pcap_close)
LOAD_PCAP_FUNC(pcap_setnonblock)
LOAD_PCAP_FUNC(pcap_sendpacket)
LOAD_PCAP_FUNC(pcap_dispatch)
return true;
}
bool Init()
{
PCapLib = NULL;
PCapAdapter = NULL;
PCapPacketLen = 0;
PCapRXNum = 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];
int ret;
pcap_if_t* alldevs;
ret = pcap_findalldevs(&alldevs, errbuf);
if (ret < 0 || alldevs == NULL)
{
printf("PCap: no devices available\n");
return false;
}
/*while (alldevs){
printf("picking dev %08X %s | %s\n", alldevs->flags, alldevs->name, alldevs->description);
alldevs = alldevs->next;}*/
// temp hack
// TODO: ADAPTER SELECTOR!!
pcap_if_t* dev = alldevs->next;
PCapAdapter = pcap_open_live(dev->name, 2048, PCAP_OPENFLAG_PROMISCUOUS, 1, errbuf);
if (!PCapAdapter)
{
printf("PCap: failed to open adapter\n");
return false;
}
pcap_freealldevs(alldevs);
if (pcap_setnonblock(PCapAdapter, 1, errbuf) < 0)
{
printf("PCap: failed to set nonblocking mode\n");
pcap_close(PCapAdapter); PCapAdapter = NULL;
return false;
}
return true;
}
void DeInit()
{
if (PCapLib)
{
if (PCapAdapter)
{
pcap_close(PCapAdapter);
PCapAdapter = NULL;
}
SDL_UnloadObject(PCapLib);
PCapLib = NULL;
}
}
} }

View File

@ -38,7 +38,8 @@ typedef struct
} AdapterData; } AdapterData;
// function shito here bool Init();
void DeInit();
} }

View File

@ -20,7 +20,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <pcap/pcap.h>
#include "../Platform.h" #include "../Platform.h"
#include "../Config.h" #include "../Config.h"
@ -38,7 +37,6 @@
#define socket_t int #define socket_t int
#define sockaddr_t struct sockaddr #define sockaddr_t struct sockaddr
#define closesocket close #define closesocket close
#define PCAP_OPENFLAG_PROMISCUOUS 1
#endif #endif
#ifndef INVALID_SOCKET #ifndef INVALID_SOCKET
@ -46,20 +44,6 @@
#endif #endif
#define DECL_PCAP_FUNC(ret, name, args, args2) \
typedef ret (*type_##name) args; \
type_##name ptr_##name = NULL; \
ret name args { return ptr_##name args2; }
DECL_PCAP_FUNC(int, pcap_findalldevs, (pcap_if_t** alldevs, char* errbuf), (alldevs,errbuf))
DECL_PCAP_FUNC(void, pcap_freealldevs, (pcap_if_t* alldevs), (alldevs))
DECL_PCAP_FUNC(pcap_t*, pcap_open_live, (const char* src, int snaplen, int flags, int readtimeout, char* errbuf), (src,snaplen,flags,readtimeout,errbuf))
DECL_PCAP_FUNC(void, pcap_close, (pcap_t* dev), (dev))
DECL_PCAP_FUNC(int, pcap_setnonblock, (pcap_t* dev, int nonblock, char* errbuf), (dev,nonblock,errbuf))
DECL_PCAP_FUNC(int, pcap_sendpacket, (pcap_t* dev, const u_char* data, int len), (dev,data,len))
DECL_PCAP_FUNC(int, pcap_dispatch, (pcap_t* dev, int num, pcap_handler callback, u_char* data), (dev,num,callback,data))
void Stop(bool internal); void Stop(bool internal);
@ -89,27 +73,6 @@ u8 PacketBuffer[2048];
#define NIFI_VER 1 #define NIFI_VER 1
const char* PCapLibNames[] =
{
#ifdef __WIN32__
// TODO: name for npcap in non-WinPCap mode
"wpcap.dll",
#else
// Linux lib names
"libpcap.so.1",
"libpcap.so",
#endif
NULL
};
void* PCapLib = NULL;
pcap_t* PCapAdapter = NULL;
u8 PCapPacketBuffer[2048];
int PCapPacketLen;
int PCapRXNum;
void StopEmu() void StopEmu()
{ {
Stop(true); Stop(true);
@ -294,108 +257,21 @@ int MP_RecvPacket(u8* data, bool block)
} }
// LAN interface. Currently powered by libpcap, may change.
#define LOAD_PCAP_FUNC(sym) \
ptr_##sym = (type_##sym)SDL_LoadFunction(lib, #sym); \
if (!ptr_##sym) return false;
bool TryLoadPCap(void* lib)
{
LOAD_PCAP_FUNC(pcap_findalldevs)
LOAD_PCAP_FUNC(pcap_freealldevs)
LOAD_PCAP_FUNC(pcap_open_live)
LOAD_PCAP_FUNC(pcap_close)
LOAD_PCAP_FUNC(pcap_setnonblock)
LOAD_PCAP_FUNC(pcap_sendpacket)
LOAD_PCAP_FUNC(pcap_dispatch)
return true;
}
bool LAN_Init() bool LAN_Init()
{ {
PCapLib = NULL; // welp
PCapAdapter = NULL;
PCapPacketLen = 0;
PCapRXNum = 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];
int ret;
pcap_if_t* alldevs;
ret = pcap_findalldevs(&alldevs, errbuf);
if (ret < 0 || alldevs == NULL)
{
printf("PCap: no devices available\n");
return false;
}
/*while (alldevs){
printf("picking dev %08X %s | %s\n", alldevs->flags, alldevs->name, alldevs->description);
alldevs = alldevs->next;}*/
// temp hack
// TODO: ADAPTER SELECTOR!!
pcap_if_t* dev = alldevs->next;
PCapAdapter = pcap_open_live(dev->name, 2048, PCAP_OPENFLAG_PROMISCUOUS, 1, errbuf);
if (!PCapAdapter)
{
printf("PCap: failed to open adapter\n");
return false;
}
pcap_freealldevs(alldevs);
if (pcap_setnonblock(PCapAdapter, 1, errbuf) < 0)
{
printf("PCap: failed to set nonblocking mode\n");
pcap_close(PCapAdapter); PCapAdapter = NULL;
return false;
}
return true; return true;
} }
void LAN_DeInit() void LAN_DeInit()
{ {
if (PCapLib) //
{
if (PCapAdapter)
{
pcap_close(PCapAdapter);
PCapAdapter = NULL;
}
SDL_UnloadObject(PCapLib);
PCapLib = NULL;
}
} }
int LAN_SendPacket(u8* data, int len) int LAN_SendPacket(u8* data, int len)
{ {
if (PCapAdapter == NULL) /*if (PCapAdapter == NULL)
return 0; return 0;
if (len > 2048) if (len > 2048)
@ -406,10 +282,11 @@ int LAN_SendPacket(u8* data, int len)
pcap_sendpacket(PCapAdapter, data, len); pcap_sendpacket(PCapAdapter, data, len);
// TODO: check success // TODO: check success
return len;*/
return len; return len;
} }
void LAN_RXCallback(u_char* blarg, const struct pcap_pkthdr* header, const u_char* data) /*void LAN_RXCallback(u_char* blarg, const struct pcap_pkthdr* header, const u_char* data)
{ {
while (PCapRXNum > 0); while (PCapRXNum > 0);
@ -418,11 +295,11 @@ void LAN_RXCallback(u_char* blarg, const struct pcap_pkthdr* header, const u_cha
PCapPacketLen = header->len; PCapPacketLen = header->len;
memcpy(PCapPacketBuffer, data, PCapPacketLen); memcpy(PCapPacketBuffer, data, PCapPacketLen);
PCapRXNum = 1; PCapRXNum = 1;
} }*/
int LAN_RecvPacket(u8* data) int LAN_RecvPacket(u8* data)
{ {
if (PCapAdapter == NULL) /*if (PCapAdapter == NULL)
return 0; return 0;
int ret = 0; int ret = 0;
@ -434,7 +311,8 @@ int LAN_RecvPacket(u8* data)
} }
pcap_dispatch(PCapAdapter, 1, LAN_RXCallback, NULL); pcap_dispatch(PCapAdapter, 1, LAN_RXCallback, NULL);
return ret; return ret;*/
return 0;
} }