ppp_async.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:22k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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