A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.

Dependents:   oldheating gps motorhome heating

ip4/udptcp4.c

Committer:
andrewboyson
Date:
2019-02-22
Revision:
125:8c84daac38ab
Parent:
121:bc048b65a630
Child:
136:8a65abb0dc63

File content as of revision 125:8c84daac38ab:

#include <stdint.h>

#include     "log.h"
#include     "net.h"
#include  "action.h"
#include    "dhcp.h"
#include     "eth.h"
#include      "ip.h"
#include "ip4addr.h"
#include     "tcp.h"
#include "tcprecv.h"
#include "tcpsend.h"
#include  "tcphdr.h"
#include     "udp.h"
#include     "ar4.h"
#include     "led.h"
#include   "fault.h"

static uint16_t calculateChecksum(uint8_t pro, uint32_t srcIp, uint32_t dstIp, int size, void* pPacket)
{
    __packed struct pseudo
    {
        uint32_t src;
        uint32_t dst;
        uint8_t  zer;
        uint8_t  pro;
        uint16_t len;
    } pseudo;
    
    pseudo.src = srcIp;
    pseudo.dst = dstIp;
    pseudo.zer = 0;
    pseudo.pro = pro;
    pseudo.len = NetToHost16(size);

    return NetCheckSumTwo(sizeof(pseudo), &pseudo, size, pPacket);
}
static void finalisePacket(uint8_t pro, int action, void* pPacket, int size, uint32_t* pSrcIp, uint32_t* pDstIp)
{    
    if (!action) return;
    
    Ip4AddressFromDest(ActionGetDestPart(action), pDstIp);
    *pSrcIp = DhcpLocalIp;
    
    switch (pro)
    {
        case TCP: TcpHdrWriteToPacket(pPacket); break;
        case UDP: UdpMakeHeader(size, pPacket); break;
    }
    
    uint16_t checksum = calculateChecksum(pro, *pSrcIp, *pDstIp, size, pPacket);
    
    switch (pro)
    {
        case TCP: TcpHdrAddChecksumToPacket(pPacket, checksum); break;
        case UDP: UdpAddChecksum(pPacket, checksum); break;
    }
    
    if (ActionGetTracePart(action))
    {
        switch (pro)
        {
            case TCP: TcpHdrLog(0); break;
            case UDP: UdpLogHeader(0); break;
        }
    }
}

static void (*pTraceBack)(void);
static int tracePacketProtocol;
static uint16_t calculatedChecksum;
static void trace()
{
    pTraceBack();
    switch(tracePacketProtocol)
    {
        case UDP: UdpLogHeader(calculatedChecksum); break;
        case TCP: TcpHdrLog(calculatedChecksum); break;
        default: LogTimeF("UdpTcp4 - traceback unrecognised protocol %d\r\n", tracePacketProtocol); break;
    }
}
int Tcp4HandleReceivedPacket(void (*traceback)(void), void* pPacketRx, int sizeRx, void* pPacketTx, int* pSizeTx, uint32_t* pSrcIp, uint32_t* pDstIp, int remArIndex)
{
    int lastFaultPoint = FaultPoint;
    FaultPoint = FAULT_POINT_Tcp4HandleReceivedPacket;
    
    pTraceBack = traceback;
    tracePacketProtocol = TCP;
    calculatedChecksum = calculateChecksum(TCP, *pSrcIp, *pDstIp, sizeRx, pPacketRx);
        
    int action = TcpHandleReceivedPacket(trace, sizeRx, pPacketRx, pSizeTx, pPacketTx, IPV4, remArIndex, 0);
    
    *pDstIp = *pSrcIp;
    
    finalisePacket(TCP, action, pPacketTx, *pSizeTx, pSrcIp, pDstIp);
  
    FaultPoint = lastFaultPoint;
    return action;
}

int Udp4HandleReceivedPacket(void (*traceback)(void), void* pPacketRx, int sizeRx, void* pPacketTx, int* pSizeTx, uint32_t* pSrcIp, uint32_t* pDstIp)
{   
    int lastFaultPoint = FaultPoint;
    FaultPoint = FAULT_POINT_Udp4HandleReceivedPacket;
    
    pTraceBack = traceback;
    tracePacketProtocol = UDP;
    calculatedChecksum = calculateChecksum(UDP, *pSrcIp, *pDstIp, sizeRx, pPacketRx);
     
    int action = UdpHandleReceivedPacket(trace, sizeRx, pPacketRx, pSizeTx, pPacketTx);

    *pDstIp = *pSrcIp;
    
    finalisePacket(UDP, action, pPacketTx, *pSizeTx, pSrcIp, pDstIp); //Note that the ports are reversed here
    
    FaultPoint = lastFaultPoint;
    return action;
}
int Tcp4PollForPacketToSend(void* pPacket, int* pSize, uint32_t* pSrcIp, uint32_t* pDstIp)
{        
    int remArIndex = -1;
    int action = TcpPollForPacketToSend(pSize, pPacket, IPV4, &remArIndex, NULL);
    if (action && remArIndex >= 0) *pDstIp = Ar4IndexToIp(remArIndex);
    
    finalisePacket(TCP, action, pPacket, *pSize, pSrcIp, pDstIp);
        
    return action;
}
int Udp4PollForPacketToSend(void* pPacket, int* pSize, uint32_t* pSrcIp, uint32_t* pDstIp)
{        
    int action = UdpPollForPacketToSend(IPV4, pSize, pPacket);
    
    finalisePacket(UDP, action, pPacket, *pSize, pSrcIp, pDstIp);
        
    return action;
}