File: /usr/src/linux/drivers/net/ppp_async.c
1 /*
2 * PPP async serial channel driver for Linux.
3 *
4 * Copyright 1999 Paul Mackerras.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * This driver provides the encapsulation and framing for sending
12 * and receiving PPP frames over async serial lines. It relies on
13 * the generic PPP layer to give it frames to send and to process
14 * received frames. It implements the PPP line discipline.
15 *
16 * Part of the code in this driver was inspired by the old async-only
17 * PPP driver, written by Michael Callahan and Al Longyear, and
18 * subsequently hacked by Paul Mackerras.
19 *
20 * ==FILEVERSION 20000227==
21 */
22
23 #include <linux/module.h>
24 #include <linux/kernel.h>
25 #include <linux/skbuff.h>
26 #include <linux/tty.h>
27 #include <linux/netdevice.h>
28 #include <linux/poll.h>
29 #include <linux/ppp_defs.h>
30 #include <linux/if_ppp.h>
31 #include <linux/ppp_channel.h>
32 #include <linux/spinlock.h>
33 #include <linux/init.h>
34 #include <asm/uaccess.h>
35
36 #define PPP_VERSION "2.4.1"
37
38 #define OBUFSIZE 256
39
40 /* Structure for storing local state. */
41 struct asyncppp {
42 struct tty_struct *tty;
43 unsigned int flags;
44 unsigned int state;
45 unsigned int rbits;
46 int mru;
47 spinlock_t xmit_lock;
48 spinlock_t recv_lock;
49 unsigned long xmit_flags;
50 u32 xaccm[8];
51 u32 raccm;
52 unsigned int bytes_sent;
53 unsigned int bytes_rcvd;
54
55 struct sk_buff *tpkt;
56 int tpkt_pos;
57 u16 tfcs;
58 unsigned char *optr;
59 unsigned char *olim;
60 unsigned long last_xmit;
61
62 struct sk_buff *rpkt;
63 int lcp_fcs;
64
65 struct ppp_channel chan; /* interface to generic ppp layer */
66 unsigned char obuf[OBUFSIZE];
67 };
68
69 /* Bit numbers in xmit_flags */
70 #define XMIT_WAKEUP 0
71 #define XMIT_FULL 1
72 #define XMIT_BUSY 2
73
74 /* State bits */
75 #define SC_TOSS 0x20000000
76 #define SC_ESCAPE 0x40000000
77
78 /* Bits in rbits */
79 #define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)
80
81 static int flag_time = HZ;
82 MODULE_PARM(flag_time, "i");
83 MODULE_PARM_DESC(flag_time, "ppp_async: interval between flagged packets (in clock ticks)");
84
85 /*
86 * Prototypes.
87 */
88 static int ppp_async_encode(struct asyncppp *ap);
89 static int ppp_async_send(struct ppp_channel *chan, struct sk_buff *skb);
90 static int ppp_async_push(struct asyncppp *ap);
91 static void ppp_async_flush_output(struct asyncppp *ap);
92 static void ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
93 char *flags, int count);
94 static int ppp_async_ioctl(struct ppp_channel *chan, unsigned int cmd,
95 unsigned long arg);
96 static void async_lcp_peek(struct asyncppp *ap, unsigned char *data,
97 int len, int inbound);
98
99 static struct ppp_channel_ops async_ops = {
100 ppp_async_send,
101 ppp_async_ioctl
102 };
103
104 /*
105 * Routines implementing the PPP line discipline.
106 */
107
108 /*
109 * Called when a tty is put into PPP line discipline.
110 */
111 static int
112 ppp_asynctty_open(struct tty_struct *tty)
113 {
114 struct asyncppp *ap;
115 int err;
116
117 MOD_INC_USE_COUNT;
118 err = -ENOMEM;
119 ap = kmalloc(sizeof(*ap), GFP_KERNEL);
120 if (ap == 0)
121 goto out;
122
123 /* initialize the asyncppp structure */
124 memset(ap, 0, sizeof(*ap));
125 ap->tty = tty;
126 ap->mru = PPP_MRU;
127 spin_lock_init(&ap->xmit_lock);
128 spin_lock_init(&ap->recv_lock);
129 ap->xaccm[0] = ~0U;
130 ap->xaccm[3] = 0x60000000U;
131 ap->raccm = ~0U;
132 ap->optr = ap->obuf;
133 ap->olim = ap->obuf;
134 ap->lcp_fcs = -1;
135
136 ap->chan.private = ap;
137 ap->chan.ops = &async_ops;
138 ap->chan.mtu = PPP_MRU;
139 err = ppp_register_channel(&ap->chan);
140 if (err)
141 goto out_free;
142
143 tty->disc_data = ap;
144
145 return 0;
146
147 out_free:
148 kfree(ap);
149 out:
150 MOD_DEC_USE_COUNT;
151 return err;
152 }
153
154 /*
155 * Called when the tty is put into another line discipline
156 * or it hangs up.
157 * We assume that while we are in this routine, the tty layer
158 * won't call any of the other line discipline entries for the
159 * same tty.
160 */
161 static void
162 ppp_asynctty_close(struct tty_struct *tty)
163 {
164 struct asyncppp *ap = tty->disc_data;
165
166 if (ap == 0)
167 return;
168 tty->disc_data = 0;
169 ppp_unregister_channel(&ap->chan);
170 if (ap->rpkt != 0)
171 kfree_skb(ap->rpkt);
172 if (ap->tpkt != 0)
173 kfree_skb(ap->tpkt);
174 kfree(ap);
175 MOD_DEC_USE_COUNT;
176 }
177
178 /*
179 * Read does nothing - no data is ever available this way.
180 * Pppd reads and writes packets via /dev/ppp instead.
181 */
182 static ssize_t
183 ppp_asynctty_read(struct tty_struct *tty, struct file *file,
184 unsigned char *buf, size_t count)
185 {
186 return -EAGAIN;
187 }
188
189 /*
190 * Write on the tty does nothing, the packets all come in
191 * from the ppp generic stuff.
192 */
193 static ssize_t
194 ppp_asynctty_write(struct tty_struct *tty, struct file *file,
195 const unsigned char *buf, size_t count)
196 {
197 return -EAGAIN;
198 }
199
200 static int
201 ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
202 unsigned int cmd, unsigned long arg)
203 {
204 struct asyncppp *ap = tty->disc_data;
205 int err, val;
206
207 err = -EFAULT;
208 switch (cmd) {
209 case PPPIOCGCHAN:
210 err = -ENXIO;
211 if (ap == 0)
212 break;
213 err = -EFAULT;
214 if (put_user(ppp_channel_index(&ap->chan), (int *) arg))
215 break;
216 err = 0;
217 break;
218
219 case PPPIOCGUNIT:
220 err = -ENXIO;
221 if (ap == 0)
222 break;
223 err = -EFAULT;
224 if (put_user(ppp_unit_number(&ap->chan), (int *) arg))
225 break;
226 err = 0;
227 break;
228
229 case TCGETS:
230 case TCGETA:
231 err = n_tty_ioctl(tty, file, cmd, arg);
232 break;
233
234 case TCFLSH:
235 /* flush our buffers and the serial port's buffer */
236 if (arg == TCIOFLUSH || arg == TCOFLUSH)
237 ppp_async_flush_output(ap);
238 err = n_tty_ioctl(tty, file, cmd, arg);
239 break;
240
241 case FIONREAD:
242 val = 0;
243 if (put_user(val, (int *) arg))
244 break;
245 err = 0;
246 break;
247
248 default:
249 err = -ENOIOCTLCMD;
250 }
251
252 return err;
253 }
254
255 /* No kernel lock - fine */
256 static unsigned int
257 ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
258 {
259 return 0;
260 }
261
262 static int
263 ppp_asynctty_room(struct tty_struct *tty)
264 {
265 return 65535;
266 }
267
268 static void
269 ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
270 char *flags, int count)
271 {
272 struct asyncppp *ap = tty->disc_data;
273
274 if (ap == 0)
275 return;
276 spin_lock_bh(&ap->recv_lock);
277 ppp_async_input(ap, buf, flags, count);
278 spin_unlock_bh(&ap->recv_lock);
279 if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
280 && tty->driver.unthrottle)
281 tty->driver.unthrottle(tty);
282 }
283
284 static void
285 ppp_asynctty_wakeup(struct tty_struct *tty)
286 {
287 struct asyncppp *ap = tty->disc_data;
288
289 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
290 if (ap == 0)
291 return;
292 if (ppp_async_push(ap))
293 ppp_output_wakeup(&ap->chan);
294 }
295
296
297 static struct tty_ldisc ppp_ldisc = {
298 magic: TTY_LDISC_MAGIC,
299 name: "ppp",
300 open: ppp_asynctty_open,
301 close: ppp_asynctty_close,
302 read: ppp_asynctty_read,
303 write: ppp_asynctty_write,
304 ioctl: ppp_asynctty_ioctl,
305 poll: ppp_asynctty_poll,
306 receive_room: ppp_asynctty_room,
307 receive_buf: ppp_asynctty_receive,
308 write_wakeup: ppp_asynctty_wakeup,
309 };
310
311 static int __init
312 ppp_async_init(void)
313 {
314 int err;
315
316 err = tty_register_ldisc(N_PPP, &ppp_ldisc);
317 if (err != 0)
318 printk(KERN_ERR "PPP_async: error %d registering line disc.\n",
319 err);
320 return err;
321 }
322
323 /*
324 * The following routines provide the PPP channel interface.
325 */
326 static int
327 ppp_async_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg)
328 {
329 struct asyncppp *ap = chan->private;
330 int err, val;
331 u32 accm[8];
332
333 err = -EFAULT;
334 switch (cmd) {
335 case PPPIOCGFLAGS:
336 val = ap->flags | ap->rbits;
337 if (put_user(val, (int *) arg))
338 break;
339 err = 0;
340 break;
341 case PPPIOCSFLAGS:
342 if (get_user(val, (int *) arg))
343 break;
344 ap->flags = val & ~SC_RCV_BITS;
345 spin_lock_bh(&ap->recv_lock);
346 ap->rbits = val & SC_RCV_BITS;
347 spin_unlock_bh(&ap->recv_lock);
348 err = 0;
349 break;
350
351 case PPPIOCGASYNCMAP:
352 if (put_user(ap->xaccm[0], (u32 *) arg))
353 break;
354 err = 0;
355 break;
356 case PPPIOCSASYNCMAP:
357 if (get_user(ap->xaccm[0], (u32 *) arg))
358 break;
359 err = 0;
360 break;
361
362 case PPPIOCGRASYNCMAP:
363 if (put_user(ap->raccm, (u32 *) arg))
364 break;
365 err = 0;
366 break;
367 case PPPIOCSRASYNCMAP:
368 if (get_user(ap->raccm, (u32 *) arg))
369 break;
370 err = 0;
371 break;
372
373 case PPPIOCGXASYNCMAP:
374 if (copy_to_user((void *) arg, ap->xaccm, sizeof(ap->xaccm)))
375 break;
376 err = 0;
377 break;
378 case PPPIOCSXASYNCMAP:
379 if (copy_from_user(accm, (void *) arg, sizeof(accm)))
380 break;
381 accm[2] &= ~0x40000000U; /* can't escape 0x5e */
382 accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */
383 memcpy(ap->xaccm, accm, sizeof(ap->xaccm));
384 err = 0;
385 break;
386
387 case PPPIOCGMRU:
388 if (put_user(ap->mru, (int *) arg))
389 break;
390 err = 0;
391 break;
392 case PPPIOCSMRU:
393 if (get_user(val, (int *) arg))
394 break;
395 if (val < PPP_MRU)
396 val = PPP_MRU;
397 ap->mru = val;
398 err = 0;
399 break;
400
401 default:
402 err = -ENOTTY;
403 }
404
405 return err;
406 }
407
408 /*
409 * Procedures for encapsulation and framing.
410 */
411
412 u16 ppp_crc16_table[256] = {
413 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
414 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
415 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
416 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
417 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
418 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
419 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
420 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
421 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
422 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
423 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
424 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
425 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
426 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
427 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
428 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
429 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
430 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
431 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
432 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
433 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
434 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
435 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
436 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
437 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
438 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
439 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
440 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
441 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
442 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
443 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
444 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
445 };
446 EXPORT_SYMBOL(ppp_crc16_table);
447 #define fcstab ppp_crc16_table /* for PPP_FCS macro */
448
449 /*
450 * Procedure to encode the data for async serial transmission.
451 * Does octet stuffing (escaping), puts the address/control bytes
452 * on if A/C compression is disabled, and does protocol compression.
453 * Assumes ap->tpkt != 0 on entry.
454 * Returns 1 if we finished the current frame, 0 otherwise.
455 */
456
457 #define PUT_BYTE(ap, buf, c, islcp) do { \
458 if ((islcp && c < 0x20) || (ap->xaccm[c >> 5] & (1 << (c & 0x1f)))) {\
459 *buf++ = PPP_ESCAPE; \
460 *buf++ = c ^ 0x20; \
461 } else \
462 *buf++ = c; \
463 } while (0)
464
465 static int
466 ppp_async_encode(struct asyncppp *ap)
467 {
468 int fcs, i, count, c, proto;
469 unsigned char *buf, *buflim;
470 unsigned char *data;
471 int islcp;
472
473 buf = ap->obuf;
474 ap->olim = buf;
475 ap->optr = buf;
476 i = ap->tpkt_pos;
477 data = ap->tpkt->data;
478 count = ap->tpkt->len;
479 fcs = ap->tfcs;
480 proto = (data[0] << 8) + data[1];
481
482 /*
483 * LCP packets with code values between 1 (configure-reqest)
484 * and 7 (code-reject) must be sent as though no options
485 * had been negotiated.
486 */
487 islcp = proto == PPP_LCP && 1 <= data[2] && data[2] <= 7;
488
489 if (i == 0) {
490 if (islcp)
491 async_lcp_peek(ap, data, count, 0);
492
493 /*
494 * Start of a new packet - insert the leading FLAG
495 * character if necessary.
496 */
497 if (islcp || flag_time == 0
498 || jiffies - ap->last_xmit >= flag_time)
499 *buf++ = PPP_FLAG;
500 ap->last_xmit = jiffies;
501 fcs = PPP_INITFCS;
502
503 /*
504 * Put in the address/control bytes if necessary
505 */
506 if ((ap->flags & SC_COMP_AC) == 0 || islcp) {
507 PUT_BYTE(ap, buf, 0xff, islcp);
508 fcs = PPP_FCS(fcs, 0xff);
509 PUT_BYTE(ap, buf, 0x03, islcp);
510 fcs = PPP_FCS(fcs, 0x03);
511 }
512 }
513
514 /*
515 * Once we put in the last byte, we need to put in the FCS
516 * and closing flag, so make sure there is at least 7 bytes
517 * of free space in the output buffer.
518 */
519 buflim = ap->obuf + OBUFSIZE - 6;
520 while (i < count && buf < buflim) {
521 c = data[i++];
522 if (i == 1 && c == 0 && (ap->flags & SC_COMP_PROT))
523 continue; /* compress protocol field */
524 fcs = PPP_FCS(fcs, c);
525 PUT_BYTE(ap, buf, c, islcp);
526 }
527
528 if (i < count) {
529 /*
530 * Remember where we are up to in this packet.
531 */
532 ap->olim = buf;
533 ap->tpkt_pos = i;
534 ap->tfcs = fcs;
535 return 0;
536 }
537
538 /*
539 * We have finished the packet. Add the FCS and flag.
540 */
541 fcs = ~fcs;
542 c = fcs & 0xff;
543 PUT_BYTE(ap, buf, c, islcp);
544 c = (fcs >> 8) & 0xff;
545 PUT_BYTE(ap, buf, c, islcp);
546 *buf++ = PPP_FLAG;
547 ap->olim = buf;
548
549 kfree_skb(ap->tpkt);
550 ap->tpkt = 0;
551 return 1;
552 }
553
554 /*
555 * Transmit-side routines.
556 */
557
558 /*
559 * Send a packet to the peer over an async tty line.
560 * Returns 1 iff the packet was accepted.
561 * If the packet was not accepted, we will call ppp_output_wakeup
562 * at some later time.
563 */
564 static int
565 ppp_async_send(struct ppp_channel *chan, struct sk_buff *skb)
566 {
567 struct asyncppp *ap = chan->private;
568
569 ppp_async_push(ap);
570
571 if (test_and_set_bit(XMIT_FULL, &ap->xmit_flags))
572 return 0; /* already full */
573 ap->tpkt = skb;
574 ap->tpkt_pos = 0;
575
576 ppp_async_push(ap);
577 return 1;
578 }
579
580 /*
581 * Push as much data as possible out to the tty.
582 */
583 static int
584 ppp_async_push(struct asyncppp *ap)
585 {
586 int avail, sent, done = 0;
587 struct tty_struct *tty = ap->tty;
588 int tty_stuffed = 0;
589
590 set_bit(XMIT_WAKEUP, &ap->xmit_flags);
591 /*
592 * We can get called recursively here if the tty write
593 * function calls our wakeup function. This can happen
594 * for example on a pty with both the master and slave
595 * set to PPP line discipline.
596 * We use the XMIT_BUSY bit to detect this and get out,
597 * leaving the XMIT_WAKEUP bit set to tell the other
598 * instance that it may now be able to write more now.
599 */
600 if (test_and_set_bit(XMIT_BUSY, &ap->xmit_flags))
601 return 0;
602 spin_lock_bh(&ap->xmit_lock);
603 for (;;) {
604 if (test_and_clear_bit(XMIT_WAKEUP, &ap->xmit_flags))
605 tty_stuffed = 0;
606 if (!tty_stuffed && ap->optr < ap->olim) {
607 avail = ap->olim - ap->optr;
608 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
609 sent = tty->driver.write(tty, 0, ap->optr, avail);
610 if (sent < 0)
611 goto flush; /* error, e.g. loss of CD */
612 ap->optr += sent;
613 if (sent < avail)
614 tty_stuffed = 1;
615 continue;
616 }
617 if (ap->optr >= ap->olim && ap->tpkt != 0) {
618 if (ppp_async_encode(ap)) {
619 /* finished processing ap->tpkt */
620 clear_bit(XMIT_FULL, &ap->xmit_flags);
621 done = 1;
622 }
623 continue;
624 }
625 /*
626 * We haven't made any progress this time around.
627 * Clear XMIT_BUSY to let other callers in, but
628 * after doing so we have to check if anyone set
629 * XMIT_WAKEUP since we last checked it. If they
630 * did, we should try again to set XMIT_BUSY and go
631 * around again in case XMIT_BUSY was still set when
632 * the other caller tried.
633 */
634 clear_bit(XMIT_BUSY, &ap->xmit_flags);
635 /* any more work to do? if not, exit the loop */
636 if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags)
637 || (!tty_stuffed && ap->tpkt != 0)))
638 break;
639 /* more work to do, see if we can do it now */
640 if (test_and_set_bit(XMIT_BUSY, &ap->xmit_flags))
641 break;
642 }
643 spin_unlock_bh(&ap->xmit_lock);
644 return done;
645
646 flush:
647 clear_bit(XMIT_BUSY, &ap->xmit_flags);
648 if (ap->tpkt != 0) {
649 kfree_skb(ap->tpkt);
650 ap->tpkt = 0;
651 clear_bit(XMIT_FULL, &ap->xmit_flags);
652 done = 1;
653 }
654 ap->optr = ap->olim;
655 spin_unlock_bh(&ap->xmit_lock);
656 return done;
657 }
658
659 /*
660 * Flush output from our internal buffers.
661 * Called for the TCFLSH ioctl.
662 */
663 static void
664 ppp_async_flush_output(struct asyncppp *ap)
665 {
666 int done = 0;
667
668 spin_lock_bh(&ap->xmit_lock);
669 ap->optr = ap->olim;
670 if (ap->tpkt != NULL) {
671 kfree_skb(ap->tpkt);
672 ap->tpkt = 0;
673 clear_bit(XMIT_FULL, &ap->xmit_flags);
674 done = 1;
675 }
676 spin_unlock_bh(&ap->xmit_lock);
677 if (done)
678 ppp_output_wakeup(&ap->chan);
679 }
680
681 /*
682 * Receive-side routines.
683 */
684
685 /* see how many ordinary chars there are at the start of buf */
686 static inline int
687 scan_ordinary(struct asyncppp *ap, const unsigned char *buf, int count)
688 {
689 int i, c;
690
691 for (i = 0; i < count; ++i) {
692 c = buf[i];
693 if (c == PPP_ESCAPE || c == PPP_FLAG
694 || (c < 0x20 && (ap->raccm & (1 << c)) != 0))
695 break;
696 }
697 return i;
698 }
699
700 /* called when a flag is seen - do end-of-packet processing */
701 static inline void
702 process_input_packet(struct asyncppp *ap)
703 {
704 struct sk_buff *skb;
705 unsigned char *p;
706 unsigned int len, fcs, proto;
707 int code = 0;
708
709 skb = ap->rpkt;
710 ap->rpkt = 0;
711 if ((ap->state & (SC_TOSS | SC_ESCAPE)) || skb == 0) {
712 ap->state &= ~(SC_TOSS | SC_ESCAPE);
713 if (skb != 0)
714 kfree_skb(skb);
715 return;
716 }
717
718 /* check the FCS */
719 p = skb->data;
720 len = skb->len;
721 if (len < 3)
722 goto err; /* too short */
723 fcs = PPP_INITFCS;
724 for (; len > 0; --len)
725 fcs = PPP_FCS(fcs, *p++);
726 if (fcs != PPP_GOODFCS)
727 goto err; /* bad FCS */
728 skb_trim(skb, skb->len - 2);
729
730 /* check for address/control and protocol compression */
731 p = skb->data;
732 if (p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) {
733 /* chop off address/control */
734 if (skb->len < 3)
735 goto err;
736 p = skb_pull(skb, 2);
737 }
738 proto = p[0];
739 if (proto & 1) {
740 /* protocol is compressed */
741 skb_push(skb, 1)[0] = 0;
742 } else {
743 if (skb->len < 2)
744 goto err;
745 proto = (proto << 8) + p[1];
746 if (proto == PPP_LCP)
747 async_lcp_peek(ap, p, skb->len, 1);
748 }
749
750 /* all OK, give it to the generic layer */
751 ppp_input(&ap->chan, skb);
752 return;
753
754 err:
755 kfree_skb(skb);
756 ppp_input_error(&ap->chan, code);
757 }
758
759 static inline void
760 input_error(struct asyncppp *ap, int code)
761 {
762 ap->state |= SC_TOSS;
763 ppp_input_error(&ap->chan, code);
764 }
765
766 /* called when the tty driver has data for us. */
767 static void
768 ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
769 char *flags, int count)
770 {
771 struct sk_buff *skb;
772 int c, i, j, n, s, f;
773 unsigned char *sp;
774
775 /* update bits used for 8-bit cleanness detection */
776 if (~ap->rbits & SC_RCV_BITS) {
777 s = 0;
778 for (i = 0; i < count; ++i) {
779 c = buf[i];
780 if (flags != 0 && flags[i] != 0)
781 continue;
782 s |= (c & 0x80)? SC_RCV_B7_1: SC_RCV_B7_0;
783 c = ((c >> 4) ^ c) & 0xf;
784 s |= (0x6996 & (1 << c))? SC_RCV_ODDP: SC_RCV_EVNP;
785 }
786 ap->rbits |= s;
787 }
788
789 while (count > 0) {
790 /* scan through and see how many chars we can do in bulk */
791 if ((ap->state & SC_ESCAPE) && buf[0] == PPP_ESCAPE)
792 n = 1;
793 else
794 n = scan_ordinary(ap, buf, count);
795
796 f = 0;
797 if (flags != 0 && (ap->state & SC_TOSS) == 0) {
798 /* check the flags to see if any char had an error */
799 for (j = 0; j < n; ++j)
800 if ((f = flags[j]) != 0)
801 break;
802 }
803 if (f != 0) {
804 /* start tossing */
805 input_error(ap, f);
806
807 } else if (n > 0 && (ap->state & SC_TOSS) == 0) {
808 /* stuff the chars in the skb */
809 skb = ap->rpkt;
810 if (skb == 0) {
811 skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
812 if (skb == 0)
813 goto nomem;
814 /* Try to get the payload 4-byte aligned */
815 if (buf[0] != PPP_ALLSTATIONS)
816 skb_reserve(skb, 2 + (buf[0] & 1));
817 ap->rpkt = skb;
818 }
819 if (n > skb_tailroom(skb)) {
820 /* packet overflowed MRU */
821 input_error(ap, 1);
822 } else {
823 sp = skb_put(skb, n);
824 memcpy(sp, buf, n);
825 if (ap->state & SC_ESCAPE) {
826 sp[0] ^= 0x20;
827 ap->state &= ~SC_ESCAPE;
828 }
829 }
830 }
831
832 if (n >= count)
833 break;
834
835 c = buf[n];
836 if (c == PPP_FLAG) {
837 process_input_packet(ap);
838 } else if (c == PPP_ESCAPE) {
839 ap->state |= SC_ESCAPE;
840 }
841 /* otherwise it's a char in the recv ACCM */
842 ++n;
843
844 buf += n;
845 if (flags != 0)
846 flags += n;
847 count -= n;
848 }
849 return;
850
851 nomem:
852 printk(KERN_ERR "PPPasync: no memory (input pkt)\n");
853 input_error(ap, 0);
854 }
855
856 /*
857 * We look at LCP frames going past so that we can notice
858 * and react to the LCP configure-ack from the peer.
859 * In the situation where the peer has been sent a configure-ack
860 * already, LCP is up once it has sent its configure-ack
861 * so the immediately following packet can be sent with the
862 * configured LCP options. This allows us to process the following
863 * packet correctly without pppd needing to respond quickly.
864 *
865 * We only respond to the received configure-ack if we have just
866 * sent a configure-request, and the configure-ack contains the
867 * same data (this is checked using a 16-bit crc of the data).
868 */
869 #define CONFREQ 1 /* LCP code field values */
870 #define CONFACK 2
871 #define LCP_MRU 1 /* LCP option numbers */
872 #define LCP_ASYNCMAP 2
873
874 static void async_lcp_peek(struct asyncppp *ap, unsigned char *data,
875 int len, int inbound)
876 {
877 int dlen, fcs, i, code;
878 u32 val;
879
880 data += 2; /* skip protocol bytes */
881 len -= 2;
882 if (len < 4) /* 4 = code, ID, length */
883 return;
884 code = data[0];
885 if (code != CONFACK && code != CONFREQ)
886 return;
887 dlen = (data[2] << 8) + data[3];
888 if (len < dlen)
889 return; /* packet got truncated or length is bogus */
890
891 if (code == (inbound? CONFACK: CONFREQ)) {
892 /*
893 * sent confreq or received confack:
894 * calculate the crc of the data from the ID field on.
895 */
896 fcs = PPP_INITFCS;
897 for (i = 1; i < dlen; ++i)
898 fcs = PPP_FCS(fcs, data[i]);
899
900 if (!inbound) {
901 /* outbound confreq - remember the crc for later */
902 ap->lcp_fcs = fcs;
903 return;
904 }
905
906 /* received confack, check the crc */
907 fcs ^= ap->lcp_fcs;
908 ap->lcp_fcs = -1;
909 if (fcs != 0)
910 return;
911 } else if (inbound)
912 return; /* not interested in received confreq */
913
914 /* process the options in the confack */
915 data += 4;
916 dlen -= 4;
917 /* data[0] is code, data[1] is length */
918 while (dlen >= 2 && dlen >= data[1]) {
919 switch (data[0]) {
920 case LCP_MRU:
921 val = (data[2] << 8) + data[3];
922 if (inbound)
923 ap->mru = val;
924 else
925 ap->chan.mtu = val;
926 break;
927 case LCP_ASYNCMAP:
928 val = (data[2] << 24) + (data[3] << 16)
929 + (data[4] << 8) + data[5];
930 if (inbound)
931 ap->raccm = val;
932 else
933 ap->xaccm[0] = val;
934 break;
935 }
936 dlen -= data[1];
937 data += data[1];
938 }
939 }
940
941 static void __exit ppp_async_cleanup(void)
942 {
943 if (tty_register_ldisc(N_PPP, NULL) != 0)
944 printk(KERN_ERR "failed to unregister PPP line discipline\n");
945 }
946
947 module_init(ppp_async_init);
948 module_exit(ppp_async_cleanup);
949