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 Jan 18 18:23:46 2021 +0000
Revision:
187:122fc1996c86
Parent:
186:24198369b198
Child:
188:57f44b620d0e
Changed Ip4Address to Ip4Addr.; Moved Ip6AddrIsExternal from NdpNeedsToBeRouted.

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 172:9bc3c7b2cca1 212 LogTimeF("NR - renew name of ");
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 172:9bc3c7b2cca1 223 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 224 {
andrewboyson 172:9bc3c7b2cca1 225 LogTimeF("NR - request name of ");
andrewboyson 182:ff48c6ea91c1 226 addrLog(addrType, address);
andrewboyson 172:9bc3c7b2cca1 227 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 228 }
andrewboyson 172:9bc3c7b2cca1 229 i = getOldest();
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 182:ff48c6ea91c1 262 if (addrType == ADDR_TYPE_A) LogTimeF("NR - renew A of %s\r\n", name);
andrewboyson 182:ff48c6ea91c1 263 else LogTimeF("NR - renew AAAA of %s\r\n", 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 172:9bc3c7b2cca1 272 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 273 {
andrewboyson 182:ff48c6ea91c1 274 if (addrType == ADDR_TYPE_A) LogTimeF("NR - request A of %s\r\n", name);
andrewboyson 182:ff48c6ea91c1 275 else LogTimeF("NR - request AAAA of %s\r\n", name);
andrewboyson 172:9bc3c7b2cca1 276 }
andrewboyson 172:9bc3c7b2cca1 277 i = getOldest();
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 182:ff48c6ea91c1 310 addrLog(addrType, address);
andrewboyson 172:9bc3c7b2cca1 311 Log(" == '");
andrewboyson 172:9bc3c7b2cca1 312 Log(name);
andrewboyson 172:9bc3c7b2cca1 313 Log("'\r\n");
andrewboyson 172:9bc3c7b2cca1 314 }
andrewboyson 172:9bc3c7b2cca1 315
andrewboyson 172:9bc3c7b2cca1 316 //Ignore records which do not have both address and name
andrewboyson 182:ff48c6ea91c1 317 if (addrIsEmpty(addrType, address) || name == 0 || name[0] == 0)
andrewboyson 172:9bc3c7b2cca1 318 {
andrewboyson 172:9bc3c7b2cca1 319 if (NrTrace) LogTimeF("NR -- ignoring invalid entry\r\n");
andrewboyson 172:9bc3c7b2cca1 320 return;
andrewboyson 172:9bc3c7b2cca1 321 }
andrewboyson 186:24198369b198 322 //Ignore records with the name 'UNKNOWN'
andrewboyson 186:24198369b198 323 if (strcmp(name, "UNKNOWN") == 0) return;
andrewboyson 172:9bc3c7b2cca1 324
andrewboyson 182:ff48c6ea91c1 325 i = getExistingEntry(addrType, address, name);
andrewboyson 172:9bc3c7b2cca1 326 if (i >= 0)
andrewboyson 182:ff48c6ea91c1 327 {
andrewboyson 182:ff48c6ea91c1 328 updateRecord(i, address, addrType, name, dnsProtocol, ipProtocol);
andrewboyson 182:ff48c6ea91c1 329 if (NrTrace) LogTimeF("NR -- record %d - refresh existing entry\r\n", i);
andrewboyson 182:ff48c6ea91c1 330 return;
andrewboyson 182:ff48c6ea91c1 331 }
andrewboyson 182:ff48c6ea91c1 332
andrewboyson 182:ff48c6ea91c1 333 i = getCorrespondingRequest(addrType, address, name);
andrewboyson 182:ff48c6ea91c1 334 if (i >= 0)
andrewboyson 182:ff48c6ea91c1 335 {
andrewboyson 182:ff48c6ea91c1 336 updateRecord(i, address, addrType, name, dnsProtocol, ipProtocol);
andrewboyson 182:ff48c6ea91c1 337 if (NrTrace) LogTimeF("NR -- record %d - replace request with new entry\r\n", i);
andrewboyson 182:ff48c6ea91c1 338 i = getCorrespondingRequest(addrType, address, name);
andrewboyson 172:9bc3c7b2cca1 339 if (i >= 0)
andrewboyson 172:9bc3c7b2cca1 340 {
andrewboyson 182:ff48c6ea91c1 341 if (NrTrace) LogTimeF("NR -- record %d - clear duplicate request\r\n", i, name);
andrewboyson 172:9bc3c7b2cca1 342 records[i].state = STATE_EMPTY;
andrewboyson 172:9bc3c7b2cca1 343 }
andrewboyson 172:9bc3c7b2cca1 344 return;
andrewboyson 172:9bc3c7b2cca1 345 }
andrewboyson 172:9bc3c7b2cca1 346
andrewboyson 172:9bc3c7b2cca1 347 //No other entry exists so just add it to the next available space
andrewboyson 172:9bc3c7b2cca1 348 i = getOldest();
andrewboyson 182:ff48c6ea91c1 349 if (NrTrace) LogTimeF("NR -- record %d - add entry\r\n", i);
andrewboyson 182:ff48c6ea91c1 350 updateRecord(i, address, addrType, name, dnsProtocol, ipProtocol);
andrewboyson 172:9bc3c7b2cca1 351 }
andrewboyson 182:ff48c6ea91c1 352 static void addressToName(uint8_t addrType, void* address, char* name)
andrewboyson 172:9bc3c7b2cca1 353 {
andrewboyson 172:9bc3c7b2cca1 354 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 355 {
andrewboyson 172:9bc3c7b2cca1 356 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 357 if (addrIsSame(addrType, records[i].address, address))
andrewboyson 172:9bc3c7b2cca1 358 {
andrewboyson 172:9bc3c7b2cca1 359 strcpy(name, records[i].name);
andrewboyson 172:9bc3c7b2cca1 360 return;
andrewboyson 172:9bc3c7b2cca1 361 }
andrewboyson 172:9bc3c7b2cca1 362 }
andrewboyson 172:9bc3c7b2cca1 363 name[0] = 0;
andrewboyson 172:9bc3c7b2cca1 364 }
andrewboyson 182:ff48c6ea91c1 365 static void nameToAddress(char* name, uint8_t addrType, void* address)
andrewboyson 172:9bc3c7b2cca1 366 {
andrewboyson 172:9bc3c7b2cca1 367 uint32_t newest = 0xFFFFFFFF;
andrewboyson 182:ff48c6ea91c1 368 addrClear(addrType, address);
andrewboyson 172:9bc3c7b2cca1 369 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 370 {
andrewboyson 172:9bc3c7b2cca1 371 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 372 if (records[i].addrType != addrType) continue;
andrewboyson 182:ff48c6ea91c1 373 if(addrIsEmpty(records[i].addrType, records[i].address)) continue;
andrewboyson 172:9bc3c7b2cca1 374 if (!DnsLabelIsSame(records[i].name, name)) continue;
andrewboyson 172:9bc3c7b2cca1 375 uint32_t age = MsTimerCount - records[i].ageMs;
andrewboyson 172:9bc3c7b2cca1 376 if (age <= newest)
andrewboyson 172:9bc3c7b2cca1 377 {
andrewboyson 172:9bc3c7b2cca1 378 newest = age;
andrewboyson 182:ff48c6ea91c1 379 addrCopy(addrType, address, records[i].address);
andrewboyson 172:9bc3c7b2cca1 380 }
andrewboyson 172:9bc3c7b2cca1 381 }
andrewboyson 172:9bc3c7b2cca1 382 }
andrewboyson 182:ff48c6ea91c1 383 void NrMakeRequestForNameFromAddress6(char* pAddress) { makeRequestForNameFromAddress(ADDR_TYPE_AAAA, pAddress); }
andrewboyson 182:ff48c6ea91c1 384 void NrMakeRequestForNameFromAddress4(uint32_t address) { makeRequestForNameFromAddress(ADDR_TYPE_A, &address); }
andrewboyson 182:ff48c6ea91c1 385 void NrMakeRequestForAddress6FromName(char* name) { makeRequestForAddressFromName(name, ADDR_TYPE_AAAA); }
andrewboyson 182:ff48c6ea91c1 386 void NrMakeRequestForAddress4FromName(char* name) { makeRequestForAddressFromName(name, ADDR_TYPE_A ); }
andrewboyson 182:ff48c6ea91c1 387 void NrAddAddress6(char* pAddress, char* name, int dnsProtocol) { addEntry(ADDR_TYPE_AAAA, pAddress, name, dnsProtocol, EthProtocol); }
andrewboyson 182:ff48c6ea91c1 388 void NrAddAddress4(uint32_t address, char* name, int dnsProtocol) { addEntry(ADDR_TYPE_A, &address, name, dnsProtocol, EthProtocol); }
andrewboyson 182:ff48c6ea91c1 389 void NrNameToAddress6(char* name, char* address) { nameToAddress(name, ADDR_TYPE_AAAA, address); }
andrewboyson 182:ff48c6ea91c1 390 void NrNameToAddress4(char* name, uint32_t* pAddress) { nameToAddress(name, ADDR_TYPE_A, pAddress); }
andrewboyson 182:ff48c6ea91c1 391 void NrAddress6ToName(char* pAddress, char* name) { addressToName(ADDR_TYPE_AAAA, pAddress, name); }
andrewboyson 182:ff48c6ea91c1 392 void NrAddress4ToName(uint32_t address, char* name) { addressToName(ADDR_TYPE_A, &address, name); }
andrewboyson 182:ff48c6ea91c1 393
andrewboyson 172:9bc3c7b2cca1 394 static char letterFromStateAndProtocol(uint8_t dnsState, uint8_t dnsProtocol, uint16_t ipProtocol)
andrewboyson 172:9bc3c7b2cca1 395 {
andrewboyson 172:9bc3c7b2cca1 396 switch (dnsState)
andrewboyson 172:9bc3c7b2cca1 397 {
andrewboyson 172:9bc3c7b2cca1 398 case STATE_WANT: return '}';
andrewboyson 172:9bc3c7b2cca1 399 case STATE_WAIT_FOR_ETH: return ']';
andrewboyson 172:9bc3c7b2cca1 400 case STATE_WAIT_TIMEOUT: return '>';
andrewboyson 172:9bc3c7b2cca1 401
andrewboyson 172:9bc3c7b2cca1 402 case STATE_VALID:
andrewboyson 172:9bc3c7b2cca1 403 switch (dnsProtocol)
andrewboyson 172:9bc3c7b2cca1 404 {
andrewboyson 172:9bc3c7b2cca1 405 case DNS_PROTOCOL_UDNS: if (ipProtocol == ETH_IPV4) return 'd' ; else return 'D';
andrewboyson 172:9bc3c7b2cca1 406 case DNS_PROTOCOL_MDNS: if (ipProtocol == ETH_IPV4) return 'm' ; else return 'M';
andrewboyson 172:9bc3c7b2cca1 407 case DNS_PROTOCOL_LLMNR: if (ipProtocol == ETH_IPV4) return 'l' ; else return 'L';
andrewboyson 172:9bc3c7b2cca1 408 case DNS_PROTOCOL_NONE: return '-';
andrewboyson 172:9bc3c7b2cca1 409 default: return '?';
andrewboyson 172:9bc3c7b2cca1 410 }
andrewboyson 172:9bc3c7b2cca1 411 default: return '~';
andrewboyson 172:9bc3c7b2cca1 412 }
andrewboyson 172:9bc3c7b2cca1 413 }
andrewboyson 172:9bc3c7b2cca1 414 void NrSendAjax()
andrewboyson 172:9bc3c7b2cca1 415 {
andrewboyson 172:9bc3c7b2cca1 416 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 417 {
andrewboyson 172:9bc3c7b2cca1 418 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 419 if (!addrIsEmpty(records[i].addrType, records[i].address) || records[i].name[0])
andrewboyson 172:9bc3c7b2cca1 420 {
andrewboyson 172:9bc3c7b2cca1 421 HttpAddByteAsHex(i);
andrewboyson 172:9bc3c7b2cca1 422 HttpAddChar('\t');
andrewboyson 172:9bc3c7b2cca1 423 HttpAddInt32AsHex(MsTimerCount - records[i].ageMs);
andrewboyson 172:9bc3c7b2cca1 424 HttpAddChar('\t');
andrewboyson 182:ff48c6ea91c1 425 HttpAddNibbleAsHex(records[i].addrType);
andrewboyson 182:ff48c6ea91c1 426 HttpAddChar('\t');
andrewboyson 182:ff48c6ea91c1 427 switch (records[i].addrType)
andrewboyson 182:ff48c6ea91c1 428 {
andrewboyson 182:ff48c6ea91c1 429 case ADDR_TYPE_A:
andrewboyson 182:ff48c6ea91c1 430 {
andrewboyson 182:ff48c6ea91c1 431 HttpAddInt32AsHex(records[i].A);
andrewboyson 182:ff48c6ea91c1 432 break;
andrewboyson 182:ff48c6ea91c1 433 }
andrewboyson 182:ff48c6ea91c1 434 case ADDR_TYPE_AAAA:
andrewboyson 182:ff48c6ea91c1 435 for (int b = 0; b < 16; b++) HttpAddByteAsHex(records[i].AAAA[b]);
andrewboyson 182:ff48c6ea91c1 436 break;
andrewboyson 182:ff48c6ea91c1 437 }
andrewboyson 172:9bc3c7b2cca1 438 HttpAddChar('\t');
andrewboyson 172:9bc3c7b2cca1 439 HttpAddChar(letterFromStateAndProtocol(records[i].state, records[i].dnsProtocol, records[i].ipProtocol));
andrewboyson 172:9bc3c7b2cca1 440 HttpAddChar('\t');
andrewboyson 172:9bc3c7b2cca1 441 HttpAddText(records[i].name);
andrewboyson 172:9bc3c7b2cca1 442 HttpAddChar('\n');
andrewboyson 172:9bc3c7b2cca1 443 }
andrewboyson 172:9bc3c7b2cca1 444 }
andrewboyson 172:9bc3c7b2cca1 445 }
andrewboyson 172:9bc3c7b2cca1 446 static void clearCache(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 447 {
andrewboyson 172:9bc3c7b2cca1 448 if (MsTimerRelative(pr->ageMs, CACHE_TIMEOUT_MS)) pr->state = STATE_EMPTY;
andrewboyson 172:9bc3c7b2cca1 449 }
andrewboyson 172:9bc3c7b2cca1 450 static void queryNameFromIp(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 451 {
andrewboyson 182:ff48c6ea91c1 452 if (addrIsEmpty(pr->addrType, pr->address))
andrewboyson 176:7eb916c22084 453 {
andrewboyson 176:7eb916c22084 454 LogTime("NR -- queryNameFromIp has no address\r\n");
andrewboyson 176:7eb916c22084 455 return;
andrewboyson 176:7eb916c22084 456 }
andrewboyson 172:9bc3c7b2cca1 457 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 458 {
andrewboyson 172:9bc3c7b2cca1 459 LogTime("NR -- send ");
andrewboyson 172:9bc3c7b2cca1 460 EthProtocolLog(pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 461 Log(" ");
andrewboyson 172:9bc3c7b2cca1 462 DnsProtocolLog(pr->dnsProtocol);
andrewboyson 172:9bc3c7b2cca1 463 Log(" request for name of ");
andrewboyson 182:ff48c6ea91c1 464 addrLog(pr->addrType, pr->address);
andrewboyson 172:9bc3c7b2cca1 465 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 466 }
andrewboyson 182:ff48c6ea91c1 467 if (pr->addrType == ADDR_TYPE_A)
andrewboyson 172:9bc3c7b2cca1 468 {
andrewboyson 182:ff48c6ea91c1 469 //uint32_t address4 = addrToIp4(pr->address);
andrewboyson 182:ff48c6ea91c1 470 DnsQueryNameFromIp4(pr->A, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 471 }
andrewboyson 172:9bc3c7b2cca1 472 else
andrewboyson 172:9bc3c7b2cca1 473 {
andrewboyson 172:9bc3c7b2cca1 474 DnsQueryNameFromIp6(pr->address, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 475 }
andrewboyson 172:9bc3c7b2cca1 476 }
andrewboyson 182:ff48c6ea91c1 477 static void queryIpFromName(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 478 {
andrewboyson 172:9bc3c7b2cca1 479 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 480 {
andrewboyson 172:9bc3c7b2cca1 481 LogTime("NR -- send ");
andrewboyson 172:9bc3c7b2cca1 482 EthProtocolLog(pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 483 Log(" ");
andrewboyson 172:9bc3c7b2cca1 484 DnsProtocolLog(pr->dnsProtocol);
andrewboyson 182:ff48c6ea91c1 485 if (pr->addrType == ADDR_TYPE_A) Log(" request for A of name '");
andrewboyson 182:ff48c6ea91c1 486 else Log(" request for AAAA of name '");
andrewboyson 172:9bc3c7b2cca1 487 Log(pr->name);
andrewboyson 172:9bc3c7b2cca1 488 Log("'\r\n");
andrewboyson 172:9bc3c7b2cca1 489 }
andrewboyson 182:ff48c6ea91c1 490 if (pr->addrType == ADDR_TYPE_A) DnsQueryIp4FromName(pr->name, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 182:ff48c6ea91c1 491 else DnsQueryIp6FromName(pr->name, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 492 }
andrewboyson 183:ee809769bf89 493 static bool getIsExternal(struct record* pr)
andrewboyson 183:ee809769bf89 494 {
andrewboyson 183:ee809769bf89 495 switch(pr->todo)
andrewboyson 183:ee809769bf89 496 {
andrewboyson 183:ee809769bf89 497 case TODO_NAME_FROM_ADDRESS:
andrewboyson 183:ee809769bf89 498
andrewboyson 183:ee809769bf89 499 if (pr->addrType == ADDR_TYPE_AAAA)
andrewboyson 183:ee809769bf89 500 {
andrewboyson 187:122fc1996c86 501 return Ip6AddrIsExternal((char*)pr->AAAA);
andrewboyson 183:ee809769bf89 502 }
andrewboyson 183:ee809769bf89 503 else
andrewboyson 183:ee809769bf89 504 {
andrewboyson 187:122fc1996c86 505 return Ip4AddrIsExternal(pr->A);
andrewboyson 183:ee809769bf89 506 }
andrewboyson 183:ee809769bf89 507 case TODO_ADDRESS_FROM_NAME:
andrewboyson 183:ee809769bf89 508 return DnsLabelIsExternal(pr->name);
andrewboyson 183:ee809769bf89 509 default:
andrewboyson 183:ee809769bf89 510 LogTimeF("NR - getIsExternal - undefined todo '%d'\r\n", pr->todo);
andrewboyson 183:ee809769bf89 511 return false;
andrewboyson 183:ee809769bf89 512 }
andrewboyson 183:ee809769bf89 513 }
andrewboyson 183:ee809769bf89 514 static bool protocolIsAvailable(struct record* pr)
andrewboyson 183:ee809769bf89 515 {
andrewboyson 183:ee809769bf89 516 bool isExternal = getIsExternal(pr);
andrewboyson 183:ee809769bf89 517 switch(pr->dnsProtocol)
andrewboyson 183:ee809769bf89 518 {
andrewboyson 183:ee809769bf89 519 case DNS_PROTOCOL_MDNS: return !isExternal;
andrewboyson 183:ee809769bf89 520 case DNS_PROTOCOL_LLMNR: return !isExternal;
andrewboyson 183:ee809769bf89 521 case DNS_PROTOCOL_UDNS:
andrewboyson 183:ee809769bf89 522 if (pr->ipProtocol == ETH_IPV6)
andrewboyson 183:ee809769bf89 523 {
andrewboyson 183:ee809769bf89 524 if (Ip6AddrIsEmpty(NdpDnsServer)) return false; //No DNS server so not ok
andrewboyson 183:ee809769bf89 525 if (isExternal) return true; //External and have DNS server so ok
andrewboyson 183:ee809769bf89 526 return false; //Internal but have no DHCP6 domain name so not ok
andrewboyson 183:ee809769bf89 527 }
andrewboyson 183:ee809769bf89 528 else //ETH_IPV4
andrewboyson 183:ee809769bf89 529 {
andrewboyson 183:ee809769bf89 530 if (DhcpDnsServerIp == 0) return false; //No DNS server so not ok
andrewboyson 183:ee809769bf89 531 if (isExternal) return true; //External and have DNS server so ok
andrewboyson 183:ee809769bf89 532 return DhcpDomainName[0] != 0; //Internal and have domain name so ok
andrewboyson 183:ee809769bf89 533 }
andrewboyson 183:ee809769bf89 534 case DNS_PROTOCOL_NONE: return true; //No protocol is valid as it designates 'not found'
andrewboyson 183:ee809769bf89 535 default: return false;
andrewboyson 183:ee809769bf89 536 }
andrewboyson 183:ee809769bf89 537 }
andrewboyson 172:9bc3c7b2cca1 538 static void makeNextProtocol(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 539 {
andrewboyson 172:9bc3c7b2cca1 540 //If current protocol is empty or unknown then return with the first.
andrewboyson 172:9bc3c7b2cca1 541 switch (pr->ipProtocol)
andrewboyson 172:9bc3c7b2cca1 542 {
andrewboyson 172:9bc3c7b2cca1 543 case ETH_IPV6: break;
andrewboyson 172:9bc3c7b2cca1 544 case ETH_IPV4: break;
andrewboyson 172:9bc3c7b2cca1 545 default:
andrewboyson 172:9bc3c7b2cca1 546 pr->ipProtocol = ETH_IPV6;
andrewboyson 172:9bc3c7b2cca1 547 pr->dnsProtocol = DNS_PROTOCOL_MDNS;
andrewboyson 172:9bc3c7b2cca1 548 return;
andrewboyson 172:9bc3c7b2cca1 549 }
andrewboyson 172:9bc3c7b2cca1 550 switch (pr->dnsProtocol)
andrewboyson 172:9bc3c7b2cca1 551 {
andrewboyson 172:9bc3c7b2cca1 552 case DNS_PROTOCOL_MDNS: break;
andrewboyson 172:9bc3c7b2cca1 553 case DNS_PROTOCOL_LLMNR: break;
andrewboyson 172:9bc3c7b2cca1 554 case DNS_PROTOCOL_UDNS: break;
andrewboyson 172:9bc3c7b2cca1 555 default:
andrewboyson 172:9bc3c7b2cca1 556 pr->ipProtocol = ETH_IPV6;
andrewboyson 172:9bc3c7b2cca1 557 pr->dnsProtocol = DNS_PROTOCOL_MDNS;
andrewboyson 172:9bc3c7b2cca1 558 return;
andrewboyson 172:9bc3c7b2cca1 559
andrewboyson 172:9bc3c7b2cca1 560 }
andrewboyson 172:9bc3c7b2cca1 561 switch(pr->dnsProtocol)
andrewboyson 172:9bc3c7b2cca1 562 {
andrewboyson 172:9bc3c7b2cca1 563 case DNS_PROTOCOL_MDNS:
andrewboyson 172:9bc3c7b2cca1 564 if (pr->ipProtocol == ETH_IPV6)
andrewboyson 172:9bc3c7b2cca1 565 {
andrewboyson 172:9bc3c7b2cca1 566 pr->ipProtocol = ETH_IPV4;
andrewboyson 172:9bc3c7b2cca1 567 }
andrewboyson 172:9bc3c7b2cca1 568 else
andrewboyson 172:9bc3c7b2cca1 569 {
andrewboyson 172:9bc3c7b2cca1 570 pr->ipProtocol = ETH_IPV6;
andrewboyson 172:9bc3c7b2cca1 571 pr->dnsProtocol = DNS_PROTOCOL_LLMNR;
andrewboyson 172:9bc3c7b2cca1 572 }
andrewboyson 172:9bc3c7b2cca1 573 break;
andrewboyson 172:9bc3c7b2cca1 574 case DNS_PROTOCOL_LLMNR:
andrewboyson 172:9bc3c7b2cca1 575 if (pr->ipProtocol == ETH_IPV6)
andrewboyson 172:9bc3c7b2cca1 576 {
andrewboyson 172:9bc3c7b2cca1 577 pr->ipProtocol = ETH_IPV4;
andrewboyson 172:9bc3c7b2cca1 578 }
andrewboyson 172:9bc3c7b2cca1 579 else
andrewboyson 172:9bc3c7b2cca1 580 {
andrewboyson 172:9bc3c7b2cca1 581 pr->ipProtocol = ETH_IPV6;
andrewboyson 172:9bc3c7b2cca1 582 pr->dnsProtocol = DNS_PROTOCOL_UDNS;
andrewboyson 172:9bc3c7b2cca1 583 }
andrewboyson 172:9bc3c7b2cca1 584 break;
andrewboyson 172:9bc3c7b2cca1 585 case DNS_PROTOCOL_UDNS:
andrewboyson 172:9bc3c7b2cca1 586 if (pr->ipProtocol == ETH_IPV6)
andrewboyson 172:9bc3c7b2cca1 587 {
andrewboyson 172:9bc3c7b2cca1 588 pr->ipProtocol = ETH_IPV4;
andrewboyson 172:9bc3c7b2cca1 589 }
andrewboyson 172:9bc3c7b2cca1 590 else
andrewboyson 172:9bc3c7b2cca1 591 {
andrewboyson 172:9bc3c7b2cca1 592 pr->ipProtocol = ETH_NONE;
andrewboyson 172:9bc3c7b2cca1 593 pr->dnsProtocol = DNS_PROTOCOL_NONE;
andrewboyson 172:9bc3c7b2cca1 594 }
andrewboyson 172:9bc3c7b2cca1 595 break;
andrewboyson 172:9bc3c7b2cca1 596 }
andrewboyson 172:9bc3c7b2cca1 597 }
andrewboyson 172:9bc3c7b2cca1 598
andrewboyson 172:9bc3c7b2cca1 599 static void sendRequest(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 600 {
andrewboyson 172:9bc3c7b2cca1 601 if (DnsQueryIsBusy) return;
andrewboyson 172:9bc3c7b2cca1 602
andrewboyson 172:9bc3c7b2cca1 603 switch (pr->state)
andrewboyson 172:9bc3c7b2cca1 604 {
andrewboyson 172:9bc3c7b2cca1 605 case STATE_WANT:
andrewboyson 172:9bc3c7b2cca1 606 makeNextProtocol(pr);
andrewboyson 183:ee809769bf89 607 while (!protocolIsAvailable(pr)) makeNextProtocol(pr);
andrewboyson 172:9bc3c7b2cca1 608 if (!pr->dnsProtocol || !pr->ipProtocol) //No more protocols to try so resolution has failed
andrewboyson 172:9bc3c7b2cca1 609 {
andrewboyson 172:9bc3c7b2cca1 610 if (pr->todo == TODO_NAME_FROM_ADDRESS)
andrewboyson 172:9bc3c7b2cca1 611 {
andrewboyson 172:9bc3c7b2cca1 612 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 613 {
andrewboyson 183:ee809769bf89 614 LogTimeF("NR - record %d - request for name of ", pr - records);
andrewboyson 182:ff48c6ea91c1 615 addrLog(pr->addrType, pr->address);
andrewboyson 172:9bc3c7b2cca1 616 Log(" has timed out\r\n");
andrewboyson 172:9bc3c7b2cca1 617 }
andrewboyson 172:9bc3c7b2cca1 618 pr->name[0] = 0;
andrewboyson 172:9bc3c7b2cca1 619 }
andrewboyson 182:ff48c6ea91c1 620 if (pr->todo == TODO_ADDRESS_FROM_NAME)
andrewboyson 172:9bc3c7b2cca1 621 {
andrewboyson 172:9bc3c7b2cca1 622 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 623 {
andrewboyson 183:ee809769bf89 624 LogTimeF("NR - record %d request for address of '", pr - records);
andrewboyson 172:9bc3c7b2cca1 625 Log(pr->name);
andrewboyson 172:9bc3c7b2cca1 626 Log("' has timed out\r\n");
andrewboyson 172:9bc3c7b2cca1 627 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 628 }
andrewboyson 182:ff48c6ea91c1 629 addrClear(pr->addrType, pr->address);
andrewboyson 172:9bc3c7b2cca1 630 }
andrewboyson 172:9bc3c7b2cca1 631 pr->todo = TODO_NONE;
andrewboyson 172:9bc3c7b2cca1 632 pr->state = STATE_VALID;
andrewboyson 172:9bc3c7b2cca1 633 pr->ageMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 634 }
andrewboyson 172:9bc3c7b2cca1 635 else
andrewboyson 172:9bc3c7b2cca1 636 {
andrewboyson 172:9bc3c7b2cca1 637 pr->state = STATE_WAIT_FOR_ETH;
andrewboyson 172:9bc3c7b2cca1 638 }
andrewboyson 172:9bc3c7b2cca1 639 break;
andrewboyson 172:9bc3c7b2cca1 640 case STATE_WAIT_FOR_ETH:
andrewboyson 172:9bc3c7b2cca1 641 if (!DnsQueryIsBusy)
andrewboyson 172:9bc3c7b2cca1 642 {
andrewboyson 172:9bc3c7b2cca1 643 switch (pr->todo)
andrewboyson 172:9bc3c7b2cca1 644 {
andrewboyson 182:ff48c6ea91c1 645 case TODO_NAME_FROM_ADDRESS: queryNameFromIp(pr); break;
andrewboyson 182:ff48c6ea91c1 646 case TODO_ADDRESS_FROM_NAME: queryIpFromName(pr); break;
andrewboyson 172:9bc3c7b2cca1 647 }
andrewboyson 172:9bc3c7b2cca1 648 pr->state = STATE_WAIT_TIMEOUT;
andrewboyson 172:9bc3c7b2cca1 649 pr->replyMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 650 }
andrewboyson 172:9bc3c7b2cca1 651 break;
andrewboyson 172:9bc3c7b2cca1 652 case STATE_WAIT_TIMEOUT:
andrewboyson 172:9bc3c7b2cca1 653 if (MsTimerRelative(pr->replyMs, REPLY_TIMEOUT_MS))
andrewboyson 172:9bc3c7b2cca1 654 {
andrewboyson 172:9bc3c7b2cca1 655 pr->state = STATE_WANT;
andrewboyson 172:9bc3c7b2cca1 656 }
andrewboyson 172:9bc3c7b2cca1 657 break;
andrewboyson 172:9bc3c7b2cca1 658 default:
andrewboyson 172:9bc3c7b2cca1 659 break;
andrewboyson 172:9bc3c7b2cca1 660 }
andrewboyson 172:9bc3c7b2cca1 661 }
andrewboyson 172:9bc3c7b2cca1 662 void NrMain()
andrewboyson 172:9bc3c7b2cca1 663 {
andrewboyson 172:9bc3c7b2cca1 664 static int i = -1;
andrewboyson 172:9bc3c7b2cca1 665 i++;
andrewboyson 172:9bc3c7b2cca1 666 if (i >= RECORDS_COUNT) i = 0;
andrewboyson 172:9bc3c7b2cca1 667
andrewboyson 172:9bc3c7b2cca1 668 struct record* pr = &records[i];
andrewboyson 172:9bc3c7b2cca1 669
andrewboyson 172:9bc3c7b2cca1 670 clearCache (pr);
andrewboyson 172:9bc3c7b2cca1 671 sendRequest (pr);
andrewboyson 172:9bc3c7b2cca1 672 }
andrewboyson 172:9bc3c7b2cca1 673 void NrInit()
andrewboyson 172:9bc3c7b2cca1 674 {
andrewboyson 172:9bc3c7b2cca1 675 for (int i = 0; i < RECORDS_COUNT; i++) records[i].state = STATE_EMPTY;
andrewboyson 172:9bc3c7b2cca1 676 }