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.c
00001 #include <stdint.h> 00002 #include "log.h" 00003 #include "net.h" 00004 #include "action.h" 00005 #include "arp.h" 00006 #include "ip4.h" 00007 #include "ip6.h" 00008 #include "link.h" 00009 #include "eth.h" 00010 #include "mac.h" 00011 #include "restart.h" 00012 00013 #define MTU 1500 00014 00015 uint16_t EthProtocol; //Set when receiving or sending packets so that higher levels can read the protocol in use 00016 char* EthMacRemote; //Set when receiving packets so that higher levels can read the protocol in use 00017 00018 //header variables 00019 static char* hdrDstPtr(char* pPacket) { return pPacket + 0; } 00020 static char* hdrSrcPtr(char* pPacket) { return pPacket + 6; } 00021 static char* hdrTypPtr(char* pPacket) { return pPacket + 12; } 00022 #define HEADER_LENGTH 14 00023 static uint16_t hdrTypGet(char* pPacket) { uint16_t res; NetInvert16(&res, hdrTypPtr(pPacket) ); return res; } 00024 static void hdrTypSet(char* pPacket, uint16_t value) { NetInvert16( hdrTypPtr(pPacket), &value); } 00025 00026 void EthProtocolLog(uint16_t protocol) 00027 { 00028 switch (protocol) 00029 { 00030 case ETH_ARP: Log("ARP"); break; 00031 case ETH_IPV4: Log("IPV4"); break; 00032 case ETH_IPV6: Log("IPV6"); break; 00033 default: LogF("%04hX", protocol); break; 00034 } 00035 } 00036 void LogHeader(char* pPacket) 00037 { 00038 if (NetTraceVerbose) 00039 { 00040 Log("ETH header\r\n"); 00041 Log(" Destination: "); MacLog(hdrDstPtr(pPacket)); Log("\r\n"); 00042 Log(" Source: "); MacLog(hdrSrcPtr(pPacket)); Log("\r\n"); 00043 Log(" EtherType: "); EthProtocolLog(hdrTypGet(pPacket)); Log("\r\n"); 00044 } 00045 else 00046 { 00047 Log("ETH header "); 00048 EthProtocolLog(hdrTypGet(pPacket)); 00049 Log(" "); 00050 MacLog(hdrSrcPtr(pPacket)); 00051 Log(" >>> "); 00052 MacLog(hdrDstPtr(pPacket)); 00053 Log("\r\n"); 00054 } 00055 } 00056 static char* tracePacket; 00057 static void trace() { LogHeader(tracePacket); } 00058 int EthHandlePacket(char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx) 00059 { 00060 int lastRestartPoint = RestartPoint; 00061 RestartPoint = FAULT_POINT_EthHandlePacket; 00062 00063 tracePacket = pPacketRx; 00064 00065 char* pDataRx = pPacketRx + HEADER_LENGTH; 00066 char* pDataTx = pPacketTx + HEADER_LENGTH; 00067 int dataLengthRx = sizeRx - HEADER_LENGTH; 00068 int dataLengthTx = *pSizeTx - HEADER_LENGTH; 00069 if (dataLengthTx > MTU) dataLengthTx = MTU; //Limit the transmitted length to the maximum ethernet frame payload length 00070 00071 if (!MacAccept(hdrDstPtr(pPacketRx))) 00072 { 00073 RestartPoint = lastRestartPoint; 00074 return DO_NOTHING; 00075 } 00076 00077 EthProtocol = hdrTypGet(pPacketRx); 00078 if (EthProtocol < 1500) 00079 { 00080 RestartPoint = lastRestartPoint; 00081 return DO_NOTHING; //drop 802.3 messages 00082 } 00083 00084 NetTraceHostCheckMac(hdrSrcPtr(pPacketRx)); 00085 00086 int action = DO_NOTHING; 00087 EthMacRemote = hdrSrcPtr(pPacketRx); 00088 switch (EthProtocol) 00089 { 00090 case ETH_ARP: action = ArpHandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx); break; 00091 case ETH_IPV4: action = Ip4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, EthMacRemote); break; 00092 case ETH_IPV6: action = Ip6HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, EthMacRemote); break; 00093 case 0x6970: break; //Drop Sonos group membership packet 00094 case 0x7374: break; //Drop Sky Q packet 00095 case 0x7475: break; //Drop Sky Q packet 00096 case 0x7380: break; //Drop Sky Q packet 00097 case 0x8100: break; //Drop Sky Q VLAN 802.1Q packet 00098 case 0x887b: break; //Drop Sky Q packet 00099 default: 00100 LogTimeF("ETH protocol %d not handled", EthProtocol); 00101 break; 00102 } 00103 if (!action) 00104 { 00105 RestartPoint = lastRestartPoint; 00106 return DO_NOTHING; 00107 } 00108 00109 MacMakeFromDest(ActionGetDestPart(action), EthProtocol, EthMacRemote); 00110 MacCopy(hdrSrcPtr(pPacketTx), MacLocal); 00111 MacCopy(hdrDstPtr(pPacketTx), EthMacRemote); 00112 hdrTypSet(pPacketTx, EthProtocol); 00113 00114 *pSizeTx = HEADER_LENGTH + dataLengthTx; 00115 00116 if (ActionGetTracePart(action)) LogHeader(pPacketTx); 00117 00118 RestartPoint = lastRestartPoint; 00119 return action; 00120 } 00121 int EthPollForPacketToSend(char* pPacket, int* pSize) 00122 { 00123 char* pData = pPacket + HEADER_LENGTH; 00124 int dataLength = *pSize - HEADER_LENGTH; 00125 if (dataLength > MTU) dataLength = MTU; //Limit the transmitted length to the maximum ethernet frame payload length 00126 00127 int action = DO_NOTHING; 00128 EthProtocol = 0; 00129 if (!action) 00130 { 00131 EthProtocol = ETH_ARP; 00132 action = ArpPollForPacketToSend(pData, &dataLength); 00133 } 00134 00135 if (!action) 00136 { 00137 EthProtocol = ETH_IPV6; 00138 action = Ip6PollForPacketToSend(pData, &dataLength, hdrDstPtr(pPacket)); 00139 } 00140 00141 if (!action) 00142 { 00143 EthProtocol = ETH_IPV4; 00144 action = Ip4PollForPacketToSend(pData, &dataLength, hdrDstPtr(pPacket)); 00145 } 00146 00147 if (!action) return DO_NOTHING; 00148 00149 MacMakeFromDest(ActionGetDestPart(action), EthProtocol, hdrDstPtr(pPacket)); 00150 MacCopy(hdrSrcPtr(pPacket), MacLocal); 00151 hdrTypSet(pPacket, EthProtocol); 00152 00153 *pSize = HEADER_LENGTH + dataLength; 00154 00155 if (ActionGetTracePart(action)) LogHeader(pPacket); 00156 00157 return action; 00158 } 00159
Generated on Tue Jul 12 2022 18:53:40 by 1.7.2