Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Revision:
47:73af5c0b0dc2
Parent:
46:40d33e9037e4
Child:
49:1a6336f2b3f9
--- a/ip6/icmp/ndp/ndp.cpp	Tue Oct 24 07:01:35 2017 +0000
+++ b/ip6/icmp/ndp/ndp.cpp	Thu Oct 26 14:50:24 2017 +0000
@@ -1,15 +1,16 @@
 #include "mbed.h"
 #include "log.h"
+#include "net.h"
 #include "mac.h"
 #include "ip6.h"
 #include "slaac.h"
 #include "clock.h"
 #include "rs.h"
 
-int      NdpHopLimit                = 0;
-bool     NdpManagedAddressConfiguration = false;
-bool     NdpOtherConfiguration      = false;
-int      NdpLifetime                = 0;
+int      NdpHopLimit             = 0;
+bool     NdpManagedConfiguration = false;
+bool     NdpOtherConfiguration   = false;
+int      NdpLifetime             = 0;
 
 char     NdpRouterMac[6];
 
@@ -26,8 +27,6 @@
 
 uint32_t NdpElapsedTime = 0;         //Reset whenever an IP address request has been acknowledged 
 
-static char dstMAC[6];
-
 bool NdpIpNeedsToBeRouted(char* ip)
 {
     //Check address is assigned to internet
@@ -49,17 +48,17 @@
     value |= *p++ <<  0;
     return value;
 }
-static int decodeOption(char* p)
+static int decodeOption(char* p, char* srcMac, char* dstMac)
 {
     int type = *p++;
     int size = *p++;
     switch (type)
     {
         case 1:
-            MacCopy(NdpRouterMac, p);
+            if (srcMac) MacCopy(srcMac, p);
             break;
         case 2:
-            MacCopy(dstMAC, p);
+            if (dstMac) MacCopy(dstMac, p);
             break;
         case 3:
             NdpPrefixLength = *p++;
@@ -95,21 +94,25 @@
     MacCopy(p, pMac);
     return 8;
 }
-static int logOption(char* p)
+int NdpAddOptionTargetMac(char* p, char* pMac)
 {
-    char text[100];
+    *p++ = 2; //Target MAC option
+    *p++ = 1; //8 bytes
+    MacCopy(p, pMac);
+    return 8;
+}
+static int logOptionVerbose(char* p)
+{
     uint32_t value;
     int type = *p++;
     int size = *p++;
     switch (type)
     {
         case 1:
-            MacToString(p, sizeof(text), text);
-            LogF("    Src MAC          %s\r\n", text);
+            Log("    Src MAC          "); MacLog(p); Log("\r\n");
             break;
         case 2:
-            MacToString(p, sizeof(text), text);
-            LogF("    Dst MAC          %s\r\n", text);
+            Log("    Dst MAC          "); MacLog(p); Log("\r\n");
             break;
         case 3:
             LogF("    Prefix length    %d\r\n", *p++);
@@ -119,8 +122,7 @@
             value = decodeUint32(p);           p += 4;
             LogF("    Prefix preferred %u seconds\r\n", value);
             p += 4; //Skip gracefully past the Reserved2 field
-            Ip6AddressToString(p, sizeof(text), text);
-            LogF("    Prefix           %s\r\n", text);
+            LogF("    Prefix           "); Ip6AddressLog(p); Log("\r\n");
             break;
         case 5:
             p += 2; //Skip past the reserved field
@@ -133,8 +135,7 @@
             value = decodeUint32(p);
             p += 4;
             LogF("    DNS lifetime     %u\r\n", value);
-            Ip6AddressToString(p, sizeof(text), text);
-            LogF("    DNS Server       %s\r\n", text);
+            LogF("    DNS Server       "); Ip6AddressLog(p); Log("\r\n");
             break;
         default:
             LogF("    Unknown option   %d\r\n", type);
@@ -142,15 +143,91 @@
     }
     return size * 8;
 }
-void NdpDecodeOptions(char* pData, int dataLength)
+static int logOptionQuiet(char* p)
+{
+    uint32_t value;
+    int type = *p++;
+    int size = *p++;
+    switch (type)
+    {
+        case 1:
+            Log(" src ");
+            MacLog(p);
+            break;
+        case 2:
+            Log(" dst ");
+            MacLog(p);
+            break;
+        case 3:
+            *p++; //Length
+            *p++; //LA
+            p += 4; //Valid lifetime
+            p += 4; //Preferred lifetime
+            p += 4; //Reserved 2
+            Log(" prefix ");
+            Ip6AddressLog(p); //IP6 address
+            break;
+        case 5:
+            p += 2; //Skip past the reserved field
+            value = decodeUint32(p);
+            p += 4;
+            LogF(" MTU %u", value);
+            break;
+        case 25:
+            p += 2; //Skip past the reserved field
+            p += 4; //DNS lifetime
+            Log(" DNS ");
+            Ip6AddressLog(p);
+            break;
+        default:
+            LogF(" ? %d", type);
+            break;
+    }
+    return size * 8;
+}
+void NdpDecodeOptions(char* pData, int dataLength, char* srcMac, char* dstMac)
 {
     char* p = pData;
     char* pE = pData + dataLength;
-    while(p < pE) p += decodeOption(p);
+    while(p < pE) p += decodeOption(p, srcMac, dstMac);
 }
-void NdpLogOptions(char* pData, int dataLength)
+void NdpLogOptionsVerbose(char* pData, int dataLength)
+{
+    char* p = pData;
+    char* pE = pData + dataLength;
+    while(p < pE) p += logOptionVerbose(p);
+}
+void NdpLogOptionsQuiet(char* pData, int dataLength)
 {
     char* p = pData;
     char* pE = pData + dataLength;
-    while(p < pE) p += logOption(p);
+    while(p < pE) p += logOptionQuiet(p);
 }
+
+#define INITIAL_DELAY 1
+#define REPEAT_DELAY 60
+static uint32_t delayTime = INITIAL_DELAY; //Set to REPEAT_DELAY_TIME whenever a message is sent and blocks another send until count is back at zero
+void NdpMain()
+{
+    if (ClockTicked)
+    {
+        NdpElapsedTime++;
+        if (delayTime > 0) delayTime--;
+    }
+    if (delayTime) return; //Don't retry within the delay time
+    
+    if (NdpLifetime && NdpElapsedTime < (NdpLifetime >> 1)) return; //Do nothing if within half the life
+    
+    if (!NdpLifetime || NdpElapsedTime >= NdpLifetime)
+    {
+        if (NetTraceNewLine) Log("\r\n");
+        LogTime("NDP lifetime has expired\r\n");
+        NdpLifetime = 0;
+        Ip6Clear(NdpPrefix);
+        SlaacMakeGlobal(NdpPrefix);
+        Ip6Clear(NdpDnsServer);
+    }
+    
+    delayTime = REPEAT_DELAY;
+    RsSendSolicitation = true;
+}