00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00071 #include<inet/datatypes.h>
00072 #include<inet/debug.h>
00073 #include<inet/system.h>
00074 #include<inet/tcp_ip.h>
00075 #include<inet/timers.h>
00076 #include<inet/arp.h>
00077 #include<inet/ethernet.h>
00078 #include<inet/dhcp/dhcpc.h>
00079
00087 UINT8 dhcpc_state;
00088
00094 UINT8 dhcpc_timer_handle;
00095
00100 INT8 dhcpc_soc_handle;
00101
00106 UINT8 dhcpc_initialized=0;
00107
00115 UINT32 dhcpc_t1;
00116
00124 UINT32 dhcpc_t2;
00125
00131 UINT32 dhcpc_server_identifier;
00132
00140 UINT32 dhcpc_requested_ip;
00141
00142 INT32 dhcpc_eventlistener(INT8 cbhandle, UINT8 event, UINT32 ipaddr, UINT16 port, UINT16 buffindex, UINT16 datalen);
00143 INT8 dhcpc_send_message(UINT8 msg_type);
00144
00158 INT8 dhcpc_init(void)
00159 {
00160
00161
00162
00163 if((localmachine.localip!=0)&&(localmachine.localip!=0xffffffff)){
00164 dhcpc_state=DHCP_STATE_INIT_REBOOT;
00165 }else{
00166
00167 dhcpc_state=DHCP_STATE_INIT;
00168 }
00169
00170 dhcpc_soc_handle=udp_getsocket(0,dhcpc_eventlistener,UDP_OPT_SEND_CS|UDP_OPT_CHECK_CS);
00171
00172 if(dhcpc_soc_handle<0){
00173 DEBUGOUT("DHCP client not able to obtain socket!\r\n");
00174 return (-1);
00175 }
00176
00177
00178 udp_open(dhcpc_soc_handle,DHCP_CLIENT_PORT);
00179
00180
00181 dhcpc_timer_handle=get_timer();
00182
00183
00184 init_timer(dhcpc_timer_handle,TIMERTIC*1);
00185
00186 dhcpc_initialized=1;
00187 DEBUGOUT("DHCP Client initialized\r\n");
00188
00189 return (0);
00190 }
00191
00201 void dhcpc_run(void){
00202 UINT8 sec=0;
00203
00204 if(!dhcpc_initialized)
00205 return;
00206
00207 if(!check_timer(dhcpc_timer_handle))
00208 sec=1;
00209
00210 switch(dhcpc_state){
00211 case DHCP_STATE_INIT_REBOOT:
00212 dhcpc_state=DHCP_STATE_REBOOTING;
00213 dhcpc_t1=4;
00214 dhcpc_t2=8;
00215 dhcpc_requested_ip=localmachine.localip;
00216 dhcpc_send_message(DHCP_REQUEST);
00217 break;
00218
00219 case DHCP_STATE_REBOOTING:
00220 if(sec)
00221 dhcpc_t1--;
00222
00223 if(!dhcpc_t1){
00224 if(dhcpc_t2>=32){
00225
00226
00227
00228 dhcpc_state=DHCP_STATE_INIT_REBOOT;
00229 }else{
00230 dhcpc_t1=dhcpc_t2;
00231 dhcpc_t2<<=1;
00232 dhcpc_send_message(DHCP_REQUEST);
00233 }
00234 }
00235 break;
00236 case DHCP_STATE_INIT:
00237
00238
00239
00240 DEBUGOUT("DHCP State=INIT; Sending DHCPDISCOVER message; State INIT-->SELECTING\r\n");
00241 dhcpc_state=DHCP_STATE_SELECTING;
00242 dhcpc_send_message(DHCP_DISCOVER);
00243
00244 dhcpc_t1=4;
00245 dhcpc_t2=8;
00246 break;
00247 case DHCP_STATE_SELECTING:
00248
00249 if(sec)
00250 dhcpc_t1--;
00251
00252
00253 if(!dhcpc_t1){
00254 DEBUGOUT("DHCP State=SELECTING; ");
00255
00256 if(dhcpc_t2>=32){
00257
00258
00259
00260 dhcpc_state=DHCP_STATE_INIT;
00261 DEBUGOUT("Timeout for retransmissions too big; State SELECTING-->INIT\r\n");
00262 }else{
00263 DEBUGOUT("Retransmitting DHCPDISCOVER\r\n");
00264 dhcpc_t1=dhcpc_t2;
00265 dhcpc_t2<<=1;
00266 dhcpc_send_message(DHCP_DISCOVER);
00267 }
00268 }
00269 break;
00270 case DHCP_STATE_REQUESTING:
00271
00272
00273
00274 if(sec)
00275 dhcpc_t1--;
00276
00277 if(!dhcpc_t1){
00278
00279 DEBUGOUT("DHCP State=REQUESTING; ");
00280 if(dhcpc_t2>=32){
00281
00282
00283
00284
00285 dhcpc_state=DHCP_STATE_INIT;
00286 DEBUGOUT("Timeout for retransmits too big; State REQUESTING-->INIT\r\n");
00287 }else{
00288 DEBUGOUT("Retransmitting DHCPREQUEST\r\n");
00289 dhcpc_t1=dhcpc_t2;
00290 dhcpc_t2<<=1;
00291 dhcpc_send_message(DHCP_REQUEST);
00292 }
00293 }
00294 break;
00295 case DHCP_STATE_BOUND:
00296
00297 if(sec){
00298 dhcpc_t1--;
00299 dhcpc_t2--;
00300 }
00301 if(!dhcpc_t1){
00302 DEBUGOUT("DHCP State=BOUND; Starting renewing process; State BOUND-->RENEWING\r\n");
00303
00304 dhcpc_state=DHCP_STATE_RENEWING;
00305
00306 dhcpc_send_message(DHCP_REQUEST);
00307
00308
00309
00310
00311 dhcpc_t1=10;
00312 }
00313 break;
00314 case DHCP_STATE_RENEWING:
00315 if(sec){
00316 dhcpc_t1--;
00317 dhcpc_t2--;
00318 }
00319
00320 if(!dhcpc_t2){
00321 DEBUGOUT("DHCP State=RENEWING; T2 expired; State RENEWING-->REBINDING\r\n");
00322
00323
00324
00325 dhcpc_state=DHCP_STATE_REBINDING;
00326
00327 dhcpc_send_message(DHCP_REQUEST);
00328
00329
00330 dhcpc_t1=5;
00331
00332
00333
00334
00335
00336 dhcpc_t2=10;
00337 }else
00338 if(!dhcpc_t1){
00339 DEBUGOUT("DHCP State=RENEWING; Retransmitting DHCPREQUEST\r\n");
00340
00341 dhcpc_send_message(DHCP_REQUEST);
00342 dhcpc_t1=10;
00343 }
00344 break;
00345 case DHCP_STATE_REBINDING:
00346 if(sec)
00347 dhcpc_t1--;
00348
00349 if(!dhcpc_t1){
00350
00351 dhcpc_t1=5;
00352
00353 dhcpc_t2--;
00354
00355 if(!dhcpc_t2){
00356 DEBUGOUT("DHCP State=REBINDING; Lease time expired; State REBINDING-->INIT\r\n");
00357
00358
00359
00360 dhcpc_state=DHCP_STATE_INIT;
00361 localmachine.localip=0;
00362 }else{
00363 DEBUGOUT("DHCP State=REBINDING; Retransmitting DHCPREQUEST\r\n");
00364
00365 dhcpc_send_message(DHCP_REQUEST);
00366 }
00367 }
00368 break;
00369 default:
00370 break;
00371 }
00372
00373 if(sec){
00374 init_timer(dhcpc_timer_handle,TIMERTIC*1);
00375 }
00376 }
00377
00389 INT8 dhcpc_send_message(UINT8 msg_type)
00390 {
00391
00392 UINT16 index;
00393 UINT8 *buf_ptr;
00394
00395
00396 for(index=UDP_APP_OFFSET;index<NETWORK_TX_BUFFER_SIZE;index++)
00397 net_buf[index]=0;
00398
00399 buf_ptr=net_buf+UDP_APP_OFFSET;
00400
00401
00402
00403 *buf_ptr++=BOOT_REQUEST;
00404 *buf_ptr++=0x01;
00405 *buf_ptr++=0x06;
00406 *buf_ptr++=0x00;
00407
00408
00409 *buf_ptr++=0xAA;
00410 *buf_ptr++=0xBB;
00411 *buf_ptr++=0xCC;
00412 *buf_ptr++=0xDD;
00413
00414
00415 *buf_ptr++=0x00;
00416 *buf_ptr++=0x00;
00417
00418
00419 *buf_ptr++=0x80;
00420 *buf_ptr++=0x00;
00421
00422
00423
00424
00425 if((dhcpc_state==DHCP_STATE_BOUND)
00426 ||(dhcpc_state==DHCP_STATE_RENEWING)
00427 ||(dhcpc_state==DHCP_STATE_REBINDING)){
00428 *buf_ptr++=(UINT8)(localmachine.localip>>24);
00429 *buf_ptr++=(UINT8)(localmachine.localip>>16);
00430 *buf_ptr++=(UINT8)(localmachine.localip>>8);
00431 *buf_ptr++=(UINT8)(localmachine.localip);
00432 }else{
00433 buf_ptr+=4;
00434 }
00435
00436
00437 buf_ptr+=12;
00438
00439
00440 *buf_ptr++=localmachine.localHW[5];
00441 *buf_ptr++=localmachine.localHW[4];
00442 *buf_ptr++=localmachine.localHW[3];
00443 *buf_ptr++=localmachine.localHW[2];
00444 *buf_ptr++=localmachine.localHW[1];
00445 *buf_ptr++=localmachine.localHW[0];
00446 buf_ptr+=10;
00447
00448
00449 buf_ptr+=192;
00450
00451
00452 *buf_ptr++=99;
00453 *buf_ptr++=130;
00454 *buf_ptr++=83;
00455 *buf_ptr++=99;
00456
00457
00458 *buf_ptr++=DHCP_OPT_MSG_TYPE;
00459 *buf_ptr++=1;
00460 *buf_ptr++=msg_type;
00461
00462
00463 switch(msg_type){
00464
00465 case DHCP_REQUEST:
00466 case DHCP_DECLINE:
00467
00468
00469
00470
00471 if((dhcpc_state!=DHCP_STATE_RENEWING)
00472 &&(dhcpc_state!=DHCP_STATE_REBINDING)){
00473 *buf_ptr++=DHCP_OPT_REQUESTED_IP;
00474 *buf_ptr++=4;
00475 *buf_ptr++=(UINT8)(dhcpc_requested_ip>>24);
00476 *buf_ptr++=(UINT8)(dhcpc_requested_ip>>16);
00477 *buf_ptr++=(UINT8)(dhcpc_requested_ip>>8);
00478 *buf_ptr++=(UINT8)(dhcpc_requested_ip);
00479 }
00480
00481
00482
00483
00484 if((dhcpc_state!=DHCP_STATE_INIT_REBOOT)
00485 &&(dhcpc_state!=DHCP_STATE_REBOOTING)
00486 &&(dhcpc_state!=DHCP_STATE_RENEWING)
00487 &&(dhcpc_state!=DHCP_STATE_REBINDING)){
00488 *buf_ptr++=DHCP_OPT_SERV_IDENT;
00489 *buf_ptr++=4;
00490 *buf_ptr++=(UINT8)(dhcpc_server_identifier>>24);
00491 *buf_ptr++=(UINT8)(dhcpc_server_identifier>>16);
00492 *buf_ptr++=(UINT8)(dhcpc_server_identifier>>8);
00493 *buf_ptr++=(UINT8)(dhcpc_server_identifier);
00494 }
00495
00496
00497
00498
00499 if(msg_type==DHCP_DECLINE)
00500 break;
00501
00502 case DHCP_DISCOVER:
00503
00504
00505 *buf_ptr++=DHCP_OPT_PARAM_REQUEST;
00506 *buf_ptr++=7;
00507 *buf_ptr++=DHCP_OPT_SUBNET_MASK;
00508 *buf_ptr++=DHCP_OPT_ROUTER;
00509 *buf_ptr++=DHCP_OPT_DNS_SERVER;
00510 *buf_ptr++=DHCP_OPT_HOST_NAME;
00511 *buf_ptr++=DHCP_OPT_LEASE_TIME;
00512 *buf_ptr++=DHCP_OPT_T1_VALUE;
00513 *buf_ptr++=DHCP_OPT_T2_VALUE;
00514 break;
00515
00516 default:
00517 break;
00518 }
00519
00520
00521 *buf_ptr++=DHCP_OPT_END;
00522 while(buf_ptr<(net_buf+UDP_APP_OFFSET+300))
00523 *buf_ptr++=0x00;
00524
00525
00526
00527
00528
00529 if((dhcpc_state==DHCP_STATE_BOUND)
00530 ||(dhcpc_state==DHCP_STATE_RENEWING))
00531 return udp_send(dhcpc_soc_handle,dhcpc_server_identifier,DHCP_SERVER_PORT,net_buf+UDP_APP_OFFSET,NETWORK_TX_BUFFER_SIZE-UDP_APP_OFFSET,buf_ptr-(net_buf+UDP_APP_OFFSET));
00532 else
00533 return udp_send(dhcpc_soc_handle,IP_BROADCAST_ADDRESS,DHCP_SERVER_PORT,net_buf+UDP_APP_OFFSET,NETWORK_TX_BUFFER_SIZE-UDP_APP_OFFSET,buf_ptr-(net_buf+UDP_APP_OFFSET));
00534
00535 }
00536
00549 UINT32 dhcpc_read_n_bytes(UINT8 n){
00550 UINT32 ret_value=0;
00551
00552 while(n--){
00553 ret_value=(ret_value<<8)|RECEIVE_NETWORK_B();
00554 }
00555 return ret_value;
00556 }
00557
00568 INT32 dhcpc_eventlistener(INT8 cbhandle, UINT8 event, UINT32 ipaddr, UINT16 port, UINT16 buffindex, UINT16 datalen)
00569 {
00570 UINT32 temp;
00571 UINT32 yiaddr;
00572 UINT8 i;
00573 UINT8 msg_type=0;
00574
00575 if(cbhandle!=dhcpc_soc_handle){
00576 DEBUGOUT("DHCP Client: Not my handle!!!!\r\n");
00577 return (-1);
00578 }
00579
00580 switch(event){
00581 case UDP_EVENT_DATA:
00582 DEBUGOUT("DHCP Client: Received data....");
00583
00584 if(datalen<236){
00585 DEBUGOUT("length not OK, dumping packet\r\n");
00586 return (-1);
00587 }
00588
00589
00590 if(RECEIVE_NETWORK_B()!=BOOT_REPLY){
00591 DEBUGOUT("op not BOOT_REPLY, dumping packet\r\n");
00592 return (-1);
00593 }
00594
00595
00596 RECEIVE_NETWORK_B();
00597 RECEIVE_NETWORK_B();
00598 RECEIVE_NETWORK_B();
00599
00600
00601 temp=0;
00602 temp|=((UINT32)RECEIVE_NETWORK_B())<<24;
00603 temp|=((UINT32)RECEIVE_NETWORK_B())<<16;
00604 temp|=((UINT32)RECEIVE_NETWORK_B())<<8;
00605 temp|=RECEIVE_NETWORK_B();
00606 if(temp!=0xAABBCCDD){
00607 DEBUGOUT("xid not OK, dumping packet\r\n");
00608 return (-1);
00609 }
00610
00611
00612 for(i=0;i<12;i++)
00613 yiaddr=(yiaddr<<8)|RECEIVE_NETWORK_B();
00614
00615
00616
00617
00618 for(i=0;i<216;i++)
00619 RECEIVE_NETWORK_B();
00620
00621
00622 temp=0;
00623 temp|=((UINT32)RECEIVE_NETWORK_B())<<24;
00624 temp|=((UINT32)RECEIVE_NETWORK_B())<<16;
00625 temp|=((UINT32)RECEIVE_NETWORK_B())<<8;
00626 temp|=RECEIVE_NETWORK_B();
00627 if(temp!=0x63825363){
00628 DEBUGOUT("magic cookie not OK, dumping packet\r\n");
00629 return (-1);
00630 }
00631 DEBUGOUT("initial check OK, proceeding...\r\n");
00632
00633 switch(dhcpc_state){
00634 case DHCP_STATE_SELECTING:
00635
00636 dhcpc_server_identifier=0;
00637 DEBUGOUT("DHCP Client state=SELECTING; ");
00638
00639
00640
00641
00642
00643 while((i=RECEIVE_NETWORK_B())!=DHCP_OPT_END){
00644
00645 switch(i){
00646 case DHCP_OPT_MSG_TYPE:
00647 RECEIVE_NETWORK_B();
00648 msg_type=RECEIVE_NETWORK_B();
00649 break;
00650 case DHCP_OPT_SERV_IDENT:
00651 RECEIVE_NETWORK_B();
00652
00653 dhcpc_server_identifier|=((UINT32)RECEIVE_NETWORK_B())<<24;
00654 dhcpc_server_identifier|=((UINT32)RECEIVE_NETWORK_B())<<16;
00655 dhcpc_server_identifier|=((UINT32)RECEIVE_NETWORK_B())<<8;
00656 dhcpc_server_identifier|=RECEIVE_NETWORK_B();
00657 break;
00658 case DHCP_OPT_OVERLOAD:
00659
00660 DEBUGOUT("Overloaded DHCP message, can't process...\r\n");
00661 return (-1);
00662 break;
00663 default:
00664
00665 if(i==DHCP_OPT_PAD)
00666 break;
00667 i=RECEIVE_NETWORK_B();
00668 while(i--){
00669 RECEIVE_NETWORK_B();
00670 }
00671 break;
00672 }
00673 }
00674
00675 if((!dhcpc_server_identifier)||(msg_type!=DHCP_OFFER)){
00676 DEBUGOUT(" Not a DHCP offer or no server identifier; Aborting...\r\n");
00677 return(-1);
00678 }
00679
00680 DEBUGOUT(" DHCP offer valid, sending DHCP REQUEST; State SELECTING-->REQUESTING\r\n");
00681
00682 dhcpc_state=DHCP_STATE_REQUESTING;
00683 dhcpc_requested_ip=yiaddr;
00684
00685 dhcpc_send_message(DHCP_REQUEST);
00686
00687 dhcpc_t1=4;
00688 dhcpc_t2=8;
00689 break;
00690
00691 case DHCP_STATE_REQUESTING:
00692
00693
00694 DEBUGOUT("DHCP Client state=REQUESTING; ");
00695
00696
00697
00698
00699
00700 if((dhcpc_server_identifier!=ipaddr)||(yiaddr!=dhcpc_requested_ip)){
00701 DEBUGOUT("Server or requested IP not the same, dumping..\r\n");
00702 return (-1);
00703 }
00704
00705
00706
00707
00708 DEBUGOUT("Received params: ");
00709 while((i=RECEIVE_NETWORK_B())!=DHCP_OPT_END){
00710
00711 switch(i){
00712 case DHCP_OPT_PAD:
00713 break;
00714 case DHCP_OPT_SUBNET_MASK:
00715 temp=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
00716
00717 localmachine.netmask=temp;
00718 DEBUGOUT("Subnet mask;");
00719 break;
00720 case DHCP_OPT_ROUTER:
00721 temp=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
00722
00723 localmachine.defgw=temp;
00724 DEBUGOUT("Gateway IP; ");
00725 break;
00726 case DHCP_OPT_DNS_SERVER:
00727 temp=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
00728 DEBUGOUT("DNS IP;");
00729 break;
00730 case DHCP_OPT_HOST_NAME:
00731
00732 i=RECEIVE_NETWORK_B();
00733 while(i--){
00734
00735 RECEIVE_NETWORK_B();
00736 }
00737 DEBUGOUT("Host name; ");
00738 break;
00739 case DHCP_OPT_LEASE_TIME:
00740 temp=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
00741
00742
00743
00744 dhcpc_t1=0.5*temp;
00745 dhcpc_t2=0.875*temp;
00746 DEBUGOUT("Lease time;");
00747 break;
00748 case DHCP_OPT_OVERLOAD:
00749 DEBUGOUT("Overloaded DHCP message, can't process...\r\n");
00750 return (-1);
00751 break;
00752 case DHCP_OPT_MSG_TYPE:
00753
00754
00755
00756 RECEIVE_NETWORK_B();
00757 if(RECEIVE_NETWORK_B()==DHCP_ACK){
00758 DEBUGOUT("DHCP_ACK Message!; State REQUESTING-->BOUND; ");
00759 dhcpc_state=DHCP_STATE_BOUND;
00760
00761
00762
00763
00764
00765 localmachine.localip=dhcpc_requested_ip;
00766
00767
00768
00769 DEBUGOUT("IP address;");
00770 }else{
00771 DEBUGOUT("NOT DHCPACK message; dumping...\r\n");
00772 return(-1);
00773 }
00774 break;
00775 case DHCP_OPT_T1_VALUE:
00776 DEBUGOUT("T1;");
00777 dhcpc_t1=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
00778 break;
00779 case DHCP_OPT_T2_VALUE:
00780 DEBUGOUT("T2; ");
00781 dhcpc_t2=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
00782 break;
00783 default:
00784 dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
00785 break;
00786 }
00787 }
00788 DEBUGOUT("\r\n");
00789 break;
00790 case DHCP_STATE_RENEWING:
00791 case DHCP_STATE_REBINDING:
00792 case DHCP_STATE_REBOOTING:
00793
00794
00795
00796
00797
00798
00799 DEBUGOUT("DHCP Client state=REQUESTING or REBINDING; ");
00800 while((i=RECEIVE_NETWORK_B())!=DHCP_OPT_END){
00801 switch(i){
00802 case DHCP_OPT_PAD:
00803 break;
00804 case DHCP_OPT_LEASE_TIME:
00805 DEBUGOUT("Lease time; ");
00806 temp=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
00807
00808
00809
00810 dhcpc_t1=0.5*temp;
00811 dhcpc_t2=0.875*temp;
00812 break;
00813 case DHCP_OPT_MSG_TYPE:
00814 RECEIVE_NETWORK_B();
00815 i=RECEIVE_NETWORK_B();
00816 if(i==DHCP_NAK){
00817 DEBUGOUT("DHCP_NAK received; State --> INIT\r\n");
00818 dhcpc_state=DHCP_STATE_INIT;
00819 localmachine.localip=0;
00820 return(-1);
00821 }
00822 if(i==DHCP_ACK){
00823 DEBUGOUT("DHCP_ACK received; State --> BOUND\r\n");
00824 dhcpc_state=DHCP_STATE_BOUND;
00825 }
00826 break;
00827 case DHCP_OPT_T1_VALUE:
00828 DEBUGOUT("T1; ");
00829 dhcpc_t1=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
00830 break;
00831 case DHCP_OPT_T2_VALUE:
00832 DEBUGOUT("T2; ");
00833 dhcpc_t2=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
00834 break;
00835 default:
00836 dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
00837 break;
00838 }
00839 }
00840 break;
00841 default:
00842
00843 break;
00844 }
00845 break;
00846 default:
00847
00848 DEBUGOUT("DHCP Client: Unknown UDP event :-( \r\n");
00849 break;
00850 }
00851 return 1;
00852
00853 }