Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Mon Jan 18 18:23:46 2021 +0000
Revision:
187:122fc1996c86
Parent:
176:7eb916c22084
Child:
193:47a953ab571b
Changed Ip4Address to Ip4Addr.; Moved Ip6AddrIsExternal from NdpNeedsToBeRouted.

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 49:1a6336f2b3f9 16 }
andrewboyson 172:9bc3c7b2cca1 17 bool Ip6AddrIsEmpty(const char* ip)
andrewboyson 49:1a6336f2b3f9 18 {
andrewboyson 176:7eb916c22084 19 return !ip[0]; //Check for the first byte being non zero
andrewboyson 49:1a6336f2b3f9 20 }
andrewboyson 49:1a6336f2b3f9 21 static void addHexNibble(bool* pAdded, int number, int index, char** pp)
andrewboyson 49:1a6336f2b3f9 22 {
andrewboyson 49:1a6336f2b3f9 23 int nibble = number;
andrewboyson 49:1a6336f2b3f9 24 if (index) nibble >>= 4;
andrewboyson 49:1a6336f2b3f9 25 nibble &= 0xF;
andrewboyson 49:1a6336f2b3f9 26
andrewboyson 49:1a6336f2b3f9 27 if (nibble || *pAdded)
andrewboyson 49:1a6336f2b3f9 28 {
andrewboyson 49:1a6336f2b3f9 29 **pp = nibble < 10 ? nibble + '0' : nibble - 10 + 'a';
andrewboyson 49:1a6336f2b3f9 30 *pp += 1;
andrewboyson 49:1a6336f2b3f9 31 *pAdded = true;
andrewboyson 49:1a6336f2b3f9 32 }
andrewboyson 49:1a6336f2b3f9 33 }
andrewboyson 172:9bc3c7b2cca1 34 int Ip6AddrToString(const char* pIp, int size, char* pText)
andrewboyson 49:1a6336f2b3f9 35 {
andrewboyson 143:8cec8f08dc54 36 const char* pIpE = pIp + 16;
andrewboyson 49:1a6336f2b3f9 37 char* p = pText;
andrewboyson 49:1a6336f2b3f9 38 while (true)
andrewboyson 49:1a6336f2b3f9 39 {
andrewboyson 49:1a6336f2b3f9 40 bool added = false;
andrewboyson 49:1a6336f2b3f9 41 if (*pIp || *(pIp + 1))
andrewboyson 49:1a6336f2b3f9 42 {
andrewboyson 49:1a6336f2b3f9 43 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 0), 1, &p);
andrewboyson 49:1a6336f2b3f9 44 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 0), 0, &p);
andrewboyson 49:1a6336f2b3f9 45 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 1), 1, &p);
andrewboyson 49:1a6336f2b3f9 46 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 1), 0, &p);
andrewboyson 49:1a6336f2b3f9 47 }
andrewboyson 49:1a6336f2b3f9 48
andrewboyson 49:1a6336f2b3f9 49 pIp += 2;
andrewboyson 49:1a6336f2b3f9 50 if (pIp >= pIpE) break;
andrewboyson 49:1a6336f2b3f9 51
andrewboyson 49:1a6336f2b3f9 52 if (p > pText + size - 2) break; *p++ = ':';
andrewboyson 49:1a6336f2b3f9 53 }
andrewboyson 49:1a6336f2b3f9 54 *p = 0;
andrewboyson 49:1a6336f2b3f9 55 return p - pText;
andrewboyson 49:1a6336f2b3f9 56 }
andrewboyson 49:1a6336f2b3f9 57 static void logHexNibble(bool* pAdded, int number, int index)
andrewboyson 49:1a6336f2b3f9 58 {
andrewboyson 49:1a6336f2b3f9 59 int nibble = number;
andrewboyson 49:1a6336f2b3f9 60 if (index) nibble >>= 4;
andrewboyson 49:1a6336f2b3f9 61 nibble &= 0xF;
andrewboyson 49:1a6336f2b3f9 62
andrewboyson 49:1a6336f2b3f9 63 if (nibble || *pAdded)
andrewboyson 49:1a6336f2b3f9 64 {
andrewboyson 121:bc048b65a630 65 LogChar(nibble < 10 ? nibble + '0' : nibble - 10 + 'a');
andrewboyson 49:1a6336f2b3f9 66 *pAdded = true;
andrewboyson 49:1a6336f2b3f9 67 }
andrewboyson 49:1a6336f2b3f9 68 }
andrewboyson 172:9bc3c7b2cca1 69 int Ip6AddrLog(const char* pIp)
andrewboyson 49:1a6336f2b3f9 70 {
andrewboyson 49:1a6336f2b3f9 71 int count = 0;
andrewboyson 143:8cec8f08dc54 72 const char* pIpE = pIp + 16;
andrewboyson 49:1a6336f2b3f9 73 while (true)
andrewboyson 49:1a6336f2b3f9 74 {
andrewboyson 49:1a6336f2b3f9 75 bool added = false;
andrewboyson 49:1a6336f2b3f9 76 if (*pIp || *(pIp + 1))
andrewboyson 49:1a6336f2b3f9 77 {
andrewboyson 49:1a6336f2b3f9 78 logHexNibble(&added, *(pIp + 0), 1); if (added) count++;
andrewboyson 49:1a6336f2b3f9 79 logHexNibble(&added, *(pIp + 0), 0); if (added) count++;
andrewboyson 49:1a6336f2b3f9 80 logHexNibble(&added, *(pIp + 1), 1); if (added) count++;
andrewboyson 49:1a6336f2b3f9 81 logHexNibble(&added, *(pIp + 1), 0); if (added) count++;
andrewboyson 49:1a6336f2b3f9 82 }
andrewboyson 49:1a6336f2b3f9 83
andrewboyson 49:1a6336f2b3f9 84 pIp += 2;
andrewboyson 49:1a6336f2b3f9 85 if (pIp >= pIpE) break;
andrewboyson 49:1a6336f2b3f9 86
andrewboyson 121:bc048b65a630 87 LogChar(':'); count++;
andrewboyson 49:1a6336f2b3f9 88 }
andrewboyson 49:1a6336f2b3f9 89 return count;
andrewboyson 49:1a6336f2b3f9 90 }
andrewboyson 49:1a6336f2b3f9 91 static void httpHexNibble(bool* pAdded, int number, int index)
andrewboyson 49:1a6336f2b3f9 92 {
andrewboyson 49:1a6336f2b3f9 93 int nibble = number;
andrewboyson 49:1a6336f2b3f9 94 if (index) nibble >>= 4;
andrewboyson 49:1a6336f2b3f9 95 nibble &= 0xF;
andrewboyson 49:1a6336f2b3f9 96
andrewboyson 49:1a6336f2b3f9 97 if (nibble || *pAdded)
andrewboyson 49:1a6336f2b3f9 98 {
andrewboyson 54:84ef2b29cf7e 99 HttpAddChar(nibble < 10 ? nibble + '0' : nibble - 10 + 'a');
andrewboyson 49:1a6336f2b3f9 100 *pAdded = true;
andrewboyson 49:1a6336f2b3f9 101 }
andrewboyson 49:1a6336f2b3f9 102 }
andrewboyson 172:9bc3c7b2cca1 103 int Ip6AddrHttp(const char* pIp)
andrewboyson 49:1a6336f2b3f9 104 {
andrewboyson 49:1a6336f2b3f9 105 int count = 0;
andrewboyson 143:8cec8f08dc54 106 const char* pIpE = pIp + 16;
andrewboyson 49:1a6336f2b3f9 107 while (true)
andrewboyson 49:1a6336f2b3f9 108 {
andrewboyson 49:1a6336f2b3f9 109 bool added = false;
andrewboyson 49:1a6336f2b3f9 110 if (*pIp || *(pIp + 1))
andrewboyson 49:1a6336f2b3f9 111 {
andrewboyson 49:1a6336f2b3f9 112 httpHexNibble(&added, *(pIp + 0), 1); if (added) count++;
andrewboyson 49:1a6336f2b3f9 113 httpHexNibble(&added, *(pIp + 0), 0); if (added) count++;
andrewboyson 49:1a6336f2b3f9 114 httpHexNibble(&added, *(pIp + 1), 1); if (added) count++;
andrewboyson 49:1a6336f2b3f9 115 httpHexNibble(&added, *(pIp + 1), 0); if (added) count++;
andrewboyson 49:1a6336f2b3f9 116 }
andrewboyson 49:1a6336f2b3f9 117
andrewboyson 49:1a6336f2b3f9 118 pIp += 2;
andrewboyson 49:1a6336f2b3f9 119 if (pIp >= pIpE) break;
andrewboyson 49:1a6336f2b3f9 120
andrewboyson 54:84ef2b29cf7e 121 HttpAddChar(':'); count++;
andrewboyson 49:1a6336f2b3f9 122 }
andrewboyson 49:1a6336f2b3f9 123 return count;
andrewboyson 49:1a6336f2b3f9 124 }
andrewboyson 172:9bc3c7b2cca1 125 bool Ip6AddrIsSame(const char* ipA, const char* ipB)
andrewboyson 49:1a6336f2b3f9 126 {
andrewboyson 49:1a6336f2b3f9 127 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 128 }
andrewboyson 172:9bc3c7b2cca1 129 void Ip6AddrCopy(char* ipTo, const char* ipFrom)
andrewboyson 49:1a6336f2b3f9 130 {
andrewboyson 49:1a6336f2b3f9 131 memcpy(ipTo, ipFrom, 16);
andrewboyson 49:1a6336f2b3f9 132 }
andrewboyson 49:1a6336f2b3f9 133
andrewboyson 172:9bc3c7b2cca1 134 bool Ip6AddrIsLinkLocal(const char* p)
andrewboyson 172:9bc3c7b2cca1 135 {
andrewboyson 172:9bc3c7b2cca1 136 if (p[0] != 0xFE) return false;
andrewboyson 172:9bc3c7b2cca1 137 if (p[1] != 0x80) return false;
andrewboyson 172:9bc3c7b2cca1 138 return true;
andrewboyson 172:9bc3c7b2cca1 139 }
andrewboyson 172:9bc3c7b2cca1 140 bool Ip6AddrIsUniqueLocal(const char* p)
andrewboyson 172:9bc3c7b2cca1 141 {
andrewboyson 172:9bc3c7b2cca1 142 if (p[0] != 0xFD) return false;
andrewboyson 172:9bc3c7b2cca1 143 if (p[1] != 0x00) return false;
andrewboyson 172:9bc3c7b2cca1 144 return true;
andrewboyson 172:9bc3c7b2cca1 145 }
andrewboyson 172:9bc3c7b2cca1 146 bool Ip6AddrIsGlobal(const char* p)
andrewboyson 172:9bc3c7b2cca1 147 {
andrewboyson 172:9bc3c7b2cca1 148 //[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 149 //The top byte AND 0b11100000 (0xE0)must be 0x20
andrewboyson 172:9bc3c7b2cca1 150 return (p[0] & 0xE0) == 0x20;
andrewboyson 172:9bc3c7b2cca1 151 }
andrewboyson 187:122fc1996c86 152 bool Ip6AddrIsExternal(const char* p)
andrewboyson 187:122fc1996c86 153 {
andrewboyson 187:122fc1996c86 154 //Logic is address must be global and not have the global prefix
andrewboyson 187:122fc1996c86 155 if (!Ip6AddrIsGlobal(p)) return false;
andrewboyson 187:122fc1996c86 156 if (!NdpGlobalPrefixLength) return false;
andrewboyson 187:122fc1996c86 157 if (memcmp(NdpGlobalPrefix, p, NdpGlobalPrefixLength) != 0) return false; //Only 0 if the same
andrewboyson 187:122fc1996c86 158 return true;
andrewboyson 187:122fc1996c86 159
andrewboyson 187:122fc1996c86 160 }
andrewboyson 143:8cec8f08dc54 161 bool Ip6AddrIsSolicited(const char* p)
andrewboyson 136:8a65abb0dc63 162 {
andrewboyson 136:8a65abb0dc63 163 if (*p++ != 0xff) return false;
andrewboyson 136:8a65abb0dc63 164 if (*p++ != 0x02) return false;
andrewboyson 136:8a65abb0dc63 165
andrewboyson 136:8a65abb0dc63 166 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 167 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 168
andrewboyson 136:8a65abb0dc63 169 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 170 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 171
andrewboyson 136:8a65abb0dc63 172 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 173 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 174
andrewboyson 136:8a65abb0dc63 175 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 176 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 177
andrewboyson 136:8a65abb0dc63 178 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 179 if (*p++ != 0x01) return false;
andrewboyson 136:8a65abb0dc63 180
andrewboyson 136:8a65abb0dc63 181 if (*p++ != 0xff) return false;
andrewboyson 136:8a65abb0dc63 182
andrewboyson 136:8a65abb0dc63 183 return true;
andrewboyson 136:8a65abb0dc63 184 }
andrewboyson 143:8cec8f08dc54 185 bool Ip6AddrIsMulticast(const char *p)
andrewboyson 136:8a65abb0dc63 186 {
andrewboyson 136:8a65abb0dc63 187 return *p == 0xFF;
andrewboyson 136:8a65abb0dc63 188 }
andrewboyson 143:8cec8f08dc54 189 bool Ip6AddrIsSameGroup(const char* pA, const char* pB)
andrewboyson 136:8a65abb0dc63 190 {
andrewboyson 136:8a65abb0dc63 191 pA += 13;
andrewboyson 136:8a65abb0dc63 192 pB += 13;
andrewboyson 136:8a65abb0dc63 193 if (*pA++ != *pB++) return false;
andrewboyson 136:8a65abb0dc63 194 if (*pA++ != *pB++) return false;
andrewboyson 136:8a65abb0dc63 195 return *pA == *pB;
andrewboyson 136:8a65abb0dc63 196 }
andrewboyson 136:8a65abb0dc63 197
andrewboyson 172:9bc3c7b2cca1 198 const char Ip6AddrAllNodes [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
andrewboyson 172:9bc3c7b2cca1 199 const char Ip6AddrAllRouters[] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
andrewboyson 172:9bc3c7b2cca1 200 const char Ip6AddrMdns [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
andrewboyson 172:9bc3c7b2cca1 201 const char Ip6AddrLlmnr [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03};
andrewboyson 172:9bc3c7b2cca1 202 const char Ip6AddrNtp [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01};
andrewboyson 49:1a6336f2b3f9 203
andrewboyson 172:9bc3c7b2cca1 204 void Ip6AddrFromDest(int dest, char* pDstIp)
andrewboyson 49:1a6336f2b3f9 205 {
andrewboyson 49:1a6336f2b3f9 206 switch (dest)
andrewboyson 49:1a6336f2b3f9 207 {
andrewboyson 171:f708d6776752 208 case UNICAST: /*No change*/ break;
andrewboyson 172:9bc3c7b2cca1 209 case UNICAST_DNS: Ip6AddrCopy(pDstIp, NdpDnsServer ); break;
andrewboyson 172:9bc3c7b2cca1 210 case UNICAST_NTP: Ip6AddrCopy(pDstIp, NtpClientQueryServerIp6); break;
andrewboyson 172:9bc3c7b2cca1 211 case UNICAST_TFTP: Ip6AddrCopy(pDstIp, TftpServerIp6 ); break;
andrewboyson 172:9bc3c7b2cca1 212 case MULTICAST_NODE: Ip6AddrCopy(pDstIp, Ip6AddrAllNodes ); break;
andrewboyson 172:9bc3c7b2cca1 213 case MULTICAST_ROUTER: Ip6AddrCopy(pDstIp, Ip6AddrAllRouters ); break;
andrewboyson 172:9bc3c7b2cca1 214 case MULTICAST_MDNS: Ip6AddrCopy(pDstIp, Ip6AddrMdns ); break;
andrewboyson 172:9bc3c7b2cca1 215 case MULTICAST_LLMNR: Ip6AddrCopy(pDstIp, Ip6AddrLlmnr ); break;
andrewboyson 172:9bc3c7b2cca1 216 case MULTICAST_NTP: Ip6AddrCopy(pDstIp, Ip6AddrNtp ); break;
andrewboyson 49:1a6336f2b3f9 217 default:
andrewboyson 52:fbc5a46b5e16 218 LogTimeF("Ip6AddressFromDest unknown destination %d\r\n", dest);
andrewboyson 49:1a6336f2b3f9 219 break;
andrewboyson 49:1a6336f2b3f9 220 }
andrewboyson 49:1a6336f2b3f9 221 }