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.c@195:bd5b123143ca, 2021-04-18 (annotated)
- Committer:
- andrewboyson
- Date:
- Sun Apr 18 19:04:48 2021 +0000
- Revision:
- 195:bd5b123143ca
- Parent:
- 172:9bc3c7b2cca1
Added a user module to allow user defined UDPs port to be used - in this case for a WIZ module.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 61:aad055f1b0d1 | 1 | #include <stdint.h> |
andrewboyson | 37:793b39683406 | 2 | #include "log.h" |
andrewboyson | 37:793b39683406 | 3 | #include "net.h" |
andrewboyson | 37:793b39683406 | 4 | #include "action.h" |
andrewboyson | 37:793b39683406 | 5 | #include "arp.h" |
andrewboyson | 37:793b39683406 | 6 | #include "ip4.h" |
andrewboyson | 37:793b39683406 | 7 | #include "ip6.h" |
andrewboyson | 59:e0e556c8bd46 | 8 | #include "link.h" |
andrewboyson | 37:793b39683406 | 9 | #include "eth.h" |
andrewboyson | 37:793b39683406 | 10 | #include "mac.h" |
andrewboyson | 142:a8c0890a58d1 | 11 | #include "restart.h" |
andrewboyson | 10:f0854784e960 | 12 | |
andrewboyson | 59:e0e556c8bd46 | 13 | #define MTU 1500 |
andrewboyson | 13:9cd54f7db57a | 14 | |
andrewboyson | 172:9bc3c7b2cca1 | 15 | uint16_t EthProtocol; //Set when receiving or sending packets so that higher levels can read the protocol in use |
andrewboyson | 195:bd5b123143ca | 16 | char* EthMacRemote; //Set when receiving packets so that higher levels can read the protocol in use |
andrewboyson | 172:9bc3c7b2cca1 | 17 | |
andrewboyson | 42:222a4f45f916 | 18 | //header variables |
andrewboyson | 136:8a65abb0dc63 | 19 | static char* hdrDstPtr(char* pPacket) { return pPacket + 0; } |
andrewboyson | 136:8a65abb0dc63 | 20 | static char* hdrSrcPtr(char* pPacket) { return pPacket + 6; } |
andrewboyson | 136:8a65abb0dc63 | 21 | static char* hdrTypPtr(char* pPacket) { return pPacket + 12; } |
andrewboyson | 136:8a65abb0dc63 | 22 | #define HEADER_LENGTH 14 |
andrewboyson | 136:8a65abb0dc63 | 23 | static uint16_t hdrTypGet(char* pPacket) { uint16_t res; NetInvert16(&res, hdrTypPtr(pPacket) ); return res; } |
andrewboyson | 136:8a65abb0dc63 | 24 | static void hdrTypSet(char* pPacket, uint16_t value) { NetInvert16( hdrTypPtr(pPacket), &value); } |
andrewboyson | 136:8a65abb0dc63 | 25 | |
andrewboyson | 171:f708d6776752 | 26 | void EthProtocolLog(uint16_t protocol) |
andrewboyson | 10:f0854784e960 | 27 | { |
andrewboyson | 171:f708d6776752 | 28 | switch (protocol) |
andrewboyson | 10:f0854784e960 | 29 | { |
andrewboyson | 172:9bc3c7b2cca1 | 30 | case ETH_ARP: Log("ARP"); break; |
andrewboyson | 172:9bc3c7b2cca1 | 31 | case ETH_IPV4: Log("IPV4"); break; |
andrewboyson | 172:9bc3c7b2cca1 | 32 | case ETH_IPV6: Log("IPV6"); break; |
andrewboyson | 172:9bc3c7b2cca1 | 33 | default: LogF("%04hX", protocol); break; |
andrewboyson | 10:f0854784e960 | 34 | } |
andrewboyson | 10:f0854784e960 | 35 | } |
andrewboyson | 136:8a65abb0dc63 | 36 | void LogHeader(char* pPacket) |
andrewboyson | 13:9cd54f7db57a | 37 | { |
andrewboyson | 43:bc028d5a6424 | 38 | if (NetTraceVerbose) |
andrewboyson | 43:bc028d5a6424 | 39 | { |
andrewboyson | 47:73af5c0b0dc2 | 40 | Log("ETH header\r\n"); |
andrewboyson | 136:8a65abb0dc63 | 41 | Log(" Destination: "); MacLog(hdrDstPtr(pPacket)); Log("\r\n"); |
andrewboyson | 136:8a65abb0dc63 | 42 | Log(" Source: "); MacLog(hdrSrcPtr(pPacket)); Log("\r\n"); |
andrewboyson | 136:8a65abb0dc63 | 43 | Log(" EtherType: "); EthProtocolLog(hdrTypGet(pPacket)); Log("\r\n"); |
andrewboyson | 43:bc028d5a6424 | 44 | } |
andrewboyson | 43:bc028d5a6424 | 45 | else |
andrewboyson | 43:bc028d5a6424 | 46 | { |
andrewboyson | 44:83ce5ace337b | 47 | Log("ETH header "); |
andrewboyson | 136:8a65abb0dc63 | 48 | EthProtocolLog(hdrTypGet(pPacket)); |
andrewboyson | 43:bc028d5a6424 | 49 | Log(" "); |
andrewboyson | 136:8a65abb0dc63 | 50 | MacLog(hdrSrcPtr(pPacket)); |
andrewboyson | 43:bc028d5a6424 | 51 | Log(" >>> "); |
andrewboyson | 136:8a65abb0dc63 | 52 | MacLog(hdrDstPtr(pPacket)); |
andrewboyson | 43:bc028d5a6424 | 53 | Log("\r\n"); |
andrewboyson | 43:bc028d5a6424 | 54 | } |
andrewboyson | 13:9cd54f7db57a | 55 | } |
andrewboyson | 136:8a65abb0dc63 | 56 | static char* tracePacket; |
andrewboyson | 136:8a65abb0dc63 | 57 | static void trace() { LogHeader(tracePacket); } |
andrewboyson | 136:8a65abb0dc63 | 58 | int EthHandlePacket(char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx) |
andrewboyson | 37:793b39683406 | 59 | { |
andrewboyson | 142:a8c0890a58d1 | 60 | int lastRestartPoint = RestartPoint; |
andrewboyson | 142:a8c0890a58d1 | 61 | RestartPoint = FAULT_POINT_EthHandlePacket; |
andrewboyson | 97:d91f7db00235 | 62 | |
andrewboyson | 59:e0e556c8bd46 | 63 | tracePacket = pPacketRx; |
andrewboyson | 59:e0e556c8bd46 | 64 | |
andrewboyson | 136:8a65abb0dc63 | 65 | char* pDataRx = pPacketRx + HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 66 | char* pDataTx = pPacketTx + HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 67 | int dataLengthRx = sizeRx - HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 68 | int dataLengthTx = *pSizeTx - HEADER_LENGTH; |
andrewboyson | 59:e0e556c8bd46 | 69 | if (dataLengthTx > MTU) dataLengthTx = MTU; //Limit the transmitted length to the maximum ethernet frame payload length |
andrewboyson | 14:e75a59c1123d | 70 | |
andrewboyson | 136:8a65abb0dc63 | 71 | if (!MacAccept(hdrDstPtr(pPacketRx))) |
andrewboyson | 86:55bc5ddac16c | 72 | { |
andrewboyson | 142:a8c0890a58d1 | 73 | RestartPoint = lastRestartPoint; |
andrewboyson | 86:55bc5ddac16c | 74 | return DO_NOTHING; |
andrewboyson | 86:55bc5ddac16c | 75 | } |
andrewboyson | 13:9cd54f7db57a | 76 | |
andrewboyson | 172:9bc3c7b2cca1 | 77 | EthProtocol = hdrTypGet(pPacketRx); |
andrewboyson | 172:9bc3c7b2cca1 | 78 | if (EthProtocol < 1500) |
andrewboyson | 86:55bc5ddac16c | 79 | { |
andrewboyson | 142:a8c0890a58d1 | 80 | RestartPoint = lastRestartPoint; |
andrewboyson | 86:55bc5ddac16c | 81 | return DO_NOTHING; //drop 802.3 messages |
andrewboyson | 86:55bc5ddac16c | 82 | } |
andrewboyson | 10:f0854784e960 | 83 | |
andrewboyson | 136:8a65abb0dc63 | 84 | NetTraceHostCheckMac(hdrSrcPtr(pPacketRx)); |
andrewboyson | 57:e0fb648acf48 | 85 | |
andrewboyson | 10:f0854784e960 | 86 | int action = DO_NOTHING; |
andrewboyson | 195:bd5b123143ca | 87 | EthMacRemote = hdrSrcPtr(pPacketRx); |
andrewboyson | 172:9bc3c7b2cca1 | 88 | switch (EthProtocol) |
andrewboyson | 10:f0854784e960 | 89 | { |
andrewboyson | 195:bd5b123143ca | 90 | case ETH_ARP: action = ArpHandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx); break; |
andrewboyson | 195:bd5b123143ca | 91 | case ETH_IPV4: action = Ip4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, EthMacRemote); break; |
andrewboyson | 195:bd5b123143ca | 92 | case ETH_IPV6: action = Ip6HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, EthMacRemote); break; |
andrewboyson | 28:edc17eeb4142 | 93 | case 0x6970: break; //Drop Sonos group membership packet |
andrewboyson | 16:f416ef583c89 | 94 | case 0x7374: break; //Drop Sky Q packet |
andrewboyson | 16:f416ef583c89 | 95 | case 0x7475: break; //Drop Sky Q packet |
andrewboyson | 16:f416ef583c89 | 96 | case 0x7380: break; //Drop Sky Q packet |
andrewboyson | 23:b641979389b2 | 97 | case 0x8100: break; //Drop Sky Q VLAN 802.1Q packet |
andrewboyson | 33:714a0345e59b | 98 | case 0x887b: break; //Drop Sky Q packet |
andrewboyson | 10:f0854784e960 | 99 | default: |
andrewboyson | 172:9bc3c7b2cca1 | 100 | LogTimeF("ETH protocol %d not handled", EthProtocol); |
andrewboyson | 10:f0854784e960 | 101 | break; |
andrewboyson | 10:f0854784e960 | 102 | } |
andrewboyson | 86:55bc5ddac16c | 103 | if (!action) |
andrewboyson | 86:55bc5ddac16c | 104 | { |
andrewboyson | 142:a8c0890a58d1 | 105 | RestartPoint = lastRestartPoint; |
andrewboyson | 86:55bc5ddac16c | 106 | return DO_NOTHING; |
andrewboyson | 86:55bc5ddac16c | 107 | } |
andrewboyson | 59:e0e556c8bd46 | 108 | |
andrewboyson | 195:bd5b123143ca | 109 | MacMakeFromDest(ActionGetDestPart(action), EthProtocol, EthMacRemote); |
andrewboyson | 136:8a65abb0dc63 | 110 | MacCopy(hdrSrcPtr(pPacketTx), MacLocal); |
andrewboyson | 195:bd5b123143ca | 111 | MacCopy(hdrDstPtr(pPacketTx), EthMacRemote); |
andrewboyson | 172:9bc3c7b2cca1 | 112 | hdrTypSet(pPacketTx, EthProtocol); |
andrewboyson | 10:f0854784e960 | 113 | |
andrewboyson | 136:8a65abb0dc63 | 114 | *pSizeTx = HEADER_LENGTH + dataLengthTx; |
andrewboyson | 37:793b39683406 | 115 | |
andrewboyson | 136:8a65abb0dc63 | 116 | if (ActionGetTracePart(action)) LogHeader(pPacketTx); |
andrewboyson | 37:793b39683406 | 117 | |
andrewboyson | 142:a8c0890a58d1 | 118 | RestartPoint = lastRestartPoint; |
andrewboyson | 10:f0854784e960 | 119 | return action; |
andrewboyson | 10:f0854784e960 | 120 | } |
andrewboyson | 136:8a65abb0dc63 | 121 | int EthPollForPacketToSend(char* pPacket, int* pSize) |
andrewboyson | 10:f0854784e960 | 122 | { |
andrewboyson | 136:8a65abb0dc63 | 123 | char* pData = pPacket + HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 124 | int dataLength = *pSize - HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 125 | if (dataLength > MTU) dataLength = MTU; //Limit the transmitted length to the maximum ethernet frame payload length |
andrewboyson | 10:f0854784e960 | 126 | |
andrewboyson | 10:f0854784e960 | 127 | int action = DO_NOTHING; |
andrewboyson | 172:9bc3c7b2cca1 | 128 | EthProtocol = 0; |
andrewboyson | 47:73af5c0b0dc2 | 129 | if (!action) |
andrewboyson | 10:f0854784e960 | 130 | { |
andrewboyson | 172:9bc3c7b2cca1 | 131 | EthProtocol = ETH_ARP; |
andrewboyson | 22:914b970356f0 | 132 | action = ArpPollForPacketToSend(pData, &dataLength); |
andrewboyson | 22:914b970356f0 | 133 | } |
andrewboyson | 22:914b970356f0 | 134 | |
andrewboyson | 47:73af5c0b0dc2 | 135 | if (!action) |
andrewboyson | 22:914b970356f0 | 136 | { |
andrewboyson | 172:9bc3c7b2cca1 | 137 | EthProtocol = ETH_IPV6; |
andrewboyson | 136:8a65abb0dc63 | 138 | action = Ip6PollForPacketToSend(pData, &dataLength, hdrDstPtr(pPacket)); |
andrewboyson | 10:f0854784e960 | 139 | } |
andrewboyson | 10:f0854784e960 | 140 | |
andrewboyson | 47:73af5c0b0dc2 | 141 | if (!action) |
andrewboyson | 10:f0854784e960 | 142 | { |
andrewboyson | 172:9bc3c7b2cca1 | 143 | EthProtocol = ETH_IPV4; |
andrewboyson | 136:8a65abb0dc63 | 144 | action = Ip4PollForPacketToSend(pData, &dataLength, hdrDstPtr(pPacket)); |
andrewboyson | 10:f0854784e960 | 145 | } |
andrewboyson | 10:f0854784e960 | 146 | |
andrewboyson | 47:73af5c0b0dc2 | 147 | if (!action) return DO_NOTHING; |
andrewboyson | 47:73af5c0b0dc2 | 148 | |
andrewboyson | 172:9bc3c7b2cca1 | 149 | MacMakeFromDest(ActionGetDestPart(action), EthProtocol, hdrDstPtr(pPacket)); |
andrewboyson | 136:8a65abb0dc63 | 150 | MacCopy(hdrSrcPtr(pPacket), MacLocal); |
andrewboyson | 172:9bc3c7b2cca1 | 151 | hdrTypSet(pPacket, EthProtocol); |
andrewboyson | 59:e0e556c8bd46 | 152 | |
andrewboyson | 136:8a65abb0dc63 | 153 | *pSize = HEADER_LENGTH + dataLength; |
andrewboyson | 10:f0854784e960 | 154 | |
andrewboyson | 136:8a65abb0dc63 | 155 | if (ActionGetTracePart(action)) LogHeader(pPacket); |
andrewboyson | 13:9cd54f7db57a | 156 | |
andrewboyson | 10:f0854784e960 | 157 | return action; |
andrewboyson | 10:f0854784e960 | 158 | } |
andrewboyson | 10:f0854784e960 | 159 |