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
Diff: eth/eth.c
- Revision:
- 61:aad055f1b0d1
- Parent:
- 59:e0e556c8bd46
- Child:
- 86:55bc5ddac16c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eth/eth.c Thu Jan 11 17:38:21 2018 +0000 @@ -0,0 +1,145 @@ +#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" + +#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) +{ + 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)) return DO_NOTHING; + + protocol = NetToHost16(pHeaderRx->typ); + if (protocol < 1500) 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) 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); + + return action; +} +int EthPollForPacketToSend(void* pPacket, int* pSize) +{ + struct header * pHeader = (struct header*)pPacket; + void* pData = (char*)pPacket + sizeof(struct header); + + int dataLength = 0; + 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; +} +