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

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;
+}
+