Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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