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: udp/udp.cpp
- Revision:
- 10:f0854784e960
- Child:
- 13:9cd54f7db57a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/udp/udp.cpp Sun Apr 16 14:21:55 2017 +0000 @@ -0,0 +1,149 @@ +#include "mbed.h" +#include "log.h" +#include "net.h" +#include "udp.h" +#include "ntp.h" +#include "dhcp.h" +#include "dns.h" +#include "ip4.h" +#include "ip6.h" +#include "slaac.h" +#include "ndp.h" + +#define UNKNOWN false + +#define HEADER_SIZE 8 +__packed struct header +{ + uint16_t srcPort; + uint16_t dstPort; + uint16_t totalLength; + uint16_t checksum; +}; +static uint16_t srcPort; +static uint16_t dstPort; +static uint16_t checksum; +static uint16_t totalLength; + +static int handlePort(int* pDataLength, void* pData) +{ + switch (dstPort) + { + //Handle these + case DHCP_CLIENT_PORT: return DhcpHandleResponse(pDataLength, pData); //68 + case NTP_SERVER_PORT: return NtpHandleRequest (pDataLength, pData); //123 + case DNS_CLIENT_PORT: return DnsHandleResponse(pDataLength, pData); //53053 + case DNS_MULTICAST_SERVER_PORT: return DnsHandleRequest (DNS_TYPE_MDNS, pDataLength, pData); //5353 + case DNS_LLMNR_SERVER_PORT: return DnsHandleRequest (DNS_TYPE_LLMNR, pDataLength, pData); //5355 + + //Quietly drop these + case DHCP_SERVER_PORT: //67 + case 1900: //SSDP Simple Service Discovery Protocol (uPnP) + case 3076: //Call of Duty - Xbox + case 9997: //VLC + case 9998: //VLC + case 9999: //VLC + case 17500: //Dropbox LAN sync + return DO_NOTHING; + + //Report anything else + default: + if (UNKNOWN) LogTimeF("UDP unknown port %d\r\n", dstPort); + return DO_NOTHING; + } +} +int UdpHandleReceivedPacket(int* pSize, void* pPacket) +{ + void* pData = (char*)pPacket + HEADER_SIZE; + int dataLength = *pSize - HEADER_SIZE; + + int action = handlePort(&dataLength, pData); + + *pSize = dataLength + HEADER_SIZE; + + uint16_t tmpPort = dstPort; + dstPort = srcPort; + srcPort = tmpPort; + + return action; +} +static int pollForPacketToSend(int type, int* pDataLength, void* pData) +{ + int action = 0; + + if (!action && type == IPV4) //DHCP only works under IPv4 + { + action = DhcpPollForRequestToSend(pData, pDataLength); + if (action) + { + srcPort = DHCP_CLIENT_PORT; + dstPort = DHCP_SERVER_PORT; + } + } + + if (!action) //DNS is agnostic + { + action = DnsPollForRequestToSend(pData, pDataLength); + if (action) + { + srcPort = DNS_CLIENT_PORT; //53053 + switch (action) + { + case UNICAST_DNS: dstPort = DNS_UNICAST_SERVER_PORT; break; //53 + case MULTICAST_MDNS: dstPort = DNS_MULTICAST_SERVER_PORT; break; //5353 + case MULTICAST_LLMNR: dstPort = DNS_LLMNR_SERVER_PORT; break; //5355 + + //Report anything else + default: + LogTimeF("DNS unknown action %d\r\n", action); + return DO_NOTHING; + } + } + } + return action; +} +int UdpPollForPacketToSend(int type, int* pSize, void* pPacket) +{ + void* pData = (char*)pPacket + HEADER_SIZE; + int dataLength = *pSize - HEADER_SIZE; + + int action = pollForPacketToSend(type, &dataLength, pData); + + *pSize = dataLength + HEADER_SIZE; + return action; +} + +void UdpLogHeader(char* title, void* pPacket, uint16_t calculatedChecksum) +{ + LogTimeF("UDP %s\r\n", title); + LogF(" Source port %hu\r\n", srcPort); + LogF(" Destination port %hu\r\n", dstPort); + LogF(" Total length %hu\r\n", totalLength); + LogF(" Checksum (hex) %04hX\r\n", checksum); + LogF(" Calculated %04hX\r\n", calculatedChecksum); +} + +void UdpMakeHeader(int size, void* pPacket) +{ + struct header* pHeader = (header*)pPacket; + + pHeader->dstPort = NetToHost16(dstPort); + pHeader->srcPort = NetToHost16(srcPort); + pHeader->totalLength = NetToHost16(size); + pHeader->checksum = 0; + +} +void UdpAddChecksum(void* pPacket, uint16_t checksum) +{ + struct header* pHeader = (header*)pPacket; + pHeader->checksum = checksum; +} +void UdpReadHeader(void* pPacket, uint16_t size) +{ + struct header* pHeader = (header*)pPacket; + + srcPort = NetToHost16(pHeader->srcPort); + dstPort = NetToHost16(pHeader->dstPort); + totalLength = NetToHost16(pHeader->totalLength); + checksum = NetToHost16(pHeader->checksum); +} \ No newline at end of file