Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Mon Feb 04 15:27:33 2019 +0000
Revision:
121:bc048b65a630
Parent:
119:8e1a7805b801
Child:
160:6a1d1d368f80
Added fault codes to UDP and NTP modules following a hard fault.

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