bundle.c revision 62000
155992Swpaul/*- 255992Swpaul * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org> 355992Swpaul * All rights reserved. 455992Swpaul * 555992Swpaul * Redistribution and use in source and binary forms, with or without 655992Swpaul * modification, are permitted provided that the following conditions 755992Swpaul * are met: 855992Swpaul * 1. Redistributions of source code must retain the above copyright 955992Swpaul * notice, this list of conditions and the following disclaimer. 1055992Swpaul * 2. Redistributions in binary form must reproduce the above copyright 1155992Swpaul * notice, this list of conditions and the following disclaimer in the 1255992Swpaul * documentation and/or other materials provided with the distribution. 1355992Swpaul * 1455992Swpaul * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1555992Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1655992Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1755992Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1855992Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1955992Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2055992Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2155992Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2255992Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2355992Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2455992Swpaul * SUCH DAMAGE. 2555992Swpaul * 2655992Swpaul * $FreeBSD: head/usr.sbin/ppp/bundle.c 62000 2000-06-23 09:48:26Z brian $ 2755992Swpaul */ 2855992Swpaul 2955992Swpaul#include <sys/param.h> 3055992Swpaul#include <sys/socket.h> 3155992Swpaul#include <netinet/in.h> 3255992Swpaul#include <net/if.h> 3355992Swpaul#include <net/if_tun.h> /* For TUNS* ioctls */ 3455992Swpaul#include <arpa/inet.h> 3555992Swpaul#include <net/route.h> 3655992Swpaul#include <netinet/in_systm.h> 3755992Swpaul#include <netinet/ip.h> 3855992Swpaul#include <sys/un.h> 3955992Swpaul 4055992Swpaul#include <errno.h> 4155992Swpaul#include <fcntl.h> 4255992Swpaul#ifdef __OpenBSD__ 4355992Swpaul#include <util.h> 4455992Swpaul#else 4555992Swpaul#include <libutil.h> 4655992Swpaul#endif 4755992Swpaul#include <paths.h> 4855992Swpaul#include <stdio.h> 4955992Swpaul#include <stdlib.h> 5055992Swpaul#include <string.h> 5155992Swpaul#include <sys/uio.h> 5255992Swpaul#include <sys/wait.h> 5355992Swpaul#if defined(__FreeBSD__) && !defined(NOKLDLOAD) 5455992Swpaul#include <sys/linker.h> 5555992Swpaul#include <sys/module.h> 5655992Swpaul#endif 5755992Swpaul#include <termios.h> 5855992Swpaul#include <unistd.h> 5955992Swpaul 6055992Swpaul#include "layer.h" 6155992Swpaul#include "defs.h" 6255992Swpaul#include "command.h" 6355992Swpaul#include "mbuf.h" 6455992Swpaul#include "log.h" 6555992Swpaul#include "id.h" 6655992Swpaul#include "timer.h" 6755992Swpaul#include "fsm.h" 6855992Swpaul#include "iplist.h" 6955992Swpaul#include "lqr.h" 7055992Swpaul#include "hdlc.h" 7155992Swpaul#include "throughput.h" 7255992Swpaul#include "slcompress.h" 7355992Swpaul#include "ipcp.h" 7455992Swpaul#include "filter.h" 7555992Swpaul#include "descriptor.h" 7655992Swpaul#include "route.h" 7755992Swpaul#include "lcp.h" 7855992Swpaul#include "ccp.h" 7955992Swpaul#include "link.h" 8055992Swpaul#include "mp.h" 8155992Swpaul#ifndef NORADIUS 8255992Swpaul#include "radius.h" 8355992Swpaul#endif 8455992Swpaul#include "bundle.h" 8555992Swpaul#include "async.h" 8655992Swpaul#include "physical.h" 8755992Swpaul#include "auth.h" 8855992Swpaul#include "proto.h" 8955992Swpaul#include "chap.h" 9055992Swpaul#include "tun.h" 9155992Swpaul#include "prompt.h" 9255992Swpaul#include "chat.h" 9355992Swpaul#include "cbcp.h" 9455992Swpaul#include "datalink.h" 9555992Swpaul#include "ip.h" 9655992Swpaul#include "iface.h" 9755992Swpaul 9855992Swpaul#define SCATTER_SEGMENTS 6 /* version, datalink, name, physical, 9955992Swpaul throughput, device */ 10055992Swpaul 10155992Swpaul#define SEND_MAXFD 3 /* Max file descriptors passed through 10255992Swpaul the local domain socket */ 10355992Swpaul 10455992Swpaulstatic int bundle_RemainingIdleTime(struct bundle *); 10555992Swpaul 10655992Swpaulstatic const char * const PhaseNames[] = { 10755992Swpaul "Dead", "Establish", "Authenticate", "Network", "Terminate" 10855992Swpaul}; 10955992Swpaul 11055992Swpaulconst char * 11155992Swpaulbundle_PhaseName(struct bundle *bundle) 11255992Swpaul{ 11355992Swpaul return bundle->phase <= PHASE_TERMINATE ? 11455992Swpaul PhaseNames[bundle->phase] : "unknown"; 11555992Swpaul} 11655992Swpaul 11755992Swpaulvoid 11855992Swpaulbundle_NewPhase(struct bundle *bundle, u_int new) 11955992Swpaul{ 12055992Swpaul if (new == bundle->phase) 12155992Swpaul return; 12255992Swpaul 12355992Swpaul if (new <= PHASE_TERMINATE) 12455992Swpaul log_Printf(LogPHASE, "bundle: %s\n", PhaseNames[new]); 12555992Swpaul 12655992Swpaul switch (new) { 12755992Swpaul case PHASE_DEAD: 12855992Swpaul log_DisplayPrompts(); 12955992Swpaul bundle->phase = new; 13055992Swpaul break; 13155992Swpaul 13255992Swpaul case PHASE_ESTABLISH: 13355992Swpaul bundle->phase = new; 13455992Swpaul break; 13555992Swpaul 13655992Swpaul case PHASE_AUTHENTICATE: 13755992Swpaul bundle->phase = new; 13855992Swpaul log_DisplayPrompts(); 13955992Swpaul break; 14055992Swpaul 14155992Swpaul case PHASE_NETWORK: 14255992Swpaul fsm_Up(&bundle->ncp.ipcp.fsm); 14355992Swpaul fsm_Open(&bundle->ncp.ipcp.fsm); 14455992Swpaul bundle->phase = new; 14555992Swpaul log_DisplayPrompts(); 14655992Swpaul break; 14755992Swpaul 14855992Swpaul case PHASE_TERMINATE: 14955992Swpaul bundle->phase = new; 15055992Swpaul mp_Down(&bundle->ncp.mp); 15155992Swpaul log_DisplayPrompts(); 15255992Swpaul break; 15355992Swpaul } 15455992Swpaul} 15555992Swpaul 15655992Swpaulstatic void 15755992Swpaulbundle_LayerStart(void *v, struct fsm *fp) 15855992Swpaul{ 15955992Swpaul /* The given FSM is about to start up ! */ 16055992Swpaul} 16155992Swpaul 16255992Swpaul 16355992Swpaulvoid 16455992Swpaulbundle_Notify(struct bundle *bundle, char c) 16555992Swpaul{ 16655992Swpaul if (bundle->notify.fd != -1) { 16755992Swpaul int ret; 16855992Swpaul 16955992Swpaul ret = write(bundle->notify.fd, &c, 1); 17055992Swpaul if (c != EX_REDIAL && c != EX_RECONNECT) { 17155992Swpaul if (ret == 1) 17255992Swpaul log_Printf(LogCHAT, "Parent notified of %s\n", 17355992Swpaul c == EX_NORMAL ? "success" : "failure"); 17455992Swpaul else 17555992Swpaul log_Printf(LogERROR, "Failed to notify parent of success\n"); 17655992Swpaul close(bundle->notify.fd); 17755992Swpaul bundle->notify.fd = -1; 17855992Swpaul } else if (ret == 1) 17955992Swpaul log_Printf(LogCHAT, "Parent notified of %s\n", ex_desc(c)); 18055992Swpaul else 18155992Swpaul log_Printf(LogERROR, "Failed to notify parent of %s\n", ex_desc(c)); 18255992Swpaul } 18355992Swpaul} 18455992Swpaul 18555992Swpaulstatic void 18655992Swpaulbundle_ClearQueues(void *v) 18755992Swpaul{ 18855992Swpaul struct bundle *bundle = (struct bundle *)v; 18955992Swpaul struct datalink *dl; 19055992Swpaul 19155992Swpaul log_Printf(LogPHASE, "Clearing choked output queue\n"); 19255992Swpaul timer_Stop(&bundle->choked.timer); 19355992Swpaul 19455992Swpaul /* 19555992Swpaul * Emergency time: 19655992Swpaul * 19755992Swpaul * We've had a full queue for PACKET_DEL_SECS seconds without being 19855992Swpaul * able to get rid of any of the packets. We've probably given up 19955992Swpaul * on the redials at this point, and the queued data has almost 20055992Swpaul * definitely been timed out by the layer above. As this is preventing 20155992Swpaul * us from reading the TUN_NAME device (we don't want to buffer stuff 20255992Swpaul * indefinitely), we may as well nuke this data and start with a clean 20355992Swpaul * slate ! 20455992Swpaul * 20555992Swpaul * Unfortunately, this has the side effect of shafting any compression 20655992Swpaul * dictionaries in use (causing the relevant RESET_REQ/RESET_ACK). 20755992Swpaul */ 20855992Swpaul 20955992Swpaul ip_DeleteQueue(&bundle->ncp.ipcp); 21055992Swpaul mp_DeleteQueue(&bundle->ncp.mp); 21155992Swpaul for (dl = bundle->links; dl; dl = dl->next) 21255992Swpaul physical_DeleteQueue(dl->physical); 21355992Swpaul} 21455992Swpaul 21555992Swpaulstatic void 21655992Swpaulbundle_LinkAdded(struct bundle *bundle, struct datalink *dl) 21755992Swpaul{ 21855992Swpaul bundle->phys_type.all |= dl->physical->type; 21955992Swpaul if (dl->state == DATALINK_OPEN) 22055992Swpaul bundle->phys_type.open |= dl->physical->type; 22155992Swpaul 22255992Swpaul if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) 22355992Swpaul != bundle->phys_type.open && bundle->idle.timer.state == TIMER_STOPPED) 22455992Swpaul /* We may need to start our idle timer */ 22555992Swpaul bundle_StartIdleTimer(bundle); 22655992Swpaul} 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 u_short ifqueue; 444 size_t queued; 445 446 result = 0; 447 448 /* If there are aren't many packets queued, look for some more. */ 449 for (nlinks = 0, dl = bundle->links; dl; dl = dl->next) 450 nlinks++; 451 452 if (nlinks) { 453 queued = r ? bundle_FillQueues(bundle) : ip_QueueLen(&bundle->ncp.ipcp); 454 455 if (r && (bundle->phase == PHASE_NETWORK || 456 bundle->phys_type.all & PHYS_AUTO)) { 457 /* enough surplus so that we can tell if we're getting swamped */ 458 ifqueue = nlinks > bundle->cfg.ifqueue ? nlinks : bundle->cfg.ifqueue; 459 if (queued < ifqueue) { 460 /* Not enough - select() for more */ 461 if (bundle->choked.timer.state == TIMER_RUNNING) 462 timer_Stop(&bundle->choked.timer); /* Not needed any more */ 463 FD_SET(bundle->dev.fd, r); 464 if (*n < bundle->dev.fd + 1) 465 *n = bundle->dev.fd + 1; 466 log_Printf(LogTIMER, "%s: fdset(r) %d\n", TUN_NAME, bundle->dev.fd); 467 result++; 468 } else if (bundle->choked.timer.state == TIMER_STOPPED) { 469 bundle->choked.timer.func = bundle_ClearQueues; 470 bundle->choked.timer.name = "output choke"; 471 bundle->choked.timer.load = bundle->cfg.choked.timeout * SECTICKS; 472 bundle->choked.timer.arg = bundle; 473 timer_Start(&bundle->choked.timer); 474 } 475 } 476 } 477 478#ifndef NORADIUS 479 result += descriptor_UpdateSet(&bundle->radius.desc, r, w, e, n); 480#endif 481 482 /* Which links need a select() ? */ 483 for (dl = bundle->links; dl; dl = dl->next) 484 result += descriptor_UpdateSet(&dl->desc, r, w, e, n); 485 486 /* 487 * This *MUST* be called after the datalink UpdateSet()s as it 488 * might be ``holding'' one of the datalinks (death-row) and 489 * wants to be able to de-select() it from the descriptor set. 490 */ 491 result += descriptor_UpdateSet(&bundle->ncp.mp.server.desc, r, w, e, n); 492 493 return result; 494} 495 496static int 497bundle_IsSet(struct fdescriptor *d, const fd_set *fdset) 498{ 499 struct bundle *bundle = descriptor2bundle(d); 500 struct datalink *dl; 501 502 for (dl = bundle->links; dl; dl = dl->next) 503 if (descriptor_IsSet(&dl->desc, fdset)) 504 return 1; 505 506#ifndef NORADIUS 507 if (descriptor_IsSet(&bundle->radius.desc, fdset)) 508 return 1; 509#endif 510 511 if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset)) 512 return 1; 513 514 return FD_ISSET(bundle->dev.fd, fdset); 515} 516 517static void 518bundle_DescriptorRead(struct fdescriptor *d, struct bundle *bundle, 519 const fd_set *fdset) 520{ 521 struct datalink *dl; 522 523 if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset)) 524 descriptor_Read(&bundle->ncp.mp.server.desc, bundle, fdset); 525 526 for (dl = bundle->links; dl; dl = dl->next) 527 if (descriptor_IsSet(&dl->desc, fdset)) 528 descriptor_Read(&dl->desc, bundle, fdset); 529 530#ifndef NORADIUS 531 if (descriptor_IsSet(&bundle->radius.desc, fdset)) 532 descriptor_Read(&bundle->radius.desc, bundle, fdset); 533#endif 534 535 if (FD_ISSET(bundle->dev.fd, fdset)) { 536 struct tun_data tun; 537 int n, pri; 538 char *data; 539 size_t sz; 540 541 if (bundle->dev.header) { 542 data = (char *)&tun; 543 sz = sizeof tun; 544 } else { 545 data = tun.data; 546 sz = sizeof tun.data; 547 } 548 549 /* something to read from tun */ 550 551 n = read(bundle->dev.fd, data, sz); 552 if (n < 0) { 553 log_Printf(LogWARN, "%s: read: %s\n", bundle->dev.Name, strerror(errno)); 554 return; 555 } 556 557 if (bundle->dev.header) { 558 n -= sz - sizeof tun.data; 559 if (n <= 0) { 560 log_Printf(LogERROR, "%s: read: Got only %d bytes of data !\n", 561 bundle->dev.Name, n); 562 return; 563 } 564 if (ntohl(tun.family) != AF_INET) 565 /* XXX: Should be maintaining drop/family counts ! */ 566 return; 567 } 568 569 if (((struct ip *)tun.data)->ip_dst.s_addr == 570 bundle->ncp.ipcp.my_ip.s_addr) { 571 /* we've been asked to send something addressed *to* us :( */ 572 if (Enabled(bundle, OPT_LOOPBACK)) { 573 pri = PacketCheck(bundle, tun.data, n, &bundle->filter.in); 574 if (pri >= 0) { 575 n += sz - sizeof tun.data; 576 write(bundle->dev.fd, data, n); 577 log_Printf(LogDEBUG, "Looped back packet addressed to myself\n"); 578 } 579 return; 580 } else 581 log_Printf(LogDEBUG, "Oops - forwarding packet addressed to myself\n"); 582 } 583 584 /* 585 * Process on-demand dialup. Output packets are queued within tunnel 586 * device until IPCP is opened. 587 */ 588 589 if (bundle_Phase(bundle) == PHASE_DEAD) { 590 /* 591 * Note, we must be in AUTO mode :-/ otherwise our interface should 592 * *not* be UP and we can't receive data 593 */ 594 if ((pri = PacketCheck(bundle, tun.data, n, &bundle->filter.dial)) >= 0) 595 bundle_Open(bundle, NULL, PHYS_AUTO, 0); 596 else 597 /* 598 * Drop the packet. If we were to queue it, we'd just end up with 599 * a pile of timed-out data in our output queue by the time we get 600 * around to actually dialing. We'd also prematurely reach the 601 * threshold at which we stop select()ing to read() the tun 602 * device - breaking auto-dial. 603 */ 604 return; 605 } 606 607 pri = PacketCheck(bundle, tun.data, n, &bundle->filter.out); 608 if (pri >= 0) 609 ip_Enqueue(&bundle->ncp.ipcp, pri, tun.data, n); 610 } 611} 612 613static int 614bundle_DescriptorWrite(struct fdescriptor *d, struct bundle *bundle, 615 const fd_set *fdset) 616{ 617 struct datalink *dl; 618 int result = 0; 619 620 /* This is not actually necessary as struct mpserver doesn't Write() */ 621 if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset)) 622 descriptor_Write(&bundle->ncp.mp.server.desc, bundle, fdset); 623 624 for (dl = bundle->links; dl; dl = dl->next) 625 if (descriptor_IsSet(&dl->desc, fdset)) 626 result += descriptor_Write(&dl->desc, bundle, fdset); 627 628 return result; 629} 630 631void 632bundle_LockTun(struct bundle *bundle) 633{ 634 FILE *lockfile; 635 char pidfile[MAXPATHLEN]; 636 637 snprintf(pidfile, sizeof pidfile, "%stun%d.pid", _PATH_VARRUN, bundle->unit); 638 lockfile = ID0fopen(pidfile, "w"); 639 if (lockfile != NULL) { 640 fprintf(lockfile, "%d\n", (int)getpid()); 641 fclose(lockfile); 642 } 643#ifndef RELEASE_CRUNCH 644 else 645 log_Printf(LogERROR, "Warning: Can't create %s: %s\n", 646 pidfile, strerror(errno)); 647#endif 648} 649 650static void 651bundle_UnlockTun(struct bundle *bundle) 652{ 653 char pidfile[MAXPATHLEN]; 654 655 snprintf(pidfile, sizeof pidfile, "%stun%d.pid", _PATH_VARRUN, bundle->unit); 656 ID0unlink(pidfile); 657} 658 659struct bundle * 660bundle_Create(const char *prefix, int type, int unit) 661{ 662 static struct bundle bundle; /* there can be only one */ 663 int enoentcount, err, minunit, maxunit; 664 const char *ifname; 665#if defined(__FreeBSD__) && !defined(NOKLDLOAD) 666 int kldtried; 667#endif 668#if defined(TUNSIFMODE) || defined(TUNSLMODE) || defined(TUNSIFHEAD) 669 int iff; 670#endif 671 672 if (bundle.iface != NULL) { /* Already allocated ! */ 673 log_Printf(LogALERT, "bundle_Create: There's only one BUNDLE !\n"); 674 return NULL; 675 } 676 677 if (unit == -1) { 678 minunit = 0; 679 maxunit = -1; 680 } else { 681 minunit = unit; 682 maxunit = unit + 1; 683 } 684 err = ENOENT; 685 enoentcount = 0; 686#if defined(__FreeBSD__) && !defined(NOKLDLOAD) 687 kldtried = 0; 688#endif 689 for (bundle.unit = minunit; bundle.unit != maxunit; bundle.unit++) { 690 snprintf(bundle.dev.Name, sizeof bundle.dev.Name, "%s%d", 691 prefix, bundle.unit); 692 bundle.dev.fd = ID0open(bundle.dev.Name, O_RDWR); 693 if (bundle.dev.fd >= 0) 694 break; 695 else if (errno == ENXIO) { 696#if defined(__FreeBSD__) && !defined(NOKLDLOAD) 697 if (bundle.unit == minunit && !kldtried++) { 698 /* 699 * Attempt to load the tunnel interface KLD if it isn't loaded 700 * already. 701 */ 702 if (modfind("if_tun") == -1) { 703 if (ID0kldload("if_tun") != -1) { 704 bundle.unit--; 705 continue; 706 } 707 log_Printf(LogWARN, "kldload: if_tun: %s\n", strerror(errno)); 708 } 709 } 710#endif 711 err = errno; 712 break; 713 } else if (errno == ENOENT) { 714 if (++enoentcount > 2) 715 break; 716 } else 717 err = errno; 718 } 719 720 if (bundle.dev.fd < 0) { 721 if (unit == -1) 722 log_Printf(LogWARN, "No available tunnel devices found (%s)\n", 723 strerror(err)); 724 else 725 log_Printf(LogWARN, "%s%d: %s\n", prefix, unit, strerror(err)); 726 return NULL; 727 } 728 729 log_SetTun(bundle.unit); 730 731 ifname = strrchr(bundle.dev.Name, '/'); 732 if (ifname == NULL) 733 ifname = bundle.dev.Name; 734 else 735 ifname++; 736 737 bundle.iface = iface_Create(ifname); 738 if (bundle.iface == NULL) { 739 close(bundle.dev.fd); 740 return NULL; 741 } 742 743#ifdef TUNSIFMODE 744 /* Make sure we're POINTOPOINT */ 745 iff = IFF_POINTOPOINT; 746 if (ID0ioctl(bundle.dev.fd, TUNSIFMODE, &iff) < 0) 747 log_Printf(LogERROR, "bundle_Create: ioctl(TUNSIFMODE): %s\n", 748 strerror(errno)); 749#endif 750 751#ifdef TUNSLMODE 752 /* Make sure we're not prepending sockaddrs */ 753 iff = 0; 754 if (ID0ioctl(bundle.dev.fd, TUNSLMODE, &iff) < 0) 755 log_Printf(LogERROR, "bundle_Create: ioctl(TUNSLMODE): %s\n", 756 strerror(errno)); 757#endif 758 759#ifdef TUNSIFHEAD 760 /* We want the address family please ! */ 761 iff = 1; 762 if (ID0ioctl(bundle.dev.fd, TUNSIFHEAD, &iff) < 0) { 763 log_Printf(LogERROR, "bundle_Create: ioctl(TUNSIFHEAD): %s\n", 764 strerror(errno)); 765 bundle.dev.header = 0; 766 } else 767 bundle.dev.header = 1; 768#else 769#ifdef __OpenBSD__ 770 /* Always present for OpenBSD */ 771 bundle.dev.header = 1; 772#else 773 /* 774 * If TUNSIFHEAD isn't available and we're not OpenBSD, assume 775 * everything's AF_INET (hopefully the tun device won't pass us 776 * anything else !). 777 */ 778 bundle.dev.header = 0; 779#endif 780#endif 781 782 if (!iface_SetFlags(bundle.iface, IFF_UP)) { 783 iface_Destroy(bundle.iface); 784 bundle.iface = NULL; 785 close(bundle.dev.fd); 786 return NULL; 787 } 788 789 log_Printf(LogPHASE, "Using interface: %s\n", ifname); 790 791 bundle.bandwidth = 0; 792 bundle.routing_seq = 0; 793 bundle.phase = PHASE_DEAD; 794 bundle.CleaningUp = 0; 795 bundle.NatEnabled = 0; 796 797 bundle.fsm.LayerStart = bundle_LayerStart; 798 bundle.fsm.LayerUp = bundle_LayerUp; 799 bundle.fsm.LayerDown = bundle_LayerDown; 800 bundle.fsm.LayerFinish = bundle_LayerFinish; 801 bundle.fsm.object = &bundle; 802 803 bundle.cfg.idle.timeout = NCP_IDLE_TIMEOUT; 804 bundle.cfg.idle.min_timeout = 0; 805 *bundle.cfg.auth.name = '\0'; 806 *bundle.cfg.auth.key = '\0'; 807 bundle.cfg.opt = OPT_SROUTES | OPT_IDCHECK | OPT_LOOPBACK | 808 OPT_THROUGHPUT | OPT_UTMP; 809 *bundle.cfg.label = '\0'; 810 bundle.cfg.mtu = DEF_MTU; 811 bundle.cfg.ifqueue = DEF_IFQUEUE; 812 bundle.cfg.choked.timeout = CHOKED_TIMEOUT; 813 bundle.phys_type.all = type; 814 bundle.phys_type.open = 0; 815 bundle.upat = 0; 816 817 bundle.links = datalink_Create("deflink", &bundle, type); 818 if (bundle.links == NULL) { 819 log_Printf(LogALERT, "Cannot create data link: %s\n", strerror(errno)); 820 iface_Destroy(bundle.iface); 821 bundle.iface = NULL; 822 close(bundle.dev.fd); 823 return NULL; 824 } 825 826 bundle.desc.type = BUNDLE_DESCRIPTOR; 827 bundle.desc.UpdateSet = bundle_UpdateSet; 828 bundle.desc.IsSet = bundle_IsSet; 829 bundle.desc.Read = bundle_DescriptorRead; 830 bundle.desc.Write = bundle_DescriptorWrite; 831 832 mp_Init(&bundle.ncp.mp, &bundle); 833 834 /* Send over the first physical link by default */ 835 ipcp_Init(&bundle.ncp.ipcp, &bundle, &bundle.links->physical->link, 836 &bundle.fsm); 837 838 memset(&bundle.filter, '\0', sizeof bundle.filter); 839 bundle.filter.in.fragok = bundle.filter.in.logok = 1; 840 bundle.filter.in.name = "IN"; 841 bundle.filter.out.fragok = bundle.filter.out.logok = 1; 842 bundle.filter.out.name = "OUT"; 843 bundle.filter.dial.name = "DIAL"; 844 bundle.filter.dial.logok = 1; 845 bundle.filter.alive.name = "ALIVE"; 846 bundle.filter.alive.logok = 1; 847 { 848 int i; 849 for (i = 0; i < MAXFILTERS; i++) { 850 bundle.filter.in.rule[i].f_action = A_NONE; 851 bundle.filter.out.rule[i].f_action = A_NONE; 852 bundle.filter.dial.rule[i].f_action = A_NONE; 853 bundle.filter.alive.rule[i].f_action = A_NONE; 854 } 855 } 856 memset(&bundle.idle.timer, '\0', sizeof bundle.idle.timer); 857 bundle.idle.done = 0; 858 bundle.notify.fd = -1; 859 memset(&bundle.choked.timer, '\0', sizeof bundle.choked.timer); 860#ifndef NORADIUS 861 radius_Init(&bundle.radius); 862#endif 863 864 /* Clean out any leftover crud */ 865 iface_Clear(bundle.iface, IFACE_CLEAR_ALL); 866 867 bundle_LockTun(&bundle); 868 869 return &bundle; 870} 871 872static void 873bundle_DownInterface(struct bundle *bundle) 874{ 875 route_IfDelete(bundle, 1); 876 iface_ClearFlags(bundle->iface, IFF_UP); 877} 878 879void 880bundle_Destroy(struct bundle *bundle) 881{ 882 struct datalink *dl; 883 884 /* 885 * Clean up the interface. We don't need to timer_Stop()s, mp_Down(), 886 * ipcp_CleanInterface() and bundle_DownInterface() unless we're getting 887 * out under exceptional conditions such as a descriptor exception. 888 */ 889 timer_Stop(&bundle->idle.timer); 890 timer_Stop(&bundle->choked.timer); 891 mp_Down(&bundle->ncp.mp); 892 ipcp_CleanInterface(&bundle->ncp.ipcp); 893 bundle_DownInterface(bundle); 894 895#ifndef NORADIUS 896 /* Tell the radius server the bad news */ 897 radius_Destroy(&bundle->radius); 898#endif 899 900 /* Again, these are all DATALINK_CLOSED unless we're abending */ 901 dl = bundle->links; 902 while (dl) 903 dl = datalink_Destroy(dl); 904 905 ipcp_Destroy(&bundle->ncp.ipcp); 906 907 close(bundle->dev.fd); 908 bundle_UnlockTun(bundle); 909 910 /* In case we never made PHASE_NETWORK */ 911 bundle_Notify(bundle, EX_ERRDEAD); 912 913 iface_Destroy(bundle->iface); 914 bundle->iface = NULL; 915} 916 917struct rtmsg { 918 struct rt_msghdr m_rtm; 919 char m_space[64]; 920}; 921 922int 923bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst, 924 struct in_addr gateway, struct in_addr mask, int bang, int ssh) 925{ 926 struct rtmsg rtmes; 927 int s, nb, wb; 928 char *cp; 929 const char *cmdstr; 930 struct sockaddr_in rtdata; 931 int result = 1; 932 933 if (bang) 934 cmdstr = (cmd == RTM_ADD ? "Add!" : "Delete!"); 935 else 936 cmdstr = (cmd == RTM_ADD ? "Add" : "Delete"); 937 s = ID0socket(PF_ROUTE, SOCK_RAW, 0); 938 if (s < 0) { 939 log_Printf(LogERROR, "bundle_SetRoute: socket(): %s\n", strerror(errno)); 940 return result; 941 } 942 memset(&rtmes, '\0', sizeof rtmes); 943 rtmes.m_rtm.rtm_version = RTM_VERSION; 944 rtmes.m_rtm.rtm_type = cmd; 945 rtmes.m_rtm.rtm_addrs = RTA_DST; 946 rtmes.m_rtm.rtm_seq = ++bundle->routing_seq; 947 rtmes.m_rtm.rtm_pid = getpid(); 948 rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; 949 950 if (cmd == RTM_ADD || cmd == RTM_CHANGE) { 951 if (bundle->ncp.ipcp.cfg.sendpipe > 0) { 952 rtmes.m_rtm.rtm_rmx.rmx_sendpipe = bundle->ncp.ipcp.cfg.sendpipe; 953 rtmes.m_rtm.rtm_inits |= RTV_SPIPE; 954 } 955 if (bundle->ncp.ipcp.cfg.recvpipe > 0) { 956 rtmes.m_rtm.rtm_rmx.rmx_recvpipe = bundle->ncp.ipcp.cfg.recvpipe; 957 rtmes.m_rtm.rtm_inits |= RTV_RPIPE; 958 } 959 } 960 961 memset(&rtdata, '\0', sizeof rtdata); 962 rtdata.sin_len = sizeof rtdata; 963 rtdata.sin_family = AF_INET; 964 rtdata.sin_port = 0; 965 rtdata.sin_addr = dst; 966 967 cp = rtmes.m_space; 968 memcpy(cp, &rtdata, rtdata.sin_len); 969 cp += rtdata.sin_len; 970 if (cmd == RTM_ADD) { 971 if (gateway.s_addr == INADDR_ANY) { 972 if (!ssh) 973 log_Printf(LogERROR, "bundle_SetRoute: Cannot add a route with" 974 " destination 0.0.0.0\n"); 975 close(s); 976 return result; 977 } else { 978 rtdata.sin_addr = gateway; 979 memcpy(cp, &rtdata, rtdata.sin_len); 980 cp += rtdata.sin_len; 981 rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY; 982 } 983 } 984 985 if (dst.s_addr == INADDR_ANY) 986 mask.s_addr = INADDR_ANY; 987 988 if (cmd == RTM_ADD || dst.s_addr == INADDR_ANY) { 989 rtdata.sin_addr = mask; 990 memcpy(cp, &rtdata, rtdata.sin_len); 991 cp += rtdata.sin_len; 992 rtmes.m_rtm.rtm_addrs |= RTA_NETMASK; 993 } 994 995 nb = cp - (char *) &rtmes; 996 rtmes.m_rtm.rtm_msglen = nb; 997 wb = ID0write(s, &rtmes, nb); 998 if (wb < 0) { 999 log_Printf(LogTCPIP, "bundle_SetRoute failure:\n"); 1000 log_Printf(LogTCPIP, "bundle_SetRoute: Cmd = %s\n", cmdstr); 1001 log_Printf(LogTCPIP, "bundle_SetRoute: Dst = %s\n", inet_ntoa(dst)); 1002 log_Printf(LogTCPIP, "bundle_SetRoute: Gateway = %s\n", 1003 inet_ntoa(gateway)); 1004 log_Printf(LogTCPIP, "bundle_SetRoute: Mask = %s\n", inet_ntoa(mask)); 1005failed: 1006 if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST || 1007 (rtmes.m_rtm.rtm_errno == 0 && errno == EEXIST))) { 1008 if (!bang) { 1009 log_Printf(LogWARN, "Add route failed: %s already exists\n", 1010 dst.s_addr == 0 ? "default" : inet_ntoa(dst)); 1011 result = 0; /* Don't add to our dynamic list */ 1012 } else { 1013 rtmes.m_rtm.rtm_type = cmd = RTM_CHANGE; 1014 if ((wb = ID0write(s, &rtmes, nb)) < 0) 1015 goto failed; 1016 } 1017 } else if (cmd == RTM_DELETE && 1018 (rtmes.m_rtm.rtm_errno == ESRCH || 1019 (rtmes.m_rtm.rtm_errno == 0 && errno == ESRCH))) { 1020 if (!bang) 1021 log_Printf(LogWARN, "Del route failed: %s: Non-existent\n", 1022 inet_ntoa(dst)); 1023 } else if (rtmes.m_rtm.rtm_errno == 0) { 1024 if (!ssh || errno != ENETUNREACH) 1025 log_Printf(LogWARN, "%s route failed: %s: errno: %s\n", cmdstr, 1026 inet_ntoa(dst), strerror(errno)); 1027 } else 1028 log_Printf(LogWARN, "%s route failed: %s: %s\n", 1029 cmdstr, inet_ntoa(dst), strerror(rtmes.m_rtm.rtm_errno)); 1030 } 1031 log_Printf(LogDEBUG, "wrote %d: cmd = %s, dst = %x, gateway = %x\n", 1032 wb, cmdstr, (unsigned)dst.s_addr, (unsigned)gateway.s_addr); 1033 close(s); 1034 1035 return result; 1036} 1037 1038void 1039bundle_LinkClosed(struct bundle *bundle, struct datalink *dl) 1040{ 1041 /* 1042 * Our datalink has closed. 1043 * CleanDatalinks() (called from DoLoop()) will remove closed 1044 * BACKGROUND, FOREGROUND and DIRECT links. 1045 * If it's the last data link, enter phase DEAD. 1046 * 1047 * NOTE: dl may not be in our list (bundle_SendDatalink()) ! 1048 */ 1049 1050 struct datalink *odl; 1051 int other_links; 1052 1053 log_SetTtyCommandMode(dl); 1054 1055 other_links = 0; 1056 for (odl = bundle->links; odl; odl = odl->next) 1057 if (odl != dl && odl->state != DATALINK_CLOSED) 1058 other_links++; 1059 1060 if (!other_links) { 1061 if (dl->physical->type != PHYS_AUTO) /* Not in -auto mode */ 1062 bundle_DownInterface(bundle); 1063 fsm2initial(&bundle->ncp.ipcp.fsm); 1064 bundle_NewPhase(bundle, PHASE_DEAD); 1065 bundle_StopIdleTimer(bundle); 1066 } 1067} 1068 1069void 1070bundle_Open(struct bundle *bundle, const char *name, int mask, int force) 1071{ 1072 /* 1073 * Please open the given datalink, or all if name == NULL 1074 */ 1075 struct datalink *dl; 1076 1077 for (dl = bundle->links; dl; dl = dl->next) 1078 if (name == NULL || !strcasecmp(dl->name, name)) { 1079 if ((mask & dl->physical->type) && 1080 (dl->state == DATALINK_CLOSED || 1081 (force && dl->state == DATALINK_OPENING && 1082 dl->dial.timer.state == TIMER_RUNNING) || 1083 dl->state == DATALINK_READY)) { 1084 timer_Stop(&dl->dial.timer); /* We're finished with this */ 1085 datalink_Up(dl, 1, 1); 1086 if (mask & PHYS_AUTO) 1087 break; /* Only one AUTO link at a time */ 1088 } 1089 if (name != NULL) 1090 break; 1091 } 1092} 1093 1094struct datalink * 1095bundle2datalink(struct bundle *bundle, const char *name) 1096{ 1097 struct datalink *dl; 1098 1099 if (name != NULL) { 1100 for (dl = bundle->links; dl; dl = dl->next) 1101 if (!strcasecmp(dl->name, name)) 1102 return dl; 1103 } else if (bundle->links && !bundle->links->next) 1104 return bundle->links; 1105 1106 return NULL; 1107} 1108 1109int 1110bundle_ShowLinks(struct cmdargs const *arg) 1111{ 1112 struct datalink *dl; 1113 struct pppThroughput *t; 1114 int secs; 1115 1116 for (dl = arg->bundle->links; dl; dl = dl->next) { 1117 prompt_Printf(arg->prompt, "Name: %s [%s, %s]", 1118 dl->name, mode2Nam(dl->physical->type), datalink_State(dl)); 1119 if (dl->physical->link.throughput.rolling && dl->state == DATALINK_OPEN) 1120 prompt_Printf(arg->prompt, " bandwidth %d, %llu bps (%llu bytes/sec)", 1121 dl->mp.bandwidth ? dl->mp.bandwidth : 1122 physical_GetSpeed(dl->physical), 1123 dl->physical->link.throughput.OctetsPerSecond * 8, 1124 dl->physical->link.throughput.OctetsPerSecond); 1125 prompt_Printf(arg->prompt, "\n"); 1126 } 1127 1128 t = &arg->bundle->ncp.mp.link.throughput; 1129 secs = t->downtime ? 0 : throughput_uptime(t); 1130 if (secs > t->SamplePeriod) 1131 secs = t->SamplePeriod; 1132 if (secs) 1133 prompt_Printf(arg->prompt, "Currently averaging %llu bps (%llu bytes/sec)" 1134 " over the last %d secs\n", t->OctetsPerSecond * 8, 1135 t->OctetsPerSecond, secs); 1136 1137 return 0; 1138} 1139 1140static const char * 1141optval(struct bundle *bundle, int bit) 1142{ 1143 return (bundle->cfg.opt & bit) ? "enabled" : "disabled"; 1144} 1145 1146int 1147bundle_ShowStatus(struct cmdargs const *arg) 1148{ 1149 int remaining; 1150 1151 prompt_Printf(arg->prompt, "Phase %s\n", bundle_PhaseName(arg->bundle)); 1152 prompt_Printf(arg->prompt, " Device: %s\n", arg->bundle->dev.Name); 1153 prompt_Printf(arg->prompt, " Interface: %s @ %lubps", 1154 arg->bundle->iface->name, arg->bundle->bandwidth); 1155 1156 if (arg->bundle->upat) { 1157 int secs = time(NULL) - arg->bundle->upat; 1158 1159 prompt_Printf(arg->prompt, ", up time %d:%02d:%02d", secs / 3600, 1160 (secs / 60) % 60, secs % 60); 1161 } 1162 prompt_Printf(arg->prompt, "\n Queued: %lu of %u\n", 1163 (unsigned long)ip_QueueLen(&arg->bundle->ncp.ipcp), 1164 arg->bundle->cfg.ifqueue); 1165 1166 prompt_Printf(arg->prompt, "\nDefaults:\n"); 1167 prompt_Printf(arg->prompt, " Label: %s\n", arg->bundle->cfg.label); 1168 prompt_Printf(arg->prompt, " Auth name: %s\n", 1169 arg->bundle->cfg.auth.name); 1170 1171 prompt_Printf(arg->prompt, " Choked Timer: %ds\n", 1172 arg->bundle->cfg.choked.timeout); 1173 1174#ifndef NORADIUS 1175 radius_Show(&arg->bundle->radius, arg->prompt); 1176#endif 1177 1178 prompt_Printf(arg->prompt, " Idle Timer: "); 1179 if (arg->bundle->cfg.idle.timeout) { 1180 prompt_Printf(arg->prompt, "%ds", arg->bundle->cfg.idle.timeout); 1181 if (arg->bundle->cfg.idle.min_timeout) 1182 prompt_Printf(arg->prompt, ", min %ds", 1183 arg->bundle->cfg.idle.min_timeout); 1184 remaining = bundle_RemainingIdleTime(arg->bundle); 1185 if (remaining != -1) 1186 prompt_Printf(arg->prompt, " (%ds remaining)", remaining); 1187 prompt_Printf(arg->prompt, "\n"); 1188 } else 1189 prompt_Printf(arg->prompt, "disabled\n"); 1190 prompt_Printf(arg->prompt, " MTU: "); 1191 if (arg->bundle->cfg.mtu) 1192 prompt_Printf(arg->prompt, "%d\n", arg->bundle->cfg.mtu); 1193 else 1194 prompt_Printf(arg->prompt, "unspecified\n"); 1195 1196 prompt_Printf(arg->prompt, " sendpipe: "); 1197 if (arg->bundle->ncp.ipcp.cfg.sendpipe > 0) 1198 prompt_Printf(arg->prompt, "%-20ld", arg->bundle->ncp.ipcp.cfg.sendpipe); 1199 else 1200 prompt_Printf(arg->prompt, "unspecified "); 1201 prompt_Printf(arg->prompt, " recvpipe: "); 1202 if (arg->bundle->ncp.ipcp.cfg.recvpipe > 0) 1203 prompt_Printf(arg->prompt, "%ld\n", arg->bundle->ncp.ipcp.cfg.recvpipe); 1204 else 1205 prompt_Printf(arg->prompt, "unspecified\n"); 1206 1207 prompt_Printf(arg->prompt, " Sticky Routes: %-20.20s", 1208 optval(arg->bundle, OPT_SROUTES)); 1209 prompt_Printf(arg->prompt, " ID check: %s\n", 1210 optval(arg->bundle, OPT_IDCHECK)); 1211 prompt_Printf(arg->prompt, " Keep-Session: %-20.20s", 1212 optval(arg->bundle, OPT_KEEPSESSION)); 1213 prompt_Printf(arg->prompt, " Loopback: %s\n", 1214 optval(arg->bundle, OPT_LOOPBACK)); 1215 prompt_Printf(arg->prompt, " PasswdAuth: %-20.20s", 1216 optval(arg->bundle, OPT_PASSWDAUTH)); 1217 prompt_Printf(arg->prompt, " Proxy: %s\n", 1218 optval(arg->bundle, OPT_PROXY)); 1219 prompt_Printf(arg->prompt, " Proxyall: %-20.20s", 1220 optval(arg->bundle, OPT_PROXYALL)); 1221 prompt_Printf(arg->prompt, " Throughput: %s\n", 1222 optval(arg->bundle, OPT_THROUGHPUT)); 1223 prompt_Printf(arg->prompt, " Utmp Logging: %-20.20s", 1224 optval(arg->bundle, OPT_UTMP)); 1225 prompt_Printf(arg->prompt, " Iface-Alias: %s\n", 1226 optval(arg->bundle, OPT_IFACEALIAS)); 1227 1228 return 0; 1229} 1230 1231static void 1232bundle_IdleTimeout(void *v) 1233{ 1234 struct bundle *bundle = (struct bundle *)v; 1235 1236 log_Printf(LogPHASE, "Idle timer expired\n"); 1237 bundle_StopIdleTimer(bundle); 1238 bundle_Close(bundle, NULL, CLOSE_STAYDOWN); 1239} 1240 1241/* 1242 * Start Idle timer. If timeout is reached, we call bundle_Close() to 1243 * close LCP and link. 1244 */ 1245void 1246bundle_StartIdleTimer(struct bundle *bundle) 1247{ 1248 timer_Stop(&bundle->idle.timer); 1249 if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) != 1250 bundle->phys_type.open && bundle->cfg.idle.timeout) { 1251 int secs; 1252 1253 secs = bundle->cfg.idle.timeout; 1254 if (bundle->cfg.idle.min_timeout > secs && bundle->upat) { 1255 int up = time(NULL) - bundle->upat; 1256 1257 if ((long long)bundle->cfg.idle.min_timeout - up > (long long)secs) 1258 secs = bundle->cfg.idle.min_timeout - up; 1259 } 1260 bundle->idle.timer.func = bundle_IdleTimeout; 1261 bundle->idle.timer.name = "idle"; 1262 bundle->idle.timer.load = secs * SECTICKS; 1263 bundle->idle.timer.arg = bundle; 1264 timer_Start(&bundle->idle.timer); 1265 bundle->idle.done = time(NULL) + secs; 1266 } 1267} 1268 1269void 1270bundle_SetIdleTimer(struct bundle *bundle, int timeout, int min_timeout) 1271{ 1272 bundle->cfg.idle.timeout = timeout; 1273 if (min_timeout >= 0) 1274 bundle->cfg.idle.min_timeout = min_timeout; 1275 if (bundle_LinkIsUp(bundle)) 1276 bundle_StartIdleTimer(bundle); 1277} 1278 1279void 1280bundle_StopIdleTimer(struct bundle *bundle) 1281{ 1282 timer_Stop(&bundle->idle.timer); 1283 bundle->idle.done = 0; 1284} 1285 1286static int 1287bundle_RemainingIdleTime(struct bundle *bundle) 1288{ 1289 if (bundle->idle.done) 1290 return bundle->idle.done - time(NULL); 1291 return -1; 1292} 1293 1294int 1295bundle_IsDead(struct bundle *bundle) 1296{ 1297 return !bundle->links || (bundle->phase == PHASE_DEAD && bundle->CleaningUp); 1298} 1299 1300static struct datalink * 1301bundle_DatalinkLinkout(struct bundle *bundle, struct datalink *dl) 1302{ 1303 struct datalink **dlp; 1304 1305 for (dlp = &bundle->links; *dlp; dlp = &(*dlp)->next) 1306 if (*dlp == dl) { 1307 *dlp = dl->next; 1308 dl->next = NULL; 1309 bundle_LinksRemoved(bundle); 1310 return dl; 1311 } 1312 1313 return NULL; 1314} 1315 1316static void 1317bundle_DatalinkLinkin(struct bundle *bundle, struct datalink *dl) 1318{ 1319 struct datalink **dlp = &bundle->links; 1320 1321 while (*dlp) 1322 dlp = &(*dlp)->next; 1323 1324 *dlp = dl; 1325 dl->next = NULL; 1326 1327 bundle_LinkAdded(bundle, dl); 1328 mp_CheckAutoloadTimer(&bundle->ncp.mp); 1329} 1330 1331void 1332bundle_CleanDatalinks(struct bundle *bundle) 1333{ 1334 struct datalink **dlp = &bundle->links; 1335 int found = 0; 1336 1337 while (*dlp) 1338 if ((*dlp)->state == DATALINK_CLOSED && 1339 (*dlp)->physical->type & 1340 (PHYS_DIRECT|PHYS_BACKGROUND|PHYS_FOREGROUND)) { 1341 *dlp = datalink_Destroy(*dlp); 1342 found++; 1343 } else 1344 dlp = &(*dlp)->next; 1345 1346 if (found) 1347 bundle_LinksRemoved(bundle); 1348} 1349 1350int 1351bundle_DatalinkClone(struct bundle *bundle, struct datalink *dl, 1352 const char *name) 1353{ 1354 if (bundle2datalink(bundle, name)) { 1355 log_Printf(LogWARN, "Clone: %s: name already exists\n", name); 1356 return 0; 1357 } 1358 1359 bundle_DatalinkLinkin(bundle, datalink_Clone(dl, name)); 1360 return 1; 1361} 1362 1363void 1364bundle_DatalinkRemove(struct bundle *bundle, struct datalink *dl) 1365{ 1366 dl = bundle_DatalinkLinkout(bundle, dl); 1367 if (dl) 1368 datalink_Destroy(dl); 1369} 1370 1371void 1372bundle_SetLabel(struct bundle *bundle, const char *label) 1373{ 1374 if (label) 1375 strncpy(bundle->cfg.label, label, sizeof bundle->cfg.label - 1); 1376 else 1377 *bundle->cfg.label = '\0'; 1378} 1379 1380const char * 1381bundle_GetLabel(struct bundle *bundle) 1382{ 1383 return *bundle->cfg.label ? bundle->cfg.label : NULL; 1384} 1385 1386int 1387bundle_LinkSize() 1388{ 1389 struct iovec iov[SCATTER_SEGMENTS]; 1390 int niov, expect, f; 1391 1392 iov[0].iov_len = strlen(Version) + 1; 1393 iov[0].iov_base = NULL; 1394 niov = 1; 1395 if (datalink2iov(NULL, iov, &niov, SCATTER_SEGMENTS, NULL, NULL) == -1) { 1396 log_Printf(LogERROR, "Cannot determine space required for link\n"); 1397 return 0; 1398 } 1399 1400 for (f = expect = 0; f < niov; f++) 1401 expect += iov[f].iov_len; 1402 1403 return expect; 1404} 1405 1406void 1407bundle_ReceiveDatalink(struct bundle *bundle, int s) 1408{ 1409 char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int) * SEND_MAXFD]; 1410 int niov, expect, f, *fd, nfd, onfd, got; 1411 struct iovec iov[SCATTER_SEGMENTS]; 1412 struct cmsghdr *cmsg; 1413 struct msghdr msg; 1414 struct datalink *dl; 1415 pid_t pid; 1416 1417 log_Printf(LogPHASE, "Receiving datalink\n"); 1418 1419 /* 1420 * Create our scatter/gather array - passing NULL gets the space 1421 * allocation requirement rather than actually flattening the 1422 * structures. 1423 */ 1424 iov[0].iov_len = strlen(Version) + 1; 1425 iov[0].iov_base = NULL; 1426 niov = 1; 1427 if (datalink2iov(NULL, iov, &niov, SCATTER_SEGMENTS, NULL, NULL) == -1) { 1428 log_Printf(LogERROR, "Cannot determine space required for link\n"); 1429 return; 1430 } 1431 1432 /* Allocate the scatter/gather array for recvmsg() */ 1433 for (f = expect = 0; f < niov; f++) { 1434 if ((iov[f].iov_base = malloc(iov[f].iov_len)) == NULL) { 1435 log_Printf(LogERROR, "Cannot allocate space to receive link\n"); 1436 return; 1437 } 1438 if (f) 1439 expect += iov[f].iov_len; 1440 } 1441 1442 /* Set up our message */ 1443 cmsg = (struct cmsghdr *)cmsgbuf; 1444 cmsg->cmsg_len = sizeof cmsgbuf; 1445 cmsg->cmsg_level = SOL_SOCKET; 1446 cmsg->cmsg_type = 0; 1447 1448 memset(&msg, '\0', sizeof msg); 1449 msg.msg_name = NULL; 1450 msg.msg_namelen = 0; 1451 msg.msg_iov = iov; 1452 msg.msg_iovlen = 1; /* Only send the version at the first pass */ 1453 msg.msg_control = cmsgbuf; 1454 msg.msg_controllen = sizeof cmsgbuf; 1455 1456 log_Printf(LogDEBUG, "Expecting %u scatter/gather bytes\n", 1457 (unsigned)iov[0].iov_len); 1458 1459 if ((got = recvmsg(s, &msg, MSG_WAITALL)) != iov[0].iov_len) { 1460 if (got == -1) 1461 log_Printf(LogERROR, "Failed recvmsg: %s\n", strerror(errno)); 1462 else 1463 log_Printf(LogERROR, "Failed recvmsg: Got %d, not %u\n", 1464 got, (unsigned)iov[0].iov_len); 1465 while (niov--) 1466 free(iov[niov].iov_base); 1467 return; 1468 } 1469 1470 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { 1471 log_Printf(LogERROR, "Recvmsg: no descriptors received !\n"); 1472 while (niov--) 1473 free(iov[niov].iov_base); 1474 return; 1475 } 1476 1477 fd = (int *)(cmsg + 1); 1478 nfd = (cmsg->cmsg_len - sizeof *cmsg) / sizeof(int); 1479 1480 if (nfd < 2) { 1481 log_Printf(LogERROR, "Recvmsg: %d descriptor%s received (too few) !\n", 1482 nfd, nfd == 1 ? "" : "s"); 1483 while (nfd--) 1484 close(fd[nfd]); 1485 while (niov--) 1486 free(iov[niov].iov_base); 1487 return; 1488 } 1489 1490 /* 1491 * We've successfully received two or more open file descriptors 1492 * through our socket, plus a version string. Make sure it's the 1493 * correct version, and drop the connection if it's not. 1494 */ 1495 if (strncmp(Version, iov[0].iov_base, iov[0].iov_len)) { 1496 log_Printf(LogWARN, "Cannot receive datalink, incorrect version" 1497 " (\"%.*s\", not \"%s\")\n", (int)iov[0].iov_len, 1498 (char *)iov[0].iov_base, Version); 1499 while (nfd--) 1500 close(fd[nfd]); 1501 while (niov--) 1502 free(iov[niov].iov_base); 1503 return; 1504 } 1505 1506 /* 1507 * Everything looks good. Send the other side our process id so that 1508 * they can transfer lock ownership, and wait for them to send the 1509 * actual link data. 1510 */ 1511 pid = getpid(); 1512 if ((got = write(fd[1], &pid, sizeof pid)) != sizeof pid) { 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, 1517 (int)(sizeof pid)); 1518 while (nfd--) 1519 close(fd[nfd]); 1520 while (niov--) 1521 free(iov[niov].iov_base); 1522 return; 1523 } 1524 1525 if ((got = readv(fd[1], iov + 1, niov - 1)) != expect) { 1526 if (got == -1) 1527 log_Printf(LogERROR, "Failed write: %s\n", strerror(errno)); 1528 else 1529 log_Printf(LogERROR, "Failed write: Got %d, not %d\n", got, expect); 1530 while (nfd--) 1531 close(fd[nfd]); 1532 while (niov--) 1533 free(iov[niov].iov_base); 1534 return; 1535 } 1536 close(fd[1]); 1537 1538 onfd = nfd; /* We've got this many in our array */ 1539 nfd -= 2; /* Don't include p->fd and our reply descriptor */ 1540 niov = 1; /* Skip the version id */ 1541 dl = iov2datalink(bundle, iov, &niov, sizeof iov / sizeof *iov, fd[0], 1542 fd + 2, &nfd); 1543 if (dl) { 1544 1545 if (nfd) { 1546 log_Printf(LogERROR, "bundle_ReceiveDatalink: Failed to handle %d " 1547 "auxiliary file descriptors (%d remain)\n", onfd, nfd); 1548 datalink_Destroy(dl); 1549 while (nfd--) 1550 close(fd[onfd--]); 1551 close(fd[0]); 1552 } else { 1553 bundle_DatalinkLinkin(bundle, dl); 1554 datalink_AuthOk(dl); 1555 bundle_CalculateBandwidth(dl->bundle); 1556 } 1557 } else { 1558 while (nfd--) 1559 close(fd[onfd--]); 1560 close(fd[0]); 1561 close(fd[1]); 1562 } 1563 1564 free(iov[0].iov_base); 1565} 1566 1567void 1568bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun) 1569{ 1570 char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int) * SEND_MAXFD]; 1571 const char *constlock; 1572 char *lock; 1573 struct cmsghdr *cmsg; 1574 struct msghdr msg; 1575 struct iovec iov[SCATTER_SEGMENTS]; 1576 int niov, f, expect, newsid, fd[SEND_MAXFD], nfd, reply[2], got; 1577 pid_t newpid; 1578 1579 log_Printf(LogPHASE, "Transmitting datalink %s\n", dl->name); 1580 1581 /* Record the base device name for a lock transfer later */ 1582 constlock = physical_LockedDevice(dl->physical); 1583 if (constlock) { 1584 lock = alloca(strlen(constlock) + 1); 1585 strcpy(lock, constlock); 1586 } else 1587 lock = NULL; 1588 1589 bundle_LinkClosed(dl->bundle, dl); 1590 bundle_DatalinkLinkout(dl->bundle, dl); 1591 1592 /* Build our scatter/gather array */ 1593 iov[0].iov_len = strlen(Version) + 1; 1594 iov[0].iov_base = strdup(Version); 1595 niov = 1; 1596 nfd = 0; 1597 1598 fd[0] = datalink2iov(dl, iov, &niov, SCATTER_SEGMENTS, fd + 2, &nfd); 1599 1600 if (fd[0] != -1 && socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, reply) != -1) { 1601 /* 1602 * fd[1] is used to get the peer process id back, then to confirm that 1603 * we've transferred any device locks to that process id. 1604 */ 1605 fd[1] = reply[1]; 1606 1607 nfd += 2; /* Include fd[0] and fd[1] */ 1608 memset(&msg, '\0', sizeof msg); 1609 1610 msg.msg_name = NULL; 1611 msg.msg_namelen = 0; 1612 /* 1613 * Only send the version to start... We used to send the whole lot, but 1614 * this caused problems with our RECVBUF size as a single link is about 1615 * 22k ! This way, we should bump into no limits. 1616 */ 1617 msg.msg_iovlen = 1; 1618 msg.msg_iov = iov; 1619 msg.msg_control = cmsgbuf; 1620 msg.msg_controllen = sizeof *cmsg + sizeof(int) * nfd; 1621 msg.msg_flags = 0; 1622 1623 cmsg = (struct cmsghdr *)cmsgbuf; 1624 cmsg->cmsg_len = msg.msg_controllen; 1625 cmsg->cmsg_level = SOL_SOCKET; 1626 cmsg->cmsg_type = SCM_RIGHTS; 1627 1628 for (f = 0; f < nfd; f++) 1629 *((int *)(cmsg + 1) + f) = fd[f]; 1630 1631 for (f = 1, expect = 0; f < niov; f++) 1632 expect += iov[f].iov_len; 1633 1634 if (setsockopt(reply[0], SOL_SOCKET, SO_SNDBUF, &expect, sizeof(int)) == -1) 1635 log_Printf(LogERROR, "setsockopt(SO_RCVBUF, %d): %s\n", expect, 1636 strerror(errno)); 1637 if (setsockopt(reply[1], SOL_SOCKET, SO_RCVBUF, &expect, sizeof(int)) == -1) 1638 log_Printf(LogERROR, "setsockopt(SO_RCVBUF, %d): %s\n", expect, 1639 strerror(errno)); 1640 1641 log_Printf(LogDEBUG, "Sending %d descriptor%s and %u bytes in scatter" 1642 "/gather array\n", nfd, nfd == 1 ? "" : "s", 1643 (unsigned)iov[0].iov_len); 1644 1645 if ((got = sendmsg(s, &msg, 0)) == -1) 1646 log_Printf(LogERROR, "Failed sendmsg: %s: %s\n", 1647 sun->sun_path, strerror(errno)); 1648 else if (got != iov[0].iov_len) 1649 log_Printf(LogERROR, "%s: Failed initial sendmsg: Only sent %d of %u\n", 1650 sun->sun_path, got, (unsigned)iov[0].iov_len); 1651 else { 1652 /* We must get the ACK before closing the descriptor ! */ 1653 int res; 1654 1655 if ((got = read(reply[0], &newpid, sizeof newpid)) == sizeof newpid) { 1656 log_Printf(LogDEBUG, "Received confirmation from pid %d\n", 1657 (int)newpid); 1658 if (lock && (res = ID0uu_lock_txfr(lock, newpid)) != UU_LOCK_OK) 1659 log_Printf(LogERROR, "uu_lock_txfr: %s\n", uu_lockerr(res)); 1660 1661 log_Printf(LogDEBUG, "Transmitting link (%d bytes)\n", expect); 1662 if ((got = writev(reply[0], iov + 1, niov - 1)) != expect) { 1663 if (got == -1) 1664 log_Printf(LogERROR, "%s: Failed writev: %s\n", 1665 sun->sun_path, strerror(errno)); 1666 else 1667 log_Printf(LogERROR, "%s: Failed writev: Wrote %d of %d\n", 1668 sun->sun_path, got, expect); 1669 } 1670 } else if (got == -1) 1671 log_Printf(LogERROR, "%s: Failed socketpair read: %s\n", 1672 sun->sun_path, strerror(errno)); 1673 else 1674 log_Printf(LogERROR, "%s: Failed socketpair read: Got %d of %d\n", 1675 sun->sun_path, got, (int)(sizeof newpid)); 1676 } 1677 1678 close(reply[0]); 1679 close(reply[1]); 1680 1681 newsid = Enabled(dl->bundle, OPT_KEEPSESSION) || 1682 tcgetpgrp(fd[0]) == getpgrp(); 1683 while (nfd) 1684 close(fd[--nfd]); 1685 if (newsid) 1686 bundle_setsid(dl->bundle, got != -1); 1687 } 1688 close(s); 1689 1690 while (niov--) 1691 free(iov[niov].iov_base); 1692} 1693 1694int 1695bundle_RenameDatalink(struct bundle *bundle, struct datalink *ndl, 1696 const char *name) 1697{ 1698 struct datalink *dl; 1699 1700 if (!strcasecmp(ndl->name, name)) 1701 return 1; 1702 1703 for (dl = bundle->links; dl; dl = dl->next) 1704 if (!strcasecmp(dl->name, name)) 1705 return 0; 1706 1707 datalink_Rename(ndl, name); 1708 return 1; 1709} 1710 1711int 1712bundle_SetMode(struct bundle *bundle, struct datalink *dl, int mode) 1713{ 1714 int omode; 1715 1716 omode = dl->physical->type; 1717 if (omode == mode) 1718 return 1; 1719 1720 if (mode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO)) 1721 /* First auto link */ 1722 if (bundle->ncp.ipcp.peer_ip.s_addr == INADDR_ANY) { 1723 log_Printf(LogWARN, "You must `set ifaddr' or `open' before" 1724 " changing mode to %s\n", mode2Nam(mode)); 1725 return 0; 1726 } 1727 1728 if (!datalink_SetMode(dl, mode)) 1729 return 0; 1730 1731 if (mode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO) && 1732 bundle->phase != PHASE_NETWORK) 1733 /* First auto link, we need an interface */ 1734 ipcp_InterfaceUp(&bundle->ncp.ipcp); 1735 1736 /* Regenerate phys_type and adjust idle timer */ 1737 bundle_LinksRemoved(bundle); 1738 1739 return 1; 1740} 1741 1742void 1743bundle_setsid(struct bundle *bundle, int holdsession) 1744{ 1745 /* 1746 * Lose the current session. This means getting rid of our pid 1747 * too so that the tty device will really go away, and any getty 1748 * etc will be allowed to restart. 1749 */ 1750 pid_t pid, orig; 1751 int fds[2]; 1752 char done; 1753 struct datalink *dl; 1754 1755 if (!holdsession && bundle_IsDead(bundle)) { 1756 /* 1757 * No need to lose our session after all... we're going away anyway 1758 * 1759 * We should really stop the timer and pause if holdsession is set and 1760 * the bundle's dead, but that leaves other resources lying about :-( 1761 */ 1762 return; 1763 } 1764 1765 orig = getpid(); 1766 if (pipe(fds) == -1) { 1767 log_Printf(LogERROR, "pipe: %s\n", strerror(errno)); 1768 return; 1769 } 1770 switch ((pid = fork())) { 1771 case -1: 1772 log_Printf(LogERROR, "fork: %s\n", strerror(errno)); 1773 close(fds[0]); 1774 close(fds[1]); 1775 return; 1776 case 0: 1777 close(fds[1]); 1778 read(fds[0], &done, 1); /* uu_locks are mine ! */ 1779 close(fds[0]); 1780 if (pipe(fds) == -1) { 1781 log_Printf(LogERROR, "pipe(2): %s\n", strerror(errno)); 1782 return; 1783 } 1784 switch ((pid = fork())) { 1785 case -1: 1786 log_Printf(LogERROR, "fork(2): %s\n", strerror(errno)); 1787 close(fds[0]); 1788 close(fds[1]); 1789 return; 1790 case 0: 1791 close(fds[1]); 1792 bundle_LockTun(bundle); /* update pid */ 1793 read(fds[0], &done, 1); /* uu_locks are mine ! */ 1794 close(fds[0]); 1795 setsid(); 1796 bundle_ChangedPID(bundle); 1797 log_Printf(LogDEBUG, "%d -> %d: %s session control\n", 1798 (int)orig, (int)getpid(), 1799 holdsession ? "Passed" : "Dropped"); 1800 timer_InitService(0); /* Start the Timer Service */ 1801 break; 1802 default: 1803 close(fds[0]); 1804 /* Give away all our physical locks (to the final process) */ 1805 for (dl = bundle->links; dl; dl = dl->next) 1806 if (dl->state != DATALINK_CLOSED) 1807 physical_ChangedPid(dl->physical, pid); 1808 write(fds[1], "!", 1); /* done */ 1809 close(fds[1]); 1810 _exit(0); 1811 break; 1812 } 1813 break; 1814 default: 1815 close(fds[0]); 1816 /* Give away all our physical locks (to the intermediate process) */ 1817 for (dl = bundle->links; dl; dl = dl->next) 1818 if (dl->state != DATALINK_CLOSED) 1819 physical_ChangedPid(dl->physical, pid); 1820 write(fds[1], "!", 1); /* done */ 1821 close(fds[1]); 1822 if (holdsession) { 1823 int fd, status; 1824 1825 timer_TermService(); 1826 signal(SIGPIPE, SIG_DFL); 1827 signal(SIGALRM, SIG_DFL); 1828 signal(SIGHUP, SIG_DFL); 1829 signal(SIGTERM, SIG_DFL); 1830 signal(SIGINT, SIG_DFL); 1831 signal(SIGQUIT, SIG_DFL); 1832 for (fd = getdtablesize(); fd >= 0; fd--) 1833 close(fd); 1834 /* 1835 * Reap the intermediate process. As we're not exiting but the 1836 * intermediate is, we don't want it to become defunct. 1837 */ 1838 waitpid(pid, &status, 0); 1839 /* Tweak our process arguments.... */ 1840 ID0setproctitle("session owner"); 1841 setuid(ID0realuid()); 1842 /* 1843 * Hang around for a HUP. This should happen as soon as the 1844 * ppp that we passed our ctty descriptor to closes it. 1845 * NOTE: If this process dies, the passed descriptor becomes 1846 * invalid and will give a select() error by setting one 1847 * of the error fds, aborting the other ppp. We don't 1848 * want that to happen ! 1849 */ 1850 pause(); 1851 } 1852 _exit(0); 1853 break; 1854 } 1855} 1856 1857int 1858bundle_HighestState(struct bundle *bundle) 1859{ 1860 struct datalink *dl; 1861 int result = DATALINK_CLOSED; 1862 1863 for (dl = bundle->links; dl; dl = dl->next) 1864 if (result < dl->state) 1865 result = dl->state; 1866 1867 return result; 1868} 1869 1870int 1871bundle_Exception(struct bundle *bundle, int fd) 1872{ 1873 struct datalink *dl; 1874 1875 for (dl = bundle->links; dl; dl = dl->next) 1876 if (dl->physical->fd == fd) { 1877 datalink_Down(dl, CLOSE_NORMAL); 1878 return 1; 1879 } 1880 1881 return 0; 1882} 1883 1884void 1885bundle_AdjustFilters(struct bundle *bundle, struct in_addr *my_ip, 1886 struct in_addr *peer_ip) 1887{ 1888 filter_AdjustAddr(&bundle->filter.in, my_ip, peer_ip, NULL); 1889 filter_AdjustAddr(&bundle->filter.out, my_ip, peer_ip, NULL); 1890 filter_AdjustAddr(&bundle->filter.dial, my_ip, peer_ip, NULL); 1891 filter_AdjustAddr(&bundle->filter.alive, my_ip, peer_ip, NULL); 1892} 1893 1894void 1895bundle_AdjustDNS(struct bundle *bundle, struct in_addr dns[2]) 1896{ 1897 filter_AdjustAddr(&bundle->filter.in, NULL, NULL, dns); 1898 filter_AdjustAddr(&bundle->filter.out, NULL, NULL, dns); 1899 filter_AdjustAddr(&bundle->filter.dial, NULL, NULL, dns); 1900 filter_AdjustAddr(&bundle->filter.alive, NULL, NULL, dns); 1901} 1902 1903void 1904bundle_CalculateBandwidth(struct bundle *bundle) 1905{ 1906 struct datalink *dl; 1907 int mtu, sp; 1908 1909 bundle->bandwidth = 0; 1910 mtu = 0; 1911 for (dl = bundle->links; dl; dl = dl->next) 1912 if (dl->state == DATALINK_OPEN) { 1913 if ((sp = dl->mp.bandwidth) == 0 && 1914 (sp = physical_GetSpeed(dl->physical)) == 0) 1915 log_Printf(LogDEBUG, "%s: %s: Cannot determine bandwidth\n", 1916 dl->name, dl->physical->name.full); 1917 else 1918 bundle->bandwidth += sp; 1919 if (!bundle->ncp.mp.active) { 1920 mtu = dl->physical->link.lcp.his_mru; 1921 break; 1922 } 1923 } 1924 1925 if(bundle->bandwidth == 0) 1926 bundle->bandwidth = 115200; /* Shrug */ 1927 1928 if (bundle->ncp.mp.active) 1929 mtu = bundle->ncp.mp.peer_mrru; 1930 else if (!mtu) 1931 mtu = 1500; 1932 1933#ifndef NORADIUS 1934 if (bundle->radius.valid && bundle->radius.mtu && bundle->radius.mtu < mtu) { 1935 log_Printf(LogLCP, "Reducing MTU to radius value %lu\n", 1936 bundle->radius.mtu); 1937 mtu = bundle->radius.mtu; 1938 } 1939#endif 1940 1941 tun_configure(bundle, mtu); 1942} 1943 1944void 1945bundle_AutoAdjust(struct bundle *bundle, int percent, int what) 1946{ 1947 struct datalink *dl, *choice, *otherlinkup; 1948 1949 choice = otherlinkup = NULL; 1950 for (dl = bundle->links; dl; dl = dl->next) 1951 if (dl->physical->type == PHYS_AUTO) { 1952 if (dl->state == DATALINK_OPEN) { 1953 if (what == AUTO_DOWN) { 1954 if (choice) 1955 otherlinkup = choice; 1956 choice = dl; 1957 } 1958 } else if (dl->state == DATALINK_CLOSED) { 1959 if (what == AUTO_UP) { 1960 choice = dl; 1961 break; 1962 } 1963 } else { 1964 /* An auto link in an intermediate state - forget it for the moment */ 1965 choice = NULL; 1966 break; 1967 } 1968 } else if (dl->state == DATALINK_OPEN && what == AUTO_DOWN) 1969 otherlinkup = dl; 1970 1971 if (choice) { 1972 if (what == AUTO_UP) { 1973 log_Printf(LogPHASE, "%d%% saturation -> Opening link ``%s''\n", 1974 percent, choice->name); 1975 datalink_Up(choice, 1, 1); 1976 mp_CheckAutoloadTimer(&bundle->ncp.mp); 1977 } else if (otherlinkup) { /* Only bring the second-last link down */ 1978 log_Printf(LogPHASE, "%d%% saturation -> Closing link ``%s''\n", 1979 percent, choice->name); 1980 datalink_Close(choice, CLOSE_STAYDOWN); 1981 mp_CheckAutoloadTimer(&bundle->ncp.mp); 1982 } 1983 } 1984} 1985 1986int 1987bundle_WantAutoloadTimer(struct bundle *bundle) 1988{ 1989 struct datalink *dl; 1990 int autolink, opened; 1991 1992 if (bundle->phase == PHASE_NETWORK) { 1993 for (autolink = opened = 0, dl = bundle->links; dl; dl = dl->next) 1994 if (dl->physical->type == PHYS_AUTO) { 1995 if (++autolink == 2 || (autolink == 1 && opened)) 1996 /* Two auto links or one auto and one open in NETWORK phase */ 1997 return 1; 1998 } else if (dl->state == DATALINK_OPEN) { 1999 opened++; 2000 if (autolink) 2001 /* One auto and one open link in NETWORK phase */ 2002 return 1; 2003 } 2004 } 2005 2006 return 0; 2007} 2008 2009void 2010bundle_ChangedPID(struct bundle *bundle) 2011{ 2012#ifdef TUNSIFPID 2013 ioctl(bundle->dev.fd, TUNSIFPID, 0); 2014#endif 2015} 2016