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
Diff: ip6/ip6addr.c
- Revision:
- 61:aad055f1b0d1
- Parent:
- 57:e0fb648acf48
- Child:
- 107:cc58b4c2090b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ip6/ip6addr.c Thu Jan 11 17:38:21 2018 +0000 @@ -0,0 +1,155 @@ +#include <stdbool.h> +#include <string.h> + +#include "log.h" +#include "ip6addr.h" +#include "http.h" +#include "action.h" +#include "ndp.h" +#include "ntp.h" +#include "slaac.h" +#include "tftp.h" + +void Ip6AddressClear(char* ip) +{ + *ip = 0; +} +bool Ip6AddressIsEmpty(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(char* ipA, 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, char* ipFrom) +{ + memcpy(ipTo, ipFrom, 16); +} + +char Ip6AddressAllNodes [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; +char Ip6AddressAllRouters[] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; +char Ip6AddressMdns [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb}; +char Ip6AddressLlmnr [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03}; + +void Ip6AddressFromDest(int dest, char* pDstIp) +{ + switch (dest) + { + case UNICAST: break; + case UNICAST_DNS: Ip6AddressCopy(pDstIp, NdpDnsServer ); break; + case UNICAST_NTP: Ip6AddressCopy(pDstIp, NtpServerIp6 ); 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; + default: + LogTimeF("Ip6AddressFromDest unknown destination %d\r\n", dest); + break; + } +}