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:
11:c051adb70c5a
Parent:
10:f0854784e960
Child:
13:9cd54f7db57a
--- a/ip6/ip6.cpp	Sun Apr 16 14:21:55 2017 +0000
+++ b/ip6/ip6.cpp	Tue Apr 18 19:07:05 2017 +0000
@@ -1,37 +1,38 @@
-#include  "mbed.h"
-#include   "log.h"
-#include   "net.h"
-#include "icmp6.h"
-#include  "udp6.h"
-#include  "tcp6.h"
-#include    "ar.h"
-#include  "dhcp.h"
-#include "slaac.h"
-#include   "eth.h"
-#include   "ip6.h"
+#include    "mbed.h"
+#include     "log.h"
+#include     "net.h"
+#include   "icmp6.h"
+#include "udptcp6.h"
+#include      "ar.h"
+#include   "slaac.h"
+#include     "eth.h"
+#include     "ip6.h"
+#include     "ndp.h"
+
+#define DEBUG false
+
+char Ip6AllNodes  [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
+char Ip6AllRouters[] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
+char Ip6Mdns      [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
+char Ip6Llmnr     [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03};
+
+void Ip6DestIpFromAction(int action, char* pDstIp)
+{
+    switch (action)
+    {
+        case   UNICAST:                                            break;
+        case   UNICAST_DNS:    memcpy(pDstIp, NdpDnsServer,  16);  break;
+        case MULTICAST_NODE:   memcpy(pDstIp, Ip6AllNodes,   16);  break;
+        case MULTICAST_ROUTER: memcpy(pDstIp, Ip6AllRouters, 16);  break;
+        case MULTICAST_MDNS:   memcpy(pDstIp, Ip6Mdns,       16);  break;
+        case MULTICAST_LLMNR:  memcpy(pDstIp, Ip6Llmnr,      16);  break;
+        default:
+            LogTimeF("Ip6 DestIpFromAction unknown action %d\r\n", action);
+            break;           
+    }
+}
 
 #define HEADER_LENGTH 40
-
-char Ip6AllNodes[] = {  0xff, 0x02, 0x00, 0x00,
-                        0x00, 0x00, 0x00, 0x00,
-                        0x00, 0x00, 0x00, 0x00,
-                        0x00, 0x00, 0x00, 0x01};
-
-char Ip6AllRouters[] = {0xff, 0x02, 0x00, 0x00,
-                        0x00, 0x00, 0x00, 0x00,
-                        0x00, 0x00, 0x00, 0x00,
-                        0x00, 0x00, 0x00, 0x02};
-
-char Ip6Mdns[] = {      0xff, 0x02, 0x00, 0x00,
-                        0x00, 0x00, 0x00, 0x00,
-                        0x00, 0x00, 0x00, 0x00,
-                        0x00, 0x00, 0x00, 0xfb};
-
-char Ip6Llmnr[] = {     0xff, 0x02, 0x00, 0x00,
-                        0x00, 0x00, 0x00, 0x00,
-                        0x00, 0x00, 0x00, 0x00,
-                        0x00, 0x01, 0x00, 0x03};
-
 __packed struct header
 {
     uint32_t versionTrafficFlow;
@@ -41,6 +42,50 @@
     char     src[16];
     char     dst[16];
 };
+
+static uint8_t     version;
+static int      dataLength;
+static uint8_t    protocol;
+static uint8_t    hoplimit;
+static char     pSrcIp[16];
+static char     pDstIp[16];
+static void*         pData;
+
+static void readHeader(struct header * pHeader)
+{
+    version    =            (pHeader->versionTrafficFlow >> 4) & 0xF;
+    dataLength = NetToHost16(pHeader->dataLength);
+    protocol   =             pHeader->protocol;
+    hoplimit   =             pHeader->hoplimit;
+              memcpy(pSrcIp, pHeader->src, 16);
+              memcpy(pDstIp, pHeader->dst, 16);
+    pData      = (char*)pHeader + HEADER_LENGTH;
+}
+static void writeHeader(struct header * pHeader)
+{
+           pHeader->versionTrafficFlow  = version << 4;
+           pHeader->protocol            = protocol;
+           pHeader->hoplimit            = 255;
+    memcpy(pHeader->dst, pDstIp, 16);
+    memcpy(pHeader->src, pSrcIp, 16);
+           pHeader->dataLength          = NetToHost16(dataLength);
+}
+
+static void logHeader(char* title)
+{
+    char text[100];
+    LogTimeF("%s\r\n", title);
+    LogF("  Version           %d\r\n", version);
+    LogF("  Payload length    %d\r\n", dataLength);
+    LogF("  Hop limit         %d\r\n", hoplimit);
+    NetProtocolToString(protocol, sizeof(text), text);
+    LogF("  Protocol          %s\r\n", text);
+    NetIp6AddressToString(pSrcIp, sizeof(text), text);
+    LogF("  Source IP         %s\r\n", text);
+    NetIp6AddressToString(pDstIp, sizeof(text), text);
+    LogF("  Destination IP    %s\r\n", text);
+}
+
 static bool getIsSolicited(char* p)
 {
     if (*p++ != 0xff) return false;
@@ -80,76 +125,50 @@
 int Ip6HandleReceivedPacket(char* pSrcMac, void* pPacket, int* pSize, char* pDstMac)
 {
     struct header * pHeader = (header*)pPacket;
+    readHeader(pHeader);
     
-    uint8_t     version  =            (pHeader->versionTrafficFlow >> 4) & 0xF;
-    int      dataLength  = NetToHost16(pHeader->dataLength);
-    uint8_t    protocol  =             pHeader->protocol;
-    uint8_t    hoplimit  =             pHeader->hoplimit;
-    char        src[16];   memcpy(src, pHeader->src, 16);
-    char        dst[16];   memcpy(dst, pHeader->dst, 16);
-    void*          pData = (char*)pPacket + HEADER_LENGTH;
-    
-    bool isMe        = getIsSame(dst, SlaacLinkLocalIp);
-    bool isMulticast = dst[0] == 0xFF;
-    bool isSolicited = getIsSolicited(dst);
-    bool isGroup     = isSolicited && getIsSameGroup(dst, SlaacLinkLocalIp);
+    bool isMe        = getIsSame(pDstIp, SlaacLinkLocalIp);
+    bool isMulticast = pDstIp[0] == 0xFF;
+    bool isSolicited = getIsSolicited(pDstIp);
+    bool isGroup     = isSolicited && getIsSameGroup(pDstIp, SlaacLinkLocalIp);
     
     bool doIt = isMe || (isMulticast && !isSolicited) || isGroup;
     
     if (!doIt) return DO_NOTHING;
     
-    ArAdd6(pSrcMac, src);
+    ArAdd6(pSrcMac, pSrcIp);
+    
+    if (DEBUG) logHeader("IP6 packet received");
+
     int action = DO_NOTHING;
     switch (protocol)
     {
-        case ICMP6: action = Icmp6HandleReceivedPacket(src, dst, &dataLength, pData); break;
-        case UDP:   action =  Udp6HandleReceivedPacket(src, dst, &dataLength, pData); break;
-        case TCP:   action =  Tcp6HandleReceivedPacket(src, dst, &dataLength, pData); break;        
+        case ICMP6: action = Icmp6HandleReceivedPacket(pSrcIp, pDstIp, &dataLength, pData); break;
+        case UDP:   action =  Udp6HandleReceivedPacket(pSrcIp, pDstIp, &dataLength, pData); break;
+        case TCP:   action =  Tcp6HandleReceivedPacket(pSrcIp, pDstIp, &dataLength, pData); break;        
         default:
-            char text[100];
-            LogTimeF("IP6 packet unhandled\r\n");
-            LogF("  Size              %d\r\n", *pSize);
-            LogF("  Version           %d\r\n", version);
-            LogF("  Payload length    %d\r\n", dataLength);
-            LogF("  Hop limit         %d\r\n", hoplimit);
-            NetProtocolToString(protocol, sizeof(text), text);
-            LogF("  Protocol          %s\r\n", text);
-            NetIp6AddressToString(src, sizeof(text), text);
-            LogF("  Source IP         %s\r\n", text);
-            NetIp6AddressToString(dst, sizeof(text), text);
-            LogF("  Destination IP    %s\r\n", text);
+            logHeader("IP6 packet unhandled");
             return DO_NOTHING;
     }
-    switch (action)
-    {
-        case DO_NOTHING:
-            return DO_NOTHING;
-        case UNICAST:
-            memcpy(pDstMac, pSrcMac, 6);
-            break;
-        case MULTICAST_ROUTER:
-            break;
-        default:
-            LogTimeF("Ip6 unknown action %d\r\n", action);
-            return DO_NOTHING;
-    }
+    if (!action) return DO_NOTHING;
+    
+    memcpy(pDstMac, pSrcMac, 6);
+    
+    if (DEBUG) logHeader("IP6 packet replied to");
 
-    memcpy(pHeader->dst, dst, 16);
-    memcpy(pHeader->src, src, 16);
-    pHeader->dataLength   = NetToHost16(dataLength);
-        
+    writeHeader(pHeader);
+      
     *pSize = HEADER_LENGTH + dataLength;
     
     return action;
 }
 int Ip6PollForPacketToSend(void* pPacket, int* pSize, char* pDstMac)
 {    
-    void* pData = (char*)pPacket + HEADER_LENGTH;
-    int dataLength = 0;
+    pData      = (char*)pPacket + HEADER_LENGTH;
+    dataLength = 0;
+    version    = 6;
+    hoplimit   = 255;
     
-    char pSrcIp[16];
-    char pDstIp[16];
-    uint8_t protocol = 0;
     int action = DO_NOTHING;
     if (action == DO_NOTHING)
     {
@@ -162,35 +181,21 @@
         action = Udp6PollForPacketToSend(pData, &dataLength, pSrcIp, pDstIp);
         protocol = UDP;
     }
-    if (action == DO_NOTHING) return DO_NOTHING;
-    
-    ArRev6(pDstIp, pDstMac);             //Make the remote MAC from ARP
+    if (!action) return DO_NOTHING;
+    switch (action)
+    {
+        case UNICAST:
+        case UNICAST_DNS:
+        case UNICAST_DHCP:
+            ArRev6(pDstIp, pDstMac);             //Make the remote MAC from NP
+            break;
+    }
+        
+    if (DEBUG) logHeader("IP6 polled packet sent");
 
-    uint8_t version  = 6;
-    uint8_t hoplimit = 255;
-    
-    struct header * pHeader = (header*)pPacket;
-    pHeader->versionTrafficFlow  = version << 4;
-    pHeader->protocol            = protocol;
-    pHeader->hoplimit            = 255;
-    memcpy(pHeader->dst, pDstIp, 16);
-    memcpy(pHeader->src, pSrcIp, 16);
-    pHeader->dataLength   = NetToHost16(dataLength);
-    
+    writeHeader((header*)pPacket);
+
     *pSize = HEADER_LENGTH + dataLength;
     
-    LogTimeF("Ip6 sending waiting packet\r\n");
-    char text[100];
-    LogF("  Size              %d\r\n", *pSize);
-    LogF("  Version           %d\r\n", version);
-    LogF("  Payload length    %d\r\n", dataLength);
-    LogF("  Hop limit         %d\r\n", hoplimit);
-    NetProtocolToString(protocol, sizeof(text), text);
-    LogF("  Protocol          %s\r\n", text);
-    NetIp6AddressToString(pSrcIp, sizeof(text), text);
-    LogF("  Source IP         %s\r\n", text);
-    NetIp6AddressToString(pDstIp, sizeof(text), text);
-    LogF("  Destination IP    %s\r\n", text);
-    
     return action;
 }