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