patch-2.4.20 linux-2.4.20/drivers/isdn/isdn_ppp.c
Next file: linux-2.4.20/drivers/isdn/pcbit/drv.c
Previous file: linux-2.4.20/drivers/isdn/isdn_net.h
Back to the patch index
Back to the overall index
- Lines: 383
- Date:
Thu Nov 28 15:53:13 2002
- Orig file:
linux-2.4.19/drivers/isdn/isdn_ppp.c
- Orig date:
Fri Aug 2 17:39:44 2002
diff -urN linux-2.4.19/drivers/isdn/isdn_ppp.c linux-2.4.20/drivers/isdn/isdn_ppp.c
@@ -107,8 +107,11 @@
unsigned long flags;
struct ippp_struct *is;
- if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS)
+ if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
+ printk(KERN_ERR __FUNCTION__": ppp_slot(%d) out of range\n",
+ lp->ppp_slot);
return 0;
+ }
save_flags(flags);
cli();
@@ -124,7 +127,12 @@
lp->netdev->pb->ref_ct--;
spin_unlock(&lp->netdev->pb->lock);
#endif /* CONFIG_ISDN_MPP */
-
+ if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
+ printk(KERN_ERR __FUNCTION__": ppp_slot(%d) now invalid\n",
+ lp->ppp_slot);
+ restore_flags(flags);
+ return 0;
+ }
is = ippp_table[lp->ppp_slot];
if ((is->state & IPPP_CONNECT))
isdn_ppp_closewait(lp->ppp_slot); /* force wakeup on ippp device */
@@ -220,12 +228,13 @@
void
isdn_ppp_wakeup_daemon(isdn_net_local * lp)
{
- if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS)
+ if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
+ printk(KERN_ERR __FUNCTION__": ppp_slot(%d) out of range\n",
+ lp->ppp_slot);
return;
-
+ }
ippp_table[lp->ppp_slot]->state = IPPP_OPEN | IPPP_CONNECT | IPPP_NOBLOCK;
-
- wake_up_interruptible(&ippp_table[lp->ppp_slot]->wq);
+ wake_up_interruptible(&ippp_table[lp->ppp_slot]->wq);
}
/*
@@ -238,13 +247,14 @@
{
struct ippp_struct *is;
- if (slot < 0 || slot >= ISDN_MAX_CHANNELS)
+ if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
+ printk(KERN_ERR __FUNCTION__": slot(%d) out of range\n",
+ slot);
return 0;
+ }
is = ippp_table[slot];
-
if (is->state)
wake_up_interruptible(&is->wq);
-
is->state = IPPP_CLOSEWAIT;
return 1;
}
@@ -282,8 +292,9 @@
return -EBUSY;
}
is = file->private_data = ippp_table[slot];
-
- printk(KERN_DEBUG "ippp, open, slot: %d, minor: %d, state: %04x\n", slot, min, is->state);
+
+ printk(KERN_DEBUG "ippp, open, slot: %d, minor: %d, state: %04x\n",
+ slot, min, is->state);
/* compression stuff */
is->link_compressor = is->compressor = NULL;
@@ -332,12 +343,20 @@
return;
is = file->private_data;
+ if (!is) {
+ printk(KERN_ERR __FUNCTION__": no file->private_data\n");
+ return;
+ }
if (is->debug & 0x1)
printk(KERN_DEBUG "ippp: release, minor: %d %lx\n", min, (long) is->lp);
if (is->lp) { /* a lp address says: this link is still up */
isdn_net_dev *p = is->lp->netdev;
+ if (!p) {
+ printk(KERN_ERR __FUNCTION__": no lp->netdev\n");
+ return;
+ }
is->state &= ~IPPP_CONNECT; /* -> effect: no call of wakeup */
/*
* isdn_net_hangup() calls isdn_ppp_free()
@@ -474,7 +493,9 @@
if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) {
if (lp) {
/* OK .. we are ready to send buffers */
+ is->pppcfg = val; /* isdn_ppp_xmit test for SC_ENABLE_IP !!! */
netif_wake_queue(&lp->netdev->dev);
+ break;
}
}
is->pppcfg = val;
@@ -629,7 +650,7 @@
struct ippp_struct *is;
if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
- printk(KERN_WARNING "ippp: illegal slot.\n");
+ printk(KERN_WARNING "ippp: illegal slot(%d).\n", slot);
return 0;
}
is = ippp_table[slot];
@@ -906,7 +927,8 @@
slot = lp->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
- printk(KERN_ERR "isdn_ppp_receive: lp->ppp_slot %d\n", lp->ppp_slot);
+ printk(KERN_ERR "isdn_ppp_receive: lp->ppp_slot(%d)\n",
+ lp->ppp_slot);
kfree_skb(skb);
return;
}
@@ -959,7 +981,8 @@
slot = lp->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
- printk(KERN_ERR "isdn_ppp_push_higher: lp->ppp_slot %d\n", lp->ppp_slot);
+ printk(KERN_ERR "isdn_ppp_push_higher: lp->ppp_slot(%d)\n",
+ lp->ppp_slot);
goto drop_packet;
}
is = ippp_table[slot];
@@ -967,7 +990,8 @@
if (lp->master) { // FIXME?
slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
- printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot %d\n", lp->ppp_slot);
+ printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot(%d)\n",
+ lp->ppp_slot);
goto drop_packet;
}
}
@@ -1001,6 +1025,11 @@
case PPP_VJC_UNCOMP:
if (is->debug & 0x20)
printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n");
+ if (net_dev->local->ppp_slot < 0) {
+ printk(KERN_ERR __FUNCTION__": net_dev->local->ppp_slot(%d) out of range\n",
+ net_dev->local->ppp_slot);
+ goto drop_packet;
+ }
if (slhc_remember(ippp_table[net_dev->local->ppp_slot]->slcomp, skb->data, skb->len) <= 0) {
printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n");
goto drop_packet;
@@ -1022,6 +1051,11 @@
}
skb_put(skb, skb_old->len + 128);
memcpy(skb->data, skb_old->data, skb_old->len);
+ if (net_dev->local->ppp_slot < 0) {
+ printk(KERN_ERR __FUNCTION__": net_dev->local->ppp_slot(%d) out of range\n",
+ net_dev->local->ppp_slot);
+ goto drop_packet;
+ }
pkt_len = slhc_uncompress(ippp_table[net_dev->local->ppp_slot]->slcomp,
skb->data, skb_old->len);
kfree_skb(skb_old);
@@ -1103,23 +1137,25 @@
isdn_net_dev *nd;
unsigned int proto = PPP_IP; /* 0x21 */
struct ippp_struct *ipt,*ipts;
- int slot;
+ int slot, retval = 0;
mlp = (isdn_net_local *) (netdev->priv);
nd = mlp->netdev; /* get master lp */
slot = mlp->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
- printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot %d\n", mlp->ppp_slot);
+ printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
+ mlp->ppp_slot);
kfree_skb(skb);
- return 0;
+ goto out;
}
ipts = ippp_table[slot];
if (!(ipts->pppcfg & SC_ENABLE_IP)) { /* PPP connected ? */
if (ipts->debug & 0x1)
printk(KERN_INFO "%s: IP frame delayed.\n", netdev->name);
- return 1;
+ retval = 1;
+ goto out;
}
switch (ntohs(skb->protocol)) {
@@ -1133,21 +1169,23 @@
printk(KERN_ERR "isdn_ppp: skipped unsupported protocol: %#x.\n",
skb->protocol);
dev_kfree_skb(skb);
- return 0;
+ goto out;
}
lp = isdn_net_get_locked_lp(nd);
if (!lp) {
printk(KERN_WARNING "%s: all channels busy - requeuing!\n", netdev->name);
- return 1;
+ retval = 1;
+ goto unlock;
}
/* we have our lp locked from now on */
slot = lp->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
- printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot %d\n", lp->ppp_slot);
+ printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
+ lp->ppp_slot);
kfree_skb(skb);
- return 0;
+ goto unlock;
}
ipt = ippp_table[slot];
lp->huptimer = 0;
@@ -1298,7 +1336,8 @@
unlock:
spin_unlock_bh(&lp->xmit_lock);
- return 0;
+ out:
+ return retval;
}
#ifdef CONFIG_ISDN_MPP
@@ -1350,8 +1389,15 @@
static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
{
- struct ippp_struct * is = ippp_table[lp->ppp_slot];
-
+ struct ippp_struct * is;
+
+ if (lp->ppp_slot < 0) {
+ printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d) out of range\n",
+ lp->ppp_slot);
+ return(-EINVAL);
+ }
+
+ is = ippp_table[lp->ppp_slot];
if (add_to) {
if( lp->netdev->pb )
lp->netdev->pb->ref_ct--;
@@ -1397,7 +1443,8 @@
stats = &mp->stats;
slot = lp->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
- printk(KERN_ERR "isdn_ppp_mp_receive: lp->ppp_slot %d\n", lp->ppp_slot);
+ printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d)\n",
+ lp->ppp_slot);
stats->frame_drops++;
dev_kfree_skb(skb);
spin_unlock_irqrestore(&mp->lock, flags);
@@ -1433,7 +1480,8 @@
for (lpq = net_dev->queue;;) {
slot = lpq->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
- printk(KERN_ERR "isdn_ppp_mp_receive: lpq->ppp_slot %d\n", lpq->ppp_slot);
+ printk(KERN_ERR __FUNCTION__": lpq->ppp_slot(%d)\n",
+ lpq->ppp_slot);
} else {
u32 lls = ippp_table[slot]->last_link_seqno;
if (MP_LT(lls, minseq))
@@ -1665,9 +1713,14 @@
struct sk_buff * skb;
unsigned int tot_len;
+ if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
+ printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d) out of range\n",
+ lp->ppp_slot);
+ return;
+ }
if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) {
if( ippp_table[lp->ppp_slot]->debug & 0x40 )
- printk(KERN_DEBUG"isdn_mppp: reassembly: frame %d, "
+ printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, "
"len %d\n", MP_SEQ(from), from->len );
skb = from;
skb_pull(skb, MP_HEADER_LEN);
@@ -2230,7 +2283,7 @@
return;
}
rs->state = CCPResetSentReq;
- /* We always expect an Ack if the decompressor doesnt
+ /* We always expect an Ack if the decompressor doesn't
know better */
rs->expra = 1;
rs->dlen = 0;
@@ -2429,18 +2482,31 @@
static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
struct sk_buff *skb,int proto)
{
- struct ippp_struct *is = ippp_table[lp->ppp_slot];
+ struct ippp_struct *is;
struct ippp_struct *mis;
int len;
struct isdn_ppp_resetparams rsparm;
unsigned char rsdata[IPPP_RESET_MAXDATABYTES];
- printk(KERN_DEBUG "Received CCP frame from peer\n");
+ printk(KERN_DEBUG "Received CCP frame from peer slot(%d)\n",
+ lp->ppp_slot);
+ if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
+ printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d) out of range\n",
+ lp->ppp_slot);
+ return;
+ }
+ is = ippp_table[lp->ppp_slot];
isdn_ppp_frame_log("ccp-rcv", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
- if(lp->master)
- mis = ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot];
- else
+ if(lp->master) {
+ int slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot;
+ if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
+ printk(KERN_ERR __FUNCTION__": slot(%d) out of range\n",
+ slot);
+ return;
+ }
+ mis = ippp_table[slot];
+ } else
mis = is;
switch(skb->data[0]) {
@@ -2592,13 +2658,18 @@
static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *skb)
{
- struct ippp_struct *mis,*is = ippp_table[lp->ppp_slot];
- int proto;
+ struct ippp_struct *mis,*is;
+ int proto, slot = lp->ppp_slot;
unsigned char *data;
if(!skb || skb->len < 3)
return;
-
+ if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
+ printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d) out of range\n",
+ slot);
+ return;
+ }
+ is = ippp_table[slot];
/* Daemon may send with or without address and control field comp */
data = skb->data;
if(!(is->pppcfg & SC_COMP_AC) && data[0] == 0xff && data[1] == 0x03) {
@@ -2614,12 +2685,17 @@
printk(KERN_DEBUG "Received CCP frame from daemon:\n");
isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
- if(lp->master)
- mis = ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot];
- else
- mis = is;
-
- if(mis != is)
+ if (lp->master) {
+ slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot;
+ if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
+ printk(KERN_ERR __FUNCTION__": slot(%d) out of range\n",
+ slot);
+ return;
+ }
+ mis = ippp_table[slot];
+ } else
+ mis = is;
+ if (mis != is)
printk(KERN_DEBUG "isdn_ppp: Ouch! Master CCP sends on slave slot!\n");
switch(data[2]) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)