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

Generated on Sun Aug 3 20:32:59 2003 for OpenTCP by doxygen1.2.18