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:
Mon Mar 11 16:42:45 2019 +0000
Revision:
128:79052cb4a41c
Parent:
61:aad055f1b0d1
Child:
170:96c637dc3f52
Tidied up the DNS label module and removed some declarations that had not left room for the terminating null.

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