Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
eth/eth.cpp@42:222a4f45f916, 2017-10-15 (annotated)
- Committer:
- andrewboyson
- Date:
- Sun Oct 15 17:54:09 2017 +0000
- Revision:
- 42:222a4f45f916
- Parent:
- 37:793b39683406
- Child:
- 43:bc028d5a6424
Made the use of IPv4 or IPv6 for client requests a configurable option
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| andrewboyson | 37:793b39683406 | 1 | #include "mbed.h" |
| andrewboyson | 37:793b39683406 | 2 | #include "io.h" |
| andrewboyson | 37:793b39683406 | 3 | #include "log.h" |
| andrewboyson | 37:793b39683406 | 4 | #include "net.h" |
| andrewboyson | 37:793b39683406 | 5 | #include "action.h" |
| andrewboyson | 37:793b39683406 | 6 | #include "arp.h" |
| andrewboyson | 37:793b39683406 | 7 | #include "ip4.h" |
| andrewboyson | 37:793b39683406 | 8 | #include "ip6.h" |
| andrewboyson | 37:793b39683406 | 9 | #include "phy.h" |
| andrewboyson | 37:793b39683406 | 10 | #include "eth.h" |
| andrewboyson | 37:793b39683406 | 11 | #include "mac.h" |
| andrewboyson | 10:f0854784e960 | 12 | |
| andrewboyson | 10:f0854784e960 | 13 | #define HEADER_SIZE 14 |
| andrewboyson | 13:9cd54f7db57a | 14 | |
| andrewboyson | 42:222a4f45f916 | 15 | //header variables |
| 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 | 42:222a4f45f916 | 22 | static uint16_t protocol; |
| andrewboyson | 14:e75a59c1123d | 23 | |
| andrewboyson | 14:e75a59c1123d | 24 | void EthProtocolToString(uint16_t prototype, int size, char* text) |
| andrewboyson | 10:f0854784e960 | 25 | { |
| andrewboyson | 14:e75a59c1123d | 26 | switch (prototype) |
| andrewboyson | 10:f0854784e960 | 27 | { |
| andrewboyson | 37:793b39683406 | 28 | case ARP: strncpy (text, "ARP" , size); break; |
| andrewboyson | 37:793b39683406 | 29 | case IPV4: strncpy (text, "IPV4", size); break; |
| andrewboyson | 37:793b39683406 | 30 | case IPV6: strncpy (text, "IPV6", size); break; |
| andrewboyson | 14:e75a59c1123d | 31 | default: snprintf(text, size, "%04hX", prototype); break; |
| andrewboyson | 10:f0854784e960 | 32 | } |
| andrewboyson | 10:f0854784e960 | 33 | } |
| andrewboyson | 10:f0854784e960 | 34 | |
| andrewboyson | 14:e75a59c1123d | 35 | static void finalisePacket(int action, int dataLength, void* pPacket, int* pSize) |
| andrewboyson | 10:f0854784e960 | 36 | { |
| andrewboyson | 14:e75a59c1123d | 37 | if (!action) return; |
| andrewboyson | 14:e75a59c1123d | 38 | |
| andrewboyson | 10:f0854784e960 | 39 | struct header * pHeader = (header*)pPacket; |
| andrewboyson | 14:e75a59c1123d | 40 | |
| andrewboyson | 42:222a4f45f916 | 41 | MacMake(action, protocol, pHeader->dst); |
| andrewboyson | 10:f0854784e960 | 42 | |
| andrewboyson | 36:900e24b27bfb | 43 | MacCopy(pHeader->src, MacLocal); //Put our MAC into the source |
| andrewboyson | 42:222a4f45f916 | 44 | pHeader->typ = NetToHost16(protocol); |
| andrewboyson | 10:f0854784e960 | 45 | |
| andrewboyson | 10:f0854784e960 | 46 | *pSize = HEADER_SIZE + dataLength; |
| andrewboyson | 10:f0854784e960 | 47 | } |
| andrewboyson | 37:793b39683406 | 48 | void LogHeader(struct header* pHeader) |
| andrewboyson | 13:9cd54f7db57a | 49 | { |
| andrewboyson | 13:9cd54f7db57a | 50 | char text[20]; |
| andrewboyson | 37:793b39683406 | 51 | Log("ETH header\r\n"); |
| andrewboyson | 37:793b39683406 | 52 | MacToString(pHeader->dst, sizeof(text), text); LogF(" Destination: %s\r\n", text); |
| andrewboyson | 37:793b39683406 | 53 | MacToString(pHeader->src, sizeof(text), text); LogF(" Source: %s\r\n", text); |
| andrewboyson | 37:793b39683406 | 54 | EthProtocolToString(NetToHost16(pHeader->typ), sizeof(text), text); LogF(" EtherType: %s\r\n", text); |
| andrewboyson | 13:9cd54f7db57a | 55 | } |
| andrewboyson | 37:793b39683406 | 56 | static void (*pTraceBack)(void); |
| andrewboyson | 37:793b39683406 | 57 | static void* tracePacket; |
| andrewboyson | 37:793b39683406 | 58 | static void trace() |
| andrewboyson | 10:f0854784e960 | 59 | { |
| andrewboyson | 37:793b39683406 | 60 | pTraceBack(); |
| andrewboyson | 37:793b39683406 | 61 | struct header * pHeader = (header*)tracePacket; |
| andrewboyson | 37:793b39683406 | 62 | LogHeader(pHeader); |
| andrewboyson | 37:793b39683406 | 63 | } |
| andrewboyson | 37:793b39683406 | 64 | int EthHandlePacket(void (*traceback)(void), void* pPacket, int* pSize) |
| andrewboyson | 37:793b39683406 | 65 | { |
| andrewboyson | 37:793b39683406 | 66 | pTraceBack = traceback; |
| andrewboyson | 37:793b39683406 | 67 | tracePacket = pPacket; |
| andrewboyson | 10:f0854784e960 | 68 | struct header * pHeader = (header*)pPacket; |
| andrewboyson | 10:f0854784e960 | 69 | int dataLength = *pSize - HEADER_SIZE; |
| andrewboyson | 10:f0854784e960 | 70 | void* pData = (char*)pPacket + HEADER_SIZE; |
| andrewboyson | 14:e75a59c1123d | 71 | |
| andrewboyson | 14:e75a59c1123d | 72 | if (!MacAccept(pHeader->dst)) return DO_NOTHING; |
| andrewboyson | 13:9cd54f7db57a | 73 | |
| andrewboyson | 42:222a4f45f916 | 74 | protocol = NetToHost16(pHeader->typ); |
| andrewboyson | 42:222a4f45f916 | 75 | if (protocol < 1500) return DO_NOTHING; //drop 802.3 messages |
| andrewboyson | 10:f0854784e960 | 76 | |
| andrewboyson | 10:f0854784e960 | 77 | int action = DO_NOTHING; |
| andrewboyson | 42:222a4f45f916 | 78 | switch (protocol) |
| andrewboyson | 10:f0854784e960 | 79 | { |
| andrewboyson | 37:793b39683406 | 80 | case ARP: action = ArpHandleReceivedPacket(trace, pHeader->src, pData, &dataLength, pHeader->dst); break; |
| andrewboyson | 37:793b39683406 | 81 | case IPV4: action = Ip4HandleReceivedPacket(trace, pHeader->src, pData, &dataLength, pHeader->dst); break; |
| andrewboyson | 37:793b39683406 | 82 | case IPV6: action = Ip6HandleReceivedPacket(trace, pHeader->src, pData, &dataLength, pHeader->dst); break; |
| andrewboyson | 28:edc17eeb4142 | 83 | case 0x6970: break; //Drop Sonos group membership packet |
| andrewboyson | 16:f416ef583c89 | 84 | case 0x7374: break; //Drop Sky Q packet |
| andrewboyson | 16:f416ef583c89 | 85 | case 0x7475: break; //Drop Sky Q packet |
| andrewboyson | 16:f416ef583c89 | 86 | case 0x7380: break; //Drop Sky Q packet |
| andrewboyson | 23:b641979389b2 | 87 | case 0x8100: break; //Drop Sky Q VLAN 802.1Q packet |
| andrewboyson | 33:714a0345e59b | 88 | case 0x887b: break; //Drop Sky Q packet |
| andrewboyson | 10:f0854784e960 | 89 | default: |
| andrewboyson | 42:222a4f45f916 | 90 | LogTimeF("ETH protocol %d not handled", protocol); |
| andrewboyson | 10:f0854784e960 | 91 | break; |
| andrewboyson | 10:f0854784e960 | 92 | } |
| andrewboyson | 10:f0854784e960 | 93 | |
| andrewboyson | 14:e75a59c1123d | 94 | finalisePacket(action, dataLength, pPacket, pSize); |
| andrewboyson | 37:793b39683406 | 95 | |
| andrewboyson | 37:793b39683406 | 96 | if (ActionGetTracePart(action)) LogHeader(pHeader); |
| andrewboyson | 37:793b39683406 | 97 | |
| andrewboyson | 10:f0854784e960 | 98 | return action; |
| andrewboyson | 10:f0854784e960 | 99 | } |
| andrewboyson | 10:f0854784e960 | 100 | int EthPollForPacketToSend(void* pPacket, int* pSize) |
| andrewboyson | 10:f0854784e960 | 101 | { |
| andrewboyson | 10:f0854784e960 | 102 | struct header * pHeader = (header*)pPacket; |
| andrewboyson | 10:f0854784e960 | 103 | void* pData = (char*)pPacket + HEADER_SIZE; |
| andrewboyson | 10:f0854784e960 | 104 | |
| andrewboyson | 10:f0854784e960 | 105 | int dataLength = 0; |
| andrewboyson | 42:222a4f45f916 | 106 | protocol = 0; |
| andrewboyson | 10:f0854784e960 | 107 | int action = DO_NOTHING; |
| andrewboyson | 10:f0854784e960 | 108 | |
| andrewboyson | 10:f0854784e960 | 109 | if (action == DO_NOTHING) |
| andrewboyson | 10:f0854784e960 | 110 | { |
| andrewboyson | 22:914b970356f0 | 111 | action = ArpPollForPacketToSend(pData, &dataLength); |
| andrewboyson | 42:222a4f45f916 | 112 | protocol = ARP; |
| andrewboyson | 22:914b970356f0 | 113 | } |
| andrewboyson | 22:914b970356f0 | 114 | |
| andrewboyson | 22:914b970356f0 | 115 | if (action == DO_NOTHING) |
| andrewboyson | 22:914b970356f0 | 116 | { |
| andrewboyson | 10:f0854784e960 | 117 | action = Ip6PollForPacketToSend(pData, &dataLength, pHeader->dst); |
| andrewboyson | 42:222a4f45f916 | 118 | protocol = IPV6; |
| andrewboyson | 10:f0854784e960 | 119 | } |
| andrewboyson | 10:f0854784e960 | 120 | |
| andrewboyson | 10:f0854784e960 | 121 | if (action == DO_NOTHING) |
| andrewboyson | 10:f0854784e960 | 122 | { |
| andrewboyson | 10:f0854784e960 | 123 | action = Ip4PollForPacketToSend(pData, &dataLength, pHeader->dst); |
| andrewboyson | 42:222a4f45f916 | 124 | protocol = IPV4; |
| andrewboyson | 10:f0854784e960 | 125 | } |
| andrewboyson | 10:f0854784e960 | 126 | |
| andrewboyson | 14:e75a59c1123d | 127 | finalisePacket(action, dataLength, pPacket, pSize); |
| andrewboyson | 10:f0854784e960 | 128 | |
| andrewboyson | 37:793b39683406 | 129 | if (ActionGetTracePart(action)) LogHeader(pHeader); |
| andrewboyson | 13:9cd54f7db57a | 130 | |
| andrewboyson | 10:f0854784e960 | 131 | return action; |
| andrewboyson | 10:f0854784e960 | 132 | } |
| andrewboyson | 10:f0854784e960 | 133 |