Create struct datalink.

This is a type of physical link that can chat and talk
LCP & CCP.  A bundle contains a list of these (only one
in the list for the moment).

The datalink is a type of descriptor, and dials, enters
LCP (& does CCP), kicks the bundle when its FSMs do
something interesting and does the hangup chat script
on the way down.  It also handles redials and reconnects.

There are lots of loose ends, and probably lots of bugs,
but the data structures are getting there !
This commit is contained in:
Brian Somers 1998-02-16 00:01:12 +00:00
parent c78db105b5
commit 3006ec67fe
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/MP/; revision=33415
27 changed files with 750 additions and 412 deletions

View File

@ -1,9 +1,9 @@
# $Id: Makefile,v 1.36.2.5 1998/02/07 20:49:12 brian Exp $
# $Id: Makefile,v 1.36.2.6 1998/02/10 03:23:04 brian Exp $
PROG= ppp
SRCS= arp.c async.c auth.c bundle.c ccp.c chap.c chat.c command.c deflate.c \
defs.c filter.c fsm.c hdlc.c id.c ip.c ipcp.c iplist.c lcp.c \
link.c log.c lqr.c main.c mbuf.c modem.c pap.c physical.c pred.c \
datalink.c defs.c filter.c fsm.c hdlc.c id.c ip.c ipcp.c iplist.c \
lcp.c link.c log.c lqr.c main.c mbuf.c modem.c pap.c physical.c pred.c \
prompt.c route.c server.c sig.c slcompress.c systems.c throughput.c \
timer.c tun.c vars.c vjcomp.c
CFLAGS+=-Wall -Wpointer-arith

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bundle.c,v 1.1.2.7 1998/02/09 19:20:33 brian Exp $
* $Id: bundle.c,v 1.1.2.8 1998/02/10 03:23:06 brian Exp $
*/
#include <sys/param.h>
@ -74,6 +74,9 @@
#include "chap.h"
#include "tun.h"
#include "prompt.h"
#include "chat.h"
#include "datalink.h"
#include "ip.h"
static const char *PhaseNames[] = {
"Dead", "Establish", "Authenticate", "Network", "Terminate"
@ -95,9 +98,6 @@ bundle_NewPhase(struct bundle *bundle, struct physical *physical, u_int new)
switch (new) {
case PHASE_DEAD:
bundle->phase = new;
if (CleaningUp || (mode & MODE_DIRECT) ||
((mode & MODE_BACKGROUND) && reconnectState != RECON_TRUE))
Cleanup(EX_DEAD);
break;
case PHASE_ESTABLISH:
@ -123,6 +123,7 @@ bundle_NewPhase(struct bundle *bundle, struct physical *physical, u_int new)
case PHASE_NETWORK:
tun_configure(bundle, LcpInfo.his_mru, modem_Speed(physical));
IpcpInit(bundle, &physical->link);
IpcpUp();
IpcpOpen();
CcpUp();
@ -181,6 +182,7 @@ bundle_CleanInterface(const struct bundle *bundle)
void
bundle_LayerStart(struct bundle *bundle, struct fsm *fp)
{
/* The given FSM is about to start up ! */
if (fp == &LcpInfo.fsm)
bundle_NewPhase(bundle, link2physical(fp->link), PHASE_ESTABLISH);
}
@ -188,11 +190,12 @@ bundle_LayerStart(struct bundle *bundle, struct fsm *fp)
void
bundle_LayerUp(struct bundle *bundle, struct fsm *fp)
{
/* The given fsm is now up */
if (fp == &LcpInfo.fsm) {
reconnectState = RECON_UNKNOWN;
/*
* The given fsm is now up
* If it's the first datalink, bring all NCPs up.
*/
if (fp == &LcpInfo.fsm)
bundle_NewPhase(bundle, link2physical(fp->link), PHASE_AUTHENTICATE);
}
if (fp == &IpcpInfo.fsm)
if (mode & MODE_BACKGROUND && BGFiledes[1] != -1) {
@ -214,36 +217,28 @@ bundle_LinkIsUp(const struct bundle *bundle)
}
void
bundle_Close(struct bundle *bundle, struct fsm *fp)
bundle_Close(struct bundle *bundle, const char *name, int staydown)
{
/*
* Please close the given FSM.
* Please close the given datalink.
*
* If fp is any CCP, just FsmClose that CCP.
* If name == NULL or name is the last datalink, enter TERMINATE phase.
*
* If fp == NULL or fp is the last NCP or the last LCP, enter TERMINATE phase.
* If name == NULL, FsmClose all NCPs.
*
* If fp == NULL, FsmClose all NCPs.
* If name is the last datalink, FsmClose all NCPs.
*
* If fp is an NCP, just FsmClose that. When the NCPs TLF happens,
* and if it's the last NCP, bundle_LayerFinish will enter TERMINATE
* phase, FsmDown the top level CCP and FsmClose each of the LCPs.
*
* If fp is the last LCP, FsmClose all NCPs for the same
* reasons as above.
*
* If fp isn't an NCP and isn't the last LCP, just FsmClose that LCP.
* If isn't the last datalink, just Close that datalink.
*/
if (fp == &CcpInfo.fsm) {
FsmClose(&CcpInfo.fsm);
return;
}
bundle_NewPhase(bundle, NULL, PHASE_TERMINATE);
FsmClose(&IpcpInfo.fsm);
FsmClose(&CcpInfo.fsm);
if (staydown) {
struct datalink *dl;
for (dl = bundle->links; dl; dl = dl->next)
datalink_StayDown(dl);
}
}
/*
@ -349,16 +344,13 @@ bundle_Create(const char *prefix)
/* Clean out any leftover crud */
bundle_CleanInterface(&bundle);
bundle.physical = modem_Create("Modem");
if (bundle.physical == NULL) {
LogPrintf(LogERROR, "Cannot create modem device: %s\n", strerror(errno));
bundle.links = datalink_Create("Modem", &bundle);
if (bundle.links == NULL) {
LogPrintf(LogERROR, "Cannot create data link: %s\n", strerror(errno));
return NULL;
}
IpcpDefAddress();
LcpInit(&bundle, bundle.physical);
IpcpInit(&bundle, physical2link(bundle.physical));
CcpInit(&bundle, physical2link(bundle.physical));
IpcpInit(&bundle, &bundle.links->physical->link);
return &bundle;
}
@ -399,11 +391,17 @@ bundle_DownInterface(struct bundle *bundle)
void
bundle_Destroy(struct bundle *bundle)
{
struct datalink *dl;
if (mode & MODE_AUTO) {
IpcpCleanInterface(&IpcpInfo.fsm);
bundle_DownInterface(bundle);
}
link_Destroy(&bundle->physical->link);
dl = bundle->links;
while (dl)
dl = datalink_Destroy(dl);
bundle->ifname = NULL;
}
@ -524,18 +522,36 @@ bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst,
}
void
bundle_LinkLost(struct bundle *bundle, struct link *link)
bundle_LinkLost(struct bundle *bundle, struct link *link, int staydown)
{
/*
* Locate the appropriate LCP and its associated CCP, and FsmDown
* them both.
* The LCP TLF will notify bundle_LayerFinish() which will
* slam the top level CCP and all NCPs down.
* Locate the appropriate datalink, and Down it.
*
* The LayerFinish() called from the datalinks LCP will
* potentially Down our NCPs (if it's the last link).
*
* The LinkClosed() called when the datalink is finally in
* the CLOSED state MAY cause the entire datalink to be deleted
* and MAY cause a program exit.
*/
FsmDown(&LcpInfo.fsm);
if (CleaningUp || reconnectState == RECON_FALSE)
FsmClose(&LcpInfo.fsm);
datalink_Down(bundle->links, staydown);
}
void
bundle_LinkClosed(struct bundle *bundle, struct datalink *dl)
{
/*
* Our datalink has closed.
* If it's DIRECT, delete it.
* If it's the last data link,
*/
if (!(mode & MODE_AUTO))
bundle_DownInterface(bundle);
if (mode & MODE_DDIAL)
datalink_Up(dl);
else
bundle_NewPhase(bundle, NULL, PHASE_DEAD);
}
void
@ -554,10 +570,13 @@ bundle_LayerFinish(struct bundle *bundle, struct fsm *fp)
/* The given fsm is now down (fp cannot be NULL)
*
* If it's a CCP, just bring it back to STARTING in case we get more REQs
* If it's an LCP, FsmDown the corresponding CCP and link (if open). The
* link_Close causes the LCP to be FsmDown()d, so make sure we only close
* open links. XXX Not if the link is ok to come up again.
*
* If it's an LCP, FsmDown the corresponding CCP and Close the link if
* it's open. The link_Close causes the LCP to be FsmDown()d,
* via bundle_LinkLost() causing re-entry.
*
* If it's the last LCP, FsmDown all NCPs
*
* If it's the last NCP, FsmClose all LCPs and enter TERMINATE phase.
*/
@ -571,14 +590,92 @@ bundle_LayerFinish(struct bundle *bundle, struct fsm *fp)
FsmClose(&IpcpInfo.fsm); /* ST_INITIAL please */
if (link_IsActive(fp->link))
link_Close(fp->link, bundle, 0); /* clean shutdown */
if (!(mode & MODE_AUTO))
bundle_DownInterface(bundle);
bundle_NewPhase(bundle, NULL, PHASE_DEAD);
link_Close(fp->link, bundle, 0, 0); /* clean shutdown */
/* And wait for the LinkLost() */
} else if (fp == &IpcpInfo.fsm) {
FsmClose(&LcpInfo.fsm);
struct datalink *dl;
if (fp->bundle->phase != PHASE_TERMINATE)
bundle_NewPhase(bundle, NULL, PHASE_TERMINATE);
for (dl = bundle->links; dl; dl = dl->next)
datalink_Close(dl, 1);
}
}
void
bundle_Open(struct bundle *bundle, const char *name)
{
/*
* Please open the given datalink, or all if name == NULL
*/
struct datalink *dl;
for (dl = bundle->links; dl; dl = dl->next)
if (name == NULL || !strcasecmp(dl->name, name)) {
datalink_Up(dl);
if (name != NULL)
break;
}
}
struct datalink *
bundle2datalink(struct bundle *bundle, const char *name)
{
struct datalink *dl;
if (name != NULL) {
for (dl = bundle->links; dl; dl = dl->next)
if (!strcasecmp(dl->name, name))
return dl;
} else if (bundle->links && !bundle->links->next)
return bundle->links;
return NULL;
}
struct physical *
bundle2physical(struct bundle *bundle, const char *name)
{
struct datalink *dl = bundle2datalink(bundle, name);
return dl ? dl->physical : NULL;
}
struct link *
bundle2link(struct bundle *bundle, const char *name)
{
struct physical *physical = bundle2physical(bundle, name);
return physical ? &physical->link : NULL;
}
int
bundle_UpdateSet(struct bundle *bundle, fd_set *r, fd_set *w, fd_set *e, int *n)
{
struct datalink *dl;
int result;
result = 0;
for (dl = bundle->links; dl; dl = dl->next)
result += descriptor_UpdateSet(&dl->desc, r, w, e, n);
return result;
}
int
bundle_FillQueues(struct bundle *bundle)
{
struct datalink *dl;
int packets, total;
total = 0;
for (dl = bundle->links; dl; dl = dl->next) {
packets = link_QueueLen(&dl->physical->link);
if (packets == 0) {
IpStartOutput(&dl->physical->link);
packets = link_QueueLen(&dl->physical->link);
}
total += packets;
}
return total;
}

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bundle.h,v 1.1.2.6 1998/02/07 20:49:24 brian Exp $
* $Id: bundle.h,v 1.1.2.7 1998/02/08 19:29:43 brian Exp $
*/
#define PHASE_DEAD 0 /* Link is dead */
@ -32,6 +32,7 @@
#define PHASE_NETWORK 3 /* We're alive ! */
#define PHASE_TERMINATE 4 /* Terminating link */
struct datalink;
struct physical;
struct link;
struct fsm;
@ -45,7 +46,7 @@ struct bundle {
int routing_seq; /* The current routing sequence number */
u_int phase; /* Curent phase */
struct physical *physical; /* For the time being */
struct datalink *links; /* Our data links */
};
extern struct bundle *bundle_Create(const char *);
@ -58,7 +59,16 @@ extern void bundle_LayerUp(struct bundle *, struct fsm *);
extern int bundle_LinkIsUp(const struct bundle *);
extern void bundle_SetRoute(struct bundle *, int, struct in_addr,
struct in_addr, struct in_addr, int);
extern void bundle_LinkLost(struct bundle *, struct link *);
extern void bundle_Close(struct bundle *, struct fsm *);
extern void bundle_LinkLost(struct bundle *, struct link *, int);
extern void bundle_Close(struct bundle *, const char *, int);
extern void bundle_Open(struct bundle *, const char *name);
extern void bundle_LayerDown(struct bundle *, struct fsm *);
extern void bundle_LayerFinish(struct bundle *, struct fsm *);
extern void bundle_LinkClosed(struct bundle *, struct datalink *);
extern struct link *bundle2link(struct bundle *, const char *);
extern struct physical *bundle2physical(struct bundle *, const char *);
extern struct datalink *bundle2datalink(struct bundle *, const char *);
extern int bundle_UpdateSet(struct bundle *, fd_set *, fd_set *, fd_set *,
int *);
extern int bundle_FillQueues(struct bundle *);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: chap.c,v 1.28.2.7 1998/02/07 20:49:30 brian Exp $
* $Id: chap.c,v 1.28.2.8 1998/02/09 19:20:34 brian Exp $
*
* TODO:
*/
@ -268,8 +268,7 @@ RecvChapTalk(struct bundle *bundle, struct fsmheader *chp, struct mbuf *bp,
* Peer is not registerd, or response digest is wrong.
*/
ChapOutput(physical, CHAP_FAILURE, chp->id, "Invalid!!", 9);
reconnect(RECON_FALSE);
bundle_Close(bundle, &LcpInfo.fsm);
link_Close(&physical->link, bundle, 1, 1);
break;
}
}
@ -293,11 +292,9 @@ RecvChapResult(struct bundle *bundle, struct fsmheader *chp, struct mbuf *bp,
*/
bundle_NewPhase(bundle, physical, PHASE_NETWORK);
}
} else {
} else
/* CHAP failed - it's not going to get any better */
reconnect(RECON_FALSE);
bundle_Close(bundle, &LcpInfo.fsm);
}
link_Close(&physical->link, bundle, 1, 1);
}
void

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: command.c,v 1.131.2.15 1998/02/10 03:23:09 brian Exp $
* $Id: command.c,v 1.131.2.16 1998/02/13 05:10:13 brian Exp $
*
*/
#include <sys/param.h>
@ -78,6 +78,7 @@
#include "server.h"
#include "prompt.h"
#include "chat.h"
#include "datalink.h"
struct in_addr ifnetmask;
static const char *HIDDEN = "********";
@ -166,14 +167,8 @@ IsInteractive(int Display)
static int
DialCommand(struct cmdargs const *arg)
{
int tries;
int res;
if (dialing) {
prompt_Printf(&prompt, "A dial is already in progress\n");
return 0;
}
if (LcpInfo.fsm.state > ST_CLOSED) {
prompt_Printf(&prompt, "LCP state is [%s]\n",
StateNames[LcpInfo.fsm.state]);
@ -189,7 +184,7 @@ DialCommand(struct cmdargs const *arg)
if (arg->argc > 0 && (res = LoadCommand(arg)) != 0)
return res;
dial_up = 1;
bundle_Open(arg->bundle, NULL);
return 0;
}
@ -787,7 +782,7 @@ TerminalCommand(struct cmdargs const *arg)
}
if (!IsInteractive(1))
return (1);
if (modem_Open(arg->bundle->physical, arg->bundle) < 0) {
if (modem_Open(bundle2physical(arg->bundle, NULL), arg->bundle) < 0) {
prompt_Printf(&prompt, "Failed to open modem.\n");
return (1);
}
@ -814,17 +809,14 @@ QuitCommand(struct cmdargs const *arg)
static int
CloseCommand(struct cmdargs const *arg)
{
reconnect(RECON_FALSE);
bundle_Close(LcpInfo.fsm.bundle, &LcpInfo.fsm);
bundle_Close(LcpInfo.fsm.bundle, NULL, 1);
return 0;
}
static int
DownCommand(struct cmdargs const *arg)
{
reconnectState = RECON_FALSE;
reconnectCount = 0;
link_Close(&arg->bundle->physical->link, arg->bundle, 0);
link_Close(&arg->bundle->links->physical->link, arg->bundle, 0, 1);
return 0;
}
@ -840,7 +832,7 @@ SetModemSpeed(struct cmdargs const *arg)
return -1;
}
if (strcasecmp(*arg->argv, "sync") == 0) {
Physical_SetSync(arg->bundle->physical);
Physical_SetSync(arg->bundle->links->physical);
return 0;
}
end = NULL;
@ -849,7 +841,7 @@ SetModemSpeed(struct cmdargs const *arg)
LogPrintf(LogWARN, "SetModemSpeed: Bad argument \"%s\"", *arg->argv);
return -1;
}
if (Physical_SetSpeed(arg->bundle->physical, speed))
if (Physical_SetSpeed(arg->bundle->links->physical, speed))
return 0;
LogPrintf(LogWARN, "%s: Invalid speed\n", *arg->argv);
} else
@ -983,8 +975,6 @@ SetServer(struct cmdargs const *arg)
LocalAuthInit();
if (strcasecmp(port, "none") == 0) {
int oserver;
if (mask != NULL || passwd != NULL)
return -1;
@ -1030,7 +1020,7 @@ SetServer(struct cmdargs const *arg)
static int
SetModemParity(struct cmdargs const *arg)
{
return arg->argc > 0 ? modem_SetParity(arg->bundle->physical, *arg->argv) : -1;
return arg->argc > 0 ? modem_SetParity(arg->bundle->links->physical, *arg->argv) : -1;
}
static int
@ -1311,14 +1301,12 @@ SetVariable(struct cmdargs const *arg)
VarLoginScript[sizeof VarLoginScript - 1] = '\0';
break;
case VAR_DEVICE:
if (mode & MODE_INTER)
link_Close(physical2link(arg->bundle->physical), arg->bundle, 0);
if (link_IsActive(physical2link(arg->bundle->physical)))
if (link_IsActive(&arg->bundle->links->physical->link))
LogPrintf(LogWARN,
"Cannot change device to \"%s\" when \"%s\" is open\n",
argp, Physical_GetDevice(arg->bundle->physical));
argp, Physical_GetDevice(bundle2physical(arg->bundle, NULL)));
else {
Physical_SetDevice(arg->bundle->physical, argp);
Physical_SetDevice(bundle2physical(arg->bundle, NULL), argp);
}
break;
case VAR_ACCMAP:
@ -1356,9 +1344,9 @@ SetCtsRts(struct cmdargs const *arg)
}
if (strcmp(*arg->argv, "on") == 0)
Physical_SetRtsCts(arg->bundle->physical, 1);
Physical_SetRtsCts(bundle2physical(arg->bundle, NULL), 1);
else if (strcmp(*arg->argv, "off") == 0)
Physical_SetRtsCts(arg->bundle->physical, 0);
Physical_SetRtsCts(bundle2physical(arg->bundle, NULL), 0);
else
return -1;
return 0;

375
usr.sbin/ppp/datalink.c Normal file
View File

@ -0,0 +1,375 @@
/*-
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*/
#include <sys/param.h>
#include <netinet/in.h>
#include <alias.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include "command.h"
#include "mbuf.h"
#include "log.h"
#include "defs.h"
#include "loadalias.h"
#include "vars.h"
#include "timer.h"
#include "fsm.h"
#include "lcp.h"
#include "descriptor.h"
#include "hdlc.h"
#include "async.h"
#include "throughput.h"
#include "link.h"
#include "physical.h"
#include "bundle.h"
#include "chat.h"
#include "datalink.h"
#include "ccp.h"
#include "main.h"
#include "modem.h"
#include "iplist.h"
#include "ipcp.h"
static void
datalink_OpenTimeout(void *v)
{
struct datalink *dl = (struct datalink *)v;
StopTimer(&dl->dial_timer);
if (dl->state == DATALINK_OPENING)
LogPrintf(LogPHASE, "%s: Redial timer expired.\n", dl->name);
}
static void
datalink_StartDialTimer(struct datalink *dl, int Timeout)
{
StopTimer(&dl->dial_timer);
if (Timeout) {
dl->dial_timer.state = TIMER_STOPPED;
if (Timeout > 0)
dl->dial_timer.load = Timeout * SECTICKS;
else
dl->dial_timer.load = (random() % REDIAL_PERIOD) * SECTICKS;
dl->dial_timer.func = datalink_OpenTimeout;
dl->dial_timer.arg = dl;
StartTimer(&dl->dial_timer);
if (dl->state == DATALINK_OPENING)
LogPrintf(LogPHASE, "%s: Enter pause (%d) for redialing.\n",
dl->name, Timeout);
}
}
static void
datalink_HangupDone(struct datalink *dl)
{
modem_Close(dl->physical);
if (!dl->dial_tries || (dl->dial_tries < 0 && !dl->reconnect_tries)) {
LogPrintf(LogPHASE, "%s: Entering CLOSED state\n", dl->name);
dl->state = DATALINK_CLOSED;
dl->dial_tries = -1;
dl->reconnect_tries = 0;
bundle_LinkClosed(dl->bundle, dl);
} else {
LogPrintf(LogPHASE, "%s: Entering OPENING state\n", dl->name);
dl->state = DATALINK_OPENING;
}
if (VarNextPhone == NULL)
datalink_StartDialTimer(dl, VarRedialTimeout);
else
datalink_StartDialTimer(dl, VarRedialNextTimeout);
}
static int
datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
int *n)
{
struct datalink *dl = descriptor2datalink(d);
int result;
switch (dl->state) {
case DATALINK_CLOSED:
return 0;
case DATALINK_OPENING:
if (dl->dial_timer.state != TIMER_RUNNING) {
if (--dl->dial_tries < 0)
dl->dial_tries = 0;
if (modem_Open(dl->physical, dl->bundle) >= 0) {
LogPrintf(LogPHASE, "%s: Entering DIAL state\n", dl->name);
dl->state = DATALINK_DIAL;
chat_Init(&dl->chat, dl->physical, VarDialScript, 1);
if (!(mode & MODE_DDIAL) && VarDialTries)
LogPrintf(LogCHAT, "%s: Dial attempt %u of %d\n",
dl->name, VarDialTries - dl->dial_tries, VarDialTries);
} else {
if (!(mode & MODE_DDIAL) && VarDialTries)
LogPrintf(LogCHAT, "Failed to open modem (attempt %u of %d)\n",
VarDialTries - dl->dial_tries, VarDialTries);
else
LogPrintf(LogCHAT, "Failed to open modem\n");
if (!(mode & MODE_DDIAL) && VarDialTries && dl->dial_tries == 0) {
LogPrintf(LogPHASE, "%s: Entering CLOSED state\n", dl->name);
dl->state = DATALINK_CLOSED;
dl->reconnect_tries = 0;
dl->dial_tries = -1;
if (mode & MODE_BACKGROUND)
CleaningUp = 1;
} else
datalink_StartDialTimer(dl, VarRedialTimeout);
}
}
return 0;
case DATALINK_HANGUP:
case DATALINK_DIAL:
case DATALINK_LOGIN:
result = descriptor_UpdateSet(&dl->chat.desc, r, w, e, n);
switch (dl->chat.state) {
case CHAT_DONE:
/* script succeeded */
switch(dl->state) {
case DATALINK_HANGUP:
datalink_HangupDone(dl);
break;
case DATALINK_DIAL:
LogPrintf(LogPHASE, "%s: Entering LOGIN state\n", dl->name);
dl->state = DATALINK_LOGIN;
chat_Init(&dl->chat, dl->physical, VarLoginScript, 0);
break;
case DATALINK_LOGIN:
dl->dial_tries = 0;
if (modem_Raw(dl->physical, dl->bundle) < 0) {
LogPrintf(LogWARN, "PacketMode: Not connected.\n");
LogPrintf(LogPHASE, "%s: Entering HANGUP state\n", dl->name);
dl->state = DATALINK_HANGUP;
modem_Offline(dl->physical);
chat_Init(&dl->chat, dl->physical, VarHangupScript, 1);
} else {
LogPrintf(LogPHASE, "%s: Entering OPEN state\n", dl->name);
dl->state = DATALINK_OPEN;
dl->dial_tries = -1;
PacketMode(dl->bundle, VarOpenMode);
}
break;
}
break;
case CHAT_FAILED:
/* Going down - script failed */
LogPrintf(LogWARN, "Chat script failed\n");
switch(dl->state) {
case DATALINK_HANGUP:
datalink_HangupDone(dl);
break;
case DATALINK_DIAL:
case DATALINK_LOGIN:
LogPrintf(LogPHASE, "%s: Entering HANGUP state\n", dl->name);
dl->state = DATALINK_HANGUP;
modem_Offline(dl->physical);
chat_Init(&dl->chat, dl->physical, VarHangupScript, 1);
break;
}
break;
}
break;
case DATALINK_OPEN:
result = descriptor_UpdateSet(&dl->physical->desc, r, w, e, n);
break;
}
return result;
}
static int
datalink_IsSet(struct descriptor *d, fd_set *fdset)
{
struct datalink *dl = descriptor2datalink(d);
switch (dl->state) {
case DATALINK_CLOSED:
break;
case DATALINK_HANGUP:
case DATALINK_DIAL:
case DATALINK_LOGIN:
return descriptor_IsSet(&dl->chat.desc, fdset);
case DATALINK_OPEN:
return descriptor_IsSet(&dl->physical->desc, fdset);
}
return 0;
}
static void
datalink_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset)
{
struct datalink *dl = descriptor2datalink(d);
switch (dl->state) {
case DATALINK_CLOSED:
break;
case DATALINK_HANGUP:
case DATALINK_DIAL:
case DATALINK_LOGIN:
descriptor_Read(&dl->chat.desc, bundle, fdset);
break;
case DATALINK_OPEN:
descriptor_Read(&dl->physical->desc, bundle, fdset);
break;
}
}
static void
datalink_Write(struct descriptor *d, const fd_set *fdset)
{
struct datalink *dl = descriptor2datalink(d);
switch (dl->state) {
case DATALINK_CLOSED:
break;
case DATALINK_HANGUP:
case DATALINK_DIAL:
case DATALINK_LOGIN:
descriptor_Write(&dl->chat.desc, fdset);
break;
case DATALINK_OPEN:
descriptor_Write(&dl->physical->desc, fdset);
break;
}
}
struct datalink *
datalink_Create(const char *name, struct bundle *bundle)
{
struct datalink *dl;
dl = (struct datalink *)malloc(sizeof(struct datalink));
if (dl == NULL)
return dl;
dl->desc.type = DATALINK_DESCRIPTOR;
dl->desc.next = NULL;
dl->desc.UpdateSet = datalink_UpdateSet;
dl->desc.IsSet = datalink_IsSet;
dl->desc.Read = datalink_Read;
dl->desc.Write = datalink_Write;
dl->state = DATALINK_CLOSED;
dl->bundle = bundle;
dl->next = NULL;
memset(&dl->dial_timer, '\0', sizeof dl->dial_timer);
dl->dial_tries = 0;
dl->name = strdup(name);
if ((dl->physical = modem_Create(dl->name)) == NULL) {
free(dl->name);
free(dl);
return NULL;
}
IpcpDefAddress();
LcpInit(dl->bundle, dl->physical);
CcpInit(dl->bundle, &dl->physical->link);
LogPrintf(LogPHASE, "%s: Entering CLOSED state\n", dl->name);
return dl;
}
struct datalink *
datalink_Destroy(struct datalink *dl)
{
struct datalink *result;
if (dl->state != DATALINK_CLOSED)
LogPrintf(LogERROR, "Oops, destroying a datalink in state %d\n", dl->state);
result = dl->next;
chat_Destroy(&dl->chat);
link_Destroy(&dl->physical->link);
free(dl->name);
free(dl);
return result;
}
void
datalink_Up(struct datalink *dl)
{
if (dl->state == DATALINK_CLOSED) {
LogPrintf(LogPHASE, "%s: Entering OPENING state\n", dl->name);
dl->state = DATALINK_OPENING;
dl->reconnect_tries = VarReconnectTries;
dl->dial_tries = VarDialTries;
}
}
void
datalink_Close(struct datalink *dl, int stay)
{
/* Please close */
FsmClose(&CcpInfo.fsm);
FsmClose(&LcpInfo.fsm);
if (stay) {
dl->dial_tries = -1;
dl->reconnect_tries = 0;
}
}
void
datalink_Down(struct datalink *dl, int stay)
{
/* Carrier is lost */
LogPrintf(LogPHASE, "datalink_Down: %sstay down\n", stay ? "" : "don't ");
FsmDown(&CcpInfo.fsm);
FsmClose(&CcpInfo.fsm);
FsmDown(&LcpInfo.fsm);
if (CleaningUp || stay)
FsmClose(&LcpInfo.fsm);
else
FsmOpen(&CcpInfo.fsm);
if (dl->state != DATALINK_CLOSED && dl->state != DATALINK_HANGUP) {
LogPrintf(LogPHASE, "%s: Entering HANGUP state\n", dl->name);
dl->state = DATALINK_HANGUP;
modem_Offline(dl->physical);
chat_Init(&dl->chat, dl->physical, VarHangupScript, 1);
}
if (stay) {
dl->dial_tries = -1;
dl->reconnect_tries = 0;
}
}
void
datalink_StayDown(struct datalink *dl)
{
dl->reconnect_tries = 0;
}

66
usr.sbin/ppp/datalink.h Normal file
View File

@ -0,0 +1,66 @@
/*-
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*/
#define DATALINK_CLOSED (0)
#define DATALINK_OPENING (1)
#define DATALINK_HANGUP (2)
#define DATALINK_DIAL (3)
#define DATALINK_LOGIN (4)
#define DATALINK_OPEN (5)
struct datalink {
struct descriptor desc; /* We play either a physical or a chat */
int state; /* Our DATALINK_* state */
struct physical *physical; /* Our link */
struct chat chat; /* For bringing the link up & down */
struct pppTimer dial_timer; /* For timing between opens & scripts */
int dial_tries; /* try again this number of times */
unsigned reconnect_tries; /* try again this number of times */
char *name; /* Our name */
#ifdef soon
struct lcp lcp; /* Our line control FSM */
struct ccp ccp; /* Our compression FSM */
#endif
struct bundle *bundle; /* for the moment */
struct datalink *next; /* Next in the list */
};
#define datalink2descriptor(dl) (&(dl)->desc)
#define descriptor2datalink(d) \
((d)->type == DATALINK_DESCRIPTOR ? (struct datalink *)(d) : NULL)
extern struct datalink *datalink_Create(const char *name, struct bundle *);
extern struct datalink *datalink_Destroy(struct datalink *);
extern void datalink_Up(struct datalink *);
extern void datalink_Close(struct datalink *, int);
extern void datalink_Down(struct datalink *, int);
extern void datalink_StayDown(struct datalink *);

View File

@ -23,13 +23,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: descriptor.h,v 1.1.2.4 1998/02/10 03:23:17 brian Exp $
* $Id: descriptor.h,v 1.1.2.5 1998/02/13 05:10:15 brian Exp $
*/
#define PHYSICAL_DESCRIPTOR (1)
#define SERVER_DESCRIPTOR (2)
#define PROMPT_DESCRIPTOR (3)
#define CHAT_DESCRIPTOR (4)
#define DATALINK_DESCRIPTOR (5)
struct descriptor {
int type;

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: fsm.c,v 1.27.2.8 1998/02/07 20:49:35 brian Exp $
* $Id: fsm.c,v 1.27.2.9 1998/02/09 19:20:45 brian Exp $
*
* TODO:
* o Refer loglevel for log output
@ -80,7 +80,7 @@ StoppedTimeout(void *v)
StopTimer(&fp->OpenTimer);
}
if (link_IsActive(fp->link))
link_Close(fp->link, fp->bundle, 0);
link_Close(fp->link, fp->bundle, 0, 1);
}
void

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ip.c,v 1.38.2.5 1998/02/02 19:32:07 brian Exp $
* $Id: ip.c,v 1.38.2.6 1998/02/07 20:49:38 brian Exp $
*
* TODO:
* o Return ICMP message for filterd packet
@ -72,8 +72,7 @@ static void
IdleTimeout(void *v)
{
LogPrintf(LogPHASE, "Idle timer expired.\n");
reconnect(RECON_FALSE);
bundle_Close(LcpInfo.fsm.bundle, &LcpInfo.fsm);
bundle_Close(LcpInfo.fsm.bundle, NULL, 1);
}
/*

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: lcp.c,v 1.55.2.13 1998/02/09 19:20:54 brian Exp $
* $Id: lcp.c,v 1.55.2.14 1998/02/10 03:23:22 brian Exp $
*
* TODO:
* o Limit data field length by MRU
@ -396,6 +396,7 @@ LcpLayerStart(struct fsm *fp)
{
/* We're about to start up ! */
LogPrintf(LogLCP, "LcpLayerStart\n");
LcpInfo.LcpFailedMagic = 0;
}
static void
@ -450,14 +451,6 @@ LcpLayerDown(struct fsm *fp)
LogPrintf(LogLCP, "LcpLayerDown\n");
}
void
LcpUp()
{
/* Lower layers are ready.... go */
LcpInfo.LcpFailedMagic = 0;
FsmUp(&LcpInfo.fsm);
}
void
LcpOpen(int open_mode)
{

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: lcp.h,v 1.16.2.6 1998/02/07 20:49:45 brian Exp $
* $Id: lcp.h,v 1.16.2.7 1998/02/08 11:04:57 brian Exp $
*
* TODO:
*/
@ -77,7 +77,6 @@ extern struct lcp LcpInfo;
#define fsm2lcp(fp) (fp->proto == PROTO_LCP ? (struct lcp *)fp : NULL)
extern void LcpInit(struct bundle *, struct physical *);
extern void LcpUp(void);
extern void LcpSendProtoRej(u_char *, int);
extern void LcpOpen(int);
extern int LcpPutConf(int, u_char *, const struct lcp_opt *, const char *,

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: link.c,v 1.1.2.4 1998/02/07 20:49:47 brian Exp $
* $Id: link.c,v 1.1.2.5 1998/02/10 03:23:24 brian Exp $
*
*/
@ -143,10 +143,10 @@ link_IsActive(struct link *l)
}
void
link_Close(struct link *l, struct bundle *bundle, int dedicated_force)
link_Close(struct link *l, struct bundle *bundle, int dedicated_force, int stay)
{
(*l->Close)(l, dedicated_force);
bundle_LinkLost(bundle, l);
bundle_LinkLost(bundle, l, stay);
}
void

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: link.h,v 1.1.2.2 1998/02/06 02:22:44 brian Exp $
* $Id: link.h,v 1.1.2.3 1998/02/07 20:49:48 brian Exp $
*
*/
@ -70,5 +70,5 @@ extern void link_ProtocolRecord(struct link *, u_short, int);
extern void link_ReportProtocolStatus(struct link *);
extern int link_IsActive(struct link *);
extern void link_Close(struct link *, struct bundle *, int);
extern void link_Close(struct link *, struct bundle *, int, int);
extern void link_Destroy(struct link *);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: lqr.c,v 1.22.2.6 1998/02/07 20:49:50 brian Exp $
* $Id: lqr.c,v 1.22.2.7 1998/02/09 19:20:56 brian Exp $
*
* o LQR based on RFC1333
*
@ -130,8 +130,7 @@ SendLqrReport(void *v)
*/
LogPrintf(LogPHASE, "** 1 Too many ECHO packets are lost. **\n");
lqmmethod = 0; /* Prevent rcursion via bundle_Close() */
reconnect(RECON_TRUE);
bundle_Close(LcpInfo.fsm.bundle, &LcpInfo.fsm);
bundle_Close(LcpInfo.fsm.bundle, NULL, 1);
} else {
bp = mballoc(sizeof(struct lqrdata), MB_LQR);
HdlcOutput(physical2link(physical), PRI_LINK, PROTO_LQR, bp);
@ -141,8 +140,7 @@ SendLqrReport(void *v)
if (echoseq - gotseq > 5) {
LogPrintf(LogPHASE, "** 2 Too many ECHO packets are lost. **\n");
lqmmethod = 0; /* Prevent rcursion via bundle_Close() */
reconnect(RECON_TRUE);
bundle_Close(LcpInfo.fsm.bundle, &LcpInfo.fsm);
bundle_Close(LcpInfo.fsm.bundle, NULL, 1);
} else
SendEchoReq();
}

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: main.c,v 1.121.2.20 1998/02/10 22:28:51 brian Exp $
* $Id: main.c,v 1.121.2.21 1998/02/13 05:10:16 brian Exp $
*
* TODO:
* o Add commands for traffic summary, version display, etc.
@ -80,6 +80,7 @@
#include "server.h"
#include "prompt.h"
#include "chat.h"
#include "datalink.h"
#ifndef O_NONBLOCK
#ifdef O_NDELAY
@ -89,8 +90,6 @@
static pid_t BGPid = 0;
static char pid_filename[MAXPATHLEN];
int dial_up;
int dialing;
static void DoLoop(struct bundle *);
static void TerminalStop(int);
@ -103,12 +102,8 @@ void
Cleanup(int excode)
{
CleaningUp = 1;
reconnect(RECON_FALSE);
if (bundle_Phase(SignalBundle) != PHASE_DEAD) {
bundle_Close(SignalBundle, NULL);
return;
}
AbortProgram(excode);
if (bundle_Phase(SignalBundle) != PHASE_DEAD)
bundle_Close(SignalBundle, NULL, 0);
}
void
@ -128,9 +123,8 @@ AbortProgram(int excode)
}
LogPrintf(LogPHASE, "PPP Terminated (%s).\n", ex_desc(excode));
prompt_TtyOldMode(&prompt);
link_Destroy(physical2link(SignalBundle->physical));
LogClose();
bundle_Destroy(SignalBundle);
LogClose();
exit(excode);
}
@ -140,10 +134,8 @@ CloseConnection(int signo)
/* NOTE, these are manual, we've done a setsid() */
pending_signal(SIGINT, SIG_IGN);
LogPrintf(LogPHASE, "Caught signal %d, abort connection\n", signo);
reconnectState = RECON_FALSE;
reconnectCount = 0;
link_Close(&SignalBundle->physical->link, SignalBundle, 0);
dial_up = 0;
/* XXX close 'em all ! */
link_Close(bundle2link(SignalBundle, NULL), SignalBundle, 0, 1);
pending_signal(SIGINT, CloseConnection);
}
@ -511,213 +503,56 @@ main(int argc, char **argv)
void
PacketMode(struct bundle *bundle, int delay)
{
if (modem_Raw(bundle->physical) < 0) {
LogPrintf(LogWARN, "PacketMode: Not connected.\n");
return;
}
LcpInit(bundle, bundle->physical);
IpcpInit(bundle, physical2link(bundle->physical));
CcpInit(bundle, physical2link(bundle->physical));
LcpUp();
/* XXX which one ? */
LcpInit(bundle, bundle2physical(bundle, NULL));
CcpInit(bundle, bundle2link(bundle, NULL));
FsmUp(&LcpInfo.fsm);
LcpOpen(delay);
prompt_TtyCommandMode(&prompt);
prompt_Printf(&prompt, "Packet mode.\n");
}
static struct pppTimer RedialTimer;
static void
RedialTimeout(void *v)
{
StopTimer(&RedialTimer);
LogPrintf(LogPHASE, "Redialing timer expired.\n");
}
static void
StartRedialTimer(int Timeout)
{
StopTimer(&RedialTimer);
if (Timeout) {
RedialTimer.state = TIMER_STOPPED;
if (Timeout > 0)
RedialTimer.load = Timeout * SECTICKS;
else
RedialTimer.load = (random() % REDIAL_PERIOD) * SECTICKS;
LogPrintf(LogPHASE, "Enter pause (%d) for redialing.\n",
RedialTimer.load / SECTICKS);
RedialTimer.func = RedialTimeout;
StartTimer(&RedialTimer);
}
}
static void
DoLoop(struct bundle *bundle)
{
fd_set rfds, wfds, efds;
int pri, i, n, wfd, nfds;
struct timeval timeout, *tp;
const u_char *cp;
int tries;
int pri, i, n, nfds;
struct timeval timeout;
int qlen;
int res;
struct tun_data tun;
#define rbuff tun.data
if (mode & MODE_DIRECT) {
LogPrintf(LogDEBUG, "Opening modem\n");
if (modem_Open(bundle->physical, bundle) < 0)
if (modem_Open(bundle2physical(bundle, NULL), bundle) < 0)
return;
LogPrintf(LogPHASE, "Packet mode enabled\n");
PacketMode(bundle, VarOpenMode);
} else if (mode & MODE_DEDICATED) {
if (!link_IsActive(physical2link(bundle->physical)))
while (modem_Open(bundle->physical, bundle) < 0)
if (!link_IsActive(bundle2link(bundle, NULL)))
while (modem_Open(bundle2physical(bundle, NULL), bundle) < 0)
nointr_sleep(VarReconnectTimer);
}
timeout.tv_sec = 0;
timeout.tv_usec = 0;
reconnectState = RECON_UNKNOWN;
if (mode & MODE_BACKGROUND)
dial_up = 1; /* Bring the line up */
else
dial_up = 0; /* XXXX */
tries = 0;
for (;;) {
bundle_Open(bundle, NULL);
while (!CleaningUp || bundle_Phase(SignalBundle) != PHASE_DEAD) {
nfds = 0;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&efds);
/*
* If the link is down and we're in DDIAL mode, bring it back up.
*/
if (mode & MODE_DDIAL && LcpInfo.fsm.state <= ST_CLOSED)
dial_up = 1;
/*
* If we lost carrier and want to re-establish the connection due to the
* "set reconnect" value, we'd better bring the line back up.
*/
if (!dialing && LcpInfo.fsm.state <= ST_CLOSED) {
if (!dial_up && reconnectState == RECON_TRUE) {
if (++reconnectCount <= VarReconnectTries) {
LogPrintf(LogPHASE, "Connection lost, re-establish (%d/%d)\n",
reconnectCount, VarReconnectTries);
StartRedialTimer(VarReconnectTimer);
dial_up = 1;
} else {
if (VarReconnectTries)
LogPrintf(LogPHASE, "Connection lost, maximum (%d) times\n",
VarReconnectTries);
reconnectCount = 0;
if (mode & MODE_BACKGROUND)
Cleanup(EX_DEAD);
}
reconnectState = RECON_ENVOKED;
} else if (mode & MODE_DEDICATED)
PacketMode(bundle, VarOpenMode);
}
/*
* If Ip packet for output is enqueued and require dial up, Just do it!
*/
if (dial_up && !dialing && RedialTimer.state != TIMER_RUNNING) {
LogPrintf(LogDEBUG, "going to dial: modem = %d\n",
Physical_GetFD(bundle->physical));
if (modem_Open(bundle->physical, bundle) < 0) {
tries++;
if (!(mode & MODE_DDIAL) && VarDialTries)
LogPrintf(LogCHAT, "Failed to open modem (attempt %u of %d)\n",
tries, VarDialTries);
else
LogPrintf(LogCHAT, "Failed to open modem (attempt %u)\n", tries);
if (!(mode & MODE_DDIAL) && VarDialTries && tries >= VarDialTries) {
if (mode & MODE_BACKGROUND)
Cleanup(EX_DIAL); /* Can't get the modem */
dial_up = 0;
reconnectState = RECON_UNKNOWN;
reconnectCount = 0;
tries = 0;
} else
StartRedialTimer(VarRedialTimeout);
} else {
tries++; /* Tries are per number, not per list of
* numbers. */
if (!(mode & MODE_DDIAL) && VarDialTries)
LogPrintf(LogCHAT, "Dial attempt %u of %d\n", tries, VarDialTries);
else
LogPrintf(LogCHAT, "Dial attempt %u\n", tries);
chat_Init(&chat, bundle->physical, VarDialScript, 1);
dialing = 1;
dial_up = 0;
}
}
qlen = link_QueueLen(physical2link(bundle->physical));
if (qlen == 0) {
IpStartOutput(physical2link(bundle->physical));
qlen = link_QueueLen(physical2link(bundle->physical));
}
qlen = bundle_FillQueues(bundle);
handle_signals();
if (dialing) {
descriptor_UpdateSet(&chat.desc, &rfds, &wfds, &efds, &nfds);
if (dialing == -1) {
if (chat.state == CHAT_DONE || chat.state == CHAT_FAILED) {
dialing = 0;
modem_Close(bundle->physical);
if (mode & MODE_BACKGROUND) {
if (VarNextPhone == NULL || res == EX_SIG)
Cleanup(EX_DIAL); /* Tried all numbers - no luck */
else
/* Try all numbers in background mode */
StartRedialTimer(VarRedialNextTimeout);
} else if (!(mode & MODE_DDIAL) &&
((VarDialTries && tries >= VarDialTries) ||
res == EX_SIG)) {
/* I give up ! Can't get through :( */
StartRedialTimer(VarRedialTimeout);
dial_up = 0;
reconnectState = RECON_UNKNOWN;
reconnectCount = 0;
tries = 0;
} else if (VarNextPhone == NULL)
/* Dial failed. Keep quite during redial wait period. */
StartRedialTimer(VarRedialTimeout);
else
StartRedialTimer(VarRedialNextTimeout);
continue;
}
} else if (chat.state == CHAT_DONE) {
if (dialing == 1) {
chat_Init(&chat, bundle->physical, VarLoginScript, 0);
dialing++;
continue;
} else {
PacketMode(bundle, VarOpenMode);
reconnectState = RECON_UNKNOWN;
tries = 0;
dialing = 0;
}
} else if (chat.state == CHAT_FAILED) {
chat_Init(&chat, bundle->physical, VarHangupScript, 0);
dialing = -1;
continue;
}
}
if (!dialing)
descriptor_UpdateSet(&bundle->physical->desc, &rfds, &wfds, &efds, &nfds);
bundle_UpdateSet(bundle, &rfds, &wfds, &efds, &nfds);
descriptor_UpdateSet(&server.desc, &rfds, &wfds, &efds, &nfds);
#ifndef SIGALRM
@ -741,29 +576,10 @@ DoLoop(struct bundle *bundle)
descriptor_UpdateSet(&prompt.desc, &rfds, &wfds, &efds, &nfds);
#ifndef SIGALRM
i = select(nfds, &rfds, &wfds, &efds, NULL);
/*
* Normally, select() will not block because modem is writable. In AUTO
* mode, select will block until we find packet from tun
*/
tp = (RedialTimer.state == TIMER_RUNNING) ? &timeout : NULL;
i = select(nfds, &rfds, &wfds, &efds, tp);
#else
/*
* When SIGALRM timer is running, the select function will return -1 and
* EINTR after the Time Service signal handler is done. If the redial
* timer is not running and we are trying to dial, poll with a 0 value
* timer.
*/
tp = (dial_up && RedialTimer.state != TIMER_RUNNING) ? &timeout : NULL;
i = select(nfds, &rfds, &wfds, &efds, tp);
#endif
if (i == 0) {
if (i == 0)
continue;
}
if (i < 0) {
if (errno == EINTR) {
@ -774,11 +590,11 @@ DoLoop(struct bundle *bundle)
break;
}
if (descriptor_IsSet(&prompt.desc, &efds) ||
descriptor_IsSet(&bundle->physical->desc, &efds)) {
LogPrintf(LogALERT, "Exception detected.\n");
break;
}
for (i = 0; i <= nfds; i++)
if (FD_ISSET(i, &efds)) {
LogPrintf(LogALERT, "Exception detected on descriptor %d\n", i);
break;
}
if (descriptor_IsSet(&server.desc, &rfds))
descriptor_Read(&server.desc, bundle, &rfds);
@ -786,22 +602,11 @@ DoLoop(struct bundle *bundle)
if (descriptor_IsSet(&prompt.desc, &rfds))
descriptor_Read(&prompt.desc, bundle, &rfds);
if (dialing) {
if (descriptor_IsSet(&chat.desc, &wfds))
descriptor_Write(&chat.desc, &wfds);
if (descriptor_IsSet(&chat.desc, &rfds))
descriptor_Read(&chat.desc, bundle, &rfds);
} else {
if (descriptor_IsSet(&bundle->physical->desc, &wfds)) {
/* ready to write into modem */
descriptor_Write(&bundle->physical->desc, &wfds);
if (!link_IsActive(physical2link(bundle->physical)))
dial_up = 1;
}
if (descriptor_IsSet(&bundle->physical->desc, &rfds))
descriptor_Read(&bundle->physical->desc, bundle, &rfds);
}
/* XXX FIX ME ! */
if (descriptor_IsSet(&bundle2datalink(bundle, NULL)->desc, &wfds))
descriptor_Write(&bundle2datalink(bundle, NULL)->desc, &wfds);
if (descriptor_IsSet(&bundle2datalink(bundle, NULL)->desc, &rfds))
descriptor_Read(&bundle2datalink(bundle, NULL)->desc, bundle, &rfds);
if (bundle->tun_fd >= 0 && FD_ISSET(bundle->tun_fd, &rfds)) {
/* something to read from tun */
@ -846,7 +651,7 @@ DoLoop(struct bundle *bundle)
*/
if (LcpInfo.fsm.state <= ST_CLOSED && (mode & MODE_AUTO) &&
(pri = PacketCheck(rbuff, n, FL_DIAL)) >= 0)
dial_up = 1;
bundle_Open(bundle, NULL);
pri = PacketCheck(rbuff, n, FL_OUT);
if (pri >= 0) {

View File

@ -17,13 +17,11 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: main.h,v 1.9.2.4 1998/02/10 03:23:31 brian Exp $
* $Id: main.h,v 1.9.2.5 1998/02/13 05:10:18 brian Exp $
*
*/
extern int CleaningUp;
extern int dial_up;
extern int dialing;
extern void Cleanup(int);
extern void AbortProgram(int);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: mbuf.c,v 1.13.2.3 1998/02/09 19:24:01 brian Exp $
* $Id: mbuf.c,v 1.13.2.4 1998/02/10 03:23:33 brian Exp $
*
*/
#include <sys/param.h>
@ -26,6 +26,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <termios.h>
#include "command.h"
@ -36,6 +37,7 @@
#include "vars.h"
#include "descriptor.h"
#include "prompt.h"
#include "main.h"
static struct memmap {
struct mbuf *queue;
@ -65,15 +67,13 @@ mballoc(int cnt, int type)
bp = (struct mbuf *) malloc(sizeof(struct mbuf));
if (bp == NULL) {
LogPrintf(LogALERT, "failed to allocate memory: %u\n", sizeof(struct mbuf));
ServerClose();
exit(1);
AbortProgram(EX_OSERR);
}
memset(bp, '\0', sizeof(struct mbuf));
p = (u_char *) malloc(cnt);
if (p == NULL) {
LogPrintf(LogALERT, "failed to allocate memory: %d\n", cnt);
ServerClose();
exit(1);
AbortProgram(EX_OSERR);
}
MemMap[type].count += cnt;
totalalloced += cnt;

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: modem.c,v 1.77.2.14 1998/02/10 03:23:35 brian Exp $
* $Id: modem.c,v 1.77.2.15 1998/02/13 05:10:19 brian Exp $
*
* TODO:
*/
@ -246,13 +246,12 @@ modem_Timeout(void *data)
if (to->modem->abort) {
/* Something went horribly wrong */
to->modem->abort = 0;
link_Close(&to->modem->link, to->bundle, 0);
link_Close(&to->modem->link, to->bundle, 0, 0);
} else if (to->modem->dev_is_modem) {
if (to->modem->fd >= 0) {
if (ioctl(to->modem->fd, TIOCMGET, &to->modem->mbits) < 0) {
LogPrintf(LogPHASE, "ioctl error (%s)!\n", strerror(errno));
reconnect(RECON_TRUE);
link_Close(&to->modem->link, to->bundle, 0);
link_Close(&to->modem->link, to->bundle, 0, 0);
return;
}
} else
@ -274,8 +273,7 @@ modem_Timeout(void *data)
#endif
} else {
LogPrintf(LogDEBUG, "modem_Timeout: online -> offline\n");
reconnect(RECON_TRUE);
link_Close(&to->modem->link, to->bundle, 0);
link_Close(&to->modem->link, to->bundle, 0, 0);
}
}
else
@ -666,8 +664,9 @@ modem_Speed(struct physical *modem)
* Put modem tty line into raw mode which is necessary in packet mode operation
*/
int
modem_Raw(struct physical *modem)
modem_Raw(struct physical *modem, struct bundle *bundle)
{
struct timeoutArg to;
struct termios rstio;
int oldflag;
@ -703,7 +702,12 @@ modem_Raw(struct physical *modem)
if (oldflag < 0)
return (-1);
(void) fcntl(modem->fd, F_SETFL, oldflag | O_NONBLOCK);
return (0);
to.modem = modem;
to.bundle = bundle;
modem_Timeout(&to);
return Online(modem) ? 0 : -1;
}
static void
@ -734,49 +738,53 @@ static int force_hack;
static void
modem_Hangup(struct link *l, int dedicated_force)
{
/* We're about to close (pre hangup script) */
struct physical *modem = (struct physical *)l;
force_hack = dedicated_force;
if (modem->fd >= 0 && dialing != -1) {
if (modem->fd >= 0) {
StopTimer(&modem->link.Timer);
throughput_stop(&modem->link.throughput);
if (prompt_IsTermMode(&prompt))
prompt_TtyCommandMode(&prompt);
}
}
dialing = -1;
dial_up = 0;
chat_Init(&chat, modem, VarHangupScript, 1);
void
modem_Offline(struct physical *modem)
{
if (modem->fd >= 0) {
struct termios tio;
modem->mbits &= ~TIOCM_DTR;
if (isatty(modem->fd) && Online(modem)) {
tcgetattr(modem->fd, &tio);
if (cfsetspeed(&tio, B0) == -1)
LogPrintf(LogWARN, "Unable to set modem to speed 0\n");
else
tcsetattr(modem->fd, TCSANOW, &tio);
/* nointr_sleep(1); */
}
}
}
void
modem_Close(struct physical *modem)
{
struct termios tio;
LogPrintf(LogDEBUG, "Hangup modem (%s)\n",
LogPrintf(LogDEBUG, "Close modem (%s)\n",
modem->fd >= 0 ? "open" : "closed");
if (modem->fd < 0)
return;
modem_Offline(modem);
if (!isatty(modem->fd)) {
modem->mbits &= ~TIOCM_DTR;
modem_PhysicalClose(modem);
return;
}
if (modem->fd >= 0 && Online(modem)) {
modem->mbits &= ~TIOCM_DTR;
tcgetattr(modem->fd, &tio);
if (cfsetspeed(&tio, B0) == -1) {
LogPrintf(LogWARN, "Unable to set modem to speed 0\n");
}
tcsetattr(modem->fd, TCSANOW, &tio);
nointr_sleep(1);
}
if (modem->fd >= 0) {
if (force_hack ||
#ifdef notyet
@ -806,7 +814,7 @@ modem_Destroy(struct link *l)
p = link2physical(l);
if (p->fd != -1)
modem_Hangup(l, 1);
modem_Close(p);
free(l->name);
free(p);
}
@ -863,7 +871,6 @@ modem_StartOutput(struct link *l)
if (errno != EAGAIN) {
LogPrintf(LogERROR, "modem write (%d): %s\n", modem->fd,
strerror(errno));
reconnect(RECON_TRUE);
modem->abort = 1;
}
}
@ -880,7 +887,7 @@ int
modem_ShowStatus(struct cmdargs const *arg)
{
const char *dev;
struct physical *modem = arg->bundle->physical;
struct physical *modem = bundle2physical(arg->bundle, NULL);
#ifdef TIOCOUTQ
int nb;
#endif
@ -963,10 +970,9 @@ modem_DescriptorRead(struct descriptor *d, struct bundle *bundle,
nointr_usleep(10000);
n = Physical_Read(p, rbuff, sizeof rbuff);
if ((mode & MODE_DIRECT) && n <= 0) {
reconnect(RECON_TRUE);
link_Close(&p->link, bundle, 0);
} else
if ((mode & MODE_DIRECT) && n <= 0)
link_Close(&p->link, bundle, 0, 1);
else
LogDumpBuff(LogASYNC, "ReadFromModem", rbuff, n);
if (LcpInfo.fsm.state <= ST_CLOSED) {

View File

@ -15,14 +15,14 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: modem.h,v 1.16.2.5 1998/02/06 02:22:51 brian Exp $
* $Id: modem.h,v 1.16.2.6 1998/02/13 05:10:21 brian Exp $
*
* TODO:
*/
struct physical;
extern int modem_Raw(struct physical *);
extern int modem_Raw(struct physical *, struct bundle *);
extern struct physical *modem_Create(const char *);
extern int modem_Open(struct physical *, struct bundle *);
extern int modem_Speed(struct physical *);
@ -30,3 +30,4 @@ extern speed_t IntToSpeed(int);
extern int modem_SetParity(struct physical *, const char *);
extern int modem_ShowStatus(struct cmdargs const *);
extern void modem_Close(struct physical *);
extern void modem_Offline(struct physical *);

View File

@ -18,7 +18,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: pap.c,v 1.20.2.7 1998/02/07 20:50:01 brian Exp $
* $Id: pap.c,v 1.20.2.8 1998/02/09 19:21:05 brian Exp $
*
* TODO:
*/
@ -196,8 +196,7 @@ PapInput(struct bundle *bundle, struct mbuf *bp, struct physical *physical)
} else {
SendPapCode(php->id, PAP_NAK, "Login incorrect", physical);
reconnect(RECON_FALSE);
bundle_Close(bundle, &LcpInfo.fsm);
link_Close(&physical->link, bundle, 1, 1);
}
break;
case PAP_ACK:
@ -223,8 +222,7 @@ PapInput(struct bundle *bundle, struct mbuf *bp, struct physical *physical)
len = *cp++;
cp[len] = 0;
LogPrintf(LogPHASE, "Received PAP_NAK (%s)\n", cp);
reconnect(RECON_FALSE);
bundle_Close(bundle, &LcpInfo.fsm);
link_Close(&physical->link, bundle, 1, 1);
break;
}
}

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: physical.c,v 1.1.2.7 1998/02/10 03:22:02 brian Exp $
* $Id: physical.c,v 1.1.2.8 1998/02/13 05:10:22 brian Exp $
*
*/
@ -173,7 +173,7 @@ Physical_Write(struct physical *phys, const void *buf, size_t nbytes) {
int
Physical_ReportProtocolStatus(struct cmdargs const *arg)
{
link_ReportProtocolStatus(&arg->bundle->physical->link);
link_ReportProtocolStatus(bundle2link(arg->bundle, NULL));
return 0;
}

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: prompt.c,v 1.1.2.1 1998/02/10 03:23:38 brian Exp $
* $Id: prompt.c,v 1.1.2.2 1998/02/13 05:10:23 brian Exp $
*/
#include <sys/param.h>
@ -52,6 +52,11 @@
#include "iplist.h"
#include "throughput.h"
#include "ipcp.h"
#include "hdlc.h"
#include "async.h"
#include "mbuf.h"
#include "link.h"
#include "physical.h"
static int prompt_nonewline = 1;
@ -146,7 +151,7 @@ prompt_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset)
ttystate++;
else
/* XXX missing return value check */
Physical_Write(bundle->physical, &ch, n);
Physical_Write(bundle2physical(bundle, NULL), &ch, n);
break;
case 1:
switch (ch) {
@ -178,7 +183,7 @@ prompt_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset)
break;
}
default:
if (Physical_Write(bundle->physical, &ch, n) < 0)
if (Physical_Write(bundle2physical(bundle, NULL), &ch, n) < 0)
LogPrintf(LogERROR, "error writing to modem.\n");
break;
}
@ -231,7 +236,7 @@ prompt_Init(struct prompt *p, int fd)
return 1;
}
int
void
prompt_Display(struct prompt *p, struct bundle *bundle)
{
const char *pconnect, *pauth;

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: prompt.h,v 1.1.2.1 1998/02/10 03:23:39 brian Exp $
*/
struct prompt {
@ -46,7 +46,7 @@ extern struct prompt prompt;
#define PROMPT_NONE -2
#define PROMPT_STD -1
extern int prompt_Init(struct prompt *, int);
extern int prompt_Display(struct prompt *, struct bundle *);
extern void prompt_Display(struct prompt *, struct bundle *);
extern void prompt_Drop(struct prompt *, int);
extern void prompt_Printf(struct prompt *, const char *, ...);
extern void prompt_vPrintf(struct prompt *, const char *, _BSD_VA_LIST_);

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: server.c,v 1.16.2.4 1998/02/10 03:23:41 brian Exp $
* $Id: server.c,v 1.16.2.5 1998/02/13 05:10:24 brian Exp $
*/
#include <sys/param.h>
@ -50,6 +50,8 @@
#include "server.h"
#include "id.h"
#include "prompt.h"
#include "timer.h"
#include "auth.h"
static int
server_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: vars.c,v 1.45.2.6 1998/02/10 03:23:49 brian Exp $
* $Id: vars.c,v 1.45.2.7 1998/02/13 05:10:26 brian Exp $
*
*/
#include <sys/param.h>
@ -46,11 +46,9 @@
#include "prompt.h"
char VarVersion[] = "PPP Version 2.0-beta";
char VarLocalVersion[] = "$Date: 1998/02/10 03:23:49 $";
char VarLocalVersion[] = "$Date: 1998/02/13 05:10:26 $";
int Utmp = 0;
int ipKeepAlive = 0;
int reconnectState = RECON_UNKNOWN;
int reconnectCount = 0;
/*
* Order of conf option is important. See vars.h.

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: vars.h,v 1.42.2.2 1998/02/06 02:23:48 brian Exp $
* $Id: vars.h,v 1.42.2.3 1998/02/10 03:23:50 brian Exp $
*
* TODO:
*/
@ -159,6 +159,7 @@ extern char VarLocalVersion[];
extern int Utmp; /* Are we in /etc/utmp ? */
extern int ipKeepAlive;
#if 0
extern int reconnectState;
extern int reconnectCount;
@ -198,6 +199,7 @@ extern int reconnectCount;
* connection, we set reconnectCount back to zero.
*
*/
#endif
extern int EnableCommand(struct cmdargs const *);
extern int DisableCommand(struct cmdargs const *);