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:
Fri Jul 19 17:48:06 2019 +0000
Revision:
151:bde6f7da1755
Parent:
138:5ff0c7069300
Child:
172:9bc3c7b2cca1
Removed private key and certificate from semihost storage as found to be unreliable (though secure) and moved it into flash storage (reliable, simple, but visible on mbed.

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 }