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:
Mon Jul 24 15:27:36 2017 +0000
Revision:
28:edc17eeb4142
Parent:
23:b641979389b2
Child:
33:714a0345e59b
Added check of DHCP MAC address to prevent two systems picking up the same broadcast response.

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 28:edc17eeb4142 79 case 0x6970: break; //Drop Sonos group membership packet
andrewboyson 16:f416ef583c89 80 case 0x7374: break; //Drop Sky Q packet
andrewboyson 16:f416ef583c89 81 case 0x7475: break; //Drop Sky Q packet
andrewboyson 16:f416ef583c89 82 case 0x7380: break; //Drop Sky Q packet
andrewboyson 23:b641979389b2 83 case 0x8100: break; //Drop Sky Q VLAN 802.1Q packet
andrewboyson 10:f0854784e960 84 default:
andrewboyson 13:9cd54f7db57a 85 LogHeader(pHeader, "packet not handled");
andrewboyson 10:f0854784e960 86 break;
andrewboyson 10:f0854784e960 87 }
andrewboyson 10:f0854784e960 88
andrewboyson 14:e75a59c1123d 89 finalisePacket(action, dataLength, pPacket, pSize);
andrewboyson 10:f0854784e960 90 return action;
andrewboyson 10:f0854784e960 91 }
andrewboyson 10:f0854784e960 92 int EthPollForPacketToSend(void* pPacket, int* pSize)
andrewboyson 10:f0854784e960 93 {
andrewboyson 10:f0854784e960 94 struct header * pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 95 void* pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 10:f0854784e960 96
andrewboyson 10:f0854784e960 97 int dataLength = 0;
andrewboyson 14:e75a59c1123d 98 EthProtocol = 0;
andrewboyson 10:f0854784e960 99 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 100
andrewboyson 10:f0854784e960 101 if (action == DO_NOTHING)
andrewboyson 10:f0854784e960 102 {
andrewboyson 22:914b970356f0 103 action = ArpPollForPacketToSend(pData, &dataLength);
andrewboyson 22:914b970356f0 104 EthProtocol = ARP;
andrewboyson 22:914b970356f0 105 }
andrewboyson 22:914b970356f0 106
andrewboyson 22:914b970356f0 107 if (action == DO_NOTHING)
andrewboyson 22:914b970356f0 108 {
andrewboyson 10:f0854784e960 109 action = Ip6PollForPacketToSend(pData, &dataLength, pHeader->dst);
andrewboyson 14:e75a59c1123d 110 EthProtocol = IPV6;
andrewboyson 10:f0854784e960 111 }
andrewboyson 10:f0854784e960 112
andrewboyson 10:f0854784e960 113 if (action == DO_NOTHING)
andrewboyson 10:f0854784e960 114 {
andrewboyson 10:f0854784e960 115 action = Ip4PollForPacketToSend(pData, &dataLength, pHeader->dst);
andrewboyson 14:e75a59c1123d 116 EthProtocol = IPV4;
andrewboyson 10:f0854784e960 117 }
andrewboyson 10:f0854784e960 118
andrewboyson 14:e75a59c1123d 119 finalisePacket(action, dataLength, pPacket, pSize);
andrewboyson 10:f0854784e960 120
andrewboyson 13:9cd54f7db57a 121 if (DEBUG) LogHeader(pHeader, "sent packet");
andrewboyson 13:9cd54f7db57a 122
andrewboyson 10:f0854784e960 123 return action;
andrewboyson 10:f0854784e960 124 }
andrewboyson 10:f0854784e960 125