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:
136:8a65abb0dc63
Parent:
112:f8694d0b8858
Child:
172:9bc3c7b2cca1
--- a/ip6/ip6.c	Sat Mar 23 12:25:48 2019 +0000
+++ b/ip6/ip6.c	Sat Apr 06 11:20:20 2019 +0000
@@ -12,6 +12,7 @@
 #include     "eth.h"
 #include      "ip.h"
 #include "ip6addr.h"
+#include  "ip6hdr.h"
 #include     "ndp.h"
 #include     "ntp.h"
 #include     "mac.h"
@@ -19,125 +20,61 @@
 
 bool Ip6Trace = true;
 
-__packed struct header
-{
-    uint32_t versionTrafficFlow;
-    uint16_t payloadLength;
-    uint8_t  protocol;
-    uint8_t  hoplimit;
-    char     src[16];
-    char     dst[16];
-};
-
-static uint8_t     version;
-static int   payloadLength;
-static uint8_t    protocol;
-static uint8_t    hoplimit;
-static char      srcIp[16];
-static char      dstIp[16];
-
-static void readHeader(struct header * pHeader)
-{
-    version    =            (pHeader->versionTrafficFlow >> 4) & 0x0F;
- payloadLength = NetToHost16(pHeader->payloadLength);
-    protocol   =             pHeader->protocol;
-    hoplimit   =             pHeader->hoplimit;
-       Ip6AddressCopy(srcIp, pHeader->src);
-       Ip6AddressCopy(dstIp, pHeader->dst);
-}
-static void writeHeader(struct header * pHeader)
-{
-                   pHeader->versionTrafficFlow  = version << 4;
-                   pHeader->payloadLength       = NetToHost16(payloadLength);
-                   pHeader->protocol            = protocol;
-                   pHeader->hoplimit            = hoplimit;
-    Ip6AddressCopy(pHeader->dst, dstIp);
-    Ip6AddressCopy(pHeader->src, srcIp);
-}
-
-static void logHeader()
+static void logHeader(char* pPacket)
 {
     if (NetTraceVerbose)
     {
         Log("IP6 header\r\n");
-        LogF("  Version           %d\r\n", version);
-        LogF("  Payload length    %d\r\n", payloadLength);
-        LogF("  Hop limit         %d\r\n", hoplimit);
-        LogF("  Protocol          "); IpProtocolLog(protocol); Log("\r\n");
-        Log ("  Source IP         "); Ip6AddressLog(srcIp);    Log("\r\n");
-        Log ("  Destination IP    "); Ip6AddressLog(dstIp);    Log("\r\n");
+        LogF("  Version           %d\r\n",          Ip6HdrGetVersion   (pPacket));
+        LogF("  Payload length    %d\r\n",          Ip6HdrGetPayloadLen(pPacket));
+        LogF("  Hop limit         %d\r\n",          Ip6HdrGetHopLimit  (pPacket));
+        LogF("  Protocol          "); IpProtocolLog(Ip6HdrGetProtocol  (pPacket)); Log("\r\n");
+        Log ("  Source IP         "); Ip6AddressLog(Ip6HdrPtrSrc       (pPacket)); Log("\r\n");
+        Log ("  Destination IP    "); Ip6AddressLog(Ip6HdrPtrDst       (pPacket)); Log("\r\n");
     }
     else
     {
         Log("IP6   header ");
-        IpProtocolLog(protocol);
+        IpProtocolLog(Ip6HdrGetProtocol(pPacket));
         Log(" ");
-        Ip6AddressLog(srcIp);
+        Ip6AddressLog(Ip6HdrPtrSrc     (pPacket));
         Log(" >>> ");
-        Ip6AddressLog(dstIp);
+        Ip6AddressLog(Ip6HdrPtrDst     (pPacket));
         Log("\r\n");
     }
 }
-
-static bool getIsSolicited(char* p)
-{
-    if (*p++ != 0xff) return false;
-    if (*p++ != 0x02) return false;
-    
-    if (*p++ != 0x00) return false;
-    if (*p++ != 0x00) return false;
-    
-    if (*p++ != 0x00) return false;
-    if (*p++ != 0x00) return false;
-    
-    if (*p++ != 0x00) return false;
-    if (*p++ != 0x00) return false;
-    
-    if (*p++ != 0x00) return false;
-    if (*p++ != 0x00) return false;
-    
-    if (*p++ != 0x00) return false;
-    if (*p++ != 0x01) return false;
-    
-    if (*p++ != 0xff) return false;
-    
-    return true;
-}
-static bool getIsSameGroup(char* pA, char* pB)
-{
-    pA += 13;
-    pB += 13;
-    if (*pA++ != *pB++) return false;
-    if (*pA++ != *pB++) return false;
-    return *pA == *pB;
-}
+static char* pTracePacket;
 static void (*pTraceBack)(void);
 static void trace()
 {
     pTraceBack();
-    logHeader();
+    logHeader(pTracePacket);
 }
-int Ip6HandleReceivedPacket(void (*traceback)(void), void* pPacketRx, int sizeRx, void* pPacketTx, int* pSizeTx, char* macRemote)
-{
-    pTraceBack = traceback;
+int Ip6HandleReceivedPacket(void (*traceback)(void), char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx, char* macRemote)
+{    
+    pTracePacket = pPacketRx;
+    pTraceBack   = traceback;
     
-    struct header* pHeaderRx = (struct header*)pPacketRx;
-    struct header* pHeaderTx = (struct header*)pPacketTx;
+    char* pDataRx = pPacketRx + IP6_HEADER_LENGTH;
+    char* pDataTx = pPacketTx + IP6_HEADER_LENGTH;
     
-    char* pDataRx = (char*)pHeaderRx + sizeof(struct header);
-    char* pDataTx = (char*)pHeaderTx + sizeof(struct header);
+    int protocol        = Ip6HdrGetProtocol  (pPacketRx);
+    int payloadLengthRx = Ip6HdrGetPayloadLen(pPacketRx);
     
-    readHeader(pHeaderRx); //This also fetches the payload length out of the header
+    static char srcIp[16];
+    static char dstIp[16];
+    Ip6AddressCopy(srcIp, Ip6HdrPtrSrc (pPacketRx));
+    Ip6AddressCopy(dstIp, Ip6HdrPtrDst (pPacketRx));
     
-    int dataLengthRx = sizeRx - sizeof(struct header);
-    if (payloadLength < dataLengthRx) dataLengthRx = payloadLength; //Choose the lesser of the data length and the payload length
-    int dataLengthTx = *pSizeTx - sizeof(struct header);
+    int dataLengthRx = sizeRx - IP6_HEADER_LENGTH;
+    if (dataLengthRx > payloadLengthRx) dataLengthRx = payloadLengthRx; //Choose the lesser of the data length and the payload length
+    int dataLengthTx = *pSizeTx - IP6_HEADER_LENGTH;
     
     int  scope       = SlaacScope(dstIp);
     bool isMe        = scope != SCOPE_NONE;
-    bool isMulticast = dstIp[0] == 0xFF;
-    bool isSolicited = getIsSolicited(dstIp);
-    bool isGroup     = getIsSameGroup(dstIp, SlaacLinkLocalIp);
+    bool isMulticast = Ip6AddrIsMulticast(dstIp);
+    bool isSolicited = Ip6AddrIsSolicited(dstIp);
+    bool isGroup     = Ip6AddrIsSameGroup(dstIp, SlaacLinkLocalIp);
     
     bool doIt = isMe || (isMulticast && !isSolicited) || (isGroup && isSolicited);
     
@@ -172,6 +109,7 @@
     }
     if (!action) return DO_NOTHING;
     
+    int hoplimit;
     if (NdpIpNeedsToBeRouted(dstIp))
     {
         MacCopy(macRemote, NdpRouterMac); //Send to the router MAC
@@ -182,27 +120,36 @@
         hoplimit = 255;
     }
     
-    payloadLength = dataLengthTx;
-
-    writeHeader(pHeaderTx);
+    Ip6HdrSetVersion   (pPacketTx, 6           );
+    Ip6HdrSetPayloadLen(pPacketTx, dataLengthTx);
+    Ip6HdrSetProtocol  (pPacketTx, protocol    );
+    Ip6HdrSetHopLimit  (pPacketTx, hoplimit    );
+    
+    Ip6AddressCopy(Ip6HdrPtrSrc(pPacketTx), srcIp);
+    Ip6AddressCopy(Ip6HdrPtrDst(pPacketTx), dstIp);
       
-    *pSizeTx = sizeof(struct header) + payloadLength;
+    *pSizeTx = IP6_HEADER_LENGTH + dataLengthTx;
     
-    if (ActionGetTracePart(action)) logHeader();
+    if (ActionGetTracePart(action)) logHeader(pPacketTx);
 
     return action;
 }
-int Ip6PollForPacketToSend(void* pPacket, int* pSize, char* pDstMac)
+int Ip6PollForPacketToSend(char* pPacket, int* pSize, char* pDstMac)
 {    
-    char* pData = (char*)pPacket + sizeof(struct header);
-    int dataLength = *pSize - sizeof(struct header);
+    static char srcIp[16];
+    static char dstIp[16];
     
+    char* pData    = pPacket + IP6_HEADER_LENGTH;
+    int dataLength = *pSize  - IP6_HEADER_LENGTH;
+    
+    int protocol = 0;
     int action = DO_NOTHING;
     if (!action) { action = Icmp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = ICMP6; }
     if (!action) { action =  Udp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = UDP;   }
     if (!action) { action =  Tcp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = TCP;   }
     if (!action) return DO_NOTHING;
     
+    int hoplimit = 0;
     int dest = ActionGetDestPart(action);
     switch (dest)
     {
@@ -235,13 +182,16 @@
             return DO_NOTHING;
     }
 
-    payloadLength  = dataLength;
-    version        = 6;
-    writeHeader((struct header*)pPacket);
+    Ip6HdrSetVersion   (pPacket, 6         );
+    Ip6HdrSetPayloadLen(pPacket, dataLength);
+    Ip6HdrSetProtocol  (pPacket, protocol  );
+    Ip6HdrSetHopLimit  (pPacket, hoplimit  );
+    Ip6AddressCopy(Ip6HdrPtrSrc(pPacket), srcIp);
+    Ip6AddressCopy(Ip6HdrPtrDst(pPacket), dstIp);
 
-    *pSize = sizeof(struct header) + payloadLength;
+    *pSize = IP6_HEADER_LENGTH + dataLength;
     
-    if (ActionGetTracePart(action)) logHeader();
+    if (ActionGetTracePart(action)) logHeader(pPacket);
 
     return action;
 }