Home | History | Annotate | Download | only in src
      1 /*-
      2  * Copyright (c) 1998 Brian Somers <brian (at) 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 
     81 static void datalink_LoginDone(struct datalink *);
     82 static void datalink_NewState(struct datalink *, unsigned);
     83 static char *datalink_NextName(struct datalink *);
     84 
     85 static void
     86 datalink_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 
     95 static int
     96 datalink_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 
    114 static void
    115 datalink_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 
    188 const char *
    189 datalink_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 
    210 static void
    211 datalink_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 
    250 static int
    251 datalink_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 
    414 int
    415 datalink_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 
    420 static int
    421 datalink_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 
    447 static void
    448 datalink_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 
    477 static int
    478 datalink_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 
    526 void
    527 datalink_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 
    559 static void
    560 datalink_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 
    569 static void
    570 datalink_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 
    596 static void
    597 datalink_AuthReInit(struct datalink *dl)
    598 {
    599   auth_StopTimer(&dl->pap);
    600   auth_StopTimer(&dl->chap.auth);
    601   chap_ReInit(&dl->chap);
    602 }
    603 
    604 void
    605 datalink_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 
    611 void
    612 datalink_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 
    657 void
    658 datalink_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 
    665 void
    666 datalink_CBCPFailed(struct datalink *dl)
    667 {
    668   cbcp_Down(&dl->cbcp);
    669   datalink_CBCPComplete(dl);
    670 }
    671 
    672 void
    673 datalink_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 
    740 void
    741 datalink_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 
    748 static void
    749 datalink_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 
    777 static void
    778 datalink_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 
    791 struct datalink *
    792 datalink_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 
    871 struct datalink *
    872 datalink_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 
    935 struct datalink *
    936 datalink_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 
    962 void
    963 datalink_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 
   1002 void
   1003 datalink_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 
   1028 void
   1029 datalink_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 
   1051 void
   1052 datalink_StayDown(struct datalink *dl)
   1053 {
   1054   dl->dial.tries = -1;
   1055   dl->reconnect_tries = 0;
   1056   dl->stayonline = 0;
   1057 }
   1058 
   1059 void
   1060 datalink_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 
   1067 int
   1068 datalink_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 
   1157 int
   1158 datalink_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 
   1168 int
   1169 datalink_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 
   1255 static 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 
   1270 const char *
   1271 datalink_State(struct datalink *dl)
   1272 {
   1273   if (dl->state >= sizeof states / sizeof states[0])
   1274     return "unknown";
   1275   return states[dl->state];
   1276 }
   1277 
   1278 static void
   1279 datalink_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 
   1291 struct datalink *
   1292 iov2datalink(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 
   1385 int
   1386 datalink2iov(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 
   1425 void
   1426 datalink_Rename(struct datalink *dl, const char *name)
   1427 {
   1428   free(dl->name);
   1429   dl->physical->link.name = dl->name = strdup(name);
   1430 }
   1431 
   1432 static char *
   1433 datalink_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 
   1454 int
   1455 datalink_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 
   1469 int
   1470 datalink_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