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 Jan 03 17:23:38 2019 +0000
Revision:
98:b977424ec7f7
Parent:
97:d91f7db00235
Child:
112:f8694d0b8858
Added more fault positions and removed need for a net server module. Added need for the ethernet jack leds definition.

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 43:bc028d5a6424 4 #include "log.h"
andrewboyson 43:bc028d5a6424 5 #include "net.h"
andrewboyson 43:bc028d5a6424 6 #include "action.h"
andrewboyson 43:bc028d5a6424 7 #include "icmp4.h"
andrewboyson 10:f0854784e960 8 #include "udptcp4.h"
andrewboyson 48:952dddb74b8b 9 #include "ar4.h"
andrewboyson 50:492f2d2954e4 10 #include "nr4.h"
andrewboyson 43:bc028d5a6424 11 #include "dhcp.h"
andrewboyson 43:bc028d5a6424 12 #include "eth.h"
andrewboyson 43:bc028d5a6424 13 #include "ip.h"
andrewboyson 49:1a6336f2b3f9 14 #include "ip4addr.h"
andrewboyson 43:bc028d5a6424 15 #include "ntp.h"
andrewboyson 43:bc028d5a6424 16 #include "mac.h"
andrewboyson 97:d91f7db00235 17 #include "fault.h"
andrewboyson 10:f0854784e960 18
andrewboyson 48:952dddb74b8b 19 bool Ip4Trace = true;
andrewboyson 10:f0854784e960 20
andrewboyson 53:77f8a49adf89 21 #define OFF_LINK_TTL 64
andrewboyson 53:77f8a49adf89 22
andrewboyson 10:f0854784e960 23 __packed struct header
andrewboyson 10:f0854784e960 24 {
andrewboyson 10:f0854784e960 25 uint8_t versionIhl;
andrewboyson 10:f0854784e960 26 uint8_t tos;
andrewboyson 10:f0854784e960 27 uint16_t length;
andrewboyson 10:f0854784e960 28 uint16_t id;
andrewboyson 10:f0854784e960 29 uint16_t flagsOffset;
andrewboyson 10:f0854784e960 30 uint8_t ttl;
andrewboyson 10:f0854784e960 31 uint8_t protocol;
andrewboyson 10:f0854784e960 32 uint16_t checksum;
andrewboyson 10:f0854784e960 33 uint32_t src;
andrewboyson 10:f0854784e960 34 uint32_t dst;
andrewboyson 10:f0854784e960 35 };
andrewboyson 10:f0854784e960 36
andrewboyson 10:f0854784e960 37 //Header variables
andrewboyson 10:f0854784e960 38 static uint8_t version;
andrewboyson 10:f0854784e960 39 static int headerLength;
andrewboyson 10:f0854784e960 40 static uint8_t tos;
andrewboyson 59:e0e556c8bd46 41 static uint16_t totalLength;
andrewboyson 10:f0854784e960 42 static uint16_t id;
andrewboyson 10:f0854784e960 43 static bool dontFragment;
andrewboyson 10:f0854784e960 44 static bool moreFragments;
andrewboyson 10:f0854784e960 45 static uint16_t offset;
andrewboyson 10:f0854784e960 46 static uint8_t ttl;
andrewboyson 10:f0854784e960 47 static uint8_t protocol;
andrewboyson 10:f0854784e960 48 static uint16_t checksum;
andrewboyson 10:f0854784e960 49 static uint16_t calcsum;
andrewboyson 35:93c39d260a83 50 static uint32_t srcIp;
andrewboyson 35:93c39d260a83 51 static uint32_t dstIp;
andrewboyson 10:f0854784e960 52
andrewboyson 59:e0e556c8bd46 53 static void readHeader(struct header * pHeader)
andrewboyson 10:f0854784e960 54 {
andrewboyson 10:f0854784e960 55 version = pHeader->versionIhl >> 4;
andrewboyson 10:f0854784e960 56 uint8_t ihl = pHeader->versionIhl & 0xF;
andrewboyson 10:f0854784e960 57 headerLength = ihl * 4;
andrewboyson 10:f0854784e960 58 tos = pHeader->tos;
andrewboyson 59:e0e556c8bd46 59 totalLength = NetToHost16(pHeader->length);
andrewboyson 10:f0854784e960 60 id = NetToHost16(pHeader->id);
andrewboyson 10:f0854784e960 61 uint16_t flagsOffset = NetToHost16(pHeader->flagsOffset);
andrewboyson 10:f0854784e960 62 dontFragment = flagsOffset & 0x4000;
andrewboyson 10:f0854784e960 63 moreFragments = flagsOffset & 0x8000;
andrewboyson 10:f0854784e960 64 offset = flagsOffset & 0x1FFF;
andrewboyson 10:f0854784e960 65 ttl = pHeader->ttl;
andrewboyson 10:f0854784e960 66 protocol = pHeader->protocol;
andrewboyson 10:f0854784e960 67 checksum = NetToHost16(pHeader->checksum);
andrewboyson 10:f0854784e960 68 calcsum = NetCheckSum(headerLength, pHeader);
andrewboyson 35:93c39d260a83 69 srcIp = pHeader->src;
andrewboyson 35:93c39d260a83 70 dstIp = pHeader->dst;
andrewboyson 10:f0854784e960 71 }
andrewboyson 59:e0e556c8bd46 72 static void writeHeader(struct header * pHeader)
andrewboyson 10:f0854784e960 73 {
andrewboyson 10:f0854784e960 74 uint16_t flagsOffset = offset;
andrewboyson 10:f0854784e960 75 if (dontFragment) flagsOffset |= 0x4000;
andrewboyson 10:f0854784e960 76 if (moreFragments) flagsOffset |= 0x8000;
andrewboyson 10:f0854784e960 77
andrewboyson 10:f0854784e960 78 uint8_t ihl = headerLength >> 2;
andrewboyson 10:f0854784e960 79 pHeader->versionIhl = (version << 4) + ihl;
andrewboyson 10:f0854784e960 80 pHeader->tos = tos;
andrewboyson 10:f0854784e960 81 pHeader->id = NetToHost16(id);
andrewboyson 10:f0854784e960 82 pHeader->flagsOffset = NetToHost16(flagsOffset);
andrewboyson 10:f0854784e960 83 pHeader->ttl = ttl;
andrewboyson 10:f0854784e960 84 pHeader->protocol = protocol;
andrewboyson 10:f0854784e960 85
andrewboyson 35:93c39d260a83 86 pHeader->dst = dstIp;
andrewboyson 35:93c39d260a83 87 pHeader->src = srcIp;
andrewboyson 59:e0e556c8bd46 88 pHeader->length = NetToHost16(totalLength);
andrewboyson 10:f0854784e960 89 pHeader->checksum = 0;
andrewboyson 10:f0854784e960 90 pHeader->checksum = NetCheckSum(headerLength, pHeader);
andrewboyson 10:f0854784e960 91 calcsum = 0;
andrewboyson 10:f0854784e960 92 }
andrewboyson 11:c051adb70c5a 93
andrewboyson 37:793b39683406 94 static void logHeader()
andrewboyson 11:c051adb70c5a 95 {
andrewboyson 43:bc028d5a6424 96 if (NetTraceVerbose)
andrewboyson 43:bc028d5a6424 97 {
andrewboyson 44:83ce5ace337b 98 Log ("IP4 header\r\n");
andrewboyson 43:bc028d5a6424 99 LogF(" Version %d\r\n", version);
andrewboyson 43:bc028d5a6424 100 LogF(" Header length %d\r\n", headerLength);
andrewboyson 43:bc028d5a6424 101 LogF(" Type of service %d\r\n", tos);
andrewboyson 59:e0e556c8bd46 102 LogF(" Total length %d\r\n", totalLength);
andrewboyson 43:bc028d5a6424 103 LogF(" Identification %d\r\n", id);
andrewboyson 43:bc028d5a6424 104 if (dontFragment) LogF(" Don't fragment\r\n");
andrewboyson 43:bc028d5a6424 105 else LogF(" Do fragment\r\n");
andrewboyson 43:bc028d5a6424 106 if (moreFragments) LogF(" More fragments\r\n");
andrewboyson 43:bc028d5a6424 107 else LogF(" No more fragments\r\n");
andrewboyson 43:bc028d5a6424 108 LogF(" Offset %d\r\n", offset);
andrewboyson 43:bc028d5a6424 109 LogF(" Time to live %d\r\n", ttl);
andrewboyson 47:73af5c0b0dc2 110 LogF(" Protocol "); IpProtocolLog(protocol); Log("\r\n");
andrewboyson 43:bc028d5a6424 111 LogF(" Checksum (hex) %04hX\r\n", checksum);
andrewboyson 43:bc028d5a6424 112 LogF(" Calculated (hex) %04hX\r\n", calcsum);
andrewboyson 47:73af5c0b0dc2 113 LogF(" Source IP "); Ip4AddressLog(srcIp); Log("\r\n");
andrewboyson 47:73af5c0b0dc2 114 LogF(" Destination IP "); Ip4AddressLog(dstIp); Log("\r\n");
andrewboyson 43:bc028d5a6424 115 }
andrewboyson 43:bc028d5a6424 116 else
andrewboyson 43:bc028d5a6424 117 {
andrewboyson 44:83ce5ace337b 118 Log ("IP4 header ");
andrewboyson 47:73af5c0b0dc2 119 IpProtocolLog(protocol);
andrewboyson 43:bc028d5a6424 120 Log(" ");
andrewboyson 47:73af5c0b0dc2 121 Ip4AddressLog(srcIp);
andrewboyson 43:bc028d5a6424 122 Log(" >>> ");
andrewboyson 47:73af5c0b0dc2 123 Ip4AddressLog(dstIp);
andrewboyson 43:bc028d5a6424 124 Log("\r\n");
andrewboyson 43:bc028d5a6424 125 }
andrewboyson 11:c051adb70c5a 126 }
andrewboyson 37:793b39683406 127 static void (*pTraceBack)(void);
andrewboyson 37:793b39683406 128 static void trace()
andrewboyson 10:f0854784e960 129 {
andrewboyson 37:793b39683406 130 pTraceBack();
andrewboyson 37:793b39683406 131 logHeader();
andrewboyson 37:793b39683406 132 }
andrewboyson 59:e0e556c8bd46 133 int Ip4HandleReceivedPacket(void (*traceback)(void), void* pPacketRx, int sizeRx, void* pPacketTx, int* pSizeTx, char* macRemote)
andrewboyson 37:793b39683406 134 {
andrewboyson 98:b977424ec7f7 135 int lastFaultPoint = FaultPoint;
andrewboyson 97:d91f7db00235 136 FaultPoint = FAULT_POINT_Ip4HandleReceivedPacket;
andrewboyson 86:55bc5ddac16c 137
andrewboyson 37:793b39683406 138 pTraceBack = traceback;
andrewboyson 61:aad055f1b0d1 139 struct header * pHeaderRx = (struct header*)pPacketRx;
andrewboyson 61:aad055f1b0d1 140 struct header * pHeaderTx = (struct header*)pPacketTx;
andrewboyson 59:e0e556c8bd46 141
andrewboyson 59:e0e556c8bd46 142 char* pDataRx = (char*)pHeaderRx + headerLength;
andrewboyson 59:e0e556c8bd46 143 char* pDataTx = (char*)pHeaderTx + headerLength;
andrewboyson 59:e0e556c8bd46 144
andrewboyson 59:e0e556c8bd46 145 readHeader(pHeaderRx);
andrewboyson 59:e0e556c8bd46 146 if (totalLength < sizeRx) sizeRx = totalLength;
andrewboyson 59:e0e556c8bd46 147 int dataLengthRx = sizeRx - headerLength;
andrewboyson 61:aad055f1b0d1 148 int dataLengthTx = *pSizeTx - sizeof(struct header);
andrewboyson 10:f0854784e960 149
andrewboyson 61:aad055f1b0d1 150 bool isMe = dstIp == DhcpLocalIp;
andrewboyson 61:aad055f1b0d1 151 bool isLocalBroadcast = dstIp == (DhcpLocalIp | 0xFF000000); // dstIp == 192.168.1.255; '|' is lower precendence than '=='
andrewboyson 61:aad055f1b0d1 152 bool isBroadcast = dstIp == IP4_BROADCAST_ADDRESS; // dstIp == 255.255.255.255
andrewboyson 37:793b39683406 153 bool isMulticast = (dstIp & 0xE0) == 0xE0; //224.x.x.x == 1110 0000 == E0.xx.xx.xx == xx.xx.xx.E0 in little endian
andrewboyson 10:f0854784e960 154
andrewboyson 15:6ca6778168b1 155 bool doIt = isMe || isLocalBroadcast || isBroadcast || isMulticast;
andrewboyson 15:6ca6778168b1 156 if (!doIt)
andrewboyson 15:6ca6778168b1 157 {
andrewboyson 48:952dddb74b8b 158 if (Ip4Trace);
andrewboyson 15:6ca6778168b1 159 {
andrewboyson 47:73af5c0b0dc2 160 LogTimeF("IP4 filtered out ip "); Ip4AddressLog(dstIp);
andrewboyson 47:73af5c0b0dc2 161 Log(" from ");
andrewboyson 47:73af5c0b0dc2 162 Ip4AddressLog(srcIp);
andrewboyson 47:73af5c0b0dc2 163 Log("\r\n");
andrewboyson 15:6ca6778168b1 164 }
andrewboyson 98:b977424ec7f7 165 FaultPoint = lastFaultPoint;
andrewboyson 15:6ca6778168b1 166 return DO_NOTHING;
andrewboyson 15:6ca6778168b1 167 }
andrewboyson 10:f0854784e960 168
andrewboyson 74:c3756bfa960e 169 int remArIndex = Ar4AddIpRecord(trace, macRemote, srcIp);
andrewboyson 71:736a5747ade1 170 Nr4MakeRequestForNameFromIp(srcIp);
andrewboyson 59:e0e556c8bd46 171
andrewboyson 10:f0854784e960 172 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 173 switch (protocol)
andrewboyson 10:f0854784e960 174 {
andrewboyson 97:d91f7db00235 175 case ICMP: action = Icmp4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, &srcIp, &dstIp); break;
andrewboyson 97:d91f7db00235 176 case IGMP: break;
andrewboyson 97:d91f7db00235 177 case UDP: action = Udp4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, &srcIp, &dstIp); break;
andrewboyson 74:c3756bfa960e 178 case TCP: action = Tcp4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, &srcIp, &dstIp, remArIndex); break;
andrewboyson 97:d91f7db00235 179 case IP6IN4: break;
andrewboyson 10:f0854784e960 180 default:
andrewboyson 37:793b39683406 181 LogTimeF("IP4 received packet unknown protocol %d\r\n");
andrewboyson 98:b977424ec7f7 182 FaultPoint = lastFaultPoint;
andrewboyson 10:f0854784e960 183 return DO_NOTHING;
andrewboyson 10:f0854784e960 184 }
andrewboyson 86:55bc5ddac16c 185 if (!action)
andrewboyson 86:55bc5ddac16c 186 {
andrewboyson 98:b977424ec7f7 187 FaultPoint = lastFaultPoint;
andrewboyson 86:55bc5ddac16c 188 return DO_NOTHING;
andrewboyson 86:55bc5ddac16c 189 }
andrewboyson 10:f0854784e960 190
andrewboyson 53:77f8a49adf89 191 if (DhcpIpNeedsToBeRouted(dstIp))
andrewboyson 53:77f8a49adf89 192 {
andrewboyson 59:e0e556c8bd46 193 Ar4IpToMac(DhcpRouter, macRemote); //Send back to the router
andrewboyson 53:77f8a49adf89 194 ttl = OFF_LINK_TTL;
andrewboyson 53:77f8a49adf89 195 }
andrewboyson 53:77f8a49adf89 196 else
andrewboyson 53:77f8a49adf89 197 {
andrewboyson 53:77f8a49adf89 198 ttl = 255;
andrewboyson 53:77f8a49adf89 199 }
andrewboyson 59:e0e556c8bd46 200
andrewboyson 61:aad055f1b0d1 201 totalLength = sizeof(struct header) + dataLengthTx;
andrewboyson 61:aad055f1b0d1 202 headerLength = sizeof(struct header);
andrewboyson 59:e0e556c8bd46 203
andrewboyson 59:e0e556c8bd46 204 writeHeader(pHeaderTx);
andrewboyson 53:77f8a49adf89 205
andrewboyson 59:e0e556c8bd46 206 *pSizeTx = totalLength;
andrewboyson 10:f0854784e960 207
andrewboyson 37:793b39683406 208 if (ActionGetTracePart(action)) logHeader();
andrewboyson 37:793b39683406 209
andrewboyson 98:b977424ec7f7 210 FaultPoint = lastFaultPoint;
andrewboyson 10:f0854784e960 211 return action;
andrewboyson 10:f0854784e960 212 }
andrewboyson 10:f0854784e960 213 int Ip4PollForPacketToSend(void* pPacket, int* pSize, char* pDstMac)
andrewboyson 59:e0e556c8bd46 214 {
andrewboyson 61:aad055f1b0d1 215 headerLength = sizeof(struct header);
andrewboyson 59:e0e556c8bd46 216 char* pData = (char*)pPacket + headerLength;
andrewboyson 10:f0854784e960 217 version = 4;
andrewboyson 10:f0854784e960 218 tos = 0;
andrewboyson 10:f0854784e960 219 id = 0;
andrewboyson 10:f0854784e960 220 dontFragment = true;
andrewboyson 10:f0854784e960 221 moreFragments = false;
andrewboyson 10:f0854784e960 222 offset = 0;
andrewboyson 10:f0854784e960 223
andrewboyson 61:aad055f1b0d1 224 int dataLength = *pSize - sizeof(struct header);
andrewboyson 59:e0e556c8bd46 225
andrewboyson 11:c051adb70c5a 226 int action = DO_NOTHING;
andrewboyson 71:736a5747ade1 227 if (!action) { action = Udp4PollForPacketToSend(pData, &dataLength, &srcIp, &dstIp); protocol = UDP; }
andrewboyson 71:736a5747ade1 228 if (!action) { action = Tcp4PollForPacketToSend(pData, &dataLength, &srcIp, &dstIp); protocol = TCP; }
andrewboyson 11:c051adb70c5a 229 if (!action) return DO_NOTHING;
andrewboyson 42:222a4f45f916 230 int dest = ActionGetDestPart(action);
andrewboyson 42:222a4f45f916 231 switch (dest)
andrewboyson 11:c051adb70c5a 232 {
andrewboyson 11:c051adb70c5a 233 case UNICAST:
andrewboyson 11:c051adb70c5a 234 case UNICAST_DNS:
andrewboyson 11:c051adb70c5a 235 case UNICAST_DHCP:
andrewboyson 22:914b970356f0 236 case UNICAST_NTP:
andrewboyson 57:e0fb648acf48 237 case UNICAST_TFTP:
andrewboyson 53:77f8a49adf89 238 if (DhcpIpNeedsToBeRouted(dstIp))
andrewboyson 53:77f8a49adf89 239 {
andrewboyson 53:77f8a49adf89 240 Ar4IpToMac(DhcpRouter, pDstMac); //send via router
andrewboyson 53:77f8a49adf89 241 ttl = OFF_LINK_TTL;
andrewboyson 53:77f8a49adf89 242 }
andrewboyson 53:77f8a49adf89 243 else
andrewboyson 53:77f8a49adf89 244 {
andrewboyson 53:77f8a49adf89 245 Ar4IpToMac(dstIp, pDstMac); //Send direct
andrewboyson 53:77f8a49adf89 246 ttl = 255;
andrewboyson 53:77f8a49adf89 247 }
andrewboyson 11:c051adb70c5a 248 break;
andrewboyson 42:222a4f45f916 249 case MULTICAST_NODE:
andrewboyson 42:222a4f45f916 250 case MULTICAST_ROUTER:
andrewboyson 42:222a4f45f916 251 case MULTICAST_MDNS:
andrewboyson 42:222a4f45f916 252 case MULTICAST_LLMNR:
andrewboyson 22:914b970356f0 253 case BROADCAST:
andrewboyson 53:77f8a49adf89 254 ttl = 255;
andrewboyson 22:914b970356f0 255 break;
andrewboyson 22:914b970356f0 256 default:
andrewboyson 42:222a4f45f916 257 LogTimeF("Ip4PollForPacketToSend - undefined destination %d\r\n", dest);
andrewboyson 53:77f8a49adf89 258 return DO_NOTHING;
andrewboyson 11:c051adb70c5a 259 }
andrewboyson 10:f0854784e960 260
andrewboyson 59:e0e556c8bd46 261 struct header* pHeader = (struct header*)pPacket;
andrewboyson 59:e0e556c8bd46 262
andrewboyson 61:aad055f1b0d1 263 totalLength = sizeof(struct header) + dataLength;
andrewboyson 61:aad055f1b0d1 264 headerLength = sizeof(struct header);
andrewboyson 59:e0e556c8bd46 265
andrewboyson 59:e0e556c8bd46 266 writeHeader(pHeader);
andrewboyson 10:f0854784e960 267
andrewboyson 59:e0e556c8bd46 268 *pSize = totalLength;
andrewboyson 10:f0854784e960 269
andrewboyson 37:793b39683406 270 if (ActionGetTracePart(action)) logHeader();
andrewboyson 37:793b39683406 271
andrewboyson 10:f0854784e960 272 return action;
andrewboyson 10:f0854784e960 273 }