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

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