2001-08-16 Mike Siers <mikes@poliac.com>

* Update of PPPD to 2.3.11 from 2.3.5 and addition of an example
	application.  Mike's notes on the modifications:
	   - renamed error() function because of namespace problems
	   - removed calls to the exit() funciton
	   - removed extra files from the pppd source directory
	   - defined pppd task constant values in rtemspppd.h
	   - modifyied example code to get actual tick per second value
	   - placed the pppd 2.3.11 man page file (pppd.8) into the pppd
	   directory
	* pppd/cbcp.c, pppd/cbcp.h, pppd/main.c, pppd/ppp_tty.c,
	pppd/pppmain.c, pppd/rtems-ppp.c, pppd/rtems-ppp.c: Deleted.
	* pppd/pppd.8, pppd/rtemsmain.c, pppd/rtemspppd.c, pppd/rtemspppd.h,
	pppd/sys-rtems.c, pppd/utils.c, pppd/example/Makefile,
	pppd/example/README, pppd/example/init.c, pppd/example/netconfig.h,
	pppd/example/ppp.conf, pppd/example/pppdapp.c, pppd/example/system.h:
	New files.
	* modem/ppp_tty.c, net/if_ppp.h, pppd/Makefile.am, pppd/README,
	pppd/STATUS, pppd/auth.c, pppd/ccp.c, pppd/ccp.h, pppd/chap.c,
	pppd/chap.h, pppd/chap_ms.c, pppd/chap_ms.h, pppd/chat.c,
	pppd/demand.c, pppd/fsm.c, pppd/fsm.h, pppd/ipcp.c, pppd/ipcp.h,
	pppd/ipxcp.c, pppd/ipxcp.h, pppd/lcp.c, pppd/lcp.h, pppd/magic.c,
	pppd/magic.h, pppd/options.c, pppd/patchlevel.h,
	pppd/pathnames.h, pppd/pppd.h, pppd/upap.c, pppd/upap.h: Modified.
This commit is contained in:
Joel Sherrill
2001-08-16 20:42:09 +00:00
parent 4b3c197fc0
commit 2f1b9304ac
91 changed files with 15929 additions and 7959 deletions

View File

@@ -1,3 +1,29 @@
2001-08-16 Mike Siers <mikes@poliac.com>
* Update of PPPD to 2.3.11 from 2.3.5 and addition of an example
application. Mike's notes on the modifications:
- renamed error() function because of namespace problems
- removed calls to the exit() funciton
- removed extra files from the pppd source directory
- defined pppd task constant values in rtemspppd.h
- modifyied example code to get actual tick per second value
- placed the pppd 2.3.11 man page file (pppd.8) into the pppd
directory
* pppd/cbcp.c, pppd/cbcp.h, pppd/main.c, pppd/ppp_tty.c,
pppd/pppmain.c, pppd/rtems-ppp.c, pppd/rtems-ppp.c: Deleted.
* pppd/pppd.8, pppd/rtemsmain.c, pppd/rtemspppd.c, pppd/rtemspppd.h,
pppd/sys-rtems.c, pppd/utils.c, pppd/example/Makefile,
pppd/example/README, pppd/example/init.c, pppd/example/netconfig.h,
pppd/example/ppp.conf, pppd/example/pppdapp.c, pppd/example/system.h:
New files.
* modem/ppp_tty.c, net/if_ppp.h, pppd/Makefile.am, pppd/README,
pppd/STATUS, pppd/auth.c, pppd/ccp.c, pppd/ccp.h, pppd/chap.c,
pppd/chap.h, pppd/chap_ms.c, pppd/chap_ms.h, pppd/chat.c,
pppd/demand.c, pppd/fsm.c, pppd/fsm.h, pppd/ipcp.c, pppd/ipcp.h,
pppd/ipxcp.c, pppd/ipxcp.h, pppd/lcp.c, pppd/lcp.h, pppd/magic.c,
pppd/magic.h, pppd/options.c, pppd/patchlevel.h,
pppd/pathnames.h, pppd/pppd.h, pppd/upap.c, pppd/upap.h: Modified.
2001-08-16 Joel Sherrill <joel@OARcorp.com>
* rtems_telnetd/.cvsignore: New file.

View File

@@ -38,6 +38,7 @@
#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */
#define SC_LOG_RAWIN 0x00080000 /* log all chars received */
#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */
#define SC_SYNC 0x00200000 /* synchrounous HDLC */
#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */
#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */
#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */

View File

@@ -1,3 +1,29 @@
2001-08-16 Mike Siers <mikes@poliac.com>
* Update of PPPD to 2.3.11 from 2.3.5 and addition of an example
application. Mike's notes on the modifications:
- renamed error() function because of namespace problems
- removed calls to the exit() funciton
- removed extra files from the pppd source directory
- defined pppd task constant values in rtemspppd.h
- modifyied example code to get actual tick per second value
- placed the pppd 2.3.11 man page file (pppd.8) into the pppd
directory
* pppd/cbcp.c, pppd/cbcp.h, pppd/main.c, pppd/ppp_tty.c,
pppd/pppmain.c, pppd/rtems-ppp.c, pppd/rtems-ppp.c: Deleted.
* pppd/pppd.8, pppd/rtemsmain.c, pppd/rtemspppd.c, pppd/rtemspppd.h,
pppd/sys-rtems.c, pppd/utils.c, pppd/example/Makefile,
pppd/example/README, pppd/example/init.c, pppd/example/netconfig.h,
pppd/example/ppp.conf, pppd/example/pppdapp.c, pppd/example/system.h:
New files.
* modem/ppp_tty.c, net/if_ppp.h, pppd/Makefile.am, pppd/README,
pppd/STATUS, pppd/auth.c, pppd/ccp.c, pppd/ccp.h, pppd/chap.c,
pppd/chap.h, pppd/chap_ms.c, pppd/chap_ms.h, pppd/chat.c,
pppd/demand.c, pppd/fsm.c, pppd/fsm.h, pppd/ipcp.c, pppd/ipcp.h,
pppd/ipxcp.c, pppd/ipxcp.h, pppd/lcp.c, pppd/lcp.h, pppd/magic.c,
pppd/magic.h, pppd/options.c, pppd/patchlevel.h,
pppd/pathnames.h, pppd/pppd.h, pppd/upap.c, pppd/upap.h: Modified.
2001-08-16 Joel Sherrill <joel@OARcorp.com>
* rtems_telnetd/.cvsignore: New file.

View File

@@ -433,13 +433,13 @@ int
ppptioctl(struct rtems_termios_tty *tty,
rtems_libio_ioctl_args_t *args)
{
struct ppp_softc *sc=tty->t_sc;
int cmd;
caddr_t data;
int error=RTEMS_SUCCESSFUL;
int error = RTEMS_SUCCESSFUL;
struct ppp_softc *sc = tty->t_sc;
int cmd;
caddr_t data;
data=args->buffer;
cmd=args->command;
data=args->buffer;
switch (cmd) {
case RTEMS_IO_GET_ATTRIBUTES:
@@ -447,8 +447,11 @@ ppptioctl(struct rtems_termios_tty *tty,
case RTEMS_IO_TCDRAIN:
case TIOCGETD:
case TIOCSETD:
return RTEMS_UNSATISFIED;
case RTEMS_IO_SNDWAKEUP:
case RTEMS_IO_RCVWAKEUP:
error = rtems_termios_ioctl(args);
break;
case PPPIOCSASYNCMAP:
sc->sc_asyncmap[0] = *(u_int *)data;
break;

View File

@@ -38,6 +38,7 @@
#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */
#define SC_LOG_RAWIN 0x00080000 /* log all chars received */
#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */
#define SC_SYNC 0x00200000 /* synchrounous HDLC */
#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */
#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */
#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */

View File

@@ -4,13 +4,13 @@
AUTOMAKE_OPTIONS = foreign 1.4
LIBNAME = lib.a
LIB = $(ARCH)/$(LIBNAME)
# renamed main.c to pppmain.c
C_FILES = auth.c cbcp.c ccp.c chap.c chap_ms.c chat.c demand.c fsm.c ipcp.c \
ipxcp.c lcp.c magic.c options.c upap.c md4.c md5.c rtems-ppp.c \
pppmain.c
C_FILES = auth.c ccp.c chap.c chap_ms.c chat.c demand.c fsm.c ipcp.c lcp.c magic.c options.c upap.c md4.c md5.c utils.c sys-rtems.c rtemsmain.c rtemspppd.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
OBJS = $(C_O_FILES)
@@ -23,24 +23,25 @@ include $(top_srcdir)/../../../automake/lib.am
# Add local stuff here using +=
#
# DEFINES += -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS -DDIAGNOSTIC \
# -DBOOTP_COMPAT
$(LIB): $(OBJS)
$(make-library)
EXTRA_FILES = modem_example/16550.h modem_example/README \
modem_example/modem.c modem_example/modem.h modem_example/ppp.c \
modem_example/ppp.h modem_example/pppcompress.c
all-local: $(ARCH) $(OBJS) $(LIB)
all-local: $(PREINSTALL_FILES) $(ARCH) $(OBJS) $(LIB)
.PRECIOUS: $(LIB)
EXTRA_DIST = README STATUS auth.c cbcp.c cbcp.h ccp.c ccp.h chap.c chap.h \
chap_ms.c chap_ms.h chat.c demand.c fsm.c fsm.h ipcp.c ipcp.h ipxcp.c \
ipxcp.h lcp.c lcp.h magic.c magic.h main.c md4.c md4.h md5.c md5.h \
options.c patchlevel.h pathnames.h ppp_tty.c pppd.h rtems-ppp.c upap.c \
upap.h pppmain.c $(EXTRA_FILES)
EXTRA_DIST = auth.c ccp.c ccp.h chap.c chap.h chap_ms.c chap_ms.h \
chat.c demand.c fsm.c fsm.h ipcp.c ipcp.h ipxcp.c ipxcp.h \
lcp.c lcp.h magic.c magic.h md4.c md4.h md5.c md5.h options.c \
patchlevel.h pathnames.h pppd.h rtemsmain.c rtemspppd.c rtemspppd.h \
sys-rtems.c upap.c upap.h utils.c
include_HEADERS = rtemspppd.h
PREINSTALL_FILES += $(PROJECT_INCLUDE) $(include_HEADERS:%=$(PROJECT_INCLUDE)/%)
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
include $(top_srcdir)/../../../automake/local.am

View File

@@ -2,57 +2,19 @@
# $Id$
#
This directory contains a port of ppp-2.3.5. The official site for
This directory contains a port of ppp-2.3.11. The official site for
the original source for this PPP implementation is:
ftp://cs.anu.edu.au/pub/software/ppp
NOTE: As of 11/30/1999, the current version of this source is 2.3.10.
================================================================
History
The port was performed by Tomasz Domin <dot@comarch.pl> of ComArch SA
and has only been tested on the mpc823. The modem driver should
work with minor modifications on other systems.
The original port was of 2.3.5 by Tomasz Domin <dot@comarch.pl> of
ComArch SA and was initially only tested on the mpc823. He
provided the modem driver as well.
The port was updated to 2.3.11 by Mike Siers <mikes@poliac.com>
who added an example test.
=================================================================
Some comments:
+ "SetStatusInfo is a function which displays given message on
bottom side of the screen."
The issue of how to deal with SetStatusInfo in a generic, portable
fashion is still open.
+ "Dialer returns positive integer when an error occurs, and negative one
which is parsed from modem aswer, when connection is done (for example
-28000 if connection speed is 28000 baud ...)"
+ PPP_User/PPP_Password
"When this field is set, it is sent to the server when there is need
to login ....
When it is blank - it is using other method of authentification ... or
none ...
PPP_Password is also used in CHAT and PAP - because there is no
configuration files in RTEMS ..."
This falls into the general question of how to generally configure this.
+ ConnectionStatus
This is the method of synchronization between pppd task and others.
ConnectionStatus field is set by pppd - when connection occurs it`s state
is set to Connected. WantConnection is set by client application (and
the appriopriate event is sent then) so pppd knows what user wants to do ...
+ Around line 270 of main.c, there is code to change the default
nameserver... why?
Becouse in my application user can change it anytime ... - without need of
rebooting the system
When PPP connection is configured there is needed additional info about
nameservers - PPP layer cant discover them itself

View File

@@ -2,28 +2,5 @@
# $Id$
#
Overall, this code should still be considered in its early stages. It
works but has some distance to go before it is fully documented and
easily configurable.
+ Compare the code to the original 2.3.5 and eliminate spurious changes.
+ Update the code to 2.3.10.
+ Eliminate items specific to Tomasz' system. In particular, the
code reports status and gets configuration information in a system
specific manner. main.c is particularly guilty of this although
other files suffer from this also.
+ Find comments in Polish and get Tomasz to translate them. :)
(DONE but not sure if completely
Radzislaw Galler <rgaller@et.put.poznan.pl>)
+ Add netdemo showing configuration and initialization.
+ Get feature list.
+ Document dialer setup.
+ Only modem driver is system specific so there is the possibility
that shareable code exists in it.
This file needs to be redone to reflect tasks left after the 2.3.11
update.

File diff suppressed because it is too large Load Diff

View File

@@ -1,431 +0,0 @@
/*
* cbcp - Call Back Configuration Protocol.
*
* Copyright (c) 1995 Pedro Roque Marques
* 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 Pedro Roque Marques. The name of the author may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
/* static char rcsid[] = "$Id$"; */
#endif
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <syslog.h>
#include "pppd.h"
#include "cbcp.h"
#include "fsm.h"
#include "lcp.h"
#include "ipcp.h"
/*
* Protocol entry points.
*/
static void cbcp_init __P((int unit));
static void cbcp_open __P((int unit));
static void cbcp_lowerup __P((int unit));
static void cbcp_input __P((int unit, u_char *pkt, int len));
static void cbcp_protrej __P((int unit));
static int cbcp_printpkt __P((u_char *pkt, int len,
void (*printer) __P((void *, char *, ...)),
void *arg));
struct protent cbcp_protent = {
PPP_CBCP,
cbcp_init,
cbcp_input,
cbcp_protrej,
cbcp_lowerup,
NULL,
cbcp_open,
NULL,
cbcp_printpkt,
NULL,
0,
"CBCP",
NULL,
NULL,
NULL
};
cbcp_state cbcp[NUM_PPP];
/* internal prototypes */
static void cbcp_recvreq __P((cbcp_state *us, char *pckt, int len));
static void cbcp_resp __P((cbcp_state *us));
static void cbcp_up __P((cbcp_state *us));
static void cbcp_recvack __P((cbcp_state *us, char *pckt, int len));
static void cbcp_send __P((cbcp_state *us, u_char code, u_char *buf, int len));
/* init state */
static void
cbcp_init(iface)
int iface;
{
cbcp_state *us;
us = &cbcp[iface];
memset(us, 0, sizeof(cbcp_state));
us->us_unit = iface;
us->us_type |= (1 << CB_CONF_NO);
}
/* lower layer is up */
static void
cbcp_lowerup(iface)
int iface;
{
cbcp_state *us = &cbcp[iface];
syslog(LOG_DEBUG, "cbcp_lowerup");
syslog(LOG_DEBUG, "want: %d", us->us_type);
if (us->us_type == CB_CONF_USER)
syslog(LOG_DEBUG, "phone no: %s", us->us_number);
}
static void
cbcp_open(unit)
int unit;
{
syslog(LOG_DEBUG, "cbcp_open");
}
/* process an incomming packet */
static void
cbcp_input(unit, inpacket, pktlen)
int unit;
u_char *inpacket;
int pktlen;
{
u_char *inp;
u_char code, id;
u_short len;
cbcp_state *us = &cbcp[unit];
inp = inpacket;
if (pktlen < CBCP_MINLEN) {
syslog(LOG_ERR, "CBCP packet is too small");
return;
}
GETCHAR(code, inp);
GETCHAR(id, inp);
GETSHORT(len, inp);
#if 0
if (len > pktlen) {
syslog(LOG_ERR, "CBCP packet: invalid length");
return;
}
#endif
len -= CBCP_MINLEN;
switch(code) {
case CBCP_REQ:
us->us_id = id;
cbcp_recvreq(us, inp, len);
break;
case CBCP_RESP:
syslog(LOG_DEBUG, "CBCP_RESP received");
break;
case CBCP_ACK:
if (id != us->us_id)
syslog(LOG_DEBUG, "id doesn't match: expected %d recv %d",
us->us_id, id);
cbcp_recvack(us, inp, len);
break;
default:
break;
}
}
/* protocol was rejected by foe */
void cbcp_protrej(int iface)
{
}
char *cbcp_codenames[] = {
"Request", "Response", "Ack"
};
char *cbcp_optionnames[] = {
"NoCallback",
"UserDefined",
"AdminDefined",
"List"
};
/* pretty print a packet */
static int
cbcp_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __P((void *, char *, ...));
void *arg;
{
int code, opt, id, len, olen, delay;
u_char *pstart;
if (plen < HEADERLEN)
return 0;
pstart = p;
GETCHAR(code, p);
GETCHAR(id, p);
GETSHORT(len, p);
if (len < HEADERLEN || len > plen)
return 0;
if (code >= 1 && code <= sizeof(cbcp_codenames) / sizeof(char *))
printer(arg, " %s", cbcp_codenames[code-1]);
else
printer(arg, " code=0x%x", code);
printer(arg, " id=0x%x", id);
len -= HEADERLEN;
switch (code) {
case CBCP_REQ:
case CBCP_RESP:
case CBCP_ACK:
while(len >= 2) {
GETCHAR(opt, p);
GETCHAR(olen, p);
if (olen < 2 || olen > len) {
break;
}
printer(arg, " <");
len -= olen;
if (opt >= 1 && opt <= sizeof(cbcp_optionnames) / sizeof(char *))
printer(arg, " %s", cbcp_optionnames[opt-1]);
else
printer(arg, " option=0x%x", opt);
if (olen > 2) {
GETCHAR(delay, p);
printer(arg, " delay = %d", delay);
}
if (olen > 3) {
int addrt;
char str[256];
GETCHAR(addrt, p);
memcpy(str, p, olen - 4);
str[olen - 4] = 0;
printer(arg, " number = %s", str);
}
printer(arg, ">");
break;
}
default:
break;
}
for (; len > 0; --len) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
return p - pstart;
}
/* received CBCP request */
static void
cbcp_recvreq(us, pckt, pcktlen)
cbcp_state *us;
char *pckt;
int pcktlen;
{
u_char type, opt_len, delay, addr_type;
char address[256];
int len = pcktlen;
address[0] = 0;
while (len) {
syslog(LOG_DEBUG, "length: %d", len);
GETCHAR(type, pckt);
GETCHAR(opt_len, pckt);
if (opt_len > 2)
GETCHAR(delay, pckt);
us->us_allowed |= (1 << type);
switch(type) {
case CB_CONF_NO:
syslog(LOG_DEBUG, "no callback allowed");
break;
case CB_CONF_USER:
syslog(LOG_DEBUG, "user callback allowed");
if (opt_len > 4) {
GETCHAR(addr_type, pckt);
memcpy(address, pckt, opt_len - 4);
address[opt_len - 4] = 0;
if (address[0])
syslog(LOG_DEBUG, "address: %s", address);
}
break;
case CB_CONF_ADMIN:
syslog(LOG_DEBUG, "user admin defined allowed");
break;
case CB_CONF_LIST:
break;
}
len -= opt_len;
}
cbcp_resp(us);
}
static void
cbcp_resp(us)
cbcp_state *us;
{
u_char cb_type;
u_char buf[256];
u_char *bufp = buf;
int len = 0;
cb_type = us->us_allowed & us->us_type;
syslog(LOG_DEBUG, "cbcp_resp cb_type=%d", cb_type);
#if 0
if (!cb_type)
lcp_down(us->us_unit);
#endif
if (cb_type & ( 1 << CB_CONF_USER ) ) {
syslog(LOG_DEBUG, "cbcp_resp CONF_USER");
PUTCHAR(CB_CONF_USER, bufp);
len = 3 + 1 + strlen(us->us_number) + 1;
PUTCHAR(len , bufp);
PUTCHAR(5, bufp); /* delay */
PUTCHAR(1, bufp);
BCOPY(us->us_number, bufp, strlen(us->us_number) + 1);
cbcp_send(us, CBCP_RESP, buf, len);
return;
}
if (cb_type & ( 1 << CB_CONF_ADMIN ) ) {
syslog(LOG_DEBUG, "cbcp_resp CONF_ADMIN");
PUTCHAR(CB_CONF_ADMIN, bufp);
len = 3 + 1;
PUTCHAR(len , bufp);
PUTCHAR(5, bufp); /* delay */
PUTCHAR(0, bufp);
cbcp_send(us, CBCP_RESP, buf, len);
return;
}
if (cb_type & ( 1 << CB_CONF_NO ) ) {
syslog(LOG_DEBUG, "cbcp_resp CONF_NO");
PUTCHAR(CB_CONF_NO, bufp);
len = 3;
PUTCHAR(len , bufp);
PUTCHAR(0, bufp);
cbcp_send(us, CBCP_RESP, buf, len);
(*ipcp_protent.open)(us->us_unit);
return;
}
}
static void
cbcp_send(us, code, buf, len)
cbcp_state *us;
u_char code;
u_char *buf;
int len;
{
u_char *outp;
int outlen;
outp = outpacket_buf;
outlen = 4 + len;
MAKEHEADER(outp, PPP_CBCP);
PUTCHAR(code, outp);
PUTCHAR(us->us_id, outp);
PUTSHORT(outlen, outp);
if (len)
BCOPY(buf, outp, len);
output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
}
static void
cbcp_recvack(us, pckt, len)
cbcp_state *us;
char *pckt;
int len;
{
u_char type, delay, addr_type;
int opt_len;
char address[256];
if (len) {
GETCHAR(type, pckt);
GETCHAR(opt_len, pckt);
if (opt_len > 2)
GETCHAR(delay, pckt);
if (opt_len > 4) {
GETCHAR(addr_type, pckt);
memcpy(address, pckt, opt_len - 4);
address[opt_len - 4] = 0;
if (address[0])
syslog(LOG_DEBUG, "peer will call: %s", address);
}
}
cbcp_up(us);
}
extern int persist;
/* ok peer will do callback */
static void
cbcp_up(us)
cbcp_state *us;
{
persist = 0;
lcp_close(0, "Call me back, please");
}

View File

@@ -1,26 +0,0 @@
#ifndef CBCP_H
#define CBCP_H
typedef struct cbcp_state {
int us_unit; /* Interface unit number */
u_char us_id; /* Current id */
u_char us_allowed;
int us_type;
char *us_number; /* Telefone Number */
} cbcp_state;
extern cbcp_state cbcp[];
extern struct protent cbcp_protent;
#define CBCP_MINLEN 4
#define CBCP_REQ 1
#define CBCP_RESP 2
#define CBCP_ACK 3
#define CB_CONF_NO 1
#define CB_CONF_USER 2
#define CB_CONF_ADMIN 3
#define CB_CONF_LIST 4
#endif

View File

@@ -25,20 +25,60 @@
* OR MODIFICATIONS.
*/
#ifndef lint
/* static char rcsid[] = "$Id$"; */
#endif
#define RCSID "$Id$"
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include "pppd.h"
#include "fsm.h"
#include "ccp.h"
#include <net/ppp-comp.h>
static const char rcsid[] = RCSID;
/*
* Command-line options.
*/
static int setbsdcomp __P((char **));
static int setdeflate __P((char **));
static option_t ccp_option_list[] = {
{ "noccp", o_bool, &ccp_protent.enabled_flag,
"Disable CCP negotiation" },
{ "-ccp", o_bool, &ccp_protent.enabled_flag,
"Disable CCP negotiation" },
{ "bsdcomp", o_special, setbsdcomp,
"Request BSD-Compress packet compression" },
{ "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress,
"don't allow BSD-Compress", OPT_A2COPY,
&ccp_allowoptions[0].bsd_compress },
{ "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress,
"don't allow BSD-Compress", OPT_A2COPY,
&ccp_allowoptions[0].bsd_compress },
{ "deflate", 1, setdeflate,
"request Deflate compression" },
{ "nodeflate", o_bool, &ccp_wantoptions[0].deflate,
"don't allow Deflate compression", OPT_A2COPY,
&ccp_allowoptions[0].deflate },
{ "-deflate", o_bool, &ccp_wantoptions[0].deflate,
"don't allow Deflate compression", OPT_A2COPY,
&ccp_allowoptions[0].deflate },
{ "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft,
"don't use draft deflate #", OPT_A2COPY,
&ccp_allowoptions[0].deflate_draft },
{ "predictor1", o_bool, &ccp_wantoptions[0].predictor_1,
"request Predictor-1", 1, &ccp_allowoptions[0].predictor_1 },
{ "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1,
"don't allow Predictor-1", OPT_A2COPY,
&ccp_allowoptions[0].predictor_1 },
{ "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1,
"don't allow Predictor-1", OPT_A2COPY,
&ccp_allowoptions[0].predictor_1 },
{ NULL }
};
/*
* Protocol entry points from main code.
*/
@@ -67,6 +107,8 @@ struct protent ccp_protent = {
ccp_datainput,
1,
"CCP",
"Compressed",
ccp_option_list,
NULL,
NULL,
NULL
@@ -129,6 +171,83 @@ static int ccp_localstate[NUM_PPP];
static int all_rejected[NUM_PPP]; /* we rejected all peer's options */
/*
* Option parsing.
*/
static int
setbsdcomp(argv)
char **argv;
{
int rbits, abits;
char *str, *endp;
str = *argv;
abits = rbits = strtol(str, &endp, 0);
if (endp != str && *endp == ',') {
str = endp + 1;
abits = strtol(str, &endp, 0);
}
if (*endp != 0 || endp == str) {
option_error("invalid parameter '%s' for bsdcomp option", *argv);
return 0;
}
if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS))
|| (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) {
option_error("bsdcomp option values must be 0 or %d .. %d",
BSD_MIN_BITS, BSD_MAX_BITS);
return 0;
}
if (rbits > 0) {
ccp_wantoptions[0].bsd_compress = 1;
ccp_wantoptions[0].bsd_bits = rbits;
} else
ccp_wantoptions[0].bsd_compress = 0;
if (abits > 0) {
ccp_allowoptions[0].bsd_compress = 1;
ccp_allowoptions[0].bsd_bits = abits;
} else
ccp_allowoptions[0].bsd_compress = 0;
return 1;
}
static int
setdeflate(argv)
char **argv;
{
int rbits, abits;
char *str, *endp;
str = *argv;
abits = rbits = strtol(str, &endp, 0);
if (endp != str && *endp == ',') {
str = endp + 1;
abits = strtol(str, &endp, 0);
}
if (*endp != 0 || endp == str) {
option_error("invalid parameter '%s' for deflate option", *argv);
return 0;
}
if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE))
|| (abits != 0 && (abits < DEFLATE_MIN_SIZE
|| abits > DEFLATE_MAX_SIZE))) {
option_error("deflate option values must be 0 or %d .. %d",
DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE);
return 0;
}
if (rbits > 0) {
ccp_wantoptions[0].deflate = 1;
ccp_wantoptions[0].deflate_size = rbits;
} else
ccp_wantoptions[0].deflate = 0;
if (abits > 0) {
ccp_allowoptions[0].deflate = 1;
ccp_allowoptions[0].deflate_size = abits;
} else
ccp_allowoptions[0].deflate = 0;
return 1;
}
/*
* ccp_init - initialize CCP.
*/
@@ -237,8 +356,8 @@ ccp_input(unit, p, len)
*/
oldstate = f->state;
fsm_input(f, p, len);
if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED);
syslog(LOG_NOTICE, "Compression disabled by peer.");
if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED)
notice("Compression disabled by peer.");
/*
* If we get a terminate-ack and we're not asking for compression,
@@ -589,12 +708,9 @@ ccp_nakci(f, p, len)
/*
* Predictor-1 and 2 have no options, so they can't be Naked.
*
* XXX What should we do with any remaining options?
* There may be remaining options but we ignore them.
*/
if (len != 0)
return 0;
if (f->state != OPENED)
*go = try;
return 1;
@@ -872,27 +988,28 @@ method_name(opt, opt2)
case CI_DEFLATE:
case CI_DEFLATE_DRAFT:
if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)
sprintf(result, "Deflate%s (%d/%d)",
(opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
opt->deflate_size, opt2->deflate_size);
slprintf(result, sizeof(result), "Deflate%s (%d/%d)",
(opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
opt->deflate_size, opt2->deflate_size);
else
sprintf(result, "Deflate%s (%d)",
(opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
opt->deflate_size);
slprintf(result, sizeof(result), "Deflate%s (%d)",
(opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
opt->deflate_size);
break;
case CI_BSD_COMPRESS:
if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits)
sprintf(result, "BSD-Compress (%d/%d)", opt->bsd_bits,
opt2->bsd_bits);
slprintf(result, sizeof(result), "BSD-Compress (%d/%d)",
opt->bsd_bits, opt2->bsd_bits);
else
sprintf(result, "BSD-Compress (%d)", opt->bsd_bits);
slprintf(result, sizeof(result), "BSD-Compress (%d)",
opt->bsd_bits);
break;
case CI_PREDICTOR_1:
return "Predictor 1";
case CI_PREDICTOR_2:
return "Predictor 2";
default:
sprintf(result, "Method %d", opt->method);
slprintf(result, sizeof(result), "Method %d", opt->method);
}
return result;
}
@@ -912,23 +1029,16 @@ ccp_up(f)
if (ANY_COMPRESS(*go)) {
if (ANY_COMPRESS(*ho)) {
if (go->method == ho->method) {
syslog(LOG_NOTICE, "%s compression enabled",
method_name(go, ho))
;
notice("%s compression enabled", method_name(go, ho));
} else {
strcpy(method1, method_name(go, NULL));
syslog(LOG_NOTICE, "%s / %s compression enabled",
method1, method_name(ho, NULL))
;
strlcpy(method1, method_name(go, NULL), sizeof(method1));
notice("%s / %s compression enabled",
method1, method_name(ho, NULL));
}
} else
syslog(LOG_NOTICE, "%s receive compression enabled",
method_name(go, NULL))
;
notice("%s receive compression enabled", method_name(go, NULL));
} else if (ANY_COMPRESS(*ho))
syslog(LOG_NOTICE, "%s transmit compression enabled",
method_name(ho, NULL))
;
notice("%s transmit compression enabled", method_name(ho, NULL));
}
/*
@@ -1031,26 +1141,26 @@ ccp_printpkt(p, plen, printer, arg)
}
break;
}
/* while (p < optend)
while (p < optend)
printer(arg, " %.2x", *p++);
printer(arg, ">");
*/ }
}
break;
case TERMACK:
case TERMREQ:
/* if (len > 0 && *p >= ' ' && *p < 0x7f) {
if (len > 0 && *p >= ' ' && *p < 0x7f) {
print_string(p, len, printer, arg);
p += len;
len = 0;
}
*/ break;
break;
}
/* dump out the rest of the packet in hex */
/* while (--len >= 0)
while (--len >= 0)
printer(arg, " %.2x", *p++);
*/
return p - p0;
}
@@ -1080,7 +1190,7 @@ ccp_datainput(unit, pkt, len)
/*
* Disable compression by taking CCP down.
*/
syslog(LOG_ERR, "Lost compression sync: disabling compression");
error("Lost compression sync: disabling compression");
ccp_close(unit, "Lost compression sync");
} else {
/*

View File

@@ -28,12 +28,12 @@
*/
typedef struct ccp_options {
u_int bsd_compress: 1; /* do BSD Compress? */
u_int deflate: 1; /* do Deflate? */
u_int predictor_1: 1; /* do Predictor-1? */
u_int predictor_2: 1; /* do Predictor-2? */
u_int deflate_correct: 1; /* use correct code for deflate? */
u_int deflate_draft: 1; /* use draft RFC code for deflate? */
bool bsd_compress; /* do BSD Compress? */
bool deflate; /* do Deflate? */
bool predictor_1; /* do Predictor-1? */
bool predictor_2; /* do Predictor-2? */
bool deflate_correct; /* use correct code for deflate? */
bool deflate_draft; /* use draft RFC code for deflate? */
u_short bsd_bits; /* # bits/code for BSD Compress */
u_short deflate_size; /* lg(window size) for Deflate */
short method; /* code for chosen compression method */

View File

@@ -33,9 +33,7 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
/* static char rcsid[] = "$Id$"; */
#endif
#define RCSID "$Id$"
/*
* TODO:
@@ -45,7 +43,6 @@
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <syslog.h>
#include "pppd.h"
#include "chap.h"
@@ -54,6 +51,25 @@
#include "chap_ms.h"
#endif
static const char rcsid[] = RCSID;
/*
* Command-line options.
*/
static option_t chap_option_list[] = {
{ "chap-restart", o_int, &chap[0].timeouttime,
"Set timeout for CHAP" },
{ "chap-max-challenge", o_int, &chap[0].max_transmits,
"Set max #xmits for challenge" },
{ "chap-interval", o_int, &chap[0].chal_interval,
"Set interval for rechallenge" },
#ifdef MSLANMAN
{ "ms-lanman", o_bool, &ms_lanman,
"Use LanMan passwd when using MS-CHAP", 1 },
#endif
{ NULL }
};
/*
* Protocol entry points.
*/
@@ -79,6 +95,8 @@ struct protent chap_protent = {
1,
"CHAP",
NULL,
chap_option_list,
NULL,
NULL,
NULL
};
@@ -96,13 +114,8 @@ 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 *));
/* #include <stdlib.h> */
extern double drand48 __P((void));
/*{
return (((double)rand())/RAND_MAX);
}
*/
extern void srand48 __P((long));
/*
@@ -199,7 +212,7 @@ ChapChallengeTimeout(arg)
if (cstate->chal_transmits >= cstate->max_transmits) {
/* give up on peer */
syslog(LOG_ERR, "Peer failed to respond to CHAP challenge");
error("Peer failed to respond to CHAP challenge");
cstate->serverstate = CHAPSS_BADAUTH;
auth_peer_fail(cstate->unit, PPP_CHAP);
return;
@@ -336,18 +349,18 @@ ChapInput(unit, inpacket, packet_len)
*/
inp = inpacket;
if (packet_len < CHAP_HEADERLEN) {
CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short header."));
CHAPDEBUG(("ChapInput: rcvd short header."));
return;
}
GETCHAR(code, inp);
GETCHAR(id, inp);
GETSHORT(len, inp);
if (len < CHAP_HEADERLEN) {
CHAPDEBUG((LOG_INFO, "ChapInput: rcvd illegal length."));
CHAPDEBUG(("ChapInput: rcvd illegal length."));
return;
}
if (len > packet_len) {
CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short packet."));
CHAPDEBUG(("ChapInput: rcvd short packet."));
return;
}
len -= CHAP_HEADERLEN;
@@ -373,7 +386,7 @@ ChapInput(unit, inpacket, packet_len)
break;
default: /* Need code reject? */
syslog(LOG_WARNING, "Unknown CHAP code (%d) received.", code);
warn("Unknown CHAP code (%d) received.", code);
break;
}
}
@@ -397,23 +410,21 @@ ChapReceiveChallenge(cstate, inp, id, len)
MD5_CTX mdContext;
u_char hash[MD5_SIGNATURE_SIZE];
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.", id));
if (cstate->clientstate == CHAPCS_CLOSED ||
cstate->clientstate == CHAPCS_PENDING) {
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: in state %d",
cstate->clientstate));
CHAPDEBUG(("ChapReceiveChallenge: in state %d", cstate->clientstate));
return;
}
if (len < 2) {
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet."));
CHAPDEBUG(("ChapReceiveChallenge: rcvd short packet."));
return;
}
GETCHAR(rchallenge_len, inp);
len -= sizeof (u_char) + rchallenge_len; /* now name field length */
if (len < 0) {
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet."));
CHAPDEBUG(("ChapReceiveChallenge: rcvd short packet."));
return;
}
rchallenge = inp;
@@ -424,14 +435,10 @@ ChapReceiveChallenge(cstate, inp, id, len)
BCOPY(inp, rhostname, len);
rhostname[len] = '\000';
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field '%s'",
rhostname));
/* Microsoft doesn't send their name back in the PPP packet */
if (remote_name[0] != 0 && (explicit_remote || rhostname[0] == 0)) {
strncpy(rhostname, remote_name, sizeof(rhostname));
rhostname[sizeof(rhostname) - 1] = 0;
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name",
if (explicit_remote || (remote_name[0] != 0 && rhostname[0] == 0)) {
strlcpy(rhostname, remote_name, sizeof(rhostname));
CHAPDEBUG(("ChapReceiveChallenge: using '%q' as remote name",
rhostname));
}
@@ -439,8 +446,7 @@ ChapReceiveChallenge(cstate, inp, id, len)
if (!get_secret(cstate->unit, cstate->resp_name, rhostname,
secret, &secret_len, 0)) {
secret_len = 0; /* assume null secret if can't find one */
syslog(LOG_WARNING, "No CHAP secret found for authenticating us to %s",
rhostname);
warn("No CHAP secret found for authenticating us to %q", rhostname);
}
/* cancel response send timeout if necessary */
@@ -470,7 +476,7 @@ ChapReceiveChallenge(cstate, inp, id, len)
#endif
default:
CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->resp_type));
CHAPDEBUG(("unknown digest type %d", cstate->resp_type));
return;
}
@@ -497,12 +503,9 @@ ChapReceiveResponse(cstate, inp, id, len)
char secret[MAXSECRETLEN];
u_char hash[MD5_SIGNATURE_SIZE];
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: Rcvd id %d.", id));
if (cstate->serverstate == CHAPSS_CLOSED ||
cstate->serverstate == CHAPSS_PENDING) {
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: in state %d",
cstate->serverstate));
CHAPDEBUG(("ChapReceiveResponse: in state %d", cstate->serverstate));
return;
}
@@ -524,7 +527,7 @@ ChapReceiveResponse(cstate, inp, id, len)
}
if (len < 2) {
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet."));
CHAPDEBUG(("ChapReceiveResponse: rcvd short packet."));
return;
}
GETCHAR(remmd_len, inp); /* get length of MD */
@@ -533,7 +536,7 @@ ChapReceiveResponse(cstate, inp, id, len)
len -= sizeof (u_char) + remmd_len;
if (len < 0) {
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet."));
CHAPDEBUG(("ChapReceiveResponse: rcvd short packet."));
return;
}
@@ -544,18 +547,14 @@ ChapReceiveResponse(cstate, inp, id, len)
BCOPY(inp, rhostname, len);
rhostname[len] = '\000';
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: received name field: %s",
rhostname));
/*
* Get secret for authenticating them with us,
* do the hash ourselves, and compare the result.
*/
code = CHAP_FAILURE;
if (!get_secret(cstate->unit, rhostname, cstate->chal_name,
secret, &secret_len, 1)) {
syslog(LOG_WARNING, "No CHAP secret found for authenticating %s",
rhostname);
if (!get_secret(cstate->unit, (explicit_remote? remote_name: rhostname),
cstate->chal_name, secret, &secret_len, 1)) {
warn("No CHAP secret found for authenticating %q", rhostname);
} else {
/* generate MD based on negotiated type */
@@ -576,7 +575,7 @@ ChapReceiveResponse(cstate, inp, id, len)
break;
default:
CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->chal_type));
CHAPDEBUG(("unknown digest type %d", cstate->chal_type));
}
}
@@ -591,12 +590,10 @@ ChapReceiveResponse(cstate, inp, id, len)
}
if (cstate->chal_interval != 0)
TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);
syslog(LOG_NOTICE, "CHAP peer authentication succeeded for %s",
rhostname);
notice("CHAP peer authentication succeeded for %q", rhostname);
} else {
syslog(LOG_ERR, "CHAP peer authentication failed for remote host %s",
rhostname);
error("CHAP peer authentication failed for remote host %q", rhostname);
cstate->serverstate = CHAPSS_BADAUTH;
auth_peer_fail(cstate->unit, PPP_CHAP);
}
@@ -609,20 +606,17 @@ static void
ChapReceiveSuccess(cstate, inp, id, len)
chap_state *cstate;
u_char *inp;
int id; /* was u_char id */
u_char id;
int len;
{
CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: Rcvd id %d.", id));
if (cstate->clientstate == CHAPCS_OPEN)
/* presumably an answer to a duplicate response */
return;
if (cstate->clientstate != CHAPCS_RESPONSE) {
/* don't know what this is */
CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: in state %d\n",
cstate->clientstate));
CHAPDEBUG(("ChapReceiveSuccess: in state %d\n", cstate->clientstate));
return;
}
@@ -647,15 +641,12 @@ static void
ChapReceiveFailure(cstate, inp, id, len)
chap_state *cstate;
u_char *inp;
int id; /* was u_char id; */
u_char id;
int len;
{
CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: Rcvd id %d.", id));
if (cstate->clientstate != CHAPCS_RESPONSE) {
/* don't know what this is */
CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: in state %d\n",
cstate->clientstate));
CHAPDEBUG(("ChapReceiveFailure: in state %d\n", cstate->clientstate));
return;
}
@@ -667,7 +658,7 @@ ChapReceiveFailure(cstate, inp, id, len)
if (len > 0)
PRINTMSG(inp, len);
syslog(LOG_ERR, "CHAP authentication failed");
error("CHAP authentication failed");
auth_withpeer_fail(cstate->unit, PPP_CHAP);
}
@@ -702,8 +693,6 @@ ChapSendChallenge(cstate)
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.", cstate->chal_id));
TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);
++cstate->chal_transmits;
}
@@ -722,9 +711,9 @@ ChapSendStatus(cstate, code)
char msg[256];
if (code == CHAP_SUCCESS)
sprintf(msg, "Welcome to %s.", hostname);
slprintf(msg, sizeof(msg), "Welcome to %s.", hostname);
else
sprintf(msg, "I don't like you. Go 'way.");
slprintf(msg, sizeof(msg), "I don't like you. Go 'way.");
msglen = strlen(msg);
outlen = CHAP_HEADERLEN + msglen;
@@ -737,9 +726,6 @@ ChapSendStatus(cstate, code)
PUTSHORT(outlen, outp);
BCOPY(msg, outp, msglen);
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.", code,
cstate->chal_id));
}
/*
@@ -755,7 +741,7 @@ ChapGenChallenge(cstate)
{
int chal_len;
u_char *ptr = cstate->challenge;
unsigned int i;
int i;
/* pick a random challenge length between MIN_CHALLENGE_LENGTH and
MAX_CHALLENGE_LENGTH */
@@ -767,7 +753,7 @@ ChapGenChallenge(cstate)
cstate->chal_transmits = 0;
/* generate a random string */
for (i = 0; i < chal_len; i++ )
for (i = 0; i < chal_len; i++)
*ptr++ = (char) (drand48() * 0xff);
}
@@ -825,6 +811,7 @@ ChapPrintPkt(p, plen, printer, arg)
int code, id, len;
int clen, nlen;
u_char x;
if (plen < CHAP_HEADERLEN)
return 0;
GETCHAR(code, p);
@@ -868,5 +855,6 @@ ChapPrintPkt(p, plen, printer, arg)
printer(arg, " %.2x", x);
}
}
return len + CHAP_HEADERLEN;
}

View File

@@ -55,8 +55,8 @@
/*
* Challenge lengths (for challenges we send) and other limits.
*/
#define MIN_CHALLENGE_LENGTH 32
#define MAX_CHALLENGE_LENGTH 64
#define MIN_CHALLENGE_LENGTH 16
#define MAX_CHALLENGE_LENGTH 24
#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 or MS-CHAP */
/*

View File

@@ -31,18 +31,16 @@
* You should also use DOMAIN\\USERNAME as described in README.MSCHAP80
*/
#ifndef lint
/* static char rcsid[] = "$Id$"; */
#endif
#define RCSID "$Id$"
#ifdef CHAPMS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/time.h>
#include <syslog.h>
#include <unistd.h>
#ifdef HAVE_CRYPT_H
#include <crypt.h>
@@ -57,6 +55,8 @@
#include <des.h>
#endif
static const char rcsid[] = RCSID;
typedef struct {
u_char LANManResp[24];
u_char NTResp[24];
@@ -80,6 +80,11 @@ static void Expand __P((u_char *, u_char *));
static void Collapse __P((u_char *, u_char *));
#endif
#ifdef MSLANMAN
bool ms_lanman = 0; /* Use LanMan password instead of NT */
/* Has meaning only with MS-CHAP challenges */
#endif
static void
ChallengeResponse(challenge, pwHash, response)
u_char *challenge; /* IN 8 octets */
@@ -92,7 +97,8 @@ ChallengeResponse(challenge, pwHash, response)
BCOPY(pwHash, ZPasswordHash, MD4_SIGNATURE_SIZE);
#if 0
log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG);
dbglog("ChallengeResponse - ZPasswordHash %.*B",
sizeof(ZPasswordHash), ZPasswordHash);
#endif
DesEncrypt(challenge, ZPasswordHash + 0, response + 0);
@@ -100,7 +106,7 @@ ChallengeResponse(challenge, pwHash, response)
DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
#if 0
log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG);
dbglog("ChallengeResponse - response %.24B", response);
#endif
}
@@ -122,8 +128,7 @@ DesEncrypt(clear, key, cipher)
setkey(crypt_key);
#if 0
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X",
clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %.8B", clear));
#endif
Expand(clear, des_input);
@@ -131,8 +136,7 @@ DesEncrypt(clear, key, cipher)
Collapse(des_input, cipher);
#if 0
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X",
cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %.8B", cipher));
#endif
}
@@ -152,15 +156,13 @@ DesEncrypt(clear, key, cipher)
des_set_key(&des_key, key_schedule);
#if 0
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X",
clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %.8B", clear));
#endif
des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
#if 0
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X",
cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %.8B", cipher));
#endif
}
@@ -239,10 +241,8 @@ static void MakeKey(key, des_key)
#endif
#if 0
CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X",
key[0], key[1], key[2], key[3], key[4], key[5], key[6]));
CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X",
des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7]));
CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %.7B", key));
CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %.8B", des_key));
#endif
}
@@ -255,6 +255,12 @@ ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, response)
MS_ChapResponse *response;
{
int i;
#ifdef __NetBSD__
/* NetBSD uses the libc md4 routines which take bytes instead of bits */
int mdlen = secret_len * 2;
#else
int mdlen = secret_len * 2 * 8;
#endif
MD4_CTX md4Context;
u_char hash[MD4_SIGNATURE_SIZE];
u_char unicodePassword[MAX_NT_PASSWORD * 2];
@@ -266,7 +272,7 @@ ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, response)
unicodePassword[i * 2] = (u_char)secret[i];
MD4Init(&md4Context);
MD4Update(&md4Context, unicodePassword, secret_len * 2 * 8); /* Unicode is 2 bytes/char, *8 for bit count */
MD4Update(&md4Context, unicodePassword, mdlen);
MD4Final(hash, &md4Context); /* Tell MD4 we're done */
@@ -307,9 +313,6 @@ ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len)
int secret_len;
{
MS_ChapResponse response;
#ifdef MSLANMAN
extern int ms_lanman;
#endif
#if 0
CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'", secret_len, secret));

View File

@@ -156,7 +156,6 @@ int Verbose = 0;
int quiet = 0;
int report = 0;
int exit_code = 0;
static int speed=0;
char *report_file = (char *) 0;
char *chat_file = (char *) 0;
char *phone_num = (char *) 0;
@@ -167,8 +166,8 @@ int have_tty_parameters = 0;
#ifdef TERMIOS
#define term_parms struct termios
#define get_term_param(param) tcgetattr(modem_fd, param)
#define set_term_param(param) tcsetattr(modem_fd, TCSANOW, param)
#define get_term_param(param) tcgetattr(ttyfd, param)
#define set_term_param(param) tcsetattr(ttyfd, TCSANOW, param)
struct termios saved_tty_parameters;
#endif
@@ -260,52 +259,35 @@ char *getnextcommand(char **string)
}
extern int modem_fd;
int
chatmain(argv)
char *argv;
extern int ttyfd;
int chatmain(argv)
char *argv;
{
char *arg;
int i;
char *t;
exit_code=0;
speed=0;
/*
* Default the report file to the stderr location
*/
/* if (report_fp == NULL)
report_fp = stderr;
*/
init();
while ( (arg = getnextcommand(&argv)) != NULL) {
chat_expect(arg);
if (exit_code>0) break;
t=temp2;
char *arg;
while(*t)
{
if (strncmp("CARRIER",t,7)==0)
{/* parse speed information */
i=0;
while(!isdigit(t[i]))
i++;
t=&t[i];
i=0;
while(isdigit(t[i]))
i++;
t[i]=0;
sscanf(t,"%d",&speed);
break;
}
t++;
}
if ((arg = getnextcommand(&argv)) != NULL)
chat_send(arg);
if (exit_code>0) break;
}
/* initialize exit code */
exit_code = 0;
if (exit_code) return exit_code;
return -speed;
printf("chat_main: %s\n", argv);
/* get first expect string */
arg = getnextcommand(&argv);
while ( arg != NULL ) {
/* process the expect string */
chat_expect(arg);
/* get the next send string */
arg = getnextcommand(&argv);
if ( arg != NULL ) {
/* process the send string */
chat_send(arg);
/* get the next expect string */
arg = getnextcommand(&argv);
}
}
return 0;
}
@@ -317,7 +299,6 @@ int
void init()
{
set_tty_parameters();
speed=0;
}
void set_tty_parameters()
@@ -657,7 +638,7 @@ register char *s;
if (say_next) {
say_next = 0;
s = clean(s,0);
write(modem_fd, s, strlen(s));
write(ttyfd, s, strlen(s));
free(s);
return;
}
@@ -682,63 +663,6 @@ register char *s;
return;
}
/* if (report_next) {
char *s1;
report_next = 0;
if (n_reports >= MAX_REPORTS)
{
exit_code=2;
return;
}
s1 = clean(s, 0);
if (strlen(s1) > strlen(s) || strlen(s1) > sizeof fail_buffer - 1)
{
exit_code=1;
return;
}
report_string[n_reports++] = s1;
return;
}
*/
/* if (clear_report_next) {
char *s1;
int i;
int old_max;
int pack = 0;
clear_report_next = 0;
s1 = clean(s, 0);
if (strlen(s1) > strlen(s) || strlen(s1) > sizeof fail_buffer - 1)
{
exit_code=1;
return;
}
old_max = n_reports;
for (i=0; i < n_reports; i++) {
if ( strcmp(s1,report_string[i]) == 0 ) {
free(report_string[i]);
report_string[i] = NULL;
pack++;
n_reports--;
}
}
free(s1);
if (pack)
pack_array(report_string,old_max);
return;
}
*/
if (timeout_next) {
timeout=atoi(s);
timeout_next = 0;
@@ -770,7 +694,7 @@ int get_char()
while(tries)
{
status = read(modem_fd, &c, 1);
status = read(ttyfd, &c, 1);
switch (status) {
case 1:
return ((int)c & 0x7F);
@@ -789,7 +713,7 @@ int c;
/* inter-character typing delay (?) */
status = write(modem_fd, &ch, 1);
status = write(ttyfd, &ch, 1);
switch (status) {
case 1:
@@ -814,8 +738,6 @@ int c;
int put_string (s)
register char *s;
{
quiet = 0;
s = clean(s, 1);
while (*s) {
@@ -898,10 +820,10 @@ register char *string;
char *logged = temp2;
struct termios tios;
tcgetattr(modem_fd, &tios);
tcgetattr(ttyfd, &tios);
tios.c_cc[VMIN] = 0;
tios.c_cc[VTIME] = timeout*10/MAX_TIMEOUTS;
tcsetattr(modem_fd, TCSANOW, &tios);
tcsetattr(ttyfd, TCSANOW, &tios);
string = clean(string, 0);
len = strlen(string);

View File

@@ -17,16 +17,13 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
/* static char rcsid[] = "$Id$"; */
#endif
#define RCSID "$Id$";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <syslog.h>
#include <netdb.h>
#include <sys/param.h>
#include <sys/types.h>
@@ -46,6 +43,8 @@
#include "ipcp.h"
#include "lcp.h"
static const char rcsid[] = RCSID;
char *frame;
int framelen;
int framemax;
@@ -262,7 +261,7 @@ loop_frame(frame, len)
{
struct packet *pkt;
/* log_packet(frame, len, "from loop: ", LOG_DEBUG); */
/* dbglog("from loop: %P", frame, len); */
if (len < PPP_HDRLEN)
return 0;
if ((PPP_PROTOCOL(frame) & 0x8000) != 0)

View File

@@ -0,0 +1,45 @@
#
# Makefile
#
#
# RTEMS_MAKEFILE_PATH is typically set in an environment variable
#
EXEC=ppptest.exe
PGM=${ARCH}/$(EXEC)
# optional managers required
MANAGERS=io event semaphore
# C source names
CSRCS = init.c pppdapp.c
COBJS_ = $(CSRCS:.c=.o)
COBJS = $(COBJS_:%=${ARCH}/%)
# C++ source names
CXXSRCS =
CXXOBJS_ = $(CXXSRCS:.cc=.o)
CXXOBJS = $(CXXOBJS_:%=${ARCH}/%)
# AS source names
ASSRCS =
ASOBJS_ = $(ASSRCS:.s=.o)
ASOBJS = $(ASOBJS_:%=${ARCH}/%)
# Libraries
LIBS = -lrtemsall -lc
include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
include $(RTEMS_CUSTOM)
include $(PROJECT_ROOT)/make/leaf.cfg
OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS)
all: ${ARCH} $(PGM)
$(PGM): $(OBJS)
$(make-exe)

View File

@@ -0,0 +1,6 @@
#
# $Id$
#
This is an example user application using pppd. It is built using
the RTEMS application Makefiles.

View File

@@ -0,0 +1,24 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rtems/rtems_bsdnet.h>
#include <rtemspppd.h>
#define CONFIGURE_INIT
#include "system.h"
#include "netconfig.h"
extern int pppdapp_initialize(void);
rtems_task Init(rtems_task_argument argument)
{
/* initialize network */
rtems_bsdnet_initialize_network();
rtems_pppd_initialize();
pppdapp_initialize();
rtems_task_delete(RTEMS_SELF);
}

View File

@@ -0,0 +1,37 @@
#ifndef NETCONFIG_H_
#define NETCONFIG_H_
#include <bsp.h>
/* external function prototypes */
extern int rtems_ppp_driver_attach(struct rtems_bsdnet_ifconfig *config,
int attaching);
/* Default network interface */
static struct rtems_bsdnet_ifconfig netdriver_config = {
"ppp0", /* name */
rtems_ppp_driver_attach, /* attach function */
NULL, /* No more interfaces */
"192.168.2.123", /* IP address */
"255.255.255.0", /* IP net mask */
NULL, /* Driver supplies hardware address */
0 /* Use default driver parameters */
};
/* Network configuration */
struct rtems_bsdnet_config rtems_bsdnet_config = {
&netdriver_config,
NULL,
0, /* Default network task priority */
0, /* Default mbuf capacity */
0, /* Default mbuf cluster capacity */
"rtems", /* Host name */
"xxxyyy.com", /* Domain name */
0, /* Gateway */
0, /* Log host */
{ 0 }, /* Name server(s) */
{ 0 }, /* NTP server(s) */
};
#endif

View File

@@ -0,0 +1,27 @@
#
# Example configuration file for setting up a ppp server
# using a null-modem serial cable:
#
# Tested using ppp on OpenBSD 2.9
# - just follow instructions in man page for accepting
# ppp connections over the serial port
# - if pap and/or chap is enabled, you must have a ppp.secret
# file which will be used for user authentication
# - found useful to turn on syslog for ppp
#
default:
set log Phase Chat LQM LCP IPCP CCP command
set device /dev/cua00
set speed 57600
set ctsrts on
set dial ""
openbsd-server:
set timeout 0
set ifaddr 192.168.2.100 192.168.2.123
enable dns
allow users
enable chap
enable pap

View File

@@ -0,0 +1,146 @@
#include <stdio.h>
#include <rtemspppd.h>
#include "system.h"
/* define global variables */
static unsigned int pppdapp_linkcount = 0;
static rtems_id pppdapp_taskid;
static void pppdapp_linkup_hook(void)
{
pppdapp_linkcount++;
printf("PPP LINK UP [%d]\n", pppdapp_linkcount);
}
static void pppdapp_linkdown_hook(void)
{
printf("PPP LINK DOWN [%d]\n", pppdapp_linkcount);
}
static void pppdapp_ipup_hook(void)
{
/* send ipup signal to pppdapp task */
rtems_event_send(pppdapp_taskid, RTEMS_EVENT_10);
}
static void pppdapp_ipdown_hook(void)
{
/* send ip down signal to pppdapp task */
rtems_event_send(pppdapp_taskid, RTEMS_EVENT_11);
}
static void pppdapp_setup(void)
{
const char *pUser = "oscar";
const char *pPassword = "goldman";
#undef USE_MODEM
#ifdef USE_MODEM
const char *pTelephone = "5551234";
const char *pInitScript = "TIMEOUT@5@@AT@@OK@";
const char *pConnectScript = "TIMEOUT@90@@ATDT%s@CONNECT@@name:@%s@word:@%s@";
const char *pDisconnectScript = "TIMEOUT@5@@ATH0@@OK@";
char pConnect[128];
/* set the connect string */
sprintf(pConnect, pConnectScript, pTelephone, pUser, pPassword);
/* set pppd options for modem */
rtems_pppd_set_option("/dev/ttyS2", NULL);
rtems_pppd_set_option("57600", NULL);
rtems_pppd_set_option("crtscts", NULL);
rtems_pppd_set_option("modem", NULL);
rtems_pppd_set_option("noauth", NULL);
rtems_pppd_set_option("debug", NULL);
rtems_pppd_set_option("init", pInitScript);
rtems_pppd_set_option("connect", pConnect);
rtems_pppd_set_option("disconnect", pDisconnectScript);
#else
/* set pppd options for null modem direct link serial cable */
rtems_pppd_set_option("/dev/ttyS1", NULL);
rtems_pppd_set_option("57600", NULL);
rtems_pppd_set_option("crtscts", NULL);
rtems_pppd_set_option("local", NULL);
rtems_pppd_set_option("noauth", NULL);
rtems_pppd_set_option("debug", NULL);
rtems_pppd_set_option("user", pUser);
rtems_pppd_set_option("password", pPassword);
#endif
/* set up pppd hooks */
rtems_pppd_set_hook(RTEMS_PPPD_LINKUP_HOOK, pppdapp_linkup_hook);
rtems_pppd_set_hook(RTEMS_PPPD_LINKDOWN_HOOK, pppdapp_linkdown_hook);
rtems_pppd_set_hook(RTEMS_PPPD_IPUP_HOOK, pppdapp_ipup_hook);
rtems_pppd_set_hook(RTEMS_PPPD_IPDOWN_HOOK, pppdapp_ipdown_hook);
}
static rtems_task pppdapp(rtems_task_argument arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
rtems_interval tickspersecond = 0;
rtems_option options;
rtems_event_set in;
rtems_event_set out;
/* initialize ticks per second */
rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &tickspersecond);
if ( tickspersecond == 0 ) {
/* ensure value is greater than zero */
tickspersecond = 100;
}
/* initiate connection */
pppdapp_setup();
rtems_pppd_connect();
/* enter processing loop */
in = (RTEMS_EVENT_10 | RTEMS_EVENT_11);
options = (RTEMS_EVENT_ANY | RTEMS_WAIT);
while ( sc == RTEMS_SUCCESSFUL ) {
/* wait for the next event */
sc = rtems_event_receive(in, options, RTEMS_NO_TIMEOUT, &out);
if ( sc == RTEMS_SUCCESSFUL ) {
/* determine which event was sent */
if ( out & RTEMS_EVENT_10 ) {
/* ip up recived */
/* call disconnect function */
rtems_pppd_disconnect();
}
if ( out & RTEMS_EVENT_11 ) {
/* ip down recived */
/* sleep 10 seconds and call connect function */
rtems_task_wake_after(10*tickspersecond);
rtems_pppd_connect();
}
}
}
/* terminate myself */
rtems_task_delete(RTEMS_SELF);
}
int pppdapp_initialize(void)
{
int iReturn = (int)-1;
rtems_status_code status;
rtems_name taskName;
taskName = rtems_build_name( 'p', 'a', 'p', 'p' );
status = rtems_task_create(taskName,
CONFIGURE_INIT_TASK_PRIORITY,
CONFIGURE_INIT_TASK_STACK_SIZE,
CONFIGURE_INIT_TASK_INITIAL_MODES,
RTEMS_DEFAULT_ATTRIBUTES,
&pppdapp_taskid);
if ( status == RTEMS_SUCCESSFUL ) {
status = rtems_task_start(pppdapp_taskid, pppdapp, 0);
if ( status == RTEMS_SUCCESSFUL ) {
iReturn = (int)0;
}
}
return ( iReturn );
}

View File

@@ -0,0 +1,42 @@
#ifndef SYSTEM_H
#define SYSTEM_H
#include <rtems.h>
#include <tty_drv.h>
/* functions */
extern rtems_task Init(rtems_task_argument argument);
#include <bsp.h>
#define CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE
#ifdef CONFIGURE_INIT
rtems_driver_address_table Device_drivers[5] = {
CONSOLE_DRIVER_TABLE_ENTRY,
CLOCK_DRIVER_TABLE_ENTRY,
TTY1_DRIVER_TABLE_ENTRY,
TTY2_DRIVER_TABLE_ENTRY,
{NULL, NULL, NULL, NULL, NULL, NULL}
};
#endif
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 8
#define CONFIGURE_EXECUTIVE_RAM_SIZE (512*1024)
#define CONFIGURE_MAXIMUM_SEMAPHORES 20
#define CONFIGURE_MAXIMUM_TASKS 20
#define CONFIGURE_MICROSECONDS_PER_TICK 10000
#define CONFIGURE_INIT_TASK_STACK_SIZE (10*1024)
#define CONFIGURE_INIT_TASK_PRIORITY 120
#define CONFIGURE_INIT_TASK_INITIAL_MODES (RTEMS_PREEMPT | \
RTEMS_NO_TIMESLICE | \
RTEMS_NO_ASR | \
RTEMS_INTERRUPT_LEVEL(0))
#include <confdefs.h>
#endif

View File

@@ -17,10 +17,8 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
/* static char rcsid[] = "$Id$"; */
#endif
#define log_packet(p, len, prefix, level)
#define RCSID "$Id$"
/*
* TODO:
* Randomize fsm id on link/init.
@@ -30,11 +28,12 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <syslog.h>
#include "pppd.h"
#include "fsm.h"
static const char rcsid[] = RCSID;
static void fsm_timeout __P((void *));
static void fsm_rconfreq __P((fsm *, int, u_char *, int));
static void fsm_rconfack __P((fsm *, int, u_char *, int));
@@ -92,8 +91,7 @@ fsm_lowerup(f)
break;
default:
FSMDEBUG((LOG_INFO, "%s: Up event in state %d!",
PROTO_NAME(f), f->state));
FSMDEBUG(("%s: Up event in state %d!", PROTO_NAME(f), f->state));
}
}
@@ -138,8 +136,7 @@ fsm_lowerdown(f)
break;
default:
FSMDEBUG((LOG_INFO, "%s: Down event in state %d!",
PROTO_NAME(f), f->state));
FSMDEBUG(("%s: Down event in state %d!", PROTO_NAME(f), f->state));
}
}
@@ -260,8 +257,7 @@ fsm_timeout(arg)
case ACKRCVD:
case ACKSENT:
if (f->retransmits <= 0) {
syslog(LOG_WARNING, "%s: timeout sending Config-Requests",
PROTO_NAME(f));
warn("%s: timeout sending Config-Requests\n", PROTO_NAME(f));
f->state = STOPPED;
if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished )
(*f->callbacks->finished)(f);
@@ -277,8 +273,7 @@ fsm_timeout(arg)
break;
default:
FSMDEBUG((LOG_INFO, "%s: Timeout event in state %d!",
PROTO_NAME(f), f->state));
FSMDEBUG(("%s: Timeout event in state %d!", PROTO_NAME(f), f->state));
}
}
@@ -302,27 +297,24 @@ fsm_input(f, inpacket, l)
*/
inp = inpacket;
if (l < HEADERLEN) {
FSMDEBUG((LOG_WARNING, "fsm_input(%x): Rcvd short header.",
f->protocol));
FSMDEBUG(("fsm_input(%x): Rcvd short header.", f->protocol));
return;
}
GETCHAR(code, inp);
GETCHAR(id, inp);
GETSHORT(len, inp);
if (len < HEADERLEN) {
FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd illegal length.",
f->protocol));
FSMDEBUG(("fsm_input(%x): Rcvd illegal length.", f->protocol));
return;
}
if (len > l) {
FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd short packet.",
f->protocol));
FSMDEBUG(("fsm_input(%x): Rcvd short packet.", f->protocol));
return;
}
len -= HEADERLEN; /* subtract header length */
if( f->state == INITIAL || f->state == STARTING ){
FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd packet in state %d.",
FSMDEBUG(("fsm_input(%x): Rcvd packet in state %d.",
f->protocol, f->state));
return;
}
@@ -371,13 +363,12 @@ fsm_input(f, inpacket, l)
static void
fsm_rconfreq(f, id, inp, len)
fsm *f;
int id;
u_char id;
u_char *inp;
int len;
{
int code, reject_if_disagree;
FSMDEBUG((LOG_INFO, "fsm_rconfreq(%s): Rcvd id %d.", PROTO_NAME(f), id));
switch( f->state ){
case CLOSED:
/* Go away, we're closed */
@@ -446,17 +437,12 @@ fsm_rconfack(f, id, inp, len)
u_char *inp;
int len;
{
FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d.",
PROTO_NAME(f), id));
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 */
log_packet(inp, len, "Received bad configure-ack: ", LOG_ERR);
FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)",
PROTO_NAME(f), len));
error("Received bad configure-ack: %P", inp, len);
return;
}
f->seen_ack = 1;
@@ -511,17 +497,12 @@ fsm_rconfnakrej(f, code, id, inp, len)
int (*proc) __P((fsm *, u_char *, int));
int ret;
FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d.",
PROTO_NAME(f), id));
if (id != f->reqid || f->seen_ack) /* Expected id? */
return; /* Nope, toss... */
proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
if (!proc || !(ret = proc(f, inp, len))) {
/* Nak/reject is bad - ignore it */
log_packet(inp, len, "Received bad configure-nak/rej: ", LOG_ERR);
FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)",
PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
error("Received bad configure-nak/rej: %P", inp, len);
return;
}
f->seen_ack = 1;
@@ -570,11 +551,6 @@ fsm_rtermreq(f, id, p, len)
u_char *p;
int len;
{
char str[80];
FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d.",
PROTO_NAME(f), id));
switch (f->state) {
case ACKRCVD:
case ACKSENT:
@@ -583,10 +559,9 @@ fsm_rtermreq(f, id, p, len)
case OPENED:
if (len > 0) {
fmtmsg(str, sizeof(str), "%0.*v", len, p);
syslog(LOG_INFO, "%s terminated by peer (%s)", PROTO_NAME(f), str);
info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p);
} else
syslog(LOG_INFO, "%s terminated by peer", PROTO_NAME(f));
info("%s terminated by peer", PROTO_NAME(f));
if (f->callbacks->down)
(*f->callbacks->down)(f); /* Inform upper layers */
f->retransmits = 0;
@@ -606,8 +581,6 @@ static void
fsm_rtermack(f)
fsm *f;
{
FSMDEBUG((LOG_INFO, "fsm_rtermack(%s).", PROTO_NAME(f)));
switch (f->state) {
case CLOSING:
UNTIMEOUT(fsm_timeout, f);
@@ -646,16 +619,13 @@ fsm_rcoderej(f, inp, len)
{
u_char code, id;
FSMDEBUG((LOG_INFO, "fsm_rcoderej(%s).", PROTO_NAME(f)));
if (len < HEADERLEN) {
FSMDEBUG((LOG_INFO, "fsm_rcoderej: Rcvd short Code-Reject packet!"));
FSMDEBUG(("fsm_rcoderej: Rcvd short Code-Reject packet!"));
return;
}
GETCHAR(code, inp);
GETCHAR(id, inp);
syslog(LOG_WARNING, "%s: Rcvd Code-Reject for code %d, id %d",
PROTO_NAME(f), code, id);
warn("%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, id);
if( f->state == ACKRCVD )
f->state = REQSENT;
@@ -708,7 +678,7 @@ fsm_protreject(f)
break;
default:
FSMDEBUG((LOG_INFO, "%s: Protocol-reject event in state %d!",
FSMDEBUG(("%s: Protocol-reject event in state %d!",
PROTO_NAME(f), f->state));
}
}
@@ -759,9 +729,6 @@ fsm_sconfreq(f, retransmit)
/* start the retransmit timer */
--f->retransmits;
TIMEOUT(fsm_timeout, f, f->timeouttime);
FSMDEBUG((LOG_INFO, "%s: sending Configure-Request, id %d",
PROTO_NAME(f), f->reqid));
}
@@ -773,7 +740,7 @@ fsm_sconfreq(f, retransmit)
void
fsm_sdata(f, code, id, data, datalen)
fsm *f;
int code, id;
u_char code, id;
u_char *data;
int datalen;
{
@@ -792,7 +759,4 @@ fsm_sdata(f, code, id, data, datalen)
PUTCHAR(id, outp);
PUTSHORT(outlen, outp);
output(f->unit, outpacket_buf, outlen + PPP_HDRLEN);
FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d, id %d.",
PROTO_NAME(f), code, id));
}

View File

@@ -22,7 +22,7 @@
/*
* Packet header = Code, id, length.
*/
#define HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
#define HEADERLEN 4
/*

File diff suppressed because it is too large Load Diff

View File

@@ -43,17 +43,20 @@
/* compression option*/
typedef struct ipcp_options {
int neg_addr : 1; /* Negotiate IP Address? */
int old_addrs : 1; /* Use old (IP-Addresses) option? */
int req_addr : 1; /* Ask peer to send IP address? */
int default_route : 1; /* Assign default route through interface? */
int proxy_arp : 1; /* Make proxy ARP entry for peer? */
int neg_vj : 1; /* Van Jacobson Compression? */
int old_vj : 1; /* use old (short) form of VJ option? */
int accept_local : 1; /* accept peer's value for ouraddr */
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. */
bool neg_addr; /* Negotiate IP Address? */
bool old_addrs; /* Use old (IP-Addresses) option? */
bool req_addr; /* Ask peer to send IP address? */
bool default_route; /* Assign default route through interface? */
bool proxy_arp; /* Make proxy ARP entry for peer? */
bool neg_vj; /* Van Jacobson Compression? */
bool old_vj; /* use old (short) form of VJ option? */
bool accept_local; /* accept peer's value for ouraddr */
bool accept_remote; /* accept peer's value for hisaddr */
bool req_dns1; /* Ask peer to send primary DNS address? */
bool req_dns2; /* Ask peer to send secondary DNS address? */
int vj_protocol; /* protocol value to use in VJ option */
int maxslotindex; /* values for RFC1332 VJ compression neg. */
bool cflag;
u_int32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */
u_int32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */
u_int32_t winsaddr[2]; /* Primary and secondary MS WINS entries */

View File

@@ -18,9 +18,8 @@
*/
#ifdef IPX_CHANGE
#ifndef lint
/* static char rcsid[] = "$Id$"; */
#endif
#define RCSID "$Id$"
/*
* TODO:
@@ -28,7 +27,8 @@
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -37,6 +37,9 @@
#include "fsm.h"
#include "ipxcp.h"
#include "pathnames.h"
#include "magic.h"
static const char rcsid[] = RCSID;
/* global vars */
ipxcp_options ipxcp_wantoptions[NUM_PPP]; /* Options that we want to request */
@@ -61,7 +64,7 @@ static int ipxcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
static int ipxcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
static void ipxcp_up __P((fsm *)); /* We're UP */
static void ipxcp_down __P((fsm *)); /* We're DOWN */
static void ipxcp_script __P((fsm *, char *)); /* Run an up/down script */
static void ipxcp_finished __P((fsm *)); /* Don't need lower layer */
fsm ipxcp_fsm[NUM_PPP]; /* IPXCP fsm structure */
@@ -76,13 +79,57 @@ static fsm_callbacks ipxcp_callbacks = { /* IPXCP callback routines */
ipxcp_up, /* Called when fsm reaches OPENED state */
ipxcp_down, /* Called when fsm leaves OPENED state */
NULL, /* Called when we want the lower layer up */
NULL, /* Called when we want the lower layer down */
ipxcp_finished, /* Called when we want the lower layer down */
NULL, /* Called when Protocol-Reject received */
NULL, /* Retransmission is necessary */
NULL, /* Called to handle protocol-specific codes */
"IPXCP" /* String name of protocol */
};
/*
* Command-line options.
*/
static int setipxnode __P((char **));
static int setipxname __P((char **));
static option_t ipxcp_option_list[] = {
{ "ipx", o_bool, &ipxcp_protent.enabled_flag,
"Enable IPXCP (and IPX)", 1 },
{ "+ipx", o_bool, &ipxcp_protent.enabled_flag,
"Enable IPXCP (and IPX)", 1 },
{ "noipx", o_bool, &ipxcp_protent.enabled_flag,
"Disable IPXCP (and IPX)" },
{ "-ipx", o_bool, &ipxcp_protent.enabled_flag,
"Disable IPXCP (and IPX)" } ,
{ "ipx-network", o_uint32, &ipxcp_wantoptions[0].our_network,
"Set our IPX network number", 0, &ipxcp_wantoptions[0].neg_nn },
{ "ipxcp-accept-network", o_bool, &ipxcp_wantoptions[0].accept_network,
"Accept peer IPX network number", 1,
&ipxcp_allowoptions[0].accept_network },
{ "ipx-node", o_special, setipxnode,
"Set IPX node number" },
{ "ipxcp-accept-local", o_bool, &ipxcp_wantoptions[0].accept_local,
"Accept our IPX address", 1,
&ipxcp_allowoptions[0].accept_local },
{ "ipxcp-accept-remote", o_bool, &ipxcp_wantoptions[0].accept_remote,
"Accept peer's IPX address", 1,
&ipxcp_allowoptions[0].accept_remote },
{ "ipx-routing", o_int, &ipxcp_wantoptions[0].router,
"Set IPX routing proto number", 0,
&ipxcp_wantoptions[0].neg_router },
{ "ipx-router-name", o_special, setipxname,
"Set IPX router name" },
{ "ipxcp-restart", o_int, &ipxcp_fsm[0].timeouttime,
"Set timeout for IPXCP" },
{ "ipxcp-max-terminate", o_int, &ipxcp_fsm[0].maxtermtransmits,
"Set max #xmits for IPXCP term-reqs" },
{ "ipxcp-max-configure", o_int, &ipxcp_fsm[0].maxconfreqtransmits,
"Set max #xmits for IPXCP conf-reqs" },
{ "ipxcp-max-failure", o_int, &ipxcp_fsm[0].maxnakloops,
"Set max #conf-naks for IPXCP" },
{ NULL }
};
/*
* Protocol entry points.
*/
@@ -110,6 +157,8 @@ struct protent ipxcp_protent = {
NULL,
0,
"IPXCP",
"IPX",
ipxcp_option_list,
NULL,
NULL,
NULL
@@ -130,6 +179,10 @@ struct protent ipxcp_protent = {
#define CODENAME(x) ((x) == CONFACK ? "ACK" : \
(x) == CONFNAK ? "NAK" : "REJ")
static int ipxcp_is_up;
static char *ipx_ntoa __P((u_int32_t));
/* Used in printing the node number */
#define NODE(base) base[0], base[1], base[2], base[3], base[4], base[5]
@@ -146,7 +199,7 @@ short int internal;
{
short int external;
if (internal & IPX_NONE)
if (internal & BIT(IPX_NONE) )
external = IPX_NONE;
else
external = RIP_SAP;
@@ -158,16 +211,97 @@ short int internal;
* Make a string representation of a network IP address.
*/
char *
static char *
ipx_ntoa(ipxaddr)
u_int32_t ipxaddr;
{
static char b[64];
sprintf(b, "%x", ipxaddr);
slprintf(b, sizeof(b), "%x", ipxaddr);
return b;
}
static u_char *
setipxnodevalue(src,dst)
u_char *src, *dst;
{
int indx;
int item;
for (;;) {
if (!isxdigit (*src))
break;
for (indx = 0; indx < 5; ++indx) {
dst[indx] <<= 4;
dst[indx] |= (dst[indx + 1] >> 4) & 0x0F;
}
item = toupper (*src) - '0';
if (item > 9)
item -= 7;
dst[5] = (dst[5] << 4) | item;
++src;
}
return src;
}
static int
setipxnode(argv)
char **argv;
{
char *end;
memset (&ipxcp_wantoptions[0].our_node[0], 0, 6);
memset (&ipxcp_wantoptions[0].his_node[0], 0, 6);
end = setipxnodevalue (*argv, &ipxcp_wantoptions[0].our_node[0]);
if (*end == ':')
end = setipxnodevalue (++end, &ipxcp_wantoptions[0].his_node[0]);
if (*end == '\0') {
ipxcp_wantoptions[0].neg_node = 1;
return 1;
}
option_error("invalid parameter '%s' for ipx-node option", *argv);
return 0;
}
static int
setipxname (argv)
char **argv;
{
char *dest = ipxcp_wantoptions[0].name;
char *src = *argv;
int count;
char ch;
ipxcp_wantoptions[0].neg_name = 1;
ipxcp_allowoptions[0].neg_name = 1;
memset (dest, '\0', sizeof (ipxcp_wantoptions[0].name));
count = 0;
while (*src) {
ch = *src++;
if (! isalnum (ch) && ch != '_') {
option_error("IPX router name must be alphanumeric or _");
return 0;
}
if (count >= sizeof (ipxcp_wantoptions[0].name)) {
option_error("IPX router name is limited to %d characters",
sizeof (ipxcp_wantoptions[0].name) - 1);
return 0;
}
dest[count++] = toupper (ch);
}
return 1;
}
/*
* ipxcp_init - Initialize IPXCP.
*/
@@ -532,9 +666,8 @@ ipxcp_ackci(f, p, len)
ACKCINETWORK (IPX_NETWORK_NUMBER, go->neg_nn, go->our_network);
ACKCINODE (IPX_NODE_NUMBER, go->neg_node, go->our_node);
ACKCINAME (IPX_ROUTER_NAME, go->neg_name, go->name);
ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router);
ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router);
ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router);
if (len > 0)
ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router);
/*
* This is the end of the record.
*/
@@ -544,7 +677,7 @@ ipxcp_ackci(f, p, len)
/*
* The frame is invalid
*/
IPXCPDEBUG((LOG_INFO, "ipxcp_ackci: received bad Ack!"));
IPXCPDEBUG(("ipxcp_ackci: received bad Ack!"));
return (0);
}
@@ -588,7 +721,6 @@ ipxcp_nakci(f, p, len)
no.neg_nn = 1;
GETLONG(l, p);
IPXCPDEBUG((LOG_INFO, "local IP address %d", l));
if (l && ao->accept_network)
try.our_network = l;
break;
@@ -598,10 +730,6 @@ ipxcp_nakci(f, p, len)
goto bad;
no.neg_node = 1;
IPXCPDEBUG((LOG_INFO,
"local node number %02X%02X%02X%02X%02X%02X",
NODE(p)));
if (!zero_node (p) && ao->accept_local &&
! compare_node (p, ho->his_node))
copy_node (p, try.our_node);
@@ -629,8 +757,6 @@ ipxcp_nakci(f, p, len)
no.router |= s;
try.router |= s;
try.neg_router = 1;
IPXCPDEBUG((LOG_INFO, "Router protocol number %d", s));
break;
/* These, according to the RFC, must never be NAKed. */
@@ -645,10 +771,6 @@ ipxcp_nakci(f, p, len)
p = next;
}
/* If there is still anything left, this packet is bad. */
if (len != 0)
goto bad;
/*
* Do not permit the peer to force a router protocol which we do not
* support. However, default to the condition that will accept "NONE".
@@ -662,6 +784,7 @@ ipxcp_nakci(f, p, len)
/*
* OK, the Nak is good. Now we can update state.
* If there are any options left, we ignore them.
*/
if (f->state != OPENED)
*go = try;
@@ -669,7 +792,7 @@ ipxcp_nakci(f, p, len)
return 1;
bad:
IPXCPDEBUG((LOG_INFO, "ipxcp_nakci: received bad Nak!"));
IPXCPDEBUG(("ipxcp_nakci: received bad Nak!"));
return 0;
}
@@ -699,7 +822,6 @@ ipxcp_rejci(f, p, len)
GETLONG(cilong, p); \
if (cilong != val) \
break; \
IPXCPDEBUG((LOG_INFO,"ipxcp_rejci rejected long opt %d", opt)); \
neg = 0; \
}
@@ -721,14 +843,13 @@ ipxcp_rejci(f, p, len)
}\
if (indx != count) \
break; \
IPXCPDEBUG((LOG_INFO,"ipxcp_rejci rejected opt %d", opt)); \
neg = 0; \
}
#define REJCINODE(opt,neg,val) REJCICHARS(opt,neg,val,sizeof(val))
#define REJCINAME(opt,neg,val) REJCICHARS(opt,neg,val,strlen(val))
#define REJCIVOID(gpt, neg) \
#define REJCIVOID(opt, neg) \
if (neg && p[0] == opt) { \
if ((len -= CILEN_VOID) < 0) \
break; \
@@ -736,7 +857,6 @@ ipxcp_rejci(f, p, len)
GETCHAR(cilen, p); \
if (cilen != CILEN_VOID || citype != opt) \
break; \
IPXCPDEBUG((LOG_INFO, "ipxcp_rejci rejected void opt %d", opt)); \
neg = 0; \
}
@@ -753,7 +873,6 @@ ipxcp_rejci(f, p, len)
GETSHORT(cishort, p); \
if (cishort != to_external (val) || cishort == RIP_SAP) \
break; \
IPXCPDEBUG((LOG_INFO, "ipxcp_rejci short opt %d", opt)); \
neg = 0; \
}
/*
@@ -780,7 +899,7 @@ ipxcp_rejci(f, p, len)
/*
* The frame is invalid at this point.
*/
IPXCPDEBUG((LOG_INFO, "ipxcp_rejci: received bad Reject!"));
IPXCPDEBUG(("ipxcp_rejci: received bad Reject!"));
return 0;
}
@@ -823,7 +942,7 @@ ipxcp_reqci(f, inp, len, reject_if_disagree)
if (l < 2 || /* Not enough data for CI header or */
p[1] < 2 || /* CI length too small or */
p[1] > l) { /* CI length too big? */
IPXCPDEBUG((LOG_INFO, "ipxcp_reqci: bad CI length!"));
IPXCPDEBUG(("ipxcp_reqci: bad CI length!"));
orc = CONFREJ; /* Reject bad CI */
cilen = l; /* Reject till end of packet */
l = 0; /* Don't loop again */
@@ -839,8 +958,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree)
* The network number must match. Choose the larger of the two.
*/
case IPX_NETWORK_NUMBER:
IPXCPDEBUG((LOG_INFO, "ipxcp: received Network Number request"));
/* if we wont negotiate the network number or the length is wrong
then reject the option */
if ( !ao->neg_nn || cilen != CILEN_NETN ) {
@@ -848,7 +965,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree)
break;
}
GETLONG(cinetwork, p);
IPXCPDEBUG((LOG_INFO,"Remote proposed IPX network number is %8Lx",tl));
/* If the network numbers match then acknowledge them. */
if (cinetwork != 0) {
@@ -885,8 +1001,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree)
* The node number is required
*/
case IPX_NODE_NUMBER:
IPXCPDEBUG((LOG_INFO, "ipxcp: received Node Number request"));
/* if we wont negotiate the node number or the length is wrong
then reject the option */
if ( cilen != CILEN_NODEN ) {
@@ -944,7 +1058,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree)
* Compression is not desired at this time. It is always rejected.
*/
case IPX_COMPRESSION_PROTOCOL:
IPXCPDEBUG((LOG_INFO, "ipxcp: received Compression Protocol request "));
orc = CONFREJ;
break;
/*
@@ -959,9 +1072,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree)
}
GETSHORT (cishort, p);
IPXCPDEBUG((LOG_INFO,
"Remote router protocol number 0x%04x",
cishort));
if (wo->neg_router == 0) {
wo->neg_router = 1;
@@ -1006,7 +1116,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree)
* The router name is advisorary. Just accept it if it is not too large.
*/
case IPX_ROUTER_NAME:
IPXCPDEBUG((LOG_INFO, "ipxcp: received Router Name request"));
if (cilen >= CILEN_NAME) {
int name_size = cilen - CILEN_NAME;
if (name_size > sizeof (ho->name))
@@ -1024,7 +1133,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree)
* This is advisorary.
*/
case IPX_COMPLETE:
IPXCPDEBUG((LOG_INFO, "ipxcp: received Complete request"));
if (cilen != CILEN_COMPLETE)
orc = CONFREJ;
else {
@@ -1036,14 +1144,10 @@ ipxcp_reqci(f, inp, len, reject_if_disagree)
* All other entries are not known at this time.
*/
default:
IPXCPDEBUG((LOG_INFO, "ipxcp: received Complete request"));
orc = CONFREJ;
break;
}
endswitch:
IPXCPDEBUG((LOG_INFO, " (%s)\n", CODENAME(orc)));
if (orc == CONFACK && /* Good CI */
rc != CONFACK) /* but prior CI wasnt? */
continue; /* Don't send this one */
@@ -1099,7 +1203,7 @@ endswitch:
}
*len = ucp - inp; /* Compute output length */
IPXCPDEBUG((LOG_INFO, "ipxcp: returning Configure-%s", CODENAME(rc)));
IPXCPDEBUG(("ipxcp: returning Configure-%s", CODENAME(rc)));
return (rc); /* Return final code */
}
@@ -1115,7 +1219,7 @@ ipxcp_up(f)
{
int unit = f->unit;
IPXCPDEBUG((LOG_INFO, "ipxcp: up"));
IPXCPDEBUG(("ipxcp: up"));
/* The default router protocol is RIP/SAP. */
if (ho->router == 0)
@@ -1136,7 +1240,8 @@ ipxcp_up(f)
if (zero_node (go->our_node)) {
static char errmsg[] = "Could not determine local IPX node address";
IPXCPDEBUG((LOG_ERR, errmsg));
if (debug)
error(errmsg);
ipxcp_close(f->unit, errmsg);
return;
}
@@ -1147,31 +1252,30 @@ ipxcp_up(f)
if (go->network == 0) {
static char errmsg[] = "Can not determine network number";
IPXCPDEBUG((LOG_ERR, errmsg));
if (debug)
error(errmsg);
ipxcp_close (unit, errmsg);
return;
}
/* bring the interface up */
if (!sifup(unit)) {
IPXCPDEBUG((LOG_WARNING, "sifup failed"));
if (debug)
warn("sifup failed (IPX)");
ipxcp_close(unit, "Interface configuration failed");
return;
}
ipxcp_is_up = 1;
/* set the network number for IPX */
if (!sipxfaddr(unit, go->network, go->our_node)) {
IPXCPDEBUG((LOG_WARNING, "sipxfaddr failed"));
if (debug)
warn("sipxfaddr failed");
ipxcp_close(unit, "Interface configuration failed");
return;
}
/*
* Execute the ipx-up script, like this:
* /etc/ppp/ipx-up interface tty speed local-IPX remote-IPX
*/
ipxcp_script (f, _PATH_IPXUP);
np_up(f->unit, PPP_IPX);
}
/*
@@ -1185,83 +1289,29 @@ static void
ipxcp_down(f)
fsm *f;
{
IPXCPDEBUG((LOG_INFO, "ipxcp: down"));
IPXCPDEBUG(("ipxcp: down"));
cipxfaddr (f->unit);
if (!ipxcp_is_up)
return;
ipxcp_is_up = 0;
np_down(f->unit, PPP_IPX);
cipxfaddr(f->unit);
sifnpmode(f->unit, PPP_IPX, NPMODE_DROP);
sifdown(f->unit);
ipxcp_script (f, _PATH_IPXDOWN);
}
/*
* ipxcp_script - Execute a script with arguments
* interface-name tty-name speed local-IPX remote-IPX networks.
* ipxcp_finished - possibly shut down the lower layers.
*/
static void
ipxcp_script(f, script)
ipxcp_finished(f)
fsm *f;
char *script;
{
char strspeed[32], strlocal[32], strremote[32];
char strnetwork[32], strpid[32];
char *argv[14], strproto_lcl[32], strproto_rmt[32];
sprintf (strpid, "%d", getpid());
sprintf (strspeed, "%d", baud_rate);
strproto_lcl[0] = '\0';
if (go->neg_router && ((go->router & BIT(IPX_NONE)) == 0)) {
if (go->router & BIT(RIP_SAP))
strcpy (strproto_lcl, "RIP ");
if (go->router & BIT(NLSP))
strcat (strproto_lcl, "NLSP ");
}
if (strproto_lcl[0] == '\0')
strcpy (strproto_lcl, "NONE ");
strproto_lcl[strlen (strproto_lcl)-1] = '\0';
strproto_rmt[0] = '\0';
if (ho->neg_router && ((ho->router & BIT(IPX_NONE)) == 0)) {
if (ho->router & BIT(RIP_SAP))
strcpy (strproto_rmt, "RIP ");
if (ho->router & BIT(NLSP))
strcat (strproto_rmt, "NLSP ");
}
if (strproto_rmt[0] == '\0')
strcpy (strproto_rmt, "NONE ");
strproto_rmt[strlen (strproto_rmt)-1] = '\0';
strcpy (strnetwork, ipx_ntoa (go->network));
sprintf (strlocal,
"%02X%02X%02X%02X%02X%02X",
NODE(go->our_node));
sprintf (strremote,
"%02X%02X%02X%02X%02X%02X",
NODE(ho->his_node));
argv[0] = script;
argv[1] = ifname;
argv[2] = devnam;
argv[3] = strspeed;
argv[4] = strnetwork;
argv[5] = strlocal;
argv[6] = strremote;
argv[7] = strproto_lcl;
argv[8] = strproto_rmt;
argv[9] = go->name;
argv[10] = ho->name;
argv[11] = ipparam;
argv[12] = strpid;
argv[13] = NULL;
run_program(script, argv, 0);
np_finished(f->unit, PPP_IPX);
}
/*
* ipxcp_printpkt - print the contents of an IPXCP packet.
*/

View File

@@ -35,22 +35,22 @@
#define NLSP 4
typedef struct ipxcp_options {
int neg_node : 1; /* Negotiate IPX node number? */
int req_node : 1; /* Ask peer to send IPX node number? */
bool neg_node; /* Negotiate IPX node number? */
bool req_node; /* Ask peer to send IPX node number? */
int neg_nn : 1; /* Negotiate IPX network number? */
int req_nn : 1; /* Ask peer to send IPX network number */
bool neg_nn; /* Negotiate IPX network number? */
bool req_nn; /* Ask peer to send IPX network number */
int neg_name : 1; /* Negotiate IPX router name */
int neg_complete : 1; /* Negotiate completion */
int neg_router : 1; /* Negotiate IPX router number */
bool neg_name; /* Negotiate IPX router name */
bool neg_complete; /* Negotiate completion */
bool neg_router; /* Negotiate IPX router number */
int accept_local : 1; /* accept peer's value for ournode */
int accept_remote : 1; /* accept peer's value for hisnode */
int accept_network : 1; /* accept network number */
bool accept_local; /* accept peer's value for ournode */
bool accept_remote; /* accept peer's value for hisnode */
bool accept_network; /* accept network number */
int tried_nlsp : 1; /* I have suggested NLSP already */
int tried_rip : 1; /* I have suggested RIP/SAP already */
bool tried_nlsp; /* I have suggested NLSP already */
bool tried_rip; /* I have suggested RIP/SAP already */
u_int32_t his_network; /* base network number */
u_int32_t our_network; /* our value for network number */

View File

@@ -17,9 +17,7 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
/* static char rcsid[] = "$Id$"; */
#endif
#define RCSID "$Id$";
/*
* TODO:
@@ -27,13 +25,7 @@
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <assert.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <stdlib.h>
#include "pppd.h"
#include "fsm.h"
@@ -41,6 +33,83 @@
#include "chap.h"
#include "magic.h"
static const char rcsid[] = RCSID;
/*
* LCP-related command-line options.
*/
int lcp_echo_interval = 0; /* Interval between LCP echo-requests */
int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */
bool lax_recv = 0; /* accept control chars in asyncmap */
static int setescape __P((char **));
static option_t lcp_option_list[] = {
/* LCP options */
{ "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression,
"Disable address/control compression",
OPT_A2COPY, &lcp_allowoptions[0].neg_accompression },
{ "-ac", o_bool, &lcp_wantoptions[0].neg_accompression,
"Disable address/control compression",
OPT_A2COPY, &lcp_allowoptions[0].neg_accompression },
{ "default-asyncmap", o_bool, &lcp_wantoptions[0].neg_asyncmap,
"Disable asyncmap negotiation",
OPT_A2COPY, &lcp_allowoptions[0].neg_asyncmap },
{ "-am", o_bool, &lcp_wantoptions[0].neg_asyncmap,
"Disable asyncmap negotiation",
OPT_A2COPY, &lcp_allowoptions[0].neg_asyncmap },
{ "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
"Set asyncmap (for received packets)",
OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
{ "-as", o_uint32, &lcp_wantoptions[0].asyncmap,
"Set asyncmap (for received packets)",
OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
{ "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber,
"Disable magic number negotiation (looped-back line detection)",
OPT_A2COPY, &lcp_allowoptions[0].neg_magicnumber },
{ "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber,
"Disable magic number negotiation (looped-back line detection)",
OPT_A2COPY, &lcp_allowoptions[0].neg_magicnumber },
{ "default-mru", o_bool, &lcp_wantoptions[0].neg_mru,
"Disable MRU negotiation (use default 1500)",
OPT_A2COPY, &lcp_allowoptions[0].neg_mru },
{ "-mru", o_bool, &lcp_wantoptions[0].neg_mru,
"Disable MRU negotiation (use default 1500)",
OPT_A2COPY, &lcp_allowoptions[0].neg_mru },
{ "mru", o_int, &lcp_wantoptions[0].mru,
"Set MRU (maximum received packet size) for negotiation",
0, &lcp_wantoptions[0].neg_mru },
{ "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression,
"Disable protocol field compression",
OPT_A2COPY, &lcp_allowoptions[0].neg_pcompression },
{ "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression,
"Disable protocol field compression",
OPT_A2COPY, &lcp_allowoptions[0].neg_pcompression },
{ "-p", o_bool, &lcp_wantoptions[0].passive,
"Set passive mode", 1 },
{ "passive", o_bool, &lcp_wantoptions[0].passive,
"Set passive mode", 1 },
{ "silent", o_bool, &lcp_wantoptions[0].silent,
"Set silent mode", 1 },
{ "escape", o_special, setescape,
"List of character codes to escape on transmission" },
{ "lcp-echo-failure", o_int, &lcp_echo_fails,
"Set number of consecutive echo failures to indicate link failure" },
{ "lcp-echo-interval", o_int, &lcp_echo_interval,
"Set time in seconds between LCP echo requests" },
{ "lcp-restart", o_int, &lcp_fsm[0].timeouttime,
"Set time in seconds between LCP retransmissions" },
{ "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits,
"Set maximum number of LCP terminate-request transmissions" },
{ "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits,
"Set maximum number of LCP configure-request transmissions" },
{ "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops,
"Set limit on number of LCP configure-naks" },
{ "receive-all", o_bool, &lax_recv,
"Accept all received control characters", 1 },
{NULL}
};
/* global vars */
fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/
lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */
@@ -49,9 +118,9 @@ 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_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 */
static int lcp_echos_pending = 0; /* Number of outstanding echo msgs */
static int lcp_echo_number = 0; /* ID number of next echo frame */
static int lcp_echo_timer_running = 0; /* set if a timer is running */
static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */
@@ -127,6 +196,8 @@ struct protent lcp_protent = {
1,
"LCP",
NULL,
lcp_option_list,
NULL,
NULL,
NULL
};
@@ -138,16 +209,47 @@ int lcp_loopbackfail = DEFLOOPBACKFAIL;
*/
#define CILEN_VOID 2
#define CILEN_CHAR 3
#define CILEN_SHORT 4 /* CILEN_VOID + sizeof(short) */
#define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */
#define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */
#define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */
#define CILEN_SHORT 4 /* CILEN_VOID + 2 */
#define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */
#define CILEN_LONG 6 /* CILEN_VOID + 4 */
#define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */
#define CILEN_CBCP 3
#define CODENAME(x) ((x) == CONFACK ? "ACK" : \
(x) == CONFNAK ? "NAK" : "REJ")
/*
* setescape - add chars to the set we escape on transmission.
*/
static int
setescape(argv)
char **argv;
{
int n, ret;
char *p, *endp;
p = *argv;
ret = 1;
while (*p) {
n = strtol(p, &endp, 16);
if (p == endp) {
option_error("escape parameter contains invalid hex number '%s'",
p);
return 0;
}
p = endp;
if (n < 0 || n == 0x5E || n > 0xFF) {
option_error("can't escape character 0x%x", n);
ret = 0;
} else
xmit_accm[0][n >> 5] |= 1 << (n & 0x1F);
while (*p == ',' || *p == ' ')
++p;
}
return ret;
}
/*
* lcp_init - Initialize LCP.
*/
@@ -171,7 +273,7 @@ lcp_init(unit)
implementations */
wo->neg_mru = 1;
wo->mru = DEFMRU;
wo->neg_asyncmap = 0;
wo->neg_asyncmap = 1;
wo->asyncmap = 0;
wo->neg_chap = 0; /* Set to 1 on server */
wo->neg_upap = 0; /* Set to 1 on server */
@@ -234,7 +336,7 @@ lcp_close(unit, reason)
fsm *f = &lcp_fsm[unit];
if (phase != PHASE_DEAD)
phase = PHASE_TERMINATE;
new_phase(PHASE_TERMINATE);
if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
/*
* This action is not strictly according to the FSM in RFC1548,
@@ -266,7 +368,7 @@ lcp_lowerup(unit)
*/
ppp_set_xaccm(unit, xmit_accm[unit]);
ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0);
ppp_recv_config(unit, PPP_MRU, 0xffffffff,
ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff),
wo->neg_pcompression, wo->neg_accompression);
peer_mru[unit] = PPP_MRU;
lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0];
@@ -321,7 +423,6 @@ lcp_extcode(f, code, id, inp, len)
case ECHOREQ:
if (f->state != OPENED)
break;
LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d", id));
magp = inp;
PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
fsm_sdata(f, ECHOREP, id, inp, len);
@@ -356,27 +457,19 @@ lcp_rprotrej(f, inp, len)
struct protent *protp;
u_short prot;
LCPDEBUG((LOG_INFO, "lcp_rprotrej."));
if (len < sizeof (u_short)) {
LCPDEBUG((LOG_INFO,
"lcp_rprotrej: Rcvd short Protocol-Reject packet!"));
if (len < 2) {
LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!"));
return;
}
GETSHORT(prot, inp);
LCPDEBUG((LOG_INFO,
"lcp_rprotrej: Rcvd Protocol-Reject packet for %x!",
prot));
/*
* Protocol-Reject packets received in any state other than the LCP
* OPENED state SHOULD be silently discarded.
*/
if( f->state != OPENED ){
LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d",
f->state));
LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state));
return;
}
@@ -389,8 +482,7 @@ lcp_rprotrej(f, inp, len)
return;
}
syslog(LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%x",
prot);
warn("Protocol-Reject for unsupported protocol 0x%x", prot);
}
@@ -405,8 +497,7 @@ lcp_protrej(unit)
/*
* Can't reject LCP!
*/
LCPDEBUG((LOG_WARNING,
"lcp_protrej: Received Protocol-Reject for LCP!"));
error("Received Protocol-Reject for LCP!");
fsm_protreject(&lcp_fsm[unit]);
}
@@ -541,8 +632,7 @@ lcp_addci(f, ucp, lenp)
if (ucp - start_ucp != *lenp) {
/* this should never happen, because peer_mtu should be 1500 */
syslog(LOG_ERR, "Bug in lcp_addci: wrong length")
;
error("Bug in lcp_addci: wrong length");
}
}
@@ -671,7 +761,7 @@ lcp_ackci(f, p, len)
goto bad;
return (1);
bad:
LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!"));
LCPDEBUG(("lcp_acki: received bad Ack!"));
return (0);
}
@@ -829,11 +919,18 @@ lcp_nakci(f, p, len)
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
* algorithm. If they can't do MD5, we can ask for M$-CHAP
* if we support it, otherwise we'll have to stop
* asking for CHAP.
*/
if (cichar != go->chap_mdtype)
try.neg_chap = 0;
if (cichar != go->chap_mdtype) {
#ifdef CHAPMS
if (cichar == CHAP_MICROSOFT)
go->chap_mdtype = CHAP_MICROSOFT;
else
#endif /* CHAPMS */
try.neg_chap = 0;
}
} else {
/*
* Stop asking for PAP if we were asking for it.
@@ -957,18 +1054,16 @@ lcp_nakci(f, p, len)
p = next;
}
/* If there is still anything left, this packet is bad. */
if (len != 0)
goto bad;
/*
* OK, the Nak is good. Now we can update state.
* If there are any options left we ignore them.
*/
if (f->state != OPENED) {
if (looped_back) {
if (++try.numloops >= lcp_loopbackfail) {
syslog(LOG_NOTICE, "Serial line is looped back.");
notice("Serial line is looped back.");
lcp_close(f->unit, "Loopback detected");
status = EXIT_LOOPBACK;
}
} else
try.numloops = 0;
@@ -978,7 +1073,7 @@ lcp_nakci(f, p, len)
return 1;
bad:
LCPDEBUG((LOG_WARNING, "lcp_nakci: received bad Nak!"));
LCPDEBUG(("lcp_nakci: received bad Nak!"));
return 0;
}
@@ -1019,7 +1114,6 @@ lcp_rejci(f, p, len)
len -= CILEN_VOID; \
INCPTR(CILEN_VOID, p); \
try.neg = 0; \
LCPDEBUG((LOG_INFO, "lcp_rejci rejected void opt %d", opt)); \
}
#define REJCISHORT(opt, neg, val) \
if (go->neg && \
@@ -1033,7 +1127,6 @@ lcp_rejci(f, p, len)
if (cishort != val) \
goto bad; \
try.neg = 0; \
LCPDEBUG((LOG_INFO,"lcp_rejci rejected short opt %d", opt)); \
}
#define REJCICHAP(opt, neg, val, digest) \
if (go->neg && \
@@ -1049,7 +1142,6 @@ lcp_rejci(f, p, len)
goto bad; \
try.neg = 0; \
try.neg_upap = 0; \
LCPDEBUG((LOG_INFO,"lcp_rejci rejected chap opt %d", opt)); \
}
#define REJCILONG(opt, neg, val) \
if (go->neg && \
@@ -1063,7 +1155,6 @@ lcp_rejci(f, p, len)
if (cilong != val) \
goto bad; \
try.neg = 0; \
LCPDEBUG((LOG_INFO,"lcp_rejci rejected long opt %d", opt)); \
}
#define REJCILQR(opt, neg, val) \
if (go->neg && \
@@ -1078,7 +1169,6 @@ lcp_rejci(f, p, len)
if (cishort != PPP_LQR || cilong != val) \
goto bad; \
try.neg = 0; \
LCPDEBUG((LOG_INFO,"lcp_rejci rejected LQR opt %d", opt)); \
}
#define REJCICBCP(opt, neg, val) \
if (go->neg && \
@@ -1092,7 +1182,6 @@ lcp_rejci(f, p, len)
if (cichar != val) \
goto bad; \
try.neg = 0; \
LCPDEBUG((LOG_INFO,"lcp_rejci rejected Callback opt %d", opt)); \
}
REJCISHORT(CI_MRU, neg_mru, go->mru);
@@ -1120,7 +1209,7 @@ lcp_rejci(f, p, len)
return 1;
bad:
LCPDEBUG((LOG_WARNING, "lcp_rejci: received bad Reject!"));
LCPDEBUG(("lcp_rejci: received bad Reject!"));
return 0;
}
@@ -1170,7 +1259,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
if (l < 2 || /* Not enough data for CI header or */
p[1] < 2 || /* CI length too small or */
p[1] > l) { /* CI length too big? */
LCPDEBUG((LOG_WARNING, "lcp_reqci: bad CI length!"));
LCPDEBUG(("lcp_reqci: bad CI length!"));
orc = CONFREJ; /* Reject bad CI */
cilen = l; /* Reject till end of packet */
l = 0; /* Don't loop again */
@@ -1184,14 +1273,12 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
switch (citype) { /* Check CI type */
case CI_MRU:
LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MRU"));
if (!ao->neg_mru || /* Allow option? */
cilen != CILEN_SHORT) { /* Check CI length */
orc = CONFREJ; /* Reject CI */
break;
}
GETSHORT(cishort, p); /* Parse MRU */
LCPDEBUG((LOG_INFO, "(%d)", cishort));
/*
* He must be able to receive at least our minimum.
@@ -1210,14 +1297,12 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
break;
case CI_ASYNCMAP:
LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ASYNCMAP"));
if (!ao->neg_asyncmap ||
cilen != CILEN_LONG) {
orc = CONFREJ;
break;
}
GETLONG(cilong, p);
LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong));
/*
* Asyncmap must have set at least the bits
@@ -1235,7 +1320,6 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
break;
case CI_AUTHTYPE:
LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd AUTHTYPE"));
if (cilen < CILEN_SHORT ||
!(ao->neg_upap || ao->neg_chap)) {
/*
@@ -1245,10 +1329,9 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
break;
}
GETSHORT(cishort, p);
LCPDEBUG((LOG_INFO, "(%x)", cishort));
/*
* Authtype must be UPAP or CHAP.
* Authtype must be PAP or CHAP.
*
* Note: if both ao->neg_upap and ao->neg_chap are set,
* and the peer sends a Configure-Request with two
@@ -1261,8 +1344,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
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..."));
LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
orc = CONFREJ;
break;
}
@@ -1272,6 +1354,8 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
PUTCHAR(CILEN_CHAP, nakp);
PUTSHORT(PPP_CHAP, nakp);
PUTCHAR(ao->chap_mdtype, nakp);
/* XXX if we can do CHAP_MICROSOFT as well, we should
probably put in another option saying so */
break;
}
ho->neg_upap = 1;
@@ -1280,8 +1364,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
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..."));
LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
orc = CONFREJ;
break;
}
@@ -1328,7 +1411,6 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
break;
case CI_QUALITY:
LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd QUALITY"));
if (!ao->neg_lqr ||
cilen != CILEN_LQR) {
orc = CONFREJ;
@@ -1337,7 +1419,6 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
GETSHORT(cishort, p);
GETLONG(cilong, p);
LCPDEBUG((LOG_INFO, "(%x %x)", cishort, (unsigned int) cilong));
/*
* Check the protocol and the reporting period.
@@ -1354,14 +1435,12 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
break;
case CI_MAGICNUMBER:
LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MAGICNUMBER"));
if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
cilen != CILEN_LONG) {
orc = CONFREJ;
break;
}
GETLONG(cilong, p);
LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong));
/*
* He must have a different magic number.
@@ -1381,7 +1460,6 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
case CI_PCOMPRESSION:
LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd PCOMPRESSION"));
if (!ao->neg_pcompression ||
cilen != CILEN_VOID) {
orc = CONFREJ;
@@ -1391,7 +1469,6 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
break;
case CI_ACCOMPRESSION:
LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ACCOMPRESSION"));
if (!ao->neg_accompression ||
cilen != CILEN_VOID) {
orc = CONFREJ;
@@ -1401,14 +1478,12 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
break;
default:
LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd unknown option %d",
citype));
LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype));
orc = CONFREJ;
break;
}
endswitch:
LCPDEBUG((LOG_INFO, " (%s)", CODENAME(orc)));
if (orc == CONFACK && /* Good CI */
rc != CONFACK) /* but prior CI wasnt? */
continue; /* Don't send this one */
@@ -1454,7 +1529,7 @@ endswitch:
break;
}
LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.", CODENAME(rc)));
LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc)));
return (rc); /* Return final code */
}
@@ -1486,7 +1561,7 @@ lcp_up(f)
(ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
ho->neg_pcompression, ho->neg_accompression);
ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU),
(go->neg_asyncmap? go->asyncmap: 0xffffffff),
(lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff),
go->neg_pcompression, go->neg_accompression);
if (ho->neg_mru)
@@ -1584,7 +1659,7 @@ lcp_printpkt(p, plen, printer, arg)
case CONFACK:
case CONFNAK:
case CONFREJ:
/* print option list */
while (len >= 2) {
GETCHAR(code, p);
GETCHAR(olen, p);
@@ -1621,6 +1696,20 @@ lcp_printpkt(p, plen, printer, arg)
break;
case PPP_CHAP:
printer(arg, "chap");
if (p < optend) {
switch (*p) {
case CHAP_DIGEST_MD5:
printer(arg, " MD5");
++p;
break;
#ifdef CHAPMS
case CHAP_MICROSOFT:
printer(arg, " m$oft");
++p;
break;
#endif
}
}
break;
default:
printer(arg, "0x%x", cishort);
@@ -1645,7 +1734,7 @@ lcp_printpkt(p, plen, printer, arg)
if (olen >= CILEN_CHAR) {
p += 2;
printer(arg, "callback ");
GETSHORT(cishort, p);
GETCHAR(cishort, p);
switch (cishort) {
case CBCP_OPT:
printer(arg, "CBCP");
@@ -1705,7 +1794,7 @@ lcp_printpkt(p, plen, printer, arg)
break;
}
/* print the rest of the bytes in the packet */
for (; len > 0; --len) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
@@ -1723,9 +1812,10 @@ void LcpLinkFailure (f)
fsm *f;
{
if (f->state == OPENED) {
syslog(LOG_INFO, "No response to %d echo-requests", lcp_echos_pending);
syslog(LOG_NOTICE, "Serial link appears to be disconnected.");
info("No response to %d echo-requests", lcp_echos_pending);
notice("Serial link appears to be disconnected.");
lcp_close(f->unit, "Peer not responding");
status = EXIT_PEER_DEAD;
}
}
@@ -1738,11 +1828,14 @@ LcpEchoCheck (f)
fsm *f;
{
LcpSendEchoRequest (f);
if (f->state != OPENED)
return;
/*
* Start the timer for the next interval.
*/
assert (lcp_echo_timer_running==0);
if (lcp_echo_timer_running)
warn("assertion lcp_echo_timer_running==0 failed");
TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
lcp_echo_timer_running = 1;
}
@@ -1768,19 +1861,21 @@ LcpEchoTimeout (arg)
static void
lcp_received_echo_reply (f, id, inp, len)
fsm *f;
int id; u_char *inp; int len;
int id;
u_char *inp;
int len;
{
u_int32_t magic;
/* Check the magic number - don't count replies from ourselves. */
if (len < 4) {
syslog(LOG_DEBUG, "lcp: received short Echo-Reply, length %d", len);
dbglog("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) {
syslog(LOG_WARNING, "appear to have received our own echo-reply!");
warn("appear to have received our own echo-reply!");
return;
}

View File

@@ -44,19 +44,19 @@
* The state of options is described by an lcp_options structure.
*/
typedef struct lcp_options {
int passive : 1; /* Don't die if we don't get a response */
int silent : 1; /* Wait for the other end to start first */
int restart : 1; /* Restart vs. exit after close */
int neg_mru : 1; /* Negotiate the MRU? */
int neg_asyncmap : 1; /* Negotiate the async map? */
int neg_upap : 1; /* Ask for UPAP authentication? */
int neg_chap : 1; /* Ask for CHAP authentication? */
int neg_magicnumber : 1; /* Ask for magic number? */
int neg_pcompression : 1; /* HDLC Protocol Field Compression? */
int neg_accompression : 1; /* HDLC Address/Control Field Compression? */
int neg_lqr : 1; /* Negotiate use of Link Quality Reports */
int neg_cbcp : 1; /* Negotiate use of CBCP */
u_short mru; /* Value of MRU */
bool passive; /* Don't die if we don't get a response */
bool silent; /* Wait for the other end to start first */
bool restart; /* Restart vs. exit after close */
bool neg_mru; /* Negotiate the MRU? */
bool neg_asyncmap; /* Negotiate the async map? */
bool neg_upap; /* Ask for UPAP authentication? */
bool neg_chap; /* Ask for CHAP authentication? */
bool neg_magicnumber; /* Ask for magic number? */
bool neg_pcompression; /* HDLC Protocol Field Compression? */
bool neg_accompression; /* HDLC Address/Control Field Compression? */
bool neg_lqr; /* Negotiate use of Link Quality Reports */
bool neg_cbcp; /* Negotiate use of CBCP */
int mru; /* Value of MRU */
u_char chap_mdtype; /* which MD type (hashing algorithm) */
u_int32_t asyncmap; /* Value of async map */
u_int32_t magicnumber;

View File

@@ -17,19 +17,19 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
/* static char rcsid[] = "$Id$"; */
#endif
#define RCSID "$Id$"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include "pppd.h"
#include "magic.h"
static const char rcsid[] = RCSID;
extern long mrand48 __P((void));
extern void srand48 __P((long));
@@ -64,7 +64,7 @@ magic()
* Substitute procedures for those systems which don't have
* drand48 et al.
*/
/* #include <stdlib.h> */
double
drand48()
{
@@ -83,4 +83,3 @@ long seedval;
{
srand((int)seedval);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* $Id$ */
#define PATCHLEVEL 5
#define PATCHLEVEL 11
#define VERSION "2.3"
#define IMPLEMENTATION ""
#define DATE "4 May 1998"
#define DATE "23 December 1999"

View File

@@ -8,23 +8,36 @@
#include <paths.h>
#else
#ifndef _PATH_VARRUN
#define _PATH_VARRUN "/etc/ppp/"
#endif
#define _PATH_DEVNULL "/dev/null"
#endif
#define _PATH_UPAPFILE "/etc/ppp/pap-secrets"
#define _PATH_CHAPFILE "/etc/ppp/chap-secrets"
#define _PATH_SYSOPTIONS "/etc/ppp/options"
#define _PATH_IPUP "/etc/ppp/ip-up"
#define _PATH_IPDOWN "/etc/ppp/ip-down"
#define _PATH_AUTHUP "/etc/ppp/auth-up"
#define _PATH_AUTHDOWN "/etc/ppp/auth-down"
#define _PATH_TTYOPT "/etc/ppp/options."
#define _PATH_CONNERRS "/etc/ppp/connect-errors"
#define _PATH_USEROPT ".ppprc"
#define _PATH_PEERFILES "/etc/ppp/peers/"
#ifndef _ROOT_PATH
#define _ROOT_PATH
#endif
#define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets"
#define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets"
#define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options"
#define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up"
#define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down"
#define _PATH_AUTHUP _ROOT_PATH "/etc/ppp/auth-up"
#define _PATH_AUTHDOWN _ROOT_PATH "/etc/ppp/auth-down"
#define _PATH_TTYOPT _ROOT_PATH "/etc/ppp/options."
#define _PATH_CONNERRS _ROOT_PATH "/etc/ppp/connect-errors"
#define _PATH_PEERFILES _ROOT_PATH "/etc/ppp/peers/"
#define _PATH_RESOLV _ROOT_PATH "/etc/ppp/resolv.conf"
#define _PATH_USEROPT ".ppprc"
#ifdef INET6
#define _PATH_IPV6UP _ROOT_PATH "/etc/ppp/ipv6-up"
#define _PATH_IPV6DOWN _ROOT_PATH "/etc/ppp/ipv6-down"
#endif
#ifdef IPX_CHANGE
#define _PATH_IPXUP "/etc/ppp/ipx-up"
#define _PATH_IPXDOWN "/etc/ppp/ipx-down"
#define _PATH_IPXUP _ROOT_PATH "/etc/ppp/ipx-up"
#define _PATH_IPXDOWN _ROOT_PATH "/etc/ppp/ipx-down"
#endif /* IPX_CHANGE */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -26,20 +26,25 @@
#ifndef __PPPD_H__
#define __PPPD_H__
#include <rtems.h>
#include <stdio.h> /* for FILE */
#include <limits.h> /* for NGROUPS_MAX */
#include <sys/param.h> /* for MAXPATHLEN and BSD4_4, if defined */
#include <sys/types.h> /* for u_int32_t, if defined */
#include <sys/time.h> /* for struct timeval */
#include <net/ppp_defs.h>
#if __STDC__
#if defined(__STDC__)
#include <stdarg.h>
#define __V(x) x
#else
#include <varargs.h>
#define __V(x) (va_alist) va_dcl
#define const
#define volatile
#endif
#ifdef INET6
#include "eui64.h"
#endif
/*
@@ -52,12 +57,92 @@
#define MAXNAMELEN 256 /* max length of hostname or name for auth */
#define MAXSECRETLEN 256 /* max length of password or secret */
/*
* Option descriptor structure.
*/
typedef unsigned char bool;
enum opt_type {
o_special_noarg = 0,
o_special = 1,
o_bool,
o_int,
o_uint32,
o_string,
};
typedef struct {
char *name; /* name of the option */
enum opt_type type;
void *addr;
char *description;
int flags;
void *addr2;
int upper_limit;
int lower_limit;
} option_t;
/* Values for flags */
#define OPT_VALUE 0xff /* mask for presupplied value */
#define OPT_HEX 0x100 /* int option is in hex */
#define OPT_NOARG 0x200 /* option doesn't take argument */
#define OPT_OR 0x400 /* OR in argument to value */
#define OPT_INC 0x800 /* increment value */
#define OPT_PRIV 0x1000 /* privileged option */
#define OPT_STATIC 0x2000 /* string option goes into static array */
#define OPT_LLIMIT 0x4000 /* check value against lower limit */
#define OPT_ULIMIT 0x8000 /* check value against upper limit */
#define OPT_LIMITS (OPT_LLIMIT|OPT_ULIMIT)
#define OPT_ZEROOK 0x10000 /* 0 value is OK even if not within limits */
#define OPT_NOINCR 0x20000 /* value mustn't be increased */
#define OPT_ZEROINF 0x40000 /* with OPT_NOINCR, 0 == infinity */
#define OPT_A2INFO 0x100000 /* addr2 -> option_info to update */
#define OPT_A2COPY 0x200000 /* addr2 -> second location to rcv value */
#define OPT_ENABLE 0x400000 /* use *addr2 as enable for option */
#define OPT_PRIVFIX 0x800000 /* can't be overridden if noauth */
#define OPT_PREPASS 0x1000000 /* do this opt in pre-pass to find device */
#define OPT_INITONLY 0x2000000 /* option can only be set in init phase */
#define OPT_DEVEQUIV 0x4000000 /* equiv to device name */
#define OPT_DEVNAM (OPT_PREPASS | OPT_INITONLY | OPT_DEVEQUIV)
#define OPT_VAL(x) ((x) & OPT_VALUE)
#ifndef GIDSET_TYPE
#define GIDSET_TYPE gid_t
#endif
/* Structure representing a list of permitted IP addresses. */
struct permitted_ip {
int permit; /* 1 = permit, 0 = forbid */
u_int32_t base; /* match if (addr & mask) == base */
u_int32_t mask; /* base and mask are in network byte order */
};
/*
* Unfortunately, the linux kernel driver uses a different structure
* for statistics from the rest of the ports.
* This structure serves as a common representation for the bits
* pppd needs.
*/
struct pppd_stats {
unsigned int bytes_in;
unsigned int bytes_out;
};
/* Used for storing a sequence of words. Usually malloced. */
struct wordlist {
struct wordlist *next;
char *word;
};
/*
* Global variables.
*/
extern int kill_link; /* Signal to terminate processing loop */
extern int hungup; /* Physical layer has disconnected */
extern int interfunit; /* Interface unit number */
extern int pppifunit; /* Interface unit number */
extern char ifname[]; /* Interface name */
extern int ttyfd; /* Serial device file descriptor */
extern char hostname[]; /* Our hostname */
@@ -71,6 +156,21 @@ extern int privileged; /* We were run by real-uid root */
extern int need_holdoff; /* Need holdoff period after link terminates */
extern char **script_env; /* Environment variables for scripts */
extern int detached; /* Have detached from controlling tty */
extern GIDSET_TYPE groups[NGROUPS_MAX]; /* groups the user is in */
extern int ngroups; /* How many groups valid in groups */
extern struct pppd_stats link_stats; /* byte/packet counts etc. for link */
extern int using_pty; /* using pty as device (notty or pty opt.) */
extern int log_to_fd; /* logging to this fd as well as syslog */
extern char *no_ppp_msg; /* message to print if ppp not in kernel */
extern volatile int status; /* exit status for pppd */
extern int devnam_fixed; /* can no longer change devnam */
extern int unsuccess; /* # unsuccessful connection attempts */
extern int do_callback; /* set if we want to do callback next */
extern int doing_callback; /* set if this is a callback */
/* Values for do_callback and doing_callback */
#define CALLBACK_DIALIN 1 /* we are expecting the call back */
#define CALLBACK_DIALOUT 2 /* we are dialling out to call back */
/*
* Variables set by command-line options.
@@ -79,60 +179,71 @@ extern int detached; /* Have detached from controlling tty */
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 char devnam[MAXPATHLEN]; /* Device name */
extern int crtscts; /* Use hardware flow control */
extern int modem; /* Use modem control lines */
extern bool 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 **welcomer; /* Script to welcome client after connection */
extern bool lockflag; /* Create lock file to lock the serial dev */
extern bool nodetach; /* Don't detach from controlling tty */
extern bool updetach; /* Detach from controlling tty when link up */
extern char *initializer; /* Script to initialize physical link */
extern char *connect_script; /* Script to establish physical link */
extern char *disconnect_script; /* Script to disestablish physical link */
extern char *welcomer; /* Script to welcome client after connection */
extern char *ptycommand; /* Command to run on other side of pty */
extern int maxconnect; /* Maximum connect time (seconds) */
extern char user[]; /* Our name for authenticating ourselves */
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 explicit_remote;/* remote_name specified with remotename opt */
extern int usehostname; /* Use hostname for our_name */
extern int disable_defaultip; /* Don't use hostname for default IP adrs */
extern int demand; /* Do dial-on-demand */
extern char user[MAXNAMELEN];/* Our name for authenticating ourselves */
extern char passwd[MAXSECRETLEN]; /* Password for PAP or CHAP */
extern bool auth_required; /* Peer is required to authenticate */
extern bool persist; /* Reopen link after it goes down */
extern bool uselogin; /* Use /etc/passwd for checking PAP */
extern char our_name[MAXNAMELEN];/* Our name for authentication purposes */
extern char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
extern bool explicit_remote;/* remote_name specified with remotename opt */
extern bool demand; /* Do dial-on-demand */
extern char *ipparam; /* Extra parameter for ip up/down scripts */
extern int cryptpap; /* Others' PAP passwords are encrypted */
extern bool cryptpap; /* Others' PAP passwords are encrypted */
extern int idle_time_limit;/* Shut down link if idle for this long */
extern int holdoff; /* Dead time before restarting */
extern int refuse_pap; /* Don't wanna auth. ourselves with PAP */
extern int refuse_chap; /* Don't wanna auth. ourselves with CHAP */
extern bool holdoff_specified; /* true if user gave a holdoff value */
extern bool notty; /* Stdin/out is not a tty */
extern char *record_file; /* File to record chars sent/received */
extern bool sync_serial; /* Device is synchronous serial device */
extern int maxfail; /* Max # of unsuccessful connection attempts */
extern char linkname[MAXPATHLEN]; /* logical name for link */
extern bool tune_kernel; /* May alter kernel settings as necessary */
extern int connect_delay; /* Time to delay after connect script */
#ifdef PPP_FILTER
extern struct bpf_program pass_filter; /* Filter for pkts to pass */
extern struct bpf_program active_filter; /* Filter for link-active pkts */
#endif
#ifdef MSLANMAN
extern int ms_lanman; /* Nonzero if use LanMan password instead of NT */
extern bool ms_lanman; /* Use LanMan password instead of NT */
/* Has meaning only with MS-CHAP challenges */
#endif
extern char *current_option; /* the name of the option being parsed */
extern int privileged_option; /* set iff the current option came from root */
extern char *option_source; /* string saying where the option came from */
/*
* Values for phase.
*/
#define PHASE_DEAD 0
#define PHASE_INITIALIZE 1
#define PHASE_DORMANT 2
#define PHASE_ESTABLISH 3
#define PHASE_AUTHENTICATE 4
#define PHASE_CALLBACK 5
#define PHASE_NETWORK 6
#define PHASE_TERMINATE 7
#define PHASE_HOLDOFF 8
#define PHASE_SERIALCONN 2
#define PHASE_DORMANT 3
#define PHASE_ESTABLISH 4
#define PHASE_AUTHENTICATE 5
#define PHASE_CALLBACK 6
#define PHASE_NETWORK 7
#define PHASE_RUNNING 8
#define PHASE_TERMINATE 9
#define PHASE_DISCONNECT 10
#define PHASE_HOLDOFF 11
/*
* The following struct gives the addresses of procedures to call
@@ -160,8 +271,10 @@ struct protent {
void *arg));
/* Process a received data packet */
void (*datainput) __P((int unit, u_char *pkt, int len));
int enabled_flag; /* 0 iff protocol is disabled */
bool enabled_flag; /* 0 iff protocol is disabled */
char *name; /* Text name of protocol */
char *data_name; /* Text name of corresponding data protocol */
option_t *options; /* List of command-line options */
/* Check requested options, assign defaults */
void (*check_options) __P((void));
/* Configure interface for demand-dial */
@@ -178,40 +291,45 @@ extern struct protent *protocols[];
*/
/* Procedures exported from main.c. */
void detach __P((void)); /* Detach from controlling tty */
void die __P((int)); /* Cleanup and exit */
void quit __P((void)); /* like die(1) */
void novm __P((char *)); /* Say we ran out of memory, and die */
void my_timeout __P((void (*func)(void *), void *arg, int t));
void ppptimeout __P((void (*func)(void *), void *arg, int t));
/* Call func(arg) after t seconds */
void untimeout __P((void (*func)(void *), void *arg));
/* Cancel call to func(arg) */
int run_program __P((char *prog, char **args, int must_exist));
/* Run program prog with args in child */
void demuxprotrej __P((int, int));
/* Demultiplex a Protocol-Reject */
void format_packet __P((u_char *, int, void (*) (void *, char *, ...),
void *)); /* Format a packet in human-readable form */
void update_link_stats __P((int)); /* Get stats at link termination */
void new_phase __P((int)); /* signal start of new phase */
/* Procedures exported from utils.c. */
void log_packet __P((u_char *, int, char *, int));
/* Format a packet and log it with syslog */
void print_string __P((char *, int, void (*) (void *, char *, ...),
void *)); /* Format a string for output */
int fmtmsg __P((char *, int, char *, ...)); /* sprintf++ */
int vfmtmsg __P((char *, int, char *, va_list)); /* vsprintf++ */
void script_setenv __P((char *, char *)); /* set script env var */
void script_unsetenv __P((char *)); /* unset script env var */
/* My procedures */
int connect_stb();
int disconnect_stb();
int pppdmain(int, char*[]);
int chatmain(char*);
int slprintf __P((char *, int, char *, ...)); /* sprintf++ */
int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */
size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */
size_t strlcat __P((char *, const char *, size_t)); /* safe strncpy */
void pppd_dbglog __P((char *, ...)); /* log a debug message */
void pppd_info __P((char *, ...)); /* log an informational message */
void pppd_notice __P((char *, ...)); /* log a notice-level message */
void pppd_warn __P((char *, ...)); /* log a warning message */
void pppd_error __P((char *, ...)); /* log an error message */
void pppd_fatal __P((char *, ...)); /* log an error message and die(1) */
#define dbglog pppd_dbglog
#define info pppd_info
#define notice pppd_notice
#define warn pppd_warn
#define error pppd_error
#define fatal pppd_fatal
/* Procedures exported from auth.c */
void link_required __P((int)); /* we are starting to use the link */
void link_terminated __P((int)); /* we are finished with the link */
void link_down __P((int)); /* the LCP layer has left the Opened state */
void link_established __P((int)); /* the link is up; authenticate now */
void start_networks __P((void)); /* start all the network control protos */
void np_up __P((int, int)); /* a network protocol has come up */
void np_down __P((int, int)); /* a network protocol has gone down */
void np_finished __P((int, int)); /* a network protocol no longer needs link */
@@ -223,10 +341,10 @@ void auth_withpeer_fail __P((int, int));
/* we failed to authenticate ourselves */
void auth_withpeer_success __P((int, int));
/* we successfully authenticated ourselves */
void auth_check_options __P((void));
int auth_check_options __P((void));
/* check authentication options supplied */
void auth_reset __P((int)); /* check what secrets we have */
int check_passwd __P((int, char *, int, char *, int, char **, int *));
int check_passwd __P((int, char *, int, char *, int, char **));
/* Check peer-supplied username/password */
int get_secret __P((int, char *, char *, char *, int *, int));
/* get "secret" for chap */
@@ -234,8 +352,6 @@ int auth_ip_addr __P((int, u_int32_t));
/* check if IP address is authorized */
int bad_ip_adrs __P((u_int32_t));
/* check if IP address is unreasonable */
void check_access __P((FILE *, char *));
/* check permissions on secrets file */
/* Procedures exported from demand.c */
void demand_conf __P((void)); /* config interface(s) for demand-dial */
@@ -244,16 +360,17 @@ void demand_unblock __P((void)); /* set all NPs to pass packets */
void demand_discard __P((void)); /* set all NPs to discard packets */
void demand_rexmit __P((int)); /* retransmit saved frames for an NP */
int loop_chars __P((unsigned char *, int)); /* process chars from loopback */
int loop_frame __P((unsigned char *, int)); /* process frame from loopback */
int loop_frame __P((unsigned char *, int)); /* should we bring link up? */
/* Procedures exported from sys-*.c */
void sys_init __P((void)); /* Do system-dependent initialization */
void sys_cleanup __P((void)); /* Restore system state before exiting */
void sys_check_options __P((void)); /* Check options specified */
int sys_check_options __P((void)); /* Check options specified */
void sys_close __P((void)); /* Clean up in a child before execing */
int ppp_available __P((void)); /* Test whether ppp kernel support exists */
void open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */
void establish_ppp __P((int)); /* Turn serial port into a ppp interface */
int get_pty __P((int *, int *, char *, int)); /* Get pty master/slave */
int open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */
int establish_ppp __P((int)); /* Turn serial port into a ppp interface */
void restore_loop __P((void)); /* Transfer ppp unit back to loopback */
void disestablish_ppp __P((int)); /* Restore port to normal operation */
void clean_check __P((void)); /* Check if line was 8-bit clean */
@@ -263,9 +380,6 @@ void setdtr __P((int, int)); /* Raise or lower port's DTR line */
void output __P((int, u_char *, int)); /* Output a PPP packet */
void wait_input __P((struct timeval *));
/* Wait for input, with timeout */
void wait_loop_output __P((struct timeval *));
/* Wait for pkt from loopback, with timeout */
void wait_time __P((struct timeval *)); /* Wait for given length of time */
int read_packet __P((u_char *)); /* Read PPP packet */
int get_loop_output __P((void)); /* Read pkts from loopback */
void ppp_send_config __P((int, int, u_int32_t, int, int));
@@ -281,16 +395,24 @@ void ccp_flags_set __P((int, int, int));
int ccp_fatal_error __P((int)); /* Test for fatal decomp error in kernel */
int get_idle_time __P((int, struct ppp_idle *));
/* Find out how long link has been idle */
int get_ppp_stats __P((int, struct pppd_stats *));
/* Return link statistics */
int sifvjcomp __P((int, int, int, int));
/* Configure VJ TCP header compression */
int sifup __P((int)); /* Configure i/f up (for IP) */
int sifup __P((int)); /* Configure i/f up for one protocol */
int sifnpmode __P((int u, int proto, enum NPmode mode));
/* Set mode for handling packets for proto */
int sifdown __P((int)); /* Configure i/f down (for IP) */
int sifdown __P((int)); /* Configure i/f down for one protocol */
int sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t));
/* Configure IP addresses for i/f */
/* Configure IPv4 addresses for i/f */
int cifaddr __P((int, u_int32_t, u_int32_t));
/* Reset i/f IP addresses */
#ifdef INET6
int sif6addr __P((int, eui64_t, eui64_t));
/* Configure IPv6 addresses for i/f */
int cif6addr __P((int, eui64_t, eui64_t));
/* Remove an IPv6 address from i/f */
#endif
int sifdefaultroute __P((int, u_int32_t, u_int32_t));
/* Create default route through i/f */
int cifdefaultroute __P((int, u_int32_t, u_int32_t));
@@ -301,31 +423,38 @@ int cifproxyarp __P((int, u_int32_t));
/* Delete proxy ARP entry for peer */
u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */
int lock __P((char *)); /* Create lock file for device */
int relock __P((int)); /* Rewrite lock file with new pid */
void unlock __P((void)); /* Delete previously-created lock file */
int daemon __P((int, int)); /* Detach us from terminal session */
void logwtmp __P((const char *, const char *, const char *));
/* Write entry to wtmp file */
int get_host_seed __P((void)); /* Get host-dependent random number seed */
int have_route_to __P((u_int32_t)); /* Check if route to addr exists */
#ifdef PPP_FILTER
int set_filters __P((struct bpf_program *pass, struct bpf_program *active));
/* Set filter programs in kernel */
#endif
#ifdef IPX_CHANGE
int sipxfaddr __P((int, unsigned long, unsigned char *));
int cipxfaddr __P((int));
#endif
/* Procedures exported from options.c */
int parse_args __P((int argc, char **argv));
/* Parse options from arguments given */
void usage __P((void)); /* Print a usage message */
int options_from_file __P((char *filename, int must_exist, int check_prot,
int privileged));
/* Parse options from an options file */
int options_from_user __P((void)); /* Parse options from user's .ppprc */
int options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */
void scan_args __P((int argc, char **argv));
/* Look for tty name in command-line args */
int options_from_list __P((struct wordlist *, int privileged));
/* Parse options from a wordlist */
int getword __P((FILE *f, char *word, int *newlinep, char *filename));
/* Read a word from a file */
void option_error __P((char *fmt, ...));
/* Print an error message about an option */
int int_option __P((char *, int *));
/* Simplified number_option for decimal ints */
void add_options __P((option_t *)); /* Add extra options */
/*
* This structure is used to store information about certain
@@ -338,11 +467,29 @@ struct option_info {
char *source; /* where option came from */
};
extern struct option_info auth_req_info;
extern struct option_info connector_info;
extern struct option_info disconnector_info;
extern struct option_info welcomer_info;
extern struct option_info devnam_info;
extern struct option_info initializer_info;
extern struct option_info connect_script_info;
extern struct option_info disconnect_script_info;
extern struct option_info welcomer_info;
extern struct option_info ptycommand_info;
/*
* Hooks to enable plugins to change various things.
*/
extern int (*new_phase_hook) __P((int));
extern int (*idle_time_hook) __P((struct ppp_idle *));
extern int (*holdoff_hook) __P((void));
extern int (*pap_check_hook) __P((void));
extern int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp,
struct wordlist **paddrs,
struct wordlist **popts));
extern void (*pap_logout_hook) __P((void));
extern int (*pap_passwd_hook) __P((char *user, char *passwd));
extern void (*ip_up_hook) __P((void));
extern void (*ip_down_hook) __P((void));
extern void (*auth_linkup_hook) __P((void));
extern void (*auth_linkdown_hook) __P((void));
/*
* Inline versions of get/put char/short/long.
@@ -383,25 +530,17 @@ extern struct option_info devnam_info;
#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.
*/
#define DEMUXPROTREJ(u, p) demuxprotrej(u, p)
#define TIMEOUT(r, f, t) my_timeout((r), (f), (t))
#define TIMEOUT(r, f, t) ppptimeout((r), (f), (t))
#define UNTIMEOUT(r, f) untimeout((r), (f))
#define BCOPY(s, d, l) memcpy(d, s, l)
#define BZERO(s, n) memset(s, 0, n)
#define EXIT(u) quit()
#define PRINTMSG(m, l) { m[l] = '\0'; syslog(LOG_INFO, "Remote message: %s", m); }
#define PRINTMSG(m, l) { info("Remote message: %0.*v", l, m); }
/*
* MAKEHEADER - Add Header fields to a packet.
@@ -411,71 +550,97 @@ extern struct option_info devnam_info;
PUTCHAR(PPP_UI, p); \
PUTSHORT(t, p); }
/* #define DEBUGALL */
/*
* Exit status values.
*/
#define EXIT_OK 0
#define EXIT_FATAL_ERROR 1
#define EXIT_OPTION_ERROR 2
#define EXIT_NOT_ROOT 3
#define EXIT_NO_KERNEL_SUPPORT 4
#define EXIT_USER_REQUEST 5
#define EXIT_LOCK_FAILED 6
#define EXIT_OPEN_FAILED 7
#define EXIT_CONNECT_FAILED 8
#define EXIT_PTYCMD_FAILED 9
#define EXIT_NEGOTIATION_FAILED 10
#define EXIT_PEER_AUTH_FAILED 11
#define EXIT_IDLE_TIMEOUT 12
#define EXIT_CONNECT_TIME 13
#define EXIT_CALLBACK 14
#define EXIT_PEER_DEAD 15
#define EXIT_HANGUP 16
#define EXIT_LOOPBACK 17
#define EXIT_INIT_FAILED 18
#define EXIT_AUTH_TOPEER_FAILED 19
/*
* Debug macros. Slightly useful for finding bugs in pppd, not particularly
* useful for finding out why your connection isn't being established.
*/
#ifdef DEBUGALL
#define DEBUGMAIN 1
#define DEBUGFSM 1
#define DEBUGLCP 1
#define DEBUGIPCP 1
#define DEBUGIPV6CP 1
#define DEBUGUPAP 1
#define DEBUGCHAP 1
#endif
#define DEBUGMAIN 1
#ifndef LOG_PPP /* we use LOG_LOCAL2 for syslog by default */
#if defined(DEBUGMAIN) || defined(DEBUGFSM) || defined(DEBUGSYS) \
|| defined(DEBUGLCP) || defined(DEBUGIPCP) || defined(DEBUGUPAP) \
|| defined(DEBUGCHAP) || defined(DEBUG)
#define LOG_PPP LOG_LOCAL2
#else
#define LOG_PPP LOG_DAEMON
#endif
#endif /* LOG_PPP */
extern rtems_id pppdaemon_tid;
#ifdef DEBUGMAIN
#define MAINDEBUG(x) if (debug) syslog x
#define MAINDEBUG(x) if (debug) dbglog x
#else
#define MAINDEBUG(x)
#endif
#ifdef DEBUGSYS
#define SYSDEBUG(x) if (debug) syslog x
#define SYSDEBUG(x) if (debug) dbglog x
#else
#define SYSDEBUG(x)
#endif
#ifdef DEBUGFSM
#define FSMDEBUG(x) if (debug) syslog x
#define FSMDEBUG(x) if (debug) dbglog x
#else
#define FSMDEBUG(x)
#endif
#ifdef DEBUGLCP
#define LCPDEBUG(x) if (debug) syslog x
#define LCPDEBUG(x) if (debug) dbglog x
#else
#define LCPDEBUG(x)
#endif
#ifdef DEBUGIPCP
#define IPCPDEBUG(x) if (debug) syslog x
#define IPCPDEBUG(x) if (debug) dbglog x
#else
#define IPCPDEBUG(x)
#endif
#ifdef DEBUGIPV6CP
#define IPV6CPDEBUG(x) if (debug) dbglog x
#else
#define IPV6CPDEBUG(x)
#endif
#ifdef DEBUGUPAP
#define UPAPDEBUG(x) if (debug) syslog x
#define UPAPDEBUG(x) if (debug) dbglog x
#else
#define UPAPDEBUG(x)
#endif
#ifdef DEBUGCHAP
#define CHAPDEBUG(x) if (debug) syslog x
#define CHAPDEBUG(x) if (debug) dbglog x
#else
#define CHAPDEBUG(x)
#endif
#ifdef DEBUGIPXCP
#define IPXCPDEBUG(x) if (debug) syslog x
#define IPXCPDEBUG(x) if (debug) dbglog x
#else
#define IPXCPDEBUG(x)
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,903 @@
/*
* main.c - Point-to-Point Protocol main module
*
* 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.
*/
#define RCSID "$Id$"
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <pwd.h>
#include <setjmp.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <rtems.h>
#include <rtems/rtems_bsdnet.h>
extern void rtems_bsdnet_semaphore_obtain(void);
extern void rtems_bsdnet_semaphore_release(void);
extern int chatmain(char *argv);
#include "pppd.h"
#include "magic.h"
#include "fsm.h"
#include "lcp.h"
#include "ipcp.h"
#ifdef INET6
#include "ipv6cp.h"
#endif
#include "upap.h"
#include "chap.h"
#include "ccp.h"
#include "pathnames.h"
#include "patchlevel.h"
#ifdef CBCP_SUPPORT
#include "cbcp.h"
#endif
#ifdef IPX_CHANGE
#include "ipxcp.h"
#endif /* IPX_CHANGE */
#ifdef AT_CHANGE
#include "atcp.h"
#endif
static const char rcsid[] = RCSID;
/* interface vars */
char ifname[32]; /* Interface name */
int pppifunit; /* Interface unit number */
char *progname; /* Name of this program */
char hostname[MAXNAMELEN]; /* Our hostname */
static char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */
int ttyfd; /* Serial port file descriptor */
int baud_rate; /* Actual bits/second for serial device */
int hungup; /* terminal has been hung up */
int privileged; /* we're running as real uid root */
int need_holdoff; /* need holdoff period before restarting */
int detached; /* have detached from terminal */
struct stat devstat; /* result of stat() on devnam */
int prepass = 0; /* doing prepass to find device name */
int devnam_fixed; /* set while in options.ttyxx file */
volatile int status; /* exit status for pppd */
int unsuccess; /* # unsuccessful connection attempts */
int do_callback; /* != 0 if we should do callback next */
int doing_callback; /* != 0 if we are doing callback */
char *callback_script; /* script for doing callback */
int (*holdoff_hook) __P((void)) = NULL;
int (*new_phase_hook) __P((int)) = NULL;
static int fd_ppp = -1; /* fd for talking PPP */
static int pty_master; /* fd for master side of pty */
static int pty_slave; /* fd for slave side of pty */
static int real_ttyfd; /* fd for actual serial port (not pty) */
int phase; /* where the link is at */
int kill_link;
int open_ccp_flag;
static int waiting;
char **script_env; /* Env. variable values for scripts */
int s_env_nalloc; /* # words avail at script_env */
u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */
u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */
char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n";
static struct timeval start_time; /* Time when link was started. */
struct pppd_stats link_stats;
int link_connect_time;
int link_stats_valid;
/* Prototypes for procedures local to this file. */
static void cleanup __P((void));
static void close_tty __P((void));
static void get_input __P((void));
static void calltimeout __P((void));
static struct timeval *timeleft __P((struct timeval *));
static void holdoff_end __P((void *));
static int device_script __P((char *, int, int, int));
extern char *ttyname __P((int));
extern char *getlogin __P((void));
int pppdmain __P((int, char *[]));
/*
* PPP Data Link Layer "protocol" table.
* One entry per supported protocol.
* The last entry must be NULL.
*/
struct protent *protocols[] = {
&lcp_protent,
&pap_protent,
&chap_protent,
#ifdef CBCP_SUPPORT
&cbcp_protent,
#endif
&ipcp_protent,
#ifdef INET6
&ipv6cp_protent,
#endif
&ccp_protent,
#ifdef IPX_CHANGE
&ipxcp_protent,
#endif
#ifdef AT_CHANGE
&atcp_protent,
#endif
NULL
};
int
pppdmain(argc, argv)
int argc;
char *argv[];
{
int i, fdflags, t;
char *connector;
struct timeval timo;
struct protent *protp;
new_phase(PHASE_INITIALIZE);
script_env = NULL;
hostname[MAXNAMELEN-1] = 0;
privileged = 1;
privileged_option = 1;
/*
* Initialize magic number generator now so that protocols may
* use magic numbers in initialization.
*/
magic_init();
#ifdef XXX_XXX
/* moved code the the rtems_pppd_reset_options function */
/*
* Initialize to the standard option set, then parse, in order,
* the system options file, the user's options file,
* the tty's options file, and the command line arguments.
*/
for (i = 0; (protp = protocols[i]) != NULL; ++i)
(*protp->init)(0);
#endif
progname = *argv;
if (!ppp_available()) {
option_error(no_ppp_msg);
return(EXIT_NO_KERNEL_SUPPORT);
}
/*
* Check that the options given are valid and consistent.
*/
if (!sys_check_options()) {
return(EXIT_OPTION_ERROR);
}
if (!auth_check_options()) {
return(EXIT_OPTION_ERROR);
}
for (i = 0; (protp = protocols[i]) != NULL; ++i)
if (protp->check_options != NULL)
(*protp->check_options)();
/* default holdoff to 0 if no connect script has been given */
if (connect_script == 0 && !holdoff_specified)
holdoff = 0;
if (default_device)
nodetach = 1;
/*
* Initialize system-dependent stuff.
*/
sys_init();
/* if (debug)
setlogmask(LOG_UPTO(LOG_DEBUG));
*/
waiting = 0;
do_callback = 0;
for (;;) {
need_holdoff = 1;
ttyfd = -1;
real_ttyfd = -1;
status = EXIT_OK;
++unsuccess;
doing_callback = do_callback;
do_callback = 0;
new_phase(PHASE_SERIALCONN);
/*
* Get a pty master/slave pair if the pty, notty, or record
* options were specified.
*/
strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
pty_master = -1;
pty_slave = -1;
/*
* Open the serial device and set it up to be the ppp interface.
* First we open it in non-blocking mode so we can set the
* various termios flags appropriately. If we aren't dialling
* out and we want to use the modem lines, we reopen it later
* in order to wait for the carrier detect signal from the modem.
*/
hungup = 0;
kill_link = 0;
connector = doing_callback? callback_script: connect_script;
if (devnam[0] != 0) {
for (;;) {
/* If the user specified the device name, become the
user before opening it. */
int err;
ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0);
err = errno;
if (ttyfd >= 0) {
break;
}
errno = err;
if (err != EINTR) {
error("Failed to open %s: %m", devnam);
status = EXIT_OPEN_FAILED;
}
if (!persist || err != EINTR)
goto fail;
}
if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1
|| fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)
warn("Couldn't reset non-blocking mode on device: %m");
/*
* Set line speed, flow control, etc.
* If we have a non-null connection or initializer script,
* on most systems we set CLOCAL for now so that we can talk
* to the modem before carrier comes up. But this has the
* side effect that we might miss it if CD drops before we
* get to clear CLOCAL below. On systems where we can talk
* successfully to the modem with CLOCAL clear and CD down,
* we could clear CLOCAL at this point.
*/
set_up_tty(ttyfd, ((connector != NULL && connector[0] != 0)
|| initializer != NULL));
real_ttyfd = ttyfd;
}
/* run connection script */
if ((connector && connector[0]) || initializer) {
if (real_ttyfd != -1) {
/* XXX do this if doing_callback == CALLBACK_DIALIN? */
if (!default_device && modem) {
setdtr(real_ttyfd, 0); /* in case modem is off hook */
sleep(1);
setdtr(real_ttyfd, 1);
}
}
if (initializer && initializer[0]) {
if (device_script(initializer, ttyfd, ttyfd, 0) < 0) {
error("Initializer script failed");
status = EXIT_INIT_FAILED;
goto fail;
}
if (kill_link)
goto disconnect;
info("Serial port initialized.");
}
if (connector && connector[0]) {
if (device_script(connector, ttyfd, ttyfd, 0) < 0) {
error("Connect script failed");
status = EXIT_CONNECT_FAILED;
goto fail;
}
if (kill_link)
goto disconnect;
info("Serial connection established.");
}
/* set line speed, flow control, etc.;
clear CLOCAL if modem option */
if (real_ttyfd != -1)
set_up_tty(real_ttyfd, 0);
if (doing_callback == CALLBACK_DIALIN)
connector = NULL;
}
/* reopen tty if necessary to wait for carrier */
if (connector == NULL && modem && devnam[0] != 0) {
for (;;) {
if ((i = open(devnam, O_RDWR)) >= 0)
break;
if (errno != EINTR) {
error("Failed to reopen %s: %m", devnam);
status = EXIT_OPEN_FAILED;
}
if (!persist || errno != EINTR || hungup || kill_link)
goto fail;
}
close(i);
}
info("Serial connection established.");
sleep(1);
/* run welcome script, if any */
if (welcomer && welcomer[0]) {
if (device_script(welcomer, ttyfd, ttyfd, 0) < 0)
warn("Welcome script failed");
}
/* set up the serial device as a ppp interface */
fd_ppp = establish_ppp(ttyfd);
if (fd_ppp < 0) {
status = EXIT_FATAL_ERROR;
goto disconnect;
}
if (!demand) {
info("Using interface ppp%d", pppifunit);
slprintf(ifname, sizeof(ifname), "ppp%d", pppifunit);
}
/*
* Start opening the connection and wait for
* incoming events (reply, timeout, etc.).
*/
notice("Connect: %s <--> %s", ifname, ppp_devnam);
gettimeofday(&start_time, NULL);
rtems_bsdnet_semaphore_obtain();
lcp_lowerup(0);
lcp_open(0); /* Start protocol */
rtems_bsdnet_semaphore_release();
open_ccp_flag = 0;
status = EXIT_NEGOTIATION_FAILED;
new_phase(PHASE_ESTABLISH);
while (phase != PHASE_DEAD) {
waiting = 1;
wait_input(timeleft(&timo));
waiting = 0;
calltimeout();
get_input();
if (kill_link) {
lcp_close(0, "User request");
kill_link = 0;
}
if (open_ccp_flag) {
if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) {
ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */
(*ccp_protent.open)(0);
}
open_ccp_flag = 0;
}
}
/*
* If we may want to bring the link up again, transfer
* the ppp unit back to the loopback. Set the
* real serial device back to its normal mode of operation.
*/
clean_check();
if (demand)
restore_loop();
disestablish_ppp(ttyfd);
fd_ppp = -1;
if (!hungup)
lcp_lowerdown(0);
/*
* Run disconnector script, if requested.
* XXX we may not be able to do this if the line has hung up!
*/
disconnect:
if (disconnect_script && !hungup) {
new_phase(PHASE_DISCONNECT);
if (real_ttyfd >= 0)
set_up_tty(real_ttyfd, 1);
if (device_script(disconnect_script, ttyfd, ttyfd, 0) < 0) {
warn("disconnect script failed");
} else {
info("Serial link disconnected.");
}
}
fail:
if (pty_master >= 0)
close(pty_master);
if (pty_slave >= 0)
close(pty_slave);
if (real_ttyfd >= 0)
close_tty();
if (!persist || (maxfail > 0 && unsuccess >= maxfail))
break;
kill_link = 0;
if (demand)
demand_discard();
t = need_holdoff? holdoff: 0;
if (holdoff_hook)
t = (*holdoff_hook)();
if (t > 0) {
new_phase(PHASE_HOLDOFF);
TIMEOUT(holdoff_end, NULL, t);
do {
waiting = 1;
wait_input(timeleft(&timo));
waiting = 0;
calltimeout();
if (kill_link) {
kill_link = 0;
new_phase(PHASE_DORMANT); /* allow signal to end holdoff */
}
} while (phase == PHASE_HOLDOFF);
if (!persist)
break;
}
}
die(status);
return 0;
}
/*
* holdoff_end - called via a timeout when the holdoff period ends.
*/
static void
holdoff_end(arg)
void *arg;
{
new_phase(PHASE_DORMANT);
}
/* List of protocol names, to make our messages a little more informative. */
struct protocol_list {
u_short proto;
const char *name;
} protocol_list[] = {
{ 0x21, "IP" },
{ 0x23, "OSI Network Layer" },
{ 0x25, "Xerox NS IDP" },
{ 0x27, "DECnet Phase IV" },
{ 0x29, "Appletalk" },
{ 0x2b, "Novell IPX" },
{ 0x2d, "VJ compressed TCP/IP" },
{ 0x2f, "VJ uncompressed TCP/IP" },
{ 0x31, "Bridging PDU" },
{ 0x33, "Stream Protocol ST-II" },
{ 0x35, "Banyan Vines" },
{ 0x39, "AppleTalk EDDP" },
{ 0x3b, "AppleTalk SmartBuffered" },
{ 0x3d, "Multi-Link" },
{ 0x3f, "NETBIOS Framing" },
{ 0x41, "Cisco Systems" },
{ 0x43, "Ascom Timeplex" },
{ 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" },
{ 0x47, "DCA Remote Lan" },
{ 0x49, "Serial Data Transport Protocol (PPP-SDTP)" },
{ 0x4b, "SNA over 802.2" },
{ 0x4d, "SNA" },
{ 0x4f, "IP6 Header Compression" },
{ 0x6f, "Stampede Bridging" },
{ 0xfb, "single-link compression" },
{ 0xfd, "1st choice compression" },
{ 0x0201, "802.1d Hello Packets" },
{ 0x0203, "IBM Source Routing BPDU" },
{ 0x0205, "DEC LANBridge100 Spanning Tree" },
{ 0x0231, "Luxcom" },
{ 0x0233, "Sigma Network Systems" },
{ 0x8021, "Internet Protocol Control Protocol" },
{ 0x8023, "OSI Network Layer Control Protocol" },
{ 0x8025, "Xerox NS IDP Control Protocol" },
{ 0x8027, "DECnet Phase IV Control Protocol" },
{ 0x8029, "Appletalk Control Protocol" },
{ 0x802b, "Novell IPX Control Protocol" },
{ 0x8031, "Bridging NCP" },
{ 0x8033, "Stream Protocol Control Protocol" },
{ 0x8035, "Banyan Vines Control Protocol" },
{ 0x803d, "Multi-Link Control Protocol" },
{ 0x803f, "NETBIOS Framing Control Protocol" },
{ 0x8041, "Cisco Systems Control Protocol" },
{ 0x8043, "Ascom Timeplex" },
{ 0x8045, "Fujitsu LBLB Control Protocol" },
{ 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" },
{ 0x8049, "Serial Data Control Protocol (PPP-SDCP)" },
{ 0x804b, "SNA over 802.2 Control Protocol" },
{ 0x804d, "SNA Control Protocol" },
{ 0x804f, "IP6 Header Compression Control Protocol" },
{ 0x006f, "Stampede Bridging Control Protocol" },
{ 0x80fb, "Single Link Compression Control Protocol" },
{ 0x80fd, "Compression Control Protocol" },
{ 0xc021, "Link Control Protocol" },
{ 0xc023, "Password Authentication Protocol" },
{ 0xc025, "Link Quality Report" },
{ 0xc027, "Shiva Password Authentication Protocol" },
{ 0xc029, "CallBack Control Protocol (CBCP)" },
{ 0xc081, "Container Control Protocol" },
{ 0xc223, "Challenge Handshake Authentication Protocol" },
{ 0xc281, "Proprietary Authentication Protocol" },
{ 0, NULL },
};
/*
* protocol_name - find a name for a PPP protocol.
*/
const char *
protocol_name(proto)
int proto;
{
struct protocol_list *lp;
for (lp = protocol_list; lp->proto != 0; ++lp)
if (proto == lp->proto)
return lp->name;
return NULL;
}
/*
* get_input - called when incoming data is available.
*/
static void
get_input()
{
int len, i;
u_char *p;
u_short protocol;
struct protent *protp;
p = inpacket_buf; /* point to beginning of packet buffer */
len = read_packet(inpacket_buf);
if (len < 0)
return;
if (len == 0) {
notice("Modem hangup");
hungup = 1;
status = EXIT_HANGUP;
lcp_lowerdown(0); /* serial link is no longer available */
link_terminated(0);
return;
}
if (debug /*&& (debugflags & DBG_INPACKET)*/)
dbglog("rcvd %P", p, len);
if (len < PPP_HDRLEN) {
MAINDEBUG(("io(): Received short packet."));
return;
}
rtems_bsdnet_semaphore_obtain();
p += 2; /* Skip address and control */
GETSHORT(protocol, p);
len -= PPP_HDRLEN;
/*
* Toss all non-LCP packets unless LCP is OPEN.
*/
if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) {
MAINDEBUG(("get_input: Received non-LCP packet when LCP not open."));
rtems_bsdnet_semaphore_release();
return;
}
/*
* Until we get past the authentication phase, toss all packets
* except LCP, LQR and authentication packets.
*/
if (phase <= PHASE_AUTHENTICATE
&& !(protocol == PPP_LCP || protocol == PPP_LQR
|| protocol == PPP_PAP || protocol == PPP_CHAP)) {
MAINDEBUG(("get_input: discarding proto 0x%x in phase %d",
protocol, phase));
rtems_bsdnet_semaphore_release();
return;
}
/*
* Upcall the proper protocol input routine.
*/
for (i = 0; (protp = protocols[i]) != NULL; ++i) {
if (protp->protocol == protocol && protp->enabled_flag) {
(*protp->input)(0, p, len);
rtems_bsdnet_semaphore_release();
return;
}
if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag
&& protp->datainput != NULL) {
(*protp->datainput)(0, p, len);
rtems_bsdnet_semaphore_release();
return;
}
}
if (debug) {
const char *pname = protocol_name(protocol);
if (pname != NULL)
warn("Unsupported protocol '%s' (0x%x) received", pname, protocol);
else
warn("Unsupported protocol 0x%x received", protocol);
}
lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN);
rtems_bsdnet_semaphore_release();
}
/*
* new_phase - signal the start of a new phase of pppd's operation.
*/
void
new_phase(p)
int p;
{
phase = p;
if (new_phase_hook)
(*new_phase_hook)(p);
}
/*
* die - clean up state and exit with the specified status.
*/
void
die(status)
int status;
{
cleanup();
}
/*
* cleanup - restore anything which needs to be restored before we exit
*/
/* ARGSUSED */
static void
cleanup()
{
sys_cleanup();
if (fd_ppp >= 0)
disestablish_ppp(ttyfd);
if (real_ttyfd >= 0)
close_tty();
sys_close();
}
/*
* close_tty - restore the terminal device and close it.
*/
static void
close_tty()
{
/* drop dtr to hang up */
if (!default_device && modem) {
setdtr(real_ttyfd, 0);
/*
* This sleep is in case the serial port has CLOCAL set by default,
* and consequently will reassert DTR when we close the device.
*/
sleep(1);
}
restore_tty(real_ttyfd);
close(real_ttyfd);
real_ttyfd = -1;
}
/*
* update_link_stats - get stats at link termination.
*/
void
update_link_stats(u)
int u;
{
struct timeval now;
char numbuf[32];
if (!get_ppp_stats(u, &link_stats)
|| gettimeofday(&now, NULL) < 0)
return;
link_connect_time = now.tv_sec - start_time.tv_sec;
link_stats_valid = 1;
slprintf(numbuf, sizeof(numbuf), "%d", link_connect_time);
slprintf(numbuf, sizeof(numbuf), "%d", link_stats.bytes_out);
slprintf(numbuf, sizeof(numbuf), "%d", link_stats.bytes_in);
}
struct callout {
struct timeval c_time; /* time at which to call routine */
void *c_arg; /* argument to routine */
void (*c_func) __P((void *)); /* routine */
struct callout *c_next;
};
static struct callout *callout = NULL; /* Callout list */
static struct timeval timenow; /* Current time */
/*
* timeout - Schedule a timeout.
*
* Note that this timeout takes the number of seconds, NOT hz (as in
* the kernel).
*/
void
ppptimeout(func, arg, time)
void (*func) __P((void *));
void *arg;
int time;
{
struct callout *newp, *p, **pp;
MAINDEBUG(("Timeout %p:%p in %d seconds.", func, arg, time));
/*
* Allocate timeout.
*/
if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL)
fatal("Out of memory in timeout()!");
newp->c_arg = arg;
newp->c_func = func;
gettimeofday(&timenow, NULL);
newp->c_time.tv_sec = timenow.tv_sec + time;
newp->c_time.tv_usec = timenow.tv_usec;
/*
* Find correct place and link it in.
*/
for (pp = &callout; (p = *pp); pp = &p->c_next)
if (newp->c_time.tv_sec < p->c_time.tv_sec
|| (newp->c_time.tv_sec == p->c_time.tv_sec
&& newp->c_time.tv_usec < p->c_time.tv_usec))
break;
newp->c_next = p;
*pp = newp;
}
/*
* untimeout - Unschedule a timeout.
*/
void
untimeout(func, arg)
void (*func) __P((void *));
void *arg;
{
struct callout **copp, *freep;
MAINDEBUG(("Untimeout %p:%p.", func, arg));
/*
* Find first matching timeout and remove it from the list.
*/
for (copp = &callout; (freep = *copp); copp = &freep->c_next)
if (freep->c_func == func && freep->c_arg == arg) {
*copp = freep->c_next;
free((char *) freep);
break;
}
}
/*
* calltimeout - Call any timeout routines which are now due.
*/
static void
calltimeout()
{
struct callout *p;
while (callout != NULL) {
p = callout;
if (gettimeofday(&timenow, NULL) < 0)
fatal("Failed to get time of day: %m");
if (!(p->c_time.tv_sec < timenow.tv_sec
|| (p->c_time.tv_sec == timenow.tv_sec
&& p->c_time.tv_usec <= timenow.tv_usec)))
break; /* no, it's not time yet */
callout = p->c_next;
(*p->c_func)(p->c_arg);
free((char *) p);
}
}
/*
* timeleft - return the length of time until the next timeout is due.
*/
static struct timeval *
timeleft(tvp)
struct timeval *tvp;
{
if (callout == NULL)
return NULL;
gettimeofday(&timenow, NULL);
tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec;
tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec;
if (tvp->tv_usec < 0) {
tvp->tv_usec += 1000000;
tvp->tv_sec -= 1;
}
if (tvp->tv_sec < 0)
tvp->tv_sec = tvp->tv_usec = 0;
return tvp;
}
/*
* device_script - run a program to talk to the serial device
* (e.g. to run the connector or disconnector script).
*/
static int
device_script(program, in, out, dont_wait)
char *program;
int in, out;
int dont_wait;
{
char pScript[256];
strcpy(pScript, program);
return chatmain(pScript);
}
/*
* novm - log an error message saying we ran out of memory, and die.
*/
void
novm(msg)
char *msg;
{
fatal("Virtual memory exhausted allocating %s\n", msg);
}

View File

@@ -0,0 +1,173 @@
#include <rtems.h>
#include "pppd.h"
#include "rtemspppd.h"
/* define pppd function prototypes */
extern void pppasyncattach(void);
extern int pppdmain(int, char **);
/* define global variables */
rtems_id rtems_pppd_taskid;
static rtems_task pppTask(rtems_task_argument arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
rtems_option options;
rtems_event_set in;
rtems_event_set out;
/* call function to setup ppp line discipline */
pppasyncattach();
/* enter processing loop */
in = (RTEMS_EVENT_29 | RTEMS_EVENT_30);
options = (RTEMS_EVENT_ANY | RTEMS_WAIT);
while ( sc == RTEMS_SUCCESSFUL ) {
/* wait for the next event */
sc = rtems_event_receive(in, options, RTEMS_NO_TIMEOUT, &out);
if ( sc == RTEMS_SUCCESSFUL ) {
/* determine which event was sent */
if ( out & RTEMS_EVENT_29 ) {
/* terminate event received */
/* set value to break out of event loop */
sc = RTEMS_UNSATISFIED;
}
else if ( out & RTEMS_EVENT_30 ) {
/* connect request */
/* execute the pppd main code */
pppdmain(0, NULL);
}
}
}
/* terminate myself */
rtems_task_delete(RTEMS_SELF);
}
int rtems_pppd_initialize(void)
{
int iReturn = (int)-1;
rtems_status_code status;
rtems_name taskName;
taskName = rtems_build_name( 'p', 'p', 'p', 'd' );
status = rtems_task_create(taskName,
RTEMS_PPPD_TASK_PRIORITY,
RTEMS_PPPD_TASK_STACK_SIZE,
RTEMS_PPPD_TASK_INITIAL_MODES,
RTEMS_DEFAULT_ATTRIBUTES,
&rtems_pppd_taskid);
if ( status == RTEMS_SUCCESSFUL ) {
status = rtems_task_start(rtems_pppd_taskid, pppTask, 0);
if ( status == RTEMS_SUCCESSFUL ) {
iReturn = rtems_pppd_reset_options();
}
}
return ( iReturn );
}
int rtems_pppd_terminate(void)
{
/* send terminate signal to pppd task */
rtems_event_send(rtems_pppd_taskid, RTEMS_EVENT_29);
/* call the disconnect function */
rtems_pppd_disconnect();
return ( 0 );
}
int rtems_pppd_reset_options(void)
{
int i;
struct protent *protp;
/*
* Initialize to the standard option set, then parse, in order,
* the system options file, the user's options file,
* the tty's options file, and the command line arguments.
*/
for (i = 0; (protp = protocols[i]) != NULL; ++i)
(*protp->init)(0);
return ( 0 );
}
int rtems_pppd_set_hook(int id, rtems_pppd_hookfunction hookfp)
{
int iReturn = (int)0;
switch ( id ) {
case RTEMS_PPPD_LINKUP_HOOK:
auth_linkup_hook = hookfp;
break;
case RTEMS_PPPD_LINKDOWN_HOOK:
auth_linkdown_hook = hookfp;
break;
case RTEMS_PPPD_IPUP_HOOK:
ip_up_hook = hookfp;
break;
case RTEMS_PPPD_IPDOWN_HOOK:
ip_down_hook = hookfp;
break;
default:
iReturn = (int)-1;
break;
}
return ( iReturn );
}
int rtems_pppd_set_option(const char *pOption, const char *pValue)
{
int iReturn = (int)0;
int prevPhase;
struct wordlist option;
struct wordlist value;
if ( pOption != (const char *)0 ) {
/* initialize the values */
option.word = (char *)pOption;
option.next = (struct wordlist *)0;
if ( pValue != (const char *)0 ) {
option.next = &value;
value.word = (char *)pValue;
value.next = (struct wordlist *)0;
}
/* save current phase value */
prevPhase = phase;
phase = PHASE_INITIALIZE;
/* process option and reset phase value */
iReturn = options_from_list(&option, 1);
phase = prevPhase;
}
return ( iReturn );
}
int rtems_pppd_connect(void)
{
/* send connect signal to pppd task */
rtems_event_send(rtems_pppd_taskid, RTEMS_EVENT_30);
return ( 0 );
}
int rtems_pppd_disconnect(void)
{
/* set pppd global variables to disconnect */
persist = 0;
kill_link = 1;
/* send event to wake up the pppd code */
/* pretend its a serial interrput */
rtems_event_send(rtems_pppd_taskid, RTEMS_EVENT_31);
return ( 0 );
}

View File

@@ -0,0 +1,38 @@
#ifndef RTEMSPPPD_H
#define RTEMSPPPD_H
/* check to see if pppd task values are set */
#ifndef RTEMS_PPPD_TASK_PRIORITY
#define RTEMS_PPPD_TASK_PRIORITY 120
#endif
#ifndef RTEMS_PPPD_TASK_STACK_SIZE
#define RTEMS_PPPD_TASK_STACK_SIZE (10*1024)
#endif
#ifndef RTEMS_PPPD_TASK_INITIAL_MODES
#define RTEMS_PPPD_TASK_INITIAL_MODES (RTEMS_PREEMPT | \
RTEMS_NO_TIMESLICE | \
RTEMS_NO_ASR | \
RTEMS_INTERRUPT_LEVEL(0))
#endif
/* define hook function identifiers */
#define RTEMS_PPPD_LINKUP_HOOK 1
#define RTEMS_PPPD_LINKDOWN_HOOK 2
#define RTEMS_PPPD_IPUP_HOOK 3
#define RTEMS_PPPD_IPDOWN_HOOK 4
/* define hook function pointer prototype */
typedef void (*rtems_pppd_hookfunction)(void);
/* define pppd function prototyes */
int rtems_pppd_initialize(void);
int rtems_pppd_terminate(void);
int rtems_pppd_reset_options(void);
int rtems_pppd_set_hook(int id, rtems_pppd_hookfunction hookfp);
int rtems_pppd_set_option(const char *pOption, const char *pValue);
int rtems_pppd_connect(void);
int rtems_pppd_disconnect(void);
#endif

View File

@@ -17,9 +17,7 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
/* static char rcsid[] = "$Id$"; */
#endif
#define RCSID "$Id$"
/*
* TODO:
@@ -27,13 +25,30 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <syslog.h>
#include "pppd.h"
#include "upap.h"
#define print_string(user, ulen, printer, arg)
static const char rcsid[] = RCSID;
static bool hide_password = 1;
/*
* Command-line options.
*/
static option_t pap_option_list[] = {
{ "hide-password", o_bool, &hide_password,
"Don't output passwords to log", 1 },
{ "show-password", o_bool, &hide_password,
"Show password string in debug log messages", 0 },
{ "pap-restart", o_int, &upap[0].us_timeouttime,
"Set retransmit timeout for PAP" },
{ "pap-max-authreq", o_int, &upap[0].us_maxtransmits,
"Set max number of transmissions for auth-reqs" },
{ "pap-timeout", o_int, &upap[0].us_reqtimeout,
"Set time limit for peer PAP authentication" },
{ NULL }
};
/*
* Protocol entry points.
@@ -60,6 +75,8 @@ struct protent pap_protent = {
1,
"PAP",
NULL,
pap_option_list,
NULL,
NULL,
NULL
};
@@ -166,7 +183,7 @@ upap_timeout(arg)
if (u->us_transmits >= u->us_maxtransmits) {
/* give up in disgust */
syslog(LOG_ERR, "No response to PAP authenticate-requests");
error("No response to PAP authenticate-requests");
u->us_clientstate = UPAPCS_BADAUTH;
auth_withpeer_fail(u->us_unit, PPP_PAP);
return;
@@ -253,11 +270,11 @@ upap_protrej(unit)
upap_state *u = &upap[unit];
if (u->us_clientstate == UPAPCS_AUTHREQ) {
syslog(LOG_ERR, "PAP authentication failed due to protocol-reject");
error("PAP authentication failed due to protocol-reject");
auth_withpeer_fail(unit, PPP_PAP);
}
if (u->us_serverstate == UPAPSS_LISTEN) {
syslog(LOG_ERR, "PAP authentication of peer failed (protocol-reject)");
error("PAP authentication of peer failed (protocol-reject)");
auth_peer_fail(unit, PPP_PAP);
}
upap_lowerdown(unit);
@@ -284,18 +301,18 @@ upap_input(unit, inpacket, l)
*/
inp = inpacket;
if (l < UPAP_HEADERLEN) {
UPAPDEBUG((LOG_INFO, "pap_input: rcvd short header."));
UPAPDEBUG(("pap_input: rcvd short header."));
return;
}
GETCHAR(code, inp);
GETCHAR(id, inp);
GETSHORT(len, inp);
if (len < UPAP_HEADERLEN) {
UPAPDEBUG((LOG_INFO, "pap_input: rcvd illegal length."));
UPAPDEBUG(("pap_input: rcvd illegal length."));
return;
}
if (len > l) {
UPAPDEBUG((LOG_INFO, "pap_input: rcvd short packet."));
UPAPDEBUG(("pap_input: rcvd short packet."));
return;
}
len -= UPAP_HEADERLEN;
@@ -338,8 +355,6 @@ upap_rauthreq(u, inp, id, len)
char *msg;
int msglen;
UPAPDEBUG((LOG_INFO, "pap_rauth: Rcvd id %d.", id));
if (u->us_serverstate < UPAPSS_LISTEN)
return;
@@ -359,21 +374,21 @@ upap_rauthreq(u, inp, id, len)
/*
* Parse user/passwd.
*/
if (len < sizeof (u_char)) {
UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet."));
if (len < 1) {
UPAPDEBUG(("pap_rauth: rcvd short packet."));
return;
}
GETCHAR(ruserlen, inp);
len -= sizeof (u_char) + ruserlen + sizeof (u_char);
if (len < 0) {
UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet."));
UPAPDEBUG(("pap_rauth: rcvd short packet."));
return;
}
ruser = (char *) inp;
INCPTR(ruserlen, inp);
GETCHAR(rpasswdlen, inp);
if (len < rpasswdlen) {
UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet."));
UPAPDEBUG(("pap_rauth: rcvd short packet."));
return;
}
rpasswd = (char *) inp;
@@ -382,8 +397,11 @@ upap_rauthreq(u, inp, id, len)
* Check the username and password given.
*/
retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd,
rpasswdlen, &msg, &msglen);
rpasswdlen, &msg);
BZERO(rpasswd, rpasswdlen);
msglen = strlen(msg);
if (msglen > 255)
msglen = 255;
upap_sresp(u, retcode, id, msg, msglen);
@@ -413,25 +431,26 @@ upap_rauthack(u, inp, id, len)
u_char msglen;
char *msg;
UPAPDEBUG((LOG_INFO, "pap_rauthack: Rcvd id %d.", id));
if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
return;
/*
* Parse message.
*/
if (len < sizeof (u_char)) {
UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet."));
return;
if (len < 1) {
UPAPDEBUG(("pap_rauthack: ignoring missing msg-length."));
} else {
GETCHAR(msglen, inp);
if (msglen > 0) {
len -= sizeof (u_char);
if (len < msglen) {
UPAPDEBUG(("pap_rauthack: rcvd short packet."));
return;
}
msg = (char *) inp;
PRINTMSG(msg, msglen);
}
}
GETCHAR(msglen, inp);
len -= sizeof (u_char);
if (len < msglen) {
UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet."));
return;
}
msg = (char *) inp;
PRINTMSG(msg, msglen);
u->us_clientstate = UPAPCS_OPEN;
@@ -452,29 +471,30 @@ upap_rauthnak(u, inp, id, len)
u_char msglen;
char *msg;
UPAPDEBUG((LOG_INFO, "pap_rauthnak: Rcvd id %d.", id));
if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
return;
/*
* Parse message.
*/
if (len < sizeof (u_char)) {
UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet."));
return;
if (len < 1) {
UPAPDEBUG(("pap_rauthnak: ignoring missing msg-length."));
} else {
GETCHAR(msglen, inp);
if (msglen > 0) {
len -= sizeof (u_char);
if (len < msglen) {
UPAPDEBUG(("pap_rauthnak: rcvd short packet."));
return;
}
msg = (char *) inp;
PRINTMSG(msg, msglen);
}
}
GETCHAR(msglen, inp);
len -= sizeof (u_char);
if (len < msglen) {
UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet."));
return;
}
msg = (char *) inp;
PRINTMSG(msg, msglen);
u->us_clientstate = UPAPCS_BADAUTH;
syslog(LOG_ERR, "PAP authentication failed");
error("PAP authentication failed");
auth_withpeer_fail(u->us_unit, PPP_PAP);
}
@@ -506,8 +526,6 @@ upap_sauthreq(u)
output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
UPAPDEBUG((LOG_INFO, "pap_sauth: Sent id %d.", u->us_id));
TIMEOUT(upap_timeout, u, u->us_timeouttime);
++u->us_transmits;
u->us_clientstate = UPAPCS_AUTHREQ;
@@ -520,7 +538,7 @@ upap_sauthreq(u)
static void
upap_sresp(u, code, id, msg, msglen)
upap_state *u;
int code, id;
u_char code, id;
char *msg;
int msglen;
{
@@ -537,8 +555,6 @@ upap_sresp(u, code, id, msg, msglen)
PUTCHAR(msglen, outp);
BCOPY(msg, outp, msglen);
output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
UPAPDEBUG((LOG_INFO, "pap_sresp: Sent code %d, id %d.", code, id));
}
/*
@@ -592,7 +608,10 @@ upap_printpkt(p, plen, printer, arg)
printer(arg, " user=");
print_string(user, ulen, printer, arg);
printer(arg, " password=");
print_string(pwd, wlen, printer, arg);
if (!hide_password)
print_string(pwd, wlen, printer, arg);
else
printer(arg, "<hidden>");
break;
case UPAP_AUTHACK:
case UPAP_AUTHNAK:

View File

@@ -22,7 +22,7 @@
/*
* Packet header = Code, id, length.
*/
#define UPAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
#define UPAP_HEADERLEN 4
/*

View File

@@ -0,0 +1,872 @@
/*
* utils.c - various utility functions used in pppd.
*
* Copyright (c) 1999 The Australian National 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 the Australian National 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.
*/
#define RCSID "$Id$"
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <syslog.h>
#include <pwd.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef SVR4
#include <sys/mkdev.h>
#endif
#include "pppd.h"
static const char rcsid[] = RCSID;
#if defined(SUNOS4)
extern char *strerror();
#endif
static void pr_log __P((void *, char *, ...));
static void logit __P((int, char *, va_list));
static void vslp_printer __P((void *, char *, ...));
static void format_packet __P((u_char *, int, void (*) (void *, char *, ...),
void *));
struct buffer_info {
char *ptr;
int len;
};
/*
* strlcpy - like strcpy/strncpy, doesn't overflow destination buffer,
* always leaves destination null-terminated (for len > 0).
*/
size_t
strlcpy(dest, src, len)
char *dest;
const char *src;
size_t len;
{
size_t ret = strlen(src);
if (len != 0) {
if (ret < len)
strcpy(dest, src);
else {
strncpy(dest, src, len - 1);
dest[len-1] = 0;
}
}
return ret;
}
/*
* strlcat - like strcat/strncat, doesn't overflow destination buffer,
* always leaves destination null-terminated (for len > 0).
*/
size_t
strlcat(dest, src, len)
char *dest;
const char *src;
size_t len;
{
size_t dlen = strlen(dest);
return dlen + strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0));
}
/*
* slprintf - format a message into a buffer. Like sprintf except we
* also specify the length of the output buffer, and we handle
* %r (recursive format), %m (error message), %v (visible string),
* %q (quoted string), %t (current time) and %I (IP address) formats.
* Doesn't do floating-point formats.
* Returns the number of chars put into buf.
*/
int
slprintf __V((char *buf, int buflen, char *fmt, ...))
{
va_list args;
int n;
#if defined(__STDC__)
va_start(args, fmt);
#else
char *buf;
int buflen;
char *fmt;
va_start(args);
buf = va_arg(args, char *);
buflen = va_arg(args, int);
fmt = va_arg(args, char *);
#endif
n = vslprintf(buf, buflen, fmt, args);
va_end(args);
return n;
}
/*
* vslprintf - like slprintf, takes a va_list instead of a list of args.
*/
#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0)
int
vslprintf(buf, buflen, fmt, args)
char *buf;
int buflen;
char *fmt;
va_list args;
{
int c, i, n;
int width, prec, fillch;
int base, len, neg, quoted;
unsigned long val = 0;
char *str, *f, *buf0;
unsigned char *p;
char num[32];
time_t t;
u_int32_t ip;
static char hexchars[] = "0123456789abcdef";
struct buffer_info bufinfo;
buf0 = buf;
--buflen;
while (buflen > 0) {
for (f = fmt; *f != '%' && *f != 0; ++f)
;
if (f > fmt) {
len = f - fmt;
if (len > buflen)
len = buflen;
memcpy(buf, fmt, len);
buf += len;
buflen -= len;
fmt = f;
}
if (*fmt == 0)
break;
c = *++fmt;
width = 0;
prec = -1;
fillch = ' ';
if (c == '0') {
fillch = '0';
c = *++fmt;
}
if (c == '*') {
width = va_arg(args, int);
c = *++fmt;
} else {
while (isdigit(c)) {
width = width * 10 + c - '0';
c = *++fmt;
}
}
if (c == '.') {
c = *++fmt;
if (c == '*') {
prec = va_arg(args, int);
c = *++fmt;
} else {
prec = 0;
while (isdigit(c)) {
prec = prec * 10 + c - '0';
c = *++fmt;
}
}
}
str = 0;
base = 0;
neg = 0;
++fmt;
switch (c) {
case 'd':
i = va_arg(args, int);
if (i < 0) {
neg = 1;
val = -i;
} else
val = i;
base = 10;
break;
case 'o':
val = va_arg(args, unsigned int);
base = 8;
break;
case 'x':
case 'X':
val = va_arg(args, unsigned int);
base = 16;
break;
case 'p':
val = (unsigned long) va_arg(args, void *);
base = 16;
neg = 2;
break;
case 's':
str = va_arg(args, char *);
break;
case 'c':
num[0] = va_arg(args, int);
num[1] = 0;
str = num;
break;
case 'm':
str = strerror(errno);
break;
case 'I':
ip = va_arg(args, u_int32_t);
ip = ntohl(ip);
slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff,
(ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
str = num;
break;
case 'r':
f = va_arg(args, char *);
#ifndef __powerpc__
n = vslprintf(buf, buflen + 1, f, va_arg(args, va_list));
#else
/* On the powerpc, a va_list is an array of 1 structure */
n = vslprintf(buf, buflen + 1, f, va_arg(args, void *));
#endif
buf += n;
buflen -= n;
continue;
case 't':
time(&t);
str = ctime(&t);
str += 4; /* chop off the day name */
str[15] = 0; /* chop off year and newline */
break;
case 'v': /* "visible" string */
case 'q': /* quoted string */
quoted = c == 'q';
p = va_arg(args, unsigned char *);
if (fillch == '0' && prec >= 0) {
n = prec;
} else {
n = strlen((char *)p);
if (prec >= 0 && n > prec)
n = prec;
}
while (n > 0 && buflen > 0) {
c = *p++;
--n;
if (!quoted && c >= 0x80) {
OUTCHAR('M');
OUTCHAR('-');
c -= 0x80;
}
if (quoted && (c == '"' || c == '\\'))
OUTCHAR('\\');
if (c < 0x20 || (0x7f <= c && c < 0xa0)) {
if (quoted) {
OUTCHAR('\\');
switch (c) {
case '\t': OUTCHAR('t'); break;
case '\n': OUTCHAR('n'); break;
case '\b': OUTCHAR('b'); break;
case '\f': OUTCHAR('f'); break;
default:
OUTCHAR('x');
OUTCHAR(hexchars[c >> 4]);
OUTCHAR(hexchars[c & 0xf]);
}
} else {
if (c == '\t')
OUTCHAR(c);
else {
OUTCHAR('^');
OUTCHAR(c ^ 0x40);
}
}
} else
OUTCHAR(c);
}
continue;
case 'P': /* print PPP packet */
bufinfo.ptr = buf;
bufinfo.len = buflen + 1;
p = va_arg(args, unsigned char *);
n = va_arg(args, int);
format_packet(p, n, vslp_printer, &bufinfo);
buf = bufinfo.ptr;
buflen = bufinfo.len - 1;
continue;
case 'B':
p = va_arg(args, unsigned char *);
for (n = prec; n > 0; --n) {
c = *p++;
if (fillch == ' ')
OUTCHAR(' ');
OUTCHAR(hexchars[(c >> 4) & 0xf]);
OUTCHAR(hexchars[c & 0xf]);
}
continue;
default:
*buf++ = '%';
if (c != '%')
--fmt; /* so %z outputs %z etc. */
--buflen;
continue;
}
if (base != 0) {
str = num + sizeof(num);
*--str = 0;
while (str > num + neg) {
*--str = hexchars[val % base];
val = val / base;
if (--prec <= 0 && val == 0)
break;
}
switch (neg) {
case 1:
*--str = '-';
break;
case 2:
*--str = 'x';
*--str = '0';
break;
}
len = num + sizeof(num) - 1 - str;
} else {
len = strlen(str);
if (prec >= 0 && len > prec)
len = prec;
}
if (width > 0) {
if (width > buflen)
width = buflen;
if ((n = width - len) > 0) {
buflen -= n;
for (; n > 0; --n)
*buf++ = fillch;
}
}
if (len > buflen)
len = buflen;
memcpy(buf, str, len);
buf += len;
buflen -= len;
}
*buf = 0;
return buf - buf0;
}
/*
* vslp_printer - used in processing a %P format
*/
static void
vslp_printer __V((void *arg, char *fmt, ...))
{
int n;
va_list pvar;
struct buffer_info *bi;
#if defined(__STDC__)
va_start(pvar, fmt);
#else
void *arg;
char *fmt;
va_start(pvar);
arg = va_arg(pvar, void *);
fmt = va_arg(pvar, char *);
#endif
bi = (struct buffer_info *) arg;
n = vslprintf(bi->ptr, bi->len, fmt, pvar);
va_end(pvar);
bi->ptr += n;
bi->len -= n;
}
/*
* log_packet - format a packet and log it.
*/
char line[256]; /* line to be logged accumulated here */
char *linep;
void
log_packet(p, len, prefix, level)
u_char *p;
int len;
char *prefix;
int level;
{
strlcpy(line, prefix, sizeof(line));
linep = line + strlen(line);
format_packet(p, len, pr_log, NULL);
}
/*
* format_packet - make a readable representation of a packet,
* calling `printer(arg, format, ...)' to output it.
*/
static void
format_packet(p, len, printer, arg)
u_char *p;
int len;
void (*printer) __P((void *, char *, ...));
void *arg;
{
int i, n;
u_short proto;
struct protent *protp;
if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) {
p += 2;
GETSHORT(proto, p);
len -= PPP_HDRLEN;
for (i = 0; (protp = protocols[i]) != NULL; ++i)
if (proto == protp->protocol)
break;
if (protp != NULL) {
printer(arg, "[%s", protp->name);
n = (*protp->printpkt)(p, len, printer, arg);
printer(arg, "]");
p += n;
len -= n;
} else {
for (i = 0; (protp = protocols[i]) != NULL; ++i)
if (proto == (protp->protocol & ~0x8000))
break;
if (protp != 0 && protp->data_name != 0) {
printer(arg, "[%s data]", protp->data_name);
if (len > 8)
printer(arg, "%.8B ...", p);
else
printer(arg, "%.*B", len, p);
len = 0;
} else
printer(arg, "[proto=0x%x]", proto);
}
}
if (len > 32)
printer(arg, "%.32B ...", p);
else
printer(arg, "%.*B", len, p);
}
static void
pr_log __V((void *arg, char *fmt, ...))
{
int n;
va_list pvar;
char buf[256];
#if defined(__STDC__)
va_start(pvar, fmt);
#else
void *arg;
char *fmt;
va_start(pvar);
arg = va_arg(pvar, void *);
fmt = va_arg(pvar, char *);
#endif
n = vslprintf(buf, sizeof(buf), fmt, pvar);
va_end(pvar);
if (linep + n + 1 > line + sizeof(line)) {
linep = line;
}
strlcpy(linep, buf, line + sizeof(line) - linep);
linep += n;
}
/*
* print_string - print a readable representation of a string using
* printer.
*/
void
print_string(p, len, printer, arg)
char *p;
int len;
void (*printer) __P((void *, char *, ...));
void *arg;
{
int c;
printer(arg, "\"");
for (; len > 0; --len) {
c = *p++;
if (' ' <= c && c <= '~') {
if (c == '\\' || c == '"')
printer(arg, "\\");
printer(arg, "%c", c);
} else {
switch (c) {
case '\n':
printer(arg, "\\n");
break;
case '\r':
printer(arg, "\\r");
break;
case '\t':
printer(arg, "\\t");
break;
default:
printer(arg, "\\%.3o", c);
}
}
}
printer(arg, "\"");
}
/*
* logit - does the hard work for fatal et al.
*/
static void
logit(level, fmt, args)
int level;
char *fmt;
va_list args;
{
int n;
char buf[256];
n = vslprintf(buf, sizeof(buf), fmt, args);
/* if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { */
if (log_to_fd >= 0 && (debug)) {
if (buf[n-1] != '\n')
buf[n++] = '\n';
if (write(log_to_fd, buf, n) != n)
log_to_fd = -1;
}
}
/*
* fatal - log an error message and die horribly.
*/
void
pppd_fatal __V((char *fmt, ...))
{
va_list pvar;
#if defined(__STDC__)
va_start(pvar, fmt);
#else
char *fmt;
va_start(pvar);
fmt = va_arg(pvar, char *);
#endif
logit(LOG_ERR, fmt, pvar);
va_end(pvar);
die(1); /* as promised */
}
/*
* error - log an error message.
*/
void
pppd_error __V((char *fmt, ...))
{
va_list pvar;
#if defined(__STDC__)
va_start(pvar, fmt);
#else
char *fmt;
va_start(pvar);
fmt = va_arg(pvar, char *);
#endif
logit(LOG_ERR, fmt, pvar);
va_end(pvar);
}
/*
* warn - log a warning message.
*/
void
pppd_warn __V((char *fmt, ...))
{
va_list pvar;
#if defined(__STDC__)
va_start(pvar, fmt);
#else
char *fmt;
va_start(pvar);
fmt = va_arg(pvar, char *);
#endif
logit(LOG_WARNING, fmt, pvar);
va_end(pvar);
}
/*
* notice - log a notice-level message.
*/
void
pppd_notice __V((char *fmt, ...))
{
va_list pvar;
#if defined(__STDC__)
va_start(pvar, fmt);
#else
char *fmt;
va_start(pvar);
fmt = va_arg(pvar, char *);
#endif
logit(LOG_NOTICE, fmt, pvar);
va_end(pvar);
}
/*
* info - log an informational message.
*/
void
pppd_info __V((char *fmt, ...))
{
va_list pvar;
#if defined(__STDC__)
va_start(pvar, fmt);
#else
char *fmt;
va_start(pvar);
fmt = va_arg(pvar, char *);
#endif
logit(LOG_INFO, fmt, pvar);
va_end(pvar);
}
/*
* dbglog - log a debug message.
*/
void
pppd_dbglog __V((char *fmt, ...))
{
va_list pvar;
#if defined(__STDC__)
va_start(pvar, fmt);
#else
char *fmt;
va_start(pvar);
fmt = va_arg(pvar, char *);
#endif
logit(LOG_DEBUG, fmt, pvar);
va_end(pvar);
}
/* Procedures for locking the serial device using a lock file. */
#ifndef LOCK_DIR
#ifdef _linux_
#define LOCK_DIR "/var/lock"
#else
#ifdef SVR4
#define LOCK_DIR "/var/spool/locks"
#else
#define LOCK_DIR "/var/spool/lock"
#endif
#endif
#endif /* LOCK_DIR */
static char lock_file[MAXPATHLEN];
/*
* lock - create a lock file for the named device
*/
int
lock(dev)
char *dev;
{
#ifdef LOCKLIB
int result;
result = mklock (dev, (void *) 0);
if (result == 0) {
strlcpy(lock_file, sizeof(lock_file), dev);
return 0;
}
if (result > 0)
notice("Device %s is locked by pid %d", dev, result);
else
error("Can't create lock file %s", lock_file);
return -1;
#else /* LOCKLIB */
char lock_buffer[12];
int fd, pid, n;
#ifdef SVR4
struct stat sbuf;
if (stat(dev, &sbuf) < 0) {
error("Can't get device number for %s: %m", dev);
return -1;
}
if ((sbuf.st_mode & S_IFMT) != S_IFCHR) {
error("Can't lock %s: not a character device", dev);
return -1;
}
slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d",
LOCK_DIR, major(sbuf.st_dev),
major(sbuf.st_rdev), minor(sbuf.st_rdev));
#else
char *p;
if ((p = strrchr(dev, '/')) != NULL)
dev = p + 1;
slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev);
#endif
while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
if (errno != EEXIST) {
error("Can't create lock file %s: %m", lock_file);
break;
}
/* Read the lock file to find out who has the device locked. */
fd = open(lock_file, O_RDONLY, 0);
if (fd < 0) {
if (errno == ENOENT) /* This is just a timing problem. */
continue;
error("Can't open existing lock file %s: %m", lock_file);
break;
}
#ifndef LOCK_BINARY
n = read(fd, lock_buffer, 11);
#else
n = read(fd, &pid, sizeof(pid));
#endif /* LOCK_BINARY */
close(fd);
fd = -1;
if (n <= 0) {
error("Can't read pid from lock file %s", lock_file);
break;
}
/* See if the process still exists. */
#ifndef LOCK_BINARY
lock_buffer[n] = 0;
pid = atoi(lock_buffer);
#endif /* LOCK_BINARY */
if (pid == getpid())
return 1; /* somebody else locked it for us */
if (pid == 0
|| (kill(pid, 0) == -1 && errno == ESRCH)) {
if (unlink (lock_file) == 0) {
notice("Removed stale lock on %s (pid %d)", dev, pid);
continue;
}
warn("Couldn't remove stale lock on %s", dev);
} else
notice("Device %s is locked by pid %d", dev, pid);
break;
}
if (fd < 0) {
lock_file[0] = 0;
return -1;
}
pid = getpid();
#ifndef LOCK_BINARY
slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
write (fd, lock_buffer, 11);
#else
write(fd, &pid, sizeof (pid));
#endif
close(fd);
return 0;
#endif
}
/*
* relock - called to update our lockfile when we are about to detach,
* thus changing our pid (we fork, the child carries on, and the parent dies).
* Note that this is called by the parent, with pid equal to the pid
* of the child. This avoids a potential race which would exist if
* we had the child rewrite the lockfile (the parent might die first,
* and another process could think the lock was stale if it checked
* between when the parent died and the child rewrote the lockfile).
*/
int
relock(pid)
int pid;
{
#ifdef LOCKLIB
/* XXX is there a way to do this? */
return -1;
#else /* LOCKLIB */
int fd;
char lock_buffer[12];
if (lock_file[0] == 0)
return -1;
fd = open(lock_file, O_WRONLY, 0);
if (fd < 0) {
error("Couldn't reopen lock file %s: %m", lock_file);
lock_file[0] = 0;
return -1;
}
#ifndef LOCK_BINARY
slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
write (fd, lock_buffer, 11);
#else
write(fd, &pid, sizeof(pid));
#endif /* LOCK_BINARY */
close(fd);
return 0;
#endif /* LOCKLIB */
}
/*
* unlock - remove our lockfile
*/
void
unlock()
{
if (lock_file[0]) {
#ifdef LOCKLIB
(void) rmlock(lock_file, (void *) 0);
#else
unlink(lock_file);
#endif
lock_file[0] = 0;
}
}