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

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?

UserRevisionLine numberNew 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