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
udp/udp.cpp
- Committer:
- andrewboyson
- Date:
- 2017-08-07
- Revision:
- 29:39277bf2003d
- Parent:
- 22:914b970356f0
- Child:
- 33:714a0345e59b
File content as of revision 29:39277bf2003d:
#include "mbed.h" #include "log.h" #include "net.h" #include "udp.h" #include "ntp.h" #include "dhcp.h" #include "dns.h" #include "eth.h" #include "ip4.h" #include "ip6.h" #include "slaac.h" #include "ns.h" #include "io.h" #define UNKNOWN true #define HEADER_SIZE 8 __packed struct header { uint16_t srcPort; uint16_t dstPort; uint16_t totalLength; uint16_t checksum; }; uint16_t UdpSrcPort; uint16_t UdpDstPort; static uint16_t checksum; static uint16_t totalLength; static int handlePort(int* pDataLength, void* pData) { switch (UdpDstPort) { //Handle these case DHCP_CLIENT_PORT: return DhcpHandleResponse ( pDataLength, pData); // 68 case NTP_PORT: return NtpHandlePacketReceived( pDataLength, pData); // 123 case DNS_UNICAST_CLIENT_PORT: return DnsHandlePacketReceived(DNS_PROTOCOL_UDNS, pDataLength, pData); //53053 case DNS_MDNS_PORT: return DnsHandlePacketReceived(DNS_PROTOCOL_MDNS, pDataLength, pData); // 5353 case DNS_LLMNR_CLIENT_PORT: return DnsHandlePacketReceived(DNS_PROTOCOL_LLMNR, pDataLength, pData); //53055 case DNS_LLMNR_SERVER_PORT: return DnsHandlePacketReceived(DNS_PROTOCOL_LLMNR, pDataLength, pData); // 5355 //Quietly drop these case DHCP_SERVER_PORT: //67 case 137: //NETBIOS name service case 138: //NETBIOS datagram service case 139: //NETBIOS session service case 1900: //SSDP Simple Service Discovery Protocol (uPnP) case 3076: //Call of Duty - Xbox case 9956: //Alljoyn part af Allseen IoT services 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", UdpDstPort); 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 = UdpDstPort; UdpDstPort = UdpSrcPort; UdpSrcPort = 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) { UdpSrcPort = DHCP_CLIENT_PORT; UdpDstPort = DHCP_SERVER_PORT; } } if (!action) //DNS is agnostic { action = DnsPollForPacketToSend(pData, pDataLength); if (action) { switch (action) { case UNICAST_DNS: UdpSrcPort = DNS_UNICAST_CLIENT_PORT; UdpDstPort = DNS_UNICAST_SERVER_PORT; break; //53053, 53 case MULTICAST_MDNS: UdpSrcPort = DNS_MDNS_PORT; UdpDstPort = DNS_MDNS_PORT; break; // 5353, 5353 case MULTICAST_LLMNR: UdpSrcPort = DNS_LLMNR_CLIENT_PORT; UdpDstPort = DNS_LLMNR_SERVER_PORT; break; //53055, 5355 //Report anything else default: LogTimeF("DNS unknown action %d\r\n", action); return DO_NOTHING; } } } if (!action) //NTP needs to choose depending of what address is specified { action = NtpPollForPacketToSend(type, pData, pDataLength); if (action) { UdpSrcPort = NTP_PORT; UdpDstPort = NTP_PORT; } } 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", UdpSrcPort); LogF(" Destination port %hu\r\n", UdpDstPort); 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(UdpDstPort); pHeader->srcPort = NetToHost16(UdpSrcPort); 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; UdpSrcPort = NetToHost16(pHeader->srcPort); UdpDstPort = NetToHost16(pHeader->dstPort); totalLength = NetToHost16(pHeader->totalLength); checksum = NetToHost16(pHeader->checksum); }