Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
eth/eth.cpp
- Committer:
- andrewboyson
- Date:
- 2017-09-25
- Revision:
- 36:900e24b27bfb
- Parent:
- 33:714a0345e59b
- Child:
- 37:793b39683406
File content as of revision 36:900e24b27bfb:
#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);
MacCopy(pHeader->src, MacLocal); //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 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:
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;
}