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:
Fri Sep 22 13:55:56 2017 +0000
Revision:
35:93c39d260a83
Parent:
32:679654f2d023
Child:
37:793b39683406
Added name resolution and address resolution

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 13:9cd54f7db57a 1 #include "mbed.h"
andrewboyson 13:9cd54f7db57a 2 #include "log.h"
andrewboyson 13:9cd54f7db57a 3 #include "net.h"
andrewboyson 14:e75a59c1123d 4 #include "ip4.h"
andrewboyson 14:e75a59c1123d 5 #include "ip6.h"
andrewboyson 30:e34173b7585c 6 #include "ar.h"
andrewboyson 35:93c39d260a83 7 #include "nr.h"
andrewboyson 30:e34173b7585c 8 #include "dns.h"
andrewboyson 30:e34173b7585c 9 #include "dnshdr.h"
andrewboyson 30:e34173b7585c 10 #include "dnsname.h"
andrewboyson 32:679654f2d023 11 #include "dhcp.h"
andrewboyson 13:9cd54f7db57a 12
andrewboyson 22:914b970356f0 13 #define DEBUG false
andrewboyson 13:9cd54f7db57a 14
andrewboyson 13:9cd54f7db57a 15 char DnsReplyRecordName[256];
andrewboyson 13:9cd54f7db57a 16 uint32_t DnsReplyRecordNameAsIp4 = 0;
andrewboyson 13:9cd54f7db57a 17 char DnsReplyRecordNameAsIp6[16];
andrewboyson 13:9cd54f7db57a 18 char DnsReplyName[64];
andrewboyson 13:9cd54f7db57a 19 uint32_t DnsReplyIp4 = 0;
andrewboyson 13:9cd54f7db57a 20 char DnsReplyIp6[16];
andrewboyson 13:9cd54f7db57a 21
andrewboyson 13:9cd54f7db57a 22 static char *p;
andrewboyson 13:9cd54f7db57a 23 static int recordNameOffset;
andrewboyson 13:9cd54f7db57a 24 static int recordType;
andrewboyson 13:9cd54f7db57a 25 static int recordDataLength;
andrewboyson 13:9cd54f7db57a 26 static char* pRecordData;
andrewboyson 13:9cd54f7db57a 27
andrewboyson 13:9cd54f7db57a 28 static int scanQuery()
andrewboyson 13:9cd54f7db57a 29 {
andrewboyson 13:9cd54f7db57a 30 int recordNameLength = DnsNameLength(p);
andrewboyson 13:9cd54f7db57a 31 if (!recordNameLength)
andrewboyson 13:9cd54f7db57a 32 {
andrewboyson 22:914b970356f0 33 if (DEBUG) LogTimeF("DnsReply scanRecord name length of zero\r\n");
andrewboyson 13:9cd54f7db57a 34 return -1; //failure
andrewboyson 13:9cd54f7db57a 35 }
andrewboyson 13:9cd54f7db57a 36
andrewboyson 13:9cd54f7db57a 37 recordNameOffset = DnsNameIndexFromPointer(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 13:9cd54f7db57a 51 if (!recordNameLength)
andrewboyson 13:9cd54f7db57a 52 {
andrewboyson 22:914b970356f0 53 if (DEBUG) LogTimeF("DnsReply scanRecord name length of zero\r\n");
andrewboyson 13:9cd54f7db57a 54 return -1; //failure
andrewboyson 13:9cd54f7db57a 55 }
andrewboyson 13:9cd54f7db57a 56
andrewboyson 13:9cd54f7db57a 57 recordNameOffset = DnsNameIndexFromPointer(p);
andrewboyson 13:9cd54f7db57a 58 p += recordNameLength;
andrewboyson 13:9cd54f7db57a 59
andrewboyson 13:9cd54f7db57a 60 p++ ; //skip the first byte of the type
andrewboyson 13:9cd54f7db57a 61 recordType = *p++;
andrewboyson 13:9cd54f7db57a 62
andrewboyson 13:9cd54f7db57a 63 p += 6; //skip the class, TTL
andrewboyson 13:9cd54f7db57a 64 recordDataLength = 0;
andrewboyson 13:9cd54f7db57a 65 recordDataLength |= *p++ << 8;
andrewboyson 13:9cd54f7db57a 66 recordDataLength |= *p++;
andrewboyson 13:9cd54f7db57a 67
andrewboyson 13:9cd54f7db57a 68 pRecordData = p; //record the start of the data
andrewboyson 13:9cd54f7db57a 69
andrewboyson 13:9cd54f7db57a 70 p += recordDataLength; //Move to the start of the next record
andrewboyson 13:9cd54f7db57a 71
andrewboyson 13:9cd54f7db57a 72 return 0; //success
andrewboyson 13:9cd54f7db57a 73 }
andrewboyson 13:9cd54f7db57a 74 static void readAnswer()
andrewboyson 13:9cd54f7db57a 75 {
andrewboyson 13:9cd54f7db57a 76 DnsReplyRecordName[0] = 0;
andrewboyson 13:9cd54f7db57a 77 DnsReplyRecordNameAsIp4 = 0;
andrewboyson 13:9cd54f7db57a 78 DnsReplyRecordNameAsIp6[0] = 0;
andrewboyson 13:9cd54f7db57a 79 DnsReplyName[0] = 0;
andrewboyson 13:9cd54f7db57a 80 DnsReplyIp4 = 0;
andrewboyson 13:9cd54f7db57a 81 DnsReplyIp6[0] = 0;
andrewboyson 13:9cd54f7db57a 82
andrewboyson 13:9cd54f7db57a 83 switch (recordType)
andrewboyson 13:9cd54f7db57a 84 {
andrewboyson 13:9cd54f7db57a 85 case DNS_RECORD_A:
andrewboyson 13:9cd54f7db57a 86 case DNS_RECORD_AAAA:
andrewboyson 13:9cd54f7db57a 87 case DNS_RECORD_PTR:
andrewboyson 15:6ca6778168b1 88 case DNS_RECORD_SRV:
andrewboyson 15:6ca6778168b1 89 case DNS_RECORD_TXT:
andrewboyson 13:9cd54f7db57a 90 break;
andrewboyson 13:9cd54f7db57a 91 default:
andrewboyson 13:9cd54f7db57a 92 LogTimeF("DnsReply readAnswer unrecognised record type %d\r\n", recordType);
andrewboyson 15:6ca6778168b1 93 return;
andrewboyson 15:6ca6778168b1 94 }
andrewboyson 13:9cd54f7db57a 95
andrewboyson 13:9cd54f7db57a 96 DnsNameDecode (recordNameOffset, sizeof(DnsReplyRecordName), DnsReplyRecordName);
andrewboyson 13:9cd54f7db57a 97 DnsNameDecodeIp4(recordNameOffset, &DnsReplyRecordNameAsIp4);
andrewboyson 13:9cd54f7db57a 98 DnsNameDecodeIp6(recordNameOffset, DnsReplyRecordNameAsIp6);
andrewboyson 15:6ca6778168b1 99
andrewboyson 13:9cd54f7db57a 100 switch (recordType)
andrewboyson 13:9cd54f7db57a 101 {
andrewboyson 13:9cd54f7db57a 102 case DNS_RECORD_A:
andrewboyson 13:9cd54f7db57a 103 if (recordDataLength != 4)
andrewboyson 13:9cd54f7db57a 104 {
andrewboyson 13:9cd54f7db57a 105 LogTimeF("DnsReply A type length of %d\r\n", recordDataLength);
andrewboyson 13:9cd54f7db57a 106 return;
andrewboyson 13:9cd54f7db57a 107 }
andrewboyson 13:9cd54f7db57a 108 memcpy(&DnsReplyIp4, pRecordData, 4);
andrewboyson 13:9cd54f7db57a 109 break;
andrewboyson 13:9cd54f7db57a 110 case DNS_RECORD_AAAA:
andrewboyson 13:9cd54f7db57a 111 if (recordDataLength != 16)
andrewboyson 13:9cd54f7db57a 112 {
andrewboyson 13:9cd54f7db57a 113 LogTimeF("DnsReply AAAA type length of %d\r\n", recordDataLength);
andrewboyson 13:9cd54f7db57a 114 return;
andrewboyson 13:9cd54f7db57a 115 }
andrewboyson 13:9cd54f7db57a 116 memcpy(DnsReplyIp6, pRecordData, 16);
andrewboyson 13:9cd54f7db57a 117 break;
andrewboyson 13:9cd54f7db57a 118 case DNS_RECORD_PTR:
andrewboyson 35:93c39d260a83 119 if (recordDataLength > DNS_MAX_LABEL_LENGTH)
andrewboyson 13:9cd54f7db57a 120 {
andrewboyson 35:93c39d260a83 121 LogTimeF("DnsReply PTR type length %d is greater than max DNS label length of %d\r\n", recordDataLength, DNS_MAX_LABEL_LENGTH);
andrewboyson 13:9cd54f7db57a 122 return;
andrewboyson 13:9cd54f7db57a 123 }
andrewboyson 13:9cd54f7db57a 124 DnsNameDecode(DnsNameIndexFromPointer(pRecordData), sizeof(DnsReplyName), DnsReplyName);
andrewboyson 13:9cd54f7db57a 125 break;
andrewboyson 13:9cd54f7db57a 126 }
andrewboyson 15:6ca6778168b1 127
andrewboyson 13:9cd54f7db57a 128 if (DEBUG)
andrewboyson 13:9cd54f7db57a 129 {
andrewboyson 15:6ca6778168b1 130 LogF(" answer: %s", DnsReplyRecordName);
andrewboyson 13:9cd54f7db57a 131 char text[100];
andrewboyson 15:6ca6778168b1 132 if (DnsReplyRecordNameAsIp4)
andrewboyson 15:6ca6778168b1 133 {
andrewboyson 15:6ca6778168b1 134 Ip4AddressToString(DnsReplyRecordNameAsIp4, sizeof(text), text);
andrewboyson 15:6ca6778168b1 135 LogF(" (%s)", text);
andrewboyson 15:6ca6778168b1 136 }
andrewboyson 15:6ca6778168b1 137 if (DnsReplyRecordNameAsIp6[0])
andrewboyson 15:6ca6778168b1 138 {
andrewboyson 15:6ca6778168b1 139 Ip6AddressToString(DnsReplyRecordNameAsIp6, sizeof(text), text);
andrewboyson 15:6ca6778168b1 140 LogF(" (%s)", text);
andrewboyson 15:6ca6778168b1 141 }
andrewboyson 15:6ca6778168b1 142 LogF(" == ");
andrewboyson 13:9cd54f7db57a 143 switch (recordType)
andrewboyson 13:9cd54f7db57a 144 {
andrewboyson 13:9cd54f7db57a 145 case DNS_RECORD_A:
andrewboyson 14:e75a59c1123d 146 Ip4AddressToString(DnsReplyIp4, sizeof(text), text);
andrewboyson 15:6ca6778168b1 147 LogF("%s\r\n", text);
andrewboyson 13:9cd54f7db57a 148 break;
andrewboyson 13:9cd54f7db57a 149 case DNS_RECORD_AAAA:
andrewboyson 14:e75a59c1123d 150 Ip6AddressToString(DnsReplyIp6, sizeof(text), text);
andrewboyson 15:6ca6778168b1 151 LogF("%s\r\n", text);
andrewboyson 13:9cd54f7db57a 152 break;
andrewboyson 13:9cd54f7db57a 153 case DNS_RECORD_PTR:
andrewboyson 15:6ca6778168b1 154 LogF("%s\r\n", DnsReplyName);
andrewboyson 15:6ca6778168b1 155 break;
andrewboyson 15:6ca6778168b1 156 default:
andrewboyson 15:6ca6778168b1 157 DnsRecordTypeToString(recordType, sizeof(text), text);
andrewboyson 15:6ca6778168b1 158 LogF("%d bytes of %s\r\n", recordDataLength, text);
andrewboyson 13:9cd54f7db57a 159 break;
andrewboyson 13:9cd54f7db57a 160 }
andrewboyson 13:9cd54f7db57a 161 }
andrewboyson 13:9cd54f7db57a 162 }
andrewboyson 13:9cd54f7db57a 163
andrewboyson 32:679654f2d023 164 static void sendToDnsCache(int dnsProtocol)
andrewboyson 30:e34173b7585c 165 {
andrewboyson 32:679654f2d023 166 char strippedName[100];
andrewboyson 32:679654f2d023 167 if (DnsReplyRecordName[0]) DnsStripNameFromFullName(dnsProtocol, DnsReplyRecordName, sizeof(strippedName), strippedName);
andrewboyson 32:679654f2d023 168 if (DnsReplyName[0] ) DnsStripNameFromFullName(dnsProtocol, DnsReplyName , sizeof(strippedName), strippedName);
andrewboyson 32:679654f2d023 169
andrewboyson 35:93c39d260a83 170 if (DnsReplyIp4 && DnsReplyRecordName[0]) NrAddIp4Record(DnsReplyIp4, strippedName, dnsProtocol);
andrewboyson 35:93c39d260a83 171 if (DnsReplyIp6[0] && DnsReplyRecordName[0]) NrAddIp6Record(DnsReplyIp6, strippedName, dnsProtocol);
andrewboyson 35:93c39d260a83 172 if (DnsReplyRecordNameAsIp4 && DnsReplyName[0] ) NrAddIp4Record(DnsReplyRecordNameAsIp4, strippedName, dnsProtocol);
andrewboyson 35:93c39d260a83 173 if (DnsReplyRecordNameAsIp6[0] && DnsReplyName[0] ) NrAddIp6Record(DnsReplyRecordNameAsIp6, strippedName, dnsProtocol);
andrewboyson 30:e34173b7585c 174 }
andrewboyson 13:9cd54f7db57a 175 int DnsReplyHandle(int dnsProtocol, int *pSize)
andrewboyson 13:9cd54f7db57a 176 {
andrewboyson 13:9cd54f7db57a 177 if (!DnsHdrAncount) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 178 if (DEBUG) DnsHdrLog("received reply", dnsProtocol);
andrewboyson 13:9cd54f7db57a 179
andrewboyson 13:9cd54f7db57a 180 p = DnsHdrData;
andrewboyson 13:9cd54f7db57a 181
andrewboyson 13:9cd54f7db57a 182 for (int q = 0; q < DnsHdrQdcount; q++)
andrewboyson 13:9cd54f7db57a 183 {
andrewboyson 13:9cd54f7db57a 184 if (scanQuery()) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 185 }
andrewboyson 13:9cd54f7db57a 186 for (int a = 0; a < DnsHdrAncount; a++)
andrewboyson 13:9cd54f7db57a 187 {
andrewboyson 13:9cd54f7db57a 188 if (scanAnswer()) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 189 readAnswer();
andrewboyson 32:679654f2d023 190 sendToDnsCache(dnsProtocol);
andrewboyson 13:9cd54f7db57a 191 }
andrewboyson 13:9cd54f7db57a 192
andrewboyson 13:9cd54f7db57a 193 return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 194 }