This source file includes following definitions.
- ip_dump
- clh_dump
- sl_initialize
- sl_find
- sl_alloc
- sl_free
- sl_changedmtu
- sl_enqueue
- sl_dequeue
- sl_lock
- sl_unlock
- sl_bump
- sl_next
- sl_encaps
- sl_xmit
- sl_type_trans
- sl_header
- sl_add_arp
- sl_rebuild_header
- sl_open
- sl_close
- slip_recv
- slip_open
- slip_close
- slip_esc
- slip_unesc
- slip_esc6
- slip_unesc6
- slip_ioctl
- slip_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <asm/segment.h>
22 #include <asm/system.h>
23
24 #include <linux/config.h>
25 #include <linux/types.h>
26 #include <linux/kernel.h>
27 #include <linux/sched.h>
28 #include <linux/string.h>
29 #include <linux/mm.h>
30 #include <linux/socket.h>
31 #include <linux/termios.h>
32 #include <linux/sockios.h>
33 #include <linux/interrupt.h>
34 #include <linux/tty.h>
35 #include <linux/errno.h>
36 #include <linux/stat.h>
37 #include <linux/tty.h>
38 #include <linux/in.h>
39 #include "inet.h"
40 #include "dev.h"
41 #include "eth.h"
42 #include "ip.h"
43 #include "route.h"
44 #include "protocol.h"
45 #include "tcp.h"
46 #include "skbuff.h"
47 #include "sock.h"
48 #include "arp.h"
49 #include "slip.h"
50 #include "slhc.h"
51
52 #define SLIP_VERSION "0.7.5"
53
54
55 #ifdef SL_DUMP
56 # define IP_VERSION 4
57 # define IPF_F_OFFSET 0x1fff
58 # define IPF_DF 0x4000
59 # define IPF_MF 0x2000
60 # define IP_OF_COPIED 0x80
61 # define IP_OF_CLASS 0x60
62 # define IP_OF_NUMBER 0x1f
63 #endif
64
65
66 static struct slip sl_ctrl[SL_NRUNIT];
67 static struct tty_ldisc sl_ldisc;
68 static int already = 0;
69
70
71
72 static void
73 ip_dump(unsigned char *ptr, int len)
74 {
75 #ifdef SL_DUMP
76 struct iphdr *ip;
77 struct tcphdr *th;
78 int dlen, doff;
79
80 if (inet_debug != DBG_SLIP) return;
81
82 ip = (struct iphdr *) ptr;
83 th = (struct tcphdr *) (ptr + ip->ihl * 4);
84 printk("\r%s -> %s seq %lx ack %lx len %d\n",
85 in_ntoa(ip->saddr), in_ntoa(ip->daddr),
86 ntohl(th->seq), ntohl(th->ack_seq), ntohs(ip->tot_len));
87 return;
88
89 printk("\r*****\n");
90 printk("%p %d\n", ptr, len);
91 ip = (struct iphdr *) ptr;
92 dlen = ntohs(ip->tot_len);
93 doff = ((ntohs(ip->frag_off) & IPF_F_OFFSET) << 3);
94
95
96 printk("SLIP: %s->", in_ntoa(ip->saddr));
97 printk("%s\n", in_ntoa(ip->daddr));
98 printk(" len %u ihl %u ver %u ttl %u prot %u",
99 dlen, ip->ihl, ip->version, ip->ttl, ip->protocol);
100
101 if (ip->tos != 0) printk(" tos %u", ip->tos);
102 if (doff != 0 || (ntohs(ip->frag_off) & IPF_MF))
103 printk(" id %u offs %u", ntohs(ip->id), doff);
104
105 if (ntohs(ip->frag_off) & IPF_DF) printk(" DF");
106 if (ntohs(ip->frag_off) & IPF_MF) printk(" MF");
107 printk("\n*****\n");
108 #endif
109 }
110
111 #if 0
112 void clh_dump(unsigned char *cp, int len)
113 {
114 if (len > 60)
115 len = 60;
116 printk("%d:", len);
117 while (len > 0) {
118 printk(" %x", *cp++);
119 len--;
120 }
121 printk("\n\n");
122 }
123 #endif
124
125
126 static void
127 sl_initialize(struct slip *sl, struct device *dev)
128 {
129 sl->inuse = 0;
130 sl->sending = 0;
131 sl->escape = 0;
132 sl->flags = 0;
133 #ifdef SL_COMPRESSED
134 sl->mode = SL_MODE_CSLIP;
135 #else
136 sl->mode = SL_MODE_SLIP;
137 #endif
138
139 sl->line = dev->base_addr;
140 sl->tty = NULL;
141 sl->dev = dev;
142 sl->slcomp = NULL;
143
144
145 sl->rbuff = NULL;
146 sl->xbuff = NULL;
147 sl->cbuff = NULL;
148
149 sl->rhead = NULL;
150 sl->rend = NULL;
151 dev->rmem_end = (unsigned long) NULL;
152 dev->rmem_start = (unsigned long) NULL;
153 dev->mem_end = (unsigned long) NULL;
154 dev->mem_start = (unsigned long) NULL;
155 }
156
157
158
159 static struct slip *
160 sl_find(struct tty_struct *tty)
161 {
162 struct slip *sl;
163 int i;
164
165 if (tty == NULL) return(NULL);
166 for (i = 0; i < SL_NRUNIT; i++) {
167 sl = &sl_ctrl[i];
168 if (sl->tty == tty) return(sl);
169 }
170 return(NULL);
171 }
172
173
174
175 static inline struct slip *
176 sl_alloc(void)
177 {
178 unsigned long flags;
179 struct slip *sl;
180 int i;
181
182 save_flags (flags);
183 cli();
184 for (i = 0; i < SL_NRUNIT; i++) {
185 sl = &sl_ctrl[i];
186 if (sl->inuse == 0) {
187 sl->inuse = 1;
188 sl->tty = NULL;
189 restore_flags(flags);
190 return(sl);
191 }
192 }
193 restore_flags(flags);
194 return(NULL);
195 }
196
197
198
199 static inline void
200 sl_free(struct slip *sl)
201 {
202 unsigned long flags;
203
204 if (sl->inuse) {
205 save_flags(flags);
206 cli();
207 sl->inuse = 0;
208 sl->tty = NULL;
209 restore_flags(flags);
210 }
211 }
212
213
214
215
216
217 static void sl_changedmtu(struct slip *sl)
218 {
219 struct device *dev=sl->dev;
220 unsigned char *tb,*rb,*cb,*tf,*rf,*cf;
221 int l;
222 int omtu=sl->mtu;
223
224 sl->mtu=dev->mtu;
225 l=(dev->mtu *2);
226
227 DPRINTF((DBG_SLIP,"SLIP: mtu changed!\n"));
228
229 tb= (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
230 rb= (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
231 cb= (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
232
233 if(tb==NULL || rb==NULL || cb==NULL)
234 {
235 printk("Unable to grow slip buffers. MTU change cancelled.\n");
236 sl->mtu=omtu;
237 dev->mtu=omtu;
238 if(tb!=NULL)
239 kfree(tb);
240 if(rb!=NULL)
241 kfree(rb);
242 if(cb!=NULL)
243 kfree(cb);
244 return;
245 }
246
247 cli();
248
249 tf=(unsigned char *)sl->dev->mem_start;
250 sl->dev->mem_start=(unsigned long)tb;
251 sl->dev->mem_end=(unsigned long) (sl->dev->mem_start + l);
252 rf=(unsigned char *)sl->dev->rmem_start;
253 sl->dev->rmem_start=(unsigned long)rb;
254 sl->dev->rmem_end=(unsigned long) (sl->dev->rmem_start + l);
255
256 sl->xbuff = (unsigned char *) sl->dev->mem_start;
257 sl->rbuff = (unsigned char *) sl->dev->rmem_start;
258 sl->rend = (unsigned char *) sl->dev->rmem_end;
259 sl->rhead = sl->rbuff;
260
261 cf=sl->cbuff;
262 sl->cbuff=cb;
263
264 sl->escape=0;
265 sl->sending=0;
266 sl->rcount=0;
267
268 sti();
269
270 if(rf!=NULL)
271 kfree(rf);
272 if(tf!=NULL)
273 kfree(tf);
274 if(cf!=NULL)
275 kfree(cf);
276 }
277
278
279
280 static inline void
281 sl_enqueue(struct slip *sl, unsigned char c)
282 {
283 unsigned long flags;
284
285 save_flags(flags);
286 cli();
287 if (sl->rhead < sl->rend) {
288 *sl->rhead = c;
289 sl->rhead++;
290 sl->rcount++;
291 } else sl->roverrun++;
292 restore_flags(flags);
293 }
294
295
296 static inline void
297 sl_dequeue(struct slip *sl, int i)
298 {
299 unsigned long flags;
300
301 save_flags(flags);
302 cli();
303 if (sl->rhead > sl->rbuff) {
304 sl->rhead -= i;
305 sl->rcount -= i;
306 }
307 restore_flags(flags);
308 }
309
310
311
312 static inline void
313 sl_lock(struct slip *sl)
314 {
315 unsigned long flags;
316
317 save_flags(flags);
318 cli();
319 sl->sending = 1;
320 sl->dev->tbusy = 1;
321 restore_flags(flags);
322 }
323
324
325
326 static inline void
327 sl_unlock(struct slip *sl)
328 {
329 unsigned long flags;
330
331 save_flags(flags);
332 cli();
333 sl->sending = 0;
334 sl->dev->tbusy = 0;
335 restore_flags(flags);
336 }
337
338
339
340 static void
341 sl_bump(struct slip *sl)
342 {
343 int done;
344 unsigned char c;
345 unsigned long flags;
346 int count;
347
348 count = sl->rcount;
349 if (sl->mode & SL_MODE_CSLIP) {
350 if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) {
351
352 save_flags(flags);
353 cli();
354 if ((sl->rhead + 80) < sl->rend) {
355 sl->rhead += 80;
356 sl->rcount += 80;
357 done = 1;
358 } else {
359 sl->roverrun++;
360 done = 0;
361 }
362 restore_flags(flags);
363 if (! done)
364 return;
365
366 count = slhc_uncompress(sl->slcomp, sl->rbuff, count);
367 if (count <= 0) {
368 sl->errors++;
369 return;
370 }
371 } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
372 sl->rbuff[0] &= 0x4f;
373 if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) {
374 sl->errors++;
375 return;
376 }
377 }
378 }
379
380 DPRINTF((DBG_SLIP, "<< \"%s\" recv:\r\n", sl->dev->name));
381 ip_dump(sl->rbuff, sl->rcount);
382
383
384 do {
385 DPRINTF((DBG_SLIP, "SLIP: packet is %d at 0x%X\n",
386 sl->rcount, sl->rbuff));
387
388 done = dev_rint(sl->rbuff, count, 0, sl->dev);
389 if (done == 0 || done == 1) break;
390 } while(1);
391
392 sl->rpacket++;
393 }
394
395
396
397 static void
398 sl_next(struct slip *sl)
399 {
400 DPRINTF((DBG_SLIP, "SLIP: sl_next(0x%X) called!\n", sl));
401 sl_unlock(sl);
402 dev_tint(sl->dev);
403 }
404
405
406
407 static void
408 sl_encaps(struct slip *sl, unsigned char *icp, int len)
409 {
410 unsigned char *bp, *p;
411 int count;
412
413 DPRINTF((DBG_SLIP, "SLIP: sl_encaps(0x%X, %d) called\n", icp, len));
414 DPRINTF((DBG_SLIP, ">> \"%s\" sent:\r\n", sl->dev->name));
415
416 ip_dump(icp, len);
417
418 if(sl->mtu != sl->dev->mtu)
419 sl_changedmtu(sl);
420
421 if(len>sl->mtu)
422 {
423 len=sl->mtu;
424 printk("slip: truncating oversized transmit packet!\n");
425 }
426
427 p = icp;
428 if(sl->mode & SL_MODE_CSLIP)
429 len = slhc_compress(sl->slcomp, p, len, sl->cbuff, &p, 1);
430
431 #ifdef OLD
432
433
434
435
436
437 bp = sl->xbuff;
438 *bp++ = END;
439 count = 1;
440
441
442
443
444
445 while(len-- > 0) {
446 c = *p++;
447 switch(c) {
448 case END:
449 *bp++ = ESC;
450 *bp++ = ESC_END;
451 count += 2;
452 break;
453 case ESC:
454 *bp++ = ESC;
455 *bp++ = ESC_ESC;
456 count += 2;
457 break;
458 default:
459 *bp++ = c;
460 count++;
461 }
462 }
463 *bp++ = END;
464 count++;
465 #else
466 if(sl->mode & SL_MODE_SLIP6)
467 count=slip_esc6(p, (unsigned char *)sl->xbuff,len);
468 else
469 count=slip_esc(p, (unsigned char *)sl->xbuff,len);
470 #endif
471 sl->spacket++;
472 bp = sl->xbuff;
473
474
475 DPRINTF((DBG_SLIP, "SLIP: kicking TTY for %d bytes at 0x%X\n", count, bp));
476 if (tty_write_data(sl->tty, (char *) bp, count,
477 (void (*)(void *))sl_next, (void *) sl) == 0) {
478 DPRINTF((DBG_SLIP, "SLIP: TTY already done with %d bytes!\n", count));
479 sl_next(sl);
480 }
481 }
482
483
484
485 static int
486 sl_xmit(struct sk_buff *skb, struct device *dev)
487 {
488 struct tty_struct *tty;
489 struct slip *sl;
490
491
492 sl = &sl_ctrl[dev->base_addr];
493 tty = sl->tty;
494 DPRINTF((DBG_SLIP, "SLIP: sl_xmit(\"%s\") skb=0x%X busy=%d\n",
495 dev->name, skb, sl->sending));
496
497
498
499
500
501
502 if (sl->sending) {
503 DPRINTF((DBG_SLIP, "SLIP: sl_xmit: BUSY\r\n"));
504 sl->sbusy++;
505 return(1);
506 }
507
508
509 if (skb != NULL) {
510 sl_lock(sl);
511 sl_encaps(sl, (unsigned char *) (skb + 1), skb->len);
512 if (skb->free) kfree_skb(skb, FREE_WRITE);
513 }
514 return(0);
515 }
516
517
518
519 static unsigned short
520 sl_type_trans (struct sk_buff *skb, struct device *dev)
521 {
522 return(NET16(ETH_P_IP));
523 }
524
525
526
527 static int
528 sl_header(unsigned char *buff, struct device *dev, unsigned short type,
529 unsigned long daddr, unsigned long saddr, unsigned len)
530 {
531 return(0);
532 }
533
534
535
536 static void
537 sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
538 {
539 }
540
541
542
543 static int
544 sl_rebuild_header(void *buff, struct device *dev)
545 {
546 return(0);
547 }
548
549
550
551 static int
552 sl_open(struct device *dev)
553 {
554 struct slip *sl;
555 unsigned char *p;
556 unsigned long l;
557
558 sl = &sl_ctrl[dev->base_addr];
559 if (sl->tty == NULL) {
560 DPRINTF((DBG_SLIP, "SLIP: channel %d not connected!\n", sl->line));
561 return(-ENXIO);
562 }
563 sl->dev = dev;
564
565
566
567
568
569
570
571
572
573 l = (dev->mtu * 2);
574 p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
575 if (p == NULL) {
576 DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP XMIT buffer!\n"));
577 return(-ENOMEM);
578 }
579
580 sl->mtu = dev->mtu;
581 sl->dev->mem_start = (unsigned long) p;
582 sl->dev->mem_end = (unsigned long) (sl->dev->mem_start + l);
583
584 p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
585 if (p == NULL) {
586 DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP RECV buffer!\n"));
587 return(-ENOMEM);
588 }
589 sl->dev->rmem_start = (unsigned long) p;
590 sl->dev->rmem_end = (unsigned long) (sl->dev->rmem_start + l);
591
592 sl->xbuff = (unsigned char *) sl->dev->mem_start;
593 sl->rbuff = (unsigned char *) sl->dev->rmem_start;
594 sl->rend = (unsigned char *) sl->dev->rmem_end;
595 sl->rhead = sl->rbuff;
596
597 sl->escape = 0;
598 sl->sending = 0;
599 sl->rcount = 0;
600
601 p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
602 if (p == NULL) {
603 kfree((unsigned char *)sl->dev->mem_start);
604 DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP COMPRESS buffer!\n"));
605 return(-ENOMEM);
606 }
607 sl->cbuff = p;
608
609 sl->slcomp = slhc_init(16, 16);
610 if (sl->slcomp == NULL) {
611 kfree((unsigned char *)sl->dev->mem_start);
612 kfree((unsigned char *)sl->dev->rmem_start);
613 kfree(sl->cbuff);
614 DPRINTF((DBG_SLIP, "SLIP: no memory for SLCOMP!\n"));
615 return(-ENOMEM);
616 }
617
618 DPRINTF((DBG_SLIP, "SLIP: channel %d opened.\n", sl->line));
619 return(0);
620 }
621
622
623
624 static int
625 sl_close(struct device *dev)
626 {
627 struct slip *sl;
628
629 sl = &sl_ctrl[dev->base_addr];
630 if (sl->tty == NULL) {
631 DPRINTF((DBG_SLIP, "SLIP: channel %d not connected!\n", sl->line));
632 return(-EBUSY);
633 }
634 sl_free(sl);
635
636
637 kfree(sl->rbuff);
638 kfree(sl->xbuff);
639 kfree(sl->cbuff);
640 slhc_free(sl->slcomp);
641
642 sl_initialize(sl, dev);
643
644 DPRINTF((DBG_SLIP, "SLIP: channel %d closed.\n", sl->line));
645 return(0);
646 }
647
648
649
650
651
652
653
654
655 static void
656 slip_recv(struct tty_struct *tty)
657 {
658 unsigned char buff[128];
659 unsigned char *p;
660 struct slip *sl;
661 int count, error=0;
662
663 DPRINTF((DBG_SLIP, "SLIP: slip_recv(%d) called\n", tty->line));
664 if ((sl = sl_find(tty)) == NULL) return;
665
666 if(sl->mtu!=sl->dev->mtu)
667 sl_changedmtu(sl);
668
669
670 do {
671 count = tty_read_raw_data(tty, buff, 128);
672 if (count <= 0)
673 {
674 count= - count;
675 if(count)
676 error=1;
677 break;
678 }
679 p = buff;
680 #ifdef OLD
681 while (count--) {
682 c = *p++;
683 if (sl->escape) {
684 if (c == ESC_ESC)
685 sl_enqueue(sl, ESC);
686 else if (c == ESC_END)
687 sl_enqueue(sl, END);
688 else
689 printk ("SLIP: received wrong character\n");
690 sl->escape = 0;
691 } else {
692 if (c == ESC)
693 sl->escape = 1;
694 else if (c == END) {
695 if (sl->rcount > 2) sl_bump(sl);
696 sl_dequeue(sl, sl->rcount);
697 sl->rcount = 0;
698 } else sl_enqueue(sl, c);
699 }
700 }
701 #else
702 if(sl->mode & SL_MODE_SLIP6)
703 slip_unesc6(sl,buff,count,error);
704 else
705 slip_unesc(sl,buff,count,error);
706 #endif
707 } while(1);
708
709 }
710
711
712
713
714
715
716
717
718
719 static int
720 slip_open(struct tty_struct *tty)
721 {
722 struct slip *sl;
723
724
725 if ((sl = sl_find(tty)) != NULL) {
726 DPRINTF((DBG_SLIP, "SLIP: TTY %d already connected to %s !\n",
727 tty->line, sl->dev->name));
728 return(-EEXIST);
729 }
730
731
732 if ((sl = sl_alloc()) == NULL) {
733 DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected: all channels in use!\n",
734 tty->line));
735 return(-ENFILE);
736 }
737 sl->tty = tty;
738 tty_read_flush(tty);
739 tty_write_flush(tty);
740
741
742 (void) sl_open(sl->dev);
743 DPRINTF((DBG_SLIP, "SLIP: TTY %d connected to %s.\n",
744 tty->line, sl->dev->name));
745
746
747 return(sl->line);
748 }
749
750
751
752
753
754
755
756
757 static void
758 slip_close(struct tty_struct *tty)
759 {
760 struct slip *sl;
761
762
763 if ((sl = sl_find(tty)) == NULL) {
764 DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected !\n", tty->line));
765 return;
766 }
767
768 (void) dev_close(sl->dev);
769 DPRINTF((DBG_SLIP, "SLIP: TTY %d disconnected from %s.\n",
770 tty->line, sl->dev->name));
771 }
772
773
774
775
776
777
778
779
780 int
781 slip_esc(unsigned char *s, unsigned char *d, int len)
782 {
783 int count = 0;
784
785
786
787
788
789
790
791 d[count++] = END;
792
793
794
795
796
797
798 while(len-- > 0) {
799 switch(*s) {
800 case END:
801 d[count++] = ESC;
802 d[count++] = ESC_END;
803 break;
804 case ESC:
805 d[count++] = ESC;
806 d[count++] = ESC_ESC;
807 break;
808 default:
809 d[count++] = *s;
810 }
811 ++s;
812 }
813 d[count++] = END;
814 return(count);
815 }
816
817 void
818 slip_unesc(struct slip *sl, unsigned char *s, int count, int error)
819 {
820 int i;
821
822 for (i = 0; i < count; ++i, ++s) {
823 switch(*s) {
824 case ESC:
825 sl->flags |= SLF_ESCAPE;
826 break;
827 case ESC_ESC:
828 if (sl->flags & SLF_ESCAPE)
829 sl_enqueue(sl, ESC);
830 else
831 sl_enqueue(sl, *s);
832 sl->flags &= ~SLF_ESCAPE;
833 break;
834 case ESC_END:
835 if (sl->flags & SLF_ESCAPE)
836 sl_enqueue(sl, END);
837 else
838 sl_enqueue(sl, *s);
839 sl->flags &= ~SLF_ESCAPE;
840 break;
841 case END:
842 if (sl->rcount > 2)
843 sl_bump(sl);
844 sl_dequeue(sl, sl->rcount);
845 sl->rcount = 0;
846 sl->flags &= ~(SLF_ESCAPE | SLF_ERROR);
847 break;
848 default:
849 sl_enqueue(sl, *s);
850 sl->flags &= ~SLF_ESCAPE;
851 }
852 }
853 if (error)
854 sl->flags |= SLF_ERROR;
855 }
856
857
858
859
860
861
862
863 int
864 slip_esc6(unsigned char *s, unsigned char *d, int len)
865 {
866 int count = 0;
867 int i;
868 unsigned short v = 0;
869 short bits = 0;
870
871
872
873
874
875
876
877 d[count++] = 0x70;
878
879
880
881
882
883 for (i = 0; i < len; ++i) {
884 v = (v << 8) | s[i];
885 bits += 8;
886 while (bits >= 6) {
887 unsigned char c;
888
889 bits -= 6;
890 c = 0x30 + ((v >> bits) & 0x3F);
891 d[count++] = c;
892 }
893 }
894 if (bits) {
895 unsigned char c;
896
897 c = 0x30 + ((v << (6 - bits)) & 0x3F);
898 d[count++] = c;
899 }
900 d[count++] = 0x70;
901 return(count);
902 }
903
904 void
905 slip_unesc6(struct slip *sl, unsigned char *s, int count, int error)
906 {
907 int i;
908 unsigned char c;
909
910 for (i = 0; i < count; ++i, ++s) {
911 if (*s == 0x70) {
912 if (sl->rcount > 8) {
913 #ifdef NOTDEF
914 printk("rbuff %02x %02x %02x %02x\n",
915 sl->rbuff[0],
916 sl->rbuff[1],
917 sl->rbuff[2],
918 sl->rbuff[3]
919 );
920 #endif
921 sl_bump(sl);
922 }
923 sl_dequeue(sl, sl->rcount);
924 sl->rcount = 0;
925 sl->flags &= ~(SLF_ESCAPE | SLF_ERROR);
926 sl->xbits = 0;
927 } else if (*s >= 0x30 && *s < 0x70) {
928 sl->xdata = (sl->xdata << 6) | ((*s - 0x30) & 0x3F);
929 sl->xbits += 6;
930 if (sl->xbits >= 8) {
931 sl->xbits -= 8;
932 c = (unsigned char)(sl->xdata >> sl->xbits);
933 sl_enqueue(sl, c);
934 }
935
936 }
937 }
938 if (error)
939 sl->flags |= SLF_ERROR;
940 }
941
942
943 static int
944 slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
945 {
946 struct slip *sl;
947 int err;
948
949
950 if ((sl = sl_find(tty)) == NULL) {
951 DPRINTF((DBG_SLIP, "SLIP: ioctl: TTY %d not connected !\n", tty->line));
952 return(-EINVAL);
953 }
954
955 DPRINTF((DBG_SLIP, "SLIP: ioctl(%d, 0x%X, 0x%X)\n", tty->line, cmd, arg));
956 switch(cmd) {
957 case SIOCGIFNAME:
958 err=verify_area(VERIFY_WRITE, arg, 16);
959 if(err)
960 return -err;
961 memcpy_tofs(arg, sl->dev->name, strlen(sl->dev->name) + 1);
962 return(0);
963 case SIOCGIFENCAP:
964 err=verify_area(VERIFY_WRITE,arg,sizeof(long));
965 put_fs_long(sl->mode,(long *)arg);
966 return(0);
967 case SIOCSIFENCAP:
968 err=verify_area(VERIFY_READ,arg,sizeof(long));
969 sl->mode=get_fs_long((long *)arg);
970 return(0);
971 default:
972 return(-EINVAL);
973 }
974 return(-EINVAL);
975 }
976
977
978
979 int
980 slip_init(struct device *dev)
981 {
982 struct slip *sl;
983 int i;
984
985 sl = &sl_ctrl[dev->base_addr];
986
987 if (already++ == 0) {
988 printk("SLIP: version %s (%d channels)\n",
989 SLIP_VERSION, SL_NRUNIT);
990 printk("CSLIP: code copyright 1989 Regents of the University of California\n");
991
992 sl_ldisc.flags = 0;
993 sl_ldisc.open = slip_open;
994 sl_ldisc.close = slip_close;
995 sl_ldisc.read = NULL;
996 sl_ldisc.write = NULL;
997 sl_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *,
998 unsigned int, unsigned long)) slip_ioctl;
999 sl_ldisc.handler = slip_recv;
1000 if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) == 0) printk("OK\n");
1001 else printk("ERROR: %d\n", i);
1002 }
1003
1004
1005 sl_initialize(sl, dev);
1006
1007
1008 sl->rcount = 0;
1009 sl->rpacket = 0;
1010 sl->roverrun = 0;
1011 sl->spacket = 0;
1012 sl->sbusy = 0;
1013 sl->errors = 0;
1014
1015
1016 dev->mtu = SL_MTU;
1017 dev->hard_start_xmit = sl_xmit;
1018 dev->open = sl_open;
1019 dev->stop = sl_close;
1020 dev->hard_header = sl_header;
1021 dev->add_arp = sl_add_arp;
1022 dev->type_trans = sl_type_trans;
1023 dev->hard_header_len = 0;
1024 dev->addr_len = 0;
1025 dev->type = 0;
1026 dev->queue_xmit = dev_queue_xmit;
1027 dev->rebuild_header = sl_rebuild_header;
1028 for (i = 0; i < DEV_NUMBUFFS; i++)
1029 dev->buffs[i] = NULL;
1030
1031
1032 dev->flags = 0;
1033 dev->family = AF_INET;
1034 dev->pa_addr = 0;
1035 dev->pa_brdaddr = 0;
1036 dev->pa_mask = 0;
1037 dev->pa_alen = sizeof(unsigned long);
1038
1039 return(0);
1040 }