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<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 Sun Aug 3 20:32:59 2003 for OpenTCP by doxygen1.2.18