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