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:
Wed Aug 23 18:02:42 2017 +0000
Revision:
33:714a0345e59b
Parent:
29:39277bf2003d
Child:
37:793b39683406
Made DNS names case insensitive

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 10:f0854784e960 1 #include "mbed.h"
andrewboyson 10:f0854784e960 2 #include "log.h"
andrewboyson 10:f0854784e960 3 #include "net.h"
andrewboyson 10:f0854784e960 4 #include "udp.h"
andrewboyson 10:f0854784e960 5 #include "ntp.h"
andrewboyson 10:f0854784e960 6 #include "dhcp.h"
andrewboyson 10:f0854784e960 7 #include "dns.h"
andrewboyson 15:6ca6778168b1 8 #include "eth.h"
andrewboyson 10:f0854784e960 9 #include "ip4.h"
andrewboyson 10:f0854784e960 10 #include "ip6.h"
andrewboyson 10:f0854784e960 11 #include "slaac.h"
andrewboyson 29:39277bf2003d 12 #include "ns.h"
andrewboyson 13:9cd54f7db57a 13 #include "io.h"
andrewboyson 10:f0854784e960 14
andrewboyson 15:6ca6778168b1 15 #define UNKNOWN true
andrewboyson 10:f0854784e960 16
andrewboyson 10:f0854784e960 17 #define HEADER_SIZE 8
andrewboyson 10:f0854784e960 18 __packed struct header
andrewboyson 10:f0854784e960 19 {
andrewboyson 10:f0854784e960 20 uint16_t srcPort;
andrewboyson 10:f0854784e960 21 uint16_t dstPort;
andrewboyson 10:f0854784e960 22 uint16_t totalLength;
andrewboyson 10:f0854784e960 23 uint16_t checksum;
andrewboyson 10:f0854784e960 24 };
andrewboyson 14:e75a59c1123d 25 uint16_t UdpSrcPort;
andrewboyson 14:e75a59c1123d 26 uint16_t UdpDstPort;
andrewboyson 10:f0854784e960 27 static uint16_t checksum;
andrewboyson 10:f0854784e960 28 static uint16_t totalLength;
andrewboyson 10:f0854784e960 29
andrewboyson 10:f0854784e960 30 static int handlePort(int* pDataLength, void* pData)
andrewboyson 10:f0854784e960 31 {
andrewboyson 14:e75a59c1123d 32 switch (UdpDstPort)
andrewboyson 10:f0854784e960 33 {
andrewboyson 10:f0854784e960 34 //Handle these
andrewboyson 13:9cd54f7db57a 35 case DHCP_CLIENT_PORT: return DhcpHandleResponse ( pDataLength, pData); // 68
andrewboyson 22:914b970356f0 36 case NTP_PORT: return NtpHandlePacketReceived( pDataLength, pData); // 123
andrewboyson 14:e75a59c1123d 37 case DNS_UNICAST_CLIENT_PORT: return DnsHandlePacketReceived(DNS_PROTOCOL_UDNS, pDataLength, pData); //53053
andrewboyson 14:e75a59c1123d 38 case DNS_MDNS_PORT: return DnsHandlePacketReceived(DNS_PROTOCOL_MDNS, pDataLength, pData); // 5353
andrewboyson 15:6ca6778168b1 39 case DNS_LLMNR_CLIENT_PORT: return DnsHandlePacketReceived(DNS_PROTOCOL_LLMNR, pDataLength, pData); //53055
andrewboyson 15:6ca6778168b1 40 case DNS_LLMNR_SERVER_PORT: return DnsHandlePacketReceived(DNS_PROTOCOL_LLMNR, pDataLength, pData); // 5355
andrewboyson 10:f0854784e960 41
andrewboyson 10:f0854784e960 42 //Quietly drop these
andrewboyson 10:f0854784e960 43 case DHCP_SERVER_PORT: //67
andrewboyson 15:6ca6778168b1 44 case 137: //NETBIOS name service
andrewboyson 15:6ca6778168b1 45 case 138: //NETBIOS datagram service
andrewboyson 15:6ca6778168b1 46 case 139: //NETBIOS session service
andrewboyson 10:f0854784e960 47 case 1900: //SSDP Simple Service Discovery Protocol (uPnP)
andrewboyson 10:f0854784e960 48 case 3076: //Call of Duty - Xbox
andrewboyson 33:714a0345e59b 49 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 15:6ca6778168b1 50 case 9956: //Alljoyn part af Allseen IoT services
andrewboyson 10:f0854784e960 51 case 9997: //VLC
andrewboyson 10:f0854784e960 52 case 9998: //VLC
andrewboyson 10:f0854784e960 53 case 9999: //VLC
andrewboyson 10:f0854784e960 54 case 17500: //Dropbox LAN sync
andrewboyson 10:f0854784e960 55 return DO_NOTHING;
andrewboyson 10:f0854784e960 56
andrewboyson 10:f0854784e960 57 //Report anything else
andrewboyson 10:f0854784e960 58 default:
andrewboyson 14:e75a59c1123d 59 if (UNKNOWN) LogTimeF("UDP unknown port %d\r\n", UdpDstPort);
andrewboyson 10:f0854784e960 60 return DO_NOTHING;
andrewboyson 10:f0854784e960 61 }
andrewboyson 10:f0854784e960 62 }
andrewboyson 10:f0854784e960 63 int UdpHandleReceivedPacket(int* pSize, void* pPacket)
andrewboyson 10:f0854784e960 64 {
andrewboyson 10:f0854784e960 65 void* pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 10:f0854784e960 66 int dataLength = *pSize - HEADER_SIZE;
andrewboyson 10:f0854784e960 67
andrewboyson 10:f0854784e960 68 int action = handlePort(&dataLength, pData);
andrewboyson 10:f0854784e960 69
andrewboyson 10:f0854784e960 70 *pSize = dataLength + HEADER_SIZE;
andrewboyson 10:f0854784e960 71
andrewboyson 14:e75a59c1123d 72 uint16_t tmpPort = UdpDstPort;
andrewboyson 14:e75a59c1123d 73 UdpDstPort = UdpSrcPort;
andrewboyson 14:e75a59c1123d 74 UdpSrcPort = tmpPort;
andrewboyson 10:f0854784e960 75
andrewboyson 10:f0854784e960 76 return action;
andrewboyson 10:f0854784e960 77 }
andrewboyson 10:f0854784e960 78 static int pollForPacketToSend(int type, int* pDataLength, void* pData)
andrewboyson 10:f0854784e960 79 {
andrewboyson 10:f0854784e960 80 int action = 0;
andrewboyson 10:f0854784e960 81
andrewboyson 10:f0854784e960 82 if (!action && type == IPV4) //DHCP only works under IPv4
andrewboyson 10:f0854784e960 83 {
andrewboyson 10:f0854784e960 84 action = DhcpPollForRequestToSend(pData, pDataLength);
andrewboyson 10:f0854784e960 85 if (action)
andrewboyson 10:f0854784e960 86 {
andrewboyson 14:e75a59c1123d 87 UdpSrcPort = DHCP_CLIENT_PORT;
andrewboyson 14:e75a59c1123d 88 UdpDstPort = DHCP_SERVER_PORT;
andrewboyson 10:f0854784e960 89 }
andrewboyson 10:f0854784e960 90 }
andrewboyson 10:f0854784e960 91
andrewboyson 10:f0854784e960 92 if (!action) //DNS is agnostic
andrewboyson 10:f0854784e960 93 {
andrewboyson 13:9cd54f7db57a 94 action = DnsPollForPacketToSend(pData, pDataLength);
andrewboyson 10:f0854784e960 95 if (action)
andrewboyson 10:f0854784e960 96 {
andrewboyson 10:f0854784e960 97 switch (action)
andrewboyson 10:f0854784e960 98 {
andrewboyson 14:e75a59c1123d 99 case UNICAST_DNS: UdpSrcPort = DNS_UNICAST_CLIENT_PORT; UdpDstPort = DNS_UNICAST_SERVER_PORT; break; //53053, 53
andrewboyson 14:e75a59c1123d 100 case MULTICAST_MDNS: UdpSrcPort = DNS_MDNS_PORT; UdpDstPort = DNS_MDNS_PORT; break; // 5353, 5353
andrewboyson 14:e75a59c1123d 101 case MULTICAST_LLMNR: UdpSrcPort = DNS_LLMNR_CLIENT_PORT; UdpDstPort = DNS_LLMNR_SERVER_PORT; break; //53055, 5355
andrewboyson 10:f0854784e960 102
andrewboyson 10:f0854784e960 103 //Report anything else
andrewboyson 10:f0854784e960 104 default:
andrewboyson 10:f0854784e960 105 LogTimeF("DNS unknown action %d\r\n", action);
andrewboyson 10:f0854784e960 106 return DO_NOTHING;
andrewboyson 10:f0854784e960 107 }
andrewboyson 10:f0854784e960 108 }
andrewboyson 10:f0854784e960 109 }
andrewboyson 22:914b970356f0 110 if (!action) //NTP needs to choose depending of what address is specified
andrewboyson 22:914b970356f0 111 {
andrewboyson 22:914b970356f0 112 action = NtpPollForPacketToSend(type, pData, pDataLength);
andrewboyson 22:914b970356f0 113 if (action)
andrewboyson 22:914b970356f0 114 {
andrewboyson 22:914b970356f0 115 UdpSrcPort = NTP_PORT;
andrewboyson 22:914b970356f0 116 UdpDstPort = NTP_PORT;
andrewboyson 22:914b970356f0 117 }
andrewboyson 22:914b970356f0 118 }
andrewboyson 10:f0854784e960 119 return action;
andrewboyson 10:f0854784e960 120 }
andrewboyson 10:f0854784e960 121 int UdpPollForPacketToSend(int type, int* pSize, void* pPacket)
andrewboyson 10:f0854784e960 122 {
andrewboyson 10:f0854784e960 123 void* pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 10:f0854784e960 124 int dataLength = *pSize - HEADER_SIZE;
andrewboyson 10:f0854784e960 125
andrewboyson 10:f0854784e960 126 int action = pollForPacketToSend(type, &dataLength, pData);
andrewboyson 10:f0854784e960 127
andrewboyson 10:f0854784e960 128 *pSize = dataLength + HEADER_SIZE;
andrewboyson 10:f0854784e960 129 return action;
andrewboyson 10:f0854784e960 130 }
andrewboyson 10:f0854784e960 131
andrewboyson 10:f0854784e960 132 void UdpLogHeader(char* title, void* pPacket, uint16_t calculatedChecksum)
andrewboyson 10:f0854784e960 133 {
andrewboyson 10:f0854784e960 134 LogTimeF("UDP %s\r\n", title);
andrewboyson 14:e75a59c1123d 135 LogF(" Source port %hu\r\n", UdpSrcPort);
andrewboyson 14:e75a59c1123d 136 LogF(" Destination port %hu\r\n", UdpDstPort);
andrewboyson 10:f0854784e960 137 LogF(" Total length %hu\r\n", totalLength);
andrewboyson 10:f0854784e960 138 LogF(" Checksum (hex) %04hX\r\n", checksum);
andrewboyson 10:f0854784e960 139 LogF(" Calculated %04hX\r\n", calculatedChecksum);
andrewboyson 10:f0854784e960 140 }
andrewboyson 10:f0854784e960 141
andrewboyson 10:f0854784e960 142 void UdpMakeHeader(int size, void* pPacket)
andrewboyson 10:f0854784e960 143 {
andrewboyson 10:f0854784e960 144 struct header* pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 145
andrewboyson 14:e75a59c1123d 146 pHeader->dstPort = NetToHost16(UdpDstPort);
andrewboyson 14:e75a59c1123d 147 pHeader->srcPort = NetToHost16(UdpSrcPort);
andrewboyson 10:f0854784e960 148 pHeader->totalLength = NetToHost16(size);
andrewboyson 10:f0854784e960 149 pHeader->checksum = 0;
andrewboyson 10:f0854784e960 150
andrewboyson 10:f0854784e960 151 }
andrewboyson 10:f0854784e960 152 void UdpAddChecksum(void* pPacket, uint16_t checksum)
andrewboyson 10:f0854784e960 153 {
andrewboyson 10:f0854784e960 154 struct header* pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 155 pHeader->checksum = checksum;
andrewboyson 10:f0854784e960 156 }
andrewboyson 10:f0854784e960 157 void UdpReadHeader(void* pPacket, uint16_t size)
andrewboyson 10:f0854784e960 158 {
andrewboyson 10:f0854784e960 159 struct header* pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 160
andrewboyson 14:e75a59c1123d 161 UdpSrcPort = NetToHost16(pHeader->srcPort);
andrewboyson 14:e75a59c1123d 162 UdpDstPort = NetToHost16(pHeader->dstPort);
andrewboyson 10:f0854784e960 163 totalLength = NetToHost16(pHeader->totalLength);
andrewboyson 10:f0854784e960 164 checksum = NetToHost16(pHeader->checksum);
andrewboyson 10:f0854784e960 165 }