// echo request static TCPIP_MAC_PKT_ACK_RES _ICMPProcessEchoRequest(TCPIP_NET_IF* pNetIf, TCPIP_MAC_PACKET* pRxPkt, uint32_t destAdd, uint32_t srcAdd) { ICMP_HEADER *pTxHdr; IPV4_PACKET *pTxPkt; TCPIP_UINT16_VAL checksum; uint8_t *pSrcData, *pDstData; TCPIP_MAC_DATA_SEGMENT *pSrcSeg; // allocate TX packet pTxPkt = _ICMPAllocateTxPacketStruct(pRxPkt->totTransportLen); if(pTxPkt != 0) { // succeeded // copy the 1st segment payload pSrcSeg = pRxPkt->pDSeg; pSrcData = pRxPkt->pTransportLayer; pDstData = pTxPkt->macPkt.pTransportLayer; while(pSrcSeg) { memcpy(pDstData, pSrcData, pSrcSeg->segLen); pDstData += pSrcSeg->segLen; if((pSrcSeg = pSrcSeg->next) != 0) { pSrcData = pSrcSeg->segLoad; } } // set the correct vType, vCode, and Checksum pTxHdr = (ICMP_HEADER*)pTxPkt->macPkt.pTransportLayer; pTxHdr->vType = ICMP_TYPE_ECHO_REPLY; pTxHdr->vCode = ICMP_CODE_ECHO_REPLY; checksum.Val = pTxHdr->wChecksum; checksum.v[0] += 8; // Subtract 0x0800 from the checksum if(checksum.v[0] < 8u) { checksum.v[1]++; if(checksum.v[1] == 0u) { checksum.v[0]++; } } pTxHdr->wChecksum = checksum.Val; pTxPkt->srcAddress.Val = destAdd; pTxPkt->destAddress.Val = srcAdd; pTxPkt->netIfH = pNetIf; pTxPkt->macPkt.pDSeg->segLen += pRxPkt->totTransportLen; TCPIP_IPV4_PacketFormatTx(pTxPkt, IP_PROT_ICMP, pRxPkt->totTransportLen); if(!TCPIP_IPV4_PacketTransmit(pTxPkt)) { TCPIP_PKT_PacketFree(&pTxPkt->macPkt); } } return TCPIP_MAC_PKT_ACK_RX_OK; }
ICMP_ECHO_RESULT TCPIP_ICMP_EchoRequestSend (IPV4_ADDR * targetAddr, uint16_t sequenceNumber, uint16_t identifier) { IPV4_PACKET* pTxPkt; ICMP_PACKET* pICMPPkt; uint32_t payload = 0x44332211; uint16_t pktSize = sizeof(ICMP_PACKET); ICMP_ECHO_RESULT res; while(true) { // allocate TX packet pTxPkt = _ICMPAllocateTxPacketStruct(pktSize); if(pTxPkt == 0) { res = ICMP_ECHO_ALLOC_ERROR; break; } pICMPPkt = (ICMP_PACKET*)pTxPkt->macPkt.pTransportLayer; pICMPPkt->vType = ICMP_TYPE_ECHO_REQUEST; pICMPPkt->vCode = ICMP_CODE_ECHO_REQUEST; pICMPPkt->wChecksum = 0x0000; pICMPPkt->wIdentifier = identifier; pICMPPkt->wSequenceNumber = sequenceNumber; pICMPPkt->wData = payload; pICMPPkt->wChecksum = TCPIP_Helper_CalcIPChecksum((uint8_t*)pICMPPkt, pktSize, 0); pTxPkt->destAddress.Val = targetAddr->Val; pTxPkt->netIfH = TCPIP_IPV4_SelectSourceInterface(0, targetAddr, &pTxPkt->srcAddress, false); if(pTxPkt->netIfH == 0) { // could not find an route res = ICMP_ECHO_ROUTE_ERROR; break; } pTxPkt->macPkt.pDSeg->segLen += pktSize; TCPIP_IPV4_PacketFormatTx(pTxPkt, IP_PROT_ICMP, pktSize); if(!TCPIP_IPV4_PacketTransmit(pTxPkt)) { res = ICMP_ECHO_TRANSMIT_ERROR; break; } res = ICMP_ECHO_OK; break; } if(res < 0 && pTxPkt != 0) { TCPIP_PKT_PacketFree(&pTxPkt->macPkt); } return res; }
// echo request static TCPIP_MAC_PKT_ACK_RES _ICMPProcessEchoRequest(TCPIP_NET_IF* pNetIf, TCPIP_MAC_PACKET* pRxPkt, uint32_t destAdd, uint32_t srcAdd) { ICMP_HEADER *pTxHdr; IPV4_PACKET *pTxPkt; TCPIP_UINT16_VAL checksum; int16_t dataToCopy; // allocate TX packet dataToCopy = pRxPkt->totTransportLen; pTxPkt = _ICMPAllocateTxPacketStruct(dataToCopy); if(pTxPkt != 0) { // succeeded uint8_t* pStartAdd = pRxPkt->pTransportLayer; TCPIP_Helper_PacketCopy(pRxPkt, pTxPkt->macPkt.pTransportLayer, &pStartAdd, dataToCopy, true); // set the correct vType, vCode, and Checksum pTxHdr = (ICMP_HEADER*)pTxPkt->macPkt.pTransportLayer; pTxHdr->vType = ICMP_TYPE_ECHO_REPLY; pTxHdr->vCode = ICMP_CODE_ECHO_REPLY; checksum.Val = pTxHdr->wChecksum; checksum.v[0] += 8; // Subtract 0x0800 from the checksum if(checksum.v[0] < 8u) { checksum.v[1]++; if(checksum.v[1] == 0u) { checksum.v[0]++; } } pTxHdr->wChecksum = checksum.Val; pTxPkt->srcAddress.Val = destAdd; pTxPkt->destAddress.Val = srcAdd; pTxPkt->netIfH = pNetIf; pTxPkt->macPkt.pDSeg->segLen += pRxPkt->totTransportLen; TCPIP_IPV4_PacketFormatTx(pTxPkt, IP_PROT_ICMP, pRxPkt->totTransportLen); if(!TCPIP_IPV4_PacketTransmit(pTxPkt)) { TCPIP_PKT_PacketFree(&pTxPkt->macPkt); } } return TCPIP_MAC_PKT_ACK_RX_OK; }
// packet deallocation function // packet was transmitted by the IP layer static void _ICMPAckPacket(TCPIP_MAC_PACKET* pkt, const void* ackParam) { TCPIP_PKT_PacketFree(pkt); }
// packet deallocation function // packet was transmitted by the IP layer static bool _ICMPAckPacket(TCPIP_MAC_PACKET* pkt, const void* ackParam) { TCPIP_PKT_PacketFree(pkt); return false; }