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);