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