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