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 May 05 17:44:16 2017 +0000
Revision:
14:e75a59c1123d
Parent:
13:9cd54f7db57a
Child:
15:6ca6778168b1
Made IP addresses and ports available to debug messages

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