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