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 Nov 09 15:44:29 2017 +0000
Revision:
53:77f8a49adf89
Parent:
52:fbc5a46b5e16
Child:
57:e0fb648acf48
Set hop and ttl equal to 255 for on-link and to 64 or NdpHopLimit (64) for off-link.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 52:fbc5a46b5e16 1 #include "mbed.h"
andrewboyson 52:fbc5a46b5e16 2 #include "log.h"
andrewboyson 49:1a6336f2b3f9 3 #include "net.h"
andrewboyson 49:1a6336f2b3f9 4 #include "action.h"
andrewboyson 49:1a6336f2b3f9 5 #include "icmp6.h"
andrewboyson 49:1a6336f2b3f9 6 #include "udptcp6.h"
andrewboyson 49:1a6336f2b3f9 7 #include "ar6.h"
andrewboyson 50:492f2d2954e4 8 #include "nr6.h"
andrewboyson 49:1a6336f2b3f9 9 #include "slaac.h"
andrewboyson 49:1a6336f2b3f9 10 #include "eth.h"
andrewboyson 49:1a6336f2b3f9 11 #include "ip.h"
andrewboyson 49:1a6336f2b3f9 12 #include "ip6addr.h"
andrewboyson 49:1a6336f2b3f9 13 #include "ndp.h"
andrewboyson 49:1a6336f2b3f9 14 #include "io.h"
andrewboyson 49:1a6336f2b3f9 15 #include "ntp.h"
andrewboyson 49:1a6336f2b3f9 16 #include "mac.h"
andrewboyson 49:1a6336f2b3f9 17 #include "http.h"
andrewboyson 11:c051adb70c5a 18
andrewboyson 48:952dddb74b8b 19 bool Ip6Trace = true;
andrewboyson 11:c051adb70c5a 20
andrewboyson 10:f0854784e960 21
andrewboyson 10:f0854784e960 22 #define HEADER_LENGTH 40
andrewboyson 10:f0854784e960 23 __packed struct header
andrewboyson 10:f0854784e960 24 {
andrewboyson 10:f0854784e960 25 uint32_t versionTrafficFlow;
andrewboyson 10:f0854784e960 26 uint16_t dataLength;
andrewboyson 10:f0854784e960 27 uint8_t protocol;
andrewboyson 10:f0854784e960 28 uint8_t hoplimit;
andrewboyson 10:f0854784e960 29 char src[16];
andrewboyson 10:f0854784e960 30 char dst[16];
andrewboyson 10:f0854784e960 31 };
andrewboyson 11:c051adb70c5a 32
andrewboyson 11:c051adb70c5a 33 static uint8_t version;
andrewboyson 11:c051adb70c5a 34 static int dataLength;
andrewboyson 11:c051adb70c5a 35 static uint8_t protocol;
andrewboyson 11:c051adb70c5a 36 static uint8_t hoplimit;
andrewboyson 35:93c39d260a83 37 static char srcIp[16];
andrewboyson 35:93c39d260a83 38 static char dstIp[16];
andrewboyson 11:c051adb70c5a 39 static void* pData;
andrewboyson 11:c051adb70c5a 40
andrewboyson 11:c051adb70c5a 41 static void readHeader(struct header * pHeader)
andrewboyson 11:c051adb70c5a 42 {
andrewboyson 11:c051adb70c5a 43 version = (pHeader->versionTrafficFlow >> 4) & 0xF;
andrewboyson 11:c051adb70c5a 44 dataLength = NetToHost16(pHeader->dataLength);
andrewboyson 11:c051adb70c5a 45 protocol = pHeader->protocol;
andrewboyson 11:c051adb70c5a 46 hoplimit = pHeader->hoplimit;
andrewboyson 49:1a6336f2b3f9 47 Ip6AddressCopy(srcIp, pHeader->src);
andrewboyson 49:1a6336f2b3f9 48 Ip6AddressCopy(dstIp, pHeader->dst);
andrewboyson 11:c051adb70c5a 49 pData = (char*)pHeader + HEADER_LENGTH;
andrewboyson 11:c051adb70c5a 50 }
andrewboyson 11:c051adb70c5a 51 static void writeHeader(struct header * pHeader)
andrewboyson 11:c051adb70c5a 52 {
andrewboyson 49:1a6336f2b3f9 53 pHeader->versionTrafficFlow = version << 4;
andrewboyson 49:1a6336f2b3f9 54 pHeader->protocol = protocol;
andrewboyson 49:1a6336f2b3f9 55 pHeader->hoplimit = hoplimit;
andrewboyson 49:1a6336f2b3f9 56 Ip6AddressCopy(pHeader->dst, dstIp);
andrewboyson 49:1a6336f2b3f9 57 Ip6AddressCopy(pHeader->src, srcIp);
andrewboyson 49:1a6336f2b3f9 58 pHeader->dataLength = NetToHost16(dataLength);
andrewboyson 11:c051adb70c5a 59 }
andrewboyson 11:c051adb70c5a 60
andrewboyson 37:793b39683406 61 static void logHeader()
andrewboyson 11:c051adb70c5a 62 {
andrewboyson 43:bc028d5a6424 63 if (NetTraceVerbose)
andrewboyson 43:bc028d5a6424 64 {
andrewboyson 43:bc028d5a6424 65 Log("IP6 header\r\n");
andrewboyson 43:bc028d5a6424 66 LogF(" Version %d\r\n", version);
andrewboyson 43:bc028d5a6424 67 LogF(" Payload length %d\r\n", dataLength);
andrewboyson 43:bc028d5a6424 68 LogF(" Hop limit %d\r\n", hoplimit);
andrewboyson 47:73af5c0b0dc2 69 LogF(" Protocol "); IpProtocolLog(protocol); Log("\r\n");
andrewboyson 47:73af5c0b0dc2 70 Log (" Source IP "); Ip6AddressLog(srcIp); Log("\r\n");
andrewboyson 47:73af5c0b0dc2 71 Log (" Destination IP "); Ip6AddressLog(dstIp); Log("\r\n");
andrewboyson 43:bc028d5a6424 72 }
andrewboyson 43:bc028d5a6424 73 else
andrewboyson 43:bc028d5a6424 74 {
andrewboyson 44:83ce5ace337b 75 Log("IP6 header ");
andrewboyson 47:73af5c0b0dc2 76 IpProtocolLog(protocol);
andrewboyson 43:bc028d5a6424 77 Log(" ");
andrewboyson 47:73af5c0b0dc2 78 Ip6AddressLog(srcIp);
andrewboyson 43:bc028d5a6424 79 Log(" >>> ");
andrewboyson 47:73af5c0b0dc2 80 Ip6AddressLog(dstIp);
andrewboyson 43:bc028d5a6424 81 Log("\r\n");
andrewboyson 43:bc028d5a6424 82 }
andrewboyson 11:c051adb70c5a 83 }
andrewboyson 11:c051adb70c5a 84
andrewboyson 10:f0854784e960 85 static bool getIsSolicited(char* p)
andrewboyson 10:f0854784e960 86 {
andrewboyson 10:f0854784e960 87 if (*p++ != 0xff) return false;
andrewboyson 10:f0854784e960 88 if (*p++ != 0x02) return false;
andrewboyson 10:f0854784e960 89
andrewboyson 10:f0854784e960 90 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 91 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 92
andrewboyson 10:f0854784e960 93 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 94 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 95
andrewboyson 10:f0854784e960 96 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 97 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 98
andrewboyson 10:f0854784e960 99 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 100 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 101
andrewboyson 10:f0854784e960 102 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 103 if (*p++ != 0x01) return false;
andrewboyson 10:f0854784e960 104
andrewboyson 10:f0854784e960 105 if (*p++ != 0xff) return false;
andrewboyson 10:f0854784e960 106
andrewboyson 10:f0854784e960 107 return true;
andrewboyson 10:f0854784e960 108 }
andrewboyson 10:f0854784e960 109 static bool getIsSameGroup(char* pA, char* pB)
andrewboyson 10:f0854784e960 110 {
andrewboyson 10:f0854784e960 111 pA += 13;
andrewboyson 10:f0854784e960 112 pB += 13;
andrewboyson 10:f0854784e960 113 if (*pA++ != *pB++) return false;
andrewboyson 10:f0854784e960 114 if (*pA++ != *pB++) return false;
andrewboyson 10:f0854784e960 115 return *pA == *pB;
andrewboyson 10:f0854784e960 116 }
andrewboyson 37:793b39683406 117 static void (*pTraceBack)(void);
andrewboyson 37:793b39683406 118 static void trace()
andrewboyson 10:f0854784e960 119 {
andrewboyson 37:793b39683406 120 pTraceBack();
andrewboyson 37:793b39683406 121 logHeader();
andrewboyson 37:793b39683406 122 }
andrewboyson 37:793b39683406 123 int Ip6HandleReceivedPacket(void (*traceback)(void), char* pSrcMac, void* pPacket, int* pSize, char* pDstMac)
andrewboyson 37:793b39683406 124 {
andrewboyson 37:793b39683406 125 pTraceBack = traceback;
andrewboyson 37:793b39683406 126
andrewboyson 10:f0854784e960 127 struct header * pHeader = (header*)pPacket;
andrewboyson 11:c051adb70c5a 128 readHeader(pHeader);
andrewboyson 10:f0854784e960 129
andrewboyson 44:83ce5ace337b 130 int scope = SlaacScope(dstIp);
andrewboyson 35:93c39d260a83 131 bool isMulticast = dstIp[0] == 0xFF;
andrewboyson 35:93c39d260a83 132 bool isSolicited = getIsSolicited(dstIp);
andrewboyson 35:93c39d260a83 133 bool isGroup = getIsSameGroup(dstIp, SlaacLinkLocalIp);
andrewboyson 10:f0854784e960 134
andrewboyson 44:83ce5ace337b 135 bool doIt = scope || (isMulticast && !isSolicited) || (isGroup && isSolicited);
andrewboyson 10:f0854784e960 136
andrewboyson 14:e75a59c1123d 137 if (!doIt)
andrewboyson 14:e75a59c1123d 138 {
andrewboyson 48:952dddb74b8b 139 if (Ip6Trace)
andrewboyson 15:6ca6778168b1 140 {
andrewboyson 47:73af5c0b0dc2 141 LogTime("IP6 filtered out ip ");
andrewboyson 47:73af5c0b0dc2 142 Ip6AddressLog(dstIp);
andrewboyson 47:73af5c0b0dc2 143 LogF(" from ");
andrewboyson 47:73af5c0b0dc2 144 Ip6AddressLog(srcIp);
andrewboyson 47:73af5c0b0dc2 145 Log("\r\n");
andrewboyson 15:6ca6778168b1 146 }
andrewboyson 14:e75a59c1123d 147 return DO_NOTHING;
andrewboyson 14:e75a59c1123d 148 }
andrewboyson 10:f0854784e960 149
andrewboyson 48:952dddb74b8b 150 Ar6AddIpRecord(trace, pSrcMac, srcIp);
andrewboyson 50:492f2d2954e4 151 Nr6MakeRequestForNameFromIp(srcIp);
andrewboyson 11:c051adb70c5a 152
andrewboyson 10:f0854784e960 153 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 154 switch (protocol)
andrewboyson 10:f0854784e960 155 {
andrewboyson 44:83ce5ace337b 156 case HOPOPT: action = DO_NOTHING; break;
andrewboyson 44:83ce5ace337b 157 case ICMP6: action = Icmp6HandleReceivedPacket(trace, scope, srcIp, dstIp, &dataLength, pData); break;
andrewboyson 44:83ce5ace337b 158 case UDP: action = Udp6HandleReceivedPacket(trace, scope, srcIp, dstIp, &dataLength, pData); break;
andrewboyson 44:83ce5ace337b 159 case TCP: action = Tcp6HandleReceivedPacket(trace, scope, srcIp, dstIp, &dataLength, pData); break;
andrewboyson 10:f0854784e960 160 default:
andrewboyson 37:793b39683406 161 LogTimeF("IP6 protocol %d unhandled\r\n", protocol);
andrewboyson 10:f0854784e960 162 return DO_NOTHING;
andrewboyson 10:f0854784e960 163 }
andrewboyson 11:c051adb70c5a 164 if (!action) return DO_NOTHING;
andrewboyson 11:c051adb70c5a 165
andrewboyson 53:77f8a49adf89 166 if (NdpIpNeedsToBeRouted(dstIp))
andrewboyson 53:77f8a49adf89 167 {
andrewboyson 53:77f8a49adf89 168 MacCopy(pDstMac, NdpRouterMac); //Send to the router MAC
andrewboyson 53:77f8a49adf89 169 hoplimit = NdpHopLimit;
andrewboyson 53:77f8a49adf89 170 }
andrewboyson 53:77f8a49adf89 171 else
andrewboyson 53:77f8a49adf89 172 {
andrewboyson 53:77f8a49adf89 173 MacCopy(pDstMac, pSrcMac); //Send back to the source
andrewboyson 53:77f8a49adf89 174 hoplimit = 255;
andrewboyson 53:77f8a49adf89 175 }
andrewboyson 53:77f8a49adf89 176
andrewboyson 10:f0854784e960 177
andrewboyson 11:c051adb70c5a 178 writeHeader(pHeader);
andrewboyson 11:c051adb70c5a 179
andrewboyson 10:f0854784e960 180 *pSize = HEADER_LENGTH + dataLength;
andrewboyson 10:f0854784e960 181
andrewboyson 37:793b39683406 182 if (ActionGetTracePart(action)) logHeader();
andrewboyson 37:793b39683406 183
andrewboyson 10:f0854784e960 184 return action;
andrewboyson 10:f0854784e960 185 }
andrewboyson 10:f0854784e960 186 int Ip6PollForPacketToSend(void* pPacket, int* pSize, char* pDstMac)
andrewboyson 10:f0854784e960 187 {
andrewboyson 11:c051adb70c5a 188 pData = (char*)pPacket + HEADER_LENGTH;
andrewboyson 11:c051adb70c5a 189 dataLength = 0;
andrewboyson 11:c051adb70c5a 190 version = 6;
andrewboyson 10:f0854784e960 191
andrewboyson 10:f0854784e960 192 int action = DO_NOTHING;
andrewboyson 47:73af5c0b0dc2 193 if (!action)
andrewboyson 10:f0854784e960 194 {
andrewboyson 35:93c39d260a83 195 action = Icmp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp);
andrewboyson 10:f0854784e960 196 protocol = ICMP6;
andrewboyson 10:f0854784e960 197 }
andrewboyson 10:f0854784e960 198
andrewboyson 47:73af5c0b0dc2 199 if (!action)
andrewboyson 10:f0854784e960 200 {
andrewboyson 35:93c39d260a83 201 action = Udp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp);
andrewboyson 10:f0854784e960 202 protocol = UDP;
andrewboyson 10:f0854784e960 203 }
andrewboyson 11:c051adb70c5a 204 if (!action) return DO_NOTHING;
andrewboyson 37:793b39683406 205
andrewboyson 37:793b39683406 206 int dest = ActionGetDestPart(action);
andrewboyson 37:793b39683406 207 switch (dest)
andrewboyson 11:c051adb70c5a 208 {
andrewboyson 11:c051adb70c5a 209 case UNICAST:
andrewboyson 11:c051adb70c5a 210 case UNICAST_DNS:
andrewboyson 11:c051adb70c5a 211 case UNICAST_DHCP:
andrewboyson 22:914b970356f0 212 case UNICAST_NTP:
andrewboyson 53:77f8a49adf89 213 if (NdpIpNeedsToBeRouted(dstIp))
andrewboyson 53:77f8a49adf89 214 {
andrewboyson 53:77f8a49adf89 215 MacCopy(pDstMac, NdpRouterMac); //Send to the router MAC
andrewboyson 53:77f8a49adf89 216 hoplimit = NdpHopLimit;
andrewboyson 53:77f8a49adf89 217 }
andrewboyson 53:77f8a49adf89 218 else
andrewboyson 53:77f8a49adf89 219 {
andrewboyson 53:77f8a49adf89 220 Ar6IpToMac(dstIp, pDstMac); //Make the remote MAC from NP
andrewboyson 53:77f8a49adf89 221 hoplimit = 255;
andrewboyson 53:77f8a49adf89 222 }
andrewboyson 11:c051adb70c5a 223 break;
andrewboyson 22:914b970356f0 224 case MULTICAST_NODE:
andrewboyson 22:914b970356f0 225 case MULTICAST_ROUTER:
andrewboyson 22:914b970356f0 226 case MULTICAST_MDNS:
andrewboyson 22:914b970356f0 227 case MULTICAST_LLMNR:
andrewboyson 22:914b970356f0 228 case SOLICITED_NODE:
andrewboyson 53:77f8a49adf89 229 hoplimit = 255;
andrewboyson 22:914b970356f0 230 break;
andrewboyson 22:914b970356f0 231 default:
andrewboyson 37:793b39683406 232 LogTimeF("Ip6PollForPacketToSend - undefined destination %d\r\n", dest);
andrewboyson 53:77f8a49adf89 233 return DO_NOTHING;
andrewboyson 11:c051adb70c5a 234 }
andrewboyson 10:f0854784e960 235
andrewboyson 11:c051adb70c5a 236 writeHeader((header*)pPacket);
andrewboyson 11:c051adb70c5a 237
andrewboyson 10:f0854784e960 238 *pSize = HEADER_LENGTH + dataLength;
andrewboyson 10:f0854784e960 239
andrewboyson 37:793b39683406 240 if (ActionGetTracePart(action)) logHeader();
andrewboyson 37:793b39683406 241
andrewboyson 10:f0854784e960 242 return action;
andrewboyson 10:f0854784e960 243 }