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:
138:5ff0c7069300
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
andrewboyson 57:e0fb648acf48 3 #include "log.h"
andrewboyson 57:e0fb648acf48 4 #include "net.h"
andrewboyson 57:e0fb648acf48 5 #include "action.h"
andrewboyson 57:e0fb648acf48 6 #include "ns.h"
andrewboyson 57:e0fb648acf48 7 #include "ra.h"
andrewboyson 57:e0fb648acf48 8 #include "rs.h"
andrewboyson 57:e0fb648acf48 9 #include "ip.h"
andrewboyson 49:1a6336f2b3f9 10 #include "ip6addr.h"
andrewboyson 57:e0fb648acf48 11 #include "slaac.h"
andrewboyson 57:e0fb648acf48 12 #include "echo6.h"
andrewboyson 57:e0fb648acf48 13 #include "dest6.h"
andrewboyson 136:8a65abb0dc63 14 #include "checksum.h"
andrewboyson 43:bc028d5a6424 15
andrewboyson 138:5ff0c7069300 16 static char* hdrPtrType (char* pPacket) { return pPacket + 0; } //1
andrewboyson 138:5ff0c7069300 17 static char* hdrPtrCode (char* pPacket) { return pPacket + 1; } //1
andrewboyson 138:5ff0c7069300 18 static char* hdrPtrChecksum(char* pPacket) { return pPacket + 2; } //2
andrewboyson 138:5ff0c7069300 19 static const int HEADER_LENGTH = 4;
andrewboyson 138:5ff0c7069300 20
andrewboyson 43:bc028d5a6424 21 static uint8_t type;
andrewboyson 43:bc028d5a6424 22 static uint8_t code;
andrewboyson 43:bc028d5a6424 23 static uint16_t checksum;
andrewboyson 43:bc028d5a6424 24 static uint16_t calculatedChecksum;
andrewboyson 43:bc028d5a6424 25
andrewboyson 47:73af5c0b0dc2 26 static void logType(uint8_t type)
andrewboyson 43:bc028d5a6424 27 {
andrewboyson 43:bc028d5a6424 28 switch (type)
andrewboyson 43:bc028d5a6424 29 {
andrewboyson 49:1a6336f2b3f9 30 case 1: Log ("Destination unreacheable" ); break;
andrewboyson 49:1a6336f2b3f9 31 case 128: Log ("Echo Request" ); break;
andrewboyson 49:1a6336f2b3f9 32 case 129: Log ("Echo Reply" ); break;
andrewboyson 57:e0fb648acf48 33 case 133: Log ("Router solicit" ); break;
andrewboyson 57:e0fb648acf48 34 case 134: Log ("Router advertisement" ); break;
andrewboyson 57:e0fb648acf48 35 case 135: Log ("Neighbour solicit" ); break;
andrewboyson 57:e0fb648acf48 36 case 136: Log ("Neighbour advertisement" ); break;
andrewboyson 57:e0fb648acf48 37 case 137: Log ("Redirect" ); break;
andrewboyson 57:e0fb648acf48 38 default: LogF("Unknown type %u", type ); break;
andrewboyson 43:bc028d5a6424 39 }
andrewboyson 43:bc028d5a6424 40 }
andrewboyson 138:5ff0c7069300 41 static uint16_t calculateChecksum(char* pSrcIp, char* pDstIp, int size, char* pPacket)
andrewboyson 136:8a65abb0dc63 42 {
andrewboyson 136:8a65abb0dc63 43 uint32_t sum = 0;
andrewboyson 136:8a65abb0dc63 44 uint32_t pro32 = ICMP6;
andrewboyson 136:8a65abb0dc63 45 sum = CheckSumAddDirect(sum, 16, pSrcIp );
andrewboyson 136:8a65abb0dc63 46 sum = CheckSumAddDirect(sum, 16, pDstIp );
andrewboyson 136:8a65abb0dc63 47 sum = CheckSumAddInvert(sum, 4, &size );
andrewboyson 136:8a65abb0dc63 48 sum = CheckSumAddInvert(sum, 4, &pro32 );
andrewboyson 136:8a65abb0dc63 49 return CheckSumFinDirect(sum, size, pPacket);
andrewboyson 43:bc028d5a6424 50 }
andrewboyson 43:bc028d5a6424 51 static void logHeader()
andrewboyson 43:bc028d5a6424 52 {
andrewboyson 43:bc028d5a6424 53 if (NetTraceVerbose)
andrewboyson 43:bc028d5a6424 54 {
andrewboyson 43:bc028d5a6424 55 Log ("ICMP6 header\r\n");
andrewboyson 47:73af5c0b0dc2 56 Log (" Type "); logType(type); Log("\r\n");
andrewboyson 43:bc028d5a6424 57 LogF(" Code %u\r\n", code);
andrewboyson 43:bc028d5a6424 58 LogF(" Checksum (hex) %04hX\r\n", checksum);
andrewboyson 43:bc028d5a6424 59 LogF(" Calculated %04hX\r\n", calculatedChecksum);
andrewboyson 43:bc028d5a6424 60 }
andrewboyson 43:bc028d5a6424 61 else
andrewboyson 43:bc028d5a6424 62 {
andrewboyson 43:bc028d5a6424 63 Log ("ICMP6 header ");
andrewboyson 47:73af5c0b0dc2 64 logType(type);
andrewboyson 43:bc028d5a6424 65 Log("\r\n");
andrewboyson 43:bc028d5a6424 66 }
andrewboyson 43:bc028d5a6424 67 }
andrewboyson 138:5ff0c7069300 68 static void readHeader(char* pSrcIp, char* pDstIp, char* pPacket, int size)
andrewboyson 43:bc028d5a6424 69 {
andrewboyson 138:5ff0c7069300 70 type = *hdrPtrType(pPacket);
andrewboyson 138:5ff0c7069300 71 code = *hdrPtrCode(pPacket);
andrewboyson 138:5ff0c7069300 72 NetDirect16(&checksum, hdrPtrChecksum(pPacket));
andrewboyson 43:bc028d5a6424 73 calculatedChecksum = calculateChecksum(pSrcIp, pDstIp, size, pPacket);
andrewboyson 43:bc028d5a6424 74 }
andrewboyson 138:5ff0c7069300 75 static void writeHeader(char* pPacket, int size, char* pSrcIp, char* pDstIp)
andrewboyson 138:5ff0c7069300 76 {
andrewboyson 138:5ff0c7069300 77 *hdrPtrType(pPacket) = type;
andrewboyson 138:5ff0c7069300 78 *hdrPtrCode(pPacket) = code;
andrewboyson 138:5ff0c7069300 79 checksum = 0;
andrewboyson 138:5ff0c7069300 80 NetDirect16(hdrPtrChecksum(pPacket), &checksum);
andrewboyson 47:73af5c0b0dc2 81 checksum = calculateChecksum(pSrcIp, pDstIp, size, pPacket);
andrewboyson 138:5ff0c7069300 82 NetDirect16(hdrPtrChecksum(pPacket), &checksum);
andrewboyson 43:bc028d5a6424 83 calculatedChecksum = 0;
andrewboyson 43:bc028d5a6424 84 }
andrewboyson 43:bc028d5a6424 85 static void (*pTraceBack)(void);
andrewboyson 43:bc028d5a6424 86 static void trace()
andrewboyson 43:bc028d5a6424 87 {
andrewboyson 43:bc028d5a6424 88 pTraceBack();
andrewboyson 43:bc028d5a6424 89 logHeader();
andrewboyson 43:bc028d5a6424 90 }
andrewboyson 138:5ff0c7069300 91 int Icmp6HandleReceivedPacket(void (*traceback)(void), int scope, char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx, char* pSrcIp, char* pDstIp)
andrewboyson 43:bc028d5a6424 92 {
andrewboyson 43:bc028d5a6424 93 pTraceBack = traceback;
andrewboyson 59:e0e556c8bd46 94
andrewboyson 59:e0e556c8bd46 95 readHeader(pSrcIp, pDstIp, pPacketRx, sizeRx);
andrewboyson 43:bc028d5a6424 96
andrewboyson 138:5ff0c7069300 97 int dataLengthRx = sizeRx - HEADER_LENGTH;
andrewboyson 138:5ff0c7069300 98 int dataLengthTx = *pSizeTx - HEADER_LENGTH;
andrewboyson 138:5ff0c7069300 99 char* pPayloadRx = pPacketRx + HEADER_LENGTH;
andrewboyson 138:5ff0c7069300 100 char* pPayloadTx = pPacketTx + HEADER_LENGTH;
andrewboyson 43:bc028d5a6424 101
andrewboyson 43:bc028d5a6424 102 int action = DO_NOTHING;
andrewboyson 43:bc028d5a6424 103 switch (type)
andrewboyson 43:bc028d5a6424 104 {
andrewboyson 57:e0fb648acf48 105 case 1: //Destination unreacheable
andrewboyson 57:e0fb648acf48 106 action = Dest6HandleRequest(trace, &type, &code);
andrewboyson 57:e0fb648acf48 107 break;
andrewboyson 43:bc028d5a6424 108 case 128: //Echo request - Ping
andrewboyson 59:e0e556c8bd46 109 action = Echo6HandleRequest(trace, &type, &code, pPayloadRx, dataLengthRx, pPayloadTx, &dataLengthTx);
andrewboyson 43:bc028d5a6424 110 break;
andrewboyson 43:bc028d5a6424 111 case 133: //Router solicit
andrewboyson 43:bc028d5a6424 112 return DO_NOTHING; //We are not a router so quietly drop this
andrewboyson 43:bc028d5a6424 113 case 134: //Router advertisement
andrewboyson 59:e0e556c8bd46 114 action = RaHandleReceivedAdvertisement(trace, pPayloadRx, &dataLengthRx);
andrewboyson 43:bc028d5a6424 115 break;
andrewboyson 43:bc028d5a6424 116 case 135: //Neighbour solicit
andrewboyson 59:e0e556c8bd46 117 action = NsHandleReceivedSolicitation(trace, &type, &code, pPayloadRx, dataLengthRx, pPayloadTx, &dataLengthTx);
andrewboyson 43:bc028d5a6424 118 break;
andrewboyson 43:bc028d5a6424 119 case 136: //Neighbour advertisement
andrewboyson 59:e0e556c8bd46 120 action = NsHandleReceivedAdvertisement(trace, pPayloadRx, &dataLengthRx);
andrewboyson 43:bc028d5a6424 121 break;
andrewboyson 43:bc028d5a6424 122 default:
andrewboyson 48:952dddb74b8b 123 LogTimeF("ICMP6 unknown packet type %d\r\n", type);
andrewboyson 43:bc028d5a6424 124 return DO_NOTHING;
andrewboyson 43:bc028d5a6424 125 }
andrewboyson 43:bc028d5a6424 126 if (!action) return DO_NOTHING;
andrewboyson 43:bc028d5a6424 127
andrewboyson 49:1a6336f2b3f9 128 Ip6AddressCopy(pDstIp, pSrcIp);
andrewboyson 49:1a6336f2b3f9 129 SlaacAddressFromScope(scope, pSrcIp);
andrewboyson 49:1a6336f2b3f9 130 Ip6AddressFromDest (ActionGetDestPart(action), pDstIp);
andrewboyson 43:bc028d5a6424 131
andrewboyson 138:5ff0c7069300 132 *pSizeTx = HEADER_LENGTH + dataLengthTx;
andrewboyson 43:bc028d5a6424 133
andrewboyson 59:e0e556c8bd46 134 writeHeader(pPacketTx, *pSizeTx, pSrcIp, pDstIp);
andrewboyson 43:bc028d5a6424 135
andrewboyson 43:bc028d5a6424 136 if (ActionGetTracePart(action)) logHeader();
andrewboyson 43:bc028d5a6424 137
andrewboyson 43:bc028d5a6424 138 return action;
andrewboyson 43:bc028d5a6424 139 }
andrewboyson 138:5ff0c7069300 140 int Icmp6PollForPacketToSend(char* pPacket, int* pSize, char* pSrcIp, char* pDstIp)
andrewboyson 43:bc028d5a6424 141 {
andrewboyson 138:5ff0c7069300 142 char* pData = pPacket + HEADER_LENGTH;
andrewboyson 138:5ff0c7069300 143 int dataLength = *pSize - HEADER_LENGTH;
andrewboyson 43:bc028d5a6424 144 int action = DO_NOTHING;
andrewboyson 46:40d33e9037e4 145 if (!action) action = RsGetWaitingSolicitation(pData, &dataLength, &type, &code);
andrewboyson 43:bc028d5a6424 146 if (!action) action = NsGetWaitingSolicitation(pData, &dataLength, &type, &code);
andrewboyson 43:bc028d5a6424 147 if (!action) return DO_NOTHING;
andrewboyson 43:bc028d5a6424 148
andrewboyson 44:83ce5ace337b 149 int scope = SCOPE_LOCAL;
andrewboyson 49:1a6336f2b3f9 150 SlaacAddressFromScope(scope, pSrcIp);
andrewboyson 49:1a6336f2b3f9 151 Ip6AddressFromDest (ActionGetDestPart(action), pDstIp);
andrewboyson 43:bc028d5a6424 152
andrewboyson 138:5ff0c7069300 153 *pSize = HEADER_LENGTH + dataLength;
andrewboyson 43:bc028d5a6424 154
andrewboyson 43:bc028d5a6424 155 writeHeader(pPacket, *pSize, pSrcIp, pDstIp);
andrewboyson 43:bc028d5a6424 156
andrewboyson 43:bc028d5a6424 157 if (ActionGetTracePart(action)) logHeader();
andrewboyson 43:bc028d5a6424 158
andrewboyson 43:bc028d5a6424 159 return action;
andrewboyson 43:bc028d5a6424 160
andrewboyson 43:bc028d5a6424 161 }