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:
172:9bc3c7b2cca1
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 #include <string.h>
andrewboyson 61:aad055f1b0d1 4
andrewboyson 37:793b39683406 5 #include "log.h"
andrewboyson 37:793b39683406 6 #include "net.h"
andrewboyson 37:793b39683406 7 #include "action.h"
andrewboyson 37:793b39683406 8 #include "ip4.h"
andrewboyson 37:793b39683406 9 #include "ip6.h"
andrewboyson 172:9bc3c7b2cca1 10 #include "nr.h"
andrewboyson 37:793b39683406 11 #include "dns.h"
andrewboyson 37:793b39683406 12 #include "dnshdr.h"
andrewboyson 37:793b39683406 13 #include "dnsname.h"
andrewboyson 128:79052cb4a41c 14 #include "dnslabel.h"
andrewboyson 37:793b39683406 15 #include "dhcp.h"
andrewboyson 13:9cd54f7db57a 16
andrewboyson 37:793b39683406 17 bool DnsReplyTrace = false;
andrewboyson 13:9cd54f7db57a 18
andrewboyson 13:9cd54f7db57a 19 char DnsReplyRecordName[256];
andrewboyson 13:9cd54f7db57a 20 uint32_t DnsReplyRecordNameAsIp4 = 0;
andrewboyson 13:9cd54f7db57a 21 char DnsReplyRecordNameAsIp6[16];
andrewboyson 13:9cd54f7db57a 22 char DnsReplyName[64];
andrewboyson 13:9cd54f7db57a 23 uint32_t DnsReplyIp4 = 0;
andrewboyson 13:9cd54f7db57a 24 char DnsReplyIp6[16];
andrewboyson 13:9cd54f7db57a 25
andrewboyson 58:d48c899e482f 26 static char* p;
andrewboyson 58:d48c899e482f 27 static char* pRecordName;
andrewboyson 58:d48c899e482f 28 static int recordType;
andrewboyson 58:d48c899e482f 29 static int recordDataLength;
andrewboyson 13:9cd54f7db57a 30 static char* pRecordData;
andrewboyson 13:9cd54f7db57a 31
andrewboyson 13:9cd54f7db57a 32 static int scanQuery()
andrewboyson 13:9cd54f7db57a 33 {
andrewboyson 13:9cd54f7db57a 34 int recordNameLength = DnsNameLength(p);
andrewboyson 43:bc028d5a6424 35 if (!recordNameLength) return -1; //failure
andrewboyson 13:9cd54f7db57a 36
andrewboyson 58:d48c899e482f 37 pRecordName = p;
andrewboyson 13:9cd54f7db57a 38 p += recordNameLength;
andrewboyson 13:9cd54f7db57a 39
andrewboyson 13:9cd54f7db57a 40 p++ ; //skip the first byte of the type
andrewboyson 13:9cd54f7db57a 41 recordType = *p++;
andrewboyson 13:9cd54f7db57a 42
andrewboyson 13:9cd54f7db57a 43 p += 2; //skip the class
andrewboyson 13:9cd54f7db57a 44
andrewboyson 13:9cd54f7db57a 45 return 0; //success
andrewboyson 13:9cd54f7db57a 46 }
andrewboyson 13:9cd54f7db57a 47
andrewboyson 13:9cd54f7db57a 48 static int scanAnswer()
andrewboyson 13:9cd54f7db57a 49 {
andrewboyson 13:9cd54f7db57a 50 int recordNameLength = DnsNameLength(p);
andrewboyson 43:bc028d5a6424 51 if (!recordNameLength) return -1; //failure
andrewboyson 13:9cd54f7db57a 52
andrewboyson 58:d48c899e482f 53 pRecordName = p;
andrewboyson 13:9cd54f7db57a 54 p += recordNameLength;
andrewboyson 13:9cd54f7db57a 55
andrewboyson 13:9cd54f7db57a 56 p++ ; //skip the first byte of the type
andrewboyson 13:9cd54f7db57a 57 recordType = *p++;
andrewboyson 13:9cd54f7db57a 58
andrewboyson 13:9cd54f7db57a 59 p += 6; //skip the class, TTL
andrewboyson 13:9cd54f7db57a 60 recordDataLength = 0;
andrewboyson 13:9cd54f7db57a 61 recordDataLength |= *p++ << 8;
andrewboyson 13:9cd54f7db57a 62 recordDataLength |= *p++;
andrewboyson 13:9cd54f7db57a 63
andrewboyson 13:9cd54f7db57a 64 pRecordData = p; //record the start of the data
andrewboyson 13:9cd54f7db57a 65
andrewboyson 13:9cd54f7db57a 66 p += recordDataLength; //Move to the start of the next record
andrewboyson 13:9cd54f7db57a 67
andrewboyson 13:9cd54f7db57a 68 return 0; //success
andrewboyson 13:9cd54f7db57a 69 }
andrewboyson 13:9cd54f7db57a 70 static void readAnswer()
andrewboyson 13:9cd54f7db57a 71 {
andrewboyson 13:9cd54f7db57a 72 DnsReplyRecordName[0] = 0;
andrewboyson 13:9cd54f7db57a 73 DnsReplyRecordNameAsIp4 = 0;
andrewboyson 13:9cd54f7db57a 74 DnsReplyRecordNameAsIp6[0] = 0;
andrewboyson 13:9cd54f7db57a 75 DnsReplyName[0] = 0;
andrewboyson 13:9cd54f7db57a 76 DnsReplyIp4 = 0;
andrewboyson 13:9cd54f7db57a 77 DnsReplyIp6[0] = 0;
andrewboyson 13:9cd54f7db57a 78
andrewboyson 13:9cd54f7db57a 79 switch (recordType)
andrewboyson 13:9cd54f7db57a 80 {
andrewboyson 13:9cd54f7db57a 81 case DNS_RECORD_A:
andrewboyson 13:9cd54f7db57a 82 case DNS_RECORD_AAAA:
andrewboyson 13:9cd54f7db57a 83 case DNS_RECORD_PTR:
andrewboyson 15:6ca6778168b1 84 case DNS_RECORD_SRV:
andrewboyson 15:6ca6778168b1 85 case DNS_RECORD_TXT:
andrewboyson 13:9cd54f7db57a 86 break;
andrewboyson 43:bc028d5a6424 87 default:
andrewboyson 15:6ca6778168b1 88 return;
andrewboyson 15:6ca6778168b1 89 }
andrewboyson 13:9cd54f7db57a 90
andrewboyson 59:e0e556c8bd46 91 DnsNameDecodePtr(pRecordName, DnsReplyRecordName, sizeof(DnsReplyRecordName));
andrewboyson 58:d48c899e482f 92 DnsNameDecodeIp4(pRecordName, &DnsReplyRecordNameAsIp4);
andrewboyson 58:d48c899e482f 93 DnsNameDecodeIp6(pRecordName, DnsReplyRecordNameAsIp6);
andrewboyson 15:6ca6778168b1 94
andrewboyson 13:9cd54f7db57a 95 switch (recordType)
andrewboyson 13:9cd54f7db57a 96 {
andrewboyson 13:9cd54f7db57a 97 case DNS_RECORD_A:
andrewboyson 43:bc028d5a6424 98 if (recordDataLength != 4) return;
andrewboyson 13:9cd54f7db57a 99 memcpy(&DnsReplyIp4, pRecordData, 4);
andrewboyson 13:9cd54f7db57a 100 break;
andrewboyson 13:9cd54f7db57a 101 case DNS_RECORD_AAAA:
andrewboyson 43:bc028d5a6424 102 if (recordDataLength != 16) return;
andrewboyson 13:9cd54f7db57a 103 memcpy(DnsReplyIp6, pRecordData, 16);
andrewboyson 13:9cd54f7db57a 104 break;
andrewboyson 13:9cd54f7db57a 105 case DNS_RECORD_PTR:
andrewboyson 43:bc028d5a6424 106 if (recordDataLength > DNS_MAX_LABEL_LENGTH) return;
andrewboyson 59:e0e556c8bd46 107 DnsNameDecodePtr(pRecordData, DnsReplyName, sizeof(DnsReplyName));
andrewboyson 13:9cd54f7db57a 108 break;
andrewboyson 13:9cd54f7db57a 109 }
andrewboyson 13:9cd54f7db57a 110 }
andrewboyson 13:9cd54f7db57a 111
andrewboyson 32:679654f2d023 112 static void sendToDnsCache(int dnsProtocol)
andrewboyson 30:e34173b7585c 113 {
andrewboyson 32:679654f2d023 114 char strippedName[100];
andrewboyson 128:79052cb4a41c 115 if (DnsReplyRecordName[0]) DnsLabelStripNameFromFullName(dnsProtocol, DnsReplyRecordName, sizeof(strippedName), strippedName);
andrewboyson 128:79052cb4a41c 116 if (DnsReplyName[0] ) DnsLabelStripNameFromFullName(dnsProtocol, DnsReplyName , sizeof(strippedName), strippedName);
andrewboyson 32:679654f2d023 117
andrewboyson 172:9bc3c7b2cca1 118 if (DnsReplyIp4 && DnsReplyRecordName[0]) NrAddAddress4(DnsReplyIp4, strippedName, dnsProtocol);
andrewboyson 172:9bc3c7b2cca1 119 if (DnsReplyIp6[0] && DnsReplyRecordName[0]) NrAddAddress6(DnsReplyIp6, strippedName, dnsProtocol);
andrewboyson 172:9bc3c7b2cca1 120 if (DnsReplyRecordNameAsIp4 && DnsReplyName[0] ) NrAddAddress4(DnsReplyRecordNameAsIp4, strippedName, dnsProtocol);
andrewboyson 172:9bc3c7b2cca1 121 if (DnsReplyRecordNameAsIp6[0] && DnsReplyName[0] ) NrAddAddress6(DnsReplyRecordNameAsIp6, strippedName, dnsProtocol);
andrewboyson 30:e34173b7585c 122 }
andrewboyson 59:e0e556c8bd46 123 int DnsReplyHandle(void (*traceback)(void), int dnsProtocol)
andrewboyson 57:e0fb648acf48 124 {
andrewboyson 57:e0fb648acf48 125 bool ok = true;
andrewboyson 57:e0fb648acf48 126 if (!DnsHdrAncount) ok = false;
andrewboyson 57:e0fb648acf48 127
andrewboyson 57:e0fb648acf48 128 p = DnsHdrData;
andrewboyson 170:96c637dc3f52 129
andrewboyson 170:96c637dc3f52 130 if (DnsReplyTrace || NetTraceHostGetMatched())
andrewboyson 170:96c637dc3f52 131 {
andrewboyson 170:96c637dc3f52 132 if (NetTraceNewLine) Log("\r\n");
andrewboyson 170:96c637dc3f52 133 LogTimeF("DnsReply received\r\n");
andrewboyson 170:96c637dc3f52 134 if (NetTraceStack) traceback();
andrewboyson 170:96c637dc3f52 135 DnsHdrLog(dnsProtocol);
andrewboyson 170:96c637dc3f52 136 }
andrewboyson 57:e0fb648acf48 137
andrewboyson 57:e0fb648acf48 138 if (ok)
andrewboyson 57:e0fb648acf48 139 {
andrewboyson 57:e0fb648acf48 140 for (int q = 0; q < DnsHdrQdcount; q++)
andrewboyson 57:e0fb648acf48 141 {
andrewboyson 57:e0fb648acf48 142 if (scanQuery())
andrewboyson 57:e0fb648acf48 143 {
andrewboyson 57:e0fb648acf48 144 ok = false;
andrewboyson 57:e0fb648acf48 145 break;
andrewboyson 57:e0fb648acf48 146 }
andrewboyson 57:e0fb648acf48 147 }
andrewboyson 57:e0fb648acf48 148 }
andrewboyson 57:e0fb648acf48 149 if (ok)
andrewboyson 57:e0fb648acf48 150 {
andrewboyson 57:e0fb648acf48 151 for (int a = 0; a < DnsHdrAncount; a++)
andrewboyson 57:e0fb648acf48 152 {
andrewboyson 57:e0fb648acf48 153 if (scanAnswer())
andrewboyson 57:e0fb648acf48 154 {
andrewboyson 57:e0fb648acf48 155 ok = false;
andrewboyson 57:e0fb648acf48 156 break;
andrewboyson 57:e0fb648acf48 157 }
andrewboyson 57:e0fb648acf48 158 readAnswer();
andrewboyson 57:e0fb648acf48 159 sendToDnsCache(dnsProtocol);
andrewboyson 57:e0fb648acf48 160 }
andrewboyson 57:e0fb648acf48 161 }
andrewboyson 57:e0fb648acf48 162
andrewboyson 57:e0fb648acf48 163 NetTraceHostCheckIp6(DnsReplyIp6);
andrewboyson 57:e0fb648acf48 164 NetTraceHostCheckIp6(DnsReplyRecordNameAsIp6);
andrewboyson 57:e0fb648acf48 165
andrewboyson 13:9cd54f7db57a 166 return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 167 }