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

Committer:
andrewboyson
Date:
Fri Feb 22 11:26:55 2019 +0000
Revision:
125:8c84daac38ab
Parent:
121:bc048b65a630
Child:
138:5ff0c7069300
tidied up ntp data types for calculating ms from clktime.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 61:aad055f1b0d1 1 #include <stdint.h>
andrewboyson 61:aad055f1b0d1 2 #include <stdbool.h>
andrewboyson 61:aad055f1b0d1 3
andrewboyson 121:bc048b65a630 4 #include "log.h"
andrewboyson 121:bc048b65a630 5 #include "net.h"
andrewboyson 37:793b39683406 6 #include "action.h"
andrewboyson 121:bc048b65a630 7 #include "udp.h"
andrewboyson 121:bc048b65a630 8 #include "ntp.h"
andrewboyson 121:bc048b65a630 9 #include "tftp.h"
andrewboyson 121:bc048b65a630 10 #include "dhcp.h"
andrewboyson 121:bc048b65a630 11 #include "dns.h"
andrewboyson 121:bc048b65a630 12 #include "eth.h"
andrewboyson 121:bc048b65a630 13 #include "ip4.h"
andrewboyson 121:bc048b65a630 14 #include "ip6.h"
andrewboyson 121:bc048b65a630 15 #include "slaac.h"
andrewboyson 121:bc048b65a630 16 #include "ns.h"
andrewboyson 112:f8694d0b8858 17 #include "ntpclient.h"
andrewboyson 121:bc048b65a630 18 #include "fault.h"
andrewboyson 10:f0854784e960 19
andrewboyson 52:fbc5a46b5e16 20 bool UdpTrace = true;
andrewboyson 10:f0854784e960 21
andrewboyson 10:f0854784e960 22 __packed struct header
andrewboyson 10:f0854784e960 23 {
andrewboyson 10:f0854784e960 24 uint16_t srcPort;
andrewboyson 10:f0854784e960 25 uint16_t dstPort;
andrewboyson 10:f0854784e960 26 uint16_t totalLength;
andrewboyson 10:f0854784e960 27 uint16_t checksum;
andrewboyson 10:f0854784e960 28 };
andrewboyson 37:793b39683406 29 static uint16_t srcPort;
andrewboyson 37:793b39683406 30 static uint16_t dstPort;
andrewboyson 10:f0854784e960 31 static uint16_t checksum;
andrewboyson 10:f0854784e960 32 static uint16_t totalLength;
andrewboyson 10:f0854784e960 33
andrewboyson 59:e0e556c8bd46 34 static void readHeader(void* pPacket, uint16_t size)
andrewboyson 59:e0e556c8bd46 35 {
andrewboyson 61:aad055f1b0d1 36 struct header* pHeader = (struct header*)pPacket;
andrewboyson 59:e0e556c8bd46 37
andrewboyson 59:e0e556c8bd46 38 srcPort = NetToHost16(pHeader->srcPort);
andrewboyson 59:e0e556c8bd46 39 dstPort = NetToHost16(pHeader->dstPort);
andrewboyson 59:e0e556c8bd46 40 totalLength = NetToHost16(pHeader->totalLength);
andrewboyson 59:e0e556c8bd46 41 checksum = NetToHost16(pHeader->checksum);
andrewboyson 59:e0e556c8bd46 42 }
andrewboyson 59:e0e556c8bd46 43 static int handlePort(void (*traceback)(void), int dataLengthRx, void* pDataRx, int* pPataLengthTx, void* pDataTx)
andrewboyson 10:f0854784e960 44 {
andrewboyson 37:793b39683406 45 switch (dstPort)
andrewboyson 10:f0854784e960 46 {
andrewboyson 10:f0854784e960 47 //Handle these
andrewboyson 59:e0e556c8bd46 48 case DHCP_CLIENT_PORT: return DhcpHandleResponse (traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 68
andrewboyson 59:e0e556c8bd46 49 case NTP_PORT: return NtpHandlePacketReceived(traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 123
andrewboyson 59:e0e556c8bd46 50 case DNS_UNICAST_CLIENT_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_UDNS, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); //53053
andrewboyson 59:e0e556c8bd46 51 case DNS_MDNS_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_MDNS, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 5353
andrewboyson 59:e0e556c8bd46 52 case DNS_LLMNR_CLIENT_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_LLMNR, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); //53055
andrewboyson 59:e0e556c8bd46 53 case DNS_LLMNR_SERVER_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_LLMNR, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 5355
andrewboyson 59:e0e556c8bd46 54 case TFTP_CLIENT_PORT: return TftpHandlePacketReceived(traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); //60690
andrewboyson 10:f0854784e960 55
andrewboyson 10:f0854784e960 56 //Quietly drop these
andrewboyson 42:222a4f45f916 57 case DHCP_SERVER_PORT: //67
andrewboyson 57:e0fb648acf48 58 case TFTP_SERVER_PORT: //69
andrewboyson 42:222a4f45f916 59 case 137: //NETBIOS name service
andrewboyson 42:222a4f45f916 60 case 138: //NETBIOS datagram service
andrewboyson 42:222a4f45f916 61 case 139: //NETBIOS session service
andrewboyson 42:222a4f45f916 62 case 500: //Key exchange - Xbox live
andrewboyson 42:222a4f45f916 63 case 1900: //SSDP Simple Service Discovery Protocol (uPnP)
andrewboyson 42:222a4f45f916 64 case 3074: //Xbox live
andrewboyson 42:222a4f45f916 65 case 3076: //Call of Duty - Xbox
andrewboyson 52:fbc5a46b5e16 66 case 5050: //Don't know but have been sent by Kate and my android phones.
andrewboyson 42:222a4f45f916 67 case 5224: //Don't know but a burst was broadcast by Kate's phone containing '_logitech-reverse-bonjour._tcp.local.5446 192.168.1.36 string'
andrewboyson 52:fbc5a46b5e16 68 case 9956: //Alljoyn part of Allseen IoT services
andrewboyson 42:222a4f45f916 69 case 9997: //VLC
andrewboyson 42:222a4f45f916 70 case 9998: //VLC
andrewboyson 42:222a4f45f916 71 case 9999: //VLC
andrewboyson 42:222a4f45f916 72 case 17500: //Dropbox LAN sync
andrewboyson 95:b9a99049016a 73 case 57621: //Spotify P2P
andrewboyson 10:f0854784e960 74 return DO_NOTHING;
andrewboyson 10:f0854784e960 75
andrewboyson 10:f0854784e960 76 //Report anything else
andrewboyson 10:f0854784e960 77 default:
andrewboyson 52:fbc5a46b5e16 78 if (UdpTrace)
andrewboyson 52:fbc5a46b5e16 79 {
andrewboyson 52:fbc5a46b5e16 80 LogTimeF("UDP unknown port %d\r\n", dstPort);
andrewboyson 52:fbc5a46b5e16 81 traceback(); //This will already include the UDP header
andrewboyson 52:fbc5a46b5e16 82 }
andrewboyson 10:f0854784e960 83 return DO_NOTHING;
andrewboyson 10:f0854784e960 84 }
andrewboyson 10:f0854784e960 85 }
andrewboyson 59:e0e556c8bd46 86 int UdpHandleReceivedPacket(void (*traceback)(void), int sizeRx, void* pPacketRx, int* pSizeTx, void* pPacketTx)
andrewboyson 10:f0854784e960 87 {
andrewboyson 121:bc048b65a630 88 int lastFaultPoint = FaultPoint;
andrewboyson 121:bc048b65a630 89 FaultPoint = FAULT_POINT_UdpHandleReceivedPacket;
andrewboyson 121:bc048b65a630 90
andrewboyson 59:e0e556c8bd46 91 readHeader(pPacketRx, sizeRx);
andrewboyson 59:e0e556c8bd46 92
andrewboyson 61:aad055f1b0d1 93 void* pDataRx = (char*)pPacketRx + sizeof(struct header);
andrewboyson 61:aad055f1b0d1 94 void* pDataTx = (char*)pPacketTx + sizeof(struct header);
andrewboyson 61:aad055f1b0d1 95 int dataLengthRx = sizeRx - sizeof(struct header);
andrewboyson 61:aad055f1b0d1 96 int dataLengthTx = *pSizeTx - sizeof(struct header);
andrewboyson 10:f0854784e960 97
andrewboyson 59:e0e556c8bd46 98 int action = handlePort(traceback, dataLengthRx, pDataRx, &dataLengthTx, pDataTx);
andrewboyson 10:f0854784e960 99
andrewboyson 61:aad055f1b0d1 100 *pSizeTx = dataLengthTx + sizeof(struct header);
andrewboyson 10:f0854784e960 101
andrewboyson 37:793b39683406 102 uint16_t tmpPort = dstPort;
andrewboyson 37:793b39683406 103 dstPort = srcPort;
andrewboyson 37:793b39683406 104 srcPort = tmpPort;
andrewboyson 10:f0854784e960 105
andrewboyson 121:bc048b65a630 106 FaultPoint = lastFaultPoint;
andrewboyson 10:f0854784e960 107 return action;
andrewboyson 10:f0854784e960 108 }
andrewboyson 10:f0854784e960 109 static int pollForPacketToSend(int type, int* pDataLength, void* pData)
andrewboyson 10:f0854784e960 110 {
andrewboyson 37:793b39683406 111 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 112
andrewboyson 10:f0854784e960 113 if (!action && type == IPV4) //DHCP only works under IPv4
andrewboyson 10:f0854784e960 114 {
andrewboyson 10:f0854784e960 115 action = DhcpPollForRequestToSend(pData, pDataLength);
andrewboyson 10:f0854784e960 116 if (action)
andrewboyson 10:f0854784e960 117 {
andrewboyson 37:793b39683406 118 srcPort = DHCP_CLIENT_PORT;
andrewboyson 37:793b39683406 119 dstPort = DHCP_SERVER_PORT;
andrewboyson 10:f0854784e960 120 }
andrewboyson 10:f0854784e960 121 }
andrewboyson 10:f0854784e960 122
andrewboyson 83:08c983006a6e 123 if (!action && type == (DnsSendRequestsViaIp4 ? IPV4 : IPV6)) //DNS is agnostic
andrewboyson 10:f0854784e960 124 {
andrewboyson 13:9cd54f7db57a 125 action = DnsPollForPacketToSend(pData, pDataLength);
andrewboyson 37:793b39683406 126 int dest = ActionGetDestPart(action);
andrewboyson 37:793b39683406 127 if (dest)
andrewboyson 10:f0854784e960 128 {
andrewboyson 37:793b39683406 129 switch (dest)
andrewboyson 10:f0854784e960 130 {
andrewboyson 37:793b39683406 131 case UNICAST_DNS: srcPort = DNS_UNICAST_CLIENT_PORT; dstPort = DNS_UNICAST_SERVER_PORT; break; //53053, 53
andrewboyson 37:793b39683406 132 case MULTICAST_MDNS: srcPort = DNS_MDNS_PORT; dstPort = DNS_MDNS_PORT; break; // 5353, 5353
andrewboyson 37:793b39683406 133 case MULTICAST_LLMNR: srcPort = DNS_LLMNR_CLIENT_PORT; dstPort = DNS_LLMNR_SERVER_PORT; break; //53055, 5355
andrewboyson 10:f0854784e960 134
andrewboyson 10:f0854784e960 135 //Report anything else
andrewboyson 10:f0854784e960 136 default:
andrewboyson 37:793b39683406 137 LogTimeF("DNS unknown dest %d\r\n", dest);
andrewboyson 10:f0854784e960 138 return DO_NOTHING;
andrewboyson 10:f0854784e960 139 }
andrewboyson 10:f0854784e960 140 }
andrewboyson 10:f0854784e960 141 }
andrewboyson 113:904b40231907 142 if (!action && type == (NtpClientQuerySendRequestsViaIp4 ? IPV4 : IPV6)) //NTP is agnostic
andrewboyson 22:914b970356f0 143 {
andrewboyson 22:914b970356f0 144 action = NtpPollForPacketToSend(type, pData, pDataLength);
andrewboyson 22:914b970356f0 145 if (action)
andrewboyson 22:914b970356f0 146 {
andrewboyson 37:793b39683406 147 srcPort = NTP_PORT;
andrewboyson 37:793b39683406 148 dstPort = NTP_PORT;
andrewboyson 22:914b970356f0 149 }
andrewboyson 22:914b970356f0 150 }
andrewboyson 83:08c983006a6e 151 if (!action && type == (TftpSendRequestsViaIp4 ? IPV4 : IPV6)) //TFTP is agnostic
andrewboyson 57:e0fb648acf48 152 {
andrewboyson 57:e0fb648acf48 153 action = TftpPollForPacketToSend(type, pData, pDataLength);
andrewboyson 57:e0fb648acf48 154 if (action)
andrewboyson 57:e0fb648acf48 155 {
andrewboyson 57:e0fb648acf48 156 srcPort = TFTP_CLIENT_PORT;
andrewboyson 57:e0fb648acf48 157 dstPort = TFTP_SERVER_PORT;
andrewboyson 57:e0fb648acf48 158 }
andrewboyson 57:e0fb648acf48 159 }
andrewboyson 37:793b39683406 160
andrewboyson 10:f0854784e960 161 return action;
andrewboyson 10:f0854784e960 162 }
andrewboyson 10:f0854784e960 163 int UdpPollForPacketToSend(int type, int* pSize, void* pPacket)
andrewboyson 10:f0854784e960 164 {
andrewboyson 61:aad055f1b0d1 165 void* pData = (char*)pPacket + sizeof(struct header);
andrewboyson 61:aad055f1b0d1 166 int dataLength = *pSize - sizeof(struct header);
andrewboyson 10:f0854784e960 167
andrewboyson 10:f0854784e960 168 int action = pollForPacketToSend(type, &dataLength, pData);
andrewboyson 10:f0854784e960 169
andrewboyson 61:aad055f1b0d1 170 *pSize = dataLength + sizeof(struct header);
andrewboyson 10:f0854784e960 171 return action;
andrewboyson 10:f0854784e960 172 }
andrewboyson 10:f0854784e960 173
andrewboyson 37:793b39683406 174 void UdpLogHeader(uint16_t calculatedChecksum)
andrewboyson 43:bc028d5a6424 175 {
andrewboyson 43:bc028d5a6424 176 if (NetTraceVerbose)
andrewboyson 43:bc028d5a6424 177 {
andrewboyson 43:bc028d5a6424 178 Log ("UDP header\r\n");
andrewboyson 43:bc028d5a6424 179 LogF(" Source port %hu\r\n", srcPort);
andrewboyson 43:bc028d5a6424 180 LogF(" Destination port %hu\r\n", dstPort);
andrewboyson 43:bc028d5a6424 181 LogF(" Total length %hu\r\n", totalLength);
andrewboyson 43:bc028d5a6424 182 LogF(" Checksum (hex) %04hX\r\n", checksum);
andrewboyson 43:bc028d5a6424 183 LogF(" Calculated %04hX\r\n", calculatedChecksum);
andrewboyson 43:bc028d5a6424 184 }
andrewboyson 43:bc028d5a6424 185 else
andrewboyson 43:bc028d5a6424 186 {
andrewboyson 44:83ce5ace337b 187 LogF("UDP header %hu >>> %hu\r\n", srcPort, dstPort);
andrewboyson 43:bc028d5a6424 188 }
andrewboyson 10:f0854784e960 189 }
andrewboyson 10:f0854784e960 190
andrewboyson 10:f0854784e960 191 void UdpMakeHeader(int size, void* pPacket)
andrewboyson 10:f0854784e960 192 {
andrewboyson 61:aad055f1b0d1 193 struct header* pHeader = (struct header*)pPacket;
andrewboyson 10:f0854784e960 194
andrewboyson 37:793b39683406 195 pHeader->dstPort = NetToHost16(dstPort);
andrewboyson 37:793b39683406 196 pHeader->srcPort = NetToHost16(srcPort);
andrewboyson 10:f0854784e960 197 pHeader->totalLength = NetToHost16(size);
andrewboyson 10:f0854784e960 198 pHeader->checksum = 0;
andrewboyson 10:f0854784e960 199
andrewboyson 10:f0854784e960 200 }
andrewboyson 10:f0854784e960 201 void UdpAddChecksum(void* pPacket, uint16_t checksum)
andrewboyson 10:f0854784e960 202 {
andrewboyson 61:aad055f1b0d1 203 struct header* pHeader = (struct header*)pPacket;
andrewboyson 10:f0854784e960 204 pHeader->checksum = checksum;
andrewboyson 10:f0854784e960 205 }