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:
Thu May 20 14:32:52 2021 +0000
Revision:
200:5acbc41bf469
Parent:
198:71e298f63bf0
Increased number of arp entries from 20 to 30 to accommodate the number of WIZ devices plus a few incoming port 80 calls from the internet.

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 142:a8c0890a58d1 18 #include "restart.h"
andrewboyson 195:bd5b123143ca 19 #include "user.h"
andrewboyson 10:f0854784e960 20
andrewboyson 52:fbc5a46b5e16 21 bool UdpTrace = true;
andrewboyson 10:f0854784e960 22
andrewboyson 138:5ff0c7069300 23 static char* hdrPtrSrcPort (char* pPacket) { return pPacket + 0; } //2
andrewboyson 138:5ff0c7069300 24 static char* hdrPtrDstPort (char* pPacket) { return pPacket + 2; } //2
andrewboyson 138:5ff0c7069300 25 static char* hdrPtrTotalLength(char* pPacket) { return pPacket + 4; } //2
andrewboyson 138:5ff0c7069300 26 static char* hdrPtrChecksum (char* pPacket) { return pPacket + 6; } //2
andrewboyson 138:5ff0c7069300 27 static const int HEADER_LENGTH = 8;
andrewboyson 138:5ff0c7069300 28
andrewboyson 138:5ff0c7069300 29 void UdpHdrSetChecksum(void* pPacket, uint16_t checksum)
andrewboyson 10:f0854784e960 30 {
andrewboyson 138:5ff0c7069300 31 NetDirect16(hdrPtrChecksum(pPacket), &checksum);
andrewboyson 138:5ff0c7069300 32 }
andrewboyson 37:793b39683406 33 static uint16_t srcPort;
andrewboyson 37:793b39683406 34 static uint16_t dstPort;
andrewboyson 10:f0854784e960 35 static uint16_t checksum;
andrewboyson 10:f0854784e960 36 static uint16_t totalLength;
andrewboyson 10:f0854784e960 37
andrewboyson 138:5ff0c7069300 38 static void readHeader(char* pPacket)
andrewboyson 138:5ff0c7069300 39 {
andrewboyson 138:5ff0c7069300 40 NetInvert16(&srcPort, hdrPtrSrcPort (pPacket));
andrewboyson 138:5ff0c7069300 41 NetInvert16(&dstPort, hdrPtrDstPort (pPacket));
andrewboyson 138:5ff0c7069300 42 NetDirect16(&checksum, hdrPtrChecksum (pPacket));
andrewboyson 138:5ff0c7069300 43 NetInvert16(&totalLength, hdrPtrTotalLength(pPacket));
andrewboyson 138:5ff0c7069300 44 }
andrewboyson 138:5ff0c7069300 45 void UdpMakeHeader(int size, char* pPacket)
andrewboyson 59:e0e556c8bd46 46 {
andrewboyson 138:5ff0c7069300 47 checksum = 0;
andrewboyson 138:5ff0c7069300 48 NetInvert16(hdrPtrSrcPort (pPacket), &srcPort );
andrewboyson 138:5ff0c7069300 49 NetInvert16(hdrPtrDstPort (pPacket), &dstPort );
andrewboyson 138:5ff0c7069300 50 NetDirect16(hdrPtrChecksum (pPacket), &checksum );
andrewboyson 138:5ff0c7069300 51 NetInvert16(hdrPtrTotalLength(pPacket), &size );
andrewboyson 138:5ff0c7069300 52
andrewboyson 59:e0e556c8bd46 53 }
andrewboyson 138:5ff0c7069300 54
andrewboyson 138:5ff0c7069300 55 void UdpLogHeader(uint16_t calculatedChecksum)
andrewboyson 138:5ff0c7069300 56 {
andrewboyson 138:5ff0c7069300 57 if (NetTraceVerbose)
andrewboyson 138:5ff0c7069300 58 {
andrewboyson 138:5ff0c7069300 59 Log ("UDP header\r\n");
andrewboyson 138:5ff0c7069300 60 LogF(" Source port %hu\r\n", srcPort);
andrewboyson 138:5ff0c7069300 61 LogF(" Destination port %hu\r\n", dstPort);
andrewboyson 138:5ff0c7069300 62 LogF(" Total length %hu\r\n", totalLength);
andrewboyson 138:5ff0c7069300 63 LogF(" Checksum (hex) %04hX\r\n", checksum);
andrewboyson 138:5ff0c7069300 64 LogF(" Calculated %04hX\r\n", calculatedChecksum);
andrewboyson 138:5ff0c7069300 65 }
andrewboyson 138:5ff0c7069300 66 else
andrewboyson 138:5ff0c7069300 67 {
andrewboyson 138:5ff0c7069300 68 LogF("UDP header %hu >>> %hu\r\n", srcPort, dstPort);
andrewboyson 138:5ff0c7069300 69 }
andrewboyson 138:5ff0c7069300 70 }
andrewboyson 138:5ff0c7069300 71
andrewboyson 138:5ff0c7069300 72 static int handlePort(void (*traceback)(void), int dataLengthRx, char* pDataRx, int* pPataLengthTx, char* pDataTx)
andrewboyson 10:f0854784e960 73 {
andrewboyson 195:bd5b123143ca 74 if (UserHandleReceivedUdpPacket && (dstPort == UserUdpPort1 || dstPort == UserUdpPort2)) return UserHandleReceivedUdpPacket(dstPort, traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx);
andrewboyson 195:bd5b123143ca 75
andrewboyson 37:793b39683406 76 switch (dstPort)
andrewboyson 10:f0854784e960 77 {
andrewboyson 10:f0854784e960 78 //Handle these
andrewboyson 59:e0e556c8bd46 79 case DHCP_CLIENT_PORT: return DhcpHandleResponse (traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 68
andrewboyson 59:e0e556c8bd46 80 case NTP_PORT: return NtpHandlePacketReceived(traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 123
andrewboyson 59:e0e556c8bd46 81 case DNS_UNICAST_CLIENT_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_UDNS, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); //53053
andrewboyson 59:e0e556c8bd46 82 case DNS_MDNS_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_MDNS, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 5353
andrewboyson 59:e0e556c8bd46 83 case DNS_LLMNR_CLIENT_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_LLMNR, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); //53055
andrewboyson 59:e0e556c8bd46 84 case DNS_LLMNR_SERVER_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_LLMNR, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 5355
andrewboyson 59:e0e556c8bd46 85 case TFTP_CLIENT_PORT: return TftpHandlePacketReceived(traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); //60690
andrewboyson 10:f0854784e960 86
andrewboyson 10:f0854784e960 87 //Quietly drop these
andrewboyson 198:71e298f63bf0 88 case 0: //Unused but can be generated accidentally. For example the WIZ lights send it when powered up.
andrewboyson 42:222a4f45f916 89 case DHCP_SERVER_PORT: //67
andrewboyson 57:e0fb648acf48 90 case TFTP_SERVER_PORT: //69
andrewboyson 42:222a4f45f916 91 case 137: //NETBIOS name service
andrewboyson 42:222a4f45f916 92 case 138: //NETBIOS datagram service
andrewboyson 42:222a4f45f916 93 case 139: //NETBIOS session service
andrewboyson 42:222a4f45f916 94 case 500: //Key exchange - Xbox live
andrewboyson 42:222a4f45f916 95 case 1900: //SSDP Simple Service Discovery Protocol (uPnP)
andrewboyson 42:222a4f45f916 96 case 3074: //Xbox live
andrewboyson 42:222a4f45f916 97 case 3076: //Call of Duty - Xbox
andrewboyson 52:fbc5a46b5e16 98 case 5050: //Don't know but have been sent by Kate and my android phones.
andrewboyson 42:222a4f45f916 99 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 173:9bc30cd82a76 100 case 5684: //CoAps
andrewboyson 52:fbc5a46b5e16 101 case 9956: //Alljoyn part of Allseen IoT services
andrewboyson 42:222a4f45f916 102 case 9997: //VLC
andrewboyson 42:222a4f45f916 103 case 9998: //VLC
andrewboyson 42:222a4f45f916 104 case 9999: //VLC
andrewboyson 42:222a4f45f916 105 case 17500: //Dropbox LAN sync
andrewboyson 197:465f5f2154b7 106 case 38899: //WIZ
andrewboyson 197:465f5f2154b7 107 case 38900: //WIZ
andrewboyson 95:b9a99049016a 108 case 57621: //Spotify P2P
andrewboyson 10:f0854784e960 109 return DO_NOTHING;
andrewboyson 10:f0854784e960 110
andrewboyson 10:f0854784e960 111 //Report anything else
andrewboyson 10:f0854784e960 112 default:
andrewboyson 52:fbc5a46b5e16 113 if (UdpTrace)
andrewboyson 52:fbc5a46b5e16 114 {
andrewboyson 52:fbc5a46b5e16 115 LogTimeF("UDP unknown port %d\r\n", dstPort);
andrewboyson 52:fbc5a46b5e16 116 traceback(); //This will already include the UDP header
andrewboyson 52:fbc5a46b5e16 117 }
andrewboyson 10:f0854784e960 118 return DO_NOTHING;
andrewboyson 10:f0854784e960 119 }
andrewboyson 10:f0854784e960 120 }
andrewboyson 138:5ff0c7069300 121 int UdpHandleReceivedPacket(void (*traceback)(void), int sizeRx, char* pPacketRx, int* pSizeTx, char* pPacketTx)
andrewboyson 10:f0854784e960 122 {
andrewboyson 142:a8c0890a58d1 123 int lastRestartPoint = RestartPoint;
andrewboyson 142:a8c0890a58d1 124 RestartPoint = FAULT_POINT_UdpHandleReceivedPacket;
andrewboyson 121:bc048b65a630 125
andrewboyson 138:5ff0c7069300 126 readHeader(pPacketRx);
andrewboyson 59:e0e556c8bd46 127
andrewboyson 138:5ff0c7069300 128 void* pDataRx = pPacketRx + HEADER_LENGTH;
andrewboyson 138:5ff0c7069300 129 void* pDataTx = pPacketTx + HEADER_LENGTH;
andrewboyson 138:5ff0c7069300 130 int dataLengthRx = sizeRx - HEADER_LENGTH;
andrewboyson 138:5ff0c7069300 131 int dataLengthTx = *pSizeTx - HEADER_LENGTH;
andrewboyson 10:f0854784e960 132
andrewboyson 59:e0e556c8bd46 133 int action = handlePort(traceback, dataLengthRx, pDataRx, &dataLengthTx, pDataTx);
andrewboyson 10:f0854784e960 134
andrewboyson 138:5ff0c7069300 135 *pSizeTx = dataLengthTx + HEADER_LENGTH;
andrewboyson 10:f0854784e960 136
andrewboyson 37:793b39683406 137 uint16_t tmpPort = dstPort;
andrewboyson 37:793b39683406 138 dstPort = srcPort;
andrewboyson 37:793b39683406 139 srcPort = tmpPort;
andrewboyson 10:f0854784e960 140
andrewboyson 142:a8c0890a58d1 141 RestartPoint = lastRestartPoint;
andrewboyson 10:f0854784e960 142 return action;
andrewboyson 10:f0854784e960 143 }
andrewboyson 138:5ff0c7069300 144 static int pollForPacketToSend(int type, int* pDataLength, char* pData)
andrewboyson 10:f0854784e960 145 {
andrewboyson 37:793b39683406 146 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 147
andrewboyson 172:9bc3c7b2cca1 148 if (!action && type == ETH_IPV4) //DHCP only works under IPv4
andrewboyson 10:f0854784e960 149 {
andrewboyson 10:f0854784e960 150 action = DhcpPollForRequestToSend(pData, pDataLength);
andrewboyson 10:f0854784e960 151 if (action)
andrewboyson 10:f0854784e960 152 {
andrewboyson 37:793b39683406 153 srcPort = DHCP_CLIENT_PORT;
andrewboyson 37:793b39683406 154 dstPort = DHCP_SERVER_PORT;
andrewboyson 10:f0854784e960 155 }
andrewboyson 10:f0854784e960 156 }
andrewboyson 10:f0854784e960 157
andrewboyson 172:9bc3c7b2cca1 158 //if (!action && type == (DnsSendRequestsViaIp4 ? ETH_IPV4 : ETH_IPV6)) //DNS is agnostic
andrewboyson 172:9bc3c7b2cca1 159 if (!action) //DNS is agnostic
andrewboyson 10:f0854784e960 160 {
andrewboyson 171:f708d6776752 161 action = DnsPollForPacketToSend(type, pData, pDataLength);
andrewboyson 37:793b39683406 162 int dest = ActionGetDestPart(action);
andrewboyson 37:793b39683406 163 if (dest)
andrewboyson 10:f0854784e960 164 {
andrewboyson 37:793b39683406 165 switch (dest)
andrewboyson 10:f0854784e960 166 {
andrewboyson 37:793b39683406 167 case UNICAST_DNS: srcPort = DNS_UNICAST_CLIENT_PORT; dstPort = DNS_UNICAST_SERVER_PORT; break; //53053, 53
andrewboyson 37:793b39683406 168 case MULTICAST_MDNS: srcPort = DNS_MDNS_PORT; dstPort = DNS_MDNS_PORT; break; // 5353, 5353
andrewboyson 37:793b39683406 169 case MULTICAST_LLMNR: srcPort = DNS_LLMNR_CLIENT_PORT; dstPort = DNS_LLMNR_SERVER_PORT; break; //53055, 5355
andrewboyson 10:f0854784e960 170
andrewboyson 10:f0854784e960 171 //Report anything else
andrewboyson 10:f0854784e960 172 default:
andrewboyson 37:793b39683406 173 LogTimeF("DNS unknown dest %d\r\n", dest);
andrewboyson 10:f0854784e960 174 return DO_NOTHING;
andrewboyson 10:f0854784e960 175 }
andrewboyson 10:f0854784e960 176 }
andrewboyson 10:f0854784e960 177 }
andrewboyson 172:9bc3c7b2cca1 178 if (!action && type == (NtpClientQuerySendRequestsViaIp4 ? ETH_IPV4 : ETH_IPV6)) //NTP is agnostic
andrewboyson 22:914b970356f0 179 {
andrewboyson 22:914b970356f0 180 action = NtpPollForPacketToSend(type, pData, pDataLength);
andrewboyson 22:914b970356f0 181 if (action)
andrewboyson 22:914b970356f0 182 {
andrewboyson 37:793b39683406 183 srcPort = NTP_PORT;
andrewboyson 37:793b39683406 184 dstPort = NTP_PORT;
andrewboyson 22:914b970356f0 185 }
andrewboyson 22:914b970356f0 186 }
andrewboyson 172:9bc3c7b2cca1 187 if (!action && type == (TftpSendRequestsViaIp4 ? ETH_IPV4 : ETH_IPV6)) //TFTP is agnostic
andrewboyson 57:e0fb648acf48 188 {
andrewboyson 57:e0fb648acf48 189 action = TftpPollForPacketToSend(type, pData, pDataLength);
andrewboyson 57:e0fb648acf48 190 if (action)
andrewboyson 57:e0fb648acf48 191 {
andrewboyson 57:e0fb648acf48 192 srcPort = TFTP_CLIENT_PORT;
andrewboyson 57:e0fb648acf48 193 dstPort = TFTP_SERVER_PORT;
andrewboyson 57:e0fb648acf48 194 }
andrewboyson 57:e0fb648acf48 195 }
andrewboyson 196:0876a7609a60 196 if (UserPollForUdpPacketToSend)
andrewboyson 195:bd5b123143ca 197 {
andrewboyson 196:0876a7609a60 198 if (!action)
andrewboyson 195:bd5b123143ca 199 {
andrewboyson 196:0876a7609a60 200 action = UserPollForUdpPacketToSend(type, pDataLength, pData);
andrewboyson 196:0876a7609a60 201 if (action)
andrewboyson 196:0876a7609a60 202 {
andrewboyson 196:0876a7609a60 203 srcPort = UserUdpDstPort;
andrewboyson 196:0876a7609a60 204 dstPort = UserUdpSrcPort;
andrewboyson 196:0876a7609a60 205 }
andrewboyson 195:bd5b123143ca 206 }
andrewboyson 195:bd5b123143ca 207 }
andrewboyson 37:793b39683406 208
andrewboyson 10:f0854784e960 209 return action;
andrewboyson 10:f0854784e960 210 }
andrewboyson 138:5ff0c7069300 211 int UdpPollForPacketToSend(int type, int* pSize, char* pPacket)
andrewboyson 10:f0854784e960 212 {
andrewboyson 138:5ff0c7069300 213 void* pData = pPacket + HEADER_LENGTH;
andrewboyson 138:5ff0c7069300 214 int dataLength = *pSize - HEADER_LENGTH;
andrewboyson 10:f0854784e960 215
andrewboyson 10:f0854784e960 216 int action = pollForPacketToSend(type, &dataLength, pData);
andrewboyson 10:f0854784e960 217
andrewboyson 138:5ff0c7069300 218 *pSize = dataLength + HEADER_LENGTH;
andrewboyson 10:f0854784e960 219 return action;
andrewboyson 10:f0854784e960 220 }