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