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
eth/eth.c
- Committer:
- andrewboyson
- Date:
- 2019-01-03
- Revision:
- 98:b977424ec7f7
- Parent:
- 97:d91f7db00235
- Child:
- 136:8a65abb0dc63
File content as of revision 98:b977424ec7f7:
#include <stdint.h> #include "log.h" #include "net.h" #include "action.h" #include "arp.h" #include "ip4.h" #include "ip6.h" #include "link.h" #include "eth.h" #include "mac.h" #include "fault.h" #define MTU 1500 //header variables __packed struct header { char dst[6]; char src[6]; uint16_t typ; }; static uint16_t protocol; void EthProtocolLog(uint16_t prototype) { switch (prototype) { case ARP: Log("ARP"); break; case IPV4: Log("IPV4"); break; case IPV6: Log("IPV6"); break; default: LogF("%04hX", prototype); break; } } void LogHeader(struct header* pHeader) { if (NetTraceVerbose) { Log("ETH header\r\n"); Log(" Destination: "); MacLog(pHeader->dst); Log("\r\n"); Log(" Source: "); MacLog(pHeader->src); Log("\r\n"); Log(" EtherType: "); EthProtocolLog(NetToHost16(pHeader->typ)); Log("\r\n"); } else { Log("ETH header "); EthProtocolLog(NetToHost16(pHeader->typ)); Log(" "); MacLog(pHeader->src); Log(" >>> "); MacLog(pHeader->dst); Log("\r\n"); } } static void* tracePacket; static void trace() { struct header * pHeader = (struct header*)tracePacket; LogHeader(pHeader); } int EthHandlePacket(void* pPacketRx, int sizeRx, void* pPacketTx, int* pSizeTx) { int lastFaultPoint = FaultPoint; FaultPoint = FAULT_POINT_EthHandlePacket; tracePacket = pPacketRx; struct header * pHeaderRx = (struct header*)pPacketRx; struct header * pHeaderTx = (struct header*)pPacketTx; void* pDataRx = (char*)pPacketRx + sizeof(struct header); void* pDataTx = (char*)pPacketTx + sizeof(struct header); int dataLengthRx = sizeRx - sizeof(struct header); int dataLengthTx = *pSizeTx - sizeof(struct header); if (dataLengthTx > MTU) dataLengthTx = MTU; //Limit the transmitted length to the maximum ethernet frame payload length if (!MacAccept(pHeaderRx->dst)) { FaultPoint = lastFaultPoint; return DO_NOTHING; } protocol = NetToHost16(pHeaderRx->typ); if (protocol < 1500) { FaultPoint = lastFaultPoint; return DO_NOTHING; //drop 802.3 messages } NetTraceHostCheckMac(pHeaderRx->src); int action = DO_NOTHING; char* macRemote = pHeaderRx->src; switch (protocol) { case ARP: action = ArpHandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx); break; case IPV4: action = Ip4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, macRemote); break; case IPV6: action = Ip6HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, macRemote); break; case 0x6970: break; //Drop Sonos group membership packet case 0x7374: break; //Drop Sky Q packet case 0x7475: break; //Drop Sky Q packet case 0x7380: break; //Drop Sky Q packet case 0x8100: break; //Drop Sky Q VLAN 802.1Q packet case 0x887b: break; //Drop Sky Q packet default: LogTimeF("ETH protocol %d not handled", protocol); break; } if (!action) { FaultPoint = lastFaultPoint; return DO_NOTHING; } MacMakeFromDest(ActionGetDestPart(action), protocol, macRemote); MacCopy(pHeaderTx->src, MacLocal); MacCopy(pHeaderTx->dst, macRemote); pHeaderTx->typ = NetToHost16(protocol); *pSizeTx = sizeof(struct header) + dataLengthTx; if (ActionGetTracePart(action)) LogHeader(pHeaderTx); FaultPoint = lastFaultPoint; return action; } int EthPollForPacketToSend(void* pPacket, int* pSize) { struct header * pHeader = (struct header*)pPacket; void* pData = (char*)pPacket + sizeof(struct header); int dataLength = *pSize - sizeof(struct header); if (dataLength > MTU) dataLength = MTU; //Limit the transmitted length to the maximum ethernet frame payload length protocol = 0; int action = DO_NOTHING; if (!action) { action = ArpPollForPacketToSend(pData, &dataLength); protocol = ARP; } if (!action) { action = Ip6PollForPacketToSend(pData, &dataLength, pHeader->dst); protocol = IPV6; } if (!action) { action = Ip4PollForPacketToSend(pData, &dataLength, pHeader->dst); protocol = IPV4; } if (!action) return DO_NOTHING; MacMakeFromDest(ActionGetDestPart(action), protocol, pHeader->dst); MacCopy(pHeader->src, MacLocal); pHeader->typ = NetToHost16(protocol); *pSize = sizeof(struct header) + dataLength; if (ActionGetTracePart(action)) LogHeader(pHeader); return action; }