Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Sun Dec 02 18:40:35 2018 +0000
Revision:
93:580fc113d9e9
Parent:
66:18a10c0b6d93
Child:
119:8e1a7805b801
Removed ClockTick and replaced with ms timer.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 61:aad055f1b0d1 1 #include <stdint.h>
andrewboyson 61:aad055f1b0d1 2 #include <stdbool.h>
andrewboyson 61:aad055f1b0d1 3 #include <string.h>
andrewboyson 61:aad055f1b0d1 4
andrewboyson 46:40d33e9037e4 5 #include "log.h"
andrewboyson 47:73af5c0b0dc2 6 #include "net.h"
andrewboyson 46:40d33e9037e4 7 #include "mac.h"
andrewboyson 49:1a6336f2b3f9 8 #include "ip6addr.h"
andrewboyson 46:40d33e9037e4 9 #include "slaac.h"
andrewboyson 93:580fc113d9e9 10 #include "mstimer.h"
andrewboyson 46:40d33e9037e4 11 #include "rs.h"
andrewboyson 46:40d33e9037e4 12
andrewboyson 47:73af5c0b0dc2 13 int NdpHopLimit = 0;
andrewboyson 47:73af5c0b0dc2 14 bool NdpManagedConfiguration = false;
andrewboyson 47:73af5c0b0dc2 15 bool NdpOtherConfiguration = false;
andrewboyson 47:73af5c0b0dc2 16 int NdpLifetime = 0;
andrewboyson 46:40d33e9037e4 17
andrewboyson 46:40d33e9037e4 18 char NdpRouterMac[6];
andrewboyson 46:40d33e9037e4 19
andrewboyson 46:40d33e9037e4 20 int NdpPrefixLength = 0;
andrewboyson 53:77f8a49adf89 21 bool NdpPrefixFlagL = false;
andrewboyson 53:77f8a49adf89 22 bool NdpPrefixFlagA = false;
andrewboyson 46:40d33e9037e4 23 uint32_t NdpPrefixValidLifetime = 0;
andrewboyson 46:40d33e9037e4 24 uint32_t NdpPrefixPreferredLifetime = 0;
andrewboyson 46:40d33e9037e4 25 char NdpPrefix[16];
andrewboyson 46:40d33e9037e4 26
andrewboyson 46:40d33e9037e4 27 uint32_t NdpDnsLifetime = 0;
andrewboyson 46:40d33e9037e4 28 char NdpDnsServer[16];
andrewboyson 46:40d33e9037e4 29
andrewboyson 46:40d33e9037e4 30 int NdpMtu = 0;
andrewboyson 46:40d33e9037e4 31
andrewboyson 93:580fc113d9e9 32 static uint32_t lifeStartMs = 0;
andrewboyson 93:580fc113d9e9 33
andrewboyson 93:580fc113d9e9 34 uint32_t NdpGetElapsedLife()
andrewboyson 93:580fc113d9e9 35 {
andrewboyson 93:580fc113d9e9 36 return (MsTimerCount - lifeStartMs) / 1000;
andrewboyson 93:580fc113d9e9 37 }
andrewboyson 93:580fc113d9e9 38 void NdpResetLife() //Reset whenever an IP address request has been acknowledged
andrewboyson 93:580fc113d9e9 39 {
andrewboyson 93:580fc113d9e9 40 lifeStartMs = MsTimerCount;
andrewboyson 93:580fc113d9e9 41 }
andrewboyson 46:40d33e9037e4 42
andrewboyson 46:40d33e9037e4 43 bool NdpIpNeedsToBeRouted(char* ip)
andrewboyson 46:40d33e9037e4 44 {
andrewboyson 46:40d33e9037e4 45 //Check address is assigned to internet
andrewboyson 46:40d33e9037e4 46 if (*(ip + 0) != 0x20) return false;
andrewboyson 46:40d33e9037e4 47 if (*(ip + 1) != 0x00) return false;
andrewboyson 46:40d33e9037e4 48
andrewboyson 46:40d33e9037e4 49 //Check it is not our own prefix
andrewboyson 46:40d33e9037e4 50 if (memcmp(ip, NdpPrefix, 8) == 0) return false;
andrewboyson 46:40d33e9037e4 51
andrewboyson 46:40d33e9037e4 52 return true;
andrewboyson 46:40d33e9037e4 53 }
andrewboyson 46:40d33e9037e4 54
andrewboyson 46:40d33e9037e4 55 static uint32_t decodeUint32(char* p)
andrewboyson 46:40d33e9037e4 56 {
andrewboyson 46:40d33e9037e4 57 uint32_t value = 0;
andrewboyson 46:40d33e9037e4 58 value |= *p++ << 24;
andrewboyson 46:40d33e9037e4 59 value |= *p++ << 12;
andrewboyson 46:40d33e9037e4 60 value |= *p++ << 8;
andrewboyson 46:40d33e9037e4 61 value |= *p++ << 0;
andrewboyson 46:40d33e9037e4 62 return value;
andrewboyson 46:40d33e9037e4 63 }
andrewboyson 47:73af5c0b0dc2 64 static int decodeOption(char* p, char* srcMac, char* dstMac)
andrewboyson 46:40d33e9037e4 65 {
andrewboyson 46:40d33e9037e4 66 int type = *p++;
andrewboyson 46:40d33e9037e4 67 int size = *p++;
andrewboyson 52:fbc5a46b5e16 68 if (size == 0) return 0;
andrewboyson 46:40d33e9037e4 69 switch (type)
andrewboyson 46:40d33e9037e4 70 {
andrewboyson 46:40d33e9037e4 71 case 1:
andrewboyson 47:73af5c0b0dc2 72 if (srcMac) MacCopy(srcMac, p);
andrewboyson 46:40d33e9037e4 73 break;
andrewboyson 46:40d33e9037e4 74 case 2:
andrewboyson 47:73af5c0b0dc2 75 if (dstMac) MacCopy(dstMac, p);
andrewboyson 46:40d33e9037e4 76 break;
andrewboyson 46:40d33e9037e4 77 case 3:
andrewboyson 53:77f8a49adf89 78 NdpPrefixLength = *p; p += 1;
andrewboyson 53:77f8a49adf89 79 NdpPrefixFlagL = *p & 0x80; NdpPrefixFlagA = *p & 0x40; p += 1;
andrewboyson 53:77f8a49adf89 80 NdpPrefixValidLifetime = decodeUint32(p); p += 4;
andrewboyson 53:77f8a49adf89 81 NdpPrefixPreferredLifetime = decodeUint32(p); p += 4;
andrewboyson 53:77f8a49adf89 82 /*Ignore the reserved2 field*/ p += 4;
andrewboyson 53:77f8a49adf89 83 Ip6AddressCopy(NdpPrefix, p); SlaacMakeGlobal(NdpPrefix);
andrewboyson 46:40d33e9037e4 84 break;
andrewboyson 46:40d33e9037e4 85 case 5:
andrewboyson 53:77f8a49adf89 86 /*Ignore the reserved field*/ p += 2;
andrewboyson 46:40d33e9037e4 87 NdpMtu = decodeUint32(p);
andrewboyson 46:40d33e9037e4 88 break;
andrewboyson 46:40d33e9037e4 89 case 25:
andrewboyson 53:77f8a49adf89 90 /*Ignore the reserved field*/ p += 2;
andrewboyson 53:77f8a49adf89 91 NdpDnsLifetime = decodeUint32(p); p += 4;
andrewboyson 49:1a6336f2b3f9 92 Ip6AddressCopy(NdpDnsServer, p);
andrewboyson 46:40d33e9037e4 93 break;
andrewboyson 46:40d33e9037e4 94 }
andrewboyson 46:40d33e9037e4 95 return size * 8;
andrewboyson 46:40d33e9037e4 96 }
andrewboyson 53:77f8a49adf89 97 static void logFlagsLA(char flags)
andrewboyson 53:77f8a49adf89 98 {
andrewboyson 53:77f8a49adf89 99 if (flags & 0x80) LogPush('L');
andrewboyson 53:77f8a49adf89 100 if (flags & 0x40) LogPush('A');
andrewboyson 53:77f8a49adf89 101 }
andrewboyson 47:73af5c0b0dc2 102 static int logOptionVerbose(char* p)
andrewboyson 47:73af5c0b0dc2 103 {
andrewboyson 46:40d33e9037e4 104 uint32_t value;
andrewboyson 46:40d33e9037e4 105 int type = *p++;
andrewboyson 46:40d33e9037e4 106 int size = *p++;
andrewboyson 52:fbc5a46b5e16 107 if (size == 0)
andrewboyson 52:fbc5a46b5e16 108 {
andrewboyson 52:fbc5a46b5e16 109 LogF(" Size zero for option %d\r\n", type);
andrewboyson 52:fbc5a46b5e16 110 return 0;
andrewboyson 52:fbc5a46b5e16 111 }
andrewboyson 46:40d33e9037e4 112 switch (type)
andrewboyson 46:40d33e9037e4 113 {
andrewboyson 46:40d33e9037e4 114 case 1:
andrewboyson 53:77f8a49adf89 115 Log(" Src MAC "); MacLog(p); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 116 case 2:
andrewboyson 53:77f8a49adf89 117 Log(" Tgt MAC "); MacLog(p); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 118 case 3:
andrewboyson 53:77f8a49adf89 119 Log(" Prefix length "); LogF("%d", *p); Log("\r\n"); p += 1;
andrewboyson 53:77f8a49adf89 120 Log(" Prefix flags "); logFlagsLA(*p); Log("\r\n"); p += 1;
andrewboyson 53:77f8a49adf89 121 value = decodeUint32(p); Log(" Prefix valid "); LogF("%u", value); Log("\r\n"); p += 4;
andrewboyson 53:77f8a49adf89 122 value = decodeUint32(p); Log(" Prefix preferred "); LogF("%u", value); Log("\r\n"); p += 4;
andrewboyson 53:77f8a49adf89 123 /*Ignore the Reserved2 field*/ p += 4;
andrewboyson 53:77f8a49adf89 124 Log(" Prefix "); Ip6AddressLog(p); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 125 case 5:
andrewboyson 53:77f8a49adf89 126 /*Ignore the reserved field*/ p += 2;
andrewboyson 53:77f8a49adf89 127 value = decodeUint32(p); Log(" MTU "); LogF("%u", value); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 128 case 25:
andrewboyson 53:77f8a49adf89 129 /*Ignore the reserved field*/ p += 2;
andrewboyson 53:77f8a49adf89 130 value = decodeUint32(p); Log(" DNS lifetime "); LogF("%u", value); Log("\r\n"); p += 4;
andrewboyson 53:77f8a49adf89 131 Log(" DNS Server "); Ip6AddressLog(p); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 132 default:
andrewboyson 53:77f8a49adf89 133 Log(" Unknown option "); LogF("%d", type); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 134 }
andrewboyson 46:40d33e9037e4 135 return size * 8;
andrewboyson 46:40d33e9037e4 136 }
andrewboyson 47:73af5c0b0dc2 137 static int logOptionQuiet(char* p)
andrewboyson 47:73af5c0b0dc2 138 {
andrewboyson 47:73af5c0b0dc2 139 uint32_t value;
andrewboyson 47:73af5c0b0dc2 140 int type = *p++;
andrewboyson 47:73af5c0b0dc2 141 int size = *p++;
andrewboyson 52:fbc5a46b5e16 142 if (size == 0) return 0;
andrewboyson 47:73af5c0b0dc2 143 switch (type)
andrewboyson 47:73af5c0b0dc2 144 {
andrewboyson 47:73af5c0b0dc2 145 case 1:
andrewboyson 47:73af5c0b0dc2 146 Log(" src ");
andrewboyson 47:73af5c0b0dc2 147 MacLog(p);
andrewboyson 47:73af5c0b0dc2 148 break;
andrewboyson 47:73af5c0b0dc2 149 case 2:
andrewboyson 53:77f8a49adf89 150 Log(" tgt ");
andrewboyson 47:73af5c0b0dc2 151 MacLog(p);
andrewboyson 47:73af5c0b0dc2 152 break;
andrewboyson 47:73af5c0b0dc2 153 case 3:
andrewboyson 47:73af5c0b0dc2 154 *p++; //Length
andrewboyson 47:73af5c0b0dc2 155 *p++; //LA
andrewboyson 47:73af5c0b0dc2 156 p += 4; //Valid lifetime
andrewboyson 47:73af5c0b0dc2 157 p += 4; //Preferred lifetime
andrewboyson 47:73af5c0b0dc2 158 p += 4; //Reserved 2
andrewboyson 47:73af5c0b0dc2 159 Log(" prefix ");
andrewboyson 47:73af5c0b0dc2 160 Ip6AddressLog(p); //IP6 address
andrewboyson 47:73af5c0b0dc2 161 break;
andrewboyson 47:73af5c0b0dc2 162 case 5:
andrewboyson 47:73af5c0b0dc2 163 p += 2; //Skip past the reserved field
andrewboyson 47:73af5c0b0dc2 164 value = decodeUint32(p);
andrewboyson 47:73af5c0b0dc2 165 p += 4;
andrewboyson 47:73af5c0b0dc2 166 LogF(" MTU %u", value);
andrewboyson 47:73af5c0b0dc2 167 break;
andrewboyson 47:73af5c0b0dc2 168 case 25:
andrewboyson 47:73af5c0b0dc2 169 p += 2; //Skip past the reserved field
andrewboyson 47:73af5c0b0dc2 170 p += 4; //DNS lifetime
andrewboyson 47:73af5c0b0dc2 171 Log(" DNS ");
andrewboyson 47:73af5c0b0dc2 172 Ip6AddressLog(p);
andrewboyson 47:73af5c0b0dc2 173 break;
andrewboyson 47:73af5c0b0dc2 174 default:
andrewboyson 47:73af5c0b0dc2 175 LogF(" ? %d", type);
andrewboyson 47:73af5c0b0dc2 176 break;
andrewboyson 47:73af5c0b0dc2 177 }
andrewboyson 47:73af5c0b0dc2 178 return size * 8;
andrewboyson 47:73af5c0b0dc2 179 }
andrewboyson 47:73af5c0b0dc2 180 void NdpDecodeOptions(char* pData, int dataLength, char* srcMac, char* dstMac)
andrewboyson 46:40d33e9037e4 181 {
andrewboyson 46:40d33e9037e4 182 char* p = pData;
andrewboyson 46:40d33e9037e4 183 char* pE = pData + dataLength;
andrewboyson 52:fbc5a46b5e16 184 while(p < pE)
andrewboyson 52:fbc5a46b5e16 185 {
andrewboyson 52:fbc5a46b5e16 186 int size = decodeOption(p, srcMac, dstMac);
andrewboyson 52:fbc5a46b5e16 187 if (size == 0) break;
andrewboyson 52:fbc5a46b5e16 188 p += size;
andrewboyson 52:fbc5a46b5e16 189 }
andrewboyson 46:40d33e9037e4 190 }
andrewboyson 47:73af5c0b0dc2 191 void NdpLogOptionsVerbose(char* pData, int dataLength)
andrewboyson 47:73af5c0b0dc2 192 {
andrewboyson 47:73af5c0b0dc2 193 char* p = pData;
andrewboyson 47:73af5c0b0dc2 194 char* pE = pData + dataLength;
andrewboyson 52:fbc5a46b5e16 195 while(p < pE)
andrewboyson 52:fbc5a46b5e16 196 {
andrewboyson 52:fbc5a46b5e16 197 int size = logOptionVerbose(p);
andrewboyson 52:fbc5a46b5e16 198 if (size == 0) break;
andrewboyson 52:fbc5a46b5e16 199 p += size;
andrewboyson 52:fbc5a46b5e16 200 }
andrewboyson 47:73af5c0b0dc2 201 }
andrewboyson 47:73af5c0b0dc2 202 void NdpLogOptionsQuiet(char* pData, int dataLength)
andrewboyson 46:40d33e9037e4 203 {
andrewboyson 46:40d33e9037e4 204 char* p = pData;
andrewboyson 46:40d33e9037e4 205 char* pE = pData + dataLength;
andrewboyson 52:fbc5a46b5e16 206 while(p < pE)
andrewboyson 52:fbc5a46b5e16 207 {
andrewboyson 52:fbc5a46b5e16 208 int size = logOptionQuiet(p);
andrewboyson 52:fbc5a46b5e16 209 if (size == 0) break;
andrewboyson 52:fbc5a46b5e16 210 p += size;
andrewboyson 52:fbc5a46b5e16 211 }
andrewboyson 52:fbc5a46b5e16 212 }
andrewboyson 52:fbc5a46b5e16 213 int NdpAddOptionSourceMac(char* p, char* pMac)
andrewboyson 52:fbc5a46b5e16 214 {
andrewboyson 52:fbc5a46b5e16 215 *p++ = 1; //Source MAC option
andrewboyson 52:fbc5a46b5e16 216 *p++ = 1; //8 bytes
andrewboyson 52:fbc5a46b5e16 217 MacCopy(p, pMac);
andrewboyson 52:fbc5a46b5e16 218 return 8;
andrewboyson 52:fbc5a46b5e16 219 }
andrewboyson 52:fbc5a46b5e16 220 int NdpAddOptionTargetMac(char* p, char* pMac)
andrewboyson 52:fbc5a46b5e16 221 {
andrewboyson 52:fbc5a46b5e16 222 *p++ = 2; //Target MAC option
andrewboyson 52:fbc5a46b5e16 223 *p++ = 1; //8 bytes
andrewboyson 52:fbc5a46b5e16 224 MacCopy(p, pMac);
andrewboyson 52:fbc5a46b5e16 225 return 8;
andrewboyson 46:40d33e9037e4 226 }
andrewboyson 47:73af5c0b0dc2 227
andrewboyson 93:580fc113d9e9 228
andrewboyson 93:580fc113d9e9 229 #define INITIAL_DELAY_MS 800
andrewboyson 93:580fc113d9e9 230 #define REPEAT_DELAY_MS 60000
andrewboyson 93:580fc113d9e9 231 static uint32_t delayStartMs = 0; //Set to REPEAT_DELAY_TIME whenever a message is sent and blocks another send until count is back at zero
andrewboyson 47:73af5c0b0dc2 232 void NdpMain()
andrewboyson 93:580fc113d9e9 233 {
andrewboyson 93:580fc113d9e9 234 if (!delayStartMs && MsTimerCount < INITIAL_DELAY_MS) return; //Wait a second at first start up
andrewboyson 93:580fc113d9e9 235 if ( delayStartMs && !MsTimerHasElapsed(delayStartMs, REPEAT_DELAY_MS)) return; //Don't retry within the delay time
andrewboyson 93:580fc113d9e9 236
andrewboyson 93:580fc113d9e9 237 uint32_t elapsedLifeMs = MsTimerCount - lifeStartMs;
andrewboyson 93:580fc113d9e9 238 uint32_t lifetimeMs = NdpLifetime * 1000;
andrewboyson 93:580fc113d9e9 239
andrewboyson 93:580fc113d9e9 240 if (NdpLifetime && elapsedLifeMs < (lifetimeMs >> 1)) return; //Do nothing if within half the life
andrewboyson 93:580fc113d9e9 241
andrewboyson 93:580fc113d9e9 242 if (!NdpLifetime || elapsedLifeMs >= lifetimeMs)
andrewboyson 47:73af5c0b0dc2 243 {
andrewboyson 93:580fc113d9e9 244 if (NdpLifetime)
andrewboyson 93:580fc113d9e9 245 {
andrewboyson 93:580fc113d9e9 246 if (NetTraceNewLine) Log("\r\n");
andrewboyson 93:580fc113d9e9 247 LogTime("NDP lifetime has expired -> clearing NDP information\r\n");
andrewboyson 93:580fc113d9e9 248 }
andrewboyson 93:580fc113d9e9 249 lifeStartMs = MsTimerCount;
andrewboyson 49:1a6336f2b3f9 250 Ip6AddressClear(NdpPrefix);
andrewboyson 47:73af5c0b0dc2 251 SlaacMakeGlobal(NdpPrefix);
andrewboyson 49:1a6336f2b3f9 252 Ip6AddressClear(NdpDnsServer);
andrewboyson 47:73af5c0b0dc2 253 }
andrewboyson 47:73af5c0b0dc2 254
andrewboyson 47:73af5c0b0dc2 255 RsSendSolicitation = true;
andrewboyson 93:580fc113d9e9 256 delayStartMs = MsTimerCount;
andrewboyson 47:73af5c0b0dc2 257 }