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