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-07-03
- Revision:
- 22:914b970356f0
- Parent:
- 16:f416ef583c89
- Child:
- 23:b641979389b2
File content as of revision 22:914b970356f0:
#include "mbed.h" #include "io.h" #include "log.h" #include "net.h" #include "arp.h" #include "ip4.h" #include "ip6.h" #include "phy.h" #include "eth.h" #include "mac.h" #define HEADER_SIZE 14 #define DEBUG false __packed struct header { char dst[6]; char src[6]; uint16_t typ; }; uint16_t EthProtocol; void EthProtocolToString(uint16_t prototype, int size, char* text) { switch (prototype) { case ARP: strncpy (text, "ARP" , size); break; case IPV4: strncpy (text, "IPV4", size); break; case IPV6: strncpy (text, "IPV6", size); break; default: snprintf(text, size, "%04hX", prototype); break; } } static void finalisePacket(int action, int dataLength, void* pPacket, int* pSize) { if (!action) return; struct header * pHeader = (header*)pPacket; MacMake(action, EthProtocol, pHeader->dst); memcpy(pHeader->src, MacLocal, 6); //Put our MAC into the source pHeader->typ = NetToHost16(EthProtocol); *pSize = HEADER_SIZE + dataLength; } void LogHeader(struct header* pHeader, char* title) { char text[20]; LogTimeF("ETH %s\r\n", title); MacToString(pHeader->dst, sizeof(text), text); LogTimeF("Destination: %s\r\n", text); MacToString(pHeader->src, sizeof(text), text); LogTimeF("Source: %s\r\n", text); EthProtocolToString(NetToHost16(pHeader->typ), sizeof(text), text); LogTimeF("EtherType: %s\r\n", text); } int EthHandlePacket(void* pPacket, int* pSize) { struct header * pHeader = (header*)pPacket; int dataLength = *pSize - HEADER_SIZE; void* pData = (char*)pPacket + HEADER_SIZE; if (!MacAccept(pHeader->dst)) return DO_NOTHING; if (DEBUG) LogHeader(pHeader, "received packet"); EthProtocol = NetToHost16(pHeader->typ); if (EthProtocol < 1500) return DO_NOTHING; //drop 802.3 messages int action = DO_NOTHING; switch (EthProtocol) { case ARP: action = ArpHandleReceivedPacket(pHeader->src, pData, &dataLength, pHeader->dst); break; case IPV4: action = Ip4HandleReceivedPacket(pHeader->src, pData, &dataLength, pHeader->dst); break; case IPV6: action = Ip6HandleReceivedPacket(pHeader->src, pData, &dataLength, pHeader->dst); break; case 0x7374: break; //Drop Sky Q packet case 0x7475: break; //Drop Sky Q packet case 0x7380: break; //Drop Sky Q packet default: LogHeader(pHeader, "packet not handled"); break; } finalisePacket(action, dataLength, pPacket, pSize); return action; } int EthPollForPacketToSend(void* pPacket, int* pSize) { struct header * pHeader = (header*)pPacket; void* pData = (char*)pPacket + HEADER_SIZE; int dataLength = 0; EthProtocol = 0; int action = DO_NOTHING; if (action == DO_NOTHING) { action = ArpPollForPacketToSend(pData, &dataLength); EthProtocol = ARP; } if (action == DO_NOTHING) { action = Ip6PollForPacketToSend(pData, &dataLength, pHeader->dst); EthProtocol = IPV6; } if (action == DO_NOTHING) { action = Ip4PollForPacketToSend(pData, &dataLength, pHeader->dst); EthProtocol = IPV4; } finalisePacket(action, dataLength, pPacket, pSize); if (DEBUG) LogHeader(pHeader, "sent packet"); return action; }