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