pre-2.3.4..
[davej-history.git] / drivers / isdn / isdn_ppp.c
blob7bce66d44e423b59988e397de211bf3eba0967a2
1 /* $Id: isdn_ppp.c,v 1.47 1999/04/18 14:06:59 fritz Exp $
3 * Linux ISDN subsystem, functions for synchronous PPP (linklevel).
5 * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * $Log: isdn_ppp.c,v $
22 * Revision 1.47 1999/04/18 14:06:59 fritz
23 * Removed TIMRU stuff.
25 * Revision 1.46 1999/04/12 12:33:35 fritz
26 * Changes from 2.0 tree.
28 * Revision 1.45 1998/12/30 17:48:24 paul
29 * fixed syncPPP callback out
31 * Revision 1.44 1998/10/30 17:55:34 he
32 * dialmode for x25iface and multulink ppp
34 * Revision 1.43 1998/10/29 17:23:54 hipp
35 * Minor MPPP fixes, verboser logging.
37 * Revision 1.42 1998/07/20 11:30:07 hipp
38 * Readded compression check
40 * Revision 1.41 1998/07/08 16:50:57 hipp
41 * Compression changes
43 * Revision 1.40 1998/04/06 19:07:27 hipp
44 * added check, whether compression is enabled.
46 * Revision 1.39 1998/03/25 22:46:53 hipp
47 * Some additional CCP changes.
49 * Revision 1.38 1998/03/24 16:33:06 hipp
50 * More CCP changes. BSD compression now "works" on a local loopback link.
51 * Moved some isdn_ppp stuff from isdn.h to isdn_ppp.h
53 * Revision 1.37 1998/03/22 18:50:49 hipp
54 * Added BSD Compression for syncPPP .. UNTESTED at the moment
56 * Revision 1.36 1998/03/09 17:46:30 he
57 * merged in 2.1.89 changes
59 * Revision 1.35 1998/03/07 18:21:11 cal
60 * Dynamic Timeout-Rule-Handling vs. 971110 included
62 * Revision 1.34 1998/02/25 17:49:48 he
63 * Changed return codes caused be failing copy_{to,from}_user to -EFAULT
65 * Revision 1.33 1998/02/20 17:11:54 fritz
66 * Changes for recent kernels.
68 * Revision 1.32 1998/01/31 19:29:55 calle
69 * Merged changes from and for 2.1.82, not tested only compiled ...
71 * Revision 1.31 1997/10/09 21:29:01 fritz
72 * New HL<->LL interface:
73 * New BSENT callback with nr. of bytes included.
74 * Sending without ACK.
75 * New L1 error status (not yet in use).
76 * Cleaned up obsolete structures.
77 * Implemented Cisco-SLARP.
78 * Changed local net-interface data to be dynamically allocated.
79 * Removed old 2.0 compatibility stuff.
81 * Revision 1.30 1997/10/01 09:20:38 fritz
82 * Removed old compatibility stuff for 2.0.X kernels.
83 * From now on, this code is for 2.1.X ONLY!
84 * Old stuff is still in the separate branch.
86 * Revision 1.29 1997/08/21 23:11:44 fritz
87 * Added changes for kernels >= 2.1.45
89 * Revision 1.28 1997/06/17 13:05:57 hipp
90 * Applied Eric's underflow-patches (slightly modified)
91 * more compression changes (but disabled at the moment)
92 * changed one copy_to_user() to run with enabled IRQs
93 * a few MP changes
94 * changed 'proto' handling in the isdn_ppp receive code
96 * Revision 1.27 1997/03/30 16:51:17 calle
97 * changed calls to copy_from_user/copy_to_user and removed verify_area
98 * were possible.
100 * Revision 1.26 1997/02/23 16:53:44 hipp
101 * minor cleanup
102 * some initial changes for future PPP compresion
103 * added AC,PC compression for outgoing frames
105 * Revision 1.25 1997/02/12 20:37:35 hipp
106 * New ioctl() PPPIOCGCALLINFO, minor cleanup
108 * Revision 1.24 1997/02/11 18:32:56 fritz
109 * Bugfix in isdn_ppp_free_mpqueue().
111 * Revision 1.23 1997/02/10 11:12:19 fritz
112 * More changes for Kernel 2.1.X compatibility.
114 * Revision 1.22 1997/02/06 15:03:51 hipp
115 * changed GFP_KERNEL kmalloc to GFP_ATOMIC in isdn_ppp_fill_mpqueue()
117 * Revision 1.21 1997/02/03 23:29:38 fritz
118 * Reformatted according CodingStyle
119 * Bugfix: removed isdn_ppp_skb_destructor, used by upper layers.
120 * Misc changes for Kernel 2.1.X compatibility.
122 * Revision 1.20 1996/10/30 12:21:58 fritz
123 * Cosmetic fix: Compiler warning when compiling without MPP.
125 * Revision 1.19 1996/10/25 19:03:21 hipp
126 * changed/added some defines to (re)allow compilation without MP/VJ
128 * Revision 1.18 1996/10/22 23:14:00 fritz
129 * Changes for compatibility to 2.0.X and 2.1.X kernels.
131 * Revision 1.17 1996/10/22 09:39:49 hipp
132 * a few MP changes and bugfixes
134 * Revision 1.16 1996/09/23 01:58:10 fritz
135 * Fix: With syncPPP encapsulation, discard LCP packets
136 * when calculating hangup timeout.
138 * Revision 1.15 1996/09/07 12:50:12 hipp
139 * bugfixes (unknown device after failed dial attempt, minor bugs)
141 * Revision 1.14 1996/08/12 16:26:47 hipp
142 * code cleanup
143 * changed connection management from minors to slots
145 * Revision 1.13 1996/07/01 19:47:24 hipp
146 * Fixed memory leak in VJ handling and more VJ changes
148 * Revision 1.12 1996/06/24 17:42:03 fritz
149 * Minor bugfixes.
151 * Revision 1.11 1996/06/16 17:46:05 tsbogend
152 * changed unsigned long to u32 to make Alpha people happy
154 * Revision 1.10 1996/06/11 14:50:29 hipp
155 * Lot of changes and bugfixes.
156 * New scheme to resend packets to busy LL devices.
158 * Revision 1.9 1996/05/18 01:37:01 fritz
159 * Added spelling corrections and some minor changes
160 * to stay in sync with kernel.
162 * Revision 1.8 1996/05/06 11:34:55 hipp
163 * fixed a few bugs
165 * Revision 1.7 1996/04/30 11:07:42 fritz
166 * Added Michael's ippp-bind patch.
168 * Revision 1.6 1996/04/30 09:33:09 fritz
169 * Removed compatibility-macros.
171 * Revision 1.5 1996/04/20 16:32:32 fritz
172 * Changed ippp_table to an array of pointers, allocating each part
173 * separately.
175 * Revision 1.4 1996/02/19 15:25:50 fritz
176 * Bugfix: Sync-PPP packets got compressed twice, when resent due to
177 * send-queue-full reject.
179 * Revision 1.3 1996/02/11 02:27:12 fritz
180 * Lot of Bugfixes my Michael.
181 * Moved calls to skb_push() into isdn_net_header()
182 * Fixed a possible race-condition in isdn_ppp_timer_timeout().
184 * Revision 1.2 1996/01/22 05:08:06 fritz
185 * Merged in Michael's patches for MP.
186 * Minor changes in isdn_ppp_xmit.
188 * Revision 1.1 1996/01/09 04:11:29 fritz
189 * Initial revision
193 /* TODO: right tbusy handling when using MP */
196 * experimental for dynamic addressing: readdress IP frames
198 #undef ISDN_SYNCPPP_READDRESS
199 #define CONFIG_ISDN_CCP 1
201 #include <linux/config.h>
202 #define __NO_VERSION__
203 #include <linux/module.h>
204 #include <linux/version.h>
205 #include <linux/poll.h>
206 #include <linux/isdn.h>
207 #include <linux/ppp-comp.h>
209 #include "isdn_common.h"
210 #include "isdn_ppp.h"
211 #include "isdn_net.h"
213 #ifndef PPP_IPX
214 #define PPP_IPX 0x002b
215 #endif
217 /* set this if you use dynamic addressing */
219 /* Prototypes */
220 static int isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot);
221 static int isdn_ppp_closewait(int slot);
222 static void isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp,
223 struct sk_buff *skb, int proto);
224 static int isdn_ppp_if_get_unit(char *namebuf);
225 static int isdn_ppp_set_compressor(struct ippp_struct *is,struct isdn_ppp_comp_data *);
226 static struct sk_buff *isdn_ppp_decompress(struct sk_buff *,
227 struct ippp_struct *,struct ippp_struct *,int proto);
228 static void isdn_ppp_receive_ccp(isdn_net_dev * net_dev, isdn_net_local * lp,
229 struct sk_buff *skb,int proto);
230 static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in,int *proto,
231 struct ippp_struct *is,struct ippp_struct *master,int type);
232 static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
233 struct sk_buff *skb);
235 /* New CCP stuff */
236 static void isdn_ppp_ccp_kickup(struct ippp_struct *is);
237 static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
238 unsigned char code, unsigned char id,
239 unsigned char *data, int len);
240 static struct ippp_ccp_reset *isdn_ppp_ccp_reset_alloc(struct ippp_struct *is);
241 static void isdn_ppp_ccp_reset_free_state(struct ippp_struct *is,
242 unsigned char id);
243 static void isdn_ppp_ccp_timer_callback(unsigned long closure);
244 static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_struct *is,
245 unsigned char id);
246 static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
247 struct isdn_ppp_resetparams *rp);
248 static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
249 unsigned char id);
253 #ifdef CONFIG_ISDN_MPP
254 static int isdn_ppp_bundle(struct ippp_struct *, int unit);
255 static void isdn_ppp_mask_queue(isdn_net_dev * dev, long mask);
256 static void isdn_ppp_cleanup_mpqueue(isdn_net_dev * dev, long min);
257 static void isdn_ppp_cleanup_sqqueue(isdn_net_dev * dev, isdn_net_local *, long min);
258 static void isdn_ppp_free_sqqueue(isdn_net_dev *);
259 static int isdn_ppp_fill_mpqueue(isdn_net_dev *, struct sk_buff **skb,
260 int BEbyte, long *sqno, int min_sqno);
261 static void isdn_ppp_free_mpqueue(isdn_net_dev *);
262 #endif
264 char *isdn_ppp_revision = "$Revision: 1.47 $";
266 static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
267 static struct isdn_ppp_compressor *ipc_head = NULL;
270 * frame log (debug)
272 static void
273 isdn_ppp_frame_log(char *info, char *data, int len, int maxlen,int unit,int slot)
275 int cnt,
278 char buf[80];
280 if (len < maxlen)
281 maxlen = len;
283 for (i = 0, cnt = 0; cnt < maxlen; i++) {
284 for (j = 0; j < 16 && cnt < maxlen; j++, cnt++)
285 sprintf(buf + j * 3, "%02x ", (unsigned char) data[cnt]);
286 printk(KERN_DEBUG "[%d/%d].%s[%d]: %s\n",unit,slot, info, i, buf);
291 * unbind isdn_net_local <=> ippp-device
292 * note: it can happen, that we hangup/free the master before the slaves
293 * in this case we bind another lp to the master device
296 isdn_ppp_free(isdn_net_local * lp)
298 #ifdef CONFIG_ISDN_MPP
299 isdn_net_local *master_lp = lp;
300 #endif
301 unsigned long flags;
302 struct ippp_struct *is;
304 if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS)
305 return 0;
307 is = ippp_table[lp->ppp_slot];
309 save_flags(flags);
310 cli();
311 #ifdef CONFIG_ISDN_MPP
312 if (lp->master)
313 master_lp = (isdn_net_local *) lp->master->priv;
315 lp->last->next = lp->next;
316 lp->next->last = lp->last;
317 if (master_lp->netdev->queue == lp) {
318 master_lp->netdev->queue = lp->next;
319 if (lp->next == lp) { /* last link in queue? */
320 master_lp->netdev->ib.bundled = 0;
321 isdn_ppp_free_mpqueue(master_lp->netdev);
322 isdn_ppp_free_sqqueue(master_lp->netdev);
325 lp->next = lp->last = lp; /* (re)set own pointers */
326 #endif
328 if ((is->state & IPPP_CONNECT))
329 isdn_ppp_closewait(lp->ppp_slot); /* force wakeup on ippp device */
330 else if (is->state & IPPP_ASSIGNED)
331 is->state = IPPP_OPEN; /* fallback to 'OPEN but not ASSIGNED' state */
333 if (is->debug & 0x1)
334 printk(KERN_DEBUG "isdn_ppp_free %d %lx %lx\n", lp->ppp_slot, (long) lp, (long) is->lp);
336 is->lp = NULL; /* link is down .. set lp to NULL */
337 #ifdef ISDN_SYNCPPP_READDRESS
338 is->old_pa_addr = 0x0;
339 is->old_pa_dstaddr = 0x0;
340 #endif
341 lp->ppp_slot = -1; /* is this OK ?? */
342 restore_flags(flags);
344 return 0;
348 * bind isdn_net_local <=> ippp-device
351 isdn_ppp_bind(isdn_net_local * lp)
353 int i;
354 int unit = 0;
355 long flags;
356 struct ippp_struct *is;
358 if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
359 return -1;
361 save_flags(flags);
362 cli();
364 if (lp->pppbind < 0) { /* device bounded to ippp device ? */
365 isdn_net_dev *net_dev = dev->netdev;
366 char exclusive[ISDN_MAX_CHANNELS]; /* exclusive flags */
367 memset(exclusive, 0, ISDN_MAX_CHANNELS);
368 while (net_dev) { /* step through net devices to find exclusive minors */
369 isdn_net_local *lp = net_dev->local;
370 if (lp->pppbind >= 0)
371 exclusive[lp->pppbind] = 1;
372 net_dev = net_dev->next;
375 * search a free device / slot
377 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
378 if (ippp_table[i]->state == IPPP_OPEN && !exclusive[ippp_table[i]->minor]) { /* OPEN, but not connected! */
379 break;
382 } else {
383 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
384 if (ippp_table[i]->minor == lp->pppbind &&
385 (ippp_table[i]->state & IPPP_OPEN) == IPPP_OPEN)
386 break;
390 if (i >= ISDN_MAX_CHANNELS) {
391 restore_flags(flags);
392 printk(KERN_WARNING "isdn_ppp_bind: Can't find a (free) connection to the ipppd daemon.\n");
393 return -1;
395 unit = isdn_ppp_if_get_unit(lp->name); /* get unit number from interface name .. ugly! */
396 if (unit < 0) {
397 printk(KERN_ERR "isdn_ppp_bind: illegal interface name %s.\n", lp->name);
398 return -1;
400 lp->ppp_slot = i;
402 /* reset some values */
403 lp->netdev->ib.bundled = 0;
404 lp->netdev->ib.next_num = 0;
405 lp->netdev->ib.modify = 0;
406 lp->netdev->ib.last = NULL;
407 lp->netdev->ib.min = 0;
408 lp->netdev->ib.sq = NULL;
410 is = ippp_table[i];
411 is->lp = lp;
412 is->unit = unit;
413 is->state = IPPP_OPEN | IPPP_ASSIGNED; /* assigned to a netdevice but not connected */
415 restore_flags(flags);
417 return lp->ppp_slot;
421 * kick the ipppd on the device
422 * (wakes up daemon after B-channel connect)
425 void
426 isdn_ppp_wakeup_daemon(isdn_net_local * lp)
428 if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS)
429 return;
431 ippp_table[lp->ppp_slot]->state = IPPP_OPEN | IPPP_CONNECT | IPPP_NOBLOCK;
433 #if LINUX_VERSION_CODE < 131841
434 if (ippp_table[lp->ppp_slot]->wq)
435 #endif
436 wake_up_interruptible(&ippp_table[lp->ppp_slot]->wq);
440 * there was a hangup on the netdevice
441 * force wakeup of the ippp device
442 * go into 'device waits for release' state
444 static int
445 isdn_ppp_closewait(int slot)
447 struct ippp_struct *is;
449 if (slot < 0 || slot >= ISDN_MAX_CHANNELS)
450 return 0;
451 is = ippp_table[slot];
453 #if LINUX_VERSION_CODE < 131841
454 if (is->state && is->wq)
455 #else
456 if (is->state)
457 #endif
458 wake_up_interruptible(&is->wq);
460 is->state = IPPP_CLOSEWAIT;
461 return 1;
465 * isdn_ppp_find_slot / isdn_ppp_free_slot
468 static int
469 isdn_ppp_get_slot(void)
471 int i;
472 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
473 if (!ippp_table[i]->state)
474 return i;
476 return -1;
480 * isdn_ppp_open
484 isdn_ppp_open(int min, struct file *file)
486 int slot;
487 struct ippp_struct *is;
489 if (min < 0 || min > ISDN_MAX_CHANNELS)
490 return -ENODEV;
492 slot = isdn_ppp_get_slot();
493 if (slot < 0) {
494 return -EBUSY;
496 is = file->private_data = ippp_table[slot];
498 #if 0
499 if (is->debug & 0x1)
500 #endif
501 printk(KERN_DEBUG "ippp, open, slot: %d, minor: %d, state: %04x\n", slot, min, is->state);
503 /* compression stuff */
504 is->link_compressor = is->compressor = NULL;
505 is->link_decompressor = is->decompressor = NULL;
506 is->link_comp_stat = is->comp_stat = NULL;
507 is->link_decomp_stat = is->decomp_stat = NULL;
508 is->compflags = 0;
510 is->reset = isdn_ppp_ccp_reset_alloc(is);
512 is->lp = NULL;
513 is->mp_seqno = 0; /* MP sequence number */
514 is->pppcfg = 0; /* ppp configuration */
515 is->mpppcfg = 0; /* mppp configuration */
516 is->range = 0x1000000; /* MP: 24 bit range */
517 is->last_link_seqno = -1; /* MP: maybe set to Bundle-MIN, when joining a bundle ?? */
518 is->unit = -1; /* set, when we have our interface */
519 is->mru = 1524; /* MRU, default 1524 */
520 is->maxcid = 16; /* VJ: maxcid */
521 is->tk = current;
522 #if LINUX_VERSION_CODE < 131841
523 is->wq = NULL; /* read() wait queue */
524 #else
525 init_waitqueue_head(&is->wq);
526 #endif
527 is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
528 is->last = is->rq;
529 is->minor = min;
530 #ifdef CONFIG_ISDN_PPP_VJ
532 * VJ header compression init
534 is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */
535 #endif
537 is->state = IPPP_OPEN;
539 return 0;
543 * release ippp device
545 void
546 isdn_ppp_release(int min, struct file *file)
548 int i;
549 struct ippp_struct *is;
551 if (min < 0 || min >= ISDN_MAX_CHANNELS)
552 return;
553 is = file->private_data;
555 if (is->debug & 0x1)
556 printk(KERN_DEBUG "ippp: release, minor: %d %lx\n", min, (long) is->lp);
558 if (is->lp) { /* a lp address says: this link is still up */
559 isdn_net_dev *p = is->lp->netdev;
561 is->state &= ~IPPP_CONNECT; /* -> effect: no call of wakeup */
563 * isdn_net_hangup() calls isdn_ppp_free()
564 * isdn_ppp_free() sets is->lp to NULL and lp->ppp_slot to -1
565 * removing the IPPP_CONNECT flag omits calling of isdn_ppp_wakeup_daemon()
567 isdn_net_hangup(&p->dev);
569 for (i = 0; i < NUM_RCV_BUFFS; i++) {
570 if (is->rq[i].buf) {
571 kfree(is->rq[i].buf);
572 is->rq[i].buf = NULL;
575 is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
576 is->last = is->rq;
578 #ifdef CONFIG_ISDN_PPP_VJ
579 /* TODO: if this was the previous master: link the slcomp to the new master */
580 slhc_free(is->slcomp);
581 is->slcomp = NULL;
582 #endif
584 /* TODO: if this was the previous master: link the the stuff to the new master */
585 if(is->comp_stat)
586 is->compressor->free(is->comp_stat);
587 if(is->link_comp_stat)
588 is->link_compressor->free(is->link_comp_stat);
589 if(is->link_decomp_stat)
590 is->link_decompressor->free(is->link_decomp_stat);
591 if(is->decomp_stat)
592 is->decompressor->free(is->decomp_stat);
593 is->compressor = is->link_compressor = NULL;
594 is->decompressor = is->link_decompressor = NULL;
595 is->comp_stat = is->link_comp_stat = NULL;
596 is->decomp_stat = is->link_decomp_stat = NULL;
598 if(is->reset)
599 kfree(is->reset);
600 is->reset = NULL;
602 /* this slot is ready for new connections */
603 is->state = 0;
607 * get_arg .. ioctl helper
609 static int
610 get_arg(void *b, void *val, int len)
612 if (len <= 0)
613 len = sizeof(void *);
614 if (copy_from_user((void *) val, b, len))
615 return -EFAULT;
616 return 0;
620 * set arg .. ioctl helper
622 static int
623 set_arg(void *b, void *val,int len)
625 if(len <= 0)
626 len = sizeof(void *);
627 if (copy_to_user(b, (void *) val, len))
628 return -EFAULT;
629 return 0;
633 * ippp device ioctl
636 isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
638 unsigned long val;
639 int r,i,j;
640 struct ippp_struct *is;
641 isdn_net_local *lp;
642 struct isdn_ppp_comp_data data;
644 is = (struct ippp_struct *) file->private_data;
645 lp = is->lp;
647 if (is->debug & 0x1)
648 printk(KERN_DEBUG "isdn_ppp_ioctl: minor: %d cmd: %x state: %x\n", min, cmd, is->state);
650 if (!(is->state & IPPP_OPEN))
651 return -EINVAL;
653 switch (cmd) {
654 case PPPIOCBUNDLE:
655 #ifdef CONFIG_ISDN_MPP
656 if (!(is->state & IPPP_CONNECT))
657 return -EINVAL;
658 if ((r = get_arg((void *) arg, &val, sizeof(val) )))
659 return r;
660 printk(KERN_DEBUG "iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n",
661 (int) min, (int) is->unit, (int) val);
662 return isdn_ppp_bundle(is, val);
663 #else
664 return -1;
665 #endif
666 break;
667 case PPPIOCGUNIT: /* get ppp/isdn unit number */
668 if ((r = set_arg((void *) arg, &is->unit, sizeof(is->unit) )))
669 return r;
670 break;
671 case PPPIOCGIFNAME:
672 if(!lp)
673 return -EINVAL;
674 if ((r = set_arg((void *) arg, lp->name,strlen(lp->name))))
675 return r;
676 break;
677 case PPPIOCGMPFLAGS: /* get configuration flags */
678 if ((r = set_arg((void *) arg, &is->mpppcfg, sizeof(is->mpppcfg) )))
679 return r;
680 break;
681 case PPPIOCSMPFLAGS: /* set configuration flags */
682 if ((r = get_arg((void *) arg, &val, sizeof(val) )))
683 return r;
684 is->mpppcfg = val;
685 break;
686 case PPPIOCGFLAGS: /* get configuration flags */
687 if ((r = set_arg((void *) arg, &is->pppcfg,sizeof(is->pppcfg) )))
688 return r;
689 break;
690 case PPPIOCSFLAGS: /* set configuration flags */
691 if ((r = get_arg((void *) arg, &val, sizeof(val) ))) {
692 return r;
694 if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) {
695 if (lp) {
696 lp->netdev->dev.tbusy = 0;
697 mark_bh(NET_BH); /* OK .. we are ready to send buffers */
700 is->pppcfg = val;
701 break;
702 #if 0
703 case PPPIOCGSTAT: /* read PPP statistic information */
704 break;
705 #endif
706 case PPPIOCGIDLE: /* get idle time information */
707 if (lp) {
708 struct ppp_idle pidle;
709 pidle.xmit_idle = pidle.recv_idle = lp->huptimer;
710 if ((r = set_arg((void *) arg, &pidle,sizeof(struct ppp_idle))))
711 return r;
713 break;
714 case PPPIOCSMRU: /* set receive unit size for PPP */
715 if ((r = get_arg((void *) arg, &val, sizeof(val) )))
716 return r;
717 is->mru = val;
718 break;
719 case PPPIOCSMPMRU:
720 break;
721 case PPPIOCSMPMTU:
722 break;
723 case PPPIOCSMAXCID: /* set the maximum compression slot id */
724 if ((r = get_arg((void *) arg, &val, sizeof(val) )))
725 return r;
726 val++;
727 if (is->maxcid != val) {
728 #ifdef CONFIG_ISDN_PPP_VJ
729 struct slcompress *sltmp;
730 #endif
731 if (is->debug & 0x1)
732 printk(KERN_DEBUG "ippp, ioctl: changed MAXCID to %ld\n", val);
733 is->maxcid = val;
734 #ifdef CONFIG_ISDN_PPP_VJ
735 sltmp = slhc_init(16, val);
736 if (!sltmp) {
737 printk(KERN_ERR "ippp, can't realloc slhc struct\n");
738 return -ENOMEM;
740 if (is->slcomp)
741 slhc_free(is->slcomp);
742 is->slcomp = sltmp;
743 #endif
745 break;
746 case PPPIOCGDEBUG:
747 if ((r = set_arg((void *) arg, &is->debug, sizeof(is->debug) )))
748 return r;
749 break;
750 case PPPIOCSDEBUG:
751 if ((r = get_arg((void *) arg, &val, sizeof(val) )))
752 return r;
753 is->debug = val;
754 break;
755 case PPPIOCGCOMPRESSORS:
757 unsigned long protos[8] = {0,};
758 struct isdn_ppp_compressor *ipc = ipc_head;
759 while(ipc) {
760 j = ipc->num / (sizeof(long)*8);
761 i = ipc->num % (sizeof(long)*8);
762 if(j < 8)
763 protos[j] |= (0x1<<i);
764 ipc = ipc->next;
766 if ((r = set_arg((void *) arg,protos,8*sizeof(long) )))
767 return r;
769 break;
770 case PPPIOCSCOMPRESSOR:
771 if ((r = get_arg((void *) arg, &data, sizeof(struct isdn_ppp_comp_data))))
772 return r;
773 return isdn_ppp_set_compressor(is, &data);
774 case PPPIOCGCALLINFO:
776 struct pppcallinfo pci;
777 memset((char *) &pci,0,sizeof(struct pppcallinfo));
778 if(lp)
780 strncpy(pci.local_num,lp->msn,63);
781 if(lp->dial) {
782 strncpy(pci.remote_num,lp->dial->num,63);
784 pci.charge_units = lp->charge;
785 if(lp->outgoing)
786 pci.calltype = CALLTYPE_OUTGOING;
787 else
788 pci.calltype = CALLTYPE_INCOMING;
789 if(lp->flags & ISDN_NET_CALLBACK)
790 pci.calltype |= CALLTYPE_CALLBACK;
792 return set_arg((void *)arg,&pci,sizeof(struct pppcallinfo));
794 default:
795 break;
797 return 0;
800 unsigned int
801 isdn_ppp_poll(struct file *file, poll_table * wait)
803 unsigned int mask;
804 struct ippp_buf_queue *bf;
805 struct ippp_buf_queue *bl;
806 unsigned long flags;
807 struct ippp_struct *is;
809 is = file->private_data;
811 if (is->debug & 0x2)
812 printk(KERN_DEBUG "isdn_ppp_poll: minor: %d\n",
813 MINOR(file->f_dentry->d_inode->i_rdev));
815 /* just registers wait_queue hook. This doesn't really wait. */
816 poll_wait(file, &is->wq, wait);
818 if (!(is->state & IPPP_OPEN)) {
819 if(is->state == IPPP_CLOSEWAIT)
820 return POLLHUP;
821 printk(KERN_DEBUG "isdn_ppp: device not open\n");
822 return POLLERR;
824 /* we're always ready to send .. */
825 mask = POLLOUT | POLLWRNORM;
827 save_flags(flags);
828 cli();
829 bl = is->last;
830 bf = is->first;
832 * if IPPP_NOBLOCK is set we return even if we have nothing to read
834 if (bf->next != bl || (is->state & IPPP_NOBLOCK)) {
835 is->state &= ~IPPP_NOBLOCK;
836 mask |= POLLIN | POLLRDNORM;
838 restore_flags(flags);
839 return mask;
843 * fill up isdn_ppp_read() queue ..
846 static int
847 isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot)
849 struct ippp_buf_queue *bf,
850 *bl;
851 unsigned long flags;
852 unsigned char *nbuf;
853 struct ippp_struct *is;
855 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
856 printk(KERN_WARNING "ippp: illegal slot.\n");
857 return 0;
859 is = ippp_table[slot];
861 if (!(is->state & IPPP_CONNECT)) {
862 printk(KERN_DEBUG "ippp: device not activated.\n");
863 return 0;
865 nbuf = (unsigned char *) kmalloc(len + 4, GFP_ATOMIC);
866 if (!nbuf) {
867 printk(KERN_WARNING "ippp: Can't alloc buf\n");
868 return 0;
870 nbuf[0] = PPP_ALLSTATIONS;
871 nbuf[1] = PPP_UI;
872 nbuf[2] = proto >> 8;
873 nbuf[3] = proto & 0xff;
874 memcpy(nbuf + 4, buf, len);
876 save_flags(flags);
877 cli();
879 bf = is->first;
880 bl = is->last;
882 if (bf == bl) {
883 printk(KERN_WARNING "ippp: Queue is full; discarding first buffer\n");
884 bf = bf->next;
885 kfree(bf->buf);
886 is->first = bf;
888 bl->buf = (char *) nbuf;
889 bl->len = len + 4;
891 is->last = bl->next;
892 restore_flags(flags);
894 #if LINUX_VERSION_CODE < 131841
895 if (is->wq)
896 #endif
897 wake_up_interruptible(&is->wq);
899 return len;
903 * read() .. non-blocking: ipppd calls it only after select()
904 * reports, that there is data
908 isdn_ppp_read(int min, struct file *file, char *buf, int count)
910 struct ippp_struct *is;
911 struct ippp_buf_queue *b;
912 int r;
913 unsigned long flags;
914 unsigned char *save_buf;
916 is = file->private_data;
918 if (!(is->state & IPPP_OPEN))
919 return 0;
921 if ((r = verify_area(VERIFY_WRITE, (void *) buf, count)))
922 return r;
924 save_flags(flags);
925 cli();
927 b = is->first->next;
928 save_buf = b->buf;
929 if (!save_buf) {
930 restore_flags(flags);
931 return -EAGAIN;
933 if (b->len < count)
934 count = b->len;
935 b->buf = NULL;
936 is->first = b;
938 restore_flags(flags);
940 copy_to_user(buf, save_buf, count);
941 kfree(save_buf);
943 return count;
947 * ipppd wanna write a packet to the card .. non-blocking
951 isdn_ppp_write(int min, struct file *file, const char *buf, int count)
953 isdn_net_local *lp;
954 struct ippp_struct *is;
955 int proto;
956 unsigned char protobuf[4];
958 is = file->private_data;
960 if (!(is->state & IPPP_CONNECT))
961 return 0;
963 lp = is->lp;
965 /* -> push it directly to the lowlevel interface */
967 if (!lp)
968 printk(KERN_DEBUG "isdn_ppp_write: lp == NULL\n");
969 else {
971 * Don't reset huptimer for
972 * LCP packets. (Echo requests).
974 if (copy_from_user(protobuf, buf, 4))
975 return -EFAULT;
976 proto = PPP_PROTOCOL(protobuf);
977 if (proto != PPP_LCP)
978 lp->huptimer = 0;
980 if (lp->isdn_device < 0 || lp->isdn_channel < 0)
981 return 0;
983 if ((dev->drv[lp->isdn_device]->flags & DRV_FLAG_RUNNING) &&
984 lp->dialstate == 0 &&
985 (lp->flags & ISDN_NET_CONNECTED)) {
986 int cnt;
987 struct sk_buff *skb;
988 skb = dev_alloc_skb(count);
989 if (!skb) {
990 printk(KERN_WARNING "isdn_ppp_write: out of memory!\n");
991 return count;
993 if (copy_from_user(skb_put(skb, count), buf, count))
994 return -EFAULT;
995 if (is->debug & 0x40) {
996 printk(KERN_DEBUG "ppp xmit: len %d\n", (int) skb->len);
997 isdn_ppp_frame_log("xmit", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
1000 isdn_ppp_send_ccp(lp->netdev,lp,skb); /* keeps CCP/compression states in sync */
1002 if ((cnt = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb)) != count) {
1003 if (lp->sav_skb) {
1004 dev_kfree_skb(lp->sav_skb);
1005 printk(KERN_INFO "isdn_ppp_write: freeing sav_skb (%d,%d)!\n", cnt, count);
1006 } else
1007 printk(KERN_INFO "isdn_ppp_write: Can't write PPP frame to LL (%d,%d)!\n", cnt, count);
1008 lp->sav_skb = skb;
1012 return count;
1016 * init memory, structures etc.
1020 isdn_ppp_init(void)
1022 int i,
1025 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
1026 if (!(ippp_table[i] = (struct ippp_struct *)
1027 kmalloc(sizeof(struct ippp_struct), GFP_KERNEL))) {
1028 printk(KERN_WARNING "isdn_ppp_init: Could not alloc ippp_table\n");
1029 for (j = 0; j < i; j++)
1030 kfree(ippp_table[i]);
1031 return -1;
1033 memset((char *) ippp_table[i], 0, sizeof(struct ippp_struct));
1034 ippp_table[i]->state = 0;
1035 ippp_table[i]->first = ippp_table[i]->rq + NUM_RCV_BUFFS - 1;
1036 ippp_table[i]->last = ippp_table[i]->rq;
1038 for (j = 0; j < NUM_RCV_BUFFS; j++) {
1039 ippp_table[i]->rq[j].buf = NULL;
1040 ippp_table[i]->rq[j].last = ippp_table[i]->rq +
1041 (NUM_RCV_BUFFS + j - 1) % NUM_RCV_BUFFS;
1042 ippp_table[i]->rq[j].next = ippp_table[i]->rq + (j + 1) % NUM_RCV_BUFFS;
1045 return 0;
1048 void
1049 isdn_ppp_cleanup(void)
1051 int i;
1053 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
1054 kfree(ippp_table[i]);
1058 * get the PPP protocol header and pull skb
1060 static int isdn_ppp_strip_proto(struct sk_buff *skb)
1062 int proto;
1063 if (skb->data[0] & 0x1) {
1064 proto = skb->data[0];
1065 skb_pull(skb, 1); /* protocol ID is only 8 bit */
1066 } else {
1067 proto = ((int) skb->data[0] << 8) + skb->data[1];
1068 skb_pull(skb, 2);
1070 return proto;
1075 * handler for incoming packets on a syncPPP interface
1077 void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb)
1079 struct ippp_struct *is;
1080 int proto;
1082 is = ippp_table[lp->ppp_slot];
1084 if (is->debug & 0x4) {
1085 printk(KERN_DEBUG "ippp_receive: is:%08lx lp:%08lx slot:%d unit:%d len:%d\n",
1086 (long)is,(long)lp,lp->ppp_slot,is->unit,(int) skb->len);
1087 isdn_ppp_frame_log("receive", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
1089 if (net_dev->local->master) {
1090 printk(KERN_WARNING "isdn_ppp_receice: net_dev != master\n");
1091 net_dev = ((isdn_net_local *) net_dev->local->master->priv)->netdev;
1093 if (skb->data[0] == 0xff && skb->data[1] == 0x03)
1094 skb_pull(skb, 2);
1095 else if (is->pppcfg & SC_REJ_COMP_AC) {
1096 dev_kfree_skb(skb);
1097 return; /* discard it silently */
1100 proto = isdn_ppp_strip_proto(skb);
1102 #ifdef CONFIG_ISDN_MPP
1103 if (!(is->mpppcfg & SC_REJ_MP_PROT)) {
1104 int sqno_end;
1106 if(is->compflags & SC_LINK_DECOMP_ON) {
1107 if(proto == PPP_LINK_COMP) {
1108 if(is->debug & 0x10)
1109 printk(KERN_DEBUG "received single link compressed frame\n");
1110 skb = isdn_ppp_decompress(skb,is,NULL,proto);
1111 if(!skb)
1112 return;
1113 proto = isdn_ppp_strip_proto(skb);
1115 else
1116 isdn_ppp_decompress(skb,is,NULL,proto);
1119 if (proto == PPP_MP) {
1120 isdn_net_local *lpq;
1121 long sqno, min_sqno, tseq;
1123 u_char BEbyte = skb->data[0];
1124 if (is->debug & 0x8)
1125 printk(KERN_DEBUG "recv: %d/%04x/%d -> %02x %02x %02x %02x %02x %02x\n", lp->ppp_slot, proto,
1126 (int) skb->len, (int) skb->data[0], (int) skb->data[1], (int) skb->data[2],
1127 (int) skb->data[3], (int) skb->data[4], (int) skb->data[5]);
1128 if (!(is->mpppcfg & SC_IN_SHORT_SEQ)) {
1129 sqno = ((int) skb->data[1] << 16) + ((int) skb->data[2] << 8) + (int) skb->data[3];
1130 skb_pull(skb, 4);
1131 } else {
1132 sqno = (((int) skb->data[0] & 0xf) << 8) + (int) skb->data[1];
1133 skb_pull(skb, 2);
1137 * new sequence number lower than last number? (this is only allowed
1138 * for overflow case)
1140 if ((tseq = is->last_link_seqno) >= sqno) {
1141 int range = is->range;
1142 if (tseq + 1024 < range + sqno) /* redundancy check .. not MP conform */
1143 printk(KERN_WARNING "isdn_ppp_receive, MP, detected overflow with sqno: %ld, last: %ld !!!\n", sqno, tseq);
1144 else {
1145 sqno += range;
1146 is->last_link_seqno = sqno;
1148 } else {
1149 /* here, we should also add an redundancy check */
1150 is->last_link_seqno = sqno;
1154 * step over all links to find lowest link number
1156 for (min_sqno = LONG_MAX, lpq = net_dev->queue;;) {
1157 long lls = ippp_table[lpq->ppp_slot]->last_link_seqno;
1158 if (lls >= 0 && lls < min_sqno)
1159 min_sqno = lls;
1160 lpq = lpq->next;
1161 if (lpq == net_dev->queue)
1162 break;
1166 * for the case, that the last frame numbers of all
1167 * links are overflowed: mask/reduce the sequenece number to
1168 * 'normal' numbering.
1170 if (min_sqno >= ippp_table[lpq->ppp_slot]->range) {
1171 int mask = ippp_table[lpq->ppp_slot]->range-1; /* range is power of two, so a mask will do the job */
1172 isdn_ppp_mask_queue(net_dev, mask);
1173 net_dev->ib.next_num &= mask;
1175 struct sqqueue *q = net_dev->ib.sq;
1176 while (q) {
1177 q->sqno_start &= mask;
1178 q->sqno_end &= mask;
1181 min_sqno &= mask;
1182 for (lpq = net_dev->queue;;) {
1183 if(ippp_table[lpq->ppp_slot]->last_link_seqno >= 0)
1184 ippp_table[lpq->ppp_slot]->last_link_seqno &= mask;
1185 lpq = lpq->next;
1186 if (lpq == net_dev->queue)
1187 break;
1190 if ((BEbyte & (MP_BEGIN_FRAG | MP_END_FRAG)) != (MP_BEGIN_FRAG | MP_END_FRAG)) {
1191 static int dmes = 0;
1192 if( !dmes ) {
1193 printk(KERN_DEBUG "ippp: trying ;) to fill mp_queue %d .. UNTESTED!!\n", lp->ppp_slot);
1194 dmes = 1;
1196 if ((sqno_end = isdn_ppp_fill_mpqueue(net_dev, &skb, BEbyte, &sqno, min_sqno)) < 0) {
1197 net_dev->ib.modify = 1; /* block timeout-timer */
1198 isdn_ppp_cleanup_sqqueue(net_dev, lp, min_sqno);
1199 net_dev->ib.modify = 0;
1200 return; /* no packet complete */
1202 } else
1203 sqno_end = sqno;
1205 if (is->debug & 0x40)
1206 printk(KERN_DEBUG "min_sqno: %ld sqno_end %d next: %ld\n", min_sqno, sqno_end, net_dev->ib.next_num);
1209 * MP buffer management .. reorders incoming packets ..
1210 * lotsa mem-copies and not heavily tested.
1212 * first check whether there is more than one link in the bundle
1213 * then check whether the number is in order
1215 net_dev->ib.modify = 1; /* block timeout-timer */
1216 if (net_dev->ib.bundled && net_dev->ib.next_num != sqno) {
1218 * packet is not 'in order'
1220 struct sqqueue *q;
1222 q = (struct sqqueue *) kmalloc(sizeof(struct sqqueue), GFP_ATOMIC);
1223 if (!q) {
1224 net_dev->ib.modify = 0;
1225 printk(KERN_WARNING "ippp/MPPP: Bad! Can't alloc sq node!\n");
1226 dev_kfree_skb(skb);
1227 return; /* discard */
1229 q->skb = skb;
1230 q->sqno_end = sqno_end;
1231 q->sqno_start = sqno;
1232 q->timer = jiffies + (ISDN_TIMER_1SEC) * 5; /* timeout after 5 seconds */
1234 if (!net_dev->ib.sq) {
1235 net_dev->ib.sq = q;
1236 q->next = NULL;
1237 } else {
1238 struct sqqueue *ql = net_dev->ib.sq;
1239 if (ql->sqno_start > q->sqno_start) {
1240 q->next = ql;
1241 net_dev->ib.sq = q;
1242 } else {
1243 while (ql->next && ql->next->sqno_start < q->sqno_start)
1244 ql = ql->next;
1245 q->next = ql->next;
1246 ql->next = q;
1249 } else {
1251 * packet was 'in order' .. push it higher
1253 net_dev->ib.next_num = sqno_end + 1;
1254 proto = isdn_ppp_strip_proto(skb);
1255 isdn_ppp_push_higher(net_dev, lp, skb, proto);
1257 isdn_ppp_cleanup_sqqueue(net_dev, lp, min_sqno);
1258 net_dev->ib.modify = 0;
1260 } else
1261 isdn_ppp_push_higher(net_dev, lp, skb, proto);
1262 } else
1263 #endif
1264 isdn_ppp_push_higher(net_dev, lp, skb, proto);
1268 * push frame to higher layers
1269 * note: net_dev has to be master net_dev
1271 static void
1272 isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb, int proto)
1274 struct device *dev = &net_dev->dev;
1275 struct ippp_struct *is = ippp_table[lp->ppp_slot];
1277 if (is->debug & 0x10) {
1278 printk(KERN_DEBUG "push, skb %d %04x\n", (int) skb->len, proto);
1279 isdn_ppp_frame_log("rpush", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
1282 if(proto == PPP_COMP) {
1283 if(!lp->master)
1284 skb = isdn_ppp_decompress(skb,is,is,proto);
1285 else
1286 skb = isdn_ppp_decompress(skb,is,ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot],proto);
1288 if(!skb) {
1289 printk(KERN_DEBUG "ippp: compressed frame discarded!\n");
1290 return;
1293 proto = isdn_ppp_strip_proto(skb);
1294 if (is->debug & 0x10) {
1295 printk(KERN_DEBUG "RPostDecomp, skb %d %04x\n", (int) skb->len, proto);
1296 isdn_ppp_frame_log("R-Decomp", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
1299 else if(is->compflags & SC_DECOMP_ON) { /* If decomp is ON */
1300 if(!lp->master)
1301 isdn_ppp_decompress(skb,is,is,proto);
1302 else
1303 isdn_ppp_decompress(skb,is,ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot],proto);
1306 switch (proto) {
1307 case PPP_IPX: /* untested */
1308 if (is->debug & 0x20)
1309 printk(KERN_DEBUG "isdn_ppp: IPX\n");
1310 skb->dev = dev;
1311 skb->mac.raw = skb->data;
1312 skb->protocol = htons(ETH_P_IPX);
1313 break;
1314 #ifdef CONFIG_ISDN_PPP_VJ
1315 case PPP_VJC_UNCOMP:
1316 if (is->debug & 0x20)
1317 printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n");
1318 if (slhc_remember(ippp_table[net_dev->local->ppp_slot]->slcomp, skb->data, skb->len) <= 0) {
1319 printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n");
1320 net_dev->local->stats.rx_dropped++;
1321 dev_kfree_skb(skb);
1322 return;
1324 #endif
1325 case PPP_IP:
1326 if (is->debug & 0x20)
1327 printk(KERN_DEBUG "isdn_ppp: IP\n");
1328 skb->dev = dev;
1329 skb->mac.raw = skb->data;
1330 skb->protocol = htons(ETH_P_IP);
1331 break;
1332 case PPP_VJC_COMP:
1333 if (is->debug & 0x20)
1334 printk(KERN_DEBUG "isdn_ppp: VJC_COMP\n");
1335 #ifdef CONFIG_ISDN_PPP_VJ
1337 struct sk_buff *skb_old = skb;
1338 int pkt_len;
1339 skb = dev_alloc_skb(skb_old->len + 40);
1341 if (!skb) {
1342 printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
1343 net_dev->local->stats.rx_dropped++;
1344 dev_kfree_skb(skb_old);
1345 return;
1347 skb->dev = dev;
1348 skb_put(skb, skb_old->len + 40);
1349 memcpy(skb->data, skb_old->data, skb_old->len);
1350 skb->mac.raw = skb->data;
1351 pkt_len = slhc_uncompress(ippp_table[net_dev->local->ppp_slot]->slcomp,
1352 skb->data, skb_old->len);
1353 dev_kfree_skb(skb_old);
1354 if (pkt_len < 0) {
1355 dev_kfree_skb(skb);
1356 lp->stats.rx_dropped++;
1357 return;
1359 skb_trim(skb, pkt_len);
1360 skb->protocol = htons(ETH_P_IP);
1362 #else
1363 printk(KERN_INFO "isdn: Ooopsa .. VJ-Compression support not compiled into isdn driver.\n");
1364 lp->stats.rx_dropped++;
1365 dev_kfree_skb(skb);
1366 return;
1367 #endif
1368 break;
1369 case PPP_CCP:
1370 case PPP_LINK_CCP:
1371 isdn_ppp_receive_ccp(net_dev,lp,skb,proto);
1372 /* Dont pop up ResetReq/Ack stuff to the daemon any
1373 longer - the job is done already */
1374 if(skb->data[0] == CCP_RESETREQ ||
1375 skb->data[0] == CCP_RESETACK)
1376 break;
1377 /* fall through */
1378 default:
1379 isdn_ppp_fill_rq(skb->data, skb->len, proto, lp->ppp_slot); /* push data to pppd device */
1380 dev_kfree_skb(skb);
1381 return;
1384 /* Reset hangup-timer */
1385 lp->huptimer = 0;
1386 netif_rx(skb);
1387 /* net_dev->local->stats.rx_packets++; *//* done in isdn_net.c */
1389 return;
1393 * isdn_ppp_skb_push ..
1394 * checks whether we have enough space at the beginning of the SKB
1395 * and allocs a new SKB if necessary
1397 static unsigned char *isdn_ppp_skb_push(struct sk_buff **skb_p,int len)
1399 struct sk_buff *skb = *skb_p;
1401 if(skb_headroom(skb) < len) {
1402 printk(KERN_ERR "isdn_ppp_skb_push:under %d %d\n",skb_headroom(skb),len);
1403 dev_kfree_skb(skb);
1404 return NULL;
1406 return skb_push(skb,len);
1411 * send ppp frame .. we expect a PIDCOMPressable proto --
1412 * (here: currently always PPP_IP,PPP_VJC_COMP,PPP_VJC_UNCOMP)
1414 * VJ compression may change skb pointer!!! .. requeue with old
1415 * skb isn't allowed!!
1419 isdn_ppp_xmit(struct sk_buff *skb, struct device *dev)
1421 struct device *mdev = ((isdn_net_local *) (dev->priv))->master; /* get master (for redundancy) */
1422 isdn_net_local *lp,*mlp;
1423 isdn_net_dev *nd;
1424 unsigned int proto = PPP_IP; /* 0x21 */
1425 struct ippp_struct *ipt,*ipts;
1427 if (mdev)
1428 mlp = (isdn_net_local *) (mdev->priv);
1429 else {
1430 mdev = dev;
1431 mlp = (isdn_net_local *) (dev->priv);
1433 nd = mlp->netdev; /* get master lp */
1434 ipts = ippp_table[mlp->ppp_slot];
1436 if (!(ipts->pppcfg & SC_ENABLE_IP)) { /* PPP connected ? */
1437 #ifdef ISDN_SYNCPPP_READDRESS
1438 if (!ipts->old_pa_addr)
1439 ipts->old_pa_addr = mdev->pa_addr;
1440 if (!ipts->old_pa_dstaddr)
1441 ipts->old_pa_dstaddr = mdev->pa_dstaddr;
1442 #endif
1443 if (ipts->debug & 0x1)
1444 printk(KERN_INFO "%s: IP frame delayed.\n", dev->name);
1445 return 1;
1448 switch (ntohs(skb->protocol)) {
1449 case ETH_P_IP:
1450 proto = PPP_IP;
1451 #ifdef ISDN_SYNCPPP_READDRESS
1452 if (ipts->old_pa_addr != mdev->pa_addr) {
1453 struct iphdr *ipfr;
1454 ipfr = (struct iphdr *) skb->data;
1455 if(ipts->debug & 0x4)
1456 printk(KERN_DEBUG "IF-address changed from %lx to %lx\n", ipts->old_pa_addr, mdev->pa_addr);
1457 if (ipfr->version == 4) {
1458 if (ipfr->saddr == ipts->old_pa_addr) {
1459 printk(KERN_DEBUG "readdressing %lx to %lx\n", ipfr->saddr, mdev->pa_addr);
1460 ipfr->saddr = mdev->pa_addr;
1464 /* dstaddr change not so important */
1465 #endif
1466 break;
1467 case ETH_P_IPX:
1468 proto = PPP_IPX; /* untested */
1469 break;
1470 default:
1471 dev_kfree_skb(skb);
1472 printk(KERN_ERR "isdn_ppp: skipped frame with unsupported protocoll: %#x.\n", skb->protocol);
1473 return 0;
1476 lp = nd->queue; /* get lp on top of queue */
1478 if (lp->sav_skb) { /* find a non-busy device */
1479 isdn_net_local *nlp = lp->next;
1480 while (lp->sav_skb) {
1481 if (lp == nlp)
1482 return 1;
1483 nlp = nd->queue = nd->queue->next;
1485 lp = nlp;
1487 ipt = ippp_table[lp->ppp_slot];
1488 lp->huptimer = 0;
1491 * after this line .. requeueing in the device queue is no longer allowed!!!
1494 /* Pull off the fake header we stuck on earlier to keep
1495 * the fragemntation code happy.
1496 * this will break the ISDN_SYNCPPP_READDRESS hack a few lines
1497 * above. So, enabling this is no longer allowed
1499 skb_pull(skb,IPPP_MAX_HEADER);
1501 if (ipt->debug & 0x4)
1502 printk(KERN_DEBUG "xmit skb, len %d\n", (int) skb->len);
1503 if (ipts->debug & 0x40)
1504 isdn_ppp_frame_log("xmit0", skb->data, skb->len, 32,ipts->unit,lp->ppp_slot);
1506 #ifdef CONFIG_ISDN_PPP_VJ
1507 if (proto == PPP_IP && ipts->pppcfg & SC_COMP_TCP) { /* ipts here? probably yes, but check this again */
1508 struct sk_buff *new_skb;
1510 new_skb = dev_alloc_skb(skb->len);
1511 if (new_skb) {
1512 u_char *buf;
1513 int pktlen;
1515 new_skb->dev = skb->dev;
1516 skb_put(new_skb, skb->len);
1517 buf = skb->data;
1519 pktlen = slhc_compress(ipts->slcomp, skb->data, skb->len, new_skb->data,
1520 &buf, !(ipts->pppcfg & SC_NO_TCP_CCID));
1522 if (buf != skb->data) {
1523 if (new_skb->data != buf)
1524 printk(KERN_ERR "isdn_ppp: FATAL error after slhc_compress!!\n");
1525 dev_kfree_skb(skb);
1526 skb = new_skb;
1527 } else {
1528 dev_kfree_skb(new_skb);
1531 skb_trim(skb, pktlen);
1532 if (skb->data[0] & SL_TYPE_COMPRESSED_TCP) { /* cslip? style -> PPP */
1533 proto = PPP_VJC_COMP;
1534 skb->data[0] ^= SL_TYPE_COMPRESSED_TCP;
1535 } else {
1536 if (skb->data[0] >= SL_TYPE_UNCOMPRESSED_TCP)
1537 proto = PPP_VJC_UNCOMP;
1538 skb->data[0] = (skb->data[0] & 0x0f) | 0x40;
1542 #endif
1545 * normal (single link) or bundle compression
1547 if(ipts->compflags & SC_COMP_ON)
1548 skb = isdn_ppp_compress(skb,&proto,ipt,ipts,0);
1550 if (ipt->debug & 0x24)
1551 printk(KERN_DEBUG "xmit2 skb, len %d, proto %04x\n", (int) skb->len, proto);
1553 #ifdef CONFIG_ISDN_MPP
1554 if (ipt->mpppcfg & SC_MP_PROT) {
1555 /* we get mp_seqno from static isdn_net_local */
1556 long mp_seqno = ipts->mp_seqno;
1557 ipts->mp_seqno++;
1558 nd->queue = nd->queue->next;
1559 if (ipt->mpppcfg & SC_OUT_SHORT_SEQ) {
1560 unsigned char *data = isdn_ppp_skb_push(&skb, 3);
1561 if(!data)
1562 return 0;
1563 mp_seqno &= 0xfff;
1564 data[0] = MP_BEGIN_FRAG | MP_END_FRAG | ((mp_seqno >> 8) & 0xf); /* (B)egin & (E)ndbit .. */
1565 data[1] = mp_seqno & 0xff;
1566 data[2] = proto; /* PID compression */
1567 } else {
1568 unsigned char *data = isdn_ppp_skb_push(&skb, 5);
1569 if(!data)
1570 return 0;
1571 data[0] = MP_BEGIN_FRAG | MP_END_FRAG; /* (B)egin & (E)ndbit .. */
1572 data[1] = (mp_seqno >> 16) & 0xff; /* sequence number: 24bit */
1573 data[2] = (mp_seqno >> 8) & 0xff;
1574 data[3] = (mp_seqno >> 0) & 0xff;
1575 data[4] = proto; /* PID compression */
1577 proto = PPP_MP; /* MP Protocol, 0x003d */
1579 #endif
1582 * 'link in bundle' compression ...
1584 if(ipt->compflags & SC_LINK_COMP_ON)
1585 skb = isdn_ppp_compress(skb,&proto,ipt,ipts,1);
1587 if( (ipt->pppcfg & SC_COMP_PROT) && (proto <= 0xff) ) {
1588 unsigned char *data = isdn_ppp_skb_push(&skb,1);
1589 if(!data)
1590 return 0;
1591 data[0] = proto & 0xff;
1593 else {
1594 unsigned char *data = isdn_ppp_skb_push(&skb,2);
1595 if(!data)
1596 return 0;
1597 data[0] = (proto >> 8) & 0xff;
1598 data[1] = proto & 0xff;
1600 if(!(ipt->pppcfg & SC_COMP_AC)) {
1601 unsigned char *data = isdn_ppp_skb_push(&skb,2);
1602 if(!data)
1603 return 0;
1604 data[0] = 0xff; /* All Stations */
1605 data[1] = 0x03; /* Unnumbered information */
1608 /* tx-stats are now updated via BSENT-callback */
1610 if (ipts->debug & 0x40) {
1611 printk(KERN_DEBUG "skb xmit: len: %d\n", (int) skb->len);
1612 isdn_ppp_frame_log("xmit", skb->data, skb->len, 32,ipt->unit,lp->ppp_slot);
1614 if (isdn_net_send_skb(dev, lp, skb)) {
1615 if (lp->sav_skb) { /* whole sav_skb processing with disabled IRQs ?? */
1616 printk(KERN_ERR "%s: whoops .. there is another stored skb!\n", dev->name);
1617 dev_kfree_skb(skb);
1618 } else
1619 lp->sav_skb = skb;
1621 return 0;
1624 #ifdef CONFIG_ISDN_MPP
1627 * free SQ queue
1628 * -------------
1629 * Note: We need two queues for MPPP. The SQ queue holds fully (re)assembled frames,
1630 * that can't be delivered, because there is an outstanding earlier frame
1632 static void
1633 isdn_ppp_free_sqqueue(isdn_net_dev * p)
1635 struct sqqueue *q = p->ib.sq;
1637 p->ib.sq = NULL;
1638 while (q) {
1639 struct sqqueue *qn = q->next;
1640 if (q->skb)
1641 dev_kfree_skb(q->skb);
1642 kfree(q);
1643 q = qn;
1649 * free MP queue
1650 * -------------
1651 * Note: The MP queue holds all frame fragments of frames, that can't be
1652 * reassembled, because there is at least one missing fragment.
1654 static void
1655 isdn_ppp_free_mpqueue(isdn_net_dev * p)
1657 struct mpqueue *q = p->mp_last;
1658 p->mp_last = NULL;
1660 while (q) {
1661 struct mpqueue *ql = q->next;
1662 dev_kfree_skb(q->skb);
1663 kfree(q);
1664 q = ql;
1668 static int
1669 isdn_ppp_bundle(struct ippp_struct *is, int unit)
1671 char ifn[IFNAMSIZ + 1];
1672 long flags;
1673 isdn_net_dev *p;
1674 isdn_net_local *lp,
1675 *nlp;
1677 sprintf(ifn, "ippp%d", unit);
1678 p = isdn_net_findif(ifn);
1679 if (!p)
1680 return -1;
1682 isdn_timer_ctrl(ISDN_TIMER_IPPP, 1); /* enable timer for ippp/MP */
1684 save_flags(flags);
1685 cli();
1687 nlp = is->lp;
1689 lp = p->queue;
1690 p->ib.bundled = 1;
1691 nlp->last = lp->last;
1692 lp->last->next = nlp;
1693 lp->last = nlp;
1694 nlp->next = lp;
1695 p->queue = nlp;
1697 ippp_table[nlp->ppp_slot]->unit = ippp_table[lp->ppp_slot]->unit;
1698 /* maybe also SC_CCP stuff */
1699 ippp_table[nlp->ppp_slot]->pppcfg |= ippp_table[lp->ppp_slot]->pppcfg &
1700 (SC_ENABLE_IP | SC_NO_TCP_CCID | SC_REJ_COMP_TCP);
1702 ippp_table[nlp->ppp_slot]->mpppcfg |= ippp_table[lp->ppp_slot]->mpppcfg &
1703 (SC_MP_PROT | SC_REJ_MP_PROT | SC_OUT_SHORT_SEQ | SC_IN_SHORT_SEQ);
1704 #if 0
1705 if (ippp_table[nlp->ppp_slot]->mpppcfg != ippp_table[lp->ppp_slot]->mpppcfg) {
1706 printk(KERN_WARNING "isdn_ppp_bundle: different MP options %04x and %04x\n",
1707 ippp_table[nlp->ppp_slot]->mpppcfg, ippp_table[lp->ppp_slot]->mpppcfg);
1709 #endif
1711 restore_flags(flags);
1712 return 0;
1716 * Mask sequence numbers in MP queue
1718 static void
1719 isdn_ppp_mask_queue(isdn_net_dev * dev, long mask)
1721 struct mpqueue *q = dev->mp_last;
1722 while (q) {
1723 q->sqno &= mask;
1724 q = q->next;
1729 * put a fragment at the right place into the MP queue
1730 * Also checks, whether this fragment completes a frame. In this case
1731 * the fragments are copied together into one SKB
1733 static int
1734 isdn_ppp_fill_mpqueue(isdn_net_dev * dev, struct sk_buff **skb, int BEbyte, long *sqnop, int min_sqno)
1736 struct mpqueue *qe,
1737 *q1,
1739 long cnt,
1740 flags;
1741 int pktlen,
1742 sqno_end;
1743 int sqno = *sqnop;
1745 q1 = (struct mpqueue *) kmalloc(sizeof(struct mpqueue), GFP_ATOMIC);
1746 if (!q1) {
1747 printk(KERN_WARNING "isdn_ppp_fill_mpqueue: Can't alloc struct memory.\n");
1748 save_flags(flags);
1749 cli();
1750 isdn_ppp_cleanup_mpqueue(dev, min_sqno);
1751 restore_flags(flags);
1752 return -1;
1754 q1->skb = *skb;
1755 q1->sqno = sqno;
1756 q1->BEbyte = BEbyte;
1757 q1->time = jiffies;
1759 save_flags(flags);
1760 cli();
1762 if (!(q = dev->mp_last)) {
1763 dev->mp_last = q1;
1764 q1->next = NULL;
1765 q1->last = NULL;
1766 isdn_ppp_cleanup_mpqueue(dev, min_sqno); /* not necessary */
1767 restore_flags(flags);
1768 return -1; /* -1 is not an error. Just says, that this fragment hasn't complete a full frame */
1770 for (;;) { /* the faster way would be to step from the queue-end to the start */
1771 if (sqno > q->sqno) {
1772 if (q->next) {
1773 q = q->next;
1774 continue;
1776 q->next = q1;
1777 q1->next = NULL;
1778 q1->last = q;
1779 break;
1781 if (sqno == q->sqno)
1782 printk(KERN_WARNING "isdn_fill_mpqueue: illegal sqno received!!\n");
1783 q1->last = q->last;
1784 q1->next = q;
1785 if (q->last) {
1786 q->last->next = q1;
1787 } else
1788 dev->mp_last = q1;
1789 q->last = q1;
1790 break;
1793 /* now we check whether we completed a packet with this fragment */
1794 pktlen = -q1->skb->len;
1795 q = q1;
1796 cnt = q1->sqno;
1797 while (!(q->BEbyte & MP_END_FRAG)) {
1798 cnt++;
1799 if (!(q->next) || q->next->sqno != cnt) {
1800 isdn_ppp_cleanup_mpqueue(dev, min_sqno);
1801 restore_flags(flags);
1802 return -1;
1804 pktlen += q->skb->len;
1805 q = q->next;
1807 pktlen += q->skb->len;
1808 qe = q;
1810 q = q1;
1811 cnt = q1->sqno;
1812 while (!(q->BEbyte & MP_BEGIN_FRAG)) {
1813 cnt--;
1814 if (!(q->last) || q->last->sqno != cnt) {
1815 isdn_ppp_cleanup_mpqueue(dev, min_sqno);
1816 restore_flags(flags);
1817 return -1;
1819 pktlen += q->skb->len;
1820 q = q->last;
1822 pktlen += q->skb->len;
1824 if (q->last)
1825 q->last->next = qe->next;
1826 else
1827 dev->mp_last = qe->next;
1829 if (qe->next)
1830 qe->next->last = q->last;
1831 qe->next = NULL;
1832 sqno_end = qe->sqno;
1833 *sqnop = q->sqno;
1835 isdn_ppp_cleanup_mpqueue(dev, min_sqno);
1836 restore_flags(flags);
1838 *skb = dev_alloc_skb(pktlen + 40); /* not needed: +40 for VJ compression .. */
1840 if (!(*skb)) {
1841 while (q) {
1842 struct mpqueue *ql = q->next;
1843 dev_kfree_skb(q->skb);
1844 kfree(q);
1845 q = ql;
1847 return -2;
1849 cnt = 0;
1850 skb_put(*skb, pktlen);
1851 while (q) {
1852 struct mpqueue *ql = q->next;
1853 memcpy((*skb)->data + cnt, q->skb->data, q->skb->len);
1854 cnt += q->skb->len;
1855 dev_kfree_skb(q->skb);
1856 kfree(q);
1857 q = ql;
1860 return sqno_end;
1864 * check sq-queue, whether we have still buffered the next packet(s)
1865 * or packets with a sqno less or equal to min_sqno
1866 * net_dev: master netdevice , lp: 'real' local connection
1868 static void
1869 isdn_ppp_cleanup_sqqueue(isdn_net_dev * net_dev, isdn_net_local * lp, long min_sqno)
1871 struct sqqueue *q;
1873 while ((q = net_dev->ib.sq) && (q->sqno_start == net_dev->ib.next_num || q->sqno_end <= min_sqno)) {
1874 int proto;
1875 if (q->sqno_start != net_dev->ib.next_num) {
1876 printk(KERN_DEBUG "ippp: MP, stepping over missing frame: %ld\n", net_dev->ib.next_num);
1877 #ifdef CONFIG_ISDN_PPP_VJ
1878 slhc_toss(ippp_table[net_dev->local->ppp_slot]->slcomp);
1879 #endif
1881 proto = isdn_ppp_strip_proto(q->skb);
1882 isdn_ppp_push_higher(net_dev, lp, q->skb, proto);
1883 net_dev->ib.sq = q->next;
1884 net_dev->ib.next_num = q->sqno_end + 1;
1885 kfree(q);
1890 * remove stale packets from list
1892 static void
1893 isdn_ppp_cleanup_mpqueue(isdn_net_dev * dev, long min_sqno)
1895 #ifdef CONFIG_ISDN_PPP_VJ
1896 int toss = 0;
1897 #endif
1898 /* z.z einfaches aussortieren gammeliger pakete. Fuer die Zukunft:
1899 eventuell, solange vorne kein B-paket ist und sqno<=min_sqno: auch rauswerfen
1900 wenn sqno<min_sqno und Luecken vorhanden sind: auch weg (die koennen nicht mehr gefuellt werden)
1901 bei paketen groesser min_sqno: ueber mp_mrru: wenn summe ueber pktlen der rumhaengenden Pakete
1902 groesser als mrru ist: raus damit , Pakete muessen allerdings zusammenhaengen sonst koennte
1903 ja ein Paket mit B und eins mit E dazwischenpassen */
1905 struct mpqueue *ql,
1906 *q = dev->mp_last;
1907 while(q && (q->sqno < min_sqno) ) {
1908 if ( (q->BEbyte & MP_END_FRAG) ||
1909 (q->next && (q->next->sqno <= min_sqno) && (q->next->BEbyte & MP_BEGIN_FRAG)) ) {
1910 printk(KERN_DEBUG "ippp: freeing stale packet(s), min_sq: %ld!\n",min_sqno);
1911 if ((dev->mp_last = q->next))
1912 q->next->last = NULL;
1913 while (q) {
1914 ql = q->last;
1915 printk(KERN_DEBUG "ippp, freeing packet with sqno: %ld\n",q->sqno);
1916 dev_kfree_skb(q->skb);
1917 kfree(q);
1918 #ifdef CONFIG_ISDN_PPP_VJ
1919 toss = 1;
1920 #endif
1921 q = ql;
1923 q = dev->mp_last;
1924 } else
1925 q = q->next;
1927 #ifdef CONFIG_ISDN_PPP_VJ
1928 /* did we free a stale frame ? */
1929 if (toss)
1930 slhc_toss(ippp_table[dev->local->ppp_slot]->slcomp);
1931 #endif
1933 #endif
1936 * a buffered packet timed-out?
1938 void
1939 isdn_ppp_timer_timeout(void)
1941 #ifdef CONFIG_ISDN_MPP
1942 isdn_net_dev *net_dev = dev->netdev;
1943 struct sqqueue *q,
1944 *ql = NULL,
1945 *qn;
1947 while (net_dev) {
1948 isdn_net_local *lp = net_dev->local;
1949 if (net_dev->ib.modify || lp->master) { /* interface locked or slave? */
1950 net_dev = net_dev->next;
1951 continue;
1953 q = net_dev->ib.sq;
1954 while (q) {
1955 if (q->sqno_start == net_dev->ib.next_num || q->timer < jiffies) {
1957 #ifdef CONFIG_ISDN_PPP_VJ
1958 /* did we step over a missing frame ? */
1959 if (q->sqno_start != net_dev->ib.next_num)
1960 slhc_toss(ippp_table[lp->ppp_slot]->slcomp);
1961 #endif
1963 ql = net_dev->ib.sq;
1964 net_dev->ib.sq = q->next;
1965 net_dev->ib.next_num = q->sqno_end + 1;
1966 q->next = NULL;
1967 for (; ql;) {
1968 int proto = isdn_ppp_strip_proto(ql->skb);
1969 isdn_ppp_push_higher(net_dev, lp, ql->skb, proto);
1970 qn = ql->next;
1971 kfree(ql);
1972 ql = qn;
1974 q = net_dev->ib.sq;
1975 } else
1976 q = q->next;
1978 net_dev = net_dev->next;
1980 #endif
1984 * network device ioctl handlers
1987 static int
1988 isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct device *dev)
1990 struct ppp_stats *res,
1992 isdn_net_local *lp = (isdn_net_local *) dev->priv;
1993 int err;
1995 res = (struct ppp_stats *) ifr->ifr_ifru.ifru_data;
1996 err = verify_area(VERIFY_WRITE, res, sizeof(struct ppp_stats));
1998 if (err)
1999 return err;
2001 /* build a temporary stat struct and copy it to user space */
2003 memset(&t, 0, sizeof(struct ppp_stats));
2004 if (dev->flags & IFF_UP) {
2005 t.p.ppp_ipackets = lp->stats.rx_packets;
2006 t.p.ppp_ierrors = lp->stats.rx_errors;
2007 t.p.ppp_opackets = lp->stats.tx_packets;
2008 t.p.ppp_oerrors = lp->stats.tx_errors;
2009 #ifdef CONFIG_ISDN_PPP_VJ
2010 if (slot >= 0 && ippp_table[slot]->slcomp) {
2011 struct slcompress *slcomp = ippp_table[slot]->slcomp;
2012 t.vj.vjs_packets = slcomp->sls_o_compressed + slcomp->sls_o_uncompressed;
2013 t.vj.vjs_compressed = slcomp->sls_o_compressed;
2014 t.vj.vjs_searches = slcomp->sls_o_searches;
2015 t.vj.vjs_misses = slcomp->sls_o_misses;
2016 t.vj.vjs_errorin = slcomp->sls_i_error;
2017 t.vj.vjs_tossed = slcomp->sls_i_tossed;
2018 t.vj.vjs_uncompressedin = slcomp->sls_i_uncompressed;
2019 t.vj.vjs_compressedin = slcomp->sls_i_compressed;
2021 #endif
2023 if( copy_to_user(res, &t, sizeof(struct ppp_stats))) return -EFAULT;
2024 return 0;
2028 isdn_ppp_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
2030 int error=0;
2031 char *r;
2032 int len;
2033 isdn_net_local *lp = (isdn_net_local *) dev->priv;
2035 #if 0
2036 printk(KERN_DEBUG "ippp, dev_ioctl: cmd %#08x , %d \n", cmd, lp->ppp_slot);
2037 #endif
2039 if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
2040 return -EINVAL;
2042 switch (cmd) {
2043 case SIOCGPPPVER:
2044 r = (char *) ifr->ifr_ifru.ifru_data;
2045 len = strlen(PPP_VERSION) + 1;
2046 if(copy_to_user(r, PPP_VERSION, len)) error = -EFAULT;
2047 break;
2048 case SIOCGPPPSTATS:
2049 error = isdn_ppp_dev_ioctl_stats(lp->ppp_slot, ifr, dev);
2050 break;
2051 default:
2052 error = -EINVAL;
2053 break;
2055 return error;
2058 static int
2059 isdn_ppp_if_get_unit(char *name)
2061 int len,
2063 unit = 0,
2064 deci;
2066 len = strlen(name);
2068 if (strncmp("ippp", name, 4) || len > 8)
2069 return -1;
2071 for (i = 0, deci = 1; i < len; i++, deci *= 10) {
2072 char a = name[len - i - 1];
2073 if (a >= '0' && a <= '9')
2074 unit += (a - '0') * deci;
2075 else
2076 break;
2078 if (!i || len - i != 4)
2079 unit = -1;
2081 return unit;
2086 isdn_ppp_dial_slave(char *name)
2088 #ifdef CONFIG_ISDN_MPP
2089 isdn_net_dev *ndev;
2090 isdn_net_local *lp;
2091 struct device *sdev;
2093 if (!(ndev = isdn_net_findif(name)))
2094 return 1;
2095 lp = ndev->local;
2096 if (!(lp->flags & ISDN_NET_CONNECTED))
2097 return 5;
2099 sdev = lp->slave;
2100 while (sdev) {
2101 isdn_net_local *mlp = (isdn_net_local *) sdev->priv;
2102 if (!(mlp->flags & ISDN_NET_CONNECTED))
2103 break;
2104 sdev = mlp->slave;
2106 if (!sdev)
2107 return 2;
2109 isdn_net_dial_req((isdn_net_local *) sdev->priv);
2110 return 0;
2111 #else
2112 return -1;
2113 #endif
2117 isdn_ppp_hangup_slave(char *name)
2119 #ifdef CONFIG_ISDN_MPP
2120 isdn_net_dev *ndev;
2121 isdn_net_local *lp;
2122 struct device *sdev;
2124 if (!(ndev = isdn_net_findif(name)))
2125 return 1;
2126 lp = ndev->local;
2127 if (!(lp->flags & ISDN_NET_CONNECTED))
2128 return 5;
2130 sdev = lp->slave;
2131 while (sdev) {
2132 isdn_net_local *mlp = (isdn_net_local *) sdev->priv;
2133 if ((mlp->flags & ISDN_NET_CONNECTED))
2134 break;
2135 sdev = mlp->slave;
2137 if (!sdev)
2138 return 2;
2140 isdn_net_hangup(sdev);
2141 return 0;
2142 #else
2143 return -1;
2144 #endif
2148 * PPP compression stuff
2152 /* Push an empty CCP Data Frame up to the daemon to wake it up and let it
2153 generate a CCP Reset-Request or tear down CCP altogether */
2155 static void isdn_ppp_ccp_kickup(struct ippp_struct *is)
2157 isdn_ppp_fill_rq(NULL, 0, PPP_COMP, is->lp->ppp_slot);
2160 /* In-kernel handling of CCP Reset-Request and Reset-Ack is necessary,
2161 but absolutely nontrivial. The most abstruse problem we are facing is
2162 that the generation, reception and all the handling of timeouts and
2163 resends including proper request id management should be entirely left
2164 to the (de)compressor, but indeed is not covered by the current API to
2165 the (de)compressor. The API is a prototype version from PPP where only
2166 some (de)compressors have yet been implemented and all of them are
2167 rather simple in their reset handling. Especially, their is only one
2168 outstanding ResetAck at a time with all of them and ResetReq/-Acks do
2169 not have parameters. For this very special case it was sufficient to
2170 just return an error code from the decompressor and have a single
2171 reset() entry to communicate all the necessary information between
2172 the framework and the (de)compressor. Bad enough, LZS is different
2173 (and any other compressor may be different, too). It has multiple
2174 histories (eventually) and needs to Reset each of them independently
2175 and thus uses multiple outstanding Acks and history numbers as an
2176 additional parameter to Reqs/Acks.
2177 All that makes it harder to port the reset state engine into the
2178 kernel because it is not just the same simple one as in (i)pppd but
2179 it must be able to pass additional parameters and have multiple out-
2180 standing Acks. We are trying to achieve the impossible by handling
2181 reset transactions independent by their id. The id MUST change when
2182 the data portion changes, thus any (de)compressor who uses more than
2183 one resettable state must provide and recognize individual ids for
2184 each individual reset transaction. The framework itself does _only_
2185 differentiate them by id, because it has no other semantics like the
2186 (de)compressor might.
2187 This looks like a major redesign of the interface would be nice,
2188 but I don't have an idea how to do it better. */
2190 /* Send a CCP Reset-Request or Reset-Ack directly from the kernel. This is
2191 getting that lengthy because there is no simple "send-this-frame-out"
2192 function above but every wrapper does a bit different. Hope I guess
2193 correct in this hack... */
2195 static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
2196 unsigned char code, unsigned char id,
2197 unsigned char *data, int len)
2199 struct sk_buff *skb;
2200 unsigned char *p;
2201 int count;
2202 int cnt = 0;
2203 isdn_net_local *lp = is->lp;
2205 /* Alloc large enough skb */
2206 skb = dev_alloc_skb(len + 16);
2207 if(!skb) {
2208 printk(KERN_WARNING
2209 "ippp: CCP cannot send reset - out of memory\n");
2210 return;
2213 /* We may need to stuff an address and control field first */
2214 if(!(is->pppcfg & SC_COMP_AC)) {
2215 p = skb_put(skb, 2);
2216 *p++ = 0xff;
2217 *p++ = 0x03;
2220 /* Stuff proto, code, id and length */
2221 p = skb_put(skb, 6);
2222 *p++ = (proto >> 8);
2223 *p++ = (proto & 0xff);
2224 *p++ = code;
2225 *p++ = id;
2226 cnt = 4 + len;
2227 *p++ = (cnt >> 8);
2228 *p++ = (cnt & 0xff);
2230 /* Now stuff remaining bytes */
2231 if(len) {
2232 p = skb_put(skb, len);
2233 memcpy(p, data, len);
2236 /* skb is now ready for xmit */
2237 printk(KERN_DEBUG "Sending CCP Frame:\n");
2238 isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
2240 /* Just ripped from isdn_ppp_write. Dunno whether it makes sense,
2241 especially dunno what the sav_skb stuff is good for. */
2243 count = skb->len;
2244 if ((cnt = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel,
2245 1, skb)) != count) {
2246 if (lp->sav_skb) {
2247 dev_kfree_skb(lp->sav_skb);
2248 printk(KERN_INFO
2249 "isdn_ppp_write: freeing sav_skb (%d,%d)!\n",
2250 cnt, count);
2251 } else
2252 printk(KERN_INFO
2253 "isdn_ppp_write: Can't write PPP frame to LL (%d,%d)!\n",
2254 cnt, count);
2255 lp->sav_skb = skb;
2259 /* Allocate the reset state vector */
2260 static struct ippp_ccp_reset *isdn_ppp_ccp_reset_alloc(struct ippp_struct *is)
2262 struct ippp_ccp_reset *r;
2263 printk(KERN_DEBUG "ippp_ccp: allocating reset data structure\n");
2264 r = kmalloc(sizeof(struct ippp_ccp_reset), GFP_KERNEL);
2265 if(!r)
2266 return NULL;
2267 memset(r, 0, sizeof(struct ippp_ccp_reset));
2268 is->reset = r;
2269 return r;
2272 /* Free a given state and clear everything up for later reallocation */
2273 static void isdn_ppp_ccp_reset_free_state(struct ippp_struct *is,
2274 unsigned char id)
2276 struct ippp_ccp_reset_state *rs;
2278 if(is->reset->rs[id]) {
2279 printk(KERN_DEBUG "ippp_ccp: freeing state for id %d\n", id);
2280 rs = is->reset->rs[id];
2281 /* Make sure the kernel will not call back later */
2282 if(rs->ta)
2283 del_timer(&rs->timer);
2284 is->reset->rs[id] = NULL;
2285 kfree(rs);
2286 } else {
2287 printk(KERN_WARNING "ippp_ccp: id %d is not allocated\n", id);
2291 /* The timer callback function which is called when a ResetReq has timed out,
2292 aka has never been answered by a ResetAck */
2293 static void isdn_ppp_ccp_timer_callback(unsigned long closure)
2295 struct ippp_ccp_reset_state *rs =
2296 (struct ippp_ccp_reset_state *)closure;
2298 if(!rs) {
2299 printk(KERN_ERR "ippp_ccp: timer cb with zero closure.\n");
2300 return;
2302 if(rs->ta && rs->state == CCPResetSentReq) {
2303 /* We are correct here */
2304 printk(KERN_DEBUG "ippp_ccp: CCP Reset timed out for id %d\n",
2305 rs->id);
2306 if(!rs->expra) {
2307 /* Hmm, there is no Ack really expected. We can clean
2308 up the state now, it will be reallocated if the
2309 decompressor insists on another reset */
2310 rs->ta = 0;
2311 isdn_ppp_ccp_reset_free_state(rs->is, rs->id);
2312 return;
2314 /* Push it again */
2315 isdn_ppp_ccp_xmit_reset(rs->is, PPP_CCP, CCP_RESETREQ, rs->id,
2316 rs->data, rs->dlen);
2317 /* Restart timer */
2318 rs->timer.expires = jiffies + HZ*5;
2319 add_timer(&rs->timer);
2320 } else {
2321 printk(KERN_WARNING "ippp_ccp: timer cb in wrong state %d\n",
2322 rs->state);
2326 /* Allocate a new reset transaction state */
2327 static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_struct *is,
2328 unsigned char id)
2330 struct ippp_ccp_reset_state *rs;
2331 if(is->reset->rs[id]) {
2332 printk(KERN_WARNING "ippp_ccp: old state exists for id %d\n",
2333 id);
2334 return NULL;
2335 } else {
2336 rs = kmalloc(sizeof(struct ippp_ccp_reset_state), GFP_KERNEL);
2337 if(!rs)
2338 return NULL;
2339 memset(rs, 0, sizeof(struct ippp_ccp_reset_state));
2340 rs->state = CCPResetIdle;
2341 rs->is = is;
2342 rs->id = id;
2343 rs->timer.data = (unsigned long)rs;
2344 rs->timer.function = isdn_ppp_ccp_timer_callback;
2345 is->reset->rs[id] = rs;
2347 return rs;
2351 /* A decompressor wants a reset with a set of parameters - do what is
2352 necessary to fulfill it */
2353 static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
2354 struct isdn_ppp_resetparams *rp)
2356 struct ippp_ccp_reset_state *rs;
2358 if(rp->valid) {
2359 /* The decompressor defines parameters by itself */
2360 if(rp->rsend) {
2361 /* And he wants us to send a request */
2362 if(!(rp->idval)) {
2363 printk(KERN_ERR "ippp_ccp: decompressor must"
2364 " specify reset id\n");
2365 return;
2367 if(is->reset->rs[rp->id]) {
2368 /* There is already a transaction in existence
2369 for this id. May be still waiting for a
2370 Ack or may be wrong. */
2371 rs = is->reset->rs[rp->id];
2372 if(rs->state == CCPResetSentReq && rs->ta) {
2373 printk(KERN_DEBUG "ippp_ccp: reset"
2374 " trans still in progress"
2375 " for id %d\n", rp->id);
2376 } else {
2377 printk(KERN_WARNING "ippp_ccp: reset"
2378 " trans in wrong state %d for"
2379 " id %d\n", rs->state, rp->id);
2381 } else {
2382 /* Ok, this is a new transaction */
2383 printk(KERN_DEBUG "ippp_ccp: new trans for id"
2384 " %d to be started\n", rp->id);
2385 rs = isdn_ppp_ccp_reset_alloc_state(is, rp->id);
2386 if(!rs) {
2387 printk(KERN_ERR "ippp_ccp: out of mem"
2388 " allocing ccp trans\n");
2389 return;
2391 rs->state = CCPResetSentReq;
2392 rs->expra = rp->expra;
2393 if(rp->dtval) {
2394 rs->dlen = rp->dlen;
2395 memcpy(rs->data, rp->data, rp->dlen);
2397 /* HACK TODO - add link comp here */
2398 isdn_ppp_ccp_xmit_reset(is, PPP_CCP,
2399 CCP_RESETREQ, rs->id,
2400 rs->data, rs->dlen);
2401 /* Start the timer */
2402 rs->timer.expires = jiffies + 5*HZ;
2403 add_timer(&rs->timer);
2404 rs->ta = 1;
2406 } else {
2407 printk(KERN_DEBUG "ippp_ccp: no reset sent\n");
2409 } else {
2410 /* The reset params are invalid. The decompressor does not
2411 care about them, so we just send the minimal requests
2412 and increase ids only when an Ack is received for a
2413 given id */
2414 if(is->reset->rs[is->reset->lastid]) {
2415 /* There is already a transaction in existence
2416 for this id. May be still waiting for a
2417 Ack or may be wrong. */
2418 rs = is->reset->rs[is->reset->lastid];
2419 if(rs->state == CCPResetSentReq && rs->ta) {
2420 printk(KERN_DEBUG "ippp_ccp: reset"
2421 " trans still in progress"
2422 " for id %d\n", rp->id);
2423 } else {
2424 printk(KERN_WARNING "ippp_ccp: reset"
2425 " trans in wrong state %d for"
2426 " id %d\n", rs->state, rp->id);
2428 } else {
2429 printk(KERN_DEBUG "ippp_ccp: new trans for id"
2430 " %d to be started\n", is->reset->lastid);
2431 rs = isdn_ppp_ccp_reset_alloc_state(is,
2432 is->reset->lastid);
2433 if(!rs) {
2434 printk(KERN_ERR "ippp_ccp: out of mem"
2435 " allocing ccp trans\n");
2436 return;
2438 rs->state = CCPResetSentReq;
2439 /* We always expect an Ack if the decompressor doesnt
2440 know better */
2441 rs->expra = 1;
2442 rs->dlen = 0;
2443 /* HACK TODO - add link comp here */
2444 isdn_ppp_ccp_xmit_reset(is, PPP_CCP, CCP_RESETREQ,
2445 rs->id, NULL, 0);
2446 /* Start the timer */
2447 rs->timer.expires = jiffies + 5*HZ;
2448 add_timer(&rs->timer);
2449 rs->ta = 1;
2454 /* An Ack was received for this id. This means we stop the timer and clean
2455 up the state prior to calling the decompressors reset routine. */
2456 static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
2457 unsigned char id)
2459 struct ippp_ccp_reset_state *rs = is->reset->rs[id];
2461 if(rs) {
2462 if(rs->ta && rs->state == CCPResetSentReq) {
2463 /* Great, we are correct */
2464 if(!rs->expra)
2465 printk(KERN_DEBUG "ippp_ccp: ResetAck received"
2466 " for id %d but not expected\n", id);
2467 } else {
2468 printk(KERN_INFO "ippp_ccp: ResetAck received out of"
2469 "sync for id %d\n", id);
2471 if(rs->ta) {
2472 rs->ta = 0;
2473 del_timer(&rs->timer);
2475 isdn_ppp_ccp_reset_free_state(is, id);
2476 } else {
2477 printk(KERN_INFO "ippp_ccp: ResetAck received for unknown id"
2478 " %d\n", id);
2480 /* Make sure the simple reset stuff uses a new id next time */
2481 is->reset->lastid++;
2484 static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struct *is,struct ippp_struct *master,
2485 int proto)
2487 #ifndef CONFIG_ISDN_CCP
2488 if(proto == PPP_COMP || proto == PPP_LINK_COMP) {
2489 printk(KERN_ERR "isdn_ppp: Ouch! Compression not included!\n");
2490 dev_kfree_skb(skb);
2491 return NULL;
2493 return skb;
2494 #else
2495 void *stat = NULL;
2496 struct isdn_ppp_compressor *ipc = NULL;
2497 struct sk_buff *skb_out;
2498 int len;
2499 struct ippp_struct *ri;
2500 struct isdn_ppp_resetparams rsparm;
2501 unsigned char rsdata[IPPP_RESET_MAXDATABYTES];
2503 if(!master) {
2505 * single link decompression
2507 if(!is->link_decompressor) {
2508 printk(KERN_ERR "ippp: no link decompressor defined!\n");
2509 dev_kfree_skb(skb);
2510 return NULL;
2512 if(!is->link_decomp_stat) {
2513 printk(KERN_DEBUG "ippp: no link decompressor data allocated\n");
2514 dev_kfree_skb(skb);
2515 return NULL;
2517 stat = is->link_decomp_stat;
2518 ipc = is->link_decompressor;
2519 ri = is;
2521 else {
2523 * 'normal' or bundle-compression
2525 if(!master->decompressor) {
2526 printk(KERN_ERR "ippp: no decompressor defined!\n");
2527 dev_kfree_skb(skb);
2528 return NULL;
2530 if(!master->decomp_stat) {
2531 printk(KERN_DEBUG "ippp: no decompressor data allocated\n");
2532 dev_kfree_skb(skb);
2533 return NULL;
2535 stat = master->decomp_stat;
2536 ipc = master->decompressor;
2537 ri = master;
2541 printk(KERN_DEBUG "ippp: Decompress valid!\n");
2544 if((master && proto == PPP_COMP) || (!master && proto == PPP_LINK_COMP) ) {
2545 /* Set up reset params for the decompressor */
2546 memset(&rsparm, 0, sizeof(rsparm));
2547 rsparm.data = rsdata;
2548 rsparm.maxdlen = IPPP_RESET_MAXDATABYTES;
2550 /* !!!HACK,HACK,HACK!!! 2048 is only assumed */
2551 skb_out = dev_alloc_skb(2048);
2552 len = ipc->decompress(stat,skb,skb_out, &rsparm);
2553 dev_kfree_skb(skb);
2554 if(len <= 0) {
2555 /* Ok, some error */
2556 switch(len) {
2557 case DECOMP_ERROR:
2558 ri->pppcfg |= SC_DC_ERROR;
2559 printk(KERN_INFO "ippp: decomp wants reset %s params\n",
2560 rsparm.valid ? "with" : "without");
2562 isdn_ppp_ccp_reset_trans(ri, &rsparm);
2564 break;
2565 case DECOMP_FATALERROR:
2566 ri->pppcfg |= SC_DC_FERROR;
2567 /* Kick ipppd to recognize the error */
2568 isdn_ppp_ccp_kickup(ri);
2569 break;
2571 /* Did I see a leak here ? */
2572 dev_kfree_skb(skb_out);
2573 return NULL;
2575 return skb_out;
2577 else {
2579 printk(KERN_DEBUG "isdn_ppp: [%d] Calling incomp with this frame!\n",is->unit);
2581 ipc->incomp(stat,skb,proto);
2582 return skb;
2584 #endif
2588 * compress a frame
2589 * type=0: normal/bundle compression
2590 * =1: link compression
2591 * returns original skb if we haven't compressed the frame
2592 * and a new skb pointer if we've done it
2594 static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in,int *proto,
2595 struct ippp_struct *is,struct ippp_struct *master,int type)
2597 int ret;
2598 int new_proto;
2599 struct isdn_ppp_compressor *compressor;
2600 void *stat;
2601 struct sk_buff *skb_out;
2603 #ifdef CONFIG_ISDN_CCP
2604 /* we do not compress control protocols */
2605 if(*proto < 0 || *proto > 0x3fff) {
2606 #else
2608 #endif
2609 return skb_in;
2612 if(type) { /* type=1 => Link compression */
2613 #if 0
2614 compressor = is->link_compressor;
2615 stat = is->link_comp_stat;
2616 new_proto = PPP_LINK_COMP;
2617 #else
2618 return skb_in;
2619 #endif
2621 else {
2622 if(!master) {
2623 compressor = is->compressor;
2624 stat = is->comp_stat;
2626 else {
2627 compressor = master->compressor;
2628 stat = master->comp_stat;
2630 new_proto = PPP_COMP;
2633 if(!compressor) {
2634 printk(KERN_ERR "isdn_ppp: No compressor set!\n");
2635 return skb_in;
2637 if(!stat) {
2638 printk(KERN_ERR "isdn_ppp: Compressor not initialized?\n");
2639 return skb_in;
2642 /* Allow for at least 150 % expansion (for now) */
2643 skb_out = dev_alloc_skb(skb_in->len + skb_in->len/2 + 32);
2644 if(!skb_out)
2645 return skb_in;
2647 ret = (compressor->compress)(stat,skb_in,skb_out,*proto);
2648 if(!ret) {
2649 dev_kfree_skb(skb_out);
2650 return skb_in;
2653 dev_kfree_skb(skb_in);
2654 *proto = new_proto;
2655 return skb_out;
2659 * we received a CCP frame ..
2660 * not a clean solution, but we MUST handle a few cases in the kernel
2662 static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
2663 struct sk_buff *skb,int proto)
2665 struct ippp_struct *is = ippp_table[lp->ppp_slot];
2666 struct ippp_struct *mis;
2667 int len;
2668 struct isdn_ppp_resetparams rsparm;
2669 unsigned char rsdata[IPPP_RESET_MAXDATABYTES];
2671 printk(KERN_DEBUG "Received CCP frame from peer\n");
2672 isdn_ppp_frame_log("ccp-rcv", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
2674 if(lp->master)
2675 mis = ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot];
2676 else
2677 mis = is;
2679 switch(skb->data[0]) {
2680 case CCP_CONFREQ:
2681 case CCP_TERMREQ:
2682 case CCP_TERMACK:
2683 if(is->debug & 0x10)
2684 printk(KERN_DEBUG "Disable (de)compression here!\n");
2685 if(proto == PPP_CCP)
2686 mis->compflags &= ~(SC_DECOMP_ON|SC_COMP_ON);
2687 else
2688 is->compflags &= ~(SC_LINK_DECOMP_ON|SC_LINK_COMP_ON);
2689 break;
2690 case CCP_CONFACK:
2691 /* if we RECEIVE an ackowledge we enable the decompressor */
2692 if(is->debug & 0x10)
2693 printk(KERN_DEBUG "Enable decompression here!\n");
2694 if(proto == PPP_CCP)
2695 mis->compflags |= SC_DECOMP_ON;
2696 else
2697 is->compflags |= SC_LINK_DECOMP_ON;
2698 break;
2700 case CCP_RESETACK:
2701 printk(KERN_DEBUG "Received ResetAck from peer\n");
2702 len = (skb->data[2] << 8) | skb->data[3];
2703 len -= 4;
2705 if(proto == PPP_CCP) {
2706 /* If a reset Ack was outstanding for this id, then
2707 clean up the state engine */
2708 isdn_ppp_ccp_reset_ack_rcvd(mis, skb->data[1]);
2709 if(mis->decompressor && mis->decomp_stat)
2710 mis->decompressor->
2711 reset(mis->decomp_stat,
2712 skb->data[0],
2713 skb->data[1],
2714 len ? &skb->data[4] : NULL,
2715 len, NULL);
2716 /* TODO: This is not easy to decide here */
2717 mis->compflags &= ~SC_DECOMP_DISCARD;
2718 mis->pppcfg &= ~SC_DC_ERROR;
2720 else {
2721 isdn_ppp_ccp_reset_ack_rcvd(is, skb->data[1]);
2722 if(is->link_decompressor && is->link_decomp_stat)
2723 is->link_decompressor->
2724 reset(is->link_decomp_stat,
2725 skb->data[0],
2726 skb->data[1],
2727 len ? &skb->data[4] : NULL,
2728 len, NULL);
2729 /* TODO: neither here */
2730 is->compflags &= ~SC_LINK_DECOMP_DISCARD;
2731 is->pppcfg &= ~SC_DC_ERROR;
2733 break;
2735 case CCP_RESETREQ:
2736 printk(KERN_DEBUG "Received ResetReq from peer\n");
2737 /* Receiving a ResetReq means we must reset our compressor */
2738 /* Set up reset params for the reset entry */
2739 memset(&rsparm, 0, sizeof(rsparm));
2740 rsparm.data = rsdata;
2741 rsparm.maxdlen = IPPP_RESET_MAXDATABYTES;
2742 /* Isolate data length */
2743 len = (skb->data[2] << 8) | skb->data[3];
2744 len -= 4;
2745 if(proto == PPP_CCP) {
2746 if(mis->compressor && mis->comp_stat)
2747 mis->compressor->
2748 reset(mis->comp_stat,
2749 skb->data[0],
2750 skb->data[1],
2751 len ? &skb->data[4] : NULL,
2752 len, &rsparm);
2754 else {
2755 if(is->link_compressor && is->link_comp_stat)
2756 is->link_compressor->
2757 reset(is->link_comp_stat,
2758 skb->data[0],
2759 skb->data[1],
2760 len ? &skb->data[4] : NULL,
2761 len, &rsparm);
2763 /* Ack the Req as specified by rsparm */
2764 if(rsparm.valid) {
2765 /* Compressor reset handler decided how to answer */
2766 if(rsparm.rsend) {
2767 /* We should send a Frame */
2768 isdn_ppp_ccp_xmit_reset(is, proto, CCP_RESETACK,
2769 rsparm.idval ? rsparm.id
2770 : skb->data[1],
2771 rsparm.dtval ?
2772 rsparm.data : NULL,
2773 rsparm.dtval ?
2774 rsparm.dlen : 0);
2775 } else {
2776 printk(KERN_DEBUG "ResetAck suppressed\n");
2778 } else {
2779 /* We answer with a straight reflected Ack */
2780 isdn_ppp_ccp_xmit_reset(is, proto, CCP_RESETACK,
2781 skb->data[1],
2782 len ? &skb->data[4] : NULL,
2783 len);
2785 break;
2791 * Daemon sends a CCP frame ...
2794 /* TODO: Clean this up with new Reset semantics */
2796 static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *skb)
2798 struct ippp_struct *mis,*is = ippp_table[lp->ppp_slot];
2799 int proto;
2800 unsigned char *data;
2802 if(!skb || skb->len < 3)
2803 return;
2805 /* Daemon may send with or without address and control field comp */
2806 data = skb->data;
2807 if(!(is->pppcfg & SC_COMP_AC) && data[0] == 0xff && data[1] == 0x03) {
2808 data += 2;
2809 if(skb->len < 5)
2810 return;
2813 proto = ((int)data[0]<<8)+data[1];
2814 if(proto != PPP_CCP && proto != PPP_LINK_CCP)
2815 return;
2817 printk(KERN_DEBUG "Received CCP frame from daemon:\n");
2818 isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
2820 if(lp->master)
2821 mis = ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot];
2822 else
2823 mis = is;
2825 if(mis != is)
2826 printk(KERN_DEBUG "isdn_ppp: Ouch! Master CCP sends on slave slot!\n");
2828 switch(data[2]) {
2829 case CCP_CONFREQ:
2830 case CCP_TERMREQ:
2831 case CCP_TERMACK:
2832 if(is->debug & 0x10)
2833 printk(KERN_DEBUG "Disable (de)compression here!\n");
2834 if(proto == PPP_CCP)
2835 is->compflags &= ~(SC_DECOMP_ON|SC_COMP_ON);
2836 else
2837 is->compflags &= ~(SC_LINK_DECOMP_ON|SC_LINK_COMP_ON);
2838 break;
2839 case CCP_CONFACK:
2840 /* if we SEND an ackowledge we can/must enable the compressor */
2841 if(is->debug & 0x10)
2842 printk(KERN_DEBUG "Enable compression here!\n");
2843 if(proto == PPP_CCP)
2844 is->compflags |= SC_COMP_ON;
2845 else
2846 is->compflags |= SC_LINK_COMP_ON;
2847 break;
2848 case CCP_RESETACK:
2849 /* If we send a ACK we should reset our compressor */
2850 if(is->debug & 0x10)
2851 printk(KERN_DEBUG "Reset decompression state here!\n");
2852 printk(KERN_DEBUG "ResetAck from daemon passed by\n");
2853 if(proto == PPP_CCP) {
2854 /* link to master? */
2855 if(is->compressor && is->comp_stat)
2856 is->compressor->reset(is->comp_stat, 0, 0,
2857 NULL, 0, NULL);
2858 is->compflags &= ~SC_COMP_DISCARD;
2860 else {
2861 if(is->link_compressor && is->link_comp_stat)
2862 is->link_compressor->reset(is->link_comp_stat,
2863 0, 0, NULL, 0, NULL);
2864 is->compflags &= ~SC_LINK_COMP_DISCARD;
2866 break;
2867 case CCP_RESETREQ:
2868 /* Just let it pass by */
2869 printk(KERN_DEBUG "ResetReq from daemon passed by\n");
2870 break;
2875 int isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc)
2877 ipc->next = ipc_head;
2878 ipc->prev = NULL;
2879 if(ipc_head) {
2880 ipc_head->prev = ipc;
2882 ipc_head = ipc;
2883 return 0;
2886 int isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *ipc)
2888 if(ipc->prev)
2889 ipc->prev->next = ipc->next;
2890 else
2891 ipc_head = ipc->next;
2892 if(ipc->next)
2893 ipc->next->prev = ipc->prev;
2894 ipc->prev = ipc->next = NULL;
2895 return 0;
2898 static int isdn_ppp_set_compressor(struct ippp_struct *is, struct isdn_ppp_comp_data *data)
2900 struct isdn_ppp_compressor *ipc = ipc_head;
2901 int ret;
2902 void *stat;
2903 int num = data->num;
2905 if(is->debug & 0x10)
2906 printk(KERN_DEBUG "[%d] Set %s type %d\n",is->unit,
2907 (data->flags&IPPP_COMP_FLAG_XMIT)?"compressor":"decompressor",num);
2909 while(ipc) {
2910 if(ipc->num == num) {
2911 stat = ipc->alloc(data);
2912 if(stat) {
2913 ret = ipc->init(stat,data,is->unit,0);
2914 if(!ret) {
2915 printk(KERN_ERR "Can't init (de)compression!\n");
2916 ipc->free(stat);
2917 stat = NULL;
2918 break;
2921 else {
2922 printk(KERN_ERR "Can't alloc (de)compression!\n");
2923 break;
2926 if(data->flags & IPPP_COMP_FLAG_XMIT) {
2927 if(data->flags & IPPP_COMP_FLAG_LINK) {
2928 if(is->link_comp_stat)
2929 is->link_compressor->free(is->link_comp_stat);
2930 is->link_comp_stat = stat;
2931 is->link_compressor = ipc;
2933 else {
2934 if(is->comp_stat)
2935 is->compressor->free(is->comp_stat);
2936 is->comp_stat = stat;
2937 is->compressor = ipc;
2940 else {
2941 if(data->flags & IPPP_COMP_FLAG_LINK) {
2942 if(is->link_decomp_stat)
2943 is->link_decompressor->free(is->link_decomp_stat);
2944 is->link_decomp_stat = stat;
2945 is->link_decompressor = ipc;
2947 else {
2948 if(is->decomp_stat)
2949 is->decompressor->free(is->decomp_stat);
2950 is->decomp_stat = stat;
2951 is->decompressor = ipc;
2954 return 0;
2956 ipc = ipc->next;
2958 return -EINVAL;