aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/frontend/qt_sdl/LAN_Socket.cpp910
1 files changed, 5 insertions, 905 deletions
diff --git a/src/frontend/qt_sdl/LAN_Socket.cpp b/src/frontend/qt_sdl/LAN_Socket.cpp
index 97a36e4..6a3fa74 100644
--- a/src/frontend/qt_sdl/LAN_Socket.cpp
+++ b/src/frontend/qt_sdl/LAN_Socket.cpp
@@ -21,34 +21,17 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <list>
#include "../Wifi.h"
#include "LAN_Socket.h"
#include "../Config.h"
-#include <list>
-
#include <slirp/libslirp.h>
#ifdef __WIN32__
- #include <winsock2.h>
#include <ws2tcpip.h>
- #define socket_t SOCKET
- #define sockaddr_t SOCKADDR
#else
- #include <unistd.h>
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <sys/types.h>
- #include <sys/select.h>
#include <sys/socket.h>
- #include <netdb.h>
- #define socket_t int
- #define sockaddr_t struct sockaddr
- #define closesocket close
-#endif
-
-#ifndef INVALID_SOCKET
-#define INVALID_SOCKET (socket_t)-1
#endif
@@ -67,47 +50,7 @@ u8 PacketBuffer[2048];
int PacketLen;
volatile int RXNum;
-u16 IPv4ID;
-
-
-// TODO: UDP sockets
-// * use FIFO list
-// * assign new socket when seeing new IP/port
-
-
-typedef struct
-{
- u8 DestIP[4];
- u16 SourcePort;
- u16 DestPort;
-
- u32 SeqNum; // sequence number for incoming frames
- u32 AckNum;
-
- // 0: unused
- // 1: connected
- u8 Status;
-
- socket_t Backend;
-
-} TCPSocket;
-
-typedef struct
-{
- u8 DestIP[4];
- u16 SourcePort;
- u16 DestPort;
-
- socket_t Backend;
- struct sockaddr_in BackendAddr;
-
-} UDPSocket;
-
-TCPSocket TCPSocketList[16];
-UDPSocket UDPSocketList[4];
-
-int UDPSocketID = 0;
-
+u32 IPv4ID;
Slirp* Ctx;
@@ -221,7 +164,6 @@ void SlirpCbUnregisterPollFD(int fd, void* opaque)
void SlirpCbNotify(void* opaque)
{
- //
}
SlirpCb cb =
@@ -239,21 +181,7 @@ SlirpCb cb =
bool Init()
{
- // TODO: how to deal with cases where an adapter is unplugged or changes config??
- //if (PCapLib) return true;
-
- //Lib = NULL;
- /*PacketLen = 0;
- RXNum = 0;
-
- IPv4ID = 1;
-
- memset(TCPSocketList, 0, sizeof(TCPSocketList));
- memset(UDPSocketList, 0, sizeof(UDPSocketList));
-
- UDPSocketID = 0;
-
- return true;*/
+ IPv4ID = 0;
FDListSize = 0;
memset(FDList, 0, sizeof(FDList));
@@ -269,7 +197,6 @@ bool Init()
cfg.vhostname = "melonServer";
*(u32*)&cfg.vdhcp_start = htonl(kClientIP);
*(u32*)&cfg.vnameserver = htonl(kDNSIP);
- //cfg.vdhcp_start.S_addr = kServerIP;
Ctx = slirp_new(&cfg, &cb, nullptr);
@@ -278,18 +205,6 @@ bool Init()
void DeInit()
{
- /*for (int i = 0; i < (sizeof(TCPSocketList)/sizeof(TCPSocket)); i++)
- {
- TCPSocket* sock = &TCPSocketList[i];
- if (sock->Backend) closesocket(sock->Backend);
- }
-
- for (int i = 0; i < (sizeof(UDPSocketList)/sizeof(UDPSocket)); i++)
- {
- UDPSocket* sock = &UDPSocketList[i];
- if (sock->Backend) closesocket(sock->Backend);
- }*/
-
slirp_cleanup(Ctx);
}
@@ -333,165 +248,6 @@ void FinishUDPFrame(u8* data, int len)
*(u16*)&udpheader[6] = htons(tmp);
}
-void FinishTCPFrame(u8* data, int len)
-{
- u8* ipheader = &data[0xE];
- u8* tcpheader = &data[0x22];
-
- // lengths
- *(u16*)&ipheader[2] = htons(len - 0xE);
-
- // IP checksum
- u32 tmp = 0;
-
- for (int i = 0; i < 20; i += 2)
- tmp += ntohs(*(u16*)&ipheader[i]);
- while (tmp >> 16)
- tmp = (tmp & 0xFFFF) + (tmp >> 16);
- tmp ^= 0xFFFF;
- *(u16*)&ipheader[10] = htons(tmp);
-
- u32 tcplen = ntohs(*(u16*)&ipheader[2]) - 0x14;
-
- // TCP checksum
- tmp = 0;
- tmp += ntohs(*(u16*)&ipheader[12]);
- tmp += ntohs(*(u16*)&ipheader[14]);
- tmp += ntohs(*(u16*)&ipheader[16]);
- tmp += ntohs(*(u16*)&ipheader[18]);
- tmp += ntohs(0x0600);
- tmp += tcplen;
- for (u8* i = tcpheader; i < &tcpheader[tcplen-1]; i += 2)
- tmp += ntohs(*(u16*)i);
- if (tcplen & 1)
- tmp += ntohs((u_short)tcpheader[tcplen-1]);
- while (tmp >> 16)
- tmp = (tmp & 0xFFFF) + (tmp >> 16);
- tmp ^= 0xFFFF;
- *(u16*)&tcpheader[16] = htons(tmp);
-}
-
-
-void HandleDHCPFrame(u8* data, int len)
-{
- u8 type = 0xFF;
-
- u32 transid = *(u32*)&data[0x2E];
-
- u8* options = &data[0x11A];
- for (;;)
- {
- if (options >= &data[len]) break;
- u8 opt = *options++;
- if (opt == 255) break;
-
- u8 len = *options++;
- switch (opt)
- {
- case 53: // frame type
- type = options[0];
- break;
- }
-
- options += len;
- }
-
- if (type == 0xFF)
- {
- printf("DHCP: bad frame\n");
- return;
- }
-
- printf("DHCP: frame type %d, transid %08X\n", type, transid);
-
- if (type == 1 || // discover
- type == 3) // request
- {
- u8 resp[512];
- u8* out = &resp[0];
-
- // ethernet
- memcpy(out, &data[6], 6); out += 6;
- memcpy(out, kServerMAC, 6); out += 6;
- *(u16*)out = htons(0x0800); out += 2;
-
- // IP
- u8* ipheader = out;
- *out++ = 0x45;
- *out++ = 0x00;
- *(u16*)out = 0; out += 2; // total length
- *(u16*)out = htons(IPv4ID); out += 2; IPv4ID++;
- *out++ = 0x00;
- *out++ = 0x00;
- *out++ = 0x80; // TTL
- *out++ = 0x11; // protocol (UDP)
- *(u16*)out = 0; out += 2; // checksum
- *(u32*)out = htonl(kServerIP); out += 4; // source IP
- if (type == 1)
- {
- *(u32*)out = htonl(0xFFFFFFFF); out += 4; // destination IP
- }
- else if (type == 3)
- {
- *(u32*)out = htonl(kClientIP); out += 4; // destination IP
- }
-
- // UDP
- u8* udpheader = out;
- *(u16*)out = htons(67); out += 2; // source port
- *(u16*)out = htons(68); out += 2; // destination port
- *(u16*)out = 0; out += 2; // length
- *(u16*)out = 0; out += 2; // checksum
-
- // DHCP
- u8* body = out;
- *out++ = 0x02;
- *out++ = 0x01;
- *out++ = 0x06;
- *out++ = 0x00;
- *(u32*)out = transid; out += 4;
- *(u16*)out = 0; out += 2; // seconds elapsed
- *(u16*)out = 0; out += 2;
- *(u32*)out = htonl(0x00000000); out += 4; // client IP
- *(u32*)out = htonl(kClientIP); out += 4; // your IP
- *(u32*)out = htonl(kServerIP); out += 4; // server IP
- *(u32*)out = htonl(0x00000000); out += 4; // gateway IP
- memcpy(out, &data[6], 6); out += 6;
- memset(out, 0, 10); out += 10;
- memset(out, 0, 192); out += 192;
- *(u32*)out = 0x63538263; out += 4; // DHCP magic
-
- // DHCP options
- *out++ = 53; *out++ = 1;
- *out++ = (type==1) ? 2 : 5; // DHCP type: offer/ack
- *out++ = 1; *out++ = 4;
- *(u32*)out = htonl(0xFFFFFF00); out += 4; // subnet mask
- *out++ = 3; *out++ = 4;
- *(u32*)out = htonl(kServerIP); out += 4; // router
- *out++ = 51; *out++ = 4;
- *(u32*)out = htonl(442030); out += 4; // lease time
- *out++ = 54; *out++ = 4;
- *(u32*)out = htonl(kServerIP); out += 4; // DHCP server
- *out++ = 6; *out++ = 4;
- *(u32*)out = htonl(kDNSIP); out += 4; // DNS (hax)
-
- *out++ = 0xFF;
- memset(out, 0, 20); out += 20;
-
- u32 framelen = (u32)(out - &resp[0]);
- if (framelen & 1) { *out++ = 0; framelen++; }
- FinishUDPFrame(resp, framelen);
-
- // TODO: if there is already a packet queued, this will overwrite it
- // that being said, this will only happen during DHCP setup, so probably
- // not a big deal
-
- PacketLen = framelen;
- memcpy(PacketBuffer, resp, PacketLen);
- RXNum = 1;
- }
-}
-
void HandleDNSFrame(u8* data, int len)
{
u8* ipheader = &data[0xE];
@@ -653,540 +409,6 @@ void HandleDNSFrame(u8* data, int len)
RXNum = 1;
}
-void UDP_BuildIncomingFrame(UDPSocket* sock, u8* data, int len)
-{
- u8 resp[2048];
- u8* out = &resp[0];
-
- if (len > 1536) return;
-
- // ethernet
- memcpy(out, Wifi::GetMAC(), 6); out += 6; // hurf
- memcpy(out, kServerMAC, 6); out += 6;
- *(u16*)out = htons(0x0800); out += 2;
-
- // IP
- u8* resp_ipheader = out;
- *out++ = 0x45;
- *out++ = 0x00;
- *(u16*)out = 0; out += 2; // total length
- *(u16*)out = htons(IPv4ID); out += 2; IPv4ID++;
- *out++ = 0x00;
- *out++ = 0x00;
- *out++ = 0x80; // TTL
- *out++ = 0x11; // protocol (UDP)
- *(u16*)out = 0; out += 2; // checksum
- memcpy(out, sock->DestIP, 4); out += 4; // source IP
- *(u32*)out = htonl(kClientIP); out += 4; // destination IP
-
- // UDP
- u8* resp_tcpheader = out;
- *(u16*)out = htons(sock->DestPort); out += 2; // source port
- *(u16*)out = htons(sock->SourcePort); out += 2; // destination port
- *(u16*)out = htons(len+8); out += 2; // length of header+data
- *(u16*)out = 0; out += 2; // checksum
-
- memcpy(out, data, len); out += len;
-
- u32 framelen = (u32)(out - &resp[0]);
- FinishUDPFrame(resp, framelen);
-
- // TODO: if there is already a packet queued, this will overwrite it
- // that being said, this will only happen during DHCP setup, so probably
- // not a big deal
-
- PacketLen = framelen;
- memcpy(PacketBuffer, resp, PacketLen);
- RXNum = 1;
-}
-
-void HandleUDPFrame(u8* data, int len)
-{
- u8* ipheader = &data[0xE];
- u8* udpheader = &data[0x22];
-
- // debug
- /*for (int j = 0; j < len; j += 16)
- {
- int rem = len - j;
- if (rem > 16) rem = 16;
- for (int i = 0; i < rem; i++)
- {
- printf("%02X ", data[i+j]);
- }
- printf("\n");
- }*/
-
- u16 srcport = ntohs(*(u16*)&udpheader[0]);
- u16 dstport = ntohs(*(u16*)&udpheader[2]);
-
- int sockid = -1;
- UDPSocket* sock;
- for (int i = 0; i < (sizeof(UDPSocketList)/sizeof(UDPSocket)); i++)
- {
- sock = &UDPSocketList[i];
- if (sock->Backend != 0 && !memcmp(&sock->DestIP, &ipheader[16], 4) &&
- sock->SourcePort == srcport && sock->DestPort == dstport)
- {
- sockid = i;
- break;
- }
- }
-
- if (sockid == -1)
- {
- sockid = UDPSocketID;
- sock = &UDPSocketList[sockid];
-
- UDPSocketID++;
- if (UDPSocketID >= (sizeof(UDPSocketList)/sizeof(UDPSocket)))
- UDPSocketID = 0;
-
- if (sock->Backend != 0)
- {
- printf("LANMAGIC: closing previous UDP socket #%d\n", sockid);
- closesocket(sock->Backend);
- }
-
- sock->Backend = socket(AF_INET, SOCK_DGRAM, 0);
-
- memcpy(sock->DestIP, &ipheader[16], 4);
- sock->SourcePort = srcport;
- sock->DestPort = dstport;
-
- memset(&sock->BackendAddr, 0, sizeof(sock->BackendAddr));
- sock->BackendAddr.sin_family = AF_INET;
- sock->BackendAddr.sin_port = htons(dstport);
- memcpy(&sock->BackendAddr.sin_addr, &ipheader[16], 4);
- /*if (bind(sock->Backend, (struct sockaddr*)&sock->BackendAddr, sizeof(sock->BackendAddr)) == -1)
- {
- printf("bind() shat itself :(\n");
- }*/
-
- printf("LANMAGIC: opening UDP socket #%d to %d.%d.%d.%d:%d, srcport %d\n",
- sockid,
- ipheader[16], ipheader[17], ipheader[18], ipheader[19],
- dstport, srcport);
- }
-
- u16 udplen = ntohs(*(u16*)&udpheader[4]) - 8;
-
- printf("UDP: socket %d sending %d bytes\n", sockid, udplen);
- sendto(sock->Backend, (char*)&udpheader[8], udplen, 0,
- (struct sockaddr*)&sock->BackendAddr, sizeof(sock->BackendAddr));
-}
-
-void TCP_SYNACK(TCPSocket* sock, u8* data, int len)
-{
- u8 resp[128];
- u8* out = &resp[0];
-
- u8* ipheader = &data[0xE];
- u8* tcpheader = &data[0x22];
-
- u32 seqnum = htonl(*(u32*)&tcpheader[4]);
- seqnum++;
- sock->AckNum = seqnum;
-
- //printf("SYNACK SEQ=%08X|%08X\n", sock->SeqNum, sock->AckNum);
-
- // ethernet
- memcpy(out, &data[6], 6); out += 6;
- memcpy(out, kServerMAC, 6); out += 6;
- *(u16*)out = htons(0x0800); out += 2;
-
- // IP
- u8* resp_ipheader = out;
- *out++ = 0x45;
- *out++ = 0x00;
- *(u16*)out = 0; out += 2; // total length
- *(u16*)out = htons(IPv4ID); out += 2; IPv4ID++;
- *out++ = 0x00;
- *out++ = 0x00;
- *out++ = 0x80; // TTL
- *out++ = 0x06; // protocol (TCP)
- *(u16*)out = 0; out += 2; // checksum
- *(u32*)out = *(u32*)&ipheader[16]; out += 4; // source IP
- *(u32*)out = *(u32*)&ipheader[12]; out += 4; // destination IP
-
- // TCP
- u8* resp_tcpheader = out;
- *(u16*)out = *(u16*)&tcpheader[2]; out += 2; // source port
- *(u16*)out = *(u16*)&tcpheader[0]; out += 2; // destination port
- *(u32*)out = htonl(sock->SeqNum); out += 4; sock->SeqNum++; // seq number
- *(u32*)out = htonl(seqnum); out += 4; // ack seq number
- *(u16*)out = htons(0x8012); out += 2; // flags (SYN+ACK)
- *(u16*)out = htons(0x7000); out += 2; // window size (uuuh)
- *(u16*)out = 0; out += 2; // checksum
- *(u16*)out = 0; out += 2; // urgent pointer
-
- // TCP options
- *out++ = 0x02; *out++ = 0x04; // max segment size
- *(u16*)out = htons(0x05B4); out += 2;
- *out++ = 0x01;
- *out++ = 0x01;
- *out++ = 0x04; *out++ = 0x02; // SACK permitted
- *out++ = 0x01;
- *out++ = 0x03; *out++ = 0x03; // window size
- *out++ = 0x08;
-
- u32 framelen = (u32)(out - &resp[0]);
- //if (framelen & 1) { *out++ = 0; framelen++; }
- FinishTCPFrame(resp, framelen);
-
- // TODO: if there is already a packet queued, this will overwrite it
- // that being said, this will only happen during DHCP setup, so probably
- // not a big deal
-
- PacketLen = framelen;
- memcpy(PacketBuffer, resp, PacketLen);
- RXNum = 1;
-}
-
-void TCP_ACK(TCPSocket* sock, bool fin)
-{
- u8 resp[64];
- u8* out = &resp[0];
-
- u16 flags = 0x5010;
- if (fin) flags |= 0x0001;
-
- //printf("%sACK SEQ=%08X|%08X\n", fin?"FIN":" ", sock->SeqNum, sock->AckNum);
-
- // ethernet
- memcpy(out, Wifi::GetMAC(), 6); out += 6;
- memcpy(out, kServerMAC, 6); out += 6;
- *(u16*)out = htons(0x0800); out += 2;
-
- // IP
- u8* resp_ipheader = out;
- *out++ = 0x45;
- *out++ = 0x00;
- *(u16*)out = 0; out += 2; // total length
- *(u16*)out = htons(IPv4ID); out += 2; IPv4ID++;
- *out++ = 0x00;
- *out++ = 0x00;
- *out++ = 0x80; // TTL
- *out++ = 0x06; // protocol (TCP)
- *(u16*)out = 0; out += 2; // checksum
- *(u32*)out = *(u32*)&sock->DestIP; out += 4; // source IP
- *(u32*)out = htonl(kClientIP); out += 4; // destination IP
-
- // TCP
- u8* resp_tcpheader = out;
- *(u16*)out = htonl(sock->DestPort); out += 2; // source port
- *(u16*)out = htonl(sock->SourcePort); out += 2; // destination port
- *(u32*)out = htonl(sock->SeqNum); out += 4; // seq number
- *(u32*)out = htonl(sock->AckNum); out += 4; // ack seq number
- *(u16*)out = htons(flags); out += 2; // flags
- *(u16*)out = htons(0x7000); out += 2; // window size (uuuh)
- *(u16*)out = 0; out += 2; // checksum
- *(u16*)out = 0; out += 2; // urgent pointer
-
- u32 framelen = (u32)(out - &resp[0]);
- //if (framelen & 1) { *out++ = 0; framelen++; }
- FinishTCPFrame(resp, framelen);
-
- // TODO: if there is already a packet queued, this will overwrite it
- // that being said, this will only happen during DHCP setup, so probably
- // not a big deal
-
- PacketLen = framelen;
- memcpy(PacketBuffer, resp, PacketLen);
- RXNum = 1;
-}
-
-void TCP_BuildIncomingFrame(TCPSocket* sock, u8* data, int len)
-{
- u8 resp[2048];
- u8* out = &resp[0];
-
- if (len > 1536) return;
-//printf("INCOMING SEQ=%08X|%08X\n", sock->SeqNum, sock->AckNum);
- // ethernet
- memcpy(out, Wifi::GetMAC(), 6); out += 6; // hurf
- memcpy(out, kServerMAC, 6); out += 6;
- *(u16*)out = htons(0x0800); out += 2;
-
- // IP
- u8* resp_ipheader = out;
- *out++ = 0x45;
- *out++ = 0x00;
- *(u16*)out = 0; out += 2; // total length
- *(u16*)out = htons(IPv4ID); out += 2; IPv4ID++;
- *out++ = 0x00;
- *out++ = 0x00;
- *out++ = 0x80; // TTL
- *out++ = 0x06; // protocol (TCP)
- *(u16*)out = 0; out += 2; // checksum
- memcpy(out, sock->DestIP, 4); out += 4; // source IP
- *(u32*)out = htonl(kClientIP); out += 4; // destination IP
-
- // TCP
- u8* resp_tcpheader = out;
- *(u16*)out = htons(sock->DestPort); out += 2; // source port
- *(u16*)out = htons(sock->SourcePort); out += 2; // destination port
- *(u32*)out = htonl(sock->SeqNum); out += 4; // seq number
- *(u32*)out = htonl(sock->AckNum); out += 4; // ack seq number
- *(u16*)out = htons(0x5018); out += 2; // flags (ACK, PSH)
- *(u16*)out = htons(0x7000); out += 2; // window size (uuuh)
- *(u16*)out = 0; out += 2; // checksum
- *(u16*)out = 0; out += 2; // urgent pointer
-
- memcpy(out, data, len); out += len;
-
- u32 framelen = (u32)(out - &resp[0]);
- FinishTCPFrame(resp, framelen);
-
- // TODO: if there is already a packet queued, this will overwrite it
- // that being said, this will only happen during DHCP setup, so probably
- // not a big deal
-
- PacketLen = framelen;
- memcpy(PacketBuffer, resp, PacketLen);
- RXNum = 1;
-
- sock->SeqNum += len;
-}
-
-void HandleTCPFrame(u8* data, int len)
-{
- u8* ipheader = &data[0xE];
- u8* tcpheader = &data[0x22];
-
- u16 srcport = ntohs(*(u16*)&tcpheader[0]);
- u16 dstport = ntohs(*(u16*)&tcpheader[2]);
- u16 flags = ntohs(*(u16*)&tcpheader[12]);
-
- u32 tcpheaderlen = 4 * (flags >> 12);
- u32 tcplen = ntohs(*(u16*)&ipheader[2]) - 0x14;
- u32 tcpdatalen = tcplen - tcpheaderlen;
-
- /*printf("tcpflags=%04X header=%d data=%d seq=%08X|%08X\n",
- flags, tcpheaderlen, tcpdatalen,
- ntohl(*(u32*)&tcpheader[4]),
- ntohl(*(u32*)&tcpheader[8]));*/
-
- if (flags & 0x002) // SYN
- {
- int sockid = -1;
- TCPSocket* sock;
- for (int i = 0; i < (sizeof(TCPSocketList)/sizeof(TCPSocket)); i++)
- {
- sock = &TCPSocketList[i];
- if (sock->Status != 0 && !memcmp(&sock->DestIP, &ipheader[16], 4) &&
- sock->SourcePort == srcport && sock->DestPort == dstport)
- {
- printf("LANMAGIC: duplicate TCP socket\n");
- sockid = i;
- break;
- }
- }
-
- if (sockid == -1)
- {
- for (int i = 0; i < (sizeof(TCPSocketList)/sizeof(TCPSocket)); i++)
- {
- sock = &TCPSocketList[i];
- if (sock->Status == 0)
- {
- sockid = i;
- break;
- }
- }
- }
-
- if (sockid == -1)
- {
- printf("LANMAGIC: !! TCP SOCKET LIST FULL\n");
- return;
- }
-
- printf("LANMAGIC: opening TCP socket #%d to %d.%d.%d.%d:%d, srcport %d\n",
- sockid,
- ipheader[16], ipheader[17], ipheader[18], ipheader[19],
- dstport, srcport);
-
- // keep track of it
- sock->Status = 1;
- memcpy(sock->DestIP, &ipheader[16], 4);
- sock->DestPort = dstport;
- sock->SourcePort = srcport;
- sock->SeqNum = 0x13370000;
- sock->AckNum = 0;
-
- // open backend socket
- if (!sock->Backend)
- {
- sock->Backend = socket(AF_INET, SOCK_STREAM, 0);
- }
-
- struct sockaddr_in conn_addr;
- memset(&conn_addr, 0, sizeof(conn_addr));
- conn_addr.sin_family = AF_INET;
- memcpy(&conn_addr.sin_addr, &ipheader[16], 4);
- conn_addr.sin_port = htons(dstport);
- if (connect(sock->Backend, (sockaddr*)&conn_addr, sizeof(conn_addr)) == -1)
- {
- printf("connect() shat itself :(\n");
- }
- else
- {
- // acknowledge it
- TCP_SYNACK(sock, data, len);
- }
- }
- else
- {
- int sockid = -1;
- TCPSocket* sock;
- for (int i = 0; i < (sizeof(TCPSocketList)/sizeof(TCPSocket)); i++)
- {
- sock = &TCPSocketList[i];
- if (sock->Status != 0 && !memcmp(&sock->DestIP, &ipheader[16], 4) &&
- sock->SourcePort == srcport && sock->DestPort == dstport)
- {
- sockid = i;
- break;
- }
- }
-
- if (sockid == -1)
- {
- printf("LANMAGIC: bad TCP packet\n");
- return;
- }
-
- // TODO: check those
- u32 seqnum = ntohl(*(u32*)&tcpheader[4]);
- u32 acknum = ntohl(*(u32*)&tcpheader[8]);
- sock->SeqNum = acknum;
- sock->AckNum = seqnum + tcpdatalen;
-
- // send data over the socket
- if (tcpdatalen > 0)
- {
- u8* tcpdata = &tcpheader[tcpheaderlen];
-
- printf("TCP: socket %d sending %d bytes (flags=%04X)\n", sockid, tcpdatalen, flags);
- send(sock->Backend, (char*)tcpdata, tcpdatalen, 0);
-
- // kind of a hack, there
- TCP_ACK(sock, false);
- }
-
- if (flags & 0x001) // FIN
- {
- // TODO: timeout etc
- printf("TCP: socket %d closing\n", sockid);
-
- sock->Status = 0;
- closesocket(sock->Backend);
- sock->Backend = 0;
- }
- }
-}
-
-void HandleARPFrame(u8* data, int len)
-{
- u16 protocol = ntohs(*(u16*)&data[0x10]);
- if (protocol != 0x0800) return;
-
- u16 op = ntohs(*(u16*)&data[0x14]);
- u32 targetip = ntohl(*(u32*)&data[0x26]);
-
- // TODO: handle ARP to the client
- // this only handles ARP to the DHCP/router
-
- if (op == 1)
- {
- // opcode 1=req 2=reply
- // sender MAC
- // sender IP
- // target MAC
- // target IP
-
- const u8* targetmac;
- if (targetip == kServerIP) targetmac = kServerMAC;
- else if (targetip == kDNSIP) targetmac = kDNSMAC;
- else return;
-
- u8 resp[64];
- u8* out = &resp[0];
-
- // ethernet
- memcpy(out, &data[6], 6); out += 6;
- memcpy(out, kServerMAC, 6); out += 6;
- *(u16*)out = htons(0x0806); out += 2;
-
- // ARP
- *(u16*)out = htons(0x0001); out += 2; // hardware type
- *(u16*)out = htons(0x0800); out += 2; // protocol
- *out++ = 6; // MAC address size
- *out++ = 4; // IP address size
- *(u16*)out = htons(0x0002); out += 2; // opcode
- memcpy(out, targetmac, 6); out += 6;
- *(u32*)out = htonl(targetip); out += 4;
- memcpy(out, &data[0x16], 6+4); out += 6+4;
-
- u32 framelen = (u32)(out - &resp[0]);
-
- // TODO: if there is already a packet queued, this will overwrite it
- // that being said, this will only happen during DHCP setup, so probably
- // not a big deal
-
- PacketLen = framelen;
- memcpy(PacketBuffer, resp, PacketLen);
- RXNum = 1;
- }
- else
- {
- printf("wat??\n");
- }
-}
-
-void HandlePacket(u8* data, int len)
-{
- u16 ethertype = ntohs(*(u16*)&data[0xC]);
-
- if (ethertype == 0x0800) // IPv4
- {
- u8 protocol = data[0x17];
- if (protocol == 0x11) // UDP
- {
- u16 srcport = ntohs(*(u16*)&data[0x22]);
- u16 dstport = ntohs(*(u16*)&data[0x24]);
- if (srcport == 68 && dstport == 67) // DHCP
- {
- printf("LANMAGIC: DHCP packet\n");
- return HandleDHCPFrame(data, len);
- }
- else if (dstport == 53 && htonl(*(u32*)&data[0x1E]) == kDNSIP) // DNS
- {
- printf("LANMAGIC: DNS packet\n");
- return HandleDNSFrame(data, len);
- }
-
- printf("LANMAGIC: UDP packet %d->%d\n", srcport, dstport);
- return HandleUDPFrame(data, len);
- }
- else if (protocol == 0x06) // TCP
- {
- printf("LANMAGIC: TCP packet\n");
- return HandleTCPFrame(data, len);
- }
- else
- printf("LANMAGIC: unsupported IP protocol %02X\n", protocol);
- }
- else if (ethertype == 0x0806) // ARP
- {
- printf("LANMAGIC: ARP packet\n");
- return HandleARPFrame(data, len);
- }
- else
- printf("LANMAGIC: unsupported ethernet type %04X\n", ethertype);
-}
-
int SendPacket(u8* data, int len)
{
if (len > 2048)
@@ -1196,52 +418,21 @@ int SendPacket(u8* data, int len)
}
u16 ethertype = ntohs(*(u16*)&data[0xC]);
- printf("packet of type %04X\n", ethertype);
- if (ethertype == 0x0806)
- {
- u16 protocol = ntohs(*(u16*)&data[0x10]);
- u16 op = ntohs(*(u16*)&data[0x14]);
- u32 sourceip = ntohl(*(u32*)&data[0x26-4-6]);
- u32 targetip = ntohl(*(u32*)&data[0x26]);
- printf("ARP: protocol=%04X, op=%04X, source=%08X, target=%08X\n", protocol, op, sourceip, targetip);
- }
- else if (ethertype == 0x800)
+ if (ethertype == 0x800)
{
u8 protocol = data[0x17];
if (protocol == 0x11) // UDP
{
- u16 srcport = ntohs(*(u16*)&data[0x22]);
u16 dstport = ntohs(*(u16*)&data[0x24]);
- if (srcport == 68 && dstport == 67) // DHCP
- {
- printf("LANMAGIC: DHCP packet\n");
- }
- else if (dstport == 53 && htonl(*(u32*)&data[0x1E]) == kDNSIP) // DNS
+ if (dstport == 53 && htonl(*(u32*)&data[0x1E]) == kDNSIP) // DNS
{
- printf("LANMAGIC: DNS packet\n");
HandleDNSFrame(data, len);
return len;
}
-
- printf("LANMAGIC: UDP packet %08X->%08X %d->%d\n", htonl(*(u32*)&data[0x1A]), htonl(*(u32*)&data[0x1E]), srcport, dstport);
- }
- else if (protocol == 0x06) // TCP
- {
- printf("LANMAGIC: TCP packet\n");
-
- for (int i = 0; i < len; i++)
- {
- printf("%02X ", data[i]);
- if ((i&0xF)==0xF) printf("\n");
- }
- printf("\n");
}
- else
- printf("LANMAGIC: unsupported IP protocol %02X\n", protocol);
}
- //HandlePacket(data, len);
slirp_input(Ctx, data, len);
return len;
}
@@ -1313,13 +504,6 @@ int RecvPacket(u8* data)
slirp_pollfds_fill(Ctx, &timeout, SlirpCbAddPoll, nullptr);
int res = poll(FDList, FDListSize, timeout);
slirp_pollfds_poll(Ctx, res<0, SlirpCbGetREvents, nullptr);
-
- /*struct pollfd derp = {0};;
- derp.fd = FDList[0];
- derp.events = POLLIN | POLLWRNORM;//POLLPRI | POLLIN | POLLWRNORM;
- int res = poll(&derp, 1, 0);
- if (res==SOCKET_ERROR) printf("fart: %d / %d\n", WSAGetLastError(), FDList[0]);
- if(derp.revents) printf("derp: %04X\n", derp.revents);*/
}
if (RXNum > 0)
@@ -1329,90 +513,6 @@ int RecvPacket(u8* data)
RXNum = 0;
}
- /*for (int i = 0; i < (sizeof(TCPSocketList)/sizeof(TCPSocket)); i++)
- {
- TCPSocket* sock = &TCPSocketList[i];
- if (sock->Status != 1) continue;
-
- fd_set fd;
- struct timeval tv;
-
- FD_ZERO(&fd);
- FD_SET(sock->Backend, &fd);
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- if (!select(sock->Backend+1, &fd, 0, 0, &tv))
- {
- continue;
- }
-
- u8 recvbuf[1024];
- int recvlen = recv(sock->Backend, (char*)recvbuf, 1024, 0);
- if (recvlen < 1)
- {
- if (recvlen == 0)
- {
- // socket has closed from the other side
- printf("TCP: socket %d closed from other side\n", i);
- sock->Status = 2;
- TCP_ACK(sock, true);
- }
- continue;
- }
-
- printf("TCP: socket %d receiving %d bytes\n", i, recvlen);
- TCP_BuildIncomingFrame(sock, recvbuf, recvlen);
-
- // debug
- /*for (int j = 0; j < recvlen; j += 16)
- {
- int rem = recvlen - j;
- if (rem > 16) rem = 16;
- for (int k = 0; k < rem; k++)
- {
- printf("%02X ", recvbuf[k+j]);
- }
- printf("\n");
- }*-/
-
- //recvlen = recv(sock->Backend, (char*)recvbuf, 1024, 0);
- //if (recvlen == 0) printf("it closed immediately after\n");
- }
-
- for (int i = 0; i < (sizeof(UDPSocketList)/sizeof(UDPSocket)); i++)
- {
- UDPSocket* sock = &UDPSocketList[i];
- if (sock->Backend == 0) continue;
-
- fd_set fd;
- struct timeval tv;
-
- FD_ZERO(&fd);
- FD_SET(sock->Backend, &fd);
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- if (!select(sock->Backend+1, &fd, 0, 0, &tv))
- {
- continue;
- }
-
- u8 recvbuf[1024];
- sockaddr_t fromAddr;
- socklen_t fromLen = sizeof(sockaddr_t);
- int recvlen = recvfrom(sock->Backend, (char*)recvbuf, 1024, 0, &fromAddr, &fromLen);
- if (recvlen < 1) continue;
-
- if (fromAddr.sa_family != AF_INET) continue;
- struct sockaddr_in* fromAddrIn = (struct sockaddr_in*)&fromAddr;
- if (memcmp(&fromAddrIn->sin_addr, sock->DestIP, 4)) continue;
- if (ntohs(fromAddrIn->sin_port) != sock->DestPort) continue;
-
- printf("UDP: socket %d receiving %d bytes\n", i, recvlen);
- UDP_BuildIncomingFrame(sock, recvbuf, recvlen);
- }*/
-
return ret;
}