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 May 20 14:32:52 2021 +0000
Revision:
200:5acbc41bf469
Parent:
194:f35c6e218de1
Increased number of arp entries from 20 to 30 to accommodate the number of WIZ devices plus a few incoming port 80 calls from the internet.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 61:aad055f1b0d1 1 #include <stdint.h>
andrewboyson 61:aad055f1b0d1 2 #include <stdbool.h>
andrewboyson 61:aad055f1b0d1 3 #include <stdio.h>
andrewboyson 61:aad055f1b0d1 4
andrewboyson 13:9cd54f7db57a 5 #include "dnshdr.h"
andrewboyson 13:9cd54f7db57a 6 #include "ctype.h"
andrewboyson 13:9cd54f7db57a 7 #include "log.h"
andrewboyson 13:9cd54f7db57a 8
andrewboyson 37:793b39683406 9 bool DnsNameTrace = false;
andrewboyson 22:914b970356f0 10
andrewboyson 13:9cd54f7db57a 11 #define MAX_DEPTH 10
andrewboyson 13:9cd54f7db57a 12
andrewboyson 13:9cd54f7db57a 13 static bool isOffset(char c) { return (c & 0xC0) == 0xC0; }
andrewboyson 13:9cd54f7db57a 14 static char* derefOffset(char* p)
andrewboyson 13:9cd54f7db57a 15 {
andrewboyson 13:9cd54f7db57a 16 int offset = (*p & 0x3F) << 8; //Any bits in the upper byte are added
andrewboyson 13:9cd54f7db57a 17 p++; //Move to the lower byte
andrewboyson 13:9cd54f7db57a 18 offset |= *p; //And add it
andrewboyson 13:9cd54f7db57a 19 return DnsHdrPacket + offset; //Return a pointer
andrewboyson 13:9cd54f7db57a 20 }
andrewboyson 13:9cd54f7db57a 21
andrewboyson 13:9cd54f7db57a 22 int DnsNameLength(char* pStart) //Returns 0 on error
andrewboyson 13:9cd54f7db57a 23 {
andrewboyson 13:9cd54f7db57a 24 char* p = pStart;
andrewboyson 13:9cd54f7db57a 25
andrewboyson 13:9cd54f7db57a 26 while (true)
andrewboyson 13:9cd54f7db57a 27 {
andrewboyson 59:e0e556c8bd46 28 if (p >= DnsHdrData + DnsHdrDataLength)
andrewboyson 13:9cd54f7db57a 29 {
andrewboyson 37:793b39683406 30 if (DnsNameTrace) LogTimeF("DnsNameLength strayed out of the packet\r\n");
andrewboyson 13:9cd54f7db57a 31 return 0;
andrewboyson 13:9cd54f7db57a 32 }
andrewboyson 13:9cd54f7db57a 33
andrewboyson 13:9cd54f7db57a 34 int length = *p++;
andrewboyson 13:9cd54f7db57a 35 if (length == 0) //Its the last field so finish
andrewboyson 13:9cd54f7db57a 36 {
andrewboyson 13:9cd54f7db57a 37 return p - pStart;
andrewboyson 13:9cd54f7db57a 38 }
andrewboyson 13:9cd54f7db57a 39 else if (isOffset(length)) //it's a pointer so skip the length byte and return
andrewboyson 13:9cd54f7db57a 40 {
andrewboyson 13:9cd54f7db57a 41 p++;
andrewboyson 13:9cd54f7db57a 42 return p - pStart;
andrewboyson 13:9cd54f7db57a 43 }
andrewboyson 13:9cd54f7db57a 44 else //it's a length plus a field eg 3www
andrewboyson 13:9cd54f7db57a 45 {
andrewboyson 13:9cd54f7db57a 46 p += length;
andrewboyson 13:9cd54f7db57a 47 }
andrewboyson 13:9cd54f7db57a 48 }
andrewboyson 13:9cd54f7db57a 49 }
andrewboyson 13:9cd54f7db57a 50
andrewboyson 37:793b39683406 51 bool DnsNameComparePtr(char* pStart, char* pTarget)
andrewboyson 32:679654f2d023 52 {
andrewboyson 32:679654f2d023 53 char* p = pStart;
andrewboyson 32:679654f2d023 54
andrewboyson 32:679654f2d023 55 int depth = 0;
andrewboyson 32:679654f2d023 56
andrewboyson 32:679654f2d023 57 while (true)
andrewboyson 32:679654f2d023 58 {
andrewboyson 59:e0e556c8bd46 59 if (p >= DnsHdrData + DnsHdrDataLength)
andrewboyson 32:679654f2d023 60 {
andrewboyson 37:793b39683406 61 if (DnsNameTrace) LogTimeF("DnsNameCompare strayed out of the packet\r\n");
andrewboyson 32:679654f2d023 62 return false;
andrewboyson 32:679654f2d023 63 }
andrewboyson 32:679654f2d023 64
andrewboyson 32:679654f2d023 65 int length = *p;
andrewboyson 32:679654f2d023 66 if (length == 0) //Its the last field so should be on the target's terminating NUL
andrewboyson 32:679654f2d023 67 {
andrewboyson 32:679654f2d023 68 if (*pTarget) return false;
andrewboyson 32:679654f2d023 69 return true;
andrewboyson 32:679654f2d023 70 }
andrewboyson 32:679654f2d023 71 else if (isOffset(length)) //it's a pointer so go up one
andrewboyson 32:679654f2d023 72 {
andrewboyson 32:679654f2d023 73 depth++;
andrewboyson 32:679654f2d023 74 if (depth > MAX_DEPTH)
andrewboyson 32:679654f2d023 75 {
andrewboyson 37:793b39683406 76 if (DnsNameTrace) LogTimeF("DnsNameCompare exceeded depth limit\r\n");
andrewboyson 32:679654f2d023 77 return false;
andrewboyson 32:679654f2d023 78 }
andrewboyson 36:900e24b27bfb 79 pStart = derefOffset(p);
andrewboyson 36:900e24b27bfb 80 p = pStart;
andrewboyson 32:679654f2d023 81 }
andrewboyson 32:679654f2d023 82 else //it's a length plus a field eg 3www
andrewboyson 32:679654f2d023 83 {
andrewboyson 32:679654f2d023 84 if (p > pStart) if (*pTarget++ != '.') return false;
andrewboyson 32:679654f2d023 85 p++;
andrewboyson 32:679654f2d023 86 for (int i = 0; i < length; i++)
andrewboyson 32:679654f2d023 87 {
andrewboyson 32:679654f2d023 88 if (toupper(*pTarget++) != toupper(*p++)) return false;
andrewboyson 32:679654f2d023 89 }
andrewboyson 32:679654f2d023 90 }
andrewboyson 32:679654f2d023 91 }
andrewboyson 32:679654f2d023 92 }
andrewboyson 32:679654f2d023 93 bool DnsNameCompareIp4(char *pStart, uint32_t ip)
andrewboyson 32:679654f2d023 94 {
andrewboyson 190:c4415a7253f5 95 char ipBytes[4];
andrewboyson 32:679654f2d023 96 int field = 0;
andrewboyson 32:679654f2d023 97 int depth = 0;
andrewboyson 32:679654f2d023 98 char* p = pStart;
andrewboyson 32:679654f2d023 99 while (true)
andrewboyson 32:679654f2d023 100 {
andrewboyson 59:e0e556c8bd46 101 if (p >= DnsHdrData + DnsHdrDataLength)
andrewboyson 32:679654f2d023 102 {
andrewboyson 32:679654f2d023 103 LogTimeF("DnsNameCompareIp4 could not find name end\r\n");
andrewboyson 32:679654f2d023 104 return false;
andrewboyson 32:679654f2d023 105 }
andrewboyson 32:679654f2d023 106
andrewboyson 32:679654f2d023 107 int length = *p;
andrewboyson 32:679654f2d023 108 if (length == 0) //Its the last field so return the ip if it is the correct length
andrewboyson 32:679654f2d023 109 {
andrewboyson 32:679654f2d023 110 if (field != 6) return false;
andrewboyson 32:679654f2d023 111 return true;
andrewboyson 32:679654f2d023 112 }
andrewboyson 32:679654f2d023 113 else if (isOffset(*p)) //it's a pointer so jump to the new offset eg ^C0 ^0C
andrewboyson 32:679654f2d023 114 {
andrewboyson 32:679654f2d023 115 depth++;
andrewboyson 32:679654f2d023 116 if (depth > MAX_DEPTH)
andrewboyson 32:679654f2d023 117 {
andrewboyson 32:679654f2d023 118 LogTimeF("DnsNameCompareIp4 exceeded depth limit\r\n");
andrewboyson 32:679654f2d023 119 return false;
andrewboyson 32:679654f2d023 120 }
andrewboyson 32:679654f2d023 121 p = derefOffset(p);
andrewboyson 32:679654f2d023 122 }
andrewboyson 32:679654f2d023 123 else //it's a length plus a field eg 3www
andrewboyson 32:679654f2d023 124 {
andrewboyson 32:679654f2d023 125 p++; // move past the length
andrewboyson 32:679654f2d023 126 if (field <= 3)
andrewboyson 32:679654f2d023 127 {
andrewboyson 32:679654f2d023 128 if (length > 3) return false; // expect 90.1.168.192.in-addr.arpa
andrewboyson 32:679654f2d023 129 int byte = 0;
andrewboyson 32:679654f2d023 130 for (int i = 0; i < length; i++)
andrewboyson 32:679654f2d023 131 {
andrewboyson 32:679654f2d023 132 byte = byte * 10;
andrewboyson 32:679654f2d023 133 if (*p > '9' || *p < '0') return false; // expect 90.1.168.192.in-addr.arpa
andrewboyson 32:679654f2d023 134 byte += *p - '0';
andrewboyson 32:679654f2d023 135 p++;
andrewboyson 32:679654f2d023 136 }
andrewboyson 190:c4415a7253f5 137 int ipByte = (ip >> 8 * (3 - field)) & 0xFF;
andrewboyson 191:33392a61182e 138 if (byte != ipByte) return false;
andrewboyson 32:679654f2d023 139 }
andrewboyson 32:679654f2d023 140 else if (field == 4)
andrewboyson 32:679654f2d023 141 {
andrewboyson 32:679654f2d023 142 if (length != 7) return false; // expect 90.1.168.192.in-addr.arpa
andrewboyson 32:679654f2d023 143 p+= length;
andrewboyson 32:679654f2d023 144 }
andrewboyson 32:679654f2d023 145 else if (field == 5)
andrewboyson 32:679654f2d023 146 {
andrewboyson 32:679654f2d023 147 if (length != 4) return false; // expect 90.1.168.192.in-addr.arpa
andrewboyson 32:679654f2d023 148 p+= length;
andrewboyson 32:679654f2d023 149 }
andrewboyson 32:679654f2d023 150 else
andrewboyson 32:679654f2d023 151 {
andrewboyson 32:679654f2d023 152 return false; // expect 90.1.168.192.in-addr.arpa
andrewboyson 32:679654f2d023 153 }
andrewboyson 32:679654f2d023 154 field++;
andrewboyson 32:679654f2d023 155 }
andrewboyson 32:679654f2d023 156 }
andrewboyson 32:679654f2d023 157 }
andrewboyson 32:679654f2d023 158 bool DnsNameCompareIp6(char* pStart, char* pIp)
andrewboyson 32:679654f2d023 159 {
andrewboyson 32:679654f2d023 160 int field = 0;
andrewboyson 32:679654f2d023 161 int depth = 0;
andrewboyson 32:679654f2d023 162 char* p = pStart;
andrewboyson 32:679654f2d023 163 while (true)
andrewboyson 32:679654f2d023 164 {
andrewboyson 59:e0e556c8bd46 165 if (p >= DnsHdrData + DnsHdrDataLength)
andrewboyson 32:679654f2d023 166 {
andrewboyson 32:679654f2d023 167 LogTimeF("DnsNameDecodeIp6 could not find name end\r\n");
andrewboyson 32:679654f2d023 168 return false;
andrewboyson 32:679654f2d023 169 }
andrewboyson 32:679654f2d023 170
andrewboyson 32:679654f2d023 171 int length = *p;
andrewboyson 32:679654f2d023 172 if (length == 0) //Its the last field so return the ip if it is the correct length
andrewboyson 32:679654f2d023 173 {
andrewboyson 32:679654f2d023 174 if (field != 34) return false;
andrewboyson 32:679654f2d023 175 return true;
andrewboyson 32:679654f2d023 176 }
andrewboyson 32:679654f2d023 177 else if (isOffset(*p)) //it's a pointer so jump to the new offset eg ^C0 ^0C
andrewboyson 32:679654f2d023 178 {
andrewboyson 32:679654f2d023 179 depth++;
andrewboyson 32:679654f2d023 180 if (depth > MAX_DEPTH)
andrewboyson 32:679654f2d023 181 {
andrewboyson 32:679654f2d023 182 LogTimeF("DnsNameDecodeIp6 exceeded depth limit\r\n");
andrewboyson 32:679654f2d023 183 return false;
andrewboyson 32:679654f2d023 184 }
andrewboyson 32:679654f2d023 185 p = derefOffset(p);
andrewboyson 32:679654f2d023 186 }
andrewboyson 32:679654f2d023 187 else //it's a length plus a field eg 3www
andrewboyson 32:679654f2d023 188 {
andrewboyson 32:679654f2d023 189 p++; // move past the length
andrewboyson 32:679654f2d023 190 if (field <= 31)
andrewboyson 32:679654f2d023 191 {
andrewboyson 32:679654f2d023 192 if (length > 1) return false; // expect 5.8.c.c.0.1.e.f.f.f.2.3.1.1.2.0.8.7.d.0.9.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa
andrewboyson 32:679654f2d023 193 int nibble = 0;
andrewboyson 32:679654f2d023 194 if (*p >= '0' && *p <= '9') nibble = *p - '0';
andrewboyson 32:679654f2d023 195 else if (*p >= 'a' && *p <= 'f') nibble = *p - 'a' + 10;
andrewboyson 32:679654f2d023 196 else if (*p >= 'A' && *p <= 'F') nibble = *p - 'A' + 10;
andrewboyson 37:793b39683406 197 else return false; // expect 7.2.d.7.2.f.e.f.f.f.7.f.2.0.2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa
andrewboyson 37:793b39683406 198 int target = pIp[15 - (field >> 1)];
andrewboyson 37:793b39683406 199 if ((field & 1) == 0) { target &= 0x0F; }
andrewboyson 37:793b39683406 200 else { target &= 0xF0; target >>=4; }
andrewboyson 37:793b39683406 201 if (target != nibble) return false;
andrewboyson 32:679654f2d023 202 p += length;
andrewboyson 32:679654f2d023 203 }
andrewboyson 32:679654f2d023 204 else if (field == 32)
andrewboyson 32:679654f2d023 205 {
andrewboyson 32:679654f2d023 206 if (length != 3) return false; // expect 5.8.c.c.0.1.e.f.f.f.2.3.1.1.2.0.8.7.d.0.9.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa
andrewboyson 32:679654f2d023 207 p+= length;
andrewboyson 32:679654f2d023 208 }
andrewboyson 32:679654f2d023 209 else if (field == 33)
andrewboyson 32:679654f2d023 210 {
andrewboyson 32:679654f2d023 211 if (length != 4) return false; // expect 5.8.c.c.0.1.e.f.f.f.2.3.1.1.2.0.8.7.d.0.9.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa
andrewboyson 32:679654f2d023 212 p+= length;
andrewboyson 32:679654f2d023 213 }
andrewboyson 32:679654f2d023 214 else
andrewboyson 32:679654f2d023 215 {
andrewboyson 32:679654f2d023 216 return false; // expect 5.8.c.c.0.1.e.f.f.f.2.3.1.1.2.0.8.7.d.0.9.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa
andrewboyson 32:679654f2d023 217 }
andrewboyson 32:679654f2d023 218 field++;
andrewboyson 32:679654f2d023 219 }
andrewboyson 32:679654f2d023 220 }
andrewboyson 32:679654f2d023 221 }
andrewboyson 32:679654f2d023 222
andrewboyson 59:e0e556c8bd46 223 void DnsNameDecodePtr(char* pStart, char* pName, int lenName)
andrewboyson 13:9cd54f7db57a 224 {
andrewboyson 13:9cd54f7db57a 225 bool nameStarted = false;
andrewboyson 13:9cd54f7db57a 226 int depth = 0;
andrewboyson 58:d48c899e482f 227 char* p = pStart;
andrewboyson 194:f35c6e218de1 228 char* pNameStart = pName;
andrewboyson 13:9cd54f7db57a 229 while (true)
andrewboyson 13:9cd54f7db57a 230 {
andrewboyson 59:e0e556c8bd46 231 if (p >= DnsHdrData + DnsHdrDataLength)
andrewboyson 13:9cd54f7db57a 232 {
andrewboyson 13:9cd54f7db57a 233 *pName = 0;
andrewboyson 37:793b39683406 234 if (DnsNameTrace) LogTimeF("DnsNameDecodePtr could not find name end\r\n");
andrewboyson 13:9cd54f7db57a 235 return;
andrewboyson 13:9cd54f7db57a 236 }
andrewboyson 13:9cd54f7db57a 237
andrewboyson 13:9cd54f7db57a 238 int length = *p;
andrewboyson 13:9cd54f7db57a 239 if (length == 0) //Its the last field so terminate the string
andrewboyson 13:9cd54f7db57a 240 {
andrewboyson 13:9cd54f7db57a 241 *pName = 0;
andrewboyson 13:9cd54f7db57a 242 return;
andrewboyson 13:9cd54f7db57a 243 }
andrewboyson 13:9cd54f7db57a 244 else if (isOffset(*p)) //it's a pointer so jump to the new offset eg ^C0 ^0C
andrewboyson 13:9cd54f7db57a 245 {
andrewboyson 13:9cd54f7db57a 246 depth++;
andrewboyson 13:9cd54f7db57a 247 if (depth > MAX_DEPTH)
andrewboyson 13:9cd54f7db57a 248 {
andrewboyson 37:793b39683406 249 LogTimeF("DnsNameDecodePtr exceeded depth limit\r\n");
andrewboyson 13:9cd54f7db57a 250 *pName = 0;
andrewboyson 13:9cd54f7db57a 251 return;
andrewboyson 13:9cd54f7db57a 252 }
andrewboyson 13:9cd54f7db57a 253 p = derefOffset(p);
andrewboyson 13:9cd54f7db57a 254 }
andrewboyson 13:9cd54f7db57a 255 else //it's a length plus a field eg 3www
andrewboyson 13:9cd54f7db57a 256 {
andrewboyson 13:9cd54f7db57a 257 if (pName)
andrewboyson 13:9cd54f7db57a 258 {
andrewboyson 194:f35c6e218de1 259 if (length + 1 > lenName) //Leave room to terminate the string.
andrewboyson 194:f35c6e218de1 260 //Warning removed as had too many 'amzn.dmgr:9D184A89EEDE554B15EABD4931BB839B:S/FRy5cPXE:914584' alerts
andrewboyson 13:9cd54f7db57a 261 {
andrewboyson 13:9cd54f7db57a 262 *pName = 0;
andrewboyson 194:f35c6e218de1 263 //LogTimeF("DnsNameDecodePtr decoded name '%s' overran name buffer trying to add %d bytes\r\n", pNameStart, length);
andrewboyson 13:9cd54f7db57a 264 return;
andrewboyson 13:9cd54f7db57a 265 }
andrewboyson 13:9cd54f7db57a 266 lenName -= length + 1; //name chunk plus a '.'
andrewboyson 13:9cd54f7db57a 267 if (nameStarted) *pName++ = '.';
andrewboyson 13:9cd54f7db57a 268 p++;
andrewboyson 13:9cd54f7db57a 269 for (int i = 0; i < length; i++) *pName++ = *p++;
andrewboyson 13:9cd54f7db57a 270 nameStarted = true;
andrewboyson 13:9cd54f7db57a 271 }
andrewboyson 13:9cd54f7db57a 272 else
andrewboyson 13:9cd54f7db57a 273 {
andrewboyson 13:9cd54f7db57a 274 p += length + 1;
andrewboyson 13:9cd54f7db57a 275 }
andrewboyson 13:9cd54f7db57a 276 }
andrewboyson 13:9cd54f7db57a 277 }
andrewboyson 13:9cd54f7db57a 278 }
andrewboyson 58:d48c899e482f 279 void DnsNameLogPtr(char* pStart)
andrewboyson 47:73af5c0b0dc2 280 {
andrewboyson 47:73af5c0b0dc2 281 bool nameStarted = false;
andrewboyson 47:73af5c0b0dc2 282 int depth = 0;
andrewboyson 58:d48c899e482f 283 char* p = pStart;
andrewboyson 47:73af5c0b0dc2 284 while (true)
andrewboyson 47:73af5c0b0dc2 285 {
andrewboyson 59:e0e556c8bd46 286 if (p >= DnsHdrData + DnsHdrDataLength)
andrewboyson 47:73af5c0b0dc2 287 {
andrewboyson 47:73af5c0b0dc2 288 if (DnsNameTrace) LogTimeF("DnsNameDecodePtr could not find name end\r\n");
andrewboyson 47:73af5c0b0dc2 289 return;
andrewboyson 47:73af5c0b0dc2 290 }
andrewboyson 47:73af5c0b0dc2 291
andrewboyson 47:73af5c0b0dc2 292 int length = *p;
andrewboyson 47:73af5c0b0dc2 293 if (length == 0) //Its the last field so terminate the string
andrewboyson 47:73af5c0b0dc2 294 {
andrewboyson 47:73af5c0b0dc2 295 return;
andrewboyson 47:73af5c0b0dc2 296 }
andrewboyson 47:73af5c0b0dc2 297 else if (isOffset(*p)) //it's a pointer so jump to the new offset eg ^C0 ^0C
andrewboyson 47:73af5c0b0dc2 298 {
andrewboyson 47:73af5c0b0dc2 299 depth++;
andrewboyson 47:73af5c0b0dc2 300 if (depth > MAX_DEPTH)
andrewboyson 47:73af5c0b0dc2 301 {
andrewboyson 47:73af5c0b0dc2 302 LogTimeF("DnsNameDecodePtr exceeded depth limit\r\n");
andrewboyson 47:73af5c0b0dc2 303 return;
andrewboyson 47:73af5c0b0dc2 304 }
andrewboyson 47:73af5c0b0dc2 305 p = derefOffset(p);
andrewboyson 47:73af5c0b0dc2 306 }
andrewboyson 47:73af5c0b0dc2 307 else //it's a length plus a field eg 3www
andrewboyson 47:73af5c0b0dc2 308 {
andrewboyson 121:bc048b65a630 309 if (nameStarted) LogChar('.');
andrewboyson 47:73af5c0b0dc2 310 p++;
andrewboyson 121:bc048b65a630 311 for (int i = 0; i < length; i++) LogChar(*p++);
andrewboyson 47:73af5c0b0dc2 312 nameStarted = true;
andrewboyson 47:73af5c0b0dc2 313 }
andrewboyson 47:73af5c0b0dc2 314 }
andrewboyson 47:73af5c0b0dc2 315 }
andrewboyson 58:d48c899e482f 316 void DnsNameDecodeIp4(char* pStart, uint32_t* pIp)
andrewboyson 13:9cd54f7db57a 317 {
andrewboyson 13:9cd54f7db57a 318 int field = 0;
andrewboyson 13:9cd54f7db57a 319 int depth = 0;
andrewboyson 58:d48c899e482f 320 char* p = pStart;
andrewboyson 13:9cd54f7db57a 321 while (true)
andrewboyson 13:9cd54f7db57a 322 {
andrewboyson 59:e0e556c8bd46 323 if (p >= DnsHdrData + DnsHdrDataLength)
andrewboyson 13:9cd54f7db57a 324 {
andrewboyson 13:9cd54f7db57a 325 *pIp = 0;
andrewboyson 13:9cd54f7db57a 326 LogTimeF("DnsNameDecodeIp4 could not find name end\r\n");
andrewboyson 13:9cd54f7db57a 327 return;
andrewboyson 13:9cd54f7db57a 328 }
andrewboyson 13:9cd54f7db57a 329
andrewboyson 13:9cd54f7db57a 330 int length = *p;
andrewboyson 13:9cd54f7db57a 331 if (length == 0) //Its the last field so return the ip if it is the correct length
andrewboyson 13:9cd54f7db57a 332 {
andrewboyson 13:9cd54f7db57a 333 if (field != 6) *pIp = 0;
andrewboyson 13:9cd54f7db57a 334 return;
andrewboyson 13:9cd54f7db57a 335 }
andrewboyson 13:9cd54f7db57a 336 else if (isOffset(*p)) //it's a pointer so jump to the new offset eg ^C0 ^0C
andrewboyson 13:9cd54f7db57a 337 {
andrewboyson 13:9cd54f7db57a 338 depth++;
andrewboyson 13:9cd54f7db57a 339 if (depth > MAX_DEPTH)
andrewboyson 13:9cd54f7db57a 340 {
andrewboyson 13:9cd54f7db57a 341 LogTimeF("DnsNameDecodeIp4 exceeded depth limit\r\n");
andrewboyson 13:9cd54f7db57a 342 *pIp = 0;
andrewboyson 13:9cd54f7db57a 343 return;
andrewboyson 13:9cd54f7db57a 344 }
andrewboyson 13:9cd54f7db57a 345 p = derefOffset(p);
andrewboyson 13:9cd54f7db57a 346 }
andrewboyson 13:9cd54f7db57a 347 else //it's a length plus a field eg 3www
andrewboyson 13:9cd54f7db57a 348 {
andrewboyson 13:9cd54f7db57a 349 p++; // move past the length
andrewboyson 13:9cd54f7db57a 350 if (field <= 3)
andrewboyson 13:9cd54f7db57a 351 {
andrewboyson 13:9cd54f7db57a 352 if (length > 3) {*pIp = 0; return; } // expect 90.1.168.192.in-addr.arpa
andrewboyson 13:9cd54f7db57a 353 int byte = 0;
andrewboyson 13:9cd54f7db57a 354 for (int i = 0; i < length; i++)
andrewboyson 13:9cd54f7db57a 355 {
andrewboyson 13:9cd54f7db57a 356 byte = byte * 10;
andrewboyson 13:9cd54f7db57a 357 if (*p > '9' || *p < '0') {*pIp = 0; return; } // expect 90.1.168.192.in-addr.arpa
andrewboyson 13:9cd54f7db57a 358 byte += *p - '0';
andrewboyson 13:9cd54f7db57a 359 p++;
andrewboyson 13:9cd54f7db57a 360 }
andrewboyson 13:9cd54f7db57a 361 *pIp <<= 8;
andrewboyson 13:9cd54f7db57a 362 *pIp |= byte;
andrewboyson 13:9cd54f7db57a 363 }
andrewboyson 13:9cd54f7db57a 364 else if (field == 4)
andrewboyson 13:9cd54f7db57a 365 {
andrewboyson 13:9cd54f7db57a 366 if (length != 7) {*pIp = 0; return; } // expect 90.1.168.192.in-addr.arpa
andrewboyson 13:9cd54f7db57a 367 p+= length;
andrewboyson 13:9cd54f7db57a 368 }
andrewboyson 13:9cd54f7db57a 369 else if (field == 5)
andrewboyson 13:9cd54f7db57a 370 {
andrewboyson 13:9cd54f7db57a 371 if (length != 4) {*pIp = 0; return; } // expect 90.1.168.192.in-addr.arpa
andrewboyson 13:9cd54f7db57a 372 p+= length;
andrewboyson 13:9cd54f7db57a 373 }
andrewboyson 13:9cd54f7db57a 374 else
andrewboyson 13:9cd54f7db57a 375 {
andrewboyson 13:9cd54f7db57a 376 *pIp = 0; return; // expect 90.1.168.192.in-addr.arpa
andrewboyson 13:9cd54f7db57a 377 }
andrewboyson 13:9cd54f7db57a 378 field++;
andrewboyson 13:9cd54f7db57a 379 }
andrewboyson 13:9cd54f7db57a 380 }
andrewboyson 13:9cd54f7db57a 381 }
andrewboyson 58:d48c899e482f 382 void DnsNameDecodeIp6(char* pStart, char* pIp)
andrewboyson 13:9cd54f7db57a 383 {
andrewboyson 13:9cd54f7db57a 384 int field = 0;
andrewboyson 13:9cd54f7db57a 385 int depth = 0;
andrewboyson 58:d48c899e482f 386 char* p = pStart;
andrewboyson 13:9cd54f7db57a 387 while (true)
andrewboyson 13:9cd54f7db57a 388 {
andrewboyson 59:e0e556c8bd46 389 if (p >= DnsHdrData + DnsHdrDataLength)
andrewboyson 13:9cd54f7db57a 390 {
andrewboyson 13:9cd54f7db57a 391 pIp[0] = 0;
andrewboyson 13:9cd54f7db57a 392 LogTimeF("DnsNameDecodeIp6 could not find name end\r\n");
andrewboyson 13:9cd54f7db57a 393 return;
andrewboyson 13:9cd54f7db57a 394 }
andrewboyson 13:9cd54f7db57a 395
andrewboyson 13:9cd54f7db57a 396 int length = *p;
andrewboyson 13:9cd54f7db57a 397 if (length == 0) //Its the last field so return the ip if it is the correct length
andrewboyson 13:9cd54f7db57a 398 {
andrewboyson 13:9cd54f7db57a 399 if (field != 34) pIp[0] = 0;
andrewboyson 13:9cd54f7db57a 400 return;
andrewboyson 13:9cd54f7db57a 401 }
andrewboyson 13:9cd54f7db57a 402 else if (isOffset(*p)) //it's a pointer so jump to the new offset eg ^C0 ^0C
andrewboyson 13:9cd54f7db57a 403 {
andrewboyson 13:9cd54f7db57a 404 depth++;
andrewboyson 13:9cd54f7db57a 405 if (depth > MAX_DEPTH)
andrewboyson 13:9cd54f7db57a 406 {
andrewboyson 13:9cd54f7db57a 407 LogTimeF("DnsNameDecodeIp6 exceeded depth limit\r\n");
andrewboyson 13:9cd54f7db57a 408 *pIp = 0;
andrewboyson 13:9cd54f7db57a 409 return;
andrewboyson 13:9cd54f7db57a 410 }
andrewboyson 13:9cd54f7db57a 411 p = derefOffset(p);
andrewboyson 13:9cd54f7db57a 412 }
andrewboyson 13:9cd54f7db57a 413 else //it's a length plus a field eg 3www
andrewboyson 13:9cd54f7db57a 414 {
andrewboyson 13:9cd54f7db57a 415 p++; // move past the length
andrewboyson 13:9cd54f7db57a 416 if (field <= 31)
andrewboyson 13:9cd54f7db57a 417 {
andrewboyson 13:9cd54f7db57a 418 if (length > 1) {pIp[0] = 0; return; } // expect 5.8.c.c.0.1.e.f.f.f.2.3.1.1.2.0.8.7.d.0.9.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa
andrewboyson 13:9cd54f7db57a 419 int nibble = 0;
andrewboyson 13:9cd54f7db57a 420 if (*p >= '0' && *p <= '9') nibble = *p - '0';
andrewboyson 13:9cd54f7db57a 421 else if (*p >= 'a' && *p <= 'f') nibble = *p - 'a' + 10;
andrewboyson 13:9cd54f7db57a 422 else if (*p >= 'A' && *p <= 'F') nibble = *p - 'A' + 10;
andrewboyson 13:9cd54f7db57a 423 else {pIp[0] = 0; return; } // expect 5.8.c.c.0.1.e.f.f.f.2.3.1.1.2.0.8.7.d.0.9.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa
andrewboyson 13:9cd54f7db57a 424 if ((field & 1) == 0)
andrewboyson 13:9cd54f7db57a 425 {
andrewboyson 13:9cd54f7db57a 426 pIp[15 - (field >> 1)] = nibble;
andrewboyson 13:9cd54f7db57a 427 }
andrewboyson 13:9cd54f7db57a 428 else
andrewboyson 13:9cd54f7db57a 429 {
andrewboyson 13:9cd54f7db57a 430 nibble <<= 4;
andrewboyson 13:9cd54f7db57a 431 pIp[15 - (field >> 1)] |= nibble;
andrewboyson 13:9cd54f7db57a 432 }
andrewboyson 13:9cd54f7db57a 433 p += length;
andrewboyson 13:9cd54f7db57a 434 }
andrewboyson 13:9cd54f7db57a 435 else if (field == 32)
andrewboyson 13:9cd54f7db57a 436 {
andrewboyson 13:9cd54f7db57a 437 if (length != 3) {pIp[0] = 0; return; } // expect 5.8.c.c.0.1.e.f.f.f.2.3.1.1.2.0.8.7.d.0.9.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa
andrewboyson 13:9cd54f7db57a 438 p+= length;
andrewboyson 13:9cd54f7db57a 439 }
andrewboyson 13:9cd54f7db57a 440 else if (field == 33)
andrewboyson 13:9cd54f7db57a 441 {
andrewboyson 13:9cd54f7db57a 442 if (length != 4) {pIp[0] = 0; return; } // expect 5.8.c.c.0.1.e.f.f.f.2.3.1.1.2.0.8.7.d.0.9.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa
andrewboyson 13:9cd54f7db57a 443 p+= length;
andrewboyson 13:9cd54f7db57a 444 }
andrewboyson 13:9cd54f7db57a 445 else
andrewboyson 13:9cd54f7db57a 446 {
andrewboyson 13:9cd54f7db57a 447 pIp[0] = 0; return; // expect 5.8.c.c.0.1.e.f.f.f.2.3.1.1.2.0.8.7.d.0.9.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa
andrewboyson 13:9cd54f7db57a 448 }
andrewboyson 13:9cd54f7db57a 449 field++;
andrewboyson 13:9cd54f7db57a 450 }
andrewboyson 13:9cd54f7db57a 451 }
andrewboyson 13:9cd54f7db57a 452 }
andrewboyson 13:9cd54f7db57a 453 void DnsNameEncodeIp4(uint32_t ip, char** pp)
andrewboyson 13:9cd54f7db57a 454 {
andrewboyson 13:9cd54f7db57a 455 char* p = *pp; //Get a convenient pointer to the next byte
andrewboyson 13:9cd54f7db57a 456
andrewboyson 13:9cd54f7db57a 457 char* pLen = p;
andrewboyson 13:9cd54f7db57a 458 p++;
andrewboyson 13:9cd54f7db57a 459
andrewboyson 13:9cd54f7db57a 460 *pLen = sprintf(p, "%d", (ip & 0xff000000) >> 24);
andrewboyson 13:9cd54f7db57a 461 p += *pLen;
andrewboyson 13:9cd54f7db57a 462 pLen = p;
andrewboyson 13:9cd54f7db57a 463 p++;
andrewboyson 13:9cd54f7db57a 464
andrewboyson 13:9cd54f7db57a 465 *pLen = sprintf(p, "%d", (ip & 0x00ff0000) >> 16);
andrewboyson 13:9cd54f7db57a 466 p += *pLen;
andrewboyson 13:9cd54f7db57a 467 pLen = p;
andrewboyson 13:9cd54f7db57a 468 p++;
andrewboyson 13:9cd54f7db57a 469
andrewboyson 13:9cd54f7db57a 470 *pLen = sprintf(p, "%d", (ip & 0x0000ff00) >> 8);
andrewboyson 13:9cd54f7db57a 471 p += *pLen;
andrewboyson 13:9cd54f7db57a 472 pLen = p;
andrewboyson 13:9cd54f7db57a 473 p++;
andrewboyson 13:9cd54f7db57a 474
andrewboyson 13:9cd54f7db57a 475 *pLen = sprintf(p, "%d", (ip & 0x000000ff) >> 0);
andrewboyson 13:9cd54f7db57a 476 p += *pLen;
andrewboyson 13:9cd54f7db57a 477 pLen = p;
andrewboyson 13:9cd54f7db57a 478 p++;
andrewboyson 13:9cd54f7db57a 479
andrewboyson 13:9cd54f7db57a 480 *pLen = sprintf(p, "in-addr");
andrewboyson 13:9cd54f7db57a 481 p += *pLen;
andrewboyson 13:9cd54f7db57a 482 pLen = p;
andrewboyson 13:9cd54f7db57a 483 p++;
andrewboyson 13:9cd54f7db57a 484
andrewboyson 13:9cd54f7db57a 485 *pLen = sprintf(p, "arpa");
andrewboyson 13:9cd54f7db57a 486 p += *pLen;
andrewboyson 13:9cd54f7db57a 487 pLen = p;
andrewboyson 13:9cd54f7db57a 488 p++;
andrewboyson 13:9cd54f7db57a 489
andrewboyson 13:9cd54f7db57a 490 *pLen = 0;
andrewboyson 13:9cd54f7db57a 491
andrewboyson 13:9cd54f7db57a 492 *pp = p; //Save the convenient pointer back into the pointer to pointer
andrewboyson 13:9cd54f7db57a 493
andrewboyson 13:9cd54f7db57a 494 }
andrewboyson 13:9cd54f7db57a 495
andrewboyson 13:9cd54f7db57a 496 void DnsNameEncodeIp6(char* ip, char** pp)
andrewboyson 13:9cd54f7db57a 497 {
andrewboyson 13:9cd54f7db57a 498 char* p = *pp; //Get a convenient pointer to the next byte
andrewboyson 13:9cd54f7db57a 499
andrewboyson 13:9cd54f7db57a 500 ip += 16;
andrewboyson 13:9cd54f7db57a 501 for (int i = 0; i < 16; i++)
andrewboyson 13:9cd54f7db57a 502 {
andrewboyson 13:9cd54f7db57a 503 ip--;
andrewboyson 13:9cd54f7db57a 504
andrewboyson 13:9cd54f7db57a 505 int v;
andrewboyson 13:9cd54f7db57a 506
andrewboyson 13:9cd54f7db57a 507 *p++ = 1;
andrewboyson 13:9cd54f7db57a 508 v = *ip & 0x0F;
andrewboyson 13:9cd54f7db57a 509 *p++ = v < 10 ? v + '0' : v - 10 + 'a';
andrewboyson 13:9cd54f7db57a 510
andrewboyson 13:9cd54f7db57a 511 *p++ = 1;
andrewboyson 13:9cd54f7db57a 512 v = *ip >> 4;
andrewboyson 13:9cd54f7db57a 513 *p++ = v < 10 ? v + '0' : v - 10 + 'a';
andrewboyson 13:9cd54f7db57a 514 }
andrewboyson 13:9cd54f7db57a 515 char* pLen = p;
andrewboyson 13:9cd54f7db57a 516 p++;
andrewboyson 13:9cd54f7db57a 517
andrewboyson 13:9cd54f7db57a 518 *pLen = sprintf(p, "ip6");
andrewboyson 13:9cd54f7db57a 519 p += *pLen;
andrewboyson 13:9cd54f7db57a 520 pLen = p;
andrewboyson 13:9cd54f7db57a 521 p++;
andrewboyson 13:9cd54f7db57a 522
andrewboyson 13:9cd54f7db57a 523 *pLen = sprintf(p, "arpa");
andrewboyson 13:9cd54f7db57a 524 p += *pLen;
andrewboyson 13:9cd54f7db57a 525 pLen = p;
andrewboyson 13:9cd54f7db57a 526 p++;
andrewboyson 13:9cd54f7db57a 527
andrewboyson 13:9cd54f7db57a 528 *pLen = 0;
andrewboyson 13:9cd54f7db57a 529
andrewboyson 13:9cd54f7db57a 530 *pp = p; //Save the convenient pointer back into the pointer to pointer
andrewboyson 13:9cd54f7db57a 531
andrewboyson 13:9cd54f7db57a 532 }
andrewboyson 13:9cd54f7db57a 533
andrewboyson 37:793b39683406 534 void DnsNameEncodePtr(char* pName, char** pp)
andrewboyson 13:9cd54f7db57a 535 {
andrewboyson 13:9cd54f7db57a 536 char* p = *pp; //Get a convenient pointer to the next byte
andrewboyson 13:9cd54f7db57a 537
andrewboyson 13:9cd54f7db57a 538 char* pLen = p; //Record the position of the first length byte
andrewboyson 13:9cd54f7db57a 539 p++; //Move to the start of the first field
andrewboyson 13:9cd54f7db57a 540
andrewboyson 13:9cd54f7db57a 541 while (true)
andrewboyson 13:9cd54f7db57a 542 {
andrewboyson 13:9cd54f7db57a 543 char c = *pName;
andrewboyson 13:9cd54f7db57a 544 switch (c)
andrewboyson 13:9cd54f7db57a 545 {
andrewboyson 13:9cd54f7db57a 546 case 0:
andrewboyson 13:9cd54f7db57a 547 *pLen = p - pLen - 1;
andrewboyson 13:9cd54f7db57a 548 *p = 0;
andrewboyson 13:9cd54f7db57a 549 p++;
andrewboyson 13:9cd54f7db57a 550 *pp = p; //Save the convenient pointer back into the pointer to pointer
andrewboyson 13:9cd54f7db57a 551 return;
andrewboyson 13:9cd54f7db57a 552 case '.':
andrewboyson 13:9cd54f7db57a 553 *pLen = p - pLen - 1;
andrewboyson 13:9cd54f7db57a 554 pLen = p;
andrewboyson 13:9cd54f7db57a 555 p++;
andrewboyson 13:9cd54f7db57a 556 break;
andrewboyson 13:9cd54f7db57a 557 default:
andrewboyson 13:9cd54f7db57a 558 *p = c;
andrewboyson 13:9cd54f7db57a 559 p++;
andrewboyson 13:9cd54f7db57a 560 break;
andrewboyson 13:9cd54f7db57a 561 }
andrewboyson 13:9cd54f7db57a 562 pName++;
andrewboyson 13:9cd54f7db57a 563 }
andrewboyson 13:9cd54f7db57a 564 }