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
Diff: ip4/udptcp4.cpp
- Revision:
- 10:f0854784e960
- Child:
- 11:c051adb70c5a
diff -r 91dae5300a4d -r f0854784e960 ip4/udptcp4.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ip4/udptcp4.cpp Sun Apr 16 14:21:55 2017 +0000 @@ -0,0 +1,125 @@ +#include "mbed.h" +#include "log.h" +#include "net.h" +#include "dhcp.h" +#include "ip4.h" +#include "tcp.h" +#include "udp.h" + +#define DEBUG false + +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 destIpFromAction(int action, uint32_t* pDstIp) +{ + switch (action) + { + case UNICAST: + break; + case UNICAST_DNS: + *pDstIp = DhcpDnsServer; + break; + case UNICAST_DHCP: + *pDstIp = DhcpServer; + break; + case MULTICAST_NODE: + *pDstIp = IP4_MULTICAST_ALL_HOSTS; + break; + case MULTICAST_ROUTER: + *pDstIp = IP4_MULTICAST_ALL_ROUTERS; + break; + case MULTICAST_MDNS: + *pDstIp = IP4_MULTICAST_DNS_ADDRESS; + break; + case MULTICAST_LLMNR: + *pDstIp = IP4_MULTICAST_LLMNR_ADDRESS; + break; + case BROADCAST: + *pDstIp = IP4_BROADCAST_ADDRESS; + break; + default: + LogTimeF("UdpTcp4 destIpFromAction unknown action %d\r\n", action); + return; + } +} +static void finalisePacket(uint8_t pro, int action, void* pPacket, int size, uint32_t* pSrcIp, uint32_t* pDstIp) +{ + if (!action) return; + + destIpFromAction(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 (DEBUG) TcpLogHeader("IPv4 packet sent", pPacket, 0); +} + +int Tcp4HandleReceivedPacket(uint32_t* pSrcIp, uint32_t* pDstIp, int* pSize, void * pPacket) +{ + uint16_t calculatedChecksum = calculateChecksum(TCP, *pSrcIp, *pDstIp, *pSize, pPacket); + if (DEBUG) TcpLogHeader("IPv4 packet received", pPacket, calculatedChecksum); + + TcpReadHeader(pPacket, *pSize); + + int action = TcpHandleReceivedPacket(pSize, pPacket); + + *pDstIp = *pSrcIp; + + finalisePacket(TCP, action, pPacket, *pSize, pSrcIp, pDstIp); + + return action; +} + +int Udp4HandleReceivedPacket(uint32_t* pSrcIp, uint32_t* pDstIp, int* pSize, void * pPacket) +{ + uint16_t calculatedChecksum = calculateChecksum(UDP, *pSrcIp, *pDstIp, *pSize, pPacket); + if (DEBUG) UdpLogHeader("IPv4 packet received", pPacket, calculatedChecksum); + + UdpReadHeader(pPacket, *pSize); + + int action = UdpHandleReceivedPacket(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; +}