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