Esempio n. 1
0
static void l2_packet_receive_timeout(void *eloop_ctx, void *timeout_ctx)
{
	struct l2_packet_data *l2 = eloop_ctx;
	pcap_t *pcap = timeout_ctx;
	/* Register new timeout before calling l2_packet_receive() since
	 * receive handler may free this l2_packet instance (which will
	 * cancel this timeout). */
	eloop_register_timeout(0, 100000, l2_packet_receive_timeout,
			       l2, pcap);
	l2_packet_receive(-1, eloop_ctx, timeout_ctx);
}
/*********************************************************************
 * Function:        void StackTask(void)
 *
 * PreCondition:    StackInit() is already called.
 *
 * Input:           None
 *
 * Output:          Stack FSM is executed.
 *
 * Side Effects:    None
 *
 * Note:            This FSM checks for new incoming packets,
 *                  and routes it to appropriate stack components.
 *                  It also performs timed operations.
 *
 *                  This function must be called periodically to
 *                  ensure timely responses.
 *
 ********************************************************************/
void StackTask(void)
{
    WORD dataCount;
    IP_ADDR tempLocalIP;
	BYTE cFrameType;
	BYTE cIPFrameType;

   
    #if defined( WF_CS_TRIS )
        // This task performs low-level MAC processing specific to the MRF24W
        MACProcess();
        #if defined( STACK_USE_EZ_CONFIG ) && !defined(__18CXX)
            WFEasyConfigMgr();
        #endif
        
    	#if defined(STACK_USE_DHCP_CLIENT)
        	// Normally, an application would not include  DHCP module
        	// if it is not enabled. But in case some one wants to disable
        	// DHCP module at run-time, remember to not clear our IP
        	// address if link is removed.
        	if(AppConfig.Flags.bIsDHCPEnabled)
        	{
        		if(g_DhcpRenew == TRUE)
        		{
        			g_DhcpRenew = FALSE;
            		AppConfig.MyIPAddr.Val = AppConfig.DefaultIPAddr.Val;
        			AppConfig.MyMask.Val = AppConfig.DefaultMask.Val;
        			AppConfig.Flags.bInConfigMode = TRUE;
        			DHCPInit(0);
					g_DhcpRetryTimer = (UINT32)TickGet();
        		} else {
        			if (g_DhcpRetryTimer && TickGet() - g_DhcpRetryTimer >= TICKS_PER_SECOND * 8) {
						DHCPInit(0);
						g_DhcpRetryTimer = (UINT32)TickGet();
        			}
        		}
        	
        		// DHCP must be called all the time even after IP configuration is
        		// discovered.
        		// DHCP has to account lease expiration time and renew the configuration
        		// time.
        		DHCPTask();
        		
        		if(DHCPIsBound(0)) {
        			AppConfig.Flags.bInConfigMode = FALSE;
					g_DhcpRetryTimer = 0;
        		}
        	}
    	#endif // STACK_USE_DHCP_CLIENT
        
    #endif // WF_CS_TRIS


	#if defined(STACK_USE_DHCP_CLIENT) && !defined(WF_CS_TRIS)
	// Normally, an application would not include  DHCP module
	// if it is not enabled. But in case some one wants to disable
	// DHCP module at run-time, remember to not clear our IP
	// address if link is removed.
	if(AppConfig.Flags.bIsDHCPEnabled)
	{
		static BOOL bLastLinkState = FALSE;
		BOOL bCurrentLinkState;
		
		bCurrentLinkState = MACIsLinked();
		if(bCurrentLinkState != bLastLinkState)
		{
			bLastLinkState = bCurrentLinkState;
			if(!bCurrentLinkState)
			{
				AppConfig.MyIPAddr.Val = AppConfig.DefaultIPAddr.Val;
				AppConfig.MyMask.Val = AppConfig.DefaultMask.Val;
				AppConfig.Flags.bInConfigMode = TRUE;
				DHCPInit(0);
			}
		}
	
		// DHCP must be called all the time even after IP configuration is
		// discovered.
		// DHCP has to account lease expiration time and renew the configuration
		// time.
		DHCPTask();
		
		if(DHCPIsBound(0))
			AppConfig.Flags.bInConfigMode = FALSE;
	}
	#endif
	

    #if defined (STACK_USE_AUTO_IP)
    AutoIPTasks();
    #endif

	#if defined(STACK_USE_TCP)
	// Perform all TCP time related tasks (retransmit, send acknowledge, close connection, etc)
	TCPTick();
	#endif


	#if defined(STACK_USE_UDP)
	UDPTask();
	#endif

	// Process as many incomming packets as we can
	while(1)
	{
		//if using the random module, generate entropy
		#if defined(STACK_USE_RANDOM)
			RandomAdd(remoteNode.MACAddr.v[5]);
		#endif

		// We are about to fetch a new packet, make sure that the 
		// UDP module knows that any old RX data it has laying 
		// around will now be gone.
		#if defined(STACK_USE_UDP)
			UDPDiscard();
		#endif

		// Fetch a packet (throws old one away, if not thrown away 
		// yet)
		if(!MACGetHeader(&remoteNode.MACAddr, &cFrameType))
			break;
		
		// When using a WiFi module, filter out all incoming packets that have 
		// the same source MAC address as our own MAC address.  This is to 
		// prevent receiving and passing our own broadcast packets up to other 
		// layers and avoid, for example, having our own gratuitous ARPs get 
		// answered by ourself.
		#if defined(WF_CS_TRIS)
			if(memcmp((void*)&remoteNode.MACAddr, (void*)&AppConfig.MyMACAddr, 6) == 0u)
				continue;

			#if defined(CONFIG_WPA_ENTERPRISE)
			if (cFrameType == MAC_UNKNOWN) {
				static unsigned char buf[2300];
				struct ieee8021xhdr *hdr = (struct ieee8021xhdr *)buf;
				MACGetArray((BYTE*)hdr, sizeof(*hdr));
				if (SWAP16(hdr->length) > 0)
					MACGetArray((BYTE*)(hdr + 1), SWAP16(hdr->length));
				l2_packet_receive(hdr, SWAP16(hdr->length) + sizeof(*hdr), &remoteNode.MACAddr);
				continue;
			}
			#endif /* defined(CONFIG_WPA_ENTERPRISE) */
		#endif	/* defined(WF_CS_TRIS) */

		// Dispatch the packet to the appropriate handler
		switch(cFrameType)
		{
			case MAC_ARP:
				ARPProcess();
				break;
	
			case MAC_IP:
				if(!IPGetHeader(&tempLocalIP, &remoteNode, &cIPFrameType, &dataCount))
					break;

				#if defined(STACK_USE_ICMP_SERVER) || defined(STACK_USE_ICMP_CLIENT)
				if(cIPFrameType == IP_PROT_ICMP)
				{
					#if defined(STACK_USE_IP_GLEANING)
					if(AppConfig.Flags.bInConfigMode && AppConfig.Flags.bIsDHCPEnabled)
					{
						// According to "IP Gleaning" procedure,
						// when we receive an ICMP packet with a valid
						// IP address while we are still in configuration
						// mode, accept that address as ours and conclude
						// configuration mode.
						if(tempLocalIP.Val != 0xffffffff)
						{
							AppConfig.Flags.bInConfigMode = FALSE;
							AppConfig.MyIPAddr = tempLocalIP;
						}
					}
					#endif

					// Process this ICMP packet if it the destination IP address matches our address or one of the broadcast IP addressees
					if( (tempLocalIP.Val == AppConfig.MyIPAddr.Val) ||
						(tempLocalIP.Val == 0xFFFFFFFF) ||
#if defined(STACK_USE_ZEROCONF_LINK_LOCAL) || defined(STACK_USE_ZEROCONF_MDNS_SD)
                                                (tempLocalIP.Val == 0xFB0000E0) ||
#endif
						(tempLocalIP.Val == ((AppConfig.MyIPAddr.Val & AppConfig.MyMask.Val) | ~AppConfig.MyMask.Val)))
					{
						ICMPProcess(&remoteNode, dataCount);
					}

					break;
				}
				#endif
				
				#if defined(STACK_USE_TCP)
				if(cIPFrameType == IP_PROT_TCP)
				{
					TCPProcess(&remoteNode, &tempLocalIP, dataCount);
					break;
				}
				#endif
				
				#if defined(STACK_USE_UDP)
				if(cIPFrameType == IP_PROT_UDP)
				{
					// Stop processing packets if we came upon a UDP frame with application data in it
					if(UDPProcess(&remoteNode, &tempLocalIP, dataCount))
						return;
				}
				#endif

				break;
		}
	}
}