Deleted Added
full compact
bundle.c (59070) bundle.c (59084)
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 *
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 * $FreeBSD: head/usr.sbin/ppp/bundle.c 59070 2000-04-06 10:03:48Z brian $
26 * $FreeBSD: head/usr.sbin/ppp/bundle.c 59084 2000-04-07 23:46:14Z brian $
27 */
28
29#include <sys/param.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <net/if.h>
33#include <net/if_tun.h> /* For TUNS* ioctls */
34#include <arpa/inet.h>
35#include <net/route.h>
36#include <netinet/in_systm.h>
37#include <netinet/ip.h>
38#include <sys/un.h>
39
40#include <errno.h>
41#include <fcntl.h>
42#ifdef __OpenBSD__
43#include <util.h>
44#else
45#include <libutil.h>
46#endif
47#include <paths.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <sys/uio.h>
52#include <sys/wait.h>
53#if defined(__FreeBSD__) && !defined(NOKLDLOAD)
54#include <sys/linker.h>
55#include <sys/module.h>
56#endif
57#include <termios.h>
58#include <unistd.h>
59
60#include "layer.h"
61#include "defs.h"
62#include "command.h"
63#include "mbuf.h"
64#include "log.h"
65#include "id.h"
66#include "timer.h"
67#include "fsm.h"
68#include "iplist.h"
69#include "lqr.h"
70#include "hdlc.h"
71#include "throughput.h"
72#include "slcompress.h"
73#include "ipcp.h"
74#include "filter.h"
75#include "descriptor.h"
76#include "route.h"
77#include "lcp.h"
78#include "ccp.h"
79#include "link.h"
80#include "mp.h"
81#ifndef NORADIUS
82#include "radius.h"
83#endif
84#include "bundle.h"
85#include "async.h"
86#include "physical.h"
87#include "auth.h"
88#include "proto.h"
89#include "chap.h"
90#include "tun.h"
91#include "prompt.h"
92#include "chat.h"
93#include "cbcp.h"
94#include "datalink.h"
95#include "ip.h"
96#include "iface.h"
97
98#define SCATTER_SEGMENTS 6 /* version, datalink, name, physical,
99 throughput, device */
100
101#define SEND_MAXFD 3 /* Max file descriptors passed through
102 the local domain socket */
103
104static int bundle_RemainingIdleTime(struct bundle *);
105
106static const char * const PhaseNames[] = {
107 "Dead", "Establish", "Authenticate", "Network", "Terminate"
108};
109
110const char *
111bundle_PhaseName(struct bundle *bundle)
112{
113 return bundle->phase <= PHASE_TERMINATE ?
114 PhaseNames[bundle->phase] : "unknown";
115}
116
117void
118bundle_NewPhase(struct bundle *bundle, u_int new)
119{
120 if (new == bundle->phase)
121 return;
122
123 if (new <= PHASE_TERMINATE)
124 log_Printf(LogPHASE, "bundle: %s\n", PhaseNames[new]);
125
126 switch (new) {
127 case PHASE_DEAD:
128 log_DisplayPrompts();
129 bundle->phase = new;
130 break;
131
132 case PHASE_ESTABLISH:
133 bundle->phase = new;
134 break;
135
136 case PHASE_AUTHENTICATE:
137 bundle->phase = new;
138 log_DisplayPrompts();
139 break;
140
141 case PHASE_NETWORK:
142 fsm_Up(&bundle->ncp.ipcp.fsm);
143 fsm_Open(&bundle->ncp.ipcp.fsm);
144 bundle->phase = new;
145 log_DisplayPrompts();
146 break;
147
148 case PHASE_TERMINATE:
149 bundle->phase = new;
150 mp_Down(&bundle->ncp.mp);
151 log_DisplayPrompts();
152 break;
153 }
154}
155
156static void
157bundle_LayerStart(void *v, struct fsm *fp)
158{
159 /* The given FSM is about to start up ! */
160}
161
162
27 */
28
29#include <sys/param.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <net/if.h>
33#include <net/if_tun.h> /* For TUNS* ioctls */
34#include <arpa/inet.h>
35#include <net/route.h>
36#include <netinet/in_systm.h>
37#include <netinet/ip.h>
38#include <sys/un.h>
39
40#include <errno.h>
41#include <fcntl.h>
42#ifdef __OpenBSD__
43#include <util.h>
44#else
45#include <libutil.h>
46#endif
47#include <paths.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <sys/uio.h>
52#include <sys/wait.h>
53#if defined(__FreeBSD__) && !defined(NOKLDLOAD)
54#include <sys/linker.h>
55#include <sys/module.h>
56#endif
57#include <termios.h>
58#include <unistd.h>
59
60#include "layer.h"
61#include "defs.h"
62#include "command.h"
63#include "mbuf.h"
64#include "log.h"
65#include "id.h"
66#include "timer.h"
67#include "fsm.h"
68#include "iplist.h"
69#include "lqr.h"
70#include "hdlc.h"
71#include "throughput.h"
72#include "slcompress.h"
73#include "ipcp.h"
74#include "filter.h"
75#include "descriptor.h"
76#include "route.h"
77#include "lcp.h"
78#include "ccp.h"
79#include "link.h"
80#include "mp.h"
81#ifndef NORADIUS
82#include "radius.h"
83#endif
84#include "bundle.h"
85#include "async.h"
86#include "physical.h"
87#include "auth.h"
88#include "proto.h"
89#include "chap.h"
90#include "tun.h"
91#include "prompt.h"
92#include "chat.h"
93#include "cbcp.h"
94#include "datalink.h"
95#include "ip.h"
96#include "iface.h"
97
98#define SCATTER_SEGMENTS 6 /* version, datalink, name, physical,
99 throughput, device */
100
101#define SEND_MAXFD 3 /* Max file descriptors passed through
102 the local domain socket */
103
104static int bundle_RemainingIdleTime(struct bundle *);
105
106static const char * const PhaseNames[] = {
107 "Dead", "Establish", "Authenticate", "Network", "Terminate"
108};
109
110const char *
111bundle_PhaseName(struct bundle *bundle)
112{
113 return bundle->phase <= PHASE_TERMINATE ?
114 PhaseNames[bundle->phase] : "unknown";
115}
116
117void
118bundle_NewPhase(struct bundle *bundle, u_int new)
119{
120 if (new == bundle->phase)
121 return;
122
123 if (new <= PHASE_TERMINATE)
124 log_Printf(LogPHASE, "bundle: %s\n", PhaseNames[new]);
125
126 switch (new) {
127 case PHASE_DEAD:
128 log_DisplayPrompts();
129 bundle->phase = new;
130 break;
131
132 case PHASE_ESTABLISH:
133 bundle->phase = new;
134 break;
135
136 case PHASE_AUTHENTICATE:
137 bundle->phase = new;
138 log_DisplayPrompts();
139 break;
140
141 case PHASE_NETWORK:
142 fsm_Up(&bundle->ncp.ipcp.fsm);
143 fsm_Open(&bundle->ncp.ipcp.fsm);
144 bundle->phase = new;
145 log_DisplayPrompts();
146 break;
147
148 case PHASE_TERMINATE:
149 bundle->phase = new;
150 mp_Down(&bundle->ncp.mp);
151 log_DisplayPrompts();
152 break;
153 }
154}
155
156static void
157bundle_LayerStart(void *v, struct fsm *fp)
158{
159 /* The given FSM is about to start up ! */
160}
161
162
163static void
163void
164bundle_Notify(struct bundle *bundle, char c)
165{
166 if (bundle->notify.fd != -1) {
164bundle_Notify(struct bundle *bundle, char c)
165{
166 if (bundle->notify.fd != -1) {
167 if (write(bundle->notify.fd, &c, 1) == 1)
168 log_Printf(LogPHASE, "Parent notified of %s\n",
169 c == EX_NORMAL ? "success" : "failure");
167 int ret;
168
169 ret = write(bundle->notify.fd, &c, 1);
170 if (c != EX_REDIAL && c != EX_RECONNECT) {
171 if (ret == 1)
172 log_Printf(LogCHAT, "Parent notified of %s\n",
173 c == EX_NORMAL ? "success" : "failure");
174 else
175 log_Printf(LogERROR, "Failed to notify parent of success\n");
176 close(bundle->notify.fd);
177 bundle->notify.fd = -1;
178 } else if (ret == 1)
179 log_Printf(LogCHAT, "Parent notified of %s\n", ex_desc(c));
170 else
180 else
171 log_Printf(LogPHASE, "Failed to notify parent of success.\n");
172 close(bundle->notify.fd);
173 bundle->notify.fd = -1;
181 log_Printf(LogERROR, "Failed to notify parent of %s\n", ex_desc(c));
174 }
175}
176
177static void
178bundle_ClearQueues(void *v)
179{
180 struct bundle *bundle = (struct bundle *)v;
181 struct datalink *dl;
182
183 log_Printf(LogPHASE, "Clearing choked output queue\n");
184 timer_Stop(&bundle->choked.timer);
185
186 /*
187 * Emergency time:
188 *
189 * We've had a full queue for PACKET_DEL_SECS seconds without being
190 * able to get rid of any of the packets. We've probably given up
191 * on the redials at this point, and the queued data has almost
192 * definitely been timed out by the layer above. As this is preventing
193 * us from reading the TUN_NAME device (we don't want to buffer stuff
194 * indefinitely), we may as well nuke this data and start with a clean
195 * slate !
196 *
197 * Unfortunately, this has the side effect of shafting any compression
198 * dictionaries in use (causing the relevant RESET_REQ/RESET_ACK).
199 */
200
201 ip_DeleteQueue(&bundle->ncp.ipcp);
202 mp_DeleteQueue(&bundle->ncp.mp);
203 for (dl = bundle->links; dl; dl = dl->next)
204 physical_DeleteQueue(dl->physical);
205}
206
207static void
208bundle_LinkAdded(struct bundle *bundle, struct datalink *dl)
209{
210 bundle->phys_type.all |= dl->physical->type;
211 if (dl->state == DATALINK_OPEN)
212 bundle->phys_type.open |= dl->physical->type;
213
214 if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL))
215 != bundle->phys_type.open && bundle->idle.timer.state == TIMER_STOPPED)
216 /* We may need to start our idle timer */
217 bundle_StartIdleTimer(bundle);
218}
219
220void
221bundle_LinksRemoved(struct bundle *bundle)
222{
223 struct datalink *dl;
224
225 bundle->phys_type.all = bundle->phys_type.open = 0;
226 for (dl = bundle->links; dl; dl = dl->next)
227 bundle_LinkAdded(bundle, dl);
228
229 bundle_CalculateBandwidth(bundle);
230 mp_CheckAutoloadTimer(&bundle->ncp.mp);
231
232 if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL))
233 == bundle->phys_type.open)
234 bundle_StopIdleTimer(bundle);
235}
236
237static void
238bundle_LayerUp(void *v, struct fsm *fp)
239{
240 /*
241 * The given fsm is now up
242 * If it's an LCP, adjust our phys_mode.open value and check the
243 * autoload timer.
244 * If it's the first NCP, calculate our bandwidth
245 * If it's the first NCP, set our ``upat'' time
246 * If it's the first NCP, start the idle timer.
247 * If it's an NCP, tell our -background parent to go away.
248 * If it's the first NCP, start the autoload timer
249 */
250 struct bundle *bundle = (struct bundle *)v;
251
252 if (fp->proto == PROTO_LCP) {
253 struct physical *p = link2physical(fp->link);
254
255 bundle_LinkAdded(bundle, p->dl);
256 mp_CheckAutoloadTimer(&bundle->ncp.mp);
257 } else if (fp->proto == PROTO_IPCP) {
258 bundle_CalculateBandwidth(fp->bundle);
259 time(&bundle->upat);
260 bundle_StartIdleTimer(bundle);
261 bundle_Notify(bundle, EX_NORMAL);
262 mp_CheckAutoloadTimer(&fp->bundle->ncp.mp);
263 }
264}
265
266static void
267bundle_LayerDown(void *v, struct fsm *fp)
268{
269 /*
270 * The given FSM has been told to come down.
271 * If it's our last NCP, stop the idle timer.
272 * If it's our last NCP, clear our ``upat'' value.
273 * If it's our last NCP, stop the autoload timer
274 * If it's an LCP, adjust our phys_type.open value and any timers.
275 * If it's an LCP and we're in multilink mode, adjust our tun
276 * If it's the last LCP, down all NCPs
277 * speed and make sure our minimum sequence number is adjusted.
278 */
279
280 struct bundle *bundle = (struct bundle *)v;
281
282 if (fp->proto == PROTO_IPCP) {
283 bundle_StopIdleTimer(bundle);
284 bundle->upat = 0;
285 mp_StopAutoloadTimer(&bundle->ncp.mp);
286 } else if (fp->proto == PROTO_LCP) {
287 struct datalink *dl;
288 struct datalink *lost;
289 int others_active;
290
291 bundle_LinksRemoved(bundle); /* adjust timers & phys_type values */
292
293 lost = NULL;
294 others_active = 0;
295 for (dl = bundle->links; dl; dl = dl->next) {
296 if (fp == &dl->physical->link.lcp.fsm)
297 lost = dl;
298 else if (dl->state != DATALINK_CLOSED && dl->state != DATALINK_HANGUP)
299 others_active++;
300 }
301
302 if (bundle->ncp.mp.active) {
303 bundle_CalculateBandwidth(bundle);
304
305 if (lost)
306 mp_LinkLost(&bundle->ncp.mp, lost);
307 else
308 log_Printf(LogALERT, "Oops, lost an unrecognised datalink (%s) !\n",
309 fp->link->name);
310 }
311
312 if (!others_active)
313 /* Down the NCPs. We don't expect to get fsm_Close()d ourself ! */
314 fsm2initial(&bundle->ncp.ipcp.fsm);
315 }
316}
317
318static void
319bundle_LayerFinish(void *v, struct fsm *fp)
320{
321 /* The given fsm is now down (fp cannot be NULL)
322 *
323 * If it's the last NCP, fsm_Close all LCPs
324 */
325
326 struct bundle *bundle = (struct bundle *)v;
327 struct datalink *dl;
328
329 if (fp->proto == PROTO_IPCP) {
330 if (bundle_Phase(bundle) != PHASE_DEAD)
331 bundle_NewPhase(bundle, PHASE_TERMINATE);
332 for (dl = bundle->links; dl; dl = dl->next)
333 if (dl->state == DATALINK_OPEN)
334 datalink_Close(dl, CLOSE_STAYDOWN);
335 fsm2initial(fp);
336 }
337}
338
339int
340bundle_LinkIsUp(const struct bundle *bundle)
341{
342 return bundle->ncp.ipcp.fsm.state == ST_OPENED;
343}
344
345void
346bundle_Close(struct bundle *bundle, const char *name, int how)
347{
348 /*
349 * Please close the given datalink.
350 * If name == NULL or name is the last datalink, fsm_Close all NCPs
351 * (except our MP)
352 * If it isn't the last datalink, just Close that datalink.
353 */
354
355 struct datalink *dl, *this_dl;
356 int others_active;
357
358 others_active = 0;
359 this_dl = NULL;
360
361 for (dl = bundle->links; dl; dl = dl->next) {
362 if (name && !strcasecmp(name, dl->name))
363 this_dl = dl;
364 if (name == NULL || this_dl == dl) {
365 switch (how) {
366 case CLOSE_LCP:
367 datalink_DontHangup(dl);
368 /* fall through */
369 case CLOSE_STAYDOWN:
370 datalink_StayDown(dl);
371 break;
372 }
373 } else if (dl->state != DATALINK_CLOSED && dl->state != DATALINK_HANGUP)
374 others_active++;
375 }
376
377 if (name && this_dl == NULL) {
378 log_Printf(LogWARN, "%s: Invalid datalink name\n", name);
379 return;
380 }
381
382 if (!others_active) {
383 bundle_StopIdleTimer(bundle);
384 if (bundle->ncp.ipcp.fsm.state > ST_CLOSED ||
385 bundle->ncp.ipcp.fsm.state == ST_STARTING)
386 fsm_Close(&bundle->ncp.ipcp.fsm);
387 else {
388 fsm2initial(&bundle->ncp.ipcp.fsm);
389 for (dl = bundle->links; dl; dl = dl->next)
390 datalink_Close(dl, how);
391 }
392 } else if (this_dl && this_dl->state != DATALINK_CLOSED &&
393 this_dl->state != DATALINK_HANGUP)
394 datalink_Close(this_dl, how);
395}
396
397void
398bundle_Down(struct bundle *bundle, int how)
399{
400 struct datalink *dl;
401
402 for (dl = bundle->links; dl; dl = dl->next)
403 datalink_Down(dl, how);
404}
405
406static size_t
407bundle_FillQueues(struct bundle *bundle)
408{
409 size_t total;
410
411 if (bundle->ncp.mp.active)
412 total = mp_FillQueues(bundle);
413 else {
414 struct datalink *dl;
415 size_t add;
416
417 for (total = 0, dl = bundle->links; dl; dl = dl->next)
418 if (dl->state == DATALINK_OPEN) {
419 add = link_QueueLen(&dl->physical->link);
420 if (add == 0 && dl->physical->out == NULL)
421 add = ip_PushPacket(&dl->physical->link, bundle);
422 total += add;
423 }
424 }
425
426 return total + ip_QueueLen(&bundle->ncp.ipcp);
427}
428
429static int
430bundle_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
431{
432 struct bundle *bundle = descriptor2bundle(d);
433 struct datalink *dl;
434 int result, nlinks;
435 size_t queued;
436
437 result = 0;
438
439 /* If there are aren't many packets queued, look for some more. */
440 for (nlinks = 0, dl = bundle->links; dl; dl = dl->next)
441 nlinks++;
442
443 if (nlinks) {
444 queued = r ? bundle_FillQueues(bundle) : ip_QueueLen(&bundle->ncp.ipcp);
445
446 if (r && (bundle->phase == PHASE_NETWORK ||
447 bundle->phys_type.all & PHYS_AUTO)) {
448 /* enough surplus so that we can tell if we're getting swamped */
449 if (queued < 30) {
450 /* Not enough - select() for more */
451 if (bundle->choked.timer.state == TIMER_RUNNING)
452 timer_Stop(&bundle->choked.timer); /* Not needed any more */
453 FD_SET(bundle->dev.fd, r);
454 if (*n < bundle->dev.fd + 1)
455 *n = bundle->dev.fd + 1;
456 log_Printf(LogTIMER, "%s: fdset(r) %d\n", TUN_NAME, bundle->dev.fd);
457 result++;
458 } else if (bundle->choked.timer.state == TIMER_STOPPED) {
459 bundle->choked.timer.func = bundle_ClearQueues;
460 bundle->choked.timer.name = "output choke";
461 bundle->choked.timer.load = bundle->cfg.choked.timeout * SECTICKS;
462 bundle->choked.timer.arg = bundle;
463 timer_Start(&bundle->choked.timer);
464 }
465 }
466 }
467
468#ifndef NORADIUS
469 result += descriptor_UpdateSet(&bundle->radius.desc, r, w, e, n);
470#endif
471
472 /* Which links need a select() ? */
473 for (dl = bundle->links; dl; dl = dl->next)
474 result += descriptor_UpdateSet(&dl->desc, r, w, e, n);
475
476 /*
477 * This *MUST* be called after the datalink UpdateSet()s as it
478 * might be ``holding'' one of the datalinks (death-row) and
479 * wants to be able to de-select() it from the descriptor set.
480 */
481 result += descriptor_UpdateSet(&bundle->ncp.mp.server.desc, r, w, e, n);
482
483 return result;
484}
485
486static int
487bundle_IsSet(struct fdescriptor *d, const fd_set *fdset)
488{
489 struct bundle *bundle = descriptor2bundle(d);
490 struct datalink *dl;
491
492 for (dl = bundle->links; dl; dl = dl->next)
493 if (descriptor_IsSet(&dl->desc, fdset))
494 return 1;
495
496#ifndef NORADIUS
497 if (descriptor_IsSet(&bundle->radius.desc, fdset))
498 return 1;
499#endif
500
501 if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
502 return 1;
503
504 return FD_ISSET(bundle->dev.fd, fdset);
505}
506
507static void
508bundle_DescriptorRead(struct fdescriptor *d, struct bundle *bundle,
509 const fd_set *fdset)
510{
511 struct datalink *dl;
512
513 if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
514 descriptor_Read(&bundle->ncp.mp.server.desc, bundle, fdset);
515
516 for (dl = bundle->links; dl; dl = dl->next)
517 if (descriptor_IsSet(&dl->desc, fdset))
518 descriptor_Read(&dl->desc, bundle, fdset);
519
520#ifndef NORADIUS
521 if (descriptor_IsSet(&bundle->radius.desc, fdset))
522 descriptor_Read(&bundle->radius.desc, bundle, fdset);
523#endif
524
525 if (FD_ISSET(bundle->dev.fd, fdset)) {
526 struct tun_data tun;
527 int n, pri;
528 char *data;
529 size_t sz;
530
531 if (bundle->dev.header) {
532 data = (char *)&tun;
533 sz = sizeof tun;
534 } else {
535 data = tun.data;
536 sz = sizeof tun.data;
537 }
538
539 /* something to read from tun */
540
541 n = read(bundle->dev.fd, data, sz);
542 if (n < 0) {
543 log_Printf(LogWARN, "%s: read: %s\n", bundle->dev.Name, strerror(errno));
544 return;
545 }
546
547 if (bundle->dev.header) {
548 n -= sz - sizeof tun.data;
549 if (n <= 0) {
550 log_Printf(LogERROR, "%s: read: Got only %d bytes of data !\n",
551 bundle->dev.Name, n);
552 return;
553 }
554 if (ntohl(tun.family) != AF_INET)
555 /* XXX: Should be maintaining drop/family counts ! */
556 return;
557 }
558
559 if (((struct ip *)tun.data)->ip_dst.s_addr ==
560 bundle->ncp.ipcp.my_ip.s_addr) {
561 /* we've been asked to send something addressed *to* us :( */
562 if (Enabled(bundle, OPT_LOOPBACK)) {
563 pri = PacketCheck(bundle, tun.data, n, &bundle->filter.in);
564 if (pri >= 0) {
565 n += sz - sizeof tun.data;
566 write(bundle->dev.fd, data, n);
567 log_Printf(LogDEBUG, "Looped back packet addressed to myself\n");
568 }
569 return;
570 } else
571 log_Printf(LogDEBUG, "Oops - forwarding packet addressed to myself\n");
572 }
573
574 /*
575 * Process on-demand dialup. Output packets are queued within tunnel
576 * device until IPCP is opened.
577 */
578
579 if (bundle_Phase(bundle) == PHASE_DEAD) {
580 /*
581 * Note, we must be in AUTO mode :-/ otherwise our interface should
582 * *not* be UP and we can't receive data
583 */
584 if ((pri = PacketCheck(bundle, tun.data, n, &bundle->filter.dial)) >= 0)
585 bundle_Open(bundle, NULL, PHYS_AUTO, 0);
586 else
587 /*
588 * Drop the packet. If we were to queue it, we'd just end up with
589 * a pile of timed-out data in our output queue by the time we get
590 * around to actually dialing. We'd also prematurely reach the
591 * threshold at which we stop select()ing to read() the tun
592 * device - breaking auto-dial.
593 */
594 return;
595 }
596
597 pri = PacketCheck(bundle, tun.data, n, &bundle->filter.out);
598 if (pri >= 0)
599 ip_Enqueue(&bundle->ncp.ipcp, pri, tun.data, n);
600 }
601}
602
603static int
604bundle_DescriptorWrite(struct fdescriptor *d, struct bundle *bundle,
605 const fd_set *fdset)
606{
607 struct datalink *dl;
608 int result = 0;
609
610 /* This is not actually necessary as struct mpserver doesn't Write() */
611 if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
612 descriptor_Write(&bundle->ncp.mp.server.desc, bundle, fdset);
613
614 for (dl = bundle->links; dl; dl = dl->next)
615 if (descriptor_IsSet(&dl->desc, fdset))
616 result += descriptor_Write(&dl->desc, bundle, fdset);
617
618 return result;
619}
620
621void
622bundle_LockTun(struct bundle *bundle)
623{
624 FILE *lockfile;
625 char pidfile[MAXPATHLEN];
626
627 snprintf(pidfile, sizeof pidfile, "%stun%d.pid", _PATH_VARRUN, bundle->unit);
628 lockfile = ID0fopen(pidfile, "w");
629 if (lockfile != NULL) {
630 fprintf(lockfile, "%d\n", (int)getpid());
631 fclose(lockfile);
632 }
633#ifndef RELEASE_CRUNCH
634 else
635 log_Printf(LogERROR, "Warning: Can't create %s: %s\n",
636 pidfile, strerror(errno));
637#endif
638}
639
640static void
641bundle_UnlockTun(struct bundle *bundle)
642{
643 char pidfile[MAXPATHLEN];
644
645 snprintf(pidfile, sizeof pidfile, "%stun%d.pid", _PATH_VARRUN, bundle->unit);
646 ID0unlink(pidfile);
647}
648
649struct bundle *
650bundle_Create(const char *prefix, int type, int unit)
651{
652 static struct bundle bundle; /* there can be only one */
653 int enoentcount, err, minunit, maxunit;
654 const char *ifname;
655#if defined(__FreeBSD__) && !defined(NOKLDLOAD)
656 int kldtried;
657#endif
658#if defined(TUNSIFMODE) || defined(TUNSLMODE) || defined(TUNSIFHEAD)
659 int iff;
660#endif
661
662 if (bundle.iface != NULL) { /* Already allocated ! */
663 log_Printf(LogALERT, "bundle_Create: There's only one BUNDLE !\n");
664 return NULL;
665 }
666
667 if (unit == -1) {
668 minunit = 0;
669 maxunit = -1;
670 } else {
671 minunit = unit;
672 maxunit = unit + 1;
673 }
674 err = ENOENT;
675 enoentcount = 0;
676#if defined(__FreeBSD__) && !defined(NOKLDLOAD)
677 kldtried = 0;
678#endif
679 for (bundle.unit = minunit; bundle.unit != maxunit; bundle.unit++) {
680 snprintf(bundle.dev.Name, sizeof bundle.dev.Name, "%s%d",
681 prefix, bundle.unit);
682 bundle.dev.fd = ID0open(bundle.dev.Name, O_RDWR);
683 if (bundle.dev.fd >= 0)
684 break;
685 else if (errno == ENXIO) {
686#if defined(__FreeBSD__) && !defined(NOKLDLOAD)
687 if (bundle.unit == minunit && !kldtried++) {
688 /*
689 * Attempt to load the tunnel interface KLD if it isn't loaded
690 * already.
691 */
692 if (modfind("if_tun") == -1) {
693 if (ID0kldload("if_tun") != -1) {
694 bundle.unit--;
695 continue;
696 }
697 log_Printf(LogWARN, "kldload: if_tun: %s\n", strerror(errno));
698 }
699 }
700#endif
701 err = errno;
702 break;
703 } else if (errno == ENOENT) {
704 if (++enoentcount > 2)
705 break;
706 } else
707 err = errno;
708 }
709
710 if (bundle.dev.fd < 0) {
711 if (unit == -1)
712 log_Printf(LogWARN, "No available tunnel devices found (%s)\n",
713 strerror(err));
714 else
715 log_Printf(LogWARN, "%s%d: %s\n", prefix, unit, strerror(err));
716 return NULL;
717 }
718
719 log_SetTun(bundle.unit);
720
721 ifname = strrchr(bundle.dev.Name, '/');
722 if (ifname == NULL)
723 ifname = bundle.dev.Name;
724 else
725 ifname++;
726
727 bundle.iface = iface_Create(ifname);
728 if (bundle.iface == NULL) {
729 close(bundle.dev.fd);
730 return NULL;
731 }
732
733#ifdef TUNSIFMODE
734 /* Make sure we're POINTOPOINT */
735 iff = IFF_POINTOPOINT;
736 if (ID0ioctl(bundle.dev.fd, TUNSIFMODE, &iff) < 0)
737 log_Printf(LogERROR, "bundle_Create: ioctl(TUNSIFMODE): %s\n",
738 strerror(errno));
739#endif
740
741#ifdef TUNSLMODE
742 /* Make sure we're not prepending sockaddrs */
743 iff = 0;
744 if (ID0ioctl(bundle.dev.fd, TUNSLMODE, &iff) < 0)
745 log_Printf(LogERROR, "bundle_Create: ioctl(TUNSLMODE): %s\n",
746 strerror(errno));
747#endif
748
749#ifdef TUNSIFHEAD
750 /* We want the address family please ! */
751 iff = 1;
752 if (ID0ioctl(bundle.dev.fd, TUNSIFHEAD, &iff) < 0) {
753 log_Printf(LogERROR, "bundle_Create: ioctl(TUNSIFHEAD): %s\n",
754 strerror(errno));
755 bundle.dev.header = 0;
756 } else
757 bundle.dev.header = 1;
758#else
759#ifdef __OpenBSD__
760 /* Always present for OpenBSD */
761 bundle.dev.header = 1;
762#else
763 /*
764 * If TUNSIFHEAD isn't available and we're not OpenBSD, assume
765 * everything's AF_INET (hopefully the tun device won't pass us
766 * anything else !).
767 */
768 bundle.dev.header = 0;
769#endif
770#endif
771
772 if (!iface_SetFlags(bundle.iface, IFF_UP)) {
773 iface_Destroy(bundle.iface);
774 bundle.iface = NULL;
775 close(bundle.dev.fd);
776 return NULL;
777 }
778
779 log_Printf(LogPHASE, "Using interface: %s\n", ifname);
780
781 bundle.bandwidth = 0;
782 bundle.routing_seq = 0;
783 bundle.phase = PHASE_DEAD;
784 bundle.CleaningUp = 0;
785 bundle.NatEnabled = 0;
786
787 bundle.fsm.LayerStart = bundle_LayerStart;
788 bundle.fsm.LayerUp = bundle_LayerUp;
789 bundle.fsm.LayerDown = bundle_LayerDown;
790 bundle.fsm.LayerFinish = bundle_LayerFinish;
791 bundle.fsm.object = &bundle;
792
793 bundle.cfg.idle.timeout = NCP_IDLE_TIMEOUT;
794 bundle.cfg.idle.min_timeout = 0;
795 *bundle.cfg.auth.name = '\0';
796 *bundle.cfg.auth.key = '\0';
797 bundle.cfg.opt = OPT_SROUTES | OPT_IDCHECK | OPT_LOOPBACK |
798 OPT_THROUGHPUT | OPT_UTMP;
799 *bundle.cfg.label = '\0';
800 bundle.cfg.mtu = DEF_MTU;
801 bundle.cfg.choked.timeout = CHOKED_TIMEOUT;
802 bundle.phys_type.all = type;
803 bundle.phys_type.open = 0;
804 bundle.upat = 0;
805
806 bundle.links = datalink_Create("deflink", &bundle, type);
807 if (bundle.links == NULL) {
808 log_Printf(LogALERT, "Cannot create data link: %s\n", strerror(errno));
809 iface_Destroy(bundle.iface);
810 bundle.iface = NULL;
811 close(bundle.dev.fd);
812 return NULL;
813 }
814
815 bundle.desc.type = BUNDLE_DESCRIPTOR;
816 bundle.desc.UpdateSet = bundle_UpdateSet;
817 bundle.desc.IsSet = bundle_IsSet;
818 bundle.desc.Read = bundle_DescriptorRead;
819 bundle.desc.Write = bundle_DescriptorWrite;
820
821 mp_Init(&bundle.ncp.mp, &bundle);
822
823 /* Send over the first physical link by default */
824 ipcp_Init(&bundle.ncp.ipcp, &bundle, &bundle.links->physical->link,
825 &bundle.fsm);
826
827 memset(&bundle.filter, '\0', sizeof bundle.filter);
828 bundle.filter.in.fragok = bundle.filter.in.logok = 1;
829 bundle.filter.in.name = "IN";
830 bundle.filter.out.fragok = bundle.filter.out.logok = 1;
831 bundle.filter.out.name = "OUT";
832 bundle.filter.dial.name = "DIAL";
833 bundle.filter.dial.logok = 1;
834 bundle.filter.alive.name = "ALIVE";
835 bundle.filter.alive.logok = 1;
836 {
837 int i;
838 for (i = 0; i < MAXFILTERS; i++) {
839 bundle.filter.in.rule[i].f_action = A_NONE;
840 bundle.filter.out.rule[i].f_action = A_NONE;
841 bundle.filter.dial.rule[i].f_action = A_NONE;
842 bundle.filter.alive.rule[i].f_action = A_NONE;
843 }
844 }
845 memset(&bundle.idle.timer, '\0', sizeof bundle.idle.timer);
846 bundle.idle.done = 0;
847 bundle.notify.fd = -1;
848 memset(&bundle.choked.timer, '\0', sizeof bundle.choked.timer);
849#ifndef NORADIUS
850 radius_Init(&bundle.radius);
851#endif
852
853 /* Clean out any leftover crud */
854 iface_Clear(bundle.iface, IFACE_CLEAR_ALL);
855
856 bundle_LockTun(&bundle);
857
858 return &bundle;
859}
860
861static void
862bundle_DownInterface(struct bundle *bundle)
863{
864 route_IfDelete(bundle, 1);
865 iface_ClearFlags(bundle->iface, IFF_UP);
866}
867
868void
869bundle_Destroy(struct bundle *bundle)
870{
871 struct datalink *dl;
872
873 /*
874 * Clean up the interface. We don't need to timer_Stop()s, mp_Down(),
875 * ipcp_CleanInterface() and bundle_DownInterface() unless we're getting
876 * out under exceptional conditions such as a descriptor exception.
877 */
878 timer_Stop(&bundle->idle.timer);
879 timer_Stop(&bundle->choked.timer);
880 mp_Down(&bundle->ncp.mp);
881 ipcp_CleanInterface(&bundle->ncp.ipcp);
882 bundle_DownInterface(bundle);
883
884#ifndef NORADIUS
885 /* Tell the radius server the bad news */
886 radius_Destroy(&bundle->radius);
887#endif
888
889 /* Again, these are all DATALINK_CLOSED unless we're abending */
890 dl = bundle->links;
891 while (dl)
892 dl = datalink_Destroy(dl);
893
894 ipcp_Destroy(&bundle->ncp.ipcp);
895
896 close(bundle->dev.fd);
897 bundle_UnlockTun(bundle);
898
899 /* In case we never made PHASE_NETWORK */
900 bundle_Notify(bundle, EX_ERRDEAD);
901
902 iface_Destroy(bundle->iface);
903 bundle->iface = NULL;
904}
905
906struct rtmsg {
907 struct rt_msghdr m_rtm;
908 char m_space[64];
909};
910
911int
912bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst,
913 struct in_addr gateway, struct in_addr mask, int bang, int ssh)
914{
915 struct rtmsg rtmes;
916 int s, nb, wb;
917 char *cp;
918 const char *cmdstr;
919 struct sockaddr_in rtdata;
920 int result = 1;
921
922 if (bang)
923 cmdstr = (cmd == RTM_ADD ? "Add!" : "Delete!");
924 else
925 cmdstr = (cmd == RTM_ADD ? "Add" : "Delete");
926 s = ID0socket(PF_ROUTE, SOCK_RAW, 0);
927 if (s < 0) {
928 log_Printf(LogERROR, "bundle_SetRoute: socket(): %s\n", strerror(errno));
929 return result;
930 }
931 memset(&rtmes, '\0', sizeof rtmes);
932 rtmes.m_rtm.rtm_version = RTM_VERSION;
933 rtmes.m_rtm.rtm_type = cmd;
934 rtmes.m_rtm.rtm_addrs = RTA_DST;
935 rtmes.m_rtm.rtm_seq = ++bundle->routing_seq;
936 rtmes.m_rtm.rtm_pid = getpid();
937 rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
938
939 if (cmd == RTM_ADD || cmd == RTM_CHANGE) {
940 if (bundle->ncp.ipcp.cfg.sendpipe > 0) {
941 rtmes.m_rtm.rtm_rmx.rmx_sendpipe = bundle->ncp.ipcp.cfg.sendpipe;
942 rtmes.m_rtm.rtm_inits |= RTV_SPIPE;
943 }
944 if (bundle->ncp.ipcp.cfg.recvpipe > 0) {
945 rtmes.m_rtm.rtm_rmx.rmx_recvpipe = bundle->ncp.ipcp.cfg.recvpipe;
946 rtmes.m_rtm.rtm_inits |= RTV_RPIPE;
947 }
948 }
949
950 memset(&rtdata, '\0', sizeof rtdata);
951 rtdata.sin_len = sizeof rtdata;
952 rtdata.sin_family = AF_INET;
953 rtdata.sin_port = 0;
954 rtdata.sin_addr = dst;
955
956 cp = rtmes.m_space;
957 memcpy(cp, &rtdata, rtdata.sin_len);
958 cp += rtdata.sin_len;
959 if (cmd == RTM_ADD) {
960 if (gateway.s_addr == INADDR_ANY) {
961 if (!ssh)
962 log_Printf(LogERROR, "bundle_SetRoute: Cannot add a route with"
963 " destination 0.0.0.0\n");
964 close(s);
965 return result;
966 } else {
967 rtdata.sin_addr = gateway;
968 memcpy(cp, &rtdata, rtdata.sin_len);
969 cp += rtdata.sin_len;
970 rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
971 }
972 }
973
974 if (dst.s_addr == INADDR_ANY)
975 mask.s_addr = INADDR_ANY;
976
977 if (cmd == RTM_ADD || dst.s_addr == INADDR_ANY) {
978 rtdata.sin_addr = mask;
979 memcpy(cp, &rtdata, rtdata.sin_len);
980 cp += rtdata.sin_len;
981 rtmes.m_rtm.rtm_addrs |= RTA_NETMASK;
982 }
983
984 nb = cp - (char *) &rtmes;
985 rtmes.m_rtm.rtm_msglen = nb;
986 wb = ID0write(s, &rtmes, nb);
987 if (wb < 0) {
988 log_Printf(LogTCPIP, "bundle_SetRoute failure:\n");
989 log_Printf(LogTCPIP, "bundle_SetRoute: Cmd = %s\n", cmdstr);
990 log_Printf(LogTCPIP, "bundle_SetRoute: Dst = %s\n", inet_ntoa(dst));
991 log_Printf(LogTCPIP, "bundle_SetRoute: Gateway = %s\n",
992 inet_ntoa(gateway));
993 log_Printf(LogTCPIP, "bundle_SetRoute: Mask = %s\n", inet_ntoa(mask));
994failed:
995 if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST ||
996 (rtmes.m_rtm.rtm_errno == 0 && errno == EEXIST))) {
997 if (!bang) {
998 log_Printf(LogWARN, "Add route failed: %s already exists\n",
999 dst.s_addr == 0 ? "default" : inet_ntoa(dst));
1000 result = 0; /* Don't add to our dynamic list */
1001 } else {
1002 rtmes.m_rtm.rtm_type = cmd = RTM_CHANGE;
1003 if ((wb = ID0write(s, &rtmes, nb)) < 0)
1004 goto failed;
1005 }
1006 } else if (cmd == RTM_DELETE &&
1007 (rtmes.m_rtm.rtm_errno == ESRCH ||
1008 (rtmes.m_rtm.rtm_errno == 0 && errno == ESRCH))) {
1009 if (!bang)
1010 log_Printf(LogWARN, "Del route failed: %s: Non-existent\n",
1011 inet_ntoa(dst));
1012 } else if (rtmes.m_rtm.rtm_errno == 0) {
1013 if (!ssh || errno != ENETUNREACH)
1014 log_Printf(LogWARN, "%s route failed: %s: errno: %s\n", cmdstr,
1015 inet_ntoa(dst), strerror(errno));
1016 } else
1017 log_Printf(LogWARN, "%s route failed: %s: %s\n",
1018 cmdstr, inet_ntoa(dst), strerror(rtmes.m_rtm.rtm_errno));
1019 }
1020 log_Printf(LogDEBUG, "wrote %d: cmd = %s, dst = %x, gateway = %x\n",
1021 wb, cmdstr, (unsigned)dst.s_addr, (unsigned)gateway.s_addr);
1022 close(s);
1023
1024 return result;
1025}
1026
1027void
1028bundle_LinkClosed(struct bundle *bundle, struct datalink *dl)
1029{
1030 /*
1031 * Our datalink has closed.
1032 * CleanDatalinks() (called from DoLoop()) will remove closed
1033 * BACKGROUND, FOREGROUND and DIRECT links.
1034 * If it's the last data link, enter phase DEAD.
1035 *
1036 * NOTE: dl may not be in our list (bundle_SendDatalink()) !
1037 */
1038
1039 struct datalink *odl;
1040 int other_links;
1041
1042 log_SetTtyCommandMode(dl);
1043
1044 other_links = 0;
1045 for (odl = bundle->links; odl; odl = odl->next)
1046 if (odl != dl && odl->state != DATALINK_CLOSED)
1047 other_links++;
1048
1049 if (!other_links) {
1050 if (dl->physical->type != PHYS_AUTO) /* Not in -auto mode */
1051 bundle_DownInterface(bundle);
1052 fsm2initial(&bundle->ncp.ipcp.fsm);
1053 bundle_NewPhase(bundle, PHASE_DEAD);
1054 bundle_StopIdleTimer(bundle);
1055 }
1056}
1057
1058void
1059bundle_Open(struct bundle *bundle, const char *name, int mask, int force)
1060{
1061 /*
1062 * Please open the given datalink, or all if name == NULL
1063 */
1064 struct datalink *dl;
1065
1066 for (dl = bundle->links; dl; dl = dl->next)
1067 if (name == NULL || !strcasecmp(dl->name, name)) {
1068 if ((mask & dl->physical->type) &&
1069 (dl->state == DATALINK_CLOSED ||
1070 (force && dl->state == DATALINK_OPENING &&
1071 dl->dial.timer.state == TIMER_RUNNING))) {
1072 if (force) /* Ignore redial timeout ? */
1073 timer_Stop(&dl->dial.timer);
1074 datalink_Up(dl, 1, 1);
1075 if (mask & PHYS_AUTO)
1076 /* Only one AUTO link at a time */
1077 break;
1078 }
1079 if (name != NULL)
1080 break;
1081 }
1082}
1083
1084struct datalink *
1085bundle2datalink(struct bundle *bundle, const char *name)
1086{
1087 struct datalink *dl;
1088
1089 if (name != NULL) {
1090 for (dl = bundle->links; dl; dl = dl->next)
1091 if (!strcasecmp(dl->name, name))
1092 return dl;
1093 } else if (bundle->links && !bundle->links->next)
1094 return bundle->links;
1095
1096 return NULL;
1097}
1098
1099int
1100bundle_ShowLinks(struct cmdargs const *arg)
1101{
1102 struct datalink *dl;
1103 struct pppThroughput *t;
1104 int secs;
1105
1106 for (dl = arg->bundle->links; dl; dl = dl->next) {
1107 prompt_Printf(arg->prompt, "Name: %s [%s, %s]",
1108 dl->name, mode2Nam(dl->physical->type), datalink_State(dl));
1109 if (dl->physical->link.throughput.rolling && dl->state == DATALINK_OPEN)
1110 prompt_Printf(arg->prompt, " bandwidth %d, %llu bps (%llu bytes/sec)",
1111 dl->mp.bandwidth ? dl->mp.bandwidth :
1112 physical_GetSpeed(dl->physical),
1113 dl->physical->link.throughput.OctetsPerSecond * 8,
1114 dl->physical->link.throughput.OctetsPerSecond);
1115 prompt_Printf(arg->prompt, "\n");
1116 }
1117
1118 t = &arg->bundle->ncp.mp.link.throughput;
1119 secs = t->downtime ? 0 : throughput_uptime(t);
1120 if (secs > t->SamplePeriod)
1121 secs = t->SamplePeriod;
1122 if (secs)
1123 prompt_Printf(arg->prompt, "Currently averaging %llu bps (%llu bytes/sec)"
1124 " over the last %d secs\n", t->OctetsPerSecond * 8,
1125 t->OctetsPerSecond, secs);
1126
1127 return 0;
1128}
1129
1130static const char *
1131optval(struct bundle *bundle, int bit)
1132{
1133 return (bundle->cfg.opt & bit) ? "enabled" : "disabled";
1134}
1135
1136int
1137bundle_ShowStatus(struct cmdargs const *arg)
1138{
1139 int remaining;
1140
1141 prompt_Printf(arg->prompt, "Phase %s\n", bundle_PhaseName(arg->bundle));
1142 prompt_Printf(arg->prompt, " Device: %s\n", arg->bundle->dev.Name);
1143 prompt_Printf(arg->prompt, " Interface: %s @ %lubps",
1144 arg->bundle->iface->name, arg->bundle->bandwidth);
1145
1146 if (arg->bundle->upat) {
1147 int secs = time(NULL) - arg->bundle->upat;
1148
1149 prompt_Printf(arg->prompt, ", up time %d:%02d:%02d", secs / 3600,
1150 (secs / 60) % 60, secs % 60);
1151 }
1152
1153 prompt_Printf(arg->prompt, "\n\nDefaults:\n");
1154 prompt_Printf(arg->prompt, " Label: %s\n", arg->bundle->cfg.label);
1155 prompt_Printf(arg->prompt, " Auth name: %s\n",
1156 arg->bundle->cfg.auth.name);
1157
1158 prompt_Printf(arg->prompt, " Choked Timer: %ds\n",
1159 arg->bundle->cfg.choked.timeout);
1160
1161#ifndef NORADIUS
1162 radius_Show(&arg->bundle->radius, arg->prompt);
1163#endif
1164
1165 prompt_Printf(arg->prompt, " Idle Timer: ");
1166 if (arg->bundle->cfg.idle.timeout) {
1167 prompt_Printf(arg->prompt, "%ds", arg->bundle->cfg.idle.timeout);
1168 if (arg->bundle->cfg.idle.min_timeout)
1169 prompt_Printf(arg->prompt, ", min %ds",
1170 arg->bundle->cfg.idle.min_timeout);
1171 remaining = bundle_RemainingIdleTime(arg->bundle);
1172 if (remaining != -1)
1173 prompt_Printf(arg->prompt, " (%ds remaining)", remaining);
1174 prompt_Printf(arg->prompt, "\n");
1175 } else
1176 prompt_Printf(arg->prompt, "disabled\n");
1177 prompt_Printf(arg->prompt, " MTU: ");
1178 if (arg->bundle->cfg.mtu)
1179 prompt_Printf(arg->prompt, "%d\n", arg->bundle->cfg.mtu);
1180 else
1181 prompt_Printf(arg->prompt, "unspecified\n");
1182
1183 prompt_Printf(arg->prompt, " sendpipe: ");
1184 if (arg->bundle->ncp.ipcp.cfg.sendpipe > 0)
1185 prompt_Printf(arg->prompt, "%-20ld", arg->bundle->ncp.ipcp.cfg.sendpipe);
1186 else
1187 prompt_Printf(arg->prompt, "unspecified ");
1188 prompt_Printf(arg->prompt, " recvpipe: ");
1189 if (arg->bundle->ncp.ipcp.cfg.recvpipe > 0)
1190 prompt_Printf(arg->prompt, "%ld\n", arg->bundle->ncp.ipcp.cfg.recvpipe);
1191 else
1192 prompt_Printf(arg->prompt, "unspecified\n");
1193
1194 prompt_Printf(arg->prompt, " Sticky Routes: %-20.20s",
1195 optval(arg->bundle, OPT_SROUTES));
1196 prompt_Printf(arg->prompt, " ID check: %s\n",
1197 optval(arg->bundle, OPT_IDCHECK));
1198 prompt_Printf(arg->prompt, " Keep-Session: %-20.20s",
1199 optval(arg->bundle, OPT_KEEPSESSION));
1200 prompt_Printf(arg->prompt, " Loopback: %s\n",
1201 optval(arg->bundle, OPT_LOOPBACK));
1202 prompt_Printf(arg->prompt, " PasswdAuth: %-20.20s",
1203 optval(arg->bundle, OPT_PASSWDAUTH));
1204 prompt_Printf(arg->prompt, " Proxy: %s\n",
1205 optval(arg->bundle, OPT_PROXY));
1206 prompt_Printf(arg->prompt, " Proxyall: %-20.20s",
1207 optval(arg->bundle, OPT_PROXYALL));
1208 prompt_Printf(arg->prompt, " Throughput: %s\n",
1209 optval(arg->bundle, OPT_THROUGHPUT));
1210 prompt_Printf(arg->prompt, " Utmp Logging: %-20.20s",
1211 optval(arg->bundle, OPT_UTMP));
1212 prompt_Printf(arg->prompt, " Iface-Alias: %s\n",
1213 optval(arg->bundle, OPT_IFACEALIAS));
1214
1215 return 0;
1216}
1217
1218static void
1219bundle_IdleTimeout(void *v)
1220{
1221 struct bundle *bundle = (struct bundle *)v;
1222
182 }
183}
184
185static void
186bundle_ClearQueues(void *v)
187{
188 struct bundle *bundle = (struct bundle *)v;
189 struct datalink *dl;
190
191 log_Printf(LogPHASE, "Clearing choked output queue\n");
192 timer_Stop(&bundle->choked.timer);
193
194 /*
195 * Emergency time:
196 *
197 * We've had a full queue for PACKET_DEL_SECS seconds without being
198 * able to get rid of any of the packets. We've probably given up
199 * on the redials at this point, and the queued data has almost
200 * definitely been timed out by the layer above. As this is preventing
201 * us from reading the TUN_NAME device (we don't want to buffer stuff
202 * indefinitely), we may as well nuke this data and start with a clean
203 * slate !
204 *
205 * Unfortunately, this has the side effect of shafting any compression
206 * dictionaries in use (causing the relevant RESET_REQ/RESET_ACK).
207 */
208
209 ip_DeleteQueue(&bundle->ncp.ipcp);
210 mp_DeleteQueue(&bundle->ncp.mp);
211 for (dl = bundle->links; dl; dl = dl->next)
212 physical_DeleteQueue(dl->physical);
213}
214
215static void
216bundle_LinkAdded(struct bundle *bundle, struct datalink *dl)
217{
218 bundle->phys_type.all |= dl->physical->type;
219 if (dl->state == DATALINK_OPEN)
220 bundle->phys_type.open |= dl->physical->type;
221
222 if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL))
223 != bundle->phys_type.open && bundle->idle.timer.state == TIMER_STOPPED)
224 /* We may need to start our idle timer */
225 bundle_StartIdleTimer(bundle);
226}
227
228void
229bundle_LinksRemoved(struct bundle *bundle)
230{
231 struct datalink *dl;
232
233 bundle->phys_type.all = bundle->phys_type.open = 0;
234 for (dl = bundle->links; dl; dl = dl->next)
235 bundle_LinkAdded(bundle, dl);
236
237 bundle_CalculateBandwidth(bundle);
238 mp_CheckAutoloadTimer(&bundle->ncp.mp);
239
240 if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL))
241 == bundle->phys_type.open)
242 bundle_StopIdleTimer(bundle);
243}
244
245static void
246bundle_LayerUp(void *v, struct fsm *fp)
247{
248 /*
249 * The given fsm is now up
250 * If it's an LCP, adjust our phys_mode.open value and check the
251 * autoload timer.
252 * If it's the first NCP, calculate our bandwidth
253 * If it's the first NCP, set our ``upat'' time
254 * If it's the first NCP, start the idle timer.
255 * If it's an NCP, tell our -background parent to go away.
256 * If it's the first NCP, start the autoload timer
257 */
258 struct bundle *bundle = (struct bundle *)v;
259
260 if (fp->proto == PROTO_LCP) {
261 struct physical *p = link2physical(fp->link);
262
263 bundle_LinkAdded(bundle, p->dl);
264 mp_CheckAutoloadTimer(&bundle->ncp.mp);
265 } else if (fp->proto == PROTO_IPCP) {
266 bundle_CalculateBandwidth(fp->bundle);
267 time(&bundle->upat);
268 bundle_StartIdleTimer(bundle);
269 bundle_Notify(bundle, EX_NORMAL);
270 mp_CheckAutoloadTimer(&fp->bundle->ncp.mp);
271 }
272}
273
274static void
275bundle_LayerDown(void *v, struct fsm *fp)
276{
277 /*
278 * The given FSM has been told to come down.
279 * If it's our last NCP, stop the idle timer.
280 * If it's our last NCP, clear our ``upat'' value.
281 * If it's our last NCP, stop the autoload timer
282 * If it's an LCP, adjust our phys_type.open value and any timers.
283 * If it's an LCP and we're in multilink mode, adjust our tun
284 * If it's the last LCP, down all NCPs
285 * speed and make sure our minimum sequence number is adjusted.
286 */
287
288 struct bundle *bundle = (struct bundle *)v;
289
290 if (fp->proto == PROTO_IPCP) {
291 bundle_StopIdleTimer(bundle);
292 bundle->upat = 0;
293 mp_StopAutoloadTimer(&bundle->ncp.mp);
294 } else if (fp->proto == PROTO_LCP) {
295 struct datalink *dl;
296 struct datalink *lost;
297 int others_active;
298
299 bundle_LinksRemoved(bundle); /* adjust timers & phys_type values */
300
301 lost = NULL;
302 others_active = 0;
303 for (dl = bundle->links; dl; dl = dl->next) {
304 if (fp == &dl->physical->link.lcp.fsm)
305 lost = dl;
306 else if (dl->state != DATALINK_CLOSED && dl->state != DATALINK_HANGUP)
307 others_active++;
308 }
309
310 if (bundle->ncp.mp.active) {
311 bundle_CalculateBandwidth(bundle);
312
313 if (lost)
314 mp_LinkLost(&bundle->ncp.mp, lost);
315 else
316 log_Printf(LogALERT, "Oops, lost an unrecognised datalink (%s) !\n",
317 fp->link->name);
318 }
319
320 if (!others_active)
321 /* Down the NCPs. We don't expect to get fsm_Close()d ourself ! */
322 fsm2initial(&bundle->ncp.ipcp.fsm);
323 }
324}
325
326static void
327bundle_LayerFinish(void *v, struct fsm *fp)
328{
329 /* The given fsm is now down (fp cannot be NULL)
330 *
331 * If it's the last NCP, fsm_Close all LCPs
332 */
333
334 struct bundle *bundle = (struct bundle *)v;
335 struct datalink *dl;
336
337 if (fp->proto == PROTO_IPCP) {
338 if (bundle_Phase(bundle) != PHASE_DEAD)
339 bundle_NewPhase(bundle, PHASE_TERMINATE);
340 for (dl = bundle->links; dl; dl = dl->next)
341 if (dl->state == DATALINK_OPEN)
342 datalink_Close(dl, CLOSE_STAYDOWN);
343 fsm2initial(fp);
344 }
345}
346
347int
348bundle_LinkIsUp(const struct bundle *bundle)
349{
350 return bundle->ncp.ipcp.fsm.state == ST_OPENED;
351}
352
353void
354bundle_Close(struct bundle *bundle, const char *name, int how)
355{
356 /*
357 * Please close the given datalink.
358 * If name == NULL or name is the last datalink, fsm_Close all NCPs
359 * (except our MP)
360 * If it isn't the last datalink, just Close that datalink.
361 */
362
363 struct datalink *dl, *this_dl;
364 int others_active;
365
366 others_active = 0;
367 this_dl = NULL;
368
369 for (dl = bundle->links; dl; dl = dl->next) {
370 if (name && !strcasecmp(name, dl->name))
371 this_dl = dl;
372 if (name == NULL || this_dl == dl) {
373 switch (how) {
374 case CLOSE_LCP:
375 datalink_DontHangup(dl);
376 /* fall through */
377 case CLOSE_STAYDOWN:
378 datalink_StayDown(dl);
379 break;
380 }
381 } else if (dl->state != DATALINK_CLOSED && dl->state != DATALINK_HANGUP)
382 others_active++;
383 }
384
385 if (name && this_dl == NULL) {
386 log_Printf(LogWARN, "%s: Invalid datalink name\n", name);
387 return;
388 }
389
390 if (!others_active) {
391 bundle_StopIdleTimer(bundle);
392 if (bundle->ncp.ipcp.fsm.state > ST_CLOSED ||
393 bundle->ncp.ipcp.fsm.state == ST_STARTING)
394 fsm_Close(&bundle->ncp.ipcp.fsm);
395 else {
396 fsm2initial(&bundle->ncp.ipcp.fsm);
397 for (dl = bundle->links; dl; dl = dl->next)
398 datalink_Close(dl, how);
399 }
400 } else if (this_dl && this_dl->state != DATALINK_CLOSED &&
401 this_dl->state != DATALINK_HANGUP)
402 datalink_Close(this_dl, how);
403}
404
405void
406bundle_Down(struct bundle *bundle, int how)
407{
408 struct datalink *dl;
409
410 for (dl = bundle->links; dl; dl = dl->next)
411 datalink_Down(dl, how);
412}
413
414static size_t
415bundle_FillQueues(struct bundle *bundle)
416{
417 size_t total;
418
419 if (bundle->ncp.mp.active)
420 total = mp_FillQueues(bundle);
421 else {
422 struct datalink *dl;
423 size_t add;
424
425 for (total = 0, dl = bundle->links; dl; dl = dl->next)
426 if (dl->state == DATALINK_OPEN) {
427 add = link_QueueLen(&dl->physical->link);
428 if (add == 0 && dl->physical->out == NULL)
429 add = ip_PushPacket(&dl->physical->link, bundle);
430 total += add;
431 }
432 }
433
434 return total + ip_QueueLen(&bundle->ncp.ipcp);
435}
436
437static int
438bundle_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
439{
440 struct bundle *bundle = descriptor2bundle(d);
441 struct datalink *dl;
442 int result, nlinks;
443 size_t queued;
444
445 result = 0;
446
447 /* If there are aren't many packets queued, look for some more. */
448 for (nlinks = 0, dl = bundle->links; dl; dl = dl->next)
449 nlinks++;
450
451 if (nlinks) {
452 queued = r ? bundle_FillQueues(bundle) : ip_QueueLen(&bundle->ncp.ipcp);
453
454 if (r && (bundle->phase == PHASE_NETWORK ||
455 bundle->phys_type.all & PHYS_AUTO)) {
456 /* enough surplus so that we can tell if we're getting swamped */
457 if (queued < 30) {
458 /* Not enough - select() for more */
459 if (bundle->choked.timer.state == TIMER_RUNNING)
460 timer_Stop(&bundle->choked.timer); /* Not needed any more */
461 FD_SET(bundle->dev.fd, r);
462 if (*n < bundle->dev.fd + 1)
463 *n = bundle->dev.fd + 1;
464 log_Printf(LogTIMER, "%s: fdset(r) %d\n", TUN_NAME, bundle->dev.fd);
465 result++;
466 } else if (bundle->choked.timer.state == TIMER_STOPPED) {
467 bundle->choked.timer.func = bundle_ClearQueues;
468 bundle->choked.timer.name = "output choke";
469 bundle->choked.timer.load = bundle->cfg.choked.timeout * SECTICKS;
470 bundle->choked.timer.arg = bundle;
471 timer_Start(&bundle->choked.timer);
472 }
473 }
474 }
475
476#ifndef NORADIUS
477 result += descriptor_UpdateSet(&bundle->radius.desc, r, w, e, n);
478#endif
479
480 /* Which links need a select() ? */
481 for (dl = bundle->links; dl; dl = dl->next)
482 result += descriptor_UpdateSet(&dl->desc, r, w, e, n);
483
484 /*
485 * This *MUST* be called after the datalink UpdateSet()s as it
486 * might be ``holding'' one of the datalinks (death-row) and
487 * wants to be able to de-select() it from the descriptor set.
488 */
489 result += descriptor_UpdateSet(&bundle->ncp.mp.server.desc, r, w, e, n);
490
491 return result;
492}
493
494static int
495bundle_IsSet(struct fdescriptor *d, const fd_set *fdset)
496{
497 struct bundle *bundle = descriptor2bundle(d);
498 struct datalink *dl;
499
500 for (dl = bundle->links; dl; dl = dl->next)
501 if (descriptor_IsSet(&dl->desc, fdset))
502 return 1;
503
504#ifndef NORADIUS
505 if (descriptor_IsSet(&bundle->radius.desc, fdset))
506 return 1;
507#endif
508
509 if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
510 return 1;
511
512 return FD_ISSET(bundle->dev.fd, fdset);
513}
514
515static void
516bundle_DescriptorRead(struct fdescriptor *d, struct bundle *bundle,
517 const fd_set *fdset)
518{
519 struct datalink *dl;
520
521 if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
522 descriptor_Read(&bundle->ncp.mp.server.desc, bundle, fdset);
523
524 for (dl = bundle->links; dl; dl = dl->next)
525 if (descriptor_IsSet(&dl->desc, fdset))
526 descriptor_Read(&dl->desc, bundle, fdset);
527
528#ifndef NORADIUS
529 if (descriptor_IsSet(&bundle->radius.desc, fdset))
530 descriptor_Read(&bundle->radius.desc, bundle, fdset);
531#endif
532
533 if (FD_ISSET(bundle->dev.fd, fdset)) {
534 struct tun_data tun;
535 int n, pri;
536 char *data;
537 size_t sz;
538
539 if (bundle->dev.header) {
540 data = (char *)&tun;
541 sz = sizeof tun;
542 } else {
543 data = tun.data;
544 sz = sizeof tun.data;
545 }
546
547 /* something to read from tun */
548
549 n = read(bundle->dev.fd, data, sz);
550 if (n < 0) {
551 log_Printf(LogWARN, "%s: read: %s\n", bundle->dev.Name, strerror(errno));
552 return;
553 }
554
555 if (bundle->dev.header) {
556 n -= sz - sizeof tun.data;
557 if (n <= 0) {
558 log_Printf(LogERROR, "%s: read: Got only %d bytes of data !\n",
559 bundle->dev.Name, n);
560 return;
561 }
562 if (ntohl(tun.family) != AF_INET)
563 /* XXX: Should be maintaining drop/family counts ! */
564 return;
565 }
566
567 if (((struct ip *)tun.data)->ip_dst.s_addr ==
568 bundle->ncp.ipcp.my_ip.s_addr) {
569 /* we've been asked to send something addressed *to* us :( */
570 if (Enabled(bundle, OPT_LOOPBACK)) {
571 pri = PacketCheck(bundle, tun.data, n, &bundle->filter.in);
572 if (pri >= 0) {
573 n += sz - sizeof tun.data;
574 write(bundle->dev.fd, data, n);
575 log_Printf(LogDEBUG, "Looped back packet addressed to myself\n");
576 }
577 return;
578 } else
579 log_Printf(LogDEBUG, "Oops - forwarding packet addressed to myself\n");
580 }
581
582 /*
583 * Process on-demand dialup. Output packets are queued within tunnel
584 * device until IPCP is opened.
585 */
586
587 if (bundle_Phase(bundle) == PHASE_DEAD) {
588 /*
589 * Note, we must be in AUTO mode :-/ otherwise our interface should
590 * *not* be UP and we can't receive data
591 */
592 if ((pri = PacketCheck(bundle, tun.data, n, &bundle->filter.dial)) >= 0)
593 bundle_Open(bundle, NULL, PHYS_AUTO, 0);
594 else
595 /*
596 * Drop the packet. If we were to queue it, we'd just end up with
597 * a pile of timed-out data in our output queue by the time we get
598 * around to actually dialing. We'd also prematurely reach the
599 * threshold at which we stop select()ing to read() the tun
600 * device - breaking auto-dial.
601 */
602 return;
603 }
604
605 pri = PacketCheck(bundle, tun.data, n, &bundle->filter.out);
606 if (pri >= 0)
607 ip_Enqueue(&bundle->ncp.ipcp, pri, tun.data, n);
608 }
609}
610
611static int
612bundle_DescriptorWrite(struct fdescriptor *d, struct bundle *bundle,
613 const fd_set *fdset)
614{
615 struct datalink *dl;
616 int result = 0;
617
618 /* This is not actually necessary as struct mpserver doesn't Write() */
619 if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
620 descriptor_Write(&bundle->ncp.mp.server.desc, bundle, fdset);
621
622 for (dl = bundle->links; dl; dl = dl->next)
623 if (descriptor_IsSet(&dl->desc, fdset))
624 result += descriptor_Write(&dl->desc, bundle, fdset);
625
626 return result;
627}
628
629void
630bundle_LockTun(struct bundle *bundle)
631{
632 FILE *lockfile;
633 char pidfile[MAXPATHLEN];
634
635 snprintf(pidfile, sizeof pidfile, "%stun%d.pid", _PATH_VARRUN, bundle->unit);
636 lockfile = ID0fopen(pidfile, "w");
637 if (lockfile != NULL) {
638 fprintf(lockfile, "%d\n", (int)getpid());
639 fclose(lockfile);
640 }
641#ifndef RELEASE_CRUNCH
642 else
643 log_Printf(LogERROR, "Warning: Can't create %s: %s\n",
644 pidfile, strerror(errno));
645#endif
646}
647
648static void
649bundle_UnlockTun(struct bundle *bundle)
650{
651 char pidfile[MAXPATHLEN];
652
653 snprintf(pidfile, sizeof pidfile, "%stun%d.pid", _PATH_VARRUN, bundle->unit);
654 ID0unlink(pidfile);
655}
656
657struct bundle *
658bundle_Create(const char *prefix, int type, int unit)
659{
660 static struct bundle bundle; /* there can be only one */
661 int enoentcount, err, minunit, maxunit;
662 const char *ifname;
663#if defined(__FreeBSD__) && !defined(NOKLDLOAD)
664 int kldtried;
665#endif
666#if defined(TUNSIFMODE) || defined(TUNSLMODE) || defined(TUNSIFHEAD)
667 int iff;
668#endif
669
670 if (bundle.iface != NULL) { /* Already allocated ! */
671 log_Printf(LogALERT, "bundle_Create: There's only one BUNDLE !\n");
672 return NULL;
673 }
674
675 if (unit == -1) {
676 minunit = 0;
677 maxunit = -1;
678 } else {
679 minunit = unit;
680 maxunit = unit + 1;
681 }
682 err = ENOENT;
683 enoentcount = 0;
684#if defined(__FreeBSD__) && !defined(NOKLDLOAD)
685 kldtried = 0;
686#endif
687 for (bundle.unit = minunit; bundle.unit != maxunit; bundle.unit++) {
688 snprintf(bundle.dev.Name, sizeof bundle.dev.Name, "%s%d",
689 prefix, bundle.unit);
690 bundle.dev.fd = ID0open(bundle.dev.Name, O_RDWR);
691 if (bundle.dev.fd >= 0)
692 break;
693 else if (errno == ENXIO) {
694#if defined(__FreeBSD__) && !defined(NOKLDLOAD)
695 if (bundle.unit == minunit && !kldtried++) {
696 /*
697 * Attempt to load the tunnel interface KLD if it isn't loaded
698 * already.
699 */
700 if (modfind("if_tun") == -1) {
701 if (ID0kldload("if_tun") != -1) {
702 bundle.unit--;
703 continue;
704 }
705 log_Printf(LogWARN, "kldload: if_tun: %s\n", strerror(errno));
706 }
707 }
708#endif
709 err = errno;
710 break;
711 } else if (errno == ENOENT) {
712 if (++enoentcount > 2)
713 break;
714 } else
715 err = errno;
716 }
717
718 if (bundle.dev.fd < 0) {
719 if (unit == -1)
720 log_Printf(LogWARN, "No available tunnel devices found (%s)\n",
721 strerror(err));
722 else
723 log_Printf(LogWARN, "%s%d: %s\n", prefix, unit, strerror(err));
724 return NULL;
725 }
726
727 log_SetTun(bundle.unit);
728
729 ifname = strrchr(bundle.dev.Name, '/');
730 if (ifname == NULL)
731 ifname = bundle.dev.Name;
732 else
733 ifname++;
734
735 bundle.iface = iface_Create(ifname);
736 if (bundle.iface == NULL) {
737 close(bundle.dev.fd);
738 return NULL;
739 }
740
741#ifdef TUNSIFMODE
742 /* Make sure we're POINTOPOINT */
743 iff = IFF_POINTOPOINT;
744 if (ID0ioctl(bundle.dev.fd, TUNSIFMODE, &iff) < 0)
745 log_Printf(LogERROR, "bundle_Create: ioctl(TUNSIFMODE): %s\n",
746 strerror(errno));
747#endif
748
749#ifdef TUNSLMODE
750 /* Make sure we're not prepending sockaddrs */
751 iff = 0;
752 if (ID0ioctl(bundle.dev.fd, TUNSLMODE, &iff) < 0)
753 log_Printf(LogERROR, "bundle_Create: ioctl(TUNSLMODE): %s\n",
754 strerror(errno));
755#endif
756
757#ifdef TUNSIFHEAD
758 /* We want the address family please ! */
759 iff = 1;
760 if (ID0ioctl(bundle.dev.fd, TUNSIFHEAD, &iff) < 0) {
761 log_Printf(LogERROR, "bundle_Create: ioctl(TUNSIFHEAD): %s\n",
762 strerror(errno));
763 bundle.dev.header = 0;
764 } else
765 bundle.dev.header = 1;
766#else
767#ifdef __OpenBSD__
768 /* Always present for OpenBSD */
769 bundle.dev.header = 1;
770#else
771 /*
772 * If TUNSIFHEAD isn't available and we're not OpenBSD, assume
773 * everything's AF_INET (hopefully the tun device won't pass us
774 * anything else !).
775 */
776 bundle.dev.header = 0;
777#endif
778#endif
779
780 if (!iface_SetFlags(bundle.iface, IFF_UP)) {
781 iface_Destroy(bundle.iface);
782 bundle.iface = NULL;
783 close(bundle.dev.fd);
784 return NULL;
785 }
786
787 log_Printf(LogPHASE, "Using interface: %s\n", ifname);
788
789 bundle.bandwidth = 0;
790 bundle.routing_seq = 0;
791 bundle.phase = PHASE_DEAD;
792 bundle.CleaningUp = 0;
793 bundle.NatEnabled = 0;
794
795 bundle.fsm.LayerStart = bundle_LayerStart;
796 bundle.fsm.LayerUp = bundle_LayerUp;
797 bundle.fsm.LayerDown = bundle_LayerDown;
798 bundle.fsm.LayerFinish = bundle_LayerFinish;
799 bundle.fsm.object = &bundle;
800
801 bundle.cfg.idle.timeout = NCP_IDLE_TIMEOUT;
802 bundle.cfg.idle.min_timeout = 0;
803 *bundle.cfg.auth.name = '\0';
804 *bundle.cfg.auth.key = '\0';
805 bundle.cfg.opt = OPT_SROUTES | OPT_IDCHECK | OPT_LOOPBACK |
806 OPT_THROUGHPUT | OPT_UTMP;
807 *bundle.cfg.label = '\0';
808 bundle.cfg.mtu = DEF_MTU;
809 bundle.cfg.choked.timeout = CHOKED_TIMEOUT;
810 bundle.phys_type.all = type;
811 bundle.phys_type.open = 0;
812 bundle.upat = 0;
813
814 bundle.links = datalink_Create("deflink", &bundle, type);
815 if (bundle.links == NULL) {
816 log_Printf(LogALERT, "Cannot create data link: %s\n", strerror(errno));
817 iface_Destroy(bundle.iface);
818 bundle.iface = NULL;
819 close(bundle.dev.fd);
820 return NULL;
821 }
822
823 bundle.desc.type = BUNDLE_DESCRIPTOR;
824 bundle.desc.UpdateSet = bundle_UpdateSet;
825 bundle.desc.IsSet = bundle_IsSet;
826 bundle.desc.Read = bundle_DescriptorRead;
827 bundle.desc.Write = bundle_DescriptorWrite;
828
829 mp_Init(&bundle.ncp.mp, &bundle);
830
831 /* Send over the first physical link by default */
832 ipcp_Init(&bundle.ncp.ipcp, &bundle, &bundle.links->physical->link,
833 &bundle.fsm);
834
835 memset(&bundle.filter, '\0', sizeof bundle.filter);
836 bundle.filter.in.fragok = bundle.filter.in.logok = 1;
837 bundle.filter.in.name = "IN";
838 bundle.filter.out.fragok = bundle.filter.out.logok = 1;
839 bundle.filter.out.name = "OUT";
840 bundle.filter.dial.name = "DIAL";
841 bundle.filter.dial.logok = 1;
842 bundle.filter.alive.name = "ALIVE";
843 bundle.filter.alive.logok = 1;
844 {
845 int i;
846 for (i = 0; i < MAXFILTERS; i++) {
847 bundle.filter.in.rule[i].f_action = A_NONE;
848 bundle.filter.out.rule[i].f_action = A_NONE;
849 bundle.filter.dial.rule[i].f_action = A_NONE;
850 bundle.filter.alive.rule[i].f_action = A_NONE;
851 }
852 }
853 memset(&bundle.idle.timer, '\0', sizeof bundle.idle.timer);
854 bundle.idle.done = 0;
855 bundle.notify.fd = -1;
856 memset(&bundle.choked.timer, '\0', sizeof bundle.choked.timer);
857#ifndef NORADIUS
858 radius_Init(&bundle.radius);
859#endif
860
861 /* Clean out any leftover crud */
862 iface_Clear(bundle.iface, IFACE_CLEAR_ALL);
863
864 bundle_LockTun(&bundle);
865
866 return &bundle;
867}
868
869static void
870bundle_DownInterface(struct bundle *bundle)
871{
872 route_IfDelete(bundle, 1);
873 iface_ClearFlags(bundle->iface, IFF_UP);
874}
875
876void
877bundle_Destroy(struct bundle *bundle)
878{
879 struct datalink *dl;
880
881 /*
882 * Clean up the interface. We don't need to timer_Stop()s, mp_Down(),
883 * ipcp_CleanInterface() and bundle_DownInterface() unless we're getting
884 * out under exceptional conditions such as a descriptor exception.
885 */
886 timer_Stop(&bundle->idle.timer);
887 timer_Stop(&bundle->choked.timer);
888 mp_Down(&bundle->ncp.mp);
889 ipcp_CleanInterface(&bundle->ncp.ipcp);
890 bundle_DownInterface(bundle);
891
892#ifndef NORADIUS
893 /* Tell the radius server the bad news */
894 radius_Destroy(&bundle->radius);
895#endif
896
897 /* Again, these are all DATALINK_CLOSED unless we're abending */
898 dl = bundle->links;
899 while (dl)
900 dl = datalink_Destroy(dl);
901
902 ipcp_Destroy(&bundle->ncp.ipcp);
903
904 close(bundle->dev.fd);
905 bundle_UnlockTun(bundle);
906
907 /* In case we never made PHASE_NETWORK */
908 bundle_Notify(bundle, EX_ERRDEAD);
909
910 iface_Destroy(bundle->iface);
911 bundle->iface = NULL;
912}
913
914struct rtmsg {
915 struct rt_msghdr m_rtm;
916 char m_space[64];
917};
918
919int
920bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst,
921 struct in_addr gateway, struct in_addr mask, int bang, int ssh)
922{
923 struct rtmsg rtmes;
924 int s, nb, wb;
925 char *cp;
926 const char *cmdstr;
927 struct sockaddr_in rtdata;
928 int result = 1;
929
930 if (bang)
931 cmdstr = (cmd == RTM_ADD ? "Add!" : "Delete!");
932 else
933 cmdstr = (cmd == RTM_ADD ? "Add" : "Delete");
934 s = ID0socket(PF_ROUTE, SOCK_RAW, 0);
935 if (s < 0) {
936 log_Printf(LogERROR, "bundle_SetRoute: socket(): %s\n", strerror(errno));
937 return result;
938 }
939 memset(&rtmes, '\0', sizeof rtmes);
940 rtmes.m_rtm.rtm_version = RTM_VERSION;
941 rtmes.m_rtm.rtm_type = cmd;
942 rtmes.m_rtm.rtm_addrs = RTA_DST;
943 rtmes.m_rtm.rtm_seq = ++bundle->routing_seq;
944 rtmes.m_rtm.rtm_pid = getpid();
945 rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
946
947 if (cmd == RTM_ADD || cmd == RTM_CHANGE) {
948 if (bundle->ncp.ipcp.cfg.sendpipe > 0) {
949 rtmes.m_rtm.rtm_rmx.rmx_sendpipe = bundle->ncp.ipcp.cfg.sendpipe;
950 rtmes.m_rtm.rtm_inits |= RTV_SPIPE;
951 }
952 if (bundle->ncp.ipcp.cfg.recvpipe > 0) {
953 rtmes.m_rtm.rtm_rmx.rmx_recvpipe = bundle->ncp.ipcp.cfg.recvpipe;
954 rtmes.m_rtm.rtm_inits |= RTV_RPIPE;
955 }
956 }
957
958 memset(&rtdata, '\0', sizeof rtdata);
959 rtdata.sin_len = sizeof rtdata;
960 rtdata.sin_family = AF_INET;
961 rtdata.sin_port = 0;
962 rtdata.sin_addr = dst;
963
964 cp = rtmes.m_space;
965 memcpy(cp, &rtdata, rtdata.sin_len);
966 cp += rtdata.sin_len;
967 if (cmd == RTM_ADD) {
968 if (gateway.s_addr == INADDR_ANY) {
969 if (!ssh)
970 log_Printf(LogERROR, "bundle_SetRoute: Cannot add a route with"
971 " destination 0.0.0.0\n");
972 close(s);
973 return result;
974 } else {
975 rtdata.sin_addr = gateway;
976 memcpy(cp, &rtdata, rtdata.sin_len);
977 cp += rtdata.sin_len;
978 rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
979 }
980 }
981
982 if (dst.s_addr == INADDR_ANY)
983 mask.s_addr = INADDR_ANY;
984
985 if (cmd == RTM_ADD || dst.s_addr == INADDR_ANY) {
986 rtdata.sin_addr = mask;
987 memcpy(cp, &rtdata, rtdata.sin_len);
988 cp += rtdata.sin_len;
989 rtmes.m_rtm.rtm_addrs |= RTA_NETMASK;
990 }
991
992 nb = cp - (char *) &rtmes;
993 rtmes.m_rtm.rtm_msglen = nb;
994 wb = ID0write(s, &rtmes, nb);
995 if (wb < 0) {
996 log_Printf(LogTCPIP, "bundle_SetRoute failure:\n");
997 log_Printf(LogTCPIP, "bundle_SetRoute: Cmd = %s\n", cmdstr);
998 log_Printf(LogTCPIP, "bundle_SetRoute: Dst = %s\n", inet_ntoa(dst));
999 log_Printf(LogTCPIP, "bundle_SetRoute: Gateway = %s\n",
1000 inet_ntoa(gateway));
1001 log_Printf(LogTCPIP, "bundle_SetRoute: Mask = %s\n", inet_ntoa(mask));
1002failed:
1003 if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST ||
1004 (rtmes.m_rtm.rtm_errno == 0 && errno == EEXIST))) {
1005 if (!bang) {
1006 log_Printf(LogWARN, "Add route failed: %s already exists\n",
1007 dst.s_addr == 0 ? "default" : inet_ntoa(dst));
1008 result = 0; /* Don't add to our dynamic list */
1009 } else {
1010 rtmes.m_rtm.rtm_type = cmd = RTM_CHANGE;
1011 if ((wb = ID0write(s, &rtmes, nb)) < 0)
1012 goto failed;
1013 }
1014 } else if (cmd == RTM_DELETE &&
1015 (rtmes.m_rtm.rtm_errno == ESRCH ||
1016 (rtmes.m_rtm.rtm_errno == 0 && errno == ESRCH))) {
1017 if (!bang)
1018 log_Printf(LogWARN, "Del route failed: %s: Non-existent\n",
1019 inet_ntoa(dst));
1020 } else if (rtmes.m_rtm.rtm_errno == 0) {
1021 if (!ssh || errno != ENETUNREACH)
1022 log_Printf(LogWARN, "%s route failed: %s: errno: %s\n", cmdstr,
1023 inet_ntoa(dst), strerror(errno));
1024 } else
1025 log_Printf(LogWARN, "%s route failed: %s: %s\n",
1026 cmdstr, inet_ntoa(dst), strerror(rtmes.m_rtm.rtm_errno));
1027 }
1028 log_Printf(LogDEBUG, "wrote %d: cmd = %s, dst = %x, gateway = %x\n",
1029 wb, cmdstr, (unsigned)dst.s_addr, (unsigned)gateway.s_addr);
1030 close(s);
1031
1032 return result;
1033}
1034
1035void
1036bundle_LinkClosed(struct bundle *bundle, struct datalink *dl)
1037{
1038 /*
1039 * Our datalink has closed.
1040 * CleanDatalinks() (called from DoLoop()) will remove closed
1041 * BACKGROUND, FOREGROUND and DIRECT links.
1042 * If it's the last data link, enter phase DEAD.
1043 *
1044 * NOTE: dl may not be in our list (bundle_SendDatalink()) !
1045 */
1046
1047 struct datalink *odl;
1048 int other_links;
1049
1050 log_SetTtyCommandMode(dl);
1051
1052 other_links = 0;
1053 for (odl = bundle->links; odl; odl = odl->next)
1054 if (odl != dl && odl->state != DATALINK_CLOSED)
1055 other_links++;
1056
1057 if (!other_links) {
1058 if (dl->physical->type != PHYS_AUTO) /* Not in -auto mode */
1059 bundle_DownInterface(bundle);
1060 fsm2initial(&bundle->ncp.ipcp.fsm);
1061 bundle_NewPhase(bundle, PHASE_DEAD);
1062 bundle_StopIdleTimer(bundle);
1063 }
1064}
1065
1066void
1067bundle_Open(struct bundle *bundle, const char *name, int mask, int force)
1068{
1069 /*
1070 * Please open the given datalink, or all if name == NULL
1071 */
1072 struct datalink *dl;
1073
1074 for (dl = bundle->links; dl; dl = dl->next)
1075 if (name == NULL || !strcasecmp(dl->name, name)) {
1076 if ((mask & dl->physical->type) &&
1077 (dl->state == DATALINK_CLOSED ||
1078 (force && dl->state == DATALINK_OPENING &&
1079 dl->dial.timer.state == TIMER_RUNNING))) {
1080 if (force) /* Ignore redial timeout ? */
1081 timer_Stop(&dl->dial.timer);
1082 datalink_Up(dl, 1, 1);
1083 if (mask & PHYS_AUTO)
1084 /* Only one AUTO link at a time */
1085 break;
1086 }
1087 if (name != NULL)
1088 break;
1089 }
1090}
1091
1092struct datalink *
1093bundle2datalink(struct bundle *bundle, const char *name)
1094{
1095 struct datalink *dl;
1096
1097 if (name != NULL) {
1098 for (dl = bundle->links; dl; dl = dl->next)
1099 if (!strcasecmp(dl->name, name))
1100 return dl;
1101 } else if (bundle->links && !bundle->links->next)
1102 return bundle->links;
1103
1104 return NULL;
1105}
1106
1107int
1108bundle_ShowLinks(struct cmdargs const *arg)
1109{
1110 struct datalink *dl;
1111 struct pppThroughput *t;
1112 int secs;
1113
1114 for (dl = arg->bundle->links; dl; dl = dl->next) {
1115 prompt_Printf(arg->prompt, "Name: %s [%s, %s]",
1116 dl->name, mode2Nam(dl->physical->type), datalink_State(dl));
1117 if (dl->physical->link.throughput.rolling && dl->state == DATALINK_OPEN)
1118 prompt_Printf(arg->prompt, " bandwidth %d, %llu bps (%llu bytes/sec)",
1119 dl->mp.bandwidth ? dl->mp.bandwidth :
1120 physical_GetSpeed(dl->physical),
1121 dl->physical->link.throughput.OctetsPerSecond * 8,
1122 dl->physical->link.throughput.OctetsPerSecond);
1123 prompt_Printf(arg->prompt, "\n");
1124 }
1125
1126 t = &arg->bundle->ncp.mp.link.throughput;
1127 secs = t->downtime ? 0 : throughput_uptime(t);
1128 if (secs > t->SamplePeriod)
1129 secs = t->SamplePeriod;
1130 if (secs)
1131 prompt_Printf(arg->prompt, "Currently averaging %llu bps (%llu bytes/sec)"
1132 " over the last %d secs\n", t->OctetsPerSecond * 8,
1133 t->OctetsPerSecond, secs);
1134
1135 return 0;
1136}
1137
1138static const char *
1139optval(struct bundle *bundle, int bit)
1140{
1141 return (bundle->cfg.opt & bit) ? "enabled" : "disabled";
1142}
1143
1144int
1145bundle_ShowStatus(struct cmdargs const *arg)
1146{
1147 int remaining;
1148
1149 prompt_Printf(arg->prompt, "Phase %s\n", bundle_PhaseName(arg->bundle));
1150 prompt_Printf(arg->prompt, " Device: %s\n", arg->bundle->dev.Name);
1151 prompt_Printf(arg->prompt, " Interface: %s @ %lubps",
1152 arg->bundle->iface->name, arg->bundle->bandwidth);
1153
1154 if (arg->bundle->upat) {
1155 int secs = time(NULL) - arg->bundle->upat;
1156
1157 prompt_Printf(arg->prompt, ", up time %d:%02d:%02d", secs / 3600,
1158 (secs / 60) % 60, secs % 60);
1159 }
1160
1161 prompt_Printf(arg->prompt, "\n\nDefaults:\n");
1162 prompt_Printf(arg->prompt, " Label: %s\n", arg->bundle->cfg.label);
1163 prompt_Printf(arg->prompt, " Auth name: %s\n",
1164 arg->bundle->cfg.auth.name);
1165
1166 prompt_Printf(arg->prompt, " Choked Timer: %ds\n",
1167 arg->bundle->cfg.choked.timeout);
1168
1169#ifndef NORADIUS
1170 radius_Show(&arg->bundle->radius, arg->prompt);
1171#endif
1172
1173 prompt_Printf(arg->prompt, " Idle Timer: ");
1174 if (arg->bundle->cfg.idle.timeout) {
1175 prompt_Printf(arg->prompt, "%ds", arg->bundle->cfg.idle.timeout);
1176 if (arg->bundle->cfg.idle.min_timeout)
1177 prompt_Printf(arg->prompt, ", min %ds",
1178 arg->bundle->cfg.idle.min_timeout);
1179 remaining = bundle_RemainingIdleTime(arg->bundle);
1180 if (remaining != -1)
1181 prompt_Printf(arg->prompt, " (%ds remaining)", remaining);
1182 prompt_Printf(arg->prompt, "\n");
1183 } else
1184 prompt_Printf(arg->prompt, "disabled\n");
1185 prompt_Printf(arg->prompt, " MTU: ");
1186 if (arg->bundle->cfg.mtu)
1187 prompt_Printf(arg->prompt, "%d\n", arg->bundle->cfg.mtu);
1188 else
1189 prompt_Printf(arg->prompt, "unspecified\n");
1190
1191 prompt_Printf(arg->prompt, " sendpipe: ");
1192 if (arg->bundle->ncp.ipcp.cfg.sendpipe > 0)
1193 prompt_Printf(arg->prompt, "%-20ld", arg->bundle->ncp.ipcp.cfg.sendpipe);
1194 else
1195 prompt_Printf(arg->prompt, "unspecified ");
1196 prompt_Printf(arg->prompt, " recvpipe: ");
1197 if (arg->bundle->ncp.ipcp.cfg.recvpipe > 0)
1198 prompt_Printf(arg->prompt, "%ld\n", arg->bundle->ncp.ipcp.cfg.recvpipe);
1199 else
1200 prompt_Printf(arg->prompt, "unspecified\n");
1201
1202 prompt_Printf(arg->prompt, " Sticky Routes: %-20.20s",
1203 optval(arg->bundle, OPT_SROUTES));
1204 prompt_Printf(arg->prompt, " ID check: %s\n",
1205 optval(arg->bundle, OPT_IDCHECK));
1206 prompt_Printf(arg->prompt, " Keep-Session: %-20.20s",
1207 optval(arg->bundle, OPT_KEEPSESSION));
1208 prompt_Printf(arg->prompt, " Loopback: %s\n",
1209 optval(arg->bundle, OPT_LOOPBACK));
1210 prompt_Printf(arg->prompt, " PasswdAuth: %-20.20s",
1211 optval(arg->bundle, OPT_PASSWDAUTH));
1212 prompt_Printf(arg->prompt, " Proxy: %s\n",
1213 optval(arg->bundle, OPT_PROXY));
1214 prompt_Printf(arg->prompt, " Proxyall: %-20.20s",
1215 optval(arg->bundle, OPT_PROXYALL));
1216 prompt_Printf(arg->prompt, " Throughput: %s\n",
1217 optval(arg->bundle, OPT_THROUGHPUT));
1218 prompt_Printf(arg->prompt, " Utmp Logging: %-20.20s",
1219 optval(arg->bundle, OPT_UTMP));
1220 prompt_Printf(arg->prompt, " Iface-Alias: %s\n",
1221 optval(arg->bundle, OPT_IFACEALIAS));
1222
1223 return 0;
1224}
1225
1226static void
1227bundle_IdleTimeout(void *v)
1228{
1229 struct bundle *bundle = (struct bundle *)v;
1230
1223 log_Printf(LogPHASE, "Idle timer expired.\n");
1231 log_Printf(LogPHASE, "Idle timer expired\n");
1224 bundle_StopIdleTimer(bundle);
1225 bundle_Close(bundle, NULL, CLOSE_STAYDOWN);
1226}
1227
1228/*
1229 * Start Idle timer. If timeout is reached, we call bundle_Close() to
1230 * close LCP and link.
1231 */
1232void
1233bundle_StartIdleTimer(struct bundle *bundle)
1234{
1235 timer_Stop(&bundle->idle.timer);
1236 if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) !=
1237 bundle->phys_type.open && bundle->cfg.idle.timeout) {
1238 int secs;
1239
1240 secs = bundle->cfg.idle.timeout;
1241 if (bundle->cfg.idle.min_timeout > secs && bundle->upat) {
1242 int up = time(NULL) - bundle->upat;
1243
1244 if ((long long)bundle->cfg.idle.min_timeout - up > (long long)secs)
1245 secs = bundle->cfg.idle.min_timeout - up;
1246 }
1247 bundle->idle.timer.func = bundle_IdleTimeout;
1248 bundle->idle.timer.name = "idle";
1249 bundle->idle.timer.load = secs * SECTICKS;
1250 bundle->idle.timer.arg = bundle;
1251 timer_Start(&bundle->idle.timer);
1252 bundle->idle.done = time(NULL) + secs;
1253 }
1254}
1255
1256void
1257bundle_SetIdleTimer(struct bundle *bundle, int timeout, int min_timeout)
1258{
1259 bundle->cfg.idle.timeout = timeout;
1260 if (min_timeout >= 0)
1261 bundle->cfg.idle.min_timeout = min_timeout;
1262 if (bundle_LinkIsUp(bundle))
1263 bundle_StartIdleTimer(bundle);
1264}
1265
1266void
1267bundle_StopIdleTimer(struct bundle *bundle)
1268{
1269 timer_Stop(&bundle->idle.timer);
1270 bundle->idle.done = 0;
1271}
1272
1273static int
1274bundle_RemainingIdleTime(struct bundle *bundle)
1275{
1276 if (bundle->idle.done)
1277 return bundle->idle.done - time(NULL);
1278 return -1;
1279}
1280
1281int
1282bundle_IsDead(struct bundle *bundle)
1283{
1284 return !bundle->links || (bundle->phase == PHASE_DEAD && bundle->CleaningUp);
1285}
1286
1287static struct datalink *
1288bundle_DatalinkLinkout(struct bundle *bundle, struct datalink *dl)
1289{
1290 struct datalink **dlp;
1291
1292 for (dlp = &bundle->links; *dlp; dlp = &(*dlp)->next)
1293 if (*dlp == dl) {
1294 *dlp = dl->next;
1295 dl->next = NULL;
1296 bundle_LinksRemoved(bundle);
1297 return dl;
1298 }
1299
1300 return NULL;
1301}
1302
1303static void
1304bundle_DatalinkLinkin(struct bundle *bundle, struct datalink *dl)
1305{
1306 struct datalink **dlp = &bundle->links;
1307
1308 while (*dlp)
1309 dlp = &(*dlp)->next;
1310
1311 *dlp = dl;
1312 dl->next = NULL;
1313
1314 bundle_LinkAdded(bundle, dl);
1315 mp_CheckAutoloadTimer(&bundle->ncp.mp);
1316}
1317
1318void
1319bundle_CleanDatalinks(struct bundle *bundle)
1320{
1321 struct datalink **dlp = &bundle->links;
1322 int found = 0;
1323
1324 while (*dlp)
1325 if ((*dlp)->state == DATALINK_CLOSED &&
1326 (*dlp)->physical->type &
1327 (PHYS_DIRECT|PHYS_BACKGROUND|PHYS_FOREGROUND)) {
1328 *dlp = datalink_Destroy(*dlp);
1329 found++;
1330 } else
1331 dlp = &(*dlp)->next;
1332
1333 if (found)
1334 bundle_LinksRemoved(bundle);
1335}
1336
1337int
1338bundle_DatalinkClone(struct bundle *bundle, struct datalink *dl,
1339 const char *name)
1340{
1341 if (bundle2datalink(bundle, name)) {
1342 log_Printf(LogWARN, "Clone: %s: name already exists\n", name);
1343 return 0;
1344 }
1345
1346 bundle_DatalinkLinkin(bundle, datalink_Clone(dl, name));
1347 return 1;
1348}
1349
1350void
1351bundle_DatalinkRemove(struct bundle *bundle, struct datalink *dl)
1352{
1353 dl = bundle_DatalinkLinkout(bundle, dl);
1354 if (dl)
1355 datalink_Destroy(dl);
1356}
1357
1358void
1359bundle_SetLabel(struct bundle *bundle, const char *label)
1360{
1361 if (label)
1362 strncpy(bundle->cfg.label, label, sizeof bundle->cfg.label - 1);
1363 else
1364 *bundle->cfg.label = '\0';
1365}
1366
1367const char *
1368bundle_GetLabel(struct bundle *bundle)
1369{
1370 return *bundle->cfg.label ? bundle->cfg.label : NULL;
1371}
1372
1373int
1374bundle_LinkSize()
1375{
1376 struct iovec iov[SCATTER_SEGMENTS];
1377 int niov, expect, f;
1378
1379 iov[0].iov_len = strlen(Version) + 1;
1380 iov[0].iov_base = NULL;
1381 niov = 1;
1382 if (datalink2iov(NULL, iov, &niov, SCATTER_SEGMENTS, NULL, NULL) == -1) {
1383 log_Printf(LogERROR, "Cannot determine space required for link\n");
1384 return 0;
1385 }
1386
1387 for (f = expect = 0; f < niov; f++)
1388 expect += iov[f].iov_len;
1389
1390 return expect;
1391}
1392
1393void
1394bundle_ReceiveDatalink(struct bundle *bundle, int s)
1395{
1396 char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int) * SEND_MAXFD];
1397 int niov, expect, f, *fd, nfd, onfd, got;
1398 struct iovec iov[SCATTER_SEGMENTS];
1399 struct cmsghdr *cmsg;
1400 struct msghdr msg;
1401 struct datalink *dl;
1402 pid_t pid;
1403
1404 log_Printf(LogPHASE, "Receiving datalink\n");
1405
1406 /*
1407 * Create our scatter/gather array - passing NULL gets the space
1408 * allocation requirement rather than actually flattening the
1409 * structures.
1410 */
1411 iov[0].iov_len = strlen(Version) + 1;
1412 iov[0].iov_base = NULL;
1413 niov = 1;
1414 if (datalink2iov(NULL, iov, &niov, SCATTER_SEGMENTS, NULL, NULL) == -1) {
1415 log_Printf(LogERROR, "Cannot determine space required for link\n");
1416 return;
1417 }
1418
1419 /* Allocate the scatter/gather array for recvmsg() */
1420 for (f = expect = 0; f < niov; f++) {
1421 if ((iov[f].iov_base = malloc(iov[f].iov_len)) == NULL) {
1422 log_Printf(LogERROR, "Cannot allocate space to receive link\n");
1423 return;
1424 }
1425 if (f)
1426 expect += iov[f].iov_len;
1427 }
1428
1429 /* Set up our message */
1430 cmsg = (struct cmsghdr *)cmsgbuf;
1431 cmsg->cmsg_len = sizeof cmsgbuf;
1432 cmsg->cmsg_level = SOL_SOCKET;
1433 cmsg->cmsg_type = 0;
1434
1435 memset(&msg, '\0', sizeof msg);
1436 msg.msg_name = NULL;
1437 msg.msg_namelen = 0;
1438 msg.msg_iov = iov;
1439 msg.msg_iovlen = 1; /* Only send the version at the first pass */
1440 msg.msg_control = cmsgbuf;
1441 msg.msg_controllen = sizeof cmsgbuf;
1442
1443 log_Printf(LogDEBUG, "Expecting %u scatter/gather bytes\n",
1444 (unsigned)iov[0].iov_len);
1445
1446 if ((got = recvmsg(s, &msg, MSG_WAITALL)) != iov[0].iov_len) {
1447 if (got == -1)
1448 log_Printf(LogERROR, "Failed recvmsg: %s\n", strerror(errno));
1449 else
1450 log_Printf(LogERROR, "Failed recvmsg: Got %d, not %u\n",
1451 got, (unsigned)iov[0].iov_len);
1452 while (niov--)
1453 free(iov[niov].iov_base);
1454 return;
1455 }
1456
1457 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1458 log_Printf(LogERROR, "Recvmsg: no descriptors received !\n");
1459 while (niov--)
1460 free(iov[niov].iov_base);
1461 return;
1462 }
1463
1464 fd = (int *)(cmsg + 1);
1465 nfd = (cmsg->cmsg_len - sizeof *cmsg) / sizeof(int);
1466
1467 if (nfd < 2) {
1468 log_Printf(LogERROR, "Recvmsg: %d descriptor%s received (too few) !\n",
1469 nfd, nfd == 1 ? "" : "s");
1470 while (nfd--)
1471 close(fd[nfd]);
1472 while (niov--)
1473 free(iov[niov].iov_base);
1474 return;
1475 }
1476
1477 /*
1478 * We've successfully received two or more open file descriptors
1479 * through our socket, plus a version string. Make sure it's the
1480 * correct version, and drop the connection if it's not.
1481 */
1482 if (strncmp(Version, iov[0].iov_base, iov[0].iov_len)) {
1483 log_Printf(LogWARN, "Cannot receive datalink, incorrect version"
1484 " (\"%.*s\", not \"%s\")\n", (int)iov[0].iov_len,
1485 (char *)iov[0].iov_base, Version);
1486 while (nfd--)
1487 close(fd[nfd]);
1488 while (niov--)
1489 free(iov[niov].iov_base);
1490 return;
1491 }
1492
1493 /*
1494 * Everything looks good. Send the other side our process id so that
1495 * they can transfer lock ownership, and wait for them to send the
1496 * actual link data.
1497 */
1498 pid = getpid();
1499 if ((got = write(fd[1], &pid, sizeof pid)) != sizeof pid) {
1500 if (got == -1)
1501 log_Printf(LogERROR, "Failed write: %s\n", strerror(errno));
1502 else
1503 log_Printf(LogERROR, "Failed write: Got %d, not %d\n", got,
1504 (int)(sizeof pid));
1505 while (nfd--)
1506 close(fd[nfd]);
1507 while (niov--)
1508 free(iov[niov].iov_base);
1509 return;
1510 }
1511
1512 if ((got = readv(fd[1], iov + 1, niov - 1)) != expect) {
1513 if (got == -1)
1514 log_Printf(LogERROR, "Failed write: %s\n", strerror(errno));
1515 else
1516 log_Printf(LogERROR, "Failed write: Got %d, not %d\n", got, expect);
1517 while (nfd--)
1518 close(fd[nfd]);
1519 while (niov--)
1520 free(iov[niov].iov_base);
1521 return;
1522 }
1523 close(fd[1]);
1524
1525 onfd = nfd; /* We've got this many in our array */
1526 nfd -= 2; /* Don't include p->fd and our reply descriptor */
1527 niov = 1; /* Skip the version id */
1528 dl = iov2datalink(bundle, iov, &niov, sizeof iov / sizeof *iov, fd[0],
1529 fd + 2, &nfd);
1530 if (dl) {
1531
1532 if (nfd) {
1533 log_Printf(LogERROR, "bundle_ReceiveDatalink: Failed to handle %d "
1534 "auxiliary file descriptors (%d remain)\n", onfd, nfd);
1535 datalink_Destroy(dl);
1536 while (nfd--)
1537 close(fd[onfd--]);
1538 close(fd[0]);
1539 } else {
1540 bundle_DatalinkLinkin(bundle, dl);
1541 datalink_AuthOk(dl);
1542 bundle_CalculateBandwidth(dl->bundle);
1543 }
1544 } else {
1545 while (nfd--)
1546 close(fd[onfd--]);
1547 close(fd[0]);
1548 close(fd[1]);
1549 }
1550
1551 free(iov[0].iov_base);
1552}
1553
1554void
1555bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun)
1556{
1557 char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int) * SEND_MAXFD];
1558 const char *constlock;
1559 char *lock;
1560 struct cmsghdr *cmsg;
1561 struct msghdr msg;
1562 struct iovec iov[SCATTER_SEGMENTS];
1563 int niov, f, expect, newsid, fd[SEND_MAXFD], nfd, reply[2], got;
1564 pid_t newpid;
1565
1566 log_Printf(LogPHASE, "Transmitting datalink %s\n", dl->name);
1567
1568 /* Record the base device name for a lock transfer later */
1569 constlock = physical_LockedDevice(dl->physical);
1570 if (constlock) {
1571 lock = alloca(strlen(constlock) + 1);
1572 strcpy(lock, constlock);
1573 } else
1574 lock = NULL;
1575
1576 bundle_LinkClosed(dl->bundle, dl);
1577 bundle_DatalinkLinkout(dl->bundle, dl);
1578
1579 /* Build our scatter/gather array */
1580 iov[0].iov_len = strlen(Version) + 1;
1581 iov[0].iov_base = strdup(Version);
1582 niov = 1;
1583 nfd = 0;
1584
1585 fd[0] = datalink2iov(dl, iov, &niov, SCATTER_SEGMENTS, fd + 2, &nfd);
1586
1587 if (fd[0] != -1 && socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, reply) != -1) {
1588 /*
1589 * fd[1] is used to get the peer process id back, then to confirm that
1590 * we've transferred any device locks to that process id.
1591 */
1592 fd[1] = reply[1];
1593
1594 nfd += 2; /* Include fd[0] and fd[1] */
1595 memset(&msg, '\0', sizeof msg);
1596
1597 msg.msg_name = NULL;
1598 msg.msg_namelen = 0;
1599 /*
1600 * Only send the version to start... We used to send the whole lot, but
1601 * this caused problems with our RECVBUF size as a single link is about
1602 * 22k ! This way, we should bump into no limits.
1603 */
1604 msg.msg_iovlen = 1;
1605 msg.msg_iov = iov;
1606 msg.msg_control = cmsgbuf;
1607 msg.msg_controllen = sizeof *cmsg + sizeof(int) * nfd;
1608 msg.msg_flags = 0;
1609
1610 cmsg = (struct cmsghdr *)cmsgbuf;
1611 cmsg->cmsg_len = msg.msg_controllen;
1612 cmsg->cmsg_level = SOL_SOCKET;
1613 cmsg->cmsg_type = SCM_RIGHTS;
1614
1615 for (f = 0; f < nfd; f++)
1616 *((int *)(cmsg + 1) + f) = fd[f];
1617
1618 for (f = 1, expect = 0; f < niov; f++)
1619 expect += iov[f].iov_len;
1620
1621 if (setsockopt(reply[0], SOL_SOCKET, SO_SNDBUF, &expect, sizeof(int)) == -1)
1622 log_Printf(LogERROR, "setsockopt(SO_RCVBUF, %d): %s\n", expect,
1623 strerror(errno));
1624 if (setsockopt(reply[1], SOL_SOCKET, SO_RCVBUF, &expect, sizeof(int)) == -1)
1625 log_Printf(LogERROR, "setsockopt(SO_RCVBUF, %d): %s\n", expect,
1626 strerror(errno));
1627
1628 log_Printf(LogDEBUG, "Sending %d descriptor%s and %u bytes in scatter"
1629 "/gather array\n", nfd, nfd == 1 ? "" : "s",
1630 (unsigned)iov[0].iov_len);
1631
1632 if ((got = sendmsg(s, &msg, 0)) == -1)
1633 log_Printf(LogERROR, "Failed sendmsg: %s: %s\n",
1634 sun->sun_path, strerror(errno));
1635 else if (got != iov[0].iov_len)
1636 log_Printf(LogERROR, "%s: Failed initial sendmsg: Only sent %d of %u\n",
1637 sun->sun_path, got, (unsigned)iov[0].iov_len);
1638 else {
1639 /* We must get the ACK before closing the descriptor ! */
1640 int res;
1641
1642 if ((got = read(reply[0], &newpid, sizeof newpid)) == sizeof newpid) {
1643 log_Printf(LogDEBUG, "Received confirmation from pid %d\n",
1644 (int)newpid);
1645 if (lock && (res = ID0uu_lock_txfr(lock, newpid)) != UU_LOCK_OK)
1232 bundle_StopIdleTimer(bundle);
1233 bundle_Close(bundle, NULL, CLOSE_STAYDOWN);
1234}
1235
1236/*
1237 * Start Idle timer. If timeout is reached, we call bundle_Close() to
1238 * close LCP and link.
1239 */
1240void
1241bundle_StartIdleTimer(struct bundle *bundle)
1242{
1243 timer_Stop(&bundle->idle.timer);
1244 if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) !=
1245 bundle->phys_type.open && bundle->cfg.idle.timeout) {
1246 int secs;
1247
1248 secs = bundle->cfg.idle.timeout;
1249 if (bundle->cfg.idle.min_timeout > secs && bundle->upat) {
1250 int up = time(NULL) - bundle->upat;
1251
1252 if ((long long)bundle->cfg.idle.min_timeout - up > (long long)secs)
1253 secs = bundle->cfg.idle.min_timeout - up;
1254 }
1255 bundle->idle.timer.func = bundle_IdleTimeout;
1256 bundle->idle.timer.name = "idle";
1257 bundle->idle.timer.load = secs * SECTICKS;
1258 bundle->idle.timer.arg = bundle;
1259 timer_Start(&bundle->idle.timer);
1260 bundle->idle.done = time(NULL) + secs;
1261 }
1262}
1263
1264void
1265bundle_SetIdleTimer(struct bundle *bundle, int timeout, int min_timeout)
1266{
1267 bundle->cfg.idle.timeout = timeout;
1268 if (min_timeout >= 0)
1269 bundle->cfg.idle.min_timeout = min_timeout;
1270 if (bundle_LinkIsUp(bundle))
1271 bundle_StartIdleTimer(bundle);
1272}
1273
1274void
1275bundle_StopIdleTimer(struct bundle *bundle)
1276{
1277 timer_Stop(&bundle->idle.timer);
1278 bundle->idle.done = 0;
1279}
1280
1281static int
1282bundle_RemainingIdleTime(struct bundle *bundle)
1283{
1284 if (bundle->idle.done)
1285 return bundle->idle.done - time(NULL);
1286 return -1;
1287}
1288
1289int
1290bundle_IsDead(struct bundle *bundle)
1291{
1292 return !bundle->links || (bundle->phase == PHASE_DEAD && bundle->CleaningUp);
1293}
1294
1295static struct datalink *
1296bundle_DatalinkLinkout(struct bundle *bundle, struct datalink *dl)
1297{
1298 struct datalink **dlp;
1299
1300 for (dlp = &bundle->links; *dlp; dlp = &(*dlp)->next)
1301 if (*dlp == dl) {
1302 *dlp = dl->next;
1303 dl->next = NULL;
1304 bundle_LinksRemoved(bundle);
1305 return dl;
1306 }
1307
1308 return NULL;
1309}
1310
1311static void
1312bundle_DatalinkLinkin(struct bundle *bundle, struct datalink *dl)
1313{
1314 struct datalink **dlp = &bundle->links;
1315
1316 while (*dlp)
1317 dlp = &(*dlp)->next;
1318
1319 *dlp = dl;
1320 dl->next = NULL;
1321
1322 bundle_LinkAdded(bundle, dl);
1323 mp_CheckAutoloadTimer(&bundle->ncp.mp);
1324}
1325
1326void
1327bundle_CleanDatalinks(struct bundle *bundle)
1328{
1329 struct datalink **dlp = &bundle->links;
1330 int found = 0;
1331
1332 while (*dlp)
1333 if ((*dlp)->state == DATALINK_CLOSED &&
1334 (*dlp)->physical->type &
1335 (PHYS_DIRECT|PHYS_BACKGROUND|PHYS_FOREGROUND)) {
1336 *dlp = datalink_Destroy(*dlp);
1337 found++;
1338 } else
1339 dlp = &(*dlp)->next;
1340
1341 if (found)
1342 bundle_LinksRemoved(bundle);
1343}
1344
1345int
1346bundle_DatalinkClone(struct bundle *bundle, struct datalink *dl,
1347 const char *name)
1348{
1349 if (bundle2datalink(bundle, name)) {
1350 log_Printf(LogWARN, "Clone: %s: name already exists\n", name);
1351 return 0;
1352 }
1353
1354 bundle_DatalinkLinkin(bundle, datalink_Clone(dl, name));
1355 return 1;
1356}
1357
1358void
1359bundle_DatalinkRemove(struct bundle *bundle, struct datalink *dl)
1360{
1361 dl = bundle_DatalinkLinkout(bundle, dl);
1362 if (dl)
1363 datalink_Destroy(dl);
1364}
1365
1366void
1367bundle_SetLabel(struct bundle *bundle, const char *label)
1368{
1369 if (label)
1370 strncpy(bundle->cfg.label, label, sizeof bundle->cfg.label - 1);
1371 else
1372 *bundle->cfg.label = '\0';
1373}
1374
1375const char *
1376bundle_GetLabel(struct bundle *bundle)
1377{
1378 return *bundle->cfg.label ? bundle->cfg.label : NULL;
1379}
1380
1381int
1382bundle_LinkSize()
1383{
1384 struct iovec iov[SCATTER_SEGMENTS];
1385 int niov, expect, f;
1386
1387 iov[0].iov_len = strlen(Version) + 1;
1388 iov[0].iov_base = NULL;
1389 niov = 1;
1390 if (datalink2iov(NULL, iov, &niov, SCATTER_SEGMENTS, NULL, NULL) == -1) {
1391 log_Printf(LogERROR, "Cannot determine space required for link\n");
1392 return 0;
1393 }
1394
1395 for (f = expect = 0; f < niov; f++)
1396 expect += iov[f].iov_len;
1397
1398 return expect;
1399}
1400
1401void
1402bundle_ReceiveDatalink(struct bundle *bundle, int s)
1403{
1404 char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int) * SEND_MAXFD];
1405 int niov, expect, f, *fd, nfd, onfd, got;
1406 struct iovec iov[SCATTER_SEGMENTS];
1407 struct cmsghdr *cmsg;
1408 struct msghdr msg;
1409 struct datalink *dl;
1410 pid_t pid;
1411
1412 log_Printf(LogPHASE, "Receiving datalink\n");
1413
1414 /*
1415 * Create our scatter/gather array - passing NULL gets the space
1416 * allocation requirement rather than actually flattening the
1417 * structures.
1418 */
1419 iov[0].iov_len = strlen(Version) + 1;
1420 iov[0].iov_base = NULL;
1421 niov = 1;
1422 if (datalink2iov(NULL, iov, &niov, SCATTER_SEGMENTS, NULL, NULL) == -1) {
1423 log_Printf(LogERROR, "Cannot determine space required for link\n");
1424 return;
1425 }
1426
1427 /* Allocate the scatter/gather array for recvmsg() */
1428 for (f = expect = 0; f < niov; f++) {
1429 if ((iov[f].iov_base = malloc(iov[f].iov_len)) == NULL) {
1430 log_Printf(LogERROR, "Cannot allocate space to receive link\n");
1431 return;
1432 }
1433 if (f)
1434 expect += iov[f].iov_len;
1435 }
1436
1437 /* Set up our message */
1438 cmsg = (struct cmsghdr *)cmsgbuf;
1439 cmsg->cmsg_len = sizeof cmsgbuf;
1440 cmsg->cmsg_level = SOL_SOCKET;
1441 cmsg->cmsg_type = 0;
1442
1443 memset(&msg, '\0', sizeof msg);
1444 msg.msg_name = NULL;
1445 msg.msg_namelen = 0;
1446 msg.msg_iov = iov;
1447 msg.msg_iovlen = 1; /* Only send the version at the first pass */
1448 msg.msg_control = cmsgbuf;
1449 msg.msg_controllen = sizeof cmsgbuf;
1450
1451 log_Printf(LogDEBUG, "Expecting %u scatter/gather bytes\n",
1452 (unsigned)iov[0].iov_len);
1453
1454 if ((got = recvmsg(s, &msg, MSG_WAITALL)) != iov[0].iov_len) {
1455 if (got == -1)
1456 log_Printf(LogERROR, "Failed recvmsg: %s\n", strerror(errno));
1457 else
1458 log_Printf(LogERROR, "Failed recvmsg: Got %d, not %u\n",
1459 got, (unsigned)iov[0].iov_len);
1460 while (niov--)
1461 free(iov[niov].iov_base);
1462 return;
1463 }
1464
1465 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1466 log_Printf(LogERROR, "Recvmsg: no descriptors received !\n");
1467 while (niov--)
1468 free(iov[niov].iov_base);
1469 return;
1470 }
1471
1472 fd = (int *)(cmsg + 1);
1473 nfd = (cmsg->cmsg_len - sizeof *cmsg) / sizeof(int);
1474
1475 if (nfd < 2) {
1476 log_Printf(LogERROR, "Recvmsg: %d descriptor%s received (too few) !\n",
1477 nfd, nfd == 1 ? "" : "s");
1478 while (nfd--)
1479 close(fd[nfd]);
1480 while (niov--)
1481 free(iov[niov].iov_base);
1482 return;
1483 }
1484
1485 /*
1486 * We've successfully received two or more open file descriptors
1487 * through our socket, plus a version string. Make sure it's the
1488 * correct version, and drop the connection if it's not.
1489 */
1490 if (strncmp(Version, iov[0].iov_base, iov[0].iov_len)) {
1491 log_Printf(LogWARN, "Cannot receive datalink, incorrect version"
1492 " (\"%.*s\", not \"%s\")\n", (int)iov[0].iov_len,
1493 (char *)iov[0].iov_base, Version);
1494 while (nfd--)
1495 close(fd[nfd]);
1496 while (niov--)
1497 free(iov[niov].iov_base);
1498 return;
1499 }
1500
1501 /*
1502 * Everything looks good. Send the other side our process id so that
1503 * they can transfer lock ownership, and wait for them to send the
1504 * actual link data.
1505 */
1506 pid = getpid();
1507 if ((got = write(fd[1], &pid, sizeof pid)) != sizeof pid) {
1508 if (got == -1)
1509 log_Printf(LogERROR, "Failed write: %s\n", strerror(errno));
1510 else
1511 log_Printf(LogERROR, "Failed write: Got %d, not %d\n", got,
1512 (int)(sizeof pid));
1513 while (nfd--)
1514 close(fd[nfd]);
1515 while (niov--)
1516 free(iov[niov].iov_base);
1517 return;
1518 }
1519
1520 if ((got = readv(fd[1], iov + 1, niov - 1)) != expect) {
1521 if (got == -1)
1522 log_Printf(LogERROR, "Failed write: %s\n", strerror(errno));
1523 else
1524 log_Printf(LogERROR, "Failed write: Got %d, not %d\n", got, expect);
1525 while (nfd--)
1526 close(fd[nfd]);
1527 while (niov--)
1528 free(iov[niov].iov_base);
1529 return;
1530 }
1531 close(fd[1]);
1532
1533 onfd = nfd; /* We've got this many in our array */
1534 nfd -= 2; /* Don't include p->fd and our reply descriptor */
1535 niov = 1; /* Skip the version id */
1536 dl = iov2datalink(bundle, iov, &niov, sizeof iov / sizeof *iov, fd[0],
1537 fd + 2, &nfd);
1538 if (dl) {
1539
1540 if (nfd) {
1541 log_Printf(LogERROR, "bundle_ReceiveDatalink: Failed to handle %d "
1542 "auxiliary file descriptors (%d remain)\n", onfd, nfd);
1543 datalink_Destroy(dl);
1544 while (nfd--)
1545 close(fd[onfd--]);
1546 close(fd[0]);
1547 } else {
1548 bundle_DatalinkLinkin(bundle, dl);
1549 datalink_AuthOk(dl);
1550 bundle_CalculateBandwidth(dl->bundle);
1551 }
1552 } else {
1553 while (nfd--)
1554 close(fd[onfd--]);
1555 close(fd[0]);
1556 close(fd[1]);
1557 }
1558
1559 free(iov[0].iov_base);
1560}
1561
1562void
1563bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun)
1564{
1565 char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int) * SEND_MAXFD];
1566 const char *constlock;
1567 char *lock;
1568 struct cmsghdr *cmsg;
1569 struct msghdr msg;
1570 struct iovec iov[SCATTER_SEGMENTS];
1571 int niov, f, expect, newsid, fd[SEND_MAXFD], nfd, reply[2], got;
1572 pid_t newpid;
1573
1574 log_Printf(LogPHASE, "Transmitting datalink %s\n", dl->name);
1575
1576 /* Record the base device name for a lock transfer later */
1577 constlock = physical_LockedDevice(dl->physical);
1578 if (constlock) {
1579 lock = alloca(strlen(constlock) + 1);
1580 strcpy(lock, constlock);
1581 } else
1582 lock = NULL;
1583
1584 bundle_LinkClosed(dl->bundle, dl);
1585 bundle_DatalinkLinkout(dl->bundle, dl);
1586
1587 /* Build our scatter/gather array */
1588 iov[0].iov_len = strlen(Version) + 1;
1589 iov[0].iov_base = strdup(Version);
1590 niov = 1;
1591 nfd = 0;
1592
1593 fd[0] = datalink2iov(dl, iov, &niov, SCATTER_SEGMENTS, fd + 2, &nfd);
1594
1595 if (fd[0] != -1 && socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, reply) != -1) {
1596 /*
1597 * fd[1] is used to get the peer process id back, then to confirm that
1598 * we've transferred any device locks to that process id.
1599 */
1600 fd[1] = reply[1];
1601
1602 nfd += 2; /* Include fd[0] and fd[1] */
1603 memset(&msg, '\0', sizeof msg);
1604
1605 msg.msg_name = NULL;
1606 msg.msg_namelen = 0;
1607 /*
1608 * Only send the version to start... We used to send the whole lot, but
1609 * this caused problems with our RECVBUF size as a single link is about
1610 * 22k ! This way, we should bump into no limits.
1611 */
1612 msg.msg_iovlen = 1;
1613 msg.msg_iov = iov;
1614 msg.msg_control = cmsgbuf;
1615 msg.msg_controllen = sizeof *cmsg + sizeof(int) * nfd;
1616 msg.msg_flags = 0;
1617
1618 cmsg = (struct cmsghdr *)cmsgbuf;
1619 cmsg->cmsg_len = msg.msg_controllen;
1620 cmsg->cmsg_level = SOL_SOCKET;
1621 cmsg->cmsg_type = SCM_RIGHTS;
1622
1623 for (f = 0; f < nfd; f++)
1624 *((int *)(cmsg + 1) + f) = fd[f];
1625
1626 for (f = 1, expect = 0; f < niov; f++)
1627 expect += iov[f].iov_len;
1628
1629 if (setsockopt(reply[0], SOL_SOCKET, SO_SNDBUF, &expect, sizeof(int)) == -1)
1630 log_Printf(LogERROR, "setsockopt(SO_RCVBUF, %d): %s\n", expect,
1631 strerror(errno));
1632 if (setsockopt(reply[1], SOL_SOCKET, SO_RCVBUF, &expect, sizeof(int)) == -1)
1633 log_Printf(LogERROR, "setsockopt(SO_RCVBUF, %d): %s\n", expect,
1634 strerror(errno));
1635
1636 log_Printf(LogDEBUG, "Sending %d descriptor%s and %u bytes in scatter"
1637 "/gather array\n", nfd, nfd == 1 ? "" : "s",
1638 (unsigned)iov[0].iov_len);
1639
1640 if ((got = sendmsg(s, &msg, 0)) == -1)
1641 log_Printf(LogERROR, "Failed sendmsg: %s: %s\n",
1642 sun->sun_path, strerror(errno));
1643 else if (got != iov[0].iov_len)
1644 log_Printf(LogERROR, "%s: Failed initial sendmsg: Only sent %d of %u\n",
1645 sun->sun_path, got, (unsigned)iov[0].iov_len);
1646 else {
1647 /* We must get the ACK before closing the descriptor ! */
1648 int res;
1649
1650 if ((got = read(reply[0], &newpid, sizeof newpid)) == sizeof newpid) {
1651 log_Printf(LogDEBUG, "Received confirmation from pid %d\n",
1652 (int)newpid);
1653 if (lock && (res = ID0uu_lock_txfr(lock, newpid)) != UU_LOCK_OK)
1646 log_Printf(LogPHASE, "uu_lock_txfr: %s\n", uu_lockerr(res));
1654 log_Printf(LogERROR, "uu_lock_txfr: %s\n", uu_lockerr(res));
1647
1648 log_Printf(LogDEBUG, "Transmitting link (%d bytes)\n", expect);
1649 if ((got = writev(reply[0], iov + 1, niov - 1)) != expect) {
1650 if (got == -1)
1651 log_Printf(LogERROR, "%s: Failed writev: %s\n",
1652 sun->sun_path, strerror(errno));
1653 else
1654 log_Printf(LogERROR, "%s: Failed writev: Wrote %d of %d\n",
1655 sun->sun_path, got, expect);
1656 }
1657 } else if (got == -1)
1658 log_Printf(LogERROR, "%s: Failed socketpair read: %s\n",
1659 sun->sun_path, strerror(errno));
1660 else
1661 log_Printf(LogERROR, "%s: Failed socketpair read: Got %d of %d\n",
1662 sun->sun_path, got, (int)(sizeof newpid));
1663 }
1664
1665 close(reply[0]);
1666 close(reply[1]);
1667
1668 newsid = Enabled(dl->bundle, OPT_KEEPSESSION) ||
1669 tcgetpgrp(fd[0]) == getpgrp();
1670 while (nfd)
1671 close(fd[--nfd]);
1672 if (newsid)
1673 bundle_setsid(dl->bundle, got != -1);
1674 }
1675 close(s);
1676
1677 while (niov--)
1678 free(iov[niov].iov_base);
1679}
1680
1681int
1682bundle_RenameDatalink(struct bundle *bundle, struct datalink *ndl,
1683 const char *name)
1684{
1685 struct datalink *dl;
1686
1687 if (!strcasecmp(ndl->name, name))
1688 return 1;
1689
1690 for (dl = bundle->links; dl; dl = dl->next)
1691 if (!strcasecmp(dl->name, name))
1692 return 0;
1693
1694 datalink_Rename(ndl, name);
1695 return 1;
1696}
1697
1698int
1699bundle_SetMode(struct bundle *bundle, struct datalink *dl, int mode)
1700{
1701 int omode;
1702
1703 omode = dl->physical->type;
1704 if (omode == mode)
1705 return 1;
1706
1707 if (mode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO))
1708 /* First auto link */
1709 if (bundle->ncp.ipcp.peer_ip.s_addr == INADDR_ANY) {
1710 log_Printf(LogWARN, "You must `set ifaddr' or `open' before"
1711 " changing mode to %s\n", mode2Nam(mode));
1712 return 0;
1713 }
1714
1715 if (!datalink_SetMode(dl, mode))
1716 return 0;
1717
1718 if (mode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO) &&
1719 bundle->phase != PHASE_NETWORK)
1720 /* First auto link, we need an interface */
1721 ipcp_InterfaceUp(&bundle->ncp.ipcp);
1722
1723 /* Regenerate phys_type and adjust idle timer */
1724 bundle_LinksRemoved(bundle);
1725
1726 return 1;
1727}
1728
1729void
1730bundle_setsid(struct bundle *bundle, int holdsession)
1731{
1732 /*
1733 * Lose the current session. This means getting rid of our pid
1734 * too so that the tty device will really go away, and any getty
1735 * etc will be allowed to restart.
1736 */
1737 pid_t pid, orig;
1738 int fds[2];
1739 char done;
1740 struct datalink *dl;
1741
1742 if (!holdsession && bundle_IsDead(bundle)) {
1743 /*
1744 * No need to lose our session after all... we're going away anyway
1745 *
1746 * We should really stop the timer and pause if holdsession is set and
1747 * the bundle's dead, but that leaves other resources lying about :-(
1748 */
1749 return;
1750 }
1751
1752 orig = getpid();
1753 if (pipe(fds) == -1) {
1754 log_Printf(LogERROR, "pipe: %s\n", strerror(errno));
1755 return;
1756 }
1757 switch ((pid = fork())) {
1758 case -1:
1759 log_Printf(LogERROR, "fork: %s\n", strerror(errno));
1760 close(fds[0]);
1761 close(fds[1]);
1762 return;
1763 case 0:
1764 close(fds[1]);
1765 read(fds[0], &done, 1); /* uu_locks are mine ! */
1766 close(fds[0]);
1767 if (pipe(fds) == -1) {
1768 log_Printf(LogERROR, "pipe(2): %s\n", strerror(errno));
1769 return;
1770 }
1771 switch ((pid = fork())) {
1772 case -1:
1773 log_Printf(LogERROR, "fork(2): %s\n", strerror(errno));
1774 close(fds[0]);
1775 close(fds[1]);
1776 return;
1777 case 0:
1778 close(fds[1]);
1779 bundle_LockTun(bundle); /* update pid */
1780 read(fds[0], &done, 1); /* uu_locks are mine ! */
1781 close(fds[0]);
1782 setsid();
1783 bundle_ChangedPID(bundle);
1655
1656 log_Printf(LogDEBUG, "Transmitting link (%d bytes)\n", expect);
1657 if ((got = writev(reply[0], iov + 1, niov - 1)) != expect) {
1658 if (got == -1)
1659 log_Printf(LogERROR, "%s: Failed writev: %s\n",
1660 sun->sun_path, strerror(errno));
1661 else
1662 log_Printf(LogERROR, "%s: Failed writev: Wrote %d of %d\n",
1663 sun->sun_path, got, expect);
1664 }
1665 } else if (got == -1)
1666 log_Printf(LogERROR, "%s: Failed socketpair read: %s\n",
1667 sun->sun_path, strerror(errno));
1668 else
1669 log_Printf(LogERROR, "%s: Failed socketpair read: Got %d of %d\n",
1670 sun->sun_path, got, (int)(sizeof newpid));
1671 }
1672
1673 close(reply[0]);
1674 close(reply[1]);
1675
1676 newsid = Enabled(dl->bundle, OPT_KEEPSESSION) ||
1677 tcgetpgrp(fd[0]) == getpgrp();
1678 while (nfd)
1679 close(fd[--nfd]);
1680 if (newsid)
1681 bundle_setsid(dl->bundle, got != -1);
1682 }
1683 close(s);
1684
1685 while (niov--)
1686 free(iov[niov].iov_base);
1687}
1688
1689int
1690bundle_RenameDatalink(struct bundle *bundle, struct datalink *ndl,
1691 const char *name)
1692{
1693 struct datalink *dl;
1694
1695 if (!strcasecmp(ndl->name, name))
1696 return 1;
1697
1698 for (dl = bundle->links; dl; dl = dl->next)
1699 if (!strcasecmp(dl->name, name))
1700 return 0;
1701
1702 datalink_Rename(ndl, name);
1703 return 1;
1704}
1705
1706int
1707bundle_SetMode(struct bundle *bundle, struct datalink *dl, int mode)
1708{
1709 int omode;
1710
1711 omode = dl->physical->type;
1712 if (omode == mode)
1713 return 1;
1714
1715 if (mode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO))
1716 /* First auto link */
1717 if (bundle->ncp.ipcp.peer_ip.s_addr == INADDR_ANY) {
1718 log_Printf(LogWARN, "You must `set ifaddr' or `open' before"
1719 " changing mode to %s\n", mode2Nam(mode));
1720 return 0;
1721 }
1722
1723 if (!datalink_SetMode(dl, mode))
1724 return 0;
1725
1726 if (mode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO) &&
1727 bundle->phase != PHASE_NETWORK)
1728 /* First auto link, we need an interface */
1729 ipcp_InterfaceUp(&bundle->ncp.ipcp);
1730
1731 /* Regenerate phys_type and adjust idle timer */
1732 bundle_LinksRemoved(bundle);
1733
1734 return 1;
1735}
1736
1737void
1738bundle_setsid(struct bundle *bundle, int holdsession)
1739{
1740 /*
1741 * Lose the current session. This means getting rid of our pid
1742 * too so that the tty device will really go away, and any getty
1743 * etc will be allowed to restart.
1744 */
1745 pid_t pid, orig;
1746 int fds[2];
1747 char done;
1748 struct datalink *dl;
1749
1750 if (!holdsession && bundle_IsDead(bundle)) {
1751 /*
1752 * No need to lose our session after all... we're going away anyway
1753 *
1754 * We should really stop the timer and pause if holdsession is set and
1755 * the bundle's dead, but that leaves other resources lying about :-(
1756 */
1757 return;
1758 }
1759
1760 orig = getpid();
1761 if (pipe(fds) == -1) {
1762 log_Printf(LogERROR, "pipe: %s\n", strerror(errno));
1763 return;
1764 }
1765 switch ((pid = fork())) {
1766 case -1:
1767 log_Printf(LogERROR, "fork: %s\n", strerror(errno));
1768 close(fds[0]);
1769 close(fds[1]);
1770 return;
1771 case 0:
1772 close(fds[1]);
1773 read(fds[0], &done, 1); /* uu_locks are mine ! */
1774 close(fds[0]);
1775 if (pipe(fds) == -1) {
1776 log_Printf(LogERROR, "pipe(2): %s\n", strerror(errno));
1777 return;
1778 }
1779 switch ((pid = fork())) {
1780 case -1:
1781 log_Printf(LogERROR, "fork(2): %s\n", strerror(errno));
1782 close(fds[0]);
1783 close(fds[1]);
1784 return;
1785 case 0:
1786 close(fds[1]);
1787 bundle_LockTun(bundle); /* update pid */
1788 read(fds[0], &done, 1); /* uu_locks are mine ! */
1789 close(fds[0]);
1790 setsid();
1791 bundle_ChangedPID(bundle);
1784 log_Printf(LogPHASE, "%d -> %d: %s session control\n",
1792 log_Printf(LogDEBUG, "%d -> %d: %s session control\n",
1785 (int)orig, (int)getpid(),
1786 holdsession ? "Passed" : "Dropped");
1787 timer_InitService(0); /* Start the Timer Service */
1788 break;
1789 default:
1790 close(fds[0]);
1791 /* Give away all our physical locks (to the final process) */
1792 for (dl = bundle->links; dl; dl = dl->next)
1793 if (dl->state != DATALINK_CLOSED)
1794 physical_ChangedPid(dl->physical, pid);
1795 write(fds[1], "!", 1); /* done */
1796 close(fds[1]);
1797 _exit(0);
1798 break;
1799 }
1800 break;
1801 default:
1802 close(fds[0]);
1803 /* Give away all our physical locks (to the intermediate process) */
1804 for (dl = bundle->links; dl; dl = dl->next)
1805 if (dl->state != DATALINK_CLOSED)
1806 physical_ChangedPid(dl->physical, pid);
1807 write(fds[1], "!", 1); /* done */
1808 close(fds[1]);
1809 if (holdsession) {
1810 int fd, status;
1811
1812 timer_TermService();
1813 signal(SIGPIPE, SIG_DFL);
1814 signal(SIGALRM, SIG_DFL);
1815 signal(SIGHUP, SIG_DFL);
1816 signal(SIGTERM, SIG_DFL);
1817 signal(SIGINT, SIG_DFL);
1818 signal(SIGQUIT, SIG_DFL);
1819 for (fd = getdtablesize(); fd >= 0; fd--)
1820 close(fd);
1821 /*
1822 * Reap the intermediate process. As we're not exiting but the
1823 * intermediate is, we don't want it to become defunct.
1824 */
1825 waitpid(pid, &status, 0);
1826 /* Tweak our process arguments.... */
1827 ID0setproctitle("session owner");
1828 setuid(ID0realuid());
1829 /*
1830 * Hang around for a HUP. This should happen as soon as the
1831 * ppp that we passed our ctty descriptor to closes it.
1832 * NOTE: If this process dies, the passed descriptor becomes
1833 * invalid and will give a select() error by setting one
1834 * of the error fds, aborting the other ppp. We don't
1835 * want that to happen !
1836 */
1837 pause();
1838 }
1839 _exit(0);
1840 break;
1841 }
1842}
1843
1844int
1845bundle_HighestState(struct bundle *bundle)
1846{
1847 struct datalink *dl;
1848 int result = DATALINK_CLOSED;
1849
1850 for (dl = bundle->links; dl; dl = dl->next)
1851 if (result < dl->state)
1852 result = dl->state;
1853
1854 return result;
1855}
1856
1857int
1858bundle_Exception(struct bundle *bundle, int fd)
1859{
1860 struct datalink *dl;
1861
1862 for (dl = bundle->links; dl; dl = dl->next)
1863 if (dl->physical->fd == fd) {
1864 datalink_Down(dl, CLOSE_NORMAL);
1865 return 1;
1866 }
1867
1868 return 0;
1869}
1870
1871void
1872bundle_AdjustFilters(struct bundle *bundle, struct in_addr *my_ip,
1873 struct in_addr *peer_ip)
1874{
1875 filter_AdjustAddr(&bundle->filter.in, my_ip, peer_ip, NULL);
1876 filter_AdjustAddr(&bundle->filter.out, my_ip, peer_ip, NULL);
1877 filter_AdjustAddr(&bundle->filter.dial, my_ip, peer_ip, NULL);
1878 filter_AdjustAddr(&bundle->filter.alive, my_ip, peer_ip, NULL);
1879}
1880
1881void
1882bundle_AdjustDNS(struct bundle *bundle, struct in_addr dns[2])
1883{
1884 filter_AdjustAddr(&bundle->filter.in, NULL, NULL, dns);
1885 filter_AdjustAddr(&bundle->filter.out, NULL, NULL, dns);
1886 filter_AdjustAddr(&bundle->filter.dial, NULL, NULL, dns);
1887 filter_AdjustAddr(&bundle->filter.alive, NULL, NULL, dns);
1888}
1889
1890void
1891bundle_CalculateBandwidth(struct bundle *bundle)
1892{
1893 struct datalink *dl;
1894 int mtu, sp;
1895
1896 bundle->bandwidth = 0;
1897 mtu = 0;
1898 for (dl = bundle->links; dl; dl = dl->next)
1899 if (dl->state == DATALINK_OPEN) {
1900 if ((sp = dl->mp.bandwidth) == 0 &&
1901 (sp = physical_GetSpeed(dl->physical)) == 0)
1902 log_Printf(LogDEBUG, "%s: %s: Cannot determine bandwidth\n",
1903 dl->name, dl->physical->name.full);
1904 else
1905 bundle->bandwidth += sp;
1906 if (!bundle->ncp.mp.active) {
1907 mtu = dl->physical->link.lcp.his_mru;
1908 break;
1909 }
1910 }
1911
1912 if(bundle->bandwidth == 0)
1913 bundle->bandwidth = 115200; /* Shrug */
1914
1915 if (bundle->ncp.mp.active)
1916 mtu = bundle->ncp.mp.peer_mrru;
1917 else if (!mtu)
1918 mtu = 1500;
1919
1920#ifndef NORADIUS
1921 if (bundle->radius.valid && bundle->radius.mtu && bundle->radius.mtu < mtu) {
1922 log_Printf(LogLCP, "Reducing MTU to radius value %lu\n",
1923 bundle->radius.mtu);
1924 mtu = bundle->radius.mtu;
1925 }
1926#endif
1927
1928 tun_configure(bundle, mtu);
1929}
1930
1931void
1932bundle_AutoAdjust(struct bundle *bundle, int percent, int what)
1933{
1934 struct datalink *dl, *choice, *otherlinkup;
1935
1936 choice = otherlinkup = NULL;
1937 for (dl = bundle->links; dl; dl = dl->next)
1938 if (dl->physical->type == PHYS_AUTO) {
1939 if (dl->state == DATALINK_OPEN) {
1940 if (what == AUTO_DOWN) {
1941 if (choice)
1942 otherlinkup = choice;
1943 choice = dl;
1944 }
1945 } else if (dl->state == DATALINK_CLOSED) {
1946 if (what == AUTO_UP) {
1947 choice = dl;
1948 break;
1949 }
1950 } else {
1951 /* An auto link in an intermediate state - forget it for the moment */
1952 choice = NULL;
1953 break;
1954 }
1955 } else if (dl->state == DATALINK_OPEN && what == AUTO_DOWN)
1956 otherlinkup = dl;
1957
1958 if (choice) {
1959 if (what == AUTO_UP) {
1960 log_Printf(LogPHASE, "%d%% saturation -> Opening link ``%s''\n",
1961 percent, choice->name);
1962 datalink_Up(choice, 1, 1);
1963 mp_StopAutoloadTimer(&bundle->ncp.mp);
1964 } else if (otherlinkup) { /* Only bring the second-last link down */
1965 log_Printf(LogPHASE, "%d%% saturation -> Closing link ``%s''\n",
1966 percent, choice->name);
1967 datalink_Close(choice, CLOSE_STAYDOWN);
1968 mp_StopAutoloadTimer(&bundle->ncp.mp);
1969 }
1970 }
1971}
1972
1973int
1974bundle_WantAutoloadTimer(struct bundle *bundle)
1975{
1976 struct datalink *dl;
1977 int autolink, opened;
1978
1979 if (bundle->phase == PHASE_NETWORK) {
1980 for (autolink = opened = 0, dl = bundle->links; dl; dl = dl->next)
1981 if (dl->physical->type == PHYS_AUTO) {
1982 if (++autolink == 2 || (autolink == 1 && opened))
1983 /* Two auto links or one auto and one open in NETWORK phase */
1984 return 1;
1985 } else if (dl->state == DATALINK_OPEN) {
1986 opened++;
1987 if (autolink)
1988 /* One auto and one open link in NETWORK phase */
1989 return 1;
1990 }
1991 }
1992
1993 return 0;
1994}
1995
1996void
1997bundle_ChangedPID(struct bundle *bundle)
1998{
1999#ifdef TUNSIFPID
2000 ioctl(bundle->dev.fd, TUNSIFPID, 0);
2001#endif
2002}
1793 (int)orig, (int)getpid(),
1794 holdsession ? "Passed" : "Dropped");
1795 timer_InitService(0); /* Start the Timer Service */
1796 break;
1797 default:
1798 close(fds[0]);
1799 /* Give away all our physical locks (to the final process) */
1800 for (dl = bundle->links; dl; dl = dl->next)
1801 if (dl->state != DATALINK_CLOSED)
1802 physical_ChangedPid(dl->physical, pid);
1803 write(fds[1], "!", 1); /* done */
1804 close(fds[1]);
1805 _exit(0);
1806 break;
1807 }
1808 break;
1809 default:
1810 close(fds[0]);
1811 /* Give away all our physical locks (to the intermediate process) */
1812 for (dl = bundle->links; dl; dl = dl->next)
1813 if (dl->state != DATALINK_CLOSED)
1814 physical_ChangedPid(dl->physical, pid);
1815 write(fds[1], "!", 1); /* done */
1816 close(fds[1]);
1817 if (holdsession) {
1818 int fd, status;
1819
1820 timer_TermService();
1821 signal(SIGPIPE, SIG_DFL);
1822 signal(SIGALRM, SIG_DFL);
1823 signal(SIGHUP, SIG_DFL);
1824 signal(SIGTERM, SIG_DFL);
1825 signal(SIGINT, SIG_DFL);
1826 signal(SIGQUIT, SIG_DFL);
1827 for (fd = getdtablesize(); fd >= 0; fd--)
1828 close(fd);
1829 /*
1830 * Reap the intermediate process. As we're not exiting but the
1831 * intermediate is, we don't want it to become defunct.
1832 */
1833 waitpid(pid, &status, 0);
1834 /* Tweak our process arguments.... */
1835 ID0setproctitle("session owner");
1836 setuid(ID0realuid());
1837 /*
1838 * Hang around for a HUP. This should happen as soon as the
1839 * ppp that we passed our ctty descriptor to closes it.
1840 * NOTE: If this process dies, the passed descriptor becomes
1841 * invalid and will give a select() error by setting one
1842 * of the error fds, aborting the other ppp. We don't
1843 * want that to happen !
1844 */
1845 pause();
1846 }
1847 _exit(0);
1848 break;
1849 }
1850}
1851
1852int
1853bundle_HighestState(struct bundle *bundle)
1854{
1855 struct datalink *dl;
1856 int result = DATALINK_CLOSED;
1857
1858 for (dl = bundle->links; dl; dl = dl->next)
1859 if (result < dl->state)
1860 result = dl->state;
1861
1862 return result;
1863}
1864
1865int
1866bundle_Exception(struct bundle *bundle, int fd)
1867{
1868 struct datalink *dl;
1869
1870 for (dl = bundle->links; dl; dl = dl->next)
1871 if (dl->physical->fd == fd) {
1872 datalink_Down(dl, CLOSE_NORMAL);
1873 return 1;
1874 }
1875
1876 return 0;
1877}
1878
1879void
1880bundle_AdjustFilters(struct bundle *bundle, struct in_addr *my_ip,
1881 struct in_addr *peer_ip)
1882{
1883 filter_AdjustAddr(&bundle->filter.in, my_ip, peer_ip, NULL);
1884 filter_AdjustAddr(&bundle->filter.out, my_ip, peer_ip, NULL);
1885 filter_AdjustAddr(&bundle->filter.dial, my_ip, peer_ip, NULL);
1886 filter_AdjustAddr(&bundle->filter.alive, my_ip, peer_ip, NULL);
1887}
1888
1889void
1890bundle_AdjustDNS(struct bundle *bundle, struct in_addr dns[2])
1891{
1892 filter_AdjustAddr(&bundle->filter.in, NULL, NULL, dns);
1893 filter_AdjustAddr(&bundle->filter.out, NULL, NULL, dns);
1894 filter_AdjustAddr(&bundle->filter.dial, NULL, NULL, dns);
1895 filter_AdjustAddr(&bundle->filter.alive, NULL, NULL, dns);
1896}
1897
1898void
1899bundle_CalculateBandwidth(struct bundle *bundle)
1900{
1901 struct datalink *dl;
1902 int mtu, sp;
1903
1904 bundle->bandwidth = 0;
1905 mtu = 0;
1906 for (dl = bundle->links; dl; dl = dl->next)
1907 if (dl->state == DATALINK_OPEN) {
1908 if ((sp = dl->mp.bandwidth) == 0 &&
1909 (sp = physical_GetSpeed(dl->physical)) == 0)
1910 log_Printf(LogDEBUG, "%s: %s: Cannot determine bandwidth\n",
1911 dl->name, dl->physical->name.full);
1912 else
1913 bundle->bandwidth += sp;
1914 if (!bundle->ncp.mp.active) {
1915 mtu = dl->physical->link.lcp.his_mru;
1916 break;
1917 }
1918 }
1919
1920 if(bundle->bandwidth == 0)
1921 bundle->bandwidth = 115200; /* Shrug */
1922
1923 if (bundle->ncp.mp.active)
1924 mtu = bundle->ncp.mp.peer_mrru;
1925 else if (!mtu)
1926 mtu = 1500;
1927
1928#ifndef NORADIUS
1929 if (bundle->radius.valid && bundle->radius.mtu && bundle->radius.mtu < mtu) {
1930 log_Printf(LogLCP, "Reducing MTU to radius value %lu\n",
1931 bundle->radius.mtu);
1932 mtu = bundle->radius.mtu;
1933 }
1934#endif
1935
1936 tun_configure(bundle, mtu);
1937}
1938
1939void
1940bundle_AutoAdjust(struct bundle *bundle, int percent, int what)
1941{
1942 struct datalink *dl, *choice, *otherlinkup;
1943
1944 choice = otherlinkup = NULL;
1945 for (dl = bundle->links; dl; dl = dl->next)
1946 if (dl->physical->type == PHYS_AUTO) {
1947 if (dl->state == DATALINK_OPEN) {
1948 if (what == AUTO_DOWN) {
1949 if (choice)
1950 otherlinkup = choice;
1951 choice = dl;
1952 }
1953 } else if (dl->state == DATALINK_CLOSED) {
1954 if (what == AUTO_UP) {
1955 choice = dl;
1956 break;
1957 }
1958 } else {
1959 /* An auto link in an intermediate state - forget it for the moment */
1960 choice = NULL;
1961 break;
1962 }
1963 } else if (dl->state == DATALINK_OPEN && what == AUTO_DOWN)
1964 otherlinkup = dl;
1965
1966 if (choice) {
1967 if (what == AUTO_UP) {
1968 log_Printf(LogPHASE, "%d%% saturation -> Opening link ``%s''\n",
1969 percent, choice->name);
1970 datalink_Up(choice, 1, 1);
1971 mp_StopAutoloadTimer(&bundle->ncp.mp);
1972 } else if (otherlinkup) { /* Only bring the second-last link down */
1973 log_Printf(LogPHASE, "%d%% saturation -> Closing link ``%s''\n",
1974 percent, choice->name);
1975 datalink_Close(choice, CLOSE_STAYDOWN);
1976 mp_StopAutoloadTimer(&bundle->ncp.mp);
1977 }
1978 }
1979}
1980
1981int
1982bundle_WantAutoloadTimer(struct bundle *bundle)
1983{
1984 struct datalink *dl;
1985 int autolink, opened;
1986
1987 if (bundle->phase == PHASE_NETWORK) {
1988 for (autolink = opened = 0, dl = bundle->links; dl; dl = dl->next)
1989 if (dl->physical->type == PHYS_AUTO) {
1990 if (++autolink == 2 || (autolink == 1 && opened))
1991 /* Two auto links or one auto and one open in NETWORK phase */
1992 return 1;
1993 } else if (dl->state == DATALINK_OPEN) {
1994 opened++;
1995 if (autolink)
1996 /* One auto and one open link in NETWORK phase */
1997 return 1;
1998 }
1999 }
2000
2001 return 0;
2002}
2003
2004void
2005bundle_ChangedPID(struct bundle *bundle)
2006{
2007#ifdef TUNSIFPID
2008 ioctl(bundle->dev.fd, TUNSIFPID, 0);
2009#endif
2010}