root/net/appletalk/aarp.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. aarp_expire
  2. aarp_send_query
  3. aarp_send_reply
  4. aarp_send_probe
  5. aarp_expire_timer
  6. aarp_kick
  7. aarp_expire_device
  8. aarp_expire_timeout
  9. aarp_device_event
  10. aarp_alloc
  11. aarp_find_entry
  12. aarp_send_ddp
  13. aarp_resolved
  14. aarp_rcv
  15. aarp_proto_init
  16. free_entry_list
  17. aarp_cleanup_module

   1 /*
   2  *      AARP:           An implementation of the Appletalk aarp protocol for
   3  *                      ethernet 'ELAP'.
   4  *
   5  *              Alan Cox  <Alan.Cox@linux.org>
   6  *                        <alan@cymru.net>
   7  *
   8  *      This doesn't fit cleanly with the IP arp. This isn't a problem as
   9  *      the IP arp wants extracting from the device layer in 1.3.x anyway.
  10  *      [see the pre-1.3 test code for details 8)]
  11  *
  12  *      FIXME:
  13  *              We ought to handle the retransmits with a single list and a 
  14  *      seperate fast timer for when it is needed.
  15  *
  16  *              This program is free software; you can redistribute it and/or
  17  *              modify it under the terms of the GNU General Public License
  18  *              as published by the Free Software Foundation; either version
  19  *              2 of the License, or (at your option) any later version.
  20  *
  21  *
  22  *      References:
  23  *              Inside Appletalk (2nd Ed).
  24  */
  25  
  26 #include <asm/segment.h>
  27 #include <asm/system.h>
  28 #include <asm/bitops.h>
  29 #include <linux/types.h>
  30 #include <linux/kernel.h>
  31 #include <linux/sched.h>
  32 #include <linux/string.h>
  33 #include <linux/mm.h>
  34 #include <linux/socket.h>
  35 #include <linux/sockios.h>
  36 #include <linux/in.h>
  37 #include <linux/errno.h>
  38 #include <linux/interrupt.h>
  39 #include <linux/if_ether.h>
  40 #include <linux/inet.h>
  41 #include <linux/notifier.h>
  42 #include <linux/netdevice.h>
  43 #include <linux/etherdevice.h>
  44 #include <linux/if_arp.h>
  45 #include <linux/skbuff.h>
  46 #include <net/sock.h>
  47 #include <net/datalink.h>
  48 #include <net/psnap.h>
  49 #include <linux/atalk.h>
  50 
  51 /*
  52  *      Lists of aarp entries
  53  */
  54  
  55 struct aarp_entry
  56 {
  57         /* These first two are only used for unresolved entries */
  58         unsigned long last_sent;                /* Last time we xmitted the aarp request */
  59         struct sk_buff_head packet_queue;       /* Queue of frames wait for resolution */
  60         unsigned long expires_at;               /* Entry expiry time */
  61         struct at_addr target_addr;             /* DDP Address */
  62         struct device *dev;                     /* Device to use */
  63         char hwaddr[6];                         /* Physical i/f address of target/router */
  64         unsigned short xmit_count;              /* When this hits 10 we give up */
  65         struct aarp_entry *next;                /* Next entry in chain */
  66 };
  67 
  68 
  69 /*
  70  *      Hashed list of resolved and unresolved entries
  71  */
  72 
  73 static struct aarp_entry *resolved[AARP_HASH_SIZE], *unresolved[AARP_HASH_SIZE];
  74 static int unresolved_count=0;
  75 
  76 /*
  77  *      Used to walk the list and purge/kick entries.
  78  */
  79  
  80 static struct timer_list aarp_timer;
  81 
  82 /*
  83  *      Delete an aarp queue
  84  */
  85 
  86 static void aarp_expire(struct aarp_entry *a)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88         struct sk_buff *skb;
  89         
  90         while((skb=skb_dequeue(&a->packet_queue))!=NULL)
  91                 kfree_skb(skb, FREE_WRITE);
  92         kfree_s(a,sizeof(*a));
  93 }
  94 
  95 /*
  96  *      Send an aarp queue entry request
  97  */
  98  
  99 static void aarp_send_query(struct aarp_entry *a)
     /* [previous][next][first][last][top][bottom][index][help] */
 100 {
 101         static char aarp_eth_multicast[ETH_ALEN]={ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
 102         struct device *dev=a->dev;
 103         int len=dev->hard_header_len+sizeof(struct elapaarp)+aarp_dl->header_length;
 104         struct sk_buff *skb=alloc_skb(len, GFP_ATOMIC);
 105         struct elapaarp *eah;
 106         struct at_addr *sat=atalk_find_dev_addr(dev);
 107         
 108         if(skb==NULL || sat==NULL)
 109                 return;
 110         
 111         /*
 112          *      Set up the buffer.
 113          */             
 114 
 115         skb_reserve(skb,dev->hard_header_len+aarp_dl->header_length);
 116         eah             =       (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp));
 117         skb->arp        =       1;
 118         skb->free       =       1;
 119         skb->dev        =       a->dev;
 120         
 121         /*
 122          *      Set up the ARP.
 123          */
 124          
 125         eah->hw_type    =       htons(AARP_HW_TYPE_ETHERNET);
 126         eah->pa_type    =       htons(ETH_P_ATALK);
 127         eah->hw_len     =       ETH_ALEN;       
 128         eah->pa_len     =       AARP_PA_ALEN;
 129         eah->function   =       htons(AARP_REQUEST);
 130         
 131         memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN);
 132         
 133         eah->pa_src_zero=       0;
 134         eah->pa_src_net =       sat->s_net;
 135         eah->pa_src_node=       sat->s_node;
 136         
 137         memset(eah->hw_dst, '\0', ETH_ALEN);
 138         
 139         eah->pa_dst_zero=       0;
 140         eah->pa_dst_net =       a->target_addr.s_net;
 141         eah->pa_dst_node=       a->target_addr.s_node;
 142         
 143         /*
 144          *      Add ELAP headers and set target to the AARP multicast.
 145          */
 146          
 147         aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast);     
 148 
 149         /*
 150          *      Send it.
 151          */     
 152          
 153         dev_queue_xmit(skb, dev, SOPRI_NORMAL);
 154         
 155         /*
 156          *      Update the sending count
 157          */
 158          
 159         a->xmit_count++;
 160 }
 161 
 162 static void aarp_send_reply(struct device *dev, struct at_addr *us, struct at_addr *them, unsigned char *sha)
     /* [previous][next][first][last][top][bottom][index][help] */
 163 {
 164         int len=dev->hard_header_len+sizeof(struct elapaarp)+aarp_dl->header_length;
 165         struct sk_buff *skb=alloc_skb(len, GFP_ATOMIC);
 166         struct elapaarp *eah;
 167         
 168         if(skb==NULL)
 169                 return;
 170         
 171         /*
 172          *      Set up the buffer.
 173          */             
 174 
 175         skb_reserve(skb,dev->hard_header_len+aarp_dl->header_length);
 176         eah             =       (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp));         
 177         skb->arp        =       1;
 178         skb->free       =       1;
 179         skb->dev        =       dev;
 180         
 181         /*
 182          *      Set up the ARP.
 183          */
 184          
 185         eah->hw_type    =       htons(AARP_HW_TYPE_ETHERNET);
 186         eah->pa_type    =       htons(ETH_P_ATALK);
 187         eah->hw_len     =       ETH_ALEN;       
 188         eah->pa_len     =       AARP_PA_ALEN;
 189         eah->function   =       htons(AARP_REPLY);
 190         
 191         memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN);
 192         
 193         eah->pa_src_zero=       0;
 194         eah->pa_src_net =       us->s_net;
 195         eah->pa_src_node=       us->s_node;
 196         
 197         if(sha==NULL)
 198                 memset(eah->hw_dst, '\0', ETH_ALEN);
 199         else
 200                 memcpy(eah->hw_dst, sha, ETH_ALEN);
 201         
 202         eah->pa_dst_zero=       0;
 203         eah->pa_dst_net =       them->s_net;
 204         eah->pa_dst_node=       them->s_node;
 205         
 206         /*
 207          *      Add ELAP headers and set target to the AARP multicast.
 208          */
 209          
 210         aarp_dl->datalink_header(aarp_dl, skb, sha);    
 211 
 212         /*
 213          *      Send it.
 214          */     
 215          
 216         dev_queue_xmit(skb, dev, SOPRI_NORMAL);
 217         
 218 }
 219 
 220 /*
 221  *      Send probe frames. Called from atif_probe_device.
 222  */
 223  
 224 void aarp_send_probe(struct device *dev, struct at_addr *us)
     /* [previous][next][first][last][top][bottom][index][help] */
 225 {
 226         int len=dev->hard_header_len+sizeof(struct elapaarp)+aarp_dl->header_length;
 227         struct sk_buff *skb=alloc_skb(len, GFP_ATOMIC);
 228         struct elapaarp *eah;
 229         static char aarp_eth_multicast[ETH_ALEN]={ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
 230         
 231         if(skb==NULL)
 232                 return;
 233         
 234         /*
 235          *      Set up the buffer.
 236          */             
 237 
 238         skb_reserve(skb,dev->hard_header_len+aarp_dl->header_length);
 239         eah             =       (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp));
 240         
 241         skb->arp        =       1;
 242         skb->free       =       1;
 243         skb->dev        =       dev;
 244         
 245         /*
 246          *      Set up the ARP.
 247          */
 248          
 249         eah->hw_type    =       htons(AARP_HW_TYPE_ETHERNET);
 250         eah->pa_type    =       htons(ETH_P_ATALK);
 251         eah->hw_len     =       ETH_ALEN;       
 252         eah->pa_len     =       AARP_PA_ALEN;
 253         eah->function   =       htons(AARP_PROBE);
 254         
 255         memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN);
 256         
 257         eah->pa_src_zero=       0;
 258         eah->pa_src_net =       us->s_net;
 259         eah->pa_src_node=       us->s_node;
 260         
 261         memset(eah->hw_dst, '\0', ETH_ALEN);
 262         
 263         eah->pa_dst_zero=       0;
 264         eah->pa_dst_net =       us->s_net;
 265         eah->pa_dst_node=       us->s_node;
 266         
 267         /*
 268          *      Add ELAP headers and set target to the AARP multicast.
 269          */
 270          
 271         aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast);     
 272 
 273         /*
 274          *      Send it.
 275          */     
 276          
 277         dev_queue_xmit(skb, dev, SOPRI_NORMAL);
 278         
 279 }
 280         
 281 /*
 282  *      Handle an aarp timer expire
 283  */
 284 
 285 static void aarp_expire_timer(struct aarp_entry **n)
     /* [previous][next][first][last][top][bottom][index][help] */
 286 {
 287         struct aarp_entry *t;
 288         while((*n)!=NULL)
 289         {
 290                 /* Expired ? */
 291                 if((*n)->expires_at < jiffies)
 292                 {
 293                         t= *n;
 294                         *n=(*n)->next;
 295                         aarp_expire(t);
 296                 }
 297                 else
 298                         n=&((*n)->next);
 299         }
 300 }
 301 
 302 /*
 303  *      Kick all pending requests 5 times a second.
 304  */
 305  
 306 static void aarp_kick(struct aarp_entry **n)
     /* [previous][next][first][last][top][bottom][index][help] */
 307 {
 308         struct aarp_entry *t;
 309         while((*n)!=NULL)
 310         {
 311                 /* Expired - if this will be the 11th transmit, we delete
 312                    instead */
 313                 if((*n)->xmit_count>=AARP_RETRANSMIT_LIMIT)
 314                 {
 315                         t= *n;
 316                         *n=(*n)->next;
 317                         aarp_expire(t);
 318                 }
 319                 else
 320                 {
 321                         aarp_send_query(*n);
 322                         n=&((*n)->next);
 323                 }
 324         }
 325 }
 326 
 327 /*
 328  *      A device has gone down. Take all entries referring to the device
 329  *      and remove them.
 330  */
 331  
 332 static void aarp_expire_device(struct aarp_entry **n, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 333 {
 334         struct aarp_entry *t;
 335         while((*n)!=NULL)
 336         {
 337                 if((*n)->dev==dev)
 338                 {
 339                         t= *n;
 340                         *n=(*n)->next;
 341                         aarp_expire(t);
 342                 }
 343                 else
 344                         n=&((*n)->next);
 345         }
 346 }
 347                 
 348 /*
 349  *      Handle the timer event 
 350  */
 351  
 352 static void aarp_expire_timeout(unsigned long unused)
     /* [previous][next][first][last][top][bottom][index][help] */
 353 {
 354         int ct=0;
 355         for(ct=0;ct<AARP_HASH_SIZE;ct++)
 356         {
 357                 aarp_expire_timer(&resolved[ct]);
 358                 aarp_kick(&unresolved[ct]);
 359                 aarp_expire_timer(&unresolved[ct]);
 360         }
 361         del_timer(&aarp_timer);
 362         if(unresolved_count==0)
 363                 aarp_timer.expires=jiffies+AARP_EXPIRY_TIME;
 364         else
 365                 aarp_timer.expires=jiffies+AARP_TICK_TIME;
 366         add_timer(&aarp_timer);
 367 }
 368 
 369 /*
 370  *      Network device notifier chain handler.
 371  */
 372  
 373 static int aarp_device_event(struct notifier_block *this, unsigned long event, void *ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 374 {
 375         int ct=0;
 376         if(event==NETDEV_DOWN)
 377         {
 378                 for(ct=0;ct<AARP_HASH_SIZE;ct++)
 379                 {
 380                         aarp_expire_device(&resolved[ct],ptr);
 381                         aarp_expire_device(&unresolved[ct],ptr);
 382                 }
 383         }
 384         return NOTIFY_DONE;
 385 }
 386 
 387 /*
 388  *      Create a new aarp entry.
 389  */
 390  
 391 static struct aarp_entry *aarp_alloc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 392 {
 393         struct aarp_entry *a=kmalloc(sizeof(struct aarp_entry), GFP_ATOMIC);
 394         if(a==NULL)
 395                 return NULL;
 396         skb_queue_head_init(&a->packet_queue);
 397         return a;
 398 }
 399 
 400 /*
 401  *      Find an entry. We might return an expired but not yet purged entry. We
 402  *      don't care as it will do no harm.
 403  */
 404  
 405 static struct aarp_entry *aarp_find_entry(struct aarp_entry *list, struct device *dev, struct at_addr *sat)
     /* [previous][next][first][last][top][bottom][index][help] */
 406 {
 407         unsigned long flags;
 408         save_flags(flags);
 409         cli();
 410         while(list)
 411         {
 412                 if(list->target_addr.s_net==sat->s_net &&
 413                    list->target_addr.s_node==sat->s_node && list->dev==dev)
 414                         break;
 415                 list=list->next;
 416         }
 417         restore_flags(flags);
 418         return list;
 419 }
 420 
 421 /*
 422  *      Send a DDP frame
 423  */
 424  
 425 int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 426 {
 427         static char ddp_eth_multicast[ETH_ALEN]={ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
 428         int hash;
 429         struct aarp_entry *a;
 430         unsigned long flags;
 431         
 432         /*
 433          *      Check for localtalk first
 434          */
 435          
 436         if(dev->type==ARPHRD_LOCALTLK)
 437         {
 438                 struct at_addr *at=atalk_find_dev_addr(dev);
 439                 struct ddpehdr *ddp=(struct ddpehdr *)skb->data;
 440                 int ft=2;
 441                 
 442                 /*
 443                  *      Compressible ?
 444                  * 
 445                  *      IFF: src_net==dest_net==device_net
 446                  */
 447                  
 448                 if(at->s_net==sa->s_net && sa->s_net==ddp->deh_snet)
 449                 {
 450                         skb_pull(skb,sizeof(struct ddpehdr)-4);
 451                         /*
 452                          *      The uper two remaining bytes are the port 
 453                          *      numbers we just happen to need. Now put the 
 454                          *      length in the lower two.
 455                          */
 456                         *((__u16 *)skb->data)=htons(skb->len);
 457                         ft=1;
 458                 }
 459                 /*
 460                  *      Nice and easy. No AARP type protocols occur here
 461                  *      so we can just shovel it out with a 3 byte LLAP header
 462                  */
 463                  
 464                 skb_push(skb,3);
 465                 skb->data[0]=sa->s_node;
 466                 skb->data[1]=at->s_node;
 467                 skb->data[2]=ft;
 468                  
 469                 if(skb->sk==NULL)
 470                         dev_queue_xmit(skb, skb->dev, SOPRI_NORMAL);
 471                 else
 472                         dev_queue_xmit(skb, skb->dev, skb->sk->priority);
 473                 return 1;
 474         }       
 475          
 476         /*
 477          *      Non ELAP we cannot do.
 478          */
 479 
 480         if(dev->type!=ARPHRD_ETHER)
 481         {
 482                 return -1;
 483         }
 484 
 485         skb->dev = dev;
 486         skb->protocol = htons(ETH_P_ATALK);
 487                         
 488         hash=sa->s_node%(AARP_HASH_SIZE-1);
 489         save_flags(flags);
 490         cli();
 491         
 492         /*
 493          *      Do we have a resolved entry ?
 494          */
 495          
 496         if(sa->s_node==ATADDR_BCAST)
 497         {
 498                 ddp_dl->datalink_header(ddp_dl, skb, ddp_eth_multicast);
 499                 if(skb->sk==NULL)
 500                         dev_queue_xmit(skb, skb->dev, SOPRI_NORMAL);
 501                 else
 502                         dev_queue_xmit(skb, skb->dev, skb->sk->priority);
 503                 restore_flags(flags);
 504                 return 1;
 505         }
 506         a=aarp_find_entry(resolved[hash],dev,sa);
 507         if(a!=NULL)
 508         {
 509                 /*
 510                  *      Return 1 and fill in the address
 511                  */
 512 
 513                 a->expires_at=jiffies+AARP_EXPIRY_TIME*10;
 514                 ddp_dl->datalink_header(ddp_dl, skb, a->hwaddr);
 515                 if(skb->sk==NULL)
 516                         dev_queue_xmit(skb, skb->dev, SOPRI_NORMAL);
 517                 else
 518                         dev_queue_xmit(skb, skb->dev, skb->sk->priority);
 519                 restore_flags(flags);
 520                 return 1;
 521         }
 522 
 523         /*
 524          *      Do we have an unresolved entry: This is the less common path
 525          */
 526 
 527         a=aarp_find_entry(unresolved[hash],dev,sa);
 528         if(a!=NULL)
 529         {
 530                 /*
 531                  *      Queue onto the unresolved queue
 532                  */
 533 
 534                 skb_queue_tail(&a->packet_queue, skb);
 535                 restore_flags(flags);
 536                 return 0;
 537         }
 538 
 539         /*
 540          *      Allocate a new entry
 541          */
 542 
 543         a=aarp_alloc();
 544         if(a==NULL)
 545         {
 546                 /*
 547                  *      Whoops slipped... good job it's an unreliable 
 548                  *      protocol 8)     
 549                  */
 550                 restore_flags(flags);
 551                 return -1;
 552         }
 553 
 554         /*
 555          *      Set up the queue
 556          */
 557 
 558         skb_queue_tail(&a->packet_queue, skb);
 559         a->expires_at=jiffies+AARP_RESOLVE_TIME;
 560         a->dev=dev;
 561         a->next=unresolved[hash];
 562         a->target_addr= *sa;
 563         a->xmit_count=0;
 564         unresolved[hash]=a;
 565         unresolved_count++;
 566         restore_flags(flags);
 567 
 568         /*
 569          *      Send an initial request for the address
 570          */
 571 
 572         aarp_send_query(a);
 573 
 574         /*
 575          *      Switch to fast timer if needed (That is if this is the
 576          *      first unresolved entry to get added)
 577          */
 578 
 579         if(unresolved_count==1)
 580         {
 581                 del_timer(&aarp_timer);
 582                 aarp_timer.expires=jiffies+AARP_TICK_TIME;
 583                 add_timer(&aarp_timer);
 584         }
 585 
 586         /*
 587          *      Tell the ddp layer we have taken over for this frame.
 588          */
 589 
 590         return 0;
 591 }
 592 
 593 /*
 594  *      An entry in the aarp unresolved queue has become resolved. Send
 595  *      all the frames queued under it.
 596  */
 597  
 598 static void aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, int hash)
     /* [previous][next][first][last][top][bottom][index][help] */
 599 {
 600         struct sk_buff *skb;
 601         while(*list!=NULL)
 602         {
 603                 if(*list==a)
 604                 {
 605                         unresolved_count--;
 606                         *list=a->next;
 607                         
 608                         /* 
 609                          *      Move into the resolved list 
 610                          */
 611                          
 612                         a->next=resolved[hash];
 613                         resolved[hash]=a;
 614                         
 615                         /*
 616                          *      Kick frames off 
 617                          */
 618                          
 619                         while((skb=skb_dequeue(&a->packet_queue))!=NULL)
 620                         {
 621                                 a->expires_at=jiffies+AARP_EXPIRY_TIME*10;
 622                                 ddp_dl->datalink_header(ddp_dl,skb,a->hwaddr);
 623                                 if(skb->sk==NULL)
 624                                         dev_queue_xmit(skb, skb->dev, SOPRI_NORMAL);
 625                                 else
 626                                         dev_queue_xmit(skb, skb->dev, skb->sk->priority);
 627                         }
 628                 }
 629                 else
 630                         list=&((*list)->next);
 631         }
 632 }
 633 
 634 /*
 635  *      This is called by the SNAP driver whenever we see an AARP SNAP
 636  *      frame. We currently only support ethernet.
 637  */
 638  
 639 static int aarp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
 640 {
 641         struct elapaarp *ea=(struct elapaarp *)skb->h.raw;
 642         struct aarp_entry *a;
 643         struct at_addr sa, *ma;
 644         unsigned long flags;
 645         int hash;
 646         struct atalk_iface *ifa;
 647         
 648         
 649         /*
 650          *      We only do ethernet SNAP AARP
 651          */
 652          
 653         if(dev->type!=ARPHRD_ETHER)
 654         {
 655                 kfree_skb(skb, FREE_READ);
 656                 return 0;
 657         }
 658         
 659         /*
 660          *      Frame size ok ?
 661          */
 662          
 663         if(!skb_pull(skb,sizeof(*ea)))
 664         {
 665                 kfree_skb(skb, FREE_READ);
 666                 return 0;
 667         }
 668 
 669         ea->function=ntohs(ea->function);
 670         
 671         /*
 672          *      Sanity check fields.
 673          */
 674          
 675         if(ea->function<AARP_REQUEST || ea->function > AARP_PROBE || ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN ||
 676                 ea->pa_src_zero != 0 || ea->pa_dst_zero != 0)
 677         {
 678                 kfree_skb(skb, FREE_READ);
 679                 return 0;
 680         }
 681         
 682         /*
 683          *      Looks good
 684          */
 685         
 686         hash=ea->pa_src_node%(AARP_HASH_SIZE-1);
 687 
 688         /*
 689          *      Build an address
 690          */
 691          
 692         sa.s_node=ea->pa_src_node;
 693         sa.s_net=ea->pa_src_net;
 694         
 695         /*
 696          *      Process the packet
 697          */
 698          
 699         save_flags(flags);
 700 
 701         /*
 702          *      Check for replies of me
 703          */
 704                         
 705         ifa=atalk_find_dev(dev);
 706         if(ifa==NULL)
 707         {
 708                 restore_flags(flags);
 709                 kfree_skb(skb, FREE_READ);
 710                 return 1;               
 711         }
 712         if(ifa->status&ATIF_PROBE)
 713         {                       
 714                 if(ifa->address.s_node==ea->pa_dst_node && ifa->address.s_net==ea->pa_dst_net)
 715                 {
 716                         /*
 717                          *      Fail the probe (in use)
 718                          */
 719                          
 720                         ifa->status|=ATIF_PROBE_FAIL;
 721                         restore_flags(flags);
 722                         kfree_skb(skb, FREE_READ);
 723                         return 1;               
 724                 }
 725         }                                
 726         
 727         switch(ea->function)
 728         {
 729                 case AARP_REPLY:        
 730                         if(unresolved_count==0) /* Speed up */
 731                                 break;
 732                         /*
 733                          *      Find the entry  
 734                          */
 735                          
 736                         cli();
 737                         if((a=aarp_find_entry(unresolved[hash],dev,&sa))==NULL || dev != a->dev)
 738                                 break;
 739                         /*
 740                          *      We can fill one in - this is good
 741                          */
 742                          
 743                         memcpy(a->hwaddr,ea->hw_src,ETH_ALEN);
 744                         aarp_resolved(&unresolved[hash],a,hash);
 745                         if(unresolved_count==0)
 746                         {
 747                                 del_timer(&aarp_timer);
 748                                 aarp_timer.expires=jiffies+AARP_EXPIRY_TIME;
 749                                 add_timer(&aarp_timer);
 750                         }
 751                         break;
 752                         
 753                 case AARP_REQUEST:
 754                 case AARP_PROBE:
 755                         /*
 756                          *      If it is my address set ma to my address and reply. We can treat probe and
 757                          *      request the same. Probe simply means we shouldn't cache the querying host, 
 758                          *      as in a probe they are proposing an address not using one.
 759                          */
 760                          
 761                         ma=&ifa->address;
 762                         sa.s_node=ea->pa_dst_node;
 763                         sa.s_net=ea->pa_dst_net;
 764                         
 765                         if(sa.s_node!=ma->s_node)
 766                                 break;
 767                         if(sa.s_net && ma->s_net && sa.s_net!=ma->s_net)
 768                                 break;
 769 
 770                         sa.s_node=ea->pa_src_node;
 771                         sa.s_net=ea->pa_src_net;
 772                         
 773                         /*
 774                          *      aarp_my_address has found the address to use for us.
 775                          */
 776                          
 777                         aarp_send_reply(dev,ma,&sa,ea->hw_src);
 778                         break;
 779         }
 780         restore_flags(flags);
 781         kfree_skb(skb, FREE_READ);
 782         return 1;               
 783 }
 784 
 785 static struct notifier_block aarp_notifier={
 786         aarp_device_event,
 787         NULL,
 788         0
 789 };
 790 
 791 static char aarp_snap_id[]={0x00,0x00,0x00,0x80,0xF3};
 792 
 793 
 794 void aarp_proto_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 795 {
 796         if((aarp_dl=register_snap_client(aarp_snap_id, aarp_rcv))==NULL)
 797                 printk("Unable to register AARP with SNAP.\n");
 798         init_timer(&aarp_timer);
 799         aarp_timer.function=aarp_expire_timeout;
 800         aarp_timer.data=0;
 801         aarp_timer.expires=jiffies+AARP_EXPIRY_TIME;
 802         add_timer(&aarp_timer);
 803         register_netdevice_notifier(&aarp_notifier);
 804 }
 805 
 806 
 807 #ifdef MODULE
 808 
 809 /* Free all the entries in an aarp list. Caller should turn off interrupts. */
 810 static void free_entry_list(struct aarp_entry *list)
     /* [previous][next][first][last][top][bottom][index][help] */
 811 {
 812         struct aarp_entry *tmp;
 813 
 814         while (list != NULL)
 815         {
 816                 tmp = list->next;
 817                 aarp_expire(list);
 818                 list = tmp;
 819         }
 820 }
 821 
 822 /* General module cleanup. Called from cleanup_module() in ddp.c. */
 823 void aarp_cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 824 {
 825         unsigned long flags;
 826         int i;
 827 
 828         save_flags(flags);
 829         cli();
 830 
 831         del_timer(&aarp_timer);
 832         unregister_netdevice_notifier(&aarp_notifier);
 833         unregister_snap_client(aarp_snap_id);
 834 
 835         for (i = 0; i < AARP_HASH_SIZE; i++)
 836         {
 837                 free_entry_list(resolved[i]);
 838                 free_entry_list(unresolved[i]);
 839         }
 840 
 841         restore_flags(flags);
 842 }
 843 
 844 #endif  /* MODULE */

/* [previous][next][first][last][top][bottom][index][help] */