Import pppd onto the vendor branch from the ppp-2.2 package..
This commit is contained in:
parent
560c30efa3
commit
945f93070b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/MACKERAS/; revision=11981
@ -1,10 +1,14 @@
|
||||
# From: Id: Makefile.bsd,v 1.4 1994/04/20 00:07:50 paulus Exp
|
||||
# $Id$
|
||||
# $Id: Makefile.bsd,v 1.7 1995/04/27 00:19:50 paulus Exp $
|
||||
|
||||
BINDIR?= /usr/sbin
|
||||
CFLAGS+= -I.. -DHAVE_PATHS_H
|
||||
|
||||
PROG= pppd
|
||||
SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c \
|
||||
auth.c options.c lock.c sys-bsd.c
|
||||
MAN8= pppd.8
|
||||
SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
|
||||
auth.c options.c sys-bsd.c
|
||||
MAN8= pppd.0
|
||||
# The next line is for NetBSD-current systems.
|
||||
MAN= pppd.cat8
|
||||
BINMODE=4555
|
||||
BINOWN= root
|
||||
|
||||
|
@ -33,11 +33,12 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: auth.c,v 1.6 1994/05/25 06:25:05 paulus Exp $";
|
||||
static char rcsid[] = "$Id: auth.c,v 1.17 1995/08/16 01:37:22 paulus Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
@ -48,16 +49,24 @@ static char rcsid[] = "$Id: auth.c,v 1.6 1994/05/25 06:25:05 paulus Exp $";
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "ppp.h"
|
||||
#ifdef HAS_SHADOW
|
||||
#include <shadow.h>
|
||||
#include <shadow/pwauth.h>
|
||||
#ifndef PW_PPP
|
||||
#define PW_PPP PW_LOGIN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "pppd.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "upap.h"
|
||||
#include "chap.h"
|
||||
#include "ipcp.h"
|
||||
#include "ccp.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
#ifdef sparc
|
||||
#if defined(sun) && defined(sparc)
|
||||
#include <alloca.h>
|
||||
#endif /*sparc*/
|
||||
|
||||
@ -76,20 +85,10 @@ struct wordlist {
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
extern char user[];
|
||||
extern char passwd[];
|
||||
extern char devname[];
|
||||
extern char our_name[];
|
||||
extern char remote_name[];
|
||||
extern char hostname[];
|
||||
extern int uselogin;
|
||||
extern int usehostname;
|
||||
extern int auth_required;
|
||||
|
||||
/* Records which authentication operations haven't completed yet. */
|
||||
static int auth_pending[NPPP];
|
||||
static int auth_pending[NUM_PPP];
|
||||
static int logged_in;
|
||||
static struct wordlist *addresses[NPPP];
|
||||
static struct wordlist *addresses[NUM_PPP];
|
||||
|
||||
/* Bits in auth_pending[] */
|
||||
#define UPAP_WITHPEER 1
|
||||
@ -98,19 +97,20 @@ static struct wordlist *addresses[NPPP];
|
||||
#define CHAP_PEER 8
|
||||
|
||||
/* Prototypes */
|
||||
void check_access __ARGS((FILE *, char *));
|
||||
void check_access __P((FILE *, char *));
|
||||
|
||||
static int login __ARGS((char *, char *, char **, int *));
|
||||
static void logout __ARGS((void));
|
||||
static int null_login __ARGS((int));
|
||||
static int get_upap_passwd __ARGS((void));
|
||||
static int have_upap_secret __ARGS((void));
|
||||
static int have_chap_secret __ARGS((char *, char *));
|
||||
static int scan_authfile __ARGS((FILE *, char *, char *, char *,
|
||||
static void network_phase __P((int));
|
||||
static int login __P((char *, char *, char **, int *));
|
||||
static void logout __P((void));
|
||||
static int null_login __P((int));
|
||||
static int get_upap_passwd __P((void));
|
||||
static int have_upap_secret __P((void));
|
||||
static int have_chap_secret __P((char *, char *));
|
||||
static int scan_authfile __P((FILE *, char *, char *, char *,
|
||||
struct wordlist **, char *));
|
||||
static void free_wordlist __ARGS((struct wordlist *));
|
||||
static void free_wordlist __P((struct wordlist *));
|
||||
|
||||
extern char *crypt __ARGS((char *, char *));
|
||||
extern char *crypt __P((char *, char *));
|
||||
|
||||
/*
|
||||
* An Open on LCP has requested a change from Dead to Establish phase.
|
||||
@ -130,6 +130,8 @@ void
|
||||
link_terminated(unit)
|
||||
int unit;
|
||||
{
|
||||
if (phase == PHASE_DEAD)
|
||||
return;
|
||||
if (logged_in)
|
||||
logout();
|
||||
phase = PHASE_DEAD;
|
||||
@ -143,6 +145,8 @@ void
|
||||
link_down(unit)
|
||||
int unit;
|
||||
{
|
||||
ipcp_close(0);
|
||||
ccp_close(0);
|
||||
phase = PHASE_TERMINATE;
|
||||
}
|
||||
|
||||
@ -165,7 +169,7 @@ link_established(unit)
|
||||
* treat it as though it authenticated with PAP using a username
|
||||
* of "" and a password of "". If that's not OK, boot it out.
|
||||
*/
|
||||
if (wo->neg_upap && !null_login(unit)) {
|
||||
if (!wo->neg_upap || !null_login(unit)) {
|
||||
syslog(LOG_WARNING, "peer refused to authenticate");
|
||||
lcp_close(unit);
|
||||
phase = PHASE_TERMINATE;
|
||||
@ -191,10 +195,20 @@ link_established(unit)
|
||||
}
|
||||
auth_pending[unit] = auth;
|
||||
|
||||
if (!auth) {
|
||||
phase = PHASE_NETWORK;
|
||||
ipcp_open(unit);
|
||||
}
|
||||
if (!auth)
|
||||
network_phase(unit);
|
||||
}
|
||||
|
||||
/*
|
||||
* Proceed to the network phase.
|
||||
*/
|
||||
static void
|
||||
network_phase(unit)
|
||||
int unit;
|
||||
{
|
||||
phase = PHASE_NETWORK;
|
||||
ipcp_open(unit);
|
||||
ccp_open(unit);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -221,10 +235,10 @@ auth_peer_success(unit, protocol)
|
||||
int bit;
|
||||
|
||||
switch (protocol) {
|
||||
case CHAP:
|
||||
case PPP_CHAP:
|
||||
bit = CHAP_PEER;
|
||||
break;
|
||||
case UPAP:
|
||||
case PPP_PAP:
|
||||
bit = UPAP_PEER;
|
||||
break;
|
||||
default:
|
||||
@ -240,6 +254,7 @@ auth_peer_success(unit, protocol)
|
||||
if ((auth_pending[unit] &= ~bit) == 0) {
|
||||
phase = PHASE_NETWORK;
|
||||
ipcp_open(unit);
|
||||
ccp_open(unit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,10 +282,10 @@ auth_withpeer_success(unit, protocol)
|
||||
int bit;
|
||||
|
||||
switch (protocol) {
|
||||
case CHAP:
|
||||
case PPP_CHAP:
|
||||
bit = CHAP_WITHPEER;
|
||||
break;
|
||||
case UPAP:
|
||||
case PPP_PAP:
|
||||
bit = UPAP_WITHPEER;
|
||||
break;
|
||||
default:
|
||||
@ -283,10 +298,8 @@ auth_withpeer_success(unit, protocol)
|
||||
* If there is no more authentication still being done,
|
||||
* proceed to the network phase.
|
||||
*/
|
||||
if ((auth_pending[unit] &= ~bit) == 0) {
|
||||
phase = PHASE_NETWORK;
|
||||
ipcp_open(unit);
|
||||
}
|
||||
if ((auth_pending[unit] &= ~bit) == 0)
|
||||
network_phase(unit);
|
||||
}
|
||||
|
||||
|
||||
@ -386,7 +399,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
|
||||
} else {
|
||||
check_access(f, filename);
|
||||
if (scan_authfile(f, user, our_name, secret, &addrs, filename) < 0
|
||||
|| (secret[0] != 0 && strcmp(passwd, secret) != 0
|
||||
|| (secret[0] != 0 && (cryptpap || strcmp(passwd, secret) != 0)
|
||||
&& strcmp(crypt(passwd, secret), secret) != 0)) {
|
||||
syslog(LOG_WARNING, "upap authentication failure for %s", user);
|
||||
ret = UPAP_AUTHNAK;
|
||||
@ -411,7 +424,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
|
||||
*/
|
||||
if (attempts++ >= 10) {
|
||||
syslog(LOG_WARNING, "%d LOGIN FAILURES ON %s, %s",
|
||||
attempts, devname, user);
|
||||
attempts, devnam, user);
|
||||
quit();
|
||||
}
|
||||
if (attempts > 3)
|
||||
@ -452,10 +465,23 @@ login(user, passwd, msg, msglen)
|
||||
char *epasswd;
|
||||
char *tty;
|
||||
|
||||
#ifdef HAS_SHADOW
|
||||
struct spwd *spwd;
|
||||
struct spwd *getspnam();
|
||||
#endif
|
||||
|
||||
if ((pw = getpwnam(user)) == NULL) {
|
||||
return (UPAP_AUTHNAK);
|
||||
}
|
||||
|
||||
#ifdef HAS_SHADOW
|
||||
if ((spwd = getspnam(user)) == NULL) {
|
||||
pw->pw_passwd = "";
|
||||
} else {
|
||||
pw->pw_passwd = spwd->sp_pwdp;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XXX If no passwd, let them login without one.
|
||||
*/
|
||||
@ -463,21 +489,27 @@ login(user, passwd, msg, msglen)
|
||||
return (UPAP_AUTHACK);
|
||||
}
|
||||
|
||||
#ifdef HAS_SHADOW
|
||||
if ((pw->pw_passwd && pw->pw_passwd[0] == '@'
|
||||
&& pw_auth (pw->pw_passwd+1, pw->pw_name, PW_PPP, NULL))
|
||||
|| !valid (passwd, pw)) {
|
||||
return (UPAP_AUTHNAK);
|
||||
}
|
||||
#else
|
||||
epasswd = crypt(passwd, pw->pw_passwd);
|
||||
if (strcmp(epasswd, pw->pw_passwd)) {
|
||||
return (UPAP_AUTHNAK);
|
||||
}
|
||||
#endif
|
||||
|
||||
syslog(LOG_INFO, "user %s logged in", user);
|
||||
|
||||
/*
|
||||
* Write a wtmp entry for this user.
|
||||
*/
|
||||
tty = strrchr(devname, '/');
|
||||
if (tty == NULL)
|
||||
tty = devname;
|
||||
else
|
||||
tty++;
|
||||
tty = devnam;
|
||||
if (strncmp(tty, "/dev/", 5) == 0)
|
||||
tty += 5;
|
||||
logwtmp(tty, user, ""); /* Add wtmp login entry */
|
||||
logged_in = TRUE;
|
||||
|
||||
@ -492,11 +524,9 @@ logout()
|
||||
{
|
||||
char *tty;
|
||||
|
||||
tty = strrchr(devname, '/');
|
||||
if (tty == NULL)
|
||||
tty = devname;
|
||||
else
|
||||
tty++;
|
||||
tty = devnam;
|
||||
if (strncmp(tty, "/dev/", 5) == 0)
|
||||
tty += 5;
|
||||
logwtmp(tty, "", ""); /* Wipe out wtmp logout entry */
|
||||
logged_in = FALSE;
|
||||
}
|
||||
@ -688,9 +718,9 @@ get_secret(unit, client, server, secret, secret_len, save_addrs)
|
||||
int
|
||||
auth_ip_addr(unit, addr)
|
||||
int unit;
|
||||
u_long addr;
|
||||
u_int32_t addr;
|
||||
{
|
||||
u_long a;
|
||||
u_int32_t a;
|
||||
struct hostent *hp;
|
||||
struct wordlist *addrs;
|
||||
|
||||
@ -711,7 +741,7 @@ auth_ip_addr(unit, addr)
|
||||
addrs->word);
|
||||
continue;
|
||||
} else
|
||||
a = *(u_long *)hp->h_addr;
|
||||
a = *(u_int32_t *)hp->h_addr;
|
||||
}
|
||||
if (addr == a)
|
||||
return 1;
|
||||
@ -726,7 +756,7 @@ auth_ip_addr(unit, addr)
|
||||
*/
|
||||
int
|
||||
bad_ip_adrs(addr)
|
||||
u_long addr;
|
||||
u_int32_t addr;
|
||||
{
|
||||
addr = ntohl(addr);
|
||||
return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
|
||||
|
@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: chap.c,v 1.3 1994/04/18 04:01:07 paulus Exp $";
|
||||
static char rcsid[] = "$Id: chap.c,v 1.8 1995/07/04 12:32:26 paulus Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -27,30 +27,30 @@ static char rcsid[] = "$Id: chap.c,v 1.3 1994/04/18 04:01:07 paulus Exp $";
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "ppp.h"
|
||||
#include "pppd.h"
|
||||
#include "chap.h"
|
||||
#include "md5.h"
|
||||
|
||||
chap_state chap[NPPP]; /* CHAP state; one for each unit */
|
||||
chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */
|
||||
|
||||
static void ChapChallengeTimeout __ARGS((caddr_t));
|
||||
static void ChapResponseTimeout __ARGS((caddr_t));
|
||||
static void ChapReceiveChallenge __ARGS((chap_state *, u_char *, int, int));
|
||||
static void ChapReceiveResponse __ARGS((chap_state *, u_char *, int, int));
|
||||
static void ChapReceiveSuccess __ARGS((chap_state *, u_char *, int, int));
|
||||
static void ChapReceiveFailure __ARGS((chap_state *, u_char *, int, int));
|
||||
static void ChapSendStatus __ARGS((chap_state *, int));
|
||||
static void ChapSendChallenge __ARGS((chap_state *));
|
||||
static void ChapSendResponse __ARGS((chap_state *));
|
||||
static void ChapGenChallenge __ARGS((chap_state *));
|
||||
static void ChapChallengeTimeout __P((caddr_t));
|
||||
static void ChapResponseTimeout __P((caddr_t));
|
||||
static void ChapReceiveChallenge __P((chap_state *, u_char *, int, int));
|
||||
static void ChapReceiveResponse __P((chap_state *, u_char *, int, int));
|
||||
static void ChapReceiveSuccess __P((chap_state *, u_char *, int, int));
|
||||
static void ChapReceiveFailure __P((chap_state *, u_char *, int, int));
|
||||
static void ChapSendStatus __P((chap_state *, int));
|
||||
static void ChapSendChallenge __P((chap_state *));
|
||||
static void ChapSendResponse __P((chap_state *));
|
||||
static void ChapGenChallenge __P((chap_state *));
|
||||
|
||||
extern double drand48 __ARGS((void));
|
||||
extern void srand48 __ARGS((long));
|
||||
extern double drand48 __P((void));
|
||||
extern void srand48 __P((long));
|
||||
|
||||
/*
|
||||
* ChapInit - Initialize a CHAP unit.
|
||||
@ -67,7 +67,7 @@ ChapInit(unit)
|
||||
cstate->serverstate = CHAPSS_INITIAL;
|
||||
cstate->timeouttime = CHAP_DEFTIMEOUT;
|
||||
cstate->max_transmits = CHAP_DEFTRANSMITS;
|
||||
srand48((long) time(NULL)); /* joggle random number generator */
|
||||
/* random number generator is initialized in magic_init */
|
||||
}
|
||||
|
||||
|
||||
@ -148,7 +148,7 @@ ChapChallengeTimeout(arg)
|
||||
/* give up on peer */
|
||||
syslog(LOG_ERR, "Peer failed to respond to CHAP challenge");
|
||||
cstate->serverstate = CHAPSS_BADAUTH;
|
||||
auth_peer_fail(cstate->unit, CHAP);
|
||||
auth_peer_fail(cstate->unit, PPP_CHAP);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -189,9 +189,6 @@ ChapRechallenge(arg)
|
||||
ChapGenChallenge(cstate);
|
||||
ChapSendChallenge(cstate);
|
||||
cstate->serverstate = CHAPSS_RECHALLENGE;
|
||||
|
||||
if (cstate->chal_interval != 0)
|
||||
TIMEOUT(ChapRechallenge, (caddr_t) cstate, cstate->chal_interval);
|
||||
}
|
||||
|
||||
|
||||
@ -258,10 +255,10 @@ ChapProtocolReject(unit)
|
||||
|
||||
if (cstate->serverstate != CHAPSS_INITIAL &&
|
||||
cstate->serverstate != CHAPSS_CLOSED)
|
||||
auth_peer_fail(unit, CHAP);
|
||||
auth_peer_fail(unit, PPP_CHAP);
|
||||
if (cstate->clientstate != CHAPCS_INITIAL &&
|
||||
cstate->clientstate != CHAPCS_CLOSED)
|
||||
auth_withpeer_fail(unit, CHAP);
|
||||
auth_withpeer_fail(unit, PPP_CHAP);
|
||||
ChapLowerDown(unit); /* shutdown chap */
|
||||
}
|
||||
|
||||
@ -506,7 +503,7 @@ ChapReceiveResponse(cstate, inp, id, len)
|
||||
MD5Final(&mdContext);
|
||||
|
||||
/* compare local and remote MDs and send the appropriate status */
|
||||
if (bcmp (mdContext.digest, remmd, MD5_SIGNATURE_SIZE) == 0)
|
||||
if (memcmp (mdContext.digest, remmd, MD5_SIGNATURE_SIZE) == 0)
|
||||
code = CHAP_SUCCESS; /* they are the same! */
|
||||
break;
|
||||
|
||||
@ -521,7 +518,7 @@ ChapReceiveResponse(cstate, inp, id, len)
|
||||
old_state = cstate->serverstate;
|
||||
cstate->serverstate = CHAPSS_OPEN;
|
||||
if (old_state == CHAPSS_INITIAL_CHAL) {
|
||||
auth_peer_success(cstate->unit, CHAP);
|
||||
auth_peer_success(cstate->unit, PPP_CHAP);
|
||||
}
|
||||
if (cstate->chal_interval != 0)
|
||||
TIMEOUT(ChapRechallenge, (caddr_t) cstate, cstate->chal_interval);
|
||||
@ -529,7 +526,7 @@ ChapReceiveResponse(cstate, inp, id, len)
|
||||
} else {
|
||||
syslog(LOG_ERR, "CHAP peer authentication failed");
|
||||
cstate->serverstate = CHAPSS_BADAUTH;
|
||||
auth_peer_fail(cstate->unit, CHAP);
|
||||
auth_peer_fail(cstate->unit, PPP_CHAP);
|
||||
}
|
||||
}
|
||||
|
||||
@ -567,7 +564,7 @@ ChapReceiveSuccess(cstate, inp, id, len)
|
||||
|
||||
cstate->clientstate = CHAPCS_OPEN;
|
||||
|
||||
auth_withpeer_success(cstate->unit, CHAP);
|
||||
auth_withpeer_success(cstate->unit, PPP_CHAP);
|
||||
}
|
||||
|
||||
|
||||
@ -602,7 +599,7 @@ ChapReceiveFailure(cstate, inp, id, len)
|
||||
PRINTMSG(inp, len);
|
||||
|
||||
syslog(LOG_ERR, "CHAP authentication failed");
|
||||
auth_withpeer_fail(cstate->unit, CHAP);
|
||||
auth_withpeer_fail(cstate->unit, PPP_CHAP);
|
||||
}
|
||||
|
||||
|
||||
@ -622,7 +619,7 @@ ChapSendChallenge(cstate)
|
||||
outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, CHAP); /* paste in a CHAP header */
|
||||
MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */
|
||||
|
||||
PUTCHAR(CHAP_CHALLENGE, outp);
|
||||
PUTCHAR(cstate->chal_id, outp);
|
||||
@ -634,7 +631,7 @@ ChapSendChallenge(cstate)
|
||||
|
||||
BCOPY(cstate->chal_name, outp, name_len); /* append hostname */
|
||||
|
||||
output(cstate->unit, outpacket_buf, outlen + DLLHEADERLEN);
|
||||
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.", cstate->chal_id));
|
||||
|
||||
@ -664,13 +661,13 @@ ChapSendStatus(cstate, code)
|
||||
outlen = CHAP_HEADERLEN + msglen;
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, CHAP); /* paste in a header */
|
||||
MAKEHEADER(outp, PPP_CHAP); /* paste in a header */
|
||||
|
||||
PUTCHAR(code, outp);
|
||||
PUTCHAR(cstate->chal_id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
BCOPY(msg, outp, msglen);
|
||||
output(cstate->unit, outpacket_buf, outlen + DLLHEADERLEN);
|
||||
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.", code,
|
||||
cstate->chal_id));
|
||||
@ -722,7 +719,7 @@ ChapSendResponse(cstate)
|
||||
outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, CHAP);
|
||||
MAKEHEADER(outp, PPP_CHAP);
|
||||
|
||||
PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */
|
||||
PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */
|
||||
@ -735,7 +732,7 @@ ChapSendResponse(cstate)
|
||||
BCOPY(cstate->resp_name, outp, name_len); /* append our name */
|
||||
|
||||
/* send the packet */
|
||||
output(cstate->unit, outpacket_buf, outlen + DLLHEADERLEN);
|
||||
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
cstate->clientstate = CHAPCS_RESPONSE;
|
||||
TIMEOUT(ChapResponseTimeout, (caddr_t) cstate, cstate->timeouttime);
|
||||
@ -753,7 +750,7 @@ int
|
||||
ChapPrintPkt(p, plen, printer, arg)
|
||||
u_char *p;
|
||||
int plen;
|
||||
void (*printer) __ARGS((void *, char *, ...));
|
||||
void (*printer) __P((void *, char *, ...));
|
||||
void *arg;
|
||||
{
|
||||
int code, id, len;
|
||||
@ -806,18 +803,3 @@ ChapPrintPkt(p, plen, printer, arg)
|
||||
|
||||
return len + CHAP_HEADERLEN;
|
||||
}
|
||||
|
||||
#ifdef NO_DRAND48
|
||||
|
||||
double drand48()
|
||||
{
|
||||
return (double)random() / (double)0x7fffffffL; /* 2**31-1 */
|
||||
}
|
||||
|
||||
void srand48(seedval)
|
||||
long seedval;
|
||||
{
|
||||
srand((int)seedval);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -15,7 +15,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: chap.h,v 1.2 1994/04/11 07:13:44 paulus Exp $
|
||||
* $Id: chap.h,v 1.3 1994/09/21 06:47:37 paulus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CHAP_INCLUDE__
|
||||
@ -98,15 +98,15 @@ typedef struct chap_state {
|
||||
|
||||
extern chap_state chap[];
|
||||
|
||||
void ChapInit __ARGS((int));
|
||||
void ChapAuthWithPeer __ARGS((int, char *, int));
|
||||
void ChapAuthPeer __ARGS((int, char *, int));
|
||||
void ChapLowerUp __ARGS((int));
|
||||
void ChapLowerDown __ARGS((int));
|
||||
void ChapInput __ARGS((int, u_char *, int));
|
||||
void ChapProtocolReject __ARGS((int));
|
||||
int ChapPrintPkt __ARGS((u_char *, int,
|
||||
void (*) __ARGS((void *, char *, ...)), void *));
|
||||
void ChapInit __P((int));
|
||||
void ChapAuthWithPeer __P((int, char *, int));
|
||||
void ChapAuthPeer __P((int, char *, int));
|
||||
void ChapLowerUp __P((int));
|
||||
void ChapLowerDown __P((int));
|
||||
void ChapInput __P((int, u_char *, int));
|
||||
void ChapProtocolReject __P((int));
|
||||
int ChapPrintPkt __P((u_char *, int,
|
||||
void (*) __P((void *, char *, ...)), void *));
|
||||
|
||||
#define __CHAP_INCLUDE__
|
||||
#endif /* __CHAP_INCLUDE__ */
|
||||
|
@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: fsm.c,v 1.3 1994/05/24 11:21:10 paulus Exp $";
|
||||
static char rcsid[] = "$Id: fsm.c,v 1.8 1994/11/10 01:52:05 paulus Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -28,27 +28,27 @@ static char rcsid[] = "$Id: fsm.c,v 1.3 1994/05/24 11:21:10 paulus Exp $";
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "ppp.h"
|
||||
#include "pppd.h"
|
||||
#include "fsm.h"
|
||||
|
||||
extern char *proto_name();
|
||||
|
||||
static void fsm_timeout __ARGS((caddr_t));
|
||||
static void fsm_rconfreq __ARGS((fsm *, int, u_char *, int));
|
||||
static void fsm_rconfack __ARGS((fsm *, int, u_char *, int));
|
||||
static void fsm_rconfnakrej __ARGS((fsm *, int, int, u_char *, int));
|
||||
static void fsm_rtermreq __ARGS((fsm *, int));
|
||||
static void fsm_rtermack __ARGS((fsm *));
|
||||
static void fsm_rcoderej __ARGS((fsm *, u_char *, int));
|
||||
static void fsm_sconfreq __ARGS((fsm *, int));
|
||||
static void fsm_timeout __P((caddr_t));
|
||||
static void fsm_rconfreq __P((fsm *, int, u_char *, int));
|
||||
static void fsm_rconfack __P((fsm *, int, u_char *, int));
|
||||
static void fsm_rconfnakrej __P((fsm *, int, int, u_char *, int));
|
||||
static void fsm_rtermreq __P((fsm *, int));
|
||||
static void fsm_rtermack __P((fsm *));
|
||||
static void fsm_rcoderej __P((fsm *, u_char *, int));
|
||||
static void fsm_sconfreq __P((fsm *, int));
|
||||
|
||||
#define PROTO_NAME(f) ((f)->callbacks->proto_name)
|
||||
|
||||
int peer_mru[NPPP];
|
||||
int peer_mru[NUM_PPP];
|
||||
|
||||
|
||||
/*
|
||||
@ -446,15 +446,16 @@ fsm_rconfack(f, id, inp, len)
|
||||
FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d.",
|
||||
PROTO_NAME(f), id));
|
||||
|
||||
if (id != f->reqid) /* Expected id? */
|
||||
return; /* Nope, toss... */
|
||||
if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): (len == 0)) ){
|
||||
if (id != f->reqid || f->seen_ack) /* Expected id? */
|
||||
return; /* Nope, toss... */
|
||||
if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
|
||||
(len == 0)) ){
|
||||
/* Ack is bad - ignore it */
|
||||
FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)",
|
||||
PROTO_NAME(f), len));
|
||||
return;
|
||||
}
|
||||
f->reqid = -1;
|
||||
f->seen_ack = 1;
|
||||
|
||||
switch (f->state) {
|
||||
case CLOSED:
|
||||
@ -468,7 +469,8 @@ fsm_rconfack(f, id, inp, len)
|
||||
break;
|
||||
|
||||
case ACKRCVD:
|
||||
/* Huh? an extra Ack? oh well... */
|
||||
/* Huh? an extra valid Ack? oh well... */
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
|
||||
fsm_sconfreq(f, 0);
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
@ -507,16 +509,16 @@ fsm_rconfnakrej(f, code, id, inp, len)
|
||||
FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d.",
|
||||
PROTO_NAME(f), id));
|
||||
|
||||
if (id != f->reqid) /* Expected id? */
|
||||
return; /* Nope, toss... */
|
||||
if (id != f->reqid || f->seen_ack) /* Expected id? */
|
||||
return; /* Nope, toss... */
|
||||
proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
|
||||
if( !proc || !proc(f, inp, len) ){
|
||||
if (!proc || !proc(f, inp, len)) {
|
||||
/* Nak/reject is bad - ignore it */
|
||||
FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)",
|
||||
PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
|
||||
return;
|
||||
}
|
||||
f->reqid = -1;
|
||||
f->seen_ack = 1;
|
||||
|
||||
switch (f->state) {
|
||||
case CLOSED:
|
||||
@ -533,6 +535,7 @@ fsm_rconfnakrej(f, code, id, inp, len)
|
||||
|
||||
case ACKRCVD:
|
||||
/* Got a Nak/reject when we had already had an Ack?? oh well... */
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
|
||||
fsm_sconfreq(f, 0);
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
@ -590,11 +593,13 @@ fsm_rtermack(f)
|
||||
|
||||
switch (f->state) {
|
||||
case CLOSING:
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f);
|
||||
f->state = CLOSED;
|
||||
if( f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
break;
|
||||
case STOPPING:
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f);
|
||||
f->state = STOPPED;
|
||||
if( f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
@ -715,10 +720,12 @@ fsm_sconfreq(f, retransmit)
|
||||
f->reqid = ++f->id;
|
||||
}
|
||||
|
||||
f->seen_ack = 0;
|
||||
|
||||
/*
|
||||
* Make up the request packet
|
||||
*/
|
||||
outp = outpacket_buf + DLLHEADERLEN + HEADERLEN;
|
||||
outp = outpacket_buf + PPP_HDRLEN + HEADERLEN;
|
||||
if( f->callbacks->cilen && f->callbacks->addci ){
|
||||
cilen = (*f->callbacks->cilen)(f);
|
||||
if( cilen > peer_mru[f->unit] - HEADERLEN )
|
||||
@ -759,14 +766,14 @@ fsm_sdata(f, code, id, data, datalen)
|
||||
outp = outpacket_buf;
|
||||
if (datalen > peer_mru[f->unit] - HEADERLEN)
|
||||
datalen = peer_mru[f->unit] - HEADERLEN;
|
||||
if (datalen && data != outp + DLLHEADERLEN + HEADERLEN)
|
||||
BCOPY(data, outp + DLLHEADERLEN + HEADERLEN, datalen);
|
||||
if (datalen && data != outp + PPP_HDRLEN + HEADERLEN)
|
||||
BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);
|
||||
outlen = datalen + HEADERLEN;
|
||||
MAKEHEADER(outp, f->protocol);
|
||||
PUTCHAR(code, outp);
|
||||
PUTCHAR(id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
output(f->unit, outpacket_buf, outlen + DLLHEADERLEN);
|
||||
output(f->unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d, id %d.",
|
||||
PROTO_NAME(f), code, id));
|
||||
|
@ -16,7 +16,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: fsm.h,v 1.2 1994/04/11 07:18:35 paulus Exp $
|
||||
* $Id: fsm.h,v 1.5 1995/05/19 03:17:35 paulus Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -66,6 +66,7 @@ typedef struct fsm {
|
||||
int flags; /* Contains option bits */
|
||||
u_char id; /* Current id */
|
||||
u_char reqid; /* Current request id */
|
||||
u_char seen_ack; /* Have received valid Ack/Nak/Rej to Req */
|
||||
int timeouttime; /* Timeout time in milliseconds */
|
||||
int maxconfreqtransmits; /* Maximum Configure-Request transmissions */
|
||||
int retransmits; /* Number of retransmissions left */
|
||||
@ -105,20 +106,20 @@ typedef struct fsm {
|
||||
#define DEFTIMEOUT 3 /* Timeout time in seconds */
|
||||
#define DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */
|
||||
#define DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */
|
||||
#define DEFMAXNAKLOOPS 10 /* Maximum number of nak loops */
|
||||
#define DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */
|
||||
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
void fsm_init __ARGS((fsm *));
|
||||
void fsm_lowerup __ARGS((fsm *));
|
||||
void fsm_lowerdown __ARGS((fsm *));
|
||||
void fsm_open __ARGS((fsm *));
|
||||
void fsm_close __ARGS((fsm *));
|
||||
void fsm_input __ARGS((fsm *, u_char *, int));
|
||||
void fsm_protreject __ARGS((fsm *));
|
||||
void fsm_sdata __ARGS((fsm *, int, int, u_char *, int));
|
||||
void fsm_init __P((fsm *));
|
||||
void fsm_lowerup __P((fsm *));
|
||||
void fsm_lowerdown __P((fsm *));
|
||||
void fsm_open __P((fsm *));
|
||||
void fsm_close __P((fsm *));
|
||||
void fsm_input __P((fsm *, u_char *, int));
|
||||
void fsm_protreject __P((fsm *));
|
||||
void fsm_sdata __P((fsm *, int, int, u_char *, int));
|
||||
|
||||
|
||||
/*
|
||||
|
@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: ipcp.c,v 1.8 1994/05/26 06:37:34 paulus Exp $";
|
||||
static char rcsid[] = "$Id: ipcp.c,v 1.20 1995/08/10 06:51:04 paulus Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -30,41 +30,37 @@ static char rcsid[] = "$Id: ipcp.c,v 1.8 1994/05/26 06:37:34 paulus Exp $";
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "ppp.h"
|
||||
#include "fsm.h"
|
||||
#include "ipcp.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
/* global vars */
|
||||
ipcp_options ipcp_wantoptions[NPPP]; /* Options that we want to request */
|
||||
ipcp_options ipcp_gotoptions[NPPP]; /* Options that peer ack'd */
|
||||
ipcp_options ipcp_allowoptions[NPPP]; /* Options we allow peer to request */
|
||||
ipcp_options ipcp_hisoptions[NPPP]; /* Options that we ack'd */
|
||||
|
||||
extern char ifname[];
|
||||
extern char devname[];
|
||||
extern int baud_rate;
|
||||
ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */
|
||||
ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
|
||||
ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
|
||||
ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
|
||||
|
||||
/* local vars */
|
||||
static int cis_received[NPPP]; /* # Conf-Reqs received */
|
||||
static int cis_received[NUM_PPP]; /* # Conf-Reqs received */
|
||||
|
||||
/*
|
||||
* Callbacks for fsm code. (CI = Configuration Information)
|
||||
*/
|
||||
static void ipcp_resetci __ARGS((fsm *)); /* Reset our CI */
|
||||
static int ipcp_cilen __ARGS((fsm *)); /* Return length of our CI */
|
||||
static void ipcp_addci __ARGS((fsm *, u_char *, int *)); /* Add our CI */
|
||||
static int ipcp_ackci __ARGS((fsm *, u_char *, int)); /* Peer ack'd our CI */
|
||||
static int ipcp_nakci __ARGS((fsm *, u_char *, int)); /* Peer nak'd our CI */
|
||||
static int ipcp_rejci __ARGS((fsm *, u_char *, int)); /* Peer rej'd our CI */
|
||||
static int ipcp_reqci __ARGS((fsm *, u_char *, int *, int)); /* Rcv CI */
|
||||
static void ipcp_up __ARGS((fsm *)); /* We're UP */
|
||||
static void ipcp_down __ARGS((fsm *)); /* We're DOWN */
|
||||
static void ipcp_script __ARGS((fsm *, char *)); /* Run an up/down script */
|
||||
static void ipcp_resetci __P((fsm *)); /* Reset our CI */
|
||||
static int ipcp_cilen __P((fsm *)); /* Return length of our CI */
|
||||
static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
|
||||
static int ipcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
|
||||
static int ipcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */
|
||||
static int ipcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
|
||||
static int ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
|
||||
static void ipcp_up __P((fsm *)); /* We're UP */
|
||||
static void ipcp_down __P((fsm *)); /* We're DOWN */
|
||||
static void ipcp_script __P((fsm *, char *)); /* Run an up/down script */
|
||||
|
||||
fsm ipcp_fsm[NPPP]; /* IPCP fsm structure */
|
||||
fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */
|
||||
|
||||
static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
|
||||
ipcp_resetci, /* Reset our Configuration Information */
|
||||
@ -103,7 +99,7 @@ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
|
||||
*/
|
||||
char *
|
||||
ip_ntoa(ipaddr)
|
||||
u_long ipaddr;
|
||||
u_int32_t ipaddr;
|
||||
{
|
||||
static char b[64];
|
||||
|
||||
@ -130,7 +126,7 @@ ipcp_init(unit)
|
||||
ipcp_options *ao = &ipcp_allowoptions[unit];
|
||||
|
||||
f->unit = unit;
|
||||
f->protocol = IPCP;
|
||||
f->protocol = PPP_IPCP;
|
||||
f->callbacks = &ipcp_callbacks;
|
||||
fsm_init(&ipcp_fsm[unit]);
|
||||
|
||||
@ -296,7 +292,7 @@ ipcp_addci(f, ucp, lenp)
|
||||
if (neg) { \
|
||||
int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
|
||||
if (len >= addrlen) { \
|
||||
u_long l; \
|
||||
u_int32_t l; \
|
||||
PUTCHAR(opt, ucp); \
|
||||
PUTCHAR(addrlen, ucp); \
|
||||
l = ntohl(val1); \
|
||||
@ -359,7 +355,7 @@ ipcp_ackci(f, p, len)
|
||||
{
|
||||
ipcp_options *go = &ipcp_gotoptions[f->unit];
|
||||
u_short cilen, citype, cishort;
|
||||
u_long cilong;
|
||||
u_int32_t cilong;
|
||||
u_char cimaxslotindex, cicflag;
|
||||
|
||||
/*
|
||||
@ -394,7 +390,7 @@ ipcp_ackci(f, p, len)
|
||||
#define ACKCIADDR(opt, neg, old, val1, val2) \
|
||||
if (neg) { \
|
||||
int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
|
||||
u_long l; \
|
||||
u_int32_t l; \
|
||||
if ((len -= addrlen) < 0) \
|
||||
goto bad; \
|
||||
GETCHAR(citype, p); \
|
||||
@ -451,7 +447,7 @@ ipcp_nakci(f, p, len)
|
||||
u_char cimaxslotindex, cicflag;
|
||||
u_char citype, cilen, *next;
|
||||
u_short cishort;
|
||||
u_long ciaddr1, ciaddr2, l;
|
||||
u_int32_t ciaddr1, ciaddr2, l;
|
||||
ipcp_options no; /* options we've seen Naks for */
|
||||
ipcp_options try; /* options to request next time */
|
||||
|
||||
@ -498,7 +494,7 @@ ipcp_nakci(f, p, len)
|
||||
* Accept the peer's idea of {our,his} address, if different
|
||||
* from our idea, only if the accept_{local,remote} flag is set.
|
||||
*/
|
||||
NAKCIADDR(CI_ADDR, neg_addr, go->old_addrs,
|
||||
NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,
|
||||
if (go->accept_local && ciaddr1) { /* Do we know our address? */
|
||||
try.ouraddr = ciaddr1;
|
||||
IPCPDEBUG((LOG_INFO, "local IP address %s",
|
||||
@ -579,16 +575,15 @@ ipcp_nakci(f, p, len)
|
||||
case CI_ADDR:
|
||||
if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR)
|
||||
goto bad;
|
||||
try.neg_addr = 1;
|
||||
try.old_addrs = 0;
|
||||
GETLONG(l, p);
|
||||
ciaddr1 = htonl(l);
|
||||
if (ciaddr1 && go->accept_local)
|
||||
try.ouraddr = ciaddr1;
|
||||
if (try.ouraddr != 0)
|
||||
try.neg_addr = 1;
|
||||
no.neg_addr = 1;
|
||||
break;
|
||||
default:
|
||||
goto bad;
|
||||
}
|
||||
p = next;
|
||||
}
|
||||
@ -623,7 +618,7 @@ ipcp_rejci(f, p, len)
|
||||
ipcp_options *go = &ipcp_gotoptions[f->unit];
|
||||
u_char cimaxslotindex, ciflag, cilen;
|
||||
u_short cishort;
|
||||
u_long cilong;
|
||||
u_int32_t cilong;
|
||||
ipcp_options try; /* options to request next time */
|
||||
|
||||
try = *go;
|
||||
@ -637,7 +632,7 @@ ipcp_rejci(f, p, len)
|
||||
len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \
|
||||
p[1] == cilen && \
|
||||
p[0] == opt) { \
|
||||
u_long l; \
|
||||
u_int32_t l; \
|
||||
len -= cilen; \
|
||||
INCPTR(2, p); \
|
||||
GETLONG(l, p); \
|
||||
@ -722,7 +717,7 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
|
||||
u_char *cip, *next; /* Pointer to current and next CIs */
|
||||
u_short cilen, citype; /* Parsed len, type */
|
||||
u_short cishort; /* Parsed short value */
|
||||
u_long tl, ciaddr1, ciaddr2;/* Parsed address values */
|
||||
u_int32_t tl, ciaddr1, ciaddr2;/* Parsed address values */
|
||||
int rc = CONFACK; /* Final packet return code */
|
||||
int orc; /* Individual option return code */
|
||||
u_char *p; /* Pointer to next char to parse */
|
||||
@ -778,10 +773,17 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
|
||||
&& (ciaddr1 == 0 || !wo->accept_remote)) {
|
||||
orc = CONFNAK;
|
||||
if (!reject_if_disagree) {
|
||||
DECPTR(sizeof (long), p);
|
||||
DECPTR(sizeof(u_int32_t), p);
|
||||
tl = ntohl(wo->hisaddr);
|
||||
PUTLONG(tl, p);
|
||||
}
|
||||
} else if (ciaddr1 == 0 && wo->hisaddr == 0) {
|
||||
/*
|
||||
* If neither we nor he knows his address, reject the option.
|
||||
*/
|
||||
orc = CONFREJ;
|
||||
wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -795,7 +797,7 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
|
||||
if (ciaddr2 == 0 || !wo->accept_local) {
|
||||
orc = CONFNAK;
|
||||
if (!reject_if_disagree) {
|
||||
DECPTR(sizeof (long), p);
|
||||
DECPTR(sizeof(u_int32_t), p);
|
||||
tl = ntohl(wo->ouraddr);
|
||||
PUTLONG(tl, p);
|
||||
}
|
||||
@ -832,10 +834,17 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
|
||||
&& (ciaddr1 == 0 || !wo->accept_remote)) {
|
||||
orc = CONFNAK;
|
||||
if (!reject_if_disagree) {
|
||||
DECPTR(sizeof (long), p);
|
||||
DECPTR(sizeof(u_int32_t), p);
|
||||
tl = ntohl(wo->hisaddr);
|
||||
PUTLONG(tl, p);
|
||||
}
|
||||
} else if (ciaddr1 == 0 && wo->hisaddr == 0) {
|
||||
/*
|
||||
* Don't ACK an address of 0.0.0.0 - reject it instead.
|
||||
*/
|
||||
orc = CONFREJ;
|
||||
wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
|
||||
break;
|
||||
}
|
||||
|
||||
ho->neg_addr = 1;
|
||||
@ -878,7 +887,7 @@ ipcp_reqci(f, inp, len, reject_if_disagree)
|
||||
}
|
||||
}
|
||||
ho->maxslotindex = maxslotindex;
|
||||
ho->cflag = wo->cflag;
|
||||
ho->cflag = cflag;
|
||||
} else {
|
||||
ho->old_vj = 1;
|
||||
ho->maxslotindex = MAX_STATES - 1;
|
||||
@ -960,7 +969,7 @@ static void
|
||||
ipcp_up(f)
|
||||
fsm *f;
|
||||
{
|
||||
u_long mask;
|
||||
u_int32_t mask;
|
||||
ipcp_options *ho = &ipcp_hisoptions[f->unit];
|
||||
ipcp_options *go = &ipcp_gotoptions[f->unit];
|
||||
|
||||
@ -1047,7 +1056,7 @@ static void
|
||||
ipcp_down(f)
|
||||
fsm *f;
|
||||
{
|
||||
u_long ouraddr, hisaddr;
|
||||
u_int32_t ouraddr, hisaddr;
|
||||
|
||||
IPCPDEBUG((LOG_INFO, "ipcp: down"));
|
||||
|
||||
@ -1083,11 +1092,12 @@ ipcp_script(f, script)
|
||||
|
||||
argv[0] = script;
|
||||
argv[1] = ifname;
|
||||
argv[2] = devname;
|
||||
argv[2] = devnam;
|
||||
argv[3] = strspeed;
|
||||
argv[4] = strlocal;
|
||||
argv[5] = strremote;
|
||||
argv[6] = NULL;
|
||||
argv[6] = ipparam;
|
||||
argv[7] = NULL;
|
||||
run_program(script, argv, 0);
|
||||
}
|
||||
|
||||
@ -1109,7 +1119,7 @@ ipcp_printpkt(p, plen, printer, arg)
|
||||
int code, id, len, olen;
|
||||
u_char *pstart, *optend;
|
||||
u_short cishort;
|
||||
u_long cilong;
|
||||
u_int32_t cilong;
|
||||
|
||||
if (plen < HEADERLEN)
|
||||
return 0;
|
||||
|
@ -16,7 +16,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ipcp.h,v 1.3 1994/04/18 04:05:15 paulus Exp $
|
||||
* $Id: ipcp.h,v 1.5 1994/09/21 06:47:37 paulus Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -49,7 +49,7 @@ typedef struct ipcp_options {
|
||||
int accept_remote : 1; /* accept peer's value for hisaddr */
|
||||
u_short vj_protocol; /* protocol value to use in VJ option */
|
||||
u_char maxslotindex, cflag; /* values for RFC1332 VJ compression neg. */
|
||||
u_long ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */
|
||||
u_int32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */
|
||||
} ipcp_options;
|
||||
|
||||
extern fsm ipcp_fsm[];
|
||||
@ -58,11 +58,11 @@ extern ipcp_options ipcp_gotoptions[];
|
||||
extern ipcp_options ipcp_allowoptions[];
|
||||
extern ipcp_options ipcp_hisoptions[];
|
||||
|
||||
void ipcp_init __ARGS((int));
|
||||
void ipcp_open __ARGS((int));
|
||||
void ipcp_close __ARGS((int));
|
||||
void ipcp_lowerup __ARGS((int));
|
||||
void ipcp_lowerdown __ARGS((int));
|
||||
void ipcp_input __ARGS((int, u_char *, int));
|
||||
void ipcp_protrej __ARGS((int));
|
||||
int ipcp_printpkt __ARGS((u_char *, int, void (*)(), void *));
|
||||
void ipcp_init __P((int));
|
||||
void ipcp_open __P((int));
|
||||
void ipcp_close __P((int));
|
||||
void ipcp_lowerup __P((int));
|
||||
void ipcp_lowerdown __P((int));
|
||||
void ipcp_input __P((int, u_char *, int));
|
||||
void ipcp_protrej __P((int));
|
||||
int ipcp_printpkt __P((u_char *, int, void (*)(), void *));
|
||||
|
@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: lcp.c,v 1.8 1994/05/30 02:38:49 paulus Exp $";
|
||||
static char rcsid[] = "$Id: lcp.c,v 1.21 1995/08/10 06:51:06 paulus Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -36,7 +36,6 @@ static char rcsid[] = "$Id: lcp.c,v 1.8 1994/05/30 02:38:49 paulus Exp $";
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "ppp.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "magic.h"
|
||||
@ -45,51 +44,56 @@ static char rcsid[] = "$Id: lcp.c,v 1.8 1994/05/30 02:38:49 paulus Exp $";
|
||||
#include "ipcp.h"
|
||||
|
||||
#ifdef _linux_ /* Needs ppp ioctls */
|
||||
#include <linux/ppp.h>
|
||||
#include <net/if.h>
|
||||
#include <linux/if_ppp.h>
|
||||
#endif
|
||||
|
||||
/* global vars */
|
||||
fsm lcp_fsm[NPPP]; /* LCP fsm structure (global)*/
|
||||
lcp_options lcp_wantoptions[NPPP]; /* Options that we want to request */
|
||||
lcp_options lcp_gotoptions[NPPP]; /* Options that peer ack'd */
|
||||
lcp_options lcp_allowoptions[NPPP]; /* Options we allow peer to request */
|
||||
lcp_options lcp_hisoptions[NPPP]; /* Options that we ack'd */
|
||||
u_long xmit_accm[NPPP][8]; /* extended transmit ACCM */
|
||||
fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/
|
||||
lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */
|
||||
lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
|
||||
lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
|
||||
lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
|
||||
u_int32_t xmit_accm[NUM_PPP][8]; /* extended transmit ACCM */
|
||||
|
||||
static u_long lcp_echos_pending = 0; /* Number of outstanding echo msgs */
|
||||
static u_long lcp_echo_number = 0; /* ID number of next echo frame */
|
||||
static u_long lcp_echo_timer_running = 0; /* TRUE if a timer is running */
|
||||
static u_int32_t lcp_echos_pending = 0; /* Number of outstanding echo msgs */
|
||||
static u_int32_t lcp_echo_number = 0; /* ID number of next echo frame */
|
||||
static u_int32_t lcp_echo_timer_running = 0; /* TRUE if a timer is running */
|
||||
|
||||
u_long lcp_echo_interval = 0;
|
||||
u_long lcp_echo_fails = 0;
|
||||
static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */
|
||||
|
||||
#ifdef _linux_
|
||||
u_int32_t idle_timer_running = 0;
|
||||
extern int idle_time_limit;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Callbacks for fsm code. (CI = Configuration Information)
|
||||
*/
|
||||
static void lcp_resetci __ARGS((fsm *)); /* Reset our CI */
|
||||
static int lcp_cilen __ARGS((fsm *)); /* Return length of our CI */
|
||||
static void lcp_addci __ARGS((fsm *, u_char *, int *)); /* Add our CI to pkt */
|
||||
static int lcp_ackci __ARGS((fsm *, u_char *, int)); /* Peer ack'd our CI */
|
||||
static int lcp_nakci __ARGS((fsm *, u_char *, int)); /* Peer nak'd our CI */
|
||||
static int lcp_rejci __ARGS((fsm *, u_char *, int)); /* Peer rej'd our CI */
|
||||
static int lcp_reqci __ARGS((fsm *, u_char *, int *, int)); /* Rcv peer CI */
|
||||
static void lcp_up __ARGS((fsm *)); /* We're UP */
|
||||
static void lcp_down __ARGS((fsm *)); /* We're DOWN */
|
||||
static void lcp_starting __ARGS((fsm *)); /* We need lower layer up */
|
||||
static void lcp_finished __ARGS((fsm *)); /* We need lower layer down */
|
||||
static int lcp_extcode __ARGS((fsm *, int, int, u_char *, int));
|
||||
static void lcp_rprotrej __ARGS((fsm *, u_char *, int));
|
||||
static void lcp_resetci __P((fsm *)); /* Reset our CI */
|
||||
static int lcp_cilen __P((fsm *)); /* Return length of our CI */
|
||||
static void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */
|
||||
static int lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
|
||||
static int lcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */
|
||||
static int lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
|
||||
static int lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */
|
||||
static void lcp_up __P((fsm *)); /* We're UP */
|
||||
static void lcp_down __P((fsm *)); /* We're DOWN */
|
||||
static void lcp_starting __P((fsm *)); /* We need lower layer up */
|
||||
static void lcp_finished __P((fsm *)); /* We need lower layer down */
|
||||
static int lcp_extcode __P((fsm *, int, int, u_char *, int));
|
||||
static void lcp_rprotrej __P((fsm *, u_char *, int));
|
||||
|
||||
/*
|
||||
* routines to send LCP echos to peer
|
||||
*/
|
||||
|
||||
static void lcp_echo_lowerup __ARGS((int));
|
||||
static void lcp_echo_lowerdown __ARGS((int));
|
||||
static void LcpEchoTimeout __ARGS((caddr_t));
|
||||
static void lcp_received_echo_reply __ARGS((fsm *, int, u_char *, int));
|
||||
static void LcpSendEchoRequest __ARGS((fsm *));
|
||||
static void LcpLinkFailure __ARGS((fsm *));
|
||||
static void lcp_echo_lowerup __P((int));
|
||||
static void lcp_echo_lowerdown __P((int));
|
||||
static void LcpEchoTimeout __P((caddr_t));
|
||||
static void lcp_received_echo_reply __P((fsm *, int, u_char *, int));
|
||||
static void LcpSendEchoRequest __P((fsm *));
|
||||
static void LcpLinkFailure __P((fsm *));
|
||||
|
||||
static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
|
||||
lcp_resetci, /* Reset our Configuration Information */
|
||||
@ -109,7 +113,7 @@ static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
|
||||
"LCP" /* String name of protocol */
|
||||
};
|
||||
|
||||
int lcp_warnloops = DEFWARNLOOPS; /* Warn about a loopback this often */
|
||||
int lcp_loopbackfail = DEFLOOPBACKFAIL;
|
||||
|
||||
/*
|
||||
* Length of each type of configuration option (in octets)
|
||||
@ -136,7 +140,7 @@ lcp_init(unit)
|
||||
lcp_options *ao = &lcp_allowoptions[unit];
|
||||
|
||||
f->unit = unit;
|
||||
f->protocol = LCP;
|
||||
f->protocol = PPP_LCP;
|
||||
f->callbacks = &lcp_callbacks;
|
||||
|
||||
fsm_init(f);
|
||||
@ -216,6 +220,58 @@ lcp_close(unit)
|
||||
fsm_close(&lcp_fsm[unit]);
|
||||
}
|
||||
|
||||
#ifdef _linux_
|
||||
static void IdleTimeCheck __P((caddr_t));
|
||||
|
||||
/*
|
||||
* Timer expired for the LCP echo requests from this process.
|
||||
*/
|
||||
|
||||
static void
|
||||
RestartIdleTimer (f)
|
||||
fsm *f;
|
||||
{
|
||||
u_long delta;
|
||||
struct ppp_idle ddinfo;
|
||||
/*
|
||||
* Read the time since the last packet was received.
|
||||
*/
|
||||
if (ioctl (fd, PPPIOCGIDLE, &ddinfo) < 0) {
|
||||
syslog (LOG_ERR, "ioctl(PPPIOCGIDLE): %m");
|
||||
die (1);
|
||||
}
|
||||
/*
|
||||
* Compute the time since the last packet was received. If the timer
|
||||
* has expired then disconnect the line.
|
||||
*/
|
||||
delta = idle_time_limit - (u_long) ddinfo.recv_idle;
|
||||
if (((int) delta <= 0L) && (f->state == OPENED)) {
|
||||
syslog (LOG_NOTICE, "No IP frames received within idle time limit");
|
||||
lcp_close(f->unit); /* Reset connection */
|
||||
phase = PHASE_TERMINATE; /* Mark it down */
|
||||
} else {
|
||||
if ((int) delta <= 0L)
|
||||
delta = (u_long) idle_time_limit;
|
||||
assert (idle_timer_running==0);
|
||||
TIMEOUT (IdleTimeCheck, (caddr_t) f, delta);
|
||||
idle_timer_running = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* IdleTimeCheck - Timer expired on the IDLE detection for IP frames
|
||||
*/
|
||||
|
||||
static void
|
||||
IdleTimeCheck (arg)
|
||||
caddr_t arg;
|
||||
{
|
||||
if (idle_timer_running != 0) {
|
||||
idle_timer_running = 0;
|
||||
RestartIdleTimer ((fsm *) arg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* lcp_lowerup - The lower layer is up.
|
||||
@ -226,9 +282,9 @@ lcp_lowerup(unit)
|
||||
{
|
||||
sifdown(unit);
|
||||
ppp_set_xaccm(unit, xmit_accm[unit]);
|
||||
ppp_send_config(unit, MTU, 0xffffffff, 0, 0);
|
||||
ppp_recv_config(unit, MTU, 0x00000000, 0, 0);
|
||||
peer_mru[unit] = MTU;
|
||||
ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0);
|
||||
ppp_recv_config(unit, PPP_MRU, 0x00000000, 0, 0);
|
||||
peer_mru[unit] = PPP_MRU;
|
||||
lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0];
|
||||
|
||||
fsm_lowerup(&lcp_fsm[unit]);
|
||||
@ -255,7 +311,23 @@ lcp_input(unit, p, len)
|
||||
u_char *p;
|
||||
int len;
|
||||
{
|
||||
fsm_input(&lcp_fsm[unit], p, len);
|
||||
int oldstate;
|
||||
fsm *f = &lcp_fsm[unit];
|
||||
lcp_options *go = &lcp_gotoptions[f->unit];
|
||||
|
||||
oldstate = f->state;
|
||||
fsm_input(f, p, len);
|
||||
if (oldstate == REQSENT && f->state == ACKSENT) {
|
||||
/*
|
||||
* The peer will probably send us an ack soon and then
|
||||
* immediately start sending packets with the negotiated
|
||||
* options. So as to be ready when that happens, we set
|
||||
* our receive side to accept packets as negotiated now.
|
||||
*/
|
||||
ppp_recv_config(f->unit, PPP_MRU,
|
||||
go->neg_asyncmap? go->asyncmap: 0x00000000,
|
||||
go->neg_pcompression, go->neg_accompression);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -282,8 +354,6 @@ lcp_extcode(f, code, id, inp, len)
|
||||
LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d", id));
|
||||
magp = inp;
|
||||
PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
|
||||
if (len < CILEN_LONG)
|
||||
len = CILEN_LONG;
|
||||
fsm_sdata(f, ECHOREP, id, inp, len);
|
||||
break;
|
||||
|
||||
@ -390,7 +460,7 @@ fsm *f;
|
||||
lcp_wantoptions[f->unit].magicnumber = magic();
|
||||
lcp_wantoptions[f->unit].numloops = 0;
|
||||
lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];
|
||||
peer_mru[f->unit] = MTU;
|
||||
peer_mru[f->unit] = PPP_MRU;
|
||||
}
|
||||
|
||||
|
||||
@ -463,14 +533,14 @@ lcp_addci(f, ucp, lenp)
|
||||
if (neg) { \
|
||||
PUTCHAR(opt, ucp); \
|
||||
PUTCHAR(CILEN_LQR, ucp); \
|
||||
PUTSHORT(LQR, ucp); \
|
||||
PUTSHORT(PPP_LQR, ucp); \
|
||||
PUTLONG(val, ucp); \
|
||||
}
|
||||
|
||||
ADDCISHORT(CI_MRU, go->neg_mru, go->mru);
|
||||
ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap, go->asyncmap);
|
||||
ADDCICHAP(CI_AUTHTYPE, go->neg_chap, CHAP, go->chap_mdtype);
|
||||
ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, UPAP);
|
||||
ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
|
||||
ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
|
||||
ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
|
||||
ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
|
||||
ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
|
||||
@ -500,7 +570,7 @@ lcp_ackci(f, p, len)
|
||||
lcp_options *go = &lcp_gotoptions[f->unit];
|
||||
u_char cilen, citype, cichar;
|
||||
u_short cishort;
|
||||
u_long cilong;
|
||||
u_int32_t cilong;
|
||||
|
||||
/*
|
||||
* CIs must be in exactly the same order that we sent.
|
||||
@ -569,7 +639,7 @@ lcp_ackci(f, p, len)
|
||||
citype != opt) \
|
||||
goto bad; \
|
||||
GETSHORT(cishort, p); \
|
||||
if (cishort != LQR) \
|
||||
if (cishort != PPP_LQR) \
|
||||
goto bad; \
|
||||
GETLONG(cilong, p); \
|
||||
if (cilong != val) \
|
||||
@ -578,8 +648,8 @@ lcp_ackci(f, p, len)
|
||||
|
||||
ACKCISHORT(CI_MRU, go->neg_mru, go->mru);
|
||||
ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap, go->asyncmap);
|
||||
ACKCICHAP(CI_AUTHTYPE, go->neg_chap, CHAP, go->chap_mdtype);
|
||||
ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, UPAP);
|
||||
ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
|
||||
ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
|
||||
ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
|
||||
ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
|
||||
ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
|
||||
@ -614,12 +684,13 @@ lcp_nakci(f, p, len)
|
||||
{
|
||||
lcp_options *go = &lcp_gotoptions[f->unit];
|
||||
lcp_options *wo = &lcp_wantoptions[f->unit];
|
||||
u_char cilen, citype, cichar, *next;
|
||||
u_char citype, cichar, *next;
|
||||
u_short cishort;
|
||||
u_long cilong;
|
||||
u_int32_t cilong;
|
||||
lcp_options no; /* options we've seen Naks for */
|
||||
lcp_options try; /* options to request next time */
|
||||
int looped_back = 0;
|
||||
int cilen;
|
||||
|
||||
BZERO(&no, sizeof(no));
|
||||
try = *go;
|
||||
@ -697,21 +768,67 @@ lcp_nakci(f, p, len)
|
||||
if (cishort <= wo->mru || cishort < DEFMRU)
|
||||
try.mru = cishort;
|
||||
);
|
||||
|
||||
/*
|
||||
* Add any characters they want to our (receive-side) asyncmap.
|
||||
*/
|
||||
NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
|
||||
try.asyncmap = go->asyncmap | cilong;
|
||||
);
|
||||
|
||||
/*
|
||||
* If they can't cope with our CHAP hash algorithm, we'll have
|
||||
* to stop asking for CHAP. We haven't got any other algorithm.
|
||||
* If they've nak'd our authentication-protocol, check whether
|
||||
* they are proposing a different protocol, or a different
|
||||
* hash algorithm for CHAP.
|
||||
*/
|
||||
NAKCICHAP(CI_AUTHTYPE, neg_chap,
|
||||
try.neg_chap = 0;
|
||||
);
|
||||
if ((go->neg_chap || go->neg_upap)
|
||||
&& len >= CILEN_SHORT
|
||||
&& p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT) {
|
||||
cilen = p[1];
|
||||
INCPTR(2, p);
|
||||
GETSHORT(cishort, p);
|
||||
if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
|
||||
/*
|
||||
* If they are asking for PAP, then they don't want to do CHAP.
|
||||
* If we weren't asking for CHAP, then we were asking for PAP,
|
||||
* in which case this Nak is bad.
|
||||
*/
|
||||
if (!go->neg_chap)
|
||||
goto bad;
|
||||
go->neg_chap = 0;
|
||||
|
||||
} else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
|
||||
GETCHAR(cichar, p);
|
||||
if (go->neg_chap) {
|
||||
/*
|
||||
* We were asking for CHAP/MD5; they must want a different
|
||||
* algorithm. If they can't do MD5, we'll have to stop
|
||||
* asking for CHAP.
|
||||
*/
|
||||
if (cichar != go->chap_mdtype)
|
||||
go->neg_chap = 0;
|
||||
} else {
|
||||
/*
|
||||
* Stop asking for PAP if we were asking for it.
|
||||
*/
|
||||
go->neg_upap = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
/*
|
||||
* We don't recognize what they're suggesting.
|
||||
* Stop asking for what we were asking for.
|
||||
*/
|
||||
if (go->neg_chap)
|
||||
go->neg_chap = 0;
|
||||
else
|
||||
go->neg_upap = 0;
|
||||
p += cilen - CILEN_SHORT;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Peer shouldn't send Nak for UPAP, protocol compression or
|
||||
* Peer shouldn't send Nak for protocol compression or
|
||||
* address/control compression requests; they should send
|
||||
* a Reject instead. If they send a Nak, treat it as a Reject.
|
||||
*/
|
||||
@ -720,23 +837,24 @@ lcp_nakci(f, p, len)
|
||||
try.neg_upap = 0;
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* If they can't cope with our link quality protocol, we'll have
|
||||
* to stop asking for LQR. We haven't got any other protocol.
|
||||
* If they Nak the reporting period, take their value XXX ?
|
||||
*/
|
||||
NAKCILQR(CI_QUALITY, neg_lqr,
|
||||
if (cishort != LQR)
|
||||
if (cishort != PPP_LQR)
|
||||
try.neg_lqr = 0;
|
||||
else
|
||||
try.lqr_period = cilong;
|
||||
);
|
||||
|
||||
/*
|
||||
* Check for a looped-back line.
|
||||
*/
|
||||
NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
|
||||
try.magicnumber = magic();
|
||||
++try.numloops;
|
||||
looped_back = 1;
|
||||
);
|
||||
|
||||
@ -760,11 +878,13 @@ lcp_nakci(f, p, len)
|
||||
* `let me authenticate myself with you' which is a bit pointless.
|
||||
* For the quality protocol, the Nak means `ask me to send you quality
|
||||
* reports', but if we didn't ask for them, we don't want them.
|
||||
* An option we don't recognize represents the peer asking to
|
||||
* negotiate some option we don't support, so ignore it.
|
||||
*/
|
||||
while (len > CILEN_VOID) {
|
||||
GETCHAR(citype, p);
|
||||
GETCHAR(cilen, p);
|
||||
if( (len -= cilen) < 0 )
|
||||
if ((len -= cilen) < 0)
|
||||
goto bad;
|
||||
next = p + cilen - 2;
|
||||
|
||||
@ -800,8 +920,6 @@ lcp_nakci(f, p, len)
|
||||
if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
|
||||
goto bad;
|
||||
break;
|
||||
default:
|
||||
goto bad;
|
||||
}
|
||||
p = next;
|
||||
}
|
||||
@ -814,9 +932,14 @@ lcp_nakci(f, p, len)
|
||||
* OK, the Nak is good. Now we can update state.
|
||||
*/
|
||||
if (f->state != OPENED) {
|
||||
if (looped_back) {
|
||||
if (++try.numloops >= lcp_loopbackfail) {
|
||||
syslog(LOG_NOTICE, "Serial line is looped back.");
|
||||
lcp_close(f->unit);
|
||||
}
|
||||
} else
|
||||
try.numloops = 0;
|
||||
*go = try;
|
||||
if (looped_back && try.numloops % lcp_warnloops == 0)
|
||||
LCPDEBUG((LOG_INFO, "The line appears to be looped back."));
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -845,7 +968,7 @@ lcp_rejci(f, p, len)
|
||||
lcp_options *go = &lcp_gotoptions[f->unit];
|
||||
u_char cichar;
|
||||
u_short cishort;
|
||||
u_long cilong;
|
||||
u_int32_t cilong;
|
||||
u_char *start = p;
|
||||
int plen = len;
|
||||
lcp_options try; /* options to request next time */
|
||||
@ -894,6 +1017,7 @@ lcp_rejci(f, p, len)
|
||||
if (cishort != val || cichar != digest) \
|
||||
goto bad; \
|
||||
try.neg = 0; \
|
||||
try.neg_upap = 0; \
|
||||
LCPDEBUG((LOG_INFO,"lcp_rejci rejected chap opt %d", opt)); \
|
||||
}
|
||||
#define REJCILONG(opt, neg, val) \
|
||||
@ -920,7 +1044,7 @@ lcp_rejci(f, p, len)
|
||||
GETSHORT(cishort, p); \
|
||||
GETLONG(cilong, p); \
|
||||
/* Check rejected value. */ \
|
||||
if (cishort != LQR || cilong != val) \
|
||||
if (cishort != PPP_LQR || cilong != val) \
|
||||
goto bad; \
|
||||
try.neg = 0; \
|
||||
LCPDEBUG((LOG_INFO,"lcp_rejci rejected LQR opt %d", opt)); \
|
||||
@ -928,9 +1052,9 @@ lcp_rejci(f, p, len)
|
||||
|
||||
REJCISHORT(CI_MRU, neg_mru, go->mru);
|
||||
REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
|
||||
REJCICHAP(CI_AUTHTYPE, neg_chap, CHAP, go->chap_mdtype);
|
||||
REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype);
|
||||
if (!go->neg_chap) {
|
||||
REJCISHORT(CI_AUTHTYPE, neg_upap, UPAP);
|
||||
REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
|
||||
}
|
||||
REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
|
||||
REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
|
||||
@ -977,11 +1101,12 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
|
||||
u_char *cip, *next; /* Pointer to current and next CIs */
|
||||
u_char cilen, citype, cichar;/* Parsed len, type, char value */
|
||||
u_short cishort; /* Parsed short value */
|
||||
u_long cilong; /* Parse long value */
|
||||
u_int32_t cilong; /* Parse long value */
|
||||
int rc = CONFACK; /* Final packet return code */
|
||||
int orc; /* Individual option return code */
|
||||
u_char *p; /* Pointer to next char to parse */
|
||||
u_char *ucp = inp; /* Pointer to current output char */
|
||||
u_char *rejp; /* Pointer to next char in reject frame */
|
||||
u_char *nakp; /* Pointer to next char in Nak frame */
|
||||
int l = *lenp; /* Length left */
|
||||
|
||||
/*
|
||||
@ -993,6 +1118,8 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
|
||||
* Process all his options.
|
||||
*/
|
||||
next = inp;
|
||||
nakp = nak_buffer;
|
||||
rejp = inp;
|
||||
while (l) {
|
||||
orc = CONFACK; /* Assume success */
|
||||
cip = p = next; /* Remember begining of CI */
|
||||
@ -1028,10 +1155,9 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
|
||||
*/
|
||||
if (cishort < MINMRU) {
|
||||
orc = CONFNAK; /* Nak CI */
|
||||
if( !reject_if_disagree ){
|
||||
DECPTR(sizeof (short), p); /* Backup */
|
||||
PUTSHORT(MINMRU, p); /* Give him a hint */
|
||||
}
|
||||
PUTCHAR(CI_MRU, nakp);
|
||||
PUTCHAR(CILEN_SHORT, nakp);
|
||||
PUTSHORT(MINMRU, nakp); /* Give him a hint */
|
||||
break;
|
||||
}
|
||||
ho->neg_mru = 1; /* Remember he sent MRU */
|
||||
@ -1046,7 +1172,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
|
||||
break;
|
||||
}
|
||||
GETLONG(cilong, p);
|
||||
LCPDEBUG((LOG_INFO, "(%lx)", cilong));
|
||||
LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong));
|
||||
|
||||
/*
|
||||
* Asyncmap must have set at least the bits
|
||||
@ -1054,10 +1180,9 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
|
||||
*/
|
||||
if ((ao->asyncmap & ~cilong) != 0) {
|
||||
orc = CONFNAK;
|
||||
if( !reject_if_disagree ){
|
||||
DECPTR(sizeof (long), p);
|
||||
PUTLONG(ao->asyncmap | cilong, p);
|
||||
}
|
||||
PUTCHAR(CI_ASYNCMAP, nakp);
|
||||
PUTCHAR(CILEN_LONG, nakp);
|
||||
PUTLONG(ao->asyncmap | cilong, nakp);
|
||||
break;
|
||||
}
|
||||
ho->neg_asyncmap = 1;
|
||||
@ -1068,6 +1193,9 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
|
||||
LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd AUTHTYPE"));
|
||||
if (cilen < CILEN_SHORT ||
|
||||
!(ao->neg_upap || ao->neg_chap)) {
|
||||
/*
|
||||
* Reject the option if we're not willing to authenticate.
|
||||
*/
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
@ -1085,34 +1213,47 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
|
||||
* the ordering of the CIs in the peer's Configure-Request.
|
||||
*/
|
||||
|
||||
if (cishort == UPAP) {
|
||||
if (!ao->neg_upap || /* we don't want to do PAP */
|
||||
ho->neg_chap || /* or we've already accepted CHAP */
|
||||
if (cishort == PPP_PAP) {
|
||||
if (ho->neg_chap || /* we've already accepted CHAP */
|
||||
cilen != CILEN_SHORT) {
|
||||
LCPDEBUG((LOG_WARNING,
|
||||
"lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
if (!ao->neg_upap) { /* we don't want to do PAP */
|
||||
orc = CONFNAK; /* NAK it and suggest CHAP */
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
PUTCHAR(CILEN_CHAP, nakp);
|
||||
PUTSHORT(PPP_CHAP, nakp);
|
||||
PUTCHAR(ao->chap_mdtype, nakp);
|
||||
break;
|
||||
}
|
||||
ho->neg_upap = 1;
|
||||
break;
|
||||
}
|
||||
if (cishort == CHAP) {
|
||||
if (!ao->neg_chap || /* we don't want to do CHAP */
|
||||
ho->neg_upap || /* or we've already accepted UPAP */
|
||||
if (cishort == PPP_CHAP) {
|
||||
if (ho->neg_upap || /* we've already accepted PAP */
|
||||
cilen != CILEN_CHAP) {
|
||||
LCPDEBUG((LOG_INFO,
|
||||
"lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
if (!ao->neg_chap) { /* we don't want to do CHAP */
|
||||
orc = CONFNAK; /* NAK it and suggest PAP */
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
PUTCHAR(CILEN_SHORT, nakp);
|
||||
PUTSHORT(PPP_PAP, nakp);
|
||||
break;
|
||||
}
|
||||
GETCHAR(cichar, p); /* get digest type*/
|
||||
if (cichar != ao->chap_mdtype) {
|
||||
orc = CONFNAK;
|
||||
if( !reject_if_disagree ){
|
||||
DECPTR(sizeof (u_char), p);
|
||||
PUTCHAR(ao->chap_mdtype, p);
|
||||
}
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
PUTCHAR(CILEN_CHAP, nakp);
|
||||
PUTSHORT(PPP_CHAP, nakp);
|
||||
PUTCHAR(ao->chap_mdtype, nakp);
|
||||
break;
|
||||
}
|
||||
ho->chap_mdtype = cichar; /* save md type */
|
||||
@ -1122,9 +1263,19 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
|
||||
|
||||
/*
|
||||
* We don't recognize the protocol they're asking for.
|
||||
* Reject it.
|
||||
* Nak it with something we're willing to do.
|
||||
* (At this point we know ao->neg_upap || ao->neg_chap.)
|
||||
*/
|
||||
orc = CONFREJ;
|
||||
orc = CONFNAK;
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
if (ao->neg_chap) {
|
||||
PUTCHAR(CILEN_CHAP, nakp);
|
||||
PUTSHORT(PPP_CHAP, nakp);
|
||||
PUTCHAR(ao->chap_mdtype, nakp);
|
||||
} else {
|
||||
PUTCHAR(CILEN_SHORT, nakp);
|
||||
PUTSHORT(PPP_PAP, nakp);
|
||||
}
|
||||
break;
|
||||
|
||||
case CI_QUALITY:
|
||||
@ -1137,16 +1288,20 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
|
||||
|
||||
GETSHORT(cishort, p);
|
||||
GETLONG(cilong, p);
|
||||
LCPDEBUG((LOG_INFO, "(%x %lx)", cishort, cilong));
|
||||
if (cishort != LQR) {
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
LCPDEBUG((LOG_INFO, "(%x %x)", cishort, (unsigned int) cilong));
|
||||
|
||||
/*
|
||||
* Check the reporting period.
|
||||
* Check the protocol and the reporting period.
|
||||
* XXX When should we Nak this, and what with?
|
||||
*/
|
||||
if (cishort != PPP_LQR) {
|
||||
orc = CONFNAK;
|
||||
PUTCHAR(CI_QUALITY, nakp);
|
||||
PUTCHAR(CILEN_LQR, nakp);
|
||||
PUTSHORT(PPP_LQR, nakp);
|
||||
PUTLONG(ao->lqr_period, nakp);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CI_MAGICNUMBER:
|
||||
@ -1157,17 +1312,18 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
|
||||
break;
|
||||
}
|
||||
GETLONG(cilong, p);
|
||||
LCPDEBUG((LOG_INFO, "(%lx)", cilong));
|
||||
LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong));
|
||||
|
||||
/*
|
||||
* He must have a different magic number.
|
||||
*/
|
||||
if (go->neg_magicnumber &&
|
||||
cilong == go->magicnumber) {
|
||||
orc = CONFNAK;
|
||||
DECPTR(sizeof (long), p);
|
||||
cilong = magic(); /* Don't put magic() inside macro! */
|
||||
PUTLONG(cilong, p);
|
||||
orc = CONFNAK;
|
||||
PUTCHAR(CI_MAGICNUMBER, nakp);
|
||||
PUTCHAR(CILEN_LONG, nakp);
|
||||
PUTLONG(cilong, nakp);
|
||||
break;
|
||||
}
|
||||
ho->neg_magicnumber = 1;
|
||||
@ -1209,35 +1365,46 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
|
||||
continue; /* Don't send this one */
|
||||
|
||||
if (orc == CONFNAK) { /* Nak this CI? */
|
||||
if (reject_if_disagree) /* Getting fed up with sending NAKs? */
|
||||
if (reject_if_disagree /* Getting fed up with sending NAKs? */
|
||||
&& citype != CI_MAGICNUMBER) {
|
||||
orc = CONFREJ; /* Get tough if so */
|
||||
else {
|
||||
} else {
|
||||
if (rc == CONFREJ) /* Rejecting prior CI? */
|
||||
continue; /* Don't send this one */
|
||||
if (rc == CONFACK) { /* Ack'd all prior CIs? */
|
||||
rc = CONFNAK; /* Not anymore... */
|
||||
ucp = inp; /* Backup */
|
||||
}
|
||||
rc = CONFNAK;
|
||||
}
|
||||
}
|
||||
if (orc == CONFREJ && /* Reject this CI */
|
||||
rc != CONFREJ) { /* but no prior ones? */
|
||||
if (orc == CONFREJ) { /* Reject this CI */
|
||||
rc = CONFREJ;
|
||||
ucp = inp; /* Backup */
|
||||
if (cip != rejp) /* Need to move rejected CI? */
|
||||
BCOPY(cip, rejp, cilen); /* Move it */
|
||||
INCPTR(cilen, rejp); /* Update output pointer */
|
||||
}
|
||||
if (ucp != cip) /* Need to move CI? */
|
||||
BCOPY(cip, ucp, cilen); /* Move it */
|
||||
INCPTR(cilen, ucp); /* Update output pointer */
|
||||
}
|
||||
|
||||
/*
|
||||
* If we wanted to send additional NAKs (for unsent CIs), the
|
||||
* code would go here. This must be done with care since it might
|
||||
* require a longer packet than we received. At present there
|
||||
* are no cases where we want to ask the peer to negotiate an option.
|
||||
* code would go here. The extra NAKs would go at *nakp.
|
||||
* At present there are no cases where we want to ask the
|
||||
* peer to negotiate an option.
|
||||
*/
|
||||
|
||||
*lenp = ucp - inp; /* Compute output length */
|
||||
switch (rc) {
|
||||
case CONFACK:
|
||||
*lenp = next - inp;
|
||||
break;
|
||||
case CONFNAK:
|
||||
/*
|
||||
* Copy the Nak'd options from the nak_buffer to the caller's buffer.
|
||||
*/
|
||||
*lenp = nakp - nak_buffer;
|
||||
BCOPY(nak_buffer, inp, *lenp);
|
||||
break;
|
||||
case CONFREJ:
|
||||
*lenp = rejp - inp;
|
||||
break;
|
||||
}
|
||||
|
||||
LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.", CODENAME(rc)));
|
||||
return (rc); /* Return final code */
|
||||
}
|
||||
@ -1268,7 +1435,7 @@ lcp_up(f)
|
||||
* set our MRU to the larger of value we wanted and
|
||||
* the value we got in the negotiation.
|
||||
*/
|
||||
ppp_send_config(f->unit, MIN(ao->mru, (ho->neg_mru? ho->mru: MTU)),
|
||||
ppp_send_config(f->unit, MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),
|
||||
(ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
|
||||
ho->neg_pcompression, ho->neg_accompression);
|
||||
/*
|
||||
@ -1276,7 +1443,7 @@ lcp_up(f)
|
||||
* set the receive asyncmap to ffffffff, but we set it to 0
|
||||
* for backwards contemptibility.
|
||||
*/
|
||||
ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): MTU),
|
||||
ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU),
|
||||
(go->neg_asyncmap? go->asyncmap: 0x00000000),
|
||||
go->neg_pcompression, go->neg_accompression);
|
||||
|
||||
@ -1286,6 +1453,7 @@ lcp_up(f)
|
||||
ChapLowerUp(f->unit); /* Enable CHAP */
|
||||
upap_lowerup(f->unit); /* Enable UPAP */
|
||||
ipcp_lowerup(f->unit); /* Enable IPCP */
|
||||
ccp_lowerup(f->unit); /* Enable CCP */
|
||||
lcp_echo_lowerup(f->unit); /* Enable echo messages */
|
||||
|
||||
link_established(f->unit);
|
||||
@ -1302,14 +1470,15 @@ lcp_down(f)
|
||||
fsm *f;
|
||||
{
|
||||
lcp_echo_lowerdown(f->unit);
|
||||
ccp_lowerdown(f->unit);
|
||||
ipcp_lowerdown(f->unit);
|
||||
ChapLowerDown(f->unit);
|
||||
upap_lowerdown(f->unit);
|
||||
|
||||
sifdown(f->unit);
|
||||
ppp_send_config(f->unit, MTU, 0xffffffff, 0, 0);
|
||||
ppp_recv_config(f->unit, MTU, 0x00000000, 0, 0);
|
||||
peer_mru[f->unit] = MTU;
|
||||
ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0);
|
||||
ppp_recv_config(f->unit, PPP_MRU, 0x00000000, 0, 0);
|
||||
peer_mru[f->unit] = PPP_MRU;
|
||||
|
||||
link_down(f->unit);
|
||||
}
|
||||
@ -1350,13 +1519,13 @@ int
|
||||
lcp_printpkt(p, plen, printer, arg)
|
||||
u_char *p;
|
||||
int plen;
|
||||
void (*printer) __ARGS((void *, char *, ...));
|
||||
void (*printer) __P((void *, char *, ...));
|
||||
void *arg;
|
||||
{
|
||||
int code, id, len, olen;
|
||||
u_char *pstart, *optend;
|
||||
u_short cishort;
|
||||
u_long cilong;
|
||||
u_int32_t cilong;
|
||||
|
||||
if (plen < HEADERLEN)
|
||||
return 0;
|
||||
@ -1410,10 +1579,10 @@ lcp_printpkt(p, plen, printer, arg)
|
||||
printer(arg, "auth ");
|
||||
GETSHORT(cishort, p);
|
||||
switch (cishort) {
|
||||
case UPAP:
|
||||
case PPP_PAP:
|
||||
printer(arg, "upap");
|
||||
break;
|
||||
case CHAP:
|
||||
case PPP_CHAP:
|
||||
printer(arg, "chap");
|
||||
break;
|
||||
default:
|
||||
@ -1427,7 +1596,7 @@ lcp_printpkt(p, plen, printer, arg)
|
||||
printer(arg, "quality ");
|
||||
GETSHORT(cishort, p);
|
||||
switch (cishort) {
|
||||
case LQR:
|
||||
case PPP_LQR:
|
||||
printer(arg, "lqr");
|
||||
break;
|
||||
default:
|
||||
@ -1483,7 +1652,7 @@ void LcpLinkFailure (f)
|
||||
{
|
||||
if (f->state == OPENED) {
|
||||
syslog (LOG_NOTICE, "Excessive lack of response to LCP echo frames.");
|
||||
lcp_lowerdown(f->unit); /* Reset connection */
|
||||
lcp_close(f->unit); /* Reset connection */
|
||||
}
|
||||
}
|
||||
|
||||
@ -1495,43 +1664,36 @@ static void
|
||||
LcpEchoCheck (f)
|
||||
fsm *f;
|
||||
{
|
||||
u_long delta;
|
||||
long int delta;
|
||||
#ifdef __linux__
|
||||
struct ppp_ddinfo ddinfo;
|
||||
u_long latest;
|
||||
struct ppp_idle ddinfo;
|
||||
/*
|
||||
* Read the time since the last packet was received.
|
||||
*/
|
||||
if (ioctl (fd, PPPIOCGTIME, &ddinfo) < 0) {
|
||||
syslog (LOG_ERR, "ioctl(PPPIOCGTIME): %m");
|
||||
if (ioctl (fd, PPPIOCGIDLE, &ddinfo) < 0) {
|
||||
syslog (LOG_ERR, "ioctl(PPPIOCGIDLE): %m");
|
||||
die (1);
|
||||
}
|
||||
/*
|
||||
* Choose the most recient frame received. It may be an IP or NON-IP frame.
|
||||
*/
|
||||
latest = ddinfo.nip_rjiffies < ddinfo.ip_rjiffies ? ddinfo.nip_rjiffies
|
||||
: ddinfo.ip_rjiffies;
|
||||
/*
|
||||
* Compute the time since the last packet was received. If the timer
|
||||
* has expired then send the echo request and reset the timer to maximum.
|
||||
*/
|
||||
delta = (lcp_echo_interval * HZ) - latest;
|
||||
if (delta < HZ || latest < 0L) {
|
||||
delta = (long int) lcp_echo_interval - (long int) ddinfo.recv_idle;
|
||||
if (delta < 0L) {
|
||||
LcpSendEchoRequest (f);
|
||||
delta = lcp_echo_interval * HZ;
|
||||
delta = (int) lcp_echo_interval;
|
||||
}
|
||||
delta /= HZ;
|
||||
|
||||
#else /* Other implementations do not have ability to find delta */
|
||||
LcpSendEchoRequest (f);
|
||||
delta = lcp_echo_interval;
|
||||
delta = (int) lcp_echo_interval;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start the timer for the next interval.
|
||||
*/
|
||||
assert (lcp_echo_timer_running==0);
|
||||
TIMEOUT (LcpEchoTimeout, (caddr_t) f, delta);
|
||||
TIMEOUT (LcpEchoTimeout, (caddr_t) f, (u_int32_t) delta);
|
||||
lcp_echo_timer_running = 1;
|
||||
}
|
||||
|
||||
@ -1558,15 +1720,19 @@ lcp_received_echo_reply (f, id, inp, len)
|
||||
fsm *f;
|
||||
int id; u_char *inp; int len;
|
||||
{
|
||||
u_long magic;
|
||||
u_int32_t magic;
|
||||
|
||||
/* Check the magic number - don't count replies from ourselves. */
|
||||
if (len < CILEN_LONG)
|
||||
if (len < 4) {
|
||||
syslog(LOG_DEBUG, "lcp: received short Echo-Reply, length %d", len);
|
||||
return;
|
||||
}
|
||||
GETLONG(magic, inp);
|
||||
if (lcp_gotoptions[f->unit].neg_magicnumber
|
||||
&& magic == lcp_gotoptions[f->unit].magicnumber)
|
||||
&& magic == lcp_gotoptions[f->unit].magicnumber) {
|
||||
syslog(LOG_WARNING, "appear to have received our own echo-reply!");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reset the number of outstanding echo frames */
|
||||
lcp_echos_pending = 0;
|
||||
@ -1580,7 +1746,7 @@ static void
|
||||
LcpSendEchoRequest (f)
|
||||
fsm *f;
|
||||
{
|
||||
u_long lcp_magic;
|
||||
u_int32_t lcp_magic;
|
||||
u_char pkt[4], *pktp;
|
||||
|
||||
/*
|
||||
@ -1625,6 +1791,11 @@ lcp_echo_lowerup (unit)
|
||||
/* If a timeout interval is specified then start the timer */
|
||||
if (lcp_echo_interval != 0)
|
||||
LcpEchoCheck (f);
|
||||
#ifdef _linux_
|
||||
/* If a idle time limit is given then start it */
|
||||
if (idle_time_limit != 0)
|
||||
RestartIdleTimer (f);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1641,4 +1812,11 @@ lcp_echo_lowerdown (unit)
|
||||
UNTIMEOUT (LcpEchoTimeout, (caddr_t) f);
|
||||
lcp_echo_timer_running = 0;
|
||||
}
|
||||
#ifdef _linux_
|
||||
/* If a idle time limit is running then stop it */
|
||||
if (idle_timer_running != 0) {
|
||||
UNTIMEOUT (IdleTimeCheck, (caddr_t) f);
|
||||
idle_timer_running = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: lcp.h,v 1.4 1994/05/24 11:22:28 paulus Exp $
|
||||
* $Id: lcp.h,v 1.8 1995/06/12 11:22:47 paulus Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -55,10 +55,10 @@ typedef struct lcp_options {
|
||||
int neg_lqr : 1; /* Negotiate use of Link Quality Reports */
|
||||
u_short mru; /* Value of MRU */
|
||||
u_char chap_mdtype; /* which MD type (hashing algorithm) */
|
||||
u_long asyncmap; /* Value of async map */
|
||||
u_long magicnumber;
|
||||
u_int32_t asyncmap; /* Value of async map */
|
||||
u_int32_t magicnumber;
|
||||
int numloops; /* Number of loops during magic number neg. */
|
||||
u_long lqr_period; /* Reporting period for link quality */
|
||||
u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */
|
||||
} lcp_options;
|
||||
|
||||
extern fsm lcp_fsm[];
|
||||
@ -66,22 +66,23 @@ extern lcp_options lcp_wantoptions[];
|
||||
extern lcp_options lcp_gotoptions[];
|
||||
extern lcp_options lcp_allowoptions[];
|
||||
extern lcp_options lcp_hisoptions[];
|
||||
extern u_long xmit_accm[][8];
|
||||
extern u_int32_t xmit_accm[][8];
|
||||
|
||||
#define DEFMRU 1500 /* Try for this */
|
||||
#define MINMRU 128 /* No MRUs below this */
|
||||
#define MAXMRU 16384 /* Normally limit MRU to this */
|
||||
|
||||
void lcp_init __ARGS((int));
|
||||
void lcp_open __ARGS((int));
|
||||
void lcp_close __ARGS((int));
|
||||
void lcp_lowerup __ARGS((int));
|
||||
void lcp_lowerdown __ARGS((int));
|
||||
void lcp_input __ARGS((int, u_char *, int));
|
||||
void lcp_protrej __ARGS((int));
|
||||
void lcp_sprotrej __ARGS((int, u_char *, int));
|
||||
int lcp_printpkt __ARGS((u_char *, int,
|
||||
void (*) __ARGS((void *, char *, ...)), void *));
|
||||
void lcp_init __P((int));
|
||||
void lcp_open __P((int));
|
||||
void lcp_close __P((int));
|
||||
void lcp_lowerup __P((int));
|
||||
void lcp_lowerdown __P((int));
|
||||
void lcp_input __P((int, u_char *, int));
|
||||
void lcp_protrej __P((int));
|
||||
void lcp_sprotrej __P((int, u_char *, int));
|
||||
int lcp_printpkt __P((u_char *, int,
|
||||
void (*) __P((void *, char *, ...)), void *));
|
||||
|
||||
extern int lcp_warnloops; /* Warn about a loopback this often */
|
||||
#define DEFWARNLOOPS 10 /* Default value for above */
|
||||
/* Default number of times we receive our magic number from the peer
|
||||
before deciding the link is looped-back. */
|
||||
#define DEFLOOPBACKFAIL 5
|
||||
|
@ -1,122 +0,0 @@
|
||||
/*
|
||||
* lock.c - lock/unlock the serial device.
|
||||
*
|
||||
* This code is derived from chat.c.
|
||||
*/
|
||||
|
||||
static char rcsid[] = "$Id: lock.c,v 1.1 1994/04/18 23:41:52 paulus Exp $";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#ifdef sun
|
||||
# if defined(SUNOS) && SUNOS >= 41
|
||||
# ifndef HDB
|
||||
# define HDB
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef LOCK_DIR
|
||||
# ifdef __NetBSD__
|
||||
# define PIDSTRING
|
||||
# define LOCK_PREFIX "/var/spool/lock/LCK.."
|
||||
# else
|
||||
# ifdef HDB
|
||||
# define PIDSTRING
|
||||
# define LOCK_PREFIX "/usr/spool/locks/LCK.."
|
||||
# else /* HDB */
|
||||
# define LOCK_PREFIX "/usr/spool/uucp/LCK.."
|
||||
# endif /* HDB */
|
||||
# endif
|
||||
#endif /* LOCK_DIR */
|
||||
|
||||
static char *lock_file;
|
||||
|
||||
/*
|
||||
* Create a lock file for the named lock device
|
||||
*/
|
||||
int
|
||||
lock(dev)
|
||||
char *dev;
|
||||
{
|
||||
char hdb_lock_buffer[12];
|
||||
int fd, pid, n;
|
||||
char *p;
|
||||
|
||||
if ((p = strrchr(dev, '/')) != NULL)
|
||||
dev = p + 1;
|
||||
lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1);
|
||||
if (lock_file == NULL)
|
||||
novm("lock file name");
|
||||
strcat(strcpy(lock_file, LOCK_PREFIX), dev);
|
||||
|
||||
while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
|
||||
if (errno == EEXIST
|
||||
&& (fd = open(lock_file, O_RDONLY, 0)) >= 0) {
|
||||
/* Read the lock file to find out who has the device locked */
|
||||
#ifdef PIDSTRING
|
||||
n = read(fd, hdb_lock_buffer, 11);
|
||||
if (n > 0) {
|
||||
hdb_lock_buffer[n] = 0;
|
||||
pid = atoi(hdb_lock_buffer);
|
||||
}
|
||||
#else
|
||||
n = read(fd, &pid, sizeof(pid));
|
||||
#endif
|
||||
if (n <= 0) {
|
||||
syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file);
|
||||
close(fd);
|
||||
} else {
|
||||
if (kill(pid, 0) == -1 && errno == ESRCH) {
|
||||
/* pid no longer exists - remove the lock file */
|
||||
if (unlink(lock_file) == 0) {
|
||||
close(fd);
|
||||
syslog(LOG_NOTICE, "Removed stale lock on %s (pid %d)",
|
||||
dev, pid);
|
||||
continue;
|
||||
} else
|
||||
syslog(LOG_WARNING, "Couldn't remove stale lock on %s",
|
||||
dev);
|
||||
} else
|
||||
syslog(LOG_NOTICE, "Device %s is locked by pid %d",
|
||||
dev, pid);
|
||||
}
|
||||
close(fd);
|
||||
} else
|
||||
syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file);
|
||||
free(lock_file);
|
||||
lock_file = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
# ifdef PIDSTRING
|
||||
sprintf(hdb_lock_buffer, "%10d\n", getpid());
|
||||
write(fd, hdb_lock_buffer, 11);
|
||||
# else
|
||||
pid = getpid();
|
||||
write(fd, &pid, sizeof pid);
|
||||
# endif
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove our lockfile
|
||||
*/
|
||||
unlock()
|
||||
{
|
||||
if (lock_file) {
|
||||
unlink(lock_file);
|
||||
free(lock_file);
|
||||
lock_file = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -18,53 +18,73 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: magic.c,v 1.1 1993/11/11 03:54:25 paulus Exp $";
|
||||
static char rcsid[] = "$Id: magic.c,v 1.5 1995/06/06 01:52:25 paulus Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "magic.h"
|
||||
|
||||
static u_int32_t next; /* Next value to return */
|
||||
|
||||
static u_long next; /* Next value to return */
|
||||
|
||||
extern u_long gethostid __ARGS((void));
|
||||
extern long random __ARGS((void));
|
||||
extern void srandom __ARGS((int));
|
||||
extern int gethostid __P((void));
|
||||
extern long mrand48 __P((void));
|
||||
extern void srand48 __P((long));
|
||||
|
||||
|
||||
/*
|
||||
* magic_init - Initialize the magic number generator.
|
||||
*
|
||||
* Computes first magic number and seed for random number generator.
|
||||
* Attempts to compute a random number seed which will not repeat.
|
||||
* The current method uses the current hostid and current time.
|
||||
* The current method uses the current hostid, current process ID
|
||||
* and current time, currently.
|
||||
*/
|
||||
void magic_init()
|
||||
void
|
||||
magic_init()
|
||||
{
|
||||
struct timeval tv;
|
||||
long seed;
|
||||
struct timeval t;
|
||||
|
||||
next = gethostid();
|
||||
if (gettimeofday(&tv, NULL)) {
|
||||
perror("gettimeofday");
|
||||
exit(1);
|
||||
}
|
||||
next ^= (u_long) tv.tv_sec ^ (u_long) tv.tv_usec;
|
||||
|
||||
srandom((int) next);
|
||||
gettimeofday(&t, NULL);
|
||||
seed = gethostid() ^ t.tv_sec ^ t.tv_usec ^ getpid();
|
||||
srand48(seed);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* magic - Returns the next magic number.
|
||||
*/
|
||||
u_long magic()
|
||||
u_int32_t
|
||||
magic()
|
||||
{
|
||||
u_long m;
|
||||
|
||||
m = next;
|
||||
next = (u_long) random();
|
||||
return (m);
|
||||
return (u_int32_t) mrand48();
|
||||
}
|
||||
|
||||
#ifdef NO_DRAND48
|
||||
/*
|
||||
* Substitute procedures for those systems which don't have
|
||||
* drand48 et al.
|
||||
*/
|
||||
|
||||
double
|
||||
drand48()
|
||||
{
|
||||
return (double)random() / (double)0x7fffffffL; /* 2**31-1 */
|
||||
}
|
||||
|
||||
long
|
||||
mrand48()
|
||||
{
|
||||
return random();
|
||||
}
|
||||
|
||||
void
|
||||
srand48(seedval)
|
||||
long seedval;
|
||||
{
|
||||
srandom((int)seedval);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -16,9 +16,8 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: magic.h,v 1.1 1993/11/11 03:54:25 paulus Exp $
|
||||
* $Id: magic.h,v 1.3 1994/09/21 06:47:37 paulus Exp $
|
||||
*/
|
||||
#include "args.h"
|
||||
|
||||
void magic_init __ARGS((void)); /* Initialize the magic number generator */
|
||||
u_long magic __ARGS((void)); /* Returns the next magic number */
|
||||
void magic_init __P((void)); /* Initialize the magic number generator */
|
||||
u_int32_t magic __P((void)); /* Returns the next magic number */
|
||||
|
1368
usr.sbin/pppd/main.c
1368
usr.sbin/pppd/main.c
File diff suppressed because it is too large
Load Diff
@ -40,7 +40,7 @@
|
||||
#ifndef __MD5_INCLUDE__
|
||||
|
||||
/* typedef a 32-bit type */
|
||||
typedef unsigned long int UINT4;
|
||||
typedef unsigned int UINT4;
|
||||
|
||||
/* Data structure for MD5 (Message-Digest) computation */
|
||||
typedef struct {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
/* $Id: patchlevel.h,v 1.10 1994/06/09 01:51:10 paulus Exp $ */
|
||||
#define PATCHLEVEL 2
|
||||
/* $Id: patchlevel.h,v 1.16 1995/07/11 06:41:07 paulus Exp $ */
|
||||
#define PATCHLEVEL 0
|
||||
|
||||
#define VERSION "2.1"
|
||||
#define DATE "9 June 94"
|
||||
#define VERSION "2.2"
|
||||
#define IMPLEMENTATION "beta3"
|
||||
#define DATE "11 July 95"
|
||||
|
@ -1,13 +1,15 @@
|
||||
/*
|
||||
* define path names
|
||||
*
|
||||
* $Id: pathnames.h,v 1.4 1994/05/18 06:34:46 paulus Exp $
|
||||
* $Id: pathnames.h,v 1.6 1995/06/12 11:22:53 paulus Exp $
|
||||
*/
|
||||
|
||||
#if defined(STREAMS) || defined(ultrix)
|
||||
#define _PATH_PIDFILE "/etc/ppp"
|
||||
#ifdef HAVE_PATHS_H
|
||||
#include <paths.h>
|
||||
|
||||
#else
|
||||
#define _PATH_PIDFILE "/var/run"
|
||||
#define _PATH_VARRUN "/etc/ppp/"
|
||||
#define _PATH_DEVNULL "/dev/null"
|
||||
#endif
|
||||
|
||||
#define _PATH_UPAPFILE "/etc/ppp/pap-secrets"
|
||||
@ -16,4 +18,5 @@
|
||||
#define _PATH_IPUP "/etc/ppp/ip-up"
|
||||
#define _PATH_IPDOWN "/etc/ppp/ip-down"
|
||||
#define _PATH_TTYOPT "/etc/ppp/options."
|
||||
#define _PATH_CONNERRS "/etc/ppp/connect-errors"
|
||||
#define _PATH_USEROPT ".ppprc"
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" manual page [] for pppd 2.0
|
||||
.\" $Id: pppd.8,v 1.7 1994/06/09 01:50:48 paulus Exp $
|
||||
.\" $Id: pppd.8,v 1.14 1995/08/16 01:39:53 paulus Exp $
|
||||
.\" SH section heading
|
||||
.\" SS subsection heading
|
||||
.\" LP paragraph
|
||||
@ -36,6 +36,7 @@ NCP for establishing and configuring the Internet Protocol (IP)
|
||||
.I <tty_name>
|
||||
Communicate over the named device. The string "/dev/"
|
||||
is prepended if necessary. If no device name is given,
|
||||
or if the name of the controlling terminal is given,
|
||||
.I pppd
|
||||
will use the controlling terminal, and will not fork to put itself in
|
||||
the background.
|
||||
@ -58,7 +59,7 @@ bit 31 (80000000) represents the character 0x1f or ^_.
|
||||
If multiple \fBasyncmap\fR options are
|
||||
given, the values are ORed together.
|
||||
If no \fBasyncmap\fR option is given, no async character map will be
|
||||
negotiated for the receive direction; the peer will then escape
|
||||
negotiated for the receive direction; the peer should then escape
|
||||
\fIall\fR control characters.
|
||||
.TP
|
||||
.B auth
|
||||
@ -74,14 +75,17 @@ dial the modem and start the remote ppp session.
|
||||
Use hardware flow control (i.e. RTS/CTS) to control the flow of data on
|
||||
the serial port.
|
||||
.TP
|
||||
.B -crtscts
|
||||
Disable hardware flow control (i.e. RTS/CTS) on the serial port. If
|
||||
neither the \fBcrtscts\fR nor the \fB\-crtscts\fR option is given,
|
||||
the hardware flow control setting for the serial port is left
|
||||
unchanged.
|
||||
.TP
|
||||
.B xonxoff
|
||||
Use software flow control (i.e. XON/XOFF) to control the flow of data on
|
||||
the serial port. This option is not implemented on BSD or Ultrix systems
|
||||
the serial port. This option is only implemented on Linux systems
|
||||
at present.
|
||||
.TP
|
||||
.B -crtscts
|
||||
A synonym for \fBxonxoff\fR.
|
||||
.TP
|
||||
.B defaultroute
|
||||
Add a default route to the system routing tables, using the peer as
|
||||
the gateway, when IPCP negotiation is successfully completed.
|
||||
@ -135,7 +139,7 @@ will then just wait passively for a valid LCP packet from the peer
|
||||
With this option,
|
||||
.I pppd
|
||||
will not transmit LCP packets to initiate a connection until a valid
|
||||
LCP packet is received from the peer (as for the "passive" option with
|
||||
LCP packet is received from the peer (as for the `passive' option with
|
||||
old versions of \fIpppd\fR).
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
@ -228,6 +232,21 @@ Don't agree to authenticate using CHAP.
|
||||
Disable negotiation of Van Jacobson style IP header compression (use
|
||||
default, i.e. no compression).
|
||||
.TP
|
||||
.B bsdcomp \fInr,nt
|
||||
Request that the peer compress packets that it sends, using the
|
||||
BSD-Compress scheme, with a maximum code size of \fInr\fR bits, and
|
||||
agree to compress packets sent to the peer with a maximum code size of
|
||||
\fInt\fR bits. If \fInt\fR is not specified, it defaults to the value
|
||||
given for \fInr\fR. Values in the range 9 to 15 may be used for
|
||||
\fInr\fR and \fInt\fR; larger values give better compression but
|
||||
consume more kernel memory for compression dictionaries.
|
||||
Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables
|
||||
compression in the corresponding direction.
|
||||
.TP
|
||||
.B \-bsdcomp
|
||||
Disables compression; \fBpppd\fR will not request or agree to compress
|
||||
packets using the BSD-Compress scheme.
|
||||
.TP
|
||||
.B debug
|
||||
Increase debugging level (same as \fB\-d\fR).
|
||||
If this
|
||||
@ -235,9 +254,12 @@ option is given, \fIpppd\fR will log the contents of all control
|
||||
packets sent or received in a readable form. The packets are logged
|
||||
through syslog with facility \fIdaemon\fR and level \fIdebug\fR. This
|
||||
information can be directed to a file by setting up /etc/syslog.conf
|
||||
appropriately (see syslog.conf(5)). (If \fIpppd\fR is compiled with
|
||||
extra debugging enabled, it will log messages using facility
|
||||
\fIlocal2\fR instead of \fIdaemon\fR).
|
||||
appropriately (see syslog.conf(5)).
|
||||
.TP
|
||||
.B \-defaultroute
|
||||
Disable the \fBdefaultroute\fR option. The system administrator who
|
||||
wishes to prevent users from creating default routes with \fIpppd\fR
|
||||
can do so by placing this option in the /etc/ppp/options file.
|
||||
.TP
|
||||
.B domain \fI<d>
|
||||
Append the domain name <d> to the local host name for authentication
|
||||
@ -245,10 +267,22 @@ purposes. For example, if gethostname() returns the name porsche, but the
|
||||
fully qualified domain name is porsche.Quotron.COM, you would use the
|
||||
domain option to set the domain name to Quotron.COM.
|
||||
.TP
|
||||
.B ipparam \fIstring
|
||||
Provides an extra parameter to the ip-up and ip-down scripts. If this
|
||||
option is given, the \fIstring\fR supplied is given as the 6th
|
||||
parameter to those scripts.
|
||||
.TP
|
||||
.B modem
|
||||
Use the modem control lines. On Ultrix, this option implies hardware
|
||||
flow control, as for the \fBcrtscts\fR option. (This option is not fully
|
||||
implemented.)
|
||||
Use the modem control lines. This option is the default. With this
|
||||
option,
|
||||
.B pppd
|
||||
will wait for the CD (Carrier Detect) signal from the modem to be asserted
|
||||
when opening the serial device
|
||||
(unless a connect script is specified), and it will drop the DTR (Data
|
||||
Terminal Ready) signal briefly when the connection is terminated and before
|
||||
executing the connect script.
|
||||
On Ultrix, this option implies hardware
|
||||
flow control, as for the \fBcrtscts\fR option.
|
||||
.TP
|
||||
.B kdebug \fIn
|
||||
Enable debugging code in the kernel-level PPP driver. The argument
|
||||
@ -258,7 +292,10 @@ received packets be printed, and 4 to request that the contents of
|
||||
transmitted packets be printed.
|
||||
.TP
|
||||
.B local
|
||||
Don't use the modem control lines.
|
||||
Don't use the modem control lines. With this option,
|
||||
.B pppd
|
||||
will ignore the state of the CD (Carrier Detect) signal from the modem and
|
||||
will not change the state of the DTR (Data Terminal Ready) signal.
|
||||
.TP
|
||||
.B mtu \fI<n>
|
||||
Set the MTU [Maximum Transmit Unit] value to \fI<n>\fR. Unless the
|
||||
@ -283,11 +320,27 @@ option).
|
||||
Set the assumed name of the remote system for authentication purposes
|
||||
to <n>.
|
||||
.TP
|
||||
.B papcrypt
|
||||
Indicates that all secrets in the /etc/ppp/pap-secrets file which
|
||||
are used for checking the identity of the peer are encrypted, and thus
|
||||
pppd should not accept a password which (before encryption) is
|
||||
identical to the secret from the /etc/ppp/pap-secrets file.
|
||||
.TP
|
||||
.B proxyarp
|
||||
Add an entry to this system's ARP [Address Resolution Protocol] table
|
||||
with the IP address of the peer and the Ethernet address of this
|
||||
system.
|
||||
.TP
|
||||
.B \-proxyarp
|
||||
Disable the \fBproxyarp\fR option. The system administrator who
|
||||
wishes to prevent users from creating proxy ARP entries with
|
||||
\fIpppd\fR can do so by placing this option in the /etc/ppp/options
|
||||
file.
|
||||
.TP
|
||||
.B persist
|
||||
Do not exit after a connection is terminated; instead try to reopen
|
||||
the connection.
|
||||
.TP
|
||||
.B login
|
||||
Use the system password database for authenticating the peer using
|
||||
PAP.
|
||||
@ -358,6 +411,12 @@ Set the PAP restart interval (retransmission timeout) to <n> seconds
|
||||
Set the maximum number of PAP authenticate-request transmissions to
|
||||
<n> (default 10).
|
||||
.TP
|
||||
.B pap-timeout \fI<n>
|
||||
Set the maximum time that
|
||||
.I pppd
|
||||
will wait for the peer to authenticate itself with PAP to
|
||||
<n> seconds (0 means no limit).
|
||||
.TP
|
||||
.B chap-restart \fI<n>
|
||||
Set the CHAP restart interval (retransmission timeout for challenges)
|
||||
to <n> seconds (default 3).
|
||||
@ -424,7 +483,7 @@ directions if desired.
|
||||
.LP
|
||||
A secrets file is parsed into words as for a options file. A secret
|
||||
is specified by a line containing at least 3 words, in the order
|
||||
client, server, secret. Any following words on the same line are
|
||||
client name, server name, secret. Any following words on the same line are
|
||||
taken to be a list of acceptable IP addresses for that client. If
|
||||
there are only 3 words on the line, it is assumed that any IP address
|
||||
is OK; to disallow all IP addresses, use "-". If the secret starts
|
||||
@ -480,11 +539,16 @@ When authenticating the peer with PAP, a secret of "" matches any
|
||||
password supplied by the peer. If the password doesn't match the
|
||||
secret, the password is encrypted using crypt() and checked against
|
||||
the secret again; thus secrets for authenticating the peer can be
|
||||
stored in encrypted form. If the \fBlogin\fR option was specified, the
|
||||
stored in encrypted form. If the \fBpapcrypt\fR option is given, the
|
||||
first (unencrypted) comparison is omitted, for better security.
|
||||
.LP
|
||||
If the \fBlogin\fR option was specified, the
|
||||
username and password are also checked against the system password
|
||||
database. Thus, the system administrator can set up the pap-secrets
|
||||
file to allow PPP access only to certain users, and to restrict the
|
||||
set of IP addresses that each user can use.
|
||||
set of IP addresses that each user can use. Typically, when using the
|
||||
\fBlogin\fR option, the secret in /etc/ppp/pap-secrets would be "", to
|
||||
avoid the need to have the same secret in two places.
|
||||
.LP
|
||||
Secrets are selected from the CHAP secrets file as follows:
|
||||
.TP 2
|
||||
@ -590,27 +654,28 @@ to direct the messages to the desired output device or file.
|
||||
The \fBdebug\fR option causes the contents of all control packets sent
|
||||
or received to be logged, that is, all LCP, PAP, CHAP or IPCP packets.
|
||||
This can be useful if the PPP negotiation does not succeed.
|
||||
If debugging is enabled at compile time, \fIpppd\fR uses facility
|
||||
LOG_LOCAL2 instead of LOG_DAEMON, and the \fBdebug\fR option
|
||||
causes additional debugging messages to be logged.
|
||||
If debugging is enabled at compile time, the \fBdebug\fR option also
|
||||
causes other debugging messages to be logged.
|
||||
.LP
|
||||
Debugging can also be enabled by sending a
|
||||
Debugging can also be enabled or disabled by sending a
|
||||
SIGUSR1 to the
|
||||
.I pppd
|
||||
process.
|
||||
Debugging may be disabled by sending a SIGUSR2 to the
|
||||
.I pppd
|
||||
process.
|
||||
process. This signal acts as a toggle.
|
||||
.SH FILES
|
||||
.TP
|
||||
.B /var/run/ppp\fIn\fB.pid \fR(BSD), \fB/etc/ppp/ppp\fIn\fB.pid \fR(SunOS)
|
||||
.B /var/run/ppp\fIn\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp\fIn\fB.pid \fR(others)
|
||||
Process-ID for \fIpppd\fR process on ppp interface unit \fIn\fR.
|
||||
.TP
|
||||
.B /etc/ppp/ip-up
|
||||
A program or script which is executed when the link is available for
|
||||
sending and receiving IP packets (that is, IPCP has come up). It is
|
||||
executed with the parameters \fIinterface-name tty-device speed
|
||||
local-IP-address remote-IP-address\fR.
|
||||
executed with the parameters
|
||||
.IP
|
||||
\fIinterface-name tty-device speed local-IP-address
|
||||
remote-IP-address\fR
|
||||
.IP
|
||||
and with its standard input,
|
||||
output and error streams redirected to \fB/dev/null\fR.
|
||||
.IP
|
||||
This program or script is executed with the same real and effective
|
||||
user-ID as \fIpppd\fR, that is, at least the effective user-ID and
|
||||
@ -682,20 +747,29 @@ The following signals have the specified effect when sent to the
|
||||
process.
|
||||
.TP
|
||||
.B SIGINT, SIGTERM
|
||||
These signals cause \fIpppd\fR to terminate the link (by closing LCP),
|
||||
These signals cause \fBpppd\fR to terminate the link (by closing LCP),
|
||||
restore the serial device settings, and exit.
|
||||
.TP
|
||||
.B SIGHUP
|
||||
Indicates that the physical layer has been disconnected. \fIpppd\fR
|
||||
will attempt to restore the serial device settings (this may produce
|
||||
error messages on Suns), and then exit.
|
||||
.SH BUGS
|
||||
The use of the modem control lines and the effects of the \fBmodem\fR
|
||||
and \fBlocal\fR options are not well defined.
|
||||
This signal causes \fBpppd\fR to terminate the link, restore the
|
||||
serial device settings, and close the serial device. If the
|
||||
\fBpersist\fR option has been specified, \fBpppd\fR will try to reopen
|
||||
the serial device and start another connection. Otherwise \fBpppd\fR
|
||||
will exit.
|
||||
.TP
|
||||
.B SIGUSR2
|
||||
This signal causes
|
||||
.B pppd
|
||||
to renegotiate compression. This can be useful to re-enable
|
||||
compression after it has been disabled as a result of a fatal
|
||||
decompression error. With the BSD Compress scheme, fatal
|
||||
decompression errors generally indicate a bug in one or other
|
||||
implementation.
|
||||
|
||||
.SH AUTHORS
|
||||
Drew Perkins,
|
||||
Brad Clements,
|
||||
Karl Fox,
|
||||
Greg Christy,
|
||||
Brad Parker (brad@fcr.com),
|
||||
Paul Mackerras (paulus@cs.anu.edu.au)
|
||||
Brad Parker,
|
||||
Paul Mackerras (paulus@cs.anu.edu.au).
|
||||
|
@ -16,7 +16,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: pppd.h,v 1.3 1994/05/26 06:43:42 paulus Exp $
|
||||
* $Id: pppd.h,v 1.8 1995/04/26 06:46:31 paulus Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -25,15 +25,17 @@
|
||||
|
||||
#ifndef __PPPD_H__
|
||||
#define __PPPD_H__
|
||||
#include "args.h"
|
||||
|
||||
#include <sys/param.h> /* for MAXPATHLEN and BSD4_4, if defined */
|
||||
#include <sys/types.h> /* for u_int32_t, if defined */
|
||||
#include <net/ppp_defs.h>
|
||||
|
||||
#define NPPP 1 /* One PPP interface supported (per process) */
|
||||
#define NUM_PPP 1 /* One PPP interface supported (per process) */
|
||||
|
||||
/*
|
||||
* Limits.
|
||||
*/
|
||||
|
||||
#define MAXWORDLEN 1024 /* max length of word in file (incl null) */
|
||||
#define MAXARGS 1 /* max # args to a command */
|
||||
#define MAXNAMELEN 256 /* max length of hostname or name for auth */
|
||||
@ -42,14 +44,47 @@
|
||||
/*
|
||||
* Global variables.
|
||||
*/
|
||||
extern int debug; /* Debug flag */
|
||||
extern int ifunit; /* Interface unit number */
|
||||
extern char ifname[]; /* Interface name */
|
||||
extern int fd; /* Device file descriptor */
|
||||
extern int s; /* socket descriptor */
|
||||
extern char hostname[]; /* hostname */
|
||||
extern u_char outpacket_buf[]; /* buffer for outgoing packets */
|
||||
extern int phase; /* See values below */
|
||||
|
||||
extern int hungup; /* Physical layer has disconnected */
|
||||
extern int ifunit; /* Interface unit number */
|
||||
extern char ifname[]; /* Interface name */
|
||||
extern int fd; /* Serial device file descriptor */
|
||||
extern char hostname[]; /* Our hostname */
|
||||
extern u_char outpacket_buf[]; /* Buffer for outgoing packets */
|
||||
extern int phase; /* Current state of link - see values below */
|
||||
extern int baud_rate; /* Current link speed in bits/sec */
|
||||
extern char *progname; /* Name of this program */
|
||||
|
||||
/*
|
||||
* Variables set by command-line options.
|
||||
*/
|
||||
|
||||
extern int debug; /* Debug flag */
|
||||
extern int kdebugflag; /* Tell kernel to print debug messages */
|
||||
extern int default_device; /* Using /dev/tty or equivalent */
|
||||
extern char devnam[]; /* Device name */
|
||||
extern int crtscts; /* Use hardware flow control */
|
||||
extern int modem; /* Use modem control lines */
|
||||
extern int inspeed; /* Input/Output speed requested */
|
||||
extern u_int32_t netmask; /* IP netmask to set on interface */
|
||||
extern int lockflag; /* Create lock file to lock the serial dev */
|
||||
extern int nodetach; /* Don't detach from controlling tty */
|
||||
extern char *connector; /* Script to establish physical link */
|
||||
extern char *disconnector; /* Script to disestablish physical link */
|
||||
extern char user[]; /* Username for PAP */
|
||||
extern char passwd[]; /* Password for PAP */
|
||||
extern int auth_required; /* Peer is required to authenticate */
|
||||
extern int proxyarp; /* Set up proxy ARP entry for peer */
|
||||
extern int persist; /* Reopen link after it goes down */
|
||||
extern int uselogin; /* Use /etc/passwd for checking PAP */
|
||||
extern int lcp_echo_interval; /* Interval between LCP echo-requests */
|
||||
extern int lcp_echo_fails; /* Tolerance to unanswered echo-requests */
|
||||
extern char our_name[]; /* Our name for authentication purposes */
|
||||
extern char remote_name[]; /* Peer's name for authentication */
|
||||
extern int usehostname; /* Use hostname for our_name */
|
||||
extern int disable_defaultip; /* Don't use hostname for default IP adrs */
|
||||
extern char *ipparam; /* Extra parameter for ip up/down scripts */
|
||||
extern int cryptpap; /* Others' PAP passwords are encrypted */
|
||||
|
||||
/*
|
||||
* Values for phase.
|
||||
@ -63,21 +98,21 @@ extern int phase; /* See values below */
|
||||
/*
|
||||
* Prototypes.
|
||||
*/
|
||||
void quit __ARGS((void)); /* Cleanup and exit */
|
||||
void timeout __ARGS((void (*)(), caddr_t, int));
|
||||
void quit __P((void)); /* Cleanup and exit */
|
||||
void timeout __P((void (*)(), caddr_t, int));
|
||||
/* Look-alike of kernel's timeout() */
|
||||
void untimeout __ARGS((void (*)(), caddr_t));
|
||||
void untimeout __P((void (*)(), caddr_t));
|
||||
/* Look-alike of kernel's untimeout() */
|
||||
void output __ARGS((int, u_char *, int));
|
||||
void output __P((int, u_char *, int));
|
||||
/* Output a PPP packet */
|
||||
void demuxprotrej __ARGS((int, int));
|
||||
void demuxprotrej __P((int, int));
|
||||
/* Demultiplex a Protocol-Reject */
|
||||
int check_passwd __ARGS((int, char *, int, char *, int, char **, int *));
|
||||
int check_passwd __P((int, char *, int, char *, int, char **, int *));
|
||||
/* Check peer-supplied username/password */
|
||||
int get_secret __ARGS((int, char *, char *, char *, int *, int));
|
||||
int get_secret __P((int, char *, char *, char *, int *, int));
|
||||
/* get "secret" for chap */
|
||||
u_long GetMask __ARGS((u_long)); /* get netmask for address */
|
||||
|
||||
u_int32_t GetMask __P((u_int32_t)); /* get netmask for address */
|
||||
void die __P((int));
|
||||
|
||||
/*
|
||||
* Inline versions of get/put char/short/long.
|
||||
@ -118,6 +153,11 @@ u_long GetMask __ARGS((u_long)); /* get netmask for address */
|
||||
#define INCPTR(n, cp) ((cp) += (n))
|
||||
#define DECPTR(n, cp) ((cp) -= (n))
|
||||
|
||||
#undef FALSE
|
||||
#define FALSE 0
|
||||
#undef TRUE
|
||||
#define TRUE 1
|
||||
|
||||
/*
|
||||
* System dependent definitions for user-level 4.3BSD UNIX implementation.
|
||||
*/
|
||||
@ -137,8 +177,8 @@ u_long GetMask __ARGS((u_long)); /* get netmask for address */
|
||||
* MAKEHEADER - Add Header fields to a packet.
|
||||
*/
|
||||
#define MAKEHEADER(p, t) { \
|
||||
PUTCHAR(ALLSTATIONS, p); \
|
||||
PUTCHAR(UI, p); \
|
||||
PUTCHAR(PPP_ALLSTATIONS, p); \
|
||||
PUTCHAR(PPP_UI, p); \
|
||||
PUTSHORT(t, p); }
|
||||
|
||||
|
||||
|
@ -19,21 +19,28 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: sys-bsd.c,v 1.7 1994/05/30 06:10:07 paulus Exp $";
|
||||
static char rcsid[] = "$Id: sys-bsd.c,v 1.21 1995/08/16 01:40:23 paulus Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/ppp_defs.h>
|
||||
#include <net/if_ppp.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_dl.h>
|
||||
@ -44,12 +51,75 @@ static char rcsid[] = "$Id: sys-bsd.c,v 1.7 1994/05/30 06:10:07 paulus Exp $";
|
||||
#endif
|
||||
|
||||
#include "pppd.h"
|
||||
#include "ppp.h"
|
||||
|
||||
static int initdisc = -1; /* Initial TTY discipline */
|
||||
extern int kdebugflag;
|
||||
static int initdisc = -1; /* Initial TTY discipline */
|
||||
static int rtm_seq;
|
||||
|
||||
static int restore_term; /* 1 => we've munged the terminal */
|
||||
static struct termios inittermios; /* Initial TTY termios */
|
||||
static struct winsize wsinfo; /* Initial window size info */
|
||||
|
||||
static char *lock_file; /* name of lock file created */
|
||||
|
||||
int sockfd; /* socket for doing interface ioctls */
|
||||
|
||||
/*
|
||||
* sys_init - System-dependent initialization.
|
||||
*/
|
||||
void
|
||||
sys_init()
|
||||
{
|
||||
openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
|
||||
setlogmask(LOG_UPTO(LOG_INFO));
|
||||
if (debug)
|
||||
setlogmask(LOG_UPTO(LOG_DEBUG));
|
||||
|
||||
/* Get an internet socket for doing socket ioctl's on. */
|
||||
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
syslog(LOG_ERR, "Couldn't create IP socket: %m");
|
||||
die(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* note_debug_level - note a change in the debug level.
|
||||
*/
|
||||
void
|
||||
note_debug_level()
|
||||
{
|
||||
if (debug) {
|
||||
syslog(LOG_INFO, "Debug turned ON, Level %d", debug);
|
||||
setlogmask(LOG_UPTO(LOG_DEBUG));
|
||||
} else {
|
||||
setlogmask(LOG_UPTO(LOG_WARNING));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ppp_available - check whether the system has any ppp interfaces
|
||||
* (in fact we check whether we can do an ioctl on ppp0).
|
||||
*/
|
||||
int
|
||||
ppp_available()
|
||||
{
|
||||
int s, ok;
|
||||
struct ifreq ifr;
|
||||
extern char *no_ppp_msg;
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
return 1; /* can't tell */
|
||||
|
||||
strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
|
||||
ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
|
||||
close(s);
|
||||
|
||||
no_ppp_msg = "\
|
||||
This system lacks kernel support for PPP. To include PPP support\n\
|
||||
in the kernel, please follow the steps detailed in the README.bsd\n\
|
||||
file in the ppp-2.2 distribution.\n";
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* establish_ppp - Turn the serial port into a ppp interface.
|
||||
*/
|
||||
@ -132,6 +202,111 @@ disestablish_ppp()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
|
||||
* at the requested speed, etc. If `local' is true, set CLOCAL
|
||||
* regardless of whether the modem option was specified.
|
||||
*
|
||||
* For *BSD, we assume that speed_t values numerically equal bits/second.
|
||||
*/
|
||||
set_up_tty(fd, local)
|
||||
int fd, local;
|
||||
{
|
||||
struct termios tios;
|
||||
|
||||
if (tcgetattr(fd, &tios) < 0) {
|
||||
syslog(LOG_ERR, "tcgetattr: %m");
|
||||
die(1);
|
||||
}
|
||||
|
||||
if (!restore_term) {
|
||||
inittermios = tios;
|
||||
ioctl(fd, TIOCGWINSZ, &wsinfo);
|
||||
}
|
||||
|
||||
tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
|
||||
if (crtscts > 0)
|
||||
tios.c_cflag |= CRTSCTS;
|
||||
else if (crtscts < 0)
|
||||
tios.c_cflag &= ~CRTSCTS;
|
||||
|
||||
tios.c_cflag |= CS8 | CREAD | HUPCL;
|
||||
if (local || !modem)
|
||||
tios.c_cflag |= CLOCAL;
|
||||
tios.c_iflag = IGNBRK | IGNPAR;
|
||||
tios.c_oflag = 0;
|
||||
tios.c_lflag = 0;
|
||||
tios.c_cc[VMIN] = 1;
|
||||
tios.c_cc[VTIME] = 0;
|
||||
|
||||
if (crtscts == 2) {
|
||||
tios.c_iflag |= IXOFF;
|
||||
tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
|
||||
tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
|
||||
}
|
||||
|
||||
if (inspeed) {
|
||||
cfsetospeed(&tios, inspeed);
|
||||
cfsetispeed(&tios, inspeed);
|
||||
} else {
|
||||
inspeed = cfgetospeed(&tios);
|
||||
/*
|
||||
* We can't proceed if the serial port speed is 0,
|
||||
* since that implies that the serial port is disabled.
|
||||
*/
|
||||
if (inspeed == 0) {
|
||||
syslog(LOG_ERR, "Baud rate for %s is 0; need explicit baud rate",
|
||||
devnam);
|
||||
die(1);
|
||||
}
|
||||
}
|
||||
baud_rate = inspeed;
|
||||
|
||||
if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
|
||||
syslog(LOG_ERR, "tcsetattr: %m");
|
||||
die(1);
|
||||
}
|
||||
|
||||
restore_term = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* restore_tty - restore the terminal to the saved settings.
|
||||
*/
|
||||
void
|
||||
restore_tty()
|
||||
{
|
||||
if (restore_term) {
|
||||
if (!default_device) {
|
||||
/*
|
||||
* Turn off echoing, because otherwise we can get into
|
||||
* a loop with the tty and the modem echoing to each other.
|
||||
* We presume we are the sole user of this tty device, so
|
||||
* when we close it, it will revert to its defaults anyway.
|
||||
*/
|
||||
inittermios.c_lflag &= ~(ECHO | ECHONL);
|
||||
}
|
||||
if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
|
||||
if (errno != ENXIO)
|
||||
syslog(LOG_WARNING, "tcsetattr: %m");
|
||||
ioctl(fd, TIOCSWINSZ, &wsinfo);
|
||||
restore_term = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* setdtr - control the DTR line on the serial port.
|
||||
* This is called from die(), so it shouldn't call die().
|
||||
*/
|
||||
setdtr(fd, on)
|
||||
int fd, on;
|
||||
{
|
||||
int modembits = TIOCM_DTR;
|
||||
|
||||
ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* output - Output PPP packet.
|
||||
*/
|
||||
@ -153,6 +328,27 @@ output(unit, p, len)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wait_input - wait until there is data available on fd,
|
||||
* for the length of time specified by *timo (indefinite
|
||||
* if timo is NULL).
|
||||
*/
|
||||
wait_input(timo)
|
||||
struct timeval *timo;
|
||||
{
|
||||
fd_set ready;
|
||||
int n;
|
||||
|
||||
FD_ZERO(&ready);
|
||||
FD_SET(fd, &ready);
|
||||
n = select(fd+1, &ready, NULL, &ready, timo);
|
||||
if (n < 0 && errno != EINTR) {
|
||||
syslog(LOG_ERR, "select: %m");
|
||||
die(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* read_packet - get a PPP packet from the serial device.
|
||||
*/
|
||||
@ -162,11 +358,9 @@ read_packet(buf)
|
||||
{
|
||||
int len;
|
||||
|
||||
if ((len = read(fd, buf, MTU + DLLHEADERLEN)) < 0) {
|
||||
if (errno == EWOULDBLOCK) {
|
||||
MAINDEBUG((LOG_DEBUG, "read(fd): EWOULDBLOCK"));
|
||||
if ((len = read(fd, buf, PPP_MTU + PPP_HDRLEN)) < 0) {
|
||||
if (errno == EWOULDBLOCK || errno == EINTR)
|
||||
return -1;
|
||||
}
|
||||
syslog(LOG_ERR, "read(fd): %m");
|
||||
die(1);
|
||||
}
|
||||
@ -181,7 +375,7 @@ read_packet(buf)
|
||||
void
|
||||
ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
|
||||
int unit, mtu;
|
||||
u_long asyncmap;
|
||||
u_int32_t asyncmap;
|
||||
int pcomp, accomp;
|
||||
{
|
||||
u_int x;
|
||||
@ -189,7 +383,7 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
ifr.ifr_mtu = mtu;
|
||||
if (ioctl(s, SIOCSIFMTU, (caddr_t) &ifr) < 0) {
|
||||
if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m");
|
||||
quit();
|
||||
}
|
||||
@ -232,7 +426,7 @@ ppp_set_xaccm(unit, accm)
|
||||
void
|
||||
ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
|
||||
int unit, mru;
|
||||
u_long asyncmap;
|
||||
u_int32_t asyncmap;
|
||||
int pcomp, accomp;
|
||||
{
|
||||
int x;
|
||||
@ -256,6 +450,59 @@ ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ccp_test - ask kernel whether a given compression method
|
||||
* is acceptable for use.
|
||||
*/
|
||||
ccp_test(unit, opt_ptr, opt_len, for_transmit)
|
||||
int unit, opt_len, for_transmit;
|
||||
u_char *opt_ptr;
|
||||
{
|
||||
struct ppp_option_data data;
|
||||
|
||||
data.ptr = opt_ptr;
|
||||
data.length = opt_len;
|
||||
data.transmit = for_transmit;
|
||||
return ioctl(fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ccp_flags_set - inform kernel about the current state of CCP.
|
||||
*/
|
||||
void
|
||||
ccp_flags_set(unit, isopen, isup)
|
||||
int unit, isopen, isup;
|
||||
{
|
||||
int x;
|
||||
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
|
||||
return;
|
||||
}
|
||||
x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN;
|
||||
x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP;
|
||||
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
}
|
||||
|
||||
/*
|
||||
* ccp_fatal_error - returns 1 if decompression was disabled as a
|
||||
* result of an error detected after decompression of a packet,
|
||||
* 0 otherwise. This is necessary because of patent nonsense.
|
||||
*/
|
||||
int
|
||||
ccp_fatal_error(unit)
|
||||
int unit;
|
||||
{
|
||||
int x;
|
||||
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCGFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
return x & SC_DC_FERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* sifvjcomp - config tcp header compression
|
||||
*/
|
||||
@ -285,31 +532,45 @@ sifvjcomp(u, vjcomp, cidcomp, maxcid)
|
||||
/*
|
||||
* sifup - Config the interface up and enable IP packets to pass.
|
||||
*/
|
||||
#ifndef SC_ENABLE_IP
|
||||
#define SC_ENABLE_IP 0x100 /* compat for old versions of kernel code */
|
||||
#endif
|
||||
|
||||
int
|
||||
sifup(u)
|
||||
int u;
|
||||
{
|
||||
struct ifreq ifr;
|
||||
u_int x;
|
||||
struct npioctl npi;
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
ifr.ifr_flags |= IFF_UP;
|
||||
if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
x |= SC_ENABLE_IP;
|
||||
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
return 0;
|
||||
npi.protocol = PPP_IP;
|
||||
npi.mode = NPMODE_PASS;
|
||||
if (ioctl(fd, PPPIOCSNPMODE, &npi) < 0) {
|
||||
if (errno != ENOTTY) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSNPMODE): %m");
|
||||
return 0;
|
||||
}
|
||||
/* for backwards compatibility */
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
x |= SC_ENABLE_IP;
|
||||
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -324,25 +585,37 @@ sifdown(u)
|
||||
struct ifreq ifr;
|
||||
u_int x;
|
||||
int rv;
|
||||
struct npioctl npi;
|
||||
|
||||
rv = 1;
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
|
||||
rv = 0;
|
||||
} else {
|
||||
x &= ~SC_ENABLE_IP;
|
||||
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
npi.protocol = PPP_IP;
|
||||
npi.mode = NPMODE_ERROR;
|
||||
if (ioctl(fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
|
||||
if (errno != ENOTTY) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSNPMODE): %m");
|
||||
rv = 0;
|
||||
} else {
|
||||
/* backwards compatibility */
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
|
||||
rv = 0;
|
||||
} else {
|
||||
x &= ~SC_ENABLE_IP;
|
||||
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
rv = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
|
||||
rv = 0;
|
||||
} else {
|
||||
ifr.ifr_flags &= ~IFF_UP;
|
||||
if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
|
||||
rv = 0;
|
||||
}
|
||||
@ -365,7 +638,7 @@ sifdown(u)
|
||||
int
|
||||
sifaddr(u, o, h, m)
|
||||
int u;
|
||||
u_long o, h, m;
|
||||
u_int32_t o, h, m;
|
||||
{
|
||||
struct ifaliasreq ifra;
|
||||
|
||||
@ -379,7 +652,7 @@ sifaddr(u, o, h, m)
|
||||
((struct sockaddr_in *) &ifra.ifra_mask)->sin_addr.s_addr = m;
|
||||
} else
|
||||
BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));
|
||||
if (ioctl(s, SIOCAIFADDR, (caddr_t) &ifra) < 0) {
|
||||
if (ioctl(sockfd, SIOCAIFADDR, (caddr_t) &ifra) < 0) {
|
||||
if (errno != EEXIST) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCAIFADDR): %m");
|
||||
return 0;
|
||||
@ -396,7 +669,7 @@ sifaddr(u, o, h, m)
|
||||
int
|
||||
cifaddr(u, o, h)
|
||||
int u;
|
||||
u_long o, h;
|
||||
u_int32_t o, h;
|
||||
{
|
||||
struct ifaliasreq ifra;
|
||||
|
||||
@ -406,21 +679,20 @@ cifaddr(u, o, h)
|
||||
SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);
|
||||
((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h;
|
||||
BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));
|
||||
if (ioctl(s, SIOCDIFADDR, (caddr_t) &ifra) < 0) {
|
||||
if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifra) < 0) {
|
||||
syslog(LOG_WARNING, "ioctl(SIOCDIFADDR): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sifdefaultroute - assign a default route through the address given.
|
||||
*/
|
||||
int
|
||||
sifdefaultroute(u, g)
|
||||
int u;
|
||||
u_long g;
|
||||
u_int32_t g;
|
||||
{
|
||||
return dodefaultroute(g, 's');
|
||||
}
|
||||
@ -431,7 +703,7 @@ sifdefaultroute(u, g)
|
||||
int
|
||||
cifdefaultroute(u, g)
|
||||
int u;
|
||||
u_long g;
|
||||
u_int32_t g;
|
||||
{
|
||||
return dodefaultroute(g, 'c');
|
||||
}
|
||||
@ -441,7 +713,7 @@ cifdefaultroute(u, g)
|
||||
*/
|
||||
int
|
||||
dodefaultroute(g, cmd)
|
||||
u_long g;
|
||||
u_int32_t g;
|
||||
int cmd;
|
||||
{
|
||||
int routes;
|
||||
@ -499,7 +771,7 @@ static int arpmsg_valid;
|
||||
int
|
||||
sifproxyarp(unit, hisaddr)
|
||||
int unit;
|
||||
u_long hisaddr;
|
||||
u_int32_t hisaddr;
|
||||
{
|
||||
int routes;
|
||||
int l;
|
||||
@ -549,7 +821,7 @@ sifproxyarp(unit, hisaddr)
|
||||
int
|
||||
cifproxyarp(unit, hisaddr)
|
||||
int unit;
|
||||
u_long hisaddr;
|
||||
u_int32_t hisaddr;
|
||||
{
|
||||
int routes;
|
||||
|
||||
@ -583,7 +855,7 @@ cifproxyarp(unit, hisaddr)
|
||||
int
|
||||
sifproxyarp(unit, hisaddr)
|
||||
int unit;
|
||||
u_long hisaddr;
|
||||
u_int32_t hisaddr;
|
||||
{
|
||||
struct arpreq arpreq;
|
||||
struct {
|
||||
@ -608,7 +880,7 @@ sifproxyarp(unit, hisaddr)
|
||||
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
|
||||
((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
|
||||
arpreq.arp_flags = ATF_PERM | ATF_PUBL;
|
||||
if (ioctl(s, SIOCSARP, (caddr_t)&arpreq) < 0) {
|
||||
if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSARP): %m");
|
||||
return 0;
|
||||
}
|
||||
@ -622,14 +894,14 @@ sifproxyarp(unit, hisaddr)
|
||||
int
|
||||
cifproxyarp(unit, hisaddr)
|
||||
int unit;
|
||||
u_long hisaddr;
|
||||
u_int32_t hisaddr;
|
||||
{
|
||||
struct arpreq arpreq;
|
||||
|
||||
BZERO(&arpreq, sizeof(arpreq));
|
||||
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
|
||||
((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
|
||||
if (ioctl(s, SIOCDARP, (caddr_t)&arpreq) < 0) {
|
||||
if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) {
|
||||
syslog(LOG_WARNING, "ioctl(SIOCDARP): %m");
|
||||
return 0;
|
||||
}
|
||||
@ -646,11 +918,11 @@ cifproxyarp(unit, hisaddr)
|
||||
|
||||
int
|
||||
get_ether_addr(ipaddr, hwaddr)
|
||||
u_long ipaddr;
|
||||
u_int32_t ipaddr;
|
||||
struct sockaddr_dl *hwaddr;
|
||||
{
|
||||
struct ifreq *ifr, *ifend, *ifp;
|
||||
u_long ina, mask;
|
||||
u_int32_t ina, mask;
|
||||
struct sockaddr_dl *dla;
|
||||
struct ifreq ifreq;
|
||||
struct ifconf ifc;
|
||||
@ -658,7 +930,7 @@ get_ether_addr(ipaddr, hwaddr)
|
||||
|
||||
ifc.ifc_len = sizeof(ifs);
|
||||
ifc.ifc_req = ifs;
|
||||
if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
|
||||
if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m");
|
||||
return 0;
|
||||
}
|
||||
@ -668,7 +940,8 @@ get_ether_addr(ipaddr, hwaddr)
|
||||
* address on the same subnet as `ipaddr'.
|
||||
*/
|
||||
ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
|
||||
for (ifr = ifc.ifc_req; ifr < ifend; ) {
|
||||
for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *)
|
||||
((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) {
|
||||
if (ifr->ifr_addr.sa_family == AF_INET) {
|
||||
ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
|
||||
strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
|
||||
@ -676,7 +949,7 @@ get_ether_addr(ipaddr, hwaddr)
|
||||
* Check that the interface is up, and not point-to-point
|
||||
* or loopback.
|
||||
*/
|
||||
if (ioctl(s, SIOCGIFFLAGS, &ifreq) < 0)
|
||||
if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
|
||||
continue;
|
||||
if ((ifreq.ifr_flags &
|
||||
(IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
|
||||
@ -685,15 +958,14 @@ get_ether_addr(ipaddr, hwaddr)
|
||||
/*
|
||||
* Get its netmask and check that it's on the right subnet.
|
||||
*/
|
||||
if (ioctl(s, SIOCGIFNETMASK, &ifreq) < 0)
|
||||
if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
|
||||
continue;
|
||||
mask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
|
||||
mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;
|
||||
if ((ipaddr & mask) != (ina & mask))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len);
|
||||
}
|
||||
|
||||
if (ifr >= ifend)
|
||||
@ -721,23 +993,143 @@ get_ether_addr(ipaddr, hwaddr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return user specified netmask, modified by any mask we might determine
|
||||
* for address `addr' (in network byte order).
|
||||
* Here we scan through the system's list of interfaces, looking for
|
||||
* any non-point-to-point interfaces which might appear to be on the same
|
||||
* network as `addr'. If we find any, we OR in their netmask to the
|
||||
* user-specified netmask.
|
||||
*/
|
||||
u_int32_t
|
||||
GetMask(addr)
|
||||
u_int32_t addr;
|
||||
{
|
||||
u_int32_t mask, nmask, ina;
|
||||
struct ifreq *ifr, *ifend, ifreq;
|
||||
struct ifconf ifc;
|
||||
struct ifreq ifs[MAX_IFS];
|
||||
|
||||
addr = ntohl(addr);
|
||||
if (IN_CLASSA(addr)) /* determine network mask for address class */
|
||||
nmask = IN_CLASSA_NET;
|
||||
else if (IN_CLASSB(addr))
|
||||
nmask = IN_CLASSB_NET;
|
||||
else
|
||||
nmask = IN_CLASSC_NET;
|
||||
/* class D nets are disallowed by bad_ip_adrs */
|
||||
mask = netmask | htonl(nmask);
|
||||
|
||||
/*
|
||||
* Scan through the system's network interfaces.
|
||||
*/
|
||||
ifc.ifc_len = sizeof(ifs);
|
||||
ifc.ifc_req = ifs;
|
||||
if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
|
||||
syslog(LOG_WARNING, "ioctl(SIOCGIFCONF): %m");
|
||||
return mask;
|
||||
}
|
||||
ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
|
||||
for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *)
|
||||
((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) {
|
||||
/*
|
||||
* Check the interface's internet address.
|
||||
*/
|
||||
if (ifr->ifr_addr.sa_family != AF_INET)
|
||||
continue;
|
||||
ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
|
||||
if ((ntohl(ina) & nmask) != (addr & nmask))
|
||||
continue;
|
||||
/*
|
||||
* Check that the interface is up, and not point-to-point or loopback.
|
||||
*/
|
||||
strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
|
||||
if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
|
||||
continue;
|
||||
if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))
|
||||
!= IFF_UP)
|
||||
continue;
|
||||
/*
|
||||
* Get its netmask and OR it into our mask.
|
||||
*/
|
||||
if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
|
||||
continue;
|
||||
mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* ppp_available - check whether the system has any ppp interfaces
|
||||
* (in fact we check whether we can do an ioctl on ppp0).
|
||||
* lock - create a lock file for the named lock device
|
||||
*/
|
||||
#define LOCK_PREFIX "/var/spool/lock/LCK.."
|
||||
|
||||
int
|
||||
ppp_available()
|
||||
lock(dev)
|
||||
char *dev;
|
||||
{
|
||||
int s, ok;
|
||||
struct ifreq ifr;
|
||||
char hdb_lock_buffer[12];
|
||||
int fd, pid, n;
|
||||
char *p;
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
return 1; /* can't tell - maybe we're not root */
|
||||
if ((p = strrchr(dev, '/')) != NULL)
|
||||
dev = p + 1;
|
||||
lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1);
|
||||
if (lock_file == NULL)
|
||||
novm("lock file name");
|
||||
strcat(strcpy(lock_file, LOCK_PREFIX), dev);
|
||||
|
||||
strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
|
||||
ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
|
||||
close(s);
|
||||
while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
|
||||
if (errno == EEXIST
|
||||
&& (fd = open(lock_file, O_RDONLY, 0)) >= 0) {
|
||||
/* Read the lock file to find out who has the device locked */
|
||||
n = read(fd, hdb_lock_buffer, 11);
|
||||
if (n > 0) {
|
||||
hdb_lock_buffer[n] = 0;
|
||||
pid = atoi(hdb_lock_buffer);
|
||||
}
|
||||
if (n <= 0) {
|
||||
syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file);
|
||||
close(fd);
|
||||
} else {
|
||||
if (kill(pid, 0) == -1 && errno == ESRCH) {
|
||||
/* pid no longer exists - remove the lock file */
|
||||
if (unlink(lock_file) == 0) {
|
||||
close(fd);
|
||||
syslog(LOG_NOTICE, "Removed stale lock on %s (pid %d)",
|
||||
dev, pid);
|
||||
continue;
|
||||
} else
|
||||
syslog(LOG_WARNING, "Couldn't remove stale lock on %s",
|
||||
dev);
|
||||
} else
|
||||
syslog(LOG_NOTICE, "Device %s is locked by pid %d",
|
||||
dev, pid);
|
||||
}
|
||||
close(fd);
|
||||
} else
|
||||
syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file);
|
||||
free(lock_file);
|
||||
lock_file = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ok;
|
||||
sprintf(hdb_lock_buffer, "%10d\n", getpid());
|
||||
write(fd, hdb_lock_buffer, 11);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* unlock - remove our lockfile
|
||||
*/
|
||||
unlock()
|
||||
{
|
||||
if (lock_file) {
|
||||
unlink(lock_file);
|
||||
free(lock_file);
|
||||
lock_file = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1,830 +0,0 @@
|
||||
/*
|
||||
* sys-linux.c - System-dependent procedures for setting up
|
||||
* PPP interfaces on Linux systems
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <memory.h>
|
||||
#include <utmp.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/errno.h>
|
||||
#include <mntent.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <linux/ppp.h>
|
||||
#include <linux/route.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <netinet/in.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "ppp.h"
|
||||
#include "fsm.h"
|
||||
#include "ipcp.h"
|
||||
|
||||
static int initdisc = -1; /* Initial TTY discipline */
|
||||
static int prev_kdebugflag = 0;
|
||||
extern int kdebugflag;
|
||||
extern u_long netmask;
|
||||
|
||||
#define MAX_IFS 32
|
||||
|
||||
/* prototypes */
|
||||
void die __ARGS((int));
|
||||
|
||||
/*
|
||||
* SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
|
||||
* if it exists.
|
||||
*/
|
||||
|
||||
#define SET_SA_FAMILY(addr, family) \
|
||||
memset ((char *) &(addr), '\0', sizeof(addr)); \
|
||||
addr.sa_family = (family);
|
||||
|
||||
/*
|
||||
* set_kdebugflag - Define the debugging level for the kernel
|
||||
*/
|
||||
|
||||
int set_kdebugflag (int requested_level)
|
||||
{
|
||||
if (ioctl(fd, PPPIOCGDEBUG, &prev_kdebugflag) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCGDEBUG): %m");
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (prev_kdebugflag != requested_level) {
|
||||
if (ioctl(fd, PPPIOCSDEBUG, &requested_level) < 0) {
|
||||
syslog (LOG_ERR, "ioctl(PPPIOCSDEBUG): %m");
|
||||
return (0);
|
||||
}
|
||||
syslog(LOG_INFO, "set kernel debugging level to %d", requested_level);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* establish_ppp - Turn the serial port into a ppp interface.
|
||||
*/
|
||||
|
||||
void establish_ppp (void)
|
||||
{
|
||||
int pppdisc = N_PPP;
|
||||
int sig = SIGIO;
|
||||
|
||||
if (ioctl(fd, PPPIOCSINPSIG, &sig) == -1) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSINPSIG): %m");
|
||||
die(1);
|
||||
}
|
||||
|
||||
if (ioctl(fd, TIOCEXCL, 0) < 0) {
|
||||
syslog (LOG_WARNING, "ioctl(TIOCEXCL): %m");
|
||||
}
|
||||
|
||||
if (ioctl(fd, TIOCGETD, &initdisc) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(TIOCGETD): %m");
|
||||
die (1);
|
||||
}
|
||||
|
||||
if (ioctl(fd, TIOCSETD, &pppdisc) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(TIOCSETD): %m");
|
||||
die (1);
|
||||
}
|
||||
|
||||
if (ioctl(fd, PPPIOCGUNIT, &ifunit) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m");
|
||||
die (1);
|
||||
}
|
||||
|
||||
set_kdebugflag (kdebugflag);
|
||||
}
|
||||
|
||||
/*
|
||||
* disestablish_ppp - Restore the serial port to normal operation.
|
||||
* This shouldn't call die() because it's called from die().
|
||||
*/
|
||||
|
||||
void disestablish_ppp(void)
|
||||
{
|
||||
int x;
|
||||
char *s;
|
||||
|
||||
if (initdisc >= 0) {
|
||||
set_kdebugflag (prev_kdebugflag);
|
||||
/*
|
||||
* Check whether the link seems not to be 8-bit clean.
|
||||
*/
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
|
||||
s = NULL;
|
||||
switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
|
||||
case SC_RCV_B7_0:
|
||||
s = "bit 7 set to 1";
|
||||
break;
|
||||
case SC_RCV_B7_1:
|
||||
s = "bit 7 set to 0";
|
||||
break;
|
||||
case SC_RCV_EVNP:
|
||||
s = "odd parity";
|
||||
break;
|
||||
case SC_RCV_ODDP:
|
||||
s = "even parity";
|
||||
break;
|
||||
}
|
||||
if (s != NULL) {
|
||||
syslog(LOG_WARNING, "Serial link is not 8-bit clean:");
|
||||
syslog(LOG_WARNING, "All received characters had %s", s);
|
||||
}
|
||||
}
|
||||
|
||||
if (ioctl(fd, TIOCSETD, &initdisc) < 0)
|
||||
syslog(LOG_ERR, "ioctl(TIOCSETD): %m");
|
||||
|
||||
if (ioctl(fd, TIOCNXCL, 0) < 0)
|
||||
syslog (LOG_WARNING, "ioctl(TIOCNXCL): %m");
|
||||
|
||||
initdisc = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* output - Output PPP packet.
|
||||
*/
|
||||
|
||||
void output (int unit, unsigned char *p, int len)
|
||||
{
|
||||
if (unit != 0)
|
||||
MAINDEBUG((LOG_WARNING, "output: unit != 0!"));
|
||||
|
||||
if (debug)
|
||||
log_packet(p, len, "sent ");
|
||||
|
||||
if (write(fd, p, len) < 0) {
|
||||
syslog(LOG_ERR, "write: %m");
|
||||
die(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* read_packet - get a PPP packet from the serial device.
|
||||
*/
|
||||
|
||||
int read_packet (unsigned char *buf)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = read(fd, buf, MTU + DLLHEADERLEN);
|
||||
if (len < 0) {
|
||||
if (errno == EWOULDBLOCK) {
|
||||
#if 0
|
||||
MAINDEBUG((LOG_DEBUG, "read(fd): EWOULDBLOCK"));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
syslog(LOG_ERR, "read(fd): %m");
|
||||
die(1);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* ppp_send_config - configure the transmit characteristics of
|
||||
* the ppp interface.
|
||||
*/
|
||||
void ppp_send_config (int unit,int mtu,u_long asyncmap,int pcomp,int accomp)
|
||||
{
|
||||
u_int x;
|
||||
struct ifreq ifr;
|
||||
|
||||
MAINDEBUG ((LOG_DEBUG, "send_config: mtu = %d\n", mtu));
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
ifr.ifr_mtu = mtu;
|
||||
if (ioctl(s, SIOCSIFMTU, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m");
|
||||
quit();
|
||||
}
|
||||
|
||||
MAINDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap));
|
||||
if (ioctl(fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSASYNCMAP): %m");
|
||||
quit();
|
||||
}
|
||||
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
|
||||
quit();
|
||||
}
|
||||
|
||||
x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT;
|
||||
x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC;
|
||||
|
||||
MAINDEBUG ((LOG_DEBUG, "send_config: flags = %x\n", x));
|
||||
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
quit();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ppp_set_xaccm - set the extended transmit ACCM for the interface.
|
||||
*/
|
||||
void
|
||||
ppp_set_xaccm(unit, accm)
|
||||
int unit;
|
||||
ext_accm accm;
|
||||
{
|
||||
MAINDEBUG ((LOG_DEBUG, "set_xaccm: %08lx %08lx %08lx %08lx\n",
|
||||
accm[0], accm[1], accm[2], accm[3]));
|
||||
if (ioctl(fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY)
|
||||
syslog(LOG_WARNING, "ioctl(set extended ACCM): %m");
|
||||
}
|
||||
|
||||
/*
|
||||
* ppp_recv_config - configure the receive-side characteristics of
|
||||
* the ppp interface.
|
||||
*/
|
||||
void ppp_recv_config (int unit,int mru,u_long asyncmap,int pcomp,int accomp)
|
||||
{
|
||||
u_int x;
|
||||
|
||||
MAINDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru));
|
||||
if (ioctl(fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %m");
|
||||
|
||||
MAINDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap));
|
||||
if (ioctl(fd, PPPIOCRASYNCMAP, (caddr_t) &asyncmap) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCRASYNCMAP): %m");
|
||||
quit();
|
||||
}
|
||||
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
|
||||
quit();
|
||||
}
|
||||
|
||||
x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC;
|
||||
MAINDEBUG ((LOG_DEBUG, "recv_config: flags = %x\n", x));
|
||||
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
quit();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sifvjcomp - config tcp header compression
|
||||
*/
|
||||
|
||||
int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
|
||||
{
|
||||
u_int x;
|
||||
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
x = vjcomp ? x | SC_COMP_TCP : x &~ SC_COMP_TCP;
|
||||
x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID;
|
||||
|
||||
if(ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vjcomp) {
|
||||
if (ioctl (fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
|
||||
syslog (LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sifup - Config the interface up and enable IP packets to pass.
|
||||
*/
|
||||
|
||||
int sifup (int u)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
|
||||
if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sifdown - Config the interface down and disable IP.
|
||||
*/
|
||||
|
||||
int sifdown (int u)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ifr.ifr_flags &= ~IFF_UP;
|
||||
ifr.ifr_flags |= IFF_POINTOPOINT;
|
||||
if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sifaddr - Config the interface IP addresses and netmask.
|
||||
*/
|
||||
|
||||
int sifaddr (int unit, int our_adr, int his_adr, int net_mask)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
struct rtentry rt;
|
||||
|
||||
SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
|
||||
SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
|
||||
SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
|
||||
|
||||
strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
/*
|
||||
* Set our IP address
|
||||
*/
|
||||
((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = our_adr;
|
||||
if (ioctl(s, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
|
||||
if (errno != EEXIST)
|
||||
syslog (LOG_ERR, "ioctl(SIOCAIFADDR): %m");
|
||||
else
|
||||
syslog (LOG_WARNING, "ioctl(SIOCAIFADDR): Address already exists");
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* Set the gateway address
|
||||
*/
|
||||
((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = his_adr;
|
||||
if (ioctl(s, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
|
||||
syslog (LOG_ERR, "ioctl(SIOCSIFDSTADDR): %m");
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* Set the netmask
|
||||
*/
|
||||
if (net_mask != 0) {
|
||||
((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr.s_addr = net_mask;
|
||||
if (ioctl(s, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
|
||||
syslog (LOG_ERR, "ioctl(SIOCSIFNETMASK): %m");
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Add the device route
|
||||
*/
|
||||
memset (&rt, '\0', sizeof (rt));
|
||||
|
||||
SET_SA_FAMILY (rt.rt_dst, AF_INET);
|
||||
SET_SA_FAMILY (rt.rt_gateway, AF_INET);
|
||||
rt.rt_dev = ifname; /* MJC */
|
||||
|
||||
((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0;
|
||||
((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = his_adr;
|
||||
rt.rt_flags = RTF_UP | RTF_HOST;
|
||||
|
||||
if (ioctl(s, SIOCADDRT, &rt) < 0) {
|
||||
syslog (LOG_ERR, "ioctl(SIOCADDRT) device route: %m");
|
||||
return (0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* cifaddr - Clear the interface IP addresses, and delete routes
|
||||
* through the interface if possible.
|
||||
*/
|
||||
|
||||
int cifaddr (int unit, int our_adr, int his_adr)
|
||||
{
|
||||
struct rtentry rt;
|
||||
/*
|
||||
* Delete the route through the device
|
||||
*/
|
||||
memset (&rt, '\0', sizeof (rt));
|
||||
|
||||
SET_SA_FAMILY (rt.rt_dst, AF_INET);
|
||||
SET_SA_FAMILY (rt.rt_gateway, AF_INET);
|
||||
rt.rt_dev = ifname; /* MJC */
|
||||
|
||||
((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0;
|
||||
((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = his_adr;
|
||||
rt.rt_flags = RTF_UP | RTF_HOST;
|
||||
|
||||
if (ioctl(s, SIOCDELRT, &rt) < 0) {
|
||||
syslog (LOG_ERR, "ioctl(SIOCDELRT) device route: %m");
|
||||
return (0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* path_to_route - determine the path to the proc file system data
|
||||
*/
|
||||
|
||||
FILE *route_fd = (FILE *) 0;
|
||||
static char route_buffer [100];
|
||||
|
||||
static char *path_to_route (void);
|
||||
static int open_route_table (void);
|
||||
static void close_route_table (void);
|
||||
static int read_route_table (struct rtentry *rt);
|
||||
static int defaultroute_exists (void);
|
||||
|
||||
/*
|
||||
* path_to_route - find the path to the route tables in the proc file system
|
||||
*/
|
||||
|
||||
static char *path_to_route (void)
|
||||
{
|
||||
struct mntent *mntent;
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen (MOUNTED, "r");
|
||||
if (fp != 0) {
|
||||
while ((mntent = getmntent (fp)) != 0) {
|
||||
if (strcmp (mntent->mnt_type, MNTTYPE_IGNORE) == 0)
|
||||
continue;
|
||||
|
||||
if (strcmp (mntent->mnt_type, "proc") == 0) {
|
||||
strncpy (route_buffer, mntent->mnt_dir,
|
||||
sizeof (route_buffer)-10);
|
||||
route_buffer [sizeof (route_buffer)-10] = '\0';
|
||||
strcat (route_buffer, "/net/route");
|
||||
|
||||
fclose (fp);
|
||||
return (route_buffer);
|
||||
}
|
||||
}
|
||||
fclose (fp);
|
||||
}
|
||||
syslog (LOG_ERR, "proc file system not mounted");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* open_route_table - open the interface to the route table
|
||||
*/
|
||||
|
||||
static int open_route_table (void)
|
||||
{
|
||||
char *path;
|
||||
|
||||
if (route_fd != (FILE *) 0)
|
||||
close_route_table();
|
||||
|
||||
path = path_to_route();
|
||||
if (path == NULL)
|
||||
return 0;
|
||||
|
||||
route_fd = fopen (path, "r");
|
||||
if (route_fd == (FILE *) 0) {
|
||||
syslog (LOG_ERR, "can not open %s: %m", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read and discard the header line. */
|
||||
if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0) {
|
||||
close_route_table();
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* close_route_table - close the interface to the route table
|
||||
*/
|
||||
|
||||
static void close_route_table (void)
|
||||
{
|
||||
if (route_fd != (FILE *) 0) {
|
||||
fclose (route_fd);
|
||||
route_fd = (FILE *) 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* read_route_table - read the next entry from the route table
|
||||
*/
|
||||
|
||||
static int read_route_table (struct rtentry *rt)
|
||||
{
|
||||
static char delims[] = " \t\n";
|
||||
char *dev_ptr, *ptr, *dst_ptr, *gw_ptr, *flag_ptr;
|
||||
|
||||
if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
|
||||
return 0;
|
||||
|
||||
memset (rt, '\0', sizeof (struct rtentry));
|
||||
|
||||
dev_ptr = strtok (route_buffer, delims); /* interface name */
|
||||
dst_ptr = strtok (NULL, delims); /* destination address */
|
||||
gw_ptr = strtok (NULL, delims); /* gateway */
|
||||
flag_ptr = strtok (NULL, delims); /* flags */
|
||||
#if 0
|
||||
ptr = strtok (NULL, delims); /* reference count */
|
||||
ptr = strtok (NULL, delims); /* useage count */
|
||||
ptr = strtok (NULL, delims); /* metric */
|
||||
ptr = strtok (NULL, delims); /* mask */
|
||||
#endif
|
||||
|
||||
((struct sockaddr_in *) &rt->rt_dst)->sin_addr.s_addr =
|
||||
strtoul (dst_ptr, NULL, 16);
|
||||
|
||||
((struct sockaddr_in *) &rt->rt_gateway)->sin_addr.s_addr =
|
||||
strtoul (gw_ptr, NULL, 16);
|
||||
|
||||
rt->rt_flags = (short) strtoul (flag_ptr, NULL, 16);
|
||||
rt->rt_dev = dev_ptr;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* defaultroute_exists - determine if there is a default route
|
||||
*/
|
||||
|
||||
static int defaultroute_exists (void)
|
||||
{
|
||||
struct rtentry rt;
|
||||
int result = 0;
|
||||
|
||||
if (!open_route_table())
|
||||
return 0;
|
||||
|
||||
while (read_route_table(&rt) != 0) {
|
||||
if (rt.rt_flags & RTF_UP == 0)
|
||||
continue;
|
||||
|
||||
if (((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr == 0L) {
|
||||
syslog (LOG_ERR,
|
||||
"ppp not replacing existing default route to %s[%s]",
|
||||
rt.rt_dev,
|
||||
inet_ntoa (((struct sockaddr_in *) &rt.rt_gateway)->
|
||||
sin_addr.s_addr));
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
close_route_table();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* sifdefaultroute - assign a default route through the address given.
|
||||
*/
|
||||
|
||||
int sifdefaultroute (int unit, int gateway)
|
||||
{
|
||||
struct rtentry rt;
|
||||
|
||||
if (defaultroute_exists())
|
||||
return 0;
|
||||
|
||||
memset (&rt, '\0', sizeof (rt));
|
||||
SET_SA_FAMILY (rt.rt_dst, AF_INET);
|
||||
SET_SA_FAMILY (rt.rt_gateway, AF_INET);
|
||||
((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
|
||||
|
||||
rt.rt_flags = RTF_UP | RTF_GATEWAY;
|
||||
if (ioctl(s, SIOCADDRT, &rt) < 0) {
|
||||
syslog (LOG_ERR, "default route ioctl(SIOCADDRT): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* cifdefaultroute - delete a default route through the address given.
|
||||
*/
|
||||
|
||||
int cifdefaultroute (int unit, int gateway)
|
||||
{
|
||||
struct rtentry rt;
|
||||
|
||||
SET_SA_FAMILY (rt.rt_dst, AF_INET);
|
||||
SET_SA_FAMILY (rt.rt_gateway, AF_INET);
|
||||
((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
|
||||
|
||||
rt.rt_flags = RTF_UP | RTF_GATEWAY;
|
||||
if (ioctl(s, SIOCDELRT, &rt) < 0) {
|
||||
syslog (LOG_ERR, "default route ioctl(SIOCDELRT): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sifproxyarp - Make a proxy ARP entry for the peer.
|
||||
*/
|
||||
|
||||
int sifproxyarp (int unit, u_long his_adr)
|
||||
{
|
||||
struct arpreq arpreq;
|
||||
|
||||
memset (&arpreq, '\0', sizeof(arpreq));
|
||||
/*
|
||||
* Get the hardware address of an interface on the same subnet
|
||||
* as our local address.
|
||||
*/
|
||||
if (!get_ether_addr(his_adr, &arpreq.arp_ha)) {
|
||||
syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
|
||||
((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr;
|
||||
arpreq.arp_flags = ATF_PERM | ATF_PUBL;
|
||||
|
||||
if (ioctl(s, SIOCSARP, (caddr_t)&arpreq) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSARP): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* cifproxyarp - Delete the proxy ARP entry for the peer.
|
||||
*/
|
||||
|
||||
int cifproxyarp (int unit, u_long his_adr)
|
||||
{
|
||||
struct arpreq arpreq;
|
||||
|
||||
memset (&arpreq, '\0', sizeof(arpreq));
|
||||
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
|
||||
|
||||
((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr;
|
||||
if (ioctl(s, SIOCDARP, (caddr_t)&arpreq) < 0) {
|
||||
syslog(LOG_WARNING, "ioctl(SIOCDARP): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_ether_addr - get the hardware address of an interface on the
|
||||
* the same subnet as ipaddr.
|
||||
*/
|
||||
|
||||
int get_ether_addr (u_long ipaddr, struct sockaddr *hwaddr)
|
||||
{
|
||||
struct ifreq *ifr, *ifend, *ifp;
|
||||
int i;
|
||||
u_long ina, mask;
|
||||
struct sockaddr_dl *dla;
|
||||
struct ifreq ifreq;
|
||||
struct ifconf ifc;
|
||||
struct ifreq ifs[MAX_IFS];
|
||||
|
||||
ifc.ifc_len = sizeof(ifs);
|
||||
ifc.ifc_req = ifs;
|
||||
if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m");
|
||||
return 0;
|
||||
}
|
||||
MAINDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s",
|
||||
ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr)));
|
||||
/*
|
||||
* Scan through looking for an interface with an Internet
|
||||
* address on the same subnet as `ipaddr'.
|
||||
*/
|
||||
ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
|
||||
for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
|
||||
if (ifr->ifr_addr.sa_family == AF_INET) {
|
||||
ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
|
||||
strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
|
||||
MAINDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",
|
||||
ifreq.ifr_name));
|
||||
/*
|
||||
* Check that the interface is up, and not point-to-point
|
||||
* or loopback.
|
||||
*/
|
||||
if (ioctl(s, SIOCGIFFLAGS, &ifreq) < 0)
|
||||
continue;
|
||||
if ((ifreq.ifr_flags &
|
||||
(IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
|
||||
!= (IFF_UP|IFF_BROADCAST))
|
||||
continue;
|
||||
/*
|
||||
* Get its netmask and check that it's on the right subnet.
|
||||
*/
|
||||
if (ioctl(s, SIOCGIFNETMASK, &ifreq) < 0)
|
||||
continue;
|
||||
mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;
|
||||
MAINDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx",
|
||||
ip_ntoa(ina), ntohl(mask)));
|
||||
if (((ipaddr ^ ina) & mask) != 0)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ifr >= ifend)
|
||||
return 0;
|
||||
|
||||
syslog(LOG_INFO, "found interface %s for proxy arp", ifreq.ifr_name);
|
||||
/*
|
||||
* Now get the hardware address.
|
||||
*/
|
||||
if (ioctl (s, SIOCGIFHWADDR, &ifreq) < 0) {
|
||||
syslog(LOG_ERR, "SIOCGIFHWADDR(%s): %m", ifreq.ifr_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hwaddr->sa_family = ARPHRD_ETHER;
|
||||
#ifndef old_ifr_hwaddr
|
||||
memcpy (&hwaddr->sa_data, &ifreq.ifr_hwaddr, ETH_ALEN);
|
||||
#else
|
||||
memcpy (&hwaddr->sa_data, &ifreq.ifr_hwaddr.sa_data, ETH_ALEN);
|
||||
#endif
|
||||
|
||||
MAINDEBUG ((LOG_DEBUG,
|
||||
"proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
(int) ((unsigned char *) &hwaddr->sa_data)[0],
|
||||
(int) ((unsigned char *) &hwaddr->sa_data)[1],
|
||||
(int) ((unsigned char *) &hwaddr->sa_data)[2],
|
||||
(int) ((unsigned char *) &hwaddr->sa_data)[3],
|
||||
(int) ((unsigned char *) &hwaddr->sa_data)[4],
|
||||
(int) ((unsigned char *) &hwaddr->sa_data)[5]));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* ppp_available - check whether the system has any ppp interfaces
|
||||
* (in fact we check whether we can do an ioctl on ppp0).
|
||||
*/
|
||||
|
||||
int ppp_available(void)
|
||||
{
|
||||
int s, ok;
|
||||
struct ifreq ifr;
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0)
|
||||
return 1; /* can't tell - maybe we're not root */
|
||||
|
||||
strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
|
||||
ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
|
||||
close(s);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
int
|
||||
logwtmp(line, name, host)
|
||||
char *line, *name, *host;
|
||||
{
|
||||
struct utmp ut;
|
||||
|
||||
memset (&ut, 0, sizeof (ut));
|
||||
(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
|
||||
(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
|
||||
(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
|
||||
(void)time(&ut.ut_time);
|
||||
|
||||
pututline (&ut); /* Write the line to the proper place */
|
||||
endutent(); /* Indicate operation is complete */
|
||||
}
|
@ -1,730 +0,0 @@
|
||||
/*
|
||||
* sys-str.c - System-dependent procedures for setting up
|
||||
* PPP interfaces on systems which use the STREAMS ppp interface.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <utmp.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/stropts.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "ppp.h"
|
||||
#include <net/ppp_str.h>
|
||||
|
||||
#ifndef ifr_mtu
|
||||
#define ifr_mtu ifr_metric
|
||||
#endif
|
||||
|
||||
#define MAXMODULES 10 /* max number of module names to save */
|
||||
static struct modlist {
|
||||
char modname[FMNAMESZ+1];
|
||||
} str_modules[MAXMODULES];
|
||||
static int str_module_count = 0;
|
||||
static int pushed_ppp;
|
||||
|
||||
extern int hungup; /* has the physical layer been disconnected? */
|
||||
extern int kdebugflag;
|
||||
|
||||
#define PAI_FLAGS_B7_0 0x100
|
||||
#define PAI_FLAGS_B7_1 0x200
|
||||
#define PAI_FLAGS_PAR_EVEN 0x400
|
||||
#define PAI_FLAGS_PAR_ODD 0x800
|
||||
#define PAI_FLAGS_HIBITS 0xF00
|
||||
|
||||
/*
|
||||
* ppp_available - check if this kernel supports PPP.
|
||||
*/
|
||||
int
|
||||
ppp_available()
|
||||
{
|
||||
int fd, ret;
|
||||
|
||||
fd = open("/dev/tty", O_RDONLY, 0);
|
||||
if (fd < 0)
|
||||
return 1; /* can't find out - assume we have ppp */
|
||||
ret = ioctl(fd, I_FIND, "pppasync") >= 0;
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* establish_ppp - Turn the serial port into a ppp interface.
|
||||
*/
|
||||
void
|
||||
establish_ppp()
|
||||
{
|
||||
/* go through and save the name of all the modules, then pop em */
|
||||
for (;;) {
|
||||
if (ioctl(fd, I_LOOK, str_modules[str_module_count].modname) < 0 ||
|
||||
ioctl(fd, I_POP, 0) < 0)
|
||||
break;
|
||||
MAINDEBUG((LOG_DEBUG, "popped stream module : %s",
|
||||
str_modules[str_module_count].modname));
|
||||
str_module_count++;
|
||||
}
|
||||
|
||||
/* now push the async/fcs module */
|
||||
if (ioctl(fd, I_PUSH, "pppasync") < 0) {
|
||||
syslog(LOG_ERR, "ioctl(I_PUSH, ppp_async): %m");
|
||||
die(1);
|
||||
}
|
||||
/* finally, push the ppp_if module that actually handles the */
|
||||
/* network interface */
|
||||
if (ioctl(fd, I_PUSH, "pppif") < 0) {
|
||||
syslog(LOG_ERR, "ioctl(I_PUSH, ppp_if): %m");
|
||||
die(1);
|
||||
}
|
||||
pushed_ppp = 1;
|
||||
if (ioctl(fd, I_SETSIG, S_INPUT) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(I_SETSIG, S_INPUT): %m");
|
||||
die(1);
|
||||
}
|
||||
/* read mode, message non-discard mode */
|
||||
if (ioctl(fd, I_SRDOPT, RMSGN) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(I_SRDOPT, RMSGN): %m");
|
||||
die(1);
|
||||
}
|
||||
/* Flush any waiting messages, or we'll never get SIGPOLL */
|
||||
if (ioctl(fd, I_FLUSH, FLUSHRW) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(I_FLUSH, FLUSHRW): %m");
|
||||
die(1);
|
||||
}
|
||||
/*
|
||||
* Find out which interface we were given.
|
||||
* (ppp_if handles this ioctl)
|
||||
*/
|
||||
if (ioctl(fd, SIOCGETU, &ifunit) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCGETU): %m");
|
||||
die(1);
|
||||
}
|
||||
|
||||
/* Set debug flags in driver */
|
||||
if (ioctl(fd, SIOCSIFDEBUG, &kdebugflag) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFDEBUG): %m");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* disestablish_ppp - Restore the serial port to normal operation.
|
||||
* It attempts to reconstruct the stream with the previously popped
|
||||
* modules. This shouldn't call die() because it's called from die().
|
||||
*/
|
||||
void
|
||||
disestablish_ppp()
|
||||
{
|
||||
int flags;
|
||||
char *s;
|
||||
|
||||
if (hungup) {
|
||||
/* we can't push or pop modules after the stream has hung up */
|
||||
str_module_count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (pushed_ppp) {
|
||||
/*
|
||||
* Check whether the link seems not to be 8-bit clean.
|
||||
*/
|
||||
if (ioctl(fd, SIOCGIFDEBUG, (caddr_t) &flags) == 0) {
|
||||
s = NULL;
|
||||
switch (~flags & PAI_FLAGS_HIBITS) {
|
||||
case PAI_FLAGS_B7_0:
|
||||
s = "bit 7 set to 1";
|
||||
break;
|
||||
case PAI_FLAGS_B7_1:
|
||||
s = "bit 7 set to 0";
|
||||
break;
|
||||
case PAI_FLAGS_PAR_EVEN:
|
||||
s = "odd parity";
|
||||
break;
|
||||
case PAI_FLAGS_PAR_ODD:
|
||||
s = "even parity";
|
||||
break;
|
||||
}
|
||||
if (s != NULL) {
|
||||
syslog(LOG_WARNING, "Serial link is not 8-bit clean:");
|
||||
syslog(LOG_WARNING, "All received characters had %s", s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (ioctl(fd, I_POP, 0) == 0) /* pop any we pushed */
|
||||
;
|
||||
pushed_ppp = 0;
|
||||
|
||||
for (; str_module_count > 0; str_module_count--) {
|
||||
if (ioctl(fd, I_PUSH, str_modules[str_module_count-1].modname)) {
|
||||
syslog(LOG_WARNING, "str_restore: couldn't push module %s: %m",
|
||||
str_modules[str_module_count-1].modname);
|
||||
} else {
|
||||
MAINDEBUG((LOG_INFO, "str_restore: pushed module %s",
|
||||
str_modules[str_module_count-1].modname));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* output - Output PPP packet.
|
||||
*/
|
||||
void
|
||||
output(unit, p, len)
|
||||
int unit;
|
||||
u_char *p;
|
||||
int len;
|
||||
{
|
||||
struct strbuf str;
|
||||
|
||||
if (unit != 0)
|
||||
MAINDEBUG((LOG_WARNING, "output: unit != 0!"));
|
||||
if (debug)
|
||||
log_packet(p, len, "sent ");
|
||||
|
||||
str.len = len;
|
||||
str.buf = (caddr_t) p;
|
||||
if(putmsg(fd, NULL, &str, 0) < 0) {
|
||||
syslog(LOG_ERR, "putmsg: %m");
|
||||
die(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* read_packet - get a PPP packet from the serial device.
|
||||
*/
|
||||
int
|
||||
read_packet(buf)
|
||||
u_char *buf;
|
||||
{
|
||||
struct strbuf str;
|
||||
int len, i;
|
||||
|
||||
str.maxlen = MTU+DLLHEADERLEN;
|
||||
str.buf = (caddr_t) buf;
|
||||
i = 0;
|
||||
len = getmsg(fd, NULL, &str, &i);
|
||||
if (len < 0) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
return -1;
|
||||
}
|
||||
syslog(LOG_ERR, "getmsg(fd) %m");
|
||||
die(1);
|
||||
}
|
||||
if (len)
|
||||
MAINDEBUG((LOG_DEBUG, "getmsg returned 0x%x",len));
|
||||
|
||||
if (str.len < 0) {
|
||||
MAINDEBUG((LOG_DEBUG, "getmsg short return length %d", str.len));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return str.len;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ppp_send_config - configure the transmit characteristics of
|
||||
* the ppp interface.
|
||||
*/
|
||||
void
|
||||
ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
|
||||
int unit, mtu;
|
||||
u_long asyncmap;
|
||||
int pcomp, accomp;
|
||||
{
|
||||
char c;
|
||||
struct ifreq ifr;
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
ifr.ifr_mtu = mtu;
|
||||
if (ioctl(s, SIOCSIFMTU, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m");
|
||||
quit();
|
||||
}
|
||||
|
||||
if(ioctl(fd, SIOCSIFASYNCMAP, (caddr_t) &asyncmap) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFASYNCMAP): %m");
|
||||
quit();
|
||||
}
|
||||
|
||||
c = (pcomp? 1: 0);
|
||||
if(ioctl(fd, SIOCSIFCOMPPROT, &c) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFCOMPPROT): %m");
|
||||
quit();
|
||||
}
|
||||
|
||||
c = (accomp? 1: 0);
|
||||
if(ioctl(fd, SIOCSIFCOMPAC, &c) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFCOMPAC): %m");
|
||||
quit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ppp_set_xaccm - set the extended transmit ACCM for the interface.
|
||||
*/
|
||||
void
|
||||
ppp_set_xaccm(unit, accm)
|
||||
int unit;
|
||||
ext_accm accm;
|
||||
{
|
||||
if (ioctl(fd, SIOCSIFXASYNCMAP, accm) < 0 && errno != ENOTTY)
|
||||
syslog(LOG_WARNING, "ioctl(set extended ACCM): %m");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ppp_recv_config - configure the receive-side characteristics of
|
||||
* the ppp interface.
|
||||
*/
|
||||
void
|
||||
ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
|
||||
int unit, mru;
|
||||
u_long asyncmap;
|
||||
int pcomp, accomp;
|
||||
{
|
||||
char c;
|
||||
|
||||
if (ioctl(fd, SIOCSIFMRU, &mru) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFMRU): %m");
|
||||
}
|
||||
|
||||
if (ioctl(fd, SIOCSIFRASYNCMAP, (caddr_t) &asyncmap) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFRASYNCMAP): %m");
|
||||
}
|
||||
|
||||
c = 2 + (pcomp? 1: 0);
|
||||
if(ioctl(fd, SIOCSIFCOMPPROT, &c) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFCOMPPROT): %m");
|
||||
}
|
||||
|
||||
c = 2 + (accomp? 1: 0);
|
||||
if (ioctl(fd, SIOCSIFCOMPAC, &c) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFCOMPAC): %m");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sifvjcomp - config tcp header compression
|
||||
*/
|
||||
int
|
||||
sifvjcomp(u, vjcomp, cidcomp, maxcid)
|
||||
int u, vjcomp, cidcomp, maxcid;
|
||||
{
|
||||
char x;
|
||||
|
||||
x = (vjcomp? 1: 0) + (cidcomp? 0: 2) + (maxcid << 4);
|
||||
if (ioctl(fd, SIOCSIFVJCOMP, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFVJCOMP): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sifup - Config the interface up.
|
||||
*/
|
||||
int
|
||||
sifup(u)
|
||||
int u;
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
ifr.ifr_flags |= IFF_UP;
|
||||
if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sifdown - Config the interface down.
|
||||
*/
|
||||
int
|
||||
sifdown(u)
|
||||
int u;
|
||||
{
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
ifr.ifr_flags &= ~IFF_UP;
|
||||
if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* SET_SA_FAMILY - initialize a struct sockaddr, setting the sa_family field.
|
||||
*/
|
||||
#define SET_SA_FAMILY(addr, family) \
|
||||
BZERO((char *) &(addr), sizeof(addr)); \
|
||||
addr.sa_family = (family);
|
||||
|
||||
/*
|
||||
* sifaddr - Config the interface IP addresses and netmask.
|
||||
*/
|
||||
int
|
||||
sifaddr(u, o, h, m)
|
||||
int u;
|
||||
u_long o, h, m;
|
||||
{
|
||||
int ret;
|
||||
struct ifreq ifr;
|
||||
|
||||
ret = 1;
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
|
||||
((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o;
|
||||
if (ioctl(s, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFADDR): %m");
|
||||
ret = 0;
|
||||
}
|
||||
((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = h;
|
||||
if (ioctl(s, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFDSTADDR): %m");
|
||||
ret = 0;
|
||||
}
|
||||
if (m != 0) {
|
||||
((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = m;
|
||||
syslog(LOG_INFO, "Setting interface mask to %s\n", ip_ntoa(m));
|
||||
if (ioctl(s, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFNETMASK): %m");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* cifaddr - Clear the interface IP addresses, and delete routes
|
||||
* through the interface if possible.
|
||||
*/
|
||||
int
|
||||
cifaddr(u, o, h)
|
||||
int u;
|
||||
u_long o, h;
|
||||
{
|
||||
struct rtentry rt;
|
||||
|
||||
SET_SA_FAMILY(rt.rt_dst, AF_INET);
|
||||
((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = h;
|
||||
SET_SA_FAMILY(rt.rt_gateway, AF_INET);
|
||||
((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = o;
|
||||
rt.rt_flags = RTF_HOST;
|
||||
if (ioctl(s, SIOCDELRT, (caddr_t) &rt) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCDELRT): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sifdefaultroute - assign a default route through the address given.
|
||||
*/
|
||||
int
|
||||
sifdefaultroute(u, g)
|
||||
int u;
|
||||
u_long g;
|
||||
{
|
||||
struct rtentry rt;
|
||||
|
||||
SET_SA_FAMILY(rt.rt_dst, AF_INET);
|
||||
SET_SA_FAMILY(rt.rt_gateway, AF_INET);
|
||||
((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g;
|
||||
rt.rt_flags = RTF_GATEWAY;
|
||||
if (ioctl(s, SIOCADDRT, &rt) < 0) {
|
||||
syslog(LOG_ERR, "default route ioctl(SIOCADDRT): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* cifdefaultroute - delete a default route through the address given.
|
||||
*/
|
||||
int
|
||||
cifdefaultroute(u, g)
|
||||
int u;
|
||||
u_long g;
|
||||
{
|
||||
struct rtentry rt;
|
||||
|
||||
SET_SA_FAMILY(rt.rt_dst, AF_INET);
|
||||
SET_SA_FAMILY(rt.rt_gateway, AF_INET);
|
||||
((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g;
|
||||
rt.rt_flags = RTF_GATEWAY;
|
||||
if (ioctl(s, SIOCDELRT, &rt) < 0) {
|
||||
syslog(LOG_ERR, "default route ioctl(SIOCDELRT): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sifproxyarp - Make a proxy ARP entry for the peer.
|
||||
*/
|
||||
int
|
||||
sifproxyarp(unit, hisaddr)
|
||||
int unit;
|
||||
u_long hisaddr;
|
||||
{
|
||||
struct arpreq arpreq;
|
||||
|
||||
BZERO(&arpreq, sizeof(arpreq));
|
||||
|
||||
/*
|
||||
* Get the hardware address of an interface on the same subnet
|
||||
* as our local address.
|
||||
*/
|
||||
if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) {
|
||||
syslog(LOG_WARNING, "Cannot determine ethernet address for proxy ARP");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
|
||||
((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
|
||||
arpreq.arp_flags = ATF_PERM | ATF_PUBL;
|
||||
if (ioctl(s, SIOCSARP, (caddr_t)&arpreq) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSARP): %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* cifproxyarp - Delete the proxy ARP entry for the peer.
|
||||
*/
|
||||
int
|
||||
cifproxyarp(unit, hisaddr)
|
||||
int unit;
|
||||
u_long hisaddr;
|
||||
{
|
||||
struct arpreq arpreq;
|
||||
|
||||
BZERO(&arpreq, sizeof(arpreq));
|
||||
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
|
||||
((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
|
||||
if (ioctl(s, SIOCDARP, (caddr_t)&arpreq) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCDARP): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_ether_addr - get the hardware address of an interface on the
|
||||
* the same subnet as ipaddr. Code borrowed from myetheraddr.c
|
||||
* in the cslip-2.6 distribution, which is subject to the following
|
||||
* copyright notice (which also applies to logwtmp below):
|
||||
*
|
||||
* Copyright (c) 1990, 1992 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <nlist.h>
|
||||
#include <kvm.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* XXX SunOS 4.1 defines this and 3.5 doesn't... */
|
||||
#ifdef _nlist_h
|
||||
#define SUNOS4
|
||||
#endif
|
||||
|
||||
#ifdef SUNOS4
|
||||
#include <netinet/in_var.h>
|
||||
#endif
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
/* Cast a struct sockaddr to a structaddr_in */
|
||||
#define SATOSIN(sa) ((struct sockaddr_in *)(sa))
|
||||
|
||||
/* Determine if "bits" is set in "flag" */
|
||||
#define ALLSET(flag, bits) (((flag) & (bits)) == (bits))
|
||||
|
||||
static struct nlist nl[] = {
|
||||
#define N_IFNET 0
|
||||
{ "_ifnet" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void kread();
|
||||
|
||||
int
|
||||
get_ether_addr(ipaddr, hwaddr)
|
||||
u_long ipaddr;
|
||||
struct sockaddr *hwaddr;
|
||||
{
|
||||
register kvm_t *kd;
|
||||
register struct ifnet *ifp;
|
||||
register struct arpcom *ac;
|
||||
struct arpcom arpcom;
|
||||
struct in_addr *inp;
|
||||
#ifdef SUNOS4
|
||||
register struct ifaddr *ifa;
|
||||
register struct in_ifaddr *in;
|
||||
union {
|
||||
struct ifaddr ifa;
|
||||
struct in_ifaddr in;
|
||||
} ifaddr;
|
||||
#endif
|
||||
u_long addr, mask;
|
||||
|
||||
/* Open kernel memory for reading */
|
||||
kd = kvm_open(0, 0, 0, O_RDONLY, NULL);
|
||||
if (kd == 0) {
|
||||
syslog(LOG_ERR, "kvm_open: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fetch namelist */
|
||||
if (kvm_nlist(kd, nl) != 0) {
|
||||
syslog(LOG_ERR, "kvm_nlist failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ac = &arpcom;
|
||||
ifp = &arpcom.ac_if;
|
||||
#ifdef SUNOS4
|
||||
ifa = &ifaddr.ifa;
|
||||
in = &ifaddr.in;
|
||||
#endif
|
||||
|
||||
if (kvm_read(kd, nl[N_IFNET].n_value, (char *)&addr, sizeof(addr))
|
||||
!= sizeof(addr)) {
|
||||
syslog(LOG_ERR, "error reading ifnet addr");
|
||||
return 0;
|
||||
}
|
||||
for ( ; addr; addr = (u_long)ifp->if_next) {
|
||||
if (kvm_read(kd, addr, (char *)ac, sizeof(*ac)) != sizeof(*ac)) {
|
||||
syslog(LOG_ERR, "error reading ifnet");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only look at configured, broadcast interfaces */
|
||||
if (!ALLSET(ifp->if_flags, IFF_UP | IFF_BROADCAST))
|
||||
continue;
|
||||
#ifdef SUNOS4
|
||||
/* This probably can't happen... */
|
||||
if (ifp->if_addrlist == 0)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
/* Get interface ip address */
|
||||
#ifdef SUNOS4
|
||||
if (kvm_read(kd, (u_long)ifp->if_addrlist, (char *)&ifaddr,
|
||||
sizeof(ifaddr)) != sizeof(ifaddr)) {
|
||||
syslog(LOG_ERR, "error reading ifaddr");
|
||||
return 0;
|
||||
}
|
||||
inp = &SATOSIN(&ifa->ifa_addr)->sin_addr;
|
||||
#else
|
||||
inp = &SATOSIN(&ifp->if_addr)->sin_addr;
|
||||
#endif
|
||||
|
||||
/* Check if this interface on the right subnet */
|
||||
#ifdef SUNOS4
|
||||
mask = in->ia_subnetmask;
|
||||
#else
|
||||
mask = ifp->if_subnetmask;
|
||||
#endif
|
||||
if ((ipaddr & mask) != (inp->s_addr & mask))
|
||||
continue;
|
||||
|
||||
/* Copy out the local ethernet address */
|
||||
hwaddr->sa_family = AF_UNSPEC;
|
||||
BCOPY((caddr_t) &arpcom.ac_enaddr, hwaddr->sa_data,
|
||||
sizeof(arpcom.ac_enaddr));
|
||||
return 1; /* success! */
|
||||
}
|
||||
|
||||
/* couldn't find one */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define WTMPFILE "/usr/adm/wtmp"
|
||||
|
||||
int
|
||||
logwtmp(line, name, host)
|
||||
char *line, *name, *host;
|
||||
{
|
||||
int fd;
|
||||
struct stat buf;
|
||||
struct utmp ut;
|
||||
|
||||
if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
|
||||
return;
|
||||
if (!fstat(fd, &buf)) {
|
||||
(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
|
||||
(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
|
||||
(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
|
||||
(void)time(&ut.ut_time);
|
||||
if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp))
|
||||
(void)ftruncate(fd, buf.st_size);
|
||||
}
|
||||
close(fd);
|
||||
}
|
@ -1,663 +0,0 @@
|
||||
/*
|
||||
* sys-ultrix.c - System-dependent procedures for setting up
|
||||
* PPP interfaces on Ultrix systems.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: sys-ultrix.c,v 1.4 1994/05/25 06:30:49 paulus Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#include <syslog.h>
|
||||
#include <utmp.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <net/if_ppp.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "ppp.h"
|
||||
|
||||
static int initdisc = -1; /* Initial TTY discipline */
|
||||
extern int kdebugflag;
|
||||
|
||||
/*
|
||||
* establish_ppp - Turn the serial port into a ppp interface.
|
||||
*/
|
||||
void
|
||||
establish_ppp()
|
||||
{
|
||||
int pppdisc = PPPDISC;
|
||||
int x;
|
||||
|
||||
if (ioctl(fd, TIOCGETD, &initdisc) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(TIOCGETD): %m");
|
||||
die(1);
|
||||
}
|
||||
if (ioctl(fd, TIOCSETD, &pppdisc) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(TIOCSETD): %m");
|
||||
die(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find out which interface we were given.
|
||||
*/
|
||||
if (ioctl(fd, PPPIOCGUNIT, &ifunit) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m");
|
||||
die(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable debug in the driver if requested.
|
||||
*/
|
||||
if (kdebugflag) {
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_WARNING, "ioctl (PPPIOCGFLAGS): %m");
|
||||
} else {
|
||||
x |= (kdebugflag & 0xFF) * SC_DEBUG;
|
||||
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)
|
||||
syslog(LOG_WARNING, "ioctl(PPPIOCSFLAGS): %m");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* disestablish_ppp - Restore the serial port to normal operation.
|
||||
* This shouldn't call die() because it's called from die().
|
||||
*/
|
||||
void
|
||||
disestablish_ppp()
|
||||
{
|
||||
int x;
|
||||
char *s;
|
||||
|
||||
if (initdisc >= 0) {
|
||||
/*
|
||||
* Check whether the link seems not to be 8-bit clean.
|
||||
*/
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
|
||||
s = NULL;
|
||||
switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
|
||||
case SC_RCV_B7_0:
|
||||
s = "bit 7 set to 1";
|
||||
break;
|
||||
case SC_RCV_B7_1:
|
||||
s = "bit 7 set to 0";
|
||||
break;
|
||||
case SC_RCV_EVNP:
|
||||
s = "odd parity";
|
||||
break;
|
||||
case SC_RCV_ODDP:
|
||||
s = "even parity";
|
||||
break;
|
||||
}
|
||||
if (s != NULL) {
|
||||
syslog(LOG_WARNING, "Serial link is not 8-bit clean:");
|
||||
syslog(LOG_WARNING, "All received characters had %s", s);
|
||||
}
|
||||
}
|
||||
if (ioctl(fd, TIOCSETD, &initdisc) < 0)
|
||||
syslog(LOG_ERR, "ioctl(TIOCSETD): %m");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* output - Output PPP packet.
|
||||
*/
|
||||
void
|
||||
output(unit, p, len)
|
||||
int unit;
|
||||
u_char *p;
|
||||
int len;
|
||||
{
|
||||
if (unit != 0)
|
||||
MAINDEBUG((LOG_WARNING, "output: unit != 0!"));
|
||||
if (debug)
|
||||
log_packet(p, len, "sent ");
|
||||
|
||||
if (write(fd, p, len) < 0) {
|
||||
syslog(LOG_ERR, "write: %m");
|
||||
die(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* read_packet - get a PPP packet from the serial device.
|
||||
*/
|
||||
int
|
||||
read_packet(buf)
|
||||
u_char *buf;
|
||||
{
|
||||
int len;
|
||||
|
||||
if ((len = read(fd, buf, MTU + DLLHEADERLEN)) < 0) {
|
||||
if (errno == EWOULDBLOCK) {
|
||||
MAINDEBUG((LOG_DEBUG, "read(fd): EWOULDBLOCK"));
|
||||
return -1;
|
||||
}
|
||||
syslog(LOG_ERR, "read(fd): %m");
|
||||
die(1);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ppp_send_config - configure the transmit characteristics of
|
||||
* the ppp interface.
|
||||
*/
|
||||
void
|
||||
ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
|
||||
int unit, mtu;
|
||||
u_long asyncmap;
|
||||
int pcomp, accomp;
|
||||
{
|
||||
u_int x;
|
||||
struct ifreq ifr;
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
ifr.ifr_mtu = mtu;
|
||||
if (ioctl(s, SIOCSIFMTU, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m");
|
||||
quit();
|
||||
}
|
||||
|
||||
if (ioctl(fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSASYNCMAP): %m");
|
||||
quit();
|
||||
}
|
||||
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
|
||||
quit();
|
||||
}
|
||||
x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT;
|
||||
x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC;
|
||||
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
quit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ppp_set_xaccm - set the extended transmit ACCM for the interface.
|
||||
*/
|
||||
void
|
||||
ppp_set_xaccm(unit, accm)
|
||||
int unit;
|
||||
ext_accm accm;
|
||||
{
|
||||
if (ioctl(fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY)
|
||||
syslog(LOG_WARNING, "ioctl(set extended ACCM): %m");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ppp_recv_config - configure the receive-side characteristics of
|
||||
* the ppp interface.
|
||||
*/
|
||||
void
|
||||
ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
|
||||
int unit, mru;
|
||||
u_long asyncmap;
|
||||
int pcomp, accomp;
|
||||
{
|
||||
int x;
|
||||
|
||||
if (ioctl(fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %m");
|
||||
quit();
|
||||
}
|
||||
if (ioctl(fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSRASYNCMAP): %m");
|
||||
quit();
|
||||
}
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
|
||||
quit();
|
||||
}
|
||||
x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC;
|
||||
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
quit();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sifvjcomp - config tcp header compression
|
||||
*/
|
||||
int
|
||||
sifvjcomp(u, vjcomp, cidcomp, maxcid)
|
||||
int u, vjcomp, cidcomp, maxcid;
|
||||
{
|
||||
u_int x;
|
||||
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP;
|
||||
x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID;
|
||||
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
if (ioctl(fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sifup - Config the interface up and enable IP packets to pass.
|
||||
*/
|
||||
int
|
||||
sifup(u)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
u_int x;
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
ifr.ifr_flags |= IFF_UP;
|
||||
if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
x |= SC_ENABLE_IP;
|
||||
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sifdown - Config the interface down and disable IP.
|
||||
*/
|
||||
int
|
||||
sifdown(u)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
u_int x;
|
||||
int rv;
|
||||
|
||||
rv = 1;
|
||||
if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
|
||||
rv = 0;
|
||||
} else {
|
||||
x &= ~SC_ENABLE_IP;
|
||||
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
|
||||
rv = 0;
|
||||
}
|
||||
}
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
|
||||
rv = 0;
|
||||
} else {
|
||||
ifr.ifr_flags &= ~IFF_UP;
|
||||
if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
|
||||
rv = 0;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
|
||||
* if it exists.
|
||||
*/
|
||||
#define SET_SA_FAMILY(addr, family) \
|
||||
BZERO((char *) &(addr), sizeof(addr)); \
|
||||
addr.sa_family = (family);
|
||||
|
||||
/*
|
||||
* sifaddr - Config the interface IP addresses and netmask.
|
||||
*/
|
||||
int
|
||||
sifaddr(u, o, h, m)
|
||||
{
|
||||
int ret;
|
||||
struct ifreq ifr;
|
||||
|
||||
ret = 1;
|
||||
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||
SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
|
||||
((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o;
|
||||
if (ioctl(s, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFADDR): %m");
|
||||
ret = 0;
|
||||
}
|
||||
((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = h;
|
||||
if (ioctl(s, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFDSTADDR): %m");
|
||||
ret = 0;
|
||||
}
|
||||
if (m != 0) {
|
||||
((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = m;
|
||||
syslog(LOG_INFO, "Setting interface mask to %s\n", ip_ntoa(m));
|
||||
if (ioctl(s, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSIFNETMASK): %m");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* cifaddr - Clear the interface IP addresses, and delete routes
|
||||
* through the interface if possible.
|
||||
*/
|
||||
int
|
||||
cifaddr(u, o, h)
|
||||
{
|
||||
struct rtentry rt;
|
||||
|
||||
SET_SA_FAMILY(rt.rt_dst, AF_INET);
|
||||
((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = h;
|
||||
SET_SA_FAMILY(rt.rt_gateway, AF_INET);
|
||||
((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = o;
|
||||
rt.rt_flags = RTF_HOST;
|
||||
if (ioctl(s, SIOCDELRT, (caddr_t) &rt) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCDELRT): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sifdefaultroute - assign a default route through the address given.
|
||||
*/
|
||||
int
|
||||
sifdefaultroute(u, g)
|
||||
{
|
||||
struct rtentry rt;
|
||||
|
||||
SET_SA_FAMILY(rt.rt_dst, AF_INET);
|
||||
SET_SA_FAMILY(rt.rt_gateway, AF_INET);
|
||||
((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g;
|
||||
rt.rt_flags = RTF_GATEWAY;
|
||||
if (ioctl(s, SIOCADDRT, &rt) < 0) {
|
||||
syslog(LOG_ERR, "default route ioctl(SIOCADDRT): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* cifdefaultroute - delete a default route through the address given.
|
||||
*/
|
||||
int
|
||||
cifdefaultroute(u, g)
|
||||
{
|
||||
struct rtentry rt;
|
||||
|
||||
SET_SA_FAMILY(rt.rt_dst, AF_INET);
|
||||
SET_SA_FAMILY(rt.rt_gateway, AF_INET);
|
||||
((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g;
|
||||
rt.rt_flags = RTF_GATEWAY;
|
||||
if (ioctl(s, SIOCDELRT, &rt) < 0)
|
||||
syslog(LOG_WARNING, "default route ioctl(SIOCDELRT): %m");
|
||||
}
|
||||
|
||||
/*
|
||||
* sifproxyarp - Make a proxy ARP entry for the peer.
|
||||
*/
|
||||
int
|
||||
sifproxyarp(unit, hisaddr)
|
||||
int unit;
|
||||
u_long hisaddr;
|
||||
{
|
||||
struct arpreq arpreq;
|
||||
|
||||
BZERO(&arpreq, sizeof(arpreq));
|
||||
|
||||
/*
|
||||
* Get the hardware address of an interface on the same subnet
|
||||
* as our local address.
|
||||
*/
|
||||
if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) {
|
||||
syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
|
||||
((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
|
||||
arpreq.arp_flags = ATF_PERM | ATF_PUBL;
|
||||
if (ioctl(s, SIOCSARP, (caddr_t)&arpreq) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCSARP): %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* cifproxyarp - Delete the proxy ARP entry for the peer.
|
||||
*/
|
||||
int
|
||||
cifproxyarp(unit, hisaddr)
|
||||
int unit;
|
||||
u_long hisaddr;
|
||||
{
|
||||
struct arpreq arpreq;
|
||||
|
||||
BZERO(&arpreq, sizeof(arpreq));
|
||||
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
|
||||
((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
|
||||
if (ioctl(s, SIOCDARP, (caddr_t)&arpreq) < 0) {
|
||||
syslog(LOG_WARNING, "ioctl(SIOCDARP): %m");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_ether_addr - get the hardware address of an interface on the
|
||||
* the same subnet as ipaddr.
|
||||
*/
|
||||
#define MAX_IFS 32
|
||||
|
||||
int
|
||||
get_ether_addr(ipaddr, hwaddr)
|
||||
u_long ipaddr;
|
||||
struct sockaddr *hwaddr;
|
||||
{
|
||||
struct ifreq *ifr, *ifend, *ifp;
|
||||
u_long ina, mask;
|
||||
struct sockaddr_dl *dla;
|
||||
struct ifreq ifreq;
|
||||
struct ifconf ifc;
|
||||
struct ifreq ifs[MAX_IFS];
|
||||
|
||||
ifc.ifc_len = sizeof(ifs);
|
||||
ifc.ifc_req = ifs;
|
||||
if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
|
||||
syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan through looking for an interface with an Internet
|
||||
* address on the same subnet as `ipaddr'.
|
||||
*/
|
||||
ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
|
||||
for (ifr = ifc.ifc_req; ifr < ifend; ) {
|
||||
if (ifr->ifr_addr.sa_family == AF_INET) {
|
||||
ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
|
||||
strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
|
||||
/*
|
||||
* Check that the interface is up, and not point-to-point
|
||||
* or loopback.
|
||||
*/
|
||||
if (ioctl(s, SIOCGIFFLAGS, &ifreq) < 0)
|
||||
continue;
|
||||
if ((ifreq.ifr_flags &
|
||||
(IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
|
||||
!= (IFF_UP|IFF_BROADCAST))
|
||||
continue;
|
||||
/*
|
||||
* Get its netmask and check that it's on the right subnet.
|
||||
*/
|
||||
if (ioctl(s, SIOCGIFNETMASK, &ifreq) < 0)
|
||||
continue;
|
||||
mask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
|
||||
if ((ipaddr & mask) != (ina & mask))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + sizeof(struct sockaddr)
|
||||
);
|
||||
}
|
||||
|
||||
if (ifr >= ifend)
|
||||
return 0;
|
||||
syslog(LOG_DEBUG, "found interface %s for proxy arp", ifr->ifr_name);
|
||||
|
||||
/*
|
||||
* Now scan through again looking for a link-level address
|
||||
* for this interface.
|
||||
*/
|
||||
ifp = ifr;
|
||||
for (ifr = ifc.ifc_req; ifr < ifend; ) {
|
||||
if (strcmp(ifp->ifr_name, ifr->ifr_name) == 0
|
||||
&& ifr->ifr_addr.sa_family == AF_DLI) {
|
||||
/* && ifr->ifr_addr.sa_family == AF_LINK) { Per! Kolla !!! ROHACK */
|
||||
/*
|
||||
* Found the link-level address - copy it out
|
||||
*/
|
||||
dla = (struct sockaddr_dl *)&ifr->ifr_addr;
|
||||
hwaddr->sa_family = AF_UNSPEC;
|
||||
BCOPY(dla, hwaddr->sa_data, sizeof(hwaddr->sa_data));
|
||||
return 1;
|
||||
}
|
||||
ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + sizeof(struct sockaddr)
|
||||
);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ppp_available - check whether the system has any ppp interfaces
|
||||
* (in fact we check whether we can do an ioctl on ppp0).
|
||||
*/
|
||||
|
||||
int
|
||||
ppp_available()
|
||||
{
|
||||
int s, ok;
|
||||
struct ifreq ifr;
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
return 1; /* can't tell - maybe we're not root */
|
||||
|
||||
strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
|
||||
ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
|
||||
close(s);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Seems like strdup() is not part of string package in Ultrix.
|
||||
If I understood the man-page on the sun this should work.
|
||||
|
||||
Robert Olsson
|
||||
*/
|
||||
|
||||
char *strdup( in ) char *in;
|
||||
{
|
||||
char* dup;
|
||||
if(! (dup = (char *) malloc( strlen( in ) +1 ))) return NULL;
|
||||
(void) strcpy( dup, in );
|
||||
return dup;
|
||||
}
|
||||
|
||||
/*
|
||||
* This logwtmp() implementation is subject to the following copyright:
|
||||
*
|
||||
* Copyright (c) 1988 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by the University of California, Berkeley. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#define WTMPFILE "/usr/adm/wtmp"
|
||||
|
||||
int
|
||||
logwtmp(line, name, host)
|
||||
char *line, *name, *host;
|
||||
{
|
||||
int fd;
|
||||
struct stat buf;
|
||||
struct utmp ut;
|
||||
|
||||
if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
|
||||
return;
|
||||
if (!fstat(fd, &buf)) {
|
||||
(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
|
||||
(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
|
||||
(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
|
||||
(void)time(&ut.ut_time);
|
||||
if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp))
|
||||
(void)ftruncate(fd, buf.st_size);
|
||||
}
|
||||
close(fd);
|
||||
}
|
@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: upap.c,v 1.2 1994/04/11 07:13:44 paulus Exp $";
|
||||
static char rcsid[] = "$Id: upap.c,v 1.6 1995/06/12 12:02:24 paulus Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -26,24 +26,25 @@ static char rcsid[] = "$Id: upap.c,v 1.2 1994/04/11 07:13:44 paulus Exp $";
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "ppp.h"
|
||||
#include "pppd.h"
|
||||
#include "upap.h"
|
||||
|
||||
|
||||
upap_state upap[NPPP]; /* UPAP state; one for each unit */
|
||||
upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */
|
||||
|
||||
|
||||
static void upap_timeout __ARGS((caddr_t));
|
||||
static void upap_rauthreq __ARGS((upap_state *, u_char *, int, int));
|
||||
static void upap_rauthack __ARGS((upap_state *, u_char *, int, int));
|
||||
static void upap_rauthnak __ARGS((upap_state *, u_char *, int, int));
|
||||
static void upap_sauthreq __ARGS((upap_state *));
|
||||
static void upap_sresp __ARGS((upap_state *, int, int, char *, int));
|
||||
static void upap_timeout __P((caddr_t));
|
||||
static void upap_reqtimeout __P((caddr_t));
|
||||
static void upap_rauthreq __P((upap_state *, u_char *, int, int));
|
||||
static void upap_rauthack __P((upap_state *, u_char *, int, int));
|
||||
static void upap_rauthnak __P((upap_state *, u_char *, int, int));
|
||||
static void upap_sauthreq __P((upap_state *));
|
||||
static void upap_sresp __P((upap_state *, int, int, char *, int));
|
||||
|
||||
|
||||
/*
|
||||
@ -65,6 +66,7 @@ upap_init(unit)
|
||||
u->us_id = 0;
|
||||
u->us_timeouttime = UPAP_DEFTIMEOUT;
|
||||
u->us_maxtransmits = 10;
|
||||
u->us_reqtimeout = UPAP_DEFREQTIME;
|
||||
}
|
||||
|
||||
|
||||
@ -117,11 +119,13 @@ upap_authpeer(unit)
|
||||
}
|
||||
|
||||
u->us_serverstate = UPAPSS_LISTEN;
|
||||
if (u->us_reqtimeout > 0)
|
||||
TIMEOUT(upap_reqtimeout, (caddr_t) u, u->us_reqtimeout);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_timeout - Timeout expired.
|
||||
* upap_timeout - Retransmission timer for sending auth-reqs expired.
|
||||
*/
|
||||
static void
|
||||
upap_timeout(arg)
|
||||
@ -136,7 +140,7 @@ upap_timeout(arg)
|
||||
/* give up in disgust */
|
||||
syslog(LOG_ERR, "No response to PAP authenticate-requests");
|
||||
u->us_clientstate = UPAPCS_BADAUTH;
|
||||
auth_withpeer_fail(u->us_unit, UPAP);
|
||||
auth_withpeer_fail(u->us_unit, PPP_PAP);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -144,6 +148,23 @@ upap_timeout(arg)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_reqtimeout - Give up waiting for the peer to send an auth-req.
|
||||
*/
|
||||
static void
|
||||
upap_reqtimeout(arg)
|
||||
caddr_t arg;
|
||||
{
|
||||
upap_state *u = (upap_state *) arg;
|
||||
|
||||
if (u->us_serverstate != UPAPSS_LISTEN)
|
||||
return; /* huh?? */
|
||||
|
||||
auth_peer_fail(u->us_unit, PPP_PAP);
|
||||
u->us_serverstate = UPAPSS_BADAUTH;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_lowerup - The lower layer is up.
|
||||
*
|
||||
@ -163,8 +184,11 @@ upap_lowerup(unit)
|
||||
|
||||
if (u->us_serverstate == UPAPSS_INITIAL)
|
||||
u->us_serverstate = UPAPSS_CLOSED;
|
||||
else if (u->us_serverstate == UPAPSS_PENDING)
|
||||
else if (u->us_serverstate == UPAPSS_PENDING) {
|
||||
u->us_serverstate = UPAPSS_LISTEN;
|
||||
if (u->us_reqtimeout > 0)
|
||||
TIMEOUT(upap_reqtimeout, (caddr_t) u, u->us_reqtimeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -179,8 +203,10 @@ upap_lowerdown(unit)
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */
|
||||
if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */
|
||||
UNTIMEOUT(upap_timeout, (caddr_t) u); /* Cancel timeout */
|
||||
if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0)
|
||||
UNTIMEOUT(upap_reqtimeout, (caddr_t) u);
|
||||
|
||||
u->us_clientstate = UPAPCS_INITIAL;
|
||||
u->us_serverstate = UPAPSS_INITIAL;
|
||||
@ -200,11 +226,11 @@ upap_protrej(unit)
|
||||
|
||||
if (u->us_clientstate == UPAPCS_AUTHREQ) {
|
||||
syslog(LOG_ERR, "PAP authentication failed due to protocol-reject");
|
||||
auth_withpeer_fail(unit, UPAP);
|
||||
auth_withpeer_fail(unit, PPP_PAP);
|
||||
}
|
||||
if (u->us_serverstate == UPAPSS_LISTEN) {
|
||||
syslog(LOG_ERR, "PAP authentication of peer failed (protocol-reject)");
|
||||
auth_peer_fail(unit, UPAP);
|
||||
auth_peer_fail(unit, PPP_PAP);
|
||||
}
|
||||
upap_lowerdown(unit);
|
||||
}
|
||||
@ -334,11 +360,14 @@ upap_rauthreq(u, inp, id, len)
|
||||
|
||||
if (retcode == UPAP_AUTHACK) {
|
||||
u->us_serverstate = UPAPSS_OPEN;
|
||||
auth_peer_success(u->us_unit, UPAP);
|
||||
auth_peer_success(u->us_unit, PPP_PAP);
|
||||
} else {
|
||||
u->us_serverstate = UPAPSS_BADAUTH;
|
||||
auth_peer_fail(u->us_unit, UPAP);
|
||||
auth_peer_fail(u->us_unit, PPP_PAP);
|
||||
}
|
||||
|
||||
if (u->us_reqtimeout > 0)
|
||||
UNTIMEOUT(upap_reqtimeout, (caddr_t) u);
|
||||
}
|
||||
|
||||
|
||||
@ -377,7 +406,7 @@ upap_rauthack(u, inp, id, len)
|
||||
|
||||
u->us_clientstate = UPAPCS_OPEN;
|
||||
|
||||
auth_withpeer_success(u->us_unit, UPAP);
|
||||
auth_withpeer_success(u->us_unit, PPP_PAP);
|
||||
}
|
||||
|
||||
|
||||
@ -417,7 +446,7 @@ upap_rauthnak(u, inp, id, len)
|
||||
u->us_clientstate = UPAPCS_BADAUTH;
|
||||
|
||||
syslog(LOG_ERR, "PAP authentication failed");
|
||||
auth_withpeer_fail(u->us_unit, UPAP);
|
||||
auth_withpeer_fail(u->us_unit, PPP_PAP);
|
||||
}
|
||||
|
||||
|
||||
@ -435,7 +464,7 @@ upap_sauthreq(u)
|
||||
u->us_userlen + u->us_passwdlen;
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, UPAP);
|
||||
MAKEHEADER(outp, PPP_PAP);
|
||||
|
||||
PUTCHAR(UPAP_AUTHREQ, outp);
|
||||
PUTCHAR(++u->us_id, outp);
|
||||
@ -446,7 +475,7 @@ upap_sauthreq(u)
|
||||
PUTCHAR(u->us_passwdlen, outp);
|
||||
BCOPY(u->us_passwd, outp, u->us_passwdlen);
|
||||
|
||||
output(u->us_unit, outpacket_buf, outlen + DLLHEADERLEN);
|
||||
output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "upap_sauth: Sent id %d.", u->us_id));
|
||||
|
||||
@ -471,14 +500,14 @@ upap_sresp(u, code, id, msg, msglen)
|
||||
|
||||
outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
|
||||
outp = outpacket_buf;
|
||||
MAKEHEADER(outp, UPAP);
|
||||
MAKEHEADER(outp, PPP_PAP);
|
||||
|
||||
PUTCHAR(code, outp);
|
||||
PUTCHAR(id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
PUTCHAR(msglen, outp);
|
||||
BCOPY(msg, outp, msglen);
|
||||
output(u->us_unit, outpacket_buf, outlen + DLLHEADERLEN);
|
||||
output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "upap_sresp: Sent code %d, id %d.", code, id));
|
||||
}
|
||||
@ -494,7 +523,7 @@ int
|
||||
upap_printpkt(p, plen, printer, arg)
|
||||
u_char *p;
|
||||
int plen;
|
||||
void (*printer) __ARGS((void *, char *, ...));
|
||||
void (*printer) __P((void *, char *, ...));
|
||||
void *arg;
|
||||
{
|
||||
int code, id, len;
|
||||
|
@ -16,7 +16,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: upap.h,v 1.2 1994/04/11 07:13:44 paulus Exp $
|
||||
* $Id: upap.h,v 1.4 1995/06/12 12:02:25 paulus Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -45,9 +45,10 @@ typedef struct upap_state {
|
||||
int us_clientstate; /* Client state */
|
||||
int us_serverstate; /* Server state */
|
||||
u_char us_id; /* Current id */
|
||||
int us_timeouttime; /* Timeout time in milliseconds */
|
||||
int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */
|
||||
int us_transmits; /* Number of auth-reqs sent */
|
||||
int us_maxtransmits; /* Maximum number of auth-reqs to send */
|
||||
int us_reqtimeout; /* Time to wait for auth-req from peer */
|
||||
} upap_state;
|
||||
|
||||
|
||||
@ -75,17 +76,18 @@ typedef struct upap_state {
|
||||
/*
|
||||
* Timeouts.
|
||||
*/
|
||||
#define UPAP_DEFTIMEOUT 3 /* Timeout time in seconds */
|
||||
#define UPAP_DEFTIMEOUT 3 /* Timeout (seconds) for retransmitting req */
|
||||
#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */
|
||||
|
||||
|
||||
extern upap_state upap[];
|
||||
|
||||
void upap_init __ARGS((int));
|
||||
void upap_authwithpeer __ARGS((int, char *, char *));
|
||||
void upap_authpeer __ARGS((int));
|
||||
void upap_lowerup __ARGS((int));
|
||||
void upap_lowerdown __ARGS((int));
|
||||
void upap_input __ARGS((int, u_char *, int));
|
||||
void upap_protrej __ARGS((int));
|
||||
int upap_printpkt __ARGS((u_char *, int,
|
||||
void (*) __ARGS((void *, char *, ...)), void *));
|
||||
void upap_init __P((int));
|
||||
void upap_authwithpeer __P((int, char *, char *));
|
||||
void upap_authpeer __P((int));
|
||||
void upap_lowerup __P((int));
|
||||
void upap_lowerdown __P((int));
|
||||
void upap_input __P((int, u_char *, int));
|
||||
void upap_protrej __P((int));
|
||||
int upap_printpkt __P((u_char *, int,
|
||||
void (*) __P((void *, char *, ...)), void *));
|
||||
|
Loading…
Reference in New Issue
Block a user