14 #if (USE_DHCP == VAL_DISABLE)
18 #define DHCP_SERVER_PORT 67 // from server to client
19 #define DHCP_CLIENT_PORT 68 // from client to server
21 #define DHCP_BOOTREQUEST 1
22 #define DHCP_BOOTREPLY 2
23 #define DHCP_HTYPE10MB 1
24 #define DHCP_HTYPE100MB 2
25 #define DHCP_HLENETHERNET 6
28 #define DHCP_UNICAST 0x0
29 #define DHCP_BROADCAST 0x8000
30 #define MAGIC_COOKIE 0x63825363
31 #define HOST_NAME "WIZnet"
33 #define DHCP_MSG_DISCOVER 1 // DHCP message type
34 #define DHCP_MSG_OFFER 2
35 #define DHCP_MSG_REQUEST 3
36 #define DHCP_MSG_DECLINE 4
37 #define DHCP_MSG_ACK 5
38 #define DHCP_MSG_NAK 6
39 #define DHCP_MSG_RELEASE 7
41 #define DHCP_START_RETRY_DELAY 60000 // tick
42 #define DHCP_RETRY_DELAY 5000 // tick
45 #define DHCP_OPEN_DELAY 0 // tick
46 #define DHCP_SEND_RETRY_COUNT 3
48 #define IS_IP_SET(ip_p) (ip_p[0]+ip_p[1]+ip_p[2]+ip_p[3] != 0)
49 #define IS_TIME_PASSED(tick_v, time_v) (wizpf_tick_elapse(tick_v) > time_v)
50 #define SET_STATE(_new_state) do { \
51 DBGA("DHCP STATE: [%d] => [%d]", di.state, _new_state); \
52 di.state = _new_state; \
67 resourceLocationServer = 11,
76 nonLocalSourceRouting = 20,
78 maxDgramReasmSize = 22,
80 pathMTUagingTimeout = 24,
81 pathMTUplateauTable = 25,
85 performMaskDiscovery = 29,
87 performRouterDiscovery = 31,
88 routerSolicitationAddr = 32,
90 trailerEncapsulation = 34,
92 ethernetEncapsulation = 36,
94 tcpKeepaliveInterval = 38,
95 tcpKeepaliveGarbage = 39,
99 vendorSpecificInfo = 43,
100 netBIOSnameServer = 44,
101 netBIOSdgramDistServer = 45,
102 netBIOSnodeType = 46,
105 xDisplayManager = 49,
106 dhcpRequestedIPaddr = 50,
107 dhcpIPaddrLeaseTime = 51,
108 dhcpOptionOverload = 52,
109 dhcpMessageType = 53,
110 dhcpServerIdentifier = 54,
111 dhcpParamRequest = 55,
116 dhcpClassIdentifier = 60,
117 dhcpClientIdentifier = 61,
141 uint8 srv_ip_real[4];
153 static void dhcp_alarm_cb(int8 arg);
154 static void dhcp_async_cb(uint8 sock, uint8 item, int32 ret);
155 static void dhcp_run(
void);
156 static void dhcp_fail(
void);
157 static int8 recv_handler(
void);
158 static int8 send_discover(
void);
159 static int8 send_request(
void);
167 static struct dhcp_info di;
168 static struct dhcp_msg dm;
169 static bool dhcp_alarm = FALSE;
170 static bool dhcp_async = FALSE;
171 static uint8 dhcp_run_cnt = 0;
172 static uint32 dhcp_run_tick = 0;
194 ERRA(
"wrong socket number(%d)", sock);
205 memset(&di, 0,
sizeof(di));
206 memcpy(&storage, def,
sizeof(storage));
207 memset(&workinfo, 0,
sizeof(workinfo));
208 memcpy(workinfo.
mac, storage.
mac, 6);
213 if(ip_update_hook) di.ip_update = ip_update_hook;
214 if(ip_conflict_hook) di.ip_conflict = ip_conflict_hook;
238 if(dhcp_alarm == TRUE)
return RET_NOK;
247 memset(&workinfo, 0,
sizeof(workinfo));
259 if(renew) *renew = di.renew_time;
260 if(rebind) *rebind = di.rebind_time;
263 if(renew) *renew = 0;
264 if(rebind) *rebind = 0;
275 ERRA(
"wrong action(%d)", action);
284 if(renew) *renew = di.renew_time;
285 if(rebind) *rebind = di.rebind_time;
322 if(net->
mac[0]!=0 || net->
mac[1]!=0 || net->
mac[2]!=0 || net->
mac[3]!=0 ||
323 net->
mac[2]!=0 || net->
mac[3]!=0) memcpy(storage.
mac, net->
mac, 6);
324 if(net->
ip[0]!=0 || net->
ip[1]!=0 || net->
ip[2]!=0 || net->
ip[3]!=0)
325 memcpy(storage.
ip, net->
ip, 4);
326 if(net->
sn[0]!=0 || net->
sn[1]!=0 || net->
sn[2]!=0 || net->
sn[3]!=0)
327 memcpy(storage.
sn, net->
sn, 4);
328 if(net->
gw[0]!=0 || net->
gw[1]!=0 || net->
gw[2]!=0 || net->
gw[3]!=0)
329 memcpy(storage.
gw, net->
gw, 4);
330 if(net->
dns[0]!=0 || net->
dns[1]!=0 || net->
dns[2]!=0 || net->
dns[3]!=0)
331 memcpy(storage.
dns, net->
dns, 4);
349 memcpy(net->
mac, storage.
mac, 6);
350 memcpy(net->
ip, storage.
ip, 4);
351 memcpy(net->
sn, storage.
sn, 4);
352 memcpy(net->
gw, storage.
gw, 4);
353 memcpy(net->
dns, storage.
dns, 4);
370 if(net->
ip[0]!=0 || net->
ip[1]!=0 || net->
ip[2]!=0 || net->
ip[3]!=0)
371 memcpy(storage.
ip, net->
ip, 4);
372 else memcpy(net->
ip, storage.
ip, 4);
373 if(net->
sn[0]!=0 || net->
sn[1]!=0 || net->
sn[2]!=0 || net->
sn[3]!=0)
374 memcpy(storage.
sn, net->
sn, 4);
375 else memcpy(net->
sn, storage.
sn, 4);
376 if(net->
gw[0]!=0 || net->
gw[1]!=0 || net->
gw[2]!=0 || net->
gw[3]!=0)
377 memcpy(storage.
gw, net->
gw, 4);
378 else memcpy(net->
gw, storage.
gw, 4);
379 if(net->
dns[0]!=0 || net->
dns[1]!=0 || net->
dns[2]!=0 || net->
dns[3]!=0)
380 memcpy(storage.
dns, net->
dns, 4);
381 else memcpy(net->
dns, storage.
dns, 4);
387 memset(&workinfo, 0,
sizeof(workinfo));
392 if(dhcp_alarm)
alarm_del(dhcp_alarm_cb, -1);
410 memset(&workinfo, 0,
sizeof(workinfo));
416 if(dhcp_alarm)
alarm_set(10, dhcp_alarm_cb, 0);
421 static void dhcp_alarm_cb(int8 arg)
423 if(dhcp_alarm == FALSE)
return;
434 }
else if(arg == 1) {
439 }
else if(arg == 2) {
447 static void dhcp_async_cb(uint8 sock, uint8 item, int32 ret)
451 if(dhcp_alarm)
alarm_set(10, dhcp_alarm_cb, 0);
454 DBG(
"DHCP Discovery Sent Async");
457 else DBGCRTCA(TRUE,
"wrong state(%d)", di.state);
459 DBGA(
"WATCH_SOCK_UDP_SEND fail - ret(%d)", ret);
468 DBGCRTC(TRUE,
"DHCP does not use TCP");
469 default:
DBGCRTCA(TRUE,
"wrong item(0x%x)", item);
474 static void dhcp_run(
void)
476 static bool udp_open_fail = FALSE;
479 DBG(
"wrong attempt");
482 if(udp_open_fail == TRUE && !IS_TIME_PASSED(dhcp_run_tick, DHCP_RETRY_DELAY))
490 udp_open_fail = FALSE;
495 udp_open_fail = TRUE;
503 if(dhcp_run_cnt==0 && !IS_TIME_PASSED(dhcp_run_tick, DHCP_OPEN_DELAY))
506 if(dhcp_run_cnt < DHCP_SEND_RETRY_COUNT) {
508 if(send_discover() ==
RET_OK) {
510 DBG(
"DHCP Discovery Send Async");
514 DBG(
"DHCP Discovery Sent");
519 ERRA(
"DHCP Discovery SEND fail - (%d)times", dhcp_run_cnt);
523 ERRA(
"DHCP Discovery SEND fail - (%d)times", dhcp_run_cnt);
532 if(!IS_TIME_PASSED(dhcp_run_tick, DHCP_RETRY_DELAY)) {
533 int8 ret = recv_handler();
534 if(ret == DHCP_MSG_OFFER) {
538 }
else if(ret !=
RET_NOK)
DBGCRTCA(TRUE,
"recv wrong packet(%d)", ret);
540 ERRA(
"DHCP Offer RECV fail - for (%d)msec", DHCP_RETRY_DELAY);
546 if(dhcp_run_cnt < DHCP_SEND_RETRY_COUNT) {
548 if(send_request() ==
RET_OK) {
550 DBG(
"DHCP Request Send Async");
554 DBG(
"DHCP Request Sent");
559 ERRA(
"DHCP Request SEND fail - (%d)times", dhcp_run_cnt);
563 ERRA(
"DHCP Request SEND fail - (%d)times", dhcp_run_cnt);
572 if(!IS_TIME_PASSED(dhcp_run_tick, DHCP_RETRY_DELAY)) {
573 int8 ret = recv_handler();
574 if(ret == DHCP_MSG_ACK) {
579 }
else if(ret == DHCP_MSG_NAK) {
587 }
else if(ret !=
RET_NOK)
DBGCRTCA(TRUE,
"recv wrong packet(%d)", ret);
589 ERRA(
"DHCP ACK RECV fail - for (%d)msec", DHCP_RETRY_DELAY);
602 if(di.ip_update) di.ip_update();
603 LOGA(
"DHCP ok - New IP (%d.%d.%d.%d)",
604 workinfo.
ip[0], workinfo.
ip[1], workinfo.
ip[2], workinfo.
ip[3]);
620 ERRA(
"wrong state(%d)", di.state);
625 if(dhcp_alarm)
alarm_set(10, dhcp_alarm_cb, 0);
628 static void dhcp_fail(
void)
630 LOG(
"DHCP Fail - set temp addr");
633 memcpy(&workinfo, &storage,
sizeof(storage));
634 memset(workinfo.
mac, 0, 6);
638 alarm_set(DHCP_START_RETRY_DELAY, dhcp_alarm_cb, 0);
642 static int8 recv_handler(
void)
645 uint8 recv_ip[4], opt_len, msg_type;
650 if(recv_len == 0)
return RET_NOK;
651 else memset(&dm, 0,
sizeof(
struct dhcp_msg));
653 recv_len =
UDPRecv(di.sock, (int8*)&dm,
sizeof(
struct dhcp_msg), recv_ip, &recv_port);
655 ERRA(
"UDPRecv fail - ret(%d)", recv_len);
660 DBGA(
"DHCP_SIP:%d.%d.%d.%d",di.srv_ip[0],di.srv_ip[1],di.srv_ip[2],di.srv_ip[3]);
661 DBGA(
"DHCP_RIP:%d.%d.%d.%d",di.srv_ip_real[0],di.srv_ip_real[1],di.srv_ip_real[2],di.srv_ip_real[3]);
662 DBGA(
"recv_ip:%d.%d.%d.%d",recv_ip[0],recv_ip[1],recv_ip[2],recv_ip[3]);
664 if(dm.op != DHCP_BOOTREPLY || recv_port != DHCP_SERVER_PORT) {
665 if(dm.op != DHCP_BOOTREPLY)
DBG(
"DHCP : NO DHCP MSG");
666 if(recv_port != DHCP_SERVER_PORT)
DBG(
"DHCP : WRONG PORT");
670 if(memcmp(dm.chaddr, storage.
mac, 6) != 0 || dm.xid !=
htonl(di.xid)) {
671 DBG(
"No My DHCP Message. This message is ignored.");
672 DBGA(
"SRC_MAC_ADDR(%02X:%02X:%02X:%02X:%02X:%02X)",
673 storage.
mac[0], storage.
mac[1], storage.
mac[2],
674 storage.
mac[3], storage.
mac[4], storage.
mac[5]);
675 DBGA(
"chaddr(%02X:%02X:%02X:%02X:%02X:%02X)", dm.chaddr[0],
676 dm.chaddr[1], dm.chaddr[2], dm.chaddr[3], dm.chaddr[4], dm.chaddr[5]);
677 DBGA(
"DHCP_XID(%08lX), xid(%08lX), yiaddr(%d.%d.%d.%d)",
htonl(di.xid),
678 dm.xid, dm.yiaddr[0], dm.yiaddr[1], dm.yiaddr[2], dm.yiaddr[3]);
682 if( *((uint32*)di.srv_ip) != 0x00000000 ) {
683 if( *((uint32*)di.srv_ip_real) != *((uint32*)recv_ip) &&
684 *((uint32*)di.srv_ip) != *((uint32*)recv_ip) ) {
685 DBG(
"Another DHCP sever send a response message. This is ignored.");
686 DBGA(
"IP:%d.%d.%d.%d",recv_ip[0],recv_ip[1],recv_ip[2],recv_ip[3]);
691 memcpy(workinfo.
ip, dm.yiaddr, 4);
692 DBG(
"DHCP MSG received..");
693 DBGA(
"yiaddr : %d.%d.%d.%d",workinfo.
ip[0],workinfo.
ip[1],workinfo.
ip[2],workinfo.
ip[3]);
696 cur = (uint8 *)(&dm.op);
698 end = cur + (recv_len - 240);
707 case dhcpMessageType:
710 DBGA(
"dhcpMessageType : %x", msg_type);
714 memcpy(workinfo.
sn,cur,4);
715 DBGA(
"subnetMask : %d.%d.%d.%d",
716 workinfo.
sn[0],workinfo.
sn[1],workinfo.
sn[2],workinfo.
sn[3]);
718 case routersOnSubnet:
720 memcpy(workinfo.
gw,cur,4);
721 DBGA(
"routersOnSubnet : %d.%d.%d.%d",
722 workinfo.
gw[0],workinfo.
gw[1],workinfo.
gw[2],workinfo.
gw[3]);
726 memcpy(workinfo.
dns,cur,4);
728 case dhcpIPaddrLeaseTime:
730 di.lease_time =
ntohl(*((uint32*)cur));
731 di.renew_time = di.lease_time / 2;
732 di.rebind_time = di.lease_time / 8 * 7;
733 DBGA(
"lease(%d), renew(%d), rebind(%d)", di.lease_time, di.renew_time, di.rebind_time);
735 case dhcpServerIdentifier:
737 DBGA(
"DHCP_SIP : %d.%d.%d.%d", di.srv_ip[0], di.srv_ip[1], di.srv_ip[2], di.srv_ip[3]);
738 if( *((uint32*)di.srv_ip) == 0 || *((uint32*)di.srv_ip_real) == *((uint32*)recv_ip) ||
739 *((uint32*)di.srv_ip) == *((uint32*)recv_ip) ) {
740 memcpy(di.srv_ip,cur,4);
741 memcpy(di.srv_ip_real,recv_ip,4);
742 DBGA(
"My dhcpServerIdentifier : %d.%d.%d.%d",
743 di.srv_ip[0], di.srv_ip[1], di.srv_ip[2], di.srv_ip[3]);
744 DBGA(
"My DHCP server real IP address : %d.%d.%d.%d",
745 di.srv_ip_real[0], di.srv_ip_real[1], di.srv_ip_real[2], di.srv_ip_real[3]);
747 DBGA(
"Another dhcpServerIdentifier : MY(%d.%d.%d.%d)",
748 di.srv_ip[0], di.srv_ip[1], di.srv_ip[2], di.srv_ip[3]);
749 DBGA(
"Another(%d.%d.%d.%d)", recv_ip[0], recv_ip[1], recv_ip[2], recv_ip[3]);
754 DBGA(
"opt_len : %d", opt_len);
763 static int8 send_discover(
void)
768 memset(&dm, 0,
sizeof(
struct dhcp_msg));
770 *((uint32*)di.srv_ip)=0;
771 *((uint32*)di.srv_ip_real)=0;
773 dm.op = DHCP_BOOTREQUEST;
774 dm.htype = DHCP_HTYPE10MB;
775 dm.hlen = DHCP_HLENETHERNET;
777 dm.xid =
htonl(di.xid);
778 dm.secs =
htons(DHCP_SECS);
779 memcpy(dm.chaddr, storage.
mac, 6);
780 dm.flags =
htons(DHCP_BROADCAST);
783 *(uint32*)&dm.opt[len] =
htonl(MAGIC_COOKIE);
787 dm.opt[len++] = dhcpMessageType;
788 dm.opt[len++] = 0x01;
789 dm.opt[len++] = DHCP_MSG_DISCOVER;
792 dm.opt[len++] = dhcpClientIdentifier;
793 dm.opt[len++] = 0x07;
794 dm.opt[len++] = 0x01;
795 memcpy(&dm.opt[len], storage.
mac, 6);
799 dm.opt[len++] = hostName;
800 dm.opt[len++] = strlen(HOST_NAME) + 6;
801 strcpy((
char*)&dm.opt[len], HOST_NAME);
802 len += strlen(HOST_NAME);
803 sprintf((
char*)&dm.opt[len],
"%02x%02x%02x",
804 storage.
mac[3], storage.
mac[4], storage.
mac[5]);
807 dm.opt[len++] = dhcpParamRequest;
808 dm.opt[len++] = 0x06;
809 dm.opt[len++] = subnetMask;
810 dm.opt[len++] = routersOnSubnet;
812 dm.opt[len++] = domainName;
813 dm.opt[len++] = dhcpT1value;
814 dm.opt[len++] = dhcpT2value;
815 dm.opt[len++] = endOption;
818 srv_ip[0] = srv_ip[1] = srv_ip[2] = srv_ip[3] = 255;
821 len =
UDPSendNB(di.sock, (int8*)&dm,
sizeof(
struct dhcp_msg), srv_ip, DHCP_SERVER_PORT);
822 if(len <
sizeof(
struct dhcp_msg)) {
823 if(len < 0)
ERRA(
"UDPSend fail - ret(%d)", len);
824 else ERRA(
"UDPSend sent less than size - size(%d), sent(%d)",
825 sizeof(
struct dhcp_msg), len);
829 len =
UDPSend(di.sock, (int8*)&dm,
sizeof(
struct dhcp_msg), srv_ip, DHCP_SERVER_PORT);
831 ERRA(
"UDPSend fail - ret(%d)", len);
839 static int8 send_request(
void)
844 memset(&dm, 0,
sizeof(
struct dhcp_msg));
846 dm.op = DHCP_BOOTREQUEST;
847 dm.htype = DHCP_HTYPE10MB;
848 dm.hlen = DHCP_HLENETHERNET;
850 dm.xid =
htonl(di.xid);
851 dm.secs =
htons(DHCP_SECS);
855 memcpy(dm.ciaddr, workinfo.
ip, 4);
857 dm.flags =
htons(DHCP_BROADCAST);
860 memcpy(dm.chaddr, storage.
mac, 6);
863 *(uint32*)&dm.opt[len] =
htonl(MAGIC_COOKIE);
867 dm.opt[len++] = dhcpMessageType;
868 dm.opt[len++] = 0x01;
869 dm.opt[len++] = DHCP_MSG_REQUEST;
871 dm.opt[len++] = dhcpClientIdentifier;
872 dm.opt[len++] = 0x07;
873 dm.opt[len++] = 0x01;
874 memcpy(&dm.opt[len], storage.
mac, 6);
878 dm.opt[len++] = dhcpRequestedIPaddr;
879 dm.opt[len++] = 0x04;
880 memcpy(&dm.opt[len], workinfo.
ip, 4);
882 dm.opt[len++] = dhcpServerIdentifier;
883 dm.opt[len++] = 0x04;
884 memcpy(&dm.opt[len], di.srv_ip, 4);
889 dm.opt[len++] = hostName;
890 dm.opt[len++] = strlen(HOST_NAME) + 6;
891 strcpy((
char*)&dm.opt[len], HOST_NAME);
892 len += strlen(HOST_NAME);
893 sprintf((
char*)&dm.opt[len],
"%02x%02x%02x",
894 storage.
mac[3], storage.
mac[4], storage.
mac[5]);
897 dm.opt[len++] = dhcpParamRequest;
898 dm.opt[len++] = 0x08;
899 dm.opt[len++] = subnetMask;
900 dm.opt[len++] = routersOnSubnet;
902 dm.opt[len++] = domainName;
903 dm.opt[len++] = dhcpT1value;
904 dm.opt[len++] = dhcpT2value;
905 dm.opt[len++] = performRouterDiscovery;
906 dm.opt[len++] = staticRoute;
907 dm.opt[len++] = endOption;
911 memcpy(srv_ip, di.srv_ip, 4);
913 srv_ip[0] = srv_ip[1] = srv_ip[2] = srv_ip[3] = 255;
917 len =
UDPSendNB(di.sock, (int8*)&dm,
sizeof(
struct dhcp_msg), srv_ip, DHCP_SERVER_PORT);
918 if(len <
sizeof(
struct dhcp_msg)) {
919 if(len < 0)
ERRA(
"UDPSend fail - ret(%d)", len);
920 else ERRA(
"UDPSend sent less than size - size(%d), sent(%d)",
sizeof(
struct dhcp_msg), len);
924 len =
UDPSend(di.sock, (int8*)&dm,
sizeof(
struct dhcp_msg), srv_ip, DHCP_SERVER_PORT);
926 ERRA(
"UDPSend fail - ret(%d)", len);