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@171:f708d6776752, 2020-12-12 (annotated)
- Committer:
- andrewboyson
- Date:
- Sat Dec 12 20:10:02 2020 +0000
- Revision:
- 171:f708d6776752
- Parent:
- 142:a8c0890a58d1
- Child:
- 172:9bc3c7b2cca1
Modified NR to accept both IPV6 and IPV4 addresses instead of having two modules with diffrent address lengths. Encapsulated 32but address into lsb 128 bit address
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 | 171:f708d6776752 | 23 | void EthProtocolLog(uint16_t protocol) |
andrewboyson | 10:f0854784e960 | 24 | { |
andrewboyson | 171:f708d6776752 | 25 | switch (protocol) |
andrewboyson | 10:f0854784e960 | 26 | { |
andrewboyson | 171:f708d6776752 | 27 | case ARP: Log("ARP"); break; |
andrewboyson | 171:f708d6776752 | 28 | case IPV4: Log("IPV4"); break; |
andrewboyson | 171:f708d6776752 | 29 | case IPV6: Log("IPV6"); break; |
andrewboyson | 171:f708d6776752 | 30 | default: LogF("%04hX", protocol); 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 |