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 Apr 02 19:08:25 2020 +0000
Revision:
167:3ba4e3c49631
Parent:
136:8a65abb0dc63
Child:
172:9bc3c7b2cca1
Modified resolution cache ajaxs to include the index

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 136:8a65abb0dc63 15 #include "ip6hdr.h"
andrewboyson 49:1a6336f2b3f9 16 #include "ndp.h"
andrewboyson 49:1a6336f2b3f9 17 #include "ntp.h"
andrewboyson 49:1a6336f2b3f9 18 #include "mac.h"
andrewboyson 49:1a6336f2b3f9 19 #include "http.h"
andrewboyson 11:c051adb70c5a 20
andrewboyson 48:952dddb74b8b 21 bool Ip6Trace = true;
andrewboyson 11:c051adb70c5a 22
andrewboyson 136:8a65abb0dc63 23 static void logHeader(char* pPacket)
andrewboyson 11:c051adb70c5a 24 {
andrewboyson 43:bc028d5a6424 25 if (NetTraceVerbose)
andrewboyson 43:bc028d5a6424 26 {
andrewboyson 43:bc028d5a6424 27 Log("IP6 header\r\n");
andrewboyson 136:8a65abb0dc63 28 LogF(" Version %d\r\n", Ip6HdrGetVersion (pPacket));
andrewboyson 136:8a65abb0dc63 29 LogF(" Payload length %d\r\n", Ip6HdrGetPayloadLen(pPacket));
andrewboyson 136:8a65abb0dc63 30 LogF(" Hop limit %d\r\n", Ip6HdrGetHopLimit (pPacket));
andrewboyson 136:8a65abb0dc63 31 LogF(" Protocol "); IpProtocolLog(Ip6HdrGetProtocol (pPacket)); Log("\r\n");
andrewboyson 136:8a65abb0dc63 32 Log (" Source IP "); Ip6AddressLog(Ip6HdrPtrSrc (pPacket)); Log("\r\n");
andrewboyson 136:8a65abb0dc63 33 Log (" Destination IP "); Ip6AddressLog(Ip6HdrPtrDst (pPacket)); Log("\r\n");
andrewboyson 43:bc028d5a6424 34 }
andrewboyson 43:bc028d5a6424 35 else
andrewboyson 43:bc028d5a6424 36 {
andrewboyson 44:83ce5ace337b 37 Log("IP6 header ");
andrewboyson 136:8a65abb0dc63 38 IpProtocolLog(Ip6HdrGetProtocol(pPacket));
andrewboyson 43:bc028d5a6424 39 Log(" ");
andrewboyson 136:8a65abb0dc63 40 Ip6AddressLog(Ip6HdrPtrSrc (pPacket));
andrewboyson 43:bc028d5a6424 41 Log(" >>> ");
andrewboyson 136:8a65abb0dc63 42 Ip6AddressLog(Ip6HdrPtrDst (pPacket));
andrewboyson 43:bc028d5a6424 43 Log("\r\n");
andrewboyson 43:bc028d5a6424 44 }
andrewboyson 11:c051adb70c5a 45 }
andrewboyson 136:8a65abb0dc63 46 static char* pTracePacket;
andrewboyson 37:793b39683406 47 static void (*pTraceBack)(void);
andrewboyson 37:793b39683406 48 static void trace()
andrewboyson 10:f0854784e960 49 {
andrewboyson 37:793b39683406 50 pTraceBack();
andrewboyson 136:8a65abb0dc63 51 logHeader(pTracePacket);
andrewboyson 37:793b39683406 52 }
andrewboyson 136:8a65abb0dc63 53 int Ip6HandleReceivedPacket(void (*traceback)(void), char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx, char* macRemote)
andrewboyson 136:8a65abb0dc63 54 {
andrewboyson 136:8a65abb0dc63 55 pTracePacket = pPacketRx;
andrewboyson 136:8a65abb0dc63 56 pTraceBack = traceback;
andrewboyson 37:793b39683406 57
andrewboyson 136:8a65abb0dc63 58 char* pDataRx = pPacketRx + IP6_HEADER_LENGTH;
andrewboyson 136:8a65abb0dc63 59 char* pDataTx = pPacketTx + IP6_HEADER_LENGTH;
andrewboyson 59:e0e556c8bd46 60
andrewboyson 136:8a65abb0dc63 61 int protocol = Ip6HdrGetProtocol (pPacketRx);
andrewboyson 136:8a65abb0dc63 62 int payloadLengthRx = Ip6HdrGetPayloadLen(pPacketRx);
andrewboyson 59:e0e556c8bd46 63
andrewboyson 136:8a65abb0dc63 64 static char srcIp[16];
andrewboyson 136:8a65abb0dc63 65 static char dstIp[16];
andrewboyson 136:8a65abb0dc63 66 Ip6AddressCopy(srcIp, Ip6HdrPtrSrc (pPacketRx));
andrewboyson 136:8a65abb0dc63 67 Ip6AddressCopy(dstIp, Ip6HdrPtrDst (pPacketRx));
andrewboyson 59:e0e556c8bd46 68
andrewboyson 136:8a65abb0dc63 69 int dataLengthRx = sizeRx - IP6_HEADER_LENGTH;
andrewboyson 136:8a65abb0dc63 70 if (dataLengthRx > payloadLengthRx) dataLengthRx = payloadLengthRx; //Choose the lesser of the data length and the payload length
andrewboyson 136:8a65abb0dc63 71 int dataLengthTx = *pSizeTx - IP6_HEADER_LENGTH;
andrewboyson 10:f0854784e960 72
andrewboyson 44:83ce5ace337b 73 int scope = SlaacScope(dstIp);
andrewboyson 61:aad055f1b0d1 74 bool isMe = scope != SCOPE_NONE;
andrewboyson 136:8a65abb0dc63 75 bool isMulticast = Ip6AddrIsMulticast(dstIp);
andrewboyson 136:8a65abb0dc63 76 bool isSolicited = Ip6AddrIsSolicited(dstIp);
andrewboyson 136:8a65abb0dc63 77 bool isGroup = Ip6AddrIsSameGroup(dstIp, SlaacLinkLocalIp);
andrewboyson 10:f0854784e960 78
andrewboyson 61:aad055f1b0d1 79 bool doIt = isMe || (isMulticast && !isSolicited) || (isGroup && isSolicited);
andrewboyson 10:f0854784e960 80
andrewboyson 14:e75a59c1123d 81 if (!doIt)
andrewboyson 14:e75a59c1123d 82 {
andrewboyson 48:952dddb74b8b 83 if (Ip6Trace)
andrewboyson 15:6ca6778168b1 84 {
andrewboyson 47:73af5c0b0dc2 85 LogTime("IP6 filtered out ip ");
andrewboyson 47:73af5c0b0dc2 86 Ip6AddressLog(dstIp);
andrewboyson 47:73af5c0b0dc2 87 LogF(" from ");
andrewboyson 47:73af5c0b0dc2 88 Ip6AddressLog(srcIp);
andrewboyson 47:73af5c0b0dc2 89 Log("\r\n");
andrewboyson 15:6ca6778168b1 90 }
andrewboyson 14:e75a59c1123d 91 return DO_NOTHING;
andrewboyson 14:e75a59c1123d 92 }
andrewboyson 10:f0854784e960 93
andrewboyson 57:e0fb648acf48 94 NetTraceHostCheckIp6(srcIp);
andrewboyson 57:e0fb648acf48 95
andrewboyson 74:c3756bfa960e 96 int remArIndex = Ar6AddIpRecord(trace, macRemote, srcIp);
andrewboyson 50:492f2d2954e4 97 Nr6MakeRequestForNameFromIp(srcIp);
andrewboyson 11:c051adb70c5a 98
andrewboyson 10:f0854784e960 99 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 100 switch (protocol)
andrewboyson 10:f0854784e960 101 {
andrewboyson 61:aad055f1b0d1 102 case HOPOPT: action = DO_NOTHING; break;
andrewboyson 59:e0e556c8bd46 103 case ICMP6: action = Icmp6HandleReceivedPacket(trace, scope, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, srcIp, dstIp); break;
andrewboyson 59:e0e556c8bd46 104 case UDP: action = Udp6HandleReceivedPacket(trace, scope, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, srcIp, dstIp); break;
andrewboyson 74:c3756bfa960e 105 case TCP: action = Tcp6HandleReceivedPacket(trace, scope, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, srcIp, dstIp, remArIndex); break;
andrewboyson 10:f0854784e960 106 default:
andrewboyson 37:793b39683406 107 LogTimeF("IP6 protocol %d unhandled\r\n", protocol);
andrewboyson 10:f0854784e960 108 return DO_NOTHING;
andrewboyson 10:f0854784e960 109 }
andrewboyson 11:c051adb70c5a 110 if (!action) return DO_NOTHING;
andrewboyson 11:c051adb70c5a 111
andrewboyson 136:8a65abb0dc63 112 int hoplimit;
andrewboyson 53:77f8a49adf89 113 if (NdpIpNeedsToBeRouted(dstIp))
andrewboyson 53:77f8a49adf89 114 {
andrewboyson 59:e0e556c8bd46 115 MacCopy(macRemote, NdpRouterMac); //Send to the router MAC
andrewboyson 53:77f8a49adf89 116 hoplimit = NdpHopLimit;
andrewboyson 53:77f8a49adf89 117 }
andrewboyson 53:77f8a49adf89 118 else
andrewboyson 53:77f8a49adf89 119 {
andrewboyson 53:77f8a49adf89 120 hoplimit = 255;
andrewboyson 53:77f8a49adf89 121 }
andrewboyson 59:e0e556c8bd46 122
andrewboyson 136:8a65abb0dc63 123 Ip6HdrSetVersion (pPacketTx, 6 );
andrewboyson 136:8a65abb0dc63 124 Ip6HdrSetPayloadLen(pPacketTx, dataLengthTx);
andrewboyson 136:8a65abb0dc63 125 Ip6HdrSetProtocol (pPacketTx, protocol );
andrewboyson 136:8a65abb0dc63 126 Ip6HdrSetHopLimit (pPacketTx, hoplimit );
andrewboyson 136:8a65abb0dc63 127
andrewboyson 136:8a65abb0dc63 128 Ip6AddressCopy(Ip6HdrPtrSrc(pPacketTx), srcIp);
andrewboyson 136:8a65abb0dc63 129 Ip6AddressCopy(Ip6HdrPtrDst(pPacketTx), dstIp);
andrewboyson 11:c051adb70c5a 130
andrewboyson 136:8a65abb0dc63 131 *pSizeTx = IP6_HEADER_LENGTH + dataLengthTx;
andrewboyson 10:f0854784e960 132
andrewboyson 136:8a65abb0dc63 133 if (ActionGetTracePart(action)) logHeader(pPacketTx);
andrewboyson 37:793b39683406 134
andrewboyson 10:f0854784e960 135 return action;
andrewboyson 10:f0854784e960 136 }
andrewboyson 136:8a65abb0dc63 137 int Ip6PollForPacketToSend(char* pPacket, int* pSize, char* pDstMac)
andrewboyson 10:f0854784e960 138 {
andrewboyson 136:8a65abb0dc63 139 static char srcIp[16];
andrewboyson 136:8a65abb0dc63 140 static char dstIp[16];
andrewboyson 10:f0854784e960 141
andrewboyson 136:8a65abb0dc63 142 char* pData = pPacket + IP6_HEADER_LENGTH;
andrewboyson 136:8a65abb0dc63 143 int dataLength = *pSize - IP6_HEADER_LENGTH;
andrewboyson 136:8a65abb0dc63 144
andrewboyson 136:8a65abb0dc63 145 int protocol = 0;
andrewboyson 10:f0854784e960 146 int action = DO_NOTHING;
andrewboyson 71:736a5747ade1 147 if (!action) { action = Icmp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = ICMP6; }
andrewboyson 71:736a5747ade1 148 if (!action) { action = Udp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = UDP; }
andrewboyson 71:736a5747ade1 149 if (!action) { action = Tcp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = TCP; }
andrewboyson 11:c051adb70c5a 150 if (!action) return DO_NOTHING;
andrewboyson 37:793b39683406 151
andrewboyson 136:8a65abb0dc63 152 int hoplimit = 0;
andrewboyson 37:793b39683406 153 int dest = ActionGetDestPart(action);
andrewboyson 37:793b39683406 154 switch (dest)
andrewboyson 11:c051adb70c5a 155 {
andrewboyson 11:c051adb70c5a 156 case UNICAST:
andrewboyson 11:c051adb70c5a 157 case UNICAST_DNS:
andrewboyson 11:c051adb70c5a 158 case UNICAST_DHCP:
andrewboyson 22:914b970356f0 159 case UNICAST_NTP:
andrewboyson 57:e0fb648acf48 160 case UNICAST_TFTP:
andrewboyson 53:77f8a49adf89 161 if (NdpIpNeedsToBeRouted(dstIp))
andrewboyson 53:77f8a49adf89 162 {
andrewboyson 53:77f8a49adf89 163 MacCopy(pDstMac, NdpRouterMac); //Send to the router MAC
andrewboyson 53:77f8a49adf89 164 hoplimit = NdpHopLimit;
andrewboyson 53:77f8a49adf89 165 }
andrewboyson 53:77f8a49adf89 166 else
andrewboyson 53:77f8a49adf89 167 {
andrewboyson 53:77f8a49adf89 168 Ar6IpToMac(dstIp, pDstMac); //Make the remote MAC from NP
andrewboyson 53:77f8a49adf89 169 hoplimit = 255;
andrewboyson 53:77f8a49adf89 170 }
andrewboyson 11:c051adb70c5a 171 break;
andrewboyson 22:914b970356f0 172 case MULTICAST_NODE:
andrewboyson 22:914b970356f0 173 case MULTICAST_ROUTER:
andrewboyson 22:914b970356f0 174 case MULTICAST_MDNS:
andrewboyson 22:914b970356f0 175 case MULTICAST_LLMNR:
andrewboyson 112:f8694d0b8858 176 case MULTICAST_NTP:
andrewboyson 22:914b970356f0 177 case SOLICITED_NODE:
andrewboyson 53:77f8a49adf89 178 hoplimit = 255;
andrewboyson 22:914b970356f0 179 break;
andrewboyson 22:914b970356f0 180 default:
andrewboyson 37:793b39683406 181 LogTimeF("Ip6PollForPacketToSend - undefined destination %d\r\n", dest);
andrewboyson 53:77f8a49adf89 182 return DO_NOTHING;
andrewboyson 11:c051adb70c5a 183 }
andrewboyson 10:f0854784e960 184
andrewboyson 136:8a65abb0dc63 185 Ip6HdrSetVersion (pPacket, 6 );
andrewboyson 136:8a65abb0dc63 186 Ip6HdrSetPayloadLen(pPacket, dataLength);
andrewboyson 136:8a65abb0dc63 187 Ip6HdrSetProtocol (pPacket, protocol );
andrewboyson 136:8a65abb0dc63 188 Ip6HdrSetHopLimit (pPacket, hoplimit );
andrewboyson 136:8a65abb0dc63 189 Ip6AddressCopy(Ip6HdrPtrSrc(pPacket), srcIp);
andrewboyson 136:8a65abb0dc63 190 Ip6AddressCopy(Ip6HdrPtrDst(pPacket), dstIp);
andrewboyson 11:c051adb70c5a 191
andrewboyson 136:8a65abb0dc63 192 *pSize = IP6_HEADER_LENGTH + dataLength;
andrewboyson 10:f0854784e960 193
andrewboyson 136:8a65abb0dc63 194 if (ActionGetTracePart(action)) logHeader(pPacket);
andrewboyson 37:793b39683406 195
andrewboyson 10:f0854784e960 196 return action;
andrewboyson 10:f0854784e960 197 }