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 May 01 18:20:55 2017 +0000
Revision:
13:9cd54f7db57a
Parent:
11:c051adb70c5a
Child:
14:e75a59c1123d
Added ability to read DNS queries with encoded IP addresses

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 10:f0854784e960 23 static void typeToString(uint16_t type, int size, char* text)
andrewboyson 10:f0854784e960 24 {
andrewboyson 10:f0854784e960 25 switch (type)
andrewboyson 10:f0854784e960 26 {
andrewboyson 10:f0854784e960 27 case ARP: strncpy (text, "ARP" , size); break;
andrewboyson 10:f0854784e960 28 case IPV4: strncpy (text, "IPV4", size); break;
andrewboyson 10:f0854784e960 29 case IPV6: strncpy (text, "IPV6", size); break;
andrewboyson 10:f0854784e960 30 default: snprintf(text, size, "%04hX", type); break;
andrewboyson 10:f0854784e960 31 }
andrewboyson 10:f0854784e960 32 }
andrewboyson 10:f0854784e960 33
andrewboyson 10:f0854784e960 34 static void finalisePacket(int action, int type, int dataLength, void* pPacket, int* pSize)
andrewboyson 10:f0854784e960 35 {
andrewboyson 10:f0854784e960 36 struct header * pHeader = (header*)pPacket;
andrewboyson 11:c051adb70c5a 37
andrewboyson 11:c051adb70c5a 38 if (!action) return;
andrewboyson 10:f0854784e960 39
andrewboyson 10:f0854784e960 40 switch (action)
andrewboyson 10:f0854784e960 41 {
andrewboyson 10:f0854784e960 42 case DO_NOTHING:
andrewboyson 10:f0854784e960 43 return;
andrewboyson 10:f0854784e960 44 case UNICAST:
andrewboyson 10:f0854784e960 45 case UNICAST_DNS:
andrewboyson 10:f0854784e960 46 case UNICAST_DHCP:
andrewboyson 10:f0854784e960 47 break;
andrewboyson 10:f0854784e960 48 case MULTICAST_NODE:
andrewboyson 13:9cd54f7db57a 49 if (type == IPV6) MacMakeMulticastNode6(pHeader->dst);
andrewboyson 13:9cd54f7db57a 50 else MacMakeMulticastNode4(pHeader->dst);
andrewboyson 10:f0854784e960 51 break;
andrewboyson 10:f0854784e960 52 case MULTICAST_ROUTER:
andrewboyson 13:9cd54f7db57a 53 if (type == IPV6) MacMakeMulticastRouter6(pHeader->dst);
andrewboyson 13:9cd54f7db57a 54 else MacMakeMulticastRouter4(pHeader->dst);
andrewboyson 10:f0854784e960 55 break;
andrewboyson 10:f0854784e960 56 case MULTICAST_MDNS:
andrewboyson 13:9cd54f7db57a 57 if (type == IPV6) MacMakeMulticastMdns6(pHeader->dst);
andrewboyson 13:9cd54f7db57a 58 else MacMakeMulticastMdns4(pHeader->dst);
andrewboyson 10:f0854784e960 59 break;
andrewboyson 10:f0854784e960 60 case MULTICAST_LLMNR:
andrewboyson 13:9cd54f7db57a 61 if (type == IPV6) MacMakeMulticastLlmnr6(pHeader->dst);
andrewboyson 13:9cd54f7db57a 62 else MacMakeMulticastLlmnr4(pHeader->dst);
andrewboyson 10:f0854784e960 63 break;
andrewboyson 10:f0854784e960 64 case BROADCAST:
andrewboyson 13:9cd54f7db57a 65 MacMakeBroadcast(pHeader->dst);
andrewboyson 10:f0854784e960 66 break;
andrewboyson 10:f0854784e960 67 default:
andrewboyson 10:f0854784e960 68 LogTimeF("Unknown ETH action %d\r\n", action);
andrewboyson 10:f0854784e960 69 return;
andrewboyson 10:f0854784e960 70 }
andrewboyson 13:9cd54f7db57a 71 memcpy(pHeader->src, MacLocal, 6); //Put our MAC into the source
andrewboyson 10:f0854784e960 72 pHeader->typ = NetToHost16(type);
andrewboyson 10:f0854784e960 73
andrewboyson 10:f0854784e960 74 *pSize = HEADER_SIZE + dataLength;
andrewboyson 10:f0854784e960 75 }
andrewboyson 13:9cd54f7db57a 76 void LogHeader(struct header* pHeader, char* title)
andrewboyson 13:9cd54f7db57a 77 {
andrewboyson 13:9cd54f7db57a 78 char text[20];
andrewboyson 13:9cd54f7db57a 79 LogTimeF("ETH %s\r\n", title);
andrewboyson 13:9cd54f7db57a 80 NetMacToString(pHeader->dst, sizeof(text), text);
andrewboyson 13:9cd54f7db57a 81 LogTimeF("Destination: %s\r\n", text);
andrewboyson 13:9cd54f7db57a 82 NetMacToString(pHeader->src, sizeof(text), text);
andrewboyson 13:9cd54f7db57a 83 LogTimeF("Source: %s\r\n", text);
andrewboyson 13:9cd54f7db57a 84 typeToString(NetToHost16(pHeader->typ), sizeof(text), text);
andrewboyson 13:9cd54f7db57a 85 LogTimeF("EtherType: %s\r\n", text);
andrewboyson 13:9cd54f7db57a 86 }
andrewboyson 10:f0854784e960 87 int EthHandlePacket(void* pPacket, int* pSize)
andrewboyson 10:f0854784e960 88 {
andrewboyson 10:f0854784e960 89 struct header * pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 90 int dataLength = *pSize - HEADER_SIZE;
andrewboyson 10:f0854784e960 91 void* pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 10:f0854784e960 92
andrewboyson 13:9cd54f7db57a 93 bool doIt = MacCompareUnicastLocal (pHeader->dst) || MacCompareBroadcast (pHeader->dst) ||
andrewboyson 13:9cd54f7db57a 94 MacCompareMulticastLocal4 (pHeader->dst) || MacCompareMulticastLocal6 (pHeader->dst) ||
andrewboyson 13:9cd54f7db57a 95 MacCompareMulticastAllNodes4 (pHeader->dst) || MacCompareMulticastAllNodes6 (pHeader->dst) ||
andrewboyson 13:9cd54f7db57a 96 MacCompareMulticastAllRouters4(pHeader->dst) || MacCompareMulticastAllRouters6(pHeader->dst) ||
andrewboyson 13:9cd54f7db57a 97 MacCompareMulticastMdns4 (pHeader->dst) || MacCompareMulticastMdns6 (pHeader->dst) ||
andrewboyson 13:9cd54f7db57a 98 MacCompareMulticastLlmnr4 (pHeader->dst) || MacCompareMulticastLlmnr6 (pHeader->dst);
andrewboyson 10:f0854784e960 99
andrewboyson 10:f0854784e960 100 if (!doIt) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 101
andrewboyson 13:9cd54f7db57a 102 if (DEBUG) LogHeader(pHeader, "received packet");
andrewboyson 10:f0854784e960 103
andrewboyson 10:f0854784e960 104 uint16_t type = NetToHost16(pHeader->typ);
andrewboyson 10:f0854784e960 105 if (type < 1500) return DO_NOTHING; //drop 802.3 messages
andrewboyson 10:f0854784e960 106
andrewboyson 10:f0854784e960 107 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 108 switch (type)
andrewboyson 10:f0854784e960 109 {
andrewboyson 10:f0854784e960 110 case ARP: action = ArpHandleReceivedPacket(pHeader->src, pData, &dataLength, pHeader->dst); break;
andrewboyson 10:f0854784e960 111 case IPV4: action = Ip4HandleReceivedPacket(pHeader->src, pData, &dataLength, pHeader->dst); break;
andrewboyson 10:f0854784e960 112 case IPV6: action = Ip6HandleReceivedPacket(pHeader->src, pData, &dataLength, pHeader->dst); break;
andrewboyson 10:f0854784e960 113 default:
andrewboyson 13:9cd54f7db57a 114 LogHeader(pHeader, "packet not handled");
andrewboyson 10:f0854784e960 115 break;
andrewboyson 10:f0854784e960 116 }
andrewboyson 10:f0854784e960 117
andrewboyson 10:f0854784e960 118 finalisePacket(action, type, dataLength, pPacket, pSize);
andrewboyson 10:f0854784e960 119 return action;
andrewboyson 10:f0854784e960 120 }
andrewboyson 10:f0854784e960 121 int EthPollForPacketToSend(void* pPacket, int* pSize)
andrewboyson 10:f0854784e960 122 {
andrewboyson 10:f0854784e960 123 struct header * pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 124 void* pData = (char*)pPacket + HEADER_SIZE;
andrewboyson 10:f0854784e960 125
andrewboyson 10:f0854784e960 126 int dataLength = 0;
andrewboyson 10:f0854784e960 127 int type = 0;
andrewboyson 10:f0854784e960 128 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 129
andrewboyson 10:f0854784e960 130 if (action == DO_NOTHING)
andrewboyson 10:f0854784e960 131 {
andrewboyson 10:f0854784e960 132 action = Ip6PollForPacketToSend(pData, &dataLength, pHeader->dst);
andrewboyson 10:f0854784e960 133 type = IPV6;
andrewboyson 10:f0854784e960 134 }
andrewboyson 10:f0854784e960 135
andrewboyson 10:f0854784e960 136 if (action == DO_NOTHING)
andrewboyson 10:f0854784e960 137 {
andrewboyson 10:f0854784e960 138 action = Ip4PollForPacketToSend(pData, &dataLength, pHeader->dst);
andrewboyson 10:f0854784e960 139 type = IPV4;
andrewboyson 10:f0854784e960 140 }
andrewboyson 10:f0854784e960 141
andrewboyson 10:f0854784e960 142 finalisePacket(action, type, dataLength, pPacket, pSize);
andrewboyson 10:f0854784e960 143
andrewboyson 13:9cd54f7db57a 144 if (DEBUG) LogHeader(pHeader, "sent packet");
andrewboyson 13:9cd54f7db57a 145
andrewboyson 10:f0854784e960 146 return action;
andrewboyson 10:f0854784e960 147 }
andrewboyson 10:f0854784e960 148