pack your shit, kids, we're moving
This commit is contained in:
parent
2340be886c
commit
2d41291ee9
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,8 @@ typedef struct
|
||||||
} AdapterData;
|
} AdapterData;
|
||||||
|
|
||||||
|
|
||||||
// function shito here
|
bool Init();
|
||||||
|
void DeInit();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue