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.c
- Revision:
- 136:8a65abb0dc63
- Parent:
- 112:f8694d0b8858
- Child:
- 172:9bc3c7b2cca1
--- a/ip6/ip6.c Sat Mar 23 12:25:48 2019 +0000 +++ b/ip6/ip6.c Sat Apr 06 11:20:20 2019 +0000 @@ -12,6 +12,7 @@ #include "eth.h" #include "ip.h" #include "ip6addr.h" +#include "ip6hdr.h" #include "ndp.h" #include "ntp.h" #include "mac.h" @@ -19,125 +20,61 @@ bool Ip6Trace = true; -__packed struct header -{ - uint32_t versionTrafficFlow; - uint16_t payloadLength; - uint8_t protocol; - uint8_t hoplimit; - char src[16]; - char dst[16]; -}; - -static uint8_t version; -static int payloadLength; -static uint8_t protocol; -static uint8_t hoplimit; -static char srcIp[16]; -static char dstIp[16]; - -static void readHeader(struct header * pHeader) -{ - version = (pHeader->versionTrafficFlow >> 4) & 0x0F; - payloadLength = NetToHost16(pHeader->payloadLength); - protocol = pHeader->protocol; - hoplimit = pHeader->hoplimit; - Ip6AddressCopy(srcIp, pHeader->src); - Ip6AddressCopy(dstIp, pHeader->dst); -} -static void writeHeader(struct header * pHeader) -{ - pHeader->versionTrafficFlow = version << 4; - pHeader->payloadLength = NetToHost16(payloadLength); - pHeader->protocol = protocol; - pHeader->hoplimit = hoplimit; - Ip6AddressCopy(pHeader->dst, dstIp); - Ip6AddressCopy(pHeader->src, srcIp); -} - -static void logHeader() +static void logHeader(char* pPacket) { if (NetTraceVerbose) { Log("IP6 header\r\n"); - LogF(" Version %d\r\n", version); - LogF(" Payload length %d\r\n", payloadLength); - LogF(" Hop limit %d\r\n", hoplimit); - LogF(" Protocol "); IpProtocolLog(protocol); Log("\r\n"); - Log (" Source IP "); Ip6AddressLog(srcIp); Log("\r\n"); - Log (" Destination IP "); Ip6AddressLog(dstIp); Log("\r\n"); + LogF(" Version %d\r\n", Ip6HdrGetVersion (pPacket)); + LogF(" Payload length %d\r\n", Ip6HdrGetPayloadLen(pPacket)); + LogF(" Hop limit %d\r\n", Ip6HdrGetHopLimit (pPacket)); + LogF(" Protocol "); IpProtocolLog(Ip6HdrGetProtocol (pPacket)); Log("\r\n"); + Log (" Source IP "); Ip6AddressLog(Ip6HdrPtrSrc (pPacket)); Log("\r\n"); + Log (" Destination IP "); Ip6AddressLog(Ip6HdrPtrDst (pPacket)); Log("\r\n"); } else { Log("IP6 header "); - IpProtocolLog(protocol); + IpProtocolLog(Ip6HdrGetProtocol(pPacket)); Log(" "); - Ip6AddressLog(srcIp); + Ip6AddressLog(Ip6HdrPtrSrc (pPacket)); Log(" >>> "); - Ip6AddressLog(dstIp); + Ip6AddressLog(Ip6HdrPtrDst (pPacket)); Log("\r\n"); } } - -static bool getIsSolicited(char* p) -{ - if (*p++ != 0xff) return false; - if (*p++ != 0x02) return false; - - if (*p++ != 0x00) return false; - if (*p++ != 0x00) return false; - - if (*p++ != 0x00) return false; - if (*p++ != 0x00) return false; - - if (*p++ != 0x00) return false; - if (*p++ != 0x00) return false; - - if (*p++ != 0x00) return false; - if (*p++ != 0x00) return false; - - if (*p++ != 0x00) return false; - if (*p++ != 0x01) return false; - - if (*p++ != 0xff) return false; - - return true; -} -static bool getIsSameGroup(char* pA, char* pB) -{ - pA += 13; - pB += 13; - if (*pA++ != *pB++) return false; - if (*pA++ != *pB++) return false; - return *pA == *pB; -} +static char* pTracePacket; static void (*pTraceBack)(void); static void trace() { pTraceBack(); - logHeader(); + logHeader(pTracePacket); } -int Ip6HandleReceivedPacket(void (*traceback)(void), void* pPacketRx, int sizeRx, void* pPacketTx, int* pSizeTx, char* macRemote) -{ - pTraceBack = traceback; +int Ip6HandleReceivedPacket(void (*traceback)(void), char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx, char* macRemote) +{ + pTracePacket = pPacketRx; + pTraceBack = traceback; - struct header* pHeaderRx = (struct header*)pPacketRx; - struct header* pHeaderTx = (struct header*)pPacketTx; + char* pDataRx = pPacketRx + IP6_HEADER_LENGTH; + char* pDataTx = pPacketTx + IP6_HEADER_LENGTH; - char* pDataRx = (char*)pHeaderRx + sizeof(struct header); - char* pDataTx = (char*)pHeaderTx + sizeof(struct header); + int protocol = Ip6HdrGetProtocol (pPacketRx); + int payloadLengthRx = Ip6HdrGetPayloadLen(pPacketRx); - readHeader(pHeaderRx); //This also fetches the payload length out of the header + static char srcIp[16]; + static char dstIp[16]; + Ip6AddressCopy(srcIp, Ip6HdrPtrSrc (pPacketRx)); + Ip6AddressCopy(dstIp, Ip6HdrPtrDst (pPacketRx)); - int dataLengthRx = sizeRx - sizeof(struct header); - if (payloadLength < dataLengthRx) dataLengthRx = payloadLength; //Choose the lesser of the data length and the payload length - int dataLengthTx = *pSizeTx - sizeof(struct header); + int dataLengthRx = sizeRx - IP6_HEADER_LENGTH; + if (dataLengthRx > payloadLengthRx) dataLengthRx = payloadLengthRx; //Choose the lesser of the data length and the payload length + int dataLengthTx = *pSizeTx - IP6_HEADER_LENGTH; int scope = SlaacScope(dstIp); bool isMe = scope != SCOPE_NONE; - bool isMulticast = dstIp[0] == 0xFF; - bool isSolicited = getIsSolicited(dstIp); - bool isGroup = getIsSameGroup(dstIp, SlaacLinkLocalIp); + bool isMulticast = Ip6AddrIsMulticast(dstIp); + bool isSolicited = Ip6AddrIsSolicited(dstIp); + bool isGroup = Ip6AddrIsSameGroup(dstIp, SlaacLinkLocalIp); bool doIt = isMe || (isMulticast && !isSolicited) || (isGroup && isSolicited); @@ -172,6 +109,7 @@ } if (!action) return DO_NOTHING; + int hoplimit; if (NdpIpNeedsToBeRouted(dstIp)) { MacCopy(macRemote, NdpRouterMac); //Send to the router MAC @@ -182,27 +120,36 @@ hoplimit = 255; } - payloadLength = dataLengthTx; - - writeHeader(pHeaderTx); + Ip6HdrSetVersion (pPacketTx, 6 ); + Ip6HdrSetPayloadLen(pPacketTx, dataLengthTx); + Ip6HdrSetProtocol (pPacketTx, protocol ); + Ip6HdrSetHopLimit (pPacketTx, hoplimit ); + + Ip6AddressCopy(Ip6HdrPtrSrc(pPacketTx), srcIp); + Ip6AddressCopy(Ip6HdrPtrDst(pPacketTx), dstIp); - *pSizeTx = sizeof(struct header) + payloadLength; + *pSizeTx = IP6_HEADER_LENGTH + dataLengthTx; - if (ActionGetTracePart(action)) logHeader(); + if (ActionGetTracePart(action)) logHeader(pPacketTx); return action; } -int Ip6PollForPacketToSend(void* pPacket, int* pSize, char* pDstMac) +int Ip6PollForPacketToSend(char* pPacket, int* pSize, char* pDstMac) { - char* pData = (char*)pPacket + sizeof(struct header); - int dataLength = *pSize - sizeof(struct header); + static char srcIp[16]; + static char dstIp[16]; + char* pData = pPacket + IP6_HEADER_LENGTH; + int dataLength = *pSize - IP6_HEADER_LENGTH; + + int protocol = 0; int action = DO_NOTHING; if (!action) { action = Icmp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = ICMP6; } if (!action) { action = Udp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = UDP; } if (!action) { action = Tcp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = TCP; } if (!action) return DO_NOTHING; + int hoplimit = 0; int dest = ActionGetDestPart(action); switch (dest) { @@ -235,13 +182,16 @@ return DO_NOTHING; } - payloadLength = dataLength; - version = 6; - writeHeader((struct header*)pPacket); + Ip6HdrSetVersion (pPacket, 6 ); + Ip6HdrSetPayloadLen(pPacket, dataLength); + Ip6HdrSetProtocol (pPacket, protocol ); + Ip6HdrSetHopLimit (pPacket, hoplimit ); + Ip6AddressCopy(Ip6HdrPtrSrc(pPacket), srcIp); + Ip6AddressCopy(Ip6HdrPtrDst(pPacket), dstIp); - *pSize = sizeof(struct header) + payloadLength; + *pSize = IP6_HEADER_LENGTH + dataLength; - if (ActionGetTracePart(action)) logHeader(); + if (ActionGetTracePart(action)) logHeader(pPacket); return action; }