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.cpp
- Committer:
- andrewboyson
- Date:
- 2017-10-26
- Revision:
- 47:73af5c0b0dc2
- Parent:
- 44:83ce5ace337b
- Child:
- 57:e0fb648acf48
File content as of revision 47:73af5c0b0dc2:
#include "mbed.h" #include "io.h" #include "log.h" #include "net.h" #include "action.h" #include "arp.h" #include "ip4.h" #include "ip6.h" #include "phy.h" #include "eth.h" #include "mac.h" #define HEADER_SIZE 14 //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; } } static void finalisePacket(int dest, int dataLength, void* pPacket, int* pSize) { if (!dest) return; struct header * pHeader = (header*)pPacket; MacMakeFromDest(dest, protocol, pHeader->dst); MacCopy(pHeader->src, MacLocal); //Put our MAC into the source pHeader->typ = NetToHost16(protocol); *pSize = HEADER_SIZE + dataLength; } 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 (*pTraceBack)(void); static void* tracePacket; static void trace() { pTraceBack(); struct header * pHeader = (header*)tracePacket; LogHeader(pHeader); } int EthHandlePacket(void (*traceback)(void), void* pPacket, int* pSize) { pTraceBack = traceback; tracePacket = pPacket; struct header * pHeader = (header*)pPacket; int dataLength = *pSize - HEADER_SIZE; void* pData = (char*)pPacket + HEADER_SIZE; if (!MacAccept(pHeader->dst)) return DO_NOTHING; protocol = NetToHost16(pHeader->typ); if (protocol < 1500) return DO_NOTHING; //drop 802.3 messages int action = DO_NOTHING; switch (protocol) { case ARP: action = ArpHandleReceivedPacket(trace, pHeader->src, pData, &dataLength, pHeader->dst); break; case IPV4: action = Ip4HandleReceivedPacket(trace, pHeader->src, pData, &dataLength, pHeader->dst); break; case IPV6: action = Ip6HandleReceivedPacket(trace, pHeader->src, pData, &dataLength, pHeader->dst); 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; finalisePacket(ActionGetDestPart(action), dataLength, pPacket, pSize); if (ActionGetTracePart(action)) LogHeader(pHeader); return action; } int EthPollForPacketToSend(void* pPacket, int* pSize) { struct header * pHeader = (header*)pPacket; void* pData = (char*)pPacket + HEADER_SIZE; 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; finalisePacket(ActionGetDestPart(action), dataLength, pPacket, pSize); if (ActionGetTracePart(action)) LogHeader(pHeader); return action; }