bundle.c revision 40622
155682Smarkm/*-
2233294Sstas * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
3233294Sstas * All rights reserved.
4233294Sstas *
555682Smarkm * Redistribution and use in source and binary forms, with or without
6233294Sstas * modification, are permitted provided that the following conditions
7233294Sstas * are met:
8233294Sstas * 1. Redistributions of source code must retain the above copyright
955682Smarkm *    notice, this list of conditions and the following disclaimer.
10233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer in the
1255682Smarkm *    documentation and/or other materials provided with the distribution.
13233294Sstas *
14233294Sstas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1655682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2055682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24233294Sstas * SUCH DAMAGE.
25233294Sstas *
26233294Sstas *	$Id: bundle.c,v 1.36 1998/10/22 02:32:48 brian Exp $
27233294Sstas */
28233294Sstas
29233294Sstas#include <sys/param.h>
30233294Sstas#include <sys/socket.h>
31233294Sstas#include <netinet/in.h>
3255682Smarkm#include <net/if.h>
3355682Smarkm#include <arpa/inet.h>
3455682Smarkm#include <net/route.h>
3555682Smarkm#include <net/if_dl.h>
3655682Smarkm#include <netinet/in_systm.h>
3755682Smarkm#include <netinet/ip.h>
38178825Sdfr#include <sys/un.h>
39178825Sdfr
40178825Sdfr#include <errno.h>
41178825Sdfr#include <fcntl.h>
4255682Smarkm#include <paths.h>
43178825Sdfr#include <stdio.h>
44178825Sdfr#include <stdlib.h>
4572445Sassar#include <string.h>
46178825Sdfr#include <sys/ioctl.h>
4772445Sassar#include <sys/uio.h>
48178825Sdfr#include <sys/wait.h>
49233294Sstas#include <termios.h>
50233294Sstas#include <unistd.h>
5155682Smarkm
52233294Sstas#ifndef NOALIAS
53233294Sstas#ifdef __OpenBSD__
54233294Sstas#include "alias.h"
5572445Sassar#else
56233294Sstas#include <alias.h>
57233294Sstas#endif
58233294Sstas#endif
59233294Sstas#include "defs.h"
6055682Smarkm#include "command.h"
6155682Smarkm#include "mbuf.h"
6255682Smarkm#include "log.h"
6355682Smarkm#include "id.h"
6455682Smarkm#include "timer.h"
6555682Smarkm#include "fsm.h"
6655682Smarkm#include "iplist.h"
6755682Smarkm#include "lqr.h"
6872445Sassar#include "hdlc.h"
69233294Sstas#include "throughput.h"
7072445Sassar#include "slcompress.h"
7172445Sassar#include "ipcp.h"
7272445Sassar#include "filter.h"
73233294Sstas#include "descriptor.h"
7455682Smarkm#include "route.h"
7555682Smarkm#include "lcp.h"
7655682Smarkm#include "ccp.h"
7755682Smarkm#include "link.h"
7855682Smarkm#include "mp.h"
7955682Smarkm#include "bundle.h"
8055682Smarkm#include "async.h"
8155682Smarkm#include "physical.h"
8255682Smarkm#include "modem.h"
83178825Sdfr#include "auth.h"
84178825Sdfr#include "lcpproto.h"
85178825Sdfr#include "chap.h"
86178825Sdfr#include "tun.h"
87178825Sdfr#include "prompt.h"
88178825Sdfr#include "chat.h"
89178825Sdfr#include "cbcp.h"
9072445Sassar#include "datalink.h"
9172445Sassar#include "ip.h"
9272445Sassar#include "iface.h"
9355682Smarkm
9472445Sassar#define SCATTER_SEGMENTS 4	/* version, datalink, name, physical */
9572445Sassar#define SOCKET_OVERHEAD	100	/* additional buffer space for large */
9672445Sassar                                /* {recv,send}msg() calls            */
9772445Sassar
9872445Sassarstatic int bundle_RemainingIdleTime(struct bundle *);
9972445Sassarstatic int bundle_RemainingAutoLoadTime(struct bundle *);
10072445Sassar
10155682Smarkmstatic const char *PhaseNames[] = {
10272445Sassar  "Dead", "Establish", "Authenticate", "Network", "Terminate"
10355682Smarkm};
10455682Smarkm
10555682Smarkmconst char *
10655682Smarkmbundle_PhaseName(struct bundle *bundle)
10755682Smarkm{
108178825Sdfr  return bundle->phase <= PHASE_TERMINATE ?
109178825Sdfr    PhaseNames[bundle->phase] : "unknown";
110178825Sdfr}
111178825Sdfr
112178825Sdfrvoid
11372445Sassarbundle_NewPhase(struct bundle *bundle, u_int new)
114178825Sdfr{
115178825Sdfr  if (new == bundle->phase)
116178825Sdfr    return;
117178825Sdfr
118178825Sdfr  if (new <= PHASE_TERMINATE)
119178825Sdfr    log_Printf(LogPHASE, "bundle: %s\n", PhaseNames[new]);
120178825Sdfr
121233294Sstas  switch (new) {
122178825Sdfr  case PHASE_DEAD:
123178825Sdfr    log_DisplayPrompts();
124178825Sdfr    bundle->phase = new;
125178825Sdfr    break;
126178825Sdfr
12772445Sassar  case PHASE_ESTABLISH:
12872445Sassar    bundle->phase = new;
129233294Sstas    break;
13072445Sassar
13172445Sassar  case PHASE_AUTHENTICATE:
13255682Smarkm    bundle->phase = new;
133233294Sstas    log_DisplayPrompts();
13472445Sassar    break;
13572445Sassar
13672445Sassar  case PHASE_NETWORK:
13772445Sassar    ipcp_Setup(&bundle->ncp.ipcp);
13872445Sassar    fsm_Up(&bundle->ncp.ipcp.fsm);
13972445Sassar    fsm_Open(&bundle->ncp.ipcp.fsm);
14072445Sassar    bundle->phase = new;
14172445Sassar    log_DisplayPrompts();
14272445Sassar    break;
14372445Sassar
14472445Sassar  case PHASE_TERMINATE:
14572445Sassar    bundle->phase = new;
14672445Sassar    mp_Down(&bundle->ncp.mp);
147233294Sstas    log_DisplayPrompts();
14872445Sassar    break;
14972445Sassar  }
15072445Sassar}
15172445Sassar
152233294Sstasstatic void
153233294Sstasbundle_LayerStart(void *v, struct fsm *fp)
154233294Sstas{
155233294Sstas  /* The given FSM is about to start up ! */
156233294Sstas}
157233294Sstas
15872445Sassar
159233294Sstasstatic void
16072445Sassarbundle_Notify(struct bundle *bundle, char c)
16172445Sassar{
16272445Sassar  if (bundle->notify.fd != -1) {
16372445Sassar    if (write(bundle->notify.fd, &c, 1) == 1)
16472445Sassar      log_Printf(LogPHASE, "Parent notified of success.\n");
16572445Sassar    else
16672445Sassar      log_Printf(LogPHASE, "Failed to notify parent of success.\n");
16772445Sassar    close(bundle->notify.fd);
16872445Sassar    bundle->notify.fd = -1;
16972445Sassar  }
17072445Sassar}
17155682Smarkm
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_AutoLoadTimeout(void *v)
204{
205  struct bundle *bundle = (struct bundle *)v;
206
207  if (bundle->autoload.comingup) {
208    log_Printf(LogPHASE, "autoload: Another link is required\n");
209    /* bundle_Open() stops the timer */
210    bundle_Open(bundle, NULL, PHYS_AUTO, 0);
211  } else {
212    struct datalink *dl, *last;
213
214    timer_Stop(&bundle->autoload.timer);
215    for (last = NULL, dl = bundle->links; dl; dl = dl->next)
216      if (dl->physical->type == PHYS_AUTO && dl->state == DATALINK_OPEN)
217        last = dl;
218
219    if (last)
220      datalink_Close(last, CLOSE_STAYDOWN);
221  }
222}
223
224static void
225bundle_StartAutoLoadTimer(struct bundle *bundle, int up)
226{
227  struct datalink *dl;
228
229  timer_Stop(&bundle->autoload.timer);
230
231  if (bundle->CleaningUp || bundle->phase != PHASE_NETWORK) {
232    dl = NULL;
233    bundle->autoload.running = 0;
234  } else if (up) {
235    for (dl = bundle->links; dl; dl = dl->next)
236      if (dl->state == DATALINK_CLOSED && dl->physical->type == PHYS_AUTO) {
237        if (bundle->cfg.autoload.max.timeout) {
238          bundle->autoload.timer.func = bundle_AutoLoadTimeout;
239          bundle->autoload.timer.name = "autoload up";
240          bundle->autoload.timer.load =
241            bundle->cfg.autoload.max.timeout * SECTICKS;
242          bundle->autoload.timer.arg = bundle;
243          timer_Start(&bundle->autoload.timer);
244          bundle->autoload.done = time(NULL) + bundle->cfg.autoload.max.timeout;
245        } else
246          bundle_AutoLoadTimeout(bundle);
247        break;
248      }
249    bundle->autoload.running = (dl || bundle->cfg.autoload.min.timeout) ? 1 : 0;
250  } else {
251    int nlinks;
252    struct datalink *adl;
253
254    for (nlinks = 0, adl = NULL, dl = bundle->links; dl; dl = dl->next)
255      if (dl->state == DATALINK_OPEN) {
256        if (dl->physical->type == PHYS_AUTO)
257          adl = dl;
258        if (++nlinks > 1 && adl) {
259          if (bundle->cfg.autoload.min.timeout) {
260            bundle->autoload.timer.func = bundle_AutoLoadTimeout;
261            bundle->autoload.timer.name = "autoload down";
262            bundle->autoload.timer.load =
263              bundle->cfg.autoload.min.timeout * SECTICKS;
264            bundle->autoload.timer.arg = bundle;
265            timer_Start(&bundle->autoload.timer);
266            bundle->autoload.done =
267              time(NULL) + bundle->cfg.autoload.min.timeout;
268          }
269          break;
270        }
271      }
272
273    bundle->autoload.running = 1;
274  }
275
276  bundle->autoload.comingup = up ? 1 : 0;
277}
278
279static void
280bundle_StopAutoLoadTimer(struct bundle *bundle)
281{
282  timer_Stop(&bundle->autoload.timer);
283  bundle->autoload.done = 0;
284}
285
286static int
287bundle_RemainingAutoLoadTime(struct bundle *bundle)
288{
289  if (bundle->autoload.done)
290    return bundle->autoload.done - time(NULL);
291  return -1;
292}
293
294static void
295bundle_LinkAdded(struct bundle *bundle, struct datalink *dl)
296{
297  bundle->phys_type.all |= dl->physical->type;
298  if (dl->state == DATALINK_OPEN)
299    bundle->phys_type.open |= dl->physical->type;
300
301  /* Note: We only re-add links that are DATALINK_OPEN */
302  if (dl->physical->type == PHYS_AUTO &&
303      bundle->autoload.timer.state == TIMER_STOPPED &&
304      dl->state != DATALINK_OPEN &&
305      bundle->phase == PHASE_NETWORK)
306    bundle->autoload.running = 1;
307
308  if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL))
309      != bundle->phys_type.open && bundle->idle.timer.state == TIMER_STOPPED)
310    /* We may need to start our idle timer */
311    bundle_StartIdleTimer(bundle);
312}
313
314void
315bundle_LinksRemoved(struct bundle *bundle)
316{
317  struct datalink *dl;
318
319  bundle->phys_type.all = bundle->phys_type.open = 0;
320  for (dl = bundle->links; dl; dl = dl->next)
321    bundle_LinkAdded(bundle, dl);
322
323  if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL))
324      == bundle->phys_type.open)
325    bundle_StopIdleTimer(bundle);
326}
327
328static void
329bundle_LayerUp(void *v, struct fsm *fp)
330{
331  /*
332   * The given fsm is now up
333   * If it's an LCP, adjust our phys_mode.open value.
334   * If it's an LCP set our mtu (if we're multilink, add up the link
335   * speeds and set the MRRU) and start our autoload timer.
336   * If it's an NCP, tell our -background parent to go away.
337   * If it's the first NCP, start the idle timer.
338   */
339  struct bundle *bundle = (struct bundle *)v;
340
341  if (fp->proto == PROTO_LCP) {
342    struct physical *p = link2physical(fp->link);
343
344    bundle_LinkAdded(bundle, p->dl);
345    if (bundle->ncp.mp.active) {
346      struct datalink *dl;
347
348      bundle->ifSpeed = 0;
349      for (dl = bundle->links; dl; dl = dl->next)
350        if (dl->state == DATALINK_OPEN)
351          bundle->ifSpeed += modem_Speed(dl->physical);
352      tun_configure(bundle, bundle->ncp.mp.peer_mrru);
353      bundle->autoload.running = 1;
354    } else {
355      bundle->ifSpeed = modem_Speed(p);
356      tun_configure(bundle, fsm2lcp(fp)->his_mru);
357    }
358  } else if (fp->proto == PROTO_IPCP) {
359    bundle_StartIdleTimer(bundle);
360    bundle_Notify(bundle, EX_NORMAL);
361  }
362}
363
364static void
365bundle_LayerDown(void *v, struct fsm *fp)
366{
367  /*
368   * The given FSM has been told to come down.
369   * If it's our last NCP, stop the idle timer.
370   * If it's an LCP, adjust our phys_type.open value and any timers.
371   * If it's an LCP and we're in multilink mode, adjust our tun
372   * speed and make sure our minimum sequence number is adjusted.
373   */
374
375  struct bundle *bundle = (struct bundle *)v;
376
377  if (fp->proto == PROTO_IPCP)
378    bundle_StopIdleTimer(bundle);
379  else if (fp->proto == PROTO_LCP) {
380    bundle_LinksRemoved(bundle);  /* adjust timers & phys_type values */
381    if (bundle->ncp.mp.active) {
382      struct datalink *dl;
383      struct datalink *lost;
384
385      bundle->ifSpeed = 0;
386      lost = NULL;
387      for (dl = bundle->links; dl; dl = dl->next)
388        if (fp == &dl->physical->link.lcp.fsm)
389          lost = dl;
390        else if (dl->state == DATALINK_OPEN)
391          bundle->ifSpeed += modem_Speed(dl->physical);
392
393      if (bundle->ifSpeed)
394        /* Don't configure down to a speed of 0 */
395        tun_configure(bundle, bundle->ncp.mp.link.lcp.his_mru);
396
397      if (lost)
398        mp_LinkLost(&bundle->ncp.mp, lost);
399      else
400        log_Printf(LogALERT, "Oops, lost an unrecognised datalink (%s) !\n",
401                   fp->link->name);
402    }
403  }
404}
405
406static void
407bundle_LayerFinish(void *v, struct fsm *fp)
408{
409  /* The given fsm is now down (fp cannot be NULL)
410   *
411   * If it's the last LCP, fsm_Down all NCPs
412   * If it's the last NCP, fsm_Close all LCPs
413   */
414
415  struct bundle *bundle = (struct bundle *)v;
416  struct datalink *dl;
417
418  if (fp->proto == PROTO_IPCP) {
419    if (bundle_Phase(bundle) != PHASE_DEAD)
420      bundle_NewPhase(bundle, PHASE_TERMINATE);
421    for (dl = bundle->links; dl; dl = dl->next)
422      datalink_Close(dl, CLOSE_NORMAL);
423    fsm2initial(fp);
424  } else if (fp->proto == PROTO_LCP) {
425    int others_active;
426
427    others_active = 0;
428    for (dl = bundle->links; dl; dl = dl->next)
429      if (fp != &dl->physical->link.lcp.fsm &&
430          dl->state != DATALINK_CLOSED && dl->state != DATALINK_HANGUP)
431        others_active++;
432
433    if (!others_active)
434      fsm2initial(&bundle->ncp.ipcp.fsm);
435  }
436}
437
438int
439bundle_LinkIsUp(const struct bundle *bundle)
440{
441  return bundle->ncp.ipcp.fsm.state == ST_OPENED;
442}
443
444void
445bundle_Close(struct bundle *bundle, const char *name, int how)
446{
447  /*
448   * Please close the given datalink.
449   * If name == NULL or name is the last datalink, fsm_Close all NCPs
450   * (except our MP)
451   * If it isn't the last datalink, just Close that datalink.
452   */
453
454  struct datalink *dl, *this_dl;
455  int others_active;
456
457  others_active = 0;
458  this_dl = NULL;
459
460  for (dl = bundle->links; dl; dl = dl->next) {
461    if (name && !strcasecmp(name, dl->name))
462      this_dl = dl;
463    if (name == NULL || this_dl == dl) {
464      switch (how) {
465        case CLOSE_LCP:
466          datalink_DontHangup(dl);
467          /* fall through */
468        case CLOSE_STAYDOWN:
469          datalink_StayDown(dl);
470          break;
471      }
472    } else if (dl->state != DATALINK_CLOSED && dl->state != DATALINK_HANGUP)
473      others_active++;
474  }
475
476  if (name && this_dl == NULL) {
477    log_Printf(LogWARN, "%s: Invalid datalink name\n", name);
478    return;
479  }
480
481  if (!others_active) {
482    bundle_StopIdleTimer(bundle);
483    bundle_StopAutoLoadTimer(bundle);
484    if (bundle->ncp.ipcp.fsm.state > ST_CLOSED ||
485        bundle->ncp.ipcp.fsm.state == ST_STARTING)
486      fsm_Close(&bundle->ncp.ipcp.fsm);
487    else {
488      fsm2initial(&bundle->ncp.ipcp.fsm);
489      for (dl = bundle->links; dl; dl = dl->next)
490        datalink_Close(dl, how);
491    }
492  } else if (this_dl && this_dl->state != DATALINK_CLOSED &&
493             this_dl->state != DATALINK_HANGUP)
494    datalink_Close(this_dl, how);
495}
496
497void
498bundle_Down(struct bundle *bundle, int how)
499{
500  struct datalink *dl;
501
502  for (dl = bundle->links; dl; dl = dl->next)
503    datalink_Down(dl, how);
504}
505
506static int
507bundle_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
508{
509  struct bundle *bundle = descriptor2bundle(d);
510  struct datalink *dl;
511  int result, want, queued, nlinks;
512
513  result = 0;
514
515  /* If there are aren't many packets queued, look for some more. */
516  for (nlinks = 0, dl = bundle->links; dl; dl = dl->next)
517    nlinks++;
518
519  if (nlinks) {
520    queued = r ? bundle_FillQueues(bundle) : ip_QueueLen(&bundle->ncp.ipcp);
521    if (bundle->autoload.running) {
522      if (queued < bundle->cfg.autoload.max.packets) {
523        if (queued > bundle->cfg.autoload.min.packets)
524          bundle_StopAutoLoadTimer(bundle);
525        else if (bundle->autoload.timer.state != TIMER_RUNNING ||
526                 bundle->autoload.comingup)
527          bundle_StartAutoLoadTimer(bundle, 0);
528      } else if (bundle->autoload.timer.state != TIMER_RUNNING ||
529                 !bundle->autoload.comingup)
530        bundle_StartAutoLoadTimer(bundle, 1);
531    }
532
533    if (r && (bundle->phase == PHASE_NETWORK ||
534              bundle->phys_type.all & PHYS_AUTO)) {
535      /* enough surplus so that we can tell if we're getting swamped */
536      want = bundle->cfg.autoload.max.packets + nlinks * 2;
537      /* but at least 20 packets ! */
538      if (want < 20)
539        want = 20;
540      if (queued < want) {
541        /* Not enough - select() for more */
542        if (bundle->choked.timer.state == TIMER_RUNNING)
543          timer_Stop(&bundle->choked.timer);	/* Not needed any more */
544        FD_SET(bundle->dev.fd, r);
545        if (*n < bundle->dev.fd + 1)
546          *n = bundle->dev.fd + 1;
547        log_Printf(LogTIMER, "%s: fdset(r) %d\n", TUN_NAME, bundle->dev.fd);
548        result++;
549      } else if (bundle->choked.timer.state == TIMER_STOPPED) {
550        bundle->choked.timer.func = bundle_ClearQueues;
551        bundle->choked.timer.name = "output choke";
552        bundle->choked.timer.load = bundle->cfg.choked.timeout * SECTICKS;
553        bundle->choked.timer.arg = bundle;
554        timer_Start(&bundle->choked.timer);
555      }
556    }
557  }
558
559  /* Which links need a select() ? */
560  for (dl = bundle->links; dl; dl = dl->next)
561    result += descriptor_UpdateSet(&dl->desc, r, w, e, n);
562
563  /*
564   * This *MUST* be called after the datalink UpdateSet()s as it
565   * might be ``holding'' one of the datalinks (death-row) and
566   * wants to be able to de-select() it from the descriptor set.
567   */
568  result += descriptor_UpdateSet(&bundle->ncp.mp.server.desc, r, w, e, n);
569
570  return result;
571}
572
573static int
574bundle_IsSet(struct descriptor *d, const fd_set *fdset)
575{
576  struct bundle *bundle = descriptor2bundle(d);
577  struct datalink *dl;
578
579  for (dl = bundle->links; dl; dl = dl->next)
580    if (descriptor_IsSet(&dl->desc, fdset))
581      return 1;
582
583  if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
584    return 1;
585
586  return FD_ISSET(bundle->dev.fd, fdset);
587}
588
589static void
590bundle_DescriptorRead(struct descriptor *d, struct bundle *bundle,
591                      const fd_set *fdset)
592{
593  struct datalink *dl;
594
595  if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
596    descriptor_Read(&bundle->ncp.mp.server.desc, bundle, fdset);
597
598  for (dl = bundle->links; dl; dl = dl->next)
599    if (descriptor_IsSet(&dl->desc, fdset))
600      descriptor_Read(&dl->desc, bundle, fdset);
601
602  if (FD_ISSET(bundle->dev.fd, fdset)) {
603    struct tun_data tun;
604    int n, pri;
605
606    /* something to read from tun */
607    n = read(bundle->dev.fd, &tun, sizeof tun);
608    if (n < 0) {
609      log_Printf(LogWARN, "read from %s: %s\n", TUN_NAME, strerror(errno));
610      return;
611    }
612    n -= sizeof tun - sizeof tun.data;
613    if (n <= 0) {
614      log_Printf(LogERROR, "read from %s: Only %d bytes read ?\n", TUN_NAME, n);
615      return;
616    }
617    if (!tun_check_header(tun, AF_INET))
618      return;
619
620    if (((struct ip *)tun.data)->ip_dst.s_addr ==
621        bundle->ncp.ipcp.my_ip.s_addr) {
622      /* we've been asked to send something addressed *to* us :( */
623      if (Enabled(bundle, OPT_LOOPBACK)) {
624        pri = PacketCheck(bundle, tun.data, n, &bundle->filter.in);
625        if (pri >= 0) {
626          struct mbuf *bp;
627
628#ifndef NOALIAS
629          if (bundle->AliasEnabled) {
630            PacketAliasIn(tun.data, sizeof tun.data);
631            n = ntohs(((struct ip *)tun.data)->ip_len);
632          }
633#endif
634          bp = mbuf_Alloc(n, MB_IPIN);
635          memcpy(MBUF_CTOP(bp), tun.data, n);
636          ip_Input(bundle, bp);
637          log_Printf(LogDEBUG, "Looped back packet addressed to myself\n");
638        }
639        return;
640      } else
641        log_Printf(LogDEBUG, "Oops - forwarding packet addressed to myself\n");
642    }
643
644    /*
645     * Process on-demand dialup. Output packets are queued within tunnel
646     * device until IPCP is opened.
647     */
648
649    if (bundle_Phase(bundle) == PHASE_DEAD) {
650      /*
651       * Note, we must be in AUTO mode :-/ otherwise our interface should
652       * *not* be UP and we can't receive data
653       */
654      if ((pri = PacketCheck(bundle, tun.data, n, &bundle->filter.dial)) >= 0)
655        bundle_Open(bundle, NULL, PHYS_AUTO, 0);
656      else
657        /*
658         * Drop the packet.  If we were to queue it, we'd just end up with
659         * a pile of timed-out data in our output queue by the time we get
660         * around to actually dialing.  We'd also prematurely reach the
661         * threshold at which we stop select()ing to read() the tun
662         * device - breaking auto-dial.
663         */
664        return;
665    }
666
667    pri = PacketCheck(bundle, tun.data, n, &bundle->filter.out);
668    if (pri >= 0) {
669#ifndef NOALIAS
670      if (bundle->AliasEnabled) {
671        PacketAliasOut(tun.data, sizeof tun.data);
672        n = ntohs(((struct ip *)tun.data)->ip_len);
673      }
674#endif
675      ip_Enqueue(&bundle->ncp.ipcp, pri, tun.data, n);
676    }
677  }
678}
679
680static int
681bundle_DescriptorWrite(struct descriptor *d, struct bundle *bundle,
682                       const fd_set *fdset)
683{
684  struct datalink *dl;
685  int result = 0;
686
687  /* This is not actually necessary as struct mpserver doesn't Write() */
688  if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
689    descriptor_Write(&bundle->ncp.mp.server.desc, bundle, fdset);
690
691  for (dl = bundle->links; dl; dl = dl->next)
692    if (descriptor_IsSet(&dl->desc, fdset))
693      result += descriptor_Write(&dl->desc, bundle, fdset);
694
695  return result;
696}
697
698void
699bundle_LockTun(struct bundle *bundle)
700{
701  FILE *lockfile;
702  char pidfile[MAXPATHLEN];
703
704  snprintf(pidfile, sizeof pidfile, "%stun%d.pid", _PATH_VARRUN, bundle->unit);
705  lockfile = ID0fopen(pidfile, "w");
706  if (lockfile != NULL) {
707    fprintf(lockfile, "%d\n", (int)getpid());
708    fclose(lockfile);
709  }
710#ifndef RELEASE_CRUNCH
711  else
712    log_Printf(LogERROR, "Warning: Can't create %s: %s\n",
713               pidfile, strerror(errno));
714#endif
715}
716
717static void
718bundle_UnlockTun(struct bundle *bundle)
719{
720  char pidfile[MAXPATHLEN];
721
722  snprintf(pidfile, sizeof pidfile, "%stun%d.pid", _PATH_VARRUN, bundle->unit);
723  ID0unlink(pidfile);
724}
725
726struct bundle *
727bundle_Create(const char *prefix, int type, const char **argv)
728{
729  int s, enoentcount, err;
730  const char *ifname;
731  struct ifreq ifrq;
732  static struct bundle bundle;		/* there can be only one */
733
734  if (bundle.iface != NULL) {	/* Already allocated ! */
735    log_Printf(LogALERT, "bundle_Create:  There's only one BUNDLE !\n");
736    return NULL;
737  }
738
739  err = ENOENT;
740  enoentcount = 0;
741  for (bundle.unit = 0; ; bundle.unit++) {
742    snprintf(bundle.dev.Name, sizeof bundle.dev.Name, "%s%d",
743             prefix, bundle.unit);
744    bundle.dev.fd = ID0open(bundle.dev.Name, O_RDWR);
745    if (bundle.dev.fd >= 0)
746      break;
747    else if (errno == ENXIO) {
748      err = errno;
749      break;
750    } else if (errno == ENOENT) {
751      if (++enoentcount > 2)
752	break;
753    } else
754      err = errno;
755  }
756
757  if (bundle.dev.fd < 0) {
758    log_Printf(LogWARN, "No available tunnel devices found (%s).\n",
759              strerror(err));
760    return NULL;
761  }
762
763  log_SetTun(bundle.unit);
764  bundle.argv = argv;
765
766  s = socket(AF_INET, SOCK_DGRAM, 0);
767  if (s < 0) {
768    log_Printf(LogERROR, "bundle_Create: socket(): %s\n", strerror(errno));
769    close(bundle.dev.fd);
770    return NULL;
771  }
772
773  ifname = strrchr(bundle.dev.Name, '/');
774  if (ifname == NULL)
775    ifname = bundle.dev.Name;
776  else
777    ifname++;
778
779  bundle.iface = iface_Create(ifname);
780  if (bundle.iface == NULL) {
781    close(s);
782    close(bundle.dev.fd);
783    return NULL;
784  }
785
786  /*
787   * Now, bring up the interface.
788   */
789  memset(&ifrq, '\0', sizeof ifrq);
790  strncpy(ifrq.ifr_name, ifname, sizeof ifrq.ifr_name - 1);
791  ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0';
792  if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
793    log_Printf(LogERROR, "bundle_Create: ioctl(SIOCGIFFLAGS): %s\n",
794	      strerror(errno));
795    close(s);
796    iface_Destroy(bundle.iface);
797    bundle.iface = NULL;
798    close(bundle.dev.fd);
799    return NULL;
800  }
801  ifrq.ifr_flags |= IFF_UP;
802  if (ID0ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
803    log_Printf(LogERROR, "bundle_Create: ioctl(SIOCSIFFLAGS): %s\n",
804	      strerror(errno));
805    close(s);
806    iface_Destroy(bundle.iface);
807    bundle.iface = NULL;
808    close(bundle.dev.fd);
809    return NULL;
810  }
811
812  close(s);
813
814  log_Printf(LogPHASE, "Using interface: %s\n", ifname);
815
816  bundle.ifSpeed = 0;
817
818  bundle.routing_seq = 0;
819  bundle.phase = PHASE_DEAD;
820  bundle.CleaningUp = 0;
821  bundle.AliasEnabled = 0;
822
823  bundle.fsm.LayerStart = bundle_LayerStart;
824  bundle.fsm.LayerUp = bundle_LayerUp;
825  bundle.fsm.LayerDown = bundle_LayerDown;
826  bundle.fsm.LayerFinish = bundle_LayerFinish;
827  bundle.fsm.object = &bundle;
828
829  bundle.cfg.idle_timeout = NCP_IDLE_TIMEOUT;
830  *bundle.cfg.auth.name = '\0';
831  *bundle.cfg.auth.key = '\0';
832  bundle.cfg.opt = OPT_SROUTES | OPT_IDCHECK | OPT_LOOPBACK |
833                   OPT_THROUGHPUT | OPT_UTMP;
834  *bundle.cfg.label = '\0';
835  bundle.cfg.mtu = DEF_MTU;
836  bundle.cfg.autoload.max.packets = 0;
837  bundle.cfg.autoload.max.timeout = 0;
838  bundle.cfg.autoload.min.packets = 0;
839  bundle.cfg.autoload.min.timeout = 0;
840  bundle.cfg.choked.timeout = CHOKED_TIMEOUT;
841  bundle.phys_type.all = type;
842  bundle.phys_type.open = 0;
843
844  bundle.links = datalink_Create("deflink", &bundle, type);
845  if (bundle.links == NULL) {
846    log_Printf(LogALERT, "Cannot create data link: %s\n", strerror(errno));
847    iface_Destroy(bundle.iface);
848    bundle.iface = NULL;
849    close(bundle.dev.fd);
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  memset(&bundle.choked.timer, '\0', sizeof bundle.choked.timer);
881
882  /* Clean out any leftover crud */
883  iface_Clear(bundle.iface, IFACE_CLEAR_ALL);
884
885  bundle_LockTun(&bundle);
886
887  return &bundle;
888}
889
890static void
891bundle_DownInterface(struct bundle *bundle)
892{
893  struct ifreq ifrq;
894  int s;
895
896  route_IfDelete(bundle, 1);
897
898  s = ID0socket(AF_INET, SOCK_DGRAM, 0);
899  if (s < 0) {
900    log_Printf(LogERROR, "bundle_DownInterface: socket: %s\n", strerror(errno));
901    return;
902  }
903
904  memset(&ifrq, '\0', sizeof ifrq);
905  strncpy(ifrq.ifr_name, bundle->iface->name, sizeof ifrq.ifr_name - 1);
906  ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0';
907  if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
908    log_Printf(LogERROR, "bundle_DownInterface: ioctl(SIOCGIFFLAGS): %s\n",
909       strerror(errno));
910    close(s);
911    return;
912  }
913  ifrq.ifr_flags &= ~IFF_UP;
914  if (ID0ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
915    log_Printf(LogERROR, "bundle_DownInterface: ioctl(SIOCSIFFLAGS): %s\n",
916       strerror(errno));
917    close(s);
918    return;
919  }
920  close(s);
921}
922
923void
924bundle_Destroy(struct bundle *bundle)
925{
926  struct datalink *dl;
927
928  /*
929   * Clean up the interface.  We don't need to timer_Stop()s, mp_Down(),
930   * ipcp_CleanInterface() and bundle_DownInterface() unless we're getting
931   * out under exceptional conditions such as a descriptor exception.
932   */
933  timer_Stop(&bundle->idle.timer);
934  timer_Stop(&bundle->choked.timer);
935  timer_Stop(&bundle->autoload.timer);
936  mp_Down(&bundle->ncp.mp);
937  ipcp_CleanInterface(&bundle->ncp.ipcp);
938  bundle_DownInterface(bundle);
939
940  /* Again, these are all DATALINK_CLOSED unless we're abending */
941  dl = bundle->links;
942  while (dl)
943    dl = datalink_Destroy(dl);
944
945  close(bundle->dev.fd);
946  bundle_UnlockTun(bundle);
947
948  /* In case we never made PHASE_NETWORK */
949  bundle_Notify(bundle, EX_ERRDEAD);
950
951  iface_Destroy(bundle->iface);
952  bundle->iface = NULL;
953}
954
955struct rtmsg {
956  struct rt_msghdr m_rtm;
957  char m_space[64];
958};
959
960int
961bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst,
962                struct in_addr gateway, struct in_addr mask, int bang, int ssh)
963{
964  struct rtmsg rtmes;
965  int s, nb, wb;
966  char *cp;
967  const char *cmdstr;
968  struct sockaddr_in rtdata;
969  int result = 1;
970
971  if (bang)
972    cmdstr = (cmd == RTM_ADD ? "Add!" : "Delete!");
973  else
974    cmdstr = (cmd == RTM_ADD ? "Add" : "Delete");
975  s = ID0socket(PF_ROUTE, SOCK_RAW, 0);
976  if (s < 0) {
977    log_Printf(LogERROR, "bundle_SetRoute: socket(): %s\n", strerror(errno));
978    return result;
979  }
980  memset(&rtmes, '\0', sizeof rtmes);
981  rtmes.m_rtm.rtm_version = RTM_VERSION;
982  rtmes.m_rtm.rtm_type = cmd;
983  rtmes.m_rtm.rtm_addrs = RTA_DST;
984  rtmes.m_rtm.rtm_seq = ++bundle->routing_seq;
985  rtmes.m_rtm.rtm_pid = getpid();
986  rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
987
988  memset(&rtdata, '\0', sizeof rtdata);
989  rtdata.sin_len = sizeof rtdata;
990  rtdata.sin_family = AF_INET;
991  rtdata.sin_port = 0;
992  rtdata.sin_addr = dst;
993
994  cp = rtmes.m_space;
995  memcpy(cp, &rtdata, rtdata.sin_len);
996  cp += rtdata.sin_len;
997  if (cmd == RTM_ADD) {
998    if (gateway.s_addr == INADDR_ANY) {
999      log_Printf(LogERROR, "bundle_SetRoute: Cannot add a route with"
1000                 " destination 0.0.0.0\n");
1001      close(s);
1002      return result;
1003    } else {
1004      rtdata.sin_addr = gateway;
1005      memcpy(cp, &rtdata, rtdata.sin_len);
1006      cp += rtdata.sin_len;
1007      rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
1008    }
1009  }
1010
1011  if (dst.s_addr == INADDR_ANY)
1012    mask.s_addr = INADDR_ANY;
1013
1014  if (cmd == RTM_ADD || dst.s_addr == INADDR_ANY) {
1015    rtdata.sin_addr = mask;
1016    memcpy(cp, &rtdata, rtdata.sin_len);
1017    cp += rtdata.sin_len;
1018    rtmes.m_rtm.rtm_addrs |= RTA_NETMASK;
1019  }
1020
1021  nb = cp - (char *) &rtmes;
1022  rtmes.m_rtm.rtm_msglen = nb;
1023  wb = ID0write(s, &rtmes, nb);
1024  if (wb < 0) {
1025    log_Printf(LogTCPIP, "bundle_SetRoute failure:\n");
1026    log_Printf(LogTCPIP, "bundle_SetRoute:  Cmd = %s\n", cmdstr);
1027    log_Printf(LogTCPIP, "bundle_SetRoute:  Dst = %s\n", inet_ntoa(dst));
1028    log_Printf(LogTCPIP, "bundle_SetRoute:  Gateway = %s\n", inet_ntoa(gateway));
1029    log_Printf(LogTCPIP, "bundle_SetRoute:  Mask = %s\n", inet_ntoa(mask));
1030failed:
1031    if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST ||
1032                           (rtmes.m_rtm.rtm_errno == 0 && errno == EEXIST))) {
1033      if (!bang) {
1034        log_Printf(LogWARN, "Add route failed: %s already exists\n",
1035                  inet_ntoa(dst));
1036        result = 0;	/* Don't add to our dynamic list */
1037      } else {
1038        rtmes.m_rtm.rtm_type = cmd = RTM_CHANGE;
1039        if ((wb = ID0write(s, &rtmes, nb)) < 0)
1040          goto failed;
1041      }
1042    } else if (cmd == RTM_DELETE &&
1043             (rtmes.m_rtm.rtm_errno == ESRCH ||
1044              (rtmes.m_rtm.rtm_errno == 0 && errno == ESRCH))) {
1045      if (!bang)
1046        log_Printf(LogWARN, "Del route failed: %s: Non-existent\n",
1047                  inet_ntoa(dst));
1048    } else if (rtmes.m_rtm.rtm_errno == 0) {
1049      if (!ssh || errno != ENETUNREACH)
1050        log_Printf(LogWARN, "%s route failed: %s: errno: %s\n", cmdstr,
1051                   inet_ntoa(dst), strerror(errno));
1052    } else
1053      log_Printf(LogWARN, "%s route failed: %s: %s\n",
1054		 cmdstr, inet_ntoa(dst), strerror(rtmes.m_rtm.rtm_errno));
1055  }
1056  log_Printf(LogDEBUG, "wrote %d: cmd = %s, dst = %x, gateway = %x\n",
1057            wb, cmdstr, (unsigned)dst.s_addr, (unsigned)gateway.s_addr);
1058  close(s);
1059
1060  return result;
1061}
1062
1063void
1064bundle_LinkClosed(struct bundle *bundle, struct datalink *dl)
1065{
1066  /*
1067   * Our datalink has closed.
1068   * CleanDatalinks() (called from DoLoop()) will remove closed
1069   * BACKGROUND and DIRECT links.
1070   * If it's the last data link, enter phase DEAD.
1071   *
1072   * NOTE: dl may not be in our list (bundle_SendDatalink()) !
1073   */
1074
1075  struct datalink *odl;
1076  int other_links;
1077
1078  log_SetTtyCommandMode(dl);
1079
1080  other_links = 0;
1081  for (odl = bundle->links; odl; odl = odl->next)
1082    if (odl != dl && odl->state != DATALINK_CLOSED)
1083      other_links++;
1084
1085  if (!other_links) {
1086    if (dl->physical->type != PHYS_AUTO)	/* Not in -auto mode */
1087      bundle_DownInterface(bundle);
1088    fsm2initial(&bundle->ncp.ipcp.fsm);
1089    bundle_NewPhase(bundle, PHASE_DEAD);
1090    bundle_StopIdleTimer(bundle);
1091    bundle_StopAutoLoadTimer(bundle);
1092    bundle->autoload.running = 0;
1093  } else
1094    bundle->autoload.running = 1;
1095}
1096
1097void
1098bundle_Open(struct bundle *bundle, const char *name, int mask, int force)
1099{
1100  /*
1101   * Please open the given datalink, or all if name == NULL
1102   */
1103  struct datalink *dl;
1104
1105  timer_Stop(&bundle->autoload.timer);
1106  for (dl = bundle->links; dl; dl = dl->next)
1107    if (name == NULL || !strcasecmp(dl->name, name)) {
1108      if ((mask & dl->physical->type) &&
1109          (dl->state == DATALINK_CLOSED ||
1110           (force && dl->state == DATALINK_OPENING &&
1111            dl->dial_timer.state == TIMER_RUNNING))) {
1112        if (force)
1113          timer_Stop(&dl->dial_timer);
1114        datalink_Up(dl, 1, 1);
1115        if (mask == PHYS_AUTO)
1116          /* Only one AUTO link at a time (see the AutoLoad timer) */
1117          break;
1118      }
1119      if (name != NULL)
1120        break;
1121    }
1122}
1123
1124struct datalink *
1125bundle2datalink(struct bundle *bundle, const char *name)
1126{
1127  struct datalink *dl;
1128
1129  if (name != NULL) {
1130    for (dl = bundle->links; dl; dl = dl->next)
1131      if (!strcasecmp(dl->name, name))
1132        return dl;
1133  } else if (bundle->links && !bundle->links->next)
1134    return bundle->links;
1135
1136  return NULL;
1137}
1138
1139int
1140bundle_FillQueues(struct bundle *bundle)
1141{
1142  int total;
1143
1144  if (bundle->ncp.mp.active)
1145    total = mp_FillQueues(bundle);
1146  else {
1147    struct datalink *dl;
1148    int add;
1149
1150    for (total = 0, dl = bundle->links; dl; dl = dl->next)
1151      if (dl->state == DATALINK_OPEN) {
1152        add = link_QueueLen(&dl->physical->link);
1153        if (add == 0 && dl->physical->out == NULL)
1154          add = ip_FlushPacket(&dl->physical->link, bundle);
1155        total += add;
1156      }
1157  }
1158
1159  return total + ip_QueueLen(&bundle->ncp.ipcp);
1160}
1161
1162int
1163bundle_ShowLinks(struct cmdargs const *arg)
1164{
1165  struct datalink *dl;
1166
1167  for (dl = arg->bundle->links; dl; dl = dl->next) {
1168    prompt_Printf(arg->prompt, "Name: %s [%s, %s]",
1169                  dl->name, mode2Nam(dl->physical->type), datalink_State(dl));
1170    if (dl->physical->link.throughput.rolling && dl->state == DATALINK_OPEN)
1171      prompt_Printf(arg->prompt, " weight %d, %d bytes/sec",
1172                    dl->mp.weight,
1173                    dl->physical->link.throughput.OctetsPerSecond);
1174    prompt_Printf(arg->prompt, "\n");
1175  }
1176
1177  return 0;
1178}
1179
1180static const char *
1181optval(struct bundle *bundle, int bit)
1182{
1183  return (bundle->cfg.opt & bit) ? "enabled" : "disabled";
1184}
1185
1186int
1187bundle_ShowStatus(struct cmdargs const *arg)
1188{
1189  int remaining;
1190
1191  prompt_Printf(arg->prompt, "Phase %s\n", bundle_PhaseName(arg->bundle));
1192  prompt_Printf(arg->prompt, " Device:        %s\n", arg->bundle->dev.Name);
1193  prompt_Printf(arg->prompt, " Interface:     %s @ %lubps\n",
1194                arg->bundle->iface->name, arg->bundle->ifSpeed);
1195
1196  prompt_Printf(arg->prompt, "\nDefaults:\n");
1197  prompt_Printf(arg->prompt, " Label:         %s\n", arg->bundle->cfg.label);
1198  prompt_Printf(arg->prompt, " Auth name:     %s\n",
1199                arg->bundle->cfg.auth.name);
1200  prompt_Printf(arg->prompt, " Auto Load:     Up after %ds of >= %d packets\n",
1201                arg->bundle->cfg.autoload.max.timeout,
1202                arg->bundle->cfg.autoload.max.packets);
1203  prompt_Printf(arg->prompt, "                Down after %ds of <= %d"
1204                " packets\n", arg->bundle->cfg.autoload.min.timeout,
1205                arg->bundle->cfg.autoload.min.packets);
1206  if (arg->bundle->autoload.timer.state == TIMER_RUNNING)
1207    prompt_Printf(arg->prompt, "                %ds remaining 'till "
1208                  "a link comes %s\n",
1209                  bundle_RemainingAutoLoadTime(arg->bundle),
1210                  arg->bundle->autoload.comingup ? "up" : "down");
1211  else
1212    prompt_Printf(arg->prompt, "                %srunning with %d"
1213                  " packets queued\n", arg->bundle->autoload.running ?
1214                  "" : "not ", ip_QueueLen(&arg->bundle->ncp.ipcp));
1215
1216  prompt_Printf(arg->prompt, " Choked Timer:  %ds\n",
1217                arg->bundle->cfg.choked.timeout);
1218  prompt_Printf(arg->prompt, " Idle Timer:    ");
1219  if (arg->bundle->cfg.idle_timeout) {
1220    prompt_Printf(arg->prompt, "%ds", arg->bundle->cfg.idle_timeout);
1221    remaining = bundle_RemainingIdleTime(arg->bundle);
1222    if (remaining != -1)
1223      prompt_Printf(arg->prompt, " (%ds remaining)", remaining);
1224    prompt_Printf(arg->prompt, "\n");
1225  } else
1226    prompt_Printf(arg->prompt, "disabled\n");
1227  prompt_Printf(arg->prompt, " MTU:           ");
1228  if (arg->bundle->cfg.mtu)
1229    prompt_Printf(arg->prompt, "%d\n", arg->bundle->cfg.mtu);
1230  else
1231    prompt_Printf(arg->prompt, "unspecified\n");
1232
1233  prompt_Printf(arg->prompt, " Sticky Routes: %s\n",
1234                optval(arg->bundle, OPT_SROUTES));
1235  prompt_Printf(arg->prompt, " ID check:      %s\n",
1236                optval(arg->bundle, OPT_IDCHECK));
1237  prompt_Printf(arg->prompt, " Loopback:      %s\n",
1238                optval(arg->bundle, OPT_LOOPBACK));
1239  prompt_Printf(arg->prompt, " PasswdAuth:    %s\n",
1240                optval(arg->bundle, OPT_PASSWDAUTH));
1241  prompt_Printf(arg->prompt, " Proxy:         %s\n",
1242                optval(arg->bundle, OPT_PROXY));
1243  prompt_Printf(arg->prompt, " Throughput:    %s\n",
1244                optval(arg->bundle, OPT_THROUGHPUT));
1245  prompt_Printf(arg->prompt, " Utmp Logging:  %s\n",
1246                optval(arg->bundle, OPT_UTMP));
1247  prompt_Printf(arg->prompt, " Iface-Alias:   %s\n",
1248                optval(arg->bundle, OPT_IFACEALIAS));
1249
1250  return 0;
1251}
1252
1253static void
1254bundle_IdleTimeout(void *v)
1255{
1256  struct bundle *bundle = (struct bundle *)v;
1257
1258  log_Printf(LogPHASE, "Idle timer expired.\n");
1259  bundle_StopIdleTimer(bundle);
1260  bundle_Close(bundle, NULL, CLOSE_STAYDOWN);
1261}
1262
1263/*
1264 *  Start Idle timer. If timeout is reached, we call bundle_Close() to
1265 *  close LCP and link.
1266 */
1267void
1268bundle_StartIdleTimer(struct bundle *bundle)
1269{
1270  timer_Stop(&bundle->idle.timer);
1271  if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) !=
1272      bundle->phys_type.open && bundle->cfg.idle_timeout) {
1273    bundle->idle.timer.func = bundle_IdleTimeout;
1274    bundle->idle.timer.name = "idle";
1275    bundle->idle.timer.load = bundle->cfg.idle_timeout * SECTICKS;
1276    bundle->idle.timer.arg = bundle;
1277    timer_Start(&bundle->idle.timer);
1278    bundle->idle.done = time(NULL) + bundle->cfg.idle_timeout;
1279  }
1280}
1281
1282void
1283bundle_SetIdleTimer(struct bundle *bundle, int value)
1284{
1285  bundle->cfg.idle_timeout = value;
1286  if (bundle_LinkIsUp(bundle))
1287    bundle_StartIdleTimer(bundle);
1288}
1289
1290void
1291bundle_StopIdleTimer(struct bundle *bundle)
1292{
1293  timer_Stop(&bundle->idle.timer);
1294  bundle->idle.done = 0;
1295}
1296
1297static int
1298bundle_RemainingIdleTime(struct bundle *bundle)
1299{
1300  if (bundle->idle.done)
1301    return bundle->idle.done - time(NULL);
1302  return -1;
1303}
1304
1305int
1306bundle_IsDead(struct bundle *bundle)
1307{
1308  return !bundle->links || (bundle->phase == PHASE_DEAD && bundle->CleaningUp);
1309}
1310
1311static struct datalink *
1312bundle_DatalinkLinkout(struct bundle *bundle, struct datalink *dl)
1313{
1314  struct datalink **dlp;
1315
1316  for (dlp = &bundle->links; *dlp; dlp = &(*dlp)->next)
1317    if (*dlp == dl) {
1318      *dlp = dl->next;
1319      dl->next = NULL;
1320      bundle_LinksRemoved(bundle);
1321      return dl;
1322    }
1323
1324  return NULL;
1325}
1326
1327static void
1328bundle_DatalinkLinkin(struct bundle *bundle, struct datalink *dl)
1329{
1330  struct datalink **dlp = &bundle->links;
1331
1332  while (*dlp)
1333    dlp = &(*dlp)->next;
1334
1335  *dlp = dl;
1336  dl->next = NULL;
1337
1338  bundle_LinkAdded(bundle, dl);
1339}
1340
1341void
1342bundle_CleanDatalinks(struct bundle *bundle)
1343{
1344  struct datalink **dlp = &bundle->links;
1345  int found = 0;
1346
1347  while (*dlp)
1348    if ((*dlp)->state == DATALINK_CLOSED &&
1349        (*dlp)->physical->type & (PHYS_DIRECT|PHYS_BACKGROUND)) {
1350      *dlp = datalink_Destroy(*dlp);
1351      found++;
1352    } else
1353      dlp = &(*dlp)->next;
1354
1355  if (found)
1356    bundle_LinksRemoved(bundle);
1357}
1358
1359int
1360bundle_DatalinkClone(struct bundle *bundle, struct datalink *dl,
1361                     const char *name)
1362{
1363  if (bundle2datalink(bundle, name)) {
1364    log_Printf(LogWARN, "Clone: %s: name already exists\n", name);
1365    return 0;
1366  }
1367
1368  bundle_DatalinkLinkin(bundle, datalink_Clone(dl, name));
1369  return 1;
1370}
1371
1372void
1373bundle_DatalinkRemove(struct bundle *bundle, struct datalink *dl)
1374{
1375  dl = bundle_DatalinkLinkout(bundle, dl);
1376  if (dl)
1377    datalink_Destroy(dl);
1378}
1379
1380void
1381bundle_SetLabel(struct bundle *bundle, const char *label)
1382{
1383  if (label)
1384    strncpy(bundle->cfg.label, label, sizeof bundle->cfg.label - 1);
1385  else
1386    *bundle->cfg.label = '\0';
1387}
1388
1389const char *
1390bundle_GetLabel(struct bundle *bundle)
1391{
1392  return *bundle->cfg.label ? bundle->cfg.label : NULL;
1393}
1394
1395void
1396bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun)
1397{
1398  char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int)];
1399  struct cmsghdr *cmsg = (struct cmsghdr *)cmsgbuf;
1400  struct msghdr msg;
1401  struct iovec iov[SCATTER_SEGMENTS];
1402  struct datalink *dl;
1403  int niov, link_fd, expect, f;
1404  pid_t pid;
1405
1406  log_Printf(LogPHASE, "Receiving datalink\n");
1407
1408  /* Create our scatter/gather array */
1409  niov = 1;
1410  iov[0].iov_len = strlen(Version) + 1;
1411  iov[0].iov_base = (char *)malloc(iov[0].iov_len);
1412  if (datalink2iov(NULL, iov, &niov, sizeof iov / sizeof *iov, 0) == -1) {
1413    close(s);
1414    return;
1415  }
1416
1417  pid = getpid();
1418  write(s, &pid, sizeof pid);
1419
1420  for (f = expect = 0; f < niov; f++)
1421    expect += iov[f].iov_len;
1422
1423  /* Set up our message */
1424  cmsg->cmsg_len = sizeof cmsgbuf;
1425  cmsg->cmsg_level = SOL_SOCKET;
1426  cmsg->cmsg_type = 0;
1427
1428  memset(&msg, '\0', sizeof msg);
1429  msg.msg_name = (caddr_t)sun;
1430  msg.msg_namelen = sizeof *sun;
1431  msg.msg_iov = iov;
1432  msg.msg_iovlen = niov;
1433  msg.msg_control = cmsgbuf;
1434  msg.msg_controllen = sizeof cmsgbuf;
1435
1436  log_Printf(LogDEBUG, "Expecting %d scatter/gather bytes\n", expect);
1437  f = expect + 100;
1438  setsockopt(s, SOL_SOCKET, SO_RCVBUF, &f, sizeof f);
1439  if ((f = recvmsg(s, &msg, MSG_WAITALL)) != expect) {
1440    if (f == -1)
1441      log_Printf(LogERROR, "Failed recvmsg: %s\n", strerror(errno));
1442    else
1443      log_Printf(LogERROR, "Failed recvmsg: Got %d, not %d\n", f, expect);
1444    while (niov--)
1445      free(iov[niov].iov_base);
1446    close(s);
1447    return;
1448  }
1449
1450  write(s, "!", 1);	/* ACK */
1451  close(s);
1452
1453  if (cmsg->cmsg_type != SCM_RIGHTS) {
1454    log_Printf(LogERROR, "Recvmsg: no descriptor received !\n");
1455    while (niov--)
1456      free(iov[niov].iov_base);
1457    return;
1458  }
1459
1460  /* We've successfully received an open file descriptor through our socket */
1461  log_Printf(LogDEBUG, "Receiving device descriptor\n");
1462  link_fd = *(int *)CMSG_DATA(cmsg);
1463
1464  if (strncmp(Version, iov[0].iov_base, iov[0].iov_len)) {
1465    log_Printf(LogWARN, "Cannot receive datalink, incorrect version"
1466               " (\"%.*s\", not \"%s\")\n", (int)iov[0].iov_len,
1467               (char *)iov[0].iov_base, Version);
1468    close(link_fd);
1469    while (niov--)
1470      free(iov[niov].iov_base);
1471    return;
1472  }
1473
1474  niov = 1;
1475  dl = iov2datalink(bundle, iov, &niov, sizeof iov / sizeof *iov, link_fd);
1476  if (dl) {
1477    bundle_DatalinkLinkin(bundle, dl);
1478    datalink_AuthOk(dl);
1479  } else
1480    close(link_fd);
1481
1482  free(iov[0].iov_base);
1483}
1484
1485void
1486bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun)
1487{
1488  char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int)], ack;
1489  struct cmsghdr *cmsg = (struct cmsghdr *)cmsgbuf;
1490  struct msghdr msg;
1491  struct iovec iov[SCATTER_SEGMENTS];
1492  int niov, link_fd, f, expect, newsid;
1493  pid_t newpid;
1494
1495  log_Printf(LogPHASE, "Transmitting datalink %s\n", dl->name);
1496
1497  bundle_LinkClosed(dl->bundle, dl);
1498  bundle_DatalinkLinkout(dl->bundle, dl);
1499
1500  /* Build our scatter/gather array */
1501  iov[0].iov_len = strlen(Version) + 1;
1502  iov[0].iov_base = strdup(Version);
1503  niov = 1;
1504
1505  read(s, &newpid, sizeof newpid);
1506  link_fd = datalink2iov(dl, iov, &niov, sizeof iov / sizeof *iov, newpid);
1507
1508  if (link_fd != -1) {
1509    memset(&msg, '\0', sizeof msg);
1510
1511    msg.msg_name = (caddr_t)sun;
1512    msg.msg_namelen = sizeof *sun;
1513    msg.msg_iov = iov;
1514    msg.msg_iovlen = niov;
1515
1516    cmsg->cmsg_len = sizeof cmsgbuf;
1517    cmsg->cmsg_level = SOL_SOCKET;
1518    cmsg->cmsg_type = SCM_RIGHTS;
1519    *(int *)CMSG_DATA(cmsg) = link_fd;
1520    msg.msg_control = cmsgbuf;
1521    msg.msg_controllen = sizeof cmsgbuf;
1522
1523    for (f = expect = 0; f < niov; f++)
1524      expect += iov[f].iov_len;
1525
1526    log_Printf(LogDEBUG, "Sending %d bytes in scatter/gather array\n", expect);
1527
1528    f = expect + SOCKET_OVERHEAD;
1529    setsockopt(s, SOL_SOCKET, SO_SNDBUF, &f, sizeof f);
1530    if (sendmsg(s, &msg, 0) == -1)
1531      log_Printf(LogERROR, "Failed sendmsg: %s\n", strerror(errno));
1532    /* We must get the ACK before closing the descriptor ! */
1533    read(s, &ack, 1);
1534
1535    newsid = tcgetpgrp(link_fd) == getpgrp();
1536    close(link_fd);
1537    if (newsid)
1538      bundle_setsid(dl->bundle, 1);
1539  }
1540  close(s);
1541
1542  while (niov--)
1543    free(iov[niov].iov_base);
1544}
1545
1546int
1547bundle_RenameDatalink(struct bundle *bundle, struct datalink *ndl,
1548                      const char *name)
1549{
1550  struct datalink *dl;
1551
1552  if (!strcasecmp(ndl->name, name))
1553    return 1;
1554
1555  for (dl = bundle->links; dl; dl = dl->next)
1556    if (!strcasecmp(dl->name, name))
1557      return 0;
1558
1559  datalink_Rename(ndl, name);
1560  return 1;
1561}
1562
1563int
1564bundle_SetMode(struct bundle *bundle, struct datalink *dl, int mode)
1565{
1566  int omode;
1567
1568  omode = dl->physical->type;
1569  if (omode == mode)
1570    return 1;
1571
1572  if (mode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO))
1573    /* First auto link */
1574    if (bundle->ncp.ipcp.peer_ip.s_addr == INADDR_ANY) {
1575      log_Printf(LogWARN, "You must `set ifaddr' or `open' before"
1576                 " changing mode to %s\n", mode2Nam(mode));
1577      return 0;
1578    }
1579
1580  if (!datalink_SetMode(dl, mode))
1581    return 0;
1582
1583  if (mode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO) &&
1584      bundle->phase != PHASE_NETWORK)
1585    /* First auto link, we need an interface */
1586    ipcp_InterfaceUp(&bundle->ncp.ipcp);
1587
1588  /* Regenerate phys_type and adjust autoload & idle timers */
1589  bundle_LinksRemoved(bundle);
1590
1591  return 1;
1592}
1593
1594void
1595bundle_setsid(struct bundle *bundle, int holdsession)
1596{
1597  /*
1598   * Lose the current session.  This means getting rid of our pid
1599   * too so that the tty device will really go away, and any getty
1600   * etc will be allowed to restart.
1601   */
1602  pid_t pid, orig;
1603  int fds[2];
1604  char done;
1605  struct datalink *dl;
1606
1607  orig = getpid();
1608  if (pipe(fds) == -1) {
1609    log_Printf(LogERROR, "pipe: %s\n", strerror(errno));
1610    return;
1611  }
1612  switch ((pid = fork())) {
1613    case -1:
1614      log_Printf(LogERROR, "fork: %s\n", strerror(errno));
1615      close(fds[0]);
1616      close(fds[1]);
1617      return;
1618    case 0:
1619      close(fds[0]);
1620      read(fds[1], &done, 1);		/* uu_locks are mine ! */
1621      close(fds[1]);
1622      if (pipe(fds) == -1) {
1623        log_Printf(LogERROR, "pipe(2): %s\n", strerror(errno));
1624        return;
1625      }
1626      switch ((pid = fork())) {
1627        case -1:
1628          log_Printf(LogERROR, "fork(2): %s\n", strerror(errno));
1629          close(fds[0]);
1630          close(fds[1]);
1631          return;
1632        case 0:
1633          close(fds[0]);
1634          bundle_LockTun(bundle);	/* update pid */
1635          read(fds[1], &done, 1);	/* uu_locks are mine ! */
1636          close(fds[1]);
1637          setsid();
1638          log_Printf(LogPHASE, "%d -> %d: %s session control\n",
1639                     (int)orig, (int)getpid(),
1640                     holdsession ? "Passed" : "Dropped");
1641          timer_InitService();
1642          break;
1643        default:
1644          close(fds[1]);
1645          /* Give away all our modem locks (to the final process) */
1646          for (dl = bundle->links; dl; dl = dl->next)
1647            if (dl->state != DATALINK_CLOSED)
1648              modem_ChangedPid(dl->physical, pid);
1649          write(fds[0], "!", 1);	/* done */
1650          close(fds[0]);
1651          exit(0);
1652          break;
1653      }
1654      break;
1655    default:
1656      close(fds[1]);
1657      /* Give away all our modem locks (to the intermediate process) */
1658      for (dl = bundle->links; dl; dl = dl->next)
1659        if (dl->state != DATALINK_CLOSED)
1660          modem_ChangedPid(dl->physical, pid);
1661      write(fds[0], "!", 1);	/* done */
1662      close(fds[0]);
1663      if (holdsession) {
1664        int fd, status;
1665
1666        timer_TermService();
1667        signal(SIGPIPE, SIG_DFL);
1668        signal(SIGALRM, SIG_DFL);
1669        signal(SIGHUP, SIG_DFL);
1670        signal(SIGTERM, SIG_DFL);
1671        signal(SIGINT, SIG_DFL);
1672        signal(SIGQUIT, SIG_DFL);
1673        for (fd = getdtablesize(); fd >= 0; fd--)
1674          close(fd);
1675        setuid(geteuid());
1676        /*
1677         * Reap the intermediate process.  As we're not exiting but the
1678         * intermediate is, we don't want it to become defunct.
1679         */
1680        waitpid(pid, &status, 0);
1681        /* Tweak our process arguments.... */
1682        bundle->argv[0] = "session owner";
1683        bundle->argv[1] = NULL;
1684        /*
1685         * Hang around for a HUP.  This should happen as soon as the
1686         * ppp that we passed our ctty descriptor to closes it.
1687         * NOTE: If this process dies, the passed descriptor becomes
1688         *       invalid and will give a select() error by setting one
1689         *       of the error fds, aborting the other ppp.  We don't
1690         *       want that to happen !
1691         */
1692        pause();
1693      }
1694      exit(0);
1695      break;
1696  }
1697}
1698
1699int
1700bundle_HighestState(struct bundle *bundle)
1701{
1702  struct datalink *dl;
1703  int result = DATALINK_CLOSED;
1704
1705  for (dl = bundle->links; dl; dl = dl->next)
1706    if (result < dl->state)
1707      result = dl->state;
1708
1709  return result;
1710}
1711