Import 2.4.0-test4
[davej-history.git] / drivers / net / ppp_async.c
blobd6b2c47f3cb209b4097d4cef826e6c6c9b0958dc
1 /*
2 * PPP async serial channel driver for Linux.
4 * Copyright 1999 Paul Mackerras.
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.
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.
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.
20 * ==FILEVERSION 20000227==
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>
36 #ifndef spin_trylock_bh
37 #define spin_trylock_bh(lock) ({ int __r; local_bh_disable(); \
38 __r = spin_trylock(lock); \
39 if (!__r) local_bh_enable(); \
40 __r; })
41 #endif
43 #define PPP_VERSION "2.4.1"
45 #define OBUFSIZE 256
47 /* Structure for storing local state. */
48 struct asyncppp {
49 struct tty_struct *tty;
50 unsigned int flags;
51 unsigned int state;
52 unsigned int rbits;
53 int mru;
54 spinlock_t xmit_lock;
55 spinlock_t recv_lock;
56 unsigned long xmit_flags;
57 u32 xaccm[8];
58 u32 raccm;
59 unsigned int bytes_sent;
60 unsigned int bytes_rcvd;
62 struct sk_buff *tpkt;
63 int tpkt_pos;
64 u16 tfcs;
65 unsigned char *optr;
66 unsigned char *olim;
67 unsigned long last_xmit;
69 struct sk_buff *rpkt;
70 int lcp_fcs;
72 struct ppp_channel chan; /* interface to generic ppp layer */
73 unsigned char obuf[OBUFSIZE];
76 /* Bit numbers in xmit_flags */
77 #define XMIT_WAKEUP 0
78 #define XMIT_FULL 1
80 /* State bits */
81 #define SC_TOSS 0x20000000
82 #define SC_ESCAPE 0x40000000
84 /* Bits in rbits */
85 #define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)
87 static int flag_time = HZ;
88 MODULE_PARM(flag_time, "i");
91 * Prototypes.
93 static int ppp_async_encode(struct asyncppp *ap);
94 static int ppp_async_send(struct ppp_channel *chan, struct sk_buff *skb);
95 static int ppp_async_push(struct asyncppp *ap);
96 static void ppp_async_flush_output(struct asyncppp *ap);
97 static void ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
98 char *flags, int count);
99 static int ppp_async_ioctl(struct ppp_channel *chan, unsigned int cmd,
100 unsigned long arg);
101 static void async_lcp_peek(struct asyncppp *ap, unsigned char *data,
102 int len, int inbound);
104 struct ppp_channel_ops async_ops = {
105 ppp_async_send,
106 ppp_async_ioctl
110 * Routines implementing the PPP line discipline.
114 * Called when a tty is put into PPP line discipline.
116 static int
117 ppp_asynctty_open(struct tty_struct *tty)
119 struct asyncppp *ap;
120 int err;
122 MOD_INC_USE_COUNT;
123 err = -ENOMEM;
124 ap = kmalloc(sizeof(*ap), GFP_KERNEL);
125 if (ap == 0)
126 goto out;
128 /* initialize the asyncppp structure */
129 memset(ap, 0, sizeof(*ap));
130 ap->tty = tty;
131 ap->mru = PPP_MRU;
132 spin_lock_init(&ap->xmit_lock);
133 spin_lock_init(&ap->recv_lock);
134 ap->xaccm[0] = ~0U;
135 ap->xaccm[3] = 0x60000000U;
136 ap->raccm = ~0U;
137 ap->optr = ap->obuf;
138 ap->olim = ap->obuf;
139 ap->lcp_fcs = -1;
141 ap->chan.private = ap;
142 ap->chan.ops = &async_ops;
143 ap->chan.mtu = PPP_MRU;
144 err = ppp_register_channel(&ap->chan);
145 if (err)
146 goto out_free;
148 tty->disc_data = ap;
150 return 0;
152 out_free:
153 kfree(ap);
154 out:
155 MOD_DEC_USE_COUNT;
156 return err;
160 * Called when the tty is put into another line discipline
161 * or it hangs up.
162 * We assume that while we are in this routine, the tty layer
163 * won't call any of the other line discipline entries for the
164 * same tty.
166 static void
167 ppp_asynctty_close(struct tty_struct *tty)
169 struct asyncppp *ap = tty->disc_data;
171 if (ap == 0)
172 return;
173 tty->disc_data = 0;
174 ppp_unregister_channel(&ap->chan);
175 if (ap->rpkt != 0)
176 kfree_skb(ap->rpkt);
177 if (ap->tpkt != 0)
178 kfree_skb(ap->tpkt);
179 kfree(ap);
180 MOD_DEC_USE_COUNT;
184 * Read does nothing.
186 static ssize_t
187 ppp_asynctty_read(struct tty_struct *tty, struct file *file,
188 unsigned char *buf, size_t count)
190 /* For now, do the same as the old 2.3.x code useta */
191 struct asyncppp *ap = tty->disc_data;
193 if (ap == 0)
194 return -ENXIO;
195 return ppp_channel_read(&ap->chan, file, buf, count);
199 * Write on the tty does nothing, the packets all come in
200 * from the ppp generic stuff.
202 static ssize_t
203 ppp_asynctty_write(struct tty_struct *tty, struct file *file,
204 const unsigned char *buf, size_t count)
206 /* For now, do the same as the old 2.3.x code useta */
207 struct asyncppp *ap = tty->disc_data;
209 if (ap == 0)
210 return -ENXIO;
211 return ppp_channel_write(&ap->chan, buf, count);
214 static int
215 ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
216 unsigned int cmd, unsigned long arg)
218 struct asyncppp *ap = tty->disc_data;
219 int err, val;
221 err = -EFAULT;
222 switch (cmd) {
223 case PPPIOCGCHAN:
224 err = -ENXIO;
225 if (ap == 0)
226 break;
227 err = -EFAULT;
228 if (put_user(ppp_channel_index(&ap->chan), (int *) arg))
229 break;
230 err = 0;
231 break;
233 case PPPIOCGUNIT:
234 err = -ENXIO;
235 if (ap == 0)
236 break;
237 err = -EFAULT;
238 if (put_user(ppp_unit_number(&ap->chan), (int *) arg))
239 break;
240 err = 0;
241 break;
243 case TCGETS:
244 case TCGETA:
245 err = n_tty_ioctl(tty, file, cmd, arg);
246 break;
248 case TCFLSH:
249 /* flush our buffers and the serial port's buffer */
250 if (arg == TCIOFLUSH || arg == TCOFLUSH)
251 ppp_async_flush_output(ap);
252 err = n_tty_ioctl(tty, file, cmd, arg);
253 break;
255 case FIONREAD:
256 val = 0;
257 if (put_user(val, (int *) arg))
258 break;
259 err = 0;
260 break;
263 * For now, do the same as the old 2.3 driver useta
265 case PPPIOCGFLAGS:
266 case PPPIOCSFLAGS:
267 case PPPIOCGASYNCMAP:
268 case PPPIOCSASYNCMAP:
269 case PPPIOCGRASYNCMAP:
270 case PPPIOCSRASYNCMAP:
271 case PPPIOCGXASYNCMAP:
272 case PPPIOCSXASYNCMAP:
273 case PPPIOCGMRU:
274 case PPPIOCSMRU:
275 err = -EPERM;
276 if (!capable(CAP_NET_ADMIN))
277 break;
278 err = ppp_async_ioctl(&ap->chan, cmd, arg);
279 break;
281 case PPPIOCATTACH:
282 case PPPIOCDETACH:
283 err = ppp_channel_ioctl(&ap->chan, cmd, arg);
284 break;
286 default:
287 err = -ENOIOCTLCMD;
290 return err;
293 /* No kernel lock - fine */
294 static unsigned int
295 ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
297 unsigned int mask;
298 struct asyncppp *ap = tty->disc_data;
300 mask = POLLOUT | POLLWRNORM;
302 * For now, do the same as the old 2.3 driver useta
304 if (ap != 0)
305 mask |= ppp_channel_poll(&ap->chan, file, wait);
306 if (test_bit(TTY_OTHER_CLOSED, &tty->flags) || tty_hung_up_p(file))
307 mask |= POLLHUP;
308 return mask;
311 static int
312 ppp_asynctty_room(struct tty_struct *tty)
314 return 65535;
317 static void
318 ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
319 char *flags, int count)
321 struct asyncppp *ap = tty->disc_data;
323 if (ap == 0)
324 return;
325 spin_lock_bh(&ap->recv_lock);
326 ppp_async_input(ap, buf, flags, count);
327 spin_unlock_bh(&ap->recv_lock);
328 if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
329 && tty->driver.unthrottle)
330 tty->driver.unthrottle(tty);
333 static void
334 ppp_asynctty_wakeup(struct tty_struct *tty)
336 struct asyncppp *ap = tty->disc_data;
338 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
339 if (ap == 0)
340 return;
341 if (ppp_async_push(ap))
342 ppp_output_wakeup(&ap->chan);
346 static struct tty_ldisc ppp_ldisc = {
347 magic: TTY_LDISC_MAGIC,
348 name: "ppp",
349 open: ppp_asynctty_open,
350 close: ppp_asynctty_close,
351 read: ppp_asynctty_read,
352 write: ppp_asynctty_write,
353 ioctl: ppp_asynctty_ioctl,
354 poll: ppp_asynctty_poll,
355 receive_room: ppp_asynctty_room,
356 receive_buf: ppp_asynctty_receive,
357 write_wakeup: ppp_asynctty_wakeup,
361 ppp_async_init(void)
363 int err;
365 err = tty_register_ldisc(N_PPP, &ppp_ldisc);
366 if (err != 0)
367 printk(KERN_ERR "PPP_async: error %d registering line disc.\n",
368 err);
369 return err;
373 * The following routines provide the PPP channel interface.
375 static int
376 ppp_async_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg)
378 struct asyncppp *ap = chan->private;
379 int err, val;
380 u32 accm[8];
382 err = -EFAULT;
383 switch (cmd) {
384 case PPPIOCGFLAGS:
385 val = ap->flags | ap->rbits;
386 if (put_user(val, (int *) arg))
387 break;
388 err = 0;
389 break;
390 case PPPIOCSFLAGS:
391 if (get_user(val, (int *) arg))
392 break;
393 ap->flags = val & ~SC_RCV_BITS;
394 spin_lock_bh(&ap->recv_lock);
395 ap->rbits = val & SC_RCV_BITS;
396 spin_unlock_bh(&ap->recv_lock);
397 err = 0;
398 break;
400 case PPPIOCGASYNCMAP:
401 if (put_user(ap->xaccm[0], (u32 *) arg))
402 break;
403 err = 0;
404 break;
405 case PPPIOCSASYNCMAP:
406 if (get_user(ap->xaccm[0], (u32 *) arg))
407 break;
408 err = 0;
409 break;
411 case PPPIOCGRASYNCMAP:
412 if (put_user(ap->raccm, (u32 *) arg))
413 break;
414 err = 0;
415 break;
416 case PPPIOCSRASYNCMAP:
417 if (get_user(ap->raccm, (u32 *) arg))
418 break;
419 err = 0;
420 break;
422 case PPPIOCGXASYNCMAP:
423 if (copy_to_user((void *) arg, ap->xaccm, sizeof(ap->xaccm)))
424 break;
425 err = 0;
426 break;
427 case PPPIOCSXASYNCMAP:
428 if (copy_from_user(accm, (void *) arg, sizeof(accm)))
429 break;
430 accm[2] &= ~0x40000000U; /* can't escape 0x5e */
431 accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */
432 memcpy(ap->xaccm, accm, sizeof(ap->xaccm));
433 err = 0;
434 break;
436 case PPPIOCGMRU:
437 if (put_user(ap->mru, (int *) arg))
438 break;
439 err = 0;
440 break;
441 case PPPIOCSMRU:
442 if (get_user(val, (int *) arg))
443 break;
444 if (val < PPP_MRU)
445 val = PPP_MRU;
446 ap->mru = val;
447 err = 0;
448 break;
450 default:
451 err = -ENOTTY;
454 return err;
458 * Procedures for encapsulation and framing.
461 u16 ppp_crc16_table[256] = {
462 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
463 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
464 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
465 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
466 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
467 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
468 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
469 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
470 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
471 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
472 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
473 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
474 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
475 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
476 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
477 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
478 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
479 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
480 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
481 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
482 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
483 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
484 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
485 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
486 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
487 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
488 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
489 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
490 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
491 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
492 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
493 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
495 EXPORT_SYMBOL(ppp_crc16_table);
496 #define fcstab ppp_crc16_table /* for PPP_FCS macro */
499 * Procedure to encode the data for async serial transmission.
500 * Does octet stuffing (escaping), puts the address/control bytes
501 * on if A/C compression is disabled, and does protocol compression.
502 * Assumes ap->tpkt != 0 on entry.
503 * Returns 1 if we finished the current frame, 0 otherwise.
506 #define PUT_BYTE(ap, buf, c, islcp) do { \
507 if ((islcp && c < 0x20) || (ap->xaccm[c >> 5] & (1 << (c & 0x1f)))) {\
508 *buf++ = PPP_ESCAPE; \
509 *buf++ = c ^ 0x20; \
510 } else \
511 *buf++ = c; \
512 } while (0)
514 static int
515 ppp_async_encode(struct asyncppp *ap)
517 int fcs, i, count, c, proto;
518 unsigned char *buf, *buflim;
519 unsigned char *data;
520 int islcp;
522 buf = ap->obuf;
523 ap->olim = buf;
524 ap->optr = buf;
525 i = ap->tpkt_pos;
526 data = ap->tpkt->data;
527 count = ap->tpkt->len;
528 fcs = ap->tfcs;
529 proto = (data[0] << 8) + data[1];
532 * LCP packets with code values between 1 (configure-reqest)
533 * and 7 (code-reject) must be sent as though no options
534 * had been negotiated.
536 islcp = proto == PPP_LCP && 1 <= data[2] && data[2] <= 7;
538 if (i == 0) {
539 if (islcp)
540 async_lcp_peek(ap, data, count, 0);
543 * Start of a new packet - insert the leading FLAG
544 * character if necessary.
546 if (islcp || flag_time == 0
547 || jiffies - ap->last_xmit >= flag_time)
548 *buf++ = PPP_FLAG;
549 ap->last_xmit = jiffies;
550 fcs = PPP_INITFCS;
553 * Put in the address/control bytes if necessary
555 if ((ap->flags & SC_COMP_AC) == 0 || islcp) {
556 PUT_BYTE(ap, buf, 0xff, islcp);
557 fcs = PPP_FCS(fcs, 0xff);
558 PUT_BYTE(ap, buf, 0x03, islcp);
559 fcs = PPP_FCS(fcs, 0x03);
564 * Once we put in the last byte, we need to put in the FCS
565 * and closing flag, so make sure there is at least 7 bytes
566 * of free space in the output buffer.
568 buflim = ap->obuf + OBUFSIZE - 6;
569 while (i < count && buf < buflim) {
570 c = data[i++];
571 if (i == 1 && c == 0 && (ap->flags & SC_COMP_PROT))
572 continue; /* compress protocol field */
573 fcs = PPP_FCS(fcs, c);
574 PUT_BYTE(ap, buf, c, islcp);
577 if (i < count) {
579 * Remember where we are up to in this packet.
581 ap->olim = buf;
582 ap->tpkt_pos = i;
583 ap->tfcs = fcs;
584 return 0;
588 * We have finished the packet. Add the FCS and flag.
590 fcs = ~fcs;
591 c = fcs & 0xff;
592 PUT_BYTE(ap, buf, c, islcp);
593 c = (fcs >> 8) & 0xff;
594 PUT_BYTE(ap, buf, c, islcp);
595 *buf++ = PPP_FLAG;
596 ap->olim = buf;
598 kfree_skb(ap->tpkt);
599 ap->tpkt = 0;
600 return 1;
604 * Transmit-side routines.
608 * Send a packet to the peer over an async tty line.
609 * Returns 1 iff the packet was accepted.
610 * If the packet was not accepted, we will call ppp_output_wakeup
611 * at some later time.
613 static int
614 ppp_async_send(struct ppp_channel *chan, struct sk_buff *skb)
616 struct asyncppp *ap = chan->private;
618 ppp_async_push(ap);
620 if (test_and_set_bit(XMIT_FULL, &ap->xmit_flags))
621 return 0; /* already full */
622 ap->tpkt = skb;
623 ap->tpkt_pos = 0;
625 ppp_async_push(ap);
626 return 1;
630 * Push as much data as possible out to the tty.
632 static int
633 ppp_async_push(struct asyncppp *ap)
635 int avail, sent, done = 0;
636 struct tty_struct *tty = ap->tty;
637 int tty_stuffed = 0;
639 set_bit(XMIT_WAKEUP, &ap->xmit_flags);
640 if (!spin_trylock_bh(&ap->xmit_lock))
641 return 0;
642 for (;;) {
643 if (test_and_clear_bit(XMIT_WAKEUP, &ap->xmit_flags))
644 tty_stuffed = 0;
645 if (!tty_stuffed && ap->optr < ap->olim) {
646 avail = ap->olim - ap->optr;
647 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
648 sent = tty->driver.write(tty, 0, ap->optr, avail);
649 if (sent < 0)
650 goto flush; /* error, e.g. loss of CD */
651 ap->optr += sent;
652 if (sent < avail)
653 tty_stuffed = 1;
654 continue;
656 if (ap->optr == ap->olim && ap->tpkt != 0) {
657 if (ppp_async_encode(ap)) {
658 /* finished processing ap->tpkt */
659 clear_bit(XMIT_FULL, &ap->xmit_flags);
660 done = 1;
662 continue;
664 /* haven't made any progress */
665 spin_unlock_bh(&ap->xmit_lock);
666 if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags)
667 || (!tty_stuffed && ap->tpkt != 0)))
668 break;
669 if (!spin_trylock_bh(&ap->xmit_lock))
670 break;
672 return done;
674 flush:
675 if (ap->tpkt != 0) {
676 kfree_skb(ap->tpkt);
677 ap->tpkt = 0;
678 clear_bit(XMIT_FULL, &ap->xmit_flags);
679 done = 1;
681 ap->optr = ap->olim;
682 spin_unlock_bh(&ap->xmit_lock);
683 return done;
687 * Flush output from our internal buffers.
688 * Called for the TCFLSH ioctl.
690 static void
691 ppp_async_flush_output(struct asyncppp *ap)
693 int done = 0;
695 spin_lock_bh(&ap->xmit_lock);
696 ap->optr = ap->olim;
697 if (ap->tpkt != NULL) {
698 kfree_skb(ap->tpkt);
699 ap->tpkt = 0;
700 clear_bit(XMIT_FULL, &ap->xmit_flags);
701 done = 1;
703 spin_unlock_bh(&ap->xmit_lock);
704 if (done)
705 ppp_output_wakeup(&ap->chan);
709 * Receive-side routines.
712 /* see how many ordinary chars there are at the start of buf */
713 static inline int
714 scan_ordinary(struct asyncppp *ap, const unsigned char *buf, int count)
716 int i, c;
718 for (i = 0; i < count; ++i) {
719 c = buf[i];
720 if (c == PPP_ESCAPE || c == PPP_FLAG
721 || (c < 0x20 && (ap->raccm & (1 << c)) != 0))
722 break;
724 return i;
727 /* called when a flag is seen - do end-of-packet processing */
728 static inline void
729 process_input_packet(struct asyncppp *ap)
731 struct sk_buff *skb;
732 unsigned char *p;
733 unsigned int len, fcs, proto;
734 int code = 0;
736 skb = ap->rpkt;
737 ap->rpkt = 0;
738 if ((ap->state & (SC_TOSS | SC_ESCAPE)) || skb == 0) {
739 ap->state &= ~(SC_TOSS | SC_ESCAPE);
740 if (skb != 0)
741 kfree_skb(skb);
742 return;
745 /* check the FCS */
746 p = skb->data;
747 len = skb->len;
748 if (len < 3)
749 goto err; /* too short */
750 fcs = PPP_INITFCS;
751 for (; len > 0; --len)
752 fcs = PPP_FCS(fcs, *p++);
753 if (fcs != PPP_GOODFCS)
754 goto err; /* bad FCS */
755 skb_trim(skb, skb->len - 2);
757 /* check for address/control and protocol compression */
758 p = skb->data;
759 if (p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) {
760 /* chop off address/control */
761 if (skb->len < 3)
762 goto err;
763 p = skb_pull(skb, 2);
765 proto = p[0];
766 if (proto & 1) {
767 /* protocol is compressed */
768 skb_push(skb, 1)[0] = 0;
769 } else {
770 if (skb->len < 2)
771 goto err;
772 proto = (proto << 8) + p[1];
773 if (proto == PPP_LCP)
774 async_lcp_peek(ap, p, skb->len, 1);
777 /* all OK, give it to the generic layer */
778 ppp_input(&ap->chan, skb);
779 return;
781 err:
782 kfree_skb(skb);
783 ppp_input_error(&ap->chan, code);
786 static inline void
787 input_error(struct asyncppp *ap, int code)
789 ap->state |= SC_TOSS;
790 ppp_input_error(&ap->chan, code);
793 /* called when the tty driver has data for us. */
794 static void
795 ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
796 char *flags, int count)
798 struct sk_buff *skb;
799 int c, i, j, n, s, f;
800 unsigned char *sp;
802 /* update bits used for 8-bit cleanness detection */
803 if (~ap->rbits & SC_RCV_BITS) {
804 s = 0;
805 for (i = 0; i < count; ++i) {
806 c = buf[i];
807 if (flags != 0 && flags[i] != 0)
808 continue;
809 s |= (c & 0x80)? SC_RCV_B7_1: SC_RCV_B7_0;
810 c = ((c >> 4) ^ c) & 0xf;
811 s |= (0x6996 & (1 << c))? SC_RCV_ODDP: SC_RCV_EVNP;
813 ap->rbits |= s;
816 while (count > 0) {
817 /* scan through and see how many chars we can do in bulk */
818 if ((ap->state & SC_ESCAPE) && buf[0] == PPP_ESCAPE)
819 n = 1;
820 else
821 n = scan_ordinary(ap, buf, count);
823 f = 0;
824 if (flags != 0 && (ap->state & SC_TOSS) == 0) {
825 /* check the flags to see if any char had an error */
826 for (j = 0; j < n; ++j)
827 if ((f = flags[j]) != 0)
828 break;
830 if (f != 0) {
831 /* start tossing */
832 input_error(ap, f);
834 } else if (n > 0 && (ap->state & SC_TOSS) == 0) {
835 /* stuff the chars in the skb */
836 skb = ap->rpkt;
837 if (skb == 0) {
838 skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
839 if (skb == 0)
840 goto nomem;
841 /* Try to get the payload 4-byte aligned */
842 if (buf[0] != PPP_ALLSTATIONS)
843 skb_reserve(skb, 2 + (buf[0] & 1));
844 ap->rpkt = skb;
846 if (n > skb_tailroom(skb)) {
847 /* packet overflowed MRU */
848 input_error(ap, 1);
849 } else {
850 sp = skb_put(skb, n);
851 memcpy(sp, buf, n);
852 if (ap->state & SC_ESCAPE) {
853 sp[0] ^= 0x20;
854 ap->state &= ~SC_ESCAPE;
859 if (n >= count)
860 break;
862 c = buf[n];
863 if (c == PPP_FLAG) {
864 process_input_packet(ap);
865 } else if (c == PPP_ESCAPE) {
866 ap->state |= SC_ESCAPE;
868 /* otherwise it's a char in the recv ACCM */
869 ++n;
871 buf += n;
872 if (flags != 0)
873 flags += n;
874 count -= n;
876 return;
878 nomem:
879 printk(KERN_ERR "PPPasync: no memory (input pkt)\n");
880 input_error(ap, 0);
884 * We look at LCP frames going past so that we can notice
885 * and react to the LCP configure-ack from the peer.
886 * In the situation where the peer has been sent a configure-ack
887 * already, LCP is up once it has sent its configure-ack
888 * so the immediately following packet can be sent with the
889 * configured LCP options. This allows us to process the following
890 * packet correctly without pppd needing to respond quickly.
892 * We only respond to the received configure-ack if we have just
893 * sent a configure-request, and the configure-ack contains the
894 * same data (this is checked using a 16-bit crc of the data).
896 #define CONFREQ 1 /* LCP code field values */
897 #define CONFACK 2
898 #define LCP_MRU 1 /* LCP option numbers */
899 #define LCP_ASYNCMAP 2
901 static void async_lcp_peek(struct asyncppp *ap, unsigned char *data,
902 int len, int inbound)
904 int dlen, fcs, i, code;
905 u32 val;
907 data += 2; /* skip protocol bytes */
908 len -= 2;
909 if (len < 4) /* 4 = code, ID, length */
910 return;
911 code = data[0];
912 if (code != CONFACK && code != CONFREQ)
913 return;
914 dlen = (data[2] << 8) + data[3];
915 if (len < dlen)
916 return; /* packet got truncated or length is bogus */
918 if (code == (inbound? CONFACK: CONFREQ)) {
920 * sent confreq or received confack:
921 * calculate the crc of the data from the ID field on.
923 fcs = PPP_INITFCS;
924 for (i = 1; i < dlen; ++i)
925 fcs = PPP_FCS(fcs, data[i]);
927 if (!inbound) {
928 /* outbound confreq - remember the crc for later */
929 ap->lcp_fcs = fcs;
930 return;
933 /* received confack, check the crc */
934 fcs ^= ap->lcp_fcs;
935 ap->lcp_fcs = -1;
936 if (fcs != 0)
937 return;
938 } else if (inbound)
939 return; /* not interested in received confreq */
941 /* process the options in the confack */
942 data += 4;
943 dlen -= 4;
944 /* data[0] is code, data[1] is length */
945 while (dlen >= 2 && dlen >= data[1]) {
946 switch (data[0]) {
947 case LCP_MRU:
948 val = (data[2] << 8) + data[3];
949 if (inbound)
950 ap->mru = val;
951 else
952 ap->chan.mtu = val;
953 break;
954 case LCP_ASYNCMAP:
955 val = (data[2] << 24) + (data[3] << 16)
956 + (data[4] << 8) + data[5];
957 if (inbound)
958 ap->raccm = val;
959 else
960 ap->xaccm[0] = val;
961 break;
963 dlen -= data[1];
964 data += data[1];
968 void __exit ppp_async_cleanup(void)
970 if (tty_register_ldisc(N_PPP, NULL) != 0)
971 printk(KERN_ERR "failed to unregister PPP line discipline\n");
974 module_init(ppp_async_init);
975 module_exit(ppp_async_cleanup);