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