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:
Tue Nov 28 17:05:46 2017 +0000
Revision:
57:e0fb648acf48
Parent:
50:492f2d2954e4
Child:
58:d48c899e482f
Added TFTP

Who changed what in which revision?

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