* Dynamic PPP devices by Jim Freeman <jfree@caldera.com>.
* ppp_tty_receive ``noisy-raise-bug'' fixed by Ove Ewerlid <ewerlid@syscon.uu.se>
*
- * ==FILEVERSION 960528==
+ * ==FILEVERSION 970227==
*
* NOTE TO MAINTAINERS:
* If you modify this file at all, please set the number above to the
#define PPP_MAX_DEV 256
#endif
-/* From: ppp.c,v 1.5 1995/06/12 11:36:53 paulus Exp
+/* $Id: ppp.c,v 1.10 1997/03/04 03:29:58 paulus Exp $
* Added dynamic allocation of channels to eliminate
* compiled-in limits on the number of channels.
*
* released under the GNU General Public License Version 2.
*/
+#include <linux/version.h>
#include <linux/module.h>
-#include <endian.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
+
+#undef VERSION
+/* a nice define to generate linux version numbers */
+#define VERSION(major,minor,patch) (((((major)<<8)+(minor))<<8)+(patch))
+
+#if LINUX_VERSION_CODE < VERSION(2,1,14)
#include <linux/ioport.h>
+#endif
+
#include <linux/in.h>
#include <linux/malloc.h>
#include <linux/tty.h>
#include <linux/signal.h> /* used in new tty drivers */
#include <asm/system.h>
#include <asm/bitops.h>
-#include <asm/segment.h>
-#include <linux/netdevice.h>
#include <linux/if.h>
#include <linux/if_ether.h>
+#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/inet.h>
#include <linux/ioctl.h>
#include <linux/socket.h>
#include <linux/if_ppp.h>
#include <linux/if_pppvar.h>
-
-#undef PACKETPTR
-#define PACKETPTR 1
#include <linux/ppp-comp.h>
-#undef PACKETPTR
-
-#define bsd_decompress (*ppp->sc_rcomp->decompress)
-#define bsd_compress (*ppp->sc_xcomp->compress)
#ifndef PPP_IPX
#define PPP_IPX 0x2b /* IPX protocol over PPP */
#define PPP_LQR 0xc025 /* Link Quality Reporting Protocol */
#endif
+#if LINUX_VERSION_CODE >= VERSION(2,1,4)
+#include <asm/segment.h>
+#define GET_USER(error,value,addr) error = get_user(value,addr)
+#define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0
+#define PUT_USER(error,value,addr) error = put_user(value,addr)
+#define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0
+
+#if LINUX_VERSION_CODE >= VERSION(2,1,5)
+#include <asm/uaccess.h>
+#endif
+
+#else /* 2.0.x and 2.1.x before 2.1.4 */
+
+#define GET_USER(error,value,addr) \
+do { \
+ error = verify_area (VERIFY_READ, (void *) addr, sizeof (value)); \
+ if (error == 0) \
+ value = get_user(addr); \
+} while (0)
+
+#define COPY_FROM_USER(error,dest,src,size) \
+do { \
+ error = verify_area (VERIFY_READ, (void *) src, size); \
+ if (error == 0) \
+ memcpy_fromfs (dest, src, size); \
+} while (0)
+
+#define PUT_USER(error,value,addr) \
+do { \
+ error = verify_area (VERIFY_WRITE, (void *) addr, sizeof (value)); \
+ if (error == 0) \
+ put_user (value, addr); \
+} while (0)
+
+#define COPY_TO_USER(error,dest,src,size) \
+do { \
+ error = verify_area (VERIFY_WRITE, (void *) src, size); \
+ if (error == 0) \
+ memcpy_tofs (dest, src, size); \
+} while (0)
+
+#endif
+
static int ppp_register_compressor (struct compressor *cp);
static void ppp_unregister_compressor (struct compressor *cp);
static void ppp_doframe_lower (struct ppp *, __u8 *, int);
static int ppp_doframe (struct ppp *);
-extern int ppp_bsd_compressor_init(void);
static void ppp_proto_ccp (struct ppp *ppp, __u8 *dp, int len, int rcvd);
static int rcv_proto_ccp (struct ppp *, __u16, __u8 *, int);
static int ppp_dev_close (struct device *);
static int ppp_dev_xmit (sk_buff *, struct device *);
static struct enet_statistics *ppp_dev_stats (struct device *);
+
+#if LINUX_VERSION_CODE < VERSION(2,1,15)
static int ppp_dev_header (sk_buff *, struct device *, __u16,
void *, void *, unsigned int);
static int ppp_dev_rebuild (void *eth, struct device *dev,
- unsigned long raddr, struct sk_buff *skb);
+ unsigned long raddr, struct sk_buff *skb);
+#endif
+
/*
* TTY callbacks
*/
static int ppp_tty_write (struct tty_struct *, struct file *, const __u8 *,
unsigned int);
static int ppp_tty_ioctl (struct tty_struct *, struct file *, unsigned int,
- unsigned long);
+ unsigned long);
static int ppp_tty_select (struct tty_struct *tty, struct inode *inode,
struct file *filp, int sel_type, select_table * wait);
static int ppp_tty_open (struct tty_struct *);
static char ppp_warning[] = KERN_WARNING "PPP: ALERT! not INUSE! %d\n";
static char szVersion[] = PPP_VERSION;
-
+
/*
* Information for the protocol decoder
*/
int status;
printk (KERN_INFO
- "PPP: version %s (dynamic channel allocation)"
+ "PPP: version %s (demand dialling)"
"\n", szVersion);
#ifndef MODULE /* slhc module logic has its own copyright announcement */
"TCP compression code copyright 1989 Regents of the "
"University of California\n");
#endif
-
+
printk (KERN_INFO
"PPP Dynamic channel allocation code copyright 1995 "
"Caldera, Inc.\n");
/*
* Register the tty discipline
- */
+ */
(void) memset (&ppp_ldisc, 0, sizeof (ppp_ldisc));
ppp_ldisc.magic = TTY_LDISC_MAGIC;
ppp_ldisc.open = ppp_tty_open;
ppp_ldisc.receive_room = ppp_tty_room;
ppp_ldisc.receive_buf = ppp_tty_receive;
ppp_ldisc.write_wakeup = ppp_tty_wakeup;
-
+
status = tty_register_ldisc (N_PPP, &ppp_ldisc);
if (status == 0)
printk (KERN_INFO "PPP line discipline registered.\n");
{
int indx;
+#if LINUX_VERSION_CODE < VERSION(2,1,15)
dev->hard_header = ppp_dev_header;
dev->rebuild_header = ppp_dev_rebuild;
+#endif
+
dev->hard_header_len = PPP_HARD_HDR_LEN;
/* device INFO */
ppp->last_xmit = jiffies - flag_time;
/* clear statistics */
- memset (&ppp->stats, '\0', sizeof (struct pppstat));
+ memset(&ppp->stats, 0, sizeof (struct pppstat));
+ memset(&ppp->estats, 0, sizeof(struct enet_statistics));
/* Reset the demand dial information */
ppp->ddinfo.xmit_idle= /* time since last NP packet sent */
ppp->sc_rc_state = NULL;
}
+#if LINUX_VERSION_CODE < VERSION(2,1,18)
static struct symbol_table ppp_syms = {
#include <linux/symtab_begin.h>
X(ppp_register_compressor),
X(ppp_crc16_table),
#include <linux/symtab_end.h>
};
+#else
+EXPORT_SYMBOL(ppp_register_compressor);
+EXPORT_SYMBOL(ppp_unregister_compressor);
+EXPORT_SYMBOL(ppp_crc16_table);
+#endif
/* called at boot/load time for each ppp device defined in the kernel */
if (first_time) {
first_time = 0;
answer = ppp_first_time();
+#if LINUX_VERSION_CODE < VERSION(2,1,18)
if (answer == 0)
(void) register_symtab (&ppp_syms);
+#endif
}
if (answer == 0)
answer = -ENODEV;
lock_buffer (register struct ppp_buffer *buf)
{
register int state;
- int flags;
+ unsigned long flags;
/*
* Save the current state and if free then set it to the "busy" state
*/
mru = PPP_MRU;
mru += 10;
-
- if (ppp->flags & SC_DEBUG)
- printk (KERN_INFO "ppp: channel %s mtu = %d, mru = %d\n",
- dev->name, new_mtu, new_mru);
new_wbuf = ppp_alloc_buf (mtu+PPP_HARD_HDR_LEN, BUFFER_TYPE_DEV_WR);
new_tbuf = ppp_alloc_buf ((PPP_MTU * 2) + 24, BUFFER_TYPE_TTY_WR);
ppp_ccp_closed (ppp);
- /* Ensure that the pppd process is not hanging on select() */
- wake_up_interruptible (&ppp->read_wait);
- wake_up_interruptible (&ppp->write_wait);
+ /* Ensure that the pppd process is not hanging on select() */
+ wake_up_interruptible (&ppp->read_wait);
+ wake_up_interruptible (&ppp->write_wait);
if (tty != NULL && tty->disc_data == ppp)
tty->disc_data = NULL; /* Break the tty->ppp link */
ppp->inuse = 0;
ppp->tty = NULL;
+ ppp->backup_tty = NULL;
}
/*
- * Device callback.
+ * TTY callback.
*
- * Called when the PPP device goes down in response to an ifconfig request.
+ * Called when the line discipline is changed to something
+ * else, the tty is closed, or the tty detects a hangup.
*/
static void
-ppp_tty_close_local (struct tty_struct *tty, int sc_xfer)
+ppp_tty_close (struct tty_struct *tty)
{
struct ppp *ppp = tty2ppp (tty);
if (ppp->flags & SC_DEBUG)
printk (KERN_WARNING
"ppp: trying to close unopened tty!\n");
+ return;
+ }
+ CHECK_PPP_VOID();
+ tty->disc_data = NULL;
+ if (tty == ppp->backup_tty)
+ ppp->backup_tty = 0;
+ if (tty != ppp->tty)
+ return;
+ if (ppp->backup_tty) {
+ ppp->tty = ppp->backup_tty;
} else {
- CHECK_PPP_VOID();
- ppp->sc_xfer = sc_xfer;
+ ppp->sc_xfer = 0;
if (ppp->flags & SC_DEBUG)
printk (KERN_INFO "ppp: channel %s closing.\n",
- ppp2dev(ppp) -> name);
+ ppp2dev(ppp)->name);
ppp_release (ppp);
MOD_DEC_USE_COUNT;
}
}
}
-static void
-ppp_tty_close (struct tty_struct *tty)
-{
- ppp_tty_close_local (tty, 0);
-}
-
/*
* TTY callback.
*
* Allocate the structure from the system
*/
ppp = ppp_find(current->pid);
- if (ppp == NULL) {
- ppp = ppp_find(0);
- if (ppp == NULL)
- ppp = ppp_alloc();
- }
+ if (ppp != NULL) {
+ /*
+ * If we are taking over a ppp unit which is currently
+ * connected to a loopback pty, there's not much to do.
+ */
+ ppp->tty = tty;
+ tty->disc_data = ppp;
- if (ppp == NULL) {
- if (ppp->flags & SC_DEBUG)
- printk (KERN_ERR
- "ppp_tty_open: couldn't allocate ppp channel\n");
- return -ENFILE;
- }
+ } else {
+ ppp = ppp_alloc();
+ if (ppp == NULL) {
+ if (ppp->flags & SC_DEBUG)
+ printk (KERN_ERR "ppp_alloc failed\n");
+ return -ENFILE;
+ }
/*
* Initialize the control block
*/
- ppp_init_ctrl_blk (ppp);
- ppp->tty = tty;
- tty->disc_data = ppp;
-/*
- * Flush any pending characters in the driver and discipline.
- */
- if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer (tty);
-
- if (tty->driver.flush_buffer)
- tty->driver.flush_buffer (tty);
+ ppp_init_ctrl_blk (ppp);
+ ppp->tty = tty;
+ tty->disc_data = ppp;
/*
* Allocate space for the default VJ header compression slots
*/
- ppp->slcomp = slhc_init (16, 16);
- if (ppp->slcomp == NULL) {
- if (ppp->flags & SC_DEBUG)
- printk (KERN_ERR
- "ppp_tty_open: no space for compression buffers!\n");
- ppp_release (ppp);
- return -ENOMEM;
- }
+ ppp->slcomp = slhc_init (16, 16);
+ if (ppp->slcomp == NULL) {
+ if (ppp->flags & SC_DEBUG)
+ printk (KERN_ERR "ppp_tty_open: "
+ "no space for compression buffers!\n");
+ ppp_release (ppp);
+ return -ENOMEM;
+ }
/*
* Allocate space for the MTU and MRU buffers
*/
- if (ppp_changedmtu (ppp, ppp2dev(ppp)->mtu, ppp->mru) == 0) {
- ppp_release (ppp);
- return -ENOMEM;
- }
+ if (ppp_changedmtu (ppp, ppp2dev(ppp)->mtu, ppp->mru) == 0) {
+ ppp_release (ppp);
+ return -ENOMEM;
+ }
/*
* Allocate space for a user level buffer
*/
- ppp->ubuf = ppp_alloc_buf (RBUFSIZE, BUFFER_TYPE_TTY_RD);
- if (ppp->ubuf == NULL) {
+ ppp->ubuf = ppp_alloc_buf (RBUFSIZE, BUFFER_TYPE_TTY_RD);
+ if (ppp->ubuf == NULL) {
+ if (ppp->flags & SC_DEBUG)
+ printk (KERN_ERR "ppp_tty_open: "
+ "no space for user receive buffer\n");
+ ppp_release (ppp);
+ return -ENOMEM;
+ }
+
if (ppp->flags & SC_DEBUG)
- printk (KERN_ERR
- "ppp_tty_open: no space for user receive buffer\n");
- ppp_release (ppp);
- return -ENOMEM;
- }
+ printk (KERN_INFO "ppp: channel %s open\n",
+ ppp2dev(ppp)->name);
- if (ppp->flags & SC_DEBUG)
- printk (KERN_INFO "ppp: channel %s open\n",
- ppp2dev(ppp)->name);
+ for (indx = 0; indx < NUM_NP; ++indx)
+ ppp->sc_npmode[indx] = NPMODE_PASS;
- for (indx = 0; indx < NUM_NP; ++indx)
- ppp->sc_npmode[indx] = NPMODE_PASS;
+ MOD_INC_USE_COUNT;
+ }
+/*
+ * Flush any pending characters in the driver and discipline.
+ */
+ if (tty->ldisc.flush_buffer)
+ tty->ldisc.flush_buffer (tty);
- MOD_INC_USE_COUNT;
+ if (tty->driver.flush_buffer)
+ tty->driver.flush_buffer (tty);
return (ppp->line);
}
if (ppp->magic != PPP_MAGIC)
return;
+
+ if (tty != ppp->tty) {
+ tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
+ return;
+ }
/*
* Ensure that there is a transmission pending. Clear the re-entry flag if
* there is no pending buffer. Otherwise, send the buffer.
static void
ppp_kick_tty (struct ppp *ppp, struct ppp_buffer *xbuf)
{
- register int flags;
+ unsigned long flags;
/*
* Hold interrupts.
*/
/*
* Callback function when data is available at the tty driver.
*/
-
static void
ppp_tty_receive (struct tty_struct *tty, const __u8 * data,
char *flags, int count)
register struct ppp *ppp = tty2ppp (tty);
register struct ppp_buffer *buf = NULL;
__u8 chr;
+
+ /*
+ * This can happen if stuff comes in on the backup tty.
+ */
+ if (tty != ppp->tty)
+ return;
/*
* Fetch the pointer to the buffer. Be careful about race conditions.
*/
ppp->bytes_rcvd++;
chr = *data++;
if (flags) {
- if (*flags && ppp->toss == 0)
+ if (*flags && ppp->toss == 0) {
ppp->toss = *flags;
+ switch (ppp->toss) {
+ case TTY_OVERRUN:
+ ++ppp->estats.rx_fifo_errors;
+ break;
+ case TTY_FRAME:
+ case TTY_BREAK:
+ ++ppp->estats.rx_frame_errors;
+ break;
+ }
+ }
++flags;
}
/*
- * Set the flags for 8 data bits and no parity.
- *
- * Actually, it sets the flags for d7 being 0/1 and parity being even/odd
- * so that the normal processing would have all flags set at the end of the
- * session. A missing flag bit would denote an error condition.
+ * Set the flags for d7 being 0/1 and parity being even/odd so that
+ * the normal processing would have all flags set at the end of the
+ * session. A missing flag bit indicates an error condition.
*/
#ifdef CHECK_CHARACTERS
ppp->flags |= SC_RCV_EVNP;
#endif
/*
- * Branch on the character. Process the escape character. The sequence ESC ESC
- * is defined to be ESC.
+ * Branch on the character.
*/
switch (chr) {
- case PPP_ESCAPE: /* PPP_ESCAPE: invert bit in next character */
- ppp->escape = PPP_TRANS;
- break;
/*
* FLAG. This is the end of the block. If the block terminated by ESC FLAG,
* then the block is to be ignored. In addition, characters before the very
* Process frames which are not to be ignored. If the processing failed,
* then clean up the VJ tables.
*/
- if ((ppp->toss & 0x80) != 0 ||
- ppp_doframe (ppp) == 0) {
+ if (ppp_doframe (ppp) == 0) {
+ ++ppp->stats.ppp_ierrors;
slhc_toss (ppp->slcomp);
}
/*
* receive mask then ignore the character.
*/
default:
+ /* If we're tossing, look no further. */
+ if (ppp->toss != 0)
+ break;
+
+ /* If this is a control char to be ignored, do so */
if (in_rmap (ppp, chr))
break;
-/*
- * Adjust the character and if the frame is to be discarded then simply
- * ignore the character until the ending FLAG is received.
- */
- chr ^= ppp->escape;
- ppp->escape = 0;
- if (ppp->toss != 0)
+ /*
+ * Modify the next character if preceded by escape.
+ * The escape character (0x7d) could be an escaped
+ * 0x5d, if it follows an escape :-)
+ */
+ if (ppp->escape) {
+ chr ^= ppp->escape;
+ ppp->escape = 0;
+ } else if (chr == PPP_ESCAPE) {
+ ppp->escape = PPP_TRANS;
break;
+ }
+
/*
* If the count sent is within reason then store the character, bump the
* count, and update the FCS for the character.
* The peer sent too much data. Set the flags to discard the current frame
* and wait for the re-synchronization FLAG to be sent.
*/
- ppp->stats.ppp_ierrors++;
+ ++ppp->estats.rx_length_errors;
ppp->toss |= 0xC0;
break;
}
/*
* Tag the frame and kick it to the proper receive routine
*/
+#if LINUX_VERSION_CODE < VERSION(2,1,15)
skb->free = 1;
+#endif
+
ppp->ddinfo.recv_idle = jiffies;
netif_rx (skb);
return 1;
if (ppp->tty->fasync != NULL)
kill_fasync (ppp->tty->fasync, SIGIO);
- if (ppp->flags & SC_DEBUG)
- printk (KERN_INFO
- "ppp: successfully queued %d bytes, flags = %x\n",
- len + 2, ppp->flags);
-
return 1;
/*
* The buffer is full. Unlock the header
failure:
clear_bit (0, &ppp->ubuf->locked);
if (ppp->flags & SC_DEBUG)
- printk (KERN_INFO
+ printk (KERN_DEBUG
"ppp_us_queue: ran out of buffer space.\n");
}
/*
* Discard the frame. There are no takers for this protocol.
*/
if (ppp->flags & SC_DEBUG)
- printk (KERN_WARNING
+ printk (KERN_DEBUG
"ppp: dropping packet on the floor.\n");
slhc_toss (ppp->slcomp);
return 0;
opt_len,
ppp2dev (ppp)->base_addr,
0,
- ppp->flags))
+ ppp->flags & SC_DEBUG))
ppp->flags |= SC_COMP_RUN;
break;
}
ppp2dev (ppp)->base_addr,
0,
ppp->mru,
- ppp->flags)) {
+ ppp->flags & SC_DEBUG)) {
ppp->flags |= SC_DECOMP_RUN;
ppp->flags &= ~(SC_DC_ERROR | SC_DC_FERROR);
}
return rcv_proto_unknown (ppp, proto, data, len);
}
-/* on entry, a received frame is in ppp->rbuf.bufr
- check it and dispose as appropriate */
-
static void ppp_doframe_lower (struct ppp *ppp, __u8 *data, int count)
{
__u16 proto = PPP_PROTOCOL (data);
/*
* Ignore empty frames
*/
- if (count <= 4)
+ if (count <= PPP_HDRLEN)
return;
/*
* Count the frame and print it
* the damaged frame.
*/
if (ppp->toss) {
- if (ppp->flags & SC_DEBUG)
- printk (KERN_WARNING
- "ppp_toss: tossing frame, reason = %d\n",
+ if ((ppp->flags & SC_DEBUG) && count > 0)
+ printk (KERN_DEBUG
+ "ppp_toss: tossing frame, reason = %x\n",
ppp->toss);
- ppp->stats.ppp_ierrors++;
return 0;
}
/*
*/
if (count < PPP_HARD_HDR_LEN) {
if (ppp->flags & SC_DEBUG)
- printk (KERN_WARNING
+ printk (KERN_DEBUG
"ppp: got runt ppp frame, %d chars\n", count);
- slhc_toss (ppp->slcomp);
- ppp->stats.ppp_ierrors++;
- return 1;
+ ++ppp->estats.rx_length_errors;
+ return 0;
}
/*
* Verify the CRC of the frame and discard the CRC characters from the
* end of the buffer.
*/
if (ppp->rbuf->fcs != PPP_GOODFCS) {
- if (ppp->flags & SC_DEBUG)
- printk (KERN_WARNING
- "ppp: frame with bad fcs, excess = %x\n",
- ppp->rbuf->fcs ^ PPP_GOODFCS);
- ppp->stats.ppp_ierrors++;
+ if (ppp->flags & SC_DEBUG) {
+ printk (KERN_DEBUG
+ "ppp: frame with bad fcs, length = %d\n",
+ count);
+ ppp_print_buffer("bad frame", data, count);
+ }
+ ++ppp->estats.rx_crc_errors;
return 0;
}
count -= 2; /* ignore the fcs characters */
/*
* If the frame is compressed then decompress it.
*/
- new_data = kmalloc (ppp->mru + 4, GFP_ATOMIC);
+ new_data = kmalloc (ppp->mru + PPP_HDRLEN, GFP_ATOMIC);
if (new_data == NULL) {
if (ppp->flags & SC_DEBUG)
printk (KERN_ERR
"ppp_doframe: no memory\n");
- slhc_toss (ppp->slcomp);
- (*ppp->sc_rcomp->incomp) (ppp->sc_rc_state,
- data,
- count);
- return 1;
+ new_count = DECOMP_ERROR;
+ } else {
+ new_count = (*ppp->sc_rcomp->decompress)
+ (ppp->sc_rc_state, data, count,
+ new_data, ppp->mru + PPP_HDRLEN);
}
-/*
- * Decompress the frame
- */
- new_count = bsd_decompress (ppp->sc_rc_state,
- data,
- count,
- new_data,
- ppp->mru + 4);
switch (new_count) {
default:
ppp_doframe_lower (ppp, new_data, new_count);
kfree (new_data);
return 1;
- case DECOMP_OK:
- break;
-
case DECOMP_ERROR:
ppp->flags |= SC_DC_ERROR;
break;
case DECOMP_FATALERROR:
ppp->flags |= SC_DC_FERROR;
+ if (ppp->flags & SC_DEBUG)
+ printk(KERN_ERR "ppp: fatal decomp error\n");
break;
}
/*
* Log the error condition and discard the frame.
*/
- if (ppp->flags & SC_DEBUG)
- printk (KERN_ERR
- "ppp_proto_comp: "
- "decompress err %d\n", new_count);
- kfree (new_data);
+ if (new_data != 0)
+ kfree (new_data);
slhc_toss (ppp->slcomp);
- return 1;
- }
+ ++ppp->stats.ppp_ierrors;
+ } else {
/*
* The frame is not special. Pass it through the compressor without
* actually compressing the data
*/
- (*ppp->sc_rcomp->incomp) (ppp->sc_rc_state,
- data,
- count);
+ (*ppp->sc_rcomp->incomp) (ppp->sc_rc_state,
+ data, count);
+ }
}
/*
* Process the uncompressed frame.
struct ppp *ppp = tty2ppp (tty);
__u8 c;
int len, indx;
+ int error;
#define GETC(c) \
{ \
return -EIO;
CHECK_PPP (-ENXIO);
-
- if (ppp->flags & SC_DEBUG)
- printk (KERN_DEBUG
- "ppp_tty_read: called buf=%p nr=%u\n",
- buf, nr);
/*
* Acquire the read lock.
*/
for (;;) {
ppp = tty2ppp (tty);
- if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse)
+ if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse
+ || tty != ppp->tty)
return 0;
if (set_bit (0, &ppp->ubuf->locked) != 0) {
if (len == 0) {
/* no data */
clear_bit (0, &ppp->ubuf->locked);
- if (file->f_flags & O_NONBLOCK) {
- if (ppp->flags & SC_DEBUG)
- printk (KERN_DEBUG
- "ppp_tty_read: no data "
- "(EAGAIN)\n");
+ if (file->f_flags & O_NONBLOCK)
return -EAGAIN;
- }
current->timeout = 0;
if (ppp->flags & SC_DEBUG)
return -EINTR;
continue;
}
-/*
- * Reset the time of the last read operation.
- */
- if (ppp->flags & SC_DEBUG)
- printk (KERN_DEBUG "ppp_tty_read: len = %d\n", len);
/*
* Ensure that the frame will fit within the caller's buffer. If not, then
* discard the frame from the input buffer.
* Fake the insertion of the ADDRESS and CONTROL information because these
* were not saved in the buffer.
*/
- put_user (PPP_ALLSTATIONS, buf++);
- put_user (PPP_UI, buf++);
+ PUT_USER (error, (u_char) PPP_ALLSTATIONS, buf);
+ ++buf;
+ PUT_USER (error, (u_char) PPP_UI, buf);
+ ++buf;
indx = len;
/*
*/
while (indx-- > 0) {
GETC (c);
- put_user (c, buf);
+ PUT_USER (error, c, buf);
++buf;
}
*/
if (ppp->flags & SC_DEBUG) {
if ((buf->count < 0) || (buf->count > 3000))
- printk (KERN_DEBUG "ppp_stuff_char: %x %d\n",
+ printk (KERN_DEBUG "ppp_stuff_char: %d %x\n",
(unsigned int) buf->count,
(unsigned int) chr);
}
ppp_dev_xmit_lower (struct ppp *ppp, struct ppp_buffer *buf,
__u8 *data, int count, int non_ip)
{
- __u16 write_fcs;
+ __u16 write_fcs;
int address, control;
int proto;
+
+ ++ppp->stats.ppp_opackets;
+ ppp->stats.ppp_ooctects += count;
+
/*
* Insert the leading FLAG character
*/
write_fcs = buf->fcs ^ 0xFFFF;
ppp_stuff_char (ppp, buf, write_fcs);
ppp_stuff_char (ppp, buf, write_fcs >> 8);
-
- if (ppp->flags & SC_DEBUG)
- printk (KERN_DEBUG "ppp_dev_xmit_lower: fcs is %hx\n",
- write_fcs);
/*
* Add the trailing flag character
*/
if (ppp->flags & SC_LOG_FLUSH)
ppp_print_buffer ("ppp flush", buf_base (buf),
buf->count);
- else {
- if (ppp->flags & SC_DEBUG)
- printk (KERN_DEBUG
- "ppp_dev_xmit: writing %d chars\n",
- buf->count);
- }
/*
* Send the block to the tty driver.
*/
return 1;
}
- new_count = bsd_compress (ppp->sc_xc_state,
- data,
- new_data,
- count,
- count);
-
- if (new_count > 0) {
- ++ppp->stats.ppp_opackets;
- ppp->stats.ppp_ooctects += new_count;
+ new_count = (*ppp->sc_xcomp->compress)
+ (ppp->sc_xc_state, data, new_data, count, count);
- ppp_dev_xmit_lower (ppp, buf, new_data,
- new_count, 0);
+ if (new_count > 0 && (ppp->flags & SC_CCP_UP)) {
+ ppp_dev_xmit_lower (ppp, buf, new_data, new_count, 0);
kfree (new_data);
return 0;
}
/*
- * The frame could not be compressed.
+ * The frame could not be compressed, or it could not be sent in
+ * compressed form because CCP is not yet up.
*/
kfree (new_data);
}
-/*
- * The frame may not be compressed. Update the statistics before the
- * count field is destroyed. The frame will be transmitted.
- */
- ++ppp->stats.ppp_opackets;
- ppp->stats.ppp_ooctects += count;
/*
* Go to the escape encoding
*/
/*
* Ensure that the caller does not wish to send too much.
*/
- if (count > PPP_MTU) {
+ if (count > PPP_MTU + PPP_HDRLEN) {
if (ppp->flags & SC_DEBUG)
printk (KERN_WARNING
"ppp_tty_write: truncating user packet "
- "from %u to mtu %d\n", count, PPP_MTU);
- count = PPP_MTU;
+ "from %u to mtu %d\n", count,
+ PPP_MTU + PPP_HDRLEN);
+ count = PPP_MTU + PPP_HDRLEN;
}
/*
* Allocate a buffer for the data and fetch it from the user space.
interruptible_sleep_on (&ppp->write_wait);
ppp = tty2ppp (tty);
- if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse) {
+ if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse
+ || tty != ppp->tty) {
kfree (new_data);
return 0;
}
}
}
/*
- * Ensure that the caller's buffer is valid.
+ * Retrieve the user's buffer
*/
- status = verify_area (VERIFY_READ, data, count);
+ COPY_FROM_USER (status,
+ new_data,
+ data,
+ count);
+
if (status != 0) {
kfree (new_data);
ppp->tbuf->locked = 0;
return status;
}
-
- memcpy_fromfs (new_data, data, count);
/*
* Change the LQR frame
*/
/*
* Fetch the compression parameters
*/
- error = verify_area (VERIFY_READ, odp, sizeof (data));
- if (error == 0) {
- memcpy_fromfs (&data, odp, sizeof (data));
- nb = data.length;
- ptr = data.ptr;
- if ((__u32) nb >= (__u32)CCP_MAX_OPTION_LENGTH)
- nb = CCP_MAX_OPTION_LENGTH;
-
- error = verify_area (VERIFY_READ, ptr, nb);
- }
+ COPY_FROM_USER (error,
+ &data,
+ odp,
+ sizeof (data));
if (error != 0)
return error;
- memcpy_fromfs (ccp_option, ptr, nb);
+ nb = data.length;
+ ptr = data.ptr;
+ if ((__u32) nb >= (__u32)CCP_MAX_OPTION_LENGTH)
+ nb = CCP_MAX_OPTION_LENGTH;
+
+ COPY_FROM_USER (error,
+ ccp_option,
+ ptr,
+ nb);
+
+ if (error != 0)
+ return error;
if (ccp_option[1] < 2) /* preliminary check on the length byte */
return (-EINVAL);
static int
ppp_tty_ioctl (struct tty_struct *tty, struct file * file,
- unsigned int param2, unsigned long param3)
+ unsigned int param2, unsigned long param3)
{
struct ppp *ppp = tty2ppp (tty);
register int temp_i = 0;
*/
switch (param2) {
case PPPIOCSMRU:
- error = verify_area (VERIFY_READ, (void *) param3,
- sizeof (temp_i));
+ GET_USER (error, temp_i, (int *) param3);
if (error == 0) {
- temp_i = get_user ((int *) param3);
if (ppp->flags & SC_DEBUG)
printk (KERN_INFO
"ppp_tty_ioctl: set mru to %x\n", temp_i);
* Fetch the flags
*/
case PPPIOCGFLAGS:
- error = verify_area (VERIFY_WRITE, (void *) param3,
- sizeof (temp_i));
- if (error == 0) {
- temp_i = (ppp->flags & SC_MASK);
+ temp_i = (ppp->flags & SC_MASK);
#ifndef CHECK_CHARACTERS /* Don't generate errors if we don't check chars. */
- temp_i |= SC_RCV_B7_1 | SC_RCV_B7_0 |
- SC_RCV_ODDP | SC_RCV_EVNP;
+ temp_i |= SC_RCV_B7_1 | SC_RCV_B7_0 |
+ SC_RCV_ODDP | SC_RCV_EVNP;
#endif
- put_user (temp_i, (int *) param3);
- if (ppp->flags & SC_DEBUG)
- printk (KERN_DEBUG
- "ppp_tty_ioctl: get flags: addr %lx flags "
- "%x\n", param3, temp_i);
- }
+ PUT_USER (error, temp_i, (int *) param3);
break;
/*
* Set the flags for the various options
*/
case PPPIOCSFLAGS:
- error = verify_area (VERIFY_READ, (void *) param3,
- sizeof (temp_i));
+ GET_USER (error, temp_i, (int *) param3);
if (error == 0) {
- temp_i = get_user ((int *) param3) & SC_MASK;
+ temp_i &= SC_MASK;
temp_i |= (ppp->flags & ~SC_MASK);
if ((ppp->flags & SC_CCP_OPEN) &&
* Retrieve the transmit async map
*/
case PPPIOCGASYNCMAP:
- error = verify_area (VERIFY_WRITE, (void *) param3,
- sizeof (temp_i));
- if (error == 0) {
- put_user (ppp->xmit_async_map[0], (int *) param3);
- if (ppp->flags & SC_DEBUG)
- printk (KERN_INFO
- "ppp_tty_ioctl: get asyncmap: addr "
- "%lx asyncmap %x\n",
- param3,
- ppp->xmit_async_map[0]);
- }
+ PUT_USER (error, ppp->xmit_async_map[0], (int *) param3);
break;
/*
* Set the transmit async map
*/
case PPPIOCSASYNCMAP:
- error = verify_area (VERIFY_READ, (void *) param3,
- sizeof (temp_i));
+ GET_USER (error, temp_i, (int *) param3);
if (error == 0) {
- ppp->xmit_async_map[0] = get_user ((int *) param3);
+ ppp->xmit_async_map[0] = temp_i;
if (ppp->flags & SC_DEBUG)
printk (KERN_INFO
"ppp_tty_ioctl: set xmit asyncmap %x\n",
* Set the receive async map
*/
case PPPIOCSRASYNCMAP:
- error = verify_area (VERIFY_READ, (void *) param3,
- sizeof (temp_i));
+ GET_USER (error, temp_i, (int *) param3);
if (error == 0) {
- ppp->recv_async_map = get_user ((int *) param3);
+ ppp->recv_async_map = temp_i;
if (ppp->flags & SC_DEBUG)
printk (KERN_INFO
"ppp_tty_ioctl: set rcv asyncmap %x\n",
* Obtain the unit number for this device.
*/
case PPPIOCGUNIT:
- error = verify_area (VERIFY_WRITE, (void *) param3,
- sizeof (temp_i));
+ PUT_USER (error, ppp2dev (ppp)->base_addr, (int *) param3);
if (error == 0) {
- put_user (ppp2dev (ppp)->base_addr, (int *) param3);
if (ppp->flags & SC_DEBUG)
printk (KERN_INFO
- "ppp_tty_ioctl: get unit: %ld",
+ "ppp_tty_ioctl: get unit: %ld\n",
ppp2dev (ppp)->base_addr);
}
break;
* Set the debug level
*/
case PPPIOCSDEBUG:
- error = verify_area (VERIFY_READ, (void *) param3,
- sizeof (temp_i));
+ GET_USER (error, temp_i, (int *) param3);
if (error == 0) {
- temp_i = (get_user ((int *) param3) & 0x1F) << 16;
+ temp_i = (temp_i & 0x1F) << 16;
temp_i |= (ppp->flags & ~0x1F0000);
if ((ppp->flags | temp_i) & SC_DEBUG)
* Get the debug level
*/
case PPPIOCGDEBUG:
- error = verify_area (VERIFY_WRITE, (void *) param3,
- sizeof (temp_i));
- if (error == 0) {
- temp_i = (ppp->flags >> 16) & 0x1F;
- put_user (temp_i, (int *) param3);
-
- if (ppp->flags & SC_DEBUG)
- printk (KERN_INFO
- "ppp_tty_ioctl: get debug level %d\n",
- temp_i);
- }
+ temp_i = (ppp->flags >> 16) & 0x1F;
+ PUT_USER (error, temp_i, (int *) param3);
break;
/*
* Get the times since the last send/receive frame operation
*/
case PPPIOCGIDLE:
- error = verify_area (VERIFY_WRITE, (void *) param3,
- sizeof (struct ppp_idle));
- if (error == 0) {
+ {
struct ppp_idle cur_ddinfo;
__u32 cur_jiffies = jiffies;
/* change absolute times to relative times. */
cur_ddinfo.xmit_idle = (cur_jiffies - ppp->ddinfo.xmit_idle) / HZ;
cur_ddinfo.recv_idle = (cur_jiffies - ppp->ddinfo.recv_idle) / HZ;
- memcpy_tofs ((void *) param3, &cur_ddinfo,
- sizeof (cur_ddinfo));
- if (ppp->flags & SC_DEBUG)
- printk (KERN_INFO
- "ppp_tty_ioctl: read demand dial info\n");
+ COPY_TO_USER (error,
+ (void *) param3,
+ &cur_ddinfo,
+ sizeof (cur_ddinfo));
}
break;
/*
* Retrieve the extended async map
*/
case PPPIOCGXASYNCMAP:
- error = verify_area (VERIFY_WRITE,
- (void *) param3,
- sizeof (ppp->xmit_async_map));
- if (error == 0) {
- memcpy_tofs ((void *) param3,
- ppp->xmit_async_map,
- sizeof (ppp->xmit_async_map));
-
- if (ppp->flags & SC_DEBUG)
- printk (KERN_INFO
- "ppp_tty_ioctl: get xasyncmap: addr %lx\n",
- param3);
- }
+ COPY_TO_USER (error,
+ (void *) param3,
+ ppp->xmit_async_map,
+ sizeof (ppp->xmit_async_map));
break;
/*
* Set the async extended map
*/
case PPPIOCSXASYNCMAP:
- error = verify_area (VERIFY_READ, (void *) param3,
- sizeof (ppp->xmit_async_map));
- if (error == 0) {
+ {
__u32 temp_tbl[8];
- memcpy_fromfs (temp_tbl, (void *) param3,
- sizeof (ppp->xmit_async_map));
- temp_tbl[1] = 0x00000000;
- temp_tbl[2] &= ~0x40000000;
- temp_tbl[3] |= 0x60000000;
-
- if ((temp_tbl[2] & temp_tbl[3]) != 0 ||
- (temp_tbl[4] & temp_tbl[5]) != 0 ||
- (temp_tbl[6] & temp_tbl[7]) != 0)
- error = -EINVAL;
- else {
- memcpy (ppp->xmit_async_map, temp_tbl,
- sizeof (ppp->xmit_async_map));
-
- if (ppp->flags & SC_DEBUG)
- printk (KERN_INFO
- "ppp_tty_ioctl: set xasyncmap\n");
+ COPY_FROM_USER (error,
+ temp_tbl,
+ (void *) param3,
+ sizeof (temp_tbl));
+
+ if (error == 0) {
+ temp_tbl[1] = 0x00000000;
+ temp_tbl[2] &= ~0x40000000;
+ temp_tbl[3] |= 0x60000000;
+
+ if ((temp_tbl[2] & temp_tbl[3]) != 0 ||
+ (temp_tbl[4] & temp_tbl[5]) != 0 ||
+ (temp_tbl[6] & temp_tbl[7]) != 0)
+ error = -EINVAL;
+ else {
+ memcpy (ppp->xmit_async_map,
+ temp_tbl,
+ sizeof (ppp->xmit_async_map));
+
+ if (ppp->flags & SC_DEBUG)
+ printk (KERN_INFO
+ "ppp_tty_ioctl: set xasyncmap\n");
+ }
}
}
break;
* Set the maximum VJ header compression slot number.
*/
case PPPIOCSMAXCID:
- error = verify_area (VERIFY_READ, (void *) param3,
- sizeof (temp_i));
+ GET_USER (error, temp_i, (int *) param3);
if (error == 0) {
- temp_i = get_user ((int *) param3) + 1;
+ temp_i = (temp_i & 255) + 1;
if (ppp->flags & SC_DEBUG)
printk (KERN_INFO
"ppp_tty_ioctl: set maxcid to %d\n",
break;
case PPPIOCXFERUNIT:
- ppp_tty_close_local (tty, current->pid);
+ ppp->backup_tty = tty;
+ ppp->sc_xfer = current->pid;
break;
case PPPIOCGNPMODE:
case PPPIOCSNPMODE:
- error = verify_area (VERIFY_READ, (void *) param3,
- sizeof (struct npioctl));
- if (error == 0) {
+ {
struct npioctl npi;
- memcpy_fromfs (&npi,
- (void *) param3,
- sizeof (npi));
+ COPY_FROM_USER (error,
+ &npi,
+ (void *) param3,
+ sizeof (npi));
+
+ if (error != 0)
+ break;
switch (npi.protocol) {
case PPP_IP:
npi.protocol = NP_IP;
break;
default:
+ if (ppp->flags & SC_DEBUG)
+ printk(KERN_DEBUG "pppioc[gs]npmode: "
+ "invalid proto %d\n", npi.protocol);
error = -EINVAL;
}
if (param2 == PPPIOCGNPMODE) {
npi.mode = ppp->sc_npmode[npi.protocol];
- error = verify_area (VERIFY_WRITE,
- (void *) param3,
- sizeof (npi));
- if (error != 0)
- break;
- memcpy_tofs ((void *) param3,
- &npi,
- sizeof (npi));
+ COPY_TO_USER (error,
+ (void *) param3,
+ &npi,
+ sizeof (npi));
break;
}
break;
case FIONREAD:
- error = verify_area (VERIFY_WRITE,
- (void *) param3,
- sizeof (int));
- if (error == 0) {
+ {
int count = ppp->ubuf->tail - ppp->ubuf->head;
if (count < 0)
count += (ppp->ubuf->size + 1);
-
- put_user (count, (int *) param3);
+ PUT_USER (error, count, (int *) param3);
}
break;
/*
if (!ppp)
return -EBADF;
- if (ppp->magic != PPP_MAGIC)
+ if (ppp->magic != PPP_MAGIC || tty != ppp->tty)
return -EBADF;
CHECK_PPP (0);
struct ppp *ppp = dev2ppp (dev);
if (ppp2tty (ppp) == NULL) {
- if (ppp->flags & SC_DEBUG)
- printk (KERN_ERR
- "ppp: %s not connected to a TTY! can't go down!\n",
- dev->name);
return -ENXIO;
}
/*
ppp_dev_ioctl_version (struct ppp *ppp, struct ifreq *ifr)
{
int error;
- int len;
- char *result;
-/*
- * Must have write access to the buffer.
- */
- result = (char *) ifr->ifr_ifru.ifru_data;
- len = strlen (szVersion) + 1;
- error = verify_area (VERIFY_WRITE, result, len);
+ char *result = (char *) ifr->ifr_ifru.ifru_data;
+ int len = strlen (szVersion) + 1;
/*
* Move the version data
*/
- if (error == 0)
- memcpy_tofs (result, szVersion, len);
+ COPY_TO_USER (error,
+ result,
+ szVersion,
+ len);
return error;
}
{
struct ppp_stats *result, temp;
int error;
-/*
- * Must have write access to the buffer.
- */
- result = (struct ppp_stats *) ifr->ifr_ifru.ifru_data;
- error = verify_area (VERIFY_WRITE,
- result,
- sizeof (temp));
/*
* Supply the information for the caller. First move the version data
* then move the ppp stats; and finally the vj stats.
*/
memset (&temp, 0, sizeof(temp));
- if (error == 0 && dev->flags & IFF_UP) {
+ if (dev->flags & IFF_UP) {
memcpy (&temp.p, &ppp->stats, sizeof (struct pppstat));
if (ppp->slcomp != NULL) {
temp.vj.vjs_packets = ppp->slcomp->sls_o_compressed+
}
}
- if (error == 0)
- memcpy_tofs (result, &temp, sizeof (temp));
+ result = (struct ppp_stats *) ifr->ifr_ifru.ifru_data;
+
+ COPY_TO_USER (error,
+ result,
+ &temp,
+ sizeof (temp));
+
return error;
}
{
struct ppp_comp_stats *result, temp;
int error;
-/*
- * Must have write access to the buffer.
- */
- result = (struct ppp_comp_stats *) ifr->ifr_ifru.ifru_data;
- error = verify_area (VERIFY_WRITE,
- result,
- sizeof (temp));
/*
* Supply the information for the caller.
*/
/*
* Move the data to the caller's buffer
*/
- if (error == 0)
- memcpy_tofs (result, &temp, sizeof (temp));
+ result = (struct ppp_comp_stats *) ifr->ifr_ifru.ifru_data;
+
+ COPY_TO_USER (error,
+ result,
+ &temp,
+ sizeof (temp));
+
return error;
}
break;
case NPMODE_ERROR:
- if (ppp->flags & SC_DEBUG)
- printk (KERN_WARNING
- "ppp_dev_xmit: npmode = NPMODE_ERROR on %s\n",
- dev->name);
- return 0;
-
case NPMODE_DROP:
if (ppp->flags & SC_DEBUG)
- printk (KERN_WARNING
- "ppp_dev_xmit: npmode = NPMODE_DROP on %s\n",
- dev->name);
+ printk (KERN_DEBUG
+ "ppp_dev_xmit: npmode = %d on %s\n",
+ ppp->sc_npmode[NP_IP], dev->name);
return 0;
case NPMODE_QUEUE:
dev_close (dev);
return 0;
}
-/*
- * Validate the tty linkage
- */
- if (ppp->flags & SC_DEBUG)
- printk (KERN_DEBUG "ppp_dev_xmit [%s]: skb %p\n",
- dev->name, skb);
/*
* Validate the tty interface
*/
*/
len = skb->len;
data = skb_data(skb);
+
+ if (data == (__u8 *) 0) {
+ if (ppp->flags & SC_DEBUG)
+ printk (KERN_CRIT "ppp_dev_xmit: %s Null skb data\n",
+ dev->name);
+ dev_kfree_skb (skb, FREE_WRITE);
+ return 0;
+ }
/*
* Look at the protocol in the skb to determine the difference between
* an IP frame and an IPX frame.
ppp_dev_stats (struct device *dev)
{
struct ppp *ppp = dev2ppp (dev);
- static struct enet_statistics ppp_stats;
-
- ppp_stats.rx_packets = ppp->stats.ppp_ipackets;
- ppp_stats.rx_errors = ppp->stats.ppp_ierrors;
- ppp_stats.rx_dropped = ppp->stats.ppp_ierrors;
- ppp_stats.rx_fifo_errors = 0;
- ppp_stats.rx_length_errors = 0;
- ppp_stats.rx_over_errors = 0;
- ppp_stats.rx_crc_errors = 0;
- ppp_stats.rx_frame_errors = 0;
- ppp_stats.tx_packets = ppp->stats.ppp_opackets;
- ppp_stats.tx_errors = ppp->stats.ppp_oerrors;
- ppp_stats.tx_dropped = 0;
- ppp_stats.tx_fifo_errors = 0;
- ppp_stats.collisions = 0;
- ppp_stats.tx_carrier_errors = 0;
- ppp_stats.tx_aborted_errors = 0;
- ppp_stats.tx_window_errors = 0;
- ppp_stats.tx_heartbeat_errors = 0;
- if (ppp->flags & SC_DEBUG)
- printk (KERN_INFO "ppp_dev_stats called");
- return &ppp_stats;
+ ppp->estats.rx_packets = ppp->stats.ppp_ipackets;
+ ppp->estats.rx_errors = ppp->stats.ppp_ierrors;
+ ppp->estats.tx_packets = ppp->stats.ppp_opackets;
+ ppp->estats.tx_errors = ppp->stats.ppp_oerrors;
+
+ return &ppp->estats;
}
+#if LINUX_VERSION_CODE < VERSION(2,1,15)
static int ppp_dev_header (sk_buff *skb, struct device *dev,
__u16 type, void *daddr,
void *saddr, unsigned int len)
static int
ppp_dev_rebuild (void *eth, struct device *dev,
- unsigned long raddr, struct sk_buff *skb)
+ unsigned long raddr, struct sk_buff *skb)
{
return (0);
}
+#endif
/*************************************************************
* UTILITIES
/* try to find the exact same free device which we had before */
ctl = ppp_list;
if_num = 0;
-
+
while (ctl) {
ppp = ctl2ppp (ctl);
- if (!set_bit(0, &ppp->inuse)) {
- if (ppp->sc_xfer == pid_value) {
- ppp->sc_xfer = 0;
- return (ppp);
- }
- clear_bit (0, &ppp->inuse);
+ if (ppp->sc_xfer == pid_value) {
+ set_bit(0, &ppp->inuse);
+ ppp->sc_xfer = 0;
+ return (ppp);
}
ctl = ctl->next;
if (++if_num == max_dev)
/* try to find an free device */
ctl = ppp_list;
if_num = 0;
-
+
while (ctl) {
ppp = ctl2ppp (ctl);
if (!set_bit(0, &ppp->inuse))
ppp->line = if_num;
ppp->tty = NULL;
+ ppp->backup_tty = NULL;
ppp->dev = dev;
-
+
dev->next = NULL;
dev->init = ppp_init_dev;
dev->name = ctl->name;
dev->priv = (void *) ppp;
sprintf (dev->name, "ppp%d", if_num);
-
+
/* link in the new channel */
ctl->next = ppp_list;
ppp_list = ctl;
static struct compressor *find_compressor (int type)
{
struct compressor_link *lnk;
- __u32 flags;
+ unsigned long flags;
save_flags(flags);
cli();
static int ppp_register_compressor (struct compressor *cp)
{
struct compressor_link *new;
- __u32 flags;
+ unsigned long flags;
new = (struct compressor_link *) kmalloc (sizeof (struct compressor_link), GFP_KERNEL);
{
struct compressor_link *prev = (struct compressor_link *) 0;
struct compressor_link *lnk;
- __u32 flags;
+ unsigned long flags;
save_flags(flags);
cli();
if (status != 0)
printk (KERN_INFO
"PPP: ppp_init() failure %d\n", status);
+#if LINUX_VERSION_CODE < VERSION(2,1,18)
else
(void) register_symtab (&ppp_syms);
+#endif
return (status);
}
"PPP: ppp line discipline successfully unregistered\n");
/*
* De-register the devices so that there is no problem with them
- */
+ */
next_ctl = ppp_list;
while (next_ctl) {
ctl = next_ctl;