1/* $Id: isdn_ppp.c,v 1.1.1.1 2008/10/15 03:26:33 james26_jang Exp $
2 *
3 * Linux ISDN subsystem, functions for synchronous PPP (linklevel).
4 *
5 * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12#include <linux/config.h>
13#include <linux/isdn.h>
14#include <linux/poll.h>
15#include <linux/ppp-comp.h>
16
17#include "isdn_common.h"
18#include "isdn_ppp.h"
19#include "isdn_net.h"
20
21#ifndef PPP_IPX
22#define PPP_IPX 0x002b
23#endif
24
25/* Prototypes */
26static int isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot);
27static int isdn_ppp_closewait(int slot);
28static void isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp,
29				 struct sk_buff *skb, int proto);
30static int isdn_ppp_if_get_unit(char *namebuf);
31static int isdn_ppp_set_compressor(struct ippp_struct *is,struct isdn_ppp_comp_data *);
32static struct sk_buff *isdn_ppp_decompress(struct sk_buff *,
33				struct ippp_struct *,struct ippp_struct *,int *proto);
34static void isdn_ppp_receive_ccp(isdn_net_dev * net_dev, isdn_net_local * lp,
35				struct sk_buff *skb,int proto);
36static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in,int *proto,
37	struct ippp_struct *is,struct ippp_struct *master,int type);
38static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
39	 struct sk_buff *skb);
40
41/* New CCP stuff */
42static void isdn_ppp_ccp_kickup(struct ippp_struct *is);
43static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
44				    unsigned char code, unsigned char id,
45				    unsigned char *data, int len);
46static struct ippp_ccp_reset *isdn_ppp_ccp_reset_alloc(struct ippp_struct *is);
47static void isdn_ppp_ccp_reset_free(struct ippp_struct *is);
48static void isdn_ppp_ccp_reset_free_state(struct ippp_struct *is,
49					  unsigned char id);
50static void isdn_ppp_ccp_timer_callback(unsigned long closure);
51static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_struct *is,
52						      unsigned char id);
53static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
54				     struct isdn_ppp_resetparams *rp);
55static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
56					unsigned char id);
57
58
59
60#ifdef CONFIG_ISDN_MPP
61static ippp_bundle * isdn_ppp_bundle_arr = NULL;
62
63static int isdn_ppp_mp_bundle_array_init(void);
64static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to );
65static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
66							struct sk_buff *skb);
67static void isdn_ppp_mp_cleanup( isdn_net_local * lp );
68
69static int isdn_ppp_bundle(struct ippp_struct *, int unit);
70#endif	/* CONFIG_ISDN_MPP */
71
72char *isdn_ppp_revision = "$Revision: 1.1.1.1 $";
73
74static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
75
76static struct isdn_ppp_compressor *ipc_head = NULL;
77
78/*
79 * frame log (debug)
80 */
81static void
82isdn_ppp_frame_log(char *info, char *data, int len, int maxlen,int unit,int slot)
83{
84	int cnt,
85	 j,
86	 i;
87	char buf[80];
88
89	if (len < maxlen)
90		maxlen = len;
91
92	for (i = 0, cnt = 0; cnt < maxlen; i++) {
93		for (j = 0; j < 16 && cnt < maxlen; j++, cnt++)
94			sprintf(buf + j * 3, "%02x ", (unsigned char) data[cnt]);
95		printk(KERN_DEBUG "[%d/%d].%s[%d]: %s\n",unit,slot, info, i, buf);
96	}
97}
98
99/*
100 * unbind isdn_net_local <=> ippp-device
101 * note: it can happen, that we hangup/free the master before the slaves
102 *       in this case we bind another lp to the master device
103 */
104int
105isdn_ppp_free(isdn_net_local * lp)
106{
107	unsigned long flags;
108	struct ippp_struct *is;
109
110	if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
111		printk(KERN_ERR __FUNCTION__": ppp_slot(%d) out of range\n",
112			lp->ppp_slot);
113		return 0;
114	}
115
116	save_flags(flags);
117	cli();
118
119#ifdef CONFIG_ISDN_MPP
120	spin_lock(&lp->netdev->pb->lock);
121#endif
122	isdn_net_rm_from_bundle(lp);
123#ifdef CONFIG_ISDN_MPP
124	if (lp->netdev->pb->ref_ct == 1)	/* last link in queue? */
125		isdn_ppp_mp_cleanup(lp);
126
127	lp->netdev->pb->ref_ct--;
128	spin_unlock(&lp->netdev->pb->lock);
129#endif /* CONFIG_ISDN_MPP */
130	if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
131		printk(KERN_ERR __FUNCTION__": ppp_slot(%d) now invalid\n",
132			lp->ppp_slot);
133		restore_flags(flags);
134		return 0;
135	}
136	is = ippp_table[lp->ppp_slot];
137	if ((is->state & IPPP_CONNECT))
138		isdn_ppp_closewait(lp->ppp_slot);	/* force wakeup on ippp device */
139	else if (is->state & IPPP_ASSIGNED)
140		is->state = IPPP_OPEN;	/* fallback to 'OPEN but not ASSIGNED' state */
141
142	if (is->debug & 0x1)
143		printk(KERN_DEBUG "isdn_ppp_free %d %lx %lx\n", lp->ppp_slot, (long) lp, (long) is->lp);
144
145	is->lp = NULL;          /* link is down .. set lp to NULL */
146	lp->ppp_slot = -1;      /* is this OK ?? */
147
148	restore_flags(flags);
149	return 0;
150}
151
152/*
153 * bind isdn_net_local <=> ippp-device
154 */
155int
156isdn_ppp_bind(isdn_net_local * lp)
157{
158	int i;
159	int unit = 0;
160	long flags;
161	struct ippp_struct *is;
162	int retval;
163
164	save_flags(flags);
165	cli();
166	if (lp->pppbind < 0) {  /* device bounded to ippp device ? */
167		isdn_net_dev *net_dev = dev->netdev;
168		char exclusive[ISDN_MAX_CHANNELS];	/* exclusive flags */
169		memset(exclusive, 0, ISDN_MAX_CHANNELS);
170		while (net_dev) {	/* step through net devices to find exclusive minors */
171			isdn_net_local *lp = net_dev->local;
172			if (lp->pppbind >= 0)
173				exclusive[lp->pppbind] = 1;
174			net_dev = net_dev->next;
175		}
176		/*
177		 * search a free device / slot
178		 */
179		for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
180			if (ippp_table[i]->state == IPPP_OPEN && !exclusive[ippp_table[i]->minor]) {	/* OPEN, but not connected! */
181				break;
182			}
183		}
184	} else {
185		for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
186			if (ippp_table[i]->minor == lp->pppbind &&
187			    (ippp_table[i]->state & IPPP_OPEN) == IPPP_OPEN)
188				break;
189		}
190	}
191
192	if (i >= ISDN_MAX_CHANNELS) {
193		restore_flags(flags);
194		printk(KERN_WARNING "isdn_ppp_bind: Can't find a (free) connection to the ipppd daemon.\n");
195		retval = -1;
196		goto out;
197	}
198	unit = isdn_ppp_if_get_unit(lp->name);	/* get unit number from interface name .. ugly! */
199	if (unit < 0) {
200		printk(KERN_ERR "isdn_ppp_bind: illegal interface name %s.\n", lp->name);
201		retval = -1;
202		goto out;
203	}
204
205	lp->ppp_slot = i;
206	is = ippp_table[i];
207	is->lp = lp;
208	is->unit = unit;
209	is->state = IPPP_OPEN | IPPP_ASSIGNED;	/* assigned to a netdevice but not connected */
210#ifdef CONFIG_ISDN_MPP
211	retval = isdn_ppp_mp_init(lp, NULL);
212	if (retval < 0)
213		goto out;
214#endif /* CONFIG_ISDN_MPP */
215
216	retval = lp->ppp_slot;
217
218 out:
219	restore_flags(flags);
220	return retval;
221}
222
223/*
224 * kick the ipppd on the device
225 * (wakes up daemon after B-channel connect)
226 */
227
228void
229isdn_ppp_wakeup_daemon(isdn_net_local * lp)
230{
231	if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
232		printk(KERN_ERR __FUNCTION__": ppp_slot(%d) out of range\n",
233			lp->ppp_slot);
234		return;
235	}
236	ippp_table[lp->ppp_slot]->state = IPPP_OPEN | IPPP_CONNECT | IPPP_NOBLOCK;
237	wake_up_interruptible(&ippp_table[lp->ppp_slot]->wq);
238}
239
240/*
241 * there was a hangup on the netdevice
242 * force wakeup of the ippp device
243 * go into 'device waits for release' state
244 */
245static int
246isdn_ppp_closewait(int slot)
247{
248	struct ippp_struct *is;
249
250	if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
251		printk(KERN_ERR __FUNCTION__": slot(%d) out of range\n",
252			slot);
253		return 0;
254	}
255	is = ippp_table[slot];
256	if (is->state)
257		wake_up_interruptible(&is->wq);
258	is->state = IPPP_CLOSEWAIT;
259	return 1;
260}
261
262/*
263 * isdn_ppp_find_slot / isdn_ppp_free_slot
264 */
265
266static int
267isdn_ppp_get_slot(void)
268{
269	int i;
270	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
271		if (!ippp_table[i]->state)
272			return i;
273	}
274	return -1;
275}
276
277/*
278 * isdn_ppp_open
279 */
280
281int
282isdn_ppp_open(int min, struct file *file)
283{
284	int slot;
285	struct ippp_struct *is;
286
287	if (min < 0 || min > ISDN_MAX_CHANNELS)
288		return -ENODEV;
289
290	slot = isdn_ppp_get_slot();
291	if (slot < 0) {
292		return -EBUSY;
293	}
294	is = file->private_data = ippp_table[slot];
295
296	printk(KERN_DEBUG "ippp, open, slot: %d, minor: %d, state: %04x\n",
297	       slot, min, is->state);
298
299	/* compression stuff */
300	is->link_compressor   = is->compressor = NULL;
301	is->link_decompressor = is->decompressor = NULL;
302	is->link_comp_stat    = is->comp_stat = NULL;
303	is->link_decomp_stat  = is->decomp_stat = NULL;
304	is->compflags = 0;
305
306	is->reset = isdn_ppp_ccp_reset_alloc(is);
307
308	is->lp = NULL;
309	is->mp_seqno = 0;       /* MP sequence number */
310	is->pppcfg = 0;         /* ppp configuration */
311	is->mpppcfg = 0;        /* mppp configuration */
312	is->last_link_seqno = -1;	/* MP: maybe set to Bundle-MIN, when joining a bundle ?? */
313	is->unit = -1;          /* set, when we have our interface */
314	is->mru = 1524;         /* MRU, default 1524 */
315	is->maxcid = 16;        /* VJ: maxcid */
316	is->tk = current;
317	init_waitqueue_head(&is->wq);
318	is->first = is->rq + NUM_RCV_BUFFS - 1;	/* receive queue */
319	is->last = is->rq;
320	is->minor = min;
321#ifdef CONFIG_ISDN_PPP_VJ
322	/*
323	 * VJ header compression init
324	 */
325	is->slcomp = slhc_init(16, 16);	/* not necessary for 2. link in bundle */
326#endif
327
328	is->state = IPPP_OPEN;
329
330	return 0;
331}
332
333/*
334 * release ippp device
335 */
336void
337isdn_ppp_release(int min, struct file *file)
338{
339	int i;
340	struct ippp_struct *is;
341
342	if (min < 0 || min >= ISDN_MAX_CHANNELS)
343		return;
344	is = file->private_data;
345
346	if (!is) {
347		printk(KERN_ERR __FUNCTION__": no file->private_data\n");
348		return;
349	}
350	if (is->debug & 0x1)
351		printk(KERN_DEBUG "ippp: release, minor: %d %lx\n", min, (long) is->lp);
352
353	if (is->lp) {           /* a lp address says: this link is still up */
354		isdn_net_dev *p = is->lp->netdev;
355
356		if (!p) {
357			printk(KERN_ERR __FUNCTION__": no lp->netdev\n");
358			return;
359		}
360		is->state &= ~IPPP_CONNECT;	/* -> effect: no call of wakeup */
361		/*
362		 * isdn_net_hangup() calls isdn_ppp_free()
363		 * isdn_ppp_free() sets is->lp to NULL and lp->ppp_slot to -1
364		 * removing the IPPP_CONNECT flag omits calling of isdn_ppp_wakeup_daemon()
365		 */
366		isdn_net_hangup(&p->dev);
367	}
368	for (i = 0; i < NUM_RCV_BUFFS; i++) {
369		if (is->rq[i].buf) {
370			kfree(is->rq[i].buf);
371			is->rq[i].buf = NULL;
372		}
373	}
374	is->first = is->rq + NUM_RCV_BUFFS - 1;	/* receive queue */
375	is->last = is->rq;
376
377#ifdef CONFIG_ISDN_PPP_VJ
378/* TODO: if this was the previous master: link the slcomp to the new master */
379	slhc_free(is->slcomp);
380	is->slcomp = NULL;
381#endif
382
383/* TODO: if this was the previous master: link the the stuff to the new master */
384	if(is->comp_stat)
385		is->compressor->free(is->comp_stat);
386	if(is->link_comp_stat)
387		is->link_compressor->free(is->link_comp_stat);
388	if(is->link_decomp_stat)
389		is->link_decompressor->free(is->link_decomp_stat);
390	if(is->decomp_stat)
391		is->decompressor->free(is->decomp_stat);
392        is->compressor   = is->link_compressor   = NULL;
393        is->decompressor = is->link_decompressor = NULL;
394	is->comp_stat    = is->link_comp_stat    = NULL;
395        is->decomp_stat  = is->link_decomp_stat  = NULL;
396
397	/* Clean up if necessary */
398	if(is->reset)
399		isdn_ppp_ccp_reset_free(is);
400
401	/* this slot is ready for new connections */
402	is->state = 0;
403}
404
405/*
406 * get_arg .. ioctl helper
407 */
408static int
409get_arg(void *b, void *val, int len)
410{
411	if (len <= 0)
412		len = sizeof(void *);
413	if (copy_from_user((void *) val, b, len))
414		return -EFAULT;
415	return 0;
416}
417
418/*
419 * set arg .. ioctl helper
420 */
421static int
422set_arg(void *b, void *val,int len)
423{
424	if(len <= 0)
425		len = sizeof(void *);
426	if (copy_to_user(b, (void *) val, len))
427		return -EFAULT;
428	return 0;
429}
430
431/*
432 * ippp device ioctl
433 */
434int
435isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
436{
437	unsigned long val;
438	int r,i,j;
439	struct ippp_struct *is;
440	isdn_net_local *lp;
441	struct isdn_ppp_comp_data data;
442
443	is = (struct ippp_struct *) file->private_data;
444	lp = is->lp;
445
446	if (is->debug & 0x1)
447		printk(KERN_DEBUG "isdn_ppp_ioctl: minor: %d cmd: %x state: %x\n", min, cmd, is->state);
448
449	if (!(is->state & IPPP_OPEN))
450		return -EINVAL;
451
452	switch (cmd) {
453		case PPPIOCBUNDLE:
454#ifdef CONFIG_ISDN_MPP
455			if (!(is->state & IPPP_CONNECT))
456				return -EINVAL;
457			if ((r = get_arg((void *) arg, &val, sizeof(val) )))
458				return r;
459			printk(KERN_DEBUG "iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n",
460			       (int) min, (int) is->unit, (int) val);
461			return isdn_ppp_bundle(is, val);
462#else
463			return -1;
464#endif
465			break;
466		case PPPIOCGUNIT:	/* get ppp/isdn unit number */
467			if ((r = set_arg((void *) arg, &is->unit, sizeof(is->unit) )))
468				return r;
469			break;
470		case PPPIOCGIFNAME:
471			if(!lp)
472				return -EINVAL;
473			if ((r = set_arg((void *) arg, lp->name, strlen(lp->name))))
474				return r;
475			break;
476		case PPPIOCGMPFLAGS:	/* get configuration flags */
477			if ((r = set_arg((void *) arg, &is->mpppcfg, sizeof(is->mpppcfg) )))
478				return r;
479			break;
480		case PPPIOCSMPFLAGS:	/* set configuration flags */
481			if ((r = get_arg((void *) arg, &val, sizeof(val) )))
482				return r;
483			is->mpppcfg = val;
484			break;
485		case PPPIOCGFLAGS:	/* get configuration flags */
486			if ((r = set_arg((void *) arg, &is->pppcfg,sizeof(is->pppcfg) )))
487				return r;
488			break;
489		case PPPIOCSFLAGS:	/* set configuration flags */
490			if ((r = get_arg((void *) arg, &val, sizeof(val) ))) {
491				return r;
492			}
493			if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) {
494				if (lp) {
495					/* OK .. we are ready to send buffers */
496					is->pppcfg = val; /* isdn_ppp_xmit test for SC_ENABLE_IP !!! */
497					netif_wake_queue(&lp->netdev->dev);
498					break;
499				}
500			}
501			is->pppcfg = val;
502			break;
503		case PPPIOCGIDLE:	/* get idle time information */
504			if (lp) {
505				struct ppp_idle pidle;
506				pidle.xmit_idle = pidle.recv_idle = lp->huptimer;
507				if ((r = set_arg((void *) arg, &pidle,sizeof(struct ppp_idle))))
508					 return r;
509			}
510			break;
511		case PPPIOCSMRU:	/* set receive unit size for PPP */
512			if ((r = get_arg((void *) arg, &val, sizeof(val) )))
513				return r;
514			is->mru = val;
515			break;
516		case PPPIOCSMPMRU:
517			break;
518		case PPPIOCSMPMTU:
519			break;
520		case PPPIOCSMAXCID:	/* set the maximum compression slot id */
521			if ((r = get_arg((void *) arg, &val, sizeof(val) )))
522				return r;
523			val++;
524			if (is->maxcid != val) {
525#ifdef CONFIG_ISDN_PPP_VJ
526				struct slcompress *sltmp;
527#endif
528				if (is->debug & 0x1)
529					printk(KERN_DEBUG "ippp, ioctl: changed MAXCID to %ld\n", val);
530				is->maxcid = val;
531#ifdef CONFIG_ISDN_PPP_VJ
532				sltmp = slhc_init(16, val);
533				if (!sltmp) {
534					printk(KERN_ERR "ippp, can't realloc slhc struct\n");
535					return -ENOMEM;
536				}
537				if (is->slcomp)
538					slhc_free(is->slcomp);
539				is->slcomp = sltmp;
540#endif
541			}
542			break;
543		case PPPIOCGDEBUG:
544			if ((r = set_arg((void *) arg, &is->debug, sizeof(is->debug) )))
545				return r;
546			break;
547		case PPPIOCSDEBUG:
548			if ((r = get_arg((void *) arg, &val, sizeof(val) )))
549				return r;
550			is->debug = val;
551			break;
552		case PPPIOCGCOMPRESSORS:
553			{
554				unsigned long protos[8] = {0,};
555				struct isdn_ppp_compressor *ipc = ipc_head;
556				while(ipc) {
557					j = ipc->num / (sizeof(long)*8);
558					i = ipc->num % (sizeof(long)*8);
559					if(j < 8)
560						protos[j] |= (0x1<<i);
561					ipc = ipc->next;
562				}
563				if ((r = set_arg((void *) arg,protos,8*sizeof(long) )))
564					return r;
565			}
566			break;
567		case PPPIOCSCOMPRESSOR:
568			if ((r = get_arg((void *) arg, &data, sizeof(struct isdn_ppp_comp_data))))
569				return r;
570			return isdn_ppp_set_compressor(is, &data);
571		case PPPIOCGCALLINFO:
572			{
573				struct pppcallinfo pci;
574				memset((char *) &pci,0,sizeof(struct pppcallinfo));
575				if(lp)
576				{
577					strncpy(pci.local_num,lp->msn,63);
578					if(lp->dial) {
579						strncpy(pci.remote_num,lp->dial->num,63);
580					}
581					pci.charge_units = lp->charge;
582					if(lp->outgoing)
583						pci.calltype = CALLTYPE_OUTGOING;
584					else
585						pci.calltype = CALLTYPE_INCOMING;
586					if(lp->flags & ISDN_NET_CALLBACK)
587						pci.calltype |= CALLTYPE_CALLBACK;
588				}
589				return set_arg((void *)arg,&pci,sizeof(struct pppcallinfo));
590			}
591		default:
592			break;
593	}
594	return 0;
595}
596
597unsigned int
598isdn_ppp_poll(struct file *file, poll_table * wait)
599{
600	unsigned int mask;
601	struct ippp_buf_queue *bf;
602	struct ippp_buf_queue *bl;
603	unsigned long flags;
604	struct ippp_struct *is;
605
606	is = file->private_data;
607
608	if (is->debug & 0x2)
609		printk(KERN_DEBUG "isdn_ppp_poll: minor: %d\n",
610				MINOR(file->f_dentry->d_inode->i_rdev));
611
612	/* just registers wait_queue hook. This doesn't really wait. */
613	poll_wait(file, &is->wq, wait);
614
615	if (!(is->state & IPPP_OPEN)) {
616		if(is->state == IPPP_CLOSEWAIT)
617			return POLLHUP;
618		printk(KERN_DEBUG "isdn_ppp: device not open\n");
619		return POLLERR;
620	}
621	/* we're always ready to send .. */
622	mask = POLLOUT | POLLWRNORM;
623
624	save_flags(flags);
625	cli();
626	bl = is->last;
627	bf = is->first;
628	/*
629	 * if IPPP_NOBLOCK is set we return even if we have nothing to read
630	 */
631	if (bf->next != bl || (is->state & IPPP_NOBLOCK)) {
632		is->state &= ~IPPP_NOBLOCK;
633		mask |= POLLIN | POLLRDNORM;
634	}
635	restore_flags(flags);
636	return mask;
637}
638
639/*
640 *  fill up isdn_ppp_read() queue ..
641 */
642
643static int
644isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot)
645{
646	struct ippp_buf_queue *bf,
647	*bl;
648	unsigned long flags;
649	unsigned char *nbuf;
650	struct ippp_struct *is;
651
652	if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
653		printk(KERN_WARNING "ippp: illegal slot(%d).\n", slot);
654		return 0;
655	}
656	is = ippp_table[slot];
657
658	if (!(is->state & IPPP_CONNECT)) {
659		printk(KERN_DEBUG "ippp: device not activated.\n");
660		return 0;
661	}
662	nbuf = (unsigned char *) kmalloc(len + 4, GFP_ATOMIC);
663	if (!nbuf) {
664		printk(KERN_WARNING "ippp: Can't alloc buf\n");
665		return 0;
666	}
667	nbuf[0] = PPP_ALLSTATIONS;
668	nbuf[1] = PPP_UI;
669	nbuf[2] = proto >> 8;
670	nbuf[3] = proto & 0xff;
671	memcpy(nbuf + 4, buf, len);
672
673	save_flags(flags);
674	cli();
675
676	bf = is->first;
677	bl = is->last;
678
679	if (bf == bl) {
680		printk(KERN_WARNING "ippp: Queue is full; discarding first buffer\n");
681		bf = bf->next;
682		kfree(bf->buf);
683		is->first = bf;
684	}
685	bl->buf = (char *) nbuf;
686	bl->len = len + 4;
687
688	is->last = bl->next;
689	restore_flags(flags);
690
691		wake_up_interruptible(&is->wq);
692
693	return len;
694}
695
696/*
697 * read() .. non-blocking: ipppd calls it only after select()
698 *           reports, that there is data
699 */
700
701int
702isdn_ppp_read(int min, struct file *file, char *buf, int count)
703{
704	struct ippp_struct *is;
705	struct ippp_buf_queue *b;
706	int r;
707	unsigned long flags;
708	unsigned char *save_buf;
709
710	is = file->private_data;
711
712	if (!(is->state & IPPP_OPEN))
713		return 0;
714
715	if ((r = verify_area(VERIFY_WRITE, (void *) buf, count)))
716		return r;
717
718	save_flags(flags);
719	cli();
720
721	b = is->first->next;
722	save_buf = b->buf;
723	if (!save_buf) {
724		restore_flags(flags);
725		return -EAGAIN;
726	}
727	if (b->len < count)
728		count = b->len;
729	b->buf = NULL;
730	is->first = b;
731
732	restore_flags(flags);
733
734	copy_to_user(buf, save_buf, count);
735	kfree(save_buf);
736
737	return count;
738}
739
740/*
741 * ipppd wanna write a packet to the card .. non-blocking
742 */
743
744int
745isdn_ppp_write(int min, struct file *file, const char *buf, int count)
746{
747	isdn_net_local *lp;
748	struct ippp_struct *is;
749	int proto;
750	unsigned char protobuf[4];
751
752	is = file->private_data;
753
754	if (!(is->state & IPPP_CONNECT))
755		return 0;
756
757	lp = is->lp;
758
759	/* -> push it directly to the lowlevel interface */
760
761	if (!lp)
762		printk(KERN_DEBUG "isdn_ppp_write: lp == NULL\n");
763	else {
764		/*
765		 * Don't reset huptimer for
766		 * LCP packets. (Echo requests).
767		 */
768		if (copy_from_user(protobuf, buf, 4))
769			return -EFAULT;
770		proto = PPP_PROTOCOL(protobuf);
771		if (proto != PPP_LCP)
772			lp->huptimer = 0;
773
774		if (lp->isdn_device < 0 || lp->isdn_channel < 0)
775			return 0;
776
777		if ((dev->drv[lp->isdn_device]->flags & DRV_FLAG_RUNNING) &&
778			lp->dialstate == 0 &&
779		    (lp->flags & ISDN_NET_CONNECTED)) {
780			unsigned short hl;
781			struct sk_buff *skb;
782			/*
783			 * we need to reserve enought space in front of
784			 * sk_buff. old call to dev_alloc_skb only reserved
785			 * 16 bytes, now we are looking what the driver want
786			 */
787			hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
788			skb = alloc_skb(hl+count, GFP_ATOMIC);
789			if (!skb) {
790				printk(KERN_WARNING "isdn_ppp_write: out of memory!\n");
791				return count;
792			}
793			skb_reserve(skb, hl);
794			if (copy_from_user(skb_put(skb, count), buf, count))
795			{
796				kfree_skb(skb);
797				return -EFAULT;
798			}
799			if (is->debug & 0x40) {
800				printk(KERN_DEBUG "ppp xmit: len %d\n", (int) skb->len);
801				isdn_ppp_frame_log("xmit", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
802			}
803
804			isdn_ppp_send_ccp(lp->netdev,lp,skb); /* keeps CCP/compression states in sync */
805
806			isdn_net_write_super(lp, skb);
807		}
808	}
809	return count;
810}
811
812/*
813 * init memory, structures etc.
814 */
815
816int
817isdn_ppp_init(void)
818{
819	int i,
820	 j;
821
822#ifdef CONFIG_ISDN_MPP
823	if( isdn_ppp_mp_bundle_array_init() < 0 )
824		return -ENOMEM;
825#endif /* CONFIG_ISDN_MPP */
826
827	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
828		if (!(ippp_table[i] = (struct ippp_struct *)
829		      kmalloc(sizeof(struct ippp_struct), GFP_KERNEL))) {
830			printk(KERN_WARNING "isdn_ppp_init: Could not alloc ippp_table\n");
831			for (j = 0; j < i; j++)
832				kfree(ippp_table[j]);
833			return -1;
834		}
835		memset((char *) ippp_table[i], 0, sizeof(struct ippp_struct));
836		ippp_table[i]->state = 0;
837		ippp_table[i]->first = ippp_table[i]->rq + NUM_RCV_BUFFS - 1;
838		ippp_table[i]->last = ippp_table[i]->rq;
839
840		for (j = 0; j < NUM_RCV_BUFFS; j++) {
841			ippp_table[i]->rq[j].buf = NULL;
842			ippp_table[i]->rq[j].last = ippp_table[i]->rq +
843			    (NUM_RCV_BUFFS + j - 1) % NUM_RCV_BUFFS;
844			ippp_table[i]->rq[j].next = ippp_table[i]->rq + (j + 1) % NUM_RCV_BUFFS;
845		}
846	}
847	return 0;
848}
849
850void
851isdn_ppp_cleanup(void)
852{
853	int i;
854
855	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
856		kfree(ippp_table[i]);
857
858#ifdef CONFIG_ISDN_MPP
859	if (isdn_ppp_bundle_arr)
860		kfree(isdn_ppp_bundle_arr);
861#endif /* CONFIG_ISDN_MPP */
862
863}
864
865/*
866 * check for address/control field and skip if allowed
867 * retval != 0 -> discard packet silently
868 */
869static int isdn_ppp_skip_ac(struct ippp_struct *is, struct sk_buff *skb)
870{
871	if (skb->len < 1)
872		return -1;
873
874	if (skb->data[0] == 0xff) {
875		if (skb->len < 2)
876			return -1;
877
878		if (skb->data[1] != 0x03)
879			return -1;
880
881		// skip address/control (AC) field
882		skb_pull(skb, 2);
883	} else {
884		if (is->pppcfg & SC_REJ_COMP_AC)
885			// if AC compression was not negotiated, but used, discard packet
886			return -1;
887	}
888	return 0;
889}
890
891/*
892 * get the PPP protocol header and pull skb
893 * retval < 0 -> discard packet silently
894 */
895static int isdn_ppp_strip_proto(struct sk_buff *skb)
896{
897	int proto;
898
899	if (skb->len < 1)
900		return -1;
901
902	if (skb->data[0] & 0x1) {
903		// protocol field is compressed
904		proto = skb->data[0];
905		skb_pull(skb, 1);
906	} else {
907		if (skb->len < 2)
908			return -1;
909		proto = ((int) skb->data[0] << 8) + skb->data[1];
910		skb_pull(skb, 2);
911	}
912	return proto;
913}
914
915
916/*
917 * handler for incoming packets on a syncPPP interface
918 */
919void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb)
920{
921	struct ippp_struct *is;
922	int slot;
923	int proto;
924
925	if (net_dev->local->master)
926		BUG(); // we're called with the master device always
927
928	slot = lp->ppp_slot;
929	if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
930		printk(KERN_ERR "isdn_ppp_receive: lp->ppp_slot(%d)\n",
931			lp->ppp_slot);
932		kfree_skb(skb);
933		return;
934	}
935	is = ippp_table[slot];
936
937	if (is->debug & 0x4) {
938		printk(KERN_DEBUG "ippp_receive: is:%08lx lp:%08lx slot:%d unit:%d len:%d\n",
939		       (long)is,(long)lp,lp->ppp_slot,is->unit,(int) skb->len);
940		isdn_ppp_frame_log("receive", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
941	}
942
943 	if (isdn_ppp_skip_ac(is, skb) < 0) {
944 		kfree_skb(skb);
945 		return;
946 	}
947  	proto = isdn_ppp_strip_proto(skb);
948 	if (proto < 0) {
949 		kfree_skb(skb);
950 		return;
951 	}
952
953#ifdef CONFIG_ISDN_MPP
954 	if (is->compflags & SC_LINK_DECOMP_ON) {
955 		skb = isdn_ppp_decompress(skb, is, NULL, &proto);
956 		if (!skb) // decompression error
957 			return;
958 	}
959
960 	if (!(is->mpppcfg & SC_REJ_MP_PROT)) { // we agreed to receive MPPP
961  		if (proto == PPP_MP) {
962  			isdn_ppp_mp_receive(net_dev, lp, skb);
963 			return;
964 		}
965 	}
966#endif
967 	isdn_ppp_push_higher(net_dev, lp, skb, proto);
968}
969
970/*
971 * we receive a reassembled frame, MPPP has been taken care of before.
972 * address/control and protocol have been stripped from the skb
973 * note: net_dev has to be master net_dev
974 */
975static void
976isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb, int proto)
977{
978	struct net_device *dev = &net_dev->dev;
979 	struct ippp_struct *is, *mis;
980	int slot;
981
982	slot = lp->ppp_slot;
983	if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
984		printk(KERN_ERR "isdn_ppp_push_higher: lp->ppp_slot(%d)\n",
985			lp->ppp_slot);
986		goto drop_packet;
987	}
988	is = ippp_table[slot];
989
990 	if (lp->master) { // FIXME?
991 		slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot;
992 		if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
993 			printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot(%d)\n",
994 				lp->ppp_slot);
995			goto drop_packet;
996 		}
997 	}
998 	mis = ippp_table[slot];
999
1000	if (is->debug & 0x10) {
1001		printk(KERN_DEBUG "push, skb %d %04x\n", (int) skb->len, proto);
1002		isdn_ppp_frame_log("rpush", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
1003	}
1004	if (mis->compflags & SC_DECOMP_ON) {
1005		skb = isdn_ppp_decompress(skb, is, mis, &proto);
1006		if (!skb) // decompression error
1007  			return;
1008  	}
1009	switch (proto) {
1010		case PPP_IPX:  /* untested */
1011			if (is->debug & 0x20)
1012				printk(KERN_DEBUG "isdn_ppp: IPX\n");
1013			skb->protocol = htons(ETH_P_IPX);
1014			break;
1015		case PPP_IP:
1016			if (is->debug & 0x20)
1017				printk(KERN_DEBUG "isdn_ppp: IP\n");
1018			skb->protocol = htons(ETH_P_IP);
1019			break;
1020		case PPP_COMP:
1021		case PPP_COMPFRAG:
1022			printk(KERN_INFO "isdn_ppp: unexpected compressed frame dropped\n");
1023			goto drop_packet;
1024#ifdef CONFIG_ISDN_PPP_VJ
1025		case PPP_VJC_UNCOMP:
1026			if (is->debug & 0x20)
1027				printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n");
1028			if (net_dev->local->ppp_slot < 0) {
1029				printk(KERN_ERR __FUNCTION__": net_dev->local->ppp_slot(%d) out of range\n",
1030					net_dev->local->ppp_slot);
1031				goto drop_packet;
1032			}
1033			if (slhc_remember(ippp_table[net_dev->local->ppp_slot]->slcomp, skb->data, skb->len) <= 0) {
1034				printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n");
1035				goto drop_packet;
1036			}
1037			skb->protocol = htons(ETH_P_IP);
1038			break;
1039		case PPP_VJC_COMP:
1040			if (is->debug & 0x20)
1041				printk(KERN_DEBUG "isdn_ppp: VJC_COMP\n");
1042			{
1043				struct sk_buff *skb_old = skb;
1044				int pkt_len;
1045				skb = dev_alloc_skb(skb_old->len + 128);
1046
1047				if (!skb) {
1048					printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
1049					skb = skb_old;
1050					goto drop_packet;
1051				}
1052				skb_put(skb, skb_old->len + 128);
1053				memcpy(skb->data, skb_old->data, skb_old->len);
1054				if (net_dev->local->ppp_slot < 0) {
1055					printk(KERN_ERR __FUNCTION__": net_dev->local->ppp_slot(%d) out of range\n",
1056						net_dev->local->ppp_slot);
1057					goto drop_packet;
1058				}
1059				pkt_len = slhc_uncompress(ippp_table[net_dev->local->ppp_slot]->slcomp,
1060						skb->data, skb_old->len);
1061				kfree_skb(skb_old);
1062				if (pkt_len < 0)
1063					goto drop_packet;
1064
1065				skb_trim(skb, pkt_len);
1066				skb->protocol = htons(ETH_P_IP);
1067			}
1068			break;
1069#endif
1070		case PPP_CCP:
1071		case PPP_CCPFRAG:
1072			isdn_ppp_receive_ccp(net_dev,lp,skb,proto);
1073			/* Dont pop up ResetReq/Ack stuff to the daemon any
1074			   longer - the job is done already */
1075			if(skb->data[0] == CCP_RESETREQ ||
1076			   skb->data[0] == CCP_RESETACK)
1077				break;
1078			/* fall through */
1079		default:
1080			isdn_ppp_fill_rq(skb->data, skb->len, proto, lp->ppp_slot);	/* push data to pppd device */
1081			kfree_skb(skb);
1082			return;
1083	}
1084
1085 	/* Reset hangup-timer */
1086 	lp->huptimer = 0;
1087
1088	skb->dev = dev;
1089	skb->mac.raw = skb->data;
1090	netif_rx(skb);
1091	/* net_dev->local->stats.rx_packets++; done in isdn_net.c */
1092	return;
1093
1094 drop_packet:
1095	net_dev->local->stats.rx_dropped++;
1096	kfree_skb(skb);
1097}
1098
1099/*
1100 * isdn_ppp_skb_push ..
1101 * checks whether we have enough space at the beginning of the skb
1102 * and allocs a new SKB if necessary
1103 */
1104static unsigned char *isdn_ppp_skb_push(struct sk_buff **skb_p,int len)
1105{
1106	struct sk_buff *skb = *skb_p;
1107
1108	if(skb_headroom(skb) < len) {
1109		struct sk_buff *nskb = skb_realloc_headroom(skb, len);
1110
1111		if (!nskb) {
1112			printk(KERN_ERR "isdn_ppp_skb_push: can't realloc headroom!\n");
1113			dev_kfree_skb(skb);
1114			return NULL;
1115		}
1116		printk(KERN_DEBUG "isdn_ppp_skb_push:under %d %d\n",skb_headroom(skb),len);
1117		dev_kfree_skb(skb);
1118		*skb_p = nskb;
1119		return skb_push(nskb, len);
1120	}
1121	return skb_push(skb,len);
1122}
1123
1124
1125/*
1126 * send ppp frame .. we expect a PIDCOMPressable proto --
1127 *  (here: currently always PPP_IP,PPP_VJC_COMP,PPP_VJC_UNCOMP)
1128 *
1129 * VJ compression may change skb pointer!!! .. requeue with old
1130 * skb isn't allowed!!
1131 */
1132
1133int
1134isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
1135{
1136	isdn_net_local *lp,*mlp;
1137	isdn_net_dev *nd;
1138	unsigned int proto = PPP_IP;     /* 0x21 */
1139	struct ippp_struct *ipt,*ipts;
1140	int slot, retval = 0;
1141
1142	mlp = (isdn_net_local *) (netdev->priv);
1143	nd = mlp->netdev;       /* get master lp */
1144
1145	slot = mlp->ppp_slot;
1146	if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
1147		printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
1148			mlp->ppp_slot);
1149		kfree_skb(skb);
1150		goto out;
1151	}
1152	ipts = ippp_table[slot];
1153
1154	if (!(ipts->pppcfg & SC_ENABLE_IP)) {	/* PPP connected ? */
1155		if (ipts->debug & 0x1)
1156			printk(KERN_INFO "%s: IP frame delayed.\n", netdev->name);
1157		retval = 1;
1158		goto out;
1159	}
1160
1161	switch (ntohs(skb->protocol)) {
1162		case ETH_P_IP:
1163			proto = PPP_IP;
1164			break;
1165		case ETH_P_IPX:
1166			proto = PPP_IPX;	/* untested */
1167			break;
1168		default:
1169			printk(KERN_ERR "isdn_ppp: skipped unsupported protocol: %#x.\n",
1170			       skb->protocol);
1171			dev_kfree_skb(skb);
1172			goto out;
1173	}
1174
1175	lp = isdn_net_get_locked_lp(nd);
1176	if (!lp) {
1177		printk(KERN_WARNING "%s: all channels busy - requeuing!\n", netdev->name);
1178		retval = 1;
1179		goto unlock;
1180	}
1181	/* we have our lp locked from now on */
1182
1183	slot = lp->ppp_slot;
1184	if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
1185		printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
1186			lp->ppp_slot);
1187		kfree_skb(skb);
1188		goto unlock;
1189	}
1190	ipt = ippp_table[slot];
1191	lp->huptimer = 0;
1192
1193	/*
1194	 * after this line .. requeueing in the device queue is no longer allowed!!!
1195	 */
1196
1197	/* Pull off the fake header we stuck on earlier to keep
1198	 * the fragmentation code happy.
1199	 */
1200	skb_pull(skb,IPPP_MAX_HEADER);
1201
1202	if (ipt->debug & 0x4)
1203		printk(KERN_DEBUG "xmit skb, len %d\n", (int) skb->len);
1204        if (ipts->debug & 0x40)
1205                isdn_ppp_frame_log("xmit0", skb->data, skb->len, 32,ipts->unit,lp->ppp_slot);
1206
1207#ifdef CONFIG_ISDN_PPP_VJ
1208	if (proto == PPP_IP && ipts->pppcfg & SC_COMP_TCP) {	/* ipts here? probably yes, but check this again */
1209		struct sk_buff *new_skb;
1210	        unsigned short hl;
1211		/*
1212		 * we need to reserve enought space in front of
1213		 * sk_buff. old call to dev_alloc_skb only reserved
1214		 * 16 bytes, now we are looking what the driver want.
1215		 */
1216		hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen + IPPP_MAX_HEADER;
1217		/*
1218		 * Note: hl might still be insufficient because the method
1219		 * above does not account for a possibible MPPP slave channel
1220		 * which had larger HL header space requirements than the
1221		 * master.
1222		 */
1223		new_skb = alloc_skb(hl+skb->len, GFP_ATOMIC);
1224		if (new_skb) {
1225			u_char *buf;
1226			int pktlen;
1227
1228			skb_reserve(new_skb, hl);
1229			new_skb->dev = skb->dev;
1230			skb_put(new_skb, skb->len);
1231			buf = skb->data;
1232
1233			pktlen = slhc_compress(ipts->slcomp, skb->data, skb->len, new_skb->data,
1234				 &buf, !(ipts->pppcfg & SC_NO_TCP_CCID));
1235
1236			if (buf != skb->data) {
1237				if (new_skb->data != buf)
1238					printk(KERN_ERR "isdn_ppp: FATAL error after slhc_compress!!\n");
1239				dev_kfree_skb(skb);
1240				skb = new_skb;
1241			} else {
1242				dev_kfree_skb(new_skb);
1243			}
1244
1245			skb_trim(skb, pktlen);
1246			if (skb->data[0] & SL_TYPE_COMPRESSED_TCP) {	/* cslip? style -> PPP */
1247				proto = PPP_VJC_COMP;
1248				skb->data[0] ^= SL_TYPE_COMPRESSED_TCP;
1249			} else {
1250				if (skb->data[0] >= SL_TYPE_UNCOMPRESSED_TCP)
1251					proto = PPP_VJC_UNCOMP;
1252				skb->data[0] = (skb->data[0] & 0x0f) | 0x40;
1253			}
1254		}
1255	}
1256#endif
1257
1258	/*
1259	 * normal (single link) or bundle compression
1260	 */
1261	if(ipts->compflags & SC_COMP_ON) {
1262		/* We send compressed only if both down- und upstream
1263		   compression is negotiated, that means, CCP is up */
1264		if(ipts->compflags & SC_DECOMP_ON) {
1265			skb = isdn_ppp_compress(skb,&proto,ipt,ipts,0);
1266		} else {
1267			printk(KERN_DEBUG "isdn_ppp: CCP not yet up - sending as-is\n");
1268		}
1269	}
1270
1271	if (ipt->debug & 0x24)
1272		printk(KERN_DEBUG "xmit2 skb, len %d, proto %04x\n", (int) skb->len, proto);
1273
1274#ifdef CONFIG_ISDN_MPP
1275	if (ipt->mpppcfg & SC_MP_PROT) {
1276		/* we get mp_seqno from static isdn_net_local */
1277		long mp_seqno = ipts->mp_seqno;
1278		ipts->mp_seqno++;
1279		if (ipt->mpppcfg & SC_OUT_SHORT_SEQ) {
1280			unsigned char *data = isdn_ppp_skb_push(&skb, 3);
1281			if(!data)
1282				goto unlock;
1283			mp_seqno &= 0xfff;
1284			data[0] = MP_BEGIN_FRAG | MP_END_FRAG | ((mp_seqno >> 8) & 0xf);	/* (B)egin & (E)ndbit .. */
1285			data[1] = mp_seqno & 0xff;
1286			data[2] = proto;	/* PID compression */
1287		} else {
1288			unsigned char *data = isdn_ppp_skb_push(&skb, 5);
1289			if(!data)
1290				goto unlock;
1291			data[0] = MP_BEGIN_FRAG | MP_END_FRAG;	/* (B)egin & (E)ndbit .. */
1292			data[1] = (mp_seqno >> 16) & 0xff;	/* sequence number: 24bit */
1293			data[2] = (mp_seqno >> 8) & 0xff;
1294			data[3] = (mp_seqno >> 0) & 0xff;
1295			data[4] = proto;	/* PID compression */
1296		}
1297		proto = PPP_MP; /* MP Protocol, 0x003d */
1298	}
1299#endif
1300
1301	/*
1302	 * 'link in bundle' compression  ...
1303	 */
1304	if(ipt->compflags & SC_LINK_COMP_ON)
1305		skb = isdn_ppp_compress(skb,&proto,ipt,ipts,1);
1306
1307	if( (ipt->pppcfg & SC_COMP_PROT) && (proto <= 0xff) ) {
1308		unsigned char *data = isdn_ppp_skb_push(&skb,1);
1309		if(!data)
1310			goto unlock;
1311		data[0] = proto & 0xff;
1312	}
1313	else {
1314		unsigned char *data = isdn_ppp_skb_push(&skb,2);
1315		if(!data)
1316			goto unlock;
1317		data[0] = (proto >> 8) & 0xff;
1318		data[1] = proto & 0xff;
1319	}
1320	if(!(ipt->pppcfg & SC_COMP_AC)) {
1321		unsigned char *data = isdn_ppp_skb_push(&skb,2);
1322		if(!data)
1323			goto unlock;
1324		data[0] = 0xff;    /* All Stations */
1325		data[1] = 0x03;    /* Unnumbered information */
1326	}
1327
1328	/* tx-stats are now updated via BSENT-callback */
1329
1330	if (ipts->debug & 0x40) {
1331		printk(KERN_DEBUG "skb xmit: len: %d\n", (int) skb->len);
1332		isdn_ppp_frame_log("xmit", skb->data, skb->len, 32,ipt->unit,lp->ppp_slot);
1333	}
1334
1335	isdn_net_writebuf_skb(lp, skb);
1336
1337 unlock:
1338	spin_unlock_bh(&lp->xmit_lock);
1339 out:
1340	return retval;
1341}
1342
1343#ifdef CONFIG_ISDN_MPP
1344
1345/* this is _not_ rfc1990 header, but something we convert both short and long
1346 * headers to for convinience's sake:
1347 * 	byte 0 is flags as in rfc1990
1348 *	bytes 1...4 is 24-bit seqence number converted to host byte order
1349 */
1350#define MP_HEADER_LEN	5
1351
1352#define MP_LONGSEQ_MASK		0x00ffffff
1353#define MP_SHORTSEQ_MASK	0x00000fff
1354#define MP_LONGSEQ_MAX		MP_LONGSEQ_MASK
1355#define MP_SHORTSEQ_MAX		MP_SHORTSEQ_MASK
1356#define MP_LONGSEQ_MAXBIT	((MP_LONGSEQ_MASK+1)>>1)
1357#define MP_SHORTSEQ_MAXBIT	((MP_SHORTSEQ_MASK+1)>>1)
1358
1359/* sequence-wrap safe comparisions (for long sequence)*/
1360#define MP_LT(a,b)	((a-b)&MP_LONGSEQ_MAXBIT)
1361#define MP_LE(a,b) 	!((b-a)&MP_LONGSEQ_MAXBIT)
1362#define MP_GT(a,b) 	((b-a)&MP_LONGSEQ_MAXBIT)
1363#define MP_GE(a,b)	!((a-b)&MP_LONGSEQ_MAXBIT)
1364
1365#define MP_SEQ(f)	((*(u32*)(f->data+1)))
1366#define MP_FLAGS(f)	(f->data[0])
1367
1368static int isdn_ppp_mp_bundle_array_init(void)
1369{
1370	int i;
1371	int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle);
1372	if( (isdn_ppp_bundle_arr = (ippp_bundle*)kmalloc(sz,
1373							GFP_KERNEL)) == NULL )
1374		return -ENOMEM;
1375	memset(isdn_ppp_bundle_arr, 0, sz);
1376	for( i = 0; i < ISDN_MAX_CHANNELS; i++ )
1377		spin_lock_init(&isdn_ppp_bundle_arr[i].lock);
1378	return 0;
1379}
1380
1381static ippp_bundle * isdn_ppp_mp_bundle_alloc(void)
1382{
1383	int i;
1384	for( i = 0; i < ISDN_MAX_CHANNELS; i++ )
1385		if (isdn_ppp_bundle_arr[i].ref_ct <= 0)
1386			return (isdn_ppp_bundle_arr + i);
1387	return NULL;
1388}
1389
1390static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
1391{
1392	struct ippp_struct * is;
1393
1394	if (lp->ppp_slot < 0) {
1395		printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d) out of range\n",
1396			lp->ppp_slot);
1397		return(-EINVAL);
1398	}
1399
1400	is = ippp_table[lp->ppp_slot];
1401	if (add_to) {
1402		if( lp->netdev->pb )
1403			lp->netdev->pb->ref_ct--;
1404		lp->netdev->pb = add_to;
1405	} else {		/* first link in a bundle */
1406		is->mp_seqno = 0;
1407		if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL)
1408			return -ENOMEM;
1409		lp->next = lp->last = lp;	/* nobody else in a queue */
1410		lp->netdev->pb->frags = NULL;
1411		lp->netdev->pb->frames = 0;
1412		lp->netdev->pb->seq = LONG_MAX;
1413	}
1414	lp->netdev->pb->ref_ct++;
1415
1416	is->last_link_seqno = 0;
1417	return 0;
1418}
1419
1420static u32 isdn_ppp_mp_get_seq( int short_seq,
1421					struct sk_buff * skb, u32 last_seq );
1422static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
1423			struct sk_buff * from, struct sk_buff * to );
1424static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
1425				struct sk_buff * from, struct sk_buff * to );
1426static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb );
1427static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb );
1428
1429static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
1430							struct sk_buff *skb)
1431{
1432	struct ippp_struct *is;
1433	isdn_net_local * lpq;
1434	ippp_bundle * mp;
1435	isdn_mppp_stats * stats;
1436	struct sk_buff * newfrag, * frag, * start, *nextf;
1437	u32 newseq, minseq, thisseq;
1438	unsigned long flags;
1439	int slot;
1440
1441	spin_lock_irqsave(&net_dev->pb->lock, flags);
1442    	mp = net_dev->pb;
1443        stats = &mp->stats;
1444	slot = lp->ppp_slot;
1445	if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
1446		printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d)\n",
1447			lp->ppp_slot);
1448		stats->frame_drops++;
1449		dev_kfree_skb(skb);
1450		spin_unlock_irqrestore(&mp->lock, flags);
1451		return;
1452	}
1453	is = ippp_table[slot];
1454    	if( ++mp->frames > stats->max_queue_len )
1455		stats->max_queue_len = mp->frames;
1456
1457	if (is->debug & 0x8)
1458		isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb);
1459
1460	newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ,
1461						skb, is->last_link_seqno);
1462
1463
1464	/* if this packet seq # is less than last already processed one,
1465	 * toss it right away, but check for sequence start case first
1466	 */
1467	if( mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT) ) {
1468		mp->seq = newseq;	/* the first packet: required for
1469					 * rfc1990 non-compliant clients --
1470					 * prevents constant packet toss */
1471	} else if( MP_LT(newseq, mp->seq) ) {
1472		stats->frame_drops++;
1473		isdn_ppp_mp_free_skb(mp, skb);
1474		spin_unlock_irqrestore(&mp->lock, flags);
1475		return;
1476	}
1477
1478	/* find the minimum received sequence number over all links */
1479	is->last_link_seqno = minseq = newseq;
1480	for (lpq = net_dev->queue;;) {
1481		slot = lpq->ppp_slot;
1482		if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
1483			printk(KERN_ERR __FUNCTION__": lpq->ppp_slot(%d)\n",
1484				lpq->ppp_slot);
1485		} else {
1486			u32 lls = ippp_table[slot]->last_link_seqno;
1487			if (MP_LT(lls, minseq))
1488				minseq = lls;
1489		}
1490		if ((lpq = lpq->next) == net_dev->queue)
1491			break;
1492	}
1493	if (MP_LT(minseq, mp->seq))
1494		minseq = mp->seq;	/* can't go beyond already processed
1495					 * packets */
1496	newfrag = skb;
1497
1498  	/* if this new fragment is before the first one, then enqueue it now. */
1499  	if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) {
1500		newfrag->next = frag;
1501    		mp->frags = frag = newfrag;
1502    		newfrag = NULL;
1503  	}
1504
1505  	start = MP_FLAGS(frag) & MP_BEGIN_FRAG &&
1506				MP_SEQ(frag) == mp->seq ? frag : NULL;
1507
1508	/*
1509	 * main fragment traversing loop
1510	 *
1511	 * try to accomplish several tasks:
1512	 * - insert new fragment into the proper sequence slot (once that's done
1513	 *   newfrag will be set to NULL)
1514	 * - reassemble any complete fragment sequence (non-null 'start'
1515	 *   indicates there is a continguous sequence present)
1516	 * - discard any incomplete sequences that are below minseq -- due
1517	 *   to the fact that sender always increment sequence number, if there
1518	 *   is an incomplete sequence below minseq, no new fragments would
1519	 *   come to complete such sequence and it should be discarded
1520	 *
1521	 * loop completes when we accomplished the following tasks:
1522	 * - new fragment is inserted in the proper sequence ('newfrag' is
1523	 *   set to NULL)
1524	 * - we hit a gap in the sequence, so no reassembly/processing is
1525	 *   possible ('start' would be set to NULL)
1526	 *
1527	 * algorightm for this code is derived from code in the book
1528	 * 'PPP Design And Debugging' by James Carlson (Addison-Wesley)
1529	 */
1530  	while (start != NULL || newfrag != NULL) {
1531
1532    		thisseq = MP_SEQ(frag);
1533    		nextf = frag->next;
1534
1535    		/* drop any duplicate fragments */
1536    		if (newfrag != NULL && thisseq == newseq) {
1537      			isdn_ppp_mp_free_skb(mp, newfrag);
1538      			newfrag = NULL;
1539    		}
1540
1541    		/* insert new fragment before next element if possible. */
1542    		if (newfrag != NULL && (nextf == NULL ||
1543						MP_LT(newseq, MP_SEQ(nextf)))) {
1544      			newfrag->next = nextf;
1545      			frag->next = nextf = newfrag;
1546      			newfrag = NULL;
1547    		}
1548
1549    		if (start != NULL) {
1550	    		/* check for misplaced start */
1551      			if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
1552				printk(KERN_WARNING"isdn_mppp(seq %d): new "
1553				      "BEGIN flag with no prior END", thisseq);
1554				stats->seqerrs++;
1555				stats->frame_drops++;
1556				start = isdn_ppp_mp_discard(mp, start,frag);
1557				nextf = frag->next;
1558      			}
1559    		} else if (MP_LE(thisseq, minseq)) {
1560      			if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
1561				start = frag;
1562      			else {
1563				if (MP_FLAGS(frag) & MP_END_FRAG)
1564	  				stats->frame_drops++;
1565				if( mp->frags == frag )
1566					mp->frags = nextf;
1567				isdn_ppp_mp_free_skb(mp, frag);
1568				frag = nextf;
1569				continue;
1570      			}
1571		}
1572
1573		/* if start is non-null and we have end fragment, then
1574		 * we have full reassembly sequence -- reassemble
1575		 * and process packet now
1576		 */
1577    		if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) {
1578      			minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK;
1579      			/* Reassemble the packet then dispatch it */
1580			isdn_ppp_mp_reassembly(net_dev, lp, start, nextf);
1581
1582      			start = NULL;
1583      			frag = NULL;
1584
1585      			mp->frags = nextf;
1586    		}
1587
1588		/* check if need to update start pointer: if we just
1589		 * reassembled the packet and sequence is contiguous
1590		 * then next fragment should be the start of new reassembly
1591		 * if sequence is contiguous, but we haven't reassembled yet,
1592		 * keep going.
1593		 * if sequence is not contiguous, either clear everyting
1594		 * below low watermark and set start to the next frag or
1595		 * clear start ptr.
1596		 */
1597    		if (nextf != NULL &&
1598		    ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) {
1599      			/* if we just reassembled and the next one is here,
1600			 * then start another reassembly. */
1601
1602      			if (frag == NULL) {
1603				if (MP_FLAGS(nextf) & MP_BEGIN_FRAG)
1604	  				start = nextf;
1605				else
1606				{
1607	  				printk(KERN_WARNING"isdn_mppp(seq %d):"
1608						" END flag with no following "
1609						"BEGIN", thisseq);
1610					stats->seqerrs++;
1611				}
1612			}
1613
1614    		} else {
1615			if ( nextf != NULL && frag != NULL &&
1616						MP_LT(thisseq, minseq)) {
1617				/* we've got a break in the sequence
1618				 * and we not at the end yet
1619				 * and we did not just reassembled
1620				 *(if we did, there wouldn't be anything before)
1621				 * and we below the low watermark
1622			 	 * discard all the frames below low watermark
1623				 * and start over */
1624				stats->frame_drops++;
1625				mp->frags = isdn_ppp_mp_discard(mp,start,nextf);
1626			}
1627			/* break in the sequence, no reassembly */
1628      			start = NULL;
1629    		}
1630
1631    		frag = nextf;
1632  	}	/* while -- main loop */
1633
1634  	if (mp->frags == NULL)
1635    		mp->frags = frag;
1636
1637	/* rather straighforward way to deal with (not very) possible
1638	 * queue overflow */
1639	if (mp->frames > MP_MAX_QUEUE_LEN) {
1640		stats->overflows++;
1641		while (mp->frames > MP_MAX_QUEUE_LEN) {
1642			frag = mp->frags->next;
1643			isdn_ppp_mp_free_skb(mp, mp->frags);
1644			mp->frags = frag;
1645		}
1646	}
1647	spin_unlock_irqrestore(&mp->lock, flags);
1648}
1649
1650static void isdn_ppp_mp_cleanup( isdn_net_local * lp )
1651{
1652	struct sk_buff * frag = lp->netdev->pb->frags;
1653	struct sk_buff * nextfrag;
1654    	while( frag ) {
1655		nextfrag = frag->next;
1656		isdn_ppp_mp_free_skb(lp->netdev->pb, frag);
1657		frag = nextfrag;
1658	}
1659	lp->netdev->pb->frags = NULL;
1660}
1661
1662static u32 isdn_ppp_mp_get_seq( int short_seq,
1663					struct sk_buff * skb, u32 last_seq )
1664{
1665	u32 seq;
1666	int flags = skb->data[0] & (MP_BEGIN_FRAG | MP_END_FRAG);
1667
1668   	if( !short_seq )
1669	{
1670		seq = ntohl(*(u32*)skb->data) & MP_LONGSEQ_MASK;
1671		skb_push(skb,1);
1672	}
1673	else
1674	{
1675		/* convert 12-bit short seq number to 24-bit long one
1676	 	*/
1677		seq = ntohs(*(u16*)skb->data) & MP_SHORTSEQ_MASK;
1678
1679		/* check for seqence wrap */
1680		if( !(seq &  MP_SHORTSEQ_MAXBIT) &&
1681		     (last_seq &  MP_SHORTSEQ_MAXBIT) &&
1682		     (unsigned long)last_seq <= MP_LONGSEQ_MAX )
1683			seq |= (last_seq + MP_SHORTSEQ_MAX+1) &
1684					(~MP_SHORTSEQ_MASK & MP_LONGSEQ_MASK);
1685		else
1686			seq |= last_seq & (~MP_SHORTSEQ_MASK & MP_LONGSEQ_MASK);
1687
1688		skb_push(skb, 3);	/* put converted seqence back in skb */
1689	}
1690	*(u32*)(skb->data+1) = seq; 	/* put seqence back in _host_ byte
1691					 * order */
1692	skb->data[0] = flags;	        /* restore flags */
1693	return seq;
1694}
1695
1696struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
1697			struct sk_buff * from, struct sk_buff * to )
1698{
1699	if( from )
1700		while (from != to) {
1701	  		struct sk_buff * next = from->next;
1702			isdn_ppp_mp_free_skb(mp, from);
1703	  		from = next;
1704		}
1705	return from;
1706}
1707
1708void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
1709				struct sk_buff * from, struct sk_buff * to )
1710{
1711	ippp_bundle * mp = net_dev->pb;
1712	int proto;
1713	struct sk_buff * skb;
1714	unsigned int tot_len;
1715
1716	if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
1717		printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d) out of range\n",
1718			lp->ppp_slot);
1719		return;
1720	}
1721	if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) {
1722		if( ippp_table[lp->ppp_slot]->debug & 0x40 )
1723			printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, "
1724					"len %d\n", MP_SEQ(from), from->len );
1725		skb = from;
1726		skb_pull(skb, MP_HEADER_LEN);
1727		mp->frames--;
1728	} else {
1729		struct sk_buff * frag;
1730		int n;
1731
1732		for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++)
1733			tot_len += frag->len - MP_HEADER_LEN;
1734
1735		if( ippp_table[lp->ppp_slot]->debug & 0x40 )
1736			printk(KERN_DEBUG"isdn_mppp: reassembling frames %d "
1737				"to %d, len %d\n", MP_SEQ(from),
1738				(MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len );
1739		if( (skb = dev_alloc_skb(tot_len)) == NULL ) {
1740			printk(KERN_ERR "isdn_mppp: cannot allocate sk buff "
1741					"of size %d\n", tot_len);
1742			isdn_ppp_mp_discard(mp, from, to);
1743			return;
1744		}
1745
1746		while( from != to ) {
1747			unsigned int len = from->len - MP_HEADER_LEN;
1748
1749			memcpy(skb_put(skb,len), from->data+MP_HEADER_LEN, len);
1750			frag = from->next;
1751			isdn_ppp_mp_free_skb(mp, from);
1752			from = frag;
1753		}
1754	}
1755   	proto = isdn_ppp_strip_proto(skb);
1756	isdn_ppp_push_higher(net_dev, lp, skb, proto);
1757}
1758
1759static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb)
1760{
1761	dev_kfree_skb(skb);
1762	mp->frames--;
1763}
1764
1765static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb )
1766{
1767	printk(KERN_DEBUG "mp_recv: %d/%d -> %02x %02x %02x %02x %02x %02x\n",
1768		slot, (int) skb->len,
1769		(int) skb->data[0], (int) skb->data[1], (int) skb->data[2],
1770		(int) skb->data[3], (int) skb->data[4], (int) skb->data[5]);
1771}
1772
1773static int
1774isdn_ppp_bundle(struct ippp_struct *is, int unit)
1775{
1776	char ifn[IFNAMSIZ + 1];
1777	isdn_net_dev *p;
1778	isdn_net_local *lp, *nlp;
1779	int rc;
1780	unsigned long flags;
1781
1782	sprintf(ifn, "ippp%d", unit);
1783	p = isdn_net_findif(ifn);
1784	if (!p) {
1785		printk(KERN_ERR "ippp_bundle: cannot find %s\n", ifn);
1786		return -EINVAL;
1787	}
1788
1789    	spin_lock_irqsave(&p->pb->lock, flags);
1790
1791	nlp = is->lp;
1792	lp = p->queue;
1793	if( nlp->ppp_slot < 0 || nlp->ppp_slot >= ISDN_MAX_CHANNELS ||
1794		lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS ) {
1795		printk(KERN_ERR "ippp_bundle: binding to invalid slot %d\n",
1796			nlp->ppp_slot < 0 || nlp->ppp_slot >= ISDN_MAX_CHANNELS ?
1797			nlp->ppp_slot : lp->ppp_slot );
1798		rc = -EINVAL;
1799		goto out;
1800 	}
1801
1802	isdn_net_add_to_bundle(p, nlp);
1803
1804	ippp_table[nlp->ppp_slot]->unit = ippp_table[lp->ppp_slot]->unit;
1805
1806	/* maybe also SC_CCP stuff */
1807	ippp_table[nlp->ppp_slot]->pppcfg |= ippp_table[lp->ppp_slot]->pppcfg &
1808		(SC_ENABLE_IP | SC_NO_TCP_CCID | SC_REJ_COMP_TCP);
1809	ippp_table[nlp->ppp_slot]->mpppcfg |= ippp_table[lp->ppp_slot]->mpppcfg &
1810		(SC_MP_PROT | SC_REJ_MP_PROT | SC_OUT_SHORT_SEQ | SC_IN_SHORT_SEQ);
1811	rc = isdn_ppp_mp_init(nlp, p->pb);
1812out:
1813	spin_unlock_irqrestore(&p->pb->lock, flags);
1814	return rc;
1815}
1816
1817#endif /* CONFIG_ISDN_MPP */
1818
1819/*
1820 * network device ioctl handlers
1821 */
1822
1823static int
1824isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct net_device *dev)
1825{
1826	struct ppp_stats *res,
1827	 t;
1828	isdn_net_local *lp = (isdn_net_local *) dev->priv;
1829	int err;
1830
1831	res = (struct ppp_stats *) ifr->ifr_ifru.ifru_data;
1832	err = verify_area(VERIFY_WRITE, res, sizeof(struct ppp_stats));
1833
1834	if (err)
1835		return err;
1836
1837	/* build a temporary stat struct and copy it to user space */
1838
1839	memset(&t, 0, sizeof(struct ppp_stats));
1840	if (dev->flags & IFF_UP) {
1841		t.p.ppp_ipackets = lp->stats.rx_packets;
1842		t.p.ppp_ibytes = lp->stats.rx_bytes;
1843		t.p.ppp_ierrors = lp->stats.rx_errors;
1844		t.p.ppp_opackets = lp->stats.tx_packets;
1845		t.p.ppp_obytes = lp->stats.tx_bytes;
1846		t.p.ppp_oerrors = lp->stats.tx_errors;
1847#ifdef CONFIG_ISDN_PPP_VJ
1848		if (slot >= 0 && ippp_table[slot]->slcomp) {
1849			struct slcompress *slcomp = ippp_table[slot]->slcomp;
1850			t.vj.vjs_packets = slcomp->sls_o_compressed + slcomp->sls_o_uncompressed;
1851			t.vj.vjs_compressed = slcomp->sls_o_compressed;
1852			t.vj.vjs_searches = slcomp->sls_o_searches;
1853			t.vj.vjs_misses = slcomp->sls_o_misses;
1854			t.vj.vjs_errorin = slcomp->sls_i_error;
1855			t.vj.vjs_tossed = slcomp->sls_i_tossed;
1856			t.vj.vjs_uncompressedin = slcomp->sls_i_uncompressed;
1857			t.vj.vjs_compressedin = slcomp->sls_i_compressed;
1858		}
1859#endif
1860	}
1861	if( copy_to_user(res, &t, sizeof(struct ppp_stats))) return -EFAULT;
1862	return 0;
1863}
1864
1865int
1866isdn_ppp_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1867{
1868	int error=0;
1869	char *r;
1870	int len;
1871	isdn_net_local *lp = (isdn_net_local *) dev->priv;
1872
1873
1874	if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
1875		return -EINVAL;
1876
1877	switch (cmd) {
1878		case SIOCGPPPVER:
1879			r = (char *) ifr->ifr_ifru.ifru_data;
1880			len = strlen(PPP_VERSION) + 1;
1881			if(copy_to_user(r, PPP_VERSION, len)) error = -EFAULT;
1882			break;
1883		case SIOCGPPPSTATS:
1884			error = isdn_ppp_dev_ioctl_stats(lp->ppp_slot, ifr, dev);
1885			break;
1886		default:
1887			error = -EINVAL;
1888			break;
1889	}
1890	return error;
1891}
1892
1893static int
1894isdn_ppp_if_get_unit(char *name)
1895{
1896	int len,
1897	 i,
1898	 unit = 0,
1899	 deci;
1900
1901	len = strlen(name);
1902
1903	if (strncmp("ippp", name, 4) || len > 8)
1904		return -1;
1905
1906	for (i = 0, deci = 1; i < len; i++, deci *= 10) {
1907		char a = name[len - i - 1];
1908		if (a >= '0' && a <= '9')
1909			unit += (a - '0') * deci;
1910		else
1911			break;
1912	}
1913	if (!i || len - i != 4)
1914		unit = -1;
1915
1916	return unit;
1917}
1918
1919
1920int
1921isdn_ppp_dial_slave(char *name)
1922{
1923#ifdef CONFIG_ISDN_MPP
1924	isdn_net_dev *ndev;
1925	isdn_net_local *lp;
1926	struct net_device *sdev;
1927
1928	if (!(ndev = isdn_net_findif(name)))
1929		return 1;
1930	lp = ndev->local;
1931	if (!(lp->flags & ISDN_NET_CONNECTED))
1932		return 5;
1933
1934	sdev = lp->slave;
1935	while (sdev) {
1936		isdn_net_local *mlp = (isdn_net_local *) sdev->priv;
1937		if (!(mlp->flags & ISDN_NET_CONNECTED))
1938			break;
1939		sdev = mlp->slave;
1940	}
1941	if (!sdev)
1942		return 2;
1943
1944	isdn_net_dial_req((isdn_net_local *) sdev->priv);
1945	return 0;
1946#else
1947	return -1;
1948#endif
1949}
1950
1951int
1952isdn_ppp_hangup_slave(char *name)
1953{
1954#ifdef CONFIG_ISDN_MPP
1955	isdn_net_dev *ndev;
1956	isdn_net_local *lp;
1957	struct net_device *sdev;
1958
1959	if (!(ndev = isdn_net_findif(name)))
1960		return 1;
1961	lp = ndev->local;
1962	if (!(lp->flags & ISDN_NET_CONNECTED))
1963		return 5;
1964
1965	sdev = lp->slave;
1966	while (sdev) {
1967		isdn_net_local *mlp = (isdn_net_local *) sdev->priv;
1968
1969		if (mlp->slave) { /* find last connected link in chain */
1970			isdn_net_local *nlp = (isdn_net_local *) mlp->slave->priv;
1971
1972			if (!(nlp->flags & ISDN_NET_CONNECTED))
1973				break;
1974		} else if (mlp->flags & ISDN_NET_CONNECTED)
1975			break;
1976
1977		sdev = mlp->slave;
1978	}
1979	if (!sdev)
1980		return 2;
1981
1982	isdn_net_hangup(sdev);
1983	return 0;
1984#else
1985	return -1;
1986#endif
1987}
1988
1989/*
1990 * PPP compression stuff
1991 */
1992
1993
1994/* Push an empty CCP Data Frame up to the daemon to wake it up and let it
1995   generate a CCP Reset-Request or tear down CCP altogether */
1996
1997static void isdn_ppp_ccp_kickup(struct ippp_struct *is)
1998{
1999	isdn_ppp_fill_rq(NULL, 0, PPP_COMP, is->lp->ppp_slot);
2000}
2001
2002/* In-kernel handling of CCP Reset-Request and Reset-Ack is necessary,
2003   but absolutely nontrivial. The most abstruse problem we are facing is
2004   that the generation, reception and all the handling of timeouts and
2005   resends including proper request id management should be entirely left
2006   to the (de)compressor, but indeed is not covered by the current API to
2007   the (de)compressor. The API is a prototype version from PPP where only
2008   some (de)compressors have yet been implemented and all of them are
2009   rather simple in their reset handling. Especially, their is only one
2010   outstanding ResetAck at a time with all of them and ResetReq/-Acks do
2011   not have parameters. For this very special case it was sufficient to
2012   just return an error code from the decompressor and have a single
2013   reset() entry to communicate all the necessary information between
2014   the framework and the (de)compressor. Bad enough, LZS is different
2015   (and any other compressor may be different, too). It has multiple
2016   histories (eventually) and needs to Reset each of them independently
2017   and thus uses multiple outstanding Acks and history numbers as an
2018   additional parameter to Reqs/Acks.
2019   All that makes it harder to port the reset state engine into the
2020   kernel because it is not just the same simple one as in (i)pppd but
2021   it must be able to pass additional parameters and have multiple out-
2022   standing Acks. We are trying to achieve the impossible by handling
2023   reset transactions independent by their id. The id MUST change when
2024   the data portion changes, thus any (de)compressor who uses more than
2025   one resettable state must provide and recognize individual ids for
2026   each individual reset transaction. The framework itself does _only_
2027   differentiate them by id, because it has no other semantics like the
2028   (de)compressor might.
2029   This looks like a major redesign of the interface would be nice,
2030   but I don't have an idea how to do it better. */
2031
2032/* Send a CCP Reset-Request or Reset-Ack directly from the kernel. This is
2033   getting that lengthy because there is no simple "send-this-frame-out"
2034   function above but every wrapper does a bit different. Hope I guess
2035   correct in this hack... */
2036
2037static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
2038				    unsigned char code, unsigned char id,
2039				    unsigned char *data, int len)
2040{
2041	struct sk_buff *skb;
2042	unsigned char *p;
2043	int hl;
2044	int cnt = 0;
2045	isdn_net_local *lp = is->lp;
2046
2047	/* Alloc large enough skb */
2048	hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
2049	skb = alloc_skb(len + hl + 16,GFP_ATOMIC);
2050	if(!skb) {
2051		printk(KERN_WARNING
2052		       "ippp: CCP cannot send reset - out of memory\n");
2053		return;
2054	}
2055	skb_reserve(skb, hl);
2056
2057	/* We may need to stuff an address and control field first */
2058	if(!(is->pppcfg & SC_COMP_AC)) {
2059		p = skb_put(skb, 2);
2060		*p++ = 0xff;
2061		*p++ = 0x03;
2062	}
2063
2064	/* Stuff proto, code, id and length */
2065	p = skb_put(skb, 6);
2066	*p++ = (proto >> 8);
2067	*p++ = (proto & 0xff);
2068	*p++ = code;
2069	*p++ = id;
2070	cnt = 4 + len;
2071	*p++ = (cnt >> 8);
2072	*p++ = (cnt & 0xff);
2073
2074	/* Now stuff remaining bytes */
2075	if(len) {
2076		p = skb_put(skb, len);
2077		memcpy(p, data, len);
2078	}
2079
2080	/* skb is now ready for xmit */
2081	printk(KERN_DEBUG "Sending CCP Frame:\n");
2082	isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
2083
2084	isdn_net_write_super(lp, skb);
2085}
2086
2087/* Allocate the reset state vector */
2088static struct ippp_ccp_reset *isdn_ppp_ccp_reset_alloc(struct ippp_struct *is)
2089{
2090	struct ippp_ccp_reset *r;
2091	r = kmalloc(sizeof(struct ippp_ccp_reset), GFP_KERNEL);
2092	if(!r) {
2093		printk(KERN_ERR "ippp_ccp: failed to allocate reset data"
2094		       " structure - no mem\n");
2095		return NULL;
2096	}
2097	memset(r, 0, sizeof(struct ippp_ccp_reset));
2098	printk(KERN_DEBUG "ippp_ccp: allocated reset data structure %p\n", r);
2099	is->reset = r;
2100	return r;
2101}
2102
2103/* Destroy the reset state vector. Kill all pending timers first. */
2104static void isdn_ppp_ccp_reset_free(struct ippp_struct *is)
2105{
2106	unsigned int id;
2107
2108	printk(KERN_DEBUG "ippp_ccp: freeing reset data structure %p\n",
2109	       is->reset);
2110	for(id = 0; id < 256; id++) {
2111		if(is->reset->rs[id]) {
2112			isdn_ppp_ccp_reset_free_state(is, (unsigned char)id);
2113		}
2114	}
2115	kfree(is->reset);
2116	is->reset = NULL;
2117}
2118
2119/* Free a given state and clear everything up for later reallocation */
2120static void isdn_ppp_ccp_reset_free_state(struct ippp_struct *is,
2121					  unsigned char id)
2122{
2123	struct ippp_ccp_reset_state *rs;
2124
2125	if(is->reset->rs[id]) {
2126		printk(KERN_DEBUG "ippp_ccp: freeing state for id %d\n", id);
2127		rs = is->reset->rs[id];
2128		/* Make sure the kernel will not call back later */
2129		if(rs->ta)
2130			del_timer(&rs->timer);
2131		is->reset->rs[id] = NULL;
2132		kfree(rs);
2133	} else {
2134		printk(KERN_WARNING "ippp_ccp: id %d is not allocated\n", id);
2135	}
2136}
2137
2138/* The timer callback function which is called when a ResetReq has timed out,
2139   aka has never been answered by a ResetAck */
2140static void isdn_ppp_ccp_timer_callback(unsigned long closure)
2141{
2142	struct ippp_ccp_reset_state *rs =
2143		(struct ippp_ccp_reset_state *)closure;
2144
2145	if(!rs) {
2146		printk(KERN_ERR "ippp_ccp: timer cb with zero closure.\n");
2147		return;
2148	}
2149	if(rs->ta && rs->state == CCPResetSentReq) {
2150		/* We are correct here */
2151		if(!rs->expra) {
2152			/* Hmm, there is no Ack really expected. We can clean
2153			   up the state now, it will be reallocated if the
2154			   decompressor insists on another reset */
2155			rs->ta = 0;
2156			isdn_ppp_ccp_reset_free_state(rs->is, rs->id);
2157			return;
2158		}
2159		printk(KERN_DEBUG "ippp_ccp: CCP Reset timed out for id %d\n",
2160		       rs->id);
2161		/* Push it again */
2162		isdn_ppp_ccp_xmit_reset(rs->is, PPP_CCP, CCP_RESETREQ, rs->id,
2163					rs->data, rs->dlen);
2164		/* Restart timer */
2165		rs->timer.expires = jiffies + HZ*5;
2166		add_timer(&rs->timer);
2167	} else {
2168		printk(KERN_WARNING "ippp_ccp: timer cb in wrong state %d\n",
2169		       rs->state);
2170	}
2171}
2172
2173/* Allocate a new reset transaction state */
2174static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_struct *is,
2175						      unsigned char id)
2176{
2177	struct ippp_ccp_reset_state *rs;
2178	if(is->reset->rs[id]) {
2179		printk(KERN_WARNING "ippp_ccp: old state exists for id %d\n",
2180		       id);
2181		return NULL;
2182	} else {
2183		rs = kmalloc(sizeof(struct ippp_ccp_reset_state), GFP_KERNEL);
2184		if(!rs)
2185			return NULL;
2186		memset(rs, 0, sizeof(struct ippp_ccp_reset_state));
2187		rs->state = CCPResetIdle;
2188		rs->is = is;
2189		rs->id = id;
2190		rs->timer.data = (unsigned long)rs;
2191		rs->timer.function = isdn_ppp_ccp_timer_callback;
2192		is->reset->rs[id] = rs;
2193	}
2194	return rs;
2195}
2196
2197
2198/* A decompressor wants a reset with a set of parameters - do what is
2199   necessary to fulfill it */
2200static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
2201				     struct isdn_ppp_resetparams *rp)
2202{
2203	struct ippp_ccp_reset_state *rs;
2204
2205	if(rp->valid) {
2206		/* The decompressor defines parameters by itself */
2207		if(rp->rsend) {
2208			/* And he wants us to send a request */
2209			if(!(rp->idval)) {
2210				printk(KERN_ERR "ippp_ccp: decompressor must"
2211				       " specify reset id\n");
2212				return;
2213			}
2214			if(is->reset->rs[rp->id]) {
2215				/* There is already a transaction in existence
2216				   for this id. May be still waiting for a
2217				   Ack or may be wrong. */
2218				rs = is->reset->rs[rp->id];
2219				if(rs->state == CCPResetSentReq && rs->ta) {
2220					printk(KERN_DEBUG "ippp_ccp: reset"
2221					       " trans still in progress"
2222					       " for id %d\n", rp->id);
2223				} else {
2224					printk(KERN_WARNING "ippp_ccp: reset"
2225					       " trans in wrong state %d for"
2226					       " id %d\n", rs->state, rp->id);
2227				}
2228			} else {
2229				/* Ok, this is a new transaction */
2230				printk(KERN_DEBUG "ippp_ccp: new trans for id"
2231				       " %d to be started\n", rp->id);
2232				rs = isdn_ppp_ccp_reset_alloc_state(is, rp->id);
2233				if(!rs) {
2234					printk(KERN_ERR "ippp_ccp: out of mem"
2235					       " allocing ccp trans\n");
2236					return;
2237				}
2238				rs->state = CCPResetSentReq;
2239				rs->expra = rp->expra;
2240				if(rp->dtval) {
2241					rs->dlen = rp->dlen;
2242					memcpy(rs->data, rp->data, rp->dlen);
2243				}
2244				/* HACK TODO - add link comp here */
2245				isdn_ppp_ccp_xmit_reset(is, PPP_CCP,
2246							CCP_RESETREQ, rs->id,
2247							rs->data, rs->dlen);
2248				/* Start the timer */
2249				rs->timer.expires = jiffies + 5*HZ;
2250				add_timer(&rs->timer);
2251				rs->ta = 1;
2252			}
2253		} else {
2254			printk(KERN_DEBUG "ippp_ccp: no reset sent\n");
2255		}
2256	} else {
2257		/* The reset params are invalid. The decompressor does not
2258		   care about them, so we just send the minimal requests
2259		   and increase ids only when an Ack is received for a
2260		   given id */
2261		if(is->reset->rs[is->reset->lastid]) {
2262			/* There is already a transaction in existence
2263			   for this id. May be still waiting for a
2264			   Ack or may be wrong. */
2265			rs = is->reset->rs[is->reset->lastid];
2266			if(rs->state == CCPResetSentReq && rs->ta) {
2267				printk(KERN_DEBUG "ippp_ccp: reset"
2268				       " trans still in progress"
2269				       " for id %d\n", rp->id);
2270			} else {
2271				printk(KERN_WARNING "ippp_ccp: reset"
2272				       " trans in wrong state %d for"
2273				       " id %d\n", rs->state, rp->id);
2274			}
2275		} else {
2276			printk(KERN_DEBUG "ippp_ccp: new trans for id"
2277			       " %d to be started\n", is->reset->lastid);
2278			rs = isdn_ppp_ccp_reset_alloc_state(is,
2279							    is->reset->lastid);
2280			if(!rs) {
2281				printk(KERN_ERR "ippp_ccp: out of mem"
2282				       " allocing ccp trans\n");
2283				return;
2284			}
2285			rs->state = CCPResetSentReq;
2286			/* We always expect an Ack if the decompressor doesn't
2287			   know	better */
2288			rs->expra = 1;
2289			rs->dlen = 0;
2290			/* HACK TODO - add link comp here */
2291			isdn_ppp_ccp_xmit_reset(is, PPP_CCP, CCP_RESETREQ,
2292						rs->id, NULL, 0);
2293			/* Start the timer */
2294			rs->timer.expires = jiffies + 5*HZ;
2295			add_timer(&rs->timer);
2296			rs->ta = 1;
2297		}
2298	}
2299}
2300
2301/* An Ack was received for this id. This means we stop the timer and clean
2302   up the state prior to calling the decompressors reset routine. */
2303static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
2304					unsigned char id)
2305{
2306	struct ippp_ccp_reset_state *rs = is->reset->rs[id];
2307
2308	if(rs) {
2309		if(rs->ta && rs->state == CCPResetSentReq) {
2310			/* Great, we are correct */
2311			if(!rs->expra)
2312				printk(KERN_DEBUG "ippp_ccp: ResetAck received"
2313				       " for id %d but not expected\n", id);
2314		} else {
2315			printk(KERN_INFO "ippp_ccp: ResetAck received out of"
2316			       "sync for id %d\n", id);
2317		}
2318		if(rs->ta) {
2319			rs->ta = 0;
2320			del_timer(&rs->timer);
2321		}
2322		isdn_ppp_ccp_reset_free_state(is, id);
2323	} else {
2324		printk(KERN_INFO "ippp_ccp: ResetAck received for unknown id"
2325		       " %d\n", id);
2326	}
2327	/* Make sure the simple reset stuff uses a new id next time */
2328	is->reset->lastid++;
2329}
2330
2331/*
2332 * decompress packet
2333 *
2334 * if master = 0, we're trying to uncompress an per-link compressed packet,
2335 * as opposed to an compressed reconstructed-from-MPPP packet.
2336 * proto is updated to protocol field of uncompressed packet.
2337 *
2338 * retval: decompressed packet,
2339 *         same packet if uncompressed,
2340 *	   NULL if decompression error
2341 */
2342
2343static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struct *is,struct ippp_struct *master,
2344	int *proto)
2345{
2346	void *stat = NULL;
2347	struct isdn_ppp_compressor *ipc = NULL;
2348	struct sk_buff *skb_out;
2349	int len;
2350	struct ippp_struct *ri;
2351	struct isdn_ppp_resetparams rsparm;
2352	unsigned char rsdata[IPPP_RESET_MAXDATABYTES];
2353
2354	if(!master) {
2355		// per-link decompression
2356		stat = is->link_decomp_stat;
2357		ipc = is->link_decompressor;
2358		ri = is;
2359	} else {
2360		stat = master->decomp_stat;
2361		ipc = master->decompressor;
2362		ri = master;
2363	}
2364
2365	if (!ipc) {
2366		// no decompressor -> we can't decompress.
2367		printk(KERN_DEBUG "ippp: no decompressor defined!\n");
2368		return skb;
2369	}
2370	if (!stat) // if we have a compressor, stat has been set as well
2371		BUG();
2372
2373	if((master && *proto == PPP_COMP) || (!master && *proto == PPP_COMPFRAG) ) {
2374		// compressed packets are compressed by their protocol type
2375
2376		// Set up reset params for the decompressor
2377  		memset(&rsparm, 0, sizeof(rsparm));
2378  		rsparm.data = rsdata;
2379  		rsparm.maxdlen = IPPP_RESET_MAXDATABYTES;
2380
2381  		skb_out = dev_alloc_skb(is->mru + PPP_HDRLEN);
2382		len = ipc->decompress(stat, skb, skb_out, &rsparm);
2383		kfree_skb(skb);
2384		if (len <= 0) {
2385			switch(len) {
2386			case DECOMP_ERROR:
2387				printk(KERN_INFO "ippp: decomp wants reset %s params\n",
2388				       rsparm.valid ? "with" : "without");
2389
2390				isdn_ppp_ccp_reset_trans(ri, &rsparm);
2391				break;
2392			case DECOMP_FATALERROR:
2393				ri->pppcfg |= SC_DC_FERROR;
2394				/* Kick ipppd to recognize the error */
2395				isdn_ppp_ccp_kickup(ri);
2396				break;
2397			}
2398			kfree_skb(skb_out);
2399			return NULL;
2400		}
2401		*proto = isdn_ppp_strip_proto(skb_out);
2402		if (*proto < 0) {
2403			kfree_skb(skb_out);
2404			return NULL;
2405		}
2406		return skb_out;
2407	} else {
2408		// uncompressed packets are fed through the decompressor to
2409		// update the decompressor state
2410		ipc->incomp(stat, skb, *proto);
2411		return skb;
2412	}
2413}
2414
2415/*
2416 * compress a frame
2417 *   type=0: normal/bundle compression
2418 *       =1: link compression
2419 * returns original skb if we haven't compressed the frame
2420 * and a new skb pointer if we've done it
2421 */
2422static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in,int *proto,
2423	struct ippp_struct *is,struct ippp_struct *master,int type)
2424{
2425    int ret;
2426    int new_proto;
2427    struct isdn_ppp_compressor *compressor;
2428    void *stat;
2429    struct sk_buff *skb_out;
2430
2431	/* we do not compress control protocols */
2432    if(*proto < 0 || *proto > 0x3fff) {
2433	    return skb_in;
2434    }
2435
2436	if(type) { /* type=1 => Link compression */
2437		return skb_in;
2438	}
2439	else {
2440		if(!master) {
2441			compressor = is->compressor;
2442			stat = is->comp_stat;
2443		}
2444		else {
2445			compressor = master->compressor;
2446			stat = master->comp_stat;
2447		}
2448		new_proto = PPP_COMP;
2449	}
2450
2451	if(!compressor) {
2452		printk(KERN_ERR "isdn_ppp: No compressor set!\n");
2453		return skb_in;
2454	}
2455	if(!stat) {
2456		printk(KERN_ERR "isdn_ppp: Compressor not initialized?\n");
2457		return skb_in;
2458	}
2459
2460	/* Allow for at least 150 % expansion (for now) */
2461	skb_out = alloc_skb(skb_in->len + skb_in->len/2 + 32 +
2462		skb_headroom(skb_in), GFP_ATOMIC);
2463	if(!skb_out)
2464		return skb_in;
2465	skb_reserve(skb_out, skb_headroom(skb_in));
2466
2467	ret = (compressor->compress)(stat,skb_in,skb_out,*proto);
2468	if(!ret) {
2469		dev_kfree_skb(skb_out);
2470		return skb_in;
2471	}
2472
2473	dev_kfree_skb(skb_in);
2474	*proto = new_proto;
2475	return skb_out;
2476}
2477
2478/*
2479 * we received a CCP frame ..
2480 * not a clean solution, but we MUST handle a few cases in the kernel
2481 */
2482static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
2483	 struct sk_buff *skb,int proto)
2484{
2485	struct ippp_struct *is;
2486	struct ippp_struct *mis;
2487	int len;
2488	struct isdn_ppp_resetparams rsparm;
2489	unsigned char rsdata[IPPP_RESET_MAXDATABYTES];
2490
2491	printk(KERN_DEBUG "Received CCP frame from peer slot(%d)\n",
2492		lp->ppp_slot);
2493	if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
2494		printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d) out of range\n",
2495			lp->ppp_slot);
2496		return;
2497	}
2498	is = ippp_table[lp->ppp_slot];
2499	isdn_ppp_frame_log("ccp-rcv", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
2500
2501	if(lp->master) {
2502		int slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot;
2503		if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
2504			printk(KERN_ERR __FUNCTION__": slot(%d) out of range\n",
2505				slot);
2506			return;
2507		}
2508		mis = ippp_table[slot];
2509	} else
2510		mis = is;
2511
2512	switch(skb->data[0]) {
2513	case CCP_CONFREQ:
2514		if(is->debug & 0x10)
2515			printk(KERN_DEBUG "Disable compression here!\n");
2516		if(proto == PPP_CCP)
2517			mis->compflags &= ~SC_COMP_ON;
2518		else
2519			is->compflags &= ~SC_LINK_COMP_ON;
2520		break;
2521	case CCP_TERMREQ:
2522	case CCP_TERMACK:
2523		if(is->debug & 0x10)
2524			printk(KERN_DEBUG "Disable (de)compression here!\n");
2525		if(proto == PPP_CCP)
2526			mis->compflags &= ~(SC_DECOMP_ON|SC_COMP_ON);
2527		else
2528			is->compflags &= ~(SC_LINK_DECOMP_ON|SC_LINK_COMP_ON);
2529		break;
2530	case CCP_CONFACK:
2531		/* if we RECEIVE an ackowledge we enable the decompressor */
2532		if(is->debug & 0x10)
2533			printk(KERN_DEBUG "Enable decompression here!\n");
2534		if(proto == PPP_CCP) {
2535			if (!mis->decompressor)
2536				break;
2537			mis->compflags |= SC_DECOMP_ON;
2538		} else {
2539			if (!is->decompressor)
2540				break;
2541			is->compflags |= SC_LINK_DECOMP_ON;
2542		}
2543		break;
2544
2545	case CCP_RESETACK:
2546		printk(KERN_DEBUG "Received ResetAck from peer\n");
2547		len = (skb->data[2] << 8) | skb->data[3];
2548		len -= 4;
2549
2550		if(proto == PPP_CCP) {
2551			/* If a reset Ack was outstanding for this id, then
2552			   clean up the state engine */
2553			isdn_ppp_ccp_reset_ack_rcvd(mis, skb->data[1]);
2554			if(mis->decompressor && mis->decomp_stat)
2555				mis->decompressor->
2556					reset(mis->decomp_stat,
2557					      skb->data[0],
2558					      skb->data[1],
2559					      len ? &skb->data[4] : NULL,
2560					      len, NULL);
2561			/* TODO: This is not easy to decide here */
2562			mis->compflags &= ~SC_DECOMP_DISCARD;
2563		}
2564		else {
2565			isdn_ppp_ccp_reset_ack_rcvd(is, skb->data[1]);
2566			if(is->link_decompressor && is->link_decomp_stat)
2567				is->link_decompressor->
2568					reset(is->link_decomp_stat,
2569					      skb->data[0],
2570					      skb->data[1],
2571					      len ? &skb->data[4] : NULL,
2572					      len, NULL);
2573			/* TODO: neither here */
2574			is->compflags &= ~SC_LINK_DECOMP_DISCARD;
2575		}
2576		break;
2577
2578	case CCP_RESETREQ:
2579		printk(KERN_DEBUG "Received ResetReq from peer\n");
2580		/* Receiving a ResetReq means we must reset our compressor */
2581		/* Set up reset params for the reset entry */
2582		memset(&rsparm, 0, sizeof(rsparm));
2583		rsparm.data = rsdata;
2584		rsparm.maxdlen = IPPP_RESET_MAXDATABYTES;
2585		/* Isolate data length */
2586		len = (skb->data[2] << 8) | skb->data[3];
2587		len -= 4;
2588		if(proto == PPP_CCP) {
2589			if(mis->compressor && mis->comp_stat)
2590				mis->compressor->
2591					reset(mis->comp_stat,
2592					      skb->data[0],
2593					      skb->data[1],
2594					      len ? &skb->data[4] : NULL,
2595					      len, &rsparm);
2596		}
2597		else {
2598			if(is->link_compressor && is->link_comp_stat)
2599				is->link_compressor->
2600					reset(is->link_comp_stat,
2601					      skb->data[0],
2602					      skb->data[1],
2603					      len ? &skb->data[4] : NULL,
2604					      len, &rsparm);
2605		}
2606		/* Ack the Req as specified by rsparm */
2607		if(rsparm.valid) {
2608			/* Compressor reset handler decided how to answer */
2609			if(rsparm.rsend) {
2610				/* We should send a Frame */
2611				isdn_ppp_ccp_xmit_reset(is, proto, CCP_RESETACK,
2612							rsparm.idval ? rsparm.id
2613							: skb->data[1],
2614							rsparm.dtval ?
2615							rsparm.data : NULL,
2616							rsparm.dtval ?
2617							rsparm.dlen : 0);
2618			} else {
2619				printk(KERN_DEBUG "ResetAck suppressed\n");
2620			}
2621		} else {
2622			/* We answer with a straight reflected Ack */
2623			isdn_ppp_ccp_xmit_reset(is, proto, CCP_RESETACK,
2624						skb->data[1],
2625						len ? &skb->data[4] : NULL,
2626						len);
2627		}
2628		break;
2629	}
2630}
2631
2632
2633/*
2634 * Daemon sends a CCP frame ...
2635 */
2636
2637/* TODO: Clean this up with new Reset semantics */
2638
2639/* I believe the CCP handling as-is is done wrong. Compressed frames
2640 * should only be sent/received after CCP reaches UP state, which means
2641 * both sides have sent CONF_ACK. Currently, we handle both directions
2642 * independently, which means we may accept compressed frames too early
2643 * (supposedly not a problem), but may also mean we send compressed frames
2644 * too early, which may turn out to be a problem.
2645 * This part of state machine should actually be handled by (i)pppd, but
2646 * that's too big of a change now. --kai
2647 */
2648
2649/* Actually, we might turn this into an advantage: deal with the RFC in
2650 * the old tradition of beeing generous on what we accept, but beeing
2651 * strict on what we send. Thus we should just
2652 * - accept compressed frames as soon as decompression is negotiated
2653 * - send compressed frames only when decomp *and* comp are negotiated
2654 * - drop rx compressed frames if we cannot decomp (instead of pushing them
2655 *   up to ipppd)
2656 * and I tried to modify this file according to that. --abp
2657 */
2658
2659static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *skb)
2660{
2661	struct ippp_struct *mis,*is;
2662	int proto, slot = lp->ppp_slot;
2663	unsigned char *data;
2664
2665	if(!skb || skb->len < 3)
2666		return;
2667	if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
2668		printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d) out of range\n",
2669			slot);
2670		return;
2671	}
2672	is = ippp_table[slot];
2673	/* Daemon may send with or without address and control field comp */
2674	data = skb->data;
2675	if(!(is->pppcfg & SC_COMP_AC) && data[0] == 0xff && data[1] == 0x03) {
2676		data += 2;
2677		if(skb->len < 5)
2678			return;
2679	}
2680
2681	proto = ((int)data[0]<<8)+data[1];
2682	if(proto != PPP_CCP && proto != PPP_CCPFRAG)
2683		return;
2684
2685	printk(KERN_DEBUG "Received CCP frame from daemon:\n");
2686	isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
2687
2688	if (lp->master) {
2689		slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot;
2690		if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
2691			printk(KERN_ERR __FUNCTION__": slot(%d) out of range\n",
2692				slot);
2693			return;
2694		}
2695		mis = ippp_table[slot];
2696	} else
2697		mis = is;
2698	if (mis != is)
2699		printk(KERN_DEBUG "isdn_ppp: Ouch! Master CCP sends on slave slot!\n");
2700
2701        switch(data[2]) {
2702	case CCP_CONFREQ:
2703		if(is->debug & 0x10)
2704			printk(KERN_DEBUG "Disable decompression here!\n");
2705		if(proto == PPP_CCP)
2706			is->compflags &= ~SC_DECOMP_ON;
2707		else
2708			is->compflags &= ~SC_LINK_DECOMP_ON;
2709		break;
2710	case CCP_TERMREQ:
2711	case CCP_TERMACK:
2712		if(is->debug & 0x10)
2713			printk(KERN_DEBUG "Disable (de)compression here!\n");
2714		if(proto == PPP_CCP)
2715			is->compflags &= ~(SC_DECOMP_ON|SC_COMP_ON);
2716		else
2717			is->compflags &= ~(SC_LINK_DECOMP_ON|SC_LINK_COMP_ON);
2718		break;
2719	case CCP_CONFACK:
2720		/* if we SEND an ackowledge we can/must enable the compressor */
2721		if(is->debug & 0x10)
2722			printk(KERN_DEBUG "Enable compression here!\n");
2723		if(proto == PPP_CCP) {
2724			if (!is->compressor)
2725				break;
2726			is->compflags |= SC_COMP_ON;
2727		} else {
2728			if (!is->compressor)
2729				break;
2730			is->compflags |= SC_LINK_COMP_ON;
2731		}
2732		break;
2733	case CCP_RESETACK:
2734		/* If we send a ACK we should reset our compressor */
2735		if(is->debug & 0x10)
2736			printk(KERN_DEBUG "Reset decompression state here!\n");
2737		printk(KERN_DEBUG "ResetAck from daemon passed by\n");
2738		if(proto == PPP_CCP) {
2739			/* link to master? */
2740			if(is->compressor && is->comp_stat)
2741				is->compressor->reset(is->comp_stat, 0, 0,
2742						      NULL, 0, NULL);
2743			is->compflags &= ~SC_COMP_DISCARD;
2744		}
2745		else {
2746			if(is->link_compressor && is->link_comp_stat)
2747				is->link_compressor->reset(is->link_comp_stat,
2748							   0, 0, NULL, 0, NULL);
2749			is->compflags &= ~SC_LINK_COMP_DISCARD;
2750		}
2751		break;
2752	case CCP_RESETREQ:
2753		/* Just let it pass by */
2754		printk(KERN_DEBUG "ResetReq from daemon passed by\n");
2755		break;
2756	}
2757}
2758
2759int isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc)
2760{
2761	ipc->next = ipc_head;
2762	ipc->prev = NULL;
2763	if(ipc_head) {
2764		ipc_head->prev = ipc;
2765	}
2766	ipc_head = ipc;
2767	return 0;
2768}
2769
2770int isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *ipc)
2771{
2772	if(ipc->prev)
2773		ipc->prev->next = ipc->next;
2774	else
2775		ipc_head = ipc->next;
2776	if(ipc->next)
2777		ipc->next->prev = ipc->prev;
2778	ipc->prev = ipc->next = NULL;
2779	return 0;
2780}
2781
2782static int isdn_ppp_set_compressor(struct ippp_struct *is, struct isdn_ppp_comp_data *data)
2783{
2784	struct isdn_ppp_compressor *ipc = ipc_head;
2785	int ret;
2786	void *stat;
2787	int num = data->num;
2788
2789	if(is->debug & 0x10)
2790		printk(KERN_DEBUG "[%d] Set %s type %d\n",is->unit,
2791			(data->flags&IPPP_COMP_FLAG_XMIT)?"compressor":"decompressor",num);
2792
2793	/* If is has no valid reset state vector, we cannot allocate a
2794	   decompressor. The decompressor would cause reset transactions
2795	   sooner or later, and they need that vector. */
2796
2797	if(!(data->flags & IPPP_COMP_FLAG_XMIT) && !is->reset) {
2798		printk(KERN_ERR "ippp_ccp: no reset data structure - can't"
2799		       " allow decompression.\n");
2800		return -ENOMEM;
2801	}
2802
2803	while(ipc) {
2804		if(ipc->num == num) {
2805			stat = ipc->alloc(data);
2806			if(stat) {
2807				ret = ipc->init(stat,data,is->unit,0);
2808				if(!ret) {
2809					printk(KERN_ERR "Can't init (de)compression!\n");
2810					ipc->free(stat);
2811					stat = NULL;
2812					break;
2813				}
2814			}
2815			else {
2816				printk(KERN_ERR "Can't alloc (de)compression!\n");
2817				break;
2818			}
2819
2820                        if(data->flags & IPPP_COMP_FLAG_XMIT) {
2821				if(data->flags & IPPP_COMP_FLAG_LINK) {
2822					if(is->link_comp_stat)
2823						is->link_compressor->free(is->link_comp_stat);
2824					is->link_comp_stat = stat;
2825                                	is->link_compressor = ipc;
2826				}
2827				else {
2828					if(is->comp_stat)
2829						is->compressor->free(is->comp_stat);
2830					is->comp_stat = stat;
2831                                	is->compressor = ipc;
2832				}
2833			}
2834                        else {
2835				if(data->flags & IPPP_COMP_FLAG_LINK) {
2836					if(is->link_decomp_stat)
2837						is->link_decompressor->free(is->link_decomp_stat);
2838					is->link_decomp_stat = stat;
2839        	                        is->link_decompressor = ipc;
2840				}
2841				else {
2842					if(is->decomp_stat)
2843						is->decompressor->free(is->decomp_stat);
2844					is->decomp_stat = stat;
2845        	                        is->decompressor = ipc;
2846				}
2847			}
2848			return 0;
2849		}
2850		ipc = ipc->next;
2851	}
2852	return -EINVAL;
2853}
2854