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:
Wed Dec 16 17:33:22 2020 +0000
Revision:
172:9bc3c7b2cca1
Parent:
171:f708d6776752
Child:
176:7eb916c22084
Modified name resolution to work with both IPv4 and IPv6. Before there were two independent modules.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 61:aad055f1b0d1 1 #include <stdbool.h>
andrewboyson 61:aad055f1b0d1 2 #include <string.h>
andrewboyson 61:aad055f1b0d1 3
andrewboyson 49:1a6336f2b3f9 4 #include "log.h"
andrewboyson 49:1a6336f2b3f9 5 #include "ip6addr.h"
andrewboyson 49:1a6336f2b3f9 6 #include "http.h"
andrewboyson 49:1a6336f2b3f9 7 #include "action.h"
andrewboyson 49:1a6336f2b3f9 8 #include "ndp.h"
andrewboyson 112:f8694d0b8858 9 #include "ntpclient.h"
andrewboyson 49:1a6336f2b3f9 10 #include "slaac.h"
andrewboyson 57:e0fb648acf48 11 #include "tftp.h"
andrewboyson 49:1a6336f2b3f9 12
andrewboyson 172:9bc3c7b2cca1 13 void Ip6AddrClear(char* ip)
andrewboyson 49:1a6336f2b3f9 14 {
andrewboyson 171:f708d6776752 15 ip[ 0] = 0; //Just set the first byte to zero
andrewboyson 171:f708d6776752 16 ip[12] = 0; //and the 12 (the first byte of a IP4 address)
andrewboyson 49:1a6336f2b3f9 17 }
andrewboyson 172:9bc3c7b2cca1 18 bool Ip6AddrIsEmpty(const char* ip)
andrewboyson 49:1a6336f2b3f9 19 {
andrewboyson 171:f708d6776752 20 return !ip[0] && !ip[12]; //Check for the first and 12th byte being non zero
andrewboyson 171:f708d6776752 21 }
andrewboyson 172:9bc3c7b2cca1 22 void Ip6AddrFromIp4(char* ip6, uint32_t ip4)
andrewboyson 171:f708d6776752 23 {
andrewboyson 171:f708d6776752 24 memset(ip6, 0, 16);
andrewboyson 171:f708d6776752 25 *ip6++ = 0; *ip6++ = 0; *ip6++ = 0; *ip6++ = 0;
andrewboyson 171:f708d6776752 26 *ip6++ = 0; *ip6++ = 0; *ip6++ = 0; *ip6++ = 0;
andrewboyson 171:f708d6776752 27 *ip6++ = 0; *ip6++ = 0; *ip6++ = 0; *ip6++ = 0;
andrewboyson 171:f708d6776752 28 *ip6++ = (ip4 >> 0) & 0xFF;
andrewboyson 171:f708d6776752 29 *ip6++ = (ip4 >> 8) & 0xFF;
andrewboyson 171:f708d6776752 30 *ip6++ = (ip4 >> 16) & 0xFF;
andrewboyson 171:f708d6776752 31 *ip6++ = (ip4 >> 24) & 0xFF;
andrewboyson 171:f708d6776752 32 }
andrewboyson 172:9bc3c7b2cca1 33 uint32_t Ip6AddrToIp4(char* ip6)
andrewboyson 171:f708d6776752 34 {
andrewboyson 171:f708d6776752 35 uint32_t ip4;
andrewboyson 171:f708d6776752 36 ip4 = ip6[12] << 0;
andrewboyson 171:f708d6776752 37 ip4 |= ip6[13] << 8;
andrewboyson 171:f708d6776752 38 ip4 |= ip6[14] << 16;
andrewboyson 171:f708d6776752 39 ip4 |= ip6[15] << 24;
andrewboyson 171:f708d6776752 40 return ip4;
andrewboyson 49:1a6336f2b3f9 41 }
andrewboyson 49:1a6336f2b3f9 42 static void addHexNibble(bool* pAdded, int number, int index, char** pp)
andrewboyson 49:1a6336f2b3f9 43 {
andrewboyson 49:1a6336f2b3f9 44 int nibble = number;
andrewboyson 49:1a6336f2b3f9 45 if (index) nibble >>= 4;
andrewboyson 49:1a6336f2b3f9 46 nibble &= 0xF;
andrewboyson 49:1a6336f2b3f9 47
andrewboyson 49:1a6336f2b3f9 48 if (nibble || *pAdded)
andrewboyson 49:1a6336f2b3f9 49 {
andrewboyson 49:1a6336f2b3f9 50 **pp = nibble < 10 ? nibble + '0' : nibble - 10 + 'a';
andrewboyson 49:1a6336f2b3f9 51 *pp += 1;
andrewboyson 49:1a6336f2b3f9 52 *pAdded = true;
andrewboyson 49:1a6336f2b3f9 53 }
andrewboyson 49:1a6336f2b3f9 54 }
andrewboyson 172:9bc3c7b2cca1 55 int Ip6AddrToString(const char* pIp, int size, char* pText)
andrewboyson 49:1a6336f2b3f9 56 {
andrewboyson 143:8cec8f08dc54 57 const char* pIpE = pIp + 16;
andrewboyson 49:1a6336f2b3f9 58 char* p = pText;
andrewboyson 49:1a6336f2b3f9 59 while (true)
andrewboyson 49:1a6336f2b3f9 60 {
andrewboyson 49:1a6336f2b3f9 61 bool added = false;
andrewboyson 49:1a6336f2b3f9 62 if (*pIp || *(pIp + 1))
andrewboyson 49:1a6336f2b3f9 63 {
andrewboyson 49:1a6336f2b3f9 64 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 0), 1, &p);
andrewboyson 49:1a6336f2b3f9 65 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 0), 0, &p);
andrewboyson 49:1a6336f2b3f9 66 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 1), 1, &p);
andrewboyson 49:1a6336f2b3f9 67 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 1), 0, &p);
andrewboyson 49:1a6336f2b3f9 68 }
andrewboyson 49:1a6336f2b3f9 69
andrewboyson 49:1a6336f2b3f9 70 pIp += 2;
andrewboyson 49:1a6336f2b3f9 71 if (pIp >= pIpE) break;
andrewboyson 49:1a6336f2b3f9 72
andrewboyson 49:1a6336f2b3f9 73 if (p > pText + size - 2) break; *p++ = ':';
andrewboyson 49:1a6336f2b3f9 74 }
andrewboyson 49:1a6336f2b3f9 75 *p = 0;
andrewboyson 49:1a6336f2b3f9 76 return p - pText;
andrewboyson 49:1a6336f2b3f9 77 }
andrewboyson 49:1a6336f2b3f9 78 static void logHexNibble(bool* pAdded, int number, int index)
andrewboyson 49:1a6336f2b3f9 79 {
andrewboyson 49:1a6336f2b3f9 80 int nibble = number;
andrewboyson 49:1a6336f2b3f9 81 if (index) nibble >>= 4;
andrewboyson 49:1a6336f2b3f9 82 nibble &= 0xF;
andrewboyson 49:1a6336f2b3f9 83
andrewboyson 49:1a6336f2b3f9 84 if (nibble || *pAdded)
andrewboyson 49:1a6336f2b3f9 85 {
andrewboyson 121:bc048b65a630 86 LogChar(nibble < 10 ? nibble + '0' : nibble - 10 + 'a');
andrewboyson 49:1a6336f2b3f9 87 *pAdded = true;
andrewboyson 49:1a6336f2b3f9 88 }
andrewboyson 49:1a6336f2b3f9 89 }
andrewboyson 172:9bc3c7b2cca1 90 int Ip6AddrLog(const char* pIp)
andrewboyson 49:1a6336f2b3f9 91 {
andrewboyson 49:1a6336f2b3f9 92 int count = 0;
andrewboyson 143:8cec8f08dc54 93 const char* pIpE = pIp + 16;
andrewboyson 49:1a6336f2b3f9 94 while (true)
andrewboyson 49:1a6336f2b3f9 95 {
andrewboyson 49:1a6336f2b3f9 96 bool added = false;
andrewboyson 49:1a6336f2b3f9 97 if (*pIp || *(pIp + 1))
andrewboyson 49:1a6336f2b3f9 98 {
andrewboyson 49:1a6336f2b3f9 99 logHexNibble(&added, *(pIp + 0), 1); if (added) count++;
andrewboyson 49:1a6336f2b3f9 100 logHexNibble(&added, *(pIp + 0), 0); if (added) count++;
andrewboyson 49:1a6336f2b3f9 101 logHexNibble(&added, *(pIp + 1), 1); if (added) count++;
andrewboyson 49:1a6336f2b3f9 102 logHexNibble(&added, *(pIp + 1), 0); if (added) count++;
andrewboyson 49:1a6336f2b3f9 103 }
andrewboyson 49:1a6336f2b3f9 104
andrewboyson 49:1a6336f2b3f9 105 pIp += 2;
andrewboyson 49:1a6336f2b3f9 106 if (pIp >= pIpE) break;
andrewboyson 49:1a6336f2b3f9 107
andrewboyson 121:bc048b65a630 108 LogChar(':'); count++;
andrewboyson 49:1a6336f2b3f9 109 }
andrewboyson 49:1a6336f2b3f9 110 return count;
andrewboyson 49:1a6336f2b3f9 111 }
andrewboyson 49:1a6336f2b3f9 112 static void httpHexNibble(bool* pAdded, int number, int index)
andrewboyson 49:1a6336f2b3f9 113 {
andrewboyson 49:1a6336f2b3f9 114 int nibble = number;
andrewboyson 49:1a6336f2b3f9 115 if (index) nibble >>= 4;
andrewboyson 49:1a6336f2b3f9 116 nibble &= 0xF;
andrewboyson 49:1a6336f2b3f9 117
andrewboyson 49:1a6336f2b3f9 118 if (nibble || *pAdded)
andrewboyson 49:1a6336f2b3f9 119 {
andrewboyson 54:84ef2b29cf7e 120 HttpAddChar(nibble < 10 ? nibble + '0' : nibble - 10 + 'a');
andrewboyson 49:1a6336f2b3f9 121 *pAdded = true;
andrewboyson 49:1a6336f2b3f9 122 }
andrewboyson 49:1a6336f2b3f9 123 }
andrewboyson 172:9bc3c7b2cca1 124 int Ip6AddrHttp(const char* pIp)
andrewboyson 49:1a6336f2b3f9 125 {
andrewboyson 49:1a6336f2b3f9 126 int count = 0;
andrewboyson 143:8cec8f08dc54 127 const char* pIpE = pIp + 16;
andrewboyson 49:1a6336f2b3f9 128 while (true)
andrewboyson 49:1a6336f2b3f9 129 {
andrewboyson 49:1a6336f2b3f9 130 bool added = false;
andrewboyson 49:1a6336f2b3f9 131 if (*pIp || *(pIp + 1))
andrewboyson 49:1a6336f2b3f9 132 {
andrewboyson 49:1a6336f2b3f9 133 httpHexNibble(&added, *(pIp + 0), 1); if (added) count++;
andrewboyson 49:1a6336f2b3f9 134 httpHexNibble(&added, *(pIp + 0), 0); if (added) count++;
andrewboyson 49:1a6336f2b3f9 135 httpHexNibble(&added, *(pIp + 1), 1); if (added) count++;
andrewboyson 49:1a6336f2b3f9 136 httpHexNibble(&added, *(pIp + 1), 0); if (added) count++;
andrewboyson 49:1a6336f2b3f9 137 }
andrewboyson 49:1a6336f2b3f9 138
andrewboyson 49:1a6336f2b3f9 139 pIp += 2;
andrewboyson 49:1a6336f2b3f9 140 if (pIp >= pIpE) break;
andrewboyson 49:1a6336f2b3f9 141
andrewboyson 54:84ef2b29cf7e 142 HttpAddChar(':'); count++;
andrewboyson 49:1a6336f2b3f9 143 }
andrewboyson 49:1a6336f2b3f9 144 return count;
andrewboyson 49:1a6336f2b3f9 145 }
andrewboyson 172:9bc3c7b2cca1 146 bool Ip6AddrIsSame(const char* ipA, const char* ipB)
andrewboyson 49:1a6336f2b3f9 147 {
andrewboyson 49:1a6336f2b3f9 148 return !memcmp(ipA, ipB, 16); //Though about optimising by doing a reverse loop but unlikely to be faster than an optimised assembly coded library function
andrewboyson 49:1a6336f2b3f9 149 }
andrewboyson 172:9bc3c7b2cca1 150 void Ip6AddrCopy(char* ipTo, const char* ipFrom)
andrewboyson 49:1a6336f2b3f9 151 {
andrewboyson 49:1a6336f2b3f9 152 memcpy(ipTo, ipFrom, 16);
andrewboyson 49:1a6336f2b3f9 153 }
andrewboyson 49:1a6336f2b3f9 154
andrewboyson 172:9bc3c7b2cca1 155 bool Ip6AddrIsIp4(const char *p)
andrewboyson 172:9bc3c7b2cca1 156 {
andrewboyson 172:9bc3c7b2cca1 157 if (p[ 0] != 0) return false;
andrewboyson 172:9bc3c7b2cca1 158 if (p[12] != 0) return false;
andrewboyson 172:9bc3c7b2cca1 159 return true;
andrewboyson 172:9bc3c7b2cca1 160 }
andrewboyson 172:9bc3c7b2cca1 161 bool Ip6AddrIsLinkLocal(const char* p)
andrewboyson 172:9bc3c7b2cca1 162 {
andrewboyson 172:9bc3c7b2cca1 163 if (p[0] != 0xFE) return false;
andrewboyson 172:9bc3c7b2cca1 164 if (p[1] != 0x80) return false;
andrewboyson 172:9bc3c7b2cca1 165 return true;
andrewboyson 172:9bc3c7b2cca1 166 }
andrewboyson 172:9bc3c7b2cca1 167 bool Ip6AddrIsUniqueLocal(const char* p)
andrewboyson 172:9bc3c7b2cca1 168 {
andrewboyson 172:9bc3c7b2cca1 169 if (p[0] != 0xFD) return false;
andrewboyson 172:9bc3c7b2cca1 170 if (p[1] != 0x00) return false;
andrewboyson 172:9bc3c7b2cca1 171 return true;
andrewboyson 172:9bc3c7b2cca1 172 }
andrewboyson 172:9bc3c7b2cca1 173 bool Ip6AddrIsGlobal(const char* p)
andrewboyson 172:9bc3c7b2cca1 174 {
andrewboyson 172:9bc3c7b2cca1 175 //[RFC 4291] designates 2000::/3 to be global unicast address space that the Internet Assigned Numbers Authority (IANA) may allocate to the RIRs.
andrewboyson 172:9bc3c7b2cca1 176 //The top byte AND 0b11100000 (0xE0)must be 0x20
andrewboyson 172:9bc3c7b2cca1 177 return (p[0] & 0xE0) == 0x20;
andrewboyson 172:9bc3c7b2cca1 178 }
andrewboyson 172:9bc3c7b2cca1 179
andrewboyson 143:8cec8f08dc54 180 bool Ip6AddrIsSolicited(const char* p)
andrewboyson 136:8a65abb0dc63 181 {
andrewboyson 136:8a65abb0dc63 182 if (*p++ != 0xff) return false;
andrewboyson 136:8a65abb0dc63 183 if (*p++ != 0x02) return false;
andrewboyson 136:8a65abb0dc63 184
andrewboyson 136:8a65abb0dc63 185 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 186 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 187
andrewboyson 136:8a65abb0dc63 188 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 189 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 190
andrewboyson 136:8a65abb0dc63 191 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 192 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 193
andrewboyson 136:8a65abb0dc63 194 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 195 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 196
andrewboyson 136:8a65abb0dc63 197 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 198 if (*p++ != 0x01) return false;
andrewboyson 136:8a65abb0dc63 199
andrewboyson 136:8a65abb0dc63 200 if (*p++ != 0xff) return false;
andrewboyson 136:8a65abb0dc63 201
andrewboyson 136:8a65abb0dc63 202 return true;
andrewboyson 136:8a65abb0dc63 203 }
andrewboyson 143:8cec8f08dc54 204 bool Ip6AddrIsMulticast(const char *p)
andrewboyson 136:8a65abb0dc63 205 {
andrewboyson 136:8a65abb0dc63 206 return *p == 0xFF;
andrewboyson 136:8a65abb0dc63 207 }
andrewboyson 143:8cec8f08dc54 208 bool Ip6AddrIsSameGroup(const char* pA, const char* pB)
andrewboyson 136:8a65abb0dc63 209 {
andrewboyson 136:8a65abb0dc63 210 pA += 13;
andrewboyson 136:8a65abb0dc63 211 pB += 13;
andrewboyson 136:8a65abb0dc63 212 if (*pA++ != *pB++) return false;
andrewboyson 136:8a65abb0dc63 213 if (*pA++ != *pB++) return false;
andrewboyson 136:8a65abb0dc63 214 return *pA == *pB;
andrewboyson 136:8a65abb0dc63 215 }
andrewboyson 136:8a65abb0dc63 216
andrewboyson 172:9bc3c7b2cca1 217 const char Ip6AddrAllNodes [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
andrewboyson 172:9bc3c7b2cca1 218 const char Ip6AddrAllRouters[] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
andrewboyson 172:9bc3c7b2cca1 219 const char Ip6AddrMdns [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
andrewboyson 172:9bc3c7b2cca1 220 const char Ip6AddrLlmnr [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03};
andrewboyson 172:9bc3c7b2cca1 221 const char Ip6AddrNtp [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01};
andrewboyson 49:1a6336f2b3f9 222
andrewboyson 172:9bc3c7b2cca1 223 void Ip6AddrFromDest(int dest, char* pDstIp)
andrewboyson 49:1a6336f2b3f9 224 {
andrewboyson 49:1a6336f2b3f9 225 switch (dest)
andrewboyson 49:1a6336f2b3f9 226 {
andrewboyson 171:f708d6776752 227 case UNICAST: /*No change*/ break;
andrewboyson 172:9bc3c7b2cca1 228 case UNICAST_DNS: Ip6AddrCopy(pDstIp, NdpDnsServer ); break;
andrewboyson 172:9bc3c7b2cca1 229 case UNICAST_NTP: Ip6AddrCopy(pDstIp, NtpClientQueryServerIp6); break;
andrewboyson 172:9bc3c7b2cca1 230 case UNICAST_TFTP: Ip6AddrCopy(pDstIp, TftpServerIp6 ); break;
andrewboyson 172:9bc3c7b2cca1 231 case MULTICAST_NODE: Ip6AddrCopy(pDstIp, Ip6AddrAllNodes ); break;
andrewboyson 172:9bc3c7b2cca1 232 case MULTICAST_ROUTER: Ip6AddrCopy(pDstIp, Ip6AddrAllRouters ); break;
andrewboyson 172:9bc3c7b2cca1 233 case MULTICAST_MDNS: Ip6AddrCopy(pDstIp, Ip6AddrMdns ); break;
andrewboyson 172:9bc3c7b2cca1 234 case MULTICAST_LLMNR: Ip6AddrCopy(pDstIp, Ip6AddrLlmnr ); break;
andrewboyson 172:9bc3c7b2cca1 235 case MULTICAST_NTP: Ip6AddrCopy(pDstIp, Ip6AddrNtp ); break;
andrewboyson 49:1a6336f2b3f9 236 default:
andrewboyson 52:fbc5a46b5e16 237 LogTimeF("Ip6AddressFromDest unknown destination %d\r\n", dest);
andrewboyson 49:1a6336f2b3f9 238 break;
andrewboyson 49:1a6336f2b3f9 239 }
andrewboyson 49:1a6336f2b3f9 240 }