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