This source file includes following definitions.
- sl_alloc
- sl_free
- sl_changedmtu
- sl_lock
- sl_unlock
- sl_bump
- sl_encaps
- slip_write_wakeup
- sl_xmit
- sl_type_trans
- sl_header
- sl_rebuild_header
- sl_open
- sl_close
- slip_receive_room
- slip_receive_buf
- slip_open
- slip_close
- sl_get_stats
- slip_esc
- slip_unesc
- slip_esc6
- slip_unesc6
- sl_set_mac_address
- sl_set_dev_mac_address
- slip_ioctl
- sl_open_dev
- slip_init
- init_module
- cleanup_module
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
40
41
42
43
44
45
46
47 #define SL_CHECK_TRANSMIT
48 #include <linux/config.h>
49 #ifdef MODULE
50 #include <linux/module.h>
51 #include <linux/version.h>
52 #endif
53
54
55 #define CONFIG_SLIP_MODE_SLIP6
56
57 #include <asm/system.h>
58 #include <asm/segment.h>
59 #include <asm/bitops.h>
60 #include <linux/string.h>
61 #include <linux/mm.h>
62 #include <linux/interrupt.h>
63 #include <linux/in.h>
64 #include <linux/tty.h>
65 #include <linux/errno.h>
66 #include <linux/netdevice.h>
67 #ifdef CONFIG_AX25
68 #include "ax25.h"
69 #endif
70 #include <linux/etherdevice.h>
71 #include <linux/skbuff.h>
72 #include <linux/if_arp.h>
73 #include "slip.h"
74 #ifdef CONFIG_INET
75 #include <linux/ip.h>
76 #include <linux/tcp.h>
77 #include "slhc.h"
78 #endif
79
80 #ifdef MODULE
81 #define SLIP_VERSION "0.8.3-NET3.019-NEWTTY-MODULAR"
82 #else
83 #define SLIP_VERSION "0.8.3-NET3.019-NEWTTY"
84 #endif
85
86
87 static struct slip sl_ctrl[SL_NRUNIT];
88 static struct tty_ldisc sl_ldisc;
89 static int already = 0;
90
91 static int slip_esc(unsigned char *p, unsigned char *d, int len);
92 static void slip_unesc(struct slip *sl, unsigned char c);
93 #ifdef CONFIG_SLIP_MODE_SLIP6
94 static int slip_esc6(unsigned char *p, unsigned char *d, int len);
95 static void slip_unesc6(struct slip *sl, unsigned char c);
96 #endif
97
98
99
100 static inline struct slip *
101 sl_alloc(void)
102 {
103 struct slip *sl;
104 int i;
105
106 for (i = 0; i < SL_NRUNIT; i++) {
107 sl = &sl_ctrl[i];
108 if (!set_bit(SLF_INUSE, &sl->flags)) {
109 return sl;
110 }
111 }
112 return NULL;
113 }
114
115
116
117 static inline void
118 sl_free(struct slip *sl)
119 {
120
121 if (sl->rbuff) {
122 kfree(sl->rbuff);
123 }
124 sl->rbuff = NULL;
125 if (sl->xbuff) {
126 kfree(sl->xbuff);
127 }
128 sl->xbuff = NULL;
129 #ifdef SL_INCLUDE_CSLIP
130
131 if (sl->slcomp) {
132 sl->rx_compressed += sl->slcomp->sls_i_compressed;
133 sl->rx_dropped += sl->slcomp->sls_i_tossed;
134 sl->tx_compressed += sl->slcomp->sls_o_compressed;
135 sl->tx_misses += sl->slcomp->sls_o_misses;
136 }
137 if (sl->cbuff) {
138 kfree(sl->cbuff);
139 }
140 sl->cbuff = NULL;
141 if(sl->slcomp)
142 slhc_free(sl->slcomp);
143 sl->slcomp = NULL;
144 #endif
145
146 if (!clear_bit(SLF_INUSE, &sl->flags)) {
147 printk("%s: sl_free for already free unit.\n", sl->dev->name);
148 }
149 }
150
151
152
153
154
155 static void sl_changedmtu(struct slip *sl)
156 {
157 struct device *dev = sl->dev;
158 unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
159 #ifdef SL_INCLUDE_CSLIP
160 unsigned char *cbuff, *ocbuff;
161 #endif
162 int len;
163 unsigned long flags;
164
165 len = dev->mtu * 2;
166
167
168
169
170
171 if (len < 576 * 2) {
172 len = 576 * 2;
173 }
174
175 xbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
176 rbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
177 #ifdef SL_INCLUDE_CSLIP
178 cbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
179 #endif
180
181 #ifdef SL_INCLUDE_CSLIP
182 if (xbuff == NULL || rbuff == NULL || cbuff == NULL) {
183 #else
184 if (xbuff == NULL || rbuff == NULL) {
185 #endif
186 printk("%s: unable to grow slip buffers, MTU change cancelled.\n",
187 sl->dev->name);
188 dev->mtu = sl->mtu;
189 if (xbuff != NULL) {
190 kfree(xbuff);
191 }
192 if (rbuff != NULL) {
193 kfree(rbuff);
194 }
195 #ifdef SL_INCLUDE_CSLIP
196 if (cbuff != NULL) {
197 kfree(cbuff);
198 }
199 #endif
200 return;
201 }
202
203 save_flags(flags); cli();
204
205 oxbuff = sl->xbuff;
206 sl->xbuff = xbuff;
207 orbuff = sl->rbuff;
208 sl->rbuff = rbuff;
209 #ifdef SL_INCLUDE_CSLIP
210 ocbuff = sl->cbuff;
211 sl->cbuff = cbuff;
212 #endif
213 if (sl->xleft) {
214 if (sl->xleft <= len) {
215 memcpy(sl->xbuff, sl->xhead, sl->xleft);
216 } else {
217 sl->xleft = 0;
218 sl->tx_dropped++;
219 }
220 }
221 sl->xhead = sl->xbuff;
222
223 if (sl->rcount) {
224 if (sl->rcount <= len) {
225 memcpy(sl->rbuff, orbuff, sl->rcount);
226 } else {
227 sl->rcount = 0;
228 sl->rx_over_errors++;
229 set_bit(SLF_ERROR, &sl->flags);
230 }
231 }
232 #ifdef CONFIG_AX25
233 sl->mtu = dev->mtu + 73;
234 #else
235 sl->mtu = dev->mtu;
236 #endif
237 sl->buffsize = len;
238
239 restore_flags(flags);
240
241 if (oxbuff != NULL) {
242 kfree(oxbuff);
243 }
244 if (orbuff != NULL) {
245 kfree(orbuff);
246 }
247 #ifdef SL_INCLUDE_CSLIP
248 if (ocbuff != NULL) {
249 kfree(ocbuff);
250 }
251 #endif
252 }
253
254
255
256 static inline void
257 sl_lock(struct slip *sl)
258 {
259 if (set_bit(0, (void *) &sl->dev->tbusy)) {
260 printk("%s: trying to lock already locked device!\n", sl->dev->name);
261 }
262 }
263
264
265
266 static inline void
267 sl_unlock(struct slip *sl)
268 {
269 if (!clear_bit(0, (void *)&sl->dev->tbusy)) {
270 printk("%s: trying to unlock already unlocked device!\n", sl->dev->name);
271 }
272 }
273
274
275 static void
276 sl_bump(struct slip *sl)
277 {
278 struct sk_buff *skb;
279 int count;
280
281 count = sl->rcount;
282 #ifdef SL_INCLUDE_CSLIP
283 if (sl->mode & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) {
284 unsigned char c;
285 if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) {
286
287 if (!(sl->mode & SL_MODE_CSLIP)) {
288 printk("%s: compressed packet ignored\n", sl->dev->name);
289 return;
290 }
291
292 if (count + 80 > sl->buffsize) {
293 sl->rx_over_errors++;
294 return;
295 }
296 count = slhc_uncompress(sl->slcomp, sl->rbuff, count);
297 if (count <= 0) {
298 return;
299 }
300 } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
301 if (!(sl->mode & SL_MODE_CSLIP)) {
302
303 sl->mode |= SL_MODE_CSLIP;
304 sl->mode &= ~SL_MODE_ADAPTIVE;
305 printk("%s: header compression turned on\n", sl->dev->name);
306 }
307 sl->rbuff[0] &= 0x4f;
308 if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) {
309 return;
310 }
311 }
312 }
313 #endif
314
315 skb = alloc_skb(count, GFP_ATOMIC);
316 if (skb == NULL) {
317 printk("%s: memory squeeze, dropping packet.\n", sl->dev->name);
318 sl->rx_dropped++;
319 return;
320 }
321 skb->len = count;
322 skb->dev = sl->dev;
323 memcpy(skb->data, sl->rbuff, count);
324 netif_rx(skb);
325 sl->rx_packets++;
326 }
327
328
329 static void
330 sl_encaps(struct slip *sl, unsigned char *icp, int len)
331 {
332 unsigned char *p;
333 int actual, count;
334
335
336 #ifdef CONFIG_AX25
337 if (sl->mtu != sl->dev->mtu + 73) {
338 #else
339 if (sl->mtu != sl->dev->mtu) {
340 #endif
341 sl_changedmtu(sl);
342 }
343
344 if (len > sl->mtu) {
345 len = sl->mtu;
346 printk ("%s: truncating oversized transmit packet!\n", sl->dev->name);
347 sl->tx_dropped++;
348 sl_unlock(sl);
349 return;
350 }
351
352 p = icp;
353 #ifdef SL_INCLUDE_CSLIP
354 if (sl->mode & SL_MODE_CSLIP) {
355 len = slhc_compress(sl->slcomp, p, len, sl->cbuff, &p, 1);
356 }
357 #endif
358 #ifdef CONFIG_SLIP_MODE_SLIP6
359 if(sl->mode & SL_MODE_SLIP6)
360 count = slip_esc6(p, (unsigned char *) sl->xbuff, len);
361 else
362 #endif
363 count = slip_esc(p, (unsigned char *) sl->xbuff, len);
364
365
366
367
368
369
370
371
372
373 sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
374 actual = sl->tty->driver.write(sl->tty, 0, sl->xbuff, count);
375 #ifdef SL_CHECK_TRANSMIT
376 sl->dev->trans_start = jiffies;
377 #endif
378 sl->xleft = count - actual;
379 sl->xhead = sl->xbuff + actual;
380 }
381
382
383
384
385
386 static void slip_write_wakeup(struct tty_struct *tty)
387 {
388 int actual;
389 struct slip *sl = (struct slip *) tty->disc_data;
390
391
392 if (!sl || sl->magic != SLIP_MAGIC || !sl->dev->start) {
393 return;
394 }
395
396 if (sl->xleft <= 0) {
397
398
399 sl->tx_packets++;
400 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
401 sl_unlock(sl);
402 mark_bh(NET_BH);
403 return;
404 }
405
406 actual = tty->driver.write(tty, 0, sl->xhead, sl->xleft);
407 sl->xleft -= actual;
408 sl->xhead += actual;
409 }
410
411
412 static int
413 sl_xmit(struct sk_buff *skb, struct device *dev)
414 {
415 struct slip *sl = &sl_ctrl[dev->base_addr];
416
417 if (!dev->start) {
418 printk("%s: xmit call when iface is down\n", dev->name);
419 return 1;
420 }
421
422
423
424
425
426
427
428
429
430
431 if (dev->tbusy) {
432
433
434
435 #ifdef SL_CHECK_TRANSMIT
436 if (jiffies - dev->trans_start < 20 * HZ) {
437
438 return 1;
439 }
440 printk("%s: transmit timed out, %s?\n", dev->name,
441 (sl->tty->driver.chars_in_buffer(sl->tty) || sl->xleft) ?
442 "bad line quality" : "driver error");
443 sl->xleft = 0;
444 sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
445 sl_unlock(sl);
446 #else
447 return 1;
448 #endif
449 }
450
451
452 if (skb != NULL) {
453 sl_lock(sl);
454 sl_encaps(sl, skb->data, skb->len);
455 dev_kfree_skb(skb, FREE_WRITE);
456 }
457 return 0;
458 }
459
460
461
462 static unsigned short
463 sl_type_trans (struct sk_buff *skb, struct device *dev)
464 {
465 #ifdef CONFIG_AX25
466 struct slip *sl = &sl_ctrl[dev->base_addr];
467
468 if (sl->mode & SL_MODE_AX25) {
469 return htons(ETH_P_AX25);
470 }
471 #endif
472 return htons(ETH_P_IP);
473 }
474
475
476
477 static int
478 sl_header(unsigned char *buff, struct device *dev, unsigned short type,
479 void *daddr, void *saddr, unsigned len, struct sk_buff *skb)
480 {
481 #ifdef CONFIG_AX25
482 #ifdef CONFIG_INET
483 struct slip *sl = &sl_ctrl[dev->base_addr];
484
485 if ((sl->mode & SL_MODE_AX25) && type != htons(ETH_P_AX25)) {
486 return ax25_encapsulate(buff, dev, type, daddr, saddr, len, skb);
487 }
488 #endif
489 #endif
490 return 0;
491 }
492
493
494
495 static int
496 sl_rebuild_header(void *buff, struct device *dev, unsigned long raddr,
497 struct sk_buff *skb)
498 {
499 #ifdef CONFIG_AX25
500 #ifdef CONFIG_INET
501 struct slip *sl = &sl_ctrl[dev->base_addr];
502
503 if (sl->mode & SL_MODE_AX25) {
504 return ax25_rebuild_header(buff, dev, raddr, skb);
505 }
506 #endif
507 #endif
508 return 0;
509 }
510
511
512
513 static int
514 sl_open(struct device *dev)
515 {
516 struct slip *sl = &sl_ctrl[dev->base_addr];
517 unsigned long len;
518
519 if (sl->tty == NULL) {
520 return -ENODEV;
521 }
522
523
524
525
526
527
528
529
530 len = dev->mtu * 2;
531
532
533
534
535
536 if (len < 576 * 2) {
537 len = 576 * 2;
538 }
539 sl->rbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
540 if (sl->rbuff == NULL) {
541 goto norbuff;
542 }
543 sl->xbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
544 if (sl->xbuff == NULL) {
545 goto noxbuff;
546 }
547 #ifdef SL_INCLUDE_CSLIP
548 sl->cbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
549 if (sl->cbuff == NULL) {
550 goto nocbuff;
551 }
552 sl->slcomp = slhc_init(16, 16);
553 if (sl->slcomp == NULL) {
554 goto noslcomp;
555 }
556 #endif
557
558 #ifdef CONFIG_AX25
559 sl->mtu = dev->mtu + 73;
560 #else
561 sl->mtu = dev->mtu;
562 #endif
563 sl->buffsize = len;
564 sl->rcount = 0;
565 sl->xleft = 0;
566 #ifdef CONFIG_SLIP_MODE_SLIP6
567 sl->xdata = 0;
568 sl->xbits = 0;
569 #endif
570 sl->flags &= (1 << SLF_INUSE);
571
572
573 if (dev->pa_addr == 0) {
574 dev->pa_addr=ntohl(0xC0A80001);
575 }
576 dev->tbusy = 0;
577
578 dev->start = 1;
579
580 return 0;
581
582
583 #ifdef SL_INCLUDE_CSLIP
584 noslcomp:
585 kfree(sl->cbuff);
586 nocbuff:
587 #endif
588 kfree(sl->xbuff);
589 noxbuff:
590 kfree(sl->rbuff);
591 norbuff:
592 return -ENOMEM;
593 }
594
595
596
597 static int
598 sl_close(struct device *dev)
599 {
600 struct slip *sl = &sl_ctrl[dev->base_addr];
601
602 if (sl->tty == NULL) {
603 return -EBUSY;
604 }
605 sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
606 dev->tbusy = 1;
607 dev->start = 0;
608
609
610
611 return 0;
612 }
613
614 static int
615 slip_receive_room(struct tty_struct *tty)
616 {
617 return 65536;
618 }
619
620
621
622
623
624
625
626 static void
627 slip_receive_buf(struct tty_struct *tty, unsigned char *cp, char *fp, int count)
628 {
629 struct slip *sl = (struct slip *) tty->disc_data;
630
631 if (!sl || sl->magic != SLIP_MAGIC || !sl->dev->start)
632 return;
633
634
635
636
637
638 #ifdef CONFIG_AX25
639 if (sl->mtu != sl->dev->mtu + 73) {
640 #else
641 if (sl->mtu != sl->dev->mtu) {
642 #endif
643 sl_changedmtu(sl);
644 }
645
646
647 while (count--) {
648 if (fp && *fp++) {
649 if (!set_bit(SLF_ERROR, &sl->flags)) {
650 sl->rx_errors++;
651 }
652 cp++;
653 continue;
654 }
655 #ifdef CONFIG_SLIP_MODE_SLIP6
656 if (sl->mode & SL_MODE_SLIP6)
657 slip_unesc6(sl, *cp++);
658 else
659 #endif
660 slip_unesc(sl, *cp++);
661 }
662 }
663
664
665
666
667
668
669
670
671 static int
672 slip_open(struct tty_struct *tty)
673 {
674 struct slip *sl = (struct slip *) tty->disc_data;
675 int err;
676
677
678 if (sl && sl->magic == SLIP_MAGIC) {
679 return -EEXIST;
680 }
681
682
683 if ((sl = sl_alloc()) == NULL) {
684 return -ENFILE;
685 }
686
687 sl->tty = tty;
688 tty->disc_data = sl;
689 if (tty->driver.flush_buffer) {
690 tty->driver.flush_buffer(tty);
691 }
692 if (tty->ldisc.flush_buffer) {
693 tty->ldisc.flush_buffer(tty);
694 }
695
696
697 sl->mode = SL_MODE_DEFAULT;
698 sl->dev->type = ARPHRD_SLIP + sl->mode;
699 #ifdef CONFIG_AX25
700 if (sl->dev->type == 260) {
701 sl->dev->type = ARPHRD_AX25;
702 }
703 #endif
704
705 if ((err = sl_open(sl->dev))) {
706 return err;
707 }
708
709 #ifdef MODULE
710 MOD_INC_USE_COUNT;
711 #endif
712
713
714 return sl->dev->base_addr;
715 }
716
717
718
719
720
721
722
723
724 static void
725 slip_close(struct tty_struct *tty)
726 {
727 struct slip *sl = (struct slip *) tty->disc_data;
728
729
730 if (!sl || sl->magic != SLIP_MAGIC) {
731 return;
732 }
733
734 (void) dev_close(sl->dev);
735
736 tty->disc_data = 0;
737 sl->tty = NULL;
738 sl_free(sl);
739 #ifdef MODULE
740 MOD_DEC_USE_COUNT;
741 #endif
742 }
743
744
745 static struct enet_statistics *
746 sl_get_stats(struct device *dev)
747 {
748 static struct enet_statistics stats;
749 struct slip *sl = &sl_ctrl[dev->base_addr];
750 #ifdef SL_INCLUDE_CSLIP
751 struct slcompress *comp;
752 #endif
753
754 memset(&stats, 0, sizeof(struct enet_statistics));
755
756 stats.rx_packets = sl->rx_packets;
757 stats.tx_packets = sl->tx_packets;
758 stats.rx_dropped = sl->rx_dropped;
759 stats.tx_dropped = sl->tx_dropped;
760 stats.tx_errors = sl->tx_errors;
761 stats.rx_errors = sl->rx_errors;
762 stats.rx_over_errors = sl->rx_over_errors;
763 #ifdef SL_INCLUDE_CSLIP
764 stats.rx_fifo_errors = sl->rx_compressed;
765 stats.tx_fifo_errors = sl->tx_compressed;
766 stats.collisions = sl->tx_misses;
767 comp = sl->slcomp;
768 if (comp) {
769 stats.rx_fifo_errors += comp->sls_i_compressed;
770 stats.rx_dropped += comp->sls_i_tossed;
771 stats.tx_fifo_errors += comp->sls_o_compressed;
772 stats.collisions += comp->sls_o_misses;
773 }
774 #endif
775 return (&stats);
776 }
777
778
779
780
781
782
783 int
784 slip_esc(unsigned char *s, unsigned char *d, int len)
785 {
786 unsigned char *ptr = d;
787 unsigned char c;
788
789
790
791
792
793
794
795 *ptr++ = END;
796
797
798
799
800
801
802 while (len-- > 0) {
803 switch(c = *s++) {
804 case END:
805 *ptr++ = ESC;
806 *ptr++ = ESC_END;
807 break;
808 case ESC:
809 *ptr++ = ESC;
810 *ptr++ = ESC_ESC;
811 break;
812 default:
813 *ptr++ = c;
814 break;
815 }
816 }
817 *ptr++ = END;
818 return (ptr - d);
819 }
820
821 static void
822 slip_unesc(struct slip *sl, unsigned char s)
823 {
824
825 switch(s) {
826 case END:
827 if (!clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) {
828 sl_bump(sl);
829 }
830 clear_bit(SLF_ESCAPE, &sl->flags);
831 sl->rcount = 0;
832 return;
833
834 case ESC:
835 set_bit(SLF_ESCAPE, &sl->flags);
836 return;
837 case ESC_ESC:
838 if (clear_bit(SLF_ESCAPE, &sl->flags)) {
839 s = ESC;
840 }
841 break;
842 case ESC_END:
843 if (clear_bit(SLF_ESCAPE, &sl->flags)) {
844 s = END;
845 }
846 break;
847 }
848 if (!test_bit(SLF_ERROR, &sl->flags)) {
849 if (sl->rcount < sl->buffsize) {
850 sl->rbuff[sl->rcount++] = s;
851 return;
852 }
853 sl->rx_over_errors++;
854 set_bit(SLF_ERROR, &sl->flags);
855 }
856 }
857
858
859 #ifdef CONFIG_SLIP_MODE_SLIP6
860
861
862
863
864 int
865 slip_esc6(unsigned char *s, unsigned char *d, int len)
866 {
867 unsigned char *ptr = d;
868 unsigned char c;
869 int i;
870 unsigned short v = 0;
871 short bits = 0;
872
873
874
875
876
877
878
879 *ptr++ = 0x70;
880
881
882
883
884
885 for (i = 0; i < len; ++i) {
886 v = (v << 8) | s[i];
887 bits += 8;
888 while (bits >= 6) {
889 bits -= 6;
890 c = 0x30 + ((v >> bits) & 0x3F);
891 *ptr++ = c;
892 }
893 }
894 if (bits) {
895 c = 0x30 + ((v << (6 - bits)) & 0x3F);
896 *ptr++ = c;
897 }
898 *ptr++ = 0x70;
899 return ptr - d;
900 }
901
902 void
903 slip_unesc6(struct slip *sl, unsigned char s)
904 {
905 unsigned char c;
906
907 if (s == 0x70) {
908 if (!clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) {
909 sl_bump(sl);
910 }
911 sl->rcount = 0;
912 sl->xbits = 0;
913 sl->xdata = 0;
914 } else if (s >= 0x30 && s < 0x70) {
915 sl->xdata = (sl->xdata << 6) | ((s - 0x30) & 0x3F);
916 sl->xbits += 6;
917 if (sl->xbits >= 8) {
918 sl->xbits -= 8;
919 c = (unsigned char)(sl->xdata >> sl->xbits);
920 if (!test_bit(SLF_ERROR, &sl->flags)) {
921 if (sl->rcount < sl->buffsize) {
922 sl->rbuff[sl->rcount++] = c;
923 return;
924 }
925 sl->rx_over_errors++;
926 set_bit(SLF_ERROR, &sl->flags);
927 }
928 }
929 }
930 }
931 #endif
932
933 #ifdef CONFIG_AX25
934 int
935 sl_set_mac_address(struct device *dev, void *addr)
936 {
937 int err;
938
939 err = verify_area(VERIFY_READ, addr, 7);
940 if (err) {
941 return err;
942 }
943
944 memcpy_fromfs(dev->dev_addr, addr, 7);
945
946 return 0;
947 }
948
949 static int
950 sl_set_dev_mac_address(struct device *dev, void *addr)
951 {
952 memcpy(dev->dev_addr, addr, 7);
953 return 0;
954 }
955 #endif
956
957
958
959 static int
960 slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
961 {
962 struct slip *sl = (struct slip *) tty->disc_data;
963 int err;
964 unsigned int tmp;
965
966
967 if (!sl || sl->magic != SLIP_MAGIC) {
968 return -EINVAL;
969 }
970
971 switch(cmd) {
972 case SIOCGIFNAME:
973 err = verify_area(VERIFY_WRITE, arg, 16);
974 if (err) {
975 return -err;
976 }
977 memcpy_tofs(arg, sl->dev->name, strlen(sl->dev->name) + 1);
978 return 0;
979
980 case SIOCGIFENCAP:
981 err = verify_area(VERIFY_WRITE, arg, sizeof(long));
982 if (err) {
983 return -err;
984 }
985 put_fs_long(sl->mode, (long *)arg);
986 return 0;
987
988 case SIOCSIFENCAP:
989 err = verify_area(VERIFY_READ, arg, sizeof(long));
990 if (err) {
991 return -err;
992 }
993 tmp = get_fs_long((long *)arg);
994 #ifndef SL_INCLUDE_CSLIP
995 if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE)) {
996 return -EINVAL;
997 }
998 #else
999 if ((tmp & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) ==
1000 (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) {
1001
1002 tmp &= ~SL_MODE_ADAPTIVE;
1003 }
1004 #endif
1005 #ifndef CONFIG_SLIP_MODE_SLIP6
1006 if (tmp & SL_MODE_SLIP6) {
1007 return -EINVAL;
1008 }
1009 #endif
1010 #ifndef CONFIG_AX25
1011 if (tmp & SL_MODE_AX25) {
1012 return -EINVAL;
1013 }
1014 #else
1015 if (tmp & SL_MODE_AX25) {
1016 sl->dev->addr_len=7;
1017 sl->dev->hard_header_len=17;
1018 } else {
1019 sl->dev->addr_len=0;
1020 sl->dev->hard_header_len=0;
1021 }
1022 #endif
1023 sl->mode = tmp;
1024 sl->dev->type = ARPHRD_SLIP+sl->mode;
1025 #ifdef CONFIG_AX25
1026 if (sl->dev->type == 260) {
1027 sl->dev->type = ARPHRD_AX25;
1028 }
1029 #endif
1030 return 0;
1031
1032 case SIOCSIFHWADDR:
1033 #ifdef CONFIG_AX25
1034 return sl_set_mac_address(sl->dev, arg);
1035 #else
1036 return -EINVAL;
1037 #endif
1038
1039
1040 case TCGETS:
1041 case TCGETA:
1042 return n_tty_ioctl(tty, (struct file *) file, cmd, (unsigned long) arg);
1043
1044 default:
1045 return -ENOIOCTLCMD;
1046 }
1047 }
1048
1049 static int sl_open_dev(struct device *dev)
1050 {
1051 struct slip *sl = &sl_ctrl[dev->base_addr];
1052 if(sl->tty==NULL)
1053 return -ENODEV;
1054 return 0;
1055 }
1056
1057
1058 int
1059 slip_init(struct device *dev)
1060 {
1061 struct slip *sl = &sl_ctrl[dev->base_addr];
1062 int i;
1063 #ifdef CONFIG_AX25
1064 static char ax25_bcast[7] =
1065 {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
1066 static char ax25_test[7] =
1067 {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
1068 #endif
1069
1070 if (already++ == 0) {
1071 printk("SLIP: version %s (%d channels) %s\n",
1072 SLIP_VERSION, SL_NRUNIT,
1073 #ifdef CONFIG_SLIP_MODE_SLIP6
1074 "(6 bit encapsulation enabled)"
1075 #else
1076 ""
1077 #endif
1078 );
1079 #if defined(SL_INCLUDE_CSLIP) && !defined(MODULE)
1080 printk("CSLIP: code copyright 1989 Regents of the University of California\n");
1081 #endif
1082 #ifdef CONFIG_AX25
1083 printk("AX25: KISS encapsulation enabled\n");
1084 #endif
1085
1086 memset(&sl_ldisc, 0, sizeof(sl_ldisc));
1087 sl_ldisc.magic = TTY_LDISC_MAGIC;
1088 sl_ldisc.flags = 0;
1089 sl_ldisc.open = slip_open;
1090 sl_ldisc.close = slip_close;
1091 sl_ldisc.read = NULL;
1092 sl_ldisc.write = NULL;
1093 sl_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *,
1094 unsigned int, unsigned long)) slip_ioctl;
1095 sl_ldisc.select = NULL;
1096 sl_ldisc.receive_buf = slip_receive_buf;
1097 sl_ldisc.receive_room = slip_receive_room;
1098 sl_ldisc.write_wakeup = slip_write_wakeup;
1099 if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0) {
1100 printk("SLIP: can't register line discipline (err = %d)\n", i);
1101 }
1102 }
1103
1104
1105
1106 memset(sl, 0, sizeof (struct slip));
1107 sl->magic = SLIP_MAGIC;
1108 sl->dev = dev;
1109
1110
1111 dev->mtu = SL_MTU;
1112 dev->hard_start_xmit = sl_xmit;
1113 dev->open = sl_open_dev;
1114 dev->stop = sl_close;
1115 dev->hard_header = sl_header;
1116 dev->type_trans = sl_type_trans;
1117 dev->get_stats = sl_get_stats;
1118 #ifdef HAVE_SET_MAC_ADDR
1119 #ifdef CONFIG_AX25
1120 dev->set_mac_address = sl_set_dev_mac_address;
1121 #endif
1122 #endif
1123 dev->hard_header_len = 0;
1124 dev->addr_len = 0;
1125 dev->type = ARPHRD_SLIP + SL_MODE_DEFAULT;
1126 #ifdef CONFIG_AX25
1127 if (sl->dev->type == 260) {
1128 sl->dev->type = ARPHRD_AX25;
1129 }
1130 memcpy(dev->broadcast, ax25_bcast, 7);
1131 memcpy(dev->dev_addr, ax25_test, 7);
1132 #endif
1133 dev->rebuild_header = sl_rebuild_header;
1134
1135 for (i = 0; i < DEV_NUMBUFFS; i++) {
1136 skb_queue_head_init(&dev->buffs[i]);
1137 }
1138
1139
1140 dev->flags = 0;
1141 dev->family = AF_INET;
1142 dev->pa_addr = 0;
1143 dev->pa_brdaddr = 0;
1144 dev->pa_mask = 0;
1145 dev->pa_alen = sizeof(unsigned long);
1146
1147 return 0;
1148 }
1149 #ifdef MODULE
1150 char kernel_version[] = UTS_RELEASE;
1151
1152 static struct device dev_slip[SL_NRUNIT] = {
1153 {
1154 "sl0",
1155 0, 0, 0, 0,
1156 0, 0,
1157 0, 0, 0, NULL, slip_init,
1158 },
1159 { "sl1" , 0, 0, 0, 0, 1, 0, 0, 0, 0, NULL, slip_init },
1160 { "sl2" , 0, 0, 0, 0, 2, 0, 0, 0, 0, NULL, slip_init },
1161 { "sl3" , 0, 0, 0, 0, 3, 0, 0, 0, 0, NULL, slip_init },
1162 #ifdef SL_SLIP_LOTS
1163 { "sl4" , 0, 0, 0, 0, 4, 0, 0, 0, 0, NULL, slip_init },
1164 { "sl5" , 0, 0, 0, 0, 5, 0, 0, 0, 0, NULL, slip_init },
1165 { "sl6" , 0, 0, 0, 0, 6, 0, 0, 0, 0, NULL, slip_init },
1166 { "sl7" , 0, 0, 0, 0, 7, 0, 0, 0, 0, NULL, slip_init },
1167 { "sl8" , 0, 0, 0, 0, 8, 0, 0, 0, 0, NULL, slip_init },
1168 { "sl9" , 0, 0, 0, 0, 9, 0, 0, 0, 0, NULL, slip_init },
1169 { "sl10", 0, 0, 0, 0, 10, 0, 0, 0, 0, NULL, slip_init },
1170 { "sl11", 0, 0, 0, 0, 11, 0, 0, 0, 0, NULL, slip_init },
1171 { "sl12", 0, 0, 0, 0, 12, 0, 0, 0, 0, NULL, slip_init },
1172 { "sl13", 0, 0, 0, 0, 13, 0, 0, 0, 0, NULL, slip_init },
1173 { "sl14", 0, 0, 0, 0, 14, 0, 0, 0, 0, NULL, slip_init },
1174 { "sl15", 0, 0, 0, 0, 15, 0, 0, 0, 0, NULL, slip_init },
1175 #endif
1176 };
1177
1178 int
1179 init_module(void)
1180 {
1181 int err;
1182 int i;
1183
1184 for (i = 0; i < SL_NRUNIT; i++) {
1185 if ((err = register_netdev(&dev_slip[i]))) {
1186 if (err == -EEXIST) {
1187 printk("SLIP: devices already present. Module not loaded.\n");
1188 }
1189 return err;
1190 }
1191 }
1192 return 0;
1193 }
1194
1195 void
1196 cleanup_module(void)
1197 {
1198 int i;
1199
1200 if (MOD_IN_USE) {
1201 printk("SLIP: device busy, remove delayed\n");
1202 return;
1203 }
1204 for (i = 0; i < SL_NRUNIT; i++) {
1205 unregister_netdev(&dev_slip[i]);
1206 }
1207 if ((i = tty_register_ldisc(N_SLIP, NULL))) {
1208 printk("SLIP: can't unregister line discipline (err = %d)\n", i);
1209 }
1210 already = 0;
1211 }
1212 #endif