This source file includes following definitions.
- ppp_init
- ppp_init_ctrl_blk
- ppp_changedmtu
- ppp_release
- ppp_close
- ppp_open
- ppp_dev_open
- ppp_dev_close
- ppp_dev_ioctl
- ppp_output_done
- ppp_kick_tty
- ppp_kick_tty
- ppp_write_wakeup
- ppp_enqueue
- ppp_dump_inqueue
- ppp_tty_input_ready
- ppp_unesc
- ppp_receive_room
- ppp_receive_buf
- ppp_doframe
- ppp_do_ip
- ppp_us_queue
- ppp_read
- ppp_stuff_char
- ppp_write
- ppp_ioctl
- ppp_select
- ppp_xmit
- ppp_type_trans
- ppp_header
- ppp_rebuild_header
- ppp_add_arp
- ppp_header
- ppp_rebuild_header
- ppp_get_stats
- ppp_find
- ppp_alloc
- ppp_lock
- ppp_unlock
- ppp_add_fcs
- ppp_check_fcs
- ppp_print_hex
- ppp_print_char
- ppp_print_buffer
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 #define NEW_TTY_DRIVERS
33 #define OPTIMIZE_FLAG_TIME ((HZ * 3)/2)
34
35 #ifdef MODULE
36 #include <linux/module.h>
37 #include <linux/version.h>
38 #endif
39
40 #include <linux/kernel.h>
41 #include <linux/sched.h>
42 #include <linux/types.h>
43 #include <linux/fcntl.h>
44 #include <linux/interrupt.h>
45 #include <linux/ptrace.h>
46 #include <linux/ioport.h>
47 #include <linux/in.h>
48 #include <linux/malloc.h>
49 #include <linux/tty.h>
50 #include <linux/errno.h>
51 #include <linux/sched.h>
52 #include <linux/string.h>
53 #include <linux/signal.h>
54 #include <asm/system.h>
55 #include <asm/bitops.h>
56 #include <asm/segment.h>
57
58 #ifdef NET02D
59 #include <dev.h>
60 #include <skbuff.h>
61 #include <inet.h>
62 #define skb_queue_head_init(buf) *(buf) = NULL
63 #else
64 #include <linux/netdevice.h>
65 #include <linux/skbuff.h>
66 #include <linux/inet.h>
67 #endif
68
69 #include <linux/ppp.h>
70
71 #include <linux/ip.h>
72 #include <linux/tcp.h>
73
74 #include "slhc.h"
75
76 #include <linux/if_arp.h>
77 #ifndef ARPHRD_PPP
78 #define ARPHRD_PPP 0
79 #endif
80
81 #define PRINTK(p) printk p ;
82 #define ASSERT(p) if (!p) PRINTK ((KERN_CRIT "assertion failed: " # p))
83 #define PRINTKN(n,p) {if (ppp_debug >= n) PRINTK (p)}
84 #define CHECK_PPP(a) if (!ppp->inuse) { PRINTK ((ppp_warning, __LINE__)) return a;}
85 #define CHECK_PPP_VOID() if (!ppp->inuse) { PRINTK ((ppp_warning, __LINE__)) return;}
86
87 #define in_xmap(ppp,c) (ppp->xmit_async_map[(c) >> 5] & (1 << ((c) & 0x1f)))
88 #define in_rmap(ppp,c) ((((unsigned int) (unsigned char) (c)) < 0x20) && \
89 ppp->recv_async_map & (1 << (c)))
90
91 #define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
92
93 int ppp_debug = 2;
94 int ppp_debug_netpackets = 0;
95
96
97 static char ppp_warning[] = KERN_WARNING "PPP: ALERT! not INUSE! %d\n";
98
99 int ppp_init(struct device *);
100 static void ppp_init_ctrl_blk(struct ppp *);
101 static int ppp_dev_open(struct device *);
102 static int ppp_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd);
103 static int ppp_dev_close(struct device *);
104 static void ppp_kick_tty(struct ppp *);
105
106 #ifdef NEW_TTY_DRIVERS
107 #define ppp_find(tty) ((struct ppp *) tty->disc_data)
108 #else
109 static void ppp_output_done(void *);
110 static void ppp_unesc(struct ppp *ppp, unsigned char *c, int n);
111 static struct ppp *ppp_find(struct tty_struct *);
112 #endif
113
114 static void ppp_doframe(struct ppp *);
115 static int ppp_do_ip(struct ppp *, unsigned short, unsigned char *, int);
116 static int ppp_us_queue(struct ppp *, unsigned short, unsigned char *, int);
117 static int ppp_xmit(struct sk_buff *, struct device *);
118 static unsigned short ppp_type_trans(struct sk_buff *, struct device *);
119
120 #ifdef NET02D
121 static int ppp_header(unsigned char *buff, struct device *dev,
122 unsigned short type, unsigned long daddr,
123 unsigned long saddr, unsigned len);
124 static int ppp_rebuild_header(void *buff, struct device *dev);
125 static void ppp_add_arp(unsigned long addr, struct sk_buff *skb,
126 struct device *dev);
127 #else
128 static int ppp_header(unsigned char *, struct device *, unsigned short,
129 void *, void *, unsigned, struct sk_buff *);
130 static int ppp_rebuild_header(void *, struct device *, unsigned long,
131 struct sk_buff *);
132 #endif
133
134 static struct enet_statistics *ppp_get_stats (struct device *);
135 static struct ppp *ppp_alloc(void);
136 static int ppp_lock(struct ppp *);
137 static void ppp_unlock(struct ppp *);
138 static void ppp_add_fcs(struct ppp *);
139 static int ppp_check_fcs(struct ppp *);
140 static void ppp_print_buffer(const char *,char *,int,int);
141
142 static int ppp_read(struct tty_struct *, struct file *, unsigned char *,
143 unsigned int);
144 static int ppp_write(struct tty_struct *, struct file *, unsigned char *,
145 unsigned int);
146 static int ppp_ioctl(struct tty_struct *, struct file *, unsigned int,
147 unsigned long);
148 static int ppp_select(struct tty_struct *tty, struct inode * inode,
149 struct file * filp, int sel_type, select_table * wait);
150 static int ppp_open(struct tty_struct *);
151 static void ppp_close(struct tty_struct *);
152
153 #ifdef NEW_TTY_DRIVERS
154 static int ppp_receive_room(struct tty_struct *tty);
155 static void ppp_receive_buf(struct tty_struct *tty, unsigned char *cp,
156 char *fp, int count);
157 static void ppp_write_wakeup(struct tty_struct *tty);
158 #else
159 static void ppp_tty_input_ready(struct tty_struct *);
160 #endif
161
162
163
164 static unsigned short fcstab[256] = {
165 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
166 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
167 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
168 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
169 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
170 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
171 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
172 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
173 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
174 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
175 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
176 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
177 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
178 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
179 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
180 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
181 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
182 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
183 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
184 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
185 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
186 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
187 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
188 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
189 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
190 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
191 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
192 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
193 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
194 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
195 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
196 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
197 };
198
199 struct tty_ldisc ppp_ldisc;
200
201 static struct ppp ppp_ctrl[PPP_NRUNIT];
202
203
204
205
206
207 static int first_time = 1;
208
209
210
211 int
212 ppp_init(struct device *dev)
213 {
214 struct ppp *ppp;
215 int i;
216
217 ppp = &ppp_ctrl[dev->base_addr];
218
219 if (first_time) {
220 first_time = 0;
221
222 printk (KERN_INFO "PPP: version %s (%d channels)"
223 #ifdef NET02D
224 " NET02D"
225 #endif
226 #ifdef NEW_TTY_DRIVERS
227 " NEW_TTY_DRIVERS"
228 #endif
229 #ifdef OPTIMIZE_FLAG_TIME
230 " OPTIMIZE_FLAGS"
231 #endif
232 "\n", PPP_VERSION, PPP_NRUNIT);
233
234 printk (KERN_INFO
235 "TCP compression code copyright 1989 Regents of the "
236 "University of California\n");
237
238 (void) memset(&ppp_ldisc, 0, sizeof(ppp_ldisc));
239 ppp_ldisc.open = ppp_open;
240 ppp_ldisc.close = ppp_close;
241 ppp_ldisc.read = ppp_read;
242 ppp_ldisc.write = ppp_write;
243 ppp_ldisc.ioctl = ppp_ioctl;
244 ppp_ldisc.select = ppp_select;
245
246 #ifdef NEW_TTY_DRIVERS
247 ppp_ldisc.magic = TTY_LDISC_MAGIC;
248 ppp_ldisc.receive_room = ppp_receive_room;
249 ppp_ldisc.receive_buf = ppp_receive_buf;
250 ppp_ldisc.write_wakeup = ppp_write_wakeup;
251 #else
252 ppp_ldisc.handler = ppp_tty_input_ready;
253 #endif
254
255 if ((i = tty_register_ldisc(N_PPP, &ppp_ldisc)) == 0)
256 printk(KERN_INFO "PPP line discipline registered.\n");
257 else
258 printk(KERN_ERR "error registering line discipline: %d\n", i);
259 }
260
261
262 ppp_init_ctrl_blk (ppp);
263 ppp->inuse = 0;
264 ppp->line = dev->base_addr;
265 ppp->tty = NULL;
266 ppp->dev = dev;
267
268
269 memset (&ppp->stats, '\0', sizeof (struct ppp_stats));
270
271
272 dev->mtu = PPP_MTU;
273 dev->hard_start_xmit = ppp_xmit;
274 dev->open = ppp_dev_open;
275 dev->stop = ppp_dev_close;
276 dev->get_stats = ppp_get_stats;
277 dev->hard_header = ppp_header;
278 dev->type_trans = ppp_type_trans;
279 dev->rebuild_header = ppp_rebuild_header;
280 dev->hard_header_len = 0;
281 dev->addr_len = 0;
282 dev->type = ARPHRD_PPP;
283
284 #ifdef NET02D
285 dev->add_arp = ppp_add_arp;
286 dev->queue_xmit = dev_queue_xmit;
287 #else
288 dev->do_ioctl = ppp_dev_ioctl;
289 #endif
290
291 for (i = 0; i < DEV_NUMBUFFS; i++)
292 skb_queue_head_init(&dev->buffs[i]);
293
294
295 dev->flags = IFF_POINTOPOINT;
296 dev->family = AF_INET;
297 dev->pa_addr = 0;
298 dev->pa_brdaddr = 0;
299 dev->pa_mask = 0;
300 dev->pa_alen = sizeof(unsigned long);
301
302 return 0;
303 }
304
305 static void
306 ppp_init_ctrl_blk(struct ppp *ppp)
307 {
308 ppp->magic = PPP_MAGIC;
309 ppp->sending = 0;
310 ppp->toss = 0xFE;
311 ppp->escape = 0;
312
313 ppp->flags = 0;
314 ppp->mtu = PPP_MTU;
315 ppp->mru = PPP_MRU;
316 ppp->fcs = 0;
317
318 memset (ppp->xmit_async_map, 0, sizeof (ppp->xmit_async_map));
319 ppp->xmit_async_map[0] = 0xffffffff;
320 ppp->xmit_async_map[3] = 0x60000000;
321 ppp->recv_async_map = 0x00000000;
322
323 ppp->slcomp = NULL;
324 ppp->rbuff = NULL;
325 ppp->xbuff = NULL;
326 ppp->cbuff = NULL;
327
328 ppp->rhead = NULL;
329 ppp->rend = NULL;
330 ppp->rcount = 0;
331 ppp->xhead = NULL;
332 ppp->xtail = NULL;
333
334 ppp->us_rbuff = NULL;
335 ppp->us_rbuff_end = NULL;
336 ppp->us_rbuff_head = NULL;
337 ppp->us_rbuff_tail = NULL;
338 ppp->read_wait = NULL;
339 ppp->write_wait = NULL;
340 ppp->us_rbuff_lock = 0;
341 ppp->inp_sig = 0;
342 ppp->inp_sig_pid = 0;
343
344 #ifdef OPTIMIZE_FLAG_TIME
345 ppp->last_xmit = jiffies - OPTIMIZE_FLAG_TIME;
346 #else
347 ppp->last_xmit = 0;
348 #endif
349
350
351 memset (&ppp->stats, '\0', sizeof (struct ppp_stats));
352
353
354 ppp->ddinfo.ip_sjiffies =
355 ppp->ddinfo.ip_rjiffies =
356 ppp->ddinfo.nip_sjiffies =
357 ppp->ddinfo.nip_rjiffies = jiffies;
358 }
359
360
361
362
363
364
365
366 static void
367 ppp_changedmtu (struct ppp *ppp, int new_mtu, int new_mru)
368 {
369 struct device *dev;
370 unsigned char *new_rbuff, *new_xbuff, *new_cbuff;
371 unsigned char *old_rbuff, *old_xbuff, *old_cbuff;
372 int mtu, mru;
373
374
375
376 dev = ppp->dev;
377 mru = new_mru;
378 mtu = new_mtu;
379
380
381 if (mru < PPP_MRU)
382 mru = PPP_MRU;
383
384 mtu = (mtu * 2) + 20;
385 mru = (mru * 2) + 20;
386
387 PRINTKN (2,(KERN_INFO "ppp: channel %s mtu = %d, mru = %d\n",
388 dev->name, new_mtu, new_mru));
389
390 new_xbuff = (unsigned char *) kmalloc(mtu + 4, GFP_ATOMIC);
391 new_rbuff = (unsigned char *) kmalloc(mru + 4, GFP_ATOMIC);
392 new_cbuff = (unsigned char *) kmalloc(mru + 4, GFP_ATOMIC);
393
394
395
396 if (new_xbuff == NULL || new_rbuff == NULL || new_cbuff == NULL)
397 {
398 PRINTKN (2,(KERN_ERR "ppp: failed to allocate new buffers\n"));
399
400
401
402 if (new_rbuff != NULL)
403 kfree (new_rbuff);
404
405 if (new_xbuff != NULL)
406 kfree (new_xbuff);
407
408 if (new_cbuff != NULL)
409 kfree (new_cbuff);
410 }
411
412
413
414 else
415 {
416 cli();
417 old_xbuff = ppp->xbuff;
418 old_rbuff = ppp->rbuff;
419 old_cbuff = ppp->cbuff;
420
421 ppp->xbuff = new_xbuff;
422 ppp->rbuff = new_rbuff;
423 ppp->cbuff = new_cbuff;
424
425 dev->mem_start = (unsigned long) new_xbuff;
426 dev->mem_end = (unsigned long) (dev->mem_start + mtu);
427
428 dev->rmem_start = (unsigned long) new_rbuff;
429 ppp->rend = (unsigned char *)
430 dev->rmem_end = (unsigned long) (dev->rmem_start + mru);
431
432 ppp->rhead = new_rbuff;
433
434
435
436 ppp->toss = 0xFE;
437 ppp->escape = 0;
438 ppp->sending = 0;
439 ppp->rcount = 0;
440
441 ppp->mru = new_mru;
442
443 ppp->mtu =
444 dev->mtu = new_mtu;
445
446 sti();
447
448
449
450 if (old_rbuff != NULL)
451 kfree (old_rbuff);
452
453 if (old_xbuff != NULL)
454 kfree (old_xbuff);
455
456 if (old_cbuff != NULL)
457 kfree (old_cbuff);
458 }
459 }
460
461
462
463 static void
464 ppp_release(struct ppp *ppp)
465 {
466 #ifdef NEW_TTY_DRIVERS
467 if (ppp->tty != NULL && ppp->tty->disc_data == ppp)
468 ppp->tty->disc_data = NULL;
469 #endif
470
471 if (ppp->dev) {
472 ppp->dev->flags &= ~IFF_UP;
473 ppp->dev->flags |= IFF_POINTOPOINT;
474 }
475
476 kfree (ppp->xbuff);
477 kfree (ppp->cbuff);
478 kfree (ppp->rbuff);
479 kfree (ppp->us_rbuff);
480
481 ppp->xbuff =
482 ppp->cbuff =
483 ppp->rbuff =
484 ppp->us_rbuff = NULL;
485
486 if (ppp->slcomp) {
487 slhc_free(ppp->slcomp);
488 ppp->slcomp = NULL;
489 }
490
491 ppp->inuse = 0;
492 ppp->tty = NULL;
493 }
494
495 static void
496 ppp_close(struct tty_struct *tty)
497 {
498 struct ppp *ppp = ppp_find(tty);
499
500 if (ppp == NULL || ppp->magic != PPP_MAGIC) {
501 PRINTKN (1,(KERN_WARNING "ppp: trying to close unopened tty!\n"));
502 } else {
503 CHECK_PPP_VOID();
504 ppp_release (ppp);
505
506 PRINTKN (2,(KERN_INFO "ppp: channel %s closing.\n", ppp->dev->name));
507 }
508 }
509
510
511 static int
512 ppp_open(struct tty_struct *tty)
513 {
514 struct ppp *ppp = ppp_find(tty);
515
516 if (ppp) {
517 PRINTKN (1,(KERN_ERR "ppp_open: gack! tty already associated to %s!\n",
518 ppp->magic == PPP_MAGIC ? ppp->dev->name : "unknown"));
519 return -EEXIST;
520 }
521
522 ppp = ppp_alloc();
523 if (ppp == NULL) {
524 PRINTKN (1,(KERN_ERR "ppp_open: couldn't allocate ppp channel\n"));
525 return -ENFILE;
526 }
527
528
529 ppp_init_ctrl_blk (ppp);
530
531 ppp->tty = tty;
532
533 #ifdef NEW_TTY_DRIVERS
534 tty->disc_data = ppp;
535 if (tty->driver.flush_buffer)
536 tty->driver.flush_buffer(tty);
537 if (tty->ldisc.flush_buffer)
538 tty->ldisc.flush_buffer(tty);
539 #else
540 tty_read_flush (tty);
541 tty_write_flush (tty);
542 #endif
543
544 if ((ppp->slcomp = slhc_init(16, 16)) == NULL) {
545 PRINTKN (1,(KERN_ERR "ppp: no space for compression buffers!\n"));
546 ppp_release (ppp);
547 return -ENOMEM;
548 }
549
550
551 ppp_changedmtu (ppp, ppp->dev->mtu, ppp->mru);
552 if (ppp->rbuff == NULL) {
553 ppp_release (ppp);
554 return -ENOMEM;
555 }
556
557
558 ppp->us_rbuff = (unsigned char *) kmalloc (RBUFSIZE, GFP_KERNEL);
559 if (ppp->us_rbuff == NULL) {
560 PRINTKN (1,(KERN_ERR "ppp: no space for user receive buffer\n"));
561 ppp_release (ppp);
562 return -ENOMEM;
563 }
564
565 ppp->us_rbuff_head =
566 ppp->us_rbuff_tail = ppp->us_rbuff;
567 ppp->us_rbuff_end = ppp->us_rbuff + RBUFSIZE;
568
569 PRINTKN (2,(KERN_INFO "ppp: channel %s open\n", ppp->dev->name));
570
571 #ifdef MODULE
572 MOD_INC_USE_COUNT;
573 #endif
574
575 return (ppp->line);
576 }
577
578
579
580 static int
581 ppp_dev_open(struct device *dev)
582 {
583 struct ppp *ppp = &ppp_ctrl[dev->base_addr];
584
585
586 dev->flags |= IFF_POINTOPOINT;
587
588 if (ppp->tty == NULL) {
589 PRINTKN (1,(KERN_ERR "ppp: %s not connected to a TTY! can't go open!\n",
590 dev->name));
591 return -ENXIO;
592 }
593
594 PRINTKN (2,(KERN_INFO "ppp: channel %s going up for IP packets!\n",
595 dev->name));
596
597 CHECK_PPP(-ENXIO);
598 return 0;
599 }
600
601 static int
602 ppp_dev_close(struct device *dev)
603 {
604 struct ppp *ppp = &ppp_ctrl[dev->base_addr];
605
606 if (ppp->tty == NULL) {
607 PRINTKN (1,(KERN_ERR "ppp: %s not connected to a TTY! can't go down!\n",
608 dev->name));
609 return -ENXIO;
610 }
611
612 PRINTKN (2,(KERN_INFO "ppp: channel %s going down for IP packets!\n",
613 dev->name));
614 CHECK_PPP(-ENXIO);
615 #ifdef MODULE
616 MOD_DEC_USE_COUNT;
617 #endif
618 return 0;
619 }
620
621 #ifndef NET02D
622 static int ppp_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
623 {
624 struct ppp *ppp = &ppp_ctrl[dev->base_addr];
625 int error;
626
627 struct stats
628 {
629 struct ppp_stats ppp_stats;
630 struct slcompress slhc;
631 } *result;
632
633 error = verify_area (VERIFY_READ,
634 ifr->ifr_ifru.ifru_data,
635 sizeof (struct stats));
636
637 if (error == 0) {
638 result = (struct stats *) ifr->ifr_ifru.ifru_data;
639
640 memcpy_tofs (&result->ppp_stats, &ppp->stats, sizeof (struct ppp_stats));
641 if (ppp->slcomp)
642 memcpy_tofs (&result->slhc, ppp->slcomp, sizeof (struct slcompress));
643 }
644
645 return error;
646 }
647 #endif
648
649
650
651
652
653
654
655 #ifdef NEW_TTY_DRIVERS
656 static inline void
657 #else
658 static void
659 #endif
660 ppp_output_done (void *ppp)
661 {
662
663 ppp_unlock ((struct ppp *) ppp);
664
665
666
667 if (((struct ppp *) ppp)->dev->flags & IFF_UP)
668 #ifndef NET02D
669 mark_bh (NET_BH);
670 #else
671 dev_tint (((struct ppp *) ppp)->dev);
672 #endif
673
674
675 wake_up_interruptible (&((struct ppp *) ppp)->write_wait);
676 }
677
678 #ifndef NEW_TTY_DRIVERS
679 static void
680 ppp_kick_tty (struct ppp *ppp)
681 {
682 register int count = ppp->xhead - ppp->xbuff;
683 register int answer;
684
685 ppp->stats.sbytes += count;
686
687 answer = tty_write_data (ppp->tty,
688 ppp->xbuff,
689 count,
690 ppp_output_done,
691 (void *) ppp);
692
693 if (answer == 0)
694 ppp_output_done (ppp);
695 else
696 if (answer < 0) {
697 ppp->stats.serrors++;
698 ppp_output_done (ppp);
699 }
700 }
701
702 #else
703
704 static void
705 ppp_kick_tty (struct ppp *ppp)
706 {
707 register int count, actual;
708
709 count = ppp->xhead - ppp->xbuff;
710
711 actual = ppp->tty->driver.write(ppp->tty, 0, ppp->xbuff, count);
712 ppp->stats.sbytes += actual;
713 if (actual == count) {
714 ppp_output_done(ppp);
715 } else {
716 ppp->xtail = ppp->xbuff + actual;
717 ppp->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
718 }
719 }
720
721 static void ppp_write_wakeup(struct tty_struct *tty)
722 {
723 register int count, actual;
724 struct ppp *ppp = ppp_find(tty);
725
726 if (!ppp || ppp->magic != PPP_MAGIC) {
727 PRINTKN (1,
728 (KERN_ERR "PPP: write_wakeup called but couldn't "
729 "find PPP struct.\n"));
730 return;
731 }
732
733 if (!ppp->xtail)
734 return;
735
736 cli();
737 if (ppp->flags & SC_XMIT_BUSY) {
738 sti();
739 return;
740 }
741 ppp->flags |= SC_XMIT_BUSY;
742 sti();
743
744 count = ppp->xhead - ppp->xtail;
745
746 actual = tty->driver.write(tty, 0, ppp->xtail, count);
747 ppp->stats.sbytes += actual;
748 if (actual == count) {
749 ppp->xtail = 0;
750 tty->flags &= ~TTY_DO_WRITE_WAKEUP;
751
752 ppp_output_done(ppp);
753 } else {
754 ppp->xtail += actual;
755 }
756 ppp->flags &= ~SC_XMIT_BUSY;
757 }
758 #endif
759
760
761
762
763
764
765
766
767
768
769
770 static inline void
771 ppp_enqueue(struct ppp *ppp, unsigned char c)
772 {
773 unsigned long flags;
774
775 save_flags(flags);
776 cli();
777 if (ppp->rhead < ppp->rend) {
778 *ppp->rhead = c;
779 ppp->rhead++;
780 ppp->rcount++;
781 } else
782 ppp->stats.roverrun++;
783 restore_flags(flags);
784 }
785
786 #ifdef CHECK_CHARACTERS
787 static unsigned paritytab[8] = {
788 0x96696996, 0x69969669, 0x69969669, 0x96696996,
789 0x69969669, 0x96696996, 0x96696996, 0x69969669
790 };
791 #endif
792
793 #ifndef NEW_TTY_DRIVERS
794 static void
795 ppp_dump_inqueue(struct tty_struct *tty)
796 {
797 int head = tty->read_q.head,
798 tail = tty->read_q.tail,
799 i, count;
800 char buffer[8];
801
802 PRINTK ((KERN_DEBUG "INQUEUE: head %d tail %d imode %x:\n", head, tail,
803 (unsigned int) tty->termios->c_iflag))
804
805 i = tail;
806 count = 0;
807
808 while (i != head) {
809 buffer [count] = tty->read_q.buf[i];
810 if (++count == 8) {
811 ppp_print_buffer (NULL, buffer, 8, KERNEL_DS);
812 count = 0;
813 }
814 i = (i + 1) & (TTY_BUF_SIZE - 1);
815 }
816 ppp_print_buffer (NULL, buffer, count, KERNEL_DS);
817 }
818
819
820
821
822 void ppp_tty_input_ready(struct tty_struct *tty)
823 {
824 struct ppp *ppp = ppp_find(tty);
825 int n, error;
826 unsigned char buff[128];
827
828
829 if (!ppp || ppp->magic != PPP_MAGIC) {
830 PRINTKN (1,
831 (KERN_ERR "PPP: handler called but couldn't find PPP struct.\n"));
832 return;
833 }
834
835 CHECK_PPP_VOID();
836
837
838 if (ppp_debug >= 5)
839 ppp_dump_inqueue(ppp->tty);
840
841 do {
842 n = tty_read_raw_data(tty, buff, 128);
843 if ( n == 0 )
844 break;
845
846 if (ppp_debug >= 5)
847 ppp_print_buffer ("receive buffer", buff, n > 0 ? n : -n, KERNEL_DS);
848
849 if ( n < 0 ) {
850
851
852 n = (-n) - 1;
853 error = buff[n];
854 } else error = 0;
855 ppp->stats.rbytes += n;
856 ppp_unesc(ppp,buff,n);
857 if (error)
858 ppp->toss = error;
859 } while (1);
860 }
861
862
863
864
865
866
867 static void
868 ppp_unesc(struct ppp *ppp, unsigned char *c, int n)
869 {
870 int i;
871
872 for (i = 0; i < n; i++, c++) {
873 PRINTKN (6,(KERN_DEBUG "(%x)", (unsigned int) *c));
874
875 #ifdef CHECK_CHARACTERS
876 if (*c & 0x80)
877 sc->sc_flags |= SC_RCV_B7_1;
878 else
879 sc->sc_flags |= SC_RCV_B7_0;
880
881 if (paritytab[*c >> 5] & (1 << (*c & 0x1F)))
882 sc->sc_flags |= SC_RCV_ODDP;
883 else
884 sc->sc_flags |= SC_RCV_EVNP;
885 #endif
886
887 switch (*c) {
888 case PPP_ESC:
889 ppp->escape = PPP_TRANS;
890 break;
891
892 case PPP_FLAG:
893 if (ppp->escape)
894 ppp->toss = 0xFF;
895
896 if ((ppp->toss & 0x80) == 0)
897 ppp_doframe(ppp);
898
899 ppp->rcount = 0;
900 ppp->rhead = ppp->rbuff;
901 ppp->escape = 0;
902 ppp->toss = 0;
903 break;
904
905 default:
906 if (!in_rmap (ppp, *c)) {
907 if (ppp->toss == 0)
908 ppp_enqueue (ppp, *c ^ ppp->escape);
909 ppp->escape = 0;
910 }
911 break;
912 }
913 }
914 }
915
916 #else
917 static int ppp_receive_room(struct tty_struct *tty)
918 {
919 return 65536;
920 }
921
922
923 static void ppp_receive_buf(struct tty_struct *tty, unsigned char *cp,
924 char *fp, int count)
925 {
926 register struct ppp *ppp = ppp_find (tty);
927 unsigned char c;
928
929
930
931 if (!ppp || ppp->magic != PPP_MAGIC) {
932 PRINTKN (1,("PPP: handler called but couldn't find "
933 "PPP struct.\n"));
934 return;
935 }
936
937 CHECK_PPP_VOID();
938
939 if (ppp_debug >= 5) {
940 ppp_print_buffer ("receive buffer", cp, count, KERNEL_DS);
941 }
942
943 ppp->stats.rbytes += count;
944
945 while (count-- > 0) {
946 c = *cp++;
947
948 if (fp) {
949 if (*fp && ppp->toss == 0)
950 ppp->toss = *fp;
951 fp++;
952 }
953
954 #ifdef CHECK_CHARACTERS
955 if (c & 0x80)
956 sc->sc_flags |= SC_RCV_B7_1;
957 else
958 sc->sc_flags |= SC_RCV_B7_0;
959
960 if (paritytab[c >> 5] & (1 << (c & 0x1F)))
961 sc->sc_flags |= SC_RCV_ODDP;
962 else
963 sc->sc_flags |= SC_RCV_EVNP;
964 #endif
965
966 switch (c) {
967 case PPP_ESC:
968 ppp->escape = PPP_TRANS;
969 break;
970
971 case PPP_FLAG:
972 if (ppp->escape)
973 ppp->toss = 0xFF;
974
975 if ((ppp->toss & 0x80) == 0)
976 ppp_doframe(ppp);
977
978 ppp->rcount = 0;
979 ppp->rhead = ppp->rbuff;
980 ppp->escape = 0;
981 ppp->toss = 0;
982 break;
983
984 default:
985 if (!in_rmap (ppp, c)) {
986 if (ppp->toss == 0)
987 ppp_enqueue (ppp, c ^ ppp->escape);
988 ppp->escape = 0;
989 }
990 }
991 }
992 }
993 #endif
994
995
996
997 static void
998 ppp_doframe(struct ppp *ppp)
999 {
1000 u_char *c = ppp->rbuff;
1001 u_short proto;
1002 int count = ppp->rcount;
1003
1004
1005 if (ppp->toss) {
1006 PRINTKN (1, (KERN_WARNING "ppp_toss: tossing frame, reason = %d\n",
1007 ppp->toss));
1008 ppp->stats.rerrors++;
1009 return;
1010 }
1011
1012
1013 if (count == 0)
1014 return;
1015
1016 if (ppp_debug >= 3)
1017 ppp_print_buffer ("receive frame", c, count, KERNEL_DS);
1018
1019 if (count < 4) {
1020 PRINTKN (1,(KERN_WARNING "ppp: got runt ppp frame, %d chars\n", count));
1021 ppp->stats.runts++;
1022 return;
1023 }
1024
1025
1026 if (!ppp_check_fcs(ppp)) {
1027 PRINTKN (1,(KERN_WARNING "ppp: frame with bad fcs\n"));
1028 ppp->stats.rerrors++;
1029 return;
1030 }
1031
1032 count -= 2;
1033
1034
1035
1036 if ((c[0] == PPP_ADDRESS) && (c[1] == PPP_CONTROL)) {
1037 c = c + 2;
1038 count -= 2;
1039 }
1040
1041 proto = (u_short) *c++;
1042 if (proto & 1) {
1043 count--;
1044 } else {
1045 proto = (proto << 8) | (u_short) *c++;
1046 count -= 2;
1047 }
1048
1049
1050 if ((ppp->dev->flags & IFF_UP) && ppp_do_ip(ppp, proto, c, count)) {
1051 ppp->ddinfo.ip_rjiffies = jiffies;
1052 return;
1053 }
1054
1055
1056
1057
1058
1059
1060
1061 if (ppp_us_queue (ppp, proto, c, count+2)) {
1062 ppp->ddinfo.nip_rjiffies = jiffies;
1063 ppp->stats.rothers++;
1064 return;
1065 }
1066
1067
1068 PRINTKN (1,(KERN_WARNING
1069 "ppp: dropping packet on the floor: nobody could take it.\n"));
1070 ppp->stats.tossed++;
1071 }
1072
1073
1074
1075
1076
1077 static int
1078 ppp_do_ip (struct ppp *ppp, unsigned short proto, unsigned char *c,
1079 int count)
1080 {
1081 int flags, done;
1082
1083 PRINTKN (4,(KERN_DEBUG "ppp_do_ip: proto %x len %d first byte %x\n",
1084 (int) proto, count, c[0]));
1085
1086 if (ppp_debug_netpackets) {
1087 PRINTK (("KERN_DEBUG %s <-- proto %x len %d\n", ppp->dev->name,
1088 (int) proto, count));
1089 }
1090
1091 if (proto == PROTO_IP) {
1092 ppp->stats.runcomp++;
1093 goto sendit;
1094 }
1095
1096 if ((proto == PROTO_VJCOMP) && !(ppp->flags & SC_REJ_COMP_TCP)) {
1097
1098 done = 0;
1099 save_flags (flags);
1100 cli();
1101 if ((ppp->rhead + 80) < ppp->rend) {
1102 ppp->rhead += 80;
1103 ppp->rcount += 80;
1104 done = 1;
1105 }
1106 restore_flags(flags);
1107
1108 if (! done) {
1109 PRINTKN (1,(KERN_NOTICE
1110 "ppp: no space to decompress VJ compressed TCP header.\n"));
1111 ppp->stats.roverrun++;
1112 return 1;
1113 }
1114
1115 count = slhc_uncompress(ppp->slcomp, c, count);
1116 if (count <= 0) {
1117 ppp->stats.rerrors++;
1118 PRINTKN (1,(KERN_NOTICE "ppp: error in VJ decompression\n"));
1119 return 1;
1120 }
1121 ppp->stats.rcomp++;
1122 goto sendit;
1123 }
1124
1125 if ((proto == PROTO_VJUNCOMP) && !(ppp->flags & SC_REJ_COMP_TCP)) {
1126 if (slhc_remember(ppp->slcomp, c, count) <= 0) {
1127 ppp->stats.rerrors++;
1128 PRINTKN (1,(KERN_NOTICE "ppp: error in VJ memorizing\n"));
1129 return 1;
1130 }
1131 ppp->stats.runcomp++;
1132 goto sendit;
1133 }
1134
1135
1136 return 0;
1137
1138 sendit:
1139 if (ppp_debug_netpackets) {
1140 struct iphdr *iph = (struct iphdr *) c;
1141 PRINTK ((KERN_INFO "%s <-- src %lx dst %lx len %d\n", ppp->dev->name,
1142 iph->saddr, iph->daddr, count))
1143 }
1144
1145
1146 (void) dev_rint (c, count, 0, ppp->dev);
1147 return 1;
1148 }
1149
1150
1151
1152
1153 #define PUTC(c,label) *ppp->us_rbuff_head++ = c; \
1154 if (ppp->us_rbuff_head == ppp->us_rbuff_end) \
1155 ppp->us_rbuff_head = ppp->us_rbuff; \
1156 if (ppp->us_rbuff_head == ppp->us_rbuff_tail) \
1157 goto label;
1158 #define GETC(c) c = *ppp->us_rbuff_tail++; \
1159 if (ppp->us_rbuff_tail == ppp->us_rbuff_end) \
1160 ppp->us_rbuff_tail = ppp->us_rbuff;
1161
1162 static int
1163 ppp_us_queue(struct ppp *ppp, unsigned short proto,
1164 unsigned char *buf, int len)
1165 {
1166 int totlen;
1167 unsigned char *saved_head;
1168
1169 totlen = len+2;
1170
1171 if (set_bit(1, &ppp->us_rbuff_lock)) {
1172 PRINTKN (1, (KERN_NOTICE "ppp_us_queue: can't get lock\n"));
1173 return 0;
1174 }
1175 saved_head = ppp->us_rbuff_head;
1176
1177 PUTC((totlen & 0xff00) >> 8, failure);
1178 PUTC(totlen & 0x00ff, failure);
1179 PUTC((proto & 0xff00) >> 8, failure);
1180 PUTC(proto & 0x00ff, failure);
1181
1182 while (len-- > 0) {
1183 PUTC(*buf++, failure);
1184 }
1185
1186 PRINTKN (3, (KERN_INFO "ppp: successfully queued %d bytes\n", totlen));
1187 clear_bit(1, &ppp->us_rbuff_lock);
1188 wake_up_interruptible (&ppp->read_wait);
1189
1190 #ifdef NEW_TTY_DRIVERS
1191 kill_fasync(ppp->tty->fasync, SIGIO);
1192 #endif
1193
1194 if (ppp->inp_sig && ppp->inp_sig_pid)
1195 if (kill_proc (ppp->inp_sig_pid, ppp->inp_sig, 1) != 0) {
1196
1197 PRINTKN (2,(KERN_NOTICE
1198 "ppp: process that requested notification is gone\n"));
1199 ppp->inp_sig = 0;
1200 ppp->inp_sig_pid = 0;
1201 }
1202 return 1;
1203
1204 failure:
1205 ppp->us_rbuff_head = saved_head;
1206 clear_bit(1, &ppp->us_rbuff_lock);
1207
1208 PRINTKN (1, (KERN_NOTICE "ppp_us_queue: ran out of buffer space.\n"));
1209
1210 return 0;
1211 }
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225 static int
1226 ppp_read(struct tty_struct *tty, struct file *file, unsigned char *buf, unsigned int nr)
1227 {
1228 struct ppp *ppp = ppp_find(tty);
1229 unsigned char c;
1230 int len, i;
1231
1232 if (!ppp || ppp->magic != PPP_MAGIC) {
1233 PRINTKN (1,(KERN_ERR "ppp_read: cannot find ppp channel\n"));
1234 return -EIO;
1235 }
1236
1237 CHECK_PPP(-ENXIO);
1238
1239 PRINTKN (4,(KERN_DEBUG "ppp_read: called %x num %u\n",
1240 (unsigned int) buf,
1241 nr));
1242
1243 do {
1244
1245 if (set_bit(0, &ppp->us_rbuff_lock) == 0) {
1246
1247 if (ppp->us_rbuff_head == ppp->us_rbuff_tail) {
1248
1249 PRINTKN (4,(KERN_DEBUG "ppp_read: no data\n"));
1250 clear_bit(0, &ppp->us_rbuff_lock);
1251 if (ppp->inp_sig) {
1252 PRINTKN (4,(KERN_DEBUG "ppp_read: EWOULDBLOCK\n"));
1253 return -EWOULDBLOCK;
1254 } else goto wait;
1255 }
1256
1257
1258 ppp->ddinfo.nip_rjiffies = jiffies;
1259
1260 GETC (c); len = c << 8; GETC (c); len += c;
1261
1262 PRINTKN (4,(KERN_DEBUG "ppp_read: len = %d\n", len));
1263
1264 if (len + 2 > nr) {
1265
1266 PRINTKN (1,(KERN_DEBUG
1267 "ppp: read of %u bytes too small for %d frame\n",
1268 nr, len+2));
1269 ppp->us_rbuff_head += len;
1270 if (ppp->us_rbuff_head > ppp->us_rbuff_end)
1271 ppp->us_rbuff_head += - (ppp->us_rbuff_end - ppp->us_rbuff);
1272 clear_bit(0, &ppp->us_rbuff_lock);
1273 wake_up_interruptible (&ppp->read_wait);
1274 ppp->stats.rgiants++;
1275 return -EOVERFLOW;
1276 } else {
1277
1278 put_fs_byte (PPP_ADDRESS, buf++);
1279 put_fs_byte (PPP_CONTROL, buf++);
1280 i = len;
1281 while (i-- > 0) {
1282 GETC (c);
1283 put_fs_byte (c, buf++);
1284 }
1285 }
1286
1287 clear_bit(0, &ppp->us_rbuff_lock);
1288 PRINTKN (3,(KERN_DEBUG "ppp_read: passing %d bytes up\n", len + 2));
1289 ppp->stats.rothers++;
1290 return len + 2;
1291 }
1292
1293
1294 wait:
1295 current->timeout = 0;
1296 PRINTKN (3,(KERN_DEBUG "ppp_read: sleeping\n"));
1297 interruptible_sleep_on (&ppp->read_wait);
1298 if (current->signal & ~current->blocked)
1299 return -EINTR;
1300 } while (1);
1301 }
1302
1303
1304
1305
1306 static inline void
1307 ppp_stuff_char(struct ppp *ppp, unsigned char c)
1308 {
1309 int curpt = ppp->xhead - ppp->xbuff;
1310 if ((curpt < 0) || (curpt > 3000)) {
1311 PRINTK ((KERN_DEBUG "ppp_stuff_char: %x %x %d\n",
1312 (unsigned int) ppp->xbuff, (unsigned int) ppp->xhead, curpt))
1313 }
1314 if (in_xmap (ppp, c)) {
1315 *ppp->xhead++ = PPP_ESC;
1316 *ppp->xhead++ = c ^ PPP_TRANS;
1317 } else
1318 *ppp->xhead++ = c;
1319 ppp->fcs = (ppp->fcs >> 8) ^ fcstab[(ppp->fcs ^ c) & 0xff];
1320 }
1321
1322
1323
1324
1325
1326 static int
1327 ppp_write(struct tty_struct *tty, struct file *file, unsigned char *buf, unsigned int nr)
1328 {
1329 struct ppp *ppp = ppp_find(tty);
1330 int i;
1331
1332 if (!ppp || ppp->magic != PPP_MAGIC) {
1333 PRINTKN (1,(KERN_ERR "ppp_write: cannot find ppp unit\n"));
1334 return -EIO;
1335 }
1336
1337 CHECK_PPP(-ENXIO);
1338
1339 if (ppp->mtu != ppp->dev->mtu)
1340 ppp_changedmtu (ppp, ppp->dev->mtu, ppp->mru);
1341
1342 if (nr > ppp->mtu) {
1343 PRINTKN (1,(KERN_WARNING
1344 "ppp_write: truncating user packet from %u to mtu %d\n",
1345 nr, ppp->mtu));
1346 nr = ppp->mtu;
1347 }
1348
1349 if (ppp_debug >= 3)
1350 ppp_print_buffer ("write frame", buf, nr, USER_DS);
1351
1352
1353
1354 while ((ppp->sending == 1) || !ppp_lock(ppp)) {
1355 current->timeout = 0;
1356 PRINTKN (3,(KERN_DEBUG "ppp_write: sleeping\n"));
1357 interruptible_sleep_on(&ppp->write_wait);
1358 if (current->signal & ~current->blocked)
1359 return -EINTR;
1360 }
1361
1362
1363
1364 PRINTKN(4,(KERN_DEBUG "ppp_write: acquired write lock\n"));
1365 ppp->xhead = ppp->xbuff;
1366
1367 #ifdef OPTIMIZE_FLAG_TIME
1368 if (jiffies - ppp->last_xmit > OPTIMIZE_FLAG_TIME)
1369 *ppp->xhead++ = PPP_FLAG;
1370 ppp->last_xmit = jiffies;
1371 #else
1372 *ppp->xhead++ = PPP_FLAG;
1373 #endif
1374
1375 ppp->fcs = PPP_FCS_INIT;
1376 i = nr;
1377 while (i-- > 0)
1378 ppp_stuff_char(ppp,get_fs_byte(buf++));
1379
1380 ppp_add_fcs(ppp);
1381
1382 *ppp->xhead++ = PPP_FLAG;
1383
1384
1385 ppp->ddinfo.nip_sjiffies = jiffies;
1386
1387 if (ppp_debug >= 6)
1388 ppp_print_buffer ("xmit buffer", ppp->xbuff, ppp->xhead - ppp->xbuff, KERNEL_DS);
1389 else {
1390 PRINTKN (4,(KERN_DEBUG
1391 "ppp_write: writing %d chars\n", ppp->xhead - ppp->xbuff));
1392 }
1393
1394
1395 ++ppp->stats.sothers;
1396 ppp_kick_tty(ppp);
1397
1398 return((int)nr);
1399 }
1400
1401 static int
1402 ppp_ioctl(struct tty_struct *tty, struct file *file, unsigned int i,
1403 unsigned long l)
1404 {
1405 struct ppp *ppp = ppp_find(tty);
1406 register int temp_i = 0;
1407 int error;
1408
1409 if (!ppp || ppp->magic != PPP_MAGIC) {
1410 PRINTK ((KERN_ERR "ppp_ioctl: can't find PPP block from tty!\n"))
1411 return -EBADF;
1412 }
1413
1414 CHECK_PPP(-ENXIO);
1415
1416
1417 if (!suser())
1418 return -EPERM;
1419
1420 switch (i) {
1421 case PPPIOCSMRU:
1422 error = verify_area (VERIFY_READ, (void *) l, sizeof (temp_i));
1423 if (error == 0) {
1424 temp_i = (int) get_fs_long (l);
1425 PRINTKN (3,(KERN_INFO "ppp_ioctl: set mru to %d\n", temp_i));
1426 if (ppp->mru != temp_i)
1427 ppp_changedmtu (ppp, ppp->dev->mtu, temp_i);
1428 }
1429 break;
1430
1431 case PPPIOCGFLAGS:
1432 error = verify_area (VERIFY_WRITE, (void *) l, sizeof (temp_i));
1433 if (error == 0) {
1434 temp_i = (ppp->flags & SC_MASK);
1435 #ifndef CHECK_CHARACTERS
1436 temp_i |= SC_RCV_B7_1 | SC_RCV_B7_0 | SC_RCV_ODDP | SC_RCV_EVNP;
1437 #endif
1438 put_fs_long ((long) temp_i, l);
1439 PRINTKN (3,(KERN_DEBUG "ppp_ioctl: get flags: addr %lx flags %x\n",
1440 l,
1441 temp_i));
1442 }
1443 break;
1444
1445 case PPPIOCSFLAGS:
1446 error = verify_area (VERIFY_READ, (void *) l, sizeof (temp_i));
1447 if (error == 0) {
1448 temp_i = (int) get_fs_long (l);
1449 ppp->flags ^= ((ppp->flags ^ temp_i) & SC_MASK);
1450 PRINTKN (3,(KERN_INFO "ppp_ioctl: set flags to %x\n", temp_i));
1451 }
1452 break;
1453
1454 case PPPIOCGASYNCMAP:
1455 error = verify_area (VERIFY_WRITE, (void *) l, sizeof (temp_i));
1456 if (error == 0) {
1457 put_fs_long (ppp->xmit_async_map[0], l);
1458 PRINTKN (3,(KERN_INFO "ppp_ioctl: get asyncmap: addr %lx asyncmap %lx\n",
1459 l, ppp->xmit_async_map[0]));
1460 }
1461 break;
1462
1463 case PPPIOCSASYNCMAP:
1464 error = verify_area (VERIFY_READ, (void *) l, sizeof (temp_i));
1465 if (error == 0) {
1466 ppp->xmit_async_map[0] = get_fs_long (l);
1467 bset (ppp->xmit_async_map, PPP_FLAG);
1468 bset (ppp->xmit_async_map, PPP_ESC);
1469 PRINTKN (3,(KERN_INFO "ppp_ioctl: set xmit asyncmap %lx\n",
1470 ppp->xmit_async_map[0]));
1471 }
1472 break;
1473
1474 case PPPIOCRASYNCMAP:
1475 error = verify_area (VERIFY_READ, (void *) l, sizeof (temp_i));
1476 if (error == 0) {
1477 ppp->recv_async_map = get_fs_long (l);
1478 PRINTKN (3,(KERN_INFO "ppp_ioctl: set recv asyncmap %lx\n",
1479 ppp->recv_async_map));
1480 }
1481 break;
1482
1483 case PPPIOCGUNIT:
1484 error = verify_area (VERIFY_WRITE, (void *) l, sizeof (temp_i));
1485 if (error == 0) {
1486 put_fs_long (ppp->dev->base_addr, l);
1487 PRINTKN (3,(KERN_INFO "ppp_ioctl: get unit: %ld", ppp->dev->base_addr));
1488 }
1489 break;
1490
1491 case PPPIOCSINPSIG:
1492 error = verify_area (VERIFY_READ, (void *) l, sizeof (temp_i));
1493 if (error == 0) {
1494 ppp->inp_sig = (int) get_fs_long (l);
1495 ppp->inp_sig_pid = current->pid;
1496 PRINTKN (3,(KERN_INFO "ppp_ioctl: set input signal %d\n", ppp->inp_sig));
1497 }
1498 break;
1499
1500 case PPPIOCSDEBUG:
1501 error = verify_area (VERIFY_READ, (void *) l, sizeof (temp_i));
1502 if (error == 0) {
1503 ppp_debug = (int) get_fs_long (l);
1504 ppp_debug_netpackets = (ppp_debug & 0xff00) >> 8;
1505 ppp_debug &= 0xff;
1506 PRINTKN (1, (KERN_INFO "ppp_ioctl: set debug level %d, netpacket %d\n",
1507 ppp_debug, ppp_debug_netpackets));
1508 }
1509 break;
1510
1511 case PPPIOCGDEBUG:
1512 error = verify_area (VERIFY_WRITE, (void *) l, sizeof (temp_i));
1513 if (error == 0) {
1514 put_fs_long ((long) (ppp_debug | (ppp_debug_netpackets << 8)), l);
1515 PRINTKN (3,(KERN_INFO "ppp_ioctl: get debug level %d\n",
1516 ppp_debug | (ppp_debug_netpackets << 8)));
1517 }
1518 break;
1519
1520 case PPPIOCGSTAT:
1521 error = verify_area (VERIFY_WRITE, (void *) l, sizeof (struct ppp_stats));
1522 if (error == 0) {
1523 memcpy_tofs ((void *) l, &ppp->stats, sizeof (struct ppp_stats));
1524 PRINTKN (3,(KERN_INFO "ppp_ioctl: read statistics\n"));
1525 }
1526 break;
1527
1528 case PPPIOCGTIME:
1529 error = verify_area (VERIFY_WRITE, (void *) l, sizeof (struct ppp_ddinfo));
1530 if (error == 0) {
1531 struct ppp_ddinfo cur_ddinfo;
1532 unsigned long cur_jiffies = jiffies;
1533
1534
1535 cur_ddinfo.ip_sjiffies = cur_jiffies - ppp->ddinfo.ip_sjiffies;
1536 cur_ddinfo.ip_rjiffies = cur_jiffies - ppp->ddinfo.ip_rjiffies;
1537 cur_ddinfo.nip_sjiffies = cur_jiffies - ppp->ddinfo.nip_sjiffies;
1538 cur_ddinfo.nip_rjiffies = cur_jiffies - ppp->ddinfo.nip_rjiffies;
1539
1540 memcpy_tofs ((void *) l, &cur_ddinfo, sizeof (struct ppp_ddinfo));
1541 PRINTKN (3,(KERN_INFO "ppp_ioctl: read demand dial info\n"));
1542 }
1543 break;
1544
1545 case PPPIOCGXASYNCMAP:
1546 error = verify_area (VERIFY_WRITE,
1547 (void *) l,
1548 sizeof (ppp->xmit_async_map));
1549 if (error == 0) {
1550 memcpy_tofs ((void *) l,
1551 ppp->xmit_async_map,
1552 sizeof (ppp->xmit_async_map));
1553 PRINTKN (3,(KERN_INFO "ppp_ioctl: get xasyncmap: addr %lx\n", l));
1554 }
1555 break;
1556
1557 case PPPIOCSXASYNCMAP:
1558 error = verify_area (VERIFY_READ, (void *) l,
1559 sizeof (ppp->xmit_async_map));
1560 if (error == 0) {
1561 unsigned long temp_tbl [8];
1562
1563 memcpy_fromfs (temp_tbl, (void *) l, sizeof (ppp->xmit_async_map));
1564 temp_tbl[1] = 0x00000000;
1565 temp_tbl[2] &= ~0x40000000;
1566 temp_tbl[3] |= 0x60000000;
1567
1568 if ((temp_tbl[2] & temp_tbl[3]) != 0 ||
1569 (temp_tbl[4] & temp_tbl[5]) != 0 ||
1570 (temp_tbl[6] & temp_tbl[7]) != 0)
1571 error = -EINVAL;
1572 else {
1573 memcpy (ppp->xmit_async_map, temp_tbl, sizeof (ppp->xmit_async_map));
1574 PRINTKN (3,(KERN_INFO "ppp_ioctl: set xasyncmap\n"));
1575 }
1576 }
1577 break;
1578
1579 case PPPIOCSMAXCID:
1580 error = verify_area (VERIFY_READ, (void *) l, sizeof (temp_i));
1581 if (error == 0) {
1582 temp_i = (int) get_fs_long (l) + 1;
1583 PRINTKN (3,(KERN_INFO "ppp_ioctl: set maxcid to %d\n", temp_i));
1584 if (ppp->slcomp != NULL)
1585 slhc_free (ppp->slcomp);
1586
1587 ppp->slcomp = slhc_init (temp_i, temp_i);
1588
1589 if (ppp->slcomp == NULL) {
1590 PRINTKN (1,(KERN_ERR "ppp: no space for compression buffers!\n"));
1591 ppp_release (ppp);
1592 error = -ENOMEM;
1593 }
1594 }
1595 break;
1596
1597 #ifdef NEW_TTY_DRIVERS
1598
1599 case TCGETS:
1600 case TCGETA:
1601 error = n_tty_ioctl(tty, file, i, l);
1602 break;
1603 #endif
1604
1605
1606
1607
1608
1609 default:
1610 PRINTKN (1,(KERN_ERR "ppp_ioctl: invalid ioctl: %x, addr %lx\n",
1611 i,
1612 l));
1613 #ifdef NEW_TTY_DRIVERS
1614 error = -ENOIOCTLCMD;
1615 #else
1616 error = -EINVAL;
1617 #endif
1618 break;
1619 }
1620 return error;
1621 }
1622
1623 static int
1624 ppp_select (struct tty_struct *tty, struct inode * inode,
1625 struct file * filp, int sel_type, select_table * wait)
1626 {
1627 struct ppp *ppp = ppp_find (tty);
1628
1629 if (!ppp || ppp->magic != PPP_MAGIC) {
1630 PRINTK ((KERN_ERR "ppp_select: can't find PPP block from tty!\n"))
1631 return -EBADF;
1632 }
1633
1634
1635 CHECK_PPP (0);
1636
1637
1638 switch (sel_type) {
1639 case SEL_IN:
1640 if (set_bit(0, &ppp->us_rbuff_lock) == 0) {
1641
1642 if (ppp->us_rbuff_head != ppp->us_rbuff_tail) {
1643 clear_bit (0, &ppp->us_rbuff_lock);
1644 return 1;
1645 }
1646 clear_bit (0, &ppp->us_rbuff_lock);
1647 }
1648
1649 case SEL_EX:
1650
1651 if (tty->packet && tty->link->ctrl_status)
1652 return 1;
1653
1654
1655 if (tty->flags & (1 << TTY_SLAVE_CLOSED))
1656 return 1;
1657
1658
1659 if (tty_hung_up_p(filp))
1660 return 1;
1661
1662 select_wait (&ppp->read_wait, wait);
1663 break;
1664
1665 case SEL_OUT:
1666 if (ppp_lock (ppp)) {
1667 if (ppp->sending == 0) {
1668 ppp_unlock (ppp);
1669 return 1;
1670 }
1671 ppp_unlock (ppp);
1672 }
1673 select_wait (&ppp->write_wait, wait);
1674 break;
1675 }
1676 return 0;
1677 }
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687 int
1688 ppp_xmit(struct sk_buff *skb, struct device *dev)
1689 {
1690 struct tty_struct *tty;
1691 struct ppp *ppp;
1692 unsigned char *p;
1693 unsigned short proto;
1694 int len;
1695
1696
1697 if (skb == NULL) {
1698 PRINTKN(3,(KERN_WARNING "ppp_xmit: null packet!\n"));
1699 return 0;
1700 }
1701
1702
1703 ppp = &ppp_ctrl[dev->base_addr];
1704 tty = ppp->tty;
1705 p = (unsigned char *) (skb + 1);
1706 len = skb->len;
1707 proto = PROTO_IP;
1708
1709 PRINTKN(4,(KERN_DEBUG "ppp_xmit [%s]: skb %lX busy %d\n", dev->name,
1710 (unsigned long int) skb, ppp->sending));
1711
1712 CHECK_PPP(0);
1713
1714 if (tty == NULL) {
1715 PRINTKN(1,(KERN_ERR "ppp_xmit: %s not connected to a TTY!\n", dev->name));
1716 goto done;
1717 }
1718
1719 if (!(dev->flags & IFF_UP)) {
1720 PRINTKN(1,(KERN_WARNING
1721 "ppp_xmit: packet sent on interface %s, which is down for IP\n",
1722 dev->name));
1723 goto done;
1724 }
1725
1726
1727 if (len < sizeof(struct iphdr)) {
1728 PRINTKN(0,(KERN_ERR "ppp_xmit: given runt packet, ignoring\n"));
1729 return 1;
1730 }
1731 len = ntohs( ((struct iphdr *)(skb->data)) -> tot_len );
1732
1733
1734 if (ppp->flags & SC_IP_DOWN) {
1735 if (ppp->flags & SC_IP_FLUSH == 0) {
1736 if (ppp_us_queue (ppp, proto, p, len))
1737 ppp->flags |= SC_IP_FLUSH;
1738 }
1739 goto done;
1740 }
1741
1742
1743 if (ppp->sending || !ppp_lock(ppp)) {
1744 PRINTKN(3,(KERN_WARNING "ppp_xmit: busy\n"));
1745 ppp->stats.sbusy++;
1746 return 1;
1747 }
1748
1749 ppp->xhead = ppp->xbuff;
1750
1751
1752 if (ppp->flags & SC_COMP_TCP) {
1753
1754 len = slhc_compress(ppp->slcomp, p, len, ppp->cbuff, &p, 0);
1755 if (p[0] & SL_TYPE_COMPRESSED_TCP)
1756 proto = PROTO_VJCOMP;
1757 else {
1758 if (p[0] >= SL_TYPE_UNCOMPRESSED_TCP) {
1759 proto = PROTO_VJUNCOMP;
1760 p[0] = (p[0] & 0x0f) | 0x40;
1761 }
1762 }
1763 }
1764
1765
1766 if (proto == PROTO_VJCOMP)
1767 ++ppp->stats.scomp;
1768 else
1769 ++ppp->stats.suncomp;
1770
1771 if (ppp_debug_netpackets) {
1772 struct iphdr *iph = (struct iphdr *) (skb + 1);
1773 PRINTK ((KERN_DEBUG "%s ==> proto %x len %d src %x dst %x proto %d\n",
1774 dev->name, (int) proto, (int) len, (int) iph->saddr,
1775 (int) iph->daddr, (int) iph->protocol))
1776 }
1777
1778
1779 #ifdef OPTIMIZE_FLAG_TIME
1780 if (jiffies - ppp->last_xmit > OPTIMIZE_FLAG_TIME)
1781 *ppp->xhead++ = PPP_FLAG;
1782 ppp->last_xmit = jiffies;
1783 #else
1784 *ppp->xhead++ = PPP_FLAG;
1785 #endif
1786
1787 ppp->fcs = PPP_FCS_INIT;
1788 if (!(ppp->flags & SC_COMP_AC)) {
1789 ppp_stuff_char(ppp, PPP_ADDRESS);
1790 ppp_stuff_char(ppp, PPP_CONTROL);
1791 }
1792
1793 if (!(ppp->flags & SC_COMP_PROT) || (proto & 0xff00))
1794 ppp_stuff_char(ppp, proto>>8);
1795 ppp_stuff_char(ppp, proto&0xff);
1796
1797
1798 while (len-- > 0)
1799 ppp_stuff_char(ppp, *p++);
1800
1801
1802 ppp_add_fcs(ppp);
1803 *ppp->xhead++ = PPP_FLAG;
1804
1805
1806 ppp->ddinfo.ip_sjiffies = jiffies;
1807
1808
1809 if (ppp_debug >= 6)
1810 ppp_print_buffer ("xmit buffer", ppp->xbuff, ppp->xhead - ppp->xbuff, KERNEL_DS);
1811 else {
1812 PRINTKN (4,(KERN_DEBUG
1813 "ppp_write: writing %d chars\n", ppp->xhead - ppp->xbuff));
1814 }
1815
1816 ppp_kick_tty(ppp);
1817
1818 done:
1819 dev_kfree_skb(skb, FREE_WRITE);
1820 return 0;
1821 }
1822
1823 static unsigned short
1824 ppp_type_trans (struct sk_buff *skb, struct device *dev)
1825 {
1826 return(htons(ETH_P_IP));
1827 }
1828
1829 #ifdef NET02D
1830 static int
1831 ppp_header(unsigned char *buff, struct device *dev, unsigned short type,
1832 unsigned long daddr, unsigned long saddr, unsigned len)
1833 {
1834 return(0);
1835 }
1836
1837 static int
1838 ppp_rebuild_header(void *buff, struct device *dev)
1839 {
1840 return(0);
1841 }
1842
1843 static void
1844 ppp_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
1845 {
1846 }
1847
1848 #else
1849
1850 static int
1851 ppp_header(unsigned char *buff, struct device *dev, unsigned short type,
1852 void *daddr, void *saddr, unsigned len, struct sk_buff *skb)
1853 {
1854 return(0);
1855 }
1856
1857 static int
1858 ppp_rebuild_header(void *buff, struct device *dev, unsigned long raddr,
1859 struct sk_buff *skb)
1860 {
1861 return(0);
1862 }
1863 #endif
1864
1865 static struct enet_statistics *
1866 ppp_get_stats (struct device *dev)
1867 {
1868 struct ppp *ppp = &ppp_ctrl[dev->base_addr];
1869 static struct enet_statistics ppp_stats;
1870
1871 ppp_stats.rx_packets = ppp->stats.rcomp + ppp->stats.runcomp;
1872 ppp_stats.rx_errors = ppp->stats.rerrors;
1873 ppp_stats.rx_dropped = ppp->stats.tossed;
1874 ppp_stats.rx_fifo_errors = 0;
1875 ppp_stats.rx_length_errors = ppp->stats.runts;
1876 ppp_stats.rx_over_errors = ppp->stats.roverrun;
1877 ppp_stats.rx_crc_errors = 0;
1878 ppp_stats.rx_frame_errors = 0;
1879 ppp_stats.tx_packets = ppp->stats.scomp + ppp->stats.suncomp;
1880 ppp_stats.tx_errors = ppp->stats.serrors;
1881 ppp_stats.tx_dropped = 0;
1882 ppp_stats.tx_fifo_errors = 0;
1883 ppp_stats.collisions = ppp->stats.sbusy;
1884 ppp_stats.tx_carrier_errors = 0;
1885 ppp_stats.tx_aborted_errors = 0;
1886 ppp_stats.tx_window_errors = 0;
1887 ppp_stats.tx_heartbeat_errors = 0;
1888
1889 PRINTKN (3, (KERN_INFO "ppp_get_stats called"));
1890 return &ppp_stats;
1891 }
1892
1893
1894
1895
1896
1897
1898 #ifndef NEW_TTY_DRIVERS
1899
1900 struct ppp *
1901 ppp_find(struct tty_struct *tty)
1902 {
1903 int i;
1904 for (i = 0; i < PPP_NRUNIT; i++)
1905 if (ppp_ctrl[i].inuse && (ppp_ctrl[i].tty == tty)) return &ppp_ctrl[i];
1906
1907 return NULL;
1908 }
1909 #endif
1910
1911
1912 static struct ppp *
1913 ppp_alloc(void)
1914 {
1915 int i;
1916 for (i = 0; i < PPP_NRUNIT; i++)
1917 if (!set_bit(0, &ppp_ctrl[i].inuse)) return &ppp_ctrl[i];
1918
1919 return NULL;
1920 }
1921
1922
1923
1924
1925
1926
1927 static int
1928 ppp_lock(struct ppp *ppp)
1929 {
1930 int flags, locked;
1931 save_flags(flags);
1932 cli();
1933 locked = ppp->sending;
1934 ppp->sending = 1;
1935 if (ppp->dev->flags & IFF_UP)
1936 ppp->dev->tbusy = 1;
1937 restore_flags(flags);
1938 return locked == 0;
1939 }
1940
1941 static void
1942 ppp_unlock(struct ppp *ppp)
1943 {
1944 int flags;
1945 save_flags(flags);
1946 cli();
1947 ppp->sending = 0;
1948 if (ppp->dev->flags & IFF_UP)
1949 ppp->dev->tbusy = 0;
1950 restore_flags(flags);
1951 }
1952
1953
1954
1955 static void
1956 ppp_add_fcs(struct ppp *ppp)
1957 {
1958 unsigned short fcs = ppp->fcs;
1959
1960 fcs ^= 0xffff;
1961 ppp_stuff_char(ppp, fcs & 0x00ff);
1962 ppp_stuff_char(ppp, (fcs & 0xff00) >> 8);
1963 ASSERT (ppp->fcs == PPP_FCS_GOOD);
1964 PRINTKN (4,(KERN_DEBUG "ppp_add_fcs: fcs is %lx\n",
1965 (long) (unsigned long) fcs));
1966 }
1967
1968 static int
1969 ppp_check_fcs(struct ppp *ppp)
1970 {
1971 unsigned short fcs = PPP_FCS_INIT, msgfcs;
1972 unsigned char *c = ppp->rbuff;
1973 int i;
1974
1975 for (i = 0; i < ppp->rcount - 2; i++, c++)
1976 fcs = (fcs >> 8) ^ fcstab[(fcs ^ *c) & 0xff];
1977
1978 fcs ^= 0xffff;
1979 msgfcs = (c[1] << 8) + c[0];
1980 PRINTKN (4,(KERN_INFO "ppp_check_fcs: got %lx want %lx\n",
1981 (unsigned long) msgfcs, (unsigned long) fcs));
1982 return fcs == msgfcs;
1983 }
1984
1985 static char hex[] = "0123456789ABCDEF";
1986
1987 static inline void ppp_print_hex (register char *out, char *in, int count)
1988 {
1989 register unsigned char next_ch;
1990
1991 while (count-- > 0) {
1992 next_ch = (unsigned char) get_fs_byte (in);
1993
1994 *out++ = hex[(next_ch >> 4) & 0x0F];
1995 *out++ = hex[next_ch & 0x0F];
1996 ++out;
1997 ++in;
1998 }
1999 }
2000
2001 static inline void ppp_print_char (register char *out, char *in, int count)
2002 {
2003 register unsigned char next_ch;
2004
2005 while (count-- > 0) {
2006 next_ch = (unsigned char) get_fs_byte (in);
2007
2008 if (next_ch < 0x20 || next_ch > 0x7e)
2009 *out++ = '.';
2010 else {
2011 *out++ = next_ch;
2012 if (next_ch == '%')
2013 *out++ = '%';
2014 }
2015 ++in;
2016 }
2017 *out = '\0';
2018 }
2019
2020 static void ppp_print_buffer(const char *name, char *buf, int count, int seg)
2021 {
2022 char line [44];
2023 int old_fs = get_fs();
2024
2025 set_fs (seg);
2026
2027 if (name != NULL)
2028 PRINTK ((KERN_DEBUG "ppp: %s, count = %d\n", name, count));
2029
2030 while (count > 8) {
2031 memset (line, ' ', sizeof (line));
2032 ppp_print_hex (line, buf, 8);
2033 ppp_print_char (&line[8 * 3], buf, 8);
2034 PRINTK ((KERN_DEBUG "%s\n", line));
2035 count -= 8;
2036 buf += 8;
2037 }
2038
2039 if (count > 0) {
2040 memset (line, ' ', sizeof (line));
2041 ppp_print_hex (line, buf, count);
2042 ppp_print_char (&line[8 * 3], buf, count);
2043 PRINTK ((KERN_DEBUG "%s\n", line));
2044 }
2045
2046 set_fs (old_fs);
2047 }
2048
2049 #ifdef MODULE
2050 char kernel_version[] = UTS_RELEASE;
2051
2052 static struct device dev_ppp[PPP_NRUNIT] = {
2053 {
2054 "ppp0",
2055 0, 0, 0, 0,
2056 0, 0,
2057 0, 0, 0, NULL, ppp_init,
2058 },
2059 { "ppp1" , 0, 0, 0, 0, 1, 0, 0, 0, 0, NULL, ppp_init },
2060 { "ppp2" , 0, 0, 0, 0, 2, 0, 0, 0, 0, NULL, ppp_init },
2061 { "ppp3" , 0, 0, 0, 0, 3, 0, 0, 0, 0, NULL, ppp_init },
2062 };
2063
2064 int
2065 init_module(void)
2066 {
2067 int err;
2068 int i;
2069
2070 for (i = 0; i < PPP_NRUNIT; i++) {
2071 if ((err = register_netdev(&dev_ppp[i]))) {
2072 if (err == -EEXIST) {
2073 printk("PPP: devices already present. Module not loaded.\n");
2074 }
2075 return err;
2076 }
2077 }
2078 return 0;
2079 }
2080
2081 void
2082 cleanup_module(void)
2083 {
2084 int i;
2085
2086 if (MOD_IN_USE) {
2087 printk("PPP: device busy, remove delayed\n");
2088 return;
2089 }
2090 for (i = 0; i < PPP_NRUNIT; i++) {
2091 unregister_netdev(&dev_ppp[i]);
2092 }
2093 if ((i = tty_register_ldisc(N_PPP, NULL))) {
2094 printk("PPP: can't unregister line discipline (err = %d)\n", i);
2095 }
2096 }
2097
2098 #endif