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
eth/eth.cpp@13:9cd54f7db57a, 2017-05-01 (annotated)
- 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?
User | Revision | Line number | New 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 |