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