Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Thu Dec 24 19:17:06 2020 +0000
Revision:
175:2d7aa004d881
Parent:
173:9bc30cd82a76
Child:
187:122fc1996c86
Corrected ndp uint32 decode routine

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 bool NdpIpNeedsToBeRouted(char* ip)
andrewboyson 46:40d33e9037e4 76 {
andrewboyson 46:40d33e9037e4 77 //Check address is assigned to internet
andrewboyson 172:9bc3c7b2cca1 78 if (!Ip6AddrIsGlobal(ip)) return false;
andrewboyson 119:8e1a7805b801 79
andrewboyson 46:40d33e9037e4 80 //Check it is not our own prefix
andrewboyson 172:9bc3c7b2cca1 81 if (memcmp(ip, NdpGlobalPrefix, 8) == 0) return false;
andrewboyson 119:8e1a7805b801 82
andrewboyson 46:40d33e9037e4 83 return true;
andrewboyson 46:40d33e9037e4 84 }
andrewboyson 46:40d33e9037e4 85
andrewboyson 46:40d33e9037e4 86 static uint32_t decodeUint32(char* p)
andrewboyson 46:40d33e9037e4 87 {
andrewboyson 175:2d7aa004d881 88 uint32_t value = *p++;
andrewboyson 175:2d7aa004d881 89 value <<= 8; value += *p++;
andrewboyson 175:2d7aa004d881 90 value <<= 8; value += *p++;
andrewboyson 175:2d7aa004d881 91 value <<= 8; value += *p++;
andrewboyson 46:40d33e9037e4 92 return value;
andrewboyson 46:40d33e9037e4 93 }
andrewboyson 47:73af5c0b0dc2 94 static int decodeOption(char* p, char* srcMac, char* dstMac)
andrewboyson 46:40d33e9037e4 95 {
andrewboyson 46:40d33e9037e4 96 int type = *p++;
andrewboyson 46:40d33e9037e4 97 int size = *p++;
andrewboyson 52:fbc5a46b5e16 98 if (size == 0) return 0;
andrewboyson 46:40d33e9037e4 99 switch (type)
andrewboyson 46:40d33e9037e4 100 {
andrewboyson 46:40d33e9037e4 101 case 1:
andrewboyson 47:73af5c0b0dc2 102 if (srcMac) MacCopy(srcMac, p);
andrewboyson 46:40d33e9037e4 103 break;
andrewboyson 46:40d33e9037e4 104 case 2:
andrewboyson 47:73af5c0b0dc2 105 if (dstMac) MacCopy(dstMac, p);
andrewboyson 46:40d33e9037e4 106 break;
andrewboyson 46:40d33e9037e4 107 case 3:
andrewboyson 172:9bc3c7b2cca1 108 {
andrewboyson 172:9bc3c7b2cca1 109 int length = *p; p += 1;
andrewboyson 172:9bc3c7b2cca1 110 uint8_t flags = *p; p += 1;
andrewboyson 172:9bc3c7b2cca1 111 uint32_t validLifetime = decodeUint32(p); p += 4;
andrewboyson 172:9bc3c7b2cca1 112 uint32_t preferredLifetime = decodeUint32(p); p += 4;
andrewboyson 172:9bc3c7b2cca1 113 /*Ignore the reserved2 field*/ p += 4;
andrewboyson 172:9bc3c7b2cca1 114 if (Ip6AddrIsGlobal(p))
andrewboyson 172:9bc3c7b2cca1 115 {
andrewboyson 172:9bc3c7b2cca1 116 Ip6AddrCopy(NdpGlobalPrefix, p);
andrewboyson 172:9bc3c7b2cca1 117 NdpGlobalPrefixLength = length;
andrewboyson 172:9bc3c7b2cca1 118 NdpGlobalPrefixFlagL = flags & 0x80;
andrewboyson 172:9bc3c7b2cca1 119 NdpGlobalPrefixFlagA = flags & 0x40;
andrewboyson 172:9bc3c7b2cca1 120 NdpGlobalPrefixValidLifetime = validLifetime;
andrewboyson 172:9bc3c7b2cca1 121 NdpGlobalPrefixPreferredLifetime = preferredLifetime;
andrewboyson 172:9bc3c7b2cca1 122 SlaacMakeGlobal(p);
andrewboyson 172:9bc3c7b2cca1 123 }
andrewboyson 172:9bc3c7b2cca1 124 else if (Ip6AddrIsUniqueLocal(p))
andrewboyson 172:9bc3c7b2cca1 125 {
andrewboyson 172:9bc3c7b2cca1 126 Ip6AddrCopy(NdpUniqueLocalPrefix, p);
andrewboyson 172:9bc3c7b2cca1 127 NdpUniqueLocalPrefixLength = length;
andrewboyson 172:9bc3c7b2cca1 128 NdpUniqueLocalPrefixFlagL = flags & 0x80;
andrewboyson 172:9bc3c7b2cca1 129 NdpUniqueLocalPrefixFlagA = flags & 0x40;
andrewboyson 172:9bc3c7b2cca1 130 NdpUniqueLocalPrefixValidLifetime = validLifetime;
andrewboyson 172:9bc3c7b2cca1 131 NdpUniqueLocalPrefixPreferredLifetime = preferredLifetime;
andrewboyson 172:9bc3c7b2cca1 132 SlaacMakeUniqueLocal(p);
andrewboyson 172:9bc3c7b2cca1 133 }
andrewboyson 172:9bc3c7b2cca1 134 break;
andrewboyson 172:9bc3c7b2cca1 135 }
andrewboyson 46:40d33e9037e4 136 case 5:
andrewboyson 53:77f8a49adf89 137 /*Ignore the reserved field*/ p += 2;
andrewboyson 46:40d33e9037e4 138 NdpMtu = decodeUint32(p);
andrewboyson 46:40d33e9037e4 139 break;
andrewboyson 46:40d33e9037e4 140 case 25:
andrewboyson 53:77f8a49adf89 141 /*Ignore the reserved field*/ p += 2;
andrewboyson 53:77f8a49adf89 142 NdpDnsLifetime = decodeUint32(p); p += 4;
andrewboyson 172:9bc3c7b2cca1 143 Ip6AddrCopy(NdpDnsServer, p);
andrewboyson 46:40d33e9037e4 144 break;
andrewboyson 46:40d33e9037e4 145 }
andrewboyson 46:40d33e9037e4 146 return size * 8;
andrewboyson 46:40d33e9037e4 147 }
andrewboyson 53:77f8a49adf89 148 static void logFlagsLA(char flags)
andrewboyson 53:77f8a49adf89 149 {
andrewboyson 121:bc048b65a630 150 if (flags & 0x80) LogChar('L');
andrewboyson 121:bc048b65a630 151 if (flags & 0x40) LogChar('A');
andrewboyson 53:77f8a49adf89 152 }
andrewboyson 47:73af5c0b0dc2 153 static int logOptionVerbose(char* p)
andrewboyson 47:73af5c0b0dc2 154 {
andrewboyson 46:40d33e9037e4 155 uint32_t value;
andrewboyson 46:40d33e9037e4 156 int type = *p++;
andrewboyson 46:40d33e9037e4 157 int size = *p++;
andrewboyson 52:fbc5a46b5e16 158 if (size == 0)
andrewboyson 52:fbc5a46b5e16 159 {
andrewboyson 119:8e1a7805b801 160 LogF(" Size zero for option %d\r\n", type);
andrewboyson 52:fbc5a46b5e16 161 return 0;
andrewboyson 52:fbc5a46b5e16 162 }
andrewboyson 46:40d33e9037e4 163 switch (type)
andrewboyson 46:40d33e9037e4 164 {
andrewboyson 46:40d33e9037e4 165 case 1:
andrewboyson 53:77f8a49adf89 166 Log(" Src MAC "); MacLog(p); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 167 case 2:
andrewboyson 53:77f8a49adf89 168 Log(" Tgt MAC "); MacLog(p); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 169 case 3:
andrewboyson 53:77f8a49adf89 170 Log(" Prefix length "); LogF("%d", *p); Log("\r\n"); p += 1;
andrewboyson 53:77f8a49adf89 171 Log(" Prefix flags "); logFlagsLA(*p); Log("\r\n"); p += 1;
andrewboyson 53:77f8a49adf89 172 value = decodeUint32(p); Log(" Prefix valid "); LogF("%u", value); Log("\r\n"); p += 4;
andrewboyson 53:77f8a49adf89 173 value = decodeUint32(p); Log(" Prefix preferred "); LogF("%u", value); Log("\r\n"); p += 4;
andrewboyson 119:8e1a7805b801 174 /*Ignore the Reserved2 field*/ p += 4;
andrewboyson 172:9bc3c7b2cca1 175 Log(" Prefix "); Ip6AddrLog(p); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 176 case 5:
andrewboyson 53:77f8a49adf89 177 /*Ignore the reserved field*/ p += 2;
andrewboyson 53:77f8a49adf89 178 value = decodeUint32(p); Log(" MTU "); LogF("%u", value); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 179 case 25:
andrewboyson 53:77f8a49adf89 180 /*Ignore the reserved field*/ p += 2;
andrewboyson 53:77f8a49adf89 181 value = decodeUint32(p); Log(" DNS lifetime "); LogF("%u", value); Log("\r\n"); p += 4;
andrewboyson 172:9bc3c7b2cca1 182 Log(" DNS Server "); Ip6AddrLog(p); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 183 default:
andrewboyson 53:77f8a49adf89 184 Log(" Unknown option "); LogF("%d", type); Log("\r\n"); break;
andrewboyson 46:40d33e9037e4 185 }
andrewboyson 46:40d33e9037e4 186 return size * 8;
andrewboyson 46:40d33e9037e4 187 }
andrewboyson 47:73af5c0b0dc2 188 static int logOptionQuiet(char* p)
andrewboyson 47:73af5c0b0dc2 189 {
andrewboyson 47:73af5c0b0dc2 190 uint32_t value;
andrewboyson 47:73af5c0b0dc2 191 int type = *p++;
andrewboyson 47:73af5c0b0dc2 192 int size = *p++;
andrewboyson 52:fbc5a46b5e16 193 if (size == 0) return 0;
andrewboyson 47:73af5c0b0dc2 194 switch (type)
andrewboyson 47:73af5c0b0dc2 195 {
andrewboyson 47:73af5c0b0dc2 196 case 1:
andrewboyson 47:73af5c0b0dc2 197 Log(" src ");
andrewboyson 47:73af5c0b0dc2 198 MacLog(p);
andrewboyson 47:73af5c0b0dc2 199 break;
andrewboyson 47:73af5c0b0dc2 200 case 2:
andrewboyson 53:77f8a49adf89 201 Log(" tgt ");
andrewboyson 47:73af5c0b0dc2 202 MacLog(p);
andrewboyson 47:73af5c0b0dc2 203 break;
andrewboyson 47:73af5c0b0dc2 204 case 3:
andrewboyson 160:6a1d1d368f80 205 p++; //Length
andrewboyson 160:6a1d1d368f80 206 p++; //LA
andrewboyson 47:73af5c0b0dc2 207 p += 4; //Valid lifetime
andrewboyson 47:73af5c0b0dc2 208 p += 4; //Preferred lifetime
andrewboyson 47:73af5c0b0dc2 209 p += 4; //Reserved 2
andrewboyson 47:73af5c0b0dc2 210 Log(" prefix ");
andrewboyson 172:9bc3c7b2cca1 211 Ip6AddrLog(p); //IP6 address
andrewboyson 47:73af5c0b0dc2 212 break;
andrewboyson 47:73af5c0b0dc2 213 case 5:
andrewboyson 47:73af5c0b0dc2 214 p += 2; //Skip past the reserved field
andrewboyson 47:73af5c0b0dc2 215 value = decodeUint32(p);
andrewboyson 47:73af5c0b0dc2 216 p += 4;
andrewboyson 47:73af5c0b0dc2 217 LogF(" MTU %u", value);
andrewboyson 47:73af5c0b0dc2 218 break;
andrewboyson 47:73af5c0b0dc2 219 case 25:
andrewboyson 47:73af5c0b0dc2 220 p += 2; //Skip past the reserved field
andrewboyson 47:73af5c0b0dc2 221 p += 4; //DNS lifetime
andrewboyson 47:73af5c0b0dc2 222 Log(" DNS ");
andrewboyson 172:9bc3c7b2cca1 223 Ip6AddrLog(p);
andrewboyson 47:73af5c0b0dc2 224 break;
andrewboyson 47:73af5c0b0dc2 225 default:
andrewboyson 47:73af5c0b0dc2 226 LogF(" ? %d", type);
andrewboyson 47:73af5c0b0dc2 227 break;
andrewboyson 47:73af5c0b0dc2 228 }
andrewboyson 47:73af5c0b0dc2 229 return size * 8;
andrewboyson 47:73af5c0b0dc2 230 }
andrewboyson 47:73af5c0b0dc2 231 void NdpDecodeOptions(char* pData, int dataLength, char* srcMac, char* dstMac)
andrewboyson 46:40d33e9037e4 232 {
andrewboyson 46:40d33e9037e4 233 char* p = pData;
andrewboyson 46:40d33e9037e4 234 char* pE = pData + dataLength;
andrewboyson 52:fbc5a46b5e16 235 while(p < pE)
andrewboyson 52:fbc5a46b5e16 236 {
andrewboyson 52:fbc5a46b5e16 237 int size = decodeOption(p, srcMac, dstMac);
andrewboyson 52:fbc5a46b5e16 238 if (size == 0) break;
andrewboyson 52:fbc5a46b5e16 239 p += size;
andrewboyson 52:fbc5a46b5e16 240 }
andrewboyson 46:40d33e9037e4 241 }
andrewboyson 47:73af5c0b0dc2 242 void NdpLogOptionsVerbose(char* pData, int dataLength)
andrewboyson 47:73af5c0b0dc2 243 {
andrewboyson 47:73af5c0b0dc2 244 char* p = pData;
andrewboyson 47:73af5c0b0dc2 245 char* pE = pData + dataLength;
andrewboyson 52:fbc5a46b5e16 246 while(p < pE)
andrewboyson 52:fbc5a46b5e16 247 {
andrewboyson 52:fbc5a46b5e16 248 int size = logOptionVerbose(p);
andrewboyson 52:fbc5a46b5e16 249 if (size == 0) break;
andrewboyson 52:fbc5a46b5e16 250 p += size;
andrewboyson 52:fbc5a46b5e16 251 }
andrewboyson 47:73af5c0b0dc2 252 }
andrewboyson 47:73af5c0b0dc2 253 void NdpLogOptionsQuiet(char* pData, int dataLength)
andrewboyson 46:40d33e9037e4 254 {
andrewboyson 46:40d33e9037e4 255 char* p = pData;
andrewboyson 46:40d33e9037e4 256 char* pE = pData + dataLength;
andrewboyson 52:fbc5a46b5e16 257 while(p < pE)
andrewboyson 52:fbc5a46b5e16 258 {
andrewboyson 52:fbc5a46b5e16 259 int size = logOptionQuiet(p);
andrewboyson 52:fbc5a46b5e16 260 if (size == 0) break;
andrewboyson 52:fbc5a46b5e16 261 p += size;
andrewboyson 52:fbc5a46b5e16 262 }
andrewboyson 52:fbc5a46b5e16 263 }
andrewboyson 52:fbc5a46b5e16 264 int NdpAddOptionSourceMac(char* p, char* pMac)
andrewboyson 52:fbc5a46b5e16 265 {
andrewboyson 52:fbc5a46b5e16 266 *p++ = 1; //Source MAC option
andrewboyson 52:fbc5a46b5e16 267 *p++ = 1; //8 bytes
andrewboyson 52:fbc5a46b5e16 268 MacCopy(p, pMac);
andrewboyson 52:fbc5a46b5e16 269 return 8;
andrewboyson 52:fbc5a46b5e16 270 }
andrewboyson 52:fbc5a46b5e16 271 int NdpAddOptionTargetMac(char* p, char* pMac)
andrewboyson 52:fbc5a46b5e16 272 {
andrewboyson 52:fbc5a46b5e16 273 *p++ = 2; //Target MAC option
andrewboyson 52:fbc5a46b5e16 274 *p++ = 1; //8 bytes
andrewboyson 52:fbc5a46b5e16 275 MacCopy(p, pMac);
andrewboyson 52:fbc5a46b5e16 276 return 8;
andrewboyson 46:40d33e9037e4 277 }