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