Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
udp/udp.c@151:bde6f7da1755, 2019-07-19 (annotated)
- Committer:
 - andrewboyson
 - Date:
 - Fri Jul 19 17:48:06 2019 +0000
 - Revision:
 - 151:bde6f7da1755
 - Parent:
 - 142:a8c0890a58d1
 - Child:
 - 171:f708d6776752
 
Removed private key and certificate from semihost storage as found to be unreliable (though secure) and moved it into flash storage (reliable, simple, but visible on mbed.
Who changed what in which revision?
| User | Revision | Line number | New 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 | 142:a8c0890a58d1 | 18 | #include "restart.h" | 
| andrewboyson | 10:f0854784e960 | 19 | |
| andrewboyson | 52:fbc5a46b5e16 | 20 | bool UdpTrace = true; | 
| andrewboyson | 10:f0854784e960 | 21 | |
| andrewboyson | 138:5ff0c7069300 | 22 | static char* hdrPtrSrcPort (char* pPacket) { return pPacket + 0; } //2 | 
| andrewboyson | 138:5ff0c7069300 | 23 | static char* hdrPtrDstPort (char* pPacket) { return pPacket + 2; } //2 | 
| andrewboyson | 138:5ff0c7069300 | 24 | static char* hdrPtrTotalLength(char* pPacket) { return pPacket + 4; } //2 | 
| andrewboyson | 138:5ff0c7069300 | 25 | static char* hdrPtrChecksum (char* pPacket) { return pPacket + 6; } //2 | 
| andrewboyson | 138:5ff0c7069300 | 26 | static const int HEADER_LENGTH = 8; | 
| andrewboyson | 138:5ff0c7069300 | 27 | |
| andrewboyson | 138:5ff0c7069300 | 28 | void UdpHdrSetChecksum(void* pPacket, uint16_t checksum) | 
| andrewboyson | 10:f0854784e960 | 29 | { | 
| andrewboyson | 138:5ff0c7069300 | 30 | NetDirect16(hdrPtrChecksum(pPacket), &checksum); | 
| andrewboyson | 138:5ff0c7069300 | 31 | } | 
| andrewboyson | 37:793b39683406 | 32 | static uint16_t srcPort; | 
| andrewboyson | 37:793b39683406 | 33 | static uint16_t dstPort; | 
| andrewboyson | 10:f0854784e960 | 34 | static uint16_t checksum; | 
| andrewboyson | 10:f0854784e960 | 35 | static uint16_t totalLength; | 
| andrewboyson | 10:f0854784e960 | 36 | |
| andrewboyson | 138:5ff0c7069300 | 37 | static void readHeader(char* pPacket) | 
| andrewboyson | 138:5ff0c7069300 | 38 | { | 
| andrewboyson | 138:5ff0c7069300 | 39 | NetInvert16(&srcPort, hdrPtrSrcPort (pPacket)); | 
| andrewboyson | 138:5ff0c7069300 | 40 | NetInvert16(&dstPort, hdrPtrDstPort (pPacket)); | 
| andrewboyson | 138:5ff0c7069300 | 41 | NetDirect16(&checksum, hdrPtrChecksum (pPacket)); | 
| andrewboyson | 138:5ff0c7069300 | 42 | NetInvert16(&totalLength, hdrPtrTotalLength(pPacket)); | 
| andrewboyson | 138:5ff0c7069300 | 43 | } | 
| andrewboyson | 138:5ff0c7069300 | 44 | void UdpMakeHeader(int size, char* pPacket) | 
| andrewboyson | 59:e0e556c8bd46 | 45 | { | 
| andrewboyson | 138:5ff0c7069300 | 46 | checksum = 0; | 
| andrewboyson | 138:5ff0c7069300 | 47 | NetInvert16(hdrPtrSrcPort (pPacket), &srcPort ); | 
| andrewboyson | 138:5ff0c7069300 | 48 | NetInvert16(hdrPtrDstPort (pPacket), &dstPort ); | 
| andrewboyson | 138:5ff0c7069300 | 49 | NetDirect16(hdrPtrChecksum (pPacket), &checksum ); | 
| andrewboyson | 138:5ff0c7069300 | 50 | NetInvert16(hdrPtrTotalLength(pPacket), &size ); | 
| andrewboyson | 138:5ff0c7069300 | 51 | |
| andrewboyson | 59:e0e556c8bd46 | 52 | } | 
| andrewboyson | 138:5ff0c7069300 | 53 | |
| andrewboyson | 138:5ff0c7069300 | 54 | void UdpLogHeader(uint16_t calculatedChecksum) | 
| andrewboyson | 138:5ff0c7069300 | 55 | { | 
| andrewboyson | 138:5ff0c7069300 | 56 | if (NetTraceVerbose) | 
| andrewboyson | 138:5ff0c7069300 | 57 | { | 
| andrewboyson | 138:5ff0c7069300 | 58 | Log ("UDP header\r\n"); | 
| andrewboyson | 138:5ff0c7069300 | 59 | LogF(" Source port %hu\r\n", srcPort); | 
| andrewboyson | 138:5ff0c7069300 | 60 | LogF(" Destination port %hu\r\n", dstPort); | 
| andrewboyson | 138:5ff0c7069300 | 61 | LogF(" Total length %hu\r\n", totalLength); | 
| andrewboyson | 138:5ff0c7069300 | 62 | LogF(" Checksum (hex) %04hX\r\n", checksum); | 
| andrewboyson | 138:5ff0c7069300 | 63 | LogF(" Calculated %04hX\r\n", calculatedChecksum); | 
| andrewboyson | 138:5ff0c7069300 | 64 | } | 
| andrewboyson | 138:5ff0c7069300 | 65 | else | 
| andrewboyson | 138:5ff0c7069300 | 66 | { | 
| andrewboyson | 138:5ff0c7069300 | 67 | LogF("UDP header %hu >>> %hu\r\n", srcPort, dstPort); | 
| andrewboyson | 138:5ff0c7069300 | 68 | } | 
| andrewboyson | 138:5ff0c7069300 | 69 | } | 
| andrewboyson | 138:5ff0c7069300 | 70 | |
| andrewboyson | 138:5ff0c7069300 | 71 | static int handlePort(void (*traceback)(void), int dataLengthRx, char* pDataRx, int* pPataLengthTx, char* pDataTx) | 
| andrewboyson | 10:f0854784e960 | 72 | { | 
| andrewboyson | 37:793b39683406 | 73 | switch (dstPort) | 
| andrewboyson | 10:f0854784e960 | 74 | { | 
| andrewboyson | 10:f0854784e960 | 75 | //Handle these | 
| andrewboyson | 59:e0e556c8bd46 | 76 | case DHCP_CLIENT_PORT: return DhcpHandleResponse (traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 68 | 
| andrewboyson | 59:e0e556c8bd46 | 77 | case NTP_PORT: return NtpHandlePacketReceived(traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 123 | 
| andrewboyson | 59:e0e556c8bd46 | 78 | case DNS_UNICAST_CLIENT_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_UDNS, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); //53053 | 
| andrewboyson | 59:e0e556c8bd46 | 79 | case DNS_MDNS_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_MDNS, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 5353 | 
| andrewboyson | 59:e0e556c8bd46 | 80 | case DNS_LLMNR_CLIENT_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_LLMNR, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); //53055 | 
| andrewboyson | 59:e0e556c8bd46 | 81 | case DNS_LLMNR_SERVER_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_LLMNR, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 5355 | 
| andrewboyson | 59:e0e556c8bd46 | 82 | case TFTP_CLIENT_PORT: return TftpHandlePacketReceived(traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); //60690 | 
| andrewboyson | 10:f0854784e960 | 83 | |
| andrewboyson | 10:f0854784e960 | 84 | //Quietly drop these | 
| andrewboyson | 42:222a4f45f916 | 85 | case DHCP_SERVER_PORT: //67 | 
| andrewboyson | 57:e0fb648acf48 | 86 | case TFTP_SERVER_PORT: //69 | 
| andrewboyson | 42:222a4f45f916 | 87 | case 137: //NETBIOS name service | 
| andrewboyson | 42:222a4f45f916 | 88 | case 138: //NETBIOS datagram service | 
| andrewboyson | 42:222a4f45f916 | 89 | case 139: //NETBIOS session service | 
| andrewboyson | 42:222a4f45f916 | 90 | case 500: //Key exchange - Xbox live | 
| andrewboyson | 42:222a4f45f916 | 91 | case 1900: //SSDP Simple Service Discovery Protocol (uPnP) | 
| andrewboyson | 42:222a4f45f916 | 92 | case 3074: //Xbox live | 
| andrewboyson | 42:222a4f45f916 | 93 | case 3076: //Call of Duty - Xbox | 
| andrewboyson | 52:fbc5a46b5e16 | 94 | case 5050: //Don't know but have been sent by Kate and my android phones. | 
| andrewboyson | 42:222a4f45f916 | 95 | 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 | 96 | case 9956: //Alljoyn part of Allseen IoT services | 
| andrewboyson | 42:222a4f45f916 | 97 | case 9997: //VLC | 
| andrewboyson | 42:222a4f45f916 | 98 | case 9998: //VLC | 
| andrewboyson | 42:222a4f45f916 | 99 | case 9999: //VLC | 
| andrewboyson | 42:222a4f45f916 | 100 | case 17500: //Dropbox LAN sync | 
| andrewboyson | 95:b9a99049016a | 101 | case 57621: //Spotify P2P | 
| andrewboyson | 10:f0854784e960 | 102 | return DO_NOTHING; | 
| andrewboyson | 10:f0854784e960 | 103 | |
| andrewboyson | 10:f0854784e960 | 104 | //Report anything else | 
| andrewboyson | 10:f0854784e960 | 105 | default: | 
| andrewboyson | 52:fbc5a46b5e16 | 106 | if (UdpTrace) | 
| andrewboyson | 52:fbc5a46b5e16 | 107 | { | 
| andrewboyson | 52:fbc5a46b5e16 | 108 | LogTimeF("UDP unknown port %d\r\n", dstPort); | 
| andrewboyson | 52:fbc5a46b5e16 | 109 | traceback(); //This will already include the UDP header | 
| andrewboyson | 52:fbc5a46b5e16 | 110 | } | 
| andrewboyson | 10:f0854784e960 | 111 | return DO_NOTHING; | 
| andrewboyson | 10:f0854784e960 | 112 | } | 
| andrewboyson | 10:f0854784e960 | 113 | } | 
| andrewboyson | 138:5ff0c7069300 | 114 | int UdpHandleReceivedPacket(void (*traceback)(void), int sizeRx, char* pPacketRx, int* pSizeTx, char* pPacketTx) | 
| andrewboyson | 10:f0854784e960 | 115 | { | 
| andrewboyson | 142:a8c0890a58d1 | 116 | int lastRestartPoint = RestartPoint; | 
| andrewboyson | 142:a8c0890a58d1 | 117 | RestartPoint = FAULT_POINT_UdpHandleReceivedPacket; | 
| andrewboyson | 121:bc048b65a630 | 118 | |
| andrewboyson | 138:5ff0c7069300 | 119 | readHeader(pPacketRx); | 
| andrewboyson | 59:e0e556c8bd46 | 120 | |
| andrewboyson | 138:5ff0c7069300 | 121 | void* pDataRx = pPacketRx + HEADER_LENGTH; | 
| andrewboyson | 138:5ff0c7069300 | 122 | void* pDataTx = pPacketTx + HEADER_LENGTH; | 
| andrewboyson | 138:5ff0c7069300 | 123 | int dataLengthRx = sizeRx - HEADER_LENGTH; | 
| andrewboyson | 138:5ff0c7069300 | 124 | int dataLengthTx = *pSizeTx - HEADER_LENGTH; | 
| andrewboyson | 10:f0854784e960 | 125 | |
| andrewboyson | 59:e0e556c8bd46 | 126 | int action = handlePort(traceback, dataLengthRx, pDataRx, &dataLengthTx, pDataTx); | 
| andrewboyson | 10:f0854784e960 | 127 | |
| andrewboyson | 138:5ff0c7069300 | 128 | *pSizeTx = dataLengthTx + HEADER_LENGTH; | 
| andrewboyson | 10:f0854784e960 | 129 | |
| andrewboyson | 37:793b39683406 | 130 | uint16_t tmpPort = dstPort; | 
| andrewboyson | 37:793b39683406 | 131 | dstPort = srcPort; | 
| andrewboyson | 37:793b39683406 | 132 | srcPort = tmpPort; | 
| andrewboyson | 10:f0854784e960 | 133 | |
| andrewboyson | 142:a8c0890a58d1 | 134 | RestartPoint = lastRestartPoint; | 
| andrewboyson | 10:f0854784e960 | 135 | return action; | 
| andrewboyson | 10:f0854784e960 | 136 | } | 
| andrewboyson | 138:5ff0c7069300 | 137 | static int pollForPacketToSend(int type, int* pDataLength, char* pData) | 
| andrewboyson | 10:f0854784e960 | 138 | { | 
| andrewboyson | 37:793b39683406 | 139 | int action = DO_NOTHING; | 
| andrewboyson | 10:f0854784e960 | 140 | |
| andrewboyson | 10:f0854784e960 | 141 | if (!action && type == IPV4) //DHCP only works under IPv4 | 
| andrewboyson | 10:f0854784e960 | 142 | { | 
| andrewboyson | 10:f0854784e960 | 143 | action = DhcpPollForRequestToSend(pData, pDataLength); | 
| andrewboyson | 10:f0854784e960 | 144 | if (action) | 
| andrewboyson | 10:f0854784e960 | 145 | { | 
| andrewboyson | 37:793b39683406 | 146 | srcPort = DHCP_CLIENT_PORT; | 
| andrewboyson | 37:793b39683406 | 147 | dstPort = DHCP_SERVER_PORT; | 
| andrewboyson | 10:f0854784e960 | 148 | } | 
| andrewboyson | 10:f0854784e960 | 149 | } | 
| andrewboyson | 10:f0854784e960 | 150 | |
| andrewboyson | 83:08c983006a6e | 151 | if (!action && type == (DnsSendRequestsViaIp4 ? IPV4 : IPV6)) //DNS is agnostic | 
| andrewboyson | 10:f0854784e960 | 152 | { | 
| andrewboyson | 13:9cd54f7db57a | 153 | action = DnsPollForPacketToSend(pData, pDataLength); | 
| andrewboyson | 37:793b39683406 | 154 | int dest = ActionGetDestPart(action); | 
| andrewboyson | 37:793b39683406 | 155 | if (dest) | 
| andrewboyson | 10:f0854784e960 | 156 | { | 
| andrewboyson | 37:793b39683406 | 157 | switch (dest) | 
| andrewboyson | 10:f0854784e960 | 158 | { | 
| andrewboyson | 37:793b39683406 | 159 | case UNICAST_DNS: srcPort = DNS_UNICAST_CLIENT_PORT; dstPort = DNS_UNICAST_SERVER_PORT; break; //53053, 53 | 
| andrewboyson | 37:793b39683406 | 160 | case MULTICAST_MDNS: srcPort = DNS_MDNS_PORT; dstPort = DNS_MDNS_PORT; break; // 5353, 5353 | 
| andrewboyson | 37:793b39683406 | 161 | case MULTICAST_LLMNR: srcPort = DNS_LLMNR_CLIENT_PORT; dstPort = DNS_LLMNR_SERVER_PORT; break; //53055, 5355 | 
| andrewboyson | 10:f0854784e960 | 162 | |
| andrewboyson | 10:f0854784e960 | 163 | //Report anything else | 
| andrewboyson | 10:f0854784e960 | 164 | default: | 
| andrewboyson | 37:793b39683406 | 165 | LogTimeF("DNS unknown dest %d\r\n", dest); | 
| andrewboyson | 10:f0854784e960 | 166 | return DO_NOTHING; | 
| andrewboyson | 10:f0854784e960 | 167 | } | 
| andrewboyson | 10:f0854784e960 | 168 | } | 
| andrewboyson | 10:f0854784e960 | 169 | } | 
| andrewboyson | 113:904b40231907 | 170 | if (!action && type == (NtpClientQuerySendRequestsViaIp4 ? IPV4 : IPV6)) //NTP is agnostic | 
| andrewboyson | 22:914b970356f0 | 171 | { | 
| andrewboyson | 22:914b970356f0 | 172 | action = NtpPollForPacketToSend(type, pData, pDataLength); | 
| andrewboyson | 22:914b970356f0 | 173 | if (action) | 
| andrewboyson | 22:914b970356f0 | 174 | { | 
| andrewboyson | 37:793b39683406 | 175 | srcPort = NTP_PORT; | 
| andrewboyson | 37:793b39683406 | 176 | dstPort = NTP_PORT; | 
| andrewboyson | 22:914b970356f0 | 177 | } | 
| andrewboyson | 22:914b970356f0 | 178 | } | 
| andrewboyson | 83:08c983006a6e | 179 | if (!action && type == (TftpSendRequestsViaIp4 ? IPV4 : IPV6)) //TFTP is agnostic | 
| andrewboyson | 57:e0fb648acf48 | 180 | { | 
| andrewboyson | 57:e0fb648acf48 | 181 | action = TftpPollForPacketToSend(type, pData, pDataLength); | 
| andrewboyson | 57:e0fb648acf48 | 182 | if (action) | 
| andrewboyson | 57:e0fb648acf48 | 183 | { | 
| andrewboyson | 57:e0fb648acf48 | 184 | srcPort = TFTP_CLIENT_PORT; | 
| andrewboyson | 57:e0fb648acf48 | 185 | dstPort = TFTP_SERVER_PORT; | 
| andrewboyson | 57:e0fb648acf48 | 186 | } | 
| andrewboyson | 57:e0fb648acf48 | 187 | } | 
| andrewboyson | 37:793b39683406 | 188 | |
| andrewboyson | 10:f0854784e960 | 189 | return action; | 
| andrewboyson | 10:f0854784e960 | 190 | } | 
| andrewboyson | 138:5ff0c7069300 | 191 | int UdpPollForPacketToSend(int type, int* pSize, char* pPacket) | 
| andrewboyson | 10:f0854784e960 | 192 | { | 
| andrewboyson | 138:5ff0c7069300 | 193 | void* pData = pPacket + HEADER_LENGTH; | 
| andrewboyson | 138:5ff0c7069300 | 194 | int dataLength = *pSize - HEADER_LENGTH; | 
| andrewboyson | 10:f0854784e960 | 195 | |
| andrewboyson | 10:f0854784e960 | 196 | int action = pollForPacketToSend(type, &dataLength, pData); | 
| andrewboyson | 10:f0854784e960 | 197 | |
| andrewboyson | 138:5ff0c7069300 | 198 | *pSize = dataLength + HEADER_LENGTH; | 
| andrewboyson | 10:f0854784e960 | 199 | return action; | 
| andrewboyson | 10:f0854784e960 | 200 | } |