From 945f93070b55f7d3b524201d3c078955be8b74cc Mon Sep 17 00:00:00 2001 From: Peter Wemm Date: Tue, 31 Oct 1995 21:11:19 +0000 Subject: [PATCH] Import pppd onto the vendor branch from the ppp-2.2 package.. --- usr.sbin/pppd/Makefile | 14 +- usr.sbin/pppd/auth.c | 138 ++-- usr.sbin/pppd/chap.c | 80 +-- usr.sbin/pppd/chap.h | 20 +- usr.sbin/pppd/fsm.c | 55 +- usr.sbin/pppd/fsm.h | 21 +- usr.sbin/pppd/ipcp.c | 98 +-- usr.sbin/pppd/ipcp.h | 20 +- usr.sbin/pppd/lcp.c | 474 +++++++++---- usr.sbin/pppd/lcp.h | 35 +- usr.sbin/pppd/lock.c | 122 ---- usr.sbin/pppd/magic.c | 70 +- usr.sbin/pppd/magic.h | 7 +- usr.sbin/pppd/main.c | 1368 +++++++++++++----------------------- usr.sbin/pppd/md5.h | 2 +- usr.sbin/pppd/options.c | 708 +++++++++++++------ usr.sbin/pppd/patchlevel.h | 9 +- usr.sbin/pppd/pathnames.h | 11 +- usr.sbin/pppd/pppd.8 | 148 +++- usr.sbin/pppd/pppd.h | 84 ++- usr.sbin/pppd/sys-bsd.c | 520 ++++++++++++-- usr.sbin/pppd/sys-linux.c | 830 ---------------------- usr.sbin/pppd/sys-str.c | 730 ------------------- usr.sbin/pppd/sys-ultrix.c | 663 ----------------- usr.sbin/pppd/upap.c | 77 +- usr.sbin/pppd/upap.h | 26 +- 26 files changed, 2344 insertions(+), 3986 deletions(-) delete mode 100644 usr.sbin/pppd/lock.c delete mode 100644 usr.sbin/pppd/sys-linux.c delete mode 100644 usr.sbin/pppd/sys-str.c delete mode 100644 usr.sbin/pppd/sys-ultrix.c diff --git a/usr.sbin/pppd/Makefile b/usr.sbin/pppd/Makefile index a0ca52e93e81..ec15113e0d2b 100644 --- a/usr.sbin/pppd/Makefile +++ b/usr.sbin/pppd/Makefile @@ -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 -MAN8= pppd.8 +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.0 +# The next line is for NetBSD-current systems. +MAN= pppd.cat8 BINMODE=4555 BINOWN= root diff --git a/usr.sbin/pppd/auth.c b/usr.sbin/pppd/auth.c index 950ef024e6b7..dd9735b89efd 100644 --- a/usr.sbin/pppd/auth.c +++ b/usr.sbin/pppd/auth.c @@ -33,11 +33,12 @@ */ #ifndef lint -static char rcsid[] = "$Id: auth.c,v 1.6 1994/05/25 06:25:05 paulus Exp $"; +static char rcsid[] = "$Id: auth.c,v 1.17 1995/08/16 01:37:22 paulus Exp $"; #endif #include #include +#include #include #include #include @@ -48,16 +49,24 @@ static char rcsid[] = "$Id: auth.c,v 1.6 1994/05/25 06:25:05 paulus Exp $"; #include #include -#include "ppp.h" +#ifdef HAS_SHADOW +#include +#include +#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 #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,10 +465,23 @@ 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); } +#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. */ @@ -463,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; @@ -492,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; } @@ -688,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; @@ -711,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; @@ -726,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 diff --git a/usr.sbin/pppd/chap.c b/usr.sbin/pppd/chap.c index 64f39bc51c1b..d72c36d4a989 100644 --- a/usr.sbin/pppd/chap.c +++ b/usr.sbin/pppd/chap.c @@ -19,7 +19,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: chap.c,v 1.3 1994/04/18 04:01:07 paulus 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.3 1994/04/18 04:01:07 paulus Exp $"; */ #include +#include #include #include #include -#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 */ } @@ -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); } @@ -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 */ } @@ -506,7 +503,7 @@ ChapReceiveResponse(cstate, inp, id, len) 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); } @@ -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,7 +631,7 @@ 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)); @@ -664,13 +661,13 @@ 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)); @@ -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 diff --git a/usr.sbin/pppd/chap.h b/usr.sbin/pppd/chap.h index 682ecb864d17..44b08f2e205f 100644 --- a/usr.sbin/pppd/chap.h +++ b/usr.sbin/pppd/chap.h @@ -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__ */ diff --git a/usr.sbin/pppd/fsm.c b/usr.sbin/pppd/fsm.c index 902ad64cbbc2..5d2eca6880ad 100644 --- a/usr.sbin/pppd/fsm.c +++ b/usr.sbin/pppd/fsm.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: fsm.c,v 1.3 1994/05/24 11:21:10 paulus 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.3 1994/05/24 11:21:10 paulus Exp $"; */ #include +#include #include #include -#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]; /* @@ -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)); diff --git a/usr.sbin/pppd/fsm.h b/usr.sbin/pppd/fsm.h index a12966bef488..efe18bf92f00 100644 --- a/usr.sbin/pppd/fsm.h +++ b/usr.sbin/pppd/fsm.h @@ -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)); /* diff --git a/usr.sbin/pppd/ipcp.c b/usr.sbin/pppd/ipcp.c index 6c9abb15f2be..3d99235440b2 100644 --- a/usr.sbin/pppd/ipcp.c +++ b/usr.sbin/pppd/ipcp.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: ipcp.c,v 1.8 1994/05/26 06:37:34 paulus 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.8 1994/05/26 06:37:34 paulus Exp $"; #include #include #include +#include #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 */ @@ -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,10 +834,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) { + /* + * 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; @@ -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]; @@ -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")); @@ -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; diff --git a/usr.sbin/pppd/ipcp.h b/usr.sbin/pppd/ipcp.h index 2d1988d5e0f4..b1f9b4032fd9 100644 --- a/usr.sbin/pppd/ipcp.h +++ b/usr.sbin/pppd/ipcp.h @@ -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.3 1994/04/18 04:05:15 paulus Exp $ + * $Id: ipcp.h,v 1.5 1994/09/21 06:47:37 paulus Exp $ */ /* @@ -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 *)); diff --git a/usr.sbin/pppd/lcp.c b/usr.sbin/pppd/lcp.c index 25815187e9a6..f9d6c1cc9b9c 100644 --- a/usr.sbin/pppd/lcp.c +++ b/usr.sbin/pppd/lcp.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: lcp.c,v 1.8 1994/05/30 02:38:49 paulus 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.8 1994/05/30 02:38:49 paulus Exp $"; #include #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.8 1994/05/30 02:38:49 paulus Exp $"; #include "ipcp.h" #ifdef _linux_ /* Needs ppp ioctls */ -#include +#include +#include #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); + } } @@ -282,8 +354,6 @@ lcp_extcode(f, code, id, inp, len) 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; @@ -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; /* @@ -1625,6 +1791,11 @@ lcp_echo_lowerup (unit) /* 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 } diff --git a/usr.sbin/pppd/lcp.h b/usr.sbin/pppd/lcp.h index 0499a7cbd0d2..271ddc5ef3b6 100644 --- a/usr.sbin/pppd/lcp.h +++ b/usr.sbin/pppd/lcp.h @@ -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 diff --git a/usr.sbin/pppd/lock.c b/usr.sbin/pppd/lock.c deleted file mode 100644 index 0fbbef33b0e7..000000000000 --- a/usr.sbin/pppd/lock.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * lock.c - lock/unlock the serial device. - * - * This code is derived from chat.c. - */ - -static char rcsid[] = "$Id: lock.c,v 1.1 1994/04/18 23:41:52 paulus Exp $"; - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef sun -# if defined(SUNOS) && SUNOS >= 41 -# ifndef HDB -# define HDB -# endif -# endif -#endif - -#ifndef LOCK_DIR -# ifdef __NetBSD__ -# define PIDSTRING -# define LOCK_PREFIX "/var/spool/lock/LCK.." -# else -# ifdef HDB -# define PIDSTRING -# define LOCK_PREFIX "/usr/spool/locks/LCK.." -# else /* HDB */ -# define LOCK_PREFIX "/usr/spool/uucp/LCK.." -# endif /* HDB */ -# endif -#endif /* LOCK_DIR */ - -static char *lock_file; - -/* - * Create a lock file for the named lock device - */ -int -lock(dev) - char *dev; -{ - char hdb_lock_buffer[12]; - int fd, pid, n; - char *p; - - 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); - - 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 */ -#ifdef PIDSTRING - n = read(fd, hdb_lock_buffer, 11); - if (n > 0) { - hdb_lock_buffer[n] = 0; - pid = atoi(hdb_lock_buffer); - } -#else - n = read(fd, &pid, sizeof(pid)); -#endif - 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; - } - -# ifdef PIDSTRING - sprintf(hdb_lock_buffer, "%10d\n", getpid()); - write(fd, hdb_lock_buffer, 11); -# else - pid = getpid(); - write(fd, &pid, sizeof pid); -# endif - - close(fd); - return 0; -} - -/* - * Remove our lockfile - */ -unlock() -{ - if (lock_file) { - unlink(lock_file); - free(lock_file); - lock_file = NULL; - } -} - diff --git a/usr.sbin/pppd/magic.c b/usr.sbin/pppd/magic.c index 20dfd6fe3a48..4797f0b19fd6 100644 --- a/usr.sbin/pppd/magic.c +++ b/usr.sbin/pppd/magic.c @@ -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 #include #include +#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 diff --git a/usr.sbin/pppd/magic.h b/usr.sbin/pppd/magic.h index d41aa39df7db..a118ca1afb9c 100644 --- a/usr.sbin/pppd/magic.h +++ b/usr.sbin/pppd/magic.h @@ -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 */ diff --git a/usr.sbin/pppd/main.c b/usr.sbin/pppd/main.c index 1e1397e55053..f4913ff28e77 100644 --- a/usr.sbin/pppd/main.c +++ b/usr.sbin/pppd/main.c @@ -18,12 +18,11 @@ */ #ifndef lint -static char rcsid[] = "$Id: main.c,v 1.13 1994/05/27 01:02:14 paulus Exp $"; +static char rcsid[] = "$Id: main.c,v 1.27 1995/08/16 01:39:08 paulus Exp $"; #endif -#define SETSID - #include +#include #include #include #include @@ -32,7 +31,25 @@ static char rcsid[] = "$Id: main.c,v 1.13 1994/05/27 01:02:14 paulus Exp $"; #include #include #include +#include +#include #include +#include +#include +#include +#include +#include + +#include "pppd.h" +#include "magic.h" +#include "fsm.h" +#include "lcp.h" +#include "ipcp.h" +#include "upap.h" +#include "chap.h" +#include "ccp.h" +#include "pathnames.h" +#include "patchlevel.h" /* * If REQ_SYSOPTIONS is defined to 1, pppd will not run unless @@ -42,134 +59,66 @@ static char rcsid[] = "$Id: main.c,v 1.13 1994/05/27 01:02:14 paulus Exp $"; #define REQ_SYSOPTIONS 1 #endif -#ifdef SGTTY -#include -#else -#ifndef sun -#include -#endif -#include -#endif - -#include -#include -#include -#include -#include -#include - -#include "callout.h" -#include "ppp.h" -#include "magic.h" -#include "fsm.h" -#include "lcp.h" -#include "ipcp.h" -#include "upap.h" -#include "chap.h" - -#include "pppd.h" -#include "pathnames.h" -#include "patchlevel.h" - - -#ifndef TRUE -#define TRUE (1) -#endif /*TRUE*/ - -#ifndef FALSE -#define FALSE (0) -#endif /*FALSE*/ - -#ifdef PIDPATH -static char *pidpath = PIDPATH; /* filename in which pid will be stored */ -#else -static char *pidpath = _PATH_PIDFILE; -#endif /* PIDFILE */ - /* interface vars */ char ifname[IFNAMSIZ]; /* Interface name */ int ifunit; /* Interface unit number */ char *progname; /* Name of this program */ char hostname[MAXNAMELEN]; /* Our hostname */ -char our_name[MAXNAMELEN]; -char remote_name[MAXNAMELEN]; -static char pidfilename[MAXPATHLEN]; - +static char pidfilename[MAXPATHLEN]; /* name of pid file */ +static char default_devnam[MAXPATHLEN]; /* name of default device */ static pid_t pid; /* Our pid */ static pid_t pgrpid; /* Process Group ID */ -uid_t uid; /* Our real user-id */ - -char devname[MAXPATHLEN] = "/dev/tty"; /* Device name */ -int default_device = TRUE; /* use default device (stdin/out) */ +static uid_t uid; /* Our real user-id */ int fd = -1; /* Device file descriptor */ -int s; /* Socket file descriptor */ int phase; /* where the link is at */ - -#ifdef SGTTY -static struct sgttyb initsgttyb; /* Initial TTY sgttyb */ -#else -static struct termios inittermios; /* Initial TTY termios */ -#endif +int kill_link; +int open_ccp_flag; static int initfdflags = -1; /* Initial file descriptor flags */ -static int restore_term; /* 1 => we've munged the terminal */ - -u_char outpacket_buf[MTU+DLLHEADERLEN]; /* buffer for outgoing packet */ -static u_char inpacket_buf[MTU+DLLHEADERLEN]; /* buffer for incoming packet */ +u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ +static u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ int hungup; /* terminal has been hung up */ static int n_children; /* # child processes still running */ -/* configured variables */ - -int debug = 0; /* Debug flag */ -int kdebugflag = 0; /* Kernel debugging flag */ -char user[MAXNAMELEN]; /* username for PAP */ -char passwd[MAXSECRETLEN]; /* password for PAP */ -char *connector = NULL; /* "connect" command */ -char *disconnector = NULL; /* "disconnect" command */ -int inspeed = 0; /* Input/Output speed requested */ -int baud_rate; /* bits/sec currently used */ -u_long netmask = 0; /* netmask to use on ppp interface */ -int crtscts = 0; /* use h/w flow control */ -int nodetach = 0; /* don't fork */ -int modem = 0; /* use modem control lines */ -int auth_required = 0; /* require peer to authenticate */ -int defaultroute = 0; /* assign default route through interface */ -int proxyarp = 0; /* set entry in arp table */ -int persist = 0; /* re-initiate on termination */ -int answer = 0; /* wait for incoming call */ -int uselogin = 0; /* check PAP info against /etc/passwd */ -int lockflag = 0; /* lock the serial device */ +int baud_rate; +char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; /* prototypes */ -static void hup __ARGS((int)); -static void intr __ARGS((int)); -static void term __ARGS((int)); -static void alrm __ARGS((int)); -static void io __ARGS((int)); -static void chld __ARGS((int)); -static void incdebug __ARGS((int)); -static void nodebug __ARGS((int)); -void establish_ppp __ARGS((void)); +static void hup __P((int)); +static void term __P((int)); +static void chld __P((int)); +static void toggle_debug __P((int)); +static void open_ccp __P((int)); +static void bad_signal __P((int)); -void reap_kids __ARGS((void)); -void cleanup __ARGS((int, caddr_t)); -void die __ARGS((int)); -void novm __ARGS((char *)); +static void get_input __P((void)); +void establish_ppp __P((void)); +void calltimeout __P((void)); +struct timeval *timeleft __P((struct timeval *)); +void reap_kids __P((void)); +void cleanup __P((int, caddr_t)); +void close_fd __P((void)); +void die __P((int)); +void novm __P((char *)); -void log_packet __ARGS((u_char *, int, char *)); -void format_packet __ARGS((u_char *, int, +void log_packet __P((u_char *, int, char *)); +void format_packet __P((u_char *, int, void (*) (void *, char *, ...), void *)); -void pr_log __ARGS((void *, char *, ...)); +void pr_log __P((void *, char *, ...)); -extern char *ttyname __ARGS((int)); -extern char *getlogin __ARGS((void)); +extern char *ttyname __P((int)); +extern char *getlogin __P((void)); + +#ifdef ultrix +#undef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif /* * PPP Data Link Layer "protocol" table. @@ -181,12 +130,19 @@ static struct protent { void (*input)(); void (*protrej)(); int (*printpkt)(); + void (*datainput)(); char *name; } prottbl[] = { - { LCP, lcp_init, lcp_input, lcp_protrej, lcp_printpkt, "LCP" }, - { IPCP, ipcp_init, ipcp_input, ipcp_protrej, ipcp_printpkt, "IPCP" }, - { UPAP, upap_init, upap_input, upap_protrej, upap_printpkt, "PAP" }, - { CHAP, ChapInit, ChapInput, ChapProtocolReject, ChapPrintPkt, "CHAP" }, + { PPP_LCP, lcp_init, lcp_input, lcp_protrej, + lcp_printpkt, NULL, "LCP" }, + { PPP_IPCP, ipcp_init, ipcp_input, ipcp_protrej, + ipcp_printpkt, NULL, "IPCP" }, + { PPP_PAP, upap_init, upap_input, upap_protrej, + upap_printpkt, NULL, "PAP" }, + { PPP_CHAP, ChapInit, ChapInput, ChapProtocolReject, + ChapPrintPkt, NULL, "CHAP" }, + { PPP_CCP, ccp_init, ccp_input, ccp_protrej, + ccp_printpkt, ccp_datainput, "CCP" }, }; #define N_PROTO (sizeof(prottbl) / sizeof(prottbl[0])) @@ -195,28 +151,30 @@ main(argc, argv) int argc; char *argv[]; { - int mask, i; + int i, nonblock; struct sigaction sa; struct cmd *cmdp; FILE *pidfile; char *p; struct passwd *pw; + struct timeval timo; + sigset_t mask; p = ttyname(0); if (p) - strcpy(devname, p); - + strcpy(devnam, p); + strcpy(default_devnam, devnam); + if (gethostname(hostname, MAXNAMELEN) < 0 ) { perror("couldn't get hostname"); die(1); } hostname[MAXNAMELEN-1] = 0; - pid = getpid(); uid = getuid(); if (!ppp_available()) { - fprintf(stderr, "Sorry - PPP is not available on this system\n"); + fprintf(stderr, no_ppp_msg); exit(1); } @@ -239,21 +197,27 @@ main(argc, argv) setipdefault(); /* - * Initialize syslog system and magic number package. + * If the user has specified the default device name explicitly, + * pretend they hadn't. */ -#if !defined(ultrix) - openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); - setlogmask(LOG_UPTO(LOG_INFO)); -#else - openlog("pppd", LOG_PID); -#define LOG_UPTO(x) (x) -#define setlogmask(x) (x) -#endif - if (debug) - setlogmask(LOG_UPTO(LOG_DEBUG)); + if (!default_device && strcmp(devnam, default_devnam) == 0) + default_device = 1; + /* + * Initialize system-dependent stuff and magic number package. + */ + sys_init(); magic_init(); + /* + * Detach ourselves from the terminal, if required, + * and identify who is running us. + */ + if (!default_device && !nodetach && daemon(0, 0) < 0) { + perror("Couldn't detach from controlling terminal"); + exit(1); + } + pid = getpid(); p = getlogin(); if (p == NULL) { pw = getpwuid(uid); @@ -264,63 +228,6 @@ main(argc, argv) } syslog(LOG_NOTICE, "pppd %s.%d started by %s, uid %d", VERSION, PATCHLEVEL, p, uid); - -#ifdef SETSID - /* - * Make sure we can set the serial device to be our controlling terminal. - */ - if (default_device) { - /* - * No device name was specified: - * we are in the device's session already. - */ - if ((pgrpid = getpgrp(0)) < 0) { - syslog(LOG_ERR, "getpgrp(0): %m"); - die(1); - } - - } else { - /* - * Not default device: make sure we're not a process group leader, - * then become session leader of a new session (so we can make - * our device its controlling terminal and thus get SIGHUPs). - */ - if (!nodetach) { - /* fork so we're not a process group leader */ - if (pid = fork()) { - exit(0); /* parent is finished */ - } - if (pid < 0) { - syslog(LOG_ERR, "fork: %m"); - die(1); - } - pid = getpid(); /* otherwise pid is 0 in child */ - } else { - /* - * try to put ourself into our parent's process group, - * so we're not a process group leader - */ - if (setpgrp(pid, getppid()) < 0) - syslog(LOG_WARNING, "setpgrp: %m"); - } - - /* create new session */ - if ((pgrpid = setsid()) < 0) { - syslog(LOG_ERR, "setsid(): %m"); - die(1); - } - } -#endif - - if (lockflag && !default_device) - if (lock(devname) < 0) - die(1); - - /* Get an internet socket for doing socket ioctl's on. */ - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - syslog(LOG_ERR, "socket : %m"); - die(1); - } /* * Compute mask of all interesting signals and install signal handlers @@ -330,17 +237,13 @@ main(argc, argv) sigemptyset(&mask); sigaddset(&mask, SIGHUP); sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGALRM); - sigaddset(&mask, SIGIO); + sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGCHLD); -#ifdef STREAMS - sigaddset(&mask, SIGPOLL); -#endif #define SIGNAL(s, handler) { \ sa.sa_handler = handler; \ if (sigaction(s, &sa, NULL) < 0) { \ - syslog(LOG_ERR, "sigaction(%d): %m", s); \ + syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \ die(1); \ } \ } @@ -348,393 +251,296 @@ main(argc, argv) sa.sa_mask = mask; sa.sa_flags = 0; SIGNAL(SIGHUP, hup); /* Hangup */ - SIGNAL(SIGINT, intr); /* Interrupt */ + SIGNAL(SIGINT, term); /* Interrupt */ SIGNAL(SIGTERM, term); /* Terminate */ - SIGNAL(SIGALRM, alrm); /* Timeout */ - SIGNAL(SIGIO, io); /* Input available */ - SIGNAL(SIGCHLD, chld); /* Death of child process */ -#ifdef STREAMS - SIGNAL(SIGPOLL, io); /* Input available */ -#endif + SIGNAL(SIGCHLD, chld); - signal(SIGUSR1, incdebug); /* Increment debug flag */ - signal(SIGUSR2, nodebug); /* Reset debug flag */ + SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ + SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ /* - * Block SIGIOs and SIGPOLLs for now + * Install a handler for other signals which would otherwise + * cause pppd to exit without cleaning up. */ - sigemptyset(&mask); - sigaddset(&mask, SIGIO); -#ifdef STREAMS - sigaddset(&mask, SIGPOLL); + SIGNAL(SIGABRT, bad_signal); + SIGNAL(SIGALRM, bad_signal); + SIGNAL(SIGFPE, bad_signal); + SIGNAL(SIGILL, bad_signal); + SIGNAL(SIGPIPE, bad_signal); + SIGNAL(SIGQUIT, bad_signal); + SIGNAL(SIGSEGV, bad_signal); +#ifdef SIGBUS + SIGNAL(SIGBUS, bad_signal); +#endif +#ifdef SIGEMT + SIGNAL(SIGEMT, bad_signal); +#endif +#ifdef SIGPOLL + SIGNAL(SIGPOLL, bad_signal); +#endif +#ifdef SIGPROF + SIGNAL(SIGPROF, bad_signal); +#endif +#ifdef SIGSYS + SIGNAL(SIGSYS, bad_signal); +#endif +#ifdef SIGTRAP + SIGNAL(SIGTRAP, bad_signal); +#endif +#ifdef SIGVTALRM + SIGNAL(SIGVTALRM, bad_signal); +#endif +#ifdef SIGXCPU + SIGNAL(SIGXCPU, bad_signal); +#endif +#ifdef SIGXFSZ + SIGNAL(SIGXFSZ, bad_signal); #endif - sigprocmask(SIG_BLOCK, &mask, NULL); /* - * Open the serial device and set it up to be the ppp interface. + * Lock the device if we've been asked to. */ - if ((fd = open(devname, O_RDWR /*| O_NDELAY*/)) < 0) { - syslog(LOG_ERR, "open(%s): %m", devname); - die(1); - } - hungup = 0; + if (lockflag && !default_device) + if (lock(devnam) < 0) + die(1); -#ifdef TIOCSCTTY - /* set device to be controlling tty */ - if (!default_device && ioctl(fd, TIOCSCTTY) < 0) { - syslog(LOG_ERR, "ioctl(TIOCSCTTY): %m"); - die(1); - } -#endif /* TIOCSCTTY */ + do { - /* run connection script */ - if (connector) { - MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector)); - - /* set line speed, flow control, etc.; set CLOCAL for now */ - set_up_tty(fd, 1); - - /* drop dtr to hang up in case modem is off hook */ - if (!default_device && modem) { - setdtr(fd, FALSE); - sleep(1); - setdtr(fd, TRUE); - } - - if (device_script(connector, fd, fd) < 0) { - syslog(LOG_ERR, "could not set up connection"); - setdtr(fd, FALSE); + /* + * Open the serial device and set it up to be the ppp interface. + * If we're dialling out, or we don't want to use the modem lines, + * we open it in non-blocking mode, but then we need to clear + * the non-blocking I/O bit. + */ + nonblock = (connector || !modem)? O_NONBLOCK: 0; + if ((fd = open(devnam, nonblock | O_RDWR, 0)) < 0) { + syslog(LOG_ERR, "Failed to open %s: %m", devnam); die(1); } + if ((initfdflags = fcntl(fd, F_GETFL)) == -1) { + syslog(LOG_ERR, "Couldn't get device fd flags: %m"); + die(1); + } + if (nonblock) { + initfdflags &= ~O_NONBLOCK; + fcntl(fd, F_SETFL, initfdflags); + } + hungup = 0; + kill_link = 0; - syslog(LOG_INFO, "Connected..."); - sleep(1); /* give it time to set up its terminal */ - } + /* run connection script */ + if (connector && connector[0]) { + MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector)); + + /* set line speed, flow control, etc.; set CLOCAL for now */ + set_up_tty(fd, 1); + + /* drop dtr to hang up in case modem is off hook */ + if (!default_device && modem) { + setdtr(fd, FALSE); + sleep(1); + setdtr(fd, TRUE); + } + + if (device_script(connector, fd, fd) < 0) { + syslog(LOG_ERR, "Connect script failed"); + setdtr(fd, FALSE); + die(1); + } + + syslog(LOG_INFO, "Serial connection established."); + sleep(1); /* give it time to set up its terminal */ + } + + /* set line speed, flow control, etc.; clear CLOCAL if modem option */ + set_up_tty(fd, 0); + + /* set up the serial device as a ppp interface */ + establish_ppp(); + + syslog(LOG_INFO, "Using interface ppp%d", ifunit); + (void) sprintf(ifname, "ppp%d", ifunit); + + /* write pid to file */ + (void) sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname); + if ((pidfile = fopen(pidfilename, "w")) != NULL) { + fprintf(pidfile, "%d\n", pid); + (void) fclose(pidfile); + } else { + syslog(LOG_ERR, "Failed to create pid file %s: %m", pidfilename); + pidfilename[0] = 0; + } + + /* + * Set device for non-blocking reads. + */ + if (fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) { + syslog(LOG_ERR, "Couldn't set device to non-blocking mode: %m"); + die(1); + } - /* set line speed, flow control, etc.; clear CLOCAL if modem option */ - set_up_tty(fd, 0); + /* + * Block all signals, start opening the connection, and wait for + * incoming events (reply, timeout, etc.). + */ + syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam); + lcp_lowerup(0); + lcp_open(0); /* Start protocol */ + for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) { + wait_input(timeleft(&timo)); + calltimeout(); + get_input(); + if (kill_link) { + lcp_close(0); + kill_link = 0; + } + if (open_ccp_flag) { + if (phase == PHASE_NETWORK) { + ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ + ccp_open(0); + } + open_ccp_flag = 0; + } + reap_kids(); /* Don't leave dead kids lying around */ + } - /* set up the serial device as a ppp interface */ - establish_ppp(); + /* + * Run disconnector script, if requested. + * First we need to reset non-blocking mode. + * XXX we may not be able to do this if the line has hung up! + */ + if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) >= 0) + initfdflags = -1; + disestablish_ppp(); + if (disconnector) { + set_up_tty(fd, 1); + if (device_script(disconnector, fd, fd) < 0) { + syslog(LOG_WARNING, "disconnect script failed"); + } else { + syslog(LOG_INFO, "Serial link disconnected."); + } + } - syslog(LOG_INFO, "Using interface ppp%d", ifunit); - (void) sprintf(ifname, "ppp%d", ifunit); - - /* write pid to file */ - (void) sprintf(pidfilename, "%s/%s.pid", pidpath, ifname); - if ((pidfile = fopen(pidfilename, "w")) != NULL) { - fprintf(pidfile, "%d\n", pid); - (void) fclose(pidfile); - } else { - syslog(LOG_ERR, "unable to create pid file: %m"); + close_fd(); + if (unlink(pidfilename) < 0 && errno != ENOENT) + syslog(LOG_WARNING, "unable to delete pid file: %m"); pidfilename[0] = 0; + + } while (persist); + + die(0); +} + + +/* + * get_input - called when incoming data is available. + */ +static void +get_input() +{ + int len, i; + u_char *p; + u_short protocol; + + p = inpacket_buf; /* point to beginning of packet buffer */ + + len = read_packet(inpacket_buf); + if (len < 0) + return; + + if (len == 0) { + syslog(LOG_NOTICE, "Modem hangup"); + hungup = 1; + lcp_lowerdown(0); /* serial link is no longer available */ + phase = PHASE_DEAD; + return; + } + + if (debug /*&& (debugflags & DBG_INPACKET)*/) + log_packet(p, len, "rcvd "); + + if (len < PPP_HDRLEN) { + MAINDEBUG((LOG_INFO, "io(): Received short packet.")); + return; + } + + p += 2; /* Skip address and control */ + GETSHORT(protocol, p); + len -= PPP_HDRLEN; + + /* + * Toss all non-LCP packets unless LCP is OPEN. + */ + if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { + MAINDEBUG((LOG_INFO, + "io(): Received non-LCP packet when LCP not open.")); + return; } /* - * Set process group of device to our process group so we can get - * SIGIOs and SIGHUPs. + * Upcall the proper protocol input routine. */ -#ifdef SETSID - if (default_device) { - int id = tcgetpgrp(fd); - if (id != pgrpid) { - syslog(LOG_WARNING, "warning: not in tty's process group"); + for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++) { + if (prottbl[i].protocol == protocol) { + (*prottbl[i].input)(0, p, len); + return; } - } else { - if (tcsetpgrp(fd, pgrpid) < 0) { - syslog(LOG_ERR, "tcsetpgrp(): %m"); - die(1); + if (protocol == (prottbl[i].protocol & ~0x8000) + && prottbl[i].datainput != NULL) { + (*prottbl[i].datainput)(0, p, len); + return; } } -#else - /* set process group on tty so we get SIGIO's */ - if (ioctl(fd, TIOCSPGRP, &pgrpid) < 0) { - syslog(LOG_ERR, "ioctl(TIOCSPGRP): %m"); - die(1); - } -#endif + + if (debug) + syslog(LOG_WARNING, "Unknown protocol (0x%x) received", protocol); + lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); +} + + +/* + * demuxprotrej - Demultiplex a Protocol-Reject. + */ +void +demuxprotrej(unit, protocol) + int unit; + u_short protocol; +{ + int i; /* - * Record initial device flags, then set device to cause SIGIO - * signals to be generated. + * Upcall the proper Protocol-Reject routine. */ - if ((initfdflags = fcntl(fd, F_GETFL)) == -1) { - syslog(LOG_ERR, "fcntl(F_GETFL): %m"); - die(1); - } - -#ifdef _linux_ /* This is a kludge for Linux. FIXME !!! -- later. */ -#undef FASYNC -#define FASYNC 0 -#endif - - if (fcntl(fd, F_SETFL, FNDELAY | FASYNC) == -1) { - syslog(LOG_ERR, "fcntl(F_SETFL, FNDELAY | FASYNC): %m"); - die(1); - } - - /* - * Block all signals, start opening the connection, and wait for - * incoming signals (reply, timeout, etc.). - */ - syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devname); - sigprocmask(SIG_BLOCK, &mask, NULL); /* Block signals now */ - lcp_lowerup(0); /* XXX Well, sort of... */ - lcp_open(0); /* Start protocol */ - for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) - sigpause(0); /* Wait for next signal */ - - /* - * Run disconnector script, if requested - */ - if (disconnector) { - if (device_script(disconnector, fd, fd) < 0) { - syslog(LOG_WARNING, "disconnect script failed"); - die(1); + for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++) + if (prottbl[i].protocol == protocol) { + (*prottbl[i].protrej)(unit); + return; } - syslog(LOG_INFO, "Disconnected..."); - } - - quit(); + syslog(LOG_WARNING, + "demuxprotrej: Unrecognized Protocol-Reject for protocol 0x%x", + protocol); } -#if B9600 == 9600 -/* - * XXX assume speed_t values numerically equal bits per second - * (so we can ask for any speed). - */ -#define translate_speed(bps) (bps) -#define baud_rate_of(speed) (speed) - -#else -/* - * List of valid speeds. - */ -struct speed { - int speed_int, speed_val; -} speeds[] = { -#ifdef B50 - { 50, B50 }, -#endif -#ifdef B75 - { 75, B75 }, -#endif -#ifdef B110 - { 110, B110 }, -#endif -#ifdef B134 - { 134, B134 }, -#endif -#ifdef B150 - { 150, B150 }, -#endif -#ifdef B200 - { 200, B200 }, -#endif -#ifdef B300 - { 300, B300 }, -#endif -#ifdef B600 - { 600, B600 }, -#endif -#ifdef B1200 - { 1200, B1200 }, -#endif -#ifdef B1800 - { 1800, B1800 }, -#endif -#ifdef B2000 - { 2000, B2000 }, -#endif -#ifdef B2400 - { 2400, B2400 }, -#endif -#ifdef B3600 - { 3600, B3600 }, -#endif -#ifdef B4800 - { 4800, B4800 }, -#endif -#ifdef B7200 - { 7200, B7200 }, -#endif -#ifdef B9600 - { 9600, B9600 }, -#endif -#ifdef B19200 - { 19200, B19200 }, -#endif -#ifdef B38400 - { 38400, B38400 }, -#endif -#ifdef EXTA - { 19200, EXTA }, -#endif -#ifdef EXTB - { 38400, EXTB }, -#endif -#ifdef B57600 - { 57600, B57600 }, -#endif -#ifdef B115200 - { 115200, B115200 }, -#endif - { 0, 0 } -}; /* - * Translate from bits/second to a speed_t. + * bad_signal - We've caught a fatal signal. Clean up state and exit. */ -int -translate_speed(bps) - int bps; +static void +bad_signal(sig) + int sig; { - struct speed *speedp; - - if (bps == 0) - return 0; - for (speedp = speeds; speedp->speed_int; speedp++) - if (bps == speedp->speed_int) - return speedp->speed_val; - syslog(LOG_WARNING, "speed %d not supported", bps); - return 0; + syslog(LOG_ERR, "Fatal signal %d", sig); + die(1); } /* - * Translate from a speed_t to bits/second. - */ -int -baud_rate_of(speed) - int speed; -{ - struct speed *speedp; - - if (speed == 0) - return 0; - for (speedp = speeds; speedp->speed_int; speedp++) - if (speed == speedp->speed_val) - return speedp->speed_int; - return 0; -} -#endif - -/* - * 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. - */ -set_up_tty(fd, local) - int fd, local; -{ -#ifndef SGTTY - int speed, x; - struct termios tios; - - if (tcgetattr(fd, &tios) < 0) { - syslog(LOG_ERR, "tcgetattr: %m"); - die(1); - } - - if (!restore_term) - inittermios = tios; - -#ifdef CRTSCTS - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL | CRTSCTS); - if (crtscts == 1) - tios.c_cflag |= CRTSCTS; -#else - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); -#endif /* 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 */ - } - - speed = translate_speed(inspeed); - if (speed) { - cfsetospeed(&tios, speed); - cfsetispeed(&tios, speed); - } else { - speed = cfgetospeed(&tios); - } - - if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { - syslog(LOG_ERR, "tcsetattr: %m"); - die(1); - } - -#ifdef ultrix - x = 0; - if (ioctl(fd, (crtscts || modem)? TIOCMODEM: TIOCNMODEM, &x) < 0) - syslog(LOG_WARNING, "TIOC(N)MODEM: %m"); - if (ioctl(fd, (local || !modem)? TIOCNCAR: TIOCCAR) < 0) - syslog(LOG_WARNING, "TIOC(N)CAR: %m"); -#endif - -#else /* SGTTY */ - int speed; - struct sgttyb sgttyb; - - /* - * Put the tty in raw mode. - */ - if (ioctl(fd, TIOCGETP, &sgttyb) < 0) { - syslog(LOG_ERR, "ioctl(TIOCGETP): %m"); - die(1); - } - - if (!restore_term) - initsgttyb = sgttyb; - - sgttyb.sg_flags = RAW | ANYP; - speed = translate_speed(inspeed); - if (speed) - sgttyb.sg_ispeed = speed; - else - speed = sgttyb.sg_ispeed; - - if (ioctl(fd, TIOCSETP, &sgttyb) < 0) { - syslog(LOG_ERR, "ioctl(TIOCSETP): %m"); - die(1); - } -#endif - - baud_rate = baud_rate_of(speed); - restore_term = TRUE; -} - -/* - * 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); -} - - -/* - * quit - Clean up state and exit. + * quit - Clean up state and exit (with an error indication). */ void quit() { - die(0); + die(1); } /* @@ -758,42 +564,49 @@ cleanup(status, arg) int status; caddr_t arg; { - if (fd >= 0) { - /* drop dtr to hang up */ - if (modem) - setdtr(fd, FALSE); + if (fd >= 0) + close_fd(); - if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) < 0) - syslog(LOG_WARNING, "fcntl(F_SETFL, fdflags): %m"); - initfdflags = -1; - - disestablish_ppp(); - - if (restore_term) { -#ifndef SGTTY - if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0) - syslog(LOG_WARNING, "tcsetattr: %m"); -#else - if (ioctl(fd, TIOCSETP, &initsgttyb) < 0) - syslog(LOG_WARNING, "ioctl(TIOCSETP): %m"); -#endif - } - - close(fd); - fd = -1; - } - - if (pidfilename[0] != 0 && unlink(pidfilename) < 0) - syslog(LOG_WARNING, "unable to unlink pid file: %m"); + if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) + syslog(LOG_WARNING, "unable to delete pid file: %m"); pidfilename[0] = 0; if (lockflag && !default_device) unlock(); } +/* + * close_fd - restore the terminal device and close it. + */ +void +close_fd() +{ + disestablish_ppp(); -static struct callout *callout = NULL; /* Callout list */ -static struct timeval schedtime; /* Time last timeout was set */ + /* drop dtr to hang up */ + if (modem) + setdtr(fd, FALSE); + + if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) < 0) + syslog(LOG_WARNING, "Couldn't restore device fd flags: %m"); + initfdflags = -1; + + restore_tty(); + + close(fd); + fd = -1; +} + + +struct callout { + struct timeval c_time; /* time at which to call routine */ + caddr_t c_arg; /* argument to routine */ + void (*c_func)(); /* routine */ + struct callout *c_next; +}; + +static struct callout *callout = NULL; /* Callout list */ +static struct timeval timenow; /* Current time */ /* * timeout - Schedule a timeout. @@ -807,11 +620,10 @@ timeout(func, arg, time) caddr_t arg; int time; { - struct itimerval itv; - struct callout *newp, **oldpp; + struct callout *newp, *p, **pp; - MAINDEBUG((LOG_DEBUG, "Timeout %x:%x in %d seconds.", - (int) func, (int) arg, time)); + MAINDEBUG((LOG_DEBUG, "Timeout %lx:%lx in %d seconds.", + (long) func, (long) arg, time)); /* * Allocate timeout. @@ -822,40 +634,20 @@ timeout(func, arg, time) } newp->c_arg = arg; newp->c_func = func; + gettimeofday(&timenow, NULL); + newp->c_time.tv_sec = timenow.tv_sec + time; + newp->c_time.tv_usec = timenow.tv_usec; /* - * Find correct place to link it in and decrement its time by the - * amount of time used by preceding timeouts. + * Find correct place and link it in. */ - for (oldpp = &callout; - *oldpp && (*oldpp)->c_time <= time; - oldpp = &(*oldpp)->c_next) - time -= (*oldpp)->c_time; - newp->c_time = time; - newp->c_next = *oldpp; - if (*oldpp) - (*oldpp)->c_time -= time; - *oldpp = newp; - - /* - * If this is now the first callout then we have to set a new - * itimer. - */ - if (callout == newp) { - itv.it_interval.tv_sec = itv.it_interval.tv_usec = - itv.it_value.tv_usec = 0; - itv.it_value.tv_sec = callout->c_time; - MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds in timeout.", - itv.it_value.tv_sec)); - if (setitimer(ITIMER_REAL, &itv, NULL)) { - syslog(LOG_ERR, "setitimer(ITIMER_REAL): %m"); - die(1); - } - if (gettimeofday(&schedtime, NULL)) { - syslog(LOG_ERR, "gettimeofday: %m"); - die(1); - } - } + for (pp = &callout; (p = *pp); pp = &p->c_next) + if (newp->c_time.tv_sec < p->c_time.tv_sec + || (newp->c_time.tv_sec == p->c_time.tv_sec + && newp->c_time.tv_usec < p->c_time.tv_sec)) + break; + newp->c_next = p; + *pp = newp; } @@ -871,187 +663,101 @@ untimeout(func, arg) struct callout **copp, *freep; int reschedule = 0; - MAINDEBUG((LOG_DEBUG, "Untimeout %x:%x.", (int) func, (int) arg)); + MAINDEBUG((LOG_DEBUG, "Untimeout %lx:%lx.", (long) func, (long) arg)); /* - * If the first callout is unscheduled then we have to set a new - * itimer. + * Find first matching timeout and remove it from the list. */ - if (callout && - callout->c_func == func && - callout->c_arg == arg) - reschedule = 1; - - /* - * Find first matching timeout. Add its time to the next timeouts - * time. - */ - for (copp = &callout; *copp; copp = &(*copp)->c_next) - if ((*copp)->c_func == func && - (*copp)->c_arg == arg) { - freep = *copp; + for (copp = &callout; (freep = *copp); copp = &freep->c_next) + if (freep->c_func == func && freep->c_arg == arg) { *copp = freep->c_next; - if (*copp) - (*copp)->c_time += freep->c_time; (void) free((char *) freep); break; } - - if (reschedule) { - itv.it_interval.tv_sec = itv.it_interval.tv_usec = - itv.it_value.tv_usec = 0; - itv.it_value.tv_sec = callout ? callout->c_time : 0; - MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds in untimeout.", - itv.it_value.tv_sec)); - if (setitimer(ITIMER_REAL, &itv, NULL)) { - syslog(LOG_ERR, "setitimer(ITIMER_REAL): %m"); - die(1); - } - if (gettimeofday(&schedtime, NULL)) { - syslog(LOG_ERR, "gettimeofday: %m"); +} + + +/* + * calltimeout - Call any timeout routines which are now due. + */ +void +calltimeout() +{ + struct callout *p; + + while (callout != NULL) { + p = callout; + + if (gettimeofday(&timenow, NULL) < 0) { + syslog(LOG_ERR, "Failed to get time of day: %m"); die(1); } + if (!(p->c_time.tv_sec < timenow.tv_sec + || (p->c_time.tv_sec == timenow.tv_sec + && p->c_time.tv_usec <= timenow.tv_usec))) + break; /* no, it's not time yet */ + + callout = p->c_next; + (*p->c_func)(p->c_arg); + + free((char *) p); } } /* - * adjtimeout - Decrement the first timeout by the amount of time since - * it was scheduled. + * timeleft - return the length of time until the next timeout is due. */ -void -adjtimeout() +struct timeval * +timeleft(tvp) + struct timeval *tvp; { - struct timeval tv; - int timediff; - if (callout == NULL) - return; - /* - * Make sure that the clock hasn't been warped dramatically. - * Account for recently expired, but blocked timer by adding - * small fudge factor. - */ - if (gettimeofday(&tv, NULL)) { - syslog(LOG_ERR, "gettimeofday: %m"); - die(1); - } - timediff = tv.tv_sec - schedtime.tv_sec; - if (timediff < 0 || - timediff > callout->c_time + 1) - return; - - callout->c_time -= timediff; /* OK, Adjust time */ -} + return NULL; + gettimeofday(&timenow, NULL); + tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; + tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec; + if (tvp->tv_usec < 0) { + tvp->tv_usec += 1000000; + tvp->tv_sec -= 1; + } + if (tvp->tv_sec < 0) + tvp->tv_sec = tvp->tv_usec = 0; + + return tvp; +} + /* * hup - Catch SIGHUP signal. * * Indicates that the physical layer has been disconnected. + * We don't rely on this indication; if the user has sent this + * signal, we just take the link down. */ static void hup(sig) int sig; { syslog(LOG_INFO, "Hangup (SIGHUP)"); - - hungup = 1; /* they hung up on us! */ - persist = 0; /* don't try to restart */ - adjtimeout(); /* Adjust timeouts */ - lcp_lowerdown(0); /* Reset connection */ - quit(); /* and die */ + kill_link = 1; } /* - * term - Catch SIGTERM signal. + * term - Catch SIGTERM signal and SIGINT signal (^C/del). * * Indicates that we should initiate a graceful disconnect and exit. */ +/*ARGSUSED*/ static void term(sig) int sig; { - syslog(LOG_INFO, "Terminating link."); + syslog(LOG_INFO, "Terminating on signal %d.", sig); persist = 0; /* don't try to restart */ - adjtimeout(); /* Adjust timeouts */ - lcp_close(0); /* Close connection */ -} - - -/* - * intr - Catch SIGINT signal (DEL/^C). - * - * Indicates that we should initiate a graceful disconnect and exit. - */ -static void -intr(sig) - int sig; -{ - syslog(LOG_INFO, "Interrupt received: terminating link"); - persist = 0; /* don't try to restart */ - adjtimeout(); /* Adjust timeouts */ - lcp_close(0); /* Close connection */ -} - - -/* - * alrm - Catch SIGALRM signal. - * - * Indicates a timeout. - */ -static void -alrm(sig) - int sig; -{ - struct itimerval itv; - struct callout *freep, *list, *last; - - MAINDEBUG((LOG_DEBUG, "Alarm")); - - if (callout == NULL) - return; - /* - * Get the first scheduled timeout and any that were scheduled - * for the same time as a list, and remove them all from callout - * list. - */ - list = last = callout; - while (last->c_next != NULL && last->c_next->c_time == 0) - last = last->c_next; - callout = last->c_next; - last->c_next = NULL; - - /* - * Set a new itimer if there are more timeouts scheduled. - */ - if (callout) { - itv.it_interval.tv_sec = itv.it_interval.tv_usec = 0; - itv.it_value.tv_usec = 0; - itv.it_value.tv_sec = callout->c_time; - MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds in alrm.", - itv.it_value.tv_sec)); - if (setitimer(ITIMER_REAL, &itv, NULL)) { - syslog(LOG_ERR, "setitimer(ITIMER_REAL): %m"); - die(1); - } - if (gettimeofday(&schedtime, NULL)) { - syslog(LOG_ERR, "gettimeofday: %m"); - die(1); - } - } - - /* - * Now call all the timeout routines scheduled for this time. - */ - while (list) { - (*list->c_func)(list->c_arg); - freep = list; - list = list->c_next; - (void) free((char *) freep); - } - + kill_link = 1; } @@ -1068,129 +774,31 @@ chld(sig) /* - * io - Catch SIGIO signal. + * toggle_debug - Catch SIGUSR1 signal. * - * Indicates that incoming data is available. - */ -static void -io(sig) - int sig; -{ - int len, i; - u_char *p; - u_short protocol; - fd_set fdset; - struct timeval notime; - int ready; - - MAINDEBUG((LOG_DEBUG, "IO signal received")); - adjtimeout(); /* Adjust timeouts */ - - /* Yup, this is for real */ - for (;;) { /* Read all available packets */ - p = inpacket_buf; /* point to beginning of packet buffer */ - - len = read_packet(inpacket_buf); - if (len < 0) - return; - - if (len == 0) { - MAINDEBUG((LOG_DEBUG, "End of file on fd!")); - lcp_lowerdown(0); - return; - } - - if (debug /*&& (debugflags & DBG_INPACKET)*/) - log_packet(p, len, "rcvd "); - - if (len < DLLHEADERLEN) { - MAINDEBUG((LOG_INFO, "io(): Received short packet.")); - return; - } - - p += 2; /* Skip address and control */ - GETSHORT(protocol, p); - len -= DLLHEADERLEN; - - /* - * Toss all non-LCP packets unless LCP is OPEN. - */ - if (protocol != LCP && lcp_fsm[0].state != OPENED) { - MAINDEBUG((LOG_INFO, - "io(): Received non-LCP packet when LCP not open.")); - return; - } - - /* - * Upcall the proper protocol input routine. - */ - for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++) - if (prottbl[i].protocol == protocol) { - (*prottbl[i].input)(0, p, len); - break; - } - - if (i == sizeof (prottbl) / sizeof (struct protent)) { - syslog(LOG_WARNING, "input: Unknown protocol (%x) received!", - protocol); - lcp_sprotrej(0, p - DLLHEADERLEN, len + DLLHEADERLEN); - } - } -} - -/* - * demuxprotrej - Demultiplex a Protocol-Reject. - */ -void -demuxprotrej(unit, protocol) - int unit; - u_short protocol; -{ - int i; - - /* - * Upcall the proper Protocol-Reject routine. - */ - for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++) - if (prottbl[i].protocol == protocol) { - (*prottbl[i].protrej)(unit); - return; - } - - syslog(LOG_WARNING, - "demuxprotrej: Unrecognized Protocol-Reject for protocol %d!", - protocol); -} - - -/* - * incdebug - Catch SIGUSR1 signal. - * - * Increment debug flag. + * Toggle debug flag. */ /*ARGSUSED*/ static void -incdebug(sig) +toggle_debug(sig) int sig; { - syslog(LOG_INFO, "Debug turned ON, Level %d", debug); - setlogmask(LOG_UPTO(LOG_DEBUG)); - debug++; + debug = !debug; + note_debug_level(); } /* - * nodebug - Catch SIGUSR2 signal. + * open_ccp - Catch SIGUSR2 signal. * - * Turn off debugging. + * Try to (re)negotiate compression. */ /*ARGSUSED*/ static void -nodebug(sig) +open_ccp(sig) int sig; { - setlogmask(LOG_UPTO(LOG_WARNING)); - debug = 0; + open_ccp_flag = 1; } @@ -1205,26 +813,23 @@ device_script(program, in, out) { int pid; int status; - sigset_t mask; - - sigemptyset(&mask); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGHUP); - sigprocmask(SIG_BLOCK, &mask, &mask); + int errfd; pid = fork(); if (pid < 0) { - syslog(LOG_ERR, "fork: %m"); + syslog(LOG_ERR, "Failed to create child process: %m"); die(1); } if (pid == 0) { - setreuid(getuid(), getuid()); - setregid(getgid(), getgid()); - sigprocmask(SIG_SETMASK, &mask, NULL); dup2(in, 0); dup2(out, 1); + errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0644); + if (errfd >= 0) + dup2(errfd, 2); + setuid(getuid()); + setgid(getgid()); execl("/bin/sh", "sh", "-c", program, (char *)0); syslog(LOG_ERR, "could not exec /bin/sh: %m"); _exit(99); @@ -1234,10 +839,9 @@ device_script(program, in, out) while (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) continue; - syslog(LOG_ERR, "waiting for (dis)connection process: %m"); + syslog(LOG_ERR, "error waiting for (dis)connection process: %m"); die(1); } - sigprocmask(SIG_SETMASK, &mask, NULL); return (status == 0 ? 0 : -1); } @@ -1256,16 +860,54 @@ run_program(prog, args, must_exist) int must_exist; { int pid; + char *nullenv[1]; pid = fork(); if (pid == -1) { - syslog(LOG_ERR, "can't fork to run %s: %m", prog); + syslog(LOG_ERR, "Failed to create child process for %s: %m", prog); return -1; } if (pid == 0) { - execv(prog, args); + int new_fd; + + /* Leave the current location */ + (void) setsid(); /* No controlling tty. */ + (void) umask (S_IRWXG|S_IRWXO); + (void) chdir ("/"); /* no current directory. */ + setuid(geteuid()); + setgid(getegid()); + + /* Ensure that nothing of our device environment is inherited. */ + close (0); + close (1); + close (2); + close (fd); /* tty interface to the ppp device */ + /* XXX should call sysdep cleanup procedure here */ + + /* Don't pass handles to the PPP device, even by accident. */ + new_fd = open (_PATH_DEVNULL, O_RDWR); + if (new_fd >= 0) { + if (new_fd != 0) { + dup2 (new_fd, 0); /* stdin <- /dev/null */ + close (new_fd); + } + dup2 (0, 1); /* stdout -> /dev/null */ + dup2 (0, 2); /* stderr -> /dev/null */ + } + +#ifdef BSD + /* Force the priority back to zero if pppd is running higher. */ + if (setpriority (PRIO_PROCESS, 0, 0) < 0) + syslog (LOG_WARNING, "can't reset priority to 0: %m"); +#endif + + /* SysV recommends a second fork at this point. */ + + /* run the program; give it a null environment */ + nullenv[0] = NULL; + execve(prog, args, nullenv); if (must_exist || errno != ENOENT) - syslog(LOG_WARNING, "can't execute %s: %m", prog); + syslog(LOG_WARNING, "Can't execute %s: %m", prog); _exit(-1); } MAINDEBUG((LOG_DEBUG, "Script %s started; pid = %d", prog, pid)); @@ -1287,13 +929,13 @@ reap_kids() return; if ((pid = waitpid(-1, &status, WNOHANG)) == -1) { if (errno != ECHILD) - syslog(LOG_ERR, "waitpid: %m"); + syslog(LOG_ERR, "Error waiting for child process: %m"); return; } if (pid > 0) { --n_children; if (WIFSIGNALED(status)) { - syslog(LOG_WARNING, "child process %d terminated with signal %d", + syslog(LOG_WARNING, "Child process %d terminated with signal %d", pid, WTERMSIG(status)); } } @@ -1328,17 +970,17 @@ void format_packet(p, len, printer, arg) u_char *p; int len; - void (*printer) __ARGS((void *, char *, ...)); + void (*printer) __P((void *, char *, ...)); void *arg; { int i, n; u_short proto; u_char x; - if (len >= DLLHEADERLEN && p[0] == ALLSTATIONS && p[1] == UI) { + if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { p += 2; GETSHORT(proto, p); - len -= DLLHEADERLEN; + len -= PPP_HDRLEN; for (i = 0; i < N_PROTO; ++i) if (proto == prottbl[i].protocol) break; @@ -1417,7 +1059,7 @@ void print_string(p, len, printer, arg) char *p; int len; - void (*printer) __ARGS((void *, char *, ...)); + void (*printer) __P((void *, char *, ...)); void *arg; { int c; diff --git a/usr.sbin/pppd/md5.h b/usr.sbin/pppd/md5.h index 535b18d4b730..7492b2228e2b 100644 --- a/usr.sbin/pppd/md5.h +++ b/usr.sbin/pppd/md5.h @@ -40,7 +40,7 @@ #ifndef __MD5_INCLUDE__ /* typedef a 32-bit type */ -typedef unsigned long int UINT4; +typedef unsigned int UINT4; /* Data structure for MD5 (Message-Digest) computation */ typedef struct { diff --git a/usr.sbin/pppd/options.c b/usr.sbin/pppd/options.c index ef1fc8a3c008..d6f89e2ab097 100644 --- a/usr.sbin/pppd/options.c +++ b/usr.sbin/pppd/options.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: options.c,v 1.10 1994/05/27 00:43:34 paulus Exp $"; +static char rcsid[] = "$Id: options.c,v 1.24 1995/08/16 01:39:35 paulus Exp $"; #endif #include @@ -35,7 +35,6 @@ static char rcsid[] = "$Id: options.c,v 1.10 1994/05/27 00:43:34 paulus Exp $"; #include #include -#include "ppp.h" #include "pppd.h" #include "pathnames.h" #include "patchlevel.h" @@ -44,116 +43,135 @@ static char rcsid[] = "$Id: options.c,v 1.10 1994/05/27 00:43:34 paulus Exp $"; #include "ipcp.h" #include "upap.h" #include "chap.h" +#include "ccp.h" + +#include #define FALSE 0 #define TRUE 1 -#ifdef ultrix -char *strdup __ARGS((char *)); +#if defined(ultrix) || defined(NeXT) +char *strdup __P((char *)); #endif #ifndef GIDSET_TYPE -#define GIDSET_TYPE int +#define GIDSET_TYPE gid_t +#endif + +/* + * Option variables and default values. + */ +int debug = 0; /* Debug flag */ +int kdebugflag = 0; /* Tell kernel to print debug messages */ +int default_device = 1; /* Using /dev/tty or equivalent */ +char devnam[MAXPATHLEN] = "/dev/tty"; /* Device name */ +int crtscts = 0; /* Use hardware flow control */ +int modem = 1; /* Use modem control lines */ +int inspeed = 0; /* Input/Output speed requested */ +u_int32_t netmask = 0; /* IP netmask to set on interface */ +int lockflag = 0; /* Create lock file to lock the serial dev */ +int nodetach = 0; /* Don't detach from controlling tty */ +char *connector = NULL; /* Script to establish physical link */ +char *disconnector = NULL; /* Script to disestablish physical link */ +char user[MAXNAMELEN]; /* Username for PAP */ +char passwd[MAXSECRETLEN]; /* Password for PAP */ +int auth_required = 0; /* Peer is required to authenticate */ +int defaultroute = 0; /* assign default route through interface */ +int proxyarp = 0; /* Set up proxy ARP entry for peer */ +int persist = 0; /* Reopen link after it goes down */ +int uselogin = 0; /* Use /etc/passwd for checking PAP */ +int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ +int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ +char our_name[MAXNAMELEN]; /* Our name for authentication purposes */ +char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ +int usehostname = 0; /* Use hostname for our_name */ +int disable_defaultip = 0; /* Don't use hostname for default IP adrs */ +char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ +int cryptpap; /* Passwords in pap-secrets are encrypted */ + +#ifdef _linux_ +int idle_time_limit = 0; +static int setidle __P((char **)); #endif /* * Prototypes */ -static int setdebug __ARGS((void)); -static int setkdebug __ARGS((char **)); -static int setpassive __ARGS((void)); -static int setsilent __ARGS((void)); -static int noopt __ARGS((void)); -static int setnovj __ARGS((void)); -static int setnovjccomp __ARGS((void)); -static int setvjslots __ARGS((char **)); -static int reqpap __ARGS((void)); -static int nopap __ARGS((void)); -static int setupapfile __ARGS((char **)); -static int nochap __ARGS((void)); -static int reqchap __ARGS((void)); -static int setspeed __ARGS((char *)); -static int noaccomp __ARGS((void)); -static int noasyncmap __ARGS((void)); -static int noipaddr __ARGS((void)); -static int nomagicnumber __ARGS((void)); -static int setasyncmap __ARGS((char **)); -static int setescape __ARGS((char **)); -static int setmru __ARGS((char **)); -static int setmtu __ARGS((char **)); -static int nomru __ARGS((void)); -static int nopcomp __ARGS((void)); -static int setconnector __ARGS((char **)); -static int setdisconnector __ARGS((char **)); -static int setdomain __ARGS((char **)); -static int setnetmask __ARGS((char **)); -static int setcrtscts __ARGS((void)); -static int setxonxoff __ARGS((void)); -static int setnodetach __ARGS((void)); -static int setmodem __ARGS((void)); -static int setlocal __ARGS((void)); -static int setlock __ARGS((void)); -static int setname __ARGS((char **)); -static int setuser __ARGS((char **)); -static int setremote __ARGS((char **)); -static int setauth __ARGS((void)); -static int readfile __ARGS((char **)); -static int setdefaultroute __ARGS((void)); -static int setproxyarp __ARGS((void)); -static int setpersist __ARGS((void)); -static int setdologin __ARGS((void)); -static int setusehostname __ARGS((void)); -static int setnoipdflt __ARGS((void)); -static int setlcptimeout __ARGS((char **)); -static int setlcpterm __ARGS((char **)); -static int setlcpconf __ARGS((char **)); -static int setlcpfails __ARGS((char **)); -static int setipcptimeout __ARGS((char **)); -static int setipcpterm __ARGS((char **)); -static int setipcpconf __ARGS((char **)); -static int setipcpfails __ARGS((char **)); -static int setpaptimeout __ARGS((char **)); -static int setpapreqs __ARGS((char **)); -static int setchaptimeout __ARGS((char **)); -static int setchapchal __ARGS((char **)); -static int setchapintv __ARGS((char **)); -static int setipcpaccl __ARGS((void)); -static int setipcpaccr __ARGS((void)); -static int setlcpechointv __ARGS((char **)); -static int setlcpechofails __ARGS((char **)); +static int setdebug __P((void)); +static int setkdebug __P((char **)); +static int setpassive __P((void)); +static int setsilent __P((void)); +static int noopt __P((void)); +static int setnovj __P((void)); +static int setnovjccomp __P((void)); +static int setvjslots __P((char **)); +static int reqpap __P((void)); +static int nopap __P((void)); +static int setupapfile __P((char **)); +static int nochap __P((void)); +static int reqchap __P((void)); +static int setspeed __P((char *)); +static int noaccomp __P((void)); +static int noasyncmap __P((void)); +static int noipaddr __P((void)); +static int nomagicnumber __P((void)); +static int setasyncmap __P((char **)); +static int setescape __P((char **)); +static int setmru __P((char **)); +static int setmtu __P((char **)); +static int nomru __P((void)); +static int nopcomp __P((void)); +static int setconnector __P((char **)); +static int setdisconnector __P((char **)); +static int setdomain __P((char **)); +static int setnetmask __P((char **)); +static int setcrtscts __P((void)); +static int setnocrtscts __P((void)); +static int setxonxoff __P((void)); +static int setnodetach __P((void)); +static int setmodem __P((void)); +static int setlocal __P((void)); +static int setlock __P((void)); +static int setname __P((char **)); +static int setuser __P((char **)); +static int setremote __P((char **)); +static int setauth __P((void)); +static int readfile __P((char **)); +static int setdefaultroute __P((void)); +static int setnodefaultroute __P((void)); +static int setproxyarp __P((void)); +static int setnoproxyarp __P((void)); +static int setpersist __P((void)); +static int setdologin __P((void)); +static int setusehostname __P((void)); +static int setnoipdflt __P((void)); +static int setlcptimeout __P((char **)); +static int setlcpterm __P((char **)); +static int setlcpconf __P((char **)); +static int setlcpfails __P((char **)); +static int setipcptimeout __P((char **)); +static int setipcpterm __P((char **)); +static int setipcpconf __P((char **)); +static int setipcpfails __P((char **)); +static int setpaptimeout __P((char **)); +static int setpapreqs __P((char **)); +static int setpapreqtime __P((char **)); +static int setchaptimeout __P((char **)); +static int setchapchal __P((char **)); +static int setchapintv __P((char **)); +static int setipcpaccl __P((void)); +static int setipcpaccr __P((void)); +static int setlcpechointv __P((char **)); +static int setlcpechofails __P((char **)); +static int setbsdcomp __P((char **)); +static int setnobsdcomp __P((void)); +static int setipparam __P((char **)); +static int setpapcrypt __P((void)); -static int number_option __ARGS((char *, long *, int)); -static int readable __ARGS((int fd)); +static int number_option __P((char *, u_int32_t *, int)); +static int readable __P((int fd)); -/* - * Option variables - */ -extern char *progname; -extern int debug; -extern int kdebugflag; -extern int modem; -extern int lockflag; -extern int crtscts; -extern int nodetach; -extern char *connector; -extern char *disconnector; -extern int inspeed; -extern char devname[]; -extern int default_device; -extern u_long netmask; -extern int detach; -extern char user[]; -extern char passwd[]; -extern int auth_required; -extern int proxyarp; -extern int persist; -extern int uselogin; -extern u_long lcp_echo_interval; -extern u_long lcp_echo_fails; -extern char our_name[]; -extern char remote_name[]; -int usehostname; -int disable_defaultip; +void usage(); /* * Valid arguments. @@ -187,8 +205,8 @@ static struct cmd { {"connect", 1, setconnector}, /* A program to set up a connection */ {"disconnect", 1, setdisconnector}, /* program to disconnect serial dev. */ {"crtscts", 0, setcrtscts}, /* set h/w flow control */ + {"-crtscts", 0, setnocrtscts}, /* clear h/w flow control */ {"xonxoff", 0, setxonxoff}, /* set s/w flow control */ - {"-crtscts", 0, setxonxoff}, /* another name for xonxoff */ {"debug", 0, setdebug}, /* Increase debugging level */ {"kdebug", 1, setkdebug}, /* Enable kernel-level debugging */ {"domain", 1, setdomain}, /* Add given domain name to hostname*/ @@ -207,7 +225,9 @@ static struct cmd { {"auth", 0, setauth}, /* Require authentication from peer */ {"file", 1, readfile}, /* Take options from a file */ {"defaultroute", 0, setdefaultroute}, /* Add default route */ + {"-defaultroute", 0, setnodefaultroute}, /* disable defaultroute option */ {"proxyarp", 0, setproxyarp}, /* Add proxy ARP entry */ + {"-proxyarp", 0, setnoproxyarp}, /* disable proxyarp option */ {"persist", 0, setpersist}, /* Keep on reopening connection after close */ {"login", 0, setdologin}, /* Use system password database for UPAP */ {"noipdefault", 0, setnoipdflt}, /* Don't use name for default IP adrs */ @@ -221,13 +241,21 @@ static struct cmd { {"ipcp-max-terminate", 1, setipcpterm}, /* Set max #xmits for term-reqs */ {"ipcp-max-configure", 1, setipcpconf}, /* Set max #xmits for conf-reqs */ {"ipcp-max-failure", 1, setipcpfails}, /* Set max #conf-naks for IPCP */ - {"pap-restart", 1, setpaptimeout}, /* Set timeout for UPAP */ + {"pap-restart", 1, setpaptimeout}, /* Set retransmit timeout for PAP */ {"pap-max-authreq", 1, setpapreqs}, /* Set max #xmits for auth-reqs */ + {"pap-timeout", 1, setpapreqtime}, /* Set time limit for peer PAP auth. */ {"chap-restart", 1, setchaptimeout}, /* Set timeout for CHAP */ {"chap-max-challenge", 1, setchapchal}, /* Set max #xmits for challenge */ {"chap-interval", 1, setchapintv}, /* Set interval for rechallenge */ {"ipcp-accept-local", 0, setipcpaccl}, /* Accept peer's address for us */ {"ipcp-accept-remote", 0, setipcpaccr}, /* Accept peer's address for it */ + {"bsdcomp", 1, setbsdcomp}, /* request BSD-Compress */ + {"-bsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */ + {"ipparam", 1, setipparam}, /* set ip script parameter */ + {"papcrypt", 0, setpapcrypt}, /* PAP passwords encrypted */ +#ifdef _linux_ + {"idle-disconnect", 1, setidle}, /* seconds for disconnect of idle IP */ +#endif {NULL, 0, NULL} }; @@ -311,6 +339,7 @@ parse_args(argc, argv) /* * usage - print out a message telling how to use the program. */ +void usage() { fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION, @@ -425,9 +454,9 @@ options_for_tty() char *dev, *path; int ret; - dev = strrchr(devname, '/'); + dev = strrchr(devnam, '/'); if (dev == NULL) - dev = devname; + dev = devnam; else ++dev; if (strcmp(dev, "tty") == 0) @@ -472,10 +501,11 @@ readable(fd) /* * Read a word from a file. - * Words are delimited by white-space or by quotes ("). + * Words are delimited by white-space or by quotes (" or '). * Quotes, white-space and \ may be escaped with \. * \ is ignored. */ + int getword(f, word, newlinep, filename) FILE *f; @@ -484,110 +514,250 @@ getword(f, word, newlinep, filename) char *filename; { int c, len, escape; - int quoted; + int quoted, comment; + int value, digit, got, n; + +#define isoctal(c) ((c) >= '0' && (c) < '8') *newlinep = 0; len = 0; escape = 0; - quoted = 0; + comment = 0; /* - * First skip white-space and comments + * First skip white-space and comments. */ - while ((c = getc(f)) != EOF) { - if (c == '\\') { - /* - * \ is ignored; \ followed by anything else - * starts a word. - */ - if ((c = getc(f)) == '\n') - continue; - word[len++] = '\\'; - escape = 1; + for (;;) { + c = getc(f); + if (c == EOF) break; + + /* + * A newline means the end of a comment; backslash-newline + * is ignored. Note that we cannot have escape && comment. + */ + if (c == '\n') { + if (!escape) { + *newlinep = 1; + comment = 0; + } else + escape = 0; + continue; } - if (c == '\n') - *newlinep = 1; /* next word starts a line */ - else if (c == '#') { - /* comment - ignore until EOF or \n */ - while ((c = getc(f)) != EOF && c != '\n') - ; - if (c == EOF) - break; - *newlinep = 1; - } else if (!isspace(c)) + + /* + * Ignore characters other than newline in a comment. + */ + if (comment) + continue; + + /* + * If this character is escaped, we have a word start. + */ + if (escape) + break; + + /* + * If this is the escape character, look at the next character. + */ + if (c == '\\') { + escape = 1; + continue; + } + + /* + * If this is the start of a comment, ignore the rest of the line. + */ + if (c == '#') { + comment = 1; + continue; + } + + /* + * A non-whitespace character is the start of a word. + */ + if (!isspace(c)) break; } /* - * End of file or error - fail + * Save the delimiter for quoted strings. + */ + if (!escape && (c == '"' || c == '\'')) { + quoted = c; + c = getc(f); + } else + quoted = 0; + + /* + * Process characters until the end of the word. + */ + while (c != EOF) { + if (escape) { + /* + * This character is escaped: backslash-newline is ignored, + * various other characters indicate particular values + * as for C backslash-escapes. + */ + escape = 0; + if (c == '\n') { + c = getc(f); + continue; + } + + got = 0; + switch (c) { + case 'a': + value = '\a'; + break; + case 'b': + value = '\b'; + break; + case 'f': + value = '\f'; + break; + case 'n': + value = '\n'; + break; + case 'r': + value = '\r'; + break; + case 's': + value = ' '; + break; + case 't': + value = '\t'; + break; + + default: + if (isoctal(c)) { + /* + * \ddd octal sequence + */ + value = 0; + for (n = 0; n < 3 && isoctal(c); ++n) { + value = (value << 3) + (c & 07); + c = getc(f); + } + got = 1; + break; + } + + if (c == 'x') { + /* + * \x sequence + */ + value = 0; + c = getc(f); + for (n = 0; n < 2 && isxdigit(c); ++n) { + digit = toupper(c) - '0'; + if (digit > 10) + digit += '0' + 10 - 'A'; + value = (value << 4) + digit; + c = getc (f); + } + got = 1; + break; + } + + /* + * Otherwise the character stands for itself. + */ + value = c; + break; + } + + /* + * Store the resulting character for the escape sequence. + */ + if (len < MAXWORDLEN-1) + word[len] = value; + ++len; + + if (!got) + c = getc(f); + continue; + + } + + /* + * Not escaped: see if we've reached the end of the word. + */ + if (quoted) { + if (c == quoted) + break; + } else { + if (isspace(c) || c == '#') { + ungetc (c, f); + break; + } + } + + /* + * Backslash starts an escape sequence. + */ + if (c == '\\') { + escape = 1; + c = getc(f); + continue; + } + + /* + * An ordinary character: store it in the word and get another. + */ + if (len < MAXWORDLEN-1) + word[len] = c; + ++len; + + c = getc(f); + } + + /* + * End of the word: check for errors. */ if (c == EOF) { if (ferror(f)) { + if (errno == 0) + errno = EIO; perror(filename); die(1); } - return 0; - } - - for (;;) { /* - * Is this character escaped by \ ? + * If len is zero, then we didn't find a word before the + * end of the file. */ - if (escape) { - if (c == '\n') - --len; /* ignore \ */ - else if (c == '"' || isspace(c) || c == '\\') - word[len-1] = c; /* put special char in word */ - else { - if (len < MAXWORDLEN-1) - word[len] = c; - ++len; - } - escape = 0; - } else if (c == '"') { - quoted = !quoted; - } else if (!quoted && (isspace(c) || c == '#')) { - ungetc(c, f); - break; - } else { - if (len < MAXWORDLEN-1) - word[len] = c; - ++len; - if (c == '\\') - escape = 1; - } - if ((c = getc(f)) == EOF) - break; - } - - if (ferror(f)) { - perror(filename); - die(1); + if (len == 0) + return 0; } + /* + * Warn if the word was too long, and append a terminating null. + */ if (len >= MAXWORDLEN) { - word[MAXWORDLEN-1] = 0; fprintf(stderr, "%s: warning: word in file %s too long (%.20s...)\n", progname, filename, word); - } else - word[len] = 0; + len = MAXWORDLEN - 1; + } + word[len] = 0; return 1; + +#undef isoctal + } /* - * number_option - parse a numeric parameter for an option + * number_option - parse an unsigned numeric parameter for an option. */ static int number_option(str, valp, base) char *str; - long *valp; + u_int32_t *valp; int base; { char *ptr; - *valp = strtol(str, &ptr, base); + *valp = strtoul(str, &ptr, base); if (ptr == str) { fprintf(stderr, "%s: invalid number: %s\n", progname, str); return 0; @@ -606,7 +776,7 @@ int_option(str, valp) char *str; int *valp; { - long v; + u_int32_t v; if (!number_option(str, &v, 0)) return 0; @@ -729,7 +899,7 @@ static int setmru(argv) char **argv; { - long mru; + u_int32_t mru; if (!number_option(*argv, &mru, 0)) return 0; @@ -746,12 +916,12 @@ static int setmtu(argv) char **argv; { - long mtu; + u_int32_t mtu; if (!number_option(*argv, &mtu, 0)) return 0; if (mtu < MINMRU || mtu > MAXMRU) { - fprintf(stderr, "mtu option value of %d is too %s\n", mtu, + fprintf(stderr, "mtu option value of %ld is too %s\n", mtu, (mtu < MINMRU? "small": "large")); return 0; } @@ -815,6 +985,7 @@ reqpap() { lcp_wantoptions[0].neg_upap = 1; auth_required = 1; + return 1; } @@ -904,6 +1075,7 @@ setnovjccomp() { ipcp_wantoptions[0].cflag = 0; ipcp_allowoptions[0].cflag = 0; + return 1; } @@ -964,7 +1136,12 @@ static int setdomain(argv) char **argv; { - strncat(hostname, *argv, MAXNAMELEN - strlen(hostname)); + gethostname(hostname, MAXNAMELEN); + if (**argv != 0) { + if (**argv != '.') + strncat(hostname, ".", MAXNAMELEN - strlen(hostname)); + strncat(hostname, *argv, MAXNAMELEN - strlen(hostname)); + } hostname[MAXNAMELEN-1] = 0; return (1); } @@ -977,7 +1154,7 @@ static int setasyncmap(argv) char **argv; { - long asyncmap; + u_int32_t asyncmap; if (!number_option(*argv, &asyncmap, 16)) return 0; @@ -1007,7 +1184,7 @@ setescape(argv) } p = endp; if (n < 0 || 0x20 <= n && n <= 0x3F || n == 0x5E || n > 0xFF) { - fprintf(stderr, "%s: can't escape character 0x%x\n", n); + fprintf(stderr, "%s: can't escape character 0x%x\n", progname, n); ret = 0; } else xmit_accm[0][n >> 5] |= 1 << (n & 0x1F); @@ -1064,8 +1241,8 @@ setdevname(cp) return -1; } - (void) strncpy(devname, cp, MAXPATHLEN); - devname[MAXPATHLEN-1] = 0; + (void) strncpy(devnam, cp, MAXPATHLEN); + devnam[MAXPATHLEN-1] = 0; default_device = FALSE; return 1; @@ -1080,14 +1257,14 @@ setipaddr(arg) char *arg; { struct hostent *hp; - char *colon, *index(); - u_long local, remote; + char *colon; + u_int32_t local, remote; ipcp_options *wo = &ipcp_wantoptions[0]; /* * IP address pair separated by ":". */ - if ((colon = index(arg, ':')) == NULL) + if ((colon = strchr(arg, ':')) == NULL) return 0; /* @@ -1100,7 +1277,7 @@ setipaddr(arg) fprintf(stderr, "unknown host: %s\n", arg); return -1; } else { - local = *(long *)hp->h_addr; + local = *(u_int32_t *)hp->h_addr; if (our_name[0] == 0) { strncpy(our_name, arg, MAXNAMELEN); our_name[MAXNAMELEN-1] = 0; @@ -1125,7 +1302,7 @@ setipaddr(arg) fprintf(stderr, "unknown host: %s\n", colon); return -1; } else { - remote = *(long *)hp->h_addr; + remote = *(u_int32_t *)hp->h_addr; if (remote_name[0] == 0) { strncpy(remote_name, colon, MAXNAMELEN); remote_name[MAXNAMELEN-1] = 0; @@ -1184,7 +1361,7 @@ void setipdefault() { struct hostent *hp; - u_long local; + u_int32_t local; ipcp_options *wo = &ipcp_wantoptions[0]; /* @@ -1201,7 +1378,7 @@ setipdefault() wo->accept_local = 1; /* don't insist on this default value */ if ((hp = gethostbyname(hostname)) == NULL) return; - local = *(long *)hp->h_addr; + local = *(u_int32_t *)hp->h_addr; if (local != 0 && !bad_ip_adrs(local)) wo->ouraddr = local; } @@ -1214,7 +1391,7 @@ static int setnetmask(argv) char **argv; { - u_long mask; + u_int32_t mask; if ((mask = inet_addr(*argv)) == -1 || (netmask & ~mask) != 0) { fprintf(stderr, "Invalid netmask %s\n", *argv); @@ -1225,19 +1402,6 @@ setnetmask(argv) return (1); } -/* - * Return user specified netmask. A value of zero means no netmask has - * been set. - */ -/* ARGSUSED */ -u_long -GetMask(addr) - u_long addr; -{ - return(netmask); -} - - static int setcrtscts() { @@ -1245,9 +1409,19 @@ setcrtscts() return (1); } +static int +setnocrtscts() +{ + crtscts = -1; + return (1); +} + static int setxonxoff() { + lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */ + lcp_wantoptions[0].neg_asyncmap = 1; + crtscts = 2; return (1); } @@ -1326,17 +1500,41 @@ setauth() static int setdefaultroute() { + if (!ipcp_allowoptions[0].default_route) { + fprintf(stderr, "%s: defaultroute option is disabled\n", progname); + return 0; + } ipcp_wantoptions[0].default_route = 1; return 1; } +static int +setnodefaultroute() +{ + ipcp_allowoptions[0].default_route = 0; + ipcp_wantoptions[0].default_route = 0; + return 1; +} + static int setproxyarp() { + if (!ipcp_allowoptions[0].proxy_arp) { + fprintf(stderr, "%s: proxyarp option is disabled\n", progname); + return 0; + } ipcp_wantoptions[0].proxy_arp = 1; return 1; } +static int +setnoproxyarp() +{ + ipcp_wantoptions[0].proxy_arp = 0; + ipcp_allowoptions[0].proxy_arp = 0; + return 1; +} + static int setpersist() { @@ -1379,74 +1577,164 @@ setlcptimeout(argv) return int_option(*argv, &lcp_fsm[0].timeouttime); } -static int setlcpterm(argv) +static int +setlcpterm(argv) char **argv; { return int_option(*argv, &lcp_fsm[0].maxtermtransmits); } -static int setlcpconf(argv) +static int +setlcpconf(argv) char **argv; { return int_option(*argv, &lcp_fsm[0].maxconfreqtransmits); } -static int setlcpfails(argv) +static int +setlcpfails(argv) char **argv; { return int_option(*argv, &lcp_fsm[0].maxnakloops); } -static int setipcptimeout(argv) +static int +setipcptimeout(argv) char **argv; { return int_option(*argv, &ipcp_fsm[0].timeouttime); } -static int setipcpterm(argv) +static int +setipcpterm(argv) char **argv; { return int_option(*argv, &ipcp_fsm[0].maxtermtransmits); } -static int setipcpconf(argv) +static int +setipcpconf(argv) char **argv; { return int_option(*argv, &ipcp_fsm[0].maxconfreqtransmits); } -static int setipcpfails(argv) +static int +setipcpfails(argv) char **argv; { return int_option(*argv, &lcp_fsm[0].maxnakloops); } -static int setpaptimeout(argv) +static int +setpaptimeout(argv) char **argv; { return int_option(*argv, &upap[0].us_timeouttime); } -static int setpapreqs(argv) +static int +setpapreqtime(argv) + char **argv; +{ + return int_option(*argv, &upap[0].us_reqtimeout); +} + +static int +setpapreqs(argv) char **argv; { return int_option(*argv, &upap[0].us_maxtransmits); } -static int setchaptimeout(argv) +static int +setchaptimeout(argv) char **argv; { return int_option(*argv, &chap[0].timeouttime); } -static int setchapchal(argv) +static int +setchapchal(argv) char **argv; { return int_option(*argv, &chap[0].max_transmits); } -static int setchapintv(argv) +static int +setchapintv(argv) char **argv; { return int_option(*argv, &chap[0].chal_interval); } + +static int +setbsdcomp(argv) + char **argv; +{ + int rbits, abits; + char *str, *endp; + + str = *argv; + abits = rbits = strtol(str, &endp, 0); + if (endp != str && *endp == ',') { + str = endp + 1; + abits = strtol(str, &endp, 0); + } + if (*endp != 0 || endp == str) { + fprintf(stderr, "%s: invalid argument format for bsdcomp option\n", + progname); + return 0; + } + if (rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS) + || abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS)) { + fprintf(stderr, "%s: bsdcomp option values must be 0 or %d .. %d\n", + progname, BSD_MIN_BITS, BSD_MAX_BITS); + return 0; + } + if (rbits > 0) { + ccp_wantoptions[0].bsd_compress = 1; + ccp_wantoptions[0].bsd_bits = rbits; + } else + ccp_wantoptions[0].bsd_compress = 0; + if (abits > 0) { + ccp_allowoptions[0].bsd_compress = 1; + ccp_allowoptions[0].bsd_bits = abits; + } else + ccp_allowoptions[0].bsd_compress = 0; + return 1; +} + +static int +setnobsdcomp() +{ + ccp_wantoptions[0].bsd_compress = 0; + ccp_allowoptions[0].bsd_compress = 0; + return 1; +} + +static int +setipparam(argv) + char **argv; +{ + ipparam = strdup(*argv); + if (ipparam == NULL) + novm("ipparam string"); + + return 1; +} + +static int +setpapcrypt() +{ + cryptpap = 1; + return 1; +} + +#ifdef _linux_ +static int setidle (argv) + char **argv; +{ + return int_option(*argv, &idle_time_limit); +} +#endif diff --git a/usr.sbin/pppd/patchlevel.h b/usr.sbin/pppd/patchlevel.h index ad290b08f5fe..c722443f029d 100644 --- a/usr.sbin/pppd/patchlevel.h +++ b/usr.sbin/pppd/patchlevel.h @@ -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" diff --git a/usr.sbin/pppd/pathnames.h b/usr.sbin/pppd/pathnames.h index d8e91dcad676..4562a967017b 100644 --- a/usr.sbin/pppd/pathnames.h +++ b/usr.sbin/pppd/pathnames.h @@ -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 + #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" diff --git a/usr.sbin/pppd/pppd.8 b/usr.sbin/pppd/pppd.8 index 3395631d8f64..e1c7bbdd9886 100644 --- a/usr.sbin/pppd/pppd.8 +++ b/usr.sbin/pppd/pppd.8 @@ -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 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 Append the domain name 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 Set the MTU [Maximum Transmit Unit] value to \fI\fR. Unless the @@ -283,11 +320,27 @@ option). Set the assumed name of the remote system for authentication purposes to . .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 seconds Set the maximum number of PAP authenticate-request transmissions to (default 10). .TP +.B pap-timeout \fI +Set the maximum time that +.I pppd +will wait for the peer to authenticate itself with PAP to + seconds (0 means no limit). +.TP .B chap-restart \fI Set the CHAP restart interval (retransmission timeout for challenges) to 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). diff --git a/usr.sbin/pppd/pppd.h b/usr.sbin/pppd/pppd.h index e38687d7ac17..66b0107efca7 100644 --- a/usr.sbin/pppd/pppd.h +++ b/usr.sbin/pppd/pppd.h @@ -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.3 1994/05/26 06:43:42 paulus 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 /* for MAXPATHLEN and BSD4_4, if defined */ +#include /* for u_int32_t, if defined */ +#include -#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); } diff --git a/usr.sbin/pppd/sys-bsd.c b/usr.sbin/pppd/sys-bsd.c index 65c0b7716faf..eea6125b3352 100644 --- a/usr.sbin/pppd/sys-bsd.c +++ b/usr.sbin/pppd/sys-bsd.c @@ -19,21 +19,28 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-bsd.c,v 1.7 1994/05/30 06:10:07 paulus Exp $"; +static char rcsid[] = "$Id: sys-bsd.c,v 1.21 1995/08/16 01:40:23 paulus Exp $"; #endif /* * TODO: */ +#include #include +#include +#include +#include +#include +#include #include #include #include #include -#include +#include #include +#include #include #include #include @@ -44,12 +51,75 @@ static char rcsid[] = "$Id: sys-bsd.c,v 1.7 1994/05/30 06:10:07 paulus 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. */ @@ -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; } @@ -646,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; @@ -658,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; } @@ -668,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; ) { + 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)); @@ -676,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)) @@ -685,15 +958,14 @@ 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 *) &ifr->ifr_addr)->sin_addr.s_addr; + mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr; if ((ipaddr & mask) != (ina & mask)) continue; break; } - ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len); } if (ifr >= ifend) @@ -721,23 +993,143 @@ get_ether_addr(ipaddr, hwaddr) 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; + } } diff --git a/usr.sbin/pppd/sys-linux.c b/usr.sbin/pppd/sys-linux.c deleted file mode 100644 index 306ae4a8bca1..000000000000 --- a/usr.sbin/pppd/sys-linux.c +++ /dev/null @@ -1,830 +0,0 @@ -/* - * sys-linux.c - System-dependent procedures for setting up - * PPP interfaces on Linux systems - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/* - * TODO: - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "pppd.h" -#include "ppp.h" -#include "fsm.h" -#include "ipcp.h" - -static int initdisc = -1; /* Initial TTY discipline */ -static int prev_kdebugflag = 0; -extern int kdebugflag; -extern u_long netmask; - -#define MAX_IFS 32 - -/* prototypes */ -void die __ARGS((int)); - -/* - * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, - * if it exists. - */ - -#define SET_SA_FAMILY(addr, family) \ - memset ((char *) &(addr), '\0', sizeof(addr)); \ - addr.sa_family = (family); - -/* - * set_kdebugflag - Define the debugging level for the kernel - */ - -int set_kdebugflag (int requested_level) -{ - if (ioctl(fd, PPPIOCGDEBUG, &prev_kdebugflag) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCGDEBUG): %m"); - return (0); - } - - if (prev_kdebugflag != requested_level) { - if (ioctl(fd, PPPIOCSDEBUG, &requested_level) < 0) { - syslog (LOG_ERR, "ioctl(PPPIOCSDEBUG): %m"); - return (0); - } - syslog(LOG_INFO, "set kernel debugging level to %d", requested_level); - } - return (1); -} - -/* - * establish_ppp - Turn the serial port into a ppp interface. - */ - -void establish_ppp (void) -{ - int pppdisc = N_PPP; - int sig = SIGIO; - - if (ioctl(fd, PPPIOCSINPSIG, &sig) == -1) { - syslog(LOG_ERR, "ioctl(PPPIOCSINPSIG): %m"); - die(1); - } - - if (ioctl(fd, TIOCEXCL, 0) < 0) { - syslog (LOG_WARNING, "ioctl(TIOCEXCL): %m"); - } - - if (ioctl(fd, TIOCGETD, &initdisc) < 0) { - syslog(LOG_ERR, "ioctl(TIOCGETD): %m"); - die (1); - } - - if (ioctl(fd, TIOCSETD, &pppdisc) < 0) { - syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); - die (1); - } - - if (ioctl(fd, PPPIOCGUNIT, &ifunit) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m"); - die (1); - } - - set_kdebugflag (kdebugflag); -} - -/* - * disestablish_ppp - Restore the serial port to normal operation. - * This shouldn't call die() because it's called from die(). - */ - -void disestablish_ppp(void) -{ - int x; - char *s; - - if (initdisc >= 0) { - set_kdebugflag (prev_kdebugflag); - /* - * Check whether the link seems not to be 8-bit clean. - */ - if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) { - s = NULL; - switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) { - case SC_RCV_B7_0: - s = "bit 7 set to 1"; - break; - case SC_RCV_B7_1: - s = "bit 7 set to 0"; - break; - case SC_RCV_EVNP: - s = "odd parity"; - break; - case SC_RCV_ODDP: - s = "even parity"; - break; - } - if (s != NULL) { - syslog(LOG_WARNING, "Serial link is not 8-bit clean:"); - syslog(LOG_WARNING, "All received characters had %s", s); - } - } - - if (ioctl(fd, TIOCSETD, &initdisc) < 0) - syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); - - if (ioctl(fd, TIOCNXCL, 0) < 0) - syslog (LOG_WARNING, "ioctl(TIOCNXCL): %m"); - - initdisc = -1; - } -} - -/* - * output - Output PPP packet. - */ - -void output (int unit, unsigned char *p, int len) -{ - if (unit != 0) - MAINDEBUG((LOG_WARNING, "output: unit != 0!")); - - if (debug) - log_packet(p, len, "sent "); - - if (write(fd, p, len) < 0) { - syslog(LOG_ERR, "write: %m"); - die(1); - } -} - -/* - * read_packet - get a PPP packet from the serial device. - */ - -int read_packet (unsigned char *buf) -{ - int len; - - len = read(fd, buf, MTU + DLLHEADERLEN); - if (len < 0) { - if (errno == EWOULDBLOCK) { -#if 0 - MAINDEBUG((LOG_DEBUG, "read(fd): EWOULDBLOCK")); -#endif - return -1; - } - syslog(LOG_ERR, "read(fd): %m"); - die(1); - } - return len; -} - -/* - * ppp_send_config - configure the transmit characteristics of - * the ppp interface. - */ -void ppp_send_config (int unit,int mtu,u_long asyncmap,int pcomp,int accomp) -{ - u_int x; - struct ifreq ifr; - - MAINDEBUG ((LOG_DEBUG, "send_config: mtu = %d\n", mtu)); - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - ifr.ifr_mtu = mtu; - if (ioctl(s, SIOCSIFMTU, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m"); - quit(); - } - - MAINDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap)); - if (ioctl(fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSASYNCMAP): %m"); - quit(); - } - - if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); - quit(); - } - - x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT; - x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC; - - MAINDEBUG ((LOG_DEBUG, "send_config: flags = %x\n", x)); - if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); - quit(); - } -} - -/* - * ppp_set_xaccm - set the extended transmit ACCM for the interface. - */ -void -ppp_set_xaccm(unit, accm) - int unit; - ext_accm accm; -{ - MAINDEBUG ((LOG_DEBUG, "set_xaccm: %08lx %08lx %08lx %08lx\n", - accm[0], accm[1], accm[2], accm[3])); - if (ioctl(fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) - syslog(LOG_WARNING, "ioctl(set extended ACCM): %m"); -} - -/* - * ppp_recv_config - configure the receive-side characteristics of - * the ppp interface. - */ -void ppp_recv_config (int unit,int mru,u_long asyncmap,int pcomp,int accomp) -{ - u_int x; - - MAINDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru)); - if (ioctl(fd, PPPIOCSMRU, (caddr_t) &mru) < 0) - syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %m"); - - MAINDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap)); - if (ioctl(fd, PPPIOCRASYNCMAP, (caddr_t) &asyncmap) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCRASYNCMAP): %m"); - quit(); - } - - if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); - quit(); - } - - x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC; - MAINDEBUG ((LOG_DEBUG, "recv_config: flags = %x\n", x)); - if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); - quit(); - } -} - -/* - * sifvjcomp - config tcp header compression - */ - -int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid) -{ - u_int x; - - if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); - return 0; - } - - x = vjcomp ? x | SC_COMP_TCP : x &~ SC_COMP_TCP; - x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID; - - if(ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); - return 0; - } - - if (vjcomp) { - if (ioctl (fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { - syslog (LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); - return 0; - } - } - - return 1; -} - -/* - * sifup - Config the interface up and enable IP packets to pass. - */ - -int sifup (int u) -{ - struct ifreq ifr; - - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); - return 0; - } - - ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT); - if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m"); - return 0; - } - return 1; -} - -/* - * sifdown - Config the interface down and disable IP. - */ - -int sifdown (int u) -{ - struct ifreq ifr; - - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); - return 0; - } - - ifr.ifr_flags &= ~IFF_UP; - ifr.ifr_flags |= IFF_POINTOPOINT; - if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m"); - return 0; - } - return 1; -} - -/* - * sifaddr - Config the interface IP addresses and netmask. - */ - -int sifaddr (int unit, int our_adr, int his_adr, int net_mask) -{ - struct ifreq ifr; - struct rtentry rt; - - SET_SA_FAMILY (ifr.ifr_addr, AF_INET); - SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); - SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); - - strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); -/* - * Set our IP address - */ - ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = our_adr; - if (ioctl(s, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - if (errno != EEXIST) - syslog (LOG_ERR, "ioctl(SIOCAIFADDR): %m"); - else - syslog (LOG_WARNING, "ioctl(SIOCAIFADDR): Address already exists"); - return (0); - } -/* - * Set the gateway address - */ - ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = his_adr; - if (ioctl(s, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { - syslog (LOG_ERR, "ioctl(SIOCSIFDSTADDR): %m"); - return (0); - } -/* - * Set the netmask - */ - if (net_mask != 0) { - ((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr.s_addr = net_mask; - if (ioctl(s, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) { - syslog (LOG_ERR, "ioctl(SIOCSIFNETMASK): %m"); - return (0); - } - } -/* - * Add the device route - */ - memset (&rt, '\0', sizeof (rt)); - - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - rt.rt_dev = ifname; /* MJC */ - - ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0; - ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = his_adr; - rt.rt_flags = RTF_UP | RTF_HOST; - - if (ioctl(s, SIOCADDRT, &rt) < 0) { - syslog (LOG_ERR, "ioctl(SIOCADDRT) device route: %m"); - return (0); - } - return 1; -} - -/* - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - */ - -int cifaddr (int unit, int our_adr, int his_adr) -{ - struct rtentry rt; -/* - * Delete the route through the device - */ - memset (&rt, '\0', sizeof (rt)); - - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - rt.rt_dev = ifname; /* MJC */ - - ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0; - ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = his_adr; - rt.rt_flags = RTF_UP | RTF_HOST; - - if (ioctl(s, SIOCDELRT, &rt) < 0) { - syslog (LOG_ERR, "ioctl(SIOCDELRT) device route: %m"); - return (0); - } - return 1; -} - -/* - * path_to_route - determine the path to the proc file system data - */ - -FILE *route_fd = (FILE *) 0; -static char route_buffer [100]; - -static char *path_to_route (void); -static int open_route_table (void); -static void close_route_table (void); -static int read_route_table (struct rtentry *rt); -static int defaultroute_exists (void); - -/* - * path_to_route - find the path to the route tables in the proc file system - */ - -static char *path_to_route (void) -{ - struct mntent *mntent; - FILE *fp; - - fp = fopen (MOUNTED, "r"); - if (fp != 0) { - while ((mntent = getmntent (fp)) != 0) { - if (strcmp (mntent->mnt_type, MNTTYPE_IGNORE) == 0) - continue; - - if (strcmp (mntent->mnt_type, "proc") == 0) { - strncpy (route_buffer, mntent->mnt_dir, - sizeof (route_buffer)-10); - route_buffer [sizeof (route_buffer)-10] = '\0'; - strcat (route_buffer, "/net/route"); - - fclose (fp); - return (route_buffer); - } - } - fclose (fp); - } - syslog (LOG_ERR, "proc file system not mounted"); - return 0; -} - -/* - * open_route_table - open the interface to the route table - */ - -static int open_route_table (void) -{ - char *path; - - if (route_fd != (FILE *) 0) - close_route_table(); - - path = path_to_route(); - if (path == NULL) - return 0; - - route_fd = fopen (path, "r"); - if (route_fd == (FILE *) 0) { - syslog (LOG_ERR, "can not open %s: %m", path); - return 0; - } - - /* read and discard the header line. */ - if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0) { - close_route_table(); - return 0; - } - return 1; -} - -/* - * close_route_table - close the interface to the route table - */ - -static void close_route_table (void) -{ - if (route_fd != (FILE *) 0) { - fclose (route_fd); - route_fd = (FILE *) 0; - } -} - -/* - * read_route_table - read the next entry from the route table - */ - -static int read_route_table (struct rtentry *rt) -{ - static char delims[] = " \t\n"; - char *dev_ptr, *ptr, *dst_ptr, *gw_ptr, *flag_ptr; - - if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0) - return 0; - - memset (rt, '\0', sizeof (struct rtentry)); - - dev_ptr = strtok (route_buffer, delims); /* interface name */ - dst_ptr = strtok (NULL, delims); /* destination address */ - gw_ptr = strtok (NULL, delims); /* gateway */ - flag_ptr = strtok (NULL, delims); /* flags */ -#if 0 - ptr = strtok (NULL, delims); /* reference count */ - ptr = strtok (NULL, delims); /* useage count */ - ptr = strtok (NULL, delims); /* metric */ - ptr = strtok (NULL, delims); /* mask */ -#endif - - ((struct sockaddr_in *) &rt->rt_dst)->sin_addr.s_addr = - strtoul (dst_ptr, NULL, 16); - - ((struct sockaddr_in *) &rt->rt_gateway)->sin_addr.s_addr = - strtoul (gw_ptr, NULL, 16); - - rt->rt_flags = (short) strtoul (flag_ptr, NULL, 16); - rt->rt_dev = dev_ptr; - - return 1; -} - -/* - * defaultroute_exists - determine if there is a default route - */ - -static int defaultroute_exists (void) -{ - struct rtentry rt; - int result = 0; - - if (!open_route_table()) - return 0; - - while (read_route_table(&rt) != 0) { - if (rt.rt_flags & RTF_UP == 0) - continue; - - if (((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr == 0L) { - syslog (LOG_ERR, - "ppp not replacing existing default route to %s[%s]", - rt.rt_dev, - inet_ntoa (((struct sockaddr_in *) &rt.rt_gateway)-> - sin_addr.s_addr)); - result = 1; - break; - } - } - close_route_table(); - return result; -} - -/* - * sifdefaultroute - assign a default route through the address given. - */ - -int sifdefaultroute (int unit, int gateway) -{ - struct rtentry rt; - - if (defaultroute_exists()) - return 0; - - memset (&rt, '\0', sizeof (rt)); - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway; - - rt.rt_flags = RTF_UP | RTF_GATEWAY; - if (ioctl(s, SIOCADDRT, &rt) < 0) { - syslog (LOG_ERR, "default route ioctl(SIOCADDRT): %m"); - return 0; - } - return 1; -} - -/* - * cifdefaultroute - delete a default route through the address given. - */ - -int cifdefaultroute (int unit, int gateway) -{ - struct rtentry rt; - - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway; - - rt.rt_flags = RTF_UP | RTF_GATEWAY; - if (ioctl(s, SIOCDELRT, &rt) < 0) { - syslog (LOG_ERR, "default route ioctl(SIOCDELRT): %m"); - return 0; - } - return 1; -} - -/* - * sifproxyarp - Make a proxy ARP entry for the peer. - */ - -int sifproxyarp (int unit, u_long his_adr) -{ - struct arpreq arpreq; - - memset (&arpreq, '\0', sizeof(arpreq)); -/* - * Get the hardware address of an interface on the same subnet - * as our local address. - */ - if (!get_ether_addr(his_adr, &arpreq.arp_ha)) { - syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP"); - return 0; - } - - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr; - arpreq.arp_flags = ATF_PERM | ATF_PUBL; - - if (ioctl(s, SIOCSARP, (caddr_t)&arpreq) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSARP): %m"); - return 0; - } - return 1; -} - -/* - * cifproxyarp - Delete the proxy ARP entry for the peer. - */ - -int cifproxyarp (int unit, u_long his_adr) -{ - struct arpreq arpreq; - - memset (&arpreq, '\0', sizeof(arpreq)); - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - - ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr; - if (ioctl(s, SIOCDARP, (caddr_t)&arpreq) < 0) { - syslog(LOG_WARNING, "ioctl(SIOCDARP): %m"); - return 0; - } - return 1; -} - -/* - * get_ether_addr - get the hardware address of an interface on the - * the same subnet as ipaddr. - */ - -int get_ether_addr (u_long ipaddr, struct sockaddr *hwaddr) -{ - struct ifreq *ifr, *ifend, *ifp; - int i; - u_long ina, mask; - struct sockaddr_dl *dla; - struct ifreq ifreq; - struct ifconf ifc; - struct ifreq ifs[MAX_IFS]; - - ifc.ifc_len = sizeof(ifs); - ifc.ifc_req = ifs; - if (ioctl(s, SIOCGIFCONF, &ifc) < 0) { - syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m"); - return 0; - } - MAINDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s", - ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr))); -/* - * Scan through looking for an interface with an Internet - * address on the same subnet as `ipaddr'. - */ - ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq)); - for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { - 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)); - MAINDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s", - ifreq.ifr_name)); -/* - * Check that the interface is up, and not point-to-point - * or loopback. - */ - if (ioctl(s, SIOCGIFFLAGS, &ifreq) < 0) - continue; - if ((ifreq.ifr_flags & - (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP)) - != (IFF_UP|IFF_BROADCAST)) - continue; -/* - * Get its netmask and check that it's on the right subnet. - */ - if (ioctl(s, SIOCGIFNETMASK, &ifreq) < 0) - continue; - mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr; - MAINDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx", - ip_ntoa(ina), ntohl(mask))); - if (((ipaddr ^ ina) & mask) != 0) - continue; - break; - } - } - - if (ifr >= ifend) - return 0; - - syslog(LOG_INFO, "found interface %s for proxy arp", ifreq.ifr_name); -/* - * Now get the hardware address. - */ - if (ioctl (s, SIOCGIFHWADDR, &ifreq) < 0) { - syslog(LOG_ERR, "SIOCGIFHWADDR(%s): %m", ifreq.ifr_name); - return 0; - } - - hwaddr->sa_family = ARPHRD_ETHER; -#ifndef old_ifr_hwaddr - memcpy (&hwaddr->sa_data, &ifreq.ifr_hwaddr, ETH_ALEN); -#else - memcpy (&hwaddr->sa_data, &ifreq.ifr_hwaddr.sa_data, ETH_ALEN); -#endif - - MAINDEBUG ((LOG_DEBUG, - "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x", - (int) ((unsigned char *) &hwaddr->sa_data)[0], - (int) ((unsigned char *) &hwaddr->sa_data)[1], - (int) ((unsigned char *) &hwaddr->sa_data)[2], - (int) ((unsigned char *) &hwaddr->sa_data)[3], - (int) ((unsigned char *) &hwaddr->sa_data)[4], - (int) ((unsigned char *) &hwaddr->sa_data)[5])); - return 1; -} - -/* - * 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(void) -{ - int s, ok; - struct ifreq ifr; - - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) - return 1; /* can't tell - maybe we're not root */ - - strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); - ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; - close(s); - - return ok; -} - -int -logwtmp(line, name, host) - char *line, *name, *host; -{ - struct utmp ut; - - memset (&ut, 0, sizeof (ut)); - (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); - (void)time(&ut.ut_time); - - pututline (&ut); /* Write the line to the proper place */ - endutent(); /* Indicate operation is complete */ -} diff --git a/usr.sbin/pppd/sys-str.c b/usr.sbin/pppd/sys-str.c deleted file mode 100644 index c197d4bf3cd2..000000000000 --- a/usr.sbin/pppd/sys-str.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - * sys-str.c - System-dependent procedures for setting up - * PPP interfaces on systems which use the STREAMS ppp interface. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/* - * TODO: - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "pppd.h" -#include "ppp.h" -#include - -#ifndef ifr_mtu -#define ifr_mtu ifr_metric -#endif - -#define MAXMODULES 10 /* max number of module names to save */ -static struct modlist { - char modname[FMNAMESZ+1]; -} str_modules[MAXMODULES]; -static int str_module_count = 0; -static int pushed_ppp; - -extern int hungup; /* has the physical layer been disconnected? */ -extern int kdebugflag; - -#define PAI_FLAGS_B7_0 0x100 -#define PAI_FLAGS_B7_1 0x200 -#define PAI_FLAGS_PAR_EVEN 0x400 -#define PAI_FLAGS_PAR_ODD 0x800 -#define PAI_FLAGS_HIBITS 0xF00 - -/* - * ppp_available - check if this kernel supports PPP. - */ -int -ppp_available() -{ - int fd, ret; - - fd = open("/dev/tty", O_RDONLY, 0); - if (fd < 0) - return 1; /* can't find out - assume we have ppp */ - ret = ioctl(fd, I_FIND, "pppasync") >= 0; - close(fd); - return ret; -} - - -/* - * establish_ppp - Turn the serial port into a ppp interface. - */ -void -establish_ppp() -{ - /* go through and save the name of all the modules, then pop em */ - for (;;) { - if (ioctl(fd, I_LOOK, str_modules[str_module_count].modname) < 0 || - ioctl(fd, I_POP, 0) < 0) - break; - MAINDEBUG((LOG_DEBUG, "popped stream module : %s", - str_modules[str_module_count].modname)); - str_module_count++; - } - - /* now push the async/fcs module */ - if (ioctl(fd, I_PUSH, "pppasync") < 0) { - syslog(LOG_ERR, "ioctl(I_PUSH, ppp_async): %m"); - die(1); - } - /* finally, push the ppp_if module that actually handles the */ - /* network interface */ - if (ioctl(fd, I_PUSH, "pppif") < 0) { - syslog(LOG_ERR, "ioctl(I_PUSH, ppp_if): %m"); - die(1); - } - pushed_ppp = 1; - if (ioctl(fd, I_SETSIG, S_INPUT) < 0) { - syslog(LOG_ERR, "ioctl(I_SETSIG, S_INPUT): %m"); - die(1); - } - /* read mode, message non-discard mode */ - if (ioctl(fd, I_SRDOPT, RMSGN) < 0) { - syslog(LOG_ERR, "ioctl(I_SRDOPT, RMSGN): %m"); - die(1); - } - /* Flush any waiting messages, or we'll never get SIGPOLL */ - if (ioctl(fd, I_FLUSH, FLUSHRW) < 0) { - syslog(LOG_ERR, "ioctl(I_FLUSH, FLUSHRW): %m"); - die(1); - } - /* - * Find out which interface we were given. - * (ppp_if handles this ioctl) - */ - if (ioctl(fd, SIOCGETU, &ifunit) < 0) { - syslog(LOG_ERR, "ioctl(SIOCGETU): %m"); - die(1); - } - - /* Set debug flags in driver */ - if (ioctl(fd, SIOCSIFDEBUG, &kdebugflag) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFDEBUG): %m"); - } -} - -/* - * disestablish_ppp - Restore the serial port to normal operation. - * It attempts to reconstruct the stream with the previously popped - * modules. This shouldn't call die() because it's called from die(). - */ -void -disestablish_ppp() -{ - int flags; - char *s; - - if (hungup) { - /* we can't push or pop modules after the stream has hung up */ - str_module_count = 0; - return; - } - - if (pushed_ppp) { - /* - * Check whether the link seems not to be 8-bit clean. - */ - if (ioctl(fd, SIOCGIFDEBUG, (caddr_t) &flags) == 0) { - s = NULL; - switch (~flags & PAI_FLAGS_HIBITS) { - case PAI_FLAGS_B7_0: - s = "bit 7 set to 1"; - break; - case PAI_FLAGS_B7_1: - s = "bit 7 set to 0"; - break; - case PAI_FLAGS_PAR_EVEN: - s = "odd parity"; - break; - case PAI_FLAGS_PAR_ODD: - s = "even parity"; - break; - } - if (s != NULL) { - syslog(LOG_WARNING, "Serial link is not 8-bit clean:"); - syslog(LOG_WARNING, "All received characters had %s", s); - } - } - } - - while (ioctl(fd, I_POP, 0) == 0) /* pop any we pushed */ - ; - pushed_ppp = 0; - - for (; str_module_count > 0; str_module_count--) { - if (ioctl(fd, I_PUSH, str_modules[str_module_count-1].modname)) { - syslog(LOG_WARNING, "str_restore: couldn't push module %s: %m", - str_modules[str_module_count-1].modname); - } else { - MAINDEBUG((LOG_INFO, "str_restore: pushed module %s", - str_modules[str_module_count-1].modname)); - } - } -} - - -/* - * output - Output PPP packet. - */ -void -output(unit, p, len) - int unit; - u_char *p; - int len; -{ - struct strbuf str; - - if (unit != 0) - MAINDEBUG((LOG_WARNING, "output: unit != 0!")); - if (debug) - log_packet(p, len, "sent "); - - str.len = len; - str.buf = (caddr_t) p; - if(putmsg(fd, NULL, &str, 0) < 0) { - syslog(LOG_ERR, "putmsg: %m"); - die(1); - } -} - - -/* - * read_packet - get a PPP packet from the serial device. - */ -int -read_packet(buf) - u_char *buf; -{ - struct strbuf str; - int len, i; - - str.maxlen = MTU+DLLHEADERLEN; - str.buf = (caddr_t) buf; - i = 0; - len = getmsg(fd, NULL, &str, &i); - if (len < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - return -1; - } - syslog(LOG_ERR, "getmsg(fd) %m"); - die(1); - } - if (len) - MAINDEBUG((LOG_DEBUG, "getmsg returned 0x%x",len)); - - if (str.len < 0) { - MAINDEBUG((LOG_DEBUG, "getmsg short return length %d", str.len)); - return -1; - } - - return str.len; -} - - -/* - * ppp_send_config - configure the transmit characteristics of - * the ppp interface. - */ -void -ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) - int unit, mtu; - u_long asyncmap; - int pcomp, accomp; -{ - char c; - struct ifreq ifr; - - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - ifr.ifr_mtu = mtu; - if (ioctl(s, SIOCSIFMTU, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m"); - quit(); - } - - if(ioctl(fd, SIOCSIFASYNCMAP, (caddr_t) &asyncmap) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFASYNCMAP): %m"); - quit(); - } - - c = (pcomp? 1: 0); - if(ioctl(fd, SIOCSIFCOMPPROT, &c) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFCOMPPROT): %m"); - quit(); - } - - c = (accomp? 1: 0); - if(ioctl(fd, SIOCSIFCOMPAC, &c) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFCOMPAC): %m"); - quit(); - } -} - - -/* - * ppp_set_xaccm - set the extended transmit ACCM for the interface. - */ -void -ppp_set_xaccm(unit, accm) - int unit; - ext_accm accm; -{ - if (ioctl(fd, SIOCSIFXASYNCMAP, accm) < 0 && errno != ENOTTY) - syslog(LOG_WARNING, "ioctl(set extended ACCM): %m"); -} - - -/* - * ppp_recv_config - configure the receive-side characteristics of - * the ppp interface. - */ -void -ppp_recv_config(unit, mru, asyncmap, pcomp, accomp) - int unit, mru; - u_long asyncmap; - int pcomp, accomp; -{ - char c; - - if (ioctl(fd, SIOCSIFMRU, &mru) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFMRU): %m"); - } - - if (ioctl(fd, SIOCSIFRASYNCMAP, (caddr_t) &asyncmap) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFRASYNCMAP): %m"); - } - - c = 2 + (pcomp? 1: 0); - if(ioctl(fd, SIOCSIFCOMPPROT, &c) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFCOMPPROT): %m"); - } - - c = 2 + (accomp? 1: 0); - if (ioctl(fd, SIOCSIFCOMPAC, &c) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFCOMPAC): %m"); - } -} - -/* - * sifvjcomp - config tcp header compression - */ -int -sifvjcomp(u, vjcomp, cidcomp, maxcid) - int u, vjcomp, cidcomp, maxcid; -{ - char x; - - x = (vjcomp? 1: 0) + (cidcomp? 0: 2) + (maxcid << 4); - if (ioctl(fd, SIOCSIFVJCOMP, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFVJCOMP): %m"); - return 0; - } - return 1; -} - -/* - * sifup - Config the interface up. - */ -int -sifup(u) - int u; -{ - struct ifreq ifr; - - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(s, 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) { - syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m"); - return 0; - } - return 1; -} - -/* - * sifdown - Config the interface down. - */ -int -sifdown(u) - int u; -{ - struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(s, 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) { - syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m"); - return 0; - } - return 1; -} - -/* - * SET_SA_FAMILY - initialize a struct sockaddr, setting the sa_family field. - */ -#define SET_SA_FAMILY(addr, family) \ - BZERO((char *) &(addr), sizeof(addr)); \ - addr.sa_family = (family); - -/* - * sifaddr - Config the interface IP addresses and netmask. - */ -int -sifaddr(u, o, h, m) - int u; - u_long o, h, m; -{ - int ret; - struct ifreq ifr; - - ret = 1; - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - SET_SA_FAMILY(ifr.ifr_addr, AF_INET); - ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o; - if (ioctl(s, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFADDR): %m"); - ret = 0; - } - ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = h; - if (ioctl(s, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFDSTADDR): %m"); - ret = 0; - } - if (m != 0) { - ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = m; - syslog(LOG_INFO, "Setting interface mask to %s\n", ip_ntoa(m)); - if (ioctl(s, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFNETMASK): %m"); - ret = 0; - } - } - return ret; -} - -/* - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - */ -int -cifaddr(u, o, h) - int u; - u_long o, h; -{ - struct rtentry rt; - - SET_SA_FAMILY(rt.rt_dst, AF_INET); - ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = h; - SET_SA_FAMILY(rt.rt_gateway, AF_INET); - ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = o; - rt.rt_flags = RTF_HOST; - if (ioctl(s, SIOCDELRT, (caddr_t) &rt) < 0) { - syslog(LOG_ERR, "ioctl(SIOCDELRT): %m"); - return 0; - } - return 1; -} - -/* - * sifdefaultroute - assign a default route through the address given. - */ -int -sifdefaultroute(u, g) - int u; - u_long g; -{ - struct rtentry rt; - - SET_SA_FAMILY(rt.rt_dst, AF_INET); - SET_SA_FAMILY(rt.rt_gateway, AF_INET); - ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g; - rt.rt_flags = RTF_GATEWAY; - if (ioctl(s, SIOCADDRT, &rt) < 0) { - syslog(LOG_ERR, "default route ioctl(SIOCADDRT): %m"); - return 0; - } - return 1; -} - -/* - * cifdefaultroute - delete a default route through the address given. - */ -int -cifdefaultroute(u, g) - int u; - u_long g; -{ - struct rtentry rt; - - SET_SA_FAMILY(rt.rt_dst, AF_INET); - SET_SA_FAMILY(rt.rt_gateway, AF_INET); - ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g; - rt.rt_flags = RTF_GATEWAY; - if (ioctl(s, SIOCDELRT, &rt) < 0) { - syslog(LOG_ERR, "default route ioctl(SIOCDELRT): %m"); - return 0; - } - return 1; -} - -/* - * sifproxyarp - Make a proxy ARP entry for the peer. - */ -int -sifproxyarp(unit, hisaddr) - int unit; - u_long hisaddr; -{ - struct arpreq arpreq; - - BZERO(&arpreq, sizeof(arpreq)); - - /* - * Get the hardware address of an interface on the same subnet - * as our local address. - */ - if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) { - syslog(LOG_WARNING, "Cannot determine ethernet address for proxy ARP"); - return 0; - } - - 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) { - syslog(LOG_ERR, "ioctl(SIOCSARP): %m"); - return 0; - } - - return 1; -} - -/* - * cifproxyarp - Delete the proxy ARP entry for the peer. - */ -int -cifproxyarp(unit, hisaddr) - int unit; - u_long 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) { - syslog(LOG_ERR, "ioctl(SIOCDARP): %m"); - return 0; - } - return 1; -} - -/* - * get_ether_addr - get the hardware address of an interface on the - * the same subnet as ipaddr. Code borrowed from myetheraddr.c - * in the cslip-2.6 distribution, which is subject to the following - * copyright notice (which also applies to logwtmp below): - * - * Copyright (c) 1990, 1992 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include -#include -#include -#include - -/* XXX SunOS 4.1 defines this and 3.5 doesn't... */ -#ifdef _nlist_h -#define SUNOS4 -#endif - -#ifdef SUNOS4 -#include -#endif -#include - -/* Cast a struct sockaddr to a structaddr_in */ -#define SATOSIN(sa) ((struct sockaddr_in *)(sa)) - -/* Determine if "bits" is set in "flag" */ -#define ALLSET(flag, bits) (((flag) & (bits)) == (bits)) - -static struct nlist nl[] = { -#define N_IFNET 0 - { "_ifnet" }, - { 0 } -}; - -static void kread(); - -int -get_ether_addr(ipaddr, hwaddr) - u_long ipaddr; - struct sockaddr *hwaddr; -{ - register kvm_t *kd; - register struct ifnet *ifp; - register struct arpcom *ac; - struct arpcom arpcom; - struct in_addr *inp; -#ifdef SUNOS4 - register struct ifaddr *ifa; - register struct in_ifaddr *in; - union { - struct ifaddr ifa; - struct in_ifaddr in; - } ifaddr; -#endif - u_long addr, mask; - - /* Open kernel memory for reading */ - kd = kvm_open(0, 0, 0, O_RDONLY, NULL); - if (kd == 0) { - syslog(LOG_ERR, "kvm_open: %m"); - return 0; - } - - /* Fetch namelist */ - if (kvm_nlist(kd, nl) != 0) { - syslog(LOG_ERR, "kvm_nlist failed"); - return 0; - } - - ac = &arpcom; - ifp = &arpcom.ac_if; -#ifdef SUNOS4 - ifa = &ifaddr.ifa; - in = &ifaddr.in; -#endif - - if (kvm_read(kd, nl[N_IFNET].n_value, (char *)&addr, sizeof(addr)) - != sizeof(addr)) { - syslog(LOG_ERR, "error reading ifnet addr"); - return 0; - } - for ( ; addr; addr = (u_long)ifp->if_next) { - if (kvm_read(kd, addr, (char *)ac, sizeof(*ac)) != sizeof(*ac)) { - syslog(LOG_ERR, "error reading ifnet"); - return 0; - } - - /* Only look at configured, broadcast interfaces */ - if (!ALLSET(ifp->if_flags, IFF_UP | IFF_BROADCAST)) - continue; -#ifdef SUNOS4 - /* This probably can't happen... */ - if (ifp->if_addrlist == 0) - continue; -#endif - - /* Get interface ip address */ -#ifdef SUNOS4 - if (kvm_read(kd, (u_long)ifp->if_addrlist, (char *)&ifaddr, - sizeof(ifaddr)) != sizeof(ifaddr)) { - syslog(LOG_ERR, "error reading ifaddr"); - return 0; - } - inp = &SATOSIN(&ifa->ifa_addr)->sin_addr; -#else - inp = &SATOSIN(&ifp->if_addr)->sin_addr; -#endif - - /* Check if this interface on the right subnet */ -#ifdef SUNOS4 - mask = in->ia_subnetmask; -#else - mask = ifp->if_subnetmask; -#endif - if ((ipaddr & mask) != (inp->s_addr & mask)) - continue; - - /* Copy out the local ethernet address */ - hwaddr->sa_family = AF_UNSPEC; - BCOPY((caddr_t) &arpcom.ac_enaddr, hwaddr->sa_data, - sizeof(arpcom.ac_enaddr)); - return 1; /* success! */ - } - - /* couldn't find one */ - return 0; -} - -#define WTMPFILE "/usr/adm/wtmp" - -int -logwtmp(line, name, host) - char *line, *name, *host; -{ - int fd; - struct stat buf; - struct utmp ut; - - if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0) - return; - if (!fstat(fd, &buf)) { - (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); - (void)time(&ut.ut_time); - if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp)) - (void)ftruncate(fd, buf.st_size); - } - close(fd); -} diff --git a/usr.sbin/pppd/sys-ultrix.c b/usr.sbin/pppd/sys-ultrix.c deleted file mode 100644 index ca8f2a4a1875..000000000000 --- a/usr.sbin/pppd/sys-ultrix.c +++ /dev/null @@ -1,663 +0,0 @@ -/* - * sys-ultrix.c - System-dependent procedures for setting up - * PPP interfaces on Ultrix systems. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef lint -static char rcsid[] = "$Id: sys-ultrix.c,v 1.4 1994/05/25 06:30:49 paulus Exp $"; -#endif - -/* - * TODO: - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "pppd.h" -#include "ppp.h" - -static int initdisc = -1; /* Initial TTY discipline */ -extern int kdebugflag; - -/* - * establish_ppp - Turn the serial port into a ppp interface. - */ -void -establish_ppp() -{ - int pppdisc = PPPDISC; - int x; - - if (ioctl(fd, TIOCGETD, &initdisc) < 0) { - syslog(LOG_ERR, "ioctl(TIOCGETD): %m"); - die(1); - } - if (ioctl(fd, TIOCSETD, &pppdisc) < 0) { - syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); - die(1); - } - - /* - * Find out which interface we were given. - */ - if (ioctl(fd, PPPIOCGUNIT, &ifunit) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m"); - die(1); - } - - /* - * Enable debug in the driver if requested. - */ - if (kdebugflag) { - if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_WARNING, "ioctl (PPPIOCGFLAGS): %m"); - } else { - x |= (kdebugflag & 0xFF) * SC_DEBUG; - if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) - syslog(LOG_WARNING, "ioctl(PPPIOCSFLAGS): %m"); - } - } -} - - -/* - * disestablish_ppp - Restore the serial port to normal operation. - * This shouldn't call die() because it's called from die(). - */ -void -disestablish_ppp() -{ - int x; - char *s; - - if (initdisc >= 0) { - /* - * Check whether the link seems not to be 8-bit clean. - */ - if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) { - s = NULL; - switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) { - case SC_RCV_B7_0: - s = "bit 7 set to 1"; - break; - case SC_RCV_B7_1: - s = "bit 7 set to 0"; - break; - case SC_RCV_EVNP: - s = "odd parity"; - break; - case SC_RCV_ODDP: - s = "even parity"; - break; - } - if (s != NULL) { - syslog(LOG_WARNING, "Serial link is not 8-bit clean:"); - syslog(LOG_WARNING, "All received characters had %s", s); - } - } - if (ioctl(fd, TIOCSETD, &initdisc) < 0) - syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); - } -} - - -/* - * output - Output PPP packet. - */ -void -output(unit, p, len) - int unit; - u_char *p; - int len; -{ - if (unit != 0) - MAINDEBUG((LOG_WARNING, "output: unit != 0!")); - if (debug) - log_packet(p, len, "sent "); - - if (write(fd, p, len) < 0) { - syslog(LOG_ERR, "write: %m"); - die(1); - } -} - - -/* - * read_packet - get a PPP packet from the serial device. - */ -int -read_packet(buf) - u_char *buf; -{ - int len; - - if ((len = read(fd, buf, MTU + DLLHEADERLEN)) < 0) { - if (errno == EWOULDBLOCK) { - MAINDEBUG((LOG_DEBUG, "read(fd): EWOULDBLOCK")); - return -1; - } - syslog(LOG_ERR, "read(fd): %m"); - die(1); - } - return len; -} - - -/* - * ppp_send_config - configure the transmit characteristics of - * the ppp interface. - */ -void -ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) - int unit, mtu; - u_long asyncmap; - int pcomp, accomp; -{ - u_int x; - struct ifreq ifr; - - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - ifr.ifr_mtu = mtu; - if (ioctl(s, SIOCSIFMTU, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m"); - quit(); - } - - if (ioctl(fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSASYNCMAP): %m"); - quit(); - } - - if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); - quit(); - } - x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT; - x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC; - if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); - quit(); - } -} - - -/* - * ppp_set_xaccm - set the extended transmit ACCM for the interface. - */ -void -ppp_set_xaccm(unit, accm) - int unit; - ext_accm accm; -{ - if (ioctl(fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) - syslog(LOG_WARNING, "ioctl(set extended ACCM): %m"); -} - - -/* - * ppp_recv_config - configure the receive-side characteristics of - * the ppp interface. - */ -void -ppp_recv_config(unit, mru, asyncmap, pcomp, accomp) - int unit, mru; - u_long asyncmap; - int pcomp, accomp; -{ - int x; - - if (ioctl(fd, PPPIOCSMRU, (caddr_t) &mru) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %m"); - quit(); - } - if (ioctl(fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSRASYNCMAP): %m"); - quit(); - } - if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); - quit(); - } - x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC; - if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); - quit(); - } -} - -/* - * sifvjcomp - config tcp header compression - */ -int -sifvjcomp(u, vjcomp, cidcomp, maxcid) - int u, vjcomp, cidcomp, maxcid; -{ - u_int x; - - if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); - return 0; - } - x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP; - x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID; - if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); - return 0; - } - if (ioctl(fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); - return 0; - } - return 1; -} - -/* - * sifup - Config the interface up and enable IP packets to pass. - */ -int -sifup(u) -{ - struct ifreq ifr; - u_int x; - - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(s, 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) { - 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; - } - return 1; -} - -/* - * sifdown - Config the interface down and disable IP. - */ -int -sifdown(u) -{ - struct ifreq ifr; - u_int x; - int rv; - - 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"); - rv = 0; - } - } - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(s, 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) { - syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m"); - rv = 0; - } - } - return rv; -} - -/* - * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, - * if it exists. - */ -#define SET_SA_FAMILY(addr, family) \ - BZERO((char *) &(addr), sizeof(addr)); \ - addr.sa_family = (family); - -/* - * sifaddr - Config the interface IP addresses and netmask. - */ -int -sifaddr(u, o, h, m) -{ - int ret; - struct ifreq ifr; - - ret = 1; - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - SET_SA_FAMILY(ifr.ifr_addr, AF_INET); - ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o; - if (ioctl(s, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFADDR): %m"); - ret = 0; - } - ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = h; - if (ioctl(s, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFDSTADDR): %m"); - ret = 0; - } - if (m != 0) { - ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = m; - syslog(LOG_INFO, "Setting interface mask to %s\n", ip_ntoa(m)); - if (ioctl(s, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFNETMASK): %m"); - ret = 0; - } - } - return ret; -} - -/* - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - */ -int -cifaddr(u, o, h) -{ - struct rtentry rt; - - SET_SA_FAMILY(rt.rt_dst, AF_INET); - ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = h; - SET_SA_FAMILY(rt.rt_gateway, AF_INET); - ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = o; - rt.rt_flags = RTF_HOST; - if (ioctl(s, SIOCDELRT, (caddr_t) &rt) < 0) { - syslog(LOG_ERR, "ioctl(SIOCDELRT): %m"); - return 0; - } - return 1; -} - -/* - * sifdefaultroute - assign a default route through the address given. - */ -int -sifdefaultroute(u, g) -{ - struct rtentry rt; - - SET_SA_FAMILY(rt.rt_dst, AF_INET); - SET_SA_FAMILY(rt.rt_gateway, AF_INET); - ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g; - rt.rt_flags = RTF_GATEWAY; - if (ioctl(s, SIOCADDRT, &rt) < 0) { - syslog(LOG_ERR, "default route ioctl(SIOCADDRT): %m"); - return 0; - } - return 1; -} - -/* - * cifdefaultroute - delete a default route through the address given. - */ -int -cifdefaultroute(u, g) -{ - struct rtentry rt; - - SET_SA_FAMILY(rt.rt_dst, AF_INET); - SET_SA_FAMILY(rt.rt_gateway, AF_INET); - ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g; - rt.rt_flags = RTF_GATEWAY; - if (ioctl(s, SIOCDELRT, &rt) < 0) - syslog(LOG_WARNING, "default route ioctl(SIOCDELRT): %m"); -} - -/* - * sifproxyarp - Make a proxy ARP entry for the peer. - */ -int -sifproxyarp(unit, hisaddr) - int unit; - u_long hisaddr; -{ - struct arpreq arpreq; - - BZERO(&arpreq, sizeof(arpreq)); - - /* - * Get the hardware address of an interface on the same subnet - * as our local address. - */ - if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) { - syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP"); - return 0; - } - - 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) { - syslog(LOG_ERR, "ioctl(SIOCSARP): %m"); - return 0; - } - - return 1; -} - -/* - * cifproxyarp - Delete the proxy ARP entry for the peer. - */ -int -cifproxyarp(unit, hisaddr) - int unit; - u_long 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) { - syslog(LOG_WARNING, "ioctl(SIOCDARP): %m"); - return 0; - } - return 1; -} - -/* - * get_ether_addr - get the hardware address of an interface on the - * the same subnet as ipaddr. - */ -#define MAX_IFS 32 - -int -get_ether_addr(ipaddr, hwaddr) - u_long ipaddr; - struct sockaddr *hwaddr; -{ - struct ifreq *ifr, *ifend, *ifp; - u_long ina, mask; - struct sockaddr_dl *dla; - struct ifreq ifreq; - struct ifconf ifc; - struct ifreq ifs[MAX_IFS]; - - ifc.ifc_len = sizeof(ifs); - ifc.ifc_req = ifs; - if (ioctl(s, SIOCGIFCONF, &ifc) < 0) { - syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m"); - return 0; - } - - /* - * Scan through looking for an interface with an Internet - * address on the same subnet as `ipaddr'. - */ - ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - for (ifr = ifc.ifc_req; ifr < ifend; ) { - 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)); - /* - * Check that the interface is up, and not point-to-point - * or loopback. - */ - if (ioctl(s, SIOCGIFFLAGS, &ifreq) < 0) - continue; - if ((ifreq.ifr_flags & - (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP)) - != (IFF_UP|IFF_BROADCAST)) - continue; - /* - * Get its netmask and check that it's on the right subnet. - */ - if (ioctl(s, SIOCGIFNETMASK, &ifreq) < 0) - continue; - mask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; - if ((ipaddr & mask) != (ina & mask)) - continue; - - break; - } - ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + sizeof(struct sockaddr) -); - } - - if (ifr >= ifend) - return 0; - syslog(LOG_DEBUG, "found interface %s for proxy arp", ifr->ifr_name); - - /* - * Now scan through again looking for a link-level address - * for this interface. - */ - ifp = ifr; - for (ifr = ifc.ifc_req; ifr < ifend; ) { - if (strcmp(ifp->ifr_name, ifr->ifr_name) == 0 - && ifr->ifr_addr.sa_family == AF_DLI) { -/* && ifr->ifr_addr.sa_family == AF_LINK) { Per! Kolla !!! ROHACK */ - /* - * Found the link-level address - copy it out - */ - dla = (struct sockaddr_dl *)&ifr->ifr_addr; - hwaddr->sa_family = AF_UNSPEC; - BCOPY(dla, hwaddr->sa_data, sizeof(hwaddr->sa_data)); - return 1; - } - ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + sizeof(struct sockaddr) -); - } - - return 0; -} - - -/* - * 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; - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - return 1; /* can't tell - maybe we're not root */ - - strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); - ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; - close(s); - - return ok; -} - - -/* - Seems like strdup() is not part of string package in Ultrix. - If I understood the man-page on the sun this should work. - - Robert Olsson -*/ - -char *strdup( in ) char *in; -{ - char* dup; - if(! (dup = (char *) malloc( strlen( in ) +1 ))) return NULL; - (void) strcpy( dup, in ); - return dup; -} - -/* - * This logwtmp() implementation is subject to the following copyright: - * - * Copyright (c) 1988 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#define WTMPFILE "/usr/adm/wtmp" - -int -logwtmp(line, name, host) - char *line, *name, *host; -{ - int fd; - struct stat buf; - struct utmp ut; - - if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0) - return; - if (!fstat(fd, &buf)) { - (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); - (void)time(&ut.ut_time); - if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp)) - (void)ftruncate(fd, buf.st_size); - } - close(fd); -} diff --git a/usr.sbin/pppd/upap.c b/usr.sbin/pppd/upap.c index 61d22acbf286..aed4a7b0e1a5 100644 --- a/usr.sbin/pppd/upap.c +++ b/usr.sbin/pppd/upap.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: upap.c,v 1.2 1994/04/11 07:13:44 paulus 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/04/11 07:13:44 paulus Exp $"; */ #include +#include #include #include #include -#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); } @@ -435,7 +464,7 @@ upap_sauthreq(u) 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; diff --git a/usr.sbin/pppd/upap.h b/usr.sbin/pppd/upap.h index 10c3414a0afa..8b1501964ad2 100644 --- a/usr.sbin/pppd/upap.h +++ b/usr.sbin/pppd/upap.h @@ -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 *));