o Hook the FSMs into our bundle.

o The FSM layering is now more sane.
o Move a lot of the NCP stuff into our ipcpstate rather than having it
  in the bundle, including control of the configured IP addresses.  We
  don't need hacks like the global `linkup' variable any more as the
  FSM decides when our ppp.link* files get run.  This is going to eventually
  be configurable based on FSM events anyway.
o Fix a few inconsistencies when both sides require authentication.
o We now have "Ppp..." and "PPp" prompts, reflecting authentication
  and network phase.  We don't print loads of spurious prompts as we
  change phases any more.
o Our phase is part of the bundle now.
o Fix a bug where the FSM wasn't calling LayerFinish.
o Close the FSM down correctly with a signal rather than slamming it
  down as if the line was dropped (the undocumented ``down'' command
  is still available though).
o Remove the forgotten `tunno' variable and fix references to it.
This commit is contained in:
Brian Somers 1998-02-07 20:50:08 +00:00
parent 83d1af558c
commit 455aabc3f8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/MP/; revision=33162
30 changed files with 640 additions and 635 deletions

View File

@ -1,9 +1,9 @@
# $Id: Makefile,v 1.36.2.3 1998/02/02 19:31:59 brian Exp $
# $Id: Makefile,v 1.36.2.4 1998/02/06 02:23:26 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 phase.c physical.c \
link.c log.c lqr.c main.c mbuf.c modem.c pap.c physical.c \
pred.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
@ -41,5 +41,3 @@ chap_ms.o alias_cmd.o loadalias.o:
.endif
.include <bsd.prog.mk>
STRIP=

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: arp.c,v 1.27 1998/01/24 00:03:14 brian Exp $
* $Id: arp.c,v 1.27.2.1 1998/02/02 19:32:56 brian Exp $
*
*/
@ -52,27 +52,14 @@
#include "id.h"
#include "route.h"
#include "bundle.h"
#include "timer.h"
#include "fsm.h"
#include "throughput.h"
#include "defs.h"
#include "iplist.h"
#include "ipcp.h"
#include "arp.h"
#ifdef DEBUG
/*
* To test the proxy arp stuff, just
*
* cc -o arp-test -DDEBUG arp.c
*
*/
#define LogIsKept(x) 1
#define LogPrintf fprintf
#undef LogDEBUG
#define LogDEBUG stderr
#undef LogERROR
#define LogERROR stderr
#undef LogPHASE
#define LogPHASE stdout
#define ID0socket socket
#define ID0ioctl ioctl
#endif
static int get_ether_addr(int, struct in_addr, struct sockaddr_dl *);
/*
@ -100,7 +87,7 @@ static struct {
static int arpmsg_valid;
int
sifproxyarp(struct bundle *bundle, int s)
sifproxyarp(struct bundle *bundle, struct ipcpstate *ipcp, int s)
{
int routes;
@ -109,7 +96,7 @@ sifproxyarp(struct bundle *bundle, int s)
* address.
*/
memset(&arpmsg, 0, sizeof arpmsg);
if (!get_ether_addr(s, bundle->if_peer, &arpmsg.hwa)) {
if (!get_ether_addr(s, ipcp->if_peer, &arpmsg.hwa)) {
LogPrintf(LogERROR, "Cannot determine ethernet address for proxy ARP\n");
return 0;
}
@ -127,7 +114,7 @@ sifproxyarp(struct bundle *bundle, int s)
arpmsg.hdr.rtm_inits = RTV_EXPIRE;
arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp);
arpmsg.dst.sin_family = AF_INET;
arpmsg.dst.sin_addr.s_addr = bundle->if_peer.s_addr;
arpmsg.dst.sin_addr.s_addr = ipcp->if_peer.s_addr;
arpmsg.dst.sin_other = SIN_PROXY;
arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg
@ -146,7 +133,7 @@ sifproxyarp(struct bundle *bundle, int s)
* cifproxyarp - Delete the proxy ARP entry for the peer.
*/
int
cifproxyarp(struct bundle *bundle, int s)
cifproxyarp(struct bundle *bundle, struct ipcpstate *ipcp, int s)
{
int routes;
@ -178,7 +165,7 @@ cifproxyarp(struct bundle *bundle, int s)
* sifproxyarp - Make a proxy ARP entry for the peer.
*/
int
sifproxyarp(struct bundle *bundle, int s)
sifproxyarp(struct bundle *bundle, struct ipcpstate *ipcp, int s)
{
struct arpreq arpreq;
struct {
@ -192,7 +179,7 @@ sifproxyarp(struct bundle *bundle, int s)
* Get the hardware address of an interface on the same subnet as our local
* address.
*/
if (!get_ether_addr(s, bundle->if_peer, &dls.sdl)) {
if (!get_ether_addr(s, ipcp->if_peer, &dls.sdl)) {
LogPrintf(LOG_PHASE_BIT, "Cannot determine ethernet address for proxy ARP\n");
return 0;
}
@ -201,7 +188,7 @@ sifproxyarp(struct bundle *bundle, int s)
memcpy(arpreq.arp_ha.sa_data, LLADDR(&dls.sdl), dls.sdl.sdl_alen);
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
((struct sockaddr_in *)&arpreq.arp_pa)->sin_addr.s_addr =
bundle->if_peer.s_addr;
ipcp->if_peer.s_addr;
arpreq.arp_flags = ATF_PERM | ATF_PUBL;
if (ID0ioctl(s, SIOCSARP, (caddr_t) & arpreq) < 0) {
LogPrintf(LogERROR, "sifproxyarp: ioctl(SIOCSARP): %s\n", strerror(errno));
@ -214,14 +201,14 @@ sifproxyarp(struct bundle *bundle, int s)
* cifproxyarp - Delete the proxy ARP entry for the peer.
*/
int
cifproxyarp(struct bundle *bundle, int s)
cifproxyarp(struct bundle *bundle, struct ipcpstate *ipcp, int s)
{
struct arpreq arpreq;
memset(&arpreq, '\0', sizeof arpreq);
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
((struct sockaddr_in *)&arpreq.arp_pa)->sin_addr.s_addr =
bundle->if_peer.s_addr;
ipcp->if_peer.s_addr;
if (ID0ioctl(s, SIOCDARP, (caddr_t) & arpreq) < 0) {
LogPrintf(LogERROR, "cifproxyarp: ioctl(SIOCDARP): %s\n", strerror(errno));
return 0;
@ -338,19 +325,3 @@ get_ether_addr(int s, struct in_addr ipaddr, struct sockaddr_dl *hwaddr)
return 0;
}
#ifdef DEBUG
int
main(int argc, char **argv)
{
struct in_addr ipaddr;
int s, f;
s = socket(AF_INET, SOCK_DGRAM, 0);
for (f = 1; f < argc; f++) {
if (inet_aton(argv[f], &ipaddr))
sifproxyarp(s, ipaddr);
}
close(s);
}
#endif

View File

@ -17,9 +17,11 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: arp.h,v 1.7 1998/01/19 02:59:32 brian Exp $
* $Id: arp.h,v 1.7.2.1 1998/02/02 19:32:57 brian Exp $
*
*/
extern int cifproxyarp(struct bundle *, int);
extern int sifproxyarp(struct bundle *, int);
struct ipcp;
extern int cifproxyarp(struct bundle *, struct ipcpstate *, int);
extern int sifproxyarp(struct bundle *, struct ipcpstate *, int);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: auth.c,v 1.27.2.4 1998/02/02 19:32:00 brian Exp $
* $Id: auth.c,v 1.27.2.5 1998/02/02 19:33:33 brian Exp $
*
* TODO:
* o Implement check against with registered IP addresses.
@ -49,6 +49,21 @@
#include "async.h"
#include "link.h"
#include "physical.h"
#include "lcpproto.h"
const char *
Auth2Nam(u_short auth)
{
switch (auth) {
case PROTO_PAP:
return "PAP";
case PROTO_CHAP:
return "CHAP";
case 0:
return "none";
}
return "unknown";
}
void
LocalAuthInit()

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: auth.h,v 1.10.2.1 1998/01/29 00:49:12 brian Exp $
* $Id: auth.h,v 1.10.2.2 1998/02/02 19:32:01 brian Exp $
*
* TODO:
*/
@ -36,6 +36,7 @@ struct authinfo {
struct physical *physical;
};
extern const char *Auth2Nam(u_short);
extern LOCAL_AUTH_VALID LocalAuthValidate(const char *, const char *, const char *);
extern void StopAuthTimer(struct authinfo *);
extern void StartAuthChallenge(struct authinfo *, struct physical *);

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.3 1998/02/06 02:23:28 brian Exp $
* $Id: bundle.c,v 1.1.2.4 1998/02/06 02:24:01 brian Exp $
*/
#include <sys/param.h>
@ -51,8 +51,10 @@
#include "timer.h"
#include "fsm.h"
#include "iplist.h"
#include "hdlc.h"
#include "throughput.h"
#include "ipcp.h"
#include "link.h"
#include "bundle.h"
#include "loadalias.h"
#include "vars.h"
@ -61,87 +63,75 @@
#include "route.h"
#include "lcp.h"
#include "ccp.h"
#include "async.h"
#include "physical.h"
#include "modem.h"
#include "main.h"
#include "auth.h"
#include "lcpproto.h"
#include "pap.h"
#include "chap.h"
#include "tun.h"
static int
bundle_SetIpDevice(struct bundle *bundle, struct in_addr myaddr,
struct in_addr hisaddr, struct in_addr netmask, int silent)
static const char *PhaseNames[] = {
"Dead", "Establish", "Authenticate", "Network", "Terminate"
};
const char *
bundle_PhaseName(struct bundle *bundle)
{
struct sockaddr_in *sock_in;
int s;
u_long mask, addr;
struct ifaliasreq ifra;
return bundle->phase <= PHASE_TERMINATE ?
PhaseNames[bundle->phase] : "unknown";
}
/* If given addresses are alreay set, then ignore this request */
if (bundle->if_mine.s_addr == myaddr.s_addr &&
bundle->if_peer.s_addr == hisaddr.s_addr)
return 0;
void
bundle_NewPhase(struct bundle *bundle, struct physical *physical, u_int new)
{
if (new <= PHASE_NETWORK)
LogPrintf(LogPHASE, "bundle_NewPhase: %s\n", PhaseNames[new]);
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
LogPrintf(LogERROR, "SetIpDevice: socket(): %s\n", strerror(errno));
return (-1);
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:
bundle->phase = new;
break;
case PHASE_AUTHENTICATE:
LcpInfo.auth_ineed = LcpInfo.want_auth;
LcpInfo.auth_iwait = LcpInfo.his_auth;
if (LcpInfo.his_auth || LcpInfo.want_auth) {
LogPrintf(LogPHASE, " his = %s, mine = %s\n",
Auth2Nam(LcpInfo.his_auth), Auth2Nam(LcpInfo.want_auth));
/* XXX-ML AuthPapInfo and AuthChapInfo must be allocated! */
if (LcpInfo.his_auth == PROTO_PAP)
StartAuthChallenge(&AuthPapInfo, physical);
if (LcpInfo.want_auth == PROTO_CHAP)
StartAuthChallenge(&AuthChapInfo, physical);
bundle->phase = new;
Prompt(bundle);
} else
bundle_NewPhase(bundle, physical, PHASE_NETWORK);
break;
case PHASE_NETWORK:
tun_configure(bundle, LcpInfo.his_mru, modem_Speed(physical));
IpcpUp();
IpcpOpen();
CcpUp();
CcpOpen();
/* Fall through */
case PHASE_TERMINATE:
bundle->phase = new;
Prompt(bundle);
break;
}
memset(&ifra, '\0', sizeof ifra);
strncpy(ifra.ifra_name, bundle->ifname, sizeof ifra.ifra_name - 1);
ifra.ifra_name[sizeof ifra.ifra_name - 1] = '\0';
/* If different address has been set, then delete it first */
if (bundle->if_mine.s_addr != INADDR_ANY ||
bundle->if_peer.s_addr != INADDR_ANY)
if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0) {
LogPrintf(LogERROR, "SetIpDevice: ioctl(SIOCDIFADDR): %s\n",
strerror(errno));
close(s);
return (-1);
}
/* Set interface address */
sock_in = (struct sockaddr_in *)&ifra.ifra_addr;
sock_in->sin_family = AF_INET;
sock_in->sin_addr = myaddr;
sock_in->sin_len = sizeof *sock_in;
/* Set destination address */
sock_in = (struct sockaddr_in *)&ifra.ifra_broadaddr;
sock_in->sin_family = AF_INET;
sock_in->sin_addr = hisaddr;
sock_in->sin_len = sizeof *sock_in;
addr = ntohl(myaddr.s_addr);
if (IN_CLASSA(addr))
mask = IN_CLASSA_NET;
else if (IN_CLASSB(addr))
mask = IN_CLASSB_NET;
else
mask = IN_CLASSC_NET;
/* if subnet mask is given, use it instead of class mask */
if (netmask.s_addr != INADDR_ANY && (ntohl(netmask.s_addr) & mask) == mask)
mask = ntohl(netmask.s_addr);
sock_in = (struct sockaddr_in *)&ifra.ifra_mask;
sock_in->sin_family = AF_INET;
sock_in->sin_addr.s_addr = htonl(mask);
sock_in->sin_len = sizeof *sock_in;
if (ID0ioctl(s, SIOCAIFADDR, &ifra) < 0) {
if (!silent)
LogPrintf(LogERROR, "SetIpDevice: ioctl(SIOCAIFADDR): %s\n",
strerror(errno));
close(s);
return (-1);
}
bundle->if_peer.s_addr = hisaddr.s_addr;
bundle->if_mine.s_addr = myaddr.s_addr;
if (Enabled(ConfProxy))
sifproxyarp(bundle, s);
close(s);
return (0);
}
static int
@ -186,27 +176,23 @@ bundle_CleanInterface(const struct bundle *bundle)
return 1;
}
int
bundle_TrySetIPaddress(struct bundle *bundle, struct in_addr myaddr,
struct in_addr hisaddr)
void
bundle_LayerStart(struct bundle *bundle, struct fsm *fp)
{
return bundle_SetIpDevice(bundle, myaddr, hisaddr, ifnetmask, 1);
}
int
bundle_SetIPaddress(struct bundle *bundle, struct in_addr myaddr,
struct in_addr hisaddr)
{
return bundle_SetIpDevice(bundle, myaddr, hisaddr, ifnetmask, 0);
if (fp == &LcpInfo.fsm)
bundle_NewPhase(bundle, link2physical(fp->link), PHASE_ESTABLISH);
}
void
bundle_Linkup(struct bundle *bundle)
bundle_LayerUp(struct bundle *bundle, struct fsm *fp)
{
if (bundle->linkup == 0) {
char *s;
/* The given fsm is now up */
if (fp == &LcpInfo.fsm) {
reconnectState = RECON_UNKNOWN;
bundle_NewPhase(bundle, link2physical(fp->link), PHASE_AUTHENTICATE);
}
if (fp == &IpcpInfo.fsm)
if (mode & MODE_BACKGROUND && BGFiledes[1] != -1) {
char c = EX_NORMAL;
@ -217,113 +203,45 @@ bundle_Linkup(struct bundle *bundle)
close(BGFiledes[1]);
BGFiledes[1] = -1;
}
s = inet_ntoa(bundle->if_peer);
if (LogIsKept(LogLINK))
LogPrintf(LogLINK, "OsLinkup: %s\n", s);
else
LogPrintf(LogLCP, "OsLinkup: %s\n", s);
/*
* XXX this stuff should really live in the FSM. Our config should
* associate executable sections in files with events.
*/
if (SelectSystem(bundle, inet_ntoa(bundle->if_mine), LINKUPFILE) < 0) {
if (GetLabel()) {
if (SelectSystem(bundle, GetLabel(), LINKUPFILE) < 0)
SelectSystem(bundle, "MYADDR", LINKUPFILE);
} else
SelectSystem(bundle, "MYADDR", LINKUPFILE);
}
bundle->linkup = 1;
}
}
int
bundle_LinkIsUp(const struct bundle *bundle)
{
return bundle->linkup;
return IpcpInfo.fsm.state == ST_OPENED;
}
void
bundle_Linkdown(struct bundle *bundle)
bundle_Close(struct bundle *bundle, struct fsm *fp)
{
char *s = NULL;
int Level;
/*
* Please close the given FSM.
*
* If fp is any CCP, just FsmClose that CCP.
*
* If fp == NULL or fp is the last NCP or the last LCP, enter TERMINATE phase.
*
* If fp == NULL, 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 (bundle->linkup) {
s = inet_ntoa(bundle->if_peer);
Level = LogIsKept(LogLINK) ? LogLINK : LogIPCP;
LogPrintf(Level, "OsLinkdown: %s\n", s);
if (fp == &CcpInfo.fsm) {
FsmClose(&CcpInfo.fsm);
return;
}
bundle_NewPhase(bundle, NULL, PHASE_TERMINATE);
FsmClose(&IpcpInfo.fsm);
FsmClose(&CcpInfo.fsm);
if (bundle->linkup) {
/*
* XXX this stuff should really live in the FSM. Our config should
* associate executable sections in files with events.
*/
bundle->linkup = 0;
if (SelectSystem(bundle, s, LINKDOWNFILE) < 0)
if (GetLabel()) {
if (SelectSystem(bundle, GetLabel(), LINKDOWNFILE) < 0)
SelectSystem(bundle, "MYADDR", LINKDOWNFILE);
} else
SelectSystem(bundle, "MYADDR", LINKDOWNFILE);
}
}
int
bundle_InterfaceDown(struct bundle *bundle)
{
struct ifreq ifrq;
struct ifaliasreq ifra;
int s;
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
LogPrintf(LogERROR, "OsInterfaceDown: socket: %s\n", strerror(errno));
return -1;
}
if (Enabled(ConfProxy))
cifproxyarp(bundle, s);
memset(&ifrq, '\0', sizeof ifrq);
strncpy(ifrq.ifr_name, bundle->ifname, sizeof ifrq.ifr_name - 1);
ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0';
if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
LogPrintf(LogERROR, "OsInterfaceDown: ioctl(SIOCGIFFLAGS): %s\n",
strerror(errno));
close(s);
return -1;
}
ifrq.ifr_flags &= ~IFF_UP;
if (ID0ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
LogPrintf(LogERROR, "OsInterfaceDown: ioctl(SIOCSIFFLAGS): %s\n",
strerror(errno));
close(s);
return -1;
}
if (bundle->if_mine.s_addr != INADDR_ANY ||
bundle->if_peer.s_addr != INADDR_ANY) {
memset(&ifra, '\0', sizeof ifra);
strncpy(ifra.ifra_name, bundle->ifname, sizeof ifra.ifra_name - 1);
ifra.ifra_name[sizeof ifra.ifra_name - 1] = '\0';
if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0) {
LogPrintf(LogERROR, "OsInterfaceDown: ioctl(SIOCDIFADDR): %s\n",
strerror(errno));
close(s);
return -1;
}
bundle->if_mine.s_addr = bundle->if_peer.s_addr = INADDR_ANY;
}
close(s);
return 0;
}
/*
@ -424,14 +342,13 @@ bundle_Create(const char *prefix)
fprintf(VarTerm, "Using interface: %s\n", bundle.ifname);
LogPrintf(LogPHASE, "Using interface: %s\n", bundle.ifname);
bundle.linkup = 0;
bundle.if_mine.s_addr = bundle.if_peer.s_addr = INADDR_ANY;
bundle.routing_seq = 0;
bundle.phase = 0;
/* Clean out any leftover crud */
bundle_CleanInterface(&bundle);
bundle.physical = modem_Create("default");
bundle.physical = modem_Create("Modem");
if (bundle.physical == NULL) {
LogPrintf(LogERROR, "Cannot create modem device: %s\n", strerror(errno));
return NULL;
@ -557,12 +474,87 @@ bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst,
}
void
bundle_Down(struct bundle *bundle, struct link *link)
bundle_LinkLost(struct bundle *bundle, struct link *link)
{
/* If link is NULL slam everything down, otherwise `link' is dead */
/*
* 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.
*/
LogPrintf(LogPHASE, "Disconnected!\n");
FsmDown(&LcpInfo.fsm);
FsmDown(&IpcpInfo.fsm);
FsmDown(&CcpInfo.fsm);
if (CleaningUp || reconnectState == RECON_FALSE)
FsmClose(&LcpInfo.fsm);
}
void
bundle_LayerDown(struct bundle *bundle, struct fsm *fp)
{
/*
* The given FSM has been told to come down.
* We don't do anything here, as the FSM will eventually
* come up or down and will call LayerUp or LayerFinish.
*/
}
void
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 the last LCP, FsmDown all NCPs
* If it's the last NCP, FsmClose all LCPs and enter TERMINATE phase.
*/
if (fp == &CcpInfo.fsm) {
FsmDown(&CcpInfo.fsm);
FsmOpen(&CcpInfo.fsm);
} else if (fp == &LcpInfo.fsm) {
struct ifreq ifrq;
int s;
FsmDown(&CcpInfo.fsm);
FsmDown(&IpcpInfo.fsm); /* You've lost your underlings */
FsmClose(&IpcpInfo.fsm); /* ST_INITIAL please */
if (link_IsActive(fp->link))
link_Close(fp->link, bundle, 0); /* clean shutdown */
DeleteIfRoutes(fp->bundle, 1);
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
LogPrintf(LogERROR, "bundle_LayerFinish: socket: %s\n", strerror(errno));
return;
}
memset(&ifrq, '\0', sizeof ifrq);
strncpy(ifrq.ifr_name, bundle->ifname, sizeof ifrq.ifr_name - 1);
ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0';
if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
LogPrintf(LogERROR, "IpcpLayerDown: ioctl(SIOCGIFFLAGS): %s\n",
strerror(errno));
close(s);
return;
}
ifrq.ifr_flags &= ~IFF_UP;
if (ID0ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
LogPrintf(LogERROR, "IpcpLayerDown: ioctl(SIOCSIFFLAGS): %s\n",
strerror(errno));
close(s);
return;
}
close(s);
bundle_NewPhase(bundle, NULL, PHASE_DEAD);
} else if (fp == &IpcpInfo.fsm) {
FsmClose(&LcpInfo.fsm);
if (fp->bundle->phase != PHASE_TERMINATE)
bundle_NewPhase(bundle, NULL, PHASE_TERMINATE);
}
}

View File

@ -23,11 +23,18 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bundle.h,v 1.1.2.4 1998/02/06 02:23:29 brian Exp $
* $Id: bundle.h,v 1.1.2.5 1998/02/06 02:24:02 brian Exp $
*/
#define PHASE_DEAD 0 /* Link is dead */
#define PHASE_ESTABLISH 1 /* Establishing link */
#define PHASE_AUTHENTICATE 2 /* Being authenticated */
#define PHASE_NETWORK 3 /* We're alive ! */
#define PHASE_TERMINATE 4 /* Terminating link */
struct physical;
struct link;
struct fsm;
struct bundle {
int unit; /* The tun number */
@ -36,24 +43,21 @@ struct bundle {
char dev[20]; /* The /dev/tunX name */
char *ifname; /* The interface name */
int routing_seq; /* The current routing sequence number */
u_int phase; /* Curent phase */
struct physical *physical; /* For the time being */
/* These really belong at the NCP level */
int linkup; /* We've called ppp.linkup */
struct in_addr if_mine; /* My configured interface address */
struct in_addr if_peer; /* My congigured destination address */
};
extern struct bundle *bundle_Create(const char *dev);
extern int bundle_InterfaceDown(struct bundle *);
extern int bundle_SetIPaddress(struct bundle *, struct in_addr,
struct in_addr);
extern int bundle_TrySetIPaddress(struct bundle *, struct in_addr,
struct in_addr);
extern void bundle_Linkup(struct bundle *);
extern const char *bundle_PhaseName(struct bundle *);
#define bundle_Phase(b) ((b)->phase)
extern void bundle_NewPhase(struct bundle *, struct physical *, u_int);
extern void bundle_LayerStart(struct bundle *, struct fsm *);
extern void bundle_LayerUp(struct bundle *, struct fsm *);
extern int bundle_LinkIsUp(const struct bundle *);
extern void bundle_Linkdown(struct bundle *);
extern void bundle_SetRoute(struct bundle *, int, struct in_addr,
struct in_addr, struct in_addr, int);
extern void bundle_Down(struct bundle *, struct link *);
extern void bundle_LinkLost(struct bundle *, struct link *);
extern void bundle_Close(struct bundle *, struct fsm *);
extern void bundle_LayerDown(struct bundle *, struct fsm *);
extern void bundle_LayerFinish(struct bundle *, struct fsm *);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ccp.c,v 1.30.2.5 1998/02/02 19:32:02 brian Exp $
* $Id: ccp.c,v 1.30.2.6 1998/02/06 02:24:04 brian Exp $
*
* TODO:
* o Support other compression protocols
@ -37,11 +37,11 @@
#include "lcpproto.h"
#include "lcp.h"
#include "ccp.h"
#include "phase.h"
#include "loadalias.h"
#include "vars.h"
#include "pred.h"
#include "deflate.h"
#include "bundle.h"
static void CcpSendConfigReq(struct fsm *);
static void CcpSendTerminateReq(struct fsm *);
@ -260,7 +260,7 @@ CcpLayerUp(struct fsm *fp)
{
/* We're now up */
struct ccpstate *ccp = fsm2ccp(fp);
LogPrintf(LogCCP, "CcpLayerUp(%d).\n", fp->state);
LogPrintf(LogCCP, "CcpLayerUp.\n");
if (!ccp->in_init && ccp->in_algorithm >= 0 &&
ccp->in_algorithm < NALGORITHMS)
if ((*algorithm[ccp->in_algorithm]->i.Init)())
@ -405,14 +405,14 @@ CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type)
}
void
CcpInput(struct mbuf *bp)
CcpInput(struct bundle *bundle, struct mbuf *bp)
{
/* Got PROTO_CCP from link */
if (phase == PHASE_NETWORK)
if (bundle_Phase(bundle) == PHASE_NETWORK)
FsmInput(&CcpInfo.fsm, bp);
else {
if (phase < PHASE_NETWORK)
LogPrintf(LogCCP, "Error: Unexpected CCP in phase %d (ignored)\n", phase);
else if (bundle_Phase(bundle) < PHASE_NETWORK) {
LogPrintf(LogCCP, "Error: Unexpected CCP in phase %s (ignored)\n",
bundle_PhaseName(bundle));
pfree(bp);
}
}

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ccp.h,v 1.14.2.5 1998/02/02 19:32:02 brian Exp $
* $Id: ccp.h,v 1.14.2.6 1998/02/06 02:24:06 brian Exp $
*
* TODO:
*/
@ -86,7 +86,7 @@ struct ccp_algorithm {
extern void CcpRecvResetReq(struct fsm *);
extern void CcpSendResetReq(struct fsm *);
extern void CcpInput(struct mbuf *);
extern void CcpInput(struct bundle *, struct mbuf *);
extern void CcpUp(void);
extern void CcpOpen(void);
extern void CcpInit(struct bundle *, 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: chap.c,v 1.28.2.5 1998/02/02 19:32:03 brian Exp $
* $Id: chap.c,v 1.28.2.6 1998/02/02 19:33:33 brian Exp $
*
* TODO:
*/
@ -53,7 +53,6 @@
#include "lcpproto.h"
#include "lcp.h"
#include "hdlc.h"
#include "phase.h"
#include "loadalias.h"
#include "vars.h"
#include "auth.h"
@ -61,6 +60,7 @@
#include "throughput.h"
#include "link.h"
#include "physical.h"
#include "bundle.h"
static const char *chapcodes[] = {
"???", "CHALLENGE", "RESPONSE", "SUCCESS", "FAILURE"
@ -251,7 +251,14 @@ RecvChapTalk(struct bundle *bundle, struct fsmheader *chp, struct mbuf *bp,
login(&ut);
Utmp = 1;
}
NewPhase(bundle, physical, PHASE_NETWORK);
if (LcpInfo.auth_iwait == 0)
/*
* Either I didn't need to authenticate, or I've already been
* told that I got the answer right.
*/
bundle_NewPhase(bundle, physical, PHASE_NETWORK);
break;
}
}
@ -261,7 +268,7 @@ RecvChapTalk(struct bundle *bundle, struct fsmheader *chp, struct mbuf *bp,
*/
ChapOutput(physical, CHAP_FAILURE, chp->id, "Invalid!!", 9);
reconnect(RECON_FALSE);
LcpClose(&LcpInfo.fsm);
bundle_Close(bundle, &LcpInfo.fsm);
break;
}
}
@ -278,14 +285,17 @@ RecvChapResult(struct bundle *bundle, struct fsmheader *chp, struct mbuf *bp,
if (LcpInfo.auth_iwait == PROTO_CHAP) {
LcpInfo.auth_iwait = 0;
if (LcpInfo.auth_ineed == 0)
NewPhase(bundle, physical, PHASE_NETWORK);
/*
* We've succeeded in our ``login''
* If we're not expecting the peer to authenticate (or he already
* has), proceed to network phase.
*/
bundle_NewPhase(bundle, physical, PHASE_NETWORK);
}
} else {
/*
* Maybe, we should close LCP. Of cause, peer may take close action, too.
*/
;
/* CHAP failed - it's not going to get any better */
reconnect(RECON_FALSE);
bundle_Close(bundle, &LcpInfo.fsm);
}
}

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.9 1998/02/06 02:23:33 brian Exp $
* $Id: command.c,v 1.131.2.10 1998/02/06 02:24:09 brian Exp $
*
*/
#include <sys/param.h>
@ -51,7 +51,6 @@
#include "defs.h"
#include "timer.h"
#include "fsm.h"
#include "phase.h"
#include "lcp.h"
#include "iplist.h"
#include "throughput.h"
@ -336,7 +335,7 @@ ShellCommand(struct cmdargs const *arg, int bg)
waitpid(shpid, &status, 0);
}
TtyCommandMode(0);
TtyCommandMode(arg->bundle, 0);
return (0);
}
@ -725,11 +724,11 @@ FindExec(struct bundle *bundle, struct cmdtab const *cmds, int argc,
int aft_cmd = 1;
void
Prompt()
Prompt(struct bundle *bundle)
{
const char *pconnect, *pauth;
if (!VarTerm || TermMode)
if (!VarTerm || TermMode || CleaningUp)
return;
if (!aft_cmd)
@ -741,8 +740,12 @@ Prompt()
pauth = " ON ";
else
pauth = " on ";
if (IpcpInfo.fsm.state == ST_OPENED && phase == PHASE_NETWORK)
if (IpcpInfo.fsm.state == ST_OPENED)
pconnect = "PPP";
else if (bundle_Phase(bundle) == PHASE_NETWORK)
pconnect = "PPp";
else if (bundle_Phase(bundle) == PHASE_AUTHENTICATE)
pconnect = "Ppp";
else
pconnect = "ppp";
fprintf(VarTerm, "%s%s%s> ", pconnect, pauth, VarShortHost);
@ -867,7 +870,7 @@ QuitCommand(struct cmdargs const *arg)
DropClient(1);
if ((mode & MODE_INTER) ||
(arg->argc > 0 && !strcasecmp(*arg->argv, "all") &&
VarLocalAuth&LOCAL_AUTH))
(VarLocalAuth & LOCAL_AUTH)))
Cleanup(EX_NORMAL);
}
@ -878,14 +881,16 @@ static int
CloseCommand(struct cmdargs const *arg)
{
reconnect(RECON_FALSE);
LcpClose(&LcpInfo.fsm);
bundle_Close(LcpInfo.fsm.bundle, &LcpInfo.fsm);
return 0;
}
static int
DownCommand(struct cmdargs const *arg)
{
bundle_Down(arg->bundle, &arg->bundle->physical->link);
reconnectState = RECON_FALSE;
reconnectCount = 0;
link_Close(&arg->bundle->physical->link, arg->bundle, 0);
return 0;
}
@ -1374,7 +1379,7 @@ SetVariable(struct cmdargs const *arg)
break;
case VAR_DEVICE:
if (mode & MODE_INTER)
link_Close(physical2link(arg->bundle->physical), 0);
link_Close(physical2link(arg->bundle->physical), arg->bundle, 0);
if (link_IsActive(physical2link(arg->bundle->physical)))
LogPrintf(LogWARN,
"Cannot change device to \"%s\" when \"%s\" is open\n",

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: command.h,v 1.12 1997/11/22 03:37:29 brian Exp $
* $Id: command.h,v 1.12.2.1 1998/02/02 19:32:04 brian Exp $
*
* TODO:
*/
@ -56,7 +56,7 @@ extern struct in_addr ifnetmask;
extern int aft_cmd;
extern int SetVariable(struct cmdargs const *);
extern void Prompt(void);
extern void Prompt(struct bundle *);
extern int IsInteractive(int);
extern void InterpretCommand(char *, int, int *, char ***);
extern void RunCommand(struct bundle *, int, char const *const *, const char *);

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.6 1998/02/06 02:22:12 brian Exp $
* $Id: fsm.c,v 1.27.2.7 1998/02/06 02:24:10 brian Exp $
*
* TODO:
* o Refer loglevel for log output
@ -79,9 +79,7 @@ StoppedTimeout(void *v)
StopTimer(&fp->OpenTimer);
}
if (link_IsActive(fp->link))
FsmDown(fp);
else
bundle_Down(fp->bundle, fp->link);
link_Close(fp->link, fp->bundle, 0);
}
void
@ -151,11 +149,10 @@ void
FsmOpen(struct fsm * fp)
{
switch (fp->state) {
case ST_INITIAL:
(*fp->fn->LayerStart)(fp);
case ST_INITIAL:
NewState(fp, ST_STARTING);
break;
case ST_STARTING:
(*fp->fn->LayerStart)(fp);
bundle_LayerStart(fp->bundle, fp);
break;
case ST_CLOSED:
if (fp->open_mode == OPEN_PASSIVE) {
@ -208,13 +205,19 @@ void
FsmDown(struct fsm *fp)
{
switch (fp->state) {
case ST_CLOSED:
case ST_CLOSING:
case ST_CLOSED:
NewState(fp, ST_INITIAL);
break;
case ST_CLOSING:
(*fp->fn->LayerFinish)(fp);
NewState(fp, ST_INITIAL);
bundle_LayerFinish(fp->bundle, fp);
break;
case ST_STOPPED:
NewState(fp, ST_STARTING);
(*fp->fn->LayerStart)(fp);
/* Fall into.. */
bundle_LayerStart(fp->bundle, fp);
break;
case ST_STOPPING:
case ST_REQSENT:
case ST_ACKRCVD:
@ -224,21 +227,19 @@ FsmDown(struct fsm *fp)
case ST_OPENED:
(*fp->fn->LayerDown)(fp);
NewState(fp, ST_STARTING);
bundle_LayerDown(fp->bundle, fp);
break;
}
if (fp->state != ST_INITIAL) {
/* XXX: Is this violating the rfc ? */
(*fp->fn->LayerFinish)(fp);
NewState(fp, ST_INITIAL);
}
}
void
FsmClose(struct fsm *fp)
{
switch (fp->state) {
case ST_STARTING:
case ST_STARTING:
(*fp->fn->LayerFinish)(fp);
NewState(fp, ST_INITIAL);
bundle_LayerFinish(fp->bundle, fp);
break;
case ST_STOPPED:
NewState(fp, ST_CLOSED);
@ -248,7 +249,11 @@ FsmClose(struct fsm *fp)
break;
case ST_OPENED:
(*fp->fn->LayerDown)(fp);
/* Fall down */
FsmInitRestartCounter(fp);
FsmSendTerminateReq(fp);
NewState(fp, ST_CLOSING);
bundle_LayerDown(fp->bundle, fp);
break;
case ST_REQSENT:
case ST_ACKRCVD:
case ST_ACKSENT:
@ -321,8 +326,8 @@ FsmTimeout(void *v)
if (fp->restart) {
switch (fp->state) {
case ST_CLOSING:
case ST_STOPPING:
case ST_CLOSING:
case ST_STOPPING:
FsmSendTerminateReq(fp);
break;
case ST_REQSENT:
@ -338,18 +343,21 @@ FsmTimeout(void *v)
} else {
switch (fp->state) {
case ST_CLOSING:
NewState(fp, ST_CLOSED);
(*fp->fn->LayerFinish)(fp);
NewState(fp, ST_CLOSED);
bundle_LayerFinish(fp->bundle, fp);
break;
case ST_STOPPING:
NewState(fp, ST_STOPPED);
(*fp->fn->LayerFinish)(fp);
NewState(fp, ST_STOPPED);
bundle_LayerFinish(fp->bundle, fp);
break;
case ST_REQSENT: /* XXX: 3p */
case ST_ACKSENT:
case ST_ACKRCVD:
NewState(fp, ST_STOPPED);
(*fp->fn->LayerFinish)(fp);
NewState(fp, ST_STOPPED);
bundle_LayerFinish(fp->bundle, fp);
break;
}
}
@ -414,6 +422,7 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
case ST_OPENED:
(*fp->fn->LayerDown)(fp);
FsmSendConfigReq(fp);
bundle_LayerDown(fp->bundle, fp);
break;
case ST_STOPPED:
FsmInitRestartCounter(fp);
@ -429,8 +438,8 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
FsmSendConfigAck(fp, lhp, AckBuff, ackp - AckBuff);
switch (fp->state) {
case ST_STOPPED:
case ST_OPENED:
case ST_STOPPED:
if (ackaction)
NewState(fp, ST_ACKSENT);
else
@ -444,6 +453,7 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
if (ackaction) {
NewState(fp, ST_OPENED);
(*fp->fn->LayerUp)(fp);
bundle_LayerUp(fp->bundle, fp);
}
break;
case ST_ACKSENT:
@ -478,11 +488,13 @@ FsmRecvConfigAck(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp)
FsmInitRestartCounter(fp);
NewState(fp, ST_OPENED);
(*fp->fn->LayerUp)(fp);
bundle_LayerUp(fp->bundle, fp);
break;
case ST_OPENED:
(*fp->fn->LayerDown)(fp);
FsmSendConfigReq(fp);
NewState(fp, ST_REQSENT);
bundle_LayerDown(fp->bundle, fp);
break;
}
pfree(bp);
@ -531,7 +543,10 @@ FsmRecvConfigNak(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
break;
case ST_OPENED:
(*fp->fn->LayerDown)(fp);
/* Fall down */
FsmSendConfigReq(fp);
NewState(fp, ST_REQSENT);
bundle_LayerDown(fp->bundle, fp);
break;
case ST_ACKRCVD:
FsmSendConfigReq(fp);
NewState(fp, ST_REQSENT);
@ -546,8 +561,8 @@ FsmRecvTermReq(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp)
/* RTR */
{
switch (fp->state) {
case ST_INITIAL:
case ST_STARTING:
case ST_INITIAL:
case ST_STARTING:
LogPrintf(fp->LogLevel, "Oops, RTR in %s\n", StateNames[fp->state]);
break;
case ST_CLOSED:
@ -568,6 +583,7 @@ FsmRecvTermReq(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp)
StartTimer(&fp->FsmTimer); /* Start restart timer */
fp->restart = 0;
NewState(fp, ST_STOPPING);
bundle_LayerDown(fp->bundle, fp);
break;
}
pfree(bp);
@ -578,13 +594,15 @@ FsmRecvTermAck(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp)
/* RTA */
{
switch (fp->state) {
case ST_CLOSING:
NewState(fp, ST_CLOSED);
case ST_CLOSING:
(*fp->fn->LayerFinish)(fp);
NewState(fp, ST_CLOSED);
bundle_LayerFinish(fp->bundle, fp);
break;
case ST_STOPPING:
NewState(fp, ST_STOPPED);
(*fp->fn->LayerFinish)(fp);
NewState(fp, ST_STOPPED);
bundle_LayerFinish(fp->bundle, fp);
break;
case ST_ACKRCVD:
NewState(fp, ST_REQSENT);
@ -593,6 +611,7 @@ FsmRecvTermAck(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp)
(*fp->fn->LayerDown)(fp);
FsmSendConfigReq(fp);
NewState(fp, ST_REQSENT);
bundle_LayerDown(fp->bundle, fp);
break;
}
pfree(bp);
@ -642,7 +661,10 @@ FsmRecvConfigRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
break;
case ST_OPENED:
(*fp->fn->LayerDown)(fp);
/* Fall down */
FsmSendConfigReq(fp);
NewState(fp, ST_REQSENT);
bundle_LayerDown(fp->bundle, fp);
break;
case ST_ACKRCVD:
FsmSendConfigReq(fp);
NewState(fp, ST_REQSENT);
@ -686,6 +708,7 @@ FsmRecvProtoRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
NewState(fp, ST_STOPPED);
break;
}
bundle_LayerFinish(fp->bundle, fp);
break;
}
pfree(bp);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: hdlc.c,v 1.28.2.5 1998/02/02 19:32:06 brian Exp $
* $Id: hdlc.c,v 1.28.2.6 1998/02/02 19:33:35 brian Exp $
*
* TODO:
*/
@ -428,7 +428,7 @@ DecodePacket(struct bundle *bundle, u_short proto, struct mbuf * bp,
IpcpInput(bp);
break;
case PROTO_CCP:
CcpInput(bp);
CcpInput(bundle, bp);
break;
default:
LogPrintf(LogPHASE, "Unknown protocol 0x%04x (%s)\n",

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.4 1998/01/31 02:48:19 brian Exp $
* $Id: ip.c,v 1.38.2.5 1998/02/02 19:32:07 brian Exp $
*
* TODO:
* o Return ICMP message for filterd packet
@ -73,11 +73,11 @@ IdleTimeout(void *v)
{
LogPrintf(LogPHASE, "Idle timer expired.\n");
reconnect(RECON_FALSE);
LcpClose(&LcpInfo.fsm);
bundle_Close(LcpInfo.fsm.bundle, &LcpInfo.fsm);
}
/*
* Start Idle timer. If timeout is reached, we call LcpClose() to
* Start Idle timer. If timeout is reached, we call bundle_Close() to
* close LCP and link.
*/
void

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ipcp.c,v 1.50.2.7 1998/02/02 19:33:36 brian Exp $
* $Id: ipcp.c,v 1.50.2.8 1998/02/06 02:24:19 brian Exp $
*
* TODO:
* o More RFC1772 backwoard compatibility
@ -29,10 +29,14 @@
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/time.h>
#include <net/if.h>
#include <sys/sockio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/errno.h>
#include <termios.h>
#include <unistd.h>
@ -49,7 +53,6 @@
#include "ipcp.h"
#include "slcompress.h"
#include "bundle.h"
#include "phase.h"
#include "loadalias.h"
#include "vars.h"
#include "vjcomp.h"
@ -60,6 +63,9 @@
#include "async.h"
#include "link.h"
#include "physical.h"
#include "id.h"
#include "arp.h"
#include "systems.h"
struct compreq {
u_short proto;
@ -251,6 +257,7 @@ IpcpInit(struct bundle *bundle, struct link *l)
LogPrintf(LogIPCP, "Using trigger address %s\n",
inet_ntoa(IpcpInfo.TriggerAddress));
}
IpcpInfo.if_mine.s_addr = IpcpInfo.if_peer.s_addr = INADDR_ANY;
if (Enabled(ConfVjcomp))
IpcpInfo.want_compproto = (PROTO_VJCOMP << 16) +
@ -265,6 +272,114 @@ IpcpInit(struct bundle *bundle, struct link *l)
throughput_init(&IpcpInfo.throughput);
}
static int
ipcp_SetIPaddress(struct bundle *bundle, struct ipcpstate *ipcp,
struct in_addr myaddr, struct in_addr hisaddr,
struct in_addr netmask, int silent)
{
struct sockaddr_in *sock_in;
int s;
u_long mask, addr;
struct ifaliasreq ifra;
/* If given addresses are alreay set, then ignore this request */
if (ipcp->if_mine.s_addr == myaddr.s_addr &&
ipcp->if_peer.s_addr == hisaddr.s_addr)
return 0;
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
LogPrintf(LogERROR, "SetIpDevice: socket(): %s\n", strerror(errno));
return (-1);
}
memset(&ifra, '\0', sizeof ifra);
strncpy(ifra.ifra_name, bundle->ifname, sizeof ifra.ifra_name - 1);
ifra.ifra_name[sizeof ifra.ifra_name - 1] = '\0';
/* If different address has been set, then delete it first */
if (ipcp->if_mine.s_addr != INADDR_ANY ||
ipcp->if_peer.s_addr != INADDR_ANY)
if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0) {
LogPrintf(LogERROR, "SetIpDevice: ioctl(SIOCDIFADDR): %s\n",
strerror(errno));
close(s);
return (-1);
}
/* Set interface address */
sock_in = (struct sockaddr_in *)&ifra.ifra_addr;
sock_in->sin_family = AF_INET;
sock_in->sin_addr = myaddr;
sock_in->sin_len = sizeof *sock_in;
/* Set destination address */
sock_in = (struct sockaddr_in *)&ifra.ifra_broadaddr;
sock_in->sin_family = AF_INET;
sock_in->sin_addr = hisaddr;
sock_in->sin_len = sizeof *sock_in;
addr = ntohl(myaddr.s_addr);
if (IN_CLASSA(addr))
mask = IN_CLASSA_NET;
else if (IN_CLASSB(addr))
mask = IN_CLASSB_NET;
else
mask = IN_CLASSC_NET;
/* if subnet mask is given, use it instead of class mask */
if (netmask.s_addr != INADDR_ANY && (ntohl(netmask.s_addr) & mask) == mask)
mask = ntohl(netmask.s_addr);
sock_in = (struct sockaddr_in *)&ifra.ifra_mask;
sock_in->sin_family = AF_INET;
sock_in->sin_addr.s_addr = htonl(mask);
sock_in->sin_len = sizeof *sock_in;
if (ID0ioctl(s, SIOCAIFADDR, &ifra) < 0) {
if (!silent)
LogPrintf(LogERROR, "SetIpDevice: ioctl(SIOCAIFADDR): %s\n",
strerror(errno));
close(s);
return (-1);
}
ipcp->if_peer.s_addr = hisaddr.s_addr;
ipcp->if_mine.s_addr = myaddr.s_addr;
if (Enabled(ConfProxy))
sifproxyarp(bundle, ipcp, s);
close(s);
return (0);
}
static struct in_addr
ChooseHisAddr(struct bundle *bundle, struct ipcpstate *ipcp,
const struct in_addr gw)
{
struct in_addr try;
int f;
for (f = 0; f < IpcpInfo.DefHisChoice.nItems; f++) {
try = iplist_next(&IpcpInfo.DefHisChoice);
LogPrintf(LogDEBUG, "ChooseHisAddr: Check item %d (%s)\n",
f, inet_ntoa(try));
if (ipcp_SetIPaddress(bundle, ipcp, gw, try, ifnetmask, 1) == 0) {
LogPrintf(LogIPCP, "ChooseHisAddr: Selected IP address %s\n",
inet_ntoa(try));
break;
}
}
if (f == IpcpInfo.DefHisChoice.nItems) {
LogPrintf(LogDEBUG, "ChooseHisAddr: All addresses in use !\n");
try.s_addr = INADDR_ANY;
}
return try;
}
static void
IpcpInitRestartCounter(struct fsm * fp)
{
@ -328,16 +443,15 @@ IpcpLayerStart(struct fsm * fp)
{
/* We're about to start up ! */
LogPrintf(LogIPCP, "IpcpLayerStart.\n");
/* This is where we should be setting up the interface in AUTO mode */
}
static void
IpcpLayerFinish(struct fsm * fp)
IpcpLayerFinish(struct fsm *fp)
{
/* We're now down */
LogPrintf(LogIPCP, "IpcpLayerFinish.\n");
/* Better tell LCP that it's all over (we're the only NCP) */
reconnect(RECON_FALSE);
LcpClose(&LcpInfo.fsm);
}
static void
@ -345,9 +459,56 @@ IpcpLayerDown(struct fsm *fp)
{
/* About to come down */
struct ipcpstate *ipcp = fsm2ipcp(fp);
LogPrintf(LogIPCP, "IpcpLayerDown.\n");
const char *s;
s = inet_ntoa(ipcp->if_peer);
LogPrintf(LogIsKept(LogLINK) ? LogLINK : LogIPCP, "IpcpLayerDown: %s\n", s);
throughput_stop(&ipcp->throughput);
throughput_log(&ipcp->throughput, LogIPCP, NULL);
/*
* XXX this stuff should really live in the FSM. Our config should
* associate executable sections in files with events.
*/
if (SelectSystem(fp->bundle, s, LINKDOWNFILE) < 0)
if (GetLabel()) {
if (SelectSystem(fp->bundle, GetLabel(), LINKDOWNFILE) < 0)
SelectSystem(fp->bundle, "MYADDR", LINKDOWNFILE);
} else
SelectSystem(fp->bundle, "MYADDR", LINKDOWNFILE);
if (!(mode & MODE_AUTO)) {
struct ifaliasreq ifra;
int s;
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
LogPrintf(LogERROR, "IpcpLayerDown: socket: %s\n", strerror(errno));
return;
}
if (Enabled(ConfProxy))
cifproxyarp(fp->bundle, ipcp, s);
if (ipcp->if_mine.s_addr != INADDR_ANY ||
ipcp->if_peer.s_addr != INADDR_ANY) {
memset(&ifra, '\0', sizeof ifra);
strncpy(ifra.ifra_name, fp->bundle->ifname, sizeof ifra.ifra_name - 1);
ifra.ifra_name[sizeof ifra.ifra_name - 1] = '\0';
/* XXX don't delete things belonging to other NCPs */
if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0) {
LogPrintf(LogERROR, "IpcpLayerDown: ioctl(SIOCDIFADDR): %s\n",
strerror(errno));
close(s);
return;
}
ipcp->if_mine.s_addr = ipcp->if_peer.s_addr = INADDR_ANY;
}
close(s);
return;
}
}
static void
@ -357,28 +518,43 @@ IpcpLayerUp(struct fsm *fp)
struct ipcpstate *ipcp = fsm2ipcp(fp);
char tbuff[100];
Prompt();
LogPrintf(LogIPCP, "IpcpLayerUp(%d).\n", fp->state);
snprintf(tbuff, sizeof tbuff, "myaddr = %s ", inet_ntoa(ipcp->want_ipaddr));
LogPrintf(LogIsKept(LogIPCP) ? LogIPCP : LogLINK, " %s hisaddr = %s\n",
tbuff, inet_ntoa(ipcp->his_ipaddr));
if (ipcp->his_compproto >> 16 == PROTO_VJCOMP)
VjInit((ipcp->his_compproto >> 8) & 255);
LogPrintf(LogIsKept(LogIPCP) ? LogIPCP : LogLINK, " %s hisaddr = %s\n",
tbuff, inet_ntoa(ipcp->his_ipaddr));
if (bundle_SetIPaddress(fp->bundle, ipcp->want_ipaddr,
ipcp->his_ipaddr) < 0) {
if (ipcp_SetIPaddress(fp->bundle, ipcp, ipcp->want_ipaddr,
ipcp->his_ipaddr, ifnetmask, 0) < 0) {
if (VarTerm)
LogPrintf(LogERROR, "IpcpLayerUp: unable to set ip address\n");
return;
}
#ifndef NOALIAS
if (mode & MODE_ALIAS)
VarPacketAliasSetAddress(ipcp->want_ipaddr);
#endif
bundle_Linkup(fp->bundle);
LogPrintf(LogIsKept(LogLINK) ? LogLINK : LogIPCP, "IpcpLayerUp: %s\n",
inet_ntoa(ipcp->if_peer));
/*
* XXX this stuff should really live in the FSM. Our config should
* associate executable sections in files with events.
*/
if (SelectSystem(fp->bundle, inet_ntoa(ipcp->if_mine), LINKUPFILE) < 0)
if (GetLabel()) {
if (SelectSystem(fp->bundle, GetLabel(), LINKUPFILE) < 0)
SelectSystem(fp->bundle, "MYADDR", LINKUPFILE);
} else
SelectSystem(fp->bundle, "MYADDR", LINKUPFILE);
throughput_start(&ipcp->throughput);
StartIdleTimer();
Prompt(fp->bundle);
}
void
@ -446,12 +622,12 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type)
if (iplist_isvalid(&ipcp->DefHisChoice)) {
if (ipaddr.s_addr == INADDR_ANY ||
iplist_ip2pos(&ipcp->DefHisChoice, ipaddr) < 0 ||
bundle_TrySetIPaddress(fp->bundle, ipcp->DefMyAddress.ipaddr,
ipaddr)) {
ipcp_SetIPaddress(fp->bundle, ipcp, ipcp->DefMyAddress.ipaddr,
ipaddr, ifnetmask, 1)) {
LogPrintf(LogIPCP, "%s: Address invalid or already in use\n",
inet_ntoa(ipaddr));
ipcp->his_ipaddr = ChooseHisAddr
(fp->bundle, ipcp->DefMyAddress.ipaddr);
(fp->bundle, ipcp, ipcp->DefMyAddress.ipaddr);
if (ipcp->his_ipaddr.s_addr == INADDR_ANY) {
memcpy(rejp, cp, length);
rejp += length;
@ -706,7 +882,8 @@ UseHisaddr(struct bundle *bundle, const char *hisaddr, int setaddr)
iplist_setsrc(&IpcpInfo.DefHisChoice, hisaddr);
if (iplist_isvalid(&IpcpInfo.DefHisChoice)) {
iplist_setrandpos(&IpcpInfo.DefHisChoice);
IpcpInfo.his_ipaddr = ChooseHisAddr(bundle, IpcpInfo.want_ipaddr);
IpcpInfo.his_ipaddr = ChooseHisAddr
(bundle, &IpcpInfo, IpcpInfo.want_ipaddr);
if (IpcpInfo.his_ipaddr.s_addr == INADDR_ANY) {
LogPrintf(LogWARN, "%s: None available !\n", IpcpInfo.DefHisChoice.src);
return(0);
@ -723,8 +900,10 @@ UseHisaddr(struct bundle *bundle, const char *hisaddr, int setaddr)
&IpcpInfo.DefHisAddress.width) != 0) {
IpcpInfo.his_ipaddr.s_addr = IpcpInfo.DefHisAddress.ipaddr.s_addr;
if (setaddr && bundle_SetIPaddress(bundle, IpcpInfo.DefMyAddress.ipaddr,
IpcpInfo.DefHisAddress.ipaddr) < 0) {
if (setaddr && ipcp_SetIPaddress(bundle, &IpcpInfo,
IpcpInfo.DefMyAddress.ipaddr,
IpcpInfo.DefHisAddress.ipaddr, ifnetmask,
0) < 0) {
IpcpInfo.DefMyAddress.ipaddr.s_addr = INADDR_ANY;
IpcpInfo.DefHisAddress.ipaddr.s_addr = INADDR_ANY;
return 0;

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ipcp.h,v 1.18.2.8 1998/02/02 19:32:31 brian Exp $
* $Id: ipcp.h,v 1.18.2.9 1998/02/06 02:24:20 brian Exp $
*
* TODO:
*/
@ -69,6 +69,9 @@ struct ipcpstate {
struct in_addr TriggerAddress; /* Address to suggest in REQ */
int HaveTriggerAddress : 1; /* Trigger address specified */
struct in_addr if_mine; /* My configured interface address */
struct in_addr if_peer; /* My congigured destination address */
struct pppThroughput throughput; /* throughput statistics */
};

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.9 1998/02/06 02:22:14 brian Exp $
* $Id: lcp.c,v 1.55.2.10 1998/02/06 02:24:22 brian Exp $
*
* TODO:
* o Limit data field length by MRU
@ -54,7 +54,6 @@
#include "hdlc.h"
#include "ccp.h"
#include "lqr.h"
#include "phase.h"
#include "loadalias.h"
#include "vars.h"
#include "auth.h"
@ -395,13 +394,7 @@ static void
LcpLayerStart(struct fsm *fp)
{
/* We're about to start up ! */
struct physical *p = link2physical(fp->link);
LogPrintf(LogLCP, "LcpLayerStart\n");
if (p)
NewPhase(fp->bundle, p, PHASE_ESTABLISH);
else
LogPrintf(LogERROR, "LcpLayerStart: Not a physical link !\n");
}
static void
@ -418,22 +411,12 @@ static void
LcpLayerFinish(struct fsm *fp)
{
/* We're now down */
struct physical *p = link2physical(fp->link);
struct lcpstate *lcp = fsm2lcp(fp);
LogPrintf(LogLCP, "LcpLayerFinish\n");
lcp->LcpFailedMagic = 0;
link_Close(fp->link, 0);
StopAllTimers();
CcpInfo.fsm.restart = 0;
IpcpInfo.fsm.restart = 0;
/* We're down at last. Lets tell background and direct mode to get out */
if (p)
NewPhase(fp->bundle, p, PHASE_DEAD);
else
LogPrintf(LogERROR, "LcpLayerFinish: Not a physical link !\n");
Prompt();
LogPrintf(LogPHASE, "%s disconnected!\n", fp->link->name);
}
static void
@ -447,7 +430,6 @@ LcpLayerUp(struct fsm *fp)
if (p) {
async_SetLinkParams(&p->async, lcp);
NewPhase(fp->bundle, p, PHASE_AUTHENTICATE);
StartLqm(p);
} else
LogPrintf(LogERROR, "LcpLayerUp: Not a physical link !\n");
@ -464,13 +446,7 @@ static void
LcpLayerDown(struct fsm *fp)
{
/* About to come down */
bundle_Linkdown(fp->bundle);
LogPrintf(LogLCP, "LcpLayerDown\n");
/*
* bundle_Linkdown() brings CCP & IPCP down, then waits 'till we go from
* STOPPING to STOPPED. At this point, the FSM gives us a LayerFinish
*/
}
void
@ -490,23 +466,6 @@ LcpOpen(int open_mode)
FsmOpen(&LcpInfo.fsm);
}
void
LcpClose(struct fsm *fp)
{
/* Stop LCP please */
struct physical *p = link2physical(fp->link);
if (p)
NewPhase(fp->bundle, p, PHASE_TERMINATE);
else
LogPrintf(LogERROR, "LcpClose: Not a physical link !\n");
bundle_Linkdown(fp->bundle);
if (!(mode & MODE_DAEMON))
bundle_InterfaceDown(fp->bundle);
FsmClose(fp);
}
static void
LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type)
{

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.4 1998/02/02 19:32:09 brian Exp $
* $Id: lcp.h,v 1.16.2.5 1998/02/06 02:24:24 brian Exp $
*
* TODO:
*/
@ -80,7 +80,6 @@ extern void LcpInit(struct bundle *, struct physical *);
extern void LcpUp(void);
extern void LcpSendProtoRej(u_char *, int);
extern void LcpOpen(int);
extern void LcpClose(struct fsm *);
extern int LcpPutConf(int, u_char *, const struct lcp_opt *, const char *,
const char *, ...);
extern int ReportLcpStatus(struct cmdargs const *);

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.2 1998/02/06 02:22:43 brian Exp $
* $Id: link.c,v 1.1.2.3 1998/02/06 02:23:35 brian Exp $
*
*/
@ -43,6 +43,7 @@
#include "loadalias.h"
#include "vars.h"
#include "link.h"
#include "bundle.h"
void
link_AddInOctets(struct link *l, int n)
@ -139,9 +140,10 @@ link_IsActive(struct link *l)
}
void
link_Close(struct link *l, int dedicated_force)
link_Close(struct link *l, struct bundle *bundle, int dedicated_force)
{
(*l->Close)(l, dedicated_force);
bundle_LinkLost(bundle, l);
}
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.1 1998/01/30 19:45:50 brian Exp $
* $Id: link.h,v 1.1.2.2 1998/02/06 02:22:44 brian Exp $
*
*/
@ -34,6 +34,8 @@
#define LINK_QUEUES (PRI_MAX + 1)
#define NPROTOSTAT 11
struct bundle;
struct link {
int type; /* _LINK type */
char *name; /* unique id per link type */
@ -68,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 *, int);
extern void link_Close(struct link *, struct bundle *, 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.4 1998/01/31 02:48:23 brian Exp $
* $Id: lqr.c,v 1.22.2.5 1998/02/02 19:33:37 brian Exp $
*
* o LQR based on RFC1333
*
@ -44,6 +44,7 @@
#include "throughput.h"
#include "link.h"
#include "physical.h"
#include "bundle.h"
#include "lqr.h"
#include "loadalias.h"
#include "vars.h"
@ -127,9 +128,9 @@ SendLqrReport(void *v)
* XXX: Should implement LQM strategy
*/
LogPrintf(LogPHASE, "** 1 Too many ECHO packets are lost. **\n");
lqmmethod = 0; /* Prevent rcursion via LcpClose() */
lqmmethod = 0; /* Prevent rcursion via bundle_Close() */
reconnect(RECON_TRUE);
LcpClose(&LcpInfo.fsm);
bundle_Close(LcpInfo.fsm.bundle, &LcpInfo.fsm);
} else {
bp = mballoc(sizeof(struct lqrdata), MB_LQR);
HdlcOutput(physical2link(physical), PRI_LINK, PROTO_LQR, bp);
@ -138,9 +139,9 @@ SendLqrReport(void *v)
} else if (lqmmethod & LQM_ECHO) {
if (echoseq - gotseq > 5) {
LogPrintf(LogPHASE, "** 2 Too many ECHO packets are lost. **\n");
lqmmethod = 0; /* Prevent rcursion via LcpClose() */
lqmmethod = 0; /* Prevent rcursion via bundle_Close() */
reconnect(RECON_TRUE);
LcpClose(&LcpInfo.fsm);
bundle_Close(LcpInfo.fsm.bundle, &LcpInfo.fsm);
} 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.9 1998/02/06 02:23:37 brian Exp $
* $Id: main.c,v 1.121.2.10 1998/02/06 02:24:25 brian Exp $
*
* TODO:
* o Add commands for traffic summary, version display, etc.
@ -85,7 +85,6 @@
#endif
int TermMode = 0;
int tunno = 0;
static struct termios oldtio; /* Original tty mode */
static struct termios comtio; /* Command level tty mode */
@ -126,7 +125,7 @@ TtyInit(int DontWantInt)
* Set tty into command mode. We allow canonical input and echo processing.
*/
void
TtyCommandMode(int prompt)
TtyCommandMode(struct bundle *bundle, int prompt)
{
struct termios newtio;
int stat;
@ -145,7 +144,7 @@ TtyCommandMode(int prompt)
}
TermMode = 0;
if (prompt)
Prompt();
Prompt(bundle);
}
/*
@ -179,16 +178,20 @@ TtyOldMode()
}
static struct bundle *SignalBundle;
int CleaningUp;
void
Cleanup(int excode)
{
CleaningUp = 1;
reconnect(RECON_FALSE);
if (bundle_Phase(SignalBundle) != PHASE_DEAD) {
bundle_Close(SignalBundle, NULL);
return;
}
DropClient(1);
ServerClose();
bundle_InterfaceDown(SignalBundle);
link_Close(physical2link(SignalBundle->physical), 1);
nointr_sleep(1);
DeleteIfRoutes(SignalBundle, 1);
ID0unlink(pid_filename);
if (mode & MODE_BACKGROUND && BGFiledes[1] != -1) {
char c = EX_ERRDEAD;
@ -215,7 +218,7 @@ CloseConnection(int signo)
LogPrintf(LogPHASE, "Caught signal %d, abort connection\n", signo);
reconnectState = RECON_FALSE;
reconnectCount = 0;
bundle_Down(SignalBundle, NULL);
link_Close(&SignalBundle->physical->link, SignalBundle, 0);
dial_up = 0;
pending_signal(SIGINT, CloseConnection);
}
@ -228,8 +231,6 @@ CloseSession(int signo)
exit(EX_TERM);
}
LogPrintf(LogPHASE, "Signal %d, terminate.\n", signo);
reconnect(RECON_FALSE);
LcpClose(&LcpInfo.fsm);
Cleanup(EX_TERM);
}
@ -238,7 +239,7 @@ TerminalCont(int signo)
{
pending_signal(SIGCONT, SIG_DFL);
pending_signal(SIGTSTP, TerminalStop);
TtyCommandMode(getpgrp() == tcgetpgrp(netfd));
TtyCommandMode(SignalBundle, getpgrp() == tcgetpgrp(netfd));
}
static void
@ -257,9 +258,9 @@ SetUpServer(int signo)
VarHaveLocalAuthKey = 0;
LocalAuthInit();
if ((res = ServerTcpOpen(SERVER_PORT + tunno)) != 0)
if ((res = ServerTcpOpen(SERVER_PORT + SignalBundle->unit)) != 0)
LogPrintf(LogERROR, "SIGUSR1: Failed %d to open port %d\n",
res, SERVER_PORT + tunno);
res, SERVER_PORT + SignalBundle->unit);
}
static void
@ -541,11 +542,11 @@ main(int argc, char **argv)
}
close(STDERR_FILENO);
TtyInit(0);
TtyCommandMode(1);
TtyCommandMode(bundle, 1);
}
snprintf(pid_filename, sizeof pid_filename, "%stun%d.pid",
_PATH_VARRUN, tunno);
_PATH_VARRUN, bundle->unit);
lockfile = ID0fopen(pid_filename, "w");
if (lockfile != NULL) {
fprintf(lockfile, "%d\n", (int) getpid());
@ -585,10 +586,10 @@ PacketMode(struct bundle *bundle, int delay)
LcpOpen(delay);
if (mode & MODE_INTER)
TtyCommandMode(1);
TtyCommandMode(bundle, 0);
if (VarTerm) {
fprintf(VarTerm, "Packet mode.\n");
aft_cmd = 1;
/* aft_cmd = 1; */
}
}
@ -625,7 +626,7 @@ ReadTty(struct bundle *bundle)
linebuff[n] = '\0';
if (n)
DecodeCommand(bundle, linebuff, n, IsInteractive(0) ? NULL : "Client");
Prompt();
Prompt(bundle);
} else if (n <= 0) {
LogPrintf(LogPHASE, "Client connection closed.\n");
DropClient(0);
@ -664,7 +665,7 @@ ReadTty(struct bundle *bundle)
case '.':
TermMode = 1;
aft_cmd = 1;
TtyCommandMode(1);
TtyCommandMode(bundle, 1);
break;
case 't':
if (LogIsKept(LogDEBUG)) {
@ -1008,7 +1009,7 @@ DoLoop(struct bundle *bundle)
VarTerm = fdopen(netfd, "a+");
LocalAuthInit();
IsInteractive(1);
Prompt();
Prompt(bundle);
}
if (netfd >= 0 && FD_ISSET(netfd, &rfds))
/* something to read from tty */
@ -1025,7 +1026,8 @@ DoLoop(struct bundle *bundle)
nointr_usleep(10000);
n = Physical_Read(bundle->physical, rbuff, sizeof rbuff);
if ((mode & MODE_DIRECT) && n <= 0) {
bundle_Down(bundle, &bundle->physical->link);
reconnect(RECON_TRUE);
link_Close(&bundle->physical->link, bundle, 0);
} else
LogDumpBuff(LogASYNC, "ReadFromModem", rbuff, n);

View File

@ -17,15 +17,15 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: main.h,v 1.9 1998/01/20 22:47:41 brian Exp $
* $Id: main.h,v 1.9.2.1 1998/02/02 19:32:10 brian Exp $
*
*/
extern int TermMode;
extern int tunno;
extern int CleaningUp;
extern void Cleanup(int);
extern void TtyTermMode(void);
extern void PacketMode(struct bundle *, int);
extern void TtyOldMode(void);
extern void TtyCommandMode(int);
extern void TtyCommandMode(struct bundle *, int);

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.7 1998/02/06 02:23:46 brian Exp $
* $Id: modem.c,v 1.77.2.8 1998/02/06 02:24:27 brian Exp $
*
* TODO:
*/
@ -235,12 +235,13 @@ modem_Timeout(void *data)
if (to->modem->abort) {
/* Something went horribly wrong */
to->modem->abort = 0;
bundle_Down(to->bundle, &to->modem->link);
link_Close(&to->modem->link, to->bundle, 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));
bundle_Down(to->bundle, &to->modem->link);
reconnect(RECON_TRUE);
link_Close(&to->modem->link, to->bundle, 0);
return;
}
} else
@ -263,7 +264,7 @@ modem_Timeout(void *data)
} else {
LogPrintf(LogDEBUG, "modem_Timeout: online -> offline\n");
reconnect(RECON_TRUE);
bundle_Down(to->bundle, &to->modem->link);
link_Close(&to->modem->link, to->bundle, 0);
}
}
else
@ -382,7 +383,7 @@ OpenConnection(char *host, char *port)
}
static int
modem_lock(struct physical *modem)
modem_lock(struct physical *modem, int tunno)
{
int res;
FILE *lockfile;
@ -484,7 +485,7 @@ modem_Open(struct physical *modem, struct bundle *bundle)
arg.argc = 1;
arg.argv = (char const *const *)&cp;
SetVariable(&arg);
if (modem_lock(modem) == -1) {
if (modem_lock(modem, bundle->unit) == -1) {
close(STDIN_FILENO);
return -1;
}
@ -511,7 +512,7 @@ modem_Open(struct physical *modem, struct bundle *bundle)
VarBaseDevice = VarBaseDevice ? VarBaseDevice + 1 : "";
if (strncmp(VarDevice, "/dev/", 5) == 0) {
if (modem_lock(modem) == -1) {
if (modem_lock(modem, bundle->unit) == -1) {
modem->fd = -1;
}
else {

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.5 1998/02/02 19:32:12 brian Exp $
* $Id: pap.c,v 1.20.2.6 1998/02/02 19:33:39 brian Exp $
*
* TODO:
*/
@ -50,12 +50,12 @@
#include "vars.h"
#include "hdlc.h"
#include "lcpproto.h"
#include "phase.h"
#include "auth.h"
#include "async.h"
#include "throughput.h"
#include "link.h"
#include "physical.h"
#include "bundle.h"
static const char *papcodes[] = { "???", "REQUEST", "ACK", "NAK" };
@ -169,29 +169,34 @@ PapInput(struct bundle *bundle, struct mbuf *bp, struct physical *physical)
if (PapValidate(bundle, cp, cp + *cp + 1, physical)) {
SendPapCode(php->id, PAP_ACK, "Greetings!!", physical);
LcpInfo.auth_ineed = 0;
if (LcpInfo.auth_iwait == 0) {
if ((mode & MODE_DIRECT) && Physical_IsATTY(physical) &&
Enabled(ConfUtmp))
if (Utmp)
LogPrintf(LogERROR, "Oops, already logged in on %s\n",
VarBaseDevice);
else {
struct utmp ut;
memset(&ut, 0, sizeof ut);
time(&ut.ut_time);
strncpy(ut.ut_name, cp+1, sizeof ut.ut_name - 1);
strncpy(ut.ut_line, VarBaseDevice, sizeof ut.ut_line - 1);
if (logout(ut.ut_line))
logwtmp(ut.ut_line, "", "");
login(&ut);
Utmp = 1;
}
NewPhase(bundle, physical, PHASE_NETWORK);
}
if ((mode & MODE_DIRECT) && Physical_IsATTY(physical) &&
Enabled(ConfUtmp))
if (Utmp)
LogPrintf(LogERROR, "Oops, already logged in on %s\n",
VarBaseDevice);
else {
struct utmp ut;
memset(&ut, 0, sizeof ut);
time(&ut.ut_time);
strncpy(ut.ut_name, cp+1, sizeof ut.ut_name - 1);
strncpy(ut.ut_line, VarBaseDevice, sizeof ut.ut_line - 1);
if (logout(ut.ut_line))
logwtmp(ut.ut_line, "", "");
login(&ut);
Utmp = 1;
}
if (LcpInfo.auth_iwait == 0)
/*
* Either I didn't need to authenticate, or I've already been
* told that I got the answer right.
*/
bundle_NewPhase(bundle, physical, PHASE_NETWORK);
} else {
SendPapCode(php->id, PAP_NAK, "Login incorrect", physical);
reconnect(RECON_FALSE);
LcpClose(&LcpInfo.fsm);
reconnect(RECON_FALSE);
bundle_Close(bundle, &LcpInfo.fsm);
}
break;
case PAP_ACK:
@ -203,7 +208,12 @@ PapInput(struct bundle *bundle, struct mbuf *bp, struct physical *physical)
if (LcpInfo.auth_iwait == PROTO_PAP) {
LcpInfo.auth_iwait = 0;
if (LcpInfo.auth_ineed == 0)
NewPhase(bundle, physical, PHASE_NETWORK);
/*
* We've succeeded in our ``login''
* If we're not expecting the peer to authenticate (or he already
* has), proceed to network phase.
*/
bundle_NewPhase(bundle, physical, PHASE_NETWORK);
}
break;
case PAP_NAK:
@ -213,7 +223,7 @@ PapInput(struct bundle *bundle, struct mbuf *bp, struct physical *physical)
cp[len] = 0;
LogPrintf(LogPHASE, "Received PAP_NAK (%s)\n", cp);
reconnect(RECON_FALSE);
LcpClose(&LcpInfo.fsm);
bundle_Close(bundle, &LcpInfo.fsm);
break;
}
}

View File

@ -1,115 +0,0 @@
/*-
* Copyright (c) 1997 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: phase.c,v 1.6.4.6 1998/02/02 19:32:13 brian Exp $
*/
#include <sys/param.h>
#include <netinet/in.h>
#include <stdio.h>
#include <termios.h>
#include "command.h"
#include "mbuf.h"
#include "log.h"
#include "timer.h"
#include "fsm.h"
#include "lcp.h"
#include "lcpproto.h"
#include "auth.h"
#include "pap.h"
#include "chap.h"
#include "defs.h"
#include "iplist.h"
#include "throughput.h"
#include "hdlc.h"
#include "link.h"
#include "ipcp.h"
#include "ccp.h"
#include "main.h"
#include "loadalias.h"
#include "vars.h"
#include "modem.h"
#include "tun.h"
#include "phase.h"
int phase = 0; /* Curent phase */
static const char *PhaseNames[] = {
"Dead", "Establish", "Authenticate", "Network", "Terminate"
};
static const char *
Auth2Nam(u_short auth)
{
switch (auth) {
case PROTO_PAP:
return "PAP";
case PROTO_CHAP:
return "CHAP";
case 0:
return "none";
}
return "unknown";
}
void
NewPhase(struct bundle *bundle, struct physical *physical, int new)
{
phase = new;
LogPrintf(LogPHASE, "NewPhase: %s\n", PhaseNames[phase]);
switch (phase) {
case PHASE_AUTHENTICATE:
LcpInfo.auth_ineed = LcpInfo.want_auth;
LcpInfo.auth_iwait = LcpInfo.his_auth;
if (LcpInfo.his_auth || LcpInfo.want_auth) {
LogPrintf(LogPHASE, " his = %s, mine = %s\n",
Auth2Nam(LcpInfo.his_auth), Auth2Nam(LcpInfo.want_auth));
/* XXX-ML AuthPapInfo and AuthChapInfo must be allocated! */
if (LcpInfo.his_auth == PROTO_PAP)
StartAuthChallenge(&AuthPapInfo, physical);
if (LcpInfo.want_auth == PROTO_CHAP)
StartAuthChallenge(&AuthChapInfo, physical);
} else
NewPhase(bundle, physical, PHASE_NETWORK);
break;
case PHASE_NETWORK:
tun_configure(bundle, LcpInfo.his_mru, modem_Speed(physical));
IpcpUp();
IpcpOpen();
CcpUp();
CcpOpen();
break;
case PHASE_DEAD:
if (mode & MODE_DIRECT)
Cleanup(EX_DEAD);
if (mode & MODE_BACKGROUND && reconnectState != RECON_TRUE)
Cleanup(EX_DEAD);
break;
}
}

View File

@ -1,33 +0,0 @@
/*
* Written by Toshiharu OHNO (tony-o@iij.ad.jp)
*
* Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
*
* 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 Internet Initiative Japan. The name of the
* IIJ 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.
*
* $Id: phase.h,v 1.9.2.1 1998/01/29 00:49:28 brian Exp $
*
* TODO:
*/
struct physical;
#define PHASE_DEAD 0 /* Link is dead */
#define PHASE_ESTABLISH 1 /* Establishing link */
#define PHASE_AUTHENTICATE 2 /* Being authenticated */
#define PHASE_NETWORK 3
#define PHASE_TERMINATE 4 /* Terminating link */
extern int phase; /* Curent phase */
extern void NewPhase(struct bundle *, struct physical *physical, int);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: route.c,v 1.42.2.4 1998/02/02 19:32:14 brian Exp $
* $Id: route.c,v 1.42.2.5 1998/02/02 19:33:01 brian Exp $
*
*/
@ -431,28 +431,3 @@ GetIfIndex(char *name)
idx++;
return -1;
}
struct in_addr
ChooseHisAddr(struct bundle *bundle, const struct in_addr gw)
{
struct in_addr try;
int f;
for (f = 0; f < IpcpInfo.DefHisChoice.nItems; f++) {
try = iplist_next(&IpcpInfo.DefHisChoice);
LogPrintf(LogDEBUG, "ChooseHisAddr: Check item %d (%s)\n",
f, inet_ntoa(try));
if (bundle_TrySetIPaddress(bundle, gw, try) == 0) {
LogPrintf(LogIPCP, "ChooseHisAddr: Selected IP address %s\n",
inet_ntoa(try));
break;
}
}
if (f == IpcpInfo.DefHisChoice.nItems) {
LogPrintf(LogDEBUG, "ChooseHisAddr: All addresses in use !\n");
try.s_addr = INADDR_ANY;
}
return try;
}

View File

@ -17,12 +17,11 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: route.h,v 1.10.2.1 1998/02/02 19:32:15 brian Exp $
* $Id: route.h,v 1.10.2.2 1998/02/02 19:33:02 brian Exp $
*
*/
extern int GetIfIndex(char *);
extern int ShowRoute(struct cmdargs const *);
extern void DeleteIfRoutes(struct bundle *, int);
extern struct in_addr ChooseHisAddr(struct bundle *, const struct in_addr);
extern const char *Index2Nam(int);