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