summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorjoshd <joshd@cvs.openbsd.org>1996-07-20 12:02:16 +0000
committerjoshd <joshd@cvs.openbsd.org>1996-07-20 12:02:16 +0000
commitd1ca06e9f2af777503835fcef79a3827eef02cd2 (patch)
tree0a8b89f672dd48513d85694a0f63e93191380c82 /usr.sbin
parentb9db315696088975891987c416c6eafdbed087eb (diff)
Update pppd to 2.3a4:
Add redo option error-reporting, add PAM, add microsoft compatibility kludges, bzero stuff at important places, add one or two options other generic enhancements. From: Paul.Mackerras@cs.anu.edu.au
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/pppd/Makefile4
-rw-r--r--usr.sbin/pppd/auth.c322
-rw-r--r--usr.sbin/pppd/ccp.c126
-rw-r--r--usr.sbin/pppd/ccp.h15
-rw-r--r--usr.sbin/pppd/chap.c74
-rw-r--r--usr.sbin/pppd/chap.h11
-rw-r--r--usr.sbin/pppd/chap_ms.c184
-rw-r--r--usr.sbin/pppd/chap_ms.h32
-rw-r--r--usr.sbin/pppd/demand.c37
-rw-r--r--usr.sbin/pppd/fsm.c20
-rw-r--r--usr.sbin/pppd/ipcp.c118
-rw-r--r--usr.sbin/pppd/ipcp.h12
-rw-r--r--usr.sbin/pppd/ipxcp.c1394
-rw-r--r--usr.sbin/pppd/ipxcp.h64
-rw-r--r--usr.sbin/pppd/lcp.c100
-rw-r--r--usr.sbin/pppd/lcp.h9
-rw-r--r--usr.sbin/pppd/main.c418
-rw-r--r--usr.sbin/pppd/md4.c295
-rw-r--r--usr.sbin/pppd/md4.h52
-rw-r--r--usr.sbin/pppd/options.c214
-rw-r--r--usr.sbin/pppd/patchlevel.h6
-rw-r--r--usr.sbin/pppd/pathnames.h4
-rw-r--r--usr.sbin/pppd/pppd.h75
-rw-r--r--usr.sbin/pppd/upap.c51
-rw-r--r--usr.sbin/pppd/upap.h9
25 files changed, 3340 insertions, 306 deletions
diff --git a/usr.sbin/pppd/Makefile b/usr.sbin/pppd/Makefile
index 65c24f33248..f8552ded808 100644
--- a/usr.sbin/pppd/Makefile
+++ b/usr.sbin/pppd/Makefile
@@ -1,10 +1,10 @@
-# $OpenBSD: Makefile,v 1.5 1996/05/29 19:14:37 deraadt Exp $
+# $OpenBSD: Makefile,v 1.6 1996/07/20 12:02:03 joshd Exp $
# $NetBSD: Makefile,v 1.12 1996/03/19 03:03:04 jtc Exp $
PROG= pppd
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 demand.c gencode.c grammar.c scanner.c \
- nametoaddr.c optimize.c bpf_filter.c
+ nametoaddr.c optimize.c bpf_filter.c chap_ms.c ipxcp.c md4.c
.PATH: ${.CURDIR}/../../lib/libpcap ${.CURDIR}/../../sys/net
MAN= pppd.8
SUBDIR= pppstats chat
diff --git a/usr.sbin/pppd/auth.c b/usr.sbin/pppd/auth.c
index 458a8f90612..765e2c7ba60 100644
--- a/usr.sbin/pppd/auth.c
+++ b/usr.sbin/pppd/auth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.c,v 1.3 1996/04/21 23:41:16 deraadt Exp $ */
+/* $OpenBSD: auth.c,v 1.4 1996/07/20 12:02:04 joshd Exp $ */
/*
* auth.c - PPP authentication and phase control.
@@ -35,7 +35,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: auth.c,v 1.3 1996/04/21 23:41:16 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: auth.c,v 1.4 1996/07/20 12:02:04 joshd Exp $";
#endif
#include <stdio.h>
@@ -53,6 +53,11 @@ static char rcsid[] = "$OpenBSD: auth.c,v 1.3 1996/04/21 23:41:16 deraadt Exp $"
#include <netinet/in.h>
#include <arpa/inet.h>
+#ifdef USE_PAM
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+#endif
+
#ifdef HAS_SHADOW
#include <shadow.h>
#include <shadow/pwauth.h>
@@ -88,12 +93,18 @@ struct wordlist {
#define FALSE 0
#define TRUE 1
+/* The name by which the peer authenticated itself to us. */
+char peer_authname[MAXNAMELEN];
+
/* Records which authentication operations haven't completed yet. */
static int auth_pending[NUM_PPP];
/* Set if we have successfully called login() */
static int logged_in;
+/* Set if we have run the /etc/ppp/auth-up script. */
+static int did_authup;
+
/* List of addresses which the peer may use. */
static struct wordlist *addresses[NUM_PPP];
@@ -103,6 +114,9 @@ static int num_np_open;
/* Number of network protocols which have come up. */
static int num_np_up;
+/* Set if we got the contents of passwd[] from the pap-secrets file. */
+static int passwd_from_file;
+
/* Bits in auth_pending[] */
#define UPAP_WITHPEER 1
#define UPAP_PEER 2
@@ -116,13 +130,15 @@ static void check_idle __P((caddr_t));
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 get_upap_passwd __P((char *));
static int have_upap_secret __P((void));
static int have_chap_secret __P((char *, char *, u_int32_t));
static int ip_addr_check __P((u_int32_t, struct wordlist *));
static int scan_authfile __P((FILE *, char *, char *, u_int32_t, char *,
struct wordlist **, char *));
static void free_wordlist __P((struct wordlist *));
+static void auth_script __P((char *));
+
/*
* An Open on LCP has requested a change from Dead to Establish phase.
@@ -160,6 +176,10 @@ link_down(unit)
int i;
struct protent *protp;
+ if (did_authup) {
+ auth_script(_PATH_AUTHDOWN);
+ did_authup = 0;
+ }
for (i = 0; (protp = protocols[i]) != NULL; ++i) {
if (!protp->enabled_flag)
continue;
@@ -167,6 +187,7 @@ link_down(unit)
(*protp->lowerdown)(unit);
if (protp->protocol < 0xC000 && protp->close != NULL)
(*protp->close)(unit, "LCP link down");
+
}
num_np_open = 0;
num_np_up = 0;
@@ -223,6 +244,11 @@ link_established(unit)
ChapAuthWithPeer(unit, our_name, ho->chap_mdtype);
auth |= CHAP_WITHPEER;
} else if (ho->neg_upap) {
+ if (passwd[0] == 0) {
+ passwd_from_file = 1;
+ if (!get_upap_passwd(passwd))
+ syslog(LOG_ERR, "No secret found for PAP login");
+ }
upap_authwithpeer(unit, user, passwd);
auth |= UPAP_WITHPEER;
}
@@ -241,10 +267,21 @@ network_phase(unit)
{
int i;
struct protent *protp;
+ lcp_options *go = &lcp_gotoptions[unit];
+
+ /*
+ * If the peer had to authenticate, run the auth-up script now.
+ */
+ if ((go->neg_chap || go->neg_upap) && !did_authup) {
+ auth_script(_PATH_AUTHUP);
+ did_authup = 1;
+ }
phase = PHASE_NETWORK;
+#if 0
if (!demand)
set_filters(&pass_filter, &active_filter);
+#endif
for (i = 0; (protp = protocols[i]) != NULL; ++i)
if (protp->protocol < 0xC000 && protp->enabled_flag
&& protp->open != NULL) {
@@ -272,8 +309,10 @@ auth_peer_fail(unit, protocol)
* The peer has been successfully authenticated using `protocol'.
*/
void
-auth_peer_success(unit, protocol)
+auth_peer_success(unit, protocol, name, namelen)
int unit, protocol;
+ char *name;
+ int namelen;
{
int bit;
@@ -291,6 +330,14 @@ auth_peer_success(unit, protocol)
}
/*
+ * Save the authenticated name of the peer for later.
+ */
+ if (namelen > sizeof(peer_authname) - 1)
+ namelen = sizeof(peer_authname) - 1;
+ BCOPY(name, peer_authname, namelen);
+ peer_authname[namelen] = 0;
+
+ /*
* If there is no more authentication still to be done,
* proceed to the network phase.
*/
@@ -305,6 +352,9 @@ void
auth_withpeer_fail(unit, protocol)
int unit, protocol;
{
+ if (passwd_from_file)
+ BZERO(passwd, MAXSECRETLEN);
+
/*
* We've failed to authenticate ourselves to our peer.
* He'll probably take the link down, and there's not much
@@ -326,6 +376,8 @@ auth_withpeer_success(unit, protocol)
bit = CHAP_WITHPEER;
break;
case PPP_PAP:
+ if (passwd_from_file)
+ BZERO(passwd, MAXSECRETLEN);
bit = UPAP_WITHPEER;
break;
default:
@@ -411,6 +463,7 @@ void
auth_check_options()
{
lcp_options *wo = &lcp_wantoptions[0];
+ int can_auth;
lcp_options *ao = &lcp_allowoptions[0];
ipcp_options *ipwo = &ipcp_wantoptions[0];
u_int32_t remote;
@@ -431,7 +484,7 @@ auth_check_options()
* Check whether we have appropriate secrets to use
* to authenticate ourselves and/or the peer.
*/
- if (ao->neg_upap && passwd[0] == 0 && !get_upap_passwd())
+ if (ao->neg_upap && passwd[0] == 0 && !get_upap_passwd(passwd))
ao->neg_upap = 0;
if (wo->neg_upap && !uselogin && !have_upap_secret())
wo->neg_upap = 0;
@@ -451,6 +504,34 @@ pppd: peer authentication required but no suitable secret(s) found\n");
}
+/*
+ * auth_reset - called when LCP is starting negotiations to recheck
+ * authentication options, i.e. whether we have appropriate secrets
+ * to use for authenticating ourselves and/or the peer.
+ */
+void
+auth_reset(unit)
+ int unit;
+{
+ lcp_options *go = &lcp_gotoptions[unit];
+ lcp_options *ao = &lcp_allowoptions[0];
+ ipcp_options *ipwo = &ipcp_wantoptions[0];
+ u_int32_t remote;
+
+ ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_upap_passwd(NULL));
+ ao->neg_chap = !refuse_chap
+ && have_chap_secret(our_name, remote_name, (u_int32_t)0);
+
+ if (go->neg_upap && !uselogin && !have_upap_secret())
+ go->neg_upap = 0;
+ if (go->neg_chap) {
+ remote = ipwo->accept_remote? 0: ipwo->hisaddr;
+ if (!have_chap_secret(remote_name, our_name, remote))
+ go->neg_chap = 0;
+ }
+
+}
+
/*
* check_passwd - Check the user name and passwd against the PAP secrets
@@ -489,6 +570,8 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
passwd[passwdlen] = '\0';
BCOPY(auser, user, userlen);
user[userlen] = '\0';
+ *msg = (char *) 0;
+
/*
* Open the file of upap secrets and scan for a suitable secret
@@ -525,7 +608,8 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
}
if (ret == UPAP_AUTHNAK) {
- *msg = "Login incorrect";
+ if (*msg == (char *) 0)
+ *msg = "Login incorrect";
*msglen = strlen(*msg);
/*
* Frustrate passwd stealer programs.
@@ -544,16 +628,94 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
} else {
attempts = 0; /* Reset count */
- *msg = "Login ok";
+ if (*msg == (char *) 0)
+ *msg = "Login ok";
*msglen = strlen(*msg);
if (addresses[unit] != NULL)
free_wordlist(addresses[unit]);
addresses[unit] = addrs;
}
+ BZERO(passwd, sizeof(passwd));
+ BZERO(secret, sizeof(secret));
+
return ret;
}
+#ifdef HAS_SHADOW
+/**************
+ * This function was lifted from the shadow-3.3.2 version by John Haugh II.
+ * It is included because the function was not in the standard libshadow
+ * library. If it is included in the library then I can remove it from here.
+ */
+
+#define DAY (24L*3600L)
+/*
+ * isexpired - determine if account is expired yet
+ *
+ * isexpired calculates the expiration date based on the
+ * password expiration criteria.
+ */
+
+/*ARGSUSED*/
+int
+isexpired (pw, sp)
+struct passwd *pw;
+struct spwd *sp;
+{
+ long clock;
+
+ clock = time ((time_t *) 0) / DAY;
+
+ /*
+ * Quick and easy - there is an expired account field
+ * along with an inactive account field. Do the expired
+ * one first since it is worse.
+ */
+
+ if (sp->sp_expire > 0 && sp->sp_expire < clock)
+ return 3;
+
+ if (sp->sp_inact > 0 && sp->sp_lstchg > 0 && sp->sp_max > 0 &&
+ sp->sp_inact + sp->sp_lstchg + sp->sp_max < clock)
+ return 2;
+
+ /*
+ * The last and max fields must be present for an account
+ * to have an expired password. A maximum of >10000 days
+ * is considered to be infinite.
+ */
+
+ if (sp->sp_lstchg == -1 ||
+ sp->sp_max == -1 || sp->sp_max >= 10000L)
+ return 0;
+
+ /*
+ * Calculate today's day and the day on which the password
+ * is going to expire. If that date has already passed,
+ * the password has expired.
+ */
+
+ if (sp->sp_lstchg + sp->sp_max < clock)
+ return 1;
+
+ return 0;
+}
+#endif
+
+/*
+ * This function is needed for PAM. However, it should not be called.
+ * If it is, return the error code.
+ */
+
+#ifdef USE_PAM
+static int pam_conv(int num_msg, const struct pam_message **msg,
+ struct pam_response **resp, void *appdata_ptr)
+{
+ return PAM_CONV_ERR;
+}
+#endif
+
/*
* login - Check the user name and password against the system
@@ -564,6 +726,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
* UPAP_AUTHACK: Login succeeded.
* In either case, msg points to an appropriate message.
*/
+
static int
login(user, passwd, msg, msglen)
char *user;
@@ -571,46 +734,101 @@ login(user, passwd, msg, msglen)
char **msg;
int *msglen;
{
- struct passwd *pw;
- char *epasswd;
char *tty;
+#ifdef USE_PAM
+ struct pam_conv pam_conversation;
+ pam_handle_t *pamh;
+ int pam_error;
+ char *pass;
+ char *dev;
+/*
+ * Fill the pam_conversion structure
+ */
+ memset (&pam_conversation, '\0', sizeof (struct pam_conv));
+ pam_conversation.conv = &pam_conv;
+
+ pam_error = pam_start ("ppp", user, &pam_conversation, &pamh);
+ if (pam_error != PAM_SUCCESS) {
+ *msg = (char *) pam_strerror (pam_error);
+ return UPAP_AUTHNAK;
+ }
+/*
+ * Define the fields for the credintial validation
+ */
+ (void) pam_set_item (pamh, PAM_AUTHTOK, passwd);
+ (void) pam_set_item (pamh, PAM_TTY, devnam);
+/*
+ * Validate the user
+ */
+ pam_error = pam_authenticate (pamh, PAM_SILENT);
+ if (pam_error == PAM_SUCCESS)
+ pam_error = pam_acct_mgmt (pamh, PAM_SILENT);
+
+ *msg = (char *) pam_strerror (pam_error);
+/*
+ * Clean up the mess
+ */
+ (void) pam_end (pamh, pam_error);
+
+ if (pam_error != PAM_SUCCESS)
+ return UPAP_AUTHNAK;
+/*
+ * Use the non-PAM methods directly
+ */
+#else /* #ifdef USE_PAM */
+
+ struct passwd *pw;
+ char *epasswd;
+
#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) {
+ return (UPAP_AUTHNAK);
+ }
+
+#ifdef HAS_SHADOW
+ if ((spwd = getspnam(user)) == NULL) {
pw->pw_passwd = "";
} else {
- pw->pw_passwd = spwd->sp_pwdp;
+ pw->pw_passwd = spwd->sp_pwdp;
}
#endif
-
+
/*
* XXX If no passwd, let them login without one.
*/
if (pw->pw_passwd == '\0') {
- 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);
+ return (UPAP_AUTHACK);
+ }
+
+#ifdef HAS_SHADOW
+ if (pw->pw_passwd) {
+ if (pw->pw_passwd[0] == '@') {
+ if (pw_auth (pw->pw_passwd+1, pw->pw_name, PW_PPP, NULL)) {
+ return (UPAP_AUTHNAK);
+ }
+ } else {
+ epasswd = pw_encrypt(passwd, pw->pw_passwd);
+ if (strcmp(epasswd, pw->pw_passwd)) {
+ return (UPAP_AUTHNAK);
+ }
+ }
+ /* check the age of the password entry */
+ if (spwd && (isexpired (pw, spwd) != 0)) {
+ return (UPAP_AUTHNAK);
+ }
}
#else
epasswd = crypt(passwd, pw->pw_passwd);
if (strcmp(epasswd, pw->pw_passwd)) {
- return (UPAP_AUTHNAK);
+ return (UPAP_AUTHNAK);
}
#endif
+#endif /* #ifdef USE_PAM */
syslog(LOG_INFO, "user %s logged in", user);
@@ -670,6 +888,7 @@ null_login(unit)
i = scan_authfile(f, "", our_name, (u_int32_t)0, secret, &addrs, filename);
ret = i >= 0 && (i & NONWILD_CLIENT) != 0 && secret[0] == 0;
+ BZERO(secret, sizeof(secret));
if (ret) {
if (addresses[unit] != NULL)
@@ -688,7 +907,8 @@ null_login(unit)
* could be found.
*/
static int
-get_upap_passwd()
+get_upap_passwd(passwd)
+char *passwd;
{
char *filename;
FILE *f;
@@ -701,11 +921,15 @@ get_upap_passwd()
if (f == NULL)
return 0;
check_access(f, filename);
- if (scan_authfile(f, user, remote_name, (u_int32_t)0,
- secret, NULL, filename) < 0)
+ if (scan_authfile(f, user,
+ remote_name[0]? remote_name: NULL,
+ (u_int32_t)0, secret, NULL, filename) < 0)
return 0;
- strncpy(passwd, secret, MAXSECRETLEN);
- passwd[MAXSECRETLEN-1] = 0;
+ if (passwd != NULL) {
+ strncpy(passwd, secret, MAXSECRETLEN);
+ passwd[MAXSECRETLEN-1] = 0;
+ }
+ BZERO(secret, sizeof(secret));
return 1;
}
@@ -910,7 +1134,7 @@ ip_addr_check(addr, addrs)
if (ptr_mask != NULL)
*ptr_mask = '/';
- if (a == 0xffffffff)
+ if (a == -1L)
syslog (LOG_WARNING,
"unknown host %s in auth. address list",
addrs->word);
@@ -1121,3 +1345,37 @@ free_wordlist(wp)
wp = next;
}
}
+
+/*
+ * auth_script - execute a script with arguments
+ * interface-name peer-name real-user tty speed
+ */
+static void
+auth_script(script)
+ char *script;
+{
+ char strspeed[32];
+ struct passwd *pw;
+ char struid[32];
+ char *user_name;
+ char *argv[8];
+
+ if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL)
+ user_name = pw->pw_name;
+ else {
+ sprintf(struid, "%d", getuid());
+ user_name = struid;
+ }
+ sprintf(strspeed, "%d", baud_rate);
+
+ argv[0] = script;
+ argv[1] = ifname;
+ argv[2] = peer_authname;
+ argv[3] = user_name;
+ argv[4] = devnam;
+ argv[5] = strspeed;
+ argv[6] = NULL;
+
+ run_program(script, argv, 0);
+}
+
diff --git a/usr.sbin/pppd/ccp.c b/usr.sbin/pppd/ccp.c
index 074ab4a70e7..dab6a1d676a 100644
--- a/usr.sbin/pppd/ccp.c
+++ b/usr.sbin/pppd/ccp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ccp.c,v 1.3 1996/04/21 23:41:18 deraadt Exp $ */
+/* $OpenBSD: ccp.c,v 1.4 1996/07/20 12:02:05 joshd Exp $ */
/*
* ccp.c - PPP Compression Control Protocol.
@@ -28,7 +28,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: ccp.c,v 1.3 1996/04/21 23:41:18 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: ccp.c,v 1.4 1996/07/20 12:02:05 joshd Exp $";
#endif
#include <string.h>
@@ -40,10 +40,37 @@ static char rcsid[] = "$OpenBSD: ccp.c,v 1.3 1996/04/21 23:41:18 deraadt Exp $";
#include "fsm.h"
#include "ccp.h"
+/*
+ * Protocol entry points from main code.
+ */
+static void ccp_init __P((int unit));
+static void ccp_open __P((int unit));
+static void ccp_close __P((int unit, char *));
+static void ccp_lowerup __P((int unit));
+static void ccp_lowerdown __P((int));
+static void ccp_input __P((int unit, u_char *pkt, int len));
+static void ccp_protrej __P((int unit));
+static int ccp_printpkt __P((u_char *pkt, int len,
+ void (*printer) __P((void *, char *, ...)),
+ void *arg));
+static void ccp_datainput __P((int unit, u_char *pkt, int len));
+
struct protent ccp_protent = {
- PPP_CCP, ccp_init, ccp_input, ccp_protrej,
- ccp_lowerup, ccp_lowerdown, ccp_open, ccp_close,
- ccp_printpkt, ccp_datainput, 1, "CCP", NULL, NULL
+ PPP_CCP,
+ ccp_init,
+ ccp_input,
+ ccp_protrej,
+ ccp_lowerup,
+ ccp_lowerdown,
+ ccp_open,
+ ccp_close,
+ ccp_printpkt,
+ ccp_datainput,
+ 1,
+ "CCP",
+ NULL,
+ NULL,
+ NULL
};
fsm ccp_fsm[NUM_PPP];
@@ -105,7 +132,7 @@ static int all_rejected[NUM_PPP]; /* we rejected all peer's options */
/*
* ccp_init - initialize CCP.
*/
-void
+static void
ccp_init(unit)
int unit;
{
@@ -160,7 +187,7 @@ ccp_open(unit)
/*
* ccp_close - Terminate CCP.
*/
-void
+static void
ccp_close(unit, reason)
int unit;
char *reason;
@@ -172,7 +199,7 @@ ccp_close(unit, reason)
/*
* ccp_lowerup - we may now transmit CCP packets.
*/
-void
+static void
ccp_lowerup(unit)
int unit;
{
@@ -182,7 +209,7 @@ ccp_lowerup(unit)
/*
* ccp_lowerdown - we may not transmit CCP packets.
*/
-void
+static void
ccp_lowerdown(unit)
int unit;
{
@@ -192,7 +219,7 @@ ccp_lowerdown(unit)
/*
* ccp_input - process a received CCP packet.
*/
-void
+static void
ccp_input(unit, p, len)
int unit;
u_char *p;
@@ -254,7 +281,7 @@ ccp_extcode(f, code, id, p, len)
/*
* ccp_protrej - peer doesn't talk CCP.
*/
-void
+static void
ccp_protrej(unit)
int unit;
{
@@ -402,6 +429,8 @@ ccp_addci(f, p, lenp)
}
}
+ go->method = (p > p0)? p0[0]: -1;
+
*lenp = p - p0;
}
@@ -613,6 +642,7 @@ ccp_reqci(f, p, lenp, dont_nak)
len = *lenp;
memset(ho, 0, sizeof(ccp_options));
+ ho->method = (len > 0)? p[0]: -1;
while (len > 0) {
newret = CONFACK;
@@ -765,6 +795,42 @@ ccp_reqci(f, p, lenp, dont_nak)
}
/*
+ * Make a string name for a compression method (or 2).
+ */
+static char *
+method_name(opt, opt2)
+ ccp_options *opt, *opt2;
+{
+ static char result[64];
+
+ if (!ANY_COMPRESS(*opt))
+ return "(none)";
+ switch (opt->method) {
+ case CI_DEFLATE:
+ if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)
+ sprintf(result, "Deflate (%d/%d)", opt->deflate_size,
+ opt2->deflate_size);
+ else
+ sprintf(result, "Deflate (%d)", opt->deflate_size);
+ break;
+ case CI_BSD_COMPRESS:
+ if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits)
+ sprintf(result, "BSD-Compress (%d/%d)", opt->bsd_bits,
+ opt2->bsd_bits);
+ else
+ sprintf(result, "BSD-Compress (%d)", opt->bsd_bits);
+ break;
+ case CI_PREDICTOR_1:
+ return "Predictor 1";
+ case CI_PREDICTOR_2:
+ return "Predictor 2";
+ default:
+ sprintf(result, "Method %d", opt->method);
+ }
+ return result;
+}
+
+/*
* CCP has come up - inform the kernel driver.
*/
static void
@@ -774,12 +840,26 @@ ccp_up(f)
ccp_options *go = &ccp_gotoptions[f->unit];
ccp_options *ho = &ccp_hisoptions[f->unit];
+ char method1[64];
+
ccp_flags_set(f->unit, 1, 1);
- if (ANY_COMPRESS(*go) || ANY_COMPRESS(*ho))
- syslog(LOG_NOTICE, "%s enabled",
- ANY_COMPRESS(*go)? ANY_COMPRESS(*ho)? "Compression":
- "Receive compression": "Transmit compression");
-}
+ if (ANY_COMPRESS(*go)) {
+ if (ANY_COMPRESS(*ho)) {
+ if (go->method == ho->method) {
+ syslog(LOG_NOTICE, "%s compression enabled",
+ method_name(go, ho));
+ } else {
+ strcpy(method1, method_name(go, NULL));
+ syslog(LOG_NOTICE, "%s / %s compression enabled",
+ method1, method_name(ho, NULL));
+ }
+ } else
+ syslog(LOG_NOTICE, "%s receive compression enabled",
+ method_name(go, NULL));
+ } else
+ syslog(LOG_NOTICE, "%s transmit compression enabled",
+ method_name(ho, NULL));
+}
/*
* CCP has gone down - inform the kernel driver.
@@ -797,14 +877,14 @@ ccp_down(f)
/*
* Print the contents of a CCP packet.
*/
-char *ccp_codenames[] = {
+static char *ccp_codenames[] = {
"ConfReq", "ConfAck", "ConfNak", "ConfRej",
"TermReq", "TermAck", "CodeRej",
NULL, NULL, NULL, NULL, NULL, NULL,
"ResetReq", "ResetAck",
};
-int
+static int
ccp_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
@@ -883,6 +963,16 @@ ccp_printpkt(p, plen, printer, arg)
printer(arg, ">");
}
break;
+
+ case TERMACK:
+ case TERMREQ:
+ if (len > 0 && *p >= ' ' && *p < 0x7f) {
+ print_string(p, len, printer, arg);
+ p += len;
+ len = 0;
+ }
+ break;
+
}
/* dump out the rest of the packet in hex */
diff --git a/usr.sbin/pppd/ccp.h b/usr.sbin/pppd/ccp.h
index 4907e636098..95bf811035f 100644
--- a/usr.sbin/pppd/ccp.h
+++ b/usr.sbin/pppd/ccp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ccp.h,v 1.2 1996/03/25 15:55:33 niklas Exp $ */
+/* $OpenBSD: ccp.h,v 1.3 1996/07/20 12:02:05 joshd Exp $ */
/*
* ccp.h - Definitions for PPP Compression Control Protocol.
@@ -34,6 +34,7 @@ typedef struct ccp_options {
u_int predictor_2: 1; /* do Predictor-2? */
u_short bsd_bits; /* # bits/code for BSD Compress */
u_short deflate_size; /* lg(window size) for Deflate */
+ short method; /* code for chosen compression method */
} ccp_options;
extern fsm ccp_fsm[];
@@ -42,16 +43,4 @@ extern ccp_options ccp_gotoptions[];
extern ccp_options ccp_allowoptions[];
extern ccp_options ccp_hisoptions[];
-void ccp_init __P((int unit));
-void ccp_open __P((int unit));
-void ccp_close __P((int unit, char *));
-void ccp_lowerup __P((int unit));
-void ccp_lowerdown __P((int));
-void ccp_input __P((int unit, u_char *pkt, int len));
-void ccp_protrej __P((int unit));
-int ccp_printpkt __P((u_char *pkt, int len,
- void (*printer) __P((void *, char *, ...)),
- void *arg));
-void ccp_datainput __P((int unit, u_char *pkt, int len));
-
extern struct protent ccp_protent;
diff --git a/usr.sbin/pppd/chap.c b/usr.sbin/pppd/chap.c
index fa081cc7ae4..a91bf2c38fe 100644
--- a/usr.sbin/pppd/chap.c
+++ b/usr.sbin/pppd/chap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: chap.c,v 1.2 1996/03/25 15:55:35 niklas Exp $ */
+/* $OpenBSD: chap.c,v 1.3 1996/07/20 12:02:06 joshd Exp $ */
/*
* chap.c - Crytographic Handshake Authentication Protocol.
@@ -21,7 +21,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: chap.c,v 1.2 1996/03/25 15:55:35 niklas Exp $";
+static char rcsid[] = "$OpenBSD: chap.c,v 1.3 1996/07/20 12:02:06 joshd Exp $";
#endif
/*
@@ -38,12 +38,41 @@ static char rcsid[] = "$OpenBSD: chap.c,v 1.2 1996/03/25 15:55:35 niklas Exp $";
#include "chap.h"
#include "md5.h"
+#ifdef CHAPMS
+#include "chap_ms.h"
+#endif
+
+/*
+ * Protocol entry points.
+ */
+static void ChapInit __P((int));
+static void ChapLowerUp __P((int));
+static void ChapLowerDown __P((int));
+static void ChapInput __P((int, u_char *, int));
+static void ChapProtocolReject __P((int));
+static int ChapPrintPkt __P((u_char *, int,
+ void (*) __P((void *, char *, ...)), void
+*));
+
struct protent chap_protent = {
- PPP_CHAP, ChapInit, ChapInput, ChapProtocolReject,
- ChapLowerUp, ChapLowerDown, NULL, NULL,
- ChapPrintPkt, NULL, 1, "CHAP", NULL, NULL
+ PPP_CHAP,
+ ChapInit,
+ ChapInput,
+ ChapProtocolReject,
+ ChapLowerUp,
+ ChapLowerDown,
+ NULL,
+ NULL,
+ ChapPrintPkt,
+ NULL,
+ 1,
+ "CHAP",
+ NULL,
+ NULL,
+ NULL
};
+
chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */
static void ChapChallengeTimeout __P((caddr_t));
@@ -63,7 +92,7 @@ extern void srand48 __P((long));
/*
* ChapInit - Initialize a CHAP unit.
*/
-void
+static void
ChapInit(unit)
int unit;
{
@@ -205,7 +234,7 @@ ChapRechallenge(arg)
*
* Start up if we have pending requests.
*/
-void
+static void
ChapLowerUp(unit)
int unit;
{
@@ -231,7 +260,7 @@ ChapLowerUp(unit)
*
* Cancel all timeouts.
*/
-void
+static void
ChapLowerDown(unit)
int unit;
{
@@ -255,7 +284,7 @@ ChapLowerDown(unit)
/*
* ChapProtocolReject - Peer doesn't grok CHAP.
*/
-void
+static void
ChapProtocolReject(unit)
int unit;
{
@@ -274,7 +303,7 @@ ChapProtocolReject(unit)
/*
* ChapInput - Input CHAP packet.
*/
-void
+static void
ChapInput(unit, inpacket, packet_len)
int unit;
u_char *inpacket;
@@ -378,8 +407,15 @@ ChapReceiveChallenge(cstate, inp, id, len)
BCOPY(inp, rhostname, len);
rhostname[len] = '\000';
- CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field: %s",
- rhostname));
+ CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field '%s'",
+ rhostname));
+
+ /* Microsoft doesn't send their name back in the PPP packet */
+ if (rhostname[0] == 0 && cstate->resp_type == CHAP_MICROSOFT) {
+ strcpy(rhostname, remote_name);
+ CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name",
+ rhostname));
+ }
/* get secret for authenticating ourselves with the specified host */
if (!get_secret(cstate->unit, cstate->resp_name, rhostname,
@@ -409,11 +445,18 @@ ChapReceiveChallenge(cstate, inp, id, len)
cstate->resp_length = MD5_SIGNATURE_SIZE;
break;
+#ifdef CHAPMS
+ case CHAP_MICROSOFT:
+ ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
+ break;
+#endif
+
default:
CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->resp_type));
return;
}
+ BZERO(secret, sizeof(secret));
ChapSendResponse(cstate);
}
@@ -518,13 +561,14 @@ ChapReceiveResponse(cstate, inp, id, len)
}
}
+ BZERO(secret, sizeof(secret));
ChapSendStatus(cstate, code);
if (code == CHAP_SUCCESS) {
old_state = cstate->serverstate;
cstate->serverstate = CHAPSS_OPEN;
if (old_state == CHAPSS_INITIAL_CHAL) {
- auth_peer_success(cstate->unit, PPP_CHAP);
+ auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len);
}
if (cstate->chal_interval != 0)
TIMEOUT(ChapRechallenge, (caddr_t) cstate, cstate->chal_interval);
@@ -745,11 +789,11 @@ ChapSendResponse(cstate)
/*
* ChapPrintPkt - print the contents of a CHAP packet.
*/
-char *ChapCodenames[] = {
+static char *ChapCodenames[] = {
"Challenge", "Response", "Success", "Failure"
};
-int
+static int
ChapPrintPkt(p, plen, printer, arg)
u_char *p;
int plen;
diff --git a/usr.sbin/pppd/chap.h b/usr.sbin/pppd/chap.h
index 45f1e3d2f3b..2f57d434ed1 100644
--- a/usr.sbin/pppd/chap.h
+++ b/usr.sbin/pppd/chap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: chap.h,v 1.3 1996/06/16 14:35:49 deraadt Exp $ */
+/* $OpenBSD: chap.h,v 1.4 1996/07/20 12:02:06 joshd Exp $ */
/*
* chap.h - Challenge-Handshake Authentication Protocol definitions.
@@ -29,6 +29,8 @@
#define CHAP_DIGEST_MD5 5 /* use MD5 algorithm */
#define MD5_SIGNATURE_SIZE 16 /* 16 bytes in a MD5 message digest */
+#define CHAP_MICROSOFT 0x80 /* use Microsoft-compatible alg. */
+#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */
#define CHAP_CHALLENGE 1
#define CHAP_RESPONSE 2
@@ -98,15 +100,8 @@ typedef struct chap_state {
extern chap_state chap[];
-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 *));
extern struct protent chap_protent;
diff --git a/usr.sbin/pppd/chap_ms.c b/usr.sbin/pppd/chap_ms.c
new file mode 100644
index 00000000000..096b649ff6c
--- /dev/null
+++ b/usr.sbin/pppd/chap_ms.c
@@ -0,0 +1,184 @@
+/*
+ * chap_ms.c - Microsoft MS-CHAP compatible implementation.
+ *
+ * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
+ * http://www.strataware.com/
+ *
+ * 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 Eric Rosenquist. The name of the author 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: chap_ms.c,v 1.1 1996/07/20 12:02:06 joshd Exp $";
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <syslog.h>
+
+#include "pppd.h"
+#include "chap.h"
+#include "chap_ms.h"
+#include "md4.h"
+
+
+#ifdef CHAPMS
+#include <des.h>
+
+typedef struct {
+ u_char LANManResp[24];
+ u_char NTResp[24];
+ u_char UseNT; /* If 1, ignore the LANMan response field */
+} MS_ChapResponse;
+/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse),
+ in case this struct gets padded. */
+
+
+static void DesEncrypt __P((u_char *, u_char *, u_char *));
+static void MakeKey __P((u_char *, u_char *));
+
+
+static void
+ChallengeResponse(challenge, pwHash, response)
+ u_char *challenge; /* IN 8 octets */
+ u_char *pwHash; /* IN 16 octets */
+ u_char *response; /* OUT 24 octets */
+{
+ char ZPasswordHash[21];
+
+ BZERO(ZPasswordHash, sizeof(ZPasswordHash));
+ BCOPY(pwHash, ZPasswordHash, 16);
+
+#if 0
+ log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash");
+#endif
+
+ DesEncrypt(challenge, ZPasswordHash + 0, response + 0);
+ DesEncrypt(challenge, ZPasswordHash + 7, response + 8);
+ DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
+
+#if 0
+ log_packet(response, 24, "ChallengeResponse - response");
+#endif
+}
+
+
+static void
+DesEncrypt(clear, key, cipher)
+ u_char *clear; /* IN 8 octets */
+ u_char *key; /* IN 7 octets */
+ u_char *cipher; /* OUT 8 octets */
+{
+ des_cblock des_key;
+ des_key_schedule key_schedule;
+
+ MakeKey(key, des_key);
+
+ des_set_key(&des_key, key_schedule);
+
+#if 0
+ CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X",
+ clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
+#endif
+
+ des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
+
+#if 0
+ CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X",
+ cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
+#endif
+}
+
+
+static u_char Get7Bits(input, startBit)
+ u_char *input;
+ int startBit;
+{
+ register unsigned int word;
+
+ word = (unsigned)input[startBit / 8] << 8;
+ word |= (unsigned)input[startBit / 8 + 1];
+
+ word >>= 15 - (startBit % 8 + 7);
+
+ return word & 0xFE;
+}
+
+
+static void MakeKey(key, des_key)
+ u_char *key; /* IN 56 bit DES key missing parity bits */
+ u_char *des_key; /* OUT 64 bit DES key with parity bits added */
+{
+ des_key[0] = Get7Bits(key, 0);
+ des_key[1] = Get7Bits(key, 7);
+ des_key[2] = Get7Bits(key, 14);
+ des_key[3] = Get7Bits(key, 21);
+ des_key[4] = Get7Bits(key, 28);
+ des_key[5] = Get7Bits(key, 35);
+ des_key[6] = Get7Bits(key, 42);
+ des_key[7] = Get7Bits(key, 49);
+
+ des_set_odd_parity((des_cblock *)des_key);
+
+#if 0
+ CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X",
+ key[0], key[1], key[2], key[3], key[4], key[5], key[6]));
+ CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X",
+ des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7]));
+#endif
+}
+
+#endif /* CHAPMS */
+
+
+void
+ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len)
+ chap_state *cstate;
+ char *rchallenge;
+ int rchallenge_len;
+ char *secret;
+ int secret_len;
+{
+#ifdef CHAPMS
+ int i;
+ MDstruct md4Context;
+ MS_ChapResponse response;
+ u_char unicodePassword[MAX_NT_PASSWORD * 2];
+
+#if 0
+ CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'", secret_len, secret));
+#endif
+
+ BZERO(&response, sizeof(response));
+
+ /* Initialize the Unicode version of the secret (== password). */
+ /* This implicitly supports 8-bit ISO8859/1 characters. */
+ BZERO(unicodePassword, sizeof(unicodePassword));
+ for (i = 0; i < secret_len; i++)
+ unicodePassword[i * 2] = (u_char)secret[i];
+
+ MDbegin(&md4Context);
+ MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8); /* Unicode is 2 bytes/char, *8 for bit count */
+ MDupdate(&md4Context, NULL, 0); /* Tell MD4 we're done */
+
+ ChallengeResponse(rchallenge, (char *)md4Context.buffer, response.NTResp);
+
+ response.UseNT = 1;
+
+ BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
+ cstate->resp_length = MS_CHAP_RESPONSE_LEN;
+#endif /* CHAPMS */
+}
diff --git a/usr.sbin/pppd/chap_ms.h b/usr.sbin/pppd/chap_ms.h
new file mode 100644
index 00000000000..6697cba328d
--- /dev/null
+++ b/usr.sbin/pppd/chap_ms.h
@@ -0,0 +1,32 @@
+/*
+ * chap.h - Challenge Handshake Authentication Protocol definitions.
+ *
+ * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
+ * http://www.strataware.com/
+ *
+ * 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 Eric Rosenquist. The name of the author 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.
+ *
+ * $Id: chap_ms.h,v 1.1 1996/07/20 12:02:07 joshd Exp $
+ */
+
+#ifndef __CHAPMS_INCLUDE__
+
+#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */
+
+void ChapMS __P((chap_state *, char *, int, char *, int));
+
+#define __CHAPMS_INCLUDE__
+#endif /* __CHAPMS_INCLUDE__ */
diff --git a/usr.sbin/pppd/demand.c b/usr.sbin/pppd/demand.c
index 0292ca43020..d57f12db57a 100644
--- a/usr.sbin/pppd/demand.c
+++ b/usr.sbin/pppd/demand.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: demand.c,v 1.1 1996/03/25 15:55:37 niklas Exp $ */
+/* $OpenBSD: demand.c,v 1.2 1996/07/20 12:02:07 joshd Exp $ */
/*
* demand.c - Dial on demand support.
@@ -20,7 +20,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: demand.c,v 1.1 1996/03/25 15:55:37 niklas Exp $";
+static char rcsid[] = "$OpenBSD: demand.c,v 1.2 1996/07/20 12:02:07 joshd Exp $";
#endif
#include <stdio.h>
@@ -62,6 +62,8 @@ struct packet {
struct packet *pend_q;
struct packet *pend_qtail;
+static int active_packet __P((unsigned char *, int));
+
/*
* demand_conf - configure the interface for doing dial-on-demand.
*/
@@ -87,7 +89,9 @@ demand_conf()
ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
+#if 0
set_filters(&pass_filter, &active_filter);
+#endif
/*
* Call the demand_conf procedure for each protocol that's got one.
@@ -310,3 +314,32 @@ demand_rexmit(proto)
if (prev != NULL)
prev->next = NULL;
}
+
+/*
+ * Scan a packet to decide whether it is an "active" packet,
+ * that is, whether it is worth bringing up the link for.
+ */
+static int
+active_packet(p, len)
+ unsigned char *p;
+ int len;
+{
+ int proto, i;
+ struct protent *protp;
+
+ if (len < PPP_HDRLEN)
+ return 0;
+ proto = PPP_PROTOCOL(p);
+ for (i = 0; (protp = protocols[i]) != NULL; ++i) {
+ if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) {
+ if (!protp->enabled_flag)
+ return 0;
+ if (protp->active_pkt == NULL)
+ return 1;
+ return (*protp->active_pkt)(p, len);
+ }
+ }
+ return 0; /* not a supported protocol !!?? */
+}
+
+
diff --git a/usr.sbin/pppd/fsm.c b/usr.sbin/pppd/fsm.c
index 1347659263a..af467df0807 100644
--- a/usr.sbin/pppd/fsm.c
+++ b/usr.sbin/pppd/fsm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fsm.c,v 1.2 1996/03/25 15:55:38 niklas Exp $ */
+/* $OpenBSD: fsm.c,v 1.3 1996/07/20 12:02:08 joshd Exp $ */
/*
* fsm.c - {Link, IP} Control Protocol Finite State Machine.
@@ -20,7 +20,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: fsm.c,v 1.2 1996/03/25 15:55:38 niklas Exp $";
+static char rcsid[] = "$OpenBSD: fsm.c,v 1.3 1996/07/20 12:02:08 joshd Exp $";
#endif
/*
@@ -43,7 +43,7 @@ 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_rtermreq __P((fsm *, int, u_char *, int));
static void fsm_rtermack __P((fsm *));
static void fsm_rcoderej __P((fsm *, u_char *, int));
static void fsm_sconfreq __P((fsm *, int));
@@ -349,7 +349,7 @@ fsm_input(f, inpacket, l)
break;
case TERMREQ:
- fsm_rtermreq(f, id);
+ fsm_rtermreq(f, id, inp, len);
break;
case TERMACK:
@@ -566,10 +566,14 @@ fsm_rconfnakrej(f, code, id, inp, len)
* fsm_rtermreq - Receive Terminate-Req.
*/
static void
-fsm_rtermreq(f, id)
+fsm_rtermreq(f, id, p, len)
fsm *f;
int id;
+ u_char *p;
+ int len;
{
+ char str[80];
+
FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d.",
PROTO_NAME(f), id));
@@ -580,7 +584,11 @@ fsm_rtermreq(f, id)
break;
case OPENED:
- syslog(LOG_INFO, "%s terminated at peer's request", PROTO_NAME(f));
+ if (len > 0) {
+ fmtmsg(str, sizeof(str), "%0.*v", len, p);
+ syslog(LOG_INFO, "%s terminated by peer (%s)", PROTO_NAME(f), str);
+ } else
+ syslog(LOG_INFO, "%s terminated by peer", PROTO_NAME(f));
if (f->callbacks->down)
(*f->callbacks->down)(f); /* Inform upper layers */
f->retransmits = 0;
diff --git a/usr.sbin/pppd/ipcp.c b/usr.sbin/pppd/ipcp.c
index 2ad4123751b..3532480a81b 100644
--- a/usr.sbin/pppd/ipcp.c
+++ b/usr.sbin/pppd/ipcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipcp.c,v 1.2 1996/03/25 15:55:43 niklas Exp $ */
+/* $OpenBSD: ipcp.c,v 1.3 1996/07/20 12:02:08 joshd Exp $ */
/*
* ipcp.c - PPP IP Control Protocol.
@@ -20,7 +20,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: ipcp.c,v 1.2 1996/03/25 15:55:43 niklas Exp $";
+static char rcsid[] = "$OpenBSD: ipcp.c,v 1.3 1996/07/20 12:02:08 joshd Exp $";
#endif
/*
@@ -31,9 +31,13 @@ static char rcsid[] = "$OpenBSD: ipcp.c,v 1.2 1996/03/25 15:55:43 niklas Exp $";
#include <string.h>
#include <syslog.h>
#include <netdb.h>
+#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
#include "pppd.h"
#include "fsm.h"
@@ -86,13 +90,41 @@ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
"IPCP" /* String name of protocol */
};
+/*
+ * Protocol entry points from main code.
+ */
+static void ipcp_init __P((int));
+static void ipcp_open __P((int));
+static void ipcp_close __P((int, char *));
+static void ipcp_lowerup __P((int));
+static void ipcp_lowerdown __P((int));
+static void ipcp_input __P((int, u_char *, int));
+static void ipcp_protrej __P((int));
+static int ipcp_printpkt __P((u_char *, int,
+ void (*) __P((void *, char *, ...)), void *));
+static void ip_check_options __P((void));
+static int ip_demand_conf __P((int));
+static int ip_active_pkt __P((u_char *, int));
+
struct protent ipcp_protent = {
- PPP_IPCP, ipcp_init, ipcp_input, ipcp_protrej,
- ipcp_lowerup, ipcp_lowerdown, ipcp_open, ipcp_close,
- ipcp_printpkt, NULL, 1, "IPCP",
- ip_check_options, ip_demand_conf,
+ PPP_IPCP,
+ ipcp_init,
+ ipcp_input,
+ ipcp_protrej,
+ ipcp_lowerup,
+ ipcp_lowerdown,
+ ipcp_open,
+ ipcp_close,
+ ipcp_printpkt,
+ NULL,
+ 1,
+ "IPCP",
+ ip_check_options,
+ ip_demand_conf,
+ ip_active_pkt
};
+
/*
* Lengths of configuration options.
*/
@@ -130,7 +162,7 @@ u_int32_t ipaddr;
/*
* ipcp_init - Initialize IPCP.
*/
-void
+static void
ipcp_init(unit)
int unit;
{
@@ -173,7 +205,7 @@ ipcp_init(unit)
/*
* ipcp_open - IPCP is allowed to come up.
*/
-void
+static void
ipcp_open(unit)
int unit;
{
@@ -184,7 +216,7 @@ ipcp_open(unit)
/*
* ipcp_close - Take IPCP down.
*/
-void
+static void
ipcp_close(unit, reason)
int unit;
char *reason;
@@ -196,7 +228,7 @@ ipcp_close(unit, reason)
/*
* ipcp_lowerup - The lower layer is up.
*/
-void
+static void
ipcp_lowerup(unit)
int unit;
{
@@ -207,7 +239,7 @@ ipcp_lowerup(unit)
/*
* ipcp_lowerdown - The lower layer is down.
*/
-void
+static void
ipcp_lowerdown(unit)
int unit;
{
@@ -218,7 +250,7 @@ ipcp_lowerdown(unit)
/*
* ipcp_input - Input IPCP packet.
*/
-void
+static void
ipcp_input(unit, p, len)
int unit;
u_char *p;
@@ -233,7 +265,7 @@ ipcp_input(unit, p, len)
*
* Pretend the lower layer went down, so we shut up.
*/
-void
+static void
ipcp_protrej(unit)
int unit;
{
@@ -1007,7 +1039,7 @@ endswitch:
* ip_check_options - check that any IP-related options are OK,
* and assign appropriate defaults.
*/
-void
+static void
ip_check_options()
{
struct hostent *hp;
@@ -1049,7 +1081,7 @@ ip_check_options()
* ip_demand_conf - configure the interface as though
* IPCP were up, for use with dial-on-demand.
*/
-int
+static int
ip_demand_conf(u)
int u;
{
@@ -1155,6 +1187,8 @@ ipcp_up(f)
return;
}
+ sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
+
/* assign a default route through the interface if required */
if (ipcp_wantoptions[f->unit].default_route)
if (sifdefaultroute(f->unit, ho->hisaddr))
@@ -1190,8 +1224,9 @@ ipcp_down(f)
{
u_int32_t ouraddr, hisaddr;
- np_down(f->unit, PPP_IP);
IPCPDEBUG((LOG_INFO, "ipcp: down"));
+ np_down(f->unit, PPP_IP);
+ sifvjcomp(f->unit, 0, 0, 0);
/*
* If we are doing dial-on-demand, set the interface
@@ -1261,16 +1296,16 @@ ipcp_script(f, script)
/*
* ipcp_printpkt - print the contents of an IPCP packet.
*/
-char *ipcp_codenames[] = {
+static char *ipcp_codenames[] = {
"ConfReq", "ConfAck", "ConfNak", "ConfRej",
"TermReq", "TermAck", "CodeRej"
};
-int
+static int
ipcp_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
- void (*printer)();
+ void (*printer) __P((void *, char *, ...));
void *arg;
{
int code, id, len, olen;
@@ -1351,6 +1386,16 @@ ipcp_printpkt(p, plen, printer, arg)
printer(arg, ">");
}
break;
+
+ case TERMACK:
+ case TERMREQ:
+ if (len > 0 && *p >= ' ' && *p < 0x7f) {
+ printer(arg, " ");
+ print_string(p, len, printer, arg);
+ p += len;
+ len = 0;
+ }
+ break;
}
/* print the rest of the bytes in the packet */
@@ -1361,3 +1406,38 @@ ipcp_printpkt(p, plen, printer, arg)
return p - pstart;
}
+
+/*
+ * ip_active_pkt - see if this IP packet is worth bringing the link up
+for.
+ * We don't bring the link up for IP fragments or for TCP FIN packets
+ * with no data.
+ */
+#ifndef IP_OFFMASK
+#define IP_OFFMASK 0x1fff
+#endif
+
+ip_active_pkt(pkt, len)
+ u_char *pkt;
+ int len;
+{
+ struct ip *ip;
+ struct tcphdr *tcp;
+ int hlen;
+
+ if (len < sizeof(struct ip) + PPP_HDRLEN)
+ return 0;
+ ip = (struct ip *) (pkt + PPP_HDRLEN);
+ if ((ntohs(ip->ip_off) & IP_OFFMASK) != 0)
+ return 0;
+ if (ip->ip_p != IPPROTO_TCP)
+ return 1;
+ hlen = ip->ip_hl * 4;
+ if (len < hlen + sizeof(struct tcphdr) + PPP_HDRLEN)
+ return 0;
+ tcp = (struct tcphdr *) (pkt + PPP_HDRLEN + hlen);
+ if ((tcp->th_flags & TH_FIN) != 0 && hlen + tcp->th_off * 4 == len)
+ return 0;
+ return 1;
+}
+
diff --git a/usr.sbin/pppd/ipcp.h b/usr.sbin/pppd/ipcp.h
index ce7fe8ba7ef..9b54252b76f 100644
--- a/usr.sbin/pppd/ipcp.h
+++ b/usr.sbin/pppd/ipcp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipcp.h,v 1.2 1996/03/25 15:55:44 niklas Exp $ */
+/* $OpenBSD: ipcp.h,v 1.3 1996/07/20 12:02:09 joshd Exp $ */
/*
* ipcp.h - IP Control Protocol definitions.
@@ -62,16 +62,6 @@ extern ipcp_options ipcp_gotoptions[];
extern ipcp_options ipcp_allowoptions[];
extern ipcp_options ipcp_hisoptions[];
-void ipcp_init __P((int));
-void ipcp_open __P((int));
-void ipcp_close __P((int, char *));
-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 *));
-void ip_check_options __P((void));
-int ip_demand_conf __P((int));
char *ip_ntoa __P((u_int32_t));
extern struct protent ipcp_protent;
diff --git a/usr.sbin/pppd/ipxcp.c b/usr.sbin/pppd/ipxcp.c
new file mode 100644
index 00000000000..39f57b36afd
--- /dev/null
+++ b/usr.sbin/pppd/ipxcp.c
@@ -0,0 +1,1394 @@
+/*
+ * ipxcp.c - PPP IPX Control Protocol.
+ *
+ * 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.
+ */
+
+#ifdef IPX_CHANGE
+#ifndef lint
+static char rcsid[] = "$Id: ipxcp.c,v 1.1 1996/07/20 12:02:09 joshd Exp $";
+#endif
+
+/*
+ * TODO:
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "pppd.h"
+#include "fsm.h"
+#include "ipxcp.h"
+#include "pathnames.h"
+
+/* global vars */
+ipxcp_options ipxcp_wantoptions[NUM_PPP]; /* Options that we want to request */
+ipxcp_options ipxcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
+ipxcp_options ipxcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
+ipxcp_options ipxcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
+
+#define wo (&ipxcp_wantoptions[0])
+#define ao (&ipxcp_allowoptions[0])
+#define go (&ipxcp_gotoptions[0])
+#define ho (&ipxcp_hisoptions[0])
+
+/*
+ * Callbacks for fsm code. (CI = Configuration Information)
+ */
+static void ipxcp_resetci __P((fsm *)); /* Reset our CI */
+static int ipxcp_cilen __P((fsm *)); /* Return length of our CI */
+static void ipxcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
+static int ipxcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
+static int ipxcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */
+static int ipxcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
+static int ipxcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
+static void ipxcp_up __P((fsm *)); /* We're UP */
+static void ipxcp_down __P((fsm *)); /* We're DOWN */
+static void ipxcp_script __P((fsm *, char *)); /* Run an up/down script */
+
+fsm ipxcp_fsm[NUM_PPP]; /* IPXCP fsm structure */
+
+static fsm_callbacks ipxcp_callbacks = { /* IPXCP callback routines */
+ ipxcp_resetci, /* Reset our Configuration Information */
+ ipxcp_cilen, /* Length of our Configuration Information */
+ ipxcp_addci, /* Add our Configuration Information */
+ ipxcp_ackci, /* ACK our Configuration Information */
+ ipxcp_nakci, /* NAK our Configuration Information */
+ ipxcp_rejci, /* Reject our Configuration Information */
+ ipxcp_reqci, /* Request peer's Configuration Information */
+ ipxcp_up, /* Called when fsm reaches OPENED state */
+ ipxcp_down, /* Called when fsm leaves OPENED state */
+ NULL, /* Called when we want the lower layer up */
+ NULL, /* Called when we want the lower layer down */
+ NULL, /* Called when Protocol-Reject received */
+ NULL, /* Retransmission is necessary */
+ NULL, /* Called to handle protocol-specific codes */
+ "IPXCP" /* String name of protocol */
+};
+
+/*
+ * Protocol entry points.
+ */
+
+static void ipxcp_init __P((int));
+static void ipxcp_open __P((int));
+static void ipxcp_close __P((int, char *));
+static void ipxcp_lowerup __P((int));
+static void ipxcp_lowerdown __P((int));
+static void ipxcp_input __P((int, u_char *, int));
+static void ipxcp_protrej __P((int));
+static int ipxcp_printpkt __P((u_char *, int,
+ void (*) __P((void *, char *, ...)), void *));
+
+struct protent ipxcp_protent = {
+ PPP_IPXCP,
+ ipxcp_init,
+ ipxcp_input,
+ ipxcp_protrej,
+ ipxcp_lowerup,
+ ipxcp_lowerdown,
+ ipxcp_open,
+ ipxcp_close,
+ ipxcp_printpkt,
+ NULL,
+ 0,
+ "IPXCP",
+ NULL,
+ NULL,
+ NULL
+};
+
+
+/*
+ * Lengths of configuration options.
+ */
+
+#define CILEN_VOID 2
+#define CILEN_COMPLETE 2 /* length of complete option */
+#define CILEN_NETN 6 /* network number length option */
+#define CILEN_NODEN 8 /* node number length option */
+#define CILEN_PROTOCOL 4 /* Minimum length of routing protocol */
+#define CILEN_NAME 3 /* Minimum length of router name */
+#define CILEN_COMPRESS 4 /* Minimum length of compression protocol */
+
+#define CODENAME(x) ((x) == CONFACK ? "ACK" : \
+ (x) == CONFNAK ? "NAK" : "REJ")
+
+/* Used in printing the node number */
+#define NODE(base) base[0], base[1], base[2], base[3], base[4], base[5]
+
+/* Used to generate the proper bit mask */
+#define BIT(num) (1 << (num))
+
+/*
+ * Make a string representation of a network IP address.
+ */
+
+char *
+ipx_ntoa(ipxaddr)
+u_int32_t ipxaddr;
+{
+ static char b[64];
+ sprintf(b, "%lx", ipxaddr);
+ return b;
+}
+
+
+/*
+ * ipxcp_init - Initialize IPXCP.
+ */
+static void
+ipxcp_init(unit)
+ int unit;
+{
+ fsm *f = &ipxcp_fsm[unit];
+
+ f->unit = unit;
+ f->protocol = PPP_IPXCP;
+ f->callbacks = &ipxcp_callbacks;
+ fsm_init(&ipxcp_fsm[unit]);
+
+ memset (wo->name, 0, sizeof (wo->name));
+ memset (wo->our_node, 0, sizeof (wo->our_node));
+ memset (wo->his_node, 0, sizeof (wo->his_node));
+
+ wo->neg_nn = 1;
+ wo->neg_complete = 1;
+ wo->network = 0;
+
+ ao->neg_node = 1;
+ ao->neg_nn = 1;
+ ao->neg_name = 1;
+ ao->neg_complete = 1;
+ ao->neg_router = 1;
+
+ ao->accept_local = 0;
+ ao->accept_remote = 0;
+ ao->accept_network = 0;
+}
+
+/*
+ * Copy the node number
+ */
+
+static void
+copy_node (src, dst)
+u_char *src, *dst;
+{
+ memcpy (dst, src, sizeof (ipxcp_wantoptions[0].our_node));
+}
+
+/*
+ * Compare node numbers
+ */
+
+static int
+compare_node (src, dst)
+u_char *src, *dst;
+{
+ return memcmp (dst, src, sizeof (ipxcp_wantoptions[0].our_node)) == 0;
+}
+
+/*
+ * Is the node number zero?
+ */
+
+static int
+zero_node (node)
+u_char *node;
+{
+ int indx;
+ for (indx = 0; indx < sizeof (ipxcp_wantoptions[0].our_node); ++indx)
+ if (node [indx] != 0)
+ return 0;
+ return 1;
+}
+
+/*
+ * Increment the node number
+ */
+
+static void
+inc_node (node)
+u_char *node;
+{
+ u_char *outp;
+ u_int32_t magic_num;
+
+ outp = node;
+ magic_num = magic();
+ *outp++ = '\0';
+ *outp++ = '\0';
+ PUTLONG (magic_num, outp);
+}
+
+/*
+ * ipxcp_open - IPXCP is allowed to come up.
+ */
+static void
+ipxcp_open(unit)
+ int unit;
+{
+ fsm_open(&ipxcp_fsm[unit]);
+}
+
+/*
+ * ipxcp_close - Take IPXCP down.
+ */
+static void
+ipxcp_close(unit, reason)
+ int unit;
+ char *reason;
+{
+ fsm_close(&ipxcp_fsm[unit], reason);
+}
+
+
+/*
+ * ipxcp_lowerup - The lower layer is up.
+ */
+static void
+ipxcp_lowerup(unit)
+ int unit;
+{
+ fsm_lowerup(&ipxcp_fsm[unit]);
+}
+
+
+/*
+ * ipxcp_lowerdown - The lower layer is down.
+ */
+static void
+ipxcp_lowerdown(unit)
+ int unit;
+{
+ fsm_lowerdown(&ipxcp_fsm[unit]);
+}
+
+
+/*
+ * ipxcp_input - Input IPXCP packet.
+ */
+static void
+ipxcp_input(unit, p, len)
+ int unit;
+ u_char *p;
+ int len;
+{
+ fsm_input(&ipxcp_fsm[unit], p, len);
+}
+
+
+/*
+ * ipxcp_protrej - A Protocol-Reject was received for IPXCP.
+ *
+ * Pretend the lower layer went down, so we shut up.
+ */
+static void
+ipxcp_protrej(unit)
+ int unit;
+{
+ fsm_lowerdown(&ipxcp_fsm[unit]);
+}
+
+
+/*
+ * ipxcp_resetci - Reset our CI.
+ */
+static void
+ipxcp_resetci(f)
+ fsm *f;
+{
+ u_int32_t network;
+ int unit = f->unit;
+
+ wo->req_node = wo->neg_node && ao->neg_node;
+ wo->req_nn = wo->neg_nn && ao->neg_nn;
+
+ if (wo->our_network == 0) {
+ wo->neg_node = 1;
+ ao->accept_network = 1;
+ }
+/*
+ * If our node number is zero then change it.
+ */
+ if (zero_node (wo->our_node)) {
+ inc_node (wo->our_node);
+ ao->accept_local = 1;
+ wo->neg_node = 1;
+ }
+/*
+ * If his node number is zero then change it.
+ */
+ if (zero_node (wo->his_node)) {
+ inc_node (wo->his_node);
+ ao->accept_remote = 1;
+ }
+/*
+ * Unless router protocol is suppressed then assume that we can do RIP.
+ */
+ if (! (wo->router & BIT(0)))
+ wo->router |= BIT(2);
+/*
+ * Router protocol is only negotiated if requested. Others force the
+ * negotiation.
+ */
+ if (wo->router & (BIT(2) | BIT(4)))
+ wo->neg_router = 1;
+/*
+ * Start with these default values
+ */
+ *go = *wo;
+}
+
+/*
+ * ipxcp_cilen - Return length of our CI.
+ */
+static int
+ipxcp_cilen(f)
+ fsm *f;
+{
+ int unit = f->unit;
+ int len;
+
+ len = go->neg_nn ? CILEN_NETN : 0;
+ len += go->neg_node ? CILEN_NODEN : 0;
+ len += go->neg_name ? CILEN_NAME + strlen (go->name) - 1 : 0;
+ len += go->neg_complete ? CILEN_COMPLETE : 0;
+/*
+ * Router protocol 0 is mutually exclusive with the others.
+ */
+ if (go->neg_router) {
+ if (go->router & BIT(0))
+ len += CILEN_PROTOCOL;
+ else {
+ if (go->router & BIT(2))
+ len += CILEN_PROTOCOL;
+ if (go->router & BIT(4))
+ len += CILEN_PROTOCOL;
+ }
+ }
+
+ return (len);
+}
+
+
+/*
+ * ipxcp_addci - Add our desired CIs to a packet.
+ */
+static void
+ipxcp_addci(f, ucp, lenp)
+ fsm *f;
+ u_char *ucp;
+ int *lenp;
+{
+ int len = *lenp;
+ int unit = f->unit;
+/*
+ * Add the options to the record.
+ */
+ if (go->neg_nn) {
+ PUTCHAR (IPX_NETWORK_NUMBER, ucp);
+ PUTCHAR (CILEN_NETN, ucp);
+ PUTLONG (go->our_network, ucp);
+ }
+
+ if (go->neg_node) {
+ int indx;
+ PUTCHAR (IPX_NODE_NUMBER, ucp);
+ PUTCHAR (CILEN_NODEN, ucp);
+ for (indx = 0; indx < sizeof (go->our_node); ++indx)
+ PUTCHAR (go->our_node[indx], ucp);
+ }
+
+ if (go->neg_name) {
+ int cilen = strlen (go->name);
+ int indx;
+ PUTCHAR (IPX_ROUTER_NAME, ucp);
+ PUTCHAR (CILEN_NAME + cilen - 1, ucp);
+ for (indx = 0; indx < cilen; ++indx)
+ PUTCHAR (go->name [indx], ucp);
+ }
+
+ if (go->neg_router && (go->router & (BIT(0) | BIT(2) | BIT(4)))) {
+ if (go->router & BIT(0)) {
+ PUTCHAR (IPX_ROUTER_PROTOCOL, ucp);
+ PUTCHAR (CILEN_PROTOCOL, ucp);
+ PUTSHORT (0, ucp);
+ } else {
+ if (go->router & BIT(2)) {
+ PUTCHAR (IPX_ROUTER_PROTOCOL, ucp);
+ PUTCHAR (CILEN_PROTOCOL, ucp);
+ PUTSHORT (2, ucp);
+ }
+
+ if (go->router & BIT(4)) {
+ PUTCHAR (IPX_ROUTER_PROTOCOL, ucp);
+ PUTCHAR (CILEN_PROTOCOL, ucp);
+ PUTSHORT (4, ucp);
+ }
+ }
+ }
+
+ if (go->neg_complete) {
+ PUTCHAR (IPX_COMPLETE, ucp);
+ PUTCHAR (CILEN_COMPLETE, ucp);
+ }
+}
+
+/*
+ * ipxcp_ackci - Ack our CIs.
+ *
+ * Returns:
+ * 0 - Ack was bad.
+ * 1 - Ack was good.
+ */
+static int
+ipxcp_ackci(f, p, len)
+ fsm *f;
+ u_char *p;
+ int len;
+{
+ int unit = f->unit;
+ u_short cilen, citype, cishort;
+ u_char cichar;
+ u_int32_t cilong;
+
+#define ACKCIVOID(opt, neg) \
+ if (neg) { \
+ if ((len -= CILEN_VOID) < 0) \
+ break; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_VOID || \
+ citype != opt) \
+ break; \
+ }
+
+#define ACKCICOMPLETE(opt,neg) ACKCIVOID(opt, neg)
+
+#define ACKCICHARS(opt, neg, val, cnt) \
+ if (neg) { \
+ int indx, count = cnt; \
+ len -= (count + 2); \
+ if (len < 0) \
+ break; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != (count + 2) || \
+ citype != opt) \
+ break; \
+ for (indx = 0; indx < count; ++indx) {\
+ GETCHAR(cichar, p); \
+ if (cichar != ((u_char *) &val)[indx]) \
+ break; \
+ }\
+ if (indx != count) \
+ break; \
+ }
+
+#define ACKCINODE(opt,neg,val) ACKCICHARS(opt,neg,val,sizeof(val))
+#define ACKCINAME(opt,neg,val) ACKCICHARS(opt,neg,val,strlen(val))
+
+#define ACKCINETWORK(opt, neg, val) \
+ if (neg) { \
+ if ((len -= CILEN_NETN) < 0) \
+ break; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_NETN || \
+ citype != opt) \
+ break; \
+ GETLONG(cilong, p); \
+ if (cilong != val) \
+ break; \
+ }
+
+#define ACKCIPROTO(opt, neg, val, bit) \
+ if (neg && (val & BIT(bit))) \
+ { \
+ if (len < 2) \
+ break; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_PROTOCOL || citype != opt) \
+ break; \
+ len -= cilen; \
+ if (len < 0) \
+ break; \
+ GETSHORT(cishort, p); \
+ if (cishort != (bit)) \
+ break; \
+ }
+/*
+ * Process the ACK frame in the order in which the frame was assembled
+ */
+ do {
+ ACKCINETWORK (IPX_NETWORK_NUMBER, go->neg_nn, go->our_network);
+ ACKCINODE (IPX_NODE_NUMBER, go->neg_node, go->our_node);
+ ACKCINAME (IPX_ROUTER_NAME, go->neg_name, go->name);
+ ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router, 0);
+ ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router, 2);
+ ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router, 4);
+ ACKCICOMPLETE (IPX_COMPLETE, go->neg_complete);
+/*
+ * This is the end of the record.
+ */
+ if (len == 0)
+ return (1);
+ } while (0);
+/*
+ * The frame is invalid
+ */
+ IPXCPDEBUG((LOG_INFO, "ipxcp_ackci: received bad Ack!"));
+ return (0);
+}
+
+/*
+ * ipxcp_nakci - Peer has sent a NAK for some of our CIs.
+ * This should not modify any state if the Nak is bad
+ * or if IPXCP is in the OPENED state.
+ *
+ * Returns:
+ * 0 - Nak was bad.
+ * 1 - Nak was good.
+ */
+
+static int
+ipxcp_nakci(f, p, len)
+ fsm *f;
+ u_char *p;
+ int len;
+{
+ int unit = f->unit;
+ u_char citype, cilen, *next;
+ u_short s;
+ u_int32_t l;
+ ipxcp_options no; /* options we've seen Naks for */
+ ipxcp_options try; /* options to request next time */
+
+ BZERO(&no, sizeof(no));
+ try = *go;
+
+ while (len > CILEN_VOID) {
+ GETCHAR (citype, p);
+ GETCHAR (cilen, p);
+ len -= cilen;
+ if (len < 0)
+ goto bad;
+ next = &p [cilen - CILEN_VOID];
+
+ switch (citype) {
+ case IPX_NETWORK_NUMBER:
+ if (!go->neg_nn || no.neg_nn || (cilen != CILEN_NETN))
+ goto bad;
+ no.neg_nn = 1;
+
+ GETLONG(l, p);
+ IPXCPDEBUG((LOG_INFO, "local IP address %d", l));
+ if (l && ao->accept_network)
+ try.our_network = l;
+ break;
+
+ case IPX_NODE_NUMBER:
+ if (!go->neg_node || no.neg_node || (cilen != CILEN_NODEN))
+ goto bad;
+ no.neg_node = 1;
+
+ IPXCPDEBUG((LOG_INFO,
+ "local node number %02X%02X%02X%02X%02X%02X",
+ NODE(p)));
+
+ if (!zero_node (p) && ao->accept_local &&
+ ! compare_node (p, ho->his_node))
+ copy_node (p, try.our_node);
+ break;
+
+ /* These have never been sent. Ignore the NAK frame */
+ case IPX_COMPRESSION_PROTOCOL:
+ goto bad;
+
+ case IPX_ROUTER_PROTOCOL:
+ if (!go->neg_router || (cilen < CILEN_PROTOCOL))
+ goto bad;
+
+ GETSHORT (s, p);
+ if ((s != 0) && (s != 2) && (s != 4))
+ goto bad;
+
+ if (no.router & BIT(s))
+ goto bad;
+
+ if (no.router == 0) /* Reset on first NAK only */
+ try.router = 0;
+ no.router |= BIT(s);
+ try.router |= BIT(s);
+ try.neg_router = 1;
+
+ IPXCPDEBUG((LOG_INFO, "Router protocol number %d", s));
+ break;
+
+ /* These, according to the RFC, must never be NAKed. */
+ case IPX_ROUTER_NAME:
+ case IPX_COMPLETE:
+ goto bad;
+
+ /* These are for options which we have not seen. */
+ default:
+ break;
+ }
+ p = next;
+ }
+
+ /* If there is still anything left, this packet is bad. */
+ if (len != 0)
+ goto bad;
+
+ /*
+ * Do not permit the peer to force a router protocol which we do not
+ * support.
+ */
+ try.router &= go->router;
+ if (try.router == 0 && go->router != 0) {
+ try.neg_router = 1;
+ try.router = BIT(0);
+ }
+
+ /*
+ * OK, the Nak is good. Now we can update state.
+ */
+ if (f->state != OPENED)
+ *go = try;
+
+ return 1;
+
+bad:
+ IPXCPDEBUG((LOG_INFO, "ipxcp_nakci: received bad Nak!"));
+ return 0;
+}
+
+/*
+ * ipxcp_rejci - Reject some of our CIs.
+ */
+static int
+ipxcp_rejci(f, p, len)
+ fsm *f;
+ u_char *p;
+ int len;
+{
+ int unit = f->unit;
+ u_short cilen, citype, cishort;
+ u_char cichar;
+ u_int32_t cilong;
+ ipxcp_options try; /* options to request next time */
+
+#define REJCINETWORK(opt, neg, val) \
+ if (neg) { \
+ neg = 0; \
+ if ((len -= CILEN_NETN) < 0) \
+ break; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_NETN || \
+ citype != opt) \
+ break; \
+ GETLONG(cilong, p); \
+ if (cilong != val) \
+ break; \
+ IPXCPDEBUG((LOG_INFO,"ipxcp_rejci rejected long opt %d", opt)); \
+ }
+
+#define REJCICHARS(opt, neg, val, cnt) \
+ if (neg) { \
+ int indx, count = cnt; \
+ neg = 0; \
+ len -= (count + 2); \
+ if (len < 0) \
+ break; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != (count + 2) || \
+ citype != opt) \
+ break; \
+ for (indx = 0; indx < count; ++indx) {\
+ GETCHAR(cichar, p); \
+ if (cichar != ((u_char *) &val)[indx]) \
+ break; \
+ }\
+ if (indx != count) \
+ break; \
+ IPXCPDEBUG((LOG_INFO,"ipxcp_rejci rejected opt %d", opt)); \
+ }
+
+#define REJCINODE(opt,neg,val) REJCICHARS(opt,neg,val,sizeof(val))
+#define REJCINAME(opt,neg,val) REJCICHARS(opt,neg,val,strlen(val))
+
+#define REJCIVOID(opt, neg) \
+ if (neg) { \
+ neg = 0; \
+ if ((len -= CILEN_VOID) < 0) \
+ break; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_VOID || citype != opt) \
+ break; \
+ IPXCPDEBUG((LOG_INFO, "ipxcp_rejci rejected void opt %d", opt)); \
+ }
+
+#define REJCIPROTO(opt, neg, val, bit) \
+ if (neg && (val & BIT(bit))) \
+ { \
+ if (len < 2) \
+ break; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_PROTOCOL || citype != opt) \
+ break; \
+ len -= cilen; \
+ if (len < 0) \
+ break; \
+ GETSHORT(cishort, p); \
+ if (cishort != (bit)) \
+ break; \
+ IPXCPDEBUG((LOG_INFO, "ipxcp_rejci rejected router proto %d", bit)); \
+ val &= ~BIT(bit); \
+ if (val == 0) \
+ neg = 0; \
+ }
+
+/*
+ * Any Rejected CIs must be in exactly the same order that we sent.
+ * Check packet length and CI length at each step.
+ * If we find any deviations, then this packet is bad.
+ */
+ try = *go;
+
+ do {
+ REJCINETWORK (IPX_NETWORK_NUMBER, try.neg_nn, try.our_network);
+ REJCINODE (IPX_NODE_NUMBER, try.neg_node, try.our_node);
+ REJCIPROTO (IPX_ROUTER_PROTOCOL, try.neg_router, try.router, 0);
+ REJCIPROTO (IPX_ROUTER_PROTOCOL, try.neg_router, try.router, 2);
+ REJCIPROTO (IPX_ROUTER_PROTOCOL, try.neg_router, try.router, 4);
+ REJCINAME (IPX_ROUTER_NAME, try.neg_name, try.name);
+ REJCIVOID (IPX_COMPLETE, try.neg_complete);
+/*
+ * This is the end of the record.
+ */
+ if (len == 0) {
+ if (f->state != OPENED)
+ *go = try;
+ return (1);
+ }
+ } while (0);
+/*
+ * The frame is invalid at this point.
+ */
+ IPXCPDEBUG((LOG_INFO, "ipxcp_rejci: received bad Reject!"));
+ return 0;
+}
+
+/*
+ * ipxcp_reqci - Check the peer's requested CIs and send appropriate response.
+ *
+ * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
+ * appropriately. If reject_if_disagree is non-zero, doesn't return
+ * CONFNAK; returns CONFREJ if it can't return CONFACK.
+ */
+static int
+ipxcp_reqci(f, inp, len, reject_if_disagree)
+ fsm *f;
+ u_char *inp; /* Requested CIs */
+ int *len; /* Length of requested CIs */
+ int reject_if_disagree;
+{
+ int unit = f->unit;
+ u_char *cip, *next; /* Pointer to current and next CIs */
+ u_short cilen, citype; /* Parsed len, type */
+ u_short cishort, ts; /* Parsed short value */
+ u_int32_t tl, cinetwork, outnet;/* 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 */
+ u_char *ucp = inp; /* Pointer to current output char */
+ int l = *len; /* Length left */
+ u_char maxslotindex, cflag;
+
+ /*
+ * Reset all his options.
+ */
+ BZERO(ho, sizeof(*ho));
+
+ /*
+ * Process all his options.
+ */
+ next = inp;
+ while (l) {
+ orc = CONFACK; /* Assume success */
+ cip = p = next; /* Remember begining of CI */
+ if (l < 2 || /* Not enough data for CI header or */
+ p[1] < 2 || /* CI length too small or */
+ p[1] > l) { /* CI length too big? */
+ IPXCPDEBUG((LOG_INFO, "ipxcp_reqci: bad CI length!"));
+ orc = CONFREJ; /* Reject bad CI */
+ cilen = l; /* Reject till end of packet */
+ l = 0; /* Don't loop again */
+ goto endswitch;
+ }
+ GETCHAR(citype, p); /* Parse CI type */
+ GETCHAR(cilen, p); /* Parse CI length */
+ l -= cilen; /* Adjust remaining length */
+ next += cilen; /* Step to next CI */
+
+ switch (citype) { /* Check CI type */
+/*
+ * The network number must match. Choose the larger of the two.
+ */
+ case IPX_NETWORK_NUMBER:
+ IPXCPDEBUG((LOG_INFO, "ipxcp: received Network Number request"));
+
+ /* if we wont negotiate the network number or the length is wrong
+ then reject the option */
+ if ( !ao->neg_nn || cilen != CILEN_NETN ) {
+ orc = CONFREJ;
+ break;
+ }
+ GETLONG(cinetwork, p);
+ IPXCPDEBUG((LOG_INFO,"Remote proposed IPX network number is %8Lx",tl));
+
+ /* If the network numbers match then acknowledge them. */
+ if (cinetwork != 0) {
+ ho->his_network = cinetwork;
+ ho->neg_nn = 1;
+ if (wo->our_network == cinetwork)
+ break;
+/*
+ * If the network number is not given or we don't accept their change or
+ * the network number is too small then NAK it.
+ */
+ if (! ao->accept_network || cinetwork < wo->our_network) {
+ DECPTR (sizeof (u_int32_t), p);
+ PUTLONG (wo->our_network, p);
+ orc = CONFNAK;
+ }
+ break;
+ }
+/*
+ * The peer sent '0' for the network. Give it ours if we have one.
+ */
+ if (go->our_network != 0) {
+ DECPTR (sizeof (u_int32_t), p);
+ PUTLONG (wo->our_network, p);
+ orc = CONFNAK;
+/*
+ * We don't have one. Reject the value.
+ */
+ } else
+ orc = CONFREJ;
+
+ break;
+/*
+ * The node number is required
+ */
+ case IPX_NODE_NUMBER:
+ IPXCPDEBUG((LOG_INFO, "ipxcp: received Node Number request"));
+
+ /* if we wont negotiate the node number or the length is wrong
+ then reject the option */
+ if ( cilen != CILEN_NODEN ) {
+ orc = CONFREJ;
+ break;
+ }
+
+ copy_node (p, ho->his_node);
+ ho->neg_node = 1;
+/*
+ * If the remote does not have a number and we do then NAK it with the value
+ * which we have for it. (We never have a default value of zero.)
+ */
+ if (zero_node (ho->his_node)) {
+ orc = CONFNAK;
+ copy_node (wo->his_node, p);
+ INCPTR (sizeof (wo->his_node), p);
+ break;
+ }
+/*
+ * If you have given me the expected network node number then I'll accept
+ * it now.
+ */
+ if (compare_node (wo->his_node, ho->his_node)) {
+ orc = CONFACK;
+ ho->neg_node = 1;
+ INCPTR (sizeof (wo->his_node), p);
+ break;
+ }
+/*
+ * If his node number is the same as ours then ask him to try the next
+ * value.
+ */
+ if (compare_node (ho->his_node, go->our_node)) {
+ inc_node (ho->his_node);
+ orc = CONFNAK;
+ copy_node (ho->his_node, p);
+ INCPTR (sizeof (wo->his_node), p);
+ break;
+ }
+/*
+ * If we don't accept a new value then NAK it.
+ */
+ if (! ao->accept_remote) {
+ copy_node (wo->his_node, p);
+ INCPTR (sizeof (wo->his_node), p);
+ orc = CONFNAK;
+ break;
+ }
+ orc = CONFACK;
+ ho->neg_node = 1;
+ INCPTR (sizeof (wo->his_node), p);
+ break;
+/*
+ * Compression is not desired at this time. It is always rejected.
+ */
+ case IPX_COMPRESSION_PROTOCOL:
+ IPXCPDEBUG((LOG_INFO, "ipxcp: received Compression Protocol request "));
+ orc = CONFREJ;
+ break;
+/*
+ * The routing protocol is a bitmask of various types. Any combination
+ * of the values 2 and 4 are permissible. '0' for no routing protocol must
+ * be specified only once.
+ */
+ case IPX_ROUTER_PROTOCOL:
+ if ( !ao->neg_router || cilen < CILEN_PROTOCOL ) {
+ orc = CONFREJ;
+ break;
+ }
+
+ GETSHORT (cishort, p);
+ IPXCPDEBUG((LOG_INFO,
+ "Remote router protocol number %d",
+ cishort));
+
+ if ((cishort == 0 && ho->router != 0) || (ho->router & BIT(0))) {
+ orc = CONFREJ;
+ break;
+ }
+
+ if (cishort != 0 && cishort != 2 && cishort != 4) {
+ orc = CONFREJ;
+ break;
+ }
+
+ if (ho->router & BIT (cishort)) {
+ orc = CONFREJ;
+ break;
+ }
+
+ ho->router |= BIT (cishort);
+ ho->neg_router = 1;
+ break;
+/*
+ * The router name is advisorary. Just accept it if it is not too large.
+ */
+ case IPX_ROUTER_NAME:
+ IPXCPDEBUG((LOG_INFO, "ipxcp: received Router Name request"));
+ if (cilen >= CILEN_NAME) {
+ int name_size = cilen - CILEN_NAME;
+ if (name_size > sizeof (ho->name))
+ name_size = sizeof (ho->name) - 1;
+ memset (ho->name, 0, sizeof (ho->name));
+ memcpy (ho->name, p, name_size);
+ ho->name [name_size] = '\0';
+ ho->neg_name = 1;
+ orc = CONFACK;
+ break;
+ }
+ orc = CONFREJ;
+ break;
+/*
+ * This is advisorary.
+ */
+ case IPX_COMPLETE:
+ IPXCPDEBUG((LOG_INFO, "ipxcp: received Complete request"));
+ if (cilen != CILEN_COMPLETE)
+ orc = CONFREJ;
+ else {
+ ho->neg_complete = 1;
+ orc = CONFACK;
+ }
+ break;
+/*
+ * All other entries are not known at this time.
+ */
+ default:
+ IPXCPDEBUG((LOG_INFO, "ipxcp: received Complete request"));
+ orc = CONFREJ;
+ break;
+ }
+
+endswitch:
+ IPXCPDEBUG((LOG_INFO, " (%s)\n", CODENAME(orc)));
+
+ if (orc == CONFACK && /* Good CI */
+ rc != CONFACK) /* but prior CI wasnt? */
+ continue; /* Don't send this one */
+
+ if (orc == CONFNAK) { /* Nak this CI? */
+ if (reject_if_disagree) /* Getting fed up with sending NAKs? */
+ orc = CONFREJ; /* Get tough if so */
+ 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 */
+ }
+ }
+
+ if (orc == CONFREJ && /* Reject this CI */
+ rc != CONFREJ) { /* but no prior ones? */
+ rc = CONFREJ;
+ ucp = inp; /* Backup */
+ }
+
+ /* Need to move CI? */
+ if (ucp != cip)
+ BCOPY(cip, ucp, cilen); /* Move it */
+
+ /* Update output pointer */
+ INCPTR(cilen, ucp);
+ }
+
+ /*
+ * If we aren't rejecting this packet, and we want to negotiate
+ * their address, and they didn't send their address, then we
+ * send a NAK with a IPX_NODE_NUMBER option appended. We assume the
+ * input buffer is long enough that we can append the extra
+ * option safely.
+ */
+
+ if (rc != CONFREJ && !ho->neg_node &&
+ wo->req_nn && !reject_if_disagree) {
+ u_char *ps;
+ if (rc == CONFACK) {
+ rc = CONFNAK;
+ wo->req_nn = 0; /* don't ask again */
+ ucp = inp; /* reset pointer */
+ }
+
+ if (zero_node (wo->his_node))
+ inc_node (wo->his_node);
+
+ PUTCHAR (IPX_NODE_NUMBER, ucp);
+ PUTCHAR (CILEN_NODEN, ucp);
+ copy_node (wo->his_node, ucp);
+ INCPTR (sizeof (wo->his_node), ucp);
+ }
+
+ *len = ucp - inp; /* Compute output length */
+ IPXCPDEBUG((LOG_INFO, "ipxcp: returning Configure-%s", CODENAME(rc)));
+ return (rc); /* Return final code */
+}
+
+/*
+ * ipxcp_up - IPXCP has come UP.
+ *
+ * Configure the IP network interface appropriately and bring it up.
+ */
+
+static void
+ipxcp_up(f)
+ fsm *f;
+{
+ int unit = f->unit;
+
+ IPXCPDEBUG((LOG_INFO, "ipxcp: up"));
+
+ if (!ho->neg_nn)
+ ho->his_network = wo->his_network;
+
+ if (!ho->neg_node)
+ copy_node (wo->his_node, ho->his_node);
+
+ if (!wo->neg_node && !go->neg_node)
+ copy_node (wo->our_node, go->our_node);
+
+ if (zero_node (go->our_node)) {
+ IPXCPDEBUG((LOG_ERR, "Could not determine local IPX node address"));
+ ipxcp_close(f->unit, "Could not determine local IPX node address");
+ return;
+ }
+
+ go->network = go->our_network;
+ if (ho->his_network != 0 && ho->his_network > go->network)
+ go->network = ho->his_network;
+
+ if (go->network == 0) {
+ IPXCPDEBUG((LOG_ERR, "Could not determine network number"));
+ ipxcp_close (unit, "Could not determine network number");
+ return;
+ }
+
+ /* bring the interface up */
+ if (!sifup(unit)) {
+ IPXCPDEBUG((LOG_WARNING, "sifup failed"));
+ ipxcp_close(unit, "Interface configuration failed");
+ return;
+ }
+
+ /* set the network number for IPX */
+ if (!sipxfaddr(unit, go->network, go->our_node)) {
+ IPXCPDEBUG((LOG_WARNING, "sipxfaddr failed"));
+ ipxcp_close(unit, "Interface configuration failed");
+ return;
+ }
+
+ /*
+ * Execute the ipx-up script, like this:
+ * /etc/ppp/ipx-up interface tty speed local-IPX remote-IPX
+ */
+
+ ipxcp_script (f, "/etc/ppp/ipx-up");
+}
+
+/*
+ * ipxcp_down - IPXCP has gone DOWN.
+ *
+ * Take the IP network interface down, clear its addresses
+ * and delete routes through it.
+ */
+
+static void
+ipxcp_down(f)
+ fsm *f;
+{
+ u_int32_t ournn, network;
+
+ IPXCPDEBUG((LOG_INFO, "ipxcp: down"));
+
+ cipxfaddr (f->unit);
+ sifdown(f->unit);
+ ipxcp_script (f, "/etc/ppp/ipx-down");
+}
+
+
+/*
+ * ipxcp_script - Execute a script with arguments
+ * interface-name tty-name speed local-IPX remote-IPX networks.
+ */
+static void
+ipxcp_script(f, script)
+ fsm *f;
+ char *script;
+{
+ int unit = f->unit;
+ char strspeed[32], strlocal[32], strremote[32];
+ char strnetwork[32], strpid[32];
+ char *argv[14], strproto_lcl[32], strproto_rmt[32];
+
+ sprintf (strpid, "%d", getpid());
+ sprintf (strspeed, "%d", baud_rate);
+
+ strproto_lcl[0] = '\0';
+ if (go->neg_router) {
+ if (go->router & BIT(2))
+ strcpy (strproto_lcl, "RIP ");
+ if (go->router & BIT(4))
+ strcpy (strproto_lcl, "NLSP ");
+ }
+
+ if (strproto_lcl[0] == '\0')
+ strcpy (strproto_lcl, "NONE ");
+
+ strproto_lcl[strlen (strproto_lcl)-1] = '\0';
+
+ strproto_rmt[0] = '\0';
+ if (ho->neg_router) {
+ if (ho->router & BIT(2))
+ strcpy (strproto_rmt, "RIP ");
+ if (ho->router & BIT(4))
+ strcpy (strproto_rmt, "NLSP ");
+ }
+
+ if (strproto_rmt[0] == '\0')
+ strcpy (strproto_rmt, "NONE ");
+
+ strproto_rmt[strlen (strproto_rmt)-1] = '\0';
+
+ strcpy (strnetwork, ipx_ntoa (go->network));
+
+ sprintf (strlocal,
+ "%02X%02X%02X%02X%02X%02X",
+ NODE(go->our_node));
+
+ sprintf (strremote,
+ "%02X%02X%02X%02X%02X%02X",
+ NODE(ho->his_node));
+
+ argv[0] = script;
+ argv[1] = ifname;
+ argv[2] = devnam;
+ argv[3] = strspeed;
+ argv[4] = strnetwork;
+ argv[5] = strlocal;
+ argv[6] = strremote;
+ argv[7] = strproto_lcl;
+ argv[8] = strproto_rmt;
+ argv[9] = go->name;
+ argv[10] = ho->name;
+ argv[11] = ipparam;
+ argv[12] = strpid;
+ argv[13] = NULL;
+ run_program(script, argv, 0);
+}
+
+/*
+ * ipxcp_printpkt - print the contents of an IPXCP packet.
+ */
+static char *ipxcp_codenames[] = {
+ "ConfReq", "ConfAck", "ConfNak", "ConfRej",
+ "TermReq", "TermAck", "CodeRej"
+};
+
+static int
+ipxcp_printpkt(p, plen, printer, arg)
+ u_char *p;
+ int plen;
+ void (*printer)();
+ void *arg;
+{
+ int code, id, len, olen;
+ u_char *pstart, *optend;
+ u_short cishort;
+ u_int32_t cilong;
+
+ if (plen < HEADERLEN)
+ return 0;
+ pstart = p;
+ GETCHAR(code, p);
+ GETCHAR(id, p);
+ GETSHORT(len, p);
+ if (len < HEADERLEN || len > plen)
+ return 0;
+
+ if (code >= 1 && code <= sizeof(ipxcp_codenames) / sizeof(char *))
+ printer(arg, " %s", ipxcp_codenames[code-1]);
+ else
+ printer(arg, " code=0x%x", code);
+ printer(arg, " id=0x%x", id);
+ len -= HEADERLEN;
+ switch (code) {
+ case CONFREQ:
+ case CONFACK:
+ case CONFNAK:
+ case CONFREJ:
+ /* print option list */
+ while (len >= 2) {
+ GETCHAR(code, p);
+ GETCHAR(olen, p);
+ p -= 2;
+ if (olen < CILEN_VOID || olen > len) {
+ break;
+ }
+ printer(arg, " <");
+ len -= olen;
+ optend = p + olen;
+ switch (code) {
+ case IPX_NETWORK_NUMBER:
+ if (olen == CILEN_NETN) {
+ p += CILEN_VOID;
+ GETLONG(cilong, p);
+ printer (arg, "network %s", ipx_ntoa (cilong));
+ }
+ break;
+ case IPX_NODE_NUMBER:
+ if (olen == CILEN_NODEN) {
+ p += CILEN_VOID;
+ printer (arg, "node ");
+ while (p < optend) {
+ GETCHAR(code, p);
+ printer(arg, "%.2x", code);
+ }
+ }
+ break;
+ case IPX_COMPRESSION_PROTOCOL:
+ if (olen == CILEN_COMPRESS) {
+ p += CILEN_VOID;
+ GETSHORT (cishort, p);
+ printer (arg, "compression %d", cishort);
+ }
+ break;
+ case IPX_ROUTER_PROTOCOL:
+ if (olen == CILEN_PROTOCOL) {
+ p += CILEN_VOID;
+ GETSHORT (cishort, p);
+ printer (arg, "router proto %d", cishort);
+ }
+ break;
+ case IPX_ROUTER_NAME:
+ if (olen >= CILEN_NAME) {
+ p += CILEN_VOID;
+ printer (arg, "router name \"");
+ while (p < optend) {
+ GETCHAR(code, p);
+ if (code >= 0x20 && code < 0x7E)
+ printer (arg, "%c", code);
+ else
+ printer (arg, " \\%.2x", code);
+ }
+ printer (arg, "\"");
+ }
+ break;
+ case IPX_COMPLETE:
+ if (olen == CILEN_COMPLETE) {
+ p += CILEN_VOID;
+ printer (arg, "complete");
+ }
+ break;
+ default:
+ break;
+ }
+
+ while (p < optend) {
+ GETCHAR(code, p);
+ printer(arg, " %.2x", code);
+ }
+ printer(arg, ">");
+ }
+ break;
+
+ case TERMACK:
+ case TERMREQ:
+ if (len > 0 && *p >= ' ' && *p < 0x7f) {
+ printer(arg, " ");
+ print_string(p, len, printer, arg);
+ p += len;
+ len = 0;
+ }
+ break;
+ }
+
+ /* print the rest of the bytes in the packet */
+ for (; len > 0; --len) {
+ GETCHAR(code, p);
+ printer(arg, " %.2x", code);
+ }
+
+ return p - pstart;
+}
+#endif /* ifdef IPX_CHANGE */
diff --git a/usr.sbin/pppd/ipxcp.h b/usr.sbin/pppd/ipxcp.h
new file mode 100644
index 00000000000..6dac3f865e8
--- /dev/null
+++ b/usr.sbin/pppd/ipxcp.h
@@ -0,0 +1,64 @@
+/*
+ * ipxcp.h - IPX Control Protocol definitions.
+ *
+ * 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.
+ *
+ * $Id: ipxcp.h,v 1.1 1996/07/20 12:02:09 joshd Exp $
+ */
+
+/*
+ * Options.
+ */
+#define IPX_NETWORK_NUMBER 1 /* IPX Network Number */
+#define IPX_NODE_NUMBER 2
+#define IPX_COMPRESSION_PROTOCOL 3
+#define IPX_ROUTER_PROTOCOL 4
+#define IPX_ROUTER_NAME 5
+#define IPX_COMPLETE 6
+
+
+typedef struct ipxcp_options {
+ int neg_node : 1; /* Negotiate IPX node number? */
+ int req_node : 1; /* Ask peer to send IPX node number? */
+
+ int neg_nn : 1; /* Negotiate IPX network number? */
+ int req_nn : 1; /* Ask peer to send IPX network number */
+
+ int neg_name : 1; /* Negotiate IPX router name */
+ int neg_complete : 1; /* Negotiate completion */
+ int neg_router : 1; /* Negotiate IPX router number */
+
+ int accept_local : 1; /* accept peer's value for ournode */
+ int accept_remote : 1; /* accept peer's value for hisnode */
+ int accept_network : 1; /* accept network number */
+
+ u_int32_t his_network; /* base network number */
+ u_int32_t our_network; /* our value for network number */
+ u_int32_t network; /* the final network number */
+
+ u_char his_node[6]; /* peer's node number */
+ u_char our_node[6]; /* our node number */
+ u_char name [48]; /* name of the router */
+ int router; /* routing protocol */
+} ipxcp_options;
+
+extern fsm ipxcp_fsm[];
+extern ipxcp_options ipxcp_wantoptions[];
+extern ipxcp_options ipxcp_gotoptions[];
+extern ipxcp_options ipxcp_allowoptions[];
+extern ipxcp_options ipxcp_hisoptions[];
+
+extern struct protent ipxcp_protent;
diff --git a/usr.sbin/pppd/lcp.c b/usr.sbin/pppd/lcp.c
index dd04e02fde2..a0dfdcd747d 100644
--- a/usr.sbin/pppd/lcp.c
+++ b/usr.sbin/pppd/lcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lcp.c,v 1.2 1996/03/25 15:55:46 niklas Exp $ */
+/* $OpenBSD: lcp.c,v 1.3 1996/07/20 12:02:10 joshd Exp $ */
/*
* lcp.c - PPP Link Control Protocol.
@@ -20,7 +20,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: lcp.c,v 1.2 1996/03/25 15:55:46 niklas Exp $";
+static char rcsid[] = "$OpenBSD: lcp.c,v 1.3 1996/07/20 12:02:10 joshd Exp $";
#endif
/*
@@ -103,11 +103,34 @@ static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
"LCP" /* String name of protocol */
};
+/*
+ * Protocol entry points.
+ * Some of these are called directly.
+ */
+
+static void lcp_init __P((int));
+static void lcp_input __P((int, u_char *, int));
+static void lcp_protrej __P((int));
+static int lcp_printpkt __P((u_char *, int,
+ void (*) __P((void *, char *, ...)), void *));
+
struct protent lcp_protent = {
- PPP_LCP, lcp_init, lcp_input, lcp_protrej,
- lcp_lowerup, lcp_lowerdown, lcp_open, lcp_close,
- lcp_printpkt, NULL, 1, "LCP", NULL, NULL
-};
+ PPP_LCP,
+ lcp_init,
+ lcp_input,
+ lcp_protrej,
+ lcp_lowerup,
+ lcp_lowerdown,
+ lcp_open,
+ lcp_close,
+ lcp_printpkt,
+ NULL,
+ 1,
+ "LCP",
+ NULL,
+ NULL,
+ NULL
+};
int lcp_loopbackfail = DEFLOOPBACKFAIL;
@@ -127,7 +150,7 @@ int lcp_loopbackfail = DEFLOOPBACKFAIL;
/*
* lcp_init - Initialize LCP.
*/
-void
+static void
lcp_init(unit)
int unit;
{
@@ -203,6 +226,7 @@ lcp_close(unit, reason)
{
fsm *f = &lcp_fsm[unit];
+ phase = PHASE_TERMINATE;
if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
/*
* This action is not strictly according to the FSM in RFC1548,
@@ -257,7 +281,7 @@ lcp_lowerdown(unit)
/*
* lcp_input - Input LCP packet.
*/
-void
+static void
lcp_input(unit, p, len)
int unit;
u_char *p;
@@ -366,7 +390,7 @@ lcp_rprotrej(f, inp, len)
* lcp_protrej - A Protocol-Reject was received.
*/
/*ARGSUSED*/
-void
+static void
lcp_protrej(unit)
int unit;
{
@@ -411,6 +435,7 @@ lcp_resetci(f)
lcp_wantoptions[f->unit].numloops = 0;
lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];
peer_mru[f->unit] = PPP_MRU;
+ auth_reset(f->unit);
}
@@ -739,8 +764,11 @@ lcp_nakci(f, p, len)
*/
if ((go->neg_chap || go->neg_upap)
&& len >= CILEN_SHORT
- && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT) {
+ && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
cilen = p[1];
+ len -= cilen;
+ no.neg_chap = go->neg_chap;
+ no.neg_upap = go->neg_upap;
INCPTR(2, p);
GETSHORT(cishort, p);
if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
@@ -751,7 +779,7 @@ lcp_nakci(f, p, len)
*/
if (!go->neg_chap)
goto bad;
- go->neg_chap = 0;
+ try.neg_chap = 0;
} else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
GETCHAR(cichar, p);
@@ -762,12 +790,12 @@ lcp_nakci(f, p, len)
* asking for CHAP.
*/
if (cichar != go->chap_mdtype)
- go->neg_chap = 0;
+ try.neg_chap = 0;
} else {
/*
* Stop asking for PAP if we were asking for it.
*/
- go->neg_upap = 0;
+ try.neg_upap = 0;
}
} else {
@@ -776,9 +804,9 @@ lcp_nakci(f, p, len)
* Stop asking for what we were asking for.
*/
if (go->neg_chap)
- go->neg_chap = 0;
+ try.neg_chap = 0;
else
- go->neg_upap = 0;
+ try.neg_upap = 0;
p += cilen - CILEN_SHORT;
}
}
@@ -813,7 +841,11 @@ lcp_nakci(f, p, len)
try.magicnumber = magic();
looped_back = 1;
);
-
+ /*
+ * 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.
+ */
NAKCIVOID(CI_PCOMPRESSION, neg_pcompression,
try.neg_pcompression = 0;
);
@@ -840,7 +872,7 @@ lcp_nakci(f, p, len)
while (len > CILEN_VOID) {
GETCHAR(citype, p);
GETCHAR(cilen, p);
- if ((len -= cilen) < 0)
+ if (cilen < CILEN_VOID || (len -= cilen) < 0)
goto bad;
next = p + cilen - 2;
@@ -1056,7 +1088,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
lcp_options *ho = &lcp_hisoptions[f->unit];
lcp_options *ao = &lcp_allowoptions[f->unit];
u_char *cip, *next; /* Pointer to current and next CIs */
- u_char cilen, citype, cichar;/* Parsed len, type, char value */
+ int cilen, citype, cichar;/* Parsed len, type, char value */
u_short cishort; /* Parsed short value */
u_int32_t cilong; /* Parse long value */
int rc = CONFACK; /* Final packet return code */
@@ -1206,7 +1238,11 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
break;
}
GETCHAR(cichar, p); /* get digest type*/
- if (cichar != ao->chap_mdtype) {
+ if (cichar != CHAP_DIGEST_MD5
+#ifdef CHAPMS
+ && cichar != CHAP_MICROSOFT
+#endif
+ ) {
orc = CONFNAK;
PUTCHAR(CI_AUTHTYPE, nakp);
PUTCHAR(CILEN_CHAP, nakp);
@@ -1460,13 +1496,13 @@ lcp_finished(f)
/*
* lcp_printpkt - print the contents of an LCP packet.
*/
-char *lcp_codenames[] = {
+static char *lcp_codenames[] = {
"ConfReq", "ConfAck", "ConfNak", "ConfRej",
"TermReq", "TermAck", "CodeRej", "ProtRej",
"EchoReq", "EchoRep", "DiscReq"
};
-int
+static int
lcp_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
@@ -1477,6 +1513,7 @@ lcp_printpkt(p, plen, printer, arg)
u_char *pstart, *optend;
u_short cishort;
u_int32_t cilong;
+ int fascii;
if (plen < HEADERLEN)
return 0;
@@ -1582,6 +1619,27 @@ lcp_printpkt(p, plen, printer, arg)
printer(arg, ">");
}
break;
+
+ case TERMACK:
+ case TERMREQ:
+ if (len > 0 && *p >= ' ' && *p < 0x7f) {
+ printer(arg, " ");
+ print_string(p, len, printer, arg);
+ p += len;
+ len = 0;
+ }
+ break;
+
+ case ECHOREQ:
+ case ECHOREP:
+ case DISCREQ:
+ if (len >= 4) {
+ GETLONG(cilong, p);
+ printer(arg, " magic=0x%x", cilong);
+ p += 4;
+ len -= 4;
+ }
+ break;
}
/* print the rest of the bytes in the packet */
diff --git a/usr.sbin/pppd/lcp.h b/usr.sbin/pppd/lcp.h
index 196a15ce10f..e7ad1b3eb19 100644
--- a/usr.sbin/pppd/lcp.h
+++ b/usr.sbin/pppd/lcp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: lcp.h,v 1.2 1996/03/25 15:55:47 niklas Exp $ */
+/* $OpenBSD: lcp.h,v 1.3 1996/07/20 12:02:11 joshd Exp $ */
/*
* lcp.h - Link Control Protocol definitions.
@@ -72,16 +72,11 @@ extern u_int32_t xmit_accm[][8];
#define MINMRU 128 /* No MRUs below this */
#define MAXMRU 16384 /* Normally limit MRU to this */
-void lcp_init __P((int));
void lcp_open __P((int));
void lcp_close __P((int, char *));
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 *));
+void lcp_sprotrej __P((int, u_char *, int)); /* send protocol reject */
extern struct protent lcp_protent;
diff --git a/usr.sbin/pppd/main.c b/usr.sbin/pppd/main.c
index f7d307941fd..2b2e9e0daac 100644
--- a/usr.sbin/pppd/main.c
+++ b/usr.sbin/pppd/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.8 1996/06/17 07:20:53 deraadt Exp $ */
+/* $OpenBSD: main.c,v 1.9 1996/07/20 12:02:11 joshd Exp $ */
/*
* main.c - Point-to-Point Protocol main module
@@ -20,7 +20,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: main.c,v 1.8 1996/06/17 07:20:53 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: main.c,v 1.9 1996/07/20 12:02:11 joshd Exp $";
#endif
#include <stdio.h>
@@ -78,10 +78,15 @@ static pid_t pid; /* Our pid */
static uid_t uid; /* Our real user-id */
int ttyfd = -1; /* Serial port file descriptor */
+mode_t tty_mode = -1; /* Original access permissions to tty */
+int baud_rate; /* Actual bits/second for serial device */
+int hungup; /* terminal has been hung up */
+
int phase; /* where the link is at */
int kill_link;
int open_ccp_flag;
+int redirect_stderr; /* Connector's stderr should go to file */
u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */
u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */
@@ -122,6 +127,10 @@ extern char *getlogin __P((void));
#define O_NONBLOCK O_NDELAY
#endif
+#ifdef PRIMITIVE_SYSLOG
+#define setlogmask(x)
+#endif
+
/*
* PPP Data Link Layer "protocol" table.
* One entry per supported protocol.
@@ -152,14 +161,24 @@ main(argc, argv)
struct timeval timo;
sigset_t mask;
struct protent *protp;
+ struct stat statbuf;
+ phase = PHASE_INITIALIZE;
p = ttyname(0);
if (p)
strcpy(devnam, p);
strcpy(default_devnam, devnam);
+ /* Initialize syslog facilities */
+#ifdef PRIMITIVE_SYSLOG
+ openlog("pppd", LOG_PID);
+#else
+ openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
+ setlogmask(LOG_UPTO(LOG_INFO));
+#endif
+
if (gethostname(hostname, MAXNAMELEN) < 0 ) {
- perror("couldn't get hostname");
+ syslog(LOG_ERR, "couldn't get hostname: %m");
die(1);
}
hostname[MAXNAMELEN-1] = 0;
@@ -168,18 +187,20 @@ main(argc, argv)
/*
* Initialize to the standard option set, then parse, in order,
- * the system options file, the user's options file, and the command
- * line arguments.
+ * the system options file, the user's options file,
+ * the tty's options file, and the command line arguments.
*/
for (i = 0; (protp = protocols[i]) != NULL; ++i)
(*protp->init)(0);
progname = *argv;
- if (!options_from_file(_PATH_SYSOPTIONS, REQ_SYSOPTIONS, 0) ||
- !options_from_user() ||
- !parse_args(argc-1, argv+1) ||
- !options_for_tty() )
+ if (!options_from_file(_PATH_SYSOPTIONS, REQ_SYSOPTIONS, 0)
+ || !options_from_user())
+ exit(1);
+ scan_args(argc-1, argv+1); /* look for tty name on command line */
+ if (!options_for_tty()
+ || !parse_args(argc-1, argv+1))
exit(1);
if (!ppp_available()) {
@@ -207,12 +228,17 @@ main(argc, argv)
*/
if (!default_device && strcmp(devnam, default_devnam) == 0)
default_device = 1;
+ redirect_stderr = !nodetach || default_device;
+
/*
* Initialize system-dependent stuff and magic number package.
*/
sys_init();
magic_init();
+ if (debug)
+ setlogmask(LOG_UPTO(LOG_DEBUG));
+
/*
* Detach ourselves from the terminal, if required,
@@ -303,6 +329,13 @@ main(argc, argv)
#endif
/*
+ * Apparently we can get a SIGPIPE when we call syslog, if
+ * syslogd has died and been restarted. Ignoring it seems
+ * be sufficient.
+ */
+ signal(SIGPIPE, SIG_IGN);
+
+ /*
* If we're doing dial-on-demand, set up the interface now.
*/
if (demand) {
@@ -388,6 +421,16 @@ main(argc, argv)
hungup = 0;
kill_link = 0;
+ /*
+ * Do the equivalent of `mesg n' to stop broadcast messages.
+ */
+ if (fstat(ttyfd, &statbuf) < 0
+ || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) {
+ syslog(LOG_WARNING,
+ "Couldn't restrict write permissions to %s: %m", devnam);
+ } else
+ tty_mode = statbuf.st_mode;
+
/* run connection script */
if (connector && connector[0]) {
MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector));
@@ -467,7 +510,7 @@ main(argc, argv)
if (open_ccp_flag) {
if (phase == PHASE_NETWORK) {
ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */
- ccp_open(0);
+ (*ccp_protent.open)(0);
}
open_ccp_flag = 0;
}
@@ -505,7 +548,8 @@ main(argc, argv)
}
if (!demand) {
- if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT)
+ if (pidfilename[0] != 0
+ && unlink(pidfilename) < 0 && errno != ENOENT)
syslog(LOG_WARNING, "unable to delete pid file: %m");
pidfilename[0] = 0;
}
@@ -686,6 +730,9 @@ close_tty()
restore_tty(ttyfd);
+ if (tty_mode != (mode_t) -1)
+ chmod(devnam, tty_mode);
+
close(ttyfd);
ttyfd = -1;
}
@@ -875,7 +922,11 @@ toggle_debug(sig)
int sig;
{
debug = !debug;
- note_debug_level();
+ if (debug) {
+ setlogmask(LOG_UPTO(LOG_DEBUG));
+ } else {
+ setlogmask(LOG_UPTO(LOG_WARNING));
+ }
}
@@ -927,11 +978,33 @@ device_script(program, in, out)
if (pid == 0) {
sys_close();
- dup2(in, 0);
- dup2(out, 1);
- errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0644);
- if (errfd >= 0)
- dup2(errfd, 2);
+ closelog();
+ if (in == out) {
+ if (in != 0) {
+ dup2(in, 0);
+ close(in);
+ }
+ dup2(0, 1);
+ } else {
+ if (out == 0)
+ out = dup(out);
+ if (in != 0) {
+ dup2(in, 0);
+ close(in);
+ }
+ if (out != 1) {
+ dup2(out, 1);
+ close(out);
+ }
+ }
+ if (redirect_stderr) {
+ close(2);
+ errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0644);
+ if (errfd >= 0 && errfd != 2) {
+ dup2(errfd, 2);
+ close(errfd);
+ }
+ }
setuid(getuid());
setgid(getgid());
execl("/bin/sh", "sh", "-c", program, (char *)0);
@@ -964,6 +1037,8 @@ run_program(prog, args, must_exist)
int must_exist;
{
int pid;
+ char *nullenv[1];
+
pid = fork();
if (pid == -1) {
@@ -982,6 +1057,7 @@ run_program(prog, args, must_exist)
/* Ensure that nothing of our device environment is inherited. */
sys_close();
+ closelog();
close (0);
close (1);
close (2);
@@ -1006,7 +1082,9 @@ run_program(prog, args, must_exist)
/* SysV recommends a second fork at this point. */
- execv(prog, args);
+ /* 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);
_exit(-1);
@@ -1103,43 +1181,23 @@ format_packet(p, len, printer, arg)
}
}
-#ifdef __STDC__
-#include <stdarg.h>
-
static void
-pr_log(void *arg, char *fmt, ...)
+pr_log __V((void *arg, char *fmt, ...))
{
int n;
va_list pvar;
char buf[256];
+#if __STDC__
va_start(pvar, fmt);
- vsprintf(buf, fmt, pvar);
- va_end(pvar);
-
- n = strlen(buf);
- if (linep + n + 1 > line + sizeof(line)) {
- syslog(LOG_DEBUG, "%s", line);
- linep = line;
- }
- strcpy(linep, buf);
- linep += n;
-}
-
-#else /* __STDC__ */
-#include <varargs.h>
-
-static void
-pr_log(arg, fmt, va_alist)
-void *arg;
-char *fmt;
-va_dcl
-{
- int n;
- va_list pvar;
- char buf[256];
-
+#else
+ void *arg;
+ char *fmt;
va_start(pvar);
+ arg = va_arg(pvar, void *);
+ fmt = va_arg(pvar, char *);
+#endif
+
vsprintf(buf, fmt, pvar);
va_end(pvar);
@@ -1151,7 +1209,6 @@ va_dcl
strcpy(linep, buf);
linep += n;
}
-#endif
/*
* print_string - print a readable representation of a string using
@@ -1169,11 +1226,27 @@ print_string(p, len, printer, arg)
printer(arg, "\"");
for (; len > 0; --len) {
c = *p++;
- if (' ' <= c && c <= '~')
+ if (' ' <= c && c <= '~') {
+ if (c == '\\' || c == '"')
+ printer(arg, "\\");
printer(arg, "%c", c);
- else
- printer(arg, "\\%.3o", c);
+ } else {
+ switch (c) {
+ case '\n':
+ printer(arg, "\\n");
+ break;
+ case '\r':
+ printer(arg, "\\r");
+ break;
+ case '\t':
+ printer(arg, "\\t");
+ break;
+ default:
+ printer(arg, "\\%.3o", c);
+ }
+ }
}
+
printer(arg, "\"");
}
@@ -1187,3 +1260,246 @@ novm(msg)
syslog(LOG_ERR, "Virtual memory exhausted allocating %s\n", msg);
die(1);
}
+
+/*
+ * fmtmsg - format a message into a buffer. Like sprintf except we
+ * also specify the length of the output buffer, and we handle
+ * %r (recursive format), %m (error message) and %I (IP address) formats.
+ * Doesn't do floating-point formats.
+ * Returns the number of chars put into buf.
+ */
+int
+fmtmsg __V((char *buf, int buflen, char *fmt, ...))
+{
+ va_list args;
+ int n;
+
+#if __STDC__
+ va_start(args, fmt);
+#else
+ char *buf;
+ int buflen;
+ char *fmt;
+ va_start(args);
+ buf = va_arg(args, char *);
+ buflen = va_arg(args, int);
+ fmt = va_arg(args, char *);
+#endif
+ n = vfmtmsg(buf, buflen, fmt, args);
+ va_end(args);
+ return n;
+}
+
+/*
+ * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args.
+ */
+#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0)
+
+int
+vfmtmsg(char *buf, int buflen, char *fmt, va_list args)
+{
+ int c, i, n;
+ int width, prec, fillch;
+ int base, len, neg, quoted;
+ unsigned long val;
+ char *str, *f, *buf0;
+ unsigned char *p;
+ va_list a;
+ char num[32];
+ time_t t;
+ static char hexchars[16] = "0123456789abcdef";
+
+ buf0 = buf;
+ --buflen;
+ while (buflen > 0) {
+ for (f = fmt; *f != '%' && *f != 0; ++f)
+ ;
+ if (f > fmt) {
+ len = f - fmt;
+ if (len > buflen)
+ len = buflen;
+ memcpy(buf, fmt, len);
+ buf += len;
+ buflen -= len;
+ fmt = f;
+ }
+ if (*fmt == 0)
+ break;
+ c = *++fmt;
+ width = prec = 0;
+ fillch = ' ';
+ if (c == '0') {
+ fillch = '0';
+ c = *++fmt;
+ }
+ if (c == '*') {
+ width = va_arg(args, int);
+ c = *++fmt;
+ } else {
+ while (isdigit(c)) {
+ width = width * 10 + c - '0';
+ c = *++fmt;
+ }
+ }
+ if (c == '.') {
+ c = *++fmt;
+ if (c == '*') {
+ prec = va_arg(args, int);
+ c = *++fmt;
+ } else {
+ while (isdigit(c)) {
+ prec = prec * 10 + c - '0';
+ c = *++fmt;
+ }
+ }
+ }
+ str = 0;
+ base = 0;
+ neg = 0;
+ ++fmt;
+ switch (c) {
+ case 'd':
+ i = va_arg(args, int);
+ if (i < 0) {
+ neg = 1;
+ val = -i;
+ } else
+ val = i;
+ base = 10;
+ break;
+ case 'o':
+ val = va_arg(args, unsigned int);
+ base = 8;
+ break;
+ case 'x':
+ val = va_arg(args, unsigned int);
+ base = 16;
+ break;
+ case 'p':
+ val = (unsigned long) va_arg(args, void *);
+ base = 16;
+ neg = 2;
+ break;
+ case 's':
+ str = va_arg(args, char *);
+ break;
+ case 'c':
+ num[0] = va_arg(args, int);
+ num[1] = 0;
+ str = num;
+ break;
+ case 'm':
+ str = strerror(errno);
+ break;
+ case 'I':
+ str = ip_ntoa(va_arg(args, u_int32_t));
+ break;
+ case 'r':
+ f = va_arg(args, char *);
+ a = va_arg(args, va_list);
+ n = vfmtmsg(buf, buflen + 1, f, a);
+ buf += n;
+ buflen -= n;
+ continue;
+ case 't':
+ time(&t);
+ str = ctime(&t);
+ str += 4; /* chop off the day name */
+ str[15] = 0; /* chop off year and newline */
+ break;
+ case 'v': /* "visible" string */
+ case 'q': /* quoted string */
+ quoted = c == 'q';
+ p = va_arg(args, unsigned char *);
+ if (fillch == '0' && prec > 0) {
+ n = prec;
+ } else {
+ n = strlen((char *)p);
+ if (prec > 0 && prec < n)
+ n = prec;
+ }
+ while (n > 0 && buflen > 0) {
+ c = *p++;
+ --n;
+ if (!quoted && c >= 0x80) {
+ OUTCHAR('M');
+ OUTCHAR('-');
+ c -= 0x80;
+ }
+ if (quoted && (c == '"' || c == '\\'))
+ OUTCHAR('\\');
+ if (c < 0x20 || 0x7f <= c && c < 0xa0) {
+ if (quoted) {
+ OUTCHAR('\\');
+ switch (c) {
+ case '\t': OUTCHAR('t'); break;
+ case '\n': OUTCHAR('n'); break;
+ case '\b': OUTCHAR('b'); break;
+ case '\f': OUTCHAR('f'); break;
+ default:
+ OUTCHAR('x');
+ OUTCHAR(hexchars[c >> 4]);
+ OUTCHAR(hexchars[c & 0xf]);
+ }
+ } else {
+ if (c == '\t')
+ OUTCHAR(c);
+ else {
+ OUTCHAR('^');
+ OUTCHAR(c ^ 0x40);
+ }
+ }
+ } else
+ OUTCHAR(c);
+ }
+ continue;
+ default:
+ *buf++ = '%';
+ if (c != '%')
+ --fmt; /* so %z outputs %z etc. */
+ --buflen;
+ continue;
+ }
+ if (base != 0) {
+ str = num + sizeof(num);
+ *--str = 0;
+ while (str > num + neg) {
+ *--str = hexchars[val % base];
+ val = val / base;
+ if (--prec <= 0 && val == 0)
+ break;
+ }
+ switch (neg) {
+ case 1:
+ *--str = '-';
+ break;
+ case 2:
+ *--str = 'x';
+ *--str = '0';
+ break;
+ }
+ len = num + sizeof(num) - 1 - str;
+ } else {
+ len = strlen(str);
+ if (prec > 0 && len > prec)
+ len = prec;
+ }
+ if (width > 0) {
+ if (width > buflen)
+ width = buflen;
+ if ((n = width - len) > 0) {
+ buflen -= n;
+ for (; n > 0; --n)
+ *buf++ = fillch;
+ }
+ }
+ if (len > buflen)
+ len = buflen;
+ memcpy(buf, str, len);
+ buf += len;
+ buflen -= len;
+ }
+ *buf = 0;
+ return buf - buf0;
+}
+
diff --git a/usr.sbin/pppd/md4.c b/usr.sbin/pppd/md4.c
new file mode 100644
index 00000000000..7d55856db82
--- /dev/null
+++ b/usr.sbin/pppd/md4.c
@@ -0,0 +1,295 @@
+/*
+** ********************************************************************
+** md4.c -- Implementation of MD4 Message Digest Algorithm **
+** Updated: 2/16/90 by Ronald L. Rivest **
+** (C) 1990 RSA Data Security, Inc. **
+** ********************************************************************
+*/
+
+/*
+** To use MD4:
+** -- Include md4.h in your program
+** -- Declare an MDstruct MD to hold the state of the digest
+** computation.
+** -- Initialize MD using MDbegin(&MD)
+** -- For each full block (64 bytes) X you wish to process, call
+** MDupdate(&MD,X,512)
+** (512 is the number of bits in a full block.)
+** -- For the last block (less than 64 bytes) you wish to process,
+** MDupdate(&MD,X,n)
+** where n is the number of bits in the partial block. A partial
+** block terminates the computation, so every MD computation
+** should terminate by processing a partial block, even if it
+** has n = 0.
+** -- The message digest is available in MD.buffer[0] ...
+** MD.buffer[3]. (Least-significant byte of each word
+** should be output first.)
+** -- You can print out the digest using MDprint(&MD)
+*/
+
+/* Implementation notes:
+** This implementation assumes that ints are 32-bit quantities.
+** If the machine stores the least-significant byte of an int in the
+** least-addressed byte (e.g., VAX and 8086), then LOWBYTEFIRST
+** should be set to TRUE. Otherwise (e.g., SUNS), LOWBYTEFIRST
+** should be set to FALSE. Note that on machines with LOWBYTEFIRST
+** FALSE the routine MDupdate modifies has a side-effect on its input
+** array (the order of bytes in each word are reversed). If this is
+** undesired a call to MDreverse(X) can reverse the bytes of X back
+** into order after each call to MDupdate.
+**
+** NOTE: LOWBYTEFIRST removed by Eric Rosenquist in favour of run-time
+** detection to simplify build process.
+*/
+
+#define TRUE 1
+#define FALSE 0
+
+/* Compile-time includes
+*/
+#include <stdio.h>
+#include "md4.h"
+#include "pppd.h"
+
+/* Compile-time declarations of MD4 "magic constants".
+*/
+#define I0 0x67452301 /* Initial values for MD buffer */
+#define I1 0xefcdab89
+#define I2 0x98badcfe
+#define I3 0x10325476
+#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */
+#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */
+/* C2 and C3 are from Knuth, The Art of Programming, Volume 2
+** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
+** Table 2, page 660.
+*/
+
+#define fs1 3 /* round 1 shift amounts */
+#define fs2 7
+#define fs3 11
+#define fs4 19
+#define gs1 3 /* round 2 shift amounts */
+#define gs2 5
+#define gs3 9
+#define gs4 13
+#define hs1 3 /* round 3 shift amounts */
+#define hs2 9
+#define hs3 11
+#define hs4 15
+
+/* Compile-time macro declarations for MD4.
+** Note: The "rot" operator uses the variable "tmp".
+** It assumes tmp is declared as unsigned int, so that the >>
+** operator will shift in zeros rather than extending the sign bit.
+*/
+#define f(X,Y,Z) ((X&Y) | ((~X)&Z))
+#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z))
+#define h(X,Y,Z) (X^Y^Z)
+#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S)))
+#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s)
+#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s)
+#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s)
+
+/* MDprint(MDp)
+** Print message digest buffer MDp as 32 hexadecimal digits.
+** Order is from low-order byte of buffer[0] to high-order byte of
+** buffer[3].
+** Each byte is printed with high-order hexadecimal digit first.
+** This is a user-callable routine.
+*/
+void
+MDprint(MDp)
+MDptr MDp;
+{ int i,j;
+for (i=0;i<4;i++)
+ for (j=0;j<32;j=j+8)
+ printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
+}
+
+/* MDbegin(MDp)
+** Initialize message digest buffer MDp.
+** This is a user-callable routine.
+*/
+void
+MDbegin(MDp)
+MDptr MDp;
+{ int i;
+MDp->buffer[0] = I0;
+MDp->buffer[1] = I1;
+MDp->buffer[2] = I2;
+MDp->buffer[3] = I3;
+for (i=0;i<8;i++) MDp->count[i] = 0;
+MDp->done = 0;
+}
+
+/* MDreverse(X)
+** Reverse the byte-ordering of every int in X.
+** Assumes X is an array of 16 ints.
+** The macro revx reverses the byte-ordering of the next word of X.
+*/
+#define revx { t = (*X << 16) | (*X >> 16); \
+ *X++ = ((t & 0xFF00FF00) >> 8) | ((t & 0x00FF00FF) << 8); }
+MDreverse(X)
+unsigned int *X;
+{ register unsigned int t;
+revx; revx; revx; revx; revx; revx; revx; revx;
+revx; revx; revx; revx; revx; revx; revx; revx;
+}
+
+/* MDblock(MDp,X)
+** Update message digest buffer MDp->buffer using 16-word data block X.
+** Assumes all 16 words of X are full of data.
+** Does not update MDp->count.
+** This routine is not user-callable.
+*/
+static void
+MDblock(MDp,X)
+MDptr MDp;
+unsigned int *X;
+{
+register unsigned int tmp, A, B, C, D;
+static int low_byte_first = -1;
+
+if (low_byte_first == -1) {
+ low_byte_first = (htons((unsigned short int)1) != 1);
+}
+
+if (low_byte_first == 0) {
+ MDreverse(X);
+}
+
+A = MDp->buffer[0];
+B = MDp->buffer[1];
+C = MDp->buffer[2];
+D = MDp->buffer[3];
+/* Update the message digest buffer */
+ff(A , B , C , D , 0 , fs1); /* Round 1 */
+ff(D , A , B , C , 1 , fs2);
+ff(C , D , A , B , 2 , fs3);
+ff(B , C , D , A , 3 , fs4);
+ff(A , B , C , D , 4 , fs1);
+ff(D , A , B , C , 5 , fs2);
+ff(C , D , A , B , 6 , fs3);
+ff(B , C , D , A , 7 , fs4);
+ff(A , B , C , D , 8 , fs1);
+ff(D , A , B , C , 9 , fs2);
+ff(C , D , A , B , 10 , fs3);
+ff(B , C , D , A , 11 , fs4);
+ff(A , B , C , D , 12 , fs1);
+ff(D , A , B , C , 13 , fs2);
+ff(C , D , A , B , 14 , fs3);
+ff(B , C , D , A , 15 , fs4);
+gg(A , B , C , D , 0 , gs1); /* Round 2 */
+gg(D , A , B , C , 4 , gs2);
+gg(C , D , A , B , 8 , gs3);
+gg(B , C , D , A , 12 , gs4);
+gg(A , B , C , D , 1 , gs1);
+gg(D , A , B , C , 5 , gs2);
+gg(C , D , A , B , 9 , gs3);
+gg(B , C , D , A , 13 , gs4);
+gg(A , B , C , D , 2 , gs1);
+gg(D , A , B , C , 6 , gs2);
+gg(C , D , A , B , 10 , gs3);
+gg(B , C , D , A , 14 , gs4);
+gg(A , B , C , D , 3 , gs1);
+gg(D , A , B , C , 7 , gs2);
+gg(C , D , A , B , 11 , gs3);
+gg(B , C , D , A , 15 , gs4);
+hh(A , B , C , D , 0 , hs1); /* Round 3 */
+hh(D , A , B , C , 8 , hs2);
+hh(C , D , A , B , 4 , hs3);
+hh(B , C , D , A , 12 , hs4);
+hh(A , B , C , D , 2 , hs1);
+hh(D , A , B , C , 10 , hs2);
+hh(C , D , A , B , 6 , hs3);
+hh(B , C , D , A , 14 , hs4);
+hh(A , B , C , D , 1 , hs1);
+hh(D , A , B , C , 9 , hs2);
+hh(C , D , A , B , 5 , hs3);
+hh(B , C , D , A , 13 , hs4);
+hh(A , B , C , D , 3 , hs1);
+hh(D , A , B , C , 11 , hs2);
+hh(C , D , A , B , 7 , hs3);
+hh(B , C , D , A , 15 , hs4);
+MDp->buffer[0] += A;
+MDp->buffer[1] += B;
+MDp->buffer[2] += C;
+MDp->buffer[3] += D;
+}
+
+/* MDupdate(MDp,X,count)
+** Input: MDp -- an MDptr
+** X -- a pointer to an array of unsigned characters.
+** count -- the number of bits of X to use.
+** (if not a multiple of 8, uses high bits of last byte.)
+** Update MDp using the number of bits of X given by count.
+** This is the basic input routine for an MD4 user.
+** The routine completes the MD computation when count < 512, so
+** every MD computation should end with one call to MDupdate with a
+** count less than 512. A call with count 0 will be ignored if the
+** MD has already been terminated (done != 0), so an extra call with
+** count 0 can be given as a "courtesy close" to force termination
+** if desired.
+*/
+void
+MDupdate(MDp,X,count)
+MDptr MDp;
+unsigned char *X;
+unsigned int count;
+{ unsigned int i, tmp, bit, byte, mask;
+unsigned char XX[64];
+unsigned char *p;
+/* return with no error if this is a courtesy close with count
+** zero and MDp->done is true.
+*/
+if (count == 0 && MDp->done) return;
+/* check to see if MD is already done and report error */
+if (MDp->done)
+ { printf("\nError: MDupdate MD already done."); return; }
+/* Add count to MDp->count */
+tmp = count;
+p = MDp->count;
+while (tmp)
+ { tmp += *p;
+ *p++ = tmp;
+ tmp = tmp >> 8;
+ }
+/* Process data */
+if (count == 512)
+ { /* Full block of data to handle */
+ MDblock(MDp,(unsigned int *)X);
+ }
+else if (count > 512) /* Check for count too large */
+ { printf("\nError: MDupdate called with illegal count value %d."
+ ,count);
+ return;
+ }
+else /* partial block -- must be last block so finish up */
+ { /* Find out how many bytes and residual bits there are */
+ byte = count >> 3;
+ bit = count & 7;
+ /* Copy X into XX since we need to modify it */
+ for (i=0;i<=byte;i++) XX[i] = X[i];
+ for (i=byte+1;i<64;i++) XX[i] = 0;
+ /* Add padding '1' bit and low-order zeros in last byte */
+ mask = 1 << (7 - bit);
+ XX[byte] = (XX[byte] | mask) & ~( mask - 1);
+ /* If room for bit count, finish up with this block */
+ if (byte <= 55)
+ { for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
+ MDblock(MDp,(unsigned int *)XX);
+ }
+ else /* need to do two blocks to finish up */
+ { MDblock(MDp,(unsigned int *)XX);
+ for (i=0;i<56;i++) XX[i] = 0;
+ for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
+ MDblock(MDp,(unsigned int *)XX);
+ }
+ /* Set flag saying we're done with MD computation */
+ MDp->done = 1;
+ }
+}
+
+/*
+** End of md4.c
+****************************(cut)***********************************/
diff --git a/usr.sbin/pppd/md4.h b/usr.sbin/pppd/md4.h
new file mode 100644
index 00000000000..af7af073b24
--- /dev/null
+++ b/usr.sbin/pppd/md4.h
@@ -0,0 +1,52 @@
+
+/*
+** ********************************************************************
+** md4.h -- Header file for implementation of **
+** MD4 Message Digest Algorithm **
+** Updated: 2/13/90 by Ronald L. Rivest **
+** (C) 1990 RSA Data Security, Inc. **
+** ********************************************************************
+*/
+
+/* MDstruct is the data structure for a message digest computation.
+*/
+typedef struct {
+unsigned int buffer[4]; /* Holds 4-word result of MD computation */
+unsigned char count[8]; /* Number of bits processed so far */
+unsigned int done; /* Nonzero means MD computation finished */
+} MDstruct, *MDptr;
+
+/* MDbegin(MD)
+** Input: MD -- an MDptr
+** Initialize the MDstruct prepatory to doing a message digest
+** computation.
+*/
+extern void MDbegin();
+
+/* MDupdate(MD,X,count)
+** Input: MD -- an MDptr
+** X -- a pointer to an array of unsigned characters.
+** count -- the number of bits of X to use (an unsigned int).
+** Updates MD using the first "count" bits of X.
+** The array pointed to by X is not modified.
+** If count is not a multiple of 8, MDupdate uses high bits of
+** last byte.
+** This is the basic input routine for a user.
+** The routine terminates the MD computation when count < 512, so
+** every MD computation should end with one call to MDupdate with a
+** count less than 512. Zero is OK for a count.
+*/
+extern void MDupdate();
+
+/* MDprint(MD)
+** Input: MD -- an MDptr
+** Prints message digest buffer MD as 32 hexadecimal digits.
+** Order is from low-order byte of buffer[0] to high-order byte
+** of buffer[3].
+** Each byte is printed with high-order hexadecimal digit first.
+*/
+extern void MDprint();
+
+/*
+** End of md4.h
+****************************(cut)***********************************/
diff --git a/usr.sbin/pppd/options.c b/usr.sbin/pppd/options.c
index 6ed99da6de8..a47eedd33ec 100644
--- a/usr.sbin/pppd/options.c
+++ b/usr.sbin/pppd/options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: options.c,v 1.3 1996/04/21 23:41:23 deraadt Exp $ */
+/* $OpenBSD: options.c,v 1.4 1996/07/20 12:02:13 joshd Exp $ */
/*
* options.c - handles option processing for PPP.
@@ -20,7 +20,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: options.c,v 1.3 1996/04/21 23:41:23 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: options.c,v 1.4 1996/07/20 12:02:13 joshd Exp $";
#endif
#include <ctype.h>
@@ -104,11 +104,14 @@ int idle_time_limit = 0; /* Disconnect if idle for this many seconds */
int holdoff = 30; /* # seconds to pause before reconnecting */
struct bpf_program pass_filter;/* Filter program for packets to pass */
struct bpf_program active_filter; /* Filter program for link-active pkts */
+int refuse_pap = 0; /* Set to say we won't do PAP */
+int refuse_chap = 0; /* Set to say we won't do CHAP */
+
/*
* Prototypes
*/
-static int setdevname __P((char *));
+static int setdevname __P((char *, int));
static int setipaddr __P((char *));
static int setdebug __P((void));
static int setkdebug __P((char **));
@@ -120,7 +123,9 @@ static int setnovjccomp __P((void));
static int setvjslots __P((char **));
static int reqpap __P((void));
static int nopap __P((void));
+#ifdef OLD_OPTIONS
static int setupapfile __P((char **));
+#endif
static int nochap __P((void));
static int reqchap __P((void));
static int setspeed __P((char *));
@@ -214,7 +219,9 @@ static int setdnsaddr __P((char **));
#endif
static int number_option __P((char *, u_int32_t *, int));
+static int int_option __P((char *, int *));
static int readable __P((int fd));
+static void option_error __P((char *fmt, ...));
void usage();
@@ -226,23 +233,40 @@ static struct cmd {
int num_args;
int (*cmd_func)();
} cmds[] = {
- {"-all", 0, noopt}, /* Don't request/allow any options */
+ {"-all", 0, noopt}, /* Don't request/allow any options (useless) */
+ {"noaccomp", 0, noaccomp}, /* Disable Address/Control compression */
{"-ac", 0, noaccomp}, /* Disable Address/Control compress */
+ {"default-asyncmap", 0, noasyncmap}, /* Disable asyncmap negoatiation */
{"-am", 0, noasyncmap}, /* Disable asyncmap negotiation */
{"-as", 1, setasyncmap}, /* set the desired async map */
{"-d", 0, setdebug}, /* Increase debugging level */
+ {"nodetach", 0, setnodetach}, /* Don't detach from controlling tty */
{"-detach", 0, setnodetach}, /* don't fork */
+ {"noip", 0, noip}, /* Disable IP and IPCP */
{"-ip", 0, noip}, /* Disable IP and IPCP */
+ {"nomagic", 0, nomagicnumber}, /* Disable magic number negotiation */
{"-mn", 0, nomagicnumber}, /* Disable magic number negotiation */
+ {"default-mru", 0, nomru}, /* Disable MRU negotiation */
{"-mru", 0, nomru}, /* Disable mru negotiation */
{"-p", 0, setpassive}, /* Set passive mode */
+ {"nopcomp", 0, nopcomp}, /* Disable protocol field compression */
+#ifdef OLD_OPTIONS
{"-pc", 0, nopcomp}, /* Disable protocol field compress */
+#endif
+ {"require-pap", 0, reqpap}, /* Require PAP authentication from peer */
+#ifdef OLD_OPTIONS
{"+ua", 1, setupapfile}, /* Get PAP user and password from file */
+#endif
{"+pap", 0, reqpap}, /* Require PAP auth from peer */
+ {"refuse-pap", 0, nopap}, /* Don't agree to auth to peer with PAP */
{"-pap", 0, nopap}, /* Don't allow UPAP authentication with peer */
+ {"require-chap", 0, reqchap}, /* Require CHAP authentication from peer */
{"+chap", 0, reqchap}, /* Require CHAP authentication from peer */
+ {"refuse-chap", 0, nochap}, /* Don't agree to auth to peer with CHAP */
{"-chap", 0, nochap}, /* Don't allow CHAP authentication with peer */
+ {"novj", 0, setnovj}, /* Disable VJ compression */
{"-vj", 0, setnovj}, /* disable VJ compression */
+ {"novjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */
{"-vjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */
{"vj-max-slots", 1, setvjslots}, /* Set maximum VJ header slots */
{"asyncmap", 1, setasyncmap}, /* set the desired async map */
@@ -252,6 +276,7 @@ static struct cmd {
{"welcome", 1, setwelcomer},/* Script to welcome client */
{"maxconnect", 1, setmaxconnect}, /* specify a maximum connect time */
{"crtscts", 0, setcrtscts}, /* set h/w flow control */
+ {"nocrtscts", 0, setnocrtscts}, /* clear h/w flow control */
{"-crtscts", 0, setnocrtscts}, /* clear h/w flow control */
{"xonxoff", 0, setxonxoff}, /* set s/w flow control */
{"debug", 0, setdebug}, /* Increase debugging level */
@@ -272,8 +297,10 @@ static struct cmd {
{"auth", 0, setauth}, /* Require authentication from peer */
{"file", 1, readfile}, /* Take options from a file */
{"defaultroute", 0, setdefaultroute}, /* Add default route */
+ {"nodefaultroute", 0, setnodefaultroute}, /* disable defaultroute option */
{"-defaultroute", 0, setnodefaultroute}, /* disable defaultroute option */
{"proxyarp", 0, setproxyarp}, /* Add proxy ARP entry */
+ {"noproxyarp", 0, setnoproxyarp}, /* disable proxyarp option */
{"-proxyarp", 0, setnoproxyarp}, /* disable proxyarp option */
{"persist", 0, setpersist}, /* Keep on reopening connection after close */
{"demand", 0, setdemand}, /* Dial on demand */
@@ -297,12 +324,16 @@ static struct cmd {
{"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 */
+ {"noccp", 0, noccp}, /* Disable CCP negotiation */
{"-ccp", 0, noccp}, /* Disable CCP negotiation */
{"bsdcomp", 1, setbsdcomp}, /* request BSD-Compress */
+ {"nobsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */
{"-bsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */
{"deflate", 1, setdeflate}, /* request Deflate compression */
+ {"nodeflate", 0, setnodeflate}, /* don't allow Deflate compression */
{"-deflate", 0, setnodeflate}, /* don't allow Deflate compression */
{"predictor1", 0, setpred1comp}, /* request Predictor-1 */
+ {"nopredictor1", 0, setnopred1comp},/* don't allow Predictor-1 */
{"-predictor1", 0, setnopred1comp}, /* don't allow Predictor-1 */
{"ipparam", 1, setipparam}, /* set ip script parameter */
{"papcrypt", 0, setpapcrypt}, /* PAP passwords encrypted */
@@ -326,6 +357,8 @@ static struct cmd {
#if 0
{"ipx-compression", 1, setipxcompression}, /* IPX compression number */
#endif
+ {"ipx", 0, setipxproto}, /* Enable IPXCP (and IPX) */
+ {"noipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */
{"+ipx", 0, setipxproto}, /* Enable IPXCP (and IPX) */
{"-ipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */
#endif /* IPX_CHANGE */
@@ -348,7 +381,7 @@ static struct cmd {
static char *usage_string = "\
pppd version %s patch level %d%s\n\
-Usage: %s [ arguments ], where arguments are:\n\
+Usage: %s [ options ], where options are:\n\
<device> Communicate over the named device\n\
<speed> Set the baud rate to <speed>\n\
<loc>:<rem> Set the local and/or remote interface IP\n\
@@ -365,6 +398,8 @@ Usage: %s [ arguments ], where arguments are:\n\
See pppd(8) for more options.\n\
";
+static char *current_option; /* the name of the option being parsed */
+
/*
* parse_args - parse a string of arguments, from the command
@@ -392,9 +427,10 @@ parse_args(argc, argv)
if (cmdp->cmd_name != NULL) {
if (argc < cmdp->num_args) {
- fprintf(stderr, "Too few parameters for command %s\n", arg);
+ option_error("too few parameters for option %s", arg);
return 0;
}
+ current_option = arg;
if (!(*cmdp->cmd_func)(argv))
return 0;
argc -= cmdp->num_args;
@@ -404,10 +440,10 @@ parse_args(argc, argv)
/*
* Maybe a tty name, speed or IP address?
*/
- if ((ret = setdevname(arg)) == 0
+ if ((ret = setdevname(arg, 0)) == 0
&& (ret = setspeed(arg)) == 0
&& (ret = setipaddr(arg)) == 0) {
- fprintf(stderr, "%s: unrecognized command\n", arg);
+ option_error("unrecognized option '%s'", arg);
usage();
return 0;
}
@@ -419,11 +455,45 @@ parse_args(argc, argv)
}
/*
+ * scan_args - scan the command line arguments to get the tty name,
+ * if specified.
+ */
+void
+scan_args(argc, argv)
+ int argc;
+ char **argv;
+{
+ char *arg;
+ struct cmd *cmdp;
+
+ while (argc > 0) {
+ arg = *argv++;
+ --argc;
+
+ /* Skip options and their arguments */
+ for (cmdp = cmds; cmdp->cmd_name; cmdp++)
+ if (!strcmp(arg, cmdp->cmd_name))
+ break;
+
+ if (cmdp->cmd_name != NULL) {
+ argc -= cmdp->num_args;
+ argv += cmdp->num_args;
+ continue;
+ }
+
+ /* Check if it's a tty name and copy it if so */
+ (void) setdevname(arg, 1);
+ }
+}
+
+
+/*
* usage - print out a message telling how to use the program.
*/
void
usage()
{
+ if (phase == PHASE_INITIALIZE)
fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION,
progname);
}
@@ -448,11 +518,11 @@ options_from_file(filename, must_exist, check_prot)
if ((f = fopen(filename, "r")) == NULL) {
if (!must_exist && errno == ENOENT)
return 1;
- perror(filename);
+ option_error("Can't open options file %s: %m", filename);
return 0;
}
if (check_prot && !readable(fileno(f))) {
- fprintf(stderr, "%s: access denied\n", filename);
+ option_error("Can't open options file %s: access denied", filename);
fclose(f);
return 0;
}
@@ -468,14 +538,15 @@ options_from_file(filename, must_exist, check_prot)
if (cmdp->cmd_name != NULL) {
for (i = 0; i < cmdp->num_args; ++i) {
if (!getword(f, args[i], &newline, filename)) {
- fprintf(stderr,
- "In file %s: too few parameters for command %s\n",
+ option_error(
+ "In file %s: too few parameters for option '%s'",
filename, cmd);
fclose(f);
return 0;
}
argv[i] = args[i];
}
+ current_option = cmd;
if (!(*cmdp->cmd_func)(argv)) {
fclose(f);
return 0;
@@ -485,10 +556,10 @@ options_from_file(filename, must_exist, check_prot)
/*
* Maybe a tty name, speed or IP address?
*/
- if ((ret = setdevname(cmd)) == 0
+ if ((ret = setdevname(cmd, 0)) == 0
&& (ret = setspeed(cmd)) == 0
&& (ret = setipaddr(cmd)) == 0) {
- fprintf(stderr, "In file %s: unrecognized command %s\n",
+ option_error("In file %s: unrecognized option '%s'",
filename, cmd);
fclose(f);
return 0;
@@ -555,6 +626,33 @@ options_for_tty()
}
/*
+ * option_error - print a message about an error in an option.
+ * The message is logged, and also sent to
+ * stderr if phase == PHASE_INITIALIZE.
+ */
+void
+option_error __V((char *fmt, ...))
+{
+ va_list args;
+ int n;
+ char buf[256];
+
+#if __STDC__
+ va_start(args, fmt);
+#else
+ char *fmt;
+ va_start(args);
+ fmt = va_arg(args, char *);
+#endif
+ vfmtmsg(buf, sizeof(buf), fmt, args);
+ va_end(args);
+ if (phase == PHASE_INITIALIZE)
+ fprintf(stderr, "%s: %s\n", progname, buf);
+ syslog(LOG_ERR, "%s", buf);
+}
+
+
+/*
* readable - check if a file is readable by the real user.
*/
static int
@@ -801,7 +899,7 @@ getword(f, word, newlinep, filename)
if (ferror(f)) {
if (errno == 0)
errno = EIO;
- perror(filename);
+ option_error("Error reading %s: %m", filename);
die(1);
}
/*
@@ -816,8 +914,8 @@ getword(f, word, newlinep, filename)
* Warn if the word was too long, and append a terminating null.
*/
if (len >= MAXWORDLEN) {
- fprintf(stderr, "%s: warning: word in file %s too long (%.20s...)\n",
- progname, filename, word);
+ option_error("warning: word in file %s too long (%.20s...)",
+ filename, word);
len = MAXWORDLEN - 1;
}
word[len] = 0;
@@ -841,7 +939,8 @@ number_option(str, valp, base)
*valp = strtoul(str, &ptr, base);
if (ptr == str) {
- fprintf(stderr, "%s: invalid number: %s\n", progname, str);
+ option_error("invalid numeric parameter '%s' for %s option",
+ str, current_option);
return 0;
}
return 1;
@@ -1008,7 +1107,7 @@ setmtu(argv)
if (!number_option(*argv, &mtu, 0))
return 0;
if (mtu < MINMRU || mtu > MAXMRU) {
- fprintf(stderr, "mtu option value of %ld is too %s\n", mtu,
+ option_error("mtu option value of %u is too %s", mtu,
(mtu < MINMRU? "small": "large"));
return 0;
}
@@ -1059,7 +1158,7 @@ setsilent()
static int
nopap()
{
- lcp_allowoptions[0].neg_upap = 0;
+ refuse_pap = 1;
return (1);
}
@@ -1076,6 +1175,7 @@ reqpap()
}
+#if OLD_OPTIONS
/*
* setupapfile - specifies UPAP info for authenticating with peer.
*/
@@ -1094,7 +1194,7 @@ setupapfile(argv)
return 0;
}
if (!readable(fileno(ufile))) {
- fprintf(stderr, "%s: access denied\n", *argv);
+ option_error("unable to open user login data file %s", *argv);
return 0;
}
check_access(ufile, *argv);
@@ -1102,7 +1202,7 @@ setupapfile(argv)
/* get username */
if (fgets(user, MAXNAMELEN - 1, ufile) == NULL
|| fgets(passwd, MAXSECRETLEN - 1, ufile) == NULL){
- fprintf(stderr, "Unable to read user login data file %s.\n", *argv);
+ option_error("%s: access denied", *argv);
return 0;
}
fclose(ufile);
@@ -1117,6 +1217,7 @@ setupapfile(argv)
return (1);
}
+#endif
/*
@@ -1125,7 +1226,7 @@ setupapfile(argv)
static int
nochap()
{
- lcp_allowoptions[0].neg_chap = 0;
+ refuse_chap = 1;
return (1);
}
@@ -1178,7 +1279,7 @@ setvjslots(argv)
if (!int_option(*argv, &value))
return 0;
if (value < 2 || value > 16) {
- fprintf(stderr, "pppd: vj-max-slots value must be between 2 and 16\n");
+ option_error("vj-max-slots value must be between 2 and 16");
return 0;
}
ipcp_wantoptions [0].maxslotindex =
@@ -1241,7 +1342,7 @@ setmaxconnect(argv)
if (!int_option(*argv, &value))
return 0;
if (value < 0) {
- fprintf(stderr, "pppd: maxconnect time must be positive\n");
+ option_error("maxconnect time must be positive");
return 0;
}
maxconnect = value;
@@ -1298,12 +1399,13 @@ setescape(argv)
while (*p) {
n = strtol(p, &endp, 16);
if (p == endp) {
- fprintf(stderr, "%s: invalid hex number: %s\n", progname, p);
+ option_error("escape parameter contains invalid hex number '%s'",
+ p);
return 0;
}
p = endp;
if (n < 0 || 0x20 <= n && n <= 0x3F || n == 0x5E || n > 0xFF) {
- fprintf(stderr, "%s: can't escape character 0x%x\n", progname, n);
+ option_error("can't escape character 0x%x", n);
ret = 0;
} else
xmit_accm[0][n >> 5] |= 1 << (n & 0x1F);
@@ -1336,12 +1438,16 @@ setspeed(arg)
* setdevname - Set the device name.
*/
static int
-setdevname(cp)
+setdevname(cp, quiet)
char *cp;
+ int quiet;
{
struct stat statbuf;
char dev[MAXPATHLEN];
-
+
+ if (*cp == 0)
+ return 0;
+
if (strncmp("/dev/", cp, 5) != 0) {
strcpy(dev, "/dev/");
strncat(dev, cp, MAXPATHLEN - 5);
@@ -1353,9 +1459,9 @@ setdevname(cp)
* Check if there is a device by this name.
*/
if (stat(cp, &statbuf) < 0) {
- if (errno == ENOENT)
+ if (errno == ENOENT || quiet)
return 0;
- syslog(LOG_ERR, cp);
+ option_error("Couldn't stat %s: %m", cp);
return -1;
}
@@ -1392,7 +1498,7 @@ setipaddr(arg)
*colon = '\0';
if ((local = inet_addr(arg)) == -1) {
if ((hp = gethostbyname(arg)) == NULL) {
- fprintf(stderr, "unknown host: %s\n", arg);
+ option_error("unknown host: %s", arg);
return -1;
} else {
local = *(u_int32_t *)hp->h_addr;
@@ -1403,7 +1509,7 @@ setipaddr(arg)
}
}
if (bad_ip_adrs(local)) {
- fprintf(stderr, "bad local IP address %s\n", ip_ntoa(local));
+ option_error("bad local IP address %s", ip_ntoa(local));
return -1;
}
if (local != 0)
@@ -1417,7 +1523,7 @@ setipaddr(arg)
if (*++colon != '\0') {
if ((remote = inet_addr(colon)) == -1) {
if ((hp = gethostbyname(colon)) == NULL) {
- fprintf(stderr, "unknown host: %s\n", colon);
+ option_error("unknown host: %s", colon);
return -1;
} else {
remote = *(u_int32_t *)hp->h_addr;
@@ -1428,7 +1534,7 @@ setipaddr(arg)
}
}
if (bad_ip_adrs(remote)) {
- fprintf(stderr, "bad remote IP address %s\n", ip_ntoa(remote));
+ option_error("bad remote IP address %s", ip_ntoa(remote));
return -1;
}
if (remote != 0)
@@ -1482,7 +1588,7 @@ setnetmask(argv)
u_int32_t mask;
if ((mask = inet_addr(*argv)) == -1 || (netmask & ~mask) != 0) {
- fprintf(stderr, "Invalid netmask %s\n", *argv);
+ option_error("invalid netmask value '%s'", *argv);
return 0;
}
@@ -1596,7 +1702,7 @@ static int
setdefaultroute()
{
if (!ipcp_allowoptions[0].default_route) {
- fprintf(stderr, "%s: defaultroute option is disabled\n", progname);
+ option_error("defaultroute option is disabled");
return 0;
}
ipcp_wantoptions[0].default_route = 1;
@@ -1615,7 +1721,7 @@ static int
setproxyarp()
{
if (!ipcp_allowoptions[0].proxy_arp) {
- fprintf(stderr, "%s: proxyarp option is disabled\n", progname);
+ option_error("proxyarp option is disabled");
return 0;
}
ipcp_wantoptions[0].proxy_arp = 1;
@@ -1784,14 +1890,13 @@ setbsdcomp(argv)
abits = strtol(str, &endp, 0);
}
if (*endp != 0 || endp == str) {
- fprintf(stderr, "%s: invalid argument format for bsdcomp option\n",
- progname);
+ option_error("invalid parameter '%s' for bsdcomp option", *argv);
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);
+ option_error("bsdcomp option values must be 0 or %d .. %d",
+ BSD_MIN_BITS, BSD_MAX_BITS);
return 0;
}
if (rbits > 0) {
@@ -1829,15 +1934,14 @@ setdeflate(argv)
abits = strtol(str, &endp, 0);
}
if (*endp != 0 || endp == str) {
- fprintf(stderr, "%s: invalid argument format for deflate option\n",
- progname);
+ option_error("invalid parameter '%s' for deflate option", *argv);
return 0;
}
if (rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE)
|| abits != 0 && (abits < DEFLATE_MIN_SIZE
|| abits > DEFLATE_MAX_SIZE)) {
- fprintf(stderr, "%s: deflate option values must be 0 or %d .. %d\n",
- progname, DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE);
+ option_error("deflate option values must be 0 or %d .. %d",
+ DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE);
return 0;
}
if (rbits > 0) {
@@ -1958,16 +2062,12 @@ setipxname (argv)
while (*src) {
ch = *src++;
if (! isalnum (ch) && ch != '_') {
- fprintf (stderr,
- "%s: IPX router name must be alphanumeric or _\n",
- progname);
+ option_error("IPX router name must be alphanumeric or _");
return 0;
}
if (count >= sizeof (ipxcp_wantoptions[0].name)) {
- fprintf (stderr,
- "%s: IPX router name is limited to %d characters\n",
- progname,
+ option_error("IPX router name is limited to %d characters",
sizeof (ipxcp_wantoptions[0].name) - 1);
return 0;
}
@@ -2079,22 +2179,21 @@ setipxnode(argv)
return 1;
}
- fprintf(stderr, "%s: invalid argument for ipx-node option\n",
- progname);
+ option_error("invalid parameter '%s' for ipx-node option", *argv);
return 0;
}
static int
setipxproto()
{
- ipx_enabled = 1; /* Enable IPXCP and IPX protocol */
+ ipxcp_protent.enabled_flag = 1;
return 1;
}
static int
resetipxproto()
{
- ipx_enabled = 0; /* Disable IPXCP and IPX protocol */
+ ipxcp_protent.enabled_flag = 0;
return 1;
}
#endif /* IPX_CHANGE */
@@ -2114,7 +2213,8 @@ setdnsaddr(argv)
dns = inet_addr(*argv);
if (dns == -1) {
if ((hp = gethostbyname(*argv)) == NULL) {
- fprintf(stderr, "Invalid DNS Address %s\n", *argv);
+ option_error("invalid address parameter '%s' for ms-dns option",
+ *argv);
return 0;
}
dns = *(u_int32_t *)hp->h_addr;
diff --git a/usr.sbin/pppd/patchlevel.h b/usr.sbin/pppd/patchlevel.h
index 4855a1f2bd4..be9ce8cac2f 100644
--- a/usr.sbin/pppd/patchlevel.h
+++ b/usr.sbin/pppd/patchlevel.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: patchlevel.h,v 1.2 1996/03/25 15:55:52 niklas Exp $ */
+/* $OpenBSD: patchlevel.h,v 1.3 1996/07/20 12:02:13 joshd Exp $ */
#define PATCHLEVEL 0
#define VERSION "2.3"
-#define IMPLEMENTATION "alpha2"
-#define DATE "6 March 96"
+#define IMPLEMENTATION "beta1"
+#define DATE "24 May 96"
diff --git a/usr.sbin/pppd/pathnames.h b/usr.sbin/pppd/pathnames.h
index 152ff75b110..823076e9881 100644
--- a/usr.sbin/pppd/pathnames.h
+++ b/usr.sbin/pppd/pathnames.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pathnames.h,v 1.2 1996/03/25 15:55:53 niklas Exp $ */
+/* $OpenBSD: pathnames.h,v 1.3 1996/07/20 12:02:13 joshd Exp $ */
/*
* define path names
@@ -17,6 +17,8 @@
#define _PATH_SYSOPTIONS "/etc/ppp/options"
#define _PATH_IPUP "/etc/ppp/ip-up"
#define _PATH_IPDOWN "/etc/ppp/ip-down"
+#define _PATH_AUTHUP "/etc/ppp/auth-up"
+#define _PATH_AUTHDOWN "/etc/ppp/auth-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.h b/usr.sbin/pppd/pppd.h
index 33061b389ba..61dde417eb0 100644
--- a/usr.sbin/pppd/pppd.h
+++ b/usr.sbin/pppd/pppd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pppd.h,v 1.2 1996/03/25 15:55:55 niklas Exp $ */
+/* $OpenBSD: pppd.h,v 1.3 1996/07/20 12:02:14 joshd Exp $ */
/*
* pppd.h - PPP daemon global declarations.
@@ -33,6 +33,14 @@
#include <net/ppp_defs.h>
#include <net/bpf.h>
+#if __STDC__
+#include <stdarg.h>
+#define __V(x) x
+#else
+#include <varargs.h>
+#define __V(x) (va_alist) va_dcl
+#endif
+
#define NUM_PPP 1 /* One PPP interface supported (per process) */
/*
@@ -57,6 +65,8 @@ 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 */
+extern int redirect_stderr; /* Connector's stderr should go to file */
+extern char peer_authname[]; /* Authenticated name of peer */
/*
* Variables set by command-line options.
@@ -95,17 +105,21 @@ extern int idle_time_limit;/* Shut down link if idle for this long */
extern int holdoff; /* Dead time before restarting */
extern struct bpf_program pass_filter; /* Filter for pkts to pass */
extern struct bpf_program active_filter; /* Filter for link-active pkts */
+extern int refuse_pap; /* Don't wanna auth. ourselves with PAP */
+extern int refuse_chap; /* Don't wanna auth. ourselves with CHAP */
+
/*
* Values for phase.
*/
#define PHASE_DEAD 0
-#define PHASE_DORMANT 1
-#define PHASE_ESTABLISH 2
-#define PHASE_AUTHENTICATE 3
-#define PHASE_NETWORK 4
-#define PHASE_TERMINATE 5
-#define PHASE_HOLDOFF 6
+#define PHASE_INITIALIZE 1
+#define PHASE_DORMANT 2
+#define PHASE_ESTABLISH 3
+#define PHASE_AUTHENTICATE 4
+#define PHASE_NETWORK 5
+#define PHASE_TERMINATE 6
+#define PHASE_HOLDOFF 7
/*
* The following struct gives the addresses of procedures to call
@@ -113,19 +127,34 @@ extern struct bpf_program active_filter; /* Filter for link-active pkts */
*/
struct protent {
u_short protocol; /* PPP protocol number */
- void (*init)(); /* Initialization procedure */
- void (*input)(); /* Process a received packet */
- void (*protrej)(); /* Process a received protocol-reject */
- void (*lowerup)(); /* Lower layer has come up */
- void (*lowerdown)(); /* Lower layer has gone down */
- void (*open)(); /* Open the protocol */
- void (*close)(); /* Close the protocol */
- int (*printpkt)(); /* Print a packet in readable form */
- void (*datainput)(); /* Process a received data packet */
+ /* Initialization procedure */
+ void (*init) __P((int unit));
+ /* Process a received packet */
+ void (*input) __P((int unit, u_char *pkt, int len));
+ /* Process a received protocol-reject */
+ void (*protrej) __P((int unit));
+ /* Lower layer has come up */
+ void (*lowerup) __P((int unit));
+ /* Lower layer has gone down */
+ void (*lowerdown) __P((int unit));
+ /* Open the protocol */
+ void (*open) __P((int unit));
+ /* Close the protocol */
+ void (*close) __P((int unit, char *reason));
+ /* Print a packet in readable form */
+ int (*printpkt) __P((u_char *pkt, int len,
+ void (*printer) __P((void *, char *, ...)),
+ void *arg));
+ /* Process a received data packet */
+ void (*datainput) __P((int unit, u_char *pkt, int len));
int enabled_flag; /* 0 iff protocol is disabled */
char *name; /* Text name of protocol */
- void (*check_options)(); /* Check requested options, assign dflts */
- int (*demand_conf)(); /* Configure interface for demand-dial */
+ /* Check requested options, assign defaults */
+ void (*check_options) __P((void));
+ /* Configure interface for demand-dial */
+ int (*demand_conf) __P((int unit));
+ /* Say whether to bring up link for this pkt */
+ int (*active_pkt) __P((u_char *pkt, int len));
};
/* Table of pointers to supported protocols */
@@ -153,6 +182,9 @@ void log_packet __P((u_char *, int, char *));
/* Format a packet and log it with syslog */
void print_string __P((char *, int, void (*) (void *, char *, ...),
void *)); /* Format a string for output */
+int fmtmsg __P((char *, int, char *, ...)); /* sprintf++ */
+int vfmtmsg __P((char *, int, char *, va_list)); /* vsprintf++ */
+
/* Procedures exported from auth.c */
void link_required __P((int)); /* we are starting to use the link */
@@ -164,7 +196,7 @@ void np_down __P((int, int)); /* a network protocol has gone down */
void np_finished __P((int, int)); /* a network protocol no longer needs link */
void auth_peer_fail __P((int, int));
/* peer failed to authenticate itself */
-void auth_peer_success __P((int, int));
+void auth_peer_success __P((int, int, char *, int));
/* peer successfully authenticated itself */
void auth_withpeer_fail __P((int, int));
/* we failed to authenticate ourselves */
@@ -172,6 +204,8 @@ void auth_withpeer_success __P((int, int));
/* we successfully authenticated ourselves */
void auth_check_options __P((void));
/* check authentication options supplied */
+void auth_reset __P((int)); /* check what secrets we have */
+
int check_passwd __P((int, char *, int, char *, int, char **, int *));
/* Check peer-supplied username/password */
int get_secret __P((int, char *, char *, char *, int *, int));
@@ -263,6 +297,9 @@ int options_from_file __P((char *filename, int must_exist, int check_prot));
/* Parse options from an options file */
int options_from_user __P((void)); /* Parse options from user's .ppprc */
int options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */
+void scan_args __P((int argc, char **argv));
+ /* Look for tty name in command-line args */
+
int getword __P((FILE *f, char *word, int *newlinep, char *filename));
/* Read a word from a file */
diff --git a/usr.sbin/pppd/upap.c b/usr.sbin/pppd/upap.c
index ac6725fd86b..5764f86022b 100644
--- a/usr.sbin/pppd/upap.c
+++ b/usr.sbin/pppd/upap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: upap.c,v 1.2 1996/03/25 15:55:58 niklas Exp $ */
+/* $OpenBSD: upap.c,v 1.3 1996/07/20 12:02:14 joshd Exp $ */
/*
* upap.c - User/Password Authentication Protocol.
@@ -20,7 +20,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: upap.c,v 1.2 1996/03/25 15:55:58 niklas Exp $";
+static char rcsid[] = "$OpenBSD: upap.c,v 1.3 1996/07/20 12:02:14 joshd Exp $";
#endif
/*
@@ -36,10 +36,34 @@ static char rcsid[] = "$OpenBSD: upap.c,v 1.2 1996/03/25 15:55:58 niklas Exp $";
#include "pppd.h"
#include "upap.h"
+/*
+ * Protocol entry points.
+ */
+static void upap_init __P((int));
+static void upap_lowerup __P((int));
+static void upap_lowerdown __P((int));
+static void upap_input __P((int, u_char *, int));
+static void upap_protrej __P((int));
+static int upap_printpkt __P((u_char *, int,
+ void (*) __P((void *, char *, ...)), void *));
+
struct protent pap_protent = {
- PPP_PAP, upap_init, upap_input, upap_protrej,
- upap_lowerup, upap_lowerdown, NULL, NULL,
- upap_printpkt, NULL, 1, "PAP", NULL, NULL
+ PPP_PAP,
+ upap_init,
+ upap_input,
+ upap_protrej,
+ upap_lowerup,
+ upap_lowerdown,
+ NULL,
+ NULL,
+ upap_printpkt,
+ NULL,
+ 1,
+ "PAP",
+ NULL,
+ NULL,
+ NULL
+
};
upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */
@@ -56,7 +80,7 @@ static void upap_sresp __P((upap_state *, int, int, char *, int));
/*
* upap_init - Initialize a UPAP unit.
*/
-void
+static void
upap_init(unit)
int unit;
{
@@ -176,7 +200,7 @@ upap_reqtimeout(arg)
*
* Start authenticating if pending.
*/
-void
+static void
upap_lowerup(unit)
int unit;
{
@@ -203,7 +227,7 @@ upap_lowerup(unit)
*
* Cancel all timeouts.
*/
-void
+static void
upap_lowerdown(unit)
int unit;
{
@@ -224,7 +248,7 @@ upap_lowerdown(unit)
*
* This shouldn't happen. In any case, pretend lower layer went down.
*/
-void
+static void
upap_protrej(unit)
int unit;
{
@@ -245,7 +269,7 @@ upap_protrej(unit)
/*
* upap_input - Input UPAP packet.
*/
-void
+static void
upap_input(unit, inpacket, l)
int unit;
u_char *inpacket;
@@ -362,11 +386,12 @@ upap_rauthreq(u, inp, id, len)
retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd,
rpasswdlen, &msg, &msglen);
+ BZERO(rpasswd, rpasswdlen);
upap_sresp(u, retcode, id, msg, msglen);
if (retcode == UPAP_AUTHACK) {
u->us_serverstate = UPAPSS_OPEN;
- auth_peer_success(u->us_unit, PPP_PAP);
+ auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
} else {
u->us_serverstate = UPAPSS_BADAUTH;
auth_peer_fail(u->us_unit, PPP_PAP);
@@ -521,11 +546,11 @@ upap_sresp(u, code, id, msg, msglen)
/*
* upap_printpkt - print the contents of a PAP packet.
*/
-char *upap_codenames[] = {
+static char *upap_codenames[] = {
"AuthReq", "AuthAck", "AuthNak"
};
-int
+static int
upap_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
diff --git a/usr.sbin/pppd/upap.h b/usr.sbin/pppd/upap.h
index 30c1a676b58..d38b74bf145 100644
--- a/usr.sbin/pppd/upap.h
+++ b/usr.sbin/pppd/upap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: upap.h,v 1.2 1996/03/25 15:55:59 niklas Exp $ */
+/* $OpenBSD: upap.h,v 1.3 1996/07/20 12:02:15 joshd Exp $ */
/*
* upap.h - User/Password Authentication Protocol definitions.
@@ -82,14 +82,7 @@ typedef struct upap_state {
extern upap_state upap[];
-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 *));
extern struct protent pap_protent;