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

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