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