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