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

Committer:
andrewboyson
Date:
Thu Oct 26 14:50:24 2017 +0000
Revision:
47:73af5c0b0dc2
Parent:
46:40d33e9037e4
Child:
48:952dddb74b8b
Replaced a number of temporary buffers with direct writes to the Log or HTTP.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 30:e34173b7585c 1 #include "mbed.h"
andrewboyson 30:e34173b7585c 2 #include "log.h"
andrewboyson 30:e34173b7585c 3 #include "net.h"
andrewboyson 37:793b39683406 4 #include "action.h"
andrewboyson 30:e34173b7585c 5 #include "icmp6.h"
andrewboyson 30:e34173b7585c 6 #include "udptcp6.h"
andrewboyson 30:e34173b7585c 7 #include "ar.h"
andrewboyson 35:93c39d260a83 8 #include "nr.h"
andrewboyson 30:e34173b7585c 9 #include "slaac.h"
andrewboyson 30:e34173b7585c 10 #include "eth.h"
andrewboyson 30:e34173b7585c 11 #include "ip.h"
andrewboyson 30:e34173b7585c 12 #include "ip6.h"
andrewboyson 46:40d33e9037e4 13 #include "ndp.h"
andrewboyson 30:e34173b7585c 14 #include "io.h"
andrewboyson 35:93c39d260a83 15 #include "ntp.h"
andrewboyson 36:900e24b27bfb 16 #include "mac.h"
andrewboyson 47:73af5c0b0dc2 17 #include "http-reply.h"
andrewboyson 11:c051adb70c5a 18
andrewboyson 34:e3a7bff69bfc 19 #define SHOW_FILTERED true
andrewboyson 11:c051adb70c5a 20
andrewboyson 36:900e24b27bfb 21 void Ip6Clear(char* ip)
andrewboyson 36:900e24b27bfb 22 {
andrewboyson 36:900e24b27bfb 23 *ip = 0;
andrewboyson 36:900e24b27bfb 24 }
andrewboyson 36:900e24b27bfb 25 bool Ip6IsEmpty(char* ip)
andrewboyson 36:900e24b27bfb 26 {
andrewboyson 36:900e24b27bfb 27 return !*ip; //Just check for the first byte being non zero
andrewboyson 36:900e24b27bfb 28 }
andrewboyson 14:e75a59c1123d 29 static void addHexNibble(bool* pAdded, int number, int index, char** pp)
andrewboyson 14:e75a59c1123d 30 {
andrewboyson 14:e75a59c1123d 31 int nibble = number;
andrewboyson 14:e75a59c1123d 32 if (index) nibble >>= 4;
andrewboyson 14:e75a59c1123d 33 nibble &= 0xF;
andrewboyson 14:e75a59c1123d 34
andrewboyson 14:e75a59c1123d 35 if (nibble || *pAdded)
andrewboyson 14:e75a59c1123d 36 {
andrewboyson 14:e75a59c1123d 37 **pp = nibble < 10 ? nibble + '0' : nibble - 10 + 'a';
andrewboyson 14:e75a59c1123d 38 *pp += 1;
andrewboyson 14:e75a59c1123d 39 *pAdded = true;
andrewboyson 14:e75a59c1123d 40 }
andrewboyson 14:e75a59c1123d 41 }
andrewboyson 14:e75a59c1123d 42 int Ip6AddressToString(char* pIp, int size, char* pText)
andrewboyson 14:e75a59c1123d 43 {
andrewboyson 14:e75a59c1123d 44 char* pIpE = pIp + 16;
andrewboyson 14:e75a59c1123d 45 char* p = pText;
andrewboyson 14:e75a59c1123d 46 while (true)
andrewboyson 14:e75a59c1123d 47 {
andrewboyson 14:e75a59c1123d 48 bool added = false;
andrewboyson 14:e75a59c1123d 49 if (*pIp || *(pIp + 1))
andrewboyson 14:e75a59c1123d 50 {
andrewboyson 14:e75a59c1123d 51 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 0), 1, &p);
andrewboyson 14:e75a59c1123d 52 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 0), 0, &p);
andrewboyson 14:e75a59c1123d 53 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 1), 1, &p);
andrewboyson 14:e75a59c1123d 54 if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 1), 0, &p);
andrewboyson 14:e75a59c1123d 55 }
andrewboyson 14:e75a59c1123d 56
andrewboyson 14:e75a59c1123d 57 pIp += 2;
andrewboyson 14:e75a59c1123d 58 if (pIp >= pIpE) break;
andrewboyson 14:e75a59c1123d 59
andrewboyson 14:e75a59c1123d 60 if (p > pText + size - 2) break; *p++ = ':';
andrewboyson 14:e75a59c1123d 61 }
andrewboyson 14:e75a59c1123d 62 *p = 0;
andrewboyson 14:e75a59c1123d 63 return p - pText;
andrewboyson 14:e75a59c1123d 64 }
andrewboyson 47:73af5c0b0dc2 65 static void logHexNibble(bool* pAdded, int number, int index)
andrewboyson 47:73af5c0b0dc2 66 {
andrewboyson 47:73af5c0b0dc2 67 int nibble = number;
andrewboyson 47:73af5c0b0dc2 68 if (index) nibble >>= 4;
andrewboyson 47:73af5c0b0dc2 69 nibble &= 0xF;
andrewboyson 47:73af5c0b0dc2 70
andrewboyson 47:73af5c0b0dc2 71 if (nibble || *pAdded)
andrewboyson 47:73af5c0b0dc2 72 {
andrewboyson 47:73af5c0b0dc2 73 LogPush(nibble < 10 ? nibble + '0' : nibble - 10 + 'a');
andrewboyson 47:73af5c0b0dc2 74 *pAdded = true;
andrewboyson 47:73af5c0b0dc2 75 }
andrewboyson 47:73af5c0b0dc2 76 }
andrewboyson 47:73af5c0b0dc2 77 int Ip6AddressLog(char* pIp)
andrewboyson 47:73af5c0b0dc2 78 {
andrewboyson 47:73af5c0b0dc2 79 int count = 0;
andrewboyson 47:73af5c0b0dc2 80 char* pIpE = pIp + 16;
andrewboyson 47:73af5c0b0dc2 81 while (true)
andrewboyson 47:73af5c0b0dc2 82 {
andrewboyson 47:73af5c0b0dc2 83 bool added = false;
andrewboyson 47:73af5c0b0dc2 84 if (*pIp || *(pIp + 1))
andrewboyson 47:73af5c0b0dc2 85 {
andrewboyson 47:73af5c0b0dc2 86 logHexNibble(&added, *(pIp + 0), 1); if (added) count++;
andrewboyson 47:73af5c0b0dc2 87 logHexNibble(&added, *(pIp + 0), 0); if (added) count++;
andrewboyson 47:73af5c0b0dc2 88 logHexNibble(&added, *(pIp + 1), 1); if (added) count++;
andrewboyson 47:73af5c0b0dc2 89 logHexNibble(&added, *(pIp + 1), 0); if (added) count++;
andrewboyson 47:73af5c0b0dc2 90 }
andrewboyson 47:73af5c0b0dc2 91
andrewboyson 47:73af5c0b0dc2 92 pIp += 2;
andrewboyson 47:73af5c0b0dc2 93 if (pIp >= pIpE) break;
andrewboyson 47:73af5c0b0dc2 94
andrewboyson 47:73af5c0b0dc2 95 LogPush(':'); count++;
andrewboyson 47:73af5c0b0dc2 96 }
andrewboyson 47:73af5c0b0dc2 97 return count;
andrewboyson 47:73af5c0b0dc2 98 }
andrewboyson 47:73af5c0b0dc2 99 static void httpHexNibble(bool* pAdded, int number, int index)
andrewboyson 47:73af5c0b0dc2 100 {
andrewboyson 47:73af5c0b0dc2 101 int nibble = number;
andrewboyson 47:73af5c0b0dc2 102 if (index) nibble >>= 4;
andrewboyson 47:73af5c0b0dc2 103 nibble &= 0xF;
andrewboyson 47:73af5c0b0dc2 104
andrewboyson 47:73af5c0b0dc2 105 if (nibble || *pAdded)
andrewboyson 47:73af5c0b0dc2 106 {
andrewboyson 47:73af5c0b0dc2 107 HttpReplyAddChar(nibble < 10 ? nibble + '0' : nibble - 10 + 'a');
andrewboyson 47:73af5c0b0dc2 108 *pAdded = true;
andrewboyson 47:73af5c0b0dc2 109 }
andrewboyson 47:73af5c0b0dc2 110 }
andrewboyson 47:73af5c0b0dc2 111 int Ip6AddressHttp(char* pIp)
andrewboyson 47:73af5c0b0dc2 112 {
andrewboyson 47:73af5c0b0dc2 113 int count = 0;
andrewboyson 47:73af5c0b0dc2 114 char* pIpE = pIp + 16;
andrewboyson 47:73af5c0b0dc2 115 while (true)
andrewboyson 47:73af5c0b0dc2 116 {
andrewboyson 47:73af5c0b0dc2 117 bool added = false;
andrewboyson 47:73af5c0b0dc2 118 if (*pIp || *(pIp + 1))
andrewboyson 47:73af5c0b0dc2 119 {
andrewboyson 47:73af5c0b0dc2 120 httpHexNibble(&added, *(pIp + 0), 1); if (added) count++;
andrewboyson 47:73af5c0b0dc2 121 httpHexNibble(&added, *(pIp + 0), 0); if (added) count++;
andrewboyson 47:73af5c0b0dc2 122 httpHexNibble(&added, *(pIp + 1), 1); if (added) count++;
andrewboyson 47:73af5c0b0dc2 123 httpHexNibble(&added, *(pIp + 1), 0); if (added) count++;
andrewboyson 47:73af5c0b0dc2 124 }
andrewboyson 47:73af5c0b0dc2 125
andrewboyson 47:73af5c0b0dc2 126 pIp += 2;
andrewboyson 47:73af5c0b0dc2 127 if (pIp >= pIpE) break;
andrewboyson 47:73af5c0b0dc2 128
andrewboyson 47:73af5c0b0dc2 129 HttpReplyAddChar(':'); count++;
andrewboyson 47:73af5c0b0dc2 130 }
andrewboyson 47:73af5c0b0dc2 131 return count;
andrewboyson 47:73af5c0b0dc2 132 }
andrewboyson 35:93c39d260a83 133 bool Ip6IsSame(char* ipA, char* ipB)
andrewboyson 35:93c39d260a83 134 {
andrewboyson 35:93c39d260a83 135 return memcmp(ipA, ipB, 16) == 0;
andrewboyson 35:93c39d260a83 136 }
andrewboyson 36:900e24b27bfb 137 void Ip6Copy(char* ipTo, char* ipFrom)
andrewboyson 35:93c39d260a83 138 {
andrewboyson 35:93c39d260a83 139 memcpy(ipTo, ipFrom, 16);
andrewboyson 35:93c39d260a83 140 }
andrewboyson 14:e75a59c1123d 141
andrewboyson 11:c051adb70c5a 142 char Ip6AllNodes [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
andrewboyson 11:c051adb70c5a 143 char Ip6AllRouters[] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
andrewboyson 11:c051adb70c5a 144 char Ip6Mdns [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
andrewboyson 11:c051adb70c5a 145 char Ip6Llmnr [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03};
andrewboyson 11:c051adb70c5a 146
andrewboyson 44:83ce5ace337b 147 void Ip6DstIpFromDest(int dest, char* pDstIp)
andrewboyson 11:c051adb70c5a 148 {
andrewboyson 37:793b39683406 149 switch (dest)
andrewboyson 11:c051adb70c5a 150 {
andrewboyson 36:900e24b27bfb 151 case UNICAST: break;
andrewboyson 46:40d33e9037e4 152 case UNICAST_DNS: Ip6Copy(pDstIp, NdpDnsServer ); break;
andrewboyson 36:900e24b27bfb 153 case UNICAST_NTP: Ip6Copy(pDstIp, NtpServerIp6 ); break;
andrewboyson 36:900e24b27bfb 154 case MULTICAST_NODE: Ip6Copy(pDstIp, Ip6AllNodes ); break;
andrewboyson 36:900e24b27bfb 155 case MULTICAST_ROUTER: Ip6Copy(pDstIp, Ip6AllRouters); break;
andrewboyson 36:900e24b27bfb 156 case MULTICAST_MDNS: Ip6Copy(pDstIp, Ip6Mdns ); break;
andrewboyson 36:900e24b27bfb 157 case MULTICAST_LLMNR: Ip6Copy(pDstIp, Ip6Llmnr ); break;
andrewboyson 11:c051adb70c5a 158 default:
andrewboyson 37:793b39683406 159 LogTimeF("Ip6DestIpFromDest unknown destination %d\r\n", dest);
andrewboyson 11:c051adb70c5a 160 break;
andrewboyson 11:c051adb70c5a 161 }
andrewboyson 11:c051adb70c5a 162 }
andrewboyson 44:83ce5ace337b 163 void Ip6SrcIpFromScope(int scope, char* pSrcIp)
andrewboyson 44:83ce5ace337b 164 {
andrewboyson 44:83ce5ace337b 165 if (scope == SCOPE_GLOBAL) Ip6Copy(pSrcIp, SlaacGlobalIp );
andrewboyson 44:83ce5ace337b 166 else Ip6Copy(pSrcIp, SlaacLinkLocalIp);
andrewboyson 44:83ce5ace337b 167 //Note that scope could be SCOPE_NONE if source was multicast in which case should return the link local ip.
andrewboyson 44:83ce5ace337b 168 }
andrewboyson 10:f0854784e960 169
andrewboyson 10:f0854784e960 170 #define HEADER_LENGTH 40
andrewboyson 10:f0854784e960 171 __packed struct header
andrewboyson 10:f0854784e960 172 {
andrewboyson 10:f0854784e960 173 uint32_t versionTrafficFlow;
andrewboyson 10:f0854784e960 174 uint16_t dataLength;
andrewboyson 10:f0854784e960 175 uint8_t protocol;
andrewboyson 10:f0854784e960 176 uint8_t hoplimit;
andrewboyson 10:f0854784e960 177 char src[16];
andrewboyson 10:f0854784e960 178 char dst[16];
andrewboyson 10:f0854784e960 179 };
andrewboyson 11:c051adb70c5a 180
andrewboyson 11:c051adb70c5a 181 static uint8_t version;
andrewboyson 11:c051adb70c5a 182 static int dataLength;
andrewboyson 11:c051adb70c5a 183 static uint8_t protocol;
andrewboyson 11:c051adb70c5a 184 static uint8_t hoplimit;
andrewboyson 35:93c39d260a83 185 static char srcIp[16];
andrewboyson 35:93c39d260a83 186 static char dstIp[16];
andrewboyson 11:c051adb70c5a 187 static void* pData;
andrewboyson 11:c051adb70c5a 188
andrewboyson 11:c051adb70c5a 189 static void readHeader(struct header * pHeader)
andrewboyson 11:c051adb70c5a 190 {
andrewboyson 11:c051adb70c5a 191 version = (pHeader->versionTrafficFlow >> 4) & 0xF;
andrewboyson 11:c051adb70c5a 192 dataLength = NetToHost16(pHeader->dataLength);
andrewboyson 11:c051adb70c5a 193 protocol = pHeader->protocol;
andrewboyson 11:c051adb70c5a 194 hoplimit = pHeader->hoplimit;
andrewboyson 36:900e24b27bfb 195 Ip6Copy(srcIp, pHeader->src);
andrewboyson 36:900e24b27bfb 196 Ip6Copy(dstIp, pHeader->dst);
andrewboyson 11:c051adb70c5a 197 pData = (char*)pHeader + HEADER_LENGTH;
andrewboyson 11:c051adb70c5a 198 }
andrewboyson 11:c051adb70c5a 199 static void writeHeader(struct header * pHeader)
andrewboyson 11:c051adb70c5a 200 {
andrewboyson 36:900e24b27bfb 201 pHeader->versionTrafficFlow = version << 4;
andrewboyson 36:900e24b27bfb 202 pHeader->protocol = protocol;
andrewboyson 44:83ce5ace337b 203 pHeader->hoplimit = hoplimit;
andrewboyson 36:900e24b27bfb 204 Ip6Copy(pHeader->dst, dstIp);
andrewboyson 36:900e24b27bfb 205 Ip6Copy(pHeader->src, srcIp);
andrewboyson 36:900e24b27bfb 206 pHeader->dataLength = NetToHost16(dataLength);
andrewboyson 11:c051adb70c5a 207 }
andrewboyson 11:c051adb70c5a 208
andrewboyson 37:793b39683406 209 static void logHeader()
andrewboyson 11:c051adb70c5a 210 {
andrewboyson 43:bc028d5a6424 211 if (NetTraceVerbose)
andrewboyson 43:bc028d5a6424 212 {
andrewboyson 43:bc028d5a6424 213 Log("IP6 header\r\n");
andrewboyson 43:bc028d5a6424 214 LogF(" Version %d\r\n", version);
andrewboyson 43:bc028d5a6424 215 LogF(" Payload length %d\r\n", dataLength);
andrewboyson 43:bc028d5a6424 216 LogF(" Hop limit %d\r\n", hoplimit);
andrewboyson 47:73af5c0b0dc2 217 LogF(" Protocol "); IpProtocolLog(protocol); Log("\r\n");
andrewboyson 47:73af5c0b0dc2 218 Log (" Source IP "); Ip6AddressLog(srcIp); Log("\r\n");
andrewboyson 47:73af5c0b0dc2 219 Log (" Destination IP "); Ip6AddressLog(dstIp); Log("\r\n");
andrewboyson 43:bc028d5a6424 220 }
andrewboyson 43:bc028d5a6424 221 else
andrewboyson 43:bc028d5a6424 222 {
andrewboyson 44:83ce5ace337b 223 Log("IP6 header ");
andrewboyson 47:73af5c0b0dc2 224 IpProtocolLog(protocol);
andrewboyson 43:bc028d5a6424 225 Log(" ");
andrewboyson 47:73af5c0b0dc2 226 Ip6AddressLog(srcIp);
andrewboyson 43:bc028d5a6424 227 Log(" >>> ");
andrewboyson 47:73af5c0b0dc2 228 Ip6AddressLog(dstIp);
andrewboyson 43:bc028d5a6424 229 Log("\r\n");
andrewboyson 43:bc028d5a6424 230 }
andrewboyson 11:c051adb70c5a 231 }
andrewboyson 11:c051adb70c5a 232
andrewboyson 10:f0854784e960 233 static bool getIsSolicited(char* p)
andrewboyson 10:f0854784e960 234 {
andrewboyson 10:f0854784e960 235 if (*p++ != 0xff) return false;
andrewboyson 10:f0854784e960 236 if (*p++ != 0x02) return false;
andrewboyson 10:f0854784e960 237
andrewboyson 10:f0854784e960 238 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 239 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 240
andrewboyson 10:f0854784e960 241 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 242 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 243
andrewboyson 10:f0854784e960 244 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 245 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 246
andrewboyson 10:f0854784e960 247 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 248 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 249
andrewboyson 10:f0854784e960 250 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 251 if (*p++ != 0x01) return false;
andrewboyson 10:f0854784e960 252
andrewboyson 10:f0854784e960 253 if (*p++ != 0xff) return false;
andrewboyson 10:f0854784e960 254
andrewboyson 10:f0854784e960 255 return true;
andrewboyson 10:f0854784e960 256 }
andrewboyson 10:f0854784e960 257 static bool getIsSameGroup(char* pA, char* pB)
andrewboyson 10:f0854784e960 258 {
andrewboyson 10:f0854784e960 259 pA += 13;
andrewboyson 10:f0854784e960 260 pB += 13;
andrewboyson 10:f0854784e960 261 if (*pA++ != *pB++) return false;
andrewboyson 10:f0854784e960 262 if (*pA++ != *pB++) return false;
andrewboyson 10:f0854784e960 263 return *pA == *pB;
andrewboyson 10:f0854784e960 264 }
andrewboyson 37:793b39683406 265 static void (*pTraceBack)(void);
andrewboyson 37:793b39683406 266 static void trace()
andrewboyson 10:f0854784e960 267 {
andrewboyson 37:793b39683406 268 pTraceBack();
andrewboyson 37:793b39683406 269 logHeader();
andrewboyson 37:793b39683406 270 }
andrewboyson 37:793b39683406 271 int Ip6HandleReceivedPacket(void (*traceback)(void), char* pSrcMac, void* pPacket, int* pSize, char* pDstMac)
andrewboyson 37:793b39683406 272 {
andrewboyson 37:793b39683406 273 pTraceBack = traceback;
andrewboyson 37:793b39683406 274
andrewboyson 10:f0854784e960 275 struct header * pHeader = (header*)pPacket;
andrewboyson 11:c051adb70c5a 276 readHeader(pHeader);
andrewboyson 10:f0854784e960 277
andrewboyson 44:83ce5ace337b 278 int scope = SlaacScope(dstIp);
andrewboyson 35:93c39d260a83 279 bool isMulticast = dstIp[0] == 0xFF;
andrewboyson 35:93c39d260a83 280 bool isSolicited = getIsSolicited(dstIp);
andrewboyson 35:93c39d260a83 281 bool isGroup = getIsSameGroup(dstIp, SlaacLinkLocalIp);
andrewboyson 10:f0854784e960 282
andrewboyson 44:83ce5ace337b 283 bool doIt = scope || (isMulticast && !isSolicited) || (isGroup && isSolicited);
andrewboyson 10:f0854784e960 284
andrewboyson 14:e75a59c1123d 285 if (!doIt)
andrewboyson 14:e75a59c1123d 286 {
andrewboyson 37:793b39683406 287 if (SHOW_FILTERED)
andrewboyson 15:6ca6778168b1 288 {
andrewboyson 47:73af5c0b0dc2 289 LogTime("IP6 filtered out ip ");
andrewboyson 47:73af5c0b0dc2 290 Ip6AddressLog(dstIp);
andrewboyson 47:73af5c0b0dc2 291 LogF(" from ");
andrewboyson 47:73af5c0b0dc2 292 Ip6AddressLog(srcIp);
andrewboyson 47:73af5c0b0dc2 293 Log("\r\n");
andrewboyson 15:6ca6778168b1 294 }
andrewboyson 14:e75a59c1123d 295 return DO_NOTHING;
andrewboyson 14:e75a59c1123d 296 }
andrewboyson 10:f0854784e960 297
andrewboyson 35:93c39d260a83 298 ArAddIp6Record(pSrcMac, srcIp);
andrewboyson 35:93c39d260a83 299 NrMakeRequestForNameFromIp6(srcIp);
andrewboyson 11:c051adb70c5a 300
andrewboyson 10:f0854784e960 301 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 302 switch (protocol)
andrewboyson 10:f0854784e960 303 {
andrewboyson 44:83ce5ace337b 304 case HOPOPT: action = DO_NOTHING; break;
andrewboyson 44:83ce5ace337b 305 case ICMP6: action = Icmp6HandleReceivedPacket(trace, scope, srcIp, dstIp, &dataLength, pData); break;
andrewboyson 44:83ce5ace337b 306 case UDP: action = Udp6HandleReceivedPacket(trace, scope, srcIp, dstIp, &dataLength, pData); break;
andrewboyson 44:83ce5ace337b 307 case TCP: action = Tcp6HandleReceivedPacket(trace, scope, srcIp, dstIp, &dataLength, pData); break;
andrewboyson 10:f0854784e960 308 default:
andrewboyson 37:793b39683406 309 LogTimeF("IP6 protocol %d unhandled\r\n", protocol);
andrewboyson 10:f0854784e960 310 return DO_NOTHING;
andrewboyson 10:f0854784e960 311 }
andrewboyson 11:c051adb70c5a 312 if (!action) return DO_NOTHING;
andrewboyson 11:c051adb70c5a 313
andrewboyson 46:40d33e9037e4 314 if (NdpIpNeedsToBeRouted(dstIp)) MacCopy(pDstMac, NdpRouterMac); //Send to the router MAC
andrewboyson 46:40d33e9037e4 315 else MacCopy(pDstMac, pSrcMac); //Send back to the source
andrewboyson 10:f0854784e960 316
andrewboyson 11:c051adb70c5a 317 writeHeader(pHeader);
andrewboyson 11:c051adb70c5a 318
andrewboyson 10:f0854784e960 319 *pSize = HEADER_LENGTH + dataLength;
andrewboyson 10:f0854784e960 320
andrewboyson 37:793b39683406 321 if (ActionGetTracePart(action)) logHeader();
andrewboyson 37:793b39683406 322
andrewboyson 10:f0854784e960 323 return action;
andrewboyson 10:f0854784e960 324 }
andrewboyson 10:f0854784e960 325 int Ip6PollForPacketToSend(void* pPacket, int* pSize, char* pDstMac)
andrewboyson 10:f0854784e960 326 {
andrewboyson 11:c051adb70c5a 327 pData = (char*)pPacket + HEADER_LENGTH;
andrewboyson 11:c051adb70c5a 328 dataLength = 0;
andrewboyson 11:c051adb70c5a 329 version = 6;
andrewboyson 11:c051adb70c5a 330 hoplimit = 255;
andrewboyson 10:f0854784e960 331
andrewboyson 10:f0854784e960 332 int action = DO_NOTHING;
andrewboyson 47:73af5c0b0dc2 333 if (!action)
andrewboyson 10:f0854784e960 334 {
andrewboyson 35:93c39d260a83 335 action = Icmp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp);
andrewboyson 10:f0854784e960 336 protocol = ICMP6;
andrewboyson 10:f0854784e960 337 }
andrewboyson 10:f0854784e960 338
andrewboyson 47:73af5c0b0dc2 339 if (!action)
andrewboyson 10:f0854784e960 340 {
andrewboyson 35:93c39d260a83 341 action = Udp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp);
andrewboyson 10:f0854784e960 342 protocol = UDP;
andrewboyson 10:f0854784e960 343 }
andrewboyson 11:c051adb70c5a 344 if (!action) return DO_NOTHING;
andrewboyson 37:793b39683406 345
andrewboyson 37:793b39683406 346 int dest = ActionGetDestPart(action);
andrewboyson 37:793b39683406 347 switch (dest)
andrewboyson 11:c051adb70c5a 348 {
andrewboyson 11:c051adb70c5a 349 case UNICAST:
andrewboyson 11:c051adb70c5a 350 case UNICAST_DNS:
andrewboyson 11:c051adb70c5a 351 case UNICAST_DHCP:
andrewboyson 22:914b970356f0 352 case UNICAST_NTP:
andrewboyson 46:40d33e9037e4 353 if (NdpIpNeedsToBeRouted(dstIp)) MacCopy (pDstMac, NdpRouterMac); //Send to the router MAC
andrewboyson 46:40d33e9037e4 354 else ArIpToMac6(dstIp, pDstMac); //Make the remote MAC from NP
andrewboyson 11:c051adb70c5a 355 break;
andrewboyson 22:914b970356f0 356 case MULTICAST_NODE:
andrewboyson 22:914b970356f0 357 case MULTICAST_ROUTER:
andrewboyson 22:914b970356f0 358 case MULTICAST_MDNS:
andrewboyson 22:914b970356f0 359 case MULTICAST_LLMNR:
andrewboyson 22:914b970356f0 360 case SOLICITED_NODE:
andrewboyson 22:914b970356f0 361 break;
andrewboyson 22:914b970356f0 362 default:
andrewboyson 37:793b39683406 363 LogTimeF("Ip6PollForPacketToSend - undefined destination %d\r\n", dest);
andrewboyson 22:914b970356f0 364 break;
andrewboyson 11:c051adb70c5a 365 }
andrewboyson 10:f0854784e960 366
andrewboyson 11:c051adb70c5a 367 writeHeader((header*)pPacket);
andrewboyson 11:c051adb70c5a 368
andrewboyson 10:f0854784e960 369 *pSize = HEADER_LENGTH + dataLength;
andrewboyson 10:f0854784e960 370
andrewboyson 37:793b39683406 371 if (ActionGetTracePart(action)) logHeader();
andrewboyson 37:793b39683406 372
andrewboyson 10:f0854784e960 373 return action;
andrewboyson 10:f0854784e960 374 }