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:
Tue Nov 28 17:05:46 2017 +0000
Revision:
57:e0fb648acf48
Parent:
54:84ef2b29cf7e
Added TFTP

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 49:1a6336f2b3f9 1 #include "mbed.h"
andrewboyson 49:1a6336f2b3f9 2 #include "log.h"
andrewboyson 49:1a6336f2b3f9 3 #include "ip6addr.h"
andrewboyson 49:1a6336f2b3f9 4 #include "http.h"
andrewboyson 49:1a6336f2b3f9 5 #include "action.h"
andrewboyson 49:1a6336f2b3f9 6 #include "ndp.h"
andrewboyson 49:1a6336f2b3f9 7 #include "ntp.h"
andrewboyson 49:1a6336f2b3f9 8 #include "slaac.h"
andrewboyson 57:e0fb648acf48 9 #include "tftp.h"
andrewboyson 49:1a6336f2b3f9 10
andrewboyson 49:1a6336f2b3f9 11 void Ip6AddressClear(char* ip)
andrewboyson 49:1a6336f2b3f9 12 {
andrewboyson 49:1a6336f2b3f9 13 *ip = 0;
andrewboyson 49:1a6336f2b3f9 14 }
andrewboyson 49:1a6336f2b3f9 15 bool Ip6AddressIsEmpty(char* ip)
andrewboyson 49:1a6336f2b3f9 16 {
andrewboyson 49:1a6336f2b3f9 17 return !*ip; //Just check for the first byte being non zero
andrewboyson 49:1a6336f2b3f9 18 }
andrewboyson 49:1a6336f2b3f9 19 static void addHexNibble(bool* pAdded, int number, int index, char** pp)
andrewboyson 49:1a6336f2b3f9 20 {
andrewboyson 49:1a6336f2b3f9 21 int nibble = number;
andrewboyson 49:1a6336f2b3f9 22 if (index) nibble >>= 4;
andrewboyson 49:1a6336f2b3f9 23 nibble &= 0xF;
andrewboyson 49:1a6336f2b3f9 24
andrewboyson 49:1a6336f2b3f9 25 if (nibble || *pAdded)
andrewboyson 49:1a6336f2b3f9 26 {
andrewboyson 49:1a6336f2b3f9 27 **pp = nibble < 10 ? nibble + '0' : nibble - 10 + 'a';
andrewboyson 49:1a6336f2b3f9 28 *pp += 1;
andrewboyson 49:1a6336f2b3f9 29 *pAdded = true;
andrewboyson 49:1a6336f2b3f9 30 }
andrewboyson 49:1a6336f2b3f9 31 }
andrewboyson 49:1a6336f2b3f9 32 int Ip6AddressToString(char* pIp, int size, char* pText)
andrewboyson 49:1a6336f2b3f9 33 {
andrewboyson 49:1a6336f2b3f9 34 char* pIpE = pIp + 16;
andrewboyson 49:1a6336f2b3f9 35 char* p = pText;
andrewboyson 49:1a6336f2b3f9 36 while (true)
andrewboyson 49:1a6336f2b3f9 37 {
andrewboyson 49:1a6336f2b3f9 38 bool added = false;
andrewboyson 49:1a6336f2b3f9 39 if (*pIp || *(pIp + 1))
andrewboyson 49:1a6336f2b3f9 40 {
andrewboyson 49:1a6336f2b3f9 41 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 0), 1, &p);
andrewboyson 49:1a6336f2b3f9 42 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 0), 0, &p);
andrewboyson 49:1a6336f2b3f9 43 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 1), 1, &p);
andrewboyson 49:1a6336f2b3f9 44 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 1), 0, &p);
andrewboyson 49:1a6336f2b3f9 45 }
andrewboyson 49:1a6336f2b3f9 46
andrewboyson 49:1a6336f2b3f9 47 pIp += 2;
andrewboyson 49:1a6336f2b3f9 48 if (pIp >= pIpE) break;
andrewboyson 49:1a6336f2b3f9 49
andrewboyson 49:1a6336f2b3f9 50 if (p > pText + size - 2) break; *p++ = ':';
andrewboyson 49:1a6336f2b3f9 51 }
andrewboyson 49:1a6336f2b3f9 52 *p = 0;
andrewboyson 49:1a6336f2b3f9 53 return p - pText;
andrewboyson 49:1a6336f2b3f9 54 }
andrewboyson 49:1a6336f2b3f9 55 static void logHexNibble(bool* pAdded, int number, int index)
andrewboyson 49:1a6336f2b3f9 56 {
andrewboyson 49:1a6336f2b3f9 57 int nibble = number;
andrewboyson 49:1a6336f2b3f9 58 if (index) nibble >>= 4;
andrewboyson 49:1a6336f2b3f9 59 nibble &= 0xF;
andrewboyson 49:1a6336f2b3f9 60
andrewboyson 49:1a6336f2b3f9 61 if (nibble || *pAdded)
andrewboyson 49:1a6336f2b3f9 62 {
andrewboyson 49:1a6336f2b3f9 63 LogPush(nibble < 10 ? nibble + '0' : nibble - 10 + 'a');
andrewboyson 49:1a6336f2b3f9 64 *pAdded = true;
andrewboyson 49:1a6336f2b3f9 65 }
andrewboyson 49:1a6336f2b3f9 66 }
andrewboyson 49:1a6336f2b3f9 67 int Ip6AddressLog(char* pIp)
andrewboyson 49:1a6336f2b3f9 68 {
andrewboyson 49:1a6336f2b3f9 69 int count = 0;
andrewboyson 49:1a6336f2b3f9 70 char* pIpE = pIp + 16;
andrewboyson 49:1a6336f2b3f9 71 while (true)
andrewboyson 49:1a6336f2b3f9 72 {
andrewboyson 49:1a6336f2b3f9 73 bool added = false;
andrewboyson 49:1a6336f2b3f9 74 if (*pIp || *(pIp + 1))
andrewboyson 49:1a6336f2b3f9 75 {
andrewboyson 49:1a6336f2b3f9 76 logHexNibble(&added, *(pIp + 0), 1); if (added) count++;
andrewboyson 49:1a6336f2b3f9 77 logHexNibble(&added, *(pIp + 0), 0); if (added) count++;
andrewboyson 49:1a6336f2b3f9 78 logHexNibble(&added, *(pIp + 1), 1); if (added) count++;
andrewboyson 49:1a6336f2b3f9 79 logHexNibble(&added, *(pIp + 1), 0); if (added) count++;
andrewboyson 49:1a6336f2b3f9 80 }
andrewboyson 49:1a6336f2b3f9 81
andrewboyson 49:1a6336f2b3f9 82 pIp += 2;
andrewboyson 49:1a6336f2b3f9 83 if (pIp >= pIpE) break;
andrewboyson 49:1a6336f2b3f9 84
andrewboyson 49:1a6336f2b3f9 85 LogPush(':'); count++;
andrewboyson 49:1a6336f2b3f9 86 }
andrewboyson 49:1a6336f2b3f9 87 return count;
andrewboyson 49:1a6336f2b3f9 88 }
andrewboyson 49:1a6336f2b3f9 89 static void httpHexNibble(bool* pAdded, int number, int index)
andrewboyson 49:1a6336f2b3f9 90 {
andrewboyson 49:1a6336f2b3f9 91 int nibble = number;
andrewboyson 49:1a6336f2b3f9 92 if (index) nibble >>= 4;
andrewboyson 49:1a6336f2b3f9 93 nibble &= 0xF;
andrewboyson 49:1a6336f2b3f9 94
andrewboyson 49:1a6336f2b3f9 95 if (nibble || *pAdded)
andrewboyson 49:1a6336f2b3f9 96 {
andrewboyson 54:84ef2b29cf7e 97 HttpAddChar(nibble < 10 ? nibble + '0' : nibble - 10 + 'a');
andrewboyson 49:1a6336f2b3f9 98 *pAdded = true;
andrewboyson 49:1a6336f2b3f9 99 }
andrewboyson 49:1a6336f2b3f9 100 }
andrewboyson 49:1a6336f2b3f9 101 int Ip6AddressHttp(char* pIp)
andrewboyson 49:1a6336f2b3f9 102 {
andrewboyson 49:1a6336f2b3f9 103 int count = 0;
andrewboyson 49:1a6336f2b3f9 104 char* pIpE = pIp + 16;
andrewboyson 49:1a6336f2b3f9 105 while (true)
andrewboyson 49:1a6336f2b3f9 106 {
andrewboyson 49:1a6336f2b3f9 107 bool added = false;
andrewboyson 49:1a6336f2b3f9 108 if (*pIp || *(pIp + 1))
andrewboyson 49:1a6336f2b3f9 109 {
andrewboyson 49:1a6336f2b3f9 110 httpHexNibble(&added, *(pIp + 0), 1); if (added) count++;
andrewboyson 49:1a6336f2b3f9 111 httpHexNibble(&added, *(pIp + 0), 0); if (added) count++;
andrewboyson 49:1a6336f2b3f9 112 httpHexNibble(&added, *(pIp + 1), 1); if (added) count++;
andrewboyson 49:1a6336f2b3f9 113 httpHexNibble(&added, *(pIp + 1), 0); if (added) count++;
andrewboyson 49:1a6336f2b3f9 114 }
andrewboyson 49:1a6336f2b3f9 115
andrewboyson 49:1a6336f2b3f9 116 pIp += 2;
andrewboyson 49:1a6336f2b3f9 117 if (pIp >= pIpE) break;
andrewboyson 49:1a6336f2b3f9 118
andrewboyson 54:84ef2b29cf7e 119 HttpAddChar(':'); count++;
andrewboyson 49:1a6336f2b3f9 120 }
andrewboyson 49:1a6336f2b3f9 121 return count;
andrewboyson 49:1a6336f2b3f9 122 }
andrewboyson 49:1a6336f2b3f9 123 bool Ip6AddressIsSame(char* ipA, char* ipB)
andrewboyson 49:1a6336f2b3f9 124 {
andrewboyson 49:1a6336f2b3f9 125 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 126 }
andrewboyson 49:1a6336f2b3f9 127 void Ip6AddressCopy(char* ipTo, char* ipFrom)
andrewboyson 49:1a6336f2b3f9 128 {
andrewboyson 49:1a6336f2b3f9 129 memcpy(ipTo, ipFrom, 16);
andrewboyson 49:1a6336f2b3f9 130 }
andrewboyson 49:1a6336f2b3f9 131
andrewboyson 49:1a6336f2b3f9 132 char Ip6AddressAllNodes [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
andrewboyson 49:1a6336f2b3f9 133 char Ip6AddressAllRouters[] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
andrewboyson 49:1a6336f2b3f9 134 char Ip6AddressMdns [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
andrewboyson 49:1a6336f2b3f9 135 char Ip6AddressLlmnr [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03};
andrewboyson 49:1a6336f2b3f9 136
andrewboyson 49:1a6336f2b3f9 137 void Ip6AddressFromDest(int dest, char* pDstIp)
andrewboyson 49:1a6336f2b3f9 138 {
andrewboyson 49:1a6336f2b3f9 139 switch (dest)
andrewboyson 49:1a6336f2b3f9 140 {
andrewboyson 49:1a6336f2b3f9 141 case UNICAST: break;
andrewboyson 49:1a6336f2b3f9 142 case UNICAST_DNS: Ip6AddressCopy(pDstIp, NdpDnsServer ); break;
andrewboyson 49:1a6336f2b3f9 143 case UNICAST_NTP: Ip6AddressCopy(pDstIp, NtpServerIp6 ); break;
andrewboyson 57:e0fb648acf48 144 case UNICAST_TFTP: Ip6AddressCopy(pDstIp, TftpServerIp6 ); break;
andrewboyson 49:1a6336f2b3f9 145 case MULTICAST_NODE: Ip6AddressCopy(pDstIp, Ip6AddressAllNodes ); break;
andrewboyson 49:1a6336f2b3f9 146 case MULTICAST_ROUTER: Ip6AddressCopy(pDstIp, Ip6AddressAllRouters); break;
andrewboyson 49:1a6336f2b3f9 147 case MULTICAST_MDNS: Ip6AddressCopy(pDstIp, Ip6AddressMdns ); break;
andrewboyson 49:1a6336f2b3f9 148 case MULTICAST_LLMNR: Ip6AddressCopy(pDstIp, Ip6AddressLlmnr ); break;
andrewboyson 49:1a6336f2b3f9 149 default:
andrewboyson 52:fbc5a46b5e16 150 LogTimeF("Ip6AddressFromDest unknown destination %d\r\n", dest);
andrewboyson 49:1a6336f2b3f9 151 break;
andrewboyson 49:1a6336f2b3f9 152 }
andrewboyson 49:1a6336f2b3f9 153 }