This source file includes following definitions.
- arp_check_expire
- arp_release_entry
- arp_send
- arp_expire_request
- arp_send_q
- arp_destroy
- arp_rcv
- arp_find
- arp_get_info
- arp_lookup
- arp_req_set
- arp_req_get
- arp_ioctl
- arp_init
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
27
28
29
30
31
32 #include <linux/types.h>
33 #include <linux/string.h>
34 #include <linux/kernel.h>
35 #include <linux/sched.h>
36 #include <linux/config.h>
37 #include <linux/socket.h>
38 #include <linux/sockios.h>
39 #include <linux/errno.h>
40 #include <linux/if_arp.h>
41 #include <linux/in.h>
42 #include <asm/system.h>
43 #include <asm/segment.h>
44 #include <stdarg.h>
45 #include <linux/inet.h>
46 #include <linux/netdevice.h>
47 #include <linux/etherdevice.h>
48 #include "ip.h"
49 #include "route.h"
50 #include "protocol.h"
51 #include "tcp.h"
52 #include <linux/skbuff.h>
53 #include "sock.h"
54 #include "arp.h"
55 #ifdef CONFIG_AX25
56 #include "ax25.h"
57 #endif
58
59
60
61
62
63
64
65
66 struct arp_table
67 {
68 struct arp_table *next;
69 unsigned long last_used;
70 unsigned int flags;
71 unsigned long ip;
72 unsigned char ha[MAX_ADDR_LEN];
73 unsigned char hlen;
74 unsigned short htype;
75 struct device *dev;
76
77
78
79
80
81 struct timer_list timer;
82 int retries;
83 struct sk_buff_head skb;
84 };
85
86
87
88
89
90 struct arphdr
91 {
92 unsigned short ar_hrd;
93 unsigned short ar_pro;
94 unsigned char ar_hln;
95 unsigned char ar_pln;
96 unsigned short ar_op;
97
98 #if 0
99
100
101
102 unsigned char ar_sha[ETH_ALEN];
103 unsigned char ar_sip[4];
104 unsigned char ar_tha[ETH_ALEN];
105 unsigned char ar_tip[4];
106 #endif
107
108 };
109
110
111
112
113
114
115
116
117
118
119 #define ARP_RES_TIME (250*(HZ/10))
120
121
122
123
124
125
126 #define ARP_MAX_TRIES 3
127
128
129
130
131
132 #define ARP_TIMEOUT (600*HZ)
133
134
135
136
137
138
139
140 #define ARP_CHECK_INTERVAL (60 * HZ)
141
142
143 static void arp_check_expire (unsigned long);
144
145
146 static struct timer_list arp_timer =
147 { NULL, NULL, ARP_CHECK_INTERVAL, 0L, &arp_check_expire };
148
149
150
151
152
153
154
155 #define ARP_TABLE_SIZE 16
156
157 struct arp_table *arp_tables[ARP_TABLE_SIZE] =
158 {
159 NULL,
160 };
161
162
163
164
165
166 #define HASH(paddr) (htonl(paddr) & (ARP_TABLE_SIZE - 1))
167
168
169
170
171
172
173 static int proxies = 0;
174
175
176
177
178
179
180
181
182
183
184 static void arp_check_expire(unsigned long dummy)
185 {
186 int i;
187 unsigned long now = jiffies;
188 unsigned long flags;
189 save_flags(flags);
190 cli();
191
192 for (i = 0; i < ARP_TABLE_SIZE; i++)
193 {
194 struct arp_table *entry;
195 struct arp_table **pentry = &arp_tables[i];
196
197 while ((entry = *pentry) != NULL)
198 {
199 if ((now - entry->last_used) > ARP_TIMEOUT
200 && !(entry->flags & ATF_PERM))
201 {
202 *pentry = entry->next;
203 if (entry->flags & ATF_PUBL)
204 proxies--;
205 del_timer(&entry->timer);
206 kfree_s(entry, sizeof(struct arp_table));
207 }
208 else
209 pentry = &entry->next;
210 }
211 }
212 restore_flags(flags);
213
214
215
216
217
218 del_timer(&arp_timer);
219 arp_timer.expires = ARP_CHECK_INTERVAL;
220 add_timer(&arp_timer);
221 }
222
223
224
225
226
227
228 static void arp_release_entry(struct arp_table *entry)
229 {
230 struct sk_buff *skb;
231
232 if (entry->flags & ATF_PUBL)
233 proxies--;
234
235 while ((skb = skb_dequeue(&entry->skb)) != NULL)
236 {
237 if (skb->free)
238 kfree_skb(skb, FREE_WRITE);
239 }
240 del_timer(&entry->timer);
241 kfree_s(entry, sizeof(struct arp_table));
242 return;
243 }
244
245
246
247
248
249
250
251 void arp_send(int type, int ptype, unsigned long dest_ip,
252 struct device *dev, unsigned long src_ip,
253 unsigned char *dest_hw, unsigned char *src_hw)
254 {
255 struct sk_buff *skb;
256 struct arphdr *arp;
257 unsigned char *arp_ptr;
258
259
260
261
262
263 if(dev->flags&IFF_NOARP)
264 return;
265
266
267
268
269
270 skb = alloc_skb(sizeof(struct arphdr)+ 2*(dev->addr_len+4)
271 + dev->hard_header_len, GFP_ATOMIC);
272 if (skb == NULL)
273 {
274 printk("ARP: no memory to send an arp packet\n");
275 return;
276 }
277 skb->len = sizeof(struct arphdr) + dev->hard_header_len + 2*(dev->addr_len+4);
278 skb->arp = 1;
279 skb->dev = dev;
280 skb->free = 1;
281
282
283
284
285
286 dev->hard_header(skb->data,dev,ptype,dest_hw?dest_hw:dev->broadcast,src_hw?src_hw:NULL,skb->len,skb);
287
288
289 arp = (struct arphdr *) (skb->data + dev->hard_header_len);
290 arp->ar_hrd = htons(dev->type);
291 #ifdef CONFIG_AX25
292 arp->ar_pro = (dev->type != ARPHRD_AX25)? htons(ETH_P_IP) : htons(AX25_P_IP);
293 #else
294 arp->ar_pro = htons(ETH_P_IP);
295 #endif
296 arp->ar_hln = dev->addr_len;
297 arp->ar_pln = 4;
298 arp->ar_op = htons(type);
299
300 arp_ptr=(unsigned char *)(arp+1);
301
302 memcpy(arp_ptr, src_hw, dev->addr_len);
303 arp_ptr+=dev->addr_len;
304 memcpy(arp_ptr, &src_ip,4);
305 arp_ptr+=4;
306 if (dest_hw != NULL)
307 memcpy(arp_ptr, dest_hw, dev->addr_len);
308 else
309 memset(arp_ptr, 0, dev->addr_len);
310 arp_ptr+=dev->addr_len;
311 memcpy(arp_ptr, &dest_ip, 4);
312
313 dev_queue_xmit(skb, dev, 0);
314 }
315
316
317
318
319
320
321
322 static void arp_expire_request (unsigned long arg)
323 {
324 struct arp_table *entry = (struct arp_table *) arg;
325 struct arp_table **pentry;
326 unsigned long hash;
327 unsigned long flags;
328
329 save_flags(flags);
330 cli();
331
332
333
334
335
336
337
338 if (entry->flags & ATF_COM)
339 {
340 restore_flags(flags);
341 return;
342 }
343
344 if (--entry->retries > 0)
345 {
346 unsigned long ip = entry->ip;
347 struct device *dev = entry->dev;
348
349
350 del_timer(&entry->timer);
351 entry->timer.expires = ARP_RES_TIME;
352 add_timer(&entry->timer);
353 restore_flags(flags);
354 arp_send(ARPOP_REQUEST, ETH_P_ARP, ip, dev, dev->pa_addr,
355 NULL, dev->dev_addr);
356 return;
357 }
358
359
360
361
362
363
364
365
366 hash = HASH(entry->ip);
367 pentry = &arp_tables[hash];
368 while (*pentry != NULL)
369 {
370 if (*pentry == entry)
371 {
372 *pentry = entry->next;
373 del_timer(&entry->timer);
374 restore_flags(flags);
375 arp_release_entry(entry);
376 return;
377 }
378 pentry = &(*pentry)->next;
379 }
380 restore_flags(flags);
381 printk("Possible ARP queue corruption.\n");
382
383
384
385 }
386
387
388
389
390
391
392 static void arp_send_q(struct arp_table *entry, unsigned char *hw_dest)
393 {
394 struct sk_buff *skb;
395
396
397
398
399
400
401 if(!(entry->flags&ATF_COM))
402 {
403 printk("arp_send_q: incomplete entry for %s\n",
404 in_ntoa(entry->ip));
405 return;
406 }
407
408 while((skb = skb_dequeue(&entry->skb)) != NULL)
409 {
410 IS_SKB(skb);
411 if(!skb->dev->rebuild_header(skb->data,skb->dev,skb->raddr,skb))
412 {
413 skb->arp = 1;
414 if(skb->sk==NULL)
415 dev_queue_xmit(skb, skb->dev, 0);
416 else
417 dev_queue_xmit(skb,skb->dev,skb->sk->priority);
418 }
419 else
420 {
421
422
423 printk("arp_send_q: The impossible occurred. Please notify Alan.\n");
424 printk("arp_send_q: active entity %s\n",in_ntoa(entry->ip));
425 printk("arp_send_q: failed to find %s\n",in_ntoa(skb->raddr));
426 }
427 }
428 }
429
430
431
432
433
434
435 void arp_destroy(unsigned long ip_addr, int force)
436 {
437 struct arp_table *entry;
438 struct arp_table **pentry;
439 unsigned long hash = HASH(ip_addr);
440
441 cli();
442 pentry = &arp_tables[hash];
443 while ((entry = *pentry) != NULL)
444 {
445 if (entry->ip == ip_addr)
446 {
447 if ((entry->flags & ATF_PERM) && !force)
448 return;
449 *pentry = entry->next;
450 del_timer(&entry->timer);
451 sti();
452 arp_release_entry(entry);
453 return;
454 }
455 pentry = &entry->next;
456 }
457 sti();
458 }
459
460
461
462
463
464
465
466
467 int arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
468 {
469
470
471
472
473 struct arphdr *arp = (struct arphdr *)skb->h.raw;
474 unsigned char *arp_ptr= (unsigned char *)(arp+1);
475 struct arp_table *entry;
476 struct arp_table *proxy_entry;
477 int addr_hint,hlen,htype;
478 unsigned long hash,dest_hash;
479 unsigned char ha[MAX_ADDR_LEN];
480 long sip,tip;
481 unsigned char *sha,*tha;
482
483
484
485
486
487
488
489
490 if (arp->ar_hln != dev->addr_len ||
491 dev->type != ntohs(arp->ar_hrd) ||
492 dev->flags & IFF_NOARP ||
493 arp->ar_pln != 4)
494 {
495 kfree_skb(skb, FREE_READ);
496 return 0;
497 }
498
499
500
501
502
503
504
505 switch(dev->type)
506 {
507 #ifdef CONFIG_AX25
508 case ARPHRD_AX25:
509 if(arp->ar_pro != htons(AX25_P_IP))
510 {
511 kfree_skb(skb, FREE_READ);
512 return 0;
513 }
514 break;
515 #endif
516 case ARPHRD_ETHER:
517 if(arp->ar_pro != htons(ETH_P_IP))
518 {
519 kfree_skb(skb, FREE_READ);
520 return 0;
521 }
522 break;
523
524 default:
525 printk("ARP: dev->type mangled!\n");
526 kfree_skb(skb, FREE_READ);
527 return 0;
528 }
529
530
531
532
533
534 hlen = dev->addr_len;
535 htype = dev->type;
536
537 sha=arp_ptr;
538 arp_ptr+=hlen;
539 memcpy(&sip,arp_ptr,4);
540 arp_ptr+=4;
541 tha=arp_ptr;
542 arp_ptr+=hlen;
543 memcpy(&tip,arp_ptr,4);
544
545
546
547
548 if(tip == INADDR_LOOPBACK)
549 {
550 kfree_skb(skb, FREE_READ);
551 return 0;
552 }
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571 addr_hint = ip_chk_addr(tip);
572
573 if(arp->ar_op == htons(ARPOP_REPLY))
574 {
575 if(addr_hint!=IS_MYADDR)
576 {
577
578
579
580 kfree_skb(skb, FREE_READ);
581 return 0;
582 }
583
584
585
586 }
587 else
588 {
589
590
591
592 if(addr_hint != IS_MYADDR)
593 {
594
595
596
597
598
599 if (proxies == 0)
600 {
601 kfree_skb(skb, FREE_READ);
602 return 0;
603 }
604
605 dest_hash = HASH(tip);
606 cli();
607 for(proxy_entry=arp_tables[dest_hash];
608 proxy_entry;
609 proxy_entry = proxy_entry->next)
610 {
611 if(proxy_entry->ip == tip && proxy_entry->htype==htype)
612 break;
613 }
614 if (proxy_entry && (proxy_entry->flags & ATF_PUBL))
615 {
616 memcpy(ha, proxy_entry->ha, hlen);
617 sti();
618 arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,ha);
619 kfree_skb(skb, FREE_READ);
620 return 0;
621 }
622 else
623 {
624 sti();
625 kfree_skb(skb, FREE_READ);
626 return 0;
627 }
628 }
629 else
630 {
631
632
633
634 arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr);
635 }
636 }
637
638
639
640
641
642
643
644
645 hash = HASH(sip);
646 cli();
647 for(entry=arp_tables[hash];entry;entry=entry->next)
648 if(entry->ip==sip && entry->htype==htype)
649 break;
650
651 if(entry)
652 {
653
654
655
656 memcpy(entry->ha, sha, hlen);
657 entry->hlen = hlen;
658 entry->last_used = jiffies;
659 if (!(entry->flags & ATF_COM))
660 {
661
662
663
664
665 del_timer(&entry->timer);
666 entry->flags |= ATF_COM;
667 sti();
668
669
670
671
672
673 arp_send_q(entry, sha);
674 }
675 else
676 {
677 sti();
678 }
679 }
680 else
681 {
682
683
684
685 entry = (struct arp_table *)kmalloc(sizeof(struct arp_table),GFP_ATOMIC);
686 if(entry == NULL)
687 {
688 sti();
689 printk("ARP: no memory for new arp entry\n");
690
691 kfree_skb(skb, FREE_READ);
692 return 0;
693 }
694
695 entry->ip = sip;
696 entry->hlen = hlen;
697 entry->htype = htype;
698 entry->flags = ATF_COM;
699 memcpy(entry->ha, sha, hlen);
700 entry->last_used = jiffies;
701 entry->dev = skb->dev;
702 skb_queue_head_init(&entry->skb);
703 entry->next = arp_tables[hash];
704 arp_tables[hash] = entry;
705
706 sti();
707 }
708
709
710
711
712 kfree_skb(skb, FREE_READ);
713 return 0;
714 }
715
716
717
718
719
720
721 int arp_find(unsigned char *haddr, unsigned long paddr, struct device *dev,
722 unsigned long saddr, struct sk_buff *skb)
723 {
724 struct arp_table *entry;
725 unsigned long hash;
726 switch (ip_chk_addr(paddr))
727 {
728 case IS_MYADDR:
729 printk("ARP: arp called for own IP address\n");
730 memcpy(haddr, dev->dev_addr, dev->addr_len);
731 skb->arp = 1;
732 return 0;
733 case IS_BROADCAST:
734 memcpy(haddr, dev->broadcast, dev->addr_len);
735 skb->arp = 1;
736 return 0;
737 }
738
739 hash = HASH(paddr);
740 cli();
741
742
743
744
745 for (entry = arp_tables[hash]; entry != NULL; entry = entry->next)
746 if (entry->ip == paddr)
747 break;
748
749
750 if (entry != NULL)
751 {
752 if (!(entry->flags & ATF_COM))
753 {
754
755
756
757
758
759 if (skb != NULL)
760 skb_queue_tail(&entry->skb, skb);
761 sti();
762 return 1;
763 }
764
765
766
767
768
769 entry->last_used = jiffies;
770 memcpy(haddr, entry->ha, dev->addr_len);
771 if (skb)
772 skb->arp = 1;
773 sti();
774 return 0;
775 }
776
777
778
779
780
781 entry = (struct arp_table *) kmalloc(sizeof(struct arp_table),
782 GFP_ATOMIC);
783 if (entry != NULL)
784 {
785 entry->ip = paddr;
786 entry->hlen = dev->addr_len;
787 entry->htype = dev->type;
788 entry->flags = 0;
789 memset(entry->ha, 0, dev->addr_len);
790 entry->last_used = jiffies;
791 entry->next = arp_tables[hash];
792 entry->dev = dev;
793 arp_tables[hash] = entry;
794 entry->timer.function = arp_expire_request;
795 entry->timer.data = (unsigned long)entry;
796 entry->timer.expires = ARP_RES_TIME;
797 add_timer(&entry->timer);
798 entry->retries = ARP_MAX_TRIES;
799 skb_queue_head_init(&entry->skb);
800 if (skb != NULL)
801 skb_queue_tail(&entry->skb, skb);
802 }
803 else
804 {
805 if (skb != NULL && skb->free)
806 kfree_skb(skb, FREE_WRITE);
807 }
808 sti();
809
810
811
812
813
814 arp_send(ARPOP_REQUEST, ETH_P_ARP, paddr, dev, saddr, NULL,
815 dev->dev_addr);
816
817 return 1;
818 }
819
820
821
822
823
824
825 #define HBUFFERLEN 30
826
827 int arp_get_info(char *buffer, char **start, off_t offset, int length)
828 {
829 int len=0;
830 off_t begin=0;
831 off_t pos=0;
832 int size;
833 struct arp_table *entry;
834 char hbuffer[HBUFFERLEN];
835 int i,j,k;
836 const char hexbuf[] = "0123456789ABCDEF";
837
838 size = sprintf(buffer,"IP address HW type Flags HW address\n");
839 pos+=size;
840 len+=size;
841
842 cli();
843 for(i=0; i<ARP_TABLE_SIZE; i++)
844 {
845 for(entry=arp_tables[i]; entry!=NULL; entry=entry->next)
846 {
847
848
849
850 #ifdef CONFIG_AX25
851
852 if(entry->htype==ARPHRD_AX25)
853 strcpy(hbuffer,ax2asc((ax25_address *)entry->ha));
854 else {
855 #endif
856
857 for(k=0,j=0;k<HBUFFERLEN-3 && j<entry->hlen;j++)
858 {
859 hbuffer[k++]=hexbuf[ (entry->ha[j]>>4)&15 ];
860 hbuffer[k++]=hexbuf[ entry->ha[j]&15 ];
861 hbuffer[k++]=':';
862 }
863 hbuffer[--k]=0;
864
865 #ifdef CONFIG_AX25
866 }
867 #endif
868 size = sprintf(buffer+len,
869 "%-17s0x%-10x0x%-10x%s\n",
870 in_ntoa(entry->ip),
871 (unsigned int)entry->htype,
872 entry->flags,
873 hbuffer);
874
875 len+=size;
876 pos=begin+len;
877
878 if(pos<offset)
879 {
880 len=0;
881 begin=pos;
882 }
883 if(pos>offset+length)
884 break;
885 }
886 }
887 sti();
888
889 *start=buffer+(offset-begin);
890 len-=(offset-begin);
891 if(len>length)
892 len=length;
893 return len;
894 }
895
896
897
898
899
900
901
902 static struct arp_table *arp_lookup(unsigned long paddr)
903 {
904 struct arp_table *entry;
905 unsigned long hash = HASH(paddr);
906
907 cli();
908 for (entry = arp_tables[hash]; entry != NULL; entry = entry->next)
909 if (entry->ip == paddr) break;
910 return entry;
911 }
912
913
914
915
916
917
918 static int arp_req_set(struct arpreq *req)
919 {
920 struct arpreq r;
921 struct arp_table *entry;
922 struct sockaddr_in *si;
923 int htype, hlen;
924 unsigned long ip, hash;
925 struct rtable *rt;
926
927 memcpy_fromfs(&r, req, sizeof(r));
928
929
930 if (r.arp_pa.sa_family != AF_INET)
931 return -EPFNOSUPPORT;
932
933
934
935
936
937
938
939 switch (r.arp_ha.sa_family) {
940 case ARPHRD_ETHER:
941 htype = ARPHRD_ETHER;
942 hlen = ETH_ALEN;
943 break;
944 #ifdef CONFIG_AX25
945 case ARPHRD_AX25:
946 htype = ARPHRD_AX25;
947 hlen = 7;
948 break;
949 #endif
950 default:
951 return -EPFNOSUPPORT;
952 }
953
954 si = (struct sockaddr_in *) &r.arp_pa;
955 ip = si->sin_addr.s_addr;
956 if (ip == 0)
957 {
958 printk("ARP: SETARP: requested PA is 0.0.0.0 !\n");
959 return -EINVAL;
960 }
961
962
963
964
965
966 rt = ip_rt_route(ip, NULL, NULL);
967 if (rt == NULL)
968 return -ENETUNREACH;
969
970
971
972
973
974 hash = HASH(ip);
975 cli();
976
977
978
979
980 for (entry = arp_tables[hash]; entry != NULL; entry = entry->next)
981 if (entry->ip == ip)
982 break;
983
984
985
986
987
988 if (entry == NULL)
989 {
990 entry = (struct arp_table *) kmalloc(sizeof(struct arp_table),
991 GFP_ATOMIC);
992 if (entry == NULL)
993 {
994 sti();
995 return -ENOMEM;
996 }
997 entry->ip = ip;
998 entry->hlen = hlen;
999 entry->htype = htype;
1000 entry->next = arp_tables[hash];
1001 arp_tables[hash] = entry;
1002 skb_queue_head_init(&entry->skb);
1003 }
1004 else
1005 if (entry->flags & ATF_PUBL)
1006 proxies--;
1007
1008
1009
1010
1011 memcpy(&entry->ha, &r.arp_ha.sa_data, hlen);
1012 entry->last_used = jiffies;
1013 entry->flags = r.arp_flags | ATF_COM;
1014 if (entry->flags & ATF_PUBL)
1015 proxies++;
1016 entry->dev = rt->rt_dev;
1017 sti();
1018
1019 return 0;
1020 }
1021
1022
1023
1024
1025
1026
1027 static int arp_req_get(struct arpreq *req)
1028 {
1029 struct arpreq r;
1030 struct arp_table *entry;
1031 struct sockaddr_in *si;
1032
1033
1034
1035
1036
1037 memcpy_fromfs(&r, req, sizeof(r));
1038
1039 if (r.arp_pa.sa_family != AF_INET)
1040 return -EPFNOSUPPORT;
1041
1042
1043
1044
1045
1046 si = (struct sockaddr_in *) &r.arp_pa;
1047 entry = arp_lookup(si->sin_addr.s_addr);
1048
1049 if (entry == NULL)
1050 {
1051 sti();
1052 return -ENXIO;
1053 }
1054
1055
1056
1057
1058
1059 memcpy(r.arp_ha.sa_data, &entry->ha, entry->hlen);
1060 r.arp_ha.sa_family = entry->htype;
1061 r.arp_flags = entry->flags;
1062 sti();
1063
1064
1065
1066
1067
1068 memcpy_tofs(req, &r, sizeof(r));
1069 return 0;
1070 }
1071
1072
1073
1074
1075
1076
1077 int arp_ioctl(unsigned int cmd, void *arg)
1078 {
1079 struct arpreq r;
1080 struct sockaddr_in *si;
1081 int err;
1082
1083 switch(cmd)
1084 {
1085 case SIOCDARP:
1086 if (!suser())
1087 return -EPERM;
1088 err = verify_area(VERIFY_READ, arg, sizeof(struct arpreq));
1089 if(err)
1090 return err;
1091 memcpy_fromfs(&r, arg, sizeof(r));
1092 if (r.arp_pa.sa_family != AF_INET)
1093 return -EPFNOSUPPORT;
1094 si = (struct sockaddr_in *) &r.arp_pa;
1095 arp_destroy(si->sin_addr.s_addr, 1);
1096 return 0;
1097 case SIOCGARP:
1098 err = verify_area(VERIFY_WRITE, arg, sizeof(struct arpreq));
1099 if(err)
1100 return err;
1101 return arp_req_get((struct arpreq *)arg);
1102 case SIOCSARP:
1103 if (!suser())
1104 return -EPERM;
1105 err = verify_area(VERIFY_READ, arg, sizeof(struct arpreq));
1106 if(err)
1107 return err;
1108 return arp_req_set((struct arpreq *)arg);
1109 default:
1110 return -EINVAL;
1111 }
1112
1113 return 0;
1114 }
1115
1116
1117
1118
1119
1120
1121 static struct packet_type arp_packet_type =
1122 {
1123 0,
1124 0,
1125 arp_rcv,
1126 NULL,
1127 NULL
1128 };
1129
1130 void arp_init (void)
1131 {
1132
1133 arp_packet_type.type=htons(ETH_P_ARP);
1134 dev_add_pack(&arp_packet_type);
1135
1136 add_timer(&arp_timer);
1137 }
1138