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.cpp

Committer:
andrewboyson
Date:
2017-11-14
Revision:
56:35117a8b5c65
Parent:
55:e64b8b47a2b6
Child:
59:e0e556c8bd46

File content as of revision 56:35117a8b5c65:

#include   "mbed.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    "udp.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: TcpMakeHeader(size, pPacket); break;
        case UDP: UdpMakeHeader(size, pPacket); break;
    }
    
    uint16_t checksum = calculateChecksum(pro, *pSrcIp, *pDstIp, size, pPacket);
    
    switch (pro)
    {
        case TCP: TcpAddChecksum(pPacket, checksum); break;
        case UDP: UdpAddChecksum(pPacket, checksum); break;
    }
    
    if (ActionGetTracePart(action))
    {
        switch (pro)
        {
            case TCP: TcpLogHeader(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: TcpLogHeader(calculatedChecksum); break;
        default: LogTimeF("UdpTcp4 - traceback unrecognised protocol %d\r\n", tracePacketProtocol); break;
    }
}
int Tcp4HandleReceivedPacket(void (*traceback)(void), uint32_t* pSrcIp, uint32_t* pDstIp, int* pSize, void * pPacket)
{   
    pTraceBack = traceback;
    tracePacketProtocol = TCP;
    calculatedChecksum = calculateChecksum(TCP, *pSrcIp, *pDstIp, *pSize, pPacket);
 
    TcpReadHeader(pPacket, *pSize);
        
    int action = TcpHandleReceivedPacket(trace, pSize, pPacket);
    
    *pDstIp = *pSrcIp;
    
    finalisePacket(TCP, action, pPacket, *pSize, pSrcIp, pDstIp);
  
    return action;
}

int Udp4HandleReceivedPacket(void (*traceback)(void), uint32_t* pSrcIp, uint32_t* pDstIp, int* pSize, void* pPacket)
{   
    pTraceBack = traceback;
    tracePacketProtocol = UDP;
    calculatedChecksum = calculateChecksum(UDP, *pSrcIp, *pDstIp, *pSize, pPacket);
 
    UdpReadHeader(pPacket, *pSize);
    
    int action = UdpHandleReceivedPacket(trace, pSize, pPacket);

    *pDstIp = *pSrcIp;
    
    finalisePacket(UDP, action, pPacket, *pSize, pSrcIp, pDstIp); //Note that the ports are reversed here
  
    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;
}