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:
Wed Oct 04 07:51:02 2017 +0000
Revision:
37:793b39683406
Parent:
36:900e24b27bfb
Child:
42:222a4f45f916
Added trace back and trace forward to log messages

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 37:793b39683406 1 #include "mbed.h"
andrewboyson 37:793b39683406 2 #include "io.h"
andrewboyson 37:793b39683406 3 #include "log.h"
andrewboyson 37:793b39683406 4 #include "net.h"
andrewboyson 37:793b39683406 5 #include "action.h"
andrewboyson 37:793b39683406 6 #include "arp.h"
andrewboyson 37:793b39683406 7 #include "ip4.h"
andrewboyson 37:793b39683406 8 #include "ip6.h"
andrewboyson 37:793b39683406 9 #include "phy.h"
andrewboyson 37:793b39683406 10 #include "eth.h"
andrewboyson 37:793b39683406 11 #include "mac.h"
andrewboyson 10:f0854784e960 12
andrewboyson 10:f0854784e960 13 #define HEADER_SIZE 14
andrewboyson 13:9cd54f7db57a 14
andrewboyson 10:f0854784e960 15 __packed struct header
andrewboyson 10:f0854784e960 16 {
andrewboyson 10:f0854784e960 17 char dst[6];
andrewboyson 10:f0854784e960 18 char src[6];
andrewboyson 10:f0854784e960 19 uint16_t typ;
andrewboyson 10:f0854784e960 20 };
andrewboyson 10:f0854784e960 21
andrewboyson 14:e75a59c1123d 22 uint16_t EthProtocol;
andrewboyson 14:e75a59c1123d 23
andrewboyson 14:e75a59c1123d 24 void EthProtocolToString(uint16_t prototype, int size, char* text)
andrewboyson 10:f0854784e960 25 {
andrewboyson 14:e75a59c1123d 26 switch (prototype)
andrewboyson 10:f0854784e960 27 {
andrewboyson 37:793b39683406 28 case ARP: strncpy (text, "ARP" , size); break;
andrewboyson 37:793b39683406 29 case IPV4: strncpy (text, "IPV4", size); break;
andrewboyson 37:793b39683406 30 case IPV6: strncpy (text, "IPV6", size); break;
andrewboyson 14:e75a59c1123d 31 default: snprintf(text, size, "%04hX", prototype); break;
andrewboyson 10:f0854784e960 32 }
andrewboyson 10:f0854784e960 33 }
andrewboyson 10:f0854784e960 34
andrewboyson 14:e75a59c1123d 35 static void finalisePacket(int action, int dataLength, void* pPacket, int* pSize)
andrewboyson 10:f0854784e960 36 {
andrewboyson 14:e75a59c1123d 37 if (!action) return;
andrewboyson 14:e75a59c1123d 38
andrewboyson 10:f0854784e960 39 struct header * pHeader = (header*)pPacket;
andrewboyson 14:e75a59c1123d 40
andrewboyson 14:e75a59c1123d 41 MacMake(action, EthProtocol, pHeader->dst);
andrewboyson 10:f0854784e960 42
andrewboyson 36:900e24b27bfb 43 MacCopy(pHeader->src, MacLocal); //Put our MAC into the source
andrewboyson 14:e75a59c1123d 44 pHeader->typ = NetToHost16(EthProtocol);
andrewboyson 10:f0854784e960 45
andrewboyson 10:f0854784e960 46 *pSize = HEADER_SIZE + dataLength;
andrewboyson 10:f0854784e960 47 }
andrewboyson 37:793b39683406 48 void LogHeader(struct header* pHeader)
andrewboyson 13:9cd54f7db57a 49 {
andrewboyson 13:9cd54f7db57a 50 char text[20];
andrewboyson 37:793b39683406 51 Log("ETH header\r\n");
andrewboyson 37:793b39683406 52 MacToString(pHeader->dst, sizeof(text), text); LogF(" Destination: %s\r\n", text);
andrewboyson 37:793b39683406 53 MacToString(pHeader->src, sizeof(text), text); LogF(" Source: %s\r\n", text);
andrewboyson 37:793b39683406 54 EthProtocolToString(NetToHost16(pHeader->typ), sizeof(text), text); LogF(" EtherType: %s\r\n", text);
andrewboyson 13:9cd54f7db57a 55 }
andrewboyson 37:793b39683406 56 static void (*pTraceBack)(void);
andrewboyson 37:793b39683406 57 static void* tracePacket;
andrewboyson 37:793b39683406 58 static void trace()
andrewboyson 10:f0854784e960 59 {
andrewboyson 37:793b39683406 60 pTraceBack();
andrewboyson 37:793b39683406 61 struct header * pHeader = (header*)tracePacket;
andrewboyson 37:793b39683406 62 LogHeader(pHeader);
andrewboyson 37:793b39683406 63 }
andrewboyson 37:793b39683406 64 int EthHandlePacket(void (*traceback)(void), void* pPacket, int* pSize)
andrewboyson 37:793b39683406 65 {
andrewboyson 37:793b39683406 66 pTraceBack = traceback;
andrewboyson 37:793b39683406 67 tracePacket = pPacket;
andrewboyson 10:f0854784e960 68 struct header * pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 69 int dataLength = *pSize - HEADER_SIZE;
andrewboyson 10:f0854784e960 70 void* pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 14:e75a59c1123d 71
andrewboyson 14:e75a59c1123d 72 if (!MacAccept(pHeader->dst)) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 73
andrewboyson 14:e75a59c1123d 74 EthProtocol = NetToHost16(pHeader->typ);
andrewboyson 14:e75a59c1123d 75 if (EthProtocol < 1500) return DO_NOTHING; //drop 802.3 messages
andrewboyson 10:f0854784e960 76
andrewboyson 10:f0854784e960 77 int action = DO_NOTHING;
andrewboyson 14:e75a59c1123d 78 switch (EthProtocol)
andrewboyson 10:f0854784e960 79 {
andrewboyson 37:793b39683406 80 case ARP: action = ArpHandleReceivedPacket(trace, pHeader->src, pData, &dataLength, pHeader->dst); break;
andrewboyson 37:793b39683406 81 case IPV4: action = Ip4HandleReceivedPacket(trace, pHeader->src, pData, &dataLength, pHeader->dst); break;
andrewboyson 37:793b39683406 82 case IPV6: action = Ip6HandleReceivedPacket(trace, pHeader->src, pData, &dataLength, pHeader->dst); break;
andrewboyson 28:edc17eeb4142 83 case 0x6970: break; //Drop Sonos group membership packet
andrewboyson 16:f416ef583c89 84 case 0x7374: break; //Drop Sky Q packet
andrewboyson 16:f416ef583c89 85 case 0x7475: break; //Drop Sky Q packet
andrewboyson 16:f416ef583c89 86 case 0x7380: break; //Drop Sky Q packet
andrewboyson 23:b641979389b2 87 case 0x8100: break; //Drop Sky Q VLAN 802.1Q packet
andrewboyson 33:714a0345e59b 88 case 0x887b: break; //Drop Sky Q packet
andrewboyson 10:f0854784e960 89 default:
andrewboyson 37:793b39683406 90 LogTimeF("ETH protocol %d not handled", EthProtocol);
andrewboyson 10:f0854784e960 91 break;
andrewboyson 10:f0854784e960 92 }
andrewboyson 10:f0854784e960 93
andrewboyson 14:e75a59c1123d 94 finalisePacket(action, dataLength, pPacket, pSize);
andrewboyson 37:793b39683406 95
andrewboyson 37:793b39683406 96 if (ActionGetTracePart(action)) LogHeader(pHeader);
andrewboyson 37:793b39683406 97
andrewboyson 10:f0854784e960 98 return action;
andrewboyson 10:f0854784e960 99 }
andrewboyson 10:f0854784e960 100 int EthPollForPacketToSend(void* pPacket, int* pSize)
andrewboyson 10:f0854784e960 101 {
andrewboyson 10:f0854784e960 102 struct header * pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 103 void* pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 10:f0854784e960 104
andrewboyson 10:f0854784e960 105 int dataLength = 0;
andrewboyson 14:e75a59c1123d 106 EthProtocol = 0;
andrewboyson 10:f0854784e960 107 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 108
andrewboyson 10:f0854784e960 109 if (action == DO_NOTHING)
andrewboyson 10:f0854784e960 110 {
andrewboyson 22:914b970356f0 111 action = ArpPollForPacketToSend(pData, &dataLength);
andrewboyson 22:914b970356f0 112 EthProtocol = ARP;
andrewboyson 22:914b970356f0 113 }
andrewboyson 22:914b970356f0 114
andrewboyson 22:914b970356f0 115 if (action == DO_NOTHING)
andrewboyson 22:914b970356f0 116 {
andrewboyson 10:f0854784e960 117 action = Ip6PollForPacketToSend(pData, &dataLength, pHeader->dst);
andrewboyson 14:e75a59c1123d 118 EthProtocol = IPV6;
andrewboyson 10:f0854784e960 119 }
andrewboyson 10:f0854784e960 120
andrewboyson 10:f0854784e960 121 if (action == DO_NOTHING)
andrewboyson 10:f0854784e960 122 {
andrewboyson 10:f0854784e960 123 action = Ip4PollForPacketToSend(pData, &dataLength, pHeader->dst);
andrewboyson 14:e75a59c1123d 124 EthProtocol = IPV4;
andrewboyson 10:f0854784e960 125 }
andrewboyson 10:f0854784e960 126
andrewboyson 14:e75a59c1123d 127 finalisePacket(action, dataLength, pPacket, pSize);
andrewboyson 10:f0854784e960 128
andrewboyson 37:793b39683406 129 if (ActionGetTracePart(action)) LogHeader(pHeader);
andrewboyson 13:9cd54f7db57a 130
andrewboyson 10:f0854784e960 131 return action;
andrewboyson 10:f0854784e960 132 }
andrewboyson 10:f0854784e960 133