bundle.c revision 36285
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 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
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.89 1998/05/21 01:13:19 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>
35#include <net/if_dl.h>
36#include <netinet/in_systm.h>
37#include <netinet/ip.h>
38#include <net/if_tun.h>
39#include <sys/un.h>
40
41#include <errno.h>
42#include <fcntl.h>
43#include <paths.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <sys/ioctl.h>
48#include <sys/uio.h>
49#include <termios.h>
50#include <unistd.h>
51
52#include "command.h"
53#include "mbuf.h"
54#include "log.h"
55#include "id.h"
56#include "defs.h"
57#include "timer.h"
58#include "fsm.h"
59#include "iplist.h"
60#include "lqr.h"
61#include "hdlc.h"
62#include "throughput.h"
63#include "slcompress.h"
64#include "ipcp.h"
65#include "filter.h"
66#include "descriptor.h"
67#include "route.h"
68#include "lcp.h"
69#include "ccp.h"
70#include "link.h"
71#include "mp.h"
72#include "bundle.h"
73#include "async.h"
74#include "physical.h"
75#include "modem.h"
76#include "loadalias.h"
77#include "auth.h"
78#include "lcpproto.h"
79#include "chap.h"
80#include "tun.h"
81#include "prompt.h"
82#include "chat.h"
83#include "datalink.h"
84#include "ip.h"
85
86#define SCATTER_SEGMENTS 4	/* version, datalink, name, physical */
87#define SOCKET_OVERHEAD	100	/* additional buffer space for large */
88                                /* {recv,send}msg() calls            */
89
90static int bundle_RemainingIdleTime(struct bundle *);
91static int bundle_RemainingAutoLoadTime(struct bundle *);
92
93static const char *PhaseNames[] = {
94  "Dead", "Establish", "Authenticate", "Network", "Terminate"
95};
96
97const char *
98bundle_PhaseName(struct bundle *bundle)
99{
100  return bundle->phase <= PHASE_TERMINATE ?
101    PhaseNames[bundle->phase] : "unknown";
102}
103
104void
105bundle_NewPhase(struct bundle *bundle, u_int new)
106{
107  if (new == bundle->phase)
108    return;
109
110  if (new <= PHASE_TERMINATE)
111    log_Printf(LogPHASE, "bundle: %s\n", PhaseNames[new]);
112
113  switch (new) {
114  case PHASE_DEAD:
115    bundle->phase = new;
116    break;
117
118  case PHASE_ESTABLISH:
119    bundle->phase = new;
120    break;
121
122  case PHASE_AUTHENTICATE:
123    bundle->phase = new;
124    bundle_DisplayPrompt(bundle);
125    break;
126
127  case PHASE_NETWORK:
128    ipcp_Setup(&bundle->ncp.ipcp);
129    fsm_Up(&bundle->ncp.ipcp.fsm);
130    fsm_Open(&bundle->ncp.ipcp.fsm);
131    bundle->phase = new;
132    bundle_DisplayPrompt(bundle);
133    break;
134
135  case PHASE_TERMINATE:
136    bundle->phase = new;
137    mp_Down(&bundle->ncp.mp);
138    bundle_DisplayPrompt(bundle);
139    break;
140  }
141}
142
143static int
144bundle_CleanInterface(const struct bundle *bundle)
145{
146  int s;
147  struct ifreq ifrq;
148  struct ifaliasreq ifra;
149
150  s = ID0socket(AF_INET, SOCK_DGRAM, 0);
151  if (s < 0) {
152    log_Printf(LogERROR, "bundle_CleanInterface: socket(): %s\n",
153              strerror(errno));
154    return (-1);
155  }
156  strncpy(ifrq.ifr_name, bundle->ifp.Name, sizeof ifrq.ifr_name - 1);
157  ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0';
158  while (ID0ioctl(s, SIOCGIFADDR, &ifrq) == 0) {
159    memset(&ifra.ifra_mask, '\0', sizeof ifra.ifra_mask);
160    strncpy(ifra.ifra_name, bundle->ifp.Name, sizeof ifra.ifra_name - 1);
161    ifra.ifra_name[sizeof ifra.ifra_name - 1] = '\0';
162    ifra.ifra_addr = ifrq.ifr_addr;
163    if (ID0ioctl(s, SIOCGIFDSTADDR, &ifrq) < 0) {
164      if (ifra.ifra_addr.sa_family == AF_INET)
165        log_Printf(LogERROR,
166                  "bundle_CleanInterface: Can't get dst for %s on %s !\n",
167                  inet_ntoa(((struct sockaddr_in *)&ifra.ifra_addr)->sin_addr),
168                  bundle->ifp.Name);
169      close(s);
170      return 0;
171    }
172    ifra.ifra_broadaddr = ifrq.ifr_dstaddr;
173    if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0) {
174      if (ifra.ifra_addr.sa_family == AF_INET)
175        log_Printf(LogERROR,
176                  "bundle_CleanInterface: Can't delete %s address on %s !\n",
177                  inet_ntoa(((struct sockaddr_in *)&ifra.ifra_addr)->sin_addr),
178                  bundle->ifp.Name);
179      close(s);
180      return 0;
181    }
182  }
183  close(s);
184
185  return 1;
186}
187
188static void
189bundle_LayerStart(void *v, struct fsm *fp)
190{
191  /* The given FSM is about to start up ! */
192}
193
194
195static void
196bundle_Notify(struct bundle *bundle, char c)
197{
198  if (bundle->notify.fd != -1) {
199    if (write(bundle->notify.fd, &c, 1) == 1)
200      log_Printf(LogPHASE, "Parent notified of success.\n");
201    else
202      log_Printf(LogPHASE, "Failed to notify parent of success.\n");
203    close(bundle->notify.fd);
204    bundle->notify.fd = -1;
205  }
206}
207
208static void
209bundle_AutoLoadTimeout(void *v)
210{
211  struct bundle *bundle = (struct bundle *)v;
212
213  if (bundle->autoload.comingup) {
214    log_Printf(LogPHASE, "autoload: Another link is required\n");
215    /* bundle_Open() stops the timer */
216    bundle_Open(bundle, NULL, PHYS_DEMAND);
217  } else {
218    struct datalink *dl, *last;
219
220    timer_Stop(&bundle->autoload.timer);
221    for (last = NULL, dl = bundle->links; dl; dl = dl->next)
222      if (dl->physical->type == PHYS_DEMAND && dl->state == DATALINK_OPEN)
223        last = dl;
224
225    if (last)
226      datalink_Close(last, 1);
227  }
228}
229
230static void
231bundle_StartAutoLoadTimer(struct bundle *bundle, int up)
232{
233  struct datalink *dl;
234
235  timer_Stop(&bundle->autoload.timer);
236
237  if (bundle->CleaningUp || bundle->phase != PHASE_NETWORK) {
238    dl = NULL;
239    bundle->autoload.running = 0;
240  } else if (up) {
241    for (dl = bundle->links; dl; dl = dl->next)
242      if (dl->state == DATALINK_CLOSED && dl->physical->type == PHYS_DEMAND) {
243        if (bundle->cfg.autoload.max.timeout) {
244          bundle->autoload.timer.func = bundle_AutoLoadTimeout;
245          bundle->autoload.timer.name = "autoload up";
246          bundle->autoload.timer.load =
247            bundle->cfg.autoload.max.timeout * SECTICKS;
248          bundle->autoload.timer.arg = bundle;
249          timer_Start(&bundle->autoload.timer);
250          bundle->autoload.done = time(NULL) + bundle->cfg.autoload.max.timeout;
251        } else
252          bundle_AutoLoadTimeout(bundle);
253        break;
254      }
255    bundle->autoload.running = (dl || bundle->cfg.autoload.min.timeout) ? 1 : 0;
256  } else {
257    int nlinks;
258    struct datalink *adl;
259
260    for (nlinks = 0, adl = NULL, dl = bundle->links; dl; dl = dl->next)
261      if (dl->state == DATALINK_OPEN) {
262        if (dl->physical->type == PHYS_DEMAND)
263          adl = dl;
264        if (++nlinks > 1 && adl) {
265          if (bundle->cfg.autoload.min.timeout) {
266            bundle->autoload.timer.func = bundle_AutoLoadTimeout;
267            bundle->autoload.timer.name = "autoload down";
268            bundle->autoload.timer.load =
269              bundle->cfg.autoload.min.timeout * SECTICKS;
270            bundle->autoload.timer.arg = bundle;
271            timer_Start(&bundle->autoload.timer);
272            bundle->autoload.done =
273              time(NULL) + bundle->cfg.autoload.min.timeout;
274          }
275          break;
276        }
277      }
278
279    bundle->autoload.running = 1;
280  }
281
282  bundle->autoload.comingup = up ? 1 : 0;
283}
284
285static void
286bundle_StopAutoLoadTimer(struct bundle *bundle)
287{
288  timer_Stop(&bundle->autoload.timer);
289  bundle->autoload.done = 0;
290}
291
292static int
293bundle_RemainingAutoLoadTime(struct bundle *bundle)
294{
295  if (bundle->autoload.done)
296    return bundle->autoload.done - time(NULL);
297  return -1;
298}
299
300
301static void
302bundle_LayerUp(void *v, struct fsm *fp)
303{
304  /*
305   * The given fsm is now up
306   * If it's an LCP set our mtu (if we're multilink, add up the link
307   * speeds and set the MRRU) and start our autoload timer.
308   * If it's an NCP, tell our -background parent to go away.
309   * If it's the first NCP, start the idle timer.
310   */
311  struct bundle *bundle = (struct bundle *)v;
312
313  if (fp->proto == PROTO_LCP) {
314    if (bundle->ncp.mp.active) {
315      struct datalink *dl;
316
317      bundle->ifp.Speed = 0;
318      for (dl = bundle->links; dl; dl = dl->next)
319        if (dl->state == DATALINK_OPEN)
320          bundle->ifp.Speed += modem_Speed(dl->physical);
321      tun_configure(bundle, bundle->ncp.mp.peer_mrru);
322      bundle->autoload.running = 1;
323    } else {
324      bundle->ifp.Speed = modem_Speed(link2physical(fp->link));
325      tun_configure(bundle, fsm2lcp(fp)->his_mru);
326    }
327  } else if (fp->proto == PROTO_IPCP) {
328    bundle_StartIdleTimer(bundle);
329    bundle_Notify(bundle, EX_NORMAL);
330  }
331}
332
333static void
334bundle_LayerDown(void *v, struct fsm *fp)
335{
336  /*
337   * The given FSM has been told to come down.
338   * If it's our last NCP, stop the idle timer.
339   * If it's an LCP and we're in multilink mode, adjust our tun speed.
340   */
341
342  struct bundle *bundle = (struct bundle *)v;
343
344  if (fp->proto == PROTO_IPCP)
345    bundle_StopIdleTimer(bundle);
346  else if (fp->proto == PROTO_LCP && bundle->ncp.mp.active) {
347    struct datalink *dl;
348
349    bundle->ifp.Speed = 0;
350    for (dl = bundle->links; dl; dl = dl->next)
351      if (fp != &dl->physical->link.lcp.fsm && dl->state == DATALINK_OPEN)
352        bundle->ifp.Speed += modem_Speed(dl->physical);
353    if (bundle->ifp.Speed)
354      /* Don't configure down to a speed of 0 */
355      tun_configure(bundle, bundle->ncp.mp.link.lcp.his_mru);
356  }
357}
358
359static void
360bundle_LayerFinish(void *v, struct fsm *fp)
361{
362  /* The given fsm is now down (fp cannot be NULL)
363   *
364   * If it's the last LCP, fsm_Down all NCPs
365   * If it's the last NCP, fsm_Close all LCPs
366   */
367
368  struct bundle *bundle = (struct bundle *)v;
369  struct datalink *dl;
370
371  if (fp->proto == PROTO_IPCP) {
372    if (bundle_Phase(bundle) != PHASE_DEAD)
373      bundle_NewPhase(bundle, PHASE_TERMINATE);
374    for (dl = bundle->links; dl; dl = dl->next)
375      datalink_Close(dl, 0);
376    fsm_Down(fp);
377    fsm_Close(fp);
378  } else if (fp->proto == PROTO_LCP) {
379    int others_active;
380
381    others_active = 0;
382    for (dl = bundle->links; dl; dl = dl->next)
383      if (fp != &dl->physical->link.lcp.fsm &&
384          dl->state != DATALINK_CLOSED && dl->state != DATALINK_HANGUP)
385        others_active++;
386
387    if (!others_active) {
388      fsm_Down(&bundle->ncp.ipcp.fsm);
389      fsm_Close(&bundle->ncp.ipcp.fsm);		/* ST_INITIAL please */
390    }
391  }
392}
393
394int
395bundle_LinkIsUp(const struct bundle *bundle)
396{
397  return bundle->ncp.ipcp.fsm.state == ST_OPENED;
398}
399
400void
401bundle_Close(struct bundle *bundle, const char *name, int staydown)
402{
403  /*
404   * Please close the given datalink.
405   * If name == NULL or name is the last datalink, fsm_Close all NCPs
406   * (except our MP)
407   * If it isn't the last datalink, just Close that datalink.
408   */
409
410  struct datalink *dl, *this_dl;
411  int others_active;
412
413  if (bundle->phase == PHASE_TERMINATE || bundle->phase == PHASE_DEAD)
414    return;
415
416  others_active = 0;
417  this_dl = NULL;
418
419  for (dl = bundle->links; dl; dl = dl->next) {
420    if (name && !strcasecmp(name, dl->name))
421      this_dl = dl;
422    if (name == NULL || this_dl == dl) {
423      if (staydown)
424        datalink_StayDown(dl);
425    } else if (dl->state != DATALINK_CLOSED && dl->state != DATALINK_HANGUP)
426      others_active++;
427  }
428
429  if (name && this_dl == NULL) {
430    log_Printf(LogWARN, "%s: Invalid datalink name\n", name);
431    return;
432  }
433
434  if (!others_active) {
435    bundle_StopIdleTimer(bundle);
436    bundle_StopAutoLoadTimer(bundle);
437    if (bundle->ncp.ipcp.fsm.state > ST_CLOSED ||
438        bundle->ncp.ipcp.fsm.state == ST_STARTING)
439      fsm_Close(&bundle->ncp.ipcp.fsm);
440    else {
441      if (bundle->ncp.ipcp.fsm.state > ST_INITIAL) {
442        fsm_Close(&bundle->ncp.ipcp.fsm);
443        fsm_Down(&bundle->ncp.ipcp.fsm);
444      }
445      for (dl = bundle->links; dl; dl = dl->next)
446        datalink_Close(dl, staydown);
447    }
448  } else if (this_dl && this_dl->state != DATALINK_CLOSED &&
449             this_dl->state != DATALINK_HANGUP)
450    datalink_Close(this_dl, staydown);
451}
452
453void
454bundle_Down(struct bundle *bundle)
455{
456  struct datalink *dl;
457
458  for (dl = bundle->links; dl; dl = dl->next)
459    datalink_Down(dl, 1);
460}
461
462static int
463bundle_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
464{
465  struct bundle *bundle = descriptor2bundle(d);
466  struct datalink *dl;
467  struct descriptor *desc;
468  int result, want, queued, nlinks;
469
470  result = 0;
471  for (dl = bundle->links; dl; dl = dl->next)
472    result += descriptor_UpdateSet(&dl->desc, r, w, e, n);
473
474  for (desc = bundle->desc.next; desc; desc = desc->next)
475    result += descriptor_UpdateSet(desc, r, w, e, n);
476
477  /* If there are aren't many packets queued, look for some more. */
478  for (nlinks = 0, dl = bundle->links; dl; dl = dl->next)
479    nlinks++;
480
481  if (nlinks) {
482    queued = r ? bundle_FillQueues(bundle) : ip_QueueLen();
483    if (bundle->autoload.running) {
484      if (queued < bundle->cfg.autoload.max.packets) {
485        if (queued > bundle->cfg.autoload.min.packets)
486          bundle_StopAutoLoadTimer(bundle);
487        else if (bundle->autoload.timer.state != TIMER_RUNNING ||
488                 bundle->autoload.comingup)
489          bundle_StartAutoLoadTimer(bundle, 0);
490      } else if (bundle->autoload.timer.state != TIMER_RUNNING ||
491                 !bundle->autoload.comingup)
492        bundle_StartAutoLoadTimer(bundle, 1);
493    }
494
495    if (r) {
496      /* enough surplus so that we can tell if we're getting swamped */
497      want = bundle->cfg.autoload.max.packets + nlinks * 2;
498      /* but at least 20 packets ! */
499      if (want < 20)
500        want = 20;
501      if (queued < want) {
502        /* Not enough - select() for more */
503        FD_SET(bundle->dev.fd, r);
504        if (*n < bundle->dev.fd + 1)
505          *n = bundle->dev.fd + 1;
506        log_Printf(LogTIMER, "tun: fdset(r) %d\n", bundle->dev.fd);
507        result++;
508      }
509    }
510  }
511
512  /*
513   * This *MUST* be called after the datalink UpdateSet()s as it
514   * might be ``holding'' one of the datalinks (death-row) and
515   * wants to be able to de-select() it from the descriptor set.
516   */
517  descriptor_UpdateSet(&bundle->ncp.mp.server.desc, r, w, e, n);
518
519  return result;
520}
521
522static int
523bundle_IsSet(struct descriptor *d, const fd_set *fdset)
524{
525  struct bundle *bundle = descriptor2bundle(d);
526  struct datalink *dl;
527  struct descriptor *desc;
528
529  for (dl = bundle->links; dl; dl = dl->next)
530    if (descriptor_IsSet(&dl->desc, fdset))
531      return 1;
532
533  for (desc = bundle->desc.next; desc; desc = desc->next)
534    if (descriptor_IsSet(desc, fdset))
535      return 1;
536
537  if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
538    return 1;
539
540  return FD_ISSET(bundle->dev.fd, fdset);
541}
542
543static void
544bundle_DescriptorRead(struct descriptor *d, struct bundle *bundle,
545                      const fd_set *fdset)
546{
547  struct datalink *dl;
548  struct descriptor *desc;
549
550  if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
551    descriptor_Read(&bundle->ncp.mp.server.desc, bundle, fdset);
552
553  for (dl = bundle->links; dl; dl = dl->next)
554    if (descriptor_IsSet(&dl->desc, fdset))
555      descriptor_Read(&dl->desc, bundle, fdset);
556
557  for (desc = bundle->desc.next; desc; desc = desc->next)
558    if (descriptor_IsSet(desc, fdset))
559      descriptor_Read(desc, bundle, fdset);
560
561  if (FD_ISSET(bundle->dev.fd, fdset)) {
562    struct tun_data tun;
563    int n, pri;
564
565    /* something to read from tun */
566    n = read(bundle->dev.fd, &tun, sizeof tun);
567    if (n < 0) {
568      log_Printf(LogERROR, "read from tun: %s\n", strerror(errno));
569      return;
570    }
571    n -= sizeof tun - sizeof tun.data;
572    if (n <= 0) {
573      log_Printf(LogERROR, "read from tun: Only %d bytes read\n", n);
574      return;
575    }
576    if (!tun_check_header(tun, AF_INET))
577      return;
578
579    if (((struct ip *)tun.data)->ip_dst.s_addr ==
580        bundle->ncp.ipcp.my_ip.s_addr) {
581      /* we've been asked to send something addressed *to* us :( */
582      if (Enabled(bundle, OPT_LOOPBACK)) {
583        pri = PacketCheck(bundle, tun.data, n, &bundle->filter.in);
584        if (pri >= 0) {
585          struct mbuf *bp;
586
587#ifndef NOALIAS
588          if (alias_IsEnabled()) {
589            (*PacketAlias.In)(tun.data, sizeof tun.data);
590            n = ntohs(((struct ip *)tun.data)->ip_len);
591          }
592#endif
593          bp = mbuf_Alloc(n, MB_IPIN);
594          memcpy(MBUF_CTOP(bp), tun.data, n);
595          ip_Input(bundle, bp);
596          log_Printf(LogDEBUG, "Looped back packet addressed to myself\n");
597        }
598        return;
599      } else
600        log_Printf(LogDEBUG, "Oops - forwarding packet addressed to myself\n");
601    }
602
603    /*
604     * Process on-demand dialup. Output packets are queued within tunnel
605     * device until IPCP is opened.
606     */
607
608    if (bundle_Phase(bundle) == PHASE_DEAD) {
609      /*
610       * Note, we must be in AUTO mode :-/ otherwise our interface should
611       * *not* be UP and we can't receive data
612       */
613      if ((pri = PacketCheck(bundle, tun.data, n, &bundle->filter.dial)) >= 0)
614        bundle_Open(bundle, NULL, PHYS_DEMAND);
615      else
616        /*
617         * Drop the packet.  If we were to queue it, we'd just end up with
618         * a pile of timed-out data in our output queue by the time we get
619         * around to actually dialing.  We'd also prematurely reach the
620         * threshold at which we stop select()ing to read() the tun
621         * device - breaking auto-dial.
622         */
623        return;
624    }
625
626    pri = PacketCheck(bundle, tun.data, n, &bundle->filter.out);
627    if (pri >= 0) {
628#ifndef NOALIAS
629      if (alias_IsEnabled()) {
630        (*PacketAlias.Out)(tun.data, sizeof tun.data);
631        n = ntohs(((struct ip *)tun.data)->ip_len);
632      }
633#endif
634      ip_Enqueue(pri, tun.data, n);
635    }
636  }
637}
638
639static void
640bundle_DescriptorWrite(struct descriptor *d, struct bundle *bundle,
641                       const fd_set *fdset)
642{
643  struct datalink *dl;
644  struct descriptor *desc;
645
646  /* This is not actually necessary as struct mpserver doesn't Write() */
647  if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
648    descriptor_Write(&bundle->ncp.mp.server.desc, bundle, fdset);
649
650  for (dl = bundle->links; dl; dl = dl->next)
651    if (descriptor_IsSet(&dl->desc, fdset))
652      descriptor_Write(&dl->desc, bundle, fdset);
653
654  for (desc = bundle->desc.next; desc; desc = desc->next)
655    if (descriptor_IsSet(desc, fdset))
656      descriptor_Write(desc, bundle, fdset);
657}
658
659
660struct bundle *
661bundle_Create(const char *prefix, struct prompt *prompt, int type)
662{
663  int s, enoentcount, err;
664  struct ifreq ifrq;
665  static struct bundle bundle;		/* there can be only one */
666
667  if (bundle.ifp.Name != NULL) {	/* Already allocated ! */
668    log_Printf(LogERROR, "bundle_Create:  There's only one BUNDLE !\n");
669    return NULL;
670  }
671
672  err = ENOENT;
673  enoentcount = 0;
674  for (bundle.unit = 0; ; bundle.unit++) {
675    snprintf(bundle.dev.Name, sizeof bundle.dev.Name, "%s%d",
676             prefix, bundle.unit);
677    bundle.dev.fd = ID0open(bundle.dev.Name, O_RDWR);
678    if (bundle.dev.fd >= 0)
679      break;
680    else if (errno == ENXIO) {
681      err = errno;
682      break;
683    } else if (errno == ENOENT) {
684      if (++enoentcount > 2)
685	break;
686    } else
687      err = errno;
688  }
689
690  if (bundle.dev.fd < 0) {
691    log_Printf(LogWARN, "No available tunnel devices found (%s).\n",
692              strerror(err));
693    return NULL;
694  }
695
696  log_SetTun(bundle.unit);
697
698  s = socket(AF_INET, SOCK_DGRAM, 0);
699  if (s < 0) {
700    log_Printf(LogERROR, "bundle_Create: socket(): %s\n", strerror(errno));
701    close(bundle.dev.fd);
702    return NULL;
703  }
704
705  bundle.ifp.Name = strrchr(bundle.dev.Name, '/');
706  if (bundle.ifp.Name == NULL)
707    bundle.ifp.Name = bundle.dev.Name;
708  else
709    bundle.ifp.Name++;
710
711  /*
712   * Now, bring up the interface.
713   */
714  memset(&ifrq, '\0', sizeof ifrq);
715  strncpy(ifrq.ifr_name, bundle.ifp.Name, sizeof ifrq.ifr_name - 1);
716  ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0';
717  if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
718    log_Printf(LogERROR, "OpenTunnel: ioctl(SIOCGIFFLAGS): %s\n",
719	      strerror(errno));
720    close(s);
721    close(bundle.dev.fd);
722    bundle.ifp.Name = NULL;
723    return NULL;
724  }
725  ifrq.ifr_flags |= IFF_UP;
726  if (ID0ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
727    log_Printf(LogERROR, "OpenTunnel: ioctl(SIOCSIFFLAGS): %s\n",
728	      strerror(errno));
729    close(s);
730    close(bundle.dev.fd);
731    bundle.ifp.Name = NULL;
732    return NULL;
733  }
734
735  close(s);
736
737  if ((bundle.ifp.Index = GetIfIndex(bundle.ifp.Name)) < 0) {
738    log_Printf(LogERROR, "OpenTunnel: Can't find interface index.\n");
739    close(bundle.dev.fd);
740    bundle.ifp.Name = NULL;
741    return NULL;
742  }
743  prompt_Printf(prompt, "Using interface: %s\n", bundle.ifp.Name);
744  log_Printf(LogPHASE, "Using interface: %s\n", bundle.ifp.Name);
745
746  bundle.ifp.Speed = 0;
747
748  bundle.routing_seq = 0;
749  bundle.phase = PHASE_DEAD;
750  bundle.CleaningUp = 0;
751
752  bundle.fsm.LayerStart = bundle_LayerStart;
753  bundle.fsm.LayerUp = bundle_LayerUp;
754  bundle.fsm.LayerDown = bundle_LayerDown;
755  bundle.fsm.LayerFinish = bundle_LayerFinish;
756  bundle.fsm.object = &bundle;
757
758  bundle.cfg.idle_timeout = NCP_IDLE_TIMEOUT;
759  *bundle.cfg.auth.name = '\0';
760  *bundle.cfg.auth.key = '\0';
761  bundle.cfg.opt = OPT_SROUTES | OPT_IDCHECK | OPT_LOOPBACK |
762                   OPT_THROUGHPUT | OPT_UTMP;
763  *bundle.cfg.label = '\0';
764  bundle.cfg.mtu = DEF_MTU;
765  bundle.cfg.autoload.max.packets = 0;
766  bundle.cfg.autoload.max.timeout = 0;
767  bundle.cfg.autoload.min.packets = 0;
768  bundle.cfg.autoload.min.timeout = 0;
769  bundle.phys_type = type;
770
771  bundle.links = datalink_Create("deflink", &bundle, type);
772  if (bundle.links == NULL) {
773    log_Printf(LogERROR, "Cannot create data link: %s\n", strerror(errno));
774    close(bundle.dev.fd);
775    bundle.ifp.Name = NULL;
776    return NULL;
777  }
778
779  bundle.desc.type = BUNDLE_DESCRIPTOR;
780  bundle.desc.next = NULL;
781  bundle.desc.UpdateSet = bundle_UpdateSet;
782  bundle.desc.IsSet = bundle_IsSet;
783  bundle.desc.Read = bundle_DescriptorRead;
784  bundle.desc.Write = bundle_DescriptorWrite;
785
786  mp_Init(&bundle.ncp.mp, &bundle);
787
788  /* Send over the first physical link by default */
789  ipcp_Init(&bundle.ncp.ipcp, &bundle, &bundle.links->physical->link,
790            &bundle.fsm);
791
792  memset(&bundle.filter, '\0', sizeof bundle.filter);
793  bundle.filter.in.fragok = bundle.filter.in.logok = 1;
794  bundle.filter.in.name = "IN";
795  bundle.filter.out.fragok = bundle.filter.out.logok = 1;
796  bundle.filter.out.name = "OUT";
797  bundle.filter.dial.name = "DIAL";
798  bundle.filter.dial.logok = 1;
799  bundle.filter.alive.name = "ALIVE";
800  bundle.filter.alive.logok = 1;
801  memset(&bundle.idle.timer, '\0', sizeof bundle.idle.timer);
802  bundle.idle.done = 0;
803  bundle.notify.fd = -1;
804  memset(&bundle.autoload.timer, '\0', sizeof bundle.autoload.timer);
805  bundle.autoload.done = 0;
806  bundle.autoload.running = 0;
807
808  /* Clean out any leftover crud */
809  bundle_CleanInterface(&bundle);
810
811  if (prompt) {
812    /* Retrospectively introduce ourselves to the prompt */
813    prompt->bundle = &bundle;
814    bundle_RegisterDescriptor(&bundle, &prompt->desc);
815  }
816
817  return &bundle;
818}
819
820static void
821bundle_DownInterface(struct bundle *bundle)
822{
823  struct ifreq ifrq;
824  int s;
825
826  route_IfDelete(bundle, 1);
827
828  s = ID0socket(AF_INET, SOCK_DGRAM, 0);
829  if (s < 0) {
830    log_Printf(LogERROR, "bundle_DownInterface: socket: %s\n", strerror(errno));
831    return;
832  }
833
834  memset(&ifrq, '\0', sizeof ifrq);
835  strncpy(ifrq.ifr_name, bundle->ifp.Name, sizeof ifrq.ifr_name - 1);
836  ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0';
837  if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
838    log_Printf(LogERROR, "bundle_DownInterface: ioctl(SIOCGIFFLAGS): %s\n",
839       strerror(errno));
840    close(s);
841    return;
842  }
843  ifrq.ifr_flags &= ~IFF_UP;
844  if (ID0ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
845    log_Printf(LogERROR, "bundle_DownInterface: ioctl(SIOCSIFFLAGS): %s\n",
846       strerror(errno));
847    close(s);
848    return;
849  }
850  close(s);
851}
852
853void
854bundle_Destroy(struct bundle *bundle)
855{
856  struct datalink *dl;
857  struct descriptor *desc, *ndesc;
858
859  /*
860   * Clean up the interface.  We don't need to timer_Stop()s, mp_Down(),
861   * ipcp_CleanInterface() and bundle_DownInterface() unless we're getting
862   * out under exceptional conditions such as a descriptor exception.
863   */
864  timer_Stop(&bundle->idle.timer);
865  timer_Stop(&bundle->autoload.timer);
866  mp_Down(&bundle->ncp.mp);
867  ipcp_CleanInterface(&bundle->ncp.ipcp);
868  bundle_DownInterface(bundle);
869
870  /* Again, these are all DATALINK_CLOSED unless we're abending */
871  dl = bundle->links;
872  while (dl)
873    dl = datalink_Destroy(dl);
874
875  /* In case we never made PHASE_NETWORK */
876  bundle_Notify(bundle, EX_ERRDEAD);
877
878  /* Finally, destroy our prompts */
879  desc = bundle->desc.next;
880  while (desc) {
881    ndesc = desc->next;
882    if (desc->type == PROMPT_DESCRIPTOR)
883      prompt_Destroy((struct prompt *)desc, 1);
884    else
885      log_Printf(LogERROR, "bundle_Destroy: Don't know how to delete descriptor"
886                " type %d\n", desc->type);
887    desc = ndesc;
888  }
889  bundle->desc.next = NULL;
890  bundle->ifp.Name = NULL;
891}
892
893struct rtmsg {
894  struct rt_msghdr m_rtm;
895  char m_space[64];
896};
897
898int
899bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst,
900                struct in_addr gateway, struct in_addr mask, int bang)
901{
902  struct rtmsg rtmes;
903  int s, nb, wb;
904  char *cp;
905  const char *cmdstr;
906  struct sockaddr_in rtdata;
907  int result = 1;
908
909  if (bang)
910    cmdstr = (cmd == RTM_ADD ? "Add!" : "Delete!");
911  else
912    cmdstr = (cmd == RTM_ADD ? "Add" : "Delete");
913  s = ID0socket(PF_ROUTE, SOCK_RAW, 0);
914  if (s < 0) {
915    log_Printf(LogERROR, "bundle_SetRoute: socket(): %s\n", strerror(errno));
916    return result;
917  }
918  memset(&rtmes, '\0', sizeof rtmes);
919  rtmes.m_rtm.rtm_version = RTM_VERSION;
920  rtmes.m_rtm.rtm_type = cmd;
921  rtmes.m_rtm.rtm_addrs = RTA_DST;
922  rtmes.m_rtm.rtm_seq = ++bundle->routing_seq;
923  rtmes.m_rtm.rtm_pid = getpid();
924  rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
925
926  memset(&rtdata, '\0', sizeof rtdata);
927  rtdata.sin_len = sizeof rtdata;
928  rtdata.sin_family = AF_INET;
929  rtdata.sin_port = 0;
930  rtdata.sin_addr = dst;
931
932  cp = rtmes.m_space;
933  memcpy(cp, &rtdata, rtdata.sin_len);
934  cp += rtdata.sin_len;
935  if (cmd == RTM_ADD) {
936    if (gateway.s_addr == INADDR_ANY) {
937      /* Add a route through the interface */
938      struct sockaddr_dl dl;
939      const char *iname;
940      int ilen;
941
942      iname = Index2Nam(bundle->ifp.Index);
943      ilen = strlen(iname);
944      dl.sdl_len = sizeof dl - sizeof dl.sdl_data + ilen;
945      dl.sdl_family = AF_LINK;
946      dl.sdl_index = bundle->ifp.Index;
947      dl.sdl_type = 0;
948      dl.sdl_nlen = ilen;
949      dl.sdl_alen = 0;
950      dl.sdl_slen = 0;
951      strncpy(dl.sdl_data, iname, sizeof dl.sdl_data);
952      memcpy(cp, &dl, dl.sdl_len);
953      cp += dl.sdl_len;
954      rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
955    } else {
956      rtdata.sin_addr = gateway;
957      memcpy(cp, &rtdata, rtdata.sin_len);
958      cp += rtdata.sin_len;
959      rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
960    }
961  }
962
963  if (dst.s_addr == INADDR_ANY)
964    mask.s_addr = INADDR_ANY;
965
966  if (cmd == RTM_ADD || dst.s_addr == INADDR_ANY) {
967    rtdata.sin_addr = mask;
968    memcpy(cp, &rtdata, rtdata.sin_len);
969    cp += rtdata.sin_len;
970    rtmes.m_rtm.rtm_addrs |= RTA_NETMASK;
971  }
972
973  nb = cp - (char *) &rtmes;
974  rtmes.m_rtm.rtm_msglen = nb;
975  wb = ID0write(s, &rtmes, nb);
976  if (wb < 0) {
977    log_Printf(LogTCPIP, "bundle_SetRoute failure:\n");
978    log_Printf(LogTCPIP, "bundle_SetRoute:  Cmd = %s\n", cmdstr);
979    log_Printf(LogTCPIP, "bundle_SetRoute:  Dst = %s\n", inet_ntoa(dst));
980    log_Printf(LogTCPIP, "bundle_SetRoute:  Gateway = %s\n", inet_ntoa(gateway));
981    log_Printf(LogTCPIP, "bundle_SetRoute:  Mask = %s\n", inet_ntoa(mask));
982failed:
983    if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST ||
984                           (rtmes.m_rtm.rtm_errno == 0 && errno == EEXIST))) {
985      if (!bang) {
986        log_Printf(LogWARN, "Add route failed: %s already exists\n",
987                  inet_ntoa(dst));
988        result = 0;	/* Don't add to our dynamic list */
989      } else {
990        rtmes.m_rtm.rtm_type = cmd = RTM_CHANGE;
991        if ((wb = ID0write(s, &rtmes, nb)) < 0)
992          goto failed;
993      }
994    } else if (cmd == RTM_DELETE &&
995             (rtmes.m_rtm.rtm_errno == ESRCH ||
996              (rtmes.m_rtm.rtm_errno == 0 && errno == ESRCH))) {
997      if (!bang)
998        log_Printf(LogWARN, "Del route failed: %s: Non-existent\n",
999                  inet_ntoa(dst));
1000    } else if (rtmes.m_rtm.rtm_errno == 0)
1001      log_Printf(LogWARN, "%s route failed: %s: errno: %s\n", cmdstr,
1002                inet_ntoa(dst), strerror(errno));
1003    else
1004      log_Printf(LogWARN, "%s route failed: %s: %s\n",
1005		cmdstr, inet_ntoa(dst), strerror(rtmes.m_rtm.rtm_errno));
1006  }
1007  log_Printf(LogDEBUG, "wrote %d: cmd = %s, dst = %x, gateway = %x\n",
1008            wb, cmdstr, (unsigned)dst.s_addr, (unsigned)gateway.s_addr);
1009  close(s);
1010
1011  return result;
1012}
1013
1014void
1015bundle_LinkClosed(struct bundle *bundle, struct datalink *dl)
1016{
1017  /*
1018   * Our datalink has closed.
1019   * CleanDatalinks() (called from DoLoop()) will remove closed
1020   * 1OFF and DIRECT links.
1021   * If it's the last data link, enter phase DEAD.
1022   *
1023   * NOTE: dl may not be in our list (bundle_SendDatalink()) !
1024   */
1025
1026  struct datalink *odl;
1027  int other_links;
1028
1029  other_links = 0;
1030  for (odl = bundle->links; odl; odl = odl->next)
1031    if (odl != dl && odl->state != DATALINK_CLOSED)
1032      other_links++;
1033
1034  if (!other_links) {
1035    if (dl->physical->type != PHYS_DEMAND)	/* Not in -auto mode */
1036      bundle_DownInterface(bundle);
1037    if (bundle->ncp.ipcp.fsm.state > ST_CLOSED ||
1038        bundle->ncp.ipcp.fsm.state == ST_STARTING) {
1039      fsm_Down(&bundle->ncp.ipcp.fsm);
1040      fsm_Close(&bundle->ncp.ipcp.fsm);		/* ST_INITIAL please */
1041    }
1042    bundle_NewPhase(bundle, PHASE_DEAD);
1043    bundle_DisplayPrompt(bundle);
1044    bundle_StopAutoLoadTimer(bundle);
1045    bundle->autoload.running = 0;
1046  } else
1047    bundle->autoload.running = 1;
1048}
1049
1050void
1051bundle_Open(struct bundle *bundle, const char *name, int mask)
1052{
1053  /*
1054   * Please open the given datalink, or all if name == NULL
1055   */
1056  struct datalink *dl;
1057
1058  timer_Stop(&bundle->autoload.timer);
1059  for (dl = bundle->links; dl; dl = dl->next)
1060    if (name == NULL || !strcasecmp(dl->name, name)) {
1061      if (dl->state == DATALINK_CLOSED && (mask & dl->physical->type)) {
1062        datalink_Up(dl, 1, 1);
1063        if (mask == PHYS_DEMAND)
1064          /* Only one DEMAND link at a time (see the AutoLoad timer) */
1065          break;
1066      }
1067      if (name != NULL)
1068        break;
1069    }
1070}
1071
1072struct datalink *
1073bundle2datalink(struct bundle *bundle, const char *name)
1074{
1075  struct datalink *dl;
1076
1077  if (name != NULL) {
1078    for (dl = bundle->links; dl; dl = dl->next)
1079      if (!strcasecmp(dl->name, name))
1080        return dl;
1081  } else if (bundle->links && !bundle->links->next)
1082    return bundle->links;
1083
1084  return NULL;
1085}
1086
1087int
1088bundle_FillQueues(struct bundle *bundle)
1089{
1090  int total;
1091
1092  if (bundle->ncp.mp.active)
1093    total = mp_FillQueues(bundle);
1094  else {
1095    struct datalink *dl;
1096    int add;
1097
1098    for (total = 0, dl = bundle->links; dl; dl = dl->next)
1099      if (dl->state == DATALINK_OPEN) {
1100        add = link_QueueLen(&dl->physical->link);
1101        if (add == 0 && dl->physical->out == NULL)
1102          add = ip_FlushPacket(&dl->physical->link, bundle);
1103        total += add;
1104      }
1105  }
1106
1107  return total + ip_QueueLen();
1108}
1109
1110int
1111bundle_ShowLinks(struct cmdargs const *arg)
1112{
1113  struct datalink *dl;
1114
1115  for (dl = arg->bundle->links; dl; dl = dl->next) {
1116    prompt_Printf(arg->prompt, "Name: %s [%s]", dl->name, datalink_State(dl));
1117    if (dl->physical->link.throughput.rolling && dl->state == DATALINK_OPEN)
1118      prompt_Printf(arg->prompt, " (weight %d, %d bytes/sec)",
1119                    dl->mp.weight,
1120                    dl->physical->link.throughput.OctetsPerSecond);
1121    prompt_Printf(arg->prompt, "\n");
1122  }
1123
1124  return 0;
1125}
1126
1127static const char *
1128optval(struct bundle *bundle, int bit)
1129{
1130  return (bundle->cfg.opt & bit) ? "enabled" : "disabled";
1131}
1132
1133int
1134bundle_ShowStatus(struct cmdargs const *arg)
1135{
1136  int remaining;
1137
1138  prompt_Printf(arg->prompt, "Phase %s\n", bundle_PhaseName(arg->bundle));
1139  prompt_Printf(arg->prompt, " Device:        %s\n", arg->bundle->dev.Name);
1140  prompt_Printf(arg->prompt, " Interface:     %s @ %lubps\n",
1141                arg->bundle->ifp.Name, arg->bundle->ifp.Speed);
1142
1143  prompt_Printf(arg->prompt, "\nDefaults:\n");
1144  prompt_Printf(arg->prompt, " Label:         %s\n", arg->bundle->cfg.label);
1145  prompt_Printf(arg->prompt, " Auth name:     %s\n",
1146                arg->bundle->cfg.auth.name);
1147  prompt_Printf(arg->prompt, " Auto Load:     Up after %ds of >= %d packets\n",
1148                arg->bundle->cfg.autoload.max.timeout,
1149                arg->bundle->cfg.autoload.max.packets);
1150  prompt_Printf(arg->prompt, "                Down after %ds of <= %d"
1151                " packets\n", arg->bundle->cfg.autoload.min.timeout,
1152                arg->bundle->cfg.autoload.min.packets);
1153  if (arg->bundle->autoload.timer.state == TIMER_RUNNING)
1154    prompt_Printf(arg->prompt, "                %ds remaining 'till "
1155                  "a link comes %s\n",
1156                  bundle_RemainingAutoLoadTime(arg->bundle),
1157                  arg->bundle->autoload.comingup ? "up" : "down");
1158  else
1159    prompt_Printf(arg->prompt, "                %srunning with %d"
1160                  " packets queued\n", arg->bundle->autoload.running ?
1161                  "" : "not ", ip_QueueLen());
1162
1163  prompt_Printf(arg->prompt, " Idle Timer:    ");
1164  if (arg->bundle->cfg.idle_timeout) {
1165    prompt_Printf(arg->prompt, "%ds", arg->bundle->cfg.idle_timeout);
1166    remaining = bundle_RemainingIdleTime(arg->bundle);
1167    if (remaining != -1)
1168      prompt_Printf(arg->prompt, " (%ds remaining)", remaining);
1169    prompt_Printf(arg->prompt, "\n");
1170  } else
1171    prompt_Printf(arg->prompt, "disabled\n");
1172  prompt_Printf(arg->prompt, " MTU:           ");
1173  if (arg->bundle->cfg.mtu)
1174    prompt_Printf(arg->prompt, "%d\n", arg->bundle->cfg.mtu);
1175  else
1176    prompt_Printf(arg->prompt, "unspecified\n");
1177
1178  prompt_Printf(arg->prompt, " Sticky Routes: %s\n",
1179                optval(arg->bundle, OPT_SROUTES));
1180  prompt_Printf(arg->prompt, " ID check:      %s\n",
1181                optval(arg->bundle, OPT_IDCHECK));
1182  prompt_Printf(arg->prompt, " Loopback:      %s\n",
1183                optval(arg->bundle, OPT_LOOPBACK));
1184  prompt_Printf(arg->prompt, " PasswdAuth:    %s\n",
1185                optval(arg->bundle, OPT_PASSWDAUTH));
1186  prompt_Printf(arg->prompt, " Proxy:         %s\n",
1187                optval(arg->bundle, OPT_PROXY));
1188  prompt_Printf(arg->prompt, " Throughput:    %s\n",
1189                optval(arg->bundle, OPT_THROUGHPUT));
1190  prompt_Printf(arg->prompt, " Utmp Logging:  %s\n",
1191                optval(arg->bundle, OPT_UTMP));
1192
1193  return 0;
1194}
1195
1196static void
1197bundle_IdleTimeout(void *v)
1198{
1199  struct bundle *bundle = (struct bundle *)v;
1200
1201  log_Printf(LogPHASE, "Idle timer expired.\n");
1202  bundle_StopIdleTimer(bundle);
1203  bundle_Close(bundle, NULL, 1);
1204}
1205
1206/*
1207 *  Start Idle timer. If timeout is reached, we call bundle_Close() to
1208 *  close LCP and link.
1209 */
1210void
1211bundle_StartIdleTimer(struct bundle *bundle)
1212{
1213  timer_Stop(&bundle->idle.timer);
1214  if ((bundle->phys_type & (PHYS_DEDICATED|PHYS_PERM)) != bundle->phys_type &&
1215      bundle->cfg.idle_timeout) {
1216    bundle->idle.timer.func = bundle_IdleTimeout;
1217    bundle->idle.timer.name = "idle";
1218    bundle->idle.timer.load = bundle->cfg.idle_timeout * SECTICKS;
1219    bundle->idle.timer.arg = bundle;
1220    timer_Start(&bundle->idle.timer);
1221    bundle->idle.done = time(NULL) + bundle->cfg.idle_timeout;
1222  }
1223}
1224
1225void
1226bundle_SetIdleTimer(struct bundle *bundle, int value)
1227{
1228  bundle->cfg.idle_timeout = value;
1229  if (bundle_LinkIsUp(bundle))
1230    bundle_StartIdleTimer(bundle);
1231}
1232
1233void
1234bundle_StopIdleTimer(struct bundle *bundle)
1235{
1236  timer_Stop(&bundle->idle.timer);
1237  bundle->idle.done = 0;
1238}
1239
1240static int
1241bundle_RemainingIdleTime(struct bundle *bundle)
1242{
1243  if (bundle->idle.done)
1244    return bundle->idle.done - time(NULL);
1245  return -1;
1246}
1247
1248int
1249bundle_IsDead(struct bundle *bundle)
1250{
1251  return !bundle->links || (bundle->phase == PHASE_DEAD && bundle->CleaningUp);
1252}
1253
1254void
1255bundle_RegisterDescriptor(struct bundle *bundle, struct descriptor *d)
1256{
1257  d->next = bundle->desc.next;
1258  bundle->desc.next = d;
1259}
1260
1261void
1262bundle_UnRegisterDescriptor(struct bundle *bundle, struct descriptor *d)
1263{
1264  struct descriptor **desc;
1265
1266  for (desc = &bundle->desc.next; *desc; desc = &(*desc)->next)
1267    if (*desc == d) {
1268      *desc = d->next;
1269      break;
1270    }
1271}
1272
1273void
1274bundle_DelPromptDescriptors(struct bundle *bundle, struct server *s)
1275{
1276  struct descriptor **desc;
1277  struct prompt *p;
1278
1279  desc = &bundle->desc.next;
1280  while (*desc) {
1281    if ((*desc)->type == PROMPT_DESCRIPTOR) {
1282      p = (struct prompt *)*desc;
1283      if (p->owner == s) {
1284        prompt_Destroy(p, 1);
1285        desc = &bundle->desc.next;
1286        continue;
1287      }
1288    }
1289    desc = &(*desc)->next;
1290  }
1291}
1292
1293void
1294bundle_DisplayPrompt(struct bundle *bundle)
1295{
1296  struct descriptor **desc;
1297
1298  for (desc = &bundle->desc.next; *desc; desc = &(*desc)->next)
1299    if ((*desc)->type == PROMPT_DESCRIPTOR)
1300      prompt_Required((struct prompt *)*desc);
1301}
1302
1303void
1304bundle_WriteTermPrompt(struct bundle *bundle, struct datalink *dl,
1305                       const char *data, int len)
1306{
1307  struct descriptor *desc;
1308  struct prompt *p;
1309
1310  for (desc = bundle->desc.next; desc; desc = desc->next)
1311    if (desc->type == PROMPT_DESCRIPTOR) {
1312      p = (struct prompt *)desc;
1313      if (prompt_IsTermMode(p, dl))
1314        prompt_Printf(p, "%.*s", len, data);
1315    }
1316}
1317
1318void
1319bundle_SetTtyCommandMode(struct bundle *bundle, struct datalink *dl)
1320{
1321  struct descriptor *desc;
1322  struct prompt *p;
1323
1324  for (desc = bundle->desc.next; desc; desc = desc->next)
1325    if (desc->type == PROMPT_DESCRIPTOR) {
1326      p = (struct prompt *)desc;
1327      if (prompt_IsTermMode(p, dl))
1328        prompt_TtyCommandMode(p);
1329    }
1330}
1331
1332static void
1333bundle_LinkAdded(struct bundle *bundle, struct datalink *dl)
1334{
1335  bundle->phys_type |= dl->physical->type;
1336  if (dl->physical->type == PHYS_DEMAND &&
1337      bundle->autoload.timer.state == TIMER_STOPPED &&
1338      bundle->phase == PHASE_NETWORK)
1339    bundle->autoload.running = 1;
1340}
1341
1342static void
1343bundle_LinksRemoved(struct bundle *bundle)
1344{
1345  struct datalink *dl;
1346
1347  bundle->phys_type = 0;
1348  for (dl = bundle->links; dl; dl = dl->next)
1349    bundle_LinkAdded(bundle, dl);
1350
1351  if ((bundle->phys_type & (PHYS_DEDICATED|PHYS_PERM)) == bundle->phys_type)
1352    timer_Stop(&bundle->idle.timer);
1353}
1354
1355static struct datalink *
1356bundle_DatalinkLinkout(struct bundle *bundle, struct datalink *dl)
1357{
1358  struct datalink **dlp;
1359
1360  if (dl->state == DATALINK_CLOSED)
1361    for (dlp = &bundle->links; *dlp; dlp = &(*dlp)->next)
1362      if (*dlp == dl) {
1363        *dlp = dl->next;
1364        dl->next = NULL;
1365        bundle_LinksRemoved(bundle);
1366        return dl;
1367      }
1368
1369  return NULL;
1370}
1371
1372static void
1373bundle_DatalinkLinkin(struct bundle *bundle, struct datalink *dl)
1374{
1375  struct datalink **dlp = &bundle->links;
1376
1377  while (*dlp)
1378    dlp = &(*dlp)->next;
1379
1380  *dlp = dl;
1381  dl->next = NULL;
1382
1383  bundle_LinkAdded(bundle, dl);
1384}
1385
1386void
1387bundle_CleanDatalinks(struct bundle *bundle)
1388{
1389  struct datalink **dlp = &bundle->links;
1390  int found = 0;
1391
1392  while (*dlp)
1393    if ((*dlp)->state == DATALINK_CLOSED &&
1394        (*dlp)->physical->type & (PHYS_DIRECT|PHYS_1OFF)) {
1395      *dlp = datalink_Destroy(*dlp);
1396      found++;
1397    } else
1398      dlp = &(*dlp)->next;
1399
1400  if (found)
1401    bundle_LinksRemoved(bundle);
1402}
1403
1404int
1405bundle_DatalinkClone(struct bundle *bundle, struct datalink *dl,
1406                     const char *name)
1407{
1408  if (bundle2datalink(bundle, name)) {
1409    log_Printf(LogWARN, "Clone: %s: name already exists\n", name);
1410    return 0;
1411  }
1412
1413  bundle_DatalinkLinkin(bundle, datalink_Clone(dl, name));
1414  return 1;
1415}
1416
1417void
1418bundle_DatalinkRemove(struct bundle *bundle, struct datalink *dl)
1419{
1420  dl = bundle_DatalinkLinkout(bundle, dl);
1421  if (dl)
1422    datalink_Destroy(dl);
1423}
1424
1425void
1426bundle_SetLabel(struct bundle *bundle, const char *label)
1427{
1428  if (label)
1429    strncpy(bundle->cfg.label, label, sizeof bundle->cfg.label - 1);
1430  else
1431    *bundle->cfg.label = '\0';
1432}
1433
1434const char *
1435bundle_GetLabel(struct bundle *bundle)
1436{
1437  return *bundle->cfg.label ? bundle->cfg.label : NULL;
1438}
1439
1440void
1441bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun)
1442{
1443  char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int)];
1444  struct cmsghdr *cmsg = (struct cmsghdr *)cmsgbuf;
1445  struct msghdr msg;
1446  struct iovec iov[SCATTER_SEGMENTS];
1447  struct datalink *dl;
1448  int niov, link_fd, expect, f;
1449
1450  log_Printf(LogPHASE, "Receiving datalink\n");
1451
1452  /* Create our scatter/gather array */
1453  niov = 1;
1454  iov[0].iov_len = strlen(Version) + 1;
1455  iov[0].iov_base = (char *)malloc(iov[0].iov_len);
1456  if (datalink2iov(NULL, iov, &niov, sizeof iov / sizeof *iov) == -1)
1457    return;
1458
1459  for (f = expect = 0; f < niov; f++)
1460    expect += iov[f].iov_len;
1461
1462  /* Set up our message */
1463  cmsg->cmsg_len = sizeof cmsgbuf;
1464  cmsg->cmsg_level = SOL_SOCKET;
1465  cmsg->cmsg_type = SCM_RIGHTS;
1466
1467  memset(&msg, '\0', sizeof msg);
1468  msg.msg_name = (caddr_t)sun;
1469  msg.msg_namelen = sizeof *sun;
1470  msg.msg_iov = iov;
1471  msg.msg_iovlen = niov;
1472  msg.msg_control = cmsgbuf;
1473  msg.msg_controllen = sizeof cmsgbuf;
1474
1475  log_Printf(LogDEBUG, "Expecting %d scatter/gather bytes\n", expect);
1476  f = expect + 100;
1477  setsockopt(s, SOL_SOCKET, SO_RCVBUF, &f, sizeof f);
1478  if ((f = recvmsg(s, &msg, MSG_WAITALL)) != expect) {
1479    if (f == -1)
1480      log_Printf(LogERROR, "Failed recvmsg: %s\n", strerror(errno));
1481    else
1482      log_Printf(LogERROR, "Failed recvmsg: Got %d, not %d\n", f, expect);
1483    while (niov--)
1484      free(iov[niov].iov_base);
1485    return;
1486  }
1487
1488  /* We've successfully received an open file descriptor through our socket */
1489  link_fd = *(int *)CMSG_DATA(cmsg);
1490
1491  write(s, "!",1 );	/* ACK */
1492
1493  if (strncmp(Version, iov[0].iov_base, iov[0].iov_len)) {
1494    log_Printf(LogWARN, "Cannot receive datalink, incorrect version"
1495               " (\"%.*s\", not \"%s\")\n", (int)iov[0].iov_len,
1496               iov[0].iov_base, Version);
1497    close(link_fd);
1498    while (niov--)
1499      free(iov[niov].iov_base);
1500    return;
1501  }
1502
1503  niov = 1;
1504  dl = iov2datalink(bundle, iov, &niov, sizeof iov / sizeof *iov, link_fd);
1505  if (dl) {
1506    bundle_DatalinkLinkin(bundle, dl);
1507    datalink_AuthOk(dl);
1508  } else
1509    close(link_fd);
1510
1511  free(iov[0].iov_base);
1512}
1513
1514void
1515bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun)
1516{
1517  char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int)], ack;
1518  struct cmsghdr *cmsg = (struct cmsghdr *)cmsgbuf;
1519  struct msghdr msg;
1520  struct iovec iov[SCATTER_SEGMENTS];
1521  int niov, link_fd, f, expect;
1522
1523  log_Printf(LogPHASE, "Transmitting datalink %s\n", dl->name);
1524
1525  bundle_DatalinkLinkout(dl->bundle, dl);
1526  bundle_LinkClosed(dl->bundle, dl);
1527
1528  /* Build our scatter/gather array */
1529  iov[0].iov_len = strlen(Version) + 1;
1530  iov[0].iov_base = strdup(Version);
1531  niov = 1;
1532
1533  link_fd = datalink2iov(dl, iov, &niov, sizeof iov / sizeof *iov);
1534
1535  if (link_fd != -1) {
1536    cmsg->cmsg_len = sizeof cmsgbuf;
1537    cmsg->cmsg_level = SOL_SOCKET;
1538    cmsg->cmsg_type = SCM_RIGHTS;
1539    *(int *)CMSG_DATA(cmsg) = link_fd;
1540
1541    memset(&msg, '\0', sizeof msg);
1542    msg.msg_name = (caddr_t)sun;
1543    msg.msg_namelen = sizeof *sun;
1544    msg.msg_iov = iov;
1545    msg.msg_iovlen = niov;
1546    msg.msg_control = cmsgbuf;
1547    msg.msg_controllen = sizeof cmsgbuf;
1548
1549    for (f = expect = 0; f < niov; f++)
1550      expect += iov[f].iov_len;
1551
1552    log_Printf(LogDEBUG, "Sending %d bytes in scatter/gather array\n", expect);
1553
1554    f = expect + SOCKET_OVERHEAD;
1555    setsockopt(s, SOL_SOCKET, SO_SNDBUF, &f, sizeof f);
1556    if (sendmsg(s, &msg, 0) == -1)
1557      log_Printf(LogERROR, "Failed sendmsg: %s\n", strerror(errno));
1558    /* We must get the ACK before closing the descriptor ! */
1559    read(s, &ack, 1);
1560    close(link_fd);
1561  }
1562
1563  while (niov--)
1564    free(iov[niov].iov_base);
1565}
1566
1567int
1568bundle_RenameDatalink(struct bundle *bundle, struct datalink *ndl,
1569                      const char *name)
1570{
1571  struct datalink *dl;
1572
1573  if (!strcasecmp(ndl->name, name))
1574    return 1;
1575
1576  for (dl = bundle->links; dl; dl = dl->next)
1577    if (!strcasecmp(dl->name, name))
1578      return 0;
1579
1580  datalink_Rename(ndl, name);
1581  return 1;
1582}
1583
1584int
1585bundle_SetMode(struct bundle *bundle, struct datalink *dl, int mode)
1586{
1587  int omode;
1588
1589  omode = dl->physical->type;
1590  if (omode == mode)
1591    return 1;
1592
1593  if (mode == PHYS_DEMAND && !(bundle->phys_type & PHYS_DEMAND))
1594    /* Changing to demand-dial mode */
1595    if (bundle->ncp.ipcp.peer_ip.s_addr == INADDR_ANY) {
1596      log_Printf(LogWARN, "You must `set ifaddr' before changing mode to %s\n",
1597                 mode2Nam(mode));
1598      return 0;
1599    }
1600
1601  if (!datalink_SetMode(dl, mode))
1602    return 0;
1603
1604  if (mode == PHYS_DEMAND && !(bundle->phys_type & PHYS_DEMAND))
1605    ipcp_InterfaceUp(&bundle->ncp.ipcp);
1606
1607  /* Regenerate phys_type and adjust autoload & idle timers */
1608  bundle_LinksRemoved(bundle);
1609
1610  if (omode == PHYS_DEMAND && !(bundle->phys_type & PHYS_DEMAND))
1611    /* Changing from demand-dial mode */
1612    ipcp_CleanInterface(&bundle->ncp.ipcp);
1613
1614  return 1;
1615}
1616