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: ip4/ip4.cpp
- Revision:
- 59:e0e556c8bd46
- Parent:
- 57:e0fb648acf48
--- a/ip4/ip4.cpp Thu Dec 07 20:44:32 2017 +0000 +++ b/ip4/ip4.cpp Thu Dec 14 20:55:40 2017 +0000 @@ -15,8 +15,6 @@ bool Ip4Trace = true; -#define HEADER_LENGTH 20 - #define OFF_LINK_TTL 64 __packed struct header @@ -37,6 +35,7 @@ static uint8_t version; static int headerLength; static uint8_t tos; +static uint16_t totalLength; static uint16_t id; static bool dontFragment; static bool moreFragments; @@ -47,16 +46,14 @@ static uint16_t calcsum; static uint32_t srcIp; static uint32_t dstIp; -static void* pData; -static int dataLength; -void readHeader(struct header * pHeader) +static void readHeader(struct header * pHeader) { version = pHeader->versionIhl >> 4; uint8_t ihl = pHeader->versionIhl & 0xF; headerLength = ihl * 4; tos = pHeader->tos; - uint16_t totalLength = NetToHost16(pHeader->length); + totalLength = NetToHost16(pHeader->length); id = NetToHost16(pHeader->id); uint16_t flagsOffset = NetToHost16(pHeader->flagsOffset); dontFragment = flagsOffset & 0x4000; @@ -68,10 +65,8 @@ calcsum = NetCheckSum(headerLength, pHeader); srcIp = pHeader->src; dstIp = pHeader->dst; - pData = (char*)pHeader + headerLength; - dataLength = totalLength - headerLength; } -void writeHeader(struct header * pHeader) +static void writeHeader(struct header * pHeader) { uint16_t flagsOffset = offset; if (dontFragment) flagsOffset |= 0x4000; @@ -87,7 +82,7 @@ pHeader->dst = dstIp; pHeader->src = srcIp; - pHeader->length = NetToHost16(headerLength + dataLength); + pHeader->length = NetToHost16(totalLength); pHeader->checksum = 0; pHeader->checksum = NetCheckSum(headerLength, pHeader); calcsum = 0; @@ -101,7 +96,7 @@ LogF(" Version %d\r\n", version); LogF(" Header length %d\r\n", headerLength); LogF(" Type of service %d\r\n", tos); - LogF(" Data length %d\r\n", dataLength); + LogF(" Total length %d\r\n", totalLength); LogF(" Identification %d\r\n", id); if (dontFragment) LogF(" Don't fragment\r\n"); else LogF(" Do fragment\r\n"); @@ -132,11 +127,19 @@ pTraceBack(); logHeader(); } -int Ip4HandleReceivedPacket(void (*traceback)(void), char* pSrcMac, void* pPacket, int* pSize, char* pDstMac) +int Ip4HandleReceivedPacket(void (*traceback)(void), void* pPacketRx, int sizeRx, void* pPacketTx, int* pSizeTx, char* macRemote) { pTraceBack = traceback; - struct header * pHeader = (header*)pPacket; - readHeader(pHeader); + struct header * pHeaderRx = (header*)pPacketRx; + struct header * pHeaderTx = (header*)pPacketTx; + + char* pDataRx = (char*)pHeaderRx + headerLength; + char* pDataTx = (char*)pHeaderTx + headerLength; + + readHeader(pHeaderRx); + if (totalLength < sizeRx) sizeRx = totalLength; + int dataLengthRx = sizeRx - headerLength; + int dataLengthTx = *pSizeTx - sizeof(header); bool isMe = dstIp == DhcpLocalIp; bool isLocalBroadcast = dstIp == DhcpLocalIp | 0xFF000000; @@ -158,18 +161,18 @@ if (srcIp) { - Ar4AddIpRecord(trace, pSrcMac, srcIp); + Ar4AddIpRecord(trace, macRemote, srcIp); Nr4MakeRequestForNameFromIp(srcIp); } - + int action = DO_NOTHING; switch (protocol) { - case ICMP: action = Icmp4HandleReceivedPacket(trace, &srcIp, &dstIp, &dataLength, pData); break; - case IGMP: break; - case UDP: action = Udp4HandleReceivedPacket(trace, &srcIp, &dstIp, &dataLength, pData); break; - case TCP: action = Tcp4HandleReceivedPacket(trace, &srcIp, &dstIp, &dataLength, pData); break; - case IP6IN4: break; + case ICMP: action = Icmp4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, &srcIp, &dstIp); break; + case IGMP: break; + case UDP: action = Udp4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, &srcIp, &dstIp); break; + case TCP: action = Tcp4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, &srcIp, &dstIp); break; + case IP6IN4: break; default: LogTimeF("IP4 received packet unknown protocol %d\r\n"); return DO_NOTHING; @@ -178,28 +181,29 @@ if (DhcpIpNeedsToBeRouted(dstIp)) { - Ar4IpToMac(DhcpRouter, pDstMac); //Send back to the router + Ar4IpToMac(DhcpRouter, macRemote); //Send back to the router ttl = OFF_LINK_TTL; } else { - MacCopy(pDstMac, pSrcMac); //Send back to the source ttl = 255; } + + totalLength = sizeof(header) + dataLengthTx; + headerLength = sizeof(header); + + writeHeader(pHeaderTx); - writeHeader(pHeader); - - *pSize = headerLength + dataLength; + *pSizeTx = totalLength; if (ActionGetTracePart(action)) logHeader(); return action; } int Ip4PollForPacketToSend(void* pPacket, int* pSize, char* pDstMac) -{ - headerLength = HEADER_LENGTH; - pData = (char*)pPacket + headerLength; - dataLength = 0; +{ + headerLength = sizeof(header); + char* pData = (char*)pPacket + headerLength; version = 4; tos = 0; id = 0; @@ -208,6 +212,8 @@ offset = 0; protocol = UDP; + int dataLength = *pSize - sizeof(header); + int action = DO_NOTHING; if (!action) action = Udp4PollForPacketToSend(pData, &dataLength, &srcIp, &dstIp); if (!action) return DO_NOTHING; @@ -242,9 +248,14 @@ return DO_NOTHING; } - writeHeader((header*)pPacket); + struct header* pHeader = (struct header*)pPacket; + + totalLength = sizeof(header) + dataLength; + headerLength = sizeof(header); + + writeHeader(pHeader); - *pSize = headerLength + dataLength; + *pSize = totalLength; if (ActionGetTracePart(action)) logHeader();