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:
Thu Jan 21 13:34:33 2021 +0000
Revision:
189:e1c7990486c4
Parent:
188:57f44b620d0e
Child:
192:0dfa138a8e7d
Added test for name from Ipv4 address

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