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