This source file includes following definitions.
- min
- get_mask
- ip_addr_match
- chk_addr
- my_addr
- dev_add_pack
- dev_remove_pack
- dev_get
- dev_check
- dev_open
- dev_close
- dev_queue_xmit
- netif_rx
- dev_rint
- dev_transmit
- in_inet_bh
- inet_bh
- dev_tint
- dev_ifconf
- sprintf_stats
- dev_get_info
- bad_mask
- dev_ifsioc
- dev_ioctl
- dev_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
33
34
35
36
37
38
39 #include <asm/segment.h>
40 #include <asm/system.h>
41 #include <asm/bitops.h>
42 #include <linux/config.h>
43 #include <linux/types.h>
44 #include <linux/kernel.h>
45 #include <linux/sched.h>
46 #include <linux/string.h>
47 #include <linux/mm.h>
48 #include <linux/socket.h>
49 #include <linux/sockios.h>
50 #include <linux/in.h>
51 #include <linux/errno.h>
52 #include <linux/interrupt.h>
53 #include <linux/if_ether.h>
54 #include "inet.h"
55 #include "dev.h"
56 #include "eth.h"
57 #include "ip.h"
58 #include "route.h"
59 #include "protocol.h"
60 #include "tcp.h"
61 #include "skbuff.h"
62 #include "sock.h"
63 #include "arp.h"
64 #ifdef CONFIG_AX25
65 #include "ax25.h"
66 #endif
67
68
69 #ifdef CONFIG_IPX
70
71 static struct packet_type ipx_8023_type = {
72 NET16(ETH_P_802_3),
73 0,
74 ipx_rcv,
75 NULL,
76 NULL
77 };
78
79 static struct packet_type ipx_packet_type = {
80 NET16(ETH_P_IPX),
81 0,
82 ipx_rcv,
83 NULL,
84 &ipx_8023_type
85 };
86
87 #endif
88
89 #ifdef CONFIG_AX25
90
91 static struct packet_type ax25_packet_type = {
92 NET16(ETH_P_AX25),
93 0,
94 ax25_rcv,
95 NULL,
96 #ifdef CONFIG_IPX
97 &ipx_packet_type
98 #else
99 NULL
100 #endif
101 };
102 #endif
103
104
105 static struct packet_type arp_packet_type = {
106 NET16(ETH_P_ARP),
107 0,
108 arp_rcv,
109 NULL,
110 #ifdef CONFIG_IPX
111 #ifndef CONFIG_AX25
112 &ipx_packet_type
113 #else
114 &ax25_packet_type
115 #endif
116 #else
117 #ifdef CONFIG_AX25
118 &ax25_packet_type
119 #else
120 NULL
121 #endif
122 #endif
123 };
124
125
126 static struct packet_type ip_packet_type = {
127 NET16(ETH_P_IP),
128 0,
129 ip_rcv,
130 NULL,
131 &arp_packet_type
132 };
133
134
135 struct packet_type *ptype_base = &ip_packet_type;
136 static struct sk_buff *volatile backlog = NULL;
137 static int backlog_size = 0;
138 static unsigned long ip_bcast = 0;
139
140
141
142 static unsigned long
143 min(unsigned long a, unsigned long b)
144 {
145 if (a < b) return(a);
146 return(b);
147 }
148
149
150
151 static unsigned long
152 get_mask(unsigned long addr)
153 {
154 unsigned long dst;
155
156 if (addr == 0L)
157 return(0L);
158
159 dst = ntohl(addr);
160 if (IN_CLASSA(dst))
161 return(htonl(IN_CLASSA_NET));
162 if (IN_CLASSB(dst))
163 return(htonl(IN_CLASSB_NET));
164 if (IN_CLASSC(dst))
165 return(htonl(IN_CLASSC_NET));
166
167
168 return(0);
169 }
170
171
172 int
173 ip_addr_match(unsigned long me, unsigned long him)
174 {
175 int i;
176 unsigned long mask=0xFFFFFFFF;
177 DPRINTF((DBG_DEV, "ip_addr_match(%s, ", in_ntoa(me)));
178 DPRINTF((DBG_DEV, "%s)\n", in_ntoa(him)));
179
180 if (me == him)
181 return(1);
182 for (i = 0; i < 4; i++, me >>= 8, him >>= 8, mask >>= 8) {
183 if ((me & 0xFF) != (him & 0xFF)) {
184
185
186
187
188 if (me != 0 && me != mask) return(0);
189 return(1);
190 }
191 }
192 return(1);
193 }
194
195
196
197 int chk_addr(unsigned long addr)
198 {
199 struct device *dev;
200 unsigned long mask;
201
202
203 if (addr == INADDR_ANY || addr == INADDR_BROADCAST)
204 return IS_BROADCAST;
205
206 mask = get_mask(addr);
207
208
209 if ((addr & mask) == htonl(0x7F000000L))
210 return IS_MYADDR;
211
212
213 for (dev = dev_base; dev != NULL; dev = dev->next) {
214 if (!(dev->flags & IFF_UP))
215 continue;
216 if ((dev->pa_addr == 0))
217 return IS_MYADDR;
218
219 if (addr == dev->pa_addr)
220 return IS_MYADDR;
221
222 if ((dev->flags & IFF_BROADCAST) && addr == dev->pa_brdaddr)
223 return IS_BROADCAST;
224
225 if (((addr ^ dev->pa_addr) & dev->pa_mask) == 0) {
226 if ((addr & ~dev->pa_mask) == 0)
227 return IS_BROADCAST;
228 if ((addr & ~dev->pa_mask) == ~dev->pa_mask)
229 return IS_BROADCAST;
230 }
231
232 if (((addr ^ dev->pa_addr) & mask) == 0) {
233 if ((addr & ~mask) == 0)
234 return IS_BROADCAST;
235 if ((addr & ~mask) == ~mask)
236 return IS_BROADCAST;
237 }
238 }
239 return 0;
240 }
241
242
243
244
245
246
247
248
249
250
251 unsigned long
252 my_addr(void)
253 {
254 struct device *dev;
255
256 for (dev = dev_base; dev != NULL; dev = dev->next) {
257 if (dev->flags & IFF_LOOPBACK) return(dev->pa_addr);
258 }
259 return(0);
260 }
261
262
263 static int dev_nit=0;
264
265
266 void
267 dev_add_pack(struct packet_type *pt)
268 {
269 struct packet_type *p1;
270 pt->next = ptype_base;
271
272
273
274
275 pt->copy=0;
276 if(pt->type==NET16(ETH_P_ALL))
277 dev_nit++;
278 else
279 {
280
281 for (p1 = ptype_base; p1 != NULL; p1 = p1->next) {
282 if (p1->type == pt->type) {
283 pt->copy = 1;
284 break;
285 }
286 }
287 }
288
289
290
291
292
293 if(pt->type==NET16(ETH_P_ALL))
294 {
295 pt->next=NULL;
296 if(ptype_base==NULL)
297 ptype_base=pt;
298 else
299 {
300 for(p1=ptype_base;p1->next!=NULL;p1=p1->next);
301 p1->next=pt;
302 }
303 }
304 else
305 ptype_base = pt;
306 }
307
308
309
310 void
311 dev_remove_pack(struct packet_type *pt)
312 {
313 struct packet_type *lpt, *pt1;
314
315 if (pt->type == NET16(ETH_P_ALL))
316 dev_nit--;
317 if (pt == ptype_base) {
318 ptype_base = pt->next;
319 return;
320 }
321
322 lpt = NULL;
323 for (pt1 = ptype_base; pt1->next != NULL; pt1 = pt1->next) {
324 if (pt1->next == pt ) {
325 cli();
326 if (!pt->copy && lpt)
327 lpt->copy = 0;
328 pt1->next = pt->next;
329 sti();
330 return;
331 }
332
333 if (pt1->next -> type == pt ->type && pt->type != NET16(ETH_P_ALL)) {
334 lpt = pt1->next;
335 }
336 }
337 }
338
339
340
341 struct device *
342 dev_get(char *name)
343 {
344 struct device *dev;
345
346 for (dev = dev_base; dev != NULL; dev = dev->next) {
347 if (strcmp(dev->name, name) == 0)
348 return(dev);
349 }
350 return(NULL);
351 }
352
353
354
355 struct device * dev_check(unsigned long addr)
356 {
357 struct device *dev;
358
359 for (dev = dev_base; dev; dev = dev->next) {
360 if (!(dev->flags & IFF_UP))
361 continue;
362 if (!(dev->flags & IFF_POINTOPOINT))
363 continue;
364 if (addr != dev->pa_dstaddr)
365 continue;
366 return dev;
367 }
368 for (dev = dev_base; dev; dev = dev->next) {
369 if (!(dev->flags & IFF_UP))
370 continue;
371 if (dev->flags & IFF_POINTOPOINT)
372 continue;
373 if (dev->pa_mask & (addr ^ dev->pa_addr))
374 continue;
375 return dev;
376 }
377 return NULL;
378 }
379
380
381
382 int
383 dev_open(struct device *dev)
384 {
385 int ret = 0;
386
387 if (dev->open)
388 ret = dev->open(dev);
389 if (ret == 0)
390 dev->flags |= (IFF_UP | IFF_RUNNING);
391
392 return(ret);
393 }
394
395
396
397 int
398 dev_close(struct device *dev)
399 {
400 if (dev->flags != 0) {
401 int ct=0;
402 dev->flags = 0;
403 if (dev->stop)
404 dev->stop(dev);
405 rt_flush(dev);
406 dev->pa_addr = 0;
407 dev->pa_dstaddr = 0;
408 dev->pa_brdaddr = 0;
409 dev->pa_mask = 0;
410
411 while(ct<DEV_NUMBUFFS)
412 {
413 struct sk_buff *skb;
414 while((skb=skb_dequeue(&dev->buffs[ct]))!=NULL)
415 if(skb->free)
416 kfree_skb(skb,FREE_WRITE);
417 ct++;
418 }
419 }
420
421 return(0);
422 }
423
424
425
426 void
427 dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri)
428 {
429 int where = 0;
430
431
432
433 DPRINTF((DBG_DEV, "dev_queue_xmit(skb=%X, dev=%X, pri = %d)\n",
434 skb, dev, pri));
435
436 if (dev == NULL) {
437 printk("dev.c: dev_queue_xmit: dev = NULL\n");
438 return;
439 }
440
441 IS_SKB(skb);
442
443 skb->dev = dev;
444 if (skb->next != NULL) {
445
446 dev->hard_start_xmit(NULL, dev);
447 return;
448 }
449
450 if (pri < 0) {
451 pri = -pri-1;
452 where = 1;
453 }
454
455 if (pri >= DEV_NUMBUFFS) {
456 printk("bad priority in dev_queue_xmit.\n");
457 pri = 1;
458 }
459
460 if (dev->hard_start_xmit(skb, dev) == 0) {
461 return;
462 }
463
464
465 DPRINTF((DBG_DEV, "dev_queue_xmit dev->buffs[%d]=%X\n",
466 pri, dev->buffs[pri]));
467
468
469 cli();
470 skb->magic = DEV_QUEUE_MAGIC;
471 if(where)
472 skb_queue_head(&dev->buffs[pri],skb);
473 else
474 skb_queue_tail(&dev->buffs[pri],skb);
475 skb->magic = DEV_QUEUE_MAGIC;
476 sti();
477 }
478
479
480
481
482
483 void
484 netif_rx(struct sk_buff *skb)
485 {
486 static int dropping = 0;
487
488 skb->sk = NULL;
489 skb->free = 1;
490
491
492 if (!backlog_size)
493 dropping = 0;
494 else if (backlog_size > 100)
495 dropping = 1;
496 if (dropping) {
497 kfree_skb(skb, FREE_READ);
498 return;
499 }
500
501 IS_SKB(skb);
502 skb_queue_tail(&backlog,skb);
503 backlog_size++;
504
505
506 if (backlog != NULL) mark_bh(INET_BH);
507
508 return;
509 }
510
511
512
513
514
515
516
517
518
519
520
521
522 int
523 dev_rint(unsigned char *buff, long len, int flags, struct device *dev)
524 {
525 static int dropping = 0;
526 struct sk_buff *skb = NULL;
527 unsigned char *to;
528 int amount, left;
529 int len2;
530
531 if (dev == NULL || buff == NULL || len <= 0) return(1);
532 if (flags & IN_SKBUFF) {
533 skb = (struct sk_buff *) buff;
534 } else {
535 if (dropping) {
536 if (backlog != NULL)
537 return(1);
538 printk("INET: dev_rint: no longer dropping packets.\n");
539 dropping = 0;
540 }
541
542 skb = alloc_skb(sizeof(*skb) + len, GFP_ATOMIC);
543 if (skb == NULL) {
544 printk("dev_rint: packet dropped on %s (no memory) !\n",
545 dev->name);
546 dropping = 1;
547 return(1);
548 }
549 skb->mem_len = sizeof(*skb) + len;
550 skb->mem_addr = (struct sk_buff *) skb;
551
552
553 to = skb->data;
554 left = len;
555 len2 = len;
556 while (len2 > 0) {
557 amount = min(len2, (unsigned long) dev->rmem_end -
558 (unsigned long) buff);
559 memcpy(to, buff, amount);
560 len2 -= amount;
561 left -= amount;
562 buff += amount;
563 to += amount;
564 if ((unsigned long) buff == dev->rmem_end)
565 buff = (unsigned char *) dev->rmem_start;
566 }
567 }
568 skb->len = len;
569 skb->dev = dev;
570 skb->free = 1;
571
572 netif_rx(skb);
573
574 return(0);
575 }
576
577
578
579 void
580 dev_transmit(void)
581 {
582 struct device *dev;
583
584 for (dev = dev_base; dev != NULL; dev = dev->next) {
585 if (!dev->tbusy) {
586 dev_tint(dev);
587 }
588 }
589 }
590
591 static volatile char in_bh = 0;
592
593 int in_inet_bh()
594 {
595 return(in_bh==0?0:1);
596 }
597
598
599
600
601
602
603 void
604 inet_bh(void *tmp)
605 {
606 struct sk_buff *skb;
607 struct packet_type *ptype;
608 unsigned short type;
609 unsigned char flag = 0;
610 int nitcount;
611
612
613 if (set_bit(1, (void*)&in_bh))
614 return;
615
616
617 dev_transmit();
618
619
620 while((skb=skb_dequeue(&backlog))!=NULL)
621 {
622 backlog_size--;
623 nitcount=dev_nit;
624 flag=0;
625 sti();
626
627
628
629
630
631
632 skb->h.raw = skb->data + skb->dev->hard_header_len;
633 skb->len -= skb->dev->hard_header_len;
634
635
636
637
638
639
640
641
642
643
644 type = skb->dev->type_trans(skb, skb->dev);
645
646
647
648
649
650
651
652 for (ptype = ptype_base; ptype != NULL; ptype = ptype->next) {
653 if (ptype->type == type || ptype->type == NET16(ETH_P_ALL)) {
654 struct sk_buff *skb2;
655
656 if (ptype->type==NET16(ETH_P_ALL))
657 nitcount--;
658 if (ptype->copy || nitcount) {
659 skb2 = alloc_skb(skb->mem_len, GFP_ATOMIC);
660 if (skb2 == NULL)
661 continue;
662 memcpy(skb2, (const void *) skb, skb->mem_len);
663 skb2->mem_addr = skb2;
664 skb2->h.raw = (unsigned char *)(
665 (unsigned long) skb2 +
666 (unsigned long) skb->h.raw -
667 (unsigned long) skb
668 );
669 skb2->free = 1;
670 } else {
671 skb2 = skb;
672 }
673
674
675
676
677
678 flag = 1;
679
680
681 ptype->func(skb2, skb->dev, ptype);
682 }
683 }
684
685
686
687
688
689 if (!flag) {
690 DPRINTF((DBG_DEV,
691 "INET: unknown packet type 0x%04X (ignored)\n", type));
692 skb->sk = NULL;
693 kfree_skb(skb, FREE_WRITE);
694 }
695
696
697 dev_transmit();
698 cli();
699 }
700 in_bh = 0;
701 sti();
702 dev_transmit();
703 }
704
705
706
707
708
709
710
711 void dev_tint(struct device *dev)
712 {
713 int i;
714 struct sk_buff *skb;
715
716 for(i = 0;i < DEV_NUMBUFFS; i++) {
717 while((skb=skb_dequeue(&dev->buffs[i]))!=NULL)
718 {
719 skb->magic = 0;
720 skb->next = NULL;
721 skb->prev = NULL;
722 dev->queue_xmit(skb,dev,-i - 1);
723 if (dev->tbusy)
724 return;
725 }
726 }
727 }
728
729
730
731 static int
732 dev_ifconf(char *arg)
733 {
734 struct ifconf ifc;
735 struct ifreq ifr;
736 struct device *dev;
737 char *pos;
738 int len;
739 int err;
740
741
742 err=verify_area(VERIFY_WRITE, arg, sizeof(struct ifconf));
743 if(err)
744 return err;
745 memcpy_fromfs(&ifc, arg, sizeof(struct ifconf));
746 len = ifc.ifc_len;
747 pos = ifc.ifc_buf;
748
749
750 for (dev = dev_base; dev != NULL; dev = dev->next) {
751 if(!(dev->flags & IFF_UP))
752 continue;
753 memset(&ifr, 0, sizeof(struct ifreq));
754 strcpy(ifr.ifr_name, dev->name);
755 (*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = dev->family;
756 (*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
757
758
759 memcpy_tofs(pos, &ifr, sizeof(struct ifreq));
760 pos += sizeof(struct ifreq);
761 len -= sizeof(struct ifreq);
762 if (len < sizeof(struct ifreq)) break;
763 }
764
765
766 ifc.ifc_len = (pos - ifc.ifc_buf);
767 ifc.ifc_req = (struct ifreq *) ifc.ifc_buf;
768 memcpy_tofs(arg, &ifc, sizeof(struct ifconf));
769 return(pos - arg);
770 }
771
772
773 char *sprintf_stats(char *buffer, struct device *dev)
774 {
775 char *pos = buffer;
776 struct enet_statistics *stats = (dev->get_stats ? dev->get_stats(dev): NULL);
777
778 if (stats)
779 pos += sprintf(pos, "%6s:%7d %4d %4d %4d %4d %8d %4d %4d %4d %5d %4d\n",
780 dev->name,
781 stats->rx_packets, stats->rx_errors,
782 stats->rx_dropped + stats->rx_missed_errors,
783 stats->rx_fifo_errors,
784 stats->rx_length_errors + stats->rx_over_errors
785 + stats->rx_crc_errors + stats->rx_frame_errors,
786 stats->tx_packets, stats->tx_errors, stats->tx_dropped,
787 stats->tx_fifo_errors, stats->collisions,
788 stats->tx_carrier_errors + stats->tx_aborted_errors
789 + stats->tx_window_errors + stats->tx_heartbeat_errors);
790 else
791 pos += sprintf(pos, "%6s: No statistics available.\n", dev->name);
792
793 return pos;
794 }
795
796
797 int
798 dev_get_info(char *buffer)
799 {
800 char *pos = buffer;
801 struct device *dev;
802
803 pos +=
804 sprintf(pos,
805 "Inter-| Receive | Transmit\n"
806 " face |packets errs drop fifo frame|packets errs drop fifo colls carrier\n");
807 for (dev = dev_base; dev != NULL; dev = dev->next) {
808 pos = sprintf_stats(pos, dev);
809 }
810 return pos - buffer;
811 }
812
813 static inline int bad_mask(unsigned long mask, unsigned long addr)
814 {
815 if (addr & (mask = ~mask))
816 return 1;
817 mask = ntohl(mask);
818 if (mask & (mask+1))
819 return 1;
820 return 0;
821 }
822
823
824
825 static int
826 dev_ifsioc(void *arg, unsigned int getset)
827 {
828 struct ifreq ifr;
829 struct device *dev;
830 int ret;
831
832
833 int err=verify_area(VERIFY_WRITE, arg, sizeof(struct ifreq));
834 if(err)
835 return err;
836 memcpy_fromfs(&ifr, arg, sizeof(struct ifreq));
837
838
839 if ((dev = dev_get(ifr.ifr_name)) == NULL) return(-EINVAL);
840
841 switch(getset) {
842 case SIOCGIFFLAGS:
843 ifr.ifr_flags = dev->flags;
844 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
845 ret = 0;
846 break;
847 case SIOCSIFFLAGS:
848 {
849 int old_flags = dev->flags;
850 dev->flags = ifr.ifr_flags & (
851 IFF_UP | IFF_BROADCAST | IFF_DEBUG | IFF_LOOPBACK |
852 IFF_POINTOPOINT | IFF_NOTRAILERS | IFF_RUNNING |
853 IFF_NOARP | IFF_PROMISC | IFF_ALLMULTI);
854
855 if ( (old_flags & IFF_PROMISC) && ((dev->flags & IFF_PROMISC) == 0))
856 dev->set_multicast_list(dev,0,NULL);
857 if ( (dev->flags & IFF_PROMISC) && ((old_flags & IFF_PROMISC) == 0))
858 dev->set_multicast_list(dev,-1,NULL);
859 if ((old_flags & IFF_UP) && ((dev->flags & IFF_UP) == 0)) {
860 ret = dev_close(dev);
861 } else
862 {
863 ret = (! (old_flags & IFF_UP) && (dev->flags & IFF_UP))
864 ? dev_open(dev) : 0;
865 if(ret<0)
866 dev->flags&=~IFF_UP;
867 }
868 }
869 break;
870 case SIOCGIFADDR:
871 (*(struct sockaddr_in *)
872 &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
873 (*(struct sockaddr_in *)
874 &ifr.ifr_addr).sin_family = dev->family;
875 (*(struct sockaddr_in *)
876 &ifr.ifr_addr).sin_port = 0;
877 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
878 ret = 0;
879 break;
880 case SIOCSIFADDR:
881 dev->pa_addr = (*(struct sockaddr_in *)
882 &ifr.ifr_addr).sin_addr.s_addr;
883 dev->family = ifr.ifr_addr.sa_family;
884 dev->pa_mask = get_mask(dev->pa_addr);
885 dev->pa_brdaddr = dev->pa_addr | ~dev->pa_mask;
886 ret = 0;
887 break;
888 case SIOCGIFBRDADDR:
889 (*(struct sockaddr_in *)
890 &ifr.ifr_broadaddr).sin_addr.s_addr = dev->pa_brdaddr;
891 (*(struct sockaddr_in *)
892 &ifr.ifr_broadaddr).sin_family = dev->family;
893 (*(struct sockaddr_in *)
894 &ifr.ifr_broadaddr).sin_port = 0;
895 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
896 ret = 0;
897 break;
898 case SIOCSIFBRDADDR:
899 dev->pa_brdaddr = (*(struct sockaddr_in *)
900 &ifr.ifr_broadaddr).sin_addr.s_addr;
901 ret = 0;
902 break;
903 case SIOCGIFDSTADDR:
904 (*(struct sockaddr_in *)
905 &ifr.ifr_dstaddr).sin_addr.s_addr = dev->pa_dstaddr;
906 (*(struct sockaddr_in *)
907 &ifr.ifr_broadaddr).sin_family = dev->family;
908 (*(struct sockaddr_in *)
909 &ifr.ifr_broadaddr).sin_port = 0;
910 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
911 ret = 0;
912 break;
913 case SIOCSIFDSTADDR:
914 dev->pa_dstaddr = (*(struct sockaddr_in *)
915 &ifr.ifr_dstaddr).sin_addr.s_addr;
916 ret = 0;
917 break;
918 case SIOCGIFNETMASK:
919 (*(struct sockaddr_in *)
920 &ifr.ifr_netmask).sin_addr.s_addr = dev->pa_mask;
921 (*(struct sockaddr_in *)
922 &ifr.ifr_netmask).sin_family = dev->family;
923 (*(struct sockaddr_in *)
924 &ifr.ifr_netmask).sin_port = 0;
925 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
926 ret = 0;
927 break;
928 case SIOCSIFNETMASK: {
929 unsigned long mask = (*(struct sockaddr_in *)
930 &ifr.ifr_netmask).sin_addr.s_addr;
931 ret = -EINVAL;
932 if (bad_mask(mask,0))
933 break;
934 dev->pa_mask = mask;
935 ret = 0;
936 break;
937 }
938 case SIOCGIFMETRIC:
939 ifr.ifr_metric = dev->metric;
940 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
941 ret = 0;
942 break;
943 case SIOCSIFMETRIC:
944 dev->metric = ifr.ifr_metric;
945 ret = 0;
946 break;
947 case SIOCGIFMTU:
948 ifr.ifr_mtu = dev->mtu;
949 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
950 ret = 0;
951 break;
952 case SIOCSIFMTU:
953 dev->mtu = ifr.ifr_mtu;
954 ret = 0;
955 break;
956 case SIOCGIFMEM:
957 printk("NET: ioctl(SIOCGIFMEM, 0x%08X)\n", (int)arg);
958 ret = -EINVAL;
959 break;
960 case SIOCSIFMEM:
961 printk("NET: ioctl(SIOCSIFMEM, 0x%08X)\n", (int)arg);
962 ret = -EINVAL;
963 break;
964 case SIOCGIFHWADDR:
965 memcpy(ifr.ifr_hwaddr,dev->dev_addr, MAX_ADDR_LEN);
966 memcpy_tofs(arg,&ifr,sizeof(struct ifreq));
967 ret=0;
968 break;
969 default:
970 ret = -EINVAL;
971 }
972 return(ret);
973 }
974
975
976
977 int
978 dev_ioctl(unsigned int cmd, void *arg)
979 {
980 struct iflink iflink;
981 struct ddi_device *dev;
982
983 switch(cmd) {
984 case IP_SET_DEV:
985 printk("Your network configuration program needs upgrading.\n");
986 return -EINVAL;
987
988 case SIOCGIFCONF:
989 (void) dev_ifconf((char *) arg);
990 return 0;
991
992 case SIOCGIFFLAGS:
993 case SIOCGIFADDR:
994 case SIOCGIFDSTADDR:
995 case SIOCGIFBRDADDR:
996 case SIOCGIFNETMASK:
997 case SIOCGIFMETRIC:
998 case SIOCGIFMTU:
999 case SIOCGIFMEM:
1000 case SIOCGIFHWADDR:
1001 return dev_ifsioc(arg, cmd);
1002
1003 case SIOCSIFFLAGS:
1004 case SIOCSIFADDR:
1005 case SIOCSIFDSTADDR:
1006 case SIOCSIFBRDADDR:
1007 case SIOCSIFNETMASK:
1008 case SIOCSIFMETRIC:
1009 case SIOCSIFMTU:
1010 case SIOCSIFMEM:
1011 if (!suser())
1012 return -EPERM;
1013 return dev_ifsioc(arg, cmd);
1014
1015 case SIOCSIFLINK:
1016 if (!suser())
1017 return -EPERM;
1018 memcpy_fromfs(&iflink, arg, sizeof(iflink));
1019 dev = ddi_map(iflink.id);
1020 if (dev == NULL)
1021 return -EINVAL;
1022
1023
1024 printk("AF_INET: DDI \"%s\" linked to stream \"%s\"\n",
1025 dev->name, iflink.stream);
1026 return 0;
1027
1028 default:
1029 return -EINVAL;
1030 }
1031 }
1032
1033
1034
1035 void
1036 dev_init(void)
1037 {
1038 struct device *dev, *dev2;
1039
1040
1041
1042
1043
1044
1045 dev2 = NULL;
1046 for (dev = dev_base; dev != NULL; dev=dev->next) {
1047 if (dev->init && dev->init(dev)) {
1048 if (dev2 == NULL) dev_base = dev->next;
1049 else dev2->next = dev->next;
1050 } else {
1051 dev2 = dev;
1052 }
1053 }
1054
1055
1056 ip_bcast = in_aton("255.255.255.255");
1057 }