Ejemplo n.º 1
0
static void CommandPingHandler(TCPIP_NET_HANDLE hNetIf, IPV4_ADDR * remoteIP, void * data)
{
    char addBuff[20];

    if(icmpCmdStat == TCPIP_PING_CMD_IDLE)
    {
        return; // not our reply?
    }

    uint16_t* pReply = (uint16_t*)data;
    uint16_t myRecvId = *pReply;
    uint16_t myRecvSequenceNumber = *(pReply + 1);


    if (myRecvSequenceNumber != icmpSequenceNo || myRecvId != icmpIdentifier)
    {
        (*pIcmpCmd->pCmdApi->msg)(icmpCmdIoParam, "Ping: wrong reply received\r\n");
    }
    else
    {
        uint32_t pingTicks = SYS_TICK_Get() - icmpStartTick;
        int pingMs = (pingTicks * 1000) / SYS_TICK_ResolutionGet();
        if(pingMs == 0)
        {
            pingMs = 1;
        }

        TCPIP_Helper_IPAddressToString(remoteIP, addBuff, sizeof(addBuff));

        (*pIcmpCmd->pCmdApi->print)(icmpCmdIoParam, "Ping: reply from %s: time = %dms\r\n", addBuff, pingMs);
        icmpAckRecv++;
    }

}
Ejemplo n.º 2
0
/*****************************************************************************
  Function:
	bool DNSClientInit(const TCPIP_STACK_MODULE_CTRL* const stackData,
                       const DNS_CLIENT_MODULE_GONFIG* const dnsData);

  Summary:
	Initializes the DNS module.
	
  Description:
	This function perform the initialization of the DNS client module.
    It has to be called before any other operation with the DNS client
    is possible.

  Precondition:
	Stack is initialized.

  Parameters:
    stackData - stack initialization data

    dnsData   - DNS client module specific initialization data    

  Return Values:
  	true      - the initialization was performed OK and the module is ready to be used
  	false     - The DNS module initialization failed.
  	
  Remarks:
	None
  ***************************************************************************/
bool DNSClientInit(const TCPIP_STACK_MODULE_CTRL* const stackData,
                       const DNS_CLIENT_MODULE_GONFIG* const dnsData)
{
    if(stackData->stackAction == TCPIP_STACK_ACTION_IF_UP)
    {   // interface restart
        return true;
    }

    // stack start up
    if(dnsInitCount != 0)
    {   // initialize just once
        dnsInitCount++;
        return true;
    }

    // 1st time init    
    smDNS = DNS_IDLE;
    Flags.Val = 0;
    DNSSocket = INVALID_UDP_SOCKET;

#if DNS_CLIENT_VERSION_NO >= 2
    if(dnsTimerHandle == 0)
    {   // once per service
        dnsTimerHandle = SYS_TICK_TimerCreate(DNSTmoHandler);
        if(dnsTimerHandle)
        {
            dnsTickPending = 0;
            SYS_TICK_TimerSetRate(dnsTimerHandle, (SYS_TICK_ResolutionGet() * DNS_CLIENT_TASK_PROCESS_RATE)/1000);
        }
        else
        {
            return false;
        }
    }
#endif  // DNS_CLIENT_VERSION_NO >= 2

    dnsInitCount++;
    return true;
}
Ejemplo n.º 3
0
void TCPIPCommandsTask(void)
{
    ICMP_ECHO_RESULT echoRes;
    DNS_RESULT  dnsRes;
    bool killIcmp = false;

    switch(icmpCmdStat)
    {
        case TCPIP_PING_CMD_DNS_GET:

            dnsRes = TCPIP_DNS_UsageBegin(0);
            if(dnsRes == DNS_RES_OK)
            {
                TCPIP_DNS_Resolve(icmpTargetHost, DNS_TYPE_A);
                icmpCmdStat = TCPIP_PING_CMD_DNS_WAIT;
            }
            else if(dnsRes != DNS_RES_BUSY)
            {   // some other error
                (*pIcmpCmd->pCmdApi->print)(icmpCmdIoParam, "Ping: DNS failure for %s\r\n", icmpTargetHost);
                killIcmp = true;
            }
            // else wait some more
            break;

        case TCPIP_PING_CMD_DNS_WAIT:
            dnsRes = TCPIP_DNS_IsResolved(icmpTargetHost, &icmpTargetAddr);
            if(dnsRes == DNS_RES_OK || dnsRes < 0)
            {
                TCPIP_DNS_UsageEnd(0);

                if(dnsRes == DNS_RES_OK)
                {

                    TCPIP_Helper_IPAddressToString(&icmpTargetAddr, icmpTargetAddrStr, sizeof(icmpTargetAddrStr));
                    icmpCmdStat = TCPIP_PING_CMD_DO_PING;
                }
                else
                {
                    (*pIcmpCmd->pCmdApi->print)(icmpCmdIoParam, "Ping: DNS failure for %s\r\n", icmpTargetHost);
                    killIcmp = true;
                }
            }
            // else (dnsRes > 0 ); wait some more
            break;


        case TCPIP_PING_CMD_DO_PING:
            if(icmpReqCount != 0 && icmpAckRecv == 0)
            {   // no reply received; 
                if(SYS_TICK_Get() - icmpStartTick > (SYS_TICK_ResolutionGet() * TCPIP_STACK_COMMANDS_ICMP_ECHO_TIMEOUT) / 1000)
                {   // timeout
                    (*pIcmpCmd->pCmdApi->print)(icmpCmdIoParam, "Ping: request timeout.\r\n");
                    killIcmp = true;
                    break;
                }
                // else wait some more
            }

            if(icmpReqCount == icmpReqNo)
            {   // no more requests to send
                killIcmp = true;
                break;
            }

            // send another request
            echoRes = TCPIP_ICMP_EchoRequestSend (&icmpTargetAddr, ++icmpSequenceNo, icmpIdentifier);

            if(echoRes >= 0 )
            {
                icmpStartTick = SYS_TICK_Get();
                if(icmpReqCount++ == 0)
                {
                    (*pIcmpCmd->pCmdApi->print)(icmpCmdIoParam, "Ping: request sent to: %s [%s]\r\n", icmpTargetHost, icmpTargetAddrStr);
                }
            }
            else
            {
                (*pIcmpCmd->pCmdApi->print)(icmpCmdIoParam, "Ping: failed to send request to: %s\r\n", icmpTargetAddrStr);
                killIcmp = true;
            }

            break;

        default:
            killIcmp = true;
            break;

    }

    if(killIcmp)
    {
        _PingStop(pIcmpCmd, icmpCmdIoParam);
    }

}
Ejemplo n.º 4
0
/*****************************************************************************
  Function:
    void ARPInitialize(const TCPIP_STACK_MODULE_CTRL* const stackCtrl, const ARP_MODULE_CONFIG* const arpData)

  Summary:
    Initializes the ARP module.

  Description:
    Initializes the ARP module.
    Calls can be done with the request of not tearing down the ARP cache
    This helps for ifup/ifdown sequences.
    Of course, if this is the case the memory allocated for the ARP cache
    has to be from a persistent heap.

  Precondition:
    None

  Parameters:
    stackCtrl  - stack initialization parameters
    arpData    - ARP specific initialization parameters

  Returns:
    true if initialization succeded,
    false otherwise

  Remarks:
  ***************************************************************************/
bool ARPInitialize(const TCPIP_STACK_MODULE_CTRL* const stackCtrl, const ARP_MODULE_CONFIG* const arpData)
{
    OA_HASH_DCPT*   cacheDcpt;
    ARP_CACHE_DCPT* pArpDcpt;
    size_t          memSize;
    bool            newCache;

    if(stackCtrl->stackAction == TCPIP_STACK_ACTION_IF_UP)
    {   // interface going up
        return true;
    }

    // stack going up
    pArpDcpt = arpCache + stackCtrl->netIx;

    // store the delete option for de-initialization
    pArpDcpt->deleteOld = arpData->deleteOld;

    if(arpData->deleteOld)
    {   // remove the old stuff, if there
        _ARPCleanupCache(pArpDcpt);
    }
    // else do not re-initialize

    if(pArpDcpt->cacheDcpt == 0)
    {
        // some initialization to be done
        // allocate hash + descriptor contiguously
        memSize = sizeof(OA_HASH_DCPT) + arpData->cacheEntries * sizeof(ARP_HASH_ENTRY);
        cacheDcpt = (OA_HASH_DCPT*)(*stackCtrl->mallocCallback)(stackCtrl->memH, memSize);

        if(cacheDcpt == 0)
        {   // failed
            return false;
        }

        newCache = true;
        // populate the entries
        cacheDcpt->memBlk = cacheDcpt + 1;
        cacheDcpt->hEntrySize = sizeof(ARP_HASH_ENTRY);
        cacheDcpt->hEntries = arpData->cacheEntries;
        cacheDcpt->probeStep = ARP_HASH_PROBE_STEP;

        OAHashInit(cacheDcpt);

        pArpDcpt->cacheDcpt = cacheDcpt;
        SingleListInit(&pArpDcpt->permList);
        SingleListInit(&pArpDcpt->completeList);
        SingleListInit(&pArpDcpt->incompleteList);

        pArpDcpt->purgeThres = (ARP_CACHE_PURGE_THRESHOLD * pArpDcpt->cacheDcpt->hEntries)/100;
        pArpDcpt->purgeQuanta = ARP_CACHE_PURGE_QUANTA;
    }
    else
    {   // didn't create anything now
        newCache = false;
    }

    if(arpTimerHandle == 0)
    {   // once per service
        SingleListInit(&arpRegisteredUsers);
        // store the memory allocation handle
        arpMemH = stackCtrl->memH;

        arpTimerHandle = SYS_TICK_TimerCreate(ARPTmoHandler);
        if(arpTimerHandle)
        {
            arpTickPending = arpTimeSeconds = 0;
            SYS_TICK_TimerSetRate(arpTimerHandle, SYS_TICK_ResolutionGet() * ARP_TASK_PROCESS_RATE);
        }
        else
        {   // failed
            if(newCache)
            {
                _ARPCleanupCache(pArpDcpt);
            }
            return false;
        }
    }

    pArpDcpt->inited = true;

    return true;
}
Ejemplo n.º 5
0
/*****************************************************************************
  Function:
	void PingDemoTask (void)

  Summary:
	Handles state machine for ping demo processes.
	
  Description:
	This function performs state processing for the ping demo.
	
	This function can be used as a model for applications requiring Ping6 
	capabilities to check if a host is reachable.

  Precondition:
	None.

  Parameters:
	None

  Returns:
  	None
  ***************************************************************************/
void PingDemoTask (void)
{
    switch (pingState)
    {
#if defined (TCPIP_STACK_USE_ICMP_CLIENT)
        case STATE_DNS_SEND_QUERY_IPV4:
            if (!DNSBeginUsage(pNetIf))
                return;

            if (DNSResolve((const char *)targetHostName, DNS_TYPE_A) != DNS_RES_OK)
                return;

            pingTimer = SYS_TICK_Get() + (SYS_TICK_ResolutionGet() * TCPIP_PING_DNS_TIMEOUT);
            pingState = STATE_DNS_GET_RESPONSE_IPV4;
            break;
        case STATE_DNS_GET_RESPONSE_IPV4:
            {
                DNS_RESULT res;
                if ((long)(SYS_TICK_Get() - pingTimer) > 0)
                {
                    SYS_OUT_MESSAGE_LINE("Couldn't resolve", 2);
                    DNSEndUsage(pNetIf);
                    pingState = STATE_IDLE;
                    return;
                } 
    
                res = DNSIsResolved((const char *)targetHostName, &targetAddressIPv4);

                switch (res)
                {
                    case DNS_RES_OK:
                        DNSEndUsage(pNetIf);
                        pingState = STATE_RESOLVE_ARP;
                        break;
                    case DNS_RES_PENDING:
                        
                        break;
                    default:
                        SYS_OUT_MESSAGE_LINE ("Couldn't resolve", 1);
                        DNSEndUsage(pNetIf);
                        pingState = STATE_IDLE;
                        break;
                }
            }
            break;
		case STATE_RESOLVE_ARP:
            if ((targetAddressIPv4.Val & pNetIf->MyMask.Val) == pNetIf->MyMask.Val)
                firstHopAddress.Val = targetAddressIPv4.Val;
            else
                firstHopAddress.Val = pNetIf->MyGateway.Val;
  			ARPResolve(pNetIf, &firstHopAddress);
			pingTimer = SYS_TICK_Get();
			pingState = STATE_ARP_RESOLVED;
			break;

		case STATE_ARP_RESOLVED:
			if(!ARPIsResolved(pNetIf, &firstHopAddress, &targetMACAddr))
			{
				if(SYS_TICK_Get() - pingTimer > (TCPIP_PING_DNS_TIMEOUT * SYS_TICK_TicksPerSecondGet()))
                {
                    SYS_OUT_MESSAGE_LINE ("Couldn't ARP", 1);
					pingState = STATE_IDLE;
                }
				break;
			}

			pingState = STATE_SEND_ECHO_REQUEST_IPV4;
            break;
#endif
#if defined (TCPIP_STACK_USE_IPV6)
        case STATE_DNS_SEND_QUERY_IPV6:
            if (!DNSBeginUsage(pNetIf))
                return;

            if (DNSResolve((const char *)targetHostName, DNS_TYPE_AAAA) != DNS_RES_OK)
                return;

            pingTimer = SYS_TICK_Get() + (SYS_TICK_ResolutionGet() * TCPIP_PING_DNS_TIMEOUT);
            pingState = STATE_DNS_GET_RESPONSE_IPV6;
            break;
        case STATE_DNS_GET_RESPONSE_IPV6:
            {
                DNS_RESULT res;
                if ((long)(SYS_TICK_Get() - pingTimer) > 0)
                {
                    SYS_OUT_MESSAGE_LINE ("Couldn't resolve", 1);
                    DNSEndUsage(pNetIf);
                    pingState = STATE_IDLE;
                    return;
                } 
    
                res = DNSIsResolved((const char *)targetHostName, &targetAddressIPv6);

                switch (res)
                {
                    case DNS_RES_OK:
                        DNSEndUsage(pNetIf);
                        pingState = STATE_SEND_ECHO_REQUEST_IPV6;
                        break;
                    case DNS_RES_PENDING:
                        
                        break;
                    default:
                        SYS_OUT_MESSAGE_LINE ("Couldn't resolve", 1);
                        DNSEndUsage(pNetIf);
                        pingState = STATE_IDLE;
                        break;
                }
            }
            break;
#endif
#if defined(TCPIP_STACK_USE_ICMP_CLIENT)
        case STATE_SEND_ECHO_REQUEST_IPV4:
            {
                NODE_INFO info;

                info.IPAddr = targetAddressIPv4;
                memcpy (&info.MACAddr, &targetMACAddr, sizeof (MAC_ADDR));
                ICMPSendEchoRequest (&info, ++wICMPSequenceNumber, 0xBEEF);

    			// Record the current time.  This will be used as a basis for 
    			// finding the echo response time, which exludes the ARP and DNS 
    			// steps
   			    pingTimer = SYS_TICK_Get();
    
                pingCount++;

                SYS_OUT_MESSAGE_LINE ("Pinging...", 1);

    			// Echo sent, advance state
    			pingState = STATE_GET_RESPONSE_IPV4;
            }
            break;
#endif
#if defined (TCPIP_STACK_USE_IPV6)
        case STATE_SEND_ECHO_REQUEST_IPV6:
            {
                IP_PACKET * pkt;
                IPV6_ADDR_STRUCT * localAddress;

                localAddress = TCPIP_IPV6_DAS_SelectSourceAddress (pNetIf, &targetAddressIPv6, NULL);

                if (localAddress == NULL)
                {
                    SYS_OUT_MESSAGE_LINE ("No local addr!", 1);
                    pingState = STATE_IDLE;
                    break;
                }
    
                pkt = TCPIP_ICMPV6_PutHeaderEchoRequest (pNetIf, &localAddress->address, &targetAddressIPv6, ICMPV6_INFO_ECHO_REQUEST, 
                                                    0xEFBE, ++wICMPSequenceNumber);
    
                if (TCPIP_IP_IsTxPutReady(pkt, 4) < 4)
                {
                    TCPIP_IP_FreePacket (pkt);
                    return;
                }
    
                TCPIP_IP_PutArray (pkt, (uint8_t *)&miscData, sizeof (uint32_t));
    
                // Just let the IPv6 module figure out the next hop neighbor and its MAC address
                TCPIP_ICMPV6_Flush (pkt);
    		
    			// Record the current time.  This will be used as a basis for 
    			// finding the echo response time, which exludes the ARP and DNS 
    			// steps
   			    pingTimer = SYS_TICK_Get();
    
                pingCount++;

                SYS_OUT_MESSAGE_LINE ("Pinging...", 1);

    			// Echo sent, advance state
    			pingState = STATE_GET_RESPONSE_IPV6;
            }
            break;
#endif
#if defined (TCPIP_STACK_USE_ICMP_CLIENT)
        case STATE_GET_RESPONSE_IPV4:
            if ((long)(SYS_TICK_Get() - pingTimer) > (SYS_TICK_ResolutionGet() * TCPIP_PING_TIMEOUT))
            {
                SYS_OUT_MESSAGE_LINE("Ping timeout", 1);
                pingState = STATE_IDLE;
            }            
            break;
#endif
#if defined (TCPIP_STACK_USE_IPV6)
        case STATE_GET_RESPONSE_IPV6:
            if ((long)(SYS_TICK_Get() - pingTimer) > (SYS_TICK_ResolutionGet() * TCPIP_PING_TIMEOUT))
            {
                SYS_OUT_MESSAGE_LINE ("Ping timeout", 1);
                pingState = STATE_IDLE;
            }
            break;
#endif
        default:
        case STATE_IDLE:
            break;
        
    }
}