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
ip4/icmp/icmp4.c
- Committer:
- andrewboyson
- Date:
- 2021-05-20
- Revision:
- 200:5acbc41bf469
- Parent:
- 136:8a65abb0dc63
File content as of revision 200:5acbc41bf469:
#include <stdint.h> #include "log.h" #include "net.h" #include "action.h" #include "ip4.h" #include "dhcp.h" #include "echo4.h" #include "checksum.h" #define ECHO_REPLY 0 #define UNREACHABLE 3 #define REDIRECT 5 #define ECHO_REQUEST 8 static char* hdrTypePtr (char* pPacket) { return pPacket + 0; } //1 static char* hdrCodePtr (char* pPacket) { return pPacket + 1; } //1 static char* hdrChecksumPtr(char* pPacket) { return pPacket + 2; } //2 #define HEADER_LENGTH 4 static uint8_t hdrTypeGet (char* pPacket) { return *hdrTypePtr (pPacket); } static uint8_t hdrCodeGet (char* pPacket) { return *hdrCodePtr (pPacket); } static uint16_t hdrChecksumGet(char* pPacket) { uint16_t r; NetDirect16(&r, hdrChecksumPtr(pPacket)); return r; } //Don't invert the checksum static void hdrTypeSet (char* pPacket, uint8_t value) { *hdrTypePtr (pPacket) = value; } static void hdrCodeSet (char* pPacket, uint8_t value) { *hdrCodePtr (pPacket) = value; } static void hdrChecksumSet(char* pPacket, uint16_t value) { NetDirect16(hdrChecksumPtr(pPacket), &value); } //Don't invert the checksum static void logType(uint16_t type) { switch (type) { case ECHO_REPLY: Log ("Echo Reply" ); break; case ECHO_REQUEST: Log ("Echo Request" ); break; default: LogF("Unknown type %d", type); break; } } static void logHeader(int size, char* pPacket) { if (NetTraceVerbose) { Log ("ICMP4 header\r\n"); LogF(" Type "); logType(hdrTypeGet (pPacket)); Log("\r\n"); LogF(" Code %u\r\n", hdrCodeGet (pPacket)); LogF(" Checksum (hex) %04hX\r\n", hdrChecksumGet(pPacket)); LogF(" Calculated %04hX\r\n", CheckSum(size, pPacket)); } else { Log("ICMP4 header "); logType(hdrTypeGet(pPacket)); Log("\r\n"); } } static int traceSize = 0; static char* tracePacket; static void (*pTraceBack)(void); static void trace() { pTraceBack(); logHeader(traceSize, tracePacket); } int Icmp4HandleReceivedPacket(void (*traceback)(void), char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx, uint32_t* pSrcIp, uint32_t* pDstIp) { pTraceBack = traceback; tracePacket = pPacketRx; traceSize = sizeRx; uint8_t type = hdrTypeGet(pPacketRx); uint8_t code = hdrCodeGet(pPacketRx); int dataLengthRx = sizeRx - HEADER_LENGTH; int dataLengthTx = *pSizeTx - HEADER_LENGTH; char* pPayloadRx = (char*)pPacketRx + HEADER_LENGTH; char* pPayloadTx = (char*)pPacketTx + HEADER_LENGTH; int action = DO_NOTHING; switch (type) { case ECHO_REQUEST: action = Echo4HandleRequest(trace, &type, &code, pPayloadRx, dataLengthRx, pPayloadTx, &dataLengthTx); break; case UNREACHABLE: return DO_NOTHING; case REDIRECT: return DO_NOTHING; default: LogTimeF("ICMP4 packet type %d unknown\r\n", type); return DO_NOTHING; } if (!action) return DO_NOTHING; *pDstIp = *pSrcIp; *pSrcIp = DhcpLocalIp; *pSizeTx = HEADER_LENGTH + dataLengthTx; hdrTypeSet (pPacketTx, type ); hdrCodeSet (pPacketTx, code ); hdrChecksumSet(pPacketTx, 0 ); uint16_t checksum = CheckSum(*pSizeTx, pPacketTx); hdrChecksumSet(pPacketTx, checksum); if (ActionGetTracePart(action)) logHeader(*pSizeTx, pPacketTx); return action; }