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