mirror of
https://github.com/paulusmack/ppp.git
synced 2024-11-23 18:33:24 +08:00
Apply patch for sync serial support from Paul Fulghum.
This commit is contained in:
parent
4426185a13
commit
c1d7b083dc
@ -1,4 +1,4 @@
|
||||
/* $Id: if_ppp.h,v 1.17 1999/03/02 05:37:51 paulus Exp $ */
|
||||
/* $Id: if_ppp.h,v 1.18 1999/03/30 06:33:07 paulus Exp $ */
|
||||
|
||||
/*
|
||||
* if_ppp.h - Point-to-Point Protocol definitions.
|
||||
@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* ==FILEVERSION 990226==
|
||||
* ==FILEVERSION 990325==
|
||||
*
|
||||
* NOTE TO MAINTAINERS:
|
||||
* If you modify this file at all, please set the above date.
|
||||
@ -67,7 +67,8 @@
|
||||
#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */
|
||||
#define SC_LOG_RAWIN 0x00080000 /* log all chars received */
|
||||
#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */
|
||||
#define SC_MASK 0x0f0000ff /* bits that user can change */
|
||||
#define SC_SYNC 0x00200000 /* synchronous serial mode */
|
||||
#define SC_MASK 0x0f2000ff /* bits that user can change */
|
||||
|
||||
/* state bits */
|
||||
#define SC_XMIT_BUSY 0x10000000 /* (used by isdn_ppp?) */
|
||||
|
@ -42,7 +42,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* ==FILEVERSION 990114==
|
||||
* ==FILEVERSION 990325==
|
||||
*
|
||||
* NOTE TO MAINTAINERS:
|
||||
* If you modify this file at all, please set the above date.
|
||||
@ -89,6 +89,7 @@ struct ppp {
|
||||
__u8 escape; /* 0x20 if prev char was PPP_ESC */
|
||||
__u8 toss; /* toss this frame */
|
||||
volatile __u8 tty_pushing; /* internal state flag */
|
||||
volatile __u8 woke_up; /* internal state flag */
|
||||
__u32 xmit_async_map[8]; /* 1 bit means that given control
|
||||
character is quoted on output*/
|
||||
__u32 recv_async_map; /* 1 bit means that given control
|
||||
|
243
linux/ppp.c
243
linux/ppp.c
@ -4,7 +4,7 @@
|
||||
* Al Longyear <longyear@netcom.com>
|
||||
* Extensively rewritten by Paul Mackerras <paulus@cs.anu.edu.au>
|
||||
*
|
||||
* ==FILEVERSION 990114==
|
||||
* ==FILEVERSION 990325==
|
||||
*
|
||||
* NOTE TO MAINTAINERS:
|
||||
* If you modify this file at all, please set the number above to the
|
||||
@ -45,7 +45,7 @@
|
||||
|
||||
#define PPP_MAX_RCV_QLEN 32 /* max # frames we queue up for pppd */
|
||||
|
||||
/* $Id: ppp.c,v 1.21 1999/02/26 06:48:21 paulus Exp $ */
|
||||
/* $Id: ppp.c,v 1.22 1999/03/30 06:33:07 paulus Exp $ */
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/config.h>
|
||||
@ -185,9 +185,11 @@ static void ppp_unregister_compressor (struct compressor *cp);
|
||||
|
||||
static void ppp_async_init(struct ppp *ppp);
|
||||
static void ppp_async_release(struct ppp *ppp);
|
||||
static int ppp_tty_sync_push(struct ppp *ppp);
|
||||
static int ppp_tty_push(struct ppp *ppp);
|
||||
static int ppp_async_encode(struct ppp *ppp);
|
||||
static int ppp_async_send(struct ppp *, struct sk_buff *);
|
||||
static int ppp_sync_send(struct ppp *, struct sk_buff *);
|
||||
|
||||
static int ppp_ioctl(struct ppp *, unsigned int, unsigned long);
|
||||
static int ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp);
|
||||
@ -954,6 +956,135 @@ ppp_tty_wakeup (struct tty_struct *tty)
|
||||
ppp_output_wakeup(ppp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a packet to the peer over a synchronous tty line.
|
||||
* All encoding and FCS are handled by hardware.
|
||||
* Addr/Ctrl and Protocol field compression implemented.
|
||||
* Returns -1 iff the packet could not be accepted at present,
|
||||
* 0 if the packet was accepted but we can't accept another yet, or
|
||||
* 1 if we can accept another packet immediately.
|
||||
* If this procedure returns 0, ppp_output_wakeup will be called
|
||||
* exactly once.
|
||||
*/
|
||||
static int
|
||||
ppp_sync_send(struct ppp *ppp, struct sk_buff *skb)
|
||||
{
|
||||
unsigned char *data;
|
||||
int islcp;
|
||||
|
||||
CHECK_PPP(0);
|
||||
|
||||
if (ppp->tpkt != NULL)
|
||||
return -1;
|
||||
ppp->tpkt = skb;
|
||||
|
||||
data = ppp->tpkt->data;
|
||||
|
||||
/*
|
||||
* LCP packets with code values between 1 (configure-reqest)
|
||||
* and 7 (code-reject) must be sent as though no options
|
||||
* had been negotiated.
|
||||
*/
|
||||
islcp = PPP_PROTOCOL(data) == PPP_LCP
|
||||
&& 1 <= data[PPP_HDRLEN] && data[PPP_HDRLEN] <= 7;
|
||||
|
||||
/* only reset idle time for data packets */
|
||||
if (PPP_PROTOCOL(data) < 0x8000)
|
||||
ppp->last_xmit = jiffies;
|
||||
++ppp->stats.ppp_opackets;
|
||||
ppp->stats.ppp_ooctects += ppp->tpkt->len;
|
||||
|
||||
if ( !(data[2]) && (ppp->flags & SC_COMP_PROT) ) {
|
||||
/* compress protocol field */
|
||||
data[2] = data[1];
|
||||
data[1] = data[0];
|
||||
skb_pull(ppp->tpkt,1);
|
||||
data = ppp->tpkt->data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do address/control compression
|
||||
*/
|
||||
if ((ppp->flags & SC_COMP_AC) && !islcp
|
||||
&& PPP_ADDRESS(data) == PPP_ALLSTATIONS
|
||||
&& PPP_CONTROL(data) == PPP_UI) {
|
||||
/* strip addr and control field */
|
||||
skb_pull(ppp->tpkt,2);
|
||||
}
|
||||
|
||||
return ppp_tty_sync_push(ppp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Push a synchronous frame out to the tty.
|
||||
* Returns 1 if frame accepted (or discarded), 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
ppp_tty_sync_push(struct ppp *ppp)
|
||||
{
|
||||
int sent;
|
||||
struct tty_struct *tty = ppp2tty(ppp);
|
||||
unsigned long flags;
|
||||
|
||||
CHECK_PPP(0);
|
||||
|
||||
if (ppp->tpkt == NULL)
|
||||
return 0;
|
||||
|
||||
/* prevent reentrancy with tty_pushing flag */
|
||||
save_flags(flags);
|
||||
cli();
|
||||
if (ppp->tty_pushing) {
|
||||
/* record wakeup attempt so we don't loose */
|
||||
/* a wakeup call while doing push processing */
|
||||
ppp->woke_up=1;
|
||||
restore_flags(flags);
|
||||
return 0;
|
||||
}
|
||||
ppp->tty_pushing = 1;
|
||||
restore_flags(flags);
|
||||
|
||||
if (tty == NULL || tty->disc_data != (void *) ppp)
|
||||
goto flush;
|
||||
|
||||
for(;;){
|
||||
ppp->woke_up=0;
|
||||
|
||||
/* Note: Sync driver accepts complete frame or nothing */
|
||||
tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
|
||||
sent = tty->driver.write(tty, 0, ppp->tpkt->data, ppp->tpkt->len);
|
||||
if (sent < 0) {
|
||||
/* write error (possible loss of CD) */
|
||||
/* record error and discard current packet */
|
||||
ppp->stats.ppp_oerrors++;
|
||||
break;
|
||||
}
|
||||
ppp->stats.ppp_obytes += sent;
|
||||
if (sent < ppp->tpkt->len) {
|
||||
/* driver unable to accept frame just yet */
|
||||
save_flags(flags);
|
||||
cli();
|
||||
if (ppp->woke_up) {
|
||||
/* wake up called while processing */
|
||||
/* try to send the frame again */
|
||||
restore_flags(flags);
|
||||
continue;
|
||||
}
|
||||
/* wait for wakeup callback to try send again */
|
||||
ppp->tty_pushing = 0;
|
||||
restore_flags(flags);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
flush:
|
||||
/* done with current packet (sent or discarded) */
|
||||
KFREE_SKB(ppp->tpkt);
|
||||
ppp->tpkt = 0;
|
||||
ppp->tty_pushing = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a packet to the peer over an async tty line.
|
||||
* Returns -1 iff the packet could not be accepted at present,
|
||||
@ -986,6 +1117,9 @@ ppp_tty_push(struct ppp *ppp)
|
||||
{
|
||||
int avail, sent, done = 0;
|
||||
struct tty_struct *tty = ppp2tty(ppp);
|
||||
|
||||
if ( ppp->flags & SC_SYNC )
|
||||
return ppp_tty_sync_push(ppp);
|
||||
|
||||
CHECK_PPP(0);
|
||||
if (ppp->tty_pushing)
|
||||
@ -1184,6 +1318,74 @@ ppp_tty_receive (struct tty_struct *tty, const __u8 * data,
|
||||
|
||||
ppp->stats.ppp_ibytes += count;
|
||||
skb = ppp->rpkt;
|
||||
|
||||
if ( ppp->flags & SC_SYNC ) {
|
||||
/* synchronous mode */
|
||||
|
||||
if (ppp->toss==0xE0) {
|
||||
/* this is the 1st frame, reset vj comp */
|
||||
ppp_receive_error(ppp);
|
||||
ppp->toss = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate an skbuff for frame.
|
||||
* The 128 is room for VJ header expansion.
|
||||
*/
|
||||
|
||||
if (skb == NULL)
|
||||
skb = dev_alloc_skb(ppp->mru + 128 + PPP_HDRLEN);
|
||||
|
||||
if (skb == NULL) {
|
||||
if (ppp->flags & SC_DEBUG)
|
||||
printk(KERN_DEBUG "couldn't "
|
||||
"alloc skb for recv\n");
|
||||
} else {
|
||||
LIBERATE_SKB(skb);
|
||||
/*
|
||||
* Decompress A/C and protocol compression here.
|
||||
*/
|
||||
p = skb_put(skb, 2);
|
||||
p[0] = PPP_ALLSTATIONS;
|
||||
p[1] = PPP_UI;
|
||||
if (*data == PPP_ALLSTATIONS) {
|
||||
data += 2;
|
||||
count -= 2;
|
||||
}
|
||||
if ((*data & 1) != 0) {
|
||||
p = skb_put(skb, 1);
|
||||
p[0] = 0;
|
||||
}
|
||||
|
||||
/* copy frame to socket buffer */
|
||||
p = skb_put(skb, count);
|
||||
memcpy(p,data,count);
|
||||
|
||||
/*
|
||||
* Check if we've overflowed the MRU
|
||||
*/
|
||||
if (skb->len >= ppp->mru + PPP_HDRLEN + 2
|
||||
|| skb_tailroom(skb) <= 0) {
|
||||
++ppp->estats.rx_length_errors;
|
||||
if (ppp->flags & SC_DEBUG)
|
||||
printk(KERN_DEBUG "rcv frame too long: "
|
||||
"len=%d mru=%d hroom=%d troom=%d\n",
|
||||
skb->len, ppp->mru, skb_headroom(skb),
|
||||
skb_tailroom(skb));
|
||||
} else {
|
||||
if (!ppp_receive_frame(ppp, skb)) {
|
||||
KFREE_SKB(skb);
|
||||
ppp_receive_error(ppp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset for the next frame */
|
||||
skb = NULL;
|
||||
}
|
||||
ppp->rpkt = skb;
|
||||
return;
|
||||
}
|
||||
|
||||
while (count-- > 0) {
|
||||
/*
|
||||
* Collect the character and error condition for the character.
|
||||
@ -2024,23 +2226,25 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the FCS of the frame and discard the FCS characters
|
||||
* from the end of the buffer.
|
||||
*/
|
||||
if (ppp->rfcs != PPP_GOODFCS) {
|
||||
if (ppp->flags & SC_DEBUG) {
|
||||
printk(KERN_DEBUG
|
||||
"ppp: frame with bad fcs, length = %d\n",
|
||||
count);
|
||||
ppp_print_buffer("bad frame", data, count);
|
||||
if ( !(ppp->flags & SC_SYNC) ) {
|
||||
/*
|
||||
* Verify the FCS of the frame and discard the FCS characters
|
||||
* from the end of the buffer.
|
||||
*/
|
||||
if (ppp->rfcs != PPP_GOODFCS) {
|
||||
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;
|
||||
}
|
||||
++ppp->estats.rx_crc_errors;
|
||||
return 0;
|
||||
count -= 2; /* ignore the fcs characters */
|
||||
skb_trim(skb, count);
|
||||
}
|
||||
count -= 2; /* ignore the fcs characters */
|
||||
skb_trim(skb, count);
|
||||
|
||||
|
||||
/*
|
||||
* Process the active decompressor.
|
||||
*/
|
||||
@ -2410,7 +2614,10 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
|
||||
/*
|
||||
* Send the frame
|
||||
*/
|
||||
ret = ppp_async_send(ppp, skb);
|
||||
if ( ppp->flags & SC_SYNC )
|
||||
ret = ppp_sync_send(ppp, skb);
|
||||
else
|
||||
ret = ppp_async_send(ppp, skb);
|
||||
if (ret > 0) {
|
||||
/* we can release the lock */
|
||||
ppp->xmit_busy = 0;
|
||||
|
@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: options.c,v 1.55 1999/03/24 05:05:24 paulus Exp $";
|
||||
static char rcsid[] = "$Id: options.c,v 1.56 1999/03/30 06:33:08 paulus Exp $";
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
@ -89,6 +89,7 @@ int holdoff = 30; /* # seconds to pause before reconnecting */
|
||||
bool notty = 0; /* Stdin/out is not a tty */
|
||||
char *record_file = NULL; /* File to record chars sent/received */
|
||||
int using_pty = 0;
|
||||
bool sync_serial = 0; /* Device is synchronous serial device */
|
||||
|
||||
extern option_t auth_options[];
|
||||
|
||||
@ -211,6 +212,8 @@ option_t general_options[] = {
|
||||
"Show brief listing of options" },
|
||||
{ "-h", o_special_noarg, showhelp,
|
||||
"Show brief listing of options" },
|
||||
{ "sync", o_bool, &sync_serial,
|
||||
"Use synchronous HDLC serial encoding", 1 },
|
||||
|
||||
#ifdef PPP_FILTER
|
||||
{ "pdebug", o_int, &dflag,
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" manual page [] for pppd 2.3
|
||||
.\" $Id: pppd.8,v 1.37 1999/03/23 03:22:34 paulus Exp $
|
||||
.\" $Id: pppd.8,v 1.38 1999/03/30 06:33:09 paulus Exp $
|
||||
.\" SH section heading
|
||||
.\" SS subsection heading
|
||||
.\" LP paragraph
|
||||
@ -690,6 +690,12 @@ With this option, pppd will not transmit LCP packets to initiate a
|
||||
connection until a valid LCP packet is received from the peer (as for
|
||||
the `passive' option with ancient versions of pppd).
|
||||
.TP
|
||||
.B sync
|
||||
Use synchronous HDLC serial encoding instead of asynchronous.
|
||||
The device used by pppd with this option must support synchronous
|
||||
serial communications. Currently supports Microgate SyncLink adapters
|
||||
under Linux.
|
||||
.TP
|
||||
.B usehostname
|
||||
Enforce the use of the hostname (with domain name appended, if given)
|
||||
as the name of the local system for authentication purposes (overrides
|
||||
|
@ -16,7 +16,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: pppd.h,v 1.35 1999/03/24 05:05:25 paulus Exp $
|
||||
* $Id: pppd.h,v 1.36 1999/03/30 06:33:09 paulus Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -181,6 +181,7 @@ extern int idle_time_limit;/* Shut down link if idle for this long */
|
||||
extern int holdoff; /* Dead time before restarting */
|
||||
extern bool notty; /* Stdin/out is not a tty */
|
||||
extern char *record_file; /* File to record chars sent/received */
|
||||
extern bool sync_serial; /* Device is synchronous serial device */
|
||||
|
||||
#ifdef PPP_FILTER
|
||||
extern struct bpf_program pass_filter; /* Filter for pkts to pass */
|
||||
|
@ -866,6 +866,7 @@ void ppp_send_config (int unit,int mtu,u_int32_t asyncmap,int pcomp,int accomp)
|
||||
x = get_flags();
|
||||
x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT;
|
||||
x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC;
|
||||
x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC;
|
||||
set_flags(x);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user