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@172:9bc3c7b2cca1, 2020-12-16 (annotated)
- Committer:
- andrewboyson
- Date:
- Wed Dec 16 17:33:22 2020 +0000
- Revision:
- 172:9bc3c7b2cca1
- Parent:
- 171:f708d6776752
- Child:
- 195:bd5b123143ca
Modified name resolution to work with both IPv4 and IPv6. Before there were two independent modules.
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 | 172:9bc3c7b2cca1 | 16 | |
andrewboyson | 42:222a4f45f916 | 17 | //header variables |
andrewboyson | 136:8a65abb0dc63 | 18 | static char* hdrDstPtr(char* pPacket) { return pPacket + 0; } |
andrewboyson | 136:8a65abb0dc63 | 19 | static char* hdrSrcPtr(char* pPacket) { return pPacket + 6; } |
andrewboyson | 136:8a65abb0dc63 | 20 | static char* hdrTypPtr(char* pPacket) { return pPacket + 12; } |
andrewboyson | 136:8a65abb0dc63 | 21 | #define HEADER_LENGTH 14 |
andrewboyson | 136:8a65abb0dc63 | 22 | static uint16_t hdrTypGet(char* pPacket) { uint16_t res; NetInvert16(&res, hdrTypPtr(pPacket) ); return res; } |
andrewboyson | 136:8a65abb0dc63 | 23 | static void hdrTypSet(char* pPacket, uint16_t value) { NetInvert16( hdrTypPtr(pPacket), &value); } |
andrewboyson | 136:8a65abb0dc63 | 24 | |
andrewboyson | 171:f708d6776752 | 25 | void EthProtocolLog(uint16_t protocol) |
andrewboyson | 10:f0854784e960 | 26 | { |
andrewboyson | 171:f708d6776752 | 27 | switch (protocol) |
andrewboyson | 10:f0854784e960 | 28 | { |
andrewboyson | 172:9bc3c7b2cca1 | 29 | case ETH_ARP: Log("ARP"); break; |
andrewboyson | 172:9bc3c7b2cca1 | 30 | case ETH_IPV4: Log("IPV4"); break; |
andrewboyson | 172:9bc3c7b2cca1 | 31 | case ETH_IPV6: Log("IPV6"); break; |
andrewboyson | 172:9bc3c7b2cca1 | 32 | default: LogF("%04hX", protocol); break; |
andrewboyson | 10:f0854784e960 | 33 | } |
andrewboyson | 10:f0854784e960 | 34 | } |
andrewboyson | 136:8a65abb0dc63 | 35 | void LogHeader(char* pPacket) |
andrewboyson | 13:9cd54f7db57a | 36 | { |
andrewboyson | 43:bc028d5a6424 | 37 | if (NetTraceVerbose) |
andrewboyson | 43:bc028d5a6424 | 38 | { |
andrewboyson | 47:73af5c0b0dc2 | 39 | Log("ETH header\r\n"); |
andrewboyson | 136:8a65abb0dc63 | 40 | Log(" Destination: "); MacLog(hdrDstPtr(pPacket)); Log("\r\n"); |
andrewboyson | 136:8a65abb0dc63 | 41 | Log(" Source: "); MacLog(hdrSrcPtr(pPacket)); Log("\r\n"); |
andrewboyson | 136:8a65abb0dc63 | 42 | Log(" EtherType: "); EthProtocolLog(hdrTypGet(pPacket)); Log("\r\n"); |
andrewboyson | 43:bc028d5a6424 | 43 | } |
andrewboyson | 43:bc028d5a6424 | 44 | else |
andrewboyson | 43:bc028d5a6424 | 45 | { |
andrewboyson | 44:83ce5ace337b | 46 | Log("ETH header "); |
andrewboyson | 136:8a65abb0dc63 | 47 | EthProtocolLog(hdrTypGet(pPacket)); |
andrewboyson | 43:bc028d5a6424 | 48 | Log(" "); |
andrewboyson | 136:8a65abb0dc63 | 49 | MacLog(hdrSrcPtr(pPacket)); |
andrewboyson | 43:bc028d5a6424 | 50 | Log(" >>> "); |
andrewboyson | 136:8a65abb0dc63 | 51 | MacLog(hdrDstPtr(pPacket)); |
andrewboyson | 43:bc028d5a6424 | 52 | Log("\r\n"); |
andrewboyson | 43:bc028d5a6424 | 53 | } |
andrewboyson | 13:9cd54f7db57a | 54 | } |
andrewboyson | 136:8a65abb0dc63 | 55 | static char* tracePacket; |
andrewboyson | 136:8a65abb0dc63 | 56 | static void trace() { LogHeader(tracePacket); } |
andrewboyson | 136:8a65abb0dc63 | 57 | int EthHandlePacket(char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx) |
andrewboyson | 37:793b39683406 | 58 | { |
andrewboyson | 142:a8c0890a58d1 | 59 | int lastRestartPoint = RestartPoint; |
andrewboyson | 142:a8c0890a58d1 | 60 | RestartPoint = FAULT_POINT_EthHandlePacket; |
andrewboyson | 97:d91f7db00235 | 61 | |
andrewboyson | 59:e0e556c8bd46 | 62 | tracePacket = pPacketRx; |
andrewboyson | 59:e0e556c8bd46 | 63 | |
andrewboyson | 136:8a65abb0dc63 | 64 | char* pDataRx = pPacketRx + HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 65 | char* pDataTx = pPacketTx + HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 66 | int dataLengthRx = sizeRx - HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 67 | int dataLengthTx = *pSizeTx - HEADER_LENGTH; |
andrewboyson | 59:e0e556c8bd46 | 68 | if (dataLengthTx > MTU) dataLengthTx = MTU; //Limit the transmitted length to the maximum ethernet frame payload length |
andrewboyson | 14:e75a59c1123d | 69 | |
andrewboyson | 136:8a65abb0dc63 | 70 | if (!MacAccept(hdrDstPtr(pPacketRx))) |
andrewboyson | 86:55bc5ddac16c | 71 | { |
andrewboyson | 142:a8c0890a58d1 | 72 | RestartPoint = lastRestartPoint; |
andrewboyson | 86:55bc5ddac16c | 73 | return DO_NOTHING; |
andrewboyson | 86:55bc5ddac16c | 74 | } |
andrewboyson | 13:9cd54f7db57a | 75 | |
andrewboyson | 172:9bc3c7b2cca1 | 76 | EthProtocol = hdrTypGet(pPacketRx); |
andrewboyson | 172:9bc3c7b2cca1 | 77 | if (EthProtocol < 1500) |
andrewboyson | 86:55bc5ddac16c | 78 | { |
andrewboyson | 142:a8c0890a58d1 | 79 | RestartPoint = lastRestartPoint; |
andrewboyson | 86:55bc5ddac16c | 80 | return DO_NOTHING; //drop 802.3 messages |
andrewboyson | 86:55bc5ddac16c | 81 | } |
andrewboyson | 10:f0854784e960 | 82 | |
andrewboyson | 136:8a65abb0dc63 | 83 | NetTraceHostCheckMac(hdrSrcPtr(pPacketRx)); |
andrewboyson | 57:e0fb648acf48 | 84 | |
andrewboyson | 10:f0854784e960 | 85 | int action = DO_NOTHING; |
andrewboyson | 136:8a65abb0dc63 | 86 | char* macRemote = hdrSrcPtr(pPacketRx); |
andrewboyson | 172:9bc3c7b2cca1 | 87 | switch (EthProtocol) |
andrewboyson | 10:f0854784e960 | 88 | { |
andrewboyson | 172:9bc3c7b2cca1 | 89 | case ETH_ARP: action = ArpHandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx); break; |
andrewboyson | 172:9bc3c7b2cca1 | 90 | case ETH_IPV4: action = Ip4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, macRemote); break; |
andrewboyson | 172:9bc3c7b2cca1 | 91 | case ETH_IPV6: action = Ip6HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, macRemote); break; |
andrewboyson | 28:edc17eeb4142 | 92 | case 0x6970: break; //Drop Sonos group membership packet |
andrewboyson | 16:f416ef583c89 | 93 | case 0x7374: break; //Drop Sky Q packet |
andrewboyson | 16:f416ef583c89 | 94 | case 0x7475: break; //Drop Sky Q packet |
andrewboyson | 16:f416ef583c89 | 95 | case 0x7380: break; //Drop Sky Q packet |
andrewboyson | 23:b641979389b2 | 96 | case 0x8100: break; //Drop Sky Q VLAN 802.1Q packet |
andrewboyson | 33:714a0345e59b | 97 | case 0x887b: break; //Drop Sky Q packet |
andrewboyson | 10:f0854784e960 | 98 | default: |
andrewboyson | 172:9bc3c7b2cca1 | 99 | LogTimeF("ETH protocol %d not handled", EthProtocol); |
andrewboyson | 10:f0854784e960 | 100 | break; |
andrewboyson | 10:f0854784e960 | 101 | } |
andrewboyson | 86:55bc5ddac16c | 102 | if (!action) |
andrewboyson | 86:55bc5ddac16c | 103 | { |
andrewboyson | 142:a8c0890a58d1 | 104 | RestartPoint = lastRestartPoint; |
andrewboyson | 86:55bc5ddac16c | 105 | return DO_NOTHING; |
andrewboyson | 86:55bc5ddac16c | 106 | } |
andrewboyson | 59:e0e556c8bd46 | 107 | |
andrewboyson | 172:9bc3c7b2cca1 | 108 | MacMakeFromDest(ActionGetDestPart(action), EthProtocol, macRemote); |
andrewboyson | 136:8a65abb0dc63 | 109 | MacCopy(hdrSrcPtr(pPacketTx), MacLocal); |
andrewboyson | 136:8a65abb0dc63 | 110 | MacCopy(hdrDstPtr(pPacketTx), macRemote); |
andrewboyson | 172:9bc3c7b2cca1 | 111 | hdrTypSet(pPacketTx, EthProtocol); |
andrewboyson | 10:f0854784e960 | 112 | |
andrewboyson | 136:8a65abb0dc63 | 113 | *pSizeTx = HEADER_LENGTH + dataLengthTx; |
andrewboyson | 37:793b39683406 | 114 | |
andrewboyson | 136:8a65abb0dc63 | 115 | if (ActionGetTracePart(action)) LogHeader(pPacketTx); |
andrewboyson | 37:793b39683406 | 116 | |
andrewboyson | 142:a8c0890a58d1 | 117 | RestartPoint = lastRestartPoint; |
andrewboyson | 10:f0854784e960 | 118 | return action; |
andrewboyson | 10:f0854784e960 | 119 | } |
andrewboyson | 136:8a65abb0dc63 | 120 | int EthPollForPacketToSend(char* pPacket, int* pSize) |
andrewboyson | 10:f0854784e960 | 121 | { |
andrewboyson | 136:8a65abb0dc63 | 122 | char* pData = pPacket + HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 123 | int dataLength = *pSize - HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 124 | if (dataLength > MTU) dataLength = MTU; //Limit the transmitted length to the maximum ethernet frame payload length |
andrewboyson | 10:f0854784e960 | 125 | |
andrewboyson | 10:f0854784e960 | 126 | int action = DO_NOTHING; |
andrewboyson | 172:9bc3c7b2cca1 | 127 | EthProtocol = 0; |
andrewboyson | 47:73af5c0b0dc2 | 128 | if (!action) |
andrewboyson | 10:f0854784e960 | 129 | { |
andrewboyson | 172:9bc3c7b2cca1 | 130 | EthProtocol = ETH_ARP; |
andrewboyson | 22:914b970356f0 | 131 | action = ArpPollForPacketToSend(pData, &dataLength); |
andrewboyson | 22:914b970356f0 | 132 | } |
andrewboyson | 22:914b970356f0 | 133 | |
andrewboyson | 47:73af5c0b0dc2 | 134 | if (!action) |
andrewboyson | 22:914b970356f0 | 135 | { |
andrewboyson | 172:9bc3c7b2cca1 | 136 | EthProtocol = ETH_IPV6; |
andrewboyson | 136:8a65abb0dc63 | 137 | action = Ip6PollForPacketToSend(pData, &dataLength, hdrDstPtr(pPacket)); |
andrewboyson | 10:f0854784e960 | 138 | } |
andrewboyson | 10:f0854784e960 | 139 | |
andrewboyson | 47:73af5c0b0dc2 | 140 | if (!action) |
andrewboyson | 10:f0854784e960 | 141 | { |
andrewboyson | 172:9bc3c7b2cca1 | 142 | EthProtocol = ETH_IPV4; |
andrewboyson | 136:8a65abb0dc63 | 143 | action = Ip4PollForPacketToSend(pData, &dataLength, hdrDstPtr(pPacket)); |
andrewboyson | 10:f0854784e960 | 144 | } |
andrewboyson | 10:f0854784e960 | 145 | |
andrewboyson | 47:73af5c0b0dc2 | 146 | if (!action) return DO_NOTHING; |
andrewboyson | 47:73af5c0b0dc2 | 147 | |
andrewboyson | 172:9bc3c7b2cca1 | 148 | MacMakeFromDest(ActionGetDestPart(action), EthProtocol, hdrDstPtr(pPacket)); |
andrewboyson | 136:8a65abb0dc63 | 149 | MacCopy(hdrSrcPtr(pPacket), MacLocal); |
andrewboyson | 172:9bc3c7b2cca1 | 150 | hdrTypSet(pPacket, EthProtocol); |
andrewboyson | 59:e0e556c8bd46 | 151 | |
andrewboyson | 136:8a65abb0dc63 | 152 | *pSize = HEADER_LENGTH + dataLength; |
andrewboyson | 10:f0854784e960 | 153 | |
andrewboyson | 136:8a65abb0dc63 | 154 | if (ActionGetTracePart(action)) LogHeader(pPacket); |
andrewboyson | 13:9cd54f7db57a | 155 | |
andrewboyson | 10:f0854784e960 | 156 | return action; |
andrewboyson | 10:f0854784e960 | 157 | } |
andrewboyson | 10:f0854784e960 | 158 |