forked from Imagelibrary/rtems
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:
@@ -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.
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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");
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
/*
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
/*
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
45
c/src/libnetworking/pppd/example/Makefile
Normal file
45
c/src/libnetworking/pppd/example/Makefile
Normal 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)
|
||||
|
||||
6
c/src/libnetworking/pppd/example/README
Normal file
6
c/src/libnetworking/pppd/example/README
Normal file
@@ -0,0 +1,6 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
This is an example user application using pppd. It is built using
|
||||
the RTEMS application Makefiles.
|
||||
24
c/src/libnetworking/pppd/example/init.c
Normal file
24
c/src/libnetworking/pppd/example/init.c
Normal 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);
|
||||
}
|
||||
37
c/src/libnetworking/pppd/example/netconfig.h
Normal file
37
c/src/libnetworking/pppd/example/netconfig.h
Normal 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
|
||||
27
c/src/libnetworking/pppd/example/ppp.conf
Normal file
27
c/src/libnetworking/pppd/example/ppp.conf
Normal 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
|
||||
146
c/src/libnetworking/pppd/example/pppdapp.c
Normal file
146
c/src/libnetworking/pppd/example/pppdapp.c
Normal 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 );
|
||||
}
|
||||
42
c/src/libnetworking/pppd/example/system.h
Normal file
42
c/src/libnetworking/pppd/example/system.h
Normal 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
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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
1480
c/src/libnetworking/pppd/pppd.8
Normal file
1480
c/src/libnetworking/pppd/pppd.8
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
903
c/src/libnetworking/pppd/rtemsmain.c
Normal file
903
c/src/libnetworking/pppd/rtemsmain.c
Normal 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);
|
||||
}
|
||||
173
c/src/libnetworking/pppd/rtemspppd.c
Normal file
173
c/src/libnetworking/pppd/rtemspppd.c
Normal 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 );
|
||||
}
|
||||
38
c/src/libnetworking/pppd/rtemspppd.h
Normal file
38
c/src/libnetworking/pppd/rtemspppd.h
Normal 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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
/*
|
||||
|
||||
872
c/src/libnetworking/pppd/utils.c
Normal file
872
c/src/libnetworking/pppd/utils.c
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user