bundle.c (85602e5267f413a849370d3c6fe3d0a87cdd5b49) bundle.c (565e35e50e2cdac423588a3d18742544bde128b0)
1/*-
2 * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id: bundle.c,v 1.1.2.42 1998/04/07 01:49:24 brian Exp $
26 * $Id: bundle.c,v 1.1.2.43 1998/04/07 23:45:41 brian Exp $
27 */
28
29#include <sys/types.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <net/if.h>
33#include <arpa/inet.h>
34#include <net/route.h>

--- 159 unchanged lines hidden (view full) ---

194
195void
196bundle_LayerUp(struct bundle *bundle, struct fsm *fp)
197{
198 /*
199 * The given fsm is now up
200 * If it's an LCP (including MP initialisation), set our mtu
201 * (This routine is also called from mp_Init() with it's LCP)
27 */
28
29#include <sys/types.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <net/if.h>
33#include <arpa/inet.h>
34#include <net/route.h>

--- 159 unchanged lines hidden (view full) ---

194
195void
196bundle_LayerUp(struct bundle *bundle, struct fsm *fp)
197{
198 /*
199 * The given fsm is now up
200 * If it's an LCP (including MP initialisation), set our mtu
201 * (This routine is also called from mp_Init() with it's LCP)
202 * If it's an NCP, tell our background mode parent to go away.
202 * If it's an NCP, tell our -background parent to go away.
203 * If it's the first NCP, start the idle timer.
204 */
205
206 if (fp->proto == PROTO_LCP) {
207 if (bundle->ncp.mp.active) {
208 int speed;
209 struct datalink *dl;
210

--- 206 unchanged lines hidden (view full) ---

417#define MAX_TUN 256
418/*
419 * MAX_TUN is set at 256 because that is the largest minor number
420 * we can use (certainly with mknod(1) anyway). The search for a
421 * device aborts when it reaches the first `Device not configured'
422 * (ENXIO) or the third `No such file or directory' (ENOENT) error.
423 */
424struct bundle *
203 * If it's the first NCP, start the idle timer.
204 */
205
206 if (fp->proto == PROTO_LCP) {
207 if (bundle->ncp.mp.active) {
208 int speed;
209 struct datalink *dl;
210

--- 206 unchanged lines hidden (view full) ---

417#define MAX_TUN 256
418/*
419 * MAX_TUN is set at 256 because that is the largest minor number
420 * we can use (certainly with mknod(1) anyway). The search for a
421 * device aborts when it reaches the first `Device not configured'
422 * (ENXIO) or the third `No such file or directory' (ENOENT) error.
423 */
424struct bundle *
425bundle_Create(const char *prefix, struct prompt *prompt)
425bundle_Create(const char *prefix, struct prompt *prompt, int type)
426{
427 int s, enoentcount, err;
428 struct ifreq ifrq;
429 static struct bundle bundle; /* there can be only one */
430
431 if (bundle.ifname != NULL) { /* Already allocated ! */
432 LogPrintf(LogERROR, "bundle_Create: There's only one BUNDLE !\n");
433 return NULL;

--- 79 unchanged lines hidden (view full) ---

513
514 bundle.fsm.LayerStart = bundle_LayerStart;
515 bundle.fsm.LayerUp = bundle_vLayerUp;
516 bundle.fsm.LayerDown = bundle_LayerDown;
517 bundle.fsm.LayerFinish = bundle_LayerFinish;
518 bundle.fsm.object = &bundle;
519
520 bundle.cfg.idle_timeout = NCP_IDLE_TIMEOUT;
426{
427 int s, enoentcount, err;
428 struct ifreq ifrq;
429 static struct bundle bundle; /* there can be only one */
430
431 if (bundle.ifname != NULL) { /* Already allocated ! */
432 LogPrintf(LogERROR, "bundle_Create: There's only one BUNDLE !\n");
433 return NULL;

--- 79 unchanged lines hidden (view full) ---

513
514 bundle.fsm.LayerStart = bundle_LayerStart;
515 bundle.fsm.LayerUp = bundle_vLayerUp;
516 bundle.fsm.LayerDown = bundle_LayerDown;
517 bundle.fsm.LayerFinish = bundle_LayerFinish;
518 bundle.fsm.object = &bundle;
519
520 bundle.cfg.idle_timeout = NCP_IDLE_TIMEOUT;
521 bundle.phys_type = type;
521
522
522 bundle.links = datalink_Create("Modem", &bundle, &bundle.fsm);
523 bundle.links = datalink_Create("default", &bundle, &bundle.fsm, type);
523 if (bundle.links == NULL) {
524 LogPrintf(LogERROR, "Cannot create data link: %s\n", strerror(errno));
525 close(bundle.tun_fd);
526 bundle.ifname = NULL;
527 return NULL;
528 }
529
530 bundle.desc.type = BUNDLE_DESCRIPTOR;

--- 65 unchanged lines hidden (view full) ---

596}
597
598void
599bundle_Destroy(struct bundle *bundle)
600{
601 struct datalink *dl;
602 struct descriptor *desc, *ndesc;
603
524 if (bundle.links == NULL) {
525 LogPrintf(LogERROR, "Cannot create data link: %s\n", strerror(errno));
526 close(bundle.tun_fd);
527 bundle.ifname = NULL;
528 return NULL;
529 }
530
531 bundle.desc.type = BUNDLE_DESCRIPTOR;

--- 65 unchanged lines hidden (view full) ---

597}
598
599void
600bundle_Destroy(struct bundle *bundle)
601{
602 struct datalink *dl;
603 struct descriptor *desc, *ndesc;
604
604
605 if (mode & MODE_AUTO) {
606 IpcpCleanInterface(&bundle->ncp.ipcp.fsm);
605 if (bundle->phys_type & PHYS_DEMAND) {
606 IpcpCleanInterface(&bundle->ncp.ipcp);
607 bundle_DownInterface(bundle);
608 }
609
610 dl = bundle->links;
611 while (dl)
612 dl = datalink_Destroy(dl);
613
614 bundle_Notify(bundle, EX_ERRDEAD);

--- 124 unchanged lines hidden (view full) ---

739 cmdstr, inet_ntoa(dst), strerror(rtmes.m_rtm.rtm_errno));
740 }
741 LogPrintf(LogDEBUG, "wrote %d: cmd = %s, dst = %x, gateway = %x\n",
742 wb, cmdstr, dst.s_addr, gateway.s_addr);
743 close(s);
744}
745
746void
607 bundle_DownInterface(bundle);
608 }
609
610 dl = bundle->links;
611 while (dl)
612 dl = datalink_Destroy(dl);
613
614 bundle_Notify(bundle, EX_ERRDEAD);

--- 124 unchanged lines hidden (view full) ---

739 cmdstr, inet_ntoa(dst), strerror(rtmes.m_rtm.rtm_errno));
740 }
741 LogPrintf(LogDEBUG, "wrote %d: cmd = %s, dst = %x, gateway = %x\n",
742 wb, cmdstr, dst.s_addr, gateway.s_addr);
743 close(s);
744}
745
746void
747bundle_LinkLost(struct bundle *bundle, struct link *link, int staydown)
747bundle_LinkLost(struct bundle *bundle, struct physical *p, int staydown)
748{
749 /*
750 * Locate the appropriate datalink, and Down it.
751 *
752 * The LayerFinish() called from the datalinks LCP will
753 * potentially Down our NCPs (if it's the last link).
754 *
755 * The LinkClosed() called when the datalink is finally in
756 * the CLOSED state MAY cause the entire datalink to be deleted
757 * and MAY cause a program exit.
758 */
759
748{
749 /*
750 * Locate the appropriate datalink, and Down it.
751 *
752 * The LayerFinish() called from the datalinks LCP will
753 * potentially Down our NCPs (if it's the last link).
754 *
755 * The LinkClosed() called when the datalink is finally in
756 * the CLOSED state MAY cause the entire datalink to be deleted
757 * and MAY cause a program exit.
758 */
759
760 if ((mode & MODE_DIRECT) || bundle->CleaningUp)
760 if (p->type == PHYS_STDIN || bundle->CleaningUp)
761 staydown = 1;
761 staydown = 1;
762 datalink_Down(bundle->links, staydown);
762 datalink_Down(p->dl, staydown);
763}
764
765void
766bundle_LinkClosed(struct bundle *bundle, struct datalink *dl)
767{
768 /*
769 * Our datalink has closed.
763}
764
765void
766bundle_LinkClosed(struct bundle *bundle, struct datalink *dl)
767{
768 /*
769 * Our datalink has closed.
770 * If it's DIRECT or BACKGROUND, delete it.
770 * UpdateSet() will remove 1OFF and STDIN links.
771 * If it's the last data link, enter phase DEAD.
772 */
773
774 struct datalink *odl;
775 int other_links;
776
771 * If it's the last data link, enter phase DEAD.
772 */
773
774 struct datalink *odl;
775 int other_links;
776
777 if (mode & (MODE_DIRECT|MODE_BACKGROUND)) {
778 struct datalink **dlp;
779 for (dlp = &bundle->links; *dlp; dlp = &(*dlp)->next)
780 if (*dlp == dl)
781 *dlp = datalink_Destroy(*dlp);
782 }
783
784 other_links = 0;
785 for (odl = bundle->links; odl; odl = odl->next)
786 if (odl != dl && odl->state != DATALINK_CLOSED)
787 other_links++;
788
789 if (!other_links) {
777 other_links = 0;
778 for (odl = bundle->links; odl; odl = odl->next)
779 if (odl != dl && odl->state != DATALINK_CLOSED)
780 other_links++;
781
782 if (!other_links) {
790 if (!(mode & MODE_AUTO))
783 if (dl->physical->type != PHYS_DEMAND)
791 bundle_DownInterface(bundle);
792 bundle_NewPhase(bundle, PHASE_DEAD);
793 bundle_DisplayPrompt(bundle);
794 }
795}
796
797void
784 bundle_DownInterface(bundle);
785 bundle_NewPhase(bundle, PHASE_DEAD);
786 bundle_DisplayPrompt(bundle);
787 }
788}
789
790void
798bundle_Open(struct bundle *bundle, const char *name)
791bundle_Open(struct bundle *bundle, const char *name, int mask)
799{
800 /*
801 * Please open the given datalink, or all if name == NULL
802 */
803 struct datalink *dl;
792{
793 /*
794 * Please open the given datalink, or all if name == NULL
795 */
796 struct datalink *dl;
804 int runscripts;
805
797
806 runscripts = (mode & (MODE_DIRECT|MODE_DEDICATED)) ? 0 : 1;
807 for (dl = bundle->links; dl; dl = dl->next)
808 if (name == NULL || !strcasecmp(dl->name, name)) {
798 for (dl = bundle->links; dl; dl = dl->next)
799 if (name == NULL || !strcasecmp(dl->name, name)) {
809 datalink_Up(dl, runscripts, 1);
800 if (mask & dl->physical->type)
801 datalink_Up(dl, 1, 1);
810 if (name != NULL)
811 break;
812 }
813}
814
815struct datalink *
816bundle2datalink(struct bundle *bundle, const char *name)
817{

--- 52 unchanged lines hidden (view full) ---

870
871/*
872 * Start Idle timer. If timeout is reached, we call bundle_Close() to
873 * close LCP and link.
874 */
875void
876bundle_StartIdleTimer(struct bundle *bundle)
877{
802 if (name != NULL)
803 break;
804 }
805}
806
807struct datalink *
808bundle2datalink(struct bundle *bundle, const char *name)
809{

--- 52 unchanged lines hidden (view full) ---

862
863/*
864 * Start Idle timer. If timeout is reached, we call bundle_Close() to
865 * close LCP and link.
866 */
867void
868bundle_StartIdleTimer(struct bundle *bundle)
869{
878 if (!(mode & (MODE_DEDICATED | MODE_DDIAL)) && bundle->cfg.idle_timeout) {
870 if (!(bundle->phys_type & (PHYS_DEDICATED|PHYS_PERM)) &&
871 bundle->cfg.idle_timeout) {
879 StopTimer(&bundle->idle.timer);
880 bundle->idle.timer.func = bundle_IdleTimeout;
881 bundle->idle.timer.name = "idle";
882 bundle->idle.timer.load = bundle->cfg.idle_timeout * SECTICKS;
883 bundle->idle.timer.state = TIMER_STOPPED;
884 bundle->idle.timer.arg = bundle;
885 StartTimer(&bundle->idle.timer);
886 bundle->idle.done = time(NULL) + bundle->cfg.idle_timeout;

--- 101 unchanged lines hidden (view full) ---

988
989 for (desc = bundle->desc.next; desc; desc = desc->next)
990 if (desc->type == PROMPT_DESCRIPTOR) {
991 p = (struct prompt *)desc;
992 if (prompt_IsTermMode(p, dl))
993 prompt_TtyCommandMode(p);
994 }
995}
872 StopTimer(&bundle->idle.timer);
873 bundle->idle.timer.func = bundle_IdleTimeout;
874 bundle->idle.timer.name = "idle";
875 bundle->idle.timer.load = bundle->cfg.idle_timeout * SECTICKS;
876 bundle->idle.timer.state = TIMER_STOPPED;
877 bundle->idle.timer.arg = bundle;
878 StartTimer(&bundle->idle.timer);
879 bundle->idle.done = time(NULL) + bundle->cfg.idle_timeout;

--- 101 unchanged lines hidden (view full) ---

981
982 for (desc = bundle->desc.next; desc; desc = desc->next)
983 if (desc->type == PROMPT_DESCRIPTOR) {
984 p = (struct prompt *)desc;
985 if (prompt_IsTermMode(p, dl))
986 prompt_TtyCommandMode(p);
987 }
988}
989
990static void
991bundle_GenPhysType(struct bundle *bundle)
992{
993 struct datalink *dl;
994
995 bundle->phys_type = 0;
996 for (dl = bundle->links; dl; dl = dl->next)
997 bundle->phys_type |= dl->physical->type;
998}
999
996void
997bundle_DatalinkClone(struct bundle *bundle, struct datalink *dl,
998 const char *name)
999{
1000 struct datalink *ndl = datalink_Clone(dl, name);
1001
1002 ndl->next = dl->next;
1003 dl->next = ndl;
1000void
1001bundle_DatalinkClone(struct bundle *bundle, struct datalink *dl,
1002 const char *name)
1003{
1004 struct datalink *ndl = datalink_Clone(dl, name);
1005
1006 ndl->next = dl->next;
1007 dl->next = ndl;
1008 bundle_GenPhysType(bundle);
1004}
1005
1006void
1007bundle_DatalinkRemove(struct bundle *bundle, struct datalink *dl)
1008{
1009 struct datalink **dlp;
1010
1011 if (dl->state == DATALINK_CLOSED)
1012 for (dlp = &bundle->links; *dlp; dlp = &(*dlp)->next)
1013 if (*dlp == dl) {
1014 *dlp = datalink_Destroy(dl);
1015 break;
1016 }
1009}
1010
1011void
1012bundle_DatalinkRemove(struct bundle *bundle, struct datalink *dl)
1013{
1014 struct datalink **dlp;
1015
1016 if (dl->state == DATALINK_CLOSED)
1017 for (dlp = &bundle->links; *dlp; dlp = &(*dlp)->next)
1018 if (*dlp == dl) {
1019 *dlp = datalink_Destroy(dl);
1020 break;
1021 }
1022 bundle_GenPhysType(bundle);
1017}
1023}
1024
1025void
1026bundle_CleanDatalinks(struct bundle *bundle)
1027{
1028 struct datalink **dlp = &bundle->links;
1029
1030 while (*dlp)
1031 if ((*dlp)->state == DATALINK_CLOSED &&
1032 (*dlp)->physical->type & (PHYS_STDIN|PHYS_1OFF))
1033 *dlp = datalink_Destroy(*dlp);
1034 else
1035 dlp = &(*dlp)->next;
1036 bundle_GenPhysType(bundle);
1037}