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