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:
Sat Dec 12 20:10:02 2020 +0000
Revision:
171:f708d6776752
Parent:
143:8cec8f08dc54
Child:
172:9bc3c7b2cca1
Modified NR to accept both IPV6 and IPV4 addresses instead of having two modules with diffrent address lengths. Encapsulated 32but address into lsb 128 bit address

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 49:1a6336f2b3f9 13 void Ip6AddressClear(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 107:cc58b4c2090b 18 bool Ip6AddressIsEmpty(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 171:f708d6776752 22 void Ip6AddressFromIp4(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 171:f708d6776752 33 uint32_t Ip6AddressToIp4(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 143:8cec8f08dc54 55 int Ip6AddressToString(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 143:8cec8f08dc54 90 int Ip6AddressLog(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 143:8cec8f08dc54 124 int Ip6AddressHttp(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 107:cc58b4c2090b 146 bool Ip6AddressIsSame(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 107:cc58b4c2090b 150 void Ip6AddressCopy(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 143:8cec8f08dc54 155 bool Ip6AddrIsSolicited(const char* p)
andrewboyson 136:8a65abb0dc63 156 {
andrewboyson 136:8a65abb0dc63 157 if (*p++ != 0xff) return false;
andrewboyson 136:8a65abb0dc63 158 if (*p++ != 0x02) return false;
andrewboyson 136:8a65abb0dc63 159
andrewboyson 136:8a65abb0dc63 160 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 161 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 162
andrewboyson 136:8a65abb0dc63 163 if (*p++ != 0x00) return false;
andrewboyson 136:8a65abb0dc63 164 if (*p++ != 0x00) 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++ != 0x01) return false;
andrewboyson 136:8a65abb0dc63 174
andrewboyson 136:8a65abb0dc63 175 if (*p++ != 0xff) return false;
andrewboyson 136:8a65abb0dc63 176
andrewboyson 136:8a65abb0dc63 177 return true;
andrewboyson 136:8a65abb0dc63 178 }
andrewboyson 143:8cec8f08dc54 179 bool Ip6AddrIsMulticast(const char *p)
andrewboyson 136:8a65abb0dc63 180 {
andrewboyson 136:8a65abb0dc63 181 return *p == 0xFF;
andrewboyson 136:8a65abb0dc63 182 }
andrewboyson 171:f708d6776752 183 bool Ip6AddrIsIp4(const char *p)
andrewboyson 171:f708d6776752 184 {
andrewboyson 171:f708d6776752 185 return p[0] == 0 && p[12] != 0;
andrewboyson 171:f708d6776752 186 }
andrewboyson 143:8cec8f08dc54 187 bool Ip6AddrIsSameGroup(const char* pA, const char* pB)
andrewboyson 136:8a65abb0dc63 188 {
andrewboyson 136:8a65abb0dc63 189 pA += 13;
andrewboyson 136:8a65abb0dc63 190 pB += 13;
andrewboyson 136:8a65abb0dc63 191 if (*pA++ != *pB++) return false;
andrewboyson 136:8a65abb0dc63 192 if (*pA++ != *pB++) return false;
andrewboyson 136:8a65abb0dc63 193 return *pA == *pB;
andrewboyson 136:8a65abb0dc63 194 }
andrewboyson 136:8a65abb0dc63 195
andrewboyson 107:cc58b4c2090b 196 const char Ip6AddressAllNodes [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
andrewboyson 107:cc58b4c2090b 197 const char Ip6AddressAllRouters[] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
andrewboyson 107:cc58b4c2090b 198 const char Ip6AddressMdns [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
andrewboyson 107:cc58b4c2090b 199 const char Ip6AddressLlmnr [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03};
andrewboyson 107:cc58b4c2090b 200 const char Ip6AddressNtp [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01};
andrewboyson 49:1a6336f2b3f9 201
andrewboyson 49:1a6336f2b3f9 202 void Ip6AddressFromDest(int dest, char* pDstIp)
andrewboyson 49:1a6336f2b3f9 203 {
andrewboyson 49:1a6336f2b3f9 204 switch (dest)
andrewboyson 49:1a6336f2b3f9 205 {
andrewboyson 171:f708d6776752 206 case UNICAST: /*No change*/ break;
andrewboyson 171:f708d6776752 207 case UNICAST_DNS: Ip6AddressCopy(pDstIp, NdpDnsServer ); break;
andrewboyson 171:f708d6776752 208 case UNICAST_NTP: Ip6AddressCopy(pDstIp, NtpClientQueryServerIp6); break;
andrewboyson 171:f708d6776752 209 case UNICAST_TFTP: Ip6AddressCopy(pDstIp, TftpServerIp6 ); break;
andrewboyson 171:f708d6776752 210 case MULTICAST_NODE: Ip6AddressCopy(pDstIp, Ip6AddressAllNodes ); break;
andrewboyson 171:f708d6776752 211 case MULTICAST_ROUTER: Ip6AddressCopy(pDstIp, Ip6AddressAllRouters ); break;
andrewboyson 171:f708d6776752 212 case MULTICAST_MDNS: Ip6AddressCopy(pDstIp, Ip6AddressMdns ); break;
andrewboyson 171:f708d6776752 213 case MULTICAST_LLMNR: Ip6AddressCopy(pDstIp, Ip6AddressLlmnr ); break;
andrewboyson 171:f708d6776752 214 case MULTICAST_NTP: Ip6AddressCopy(pDstIp, Ip6AddressNtp ); break;
andrewboyson 49:1a6336f2b3f9 215 default:
andrewboyson 52:fbc5a46b5e16 216 LogTimeF("Ip6AddressFromDest unknown destination %d\r\n", dest);
andrewboyson 49:1a6336f2b3f9 217 break;
andrewboyson 49:1a6336f2b3f9 218 }
andrewboyson 49:1a6336f2b3f9 219 }