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.c
00001 #include <stdint.h> 00002 #include <stdbool.h> 00003 00004 #include "log.h" 00005 #include "net.h" 00006 #include "action.h" 00007 #include "udp.h" 00008 #include "ntp.h" 00009 #include "tftp.h" 00010 #include "dhcp.h" 00011 #include "dns.h" 00012 #include "eth.h" 00013 #include "ip4.h" 00014 #include "ip6.h" 00015 #include "slaac.h" 00016 #include "ns.h" 00017 #include "ntpclient.h" 00018 #include "restart.h" 00019 #include "user.h" 00020 00021 bool UdpTrace = true; 00022 00023 static char* hdrPtrSrcPort (char* pPacket) { return pPacket + 0; } //2 00024 static char* hdrPtrDstPort (char* pPacket) { return pPacket + 2; } //2 00025 static char* hdrPtrTotalLength(char* pPacket) { return pPacket + 4; } //2 00026 static char* hdrPtrChecksum (char* pPacket) { return pPacket + 6; } //2 00027 static const int HEADER_LENGTH = 8; 00028 00029 void UdpHdrSetChecksum(void* pPacket, uint16_t checksum) 00030 { 00031 NetDirect16(hdrPtrChecksum(pPacket), &checksum); 00032 } 00033 static uint16_t srcPort; 00034 static uint16_t dstPort; 00035 static uint16_t checksum; 00036 static uint16_t totalLength; 00037 00038 static void readHeader(char* pPacket) 00039 { 00040 NetInvert16(&srcPort, hdrPtrSrcPort (pPacket)); 00041 NetInvert16(&dstPort, hdrPtrDstPort (pPacket)); 00042 NetDirect16(&checksum, hdrPtrChecksum (pPacket)); 00043 NetInvert16(&totalLength, hdrPtrTotalLength(pPacket)); 00044 } 00045 void UdpMakeHeader(int size, char* pPacket) 00046 { 00047 checksum = 0; 00048 NetInvert16(hdrPtrSrcPort (pPacket), &srcPort ); 00049 NetInvert16(hdrPtrDstPort (pPacket), &dstPort ); 00050 NetDirect16(hdrPtrChecksum (pPacket), &checksum ); 00051 NetInvert16(hdrPtrTotalLength(pPacket), &size ); 00052 00053 } 00054 00055 void UdpLogHeader(uint16_t calculatedChecksum) 00056 { 00057 if (NetTraceVerbose) 00058 { 00059 Log ("UDP header\r\n"); 00060 LogF(" Source port %hu\r\n", srcPort); 00061 LogF(" Destination port %hu\r\n", dstPort); 00062 LogF(" Total length %hu\r\n", totalLength); 00063 LogF(" Checksum (hex) %04hX\r\n", checksum); 00064 LogF(" Calculated %04hX\r\n", calculatedChecksum); 00065 } 00066 else 00067 { 00068 LogF("UDP header %hu >>> %hu\r\n", srcPort, dstPort); 00069 } 00070 } 00071 00072 static int handlePort(void (*traceback)(void), int dataLengthRx, char* pDataRx, int* pPataLengthTx, char* pDataTx) 00073 { 00074 if (UserHandleReceivedUdpPacket && (dstPort == UserUdpPort1 || dstPort == UserUdpPort2)) return UserHandleReceivedUdpPacket(dstPort, traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); 00075 00076 switch (dstPort) 00077 { 00078 //Handle these 00079 case DHCP_CLIENT_PORT: return DhcpHandleResponse (traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 68 00080 case NTP_PORT: return NtpHandlePacketReceived(traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 123 00081 case DNS_UNICAST_CLIENT_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_UDNS, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); //53053 00082 case DNS_MDNS_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_MDNS, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 5353 00083 case DNS_LLMNR_CLIENT_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_LLMNR, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); //53055 00084 case DNS_LLMNR_SERVER_PORT: return DnsHandlePacketReceived(traceback, DNS_PROTOCOL_LLMNR, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); // 5355 00085 case TFTP_CLIENT_PORT: return TftpHandlePacketReceived(traceback, dataLengthRx, pDataRx, pPataLengthTx, pDataTx); //60690 00086 00087 //Quietly drop these 00088 case 0: //Unused but can be generated accidentally. For example the WIZ lights send it when powered up. 00089 case DHCP_SERVER_PORT: //67 00090 case TFTP_SERVER_PORT: //69 00091 case 137: //NETBIOS name service 00092 case 138: //NETBIOS datagram service 00093 case 139: //NETBIOS session service 00094 case 500: //Key exchange - Xbox live 00095 case 1900: //SSDP Simple Service Discovery Protocol (uPnP) 00096 case 3074: //Xbox live 00097 case 3076: //Call of Duty - Xbox 00098 case 5050: //Don't know but have been sent by Kate and my android phones. 00099 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' 00100 case 5684: //CoAps 00101 case 9956: //Alljoyn part of Allseen IoT services 00102 case 9997: //VLC 00103 case 9998: //VLC 00104 case 9999: //VLC 00105 case 17500: //Dropbox LAN sync 00106 case 38899: //WIZ 00107 case 38900: //WIZ 00108 case 57621: //Spotify P2P 00109 return DO_NOTHING; 00110 00111 //Report anything else 00112 default: 00113 if (UdpTrace) 00114 { 00115 LogTimeF("UDP unknown port %d\r\n", dstPort); 00116 traceback(); //This will already include the UDP header 00117 } 00118 return DO_NOTHING; 00119 } 00120 } 00121 int UdpHandleReceivedPacket(void (*traceback)(void), int sizeRx, char* pPacketRx, int* pSizeTx, char* pPacketTx) 00122 { 00123 int lastRestartPoint = RestartPoint; 00124 RestartPoint = FAULT_POINT_UdpHandleReceivedPacket; 00125 00126 readHeader(pPacketRx); 00127 00128 void* pDataRx = pPacketRx + HEADER_LENGTH; 00129 void* pDataTx = pPacketTx + HEADER_LENGTH; 00130 int dataLengthRx = sizeRx - HEADER_LENGTH; 00131 int dataLengthTx = *pSizeTx - HEADER_LENGTH; 00132 00133 int action = handlePort(traceback, dataLengthRx, pDataRx, &dataLengthTx, pDataTx); 00134 00135 *pSizeTx = dataLengthTx + HEADER_LENGTH; 00136 00137 uint16_t tmpPort = dstPort; 00138 dstPort = srcPort; 00139 srcPort = tmpPort; 00140 00141 RestartPoint = lastRestartPoint; 00142 return action; 00143 } 00144 static int pollForPacketToSend(int type, int* pDataLength, char* pData) 00145 { 00146 int action = DO_NOTHING; 00147 00148 if (!action && type == ETH_IPV4) //DHCP only works under IPv4 00149 { 00150 action = DhcpPollForRequestToSend(pData, pDataLength); 00151 if (action) 00152 { 00153 srcPort = DHCP_CLIENT_PORT; 00154 dstPort = DHCP_SERVER_PORT; 00155 } 00156 } 00157 00158 //if (!action && type == (DnsSendRequestsViaIp4 ? ETH_IPV4 : ETH_IPV6)) //DNS is agnostic 00159 if (!action) //DNS is agnostic 00160 { 00161 action = DnsPollForPacketToSend(type, pData, pDataLength); 00162 int dest = ActionGetDestPart(action); 00163 if (dest) 00164 { 00165 switch (dest) 00166 { 00167 case UNICAST_DNS: srcPort = DNS_UNICAST_CLIENT_PORT; dstPort = DNS_UNICAST_SERVER_PORT; break; //53053, 53 00168 case MULTICAST_MDNS: srcPort = DNS_MDNS_PORT; dstPort = DNS_MDNS_PORT; break; // 5353, 5353 00169 case MULTICAST_LLMNR: srcPort = DNS_LLMNR_CLIENT_PORT; dstPort = DNS_LLMNR_SERVER_PORT; break; //53055, 5355 00170 00171 //Report anything else 00172 default: 00173 LogTimeF("DNS unknown dest %d\r\n", dest); 00174 return DO_NOTHING; 00175 } 00176 } 00177 } 00178 if (!action && type == (NtpClientQuerySendRequestsViaIp4 ? ETH_IPV4 : ETH_IPV6)) //NTP is agnostic 00179 { 00180 action = NtpPollForPacketToSend(type, pData, pDataLength); 00181 if (action) 00182 { 00183 srcPort = NTP_PORT; 00184 dstPort = NTP_PORT; 00185 } 00186 } 00187 if (!action && type == (TftpSendRequestsViaIp4 ? ETH_IPV4 : ETH_IPV6)) //TFTP is agnostic 00188 { 00189 action = TftpPollForPacketToSend(type, pData, pDataLength); 00190 if (action) 00191 { 00192 srcPort = TFTP_CLIENT_PORT; 00193 dstPort = TFTP_SERVER_PORT; 00194 } 00195 } 00196 if (UserPollForUdpPacketToSend) 00197 { 00198 if (!action) 00199 { 00200 action = UserPollForUdpPacketToSend(type, pDataLength, pData); 00201 if (action) 00202 { 00203 srcPort = UserUdpDstPort; 00204 dstPort = UserUdpSrcPort; 00205 } 00206 } 00207 } 00208 00209 return action; 00210 } 00211 int UdpPollForPacketToSend(int type, int* pSize, char* pPacket) 00212 { 00213 void* pData = pPacket + HEADER_LENGTH; 00214 int dataLength = *pSize - HEADER_LENGTH; 00215 00216 int action = pollForPacketToSend(type, &dataLength, pData); 00217 00218 *pSize = dataLength + HEADER_LENGTH; 00219 return action; 00220 }
Generated on Tue Jul 12 2022 18:53:40 by 1.7.2