Example #1
0
/*****************************************************************************
  Function:
	void DHCPServerTask(NET_CONFIG* pConfig)

  Summary:
	Performs periodic DHCP server tasks.

  Description:
	This function performs any periodic tasks requied by the DHCP server 
	module, such as processing DHCP requests and distributing IP addresses.

  Precondition:
	None

  Parameters:
	pConfig   - interface

  Returns:
  	None
  ***************************************************************************/
void DHCPServerTask(NET_CONFIG* pConfig)
{
	uint8_t 				i;
	uint8_t				Option, Len;
	BOOTP_HEADER		BOOTPHeader;
	uint32_t				dw;
	bool				bAccept;
    int                 netIx;
    UDP_SOCKET          s;
    

#if defined(TCPIP_STACK_USE_DHCP_CLIENT)
	// Make sure we don't clobber anyone else's DHCP server
	if(DHCPIsServerDetected(pConfig))
		return;
#endif

    netIx = _TCPIPStackNetIx(pConfig);
	if(!bDHCPServerEnabled[netIx])
		return;

    s = MySocket[netIx];

	switch(smDHCPServer[netIx])
	{
		case DHCP_OPEN_SOCKET:
			// Obtain a UDP socket to listen/transmit on
			MySocket[netIx] = UDPOpen(0,UDP_OPEN_SERVER,DHCP_SERVER_PORT, DHCP_CLIENT_PORT);
			if(MySocket[netIx] == INVALID_UDP_SOCKET)
				break;

            UDPSocketSetNet(MySocket[netIx], pConfig);
			// Decide which address to lease out
			// Note that this needs to be changed if we are to 
			// support more than one lease
			DHCPNextLease[netIx].Val = (pConfig->MyIPAddr.Val & pConfig->MyMask.Val) + 0x02000000;
			if(DHCPNextLease[netIx].v[3] == 255u)
				DHCPNextLease[netIx].v[3] += 0x03;
			if(DHCPNextLease[netIx].v[3] == 0u)
				DHCPNextLease[netIx].v[3] += 0x02;

			smDHCPServer[netIx]++;

		case DHCP_LISTEN:
			// Check to see if a valid DHCP packet has arrived
			if(UDPIsGetReady(s) < 241u)
				break;

			// Retrieve the BOOTP header
			UDPGetArray(s, (uint8_t*)&BOOTPHeader, sizeof(BOOTPHeader));

			bAccept = (BOOTPHeader.ClientIP.Val == DHCPNextLease[netIx].Val) || (BOOTPHeader.ClientIP.Val == 0x00000000u);

			// Validate first three fields
			if(BOOTPHeader.MessageType != 1u)
				break;
			if(BOOTPHeader.HardwareType != 1u)
				break;
			if(BOOTPHeader.HardwareLen != 6u)
				break;

			// Throw away 10 unused bytes of hardware address,
			// server host name, and boot file name -- unsupported/not needed.
			for(i = 0; i < 64+128+(16-sizeof(MAC_ADDR)); i++)
				UDPGet(s, &Option);

			// Obtain Magic Cookie and verify
			UDPGetArray(s, (uint8_t*)&dw, sizeof(uint32_t));
			if(dw != 0x63538263ul)
				break;

			// Obtain options
			while(1)
			{
				// Get option type
				if(!UDPGet(s, &Option))
					break;
				if(Option == DHCP_END_OPTION)
					break;

				// Get option length
				UDPGet(s, &Len);
	
				// Process option
				switch(Option)
				{
					case DHCP_MESSAGE_TYPE:
						UDPGet(s, &i);
						switch(i)
						{
							case DHCP_DISCOVER_MESSAGE:
								DHCPReplyToDiscovery(&BOOTPHeader, netIx);
								break;

							case DHCP_REQUEST_MESSAGE:
							// NOTE : This #if section was missing from 5.36
                                #if defined(TCPIP_STACK_USE_ZEROCONF_LINK_LOCAL)
								if ( (BOOTPHeader.ClientIP.Val == 0x00000000u) &&
									 (bLeaseAvailable[netIx] == false) )
								{
									// Lease available only to the current lease holder
									break;
								}
								#endif

								DHCPReplyToRequest(&BOOTPHeader, bAccept, netIx);

							// NOTE : This #if section was missing from 5.36
                                #if defined(TCPIP_STACK_USE_ZEROCONF_LINK_LOCAL)
								bLeaseAvailable[netIx] = false;
								#endif

								break;

							// Need to handle these if supporting more than one DHCP lease
							case DHCP_RELEASE_MESSAGE:
							case DHCP_DECLINE_MESSAGE:
								break;
						}
						break;

					case DHCP_PARAM_REQUEST_IP_ADDRESS:
						if(Len == 4u)
						{
							// Get the requested IP address and see if it is the one we have on offer.
							UDPGetArray(s, (uint8_t*)&dw, 4);
							Len -= 4;
							bAccept = (dw == DHCPNextLease[netIx].Val);
						}
						break;

					case DHCP_END_OPTION:
						UDPDiscard(s);
						return;
				}

				// Remove any unprocessed bytes that we don't care about
				while(Len--)
				{
					UDPGet(s, &i);
				}
			}			

			UDPDiscard(s);
			break;
	}
}
Example #2
0
/*****************************************************************************
  Function:
	void DHCPServerTask(void)

  Summary:
	Performs periodic DHCP server tasks.

  Description:
	This function performs any periodic tasks requied by the DHCP server 
	module, such as processing DHCP requests and distributing IP addresses.

  Precondition:
	None

  Parameters:
	None

  Returns:
  	None
  ***************************************************************************/
void DHCPServerTask(void)
{
	BYTE 				i;
	BYTE				Option, Len;
	BOOTP_HEADER		BOOTPHeader;
	DWORD				dw;
	BOOL				bAccept;
	static enum
	{
		DHCP_OPEN_SOCKET,
		DHCP_LISTEN
	} smDHCPServer = DHCP_OPEN_SOCKET;

#if defined(STACK_USE_DHCP_CLIENT)
	// Make sure we don't clobber anyone else's DHCP server
	if(DHCPIsServerDetected(0))
		return;
#endif

	if(!bDHCPServerEnabled)
		return;

	switch(smDHCPServer)
	{
		case DHCP_OPEN_SOCKET:
			// Obtain a UDP socket to listen/transmit on
			//MySocket = UDPOpen(DHCP_SERVER_PORT, NULL, DHCP_CLIENT_PORT);
			MySocket = UDPOpenEx(0,UDP_OPEN_SERVER,DHCP_SERVER_PORT, DHCP_CLIENT_PORT);
			if(MySocket == INVALID_UDP_SOCKET)
				break;


			// Decide which address to lease out
			// Note that this needs to be changed if we are to 
			// support more than one lease
			DHCPNextLease.Val = (AppConfig.MyIPAddr.Val & AppConfig.MyMask.Val) + 0x02000000;
			if(DHCPNextLease.v[3] == 255u)
				DHCPNextLease.v[3] += 0x03;
			if(DHCPNextLease.v[3] == 0u)
				DHCPNextLease.v[3] += 0x02;

			smDHCPServer++;

		case DHCP_LISTEN:
			// Check to see if a valid DHCP packet has arrived
			if(UDPIsGetReady(MySocket) < 241u)
				break;

			// Retrieve the BOOTP header
			UDPGetArray((BYTE*)&BOOTPHeader, sizeof(BOOTPHeader));

			bAccept = (BOOTPHeader.ClientIP.Val == DHCPNextLease.Val) || (BOOTPHeader.ClientIP.Val == 0x00000000u);

			// Validate first three fields
			if(BOOTPHeader.MessageType != 1u)
				break;
			if(BOOTPHeader.HardwareType != 1u)
				break;
			if(BOOTPHeader.HardwareLen != 6u)
				break;

			// Throw away 10 unused bytes of hardware address,
			// server host name, and boot file name -- unsupported/not needed.
			for(i = 0; i < 64+128+(16-sizeof(MAC_ADDR)); i++)
				UDPGet(&Option);

			// Obtain Magic Cookie and verify
			UDPGetArray((BYTE*)&dw, sizeof(DWORD));
			if(dw != 0x63538263ul)
				break;

			// Obtain options
			while(1)
			{
				// Get option type
				if(!UDPGet(&Option))
					break;
				if(Option == DHCP_END_OPTION)
					break;

				// Get option length
				UDPGet(&Len);
	
				// Process option
				switch(Option)
				{
					case DHCP_MESSAGE_TYPE:
						UDPGet(&i);
						switch(i)
						{
							case DHCP_DISCOVER_MESSAGE:
								DHCPReplyToDiscovery(&BOOTPHeader);
								break;

							case DHCP_REQUEST_MESSAGE:
								DHCPReplyToRequest(&BOOTPHeader, bAccept);
								break;

							// Need to handle these if supporting more than one DHCP lease
							case DHCP_RELEASE_MESSAGE:
							case DHCP_DECLINE_MESSAGE:
								break;
						}
						break;

					case DHCP_PARAM_REQUEST_IP_ADDRESS:
						if(Len == 4u)
						{
							// Get the requested IP address and see if it is the one we have on offer.
							UDPGetArray((BYTE*)&dw, 4);
							Len -= 4;
							bAccept = (dw == DHCPNextLease.Val);
						}
						break;

					case DHCP_END_OPTION:
						UDPDiscard();
						return;
				}

				// Remove any unprocessed bytes that we don't care about
				while(Len--)
				{
					UDPGet(&i);
				}
			}			

			UDPDiscard();
			break;
	}
}