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:
Tue Nov 28 17:05:46 2017 +0000
Revision:
57:e0fb648acf48
Parent:
53:77f8a49adf89
Child:
59:e0e556c8bd46
Added TFTP

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 57:e0fb648acf48 150 NetTraceHostCheckIp6(srcIp);
andrewboyson 57:e0fb648acf48 151
andrewboyson 48:952dddb74b8b 152 Ar6AddIpRecord(trace, pSrcMac, srcIp);
andrewboyson 50:492f2d2954e4 153 Nr6MakeRequestForNameFromIp(srcIp);
andrewboyson 11:c051adb70c5a 154
andrewboyson 10:f0854784e960 155 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 156 switch (protocol)
andrewboyson 10:f0854784e960 157 {
andrewboyson 44:83ce5ace337b 158 case HOPOPT: action = DO_NOTHING; break;
andrewboyson 44:83ce5ace337b 159 case ICMP6: action = Icmp6HandleReceivedPacket(trace, scope, srcIp, dstIp, &dataLength, pData); break;
andrewboyson 44:83ce5ace337b 160 case UDP: action = Udp6HandleReceivedPacket(trace, scope, srcIp, dstIp, &dataLength, pData); break;
andrewboyson 44:83ce5ace337b 161 case TCP: action = Tcp6HandleReceivedPacket(trace, scope, srcIp, dstIp, &dataLength, pData); break;
andrewboyson 10:f0854784e960 162 default:
andrewboyson 37:793b39683406 163 LogTimeF("IP6 protocol %d unhandled\r\n", protocol);
andrewboyson 10:f0854784e960 164 return DO_NOTHING;
andrewboyson 10:f0854784e960 165 }
andrewboyson 11:c051adb70c5a 166 if (!action) return DO_NOTHING;
andrewboyson 11:c051adb70c5a 167
andrewboyson 53:77f8a49adf89 168 if (NdpIpNeedsToBeRouted(dstIp))
andrewboyson 53:77f8a49adf89 169 {
andrewboyson 53:77f8a49adf89 170 MacCopy(pDstMac, NdpRouterMac); //Send to the router MAC
andrewboyson 53:77f8a49adf89 171 hoplimit = NdpHopLimit;
andrewboyson 53:77f8a49adf89 172 }
andrewboyson 53:77f8a49adf89 173 else
andrewboyson 53:77f8a49adf89 174 {
andrewboyson 53:77f8a49adf89 175 MacCopy(pDstMac, pSrcMac); //Send back to the source
andrewboyson 53:77f8a49adf89 176 hoplimit = 255;
andrewboyson 53:77f8a49adf89 177 }
andrewboyson 53:77f8a49adf89 178
andrewboyson 10:f0854784e960 179
andrewboyson 11:c051adb70c5a 180 writeHeader(pHeader);
andrewboyson 11:c051adb70c5a 181
andrewboyson 10:f0854784e960 182 *pSize = HEADER_LENGTH + dataLength;
andrewboyson 10:f0854784e960 183
andrewboyson 37:793b39683406 184 if (ActionGetTracePart(action)) logHeader();
andrewboyson 37:793b39683406 185
andrewboyson 10:f0854784e960 186 return action;
andrewboyson 10:f0854784e960 187 }
andrewboyson 10:f0854784e960 188 int Ip6PollForPacketToSend(void* pPacket, int* pSize, char* pDstMac)
andrewboyson 10:f0854784e960 189 {
andrewboyson 11:c051adb70c5a 190 pData = (char*)pPacket + HEADER_LENGTH;
andrewboyson 11:c051adb70c5a 191 dataLength = 0;
andrewboyson 11:c051adb70c5a 192 version = 6;
andrewboyson 10:f0854784e960 193
andrewboyson 10:f0854784e960 194 int action = DO_NOTHING;
andrewboyson 47:73af5c0b0dc2 195 if (!action)
andrewboyson 10:f0854784e960 196 {
andrewboyson 35:93c39d260a83 197 action = Icmp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp);
andrewboyson 10:f0854784e960 198 protocol = ICMP6;
andrewboyson 10:f0854784e960 199 }
andrewboyson 10:f0854784e960 200
andrewboyson 47:73af5c0b0dc2 201 if (!action)
andrewboyson 10:f0854784e960 202 {
andrewboyson 35:93c39d260a83 203 action = Udp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp);
andrewboyson 10:f0854784e960 204 protocol = UDP;
andrewboyson 10:f0854784e960 205 }
andrewboyson 11:c051adb70c5a 206 if (!action) return DO_NOTHING;
andrewboyson 37:793b39683406 207
andrewboyson 37:793b39683406 208 int dest = ActionGetDestPart(action);
andrewboyson 37:793b39683406 209 switch (dest)
andrewboyson 11:c051adb70c5a 210 {
andrewboyson 11:c051adb70c5a 211 case UNICAST:
andrewboyson 11:c051adb70c5a 212 case UNICAST_DNS:
andrewboyson 11:c051adb70c5a 213 case UNICAST_DHCP:
andrewboyson 22:914b970356f0 214 case UNICAST_NTP:
andrewboyson 57:e0fb648acf48 215 case UNICAST_TFTP:
andrewboyson 53:77f8a49adf89 216 if (NdpIpNeedsToBeRouted(dstIp))
andrewboyson 53:77f8a49adf89 217 {
andrewboyson 53:77f8a49adf89 218 MacCopy(pDstMac, NdpRouterMac); //Send to the router MAC
andrewboyson 53:77f8a49adf89 219 hoplimit = NdpHopLimit;
andrewboyson 53:77f8a49adf89 220 }
andrewboyson 53:77f8a49adf89 221 else
andrewboyson 53:77f8a49adf89 222 {
andrewboyson 53:77f8a49adf89 223 Ar6IpToMac(dstIp, pDstMac); //Make the remote MAC from NP
andrewboyson 53:77f8a49adf89 224 hoplimit = 255;
andrewboyson 53:77f8a49adf89 225 }
andrewboyson 11:c051adb70c5a 226 break;
andrewboyson 22:914b970356f0 227 case MULTICAST_NODE:
andrewboyson 22:914b970356f0 228 case MULTICAST_ROUTER:
andrewboyson 22:914b970356f0 229 case MULTICAST_MDNS:
andrewboyson 22:914b970356f0 230 case MULTICAST_LLMNR:
andrewboyson 22:914b970356f0 231 case SOLICITED_NODE:
andrewboyson 53:77f8a49adf89 232 hoplimit = 255;
andrewboyson 22:914b970356f0 233 break;
andrewboyson 22:914b970356f0 234 default:
andrewboyson 37:793b39683406 235 LogTimeF("Ip6PollForPacketToSend - undefined destination %d\r\n", dest);
andrewboyson 53:77f8a49adf89 236 return DO_NOTHING;
andrewboyson 11:c051adb70c5a 237 }
andrewboyson 10:f0854784e960 238
andrewboyson 11:c051adb70c5a 239 writeHeader((header*)pPacket);
andrewboyson 11:c051adb70c5a 240
andrewboyson 10:f0854784e960 241 *pSize = HEADER_LENGTH + dataLength;
andrewboyson 10:f0854784e960 242
andrewboyson 37:793b39683406 243 if (ActionGetTracePart(action)) logHeader();
andrewboyson 37:793b39683406 244
andrewboyson 10:f0854784e960 245 return action;
andrewboyson 10:f0854784e960 246 }