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