EtherLib/prefab/conn_blocks/tcp_connblock.c
Wiesner András 51696f7341 - MemoryPool allocation-deallocation bug fixed
- generic Queue implemented
- PacketRegistry allocation bug fixed
- TCP implementation initials
- ALIGN to type macros added
2023-01-17 08:19:29 +01:00

116 lines
3.8 KiB
C

#include "tcp_connblock.h"
#include <stddef.h>
#include <stdlib.h>
#include "../packet_parsers/packet_parsers.h"
#include "../../utils.h"
#include "../../dynmem.h"
#include "etherlib/pckt_assembler.h"
#include "etherlib/eth_interface.h"
#include "ipv4_connblock.h"
#include "etherlib/prefab/packet_parsers/tcp_segment.h"
#include "etherlib/gen_queue.h"
#include "etherlib_options.h"
static bool filtTcp(const PcktSieveFilterCondition *filtCond, const PcktProps *contProps, const PcktProps *ownProps, EthInterface *intf) {
IPv4Props *ipProps = (IPv4Props *) contProps;
TcpProps *tcpProps = (TcpProps *) ownProps;
return ipProps->Protocol == ETH_UDP_PACKET_CLASS && (TCP_PORT_FROM_FILTCOND(filtCond) == tcpProps->DestinationPort);
}
/**
* TCP state.
*/
typedef struct {
uint16_t localPort;
uint16_t remotePort;
ip4_addr remoteAddr;
uint32_t sequenceNumber;
uint32_t ackNumber;
uint16_t window;
uint8_t * txWindow;
uint8_t * rxWindow;
Queue * txQueue;
Queue * rxQueue;
} TcpState;
void tcps_init(TcpState *tcps, uint16_t localPort) {
tcps->sequenceNumber = (uint32_t) rand();
tcps->localPort = localPort;
tcps->remotePort = 0;
tcps->remoteAddr = 0;
tcps->ackNumber = 0;
tcps->window = 0;
tcps->txWindow = dynmem_alloc(ETHLIB_DEF_TCP_WINDOW_SIZE);
tcps->rxWindow = dynmem_alloc(ETHLIB_DEF_TCP_WINDOW_SIZE);
/*tcps->txQueue = Q_CREATE_T(ETHLIB_DEF_TCP_QUEUE_SIZE, TcpQueueTicker);
tcps->rxQueue = Q_CREATE_T(ETHLIB_DEF_TCP_QUEUE_SIZE, TcpQueueTicker);*/
}
void tcp_bind(ConnBlock * connBlock, ip4_addr remoteAddr, uint16_t remotePort) {
TcpState * tcps = (TcpState *) connBlock->tag;
tcps->remoteAddr = remoteAddr;
tcps->remotePort = remotePort;
}
int tcps_receive_data_segment(TcpState * tcps, const Pckt * pckt) {
}
ConnBlock tcp_new_connblock(EthInterface *intf, ip4_addr ipAddr, uint16_t port, SieveCallBackFn cbFn) {
ConnBlock tcpConnB;
ConnBlock ipConnB = ipv4_new_connblock(intf, ipAddr, NULL); // create new IPv4 connection block
PcktSieveFilterCondition filtCond;
packfiltcond_zero(&filtCond);
TCP_PORT_TO_FILTCOND(&filtCond, port);
PcktSieveLayerTag tag; // store TCP state into sieve layer's tag
tag.p = dynmem_alloc(sizeof(TcpState));
memset(tag.p, 0, sizeof(TcpState));
tcpConnB.sieveLayer = packsieve_new_layer(ipConnB.sieveLayer, &filtCond, false, filtTcp, cbFn, tag, ETH_TCP_PACKET_CLASS);
ASSERT_NULL(tcpConnB.sieveLayer);
tcpConnB.intf = intf;
SNPRINTF(tcpConnB.sieveLayer->infoTag, PCKT_SIEVE_INFOTAG_LEN, "TCP port: %d", port);
return tcpConnB;
}
int tcp_send_segment(const struct ConnBlock_ *connBlock, const uint8_t *data, uint32_t size) {
// allocate headers
PcktHeaderElement *tcpHeader = ALLOC_HEADER_ELEMENT(TcpProps);
PcktHeaderElement *ipHeader = ALLOC_HEADER_ELEMENT(IPv4Props);
PcktHeaderElement *ethHeader = ALLOC_HEADER_ELEMENT(EthernetProps);
tcpHeader->next = NULL;
tcpHeader->prev = ipHeader;
ipHeader->next = tcpHeader;
ipHeader->prev = ethHeader;
ethHeader->next = ipHeader;
ethHeader->prev = NULL;
// prepare headers
TcpProps *tcpProps = HEADER_FETCH_PROPS(TcpProps, tcpHeader);
IPv4Props *ipProps = HEADER_FETCH_PROPS(IPv4Props, ipHeader);
EthernetProps *ethProps = HEADER_FETCH_PROPS(EthernetProps, ethHeader);
// get TCP state
PcktSieveLayer *layer = connBlock->sieveLayer; // TCP layer
TcpState *tcpState = (TcpState *) layer->tag.p;
// fetch sieve layers and fill transmit headers
tcpProps->SourcePort = tcpState->localPort;
tcpProps->DestinationPort = tcpState->remotePort;
tcpProps->SequenceNumber = tcpState->sequenceNumber;
tcpProps->AcknowledgementNumber = tcpState->ackNumber;
tcpProps->Window = tcpState->window;
tcpProps->Checksum = 0;
tcpProps->UrgentPtr = 0;
return 0;
}