This source file includes following definitions.
- unk_print
- eth_aprint
- arp_print
- arp_send_q
- arp_response
- arp_lookup
- arp_lookup_proxy
- arp_destroy
- arp_create
- arp_rcv
- arp_send
- arp_find
- arp_add
- arp_add_broad
- arp_queue
- arp_get_info
- arp_req_set
- arp_req_get
- arp_req_del
- arp_ioctl
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 #include <linux/types.h>
54 #include <linux/string.h>
55 #include <linux/kernel.h>
56 #include <linux/sched.h>
57 #include <linux/config.h>
58 #include <linux/socket.h>
59 #include <linux/sockios.h>
60 #include <linux/errno.h>
61 #include <linux/if_arp.h>
62 #include <linux/in.h>
63 #include <asm/system.h>
64 #include <asm/segment.h>
65 #include <stdarg.h>
66 #include "inet.h"
67 #include "dev.h"
68 #include "eth.h"
69 #include "ip.h"
70 #include "route.h"
71 #include "protocol.h"
72 #include "tcp.h"
73 #include "skbuff.h"
74 #include "sock.h"
75 #include "arp.h"
76
77
78 #define ARP_MAX_TRIES 3
79
80
81 static char *unk_print(unsigned char *, int);
82 static char *eth_aprint(unsigned char *, int);
83
84
85 static char *arp_cmds[] = {
86 "0x%04X",
87 "REQUEST",
88 "REPLY",
89 "REVERSE REQUEST",
90 "REVERSE REPLY",
91 NULL
92 };
93 #define ARP_MAX_CMDS (sizeof(arp_cmds) / sizeof(arp_cmds[0]))
94
95 static struct {
96 char *name;
97 char *(*print)(unsigned char *ptr, int len);
98 } arp_types[] = {
99 { "0x%04X", unk_print },
100 { "10 Mbps Ethernet", eth_aprint },
101 { "3 Mbps Ethernet", eth_aprint },
102 { "AX.25", unk_print },
103 { "Pronet", unk_print },
104 { "Chaos", unk_print },
105 { "IEEE 802.2 Ethernet (?)", eth_aprint },
106 { "Arcnet", unk_print },
107 { "AppleTalk", unk_print },
108 { NULL, NULL }
109 };
110 #define ARP_MAX_TYPE (sizeof(arp_types) / sizeof(arp_types[0]))
111
112
113 struct arp_table *arp_tables[ARP_TABLE_SIZE] = {
114 NULL,
115 };
116
117 static int arp_proxies=0;
118
119
120
121 struct sk_buff * volatile arp_q = NULL;
122
123 static struct arp_table *arp_lookup(unsigned long addr);
124 static struct arp_table *arp_lookup_proxy(unsigned long addr);
125
126
127 static char *
128 unk_print(unsigned char *ptr, int len)
129 {
130 static char buff[32];
131 char *bufp = buff;
132 int i;
133
134 for (i = 0; i < len; i++)
135 bufp += sprintf(bufp, "%02X ", (*ptr++ & 0377));
136 return(buff);
137 }
138
139
140
141 static char *
142 eth_aprint(unsigned char *ptr, int len)
143 {
144 if (len != ETH_ALEN) return("");
145 return(eth_print(ptr));
146 }
147
148
149
150 static void
151 arp_print(struct arphdr *arp)
152 {
153 int len, idx;
154 unsigned char *ptr;
155
156 if (inet_debug != DBG_ARP) return;
157
158 printk("ARP: ");
159 if (arp == NULL) {
160 printk("(null)\n");
161 return;
162 }
163
164
165 len = htons(arp->ar_op);
166 if (len < ARP_MAX_CMDS) idx = len;
167 else idx = 0;
168 printk("op ");
169 printk(arp_cmds[idx], len);
170
171
172 len = htons(arp->ar_hrd);
173 if (len < ARP_MAX_TYPE) idx = len;
174 else idx = 0;
175 printk(" hrd = "); printk(arp_types[idx].name, len);
176 printk(" pro = 0x%04X\n", htons(arp->ar_pro));
177 printk(" hlen = %d plen = %d\n", arp->ar_hln, arp->ar_pln);
178
179
180
181
182
183
184
185 ptr = ((unsigned char *) &arp->ar_op) + sizeof(u_short);
186 printk(" sender HA = %s ", arp_types[idx].print(ptr, arp->ar_hln));
187 ptr += arp->ar_hln;
188 printk(" PA = %s\n", in_ntoa(*(unsigned long *) ptr));
189 ptr += arp->ar_pln;
190 printk(" target HA = %s ", arp_types[idx].print(ptr, arp->ar_hln));
191 ptr += arp->ar_hln;
192 printk(" PA = %s\n", in_ntoa(*(unsigned long *) ptr));
193 }
194
195
196
197 static void
198 arp_send_q(void)
199 {
200 struct sk_buff *skb;
201 struct sk_buff *volatile work_q;
202 cli();
203 work_q = arp_q;
204 skb_new_list_head(&work_q);
205 arp_q = NULL;
206 sti();
207 while((skb=skb_dequeue(&work_q))!=NULL)
208 {
209 IS_SKB(skb);
210 skb->magic = 0;
211 skb->next = NULL;
212 skb->prev = NULL;
213
214
215 cli();
216 skb->tries--;
217 if (skb->tries == 0) {
218
219
220
221
222
223
224
225
226
227 skb->sk = NULL;
228 if(skb->free)
229 kfree_skb(skb, FREE_WRITE);
230
231
232 sti();
233 continue;
234 }
235
236
237 sti();
238 if (skb->arp || !skb->dev->rebuild_header(skb+1, skb->dev)) {
239 skb->arp = 1;
240 skb->dev->queue_xmit(skb, skb->dev, 0);
241 } else {
242
243 skb->magic = ARP_QUEUE_MAGIC;
244 skb_queue_head(&arp_q,skb);
245 }
246 }
247 }
248
249
250
251 static int
252 arp_response(struct arphdr *arp1, struct device *dev, int addrtype)
253 {
254 struct arphdr *arp2;
255 struct sk_buff *skb;
256 unsigned long src, dst;
257 unsigned char *ptr1, *ptr2;
258 int hlen;
259 struct arp_table *apt = NULL;
260
261
262 ptr1 = ((unsigned char *) &arp1->ar_op) + sizeof(u_short);
263 src = *((unsigned long *) (ptr1 + arp1->ar_hln));
264 dst = *((unsigned long *) (ptr1 + (arp1->ar_hln * 2) + arp1->ar_pln));
265
266 if(addrtype!=IS_MYADDR)
267 {
268 apt=arp_lookup_proxy(dst);
269 if(apt==NULL)
270 return(1);
271 }
272
273
274 skb = alloc_skb(sizeof(struct sk_buff) +
275 sizeof(struct arphdr) +
276 (2 * arp1->ar_hln) + (2 * arp1->ar_pln) +
277 dev->hard_header_len, GFP_ATOMIC);
278 if (skb == NULL) {
279 printk("ARP: no memory available for ARP REPLY!\n");
280 return(1);
281 }
282
283 skb->mem_addr = skb;
284 skb->len = sizeof(struct arphdr) + (2 * arp1->ar_hln) +
285 (2 * arp1->ar_pln) + dev->hard_header_len;
286 skb->mem_len = sizeof(struct sk_buff) + skb->len;
287 hlen = dev->hard_header((unsigned char *)(skb+1), dev,
288 ETH_P_ARP, src, dst, skb->len);
289 if (hlen < 0) {
290 printk("ARP: cannot create HW frame header for REPLY !\n");
291 kfree_skb(skb, FREE_WRITE);
292 return(1);
293 }
294
295
296
297
298
299
300 arp2 = (struct arphdr *) ((unsigned char *) (skb+1) + hlen);
301 ptr2 = ((unsigned char *) &arp2->ar_op) + sizeof(u_short);
302 arp2->ar_hrd = arp1->ar_hrd;
303 arp2->ar_pro = arp1->ar_pro;
304 arp2->ar_hln = arp1->ar_hln;
305 arp2->ar_pln = arp1->ar_pln;
306 arp2->ar_op = htons(ARPOP_REPLY);
307 if(addrtype==IS_MYADDR)
308 memcpy(ptr2, dev->dev_addr, arp2->ar_hln);
309 else
310 memcpy(ptr2, apt->ha, arp2->ar_hln);
311 ptr2 += arp2->ar_hln;
312 memcpy(ptr2, ptr1 + (arp1->ar_hln * 2) + arp1->ar_pln, arp2->ar_pln);
313 ptr2 += arp2->ar_pln;
314 memcpy(ptr2, ptr1, arp2->ar_hln);
315 ptr2 += arp2->ar_hln;
316 memcpy(ptr2, ptr1 + arp1->ar_hln, arp2->ar_pln);
317
318 skb->free = 1;
319 skb->arp = 1;
320 skb->sk = NULL;
321 skb->next = NULL;
322
323 DPRINTF((DBG_ARP, ">>"));
324 arp_print(arp2);
325
326
327 dev->queue_xmit(skb, dev, 0);
328 return(0);
329 }
330
331
332
333 static struct arp_table *
334 arp_lookup(unsigned long paddr)
335 {
336 struct arp_table *apt;
337 unsigned long hash;
338
339 DPRINTF((DBG_ARP, "ARP: lookup(%s)\n", in_ntoa(paddr)));
340
341
342 if (chk_addr(paddr) == IS_MYADDR) {
343 printk("ARP: ARPing my own IP address %s !\n", in_ntoa(paddr));
344 return(NULL);
345 }
346
347
348 hash = htonl(paddr) & (ARP_TABLE_SIZE - 1);
349 cli();
350 apt = arp_tables[hash];
351 while(apt != NULL) {
352 if (apt->ip == paddr) {
353 sti();
354 return(apt);
355 }
356 apt = apt->next;
357 }
358 sti();
359 return(NULL);
360 }
361
362
363
364 static struct arp_table *arp_lookup_proxy(unsigned long paddr)
365 {
366 struct arp_table *apt;
367 unsigned long hash;
368
369 DPRINTF((DBG_ARP, "ARP: lookup proxy(%s)\n", in_ntoa(paddr)));
370
371
372 hash = htonl(paddr) & (ARP_TABLE_SIZE - 1);
373 cli();
374 apt = arp_tables[hash];
375 while(apt != NULL) {
376 if (apt->ip == paddr && (apt->flags & ATF_PUBL) ) {
377 sti();
378 return(apt);
379 }
380 apt = apt->next;
381 }
382 sti();
383 return(NULL);
384 }
385
386
387
388 void
389 arp_destroy(unsigned long paddr)
390 {
391 struct arp_table *apt;
392 struct arp_table **lapt;
393 unsigned long hash;
394
395 DPRINTF((DBG_ARP, "ARP: destroy(%s)\n", in_ntoa(paddr)));
396
397
398 if (chk_addr(paddr) == IS_MYADDR) {
399 DPRINTF((DBG_ARP, "ARP: Destroying my own IP address %s !\n",
400 in_ntoa(paddr)));
401 return;
402 }
403 hash = htonl(paddr) & (ARP_TABLE_SIZE - 1);
404
405 cli();
406 lapt = &arp_tables[hash];
407 while ((apt = *lapt) != NULL) {
408 if (apt->ip == paddr) {
409 *lapt = apt->next;
410 if(apt->flags&ATF_PUBL)
411 arp_proxies--;
412 kfree_s(apt, sizeof(struct arp_table));
413 sti();
414 return;
415 }
416 lapt = &apt->next;
417 }
418 sti();
419 }
420
421
422
423 static struct arp_table *
424 arp_create(unsigned long paddr, unsigned char *addr, int hlen, int htype)
425 {
426 struct arp_table *apt;
427 unsigned long hash;
428
429 DPRINTF((DBG_ARP, "ARP: create(%s, ", in_ntoa(paddr)));
430 DPRINTF((DBG_ARP, "%s, ", eth_print(addr)));
431 DPRINTF((DBG_ARP, "%d, %d)\n", hlen, htype));
432
433 apt = (struct arp_table *) kmalloc(sizeof(struct arp_table), GFP_ATOMIC);
434 if (apt == NULL) {
435 printk("ARP: no memory available for new ARP entry!\n");
436 return(NULL);
437 }
438
439
440 hash = htonl(paddr) & (ARP_TABLE_SIZE - 1);
441 apt->ip = paddr;
442 apt->hlen = hlen;
443 apt->htype = htype;
444 apt->flags = (ATF_INUSE | ATF_COM);
445 memcpy(apt->ha, addr, hlen);
446 apt->last_used = jiffies;
447 cli();
448 apt->next = arp_tables[hash];
449 arp_tables[hash] = apt;
450 sti();
451 return(apt);
452 }
453
454
455
456
457
458
459
460
461
462
463
464 int
465 arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
466 {
467 struct arphdr *arp;
468 struct arp_table *tbl;
469 unsigned long src, dst;
470 unsigned char *ptr;
471 int ret;
472 int addr_hint;
473
474 DPRINTF((DBG_ARP, "<<\n"));
475 arp = skb->h.arp;
476 arp_print(arp);
477
478
479 if (arp->ar_hln != dev->addr_len || dev->type != NET16(arp->ar_hrd))
480 {
481 DPRINTF((DBG_ARP,"ARP: Bad packet received on device \"%s\" !\n", dev->name));
482 kfree_skb(skb, FREE_READ);
483 return(0);
484 }
485
486
487 if (((arp->ar_pro != NET16(0x00CC) && dev->type==3) || (arp->ar_pro != NET16(ETH_P_IP) && dev->type!=3) ) || arp->ar_pln != 4)
488 {
489 if (arp->ar_op != NET16(ARPOP_REQUEST))
490 DPRINTF((DBG_ARP,"ARP: Non-IP request on device \"%s\" !\n", dev->name));
491 kfree_skb(skb, FREE_READ);
492 return(0);
493 }
494
495
496
497
498
499
500 ptr = ((unsigned char *) &arp->ar_op) + sizeof(u_short);
501 memcpy(&src, ptr + arp->ar_hln, arp->ar_pln);
502 tbl = arp_lookup(src);
503 if (tbl != NULL) {
504 DPRINTF((DBG_ARP, "ARP: udating entry for %s\n", in_ntoa(src)));
505 memcpy(tbl->ha, ptr, arp->ar_hln);
506 tbl->hlen = arp->ar_hln;
507 tbl->flags |= ATF_COM;
508 tbl->last_used = jiffies;
509 } else {
510 memcpy(&dst, ptr + (arp->ar_hln * 2) + arp->ar_pln, arp->ar_pln);
511 if (chk_addr(dst) != IS_MYADDR) {
512 kfree_skb(skb, FREE_READ);
513 return(0);
514 } else {
515 tbl = arp_create(src, ptr, arp->ar_hln, arp->ar_hrd);
516 if (tbl == NULL) {
517 kfree_skb(skb, FREE_READ);
518 return(0);
519 }
520 }
521 }
522
523
524
525
526
527
528 arp_send_q();
529
530
531
532
533
534 if (arp->ar_op != NET16(ARPOP_REQUEST)) {
535 kfree_skb(skb, FREE_READ);
536 return(0);
537 }
538
539
540
541
542
543 if((dst&0xFF)==0xFF)
544 {
545 kfree_skb(skb, FREE_READ);
546 return 0;
547 }
548
549 memcpy(&dst, ptr + (arp->ar_hln * 2) + arp->ar_pln, arp->ar_pln);
550 if ((addr_hint=chk_addr(dst)) != IS_MYADDR && arp_proxies==0) {
551 DPRINTF((DBG_ARP, "ARP: request was not for me!\n"));
552 kfree_skb(skb, FREE_READ);
553 return(0);
554 }
555
556
557
558
559
560 ret = arp_response(arp, dev, addr_hint);
561 kfree_skb(skb, FREE_READ);
562 return(ret);
563 }
564
565
566
567 void
568 arp_send(unsigned long paddr, struct device *dev, unsigned long saddr)
569 {
570 struct sk_buff *skb;
571 struct arphdr *arp;
572 unsigned char *ptr;
573 int tmp;
574
575 DPRINTF((DBG_ARP, "ARP: send(paddr=%s, ", in_ntoa(paddr)));
576 DPRINTF((DBG_ARP, "dev=%s, ", dev->name));
577 DPRINTF((DBG_ARP, "saddr=%s)\n", in_ntoa(saddr)));
578
579 skb = alloc_skb(sizeof(struct sk_buff) +
580 sizeof(struct arphdr) + (2 * dev->addr_len) +
581 dev->hard_header_len +
582 (2 * 4 ), GFP_ATOMIC);
583 if (skb == NULL) {
584 printk("ARP: No memory available for REQUEST %s\n", in_ntoa(paddr));
585 return;
586 }
587
588
589 skb->sk = NULL;
590 skb->mem_addr = skb;
591 skb->len = sizeof(struct arphdr) +
592 dev->hard_header_len + (2 * dev->addr_len) + 8;
593 skb->mem_len = sizeof(struct sk_buff) + skb->len;
594 skb->arp = 1;
595 skb->dev = dev;
596 skb->next = NULL;
597 skb->free = 1;
598 tmp = dev->hard_header((unsigned char *)(skb+1), dev,
599 ETH_P_ARP, 0, saddr, skb->len);
600 if (tmp < 0) {
601 kfree_skb(skb,FREE_WRITE);
602 return;
603 }
604 arp = (struct arphdr *) ((unsigned char *) (skb+1) + tmp);
605 arp->ar_hrd = htons(dev->type);
606 if(dev->type!=3)
607 arp->ar_pro = htons(ETH_P_IP);
608 else
609 arp->ar_pro = htons(0xCC);
610 arp->ar_hln = dev->addr_len;
611 arp->ar_pln = 4;
612 arp->ar_op = htons(ARPOP_REQUEST);
613
614 ptr = ((unsigned char *) &arp->ar_op) + sizeof(u_short);
615 memcpy(ptr, dev->dev_addr, arp->ar_hln);
616 ptr += arp->ar_hln;
617 memcpy(ptr, &saddr, arp->ar_pln);
618 ptr += arp->ar_pln;
619
620 memset(ptr,0,arp->ar_hln);
621 ptr += arp->ar_hln;
622 memcpy(ptr, &paddr, arp->ar_pln);
623
624 DPRINTF((DBG_ARP, ">>\n"));
625 arp_print(arp);
626 dev->queue_xmit(skb, dev, 0);
627 }
628
629
630
631 int
632 arp_find(unsigned char *haddr, unsigned long paddr, struct device *dev,
633 unsigned long saddr)
634 {
635 struct arp_table *apt;
636
637 DPRINTF((DBG_ARP, "ARP: find(haddr=%s, ", eth_print(haddr)));
638 DPRINTF((DBG_ARP, "paddr=%s, ", in_ntoa(paddr)));
639 DPRINTF((DBG_ARP, "dev=%s, saddr=%s)\n", dev->name, in_ntoa(saddr)));
640
641 switch(chk_addr(paddr)) {
642 case IS_MYADDR:
643 memcpy(haddr, dev->dev_addr, dev->addr_len);
644 return(0);
645 case IS_BROADCAST:
646 memcpy(haddr, dev->broadcast, dev->addr_len);
647 return(0);
648 }
649
650 apt = arp_lookup(paddr);
651 if (apt != NULL) {
652
653
654
655
656
657 if ((!(apt->flags & ATF_PERM)) ||
658 (!before(apt->last_used, jiffies+ARP_TIMEOUT) && apt->hlen != 0)) {
659 apt->last_used = jiffies;
660 memcpy(haddr, apt->ha, dev->addr_len);
661 return(0);
662 } else {
663 DPRINTF((DBG_ARP, "ARP: find: found expired entry for %s\n",
664 in_ntoa(apt->ip)));
665 }
666 }
667
668
669
670
671
672
673 *(unsigned long *)haddr = paddr;
674
675
676 arp_send(paddr, dev, saddr);
677
678 return(1);
679 }
680
681
682
683 void
684 arp_add(unsigned long addr, unsigned char *haddr, struct device *dev)
685 {
686 struct arp_table *apt;
687
688 DPRINTF((DBG_ARP, "ARP: add(%s, ", in_ntoa(addr)));
689 DPRINTF((DBG_ARP, "%s, ", eth_print(haddr)));
690 DPRINTF((DBG_ARP, "%d, %d)\n", dev->hard_header_len, dev->type));
691
692
693 if (addr == 0) {
694 printk("ARP: add: will not add entry for 0.0.0.0 !\n");
695 return;
696 }
697
698
699 apt = arp_lookup(addr);
700 if (apt != NULL) {
701 DPRINTF((DBG_ARP, "ARP: updating entry for %s\n", in_ntoa(addr)));
702 apt->last_used = jiffies;
703 memcpy(apt->ha, haddr , dev->addr_len);
704 return;
705 }
706 arp_create(addr, haddr, dev->addr_len, dev->type);
707 }
708
709
710
711 void
712 arp_add_broad(unsigned long addr, struct device *dev)
713 {
714 struct arp_table *apt;
715
716 arp_add(addr, dev->broadcast, dev);
717 apt = arp_lookup(addr);
718 if (apt != NULL) {
719 apt->flags |= ATF_PERM;
720 }
721 }
722
723
724
725 void
726 arp_queue(struct sk_buff *skb)
727 {
728 cli();
729 skb->tries = ARP_MAX_TRIES;
730
731 if (skb->next != NULL) {
732 sti();
733 printk("ARP: arp_queue skb already on queue magic=%X.\n", skb->magic);
734 return;
735 }
736 skb_queue_tail(&arp_q,skb);
737 skb->magic = ARP_QUEUE_MAGIC;
738 sti();
739 }
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757 int
758 arp_get_info(char *buffer)
759 {
760 struct arpreq *req;
761 struct arp_table *apt;
762 int i;
763 char *pos;
764
765
766 pos = buffer;
767 i = 0;
768 for (i = 0; i < ARP_TABLE_SIZE; i++) {
769 cli();
770 apt = arp_tables[i];
771 sti();
772 while (apt != NULL) {
773 if (pos < (buffer + 4000)) {
774 req = (struct arpreq *) pos;
775 memset((char *) req, 0, sizeof(struct arpreq));
776 req->arp_pa.sa_family = AF_INET;
777 memcpy((char *) req->arp_pa.sa_data, (char *) &apt->ip, 4);
778 req->arp_ha.sa_family = apt->htype;
779 memcpy((char *) req->arp_ha.sa_data,
780 (char *) &apt->ha, apt->hlen);
781 }
782 pos += sizeof(struct arpreq);
783 cli();
784 apt = apt->next;
785 sti();
786 }
787 }
788 return(pos - buffer);
789 }
790
791
792
793 static int
794 arp_req_set(struct arpreq *req)
795 {
796 struct arpreq r;
797 struct arp_table *apt;
798 struct sockaddr_in *si;
799 int htype, hlen;
800
801
802 memcpy_fromfs(&r, req, sizeof(r));
803 if (r.arp_pa.sa_family != AF_INET) return(-EPFNOSUPPORT);
804
805
806
807
808
809
810 si = (struct sockaddr_in *) &r.arp_pa;
811 switch(r.arp_ha.sa_family) {
812 case 0:
813 case ARPHRD_ETHER:
814 htype = ARPHRD_ETHER;
815 hlen = ETH_ALEN;
816 break;
817 default:
818 return(-EPFNOSUPPORT);
819 }
820
821
822 if (si->sin_addr.s_addr == 0) {
823 printk("ARP: SETARP: requested PA is 0.0.0.0 !\n");
824 return(-EINVAL);
825 }
826 apt = arp_lookup(si->sin_addr.s_addr);
827 if (apt == NULL) {
828 apt = arp_create(si->sin_addr.s_addr,
829 (unsigned char *) r.arp_ha.sa_data, hlen, htype);
830 if (apt == NULL) return(-ENOMEM);
831 }
832
833
834 memcpy((char *) &apt->ha, (char *) &r.arp_ha.sa_data, hlen);
835 apt->last_used = jiffies;
836 apt->flags = r.arp_flags;
837 if(apt->flags&ATF_PUBL)
838 arp_proxies++;
839
840 return(0);
841 }
842
843
844
845 static int
846 arp_req_get(struct arpreq *req)
847 {
848 struct arpreq r;
849 struct arp_table *apt;
850 struct sockaddr_in *si;
851
852
853 memcpy_fromfs(&r, req, sizeof(r));
854 if (r.arp_pa.sa_family != AF_INET) return(-EPFNOSUPPORT);
855
856
857 si = (struct sockaddr_in *) &r.arp_pa;
858 apt = arp_lookup(si->sin_addr.s_addr);
859 if (apt == NULL) return(-ENXIO);
860
861
862 memcpy((char *) r.arp_ha.sa_data, (char *) &apt->ha, apt->hlen);
863 r.arp_ha.sa_family = apt->htype;
864
865
866 memcpy_tofs(req, &r, sizeof(r));
867 return(0);
868 }
869
870
871
872 static int
873 arp_req_del(struct arpreq *req)
874 {
875 struct arpreq r;
876 struct sockaddr_in *si;
877
878
879 memcpy_fromfs(&r, req, sizeof(r));
880 if (r.arp_pa.sa_family != AF_INET) return(-EPFNOSUPPORT);
881
882 si = (struct sockaddr_in *) &r.arp_pa;
883
884
885
886 if(chk_addr(si->sin_addr.s_addr)==IS_MYADDR)
887 return -EINVAL;
888
889 arp_destroy(si->sin_addr.s_addr);
890
891 return(0);
892 }
893
894
895
896 int
897 arp_ioctl(unsigned int cmd, void *arg)
898 {
899 int err;
900 switch(cmd) {
901 case DDIOCSDBG:
902 return(dbg_ioctl(arg, DBG_ARP));
903 case SIOCDARP:
904 if (!suser()) return(-EPERM);
905 err=verify_area(VERIFY_READ,arg,sizeof(struct arpreq));
906 if(err)
907 return err;
908 return(arp_req_del((struct arpreq *)arg));
909 case SIOCGARP:
910 err=verify_area(VERIFY_WRITE,arg,sizeof(struct arpreq));
911 if(err)
912 return err;
913 return(arp_req_get((struct arpreq *)arg));
914 case SIOCSARP:
915 if (!suser()) return(-EPERM);
916 err=verify_area(VERIFY_READ,arg,sizeof(struct arpreq));
917 if(err)
918 return err;
919 return(arp_req_set((struct arpreq *)arg));
920 default:
921 return(-EINVAL);
922 }
923
924 return(0);
925 }