Bring pppd from ppp-2.2 onto the mainline..

(more work needs to be done here, I'm trying to beat the supscan)
This commit is contained in:
Peter Wemm 1995-10-31 21:21:51 +00:00
parent e046098fa9
commit 60f531a365
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=11983
21 changed files with 2416 additions and 1714 deletions

View file

@ -1,10 +1,14 @@
# From: Id: Makefile.bsd,v 1.4 1994/04/20 00:07:50 paulus Exp
# $Id$
# $Id: Makefile.bsd,v 1.7 1995/04/27 00:19:50 paulus Exp $
BINDIR?= /usr/sbin
CFLAGS+= -I.. -DHAVE_PATHS_H
PROG= pppd
SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c \
auth.c options.c lock.c sys-bsd.c
SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
auth.c options.c sys-bsd.c
MAN8= pppd.8
# The next line is for NetBSD-current systems.
MAN= pppd.cat8
BINMODE=4555
BINOWN= root

View file

@ -33,11 +33,12 @@
*/
#ifndef lint
static char rcsid[] = "$Id: auth.c,v 1.3 1995/05/30 03:51:04 rgrimes Exp $";
static char rcsid[] = "$Id: auth.c,v 1.17 1995/08/16 01:37:22 paulus Exp $";
#endif
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <syslog.h>
#include <pwd.h>
#include <string.h>
@ -48,16 +49,24 @@ static char rcsid[] = "$Id: auth.c,v 1.3 1995/05/30 03:51:04 rgrimes Exp $";
#include <netinet/in.h>
#include <arpa/inet.h>
#include "ppp.h"
#ifdef HAS_SHADOW
#include <shadow.h>
#include <shadow/pwauth.h>
#ifndef PW_PPP
#define PW_PPP PW_LOGIN
#endif
#endif
#include "pppd.h"
#include "fsm.h"
#include "lcp.h"
#include "upap.h"
#include "chap.h"
#include "ipcp.h"
#include "ccp.h"
#include "pathnames.h"
#ifdef sparc
#if defined(sun) && defined(sparc)
#include <alloca.h>
#endif /*sparc*/
@ -76,20 +85,10 @@ struct wordlist {
#define FALSE 0
#define TRUE 1
extern char user[];
extern char passwd[];
extern char devname[];
extern char our_name[];
extern char remote_name[];
extern char hostname[];
extern int uselogin;
extern int usehostname;
extern int auth_required;
/* Records which authentication operations haven't completed yet. */
static int auth_pending[NPPP];
static int auth_pending[NUM_PPP];
static int logged_in;
static struct wordlist *addresses[NPPP];
static struct wordlist *addresses[NUM_PPP];
/* Bits in auth_pending[] */
#define UPAP_WITHPEER 1
@ -98,19 +97,20 @@ static struct wordlist *addresses[NPPP];
#define CHAP_PEER 8
/* Prototypes */
void check_access __ARGS((FILE *, char *));
void check_access __P((FILE *, char *));
static int login __ARGS((char *, char *, char **, int *));
static void logout __ARGS((void));
static int null_login __ARGS((int));
static int get_upap_passwd __ARGS((void));
static int have_upap_secret __ARGS((void));
static int have_chap_secret __ARGS((char *, char *));
static int scan_authfile __ARGS((FILE *, char *, char *, char *,
static void network_phase __P((int));
static int login __P((char *, char *, char **, int *));
static void logout __P((void));
static int null_login __P((int));
static int get_upap_passwd __P((void));
static int have_upap_secret __P((void));
static int have_chap_secret __P((char *, char *));
static int scan_authfile __P((FILE *, char *, char *, char *,
struct wordlist **, char *));
static void free_wordlist __ARGS((struct wordlist *));
static void free_wordlist __P((struct wordlist *));
extern char *crypt __ARGS((char *, char *));
extern char *crypt __P((char *, char *));
/*
* An Open on LCP has requested a change from Dead to Establish phase.
@ -130,6 +130,8 @@ void
link_terminated(unit)
int unit;
{
if (phase == PHASE_DEAD)
return;
if (logged_in)
logout();
phase = PHASE_DEAD;
@ -143,6 +145,8 @@ void
link_down(unit)
int unit;
{
ipcp_close(0);
ccp_close(0);
phase = PHASE_TERMINATE;
}
@ -165,7 +169,7 @@ link_established(unit)
* treat it as though it authenticated with PAP using a username
* of "" and a password of "". If that's not OK, boot it out.
*/
if (wo->neg_upap && !null_login(unit)) {
if (!wo->neg_upap || !null_login(unit)) {
syslog(LOG_WARNING, "peer refused to authenticate");
lcp_close(unit);
phase = PHASE_TERMINATE;
@ -191,10 +195,20 @@ link_established(unit)
}
auth_pending[unit] = auth;
if (!auth) {
phase = PHASE_NETWORK;
ipcp_open(unit);
}
if (!auth)
network_phase(unit);
}
/*
* Proceed to the network phase.
*/
static void
network_phase(unit)
int unit;
{
phase = PHASE_NETWORK;
ipcp_open(unit);
ccp_open(unit);
}
/*
@ -221,10 +235,10 @@ auth_peer_success(unit, protocol)
int bit;
switch (protocol) {
case CHAP:
case PPP_CHAP:
bit = CHAP_PEER;
break;
case UPAP:
case PPP_PAP:
bit = UPAP_PEER;
break;
default:
@ -240,6 +254,7 @@ auth_peer_success(unit, protocol)
if ((auth_pending[unit] &= ~bit) == 0) {
phase = PHASE_NETWORK;
ipcp_open(unit);
ccp_open(unit);
}
}
@ -267,10 +282,10 @@ auth_withpeer_success(unit, protocol)
int bit;
switch (protocol) {
case CHAP:
case PPP_CHAP:
bit = CHAP_WITHPEER;
break;
case UPAP:
case PPP_PAP:
bit = UPAP_WITHPEER;
break;
default:
@ -283,10 +298,8 @@ auth_withpeer_success(unit, protocol)
* If there is no more authentication still being done,
* proceed to the network phase.
*/
if ((auth_pending[unit] &= ~bit) == 0) {
phase = PHASE_NETWORK;
ipcp_open(unit);
}
if ((auth_pending[unit] &= ~bit) == 0)
network_phase(unit);
}
@ -386,7 +399,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
} else {
check_access(f, filename);
if (scan_authfile(f, user, our_name, secret, &addrs, filename) < 0
|| (secret[0] != 0 && strcmp(passwd, secret) != 0
|| (secret[0] != 0 && (cryptpap || strcmp(passwd, secret) != 0)
&& strcmp(crypt(passwd, secret), secret) != 0)) {
syslog(LOG_WARNING, "upap authentication failure for %s", user);
ret = UPAP_AUTHNAK;
@ -411,7 +424,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
*/
if (attempts++ >= 10) {
syslog(LOG_WARNING, "%d LOGIN FAILURES ON %s, %s",
attempts, devname, user);
attempts, devnam, user);
quit();
}
if (attempts > 3)
@ -452,12 +465,22 @@ login(user, passwd, msg, msglen)
char *epasswd;
char *tty;
#ifdef HAS_SHADOW
struct spwd *spwd;
struct spwd *getspnam();
#endif
if ((pw = getpwnam(user)) == NULL) {
return (UPAP_AUTHNAK);
}
if (pw->pw_expire && time(NULL) >= pw->pw_expire)
return (UPAP_AUTHNAK);
#ifdef HAS_SHADOW
if ((spwd = getspnam(user)) == NULL) {
pw->pw_passwd = "";
} else {
pw->pw_passwd = spwd->sp_pwdp;
}
#endif
/*
* XXX If no passwd, let them login without one.
@ -466,21 +489,27 @@ login(user, passwd, msg, msglen)
return (UPAP_AUTHACK);
}
#ifdef HAS_SHADOW
if ((pw->pw_passwd && pw->pw_passwd[0] == '@'
&& pw_auth (pw->pw_passwd+1, pw->pw_name, PW_PPP, NULL))
|| !valid (passwd, pw)) {
return (UPAP_AUTHNAK);
}
#else
epasswd = crypt(passwd, pw->pw_passwd);
if (strcmp(epasswd, pw->pw_passwd)) {
return (UPAP_AUTHNAK);
}
#endif
syslog(LOG_INFO, "user %s logged in", user);
/*
* Write a wtmp entry for this user.
*/
tty = strrchr(devname, '/');
if (tty == NULL)
tty = devname;
else
tty++;
tty = devnam;
if (strncmp(tty, "/dev/", 5) == 0)
tty += 5;
logwtmp(tty, user, ""); /* Add wtmp login entry */
logged_in = TRUE;
@ -495,11 +524,9 @@ logout()
{
char *tty;
tty = strrchr(devname, '/');
if (tty == NULL)
tty = devname;
else
tty++;
tty = devnam;
if (strncmp(tty, "/dev/", 5) == 0)
tty += 5;
logwtmp(tty, "", ""); /* Wipe out wtmp logout entry */
logged_in = FALSE;
}
@ -691,9 +718,9 @@ get_secret(unit, client, server, secret, secret_len, save_addrs)
int
auth_ip_addr(unit, addr)
int unit;
u_long addr;
u_int32_t addr;
{
u_long a;
u_int32_t a;
struct hostent *hp;
struct wordlist *addrs;
@ -714,7 +741,7 @@ auth_ip_addr(unit, addr)
addrs->word);
continue;
} else
a = *(u_long *)hp->h_addr;
a = *(u_int32_t *)hp->h_addr;
}
if (addr == a)
return 1;
@ -729,7 +756,7 @@ auth_ip_addr(unit, addr)
*/
int
bad_ip_adrs(addr)
u_long addr;
u_int32_t addr;
{
addr = ntohl(addr);
return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
@ -761,7 +788,7 @@ check_access(f, filename)
* NONWILD_CLIENT set if the secret didn't have "*" for the client, and
* NONWILD_SERVER set if the secret didn't have "*" for the server.
* Any following words on the line (i.e. address authorization
* info) are placed in a wordlist and returned in *addrs.
* info) are placed in a wordlist and returned in *addrs.
*/
static int
scan_authfile(f, client, server, secret, addrs, filename)
@ -854,7 +881,7 @@ scan_authfile(f, client, server, secret, addrs, filename)
}
if (secret != NULL)
strcpy(secret, word);
best_flag = got_flag;
/*

View file

@ -19,7 +19,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: chap.c,v 1.2 1994/09/25 02:31:54 wollman Exp $";
static char rcsid[] = "$Id: chap.c,v 1.8 1995/07/04 12:32:26 paulus Exp $";
#endif
/*
@ -27,30 +27,30 @@ static char rcsid[] = "$Id: chap.c,v 1.2 1994/09/25 02:31:54 wollman Exp $";
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <syslog.h>
#include "ppp.h"
#include "pppd.h"
#include "chap.h"
#include "md5.h"
chap_state chap[NPPP]; /* CHAP state; one for each unit */
chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */
static void ChapChallengeTimeout __ARGS((caddr_t));
static void ChapResponseTimeout __ARGS((caddr_t));
static void ChapReceiveChallenge __ARGS((chap_state *, u_char *, int, int));
static void ChapReceiveResponse __ARGS((chap_state *, u_char *, int, int));
static void ChapReceiveSuccess __ARGS((chap_state *, u_char *, int, int));
static void ChapReceiveFailure __ARGS((chap_state *, u_char *, int, int));
static void ChapSendStatus __ARGS((chap_state *, int));
static void ChapSendChallenge __ARGS((chap_state *));
static void ChapSendResponse __ARGS((chap_state *));
static void ChapGenChallenge __ARGS((chap_state *));
static void ChapChallengeTimeout __P((caddr_t));
static void ChapResponseTimeout __P((caddr_t));
static void ChapReceiveChallenge __P((chap_state *, u_char *, int, int));
static void ChapReceiveResponse __P((chap_state *, u_char *, int, int));
static void ChapReceiveSuccess __P((chap_state *, u_char *, int, int));
static void ChapReceiveFailure __P((chap_state *, u_char *, int, int));
static void ChapSendStatus __P((chap_state *, int));
static void ChapSendChallenge __P((chap_state *));
static void ChapSendResponse __P((chap_state *));
static void ChapGenChallenge __P((chap_state *));
extern double drand48 __ARGS((void));
extern void srand48 __ARGS((long));
extern double drand48 __P((void));
extern void srand48 __P((long));
/*
* ChapInit - Initialize a CHAP unit.
@ -67,7 +67,7 @@ ChapInit(unit)
cstate->serverstate = CHAPSS_INITIAL;
cstate->timeouttime = CHAP_DEFTIMEOUT;
cstate->max_transmits = CHAP_DEFTRANSMITS;
srand48((long) time(NULL)); /* joggle random number generator */
/* random number generator is initialized in magic_init */
}
@ -95,7 +95,7 @@ ChapAuthWithPeer(unit, our_name, digest)
/*
* We get here as a result of LCP coming up.
* So even if CHAP was open before, we will
* So even if CHAP was open before, we will
* have to re-authenticate ourselves.
*/
cstate->clientstate = CHAPCS_LISTEN;
@ -112,7 +112,7 @@ ChapAuthPeer(unit, our_name, digest)
int digest;
{
chap_state *cstate = &chap[unit];
cstate->chal_name = our_name;
cstate->chal_type = digest;
@ -137,7 +137,7 @@ ChapChallengeTimeout(arg)
caddr_t arg;
{
chap_state *cstate = (chap_state *) arg;
/* if we aren't sending challenges, don't worry. then again we */
/* probably shouldn't be here either */
if (cstate->serverstate != CHAPSS_INITIAL_CHAL &&
@ -148,7 +148,7 @@ ChapChallengeTimeout(arg)
/* give up on peer */
syslog(LOG_ERR, "Peer failed to respond to CHAP challenge");
cstate->serverstate = CHAPSS_BADAUTH;
auth_peer_fail(cstate->unit, CHAP);
auth_peer_fail(cstate->unit, PPP_CHAP);
return;
}
@ -189,9 +189,6 @@ ChapRechallenge(arg)
ChapGenChallenge(cstate);
ChapSendChallenge(cstate);
cstate->serverstate = CHAPSS_RECHALLENGE;
if (cstate->chal_interval != 0)
TIMEOUT(ChapRechallenge, (caddr_t) cstate, cstate->chal_interval);
}
@ -205,7 +202,7 @@ ChapLowerUp(unit)
int unit;
{
chap_state *cstate = &chap[unit];
if (cstate->clientstate == CHAPCS_INITIAL)
cstate->clientstate = CHAPCS_CLOSED;
else if (cstate->clientstate == CHAPCS_PENDING)
@ -231,7 +228,7 @@ ChapLowerDown(unit)
int unit;
{
chap_state *cstate = &chap[unit];
/* Timeout(s) pending? Cancel if so. */
if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||
cstate->serverstate == CHAPSS_RECHALLENGE)
@ -258,10 +255,10 @@ ChapProtocolReject(unit)
if (cstate->serverstate != CHAPSS_INITIAL &&
cstate->serverstate != CHAPSS_CLOSED)
auth_peer_fail(unit, CHAP);
auth_peer_fail(unit, PPP_CHAP);
if (cstate->clientstate != CHAPCS_INITIAL &&
cstate->clientstate != CHAPCS_CLOSED)
auth_withpeer_fail(unit, CHAP);
auth_withpeer_fail(unit, PPP_CHAP);
ChapLowerDown(unit); /* shutdown chap */
}
@ -279,7 +276,7 @@ ChapInput(unit, inpacket, packet_len)
u_char *inp;
u_char code, id;
int len;
/*
* Parse header (code, id and length).
* If packet too short, drop it.
@ -301,7 +298,7 @@ ChapInput(unit, inpacket, packet_len)
return;
}
len -= CHAP_HEADERLEN;
/*
* Action depends on code (as in fact it usually does :-).
*/
@ -309,11 +306,11 @@ ChapInput(unit, inpacket, packet_len)
case CHAP_CHALLENGE:
ChapReceiveChallenge(cstate, inp, id, len);
break;
case CHAP_RESPONSE:
ChapReceiveResponse(cstate, inp, id, len);
break;
case CHAP_FAILURE:
ChapReceiveFailure(cstate, inp, id, len);
break;
@ -345,7 +342,7 @@ ChapReceiveChallenge(cstate, inp, id, len)
char secret[MAXSECRETLEN];
char rhostname[256];
MD5_CTX mdContext;
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.", id));
if (cstate->clientstate == CHAPCS_CLOSED ||
cstate->clientstate == CHAPCS_PENDING) {
@ -392,7 +389,7 @@ ChapReceiveChallenge(cstate, inp, id, len)
cstate->resp_transmits = 0;
/* generate MD based on negotiated type */
switch (cstate->resp_type) {
switch (cstate->resp_type) {
case CHAP_DIGEST_MD5: /* only MD5 is defined for now */
MD5Init(&mdContext);
@ -494,7 +491,7 @@ ChapReceiveResponse(cstate, inp, id, len)
} else {
/* generate MD based on negotiated type */
switch (cstate->chal_type) {
switch (cstate->chal_type) {
case CHAP_DIGEST_MD5: /* only MD5 is defined for now */
if (remmd_len != MD5_SIGNATURE_SIZE)
@ -503,10 +500,10 @@ ChapReceiveResponse(cstate, inp, id, len)
MD5Update(&mdContext, &cstate->chal_id, 1);
MD5Update(&mdContext, secret, secret_len);
MD5Update(&mdContext, cstate->challenge, cstate->chal_len);
MD5Final(&mdContext);
MD5Final(&mdContext);
/* compare local and remote MDs and send the appropriate status */
if (bcmp (mdContext.digest, remmd, MD5_SIGNATURE_SIZE) == 0)
if (memcmp (mdContext.digest, remmd, MD5_SIGNATURE_SIZE) == 0)
code = CHAP_SUCCESS; /* they are the same! */
break;
@ -521,7 +518,7 @@ ChapReceiveResponse(cstate, inp, id, len)
old_state = cstate->serverstate;
cstate->serverstate = CHAPSS_OPEN;
if (old_state == CHAPSS_INITIAL_CHAL) {
auth_peer_success(cstate->unit, CHAP);
auth_peer_success(cstate->unit, PPP_CHAP);
}
if (cstate->chal_interval != 0)
TIMEOUT(ChapRechallenge, (caddr_t) cstate, cstate->chal_interval);
@ -529,7 +526,7 @@ ChapReceiveResponse(cstate, inp, id, len)
} else {
syslog(LOG_ERR, "CHAP peer authentication failed");
cstate->serverstate = CHAPSS_BADAUTH;
auth_peer_fail(cstate->unit, CHAP);
auth_peer_fail(cstate->unit, PPP_CHAP);
}
}
@ -567,7 +564,7 @@ ChapReceiveSuccess(cstate, inp, id, len)
cstate->clientstate = CHAPCS_OPEN;
auth_withpeer_success(cstate->unit, CHAP);
auth_withpeer_success(cstate->unit, PPP_CHAP);
}
@ -583,7 +580,7 @@ ChapReceiveFailure(cstate, inp, id, len)
{
u_char msglen;
u_char *msg;
CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: Rcvd id %d.", id));
if (cstate->clientstate != CHAPCS_RESPONSE) {
@ -602,7 +599,7 @@ ChapReceiveFailure(cstate, inp, id, len)
PRINTMSG(inp, len);
syslog(LOG_ERR, "CHAP authentication failed");
auth_withpeer_fail(cstate->unit, CHAP);
auth_withpeer_fail(cstate->unit, PPP_CHAP);
}
@ -622,7 +619,7 @@ ChapSendChallenge(cstate)
outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;
outp = outpacket_buf;
MAKEHEADER(outp, CHAP); /* paste in a CHAP header */
MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */
PUTCHAR(CHAP_CHALLENGE, outp);
PUTCHAR(cstate->chal_id, outp);
@ -634,8 +631,8 @@ ChapSendChallenge(cstate)
BCOPY(cstate->chal_name, outp, name_len); /* append hostname */
output(cstate->unit, outpacket_buf, outlen + DLLHEADERLEN);
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.", cstate->chal_id));
TIMEOUT(ChapChallengeTimeout, (caddr_t) cstate, cstate->timeouttime);
@ -664,14 +661,14 @@ ChapSendStatus(cstate, code)
outlen = CHAP_HEADERLEN + msglen;
outp = outpacket_buf;
MAKEHEADER(outp, CHAP); /* paste in a header */
MAKEHEADER(outp, PPP_CHAP); /* paste in a header */
PUTCHAR(code, outp);
PUTCHAR(cstate->chal_id, outp);
PUTSHORT(outlen, outp);
BCOPY(msg, outp, msglen);
output(cstate->unit, outpacket_buf, outlen + DLLHEADERLEN);
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.", code,
cstate->chal_id));
}
@ -691,8 +688,8 @@ ChapGenChallenge(cstate)
u_char *ptr = cstate->challenge;
unsigned int i;
/* pick a random challenge length between MIN_CHALLENGE_LENGTH and
MAX_CHALLENGE_LENGTH */
/* pick a random challenge length between MIN_CHALLENGE_LENGTH and
MAX_CHALLENGE_LENGTH */
chal_len = (unsigned) ((drand48() *
(MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
MIN_CHALLENGE_LENGTH);
@ -722,7 +719,7 @@ ChapSendResponse(cstate)
outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;
outp = outpacket_buf;
MAKEHEADER(outp, CHAP);
MAKEHEADER(outp, PPP_CHAP);
PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */
PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */
@ -735,7 +732,7 @@ ChapSendResponse(cstate)
BCOPY(cstate->resp_name, outp, name_len); /* append our name */
/* send the packet */
output(cstate->unit, outpacket_buf, outlen + DLLHEADERLEN);
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
cstate->clientstate = CHAPCS_RESPONSE;
TIMEOUT(ChapResponseTimeout, (caddr_t) cstate, cstate->timeouttime);
@ -753,7 +750,7 @@ int
ChapPrintPkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __ARGS((void *, char *, ...));
void (*printer) __P((void *, char *, ...));
void *arg;
{
int code, id, len;
@ -806,18 +803,3 @@ ChapPrintPkt(p, plen, printer, arg)
return len + CHAP_HEADERLEN;
}
#ifdef NO_DRAND48
double drand48()
{
return (double)random() / (double)0x7fffffffL; /* 2**31-1 */
}
void srand48(seedval)
long seedval;
{
srand((int)seedval);
}
#endif

View file

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: chap.h,v 1.2 1994/04/11 07:13:44 paulus Exp $
* $Id: chap.h,v 1.3 1994/09/21 06:47:37 paulus Exp $
*/
#ifndef __CHAP_INCLUDE__
@ -98,15 +98,15 @@ typedef struct chap_state {
extern chap_state chap[];
void ChapInit __ARGS((int));
void ChapAuthWithPeer __ARGS((int, char *, int));
void ChapAuthPeer __ARGS((int, char *, int));
void ChapLowerUp __ARGS((int));
void ChapLowerDown __ARGS((int));
void ChapInput __ARGS((int, u_char *, int));
void ChapProtocolReject __ARGS((int));
int ChapPrintPkt __ARGS((u_char *, int,
void (*) __ARGS((void *, char *, ...)), void *));
void ChapInit __P((int));
void ChapAuthWithPeer __P((int, char *, int));
void ChapAuthPeer __P((int, char *, int));
void ChapLowerUp __P((int));
void ChapLowerDown __P((int));
void ChapInput __P((int, u_char *, int));
void ChapProtocolReject __P((int));
int ChapPrintPkt __P((u_char *, int,
void (*) __P((void *, char *, ...)), void *));
#define __CHAP_INCLUDE__
#endif /* __CHAP_INCLUDE__ */

View file

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: fsm.c,v 1.2 1994/09/25 02:31:57 wollman Exp $";
static char rcsid[] = "$Id: fsm.c,v 1.8 1994/11/10 01:52:05 paulus Exp $";
#endif
/*
@ -28,27 +28,27 @@ static char rcsid[] = "$Id: fsm.c,v 1.2 1994/09/25 02:31:57 wollman Exp $";
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <syslog.h>
#include "ppp.h"
#include "pppd.h"
#include "fsm.h"
extern char *proto_name();
static void fsm_timeout __ARGS((caddr_t));
static void fsm_rconfreq __ARGS((fsm *, int, u_char *, int));
static void fsm_rconfack __ARGS((fsm *, int, u_char *, int));
static void fsm_rconfnakrej __ARGS((fsm *, int, int, u_char *, int));
static void fsm_rtermreq __ARGS((fsm *, int));
static void fsm_rtermack __ARGS((fsm *));
static void fsm_rcoderej __ARGS((fsm *, u_char *, int));
static void fsm_sconfreq __ARGS((fsm *, int));
static void fsm_timeout __P((caddr_t));
static void fsm_rconfreq __P((fsm *, int, u_char *, int));
static void fsm_rconfack __P((fsm *, int, u_char *, int));
static void fsm_rconfnakrej __P((fsm *, int, int, u_char *, int));
static void fsm_rtermreq __P((fsm *, int));
static void fsm_rtermack __P((fsm *));
static void fsm_rcoderej __P((fsm *, u_char *, int));
static void fsm_sconfreq __P((fsm *, int));
#define PROTO_NAME(f) ((f)->callbacks->proto_name)
int peer_mru[NPPP];
int peer_mru[NUM_PPP];
/*
@ -330,28 +330,28 @@ fsm_input(f, inpacket, l)
case CONFREQ:
fsm_rconfreq(f, id, inp, len);
break;
case CONFACK:
fsm_rconfack(f, id, inp, len);
break;
case CONFNAK:
case CONFREJ:
fsm_rconfnakrej(f, code, id, inp, len);
break;
case TERMREQ:
fsm_rtermreq(f, id);
break;
case TERMACK:
fsm_rtermack(f);
break;
case CODEREJ:
fsm_rcoderej(f, inp, len);
break;
default:
if( !f->callbacks->extcode
|| !(*f->callbacks->extcode)(f, code, id, inp, len) )
@ -446,15 +446,16 @@ fsm_rconfack(f, id, inp, len)
FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d.",
PROTO_NAME(f), id));
if (id != f->reqid) /* Expected id? */
return; /* Nope, toss... */
if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): (len == 0)) ){
if (id != f->reqid || f->seen_ack) /* Expected id? */
return; /* Nope, toss... */
if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
(len == 0)) ){
/* Ack is bad - ignore it */
FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)",
PROTO_NAME(f), len));
return;
}
f->reqid = -1;
f->seen_ack = 1;
switch (f->state) {
case CLOSED:
@ -468,7 +469,8 @@ fsm_rconfack(f, id, inp, len)
break;
case ACKRCVD:
/* Huh? an extra Ack? oh well... */
/* Huh? an extra valid Ack? oh well... */
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
fsm_sconfreq(f, 0);
f->state = REQSENT;
break;
@ -507,16 +509,16 @@ fsm_rconfnakrej(f, code, id, inp, len)
FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d.",
PROTO_NAME(f), id));
if (id != f->reqid) /* Expected id? */
return; /* Nope, toss... */
if (id != f->reqid || f->seen_ack) /* Expected id? */
return; /* Nope, toss... */
proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
if( !proc || !proc(f, inp, len) ){
if (!proc || !proc(f, inp, len)) {
/* Nak/reject is bad - ignore it */
FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)",
PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
return;
}
f->reqid = -1;
f->seen_ack = 1;
switch (f->state) {
case CLOSED:
@ -533,6 +535,7 @@ fsm_rconfnakrej(f, code, id, inp, len)
case ACKRCVD:
/* Got a Nak/reject when we had already had an Ack?? oh well... */
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
fsm_sconfreq(f, 0);
f->state = REQSENT;
break;
@ -590,11 +593,13 @@ fsm_rtermack(f)
switch (f->state) {
case CLOSING:
UNTIMEOUT(fsm_timeout, (caddr_t) f);
f->state = CLOSED;
if( f->callbacks->finished )
(*f->callbacks->finished)(f);
break;
case STOPPING:
UNTIMEOUT(fsm_timeout, (caddr_t) f);
f->state = STOPPED;
if( f->callbacks->finished )
(*f->callbacks->finished)(f);
@ -715,10 +720,12 @@ fsm_sconfreq(f, retransmit)
f->reqid = ++f->id;
}
f->seen_ack = 0;
/*
* Make up the request packet
*/
outp = outpacket_buf + DLLHEADERLEN + HEADERLEN;
outp = outpacket_buf + PPP_HDRLEN + HEADERLEN;
if( f->callbacks->cilen && f->callbacks->addci ){
cilen = (*f->callbacks->cilen)(f);
if( cilen > peer_mru[f->unit] - HEADERLEN )
@ -759,14 +766,14 @@ fsm_sdata(f, code, id, data, datalen)
outp = outpacket_buf;
if (datalen > peer_mru[f->unit] - HEADERLEN)
datalen = peer_mru[f->unit] - HEADERLEN;
if (datalen && data != outp + DLLHEADERLEN + HEADERLEN)
BCOPY(data, outp + DLLHEADERLEN + HEADERLEN, datalen);
if (datalen && data != outp + PPP_HDRLEN + HEADERLEN)
BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);
outlen = datalen + HEADERLEN;
MAKEHEADER(outp, f->protocol);
PUTCHAR(code, outp);
PUTCHAR(id, outp);
PUTSHORT(outlen, outp);
output(f->unit, outpacket_buf, outlen + DLLHEADERLEN);
output(f->unit, outpacket_buf, outlen + PPP_HDRLEN);
FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d, id %d.",
PROTO_NAME(f), code, id));

View file

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: fsm.h,v 1.2 1994/04/11 07:18:35 paulus Exp $
* $Id: fsm.h,v 1.5 1995/05/19 03:17:35 paulus Exp $
*/
/*
@ -66,6 +66,7 @@ typedef struct fsm {
int flags; /* Contains option bits */
u_char id; /* Current id */
u_char reqid; /* Current request id */
u_char seen_ack; /* Have received valid Ack/Nak/Rej to Req */
int timeouttime; /* Timeout time in milliseconds */
int maxconfreqtransmits; /* Maximum Configure-Request transmissions */
int retransmits; /* Number of retransmissions left */
@ -105,20 +106,20 @@ typedef struct fsm {
#define DEFTIMEOUT 3 /* Timeout time in seconds */
#define DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */
#define DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */
#define DEFMAXNAKLOOPS 10 /* Maximum number of nak loops */
#define DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */
/*
* Prototypes
*/
void fsm_init __ARGS((fsm *));
void fsm_lowerup __ARGS((fsm *));
void fsm_lowerdown __ARGS((fsm *));
void fsm_open __ARGS((fsm *));
void fsm_close __ARGS((fsm *));
void fsm_input __ARGS((fsm *, u_char *, int));
void fsm_protreject __ARGS((fsm *));
void fsm_sdata __ARGS((fsm *, int, int, u_char *, int));
void fsm_init __P((fsm *));
void fsm_lowerup __P((fsm *));
void fsm_lowerdown __P((fsm *));
void fsm_open __P((fsm *));
void fsm_close __P((fsm *));
void fsm_input __P((fsm *, u_char *, int));
void fsm_protreject __P((fsm *));
void fsm_sdata __P((fsm *, int, int, u_char *, int));
/*

View file

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: ipcp.c,v 1.2 1994/09/25 02:31:59 wollman Exp $";
static char rcsid[] = "$Id: ipcp.c,v 1.20 1995/08/10 06:51:04 paulus Exp $";
#endif
/*
@ -30,41 +30,37 @@ static char rcsid[] = "$Id: ipcp.c,v 1.2 1994/09/25 02:31:59 wollman Exp $";
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "pppd.h"
#include "ppp.h"
#include "fsm.h"
#include "ipcp.h"
#include "pathnames.h"
/* global vars */
ipcp_options ipcp_wantoptions[NPPP]; /* Options that we want to request */
ipcp_options ipcp_gotoptions[NPPP]; /* Options that peer ack'd */
ipcp_options ipcp_allowoptions[NPPP]; /* Options we allow peer to request */
ipcp_options ipcp_hisoptions[NPPP]; /* Options that we ack'd */
extern char ifname[];
extern char devname[];
extern int baud_rate;
ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */
ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
/* local vars */
static int cis_received[NPPP]; /* # Conf-Reqs received */
static int cis_received[NUM_PPP]; /* # Conf-Reqs received */
/*
* Callbacks for fsm code. (CI = Configuration Information)
*/
static void ipcp_resetci __ARGS((fsm *)); /* Reset our CI */
static int ipcp_cilen __ARGS((fsm *)); /* Return length of our CI */
static void ipcp_addci __ARGS((fsm *, u_char *, int *)); /* Add our CI */
static int ipcp_ackci __ARGS((fsm *, u_char *, int)); /* Peer ack'd our CI */
static int ipcp_nakci __ARGS((fsm *, u_char *, int)); /* Peer nak'd our CI */
static int ipcp_rejci __ARGS((fsm *, u_char *, int)); /* Peer rej'd our CI */
static int ipcp_reqci __ARGS((fsm *, u_char *, int *, int)); /* Rcv CI */
static void ipcp_up __ARGS((fsm *)); /* We're UP */
static void ipcp_down __ARGS((fsm *)); /* We're DOWN */
static void ipcp_script __ARGS((fsm *, char *)); /* Run an up/down script */
static void ipcp_resetci __P((fsm *)); /* Reset our CI */
static int ipcp_cilen __P((fsm *)); /* Return length of our CI */
static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
static int ipcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
static int ipcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */
static int ipcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
static int ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
static void ipcp_up __P((fsm *)); /* We're UP */
static void ipcp_down __P((fsm *)); /* We're DOWN */
static void ipcp_script __P((fsm *, char *)); /* Run an up/down script */
fsm ipcp_fsm[NPPP]; /* IPCP fsm structure */
fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */
static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
ipcp_resetci, /* Reset our Configuration Information */
@ -103,7 +99,7 @@ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
*/
char *
ip_ntoa(ipaddr)
u_long ipaddr;
u_int32_t ipaddr;
{
static char b[64];
@ -130,7 +126,7 @@ ipcp_init(unit)
ipcp_options *ao = &ipcp_allowoptions[unit];
f->unit = unit;
f->protocol = IPCP;
f->protocol = PPP_IPCP;
f->callbacks = &ipcp_callbacks;
fsm_init(&ipcp_fsm[unit]);
@ -296,7 +292,7 @@ ipcp_addci(f, ucp, lenp)
if (neg) { \
int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
if (len >= addrlen) { \
u_long l; \
u_int32_t l; \
PUTCHAR(opt, ucp); \
PUTCHAR(addrlen, ucp); \
l = ntohl(val1); \
@ -359,7 +355,7 @@ ipcp_ackci(f, p, len)
{
ipcp_options *go = &ipcp_gotoptions[f->unit];
u_short cilen, citype, cishort;
u_long cilong;
u_int32_t cilong;
u_char cimaxslotindex, cicflag;
/*
@ -394,7 +390,7 @@ ipcp_ackci(f, p, len)
#define ACKCIADDR(opt, neg, old, val1, val2) \
if (neg) { \
int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
u_long l; \
u_int32_t l; \
if ((len -= addrlen) < 0) \
goto bad; \
GETCHAR(citype, p); \
@ -451,7 +447,7 @@ ipcp_nakci(f, p, len)
u_char cimaxslotindex, cicflag;
u_char citype, cilen, *next;
u_short cishort;
u_long ciaddr1, ciaddr2, l;
u_int32_t ciaddr1, ciaddr2, l;
ipcp_options no; /* options we've seen Naks for */
ipcp_options try; /* options to request next time */
@ -498,7 +494,7 @@ ipcp_nakci(f, p, len)
* Accept the peer's idea of {our,his} address, if different
* from our idea, only if the accept_{local,remote} flag is set.
*/
NAKCIADDR(CI_ADDR, neg_addr, go->old_addrs,
NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,
if (go->accept_local && ciaddr1) { /* Do we know our address? */
try.ouraddr = ciaddr1;
IPCPDEBUG((LOG_INFO, "local IP address %s",
@ -579,16 +575,15 @@ ipcp_nakci(f, p, len)
case CI_ADDR:
if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR)
goto bad;
try.neg_addr = 1;
try.old_addrs = 0;
GETLONG(l, p);
ciaddr1 = htonl(l);
if (ciaddr1 && go->accept_local)
try.ouraddr = ciaddr1;
if (try.ouraddr != 0)
try.neg_addr = 1;
no.neg_addr = 1;
break;
default:
goto bad;
}
p = next;
}
@ -623,7 +618,7 @@ ipcp_rejci(f, p, len)
ipcp_options *go = &ipcp_gotoptions[f->unit];
u_char cimaxslotindex, ciflag, cilen;
u_short cishort;
u_long cilong;
u_int32_t cilong;
ipcp_options try; /* options to request next time */
try = *go;
@ -637,7 +632,7 @@ ipcp_rejci(f, p, len)
len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \
p[1] == cilen && \
p[0] == opt) { \
u_long l; \
u_int32_t l; \
len -= cilen; \
INCPTR(2, p); \
GETLONG(l, p); \
@ -722,7 +717,7 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
u_char *cip, *next; /* Pointer to current and next CIs */
u_short cilen, citype; /* Parsed len, type */
u_short cishort; /* Parsed short value */
u_long tl, ciaddr1, ciaddr2;/* Parsed address values */
u_int32_t tl, ciaddr1, ciaddr2;/* Parsed address values */
int rc = CONFACK; /* Final packet return code */
int orc; /* Individual option return code */
u_char *p; /* Pointer to next char to parse */
@ -734,7 +729,7 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
* Reset all his options.
*/
BZERO(ho, sizeof(*ho));
/*
* Process all his options.
*/
@ -778,10 +773,17 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
&& (ciaddr1 == 0 || !wo->accept_remote)) {
orc = CONFNAK;
if (!reject_if_disagree) {
DECPTR(sizeof (long), p);
DECPTR(sizeof(u_int32_t), p);
tl = ntohl(wo->hisaddr);
PUTLONG(tl, p);
}
} else if (ciaddr1 == 0 && wo->hisaddr == 0) {
/*
* If neither we nor he knows his address, reject the option.
*/
orc = CONFREJ;
wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
break;
}
/*
@ -795,7 +797,7 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
if (ciaddr2 == 0 || !wo->accept_local) {
orc = CONFNAK;
if (!reject_if_disagree) {
DECPTR(sizeof (long), p);
DECPTR(sizeof(u_int32_t), p);
tl = ntohl(wo->ouraddr);
PUTLONG(tl, p);
}
@ -832,16 +834,23 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
&& (ciaddr1 == 0 || !wo->accept_remote)) {
orc = CONFNAK;
if (!reject_if_disagree) {
DECPTR(sizeof (long), p);
DECPTR(sizeof(u_int32_t), p);
tl = ntohl(wo->hisaddr);
PUTLONG(tl, p);
}
} else if (ciaddr1 == 0 && wo->hisaddr == 0) {
/*
* Don't ACK an address of 0.0.0.0 - reject it instead.
*/
orc = CONFREJ;
wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
break;
}
ho->neg_addr = 1;
ho->hisaddr = ciaddr1;
break;
case CI_COMPRESSTYPE:
IPCPDEBUG((LOG_INFO, "ipcp: received COMPRESSTYPE "));
if (!ao->neg_vj ||
@ -862,7 +871,7 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
ho->vj_protocol = cishort;
if (cilen == CILEN_VJ) {
GETCHAR(maxslotindex, p);
if (maxslotindex > ao->maxslotindex) {
if (maxslotindex > ao->maxslotindex) {
orc = CONFNAK;
if (!reject_if_disagree){
DECPTR(1, p);
@ -878,7 +887,7 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
}
}
ho->maxslotindex = maxslotindex;
ho->cflag = wo->cflag;
ho->cflag = cflag;
} else {
ho->old_vj = 1;
ho->maxslotindex = MAX_STATES - 1;
@ -960,7 +969,7 @@ static void
ipcp_up(f)
fsm *f;
{
u_long mask;
u_int32_t mask;
ipcp_options *ho = &ipcp_hisoptions[f->unit];
ipcp_options *go = &ipcp_gotoptions[f->unit];
@ -1019,7 +1028,7 @@ ipcp_up(f)
}
/* assign a default route through the interface if required */
if (ipcp_wantoptions[f->unit].default_route)
if (ipcp_wantoptions[f->unit].default_route)
if (sifdefaultroute(f->unit, ho->hisaddr))
go->default_route = 1;
@ -1047,7 +1056,7 @@ static void
ipcp_down(f)
fsm *f;
{
u_long ouraddr, hisaddr;
u_int32_t ouraddr, hisaddr;
IPCPDEBUG((LOG_INFO, "ipcp: down"));
@ -1055,7 +1064,7 @@ ipcp_down(f)
hisaddr = ipcp_hisoptions[f->unit].hisaddr;
if (ipcp_gotoptions[f->unit].proxy_arp)
cifproxyarp(f->unit, hisaddr);
if (ipcp_gotoptions[f->unit].default_route)
if (ipcp_gotoptions[f->unit].default_route)
cifdefaultroute(f->unit, hisaddr);
sifdown(f->unit);
cifaddr(f->unit, ouraddr, hisaddr);
@ -1083,11 +1092,12 @@ ipcp_script(f, script)
argv[0] = script;
argv[1] = ifname;
argv[2] = devname;
argv[2] = devnam;
argv[3] = strspeed;
argv[4] = strlocal;
argv[5] = strremote;
argv[6] = NULL;
argv[6] = ipparam;
argv[7] = NULL;
run_program(script, argv, 0);
}
@ -1109,7 +1119,7 @@ ipcp_printpkt(p, plen, printer, arg)
int code, id, len, olen;
u_char *pstart, *optend;
u_short cishort;
u_long cilong;
u_int32_t cilong;
if (plen < HEADERLEN)
return 0;

View file

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ipcp.h,v 1.2 1994/09/25 02:32:00 wollman Exp $
* $Id: ipcp.h,v 1.5 1994/09/21 06:47:37 paulus Exp $
*/
/*
@ -35,7 +35,7 @@
#define IPCP_VJ_COMP 0x002d /* current value for VJ compression option*/
#define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */
/* compression option*/
/* compression option*/
typedef struct ipcp_options {
int neg_addr : 1; /* Negotiate IP Address? */
@ -49,7 +49,7 @@ typedef struct ipcp_options {
int accept_remote : 1; /* accept peer's value for hisaddr */
u_short vj_protocol; /* protocol value to use in VJ option */
u_char maxslotindex, cflag; /* values for RFC1332 VJ compression neg. */
u_long ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */
u_int32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */
} ipcp_options;
extern fsm ipcp_fsm[];
@ -58,11 +58,11 @@ extern ipcp_options ipcp_gotoptions[];
extern ipcp_options ipcp_allowoptions[];
extern ipcp_options ipcp_hisoptions[];
void ipcp_init __ARGS((int));
void ipcp_open __ARGS((int));
void ipcp_close __ARGS((int));
void ipcp_lowerup __ARGS((int));
void ipcp_lowerdown __ARGS((int));
void ipcp_input __ARGS((int, u_char *, int));
void ipcp_protrej __ARGS((int));
int ipcp_printpkt __ARGS((u_char *, int, void (*)(), void *));
void ipcp_init __P((int));
void ipcp_open __P((int));
void ipcp_close __P((int));
void ipcp_lowerup __P((int));
void ipcp_lowerdown __P((int));
void ipcp_input __P((int, u_char *, int));
void ipcp_protrej __P((int));
int ipcp_printpkt __P((u_char *, int, void (*)(), void *));

View file

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: lcp.c,v 1.2 1994/09/25 02:32:01 wollman Exp $";
static char rcsid[] = "$Id: lcp.c,v 1.21 1995/08/10 06:51:06 paulus Exp $";
#endif
/*
@ -36,7 +36,6 @@ static char rcsid[] = "$Id: lcp.c,v 1.2 1994/09/25 02:32:01 wollman Exp $";
#include <netinet/in.h>
#include "pppd.h"
#include "ppp.h"
#include "fsm.h"
#include "lcp.h"
#include "magic.h"
@ -45,51 +44,56 @@ static char rcsid[] = "$Id: lcp.c,v 1.2 1994/09/25 02:32:01 wollman Exp $";
#include "ipcp.h"
#ifdef _linux_ /* Needs ppp ioctls */
#include <linux/ppp.h>
#include <net/if.h>
#include <linux/if_ppp.h>
#endif
/* global vars */
fsm lcp_fsm[NPPP]; /* LCP fsm structure (global)*/
lcp_options lcp_wantoptions[NPPP]; /* Options that we want to request */
lcp_options lcp_gotoptions[NPPP]; /* Options that peer ack'd */
lcp_options lcp_allowoptions[NPPP]; /* Options we allow peer to request */
lcp_options lcp_hisoptions[NPPP]; /* Options that we ack'd */
u_long xmit_accm[NPPP][8]; /* extended transmit ACCM */
fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/
lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */
lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
u_int32_t xmit_accm[NUM_PPP][8]; /* extended transmit ACCM */
static u_long lcp_echos_pending = 0; /* Number of outstanding echo msgs */
static u_long lcp_echo_number = 0; /* ID number of next echo frame */
static u_long lcp_echo_timer_running = 0; /* TRUE if a timer is running */
static u_int32_t lcp_echos_pending = 0; /* Number of outstanding echo msgs */
static u_int32_t lcp_echo_number = 0; /* ID number of next echo frame */
static u_int32_t lcp_echo_timer_running = 0; /* TRUE if a timer is running */
u_long lcp_echo_interval = 0;
u_long lcp_echo_fails = 0;
static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */
#ifdef _linux_
u_int32_t idle_timer_running = 0;
extern int idle_time_limit;
#endif
/*
* Callbacks for fsm code. (CI = Configuration Information)
*/
static void lcp_resetci __ARGS((fsm *)); /* Reset our CI */
static int lcp_cilen __ARGS((fsm *)); /* Return length of our CI */
static void lcp_addci __ARGS((fsm *, u_char *, int *)); /* Add our CI to pkt */
static int lcp_ackci __ARGS((fsm *, u_char *, int)); /* Peer ack'd our CI */
static int lcp_nakci __ARGS((fsm *, u_char *, int)); /* Peer nak'd our CI */
static int lcp_rejci __ARGS((fsm *, u_char *, int)); /* Peer rej'd our CI */
static int lcp_reqci __ARGS((fsm *, u_char *, int *, int)); /* Rcv peer CI */
static void lcp_up __ARGS((fsm *)); /* We're UP */
static void lcp_down __ARGS((fsm *)); /* We're DOWN */
static void lcp_starting __ARGS((fsm *)); /* We need lower layer up */
static void lcp_finished __ARGS((fsm *)); /* We need lower layer down */
static int lcp_extcode __ARGS((fsm *, int, int, u_char *, int));
static void lcp_rprotrej __ARGS((fsm *, u_char *, int));
static void lcp_resetci __P((fsm *)); /* Reset our CI */
static int lcp_cilen __P((fsm *)); /* Return length of our CI */
static void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */
static int lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
static int lcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */
static int lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
static int lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */
static void lcp_up __P((fsm *)); /* We're UP */
static void lcp_down __P((fsm *)); /* We're DOWN */
static void lcp_starting __P((fsm *)); /* We need lower layer up */
static void lcp_finished __P((fsm *)); /* We need lower layer down */
static int lcp_extcode __P((fsm *, int, int, u_char *, int));
static void lcp_rprotrej __P((fsm *, u_char *, int));
/*
* routines to send LCP echos to peer
*/
static void lcp_echo_lowerup __ARGS((int));
static void lcp_echo_lowerdown __ARGS((int));
static void LcpEchoTimeout __ARGS((caddr_t));
static void lcp_received_echo_reply __ARGS((fsm *, int, u_char *, int));
static void LcpSendEchoRequest __ARGS((fsm *));
static void LcpLinkFailure __ARGS((fsm *));
static void lcp_echo_lowerup __P((int));
static void lcp_echo_lowerdown __P((int));
static void LcpEchoTimeout __P((caddr_t));
static void lcp_received_echo_reply __P((fsm *, int, u_char *, int));
static void LcpSendEchoRequest __P((fsm *));
static void LcpLinkFailure __P((fsm *));
static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
lcp_resetci, /* Reset our Configuration Information */
@ -109,7 +113,7 @@ static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
"LCP" /* String name of protocol */
};
int lcp_warnloops = DEFWARNLOOPS; /* Warn about a loopback this often */
int lcp_loopbackfail = DEFLOOPBACKFAIL;
/*
* Length of each type of configuration option (in octets)
@ -136,7 +140,7 @@ lcp_init(unit)
lcp_options *ao = &lcp_allowoptions[unit];
f->unit = unit;
f->protocol = LCP;
f->protocol = PPP_LCP;
f->callbacks = &lcp_callbacks;
fsm_init(f);
@ -216,6 +220,58 @@ lcp_close(unit)
fsm_close(&lcp_fsm[unit]);
}
#ifdef _linux_
static void IdleTimeCheck __P((caddr_t));
/*
* Timer expired for the LCP echo requests from this process.
*/
static void
RestartIdleTimer (f)
fsm *f;
{
u_long delta;
struct ppp_idle ddinfo;
/*
* Read the time since the last packet was received.
*/
if (ioctl (fd, PPPIOCGIDLE, &ddinfo) < 0) {
syslog (LOG_ERR, "ioctl(PPPIOCGIDLE): %m");
die (1);
}
/*
* Compute the time since the last packet was received. If the timer
* has expired then disconnect the line.
*/
delta = idle_time_limit - (u_long) ddinfo.recv_idle;
if (((int) delta <= 0L) && (f->state == OPENED)) {
syslog (LOG_NOTICE, "No IP frames received within idle time limit");
lcp_close(f->unit); /* Reset connection */
phase = PHASE_TERMINATE; /* Mark it down */
} else {
if ((int) delta <= 0L)
delta = (u_long) idle_time_limit;
assert (idle_timer_running==0);
TIMEOUT (IdleTimeCheck, (caddr_t) f, delta);
idle_timer_running = 1;
}
}
/*
* IdleTimeCheck - Timer expired on the IDLE detection for IP frames
*/
static void
IdleTimeCheck (arg)
caddr_t arg;
{
if (idle_timer_running != 0) {
idle_timer_running = 0;
RestartIdleTimer ((fsm *) arg);
}
}
#endif
/*
* lcp_lowerup - The lower layer is up.
@ -226,9 +282,9 @@ lcp_lowerup(unit)
{
sifdown(unit);
ppp_set_xaccm(unit, xmit_accm[unit]);
ppp_send_config(unit, MTU, 0xffffffff, 0, 0);
ppp_recv_config(unit, MTU, 0x00000000, 0, 0);
peer_mru[unit] = MTU;
ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0);
ppp_recv_config(unit, PPP_MRU, 0x00000000, 0, 0);
peer_mru[unit] = PPP_MRU;
lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0];
fsm_lowerup(&lcp_fsm[unit]);
@ -255,7 +311,23 @@ lcp_input(unit, p, len)
u_char *p;
int len;
{
fsm_input(&lcp_fsm[unit], p, len);
int oldstate;
fsm *f = &lcp_fsm[unit];
lcp_options *go = &lcp_gotoptions[f->unit];
oldstate = f->state;
fsm_input(f, p, len);
if (oldstate == REQSENT && f->state == ACKSENT) {
/*
* The peer will probably send us an ack soon and then
* immediately start sending packets with the negotiated
* options. So as to be ready when that happens, we set
* our receive side to accept packets as negotiated now.
*/
ppp_recv_config(f->unit, PPP_MRU,
go->neg_asyncmap? go->asyncmap: 0x00000000,
go->neg_pcompression, go->neg_accompression);
}
}
@ -275,18 +347,16 @@ lcp_extcode(f, code, id, inp, len)
case PROTREJ:
lcp_rprotrej(f, inp, len);
break;
case ECHOREQ:
if (f->state != OPENED)
break;
LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d", id));
magp = inp;
PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
if (len < CILEN_LONG)
len = CILEN_LONG;
fsm_sdata(f, ECHOREP, id, inp, len);
break;
case ECHOREP:
lcp_received_echo_reply(f, id, inp, len);
break;
@ -300,7 +370,7 @@ lcp_extcode(f, code, id, inp, len)
return 1;
}
/*
* lcp_rprotrej - Receive an Protocol-Reject.
*
@ -390,7 +460,7 @@ fsm *f;
lcp_wantoptions[f->unit].magicnumber = magic();
lcp_wantoptions[f->unit].numloops = 0;
lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];
peer_mru[f->unit] = MTU;
peer_mru[f->unit] = PPP_MRU;
}
@ -463,14 +533,14 @@ lcp_addci(f, ucp, lenp)
if (neg) { \
PUTCHAR(opt, ucp); \
PUTCHAR(CILEN_LQR, ucp); \
PUTSHORT(LQR, ucp); \
PUTSHORT(PPP_LQR, ucp); \
PUTLONG(val, ucp); \
}
ADDCISHORT(CI_MRU, go->neg_mru, go->mru);
ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap, go->asyncmap);
ADDCICHAP(CI_AUTHTYPE, go->neg_chap, CHAP, go->chap_mdtype);
ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, UPAP);
ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
@ -500,7 +570,7 @@ lcp_ackci(f, p, len)
lcp_options *go = &lcp_gotoptions[f->unit];
u_char cilen, citype, cichar;
u_short cishort;
u_long cilong;
u_int32_t cilong;
/*
* CIs must be in exactly the same order that we sent.
@ -569,7 +639,7 @@ lcp_ackci(f, p, len)
citype != opt) \
goto bad; \
GETSHORT(cishort, p); \
if (cishort != LQR) \
if (cishort != PPP_LQR) \
goto bad; \
GETLONG(cilong, p); \
if (cilong != val) \
@ -578,8 +648,8 @@ lcp_ackci(f, p, len)
ACKCISHORT(CI_MRU, go->neg_mru, go->mru);
ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap, go->asyncmap);
ACKCICHAP(CI_AUTHTYPE, go->neg_chap, CHAP, go->chap_mdtype);
ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, UPAP);
ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
@ -614,12 +684,13 @@ lcp_nakci(f, p, len)
{
lcp_options *go = &lcp_gotoptions[f->unit];
lcp_options *wo = &lcp_wantoptions[f->unit];
u_char cilen, citype, cichar, *next;
u_char citype, cichar, *next;
u_short cishort;
u_long cilong;
u_int32_t cilong;
lcp_options no; /* options we've seen Naks for */
lcp_options try; /* options to request next time */
int looped_back = 0;
int cilen;
BZERO(&no, sizeof(no));
try = *go;
@ -697,21 +768,67 @@ lcp_nakci(f, p, len)
if (cishort <= wo->mru || cishort < DEFMRU)
try.mru = cishort;
);
/*
* Add any characters they want to our (receive-side) asyncmap.
*/
NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
try.asyncmap = go->asyncmap | cilong;
);
/*
* If they can't cope with our CHAP hash algorithm, we'll have
* to stop asking for CHAP. We haven't got any other algorithm.
* If they've nak'd our authentication-protocol, check whether
* they are proposing a different protocol, or a different
* hash algorithm for CHAP.
*/
NAKCICHAP(CI_AUTHTYPE, neg_chap,
try.neg_chap = 0;
);
if ((go->neg_chap || go->neg_upap)
&& len >= CILEN_SHORT
&& p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT) {
cilen = p[1];
INCPTR(2, p);
GETSHORT(cishort, p);
if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
/*
* If they are asking for PAP, then they don't want to do CHAP.
* If we weren't asking for CHAP, then we were asking for PAP,
* in which case this Nak is bad.
*/
if (!go->neg_chap)
goto bad;
go->neg_chap = 0;
} else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
GETCHAR(cichar, p);
if (go->neg_chap) {
/*
* We were asking for CHAP/MD5; they must want a different
* algorithm. If they can't do MD5, we'll have to stop
* asking for CHAP.
*/
if (cichar != go->chap_mdtype)
go->neg_chap = 0;
} else {
/*
* Stop asking for PAP if we were asking for it.
*/
go->neg_upap = 0;
}
} else {
/*
* We don't recognize what they're suggesting.
* Stop asking for what we were asking for.
*/
if (go->neg_chap)
go->neg_chap = 0;
else
go->neg_upap = 0;
p += cilen - CILEN_SHORT;
}
}
/*
* Peer shouldn't send Nak for UPAP, protocol compression or
* Peer shouldn't send Nak for protocol compression or
* address/control compression requests; they should send
* a Reject instead. If they send a Nak, treat it as a Reject.
*/
@ -720,23 +837,24 @@ lcp_nakci(f, p, len)
try.neg_upap = 0;
);
}
/*
* If they can't cope with our link quality protocol, we'll have
* to stop asking for LQR. We haven't got any other protocol.
* If they Nak the reporting period, take their value XXX ?
*/
NAKCILQR(CI_QUALITY, neg_lqr,
if (cishort != LQR)
if (cishort != PPP_LQR)
try.neg_lqr = 0;
else
try.lqr_period = cilong;
);
/*
* Check for a looped-back line.
*/
NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
try.magicnumber = magic();
++try.numloops;
looped_back = 1;
);
@ -760,11 +878,13 @@ lcp_nakci(f, p, len)
* `let me authenticate myself with you' which is a bit pointless.
* For the quality protocol, the Nak means `ask me to send you quality
* reports', but if we didn't ask for them, we don't want them.
* An option we don't recognize represents the peer asking to
* negotiate some option we don't support, so ignore it.
*/
while (len > CILEN_VOID) {
GETCHAR(citype, p);
GETCHAR(cilen, p);
if( (len -= cilen) < 0 )
if ((len -= cilen) < 0)
goto bad;
next = p + cilen - 2;
@ -800,8 +920,6 @@ lcp_nakci(f, p, len)
if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
goto bad;
break;
default:
goto bad;
}
p = next;
}
@ -814,9 +932,14 @@ lcp_nakci(f, p, len)
* OK, the Nak is good. Now we can update state.
*/
if (f->state != OPENED) {
if (looped_back) {
if (++try.numloops >= lcp_loopbackfail) {
syslog(LOG_NOTICE, "Serial line is looped back.");
lcp_close(f->unit);
}
} else
try.numloops = 0;
*go = try;
if (looped_back && try.numloops % lcp_warnloops == 0)
LCPDEBUG((LOG_INFO, "The line appears to be looped back."));
}
return 1;
@ -845,7 +968,7 @@ lcp_rejci(f, p, len)
lcp_options *go = &lcp_gotoptions[f->unit];
u_char cichar;
u_short cishort;
u_long cilong;
u_int32_t cilong;
u_char *start = p;
int plen = len;
lcp_options try; /* options to request next time */
@ -894,6 +1017,7 @@ lcp_rejci(f, p, len)
if (cishort != val || cichar != digest) \
goto bad; \
try.neg = 0; \
try.neg_upap = 0; \
LCPDEBUG((LOG_INFO,"lcp_rejci rejected chap opt %d", opt)); \
}
#define REJCILONG(opt, neg, val) \
@ -920,7 +1044,7 @@ lcp_rejci(f, p, len)
GETSHORT(cishort, p); \
GETLONG(cilong, p); \
/* Check rejected value. */ \
if (cishort != LQR || cilong != val) \
if (cishort != PPP_LQR || cilong != val) \
goto bad; \
try.neg = 0; \
LCPDEBUG((LOG_INFO,"lcp_rejci rejected LQR opt %d", opt)); \
@ -928,9 +1052,9 @@ lcp_rejci(f, p, len)
REJCISHORT(CI_MRU, neg_mru, go->mru);
REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
REJCICHAP(CI_AUTHTYPE, neg_chap, CHAP, go->chap_mdtype);
REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype);
if (!go->neg_chap) {
REJCISHORT(CI_AUTHTYPE, neg_upap, UPAP);
REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
}
REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
@ -977,11 +1101,12 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
u_char *cip, *next; /* Pointer to current and next CIs */
u_char cilen, citype, cichar;/* Parsed len, type, char value */
u_short cishort; /* Parsed short value */
u_long cilong; /* Parse long value */
u_int32_t cilong; /* Parse long value */
int rc = CONFACK; /* Final packet return code */
int orc; /* Individual option return code */
u_char *p; /* Pointer to next char to parse */
u_char *ucp = inp; /* Pointer to current output char */
u_char *rejp; /* Pointer to next char in reject frame */
u_char *nakp; /* Pointer to next char in Nak frame */
int l = *lenp; /* Length left */
/*
@ -993,6 +1118,8 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
* Process all his options.
*/
next = inp;
nakp = nak_buffer;
rejp = inp;
while (l) {
orc = CONFACK; /* Assume success */
cip = p = next; /* Remember begining of CI */
@ -1028,10 +1155,9 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
*/
if (cishort < MINMRU) {
orc = CONFNAK; /* Nak CI */
if( !reject_if_disagree ){
DECPTR(sizeof (short), p); /* Backup */
PUTSHORT(MINMRU, p); /* Give him a hint */
}
PUTCHAR(CI_MRU, nakp);
PUTCHAR(CILEN_SHORT, nakp);
PUTSHORT(MINMRU, nakp); /* Give him a hint */
break;
}
ho->neg_mru = 1; /* Remember he sent MRU */
@ -1046,7 +1172,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
break;
}
GETLONG(cilong, p);
LCPDEBUG((LOG_INFO, "(%lx)", cilong));
LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong));
/*
* Asyncmap must have set at least the bits
@ -1054,10 +1180,9 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
*/
if ((ao->asyncmap & ~cilong) != 0) {
orc = CONFNAK;
if( !reject_if_disagree ){
DECPTR(sizeof (long), p);
PUTLONG(ao->asyncmap | cilong, p);
}
PUTCHAR(CI_ASYNCMAP, nakp);
PUTCHAR(CILEN_LONG, nakp);
PUTLONG(ao->asyncmap | cilong, nakp);
break;
}
ho->neg_asyncmap = 1;
@ -1068,6 +1193,9 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd AUTHTYPE"));
if (cilen < CILEN_SHORT ||
!(ao->neg_upap || ao->neg_chap)) {
/*
* Reject the option if we're not willing to authenticate.
*/
orc = CONFREJ;
break;
}
@ -1085,34 +1213,47 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
* the ordering of the CIs in the peer's Configure-Request.
*/
if (cishort == UPAP) {
if (!ao->neg_upap || /* we don't want to do PAP */
ho->neg_chap || /* or we've already accepted CHAP */
if (cishort == PPP_PAP) {
if (ho->neg_chap || /* we've already accepted CHAP */
cilen != CILEN_SHORT) {
LCPDEBUG((LOG_WARNING,
"lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
orc = CONFREJ;
break;
}
if (!ao->neg_upap) { /* we don't want to do PAP */
orc = CONFNAK; /* NAK it and suggest CHAP */
PUTCHAR(CI_AUTHTYPE, nakp);
PUTCHAR(CILEN_CHAP, nakp);
PUTSHORT(PPP_CHAP, nakp);
PUTCHAR(ao->chap_mdtype, nakp);
break;
}
ho->neg_upap = 1;
break;
}
if (cishort == CHAP) {
if (!ao->neg_chap || /* we don't want to do CHAP */
ho->neg_upap || /* or we've already accepted UPAP */
if (cishort == PPP_CHAP) {
if (ho->neg_upap || /* we've already accepted PAP */
cilen != CILEN_CHAP) {
LCPDEBUG((LOG_INFO,
"lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
orc = CONFREJ;
break;
}
if (!ao->neg_chap) { /* we don't want to do CHAP */
orc = CONFNAK; /* NAK it and suggest PAP */
PUTCHAR(CI_AUTHTYPE, nakp);
PUTCHAR(CILEN_SHORT, nakp);
PUTSHORT(PPP_PAP, nakp);
break;
}
GETCHAR(cichar, p); /* get digest type*/
if (cichar != ao->chap_mdtype) {
orc = CONFNAK;
if( !reject_if_disagree ){
DECPTR(sizeof (u_char), p);
PUTCHAR(ao->chap_mdtype, p);
}
PUTCHAR(CI_AUTHTYPE, nakp);
PUTCHAR(CILEN_CHAP, nakp);
PUTSHORT(PPP_CHAP, nakp);
PUTCHAR(ao->chap_mdtype, nakp);
break;
}
ho->chap_mdtype = cichar; /* save md type */
@ -1122,9 +1263,19 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
/*
* We don't recognize the protocol they're asking for.
* Reject it.
* Nak it with something we're willing to do.
* (At this point we know ao->neg_upap || ao->neg_chap.)
*/
orc = CONFREJ;
orc = CONFNAK;
PUTCHAR(CI_AUTHTYPE, nakp);
if (ao->neg_chap) {
PUTCHAR(CILEN_CHAP, nakp);
PUTSHORT(PPP_CHAP, nakp);
PUTCHAR(ao->chap_mdtype, nakp);
} else {
PUTCHAR(CILEN_SHORT, nakp);
PUTSHORT(PPP_PAP, nakp);
}
break;
case CI_QUALITY:
@ -1137,16 +1288,20 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
GETSHORT(cishort, p);
GETLONG(cilong, p);
LCPDEBUG((LOG_INFO, "(%x %lx)", cishort, cilong));
if (cishort != LQR) {
orc = CONFREJ;
break;
}
LCPDEBUG((LOG_INFO, "(%x %x)", cishort, (unsigned int) cilong));
/*
* Check the reporting period.
* Check the protocol and the reporting period.
* XXX When should we Nak this, and what with?
*/
if (cishort != PPP_LQR) {
orc = CONFNAK;
PUTCHAR(CI_QUALITY, nakp);
PUTCHAR(CILEN_LQR, nakp);
PUTSHORT(PPP_LQR, nakp);
PUTLONG(ao->lqr_period, nakp);
break;
}
break;
case CI_MAGICNUMBER:
@ -1157,17 +1312,18 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
break;
}
GETLONG(cilong, p);
LCPDEBUG((LOG_INFO, "(%lx)", cilong));
LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong));
/*
* He must have a different magic number.
*/
if (go->neg_magicnumber &&
cilong == go->magicnumber) {
orc = CONFNAK;
DECPTR(sizeof (long), p);
cilong = magic(); /* Don't put magic() inside macro! */
PUTLONG(cilong, p);
orc = CONFNAK;
PUTCHAR(CI_MAGICNUMBER, nakp);
PUTCHAR(CILEN_LONG, nakp);
PUTLONG(cilong, nakp);
break;
}
ho->neg_magicnumber = 1;
@ -1209,35 +1365,46 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
continue; /* Don't send this one */
if (orc == CONFNAK) { /* Nak this CI? */
if (reject_if_disagree) /* Getting fed up with sending NAKs? */
if (reject_if_disagree /* Getting fed up with sending NAKs? */
&& citype != CI_MAGICNUMBER) {
orc = CONFREJ; /* Get tough if so */
else {
} else {
if (rc == CONFREJ) /* Rejecting prior CI? */
continue; /* Don't send this one */
if (rc == CONFACK) { /* Ack'd all prior CIs? */
rc = CONFNAK; /* Not anymore... */
ucp = inp; /* Backup */
}
rc = CONFNAK;
}
}
if (orc == CONFREJ && /* Reject this CI */
rc != CONFREJ) { /* but no prior ones? */
if (orc == CONFREJ) { /* Reject this CI */
rc = CONFREJ;
ucp = inp; /* Backup */
if (cip != rejp) /* Need to move rejected CI? */
BCOPY(cip, rejp, cilen); /* Move it */
INCPTR(cilen, rejp); /* Update output pointer */
}
if (ucp != cip) /* Need to move CI? */
BCOPY(cip, ucp, cilen); /* Move it */
INCPTR(cilen, ucp); /* Update output pointer */
}
/*
* If we wanted to send additional NAKs (for unsent CIs), the
* code would go here. This must be done with care since it might
* require a longer packet than we received. At present there
* are no cases where we want to ask the peer to negotiate an option.
* code would go here. The extra NAKs would go at *nakp.
* At present there are no cases where we want to ask the
* peer to negotiate an option.
*/
*lenp = ucp - inp; /* Compute output length */
switch (rc) {
case CONFACK:
*lenp = next - inp;
break;
case CONFNAK:
/*
* Copy the Nak'd options from the nak_buffer to the caller's buffer.
*/
*lenp = nakp - nak_buffer;
BCOPY(nak_buffer, inp, *lenp);
break;
case CONFREJ:
*lenp = rejp - inp;
break;
}
LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.", CODENAME(rc)));
return (rc); /* Return final code */
}
@ -1268,7 +1435,7 @@ lcp_up(f)
* set our MRU to the larger of value we wanted and
* the value we got in the negotiation.
*/
ppp_send_config(f->unit, MIN(ao->mru, (ho->neg_mru? ho->mru: MTU)),
ppp_send_config(f->unit, MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),
(ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
ho->neg_pcompression, ho->neg_accompression);
/*
@ -1276,7 +1443,7 @@ lcp_up(f)
* set the receive asyncmap to ffffffff, but we set it to 0
* for backwards contemptibility.
*/
ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): MTU),
ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU),
(go->neg_asyncmap? go->asyncmap: 0x00000000),
go->neg_pcompression, go->neg_accompression);
@ -1286,6 +1453,7 @@ lcp_up(f)
ChapLowerUp(f->unit); /* Enable CHAP */
upap_lowerup(f->unit); /* Enable UPAP */
ipcp_lowerup(f->unit); /* Enable IPCP */
ccp_lowerup(f->unit); /* Enable CCP */
lcp_echo_lowerup(f->unit); /* Enable echo messages */
link_established(f->unit);
@ -1302,14 +1470,15 @@ lcp_down(f)
fsm *f;
{
lcp_echo_lowerdown(f->unit);
ccp_lowerdown(f->unit);
ipcp_lowerdown(f->unit);
ChapLowerDown(f->unit);
upap_lowerdown(f->unit);
sifdown(f->unit);
ppp_send_config(f->unit, MTU, 0xffffffff, 0, 0);
ppp_recv_config(f->unit, MTU, 0x00000000, 0, 0);
peer_mru[f->unit] = MTU;
ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0);
ppp_recv_config(f->unit, PPP_MRU, 0x00000000, 0, 0);
peer_mru[f->unit] = PPP_MRU;
link_down(f->unit);
}
@ -1350,13 +1519,13 @@ int
lcp_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __ARGS((void *, char *, ...));
void (*printer) __P((void *, char *, ...));
void *arg;
{
int code, id, len, olen;
u_char *pstart, *optend;
u_short cishort;
u_long cilong;
u_int32_t cilong;
if (plen < HEADERLEN)
return 0;
@ -1410,10 +1579,10 @@ lcp_printpkt(p, plen, printer, arg)
printer(arg, "auth ");
GETSHORT(cishort, p);
switch (cishort) {
case UPAP:
case PPP_PAP:
printer(arg, "upap");
break;
case CHAP:
case PPP_CHAP:
printer(arg, "chap");
break;
default:
@ -1427,7 +1596,7 @@ lcp_printpkt(p, plen, printer, arg)
printer(arg, "quality ");
GETSHORT(cishort, p);
switch (cishort) {
case LQR:
case PPP_LQR:
printer(arg, "lqr");
break;
default:
@ -1483,7 +1652,7 @@ void LcpLinkFailure (f)
{
if (f->state == OPENED) {
syslog (LOG_NOTICE, "Excessive lack of response to LCP echo frames.");
lcp_lowerdown(f->unit); /* Reset connection */
lcp_close(f->unit); /* Reset connection */
}
}
@ -1495,43 +1664,36 @@ static void
LcpEchoCheck (f)
fsm *f;
{
u_long delta;
long int delta;
#ifdef __linux__
struct ppp_ddinfo ddinfo;
u_long latest;
struct ppp_idle ddinfo;
/*
* Read the time since the last packet was received.
*/
if (ioctl (fd, PPPIOCGTIME, &ddinfo) < 0) {
syslog (LOG_ERR, "ioctl(PPPIOCGTIME): %m");
if (ioctl (fd, PPPIOCGIDLE, &ddinfo) < 0) {
syslog (LOG_ERR, "ioctl(PPPIOCGIDLE): %m");
die (1);
}
/*
* Choose the most recient frame received. It may be an IP or NON-IP frame.
*/
latest = ddinfo.nip_rjiffies < ddinfo.ip_rjiffies ? ddinfo.nip_rjiffies
: ddinfo.ip_rjiffies;
/*
* Compute the time since the last packet was received. If the timer
* has expired then send the echo request and reset the timer to maximum.
*/
delta = (lcp_echo_interval * HZ) - latest;
if (delta < HZ || latest < 0L) {
delta = (long int) lcp_echo_interval - (long int) ddinfo.recv_idle;
if (delta < 0L) {
LcpSendEchoRequest (f);
delta = lcp_echo_interval * HZ;
delta = (int) lcp_echo_interval;
}
delta /= HZ;
#else /* Other implementations do not have ability to find delta */
LcpSendEchoRequest (f);
delta = lcp_echo_interval;
delta = (int) lcp_echo_interval;
#endif
/*
* Start the timer for the next interval.
*/
assert (lcp_echo_timer_running==0);
TIMEOUT (LcpEchoTimeout, (caddr_t) f, delta);
TIMEOUT (LcpEchoTimeout, (caddr_t) f, (u_int32_t) delta);
lcp_echo_timer_running = 1;
}
@ -1558,15 +1720,19 @@ lcp_received_echo_reply (f, id, inp, len)
fsm *f;
int id; u_char *inp; int len;
{
u_long magic;
u_int32_t magic;
/* Check the magic number - don't count replies from ourselves. */
if (len < CILEN_LONG)
if (len < 4) {
syslog(LOG_DEBUG, "lcp: received short Echo-Reply, length %d", len);
return;
}
GETLONG(magic, inp);
if (lcp_gotoptions[f->unit].neg_magicnumber
&& magic == lcp_gotoptions[f->unit].magicnumber)
&& magic == lcp_gotoptions[f->unit].magicnumber) {
syslog(LOG_WARNING, "appear to have received our own echo-reply!");
return;
}
/* Reset the number of outstanding echo frames */
lcp_echos_pending = 0;
@ -1580,7 +1746,7 @@ static void
LcpSendEchoRequest (f)
fsm *f;
{
u_long lcp_magic;
u_int32_t lcp_magic;
u_char pkt[4], *pktp;
/*
@ -1601,7 +1767,7 @@ LcpSendEchoRequest (f)
: 0L;
pktp = pkt;
PUTLONG(lcp_magic, pktp);
fsm_sdata(f, ECHOREQ,
lcp_echo_number++ & 0xFF, pkt, pktp - pkt);
}
@ -1621,10 +1787,15 @@ lcp_echo_lowerup (unit)
lcp_echos_pending = 0;
lcp_echo_number = 0;
lcp_echo_timer_running = 0;
/* If a timeout interval is specified then start the timer */
if (lcp_echo_interval != 0)
LcpEchoCheck (f);
#ifdef _linux_
/* If a idle time limit is given then start it */
if (idle_time_limit != 0)
RestartIdleTimer (f);
#endif
}
/*
@ -1641,4 +1812,11 @@ lcp_echo_lowerdown (unit)
UNTIMEOUT (LcpEchoTimeout, (caddr_t) f);
lcp_echo_timer_running = 0;
}
#ifdef _linux_
/* If a idle time limit is running then stop it */
if (idle_timer_running != 0) {
UNTIMEOUT (IdleTimeCheck, (caddr_t) f);
idle_timer_running = 0;
}
#endif
}

View file

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: lcp.h,v 1.4 1994/05/24 11:22:28 paulus Exp $
* $Id: lcp.h,v 1.8 1995/06/12 11:22:47 paulus Exp $
*/
/*
@ -55,10 +55,10 @@ typedef struct lcp_options {
int neg_lqr : 1; /* Negotiate use of Link Quality Reports */
u_short mru; /* Value of MRU */
u_char chap_mdtype; /* which MD type (hashing algorithm) */
u_long asyncmap; /* Value of async map */
u_long magicnumber;
u_int32_t asyncmap; /* Value of async map */
u_int32_t magicnumber;
int numloops; /* Number of loops during magic number neg. */
u_long lqr_period; /* Reporting period for link quality */
u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */
} lcp_options;
extern fsm lcp_fsm[];
@ -66,22 +66,23 @@ extern lcp_options lcp_wantoptions[];
extern lcp_options lcp_gotoptions[];
extern lcp_options lcp_allowoptions[];
extern lcp_options lcp_hisoptions[];
extern u_long xmit_accm[][8];
extern u_int32_t xmit_accm[][8];
#define DEFMRU 1500 /* Try for this */
#define MINMRU 128 /* No MRUs below this */
#define MAXMRU 16384 /* Normally limit MRU to this */
void lcp_init __ARGS((int));
void lcp_open __ARGS((int));
void lcp_close __ARGS((int));
void lcp_lowerup __ARGS((int));
void lcp_lowerdown __ARGS((int));
void lcp_input __ARGS((int, u_char *, int));
void lcp_protrej __ARGS((int));
void lcp_sprotrej __ARGS((int, u_char *, int));
int lcp_printpkt __ARGS((u_char *, int,
void (*) __ARGS((void *, char *, ...)), void *));
void lcp_init __P((int));
void lcp_open __P((int));
void lcp_close __P((int));
void lcp_lowerup __P((int));
void lcp_lowerdown __P((int));
void lcp_input __P((int, u_char *, int));
void lcp_protrej __P((int));
void lcp_sprotrej __P((int, u_char *, int));
int lcp_printpkt __P((u_char *, int,
void (*) __P((void *, char *, ...)), void *));
extern int lcp_warnloops; /* Warn about a loopback this often */
#define DEFWARNLOOPS 10 /* Default value for above */
/* Default number of times we receive our magic number from the peer
before deciding the link is looped-back. */
#define DEFLOOPBACKFAIL 5

View file

@ -18,53 +18,73 @@
*/
#ifndef lint
static char rcsid[] = "$Id: magic.c,v 1.1 1993/11/11 03:54:25 paulus Exp $";
static char rcsid[] = "$Id: magic.c,v 1.5 1995/06/06 01:52:25 paulus Exp $";
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include "pppd.h"
#include "magic.h"
static u_int32_t next; /* Next value to return */
static u_long next; /* Next value to return */
extern u_long gethostid __ARGS((void));
extern long random __ARGS((void));
extern void srandom __ARGS((int));
extern int gethostid __P((void));
extern long mrand48 __P((void));
extern void srand48 __P((long));
/*
* magic_init - Initialize the magic number generator.
*
* Computes first magic number and seed for random number generator.
* Attempts to compute a random number seed which will not repeat.
* The current method uses the current hostid and current time.
* The current method uses the current hostid, current process ID
* and current time, currently.
*/
void magic_init()
void
magic_init()
{
struct timeval tv;
long seed;
struct timeval t;
next = gethostid();
if (gettimeofday(&tv, NULL)) {
perror("gettimeofday");
exit(1);
}
next ^= (u_long) tv.tv_sec ^ (u_long) tv.tv_usec;
srandom((int) next);
gettimeofday(&t, NULL);
seed = gethostid() ^ t.tv_sec ^ t.tv_usec ^ getpid();
srand48(seed);
}
/*
* magic - Returns the next magic number.
*/
u_long magic()
u_int32_t
magic()
{
u_long m;
m = next;
next = (u_long) random();
return (m);
return (u_int32_t) mrand48();
}
#ifdef NO_DRAND48
/*
* Substitute procedures for those systems which don't have
* drand48 et al.
*/
double
drand48()
{
return (double)random() / (double)0x7fffffffL; /* 2**31-1 */
}
long
mrand48()
{
return random();
}
void
srand48(seedval)
long seedval;
{
srandom((int)seedval);
}
#endif

View file

@ -16,9 +16,8 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: magic.h,v 1.1 1993/11/11 03:54:25 paulus Exp $
* $Id: magic.h,v 1.3 1994/09/21 06:47:37 paulus Exp $
*/
#include "args.h"
void magic_init __ARGS((void)); /* Initialize the magic number generator */
u_long magic __ARGS((void)); /* Returns the next magic number */
void magic_init __P((void)); /* Initialize the magic number generator */
u_int32_t magic __P((void)); /* Returns the next magic number */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
/* $Id: patchlevel.h,v 1.10 1994/06/09 01:51:10 paulus Exp $ */
#define PATCHLEVEL 2
/* $Id: patchlevel.h,v 1.16 1995/07/11 06:41:07 paulus Exp $ */
#define PATCHLEVEL 0
#define VERSION "2.1"
#define DATE "9 June 94"
#define VERSION "2.2"
#define IMPLEMENTATION "beta3"
#define DATE "11 July 95"

View file

@ -1,13 +1,15 @@
/*
* define path names
*
* $Id: pathnames.h,v 1.4 1994/05/18 06:34:46 paulus Exp $
* $Id: pathnames.h,v 1.6 1995/06/12 11:22:53 paulus Exp $
*/
#if defined(STREAMS) || defined(ultrix)
#define _PATH_PIDFILE "/etc/ppp"
#ifdef HAVE_PATHS_H
#include <paths.h>
#else
#define _PATH_PIDFILE "/var/run"
#define _PATH_VARRUN "/etc/ppp/"
#define _PATH_DEVNULL "/dev/null"
#endif
#define _PATH_UPAPFILE "/etc/ppp/pap-secrets"
@ -16,4 +18,5 @@
#define _PATH_IPUP "/etc/ppp/ip-up"
#define _PATH_IPDOWN "/etc/ppp/ip-down"
#define _PATH_TTYOPT "/etc/ppp/options."
#define _PATH_CONNERRS "/etc/ppp/connect-errors"
#define _PATH_USEROPT ".ppprc"

View file

@ -1,5 +1,5 @@
.\" manual page [] for pppd 2.0
.\" $Id: pppd.8,v 1.7 1994/06/09 01:50:48 paulus Exp $
.\" $Id: pppd.8,v 1.14 1995/08/16 01:39:53 paulus Exp $
.\" SH section heading
.\" SS subsection heading
.\" LP paragraph
@ -36,6 +36,7 @@ NCP for establishing and configuring the Internet Protocol (IP)
.I <tty_name>
Communicate over the named device. The string "/dev/"
is prepended if necessary. If no device name is given,
or if the name of the controlling terminal is given,
.I pppd
will use the controlling terminal, and will not fork to put itself in
the background.
@ -58,7 +59,7 @@ bit 31 (80000000) represents the character 0x1f or ^_.
If multiple \fBasyncmap\fR options are
given, the values are ORed together.
If no \fBasyncmap\fR option is given, no async character map will be
negotiated for the receive direction; the peer will then escape
negotiated for the receive direction; the peer should then escape
\fIall\fR control characters.
.TP
.B auth
@ -74,14 +75,17 @@ dial the modem and start the remote ppp session.
Use hardware flow control (i.e. RTS/CTS) to control the flow of data on
the serial port.
.TP
.B -crtscts
Disable hardware flow control (i.e. RTS/CTS) on the serial port. If
neither the \fBcrtscts\fR nor the \fB\-crtscts\fR option is given,
the hardware flow control setting for the serial port is left
unchanged.
.TP
.B xonxoff
Use software flow control (i.e. XON/XOFF) to control the flow of data on
the serial port. This option is not implemented on BSD or Ultrix systems
the serial port. This option is only implemented on Linux systems
at present.
.TP
.B -crtscts
A synonym for \fBxonxoff\fR.
.TP
.B defaultroute
Add a default route to the system routing tables, using the peer as
the gateway, when IPCP negotiation is successfully completed.
@ -135,7 +139,7 @@ will then just wait passively for a valid LCP packet from the peer
With this option,
.I 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
LCP packet is received from the peer (as for the `passive' option with
old versions of \fIpppd\fR).
.SH OPTIONS
.TP
@ -228,6 +232,21 @@ Don't agree to authenticate using CHAP.
Disable negotiation of Van Jacobson style IP header compression (use
default, i.e. no compression).
.TP
.B bsdcomp \fInr,nt
Request that the peer compress packets that it sends, using the
BSD-Compress scheme, with a maximum code size of \fInr\fR bits, and
agree to compress packets sent to the peer with a maximum code size of
\fInt\fR bits. If \fInt\fR is not specified, it defaults to the value
given for \fInr\fR. Values in the range 9 to 15 may be used for
\fInr\fR and \fInt\fR; larger values give better compression but
consume more kernel memory for compression dictionaries.
Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables
compression in the corresponding direction.
.TP
.B \-bsdcomp
Disables compression; \fBpppd\fR will not request or agree to compress
packets using the BSD-Compress scheme.
.TP
.B debug
Increase debugging level (same as \fB\-d\fR).
If this
@ -235,9 +254,12 @@ option is given, \fIpppd\fR will log the contents of all control
packets sent or received in a readable form. The packets are logged
through syslog with facility \fIdaemon\fR and level \fIdebug\fR. This
information can be directed to a file by setting up /etc/syslog.conf
appropriately (see syslog.conf(5)). (If \fIpppd\fR is compiled with
extra debugging enabled, it will log messages using facility
\fIlocal2\fR instead of \fIdaemon\fR).
appropriately (see syslog.conf(5)).
.TP
.B \-defaultroute
Disable the \fBdefaultroute\fR option. The system administrator who
wishes to prevent users from creating default routes with \fIpppd\fR
can do so by placing this option in the /etc/ppp/options file.
.TP
.B domain \fI<d>
Append the domain name <d> to the local host name for authentication
@ -245,10 +267,22 @@ purposes. For example, if gethostname() returns the name porsche, but the
fully qualified domain name is porsche.Quotron.COM, you would use the
domain option to set the domain name to Quotron.COM.
.TP
.B ipparam \fIstring
Provides an extra parameter to the ip-up and ip-down scripts. If this
option is given, the \fIstring\fR supplied is given as the 6th
parameter to those scripts.
.TP
.B modem
Use the modem control lines. On Ultrix, this option implies hardware
flow control, as for the \fBcrtscts\fR option. (This option is not fully
implemented.)
Use the modem control lines. This option is the default. With this
option,
.B pppd
will wait for the CD (Carrier Detect) signal from the modem to be asserted
when opening the serial device
(unless a connect script is specified), and it will drop the DTR (Data
Terminal Ready) signal briefly when the connection is terminated and before
executing the connect script.
On Ultrix, this option implies hardware
flow control, as for the \fBcrtscts\fR option.
.TP
.B kdebug \fIn
Enable debugging code in the kernel-level PPP driver. The argument
@ -258,7 +292,10 @@ received packets be printed, and 4 to request that the contents of
transmitted packets be printed.
.TP
.B local
Don't use the modem control lines.
Don't use the modem control lines. With this option,
.B pppd
will ignore the state of the CD (Carrier Detect) signal from the modem and
will not change the state of the DTR (Data Terminal Ready) signal.
.TP
.B mtu \fI<n>
Set the MTU [Maximum Transmit Unit] value to \fI<n>\fR. Unless the
@ -283,11 +320,27 @@ option).
Set the assumed name of the remote system for authentication purposes
to <n>.
.TP
.B papcrypt
Indicates that all secrets in the /etc/ppp/pap-secrets file which
are used for checking the identity of the peer are encrypted, and thus
pppd should not accept a password which (before encryption) is
identical to the secret from the /etc/ppp/pap-secrets file.
.TP
.B proxyarp
Add an entry to this system's ARP [Address Resolution Protocol] table
with the IP address of the peer and the Ethernet address of this
system.
.TP
.B \-proxyarp
Disable the \fBproxyarp\fR option. The system administrator who
wishes to prevent users from creating proxy ARP entries with
\fIpppd\fR can do so by placing this option in the /etc/ppp/options
file.
.TP
.B persist
Do not exit after a connection is terminated; instead try to reopen
the connection.
.TP
.B login
Use the system password database for authenticating the peer using
PAP.
@ -358,6 +411,12 @@ Set the PAP restart interval (retransmission timeout) to <n> seconds
Set the maximum number of PAP authenticate-request transmissions to
<n> (default 10).
.TP
.B pap-timeout \fI<n>
Set the maximum time that
.I pppd
will wait for the peer to authenticate itself with PAP to
<n> seconds (0 means no limit).
.TP
.B chap-restart \fI<n>
Set the CHAP restart interval (retransmission timeout for challenges)
to <n> seconds (default 3).
@ -424,7 +483,7 @@ directions if desired.
.LP
A secrets file is parsed into words as for a options file. A secret
is specified by a line containing at least 3 words, in the order
client, server, secret. Any following words on the same line are
client name, server name, secret. Any following words on the same line are
taken to be a list of acceptable IP addresses for that client. If
there are only 3 words on the line, it is assumed that any IP address
is OK; to disallow all IP addresses, use "-". If the secret starts
@ -480,11 +539,16 @@ When authenticating the peer with PAP, a secret of "" matches any
password supplied by the peer. If the password doesn't match the
secret, the password is encrypted using crypt() and checked against
the secret again; thus secrets for authenticating the peer can be
stored in encrypted form. If the \fBlogin\fR option was specified, the
stored in encrypted form. If the \fBpapcrypt\fR option is given, the
first (unencrypted) comparison is omitted, for better security.
.LP
If the \fBlogin\fR option was specified, the
username and password are also checked against the system password
database. Thus, the system administrator can set up the pap-secrets
file to allow PPP access only to certain users, and to restrict the
set of IP addresses that each user can use.
set of IP addresses that each user can use. Typically, when using the
\fBlogin\fR option, the secret in /etc/ppp/pap-secrets would be "", to
avoid the need to have the same secret in two places.
.LP
Secrets are selected from the CHAP secrets file as follows:
.TP 2
@ -590,27 +654,28 @@ to direct the messages to the desired output device or file.
The \fBdebug\fR option causes the contents of all control packets sent
or received to be logged, that is, all LCP, PAP, CHAP or IPCP packets.
This can be useful if the PPP negotiation does not succeed.
If debugging is enabled at compile time, \fIpppd\fR uses facility
LOG_LOCAL2 instead of LOG_DAEMON, and the \fBdebug\fR option
causes additional debugging messages to be logged.
If debugging is enabled at compile time, the \fBdebug\fR option also
causes other debugging messages to be logged.
.LP
Debugging can also be enabled by sending a
Debugging can also be enabled or disabled by sending a
SIGUSR1 to the
.I pppd
process.
Debugging may be disabled by sending a SIGUSR2 to the
.I pppd
process.
process. This signal acts as a toggle.
.SH FILES
.TP
.B /var/run/ppp\fIn\fB.pid \fR(BSD), \fB/etc/ppp/ppp\fIn\fB.pid \fR(SunOS)
.B /var/run/ppp\fIn\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp\fIn\fB.pid \fR(others)
Process-ID for \fIpppd\fR process on ppp interface unit \fIn\fR.
.TP
.B /etc/ppp/ip-up
A program or script which is executed when the link is available for
sending and receiving IP packets (that is, IPCP has come up). It is
executed with the parameters \fIinterface-name tty-device speed
local-IP-address remote-IP-address\fR.
executed with the parameters
.IP
\fIinterface-name tty-device speed local-IP-address
remote-IP-address\fR
.IP
and with its standard input,
output and error streams redirected to \fB/dev/null\fR.
.IP
This program or script is executed with the same real and effective
user-ID as \fIpppd\fR, that is, at least the effective user-ID and
@ -682,20 +747,29 @@ The following signals have the specified effect when sent to the
process.
.TP
.B SIGINT, SIGTERM
These signals cause \fIpppd\fR to terminate the link (by closing LCP),
These signals cause \fBpppd\fR to terminate the link (by closing LCP),
restore the serial device settings, and exit.
.TP
.B SIGHUP
Indicates that the physical layer has been disconnected. \fIpppd\fR
will attempt to restore the serial device settings (this may produce
error messages on Suns), and then exit.
.SH BUGS
The use of the modem control lines and the effects of the \fBmodem\fR
and \fBlocal\fR options are not well defined.
This signal causes \fBpppd\fR to terminate the link, restore the
serial device settings, and close the serial device. If the
\fBpersist\fR option has been specified, \fBpppd\fR will try to reopen
the serial device and start another connection. Otherwise \fBpppd\fR
will exit.
.TP
.B SIGUSR2
This signal causes
.B pppd
to renegotiate compression. This can be useful to re-enable
compression after it has been disabled as a result of a fatal
decompression error. With the BSD Compress scheme, fatal
decompression errors generally indicate a bug in one or other
implementation.
.SH AUTHORS
Drew Perkins,
Brad Clements,
Karl Fox,
Greg Christy,
Brad Parker (brad@fcr.com),
Paul Mackerras (paulus@cs.anu.edu.au)
Brad Parker,
Paul Mackerras (paulus@cs.anu.edu.au).

View file

@ -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.2 1994/09/25 02:32:13 wollman Exp $
* $Id: pppd.h,v 1.8 1995/04/26 06:46:31 paulus Exp $
*/
/*
@ -25,15 +25,17 @@
#ifndef __PPPD_H__
#define __PPPD_H__
#include "args.h"
#include <sys/param.h> /* for MAXPATHLEN and BSD4_4, if defined */
#include <sys/types.h> /* for u_int32_t, if defined */
#include <net/ppp_defs.h>
#define NPPP 1 /* One PPP interface supported (per process) */
#define NUM_PPP 1 /* One PPP interface supported (per process) */
/*
* Limits.
*/
#define MAXWORDLEN 1024 /* max length of word in file (incl null) */
#define MAXARGS 1 /* max # args to a command */
#define MAXNAMELEN 256 /* max length of hostname or name for auth */
@ -42,14 +44,47 @@
/*
* Global variables.
*/
extern int debug; /* Debug flag */
extern int ifunit; /* Interface unit number */
extern char ifname[]; /* Interface name */
extern int fd; /* Device file descriptor */
extern int s; /* socket descriptor */
extern char hostname[]; /* hostname */
extern u_char outpacket_buf[]; /* buffer for outgoing packets */
extern int phase; /* See values below */
extern int hungup; /* Physical layer has disconnected */
extern int ifunit; /* Interface unit number */
extern char ifname[]; /* Interface name */
extern int fd; /* Serial device file descriptor */
extern char hostname[]; /* Our hostname */
extern u_char outpacket_buf[]; /* Buffer for outgoing packets */
extern int phase; /* Current state of link - see values below */
extern int baud_rate; /* Current link speed in bits/sec */
extern char *progname; /* Name of this program */
/*
* Variables set by command-line options.
*/
extern int debug; /* Debug flag */
extern int kdebugflag; /* Tell kernel to print debug messages */
extern int default_device; /* Using /dev/tty or equivalent */
extern char devnam[]; /* Device name */
extern int crtscts; /* Use hardware flow control */
extern int modem; /* Use modem control lines */
extern int inspeed; /* Input/Output speed requested */
extern u_int32_t netmask; /* IP netmask to set on interface */
extern int lockflag; /* Create lock file to lock the serial dev */
extern int nodetach; /* Don't detach from controlling tty */
extern char *connector; /* Script to establish physical link */
extern char *disconnector; /* Script to disestablish physical link */
extern char user[]; /* Username for PAP */
extern char passwd[]; /* Password for PAP */
extern int auth_required; /* Peer is required to authenticate */
extern int proxyarp; /* Set up proxy ARP entry for peer */
extern int persist; /* Reopen link after it goes down */
extern int uselogin; /* Use /etc/passwd for checking PAP */
extern int lcp_echo_interval; /* Interval between LCP echo-requests */
extern int lcp_echo_fails; /* Tolerance to unanswered echo-requests */
extern char our_name[]; /* Our name for authentication purposes */
extern char remote_name[]; /* Peer's name for authentication */
extern int usehostname; /* Use hostname for our_name */
extern int disable_defaultip; /* Don't use hostname for default IP adrs */
extern char *ipparam; /* Extra parameter for ip up/down scripts */
extern int cryptpap; /* Others' PAP passwords are encrypted */
/*
* Values for phase.
@ -63,21 +98,21 @@ extern int phase; /* See values below */
/*
* Prototypes.
*/
void quit __ARGS((void)); /* Cleanup and exit */
void timeout __ARGS((void (*)(), caddr_t, int));
void quit __P((void)); /* Cleanup and exit */
void timeout __P((void (*)(), caddr_t, int));
/* Look-alike of kernel's timeout() */
void untimeout __ARGS((void (*)(), caddr_t));
void untimeout __P((void (*)(), caddr_t));
/* Look-alike of kernel's untimeout() */
void output __ARGS((int, u_char *, int));
void output __P((int, u_char *, int));
/* Output a PPP packet */
void demuxprotrej __ARGS((int, int));
void demuxprotrej __P((int, int));
/* Demultiplex a Protocol-Reject */
int check_passwd __ARGS((int, char *, int, char *, int, char **, int *));
int check_passwd __P((int, char *, int, char *, int, char **, int *));
/* Check peer-supplied username/password */
int get_secret __ARGS((int, char *, char *, char *, int *, int));
int get_secret __P((int, char *, char *, char *, int *, int));
/* get "secret" for chap */
u_long GetMask __ARGS((u_long)); /* get netmask for address */
u_int32_t GetMask __P((u_int32_t)); /* get netmask for address */
void die __P((int));
/*
* Inline versions of get/put char/short/long.
@ -118,6 +153,11 @@ u_long GetMask __ARGS((u_long)); /* get netmask for address */
#define INCPTR(n, cp) ((cp) += (n))
#define DECPTR(n, cp) ((cp) -= (n))
#undef FALSE
#define FALSE 0
#undef TRUE
#define TRUE 1
/*
* System dependent definitions for user-level 4.3BSD UNIX implementation.
*/
@ -137,8 +177,8 @@ u_long GetMask __ARGS((u_long)); /* get netmask for address */
* MAKEHEADER - Add Header fields to a packet.
*/
#define MAKEHEADER(p, t) { \
PUTCHAR(ALLSTATIONS, p); \
PUTCHAR(UI, p); \
PUTCHAR(PPP_ALLSTATIONS, p); \
PUTCHAR(PPP_UI, p); \
PUTSHORT(t, p); }
@ -154,7 +194,7 @@ u_long GetMask __ARGS((u_long)); /* get netmask for address */
#ifndef LOG_PPP /* we use LOG_LOCAL2 for syslog by default */
#if defined(DEBUGMAIN) || defined(DEBUGFSM) || defined(DEBUG) \
|| defined(DEBUGLCP) || defined(DEBUGIPCP) || defined(DEBUGUPAP) \
|| defined(DEBUGCHAP)
|| defined(DEBUGCHAP)
#define LOG_PPP LOG_LOCAL2
#else
#define LOG_PPP LOG_DAEMON

View file

@ -19,21 +19,28 @@
*/
#ifndef lint
static char rcsid[] = "$Id: sys-bsd.c,v 1.3 1995/05/30 03:51:16 rgrimes Exp $";
static char rcsid[] = "$Id: sys-bsd.c,v 1.21 1995/08/16 01:40:23 paulus Exp $";
#endif
/*
* TODO:
*/
#include <stdio.h>
#include <syslog.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <net/if.h>
#include <net/ppp_defs.h>
#include <net/if_ppp.h>
#include <net/route.h>
#include <net/if_dl.h>
@ -44,12 +51,75 @@ static char rcsid[] = "$Id: sys-bsd.c,v 1.3 1995/05/30 03:51:16 rgrimes Exp $";
#endif
#include "pppd.h"
#include "ppp.h"
static int initdisc = -1; /* Initial TTY discipline */
extern int kdebugflag;
static int initdisc = -1; /* Initial TTY discipline */
static int rtm_seq;
static int restore_term; /* 1 => we've munged the terminal */
static struct termios inittermios; /* Initial TTY termios */
static struct winsize wsinfo; /* Initial window size info */
static char *lock_file; /* name of lock file created */
int sockfd; /* socket for doing interface ioctls */
/*
* sys_init - System-dependent initialization.
*/
void
sys_init()
{
openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
setlogmask(LOG_UPTO(LOG_INFO));
if (debug)
setlogmask(LOG_UPTO(LOG_DEBUG));
/* Get an internet socket for doing socket ioctl's on. */
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
syslog(LOG_ERR, "Couldn't create IP socket: %m");
die(1);
}
}
/*
* note_debug_level - note a change in the debug level.
*/
void
note_debug_level()
{
if (debug) {
syslog(LOG_INFO, "Debug turned ON, Level %d", debug);
setlogmask(LOG_UPTO(LOG_DEBUG));
} else {
setlogmask(LOG_UPTO(LOG_WARNING));
}
}
/*
* ppp_available - check whether the system has any ppp interfaces
* (in fact we check whether we can do an ioctl on ppp0).
*/
int
ppp_available()
{
int s, ok;
struct ifreq ifr;
extern char *no_ppp_msg;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
return 1; /* can't tell */
strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
close(s);
no_ppp_msg = "\
This system lacks kernel support for PPP. To include PPP support\n\
in the kernel, please follow the steps detailed in the README.bsd\n\
file in the ppp-2.2 distribution.\n";
return ok;
}
/*
* establish_ppp - Turn the serial port into a ppp interface.
*/
@ -71,7 +141,7 @@ establish_ppp()
/*
* Find out which interface we were given.
*/
if (ioctl(fd, PPPIOCGUNIT, &ifunit) < 0) {
if (ioctl(fd, PPPIOCGUNIT, &ifunit) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m");
die(1);
}
@ -132,6 +202,111 @@ disestablish_ppp()
}
/*
* set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
* at the requested speed, etc. If `local' is true, set CLOCAL
* regardless of whether the modem option was specified.
*
* For *BSD, we assume that speed_t values numerically equal bits/second.
*/
set_up_tty(fd, local)
int fd, local;
{
struct termios tios;
if (tcgetattr(fd, &tios) < 0) {
syslog(LOG_ERR, "tcgetattr: %m");
die(1);
}
if (!restore_term) {
inittermios = tios;
ioctl(fd, TIOCGWINSZ, &wsinfo);
}
tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
if (crtscts > 0)
tios.c_cflag |= CRTSCTS;
else if (crtscts < 0)
tios.c_cflag &= ~CRTSCTS;
tios.c_cflag |= CS8 | CREAD | HUPCL;
if (local || !modem)
tios.c_cflag |= CLOCAL;
tios.c_iflag = IGNBRK | IGNPAR;
tios.c_oflag = 0;
tios.c_lflag = 0;
tios.c_cc[VMIN] = 1;
tios.c_cc[VTIME] = 0;
if (crtscts == 2) {
tios.c_iflag |= IXOFF;
tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
}
if (inspeed) {
cfsetospeed(&tios, inspeed);
cfsetispeed(&tios, inspeed);
} else {
inspeed = cfgetospeed(&tios);
/*
* We can't proceed if the serial port speed is 0,
* since that implies that the serial port is disabled.
*/
if (inspeed == 0) {
syslog(LOG_ERR, "Baud rate for %s is 0; need explicit baud rate",
devnam);
die(1);
}
}
baud_rate = inspeed;
if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
syslog(LOG_ERR, "tcsetattr: %m");
die(1);
}
restore_term = 1;
}
/*
* restore_tty - restore the terminal to the saved settings.
*/
void
restore_tty()
{
if (restore_term) {
if (!default_device) {
/*
* Turn off echoing, because otherwise we can get into
* a loop with the tty and the modem echoing to each other.
* We presume we are the sole user of this tty device, so
* when we close it, it will revert to its defaults anyway.
*/
inittermios.c_lflag &= ~(ECHO | ECHONL);
}
if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
if (errno != ENXIO)
syslog(LOG_WARNING, "tcsetattr: %m");
ioctl(fd, TIOCSWINSZ, &wsinfo);
restore_term = 0;
}
}
/*
* setdtr - control the DTR line on the serial port.
* This is called from die(), so it shouldn't call die().
*/
setdtr(fd, on)
int fd, on;
{
int modembits = TIOCM_DTR;
ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
}
/*
* output - Output PPP packet.
*/
@ -153,6 +328,27 @@ output(unit, p, len)
}
/*
* wait_input - wait until there is data available on fd,
* for the length of time specified by *timo (indefinite
* if timo is NULL).
*/
wait_input(timo)
struct timeval *timo;
{
fd_set ready;
int n;
FD_ZERO(&ready);
FD_SET(fd, &ready);
n = select(fd+1, &ready, NULL, &ready, timo);
if (n < 0 && errno != EINTR) {
syslog(LOG_ERR, "select: %m");
die(1);
}
}
/*
* read_packet - get a PPP packet from the serial device.
*/
@ -162,11 +358,9 @@ read_packet(buf)
{
int len;
if ((len = read(fd, buf, MTU + DLLHEADERLEN)) < 0) {
if (errno == EWOULDBLOCK) {
MAINDEBUG((LOG_DEBUG, "read(fd): EWOULDBLOCK"));
if ((len = read(fd, buf, PPP_MTU + PPP_HDRLEN)) < 0) {
if (errno == EWOULDBLOCK || errno == EINTR)
return -1;
}
syslog(LOG_ERR, "read(fd): %m");
die(1);
}
@ -181,7 +375,7 @@ read_packet(buf)
void
ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
int unit, mtu;
u_long asyncmap;
u_int32_t asyncmap;
int pcomp, accomp;
{
u_int x;
@ -189,7 +383,7 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
ifr.ifr_mtu = mtu;
if (ioctl(s, SIOCSIFMTU, (caddr_t) &ifr) < 0) {
if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m");
quit();
}
@ -232,7 +426,7 @@ ppp_set_xaccm(unit, accm)
void
ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
int unit, mru;
u_long asyncmap;
u_int32_t asyncmap;
int pcomp, accomp;
{
int x;
@ -256,6 +450,59 @@ ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
}
}
/*
* ccp_test - ask kernel whether a given compression method
* is acceptable for use.
*/
ccp_test(unit, opt_ptr, opt_len, for_transmit)
int unit, opt_len, for_transmit;
u_char *opt_ptr;
{
struct ppp_option_data data;
data.ptr = opt_ptr;
data.length = opt_len;
data.transmit = for_transmit;
return ioctl(fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0;
}
/*
* ccp_flags_set - inform kernel about the current state of CCP.
*/
void
ccp_flags_set(unit, isopen, isup)
int unit, isopen, isup;
{
int x;
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
return;
}
x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN;
x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP;
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
}
/*
* ccp_fatal_error - returns 1 if decompression was disabled as a
* result of an error detected after decompression of a packet,
* 0 otherwise. This is necessary because of patent nonsense.
*/
int
ccp_fatal_error(unit)
int unit;
{
int x;
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCGFLAGS): %m");
return 0;
}
return x & SC_DC_FERROR;
}
/*
* sifvjcomp - config tcp header compression
*/
@ -285,31 +532,45 @@ sifvjcomp(u, vjcomp, cidcomp, maxcid)
/*
* sifup - Config the interface up and enable IP packets to pass.
*/
#ifndef SC_ENABLE_IP
#define SC_ENABLE_IP 0x100 /* compat for old versions of kernel code */
#endif
int
sifup(u)
int u;
{
struct ifreq ifr;
u_int x;
struct npioctl npi;
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
return 0;
}
ifr.ifr_flags |= IFF_UP;
if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
return 0;
}
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
return 0;
}
x |= SC_ENABLE_IP;
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
return 0;
npi.protocol = PPP_IP;
npi.mode = NPMODE_PASS;
if (ioctl(fd, PPPIOCSNPMODE, &npi) < 0) {
if (errno != ENOTTY) {
syslog(LOG_ERR, "ioctl(PPPIOCSNPMODE): %m");
return 0;
}
/* for backwards compatibility */
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
return 0;
}
x |= SC_ENABLE_IP;
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
return 0;
}
}
return 1;
}
@ -324,25 +585,37 @@ sifdown(u)
struct ifreq ifr;
u_int x;
int rv;
struct npioctl npi;
rv = 1;
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
rv = 0;
} else {
x &= ~SC_ENABLE_IP;
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
npi.protocol = PPP_IP;
npi.mode = NPMODE_ERROR;
if (ioctl(fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
if (errno != ENOTTY) {
syslog(LOG_ERR, "ioctl(PPPIOCSNPMODE): %m");
rv = 0;
} else {
/* backwards compatibility */
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
rv = 0;
} else {
x &= ~SC_ENABLE_IP;
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
rv = 0;
}
}
}
}
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
rv = 0;
} else {
ifr.ifr_flags &= ~IFF_UP;
if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
rv = 0;
}
@ -365,7 +638,7 @@ sifdown(u)
int
sifaddr(u, o, h, m)
int u;
u_long o, h, m;
u_int32_t o, h, m;
{
struct ifaliasreq ifra;
@ -379,7 +652,7 @@ sifaddr(u, o, h, m)
((struct sockaddr_in *) &ifra.ifra_mask)->sin_addr.s_addr = m;
} else
BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));
if (ioctl(s, SIOCAIFADDR, (caddr_t) &ifra) < 0) {
if (ioctl(sockfd, SIOCAIFADDR, (caddr_t) &ifra) < 0) {
if (errno != EEXIST) {
syslog(LOG_ERR, "ioctl(SIOCAIFADDR): %m");
return 0;
@ -396,7 +669,7 @@ sifaddr(u, o, h, m)
int
cifaddr(u, o, h)
int u;
u_long o, h;
u_int32_t o, h;
{
struct ifaliasreq ifra;
@ -406,21 +679,20 @@ cifaddr(u, o, h)
SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);
((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h;
BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));
if (ioctl(s, SIOCDIFADDR, (caddr_t) &ifra) < 0) {
if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifra) < 0) {
syslog(LOG_WARNING, "ioctl(SIOCDIFADDR): %m");
return 0;
}
return 1;
}
/*
* sifdefaultroute - assign a default route through the address given.
*/
int
sifdefaultroute(u, g)
int u;
u_long g;
u_int32_t g;
{
return dodefaultroute(g, 's');
}
@ -431,7 +703,7 @@ sifdefaultroute(u, g)
int
cifdefaultroute(u, g)
int u;
u_long g;
u_int32_t g;
{
return dodefaultroute(g, 'c');
}
@ -441,7 +713,7 @@ cifdefaultroute(u, g)
*/
int
dodefaultroute(g, cmd)
u_long g;
u_int32_t g;
int cmd;
{
int routes;
@ -499,7 +771,7 @@ static int arpmsg_valid;
int
sifproxyarp(unit, hisaddr)
int unit;
u_long hisaddr;
u_int32_t hisaddr;
{
int routes;
int l;
@ -549,7 +821,7 @@ sifproxyarp(unit, hisaddr)
int
cifproxyarp(unit, hisaddr)
int unit;
u_long hisaddr;
u_int32_t hisaddr;
{
int routes;
@ -583,7 +855,7 @@ cifproxyarp(unit, hisaddr)
int
sifproxyarp(unit, hisaddr)
int unit;
u_long hisaddr;
u_int32_t hisaddr;
{
struct arpreq arpreq;
struct {
@ -608,7 +880,7 @@ sifproxyarp(unit, hisaddr)
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
arpreq.arp_flags = ATF_PERM | ATF_PUBL;
if (ioctl(s, SIOCSARP, (caddr_t)&arpreq) < 0) {
if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) {
syslog(LOG_ERR, "ioctl(SIOCSARP): %m");
return 0;
}
@ -622,14 +894,14 @@ sifproxyarp(unit, hisaddr)
int
cifproxyarp(unit, hisaddr)
int unit;
u_long hisaddr;
u_int32_t hisaddr;
{
struct arpreq arpreq;
BZERO(&arpreq, sizeof(arpreq));
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
if (ioctl(s, SIOCDARP, (caddr_t)&arpreq) < 0) {
if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) {
syslog(LOG_WARNING, "ioctl(SIOCDARP): %m");
return 0;
}
@ -638,12 +910,6 @@ cifproxyarp(unit, hisaddr)
#endif /* RTM_VERSION */
/*
* How to find the next ifreq structure in the stuff returned by SIOCGIFCONF.
*/
#define next_ifreq(ifr) \
((struct ifreq *) ((char *)&(ifr)->ifr_addr + (ifr)->ifr_addr.sa_len))
/*
* get_ether_addr - get the hardware address of an interface on the
* the same subnet as ipaddr.
@ -652,11 +918,11 @@ cifproxyarp(unit, hisaddr)
int
get_ether_addr(ipaddr, hwaddr)
u_long ipaddr;
u_int32_t ipaddr;
struct sockaddr_dl *hwaddr;
{
struct ifreq *ifr, *ifend, *ifp;
u_long ina, mask;
u_int32_t ina, mask;
struct sockaddr_dl *dla;
struct ifreq ifreq;
struct ifconf ifc;
@ -664,7 +930,7 @@ get_ether_addr(ipaddr, hwaddr)
ifc.ifc_len = sizeof(ifs);
ifc.ifc_req = ifs;
if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m");
return 0;
}
@ -674,7 +940,8 @@ get_ether_addr(ipaddr, hwaddr)
* address on the same subnet as `ipaddr'.
*/
ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
for (ifr = ifc.ifc_req; ifr < ifend; ifr = next_ifreq(ifr)) {
for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *)
((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) {
if (ifr->ifr_addr.sa_family == AF_INET) {
ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
@ -682,7 +949,7 @@ get_ether_addr(ipaddr, hwaddr)
* Check that the interface is up, and not point-to-point
* or loopback.
*/
if (ioctl(s, SIOCGIFFLAGS, &ifreq) < 0)
if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
continue;
if ((ifreq.ifr_flags &
(IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
@ -691,7 +958,7 @@ get_ether_addr(ipaddr, hwaddr)
/*
* Get its netmask and check that it's on the right subnet.
*/
if (ioctl(s, SIOCGIFNETMASK, &ifreq) < 0)
if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
continue;
mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;
if ((ipaddr & mask) != (ina & mask))
@ -710,7 +977,7 @@ get_ether_addr(ipaddr, hwaddr)
* for this interface.
*/
ifp = ifr;
for (ifr = ifc.ifc_req; ifr < ifend; ifr = next_ifreq(ifr)) {
for (ifr = ifc.ifc_req; ifr < ifend; ) {
if (strcmp(ifp->ifr_name, ifr->ifr_name) == 0
&& ifr->ifr_addr.sa_family == AF_LINK) {
/*
@ -720,28 +987,149 @@ get_ether_addr(ipaddr, hwaddr)
BCOPY(dla, hwaddr, dla->sdl_len);
return 1;
}
ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len);
}
return 0;
}
/*
* Return user specified netmask, modified by any mask we might determine
* for address `addr' (in network byte order).
* Here we scan through the system's list of interfaces, looking for
* any non-point-to-point interfaces which might appear to be on the same
* network as `addr'. If we find any, we OR in their netmask to the
* user-specified netmask.
*/
u_int32_t
GetMask(addr)
u_int32_t addr;
{
u_int32_t mask, nmask, ina;
struct ifreq *ifr, *ifend, ifreq;
struct ifconf ifc;
struct ifreq ifs[MAX_IFS];
addr = ntohl(addr);
if (IN_CLASSA(addr)) /* determine network mask for address class */
nmask = IN_CLASSA_NET;
else if (IN_CLASSB(addr))
nmask = IN_CLASSB_NET;
else
nmask = IN_CLASSC_NET;
/* class D nets are disallowed by bad_ip_adrs */
mask = netmask | htonl(nmask);
/*
* Scan through the system's network interfaces.
*/
ifc.ifc_len = sizeof(ifs);
ifc.ifc_req = ifs;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
syslog(LOG_WARNING, "ioctl(SIOCGIFCONF): %m");
return mask;
}
ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *)
((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) {
/*
* Check the interface's internet address.
*/
if (ifr->ifr_addr.sa_family != AF_INET)
continue;
ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
if ((ntohl(ina) & nmask) != (addr & nmask))
continue;
/*
* Check that the interface is up, and not point-to-point or loopback.
*/
strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
continue;
if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))
!= IFF_UP)
continue;
/*
* Get its netmask and OR it into our mask.
*/
if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
continue;
mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;
}
return mask;
}
/*
* ppp_available - check whether the system has any ppp interfaces
* (in fact we check whether we can do an ioctl on ppp0).
* lock - create a lock file for the named lock device
*/
#define LOCK_PREFIX "/var/spool/lock/LCK.."
int
ppp_available()
lock(dev)
char *dev;
{
int s, ok;
struct ifreq ifr;
char hdb_lock_buffer[12];
int fd, pid, n;
char *p;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
return 1; /* can't tell - maybe we're not root */
if ((p = strrchr(dev, '/')) != NULL)
dev = p + 1;
lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1);
if (lock_file == NULL)
novm("lock file name");
strcat(strcpy(lock_file, LOCK_PREFIX), dev);
strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
close(s);
while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
if (errno == EEXIST
&& (fd = open(lock_file, O_RDONLY, 0)) >= 0) {
/* Read the lock file to find out who has the device locked */
n = read(fd, hdb_lock_buffer, 11);
if (n > 0) {
hdb_lock_buffer[n] = 0;
pid = atoi(hdb_lock_buffer);
}
if (n <= 0) {
syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file);
close(fd);
} else {
if (kill(pid, 0) == -1 && errno == ESRCH) {
/* pid no longer exists - remove the lock file */
if (unlink(lock_file) == 0) {
close(fd);
syslog(LOG_NOTICE, "Removed stale lock on %s (pid %d)",
dev, pid);
continue;
} else
syslog(LOG_WARNING, "Couldn't remove stale lock on %s",
dev);
} else
syslog(LOG_NOTICE, "Device %s is locked by pid %d",
dev, pid);
}
close(fd);
} else
syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file);
free(lock_file);
lock_file = NULL;
return -1;
}
return ok;
sprintf(hdb_lock_buffer, "%10d\n", getpid());
write(fd, hdb_lock_buffer, 11);
close(fd);
return 0;
}
/*
* unlock - remove our lockfile
*/
unlock()
{
if (lock_file) {
unlink(lock_file);
free(lock_file);
lock_file = NULL;
}
}

View file

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: upap.c,v 1.2 1994/09/25 02:32:16 wollman Exp $";
static char rcsid[] = "$Id: upap.c,v 1.6 1995/06/12 12:02:24 paulus Exp $";
#endif
/*
@ -26,24 +26,25 @@ static char rcsid[] = "$Id: upap.c,v 1.2 1994/09/25 02:32:16 wollman Exp $";
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <syslog.h>
#include "ppp.h"
#include "pppd.h"
#include "upap.h"
upap_state upap[NPPP]; /* UPAP state; one for each unit */
upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */
static void upap_timeout __ARGS((caddr_t));
static void upap_rauthreq __ARGS((upap_state *, u_char *, int, int));
static void upap_rauthack __ARGS((upap_state *, u_char *, int, int));
static void upap_rauthnak __ARGS((upap_state *, u_char *, int, int));
static void upap_sauthreq __ARGS((upap_state *));
static void upap_sresp __ARGS((upap_state *, int, int, char *, int));
static void upap_timeout __P((caddr_t));
static void upap_reqtimeout __P((caddr_t));
static void upap_rauthreq __P((upap_state *, u_char *, int, int));
static void upap_rauthack __P((upap_state *, u_char *, int, int));
static void upap_rauthnak __P((upap_state *, u_char *, int, int));
static void upap_sauthreq __P((upap_state *));
static void upap_sresp __P((upap_state *, int, int, char *, int));
/*
@ -65,6 +66,7 @@ upap_init(unit)
u->us_id = 0;
u->us_timeouttime = UPAP_DEFTIMEOUT;
u->us_maxtransmits = 10;
u->us_reqtimeout = UPAP_DEFREQTIME;
}
@ -117,11 +119,13 @@ upap_authpeer(unit)
}
u->us_serverstate = UPAPSS_LISTEN;
if (u->us_reqtimeout > 0)
TIMEOUT(upap_reqtimeout, (caddr_t) u, u->us_reqtimeout);
}
/*
* upap_timeout - Timeout expired.
* upap_timeout - Retransmission timer for sending auth-reqs expired.
*/
static void
upap_timeout(arg)
@ -136,7 +140,7 @@ upap_timeout(arg)
/* give up in disgust */
syslog(LOG_ERR, "No response to PAP authenticate-requests");
u->us_clientstate = UPAPCS_BADAUTH;
auth_withpeer_fail(u->us_unit, UPAP);
auth_withpeer_fail(u->us_unit, PPP_PAP);
return;
}
@ -144,6 +148,23 @@ upap_timeout(arg)
}
/*
* upap_reqtimeout - Give up waiting for the peer to send an auth-req.
*/
static void
upap_reqtimeout(arg)
caddr_t arg;
{
upap_state *u = (upap_state *) arg;
if (u->us_serverstate != UPAPSS_LISTEN)
return; /* huh?? */
auth_peer_fail(u->us_unit, PPP_PAP);
u->us_serverstate = UPAPSS_BADAUTH;
}
/*
* upap_lowerup - The lower layer is up.
*
@ -163,8 +184,11 @@ upap_lowerup(unit)
if (u->us_serverstate == UPAPSS_INITIAL)
u->us_serverstate = UPAPSS_CLOSED;
else if (u->us_serverstate == UPAPSS_PENDING)
else if (u->us_serverstate == UPAPSS_PENDING) {
u->us_serverstate = UPAPSS_LISTEN;
if (u->us_reqtimeout > 0)
TIMEOUT(upap_reqtimeout, (caddr_t) u, u->us_reqtimeout);
}
}
@ -179,8 +203,10 @@ upap_lowerdown(unit)
{
upap_state *u = &upap[unit];
if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */
if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */
UNTIMEOUT(upap_timeout, (caddr_t) u); /* Cancel timeout */
if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0)
UNTIMEOUT(upap_reqtimeout, (caddr_t) u);
u->us_clientstate = UPAPCS_INITIAL;
u->us_serverstate = UPAPSS_INITIAL;
@ -200,11 +226,11 @@ upap_protrej(unit)
if (u->us_clientstate == UPAPCS_AUTHREQ) {
syslog(LOG_ERR, "PAP authentication failed due to protocol-reject");
auth_withpeer_fail(unit, UPAP);
auth_withpeer_fail(unit, PPP_PAP);
}
if (u->us_serverstate == UPAPSS_LISTEN) {
syslog(LOG_ERR, "PAP authentication of peer failed (protocol-reject)");
auth_peer_fail(unit, UPAP);
auth_peer_fail(unit, PPP_PAP);
}
upap_lowerdown(unit);
}
@ -334,11 +360,14 @@ upap_rauthreq(u, inp, id, len)
if (retcode == UPAP_AUTHACK) {
u->us_serverstate = UPAPSS_OPEN;
auth_peer_success(u->us_unit, UPAP);
auth_peer_success(u->us_unit, PPP_PAP);
} else {
u->us_serverstate = UPAPSS_BADAUTH;
auth_peer_fail(u->us_unit, UPAP);
auth_peer_fail(u->us_unit, PPP_PAP);
}
if (u->us_reqtimeout > 0)
UNTIMEOUT(upap_reqtimeout, (caddr_t) u);
}
@ -377,7 +406,7 @@ upap_rauthack(u, inp, id, len)
u->us_clientstate = UPAPCS_OPEN;
auth_withpeer_success(u->us_unit, UPAP);
auth_withpeer_success(u->us_unit, PPP_PAP);
}
@ -417,7 +446,7 @@ upap_rauthnak(u, inp, id, len)
u->us_clientstate = UPAPCS_BADAUTH;
syslog(LOG_ERR, "PAP authentication failed");
auth_withpeer_fail(u->us_unit, UPAP);
auth_withpeer_fail(u->us_unit, PPP_PAP);
}
@ -434,8 +463,8 @@ upap_sauthreq(u)
outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) +
u->us_userlen + u->us_passwdlen;
outp = outpacket_buf;
MAKEHEADER(outp, UPAP);
MAKEHEADER(outp, PPP_PAP);
PUTCHAR(UPAP_AUTHREQ, outp);
PUTCHAR(++u->us_id, outp);
@ -446,7 +475,7 @@ upap_sauthreq(u)
PUTCHAR(u->us_passwdlen, outp);
BCOPY(u->us_passwd, outp, u->us_passwdlen);
output(u->us_unit, outpacket_buf, outlen + DLLHEADERLEN);
output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
UPAPDEBUG((LOG_INFO, "upap_sauth: Sent id %d.", u->us_id));
@ -471,14 +500,14 @@ upap_sresp(u, code, id, msg, msglen)
outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
outp = outpacket_buf;
MAKEHEADER(outp, UPAP);
MAKEHEADER(outp, PPP_PAP);
PUTCHAR(code, outp);
PUTCHAR(id, outp);
PUTSHORT(outlen, outp);
PUTCHAR(msglen, outp);
BCOPY(msg, outp, msglen);
output(u->us_unit, outpacket_buf, outlen + DLLHEADERLEN);
output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
UPAPDEBUG((LOG_INFO, "upap_sresp: Sent code %d, id %d.", code, id));
}
@ -494,7 +523,7 @@ int
upap_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __ARGS((void *, char *, ...));
void (*printer) __P((void *, char *, ...));
void *arg;
{
int code, id, len;

View file

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: upap.h,v 1.2 1994/04/11 07:13:44 paulus Exp $
* $Id: upap.h,v 1.4 1995/06/12 12:02:25 paulus Exp $
*/
/*
@ -45,9 +45,10 @@ typedef struct upap_state {
int us_clientstate; /* Client state */
int us_serverstate; /* Server state */
u_char us_id; /* Current id */
int us_timeouttime; /* Timeout time in milliseconds */
int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */
int us_transmits; /* Number of auth-reqs sent */
int us_maxtransmits; /* Maximum number of auth-reqs to send */
int us_reqtimeout; /* Time to wait for auth-req from peer */
} upap_state;
@ -75,17 +76,18 @@ typedef struct upap_state {
/*
* Timeouts.
*/
#define UPAP_DEFTIMEOUT 3 /* Timeout time in seconds */
#define UPAP_DEFTIMEOUT 3 /* Timeout (seconds) for retransmitting req */
#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */
extern upap_state upap[];
void upap_init __ARGS((int));
void upap_authwithpeer __ARGS((int, char *, char *));
void upap_authpeer __ARGS((int));
void upap_lowerup __ARGS((int));
void upap_lowerdown __ARGS((int));
void upap_input __ARGS((int, u_char *, int));
void upap_protrej __ARGS((int));
int upap_printpkt __ARGS((u_char *, int,
void (*) __ARGS((void *, char *, ...)), void *));
void upap_init __P((int));
void upap_authwithpeer __P((int, char *, char *));
void upap_authpeer __P((int));
void upap_lowerup __P((int));
void upap_lowerdown __P((int));
void upap_input __P((int, u_char *, int));
void upap_protrej __P((int));
int upap_printpkt __P((u_char *, int,
void (*) __P((void *, char *, ...)), void *));