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:
Fri May 05 17:44:16 2017 +0000
Revision:
14:e75a59c1123d
Parent:
13:9cd54f7db57a
Child:
16:f416ef583c89
Made IP addresses and ports available to debug messages

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 10:f0854784e960 1 #include "mbed.h"
andrewboyson 10:f0854784e960 2 #include "io.h"
andrewboyson 10:f0854784e960 3 #include "log.h"
andrewboyson 10:f0854784e960 4 #include "net.h"
andrewboyson 10:f0854784e960 5 #include "arp.h"
andrewboyson 10:f0854784e960 6 #include "ip4.h"
andrewboyson 10:f0854784e960 7 #include "ip6.h"
andrewboyson 10:f0854784e960 8 #include "phy.h"
andrewboyson 10:f0854784e960 9 #include "eth.h"
andrewboyson 13:9cd54f7db57a 10 #include "mac.h"
andrewboyson 10:f0854784e960 11
andrewboyson 10:f0854784e960 12 #define HEADER_SIZE 14
andrewboyson 13:9cd54f7db57a 13
andrewboyson 13:9cd54f7db57a 14 #define DEBUG false
andrewboyson 13:9cd54f7db57a 15
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 10:f0854784e960 22
andrewboyson 14:e75a59c1123d 23 uint16_t EthProtocol;
andrewboyson 14:e75a59c1123d 24
andrewboyson 14:e75a59c1123d 25 void EthProtocolToString(uint16_t prototype, int size, char* text)
andrewboyson 10:f0854784e960 26 {
andrewboyson 14:e75a59c1123d 27 switch (prototype)
andrewboyson 10:f0854784e960 28 {
andrewboyson 10:f0854784e960 29 case ARP: strncpy (text, "ARP" , size); break;
andrewboyson 10:f0854784e960 30 case IPV4: strncpy (text, "IPV4", size); break;
andrewboyson 10:f0854784e960 31 case IPV6: strncpy (text, "IPV6", size); break;
andrewboyson 14:e75a59c1123d 32 default: snprintf(text, size, "%04hX", prototype); break;
andrewboyson 10:f0854784e960 33 }
andrewboyson 10:f0854784e960 34 }
andrewboyson 10:f0854784e960 35
andrewboyson 14:e75a59c1123d 36 static void finalisePacket(int action, int dataLength, void* pPacket, int* pSize)
andrewboyson 10:f0854784e960 37 {
andrewboyson 14:e75a59c1123d 38 if (!action) return;
andrewboyson 14:e75a59c1123d 39
andrewboyson 10:f0854784e960 40 struct header * pHeader = (header*)pPacket;
andrewboyson 14:e75a59c1123d 41
andrewboyson 14:e75a59c1123d 42 MacMake(action, EthProtocol, pHeader->dst);
andrewboyson 10:f0854784e960 43
andrewboyson 13:9cd54f7db57a 44 memcpy(pHeader->src, MacLocal, 6); //Put our MAC into the source
andrewboyson 14:e75a59c1123d 45 pHeader->typ = NetToHost16(EthProtocol);
andrewboyson 10:f0854784e960 46
andrewboyson 10:f0854784e960 47 *pSize = HEADER_SIZE + dataLength;
andrewboyson 10:f0854784e960 48 }
andrewboyson 13:9cd54f7db57a 49 void LogHeader(struct header* pHeader, char* title)
andrewboyson 13:9cd54f7db57a 50 {
andrewboyson 13:9cd54f7db57a 51 char text[20];
andrewboyson 13:9cd54f7db57a 52 LogTimeF("ETH %s\r\n", title);
andrewboyson 14:e75a59c1123d 53 MacToString(pHeader->dst, sizeof(text), text);
andrewboyson 13:9cd54f7db57a 54 LogTimeF("Destination: %s\r\n", text);
andrewboyson 14:e75a59c1123d 55 MacToString(pHeader->src, sizeof(text), text);
andrewboyson 13:9cd54f7db57a 56 LogTimeF("Source: %s\r\n", text);
andrewboyson 14:e75a59c1123d 57 EthProtocolToString(NetToHost16(pHeader->typ), sizeof(text), text);
andrewboyson 13:9cd54f7db57a 58 LogTimeF("EtherType: %s\r\n", text);
andrewboyson 13:9cd54f7db57a 59 }
andrewboyson 10:f0854784e960 60 int EthHandlePacket(void* pPacket, int* pSize)
andrewboyson 10:f0854784e960 61 {
andrewboyson 10:f0854784e960 62 struct header * pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 63 int dataLength = *pSize - HEADER_SIZE;
andrewboyson 10:f0854784e960 64 void* pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 14:e75a59c1123d 65
andrewboyson 14:e75a59c1123d 66 if (!MacAccept(pHeader->dst)) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 67
andrewboyson 13:9cd54f7db57a 68 if (DEBUG) LogHeader(pHeader, "received packet");
andrewboyson 10:f0854784e960 69
andrewboyson 14:e75a59c1123d 70 EthProtocol = NetToHost16(pHeader->typ);
andrewboyson 14:e75a59c1123d 71 if (EthProtocol < 1500) return DO_NOTHING; //drop 802.3 messages
andrewboyson 10:f0854784e960 72
andrewboyson 10:f0854784e960 73 int action = DO_NOTHING;
andrewboyson 14:e75a59c1123d 74 switch (EthProtocol)
andrewboyson 10:f0854784e960 75 {
andrewboyson 10:f0854784e960 76 case ARP: action = ArpHandleReceivedPacket(pHeader->src, pData, &dataLength, pHeader->dst); break;
andrewboyson 10:f0854784e960 77 case IPV4: action = Ip4HandleReceivedPacket(pHeader->src, pData, &dataLength, pHeader->dst); break;
andrewboyson 10:f0854784e960 78 case IPV6: action = Ip6HandleReceivedPacket(pHeader->src, pData, &dataLength, pHeader->dst); break;
andrewboyson 10:f0854784e960 79 default:
andrewboyson 13:9cd54f7db57a 80 LogHeader(pHeader, "packet not handled");
andrewboyson 10:f0854784e960 81 break;
andrewboyson 10:f0854784e960 82 }
andrewboyson 10:f0854784e960 83
andrewboyson 14:e75a59c1123d 84 finalisePacket(action, dataLength, pPacket, pSize);
andrewboyson 10:f0854784e960 85 return action;
andrewboyson 10:f0854784e960 86 }
andrewboyson 10:f0854784e960 87 int EthPollForPacketToSend(void* pPacket, int* pSize)
andrewboyson 10:f0854784e960 88 {
andrewboyson 10:f0854784e960 89 struct header * pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 90 void* pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 10:f0854784e960 91
andrewboyson 10:f0854784e960 92 int dataLength = 0;
andrewboyson 14:e75a59c1123d 93 EthProtocol = 0;
andrewboyson 10:f0854784e960 94 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 95
andrewboyson 10:f0854784e960 96 if (action == DO_NOTHING)
andrewboyson 10:f0854784e960 97 {
andrewboyson 10:f0854784e960 98 action = Ip6PollForPacketToSend(pData, &dataLength, pHeader->dst);
andrewboyson 14:e75a59c1123d 99 EthProtocol = IPV6;
andrewboyson 10:f0854784e960 100 }
andrewboyson 10:f0854784e960 101
andrewboyson 10:f0854784e960 102 if (action == DO_NOTHING)
andrewboyson 10:f0854784e960 103 {
andrewboyson 10:f0854784e960 104 action = Ip4PollForPacketToSend(pData, &dataLength, pHeader->dst);
andrewboyson 14:e75a59c1123d 105 EthProtocol = IPV4;
andrewboyson 10:f0854784e960 106 }
andrewboyson 10:f0854784e960 107
andrewboyson 14:e75a59c1123d 108 finalisePacket(action, dataLength, pPacket, pSize);
andrewboyson 10:f0854784e960 109
andrewboyson 13:9cd54f7db57a 110 if (DEBUG) LogHeader(pHeader, "sent packet");
andrewboyson 13:9cd54f7db57a 111
andrewboyson 10:f0854784e960 112 return action;
andrewboyson 10:f0854784e960 113 }
andrewboyson 10:f0854784e960 114