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