Latest version of pppd from ppp-2.1 release

This commit is contained in:
paulus 1994-05-08 12:16:10 +00:00
parent 2434886725
commit 1a4adaf687
38 changed files with 2442 additions and 570 deletions

View File

@ -1,8 +1,8 @@
# $Id: Makefile,v 1.5 1993/11/10 01:33:51 paulus Exp $
# $Id: Makefile,v 1.6 1994/05/08 12:16:10 paulus Exp $
PROG= pppd
SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c \
auth.c options.c sys-bsd.c
auth.c options.c lock.c sys-bsd.c
MAN8= pppd.0
SUBDIR= pppstats chat
BINMODE=4555

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: auth.c,v 1.4 1994/01/25 05:58:02 paulus Exp $";
static char rcsid[] = "$Id: auth.c,v 1.5 1994/05/08 12:16:13 paulus Exp $";
#endif
#include <stdio.h>
@ -106,6 +106,7 @@ void check_access __ARGS((FILE *, char *));
static int login __ARGS((char *, char *, char **, int *));
static void logout __ARGS((void));
static int null_login __ARGS((int));
static int get_upap_passwd __ARGS((void));
static int have_upap_secret __ARGS((void));
static int have_chap_secret __ARGS((char *, char *));
@ -135,11 +136,18 @@ link_terminated(unit)
{
if (logged_in)
logout();
if (lcp_wantoptions[unit].restart) {
lcp_lowerdown(unit);
lcp_lowerup(unit);
} else
EXIT(unit);
phase = PHASE_DEAD;
syslog(LOG_NOTICE, "Connection terminated.");
}
/*
* LCP has gone down; it will either die or try to re-establish.
*/
void
link_down(unit)
int unit;
{
phase = PHASE_TERMINATE;
}
/*
@ -157,14 +165,19 @@ link_established(unit)
if (auth_required && !(go->neg_chap || go->neg_upap)) {
/*
* We wanted the peer to authenticate himself, and he refused:
* tell him to go away.
* We wanted the peer to authenticate itself, and it refused:
* treat it as though it authenticated with PAP using a username
* of "" and a password of "". If that's not OK, boot it out.
*/
if (wo->neg_upap && !null_login(unit)) {
syslog(LOG_WARNING, "peer refused to authenticate");
lcp_close(unit);
phase = PHASE_TERMINATE;
return;
}
}
phase = PHASE_AUTHENTICATE;
auth = 0;
if (go->neg_chap) {
ChapAuthPeer(unit, our_name, go->chap_mdtype);
@ -182,9 +195,11 @@ link_established(unit)
}
auth_pending[unit] = auth;
if (!auth)
if (!auth) {
phase = PHASE_NETWORK;
ipcp_open(unit);
}
}
/*
* The peer has failed to authenticate himself using `protocol'.
@ -197,6 +212,7 @@ auth_peer_fail(unit, protocol)
* Authentication failure: take the link down
*/
lcp_close(unit);
phase = PHASE_TERMINATE;
}
/*
@ -225,9 +241,11 @@ auth_peer_success(unit, protocol)
* If there is no more authentication still to be done,
* proceed to the network phase.
*/
if ((auth_pending[unit] &= ~bit) == 0)
if ((auth_pending[unit] &= ~bit) == 0) {
phase = PHASE_NETWORK;
ipcp_open(unit);
}
}
/*
* We have failed to authenticate ourselves to the peer using `protocol'.
@ -268,9 +286,11 @@ auth_withpeer_success(unit, protocol)
* If there is no more authentication still being done,
* proceed to the network phase.
*/
if ((auth_pending[unit] &= ~bit) == 0)
if ((auth_pending[unit] &= ~bit) == 0) {
phase = PHASE_NETWORK;
ipcp_open(unit);
}
}
/*
@ -485,6 +505,46 @@ logout()
}
/*
* null_login - Check if a username of "" and a password of "" are
* acceptable, and iff so, set the list of acceptable IP addresses
* and return 1.
*/
static int
null_login(unit)
int unit;
{
char *filename;
FILE *f;
int i, ret;
struct wordlist *addrs;
char secret[MAXWORDLEN];
/*
* Open the file of upap secrets and scan for a suitable secret.
* We don't accept a wildcard client.
*/
filename = _PATH_UPAPFILE;
addrs = NULL;
f = fopen(filename, "r");
if (f == NULL)
return 0;
check_access(f, filename);
i = scan_authfile(f, "", our_name, secret, &addrs, filename);
ret = i >= 0 && (i & NONWILD_CLIENT) != 0 && secret[0] == 0;
if (ret) {
if (addresses[unit] != NULL)
free_wordlist(addresses[unit]);
addresses[unit] = addrs;
}
fclose(f);
return ret;
}
/*
* get_upap_passwd - get a password for authenticating ourselves with
* our peer using PAP. Returns 1 on success, 0 if no suitable password

View File

@ -19,7 +19,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: chap.c,v 1.3 1993/11/10 01:33:59 paulus Exp $";
static char rcsid[] = "$Id: chap.c,v 1.4 1994/05/08 12:16:15 paulus Exp $";
#endif
/*
@ -557,6 +557,8 @@ ChapReceiveSuccess(cstate, inp, id, len)
return;
}
UNTIMEOUT(ChapResponseTimeout, (caddr_t) cstate);
/*
* Print message.
*/
@ -591,6 +593,8 @@ ChapReceiveFailure(cstate, inp, id, len)
return;
}
UNTIMEOUT(ChapResponseTimeout, (caddr_t) cstate);
/*
* Print message.
*/
@ -738,6 +742,71 @@ ChapSendResponse(cstate)
++cstate->resp_transmits;
}
/*
* ChapPrintPkt - print the contents of a CHAP packet.
*/
char *ChapCodenames[] = {
"Challenge", "Response", "Success", "Failure"
};
int
ChapPrintPkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __ARGS((void *, char *, ...));
void *arg;
{
int code, id, len;
int clen, nlen;
u_char x;
if (plen < CHAP_HEADERLEN)
return 0;
GETCHAR(code, p);
GETCHAR(id, p);
GETSHORT(len, p);
if (len < CHAP_HEADERLEN || len > plen)
return 0;
if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *))
printer(arg, " %s", ChapCodenames[code-1]);
else
printer(arg, " code=0x%x", code);
printer(arg, " id=0x%x", id);
len -= CHAP_HEADERLEN;
switch (code) {
case CHAP_CHALLENGE:
case CHAP_RESPONSE:
if (len < 1)
break;
clen = p[0];
if (len < clen + 1)
break;
++p;
nlen = len - clen - 1;
printer(arg, " <");
for (; clen > 0; --clen) {
GETCHAR(x, p);
printer(arg, "%.2x", x);
}
printer(arg, ">, name = ");
print_string((char *)p, nlen, printer, arg);
break;
case CHAP_FAILURE:
case CHAP_SUCCESS:
printer(arg, " ");
print_string((char *)p, len, printer, arg);
break;
default:
for (clen = len; clen > 0; --clen) {
GETCHAR(x, p);
printer(arg, " %.2x", x);
}
}
return len + CHAP_HEADERLEN;
}
#ifdef NO_DRAND48
double drand48()

View File

@ -1,6 +1,5 @@
/*
* chap.h - Cryptographic Handshake Authentication Protocol definitions.
* based on November 1991 draft of PPP Authentication RFC
*
* Copyright (c) 1991 Gregory M. Christy
* All rights reserved.
@ -16,13 +15,13 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: chap.h,v 1.3 1993/11/10 01:34:02 paulus Exp $
* $Id: chap.h,v 1.4 1994/05/08 12:16:16 paulus Exp $
*/
#ifndef __CHAP_INCLUDE__
/* Code + ID + length */
#define CHAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
#define CHAP_HEADERLEN 4
/*
* CHAP codes.
@ -106,6 +105,8 @@ void ChapLowerUp __ARGS((int));
void ChapLowerDown __ARGS((int));
void ChapInput __ARGS((int, u_char *, int));
void ChapProtocolReject __ARGS((int));
int ChapPrintPkt __ARGS((u_char *, int,
void (*) __ARGS((void *, char *, ...)), void *));
#define __CHAP_INCLUDE__
#endif /* __CHAP_INCLUDE__ */

View File

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: fsm.c,v 1.3 1993/11/10 01:34:04 paulus Exp $";
static char rcsid[] = "$Id: fsm.c,v 1.4 1994/05/08 12:16:17 paulus Exp $";
#endif
/*
@ -29,7 +29,6 @@ static char rcsid[] = "$Id: fsm.c,v 1.3 1993/11/10 01:34:04 paulus Exp $";
#include <stdio.h>
#include <sys/types.h>
/*#include <malloc.h>*/
#include <syslog.h>
#include "ppp.h"
@ -453,6 +452,7 @@ fsm_rconfack(f, id, inp, len)
PROTO_NAME(f), len));
return;
}
f->reqid = -1;
switch (f->state) {
case CLOSED:
@ -514,6 +514,7 @@ fsm_rconfnakrej(f, code, id, inp, len)
PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
return;
}
f->reqid = -1;
switch (f->state) {
case CLOSED:
@ -556,7 +557,6 @@ fsm_rtermreq(f, id)
FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d.",
PROTO_NAME(f), id));
fsm_sdata(f, TERMACK, id, NULL, 0);
switch (f->state) {
case ACKRCVD:
case ACKSENT:
@ -572,6 +572,8 @@ fsm_rtermreq(f, id)
TIMEOUT(fsm_timeout, (caddr_t) f, f->timeouttime);
break;
}
fsm_sdata(f, TERMACK, id, NULL, 0);
}

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: fsm.h,v 1.3 1993/11/10 01:34:07 paulus Exp $
* $Id: fsm.h,v 1.4 1994/05/08 12:16:18 paulus Exp $
*/
/*
@ -35,11 +35,6 @@
#define TERMREQ 5 /* Termination Request */
#define TERMACK 6 /* Termination Ack */
#define CODEREJ 7 /* Code Reject */
#define PROTREJ 8 /* Protocol Reject */
#define ECHOREQ 9 /* Echo Request */
#define ECHOREP 10 /* Echo Reply */
#define DISCREQ 11 /* Discard Request */
#define KEEPALIVE 12 /* Keepalive */
/*

View File

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: ipcp.c,v 1.4 1994/02/22 00:11:57 paulus Exp $";
static char rcsid[] = "$Id: ipcp.c,v 1.5 1994/05/08 12:16:19 paulus Exp $";
#endif
/*
@ -43,7 +43,7 @@ static char rcsid[] = "$Id: ipcp.c,v 1.4 1994/02/22 00:11:57 paulus Exp $";
#include "ppp.h"
#include "fsm.h"
#include "ipcp.h"
#include "pathnames.h"
/* global vars */
ipcp_options ipcp_wantoptions[NPPP]; /* Options that we want to request */
@ -51,6 +51,10 @@ ipcp_options ipcp_gotoptions[NPPP]; /* Options that peer ack'd */
ipcp_options ipcp_allowoptions[NPPP]; /* Options we allow peer to request */
ipcp_options ipcp_hisoptions[NPPP]; /* Options that we ack'd */
extern char ifname[];
extern char devname[];
extern int baud_rate;
/* local vars */
static int cis_received[NPPP]; /* # Conf-Reqs received */
@ -66,7 +70,7 @@ static int ipcp_rejci __ARGS((fsm *, u_char *, int)); /* Peer rej'd our CI */
static int ipcp_reqci __ARGS((fsm *, u_char *, int *, int)); /* Rcv CI */
static void ipcp_up __ARGS((fsm *)); /* We're UP */
static void ipcp_down __ARGS((fsm *)); /* We're DOWN */
static void ipcp_script __ARGS((fsm *, char *)); /* Run an up/down script */
fsm ipcp_fsm[NPPP]; /* IPCP fsm structure */
@ -885,6 +889,10 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
}
ho->maxslotindex = maxslotindex;
ho->cflag = wo->cflag;
} else {
ho->old_vj = 1;
ho->maxslotindex = MAX_STATES - 1;
ho->cflag = 1;
}
break;
@ -988,7 +996,7 @@ ipcp_up(f)
}
/*
* Check that the peer is allowed to use the IP address he wants.
* Check that the peer is allowed to use the IP address it wants.
*/
if (!auth_ip_addr(f->unit, ho->hisaddr)) {
syslog(LOG_ERR, "Peer is not authorized to use remote address %s",
@ -1011,7 +1019,7 @@ ipcp_up(f)
}
/* set tcp compression */
sifvjcomp(f->unit, ho->neg_vj, ho->cflag);
sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);
/* bring the interface up for IP */
if (!sifup(f->unit)) {
@ -1029,6 +1037,13 @@ ipcp_up(f)
if (ipcp_wantoptions[f->unit].proxy_arp)
if (sifproxyarp(f->unit, ho->hisaddr))
go->proxy_arp = 1;
/*
* Execute the ip-up script, like this:
* /etc/ppp/ip-up interface tty speed local-IP remote-IP
*/
ipcp_script(f, _PATH_IPUP);
}
@ -1054,4 +1069,138 @@ ipcp_down(f)
cifdefaultroute(f->unit, hisaddr);
sifdown(f->unit);
cifaddr(f->unit, ouraddr, hisaddr);
/* Execute the ip-down script */
ipcp_script(f, _PATH_IPDOWN);
}
/*
* ipcp_script - Execute a script with arguments
* interface-name tty-name speed local-IP remote-IP.
*/
static void
ipcp_script(f, script)
fsm *f;
char *script;
{
char strspeed[32], strlocal[32], strremote[32];
char *argv[8];
sprintf(strspeed, "%d", baud_rate);
strcpy(strlocal, ip_ntoa(ipcp_gotoptions[f->unit].ouraddr));
strcpy(strremote, ip_ntoa(ipcp_hisoptions[f->unit].hisaddr));
argv[0] = script;
argv[1] = ifname;
argv[2] = devname;
argv[3] = strspeed;
argv[4] = strlocal;
argv[5] = strremote;
argv[6] = NULL;
run_program(script, argv, 0);
}
/*
* ipcp_printpkt - print the contents of an IPCP packet.
*/
char *ipcp_codenames[] = {
"ConfReq", "ConfAck", "ConfNak", "ConfRej",
"TermReq", "TermAck", "CodeRej"
};
int
ipcp_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_long 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(ipcp_codenames) / sizeof(char *))
printer(arg, " %s", ipcp_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 < 2 || olen > len) {
break;
}
printer(arg, " <");
len -= olen;
optend = p + olen;
switch (code) {
case CI_ADDRS:
if (olen == CILEN_ADDRS) {
p += 2;
GETLONG(cilong, p);
printer(arg, "addrs %s", ip_ntoa(htonl(cilong)));
GETLONG(cilong, p);
printer(arg, " %s", ip_ntoa(htonl(cilong)));
}
break;
case CI_COMPRESSTYPE:
if (olen >= CILEN_COMPRESS) {
p += 2;
GETSHORT(cishort, p);
printer(arg, "compress ");
switch (cishort) {
case IPCP_VJ_COMP:
printer(arg, "VJ");
break;
case IPCP_VJ_COMP_OLD:
printer(arg, "old-VJ");
break;
default:
printer(arg, "0x%x", cishort);
}
}
break;
case CI_ADDR:
if (olen == CILEN_ADDR) {
p += 2;
GETLONG(cilong, p);
printer(arg, "addr %s", ip_ntoa(htonl(cilong)));
}
break;
}
while (p < optend) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
printer(arg, ">");
}
break;
}
/* print the rest of the bytes in the packet */
for (; len > 0; --len) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
return p - pstart;
}

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ipcp.h,v 1.4 1994/02/22 00:11:59 paulus Exp $
* $Id: ipcp.h,v 1.5 1994/05/08 12:16:20 paulus Exp $
*/
/*
@ -65,3 +65,4 @@ void ipcp_lowerup __ARGS((int));
void ipcp_lowerdown __ARGS((int));
void ipcp_input __ARGS((int, u_char *, int));
void ipcp_protrej __ARGS((int));
int ipcp_printpkt __ARGS((u_char *, int, void (*)(), void *));

View File

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: lcp.c,v 1.3 1993/11/10 01:34:15 paulus Exp $";
static char rcsid[] = "$Id: lcp.c,v 1.4 1994/05/08 12:16:22 paulus Exp $";
#endif
/*
@ -55,6 +55,7 @@ lcp_options lcp_wantoptions[NPPP]; /* Options that we want to request */
lcp_options lcp_gotoptions[NPPP]; /* Options that peer ack'd */
lcp_options lcp_allowoptions[NPPP]; /* Options we allow peer to request */
lcp_options lcp_hisoptions[NPPP]; /* Options that we ack'd */
u_long xmit_accm[NPPP][8]; /* extended transmit ACCM */
/*
* Callbacks for fsm code. (CI = Configuration Information)
@ -129,7 +130,7 @@ lcp_init(unit)
implementations */
wo->neg_mru = 1;
wo->mru = DEFMRU;
wo->neg_asyncmap = 1;
wo->neg_asyncmap = 0;
wo->asyncmap = 0;
wo->neg_chap = 0; /* Set to 1 on server */
wo->neg_upap = 0; /* Set to 1 on server */
@ -151,6 +152,8 @@ lcp_init(unit)
ao->neg_accompression = 1;
ao->neg_lqr = 0; /* no LQR implementation yet */
memset(xmit_accm[unit], 0, sizeof(xmit_accm[0]));
xmit_accm[unit][3] = 0x60000000;
}
@ -192,9 +195,11 @@ lcp_lowerup(unit)
int unit;
{
sifdown(unit);
ppp_set_xaccm(unit, xmit_accm[unit]);
ppp_send_config(unit, MTU, 0xffffffff, 0, 0);
ppp_recv_config(unit, MTU, 0, 0, 0);
peer_mru[unit] = MTU;
lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0];
fsm_lowerup(&lcp_fsm[unit]);
}
@ -1219,7 +1224,7 @@ lcp_up(f)
* set our MRU to the larger of value we wanted and
* the value we got in the negotiation.
*/
ppp_send_config(f->unit, (ho->neg_mru? MIN(ao->mru, ho->mru): MTU),
ppp_send_config(f->unit, MIN(ao->mru, (ho->neg_mru? ho->mru: MTU)),
(ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
ho->neg_pcompression, ho->neg_accompression);
ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): MTU),
@ -1254,7 +1259,8 @@ lcp_down(f)
ppp_send_config(f->unit, MTU, 0xffffffff, 0, 0);
ppp_recv_config(f->unit, MTU, 0, 0, 0);
peer_mru[f->unit] = MTU;
syslog(LOG_NOTICE, "Connection terminated.");
link_down(f->unit);
}
@ -1279,3 +1285,139 @@ lcp_finished(f)
link_terminated(f->unit);
}
/*
* lcp_printpkt - print the contents of an LCP packet.
*/
char *lcp_codenames[] = {
"ConfReq", "ConfAck", "ConfNak", "ConfRej",
"TermReq", "TermAck", "CodeRej", "ProtRej",
"EchoReq", "EchoRep", "DiscReq"
};
int
lcp_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __ARGS((void *, char *, ...));
void *arg;
{
int code, id, len, olen;
u_char *pstart, *optend;
u_short cishort;
u_long 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(lcp_codenames) / sizeof(char *))
printer(arg, " %s", lcp_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 < 2 || olen > len) {
break;
}
printer(arg, " <");
len -= olen;
optend = p + olen;
switch (code) {
case CI_MRU:
if (olen == CILEN_SHORT) {
p += 2;
GETSHORT(cishort, p);
printer(arg, "mru %d", cishort);
}
break;
case CI_ASYNCMAP:
if (olen == CILEN_LONG) {
p += 2;
GETLONG(cilong, p);
printer(arg, "asyncmap 0x%x", cilong);
}
break;
case CI_AUTHTYPE:
if (olen >= CILEN_SHORT) {
p += 2;
printer(arg, "auth ");
GETSHORT(cishort, p);
switch (cishort) {
case UPAP:
printer(arg, "upap");
break;
case CHAP:
printer(arg, "chap");
break;
default:
printer(arg, "0x%x", cishort);
}
}
break;
case CI_QUALITY:
if (olen >= CILEN_SHORT) {
p += 2;
printer(arg, "quality ");
GETSHORT(cishort, p);
switch (cishort) {
case LQR:
printer(arg, "lqr");
break;
default:
printer(arg, "0x%x", cishort);
}
}
break;
case CI_MAGICNUMBER:
if (olen == CILEN_LONG) {
p += 2;
GETLONG(cilong, p);
printer(arg, "magic 0x%x", cilong);
}
break;
case CI_PCOMPRESSION:
if (olen == CILEN_VOID) {
p += 2;
printer(arg, "pcomp");
}
break;
case CI_ACCOMPRESSION:
if (olen == CILEN_VOID) {
p += 2;
printer(arg, "accomp");
}
break;
}
while (p < optend) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
printer(arg, ">");
}
break;
}
/* print the rest of the bytes in the packet */
for (; len > 0; --len) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
return p - pstart;
}

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: lcp.h,v 1.3 1993/11/10 01:34:17 paulus Exp $
* $Id: lcp.h,v 1.4 1994/05/08 12:16:23 paulus Exp $
*/
/*
@ -27,10 +27,16 @@
#define CI_AUTHTYPE 3 /* Authentication Type */
#define CI_QUALITY 4 /* Quality Protocol */
#define CI_MAGICNUMBER 5 /* Magic Number */
#define CI_KEEPALIVE 6 /* Keep Alive Parameters - OBSOLETE */
#define CI_PCOMPRESSION 7 /* Protocol Field Compression */
#define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */
/*
* LCP-specific packet types.
*/
#define PROTREJ 8 /* Protocol Reject */
#define ECHOREQ 9 /* Echo Request */
#define ECHOREP 10 /* Echo Reply */
#define DISCREQ 11 /* Discard Request */
/*
* The state of options is described by an lcp_options structure.
@ -60,6 +66,7 @@ extern lcp_options lcp_wantoptions[];
extern lcp_options lcp_gotoptions[];
extern lcp_options lcp_allowoptions[];
extern lcp_options lcp_hisoptions[];
extern u_long xmit_accm[][8];
#define DEFMRU 1500 /* Try for this */
#define MINMRU 128 /* No MRUs below this */
@ -73,6 +80,8 @@ void lcp_lowerdown __ARGS((int));
void lcp_input __ARGS((int, u_char *, int));
void lcp_protrej __ARGS((int));
void lcp_sprotrej __ARGS((int, u_char *, int));
int lcp_printpkt __ARGS((u_char *, int,
void (*) __ARGS((void *, char *, ...)), void *));
extern int lcp_warnloops; /* Warn about a loopback this often */
#define DEFWARNLOOPS 10 /* Default value for above */

View File

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: main.c,v 1.8 1994/01/25 05:58:05 paulus Exp $";
static char rcsid[] = "$Id: main.c,v 1.9 1994/05/08 12:16:24 paulus Exp $";
#endif
#define SETSID
@ -30,6 +30,7 @@ static char rcsid[] = "$Id: main.c,v 1.8 1994/01/25 05:58:05 paulus Exp $";
#include <syslog.h>
#include <netdb.h>
#include <utmp.h>
#include <sys/wait.h>
/*
* If REQ_SYSOPTIONS is defined to 1, pppd will not run unless
@ -39,10 +40,6 @@ static char rcsid[] = "$Id: main.c,v 1.8 1994/01/25 05:58:05 paulus Exp $";
#define REQ_SYSOPTIONS 0
#endif
#ifdef STREAMS
#undef SGTTY
#endif
#ifdef SGTTY
#include <sgtty.h>
#else
@ -115,6 +112,8 @@ int default_device = TRUE; /* use default device (stdin/out) */
int fd; /* Device file descriptor */
int s; /* Socket file descriptor */
int phase; /* where the link is at */
#ifdef SGTTY
static struct sgttyb initsgttyb; /* Initial TTY sgttyb */
#else
@ -129,14 +128,18 @@ u_char outpacket_buf[MTU+DLLHEADERLEN]; /* buffer for outgoing packet */
static u_char inpacket_buf[MTU+DLLHEADERLEN]; /* buffer for incoming packet */
int hungup; /* terminal has been hung up */
static int n_children; /* # child processes still running */
/* configured variables */
int debug = 0; /* Debug flag */
int kdebugflag = 0; /* Kernel debugging flag */
char user[MAXNAMELEN]; /* username for PAP */
char passwd[MAXSECRETLEN]; /* password for PAP */
char *connector = NULL; /* "connect" command */
int inspeed = 0; /* Input/Output speed */
char *disconnector = NULL; /* "disconnect" command */
int inspeed = 0; /* Input/Output speed requested */
int baud_rate; /* bits/sec currently used */
u_long netmask = 0; /* netmask to use on ppp interface */
int crtscts = 0; /* use h/w flow control */
int nodetach = 0; /* don't fork */
@ -147,6 +150,7 @@ int proxyarp = 0; /* set entry in arp table */
int persist = 0; /* re-initiate on termination */
int answer = 0; /* wait for incoming call */
int uselogin = 0; /* check PAP info against /etc/passwd */
int lockflag = 0; /* lock the serial device */
/* prototypes */
@ -159,13 +163,16 @@ static void incdebug __ARGS((int));
static void nodebug __ARGS((int));
void establish_ppp __ARGS((void));
void reap_kids __ARGS((void));
void cleanup __ARGS((int, caddr_t));
void die __ARGS((int));
void dumpbuffer __ARGS((unsigned char *, int, int));
void novm __ARGS((char *));
void log_packet __ARGS((u_char *, int, char *));
void format_packet __ARGS((u_char *, int,
void (*) (void *, char *, ...), void *));
void pr_log __ARGS((void *, char *, ...));
#ifdef STREAMS
extern char *ttyname __ARGS((int));
#endif
extern char *getlogin __ARGS((void));
/*
@ -177,13 +184,16 @@ static struct protent {
void (*init)();
void (*input)();
void (*protrej)();
int (*printpkt)();
char *name;
} prottbl[] = {
{ LCP, lcp_init, lcp_input, lcp_protrej },
{ IPCP, ipcp_init, ipcp_input, ipcp_protrej },
{ UPAP, upap_init, upap_input, upap_protrej },
{ CHAP, ChapInit, ChapInput, ChapProtocolReject },
{ LCP, lcp_init, lcp_input, lcp_protrej, lcp_printpkt, "LCP" },
{ IPCP, ipcp_init, ipcp_input, ipcp_protrej, ipcp_printpkt, "IPCP" },
{ UPAP, upap_init, upap_input, upap_protrej, upap_printpkt, "PAP" },
{ CHAP, ChapInit, ChapInput, ChapProtocolReject, ChapPrintPkt, "CHAP" },
};
#define N_PROTO (sizeof(prottbl) / sizeof(prottbl[0]))
main(argc, argv)
int argc;
@ -195,28 +205,8 @@ main(argc, argv)
FILE *pidfile;
char *p;
/*
* Initialize syslog system and magic number package.
*/
#if BSD >= 43 || defined(sun)
openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
setlogmask(LOG_UPTO(LOG_INFO));
#else
openlog("pppd", LOG_PID);
#define LOG_UPTO(x) (x)
#define setlogmask(x) (x)
#endif
#ifdef STREAMS
p = ttyname(fileno(stdin));
if (p)
strcpy(devname, p);
#endif
magic_init();
if (gethostname(hostname, MAXNAMELEN) < 0 ) {
syslog(LOG_ERR, "couldn't get hostname: %m");
perror("couldn't get hostname");
die(1);
}
hostname[MAXNAMELEN-1] = 0;
@ -233,7 +223,7 @@ main(argc, argv)
* the system options file, the user's options file, and the command
* line arguments.
*/
for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++)
for (i = 0; i < N_PROTO; i++)
(*prottbl[i].init)(0);
progname = *argv;
@ -245,6 +235,20 @@ main(argc, argv)
check_auth_options();
setipdefault();
if (lockflag && !default_device)
if (lock(devname) < 0)
die(1);
/*
* Initialize syslog system and magic number package.
*/
openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
setlogmask(LOG_UPTO(LOG_INFO));
if (debug)
setlogmask(LOG_UPTO(LOG_DEBUG));
magic_init();
p = getlogin();
if (p == NULL)
p = "(unknown)";
@ -314,9 +318,6 @@ main(argc, argv)
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGALRM);
sigaddset(&mask, SIGIO);
#ifdef STREAMS
sigaddset(&mask, SIGPOLL);
#endif
#define SIGNAL(s, handler) { \
sv.sv_handler = handler; \
@ -333,9 +334,6 @@ main(argc, argv)
SIGNAL(SIGTERM, term); /* Terminate */
SIGNAL(SIGALRM, alrm); /* Timeout */
SIGNAL(SIGIO, io); /* Input available */
#ifdef STREAMS
SIGNAL(SIGPOLL, io); /* Input available */
#endif
signal(SIGUSR1, incdebug); /* Increment debug flag */
signal(SIGUSR2, nodebug); /* Reset debug flag */
@ -345,9 +343,6 @@ main(argc, argv)
*/
sigemptyset(&mask);
sigaddset(&mask, SIGIO);
#ifdef STREAMS
sigaddset(&mask, SIGPOLL);
#endif
sigprocmask(SIG_BLOCK, &mask, NULL);
/*
@ -359,18 +354,20 @@ main(argc, argv)
}
hungup = 0;
#ifdef TIOCSCTTY
/* set device to be controlling tty */
if (!default_device && ioctl(fd, TIOCSCTTY) < 0) {
syslog(LOG_ERR, "ioctl(TIOCSCTTY): %m");
die(1);
}
/* set line speed, flow control, etc. */
set_up_tty(fd);
#endif /* TIOCSCTTY */
/* run connection script */
if (connector) {
syslog(LOG_INFO, "Connecting with <%s>", connector);
MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector));
/* set line speed, flow control, etc.; set CLOCAL for now */
set_up_tty(fd, 1);
/* drop dtr to hang up in case modem is off hook */
if (!default_device && modem) {
@ -379,7 +376,7 @@ main(argc, argv)
setdtr(fd, TRUE);
}
if (set_up_connection(connector, fd, fd) < 0) {
if (device_script(connector, fd, fd) < 0) {
syslog(LOG_ERR, "could not set up connection");
setdtr(fd, FALSE);
die(1);
@ -389,6 +386,9 @@ main(argc, argv)
sleep(1); /* give it time to set up its terminal */
}
/* set line speed, flow control, etc.; clear CLOCAL if modem option */
set_up_tty(fd, 0);
/* set up the serial device as a ppp interface */
establish_ppp();
@ -450,9 +450,24 @@ main(argc, argv)
sigprocmask(SIG_BLOCK, &mask, NULL); /* Block signals now */
lcp_lowerup(0); /* XXX Well, sort of... */
lcp_open(0); /* Start protocol */
for (;;) {
for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) {
sigpause(0); /* Wait for next signal */
reap_kids(); /* Don't leave dead kids lying around */
}
/*
* Run disconnector script, if requested
*/
if (disconnector) {
if (device_script(disconnector, fd, fd) < 0) {
syslog(LOG_WARNING, "disconnect script failed");
die(1);
}
syslog(LOG_INFO, "Disconnected...");
}
quit();
}
#if B9600 == 9600
@ -461,6 +476,7 @@ main(argc, argv)
* (so we can ask for any speed).
*/
#define translate_speed(bps) (bps)
#define baud_rate_of(speed) (speed)
#else
/*
@ -555,14 +571,32 @@ translate_speed(bps)
syslog(LOG_WARNING, "speed %d not supported", bps);
return 0;
}
/*
* Translate from a speed_t to bits/second.
*/
int
baud_rate_of(speed)
int speed;
{
struct speed *speedp;
if (speed == 0)
return 0;
for (speedp = speeds; speedp->speed_int; speedp++)
if (speed == speedp->speed_val)
return speedp->speed_int;
return 0;
}
#endif
/*
* set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
* at the requested speed, etc.
* at the requested speed, etc. If `local' is true, set CLOCAL
* regardless of whether the modem option was specified.
*/
set_up_tty(fd)
int fd;
set_up_tty(fd, local)
int fd, local;
{
#ifndef SGTTY
int speed;
@ -576,11 +610,16 @@ set_up_tty(fd)
if (!restore_term)
inittermios = tios;
#ifdef CRTSCTS
tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL | CRTSCTS);
tios.c_cflag |= CS8 | CREAD | HUPCL;
if (crtscts)
tios.c_cflag |= CRTSCTS;
if (!modem)
#else
tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
#endif /* CRTSCTS */
tios.c_cflag |= CS8 | CREAD | HUPCL;
if (local || !modem)
tios.c_cflag |= CLOCAL;
tios.c_iflag = IGNBRK | IGNPAR;
tios.c_oflag = 0;
@ -591,12 +630,15 @@ set_up_tty(fd)
if (speed) {
cfsetospeed(&tios, speed);
cfsetispeed(&tios, speed);
} else {
speed = cfgetospeed(&tios);
}
if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
syslog(LOG_ERR, "tcsetattr: %m");
die(1);
}
#else /* SGTTY */
int speed;
struct sgttyb sgttyb;
@ -616,15 +658,31 @@ set_up_tty(fd)
speed = translate_speed(inspeed);
if (speed)
sgttyb.sg_ispeed = speed;
else
speed = sgttyb.sg_ispeed;
if (ioctl(fd, TIOCSETP, &sgttyb) < 0) {
syslog(LOG_ERR, "ioctl(TIOCSETP): %m");
die(1);
}
#endif
baud_rate = baud_rate_of(speed);
restore_term = TRUE;
}
/*
* setdtr - control the DTR line on the serial port.
* This is called from die(), so it shouldn't call die().
*/
setdtr(fd, on)
int fd, on;
{
int modembits = TIOCM_DTR;
ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
}
/*
* quit - Clean up state and exit.
@ -656,23 +714,23 @@ cleanup(status, arg)
int status;
caddr_t arg;
{
if (fd != 0) {
if (fd >= 0) {
/* drop dtr to hang up */
if (modem)
setdtr(fd, FALSE);
if (fcntl(fd, F_SETFL, initfdflags) < 0)
syslog(LOG_ERR, "fcntl(F_SETFL, fdflags): %m");
syslog(LOG_WARNING, "fcntl(F_SETFL, fdflags): %m");
disestablish_ppp();
if (restore_term) {
#ifndef SGTTY
if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
syslog(LOG_ERR, "tcsetattr: %m");
syslog(LOG_WARNING, "tcsetattr: %m");
#else
if (ioctl(fd, TIOCSETP, &initsgttyb) < 0)
syslog(LOG_ERR, "ioctl(TIOCSETP): %m");
syslog(LOG_WARNING, "ioctl(TIOCSETP): %m");
#endif
}
@ -683,6 +741,9 @@ cleanup(status, arg)
if (pidfilename[0] != 0 && unlink(pidfilename) < 0)
syslog(LOG_WARNING, "unable to unlink pid file: %m");
pidfilename[0] = 0;
if (lockflag && !default_device)
unlock();
}
@ -739,7 +800,7 @@ timeout(func, arg, time)
itv.it_interval.tv_sec = itv.it_interval.tv_usec =
itv.it_value.tv_usec = 0;
itv.it_value.tv_sec = callout->c_time;
MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds.",
MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds in timeout.",
itv.it_value.tv_sec));
if (setitimer(ITIMER_REAL, &itv, NULL)) {
syslog(LOG_ERR, "setitimer(ITIMER_REAL): %m");
@ -795,7 +856,7 @@ untimeout(func, arg)
itv.it_interval.tv_sec = itv.it_interval.tv_usec =
itv.it_value.tv_usec = 0;
itv.it_value.tv_sec = callout ? callout->c_time : 0;
MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds.",
MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds in untimeout.",
itv.it_value.tv_sec));
if (setitimer(ITIMER_REAL, &itv, NULL)) {
syslog(LOG_ERR, "setitimer(ITIMER_REAL): %m");
@ -912,22 +973,22 @@ alrm(sig, code, scp, addr)
char *addr;
{
struct itimerval itv;
struct callout *freep;
struct callout *freep, *list, *last;
MAINDEBUG((LOG_DEBUG, "Alarm"));
if (callout == NULL)
return;
/*
* Call and free first scheduled timeout and any that were scheduled
* for the same time.
* Get the first scheduled timeout and any that were scheduled
* for the same time as a list, and remove them all from callout
* list.
*/
while (callout) {
freep = callout; /* Remove entry before calling */
callout = freep->c_next;
(*freep->c_func)(freep->c_arg);
(void) free((char *) freep);
if (callout && callout->c_time)
break;
}
list = last = callout;
while (last->c_next != NULL && last->c_next->c_time == 0)
last = last->c_next;
callout = last->c_next;
last->c_next = NULL;
/*
* Set a new itimer if there are more timeouts scheduled.
@ -936,7 +997,7 @@ alrm(sig, code, scp, addr)
itv.it_interval.tv_sec = itv.it_interval.tv_usec = 0;
itv.it_value.tv_usec = 0;
itv.it_value.tv_sec = callout->c_time;
MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds.",
MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds in alrm.",
itv.it_value.tv_sec));
if (setitimer(ITIMER_REAL, &itv, NULL)) {
syslog(LOG_ERR, "setitimer(ITIMER_REAL): %m");
@ -947,6 +1008,17 @@ alrm(sig, code, scp, addr)
die(1);
}
}
/*
* Now call all the timeout routines scheduled for this time.
*/
while (list) {
(*list->c_func)(list->c_arg);
freep = list;
list = list->c_next;
(void) free((char *) freep);
}
}
@ -1000,10 +1072,13 @@ io(sig, code, scp, addr)
return;
if (len == 0) {
syslog(LOG_ERR, "End of file on fd!");
syslog(LOG_WARNING, "End of file on fd!");
die(1);
}
if (debug /*&& (debugflags & DBG_INPACKET)*/)
log_packet(p, len, "rcvd ");
if (len < DLLHEADERLEN) {
MAINDEBUG((LOG_INFO, "io(): Received short packet."));
return;
@ -1019,8 +1094,6 @@ io(sig, code, scp, addr)
if (protocol != LCP && lcp_fsm[0].state != OPENED) {
MAINDEBUG((LOG_INFO,
"io(): Received non-LCP packet when LCP not open."));
if (debug)
dumpbuffer(inpacket_buf, len + DLLHEADERLEN, LOG_INFO);
return;
}
@ -1098,10 +1171,11 @@ nodebug(sig)
/*
* set_up_connection - run a program to initialize the serial connector
* device_script - run a program to connect or disconnect the
* serial device.
*/
int
set_up_connection(program, in, out)
device_script(program, in, out)
char *program;
int in, out;
{
@ -1133,10 +1207,10 @@ set_up_connection(program, in, out)
/* NOTREACHED */
}
while (waitpid(pid, &status, 0) != pid) {
while (waitpid(pid, &status, 0) < 0) {
if (errno == EINTR)
continue;
syslog(LOG_ERR, "waiting for connection process: %m");
syslog(LOG_ERR, "waiting for (dis)connection process: %m");
die(1);
}
sigprocmask(SIG_SETMASK, &mask, NULL);
@ -1146,82 +1220,154 @@ set_up_connection(program, in, out)
/*
* Return user specified netmask. A value of zero means no netmask has
* been set.
* run-program - execute a program with given arguments,
* but don't wait for it.
* If the program can't be executed, logs an error unless
* must_exist is 0 and the program file doesn't exist.
*/
/* ARGSUSED */
u_long
GetMask(addr)
u_long addr;
int
run_program(prog, args, must_exist)
char *prog;
char **args;
int must_exist;
{
return(netmask);
int pid;
pid = fork();
if (pid == -1) {
syslog(LOG_ERR, "can't fork to run %s: %m", prog);
return -1;
}
if (pid == 0) {
execv(prog, args);
if (must_exist || errno != ENOENT)
syslog(LOG_WARNING, "can't execute %s: %m", prog);
_exit(-1);
}
MAINDEBUG((LOG_DEBUG, "Script %s started; pid = %d", prog, pid));
++n_children;
return 0;
}
/*
* dumpbuffer - print contents of a buffer in hex to standard output.
* reap_kids - get status from any dead child processes,
* and log a message for abnormal terminations.
*/
void
dumpbuffer(buffer, size, level)
unsigned char *buffer;
int size;
int level;
reap_kids()
{
register int i;
char line[256], *p;
int pid, status;
printf("%d bytes:\n", size);
while (size > 0)
{
p = line;
sprintf(p, "%08lx: ", buffer);
p += 10;
for (i = 0; i < 8; i++, p += 3)
if (size - i <= 0)
sprintf(p, "xx ");
else
sprintf(p, "%02x ", buffer[i]);
for (i = 0; i < 8; i++)
if (size - i <= 0)
*p++ = 'x';
else
*p++ = (' ' <= buffer[i] && buffer[i] <= '~') ?
buffer[i] : '.';
*p++ = 0;
buffer += 8;
size -= 8;
/* syslog(level, "%s\n", line); */
printf("%s\n", line);
fflush(stdout);
if (n_children == 0)
return;
if ((pid = waitpid(-1, &status, WNOHANG)) == -1) {
if (errno != ECHILD)
syslog(LOG_ERR, "waitpid: %m");
return;
}
if (pid > 0) {
--n_children;
if (WIFSIGNALED(status)) {
syslog(LOG_WARNING, "child process %d terminated with signal %d",
pid, WTERMSIG(status));
}
}
}
/*
* setdtr - control the DTR line on the serial port.
* This is called from die(), so it shouldn't call die().
* log_packet - format a packet and log it.
*/
setdtr(fd, on)
int fd, on;
{
int modembits = TIOCM_DTR;
ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
char line[256]; /* line to be logged accumulated here */
char *linep;
void
log_packet(p, len, prefix)
u_char *p;
int len;
char *prefix;
{
strcpy(line, prefix);
linep = line + strlen(line);
format_packet(p, len, pr_log, NULL);
if (linep != line)
syslog(LOG_DEBUG, "%s", line);
}
/*
* format_packet - make a readable representation of a packet,
* calling `printer(arg, format, ...)' to output it.
*/
void
format_packet(p, len, printer, arg)
u_char *p;
int len;
void (*printer) __ARGS((void *, char *, ...));
void *arg;
{
int i, n;
u_short proto;
u_char x;
if (len >= DLLHEADERLEN && p[0] == ALLSTATIONS && p[1] == UI) {
p += 2;
GETSHORT(proto, p);
len -= DLLHEADERLEN;
for (i = 0; i < N_PROTO; ++i)
if (proto == prottbl[i].protocol)
break;
if (i < N_PROTO) {
printer(arg, "[%s", prottbl[i].name);
n = (*prottbl[i].printpkt)(p, len, printer, arg);
printer(arg, "]");
p += n;
len -= n;
} else {
printer(arg, "[proto=0x%x]", proto);
}
}
for (; len > 0; --len) {
GETCHAR(x, p);
printer(arg, " %.2x", x);
}
}
#ifdef __STDC__
#include <stdarg.h>
void
pr_log(void *arg, char *fmt, ...)
{
int n;
va_list pvar;
char buf[256];
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>
char line[256];
char *p;
logf(level, fmt, va_alist)
int level;
void
pr_log(arg, fmt, va_alist)
void *arg;
char *fmt;
va_dcl
{
int n;
va_list pvar;
char buf[256];
@ -1229,15 +1375,43 @@ va_dcl
vsprintf(buf, fmt, pvar);
va_end(pvar);
p = line + strlen(line);
strcat(p, buf);
if (buf[strlen(buf)-1] == '\n') {
syslog(level, "%s", line);
line[0] = 0;
n = strlen(buf);
if (linep + n + 1 > line + sizeof(line)) {
syslog(LOG_DEBUG, "%s", line);
linep = line;
}
strcpy(linep, buf);
linep += n;
}
#endif
/*
* print_string - print a readable representation of a string using
* printer.
*/
void
print_string(p, len, printer, arg)
char *p;
int len;
void (*printer) __ARGS((void *, char *, ...));
void *arg;
{
int c;
printer(arg, "\"");
for (; len > 0; --len) {
c = *p++;
if (' ' <= c && c <= '~')
printer(arg, "%c", c);
else
printer(arg, "\\%.3o", c);
}
printer(arg, "\"");
}
/*
* novm - log an error message saying we ran out of memory, and die.
*/
void
novm(msg)
char *msg;

View File

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: options.c,v 1.5 1994/02/22 00:12:01 paulus Exp $";
static char rcsid[] = "$Id: options.c,v 1.6 1994/05/08 12:16:26 paulus Exp $";
#endif
#include <stdio.h>
@ -45,11 +45,11 @@ static char rcsid[] = "$Id: options.c,v 1.5 1994/02/22 00:12:01 paulus Exp $";
#define FALSE 0
#define TRUE 1
/*
* Prototypes
*/
static int setdebug __ARGS((void));
static int setkdebug __ARGS((char **));
static int setpassive __ARGS((void));
static int setsilent __ARGS((void));
static int noopt __ARGS((void));
@ -65,16 +65,20 @@ static int noasyncmap __ARGS((void));
static int noipaddr __ARGS((void));
static int nomagicnumber __ARGS((void));
static int setasyncmap __ARGS((char **));
static int setescape __ARGS((char **));
static int setmru __ARGS((char **));
static int setmtu __ARGS((char **));
static int nomru __ARGS((void));
static int nopcomp __ARGS((void));
static int setconnector __ARGS((char **));
static int setdisconnector __ARGS((char **));
static int setdomain __ARGS((char **));
static int setnetmask __ARGS((char **));
static int setcrtscts __ARGS((void));
static int setnodetach __ARGS((void));
static int setmodem __ARGS((void));
static int setlocal __ARGS((void));
static int setlock __ARGS((void));
static int setname __ARGS((char **));
static int setuser __ARGS((char **));
static int setremote __ARGS((char **));
@ -110,10 +114,13 @@ static int number_option __ARGS((char *, long *, int));
*/
extern char *progname;
extern int debug;
extern int kdebugflag;
extern int modem;
extern int lockflag;
extern int crtscts;
extern int nodetach;
extern char *connector;
extern char *disconnector;
extern int inspeed;
extern char devname[];
extern int default_device;
@ -156,16 +163,21 @@ static struct cmd {
"-chap", 0, nochap, /* Don't allow CHAP authentication with peer */
"-vj", 0, setnovj, /* disable VJ compression */
"asyncmap", 1, setasyncmap, /* set the desired async map */
"escape", 1, setescape, /* set chars to escape on transmission */
"connect", 1, setconnector, /* A program to set up a connection */
"disconnect", 1, setdisconnector, /* program to disconnect serial dev. */
"crtscts", 0, setcrtscts, /* set h/w flow control */
"debug", 0, setdebug, /* Increase debugging level */
"kdebug", 1, setkdebug, /* Enable kernel-level debugging */
"domain", 1, setdomain, /* Add given domain name to hostname*/
"mru", 1, setmru, /* Set MRU value for negotiation */
"mtu", 1, setmtu, /* Set our MTU */
"netmask", 1, setnetmask, /* set netmask */
"passive", 0, setpassive, /* Set passive mode */
"silent", 0, setsilent, /* Set silent mode */
"modem", 0, setmodem, /* Use modem control lines */
"local", 0, setlocal, /* Don't use modem control lines */
"lock", 0, setlock, /* Lock serial device (with lock file) */
"name", 1, setname, /* Set local name for authentication */
"user", 1, setuser, /* Set username for PAP auth with peer */
"usehostname", 0, setusehostname, /* Must use hostname for auth. */
@ -215,34 +227,6 @@ Usage: %s [ arguments ], where arguments are:\n\
See pppd(8) for more options.\n\
";
/*
Options omitted:
-all Don't request/allow any options\n\
-ac Disable Address/Control compression\n\
-am Disable asyncmap negotiation\n\
-as <n> Set the desired async map to hex <n>\n\
-d Increase debugging level\n\
-detach Don't fork to background\n\
-ip Disable IP address negotiation\n\
-mn Disable magic number negotiation\n\
-mru Disable mru negotiation\n\
-p Set passive mode\n\
-pc Disable protocol field compression\n\
+ua <f> Get username and password for authenticating\n\
with peer using PAP from file <f>\n\
+pap Require PAP authentication from peer\n\
-pap Don't agree to authenticating with peer using PAP\n\
+chap Require CHAP authentication from peer\n\
-chap Don't agree to authenticating with peer using CHAP\n\
-vj disable VJ compression\n\
-auth Don't agree to authenticate with peer\n\
debug Increase debugging level\n\
domain <d> Append domain name <d> to hostname for authentication\n\
passive Set passive mode\n\
local Don't use modem control lines\n\
proxyarp Add proxy ARP entry\n\
*/
/*
* parse_args - parse a string of arguments, from the command
@ -319,7 +303,7 @@ options_from_file(filename, must_exist)
if (!must_exist && errno == ENOENT)
return 1;
perror(filename);
exit(1);
return 0;
}
while (getword(f, cmd, &newline, filename)) {
/*
@ -549,10 +533,19 @@ static int
setdebug()
{
debug++;
setlogmask(LOG_UPTO(LOG_DEBUG));
return (1);
}
/*
* setkdebug - Set kernel debugging level.
*/
static int
setkdebug(argv)
char **argv;
{
return int_option(*argv, &kdebugflag);
}
/*
* noopt - Disable all options.
*/
@ -643,6 +636,27 @@ setmru(argv)
}
/*
* setmru - Set the largest MTU we'll use.
*/
static int
setmtu(argv)
char **argv;
{
long mtu;
if (!number_option(*argv, &mtu, 0))
return 0;
if (mtu < MINMRU || mtu > MAXMRU) {
fprintf(stderr, "mtu option value of %d is too %s\n", mtu,
(mtu < MINMRU? "small": "large"));
return 0;
}
lcp_allowoptions[0].mru = mtu;
return (1);
}
/*
* nopcomp - Disable Protocol field compression negotiation.
*/
@ -716,7 +730,7 @@ setupapfile(argv)
/* open user info file */
if ((ufile = fopen(*argv, "r")) == NULL) {
fprintf(stderr, "unable to open user login data file %s\n", *argv);
exit(1);
return 0;
}
check_access(ufile, *argv);
@ -724,7 +738,7 @@ setupapfile(argv)
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);
exit(2);
return 0;
}
fclose(ufile);
@ -788,6 +802,20 @@ setconnector(argv)
return (1);
}
/*
* setdisconnector - Set a program to disconnect from the serial line
*/
static int
setdisconnector(argv)
char **argv;
{
disconnector = strdup(*argv);
if (disconnector == NULL)
novm("disconnector string");
return (1);
}
/*
* setdomain - Set domain name to append to hostname
@ -801,6 +829,10 @@ setdomain(argv)
return (1);
}
/*
* setasyncmap - add bits to asyncmap (what we request peer to escape).
*/
static int
setasyncmap(argv)
char **argv;
@ -814,6 +846,38 @@ setasyncmap(argv)
return(1);
}
/*
* setescape - add chars to the set we escape on transmission.
*/
static int
setescape(argv)
char **argv;
{
int n, ret;
char *p, *endp;
p = *argv;
ret = 1;
while (*p) {
n = strtol(p, &endp, 16);
if (p == endp) {
fprintf(stderr, "%s: invalid hex number: %s\n", progname, 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", n);
ret = 0;
} else
xmit_accm[0][n >> 5] |= 1 << (n & 0x1F);
while (*p == ',' || *p == ' ')
++p;
}
return ret;
}
/*
* setspeed - Set the speed.
*/
@ -857,7 +921,7 @@ setdevname(cp)
if (errno == ENOENT)
return (0);
syslog(LOG_ERR, cp);
exit(1);
return 0;
}
(void) strncpy(devname, cp, MAXPATHLEN);
@ -1006,13 +1070,26 @@ setnetmask(argv)
if ((mask = inet_addr(*argv)) == -1) {
fprintf(stderr, "Invalid netmask %s\n", *argv);
exit(1);
return 0;
}
netmask = mask;
return (1);
}
/*
* Return user specified netmask. A value of zero means no netmask has
* been set.
*/
/* ARGSUSED */
u_long
GetMask(addr)
u_long addr;
{
return(netmask);
}
static int
setcrtscts()
{
@ -1041,6 +1118,13 @@ setlocal()
return 1;
}
static int
setlock()
{
lockflag = 1;
return 1;
}
static int
setusehostname()
{

View File

@ -1,5 +1,5 @@
/* $Id: patchlevel.h,v 1.6 1994/02/22 00:12:03 paulus Exp $ */
#define PATCHLEVEL 4
/* $Id: patchlevel.h,v 1.7 1994/05/08 12:16:27 paulus Exp $ */
#define PATCHLEVEL 0
#define VERSION "2.0"
#define DATE "9 Feb 94"
#define VERSION "2.1"
#define DATE "1 May 94"

View File

@ -1,10 +1,10 @@
/*
* define path names
*
* $Id: pathnames.h,v 1.4 1993/11/10 01:34:26 paulus Exp $
* $Id: pathnames.h,v 1.5 1994/05/08 12:16:28 paulus Exp $
*/
#ifdef STREAMS
#if defined(STREAMS) || defined(ultrix)
#define _PATH_PIDFILE "/etc/ppp"
#else
#define _PATH_PIDFILE "/var/run"
@ -13,3 +13,5 @@
#define _PATH_UPAPFILE "/etc/ppp/pap-secrets"
#define _PATH_CHAPFILE "/etc/ppp/chap-secrets"
#define _PATH_SYSOPTIONS "/etc/ppp/options"
#define _PATH_IPUP "/etc/ppp/ip-up"
#define _PATH_IPDOWN "/etc/ppp/ip-down"

View File

@ -1,5 +1,5 @@
.\" manual page [] for pppd 2.0
.\" $Id: pppd.8,v 1.5 1994/02/22 00:12:04 paulus Exp $
.\" $Id: pppd.8,v 1.6 1994/05/08 12:16:29 paulus Exp $
.\" SH section heading
.\" SS subsection heading
.\" LP paragraph
@ -50,20 +50,23 @@ Set the async character map to <map>.
This map describes which control characters cannot be successfully
received over the serial line.
.I pppd
will ask the peer to send these characters as a 2-byte "escape" sequence.
will ask the peer to send these characters as a 2-byte escape sequence.
The argument is a 32 bit hex number
with each bit representing a character to escape.
Bit 0 (00000001) represents the character 0x00;
bit 31 (80000000) represents the character 0x1f or ^_.
The default asyncmap is 0. If multiple \fBasyncmap\fR options are
If multiple \fBasyncmap\fR options are
given, the values are ORed together.
If no \fBasyncmap\fR option is given, no async character map will be
negotiated for the receive direction; the peer will then escape
\fIall\fR control characters.
.TP
.B auth
Require the peer to authenticate itself before allowing network
packets to be sent or received.
.TP
.B connect \fI<p>
Use the executable or shell command specified by <p> to set up the
Use the executable or shell command specified by \fI<p>\fR to set up the
serial line. This script would typically use the "chat" program to
dial the modem and start the remote ppp session.
.TP
@ -76,9 +79,28 @@ Add a default route to the system routing tables, using the peer as
the gateway, when IPCP negotiation is successfully completed.
This entry is removed when the PPP connection is broken.
.TP
.B disconnect \fI<p>
Run the executable or shell command specified by \fI<p>\fR after
\fIpppd\fR has terminated the link. This script could, for example,
issue commands to the modem to cause it to hang up.
.TP
.B escape \fIxx,yy,...
Specifies that certain characters should be escaped on transmission
(regardless of whether the peer requests them to be escaped with its
async control character map). The characters to be escaped are
specified as a list of hex numbers separated by commas. Note that
almost any character can be specified for the \fBescape\fR option,
unlike the \fBasyncmap\fR option which only allows control characters
to be specified. The characters which may not be escaped are those
with hex values 0x20 - 0x3f or 0x5e.
.TP
.B file \fI<f>
Read options from file <f> (the format is described below).
.TP
.B lock
Specifies that \fIpppd\fR should use a UUCP-style lock on the serial
device to ensure exclusive access to the device.
.TP
.B mru \fI<n>
Set the MRU [Maximum Receive Unit] value to <n> for negotiation.
.I pppd
@ -132,17 +154,18 @@ default values).
.TP
.B -ac
Disable Address/Control compression negotiation (use default, i.e.
disabled).
address/control field disabled).
.TP
.B -am
Disable asyncmap negotiation (use default, i.e. 0xffffffff).
Disable asyncmap negotiation (use the default asyncmap, i.e. escape
all control characters).
.TP
.B -as \fI<n>
Same as
.B asyncmap \fI<n>
.TP
.B -d
Increase debugging level.
Increase debugging level (same as the \fBdebug\fR option).
.TP
.B -detach
Don't fork to become a background process (otherwise
@ -168,7 +191,8 @@ Same as the
option.
.TP
.B -pc
Disable protocol field compression negotiation (use default, i.e. disabled).
Disable protocol field compression negotiation (use default, i.e.
protocol field compression disabled).
.TP
.B +ua \fI<p>
Agree to authenticate using PAP [Password Authentication Protocol] if
@ -196,9 +220,13 @@ Disable negotiation of Van Jacobson style IP header compression (use
default, i.e. no compression).
.TP
.B debug
Increase debugging level (same as
.B -d
).
Increase debugging level (same as \fB\-d\fR).
If this
option is given, \fIpppd\fR will log the contents of all control
packets sent or received in a readable form. The packets are logged
through syslog with facility \fIdaemon\fR and level \fIdebug\fR. This
information can be directed to a file by setting up /etc/syslog.conf
appropriately (see syslog.conf(5)).
.TP
.B domain \fI<d>
Append the domain name <d> to the local host name for authentication
@ -209,9 +237,22 @@ domain option to set the domain name to Quotron.COM.
.B modem
Use the modem control lines. (This option is not fully implemented.)
.TP
.B kdebug \fIn
Enable debugging code in the kernel-level PPP driver. The argument
\fIn\fR is a number which is the sum of the following values: 1 to
enable general debug messages, 2 to request that the contents of
received packets be printed, and 4 to request that the contents of
transmitted packets be printed.
.TP
.B local
Don't use the modem control lines.
.TP
.B mtu \fI<n>
Set the MTU [Maximum Transmit Unit] value to \fI<n>\fR. Unless the
peer requests a smaller value via MRU negotiation, \fIpppd\fR will
request that the kernel networking code send data packets of no more
than \fIn\fR bytes through the PPP network interface.
.TP
.B name \fI<n>
Set the name of the local system for authentication purposes to <n>.
.TP
@ -429,6 +470,16 @@ other Network Control Protocol) can be started. If authentication
fails, \fIpppd\fR will terminated the link (by closing LCP). If IPCP
negotiates an unacceptable IP address for the remote host, IPCP will
be closed. IP packets can only be sent or received when IPCP is open.
.LP
In some cases it is desirable to allow some hosts which can't
authenticate themselves to connect and use one of a restricted set of
IP addresses, even when the local host generally requires
authentication. If the peer refuses to authenticate itself when
requested, \fIpppd\fR takes that as equivalent to authenticating with
PAP using the empty string for the username and password. Thus, by
adding a line to the pap-secrets file which specifies the empty string
for the client and password, it is possible to allow restricted access
to hosts which refuse to authenticate themselves.
.SH ROUTING
.LP
When IPCP negotiation is completed successfully,
@ -483,29 +534,34 @@ for example:
pppd /dev/ttya 38400 connect 'chat "" "" "login:" "username"
"Password:" "password" "% " "exec pppd passive"'
.LP
(Note however that running chat like this will leave the password
visible in the parameter list of pppd and chat.)
.LP
If your serial connection is any more complicated than a piece of
wire, you may need to arrange for some control characters to be
escaped. In particular, it is often useful to escape XON (^Q) and
XOFF (^S), using \fBasyncmap a0000\fR. If the path includes a telnet,
you probably should escape ^] as well (\fBasyncmap 200a0000\fR).
Don't use an rlogin in the path - many implementations are not
If the path includes an rlogin, you will need to use the \fBescape
ff\fR option on the end which is running the rlogin client, since many
rlogin implementations are not
transparent; they will remove the sequence [0xff, 0xff, 0x73, 0x73,
followed by any 8 bytes] from the stream.
.SH DIAGNOSTICS
.LP
Messages are sent to the syslog daemon using facility
LOG_DAEMON unless
.I pppd
has been compiled with debugging code. In this case the logging
facility used will be LOG_LOCAL2 in order to allow separation of the debug
output from the other daemons using the LOG_DAEMON facility. You can
override this by defining the macro LOG_PPP to the desired facility
and recompiling. In order to see the error and debug messages, you
will need to edit your /etc/syslog.conf file to direct the messages to
the desired output device or file.
Messages are sent to the syslog daemon using facility LOG_DAEMON.
(This can be overriden by recompiling \fIpppd\fR with the macro
LOG_PPP defined as the desired facility.) In order to see the error
and debug messages, you will need to edit your /etc/syslog.conf file
to direct the messages to the desired output device or file.
.LP
If enabled at compile time, debugging printout can be enabled by
setting the -d or debug flag on the command line, or by sending a
The \fBdebug\fR option causes the contents of all control packets sent
or received to be logged, that is, all LCP, PAP, CHAP or IPCP packets.
This can be useful if the PPP negotiation does not succeed.
If debugging is enabled at compile time, the \fBdebug\fR option also
causes other debugging messages to be logged.
.LP
Debugging can also be enabled by sending a
SIGUSR1 to the
.I pppd
process.
@ -542,12 +598,6 @@ Rivest, R.
.I The MD5 Message-Digest Algorithm.
1992 April.
.TP
.B RFC1331
Simpson, W.A.
.I Point\-to\-Point Protocol (PPP) for the transmission of multi\-protocol
.I datagrams over point\-to\-point links.
1992 May.
.TP
.B RFC1332
McGregor, G.
.I PPP Internet Protocol Control Protocol (IPCP).
@ -557,6 +607,16 @@ McGregor, G.
Lloyd, B.; Simpson, W.A.
.I PPP authentication protocols.
1992 October.
.TP
.B RFC1548
Simpson, W.A.
.I The Point\-to\-Point Protocol (PPP).
1993 December.
.TP
.B RFC1549
Simpson, W.A.
.I PPP in HDLC Framing.
1993 December
.SH NOTES
The following signals have the specified effect when sent to the
.I pppd

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: pppd.h,v 1.4 1993/11/10 01:34:32 paulus Exp $
* $Id: pppd.h,v 1.5 1994/05/08 12:16:30 paulus Exp $
*/
/*
@ -39,6 +39,9 @@
#define MAXNAMELEN 256 /* max length of hostname or name for auth */
#define MAXSECRETLEN 256 /* max length of password or secret */
/*
* Global variables.
*/
extern int debug; /* Debug flag */
extern int ifunit; /* Interface unit number */
extern char ifname[]; /* Interface name */
@ -46,7 +49,20 @@ extern int fd; /* Device file descriptor */
extern int s; /* socket descriptor */
extern char hostname[]; /* hostname */
extern u_char outpacket_buf[]; /* buffer for outgoing packets */
extern int phase; /* See values below */
/*
* Values for phase.
*/
#define PHASE_DEAD 0
#define PHASE_ESTABLISH 1
#define PHASE_AUTHENTICATE 2
#define PHASE_NETWORK 3
#define PHASE_TERMINATE 4
/*
* Prototypes.
*/
void quit __ARGS((void)); /* Cleanup and exit */
void timeout __ARGS((void (*)(), caddr_t, int));
/* Look-alike of kernel's timeout() */

View File

@ -1,8 +1,8 @@
# $Id: Makefile,v 1.5 1993/11/10 01:33:51 paulus Exp $
# $Id: Makefile,v 1.6 1994/05/08 12:16:10 paulus Exp $
PROG= pppd
SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c \
auth.c options.c sys-bsd.c
auth.c options.c lock.c sys-bsd.c
MAN8= pppd.0
SUBDIR= pppstats chat
BINMODE=4555

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: auth.c,v 1.4 1994/01/25 05:58:02 paulus Exp $";
static char rcsid[] = "$Id: auth.c,v 1.5 1994/05/08 12:16:13 paulus Exp $";
#endif
#include <stdio.h>
@ -106,6 +106,7 @@ void check_access __ARGS((FILE *, char *));
static int login __ARGS((char *, char *, char **, int *));
static void logout __ARGS((void));
static int null_login __ARGS((int));
static int get_upap_passwd __ARGS((void));
static int have_upap_secret __ARGS((void));
static int have_chap_secret __ARGS((char *, char *));
@ -135,11 +136,18 @@ link_terminated(unit)
{
if (logged_in)
logout();
if (lcp_wantoptions[unit].restart) {
lcp_lowerdown(unit);
lcp_lowerup(unit);
} else
EXIT(unit);
phase = PHASE_DEAD;
syslog(LOG_NOTICE, "Connection terminated.");
}
/*
* LCP has gone down; it will either die or try to re-establish.
*/
void
link_down(unit)
int unit;
{
phase = PHASE_TERMINATE;
}
/*
@ -157,14 +165,19 @@ link_established(unit)
if (auth_required && !(go->neg_chap || go->neg_upap)) {
/*
* We wanted the peer to authenticate himself, and he refused:
* tell him to go away.
* We wanted the peer to authenticate itself, and it refused:
* treat it as though it authenticated with PAP using a username
* of "" and a password of "". If that's not OK, boot it out.
*/
if (wo->neg_upap && !null_login(unit)) {
syslog(LOG_WARNING, "peer refused to authenticate");
lcp_close(unit);
phase = PHASE_TERMINATE;
return;
}
}
phase = PHASE_AUTHENTICATE;
auth = 0;
if (go->neg_chap) {
ChapAuthPeer(unit, our_name, go->chap_mdtype);
@ -182,9 +195,11 @@ link_established(unit)
}
auth_pending[unit] = auth;
if (!auth)
if (!auth) {
phase = PHASE_NETWORK;
ipcp_open(unit);
}
}
/*
* The peer has failed to authenticate himself using `protocol'.
@ -197,6 +212,7 @@ auth_peer_fail(unit, protocol)
* Authentication failure: take the link down
*/
lcp_close(unit);
phase = PHASE_TERMINATE;
}
/*
@ -225,9 +241,11 @@ auth_peer_success(unit, protocol)
* If there is no more authentication still to be done,
* proceed to the network phase.
*/
if ((auth_pending[unit] &= ~bit) == 0)
if ((auth_pending[unit] &= ~bit) == 0) {
phase = PHASE_NETWORK;
ipcp_open(unit);
}
}
/*
* We have failed to authenticate ourselves to the peer using `protocol'.
@ -268,9 +286,11 @@ auth_withpeer_success(unit, protocol)
* If there is no more authentication still being done,
* proceed to the network phase.
*/
if ((auth_pending[unit] &= ~bit) == 0)
if ((auth_pending[unit] &= ~bit) == 0) {
phase = PHASE_NETWORK;
ipcp_open(unit);
}
}
/*
@ -485,6 +505,46 @@ logout()
}
/*
* null_login - Check if a username of "" and a password of "" are
* acceptable, and iff so, set the list of acceptable IP addresses
* and return 1.
*/
static int
null_login(unit)
int unit;
{
char *filename;
FILE *f;
int i, ret;
struct wordlist *addrs;
char secret[MAXWORDLEN];
/*
* Open the file of upap secrets and scan for a suitable secret.
* We don't accept a wildcard client.
*/
filename = _PATH_UPAPFILE;
addrs = NULL;
f = fopen(filename, "r");
if (f == NULL)
return 0;
check_access(f, filename);
i = scan_authfile(f, "", our_name, secret, &addrs, filename);
ret = i >= 0 && (i & NONWILD_CLIENT) != 0 && secret[0] == 0;
if (ret) {
if (addresses[unit] != NULL)
free_wordlist(addresses[unit]);
addresses[unit] = addrs;
}
fclose(f);
return ret;
}
/*
* get_upap_passwd - get a password for authenticating ourselves with
* our peer using PAP. Returns 1 on success, 0 if no suitable password

View File

@ -19,7 +19,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: chap.c,v 1.3 1993/11/10 01:33:59 paulus Exp $";
static char rcsid[] = "$Id: chap.c,v 1.4 1994/05/08 12:16:15 paulus Exp $";
#endif
/*
@ -557,6 +557,8 @@ ChapReceiveSuccess(cstate, inp, id, len)
return;
}
UNTIMEOUT(ChapResponseTimeout, (caddr_t) cstate);
/*
* Print message.
*/
@ -591,6 +593,8 @@ ChapReceiveFailure(cstate, inp, id, len)
return;
}
UNTIMEOUT(ChapResponseTimeout, (caddr_t) cstate);
/*
* Print message.
*/
@ -738,6 +742,71 @@ ChapSendResponse(cstate)
++cstate->resp_transmits;
}
/*
* ChapPrintPkt - print the contents of a CHAP packet.
*/
char *ChapCodenames[] = {
"Challenge", "Response", "Success", "Failure"
};
int
ChapPrintPkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __ARGS((void *, char *, ...));
void *arg;
{
int code, id, len;
int clen, nlen;
u_char x;
if (plen < CHAP_HEADERLEN)
return 0;
GETCHAR(code, p);
GETCHAR(id, p);
GETSHORT(len, p);
if (len < CHAP_HEADERLEN || len > plen)
return 0;
if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *))
printer(arg, " %s", ChapCodenames[code-1]);
else
printer(arg, " code=0x%x", code);
printer(arg, " id=0x%x", id);
len -= CHAP_HEADERLEN;
switch (code) {
case CHAP_CHALLENGE:
case CHAP_RESPONSE:
if (len < 1)
break;
clen = p[0];
if (len < clen + 1)
break;
++p;
nlen = len - clen - 1;
printer(arg, " <");
for (; clen > 0; --clen) {
GETCHAR(x, p);
printer(arg, "%.2x", x);
}
printer(arg, ">, name = ");
print_string((char *)p, nlen, printer, arg);
break;
case CHAP_FAILURE:
case CHAP_SUCCESS:
printer(arg, " ");
print_string((char *)p, len, printer, arg);
break;
default:
for (clen = len; clen > 0; --clen) {
GETCHAR(x, p);
printer(arg, " %.2x", x);
}
}
return len + CHAP_HEADERLEN;
}
#ifdef NO_DRAND48
double drand48()

View File

@ -1,6 +1,5 @@
/*
* chap.h - Cryptographic Handshake Authentication Protocol definitions.
* based on November 1991 draft of PPP Authentication RFC
*
* Copyright (c) 1991 Gregory M. Christy
* All rights reserved.
@ -16,13 +15,13 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: chap.h,v 1.3 1993/11/10 01:34:02 paulus Exp $
* $Id: chap.h,v 1.4 1994/05/08 12:16:16 paulus Exp $
*/
#ifndef __CHAP_INCLUDE__
/* Code + ID + length */
#define CHAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
#define CHAP_HEADERLEN 4
/*
* CHAP codes.
@ -106,6 +105,8 @@ void ChapLowerUp __ARGS((int));
void ChapLowerDown __ARGS((int));
void ChapInput __ARGS((int, u_char *, int));
void ChapProtocolReject __ARGS((int));
int ChapPrintPkt __ARGS((u_char *, int,
void (*) __ARGS((void *, char *, ...)), void *));
#define __CHAP_INCLUDE__
#endif /* __CHAP_INCLUDE__ */

View File

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: fsm.c,v 1.3 1993/11/10 01:34:04 paulus Exp $";
static char rcsid[] = "$Id: fsm.c,v 1.4 1994/05/08 12:16:17 paulus Exp $";
#endif
/*
@ -29,7 +29,6 @@ static char rcsid[] = "$Id: fsm.c,v 1.3 1993/11/10 01:34:04 paulus Exp $";
#include <stdio.h>
#include <sys/types.h>
/*#include <malloc.h>*/
#include <syslog.h>
#include "ppp.h"
@ -453,6 +452,7 @@ fsm_rconfack(f, id, inp, len)
PROTO_NAME(f), len));
return;
}
f->reqid = -1;
switch (f->state) {
case CLOSED:
@ -514,6 +514,7 @@ fsm_rconfnakrej(f, code, id, inp, len)
PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
return;
}
f->reqid = -1;
switch (f->state) {
case CLOSED:
@ -556,7 +557,6 @@ fsm_rtermreq(f, id)
FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d.",
PROTO_NAME(f), id));
fsm_sdata(f, TERMACK, id, NULL, 0);
switch (f->state) {
case ACKRCVD:
case ACKSENT:
@ -572,6 +572,8 @@ fsm_rtermreq(f, id)
TIMEOUT(fsm_timeout, (caddr_t) f, f->timeouttime);
break;
}
fsm_sdata(f, TERMACK, id, NULL, 0);
}

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: fsm.h,v 1.3 1993/11/10 01:34:07 paulus Exp $
* $Id: fsm.h,v 1.4 1994/05/08 12:16:18 paulus Exp $
*/
/*
@ -35,11 +35,6 @@
#define TERMREQ 5 /* Termination Request */
#define TERMACK 6 /* Termination Ack */
#define CODEREJ 7 /* Code Reject */
#define PROTREJ 8 /* Protocol Reject */
#define ECHOREQ 9 /* Echo Request */
#define ECHOREP 10 /* Echo Reply */
#define DISCREQ 11 /* Discard Request */
#define KEEPALIVE 12 /* Keepalive */
/*

View File

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: ipcp.c,v 1.4 1994/02/22 00:11:57 paulus Exp $";
static char rcsid[] = "$Id: ipcp.c,v 1.5 1994/05/08 12:16:19 paulus Exp $";
#endif
/*
@ -43,7 +43,7 @@ static char rcsid[] = "$Id: ipcp.c,v 1.4 1994/02/22 00:11:57 paulus Exp $";
#include "ppp.h"
#include "fsm.h"
#include "ipcp.h"
#include "pathnames.h"
/* global vars */
ipcp_options ipcp_wantoptions[NPPP]; /* Options that we want to request */
@ -51,6 +51,10 @@ ipcp_options ipcp_gotoptions[NPPP]; /* Options that peer ack'd */
ipcp_options ipcp_allowoptions[NPPP]; /* Options we allow peer to request */
ipcp_options ipcp_hisoptions[NPPP]; /* Options that we ack'd */
extern char ifname[];
extern char devname[];
extern int baud_rate;
/* local vars */
static int cis_received[NPPP]; /* # Conf-Reqs received */
@ -66,7 +70,7 @@ static int ipcp_rejci __ARGS((fsm *, u_char *, int)); /* Peer rej'd our CI */
static int ipcp_reqci __ARGS((fsm *, u_char *, int *, int)); /* Rcv CI */
static void ipcp_up __ARGS((fsm *)); /* We're UP */
static void ipcp_down __ARGS((fsm *)); /* We're DOWN */
static void ipcp_script __ARGS((fsm *, char *)); /* Run an up/down script */
fsm ipcp_fsm[NPPP]; /* IPCP fsm structure */
@ -885,6 +889,10 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
}
ho->maxslotindex = maxslotindex;
ho->cflag = wo->cflag;
} else {
ho->old_vj = 1;
ho->maxslotindex = MAX_STATES - 1;
ho->cflag = 1;
}
break;
@ -988,7 +996,7 @@ ipcp_up(f)
}
/*
* Check that the peer is allowed to use the IP address he wants.
* Check that the peer is allowed to use the IP address it wants.
*/
if (!auth_ip_addr(f->unit, ho->hisaddr)) {
syslog(LOG_ERR, "Peer is not authorized to use remote address %s",
@ -1011,7 +1019,7 @@ ipcp_up(f)
}
/* set tcp compression */
sifvjcomp(f->unit, ho->neg_vj, ho->cflag);
sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);
/* bring the interface up for IP */
if (!sifup(f->unit)) {
@ -1029,6 +1037,13 @@ ipcp_up(f)
if (ipcp_wantoptions[f->unit].proxy_arp)
if (sifproxyarp(f->unit, ho->hisaddr))
go->proxy_arp = 1;
/*
* Execute the ip-up script, like this:
* /etc/ppp/ip-up interface tty speed local-IP remote-IP
*/
ipcp_script(f, _PATH_IPUP);
}
@ -1054,4 +1069,138 @@ ipcp_down(f)
cifdefaultroute(f->unit, hisaddr);
sifdown(f->unit);
cifaddr(f->unit, ouraddr, hisaddr);
/* Execute the ip-down script */
ipcp_script(f, _PATH_IPDOWN);
}
/*
* ipcp_script - Execute a script with arguments
* interface-name tty-name speed local-IP remote-IP.
*/
static void
ipcp_script(f, script)
fsm *f;
char *script;
{
char strspeed[32], strlocal[32], strremote[32];
char *argv[8];
sprintf(strspeed, "%d", baud_rate);
strcpy(strlocal, ip_ntoa(ipcp_gotoptions[f->unit].ouraddr));
strcpy(strremote, ip_ntoa(ipcp_hisoptions[f->unit].hisaddr));
argv[0] = script;
argv[1] = ifname;
argv[2] = devname;
argv[3] = strspeed;
argv[4] = strlocal;
argv[5] = strremote;
argv[6] = NULL;
run_program(script, argv, 0);
}
/*
* ipcp_printpkt - print the contents of an IPCP packet.
*/
char *ipcp_codenames[] = {
"ConfReq", "ConfAck", "ConfNak", "ConfRej",
"TermReq", "TermAck", "CodeRej"
};
int
ipcp_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_long 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(ipcp_codenames) / sizeof(char *))
printer(arg, " %s", ipcp_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 < 2 || olen > len) {
break;
}
printer(arg, " <");
len -= olen;
optend = p + olen;
switch (code) {
case CI_ADDRS:
if (olen == CILEN_ADDRS) {
p += 2;
GETLONG(cilong, p);
printer(arg, "addrs %s", ip_ntoa(htonl(cilong)));
GETLONG(cilong, p);
printer(arg, " %s", ip_ntoa(htonl(cilong)));
}
break;
case CI_COMPRESSTYPE:
if (olen >= CILEN_COMPRESS) {
p += 2;
GETSHORT(cishort, p);
printer(arg, "compress ");
switch (cishort) {
case IPCP_VJ_COMP:
printer(arg, "VJ");
break;
case IPCP_VJ_COMP_OLD:
printer(arg, "old-VJ");
break;
default:
printer(arg, "0x%x", cishort);
}
}
break;
case CI_ADDR:
if (olen == CILEN_ADDR) {
p += 2;
GETLONG(cilong, p);
printer(arg, "addr %s", ip_ntoa(htonl(cilong)));
}
break;
}
while (p < optend) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
printer(arg, ">");
}
break;
}
/* print the rest of the bytes in the packet */
for (; len > 0; --len) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
return p - pstart;
}

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ipcp.h,v 1.4 1994/02/22 00:11:59 paulus Exp $
* $Id: ipcp.h,v 1.5 1994/05/08 12:16:20 paulus Exp $
*/
/*
@ -65,3 +65,4 @@ void ipcp_lowerup __ARGS((int));
void ipcp_lowerdown __ARGS((int));
void ipcp_input __ARGS((int, u_char *, int));
void ipcp_protrej __ARGS((int));
int ipcp_printpkt __ARGS((u_char *, int, void (*)(), void *));

View File

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: lcp.c,v 1.3 1993/11/10 01:34:15 paulus Exp $";
static char rcsid[] = "$Id: lcp.c,v 1.4 1994/05/08 12:16:22 paulus Exp $";
#endif
/*
@ -55,6 +55,7 @@ lcp_options lcp_wantoptions[NPPP]; /* Options that we want to request */
lcp_options lcp_gotoptions[NPPP]; /* Options that peer ack'd */
lcp_options lcp_allowoptions[NPPP]; /* Options we allow peer to request */
lcp_options lcp_hisoptions[NPPP]; /* Options that we ack'd */
u_long xmit_accm[NPPP][8]; /* extended transmit ACCM */
/*
* Callbacks for fsm code. (CI = Configuration Information)
@ -129,7 +130,7 @@ lcp_init(unit)
implementations */
wo->neg_mru = 1;
wo->mru = DEFMRU;
wo->neg_asyncmap = 1;
wo->neg_asyncmap = 0;
wo->asyncmap = 0;
wo->neg_chap = 0; /* Set to 1 on server */
wo->neg_upap = 0; /* Set to 1 on server */
@ -151,6 +152,8 @@ lcp_init(unit)
ao->neg_accompression = 1;
ao->neg_lqr = 0; /* no LQR implementation yet */
memset(xmit_accm[unit], 0, sizeof(xmit_accm[0]));
xmit_accm[unit][3] = 0x60000000;
}
@ -192,9 +195,11 @@ lcp_lowerup(unit)
int unit;
{
sifdown(unit);
ppp_set_xaccm(unit, xmit_accm[unit]);
ppp_send_config(unit, MTU, 0xffffffff, 0, 0);
ppp_recv_config(unit, MTU, 0, 0, 0);
peer_mru[unit] = MTU;
lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0];
fsm_lowerup(&lcp_fsm[unit]);
}
@ -1219,7 +1224,7 @@ lcp_up(f)
* set our MRU to the larger of value we wanted and
* the value we got in the negotiation.
*/
ppp_send_config(f->unit, (ho->neg_mru? MIN(ao->mru, ho->mru): MTU),
ppp_send_config(f->unit, MIN(ao->mru, (ho->neg_mru? ho->mru: MTU)),
(ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
ho->neg_pcompression, ho->neg_accompression);
ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): MTU),
@ -1254,7 +1259,8 @@ lcp_down(f)
ppp_send_config(f->unit, MTU, 0xffffffff, 0, 0);
ppp_recv_config(f->unit, MTU, 0, 0, 0);
peer_mru[f->unit] = MTU;
syslog(LOG_NOTICE, "Connection terminated.");
link_down(f->unit);
}
@ -1279,3 +1285,139 @@ lcp_finished(f)
link_terminated(f->unit);
}
/*
* lcp_printpkt - print the contents of an LCP packet.
*/
char *lcp_codenames[] = {
"ConfReq", "ConfAck", "ConfNak", "ConfRej",
"TermReq", "TermAck", "CodeRej", "ProtRej",
"EchoReq", "EchoRep", "DiscReq"
};
int
lcp_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __ARGS((void *, char *, ...));
void *arg;
{
int code, id, len, olen;
u_char *pstart, *optend;
u_short cishort;
u_long 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(lcp_codenames) / sizeof(char *))
printer(arg, " %s", lcp_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 < 2 || olen > len) {
break;
}
printer(arg, " <");
len -= olen;
optend = p + olen;
switch (code) {
case CI_MRU:
if (olen == CILEN_SHORT) {
p += 2;
GETSHORT(cishort, p);
printer(arg, "mru %d", cishort);
}
break;
case CI_ASYNCMAP:
if (olen == CILEN_LONG) {
p += 2;
GETLONG(cilong, p);
printer(arg, "asyncmap 0x%x", cilong);
}
break;
case CI_AUTHTYPE:
if (olen >= CILEN_SHORT) {
p += 2;
printer(arg, "auth ");
GETSHORT(cishort, p);
switch (cishort) {
case UPAP:
printer(arg, "upap");
break;
case CHAP:
printer(arg, "chap");
break;
default:
printer(arg, "0x%x", cishort);
}
}
break;
case CI_QUALITY:
if (olen >= CILEN_SHORT) {
p += 2;
printer(arg, "quality ");
GETSHORT(cishort, p);
switch (cishort) {
case LQR:
printer(arg, "lqr");
break;
default:
printer(arg, "0x%x", cishort);
}
}
break;
case CI_MAGICNUMBER:
if (olen == CILEN_LONG) {
p += 2;
GETLONG(cilong, p);
printer(arg, "magic 0x%x", cilong);
}
break;
case CI_PCOMPRESSION:
if (olen == CILEN_VOID) {
p += 2;
printer(arg, "pcomp");
}
break;
case CI_ACCOMPRESSION:
if (olen == CILEN_VOID) {
p += 2;
printer(arg, "accomp");
}
break;
}
while (p < optend) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
printer(arg, ">");
}
break;
}
/* print the rest of the bytes in the packet */
for (; len > 0; --len) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
return p - pstart;
}

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: lcp.h,v 1.3 1993/11/10 01:34:17 paulus Exp $
* $Id: lcp.h,v 1.4 1994/05/08 12:16:23 paulus Exp $
*/
/*
@ -27,10 +27,16 @@
#define CI_AUTHTYPE 3 /* Authentication Type */
#define CI_QUALITY 4 /* Quality Protocol */
#define CI_MAGICNUMBER 5 /* Magic Number */
#define CI_KEEPALIVE 6 /* Keep Alive Parameters - OBSOLETE */
#define CI_PCOMPRESSION 7 /* Protocol Field Compression */
#define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */
/*
* LCP-specific packet types.
*/
#define PROTREJ 8 /* Protocol Reject */
#define ECHOREQ 9 /* Echo Request */
#define ECHOREP 10 /* Echo Reply */
#define DISCREQ 11 /* Discard Request */
/*
* The state of options is described by an lcp_options structure.
@ -60,6 +66,7 @@ extern lcp_options lcp_wantoptions[];
extern lcp_options lcp_gotoptions[];
extern lcp_options lcp_allowoptions[];
extern lcp_options lcp_hisoptions[];
extern u_long xmit_accm[][8];
#define DEFMRU 1500 /* Try for this */
#define MINMRU 128 /* No MRUs below this */
@ -73,6 +80,8 @@ void lcp_lowerdown __ARGS((int));
void lcp_input __ARGS((int, u_char *, int));
void lcp_protrej __ARGS((int));
void lcp_sprotrej __ARGS((int, u_char *, int));
int lcp_printpkt __ARGS((u_char *, int,
void (*) __ARGS((void *, char *, ...)), void *));
extern int lcp_warnloops; /* Warn about a loopback this often */
#define DEFWARNLOOPS 10 /* Default value for above */

View File

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: main.c,v 1.8 1994/01/25 05:58:05 paulus Exp $";
static char rcsid[] = "$Id: main.c,v 1.9 1994/05/08 12:16:24 paulus Exp $";
#endif
#define SETSID
@ -30,6 +30,7 @@ static char rcsid[] = "$Id: main.c,v 1.8 1994/01/25 05:58:05 paulus Exp $";
#include <syslog.h>
#include <netdb.h>
#include <utmp.h>
#include <sys/wait.h>
/*
* If REQ_SYSOPTIONS is defined to 1, pppd will not run unless
@ -39,10 +40,6 @@ static char rcsid[] = "$Id: main.c,v 1.8 1994/01/25 05:58:05 paulus Exp $";
#define REQ_SYSOPTIONS 0
#endif
#ifdef STREAMS
#undef SGTTY
#endif
#ifdef SGTTY
#include <sgtty.h>
#else
@ -115,6 +112,8 @@ int default_device = TRUE; /* use default device (stdin/out) */
int fd; /* Device file descriptor */
int s; /* Socket file descriptor */
int phase; /* where the link is at */
#ifdef SGTTY
static struct sgttyb initsgttyb; /* Initial TTY sgttyb */
#else
@ -129,14 +128,18 @@ u_char outpacket_buf[MTU+DLLHEADERLEN]; /* buffer for outgoing packet */
static u_char inpacket_buf[MTU+DLLHEADERLEN]; /* buffer for incoming packet */
int hungup; /* terminal has been hung up */
static int n_children; /* # child processes still running */
/* configured variables */
int debug = 0; /* Debug flag */
int kdebugflag = 0; /* Kernel debugging flag */
char user[MAXNAMELEN]; /* username for PAP */
char passwd[MAXSECRETLEN]; /* password for PAP */
char *connector = NULL; /* "connect" command */
int inspeed = 0; /* Input/Output speed */
char *disconnector = NULL; /* "disconnect" command */
int inspeed = 0; /* Input/Output speed requested */
int baud_rate; /* bits/sec currently used */
u_long netmask = 0; /* netmask to use on ppp interface */
int crtscts = 0; /* use h/w flow control */
int nodetach = 0; /* don't fork */
@ -147,6 +150,7 @@ int proxyarp = 0; /* set entry in arp table */
int persist = 0; /* re-initiate on termination */
int answer = 0; /* wait for incoming call */
int uselogin = 0; /* check PAP info against /etc/passwd */
int lockflag = 0; /* lock the serial device */
/* prototypes */
@ -159,13 +163,16 @@ static void incdebug __ARGS((int));
static void nodebug __ARGS((int));
void establish_ppp __ARGS((void));
void reap_kids __ARGS((void));
void cleanup __ARGS((int, caddr_t));
void die __ARGS((int));
void dumpbuffer __ARGS((unsigned char *, int, int));
void novm __ARGS((char *));
void log_packet __ARGS((u_char *, int, char *));
void format_packet __ARGS((u_char *, int,
void (*) (void *, char *, ...), void *));
void pr_log __ARGS((void *, char *, ...));
#ifdef STREAMS
extern char *ttyname __ARGS((int));
#endif
extern char *getlogin __ARGS((void));
/*
@ -177,13 +184,16 @@ static struct protent {
void (*init)();
void (*input)();
void (*protrej)();
int (*printpkt)();
char *name;
} prottbl[] = {
{ LCP, lcp_init, lcp_input, lcp_protrej },
{ IPCP, ipcp_init, ipcp_input, ipcp_protrej },
{ UPAP, upap_init, upap_input, upap_protrej },
{ CHAP, ChapInit, ChapInput, ChapProtocolReject },
{ LCP, lcp_init, lcp_input, lcp_protrej, lcp_printpkt, "LCP" },
{ IPCP, ipcp_init, ipcp_input, ipcp_protrej, ipcp_printpkt, "IPCP" },
{ UPAP, upap_init, upap_input, upap_protrej, upap_printpkt, "PAP" },
{ CHAP, ChapInit, ChapInput, ChapProtocolReject, ChapPrintPkt, "CHAP" },
};
#define N_PROTO (sizeof(prottbl) / sizeof(prottbl[0]))
main(argc, argv)
int argc;
@ -195,28 +205,8 @@ main(argc, argv)
FILE *pidfile;
char *p;
/*
* Initialize syslog system and magic number package.
*/
#if BSD >= 43 || defined(sun)
openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
setlogmask(LOG_UPTO(LOG_INFO));
#else
openlog("pppd", LOG_PID);
#define LOG_UPTO(x) (x)
#define setlogmask(x) (x)
#endif
#ifdef STREAMS
p = ttyname(fileno(stdin));
if (p)
strcpy(devname, p);
#endif
magic_init();
if (gethostname(hostname, MAXNAMELEN) < 0 ) {
syslog(LOG_ERR, "couldn't get hostname: %m");
perror("couldn't get hostname");
die(1);
}
hostname[MAXNAMELEN-1] = 0;
@ -233,7 +223,7 @@ main(argc, argv)
* the system options file, the user's options file, and the command
* line arguments.
*/
for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++)
for (i = 0; i < N_PROTO; i++)
(*prottbl[i].init)(0);
progname = *argv;
@ -245,6 +235,20 @@ main(argc, argv)
check_auth_options();
setipdefault();
if (lockflag && !default_device)
if (lock(devname) < 0)
die(1);
/*
* Initialize syslog system and magic number package.
*/
openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
setlogmask(LOG_UPTO(LOG_INFO));
if (debug)
setlogmask(LOG_UPTO(LOG_DEBUG));
magic_init();
p = getlogin();
if (p == NULL)
p = "(unknown)";
@ -314,9 +318,6 @@ main(argc, argv)
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGALRM);
sigaddset(&mask, SIGIO);
#ifdef STREAMS
sigaddset(&mask, SIGPOLL);
#endif
#define SIGNAL(s, handler) { \
sv.sv_handler = handler; \
@ -333,9 +334,6 @@ main(argc, argv)
SIGNAL(SIGTERM, term); /* Terminate */
SIGNAL(SIGALRM, alrm); /* Timeout */
SIGNAL(SIGIO, io); /* Input available */
#ifdef STREAMS
SIGNAL(SIGPOLL, io); /* Input available */
#endif
signal(SIGUSR1, incdebug); /* Increment debug flag */
signal(SIGUSR2, nodebug); /* Reset debug flag */
@ -345,9 +343,6 @@ main(argc, argv)
*/
sigemptyset(&mask);
sigaddset(&mask, SIGIO);
#ifdef STREAMS
sigaddset(&mask, SIGPOLL);
#endif
sigprocmask(SIG_BLOCK, &mask, NULL);
/*
@ -359,18 +354,20 @@ main(argc, argv)
}
hungup = 0;
#ifdef TIOCSCTTY
/* set device to be controlling tty */
if (!default_device && ioctl(fd, TIOCSCTTY) < 0) {
syslog(LOG_ERR, "ioctl(TIOCSCTTY): %m");
die(1);
}
/* set line speed, flow control, etc. */
set_up_tty(fd);
#endif /* TIOCSCTTY */
/* run connection script */
if (connector) {
syslog(LOG_INFO, "Connecting with <%s>", connector);
MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector));
/* set line speed, flow control, etc.; set CLOCAL for now */
set_up_tty(fd, 1);
/* drop dtr to hang up in case modem is off hook */
if (!default_device && modem) {
@ -379,7 +376,7 @@ main(argc, argv)
setdtr(fd, TRUE);
}
if (set_up_connection(connector, fd, fd) < 0) {
if (device_script(connector, fd, fd) < 0) {
syslog(LOG_ERR, "could not set up connection");
setdtr(fd, FALSE);
die(1);
@ -389,6 +386,9 @@ main(argc, argv)
sleep(1); /* give it time to set up its terminal */
}
/* set line speed, flow control, etc.; clear CLOCAL if modem option */
set_up_tty(fd, 0);
/* set up the serial device as a ppp interface */
establish_ppp();
@ -450,9 +450,24 @@ main(argc, argv)
sigprocmask(SIG_BLOCK, &mask, NULL); /* Block signals now */
lcp_lowerup(0); /* XXX Well, sort of... */
lcp_open(0); /* Start protocol */
for (;;) {
for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) {
sigpause(0); /* Wait for next signal */
reap_kids(); /* Don't leave dead kids lying around */
}
/*
* Run disconnector script, if requested
*/
if (disconnector) {
if (device_script(disconnector, fd, fd) < 0) {
syslog(LOG_WARNING, "disconnect script failed");
die(1);
}
syslog(LOG_INFO, "Disconnected...");
}
quit();
}
#if B9600 == 9600
@ -461,6 +476,7 @@ main(argc, argv)
* (so we can ask for any speed).
*/
#define translate_speed(bps) (bps)
#define baud_rate_of(speed) (speed)
#else
/*
@ -555,14 +571,32 @@ translate_speed(bps)
syslog(LOG_WARNING, "speed %d not supported", bps);
return 0;
}
/*
* Translate from a speed_t to bits/second.
*/
int
baud_rate_of(speed)
int speed;
{
struct speed *speedp;
if (speed == 0)
return 0;
for (speedp = speeds; speedp->speed_int; speedp++)
if (speed == speedp->speed_val)
return speedp->speed_int;
return 0;
}
#endif
/*
* set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
* at the requested speed, etc.
* at the requested speed, etc. If `local' is true, set CLOCAL
* regardless of whether the modem option was specified.
*/
set_up_tty(fd)
int fd;
set_up_tty(fd, local)
int fd, local;
{
#ifndef SGTTY
int speed;
@ -576,11 +610,16 @@ set_up_tty(fd)
if (!restore_term)
inittermios = tios;
#ifdef CRTSCTS
tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL | CRTSCTS);
tios.c_cflag |= CS8 | CREAD | HUPCL;
if (crtscts)
tios.c_cflag |= CRTSCTS;
if (!modem)
#else
tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
#endif /* CRTSCTS */
tios.c_cflag |= CS8 | CREAD | HUPCL;
if (local || !modem)
tios.c_cflag |= CLOCAL;
tios.c_iflag = IGNBRK | IGNPAR;
tios.c_oflag = 0;
@ -591,12 +630,15 @@ set_up_tty(fd)
if (speed) {
cfsetospeed(&tios, speed);
cfsetispeed(&tios, speed);
} else {
speed = cfgetospeed(&tios);
}
if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
syslog(LOG_ERR, "tcsetattr: %m");
die(1);
}
#else /* SGTTY */
int speed;
struct sgttyb sgttyb;
@ -616,15 +658,31 @@ set_up_tty(fd)
speed = translate_speed(inspeed);
if (speed)
sgttyb.sg_ispeed = speed;
else
speed = sgttyb.sg_ispeed;
if (ioctl(fd, TIOCSETP, &sgttyb) < 0) {
syslog(LOG_ERR, "ioctl(TIOCSETP): %m");
die(1);
}
#endif
baud_rate = baud_rate_of(speed);
restore_term = TRUE;
}
/*
* setdtr - control the DTR line on the serial port.
* This is called from die(), so it shouldn't call die().
*/
setdtr(fd, on)
int fd, on;
{
int modembits = TIOCM_DTR;
ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
}
/*
* quit - Clean up state and exit.
@ -656,23 +714,23 @@ cleanup(status, arg)
int status;
caddr_t arg;
{
if (fd != 0) {
if (fd >= 0) {
/* drop dtr to hang up */
if (modem)
setdtr(fd, FALSE);
if (fcntl(fd, F_SETFL, initfdflags) < 0)
syslog(LOG_ERR, "fcntl(F_SETFL, fdflags): %m");
syslog(LOG_WARNING, "fcntl(F_SETFL, fdflags): %m");
disestablish_ppp();
if (restore_term) {
#ifndef SGTTY
if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
syslog(LOG_ERR, "tcsetattr: %m");
syslog(LOG_WARNING, "tcsetattr: %m");
#else
if (ioctl(fd, TIOCSETP, &initsgttyb) < 0)
syslog(LOG_ERR, "ioctl(TIOCSETP): %m");
syslog(LOG_WARNING, "ioctl(TIOCSETP): %m");
#endif
}
@ -683,6 +741,9 @@ cleanup(status, arg)
if (pidfilename[0] != 0 && unlink(pidfilename) < 0)
syslog(LOG_WARNING, "unable to unlink pid file: %m");
pidfilename[0] = 0;
if (lockflag && !default_device)
unlock();
}
@ -739,7 +800,7 @@ timeout(func, arg, time)
itv.it_interval.tv_sec = itv.it_interval.tv_usec =
itv.it_value.tv_usec = 0;
itv.it_value.tv_sec = callout->c_time;
MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds.",
MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds in timeout.",
itv.it_value.tv_sec));
if (setitimer(ITIMER_REAL, &itv, NULL)) {
syslog(LOG_ERR, "setitimer(ITIMER_REAL): %m");
@ -795,7 +856,7 @@ untimeout(func, arg)
itv.it_interval.tv_sec = itv.it_interval.tv_usec =
itv.it_value.tv_usec = 0;
itv.it_value.tv_sec = callout ? callout->c_time : 0;
MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds.",
MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds in untimeout.",
itv.it_value.tv_sec));
if (setitimer(ITIMER_REAL, &itv, NULL)) {
syslog(LOG_ERR, "setitimer(ITIMER_REAL): %m");
@ -912,22 +973,22 @@ alrm(sig, code, scp, addr)
char *addr;
{
struct itimerval itv;
struct callout *freep;
struct callout *freep, *list, *last;
MAINDEBUG((LOG_DEBUG, "Alarm"));
if (callout == NULL)
return;
/*
* Call and free first scheduled timeout and any that were scheduled
* for the same time.
* Get the first scheduled timeout and any that were scheduled
* for the same time as a list, and remove them all from callout
* list.
*/
while (callout) {
freep = callout; /* Remove entry before calling */
callout = freep->c_next;
(*freep->c_func)(freep->c_arg);
(void) free((char *) freep);
if (callout && callout->c_time)
break;
}
list = last = callout;
while (last->c_next != NULL && last->c_next->c_time == 0)
last = last->c_next;
callout = last->c_next;
last->c_next = NULL;
/*
* Set a new itimer if there are more timeouts scheduled.
@ -936,7 +997,7 @@ alrm(sig, code, scp, addr)
itv.it_interval.tv_sec = itv.it_interval.tv_usec = 0;
itv.it_value.tv_usec = 0;
itv.it_value.tv_sec = callout->c_time;
MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds.",
MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds in alrm.",
itv.it_value.tv_sec));
if (setitimer(ITIMER_REAL, &itv, NULL)) {
syslog(LOG_ERR, "setitimer(ITIMER_REAL): %m");
@ -947,6 +1008,17 @@ alrm(sig, code, scp, addr)
die(1);
}
}
/*
* Now call all the timeout routines scheduled for this time.
*/
while (list) {
(*list->c_func)(list->c_arg);
freep = list;
list = list->c_next;
(void) free((char *) freep);
}
}
@ -1000,10 +1072,13 @@ io(sig, code, scp, addr)
return;
if (len == 0) {
syslog(LOG_ERR, "End of file on fd!");
syslog(LOG_WARNING, "End of file on fd!");
die(1);
}
if (debug /*&& (debugflags & DBG_INPACKET)*/)
log_packet(p, len, "rcvd ");
if (len < DLLHEADERLEN) {
MAINDEBUG((LOG_INFO, "io(): Received short packet."));
return;
@ -1019,8 +1094,6 @@ io(sig, code, scp, addr)
if (protocol != LCP && lcp_fsm[0].state != OPENED) {
MAINDEBUG((LOG_INFO,
"io(): Received non-LCP packet when LCP not open."));
if (debug)
dumpbuffer(inpacket_buf, len + DLLHEADERLEN, LOG_INFO);
return;
}
@ -1098,10 +1171,11 @@ nodebug(sig)
/*
* set_up_connection - run a program to initialize the serial connector
* device_script - run a program to connect or disconnect the
* serial device.
*/
int
set_up_connection(program, in, out)
device_script(program, in, out)
char *program;
int in, out;
{
@ -1133,10 +1207,10 @@ set_up_connection(program, in, out)
/* NOTREACHED */
}
while (waitpid(pid, &status, 0) != pid) {
while (waitpid(pid, &status, 0) < 0) {
if (errno == EINTR)
continue;
syslog(LOG_ERR, "waiting for connection process: %m");
syslog(LOG_ERR, "waiting for (dis)connection process: %m");
die(1);
}
sigprocmask(SIG_SETMASK, &mask, NULL);
@ -1146,82 +1220,154 @@ set_up_connection(program, in, out)
/*
* Return user specified netmask. A value of zero means no netmask has
* been set.
* run-program - execute a program with given arguments,
* but don't wait for it.
* If the program can't be executed, logs an error unless
* must_exist is 0 and the program file doesn't exist.
*/
/* ARGSUSED */
u_long
GetMask(addr)
u_long addr;
int
run_program(prog, args, must_exist)
char *prog;
char **args;
int must_exist;
{
return(netmask);
int pid;
pid = fork();
if (pid == -1) {
syslog(LOG_ERR, "can't fork to run %s: %m", prog);
return -1;
}
if (pid == 0) {
execv(prog, args);
if (must_exist || errno != ENOENT)
syslog(LOG_WARNING, "can't execute %s: %m", prog);
_exit(-1);
}
MAINDEBUG((LOG_DEBUG, "Script %s started; pid = %d", prog, pid));
++n_children;
return 0;
}
/*
* dumpbuffer - print contents of a buffer in hex to standard output.
* reap_kids - get status from any dead child processes,
* and log a message for abnormal terminations.
*/
void
dumpbuffer(buffer, size, level)
unsigned char *buffer;
int size;
int level;
reap_kids()
{
register int i;
char line[256], *p;
int pid, status;
printf("%d bytes:\n", size);
while (size > 0)
{
p = line;
sprintf(p, "%08lx: ", buffer);
p += 10;
for (i = 0; i < 8; i++, p += 3)
if (size - i <= 0)
sprintf(p, "xx ");
else
sprintf(p, "%02x ", buffer[i]);
for (i = 0; i < 8; i++)
if (size - i <= 0)
*p++ = 'x';
else
*p++ = (' ' <= buffer[i] && buffer[i] <= '~') ?
buffer[i] : '.';
*p++ = 0;
buffer += 8;
size -= 8;
/* syslog(level, "%s\n", line); */
printf("%s\n", line);
fflush(stdout);
if (n_children == 0)
return;
if ((pid = waitpid(-1, &status, WNOHANG)) == -1) {
if (errno != ECHILD)
syslog(LOG_ERR, "waitpid: %m");
return;
}
if (pid > 0) {
--n_children;
if (WIFSIGNALED(status)) {
syslog(LOG_WARNING, "child process %d terminated with signal %d",
pid, WTERMSIG(status));
}
}
}
/*
* setdtr - control the DTR line on the serial port.
* This is called from die(), so it shouldn't call die().
* log_packet - format a packet and log it.
*/
setdtr(fd, on)
int fd, on;
{
int modembits = TIOCM_DTR;
ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
char line[256]; /* line to be logged accumulated here */
char *linep;
void
log_packet(p, len, prefix)
u_char *p;
int len;
char *prefix;
{
strcpy(line, prefix);
linep = line + strlen(line);
format_packet(p, len, pr_log, NULL);
if (linep != line)
syslog(LOG_DEBUG, "%s", line);
}
/*
* format_packet - make a readable representation of a packet,
* calling `printer(arg, format, ...)' to output it.
*/
void
format_packet(p, len, printer, arg)
u_char *p;
int len;
void (*printer) __ARGS((void *, char *, ...));
void *arg;
{
int i, n;
u_short proto;
u_char x;
if (len >= DLLHEADERLEN && p[0] == ALLSTATIONS && p[1] == UI) {
p += 2;
GETSHORT(proto, p);
len -= DLLHEADERLEN;
for (i = 0; i < N_PROTO; ++i)
if (proto == prottbl[i].protocol)
break;
if (i < N_PROTO) {
printer(arg, "[%s", prottbl[i].name);
n = (*prottbl[i].printpkt)(p, len, printer, arg);
printer(arg, "]");
p += n;
len -= n;
} else {
printer(arg, "[proto=0x%x]", proto);
}
}
for (; len > 0; --len) {
GETCHAR(x, p);
printer(arg, " %.2x", x);
}
}
#ifdef __STDC__
#include <stdarg.h>
void
pr_log(void *arg, char *fmt, ...)
{
int n;
va_list pvar;
char buf[256];
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>
char line[256];
char *p;
logf(level, fmt, va_alist)
int level;
void
pr_log(arg, fmt, va_alist)
void *arg;
char *fmt;
va_dcl
{
int n;
va_list pvar;
char buf[256];
@ -1229,15 +1375,43 @@ va_dcl
vsprintf(buf, fmt, pvar);
va_end(pvar);
p = line + strlen(line);
strcat(p, buf);
if (buf[strlen(buf)-1] == '\n') {
syslog(level, "%s", line);
line[0] = 0;
n = strlen(buf);
if (linep + n + 1 > line + sizeof(line)) {
syslog(LOG_DEBUG, "%s", line);
linep = line;
}
strcpy(linep, buf);
linep += n;
}
#endif
/*
* print_string - print a readable representation of a string using
* printer.
*/
void
print_string(p, len, printer, arg)
char *p;
int len;
void (*printer) __ARGS((void *, char *, ...));
void *arg;
{
int c;
printer(arg, "\"");
for (; len > 0; --len) {
c = *p++;
if (' ' <= c && c <= '~')
printer(arg, "%c", c);
else
printer(arg, "\\%.3o", c);
}
printer(arg, "\"");
}
/*
* novm - log an error message saying we ran out of memory, and die.
*/
void
novm(msg)
char *msg;

View File

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: options.c,v 1.5 1994/02/22 00:12:01 paulus Exp $";
static char rcsid[] = "$Id: options.c,v 1.6 1994/05/08 12:16:26 paulus Exp $";
#endif
#include <stdio.h>
@ -45,11 +45,11 @@ static char rcsid[] = "$Id: options.c,v 1.5 1994/02/22 00:12:01 paulus Exp $";
#define FALSE 0
#define TRUE 1
/*
* Prototypes
*/
static int setdebug __ARGS((void));
static int setkdebug __ARGS((char **));
static int setpassive __ARGS((void));
static int setsilent __ARGS((void));
static int noopt __ARGS((void));
@ -65,16 +65,20 @@ static int noasyncmap __ARGS((void));
static int noipaddr __ARGS((void));
static int nomagicnumber __ARGS((void));
static int setasyncmap __ARGS((char **));
static int setescape __ARGS((char **));
static int setmru __ARGS((char **));
static int setmtu __ARGS((char **));
static int nomru __ARGS((void));
static int nopcomp __ARGS((void));
static int setconnector __ARGS((char **));
static int setdisconnector __ARGS((char **));
static int setdomain __ARGS((char **));
static int setnetmask __ARGS((char **));
static int setcrtscts __ARGS((void));
static int setnodetach __ARGS((void));
static int setmodem __ARGS((void));
static int setlocal __ARGS((void));
static int setlock __ARGS((void));
static int setname __ARGS((char **));
static int setuser __ARGS((char **));
static int setremote __ARGS((char **));
@ -110,10 +114,13 @@ static int number_option __ARGS((char *, long *, int));
*/
extern char *progname;
extern int debug;
extern int kdebugflag;
extern int modem;
extern int lockflag;
extern int crtscts;
extern int nodetach;
extern char *connector;
extern char *disconnector;
extern int inspeed;
extern char devname[];
extern int default_device;
@ -156,16 +163,21 @@ static struct cmd {
"-chap", 0, nochap, /* Don't allow CHAP authentication with peer */
"-vj", 0, setnovj, /* disable VJ compression */
"asyncmap", 1, setasyncmap, /* set the desired async map */
"escape", 1, setescape, /* set chars to escape on transmission */
"connect", 1, setconnector, /* A program to set up a connection */
"disconnect", 1, setdisconnector, /* program to disconnect serial dev. */
"crtscts", 0, setcrtscts, /* set h/w flow control */
"debug", 0, setdebug, /* Increase debugging level */
"kdebug", 1, setkdebug, /* Enable kernel-level debugging */
"domain", 1, setdomain, /* Add given domain name to hostname*/
"mru", 1, setmru, /* Set MRU value for negotiation */
"mtu", 1, setmtu, /* Set our MTU */
"netmask", 1, setnetmask, /* set netmask */
"passive", 0, setpassive, /* Set passive mode */
"silent", 0, setsilent, /* Set silent mode */
"modem", 0, setmodem, /* Use modem control lines */
"local", 0, setlocal, /* Don't use modem control lines */
"lock", 0, setlock, /* Lock serial device (with lock file) */
"name", 1, setname, /* Set local name for authentication */
"user", 1, setuser, /* Set username for PAP auth with peer */
"usehostname", 0, setusehostname, /* Must use hostname for auth. */
@ -215,34 +227,6 @@ Usage: %s [ arguments ], where arguments are:\n\
See pppd(8) for more options.\n\
";
/*
Options omitted:
-all Don't request/allow any options\n\
-ac Disable Address/Control compression\n\
-am Disable asyncmap negotiation\n\
-as <n> Set the desired async map to hex <n>\n\
-d Increase debugging level\n\
-detach Don't fork to background\n\
-ip Disable IP address negotiation\n\
-mn Disable magic number negotiation\n\
-mru Disable mru negotiation\n\
-p Set passive mode\n\
-pc Disable protocol field compression\n\
+ua <f> Get username and password for authenticating\n\
with peer using PAP from file <f>\n\
+pap Require PAP authentication from peer\n\
-pap Don't agree to authenticating with peer using PAP\n\
+chap Require CHAP authentication from peer\n\
-chap Don't agree to authenticating with peer using CHAP\n\
-vj disable VJ compression\n\
-auth Don't agree to authenticate with peer\n\
debug Increase debugging level\n\
domain <d> Append domain name <d> to hostname for authentication\n\
passive Set passive mode\n\
local Don't use modem control lines\n\
proxyarp Add proxy ARP entry\n\
*/
/*
* parse_args - parse a string of arguments, from the command
@ -319,7 +303,7 @@ options_from_file(filename, must_exist)
if (!must_exist && errno == ENOENT)
return 1;
perror(filename);
exit(1);
return 0;
}
while (getword(f, cmd, &newline, filename)) {
/*
@ -549,10 +533,19 @@ static int
setdebug()
{
debug++;
setlogmask(LOG_UPTO(LOG_DEBUG));
return (1);
}
/*
* setkdebug - Set kernel debugging level.
*/
static int
setkdebug(argv)
char **argv;
{
return int_option(*argv, &kdebugflag);
}
/*
* noopt - Disable all options.
*/
@ -643,6 +636,27 @@ setmru(argv)
}
/*
* setmru - Set the largest MTU we'll use.
*/
static int
setmtu(argv)
char **argv;
{
long mtu;
if (!number_option(*argv, &mtu, 0))
return 0;
if (mtu < MINMRU || mtu > MAXMRU) {
fprintf(stderr, "mtu option value of %d is too %s\n", mtu,
(mtu < MINMRU? "small": "large"));
return 0;
}
lcp_allowoptions[0].mru = mtu;
return (1);
}
/*
* nopcomp - Disable Protocol field compression negotiation.
*/
@ -716,7 +730,7 @@ setupapfile(argv)
/* open user info file */
if ((ufile = fopen(*argv, "r")) == NULL) {
fprintf(stderr, "unable to open user login data file %s\n", *argv);
exit(1);
return 0;
}
check_access(ufile, *argv);
@ -724,7 +738,7 @@ setupapfile(argv)
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);
exit(2);
return 0;
}
fclose(ufile);
@ -788,6 +802,20 @@ setconnector(argv)
return (1);
}
/*
* setdisconnector - Set a program to disconnect from the serial line
*/
static int
setdisconnector(argv)
char **argv;
{
disconnector = strdup(*argv);
if (disconnector == NULL)
novm("disconnector string");
return (1);
}
/*
* setdomain - Set domain name to append to hostname
@ -801,6 +829,10 @@ setdomain(argv)
return (1);
}
/*
* setasyncmap - add bits to asyncmap (what we request peer to escape).
*/
static int
setasyncmap(argv)
char **argv;
@ -814,6 +846,38 @@ setasyncmap(argv)
return(1);
}
/*
* setescape - add chars to the set we escape on transmission.
*/
static int
setescape(argv)
char **argv;
{
int n, ret;
char *p, *endp;
p = *argv;
ret = 1;
while (*p) {
n = strtol(p, &endp, 16);
if (p == endp) {
fprintf(stderr, "%s: invalid hex number: %s\n", progname, 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", n);
ret = 0;
} else
xmit_accm[0][n >> 5] |= 1 << (n & 0x1F);
while (*p == ',' || *p == ' ')
++p;
}
return ret;
}
/*
* setspeed - Set the speed.
*/
@ -857,7 +921,7 @@ setdevname(cp)
if (errno == ENOENT)
return (0);
syslog(LOG_ERR, cp);
exit(1);
return 0;
}
(void) strncpy(devname, cp, MAXPATHLEN);
@ -1006,13 +1070,26 @@ setnetmask(argv)
if ((mask = inet_addr(*argv)) == -1) {
fprintf(stderr, "Invalid netmask %s\n", *argv);
exit(1);
return 0;
}
netmask = mask;
return (1);
}
/*
* Return user specified netmask. A value of zero means no netmask has
* been set.
*/
/* ARGSUSED */
u_long
GetMask(addr)
u_long addr;
{
return(netmask);
}
static int
setcrtscts()
{
@ -1041,6 +1118,13 @@ setlocal()
return 1;
}
static int
setlock()
{
lockflag = 1;
return 1;
}
static int
setusehostname()
{

View File

@ -1,5 +1,5 @@
/* $Id: patchlevel.h,v 1.6 1994/02/22 00:12:03 paulus Exp $ */
#define PATCHLEVEL 4
/* $Id: patchlevel.h,v 1.7 1994/05/08 12:16:27 paulus Exp $ */
#define PATCHLEVEL 0
#define VERSION "2.0"
#define DATE "9 Feb 94"
#define VERSION "2.1"
#define DATE "1 May 94"

View File

@ -1,10 +1,10 @@
/*
* define path names
*
* $Id: pathnames.h,v 1.4 1993/11/10 01:34:26 paulus Exp $
* $Id: pathnames.h,v 1.5 1994/05/08 12:16:28 paulus Exp $
*/
#ifdef STREAMS
#if defined(STREAMS) || defined(ultrix)
#define _PATH_PIDFILE "/etc/ppp"
#else
#define _PATH_PIDFILE "/var/run"
@ -13,3 +13,5 @@
#define _PATH_UPAPFILE "/etc/ppp/pap-secrets"
#define _PATH_CHAPFILE "/etc/ppp/chap-secrets"
#define _PATH_SYSOPTIONS "/etc/ppp/options"
#define _PATH_IPUP "/etc/ppp/ip-up"
#define _PATH_IPDOWN "/etc/ppp/ip-down"

View File

@ -1,5 +1,5 @@
.\" manual page [] for pppd 2.0
.\" $Id: pppd.8,v 1.5 1994/02/22 00:12:04 paulus Exp $
.\" $Id: pppd.8,v 1.6 1994/05/08 12:16:29 paulus Exp $
.\" SH section heading
.\" SS subsection heading
.\" LP paragraph
@ -50,20 +50,23 @@ Set the async character map to <map>.
This map describes which control characters cannot be successfully
received over the serial line.
.I pppd
will ask the peer to send these characters as a 2-byte "escape" sequence.
will ask the peer to send these characters as a 2-byte escape sequence.
The argument is a 32 bit hex number
with each bit representing a character to escape.
Bit 0 (00000001) represents the character 0x00;
bit 31 (80000000) represents the character 0x1f or ^_.
The default asyncmap is 0. If multiple \fBasyncmap\fR options are
If multiple \fBasyncmap\fR options are
given, the values are ORed together.
If no \fBasyncmap\fR option is given, no async character map will be
negotiated for the receive direction; the peer will then escape
\fIall\fR control characters.
.TP
.B auth
Require the peer to authenticate itself before allowing network
packets to be sent or received.
.TP
.B connect \fI<p>
Use the executable or shell command specified by <p> to set up the
Use the executable or shell command specified by \fI<p>\fR to set up the
serial line. This script would typically use the "chat" program to
dial the modem and start the remote ppp session.
.TP
@ -76,9 +79,28 @@ Add a default route to the system routing tables, using the peer as
the gateway, when IPCP negotiation is successfully completed.
This entry is removed when the PPP connection is broken.
.TP
.B disconnect \fI<p>
Run the executable or shell command specified by \fI<p>\fR after
\fIpppd\fR has terminated the link. This script could, for example,
issue commands to the modem to cause it to hang up.
.TP
.B escape \fIxx,yy,...
Specifies that certain characters should be escaped on transmission
(regardless of whether the peer requests them to be escaped with its
async control character map). The characters to be escaped are
specified as a list of hex numbers separated by commas. Note that
almost any character can be specified for the \fBescape\fR option,
unlike the \fBasyncmap\fR option which only allows control characters
to be specified. The characters which may not be escaped are those
with hex values 0x20 - 0x3f or 0x5e.
.TP
.B file \fI<f>
Read options from file <f> (the format is described below).
.TP
.B lock
Specifies that \fIpppd\fR should use a UUCP-style lock on the serial
device to ensure exclusive access to the device.
.TP
.B mru \fI<n>
Set the MRU [Maximum Receive Unit] value to <n> for negotiation.
.I pppd
@ -132,17 +154,18 @@ default values).
.TP
.B -ac
Disable Address/Control compression negotiation (use default, i.e.
disabled).
address/control field disabled).
.TP
.B -am
Disable asyncmap negotiation (use default, i.e. 0xffffffff).
Disable asyncmap negotiation (use the default asyncmap, i.e. escape
all control characters).
.TP
.B -as \fI<n>
Same as
.B asyncmap \fI<n>
.TP
.B -d
Increase debugging level.
Increase debugging level (same as the \fBdebug\fR option).
.TP
.B -detach
Don't fork to become a background process (otherwise
@ -168,7 +191,8 @@ Same as the
option.
.TP
.B -pc
Disable protocol field compression negotiation (use default, i.e. disabled).
Disable protocol field compression negotiation (use default, i.e.
protocol field compression disabled).
.TP
.B +ua \fI<p>
Agree to authenticate using PAP [Password Authentication Protocol] if
@ -196,9 +220,13 @@ Disable negotiation of Van Jacobson style IP header compression (use
default, i.e. no compression).
.TP
.B debug
Increase debugging level (same as
.B -d
).
Increase debugging level (same as \fB\-d\fR).
If this
option is given, \fIpppd\fR will log the contents of all control
packets sent or received in a readable form. The packets are logged
through syslog with facility \fIdaemon\fR and level \fIdebug\fR. This
information can be directed to a file by setting up /etc/syslog.conf
appropriately (see syslog.conf(5)).
.TP
.B domain \fI<d>
Append the domain name <d> to the local host name for authentication
@ -209,9 +237,22 @@ domain option to set the domain name to Quotron.COM.
.B modem
Use the modem control lines. (This option is not fully implemented.)
.TP
.B kdebug \fIn
Enable debugging code in the kernel-level PPP driver. The argument
\fIn\fR is a number which is the sum of the following values: 1 to
enable general debug messages, 2 to request that the contents of
received packets be printed, and 4 to request that the contents of
transmitted packets be printed.
.TP
.B local
Don't use the modem control lines.
.TP
.B mtu \fI<n>
Set the MTU [Maximum Transmit Unit] value to \fI<n>\fR. Unless the
peer requests a smaller value via MRU negotiation, \fIpppd\fR will
request that the kernel networking code send data packets of no more
than \fIn\fR bytes through the PPP network interface.
.TP
.B name \fI<n>
Set the name of the local system for authentication purposes to <n>.
.TP
@ -429,6 +470,16 @@ other Network Control Protocol) can be started. If authentication
fails, \fIpppd\fR will terminated the link (by closing LCP). If IPCP
negotiates an unacceptable IP address for the remote host, IPCP will
be closed. IP packets can only be sent or received when IPCP is open.
.LP
In some cases it is desirable to allow some hosts which can't
authenticate themselves to connect and use one of a restricted set of
IP addresses, even when the local host generally requires
authentication. If the peer refuses to authenticate itself when
requested, \fIpppd\fR takes that as equivalent to authenticating with
PAP using the empty string for the username and password. Thus, by
adding a line to the pap-secrets file which specifies the empty string
for the client and password, it is possible to allow restricted access
to hosts which refuse to authenticate themselves.
.SH ROUTING
.LP
When IPCP negotiation is completed successfully,
@ -483,29 +534,34 @@ for example:
pppd /dev/ttya 38400 connect 'chat "" "" "login:" "username"
"Password:" "password" "% " "exec pppd passive"'
.LP
(Note however that running chat like this will leave the password
visible in the parameter list of pppd and chat.)
.LP
If your serial connection is any more complicated than a piece of
wire, you may need to arrange for some control characters to be
escaped. In particular, it is often useful to escape XON (^Q) and
XOFF (^S), using \fBasyncmap a0000\fR. If the path includes a telnet,
you probably should escape ^] as well (\fBasyncmap 200a0000\fR).
Don't use an rlogin in the path - many implementations are not
If the path includes an rlogin, you will need to use the \fBescape
ff\fR option on the end which is running the rlogin client, since many
rlogin implementations are not
transparent; they will remove the sequence [0xff, 0xff, 0x73, 0x73,
followed by any 8 bytes] from the stream.
.SH DIAGNOSTICS
.LP
Messages are sent to the syslog daemon using facility
LOG_DAEMON unless
.I pppd
has been compiled with debugging code. In this case the logging
facility used will be LOG_LOCAL2 in order to allow separation of the debug
output from the other daemons using the LOG_DAEMON facility. You can
override this by defining the macro LOG_PPP to the desired facility
and recompiling. In order to see the error and debug messages, you
will need to edit your /etc/syslog.conf file to direct the messages to
the desired output device or file.
Messages are sent to the syslog daemon using facility LOG_DAEMON.
(This can be overriden by recompiling \fIpppd\fR with the macro
LOG_PPP defined as the desired facility.) In order to see the error
and debug messages, you will need to edit your /etc/syslog.conf file
to direct the messages to the desired output device or file.
.LP
If enabled at compile time, debugging printout can be enabled by
setting the -d or debug flag on the command line, or by sending a
The \fBdebug\fR option causes the contents of all control packets sent
or received to be logged, that is, all LCP, PAP, CHAP or IPCP packets.
This can be useful if the PPP negotiation does not succeed.
If debugging is enabled at compile time, the \fBdebug\fR option also
causes other debugging messages to be logged.
.LP
Debugging can also be enabled by sending a
SIGUSR1 to the
.I pppd
process.
@ -542,12 +598,6 @@ Rivest, R.
.I The MD5 Message-Digest Algorithm.
1992 April.
.TP
.B RFC1331
Simpson, W.A.
.I Point\-to\-Point Protocol (PPP) for the transmission of multi\-protocol
.I datagrams over point\-to\-point links.
1992 May.
.TP
.B RFC1332
McGregor, G.
.I PPP Internet Protocol Control Protocol (IPCP).
@ -557,6 +607,16 @@ McGregor, G.
Lloyd, B.; Simpson, W.A.
.I PPP authentication protocols.
1992 October.
.TP
.B RFC1548
Simpson, W.A.
.I The Point\-to\-Point Protocol (PPP).
1993 December.
.TP
.B RFC1549
Simpson, W.A.
.I PPP in HDLC Framing.
1993 December
.SH NOTES
The following signals have the specified effect when sent to the
.I pppd

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: pppd.h,v 1.4 1993/11/10 01:34:32 paulus Exp $
* $Id: pppd.h,v 1.5 1994/05/08 12:16:30 paulus Exp $
*/
/*
@ -39,6 +39,9 @@
#define MAXNAMELEN 256 /* max length of hostname or name for auth */
#define MAXSECRETLEN 256 /* max length of password or secret */
/*
* Global variables.
*/
extern int debug; /* Debug flag */
extern int ifunit; /* Interface unit number */
extern char ifname[]; /* Interface name */
@ -46,7 +49,20 @@ extern int fd; /* Device file descriptor */
extern int s; /* socket descriptor */
extern char hostname[]; /* hostname */
extern u_char outpacket_buf[]; /* buffer for outgoing packets */
extern int phase; /* See values below */
/*
* Values for phase.
*/
#define PHASE_DEAD 0
#define PHASE_ESTABLISH 1
#define PHASE_AUTHENTICATE 2
#define PHASE_NETWORK 3
#define PHASE_TERMINATE 4
/*
* Prototypes.
*/
void quit __ARGS((void)); /* Cleanup and exit */
void timeout __ARGS((void (*)(), caddr_t, int));
/* Look-alike of kernel's timeout() */

View File

@ -19,7 +19,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: sys-bsd.c,v 1.3 1994/01/25 05:58:14 paulus Exp $";
static char rcsid[] = "$Id: sys-bsd.c,v 1.4 1994/05/08 12:16:31 paulus Exp $";
#endif
/*
@ -42,8 +42,8 @@ static char rcsid[] = "$Id: sys-bsd.c,v 1.3 1994/01/25 05:58:14 paulus Exp $";
#include "pppd.h"
#include "ppp.h"
static int initdisc; /* Initial TTY discipline */
static int initdisc = -1; /* Initial TTY discipline */
extern int kdebugflag;
/*
* establish_ppp - Turn the serial port into a ppp interface.
@ -52,6 +52,7 @@ void
establish_ppp()
{
int pppdisc = PPPDISC;
int x;
if (ioctl(fd, TIOCGETD, &initdisc) < 0) {
syslog(LOG_ERR, "ioctl(TIOCGETD): %m");
@ -69,6 +70,19 @@ establish_ppp()
syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m");
die(1);
}
/*
* Enable debug in the driver if requested.
*/
if (kdebugflag) {
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_WARNING, "ioctl (PPPIOCGFLAGS): %m");
} else {
x |= (kdebugflag & 0xFF) * SC_DEBUG;
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)
syslog(LOG_WARNING, "ioctl(PPPIOCSFLAGS): %m");
}
}
}
@ -79,9 +93,38 @@ establish_ppp()
void
disestablish_ppp()
{
int x;
char *s;
if (initdisc >= 0) {
/*
* Check whether the link seems not to be 8-bit clean.
*/
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
s = NULL;
switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
case SC_RCV_B7_0:
s = "bit 7 set to 1";
break;
case SC_RCV_B7_1:
s = "bit 7 set to 0";
break;
case SC_RCV_EVNP:
s = "odd parity";
break;
case SC_RCV_ODDP:
s = "even parity";
break;
}
if (s != NULL) {
syslog(LOG_WARNING, "Serial link is not 8-bit clean:");
syslog(LOG_WARNING, "All received characters had %s", s);
}
}
if (ioctl(fd, TIOCSETD, &initdisc) < 0)
syslog(LOG_ERR, "ioctl(TIOCSETD): %m");
}
}
/*
@ -95,6 +138,8 @@ output(unit, p, len)
{
if (unit != 0)
MAINDEBUG((LOG_WARNING, "output: unit != 0!"));
if (debug)
log_packet(p, len, "sent ");
if (write(fd, p, len) < 0) {
syslog(LOG_ERR, "write: %m");
@ -161,9 +206,23 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
}
}
/*
* ppp_set_xaccm - set the extended transmit ACCM for the interface.
*/
void
ppp_set_xaccm(unit, accm)
int unit;
ext_accm accm;
{
if (ioctl(fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY)
syslog(LOG_WARNING, "ioctl(set extended ACCM): %m");
}
/*
* ppp_recv_config - configure the receive-side characteristics of
* the ppp interface. At present this does nothing.
* the ppp interface.
*/
void
ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
@ -171,12 +230,16 @@ ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
u_long asyncmap;
int pcomp, accomp;
{
#ifdef notyet
int x;
if (ioctl(fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %m");
quit();
}
if (ioctl(fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSRASYNCMAP): %m");
quit();
}
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
quit();
@ -186,14 +249,14 @@ ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
quit();
}
#endif /* notyet */
}
/*
* sifvjcomp - config tcp header compression
*/
int
sifvjcomp(u, vjcomp, cidcomp)
sifvjcomp(u, vjcomp, cidcomp, maxcid)
int u, vjcomp, cidcomp, maxcid;
{
u_int x;
@ -207,16 +270,22 @@ sifvjcomp(u, vjcomp, cidcomp)
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
return 0;
}
if (ioctl(fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
return 0;
}
return 1;
}
/*
* sifup - Config the interface up.
* sifup - Config the interface up and enable IP packets to pass.
*/
int
sifup(u)
{
struct ifreq ifr;
u_int x;
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
@ -227,27 +296,51 @@ sifup(u)
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
return 0;
}
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
return 0;
}
x |= SC_ENABLE_IP;
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
return 0;
}
return 1;
}
/*
* sifdown - Config the interface down.
* sifdown - Config the interface down and disable IP.
*/
int
sifdown(u)
{
struct ifreq ifr;
u_int x;
int rv;
rv = 1;
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
rv = 0;
} else {
x &= ~SC_ENABLE_IP;
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
rv = 0;
}
}
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
return 0;
}
rv = 0;
} else {
ifr.ifr_flags &= ~IFF_UP;
if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
return 0;
rv = 0;
}
return 1;
}
return rv;
}
/*
@ -481,11 +574,11 @@ get_ether_addr(ipaddr, hwaddr)
return 0;
}
/*
* ppp_available - check whether the system has any ppp interfaces
* (in fact we check whether we can do an ioctl on ppp0).
*/
int
ppp_available()
{

View File

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: upap.c,v 1.3 1993/11/10 01:34:35 paulus Exp $";
static char rcsid[] = "$Id: upap.c,v 1.4 1994/05/08 12:16:32 paulus Exp $";
#endif
/*
@ -310,7 +310,7 @@ upap_rauthreq(u, inp, id, len)
return;
}
GETCHAR(ruserlen, inp);
len -= sizeof (u_char) + ruserlen + sizeof (u_char);;
len -= sizeof (u_char) + ruserlen + sizeof (u_char);
if (len < 0) {
UPAPDEBUG((LOG_INFO, "upap_rauth: rcvd short packet."));
return;
@ -482,3 +482,80 @@ upap_sresp(u, code, id, msg, msglen)
UPAPDEBUG((LOG_INFO, "upap_sresp: Sent code %d, id %d.", code, id));
}
/*
* upap_printpkt - print the contents of a PAP packet.
*/
char *upap_codenames[] = {
"AuthReq", "AuthAck", "AuthNak"
};
int
upap_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __ARGS((void *, char *, ...));
void *arg;
{
int code, id, len;
int mlen, ulen, wlen;
char *user, *pwd, *msg;
u_char *pstart;
if (plen < UPAP_HEADERLEN)
return 0;
pstart = p;
GETCHAR(code, p);
GETCHAR(id, p);
GETSHORT(len, p);
if (len < UPAP_HEADERLEN || len > plen)
return 0;
if (code >= 1 && code <= sizeof(upap_codenames) / sizeof(char *))
printer(arg, " %s", upap_codenames[code-1]);
else
printer(arg, " code=0x%x", code);
printer(arg, " id=0x%x", id);
len -= UPAP_HEADERLEN;
switch (code) {
case UPAP_AUTHREQ:
if (len < 1)
break;
ulen = p[0];
if (len < ulen + 2)
break;
wlen = p[ulen + 1];
if (len < ulen + wlen + 2)
break;
user = (char *) (p + 1);
pwd = (char *) (p + ulen + 2);
p += ulen + wlen + 2;
len -= ulen + wlen + 2;
printer(arg, " user=");
print_string(user, ulen, printer, arg);
printer(arg, " password=");
print_string(pwd, wlen, printer, arg);
break;
case UPAP_AUTHACK:
case UPAP_AUTHNAK:
if (len < 1)
break;
mlen = p[0];
if (len < mlen + 1)
break;
msg = (char *) (p + 1);
p += mlen + 1;
len -= mlen + 1;
printer(arg, "msg=");
print_string(msg, mlen, printer, arg);
break;
}
/* print the rest of the bytes in the packet */
for (; len > 0; --len) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
return p - pstart;
}

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: upap.h,v 1.3 1993/11/10 01:34:38 paulus Exp $
* $Id: upap.h,v 1.4 1994/05/08 12:16:34 paulus Exp $
*/
/*
@ -87,3 +87,5 @@ void upap_lowerup __ARGS((int));
void upap_lowerdown __ARGS((int));
void upap_input __ARGS((int, u_char *, int));
void upap_protrej __ARGS((int));
int upap_printpkt __ARGS((u_char *, int,
void (*) __ARGS((void *, char *, ...)), void *));

View File

@ -19,7 +19,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: sys-bsd.c,v 1.3 1994/01/25 05:58:14 paulus Exp $";
static char rcsid[] = "$Id: sys-bsd.c,v 1.4 1994/05/08 12:16:31 paulus Exp $";
#endif
/*
@ -42,8 +42,8 @@ static char rcsid[] = "$Id: sys-bsd.c,v 1.3 1994/01/25 05:58:14 paulus Exp $";
#include "pppd.h"
#include "ppp.h"
static int initdisc; /* Initial TTY discipline */
static int initdisc = -1; /* Initial TTY discipline */
extern int kdebugflag;
/*
* establish_ppp - Turn the serial port into a ppp interface.
@ -52,6 +52,7 @@ void
establish_ppp()
{
int pppdisc = PPPDISC;
int x;
if (ioctl(fd, TIOCGETD, &initdisc) < 0) {
syslog(LOG_ERR, "ioctl(TIOCGETD): %m");
@ -69,6 +70,19 @@ establish_ppp()
syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m");
die(1);
}
/*
* Enable debug in the driver if requested.
*/
if (kdebugflag) {
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_WARNING, "ioctl (PPPIOCGFLAGS): %m");
} else {
x |= (kdebugflag & 0xFF) * SC_DEBUG;
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)
syslog(LOG_WARNING, "ioctl(PPPIOCSFLAGS): %m");
}
}
}
@ -79,9 +93,38 @@ establish_ppp()
void
disestablish_ppp()
{
int x;
char *s;
if (initdisc >= 0) {
/*
* Check whether the link seems not to be 8-bit clean.
*/
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
s = NULL;
switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
case SC_RCV_B7_0:
s = "bit 7 set to 1";
break;
case SC_RCV_B7_1:
s = "bit 7 set to 0";
break;
case SC_RCV_EVNP:
s = "odd parity";
break;
case SC_RCV_ODDP:
s = "even parity";
break;
}
if (s != NULL) {
syslog(LOG_WARNING, "Serial link is not 8-bit clean:");
syslog(LOG_WARNING, "All received characters had %s", s);
}
}
if (ioctl(fd, TIOCSETD, &initdisc) < 0)
syslog(LOG_ERR, "ioctl(TIOCSETD): %m");
}
}
/*
@ -95,6 +138,8 @@ output(unit, p, len)
{
if (unit != 0)
MAINDEBUG((LOG_WARNING, "output: unit != 0!"));
if (debug)
log_packet(p, len, "sent ");
if (write(fd, p, len) < 0) {
syslog(LOG_ERR, "write: %m");
@ -161,9 +206,23 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
}
}
/*
* ppp_set_xaccm - set the extended transmit ACCM for the interface.
*/
void
ppp_set_xaccm(unit, accm)
int unit;
ext_accm accm;
{
if (ioctl(fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY)
syslog(LOG_WARNING, "ioctl(set extended ACCM): %m");
}
/*
* ppp_recv_config - configure the receive-side characteristics of
* the ppp interface. At present this does nothing.
* the ppp interface.
*/
void
ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
@ -171,12 +230,16 @@ ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
u_long asyncmap;
int pcomp, accomp;
{
#ifdef notyet
int x;
if (ioctl(fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %m");
quit();
}
if (ioctl(fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSRASYNCMAP): %m");
quit();
}
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
quit();
@ -186,14 +249,14 @@ ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
quit();
}
#endif /* notyet */
}
/*
* sifvjcomp - config tcp header compression
*/
int
sifvjcomp(u, vjcomp, cidcomp)
sifvjcomp(u, vjcomp, cidcomp, maxcid)
int u, vjcomp, cidcomp, maxcid;
{
u_int x;
@ -207,16 +270,22 @@ sifvjcomp(u, vjcomp, cidcomp)
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
return 0;
}
if (ioctl(fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
return 0;
}
return 1;
}
/*
* sifup - Config the interface up.
* sifup - Config the interface up and enable IP packets to pass.
*/
int
sifup(u)
{
struct ifreq ifr;
u_int x;
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
@ -227,27 +296,51 @@ sifup(u)
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
return 0;
}
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
return 0;
}
x |= SC_ENABLE_IP;
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
return 0;
}
return 1;
}
/*
* sifdown - Config the interface down.
* sifdown - Config the interface down and disable IP.
*/
int
sifdown(u)
{
struct ifreq ifr;
u_int x;
int rv;
rv = 1;
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
rv = 0;
} else {
x &= ~SC_ENABLE_IP;
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
rv = 0;
}
}
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
return 0;
}
rv = 0;
} else {
ifr.ifr_flags &= ~IFF_UP;
if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
return 0;
rv = 0;
}
return 1;
}
return rv;
}
/*
@ -481,11 +574,11 @@ get_ether_addr(ipaddr, hwaddr)
return 0;
}
/*
* ppp_available - check whether the system has any ppp interfaces
* (in fact we check whether we can do an ioctl on ppp0).
*/
int
ppp_available()
{

View File

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: upap.c,v 1.3 1993/11/10 01:34:35 paulus Exp $";
static char rcsid[] = "$Id: upap.c,v 1.4 1994/05/08 12:16:32 paulus Exp $";
#endif
/*
@ -310,7 +310,7 @@ upap_rauthreq(u, inp, id, len)
return;
}
GETCHAR(ruserlen, inp);
len -= sizeof (u_char) + ruserlen + sizeof (u_char);;
len -= sizeof (u_char) + ruserlen + sizeof (u_char);
if (len < 0) {
UPAPDEBUG((LOG_INFO, "upap_rauth: rcvd short packet."));
return;
@ -482,3 +482,80 @@ upap_sresp(u, code, id, msg, msglen)
UPAPDEBUG((LOG_INFO, "upap_sresp: Sent code %d, id %d.", code, id));
}
/*
* upap_printpkt - print the contents of a PAP packet.
*/
char *upap_codenames[] = {
"AuthReq", "AuthAck", "AuthNak"
};
int
upap_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __ARGS((void *, char *, ...));
void *arg;
{
int code, id, len;
int mlen, ulen, wlen;
char *user, *pwd, *msg;
u_char *pstart;
if (plen < UPAP_HEADERLEN)
return 0;
pstart = p;
GETCHAR(code, p);
GETCHAR(id, p);
GETSHORT(len, p);
if (len < UPAP_HEADERLEN || len > plen)
return 0;
if (code >= 1 && code <= sizeof(upap_codenames) / sizeof(char *))
printer(arg, " %s", upap_codenames[code-1]);
else
printer(arg, " code=0x%x", code);
printer(arg, " id=0x%x", id);
len -= UPAP_HEADERLEN;
switch (code) {
case UPAP_AUTHREQ:
if (len < 1)
break;
ulen = p[0];
if (len < ulen + 2)
break;
wlen = p[ulen + 1];
if (len < ulen + wlen + 2)
break;
user = (char *) (p + 1);
pwd = (char *) (p + ulen + 2);
p += ulen + wlen + 2;
len -= ulen + wlen + 2;
printer(arg, " user=");
print_string(user, ulen, printer, arg);
printer(arg, " password=");
print_string(pwd, wlen, printer, arg);
break;
case UPAP_AUTHACK:
case UPAP_AUTHNAK:
if (len < 1)
break;
mlen = p[0];
if (len < mlen + 1)
break;
msg = (char *) (p + 1);
p += mlen + 1;
len -= mlen + 1;
printer(arg, "msg=");
print_string(msg, mlen, printer, arg);
break;
}
/* print the rest of the bytes in the packet */
for (; len > 0; --len) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
return p - pstart;
}

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: upap.h,v 1.3 1993/11/10 01:34:38 paulus Exp $
* $Id: upap.h,v 1.4 1994/05/08 12:16:34 paulus Exp $
*/
/*
@ -87,3 +87,5 @@ void upap_lowerup __ARGS((int));
void upap_lowerdown __ARGS((int));
void upap_input __ARGS((int, u_char *, int));
void upap_protrej __ARGS((int));
int upap_printpkt __ARGS((u_char *, int,
void (*) __ARGS((void *, char *, ...)), void *));