o Add bundle_Destroy().

o Don't remove routes and DOWN the interface when we're
  closed in auto mode.
o Initialize the FSMs in bundle_Create.
o Initialize ipcp::if_mine & ipcp::if_peer only once (so
  that we don't forget that we've SIOCAIFADDR'd the interface).
o Do a SIOCDIFADDR on the specific address to avoid hurting any
  other (still non-existent) NCPs.
o Fix some error/diagnostic messages.
This commit is contained in:
Brian Somers 1998-02-08 19:29:45 +00:00
parent 1afedc4b86
commit 68a0f0ccdd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/MP/; revision=33174
5 changed files with 110 additions and 83 deletions

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.4 1998/02/06 02:24:01 brian Exp $
* $Id: bundle.c,v 1.1.2.5 1998/02/07 20:49:23 brian Exp $
*/
#include <sys/param.h>
@ -354,9 +354,58 @@ bundle_Create(const char *prefix)
return NULL;
}
IpcpDefAddress();
LcpInit(&bundle, bundle.physical);
IpcpInit(&bundle, physical2link(bundle.physical));
CcpInit(&bundle, physical2link(bundle.physical));
return &bundle;
}
static void
bundle_DownInterface(struct bundle *bundle)
{
struct ifreq ifrq;
int s;
DeleteIfRoutes(bundle, 1);
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
LogPrintf(LogERROR, "bundle_DownInterface: 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, "bundle_DownInterface: ioctl(SIOCGIFFLAGS): %s\n",
strerror(errno));
close(s);
return;
}
ifrq.ifr_flags &= ~IFF_UP;
if (ID0ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
LogPrintf(LogERROR, "bundle_DownInterface: ioctl(SIOCSIFFLAGS): %s\n",
strerror(errno));
close(s);
return;
}
close(s);
}
void
bundle_Destroy(struct bundle *bundle)
{
if (mode & MODE_AUTO) {
IpcpCleanInterface(&IpcpInfo.fsm);
bundle_DownInterface(bundle);
}
link_Destroy(&bundle->physical->link);
bundle->ifname = NULL;
}
struct rtmsg {
struct rt_msghdr m_rtm;
char m_space[64];
@ -378,7 +427,7 @@ bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst,
cmdstr = (cmd == RTM_ADD ? "Add" : "Delete");
s = ID0socket(PF_ROUTE, SOCK_RAW, 0);
if (s < 0) {
LogPrintf(LogERROR, "OsSetRoute: socket(): %s\n", strerror(errno));
LogPrintf(LogERROR, "bundle_SetRoute: socket(): %s\n", strerror(errno));
return;
}
memset(&rtmes, '\0', sizeof rtmes);
@ -439,11 +488,11 @@ bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst,
rtmes.m_rtm.rtm_msglen = nb;
wb = ID0write(s, &rtmes, nb);
if (wb < 0) {
LogPrintf(LogTCPIP, "OsSetRoute failure:\n");
LogPrintf(LogTCPIP, "OsSetRoute: Cmd = %s\n", cmd);
LogPrintf(LogTCPIP, "OsSetRoute: Dst = %s\n", inet_ntoa(dst));
LogPrintf(LogTCPIP, "OsSetRoute: Gateway = %s\n", inet_ntoa(gateway));
LogPrintf(LogTCPIP, "OsSetRoute: Mask = %s\n", inet_ntoa(mask));
LogPrintf(LogTCPIP, "bundle_SetRoute failure:\n");
LogPrintf(LogTCPIP, "bundle_SetRoute: Cmd = %s\n", cmd);
LogPrintf(LogTCPIP, "bundle_SetRoute: Dst = %s\n", inet_ntoa(dst));
LogPrintf(LogTCPIP, "bundle_SetRoute: Gateway = %s\n", inet_ntoa(gateway));
LogPrintf(LogTCPIP, "bundle_SetRoute: Mask = %s\n", inet_ntoa(mask));
failed:
if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST ||
(rtmes.m_rtm.rtm_errno == 0 && errno == EEXIST)))
@ -515,9 +564,6 @@ bundle_LayerFinish(struct bundle *bundle, struct fsm *fp)
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 */
@ -526,31 +572,8 @@ bundle_LayerFinish(struct bundle *bundle, struct fsm *fp)
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);
if (!(mode & MODE_AUTO))
bundle_DownInterface(bundle);
bundle_NewPhase(bundle, NULL, PHASE_DEAD);
} else if (fp == &IpcpInfo.fsm) {
FsmClose(&LcpInfo.fsm);

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.5 1998/02/06 02:24:02 brian Exp $
* $Id: bundle.h,v 1.1.2.6 1998/02/07 20:49:24 brian Exp $
*/
#define PHASE_DEAD 0 /* Link is dead */
@ -48,7 +48,8 @@ struct bundle {
struct physical *physical; /* For the time being */
};
extern struct bundle *bundle_Create(const char *dev);
extern struct bundle *bundle_Create(const char *);
extern void bundle_Destroy(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);

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.9 1998/02/07 20:49:41 brian Exp $
* $Id: ipcp.c,v 1.50.2.10 1998/02/08 11:04:51 brian Exp $
*
* TODO:
* o More RFC1772 backwoard compatibility
@ -202,6 +202,7 @@ IpcpDefAddress()
if (hp && hp->h_addrtype == AF_INET)
memcpy(&IpcpInfo.DefMyAddress.ipaddr.s_addr, hp->h_addr, hp->h_length);
}
IpcpInfo.if_mine.s_addr = IpcpInfo.if_peer.s_addr = INADDR_ANY;
}
int
@ -257,7 +258,6 @@ 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) +
@ -287,6 +287,8 @@ ipcp_SetIPaddress(struct bundle *bundle, struct ipcp *ipcp,
ipcp->if_peer.s_addr == hisaddr.s_addr)
return 0;
IpcpCleanInterface(&ipcp->fsm);
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
LogPrintf(LogERROR, "SetIpDevice: socket(): %s\n", strerror(errno));
@ -297,16 +299,6 @@ ipcp_SetIPaddress(struct bundle *bundle, struct ipcp *ipcp,
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;
@ -454,6 +446,45 @@ IpcpLayerFinish(struct fsm *fp)
LogPrintf(LogIPCP, "IpcpLayerFinish.\n");
}
void
IpcpCleanInterface(struct fsm *fp)
{
struct ipcp *ipcp = fsm2ipcp(fp);
struct ifaliasreq ifra;
struct sockaddr_in *me, *peer;
int s;
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
LogPrintf(LogERROR, "IpcpCleanInterface: 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';
me = (struct sockaddr_in *)&ifra.ifra_addr;
peer = (struct sockaddr_in *)&ifra.ifra_broadaddr;
me->sin_family = peer->sin_family = AF_INET;
me->sin_len = peer->sin_len = sizeof(struct sockaddr_in);
me->sin_addr = ipcp->if_mine;
peer->sin_addr = ipcp->if_peer;
if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0) {
LogPrintf(LogERROR, "IpcpCleanInterface: ioctl(SIOCDIFADDR): %s\n",
strerror(errno));
close(s);
}
ipcp->if_mine.s_addr = ipcp->if_peer.s_addr = INADDR_ANY;
}
close(s);
}
static void
IpcpLayerDown(struct fsm *fp)
{
@ -478,37 +509,8 @@ IpcpLayerDown(struct fsm *fp)
} 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;
}
if (!(mode & MODE_AUTO))
IpcpCleanInterface(fp);
}
static void

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.10 1998/02/07 20:49:43 brian Exp $
* $Id: ipcp.h,v 1.18.2.11 1998/02/08 11:04:52 brian Exp $
*
* TODO:
*/
@ -89,3 +89,4 @@ extern void IpcpAddInOctets(int);
extern void IpcpAddOutOctets(int);
extern int UseHisaddr(struct bundle *, const char *, int);
extern int SetInitVJ(struct cmdargs const *);
extern void IpcpCleanInterface(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: main.c,v 1.121.2.13 1998/02/08 11:05:01 brian Exp $
* $Id: main.c,v 1.121.2.14 1998/02/08 11:07:31 brian Exp $
*
* TODO:
* o Add commands for traffic summary, version display, etc.
@ -211,6 +211,7 @@ AbortProgram(int excode)
TtyOldMode();
link_Destroy(physical2link(SignalBundle->physical));
LogClose();
bundle_Destroy(SignalBundle);
exit(excode);
}
@ -422,7 +423,6 @@ main(int argc, char **argv)
if (!GetShortHost())
return 1;
IsInteractive(1);
IpcpDefAddress();
SignalBundle = bundle;