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
Diff: ip6/ip6.cpp
- Revision:
- 11:c051adb70c5a
- Parent:
- 10:f0854784e960
- Child:
- 13:9cd54f7db57a
--- a/ip6/ip6.cpp Sun Apr 16 14:21:55 2017 +0000 +++ b/ip6/ip6.cpp Tue Apr 18 19:07:05 2017 +0000 @@ -1,37 +1,38 @@ -#include "mbed.h" -#include "log.h" -#include "net.h" -#include "icmp6.h" -#include "udp6.h" -#include "tcp6.h" -#include "ar.h" -#include "dhcp.h" -#include "slaac.h" -#include "eth.h" -#include "ip6.h" +#include "mbed.h" +#include "log.h" +#include "net.h" +#include "icmp6.h" +#include "udptcp6.h" +#include "ar.h" +#include "slaac.h" +#include "eth.h" +#include "ip6.h" +#include "ndp.h" + +#define DEBUG false + +char Ip6AllNodes [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; +char Ip6AllRouters[] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; +char Ip6Mdns [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb}; +char Ip6Llmnr [] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03}; + +void Ip6DestIpFromAction(int action, char* pDstIp) +{ + switch (action) + { + case UNICAST: break; + case UNICAST_DNS: memcpy(pDstIp, NdpDnsServer, 16); break; + case MULTICAST_NODE: memcpy(pDstIp, Ip6AllNodes, 16); break; + case MULTICAST_ROUTER: memcpy(pDstIp, Ip6AllRouters, 16); break; + case MULTICAST_MDNS: memcpy(pDstIp, Ip6Mdns, 16); break; + case MULTICAST_LLMNR: memcpy(pDstIp, Ip6Llmnr, 16); break; + default: + LogTimeF("Ip6 DestIpFromAction unknown action %d\r\n", action); + break; + } +} #define HEADER_LENGTH 40 - -char Ip6AllNodes[] = { 0xff, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01}; - -char Ip6AllRouters[] = {0xff, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02}; - -char Ip6Mdns[] = { 0xff, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfb}; - -char Ip6Llmnr[] = { 0xff, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x03}; - __packed struct header { uint32_t versionTrafficFlow; @@ -41,6 +42,50 @@ char src[16]; char dst[16]; }; + +static uint8_t version; +static int dataLength; +static uint8_t protocol; +static uint8_t hoplimit; +static char pSrcIp[16]; +static char pDstIp[16]; +static void* pData; + +static void readHeader(struct header * pHeader) +{ + version = (pHeader->versionTrafficFlow >> 4) & 0xF; + dataLength = NetToHost16(pHeader->dataLength); + protocol = pHeader->protocol; + hoplimit = pHeader->hoplimit; + memcpy(pSrcIp, pHeader->src, 16); + memcpy(pDstIp, pHeader->dst, 16); + pData = (char*)pHeader + HEADER_LENGTH; +} +static void writeHeader(struct header * pHeader) +{ + pHeader->versionTrafficFlow = version << 4; + pHeader->protocol = protocol; + pHeader->hoplimit = 255; + memcpy(pHeader->dst, pDstIp, 16); + memcpy(pHeader->src, pSrcIp, 16); + pHeader->dataLength = NetToHost16(dataLength); +} + +static void logHeader(char* title) +{ + char text[100]; + LogTimeF("%s\r\n", title); + LogF(" Version %d\r\n", version); + LogF(" Payload length %d\r\n", dataLength); + LogF(" Hop limit %d\r\n", hoplimit); + NetProtocolToString(protocol, sizeof(text), text); + LogF(" Protocol %s\r\n", text); + NetIp6AddressToString(pSrcIp, sizeof(text), text); + LogF(" Source IP %s\r\n", text); + NetIp6AddressToString(pDstIp, sizeof(text), text); + LogF(" Destination IP %s\r\n", text); +} + static bool getIsSolicited(char* p) { if (*p++ != 0xff) return false; @@ -80,76 +125,50 @@ int Ip6HandleReceivedPacket(char* pSrcMac, void* pPacket, int* pSize, char* pDstMac) { struct header * pHeader = (header*)pPacket; + readHeader(pHeader); - uint8_t version = (pHeader->versionTrafficFlow >> 4) & 0xF; - int dataLength = NetToHost16(pHeader->dataLength); - uint8_t protocol = pHeader->protocol; - uint8_t hoplimit = pHeader->hoplimit; - char src[16]; memcpy(src, pHeader->src, 16); - char dst[16]; memcpy(dst, pHeader->dst, 16); - void* pData = (char*)pPacket + HEADER_LENGTH; - - bool isMe = getIsSame(dst, SlaacLinkLocalIp); - bool isMulticast = dst[0] == 0xFF; - bool isSolicited = getIsSolicited(dst); - bool isGroup = isSolicited && getIsSameGroup(dst, SlaacLinkLocalIp); + bool isMe = getIsSame(pDstIp, SlaacLinkLocalIp); + bool isMulticast = pDstIp[0] == 0xFF; + bool isSolicited = getIsSolicited(pDstIp); + bool isGroup = isSolicited && getIsSameGroup(pDstIp, SlaacLinkLocalIp); bool doIt = isMe || (isMulticast && !isSolicited) || isGroup; if (!doIt) return DO_NOTHING; - ArAdd6(pSrcMac, src); + ArAdd6(pSrcMac, pSrcIp); + + if (DEBUG) logHeader("IP6 packet received"); + int action = DO_NOTHING; switch (protocol) { - case ICMP6: action = Icmp6HandleReceivedPacket(src, dst, &dataLength, pData); break; - case UDP: action = Udp6HandleReceivedPacket(src, dst, &dataLength, pData); break; - case TCP: action = Tcp6HandleReceivedPacket(src, dst, &dataLength, pData); break; + case ICMP6: action = Icmp6HandleReceivedPacket(pSrcIp, pDstIp, &dataLength, pData); break; + case UDP: action = Udp6HandleReceivedPacket(pSrcIp, pDstIp, &dataLength, pData); break; + case TCP: action = Tcp6HandleReceivedPacket(pSrcIp, pDstIp, &dataLength, pData); break; default: - char text[100]; - LogTimeF("IP6 packet unhandled\r\n"); - LogF(" Size %d\r\n", *pSize); - LogF(" Version %d\r\n", version); - LogF(" Payload length %d\r\n", dataLength); - LogF(" Hop limit %d\r\n", hoplimit); - NetProtocolToString(protocol, sizeof(text), text); - LogF(" Protocol %s\r\n", text); - NetIp6AddressToString(src, sizeof(text), text); - LogF(" Source IP %s\r\n", text); - NetIp6AddressToString(dst, sizeof(text), text); - LogF(" Destination IP %s\r\n", text); + logHeader("IP6 packet unhandled"); return DO_NOTHING; } - switch (action) - { - case DO_NOTHING: - return DO_NOTHING; - case UNICAST: - memcpy(pDstMac, pSrcMac, 6); - break; - case MULTICAST_ROUTER: - break; - default: - LogTimeF("Ip6 unknown action %d\r\n", action); - return DO_NOTHING; - } + if (!action) return DO_NOTHING; + + memcpy(pDstMac, pSrcMac, 6); + + if (DEBUG) logHeader("IP6 packet replied to"); - memcpy(pHeader->dst, dst, 16); - memcpy(pHeader->src, src, 16); - pHeader->dataLength = NetToHost16(dataLength); - + writeHeader(pHeader); + *pSize = HEADER_LENGTH + dataLength; return action; } int Ip6PollForPacketToSend(void* pPacket, int* pSize, char* pDstMac) { - void* pData = (char*)pPacket + HEADER_LENGTH; - int dataLength = 0; + pData = (char*)pPacket + HEADER_LENGTH; + dataLength = 0; + version = 6; + hoplimit = 255; - char pSrcIp[16]; - char pDstIp[16]; - uint8_t protocol = 0; int action = DO_NOTHING; if (action == DO_NOTHING) { @@ -162,35 +181,21 @@ action = Udp6PollForPacketToSend(pData, &dataLength, pSrcIp, pDstIp); protocol = UDP; } - if (action == DO_NOTHING) return DO_NOTHING; - - ArRev6(pDstIp, pDstMac); //Make the remote MAC from ARP + if (!action) return DO_NOTHING; + switch (action) + { + case UNICAST: + case UNICAST_DNS: + case UNICAST_DHCP: + ArRev6(pDstIp, pDstMac); //Make the remote MAC from NP + break; + } + + if (DEBUG) logHeader("IP6 polled packet sent"); - uint8_t version = 6; - uint8_t hoplimit = 255; - - struct header * pHeader = (header*)pPacket; - pHeader->versionTrafficFlow = version << 4; - pHeader->protocol = protocol; - pHeader->hoplimit = 255; - memcpy(pHeader->dst, pDstIp, 16); - memcpy(pHeader->src, pSrcIp, 16); - pHeader->dataLength = NetToHost16(dataLength); - + writeHeader((header*)pPacket); + *pSize = HEADER_LENGTH + dataLength; - LogTimeF("Ip6 sending waiting packet\r\n"); - char text[100]; - LogF(" Size %d\r\n", *pSize); - LogF(" Version %d\r\n", version); - LogF(" Payload length %d\r\n", dataLength); - LogF(" Hop limit %d\r\n", hoplimit); - NetProtocolToString(protocol, sizeof(text), text); - LogF(" Protocol %s\r\n", text); - NetIp6AddressToString(pSrcIp, sizeof(text), text); - LogF(" Source IP %s\r\n", text); - NetIp6AddressToString(pDstIp, sizeof(text), text); - LogF(" Destination IP %s\r\n", text); - return action; }