1 /*- 2 * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include <sys/param.h> 30 #include <netinet/in.h> 31 #include <netinet/in_systm.h> 32 #include <netinet/ip.h> 33 #include <sys/un.h> 34 35 #include <ctype.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <sys/uio.h> 40 #include <termios.h> 41 42 #include "layer.h" 43 #include "mbuf.h" 44 #include "log.h" 45 #include "defs.h" 46 #include "timer.h" 47 #include "fsm.h" 48 #include "lcp.h" 49 #include "descriptor.h" 50 #include "lqr.h" 51 #include "hdlc.h" 52 #include "async.h" 53 #include "throughput.h" 54 #include "ccp.h" 55 #include "link.h" 56 #include "physical.h" 57 #include "iplist.h" 58 #include "slcompress.h" 59 #include "ipcp.h" 60 #include "filter.h" 61 #include "mp.h" 62 #ifndef NORADIUS 63 #include "radius.h" 64 #endif 65 #include "bundle.h" 66 #include "chat.h" 67 #include "auth.h" 68 #include "prompt.h" 69 #include "proto.h" 70 #include "pap.h" 71 #include "chap.h" 72 #include "command.h" 73 #include "cbcp.h" 74 #include "datalink.h" 75 76 static void datalink_LoginDone(struct datalink *); 77 static void datalink_NewState(struct datalink *, int); 78 79 static void 80 datalink_OpenTimeout(void *v) 81 { 82 struct datalink *dl = (struct datalink *)v; 83 84 timer_Stop(&dl->dial.timer); 85 if (dl->state == DATALINK_OPENING) 86 log_Printf(LogPHASE, "%s: Redial timer expired.\n", dl->name); 87 } 88 89 static int 90 datalink_StartDialTimer(struct datalink *dl, int Timeout) 91 { 92 int result = Timeout; 93 94 timer_Stop(&dl->dial.timer); 95 if (Timeout) { 96 if (Timeout > 0) 97 dl->dial.timer.load = Timeout * SECTICKS; 98 else { 99 result = (random() % DIAL_TIMEOUT) + 1; 100 dl->dial.timer.load = result * SECTICKS; 101 } 102 dl->dial.timer.func = datalink_OpenTimeout; 103 dl->dial.timer.name = "dial"; 104 dl->dial.timer.arg = dl; 105 timer_Start(&dl->dial.timer); 106 if (dl->state == DATALINK_OPENING) 107 log_Printf(LogPHASE, "%s: Enter pause (%d) for redialing.\n", 108 dl->name, Timeout); 109 } 110 return result; 111 } 112 113 static void 114 datalink_HangupDone(struct datalink *dl) 115 { 116 if (dl->physical->type == PHYS_DEDICATED && !dl->bundle->CleaningUp && 117 dl->physical->fd != -1) { 118 /* Don't close our device if the link is dedicated */ 119 datalink_LoginDone(dl); 120 return; 121 } 122 123 chat_Finish(&dl->chat); 124 physical_Close(dl->physical); 125 dl->phone.chosen = "N/A"; 126 127 if (dl->cbcp.required) { 128 log_Printf(LogPHASE, "Call peer back on %s\n", dl->cbcp.fsm.phone); 129 dl->cfg.callback.opmask = 0; 130 strncpy(dl->cfg.phone.list, dl->cbcp.fsm.phone, 131 sizeof dl->cfg.phone.list - 1); 132 dl->cfg.phone.list[sizeof dl->cfg.phone.list - 1] = '\0'; 133 dl->phone.alt = dl->phone.next = NULL; 134 dl->reconnect_tries = dl->cfg.reconnect.max; 135 dl->dial.tries = dl->cfg.dial.max; 136 dl->dial.incs = 0; 137 dl->script.run = 1; 138 dl->script.packetmode = 1; 139 if (!physical_SetMode(dl->physical, PHYS_BACKGROUND)) 140 log_Printf(LogERROR, "Oops - can't change mode to BACKGROUND (gulp) !\n"); 141 bundle_LinksRemoved(dl->bundle); 142 /* if dial.timeout is < 0 (random), we don't override fsm.delay */ 143 if (dl->cbcp.fsm.delay < dl->cfg.dial.timeout) 144 dl->cbcp.fsm.delay = dl->cfg.dial.timeout; 145 datalink_StartDialTimer(dl, dl->cbcp.fsm.delay); 146 cbcp_Down(&dl->cbcp); 147 datalink_NewState(dl, DATALINK_OPENING); 148 if (bundle_Phase(dl->bundle) == PHASE_DEAD || 149 bundle_Phase(dl->bundle) == PHASE_TERMINATE) 150 bundle_NewPhase(dl->bundle, PHASE_ESTABLISH); 151 } else if (dl->bundle->CleaningUp || 152 (dl->physical->type == PHYS_DIRECT) || 153 ((!dl->dial.tries || (dl->dial.tries < 0 && !dl->reconnect_tries)) && 154 !(dl->physical->type & (PHYS_DDIAL|PHYS_DEDICATED)))) { 155 datalink_NewState(dl, DATALINK_CLOSED); 156 dl->dial.tries = -1; 157 dl->dial.incs = 0; 158 dl->reconnect_tries = 0; 159 bundle_LinkClosed(dl->bundle, dl); 160 if (!dl->bundle->CleaningUp) 161 datalink_StartDialTimer(dl, datalink_GetDialTimeout(dl)); 162 } else { 163 datalink_NewState(dl, DATALINK_OPENING); 164 if (bundle_Phase(dl->bundle) == PHASE_DEAD || 165 bundle_Phase(dl->bundle) == PHASE_TERMINATE) 166 bundle_NewPhase(dl->bundle, PHASE_ESTABLISH); 167 if (dl->dial.tries < 0) { 168 datalink_StartDialTimer(dl, dl->cfg.reconnect.timeout); 169 dl->dial.tries = dl->cfg.dial.max; 170 dl->dial.incs = 0; 171 dl->reconnect_tries--; 172 } else { 173 if (dl->phone.next == NULL) 174 datalink_StartDialTimer(dl, datalink_GetDialTimeout(dl)); 175 else 176 datalink_StartDialTimer(dl, dl->cfg.dial.next_timeout); 177 } 178 } 179 } 180 181 const char * 182 datalink_ChoosePhoneNumber(struct datalink *dl) 183 { 184 char *phone; 185 186 if (dl->phone.alt == NULL) { 187 if (dl->phone.next == NULL) { 188 strncpy(dl->phone.list, dl->cfg.phone.list, sizeof dl->phone.list - 1); 189 dl->phone.list[sizeof dl->phone.list - 1] = '\0'; 190 if (*dl->phone.list == '\0') 191 return ""; 192 dl->phone.next = dl->phone.list; 193 } 194 dl->phone.alt = strsep(&dl->phone.next, ":"); 195 } 196 phone = strsep(&dl->phone.alt, "|"); 197 dl->phone.chosen = *phone ? phone : "[NONE]"; 198 if (*phone) 199 log_Printf(LogPHASE, "Phone: %s\n", phone); 200 return phone; 201 } 202 203 static void 204 datalink_LoginDone(struct datalink *dl) 205 { 206 chat_Finish(&dl->chat); 207 208 if (!dl->script.packetmode) { 209 dl->dial.tries = -1; 210 dl->dial.incs = 0; 211 datalink_NewState(dl, DATALINK_READY); 212 } else if (!physical_Raw(dl->physical)) { 213 dl->dial.tries = 0; 214 log_Printf(LogWARN, "datalink_LoginDone: Not connected.\n"); 215 if (dl->script.run) { 216 datalink_NewState(dl, DATALINK_LOGOUT); 217 if (!chat_Setup(&dl->chat, dl->cfg.script.logout, NULL)) 218 log_Printf(LogWARN, "Invalid logout script\n"); 219 } else { 220 physical_StopDeviceTimer(dl->physical); 221 if (dl->physical->type == PHYS_DEDICATED) 222 /* force a redial timeout */ 223 physical_Close(dl->physical); 224 datalink_HangupDone(dl); 225 } 226 } else { 227 dl->dial.tries = -1; 228 dl->dial.incs = 0; 229 230 hdlc_Init(&dl->physical->hdlc, &dl->physical->link.lcp); 231 async_Init(&dl->physical->async); 232 233 lcp_Setup(&dl->physical->link.lcp, dl->state == DATALINK_READY ? 234 0 : dl->physical->link.lcp.cfg.openmode); 235 ccp_Setup(&dl->physical->link.ccp); 236 237 datalink_NewState(dl, DATALINK_LCP); 238 fsm_Up(&dl->physical->link.lcp.fsm); 239 fsm_Open(&dl->physical->link.lcp.fsm); 240 } 241 } 242 243 static int 244 datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, 245 int *n) 246 { 247 struct datalink *dl = descriptor2datalink(d); 248 int result; 249 250 result = 0; 251 switch (dl->state) { 252 case DATALINK_CLOSED: 253 if ((dl->physical->type & (PHYS_DIRECT|PHYS_DEDICATED|PHYS_BACKGROUND| 254 PHYS_FOREGROUND|PHYS_DDIAL)) && 255 !dl->bundle->CleaningUp) 256 /* 257 * Our first time in - DEDICATED & DDIAL never come down, and 258 * DIRECT, FOREGROUND & BACKGROUND get deleted when they enter 259 * DATALINK_CLOSED. Go to DATALINK_OPENING via datalink_Up() 260 * and fall through. 261 */ 262 datalink_Up(dl, 1, 1); 263 else 264 break; 265 /* fall through */ 266 267 case DATALINK_OPENING: 268 if (dl->dial.timer.state != TIMER_RUNNING) { 269 if (--dl->dial.tries < 0) 270 dl->dial.tries = 0; 271 if (physical_Open(dl->physical, dl->bundle) >= 0) { 272 log_WritePrompts(dl, "%s: Entering terminal mode on %s\r\n" 273 "Type `~?' for help\r\n", dl->name, 274 dl->physical->name.full); 275 if (dl->script.run) { 276 datalink_NewState(dl, DATALINK_DIAL); 277 if (!chat_Setup(&dl->chat, dl->cfg.script.dial, 278 *dl->cfg.script.dial ? 279 datalink_ChoosePhoneNumber(dl) : "")) 280 log_Printf(LogWARN, "Invalid dial script\n"); 281 if (!(dl->physical->type & (PHYS_DDIAL|PHYS_DEDICATED)) && 282 dl->cfg.dial.max) 283 log_Printf(LogCHAT, "%s: Dial attempt %u of %d\n", 284 dl->name, dl->cfg.dial.max - dl->dial.tries, 285 dl->cfg.dial.max); 286 } else 287 datalink_NewState(dl, DATALINK_CARRIER); 288 return datalink_UpdateSet(d, r, w, e, n); 289 } else { 290 if (!(dl->physical->type & (PHYS_DDIAL|PHYS_DEDICATED)) && 291 dl->cfg.dial.max) 292 log_Printf(LogCHAT, "Failed to open device (attempt %u of %d)\n", 293 dl->cfg.dial.max - dl->dial.tries, dl->cfg.dial.max); 294 else 295 log_Printf(LogCHAT, "Failed to open device\n"); 296 297 if (dl->bundle->CleaningUp || 298 (!(dl->physical->type & (PHYS_DDIAL|PHYS_DEDICATED)) && 299 dl->cfg.dial.max && dl->dial.tries == 0)) { 300 datalink_NewState(dl, DATALINK_CLOSED); 301 dl->reconnect_tries = 0; 302 dl->dial.tries = -1; 303 log_WritePrompts(dl, "Failed to open %s\n", 304 dl->physical->name.full); 305 bundle_LinkClosed(dl->bundle, dl); 306 } 307 if (!dl->bundle->CleaningUp) { 308 int timeout; 309 310 timeout = datalink_StartDialTimer(dl, datalink_GetDialTimeout(dl)); 311 log_WritePrompts(dl, "Failed to open %s, pause %d seconds\n", 312 dl->physical->name.full, timeout); 313 } 314 } 315 } 316 break; 317 318 case DATALINK_CARRIER: 319 /* Wait for carrier on the device */ 320 switch (physical_AwaitCarrier(dl->physical)) { 321 case CARRIER_PENDING: 322 log_Printf(LogDEBUG, "Waiting for carrier\n"); 323 return 0; /* A device timer is running to wake us up again */ 324 325 case CARRIER_OK: 326 if (dl->script.run) { 327 datalink_NewState(dl, DATALINK_LOGIN); 328 if (!chat_Setup(&dl->chat, dl->cfg.script.login, NULL)) 329 log_Printf(LogWARN, "Invalid login script\n"); 330 } else 331 datalink_LoginDone(dl); 332 return datalink_UpdateSet(d, r, w, e, n); 333 334 case CARRIER_LOST: 335 physical_Offline(dl->physical); /* Is this required ? */ 336 if (dl->script.run) { 337 datalink_NewState(dl, DATALINK_HANGUP); 338 if (!chat_Setup(&dl->chat, dl->cfg.script.hangup, NULL)) 339 log_Printf(LogWARN, "Invalid hangup script\n"); 340 return datalink_UpdateSet(d, r, w, e, n); 341 } else { 342 datalink_HangupDone(dl); 343 return 0; /* Maybe bundle_CleanDatalinks() has something to do */ 344 } 345 } 346 347 case DATALINK_HANGUP: 348 case DATALINK_DIAL: 349 case DATALINK_LOGOUT: 350 case DATALINK_LOGIN: 351 result = descriptor_UpdateSet(&dl->chat.desc, r, w, e, n); 352 switch (dl->chat.state) { 353 case CHAT_DONE: 354 /* script succeeded */ 355 switch(dl->state) { 356 case DATALINK_HANGUP: 357 datalink_HangupDone(dl); 358 break; 359 case DATALINK_DIAL: 360 datalink_NewState(dl, DATALINK_CARRIER); 361 return datalink_UpdateSet(d, r, w, e, n); 362 case DATALINK_LOGOUT: 363 datalink_NewState(dl, DATALINK_HANGUP); 364 physical_Offline(dl->physical); 365 if (!chat_Setup(&dl->chat, dl->cfg.script.hangup, NULL)) 366 log_Printf(LogWARN, "Invalid hangup script\n"); 367 return datalink_UpdateSet(d, r, w, e, n); 368 case DATALINK_LOGIN: 369 dl->phone.alt = NULL; 370 datalink_LoginDone(dl); 371 return datalink_UpdateSet(d, r, w, e, n); 372 } 373 break; 374 case CHAT_FAILED: 375 /* Going down - script failed */ 376 log_Printf(LogWARN, "Chat script failed\n"); 377 switch(dl->state) { 378 case DATALINK_HANGUP: 379 datalink_HangupDone(dl); 380 break; 381 case DATALINK_DIAL: 382 case DATALINK_LOGOUT: 383 case DATALINK_LOGIN: 384 datalink_NewState(dl, DATALINK_HANGUP); 385 physical_Offline(dl->physical); 386 if (!chat_Setup(&dl->chat, dl->cfg.script.hangup, NULL)) 387 log_Printf(LogWARN, "Invalid hangup script\n"); 388 return datalink_UpdateSet(d, r, w, e, n); 389 } 390 break; 391 } 392 break; 393 394 case DATALINK_READY: 395 case DATALINK_LCP: 396 case DATALINK_AUTH: 397 case DATALINK_CBCP: 398 case DATALINK_OPEN: 399 result = descriptor_UpdateSet(&dl->chap.desc, r, w, e, n) + 400 descriptor_UpdateSet(&dl->physical->desc, r, w, e, n); 401 break; 402 } 403 return result; 404 } 405 406 int 407 datalink_RemoveFromSet(struct datalink *dl, fd_set *r, fd_set *w, fd_set *e) 408 { 409 return physical_RemoveFromSet(dl->physical, r, w, e); 410 } 411 412 static int 413 datalink_IsSet(struct descriptor *d, const fd_set *fdset) 414 { 415 struct datalink *dl = descriptor2datalink(d); 416 417 switch (dl->state) { 418 case DATALINK_CLOSED: 419 case DATALINK_OPENING: 420 break; 421 422 case DATALINK_HANGUP: 423 case DATALINK_DIAL: 424 case DATALINK_LOGOUT: 425 case DATALINK_LOGIN: 426 return descriptor_IsSet(&dl->chat.desc, fdset); 427 428 case DATALINK_READY: 429 case DATALINK_LCP: 430 case DATALINK_AUTH: 431 case DATALINK_CBCP: 432 case DATALINK_OPEN: 433 return descriptor_IsSet(&dl->chap.desc, fdset) ? 1 : 434 descriptor_IsSet(&dl->physical->desc, fdset); 435 } 436 return 0; 437 } 438 439 static void 440 datalink_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) 441 { 442 struct datalink *dl = descriptor2datalink(d); 443 444 switch (dl->state) { 445 case DATALINK_CLOSED: 446 case DATALINK_OPENING: 447 break; 448 449 case DATALINK_HANGUP: 450 case DATALINK_DIAL: 451 case DATALINK_LOGOUT: 452 case DATALINK_LOGIN: 453 descriptor_Read(&dl->chat.desc, bundle, fdset); 454 break; 455 456 case DATALINK_READY: 457 case DATALINK_LCP: 458 case DATALINK_AUTH: 459 case DATALINK_CBCP: 460 case DATALINK_OPEN: 461 if (descriptor_IsSet(&dl->chap.desc, fdset)) 462 descriptor_Read(&dl->chap.desc, bundle, fdset); 463 if (descriptor_IsSet(&dl->physical->desc, fdset)) 464 descriptor_Read(&dl->physical->desc, bundle, fdset); 465 break; 466 } 467 } 468 469 static int 470 datalink_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) 471 { 472 struct datalink *dl = descriptor2datalink(d); 473 int result = 0; 474 475 switch (dl->state) { 476 case DATALINK_CLOSED: 477 case DATALINK_OPENING: 478 break; 479 480 case DATALINK_HANGUP: 481 case DATALINK_DIAL: 482 case DATALINK_LOGOUT: 483 case DATALINK_LOGIN: 484 result = descriptor_Write(&dl->chat.desc, bundle, fdset); 485 break; 486 487 case DATALINK_READY: 488 case DATALINK_LCP: 489 case DATALINK_AUTH: 490 case DATALINK_CBCP: 491 case DATALINK_OPEN: 492 if (descriptor_IsSet(&dl->chap.desc, fdset)) 493 result += descriptor_Write(&dl->chap.desc, bundle, fdset); 494 if (descriptor_IsSet(&dl->physical->desc, fdset)) 495 result += descriptor_Write(&dl->physical->desc, bundle, fdset); 496 break; 497 } 498 499 return result; 500 } 501 502 static void 503 datalink_ComeDown(struct datalink *dl, int how) 504 { 505 if (how != CLOSE_NORMAL) { 506 dl->dial.tries = -1; 507 dl->reconnect_tries = 0; 508 if (dl->state >= DATALINK_READY && how == CLOSE_LCP) 509 dl->stayonline = 1; 510 } 511 512 if (dl->state >= DATALINK_READY && dl->stayonline) { 513 dl->stayonline = 0; 514 physical_StopDeviceTimer(dl->physical); 515 datalink_NewState(dl, DATALINK_READY); 516 } else if (dl->state != DATALINK_CLOSED && dl->state != DATALINK_HANGUP) { 517 physical_Offline(dl->physical); 518 if (dl->script.run && dl->state != DATALINK_OPENING) { 519 if (dl->state == DATALINK_LOGOUT) { 520 datalink_NewState(dl, DATALINK_HANGUP); 521 if (!chat_Setup(&dl->chat, dl->cfg.script.hangup, NULL)) 522 log_Printf(LogWARN, "Invalid hangup script\n"); 523 } else { 524 datalink_NewState(dl, DATALINK_LOGOUT); 525 if (!chat_Setup(&dl->chat, dl->cfg.script.logout, NULL)) 526 log_Printf(LogWARN, "Invalid logout script\n"); 527 } 528 } else 529 datalink_HangupDone(dl); 530 } 531 } 532 533 static void 534 datalink_LayerStart(void *v, struct fsm *fp) 535 { 536 /* The given FSM is about to start up ! */ 537 struct datalink *dl = (struct datalink *)v; 538 539 if (fp->proto == PROTO_LCP) 540 (*dl->parent->LayerStart)(dl->parent->object, fp); 541 } 542 543 static void 544 datalink_LayerUp(void *v, struct fsm *fp) 545 { 546 /* The given fsm is now up */ 547 struct datalink *dl = (struct datalink *)v; 548 struct lcp *lcp = &dl->physical->link.lcp; 549 550 if (fp->proto == PROTO_LCP) { 551 datalink_GotAuthname(dl, ""); 552 lcp->auth_ineed = lcp->want_auth; 553 lcp->auth_iwait = lcp->his_auth; 554 if (lcp->his_auth || lcp->want_auth) { 555 if (bundle_Phase(dl->bundle) != PHASE_NETWORK) 556 bundle_NewPhase(dl->bundle, PHASE_AUTHENTICATE); 557 log_Printf(LogPHASE, "%s: his = %s, mine = %s\n", dl->name, 558 Auth2Nam(lcp->his_auth, lcp->his_authtype), 559 Auth2Nam(lcp->want_auth, lcp->want_authtype)); 560 if (lcp->his_auth == PROTO_PAP) 561 auth_StartReq(&dl->pap); 562 if (lcp->want_auth == PROTO_CHAP) 563 auth_StartReq(&dl->chap.auth); 564 } else 565 datalink_AuthOk(dl); 566 } 567 } 568 569 static void 570 datalink_AuthReInit(struct datalink *dl) 571 { 572 auth_StopTimer(&dl->pap); 573 auth_StopTimer(&dl->chap.auth); 574 chap_ReInit(&dl->chap); 575 } 576 577 void 578 datalink_GotAuthname(struct datalink *dl, const char *name) 579 { 580 strncpy(dl->peer.authname, name, sizeof dl->peer.authname - 1); 581 dl->peer.authname[sizeof dl->peer.authname - 1] = '\0'; 582 } 583 584 void 585 datalink_NCPUp(struct datalink *dl) 586 { 587 int ccpok = ccp_SetOpenMode(&dl->physical->link.ccp); 588 589 if (dl->physical->link.lcp.want_mrru && dl->physical->link.lcp.his_mrru) { 590 /* we've authenticated in multilink mode ! */ 591 switch (mp_Up(&dl->bundle->ncp.mp, dl)) { 592 case MP_LINKSENT: 593 /* We've handed the link off to another ppp (well, we will soon) ! */ 594 return; 595 case MP_UP: 596 /* First link in the bundle */ 597 auth_Select(dl->bundle, dl->peer.authname); 598 bundle_CalculateBandwidth(dl->bundle); 599 /* fall through */ 600 case MP_ADDED: 601 /* We're in multilink mode ! */ 602 dl->physical->link.ccp.fsm.open_mode = OPEN_PASSIVE; /* override */ 603 bundle_CalculateBandwidth(dl->bundle); 604 break; 605 case MP_FAILED: 606 datalink_AuthNotOk(dl); 607 return; 608 } 609 } else if (bundle_Phase(dl->bundle) == PHASE_NETWORK) { 610 log_Printf(LogPHASE, "%s: Already in NETWORK phase\n", dl->name); 611 datalink_NewState(dl, DATALINK_OPEN); 612 bundle_CalculateBandwidth(dl->bundle); 613 (*dl->parent->LayerUp)(dl->parent->object, &dl->physical->link.lcp.fsm); 614 return; 615 } else { 616 dl->bundle->ncp.mp.peer = dl->peer; 617 ipcp_SetLink(&dl->bundle->ncp.ipcp, &dl->physical->link); 618 auth_Select(dl->bundle, dl->peer.authname); 619 } 620 621 if (ccpok) { 622 fsm_Up(&dl->physical->link.ccp.fsm); 623 fsm_Open(&dl->physical->link.ccp.fsm); 624 } 625 datalink_NewState(dl, DATALINK_OPEN); 626 bundle_NewPhase(dl->bundle, PHASE_NETWORK); 627 (*dl->parent->LayerUp)(dl->parent->object, &dl->physical->link.lcp.fsm); 628 } 629 630 void 631 datalink_CBCPComplete(struct datalink *dl) 632 { 633 datalink_NewState(dl, DATALINK_LCP); 634 datalink_AuthReInit(dl); 635 fsm_Close(&dl->physical->link.lcp.fsm); 636 } 637 638 void 639 datalink_CBCPFailed(struct datalink *dl) 640 { 641 cbcp_Down(&dl->cbcp); 642 datalink_CBCPComplete(dl); 643 } 644 645 void 646 datalink_AuthOk(struct datalink *dl) 647 { 648 if ((dl->physical->link.lcp.his_callback.opmask & 649 CALLBACK_BIT(CALLBACK_CBCP) || 650 dl->physical->link.lcp.want_callback.opmask & 651 CALLBACK_BIT(CALLBACK_CBCP)) && 652 !(dl->physical->link.lcp.want_callback.opmask & 653 CALLBACK_BIT(CALLBACK_AUTH))) { 654 /* We must have agreed CBCP if AUTH isn't there any more */ 655 datalink_NewState(dl, DATALINK_CBCP); 656 cbcp_Up(&dl->cbcp); 657 } else if (dl->physical->link.lcp.want_callback.opmask) { 658 /* It's not CBCP */ 659 log_Printf(LogPHASE, "%s: Shutdown and await peer callback\n", dl->name); 660 datalink_NewState(dl, DATALINK_LCP); 661 datalink_AuthReInit(dl); 662 fsm_Close(&dl->physical->link.lcp.fsm); 663 } else 664 switch (dl->physical->link.lcp.his_callback.opmask) { 665 case 0: 666 datalink_NCPUp(dl); 667 break; 668 669 case CALLBACK_BIT(CALLBACK_AUTH): 670 auth_SetPhoneList(dl->peer.authname, dl->cbcp.fsm.phone, 671 sizeof dl->cbcp.fsm.phone); 672 if (*dl->cbcp.fsm.phone == '\0' || !strcmp(dl->cbcp.fsm.phone, "*")) { 673 log_Printf(LogPHASE, "%s: %s cannot be called back\n", dl->name, 674 dl->peer.authname); 675 *dl->cbcp.fsm.phone = '\0'; 676 } else { 677 char *ptr = strchr(dl->cbcp.fsm.phone, ','); 678 if (ptr) 679 *ptr = '\0'; /* Call back on the first number */ 680 log_Printf(LogPHASE, "%s: Calling peer back on %s\n", dl->name, 681 dl->cbcp.fsm.phone); 682 dl->cbcp.required = 1; 683 } 684 dl->cbcp.fsm.delay = 0; 685 datalink_NewState(dl, DATALINK_LCP); 686 datalink_AuthReInit(dl); 687 fsm_Close(&dl->physical->link.lcp.fsm); 688 break; 689 690 case CALLBACK_BIT(CALLBACK_E164): 691 strncpy(dl->cbcp.fsm.phone, dl->physical->link.lcp.his_callback.msg, 692 sizeof dl->cbcp.fsm.phone - 1); 693 dl->cbcp.fsm.phone[sizeof dl->cbcp.fsm.phone - 1] = '\0'; 694 log_Printf(LogPHASE, "%s: Calling peer back on %s\n", dl->name, 695 dl->cbcp.fsm.phone); 696 dl->cbcp.required = 1; 697 dl->cbcp.fsm.delay = 0; 698 datalink_NewState(dl, DATALINK_LCP); 699 datalink_AuthReInit(dl); 700 fsm_Close(&dl->physical->link.lcp.fsm); 701 break; 702 703 default: 704 log_Printf(LogPHASE, "%s: Oops - Should have NAK'd peer callback !\n", 705 dl->name); 706 datalink_NewState(dl, DATALINK_LCP); 707 datalink_AuthReInit(dl); 708 fsm_Close(&dl->physical->link.lcp.fsm); 709 break; 710 } 711 } 712 713 void 714 datalink_AuthNotOk(struct datalink *dl) 715 { 716 datalink_NewState(dl, DATALINK_LCP); 717 datalink_AuthReInit(dl); 718 fsm_Close(&dl->physical->link.lcp.fsm); 719 } 720 721 static void 722 datalink_LayerDown(void *v, struct fsm *fp) 723 { 724 /* The given FSM has been told to come down */ 725 struct datalink *dl = (struct datalink *)v; 726 727 if (fp->proto == PROTO_LCP) { 728 switch (dl->state) { 729 case DATALINK_OPEN: 730 peerid_Init(&dl->peer); 731 fsm2initial(&dl->physical->link.ccp.fsm); 732 datalink_NewState(dl, DATALINK_LCP); /* before parent TLD */ 733 (*dl->parent->LayerDown)(dl->parent->object, fp); 734 /* fall through (just in case) */ 735 736 case DATALINK_CBCP: 737 if (!dl->cbcp.required) 738 cbcp_Down(&dl->cbcp); 739 /* fall through (just in case) */ 740 741 case DATALINK_AUTH: 742 timer_Stop(&dl->pap.authtimer); 743 timer_Stop(&dl->chap.auth.authtimer); 744 } 745 datalink_NewState(dl, DATALINK_LCP); 746 datalink_AuthReInit(dl); 747 } 748 } 749 750 static void 751 datalink_LayerFinish(void *v, struct fsm *fp) 752 { 753 /* The given fsm is now down */ 754 struct datalink *dl = (struct datalink *)v; 755 756 if (fp->proto == PROTO_LCP) { 757 fsm2initial(fp); 758 (*dl->parent->LayerFinish)(dl->parent->object, fp); 759 datalink_ComeDown(dl, CLOSE_NORMAL); 760 } else if (fp->state == ST_CLOSED && fp->open_mode == OPEN_PASSIVE) 761 fsm_Open(fp); /* CCP goes to ST_STOPPED */ 762 } 763 764 struct datalink * 765 datalink_Create(const char *name, struct bundle *bundle, int type) 766 { 767 struct datalink *dl; 768 769 dl = (struct datalink *)malloc(sizeof(struct datalink)); 770 if (dl == NULL) 771 return dl; 772 773 dl->desc.type = DATALINK_DESCRIPTOR; 774 dl->desc.UpdateSet = datalink_UpdateSet; 775 dl->desc.IsSet = datalink_IsSet; 776 dl->desc.Read = datalink_Read; 777 dl->desc.Write = datalink_Write; 778 779 dl->state = DATALINK_CLOSED; 780 781 *dl->cfg.script.dial = '\0'; 782 *dl->cfg.script.login = '\0'; 783 *dl->cfg.script.logout = '\0'; 784 *dl->cfg.script.hangup = '\0'; 785 *dl->cfg.phone.list = '\0'; 786 *dl->phone.list = '\0'; 787 dl->phone.next = NULL; 788 dl->phone.alt = NULL; 789 dl->phone.chosen = "N/A"; 790 dl->stayonline = 0; 791 dl->script.run = 1; 792 dl->script.packetmode = 1; 793 mp_linkInit(&dl->mp); 794 795 dl->bundle = bundle; 796 dl->next = NULL; 797 798 memset(&dl->dial.timer, '\0', sizeof dl->dial.timer); 799 800 dl->dial.tries = 0; 801 dl->cfg.dial.max = 1; 802 dl->cfg.dial.next_timeout = DIAL_NEXT_TIMEOUT; 803 dl->cfg.dial.timeout = DIAL_TIMEOUT; 804 dl->cfg.dial.inc = 0; 805 dl->cfg.dial.maxinc = 10; 806 807 dl->reconnect_tries = 0; 808 dl->cfg.reconnect.max = 0; 809 dl->cfg.reconnect.timeout = RECONNECT_TIMEOUT; 810 811 dl->cfg.callback.opmask = 0; 812 dl->cfg.cbcp.delay = 0; 813 *dl->cfg.cbcp.phone = '\0'; 814 dl->cfg.cbcp.fsmretry = DEF_FSMRETRY; 815 816 dl->name = strdup(name); 817 peerid_Init(&dl->peer); 818 dl->parent = &bundle->fsm; 819 dl->fsmp.LayerStart = datalink_LayerStart; 820 dl->fsmp.LayerUp = datalink_LayerUp; 821 dl->fsmp.LayerDown = datalink_LayerDown; 822 dl->fsmp.LayerFinish = datalink_LayerFinish; 823 dl->fsmp.object = dl; 824 825 if ((dl->physical = physical_Create(dl, type)) == NULL) { 826 free(dl->name); 827 free(dl); 828 return NULL; 829 } 830 831 pap_Init(&dl->pap, dl->physical); 832 chap_Init(&dl->chap, dl->physical); 833 cbcp_Init(&dl->cbcp, dl->physical); 834 835 memset(&dl->chat, '\0', sizeof dl->chat); /* Force buf{start,end} reset */ 836 chat_Init(&dl->chat, dl->physical); 837 838 log_Printf(LogPHASE, "%s: Created in %s state\n", 839 dl->name, datalink_State(dl)); 840 841 return dl; 842 } 843 844 struct datalink * 845 datalink_Clone(struct datalink *odl, const char *name) 846 { 847 struct datalink *dl; 848 849 dl = (struct datalink *)malloc(sizeof(struct datalink)); 850 if (dl == NULL) 851 return dl; 852 853 dl->desc.type = DATALINK_DESCRIPTOR; 854 dl->desc.UpdateSet = datalink_UpdateSet; 855 dl->desc.IsSet = datalink_IsSet; 856 dl->desc.Read = datalink_Read; 857 dl->desc.Write = datalink_Write; 858 859 dl->state = DATALINK_CLOSED; 860 861 memcpy(&dl->cfg, &odl->cfg, sizeof dl->cfg); 862 mp_linkInit(&dl->mp); 863 *dl->phone.list = '\0'; 864 dl->phone.next = NULL; 865 dl->phone.alt = NULL; 866 dl->phone.chosen = "N/A"; 867 dl->bundle = odl->bundle; 868 dl->next = NULL; 869 memset(&dl->dial.timer, '\0', sizeof dl->dial.timer); 870 dl->dial.tries = 0; 871 dl->reconnect_tries = 0; 872 dl->name = strdup(name); 873 peerid_Init(&dl->peer); 874 dl->parent = odl->parent; 875 memcpy(&dl->fsmp, &odl->fsmp, sizeof dl->fsmp); 876 dl->fsmp.object = dl; 877 878 if ((dl->physical = physical_Create(dl, PHYS_INTERACTIVE)) == NULL) { 879 free(dl->name); 880 free(dl); 881 return NULL; 882 } 883 pap_Init(&dl->pap, dl->physical); 884 dl->pap.cfg = odl->pap.cfg; 885 886 chap_Init(&dl->chap, dl->physical); 887 dl->chap.auth.cfg = odl->chap.auth.cfg; 888 889 memcpy(&dl->physical->cfg, &odl->physical->cfg, sizeof dl->physical->cfg); 890 memcpy(&dl->physical->link.lcp.cfg, &odl->physical->link.lcp.cfg, 891 sizeof dl->physical->link.lcp.cfg); 892 memcpy(&dl->physical->link.ccp.cfg, &odl->physical->link.ccp.cfg, 893 sizeof dl->physical->link.ccp.cfg); 894 memcpy(&dl->physical->async.cfg, &odl->physical->async.cfg, 895 sizeof dl->physical->async.cfg); 896 897 cbcp_Init(&dl->cbcp, dl->physical); 898 899 memset(&dl->chat, '\0', sizeof dl->chat); /* Force buf{start,end} reset */ 900 chat_Init(&dl->chat, dl->physical); 901 902 log_Printf(LogPHASE, "%s: Cloned in %s state\n", 903 dl->name, datalink_State(dl)); 904 905 return dl; 906 } 907 908 struct datalink * 909 datalink_Destroy(struct datalink *dl) 910 { 911 struct datalink *result; 912 913 if (dl->state != DATALINK_CLOSED) { 914 log_Printf(LogERROR, "Oops, destroying a datalink in state %s\n", 915 datalink_State(dl)); 916 switch (dl->state) { 917 case DATALINK_HANGUP: 918 case DATALINK_DIAL: 919 case DATALINK_LOGIN: 920 chat_Finish(&dl->chat); /* Gotta blat the timers ! */ 921 break; 922 } 923 } 924 925 chat_Destroy(&dl->chat); 926 timer_Stop(&dl->dial.timer); 927 result = dl->next; 928 physical_Destroy(dl->physical); 929 free(dl->name); 930 free(dl); 931 932 return result; 933 } 934 935 void 936 datalink_Up(struct datalink *dl, int runscripts, int packetmode) 937 { 938 if (dl->physical->type & (PHYS_DIRECT|PHYS_DEDICATED)) 939 /* Ignore scripts */ 940 runscripts = 0; 941 942 switch (dl->state) { 943 case DATALINK_CLOSED: 944 if (bundle_Phase(dl->bundle) == PHASE_DEAD || 945 bundle_Phase(dl->bundle) == PHASE_TERMINATE) 946 bundle_NewPhase(dl->bundle, PHASE_ESTABLISH); 947 datalink_NewState(dl, DATALINK_OPENING); 948 dl->reconnect_tries = 949 dl->physical->type == PHYS_DIRECT ? 0 : dl->cfg.reconnect.max; 950 dl->dial.tries = dl->cfg.dial.max; 951 dl->script.run = runscripts; 952 dl->script.packetmode = packetmode; 953 break; 954 955 case DATALINK_OPENING: 956 if (!dl->script.run && runscripts) 957 dl->script.run = 1; 958 /* fall through */ 959 960 case DATALINK_DIAL: 961 case DATALINK_LOGIN: 962 case DATALINK_READY: 963 if (!dl->script.packetmode && packetmode) { 964 dl->script.packetmode = 1; 965 if (dl->state == DATALINK_READY) 966 datalink_LoginDone(dl); 967 } 968 break; 969 } 970 } 971 972 void 973 datalink_Close(struct datalink *dl, int how) 974 { 975 /* Please close */ 976 switch (dl->state) { 977 case DATALINK_OPEN: 978 peerid_Init(&dl->peer); 979 fsm2initial(&dl->physical->link.ccp.fsm); 980 /* fall through */ 981 982 case DATALINK_CBCP: 983 case DATALINK_AUTH: 984 case DATALINK_LCP: 985 datalink_AuthReInit(dl); 986 fsm_Close(&dl->physical->link.lcp.fsm); 987 if (how != CLOSE_NORMAL) { 988 dl->dial.tries = -1; 989 dl->reconnect_tries = 0; 990 if (how == CLOSE_LCP) 991 dl->stayonline = 1; 992 } 993 break; 994 995 default: 996 datalink_ComeDown(dl, how); 997 } 998 } 999 1000 void 1001 datalink_Down(struct datalink *dl, int how) 1002 { 1003 /* Carrier is lost */ 1004 switch (dl->state) { 1005 case DATALINK_OPEN: 1006 peerid_Init(&dl->peer); 1007 fsm2initial(&dl->physical->link.ccp.fsm); 1008 /* fall through */ 1009 1010 case DATALINK_CBCP: 1011 case DATALINK_AUTH: 1012 case DATALINK_LCP: 1013 fsm2initial(&dl->physical->link.lcp.fsm); 1014 if (dl->state == DATALINK_OPENING) 1015 return; /* we're doing a callback... */ 1016 /* fall through */ 1017 1018 default: 1019 datalink_ComeDown(dl, how); 1020 } 1021 } 1022 1023 void 1024 datalink_StayDown(struct datalink *dl) 1025 { 1026 dl->reconnect_tries = 0; 1027 } 1028 1029 void 1030 datalink_DontHangup(struct datalink *dl) 1031 { 1032 if (dl->state >= DATALINK_LCP) 1033 dl->stayonline = 1; 1034 } 1035 1036 int 1037 datalink_Show(struct cmdargs const *arg) 1038 { 1039 prompt_Printf(arg->prompt, "Name: %s\n", arg->cx->name); 1040 prompt_Printf(arg->prompt, " State: %s\n", 1041 datalink_State(arg->cx)); 1042 prompt_Printf(arg->prompt, " Peer name: "); 1043 if (*arg->cx->peer.authname) 1044 prompt_Printf(arg->prompt, "%s\n", arg->cx->peer.authname); 1045 else if (arg->cx->state == DATALINK_OPEN) 1046 prompt_Printf(arg->prompt, "None requested\n"); 1047 else 1048 prompt_Printf(arg->prompt, "N/A\n"); 1049 prompt_Printf(arg->prompt, " Discriminator: %s\n", 1050 mp_Enddisc(arg->cx->peer.enddisc.class, 1051 arg->cx->peer.enddisc.address, 1052 arg->cx->peer.enddisc.len)); 1053 1054 prompt_Printf(arg->prompt, "\nDefaults:\n"); 1055 prompt_Printf(arg->prompt, " Phone List: %s\n", 1056 arg->cx->cfg.phone.list); 1057 if (arg->cx->cfg.dial.max) 1058 prompt_Printf(arg->prompt, " Dial tries: %d, delay ", 1059 arg->cx->cfg.dial.max); 1060 else 1061 prompt_Printf(arg->prompt, " Dial tries: infinite, delay "); 1062 if (arg->cx->cfg.dial.next_timeout >= 0) 1063 prompt_Printf(arg->prompt, "%ds/", arg->cx->cfg.dial.next_timeout); 1064 else 1065 prompt_Printf(arg->prompt, "random/"); 1066 if (arg->cx->cfg.dial.timeout >= 0) 1067 prompt_Printf(arg->prompt, "%ds\n", arg->cx->cfg.dial.timeout); 1068 else 1069 prompt_Printf(arg->prompt, "random\n"); 1070 prompt_Printf(arg->prompt, " Reconnect tries: %d, delay ", 1071 arg->cx->cfg.reconnect.max); 1072 if (arg->cx->cfg.reconnect.timeout > 0) 1073 prompt_Printf(arg->prompt, "%ds\n", arg->cx->cfg.reconnect.timeout); 1074 else 1075 prompt_Printf(arg->prompt, "random\n"); 1076 prompt_Printf(arg->prompt, " Callback %s ", arg->cx->physical->type == 1077 PHYS_DIRECT ? "accepted: " : "requested:"); 1078 if (!arg->cx->cfg.callback.opmask) 1079 prompt_Printf(arg->prompt, "none\n"); 1080 else { 1081 int comma = 0; 1082 1083 if (arg->cx->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_NONE)) { 1084 prompt_Printf(arg->prompt, "none"); 1085 comma = 1; 1086 } 1087 if (arg->cx->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) { 1088 prompt_Printf(arg->prompt, "%sauth", comma ? ", " : ""); 1089 comma = 1; 1090 } 1091 if (arg->cx->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164)) { 1092 prompt_Printf(arg->prompt, "%sE.164", comma ? ", " : ""); 1093 if (arg->cx->physical->type != PHYS_DIRECT) 1094 prompt_Printf(arg->prompt, " (%s)", arg->cx->cfg.callback.msg); 1095 comma = 1; 1096 } 1097 if (arg->cx->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) { 1098 prompt_Printf(arg->prompt, "%scbcp\n", comma ? ", " : ""); 1099 prompt_Printf(arg->prompt, " CBCP: delay: %ds\n", 1100 arg->cx->cfg.cbcp.delay); 1101 prompt_Printf(arg->prompt, " phone: "); 1102 if (!strcmp(arg->cx->cfg.cbcp.phone, "*")) { 1103 if (arg->cx->physical->type & PHYS_DIRECT) 1104 prompt_Printf(arg->prompt, "Caller decides\n"); 1105 else 1106 prompt_Printf(arg->prompt, "Dialback server decides\n"); 1107 } else 1108 prompt_Printf(arg->prompt, "%s\n", arg->cx->cfg.cbcp.phone); 1109 prompt_Printf(arg->prompt, " timeout: %lds\n", 1110 arg->cx->cfg.cbcp.fsmretry); 1111 } else 1112 prompt_Printf(arg->prompt, "\n"); 1113 } 1114 1115 prompt_Printf(arg->prompt, " Dial Script: %s\n", 1116 arg->cx->cfg.script.dial); 1117 prompt_Printf(arg->prompt, " Login Script: %s\n", 1118 arg->cx->cfg.script.login); 1119 prompt_Printf(arg->prompt, " Logout Script: %s\n", 1120 arg->cx->cfg.script.logout); 1121 prompt_Printf(arg->prompt, " Hangup Script: %s\n", 1122 arg->cx->cfg.script.hangup); 1123 return 0; 1124 } 1125 1126 int 1127 datalink_SetReconnect(struct cmdargs const *arg) 1128 { 1129 if (arg->argc == arg->argn+2) { 1130 arg->cx->cfg.reconnect.timeout = atoi(arg->argv[arg->argn]); 1131 arg->cx->cfg.reconnect.max = atoi(arg->argv[arg->argn+1]); 1132 return 0; 1133 } 1134 return -1; 1135 } 1136 1137 int 1138 datalink_SetRedial(struct cmdargs const *arg) 1139 { 1140 const char *sep, *osep; 1141 int timeout, inc, maxinc, tries; 1142 1143 if (arg->argc == arg->argn+1 || arg->argc == arg->argn+2) { 1144 if (strncasecmp(arg->argv[arg->argn], "random", 6) == 0 && 1145 (arg->argv[arg->argn][6] == '\0' || arg->argv[arg->argn][6] == '.')) { 1146 arg->cx->cfg.dial.timeout = -1; 1147 randinit(); 1148 } else { 1149 timeout = atoi(arg->argv[arg->argn]); 1150 1151 if (timeout >= 0) 1152 arg->cx->cfg.dial.timeout = timeout; 1153 else { 1154 log_Printf(LogWARN, "Invalid redial timeout\n"); 1155 return -1; 1156 } 1157 } 1158 1159 sep = strchr(arg->argv[arg->argn], '+'); 1160 if (sep) { 1161 inc = atoi(++sep); 1162 osep = sep; 1163 if (inc >= 0) 1164 arg->cx->cfg.dial.inc = inc; 1165 else { 1166 log_Printf(LogWARN, "Invalid timeout increment\n"); 1167 return -1; 1168 } 1169 sep = strchr(sep, '-'); 1170 if (sep) { 1171 maxinc = atoi(++sep); 1172 if (maxinc >= 0) 1173 arg->cx->cfg.dial.maxinc = maxinc; 1174 else { 1175 log_Printf(LogWARN, "Invalid maximum timeout increments\n"); 1176 return -1; 1177 } 1178 } else { 1179 /* Default timeout increment */ 1180 arg->cx->cfg.dial.maxinc = 10; 1181 sep = osep; 1182 } 1183 } else { 1184 /* Default timeout increment & max increment */ 1185 arg->cx->cfg.dial.inc = 0; 1186 arg->cx->cfg.dial.maxinc = 10; 1187 sep = arg->argv[arg->argn]; 1188 } 1189 1190 sep = strchr(sep, '.'); 1191 if (sep) { 1192 if (strcasecmp(++sep, "random") == 0) { 1193 arg->cx->cfg.dial.next_timeout = -1; 1194 randinit(); 1195 } else { 1196 timeout = atoi(sep); 1197 if (timeout >= 0) 1198 arg->cx->cfg.dial.next_timeout = timeout; 1199 else { 1200 log_Printf(LogWARN, "Invalid next redial timeout\n"); 1201 return -1; 1202 } 1203 } 1204 } else 1205 /* Default next timeout */ 1206 arg->cx->cfg.dial.next_timeout = DIAL_NEXT_TIMEOUT; 1207 1208 if (arg->argc == arg->argn+2) { 1209 tries = atoi(arg->argv[arg->argn+1]); 1210 1211 if (tries >= 0) { 1212 arg->cx->cfg.dial.max = tries; 1213 } else { 1214 log_Printf(LogWARN, "Invalid retry value\n"); 1215 return 1; 1216 } 1217 } 1218 return 0; 1219 } 1220 1221 return -1; 1222 } 1223 1224 static const char * const states[] = { 1225 "closed", 1226 "opening", 1227 "hangup", 1228 "dial", 1229 "carrier", 1230 "logout", 1231 "login", 1232 "ready", 1233 "lcp", 1234 "auth", 1235 "cbcp", 1236 "open" 1237 }; 1238 1239 const char * 1240 datalink_State(struct datalink *dl) 1241 { 1242 if (dl->state < 0 || dl->state >= sizeof states / sizeof states[0]) 1243 return "unknown"; 1244 return states[dl->state]; 1245 } 1246 1247 static void 1248 datalink_NewState(struct datalink *dl, int state) 1249 { 1250 if (state != dl->state) { 1251 if (state >= 0 && state < sizeof states / sizeof states[0]) { 1252 log_Printf(LogPHASE, "%s: %s -> %s\n", dl->name, datalink_State(dl), 1253 states[state]); 1254 dl->state = state; 1255 } else 1256 log_Printf(LogERROR, "%s: Can't enter state %d !\n", dl->name, state); 1257 } 1258 } 1259 1260 struct datalink * 1261 iov2datalink(struct bundle *bundle, struct iovec *iov, int *niov, int maxiov, 1262 int fd, int *auxfd, int *nauxfd) 1263 { 1264 struct datalink *dl, *cdl; 1265 struct fsm_retry copy; 1266 char *oname; 1267 1268 dl = (struct datalink *)iov[(*niov)++].iov_base; 1269 dl->name = iov[*niov].iov_base; 1270 1271 if (dl->name[DATALINK_MAXNAME-1]) { 1272 dl->name[DATALINK_MAXNAME-1] = '\0'; 1273 if (strlen(dl->name) == DATALINK_MAXNAME - 1) 1274 log_Printf(LogWARN, "Datalink name truncated to \"%s\"\n", dl->name); 1275 } 1276 1277 /* Make sure the name is unique ! */ 1278 oname = NULL; 1279 do { 1280 for (cdl = bundle->links; cdl; cdl = cdl->next) 1281 if (!strcasecmp(dl->name, cdl->name)) { 1282 if (oname) 1283 free(datalink_NextName(dl)); 1284 else 1285 oname = datalink_NextName(dl); 1286 break; /* Keep renaming 'till we have no conflicts */ 1287 } 1288 } while (cdl); 1289 1290 if (oname) { 1291 log_Printf(LogPHASE, "Rename link %s to %s\n", oname, dl->name); 1292 free(oname); 1293 } else { 1294 dl->name = strdup(dl->name); 1295 free(iov[*niov].iov_base); 1296 } 1297 (*niov)++; 1298 1299 dl->desc.type = DATALINK_DESCRIPTOR; 1300 dl->desc.UpdateSet = datalink_UpdateSet; 1301 dl->desc.IsSet = datalink_IsSet; 1302 dl->desc.Read = datalink_Read; 1303 dl->desc.Write = datalink_Write; 1304 1305 mp_linkInit(&dl->mp); 1306 *dl->phone.list = '\0'; 1307 dl->phone.next = NULL; 1308 dl->phone.alt = NULL; 1309 dl->phone.chosen = "N/A"; 1310 1311 dl->bundle = bundle; 1312 dl->next = NULL; 1313 memset(&dl->dial.timer, '\0', sizeof dl->dial.timer); 1314 dl->dial.tries = 0; 1315 dl->reconnect_tries = 0; 1316 dl->parent = &bundle->fsm; 1317 dl->fsmp.LayerStart = datalink_LayerStart; 1318 dl->fsmp.LayerUp = datalink_LayerUp; 1319 dl->fsmp.LayerDown = datalink_LayerDown; 1320 dl->fsmp.LayerFinish = datalink_LayerFinish; 1321 dl->fsmp.object = dl; 1322 1323 dl->physical = iov2physical(dl, iov, niov, maxiov, fd, auxfd, nauxfd); 1324 1325 if (!dl->physical) { 1326 free(dl->name); 1327 free(dl); 1328 dl = NULL; 1329 } else { 1330 copy = dl->pap.cfg.fsm; 1331 pap_Init(&dl->pap, dl->physical); 1332 dl->pap.cfg.fsm = copy; 1333 1334 copy = dl->chap.auth.cfg.fsm; 1335 chap_Init(&dl->chap, dl->physical); 1336 dl->chap.auth.cfg.fsm = copy; 1337 1338 cbcp_Init(&dl->cbcp, dl->physical); 1339 1340 memset(&dl->chat, '\0', sizeof dl->chat); /* Force buf{start,end} reset */ 1341 chat_Init(&dl->chat, dl->physical); 1342 1343 log_Printf(LogPHASE, "%s: Transferred in %s state\n", 1344 dl->name, datalink_State(dl)); 1345 } 1346 1347 return dl; 1348 } 1349 1350 int 1351 datalink2iov(struct datalink *dl, struct iovec *iov, int *niov, int maxiov, 1352 int *auxfd, int *nauxfd) 1353 { 1354 /* If `dl' is NULL, we're allocating before a Fromiov() */ 1355 int link_fd; 1356 1357 if (dl) { 1358 timer_Stop(&dl->dial.timer); 1359 /* The following is purely for the sake of paranoia */ 1360 cbcp_Down(&dl->cbcp); 1361 timer_Stop(&dl->pap.authtimer); 1362 timer_Stop(&dl->chap.auth.authtimer); 1363 } 1364 1365 if (*niov >= maxiov - 1) { 1366 log_Printf(LogERROR, "Toiov: No room for datalink !\n"); 1367 if (dl) { 1368 free(dl->name); 1369 free(dl); 1370 } 1371 return -1; 1372 } 1373 1374 iov[*niov].iov_base = (void *)dl; 1375 iov[(*niov)++].iov_len = sizeof *dl; 1376 iov[*niov].iov_base = dl ? realloc(dl->name, DATALINK_MAXNAME) : NULL; 1377 iov[(*niov)++].iov_len = DATALINK_MAXNAME; 1378 1379 link_fd = physical2iov(dl ? dl->physical : NULL, iov, niov, maxiov, auxfd, 1380 nauxfd); 1381 1382 if (link_fd == -1 && dl) { 1383 free(dl->name); 1384 free(dl); 1385 } 1386 1387 return link_fd; 1388 } 1389 1390 void 1391 datalink_Rename(struct datalink *dl, const char *name) 1392 { 1393 free(dl->name); 1394 dl->physical->link.name = dl->name = strdup(name); 1395 } 1396 1397 char * 1398 datalink_NextName(struct datalink *dl) 1399 { 1400 int f, n; 1401 char *name, *oname; 1402 1403 n = strlen(dl->name); 1404 name = (char *)malloc(n+3); 1405 for (f = n - 1; f >= 0; f--) 1406 if (!isdigit(dl->name[f])) 1407 break; 1408 n = sprintf(name, "%.*s-", dl->name[f] == '-' ? f : f + 1, dl->name); 1409 sprintf(name + n, "%d", atoi(dl->name + f + 1) + 1); 1410 oname = dl->name; 1411 dl->name = name; 1412 /* our physical link name isn't updated (it probably isn't created yet) */ 1413 return oname; 1414 } 1415 1416 int 1417 datalink_SetMode(struct datalink *dl, int mode) 1418 { 1419 if (!physical_SetMode(dl->physical, mode)) 1420 return 0; 1421 if (dl->physical->type & (PHYS_DIRECT|PHYS_DEDICATED)) 1422 dl->script.run = 0; 1423 if (dl->physical->type == PHYS_DIRECT) 1424 dl->reconnect_tries = 0; 1425 if (mode & (PHYS_DDIAL|PHYS_BACKGROUND|PHYS_FOREGROUND) && 1426 dl->state <= DATALINK_READY) 1427 datalink_Up(dl, 1, 1); 1428 return 1; 1429 } 1430 1431 int 1432 datalink_GetDialTimeout(struct datalink *dl) 1433 { 1434 int result = dl->cfg.dial.timeout + dl->dial.incs * dl->cfg.dial.inc; 1435 1436 if (dl->dial.incs < dl->cfg.dial.maxinc) 1437 dl->dial.incs++; 1438 1439 return result; 1440 } 1441