This source file includes following definitions.
- aarp_expire
- aarp_send_query
- aarp_send_reply
- aarp_send_probe
- aarp_expire_timer
- aarp_kick
- aarp_expire_device
- aarp_expire_timeout
- aarp_device_event
- aarp_alloc
- aarp_find_entry
- aarp_send_ddp
- aarp_resolved
- aarp_rcv
- aarp_proto_init
- free_entry_list
- aarp_cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
53
54
55 struct aarp_entry
56 {
57
58 unsigned long last_sent;
59 struct sk_buff_head packet_queue;
60 unsigned long expires_at;
61 struct at_addr target_addr;
62 struct device *dev;
63 char hwaddr[6];
64 unsigned short xmit_count;
65 struct aarp_entry *next;
66 };
67
68
69
70
71
72
73 static struct aarp_entry *resolved[AARP_HASH_SIZE], *unresolved[AARP_HASH_SIZE];
74 static int unresolved_count=0;
75
76
77
78
79
80 static struct timer_list aarp_timer;
81
82
83
84
85
86 static void aarp_expire(struct aarp_entry *a)
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
97
98
99 static void aarp_send_query(struct aarp_entry *a)
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
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
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
145
146
147 aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast);
148
149
150
151
152
153 dev_queue_xmit(skb, dev, SOPRI_NORMAL);
154
155
156
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)
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
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
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
208
209
210 aarp_dl->datalink_header(aarp_dl, skb, sha);
211
212
213
214
215
216 dev_queue_xmit(skb, dev, SOPRI_NORMAL);
217
218 }
219
220
221
222
223
224 void aarp_send_probe(struct device *dev, struct at_addr *us)
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
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
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
269
270
271 aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast);
272
273
274
275
276
277 dev_queue_xmit(skb, dev, SOPRI_NORMAL);
278
279 }
280
281
282
283
284
285 static void aarp_expire_timer(struct aarp_entry **n)
286 {
287 struct aarp_entry *t;
288 while((*n)!=NULL)
289 {
290
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
304
305
306 static void aarp_kick(struct aarp_entry **n)
307 {
308 struct aarp_entry *t;
309 while((*n)!=NULL)
310 {
311
312
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
329
330
331
332 static void aarp_expire_device(struct aarp_entry **n, struct device *dev)
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
350
351
352 static void aarp_expire_timeout(unsigned long unused)
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
371
372
373 static int aarp_device_event(struct notifier_block *this, unsigned long event, void *ptr)
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
389
390
391 static struct aarp_entry *aarp_alloc(void)
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
402
403
404
405 static struct aarp_entry *aarp_find_entry(struct aarp_entry *list, struct device *dev, struct at_addr *sat)
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
423
424
425 int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr)
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
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
444
445
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
453
454
455
456 *((__u16 *)skb->data)=htons(skb->len);
457 ft=1;
458 }
459
460
461
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
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
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
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
525
526
527 a=aarp_find_entry(unresolved[hash],dev,sa);
528 if(a!=NULL)
529 {
530
531
532
533
534 skb_queue_tail(&a->packet_queue, skb);
535 restore_flags(flags);
536 return 0;
537 }
538
539
540
541
542
543 a=aarp_alloc();
544 if(a==NULL)
545 {
546
547
548
549
550 restore_flags(flags);
551 return -1;
552 }
553
554
555
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
570
571
572 aarp_send_query(a);
573
574
575
576
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
588
589
590 return 0;
591 }
592
593
594
595
596
597
598 static void aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, int hash)
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
610
611
612 a->next=resolved[hash];
613 resolved[hash]=a;
614
615
616
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
636
637
638
639 static int aarp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
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
651
652
653 if(dev->type!=ARPHRD_ETHER)
654 {
655 kfree_skb(skb, FREE_READ);
656 return 0;
657 }
658
659
660
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
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
684
685
686 hash=ea->pa_src_node%(AARP_HASH_SIZE-1);
687
688
689
690
691
692 sa.s_node=ea->pa_src_node;
693 sa.s_net=ea->pa_src_net;
694
695
696
697
698
699 save_flags(flags);
700
701
702
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
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)
731 break;
732
733
734
735
736 cli();
737 if((a=aarp_find_entry(unresolved[hash],dev,&sa))==NULL || dev != a->dev)
738 break;
739
740
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
757
758
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
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)
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
810 static void free_entry_list(struct aarp_entry *list)
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
823 void aarp_cleanup_module(void)
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