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:
Wed Apr 10 10:07:06 2019 +0000
Revision:
140:9000ea70b220
Parent:
136:8a65abb0dc63
Child:
142:a8c0890a58d1
Added ajax functions to AR4, AR6, NR4, NR6 modules

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 136:8a65abb0dc63 1
andrewboyson 61:aad055f1b0d1 2 #include <stdint.h>
andrewboyson 61:aad055f1b0d1 3 #include <stdbool.h>
andrewboyson 61:aad055f1b0d1 4
andrewboyson 43:bc028d5a6424 5 #include "log.h"
andrewboyson 43:bc028d5a6424 6 #include "net.h"
andrewboyson 43:bc028d5a6424 7 #include "action.h"
andrewboyson 43:bc028d5a6424 8 #include "icmp4.h"
andrewboyson 10:f0854784e960 9 #include "udptcp4.h"
andrewboyson 48:952dddb74b8b 10 #include "ar4.h"
andrewboyson 50:492f2d2954e4 11 #include "nr4.h"
andrewboyson 43:bc028d5a6424 12 #include "dhcp.h"
andrewboyson 43:bc028d5a6424 13 #include "eth.h"
andrewboyson 43:bc028d5a6424 14 #include "ip.h"
andrewboyson 49:1a6336f2b3f9 15 #include "ip4addr.h"
andrewboyson 136:8a65abb0dc63 16 #include "ip4hdr.h"
andrewboyson 43:bc028d5a6424 17 #include "ntp.h"
andrewboyson 43:bc028d5a6424 18 #include "mac.h"
andrewboyson 97:d91f7db00235 19 #include "fault.h"
andrewboyson 136:8a65abb0dc63 20 #include "checksum.h"
andrewboyson 10:f0854784e960 21
andrewboyson 48:952dddb74b8b 22 bool Ip4Trace = true;
andrewboyson 10:f0854784e960 23
andrewboyson 53:77f8a49adf89 24 #define OFF_LINK_TTL 64
andrewboyson 53:77f8a49adf89 25
andrewboyson 136:8a65abb0dc63 26 static void logHeader(char* pPacket)
andrewboyson 11:c051adb70c5a 27 {
andrewboyson 43:bc028d5a6424 28 if (NetTraceVerbose)
andrewboyson 43:bc028d5a6424 29 {
andrewboyson 44:83ce5ace337b 30 Log ("IP4 header\r\n");
andrewboyson 136:8a65abb0dc63 31 LogF(" Version %d\r\n", Ip4HdrGetVersion (pPacket));
andrewboyson 136:8a65abb0dc63 32 int headerLength = Ip4HdrGetHeaderLen (pPacket);
andrewboyson 43:bc028d5a6424 33 LogF(" Header length %d\r\n", headerLength);
andrewboyson 136:8a65abb0dc63 34 LogF(" Type of service %d\r\n", Ip4HdrGetTos (pPacket));
andrewboyson 136:8a65abb0dc63 35 LogF(" Total length %d\r\n", Ip4HdrGetLength (pPacket));
andrewboyson 136:8a65abb0dc63 36 LogF(" Identification %d\r\n", Ip4HdrGetId (pPacket));
andrewboyson 136:8a65abb0dc63 37 if (Ip4HdrGetDontFrag(pPacket)) LogF(" Don't fragment\r\n");
andrewboyson 136:8a65abb0dc63 38 else LogF(" Do fragment\r\n");
andrewboyson 136:8a65abb0dc63 39 if (Ip4HdrGetMoreFrags(pPacket)) LogF(" More fragments\r\n");
andrewboyson 136:8a65abb0dc63 40 else LogF(" No more fragments\r\n");
andrewboyson 136:8a65abb0dc63 41 LogF(" Frag offset %d\r\n", Ip4HdrGetFragOffset(pPacket));
andrewboyson 136:8a65abb0dc63 42 LogF(" Time to live %d\r\n", Ip4HdrGetTtl (pPacket));
andrewboyson 136:8a65abb0dc63 43 LogF(" Protocol "); IpProtocolLog(Ip4HdrGetProtocol(pPacket)); Log("\r\n");
andrewboyson 136:8a65abb0dc63 44 LogF(" Checksum (hex) %04hX\r\n", Ip4HdrGetChecksum(pPacket));
andrewboyson 136:8a65abb0dc63 45 LogF(" Calculated (hex) %04hX\r\n", CheckSum(headerLength, pPacket));
andrewboyson 136:8a65abb0dc63 46 LogF(" Source IP "); Ip4AddressLog(Ip4HdrGetSrc(pPacket)); Log("\r\n");
andrewboyson 136:8a65abb0dc63 47 LogF(" Destination IP "); Ip4AddressLog(Ip4HdrGetDst(pPacket)); Log("\r\n");
andrewboyson 43:bc028d5a6424 48 }
andrewboyson 43:bc028d5a6424 49 else
andrewboyson 43:bc028d5a6424 50 {
andrewboyson 44:83ce5ace337b 51 Log ("IP4 header ");
andrewboyson 136:8a65abb0dc63 52 IpProtocolLog(Ip4HdrGetProtocol(pPacket));
andrewboyson 43:bc028d5a6424 53 Log(" ");
andrewboyson 136:8a65abb0dc63 54 Ip4AddressLog(Ip4HdrGetSrc(pPacket));
andrewboyson 43:bc028d5a6424 55 Log(" >>> ");
andrewboyson 136:8a65abb0dc63 56 Ip4AddressLog(Ip4HdrGetDst(pPacket));
andrewboyson 43:bc028d5a6424 57 Log("\r\n");
andrewboyson 43:bc028d5a6424 58 }
andrewboyson 11:c051adb70c5a 59 }
andrewboyson 136:8a65abb0dc63 60 static void makeHeader(char* pPacket, uint16_t totalLength, uint8_t ttl, uint8_t protocol, uint32_t srcIp, uint32_t dstIp)
andrewboyson 136:8a65abb0dc63 61 {
andrewboyson 136:8a65abb0dc63 62 static uint16_t id = 0;
andrewboyson 136:8a65abb0dc63 63 Ip4HdrSetVersion (pPacket, 4 );
andrewboyson 136:8a65abb0dc63 64 Ip4HdrSetHeaderLen(pPacket, IP4_HEADER_LENGTH);
andrewboyson 136:8a65abb0dc63 65 Ip4HdrSetTos (pPacket, 0 );
andrewboyson 136:8a65abb0dc63 66 Ip4HdrSetLength (pPacket, totalLength );
andrewboyson 136:8a65abb0dc63 67 Ip4HdrSetId (pPacket, id++ ); //Used by the recipient for collating packets fragmented in transit; unique per packet sent
andrewboyson 136:8a65abb0dc63 68 Ip4HdrSetFragInfo (pPacket, 0 ); //No flags and no offset
andrewboyson 136:8a65abb0dc63 69 Ip4HdrSetTtl (pPacket, ttl );
andrewboyson 136:8a65abb0dc63 70 Ip4HdrSetProtocol (pPacket, protocol );
andrewboyson 136:8a65abb0dc63 71 Ip4HdrSetSrc (pPacket, srcIp );
andrewboyson 136:8a65abb0dc63 72 Ip4HdrSetDst (pPacket, dstIp );
andrewboyson 136:8a65abb0dc63 73 Ip4HdrSetChecksum (pPacket, 0 );
andrewboyson 136:8a65abb0dc63 74 uint16_t checksum = CheckSum(IP4_HEADER_LENGTH, pPacket);
andrewboyson 136:8a65abb0dc63 75 Ip4HdrSetChecksum (pPacket, checksum );
andrewboyson 136:8a65abb0dc63 76 }
andrewboyson 136:8a65abb0dc63 77 static char* traceHeader;
andrewboyson 37:793b39683406 78 static void (*pTraceBack)(void);
andrewboyson 37:793b39683406 79 static void trace()
andrewboyson 10:f0854784e960 80 {
andrewboyson 37:793b39683406 81 pTraceBack();
andrewboyson 136:8a65abb0dc63 82 logHeader(traceHeader);
andrewboyson 37:793b39683406 83 }
andrewboyson 136:8a65abb0dc63 84
andrewboyson 136:8a65abb0dc63 85 int Ip4HandleReceivedPacket(void (*traceback)(void), char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx, char* macRemote)
andrewboyson 37:793b39683406 86 {
andrewboyson 98:b977424ec7f7 87 int lastFaultPoint = FaultPoint;
andrewboyson 97:d91f7db00235 88 FaultPoint = FAULT_POINT_Ip4HandleReceivedPacket;
andrewboyson 136:8a65abb0dc63 89
andrewboyson 136:8a65abb0dc63 90 traceHeader = pPacketRx;
andrewboyson 37:793b39683406 91 pTraceBack = traceback;
andrewboyson 136:8a65abb0dc63 92
andrewboyson 136:8a65abb0dc63 93 int headerLengthRx = Ip4HdrGetHeaderLen(pPacketRx);
andrewboyson 136:8a65abb0dc63 94 uint16_t totalLengthRx = Ip4HdrGetLength (pPacketRx);
andrewboyson 136:8a65abb0dc63 95 uint8_t protocol = Ip4HdrGetProtocol (pPacketRx);
andrewboyson 136:8a65abb0dc63 96 uint32_t srcIp = Ip4HdrGetSrc (pPacketRx);
andrewboyson 136:8a65abb0dc63 97 uint32_t dstIp = Ip4HdrGetDst (pPacketRx);
andrewboyson 59:e0e556c8bd46 98
andrewboyson 136:8a65abb0dc63 99 char* pDataRx = pPacketRx + headerLengthRx;
andrewboyson 136:8a65abb0dc63 100 char* pDataTx = pPacketTx + IP4_HEADER_LENGTH;
andrewboyson 136:8a65abb0dc63 101
andrewboyson 136:8a65abb0dc63 102 if (sizeRx > totalLengthRx) sizeRx = totalLengthRx;
andrewboyson 136:8a65abb0dc63 103 int dataLengthRx = sizeRx - headerLengthRx;
andrewboyson 136:8a65abb0dc63 104 int dataLengthTx = *pSizeTx - IP4_HEADER_LENGTH;
andrewboyson 136:8a65abb0dc63 105
andrewboyson 61:aad055f1b0d1 106 bool isMe = dstIp == DhcpLocalIp;
andrewboyson 61:aad055f1b0d1 107 bool isLocalBroadcast = dstIp == (DhcpLocalIp | 0xFF000000); // dstIp == 192.168.1.255; '|' is lower precendence than '=='
andrewboyson 61:aad055f1b0d1 108 bool isBroadcast = dstIp == IP4_BROADCAST_ADDRESS; // dstIp == 255.255.255.255
andrewboyson 136:8a65abb0dc63 109 bool isMulticast = (dstIp & 0xE0) == 0xE0; // 224.x.x.x == 1110 0000 == E0.xx.xx.xx == xx.xx.xx.E0 in little endian
andrewboyson 136:8a65abb0dc63 110
andrewboyson 15:6ca6778168b1 111 bool doIt = isMe || isLocalBroadcast || isBroadcast || isMulticast;
andrewboyson 15:6ca6778168b1 112 if (!doIt)
andrewboyson 15:6ca6778168b1 113 {
andrewboyson 48:952dddb74b8b 114 if (Ip4Trace);
andrewboyson 15:6ca6778168b1 115 {
andrewboyson 136:8a65abb0dc63 116 LogTimeF("IP4 filtered out ip "); Ip4AddressLog(dstIp);
andrewboyson 47:73af5c0b0dc2 117 Log(" from ");
andrewboyson 47:73af5c0b0dc2 118 Ip4AddressLog(srcIp);
andrewboyson 47:73af5c0b0dc2 119 Log("\r\n");
andrewboyson 15:6ca6778168b1 120 }
andrewboyson 98:b977424ec7f7 121 FaultPoint = lastFaultPoint;
andrewboyson 15:6ca6778168b1 122 return DO_NOTHING;
andrewboyson 15:6ca6778168b1 123 }
andrewboyson 136:8a65abb0dc63 124
andrewboyson 74:c3756bfa960e 125 int remArIndex = Ar4AddIpRecord(trace, macRemote, srcIp);
andrewboyson 71:736a5747ade1 126 Nr4MakeRequestForNameFromIp(srcIp);
andrewboyson 136:8a65abb0dc63 127
andrewboyson 10:f0854784e960 128 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 129 switch (protocol)
andrewboyson 10:f0854784e960 130 {
andrewboyson 97:d91f7db00235 131 case ICMP: action = Icmp4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, &srcIp, &dstIp); break;
andrewboyson 97:d91f7db00235 132 case IGMP: break;
andrewboyson 97:d91f7db00235 133 case UDP: action = Udp4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, &srcIp, &dstIp); break;
andrewboyson 74:c3756bfa960e 134 case TCP: action = Tcp4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, &srcIp, &dstIp, remArIndex); break;
andrewboyson 97:d91f7db00235 135 case IP6IN4: break;
andrewboyson 10:f0854784e960 136 default:
andrewboyson 136:8a65abb0dc63 137 LogTimeF("IP4 received packet unknown protocol %d\r\n", protocol);
andrewboyson 98:b977424ec7f7 138 FaultPoint = lastFaultPoint;
andrewboyson 10:f0854784e960 139 return DO_NOTHING;
andrewboyson 10:f0854784e960 140 }
andrewboyson 86:55bc5ddac16c 141 if (!action)
andrewboyson 86:55bc5ddac16c 142 {
andrewboyson 98:b977424ec7f7 143 FaultPoint = lastFaultPoint;
andrewboyson 86:55bc5ddac16c 144 return DO_NOTHING;
andrewboyson 86:55bc5ddac16c 145 }
andrewboyson 136:8a65abb0dc63 146
andrewboyson 136:8a65abb0dc63 147 uint8_t ttl = 0;
andrewboyson 53:77f8a49adf89 148 if (DhcpIpNeedsToBeRouted(dstIp))
andrewboyson 53:77f8a49adf89 149 {
andrewboyson 116:60521b29e4c9 150 Ar4IpToMac(DhcpRouterIp, macRemote); //Send back to the router
andrewboyson 53:77f8a49adf89 151 ttl = OFF_LINK_TTL;
andrewboyson 53:77f8a49adf89 152 }
andrewboyson 53:77f8a49adf89 153 else
andrewboyson 53:77f8a49adf89 154 {
andrewboyson 53:77f8a49adf89 155 ttl = 255;
andrewboyson 53:77f8a49adf89 156 }
andrewboyson 59:e0e556c8bd46 157
andrewboyson 136:8a65abb0dc63 158 *pSizeTx = IP4_HEADER_LENGTH + dataLengthTx;
andrewboyson 53:77f8a49adf89 159
andrewboyson 136:8a65abb0dc63 160 makeHeader(pPacketTx, *pSizeTx, ttl, protocol, srcIp, dstIp);
andrewboyson 10:f0854784e960 161
andrewboyson 136:8a65abb0dc63 162 if (ActionGetTracePart(action)) logHeader(pPacketTx);
andrewboyson 37:793b39683406 163
andrewboyson 98:b977424ec7f7 164 FaultPoint = lastFaultPoint;
andrewboyson 10:f0854784e960 165 return action;
andrewboyson 10:f0854784e960 166 }
andrewboyson 136:8a65abb0dc63 167 int Ip4PollForPacketToSend(char* pPacket, int* pSize, char* pDstMac)
andrewboyson 136:8a65abb0dc63 168 {
andrewboyson 136:8a65abb0dc63 169 char* pData = pPacket + IP4_HEADER_LENGTH;
andrewboyson 136:8a65abb0dc63 170 int dataLength = *pSize - IP4_HEADER_LENGTH;
andrewboyson 136:8a65abb0dc63 171
andrewboyson 136:8a65abb0dc63 172 uint8_t protocol = 0;
andrewboyson 136:8a65abb0dc63 173 uint32_t srcIp = 0;
andrewboyson 136:8a65abb0dc63 174 uint32_t dstIp = 0;
andrewboyson 136:8a65abb0dc63 175 int action = DO_NOTHING;
andrewboyson 71:736a5747ade1 176 if (!action) { action = Udp4PollForPacketToSend(pData, &dataLength, &srcIp, &dstIp); protocol = UDP; }
andrewboyson 71:736a5747ade1 177 if (!action) { action = Tcp4PollForPacketToSend(pData, &dataLength, &srcIp, &dstIp); protocol = TCP; }
andrewboyson 11:c051adb70c5a 178 if (!action) return DO_NOTHING;
andrewboyson 42:222a4f45f916 179 int dest = ActionGetDestPart(action);
andrewboyson 136:8a65abb0dc63 180 uint8_t ttl = 0;
andrewboyson 42:222a4f45f916 181 switch (dest)
andrewboyson 11:c051adb70c5a 182 {
andrewboyson 11:c051adb70c5a 183 case UNICAST:
andrewboyson 11:c051adb70c5a 184 case UNICAST_DNS:
andrewboyson 11:c051adb70c5a 185 case UNICAST_DHCP:
andrewboyson 22:914b970356f0 186 case UNICAST_NTP:
andrewboyson 57:e0fb648acf48 187 case UNICAST_TFTP:
andrewboyson 53:77f8a49adf89 188 if (DhcpIpNeedsToBeRouted(dstIp))
andrewboyson 53:77f8a49adf89 189 {
andrewboyson 116:60521b29e4c9 190 Ar4IpToMac(DhcpRouterIp, pDstMac); //send via router
andrewboyson 53:77f8a49adf89 191 ttl = OFF_LINK_TTL;
andrewboyson 53:77f8a49adf89 192 }
andrewboyson 53:77f8a49adf89 193 else
andrewboyson 53:77f8a49adf89 194 {
andrewboyson 116:60521b29e4c9 195 Ar4IpToMac(dstIp, pDstMac); //Send direct
andrewboyson 53:77f8a49adf89 196 ttl = 255;
andrewboyson 53:77f8a49adf89 197 }
andrewboyson 11:c051adb70c5a 198 break;
andrewboyson 42:222a4f45f916 199 case MULTICAST_NODE:
andrewboyson 42:222a4f45f916 200 case MULTICAST_ROUTER:
andrewboyson 42:222a4f45f916 201 case MULTICAST_MDNS:
andrewboyson 42:222a4f45f916 202 case MULTICAST_LLMNR:
andrewboyson 112:f8694d0b8858 203 case MULTICAST_NTP:
andrewboyson 22:914b970356f0 204 case BROADCAST:
andrewboyson 53:77f8a49adf89 205 ttl = 255;
andrewboyson 22:914b970356f0 206 break;
andrewboyson 22:914b970356f0 207 default:
andrewboyson 42:222a4f45f916 208 LogTimeF("Ip4PollForPacketToSend - undefined destination %d\r\n", dest);
andrewboyson 53:77f8a49adf89 209 return DO_NOTHING;
andrewboyson 11:c051adb70c5a 210 }
andrewboyson 10:f0854784e960 211
andrewboyson 136:8a65abb0dc63 212 *pSize = IP4_HEADER_LENGTH + dataLength;
andrewboyson 136:8a65abb0dc63 213
andrewboyson 136:8a65abb0dc63 214 makeHeader(pPacket, *pSize, ttl, protocol, srcIp, dstIp);
andrewboyson 59:e0e556c8bd46 215
andrewboyson 136:8a65abb0dc63 216 if (ActionGetTracePart(action)) logHeader(pPacket);
andrewboyson 37:793b39683406 217
andrewboyson 10:f0854784e960 218 return action;
andrewboyson 10:f0854784e960 219 }