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