Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
Diff: ip6/icmp/ndp/ndp.c
- Revision:
- 61:aad055f1b0d1
- Parent:
- 53:77f8a49adf89
- Child:
- 65:37acccf2752f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ip6/icmp/ndp/ndp.c Thu Jan 11 17:38:21 2018 +0000
@@ -0,0 +1,245 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "log.h"
+#include "net.h"
+#include "mac.h"
+#include "ip6addr.h"
+#include "slaac.h"
+#include "clock.h"
+#include "rs.h"
+
+int NdpHopLimit = 0;
+bool NdpManagedConfiguration = false;
+bool NdpOtherConfiguration = false;
+int NdpLifetime = 0;
+
+char NdpRouterMac[6];
+
+int NdpPrefixLength = 0;
+bool NdpPrefixFlagL = false;
+bool NdpPrefixFlagA = false;
+uint32_t NdpPrefixValidLifetime = 0;
+uint32_t NdpPrefixPreferredLifetime = 0;
+char NdpPrefix[16];
+
+uint32_t NdpDnsLifetime = 0;
+char NdpDnsServer[16];
+
+int NdpMtu = 0;
+
+uint32_t NdpElapsedTime = 0; //Reset whenever an IP address request has been acknowledged
+
+bool NdpIpNeedsToBeRouted(char* ip)
+{
+ //Check address is assigned to internet
+ if (*(ip + 0) != 0x20) return false;
+ if (*(ip + 1) != 0x00) return false;
+
+ //Check it is not our own prefix
+ if (memcmp(ip, NdpPrefix, 8) == 0) return false;
+
+ return true;
+}
+
+static uint32_t decodeUint32(char* p)
+{
+ uint32_t value = 0;
+ value |= *p++ << 24;
+ value |= *p++ << 12;
+ value |= *p++ << 8;
+ value |= *p++ << 0;
+ return value;
+}
+static int decodeOption(char* p, char* srcMac, char* dstMac)
+{
+ int type = *p++;
+ int size = *p++;
+ if (size == 0) return 0;
+ switch (type)
+ {
+ case 1:
+ if (srcMac) MacCopy(srcMac, p);
+ break;
+ case 2:
+ if (dstMac) MacCopy(dstMac, p);
+ break;
+ case 3:
+ NdpPrefixLength = *p; p += 1;
+ NdpPrefixFlagL = *p & 0x80; NdpPrefixFlagA = *p & 0x40; p += 1;
+ NdpPrefixValidLifetime = decodeUint32(p); p += 4;
+ NdpPrefixPreferredLifetime = decodeUint32(p); p += 4;
+ /*Ignore the reserved2 field*/ p += 4;
+ Ip6AddressCopy(NdpPrefix, p); SlaacMakeGlobal(NdpPrefix);
+ break;
+ case 5:
+ /*Ignore the reserved field*/ p += 2;
+ NdpMtu = decodeUint32(p);
+ break;
+ case 25:
+ /*Ignore the reserved field*/ p += 2;
+ NdpDnsLifetime = decodeUint32(p); p += 4;
+ Ip6AddressCopy(NdpDnsServer, p);
+ break;
+ }
+ return size * 8;
+}
+static void logFlagsLA(char flags)
+{
+ if (flags & 0x80) LogPush('L');
+ if (flags & 0x40) LogPush('A');
+}
+static int logOptionVerbose(char* p)
+{
+ uint32_t value;
+ int type = *p++;
+ int size = *p++;
+ if (size == 0)
+ {
+ LogF(" Size zero for option %d\r\n", type);
+ return 0;
+ }
+ switch (type)
+ {
+ case 1:
+ Log(" Src MAC "); MacLog(p); Log("\r\n"); break;
+ case 2:
+ Log(" Tgt MAC "); MacLog(p); Log("\r\n"); break;
+ case 3:
+ Log(" Prefix length "); LogF("%d", *p); Log("\r\n"); p += 1;
+ Log(" Prefix flags "); logFlagsLA(*p); Log("\r\n"); p += 1;
+ value = decodeUint32(p); Log(" Prefix valid "); LogF("%u", value); Log("\r\n"); p += 4;
+ value = decodeUint32(p); Log(" Prefix preferred "); LogF("%u", value); Log("\r\n"); p += 4;
+ /*Ignore the Reserved2 field*/ p += 4;
+ Log(" Prefix "); Ip6AddressLog(p); Log("\r\n"); break;
+ case 5:
+ /*Ignore the reserved field*/ p += 2;
+ value = decodeUint32(p); Log(" MTU "); LogF("%u", value); Log("\r\n"); break;
+ case 25:
+ /*Ignore the reserved field*/ p += 2;
+ value = decodeUint32(p); Log(" DNS lifetime "); LogF("%u", value); Log("\r\n"); p += 4;
+ Log(" DNS Server "); Ip6AddressLog(p); Log("\r\n"); break;
+ default:
+ Log(" Unknown option "); LogF("%d", type); Log("\r\n"); break;
+ }
+ return size * 8;
+}
+static int logOptionQuiet(char* p)
+{
+ uint32_t value;
+ int type = *p++;
+ int size = *p++;
+ if (size == 0) return 0;
+ switch (type)
+ {
+ case 1:
+ Log(" src ");
+ MacLog(p);
+ break;
+ case 2:
+ Log(" tgt ");
+ 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)
+ {
+ int size = decodeOption(p, srcMac, dstMac);
+ if (size == 0) break;
+ p += size;
+ }
+}
+void NdpLogOptionsVerbose(char* pData, int dataLength)
+{
+ char* p = pData;
+ char* pE = pData + dataLength;
+ while(p < pE)
+ {
+ int size = logOptionVerbose(p);
+ if (size == 0) break;
+ p += size;
+ }
+}
+void NdpLogOptionsQuiet(char* pData, int dataLength)
+{
+ char* p = pData;
+ char* pE = pData + dataLength;
+ while(p < pE)
+ {
+ int size = logOptionQuiet(p);
+ if (size == 0) break;
+ p += size;
+ }
+}
+int NdpAddOptionSourceMac(char* p, char* pMac)
+{
+ *p++ = 1; //Source MAC option
+ *p++ = 1; //8 bytes
+ MacCopy(p, pMac);
+ return 8;
+}
+int NdpAddOptionTargetMac(char* p, char* pMac)
+{
+ *p++ = 2; //Target MAC option
+ *p++ = 1; //8 bytes
+ MacCopy(p, pMac);
+ return 8;
+}
+
+#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;
+ Ip6AddressClear(NdpPrefix);
+ SlaacMakeGlobal(NdpPrefix);
+ Ip6AddressClear(NdpDnsServer);
+ }
+
+ delayTime = REPEAT_DELAY;
+ RsSendSolicitation = true;
+}