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:
Mon Oct 29 09:33:44 2018 +0000
Revision:
74:c3756bfa960e
Parent:
71:736a5747ade1
Child:
112:f8694d0b8858
Introduced the polling for and split Tcp into tcpSend and TcpRecv. Testied and working.

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