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