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
ip6/ip6addr.c
- Committer:
- andrewboyson
- Date:
- 2019-01-21
- Revision:
- 112:f8694d0b8858
- Parent:
- 107:cc58b4c2090b
- Child:
- 113:904b40231907
File content as of revision 112:f8694d0b8858:
#include <stdbool.h> #include <string.h> #include "log.h" #include "ip6addr.h" #include "http.h" #include "action.h" #include "ndp.h" #include "ntpclient.h" #include "slaac.h" #include "tftp.h" void Ip6AddressClear(char* ip) { *ip = 0; //Just set the first byte to zero } bool Ip6AddressIsEmpty(const char* ip) { return !*ip; //Just check for the first byte being non zero } static void addHexNibble(bool* pAdded, int number, int index, char** pp) { int nibble = number; if (index) nibble >>= 4; nibble &= 0xF; if (nibble || *pAdded) { **pp = nibble < 10 ? nibble + '0' : nibble - 10 + 'a'; *pp += 1; *pAdded = true; } } int Ip6AddressToString(char* pIp, int size, char* pText) { char* pIpE = pIp + 16; char* p = pText; while (true) { bool added = false; if (*pIp || *(pIp + 1)) { if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 0), 1, &p); if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 0), 0, &p); if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 1), 1, &p); if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 1), 0, &p); } pIp += 2; if (pIp >= pIpE) break; if (p > pText + size - 2) break; *p++ = ':'; } *p = 0; return p - pText; } static void logHexNibble(bool* pAdded, int number, int index) { int nibble = number; if (index) nibble >>= 4; nibble &= 0xF; if (nibble || *pAdded) { LogPush(nibble < 10 ? nibble + '0' : nibble - 10 + 'a'); *pAdded = true; } } int Ip6AddressLog(char* pIp) { int count = 0; char* pIpE = pIp + 16; while (true) { bool added = false; if (*pIp || *(pIp + 1)) { logHexNibble(&added, *(pIp + 0), 1); if (added) count++; logHexNibble(&added, *(pIp + 0), 0); if (added) count++; logHexNibble(&added, *(pIp + 1), 1); if (added) count++; logHexNibble(&added, *(pIp + 1), 0); if (added) count++; } pIp += 2; if (pIp >= pIpE) break; LogPush(':'); count++; } return count; } static void httpHexNibble(bool* pAdded, int number, int index) { int nibble = number; if (index) nibble >>= 4; nibble &= 0xF; if (nibble || *pAdded) { HttpAddChar(nibble < 10 ? nibble + '0' : nibble - 10 + 'a'); *pAdded = true; } } int Ip6AddressHttp(char* pIp) { int count = 0; char* pIpE = pIp + 16; while (true) { bool added = false; if (*pIp || *(pIp + 1)) { httpHexNibble(&added, *(pIp + 0), 1); if (added) count++; httpHexNibble(&added, *(pIp + 0), 0); if (added) count++; httpHexNibble(&added, *(pIp + 1), 1); if (added) count++; httpHexNibble(&added, *(pIp + 1), 0); if (added) count++; } pIp += 2; if (pIp >= pIpE) break; HttpAddChar(':'); count++; } return count; } bool Ip6AddressIsSame(const char* ipA, const char* ipB) { 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 } void Ip6AddressCopy(char* ipTo, const char* ipFrom) { memcpy(ipTo, ipFrom, 16); } const char Ip6AddressAllNodes [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; const char Ip6AddressAllRouters[] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; const char Ip6AddressMdns [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb}; const char Ip6AddressLlmnr [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03}; const char Ip6AddressNtp [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01}; void Ip6AddressFromDest(int dest, char* pDstIp) { switch (dest) { case UNICAST: /*No change*/ break; case UNICAST_DNS: Ip6AddressCopy(pDstIp, NdpDnsServer ); break; case UNICAST_NTP: Ip6AddressCopy(pDstIp, NtpClientServerIp6 ); break; case UNICAST_TFTP: Ip6AddressCopy(pDstIp, TftpServerIp6 ); break; case MULTICAST_NODE: Ip6AddressCopy(pDstIp, Ip6AddressAllNodes ); break; case MULTICAST_ROUTER: Ip6AddressCopy(pDstIp, Ip6AddressAllRouters); break; case MULTICAST_MDNS: Ip6AddressCopy(pDstIp, Ip6AddressMdns ); break; case MULTICAST_LLMNR: Ip6AddressCopy(pDstIp, Ip6AddressLlmnr ); break; case MULTICAST_NTP: Ip6AddressCopy(pDstIp, Ip6AddressNtp ); break; default: LogTimeF("Ip6AddressFromDest unknown destination %d\r\n", dest); break; } }