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

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

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