/***************************************************************************** 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; } }
/***************************************************************************** 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; } }