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 Jan 19 19:00:18 2021 +0000
Revision:
188:57f44b620d0e
Parent:
187:122fc1996c86
Child:
189:e1c7990486c4
Net NR added eth and dns protocols to the received messages.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 172:9bc3c7b2cca1 1 #include <stdint.h>
andrewboyson 172:9bc3c7b2cca1 2 #include <stdbool.h>
andrewboyson 172:9bc3c7b2cca1 3 #include <string.h>
andrewboyson 172:9bc3c7b2cca1 4
andrewboyson 172:9bc3c7b2cca1 5 #include "log.h"
andrewboyson 172:9bc3c7b2cca1 6 #include "mstimer.h"
andrewboyson 172:9bc3c7b2cca1 7 #include "net.h"
andrewboyson 172:9bc3c7b2cca1 8 #include "eth.h"
andrewboyson 172:9bc3c7b2cca1 9 #include "mac.h"
andrewboyson 172:9bc3c7b2cca1 10 #include "dhcp.h"
andrewboyson 172:9bc3c7b2cca1 11 #include "dns.h"
andrewboyson 172:9bc3c7b2cca1 12 #include "dnsquery.h"
andrewboyson 172:9bc3c7b2cca1 13 #include "dnslabel.h"
andrewboyson 172:9bc3c7b2cca1 14 #include "http.h"
andrewboyson 182:ff48c6ea91c1 15 #include "ip6addr.h"
andrewboyson 182:ff48c6ea91c1 16 #include "ip4addr.h"
andrewboyson 182:ff48c6ea91c1 17 #include "nr.h"
andrewboyson 183:ee809769bf89 18 #include "ndp.h"
andrewboyson 172:9bc3c7b2cca1 19
andrewboyson 172:9bc3c7b2cca1 20 bool Nr4Trace = false; //Do not use
andrewboyson 172:9bc3c7b2cca1 21 bool NrTrace = false;
andrewboyson 172:9bc3c7b2cca1 22
andrewboyson 172:9bc3c7b2cca1 23 #define CACHE_TIMEOUT_MS 3600 * 1000
andrewboyson 172:9bc3c7b2cca1 24 #define STALE_TIMEOUT_MS 1800 * 1000
andrewboyson 172:9bc3c7b2cca1 25 #define EMPTY_TIMEOUT_MS 300 * 1000
andrewboyson 172:9bc3c7b2cca1 26 #define REPLY_TIMEOUT_MS 100
andrewboyson 172:9bc3c7b2cca1 27
andrewboyson 172:9bc3c7b2cca1 28 #define RECORDS_COUNT 50
andrewboyson 172:9bc3c7b2cca1 29
andrewboyson 172:9bc3c7b2cca1 30 #define STATE_EMPTY 0
andrewboyson 172:9bc3c7b2cca1 31 #define STATE_WANT 1
andrewboyson 172:9bc3c7b2cca1 32 #define STATE_WAIT_FOR_ETH 2
andrewboyson 172:9bc3c7b2cca1 33 #define STATE_WAIT_TIMEOUT 3
andrewboyson 172:9bc3c7b2cca1 34 #define STATE_VALID 4
andrewboyson 172:9bc3c7b2cca1 35
andrewboyson 182:ff48c6ea91c1 36 #define TODO_NONE 0
andrewboyson 182:ff48c6ea91c1 37 #define TODO_NAME_FROM_ADDRESS 1
andrewboyson 182:ff48c6ea91c1 38 #define TODO_ADDRESS_FROM_NAME 2
andrewboyson 182:ff48c6ea91c1 39
andrewboyson 182:ff48c6ea91c1 40 #define ADDR_TYPE_A 4
andrewboyson 182:ff48c6ea91c1 41 #define ADDR_TYPE_AAAA 6
andrewboyson 182:ff48c6ea91c1 42
andrewboyson 182:ff48c6ea91c1 43 char NrTest[NR_NAME_MAX_LENGTH];
andrewboyson 172:9bc3c7b2cca1 44
andrewboyson 172:9bc3c7b2cca1 45 struct record
andrewboyson 172:9bc3c7b2cca1 46 {
andrewboyson 182:ff48c6ea91c1 47 uint32_t replyMs; //Need this in addition to the ageMs for when refreshing an existing entry
andrewboyson 172:9bc3c7b2cca1 48 uint32_t ageMs;
andrewboyson 182:ff48c6ea91c1 49 union
andrewboyson 182:ff48c6ea91c1 50 {
andrewboyson 182:ff48c6ea91c1 51 uint32_t A;
andrewboyson 182:ff48c6ea91c1 52 uint8_t AAAA[16];
andrewboyson 182:ff48c6ea91c1 53 char address[16];
andrewboyson 182:ff48c6ea91c1 54 };
andrewboyson 182:ff48c6ea91c1 55 uint8_t addrType; //ADDR_TYPE_A (4) or ADDR_TYPE_AAAA (6)
andrewboyson 172:9bc3c7b2cca1 56 uint8_t todo;
andrewboyson 172:9bc3c7b2cca1 57 uint8_t state;
andrewboyson 172:9bc3c7b2cca1 58 uint8_t dnsProtocol;
andrewboyson 172:9bc3c7b2cca1 59 uint16_t ipProtocol;
andrewboyson 182:ff48c6ea91c1 60 char name[NR_NAME_MAX_LENGTH];
andrewboyson 172:9bc3c7b2cca1 61 };
andrewboyson 172:9bc3c7b2cca1 62 static struct record records[RECORDS_COUNT];
andrewboyson 172:9bc3c7b2cca1 63
andrewboyson 182:ff48c6ea91c1 64 static void addrClear(const uint8_t addrType, char* ip)
andrewboyson 182:ff48c6ea91c1 65 {
andrewboyson 182:ff48c6ea91c1 66 switch (addrType)
andrewboyson 182:ff48c6ea91c1 67 {
andrewboyson 182:ff48c6ea91c1 68 case ADDR_TYPE_A : *(uint32_t*)ip = 0; break;
andrewboyson 182:ff48c6ea91c1 69 case ADDR_TYPE_AAAA: Ip6AddrClear(ip); break;
andrewboyson 182:ff48c6ea91c1 70 default: LogTimeF("NR - addrClear - Unknown addrType %d\r\n", addrType); break;
andrewboyson 182:ff48c6ea91c1 71 }
andrewboyson 182:ff48c6ea91c1 72 }
andrewboyson 182:ff48c6ea91c1 73 static bool addrIsEmpty(const uint8_t addrType, const char* ip)
andrewboyson 182:ff48c6ea91c1 74 {
andrewboyson 182:ff48c6ea91c1 75 switch (addrType)
andrewboyson 182:ff48c6ea91c1 76 {
andrewboyson 182:ff48c6ea91c1 77 case ADDR_TYPE_A : return *(uint32_t*)ip == 0;
andrewboyson 182:ff48c6ea91c1 78 case ADDR_TYPE_AAAA: return Ip6AddrIsEmpty(ip);
andrewboyson 182:ff48c6ea91c1 79 default: return LogTimeF("NR - addrIsEmpty - Unknown addrType %d\r\n", addrType);
andrewboyson 182:ff48c6ea91c1 80 }
andrewboyson 182:ff48c6ea91c1 81 }
andrewboyson 182:ff48c6ea91c1 82 static int addrLog(uint8_t addrType, const char* ip)
andrewboyson 182:ff48c6ea91c1 83 {
andrewboyson 182:ff48c6ea91c1 84 switch (addrType)
andrewboyson 182:ff48c6ea91c1 85 {
andrewboyson 187:122fc1996c86 86 case ADDR_TYPE_A : return Ip4AddrLog(*(uint32_t*)ip);
andrewboyson 182:ff48c6ea91c1 87 case ADDR_TYPE_AAAA: return Ip6AddrLog(ip);
andrewboyson 182:ff48c6ea91c1 88 default: return LogTimeF("NR - addrLog - Unknown addrType %d\r\n", addrType);
andrewboyson 182:ff48c6ea91c1 89 }
andrewboyson 182:ff48c6ea91c1 90 }
andrewboyson 182:ff48c6ea91c1 91
andrewboyson 182:ff48c6ea91c1 92 static bool addrIsSame(uint8_t addrType, const char* ipA, const char* ipB)
andrewboyson 182:ff48c6ea91c1 93 {
andrewboyson 182:ff48c6ea91c1 94 switch (addrType)
andrewboyson 182:ff48c6ea91c1 95 {
andrewboyson 182:ff48c6ea91c1 96 case ADDR_TYPE_A : return *(uint32_t*)ipA == *(uint32_t*)ipB;
andrewboyson 182:ff48c6ea91c1 97 case ADDR_TYPE_AAAA: return Ip6AddrIsSame(ipA, ipB);
andrewboyson 182:ff48c6ea91c1 98 default: return LogTimeF("NR - addrIsSame - Unknown addrType %d\r\n", addrType);
andrewboyson 182:ff48c6ea91c1 99 }
andrewboyson 182:ff48c6ea91c1 100 }
andrewboyson 182:ff48c6ea91c1 101
andrewboyson 182:ff48c6ea91c1 102 static void addrCopy(uint8_t addrType, char* ipTo, const char* ipFrom)
andrewboyson 182:ff48c6ea91c1 103 {
andrewboyson 182:ff48c6ea91c1 104 switch (addrType)
andrewboyson 182:ff48c6ea91c1 105 {
andrewboyson 182:ff48c6ea91c1 106 case ADDR_TYPE_A : *(uint32_t*)ipTo = *(uint32_t*)ipFrom; break;
andrewboyson 182:ff48c6ea91c1 107 case ADDR_TYPE_AAAA: Ip6AddrCopy(ipTo, ipFrom); break;
andrewboyson 182:ff48c6ea91c1 108 default: LogTimeF("NR - addrCopy - Unknown addrType %d\r\n", addrType); break;
andrewboyson 182:ff48c6ea91c1 109 }
andrewboyson 182:ff48c6ea91c1 110 }
andrewboyson 182:ff48c6ea91c1 111
andrewboyson 182:ff48c6ea91c1 112 static int getExistingAddress(char* address, uint8_t addrType)
andrewboyson 172:9bc3c7b2cca1 113 {
andrewboyson 172:9bc3c7b2cca1 114 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 115 {
andrewboyson 172:9bc3c7b2cca1 116 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 117 if (records[i].addrType != addrType) continue;
andrewboyson 182:ff48c6ea91c1 118 if (addrIsSame(addrType, records[i].address, address)) return i;
andrewboyson 172:9bc3c7b2cca1 119 }
andrewboyson 172:9bc3c7b2cca1 120 return -1;
andrewboyson 172:9bc3c7b2cca1 121 }
andrewboyson 182:ff48c6ea91c1 122 static int getExistingName(char* name, uint8_t addrType)
andrewboyson 172:9bc3c7b2cca1 123 {
andrewboyson 172:9bc3c7b2cca1 124 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 125 {
andrewboyson 172:9bc3c7b2cca1 126 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 127 if (records[i].addrType != addrType) continue;
andrewboyson 182:ff48c6ea91c1 128 if (DnsLabelIsSame(records[i].name, name)) return i;
andrewboyson 182:ff48c6ea91c1 129 }
andrewboyson 182:ff48c6ea91c1 130 return -1;
andrewboyson 182:ff48c6ea91c1 131 }
andrewboyson 182:ff48c6ea91c1 132 static int getNameOnly(char* name, uint8_t addrType)
andrewboyson 182:ff48c6ea91c1 133 {
andrewboyson 182:ff48c6ea91c1 134 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 182:ff48c6ea91c1 135 {
andrewboyson 182:ff48c6ea91c1 136 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 137 if (records[i].addrType != addrType) continue;
andrewboyson 182:ff48c6ea91c1 138 if (!addrIsEmpty(records[i].addrType, records[i].address)) continue;
andrewboyson 172:9bc3c7b2cca1 139 if (DnsLabelIsSame(records[i].name, name)) return i;
andrewboyson 172:9bc3c7b2cca1 140 }
andrewboyson 172:9bc3c7b2cca1 141 return -1;
andrewboyson 172:9bc3c7b2cca1 142 }
andrewboyson 182:ff48c6ea91c1 143 static int getIpOnly(char* address, uint8_t addrType)
andrewboyson 172:9bc3c7b2cca1 144 {
andrewboyson 172:9bc3c7b2cca1 145 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 146 {
andrewboyson 172:9bc3c7b2cca1 147 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 148 if (records[i].addrType != addrType) continue;
andrewboyson 182:ff48c6ea91c1 149 if (records[i].name[0] != 0) continue;
andrewboyson 182:ff48c6ea91c1 150 if (addrIsSame(addrType, records[i].address, address)) return i;
andrewboyson 172:9bc3c7b2cca1 151 }
andrewboyson 172:9bc3c7b2cca1 152 return -1;
andrewboyson 172:9bc3c7b2cca1 153 }
andrewboyson 182:ff48c6ea91c1 154 static int getCorrespondingRequest(uint8_t addrType, char* address, char* name)
andrewboyson 172:9bc3c7b2cca1 155 {
andrewboyson 172:9bc3c7b2cca1 156 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 157 {
andrewboyson 172:9bc3c7b2cca1 158 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 159 if (records[i].addrType != addrType) continue;
andrewboyson 182:ff48c6ea91c1 160 if (records[i].name[0] == 0 && addrIsSame(addrType, records[i].address, address)) return i;
andrewboyson 182:ff48c6ea91c1 161 if (addrIsEmpty(records[i].addrType, records[i].address) && DnsLabelIsSame(records[i].name, name)) return i;
andrewboyson 182:ff48c6ea91c1 162 }
andrewboyson 182:ff48c6ea91c1 163 return -1;
andrewboyson 182:ff48c6ea91c1 164 }
andrewboyson 182:ff48c6ea91c1 165 static int getExistingEntry(uint8_t addrType, char* address, char* name)
andrewboyson 182:ff48c6ea91c1 166 {
andrewboyson 182:ff48c6ea91c1 167 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 182:ff48c6ea91c1 168 {
andrewboyson 182:ff48c6ea91c1 169 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 170 if (records[i].addrType != addrType) continue;
andrewboyson 182:ff48c6ea91c1 171 if ( addrIsSame(addrType, records[i].address, address) && DnsLabelIsSame(records[i].name, name)) return i;
andrewboyson 172:9bc3c7b2cca1 172 }
andrewboyson 172:9bc3c7b2cca1 173 return -1;
andrewboyson 172:9bc3c7b2cca1 174 }
andrewboyson 172:9bc3c7b2cca1 175 static int getOldest()
andrewboyson 172:9bc3c7b2cca1 176 {
andrewboyson 172:9bc3c7b2cca1 177 int iOldest = 0;
andrewboyson 172:9bc3c7b2cca1 178 uint32_t ageOldest = 0;
andrewboyson 172:9bc3c7b2cca1 179 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 180 {
andrewboyson 172:9bc3c7b2cca1 181 if (records[i].state == STATE_EMPTY) return i; //Found an empty slot so just return it
andrewboyson 172:9bc3c7b2cca1 182 uint32_t age = MsTimerCount - records[i].ageMs;
andrewboyson 172:9bc3c7b2cca1 183 if (age >= ageOldest)
andrewboyson 172:9bc3c7b2cca1 184 {
andrewboyson 172:9bc3c7b2cca1 185 ageOldest = age;
andrewboyson 172:9bc3c7b2cca1 186 iOldest = i;
andrewboyson 172:9bc3c7b2cca1 187 }
andrewboyson 172:9bc3c7b2cca1 188 }
andrewboyson 172:9bc3c7b2cca1 189 return iOldest; //Otherwise return the oldest
andrewboyson 172:9bc3c7b2cca1 190 }
andrewboyson 182:ff48c6ea91c1 191 static void makeRequestForNameFromAddress(uint8_t addrType, void* address )
andrewboyson 172:9bc3c7b2cca1 192 {
andrewboyson 172:9bc3c7b2cca1 193 //Don't treat non ips
andrewboyson 182:ff48c6ea91c1 194 if (addrIsEmpty(addrType, address)) return;
andrewboyson 172:9bc3c7b2cca1 195 int i;
andrewboyson 172:9bc3c7b2cca1 196
andrewboyson 172:9bc3c7b2cca1 197 //If a valid record already exists then request an update
andrewboyson 182:ff48c6ea91c1 198 i = getExistingAddress(address, addrType);
andrewboyson 172:9bc3c7b2cca1 199 if (i > -1)
andrewboyson 172:9bc3c7b2cca1 200 {
andrewboyson 172:9bc3c7b2cca1 201 if (records[i].state != STATE_VALID) return;
andrewboyson 172:9bc3c7b2cca1 202 if (records[i].name[0] == 0)
andrewboyson 172:9bc3c7b2cca1 203 {
andrewboyson 172:9bc3c7b2cca1 204 if (!MsTimerRelative(records[i].ageMs, EMPTY_TIMEOUT_MS)) return;
andrewboyson 172:9bc3c7b2cca1 205 }
andrewboyson 172:9bc3c7b2cca1 206 else
andrewboyson 172:9bc3c7b2cca1 207 {
andrewboyson 172:9bc3c7b2cca1 208 if (!MsTimerRelative(records[i].ageMs, STALE_TIMEOUT_MS)) return;
andrewboyson 172:9bc3c7b2cca1 209 }
andrewboyson 172:9bc3c7b2cca1 210 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 211 {
andrewboyson 188:57f44b620d0e 212 LogTimeF("NR -- record %d - renew name of ", i);
andrewboyson 182:ff48c6ea91c1 213 addrLog(addrType, address);
andrewboyson 172:9bc3c7b2cca1 214 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 215 }
andrewboyson 172:9bc3c7b2cca1 216 //Leave the address as is
andrewboyson 172:9bc3c7b2cca1 217 //Leave the name as is
andrewboyson 172:9bc3c7b2cca1 218 //Leave age as is
andrewboyson 172:9bc3c7b2cca1 219 }
andrewboyson 172:9bc3c7b2cca1 220 else
andrewboyson 172:9bc3c7b2cca1 221 {
andrewboyson 172:9bc3c7b2cca1 222 //If a record does not exist then find the first empty slot and add the IP and date
andrewboyson 188:57f44b620d0e 223 i = getOldest();
andrewboyson 172:9bc3c7b2cca1 224 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 225 {
andrewboyson 188:57f44b620d0e 226 LogTimeF("NR -- record %d - request name of ", i);
andrewboyson 182:ff48c6ea91c1 227 addrLog(addrType, address);
andrewboyson 172:9bc3c7b2cca1 228 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 229 }
andrewboyson 182:ff48c6ea91c1 230 addrCopy(addrType, records[i].address, address); //Set the address
andrewboyson 182:ff48c6ea91c1 231 records[i].name[0] = 0; //Clear the name
andrewboyson 182:ff48c6ea91c1 232 records[i].ageMs = MsTimerCount; //Start age
andrewboyson 172:9bc3c7b2cca1 233 }
andrewboyson 172:9bc3c7b2cca1 234 records[i].todo = TODO_NAME_FROM_ADDRESS;
andrewboyson 182:ff48c6ea91c1 235 records[i].addrType = addrType;
andrewboyson 172:9bc3c7b2cca1 236 records[i].state = STATE_WANT;
andrewboyson 172:9bc3c7b2cca1 237 records[i].replyMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 238 records[i].ipProtocol = ETH_NONE;
andrewboyson 172:9bc3c7b2cca1 239 records[i].dnsProtocol = DNS_PROTOCOL_NONE;
andrewboyson 172:9bc3c7b2cca1 240 }
andrewboyson 182:ff48c6ea91c1 241 static void makeRequestForAddressFromName(char* name, uint8_t addrType)
andrewboyson 172:9bc3c7b2cca1 242 {
andrewboyson 172:9bc3c7b2cca1 243 //Don't treat non names
andrewboyson 172:9bc3c7b2cca1 244 if (!name[0]) return;
andrewboyson 172:9bc3c7b2cca1 245 int i;
andrewboyson 172:9bc3c7b2cca1 246
andrewboyson 172:9bc3c7b2cca1 247 //If a valid record already exists then request an update
andrewboyson 182:ff48c6ea91c1 248 i = getExistingName(name, addrType);
andrewboyson 172:9bc3c7b2cca1 249 if (i > -1)
andrewboyson 172:9bc3c7b2cca1 250 {
andrewboyson 172:9bc3c7b2cca1 251 if (records[i].state != STATE_VALID) return;
andrewboyson 182:ff48c6ea91c1 252 if (addrIsEmpty(records[i].addrType, records[i].address))
andrewboyson 172:9bc3c7b2cca1 253 {
andrewboyson 172:9bc3c7b2cca1 254 if (!MsTimerRelative(records[i].ageMs, EMPTY_TIMEOUT_MS)) return;
andrewboyson 172:9bc3c7b2cca1 255 }
andrewboyson 172:9bc3c7b2cca1 256 else
andrewboyson 172:9bc3c7b2cca1 257 {
andrewboyson 172:9bc3c7b2cca1 258 if (!MsTimerRelative(records[i].ageMs, STALE_TIMEOUT_MS)) return;
andrewboyson 172:9bc3c7b2cca1 259 }
andrewboyson 172:9bc3c7b2cca1 260 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 261 {
andrewboyson 188:57f44b620d0e 262 if (addrType == ADDR_TYPE_A) LogTimeF("NR -- record %d - renew A of %s\r\n", i, name);
andrewboyson 188:57f44b620d0e 263 else LogTimeF("NR -- record %d - renew AAAA of %s\r\n", i, name);
andrewboyson 172:9bc3c7b2cca1 264 }
andrewboyson 172:9bc3c7b2cca1 265 //Leave name as is
andrewboyson 172:9bc3c7b2cca1 266 //Leave the address as is
andrewboyson 172:9bc3c7b2cca1 267 //Leave age as is
andrewboyson 172:9bc3c7b2cca1 268 }
andrewboyson 172:9bc3c7b2cca1 269 else
andrewboyson 172:9bc3c7b2cca1 270 {
andrewboyson 172:9bc3c7b2cca1 271 //If a record does not exist then find the first empty slot and add the name and date
andrewboyson 188:57f44b620d0e 272 i = getOldest();
andrewboyson 172:9bc3c7b2cca1 273 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 274 {
andrewboyson 188:57f44b620d0e 275 if (addrType == ADDR_TYPE_A) LogTimeF("NR -- record %d - request A of %s\r\n", i, name);
andrewboyson 188:57f44b620d0e 276 else LogTimeF("NR -- record %d - request AAAA of %s\r\n", i, name);
andrewboyson 172:9bc3c7b2cca1 277 }
andrewboyson 183:ee809769bf89 278 strncpy(records[i].name, name, NR_NAME_MAX_LENGTH); //Set the name
andrewboyson 182:ff48c6ea91c1 279 records[i].name[NR_NAME_MAX_LENGTH - 1] = 0;
andrewboyson 183:ee809769bf89 280 addrClear(addrType, records[i].address); //Clear the address
andrewboyson 182:ff48c6ea91c1 281 records[i].ageMs = MsTimerCount; //Start age
andrewboyson 172:9bc3c7b2cca1 282 }
andrewboyson 182:ff48c6ea91c1 283 records[i].todo = TODO_ADDRESS_FROM_NAME;
andrewboyson 182:ff48c6ea91c1 284 records[i].addrType = addrType;
andrewboyson 172:9bc3c7b2cca1 285 records[i].state = STATE_WANT;
andrewboyson 172:9bc3c7b2cca1 286 records[i].replyMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 287 records[i].ipProtocol = ETH_NONE;
andrewboyson 172:9bc3c7b2cca1 288 records[i].dnsProtocol = DNS_PROTOCOL_NONE;
andrewboyson 172:9bc3c7b2cca1 289 }
andrewboyson 182:ff48c6ea91c1 290 static void updateRecord(int i, char* address, uint8_t addrType, char* name, int dnsProtocol, int ipProtocol)
andrewboyson 172:9bc3c7b2cca1 291 {
andrewboyson 172:9bc3c7b2cca1 292 records[i].todo = TODO_NONE;
andrewboyson 172:9bc3c7b2cca1 293 records[i].ageMs = MsTimerCount;
andrewboyson 182:ff48c6ea91c1 294 records[i].addrType = addrType;
andrewboyson 182:ff48c6ea91c1 295 addrCopy(addrType, records[i].address, address);
andrewboyson 172:9bc3c7b2cca1 296 records[i].dnsProtocol = dnsProtocol;
andrewboyson 172:9bc3c7b2cca1 297 records[i].ipProtocol = ipProtocol;
andrewboyson 172:9bc3c7b2cca1 298 records[i].state = STATE_VALID;
andrewboyson 182:ff48c6ea91c1 299 strncpy(records[i].name, name, NR_NAME_MAX_LENGTH);
andrewboyson 182:ff48c6ea91c1 300 records[i].name[NR_NAME_MAX_LENGTH - 1] = 0;
andrewboyson 172:9bc3c7b2cca1 301 }
andrewboyson 182:ff48c6ea91c1 302 void addEntry(uint8_t addrType, void* address, char* name, int dnsProtocol, int ipProtocol)
andrewboyson 182:ff48c6ea91c1 303 {
andrewboyson 172:9bc3c7b2cca1 304 int i;
andrewboyson 172:9bc3c7b2cca1 305
andrewboyson 172:9bc3c7b2cca1 306 //Print what is being handled
andrewboyson 172:9bc3c7b2cca1 307 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 308 {
andrewboyson 172:9bc3c7b2cca1 309 LogTimeF("NR - received ");
andrewboyson 188:57f44b620d0e 310 EthProtocolLog(ipProtocol);
andrewboyson 188:57f44b620d0e 311 Log(" ");
andrewboyson 188:57f44b620d0e 312 DnsProtocolLog(dnsProtocol);
andrewboyson 188:57f44b620d0e 313 Log(" ");
andrewboyson 182:ff48c6ea91c1 314 addrLog(addrType, address);
andrewboyson 172:9bc3c7b2cca1 315 Log(" == '");
andrewboyson 172:9bc3c7b2cca1 316 Log(name);
andrewboyson 172:9bc3c7b2cca1 317 Log("'\r\n");
andrewboyson 172:9bc3c7b2cca1 318 }
andrewboyson 172:9bc3c7b2cca1 319
andrewboyson 172:9bc3c7b2cca1 320 //Ignore records which do not have both address and name
andrewboyson 182:ff48c6ea91c1 321 if (addrIsEmpty(addrType, address) || name == 0 || name[0] == 0)
andrewboyson 172:9bc3c7b2cca1 322 {
andrewboyson 172:9bc3c7b2cca1 323 if (NrTrace) LogTimeF("NR -- ignoring invalid entry\r\n");
andrewboyson 172:9bc3c7b2cca1 324 return;
andrewboyson 172:9bc3c7b2cca1 325 }
andrewboyson 186:24198369b198 326 //Ignore records with the name 'UNKNOWN'
andrewboyson 186:24198369b198 327 if (strcmp(name, "UNKNOWN") == 0) return;
andrewboyson 172:9bc3c7b2cca1 328
andrewboyson 182:ff48c6ea91c1 329 i = getExistingEntry(addrType, address, name);
andrewboyson 172:9bc3c7b2cca1 330 if (i >= 0)
andrewboyson 182:ff48c6ea91c1 331 {
andrewboyson 182:ff48c6ea91c1 332 updateRecord(i, address, addrType, name, dnsProtocol, ipProtocol);
andrewboyson 182:ff48c6ea91c1 333 if (NrTrace) LogTimeF("NR -- record %d - refresh existing entry\r\n", i);
andrewboyson 182:ff48c6ea91c1 334 return;
andrewboyson 182:ff48c6ea91c1 335 }
andrewboyson 182:ff48c6ea91c1 336
andrewboyson 182:ff48c6ea91c1 337 i = getCorrespondingRequest(addrType, address, name);
andrewboyson 182:ff48c6ea91c1 338 if (i >= 0)
andrewboyson 182:ff48c6ea91c1 339 {
andrewboyson 182:ff48c6ea91c1 340 updateRecord(i, address, addrType, name, dnsProtocol, ipProtocol);
andrewboyson 182:ff48c6ea91c1 341 if (NrTrace) LogTimeF("NR -- record %d - replace request with new entry\r\n", i);
andrewboyson 182:ff48c6ea91c1 342 i = getCorrespondingRequest(addrType, address, name);
andrewboyson 172:9bc3c7b2cca1 343 if (i >= 0)
andrewboyson 172:9bc3c7b2cca1 344 {
andrewboyson 182:ff48c6ea91c1 345 if (NrTrace) LogTimeF("NR -- record %d - clear duplicate request\r\n", i, name);
andrewboyson 172:9bc3c7b2cca1 346 records[i].state = STATE_EMPTY;
andrewboyson 172:9bc3c7b2cca1 347 }
andrewboyson 172:9bc3c7b2cca1 348 return;
andrewboyson 172:9bc3c7b2cca1 349 }
andrewboyson 172:9bc3c7b2cca1 350
andrewboyson 172:9bc3c7b2cca1 351 //No other entry exists so just add it to the next available space
andrewboyson 172:9bc3c7b2cca1 352 i = getOldest();
andrewboyson 182:ff48c6ea91c1 353 if (NrTrace) LogTimeF("NR -- record %d - add entry\r\n", i);
andrewboyson 182:ff48c6ea91c1 354 updateRecord(i, address, addrType, name, dnsProtocol, ipProtocol);
andrewboyson 172:9bc3c7b2cca1 355 }
andrewboyson 182:ff48c6ea91c1 356 static void addressToName(uint8_t addrType, void* address, char* name)
andrewboyson 172:9bc3c7b2cca1 357 {
andrewboyson 172:9bc3c7b2cca1 358 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 359 {
andrewboyson 172:9bc3c7b2cca1 360 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 361 if (addrIsSame(addrType, records[i].address, address))
andrewboyson 172:9bc3c7b2cca1 362 {
andrewboyson 172:9bc3c7b2cca1 363 strcpy(name, records[i].name);
andrewboyson 172:9bc3c7b2cca1 364 return;
andrewboyson 172:9bc3c7b2cca1 365 }
andrewboyson 172:9bc3c7b2cca1 366 }
andrewboyson 172:9bc3c7b2cca1 367 name[0] = 0;
andrewboyson 172:9bc3c7b2cca1 368 }
andrewboyson 182:ff48c6ea91c1 369 static void nameToAddress(char* name, uint8_t addrType, void* address)
andrewboyson 172:9bc3c7b2cca1 370 {
andrewboyson 172:9bc3c7b2cca1 371 uint32_t newest = 0xFFFFFFFF;
andrewboyson 182:ff48c6ea91c1 372 addrClear(addrType, address);
andrewboyson 172:9bc3c7b2cca1 373 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 374 {
andrewboyson 172:9bc3c7b2cca1 375 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 376 if (records[i].addrType != addrType) continue;
andrewboyson 182:ff48c6ea91c1 377 if(addrIsEmpty(records[i].addrType, records[i].address)) continue;
andrewboyson 172:9bc3c7b2cca1 378 if (!DnsLabelIsSame(records[i].name, name)) continue;
andrewboyson 172:9bc3c7b2cca1 379 uint32_t age = MsTimerCount - records[i].ageMs;
andrewboyson 172:9bc3c7b2cca1 380 if (age <= newest)
andrewboyson 172:9bc3c7b2cca1 381 {
andrewboyson 172:9bc3c7b2cca1 382 newest = age;
andrewboyson 182:ff48c6ea91c1 383 addrCopy(addrType, address, records[i].address);
andrewboyson 172:9bc3c7b2cca1 384 }
andrewboyson 172:9bc3c7b2cca1 385 }
andrewboyson 172:9bc3c7b2cca1 386 }
andrewboyson 182:ff48c6ea91c1 387 void NrMakeRequestForNameFromAddress6(char* pAddress) { makeRequestForNameFromAddress(ADDR_TYPE_AAAA, pAddress); }
andrewboyson 182:ff48c6ea91c1 388 void NrMakeRequestForNameFromAddress4(uint32_t address) { makeRequestForNameFromAddress(ADDR_TYPE_A, &address); }
andrewboyson 182:ff48c6ea91c1 389 void NrMakeRequestForAddress6FromName(char* name) { makeRequestForAddressFromName(name, ADDR_TYPE_AAAA); }
andrewboyson 182:ff48c6ea91c1 390 void NrMakeRequestForAddress4FromName(char* name) { makeRequestForAddressFromName(name, ADDR_TYPE_A ); }
andrewboyson 182:ff48c6ea91c1 391 void NrAddAddress6(char* pAddress, char* name, int dnsProtocol) { addEntry(ADDR_TYPE_AAAA, pAddress, name, dnsProtocol, EthProtocol); }
andrewboyson 182:ff48c6ea91c1 392 void NrAddAddress4(uint32_t address, char* name, int dnsProtocol) { addEntry(ADDR_TYPE_A, &address, name, dnsProtocol, EthProtocol); }
andrewboyson 182:ff48c6ea91c1 393 void NrNameToAddress6(char* name, char* address) { nameToAddress(name, ADDR_TYPE_AAAA, address); }
andrewboyson 182:ff48c6ea91c1 394 void NrNameToAddress4(char* name, uint32_t* pAddress) { nameToAddress(name, ADDR_TYPE_A, pAddress); }
andrewboyson 182:ff48c6ea91c1 395 void NrAddress6ToName(char* pAddress, char* name) { addressToName(ADDR_TYPE_AAAA, pAddress, name); }
andrewboyson 182:ff48c6ea91c1 396 void NrAddress4ToName(uint32_t address, char* name) { addressToName(ADDR_TYPE_A, &address, name); }
andrewboyson 182:ff48c6ea91c1 397
andrewboyson 172:9bc3c7b2cca1 398 static char letterFromStateAndProtocol(uint8_t dnsState, uint8_t dnsProtocol, uint16_t ipProtocol)
andrewboyson 172:9bc3c7b2cca1 399 {
andrewboyson 172:9bc3c7b2cca1 400 switch (dnsState)
andrewboyson 172:9bc3c7b2cca1 401 {
andrewboyson 172:9bc3c7b2cca1 402 case STATE_WANT: return '}';
andrewboyson 172:9bc3c7b2cca1 403 case STATE_WAIT_FOR_ETH: return ']';
andrewboyson 172:9bc3c7b2cca1 404 case STATE_WAIT_TIMEOUT: return '>';
andrewboyson 172:9bc3c7b2cca1 405
andrewboyson 172:9bc3c7b2cca1 406 case STATE_VALID:
andrewboyson 172:9bc3c7b2cca1 407 switch (dnsProtocol)
andrewboyson 172:9bc3c7b2cca1 408 {
andrewboyson 172:9bc3c7b2cca1 409 case DNS_PROTOCOL_UDNS: if (ipProtocol == ETH_IPV4) return 'd' ; else return 'D';
andrewboyson 172:9bc3c7b2cca1 410 case DNS_PROTOCOL_MDNS: if (ipProtocol == ETH_IPV4) return 'm' ; else return 'M';
andrewboyson 172:9bc3c7b2cca1 411 case DNS_PROTOCOL_LLMNR: if (ipProtocol == ETH_IPV4) return 'l' ; else return 'L';
andrewboyson 172:9bc3c7b2cca1 412 case DNS_PROTOCOL_NONE: return '-';
andrewboyson 172:9bc3c7b2cca1 413 default: return '?';
andrewboyson 172:9bc3c7b2cca1 414 }
andrewboyson 172:9bc3c7b2cca1 415 default: return '~';
andrewboyson 172:9bc3c7b2cca1 416 }
andrewboyson 172:9bc3c7b2cca1 417 }
andrewboyson 172:9bc3c7b2cca1 418 void NrSendAjax()
andrewboyson 172:9bc3c7b2cca1 419 {
andrewboyson 172:9bc3c7b2cca1 420 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 421 {
andrewboyson 172:9bc3c7b2cca1 422 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 423 if (!addrIsEmpty(records[i].addrType, records[i].address) || records[i].name[0])
andrewboyson 172:9bc3c7b2cca1 424 {
andrewboyson 172:9bc3c7b2cca1 425 HttpAddByteAsHex(i);
andrewboyson 172:9bc3c7b2cca1 426 HttpAddChar('\t');
andrewboyson 172:9bc3c7b2cca1 427 HttpAddInt32AsHex(MsTimerCount - records[i].ageMs);
andrewboyson 172:9bc3c7b2cca1 428 HttpAddChar('\t');
andrewboyson 182:ff48c6ea91c1 429 HttpAddNibbleAsHex(records[i].addrType);
andrewboyson 182:ff48c6ea91c1 430 HttpAddChar('\t');
andrewboyson 182:ff48c6ea91c1 431 switch (records[i].addrType)
andrewboyson 182:ff48c6ea91c1 432 {
andrewboyson 182:ff48c6ea91c1 433 case ADDR_TYPE_A:
andrewboyson 182:ff48c6ea91c1 434 {
andrewboyson 182:ff48c6ea91c1 435 HttpAddInt32AsHex(records[i].A);
andrewboyson 182:ff48c6ea91c1 436 break;
andrewboyson 182:ff48c6ea91c1 437 }
andrewboyson 182:ff48c6ea91c1 438 case ADDR_TYPE_AAAA:
andrewboyson 182:ff48c6ea91c1 439 for (int b = 0; b < 16; b++) HttpAddByteAsHex(records[i].AAAA[b]);
andrewboyson 182:ff48c6ea91c1 440 break;
andrewboyson 182:ff48c6ea91c1 441 }
andrewboyson 172:9bc3c7b2cca1 442 HttpAddChar('\t');
andrewboyson 172:9bc3c7b2cca1 443 HttpAddChar(letterFromStateAndProtocol(records[i].state, records[i].dnsProtocol, records[i].ipProtocol));
andrewboyson 172:9bc3c7b2cca1 444 HttpAddChar('\t');
andrewboyson 172:9bc3c7b2cca1 445 HttpAddText(records[i].name);
andrewboyson 172:9bc3c7b2cca1 446 HttpAddChar('\n');
andrewboyson 172:9bc3c7b2cca1 447 }
andrewboyson 172:9bc3c7b2cca1 448 }
andrewboyson 172:9bc3c7b2cca1 449 }
andrewboyson 172:9bc3c7b2cca1 450 static void clearCache(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 451 {
andrewboyson 172:9bc3c7b2cca1 452 if (MsTimerRelative(pr->ageMs, CACHE_TIMEOUT_MS)) pr->state = STATE_EMPTY;
andrewboyson 172:9bc3c7b2cca1 453 }
andrewboyson 172:9bc3c7b2cca1 454 static void queryNameFromIp(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 455 {
andrewboyson 182:ff48c6ea91c1 456 if (addrIsEmpty(pr->addrType, pr->address))
andrewboyson 176:7eb916c22084 457 {
andrewboyson 188:57f44b620d0e 458 LogTimeF("NR -- record %d - queryNameFromIp has no address\r\n", pr - records);
andrewboyson 176:7eb916c22084 459 return;
andrewboyson 176:7eb916c22084 460 }
andrewboyson 172:9bc3c7b2cca1 461 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 462 {
andrewboyson 188:57f44b620d0e 463 LogTimeF("NR -- record %d - send ", pr - records);
andrewboyson 172:9bc3c7b2cca1 464 EthProtocolLog(pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 465 Log(" ");
andrewboyson 172:9bc3c7b2cca1 466 DnsProtocolLog(pr->dnsProtocol);
andrewboyson 172:9bc3c7b2cca1 467 Log(" request for name of ");
andrewboyson 182:ff48c6ea91c1 468 addrLog(pr->addrType, pr->address);
andrewboyson 172:9bc3c7b2cca1 469 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 470 }
andrewboyson 182:ff48c6ea91c1 471 if (pr->addrType == ADDR_TYPE_A)
andrewboyson 172:9bc3c7b2cca1 472 {
andrewboyson 182:ff48c6ea91c1 473 //uint32_t address4 = addrToIp4(pr->address);
andrewboyson 182:ff48c6ea91c1 474 DnsQueryNameFromIp4(pr->A, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 475 }
andrewboyson 172:9bc3c7b2cca1 476 else
andrewboyson 172:9bc3c7b2cca1 477 {
andrewboyson 172:9bc3c7b2cca1 478 DnsQueryNameFromIp6(pr->address, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 479 }
andrewboyson 172:9bc3c7b2cca1 480 }
andrewboyson 182:ff48c6ea91c1 481 static void queryIpFromName(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 482 {
andrewboyson 172:9bc3c7b2cca1 483 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 484 {
andrewboyson 188:57f44b620d0e 485 LogTimeF("NR -- record %d - send ", pr - records);
andrewboyson 172:9bc3c7b2cca1 486 EthProtocolLog(pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 487 Log(" ");
andrewboyson 172:9bc3c7b2cca1 488 DnsProtocolLog(pr->dnsProtocol);
andrewboyson 182:ff48c6ea91c1 489 if (pr->addrType == ADDR_TYPE_A) Log(" request for A of name '");
andrewboyson 182:ff48c6ea91c1 490 else Log(" request for AAAA of name '");
andrewboyson 172:9bc3c7b2cca1 491 Log(pr->name);
andrewboyson 172:9bc3c7b2cca1 492 Log("'\r\n");
andrewboyson 172:9bc3c7b2cca1 493 }
andrewboyson 182:ff48c6ea91c1 494 if (pr->addrType == ADDR_TYPE_A) DnsQueryIp4FromName(pr->name, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 182:ff48c6ea91c1 495 else DnsQueryIp6FromName(pr->name, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 496 }
andrewboyson 183:ee809769bf89 497 static bool getIsExternal(struct record* pr)
andrewboyson 183:ee809769bf89 498 {
andrewboyson 183:ee809769bf89 499 switch(pr->todo)
andrewboyson 183:ee809769bf89 500 {
andrewboyson 183:ee809769bf89 501 case TODO_NAME_FROM_ADDRESS:
andrewboyson 183:ee809769bf89 502
andrewboyson 183:ee809769bf89 503 if (pr->addrType == ADDR_TYPE_AAAA)
andrewboyson 183:ee809769bf89 504 {
andrewboyson 187:122fc1996c86 505 return Ip6AddrIsExternal((char*)pr->AAAA);
andrewboyson 183:ee809769bf89 506 }
andrewboyson 183:ee809769bf89 507 else
andrewboyson 183:ee809769bf89 508 {
andrewboyson 187:122fc1996c86 509 return Ip4AddrIsExternal(pr->A);
andrewboyson 183:ee809769bf89 510 }
andrewboyson 183:ee809769bf89 511 case TODO_ADDRESS_FROM_NAME:
andrewboyson 183:ee809769bf89 512 return DnsLabelIsExternal(pr->name);
andrewboyson 183:ee809769bf89 513 default:
andrewboyson 183:ee809769bf89 514 LogTimeF("NR - getIsExternal - undefined todo '%d'\r\n", pr->todo);
andrewboyson 183:ee809769bf89 515 return false;
andrewboyson 183:ee809769bf89 516 }
andrewboyson 183:ee809769bf89 517 }
andrewboyson 183:ee809769bf89 518 static bool protocolIsAvailable(struct record* pr)
andrewboyson 183:ee809769bf89 519 {
andrewboyson 183:ee809769bf89 520 bool isExternal = getIsExternal(pr);
andrewboyson 183:ee809769bf89 521 switch(pr->dnsProtocol)
andrewboyson 183:ee809769bf89 522 {
andrewboyson 183:ee809769bf89 523 case DNS_PROTOCOL_MDNS: return !isExternal;
andrewboyson 183:ee809769bf89 524 case DNS_PROTOCOL_LLMNR: return !isExternal;
andrewboyson 183:ee809769bf89 525 case DNS_PROTOCOL_UDNS:
andrewboyson 183:ee809769bf89 526 if (pr->ipProtocol == ETH_IPV6)
andrewboyson 183:ee809769bf89 527 {
andrewboyson 183:ee809769bf89 528 if (Ip6AddrIsEmpty(NdpDnsServer)) return false; //No DNS server so not ok
andrewboyson 183:ee809769bf89 529 if (isExternal) return true; //External and have DNS server so ok
andrewboyson 183:ee809769bf89 530 return false; //Internal but have no DHCP6 domain name so not ok
andrewboyson 183:ee809769bf89 531 }
andrewboyson 183:ee809769bf89 532 else //ETH_IPV4
andrewboyson 183:ee809769bf89 533 {
andrewboyson 183:ee809769bf89 534 if (DhcpDnsServerIp == 0) return false; //No DNS server so not ok
andrewboyson 183:ee809769bf89 535 if (isExternal) return true; //External and have DNS server so ok
andrewboyson 183:ee809769bf89 536 return DhcpDomainName[0] != 0; //Internal and have domain name so ok
andrewboyson 183:ee809769bf89 537 }
andrewboyson 183:ee809769bf89 538 case DNS_PROTOCOL_NONE: return true; //No protocol is valid as it designates 'not found'
andrewboyson 183:ee809769bf89 539 default: return false;
andrewboyson 183:ee809769bf89 540 }
andrewboyson 183:ee809769bf89 541 }
andrewboyson 172:9bc3c7b2cca1 542 static void makeNextProtocol(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 543 {
andrewboyson 172:9bc3c7b2cca1 544 //If current protocol is empty or unknown then return with the first.
andrewboyson 172:9bc3c7b2cca1 545 switch (pr->ipProtocol)
andrewboyson 172:9bc3c7b2cca1 546 {
andrewboyson 172:9bc3c7b2cca1 547 case ETH_IPV6: break;
andrewboyson 172:9bc3c7b2cca1 548 case ETH_IPV4: break;
andrewboyson 172:9bc3c7b2cca1 549 default:
andrewboyson 172:9bc3c7b2cca1 550 pr->ipProtocol = ETH_IPV6;
andrewboyson 172:9bc3c7b2cca1 551 pr->dnsProtocol = DNS_PROTOCOL_MDNS;
andrewboyson 172:9bc3c7b2cca1 552 return;
andrewboyson 172:9bc3c7b2cca1 553 }
andrewboyson 172:9bc3c7b2cca1 554 switch (pr->dnsProtocol)
andrewboyson 172:9bc3c7b2cca1 555 {
andrewboyson 172:9bc3c7b2cca1 556 case DNS_PROTOCOL_MDNS: break;
andrewboyson 172:9bc3c7b2cca1 557 case DNS_PROTOCOL_LLMNR: break;
andrewboyson 172:9bc3c7b2cca1 558 case DNS_PROTOCOL_UDNS: break;
andrewboyson 172:9bc3c7b2cca1 559 default:
andrewboyson 172:9bc3c7b2cca1 560 pr->ipProtocol = ETH_IPV6;
andrewboyson 172:9bc3c7b2cca1 561 pr->dnsProtocol = DNS_PROTOCOL_MDNS;
andrewboyson 172:9bc3c7b2cca1 562 return;
andrewboyson 172:9bc3c7b2cca1 563
andrewboyson 172:9bc3c7b2cca1 564 }
andrewboyson 172:9bc3c7b2cca1 565 switch(pr->dnsProtocol)
andrewboyson 172:9bc3c7b2cca1 566 {
andrewboyson 172:9bc3c7b2cca1 567 case DNS_PROTOCOL_MDNS:
andrewboyson 172:9bc3c7b2cca1 568 if (pr->ipProtocol == ETH_IPV6)
andrewboyson 172:9bc3c7b2cca1 569 {
andrewboyson 172:9bc3c7b2cca1 570 pr->ipProtocol = ETH_IPV4;
andrewboyson 172:9bc3c7b2cca1 571 }
andrewboyson 172:9bc3c7b2cca1 572 else
andrewboyson 172:9bc3c7b2cca1 573 {
andrewboyson 172:9bc3c7b2cca1 574 pr->ipProtocol = ETH_IPV6;
andrewboyson 172:9bc3c7b2cca1 575 pr->dnsProtocol = DNS_PROTOCOL_LLMNR;
andrewboyson 172:9bc3c7b2cca1 576 }
andrewboyson 172:9bc3c7b2cca1 577 break;
andrewboyson 172:9bc3c7b2cca1 578 case DNS_PROTOCOL_LLMNR:
andrewboyson 172:9bc3c7b2cca1 579 if (pr->ipProtocol == ETH_IPV6)
andrewboyson 172:9bc3c7b2cca1 580 {
andrewboyson 172:9bc3c7b2cca1 581 pr->ipProtocol = ETH_IPV4;
andrewboyson 172:9bc3c7b2cca1 582 }
andrewboyson 172:9bc3c7b2cca1 583 else
andrewboyson 172:9bc3c7b2cca1 584 {
andrewboyson 172:9bc3c7b2cca1 585 pr->ipProtocol = ETH_IPV6;
andrewboyson 172:9bc3c7b2cca1 586 pr->dnsProtocol = DNS_PROTOCOL_UDNS;
andrewboyson 172:9bc3c7b2cca1 587 }
andrewboyson 172:9bc3c7b2cca1 588 break;
andrewboyson 172:9bc3c7b2cca1 589 case DNS_PROTOCOL_UDNS:
andrewboyson 172:9bc3c7b2cca1 590 if (pr->ipProtocol == ETH_IPV6)
andrewboyson 172:9bc3c7b2cca1 591 {
andrewboyson 172:9bc3c7b2cca1 592 pr->ipProtocol = ETH_IPV4;
andrewboyson 172:9bc3c7b2cca1 593 }
andrewboyson 172:9bc3c7b2cca1 594 else
andrewboyson 172:9bc3c7b2cca1 595 {
andrewboyson 172:9bc3c7b2cca1 596 pr->ipProtocol = ETH_NONE;
andrewboyson 172:9bc3c7b2cca1 597 pr->dnsProtocol = DNS_PROTOCOL_NONE;
andrewboyson 172:9bc3c7b2cca1 598 }
andrewboyson 172:9bc3c7b2cca1 599 break;
andrewboyson 172:9bc3c7b2cca1 600 }
andrewboyson 172:9bc3c7b2cca1 601 }
andrewboyson 172:9bc3c7b2cca1 602
andrewboyson 172:9bc3c7b2cca1 603 static void sendRequest(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 604 {
andrewboyson 172:9bc3c7b2cca1 605 if (DnsQueryIsBusy) return;
andrewboyson 172:9bc3c7b2cca1 606
andrewboyson 172:9bc3c7b2cca1 607 switch (pr->state)
andrewboyson 172:9bc3c7b2cca1 608 {
andrewboyson 172:9bc3c7b2cca1 609 case STATE_WANT:
andrewboyson 172:9bc3c7b2cca1 610 makeNextProtocol(pr);
andrewboyson 183:ee809769bf89 611 while (!protocolIsAvailable(pr)) makeNextProtocol(pr);
andrewboyson 172:9bc3c7b2cca1 612 if (!pr->dnsProtocol || !pr->ipProtocol) //No more protocols to try so resolution has failed
andrewboyson 172:9bc3c7b2cca1 613 {
andrewboyson 172:9bc3c7b2cca1 614 if (pr->todo == TODO_NAME_FROM_ADDRESS)
andrewboyson 172:9bc3c7b2cca1 615 {
andrewboyson 172:9bc3c7b2cca1 616 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 617 {
andrewboyson 183:ee809769bf89 618 LogTimeF("NR - record %d - request for name of ", pr - records);
andrewboyson 182:ff48c6ea91c1 619 addrLog(pr->addrType, pr->address);
andrewboyson 172:9bc3c7b2cca1 620 Log(" has timed out\r\n");
andrewboyson 172:9bc3c7b2cca1 621 }
andrewboyson 172:9bc3c7b2cca1 622 pr->name[0] = 0;
andrewboyson 172:9bc3c7b2cca1 623 }
andrewboyson 182:ff48c6ea91c1 624 if (pr->todo == TODO_ADDRESS_FROM_NAME)
andrewboyson 172:9bc3c7b2cca1 625 {
andrewboyson 172:9bc3c7b2cca1 626 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 627 {
andrewboyson 183:ee809769bf89 628 LogTimeF("NR - record %d request for address of '", pr - records);
andrewboyson 172:9bc3c7b2cca1 629 Log(pr->name);
andrewboyson 172:9bc3c7b2cca1 630 Log("' has timed out\r\n");
andrewboyson 172:9bc3c7b2cca1 631 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 632 }
andrewboyson 182:ff48c6ea91c1 633 addrClear(pr->addrType, pr->address);
andrewboyson 172:9bc3c7b2cca1 634 }
andrewboyson 172:9bc3c7b2cca1 635 pr->todo = TODO_NONE;
andrewboyson 172:9bc3c7b2cca1 636 pr->state = STATE_VALID;
andrewboyson 172:9bc3c7b2cca1 637 pr->ageMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 638 }
andrewboyson 172:9bc3c7b2cca1 639 else
andrewboyson 172:9bc3c7b2cca1 640 {
andrewboyson 172:9bc3c7b2cca1 641 pr->state = STATE_WAIT_FOR_ETH;
andrewboyson 172:9bc3c7b2cca1 642 }
andrewboyson 172:9bc3c7b2cca1 643 break;
andrewboyson 172:9bc3c7b2cca1 644 case STATE_WAIT_FOR_ETH:
andrewboyson 172:9bc3c7b2cca1 645 if (!DnsQueryIsBusy)
andrewboyson 172:9bc3c7b2cca1 646 {
andrewboyson 172:9bc3c7b2cca1 647 switch (pr->todo)
andrewboyson 172:9bc3c7b2cca1 648 {
andrewboyson 182:ff48c6ea91c1 649 case TODO_NAME_FROM_ADDRESS: queryNameFromIp(pr); break;
andrewboyson 182:ff48c6ea91c1 650 case TODO_ADDRESS_FROM_NAME: queryIpFromName(pr); break;
andrewboyson 172:9bc3c7b2cca1 651 }
andrewboyson 172:9bc3c7b2cca1 652 pr->state = STATE_WAIT_TIMEOUT;
andrewboyson 172:9bc3c7b2cca1 653 pr->replyMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 654 }
andrewboyson 172:9bc3c7b2cca1 655 break;
andrewboyson 172:9bc3c7b2cca1 656 case STATE_WAIT_TIMEOUT:
andrewboyson 172:9bc3c7b2cca1 657 if (MsTimerRelative(pr->replyMs, REPLY_TIMEOUT_MS))
andrewboyson 172:9bc3c7b2cca1 658 {
andrewboyson 172:9bc3c7b2cca1 659 pr->state = STATE_WANT;
andrewboyson 172:9bc3c7b2cca1 660 }
andrewboyson 172:9bc3c7b2cca1 661 break;
andrewboyson 172:9bc3c7b2cca1 662 default:
andrewboyson 172:9bc3c7b2cca1 663 break;
andrewboyson 172:9bc3c7b2cca1 664 }
andrewboyson 172:9bc3c7b2cca1 665 }
andrewboyson 172:9bc3c7b2cca1 666 void NrMain()
andrewboyson 172:9bc3c7b2cca1 667 {
andrewboyson 172:9bc3c7b2cca1 668 static int i = -1;
andrewboyson 172:9bc3c7b2cca1 669 i++;
andrewboyson 172:9bc3c7b2cca1 670 if (i >= RECORDS_COUNT) i = 0;
andrewboyson 172:9bc3c7b2cca1 671
andrewboyson 172:9bc3c7b2cca1 672 struct record* pr = &records[i];
andrewboyson 172:9bc3c7b2cca1 673
andrewboyson 172:9bc3c7b2cca1 674 clearCache (pr);
andrewboyson 172:9bc3c7b2cca1 675 sendRequest (pr);
andrewboyson 172:9bc3c7b2cca1 676 }
andrewboyson 172:9bc3c7b2cca1 677 void NrInit()
andrewboyson 172:9bc3c7b2cca1 678 {
andrewboyson 172:9bc3c7b2cca1 679 for (int i = 0; i < RECORDS_COUNT; i++) records[i].state = STATE_EMPTY;
andrewboyson 172:9bc3c7b2cca1 680 }