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:
Tue Nov 28 17:05:46 2017 +0000
Revision:
57:e0fb648acf48
Parent:
52:fbc5a46b5e16
Child:
59:e0e556c8bd46
Added TFTP

Who changed what in which revision?

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