dhcpserver.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205
  1. #include "lwip/inet.h"
  2. #include "lwip/err.h"
  3. #include "lwip/pbuf.h"
  4. #include "lwip/udp.h"
  5. #include "lwip/mem.h"
  6. //#include "crypto/common.h"
  7. #include "osapi.h"
  8. #include "lwip/app/dhcpserver.h"
  9. #ifndef LWIP_OPEN_SRC
  10. #include "net80211/ieee80211_var.h"
  11. #endif
  12. #include "user_interface.h"
  13. #ifdef MEMLEAK_DEBUG
  14. static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
  15. #endif
  16. ////////////////////////////////////////////////////////////////////////////////////
  17. //static const uint8_t xid[4] = {0xad, 0xde, 0x12, 0x23};
  18. //static u8_t old_xid[4] = {0};
  19. static const uint32 magic_cookie ICACHE_RODATA_ATTR = 0x63538263;
  20. static struct udp_pcb *pcb_dhcps = NULL;
  21. static struct ip_addr broadcast_dhcps;
  22. static struct ip_addr server_address;
  23. static struct ip_addr client_address;//added
  24. static struct dhcps_lease dhcps_lease;
  25. //static bool dhcps_lease_flag = true;
  26. static list_node *plist = NULL;
  27. static uint8 offer = 0xFF;
  28. static bool renew = false;
  29. #define DHCPS_LEASE_TIME_DEF (120)
  30. uint32 dhcps_lease_time = DHCPS_LEASE_TIME_DEF; //minute
  31. void wifi_softap_dhcps_client_leave(u8 *bssid, struct ip_addr *ip,bool force);
  32. uint32 wifi_softap_dhcps_client_update(u8 *bssid, struct ip_addr *ip);
  33. /******************************************************************************
  34. * FunctionName : node_insert_to_list
  35. * Description : insert the node to the list
  36. * Parameters : arg -- Additional argument to pass to the callback function
  37. * Returns : none
  38. *******************************************************************************/
  39. void ICACHE_FLASH_ATTR node_insert_to_list(list_node **phead, list_node* pinsert)
  40. {
  41. list_node *plist = NULL;
  42. struct dhcps_pool *pdhcps_pool = NULL;
  43. struct dhcps_pool *pdhcps_node = NULL;
  44. if (*phead == NULL)
  45. *phead = pinsert;
  46. else {
  47. plist = *phead;
  48. pdhcps_node = pinsert->pnode;
  49. pdhcps_pool = plist->pnode;
  50. if(pdhcps_node->ip.addr < pdhcps_pool->ip.addr) {
  51. pinsert->pnext = plist;
  52. *phead = pinsert;
  53. } else {
  54. while (plist->pnext != NULL) {
  55. pdhcps_pool = plist->pnext->pnode;
  56. if (pdhcps_node->ip.addr < pdhcps_pool->ip.addr) {
  57. pinsert->pnext = plist->pnext;
  58. plist->pnext = pinsert;
  59. break;
  60. }
  61. plist = plist->pnext;
  62. }
  63. if(plist->pnext == NULL) {
  64. plist->pnext = pinsert;
  65. }
  66. }
  67. }
  68. // pinsert->pnext = NULL;
  69. }
  70. /******************************************************************************
  71. * FunctionName : node_delete_from_list
  72. * Description : remove the node from list
  73. * Parameters : arg -- Additional argument to pass to the callback function
  74. * Returns : none
  75. *******************************************************************************/
  76. void ICACHE_FLASH_ATTR node_remove_from_list(list_node **phead, list_node* pdelete)
  77. {
  78. list_node *plist = NULL;
  79. plist = *phead;
  80. if (plist == NULL){
  81. *phead = NULL;
  82. } else {
  83. if (plist == pdelete){
  84. *phead = plist->pnext;
  85. pdelete->pnext = NULL;
  86. } else {
  87. while (plist != NULL) {
  88. if (plist->pnext == pdelete){
  89. plist->pnext = pdelete->pnext;
  90. pdelete->pnext = NULL;
  91. }
  92. plist = plist->pnext;
  93. }
  94. }
  95. }
  96. }
  97. ///////////////////////////////////////////////////////////////////////////////////
  98. /*
  99. * ��DHCP msg��Ϣ�ṹ����������
  100. *
  101. * @param optptr -- DHCP msg��Ϣλ��
  102. * @param type -- Ҫ��ӵ�����option
  103. *
  104. * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ
  105. */
  106. ///////////////////////////////////////////////////////////////////////////////////
  107. static uint8_t* ICACHE_FLASH_ATTR add_msg_type(uint8_t *optptr, uint8_t type)
  108. {
  109. *optptr++ = DHCP_OPTION_MSG_TYPE;
  110. *optptr++ = 1;
  111. *optptr++ = type;
  112. return optptr;
  113. }
  114. ///////////////////////////////////////////////////////////////////////////////////
  115. /*
  116. * ��DHCP msg�ṹ������offerӦ������
  117. *
  118. * @param optptr -- DHCP msg��Ϣλ��
  119. *
  120. * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ
  121. */
  122. ///////////////////////////////////////////////////////////////////////////////////
  123. static uint8_t* ICACHE_FLASH_ATTR add_offer_options(uint8_t *optptr)
  124. {
  125. struct ip_addr ipadd;
  126. ipadd.addr = *( (uint32_t *) &server_address);
  127. #ifdef USE_CLASS_B_NET
  128. *optptr++ = DHCP_OPTION_SUBNET_MASK;
  129. *optptr++ = 4; //length
  130. *optptr++ = 255;
  131. *optptr++ = 240;
  132. *optptr++ = 0;
  133. *optptr++ = 0;
  134. #else
  135. *optptr++ = DHCP_OPTION_SUBNET_MASK;
  136. *optptr++ = 4;
  137. *optptr++ = 255;
  138. *optptr++ = 255;
  139. *optptr++ = 255;
  140. *optptr++ = 0;
  141. #endif
  142. *optptr++ = DHCP_OPTION_LEASE_TIME;
  143. *optptr++ = 4;
  144. *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 24) & 0xFF;
  145. *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 16) & 0xFF;
  146. *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 8) & 0xFF;
  147. *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 0) & 0xFF;
  148. *optptr++ = DHCP_OPTION_SERVER_ID;
  149. *optptr++ = 4;
  150. *optptr++ = ip4_addr1( &ipadd);
  151. *optptr++ = ip4_addr2( &ipadd);
  152. *optptr++ = ip4_addr3( &ipadd);
  153. *optptr++ = ip4_addr4( &ipadd);
  154. if (dhcps_router_enabled(offer)){
  155. struct ip_info if_ip;
  156. os_bzero(&if_ip, sizeof(struct ip_info));
  157. wifi_get_ip_info(SOFTAP_IF, &if_ip);
  158. *optptr++ = DHCP_OPTION_ROUTER;
  159. *optptr++ = 4;
  160. *optptr++ = ip4_addr1( &if_ip.gw);
  161. *optptr++ = ip4_addr2( &if_ip.gw);
  162. *optptr++ = ip4_addr3( &if_ip.gw);
  163. *optptr++ = ip4_addr4( &if_ip.gw);
  164. }
  165. #ifdef USE_DNS
  166. *optptr++ = DHCP_OPTION_DNS_SERVER;
  167. *optptr++ = 4;
  168. *optptr++ = ip4_addr1( &ipadd);
  169. *optptr++ = ip4_addr2( &ipadd);
  170. *optptr++ = ip4_addr3( &ipadd);
  171. *optptr++ = ip4_addr4( &ipadd);
  172. #endif
  173. #ifdef CLASS_B_NET
  174. *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS;
  175. *optptr++ = 4;
  176. *optptr++ = ip4_addr1( &ipadd);
  177. *optptr++ = 255;
  178. *optptr++ = 255;
  179. *optptr++ = 255;
  180. #else
  181. *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS;
  182. *optptr++ = 4;
  183. *optptr++ = ip4_addr1( &ipadd);
  184. *optptr++ = ip4_addr2( &ipadd);
  185. *optptr++ = ip4_addr3( &ipadd);
  186. *optptr++ = 255;
  187. #endif
  188. *optptr++ = DHCP_OPTION_INTERFACE_MTU;
  189. *optptr++ = 2;
  190. #ifdef CLASS_B_NET
  191. *optptr++ = 0x05;
  192. *optptr++ = 0xdc;
  193. #else
  194. *optptr++ = 0x02;
  195. *optptr++ = 0x40;
  196. #endif
  197. *optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY;
  198. *optptr++ = 1;
  199. *optptr++ = 0x00;
  200. *optptr++ = 43;
  201. *optptr++ = 6;
  202. *optptr++ = 0x01;
  203. *optptr++ = 4;
  204. *optptr++ = 0x00;
  205. *optptr++ = 0x00;
  206. *optptr++ = 0x00;
  207. *optptr++ = 0x02;
  208. return optptr;
  209. }
  210. ///////////////////////////////////////////////////////////////////////////////////
  211. /*
  212. * ��DHCP msg�ṹ����ӽ����־����
  213. *
  214. * @param optptr -- DHCP msg��Ϣλ��
  215. *
  216. * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ
  217. */
  218. ///////////////////////////////////////////////////////////////////////////////////
  219. static uint8_t* ICACHE_FLASH_ATTR add_end(uint8_t *optptr)
  220. {
  221. *optptr++ = DHCP_OPTION_END;
  222. return optptr;
  223. }
  224. ///////////////////////////////////////////////////////////////////////////////////
  225. ///////////////////////////////////////////////////////////////////////////////////
  226. static void ICACHE_FLASH_ATTR create_msg(struct dhcps_msg *m)
  227. {
  228. struct ip_addr client;
  229. client.addr = client_address.addr;
  230. m->op = DHCP_REPLY;
  231. m->htype = DHCP_HTYPE_ETHERNET;
  232. m->hlen = 6;
  233. m->hops = 0;
  234. // os_memcpy((char *) xid, (char *) m->xid, sizeof(m->xid));
  235. m->secs = 0;
  236. m->flags = htons(BOOTP_BROADCAST);
  237. os_memcpy((char *) m->yiaddr, (char *) &client.addr, sizeof(m->yiaddr));
  238. os_memset((char *) m->ciaddr, 0, sizeof(m->ciaddr));
  239. os_memset((char *) m->siaddr, 0, sizeof(m->siaddr));
  240. os_memset((char *) m->giaddr, 0, sizeof(m->giaddr));
  241. os_memset((char *) m->sname, 0, sizeof(m->sname));
  242. os_memset((char *) m->file, 0, sizeof(m->file));
  243. os_memset((char *) m->options, 0, sizeof(m->options));
  244. //For xiaomi crash bug
  245. uint32 magic_cookie1 = magic_cookie;
  246. os_memcpy((char *) m->options, &magic_cookie1, sizeof(magic_cookie1));
  247. }
  248. struct pbuf * dhcps_pbuf_alloc(u16_t len)
  249. {
  250. u16_t mlen = sizeof(struct dhcps_msg);
  251. if (len > mlen) {
  252. #if DHCPS_DEBUG
  253. DHCPS_LOG("dhcps: len=%d mlen=%d", len, mlen);
  254. #endif
  255. mlen = len;
  256. }
  257. return pbuf_alloc(PBUF_TRANSPORT, mlen, PBUF_RAM);
  258. }
  259. ///////////////////////////////////////////////////////////////////////////////////
  260. /*
  261. * ����һ��OFFER
  262. *
  263. * @param -- m ָ����Ҫ���͵�DHCP msg����
  264. */
  265. ///////////////////////////////////////////////////////////////////////////////////
  266. static void ICACHE_FLASH_ATTR send_offer(struct dhcps_msg *m, u16_t len)
  267. {
  268. uint8_t *end;
  269. struct pbuf *p, *q;
  270. u8_t *data;
  271. u16_t cnt=0;
  272. u16_t i;
  273. err_t SendOffer_err_t;
  274. create_msg(m);
  275. end = add_msg_type(&m->options[4], DHCPOFFER);
  276. end = add_offer_options(end);
  277. end = add_end(end);
  278. p = dhcps_pbuf_alloc(len);
  279. #if DHCPS_DEBUG
  280. os_printf("udhcp: send_offer>>p->ref = %d\n", p->ref);
  281. #endif
  282. if(p != NULL){
  283. #if DHCPS_DEBUG
  284. os_printf("dhcps: send_offer>>pbuf_alloc succeed\n");
  285. os_printf("dhcps: send_offer>>p->tot_len = %d\n", p->tot_len);
  286. os_printf("dhcps: send_offer>>p->len = %d\n", p->len);
  287. #endif
  288. q = p;
  289. while(q != NULL){
  290. data = (u8_t *)q->payload;
  291. for(i=0; i<q->len; i++)
  292. {
  293. data[i] = ((u8_t *) m)[cnt++];
  294. }
  295. q = q->next;
  296. }
  297. }else{
  298. #if DHCPS_DEBUG
  299. os_printf("dhcps: send_offer>>pbuf_alloc failed\n");
  300. #endif
  301. return;
  302. }
  303. SendOffer_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT );
  304. #if DHCPS_DEBUG
  305. os_printf("dhcps: send_offer>>udp_sendto result %x\n",SendOffer_err_t);
  306. #endif
  307. if(p->ref != 0){
  308. #if DHCPS_DEBUG
  309. os_printf("udhcp: send_offer>>free pbuf\n");
  310. #endif
  311. pbuf_free(p);
  312. }
  313. }
  314. ///////////////////////////////////////////////////////////////////////////////////
  315. /*
  316. * ����һ��NAK��Ϣ
  317. *
  318. * @param m ָ����Ҫ���͵�DHCP msg����
  319. */
  320. ///////////////////////////////////////////////////////////////////////////////////
  321. static void ICACHE_FLASH_ATTR send_nak(struct dhcps_msg *m, u16_t len)
  322. {
  323. u8_t *end;
  324. struct pbuf *p, *q;
  325. u8_t *data;
  326. u16_t cnt=0;
  327. u16_t i;
  328. err_t SendNak_err_t;
  329. create_msg(m);
  330. end = add_msg_type(&m->options[4], DHCPNAK);
  331. end = add_end(end);
  332. p = dhcps_pbuf_alloc(len);
  333. #if DHCPS_DEBUG
  334. os_printf("udhcp: send_nak>>p->ref = %d\n", p->ref);
  335. #endif
  336. if(p != NULL){
  337. #if DHCPS_DEBUG
  338. os_printf("dhcps: send_nak>>pbuf_alloc succeed\n");
  339. os_printf("dhcps: send_nak>>p->tot_len = %d\n", p->tot_len);
  340. os_printf("dhcps: send_nak>>p->len = %d\n", p->len);
  341. #endif
  342. q = p;
  343. while(q != NULL){
  344. data = (u8_t *)q->payload;
  345. for(i=0; i<q->len; i++)
  346. {
  347. data[i] = ((u8_t *) m)[cnt++];
  348. }
  349. q = q->next;
  350. }
  351. }else{
  352. #if DHCPS_DEBUG
  353. os_printf("dhcps: send_nak>>pbuf_alloc failed\n");
  354. #endif
  355. return;
  356. }
  357. SendNak_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT );
  358. #if DHCPS_DEBUG
  359. os_printf("dhcps: send_nak>>udp_sendto result %x\n",SendNak_err_t);
  360. #endif
  361. if(p->ref != 0){
  362. #if DHCPS_DEBUG
  363. os_printf("udhcp: send_nak>>free pbuf\n");
  364. #endif
  365. pbuf_free(p);
  366. }
  367. }
  368. ///////////////////////////////////////////////////////////////////////////////////
  369. /*
  370. * ����һ��ACK��DHCP�ͻ���
  371. *
  372. * @param m ָ����Ҫ���͵�DHCP msg����
  373. */
  374. ///////////////////////////////////////////////////////////////////////////////////
  375. static void ICACHE_FLASH_ATTR send_ack(struct dhcps_msg *m, u16_t len)
  376. {
  377. u8_t *end;
  378. struct pbuf *p, *q;
  379. u8_t *data;
  380. u16_t cnt=0;
  381. u16_t i;
  382. err_t SendAck_err_t;
  383. create_msg(m);
  384. end = add_msg_type(&m->options[4], DHCPACK);
  385. end = add_offer_options(end);
  386. end = add_end(end);
  387. p = dhcps_pbuf_alloc(len);
  388. #if DHCPS_DEBUG
  389. os_printf("udhcp: send_ack>>p->ref = %d\n", p->ref);
  390. #endif
  391. if(p != NULL){
  392. #if DHCPS_DEBUG
  393. os_printf("dhcps: send_ack>>pbuf_alloc succeed\n");
  394. os_printf("dhcps: send_ack>>p->tot_len = %d\n", p->tot_len);
  395. os_printf("dhcps: send_ack>>p->len = %d\n", p->len);
  396. #endif
  397. q = p;
  398. while(q != NULL){
  399. data = (u8_t *)q->payload;
  400. for(i=0; i<q->len; i++)
  401. {
  402. data[i] = ((u8_t *) m)[cnt++];
  403. }
  404. q = q->next;
  405. }
  406. }else{
  407. #if DHCPS_DEBUG
  408. os_printf("dhcps: send_ack>>pbuf_alloc failed\n");
  409. #endif
  410. return;
  411. }
  412. SendAck_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT );
  413. #if DHCPS_DEBUG
  414. os_printf("dhcps: send_ack>>udp_sendto result %x\n",SendAck_err_t);
  415. #endif
  416. if(p->ref != 0){
  417. #if DHCPS_DEBUG
  418. os_printf("udhcp: send_ack>>free pbuf\n");
  419. #endif
  420. pbuf_free(p);
  421. }
  422. }
  423. ///////////////////////////////////////////////////////////////////////////////////
  424. /*
  425. * ����DHCP�ͻ��˷�����DHCP����������Ϣ�����Բ�ͬ��DHCP��������������Ӧ��Ӧ��
  426. *
  427. * @param optptr DHCP msg���������
  428. * @param len ��������Ĵ��?(byte)
  429. *
  430. * @return uint8_t ���ش�����DHCP Server״ֵ̬
  431. */
  432. ///////////////////////////////////////////////////////////////////////////////////
  433. static uint8_t ICACHE_FLASH_ATTR parse_options(uint8_t *optptr, sint16_t len)
  434. {
  435. struct ip_addr client;
  436. bool is_dhcp_parse_end = false;
  437. struct dhcps_state s;
  438. client.addr = *( (uint32_t *) &client_address);// Ҫ�����DHCP�ͻ��˵�IP
  439. u8_t *end = optptr + len;
  440. u16_t type = 0;
  441. s.state = DHCPS_STATE_IDLE;
  442. while (optptr < end) {
  443. #if DHCPS_DEBUG
  444. os_printf("dhcps: (sint16_t)*optptr = %d\n", (sint16_t)*optptr);
  445. #endif
  446. switch ((sint16_t) *optptr) {
  447. case DHCP_OPTION_MSG_TYPE: //53
  448. type = *(optptr + 2);
  449. break;
  450. case DHCP_OPTION_REQ_IPADDR://50
  451. //os_printf("dhcps:0x%08x,0x%08x\n",client.addr,*(uint32*)(optptr+2));
  452. if( os_memcmp( (char *) &client.addr, (char *) optptr+2,4)==0 ) {
  453. #if DHCPS_DEBUG
  454. os_printf("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n");
  455. #endif
  456. s.state = DHCPS_STATE_ACK;
  457. }else {
  458. #if DHCPS_DEBUG
  459. os_printf("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n");
  460. #endif
  461. s.state = DHCPS_STATE_NAK;
  462. }
  463. break;
  464. case DHCP_OPTION_END:
  465. {
  466. is_dhcp_parse_end = true;
  467. }
  468. break;
  469. }
  470. if(is_dhcp_parse_end){
  471. break;
  472. }
  473. optptr += optptr[1] + 2;
  474. }
  475. switch (type){
  476. case DHCPDISCOVER://1
  477. s.state = DHCPS_STATE_OFFER;
  478. #if DHCPS_DEBUG
  479. os_printf("dhcps: DHCPD_STATE_OFFER\n");
  480. #endif
  481. break;
  482. case DHCPREQUEST://3
  483. if ( !(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK) ) {
  484. if(renew == true) {
  485. s.state = DHCPS_STATE_ACK;
  486. } else {
  487. s.state = DHCPS_STATE_NAK;
  488. }
  489. #if DHCPS_DEBUG
  490. os_printf("dhcps: DHCPD_STATE_NAK\n");
  491. #endif
  492. }
  493. break;
  494. case DHCPDECLINE://4
  495. s.state = DHCPS_STATE_IDLE;
  496. #if DHCPS_DEBUG
  497. os_printf("dhcps: DHCPD_STATE_IDLE\n");
  498. #endif
  499. break;
  500. case DHCPRELEASE://7
  501. s.state = DHCPS_STATE_RELEASE;
  502. #if DHCPS_DEBUG
  503. os_printf("dhcps: DHCPD_STATE_IDLE\n");
  504. #endif
  505. break;
  506. }
  507. #if DHCPS_DEBUG
  508. os_printf("dhcps: return s.state = %d\n", s.state);
  509. #endif
  510. return s.state;
  511. }
  512. ///////////////////////////////////////////////////////////////////////////////////
  513. ///////////////////////////////////////////////////////////////////////////////////
  514. static sint16_t ICACHE_FLASH_ATTR parse_msg(struct dhcps_msg *m, u16_t len)
  515. {
  516. if(os_memcmp((char *)m->options,
  517. &magic_cookie,
  518. sizeof(magic_cookie)) == 0){
  519. struct ip_addr ip;
  520. os_memcpy(&ip.addr,m->ciaddr,sizeof(ip.addr));
  521. client_address.addr = wifi_softap_dhcps_client_update(m->chaddr,&ip);
  522. sint16_t ret = parse_options(&m->options[4], len);
  523. if(ret == DHCPS_STATE_RELEASE) {
  524. wifi_softap_dhcps_client_leave(m->chaddr,&ip,TRUE); // force to delete
  525. client_address.addr = ip.addr;
  526. }
  527. return ret;
  528. }
  529. return 0;
  530. }
  531. ///////////////////////////////////////////////////////////////////////////////////
  532. /*
  533. * DHCP ��������ݰ���մ���ص�����˺�����LWIP UDPģ������ʱ������
  534. * ��Ҫ����udp_recv()������LWIP����ע��.
  535. *
  536. * @param arg
  537. * @param pcb ���յ�UDP��Ŀ��ƿ�?
  538. * @param p ���յ���UDP�е��������?
  539. * @param addr ���ʹ�UDP���Դ�����IP��ַ
  540. * @param port ���ʹ�UDP���Դ�����UDPͨ���˿ں�
  541. */
  542. ///////////////////////////////////////////////////////////////////////////////////
  543. static void ICACHE_FLASH_ATTR handle_dhcp(void *arg,
  544. struct udp_pcb *pcb,
  545. struct pbuf *p,
  546. struct ip_addr *addr,
  547. uint16_t port)
  548. {
  549. struct dhcps_msg *pmsg_dhcps = NULL;
  550. sint16_t tlen = 0, malloc_len;
  551. u16_t i = 0;
  552. u16_t dhcps_msg_cnt = 0;
  553. u8_t *p_dhcps_msg = NULL;
  554. u8_t *data = NULL;
  555. #if DHCPS_DEBUG
  556. os_printf("dhcps: handle_dhcp-> receive a packet\n");
  557. #endif
  558. if (p==NULL) return;
  559. malloc_len = sizeof(struct dhcps_msg);
  560. #if DHCPS_DEBUG
  561. DHCPS_LOG("dhcps: handle_dhcp malloc_len=%d rx_len=%d", malloc_len, p->tot_len);
  562. #endif
  563. if (malloc_len < p->tot_len) {
  564. malloc_len = p->tot_len;
  565. }
  566. pmsg_dhcps = (struct dhcps_msg *)os_malloc(malloc_len);
  567. if (NULL == pmsg_dhcps){
  568. pbuf_free(p);
  569. return;
  570. }
  571. memset(pmsg_dhcps , 0x00 , malloc_len);
  572. p_dhcps_msg = (u8_t *)pmsg_dhcps;
  573. tlen = p->tot_len;
  574. data = p->payload;
  575. #if DHCPS_DEBUG
  576. os_printf("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen);
  577. os_printf("dhcps: handle_dhcp-> p->len = %d\n", p->len);
  578. #endif
  579. for(i=0; i<p->len; i++){
  580. p_dhcps_msg[dhcps_msg_cnt++] = data[i];
  581. }
  582. if(p->next != NULL) {
  583. #if DHCPS_DEBUG
  584. os_printf("dhcps: handle_dhcp-> p->next != NULL\n");
  585. os_printf("dhcps: handle_dhcp-> p->next->tot_len = %d\n",p->next->tot_len);
  586. os_printf("dhcps: handle_dhcp-> p->next->len = %d\n",p->next->len);
  587. #endif
  588. data = p->next->payload;
  589. for(i=0; i<p->next->len; i++){
  590. p_dhcps_msg[dhcps_msg_cnt++] = data[i];
  591. }
  592. }
  593. /*
  594. * DHCP �ͻ���������Ϣ����
  595. */
  596. #if DHCPS_DEBUG
  597. os_printf("dhcps: handle_dhcp-> parse_msg(p)\n");
  598. #endif
  599. switch(parse_msg(pmsg_dhcps, tlen - 240)) {
  600. case DHCPS_STATE_OFFER://1
  601. #if DHCPS_DEBUG
  602. os_printf("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n");
  603. #endif
  604. send_offer(pmsg_dhcps, malloc_len);
  605. break;
  606. case DHCPS_STATE_ACK://3
  607. #if DHCPS_DEBUG
  608. os_printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n");
  609. #endif
  610. send_ack(pmsg_dhcps, malloc_len);
  611. wifi_softap_set_station_info(pmsg_dhcps->chaddr, &client_address.addr);
  612. break;
  613. case DHCPS_STATE_NAK://4
  614. #if DHCPS_DEBUG
  615. os_printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n");
  616. #endif
  617. send_nak(pmsg_dhcps, malloc_len);
  618. break;
  619. default :
  620. break;
  621. }
  622. #if DHCPS_DEBUG
  623. os_printf("dhcps: handle_dhcp-> pbuf_free(p)\n");
  624. #endif
  625. pbuf_free(p);
  626. os_free(pmsg_dhcps);
  627. pmsg_dhcps = NULL;
  628. }
  629. ///////////////////////////////////////////////////////////////////////////////////
  630. static void ICACHE_FLASH_ATTR wifi_softap_init_dhcps_lease(uint32 ip)
  631. {
  632. uint32 softap_ip = 0,local_ip = 0;
  633. uint32 start_ip = 0;
  634. uint32 end_ip = 0;
  635. // if (dhcps_lease_flag) {
  636. if (dhcps_lease.enable == TRUE) {
  637. softap_ip = htonl(ip);
  638. start_ip = htonl(dhcps_lease.start_ip.addr);
  639. end_ip = htonl(dhcps_lease.end_ip.addr);
  640. /*config ip information can't contain local ip*/
  641. if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) {
  642. dhcps_lease.enable = FALSE;
  643. } else {
  644. /*config ip information must be in the same segment as the local ip*/
  645. softap_ip >>= 8;
  646. if (((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip))
  647. || (end_ip - start_ip > DHCPS_MAX_LEASE)) {
  648. dhcps_lease.enable = FALSE;
  649. }
  650. }
  651. }
  652. if (dhcps_lease.enable == FALSE) {
  653. local_ip = softap_ip = htonl(ip);
  654. softap_ip &= 0xFFFFFF00;
  655. local_ip &= 0xFF;
  656. if (local_ip >= 0x80)
  657. local_ip -= DHCPS_MAX_LEASE;
  658. else
  659. local_ip ++;
  660. os_bzero(&dhcps_lease, sizeof(dhcps_lease));
  661. dhcps_lease.start_ip.addr = softap_ip | local_ip;
  662. dhcps_lease.end_ip.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE - 1);
  663. dhcps_lease.start_ip.addr = htonl(dhcps_lease.start_ip.addr);
  664. dhcps_lease.end_ip.addr= htonl(dhcps_lease.end_ip.addr);
  665. }
  666. // dhcps_lease.start_ip.addr = htonl(dhcps_lease.start_ip.addr);
  667. // dhcps_lease.end_ip.addr= htonl(dhcps_lease.end_ip.addr);
  668. // os_printf("start_ip = 0x%x, end_ip = 0x%x\n",dhcps_lease.start_ip, dhcps_lease.end_ip);
  669. }
  670. ///////////////////////////////////////////////////////////////////////////////////
  671. void ICACHE_FLASH_ATTR dhcps_start(struct ip_info *info)
  672. {
  673. struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01);
  674. if(apnetif->dhcps_pcb != NULL) {
  675. udp_remove(apnetif->dhcps_pcb);
  676. }
  677. pcb_dhcps = udp_new();
  678. if (pcb_dhcps == NULL || info ==NULL) {
  679. os_printf("dhcps_start(): could not obtain pcb\n");
  680. }
  681. apnetif->dhcps_pcb = pcb_dhcps;
  682. IP4_ADDR(&broadcast_dhcps, 255, 255, 255, 255);
  683. server_address = info->ip;
  684. wifi_softap_init_dhcps_lease(server_address.addr);
  685. udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT);
  686. udp_recv(pcb_dhcps, handle_dhcp, NULL);
  687. #if DHCPS_DEBUG
  688. os_printf("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n");
  689. #endif
  690. }
  691. void ICACHE_FLASH_ATTR dhcps_stop(void)
  692. {
  693. struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01);
  694. udp_disconnect(pcb_dhcps);
  695. // dhcps_lease_flag = true;
  696. if(apnetif->dhcps_pcb != NULL) {
  697. udp_remove(apnetif->dhcps_pcb);
  698. apnetif->dhcps_pcb = NULL;
  699. }
  700. //udp_remove(pcb_dhcps);
  701. list_node *pnode = NULL;
  702. list_node *pback_node = NULL;
  703. struct dhcps_pool* dhcp_node = NULL;
  704. struct ip_addr ip_zero;
  705. os_memset(&ip_zero,0x0,sizeof(ip_zero));
  706. pnode = plist;
  707. while (pnode != NULL) {
  708. pback_node = pnode;
  709. pnode = pback_node->pnext;
  710. node_remove_from_list(&plist, pback_node);
  711. dhcp_node = (struct dhcps_pool*)pback_node->pnode;
  712. //wifi_softap_dhcps_client_leave(dhcp_node->mac,&dhcp_node->ip,TRUE); // force to delete
  713. wifi_softap_set_station_info(dhcp_node->mac, &ip_zero);
  714. os_free(pback_node->pnode);
  715. pback_node->pnode = NULL;
  716. os_free(pback_node);
  717. pback_node = NULL;
  718. }
  719. }
  720. /******************************************************************************
  721. * FunctionName : wifi_softap_set_dhcps_lease
  722. * Description : set the lease information of DHCP server
  723. * Parameters : please -- Additional argument to set the lease information,
  724. * Little-Endian.
  725. * Returns : true or false
  726. *******************************************************************************/
  727. bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease(struct dhcps_lease *please)
  728. {
  729. struct ip_info info;
  730. uint32 softap_ip = 0;
  731. uint32 start_ip = 0;
  732. uint32 end_ip = 0;
  733. uint8 opmode = wifi_get_opmode();
  734. if (opmode == STATION_MODE || opmode == NULL_MODE) {
  735. return false;
  736. }
  737. if (please == NULL || wifi_softap_dhcps_status() == DHCP_STARTED)
  738. return false;
  739. if(please->enable) {
  740. os_bzero(&info, sizeof(struct ip_info));
  741. wifi_get_ip_info(SOFTAP_IF, &info);
  742. softap_ip = htonl(info.ip.addr);
  743. start_ip = htonl(please->start_ip.addr);
  744. end_ip = htonl(please->end_ip.addr);
  745. /*config ip information can't contain local ip*/
  746. if ((start_ip <= softap_ip) && (softap_ip <= end_ip))
  747. return false;
  748. /*config ip information must be in the same segment as the local ip*/
  749. softap_ip >>= 8;
  750. if ((start_ip >> 8 != softap_ip)
  751. || (end_ip >> 8 != softap_ip)) {
  752. return false;
  753. }
  754. if (end_ip - start_ip > DHCPS_MAX_LEASE)
  755. return false;
  756. os_bzero(&dhcps_lease, sizeof(dhcps_lease));
  757. // dhcps_lease.start_ip.addr = start_ip;
  758. // dhcps_lease.end_ip.addr = end_ip;
  759. dhcps_lease.start_ip.addr = please->start_ip.addr;
  760. dhcps_lease.end_ip.addr = please->end_ip.addr;
  761. }
  762. dhcps_lease.enable = please->enable;
  763. // dhcps_lease_flag = false;
  764. return true;
  765. }
  766. /******************************************************************************
  767. * FunctionName : wifi_softap_get_dhcps_lease
  768. * Description : get the lease information of DHCP server
  769. * Parameters : please -- Additional argument to get the lease information,
  770. * Little-Endian.
  771. * Returns : true or false
  772. *******************************************************************************/
  773. bool ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease(struct dhcps_lease *please)
  774. {
  775. uint8 opmode = wifi_get_opmode();
  776. if (opmode == STATION_MODE || opmode == NULL_MODE) {
  777. return false;
  778. }
  779. if (NULL == please)
  780. return false;
  781. // if (dhcps_lease_flag){
  782. if (dhcps_lease.enable == FALSE){
  783. if (wifi_softap_dhcps_status() == DHCP_STOPPED)
  784. return false;
  785. } else {
  786. // os_bzero(please, sizeof(dhcps_lease));
  787. // if (wifi_softap_dhcps_status() == DHCP_STOPPED){
  788. // please->start_ip.addr = htonl(dhcps_lease.start_ip.addr);
  789. // please->end_ip.addr = htonl(dhcps_lease.end_ip.addr);
  790. // }
  791. }
  792. // if (wifi_softap_dhcps_status() == DHCP_STARTED){
  793. // os_bzero(please, sizeof(dhcps_lease));
  794. // please->start_ip.addr = dhcps_lease.start_ip.addr;
  795. // please->end_ip.addr = dhcps_lease.end_ip.addr;
  796. // }
  797. please->start_ip.addr = dhcps_lease.start_ip.addr;
  798. please->end_ip.addr = dhcps_lease.end_ip.addr;
  799. return true;
  800. }
  801. static void ICACHE_FLASH_ATTR kill_oldest_dhcps_pool(void)
  802. {
  803. list_node *pre = NULL, *p = NULL;
  804. list_node *minpre = NULL, *minp = NULL;
  805. struct dhcps_pool *pdhcps_pool = NULL, *pmin_pool = NULL;
  806. pre = plist;
  807. p = pre->pnext;
  808. minpre = pre;
  809. minp = p;
  810. while (p != NULL){
  811. pdhcps_pool = p->pnode;
  812. pmin_pool = minp->pnode;
  813. if (pdhcps_pool->lease_timer < pmin_pool->lease_timer){
  814. minp = p;
  815. minpre = pre;
  816. }
  817. pre = p;
  818. p = p->pnext;
  819. }
  820. minpre->pnext = minp->pnext;
  821. os_free(minp->pnode);
  822. minp->pnode = NULL;
  823. os_free(minp);
  824. minp = NULL;
  825. }
  826. void ICACHE_FLASH_ATTR dhcps_coarse_tmr(void)
  827. {
  828. uint8 num_dhcps_pool = 0;
  829. list_node *pback_node = NULL;
  830. list_node *pnode = NULL;
  831. struct dhcps_pool *pdhcps_pool = NULL;
  832. pnode = plist;
  833. while (pnode != NULL) {
  834. pdhcps_pool = pnode->pnode;
  835. if ( pdhcps_pool->type == DHCPS_TYPE_DYNAMIC) {
  836. pdhcps_pool->lease_timer --;
  837. }
  838. if (pdhcps_pool->lease_timer == 0){
  839. pback_node = pnode;
  840. pnode = pback_node->pnext;
  841. node_remove_from_list(&plist,pback_node);
  842. os_free(pback_node->pnode);
  843. pback_node->pnode = NULL;
  844. os_free(pback_node);
  845. pback_node = NULL;
  846. } else {
  847. pnode = pnode ->pnext;
  848. num_dhcps_pool ++;
  849. }
  850. }
  851. if (num_dhcps_pool >= MAX_STATION_NUM)
  852. kill_oldest_dhcps_pool();
  853. }
  854. bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_offer_option(uint8 level, void* optarg)
  855. {
  856. bool offer_flag = true;
  857. uint8 option = 0;
  858. if (optarg == NULL && wifi_softap_dhcps_status() == false)
  859. return false;
  860. if (level <= OFFER_START || level >= OFFER_END)
  861. return false;
  862. switch (level){
  863. case OFFER_ROUTER:
  864. offer = (*(uint8 *)optarg) & 0x01;
  865. offer_flag = true;
  866. break;
  867. default :
  868. offer_flag = false;
  869. break;
  870. }
  871. return offer_flag;
  872. }
  873. bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease_time(uint32 minute)
  874. {
  875. uint8 opmode = wifi_get_opmode();
  876. if (opmode == STATION_MODE || opmode == NULL_MODE) {
  877. return false;
  878. }
  879. if (wifi_softap_dhcps_status() == DHCP_STARTED) {
  880. return false;
  881. }
  882. if(minute == 0) {
  883. return false;
  884. }
  885. dhcps_lease_time = minute;
  886. return true;
  887. }
  888. bool ICACHE_FLASH_ATTR wifi_softap_reset_dhcps_lease_time(void)
  889. {
  890. uint8 opmode = wifi_get_opmode();
  891. if (opmode == STATION_MODE || opmode == NULL_MODE) {
  892. return false;
  893. }
  894. if (wifi_softap_dhcps_status() == DHCP_STARTED) {
  895. return false;
  896. }
  897. dhcps_lease_time = DHCPS_LEASE_TIME_DEF;
  898. return true;
  899. }
  900. uint32 ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease_time(void) // minute
  901. {
  902. return dhcps_lease_time;
  903. }
  904. void ICACHE_FLASH_ATTR wifi_softap_dhcps_client_leave(u8 *bssid, struct ip_addr *ip,bool force)
  905. {
  906. struct dhcps_pool *pdhcps_pool = NULL;
  907. list_node *pback_node = NULL;
  908. if ((bssid == NULL) || (ip == NULL)) {
  909. return;
  910. }
  911. for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) {
  912. pdhcps_pool = pback_node->pnode;
  913. if (os_memcmp(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)) == 0){
  914. if (os_memcmp(&pdhcps_pool->ip.addr, &ip->addr, sizeof(pdhcps_pool->ip.addr)) == 0) {
  915. if ((pdhcps_pool->type == DHCPS_TYPE_STATIC) || (force)) {
  916. if(pback_node != NULL) {
  917. node_remove_from_list(&plist,pback_node);
  918. os_free(pback_node);
  919. pback_node = NULL;
  920. }
  921. if (pdhcps_pool != NULL) {
  922. os_free(pdhcps_pool);
  923. pdhcps_pool = NULL;
  924. }
  925. } else {
  926. pdhcps_pool->state = DHCPS_STATE_OFFLINE;
  927. }
  928. struct ip_addr ip_zero;
  929. os_memset(&ip_zero,0x0,sizeof(ip_zero));
  930. wifi_softap_set_station_info(bssid, &ip_zero);
  931. break;
  932. }
  933. }
  934. }
  935. }
  936. uint32 ICACHE_FLASH_ATTR wifi_softap_dhcps_client_update(u8 *bssid, struct ip_addr *ip)
  937. {
  938. struct dhcps_pool *pdhcps_pool = NULL;
  939. list_node *pback_node = NULL;
  940. list_node *pmac_node = NULL;
  941. list_node *pip_node = NULL;
  942. bool flag = FALSE;
  943. uint32 start_ip = dhcps_lease.start_ip.addr;
  944. uint32 end_ip = dhcps_lease.end_ip.addr;
  945. dhcps_type_t type = DHCPS_TYPE_DYNAMIC;
  946. if (bssid == NULL) {
  947. return IPADDR_ANY;
  948. }
  949. if (ip) {
  950. if (IPADDR_BROADCAST == ip->addr) {
  951. return IPADDR_ANY;
  952. } else if (IPADDR_ANY == ip->addr) {
  953. ip = NULL;
  954. } else {
  955. type = DHCPS_TYPE_STATIC;
  956. }
  957. }
  958. renew = FALSE;
  959. for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) {
  960. pdhcps_pool = pback_node->pnode;
  961. //os_printf("mac:"MACSTR"bssid:"MACSTR"\r\n",MAC2STR(pdhcps_pool->mac),MAC2STR(bssid));
  962. if (os_memcmp(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)) == 0){
  963. pmac_node = pback_node;
  964. if (ip == NULL) {
  965. flag = TRUE;
  966. break;
  967. }
  968. }
  969. if (ip != NULL) {
  970. if (os_memcmp(&pdhcps_pool->ip.addr, &ip->addr, sizeof(pdhcps_pool->ip.addr)) == 0) {
  971. pip_node = pback_node;
  972. }
  973. } else if (flag == FALSE){
  974. if (os_memcmp(&pdhcps_pool->ip.addr, &start_ip, sizeof(pdhcps_pool->ip.addr)) != 0) {
  975. flag = TRUE;
  976. } else {
  977. start_ip = htonl((ntohl(start_ip) + 1));
  978. }
  979. }
  980. }
  981. if ((ip == NULL) && (flag == FALSE)) {
  982. if (plist == NULL) {
  983. if (start_ip <= end_ip) {
  984. flag = TRUE;
  985. } else {
  986. return IPADDR_ANY;
  987. }
  988. } else {
  989. if (start_ip > end_ip) {
  990. return IPADDR_ANY;
  991. }
  992. //start_ip = htonl((ntohl(start_ip) + 1));
  993. flag = TRUE;
  994. }
  995. }
  996. if (pmac_node != NULL) { // update new ip
  997. if (pip_node != NULL){
  998. pdhcps_pool = pip_node->pnode;
  999. if (pip_node != pmac_node) {
  1000. if(pdhcps_pool->state != DHCPS_STATE_OFFLINE) { // ip is used
  1001. return IPADDR_ANY;
  1002. }
  1003. // mac exists and ip exists in other node,delete mac
  1004. node_remove_from_list(&plist,pmac_node);
  1005. os_free(pmac_node->pnode);
  1006. pmac_node->pnode = NULL;
  1007. os_free(pmac_node);
  1008. pmac_node = pip_node;
  1009. os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac));
  1010. } else {
  1011. renew = true;
  1012. type = DHCPS_TYPE_DYNAMIC;
  1013. }
  1014. pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
  1015. pdhcps_pool->type = type;
  1016. pdhcps_pool->state = DHCPS_STATE_ONLINE;
  1017. } else {
  1018. pdhcps_pool = pmac_node->pnode;
  1019. if (ip != NULL) {
  1020. pdhcps_pool->ip.addr = ip->addr;
  1021. } else if (flag == TRUE) {
  1022. pdhcps_pool->ip.addr = start_ip;
  1023. } else { // no ip to distribute
  1024. return IPADDR_ANY;
  1025. }
  1026. node_remove_from_list(&plist,pmac_node);
  1027. pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
  1028. pdhcps_pool->type = type;
  1029. pdhcps_pool->state = DHCPS_STATE_ONLINE;
  1030. node_insert_to_list(&plist,pmac_node);
  1031. }
  1032. } else { // new station
  1033. if (pip_node != NULL) { // maybe ip has used
  1034. pdhcps_pool = pip_node->pnode;
  1035. if (pdhcps_pool->state != DHCPS_STATE_OFFLINE) {
  1036. return IPADDR_ANY;
  1037. }
  1038. os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac));
  1039. pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
  1040. pdhcps_pool->type = type;
  1041. pdhcps_pool->state = DHCPS_STATE_ONLINE;
  1042. } else {
  1043. pdhcps_pool = (struct dhcps_pool *)os_zalloc(sizeof(struct dhcps_pool));
  1044. if (ip != NULL) {
  1045. pdhcps_pool->ip.addr = ip->addr;
  1046. } else if (flag == TRUE) {
  1047. pdhcps_pool->ip.addr = start_ip;
  1048. } else { // no ip to distribute
  1049. os_free(pdhcps_pool);
  1050. return IPADDR_ANY;
  1051. }
  1052. if (pdhcps_pool->ip.addr > end_ip) {
  1053. os_free(pdhcps_pool);
  1054. return IPADDR_ANY;
  1055. }
  1056. os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac));
  1057. pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
  1058. pdhcps_pool->type = type;
  1059. pdhcps_pool->state = DHCPS_STATE_ONLINE;
  1060. pback_node = (list_node *)os_zalloc(sizeof(list_node ));
  1061. pback_node->pnode = pdhcps_pool;
  1062. pback_node->pnext = NULL;
  1063. node_insert_to_list(&plist,pback_node);
  1064. }
  1065. }
  1066. return pdhcps_pool->ip.addr;
  1067. }