Uthernet 2: draft UDP processing.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2021-04-28 20:27:43 +01:00
parent 6243d17e93
commit 669c7124c2
3 changed files with 95 additions and 16 deletions

View file

@ -4,6 +4,13 @@
#include "Tfe/tfearch.h"
#include "Tfe/tfe.h"
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "../Log.h"
namespace
{
@ -47,7 +54,6 @@ void tfeTransmitOnePacket(const BYTE * buffer, const int len)
}
}
bool tfeReceiveOnePacket(const uint8_t * mac, BYTE * buffer, int & len)
{
if (!tfe_enabled)
@ -94,3 +100,80 @@ bool tfeReceiveOnePacket(const uint8_t * mac, BYTE * buffer, int & len)
} while (!done);
return false;
}
void tfeTransmitOneUDPPacket(const uint8_t * dest, const BYTE * buffer, const int len)
{
if (len < 8)
{
return;
}
const uint16_t length = readNetworkWord(buffer + 4);
if (len != length)
{
return;
}
const int socketSD = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (socketSD <= 0)
{
LogFileOutput("Error: Could not open socket.\n");
return;
}
sockaddr_in source;
memset(&source, 0, sizeof(source));
source.sin_family = AF_INET;
// already in network order
source.sin_port = *reinterpret_cast<const uint16_t *>(buffer + 0);
source.sin_addr.s_addr = INADDR_ANY;
int ret = bind(socketSD, (sockaddr*)&source, sizeof(source));
if (ret < 0)
{
perror(NULL);
LogFileOutput("Error: Could not bind socket.");
close(socketSD);
return;
}
// Configure the port and ip we want to send to
sockaddr_in destination;
memset(&destination, 0, sizeof(destination));
destination.sin_family = AF_INET;
// already in network order
destination.sin_port = *reinterpret_cast<const uint16_t *>(buffer + 2);
destination.sin_addr.s_addr = *reinterpret_cast<const uint32_t *>(dest);
if (destination.sin_addr.s_addr == INADDR_BROADCAST)
{
// set socket options enable broadcast
int broadcastEnable = 1;
const int ret = setsockopt(socketSD, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable));
if (ret)
{
LogFileOutput("Error: Could not open set socket to broadcast mode.\n");
close(socketSD);
return;
}
}
const void * data = buffer + 8;
ret = sendto(socketSD, data, len - 8, 0, (sockaddr*)&destination, sizeof(destination));
if (ret < 0)
{
LogFileOutput("Error: Could not open send broadcast.");
close(socketSD);
return;
}
close(socketSD);
}
uint16_t readNetworkWord(const uint8_t * address)
{
const uint16_t network = *reinterpret_cast<const uint16_t *>(address);
const uint16_t host = ntohs(network);
return host;
}

View file

@ -2,3 +2,5 @@
bool tfeReceiveOnePacket(const uint8_t * mac, BYTE * buffer, int & len);
void tfeTransmitOnePacket(const BYTE * buffer, const int len);
void tfeTransmitOneUDPPacket(const uint8_t * dest, const BYTE * buffer, const int len);
uint16_t readNetworkWord(const uint8_t * address);

View file

@ -78,14 +78,6 @@ namespace
}
}
uint16_t readNetworkWord(const uint16_t address)
{
const uint8_t high = memory[address];
const uint8_t low = memory[address + 1];
const uint16_t value = low + (high << 8);
return value;
}
void setSocketModeRegister(const size_t i, const uint16_t address, const uint8_t value)
{
memory[address] = value;
@ -156,11 +148,12 @@ namespace
uint16_t getTXDataSize(const size_t i)
{
const uint16_t size = sockets[i].transmitSize;
const Socket & socket = sockets[i];
const uint16_t size = socket.transmitSize;
const uint16_t mask = size - 1;
const int sn_tx_rr = readNetworkWord(sockets[i].registers + 0x22) & mask;
const int sn_tx_wr = readNetworkWord(sockets[i].registers + 0x24) & mask;
const int sn_tx_rr = readNetworkWord(memory.data() + socket.registers + 0x22) & mask;
const int sn_tx_wr = readNetworkWord(memory.data() + socket.registers + 0x24) & mask;
int dataPresent = sn_tx_wr - sn_tx_rr;
if (dataPresent < 0)
@ -193,8 +186,8 @@ namespace
const int size = sockets[i].receiveSize;
const uint16_t mask = size - 1;
const int sn_rx_rd = readNetworkWord(sockets[i].registers + 0x28) & mask;
const int sn_rx_wr = sockets[i].sn_rx_wr & mask;
const int sn_rx_rd = readNetworkWord(memory.data() + socket.registers + 0x28) & mask;
const int sn_rx_wr = socket.sn_rx_wr & mask;
int dataPresent = sn_rx_wr - sn_rx_rd;
if (dataPresent < 0)
{
@ -269,6 +262,7 @@ namespace
LogFileOutput(" from %d.%d.%d.%d", source[0], source[1], source[2], source[3]);
LogFileOutput(" to %d.%d.%d.%d", dest[0], dest[1], dest[2], dest[3]);
LogFileOutput(" via %d.%d.%d.%d\n", gway[0], gway[1], gway[2], gway[3]);
tfeTransmitOneUDPPacket(dest, data.data(), data.size());
#endif
}
@ -278,8 +272,8 @@ namespace
const uint16_t size = socket.transmitSize;
const uint16_t mask = size - 1;
const int sn_tx_rr = readNetworkWord(socket.registers + 0x22) & mask;
const int sn_tx_wr = readNetworkWord(socket.registers + 0x24) & mask;
const int sn_tx_rr = readNetworkWord(memory.data() + socket.registers + 0x22) & mask;
const int sn_tx_wr = readNetworkWord(memory.data() + socket.registers + 0x24) & mask;
const uint16_t base = socket.transmitBase;
const uint16_t rr_address = base + sn_tx_rr;