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

/opentcp/arp.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 
00073 #include <inet/debug.h>
00074 #include <inet/ethernet.h>
00075 #include <inet/arp.h>
00076 #include <inet/timers.h>
00077 #include <inet/system.h>
00078 #include <inet/globalvariables.h>
00079 
00089 struct arp_entry        arp_table[ARP_TSIZE]; 
00090 
00097 UINT8 arp_timer; 
00098 
00119 UINT8 process_arp (struct ethernet_frame* frame) {
00120         
00121         UINT8 temp;             
00122         
00123         /* Check if ARP packet*/
00124         
00125         if( frame->protocol == ARP_ETHCODE ) {
00126                 /* Yep, ARP */
00127                 
00128                 NETWORK_RECEIVE_INITIALIZE(frame->buf_index);
00129                 
00130                 /* Is it long enough?   */
00131                 
00132                 if( frame->frame_size < (2*MAXHWALEN + 2*MAXPRALEN + 2 + 6) ) {
00133                         /* Somehow corrupted ARP packet */
00134                         ARP_DEBUGOUT("Corrupted ARP packet\n\r");
00135                         NETWORK_RECEIVE_END();
00136                         return(TRUE);
00137                 }
00138                          
00139                 
00140                 /* Ignore next 6 bytes: <HW type>, <Protocol type> */
00141                 /* <HW address len> and <Protocol address len>     */
00142                 
00143                 for(temp=0; temp<6; temp++)
00144                         RECEIVE_NETWORK_B();
00145                 
00146                 ARP_DEBUGOUT("Incoming ARP..\n\r");
00147                 
00148                 /* Check if request or response */
00149                 
00150                 if( RECEIVE_NETWORK_B() == 0x00) {
00151                 
00152                         temp = RECEIVE_NETWORK_B();     /* get opcode */
00153                 
00154                         if( temp == ARP_REQUEST ) {
00155                                 ARP_DEBUGOUT(" ARP REQUEST Received..\n\r");
00156                                 arp_send_response();
00157                         } else if( temp == ARP_REPLY ) {
00158                                 ARP_DEBUGOUT("ARP Response Received..\n\r");
00159                                 arp_get_response();     
00160                         }
00161                         
00162                 /* Wasn't request or response or all done, dump it */
00163                 
00164                 }
00165                 
00166                 NETWORK_RECEIVE_END();
00167                 return(TRUE);
00168                 
00169         }
00170         
00171         /* Wasn't ARP, don't touch the packet */
00172         
00173         return(FALSE);                                                          
00174 }
00175 
00191 void arp_send_response(void)
00192 {
00193         struct arp_entry *qstruct;
00194         UINT8 rem_hwadr[MAXHWALEN];
00195         LWORD rem_ip;
00196         LWORD ltemp;
00197         INT8 i;
00198         BYTE j;
00199 
00200         /* Record Sender's HW address           */
00201         
00202         for( i=MAXHWALEN-1; i >= 0; i-- )
00203                 rem_hwadr[i] = RECEIVE_NETWORK_B();             
00204         
00205         /* Read Sender's IP Address     */
00206         
00207         for( i=0; i<MAXPRALEN; i++) {
00208                 rem_ip <<= 8;
00209                 rem_ip |= RECEIVE_NETWORK_B();
00210         } 
00211         
00212         
00213         /* Skip Target HW address               */
00214         
00215         RECEIVE_NETWORK_B();
00216         RECEIVE_NETWORK_B();
00217         RECEIVE_NETWORK_B();
00218         RECEIVE_NETWORK_B();
00219         RECEIVE_NETWORK_B();
00220         RECEIVE_NETWORK_B();    
00221         
00222         /* Is The Packet For Us?        */
00223         
00224         for( i=0; i<MAXPRALEN; i++) {
00225                 ltemp <<= 8;
00226                 ltemp |= RECEIVE_NETWORK_B();
00227         }
00228                 
00229         
00230         if( ltemp != localmachine.localip ) 
00231                 return;                                                         /* No   */
00232 
00233         ARP_DEBUGOUT("Preparing for ARP Reply\n\r");
00234         
00235         /* OK. Now send reply           */
00236         
00237         NETWORK_SEND_INITIALIZE(ARP_BUFFER);
00238         
00239         /* Add datalink (Ethernet addresses) information        */
00240         
00241         for( i=0; i<MAXHWALEN; i++)     {
00242                 send_frame.destination[i] = rem_hwadr[i];
00243                 send_frame.source[i] = localmachine.localHW[i];
00244         }
00245         
00246         send_frame.protocol = PROTOCOL_ARP;
00247         
00248         NETWORK_ADD_DATALINK(&send_frame);
00249         
00250         /* PUT ARP Data */
00251         
00252         SEND_NETWORK_B( (BYTE)(AR_HARDWARE>>8) );                               /* Hardware Type        */
00253         SEND_NETWORK_B( (BYTE)AR_HARDWARE );
00254         SEND_NETWORK_B(0x08);                                                                   /* Protocol Type        */
00255         SEND_NETWORK_B(0x00);
00256         SEND_NETWORK_B(MAXHWALEN);                                                              /* HW Adr Len           */
00257         SEND_NETWORK_B(MAXPRALEN);                                                              /* Protocol Adr. Len*/
00258         SEND_NETWORK_B( 0x00 );                                                                 /* ARP Opcode           */      
00259         SEND_NETWORK_B( 0x02 );                                 
00260         SEND_NETWORK_B((UINT8)(localmachine.localHW[5]));               /* Address fields       */
00261         SEND_NETWORK_B((UINT8)(localmachine.localHW[4]));
00262         SEND_NETWORK_B((UINT8)(localmachine.localHW[3]));
00263         SEND_NETWORK_B((UINT8)(localmachine.localHW[2]));
00264         SEND_NETWORK_B((UINT8)(localmachine.localHW[1]));
00265         SEND_NETWORK_B((UINT8)(localmachine.localHW[0]));
00266         SEND_NETWORK_B((UINT8)(localmachine.localip>>24));
00267         SEND_NETWORK_B((UINT8)(localmachine.localip>>16));
00268         SEND_NETWORK_B((UINT8)(localmachine.localip>>8));
00269         SEND_NETWORK_B((UINT8)(localmachine.localip));
00270         SEND_NETWORK_B((UINT8)rem_hwadr[5]);
00271         SEND_NETWORK_B((UINT8)rem_hwadr[4]);
00272         SEND_NETWORK_B((UINT8)rem_hwadr[3]);
00273         SEND_NETWORK_B((UINT8)rem_hwadr[2]);
00274         SEND_NETWORK_B((UINT8)rem_hwadr[1]);
00275         SEND_NETWORK_B((UINT8)rem_hwadr[0]);                                            
00276         SEND_NETWORK_B((UINT8)(rem_ip>>24));
00277         SEND_NETWORK_B((UINT8)(rem_ip>>16));
00278         SEND_NETWORK_B((UINT8)(rem_ip>>8));
00279         SEND_NETWORK_B((UINT8)rem_ip);
00280         
00281         NETWORK_COMPLETE_SEND(0x0040);          /* Send the packet      */
00282         
00283         ARP_DEBUGOUT("ARP Reply Sent..\n\r");
00284         
00285         /* Add the Sender's info to cache because we can        */
00286         
00287         arp_add(rem_ip, &send_frame.destination[0], ARP_TEMP_IP);
00288         
00289         return;
00290                 
00291 }
00292 
00293 
00310 void arp_get_response(void)
00311 {
00312         struct arp_entry *qstruct;
00313         UINT8 rem_hwadr[MAXHWALEN];
00314         UINT32  rem_ip;
00315         UINT32  ltemp;
00316         INT8 i;
00317         UINT8 j;
00318         
00319         /* Read Sender's HW address     */
00320         
00321         for( i=MAXHWALEN-1; i >= 0; i-- )
00322                 rem_hwadr[i] = RECEIVE_NETWORK_B();
00323                 
00324         /* Read Sender's IP Address     */
00325         
00326         for( i=0; i<MAXPRALEN; i++) {
00327                 rem_ip <<= 8;
00328                 rem_ip |= RECEIVE_NETWORK_B();
00329         }
00330         
00331         
00332         /* Skip our HW Address  */
00333         
00334         for(i=0; i<MAXHWALEN; i++)
00335                 RECEIVE_NETWORK_B();
00336         
00337         
00338         /* Is The Packet For Us?        */
00339         
00340         for( i=0; i<MAXPRALEN; i++)     {
00341                 ltemp <<= 8;
00342                 ltemp |= RECEIVE_NETWORK_B();
00343         }
00344                 
00345         
00346         if( ltemp != localmachine.localip ) 
00347                 return;                                                         /* No   */
00348 
00349         ARP_DEBUGOUT("Now entering to process ARP Reply..\n\r");
00350         
00351         /* Are we waiting for that reply?       */
00352         
00353         for( i=1; i<ARP_TSIZE; i++ ) {
00354                 qstruct = &arp_table[i];
00355                 
00356                 if( qstruct->state == ARP_FREE )
00357                         continue;
00358                 
00359                 if( qstruct->state == ARP_RESERVED )
00360                         continue;                               
00361                 
00362                 if( rem_ip == qstruct->pradr ) {
00363                         /* We are caching that IP, refresh it   */
00364                         
00365                         ARP_DEBUGOUT("Refreshing ARP cache from Reply..\n\r");
00366                         
00367                         for( j=0; j<MAXHWALEN; j++ )            
00368                                 qstruct->hwadr[j] = rem_hwadr[j];
00369                                 
00370                         qstruct->ttl = ARP_TIMEOUT;
00371                         qstruct->retries = ARP_MAXRETRY;                                /* No need for Retry    */
00372                         qstruct->state = ARP_RESOLVED;
00373                 
00374                         /* Done */
00375                         
00376                         break;
00377                 }       
00378         
00379         }
00380 
00381 }
00382 
00393 void arp_send_req (UINT8 entry)
00394 {
00395 
00396         struct arp_entry *qstruct;
00397         UINT8 i;
00398         
00399         qstruct = &arp_table[entry];
00400         
00401         NETWORK_SEND_INITIALIZE(ARP_BUFFER);
00402         
00403         /* Add datalink (Ethernet addresses) information        */
00404         
00405         for( i=0; i<MAXHWALEN; i++) {
00406                 send_frame.destination[i] = 0xFF;
00407                 send_frame.source[i] = localmachine.localHW[i];
00408         }
00409         
00410         send_frame.protocol = PROTOCOL_ARP;
00411         
00412         NETWORK_ADD_DATALINK(&send_frame);
00413         
00414         /* PUT ARP Data */
00415 
00416         SEND_NETWORK_B( (BYTE) (AR_HARDWARE>>8) );                      /* Hardware Type        */
00417         SEND_NETWORK_B( (BYTE) AR_HARDWARE );
00418         SEND_NETWORK_B(0x08);                                                           /* Protocol Type        */
00419         SEND_NETWORK_B(0x00);
00420         SEND_NETWORK_B(MAXHWALEN);                                                      /* HW Adr Len           */
00421         SEND_NETWORK_B(MAXPRALEN);                                                      /* Protocol Adr. Len*/
00422         SEND_NETWORK_B( (BYTE)(ARP_REQUEST>>8));                        /* ARP Opcode           */
00423         SEND_NETWORK_B( (BYTE) ARP_REQUEST );
00424         SEND_NETWORK_B((UINT8)localmachine.localHW[5]);         /* Address fields       */
00425         SEND_NETWORK_B((UINT8)localmachine.localHW[4]);
00426         SEND_NETWORK_B((UINT8)localmachine.localHW[3]);
00427         SEND_NETWORK_B((UINT8)localmachine.localHW[2]);
00428         SEND_NETWORK_B((UINT8)localmachine.localHW[1]);
00429         SEND_NETWORK_B((UINT8)localmachine.localHW[0]);
00430         SEND_NETWORK_B((UINT8)(localmachine.localip>>24));
00431         SEND_NETWORK_B((UINT8)(localmachine.localip>>16));
00432         SEND_NETWORK_B((UINT8)(localmachine.localip>>8));
00433         SEND_NETWORK_B((UINT8)localmachine.localip);
00434         SEND_NETWORK_B((UINT8)0xFF);
00435         SEND_NETWORK_B((UINT8)0xFF);
00436         SEND_NETWORK_B((UINT8)0xFF);
00437         SEND_NETWORK_B((UINT8)0xFF);
00438         SEND_NETWORK_B((UINT8)0xFF);
00439         SEND_NETWORK_B((UINT8)0xFF);                                            
00440         SEND_NETWORK_B((UINT8)(qstruct->pradr>>24));
00441         SEND_NETWORK_B((UINT8)(qstruct->pradr>>16));
00442         SEND_NETWORK_B((UINT8)(qstruct->pradr>>8));
00443         SEND_NETWORK_B((UINT8)qstruct->pradr);
00444         
00445         
00446         /* Packet assembled now, just send it ... */
00447         
00448         NETWORK_COMPLETE_SEND(0x0040);                                          /* Min packet size      */
00449  
00450         ARP_DEBUGOUT("ARP Request Sent\n\r");
00451         
00452 }
00453 
00454 
00469 INT8 arp_alloc (UINT8 type)
00470 {
00471         struct arp_entry *qstruct;
00472         char i;
00473         static BYTE aenext = 0;         /* Cache Manager        */
00474         
00475         
00476         for( i=0; i<ARP_TSIZE; i++ ) {
00477         
00478                 if( arp_table[aenext].state == ARP_FREE ) {
00479                         i = aenext;
00480                         break;
00481                 }
00482                 
00483                 /* Move to next entry */
00484                         
00485                 aenext = (aenext + 1);
00486                 if( aenext >= ARP_TSIZE )
00487                         aenext = 1;
00488                 
00489         }
00490 #if     DEBUG == 1
00491         ARP_DEBUGOUT("Found an entry - ");      
00492                         if(aenext==0){
00493                                 ARP_DEBUGOUT("Allocated Entry 0\n\r");
00494                         }
00495                         if(aenext==1){
00496                                 ARP_DEBUGOUT("Allocated Entry 1\n\r");
00497                         }
00498                         
00499                         if(aenext==2){
00500                                 ARP_DEBUGOUT("Allocated Entry 2\n\r");  
00501                         }
00502                         
00503 #endif
00504 
00505         qstruct = &arp_table[aenext];
00506         
00507         aenext = (aenext + 1);  
00508         if( aenext >= ARP_TSIZE )
00509                 aenext = 1;
00510         
00511         /* Set ARP initial parameters   */
00512         
00513         qstruct->state = ARP_RESERVED;
00514         qstruct->type = type;
00515         
00516         return(i);
00517 
00518 }
00536 INT8 arp_add (UINT32 pra, UINT8* hwadr, UINT8 type)
00537 {
00538         struct arp_entry *qstruct;
00539         UINT8 i;
00540         UINT8 j;
00541 
00542         for( i=0; i<ARP_TSIZE; i++ ) {
00543                 qstruct = &arp_table[i];
00544                 
00545                 if( qstruct->state == ARP_FREE )
00546                         continue;
00547                         
00548                 if( qstruct->pradr == pra) {
00549                         /* The address is in cache, refresh it   */
00550                         
00551                         ARP_DEBUGOUT(" Refreshing Existing ARP Entry..\n\r");
00552                 
00553                         for( j=0; j<MAXHWALEN; j++ )            
00554                                 qstruct->hwadr[j] = *hwadr++;
00555                                 
00556                         qstruct->ttl = ARP_TIMEOUT;
00557                         qstruct->retries = ARP_MAXRETRY;
00558                         qstruct->state = ARP_RESOLVED;
00559         
00560                         /* All OK       */
00561                 
00562                         return (0);     
00563                 }
00564         
00565         }
00566         
00567         if(is_subnet(pra,&localmachine) == FALSE){
00568                 return (-1);
00569         }
00570         
00571         if( localmachine.defgw == pra ) {
00572                 if(localmachine.defgw != 0) {
00573                         type = ARP_FIXED_IP;
00574                 }
00575         }
00576 
00577         
00578         /* Address was'nt on cache. Need to allocate new one    */
00579         
00580         ARP_DEBUGOUT("Allocating New ARP Entry..\n\r");
00581         
00582         i = arp_alloc(type);
00583         
00584         if( i < 0 )                             /* No Entries Left?     */
00585                 return(-1);
00586                         
00587         /* Fill the fields              */
00588                 
00589         qstruct = &arp_table[i];
00590                 
00591         qstruct->pradr = pra;                                                                           /* Fill IP                              */
00592         
00593         for(i=0; i<MAXHWALEN; i++)
00594                 qstruct->hwadr[i] = *hwadr++;                                                   /* Fill HW address              */
00595 
00596         qstruct->retries = ARP_MAXRETRY;
00597         qstruct->ttl = ARP_TIMEOUT;
00598         qstruct->state = ARP_RESOLVED;                          
00599         
00600         ARP_DEBUGOUT("ARP Entry Created!..\n\r");
00601 
00602         return(1);
00603 
00604 } 
00622 struct arp_entry* arp_find (LWORD pra, struct netif *machine, UINT8 type)
00623 {
00624         struct arp_entry *qstruct;
00625         char i;
00626         
00627         ARP_DEBUGOUT("Trying to find MAC address from ARP Cache\n\r");
00628         
00629         /* Is the address in the cache  */
00630         
00631         for( i=0; i<ARP_TSIZE; i++ ) {
00632                 qstruct = &arp_table[i];
00633                 
00634                 if( qstruct->state == ARP_FREE )
00635                         continue;
00636                 if( qstruct->pradr == pra) {
00637                         /* The address is in cache, is it valid? */
00638                         
00639                         ARP_DEBUGOUT("Address In Cache\n\r");
00640                         
00641                         if( qstruct->state < ARP_RESOLVED ) {
00642                                 ARP_DEBUGOUT("Address in cache but unresolved :(\n\r");
00643                                 return(0);
00644                         }
00645                         /* All OK       */
00646                 
00647                         return(qstruct);        
00648                 }
00649         
00650         }
00651         
00652         /* The address wasn't on the cache. Is it in our Subnet?        */
00653         
00654         if( is_subnet(pra, machine) ) {
00655                 /* Yep, we need to send ARP REQUEST     */
00656                 
00657                 ARP_DEBUGOUT("Need to send ARP Request to local network..\n\r");
00658                 
00659                 i = arp_alloc(type);
00660                 
00661                 if( i < 0 )                             /* No Entries Left?     */
00662                         return(0);
00663                         
00664                 /* Send Request after filling the fields        */
00665                 
00666                 qstruct = &arp_table[i];
00667                 
00668                 qstruct->pradr = pra;                                           /* Fill IP                              */
00669                 qstruct->hwadr[0] = 0xFF;                                       /* Fill Broadcast IP    */
00670                 qstruct->hwadr[1] = 0xFF;
00671                 qstruct->hwadr[2] = 0xFF;
00672                 qstruct->hwadr[3] = 0xFF;
00673                 qstruct->hwadr[4] = 0xFF;
00674                 qstruct->hwadr[5] = 0xFF;
00675                 qstruct->retries = ARP_MAXRETRY;
00676                 qstruct->ttl = ARP_RESEND;
00677                 arp_send_req( i );
00678                 qstruct->state = ARP_PENDING;                           /* Waiting for Reply    */
00679                 
00680                 return(0);
00681         
00682         } 
00683         
00684         /* Check for Broadcast                                                                                                  */
00685         
00686         if(machine->defgw == 0)                         /* It's not specified   */
00687                 return(0);
00688         
00689         /* The Address belongst to the outern world, need to use MAC of                 */
00690         /* Default Gateway                                                                                                              */
00691         
00692 
00693         ARP_DEBUGOUT("Need to use MAC of Default GW\n\r");
00694         
00695         for( i=0; i<ARP_TSIZE; i++ ) {
00696                 qstruct = &arp_table[i];
00697                 
00698                 if( qstruct->state == ARP_FREE )
00699                         continue;
00700                         
00701                 if( qstruct->pradr == machine->defgw ) {
00702                         /* The address is in cache, is it valid? */
00703                  
00704                         
00705                         if( qstruct->state < ARP_RESOLVED ) {
00706                                 ARP_DEBUGOUT("The Address of Def. GW is not Solved!\n\r");
00707                                 return(0);
00708                         }
00709                 
00710                         /* All OK       */
00711                         
00712                         ARP_DEBUGOUT(" >> Default Gateway MAC found!\n\r");
00713                 
00714                         return(qstruct);
00715                                 
00716                 }
00717         
00718         }
00719         
00720         ARP_DEBUGOUT("Need to send ARP Request to default gateway..\n\r");
00721                 
00722         i = arp_alloc(ARP_FIXED_IP);
00723                 
00724         if( i < 0 )                             /* No Entries Left?     */
00725                 return(0);
00726                         
00727         /* Send Request after filling the fields        */
00728                 
00729         qstruct = &arp_table[i];
00730                 
00731         qstruct->pradr = machine->defgw;                                                /* Fill IP                              */
00732         qstruct->hwadr[0] = 0xFF;                                       /* Fill Broadcast IP    */
00733         qstruct->hwadr[1] = 0xFF;
00734         qstruct->hwadr[2] = 0xFF;
00735         qstruct->hwadr[3] = 0xFF;
00736         qstruct->hwadr[4] = 0xFF;
00737         qstruct->hwadr[5] = 0xFF;
00738         qstruct->retries = ARP_MAXRETRY;
00739         qstruct->ttl = ARP_RESEND;
00740         arp_send_req( i );
00741         qstruct->state = ARP_PENDING;                           /* Waiting for Reply    */
00742         
00743         return(0);
00744 
00745         
00746 }
00747 
00762 void arp_manage (void)
00763 {
00764         struct arp_entry *qstruct;
00765         UINT8 i;
00766         
00767         /* Check Timer before entering  */
00768         
00769         if( check_timer(arp_timer) )
00770                 return;
00771                 
00772         init_timer( arp_timer, ARP_MANG_TOUT*TIMERTIC);
00773         
00774         /* ARP_DEBUGOUT("Managing ARP Cache\n\r"); */
00775         
00776         for( i=0; i<ARP_TSIZE; i++ ) {
00777                 /* ARP_DEBUGOUT("."); */
00778         
00779                 qstruct = &arp_table[i];
00780         
00781                 if( qstruct->state == ARP_FREE )
00782                         continue;
00783                         
00784                 /* TODO: How about ARP_RESERVED?        */
00785                         
00786                 if( qstruct->ttl > 0 )                          /* Aging                */
00787                         qstruct->ttl --;
00788 
00789                 /* Timed Out?   */
00790                 if( qstruct->ttl == 0 ) {
00791                         /* Do it for temporay entries   */
00792                         
00793                         ARP_DEBUGOUT("Found Timed out Entry..\n\r");
00794                 
00795                         if( qstruct->type == ARP_TEMP_IP ) {
00796                                 /* Release it?  */
00797                                 if( qstruct->state == ARP_RESOLVED ) {  
00798                                         ARP_DEBUGOUT("Releasing ARP Entry..\n\r");
00799                                         qstruct->state = ARP_FREE;
00800                                         continue;
00801                                 }
00802                                 
00803                                 /* Decrease retries left        */
00804                                 
00805                                 if( qstruct->retries > 0 )      
00806                                         qstruct->retries--;
00807                                 
00808                                 if( qstruct->retries == 0 )     {
00809                                         ARP_DEBUGOUT("ARP Replies Used up, releasing entry..\n\r");
00810                                         qstruct->state = ARP_FREE;
00811                                         continue;
00812                                 }
00813                                 
00814                                 /* So we need to resend ARP request     */
00815                                 
00816                                 ARP_DEBUGOUT("Trying to Resolve dynamic ARP Entry..\n\r");
00817                         
00818                                 qstruct->ttl = ARP_RESEND;
00819                                 arp_send_req( i );
00820                                 qstruct->state = ARP_PENDING;                           /* Waiting for Reply    */
00821                                 
00822                                 continue;
00823                         
00824                         }
00825                 
00826                         /* Do it for Static Entries                     */
00827                 
00828                         if( qstruct->type == ARP_FIXED_IP ) {
00829                                 
00830                                 /* So we need to resend ARP request     */
00831                                 
00832                                 /* Do not try to refresh broadcast      */
00833                                 
00834                                 if(qstruct->pradr == IP_BROADCAST_ADDRESS)
00835                                 {
00836                                         qstruct->ttl = ARP_TIMEOUT;
00837                                         continue;
00838                                 }
00839                                 
00840                                 ARP_DEBUGOUT("Refreshing Static ARP Entry..\n\r");
00841                         
00842                                 if( qstruct->retries > 0 )      
00843                                         qstruct->retries--;
00844                                 
00845                                 if( qstruct->retries == 0 )
00846                                         qstruct->state = ARP_PENDING;
00847                                 else
00848                                         qstruct->state = ARP_REFRESHING;
00849                         
00850                                 qstruct->ttl = ARP_RESEND;
00851                                 arp_send_req( i );
00852                                 
00853                                 continue;
00854                         
00855                         }
00856                 
00857                 }
00858         
00859         }
00860 
00861 
00862 }
00863 
00864 
00865 
00878 void arp_init (void)
00879 {
00880         struct arp_entry *qstruct;
00881         INT8 i;
00882         
00883         ARP_DEBUGOUT("Initializing ARP");
00884         
00885         for( i=0; i<ARP_TSIZE; i++ ) {
00886                 qstruct = &arp_table[i];
00887                 
00888                 qstruct->state = ARP_FREE;
00889                 qstruct->type = ARP_TEMP_IP;
00890                 
00891                 ARP_DEBUGOUT(".");
00892         }
00893         
00894         arp_timer = get_timer();
00895         init_timer(arp_timer, ARP_MANG_TOUT*TIMERTIC);
00896 
00897         /* set broadcast entry  */
00898         
00899         qstruct = &arp_table[0];
00900         qstruct->pradr = IP_BROADCAST_ADDRESS;
00901         qstruct->state = ARP_RESOLVED;
00902         qstruct->type = ARP_FIXED_IP;
00903         qstruct->ttl = ARP_TIMEOUT;
00904         qstruct->retries = ARP_MAXRETRY;        
00905         
00906         for(i=0; i<MAXHWALEN; i++)
00907                 qstruct->hwadr[i] = 0xFF;                                                       
00908         
00909         ARP_DEBUGOUT("\n\r");
00910         
00911 }
00928 BYTE is_subnet (LWORD ipadr, struct netif* machine)
00929 {
00930 
00931         UINT32 ltemp;
00932 
00933         ltemp = ipadr & machine->netmask;                                               /* Get Subnet part      */
00934         
00935         ltemp ^= (machine->localip & machine->netmask);                 /* Compare to my IP     */
00936         
00937         if( ltemp )
00938                 return(FALSE);
00939         
00940         return(TRUE);
00941 
00942 }

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