bundle.c revision 37061
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.21 1998/06/20 00:19:32 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 void
683bundle_DescriptorWrite(struct descriptor *d, struct bundle *bundle,
684                       const fd_set *fdset)
685{
686  struct datalink *dl;
687
688  /* This is not actually necessary as struct mpserver doesn't Write() */
689  if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
690    descriptor_Write(&bundle->ncp.mp.server.desc, bundle, fdset);
691
692  for (dl = bundle->links; dl; dl = dl->next)
693    if (descriptor_IsSet(&dl->desc, fdset))
694      descriptor_Write(&dl->desc, bundle, fdset);
695}
696
697void
698bundle_LockTun(struct bundle *bundle)
699{
700  FILE *lockfile;
701  char pidfile[MAXPATHLEN];
702
703  snprintf(pidfile, sizeof pidfile, "%stun%d.pid", _PATH_VARRUN, bundle->unit);
704  lockfile = ID0fopen(pidfile, "w");
705  if (lockfile != NULL) {
706    fprintf(lockfile, "%d\n", (int)getpid());
707    fclose(lockfile);
708  }
709#ifndef RELEASE_CRUNCH
710  else
711    log_Printf(LogERROR, "Warning: Can't create %s: %s\n",
712               pidfile, strerror(errno));
713#endif
714}
715
716static void
717bundle_UnlockTun(struct bundle *bundle)
718{
719  char pidfile[MAXPATHLEN];
720
721  snprintf(pidfile, sizeof pidfile, "%stun%d.pid", _PATH_VARRUN, bundle->unit);
722  ID0unlink(pidfile);
723}
724
725struct bundle *
726bundle_Create(const char *prefix, int type, const char **argv)
727{
728  int s, enoentcount, err;
729  struct ifreq ifrq;
730  static struct bundle bundle;		/* there can be only one */
731
732  if (bundle.ifp.Name != NULL) {	/* Already allocated ! */
733    log_Printf(LogALERT, "bundle_Create:  There's only one BUNDLE !\n");
734    return NULL;
735  }
736
737  err = ENOENT;
738  enoentcount = 0;
739  for (bundle.unit = 0; ; bundle.unit++) {
740    snprintf(bundle.dev.Name, sizeof bundle.dev.Name, "%s%d",
741             prefix, bundle.unit);
742    bundle.dev.fd = ID0open(bundle.dev.Name, O_RDWR);
743    if (bundle.dev.fd >= 0)
744      break;
745    else if (errno == ENXIO) {
746      err = errno;
747      break;
748    } else if (errno == ENOENT) {
749      if (++enoentcount > 2)
750	break;
751    } else
752      err = errno;
753  }
754
755  if (bundle.dev.fd < 0) {
756    log_Printf(LogWARN, "No available tunnel devices found (%s).\n",
757              strerror(err));
758    return NULL;
759  }
760
761  log_SetTun(bundle.unit);
762  bundle.argv = argv;
763
764  s = socket(AF_INET, SOCK_DGRAM, 0);
765  if (s < 0) {
766    log_Printf(LogERROR, "bundle_Create: socket(): %s\n", strerror(errno));
767    close(bundle.dev.fd);
768    return NULL;
769  }
770
771  bundle.ifp.Name = strrchr(bundle.dev.Name, '/');
772  if (bundle.ifp.Name == NULL)
773    bundle.ifp.Name = bundle.dev.Name;
774  else
775    bundle.ifp.Name++;
776
777  /*
778   * Now, bring up the interface.
779   */
780  memset(&ifrq, '\0', sizeof ifrq);
781  strncpy(ifrq.ifr_name, bundle.ifp.Name, sizeof ifrq.ifr_name - 1);
782  ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0';
783  if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
784    log_Printf(LogERROR, "bundle_Create: ioctl(SIOCGIFFLAGS): %s\n",
785	      strerror(errno));
786    close(s);
787    close(bundle.dev.fd);
788    bundle.ifp.Name = NULL;
789    return NULL;
790  }
791  ifrq.ifr_flags |= IFF_UP;
792  if (ID0ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
793    log_Printf(LogERROR, "bundle_Create: ioctl(SIOCSIFFLAGS): %s\n",
794	      strerror(errno));
795    close(s);
796    close(bundle.dev.fd);
797    bundle.ifp.Name = NULL;
798    return NULL;
799  }
800
801  close(s);
802
803  if ((bundle.ifp.Index = GetIfIndex(bundle.ifp.Name)) < 0) {
804    log_Printf(LogERROR, "Can't find interface index.\n");
805    close(bundle.dev.fd);
806    bundle.ifp.Name = NULL;
807    return NULL;
808  }
809  log_Printf(LogPHASE, "Using interface: %s\n", bundle.ifp.Name);
810
811  bundle.ifp.Speed = 0;
812
813  bundle.routing_seq = 0;
814  bundle.phase = PHASE_DEAD;
815  bundle.CleaningUp = 0;
816
817  bundle.fsm.LayerStart = bundle_LayerStart;
818  bundle.fsm.LayerUp = bundle_LayerUp;
819  bundle.fsm.LayerDown = bundle_LayerDown;
820  bundle.fsm.LayerFinish = bundle_LayerFinish;
821  bundle.fsm.object = &bundle;
822
823  bundle.cfg.idle_timeout = NCP_IDLE_TIMEOUT;
824  *bundle.cfg.auth.name = '\0';
825  *bundle.cfg.auth.key = '\0';
826  bundle.cfg.opt = OPT_SROUTES | OPT_IDCHECK | OPT_LOOPBACK |
827                   OPT_THROUGHPUT | OPT_UTMP;
828  *bundle.cfg.label = '\0';
829  bundle.cfg.mtu = DEF_MTU;
830  bundle.cfg.autoload.max.packets = 0;
831  bundle.cfg.autoload.max.timeout = 0;
832  bundle.cfg.autoload.min.packets = 0;
833  bundle.cfg.autoload.min.timeout = 0;
834  bundle.phys_type.all = type;
835  bundle.phys_type.open = 0;
836
837  bundle.links = datalink_Create("deflink", &bundle, type);
838  if (bundle.links == NULL) {
839    log_Printf(LogALERT, "Cannot create data link: %s\n", strerror(errno));
840    close(bundle.dev.fd);
841    bundle.ifp.Name = NULL;
842    return NULL;
843  }
844
845  bundle.desc.type = BUNDLE_DESCRIPTOR;
846  bundle.desc.UpdateSet = bundle_UpdateSet;
847  bundle.desc.IsSet = bundle_IsSet;
848  bundle.desc.Read = bundle_DescriptorRead;
849  bundle.desc.Write = bundle_DescriptorWrite;
850
851  mp_Init(&bundle.ncp.mp, &bundle);
852
853  /* Send over the first physical link by default */
854  ipcp_Init(&bundle.ncp.ipcp, &bundle, &bundle.links->physical->link,
855            &bundle.fsm);
856
857  memset(&bundle.filter, '\0', sizeof bundle.filter);
858  bundle.filter.in.fragok = bundle.filter.in.logok = 1;
859  bundle.filter.in.name = "IN";
860  bundle.filter.out.fragok = bundle.filter.out.logok = 1;
861  bundle.filter.out.name = "OUT";
862  bundle.filter.dial.name = "DIAL";
863  bundle.filter.dial.logok = 1;
864  bundle.filter.alive.name = "ALIVE";
865  bundle.filter.alive.logok = 1;
866  memset(&bundle.idle.timer, '\0', sizeof bundle.idle.timer);
867  bundle.idle.done = 0;
868  bundle.notify.fd = -1;
869  memset(&bundle.autoload.timer, '\0', sizeof bundle.autoload.timer);
870  bundle.autoload.done = 0;
871  bundle.autoload.running = 0;
872
873  /* Clean out any leftover crud */
874  bundle_CleanInterface(&bundle);
875
876  bundle_LockTun(&bundle);
877
878  return &bundle;
879}
880
881static void
882bundle_DownInterface(struct bundle *bundle)
883{
884  struct ifreq ifrq;
885  int s;
886
887  route_IfDelete(bundle, 1);
888
889  s = ID0socket(AF_INET, SOCK_DGRAM, 0);
890  if (s < 0) {
891    log_Printf(LogERROR, "bundle_DownInterface: socket: %s\n", strerror(errno));
892    return;
893  }
894
895  memset(&ifrq, '\0', sizeof ifrq);
896  strncpy(ifrq.ifr_name, bundle->ifp.Name, sizeof ifrq.ifr_name - 1);
897  ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0';
898  if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
899    log_Printf(LogERROR, "bundle_DownInterface: ioctl(SIOCGIFFLAGS): %s\n",
900       strerror(errno));
901    close(s);
902    return;
903  }
904  ifrq.ifr_flags &= ~IFF_UP;
905  if (ID0ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
906    log_Printf(LogERROR, "bundle_DownInterface: ioctl(SIOCSIFFLAGS): %s\n",
907       strerror(errno));
908    close(s);
909    return;
910  }
911  close(s);
912}
913
914void
915bundle_Destroy(struct bundle *bundle)
916{
917  struct datalink *dl;
918
919  /*
920   * Clean up the interface.  We don't need to timer_Stop()s, mp_Down(),
921   * ipcp_CleanInterface() and bundle_DownInterface() unless we're getting
922   * out under exceptional conditions such as a descriptor exception.
923   */
924  timer_Stop(&bundle->idle.timer);
925  timer_Stop(&bundle->autoload.timer);
926  mp_Down(&bundle->ncp.mp);
927  ipcp_CleanInterface(&bundle->ncp.ipcp);
928  bundle_DownInterface(bundle);
929
930  /* Again, these are all DATALINK_CLOSED unless we're abending */
931  dl = bundle->links;
932  while (dl)
933    dl = datalink_Destroy(dl);
934
935  close(bundle->dev.fd);
936  bundle_UnlockTun(bundle);
937
938  /* In case we never made PHASE_NETWORK */
939  bundle_Notify(bundle, EX_ERRDEAD);
940
941  bundle->ifp.Name = NULL;
942}
943
944struct rtmsg {
945  struct rt_msghdr m_rtm;
946  char m_space[64];
947};
948
949int
950bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst,
951                struct in_addr gateway, struct in_addr mask, int bang)
952{
953  struct rtmsg rtmes;
954  int s, nb, wb;
955  char *cp;
956  const char *cmdstr;
957  struct sockaddr_in rtdata;
958  int result = 1;
959
960  if (bang)
961    cmdstr = (cmd == RTM_ADD ? "Add!" : "Delete!");
962  else
963    cmdstr = (cmd == RTM_ADD ? "Add" : "Delete");
964  s = ID0socket(PF_ROUTE, SOCK_RAW, 0);
965  if (s < 0) {
966    log_Printf(LogERROR, "bundle_SetRoute: socket(): %s\n", strerror(errno));
967    return result;
968  }
969  memset(&rtmes, '\0', sizeof rtmes);
970  rtmes.m_rtm.rtm_version = RTM_VERSION;
971  rtmes.m_rtm.rtm_type = cmd;
972  rtmes.m_rtm.rtm_addrs = RTA_DST;
973  rtmes.m_rtm.rtm_seq = ++bundle->routing_seq;
974  rtmes.m_rtm.rtm_pid = getpid();
975  rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
976
977  memset(&rtdata, '\0', sizeof rtdata);
978  rtdata.sin_len = sizeof rtdata;
979  rtdata.sin_family = AF_INET;
980  rtdata.sin_port = 0;
981  rtdata.sin_addr = dst;
982
983  cp = rtmes.m_space;
984  memcpy(cp, &rtdata, rtdata.sin_len);
985  cp += rtdata.sin_len;
986  if (cmd == RTM_ADD) {
987    if (gateway.s_addr == INADDR_ANY) {
988      /* Add a route through the interface */
989      struct sockaddr_dl dl;
990      const char *iname;
991      int ilen;
992
993      iname = Index2Nam(bundle->ifp.Index);
994      ilen = strlen(iname);
995      dl.sdl_len = sizeof dl - sizeof dl.sdl_data + ilen;
996      dl.sdl_family = AF_LINK;
997      dl.sdl_index = bundle->ifp.Index;
998      dl.sdl_type = 0;
999      dl.sdl_nlen = ilen;
1000      dl.sdl_alen = 0;
1001      dl.sdl_slen = 0;
1002      strncpy(dl.sdl_data, iname, sizeof dl.sdl_data);
1003      memcpy(cp, &dl, dl.sdl_len);
1004      cp += dl.sdl_len;
1005      rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
1006    } else {
1007      rtdata.sin_addr = gateway;
1008      memcpy(cp, &rtdata, rtdata.sin_len);
1009      cp += rtdata.sin_len;
1010      rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
1011    }
1012  }
1013
1014  if (dst.s_addr == INADDR_ANY)
1015    mask.s_addr = INADDR_ANY;
1016
1017  if (cmd == RTM_ADD || dst.s_addr == INADDR_ANY) {
1018    rtdata.sin_addr = mask;
1019    memcpy(cp, &rtdata, rtdata.sin_len);
1020    cp += rtdata.sin_len;
1021    rtmes.m_rtm.rtm_addrs |= RTA_NETMASK;
1022  }
1023
1024  nb = cp - (char *) &rtmes;
1025  rtmes.m_rtm.rtm_msglen = nb;
1026  wb = ID0write(s, &rtmes, nb);
1027  if (wb < 0) {
1028    log_Printf(LogTCPIP, "bundle_SetRoute failure:\n");
1029    log_Printf(LogTCPIP, "bundle_SetRoute:  Cmd = %s\n", cmdstr);
1030    log_Printf(LogTCPIP, "bundle_SetRoute:  Dst = %s\n", inet_ntoa(dst));
1031    log_Printf(LogTCPIP, "bundle_SetRoute:  Gateway = %s\n", inet_ntoa(gateway));
1032    log_Printf(LogTCPIP, "bundle_SetRoute:  Mask = %s\n", inet_ntoa(mask));
1033failed:
1034    if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST ||
1035                           (rtmes.m_rtm.rtm_errno == 0 && errno == EEXIST))) {
1036      if (!bang) {
1037        log_Printf(LogWARN, "Add route failed: %s already exists\n",
1038                  inet_ntoa(dst));
1039        result = 0;	/* Don't add to our dynamic list */
1040      } else {
1041        rtmes.m_rtm.rtm_type = cmd = RTM_CHANGE;
1042        if ((wb = ID0write(s, &rtmes, nb)) < 0)
1043          goto failed;
1044      }
1045    } else if (cmd == RTM_DELETE &&
1046             (rtmes.m_rtm.rtm_errno == ESRCH ||
1047              (rtmes.m_rtm.rtm_errno == 0 && errno == ESRCH))) {
1048      if (!bang)
1049        log_Printf(LogWARN, "Del route failed: %s: Non-existent\n",
1050                  inet_ntoa(dst));
1051    } else if (rtmes.m_rtm.rtm_errno == 0)
1052      log_Printf(LogWARN, "%s route failed: %s: errno: %s\n", cmdstr,
1053                inet_ntoa(dst), strerror(errno));
1054    else
1055      log_Printf(LogWARN, "%s route failed: %s: %s\n",
1056		cmdstr, inet_ntoa(dst), strerror(rtmes.m_rtm.rtm_errno));
1057  }
1058  log_Printf(LogDEBUG, "wrote %d: cmd = %s, dst = %x, gateway = %x\n",
1059            wb, cmdstr, (unsigned)dst.s_addr, (unsigned)gateway.s_addr);
1060  close(s);
1061
1062  return result;
1063}
1064
1065void
1066bundle_LinkClosed(struct bundle *bundle, struct datalink *dl)
1067{
1068  /*
1069   * Our datalink has closed.
1070   * CleanDatalinks() (called from DoLoop()) will remove closed
1071   * BACKGROUND and DIRECT links.
1072   * If it's the last data link, enter phase DEAD.
1073   *
1074   * NOTE: dl may not be in our list (bundle_SendDatalink()) !
1075   */
1076
1077  struct datalink *odl;
1078  int other_links;
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)
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 (dl->state == DATALINK_CLOSED && (mask & dl->physical->type)) {
1109        datalink_Up(dl, 1, 1);
1110        if (mask == PHYS_AUTO)
1111          /* Only one AUTO link at a time (see the AutoLoad timer) */
1112          break;
1113      }
1114      if (name != NULL)
1115        break;
1116    }
1117}
1118
1119struct datalink *
1120bundle2datalink(struct bundle *bundle, const char *name)
1121{
1122  struct datalink *dl;
1123
1124  if (name != NULL) {
1125    for (dl = bundle->links; dl; dl = dl->next)
1126      if (!strcasecmp(dl->name, name))
1127        return dl;
1128  } else if (bundle->links && !bundle->links->next)
1129    return bundle->links;
1130
1131  return NULL;
1132}
1133
1134int
1135bundle_FillQueues(struct bundle *bundle)
1136{
1137  int total;
1138
1139  if (bundle->ncp.mp.active)
1140    total = mp_FillQueues(bundle);
1141  else {
1142    struct datalink *dl;
1143    int add;
1144
1145    for (total = 0, dl = bundle->links; dl; dl = dl->next)
1146      if (dl->state == DATALINK_OPEN) {
1147        add = link_QueueLen(&dl->physical->link);
1148        if (add == 0 && dl->physical->out == NULL)
1149          add = ip_FlushPacket(&dl->physical->link, bundle);
1150        total += add;
1151      }
1152  }
1153
1154  return total + ip_QueueLen();
1155}
1156
1157int
1158bundle_ShowLinks(struct cmdargs const *arg)
1159{
1160  struct datalink *dl;
1161
1162  for (dl = arg->bundle->links; dl; dl = dl->next) {
1163    prompt_Printf(arg->prompt, "Name: %s [%s, %s]",
1164                  dl->name, mode2Nam(dl->physical->type), datalink_State(dl));
1165    if (dl->physical->link.throughput.rolling && dl->state == DATALINK_OPEN)
1166      prompt_Printf(arg->prompt, " weight %d, %d bytes/sec",
1167                    dl->mp.weight,
1168                    dl->physical->link.throughput.OctetsPerSecond);
1169    prompt_Printf(arg->prompt, "\n");
1170  }
1171
1172  return 0;
1173}
1174
1175static const char *
1176optval(struct bundle *bundle, int bit)
1177{
1178  return (bundle->cfg.opt & bit) ? "enabled" : "disabled";
1179}
1180
1181int
1182bundle_ShowStatus(struct cmdargs const *arg)
1183{
1184  int remaining;
1185
1186  prompt_Printf(arg->prompt, "Phase %s\n", bundle_PhaseName(arg->bundle));
1187  prompt_Printf(arg->prompt, " Device:        %s\n", arg->bundle->dev.Name);
1188  prompt_Printf(arg->prompt, " Interface:     %s @ %lubps\n",
1189                arg->bundle->ifp.Name, arg->bundle->ifp.Speed);
1190
1191  prompt_Printf(arg->prompt, "\nDefaults:\n");
1192  prompt_Printf(arg->prompt, " Label:         %s\n", arg->bundle->cfg.label);
1193  prompt_Printf(arg->prompt, " Auth name:     %s\n",
1194                arg->bundle->cfg.auth.name);
1195  prompt_Printf(arg->prompt, " Auto Load:     Up after %ds of >= %d packets\n",
1196                arg->bundle->cfg.autoload.max.timeout,
1197                arg->bundle->cfg.autoload.max.packets);
1198  prompt_Printf(arg->prompt, "                Down after %ds of <= %d"
1199                " packets\n", arg->bundle->cfg.autoload.min.timeout,
1200                arg->bundle->cfg.autoload.min.packets);
1201  if (arg->bundle->autoload.timer.state == TIMER_RUNNING)
1202    prompt_Printf(arg->prompt, "                %ds remaining 'till "
1203                  "a link comes %s\n",
1204                  bundle_RemainingAutoLoadTime(arg->bundle),
1205                  arg->bundle->autoload.comingup ? "up" : "down");
1206  else
1207    prompt_Printf(arg->prompt, "                %srunning with %d"
1208                  " packets queued\n", arg->bundle->autoload.running ?
1209                  "" : "not ", ip_QueueLen());
1210
1211  prompt_Printf(arg->prompt, " Idle Timer:    ");
1212  if (arg->bundle->cfg.idle_timeout) {
1213    prompt_Printf(arg->prompt, "%ds", arg->bundle->cfg.idle_timeout);
1214    remaining = bundle_RemainingIdleTime(arg->bundle);
1215    if (remaining != -1)
1216      prompt_Printf(arg->prompt, " (%ds remaining)", remaining);
1217    prompt_Printf(arg->prompt, "\n");
1218  } else
1219    prompt_Printf(arg->prompt, "disabled\n");
1220  prompt_Printf(arg->prompt, " MTU:           ");
1221  if (arg->bundle->cfg.mtu)
1222    prompt_Printf(arg->prompt, "%d\n", arg->bundle->cfg.mtu);
1223  else
1224    prompt_Printf(arg->prompt, "unspecified\n");
1225
1226  prompt_Printf(arg->prompt, " Sticky Routes: %s\n",
1227                optval(arg->bundle, OPT_SROUTES));
1228  prompt_Printf(arg->prompt, " ID check:      %s\n",
1229                optval(arg->bundle, OPT_IDCHECK));
1230  prompt_Printf(arg->prompt, " Loopback:      %s\n",
1231                optval(arg->bundle, OPT_LOOPBACK));
1232  prompt_Printf(arg->prompt, " PasswdAuth:    %s\n",
1233                optval(arg->bundle, OPT_PASSWDAUTH));
1234  prompt_Printf(arg->prompt, " Proxy:         %s\n",
1235                optval(arg->bundle, OPT_PROXY));
1236  prompt_Printf(arg->prompt, " Throughput:    %s\n",
1237                optval(arg->bundle, OPT_THROUGHPUT));
1238  prompt_Printf(arg->prompt, " Utmp Logging:  %s\n",
1239                optval(arg->bundle, OPT_UTMP));
1240
1241  return 0;
1242}
1243
1244static void
1245bundle_IdleTimeout(void *v)
1246{
1247  struct bundle *bundle = (struct bundle *)v;
1248
1249  log_Printf(LogPHASE, "Idle timer expired.\n");
1250  bundle_StopIdleTimer(bundle);
1251  bundle_Close(bundle, NULL, CLOSE_STAYDOWN);
1252}
1253
1254/*
1255 *  Start Idle timer. If timeout is reached, we call bundle_Close() to
1256 *  close LCP and link.
1257 */
1258void
1259bundle_StartIdleTimer(struct bundle *bundle)
1260{
1261  timer_Stop(&bundle->idle.timer);
1262  if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) !=
1263      bundle->phys_type.open && bundle->cfg.idle_timeout) {
1264    bundle->idle.timer.func = bundle_IdleTimeout;
1265    bundle->idle.timer.name = "idle";
1266    bundle->idle.timer.load = bundle->cfg.idle_timeout * SECTICKS;
1267    bundle->idle.timer.arg = bundle;
1268    timer_Start(&bundle->idle.timer);
1269    bundle->idle.done = time(NULL) + bundle->cfg.idle_timeout;
1270  }
1271}
1272
1273void
1274bundle_SetIdleTimer(struct bundle *bundle, int value)
1275{
1276  bundle->cfg.idle_timeout = value;
1277  if (bundle_LinkIsUp(bundle))
1278    bundle_StartIdleTimer(bundle);
1279}
1280
1281void
1282bundle_StopIdleTimer(struct bundle *bundle)
1283{
1284  timer_Stop(&bundle->idle.timer);
1285  bundle->idle.done = 0;
1286}
1287
1288static int
1289bundle_RemainingIdleTime(struct bundle *bundle)
1290{
1291  if (bundle->idle.done)
1292    return bundle->idle.done - time(NULL);
1293  return -1;
1294}
1295
1296int
1297bundle_IsDead(struct bundle *bundle)
1298{
1299  return !bundle->links || (bundle->phase == PHASE_DEAD && bundle->CleaningUp);
1300}
1301
1302static struct datalink *
1303bundle_DatalinkLinkout(struct bundle *bundle, struct datalink *dl)
1304{
1305  struct datalink **dlp;
1306
1307  for (dlp = &bundle->links; *dlp; dlp = &(*dlp)->next)
1308    if (*dlp == dl) {
1309      *dlp = dl->next;
1310      dl->next = NULL;
1311      bundle_LinksRemoved(bundle);
1312      return dl;
1313    }
1314
1315  return NULL;
1316}
1317
1318static void
1319bundle_DatalinkLinkin(struct bundle *bundle, struct datalink *dl)
1320{
1321  struct datalink **dlp = &bundle->links;
1322
1323  while (*dlp)
1324    dlp = &(*dlp)->next;
1325
1326  *dlp = dl;
1327  dl->next = NULL;
1328
1329  bundle_LinkAdded(bundle, dl);
1330}
1331
1332void
1333bundle_CleanDatalinks(struct bundle *bundle)
1334{
1335  struct datalink **dlp = &bundle->links;
1336  int found = 0;
1337
1338  while (*dlp)
1339    if ((*dlp)->state == DATALINK_CLOSED &&
1340        (*dlp)->physical->type & (PHYS_DIRECT|PHYS_BACKGROUND)) {
1341      *dlp = datalink_Destroy(*dlp);
1342      found++;
1343    } else
1344      dlp = &(*dlp)->next;
1345
1346  if (found)
1347    bundle_LinksRemoved(bundle);
1348}
1349
1350int
1351bundle_DatalinkClone(struct bundle *bundle, struct datalink *dl,
1352                     const char *name)
1353{
1354  if (bundle2datalink(bundle, name)) {
1355    log_Printf(LogWARN, "Clone: %s: name already exists\n", name);
1356    return 0;
1357  }
1358
1359  bundle_DatalinkLinkin(bundle, datalink_Clone(dl, name));
1360  return 1;
1361}
1362
1363void
1364bundle_DatalinkRemove(struct bundle *bundle, struct datalink *dl)
1365{
1366  dl = bundle_DatalinkLinkout(bundle, dl);
1367  if (dl)
1368    datalink_Destroy(dl);
1369}
1370
1371void
1372bundle_SetLabel(struct bundle *bundle, const char *label)
1373{
1374  if (label)
1375    strncpy(bundle->cfg.label, label, sizeof bundle->cfg.label - 1);
1376  else
1377    *bundle->cfg.label = '\0';
1378}
1379
1380const char *
1381bundle_GetLabel(struct bundle *bundle)
1382{
1383  return *bundle->cfg.label ? bundle->cfg.label : NULL;
1384}
1385
1386void
1387bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun)
1388{
1389  char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int)];
1390  struct cmsghdr *cmsg = (struct cmsghdr *)cmsgbuf;
1391  struct msghdr msg;
1392  struct iovec iov[SCATTER_SEGMENTS];
1393  struct datalink *dl;
1394  int niov, link_fd, expect, f;
1395  pid_t pid;
1396
1397  log_Printf(LogPHASE, "Receiving datalink\n");
1398
1399  /* Create our scatter/gather array */
1400  niov = 1;
1401  iov[0].iov_len = strlen(Version) + 1;
1402  iov[0].iov_base = (char *)malloc(iov[0].iov_len);
1403  if (datalink2iov(NULL, iov, &niov, sizeof iov / sizeof *iov, 0) == -1) {
1404    close(s);
1405    return;
1406  }
1407
1408  pid = getpid();
1409  write(s, &pid, sizeof pid);
1410
1411  for (f = expect = 0; f < niov; f++)
1412    expect += iov[f].iov_len;
1413
1414  /* Set up our message */
1415  cmsg->cmsg_len = sizeof cmsgbuf;
1416  cmsg->cmsg_level = SOL_SOCKET;
1417  cmsg->cmsg_type = 0;
1418
1419  memset(&msg, '\0', sizeof msg);
1420  msg.msg_name = (caddr_t)sun;
1421  msg.msg_namelen = sizeof *sun;
1422  msg.msg_iov = iov;
1423  msg.msg_iovlen = niov;
1424  msg.msg_control = cmsgbuf;
1425  msg.msg_controllen = sizeof cmsgbuf;
1426
1427  log_Printf(LogDEBUG, "Expecting %d scatter/gather bytes\n", expect);
1428  f = expect + 100;
1429  setsockopt(s, SOL_SOCKET, SO_RCVBUF, &f, sizeof f);
1430  if ((f = recvmsg(s, &msg, MSG_WAITALL)) != expect) {
1431    if (f == -1)
1432      log_Printf(LogERROR, "Failed recvmsg: %s\n", strerror(errno));
1433    else
1434      log_Printf(LogERROR, "Failed recvmsg: Got %d, not %d\n", f, expect);
1435    while (niov--)
1436      free(iov[niov].iov_base);
1437    close(s);
1438    return;
1439  }
1440
1441  write(s, "!", 1);	/* ACK */
1442  close(s);
1443
1444  if (cmsg->cmsg_type != SCM_RIGHTS) {
1445    log_Printf(LogERROR, "Recvmsg: no descriptor received !\n");
1446    while (niov--)
1447      free(iov[niov].iov_base);
1448    return;
1449  }
1450
1451  /* We've successfully received an open file descriptor through our socket */
1452  log_Printf(LogDEBUG, "Receiving device descriptor\n");
1453  link_fd = *(int *)CMSG_DATA(cmsg);
1454
1455  if (strncmp(Version, iov[0].iov_base, iov[0].iov_len)) {
1456    log_Printf(LogWARN, "Cannot receive datalink, incorrect version"
1457               " (\"%.*s\", not \"%s\")\n", (int)iov[0].iov_len,
1458               iov[0].iov_base, Version);
1459    close(link_fd);
1460    while (niov--)
1461      free(iov[niov].iov_base);
1462    return;
1463  }
1464
1465  niov = 1;
1466  dl = iov2datalink(bundle, iov, &niov, sizeof iov / sizeof *iov, link_fd);
1467  if (dl) {
1468    bundle_DatalinkLinkin(bundle, dl);
1469    datalink_AuthOk(dl);
1470  } else
1471    close(link_fd);
1472
1473  free(iov[0].iov_base);
1474}
1475
1476void
1477bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun)
1478{
1479  char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int)], ack;
1480  struct cmsghdr *cmsg = (struct cmsghdr *)cmsgbuf;
1481  struct msghdr msg;
1482  struct iovec iov[SCATTER_SEGMENTS];
1483  int niov, link_fd, f, expect, newsid;
1484  pid_t newpid;
1485
1486  log_Printf(LogPHASE, "Transmitting datalink %s\n", dl->name);
1487
1488  bundle_LinkClosed(dl->bundle, dl);
1489  bundle_DatalinkLinkout(dl->bundle, dl);
1490
1491  /* Build our scatter/gather array */
1492  iov[0].iov_len = strlen(Version) + 1;
1493  iov[0].iov_base = strdup(Version);
1494  niov = 1;
1495
1496  read(s, &newpid, sizeof newpid);
1497  link_fd = datalink2iov(dl, iov, &niov, sizeof iov / sizeof *iov, newpid);
1498
1499  if (link_fd != -1) {
1500    memset(&msg, '\0', sizeof msg);
1501
1502    msg.msg_name = (caddr_t)sun;
1503    msg.msg_namelen = sizeof *sun;
1504    msg.msg_iov = iov;
1505    msg.msg_iovlen = niov;
1506
1507    cmsg->cmsg_len = sizeof cmsgbuf;
1508    cmsg->cmsg_level = SOL_SOCKET;
1509    cmsg->cmsg_type = SCM_RIGHTS;
1510    *(int *)CMSG_DATA(cmsg) = link_fd;
1511    msg.msg_control = cmsgbuf;
1512    msg.msg_controllen = sizeof cmsgbuf;
1513
1514    for (f = expect = 0; f < niov; f++)
1515      expect += iov[f].iov_len;
1516
1517    log_Printf(LogDEBUG, "Sending %d bytes in scatter/gather array\n", expect);
1518
1519    f = expect + SOCKET_OVERHEAD;
1520    setsockopt(s, SOL_SOCKET, SO_SNDBUF, &f, sizeof f);
1521    if (sendmsg(s, &msg, 0) == -1)
1522      log_Printf(LogERROR, "Failed sendmsg: %s\n", strerror(errno));
1523    /* We must get the ACK before closing the descriptor ! */
1524    read(s, &ack, 1);
1525
1526    newsid = tcgetpgrp(link_fd) == getpgrp();
1527    close(link_fd);
1528    if (newsid)
1529      bundle_setsid(dl->bundle, 1);
1530  }
1531  close(s);
1532
1533  while (niov--)
1534    free(iov[niov].iov_base);
1535}
1536
1537int
1538bundle_RenameDatalink(struct bundle *bundle, struct datalink *ndl,
1539                      const char *name)
1540{
1541  struct datalink *dl;
1542
1543  if (!strcasecmp(ndl->name, name))
1544    return 1;
1545
1546  for (dl = bundle->links; dl; dl = dl->next)
1547    if (!strcasecmp(dl->name, name))
1548      return 0;
1549
1550  datalink_Rename(ndl, name);
1551  return 1;
1552}
1553
1554int
1555bundle_SetMode(struct bundle *bundle, struct datalink *dl, int mode)
1556{
1557  int omode;
1558
1559  omode = dl->physical->type;
1560  if (omode == mode)
1561    return 1;
1562
1563  if (mode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO))
1564    /* First auto link */
1565    if (bundle->ncp.ipcp.peer_ip.s_addr == INADDR_ANY) {
1566      log_Printf(LogWARN, "You must `set ifaddr' or `open' before"
1567                 " changing mode to %s\n", mode2Nam(mode));
1568      return 0;
1569    }
1570
1571  if (!datalink_SetMode(dl, mode))
1572    return 0;
1573
1574  if (mode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO) &&
1575      bundle->phase != PHASE_NETWORK)
1576    /* First auto link, we need an interface */
1577    ipcp_InterfaceUp(&bundle->ncp.ipcp);
1578
1579  /* Regenerate phys_type and adjust autoload & idle timers */
1580  bundle_LinksRemoved(bundle);
1581
1582  if (omode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO) &&
1583      bundle->phase != PHASE_NETWORK)
1584    /* No auto links left */
1585    ipcp_CleanInterface(&bundle->ncp.ipcp);
1586
1587  return 1;
1588}
1589
1590void
1591bundle_setsid(struct bundle *bundle, int holdsession)
1592{
1593  /*
1594   * Lose the current session.  This means getting rid of our pid
1595   * too so that the tty device will really go away, and any getty
1596   * etc will be allowed to restart.
1597   */
1598  pid_t pid, orig;
1599  int fds[2];
1600  char done;
1601  struct datalink *dl;
1602
1603  orig = getpid();
1604  if (pipe(fds) == -1) {
1605    log_Printf(LogERROR, "pipe: %s\n", strerror(errno));
1606    return;
1607  }
1608  switch ((pid = fork())) {
1609    case -1:
1610      log_Printf(LogERROR, "fork: %s\n", strerror(errno));
1611      close(fds[0]);
1612      close(fds[1]);
1613      return;
1614    case 0:
1615      close(fds[0]);
1616      read(fds[1], &done, 1);		/* uu_locks are mine ! */
1617      close(fds[1]);
1618      if (pipe(fds) == -1) {
1619        log_Printf(LogERROR, "pipe(2): %s\n", strerror(errno));
1620        return;
1621      }
1622      switch ((pid = fork())) {
1623        case -1:
1624          log_Printf(LogERROR, "fork(2): %s\n", strerror(errno));
1625          close(fds[0]);
1626          close(fds[1]);
1627          return;
1628        case 0:
1629          close(fds[0]);
1630          bundle_LockTun(bundle);	/* update pid */
1631          read(fds[1], &done, 1);	/* uu_locks are mine ! */
1632          close(fds[1]);
1633          setsid();
1634          log_Printf(LogPHASE, "%d -> %d: %s session control\n",
1635                     (int)orig, (int)getpid(),
1636                     holdsession ? "Passed" : "Dropped");
1637          timer_InitService();
1638          break;
1639        default:
1640          close(fds[1]);
1641          /* Give away all our modem locks (to the final process) */
1642          for (dl = bundle->links; dl; dl = dl->next)
1643            if (dl->state != DATALINK_CLOSED)
1644              modem_ChangedPid(dl->physical, pid);
1645          write(fds[0], "!", 1);	/* done */
1646          close(fds[0]);
1647          exit(0);
1648          break;
1649      }
1650      break;
1651    default:
1652      close(fds[1]);
1653      /* Give away all our modem locks (to the intermediate process) */
1654      for (dl = bundle->links; dl; dl = dl->next)
1655        if (dl->state != DATALINK_CLOSED)
1656          modem_ChangedPid(dl->physical, pid);
1657      write(fds[0], "!", 1);	/* done */
1658      close(fds[0]);
1659      if (holdsession) {
1660        int fd, status;
1661
1662        timer_TermService();
1663        signal(SIGPIPE, SIG_DFL);
1664        signal(SIGALRM, SIG_DFL);
1665        signal(SIGHUP, SIG_DFL);
1666        signal(SIGTERM, SIG_DFL);
1667        signal(SIGINT, SIG_DFL);
1668        signal(SIGQUIT, SIG_DFL);
1669        for (fd = getdtablesize(); fd >= 0; fd--)
1670          close(fd);
1671        setuid(geteuid());
1672        /*
1673         * Reap the intermediate process.  As we're not exiting but the
1674         * intermediate is, we don't want it to become defunct.
1675         */
1676        waitpid(pid, &status, 0);
1677        /* Tweak our process arguments.... */
1678        bundle->argv[0] = "session owner";
1679        bundle->argv[1] = NULL;
1680        /*
1681         * Hang around for a HUP.  This should happen as soon as the
1682         * ppp that we passed our ctty descriptor to closes it.
1683         * NOTE: If this process dies, the passed descriptor becomes
1684         *       invalid and will give a select() error by setting one
1685         *       of the error fds, aborting the other ppp.  We don't
1686         *       want that to happen !
1687         */
1688        pause();
1689      }
1690      exit(0);
1691      break;
1692  }
1693}
1694