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@136:8a65abb0dc63, 2019-04-06 (annotated)
- Committer:
- andrewboyson
- Date:
- Sat Apr 06 11:20:20 2019 +0000
- Revision:
- 136:8a65abb0dc63
- Parent:
- 98:b977424ec7f7
- Child:
- 142:a8c0890a58d1
Part way through replacing __packed with byte copy access to the headers.
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 | 97:d91f7db00235 | 11 | #include "fault.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 | 98:b977424ec7f7 | 57 | int lastFaultPoint = FaultPoint; |
andrewboyson | 97:d91f7db00235 | 58 | FaultPoint = 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 | 98:b977424ec7f7 | 70 | FaultPoint = lastFaultPoint; |
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 | 98:b977424ec7f7 | 77 | FaultPoint = lastFaultPoint; |
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 | 98:b977424ec7f7 | 102 | FaultPoint = lastFaultPoint; |
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 | 98:b977424ec7f7 | 115 | FaultPoint = lastFaultPoint; |
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 |