| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433 |
- /*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- //#include "esp_common.h"
- #include <stdlib.h>
- #include <string.h>
- #include "lwip/dhcp.h"
- #include "lwip/err.h"
- #include "lwip/pbuf.h"
- #include "lwip/udp.h"
- #include "lwip/mem.h"
- #include "lwip/ip_addr.h"
- #include "lwip/timeouts.h"
- #include "dhcpserver/dhcpserver.h"
- #include "dhcpserver/dhcpserver_options.h"
- #if ESP_DHCPS
- #ifdef LWIP_HOOK_FILENAME
- #include LWIP_HOOK_FILENAME
- #endif
- #ifndef LWIP_HOOK_DHCPS_POST_APPEND_OPTS
- #define LWIP_HOOK_DHCPS_POST_APPEND_OPTS(netif, dhcps, state, pp_opts)
- #endif
- #define BOOTP_BROADCAST 0x8000
- #define DHCP_REQUEST 1
- #define DHCP_REPLY 2
- #define DHCP_HTYPE_ETHERNET 1
- #define DHCP_HLEN_ETHERNET 6
- #define DHCP_MSG_LEN 236
- #define DHCPS_SERVER_PORT 67
- #define DHCPS_CLIENT_PORT 68
- #define DHCPDISCOVER 1
- #define DHCPOFFER 2
- #define DHCPREQUEST 3
- #define DHCPDECLINE 4
- #define DHCPACK 5
- #define DHCPNAK 6
- #define DHCPRELEASE 7
- #define DHCP_OPTION_SUBNET_MASK 1
- #define DHCP_OPTION_ROUTER 3
- #define DHCP_OPTION_DNS_SERVER 6
- #define DHCP_OPTION_REQ_IPADDR 50
- #define DHCP_OPTION_LEASE_TIME 51
- #define DHCP_OPTION_MSG_TYPE 53
- #define DHCP_OPTION_SERVER_ID 54
- #define DHCP_OPTION_INTERFACE_MTU 26
- #define DHCP_OPTION_PERFORM_ROUTER_DISCOVERY 31
- #define DHCP_OPTION_BROADCAST_ADDRESS 28
- #define DHCP_OPTION_REQ_LIST 55
- #define DHCP_OPTION_END 255
- //#define USE_CLASS_B_NET 1
- #define DHCPS_DEBUG 0
- #define DHCPS_LOG printf
- #define MAX_STATION_NUM CONFIG_LWIP_DHCPS_MAX_STATION_NUM
- #define DHCPS_STATE_OFFER 1
- #define DHCPS_STATE_DECLINE 2
- #define DHCPS_STATE_ACK 3
- #define DHCPS_STATE_NAK 4
- #define DHCPS_STATE_IDLE 5
- #define DHCPS_STATE_RELEASE 6
- typedef enum {
- DHCPS_HANDLE_CREATED = 0,
- DHCPS_HANDLE_STARTED,
- DHCPS_HANDLE_STOPPED,
- DHCPS_HANDLE_DELETE_PENDING,
- } dhcps_handle_state;
- typedef struct list_node {
- void *pnode;
- struct list_node *pnext;
- } list_node;
- typedef struct {
- ip4_addr_t ip;
- ip4_addr_t netmask;
- ip4_addr_t gw;
- } ip_info_t;
- ////////////////////////////////////////////////////////////////////////////////////
- static const u32_t magic_cookie = 0x63538263;
- struct dhcps_t {
- struct netif *dhcps_netif;
- ip4_addr_t broadcast_dhcps;
- ip4_addr_t server_address;
- ip4_addr_t dns_server;
- ip4_addr_t client_address;
- ip4_addr_t client_address_plus;
- ip4_addr_t dhcps_mask;
- list_node *plist;
- bool renew;
- dhcps_lease_t dhcps_poll;
- dhcps_time_t dhcps_lease_time;
- dhcps_offer_t dhcps_offer;
- dhcps_offer_t dhcps_dns;
- dhcps_cb_t dhcps_cb;
- void* dhcps_cb_arg;
- struct udp_pcb *dhcps_pcb;
- dhcps_handle_state state;
- };
- static void dhcps_tmr(void* arg);
- dhcps_t *dhcps_new(void)
- {
- dhcps_t *dhcps = mem_calloc(1, sizeof(dhcps_t));
- if (dhcps == NULL) {
- return NULL;
- }
- dhcps->dhcps_netif = NULL;
- dhcps->dns_server.addr = 0;
- #ifdef USE_CLASS_B_NET
- dhcps->dhcps_mask.addr = PP_HTONL(LWIP_MAKEU32(255, 240, 0, 0));
- #else
- dhcps->dhcps_mask.addr = PP_HTONL(LWIP_MAKEU32(255, 255, 255, 0));
- #endif
- dhcps->plist = NULL;
- dhcps->renew = false;
- dhcps->dhcps_lease_time = DHCPS_LEASE_TIME_DEF;
- dhcps->dhcps_offer = 0xFF;
- dhcps->dhcps_dns = 0x00;
- dhcps->dhcps_pcb = NULL;
- dhcps->state = DHCPS_HANDLE_CREATED;
- return dhcps;
- }
- void dhcps_delete(dhcps_t *dhcps)
- {
- if (dhcps) {
- if (dhcps->state == DHCPS_HANDLE_STARTED) {
- // if the dhcp-server has started already, we have to postpone the deletion
- dhcps->state = DHCPS_HANDLE_DELETE_PENDING;
- } else {
- // otherwise, we're free to delete the handle immediately
- free(dhcps);
- }
- }
- }
- static void get_ip_info(struct netif * netif, ip_info_t *ip_info)
- {
- if (netif != NULL && netif_is_up(netif)) {
- ip4_addr_set(&ip_info->ip, ip_2_ip4(&netif->ip_addr));
- ip4_addr_set(&ip_info->netmask, ip_2_ip4(&netif->netmask));
- ip4_addr_set(&ip_info->gw, ip_2_ip4(&netif->gw));
- }
- }
- /******************************************************************************
- * FunctionName : dhcps_option_info
- * Description : get the DHCP message option info
- * Parameters : op_id -- DHCP message option id
- * opt_len -- DHCP message option length
- * Returns : DHCP message option addr
- *******************************************************************************/
- void *dhcps_option_info(dhcps_t *dhcps, u8_t op_id, u32_t opt_len)
- {
- void *option_arg = NULL;
- if (dhcps == NULL) {
- return NULL;
- }
- switch (op_id) {
- case IP_ADDRESS_LEASE_TIME:
- if (opt_len == sizeof(dhcps_time_t)) {
- option_arg = &dhcps->dhcps_lease_time;
- }
- break;
- case REQUESTED_IP_ADDRESS:
- if (opt_len == sizeof(dhcps_lease_t)) {
- option_arg = &dhcps->dhcps_poll;
- }
- break;
- case ROUTER_SOLICITATION_ADDRESS:
- if (opt_len == sizeof(dhcps_offer_t)) {
- option_arg = &dhcps->dhcps_offer;
- }
- break;
- case DOMAIN_NAME_SERVER:
- if (opt_len == sizeof(dhcps_offer_t)) {
- option_arg = &dhcps->dhcps_dns;
- }
- break;
- case SUBNET_MASK:
- if (opt_len == sizeof(dhcps->dhcps_mask)) {
- option_arg = &dhcps->dhcps_mask;
- }
- break;
- default:
- break;
- }
- return option_arg;
- }
- /******************************************************************************
- * FunctionName : dhcps_set_option_info
- * Description : set the DHCP message option info
- * Parameters : op_id -- DHCP message option id
- * opt_info -- DHCP message option info
- * opt_len -- DHCP message option length
- * Returns : none
- *******************************************************************************/
- err_t dhcps_set_option_info(dhcps_t *dhcps, u8_t op_id, void *opt_info, u32_t opt_len)
- {
- if (dhcps == NULL || opt_info == NULL) {
- return ERR_ARG;
- }
- switch (op_id) {
- case IP_ADDRESS_LEASE_TIME:
- if (opt_len == sizeof(dhcps_time_t)) {
- dhcps->dhcps_lease_time = *(dhcps_time_t *)opt_info;
- }
- break;
- case REQUESTED_IP_ADDRESS:
- if (opt_len == sizeof(dhcps_lease_t)) {
- dhcps->dhcps_poll = *(dhcps_lease_t *)opt_info;
- }
- break;
- case ROUTER_SOLICITATION_ADDRESS:
- if (opt_len == sizeof(dhcps_offer_t)) {
- dhcps->dhcps_offer = *(dhcps_offer_t *)opt_info;
- }
- break;
- case DOMAIN_NAME_SERVER:
- if (opt_len == sizeof(dhcps_offer_t)) {
- dhcps->dhcps_dns = *(dhcps_offer_t *)opt_info;
- }
- break;
- case SUBNET_MASK:
- if (opt_len == sizeof(dhcps->dhcps_mask)) {
- dhcps->dhcps_mask = *(ip4_addr_t *)opt_info;
- }
- default:
- break;
- }
- return ERR_OK;
- }
- /******************************************************************************
- * FunctionName : node_insert_to_list
- * Description : insert the node to the list
- * Parameters : phead -- the head node of the list
- * pinsert -- the insert node of the list
- * Returns : none
- *******************************************************************************/
- static void node_insert_to_list(list_node **phead, list_node *pinsert)
- {
- list_node *plist = NULL;
- struct dhcps_pool *pdhcps_pool = NULL;
- struct dhcps_pool *pdhcps_node = NULL;
- if (*phead == NULL) {
- *phead = pinsert;
- } else {
- plist = *phead;
- pdhcps_node = pinsert->pnode;
- pdhcps_pool = plist->pnode;
- if (pdhcps_node->ip.addr < pdhcps_pool->ip.addr) {
- pinsert->pnext = plist;
- *phead = pinsert;
- } else {
- while (plist->pnext != NULL) {
- pdhcps_pool = plist->pnext->pnode;
- if (pdhcps_node->ip.addr < pdhcps_pool->ip.addr) {
- pinsert->pnext = plist->pnext;
- plist->pnext = pinsert;
- break;
- }
- plist = plist->pnext;
- }
- if (plist->pnext == NULL) {
- plist->pnext = pinsert;
- }
- }
- }
- // pinsert->pnext = NULL;
- }
- /******************************************************************************
- * FunctionName : node_delete_from_list
- * Description : remove the node from list
- * Parameters : phead -- the head node of the list
- * pdelete -- the remove node of the list
- * Returns : none
- *******************************************************************************/
- void node_remove_from_list(list_node **phead, list_node *pdelete)
- {
- list_node *plist = NULL;
- plist = *phead;
- if (plist == NULL) {
- *phead = NULL;
- } else {
- if (plist == pdelete) {
- // Note: Ignoring the "use after free" warnings, as it could only happen
- // if the linked list contains loops
- *phead = plist->pnext; // NOLINT(clang-analyzer-unix.Malloc)
- pdelete->pnext = NULL;
- } else {
- while (plist != NULL) {
- if (plist->pnext == pdelete) { // NOLINT(clang-analyzer-unix.Malloc)
- plist->pnext = pdelete->pnext;
- pdelete->pnext = NULL;
- }
- plist = plist->pnext;
- }
- }
- }
- }
- /******************************************************************************
- * FunctionName : add_msg_type
- * Description : add TYPE option of DHCP message
- * Parameters : optptr -- the addr of DHCP message option
- * Returns : the addr of DHCP message option
- *******************************************************************************/
- static u8_t *add_msg_type(u8_t *optptr, u8_t type)
- {
- *optptr++ = DHCP_OPTION_MSG_TYPE;
- *optptr++ = 1;
- *optptr++ = type;
- return optptr;
- }
- /******************************************************************************
- * FunctionName : add_offer_options
- * Description : add OFFER option of DHCP message
- * Parameters : optptr -- the addr of DHCP message option
- * Returns : the addr of DHCP message option
- *******************************************************************************/
- static u8_t *add_offer_options(dhcps_t *dhcps, u8_t *optptr)
- {
- ip4_addr_t ipadd;
- ipadd.addr = *((u32_t *) &dhcps->server_address);
- *optptr++ = DHCP_OPTION_SUBNET_MASK;
- *optptr++ = 4;
- *optptr++ = ip4_addr1(&dhcps->dhcps_mask);
- *optptr++ = ip4_addr2(&dhcps->dhcps_mask);
- *optptr++ = ip4_addr3(&dhcps->dhcps_mask);
- *optptr++ = ip4_addr4(&dhcps->dhcps_mask);
- *optptr++ = DHCP_OPTION_LEASE_TIME;
- *optptr++ = 4;
- *optptr++ = ((dhcps->dhcps_lease_time * DHCPS_LEASE_UNIT) >> 24) & 0xFF;
- *optptr++ = ((dhcps->dhcps_lease_time * DHCPS_LEASE_UNIT) >> 16) & 0xFF;
- *optptr++ = ((dhcps->dhcps_lease_time * DHCPS_LEASE_UNIT) >> 8) & 0xFF;
- *optptr++ = ((dhcps->dhcps_lease_time * DHCPS_LEASE_UNIT) >> 0) & 0xFF;
- *optptr++ = DHCP_OPTION_SERVER_ID;
- *optptr++ = 4;
- *optptr++ = ip4_addr1(&ipadd);
- *optptr++ = ip4_addr2(&ipadd);
- *optptr++ = ip4_addr3(&ipadd);
- *optptr++ = ip4_addr4(&ipadd);
- if (dhcps_router_enabled(dhcps->dhcps_offer)) {
- ip_info_t if_ip = { 0 };
- get_ip_info(dhcps->dhcps_netif, &if_ip);
- ip4_addr_t* gw_ip = (ip4_addr_t*)&if_ip.gw;
- if (!ip4_addr_isany_val(*gw_ip)) {
- *optptr++ = DHCP_OPTION_ROUTER;
- *optptr++ = 4;
- *optptr++ = ip4_addr1(gw_ip);
- *optptr++ = ip4_addr2(gw_ip);
- *optptr++ = ip4_addr3(gw_ip);
- *optptr++ = ip4_addr4(gw_ip);
- }
- }
- *optptr++ = DHCP_OPTION_DNS_SERVER;
- *optptr++ = 4;
- if (dhcps_dns_enabled(dhcps->dhcps_dns)) {
- *optptr++ = ip4_addr1(&dhcps->dns_server);
- *optptr++ = ip4_addr2(&dhcps->dns_server);
- *optptr++ = ip4_addr3(&dhcps->dns_server);
- *optptr++ = ip4_addr4(&dhcps->dns_server);
- }else {
- *optptr++ = ip4_addr1(&ipadd);
- *optptr++ = ip4_addr2(&ipadd);
- *optptr++ = ip4_addr3(&ipadd);
- *optptr++ = ip4_addr4(&ipadd);
- }
- ip4_addr_t broadcast_addr = { .addr = (ipadd.addr & dhcps->dhcps_mask.addr) | ~dhcps->dhcps_mask.addr };
- *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS;
- *optptr++ = 4;
- *optptr++ = ip4_addr1(&broadcast_addr);
- *optptr++ = ip4_addr2(&broadcast_addr);
- *optptr++ = ip4_addr3(&broadcast_addr);
- *optptr++ = ip4_addr4(&broadcast_addr);
- *optptr++ = DHCP_OPTION_INTERFACE_MTU;
- *optptr++ = 2;
- *optptr++ = 0x05;
- *optptr++ = 0xdc;
- *optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY;
- *optptr++ = 1;
- *optptr++ = 0x00;
- *optptr++ = 43;
- *optptr++ = 6;
- *optptr++ = 0x01;
- *optptr++ = 4;
- *optptr++ = 0x00;
- *optptr++ = 0x00;
- *optptr++ = 0x00;
- *optptr++ = 0x02;
- return optptr;
- }
- /******************************************************************************
- * FunctionName : add_end
- * Description : add end option of DHCP message
- * Parameters : optptr -- the addr of DHCP message option
- * Returns : the addr of DHCP message option
- *******************************************************************************/
- static u8_t *add_end(u8_t *optptr)
- {
- *optptr++ = DHCP_OPTION_END;
- return optptr;
- }
- /******************************************************************************
- * FunctionName : create_msg
- * Description : create response message
- * Parameters : m -- DHCP message info
- * Returns : none
- *******************************************************************************/
- static void create_msg(dhcps_t *dhcps, struct dhcps_msg *m)
- {
- ip4_addr_t client;
- client.addr = *((uint32_t *) &dhcps->client_address);
- m->op = DHCP_REPLY;
- m->htype = DHCP_HTYPE_ETHERNET;
- m->hlen = 6;
- m->hops = 0;
- // os_memcpy((char *) xid, (char *) m->xid, sizeof(m->xid));
- m->secs = 0;
- m->flags = htons(BOOTP_BROADCAST);
- memcpy((char *) m->yiaddr, (char *) &client.addr, sizeof(m->yiaddr));
- memset((char *) m->ciaddr, 0, sizeof(m->ciaddr));
- memset((char *) m->siaddr, 0, sizeof(m->siaddr));
- memset((char *) m->giaddr, 0, sizeof(m->giaddr));
- memset((char *) m->sname, 0, sizeof(m->sname));
- memset((char *) m->file, 0, sizeof(m->file));
- memset((char *) m->options, 0, sizeof(m->options));
- u32_t magic_cookie_temp = magic_cookie;
- memcpy((char *) m->options, &magic_cookie_temp, sizeof(magic_cookie_temp));
- }
- struct pbuf * dhcps_pbuf_alloc(u16_t len)
- {
- u16_t mlen = sizeof(struct dhcps_msg);
- if (len > mlen) {
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: len=%d mlen=%d", len, mlen);
- #endif
- mlen = len;
- }
- return pbuf_alloc(PBUF_TRANSPORT, mlen, PBUF_RAM);
- }
- /******************************************************************************
- * FunctionName : send_offer
- * Description : DHCP message OFFER Response
- * Parameters : m -- DHCP message info
- * Returns : none
- *******************************************************************************/
- static void send_offer(dhcps_t *dhcps, struct dhcps_msg *m, u16_t len)
- {
- u8_t *end;
- struct pbuf *p, *q;
- u8_t *data;
- u16_t cnt = 0;
- u16_t i;
- #if DHCPS_DEBUG
- err_t SendOffer_err_t;
- #endif
- create_msg(dhcps, m);
- end = add_msg_type(&m->options[4], DHCPOFFER);
- end = add_offer_options(dhcps, end);
- LWIP_HOOK_DHCPS_POST_APPEND_OPTS(dhcps->netif, dhcps, DHCPOFFER, &end)
- end = add_end(end);
- p = dhcps_pbuf_alloc(len);
- #if DHCPS_DEBUG
- DHCPS_LOG("udhcp: send_offer>>p->ref = %d\n", p->ref);
- #endif
- if (p != NULL) {
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: send_offer>>pbuf_alloc succeed\n");
- DHCPS_LOG("dhcps: send_offer>>p->tot_len = %d\n", p->tot_len);
- DHCPS_LOG("dhcps: send_offer>>p->len = %d\n", p->len);
- #endif
- q = p;
- while (q != NULL) {
- data = (u8_t *)q->payload;
- for (i = 0; i < q->len; i++) {
- data[i] = ((u8_t *) m)[cnt++];
- #if DHCPS_DEBUG
- DHCPS_LOG("%02x ", data[i]);
- if ((i + 1) % 16 == 0) {
- DHCPS_LOG("\n");
- }
- #endif
- }
- q = q->next;
- }
- } else {
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: send_offer>>pbuf_alloc failed\n");
- #endif
- return;
- }
- ip_addr_t ip_temp = IPADDR4_INIT(0x0);
- ip4_addr_set(ip_2_ip4(&ip_temp), &dhcps->broadcast_dhcps);
- #if DHCPS_DEBUG
- SendOffer_err_t = udp_sendto(pcb_dhcps, p, &ip_temp, DHCPS_CLIENT_PORT);
- DHCPS_LOG("dhcps: send_offer>>udp_sendto result %x\n", SendOffer_err_t);
- #else
- udp_sendto(dhcps->dhcps_pcb, p, &ip_temp, DHCPS_CLIENT_PORT);
- #endif
- if (p->ref != 0) {
- #if DHCPS_DEBUG
- DHCPS_LOG("udhcp: send_offer>>free pbuf\n");
- #endif
- pbuf_free(p);
- }
- }
- /******************************************************************************
- * FunctionName : send_nak
- * Description : DHCP message NACK Response
- * Parameters : m -- DHCP message info
- * Returns : none
- *******************************************************************************/
- static void send_nak(dhcps_t *dhcps, struct dhcps_msg *m, u16_t len)
- {
- u8_t *end;
- struct pbuf *p, *q;
- u8_t *data;
- u16_t cnt = 0;
- u16_t i;
- #if DHCPS_DEBUG
- err_t SendNak_err_t;
- #endif
- create_msg(dhcps, m);
- end = add_msg_type(&m->options[4], DHCPNAK);
- LWIP_HOOK_DHCPS_POST_APPEND_OPTS(dhcps->netif, dhcps, DHCPNAK, &end)
- end = add_end(end);
- p = dhcps_pbuf_alloc(len);
- #if DHCPS_DEBUG
- DHCPS_LOG("udhcp: send_nak>>p->ref = %d\n", p->ref);
- #endif
- if (p != NULL) {
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: send_nak>>pbuf_alloc succeed\n");
- DHCPS_LOG("dhcps: send_nak>>p->tot_len = %d\n", p->tot_len);
- DHCPS_LOG("dhcps: send_nak>>p->len = %d\n", p->len);
- #endif
- q = p;
- while (q != NULL) {
- data = (u8_t *)q->payload;
- for (i = 0; i < q->len; i++) {
- data[i] = ((u8_t *) m)[cnt++];
- #if DHCPS_DEBUG
- DHCPS_LOG("%02x ", data[i]);
- if ((i + 1) % 16 == 0) {
- DHCPS_LOG("\n");
- }
- #endif
- }
- q = q->next;
- }
- } else {
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: send_nak>>pbuf_alloc failed\n");
- #endif
- return;
- }
- ip_addr_t ip_temp = IPADDR4_INIT(0x0);
- ip4_addr_set(ip_2_ip4(&ip_temp), &dhcps->broadcast_dhcps);
- #if DHCPS_DEBUG
- SendNak_err_t = udp_sendto(pcb_dhcps, p, &ip_temp, DHCPS_CLIENT_PORT);
- DHCPS_LOG("dhcps: send_nak>>udp_sendto result %x\n", SendNak_err_t);
- #else
- udp_sendto(dhcps->dhcps_pcb, p, &ip_temp, DHCPS_CLIENT_PORT);
- #endif
- if (p->ref != 0) {
- #if DHCPS_DEBUG
- DHCPS_LOG("udhcp: send_nak>>free pbuf\n");
- #endif
- pbuf_free(p);
- }
- }
- /******************************************************************************
- * FunctionName : send_ack
- * Description : DHCP message ACK Response
- * Parameters : m -- DHCP message info
- * Returns : none
- *******************************************************************************/
- static void send_ack(dhcps_t *dhcps, struct dhcps_msg *m, u16_t len)
- {
- u8_t *end;
- struct pbuf *p, *q;
- u8_t *data;
- u16_t cnt = 0;
- u16_t i;
- err_t SendAck_err_t;
- create_msg(dhcps, m);
- end = add_msg_type(&m->options[4], DHCPACK);
- end = add_offer_options(dhcps, end);
- LWIP_HOOK_DHCPS_POST_APPEND_OPTS(dhcps->netif, dhcps, DHCPACK, &end)
- end = add_end(end);
- p = dhcps_pbuf_alloc(len);
- #if DHCPS_DEBUG
- DHCPS_LOG("udhcp: send_ack>>p->ref = %d\n", p->ref);
- #endif
- if (p != NULL) {
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: send_ack>>pbuf_alloc succeed\n");
- DHCPS_LOG("dhcps: send_ack>>p->tot_len = %d\n", p->tot_len);
- DHCPS_LOG("dhcps: send_ack>>p->len = %d\n", p->len);
- #endif
- q = p;
- while (q != NULL) {
- data = (u8_t *)q->payload;
- for (i = 0; i < q->len; i++) {
- data[i] = ((u8_t *) m)[cnt++];
- #if DHCPS_DEBUG
- DHCPS_LOG("%02x ", data[i]);
- if ((i + 1) % 16 == 0) {
- DHCPS_LOG("\n");
- }
- #endif
- }
- q = q->next;
- }
- } else {
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: send_ack>>pbuf_alloc failed\n");
- #endif
- return;
- }
- ip_addr_t ip_temp = IPADDR4_INIT(0x0);
- ip4_addr_set(ip_2_ip4(&ip_temp), &dhcps->broadcast_dhcps);
- SendAck_err_t = udp_sendto(dhcps->dhcps_pcb, p, &ip_temp, DHCPS_CLIENT_PORT);
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: send_ack>>udp_sendto result %x\n", SendAck_err_t);
- #endif
- if (SendAck_err_t == ERR_OK) {
- dhcps->dhcps_cb(dhcps->dhcps_cb_arg, m->yiaddr, m->chaddr);
- }
- if (p->ref != 0) {
- #if DHCPS_DEBUG
- DHCPS_LOG("udhcp: send_ack>>free pbuf\n");
- #endif
- pbuf_free(p);
- }
- }
- /******************************************************************************
- * FunctionName : parse_options
- * Description : parse DHCP message options
- * Parameters : optptr -- DHCP message option info
- * len -- DHCP message option length
- * Returns : none
- *******************************************************************************/
- static u8_t parse_options(dhcps_t *dhcps, u8_t *optptr, s16_t len)
- {
- ip4_addr_t client;
- bool is_dhcp_parse_end = false;
- struct dhcps_state s;
- client.addr = *((uint32_t *) &dhcps->client_address);
- u8_t *end = optptr + len;
- u16_t type = 0;
- s.state = DHCPS_STATE_IDLE;
- while (optptr < end) {
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: (s16_t)*optptr = %d\n", (s16_t)*optptr);
- #endif
- switch ((s16_t) *optptr) {
- case DHCP_OPTION_MSG_TYPE: //53
- type = *(optptr + 2);
- break;
- case DHCP_OPTION_REQ_IPADDR://50
- if (memcmp((char *) &client.addr, (char *) optptr + 2, 4) == 0) {
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n");
- #endif
- s.state = DHCPS_STATE_ACK;
- } else {
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n");
- #endif
- s.state = DHCPS_STATE_NAK;
- }
- break;
- case DHCP_OPTION_END: {
- is_dhcp_parse_end = true;
- }
- break;
- }
- if (is_dhcp_parse_end) {
- break;
- }
- optptr += optptr[1] + 2;
- }
- switch (type) {
- case DHCPDISCOVER://1
- s.state = DHCPS_STATE_OFFER;
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: DHCPD_STATE_OFFER\n");
- #endif
- break;
- case DHCPREQUEST://3
- if (!(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK)) {
- if (dhcps->renew == true) {
- s.state = DHCPS_STATE_ACK;
- } else {
- s.state = DHCPS_STATE_NAK;
- }
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: DHCPD_STATE_NAK\n");
- #endif
- }
- break;
- case DHCPDECLINE://4
- s.state = DHCPS_STATE_IDLE;
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: DHCPD_STATE_IDLE\n");
- #endif
- break;
- case DHCPRELEASE://7
- s.state = DHCPS_STATE_RELEASE;
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: DHCPD_STATE_IDLE\n");
- #endif
- break;
- }
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: return s.state = %d\n", s.state);
- #endif
- return s.state;
- }
- /******************************************************************************
- * FunctionName : parse_msg
- * Description : parse DHCP message from netif
- * Parameters : m -- DHCP message info
- * len -- DHCP message length
- * Returns : DHCP message type
- *******************************************************************************/
- static s16_t parse_msg(dhcps_t *dhcps, struct dhcps_msg *m, u16_t len)
- {
- u32_t lease_timer = (dhcps->dhcps_lease_time * DHCPS_LEASE_UNIT)/DHCPS_COARSE_TIMER_SECS;
- if (memcmp((char *)m->options, &magic_cookie, sizeof(magic_cookie)) == 0) {
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: len = %d\n", len);
- #endif
- ip4_addr_t addr_tmp;
- struct dhcps_pool *pdhcps_pool = NULL;
- list_node *pnode = NULL;
- list_node *pback_node = NULL;
- ip4_addr_t first_address;
- bool flag = false;
- first_address.addr = dhcps->dhcps_poll.start_ip.addr;
- dhcps->client_address.addr = dhcps->client_address_plus.addr;
- dhcps->renew = false;
- if (dhcps->plist != NULL) {
- for (pback_node = dhcps->plist; pback_node != NULL; pback_node = pback_node->pnext) {
- pdhcps_pool = pback_node->pnode;
- if (memcmp(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)) == 0) {
- if (memcmp(&pdhcps_pool->ip.addr, m->ciaddr, sizeof(pdhcps_pool->ip.addr)) == 0) {
- dhcps->renew = true;
- }
- dhcps->client_address.addr = pdhcps_pool->ip.addr;
- pdhcps_pool->lease_timer = lease_timer;
- pnode = pback_node;
- goto POOL_CHECK;
- } else if (pdhcps_pool->ip.addr == dhcps->client_address_plus.addr) {
- addr_tmp.addr = htonl(dhcps->client_address_plus.addr);
- addr_tmp.addr++;
- dhcps->client_address_plus.addr = htonl(addr_tmp.addr);
- dhcps->client_address.addr = dhcps->client_address_plus.addr;
- }
- if (flag == false) { // search the fisrt unused ip
- if (first_address.addr < pdhcps_pool->ip.addr) {
- flag = true;
- } else {
- addr_tmp.addr = htonl(first_address.addr);
- addr_tmp.addr++;
- first_address.addr = htonl(addr_tmp.addr);
- }
- }
- }
- } else {
- dhcps->client_address.addr = dhcps->dhcps_poll.start_ip.addr;
- }
- if (dhcps->client_address_plus.addr > dhcps->dhcps_poll.end_ip.addr) {
- dhcps->client_address.addr = first_address.addr;
- }
- if (dhcps->client_address.addr > dhcps->dhcps_poll.end_ip.addr) {
- dhcps->client_address_plus.addr = dhcps->dhcps_poll.start_ip.addr;
- pdhcps_pool = NULL;
- pnode = NULL;
- } else {
- pdhcps_pool = (struct dhcps_pool *)mem_calloc(1, sizeof(struct dhcps_pool));
- pdhcps_pool->ip.addr = dhcps->client_address.addr;
- memcpy(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac));
- pdhcps_pool->lease_timer = lease_timer;
- pnode = (list_node *)mem_calloc(1, sizeof(list_node));
- pnode->pnode = pdhcps_pool;
- pnode->pnext = NULL;
- node_insert_to_list(&dhcps->plist, pnode);
- if (dhcps->client_address.addr == dhcps->dhcps_poll.end_ip.addr) {
- dhcps->client_address_plus.addr = dhcps->dhcps_poll.start_ip.addr;
- } else {
- addr_tmp.addr = htonl(dhcps->client_address.addr);
- addr_tmp.addr++;
- dhcps->client_address_plus.addr = htonl(addr_tmp.addr);
- }
- }
- POOL_CHECK:
- if ((dhcps->client_address.addr > dhcps->dhcps_poll.end_ip.addr) || (ip4_addr_isany(&dhcps->client_address))) {
- if (pnode != NULL) {
- node_remove_from_list(&dhcps->plist, pnode);
- free(pnode);
- pnode = NULL;
- }
- if (pdhcps_pool != NULL) {
- free(pdhcps_pool);
- pdhcps_pool = NULL;
- }
- return 4;
- }
- s16_t ret = parse_options(dhcps, &m->options[4], len);;
- if (ret == DHCPS_STATE_RELEASE || ret == DHCPS_STATE_NAK) {
- if (pnode != NULL) {
- node_remove_from_list(&dhcps->plist, pnode);
- free(pnode);
- pnode = NULL;
- }
- if (pdhcps_pool != NULL) {
- free(pdhcps_pool);
- pdhcps_pool = NULL;
- }
- memset(&dhcps->client_address, 0x0, sizeof(dhcps->client_address));
- }
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: xid changed\n");
- DHCPS_LOG("dhcps: client_address.addr = %x\n", client_address.addr);
- #endif
- return ret;
- }
- return 0;
- }
- /******************************************************************************
- * FunctionName : handle_dhcp
- * Description : If an incoming DHCP message is in response to us, then trigger the state machine
- * Parameters : arg -- arg user supplied argument (udp_pcb.recv_arg)
- * pcb -- the udp_pcb which received data
- * p -- the packet buffer that was received
- * addr -- the remote IP address from which the packet was received
- * port -- the remote port from which the packet was received
- * Returns : none
- *******************************************************************************/
- static void handle_dhcp(void *arg,
- struct udp_pcb *pcb,
- struct pbuf *p,
- const ip_addr_t *addr,
- u16_t port)
- {
- struct dhcps_t *dhcps = arg;
- struct dhcps_msg *pmsg_dhcps = NULL;
- s16_t tlen, malloc_len;
- u16_t i;
- u16_t dhcps_msg_cnt = 0;
- u8_t *p_dhcps_msg = NULL;
- u8_t *data;
- s16_t state;
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: handle_dhcp-> receive a packet\n");
- #endif
- if (p == NULL) {
- return;
- }
- malloc_len = sizeof(struct dhcps_msg);
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: handle_dhcp malloc_len=%d rx_len=%d", malloc_len, p->tot_len);
- #endif
- if (malloc_len < p->tot_len) {
- malloc_len = p->tot_len;
- }
- pmsg_dhcps = (struct dhcps_msg *)mem_calloc(1, malloc_len);
- if (NULL == pmsg_dhcps) {
- pbuf_free(p);
- return;
- }
- p_dhcps_msg = (u8_t *)pmsg_dhcps;
- tlen = p->tot_len;
- data = p->payload;
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen);
- DHCPS_LOG("dhcps: handle_dhcp-> p->len = %d\n", p->len);
- #endif
- for (i = 0; i < p->len; i++) {
- p_dhcps_msg[dhcps_msg_cnt++] = data[i];
- #if DHCPS_DEBUG
- DHCPS_LOG("%02x ", data[i]);
- if ((i + 1) % 16 == 0) {
- DHCPS_LOG("\n");
- }
- #endif
- }
- if (p->next != NULL) {
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: handle_dhcp-> p->next != NULL\n");
- DHCPS_LOG("dhcps: handle_dhcp-> p->next->tot_len = %d\n", p->next->tot_len);
- DHCPS_LOG("dhcps: handle_dhcp-> p->next->len = %d\n", p->next->len);
- #endif
- data = p->next->payload;
- for (i = 0; i < p->next->len; i++) {
- p_dhcps_msg[dhcps_msg_cnt++] = data[i];
- #if DHCPS_DEBUG
- DHCPS_LOG("%02x ", data[i]);
- if ((i + 1) % 16 == 0) {
- DHCPS_LOG("\n");
- }
- #endif
- }
- }
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: handle_dhcp-> parse_msg(p)\n");
- #endif
- state = parse_msg(dhcps, pmsg_dhcps, tlen - 240);
- #ifdef LWIP_HOOK_DHCPS_POST_STATE
- state = LWIP_HOOK_DHCPS_POST_STATE(pmsg_dhcps, malloc_len, state);
- #endif /* LWIP_HOOK_DHCPS_POST_STATE */
- switch (state) {
- case DHCPS_STATE_OFFER://1
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n");
- #endif
- send_offer(dhcps, pmsg_dhcps, malloc_len);
- break;
- case DHCPS_STATE_ACK://3
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n");
- #endif
- send_ack(dhcps, pmsg_dhcps, malloc_len);
- break;
- case DHCPS_STATE_NAK://4
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n");
- #endif
- send_nak(dhcps, pmsg_dhcps, malloc_len);
- break;
- default :
- break;
- }
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps: handle_dhcp-> pbuf_free(p)\n");
- #endif
- pbuf_free(p);
- free(pmsg_dhcps);
- pmsg_dhcps = NULL;
- }
- /******************************************************************************
- * FunctionName : dhcps_poll_set
- * Description : set ip poll from start to end for station
- * Parameters : ip -- The current ip addr
- * Returns : none
- *******************************************************************************/
- static void dhcps_poll_set(dhcps_t *dhcps, u32_t ip)
- {
- u32_t softap_ip = 0, local_ip = 0;
- u32_t start_ip = 0;
- u32_t end_ip = 0;
- dhcps_lease_t *dhcps_poll = &dhcps->dhcps_poll;
- if (dhcps_poll->enable == true) {
- softap_ip = htonl(ip);
- start_ip = htonl(dhcps_poll->start_ip.addr);
- end_ip = htonl(dhcps_poll->end_ip.addr);
- /*config ip information can't contain local ip*/
- if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) {
- dhcps_poll->enable = false;
- } else {
- /*config ip information must be in the same segment as the local ip*/
- softap_ip >>= 8;
- if (((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip))
- || (end_ip - start_ip > DHCPS_MAX_LEASE)) {
- dhcps_poll->enable = false;
- }
- }
- }
- if (dhcps_poll->enable == false) {
- local_ip = softap_ip = htonl(ip);
- softap_ip &= 0xFFFFFF00;
- local_ip &= 0xFF;
- if (local_ip >= 0x80) {
- local_ip -= DHCPS_MAX_LEASE;
- } else {
- local_ip ++;
- }
- bzero(dhcps_poll, sizeof(*dhcps_poll));
- dhcps_poll->start_ip.addr = softap_ip | local_ip;
- dhcps_poll->end_ip.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE - 1);
- dhcps_poll->start_ip.addr = htonl(dhcps_poll->start_ip.addr);
- dhcps_poll->end_ip.addr = htonl(dhcps_poll->end_ip.addr);
- }
- }
- /******************************************************************************
- * FunctionName : dhcps_set_new_lease_cb
- * Description : set callback for dhcp server when it assign an IP
- * to the connected dhcp client
- * Parameters : cb -- callback for dhcp server
- * Returns : ERR_OK on success
- *******************************************************************************/
- err_t dhcps_set_new_lease_cb(dhcps_t *dhcps, dhcps_cb_t cb, void* cb_arg)
- {
- if (dhcps == NULL) {
- return ERR_ARG;
- }
- dhcps->dhcps_cb = cb;
- dhcps->dhcps_cb_arg = cb_arg;
- return ERR_OK;
- }
- /******************************************************************************
- * FunctionName : dhcps_start
- * Description : start dhcp server function
- * Parameters : netif -- The current netif addr
- * : info -- The current ip info
- * Returns : none
- *******************************************************************************/
- err_t dhcps_start(dhcps_t *dhcps, struct netif *netif, ip4_addr_t ip)
- {
- if (dhcps == NULL || netif == NULL) {
- return ERR_ARG;
- }
- dhcps->dhcps_netif = netif;
- if (dhcps->dhcps_pcb != NULL) {
- udp_remove(dhcps->dhcps_pcb);
- }
- dhcps->dhcps_pcb = udp_new();
- if (dhcps->dhcps_pcb == NULL || ip4_addr_isany_val(ip)) {
- printf("dhcps_start(): could not obtain pcb\n");
- return ERR_ARG;
- }
- IP4_ADDR(&dhcps->broadcast_dhcps, 255, 255, 255, 255);
- dhcps->server_address.addr = ip.addr;
- dhcps_poll_set(dhcps, dhcps->server_address.addr);
- dhcps->client_address_plus.addr = dhcps->dhcps_poll.start_ip.addr;
- udp_bind(dhcps->dhcps_pcb, &netif->ip_addr, DHCPS_SERVER_PORT);
- udp_recv(dhcps->dhcps_pcb, handle_dhcp, dhcps);
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n");
- #endif
- dhcps->state = DHCPS_HANDLE_STARTED;
- sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcps_tmr, dhcps);
- return ERR_OK;
- }
- /******************************************************************************
- * FunctionName : dhcps_stop
- * Description : stop dhcp server function
- * Parameters : netif -- The current netif addr
- * Returns : none
- *******************************************************************************/
- err_t dhcps_stop(dhcps_t *dhcps, struct netif *netif)
- {
- if (dhcps == NULL || netif == NULL || dhcps->dhcps_netif != netif) {
- #if DHCPS_DEBUG
- DHCPS_LOG("dhcps_stop: netif is NULL or invalid\n");
- #endif
- return ERR_ARG;
- }
- if (dhcps->dhcps_pcb != NULL) {
- udp_disconnect(dhcps->dhcps_pcb);
- udp_remove(dhcps->dhcps_pcb);
- dhcps->dhcps_pcb = NULL;
- }
- list_node *pnode = NULL;
- list_node *pback_node = NULL;
- pnode = dhcps->plist;
- while (pnode != NULL) {
- pback_node = pnode;
- pnode = pback_node->pnext;
- node_remove_from_list(&dhcps->plist, pback_node);
- free(pback_node->pnode);
- pback_node->pnode = NULL;
- free(pback_node);
- pback_node = NULL;
- }
- sys_untimeout(dhcps_tmr, dhcps);
- dhcps->state = DHCPS_HANDLE_STOPPED;
- return ERR_OK;
- }
- /******************************************************************************
- * FunctionName : kill_oldest_dhcps_pool
- * Description : remove the oldest node from list
- * Parameters : none
- * Returns : none
- *******************************************************************************/
- static void kill_oldest_dhcps_pool(dhcps_t *dhcps)
- {
- list_node *pre = NULL, *p = NULL;
- list_node *minpre = NULL, *minp = NULL;
- struct dhcps_pool *pdhcps_pool = NULL, *pmin_pool = NULL;
- pre = dhcps->plist;
- assert(pre != NULL && pre->pnext != NULL); // Expect the list to have at least 2 nodes
- p = pre->pnext;
- minpre = pre;
- minp = p;
- while (p != NULL) {
- pdhcps_pool = p->pnode;
- pmin_pool = minp->pnode;
- if (pdhcps_pool->lease_timer < pmin_pool->lease_timer) {
- minp = p;
- minpre = pre;
- }
- pre = p;
- p = p->pnext;
- }
- minpre->pnext = minp->pnext;
- free(minp->pnode);
- minp->pnode = NULL;
- free(minp);
- minp = NULL;
- }
- /******************************************************************************
- * FunctionName : dhcps_coarse_tmr
- * Description : the lease time count
- * Parameters : none
- * Returns : none
- *******************************************************************************/
- static void dhcps_tmr(void *arg)
- {
- dhcps_t *dhcps = arg;
- dhcps_handle_state state = dhcps->state;
- if (state == DHCPS_HANDLE_DELETE_PENDING) {
- free(dhcps);
- return;
- }
- if (state != DHCPS_HANDLE_STARTED) {
- return;
- }
- sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcps_tmr, dhcps);
- u8_t num_dhcps_pool = 0;
- list_node *pback_node = NULL;
- list_node *pnode = NULL;
- struct dhcps_pool *pdhcps_pool = NULL;
- pnode = dhcps->plist;
- while (pnode != NULL) {
- pdhcps_pool = pnode->pnode;
- pdhcps_pool->lease_timer --;
- if (pdhcps_pool->lease_timer == 0) {
- pback_node = pnode;
- pnode = pback_node->pnext;
- node_remove_from_list(&dhcps->plist, pback_node);
- free(pback_node->pnode);
- pback_node->pnode = NULL;
- free(pback_node);
- pback_node = NULL;
- } else {
- pnode = pnode ->pnext;
- num_dhcps_pool ++;
- }
- }
- if (num_dhcps_pool > MAX_STATION_NUM) {
- kill_oldest_dhcps_pool(dhcps);
- }
- }
- /******************************************************************************
- * FunctionName : dhcp_search_ip_on_mac
- * Description : Search ip address based on mac address
- * Parameters : mac -- The MAC addr
- * ip -- The IP info
- * Returns : true or false
- *******************************************************************************/
- bool dhcp_search_ip_on_mac(dhcps_t *dhcps, u8_t *mac, ip4_addr_t *ip)
- {
- struct dhcps_pool *pdhcps_pool = NULL;
- list_node *pback_node = NULL;
- bool ret = false;
- if (dhcps == NULL) {
- return false;
- }
- for (pback_node = dhcps->plist; pback_node != NULL; pback_node = pback_node->pnext) {
- pdhcps_pool = pback_node->pnode;
- if (memcmp(pdhcps_pool->mac, mac, sizeof(pdhcps_pool->mac)) == 0) {
- memcpy(&ip->addr, &pdhcps_pool->ip.addr, sizeof(pdhcps_pool->ip.addr));
- ret = true;
- break;
- }
- }
- return ret;
- }
- /******************************************************************************
- * FunctionName : dhcps_dns_setserver
- * Description : set DNS server address for dhcpserver
- * Parameters : dnsserver -- The DNS server address
- * Returns : ERR_ARG if invalid handle, ERR_OK on success
- *******************************************************************************/
- err_t dhcps_dns_setserver(dhcps_t *dhcps, const ip_addr_t *dnsserver)
- {
- if (dhcps == NULL) {
- return ERR_ARG;
- }
- if (dnsserver != NULL) {
- dhcps->dns_server = *(ip_2_ip4(dnsserver));
- } else {
- dhcps->dns_server = *(ip_2_ip4(IP_ADDR_ANY));
- }
- return ERR_OK;
- }
- /******************************************************************************
- * FunctionName : dhcps_dns_getserver
- * Description : get DNS server address for dhcpserver
- * Parameters : none
- * Returns : ip4_addr_t
- *******************************************************************************/
- err_t dhcps_dns_getserver(dhcps_t *dhcps, ip4_addr_t *dnsserver)
- {
- if (dhcps) {
- *dnsserver = dhcps->dns_server;
- return ERR_OK;
- }
- return ERR_ARG;
- }
- #endif // ESP_DHCPS
|