Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
// Processes an ICMP packet and generates an echo reply, if requested
static void  TCPIP_ICMP_Process(void)
{
    TCPIP_NET_IF*           pNetIf;
    TCPIP_MAC_PACKET*       pRxPkt;
    IPV4_HEADER*            pIpv4Header;
    uint32_t                destAdd;
    uint32_t                srcAdd;
    ICMP_HEADER*            pRxHdr;
    uint16_t                icmpTotLength;
    uint16_t                checksum;
    TCPIP_MAC_PKT_ACK_RES   ackRes;



    // extract queued ICMP packets
    while((pRxPkt = _TCPIPStackModuleRxExtract(TCPIP_THIS_MODULE_ID)) != 0)
    {
        pNetIf = (TCPIP_NET_IF*)pRxPkt->pktIf;

        pRxHdr = (ICMP_HEADER*)pRxPkt->pTransportLayer;
        ackRes = TCPIP_MAC_PKT_ACK_RX_OK;

        pIpv4Header = (IPV4_HEADER*)pRxPkt->pNetLayer;
        destAdd = pIpv4Header->DestAddress.Val;
        srcAdd =  pIpv4Header->SourceAddress.Val;


        while(true)
        {
            icmpTotLength = pRxPkt->totTransportLen;

            if(icmpTotLength < sizeof(*pRxHdr))
            {
                ackRes = TCPIP_MAC_PKT_ACK_STRUCT_ERR;
                break;
            }

            // Validate the checksum
            // The checksum data includes the precomputed checksum in the header
            // so a valid packet will always have a checksum of 0x0000
            // 1st segment
            if((pRxPkt->pktFlags & TCPIP_MAC_PKT_FLAG_SPLIT) != 0)
            {
                checksum = TCPIP_Helper_PacketChecksum(pRxPkt, (uint8_t*)pRxHdr, icmpTotLength, 0);
            }
            else
            {
                checksum = TCPIP_Helper_CalcIPChecksum((uint8_t*)pRxHdr, icmpTotLength, 0);
            }

            if(checksum != 0)
            {
                ackRes = TCPIP_MAC_PKT_ACK_CHKSUM_ERR;
                break;
            }

            if(pRxHdr->vType == ICMP_TYPE_ECHO_REQUEST && pRxHdr->vCode == ICMP_CODE_ECHO_REQUEST)
            {   // echo request
                ackRes = _ICMPProcessEchoRequest(pNetIf, pRxPkt, destAdd, srcAdd);
                break;
            }

#if defined(TCPIP_STACK_USE_ICMP_CLIENT)
            if(pRxHdr->vType == ICMP_TYPE_ECHO_REPLY && pRxHdr->vCode == ICMP_CODE_ECHO_REPLY)
            {   // echo reply; check if our own
                // Get the sequence number and identifier fields
#if (TCPIP_ICMP_CLIENT_USER_NOTIFICATION != 0)
                TCPIP_UINT32_VAL userData;
                IPV4_ADDR remoteIPAddr;

                userData.w[0] = pRxHdr->wIdentifier;
                userData.w[1] = pRxHdr->wSequenceNumber;
                remoteIPAddr.Val = srcAdd;

                // Send a message to the application-level Ping driver that we've received an Echo Reply
                _ICMPNotifyClients(pNetIf, &remoteIPAddr, (void *)userData.v);
#endif  // (TCPIP_ICMP_CLIENT_USER_NOTIFICATION != 0)
                ackRes = TCPIP_MAC_PKT_ACK_RX_OK;
                break;
            }
#endif

            // unknown type
            ackRes = TCPIP_MAC_PKT_ACK_TYPE_ERR;
            break;
        }


        TCPIP_PKT_FlightLog(pRxPkt, TCPIP_THIS_MODULE_ID, ackRes, 0);
        TCPIP_PKT_PacketAcknowledge(pRxPkt, ackRes); 
    }
}