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:
Sun Apr 16 14:21:55 2017 +0000
Revision:
10:f0854784e960
Child:
13:9cd54f7db57a
MDNS and LLMNR now working.

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 10:f0854784e960 8 #include "ip4.h"
andrewboyson 10:f0854784e960 9 #include "ip6.h"
andrewboyson 10:f0854784e960 10 #include "slaac.h"
andrewboyson 10:f0854784e960 11 #include "ndp.h"
andrewboyson 10:f0854784e960 12
andrewboyson 10:f0854784e960 13 #define UNKNOWN false
andrewboyson 10:f0854784e960 14
andrewboyson 10:f0854784e960 15 #define HEADER_SIZE 8
andrewboyson 10:f0854784e960 16 __packed struct header
andrewboyson 10:f0854784e960 17 {
andrewboyson 10:f0854784e960 18 uint16_t srcPort;
andrewboyson 10:f0854784e960 19 uint16_t dstPort;
andrewboyson 10:f0854784e960 20 uint16_t totalLength;
andrewboyson 10:f0854784e960 21 uint16_t checksum;
andrewboyson 10:f0854784e960 22 };
andrewboyson 10:f0854784e960 23 static uint16_t srcPort;
andrewboyson 10:f0854784e960 24 static uint16_t dstPort;
andrewboyson 10:f0854784e960 25 static uint16_t checksum;
andrewboyson 10:f0854784e960 26 static uint16_t totalLength;
andrewboyson 10:f0854784e960 27
andrewboyson 10:f0854784e960 28 static int handlePort(int* pDataLength, void* pData)
andrewboyson 10:f0854784e960 29 {
andrewboyson 10:f0854784e960 30 switch (dstPort)
andrewboyson 10:f0854784e960 31 {
andrewboyson 10:f0854784e960 32 //Handle these
andrewboyson 10:f0854784e960 33 case DHCP_CLIENT_PORT: return DhcpHandleResponse(pDataLength, pData); //68
andrewboyson 10:f0854784e960 34 case NTP_SERVER_PORT: return NtpHandleRequest (pDataLength, pData); //123
andrewboyson 10:f0854784e960 35 case DNS_CLIENT_PORT: return DnsHandleResponse(pDataLength, pData); //53053
andrewboyson 10:f0854784e960 36 case DNS_MULTICAST_SERVER_PORT: return DnsHandleRequest (DNS_TYPE_MDNS, pDataLength, pData); //5353
andrewboyson 10:f0854784e960 37 case DNS_LLMNR_SERVER_PORT: return DnsHandleRequest (DNS_TYPE_LLMNR, pDataLength, pData); //5355
andrewboyson 10:f0854784e960 38
andrewboyson 10:f0854784e960 39 //Quietly drop these
andrewboyson 10:f0854784e960 40 case DHCP_SERVER_PORT: //67
andrewboyson 10:f0854784e960 41 case 1900: //SSDP Simple Service Discovery Protocol (uPnP)
andrewboyson 10:f0854784e960 42 case 3076: //Call of Duty - Xbox
andrewboyson 10:f0854784e960 43 case 9997: //VLC
andrewboyson 10:f0854784e960 44 case 9998: //VLC
andrewboyson 10:f0854784e960 45 case 9999: //VLC
andrewboyson 10:f0854784e960 46 case 17500: //Dropbox LAN sync
andrewboyson 10:f0854784e960 47 return DO_NOTHING;
andrewboyson 10:f0854784e960 48
andrewboyson 10:f0854784e960 49 //Report anything else
andrewboyson 10:f0854784e960 50 default:
andrewboyson 10:f0854784e960 51 if (UNKNOWN) LogTimeF("UDP unknown port %d\r\n", dstPort);
andrewboyson 10:f0854784e960 52 return DO_NOTHING;
andrewboyson 10:f0854784e960 53 }
andrewboyson 10:f0854784e960 54 }
andrewboyson 10:f0854784e960 55 int UdpHandleReceivedPacket(int* pSize, void* pPacket)
andrewboyson 10:f0854784e960 56 {
andrewboyson 10:f0854784e960 57 void* pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 10:f0854784e960 58 int dataLength = *pSize - HEADER_SIZE;
andrewboyson 10:f0854784e960 59
andrewboyson 10:f0854784e960 60 int action = handlePort(&dataLength, pData);
andrewboyson 10:f0854784e960 61
andrewboyson 10:f0854784e960 62 *pSize = dataLength + HEADER_SIZE;
andrewboyson 10:f0854784e960 63
andrewboyson 10:f0854784e960 64 uint16_t tmpPort = dstPort;
andrewboyson 10:f0854784e960 65 dstPort = srcPort;
andrewboyson 10:f0854784e960 66 srcPort = tmpPort;
andrewboyson 10:f0854784e960 67
andrewboyson 10:f0854784e960 68 return action;
andrewboyson 10:f0854784e960 69 }
andrewboyson 10:f0854784e960 70 static int pollForPacketToSend(int type, int* pDataLength, void* pData)
andrewboyson 10:f0854784e960 71 {
andrewboyson 10:f0854784e960 72 int action = 0;
andrewboyson 10:f0854784e960 73
andrewboyson 10:f0854784e960 74 if (!action && type == IPV4) //DHCP only works under IPv4
andrewboyson 10:f0854784e960 75 {
andrewboyson 10:f0854784e960 76 action = DhcpPollForRequestToSend(pData, pDataLength);
andrewboyson 10:f0854784e960 77 if (action)
andrewboyson 10:f0854784e960 78 {
andrewboyson 10:f0854784e960 79 srcPort = DHCP_CLIENT_PORT;
andrewboyson 10:f0854784e960 80 dstPort = DHCP_SERVER_PORT;
andrewboyson 10:f0854784e960 81 }
andrewboyson 10:f0854784e960 82 }
andrewboyson 10:f0854784e960 83
andrewboyson 10:f0854784e960 84 if (!action) //DNS is agnostic
andrewboyson 10:f0854784e960 85 {
andrewboyson 10:f0854784e960 86 action = DnsPollForRequestToSend(pData, pDataLength);
andrewboyson 10:f0854784e960 87 if (action)
andrewboyson 10:f0854784e960 88 {
andrewboyson 10:f0854784e960 89 srcPort = DNS_CLIENT_PORT; //53053
andrewboyson 10:f0854784e960 90 switch (action)
andrewboyson 10:f0854784e960 91 {
andrewboyson 10:f0854784e960 92 case UNICAST_DNS: dstPort = DNS_UNICAST_SERVER_PORT; break; //53
andrewboyson 10:f0854784e960 93 case MULTICAST_MDNS: dstPort = DNS_MULTICAST_SERVER_PORT; break; //5353
andrewboyson 10:f0854784e960 94 case MULTICAST_LLMNR: dstPort = DNS_LLMNR_SERVER_PORT; break; //5355
andrewboyson 10:f0854784e960 95
andrewboyson 10:f0854784e960 96 //Report anything else
andrewboyson 10:f0854784e960 97 default:
andrewboyson 10:f0854784e960 98 LogTimeF("DNS unknown action %d\r\n", action);
andrewboyson 10:f0854784e960 99 return DO_NOTHING;
andrewboyson 10:f0854784e960 100 }
andrewboyson 10:f0854784e960 101 }
andrewboyson 10:f0854784e960 102 }
andrewboyson 10:f0854784e960 103 return action;
andrewboyson 10:f0854784e960 104 }
andrewboyson 10:f0854784e960 105 int UdpPollForPacketToSend(int type, int* pSize, void* pPacket)
andrewboyson 10:f0854784e960 106 {
andrewboyson 10:f0854784e960 107 void* pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 10:f0854784e960 108 int dataLength = *pSize - HEADER_SIZE;
andrewboyson 10:f0854784e960 109
andrewboyson 10:f0854784e960 110 int action = pollForPacketToSend(type, &dataLength, pData);
andrewboyson 10:f0854784e960 111
andrewboyson 10:f0854784e960 112 *pSize = dataLength + HEADER_SIZE;
andrewboyson 10:f0854784e960 113 return action;
andrewboyson 10:f0854784e960 114 }
andrewboyson 10:f0854784e960 115
andrewboyson 10:f0854784e960 116 void UdpLogHeader(char* title, void* pPacket, uint16_t calculatedChecksum)
andrewboyson 10:f0854784e960 117 {
andrewboyson 10:f0854784e960 118 LogTimeF("UDP %s\r\n", title);
andrewboyson 10:f0854784e960 119 LogF(" Source port %hu\r\n", srcPort);
andrewboyson 10:f0854784e960 120 LogF(" Destination port %hu\r\n", dstPort);
andrewboyson 10:f0854784e960 121 LogF(" Total length %hu\r\n", totalLength);
andrewboyson 10:f0854784e960 122 LogF(" Checksum (hex) %04hX\r\n", checksum);
andrewboyson 10:f0854784e960 123 LogF(" Calculated %04hX\r\n", calculatedChecksum);
andrewboyson 10:f0854784e960 124 }
andrewboyson 10:f0854784e960 125
andrewboyson 10:f0854784e960 126 void UdpMakeHeader(int size, void* pPacket)
andrewboyson 10:f0854784e960 127 {
andrewboyson 10:f0854784e960 128 struct header* pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 129
andrewboyson 10:f0854784e960 130 pHeader->dstPort = NetToHost16(dstPort);
andrewboyson 10:f0854784e960 131 pHeader->srcPort = NetToHost16(srcPort);
andrewboyson 10:f0854784e960 132 pHeader->totalLength = NetToHost16(size);
andrewboyson 10:f0854784e960 133 pHeader->checksum = 0;
andrewboyson 10:f0854784e960 134
andrewboyson 10:f0854784e960 135 }
andrewboyson 10:f0854784e960 136 void UdpAddChecksum(void* pPacket, uint16_t checksum)
andrewboyson 10:f0854784e960 137 {
andrewboyson 10:f0854784e960 138 struct header* pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 139 pHeader->checksum = checksum;
andrewboyson 10:f0854784e960 140 }
andrewboyson 10:f0854784e960 141 void UdpReadHeader(void* pPacket, uint16_t size)
andrewboyson 10:f0854784e960 142 {
andrewboyson 10:f0854784e960 143 struct header* pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 144
andrewboyson 10:f0854784e960 145 srcPort = NetToHost16(pHeader->srcPort);
andrewboyson 10:f0854784e960 146 dstPort = NetToHost16(pHeader->dstPort);
andrewboyson 10:f0854784e960 147 totalLength = NetToHost16(pHeader->totalLength);
andrewboyson 10:f0854784e960 148 checksum = NetToHost16(pHeader->checksum);
andrewboyson 10:f0854784e960 149 }