2 * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
26 * $FreeBSD: src/usr.sbin/ppp/datalink.c,v 1.57.2.11 2002/09/01 02:12:26 brian Exp $
27 * $DragonFly: src/usr.sbin/ppp/datalink.c,v 1.2 2003/06/17 04:30:00 dillon Exp $
30 #include <sys/param.h>
31 #include <netinet/in.h>
32 #include <netinet/in_systm.h>
33 #include <netinet/ip.h>
34 #include <sys/socket.h>
51 #include "descriptor.h"
56 #include "throughput.h"
61 #include "slcompress.h"
82 static void datalink_LoginDone(struct datalink
*);
83 static void datalink_NewState(struct datalink
*, int);
86 datalink_OpenTimeout(void *v
)
88 struct datalink
*dl
= (struct datalink
*)v
;
90 timer_Stop(&dl
->dial
.timer
);
91 if (dl
->state
== DATALINK_OPENING
)
92 log_Printf(LogCHAT
, "%s: Redial timer expired.\n", dl
->name
);
96 datalink_StartDialTimer(struct datalink
*dl
, int Timeout
)
100 timer_Stop(&dl
->dial
.timer
);
102 result
= (random() % DIAL_TIMEOUT
) + 1;
103 dl
->dial
.timer
.load
= result
? result
* SECTICKS
: 1;
104 dl
->dial
.timer
.func
= datalink_OpenTimeout
;
105 dl
->dial
.timer
.name
= "dial";
106 dl
->dial
.timer
.arg
= dl
;
107 timer_Start(&dl
->dial
.timer
);
108 if (dl
->state
== DATALINK_OPENING
)
109 log_Printf(LogPHASE
, "%s: Enter pause (%d) for redialing.\n",
115 datalink_HangupDone(struct datalink
*dl
)
117 if (dl
->physical
->type
== PHYS_DEDICATED
&& !dl
->bundle
->CleaningUp
&&
118 dl
->physical
->fd
!= -1) {
119 /* Don't close our device if the link is dedicated */
120 datalink_LoginDone(dl
);
124 chat_Finish(&dl
->chat
);
125 physical_Close(dl
->physical
);
126 dl
->phone
.chosen
= "N/A";
128 if (dl
->cbcp
.required
) {
129 log_Printf(LogPHASE
, "Call peer back on %s\n", dl
->cbcp
.fsm
.phone
);
130 dl
->cfg
.callback
.opmask
= 0;
131 strncpy(dl
->cfg
.phone
.list
, dl
->cbcp
.fsm
.phone
,
132 sizeof dl
->cfg
.phone
.list
- 1);
133 dl
->cfg
.phone
.list
[sizeof dl
->cfg
.phone
.list
- 1] = '\0';
134 dl
->phone
.alt
= dl
->phone
.next
= NULL
;
135 dl
->reconnect_tries
= dl
->cfg
.reconnect
.max
;
136 dl
->dial
.tries
= dl
->cfg
.dial
.max
;
139 dl
->script
.packetmode
= 1;
140 if (!physical_SetMode(dl
->physical
, PHYS_BACKGROUND
))
141 log_Printf(LogERROR
, "Oops - can't change mode to BACKGROUND (gulp) !\n");
142 bundle_LinksRemoved(dl
->bundle
);
143 /* if dial.timeout is < 0 (random), we don't override fsm.delay */
144 if (dl
->cbcp
.fsm
.delay
< dl
->cfg
.dial
.timeout
)
145 dl
->cbcp
.fsm
.delay
= dl
->cfg
.dial
.timeout
;
146 datalink_StartDialTimer(dl
, dl
->cbcp
.fsm
.delay
);
147 cbcp_Down(&dl
->cbcp
);
148 datalink_NewState(dl
, DATALINK_OPENING
);
149 if (bundle_Phase(dl
->bundle
) == PHASE_DEAD
||
150 bundle_Phase(dl
->bundle
) == PHASE_TERMINATE
)
151 bundle_NewPhase(dl
->bundle
, PHASE_ESTABLISH
);
152 } else if (dl
->bundle
->CleaningUp
||
153 (dl
->physical
->type
== PHYS_DIRECT
) ||
154 ((!dl
->dial
.tries
|| (dl
->dial
.tries
< 0 && !dl
->reconnect_tries
)) &&
155 !(dl
->physical
->type
& (PHYS_DDIAL
|PHYS_DEDICATED
)))) {
156 datalink_NewState(dl
, DATALINK_CLOSED
);
159 dl
->reconnect_tries
= 0;
160 bundle_LinkClosed(dl
->bundle
, dl
);
161 if (!dl
->bundle
->CleaningUp
&&
162 !(dl
->physical
->type
& (PHYS_DIRECT
|PHYS_BACKGROUND
|PHYS_FOREGROUND
)))
163 datalink_StartDialTimer(dl
, datalink_GetDialTimeout(dl
));
165 datalink_NewState(dl
, DATALINK_OPENING
);
166 if (bundle_Phase(dl
->bundle
) == PHASE_DEAD
||
167 bundle_Phase(dl
->bundle
) == PHASE_TERMINATE
)
168 bundle_NewPhase(dl
->bundle
, PHASE_ESTABLISH
);
169 if (dl
->dial
.tries
< 0) {
170 datalink_StartDialTimer(dl
, dl
->cfg
.reconnect
.timeout
);
171 dl
->dial
.tries
= dl
->cfg
.dial
.max
;
173 dl
->reconnect_tries
--;
174 log_Printf(LogCHAT
, "%s: Reconnect try %d of %d\n",
175 dl
->name
, dl
->cfg
.reconnect
.max
- dl
->reconnect_tries
,
176 dl
->cfg
.reconnect
.max
);
177 bundle_Notify(dl
->bundle
, EX_RECONNECT
);
179 if (dl
->phone
.next
== NULL
)
180 datalink_StartDialTimer(dl
, datalink_GetDialTimeout(dl
));
182 datalink_StartDialTimer(dl
, dl
->cfg
.dial
.next_timeout
);
183 bundle_Notify(dl
->bundle
, EX_REDIAL
);
189 datalink_ChoosePhoneNumber(struct datalink
*dl
)
193 if (dl
->phone
.alt
== NULL
) {
194 if (dl
->phone
.next
== NULL
) {
195 strncpy(dl
->phone
.list
, dl
->cfg
.phone
.list
, sizeof dl
->phone
.list
- 1);
196 dl
->phone
.list
[sizeof dl
->phone
.list
- 1] = '\0';
197 if (*dl
->phone
.list
== '\0')
199 dl
->phone
.next
= dl
->phone
.list
;
201 dl
->phone
.alt
= strsep(&dl
->phone
.next
, ":");
203 phone
= strsep(&dl
->phone
.alt
, "|");
204 dl
->phone
.chosen
= *phone
? phone
: "[NONE]";
206 log_Printf(LogCHAT
, "Phone: %s\n", phone
);
211 datalink_LoginDone(struct datalink
*dl
)
213 chat_Finish(&dl
->chat
);
215 if (!dl
->script
.packetmode
) {
218 datalink_NewState(dl
, DATALINK_READY
);
219 } else if (!physical_Raw(dl
->physical
)) {
221 log_Printf(LogWARN
, "datalink_LoginDone: Not connected.\n");
222 if (dl
->script
.run
) {
223 datalink_NewState(dl
, DATALINK_LOGOUT
);
224 if (!chat_Setup(&dl
->chat
, dl
->cfg
.script
.logout
, NULL
))
225 log_Printf(LogWARN
, "Invalid logout script\n");
227 physical_StopDeviceTimer(dl
->physical
);
228 if (dl
->physical
->type
== PHYS_DEDICATED
)
229 /* force a redial timeout */
230 physical_Close(dl
->physical
);
231 datalink_HangupDone(dl
);
237 hdlc_Init(&dl
->physical
->hdlc
, &dl
->physical
->link
.lcp
);
238 async_Setup(&dl
->physical
->async
);
240 lcp_Setup(&dl
->physical
->link
.lcp
, dl
->state
== DATALINK_READY
?
241 0 : dl
->physical
->link
.lcp
.cfg
.openmode
);
242 ccp_Setup(&dl
->physical
->link
.ccp
);
244 datalink_NewState(dl
, DATALINK_LCP
);
245 fsm_Up(&dl
->physical
->link
.lcp
.fsm
);
246 fsm_Open(&dl
->physical
->link
.lcp
.fsm
);
251 datalink_UpdateSet(struct fdescriptor
*d
, fd_set
*r
, fd_set
*w
, fd_set
*e
,
254 struct datalink
*dl
= descriptor2datalink(d
);
259 case DATALINK_CLOSED
:
260 if ((dl
->physical
->type
& (PHYS_DIRECT
|PHYS_DEDICATED
|PHYS_BACKGROUND
|
261 PHYS_FOREGROUND
|PHYS_DDIAL
)) &&
262 !dl
->bundle
->CleaningUp
)
264 * Our first time in - DEDICATED & DDIAL never come down, and
265 * DIRECT, FOREGROUND & BACKGROUND get deleted when they enter
266 * DATALINK_CLOSED. Go to DATALINK_OPENING via datalink_Up()
269 datalink_Up(dl
, 1, 1);
274 case DATALINK_OPENING
:
275 if (dl
->dial
.timer
.state
!= TIMER_RUNNING
) {
276 if (--dl
->dial
.tries
< 0)
278 if (physical_Open(dl
->physical
, dl
->bundle
) >= 0) {
279 log_WritePrompts(dl
, "%s: Entering terminal mode on %s\r\n"
280 "Type `~?' for help\r\n", dl
->name
,
281 dl
->physical
->name
.full
);
282 if (dl
->script
.run
) {
283 datalink_NewState(dl
, DATALINK_DIAL
);
284 if (!chat_Setup(&dl
->chat
, dl
->cfg
.script
.dial
,
285 *dl
->cfg
.script
.dial
?
286 datalink_ChoosePhoneNumber(dl
) : ""))
287 log_Printf(LogWARN
, "Invalid dial script\n");
288 if (!(dl
->physical
->type
& (PHYS_DDIAL
|PHYS_DEDICATED
)) &&
290 log_Printf(LogCHAT
, "%s: Dial attempt %u of %d\n",
291 dl
->name
, dl
->cfg
.dial
.max
- dl
->dial
.tries
,
294 datalink_NewState(dl
, DATALINK_CARRIER
);
295 return datalink_UpdateSet(d
, r
, w
, e
, n
);
297 if (!(dl
->physical
->type
& (PHYS_DDIAL
|PHYS_DEDICATED
)) &&
299 log_Printf(LogCHAT
, "Failed to open device (attempt %u of %d)\n",
300 dl
->cfg
.dial
.max
- dl
->dial
.tries
, dl
->cfg
.dial
.max
);
302 log_Printf(LogCHAT
, "Failed to open device\n");
304 if (dl
->bundle
->CleaningUp
||
305 (!(dl
->physical
->type
& (PHYS_DDIAL
|PHYS_DEDICATED
)) &&
306 dl
->cfg
.dial
.max
&& dl
->dial
.tries
== 0)) {
307 datalink_NewState(dl
, DATALINK_CLOSED
);
308 dl
->reconnect_tries
= 0;
310 log_WritePrompts(dl
, "Failed to open %s\n",
311 dl
->physical
->name
.full
);
312 bundle_LinkClosed(dl
->bundle
, dl
);
314 if (!dl
->bundle
->CleaningUp
) {
317 timeout
= datalink_StartDialTimer(dl
, datalink_GetDialTimeout(dl
));
318 bundle_Notify(dl
->bundle
, EX_REDIAL
);
319 log_WritePrompts(dl
, "Failed to open %s, pause %d seconds\n",
320 dl
->physical
->name
.full
, timeout
);
326 case DATALINK_CARRIER
:
327 /* Wait for carrier on the device */
328 switch (physical_AwaitCarrier(dl
->physical
)) {
329 case CARRIER_PENDING
:
330 log_Printf(LogDEBUG
, "Waiting for carrier\n");
331 return 0; /* A device timer is running to wake us up again */
334 if (dl
->script
.run
) {
335 datalink_NewState(dl
, DATALINK_LOGIN
);
336 if (!chat_Setup(&dl
->chat
, dl
->cfg
.script
.login
, NULL
))
337 log_Printf(LogWARN
, "Invalid login script\n");
339 datalink_LoginDone(dl
);
340 return datalink_UpdateSet(d
, r
, w
, e
, n
);
343 physical_Offline(dl
->physical
); /* Is this required ? */
344 if (dl
->script
.run
) {
345 datalink_NewState(dl
, DATALINK_HANGUP
);
346 if (!chat_Setup(&dl
->chat
, dl
->cfg
.script
.hangup
, NULL
))
347 log_Printf(LogWARN
, "Invalid hangup script\n");
348 return datalink_UpdateSet(d
, r
, w
, e
, n
);
350 datalink_HangupDone(dl
);
351 return 0; /* Maybe bundle_CleanDatalinks() has something to do */
355 case DATALINK_HANGUP
:
357 case DATALINK_LOGOUT
:
359 result
= descriptor_UpdateSet(&dl
->chat
.desc
, r
, w
, e
, n
);
360 switch (dl
->chat
.state
) {
362 /* script succeeded */
364 case DATALINK_HANGUP
:
365 datalink_HangupDone(dl
);
368 datalink_NewState(dl
, DATALINK_CARRIER
);
369 return datalink_UpdateSet(d
, r
, w
, e
, n
);
370 case DATALINK_LOGOUT
:
371 datalink_NewState(dl
, DATALINK_HANGUP
);
372 physical_Offline(dl
->physical
);
373 if (!chat_Setup(&dl
->chat
, dl
->cfg
.script
.hangup
, NULL
))
374 log_Printf(LogWARN
, "Invalid hangup script\n");
375 return datalink_UpdateSet(d
, r
, w
, e
, n
);
377 dl
->phone
.alt
= NULL
;
378 datalink_LoginDone(dl
);
379 return datalink_UpdateSet(d
, r
, w
, e
, n
);
383 /* Going down - script failed */
384 log_Printf(LogWARN
, "Chat script failed\n");
386 case DATALINK_HANGUP
:
387 datalink_HangupDone(dl
);
390 case DATALINK_LOGOUT
:
392 datalink_NewState(dl
, DATALINK_HANGUP
);
393 physical_Offline(dl
->physical
);
394 if (!chat_Setup(&dl
->chat
, dl
->cfg
.script
.hangup
, NULL
))
395 log_Printf(LogWARN
, "Invalid hangup script\n");
396 return datalink_UpdateSet(d
, r
, w
, e
, n
);
407 result
= descriptor_UpdateSet(&dl
->chap
.desc
, r
, w
, e
, n
) +
408 descriptor_UpdateSet(&dl
->physical
->desc
, r
, w
, e
, n
);
415 datalink_RemoveFromSet(struct datalink
*dl
, fd_set
*r
, fd_set
*w
, fd_set
*e
)
417 return physical_RemoveFromSet(dl
->physical
, r
, w
, e
);
421 datalink_IsSet(struct fdescriptor
*d
, const fd_set
*fdset
)
423 struct datalink
*dl
= descriptor2datalink(d
);
426 case DATALINK_CLOSED
:
427 case DATALINK_OPENING
:
430 case DATALINK_HANGUP
:
432 case DATALINK_LOGOUT
:
434 return descriptor_IsSet(&dl
->chat
.desc
, fdset
);
441 return descriptor_IsSet(&dl
->chap
.desc
, fdset
) ? 1 :
442 descriptor_IsSet(&dl
->physical
->desc
, fdset
);
448 datalink_Read(struct fdescriptor
*d
, struct bundle
*bundle
, const fd_set
*fdset
)
450 struct datalink
*dl
= descriptor2datalink(d
);
453 case DATALINK_CLOSED
:
454 case DATALINK_OPENING
:
457 case DATALINK_HANGUP
:
459 case DATALINK_LOGOUT
:
461 descriptor_Read(&dl
->chat
.desc
, bundle
, fdset
);
469 if (descriptor_IsSet(&dl
->chap
.desc
, fdset
))
470 descriptor_Read(&dl
->chap
.desc
, bundle
, fdset
);
471 if (descriptor_IsSet(&dl
->physical
->desc
, fdset
))
472 descriptor_Read(&dl
->physical
->desc
, bundle
, fdset
);
478 datalink_Write(struct fdescriptor
*d
, struct bundle
*bundle
,
481 struct datalink
*dl
= descriptor2datalink(d
);
485 case DATALINK_CLOSED
:
486 case DATALINK_OPENING
:
489 case DATALINK_HANGUP
:
491 case DATALINK_LOGOUT
:
493 if ((result
= descriptor_Write(&dl
->chat
.desc
, bundle
, fdset
)) == -1) {
494 datalink_ComeDown(dl
, CLOSE_NORMAL
);
504 if (descriptor_IsSet(&dl
->chap
.desc
, fdset
))
505 switch (descriptor_Write(&dl
->chap
.desc
, bundle
, fdset
)) {
507 datalink_ComeDown(dl
, CLOSE_NORMAL
);
512 if (descriptor_IsSet(&dl
->physical
->desc
, fdset
))
513 switch (descriptor_Write(&dl
->physical
->desc
, bundle
, fdset
)) {
515 datalink_ComeDown(dl
, CLOSE_NORMAL
);
527 datalink_ComeDown(struct datalink
*dl
, int how
)
531 if (how
== CLOSE_LCP
)
532 datalink_DontHangup(dl
);
533 else if (how
== CLOSE_STAYDOWN
)
534 datalink_StayDown(dl
);
536 stayonline
= dl
->stayonline
;
539 if (dl
->state
>= DATALINK_READY
&& stayonline
) {
540 physical_StopDeviceTimer(dl
->physical
);
541 datalink_NewState(dl
, DATALINK_READY
);
542 } else if (dl
->state
!= DATALINK_CLOSED
&& dl
->state
!= DATALINK_HANGUP
) {
543 physical_Offline(dl
->physical
);
544 if (dl
->script
.run
&& dl
->state
!= DATALINK_OPENING
) {
545 if (dl
->state
== DATALINK_LOGOUT
) {
546 datalink_NewState(dl
, DATALINK_HANGUP
);
547 if (!chat_Setup(&dl
->chat
, dl
->cfg
.script
.hangup
, NULL
))
548 log_Printf(LogWARN
, "Invalid hangup script\n");
550 datalink_NewState(dl
, DATALINK_LOGOUT
);
551 if (!chat_Setup(&dl
->chat
, dl
->cfg
.script
.logout
, NULL
))
552 log_Printf(LogWARN
, "Invalid logout script\n");
555 datalink_HangupDone(dl
);
560 datalink_LayerStart(void *v
, struct fsm
*fp
)
562 /* The given FSM is about to start up ! */
563 struct datalink
*dl
= (struct datalink
*)v
;
565 if (fp
->proto
== PROTO_LCP
)
566 (*dl
->parent
->LayerStart
)(dl
->parent
->object
, fp
);
570 datalink_LayerUp(void *v
, struct fsm
*fp
)
572 /* The given fsm is now up */
573 struct datalink
*dl
= (struct datalink
*)v
;
574 struct lcp
*lcp
= &dl
->physical
->link
.lcp
;
576 if (fp
->proto
== PROTO_LCP
) {
577 datalink_GotAuthname(dl
, "");
578 lcp
->auth_ineed
= lcp
->want_auth
;
579 lcp
->auth_iwait
= lcp
->his_auth
;
580 if (lcp
->his_auth
|| lcp
->want_auth
) {
581 if (bundle_Phase(dl
->bundle
) != PHASE_NETWORK
)
582 bundle_NewPhase(dl
->bundle
, PHASE_AUTHENTICATE
);
583 log_Printf(LogPHASE
, "%s: his = %s, mine = %s\n", dl
->name
,
584 Auth2Nam(lcp
->his_auth
, lcp
->his_authtype
),
585 Auth2Nam(lcp
->want_auth
, lcp
->want_authtype
));
586 if (lcp
->his_auth
== PROTO_PAP
)
587 auth_StartReq(&dl
->pap
);
588 if (lcp
->want_auth
== PROTO_CHAP
)
589 auth_StartReq(&dl
->chap
.auth
);
592 } else if (fp
->proto
== PROTO_CCP
)
593 (*dl
->parent
->LayerUp
)(dl
->parent
->object
, &dl
->physical
->link
.ccp
.fsm
);
597 datalink_AuthReInit(struct datalink
*dl
)
599 auth_StopTimer(&dl
->pap
);
600 auth_StopTimer(&dl
->chap
.auth
);
601 chap_ReInit(&dl
->chap
);
605 datalink_GotAuthname(struct datalink
*dl
, const char *name
)
607 strncpy(dl
->peer
.authname
, name
, sizeof dl
->peer
.authname
- 1);
608 dl
->peer
.authname
[sizeof dl
->peer
.authname
- 1] = '\0';
612 datalink_NCPUp(struct datalink
*dl
)
614 int ccpok
= ccp_SetOpenMode(&dl
->physical
->link
.ccp
);
616 if (dl
->physical
->link
.lcp
.want_mrru
&& dl
->physical
->link
.lcp
.his_mrru
) {
617 /* we've authenticated in multilink mode ! */
618 switch (mp_Up(&dl
->bundle
->ncp
.mp
, dl
)) {
620 /* We've handed the link off to another ppp (well, we will soon) ! */
623 /* First link in the bundle */
624 auth_Select(dl
->bundle
, dl
->peer
.authname
);
625 bundle_CalculateBandwidth(dl
->bundle
);
628 /* We're in multilink mode ! */
629 dl
->physical
->link
.ccp
.fsm
.open_mode
= OPEN_PASSIVE
; /* override */
630 bundle_CalculateBandwidth(dl
->bundle
);
633 datalink_AuthNotOk(dl
);
636 } else if (bundle_Phase(dl
->bundle
) == PHASE_NETWORK
) {
637 log_Printf(LogPHASE
, "%s: Already in NETWORK phase\n", dl
->name
);
638 datalink_NewState(dl
, DATALINK_OPEN
);
639 bundle_CalculateBandwidth(dl
->bundle
);
640 (*dl
->parent
->LayerUp
)(dl
->parent
->object
, &dl
->physical
->link
.lcp
.fsm
);
643 dl
->bundle
->ncp
.mp
.peer
= dl
->peer
;
644 ncp_SetLink(&dl
->bundle
->ncp
, &dl
->physical
->link
);
645 auth_Select(dl
->bundle
, dl
->peer
.authname
);
649 fsm_Up(&dl
->physical
->link
.ccp
.fsm
);
650 fsm_Open(&dl
->physical
->link
.ccp
.fsm
);
652 datalink_NewState(dl
, DATALINK_OPEN
);
653 bundle_NewPhase(dl
->bundle
, PHASE_NETWORK
);
654 (*dl
->parent
->LayerUp
)(dl
->parent
->object
, &dl
->physical
->link
.lcp
.fsm
);
658 datalink_CBCPComplete(struct datalink
*dl
)
660 datalink_NewState(dl
, DATALINK_LCP
);
661 datalink_AuthReInit(dl
);
662 fsm_Close(&dl
->physical
->link
.lcp
.fsm
);
666 datalink_CBCPFailed(struct datalink
*dl
)
668 cbcp_Down(&dl
->cbcp
);
669 datalink_CBCPComplete(dl
);
673 datalink_AuthOk(struct datalink
*dl
)
675 if ((dl
->physical
->link
.lcp
.his_callback
.opmask
&
676 CALLBACK_BIT(CALLBACK_CBCP
) ||
677 dl
->physical
->link
.lcp
.want_callback
.opmask
&
678 CALLBACK_BIT(CALLBACK_CBCP
)) &&
679 !(dl
->physical
->link
.lcp
.want_callback
.opmask
&
680 CALLBACK_BIT(CALLBACK_AUTH
))) {
681 /* We must have agreed CBCP if AUTH isn't there any more */
682 datalink_NewState(dl
, DATALINK_CBCP
);
684 } else if (dl
->physical
->link
.lcp
.want_callback
.opmask
) {
686 log_Printf(LogPHASE
, "%s: Shutdown and await peer callback\n", dl
->name
);
687 datalink_NewState(dl
, DATALINK_LCP
);
688 datalink_AuthReInit(dl
);
689 fsm_Close(&dl
->physical
->link
.lcp
.fsm
);
691 switch (dl
->physical
->link
.lcp
.his_callback
.opmask
) {
696 case CALLBACK_BIT(CALLBACK_AUTH
):
697 auth_SetPhoneList(dl
->peer
.authname
, dl
->cbcp
.fsm
.phone
,
698 sizeof dl
->cbcp
.fsm
.phone
);
699 if (*dl
->cbcp
.fsm
.phone
== '\0' || !strcmp(dl
->cbcp
.fsm
.phone
, "*")) {
700 log_Printf(LogPHASE
, "%s: %s cannot be called back\n", dl
->name
,
702 *dl
->cbcp
.fsm
.phone
= '\0';
704 char *ptr
= strchr(dl
->cbcp
.fsm
.phone
, ',');
706 *ptr
= '\0'; /* Call back on the first number */
707 log_Printf(LogPHASE
, "%s: Calling peer back on %s\n", dl
->name
,
709 dl
->cbcp
.required
= 1;
711 dl
->cbcp
.fsm
.delay
= 0;
712 datalink_NewState(dl
, DATALINK_LCP
);
713 datalink_AuthReInit(dl
);
714 fsm_Close(&dl
->physical
->link
.lcp
.fsm
);
717 case CALLBACK_BIT(CALLBACK_E164
):
718 strncpy(dl
->cbcp
.fsm
.phone
, dl
->physical
->link
.lcp
.his_callback
.msg
,
719 sizeof dl
->cbcp
.fsm
.phone
- 1);
720 dl
->cbcp
.fsm
.phone
[sizeof dl
->cbcp
.fsm
.phone
- 1] = '\0';
721 log_Printf(LogPHASE
, "%s: Calling peer back on %s\n", dl
->name
,
723 dl
->cbcp
.required
= 1;
724 dl
->cbcp
.fsm
.delay
= 0;
725 datalink_NewState(dl
, DATALINK_LCP
);
726 datalink_AuthReInit(dl
);
727 fsm_Close(&dl
->physical
->link
.lcp
.fsm
);
731 log_Printf(LogPHASE
, "%s: Oops - Should have NAK'd peer callback !\n",
733 datalink_NewState(dl
, DATALINK_LCP
);
734 datalink_AuthReInit(dl
);
735 fsm_Close(&dl
->physical
->link
.lcp
.fsm
);
741 datalink_AuthNotOk(struct datalink
*dl
)
743 datalink_NewState(dl
, DATALINK_LCP
);
744 datalink_AuthReInit(dl
);
745 fsm_Close(&dl
->physical
->link
.lcp
.fsm
);
749 datalink_LayerDown(void *v
, struct fsm
*fp
)
751 /* The given FSM has been told to come down */
752 struct datalink
*dl
= (struct datalink
*)v
;
754 if (fp
->proto
== PROTO_LCP
) {
757 peerid_Init(&dl
->peer
);
758 fsm2initial(&dl
->physical
->link
.ccp
.fsm
);
759 datalink_NewState(dl
, DATALINK_LCP
); /* before parent TLD */
760 (*dl
->parent
->LayerDown
)(dl
->parent
->object
, fp
);
761 /* FALLTHROUGH (just in case) */
764 if (!dl
->cbcp
.required
)
765 cbcp_Down(&dl
->cbcp
);
766 /* FALLTHROUGH (just in case) */
769 timer_Stop(&dl
->pap
.authtimer
);
770 timer_Stop(&dl
->chap
.auth
.authtimer
);
772 datalink_NewState(dl
, DATALINK_LCP
);
773 datalink_AuthReInit(dl
);
778 datalink_LayerFinish(void *v
, struct fsm
*fp
)
780 /* The given fsm is now down */
781 struct datalink
*dl
= (struct datalink
*)v
;
783 if (fp
->proto
== PROTO_LCP
) {
785 (*dl
->parent
->LayerFinish
)(dl
->parent
->object
, fp
);
786 datalink_ComeDown(dl
, CLOSE_NORMAL
);
787 } else if (fp
->state
== ST_CLOSED
&& fp
->open_mode
== OPEN_PASSIVE
)
788 fsm_Open(fp
); /* CCP goes to ST_STOPPED */
792 datalink_Create(const char *name
, struct bundle
*bundle
, int type
)
796 dl
= (struct datalink
*)malloc(sizeof(struct datalink
));
800 dl
->desc
.type
= DATALINK_DESCRIPTOR
;
801 dl
->desc
.UpdateSet
= datalink_UpdateSet
;
802 dl
->desc
.IsSet
= datalink_IsSet
;
803 dl
->desc
.Read
= datalink_Read
;
804 dl
->desc
.Write
= datalink_Write
;
806 dl
->state
= DATALINK_CLOSED
;
808 *dl
->cfg
.script
.dial
= '\0';
809 *dl
->cfg
.script
.login
= '\0';
810 *dl
->cfg
.script
.logout
= '\0';
811 *dl
->cfg
.script
.hangup
= '\0';
812 *dl
->cfg
.phone
.list
= '\0';
813 *dl
->phone
.list
= '\0';
814 dl
->phone
.next
= NULL
;
815 dl
->phone
.alt
= NULL
;
816 dl
->phone
.chosen
= "N/A";
819 dl
->script
.packetmode
= 1;
820 mp_linkInit(&dl
->mp
);
825 memset(&dl
->dial
.timer
, '\0', sizeof dl
->dial
.timer
);
828 dl
->cfg
.dial
.max
= 1;
829 dl
->cfg
.dial
.next_timeout
= DIAL_NEXT_TIMEOUT
;
830 dl
->cfg
.dial
.timeout
= DIAL_TIMEOUT
;
831 dl
->cfg
.dial
.inc
= 0;
832 dl
->cfg
.dial
.maxinc
= 10;
834 dl
->reconnect_tries
= 0;
835 dl
->cfg
.reconnect
.max
= 0;
836 dl
->cfg
.reconnect
.timeout
= RECONNECT_TIMEOUT
;
838 dl
->cfg
.callback
.opmask
= 0;
839 dl
->cfg
.cbcp
.delay
= 0;
840 *dl
->cfg
.cbcp
.phone
= '\0';
841 dl
->cfg
.cbcp
.fsmretry
= DEF_FSMRETRY
;
843 dl
->name
= strdup(name
);
844 peerid_Init(&dl
->peer
);
845 dl
->parent
= &bundle
->fsm
;
846 dl
->fsmp
.LayerStart
= datalink_LayerStart
;
847 dl
->fsmp
.LayerUp
= datalink_LayerUp
;
848 dl
->fsmp
.LayerDown
= datalink_LayerDown
;
849 dl
->fsmp
.LayerFinish
= datalink_LayerFinish
;
850 dl
->fsmp
.object
= dl
;
852 if ((dl
->physical
= physical_Create(dl
, type
)) == NULL
) {
858 pap_Init(&dl
->pap
, dl
->physical
);
859 chap_Init(&dl
->chap
, dl
->physical
);
860 cbcp_Init(&dl
->cbcp
, dl
->physical
);
862 memset(&dl
->chat
, '\0', sizeof dl
->chat
); /* Force buf{start,end} reset */
863 chat_Init(&dl
->chat
, dl
->physical
);
865 log_Printf(LogPHASE
, "%s: Created in %s state\n",
866 dl
->name
, datalink_State(dl
));
872 datalink_Clone(struct datalink
*odl
, const char *name
)
876 dl
= (struct datalink
*)malloc(sizeof(struct datalink
));
880 dl
->desc
.type
= DATALINK_DESCRIPTOR
;
881 dl
->desc
.UpdateSet
= datalink_UpdateSet
;
882 dl
->desc
.IsSet
= datalink_IsSet
;
883 dl
->desc
.Read
= datalink_Read
;
884 dl
->desc
.Write
= datalink_Write
;
886 dl
->state
= DATALINK_CLOSED
;
888 memcpy(&dl
->cfg
, &odl
->cfg
, sizeof dl
->cfg
);
889 mp_linkInit(&dl
->mp
);
890 *dl
->phone
.list
= '\0';
891 dl
->phone
.next
= NULL
;
892 dl
->phone
.alt
= NULL
;
893 dl
->phone
.chosen
= "N/A";
894 dl
->bundle
= odl
->bundle
;
896 memset(&dl
->dial
.timer
, '\0', sizeof dl
->dial
.timer
);
898 dl
->reconnect_tries
= 0;
899 dl
->name
= strdup(name
);
900 peerid_Init(&dl
->peer
);
901 dl
->parent
= odl
->parent
;
902 memcpy(&dl
->fsmp
, &odl
->fsmp
, sizeof dl
->fsmp
);
903 dl
->fsmp
.object
= dl
;
905 if ((dl
->physical
= physical_Create(dl
, PHYS_INTERACTIVE
)) == NULL
) {
910 pap_Init(&dl
->pap
, dl
->physical
);
911 dl
->pap
.cfg
= odl
->pap
.cfg
;
913 chap_Init(&dl
->chap
, dl
->physical
);
914 dl
->chap
.auth
.cfg
= odl
->chap
.auth
.cfg
;
916 memcpy(&dl
->physical
->cfg
, &odl
->physical
->cfg
, sizeof dl
->physical
->cfg
);
917 memcpy(&dl
->physical
->link
.lcp
.cfg
, &odl
->physical
->link
.lcp
.cfg
,
918 sizeof dl
->physical
->link
.lcp
.cfg
);
919 memcpy(&dl
->physical
->link
.ccp
.cfg
, &odl
->physical
->link
.ccp
.cfg
,
920 sizeof dl
->physical
->link
.ccp
.cfg
);
921 memcpy(&dl
->physical
->async
.cfg
, &odl
->physical
->async
.cfg
,
922 sizeof dl
->physical
->async
.cfg
);
924 cbcp_Init(&dl
->cbcp
, dl
->physical
);
926 memset(&dl
->chat
, '\0', sizeof dl
->chat
); /* Force buf{start,end} reset */
927 chat_Init(&dl
->chat
, dl
->physical
);
929 log_Printf(LogPHASE
, "%s: Cloned in %s state\n",
930 dl
->name
, datalink_State(dl
));
936 datalink_Destroy(struct datalink
*dl
)
938 struct datalink
*result
;
940 if (dl
->state
!= DATALINK_CLOSED
) {
941 log_Printf(LogERROR
, "Oops, destroying a datalink in state %s\n",
944 case DATALINK_HANGUP
:
947 chat_Finish(&dl
->chat
); /* Gotta blat the timers ! */
952 chat_Destroy(&dl
->chat
);
953 timer_Stop(&dl
->dial
.timer
);
955 physical_Destroy(dl
->physical
);
963 datalink_Up(struct datalink
*dl
, int runscripts
, int packetmode
)
965 if (dl
->physical
->type
& (PHYS_DIRECT
|PHYS_DEDICATED
))
970 case DATALINK_CLOSED
:
971 if (bundle_Phase(dl
->bundle
) == PHASE_DEAD
||
972 bundle_Phase(dl
->bundle
) == PHASE_TERMINATE
)
973 bundle_NewPhase(dl
->bundle
, PHASE_ESTABLISH
);
974 datalink_NewState(dl
, DATALINK_OPENING
);
975 dl
->reconnect_tries
=
976 dl
->physical
->type
== PHYS_DIRECT
? 0 : dl
->cfg
.reconnect
.max
;
977 dl
->dial
.tries
= dl
->cfg
.dial
.max
;
978 dl
->script
.run
= runscripts
;
979 dl
->script
.packetmode
= packetmode
;
982 case DATALINK_OPENING
:
983 if (!dl
->script
.run
&& runscripts
)
990 if (!dl
->script
.packetmode
&& packetmode
) {
991 dl
->script
.packetmode
= 1;
992 if (dl
->state
== DATALINK_READY
) {
994 datalink_NewState(dl
, DATALINK_CARRIER
);
1002 datalink_Close(struct datalink
*dl
, int how
)
1005 switch (dl
->state
) {
1007 peerid_Init(&dl
->peer
);
1008 fsm2initial(&dl
->physical
->link
.ccp
.fsm
);
1014 datalink_AuthReInit(dl
);
1015 if (how
== CLOSE_LCP
)
1016 datalink_DontHangup(dl
);
1017 else if (how
== CLOSE_STAYDOWN
)
1018 datalink_StayDown(dl
);
1019 fsm_Close(&dl
->physical
->link
.lcp
.fsm
);
1023 datalink_ComeDown(dl
, how
);
1028 datalink_Down(struct datalink
*dl
, int how
)
1030 /* Carrier is lost */
1031 switch (dl
->state
) {
1033 peerid_Init(&dl
->peer
);
1034 fsm2initial(&dl
->physical
->link
.ccp
.fsm
);
1040 fsm2initial(&dl
->physical
->link
.lcp
.fsm
);
1041 if (dl
->state
== DATALINK_OPENING
)
1042 return; /* we're doing a callback... */
1046 datalink_ComeDown(dl
, how
);
1051 datalink_StayDown(struct datalink
*dl
)
1053 dl
->dial
.tries
= -1;
1054 dl
->reconnect_tries
= 0;
1059 datalink_DontHangup(struct datalink
*dl
)
1061 dl
->dial
.tries
= -1;
1062 dl
->reconnect_tries
= 0;
1063 dl
->stayonline
= dl
->state
>= DATALINK_LCP
? 1 : 0;
1067 datalink_Show(struct cmdargs
const *arg
)
1069 prompt_Printf(arg
->prompt
, "Name: %s\n", arg
->cx
->name
);
1070 prompt_Printf(arg
->prompt
, " State: %s\n",
1071 datalink_State(arg
->cx
));
1072 prompt_Printf(arg
->prompt
, " Peer name: ");
1073 if (*arg
->cx
->peer
.authname
)
1074 prompt_Printf(arg
->prompt
, "%s\n", arg
->cx
->peer
.authname
);
1075 else if (arg
->cx
->state
== DATALINK_OPEN
)
1076 prompt_Printf(arg
->prompt
, "None requested\n");
1078 prompt_Printf(arg
->prompt
, "N/A\n");
1079 prompt_Printf(arg
->prompt
, " Discriminator: %s\n",
1080 mp_Enddisc(arg
->cx
->peer
.enddisc
.class,
1081 arg
->cx
->peer
.enddisc
.address
,
1082 arg
->cx
->peer
.enddisc
.len
));
1084 prompt_Printf(arg
->prompt
, "\nDefaults:\n");
1085 prompt_Printf(arg
->prompt
, " Phone List: %s\n",
1086 arg
->cx
->cfg
.phone
.list
);
1087 if (arg
->cx
->cfg
.dial
.max
)
1088 prompt_Printf(arg
->prompt
, " Dial tries: %d, delay ",
1089 arg
->cx
->cfg
.dial
.max
);
1091 prompt_Printf(arg
->prompt
, " Dial tries: infinite, delay ");
1092 if (arg
->cx
->cfg
.dial
.next_timeout
>= 0)
1093 prompt_Printf(arg
->prompt
, "%ds/", arg
->cx
->cfg
.dial
.next_timeout
);
1095 prompt_Printf(arg
->prompt
, "random/");
1096 if (arg
->cx
->cfg
.dial
.timeout
>= 0)
1097 prompt_Printf(arg
->prompt
, "%ds\n", arg
->cx
->cfg
.dial
.timeout
);
1099 prompt_Printf(arg
->prompt
, "random\n");
1100 prompt_Printf(arg
->prompt
, " Reconnect tries: %d, delay ",
1101 arg
->cx
->cfg
.reconnect
.max
);
1102 if (arg
->cx
->cfg
.reconnect
.timeout
> 0)
1103 prompt_Printf(arg
->prompt
, "%ds\n", arg
->cx
->cfg
.reconnect
.timeout
);
1105 prompt_Printf(arg
->prompt
, "random\n");
1106 prompt_Printf(arg
->prompt
, " Callback %s ", arg
->cx
->physical
->type
==
1107 PHYS_DIRECT
? "accepted: " : "requested:");
1108 if (!arg
->cx
->cfg
.callback
.opmask
)
1109 prompt_Printf(arg
->prompt
, "none\n");
1113 if (arg
->cx
->cfg
.callback
.opmask
& CALLBACK_BIT(CALLBACK_NONE
)) {
1114 prompt_Printf(arg
->prompt
, "none");
1117 if (arg
->cx
->cfg
.callback
.opmask
& CALLBACK_BIT(CALLBACK_AUTH
)) {
1118 prompt_Printf(arg
->prompt
, "%sauth", comma
? ", " : "");
1121 if (arg
->cx
->cfg
.callback
.opmask
& CALLBACK_BIT(CALLBACK_E164
)) {
1122 prompt_Printf(arg
->prompt
, "%sE.164", comma
? ", " : "");
1123 if (arg
->cx
->physical
->type
!= PHYS_DIRECT
)
1124 prompt_Printf(arg
->prompt
, " (%s)", arg
->cx
->cfg
.callback
.msg
);
1127 if (arg
->cx
->cfg
.callback
.opmask
& CALLBACK_BIT(CALLBACK_CBCP
)) {
1128 prompt_Printf(arg
->prompt
, "%scbcp\n", comma
? ", " : "");
1129 prompt_Printf(arg
->prompt
, " CBCP: delay: %ds\n",
1130 arg
->cx
->cfg
.cbcp
.delay
);
1131 prompt_Printf(arg
->prompt
, " phone: ");
1132 if (!strcmp(arg
->cx
->cfg
.cbcp
.phone
, "*")) {
1133 if (arg
->cx
->physical
->type
& PHYS_DIRECT
)
1134 prompt_Printf(arg
->prompt
, "Caller decides\n");
1136 prompt_Printf(arg
->prompt
, "Dialback server decides\n");
1138 prompt_Printf(arg
->prompt
, "%s\n", arg
->cx
->cfg
.cbcp
.phone
);
1139 prompt_Printf(arg
->prompt
, " timeout: %lds\n",
1140 arg
->cx
->cfg
.cbcp
.fsmretry
);
1142 prompt_Printf(arg
->prompt
, "\n");
1145 prompt_Printf(arg
->prompt
, " Dial Script: %s\n",
1146 arg
->cx
->cfg
.script
.dial
);
1147 prompt_Printf(arg
->prompt
, " Login Script: %s\n",
1148 arg
->cx
->cfg
.script
.login
);
1149 prompt_Printf(arg
->prompt
, " Logout Script: %s\n",
1150 arg
->cx
->cfg
.script
.logout
);
1151 prompt_Printf(arg
->prompt
, " Hangup Script: %s\n",
1152 arg
->cx
->cfg
.script
.hangup
);
1157 datalink_SetReconnect(struct cmdargs
const *arg
)
1159 if (arg
->argc
== arg
->argn
+2) {
1160 arg
->cx
->cfg
.reconnect
.timeout
= atoi(arg
->argv
[arg
->argn
]);
1161 arg
->cx
->cfg
.reconnect
.max
= atoi(arg
->argv
[arg
->argn
+1]);
1168 datalink_SetRedial(struct cmdargs
const *arg
)
1170 const char *sep
, *osep
;
1171 int timeout
, inc
, maxinc
, tries
;
1173 if (arg
->argc
== arg
->argn
+1 || arg
->argc
== arg
->argn
+2) {
1174 if (strncasecmp(arg
->argv
[arg
->argn
], "random", 6) == 0 &&
1175 (arg
->argv
[arg
->argn
][6] == '\0' || arg
->argv
[arg
->argn
][6] == '.')) {
1176 arg
->cx
->cfg
.dial
.timeout
= -1;
1179 timeout
= atoi(arg
->argv
[arg
->argn
]);
1182 arg
->cx
->cfg
.dial
.timeout
= timeout
;
1184 log_Printf(LogWARN
, "Invalid redial timeout\n");
1189 sep
= strchr(arg
->argv
[arg
->argn
], '+');
1194 arg
->cx
->cfg
.dial
.inc
= inc
;
1196 log_Printf(LogWARN
, "Invalid timeout increment\n");
1199 sep
= strchr(sep
, '-');
1201 maxinc
= atoi(++sep
);
1203 arg
->cx
->cfg
.dial
.maxinc
= maxinc
;
1205 log_Printf(LogWARN
, "Invalid maximum timeout increments\n");
1209 /* Default timeout increment */
1210 arg
->cx
->cfg
.dial
.maxinc
= 10;
1214 /* Default timeout increment & max increment */
1215 arg
->cx
->cfg
.dial
.inc
= 0;
1216 arg
->cx
->cfg
.dial
.maxinc
= 10;
1217 sep
= arg
->argv
[arg
->argn
];
1220 sep
= strchr(sep
, '.');
1222 if (strcasecmp(++sep
, "random") == 0) {
1223 arg
->cx
->cfg
.dial
.next_timeout
= -1;
1226 timeout
= atoi(sep
);
1228 arg
->cx
->cfg
.dial
.next_timeout
= timeout
;
1230 log_Printf(LogWARN
, "Invalid next redial timeout\n");
1235 /* Default next timeout */
1236 arg
->cx
->cfg
.dial
.next_timeout
= DIAL_NEXT_TIMEOUT
;
1238 if (arg
->argc
== arg
->argn
+2) {
1239 tries
= atoi(arg
->argv
[arg
->argn
+1]);
1242 arg
->cx
->cfg
.dial
.max
= tries
;
1244 log_Printf(LogWARN
, "Invalid retry value\n");
1254 static const char * const states
[] = {
1270 datalink_State(struct datalink
*dl
)
1272 if (dl
->state
< 0 || dl
->state
>= sizeof states
/ sizeof states
[0])
1274 return states
[dl
->state
];
1278 datalink_NewState(struct datalink
*dl
, int state
)
1280 if (state
!= dl
->state
) {
1281 if (state
>= 0 && state
< sizeof states
/ sizeof states
[0]) {
1282 log_Printf(LogPHASE
, "%s: %s -> %s\n", dl
->name
, datalink_State(dl
),
1286 log_Printf(LogERROR
, "%s: Can't enter state %d !\n", dl
->name
, state
);
1291 iov2datalink(struct bundle
*bundle
, struct iovec
*iov
, int *niov
, int maxiov
,
1292 int fd
, int *auxfd
, int *nauxfd
)
1294 struct datalink
*dl
, *cdl
;
1295 struct fsm_retry copy
;
1298 dl
= (struct datalink
*)iov
[(*niov
)++].iov_base
;
1299 dl
->name
= iov
[*niov
].iov_base
;
1301 if (dl
->name
[DATALINK_MAXNAME
-1]) {
1302 dl
->name
[DATALINK_MAXNAME
-1] = '\0';
1303 if (strlen(dl
->name
) == DATALINK_MAXNAME
- 1)
1304 log_Printf(LogWARN
, "Datalink name truncated to \"%s\"\n", dl
->name
);
1307 /* Make sure the name is unique ! */
1310 for (cdl
= bundle
->links
; cdl
; cdl
= cdl
->next
)
1311 if (!strcasecmp(dl
->name
, cdl
->name
)) {
1313 free(datalink_NextName(dl
));
1315 oname
= datalink_NextName(dl
);
1316 break; /* Keep renaming 'till we have no conflicts */
1321 log_Printf(LogPHASE
, "Rename link %s to %s\n", oname
, dl
->name
);
1324 dl
->name
= strdup(dl
->name
);
1325 free(iov
[*niov
].iov_base
);
1329 dl
->desc
.type
= DATALINK_DESCRIPTOR
;
1330 dl
->desc
.UpdateSet
= datalink_UpdateSet
;
1331 dl
->desc
.IsSet
= datalink_IsSet
;
1332 dl
->desc
.Read
= datalink_Read
;
1333 dl
->desc
.Write
= datalink_Write
;
1335 mp_linkInit(&dl
->mp
);
1336 *dl
->phone
.list
= '\0';
1337 dl
->phone
.next
= NULL
;
1338 dl
->phone
.alt
= NULL
;
1339 dl
->phone
.chosen
= "N/A";
1341 dl
->bundle
= bundle
;
1343 memset(&dl
->dial
.timer
, '\0', sizeof dl
->dial
.timer
);
1345 dl
->reconnect_tries
= 0;
1346 dl
->parent
= &bundle
->fsm
;
1347 dl
->fsmp
.LayerStart
= datalink_LayerStart
;
1348 dl
->fsmp
.LayerUp
= datalink_LayerUp
;
1349 dl
->fsmp
.LayerDown
= datalink_LayerDown
;
1350 dl
->fsmp
.LayerFinish
= datalink_LayerFinish
;
1351 dl
->fsmp
.object
= dl
;
1353 dl
->physical
= iov2physical(dl
, iov
, niov
, maxiov
, fd
, auxfd
, nauxfd
);
1355 if (!dl
->physical
) {
1360 copy
= dl
->pap
.cfg
.fsm
;
1361 pap_Init(&dl
->pap
, dl
->physical
);
1362 dl
->pap
.cfg
.fsm
= copy
;
1364 copy
= dl
->chap
.auth
.cfg
.fsm
;
1365 chap_Init(&dl
->chap
, dl
->physical
);
1366 dl
->chap
.auth
.cfg
.fsm
= copy
;
1368 cbcp_Init(&dl
->cbcp
, dl
->physical
);
1370 memset(&dl
->chat
, '\0', sizeof dl
->chat
); /* Force buf{start,end} reset */
1371 chat_Init(&dl
->chat
, dl
->physical
);
1373 log_Printf(LogPHASE
, "%s: Transferred in %s state\n",
1374 dl
->name
, datalink_State(dl
));
1381 datalink2iov(struct datalink
*dl
, struct iovec
*iov
, int *niov
, int maxiov
,
1382 int *auxfd
, int *nauxfd
)
1384 /* If `dl' is NULL, we're allocating before a Fromiov() */
1388 timer_Stop(&dl
->dial
.timer
);
1389 /* The following is purely for the sake of paranoia */
1390 cbcp_Down(&dl
->cbcp
);
1391 timer_Stop(&dl
->pap
.authtimer
);
1392 timer_Stop(&dl
->chap
.auth
.authtimer
);
1395 if (*niov
>= maxiov
- 1) {
1396 log_Printf(LogERROR
, "Toiov: No room for datalink !\n");
1404 iov
[*niov
].iov_base
= (void *)dl
;
1405 iov
[(*niov
)++].iov_len
= sizeof *dl
;
1406 iov
[*niov
].iov_base
= dl
? realloc(dl
->name
, DATALINK_MAXNAME
) : NULL
;
1407 iov
[(*niov
)++].iov_len
= DATALINK_MAXNAME
;
1409 link_fd
= physical2iov(dl
? dl
->physical
: NULL
, iov
, niov
, maxiov
, auxfd
,
1412 if (link_fd
== -1 && dl
) {
1421 datalink_Rename(struct datalink
*dl
, const char *name
)
1424 dl
->physical
->link
.name
= dl
->name
= strdup(name
);
1428 datalink_NextName(struct datalink
*dl
)
1433 n
= strlen(dl
->name
);
1434 name
= (char *)malloc(n
+3);
1435 for (f
= n
- 1; f
>= 0; f
--)
1436 if (!isdigit(dl
->name
[f
]))
1438 n
= sprintf(name
, "%.*s-", dl
->name
[f
] == '-' ? f
: f
+ 1, dl
->name
);
1439 sprintf(name
+ n
, "%d", atoi(dl
->name
+ f
+ 1) + 1);
1442 /* our physical link name isn't updated (it probably isn't created yet) */
1447 datalink_SetMode(struct datalink
*dl
, int mode
)
1449 if (!physical_SetMode(dl
->physical
, mode
))
1451 if (dl
->physical
->type
& (PHYS_DIRECT
|PHYS_DEDICATED
))
1453 if (dl
->physical
->type
== PHYS_DIRECT
)
1454 dl
->reconnect_tries
= 0;
1455 if (mode
& (PHYS_DDIAL
|PHYS_BACKGROUND
|PHYS_FOREGROUND
) &&
1456 dl
->state
<= DATALINK_READY
)
1457 datalink_Up(dl
, 1, 1);
1462 datalink_GetDialTimeout(struct datalink
*dl
)
1464 int result
= dl
->cfg
.dial
.timeout
+ dl
->dial
.incs
* dl
->cfg
.dial
.inc
;
1466 if (dl
->dial
.incs
< dl
->cfg
.dial
.maxinc
)