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