2.2.0-final
[davej-history.git] / drivers / isdn / isdn_ppp.c
blob5da3a49f034b2a195eafa15f510030918d37529b
1 /* $Id: isdn_ppp.c,v 1.33 1998/02/20 17:11:54 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 * Note: This file differs from the corresponding revision as present in the
22 * isdn4linux CVS repository because some later bug fixes have been extracted
23 * from the repository and merged into this file. -- Henner Eisen
25 * $Log: isdn_ppp.c,v $
26 * Revision 1.33 1998/02/20 17:11:54 fritz
27 * Changes for recent kernels.
29 * Revision 1.32 1998/01/31 19:29:55 calle
30 * Merged changes from and for 2.1.82, not tested only compiled ...
32 * Revision 1.31 1997/10/09 21:29:01 fritz
33 * New HL<->LL interface:
34 * New BSENT callback with nr. of bytes included.
35 * Sending without ACK.
36 * New L1 error status (not yet in use).
37 * Cleaned up obsolete structures.
38 * Implemented Cisco-SLARP.
39 * Changed local net-interface data to be dynamically allocated.
40 * Removed old 2.0 compatibility stuff.
42 * Revision 1.30 1997/10/01 09:20:38 fritz
43 * Removed old compatibility stuff for 2.0.X kernels.
44 * From now on, this code is for 2.1.X ONLY!
45 * Old stuff is still in the separate branch.
47 * Revision 1.29 1997/08/21 23:11:44 fritz
48 * Added changes for kernels >= 2.1.45
50 * Revision 1.28 1997/06/17 13:05:57 hipp
51 * Applied Eric's underflow-patches (slightly modified)
52 * more compression changes (but disabled at the moment)
53 * changed one copy_to_user() to run with enabled IRQs
54 * a few MP changes
55 * changed 'proto' handling in the isdn_ppp receive code
57 * Revision 1.27 1997/03/30 16:51:17 calle
58 * changed calls to copy_from_user/copy_to_user and removed verify_area
59 * were possible.
61 * Revision 1.26 1997/02/23 16:53:44 hipp
62 * minor cleanup
63 * some initial changes for future PPP compresion
64 * added AC,PC compression for outgoing frames
66 * Revision 1.25 1997/02/12 20:37:35 hipp
67 * New ioctl() PPPIOCGCALLINFO, minor cleanup
69 * Revision 1.24 1997/02/11 18:32:56 fritz
70 * Bugfix in isdn_ppp_free_mpqueue().
72 * Revision 1.23 1997/02/10 11:12:19 fritz
73 * More changes for Kernel 2.1.X compatibility.
75 * Revision 1.22 1997/02/06 15:03:51 hipp
76 * changed GFP_KERNEL kmalloc to GFP_ATOMIC in isdn_ppp_fill_mpqueue()
78 * Revision 1.21 1997/02/03 23:29:38 fritz
79 * Reformatted according CodingStyle
80 * Bugfix: removed isdn_ppp_skb_destructor, used by upper layers.
81 * Misc changes for Kernel 2.1.X compatibility.
83 * Revision 1.20 1996/10/30 12:21:58 fritz
84 * Cosmetic fix: Compiler warning when compiling without MPP.
86 * Revision 1.19 1996/10/25 19:03:21 hipp
87 * changed/added some defines to (re)allow compilation without MP/VJ
89 * Revision 1.18 1996/10/22 23:14:00 fritz
90 * Changes for compatibility to 2.0.X and 2.1.X kernels.
92 * Revision 1.17 1996/10/22 09:39:49 hipp
93 * a few MP changes and bugfixes
95 * Revision 1.16 1996/09/23 01:58:10 fritz
96 * Fix: With syncPPP encapsulation, discard LCP packets
97 * when calculating hangup timeout.
99 * Revision 1.15 1996/09/07 12:50:12 hipp
100 * bugfixes (unknown device after failed dial attempt, minor bugs)
102 * Revision 1.14 1996/08/12 16:26:47 hipp
103 * code cleanup
104 * changed connection management from minors to slots
106 * Revision 1.13 1996/07/01 19:47:24 hipp
107 * Fixed memory leak in VJ handling and more VJ changes
109 * Revision 1.12 1996/06/24 17:42:03 fritz
110 * Minor bugfixes.
112 * Revision 1.11 1996/06/16 17:46:05 tsbogend
113 * changed unsigned long to u32 to make Alpha people happy
115 * Revision 1.10 1996/06/11 14:50:29 hipp
116 * Lot of changes and bugfixes.
117 * New scheme to resend packets to busy LL devices.
119 * Revision 1.9 1996/05/18 01:37:01 fritz
120 * Added spelling corrections and some minor changes
121 * to stay in sync with kernel.
123 * Revision 1.8 1996/05/06 11:34:55 hipp
124 * fixed a few bugs
126 * Revision 1.7 1996/04/30 11:07:42 fritz
127 * Added Michael's ippp-bind patch.
129 * Revision 1.6 1996/04/30 09:33:09 fritz
130 * Removed compatibility-macros.
132 * Revision 1.5 1996/04/20 16:32:32 fritz
133 * Changed ippp_table to an array of pointers, allocating each part
134 * separately.
136 * Revision 1.4 1996/02/19 15:25:50 fritz
137 * Bugfix: Sync-PPP packets got compressed twice, when resent due to
138 * send-queue-full reject.
140 * Revision 1.3 1996/02/11 02:27:12 fritz
141 * Lot of Bugfixes my Michael.
142 * Moved calls to skb_push() into isdn_net_header()
143 * Fixed a possible race-condition in isdn_ppp_timer_timeout().
145 * Revision 1.2 1996/01/22 05:08:06 fritz
146 * Merged in Michael's patches for MP.
147 * Minor changes in isdn_ppp_xmit.
149 * Revision 1.1 1996/01/09 04:11:29 fritz
150 * Initial revision
154 /* TODO: right tbusy handling when using MP */
157 * experimental for dynamic addressing: readdress IP frames
159 #undef ISDN_SYNCPPP_READDRESS
161 #include <linux/config.h>
162 #define __NO_VERSION__
163 #include <linux/module.h>
164 #include <linux/version.h>
165 #include <linux/isdn.h>
166 #include <linux/poll.h>
167 #include "isdn_common.h"
168 #include "isdn_ppp.h"
169 #include "isdn_net.h"
171 #ifndef PPP_IPX
172 #define PPP_IPX 0x002b
173 #endif
175 /* set this if you use dynamic addressing */
177 /* Prototypes */
178 static int isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot);
179 static int isdn_ppp_closewait(int slot);
180 static void isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp,
181 struct sk_buff *skb, int proto);
182 static int isdn_ppp_if_get_unit(char *namebuf);
183 static int isdn_ppp_set_compressor(struct ippp_struct *is,int num);
184 static struct sk_buff *isdn_ppp_decompress(struct sk_buff *,
185 struct ippp_struct *,struct ippp_struct *);
186 static void isdn_ppp_receive_ccp(isdn_net_dev * net_dev, isdn_net_local * lp,
187 struct sk_buff *skb);
188 static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in,int *proto,
189 struct ippp_struct *is,struct ippp_struct *master,int type);
191 #ifdef CONFIG_ISDN_MPP
192 static int isdn_ppp_bundle(struct ippp_struct *, int unit);
193 static void isdn_ppp_mask_queue(isdn_net_dev * dev, long mask);
194 static void isdn_ppp_cleanup_mpqueue(isdn_net_dev * dev, long min);
195 static void isdn_ppp_cleanup_sqqueue(isdn_net_dev * dev, isdn_net_local *, long min);
196 static void isdn_ppp_free_sqqueue(isdn_net_dev *);
197 static int isdn_ppp_fill_mpqueue(isdn_net_dev *, struct sk_buff **skb,
198 int BEbyte, long *sqno, int min_sqno);
199 static void isdn_ppp_free_mpqueue(isdn_net_dev *);
200 #endif
202 char *isdn_ppp_revision = "$Revision: 1.33 $";
204 static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
205 static struct isdn_ppp_compressor *ipc_head = NULL;
207 extern int isdn_net_force_dial_lp(isdn_net_local *);
210 * frame log (debug)
212 static void
213 isdn_ppp_frame_log(char *info, char *data, int len, int maxlen)
215 int cnt,
218 char buf[80];
220 if (len < maxlen)
221 maxlen = len;
223 for (i = 0, cnt = 0; cnt < maxlen; i++) {
224 for (j = 0; j < 16 && cnt < maxlen; j++, cnt++)
225 sprintf(buf + j * 3, "%02x ", (unsigned char) data[cnt]);
226 printk(KERN_DEBUG "%s[%d]: %s\n", info, i, buf);
231 * unbind isdn_net_local <=> ippp-device
232 * note: it can happen, that we hangup/free the master before the slaves
235 isdn_ppp_free(isdn_net_local * lp)
237 #ifdef CONFIG_ISDN_MPP
238 isdn_net_local *master_lp = lp;
239 #endif
240 unsigned long flags;
241 struct ippp_struct *is;
243 if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS)
244 return 0;
246 is = ippp_table[lp->ppp_slot];
248 save_flags(flags);
249 cli();
250 #ifdef CONFIG_ISDN_MPP
251 if (lp->master)
252 master_lp = (isdn_net_local *) lp->master->priv;
254 lp->last->next = lp->next;
255 lp->next->last = lp->last;
256 if (master_lp->netdev->queue == lp) {
257 master_lp->netdev->queue = lp->next;
258 if (lp->next == lp) { /* last link in queue? */
259 master_lp->netdev->ib.bundled = 0;
260 isdn_ppp_free_mpqueue(master_lp->netdev);
261 isdn_ppp_free_sqqueue(master_lp->netdev);
264 lp->next = lp->last = lp; /* (re)set own pointers */
265 #endif
267 if ((is->state & IPPP_CONNECT))
268 isdn_ppp_closewait(lp->ppp_slot); /* force wakeup on ippp device */
269 else if (is->state & IPPP_ASSIGNED)
270 is->state = IPPP_OPEN; /* fallback to 'OPEN but not ASSIGEND' staet */
273 if (is->debug & 0x1)
274 printk(KERN_DEBUG "isdn_ppp_free %d %lx %lx\n", lp->ppp_slot, (long) lp, (long) is->lp);
276 is->lp = NULL; /* link is down .. set lp to NULL */
277 #ifdef ISDN_SYNCPPP_READDRESS
278 is->old_pa_addr = 0x0;
279 is->old_pa_dstaddr = 0x0;
280 #endif
281 lp->ppp_slot = -1; /* is this OK ?? */
282 restore_flags(flags);
284 return 0;
288 * bind isdn_net_local <=> ippp-device
291 isdn_ppp_bind(isdn_net_local * lp)
293 int i;
294 int unit = 0;
295 long flags;
296 struct ippp_struct *is;
298 if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
299 return -1;
301 save_flags(flags);
302 cli();
304 if (lp->pppbind < 0) { /* device bounded to ippp device ? */
305 isdn_net_dev *net_dev = dev->netdev;
306 char exclusive[ISDN_MAX_CHANNELS]; /* exclusive flags */
307 memset(exclusive, 0, ISDN_MAX_CHANNELS);
308 while (net_dev) { /* step through net devices to find exclusive minors */
309 isdn_net_local *lp = net_dev->local;
310 if (lp->pppbind >= 0)
311 exclusive[lp->pppbind] = 1;
312 net_dev = net_dev->next;
315 * search a free device / slot
317 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
318 if (ippp_table[i]->state == IPPP_OPEN && !exclusive[ippp_table[i]->minor]) { /* OPEN, but not connected! */
319 break;
322 } else {
323 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
324 if (ippp_table[i]->minor == lp->pppbind && ippp_table[i]->state == IPPP_OPEN)
325 break;
328 if (i >= ISDN_MAX_CHANNELS) {
329 restore_flags(flags);
330 printk(KERN_WARNING "isdn_ppp_bind: Can't find usable ippp device.\n");
331 return -1;
333 unit = isdn_ppp_if_get_unit(lp->name); /* get unit number from interface name .. ugly! */
334 if (unit < 0) {
335 printk(KERN_ERR "isdn_ppp_bind: illegal interface name %s.\n", lp->name);
336 return -1;
338 lp->ppp_slot = i;
339 is = ippp_table[i];
340 is->lp = lp;
341 is->unit = unit;
342 is->state = IPPP_OPEN | IPPP_ASSIGNED; /* assigned to a netdevice but not connected */
344 restore_flags(flags);
346 return lp->ppp_slot;
350 * kick the ipppd on the device
351 * (wakes up daemon after B-channel connect)
354 void
355 isdn_ppp_wakeup_daemon(isdn_net_local * lp)
357 if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS)
358 return;
360 ippp_table[lp->ppp_slot]->state = IPPP_OPEN | IPPP_CONNECT | IPPP_NOBLOCK;
362 if (ippp_table[lp->ppp_slot]->wq)
363 wake_up_interruptible(&ippp_table[lp->ppp_slot]->wq);
367 * there was a hangup on the netdevice
368 * force wakeup of the ippp device
369 * go into 'device waits for release' state
371 static int
372 isdn_ppp_closewait(int slot)
374 struct ippp_struct *is;
376 if (slot < 0 || slot >= ISDN_MAX_CHANNELS)
377 return 0;
378 is = ippp_table[slot];
380 if (is->state && is->wq)
381 wake_up_interruptible(&is->wq);
383 is->state = IPPP_CLOSEWAIT;
384 return 1;
388 * isdn_ppp_find_slot / isdn_ppp_free_slot
391 static int
392 isdn_ppp_get_slot(void)
394 int i;
395 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
396 if (!ippp_table[i]->state)
397 return i;
399 return -1;
403 * isdn_ppp_open
407 isdn_ppp_open(int min, struct file *file)
409 int slot;
410 struct ippp_struct *is;
412 if (min < 0 || min > ISDN_MAX_CHANNELS)
413 return -ENODEV;
415 slot = isdn_ppp_get_slot();
416 if (slot < 0) {
417 return -EBUSY;
419 is = file->private_data = ippp_table[slot];
421 if (is->debug & 0x1)
422 printk(KERN_DEBUG "ippp, open, slot: %d, minor: %d, state: %04x\n", slot, min, is->state);
424 /* compression stuff */
425 is->compressor = NULL;
426 is->decomp_stat = is->comp_stat = NULL;
427 is->link_compressor = NULL;
428 is->link_decomp_stat = is->link_comp_stat = NULL;
430 is->lp = NULL;
431 is->mp_seqno = 0; /* MP sequence number */
432 is->pppcfg = 0; /* ppp configuration */
433 is->mpppcfg = 0; /* mppp configuration */
434 is->range = 0x1000000; /* MP: 24 bit range */
435 is->last_link_seqno = -1; /* MP: maybe set to Bundle-MIN, when joining a bundle ?? */
436 is->unit = -1; /* set, when we have our interface */
437 is->mru = 1524; /* MRU, default 1524 */
438 is->maxcid = 16; /* VJ: maxcid */
439 is->tk = current;
440 is->wq = NULL; /* read() wait queue */
441 is->wq1 = NULL; /* select() wait queue */
442 is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
443 is->last = is->rq;
444 is->minor = min;
445 #ifdef CONFIG_ISDN_PPP_VJ
447 * VJ header compression init
449 is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */
450 #endif
452 is->state = IPPP_OPEN;
454 return 0;
458 * release ippp device
460 void
461 isdn_ppp_release(int min, struct file *file)
463 int i;
464 struct ippp_struct *is;
466 if (min < 0 || min >= ISDN_MAX_CHANNELS)
467 return;
468 is = file->private_data;
470 if (is->debug & 0x1)
471 printk(KERN_DEBUG "ippp: release, minor: %d %lx\n", min, (long) is->lp);
473 if (is->lp) { /* a lp address says: this link is still up */
474 isdn_net_dev *p = is->lp->netdev;
476 is->state &= ~IPPP_CONNECT; /* -> effect: no call of wakeup */
478 * isdn_net_hangup() calls isdn_ppp_free()
479 * isdn_ppp_free() sets is->lp to NULL and lp->ppp_slot to -1
480 * removing the IPPP_CONNECT flag omits calling of isdn_ppp_wakeup_daemon()
482 isdn_net_hangup(&p->dev);
484 for (i = 0; i < NUM_RCV_BUFFS; i++) {
485 if (is->rq[i].buf) {
486 kfree(is->rq[i].buf);
487 is->rq[i].buf = NULL;
490 is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
491 is->last = is->rq;
493 #ifdef CONFIG_ISDN_PPP_VJ
494 slhc_free(is->slcomp);
495 is->slcomp = NULL;
496 #endif
498 is->state = 0;
502 * get_arg .. ioctl helper
504 static int
505 get_arg(void *b, void *val, int len)
507 if (len <= 0)
508 len = sizeof(unsigned long);
509 if (copy_from_user((void *) val, b, len))
510 return -EFAULT;
511 return 0;
515 * set arg .. ioctl helper
517 static int
518 set_arg(void *b, unsigned long val, void *str)
520 if (!str) {
521 if (copy_to_user(b, (void *) &val, 4))
522 return -EFAULT;
523 } else {
524 if (copy_to_user(b, str, val))
525 return -EFAULT;
527 return 0;
531 * ippp device ioctl
534 isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
536 unsigned long val;
537 int num,r;
538 struct ippp_struct *is;
539 isdn_net_local *lp;
541 is = (struct ippp_struct *) file->private_data;
542 lp = is->lp;
544 if (is->debug & 0x1)
545 printk(KERN_DEBUG "isdn_ppp_ioctl: minor: %d cmd: %x state: %x\n", min, cmd, is->state);
547 if (!(is->state & IPPP_OPEN))
548 return -EINVAL;
550 switch (cmd) {
551 case PPPIOCBUNDLE:
552 #ifdef CONFIG_ISDN_MPP
553 if (!(is->state & IPPP_CONNECT))
554 return -EINVAL;
555 if ((r = get_arg((void *) arg, &val, 0)))
556 return r;
557 printk(KERN_DEBUG "iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n",
558 (int) min, (int) is->unit, (int) val);
559 return isdn_ppp_bundle(is, val);
560 #else
561 return -1;
562 #endif
563 break;
564 case PPPIOCGUNIT: /* get ppp/isdn unit number */
565 if ((r = set_arg((void *) arg, is->unit, NULL)))
566 return r;
567 break;
568 case PPPIOCGMPFLAGS: /* get configuration flags */
569 if ((r = set_arg((void *) arg, is->mpppcfg, NULL)))
570 return r;
571 break;
572 case PPPIOCSMPFLAGS: /* set configuration flags */
573 if ((r = get_arg((void *) arg, &val, 0)))
574 return r;
575 is->mpppcfg = val;
576 break;
577 case PPPIOCGFLAGS: /* get configuration flags */
578 if ((r = set_arg((void *) arg, is->pppcfg, NULL)))
579 return r;
580 break;
581 case PPPIOCSFLAGS: /* set configuration flags */
582 if ((r = get_arg((void *) arg, &val, 0))) {
583 return r;
585 if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) {
586 if (lp) {
587 lp->netdev->dev.tbusy = 0;
588 mark_bh(NET_BH); /* OK .. we are ready to send buffers */
591 is->pppcfg = val;
592 break;
593 #if 0
594 case PPPIOCGSTAT: /* read PPP statistic information */
595 break;
596 #endif
597 case PPPIOCGIDLE: /* get idle time information */
598 if (lp) {
599 struct ppp_idle pidle;
600 pidle.xmit_idle = pidle.recv_idle = lp->huptimer;
601 if ((r = set_arg((void *) arg, sizeof(struct ppp_idle), &pidle)))
602 return r;
604 break;
605 case PPPIOCSMRU: /* set receive unit size for PPP */
606 if ((r = get_arg((void *) arg, &val, 0)))
607 return r;
608 is->mru = val;
609 break;
610 case PPPIOCSMPMRU:
611 break;
612 case PPPIOCSMPMTU:
613 break;
614 case PPPIOCSMAXCID: /* set the maximum compression slot id */
615 if ((r = get_arg((void *) arg, &val, 0)))
616 return r;
617 val++;
618 if (is->maxcid != val) {
619 #ifdef CONFIG_ISDN_PPP_VJ
620 struct slcompress *sltmp;
621 #endif
622 if (is->debug & 0x1)
623 printk(KERN_DEBUG "ippp, ioctl: changed MAXCID to %ld\n", val);
624 is->maxcid = val;
625 #ifdef CONFIG_ISDN_PPP_VJ
626 sltmp = slhc_init(16, val);
627 if (!sltmp) {
628 printk(KERN_ERR "ippp, can't realloc slhc struct\n");
629 return -ENOMEM;
631 if (is->slcomp)
632 slhc_free(is->slcomp);
633 is->slcomp = sltmp;
634 #endif
636 break;
637 case PPPIOCGDEBUG:
638 if ((r = set_arg((void *) arg, is->debug, 0)))
639 return r;
640 break;
641 case PPPIOCSDEBUG:
642 if ((r = get_arg((void *) arg, &val, 0)))
643 return r;
644 is->debug = val;
645 break;
646 case PPPIOCGCOMPRESSORS:
648 unsigned long protos = 0;
649 struct isdn_ppp_compressor *ipc = ipc_head;
650 while(ipc) {
651 protos |= (0x1<<ipc->num);
652 ipc = ipc->next;
654 if ((r = set_arg((void *) arg, protos, 0)))
655 return r;
657 break;
658 case PPPIOCSCOMPRESSOR:
659 if ((r = get_arg((void *) arg, &num, sizeof(int))))
660 return r;
661 return isdn_ppp_set_compressor(is, num);
662 break;
663 case PPPIOCGCALLINFO:
665 struct pppcallinfo pci;
666 memset((char *) &pci,0,sizeof(struct pppcallinfo));
667 if(lp)
669 strncpy(pci.local_num,lp->msn,63);
670 if(lp->dial) {
671 strncpy(pci.remote_num,lp->dial->num,63);
673 pci.charge_units = lp->charge;
674 if(lp->outgoing)
675 pci.calltype = CALLTYPE_OUTGOING;
676 else
677 pci.calltype = CALLTYPE_INCOMING;
678 if(lp->flags & ISDN_NET_CALLBACK)
679 pci.calltype |= CALLTYPE_CALLBACK;
681 return set_arg((void *)arg,sizeof(struct pppcallinfo),&pci);
683 default:
684 break;
686 return 0;
689 unsigned int
690 isdn_ppp_poll(struct file *file, poll_table * wait)
692 unsigned int mask;
693 struct ippp_buf_queue *bf;
694 struct ippp_buf_queue *bl;
695 unsigned long flags;
696 struct ippp_struct *is;
698 is = file->private_data;
700 if (is->debug & 0x2)
701 printk(KERN_DEBUG "isdn_ppp_poll: minor: %d\n",
702 MINOR(file->f_dentry->d_inode->i_rdev));
704 poll_wait(file, &is->wq, wait);
706 if (!(is->state & IPPP_OPEN)) {
707 printk(KERN_DEBUG "isdn_ppp: device not open\n");
708 return POLLERR;
710 /* we're always ready to send .. */
711 mask = POLLOUT | POLLWRNORM;
713 save_flags(flags);
714 cli();
715 bl = is->last;
716 bf = is->first;
718 * if IPPP_NOBLOCK is set we return even if we have nothing to read
720 if (bf->next != bl || (is->state & IPPP_NOBLOCK)) {
721 is->state &= ~IPPP_NOBLOCK;
722 mask |= POLLIN | POLLRDNORM;
724 restore_flags(flags);
725 return mask;
729 * fill up isdn_ppp_read() queue ..
732 static int
733 isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot)
735 struct ippp_buf_queue *bf,
736 *bl;
737 unsigned long flags;
738 unsigned char *nbuf;
739 struct ippp_struct *is;
741 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
742 printk(KERN_WARNING "ippp: illegal slot.\n");
743 return 0;
745 is = ippp_table[slot];
747 if (!(is->state & IPPP_CONNECT)) {
748 printk(KERN_DEBUG "ippp: device not activated.\n");
749 return 0;
751 nbuf = (unsigned char *) kmalloc(len + 4, GFP_ATOMIC);
752 if (!nbuf) {
753 printk(KERN_WARNING "ippp: Can't alloc buf\n");
754 return 0;
756 nbuf[0] = PPP_ALLSTATIONS;
757 nbuf[1] = PPP_UI;
758 nbuf[2] = proto >> 8;
759 nbuf[3] = proto & 0xff;
760 memcpy(nbuf + 4, buf, len);
762 save_flags(flags);
763 cli();
765 bf = is->first;
766 bl = is->last;
768 if (bf == bl) {
769 printk(KERN_WARNING "ippp: Queue is full; discarding first buffer\n");
770 bf = bf->next;
771 kfree(bf->buf);
772 is->first = bf;
774 bl->buf = (char *) nbuf;
775 bl->len = len + 4;
777 is->last = bl->next;
778 restore_flags(flags);
780 if (is->wq)
781 wake_up_interruptible(&is->wq);
783 return len;
787 * read() .. non-blocking: ipppd calls it only after select()
788 * reports, that there is data
792 isdn_ppp_read(int min, struct file *file, char *buf, int count)
794 struct ippp_struct *is;
795 struct ippp_buf_queue *b;
796 int r;
797 unsigned long flags;
798 unsigned char *save_buf;
800 is = file->private_data;
802 if (!(is->state & IPPP_OPEN))
803 return 0;
805 if ((r = verify_area(VERIFY_WRITE, (void *) buf, count)))
806 return r;
808 save_flags(flags);
809 cli();
811 b = is->first->next;
812 save_buf = b->buf;
813 if (!save_buf) {
814 restore_flags(flags);
815 return -EAGAIN;
817 if (b->len < count)
818 count = b->len;
819 b->buf = NULL;
820 is->first = b;
822 restore_flags(flags);
824 copy_to_user(buf, save_buf, count);
825 kfree(save_buf);
827 return count;
831 * ipppd wanna write a packet to the card .. non-blocking
835 isdn_ppp_write(int min, struct file *file, const char *buf, int count)
837 isdn_net_local *lp;
838 struct ippp_struct *is;
839 int proto;
840 unsigned char protobuf[4];
842 is = file->private_data;
844 if (!(is->state & IPPP_CONNECT))
845 return 0;
847 lp = is->lp;
849 /* -> push it directly to the lowlevel interface */
851 if (!lp)
852 printk(KERN_DEBUG "isdn_ppp_write: lp == NULL\n");
853 else {
855 * Don't reset huptimer for
856 * LCP packets. (Echo requests).
858 if (copy_from_user(protobuf, buf, 4))
859 return -EFAULT;
860 proto = PPP_PROTOCOL(protobuf);
861 if (proto != PPP_LCP)
862 lp->huptimer = 0;
864 if (lp->isdn_device < 0 || lp->isdn_channel < 0)
865 return 0;
867 if (dev->drv[lp->isdn_device]->running && lp->dialstate == 0 &&
868 (lp->flags & ISDN_NET_CONNECTED)) {
869 int cnt;
870 struct sk_buff *skb;
871 skb = dev_alloc_skb(count);
872 if (!skb) {
873 printk(KERN_WARNING "isdn_ppp_write: out of memory!\n");
874 return count;
876 if (copy_from_user(skb_put(skb, count), buf, count))
877 return -EFAULT;
878 if (is->debug & 0x40) {
879 printk(KERN_DEBUG "ppp xmit: len %d\n", (int) skb->len);
880 isdn_ppp_frame_log("xmit", skb->data, skb->len, 32);
882 if ((cnt = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb)) != count) {
883 if (lp->sav_skb) {
884 dev_kfree_skb(lp->sav_skb);
885 printk(KERN_INFO "isdn_ppp_write: freeing sav_skb (%d,%d)!\n", cnt, count);
886 } else
887 printk(KERN_INFO "isdn_ppp_write: Can't write PPP frame to LL (%d,%d)!\n", cnt, count);
888 lp->sav_skb = skb;
892 return count;
896 * init memory, structures etc.
900 isdn_ppp_init(void)
902 int i,
905 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
906 if (!(ippp_table[i] = (struct ippp_struct *)
907 kmalloc(sizeof(struct ippp_struct), GFP_KERNEL))) {
908 printk(KERN_WARNING "isdn_ppp_init: Could not alloc ippp_table\n");
909 for (j = 0; j < i; j++)
910 kfree(ippp_table[i]);
911 return -1;
913 memset((char *) ippp_table[i], 0, sizeof(struct ippp_struct));
914 ippp_table[i]->state = 0;
915 ippp_table[i]->first = ippp_table[i]->rq + NUM_RCV_BUFFS - 1;
916 ippp_table[i]->last = ippp_table[i]->rq;
918 for (j = 0; j < NUM_RCV_BUFFS; j++) {
919 ippp_table[i]->rq[j].buf = NULL;
920 ippp_table[i]->rq[j].last = ippp_table[i]->rq +
921 (NUM_RCV_BUFFS + j - 1) % NUM_RCV_BUFFS;
922 ippp_table[i]->rq[j].next = ippp_table[i]->rq + (j + 1) % NUM_RCV_BUFFS;
925 return 0;
928 void
929 isdn_ppp_cleanup(void)
931 int i;
933 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
934 kfree(ippp_table[i]);
938 * get the PPP protocol header and pull skb
940 static int isdn_ppp_strip_proto(struct sk_buff *skb)
942 int proto;
943 if (skb->data[0] & 0x1) {
944 proto = skb->data[0];
945 skb_pull(skb, 1); /* protocol ID is only 8 bit */
946 } else {
947 proto = ((int) skb->data[0] << 8) + skb->data[1];
948 skb_pull(skb, 2);
950 return proto;
955 * handler for incoming packets on a syncPPP interface
957 void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb)
959 struct ippp_struct *is;
960 int proto;
962 is = ippp_table[lp->ppp_slot];
964 if (is->debug & 0x4) {
965 printk(KERN_DEBUG "ippp_receive: len: %d\n", (int) skb->len);
966 isdn_ppp_frame_log("receive", skb->data, skb->len, 32);
968 if (net_dev->local->master) {
969 printk(KERN_WARNING "isdn_ppp_receice: net_dev != master\n");
970 net_dev = ((isdn_net_local *) net_dev->local->master->priv)->netdev;
972 if (skb->data[0] == 0xff && skb->data[1] == 0x03)
973 skb_pull(skb, 2);
974 else if (is->pppcfg & SC_REJ_COMP_AC) {
975 dev_kfree_skb(skb);
976 return; /* discard it silently */
979 proto = isdn_ppp_strip_proto(skb);
981 #ifdef CONFIG_ISDN_MPP
982 if (!(is->mpppcfg & SC_REJ_MP_PROT)) {
983 int sqno_end;
985 if(proto == PPP_LINK_COMP) {
986 printk(KERN_DEBUG "received single link compressed frame\n");
987 skb = isdn_ppp_decompress(skb,is,NULL);
988 if(!skb)
989 return;
990 proto = isdn_ppp_strip_proto(skb);
993 if (proto == PPP_MP) {
994 isdn_net_local *lpq;
995 long sqno, min_sqno, tseq;
997 u_char BEbyte = skb->data[0];
998 if (is->debug & 0x8)
999 printk(KERN_DEBUG "recv: %d/%04x/%d -> %02x %02x %02x %02x %02x %02x\n", lp->ppp_slot, proto,
1000 (int) skb->len, (int) skb->data[0], (int) skb->data[1], (int) skb->data[2],
1001 (int) skb->data[3], (int) skb->data[4], (int) skb->data[5]);
1002 if (!(is->mpppcfg & SC_IN_SHORT_SEQ)) {
1003 sqno = ((int) skb->data[1] << 16) + ((int) skb->data[2] << 8) + (int) skb->data[3];
1004 skb_pull(skb, 4);
1005 } else {
1006 sqno = (((int) skb->data[0] & 0xf) << 8) + (int) skb->data[1];
1007 skb_pull(skb, 2);
1011 * new sequence number lower than last number? (this is only allowed
1012 * for overflow case)
1014 if ((tseq = is->last_link_seqno) >= sqno) {
1015 int range = is->range;
1016 if (tseq + 1024 < range + sqno) /* redundancy check .. not MP conform */
1017 printk(KERN_WARNING "isdn_ppp_receive, MP, detected overflow with sqno: %ld, last: %ld !!!\n", sqno, tseq);
1018 else {
1019 sqno += range;
1020 is->last_link_seqno = sqno;
1022 } else {
1023 /* here, we should also add an redundancy check */
1024 is->last_link_seqno = sqno;
1028 * step over all links to find lowest link number
1030 for (min_sqno = LONG_MAX, lpq = net_dev->queue;;) {
1031 long lls = ippp_table[lpq->ppp_slot]->last_link_seqno;
1032 if (lls >= 0 && lls < min_sqno)
1033 min_sqno = lls;
1034 lpq = lpq->next;
1035 if (lpq == net_dev->queue)
1036 break;
1040 * for the case, that the last frame numbers of all
1041 * links are overflowed: mask/reduce the sequenece number to
1042 * 'normal' numbering.
1044 if (min_sqno >= ippp_table[lpq->ppp_slot]->range) {
1045 int mask = ippp_table[lpq->ppp_slot]->range-1; /* range is power of two, so a mask will do the job */
1046 isdn_ppp_mask_queue(net_dev, mask);
1047 net_dev->ib.next_num &= mask;
1049 struct sqqueue *q = net_dev->ib.sq;
1050 while (q) {
1051 q->sqno_start &= mask;
1052 q->sqno_end &= mask;
1055 min_sqno &= mask;
1056 for (lpq = net_dev->queue;;) {
1057 ippp_table[lpq->ppp_slot]->last_link_seqno &= mask;
1058 lpq = lpq->next;
1059 if (lpq == net_dev->queue)
1060 break;
1063 if ((BEbyte & (MP_BEGIN_FRAG | MP_END_FRAG)) != (MP_BEGIN_FRAG | MP_END_FRAG)) {
1064 static int dmes = 0;
1065 if( !dmes ) {
1066 printk(KERN_DEBUG "ippp: trying ;) to fill mp_queue %d .. UNTESTED!!\n", lp->ppp_slot);
1067 dmes = 1;
1069 if ((sqno_end = isdn_ppp_fill_mpqueue(net_dev, &skb, BEbyte, &sqno, min_sqno)) < 0) {
1070 net_dev->ib.modify = 1; /* block timeout-timer */
1071 isdn_ppp_cleanup_sqqueue(net_dev, lp, min_sqno);
1072 net_dev->ib.modify = 0;
1073 return; /* no packet complete */
1075 } else
1076 sqno_end = sqno;
1078 if (is->debug & 0x40)
1079 printk(KERN_DEBUG "min_sqno: %ld sqno_end %d next: %ld\n", min_sqno, sqno_end, net_dev->ib.next_num);
1082 * MP buffer management .. reorders incoming packets ..
1083 * lotsa mem-copies and not heavily tested.
1085 * first check whether there is more than one link in the bundle
1086 * then check whether the number is in order
1088 net_dev->ib.modify = 1; /* block timeout-timer */
1089 if (net_dev->ib.bundled && net_dev->ib.next_num != sqno) {
1091 * packet is not 'in order'
1093 struct sqqueue *q;
1095 q = (struct sqqueue *) kmalloc(sizeof(struct sqqueue), GFP_ATOMIC);
1096 if (!q) {
1097 net_dev->ib.modify = 0;
1098 printk(KERN_WARNING "ippp/MPPP: Bad! Can't alloc sq node!\n");
1099 dev_kfree_skb(skb);
1100 return; /* discard */
1102 q->skb = skb;
1103 q->sqno_end = sqno_end;
1104 q->sqno_start = sqno;
1105 q->timer = jiffies + (ISDN_TIMER_1SEC) * 5; /* timeout after 5 seconds */
1107 if (!net_dev->ib.sq) {
1108 net_dev->ib.sq = q;
1109 q->next = NULL;
1110 } else {
1111 struct sqqueue *ql = net_dev->ib.sq;
1112 if (ql->sqno_start > q->sqno_start) {
1113 q->next = ql;
1114 net_dev->ib.sq = q;
1115 } else {
1116 while (ql->next && ql->next->sqno_start < q->sqno_start)
1117 ql = ql->next;
1118 q->next = ql->next;
1119 ql->next = q;
1122 } else {
1124 * packet was 'in order' .. push it higher
1126 net_dev->ib.next_num = sqno_end + 1;
1127 proto = isdn_ppp_strip_proto(skb);
1128 isdn_ppp_push_higher(net_dev, lp, skb, proto);
1130 isdn_ppp_cleanup_sqqueue(net_dev, lp, min_sqno);
1131 net_dev->ib.modify = 0;
1133 } else
1134 isdn_ppp_push_higher(net_dev, lp, skb, proto);
1135 } else
1136 #endif
1137 isdn_ppp_push_higher(net_dev, lp, skb, proto);
1141 * push frame to higher layers
1142 * note: net_dev has to be master net_dev
1144 static void
1145 isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb, int proto)
1147 struct device *dev = &net_dev->dev;
1148 struct ippp_struct *is = ippp_table[lp->ppp_slot];
1150 if (is->debug & 0x10) {
1151 printk(KERN_DEBUG "push, skb %d %04x\n", (int) skb->len, proto);
1152 isdn_ppp_frame_log("rpush", skb->data, skb->len, 32);
1155 if(proto == PPP_COMP) {
1156 if(!lp->master)
1157 skb = isdn_ppp_decompress(skb,is,is);
1158 else
1159 skb = isdn_ppp_decompress(skb,is,ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot]);
1160 if(!skb)
1161 return;
1162 proto = isdn_ppp_strip_proto(skb);
1165 switch (proto) {
1166 case PPP_IPX: /* untested */
1167 if (is->debug & 0x20)
1168 printk(KERN_DEBUG "isdn_ppp: IPX\n");
1169 skb->dev = dev;
1170 skb->mac.raw = skb->data;
1171 skb->protocol = htons(ETH_P_IPX);
1172 break;
1173 #ifdef CONFIG_ISDN_PPP_VJ
1174 case PPP_VJC_UNCOMP:
1175 if (is->debug & 0x20)
1176 printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n");
1177 if (slhc_remember(ippp_table[net_dev->local->ppp_slot]->slcomp, skb->data, skb->len) <= 0) {
1178 printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n");
1179 net_dev->local->stats.rx_dropped++;
1180 dev_kfree_skb(skb);
1181 return;
1183 #endif
1184 case PPP_IP:
1185 if (is->debug & 0x20)
1186 printk(KERN_DEBUG "isdn_ppp: IP\n");
1187 skb->dev = dev;
1188 skb->mac.raw = skb->data;
1189 skb->protocol = htons(ETH_P_IP);
1190 break;
1191 case PPP_VJC_COMP:
1192 if (is->debug & 0x20)
1193 printk(KERN_DEBUG "isdn_ppp: VJC_COMP\n");
1194 #ifdef CONFIG_ISDN_PPP_VJ
1196 struct sk_buff *skb_old = skb;
1197 int pkt_len;
1198 skb = dev_alloc_skb(skb_old->len + 40);
1200 if (!skb) {
1201 printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
1202 net_dev->local->stats.rx_dropped++;
1203 dev_kfree_skb(skb_old);
1204 return;
1206 skb->dev = dev;
1207 skb_put(skb, skb_old->len + 40);
1208 memcpy(skb->data, skb_old->data, skb_old->len);
1209 skb->mac.raw = skb->data;
1210 pkt_len = slhc_uncompress(ippp_table[net_dev->local->ppp_slot]->slcomp,
1211 skb->data, skb_old->len);
1212 dev_kfree_skb(skb_old);
1213 if (pkt_len < 0) {
1214 dev_kfree_skb(skb);
1215 lp->stats.rx_dropped++;
1216 return;
1218 skb_trim(skb, pkt_len);
1219 skb->protocol = htons(ETH_P_IP);
1221 #else
1222 printk(KERN_INFO "isdn: Ooopsa .. VJ-Compression support not compiled into isdn driver.\n");
1223 lp->stats.rx_dropped++;
1224 dev_kfree_skb(skb);
1225 return;
1226 #endif
1227 break;
1228 case PPP_CCP:
1229 isdn_ppp_receive_ccp(net_dev,lp,skb);
1230 /* fall through */
1231 default:
1232 isdn_ppp_fill_rq(skb->data, skb->len, proto, lp->ppp_slot); /* push data to pppd device */
1233 dev_kfree_skb(skb);
1234 return;
1237 netif_rx(skb);
1238 /* net_dev->local->stats.rx_packets++; *//* done in isdn_net.c */
1239 /* Reset hangup-timer */
1240 lp->huptimer = 0;
1242 return;
1246 * isdn_ppp_skb_push ..
1247 * checks whether we have enough space at the beginning of the SKB
1248 * and allocs a new SKB if necessary
1250 static unsigned char *isdn_ppp_skb_push(struct sk_buff **skb_p,int len)
1252 struct sk_buff *skb = *skb_p;
1254 if(skb_headroom(skb) < len) {
1255 printk(KERN_ERR "isdn_ppp_skb_push:under %d %d\n",skb_headroom(skb),len);
1256 dev_kfree_skb(skb);
1257 return NULL;
1259 return skb_push(skb,len);
1264 * send ppp frame .. we expect a PIDCOMPressable proto --
1265 * (here: currently always PPP_IP,PPP_VJC_COMP,PPP_VJC_UNCOMP)
1267 * VJ compression may change skb pointer!!! .. requeue with old
1268 * skb isn't allowed!!
1272 isdn_ppp_xmit(struct sk_buff *skb, struct device *dev)
1274 struct device *mdev = ((isdn_net_local *) (dev->priv))->master; /* get master (for redundancy) */
1275 isdn_net_local *lp,*mlp;
1276 isdn_net_dev *nd;
1277 unsigned int proto = PPP_IP; /* 0x21 */
1278 struct ippp_struct *ipt,*ipts;
1280 if (mdev)
1281 mlp = (isdn_net_local *) (mdev->priv);
1282 else {
1283 mdev = dev;
1284 mlp = (isdn_net_local *) (dev->priv);
1286 nd = mlp->netdev; /* get master lp */
1287 ipts = ippp_table[mlp->ppp_slot];
1289 if (!(ipts->pppcfg & SC_ENABLE_IP)) { /* PPP connected ? */
1290 #ifdef ISDN_SYNCPPP_READDRESS
1291 if (!ipts->old_pa_addr)
1292 ipts->old_pa_addr = mdev->pa_addr;
1293 if (!ipts->old_pa_dstaddr)
1294 ipts->old_pa_dstaddr = mdev->pa_dstaddr;
1295 #endif
1296 if (ipts->debug & 0x1)
1297 printk(KERN_INFO "%s: IP frame delayed.\n", dev->name);
1298 return 1;
1301 switch (ntohs(skb->protocol)) {
1302 case ETH_P_IP:
1303 proto = PPP_IP;
1304 #ifdef ISDN_SYNCPPP_READDRESS
1305 if (ipts->old_pa_addr != mdev->pa_addr) {
1306 struct iphdr *ipfr;
1307 ipfr = (struct iphdr *) skb->data;
1308 if(ipts->debug & 0x4)
1309 printk(KERN_DEBUG "IF-address changed from %lx to %lx\n", ipts->old_pa_addr, mdev->pa_addr);
1310 if (ipfr->version == 4) {
1311 if (ipfr->saddr == ipts->old_pa_addr) {
1312 printk(KERN_DEBUG "readdressing %lx to %lx\n", ipfr->saddr, mdev->pa_addr);
1313 ipfr->saddr = mdev->pa_addr;
1317 /* dstaddr change not so important */
1318 #endif
1319 break;
1320 case ETH_P_IPX:
1321 proto = PPP_IPX; /* untested */
1322 break;
1323 default:
1324 dev_kfree_skb(skb);
1325 printk(KERN_ERR "isdn_ppp: skipped frame with unsupported protocoll: %#x.\n", skb->protocol);
1326 return 0;
1329 lp = nd->queue; /* get lp on top of queue */
1331 if (lp->sav_skb) { /* find a non-busy device */
1332 isdn_net_local *nlp = lp->next;
1333 while (lp->sav_skb) {
1334 if (lp == nlp)
1335 return 1;
1336 nlp = nd->queue = nd->queue->next;
1338 lp = nlp;
1340 ipt = ippp_table[lp->ppp_slot];
1342 lp->huptimer = 0;
1345 * after this line .. requeueing in the device queue is no longer allowed!!!
1348 /* Pull off the fake header we stuck on earlier to keep
1349 * the fragemntation code happy.
1350 * this will break the ISDN_SYNCPPP_READDRESS hack a few lines
1351 * above. So, enabling this is no longer allowed
1353 skb_pull(skb,IPPP_MAX_HEADER);
1355 if (ipt->debug & 0x4)
1356 printk(KERN_DEBUG "xmit skb, len %d\n", (int) skb->len);
1358 #ifdef CONFIG_ISDN_PPP_VJ
1359 if (proto == PPP_IP && ipts->pppcfg & SC_COMP_TCP) { /* ipts here? probably yes, but check this again */
1360 struct sk_buff *new_skb;
1362 new_skb = dev_alloc_skb(skb->len);
1363 if (new_skb) {
1364 u_char *buf;
1365 int pktlen;
1367 new_skb->dev = skb->dev;
1368 skb_put(new_skb, skb->len);
1369 buf = skb->data;
1371 pktlen = slhc_compress(ipts->slcomp, skb->data, skb->len, new_skb->data,
1372 &buf, !(ipts->pppcfg & SC_NO_TCP_CCID));
1374 if (buf != skb->data) {
1375 if (new_skb->data != buf)
1376 printk(KERN_ERR "isdn_ppp: FATAL error after slhc_compress!!\n");
1377 dev_kfree_skb(skb);
1378 skb = new_skb;
1379 } else {
1380 dev_kfree_skb(new_skb);
1383 skb_trim(skb, pktlen);
1384 if (skb->data[0] & SL_TYPE_COMPRESSED_TCP) { /* cslip? style -> PPP */
1385 proto = PPP_VJC_COMP;
1386 skb->data[0] ^= SL_TYPE_COMPRESSED_TCP;
1387 } else {
1388 if (skb->data[0] >= SL_TYPE_UNCOMPRESSED_TCP)
1389 proto = PPP_VJC_UNCOMP;
1390 skb->data[0] = (skb->data[0] & 0x0f) | 0x40;
1394 #endif
1397 * normal or bundle compression
1399 skb = isdn_ppp_compress(skb,&proto,ipt,ipts,0);
1401 if (ipt->debug & 0x24)
1402 printk(KERN_DEBUG "xmit2 skb, len %d, proto %04x\n", (int) skb->len, proto);
1404 #ifdef CONFIG_ISDN_MPP
1405 if (ipt->mpppcfg & SC_MP_PROT) {
1406 /* we get mp_seqno from static isdn_net_local */
1407 long mp_seqno = ipts->mp_seqno;
1408 ipts->mp_seqno++;
1409 nd->queue = nd->queue->next;
1410 if (ipt->mpppcfg & SC_OUT_SHORT_SEQ) {
1411 unsigned char *data = isdn_ppp_skb_push(&skb, 3);
1412 if(!data)
1413 return 0;
1414 mp_seqno &= 0xfff;
1415 data[0] = MP_BEGIN_FRAG | MP_END_FRAG | ((mp_seqno >> 8) & 0xf); /* (B)egin & (E)ndbit .. */
1416 data[1] = mp_seqno & 0xff;
1417 data[2] = proto; /* PID compression */
1418 } else {
1419 unsigned char *data = isdn_ppp_skb_push(&skb, 5);
1420 if(!data)
1421 return 0;
1422 data[0] = MP_BEGIN_FRAG | MP_END_FRAG; /* (B)egin & (E)ndbit .. */
1423 data[1] = (mp_seqno >> 16) & 0xff; /* sequence number: 24bit */
1424 data[2] = (mp_seqno >> 8) & 0xff;
1425 data[3] = (mp_seqno >> 0) & 0xff;
1426 data[4] = proto; /* PID compression */
1428 proto = PPP_MP; /* MP Protocol, 0x003d */
1430 #endif
1433 * 'link' compression
1435 skb = isdn_ppp_compress(skb,&proto,ipt,ipts,1);
1437 if( (ipt->pppcfg & SC_COMP_PROT) && (proto <= 0xff) ) {
1438 unsigned char *data = isdn_ppp_skb_push(&skb,1);
1439 if(!data)
1440 return 0;
1441 data[0] = proto & 0xff;
1443 else {
1444 unsigned char *data = isdn_ppp_skb_push(&skb,2);
1445 if(!data)
1446 return 0;
1447 data[0] = (proto >> 8) & 0xff;
1448 data[1] = proto & 0xff;
1450 if(!(ipt->pppcfg & SC_COMP_AC)) {
1451 unsigned char *data = isdn_ppp_skb_push(&skb,2);
1452 if(!data)
1453 return 0;
1454 data[0] = 0xff; /* All Stations */
1455 data[1] = 0x03; /* Unnumbered information */
1458 /* tx-stats are now updated via BSENT-callback */
1460 if (ipts->debug & 0x40) {
1461 printk(KERN_DEBUG "skb xmit: len: %d\n", (int) skb->len);
1462 isdn_ppp_frame_log("xmit", skb->data, skb->len, 32);
1464 if (isdn_net_send_skb(dev, lp, skb)) {
1465 if (lp->sav_skb) { /* whole sav_skb processing with disabled IRQs ?? */
1466 printk(KERN_ERR "%s: whoops .. there is another stored skb!\n", dev->name);
1467 dev_kfree_skb(skb);
1468 } else
1469 lp->sav_skb = skb;
1471 return 0;
1474 #ifdef CONFIG_ISDN_MPP
1476 static void
1477 isdn_ppp_free_sqqueue(isdn_net_dev * p)
1479 struct sqqueue *q = p->ib.sq;
1481 p->ib.sq = NULL;
1482 while (q) {
1483 struct sqqueue *qn = q->next;
1484 if (q->skb)
1485 dev_kfree_skb(q->skb);
1486 kfree(q);
1487 q = qn;
1492 static void
1493 isdn_ppp_free_mpqueue(isdn_net_dev * p)
1495 struct mpqueue *q = p->mp_last;
1496 p->mp_last = NULL;
1498 while (q) {
1499 struct mpqueue *ql = q->next;
1500 dev_kfree_skb(q->skb);
1501 kfree(q);
1502 q = ql;
1506 static int
1507 isdn_ppp_bundle(struct ippp_struct *is, int unit)
1509 char ifn[IFNAMSIZ + 1];
1510 long flags;
1511 isdn_net_dev *p;
1512 isdn_net_local *lp,
1513 *nlp;
1515 sprintf(ifn, "ippp%d", unit);
1516 p = isdn_net_findif(ifn);
1517 if (!p)
1518 return -1;
1520 isdn_timer_ctrl(ISDN_TIMER_IPPP, 1); /* enable timer for ippp/MP */
1522 save_flags(flags);
1523 cli();
1525 nlp = is->lp;
1527 lp = p->queue;
1528 p->ib.bundled = 1;
1529 nlp->last = lp->last;
1530 lp->last->next = nlp;
1531 lp->last = nlp;
1532 nlp->next = lp;
1533 p->queue = nlp;
1535 ippp_table[nlp->ppp_slot]->unit = ippp_table[lp->ppp_slot]->unit;
1536 /* maybe also SC_CCP stuff */
1537 ippp_table[nlp->ppp_slot]->pppcfg |= ippp_table[lp->ppp_slot]->pppcfg &
1538 (SC_ENABLE_IP | SC_NO_TCP_CCID | SC_REJ_COMP_TCP);
1540 ippp_table[nlp->ppp_slot]->mpppcfg |= ippp_table[lp->ppp_slot]->mpppcfg &
1541 (SC_MP_PROT | SC_REJ_MP_PROT | SC_OUT_SHORT_SEQ | SC_IN_SHORT_SEQ);
1542 #if 0
1543 if (ippp_table[nlp->ppp_slot]->mpppcfg != ippp_table[lp->ppp_slot]->mpppcfg) {
1544 printk(KERN_WARNING "isdn_ppp_bundle: different MP options %04x and %04x\n",
1545 ippp_table[nlp->ppp_slot]->mpppcfg, ippp_table[lp->ppp_slot]->mpppcfg);
1547 #endif
1549 restore_flags(flags);
1550 return 0;
1554 static void
1555 isdn_ppp_mask_queue(isdn_net_dev * dev, long mask)
1557 struct mpqueue *q = dev->mp_last;
1558 while (q) {
1559 q->sqno &= mask;
1560 q = q->next;
1564 static int
1565 isdn_ppp_fill_mpqueue(isdn_net_dev * dev, struct sk_buff **skb, int BEbyte, long *sqnop, int min_sqno)
1567 struct mpqueue *qe,
1568 *q1,
1570 long cnt,
1571 flags;
1572 int pktlen,
1573 sqno_end;
1574 int sqno = *sqnop;
1576 q1 = (struct mpqueue *) kmalloc(sizeof(struct mpqueue), GFP_ATOMIC);
1577 if (!q1) {
1578 printk(KERN_WARNING "isdn_ppp_fill_mpqueue: Can't alloc struct memory.\n");
1579 save_flags(flags);
1580 cli();
1581 isdn_ppp_cleanup_mpqueue(dev, min_sqno);
1582 restore_flags(flags);
1583 return -1;
1585 q1->skb = *skb;
1586 q1->sqno = sqno;
1587 q1->BEbyte = BEbyte;
1588 q1->time = jiffies;
1590 save_flags(flags);
1591 cli();
1593 if (!(q = dev->mp_last)) {
1594 dev->mp_last = q1;
1595 q1->next = NULL;
1596 q1->last = NULL;
1597 isdn_ppp_cleanup_mpqueue(dev, min_sqno); /* not necessary */
1598 restore_flags(flags);
1599 return -1; /* -1 is not an error. Just says, that this fragment hasn't complete a full frame */
1601 for (;;) { /* the faster way would be to step from the queue-end to the start */
1602 if (sqno > q->sqno) {
1603 if (q->next) {
1604 q = q->next;
1605 continue;
1607 q->next = q1;
1608 q1->next = NULL;
1609 q1->last = q;
1610 break;
1612 if (sqno == q->sqno)
1613 printk(KERN_WARNING "isdn_fill_mpqueue: illegal sqno received!!\n");
1614 q1->last = q->last;
1615 q1->next = q;
1616 if (q->last) {
1617 q->last->next = q1;
1618 } else
1619 dev->mp_last = q1;
1620 q->last = q1;
1621 break;
1624 /* now we check whether we completed a packet with this fragment */
1625 pktlen = -q1->skb->len;
1626 q = q1;
1627 cnt = q1->sqno;
1628 while (!(q->BEbyte & MP_END_FRAG)) {
1629 cnt++;
1630 if (!(q->next) || q->next->sqno != cnt) {
1631 isdn_ppp_cleanup_mpqueue(dev, min_sqno);
1632 restore_flags(flags);
1633 return -1;
1635 pktlen += q->skb->len;
1636 q = q->next;
1638 pktlen += q->skb->len;
1639 qe = q;
1641 q = q1;
1642 cnt = q1->sqno;
1643 while (!(q->BEbyte & MP_BEGIN_FRAG)) {
1644 cnt--;
1645 if (!(q->last) || q->last->sqno != cnt) {
1646 isdn_ppp_cleanup_mpqueue(dev, min_sqno);
1647 restore_flags(flags);
1648 return -1;
1650 pktlen += q->skb->len;
1651 q = q->last;
1653 pktlen += q->skb->len;
1655 if (q->last)
1656 q->last->next = qe->next;
1657 else
1658 dev->mp_last = qe->next;
1660 if (qe->next)
1661 qe->next->last = q->last;
1662 qe->next = NULL;
1663 sqno_end = qe->sqno;
1664 *sqnop = q->sqno;
1666 isdn_ppp_cleanup_mpqueue(dev, min_sqno);
1667 restore_flags(flags);
1669 *skb = dev_alloc_skb(pktlen + 40); /* not needed: +40 for VJ compression .. */
1671 if (!(*skb)) {
1672 while (q) {
1673 struct mpqueue *ql = q->next;
1674 dev_kfree_skb(q->skb);
1675 kfree(q);
1676 q = ql;
1678 return -2;
1680 cnt = 0;
1681 skb_put(*skb, pktlen);
1682 while (q) {
1683 struct mpqueue *ql = q->next;
1684 memcpy((*skb)->data + cnt, q->skb->data, q->skb->len);
1685 cnt += q->skb->len;
1686 dev_kfree_skb(q->skb);
1687 kfree(q);
1688 q = ql;
1691 return sqno_end;
1695 * check sq-queue, whether we have still buffered the next packet(s)
1696 * or packets with a sqno less or equal to min_sqno
1697 * net_dev: master netdevice , lp: 'real' local connection
1699 static void
1700 isdn_ppp_cleanup_sqqueue(isdn_net_dev * net_dev, isdn_net_local * lp, long min_sqno)
1702 struct sqqueue *q;
1704 while ((q = net_dev->ib.sq) && (q->sqno_start == net_dev->ib.next_num || q->sqno_end <= min_sqno)) {
1705 int proto;
1706 if (q->sqno_start != net_dev->ib.next_num) {
1707 printk(KERN_DEBUG "ippp: MP, stepping over missing frame: %ld\n", net_dev->ib.next_num);
1708 #ifdef CONFIG_ISDN_PPP_VJ
1709 slhc_toss(ippp_table[net_dev->local->ppp_slot]->slcomp);
1710 #endif
1712 proto = isdn_ppp_strip_proto(q->skb);
1713 isdn_ppp_push_higher(net_dev, lp, q->skb, proto);
1714 net_dev->ib.sq = q->next;
1715 net_dev->ib.next_num = q->sqno_end + 1;
1716 kfree(q);
1721 * remove stale packets from list
1723 static void
1724 isdn_ppp_cleanup_mpqueue(isdn_net_dev * dev, long min_sqno)
1726 #ifdef CONFIG_ISDN_PPP_VJ
1727 int toss = 0;
1728 #endif
1729 /* z.z einfaches aussortieren gammeliger pakete. Fuer die Zukunft:
1730 eventuell, solange vorne kein B-paket ist und sqno<=min_sqno: auch rauswerfen
1731 wenn sqno<min_sqno und Luecken vorhanden sind: auch weg (die koennen nicht mehr gefuellt werden)
1732 bei paketen groesser min_sqno: ueber mp_mrru: wenn summe ueber pktlen der rumhaengenden Pakete
1733 groesser als mrru ist: raus damit , Pakete muessen allerdings zusammenhaengen sonst koennte
1734 ja ein Paket mit B und eins mit E dazwischenpassen */
1736 struct mpqueue *ql,
1737 *q = dev->mp_last;
1738 while(q && (q->sqno < min_sqno) ) {
1739 if ( (q->BEbyte & MP_END_FRAG) ||
1740 (q->next && (q->next->sqno <= min_sqno) && (q->next->BEbyte & MP_BEGIN_FRAG)) ) {
1741 printk(KERN_DEBUG "ippp: freeing stale packet(s), min_sq: %ld!\n",min_sqno);
1742 if ((dev->mp_last = q->next))
1743 q->next->last = NULL;
1744 while (q) {
1745 ql = q->last;
1746 printk(KERN_DEBUG "ippp, freeing packet with sqno: %ld\n",q->sqno);
1747 dev_kfree_skb(q->skb);
1748 kfree(q);
1749 #ifdef CONFIG_ISDN_PPP_VJ
1750 toss = 1;
1751 #endif
1752 q = ql;
1754 q = dev->mp_last;
1755 } else
1756 q = q->next;
1758 #ifdef CONFIG_ISDN_PPP_VJ
1759 /* did we free a stale frame ? */
1760 if (toss)
1761 slhc_toss(ippp_table[dev->local->ppp_slot]->slcomp);
1762 #endif
1766 * a buffered packet timed-out?
1769 #endif
1771 void
1772 isdn_ppp_timer_timeout(void)
1774 #ifdef CONFIG_ISDN_MPP
1775 isdn_net_dev *net_dev = dev->netdev;
1776 struct sqqueue *q,
1777 *ql = NULL,
1778 *qn;
1780 while (net_dev) {
1781 isdn_net_local *lp = net_dev->local;
1782 if (net_dev->ib.modify || lp->master) { /* interface locked or slave? */
1783 net_dev = net_dev->next;
1784 continue;
1786 q = net_dev->ib.sq;
1787 while (q) {
1788 if (q->sqno_start == net_dev->ib.next_num || q->timer < jiffies) {
1790 #ifdef CONFIG_ISDN_PPP_VJ
1791 /* did we step over a missing frame ? */
1792 if (q->sqno_start != net_dev->ib.next_num)
1793 slhc_toss(ippp_table[lp->ppp_slot]->slcomp);
1794 #endif
1796 ql = net_dev->ib.sq;
1797 net_dev->ib.sq = q->next;
1798 net_dev->ib.next_num = q->sqno_end + 1;
1799 q->next = NULL;
1800 for (; ql;) {
1801 int proto = isdn_ppp_strip_proto(ql->skb);
1802 isdn_ppp_push_higher(net_dev, lp, ql->skb, proto);
1803 qn = ql->next;
1804 kfree(ql);
1805 ql = qn;
1807 q = net_dev->ib.sq;
1808 } else
1809 q = q->next;
1811 net_dev = net_dev->next;
1813 #endif
1817 * network device ioctl handlers
1820 static int
1821 isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct device *dev)
1823 struct ppp_stats *res,
1825 isdn_net_local *lp = (isdn_net_local *) dev->priv;
1826 int err;
1828 res = (struct ppp_stats *) ifr->ifr_ifru.ifru_data;
1829 err = verify_area(VERIFY_WRITE, res, sizeof(struct ppp_stats));
1831 if (err)
1832 return err;
1834 /* build a temporary stat struct and copy it to user space */
1836 memset(&t, 0, sizeof(struct ppp_stats));
1837 if (dev->flags & IFF_UP) {
1838 t.p.ppp_ipackets = lp->stats.rx_packets;
1839 t.p.ppp_ierrors = lp->stats.rx_errors;
1840 t.p.ppp_opackets = lp->stats.tx_packets;
1841 t.p.ppp_oerrors = lp->stats.tx_errors;
1842 #ifdef CONFIG_ISDN_PPP_VJ
1843 if (slot >= 0 && ippp_table[slot]->slcomp) {
1844 struct slcompress *slcomp = ippp_table[slot]->slcomp;
1845 t.vj.vjs_packets = slcomp->sls_o_compressed + slcomp->sls_o_uncompressed;
1846 t.vj.vjs_compressed = slcomp->sls_o_compressed;
1847 t.vj.vjs_searches = slcomp->sls_o_searches;
1848 t.vj.vjs_misses = slcomp->sls_o_misses;
1849 t.vj.vjs_errorin = slcomp->sls_i_error;
1850 t.vj.vjs_tossed = slcomp->sls_i_tossed;
1851 t.vj.vjs_uncompressedin = slcomp->sls_i_uncompressed;
1852 t.vj.vjs_compressedin = slcomp->sls_i_compressed;
1854 #endif
1856 if( copy_to_user(res, &t, sizeof(struct ppp_stats))) return -EFAULT;
1857 return 0;
1861 isdn_ppp_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
1863 int error=0;
1864 char *r;
1865 int len;
1866 isdn_net_local *lp = (isdn_net_local *) dev->priv;
1868 #if 0
1869 printk(KERN_DEBUG "ippp, dev_ioctl: cmd %#08x , %d \n", cmd, lp->ppp_slot);
1870 #endif
1872 if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
1873 return -EINVAL;
1875 switch (cmd) {
1876 case SIOCGPPPVER:
1877 r = (char *) ifr->ifr_ifru.ifru_data;
1878 len = strlen(PPP_VERSION) + 1;
1879 if(copy_to_user(r, PPP_VERSION, len)) error = -EFAULT;
1880 break;
1881 case SIOCGPPPSTATS:
1882 error = isdn_ppp_dev_ioctl_stats(lp->ppp_slot, ifr, dev);
1883 break;
1884 default:
1885 error = -EINVAL;
1886 break;
1888 return error;
1891 static int
1892 isdn_ppp_if_get_unit(char *name)
1894 int len,
1896 unit = 0,
1897 deci;
1899 len = strlen(name);
1901 if (strncmp("ippp", name, 4) || len > 8)
1902 return -1;
1904 for (i = 0, deci = 1; i < len; i++, deci *= 10) {
1905 char a = name[len - i - 1];
1906 if (a >= '0' && a <= '9')
1907 unit += (a - '0') * deci;
1908 else
1909 break;
1911 if (!i || len - i != 4)
1912 unit = -1;
1914 return unit;
1919 isdn_ppp_dial_slave(char *name)
1921 #ifdef CONFIG_ISDN_MPP
1922 isdn_net_dev *ndev;
1923 isdn_net_local *lp;
1924 struct device *sdev;
1926 if (!(ndev = isdn_net_findif(name)))
1927 return 1;
1928 lp = ndev->local;
1929 if (!(lp->flags & ISDN_NET_CONNECTED))
1930 return 5;
1932 sdev = lp->slave;
1933 while (sdev) {
1934 isdn_net_local *mlp = (isdn_net_local *) sdev->priv;
1935 if (!(mlp->flags & ISDN_NET_CONNECTED))
1936 break;
1937 sdev = mlp->slave;
1939 if (!sdev)
1940 return 2;
1942 isdn_net_force_dial_lp((isdn_net_local *) sdev->priv);
1943 return 0;
1944 #else
1945 return -1;
1946 #endif
1950 isdn_ppp_hangup_slave(char *name)
1952 #ifdef CONFIG_ISDN_MPP
1953 isdn_net_dev *ndev;
1954 isdn_net_local *lp;
1955 struct device *sdev;
1957 if (!(ndev = isdn_net_findif(name)))
1958 return 1;
1959 lp = ndev->local;
1960 if (!(lp->flags & ISDN_NET_CONNECTED))
1961 return 5;
1963 sdev = lp->slave;
1964 while (sdev) {
1965 isdn_net_local *mlp = (isdn_net_local *) sdev->priv;
1966 if ((mlp->flags & ISDN_NET_CONNECTED))
1967 break;
1968 sdev = mlp->slave;
1970 if (!sdev)
1971 return 2;
1973 isdn_net_hangup(sdev);
1974 return 0;
1975 #else
1976 return -1;
1977 #endif
1981 * PPP compression stuff
1983 static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struct *is,struct ippp_struct *master)
1985 #if 1
1986 printk(KERN_ERR "compression not included!\n");
1987 dev_kfree_skb(skb);
1988 return NULL;
1989 #else
1990 if(!master) {
1992 * single link compression
1994 if(!is->link_compressor) {
1995 printk(KERN_ERR "ippp: no (link) compressor defined!\n");
1996 dev_kfree_skb(skb);
1997 return NULL;
1999 if(!is->link_decomp_stat) {
2000 printk(KERN_DEBUG "ippp: initialize link compressor\n");
2003 -> decompress link
2006 else {
2008 * 'normal' or bundle-compression
2010 if(!master->compressor) {
2011 printk(KERN_ERR "ippp: no (link) compressor defined!\n");
2012 dev_kfree_skb(skb);
2013 return NULL;
2015 if(!master->decomp_stat) {
2016 #if 0
2017 master->decomp_stat = (master->compressor->decomp_alloc)( .. );
2018 #endif
2019 printk(KERN_DEBUG "ippp: initialize compressor\n");
2023 return skb;
2024 #endif
2028 * compress a frame
2029 * type=0: normal/bundle compression
2030 * =1: link compression
2031 * returns original skb if we haven't compressed the frame
2032 * and a new skb pointer if we've done it
2034 static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in,int *proto,
2035 struct ippp_struct *is,struct ippp_struct *master,int type)
2037 #if 1
2038 return skb_in;
2039 #else
2040 int ret;
2041 int new_proto;
2042 struct isdn_ppp_compressor *compressor;
2043 void *stat;
2044 struct sk_buff *skb_out;
2046 if(type) { /* type=1 => Link compression */
2047 compressor = is->link_compressor;
2048 stat = is->link_comp_stat;
2049 new_proto = PPP_LINK_COMP;
2051 else {
2052 if(!master) {
2053 compressor = is->compressor;
2054 stat = is->comp_stat;
2056 else {
2057 compressor = master->compressor;
2058 stat = master->comp_stat;
2060 new_proto = PPP_COMP;
2063 if(!compressor) {
2064 printk(KERN_ERR "No compressor set!\n");
2065 return skb_in;
2067 if(!stat) {
2068 /* init here ? */
2069 return skb_in;
2072 skb_out = dev_alloc_skb(skb_in->len);
2073 if(!skb_out)
2074 return skb_in;
2076 ret = (compressor->compress)(stat,skb_in,skb_out,*proto);
2077 if(!ret) {
2078 dev_kfree_skb(skb_out);
2079 return skb_in;
2082 dev_kfree_skb(skb_in);
2083 *proto = new_proto;
2084 return skb_out;
2085 #endif
2090 * we received a CCP frame ..
2091 * not a clean solution, but we SHOULD handle a few cased in the kernel
2093 static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
2094 struct sk_buff *skb)
2096 #if 0
2097 printk(KERN_DEBUG "isdn_ppp_receive_cpp: %02x %02x %02x %02x %02x %02x %02x %02x\n",
2098 skb->data[0],skb->data[1],skb->data[2],skb->data[3],
2099 skb->data[4],skb->data[5],skb->data[6],skb->data[7] );
2100 #endif
2103 int isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc)
2105 ipc->next = ipc_head;
2106 ipc->prev = NULL;
2107 if(ipc_head) {
2108 ipc_head->prev = ipc;
2110 ipc_head = ipc;
2111 return 0;
2114 int isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *ipc)
2116 if(ipc->prev)
2117 ipc->prev->next = ipc->next;
2118 else
2119 ipc_head = ipc->next;
2120 if(ipc->next)
2121 ipc->next->prev = ipc->prev;
2122 ipc->prev = ipc->next = NULL;
2123 return 0;
2126 static int isdn_ppp_set_compressor(struct ippp_struct *is,int num)
2128 struct isdn_ppp_compressor *ipc = ipc_head;
2130 while(ipc) {
2131 if(ipc->num == num) {
2132 return 0;
2133 is->compressor = ipc;
2134 is->link_compressor = ipc;
2136 ipc = ipc->next;
2138 return -EINVAL;
2142 #if 0
2143 static struct symbol_table isdn_ppp_syms =
2145 #include <linux/symtab_begin.h>
2146 X(isdn_ppp_register_compressor),
2147 X(isdn_ppp_unregister_compressor),
2148 #include <linux/symtab_end.h>
2150 #endif