summaryrefslogtreecommitdiffstats
path: root/drivers/isdn/isdn_ppp.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-06-03 09:23:20 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-06-03 09:23:20 +0000
commitac5ff8f4a72f7b4e66f73c3c6cb9fe7758cf6f12 (patch)
tree9fc7f8ce32e0d9a4aa055b2a58a05a5d727b333c /drivers/isdn/isdn_ppp.c
parent52662ff3e66770fd7e4fc508c91056d29c08bff0 (diff)
Sync with Linux 2.1.42.
Diffstat (limited to 'drivers/isdn/isdn_ppp.c')
-rw-r--r--drivers/isdn/isdn_ppp.c158
1 files changed, 112 insertions, 46 deletions
diff --git a/drivers/isdn/isdn_ppp.c b/drivers/isdn/isdn_ppp.c
index 5c2ad3e84..a909c298f 100644
--- a/drivers/isdn/isdn_ppp.c
+++ b/drivers/isdn/isdn_ppp.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_ppp.c,v 1.25 1997/02/12 20:37:35 hipp Exp $
+/* $Id: isdn_ppp.c,v 1.27 1997/03/30 16:51:17 calle Exp $
*
* Linux ISDN subsystem, functions for synchronous PPP (linklevel).
*
@@ -19,6 +19,15 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: isdn_ppp.c,v $
+ * Revision 1.27 1997/03/30 16:51:17 calle
+ * changed calls to copy_from_user/copy_to_user and removed verify_area
+ * were possible.
+ *
+ * Revision 1.26 1997/02/23 16:53:44 hipp
+ * minor cleanup
+ * some initial changes for future PPP compresion
+ * added AC,PC compression for outgoing frames
+ *
* Revision 1.25 1997/02/12 20:37:35 hipp
* New ioctl() PPPIOCGCALLINFO, minor cleanup
*
@@ -138,6 +147,7 @@ static int isdn_ppp_closewait(int slot);
static void isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp,
struct sk_buff *skb, int proto);
static int isdn_ppp_if_get_unit(char *namebuf);
+static int isdn_ppp_set_compressor(struct ippp_struct *is,int num);
#ifdef CONFIG_ISDN_MPP
static int isdn_ppp_bundle(struct ippp_struct *, int unit);
@@ -150,9 +160,10 @@ static int isdn_ppp_fill_mpqueue(isdn_net_dev *, struct sk_buff **skb,
static void isdn_ppp_free_mpqueue(isdn_net_dev *);
#endif
-char *isdn_ppp_revision = "$Revision: 1.25 $";
+char *isdn_ppp_revision = "$Revision: 1.27 $";
static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
+static struct isdn_ppp_compressor *ipc_head = NULL;
extern int isdn_net_force_dial_lp(isdn_net_local *);
@@ -371,6 +382,7 @@ isdn_ppp_open(int min, struct file *file)
if (is->debug & 0x1)
printk(KERN_DEBUG "ippp, open, slot: %d, minor: %d, state: %04x\n", slot, min, is->state);
+ is->compressor = NULL;
is->lp = NULL;
is->mp_seqno = 0; /* MP sequence number */
is->pppcfg = 0; /* ppp configuration */
@@ -451,9 +463,8 @@ get_arg(void *b, void *val, int len)
int r;
if (len <= 0)
len = sizeof(unsigned long);
- if ((r = verify_area(VERIFY_READ, (void *) b, len)))
+ if ((r = copy_from_user((void *) val, b, len)))
return r;
- copy_from_user((void *) val, b, len);
return 0;
}
@@ -465,13 +476,11 @@ set_arg(void *b, unsigned long val, void *str)
{
int r;
if (!str) {
- if ((r = verify_area(VERIFY_WRITE, b, 4)))
+ if ((r = copy_to_user(b, (void *) &val, 4)))
return r;
- copy_to_user(b, (void *) &val, 4);
} else {
- if ((r = verify_area(VERIFY_WRITE, b, val)))
+ if ((r = copy_to_user(b, str, val)))
return r;
- copy_to_user(b, str, val);
}
return 0;
}
@@ -483,7 +492,7 @@ int
isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
{
unsigned long val;
- int r;
+ int num,r;
struct ippp_struct *is;
isdn_net_local *lp;
@@ -592,16 +601,22 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
return r;
is->debug = val;
break;
- case PPPIOCSCOMPRESS:
-#if 0
+ case PPPIOCGCOMPRESSORS:
{
- struct ppp_option_data pod;
- r = get_arg((void *) arg, &pod, sizeof(struct ppp_option_data));
- if (r)
+ unsigned long protos = 0;
+ struct isdn_ppp_compressor *ipc = ipc_head;
+ while(ipc) {
+ protos |= (0x1<<ipc->num);
+ ipc = ipc->next;
+ }
+ if ((r = set_arg((void *) arg, protos, 0)))
return r;
- ippp_set_compression(is, &pod);
}
-#endif
+ break;
+ case PPPIOCSCOMPRESSOR:
+ if ((r = get_arg((void *) arg, &num, sizeof(int))))
+ return r;
+ return isdn_ppp_set_compressor(is, num);
break;
case PPPIOCGCALLINFO:
{
@@ -789,9 +804,6 @@ isdn_ppp_read(int min, struct file *file, char *buf, int count)
if (!(is->state & IPPP_OPEN))
return 0;
- if ((r = verify_area(VERIFY_WRITE, (void *) buf, count)))
- return r;
-
save_flags(flags);
cli();
@@ -802,7 +814,10 @@ isdn_ppp_read(int min, struct file *file, char *buf, int count)
}
if (b->len < count)
count = b->len;
- copy_to_user(buf, b->buf, count);
+ if ((r = copy_to_user(buf, b->buf, count))) {
+ restore_flags(flags);
+ return r;
+ }
kfree(b->buf);
b->buf = NULL;
is->first = b;
@@ -839,7 +854,8 @@ isdn_ppp_write(int min, struct file *file, const char *buf, int count)
* Don't reset huptimer for
* LCP packets. (Echo requests).
*/
- copy_from_user(protobuf, buf, 4);
+ if (copy_from_user(protobuf, buf, 4))
+ return -EFAULT;
proto = PPP_PROTOCOL(protobuf);
if (proto != PPP_LCP)
lp->huptimer = 0;
@@ -857,7 +873,8 @@ isdn_ppp_write(int min, struct file *file, const char *buf, int count)
return count;
}
SET_SKB_FREE(skb);
- copy_from_user(skb_put(skb, count), buf, count);
+ if (copy_from_user(skb_put(skb, count), buf, count))
+ return -EFAULT;
if (is->debug & 0x40) {
printk(KERN_DEBUG "ppp xmit: len %d\n", (int) skb->len);
isdn_ppp_frame_log("xmit", skb->data, skb->len, 32);
@@ -1209,7 +1226,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct device *dev)
isdn_net_local *lp,
*mlp;
isdn_net_dev *nd;
- int proto = PPP_IP; /* 0x21 */
+ unsigned int proto = PPP_IP; /* 0x21 */
struct ippp_struct *ipt,
*ipts;
@@ -1240,7 +1257,8 @@ isdn_ppp_xmit(struct sk_buff *skb, struct device *dev)
if (ipts->old_pa_addr != mdev->pa_addr) {
struct iphdr *ipfr;
ipfr = (struct iphdr *) skb->data;
- printk(KERN_DEBUG "IF-address changed from %lx to %lx\n", ipts->old_pa_addr, mdev->pa_addr);
+ if(ipts->debug & 0x4)
+ printk(KERN_DEBUG "IF-address changed from %lx to %lx\n", ipts->old_pa_addr, mdev->pa_addr);
if (ipfr->version == 4) {
if (ipfr->saddr == ipts->old_pa_addr) {
printk(KERN_DEBUG "readdressing %lx to %lx\n", ipfr->saddr, mdev->pa_addr);
@@ -1248,7 +1266,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct device *dev)
}
}
}
- /* dstaddr change not so improtant */
+ /* dstaddr change not so important */
#endif
break;
case ETH_P_IPX:
@@ -1331,27 +1349,36 @@ isdn_ppp_xmit(struct sk_buff *skb, struct device *dev)
ipts->mp_seqno++;
nd->queue = nd->queue->next;
if (ipt->mpppcfg & SC_OUT_SHORT_SEQ) {
- skb_push(skb, 3);
+ unsigned char *data = skb_push(skb, 3);
mp_seqno &= 0xfff;
- skb->data[0] = MP_BEGIN_FRAG | MP_END_FRAG | (mp_seqno >> 8); /* (B)egin & (E)ndbit .. */
- skb->data[1] = mp_seqno & 0xff;
- skb->data[2] = proto; /* PID compression */
+ data[0] = MP_BEGIN_FRAG | MP_END_FRAG | (mp_seqno >> 8); /* (B)egin & (E)ndbit .. */
+ data[1] = mp_seqno & 0xff;
+ data[2] = proto; /* PID compression */
} else {
- skb_push(skb, 5);
- skb->data[0] = MP_BEGIN_FRAG | MP_END_FRAG; /* (B)egin & (E)ndbit .. */
- skb->data[1] = (mp_seqno >> 16) & 0xff; /* sequence number: 24bit */
- skb->data[2] = (mp_seqno >> 8) & 0xff;
- skb->data[3] = (mp_seqno >> 0) & 0xff;
- skb->data[4] = proto; /* PID compression */
+ unsigned char *data = skb_push(skb, 5);
+ data[0] = MP_BEGIN_FRAG | MP_END_FRAG; /* (B)egin & (E)ndbit .. */
+ data[1] = (mp_seqno >> 16) & 0xff; /* sequence number: 24bit */
+ data[2] = (mp_seqno >> 8) & 0xff;
+ data[3] = (mp_seqno >> 0) & 0xff;
+ data[4] = proto; /* PID compression */
}
proto = PPP_MP; /* MP Protocol, 0x003d */
}
#endif
- skb_push(skb, 4);
- skb->data[0] = 0xff; /* All Stations */
- skb->data[1] = 0x03; /* Unnumbered information */
- skb->data[2] = proto >> 8;
- skb->data[3] = proto & 0xff;
+ if( (ipt->pppcfg & SC_COMP_PROT) && (proto <= 0xff) ) {
+ unsigned char *data = skb_push(skb,1);
+ data[0] = proto & 0xff;
+ }
+ else {
+ unsigned char *data = skb_push(skb,2);
+ data[0] = (proto >> 8) & 0xff;
+ data[1] = proto & 0xff;
+ }
+ if(!(ipt->pppcfg & SC_COMP_AC)) {
+ unsigned char *data = skb_push(skb,2);
+ data[0] = 0xff; /* All Stations */
+ data[1] = 0x03; /* Unnumbered information */
+ }
/* tx-stats are now updated via BSENT-callback */
@@ -1755,9 +1782,7 @@ isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct device *dev)
}
#endif
}
- copy_to_user(res, &t, sizeof(struct ppp_stats));
- return 0;
-
+ return copy_to_user(res, &t, sizeof(struct ppp_stats));
}
int
@@ -1779,9 +1804,7 @@ isdn_ppp_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
case SIOCGPPPVER:
r = (char *) ifr->ifr_ifru.ifru_data;
len = strlen(PPP_VERSION) + 1;
- error = verify_area(VERIFY_WRITE, r, len);
- if (!error)
- copy_to_user(r, PPP_VERSION, len);
+ error = copy_to_user(r, PPP_VERSION, len);
break;
case SIOCGPPPSTATS:
error = isdn_ppp_dev_ioctl_stats(lp->ppp_slot, ifr, dev);
@@ -1882,6 +1905,45 @@ isdn_ppp_hangup_slave(char *name)
#endif
}
+
+int isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc)
+{
+ ipc->next = ipc_head;
+ ipc->prev = NULL;
+ if(ipc_head) {
+ ipc_head->prev = ipc;
+ }
+ ipc_head = ipc;
+ return 0;
+}
+
+int isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *ipc)
+{
+ if(ipc->prev)
+ ipc->prev->next = ipc->next;
+ else
+ ipc_head = ipc->next;
+ if(ipc->next)
+ ipc->next->prev = ipc->prev;
+ ipc->prev = ipc->next = NULL;
+ return 0;
+}
+
+static int isdn_ppp_set_compressor(struct ippp_struct *is,int num)
+{
+ struct isdn_ppp_compressor *ipc = ipc_head;
+
+ while(ipc) {
+ if(ipc->num == num) {
+ return 0;
+ is->compressor = ipc;
+ }
+ ipc = ipc->next;
+ }
+ return -EINVAL;
+}
+
+
#if 0
static struct symbol_table isdn_ppp_syms =
{
@@ -1891,3 +1953,7 @@ static struct symbol_table isdn_ppp_syms =
#include <linux/symtab_end.h>
};
#endif
+
+
+
+