This source file includes following definitions.
- ip_dump
- clh_dump
- sl_initialize
- sl_find
- sl_alloc
- sl_free
- 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_ioctl
- slip_init
1
2
3
4
5
6
7
8
9
10
11 #include <asm/segment.h>
12 #include <asm/system.h>
13 #include <linux/types.h>
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/string.h>
17 #include <linux/mm.h>
18 #include <linux/socket.h>
19 #include <linux/termios.h>
20 #include <linux/sockios.h>
21 #include <linux/interrupt.h>
22 #include <linux/tty.h>
23 #include <linux/errno.h>
24 #include <linux/stat.h>
25 #include <linux/tty.h>
26 #include <linux/in.h>
27 #include "inet.h"
28 #include "dev.h"
29 #include "eth.h"
30 #include "timer.h"
31 #include "ip.h"
32 #include "route.h"
33 #include "protocol.h"
34 #include "tcp.h"
35 #include "skbuff.h"
36 #include "sock.h"
37 #include "arp.h"
38 #include "slip.h"
39 #include "slhc.h"
40
41
42 #define SLIP_VERSION "0.7.5"
43
44 #ifdef SL_COMPRESSED
45 #define COMPRESSED_SLIP 1
46 #else
47 #define COMPRESSED_SLIP 0
48 #endif
49
50
51 #ifdef SL_DUMP
52 # define IP_VERSION 4
53 # define IPF_F_OFFSET 0x1fff
54 # define IPF_DF 0x4000
55 # define IPF_MF 0x2000
56 # define IP_OF_COPIED 0x80
57 # define IP_OF_CLASS 0x60
58 # define IP_OF_NUMBER 0x1f
59 #endif
60
61
62 static struct slip sl_ctrl[SL_NRUNIT];
63 static struct tty_ldisc sl_ldisc;
64 static int already = 0;
65
66
67
68 static void
69 ip_dump(unsigned char *ptr, int len)
70 {
71 #ifdef SL_DUMP
72 struct iphdr *ip;
73 struct tcphdr *th;
74 int dlen, doff;
75
76 if (inet_debug != DBG_SLIP) return;
77
78 ip = (struct iphdr *) ptr;
79 th = (struct tcphdr *) (ptr + ip->ihl * 4);
80 printk("\r%s -> %s seq %x ack %x len %d\n",
81 in_ntoa(ip->saddr), in_ntoa(ip->daddr),
82 ntohl(th->seq), ntohl(th->ack_seq), ntohs(ip->tot_len));
83 return;
84
85 printk("\r*****\n");
86 printk("%x %d\n", ptr, len);
87 ip = (struct iphdr *) ptr;
88 dlen = ntohs(ip->tot_len);
89 doff = ((ntohs(ip->frag_off) & IPF_F_OFFSET) << 3);
90
91
92 printk("SLIP: %s->", in_ntoa(ip->saddr));
93 printk("%s\n", in_ntoa(ip->daddr));
94 printk(" len %u ihl %u ver %u ttl %u prot %u",
95 dlen, ip->ihl, ip->version, ip->ttl, ip->protocol);
96
97 if (ip->tos != 0) printk(" tos %u", ip->tos);
98 if (doff != 0 || (ntohs(ip->frag_off) & IPF_MF))
99 printk(" id %u offs %u", ntohs(ip->id), doff);
100
101 if (ntohs(ip->frag_off) & IPF_DF) printk(" DF");
102 if (ntohs(ip->frag_off) & IPF_MF) printk(" MF");
103 printk("\n*****\n");
104 #endif
105 }
106
107 void clh_dump(unsigned char *cp, int len)
108 {
109 if (len > 60)
110 len = 60;
111 printk("%d:", len);
112 while (len > 0) {
113 printk(" %x", *cp++);
114 len--;
115 }
116 printk("\n\n");
117 }
118
119
120 static void
121 sl_initialize(struct slip *sl, struct device *dev)
122 {
123 sl->inuse = 0;
124 sl->sending = 0;
125 sl->escape = 0;
126
127 sl->line = dev->base_addr;
128 sl->tty = NULL;
129 sl->dev = dev;
130 sl->slcomp = NULL;
131
132
133 sl->rbuff = NULL;
134 sl->xbuff = NULL;
135 sl->cbuff = NULL;
136
137 sl->rhead = NULL;
138 sl->rend = NULL;
139 dev->rmem_end = (unsigned long) NULL;
140 dev->rmem_start = (unsigned long) NULL;
141 dev->mem_end = (unsigned long) NULL;
142 dev->mem_start = (unsigned long) NULL;
143 }
144
145
146
147 static struct slip *
148 sl_find(struct tty_struct *tty)
149 {
150 struct slip *sl;
151 int i;
152
153 if (tty == NULL) return(NULL);
154 for (i = 0; i < SL_NRUNIT; i++) {
155 sl = &sl_ctrl[i];
156 if (sl->tty == tty) return(sl);
157 }
158 return(NULL);
159 }
160
161
162
163 static inline struct slip *
164 sl_alloc(void)
165 {
166 unsigned long flags;
167 struct slip *sl;
168 int i;
169
170 for (i = 0; i < SL_NRUNIT; i++) {
171 sl = &sl_ctrl[i];
172 if (sl->inuse == 0) {
173 save_flags(flags);
174 cli();
175 sl->inuse = 1;
176 sl->tty = NULL;
177 restore_flags(flags);
178 return(sl);
179 }
180 }
181 return(NULL);
182 }
183
184
185
186 static inline void
187 sl_free(struct slip *sl)
188 {
189 unsigned long flags;
190
191 if (sl->inuse) {
192 save_flags(flags);
193 cli();
194 sl->inuse = 0;
195 sl->tty = NULL;
196 restore_flags(flags);
197 }
198 }
199
200
201
202 static inline void
203 sl_enqueue(struct slip *sl, unsigned char c)
204 {
205 unsigned long flags;
206
207 save_flags(flags);
208 cli();
209 if (sl->rhead < sl->rend) {
210 *sl->rhead = c;
211 sl->rhead++;
212 sl->rcount++;
213 } else sl->roverrun++;
214 restore_flags(flags);
215 }
216
217
218 static inline void
219 sl_dequeue(struct slip *sl, int i)
220 {
221 unsigned long flags;
222
223 save_flags(flags);
224 cli();
225 if (sl->rhead > sl->rbuff) {
226 sl->rhead -= i;
227 sl->rcount -= i;
228 }
229 restore_flags(flags);
230 }
231
232
233
234 static inline void
235 sl_lock(struct slip *sl)
236 {
237 unsigned long flags;
238
239 save_flags(flags);
240 cli();
241 sl->sending = 1;
242 sl->dev->tbusy = 1;
243 restore_flags(flags);
244 }
245
246
247
248 static inline void
249 sl_unlock(struct slip *sl)
250 {
251 unsigned long flags;
252
253 save_flags(flags);
254 cli();
255 sl->sending = 0;
256 sl->dev->tbusy = 0;
257 restore_flags(flags);
258 }
259
260
261
262 static void
263 sl_bump(struct slip *sl)
264 {
265 int done;
266 unsigned char c;
267 unsigned long flags;
268 int count;
269
270 count = sl->rcount;
271 if (COMPRESSED_SLIP) {
272 if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) {
273
274 save_flags(flags);
275 cli();
276 if ((sl->rhead + 80) < sl->rend) {
277 sl->rhead += 80;
278 sl->rcount += 80;
279 done = 1;
280 } else {
281 sl->roverrun++;
282 done = 0;
283 }
284 restore_flags(flags);
285 if (! done)
286 return;
287
288 if ((count = slhc_uncompress((struct slcompress *)sl->slcomp,
289 sl->rbuff, count)) <= 0 ) {
290 sl->errors++;
291 return;
292 }
293 } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
294 sl->rbuff[0] &= 0x4f;
295 if ( slhc_remember((struct slcompress *)sl->slcomp, sl->rbuff,
296 count ) <= 0 ) {
297 sl->errors++;
298 return;
299 }
300 }
301 }
302
303 DPRINTF((DBG_SLIP, "<< \"%s\" recv:\r\n", sl->dev->name));
304 ip_dump(sl->rbuff, sl->rcount);
305
306
307 do {
308 DPRINTF((DBG_SLIP, "SLIP: packet is %d at 0x%X\n",
309 sl->rcount, sl->rbuff));
310
311 done = dev_rint(sl->rbuff, count, 0, sl->dev);
312 if (done == 0 || done == 1) break;
313 } while(1);
314
315 sl->rpacket++;
316 }
317
318
319
320 static void
321 sl_next(struct slip *sl)
322 {
323 DPRINTF((DBG_SLIP, "SLIP: sl_next(0x%X) called!\n", sl));
324 sl_unlock(sl);
325 dev_tint(sl->dev);
326 }
327
328
329
330 static void
331 sl_encaps(struct slip *sl, unsigned char *icp, int len)
332 {
333 unsigned char *bp, *p;
334 unsigned char c;
335 int count;
336
337 DPRINTF((DBG_SLIP, "SLIP: sl_encaps(0x%X, %d) called\n", p, len));
338 DPRINTF((DBG_SLIP, ">> \"%s\" sent:\r\n", sl->dev->name));
339 ip_dump(icp, len);
340
341 p = icp;
342 len = slhc_compress((struct slcompress *)sl->slcomp, p, len,
343 sl->cbuff, &p, 1);
344
345
346
347
348
349
350 bp = (unsigned char *) sl->xbuff;
351 *bp++ = END;
352 count = 1;
353
354
355
356
357
358 while(len-- > 0) {
359 c = *p++;
360 switch((c & 0377)) {
361 case END:
362 *bp++ = ESC;
363 *bp++ = ESC_END;
364 count += 2;
365 break;
366 case ESC:
367 *bp++ = ESC;
368 *bp++ = ESC_ESC;
369 count += 2;
370 break;
371 default:
372 *bp++ = c;
373 count++;
374 }
375 }
376 *bp++ = END;
377 count++;
378 sl->spacket++;
379 bp = (unsigned char *) sl->xbuff;
380
381
382 DPRINTF((DBG_SLIP, "SLIP: kicking TTY for %d bytes at 0x%X\n", count, bp));
383 if (tty_write_data(sl->tty, (char *) bp, count,
384 (void (*)(void *))sl_next, (void *) sl) == 0) {
385 DPRINTF((DBG_SLIP, "SLIP: TTY already done with %d bytes!\n", count));
386 sl_next(sl);
387 }
388 }
389
390
391
392 static int
393 sl_xmit(struct sk_buff *skb, struct device *dev)
394 {
395 struct tty_struct *tty;
396 struct slip *sl;
397
398
399 sl = &sl_ctrl[dev->base_addr];
400 tty = sl->tty;
401 DPRINTF((DBG_SLIP, "SLIP: sl_xmit(\"%s\") skb=0x%X busy=%d\n",
402 dev->name, skb, sl->sending));
403
404
405
406
407
408
409 if (sl->sending) {
410 DPRINTF((DBG_SLIP, "SLIP: sl_xmit: BUSY\r\n"));
411 sl->sbusy++;
412 return(1);
413 }
414
415
416 if (skb != NULL) {
417 sl_lock(sl);
418 sl_encaps(sl, (unsigned char *) (skb + 1), skb->len);
419 if (skb->free) kfree_skb(skb, FREE_WRITE);
420 }
421 return(0);
422 }
423
424
425
426 static unsigned short
427 sl_type_trans (struct sk_buff *skb, struct device *dev)
428 {
429 return(NET16(ETH_P_IP));
430 }
431
432
433
434 static int
435 sl_header(unsigned char *buff, struct device *dev, unsigned short type,
436 unsigned long daddr, unsigned long saddr, unsigned len)
437 {
438 return(0);
439 }
440
441
442
443 static void
444 sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
445 {
446 }
447
448
449
450 static int
451 sl_rebuild_header(void *buff, struct device *dev)
452 {
453 return(0);
454 }
455
456
457
458 static int
459 sl_open(struct device *dev)
460 {
461 struct slip *sl;
462 unsigned char *p;
463 unsigned long l;
464
465 sl = &sl_ctrl[dev->base_addr];
466 if (sl->tty == NULL) {
467 DPRINTF((DBG_SLIP, "SLIP: channel %d not connected!\n", sl->line));
468 return(-ENXIO);
469 }
470 sl->dev = dev;
471
472
473
474
475
476
477
478
479
480 l = (dev->mtu * 2);
481 p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
482 if (p == NULL) {
483 DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP XMIT buffer!\n"));
484 return(-ENOMEM);
485 }
486 sl->dev->mem_start = (unsigned long) p;
487 sl->dev->mem_end = (unsigned long) (sl->dev->mem_start + l);
488
489 p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
490 if (p == NULL) {
491 DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP RECV buffer!\n"));
492 return(-ENOMEM);
493 }
494 sl->dev->rmem_start = (unsigned long) p;
495 sl->dev->rmem_end = (unsigned long) (sl->dev->rmem_start + l);
496
497 sl->xbuff = (unsigned char *) sl->dev->mem_start;
498 sl->rbuff = (unsigned char *) sl->dev->rmem_start;
499 sl->rend = (unsigned char *) sl->dev->rmem_end;
500 sl->rhead = sl->rbuff;
501
502 sl->escape = 0;
503 sl->sending = 0;
504 sl->rcount = 0;
505
506 p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
507 if (p == NULL) {
508 DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP COMPRESS buffer!\n"));
509 return(-ENOMEM);
510 }
511 sl->cbuff = p;
512
513 sl->slcomp = slhc_init(16, 16);
514 if (sl->slcomp == NULL) {
515 DPRINTF((DBG_SLIP, "SLIP: no memory for SLCOMP!\n"));
516 return(-ENOMEM);
517 }
518
519 DPRINTF((DBG_SLIP, "SLIP: channel %d opened.\n", sl->line));
520 return(0);
521 }
522
523
524
525 static int
526 sl_close(struct device *dev)
527 {
528 struct slip *sl;
529
530 sl = &sl_ctrl[dev->base_addr];
531 if (sl->tty == NULL) {
532 DPRINTF((DBG_SLIP, "SLIP: channel %d not connected!\n", sl->line));
533 return(-EBUSY);
534 }
535 sl_free(sl);
536
537
538 kfree(sl->rbuff);
539 kfree(sl->xbuff);
540 kfree(sl->cbuff);
541 slhc_free(sl->slcomp);
542
543 sl_initialize(sl, dev);
544
545 DPRINTF((DBG_SLIP, "SLIP: channel %d closed.\n", sl->line));
546 return(0);
547 }
548
549
550
551
552
553
554
555
556 static void
557 slip_recv(struct tty_struct *tty)
558 {
559 unsigned char buff[128];
560 unsigned char *p, c;
561 struct slip *sl;
562 int count;
563
564 DPRINTF((DBG_SLIP, "SLIP: slip_recv(%d) called\n", tty->line));
565 if ((sl = sl_find(tty)) == NULL) return;
566
567
568 do {
569 memset(buff, 0, 128);
570 count = tty_read_raw_data(tty, buff, 128);
571 if (count <= 0) break;
572
573 p = buff;
574 while(count-- > 0) {
575 c = *p++;
576 switch((c & 0377)) {
577 case ESC:
578 sl->escape = 1;
579 break;
580 case ESC_ESC:
581 if (sl->escape) sl_enqueue(sl, ESC);
582 else sl_enqueue(sl, c);
583 sl->escape = 0;
584 break;
585 case ESC_END:
586 if (sl->escape) sl_enqueue(sl, END);
587 else sl_enqueue(sl, c);
588 sl->escape = 0;
589 break;
590 case END:
591 if (sl->rcount > 2) sl_bump(sl);
592 sl_dequeue(sl, sl->rcount);
593 sl->rcount = 0;
594 sl->escape = 0;
595 break;
596 default:
597 sl_enqueue(sl, c);
598 sl->escape = 0;
599 }
600 }
601 } while(1);
602 }
603
604
605
606
607
608
609
610
611
612 static int
613 slip_open(struct tty_struct *tty)
614 {
615 struct slip *sl;
616
617
618 if ((sl = sl_find(tty)) != NULL) {
619 DPRINTF((DBG_SLIP, "SLIP: TTY %d already connected to %s !\n",
620 tty->line, sl->dev->name));
621 return(-EEXIST);
622 }
623
624
625 if ((sl = sl_alloc()) == NULL) {
626 DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected: all channels in use!\n",
627 tty->line));
628 return(-ENFILE);
629 }
630 sl->tty = tty;
631 tty_read_flush(tty);
632 tty_write_flush(tty);
633
634
635 (void) sl_open(sl->dev);
636 DPRINTF((DBG_SLIP, "SLIP: TTY %d connected to %s.\n",
637 tty->line, sl->dev->name));
638
639
640 return(sl->line);
641 }
642
643
644
645
646
647
648
649
650 static void
651 slip_close(struct tty_struct *tty)
652 {
653 struct slip *sl;
654
655
656 if ((sl = sl_find(tty)) == NULL) {
657 DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected !\n", tty->line));
658 return;
659 }
660
661 (void) dev_close(sl->dev);
662 DPRINTF((DBG_SLIP, "SLIP: TTY %d disconnected from %s.\n",
663 tty->line, sl->dev->name));
664 }
665
666
667
668 static int
669 slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
670 {
671 struct slip *sl;
672
673
674 if ((sl = sl_find(tty)) == NULL) {
675 DPRINTF((DBG_SLIP, "SLIP: ioctl: TTY %d not connected !\n", tty->line));
676 return(-EINVAL);
677 }
678
679 DPRINTF((DBG_SLIP, "SLIP: ioctl(%d, 0x%X, 0x%X)\n", tty->line, cmd, arg));
680 switch(cmd) {
681 case SIOCGIFNAME:
682 verify_area(VERIFY_WRITE, arg, 16);
683 memcpy_tofs(arg, sl->dev->name, strlen(sl->dev->name) + 1);
684 return(0);
685 default:
686 return(-EINVAL);
687 }
688 return(-EINVAL);
689 }
690
691
692
693 int
694 slip_init(struct device *dev)
695 {
696 struct slip *sl;
697 int i;
698
699 sl = &sl_ctrl[dev->base_addr];
700
701 if (already++ == 0) {
702 printk("SLIP: version %s (%d channels): ",
703 SLIP_VERSION, SL_NRUNIT);
704
705
706 sl_ldisc.flags = 0;
707 sl_ldisc.open = slip_open;
708 sl_ldisc.close = slip_close;
709 sl_ldisc.read = NULL;
710 sl_ldisc.write = NULL;
711 sl_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *,
712 unsigned int, unsigned long)) slip_ioctl;
713 sl_ldisc.handler = slip_recv;
714 if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) == 0) printk("OK\n");
715 else printk("ERROR: %d\n", i);
716 }
717
718
719 sl_initialize(sl, dev);
720
721
722 sl->rcount = 0;
723 sl->rpacket = 0;
724 sl->roverrun = 0;
725 sl->spacket = 0;
726 sl->sbusy = 0;
727 sl->errors = 0;
728
729
730 dev->mtu = SL_MTU;
731 dev->hard_start_xmit = sl_xmit;
732 dev->open = sl_open;
733 dev->stop = sl_close;
734 dev->hard_header = sl_header;
735 dev->add_arp = sl_add_arp;
736 dev->type_trans = sl_type_trans;
737 dev->hard_header_len = 0;
738 dev->addr_len = 0;
739 dev->type = 0;
740 dev->queue_xmit = dev_queue_xmit;
741 dev->rebuild_header = sl_rebuild_header;
742 for (i = 0; i < DEV_NUMBUFFS; i++)
743 dev->buffs[i] = NULL;
744
745
746 dev->flags = 0;
747 dev->family = AF_INET;
748 dev->pa_addr = 0;
749 dev->pa_brdaddr = 0;
750 dev->pa_mask = 0;
751 dev->pa_alen = sizeof(unsigned long);
752
753 return(0);
754 }