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 05 18:30:37 2018 +0000
Revision:
94:e2973a2c488e
Parent:
86:55bc5ddac16c
Child:
97:d91f7db00235
Fixed bug - incorrect MSS being sent from a polled sync: expected 1440 but had -60. Traced to buffer datalength in EthPollForPacketToSend being set to zero instead of being calculated from the buffer length - headersize.

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 10:f0854784e960 11
andrewboyson 59:e0e556c8bd46 12 #define MTU 1500
andrewboyson 13:9cd54f7db57a 13
andrewboyson 42:222a4f45f916 14 //header variables
andrewboyson 10:f0854784e960 15 __packed struct header
andrewboyson 10:f0854784e960 16 {
andrewboyson 10:f0854784e960 17 char dst[6];
andrewboyson 10:f0854784e960 18 char src[6];
andrewboyson 10:f0854784e960 19 uint16_t typ;
andrewboyson 10:f0854784e960 20 };
andrewboyson 42:222a4f45f916 21 static uint16_t protocol;
andrewboyson 47:73af5c0b0dc2 22 void EthProtocolLog(uint16_t prototype)
andrewboyson 10:f0854784e960 23 {
andrewboyson 14:e75a59c1123d 24 switch (prototype)
andrewboyson 10:f0854784e960 25 {
andrewboyson 47:73af5c0b0dc2 26 case ARP: Log("ARP"); break;
andrewboyson 47:73af5c0b0dc2 27 case IPV4: Log("IPV4"); break;
andrewboyson 47:73af5c0b0dc2 28 case IPV6: Log("IPV6"); break;
andrewboyson 47:73af5c0b0dc2 29 default: LogF("%04hX", prototype); break;
andrewboyson 10:f0854784e960 30 }
andrewboyson 10:f0854784e960 31 }
andrewboyson 37:793b39683406 32 void LogHeader(struct header* pHeader)
andrewboyson 13:9cd54f7db57a 33 {
andrewboyson 43:bc028d5a6424 34 if (NetTraceVerbose)
andrewboyson 43:bc028d5a6424 35 {
andrewboyson 47:73af5c0b0dc2 36 Log("ETH header\r\n");
andrewboyson 47:73af5c0b0dc2 37 Log(" Destination: "); MacLog(pHeader->dst); Log("\r\n");
andrewboyson 47:73af5c0b0dc2 38 Log(" Source: "); MacLog(pHeader->src); Log("\r\n");
andrewboyson 47:73af5c0b0dc2 39 Log(" EtherType: "); EthProtocolLog(NetToHost16(pHeader->typ)); Log("\r\n");
andrewboyson 43:bc028d5a6424 40 }
andrewboyson 43:bc028d5a6424 41 else
andrewboyson 43:bc028d5a6424 42 {
andrewboyson 44:83ce5ace337b 43 Log("ETH header ");
andrewboyson 47:73af5c0b0dc2 44 EthProtocolLog(NetToHost16(pHeader->typ));
andrewboyson 43:bc028d5a6424 45 Log(" ");
andrewboyson 47:73af5c0b0dc2 46 MacLog(pHeader->src);
andrewboyson 43:bc028d5a6424 47 Log(" >>> ");
andrewboyson 47:73af5c0b0dc2 48 MacLog(pHeader->dst);
andrewboyson 43:bc028d5a6424 49 Log("\r\n");
andrewboyson 43:bc028d5a6424 50 }
andrewboyson 13:9cd54f7db57a 51 }
andrewboyson 37:793b39683406 52 static void* tracePacket;
andrewboyson 37:793b39683406 53 static void trace()
andrewboyson 10:f0854784e960 54 {
andrewboyson 61:aad055f1b0d1 55 struct header * pHeader = (struct header*)tracePacket;
andrewboyson 37:793b39683406 56 LogHeader(pHeader);
andrewboyson 37:793b39683406 57 }
andrewboyson 59:e0e556c8bd46 58 int EthHandlePacket(void* pPacketRx, int sizeRx, void* pPacketTx, int* pSizeTx)
andrewboyson 37:793b39683406 59 {
andrewboyson 59:e0e556c8bd46 60 tracePacket = pPacketRx;
andrewboyson 59:e0e556c8bd46 61
andrewboyson 61:aad055f1b0d1 62 struct header * pHeaderRx = (struct header*)pPacketRx;
andrewboyson 61:aad055f1b0d1 63 struct header * pHeaderTx = (struct header*)pPacketTx;
andrewboyson 61:aad055f1b0d1 64 void* pDataRx = (char*)pPacketRx + sizeof(struct header);
andrewboyson 61:aad055f1b0d1 65 void* pDataTx = (char*)pPacketTx + sizeof(struct header);
andrewboyson 61:aad055f1b0d1 66 int dataLengthRx = sizeRx - sizeof(struct header);
andrewboyson 61:aad055f1b0d1 67 int dataLengthTx = *pSizeTx - sizeof(struct header);
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 86:55bc5ddac16c 70 if (!MacAccept(pHeaderRx->dst))
andrewboyson 86:55bc5ddac16c 71 {
andrewboyson 86:55bc5ddac16c 72 return DO_NOTHING;
andrewboyson 86:55bc5ddac16c 73 }
andrewboyson 13:9cd54f7db57a 74
andrewboyson 59:e0e556c8bd46 75 protocol = NetToHost16(pHeaderRx->typ);
andrewboyson 86:55bc5ddac16c 76 if (protocol < 1500)
andrewboyson 86:55bc5ddac16c 77 {
andrewboyson 86:55bc5ddac16c 78 return DO_NOTHING; //drop 802.3 messages
andrewboyson 86:55bc5ddac16c 79 }
andrewboyson 10:f0854784e960 80
andrewboyson 59:e0e556c8bd46 81 NetTraceHostCheckMac(pHeaderRx->src);
andrewboyson 57:e0fb648acf48 82
andrewboyson 10:f0854784e960 83 int action = DO_NOTHING;
andrewboyson 59:e0e556c8bd46 84 char* macRemote = pHeaderRx->src;
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 86:55bc5ddac16c 102 return DO_NOTHING;
andrewboyson 86:55bc5ddac16c 103 }
andrewboyson 59:e0e556c8bd46 104
andrewboyson 59:e0e556c8bd46 105 MacMakeFromDest(ActionGetDestPart(action), protocol, macRemote);
andrewboyson 59:e0e556c8bd46 106 MacCopy(pHeaderTx->src, MacLocal);
andrewboyson 59:e0e556c8bd46 107 MacCopy(pHeaderTx->dst, macRemote);
andrewboyson 59:e0e556c8bd46 108 pHeaderTx->typ = NetToHost16(protocol);
andrewboyson 10:f0854784e960 109
andrewboyson 61:aad055f1b0d1 110 *pSizeTx = sizeof(struct header) + dataLengthTx;
andrewboyson 37:793b39683406 111
andrewboyson 59:e0e556c8bd46 112 if (ActionGetTracePart(action)) LogHeader(pHeaderTx);
andrewboyson 37:793b39683406 113
andrewboyson 10:f0854784e960 114 return action;
andrewboyson 10:f0854784e960 115 }
andrewboyson 10:f0854784e960 116 int EthPollForPacketToSend(void* pPacket, int* pSize)
andrewboyson 10:f0854784e960 117 {
andrewboyson 61:aad055f1b0d1 118 struct header * pHeader = (struct header*)pPacket;
andrewboyson 61:aad055f1b0d1 119 void* pData = (char*)pPacket + sizeof(struct header);
andrewboyson 10:f0854784e960 120
andrewboyson 94:e2973a2c488e 121 int dataLength = *pSize - sizeof(struct header);
andrewboyson 94:e2973a2c488e 122 if (dataLength > MTU) dataLength = MTU; //Limit the transmitted length to the maximum ethernet frame payload length
andrewboyson 42:222a4f45f916 123 protocol = 0;
andrewboyson 10:f0854784e960 124 int action = DO_NOTHING;
andrewboyson 47:73af5c0b0dc2 125 if (!action)
andrewboyson 10:f0854784e960 126 {
andrewboyson 22:914b970356f0 127 action = ArpPollForPacketToSend(pData, &dataLength);
andrewboyson 42:222a4f45f916 128 protocol = ARP;
andrewboyson 22:914b970356f0 129 }
andrewboyson 22:914b970356f0 130
andrewboyson 47:73af5c0b0dc2 131 if (!action)
andrewboyson 22:914b970356f0 132 {
andrewboyson 10:f0854784e960 133 action = Ip6PollForPacketToSend(pData, &dataLength, pHeader->dst);
andrewboyson 42:222a4f45f916 134 protocol = IPV6;
andrewboyson 10:f0854784e960 135 }
andrewboyson 10:f0854784e960 136
andrewboyson 47:73af5c0b0dc2 137 if (!action)
andrewboyson 10:f0854784e960 138 {
andrewboyson 10:f0854784e960 139 action = Ip4PollForPacketToSend(pData, &dataLength, pHeader->dst);
andrewboyson 42:222a4f45f916 140 protocol = IPV4;
andrewboyson 10:f0854784e960 141 }
andrewboyson 10:f0854784e960 142
andrewboyson 47:73af5c0b0dc2 143 if (!action) return DO_NOTHING;
andrewboyson 47:73af5c0b0dc2 144
andrewboyson 59:e0e556c8bd46 145 MacMakeFromDest(ActionGetDestPart(action), protocol, pHeader->dst);
andrewboyson 59:e0e556c8bd46 146 MacCopy(pHeader->src, MacLocal);
andrewboyson 59:e0e556c8bd46 147 pHeader->typ = NetToHost16(protocol);
andrewboyson 59:e0e556c8bd46 148
andrewboyson 61:aad055f1b0d1 149 *pSize = sizeof(struct header) + dataLength;
andrewboyson 10:f0854784e960 150
andrewboyson 37:793b39683406 151 if (ActionGetTracePart(action)) LogHeader(pHeader);
andrewboyson 13:9cd54f7db57a 152
andrewboyson 10:f0854784e960 153 return action;
andrewboyson 10:f0854784e960 154 }
andrewboyson 10:f0854784e960 155