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