A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.
Dependents: oldheating gps motorhome heating
ndp.c
00001 #include <stdint.h> 00002 #include <stdbool.h> 00003 #include <string.h> 00004 00005 #include "log.h" 00006 #include "net.h" 00007 #include "mac.h" 00008 #include "ip6addr.h" 00009 #include "slaac.h" 00010 #include "rs.h" 00011 #include "mstimer.h" 00012 00013 int NdpHopLimit = 0; 00014 bool NdpManagedConfiguration = false; 00015 bool NdpOtherConfiguration = false; 00016 00017 char NdpRouterMac[6]; 00018 00019 00020 int NdpGlobalPrefixLength = 0; 00021 bool NdpGlobalPrefixFlagL = false; 00022 bool NdpGlobalPrefixFlagA = false; 00023 uint32_t NdpGlobalPrefixValidLifetime = 0; 00024 uint32_t NdpGlobalPrefixPreferredLifetime = 0; 00025 char NdpGlobalPrefix[16]; 00026 00027 int NdpUniqueLocalPrefixLength = 0; 00028 bool NdpUniqueLocalPrefixFlagL = false; 00029 bool NdpUniqueLocalPrefixFlagA = false; 00030 uint32_t NdpUniqueLocalPrefixValidLifetime = 0; 00031 uint32_t NdpUniqueLocalPrefixPreferredLifetime = 0; 00032 char NdpUniqueLocalPrefix[16]; 00033 00034 uint32_t NdpDnsLifetime = 0; 00035 char NdpDnsServer[16]; 00036 00037 int NdpMtu = 0; 00038 00039 static uint32_t elapsedLifeMsTimer = 0; 00040 00041 uint32_t NdpGetElapsedLife() 00042 { 00043 return (MsTimerCount - elapsedLifeMsTimer) / 1000; 00044 } 00045 static int lease = 0; 00046 int NdpGetLease() { return lease; } 00047 void NdpSetLease(int value) //Set whenever an IP address request has been acknowledged 00048 { 00049 lease = value; 00050 elapsedLifeMsTimer = MsTimerCount; 00051 } 00052 bool NdpIsFresh() 00053 { 00054 uint32_t elapsedLifeMs = MsTimerCount - elapsedLifeMsTimer; 00055 uint32_t leaseMs = lease * 1000; 00056 00057 if (lease && elapsedLifeMs < (leaseMs >> 1)) return true; //Fresh if within half the lease 00058 00059 if (!lease || elapsedLifeMs >= leaseMs) 00060 { 00061 if (lease) 00062 { 00063 if (NetTraceNewLine) Log("\r\n"); 00064 LogTime("NDP lease has expired -> clearing NDP information\r\n"); 00065 } 00066 elapsedLifeMsTimer = MsTimerCount; 00067 Ip6AddrClear(SlaacUniqueLocalIp); 00068 Ip6AddrClear(SlaacGlobalIp); 00069 Ip6AddrClear(NdpDnsServer); 00070 } 00071 00072 return false; 00073 } 00074 00075 static uint32_t decodeUint32(char* p) 00076 { 00077 uint32_t value = *p++; 00078 value <<= 8; value += *p++; 00079 value <<= 8; value += *p++; 00080 value <<= 8; value += *p++; 00081 return value; 00082 } 00083 static int decodeOption(char* p, char* srcMac, char* dstMac) 00084 { 00085 int type = *p++; 00086 int size = *p++; 00087 if (size == 0) return 0; 00088 switch (type) 00089 { 00090 case 1: 00091 if (srcMac) MacCopy(srcMac, p); 00092 break; 00093 case 2: 00094 if (dstMac) MacCopy(dstMac, p); 00095 break; 00096 case 3: 00097 { 00098 int length = *p; p += 1; 00099 uint8_t flags = *p; p += 1; 00100 uint32_t validLifetime = decodeUint32(p); p += 4; 00101 uint32_t preferredLifetime = decodeUint32(p); p += 4; 00102 /*Ignore the reserved2 field*/ p += 4; 00103 if (Ip6AddrIsGlobal(p)) 00104 { 00105 Ip6AddrCopy(NdpGlobalPrefix, p); 00106 NdpGlobalPrefixLength = length; 00107 NdpGlobalPrefixFlagL = flags & 0x80; 00108 NdpGlobalPrefixFlagA = flags & 0x40; 00109 NdpGlobalPrefixValidLifetime = validLifetime; 00110 NdpGlobalPrefixPreferredLifetime = preferredLifetime; 00111 SlaacMakeGlobal(p); 00112 } 00113 else if (Ip6AddrIsUniqueLocal(p)) 00114 { 00115 Ip6AddrCopy(NdpUniqueLocalPrefix, p); 00116 NdpUniqueLocalPrefixLength = length; 00117 NdpUniqueLocalPrefixFlagL = flags & 0x80; 00118 NdpUniqueLocalPrefixFlagA = flags & 0x40; 00119 NdpUniqueLocalPrefixValidLifetime = validLifetime; 00120 NdpUniqueLocalPrefixPreferredLifetime = preferredLifetime; 00121 SlaacMakeUniqueLocal(p); 00122 } 00123 break; 00124 } 00125 case 5: 00126 /*Ignore the reserved field*/ p += 2; 00127 NdpMtu = decodeUint32(p); 00128 break; 00129 case 25: 00130 /*Ignore the reserved field*/ p += 2; 00131 NdpDnsLifetime = decodeUint32(p); p += 4; 00132 Ip6AddrCopy(NdpDnsServer, p); 00133 break; 00134 } 00135 return size * 8; 00136 } 00137 static void logFlagsLA(char flags) 00138 { 00139 if (flags & 0x80) LogChar('L'); 00140 if (flags & 0x40) LogChar('A'); 00141 } 00142 static int logOptionVerbose(char* p) 00143 { 00144 uint32_t value; 00145 int type = *p++; 00146 int size = *p++; 00147 if (size == 0) 00148 { 00149 LogF(" Size zero for option %d\r\n", type); 00150 return 0; 00151 } 00152 switch (type) 00153 { 00154 case 1: 00155 Log(" Src MAC "); MacLog(p); Log("\r\n"); break; 00156 case 2: 00157 Log(" Tgt MAC "); MacLog(p); Log("\r\n"); break; 00158 case 3: 00159 Log(" Prefix length "); LogF("%d", *p); Log("\r\n"); p += 1; 00160 Log(" Prefix flags "); logFlagsLA(*p); Log("\r\n"); p += 1; 00161 value = decodeUint32(p); Log(" Prefix valid "); LogF("%u", value); Log("\r\n"); p += 4; 00162 value = decodeUint32(p); Log(" Prefix preferred "); LogF("%u", value); Log("\r\n"); p += 4; 00163 /*Ignore the Reserved2 field*/ p += 4; 00164 Log(" Prefix "); Ip6AddrLog(p); Log("\r\n"); break; 00165 case 5: 00166 /*Ignore the reserved field*/ p += 2; 00167 value = decodeUint32(p); Log(" MTU "); LogF("%u", value); Log("\r\n"); break; 00168 case 25: 00169 /*Ignore the reserved field*/ p += 2; 00170 value = decodeUint32(p); Log(" DNS lifetime "); LogF("%u", value); Log("\r\n"); p += 4; 00171 Log(" DNS Server "); Ip6AddrLog(p); Log("\r\n"); break; 00172 default: 00173 Log(" Unknown option "); LogF("%d", type); Log("\r\n"); break; 00174 } 00175 return size * 8; 00176 } 00177 static int logOptionQuiet(char* p) 00178 { 00179 uint32_t value; 00180 int type = *p++; 00181 int size = *p++; 00182 if (size == 0) return 0; 00183 switch (type) 00184 { 00185 case 1: 00186 Log(" src "); 00187 MacLog(p); 00188 break; 00189 case 2: 00190 Log(" tgt "); 00191 MacLog(p); 00192 break; 00193 case 3: 00194 p++; //Length 00195 p++; //LA 00196 p += 4; //Valid lifetime 00197 p += 4; //Preferred lifetime 00198 p += 4; //Reserved 2 00199 Log(" prefix "); 00200 Ip6AddrLog(p); //IP6 address 00201 break; 00202 case 5: 00203 p += 2; //Skip past the reserved field 00204 value = decodeUint32(p); 00205 p += 4; 00206 LogF(" MTU %u", value); 00207 break; 00208 case 25: 00209 p += 2; //Skip past the reserved field 00210 p += 4; //DNS lifetime 00211 Log(" DNS "); 00212 Ip6AddrLog(p); 00213 break; 00214 default: 00215 LogF(" ? %d", type); 00216 break; 00217 } 00218 return size * 8; 00219 } 00220 void NdpDecodeOptions(char* pData, int dataLength, char* srcMac, char* dstMac) 00221 { 00222 char* p = pData; 00223 char* pE = pData + dataLength; 00224 while(p < pE) 00225 { 00226 int size = decodeOption(p, srcMac, dstMac); 00227 if (size == 0) break; 00228 p += size; 00229 } 00230 } 00231 void NdpLogOptionsVerbose(char* pData, int dataLength) 00232 { 00233 char* p = pData; 00234 char* pE = pData + dataLength; 00235 while(p < pE) 00236 { 00237 int size = logOptionVerbose(p); 00238 if (size == 0) break; 00239 p += size; 00240 } 00241 } 00242 void NdpLogOptionsQuiet(char* pData, int dataLength) 00243 { 00244 char* p = pData; 00245 char* pE = pData + dataLength; 00246 while(p < pE) 00247 { 00248 int size = logOptionQuiet(p); 00249 if (size == 0) break; 00250 p += size; 00251 } 00252 } 00253 int NdpAddOptionSourceMac(char* p, char* pMac) 00254 { 00255 *p++ = 1; //Source MAC option 00256 *p++ = 1; //8 bytes 00257 MacCopy(p, pMac); 00258 return 8; 00259 } 00260 int NdpAddOptionTargetMac(char* p, char* pMac) 00261 { 00262 *p++ = 2; //Target MAC option 00263 *p++ = 1; //8 bytes 00264 MacCopy(p, pMac); 00265 return 8; 00266 }
Generated on Tue Jul 12 2022 18:53:40 by 1.7.2