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
Parent:
42:222a4f45f916
Child:
44:83ce5ace337b
Added verbose option to trace

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 42:222a4f45f916 15 //header variables
andrewboyson 10:f0854784e960 16 __packed struct header
andrewboyson 10:f0854784e960 17 {
andrewboyson 10:f0854784e960 18 char dst[6];
andrewboyson 10:f0854784e960 19 char src[6];
andrewboyson 10:f0854784e960 20 uint16_t typ;
andrewboyson 10:f0854784e960 21 };
andrewboyson 42:222a4f45f916 22 static uint16_t protocol;
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 42:222a4f45f916 41 MacMake(action, protocol, pHeader->dst);
andrewboyson 10:f0854784e960 42
andrewboyson 36:900e24b27bfb 43 MacCopy(pHeader->src, MacLocal); //Put our MAC into the source
andrewboyson 42:222a4f45f916 44 pHeader->typ = NetToHost16(protocol);
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 43:bc028d5a6424 51 if (NetTraceVerbose)
andrewboyson 43:bc028d5a6424 52 {
andrewboyson 43:bc028d5a6424 53 Log ("ETH header\r\n");
andrewboyson 43:bc028d5a6424 54 MacToString(pHeader->dst, sizeof(text), text); LogF(" Destination: %s\r\n", text);
andrewboyson 43:bc028d5a6424 55 MacToString(pHeader->src, sizeof(text), text); LogF(" Source: %s\r\n", text);
andrewboyson 43:bc028d5a6424 56 EthProtocolToString(NetToHost16(pHeader->typ), sizeof(text), text); LogF(" EtherType: %s\r\n", text);
andrewboyson 43:bc028d5a6424 57 }
andrewboyson 43:bc028d5a6424 58 else
andrewboyson 43:bc028d5a6424 59 {
andrewboyson 43:bc028d5a6424 60 Log("ETH header ");
andrewboyson 43:bc028d5a6424 61 EthProtocolToString(NetToHost16(pHeader->typ), sizeof(text), text);
andrewboyson 43:bc028d5a6424 62 Log(text);
andrewboyson 43:bc028d5a6424 63 Log(" ");
andrewboyson 43:bc028d5a6424 64 MacToString(pHeader->src, sizeof(text), text);
andrewboyson 43:bc028d5a6424 65 Log(text);
andrewboyson 43:bc028d5a6424 66 Log(" >>> ");
andrewboyson 43:bc028d5a6424 67 MacToString(pHeader->dst, sizeof(text), text);
andrewboyson 43:bc028d5a6424 68 Log(text);
andrewboyson 43:bc028d5a6424 69 Log("\r\n");
andrewboyson 43:bc028d5a6424 70 }
andrewboyson 13:9cd54f7db57a 71 }
andrewboyson 37:793b39683406 72 static void (*pTraceBack)(void);
andrewboyson 37:793b39683406 73 static void* tracePacket;
andrewboyson 37:793b39683406 74 static void trace()
andrewboyson 10:f0854784e960 75 {
andrewboyson 37:793b39683406 76 pTraceBack();
andrewboyson 37:793b39683406 77 struct header * pHeader = (header*)tracePacket;
andrewboyson 37:793b39683406 78 LogHeader(pHeader);
andrewboyson 37:793b39683406 79 }
andrewboyson 37:793b39683406 80 int EthHandlePacket(void (*traceback)(void), void* pPacket, int* pSize)
andrewboyson 37:793b39683406 81 {
andrewboyson 37:793b39683406 82 pTraceBack = traceback;
andrewboyson 37:793b39683406 83 tracePacket = pPacket;
andrewboyson 10:f0854784e960 84 struct header * pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 85 int dataLength = *pSize - HEADER_SIZE;
andrewboyson 10:f0854784e960 86 void* pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 14:e75a59c1123d 87
andrewboyson 14:e75a59c1123d 88 if (!MacAccept(pHeader->dst)) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 89
andrewboyson 42:222a4f45f916 90 protocol = NetToHost16(pHeader->typ);
andrewboyson 42:222a4f45f916 91 if (protocol < 1500) return DO_NOTHING; //drop 802.3 messages
andrewboyson 10:f0854784e960 92
andrewboyson 10:f0854784e960 93 int action = DO_NOTHING;
andrewboyson 42:222a4f45f916 94 switch (protocol)
andrewboyson 10:f0854784e960 95 {
andrewboyson 37:793b39683406 96 case ARP: action = ArpHandleReceivedPacket(trace, pHeader->src, pData, &dataLength, pHeader->dst); break;
andrewboyson 37:793b39683406 97 case IPV4: action = Ip4HandleReceivedPacket(trace, pHeader->src, pData, &dataLength, pHeader->dst); break;
andrewboyson 37:793b39683406 98 case IPV6: action = Ip6HandleReceivedPacket(trace, pHeader->src, pData, &dataLength, pHeader->dst); break;
andrewboyson 28:edc17eeb4142 99 case 0x6970: break; //Drop Sonos group membership packet
andrewboyson 16:f416ef583c89 100 case 0x7374: break; //Drop Sky Q packet
andrewboyson 16:f416ef583c89 101 case 0x7475: break; //Drop Sky Q packet
andrewboyson 16:f416ef583c89 102 case 0x7380: break; //Drop Sky Q packet
andrewboyson 23:b641979389b2 103 case 0x8100: break; //Drop Sky Q VLAN 802.1Q packet
andrewboyson 33:714a0345e59b 104 case 0x887b: break; //Drop Sky Q packet
andrewboyson 10:f0854784e960 105 default:
andrewboyson 42:222a4f45f916 106 LogTimeF("ETH protocol %d not handled", protocol);
andrewboyson 10:f0854784e960 107 break;
andrewboyson 10:f0854784e960 108 }
andrewboyson 10:f0854784e960 109
andrewboyson 14:e75a59c1123d 110 finalisePacket(action, dataLength, pPacket, pSize);
andrewboyson 37:793b39683406 111
andrewboyson 37:793b39683406 112 if (ActionGetTracePart(action)) LogHeader(pHeader);
andrewboyson 37:793b39683406 113
andrewboyson 10:f0854784e960 114 return action;
andrewboyson 10:f0854784e960 115 }
andrewboyson 10:f0854784e960 116 int EthPollForPacketToSend(void* pPacket, int* pSize)
andrewboyson 10:f0854784e960 117 {
andrewboyson 10:f0854784e960 118 struct header * pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 119 void* pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 10:f0854784e960 120
andrewboyson 10:f0854784e960 121 int dataLength = 0;
andrewboyson 42:222a4f45f916 122 protocol = 0;
andrewboyson 10:f0854784e960 123 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 124
andrewboyson 10:f0854784e960 125 if (action == DO_NOTHING)
andrewboyson 10:f0854784e960 126 {
andrewboyson 22:914b970356f0 127 action = ArpPollForPacketToSend(pData, &dataLength);
andrewboyson 42:222a4f45f916 128 protocol = ARP;
andrewboyson 22:914b970356f0 129 }
andrewboyson 22:914b970356f0 130
andrewboyson 22:914b970356f0 131 if (action == DO_NOTHING)
andrewboyson 22:914b970356f0 132 {
andrewboyson 10:f0854784e960 133 action = Ip6PollForPacketToSend(pData, &dataLength, pHeader->dst);
andrewboyson 42:222a4f45f916 134 protocol = IPV6;
andrewboyson 10:f0854784e960 135 }
andrewboyson 10:f0854784e960 136
andrewboyson 10:f0854784e960 137 if (action == DO_NOTHING)
andrewboyson 10:f0854784e960 138 {
andrewboyson 10:f0854784e960 139 action = Ip4PollForPacketToSend(pData, &dataLength, pHeader->dst);
andrewboyson 42:222a4f45f916 140 protocol = IPV4;
andrewboyson 10:f0854784e960 141 }
andrewboyson 10:f0854784e960 142
andrewboyson 14:e75a59c1123d 143 finalisePacket(action, dataLength, pPacket, pSize);
andrewboyson 10:f0854784e960 144
andrewboyson 37:793b39683406 145 if (ActionGetTracePart(action)) LogHeader(pHeader);
andrewboyson 13:9cd54f7db57a 146
andrewboyson 10:f0854784e960 147 return action;
andrewboyson 10:f0854784e960 148 }
andrewboyson 10:f0854784e960 149