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 Oct 19 20:56:58 2017 +0000
Revision:
43:bc028d5a6424
Child:
47:73af5c0b0dc2
Added verbose option to trace

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 43:bc028d5a6424 1 #include "mbed.h"
andrewboyson 43:bc028d5a6424 2 #include "log.h"
andrewboyson 43:bc028d5a6424 3 #include "net.h"
andrewboyson 43:bc028d5a6424 4 #include "action.h"
andrewboyson 43:bc028d5a6424 5 #include "ip4.h"
andrewboyson 43:bc028d5a6424 6 #include "dhcp.h"
andrewboyson 43:bc028d5a6424 7 #include "echo4.h"
andrewboyson 43:bc028d5a6424 8
andrewboyson 43:bc028d5a6424 9 #define HEADER_SIZE 4
andrewboyson 43:bc028d5a6424 10
andrewboyson 43:bc028d5a6424 11 #define ECHO_REPLY 0
andrewboyson 43:bc028d5a6424 12 #define UNREACHABLE 3
andrewboyson 43:bc028d5a6424 13 #define REDIRECT 5
andrewboyson 43:bc028d5a6424 14 #define ECHO_REQUEST 8
andrewboyson 43:bc028d5a6424 15
andrewboyson 43:bc028d5a6424 16 __packed struct header
andrewboyson 43:bc028d5a6424 17 {
andrewboyson 43:bc028d5a6424 18 uint8_t type;
andrewboyson 43:bc028d5a6424 19 uint8_t code;
andrewboyson 43:bc028d5a6424 20 uint16_t checksum;
andrewboyson 43:bc028d5a6424 21 };
andrewboyson 43:bc028d5a6424 22 static uint8_t type;
andrewboyson 43:bc028d5a6424 23 static uint8_t code;
andrewboyson 43:bc028d5a6424 24 static uint16_t checksum;
andrewboyson 43:bc028d5a6424 25 static uint16_t calculated;
andrewboyson 43:bc028d5a6424 26 static int dataLength;
andrewboyson 43:bc028d5a6424 27 static void* pData;
andrewboyson 43:bc028d5a6424 28
andrewboyson 43:bc028d5a6424 29 static void typeToString(uint16_t type, int size, char* text)
andrewboyson 43:bc028d5a6424 30 {
andrewboyson 43:bc028d5a6424 31 switch (type)
andrewboyson 43:bc028d5a6424 32 {
andrewboyson 43:bc028d5a6424 33 case ECHO_REPLY: strncpy (text, "Echo Reply" , size); break;
andrewboyson 43:bc028d5a6424 34 case ECHO_REQUEST: strncpy (text, "Echo Request" , size); break;
andrewboyson 43:bc028d5a6424 35 default: snprintf(text, size, "Unknown type %d", type); break;
andrewboyson 43:bc028d5a6424 36 }
andrewboyson 43:bc028d5a6424 37 }
andrewboyson 43:bc028d5a6424 38 static void logHeader()
andrewboyson 43:bc028d5a6424 39 {
andrewboyson 43:bc028d5a6424 40 char text[20];
andrewboyson 43:bc028d5a6424 41
andrewboyson 43:bc028d5a6424 42 if (NetTraceVerbose)
andrewboyson 43:bc028d5a6424 43 {
andrewboyson 43:bc028d5a6424 44 Log ("ICMP4 header\r\n");
andrewboyson 43:bc028d5a6424 45 typeToString(type, sizeof(text), text);
andrewboyson 43:bc028d5a6424 46 LogF(" Type %s\r\n", text);
andrewboyson 43:bc028d5a6424 47 LogF(" Code %u\r\n", code);
andrewboyson 43:bc028d5a6424 48 LogF(" Checksum (hex) %04hX\r\n", checksum);
andrewboyson 43:bc028d5a6424 49 LogF(" Calculated %04hX\r\n", calculated);
andrewboyson 43:bc028d5a6424 50 LogF(" Data length %d\r\n", dataLength);
andrewboyson 43:bc028d5a6424 51 }
andrewboyson 43:bc028d5a6424 52 else
andrewboyson 43:bc028d5a6424 53 {
andrewboyson 43:bc028d5a6424 54 Log("ICMP4 header ");
andrewboyson 43:bc028d5a6424 55 typeToString(type, sizeof(text), text);
andrewboyson 43:bc028d5a6424 56 Log(text);
andrewboyson 43:bc028d5a6424 57 Log("\r\n");
andrewboyson 43:bc028d5a6424 58 }
andrewboyson 43:bc028d5a6424 59 }
andrewboyson 43:bc028d5a6424 60 static void readHeader(void* pPacket, int size)
andrewboyson 43:bc028d5a6424 61 {
andrewboyson 43:bc028d5a6424 62 struct header* pHeader = (header*)pPacket;
andrewboyson 43:bc028d5a6424 63 type = pHeader->type;
andrewboyson 43:bc028d5a6424 64 code = pHeader->code;
andrewboyson 43:bc028d5a6424 65 checksum = NetToHost16(pHeader->checksum);
andrewboyson 43:bc028d5a6424 66 calculated = NetCheckSum(size, pPacket);
andrewboyson 43:bc028d5a6424 67 pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 43:bc028d5a6424 68 dataLength = size - HEADER_SIZE;
andrewboyson 43:bc028d5a6424 69 }
andrewboyson 43:bc028d5a6424 70 static void writeHeader(void* pPacket, int size)
andrewboyson 43:bc028d5a6424 71 {
andrewboyson 43:bc028d5a6424 72 struct header* pHeader = (header*)pPacket;
andrewboyson 43:bc028d5a6424 73 pHeader->type = type;
andrewboyson 43:bc028d5a6424 74 pHeader->code = code;
andrewboyson 43:bc028d5a6424 75 pHeader->checksum = 0;
andrewboyson 43:bc028d5a6424 76 pHeader->checksum = NetCheckSum(size, pPacket);
andrewboyson 43:bc028d5a6424 77 calculated = 0;
andrewboyson 43:bc028d5a6424 78 }
andrewboyson 43:bc028d5a6424 79 static void (*pTraceBack)(void);
andrewboyson 43:bc028d5a6424 80 static void trace()
andrewboyson 43:bc028d5a6424 81 {
andrewboyson 43:bc028d5a6424 82 pTraceBack();
andrewboyson 43:bc028d5a6424 83 logHeader();
andrewboyson 43:bc028d5a6424 84 }
andrewboyson 43:bc028d5a6424 85 int Icmp4HandleReceivedPacket(void (*traceback)(void), uint32_t* pSrcIp, uint32_t* pDstIp, int* pSize, void * pPacket)
andrewboyson 43:bc028d5a6424 86 {
andrewboyson 43:bc028d5a6424 87 pTraceBack = traceback;
andrewboyson 43:bc028d5a6424 88
andrewboyson 43:bc028d5a6424 89 readHeader(pPacket, *pSize);
andrewboyson 43:bc028d5a6424 90
andrewboyson 43:bc028d5a6424 91 int action = DO_NOTHING;
andrewboyson 43:bc028d5a6424 92 switch (type)
andrewboyson 43:bc028d5a6424 93 {
andrewboyson 43:bc028d5a6424 94 case ECHO_REQUEST:
andrewboyson 43:bc028d5a6424 95 action = Echo4HandleRequest(trace, &type, &code);
andrewboyson 43:bc028d5a6424 96 break;
andrewboyson 43:bc028d5a6424 97 case UNREACHABLE:
andrewboyson 43:bc028d5a6424 98 return DO_NOTHING;
andrewboyson 43:bc028d5a6424 99 case REDIRECT:
andrewboyson 43:bc028d5a6424 100 return DO_NOTHING;
andrewboyson 43:bc028d5a6424 101 default:
andrewboyson 43:bc028d5a6424 102 LogTimeF("ICMP4 packet type %d unknown\r\n", type);
andrewboyson 43:bc028d5a6424 103 return DO_NOTHING;
andrewboyson 43:bc028d5a6424 104 }
andrewboyson 43:bc028d5a6424 105 if (!action) return DO_NOTHING;
andrewboyson 43:bc028d5a6424 106
andrewboyson 43:bc028d5a6424 107 *pDstIp = *pSrcIp;
andrewboyson 43:bc028d5a6424 108 *pSrcIp = DhcpLocalIp;
andrewboyson 43:bc028d5a6424 109
andrewboyson 43:bc028d5a6424 110 *pSize = HEADER_SIZE + dataLength;
andrewboyson 43:bc028d5a6424 111
andrewboyson 43:bc028d5a6424 112 writeHeader(pPacket, *pSize);
andrewboyson 43:bc028d5a6424 113
andrewboyson 43:bc028d5a6424 114 if (ActionGetTracePart(action)) logHeader();
andrewboyson 43:bc028d5a6424 115
andrewboyson 43:bc028d5a6424 116 return action;
andrewboyson 43:bc028d5a6424 117 }