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:
Sun Apr 16 14:21:55 2017 +0000
Revision:
10:f0854784e960
Child:
11:c051adb70c5a
MDNS and LLMNR now working.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 10:f0854784e960 1 #include "mbed.h"
andrewboyson 10:f0854784e960 2 #include "log.h"
andrewboyson 10:f0854784e960 3 #include "net.h"
andrewboyson 10:f0854784e960 4 #include "icmp6.h"
andrewboyson 10:f0854784e960 5 #include "udp6.h"
andrewboyson 10:f0854784e960 6 #include "tcp6.h"
andrewboyson 10:f0854784e960 7 #include "ar.h"
andrewboyson 10:f0854784e960 8 #include "dhcp.h"
andrewboyson 10:f0854784e960 9 #include "slaac.h"
andrewboyson 10:f0854784e960 10 #include "eth.h"
andrewboyson 10:f0854784e960 11 #include "ip6.h"
andrewboyson 10:f0854784e960 12
andrewboyson 10:f0854784e960 13 #define HEADER_LENGTH 40
andrewboyson 10:f0854784e960 14
andrewboyson 10:f0854784e960 15 char Ip6AllNodes[] = { 0xff, 0x02, 0x00, 0x00,
andrewboyson 10:f0854784e960 16 0x00, 0x00, 0x00, 0x00,
andrewboyson 10:f0854784e960 17 0x00, 0x00, 0x00, 0x00,
andrewboyson 10:f0854784e960 18 0x00, 0x00, 0x00, 0x01};
andrewboyson 10:f0854784e960 19
andrewboyson 10:f0854784e960 20 char Ip6AllRouters[] = {0xff, 0x02, 0x00, 0x00,
andrewboyson 10:f0854784e960 21 0x00, 0x00, 0x00, 0x00,
andrewboyson 10:f0854784e960 22 0x00, 0x00, 0x00, 0x00,
andrewboyson 10:f0854784e960 23 0x00, 0x00, 0x00, 0x02};
andrewboyson 10:f0854784e960 24
andrewboyson 10:f0854784e960 25 char Ip6Mdns[] = { 0xff, 0x02, 0x00, 0x00,
andrewboyson 10:f0854784e960 26 0x00, 0x00, 0x00, 0x00,
andrewboyson 10:f0854784e960 27 0x00, 0x00, 0x00, 0x00,
andrewboyson 10:f0854784e960 28 0x00, 0x00, 0x00, 0xfb};
andrewboyson 10:f0854784e960 29
andrewboyson 10:f0854784e960 30 char Ip6Llmnr[] = { 0xff, 0x02, 0x00, 0x00,
andrewboyson 10:f0854784e960 31 0x00, 0x00, 0x00, 0x00,
andrewboyson 10:f0854784e960 32 0x00, 0x00, 0x00, 0x00,
andrewboyson 10:f0854784e960 33 0x00, 0x01, 0x00, 0x03};
andrewboyson 10:f0854784e960 34
andrewboyson 10:f0854784e960 35 __packed struct header
andrewboyson 10:f0854784e960 36 {
andrewboyson 10:f0854784e960 37 uint32_t versionTrafficFlow;
andrewboyson 10:f0854784e960 38 uint16_t dataLength;
andrewboyson 10:f0854784e960 39 uint8_t protocol;
andrewboyson 10:f0854784e960 40 uint8_t hoplimit;
andrewboyson 10:f0854784e960 41 char src[16];
andrewboyson 10:f0854784e960 42 char dst[16];
andrewboyson 10:f0854784e960 43 };
andrewboyson 10:f0854784e960 44 static bool getIsSolicited(char* p)
andrewboyson 10:f0854784e960 45 {
andrewboyson 10:f0854784e960 46 if (*p++ != 0xff) return false;
andrewboyson 10:f0854784e960 47 if (*p++ != 0x02) return false;
andrewboyson 10:f0854784e960 48
andrewboyson 10:f0854784e960 49 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 50 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 51
andrewboyson 10:f0854784e960 52 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 53 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 54
andrewboyson 10:f0854784e960 55 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 56 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 57
andrewboyson 10:f0854784e960 58 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 59 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 60
andrewboyson 10:f0854784e960 61 if (*p++ != 0x00) return false;
andrewboyson 10:f0854784e960 62 if (*p++ != 0x01) return false;
andrewboyson 10:f0854784e960 63
andrewboyson 10:f0854784e960 64 if (*p++ != 0xff) return false;
andrewboyson 10:f0854784e960 65
andrewboyson 10:f0854784e960 66 return true;
andrewboyson 10:f0854784e960 67 }
andrewboyson 10:f0854784e960 68 static bool getIsSame(char* pA, char* pB)
andrewboyson 10:f0854784e960 69 {
andrewboyson 10:f0854784e960 70 return memcmp(pA, pB, 16) == 0;
andrewboyson 10:f0854784e960 71 }
andrewboyson 10:f0854784e960 72 static bool getIsSameGroup(char* pA, char* pB)
andrewboyson 10:f0854784e960 73 {
andrewboyson 10:f0854784e960 74 pA += 13;
andrewboyson 10:f0854784e960 75 pB += 13;
andrewboyson 10:f0854784e960 76 if (*pA++ != *pB++) return false;
andrewboyson 10:f0854784e960 77 if (*pA++ != *pB++) return false;
andrewboyson 10:f0854784e960 78 return *pA == *pB;
andrewboyson 10:f0854784e960 79 }
andrewboyson 10:f0854784e960 80 int Ip6HandleReceivedPacket(char* pSrcMac, void* pPacket, int* pSize, char* pDstMac)
andrewboyson 10:f0854784e960 81 {
andrewboyson 10:f0854784e960 82 struct header * pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 83
andrewboyson 10:f0854784e960 84 uint8_t version = (pHeader->versionTrafficFlow >> 4) & 0xF;
andrewboyson 10:f0854784e960 85 int dataLength = NetToHost16(pHeader->dataLength);
andrewboyson 10:f0854784e960 86 uint8_t protocol = pHeader->protocol;
andrewboyson 10:f0854784e960 87 uint8_t hoplimit = pHeader->hoplimit;
andrewboyson 10:f0854784e960 88 char src[16]; memcpy(src, pHeader->src, 16);
andrewboyson 10:f0854784e960 89 char dst[16]; memcpy(dst, pHeader->dst, 16);
andrewboyson 10:f0854784e960 90 void* pData = (char*)pPacket + HEADER_LENGTH;
andrewboyson 10:f0854784e960 91
andrewboyson 10:f0854784e960 92 bool isMe = getIsSame(dst, SlaacLinkLocalIp);
andrewboyson 10:f0854784e960 93 bool isMulticast = dst[0] == 0xFF;
andrewboyson 10:f0854784e960 94 bool isSolicited = getIsSolicited(dst);
andrewboyson 10:f0854784e960 95 bool isGroup = isSolicited && getIsSameGroup(dst, SlaacLinkLocalIp);
andrewboyson 10:f0854784e960 96
andrewboyson 10:f0854784e960 97 bool doIt = isMe || (isMulticast && !isSolicited) || isGroup;
andrewboyson 10:f0854784e960 98
andrewboyson 10:f0854784e960 99 if (!doIt) return DO_NOTHING;
andrewboyson 10:f0854784e960 100
andrewboyson 10:f0854784e960 101 ArAdd6(pSrcMac, src);
andrewboyson 10:f0854784e960 102 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 103 switch (protocol)
andrewboyson 10:f0854784e960 104 {
andrewboyson 10:f0854784e960 105 case ICMP6: action = Icmp6HandleReceivedPacket(src, dst, &dataLength, pData); break;
andrewboyson 10:f0854784e960 106 case UDP: action = Udp6HandleReceivedPacket(src, dst, &dataLength, pData); break;
andrewboyson 10:f0854784e960 107 case TCP: action = Tcp6HandleReceivedPacket(src, dst, &dataLength, pData); break;
andrewboyson 10:f0854784e960 108 default:
andrewboyson 10:f0854784e960 109 char text[100];
andrewboyson 10:f0854784e960 110 LogTimeF("IP6 packet unhandled\r\n");
andrewboyson 10:f0854784e960 111 LogF(" Size %d\r\n", *pSize);
andrewboyson 10:f0854784e960 112 LogF(" Version %d\r\n", version);
andrewboyson 10:f0854784e960 113 LogF(" Payload length %d\r\n", dataLength);
andrewboyson 10:f0854784e960 114 LogF(" Hop limit %d\r\n", hoplimit);
andrewboyson 10:f0854784e960 115 NetProtocolToString(protocol, sizeof(text), text);
andrewboyson 10:f0854784e960 116 LogF(" Protocol %s\r\n", text);
andrewboyson 10:f0854784e960 117 NetIp6AddressToString(src, sizeof(text), text);
andrewboyson 10:f0854784e960 118 LogF(" Source IP %s\r\n", text);
andrewboyson 10:f0854784e960 119 NetIp6AddressToString(dst, sizeof(text), text);
andrewboyson 10:f0854784e960 120 LogF(" Destination IP %s\r\n", text);
andrewboyson 10:f0854784e960 121 return DO_NOTHING;
andrewboyson 10:f0854784e960 122 }
andrewboyson 10:f0854784e960 123 switch (action)
andrewboyson 10:f0854784e960 124 {
andrewboyson 10:f0854784e960 125 case DO_NOTHING:
andrewboyson 10:f0854784e960 126 return DO_NOTHING;
andrewboyson 10:f0854784e960 127 case UNICAST:
andrewboyson 10:f0854784e960 128 memcpy(pDstMac, pSrcMac, 6);
andrewboyson 10:f0854784e960 129 break;
andrewboyson 10:f0854784e960 130 case MULTICAST_ROUTER:
andrewboyson 10:f0854784e960 131 break;
andrewboyson 10:f0854784e960 132 default:
andrewboyson 10:f0854784e960 133 LogTimeF("Ip6 unknown action %d\r\n", action);
andrewboyson 10:f0854784e960 134 return DO_NOTHING;
andrewboyson 10:f0854784e960 135 }
andrewboyson 10:f0854784e960 136
andrewboyson 10:f0854784e960 137 memcpy(pHeader->dst, dst, 16);
andrewboyson 10:f0854784e960 138 memcpy(pHeader->src, src, 16);
andrewboyson 10:f0854784e960 139 pHeader->dataLength = NetToHost16(dataLength);
andrewboyson 10:f0854784e960 140
andrewboyson 10:f0854784e960 141 *pSize = HEADER_LENGTH + dataLength;
andrewboyson 10:f0854784e960 142
andrewboyson 10:f0854784e960 143 return action;
andrewboyson 10:f0854784e960 144 }
andrewboyson 10:f0854784e960 145 int Ip6PollForPacketToSend(void* pPacket, int* pSize, char* pDstMac)
andrewboyson 10:f0854784e960 146 {
andrewboyson 10:f0854784e960 147 void* pData = (char*)pPacket + HEADER_LENGTH;
andrewboyson 10:f0854784e960 148 int dataLength = 0;
andrewboyson 10:f0854784e960 149
andrewboyson 10:f0854784e960 150 char pSrcIp[16];
andrewboyson 10:f0854784e960 151 char pDstIp[16];
andrewboyson 10:f0854784e960 152 uint8_t protocol = 0;
andrewboyson 10:f0854784e960 153 int action = DO_NOTHING;
andrewboyson 10:f0854784e960 154 if (action == DO_NOTHING)
andrewboyson 10:f0854784e960 155 {
andrewboyson 10:f0854784e960 156 action = Icmp6PollForPacketToSend(pData, &dataLength, pSrcIp, pDstIp);
andrewboyson 10:f0854784e960 157 protocol = ICMP6;
andrewboyson 10:f0854784e960 158 }
andrewboyson 10:f0854784e960 159
andrewboyson 10:f0854784e960 160 if (action == DO_NOTHING)
andrewboyson 10:f0854784e960 161 {
andrewboyson 10:f0854784e960 162 action = Udp6PollForPacketToSend(pData, &dataLength, pSrcIp, pDstIp);
andrewboyson 10:f0854784e960 163 protocol = UDP;
andrewboyson 10:f0854784e960 164 }
andrewboyson 10:f0854784e960 165 if (action == DO_NOTHING) return DO_NOTHING;
andrewboyson 10:f0854784e960 166
andrewboyson 10:f0854784e960 167 ArRev6(pDstIp, pDstMac); //Make the remote MAC from ARP
andrewboyson 10:f0854784e960 168
andrewboyson 10:f0854784e960 169 uint8_t version = 6;
andrewboyson 10:f0854784e960 170 uint8_t hoplimit = 255;
andrewboyson 10:f0854784e960 171
andrewboyson 10:f0854784e960 172 struct header * pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 173 pHeader->versionTrafficFlow = version << 4;
andrewboyson 10:f0854784e960 174 pHeader->protocol = protocol;
andrewboyson 10:f0854784e960 175 pHeader->hoplimit = 255;
andrewboyson 10:f0854784e960 176 memcpy(pHeader->dst, pDstIp, 16);
andrewboyson 10:f0854784e960 177 memcpy(pHeader->src, pSrcIp, 16);
andrewboyson 10:f0854784e960 178 pHeader->dataLength = NetToHost16(dataLength);
andrewboyson 10:f0854784e960 179
andrewboyson 10:f0854784e960 180 *pSize = HEADER_LENGTH + dataLength;
andrewboyson 10:f0854784e960 181
andrewboyson 10:f0854784e960 182 LogTimeF("Ip6 sending waiting packet\r\n");
andrewboyson 10:f0854784e960 183 char text[100];
andrewboyson 10:f0854784e960 184 LogF(" Size %d\r\n", *pSize);
andrewboyson 10:f0854784e960 185 LogF(" Version %d\r\n", version);
andrewboyson 10:f0854784e960 186 LogF(" Payload length %d\r\n", dataLength);
andrewboyson 10:f0854784e960 187 LogF(" Hop limit %d\r\n", hoplimit);
andrewboyson 10:f0854784e960 188 NetProtocolToString(protocol, sizeof(text), text);
andrewboyson 10:f0854784e960 189 LogF(" Protocol %s\r\n", text);
andrewboyson 10:f0854784e960 190 NetIp6AddressToString(pSrcIp, sizeof(text), text);
andrewboyson 10:f0854784e960 191 LogF(" Source IP %s\r\n", text);
andrewboyson 10:f0854784e960 192 NetIp6AddressToString(pDstIp, sizeof(text), text);
andrewboyson 10:f0854784e960 193 LogF(" Destination IP %s\r\n", text);
andrewboyson 10:f0854784e960 194
andrewboyson 10:f0854784e960 195 return action;
andrewboyson 10:f0854784e960 196 }