xref: /openbsd/usr.sbin/npppd/pptp/pptp_call.c (revision a6445c1d)
1 /*	$OpenBSD: pptp_call.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $	*/
2 
3 /*-
4  * Copyright (c) 2009 Internet Initiative Japan Inc.
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 /* $Id: pptp_call.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $ */
29 /**@file PPTP Call */
30 /* currently it supports PAC mode only */
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/socket.h>
34 #include <sys/time.h>
35 #include <netinet/in.h>
36 #include <net/if_dl.h>
37 #include <stdio.h>
38 #include <stdarg.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <syslog.h>
43 #include <event.h>
44 
45 #ifdef USE_LIBSOCKUTIL
46 #include <seil/sockfromto.h>
47 #endif
48 
49 #include "bytebuf.h"
50 #include "slist.h"
51 #include "hash.h"
52 #include "debugutil.h"
53 #include "time_utils.h"
54 
55 #include "pptp.h"
56 #include "pptp_local.h"
57 #include "pptp_subr.h"
58 
59 #include "npppd.h"
60 
61 #ifdef PPTP_CALL_DEBUG
62 #define PPTP_CALL_DBG(x)	pptp_call_log x
63 #define PPTP_CALL_ASSERT(x)	ASSERT(x)
64 #else
65 #define PPTP_CALL_DBG(x)
66 #define PPTP_CALL_ASSERT(x)
67 #endif
68 
69 static void  pptp_call_log (pptp_call *, int, const char *, ...) __printflike(3,4);
70 
71 
72 static void  pptp_call_notify_down (pptp_call *);
73 static int   pptp_call_recv_SLI (pptp_call *, u_char *, int);
74 static int   pptp_call_recv_CCR (pptp_call *, u_char *, int);
75 static int   pptp_call_recv_OCRQ (pptp_call *, u_char *, int);
76 static void  pptp_call_send_CDN (pptp_call *, int, int, int, const char *);
77 static int   pptp_call_send_OCRP (pptp_call *, int, int, int);
78 static int   pptp_call_gre_output (pptp_call *, int, int, u_char *, int);
79 static int   pptp_call_bind_ppp (pptp_call *);
80 static void  pptp_call_log (pptp_call *, int, const char *, ...);
81 static void  pptp_call_OCRQ_string (struct pptp_ocrq *, char *, int);
82 static void  pptp_call_OCRP_string (struct pptp_ocrp *, char *, int);
83 static void   pptp_call_ppp_input (pptp_call *, unsigned char *, int, int);
84 static char * pptp_call_state_string(int);
85 
86 static int   pptp_call_ppp_output (npppd_ppp *, unsigned char *, int, int);
87 static void  pptp_call_closed_by_ppp (npppd_ppp *);
88 
89 /* not used
90 static int   pptp_call_send_SLI (pptp_call *);
91  */
92 
93 #define SEQ_LT(a,b)	((int)((a) - (b)) <  0)
94 #define SEQ_LE(a,b)	((int)((a) - (b)) <= 0)
95 #define SEQ_GT(a,b)	((int)((a) - (b)) >  0)
96 #define SEQ_GE(a,b)	((int)((a) - (b)) >= 0)
97 #define SEQ_SUB(a,b)	((int32_t)((a) - (b)))
98 
99 /* round-up division */
100 #define RUPDIV(n,d)	(((n) + ((d) - ((n) % (d)))) / (d))
101 
102 /*
103  * instance related functions
104  */
105 pptp_call *
106 pptp_call_create(void)
107 {
108 	pptp_call *_this;
109 
110 	if ((_this = malloc(sizeof(pptp_call))) == NULL)
111 		return NULL;
112 
113 	return _this;
114 }
115 
116 int
117 pptp_call_init(pptp_call *_this, pptp_ctrl *ctrl)
118 {
119 	memset(_this, 0, sizeof(pptp_call));
120 	_this->ctrl = ctrl;
121 
122 	_this->maxwinsz = PPTP_CALL_DEFAULT_MAXWINSZ;
123 	_this->winsz = RUPDIV(_this->maxwinsz, 2);
124 	_this->last_io = get_monosec();
125 	_this->snd_nxt = 1;
126 
127 	return 0;
128 }
129 
130 int
131 pptp_call_start(pptp_call *_this)
132 {
133 	if (pptp_call_bind_ppp(_this) != 0)
134 		return 1;
135 
136 	return 0;
137 }
138 
139 int
140 pptp_call_stop(pptp_call *_this)
141 {
142 	if (_this->state != PPTP_CALL_STATE_CLEANUP_WAIT)
143 		pptp_call_disconnect(_this, 0, 0, NULL);
144 
145 	pptp_call_log(_this, LOG_NOTICE, "logtype=Terminated");
146 	pptpd_release_call(_this->ctrl->pptpd, _this);
147 
148 	return 0;
149 }
150 
151 void
152 pptp_call_destroy(pptp_call *_this)
153 {
154 	PPTP_CALL_ASSERT(_this != NULL);
155 	free(_this);
156 }
157 
158 void
159 pptp_call_disconnect(pptp_call *_this, int result, int error, const char *
160     statistics)
161 {
162 	if (_this->state == PPTP_CALL_STATE_CLEANUP_WAIT) {
163 		pptp_call_notify_down(_this);
164 		return;
165 	}
166 	if (result > 0)
167 		pptp_call_send_CDN(_this, result, error, 0, statistics);
168 	_this->state = PPTP_CALL_STATE_CLEANUP_WAIT;
169 	pptp_call_notify_down(_this);
170 }
171 
172 /*
173  * PPTP control packet I/O
174  */
175 
176 void
177 pptp_call_input(pptp_call *_this, int mes_type, u_char *pkt, int lpkt)
178 {
179 
180 	PPTP_CALL_ASSERT(_this != NULL);
181 	PPTP_CALL_ASSERT(pkt != NULL);
182 	PPTP_CALL_ASSERT(lpkt >= 4);
183 
184 	_this->last_io = get_monosec();
185 	switch (mes_type) {
186 	case PPTP_CTRL_MES_CODE_OCRQ:
187 		if (_this->state != PPTP_CALL_STATE_IDLE) {
188 			pptp_call_send_OCRP(_this,
189 			    PPTP_OCRP_RESULT_GENERIC_ERROR,
190 			    PPTP_ERROR_BAD_CALL, 0);
191 			goto bad_state;
192 		}
193 		if (pptp_call_recv_OCRQ(_this, pkt, lpkt) != 0) {
194 			pptp_call_send_OCRP(_this,
195 			    PPTP_OCRP_RESULT_GENERIC_ERROR,
196 			    PPTP_ERROR_BAD_CALL, 0);
197 			return;
198 		}
199 		if (pptpd_assign_call(_this->ctrl->pptpd, _this) != 0) {
200 			pptp_call_send_OCRP(_this, PPTP_OCRP_RESULT_BUSY,
201 			    PPTP_ERROR_NONE, 0);
202 			return;
203 		}
204 		if (pptp_call_send_OCRP(_this, PPTP_OCRP_RESULT_CONNECTED,
205 		    PPTP_ERROR_NONE, 0) != 0) {
206 			pptp_call_disconnect(_this,
207 			    PPTP_CDN_RESULT_GENRIC_ERROR,
208 			    PPTP_ERROR_PAC_ERROR, NULL);
209 			return;
210 		}
211 		if (pptp_call_start(_this) != 0) {
212 			pptp_call_disconnect(_this,
213 			    PPTP_CDN_RESULT_GENRIC_ERROR,
214 			    PPTP_ERROR_PAC_ERROR, NULL);
215 			return;
216 		}
217 		_this->state = PPTP_CALL_STATE_ESTABLISHED;
218 		break;
219 	case PPTP_CTRL_MES_CODE_SLI:
220 		if (pptp_call_recv_SLI(_this, pkt, lpkt) != 0) {
221 			return;
222 		}
223 		return;
224 	case PPTP_CTRL_MES_CODE_CCR:
225 		pptp_call_recv_CCR(_this, pkt, lpkt);
226 		if (_this->state == PPTP_CALL_STATE_ESTABLISHED) {
227 			pptp_call_disconnect(_this, PPTP_CDN_RESULT_REQUEST,
228 			    PPTP_ERROR_NONE, NULL);
229 		} else {
230 			pptp_call_disconnect(_this, 0, 0, NULL);
231 			if (_this->state != PPTP_CALL_STATE_CLEANUP_WAIT)
232 				goto bad_state;
233 		}
234 		return;
235 	default:
236 	    pptp_call_log(_this, LOG_WARNING,
237 		"Unhandled control message type=%s(%d)",
238 		    pptp_ctrl_mes_type_string(mes_type), mes_type);
239 	}
240 	return;
241 bad_state:
242 	pptp_call_log(_this, LOG_WARNING,
243 	    "Received control message %s(%d) in bad state=%s",
244 		pptp_ctrl_mes_type_string(mes_type), mes_type,
245 		pptp_call_state_string(_this->state));
246 }
247 
248 /* receive Set-Link-Info */
249 /* XXX: this implementation is only supporting "Sync-Frame",
250  * ACCM (Asynchronous Control Character Map) will be discarded */
251 static int
252 pptp_call_recv_SLI(pptp_call *_this, u_char *pkt, int lpkt)
253 {
254 	struct pptp_sli *sli;
255 
256 	if (lpkt < sizeof(struct pptp_sli)) {
257 		pptp_call_log(_this, LOG_ERR, "Received bad SLI: packet too "
258 		    "short: %d < %d", lpkt, (int)sizeof(struct pptp_sli));
259 		return 1;
260 	}
261 	sli = (struct pptp_sli *)pkt;
262 	sli->send_accm = ntohl(sli->send_accm);
263 	sli->recv_accm = ntohl(sli->recv_accm);
264 	if (sli->send_accm != 0xffffffffL ||
265 	    sli->recv_accm != 0xffffffffL) {
266 		pptp_call_log(_this, LOG_WARNING,
267 		    "RecvSLI Received bad ACCM %08x:%08x: asynchronous framing "
268 		    "is not supported.\n", sli->send_accm, sli->recv_accm);
269 		return 1;
270 	}
271 	pptp_call_log(_this, LOG_INFO, "RecvSLI accm=%08x:%08x",
272 	    sli->send_accm, sli->recv_accm);
273 
274 	return 0;
275 }
276 
277 #if 0
278 /* Some route implementation which has "PPTP pass-through" function
279  * will discard 1723/tcp packet between PAC and PNS, when it recognize
280  * SLI from PAC. (for example, FLASHWAVE by Fujitsu).
281  *
282  * To avoid avobe situation, npppd send well-known SLI only.
283  */
284 static int
285 pptp_call_send_SLI(pptp_call *_this)
286 {
287 	int lpkt;
288 	struct pptp_sli *sli;
289 
290 	sli = bytebuffer_pointer(_this->ctrl->send_buf);
291 	lpkt = bytebuffer_remaining(_this->ctrl->send_buf);
292 	if (lpkt < sizeof(struct pptp_sli)) {
293 		pptp_call_log(_this, LOG_ERR,
294 		    "SendOCRP failed: No buffer space available");
295 		return -1;
296 	}
297 	memset(sli, 0, sizeof(struct pptp_sli));
298 
299 	pptp_init_header(&sli->header, sizeof(struct pptp_sli),
300 	    PPTP_CTRL_MES_CODE_SLI);
301 
302 	sli->peers_call_id = _this->id;
303 	sli->send_accm = 0xffffffff;
304 	sli->recv_accm = 0xffffffff;
305 
306 	_this->last_io = get_monosec();
307 	pptp_call_log(_this, LOG_INFO, "SendSLI accm=%08x:%08x",
308 	    sli->send_accm, sli->recv_accm);
309 	sli->peers_call_id = htons(sli->peers_call_id);
310 	sli->send_accm = htonl(sli->send_accm);
311 	sli->recv_accm = htonl(sli->recv_accm);
312 	pptp_ctrl_output(_this->ctrl, NULL,  sizeof(struct pptp_sli));
313 
314 	return 0;
315 }
316 #endif
317 
318 /* Receive Call-Clear-Request */
319 static int
320 pptp_call_recv_CCR(pptp_call *_this, u_char *pkt, int lpkt)
321 {
322 	struct pptp_ccr *ccr;
323 
324 	/* check size */
325 	PPTP_CALL_ASSERT(lpkt >= sizeof(struct pptp_ccr));
326 	if (lpkt < sizeof(struct pptp_ccr)) {
327 		/* never happen, should KASSERT() here? */
328 		return 1;
329 	}
330 	ccr = (struct pptp_ccr *)pkt;
331 
332 	/* convert byte-order */
333 	ccr->call_id = ntohs(ccr->call_id);
334 	pptp_call_log(_this, LOG_INFO, "RecvCCR call_id=%u", ccr->call_id);
335 
336 	return 0;
337 }
338 
339 /* Send Call-Disconnect-Notify */
340 static void
341 pptp_call_send_CDN(pptp_call *_this, int result, int error, int cause,
342     const char *statistics)
343 {
344 	int lpkt;
345 	struct pptp_cdn *cdn;
346 
347 	cdn = bytebuffer_pointer(_this->ctrl->send_buf);
348 	lpkt = bytebuffer_remaining(_this->ctrl->send_buf);
349 	if (lpkt < sizeof(struct pptp_cdn)) {
350 		pptp_call_log(_this, LOG_ERR,
351 		    "SendCCR failed: No buffer space available");
352 		return;
353 	}
354 	memset(cdn, 0, sizeof(struct pptp_cdn));
355 
356 	pptp_init_header(&cdn->header, sizeof(struct pptp_cdn),
357 	    PPTP_CTRL_MES_CODE_CDN);
358 
359 	cdn->call_id = _this->id;
360 	cdn->result_code = result;
361 	cdn->error_code = error;
362 	cdn->cause_code = cause;
363 	if (statistics != NULL)
364 		strlcpy(cdn->statistics, statistics, sizeof(cdn->statistics));
365 
366 	pptp_call_log(_this, LOG_INFO, "SendCDN "
367 	    "call_id=%u result=%s(%d) error=%s(%d) cause=%d statistics=%s",
368 	    cdn->call_id,
369 	    pptp_CDN_result_string(cdn->result_code), cdn->result_code,
370 	    pptp_general_error_string(cdn->error_code), cdn->error_code,
371 	    cdn->cause_code,
372 		(statistics == NULL)? "(none)" : (char *)cdn->statistics);
373 
374 	cdn->call_id = htons(cdn->call_id);
375 	cdn->cause_code = htons(cdn->cause_code);
376 
377 	_this->last_io = get_monosec();
378 	pptp_ctrl_output(_this->ctrl, NULL, sizeof(struct pptp_cdn));
379 }
380 
381 /* Send Outgoing-Call-Reply */
382 static int
383 pptp_call_send_OCRP(pptp_call *_this, int result, int error, int cause)
384 {
385 	int lpkt;
386 	struct pptp_ocrp *ocrp;
387 	char logbuf[512];
388 
389 	ocrp = bytebuffer_pointer(_this->ctrl->send_buf);
390 	lpkt = bytebuffer_remaining(_this->ctrl->send_buf);
391 	if (lpkt < sizeof(struct pptp_ocrp)) {
392 		pptp_call_log(_this, LOG_ERR,
393 		    "SendOCRP failed: No buffer space available");
394 		return -1;
395 	}
396 	memset(ocrp, 0, sizeof(struct pptp_ocrp));
397 
398 	pptp_init_header(&ocrp->header, sizeof(struct pptp_ocrp),
399 	    PPTP_CTRL_MES_CODE_OCRP);
400 
401 	ocrp->call_id = _this->id;
402 	ocrp->peers_call_id = _this->peers_call_id;
403 	ocrp->result_code = result;
404 	ocrp->error_code = error;
405 	ocrp->cause_code = cause;
406 	ocrp->connect_speed = PPTP_CALL_CONNECT_SPEED;
407 	ocrp->recv_winsz =  _this->maxwinsz;
408 	ocrp->packet_proccessing_delay = PPTP_CALL_INITIAL_PPD;
409 	ocrp->physical_channel_id = _this->id;
410 
411 	pptp_call_OCRP_string(ocrp, logbuf, sizeof(logbuf));
412 	pptp_call_log(_this, LOG_INFO, "SendOCRP %s", logbuf);
413 
414 	ocrp->call_id = htons(ocrp->call_id);
415 	ocrp->peers_call_id = htons(ocrp->peers_call_id);
416 	ocrp->cause_code = htons(ocrp->cause_code);
417 	ocrp->connect_speed = htons(ocrp->connect_speed);
418 	ocrp->recv_winsz = htons(ocrp->recv_winsz);
419 	ocrp->packet_proccessing_delay = htons(ocrp->packet_proccessing_delay);
420 	ocrp->physical_channel_id = htonl(ocrp->physical_channel_id);
421 
422 	_this->last_io = get_monosec();
423 	pptp_ctrl_output(_this->ctrl, NULL,  sizeof(struct pptp_ocrp));
424 
425 	return 0;
426 }
427 
428 /* Receive Outgoing-Call-Request */
429 static int
430 pptp_call_recv_OCRQ(pptp_call *_this, u_char *pkt, int lpkt)
431 {
432 	char logbuf[512];
433 	struct pptp_ocrq *ocrq;
434 
435 	/* check size */
436 	if (lpkt < sizeof(struct pptp_ocrq)) {
437 		pptp_call_log(_this, LOG_ERR, "Received bad OCRQ: packet too "
438 		    "short: %d < %d", lpkt, (int)sizeof(struct pptp_ocrq));
439 		return 1;
440 	}
441 	ocrq = (struct pptp_ocrq *)pkt;
442 
443 	/* convert byte-order */
444 	ocrq->call_id = ntohs(ocrq->call_id);
445 	ocrq->call_serial_number = ntohs(ocrq->call_serial_number);
446 	ocrq->recv_winsz = ntohs(ocrq->recv_winsz);
447 	ocrq->packet_proccessing_delay =
448 	    ntohs(ocrq->packet_proccessing_delay);
449 	ocrq->phone_number_length = ntohs(ocrq->phone_number_length);
450 	ocrq->reservied1 = ntohs(ocrq->reservied1);
451 	ocrq->maximum_bps = ntohl(ocrq->maximum_bps);
452 	ocrq->minimum_bps = ntohl(ocrq->minimum_bps);
453 	ocrq->bearer_type = ntohl(ocrq->bearer_type);
454 	ocrq->framing_type = ntohl(ocrq->framing_type);
455 
456 	_this->peers_call_id = ocrq->call_id;
457 	_this->peers_maxwinsz = ocrq->recv_winsz;
458 
459 	pptp_call_OCRQ_string(ocrq, logbuf, sizeof(logbuf));
460 	pptp_call_log(_this, LOG_INFO, "RecvOCRQ %s", logbuf);
461 
462 	return 0;
463 }
464 
465 /*
466  * GRE I/O
467  */
468 
469 /* Reciver packet via GRE */
470 void
471 pptp_call_gre_input(pptp_call *_this, uint32_t seq, uint32_t ack,
472     int input_flags, u_char *pkt, int pktlen)
473 {
474 	int log_prio;
475 	const char *reason;
476 	int delayed = 0;
477 
478 	PPTP_CALL_ASSERT(_this != NULL);
479 
480 	log_prio = LOG_INFO;
481 
482 #ifdef	PPTP_CALL_DEBUG
483 	if (debuglevel >= 2) {
484 		pptp_call_log(_this, LOG_DEBUG,
485 		    "Received data packet seq=%u(%u-%u) ack=%u(%u-%u)",
486 		    seq, _this->rcv_nxt,
487 		    _this->rcv_nxt + _this->peers_maxwinsz - 1,
488 		    ack, _this->snd_una, _this->snd_nxt);
489 	}
490 #endif
491 	if (_this->state != PPTP_CALL_STATE_ESTABLISHED) {
492 		pptp_call_log(_this, LOG_INFO,
493 		    "Received data packet in illegal state=%s",
494 		    pptp_call_state_string(_this->state));
495 		return;
496 	}
497 	PPTP_CALL_ASSERT(_this->state == PPTP_CALL_STATE_ESTABLISHED);
498 
499 	if (input_flags & PPTP_GRE_PKT_ACK_PRESENT) {
500 		if (ack + 1 == _this->snd_una) {
501 			/* nothing to do */
502 		} else if (SEQ_LT(ack, _this->snd_una)) {
503 			delayed = 1;
504 		} else if (SEQ_GT(ack, _this->snd_nxt)) {
505 			reason = "ack for unknown sequence.";
506 			goto bad_pkt;
507 		} else {
508 			ack++;
509 			_this->snd_una = ack;
510 		}
511 	}
512 
513 	if ((input_flags & PPTP_GRE_PKT_SEQ_PRESENT) == 0)
514 		return;	/* ack only packet */
515 
516 	/* check sequence# */
517 	if (SEQ_LT(seq, _this->rcv_nxt)) {
518 		/* delayed delivery? */
519 		if (SEQ_LT(seq, _this->rcv_nxt - PPTP_CALL_DELAY_LIMIT)) {
520 			reason = "out of sequence";
521 			goto bad_pkt;
522 		}
523 		delayed = 1;
524 	} else if (SEQ_GE(seq, _this->rcv_nxt + _this->maxwinsz)){
525 		/* MUST Process them */
526 		/* XXX FIXME: if over 4096 packets lost, it can not
527 		 * fix MPPE state */
528 		pptp_call_log(_this, LOG_INFO,
529 		    "Received packet caused window overflow.  seq=%u(%u-%u), "
530 		    "may lost %d packets.", seq, _this->rcv_nxt,
531 		    _this->rcv_nxt + _this->maxwinsz - 1,
532 		    SEQ_SUB(seq, _this->rcv_nxt));
533 	}
534 
535 	if (!delayed) {
536 		seq++;
537 		/* XXX : TODO: should it counts lost packets  ppp->ierrors
538 		 * and update ppp->ierrors counter? */
539 		_this->rcv_nxt = seq;
540 
541 		if (SEQ_SUB(seq, _this->rcv_acked) > RUPDIV(_this->winsz, 2)) {
542 			/*
543 			 * Multi-packet acknowledgement.
544 			 * send ack when it reachs to half of window size
545 			 */
546 			PPTP_CALL_DBG((_this, LOG_DEBUG,
547 			    "rcv window size=%u %u %u\n",
548 			    SEQ_SUB(seq, _this->rcv_acked), seq,
549 			    _this->rcv_acked));
550 			pptp_call_gre_output(_this, 0, 1, NULL, 0);
551 		}
552 	}
553 
554 	pptp_call_ppp_input(_this, pkt, pktlen, delayed);
555 
556 	return;
557 bad_pkt:
558 	pptp_call_log(_this, log_prio,
559 	    "Received bad data packet: %s: seq=%u(%u-%u) ack=%u(%u-%u)",
560 	    reason, seq, _this->rcv_nxt, _this->rcv_nxt + _this->maxwinsz - 1,
561 	    ack, _this->snd_una, _this->snd_nxt);
562 }
563 
564 /* output to GRE */
565 /* flags: fseq: contain SEQ field, fack: contain ACK field */
566 static int
567 pptp_call_gre_output(pptp_call *_this, int fseq, int fack, u_char *pkt,
568     int lpkt)
569 {
570 	int sz;
571 	struct pptp_gre_header *grehdr;
572 	u_char buf[65535], *opkt;
573 	struct sockaddr_storage peer, sock;
574 #ifndef USE_LIBSOCKUTIL
575 	socklen_t peerlen;
576 #endif
577 
578 	memset(buf, 0, sizeof(buf));
579 
580 	opkt = buf;
581 	grehdr = (struct pptp_gre_header *)opkt;
582 	opkt += sizeof(struct pptp_gre_header);
583 
584 	/* GRE header */
585 	grehdr->K = 1;
586 	grehdr->ver = PPTP_GRE_VERSION;
587 	grehdr->protocol_type = htons(PPTP_GRE_PROTOCOL_TYPE);
588 	grehdr->payload_length = htons(lpkt);
589 	grehdr->call_id = htons(_this->peers_call_id);
590 
591 #ifdef	PPTP_CALL_DEBUG
592 	if (debuglevel >= 2 && (fseq || fack)) {
593 		pptp_call_log(_this, LOG_DEBUG,
594 		    "Sending data packet seq=%u ack=%u",
595 		    _this->snd_nxt, _this->rcv_nxt - 1);
596 	}
597 #endif
598 	PPTP_CALL_ASSERT(ALIGNED_POINTER(opkt, uint32_t));
599 	if (fseq) {
600 		grehdr->S = 1;
601 		*(uint32_t *)opkt = htonl(_this->snd_nxt++);
602 		opkt += 4;
603 	}
604 	if (fack) {
605 		grehdr->A = 1;
606 		_this->rcv_acked = _this->rcv_nxt;
607 		*(uint32_t *)opkt = htonl(_this->rcv_nxt - 1);
608 		opkt += 4;
609 	}
610 	if (lpkt > 0) {
611 		memcpy(opkt, pkt, lpkt);
612 		opkt += lpkt;
613 	}
614 	memcpy(&peer, &_this->ctrl->peer, sizeof(peer));
615 	memcpy(&sock, &_this->ctrl->our, sizeof(sock));
616 	switch (peer.ss_family) {
617 	case AF_INET:
618 		((struct sockaddr_in *)&peer)->sin_port = 0;
619 		((struct sockaddr_in *)&sock)->sin_port = 0;
620 #ifndef USE_LIBSOCKUTIL
621 		peerlen = sizeof(struct sockaddr_in);
622 #endif
623 		break;
624 	default:
625 		return 1;
626 	}
627 
628 	if (PPTP_CTRL_CONF(_this->ctrl)->data_out_pktdump != 0) {
629 		pptp_call_log(_this, LOG_DEBUG, "PPTP Data output packet dump");
630 		show_hd(debug_get_debugfp(), buf, opkt - buf);
631 	}
632 #ifdef USE_LIBSOCKUTIL
633 	sz = sendfromto(pptp_ctrl_sock_gre(_this->ctrl), buf, opkt - buf,
634 	    0, (struct sockaddr *)&sock, (struct sockaddr *)&peer);
635 #else
636 	sz = sendto(pptp_ctrl_sock_gre(_this->ctrl), buf, opkt - buf, 0,
637 	    (struct sockaddr *)&peer, peerlen);
638 #endif
639 
640 	if (sz <= 0)
641 		pptp_call_log(_this, LOG_WARNING, "sendto(%d) failed: %m",
642 		    pptp_ctrl_sock_gre(_this->ctrl));
643 
644 	return (sz > 0)? 0 : 1;
645 }
646 
647 /*
648  * npppd physical layer functions
649  */
650 
651 /* notify to ppp that the PPTP physical layer is already downed */
652 static void
653 pptp_call_notify_down(pptp_call *_this)
654 {
655 	if (_this->ppp != NULL)
656 		ppp_phy_downed(_this->ppp);
657 }
658 
659 
660 /* input packet to ppp */
661 static void
662 pptp_call_ppp_input(pptp_call *_this, u_char *pkt, int pktlen, int delayed)
663 {
664 	int rval;
665 	npppd_ppp *ppp;
666 
667 	ppp = _this->ppp;
668 	if (ppp == NULL) {
669 		pptp_call_log(_this, LOG_WARNING,
670 		    "Received ppp frame but ppp is not assigned yet");
671 		return;
672 	}
673 	rval = ppp->recv_packet(ppp, pkt, pktlen, delayed ? PPP_IO_FLAGS_DELAYED : 0);
674 	if (_this->ppp == NULL)		/* ppp is freed */
675 		return;
676 
677 	if (rval != 0) {
678 		ppp->ierrors++;
679 	} else {
680 		ppp->ipackets++;
681 		ppp->ibytes += pktlen;
682 	}
683 }
684 
685 /* it called when ppp outputs packet */
686 static int
687 pptp_call_ppp_output(npppd_ppp *ppp, unsigned char *bytes, int nbytes,
688     int flags)
689 {
690 	pptp_call *_this;
691 
692 	_this = ppp->phy_context;
693 	PPTP_CALL_ASSERT(_this != NULL);
694 
695 	if (_this == NULL)
696 		return 0;
697 
698 	if (pptp_call_gre_output(_this, 1, 1, bytes, nbytes) != 0) {
699 		ppp->oerrors++;
700 		return 1;
701 	}
702 	ppp->opackets++;
703 	ppp->obytes += nbytes;
704 
705 	return 0;
706 }
707 
708 /* it called when pptp call was closed at ppp */
709 static void
710 pptp_call_closed_by_ppp(npppd_ppp *ppp)
711 {
712 	pptp_call *_this;
713 
714 	PPTP_CALL_ASSERT(ppp != NULL);
715 	PPTP_CALL_ASSERT(ppp->phy_context != NULL);
716 
717 	_this = ppp->phy_context;
718 
719 	/* do this before pptp_call_disconnect() */
720 	_this->ppp = NULL;
721 
722 	if (_this->state != PPTP_CALL_STATE_CLEANUP_WAIT) {
723 		pptp_call_disconnect(_this, PPTP_CDN_RESULT_LOST_CARRIER, 0,
724 		    NULL);
725 	}
726 	pptp_call_log(_this, LOG_NOTICE, "logtype=PPPUnbind");
727 }
728 
729 /* bind() for ppp */
730 static int
731 pptp_call_bind_ppp(pptp_call *_this)
732 {
733 	npppd_ppp *ppp;
734 
735 	ppp = NULL;
736 	if ((ppp = ppp_create()) == NULL)
737 		goto fail;
738 
739 	PPTP_CALL_ASSERT(_this->ppp == NULL);
740 
741 	if (_this->ppp != NULL)
742 		return -1;
743 
744 	_this->ppp = ppp;
745 
746 	ppp->phy_context = _this;
747 	ppp->tunnel_type = NPPPD_TUNNEL_PPTP;
748 	ppp->send_packet = pptp_call_ppp_output;
749 	ppp->phy_close = pptp_call_closed_by_ppp;
750 
751 	strlcpy(ppp->phy_label, PPTP_CTRL_LISTENER_TUN_NAME(_this->ctrl),
752 	    sizeof(ppp->phy_label));
753 
754 	PPTP_CALL_ASSERT(sizeof(ppp->phy_info) >= _this->ctrl->peer.ss_len);
755 	memcpy(&ppp->phy_info, &_this->ctrl->peer,
756 	    MIN(sizeof(ppp->phy_info), _this->ctrl->peer.ss_len));
757 
758 	if (ppp_init(npppd_get_npppd(), ppp) != 0)
759 		goto fail;
760 
761 	pptp_call_log(_this, LOG_NOTICE, "logtype=PPPBind ppp=%d", ppp->id);
762 	ppp_start(ppp);
763 
764 	return 0;
765 fail:
766 	pptp_call_log(_this, LOG_ERR, "failed binding ppp");
767 
768 	if (ppp != NULL)
769 		ppp_destroy(ppp);
770 	_this->ppp = NULL;
771 
772 	return 1;
773 }
774 
775 /*
776  * utility functions
777  */
778 
779 /* logging with the label for the instance */
780 static void
781 pptp_call_log(pptp_call *_this, int prio, const char *fmt, ...)
782 {
783 	char logbuf[BUFSIZ];
784 	va_list ap;
785 
786 	va_start(ap, fmt);
787 #ifdef	PPTPD_MULTIPLE
788 	snprintf(logbuf, sizeof(logbuf), "pptpd id=%u ctrl=%u call=%u %s",
789 	    _this->ctrl->pptpd->id, _this->ctrl->id, _this->id, fmt);
790 #else
791 	snprintf(logbuf, sizeof(logbuf), "pptpd ctrl=%u call=%u %s",
792 	    _this->ctrl->id, _this->id, fmt);
793 #endif
794 	vlog_printf(prio, logbuf, ap);
795 	va_end(ap);
796 }
797 
798 /* convert Outgoing-Call-Request packet to strings */
799 static void
800 pptp_call_OCRQ_string(struct pptp_ocrq *ocrq, char *buf, int lbuf)
801 {
802 	snprintf(buf, lbuf,
803 	    "call_id=%u call_serial_number=%u max_bps=%u min_bps=%u bearer=%s "
804 	    "framing=%s recv_winsz=%u packet_proccessing_delay=%u "
805 	    "phone_nunmber=%s subaddress=%s",
806 	    ocrq->call_id, ocrq->call_serial_number, ocrq->maximum_bps,
807 	    ocrq->minimum_bps, pptp_bearer_string(ocrq->bearer_type),
808 	    pptp_framing_string(ocrq->framing_type), ocrq->recv_winsz,
809 	    ocrq->packet_proccessing_delay, ocrq->phone_number,
810 	    ocrq->subaddress);
811 }
812 
813 /* convert Outgoing-Call-Reply packet to strings */
814 void
815 pptp_call_OCRP_string(struct pptp_ocrp *ocrp, char *buf, int lbuf)
816 {
817 	snprintf(buf, lbuf,
818 	    "call_id=%u peers_call_id=%u result=%u error=%u cause=%u "
819 	    "conn_speed=%u recv_winsz=%u packet_proccessing_delay=%u "
820 	    "physical_channel_id=%u",
821 	    ocrp->call_id, ocrp->peers_call_id, ocrp->result_code,
822 	    ocrp->error_code, ocrp->cause_code, ocrp->connect_speed,
823 	    ocrp->recv_winsz, ocrp->packet_proccessing_delay,
824 	    ocrp->physical_channel_id);
825 }
826 
827 static char *
828 pptp_call_state_string(int state)
829 {
830 	switch (state) {
831 	case PPTP_CALL_STATE_IDLE:
832 		return "idle";
833 	case PPTP_CALL_STATE_WAIT_CONN:
834 		return "wait-conn";
835 	case PPTP_CALL_STATE_ESTABLISHED:
836 		return "established";
837 	case PPTP_CALL_STATE_CLEANUP_WAIT:
838 		return "cleanup-wait";
839 	}
840 	return "unknown";
841 }
842 
843