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@97:d91f7db00235, 2019-01-02 (annotated)
- Committer:
- andrewboyson
- Date:
- Wed Jan 02 17:48:38 2019 +0000
- Revision:
- 97:d91f7db00235
- Parent:
- 94:e2973a2c488e
- Child:
- 98:b977424ec7f7
Added fault points
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 | 10:f0854784e960 | 16 | __packed struct header |
andrewboyson | 10:f0854784e960 | 17 | { |
andrewboyson | 10:f0854784e960 | 18 | char dst[6]; |
andrewboyson | 10:f0854784e960 | 19 | char src[6]; |
andrewboyson | 10:f0854784e960 | 20 | uint16_t typ; |
andrewboyson | 10:f0854784e960 | 21 | }; |
andrewboyson | 42:222a4f45f916 | 22 | static uint16_t protocol; |
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 | 37:793b39683406 | 33 | void LogHeader(struct header* pHeader) |
andrewboyson | 13:9cd54f7db57a | 34 | { |
andrewboyson | 43:bc028d5a6424 | 35 | if (NetTraceVerbose) |
andrewboyson | 43:bc028d5a6424 | 36 | { |
andrewboyson | 47:73af5c0b0dc2 | 37 | Log("ETH header\r\n"); |
andrewboyson | 47:73af5c0b0dc2 | 38 | Log(" Destination: "); MacLog(pHeader->dst); Log("\r\n"); |
andrewboyson | 47:73af5c0b0dc2 | 39 | Log(" Source: "); MacLog(pHeader->src); Log("\r\n"); |
andrewboyson | 47:73af5c0b0dc2 | 40 | Log(" EtherType: "); EthProtocolLog(NetToHost16(pHeader->typ)); Log("\r\n"); |
andrewboyson | 43:bc028d5a6424 | 41 | } |
andrewboyson | 43:bc028d5a6424 | 42 | else |
andrewboyson | 43:bc028d5a6424 | 43 | { |
andrewboyson | 44:83ce5ace337b | 44 | Log("ETH header "); |
andrewboyson | 47:73af5c0b0dc2 | 45 | EthProtocolLog(NetToHost16(pHeader->typ)); |
andrewboyson | 43:bc028d5a6424 | 46 | Log(" "); |
andrewboyson | 47:73af5c0b0dc2 | 47 | MacLog(pHeader->src); |
andrewboyson | 43:bc028d5a6424 | 48 | Log(" >>> "); |
andrewboyson | 47:73af5c0b0dc2 | 49 | MacLog(pHeader->dst); |
andrewboyson | 43:bc028d5a6424 | 50 | Log("\r\n"); |
andrewboyson | 43:bc028d5a6424 | 51 | } |
andrewboyson | 13:9cd54f7db57a | 52 | } |
andrewboyson | 37:793b39683406 | 53 | static void* tracePacket; |
andrewboyson | 37:793b39683406 | 54 | static void trace() |
andrewboyson | 10:f0854784e960 | 55 | { |
andrewboyson | 61:aad055f1b0d1 | 56 | struct header * pHeader = (struct header*)tracePacket; |
andrewboyson | 37:793b39683406 | 57 | LogHeader(pHeader); |
andrewboyson | 37:793b39683406 | 58 | } |
andrewboyson | 59:e0e556c8bd46 | 59 | int EthHandlePacket(void* pPacketRx, int sizeRx, void* pPacketTx, int* pSizeTx) |
andrewboyson | 37:793b39683406 | 60 | { |
andrewboyson | 97:d91f7db00235 | 61 | FaultPoint = FAULT_POINT_EthHandlePacket; |
andrewboyson | 97:d91f7db00235 | 62 | |
andrewboyson | 59:e0e556c8bd46 | 63 | tracePacket = pPacketRx; |
andrewboyson | 59:e0e556c8bd46 | 64 | |
andrewboyson | 61:aad055f1b0d1 | 65 | struct header * pHeaderRx = (struct header*)pPacketRx; |
andrewboyson | 61:aad055f1b0d1 | 66 | struct header * pHeaderTx = (struct header*)pPacketTx; |
andrewboyson | 61:aad055f1b0d1 | 67 | void* pDataRx = (char*)pPacketRx + sizeof(struct header); |
andrewboyson | 61:aad055f1b0d1 | 68 | void* pDataTx = (char*)pPacketTx + sizeof(struct header); |
andrewboyson | 61:aad055f1b0d1 | 69 | int dataLengthRx = sizeRx - sizeof(struct header); |
andrewboyson | 61:aad055f1b0d1 | 70 | int dataLengthTx = *pSizeTx - sizeof(struct header); |
andrewboyson | 59:e0e556c8bd46 | 71 | if (dataLengthTx > MTU) dataLengthTx = MTU; //Limit the transmitted length to the maximum ethernet frame payload length |
andrewboyson | 14:e75a59c1123d | 72 | |
andrewboyson | 86:55bc5ddac16c | 73 | if (!MacAccept(pHeaderRx->dst)) |
andrewboyson | 86:55bc5ddac16c | 74 | { |
andrewboyson | 97:d91f7db00235 | 75 | FaultPoint = 0; |
andrewboyson | 86:55bc5ddac16c | 76 | return DO_NOTHING; |
andrewboyson | 86:55bc5ddac16c | 77 | } |
andrewboyson | 13:9cd54f7db57a | 78 | |
andrewboyson | 59:e0e556c8bd46 | 79 | protocol = NetToHost16(pHeaderRx->typ); |
andrewboyson | 86:55bc5ddac16c | 80 | if (protocol < 1500) |
andrewboyson | 86:55bc5ddac16c | 81 | { |
andrewboyson | 97:d91f7db00235 | 82 | FaultPoint = 0; |
andrewboyson | 86:55bc5ddac16c | 83 | return DO_NOTHING; //drop 802.3 messages |
andrewboyson | 86:55bc5ddac16c | 84 | } |
andrewboyson | 10:f0854784e960 | 85 | |
andrewboyson | 59:e0e556c8bd46 | 86 | NetTraceHostCheckMac(pHeaderRx->src); |
andrewboyson | 57:e0fb648acf48 | 87 | |
andrewboyson | 10:f0854784e960 | 88 | int action = DO_NOTHING; |
andrewboyson | 59:e0e556c8bd46 | 89 | char* macRemote = pHeaderRx->src; |
andrewboyson | 42:222a4f45f916 | 90 | switch (protocol) |
andrewboyson | 10:f0854784e960 | 91 | { |
andrewboyson | 59:e0e556c8bd46 | 92 | case ARP: action = ArpHandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx); break; |
andrewboyson | 59:e0e556c8bd46 | 93 | case IPV4: action = Ip4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, macRemote); break; |
andrewboyson | 59:e0e556c8bd46 | 94 | case IPV6: action = Ip6HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, macRemote); break; |
andrewboyson | 28:edc17eeb4142 | 95 | case 0x6970: break; //Drop Sonos group membership packet |
andrewboyson | 16:f416ef583c89 | 96 | case 0x7374: break; //Drop Sky Q packet |
andrewboyson | 16:f416ef583c89 | 97 | case 0x7475: break; //Drop Sky Q packet |
andrewboyson | 16:f416ef583c89 | 98 | case 0x7380: break; //Drop Sky Q packet |
andrewboyson | 23:b641979389b2 | 99 | case 0x8100: break; //Drop Sky Q VLAN 802.1Q packet |
andrewboyson | 33:714a0345e59b | 100 | case 0x887b: break; //Drop Sky Q packet |
andrewboyson | 10:f0854784e960 | 101 | default: |
andrewboyson | 42:222a4f45f916 | 102 | LogTimeF("ETH protocol %d not handled", protocol); |
andrewboyson | 10:f0854784e960 | 103 | break; |
andrewboyson | 10:f0854784e960 | 104 | } |
andrewboyson | 86:55bc5ddac16c | 105 | if (!action) |
andrewboyson | 86:55bc5ddac16c | 106 | { |
andrewboyson | 97:d91f7db00235 | 107 | FaultPoint = 0; |
andrewboyson | 86:55bc5ddac16c | 108 | return DO_NOTHING; |
andrewboyson | 86:55bc5ddac16c | 109 | } |
andrewboyson | 59:e0e556c8bd46 | 110 | |
andrewboyson | 59:e0e556c8bd46 | 111 | MacMakeFromDest(ActionGetDestPart(action), protocol, macRemote); |
andrewboyson | 59:e0e556c8bd46 | 112 | MacCopy(pHeaderTx->src, MacLocal); |
andrewboyson | 59:e0e556c8bd46 | 113 | MacCopy(pHeaderTx->dst, macRemote); |
andrewboyson | 59:e0e556c8bd46 | 114 | pHeaderTx->typ = NetToHost16(protocol); |
andrewboyson | 10:f0854784e960 | 115 | |
andrewboyson | 61:aad055f1b0d1 | 116 | *pSizeTx = sizeof(struct header) + dataLengthTx; |
andrewboyson | 37:793b39683406 | 117 | |
andrewboyson | 59:e0e556c8bd46 | 118 | if (ActionGetTracePart(action)) LogHeader(pHeaderTx); |
andrewboyson | 37:793b39683406 | 119 | |
andrewboyson | 97:d91f7db00235 | 120 | FaultPoint = 0; |
andrewboyson | 10:f0854784e960 | 121 | return action; |
andrewboyson | 10:f0854784e960 | 122 | } |
andrewboyson | 10:f0854784e960 | 123 | int EthPollForPacketToSend(void* pPacket, int* pSize) |
andrewboyson | 10:f0854784e960 | 124 | { |
andrewboyson | 61:aad055f1b0d1 | 125 | struct header * pHeader = (struct header*)pPacket; |
andrewboyson | 61:aad055f1b0d1 | 126 | void* pData = (char*)pPacket + sizeof(struct header); |
andrewboyson | 10:f0854784e960 | 127 | |
andrewboyson | 94:e2973a2c488e | 128 | int dataLength = *pSize - sizeof(struct header); |
andrewboyson | 94:e2973a2c488e | 129 | if (dataLength > MTU) dataLength = MTU; //Limit the transmitted length to the maximum ethernet frame payload length |
andrewboyson | 42:222a4f45f916 | 130 | protocol = 0; |
andrewboyson | 10:f0854784e960 | 131 | int action = DO_NOTHING; |
andrewboyson | 47:73af5c0b0dc2 | 132 | if (!action) |
andrewboyson | 10:f0854784e960 | 133 | { |
andrewboyson | 22:914b970356f0 | 134 | action = ArpPollForPacketToSend(pData, &dataLength); |
andrewboyson | 42:222a4f45f916 | 135 | protocol = ARP; |
andrewboyson | 22:914b970356f0 | 136 | } |
andrewboyson | 22:914b970356f0 | 137 | |
andrewboyson | 47:73af5c0b0dc2 | 138 | if (!action) |
andrewboyson | 22:914b970356f0 | 139 | { |
andrewboyson | 10:f0854784e960 | 140 | action = Ip6PollForPacketToSend(pData, &dataLength, pHeader->dst); |
andrewboyson | 42:222a4f45f916 | 141 | protocol = IPV6; |
andrewboyson | 10:f0854784e960 | 142 | } |
andrewboyson | 10:f0854784e960 | 143 | |
andrewboyson | 47:73af5c0b0dc2 | 144 | if (!action) |
andrewboyson | 10:f0854784e960 | 145 | { |
andrewboyson | 10:f0854784e960 | 146 | action = Ip4PollForPacketToSend(pData, &dataLength, pHeader->dst); |
andrewboyson | 42:222a4f45f916 | 147 | protocol = IPV4; |
andrewboyson | 10:f0854784e960 | 148 | } |
andrewboyson | 10:f0854784e960 | 149 | |
andrewboyson | 47:73af5c0b0dc2 | 150 | if (!action) return DO_NOTHING; |
andrewboyson | 47:73af5c0b0dc2 | 151 | |
andrewboyson | 59:e0e556c8bd46 | 152 | MacMakeFromDest(ActionGetDestPart(action), protocol, pHeader->dst); |
andrewboyson | 59:e0e556c8bd46 | 153 | MacCopy(pHeader->src, MacLocal); |
andrewboyson | 59:e0e556c8bd46 | 154 | pHeader->typ = NetToHost16(protocol); |
andrewboyson | 59:e0e556c8bd46 | 155 | |
andrewboyson | 61:aad055f1b0d1 | 156 | *pSize = sizeof(struct header) + dataLength; |
andrewboyson | 10:f0854784e960 | 157 | |
andrewboyson | 37:793b39683406 | 158 | if (ActionGetTracePart(action)) LogHeader(pHeader); |
andrewboyson | 13:9cd54f7db57a | 159 | |
andrewboyson | 10:f0854784e960 | 160 | return action; |
andrewboyson | 10:f0854784e960 | 161 | } |
andrewboyson | 10:f0854784e960 | 162 |