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