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 Dec 14 20:55:40 2017 +0000
Revision:
59:e0e556c8bd46
Parent:
58:d48c899e482f
Added buffer length to help avoid over runs

Who changed what in which revision?

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