/* * Copyright (c) 2018-2019 ARM Limited * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef WHD_DHCP_SERVER_H #define WHD_DHCP_SERVER_H #include "cy_result.h" #include "cy_syslib.h" #include "cynetwork_utils.h" #include "UDPSocket.h" #include "netsocket/NetworkInterface.h" #include "netsocket/NetworkStack.h" #include "rtos.h" /* DHCP data structure */ typedef struct { uint8_t Opcode; /* packet opcode type */ uint8_t HwType; /* hardware addr type */ uint8_t HwLen; /* hardware addr length */ uint8_t Hops; /* gateway hops */ uint32_t TransactionId; /* transaction ID */ uint16_t SecsElapsed; /* seconds since boot began */ uint16_t Flags; uint32_t ClientIpAddr; /* client IP address */ uint32_t YourIpAddr; /* 'your' IP address */ uint32_t ServerIpAddr; /* server IP address */ uint32_t GatewayIpAddr; /* gateway IP address */ uint8_t ClientHwAddr[16]; /* client hardware address */ uint8_t Legacy[192]; /* SName, File */ uint32_t MagicCookie; uint8_t Options[3]; /* options area */ /* as of RFC2131 it is variable length */ } dhcp_packet_t; #define DHCP_SUBNETMASK_OPTION_CODE (1) #define DHCP_ROUTER_OPTION_CODE (3) #define DHCP_DNS_SERVER_OPTION_CODE (6) #define DHCP_HOST_NAME_OPTION_CODE (12) #define DHCP_MTU_OPTION_CODE (26) #define DHCP_REQUESTED_IP_ADDRESS_OPTION_CODE (50) #define DHCP_LEASETIME_OPTION_CODE (51) #define DHCP_MESSAGETYPE_OPTION_CODE (53) #define DHCP_SERVER_IDENTIFIER_OPTION_CODE (54) #define DHCP_PARAM_REQUEST_LIST_OPTION_CODE (55) #define DHCP_WPAD_OPTION_CODE (252) #define DHCP_END_OPTION_CODE (255) #define DHCP_IP_ADDRESS_CACHE_MAX (5) #define ADDITIONAL_OPTION_BYTES (272) #define DHCP_PACKET_SIZE (sizeof(dhcp_packet_t) + ADDITIONAL_OPTION_BYTES) /** DHCP thread could not be started */ #define CY_DHCP_THREAD_CREATION_FAILED CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_BASE, 0) /** Error while trying to stop the DHCP server */ #define CY_DHCP_STOP_FAILED CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_BASE, 1) /** * Implementation of a DHCP sever */ class CyDhcpServer { public: /** * Create a DHCP server. */ CyDhcpServer(NetworkStack *nstack, NetworkInterface *niface); /** * Delete the DHCP server. */ virtual ~CyDhcpServer(); /** * Start a DHCP server instance. * @return CY_RSLT_SUCCESS on success otherwise error. */ cy_rslt_t start(void); /** * Stop a DHCP server instance. * @return CY_RSLT_SUCCESS on success otherwise error. */ cy_rslt_t stop(void); private: NetworkStack *_nstack = NULL; NetworkInterface *_niface = NULL; UDPSocket _socket; Thread _thread; bool _running = false; cy_ip_addr_t _available_addr; cy_ip_addr_t _server_addr; cy_ip_addr_t _netmask; cy_mac_addr_t _mac_addr_cache[DHCP_IP_ADDRESS_CACHE_MAX]; cy_ip_addr_t _ip_addr_cache[DHCP_IP_ADDRESS_CACHE_MAX]; uint8_t _buff[DHCP_PACKET_SIZE]; static void threadWrapper(CyDhcpServer *obj); void runServer(void); void setAddress(const cy_mac_addr_t &mac_id, const cy_ip_addr_t &addr); bool lookupAddress(const cy_mac_addr_t &mac_id, cy_ip_addr_t &addr); void freeAddress(const cy_mac_addr_t &mac_id); void handleDiscover(dhcp_packet_t *dhcp); void handleRequest(dhcp_packet_t *dhcp); }; #endif /* WHD_DHCP_SERVER_H */