Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Mon Jan 18 18:23:46 2021 +0000
Revision:
187:122fc1996c86
Parent:
175:2d7aa004d881
Changed Ip4Address to Ip4Addr.; Moved Ip6AddrIsExternal from NdpNeedsToBeRouted.

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 119:8e1a7805b801 10 #include "rs.h"
andrewboyson 93:580fc113d9e9 11 #include "mstimer.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 46:40d33e9037e4 16
andrewboyson 46:40d33e9037e4 17 char NdpRouterMac[6];
andrewboyson 46:40d33e9037e4 18
andrewboyson 172:9bc3c7b2cca1 19
andrewboyson 172:9bc3c7b2cca1 20 int NdpGlobalPrefixLength = 0;
andrewboyson 172:9bc3c7b2cca1 21 bool NdpGlobalPrefixFlagL = false;
andrewboyson 172:9bc3c7b2cca1 22 bool NdpGlobalPrefixFlagA = false;
andrewboyson 172:9bc3c7b2cca1 23 uint32_t NdpGlobalPrefixValidLifetime = 0;
andrewboyson 172:9bc3c7b2cca1 24 uint32_t NdpGlobalPrefixPreferredLifetime = 0;
andrewboyson 172:9bc3c7b2cca1 25 char NdpGlobalPrefix[16];
andrewboyson 172:9bc3c7b2cca1 26
andrewboyson 172:9bc3c7b2cca1 27 int NdpUniqueLocalPrefixLength = 0;
andrewboyson 172:9bc3c7b2cca1 28 bool NdpUniqueLocalPrefixFlagL = false;
andrewboyson 172:9bc3c7b2cca1 29 bool NdpUniqueLocalPrefixFlagA = false;
andrewboyson 172:9bc3c7b2cca1 30 uint32_t NdpUniqueLocalPrefixValidLifetime = 0;
andrewboyson 172:9bc3c7b2cca1 31 uint32_t NdpUniqueLocalPrefixPreferredLifetime = 0;
andrewboyson 172:9bc3c7b2cca1 32 char NdpUniqueLocalPrefix[16];
andrewboyson 46:40d33e9037e4 33
andrewboyson 46:40d33e9037e4 34 uint32_t NdpDnsLifetime = 0;
andrewboyson 46:40d33e9037e4 35 char NdpDnsServer[16];
andrewboyson 46:40d33e9037e4 36
andrewboyson 46:40d33e9037e4 37 int NdpMtu = 0;
andrewboyson 46:40d33e9037e4 38
andrewboyson 119:8e1a7805b801 39 static uint32_t elapsedLifeMsTimer = 0;
andrewboyson 93:580fc113d9e9 40
andrewboyson 93:580fc113d9e9 41 uint32_t NdpGetElapsedLife()
andrewboyson 93:580fc113d9e9 42 {
andrewboyson 119:8e1a7805b801 43 return (MsTimerCount - elapsedLifeMsTimer) / 1000;
andrewboyson 119:8e1a7805b801 44 }
andrewboyson 119:8e1a7805b801 45 static int lease = 0;
andrewboyson 119:8e1a7805b801 46 int NdpGetLease() { return lease; }
andrewboyson 119:8e1a7805b801 47 void NdpSetLease(int value) //Set whenever an IP address request has been acknowledged
andrewboyson 119:8e1a7805b801 48 {
andrewboyson 119:8e1a7805b801 49 lease = value;
andrewboyson 119:8e1a7805b801 50 elapsedLifeMsTimer = MsTimerCount;
andrewboyson 93:580fc113d9e9 51 }
andrewboyson 119:8e1a7805b801 52 bool NdpIsFresh()
andrewboyson 93:580fc113d9e9 53 {
andrewboyson 119:8e1a7805b801 54 uint32_t elapsedLifeMs = MsTimerCount - elapsedLifeMsTimer;
andrewboyson 119:8e1a7805b801 55 uint32_t leaseMs = lease * 1000;
andrewboyson 119:8e1a7805b801 56
andrewboyson 119:8e1a7805b801 57 if (lease && elapsedLifeMs < (leaseMs >> 1)) return true; //Fresh if within half the lease
andrewboyson 119:8e1a7805b801 58
andrewboyson 119:8e1a7805b801 59 if (!lease || elapsedLifeMs >= leaseMs)
andrewboyson 119:8e1a7805b801 60 {
andrewboyson 119:8e1a7805b801 61 if (lease)
andrewboyson 119:8e1a7805b801 62 {
andrewboyson 119:8e1a7805b801 63 if (NetTraceNewLine) Log("\r\n");
andrewboyson 119:8e1a7805b801 64 LogTime("NDP lease has expired -> clearing NDP information\r\n");
andrewboyson 119:8e1a7805b801 65 }
andrewboyson 119:8e1a7805b801 66 elapsedLifeMsTimer = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 67 Ip6AddrClear(SlaacUniqueLocalIp);
andrewboyson 172:9bc3c7b2cca1 68 Ip6AddrClear(SlaacGlobalIp);
andrewboyson 172:9bc3c7b2cca1 69 Ip6AddrClear(NdpDnsServer);
andrewboyson 119:8e1a7805b801 70 }
andrewboyson 119:8e1a7805b801 71
andrewboyson 119:8e1a7805b801 72 return false;
andrewboyson 93:580fc113d9e9 73 }
andrewboyson 46:40d33e9037e4 74
andrewboyson 46:40d33e9037e4 75 static uint32_t decodeUint32(char* p)
andrewboyson 46:40d33e9037e4 76 {
andrewboyson 175:2d7aa004d881 77 uint32_t value = *p++;
andrewboyson 175:2d7aa004d881 78 value <<= 8; value += *p++;
andrewboyson 175:2d7aa004d881 79 value <<= 8; value += *p++;
andrewboyson 175:2d7aa004d881 80 value <<= 8; value += *p++;
andrewboyson 46:40d33e9037e4 81 return value;
andrewboyson 46:40d33e9037e4 82 }
andrewboyson 47:73af5c0b0dc2 83 static int decodeOption(char* p, char* srcMac, char* dstMac)
andrewboyson 46:40d33e9037e4 84 {
andrewboyson 46:40d33e9037e4 85 int type = *p++;
andrewboyson 46:40d33e9037e4 86 int size = *p++;
andrewboyson 52:fbc5a46b5e16 87 if (size == 0) return 0;
andrewboyson 46:40d33e9037e4 88 switch (type)
andrewboyson 46:40d33e9037e4 89 {
andrewboyson 46:40d33e9037e4 90 case 1:
andrewboyson 47:73af5c0b0dc2 91 if (srcMac) MacCopy(srcMac, p);
andrewboyson 46:40d33e9037e4 92 break;
andrewboyson 46:40d33e9037e4 93 case 2:
andrewboyson 47:73af5c0b0dc2 94 if (dstMac) MacCopy(dstMac, p);
andrewboyson 46:40d33e9037e4 95 break;
andrewboyson 46:40d33e9037e4 96 case 3:
andrewboyson 172:9bc3c7b2cca1 97 {
andrewboyson 172:9bc3c7b2cca1 98 int length = *p; p += 1;
andrewboyson 172:9bc3c7b2cca1 99 uint8_t flags = *p; p += 1;
andrewboyson 172:9bc3c7b2cca1 100 uint32_t validLifetime = decodeUint32(p); p += 4;
andrewboyson 172:9bc3c7b2cca1 101 uint32_t preferredLifetime = decodeUint32(p); p += 4;
andrewboyson 172:9bc3c7b2cca1 102 /*Ignore the reserved2 field*/ p += 4;
andrewboyson 172:9bc3c7b2cca1 103 if (Ip6AddrIsGlobal(p))
andrewboyson 172:9bc3c7b2cca1 104 {
andrewboyson 172:9bc3c7b2cca1 105 Ip6AddrCopy(NdpGlobalPrefix, p);
andrewboyson 172:9bc3c7b2cca1 106 NdpGlobalPrefixLength = length;
andrewboyson 172:9bc3c7b2cca1 107 NdpGlobalPrefixFlagL = flags & 0x80;
andrewboyson 172:9bc3c7b2cca1 108 NdpGlobalPrefixFlagA = flags & 0x40;
andrewboyson 172:9bc3c7b2cca1 109 NdpGlobalPrefixValidLifetime = validLifetime;
andrewboyson 172:9bc3c7b2cca1 110 NdpGlobalPrefixPreferredLifetime = preferredLifetime;
andrewboyson 172:9bc3c7b2cca1 111 SlaacMakeGlobal(p);
andrewboyson 172:9bc3c7b2cca1 112 }
andrewboyson 172:9bc3c7b2cca1 113 else if (Ip6AddrIsUniqueLocal(p))
andrewboyson 172:9bc3c7b2cca1 114 {
andrewboyson 172:9bc3c7b2cca1 115 Ip6AddrCopy(NdpUniqueLocalPrefix, p);
andrewboyson 172:9bc3c7b2cca1 116 NdpUniqueLocalPrefixLength = length;
andrewboyson 172:9bc3c7b2cca1 117 NdpUniqueLocalPrefixFlagL = flags & 0x80;
andrewboyson 172:9bc3c7b2cca1 118 NdpUniqueLocalPrefixFlagA = flags & 0x40;
andrewboyson 172:9bc3c7b2cca1 119 NdpUniqueLocalPrefixValidLifetime = validLifetime;
andrewboyson 172:9bc3c7b2cca1 120 NdpUniqueLocalPrefixPreferredLifetime = preferredLifetime;
andrewboyson 172:9bc3c7b2cca1 121 SlaacMakeUniqueLocal(p);
andrewboyson 172:9bc3c7b2cca1 122 }
andrewboyson 172:9bc3c7b2cca1 123 break;
andrewboyson 172:9bc3c7b2cca1 124 }
andrewboyson 46:40d33e9037e4 125 case 5:
andrewboyson 53:77f8a49adf89 126 /*Ignore the reserved field*/ p += 2;
andrewboyson 46:40d33e9037e4 127 NdpMtu = decodeUint32(p);
andrewboyson 46:40d33e9037e4 128 break;
andrewboyson 46:40d33e9037e4 129 case 25:
andrewboyson 53:77f8a49adf89 130 /*Ignore the reserved field*/ p += 2;
andrewboyson 53:77f8a49adf89 131 NdpDnsLifetime = decodeUint32(p); p += 4;
andrewboyson 172:9bc3c7b2cca1 132 Ip6AddrCopy(NdpDnsServer, p);
andrewboyson 46:40d33e9037e4 133 break;
andrewboyson 46:40d33e9037e4 134 }
andrewboyson 46:40d33e9037e4 135 return size * 8;
andrewboyson 46:40d33e9037e4 136 }
andrewboyson 53:77f8a49adf89 137 static void logFlagsLA(char flags)
andrewboyson 53:77f8a49adf89 138 {
andrewboyson 121:bc048b65a630 139 if (flags & 0x80) LogChar('L');
andrewboyson 121:bc048b65a630 140 if (flags & 0x40) LogChar('A');
andrewboyson 53:77f8a49adf89 141 }
andrewboyson 47:73af5c0b0dc2 142 static int logOptionVerbose(char* p)
andrewboyson 47:73af5c0b0dc2 143 {
andrewboyson 46:40d33e9037e4 144 uint32_t value;
andrewboyson 46:40d33e9037e4 145 int type = *p++;
andrewboyson 46:40d33e9037e4 146 int size = *p++;
andrewboyson 52:fbc5a46b5e16 147 if (size == 0)
andrewboyson 52:fbc5a46b5e16 148 {
andrewboyson 119:8e1a7805b801 149 LogF(" Size zero for option %d\r\n", type);
andrewboyson 52:fbc5a46b5e16 150 return 0;
andrewboyson 52:fbc5a46b5e16 151 }
andrewboyson 46:40d33e9037e4 152 switch (type)
andrewboyson 46:40d33e9037e4 153 {
andrewboyson 46:40d33e9037e4 154 case 1:
andrewboyson 53:77f8a49adf89 155 Log(" Src MAC "); MacLog(p); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 156 case 2:
andrewboyson 53:77f8a49adf89 157 Log(" Tgt MAC "); MacLog(p); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 158 case 3:
andrewboyson 53:77f8a49adf89 159 Log(" Prefix length "); LogF("%d", *p); Log("\r\n"); p += 1;
andrewboyson 53:77f8a49adf89 160 Log(" Prefix flags "); logFlagsLA(*p); Log("\r\n"); p += 1;
andrewboyson 53:77f8a49adf89 161 value = decodeUint32(p); Log(" Prefix valid "); LogF("%u", value); Log("\r\n"); p += 4;
andrewboyson 53:77f8a49adf89 162 value = decodeUint32(p); Log(" Prefix preferred "); LogF("%u", value); Log("\r\n"); p += 4;
andrewboyson 119:8e1a7805b801 163 /*Ignore the Reserved2 field*/ p += 4;
andrewboyson 172:9bc3c7b2cca1 164 Log(" Prefix "); Ip6AddrLog(p); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 165 case 5:
andrewboyson 53:77f8a49adf89 166 /*Ignore the reserved field*/ p += 2;
andrewboyson 53:77f8a49adf89 167 value = decodeUint32(p); Log(" MTU "); LogF("%u", value); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 168 case 25:
andrewboyson 53:77f8a49adf89 169 /*Ignore the reserved field*/ p += 2;
andrewboyson 53:77f8a49adf89 170 value = decodeUint32(p); Log(" DNS lifetime "); LogF("%u", value); Log("\r\n"); p += 4;
andrewboyson 172:9bc3c7b2cca1 171 Log(" DNS Server "); Ip6AddrLog(p); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 172 default:
andrewboyson 53:77f8a49adf89 173 Log(" Unknown option "); LogF("%d", type); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 174 }
andrewboyson 46:40d33e9037e4 175 return size * 8;
andrewboyson 46:40d33e9037e4 176 }
andrewboyson 47:73af5c0b0dc2 177 static int logOptionQuiet(char* p)
andrewboyson 47:73af5c0b0dc2 178 {
andrewboyson 47:73af5c0b0dc2 179 uint32_t value;
andrewboyson 47:73af5c0b0dc2 180 int type = *p++;
andrewboyson 47:73af5c0b0dc2 181 int size = *p++;
andrewboyson 52:fbc5a46b5e16 182 if (size == 0) return 0;
andrewboyson 47:73af5c0b0dc2 183 switch (type)
andrewboyson 47:73af5c0b0dc2 184 {
andrewboyson 47:73af5c0b0dc2 185 case 1:
andrewboyson 47:73af5c0b0dc2 186 Log(" src ");
andrewboyson 47:73af5c0b0dc2 187 MacLog(p);
andrewboyson 47:73af5c0b0dc2 188 break;
andrewboyson 47:73af5c0b0dc2 189 case 2:
andrewboyson 53:77f8a49adf89 190 Log(" tgt ");
andrewboyson 47:73af5c0b0dc2 191 MacLog(p);
andrewboyson 47:73af5c0b0dc2 192 break;
andrewboyson 47:73af5c0b0dc2 193 case 3:
andrewboyson 160:6a1d1d368f80 194 p++; //Length
andrewboyson 160:6a1d1d368f80 195 p++; //LA
andrewboyson 47:73af5c0b0dc2 196 p += 4; //Valid lifetime
andrewboyson 47:73af5c0b0dc2 197 p += 4; //Preferred lifetime
andrewboyson 47:73af5c0b0dc2 198 p += 4; //Reserved 2
andrewboyson 47:73af5c0b0dc2 199 Log(" prefix ");
andrewboyson 172:9bc3c7b2cca1 200 Ip6AddrLog(p); //IP6 address
andrewboyson 47:73af5c0b0dc2 201 break;
andrewboyson 47:73af5c0b0dc2 202 case 5:
andrewboyson 47:73af5c0b0dc2 203 p += 2; //Skip past the reserved field
andrewboyson 47:73af5c0b0dc2 204 value = decodeUint32(p);
andrewboyson 47:73af5c0b0dc2 205 p += 4;
andrewboyson 47:73af5c0b0dc2 206 LogF(" MTU %u", value);
andrewboyson 47:73af5c0b0dc2 207 break;
andrewboyson 47:73af5c0b0dc2 208 case 25:
andrewboyson 47:73af5c0b0dc2 209 p += 2; //Skip past the reserved field
andrewboyson 47:73af5c0b0dc2 210 p += 4; //DNS lifetime
andrewboyson 47:73af5c0b0dc2 211 Log(" DNS ");
andrewboyson 172:9bc3c7b2cca1 212 Ip6AddrLog(p);
andrewboyson 47:73af5c0b0dc2 213 break;
andrewboyson 47:73af5c0b0dc2 214 default:
andrewboyson 47:73af5c0b0dc2 215 LogF(" ? %d", type);
andrewboyson 47:73af5c0b0dc2 216 break;
andrewboyson 47:73af5c0b0dc2 217 }
andrewboyson 47:73af5c0b0dc2 218 return size * 8;
andrewboyson 47:73af5c0b0dc2 219 }
andrewboyson 47:73af5c0b0dc2 220 void NdpDecodeOptions(char* pData, int dataLength, char* srcMac, char* dstMac)
andrewboyson 46:40d33e9037e4 221 {
andrewboyson 46:40d33e9037e4 222 char* p = pData;
andrewboyson 46:40d33e9037e4 223 char* pE = pData + dataLength;
andrewboyson 52:fbc5a46b5e16 224 while(p < pE)
andrewboyson 52:fbc5a46b5e16 225 {
andrewboyson 52:fbc5a46b5e16 226 int size = decodeOption(p, srcMac, dstMac);
andrewboyson 52:fbc5a46b5e16 227 if (size == 0) break;
andrewboyson 52:fbc5a46b5e16 228 p += size;
andrewboyson 52:fbc5a46b5e16 229 }
andrewboyson 46:40d33e9037e4 230 }
andrewboyson 47:73af5c0b0dc2 231 void NdpLogOptionsVerbose(char* pData, int dataLength)
andrewboyson 47:73af5c0b0dc2 232 {
andrewboyson 47:73af5c0b0dc2 233 char* p = pData;
andrewboyson 47:73af5c0b0dc2 234 char* pE = pData + dataLength;
andrewboyson 52:fbc5a46b5e16 235 while(p < pE)
andrewboyson 52:fbc5a46b5e16 236 {
andrewboyson 52:fbc5a46b5e16 237 int size = logOptionVerbose(p);
andrewboyson 52:fbc5a46b5e16 238 if (size == 0) break;
andrewboyson 52:fbc5a46b5e16 239 p += size;
andrewboyson 52:fbc5a46b5e16 240 }
andrewboyson 47:73af5c0b0dc2 241 }
andrewboyson 47:73af5c0b0dc2 242 void NdpLogOptionsQuiet(char* pData, int dataLength)
andrewboyson 46:40d33e9037e4 243 {
andrewboyson 46:40d33e9037e4 244 char* p = pData;
andrewboyson 46:40d33e9037e4 245 char* pE = pData + dataLength;
andrewboyson 52:fbc5a46b5e16 246 while(p < pE)
andrewboyson 52:fbc5a46b5e16 247 {
andrewboyson 52:fbc5a46b5e16 248 int size = logOptionQuiet(p);
andrewboyson 52:fbc5a46b5e16 249 if (size == 0) break;
andrewboyson 52:fbc5a46b5e16 250 p += size;
andrewboyson 52:fbc5a46b5e16 251 }
andrewboyson 52:fbc5a46b5e16 252 }
andrewboyson 52:fbc5a46b5e16 253 int NdpAddOptionSourceMac(char* p, char* pMac)
andrewboyson 52:fbc5a46b5e16 254 {
andrewboyson 52:fbc5a46b5e16 255 *p++ = 1; //Source MAC option
andrewboyson 52:fbc5a46b5e16 256 *p++ = 1; //8 bytes
andrewboyson 52:fbc5a46b5e16 257 MacCopy(p, pMac);
andrewboyson 52:fbc5a46b5e16 258 return 8;
andrewboyson 52:fbc5a46b5e16 259 }
andrewboyson 52:fbc5a46b5e16 260 int NdpAddOptionTargetMac(char* p, char* pMac)
andrewboyson 52:fbc5a46b5e16 261 {
andrewboyson 52:fbc5a46b5e16 262 *p++ = 2; //Target MAC option
andrewboyson 52:fbc5a46b5e16 263 *p++ = 1; //8 bytes
andrewboyson 52:fbc5a46b5e16 264 MacCopy(p, pMac);
andrewboyson 52:fbc5a46b5e16 265 return 8;
andrewboyson 46:40d33e9037e4 266 }