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

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;           
+    }
+}