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