Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages   Examples  

/opentcp/bootp/bootp.c

Go to the documentation of this file.
00001 /*
00002  *Copyright (c) 2000-2002 Viola Systems Ltd.
00003  *All rights reserved.
00004  *
00005  *Redistribution and use in source and binary forms, with or without 
00006  *modification, are permitted provided that the following conditions 
00007  *are met:
00008  *
00009  *1. Redistributions of source code must retain the above copyright 
00010  *notice, this list of conditions and the following disclaimer.
00011  *
00012  *2. Redistributions in binary form must reproduce the above copyright 
00013  *notice, this list of conditions and the following disclaimer in the 
00014  *documentation and/or other materials provided with the distribution.
00015  *
00016  *3. The end-user documentation included with the redistribution, if 
00017  *any, must include the following acknowledgment:
00018  *      "This product includes software developed by Viola 
00019  *      Systems (http://www.violasystems.com/)."
00020  *
00021  *Alternately, this acknowledgment may appear in the software itself, 
00022  *if and wherever such third-party acknowledgments normally appear.
00023  *
00024  *4. The names "OpenTCP" and "Viola Systems" must not be used to 
00025  *endorse or promote products derived from this software without prior 
00026  *written permission. For written permission, please contact 
00027  *opentcp@opentcp.org.
00028  *
00029  *5. Products derived from this software may not be called "OpenTCP", 
00030  *nor may "OpenTCP" appear in their name, without prior written 
00031  *permission of the Viola Systems Ltd.
00032  *
00033  *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 
00034  *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00035  *MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
00036  *IN NO EVENT SHALL VIOLA SYSTEMS LTD. OR ITS CONTRIBUTORS BE LIABLE 
00037  *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00038  *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
00039  *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
00040  *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00041  *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00042  *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
00043  *EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00044  *====================================================================
00045  *
00046  *OpenTCP is the unified open source TCP/IP stack available on a series 
00047  *of 8/16-bit microcontrollers, please see <http://www.opentcp.org>.
00048  *
00049  *For more information on how to network-enable your devices, or how to 
00050  *obtain commercial technical support for OpenTCP, please see 
00051  *<http://www.violasystems.com/>.
00052  */
00053  
00070 #include<inet/datatypes.h>
00071 #include<inet/system.h>
00072 #include<inet/timers.h>
00073 #include<inet/tcp_ip.h>
00074 #include<inet/bootp/bootp.h>
00075 #include<inet/globalvariables.h>
00076 
00077 UINT8 bootp_app_init = 0; 
00085 struct
00086 {
00087         UINT8   state;  
00088         UINT8   mode;
00089         INT8    sochandle;      
00090         UINT16  tmrhandle;
00091         UINT16  bootsecs;
00092 
00093 } bootp;
00094 
00095 
00108 INT8 bootpc_init (UINT8 mode)
00109 {
00110         /* Already initialized? */
00111         
00112         if(bootp_app_init)
00113                 return(1);
00114         
00115         /* Get socket handle            */
00116         
00117         bootp.sochandle = udp_getsocket(0, bootpc_eventlistener, UDP_OPT_SEND_CS | UDP_OPT_CHECK_CS);
00118         
00119         if(bootp.sochandle < 0)
00120                 return(-1);
00121         
00122         /* Put it to listening mode     */
00123                 
00124         if( udp_open(bootp.sochandle, BOOTP_CLIENTPORT) < 0 )
00125                 return(-1);
00126         
00127         /* Get timer handle                     */
00128         
00129         bootp.tmrhandle = get_timer();
00130         bootp.bootsecs = 0;
00131         bootp.mode = mode;
00132         
00133         bootp.state = BOOTPC_STATE_DISABLED;
00134         
00135         
00136         bootp_app_init = 1;
00137         
00138         return(1);              
00139         
00140 }
00141 
00150 void bootpc_stop (void){
00151         if(bootp_app_init == 0)
00152                 return;
00153 
00154         bootp.state = BOOTPC_STATE_DISABLED;
00155 }
00156 
00165 INT8 bootpc_enable (void){
00166         if(bootp_app_init == 0)
00167                 return(-1);
00168         
00169         bootp.state = BOOTPC_STATE_ENABLED;
00170         
00171         return(1);      
00172 
00173 }
00174 
00175 
00183 void bootpc_run (void)
00184 {
00185         INT16 i;
00186         UINT8 buf[4];
00187 
00188         /* State machine        */
00189         
00190         if(bootp_app_init == 0)
00191                 return;
00192         
00193         switch(bootp.state) {
00194                 case BOOTPC_STATE_ENABLED:
00195                 
00196                         /* Check the IP address of the device and start BOOTP procedure for getting     */
00197                         /* one if zero or 255.255.255.255                                                                                       */
00198                         
00199                         if( (localmachine.localip == 0) || (localmachine.localip == 0xFFFFFFFF) ) {
00200                                 /* We need to start BOOTP request procedure     */
00201                                 /* Firstly wait random time                                     */
00202                                 
00203                                 localmachine.localip = 0;
00204                                 localmachine.defgw = 0;
00205                                 localmachine.netmask = 0;                       
00206 
00207                                 init_timer(bootp.tmrhandle, ((UINT32)(localmachine.localHW[0]) << 2) + localmachine.localHW[1]);
00208                                 bootp.state = BOOTPC_STATE_REQUEST_NEEDED;
00209                         }
00210                 
00211                         return;
00212                         
00213                 case BOOTPC_STATE_REQUEST_NEEDED:
00214                 
00215                         if( check_timer(bootp.tmrhandle) != 0 )
00216                                 return;
00217                         
00218                         /* Send request */
00219                         
00220                         if(localmachine.localip != 0){
00221                                 bootp.state = BOOTPC_STATE_ENABLED;
00222                                 return;
00223                         
00224                         }
00225                         
00226                         i = 0;
00227                         
00228                         net_buf[UDP_APP_OFFSET + i++] = 0x01;
00229                         net_buf[UDP_APP_OFFSET + i++] = 0x01;
00230                         net_buf[UDP_APP_OFFSET + i++] = 0x06;
00231                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00232                         net_buf[UDP_APP_OFFSET + i++] = 0xCA;
00233                         net_buf[UDP_APP_OFFSET + i++] = 0x03;
00234                         net_buf[UDP_APP_OFFSET + i++] = 0x32;
00235                         net_buf[UDP_APP_OFFSET + i++] = 0xF1;
00236                         
00237                         net_buf[UDP_APP_OFFSET + i++] = (UINT8)(bootp.bootsecs >> 8);
00238                         net_buf[UDP_APP_OFFSET + i++] = (UINT8)bootp.bootsecs;
00239                         
00240                         net_buf[UDP_APP_OFFSET + i++] = 0x80;
00241                         
00242                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00243                         net_buf[UDP_APP_OFFSET + i++] = 0x00;   
00244                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00245                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00246                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00247                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00248                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00249                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00250                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00251                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00252                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00253                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00254                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00255                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00256                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00257                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00258                         net_buf[UDP_APP_OFFSET + i++] = 0x00;
00259                         
00260                         net_buf[UDP_APP_OFFSET + i++] = localmachine.localHW[5];        
00261                         net_buf[UDP_APP_OFFSET + i++] = localmachine.localHW[4];
00262                         net_buf[UDP_APP_OFFSET + i++] = localmachine.localHW[3];
00263                         net_buf[UDP_APP_OFFSET + i++] = localmachine.localHW[2];
00264                         net_buf[UDP_APP_OFFSET + i++] = localmachine.localHW[1];
00265                         net_buf[UDP_APP_OFFSET + i++] = localmachine.localHW[0];
00266                         
00267                         net_buf[UDP_APP_OFFSET + i++] = 99;
00268                         net_buf[UDP_APP_OFFSET + i++] = 130;    
00269                         net_buf[UDP_APP_OFFSET + i++] = 83;
00270                         net_buf[UDP_APP_OFFSET + i++] = 99;
00271                         net_buf[UDP_APP_OFFSET + i++] = 255;
00272                         
00273                         for(i;i<300;i++)
00274                                 net_buf[UDP_APP_OFFSET + i] = 0;
00275                         
00276                         /* Send it      */
00277                         
00278                         udp_send(bootp.sochandle, IP_BROADCAST_ADDRESS, BOOTP_SERVERPORT, &net_buf[UDP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - UDP_APP_OFFSET, 300);
00279                         
00280                         init_timer(bootp.tmrhandle, BOOTP_RETRY_TOUT*TIMERTIC);
00281                         
00282                         bootp.bootsecs += BOOTP_RETRY_TOUT*TIMERTIC;
00283                         
00284                         bootp.state = BOOTPC_STATE_WAITING_REPLY;       
00285                                         
00286                         return;
00287                         
00288                 case BOOTPC_STATE_WAITING_REPLY:
00289                 
00290                         /* Wait untill timeout elapsed and try again    */
00291                         
00292                         if( check_timer(bootp.tmrhandle) != 0 )
00293                                 return;
00294                         
00295                         bootp.state = BOOTPC_STATE_REQUEST_NEEDED;
00296                                 
00297                         return;                 
00298                                 
00299                 case BOOTPC_STATE_REPLY_GET:
00300                         /* parameters configured. Inspect state of bootp.mode
00301                          * and do something (if needed). Also turn BOOTP client
00302                          * on/off.
00303                          */
00304                         
00305                         return;
00306                         
00307         
00308                 default:
00309                 
00310                         return;
00311         }
00312 
00313 }
00314 
00335 INT32 bootpc_eventlistener (INT8 cbhandle, UINT8 event, UINT32 remip, UINT16 remport, UINT16 bufindex, UINT16 dlen) {
00336         INT16 i,j,k;
00337         UINT32 ip = 0;
00338         UINT32 nm = 0;
00339         UINT32 dgw = 0;
00340         UINT8 ch;
00341         
00342 
00343         /* This function is called by UDP stack to inform about events  */
00344         
00345         if(bootp_app_init == 0)
00346                 return(-1);
00347         
00348         if( cbhandle != bootp.sochandle)                /* Not our handle       */
00349                 return(-1);
00350                         
00351         /* The only event is data       */
00352         
00353         if(bootp.state != BOOTPC_STATE_WAITING_REPLY)
00354                 return(-1);     
00355         
00356         /* Process reply        */
00357 
00358         NETWORK_RECEIVE_INITIALIZE(bufindex);
00359                                 
00360         if(dlen < 300)
00361                 return(-1);
00362         
00363         if(     RECEIVE_NETWORK_B() != BOOTP_REPLY)
00364                 return(-1);
00365                 
00366         if(     RECEIVE_NETWORK_B() != BOOTP_HTYPE_ETHERNET)
00367                 return(-1);
00368         
00369         if(     RECEIVE_NETWORK_B() != BOOTP_HWLEN_ETHERNET)
00370                 return(-1);
00371         
00372         RECEIVE_NETWORK_B();            /* Skip hops    */
00373         
00374         /* Check transaction ID */
00375                 
00376         if(     RECEIVE_NETWORK_B() != 0xCA)
00377                 return(-1);             
00378                 
00379         if(     RECEIVE_NETWORK_B() != 0x03)
00380                 return(-1);     
00381 
00382         if(     RECEIVE_NETWORK_B() != 0x32)
00383                 return(-1);                                                     
00384 
00385         if(     RECEIVE_NETWORK_B() != 0xF1)
00386                 return(-1);             
00387         
00388         /* Skip elapsed, unused, client address */
00389         
00390         for(i=0; i<8; i++)
00391                 RECEIVE_NETWORK_B();
00392         
00393         /* Get IP       */
00394         
00395         ip = RECEIVE_NETWORK_B();
00396         ip <<= 8;
00397         ip |= RECEIVE_NETWORK_B();
00398         ip <<= 8;
00399         ip |= RECEIVE_NETWORK_B();              
00400         ip <<= 8;
00401         ip |= RECEIVE_NETWORK_B();
00402         
00403         /* Skip server ip & bootp router address        */
00404         
00405         for(i=0; i<8; i++)
00406                 RECEIVE_NETWORK_B();
00407                 
00408         /* Check MAC                                                            */
00409         
00410         if(     RECEIVE_NETWORK_B() != localmachine.localHW[5])
00411                 return(-1);     
00412                 
00413         if(     RECEIVE_NETWORK_B() != localmachine.localHW[4])
00414                 return(-1);
00415 
00416         if(     RECEIVE_NETWORK_B() != localmachine.localHW[3])
00417                 return(-1);                                             
00418 
00419         if(     RECEIVE_NETWORK_B() != localmachine.localHW[2])
00420                 return(-1);     
00421         
00422         if(     RECEIVE_NETWORK_B() != localmachine.localHW[1])
00423                 return(-1);
00424 
00425         if(     RECEIVE_NETWORK_B() != localmachine.localHW[0])
00426                 return(-1);
00427                 
00428         RECEIVE_NETWORK_B();
00429         RECEIVE_NETWORK_B();
00430         
00431         for(i=0; i<200; i++)
00432                 RECEIVE_NETWORK_B();
00433         
00434         /* Check options        */
00435         
00436         dlen -= 236;
00437         
00438         i = 0;
00439         
00440         while(i<dlen) {
00441                 ch = RECEIVE_NETWORK_B();
00442                 i++;
00443                 
00444                 if( (ch != BOOTP_OPTION_SUBNETMASK) && (ch != BOOTP_OPTION_DEFGW) )     {
00445                         /* Not supported option, skip it        */
00446                         
00447                         j = RECEIVE_NETWORK_B();
00448                         i++;
00449                 
00450                         if(j >= 2) {
00451                                 j -= 2;
00452         
00453                                 while(j--) {
00454                                         RECEIVE_NETWORK_B();
00455                                         i++;                    
00456                                 }       
00457                         }
00458                                         
00459                         continue;                       
00460                         
00461                 } 
00462                 
00463                 if( ch == BOOTP_OPTION_SUBNETMASK) {
00464                         RECEIVE_NETWORK_B();                    /* Skip totlen  */
00465                         nm = RECEIVE_NETWORK_B();
00466                         nm <<= 8;
00467                         nm |= RECEIVE_NETWORK_B();
00468                         nm <<= 8;
00469                         nm |= RECEIVE_NETWORK_B();              
00470                         nm <<= 8;
00471                         nm |= RECEIVE_NETWORK_B();
00472                         
00473                         i += 5;
00474                         
00475                 }
00476                 
00477                 if( ch == BOOTP_OPTION_DEFGW) {
00478                         j = RECEIVE_NETWORK_B();                /* Get totlen   */                      
00479                         dgw = RECEIVE_NETWORK_B();
00480                         dgw <<= 8;
00481                         dgw |= RECEIVE_NETWORK_B();
00482                         dgw <<= 8;
00483                         dgw |= RECEIVE_NETWORK_B();             
00484                         dgw <<= 8;
00485                         dgw |= RECEIVE_NETWORK_B();
00486                         
00487                         i += 5;
00488                         
00489                         /* Skip others  */
00490                         
00491                         if( j>5 ) {
00492                                 j -= 5;
00493                                 
00494                                 while(j--) {
00495                                         RECEIVE_NETWORK_B();
00496                                         i++;                    
00497                                 }                               
00498                                 
00499                         }
00500                         
00501                 }               
00502                 
00503         }
00504         
00505         /* Store parameters             */
00506         
00507         localmachine.localip = ip;
00508         localmachine.defgw = dgw;
00509         localmachine.netmask = nm;      
00510         
00511         /* Change state */
00512         
00513         bootp.state = BOOTPC_STATE_REPLY_GET;
00514         
00515         return(1);
00516         
00517 }
00518 
00519 
00520 
00521 
00522 

Generated on Sat Jan 25 17:13:14 2003 for OpenTCP by doxygen1.2.18