xref: /openbsd/usr.sbin/npppd/pptp/pptp_ctrl.c (revision f5c2ff87)
1 /*	$OpenBSD: pptp_ctrl.c,v 1.13 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 /**@file
29  * PPTP(RFC 2637) control connection implementation.
30  * currently it only support PAC part
31  */
32 /* $Id: pptp_ctrl.c,v 1.13 2021/03/29 03:54:40 yasuoka Exp $ */
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <stdio.h>
37 #include <stdarg.h>
38 #include <stdlib.h>
39 #include <netdb.h>
40 #include <unistd.h>
41 #include <syslog.h>
42 #include <time.h>
43 #include <fcntl.h>
44 #include <errno.h>
45 #include <string.h>
46 #include <event.h>
47 
48 #include "bytebuf.h"
49 #include "debugutil.h"
50 #include "hash.h"
51 #include "slist.h"
52 #include "time_utils.h"
53 
54 #include "version.h"
55 
56 #include "pptp.h"
57 #include "pptp_local.h"
58 #include "pptp_subr.h"
59 
60 #define MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
61 #define MAXIMUM(a, b)	(((a) > (b)) ? (a) : (b))
62 
63 /* periods of pptp_ctrl_timeout */
64 #define PPTP_CTRL_TIMEOUT_IVAL_SEC	2
65 
66 #ifdef	PPTP_CTRL_DEBUG
67 #define	PPTP_CTRL_ASSERT(x)	ASSERT(x)
68 #define	PPTP_CTRL_DBG(x)	pptp_ctrl_log x
69 #else
70 #define	PPTP_CTRL_ASSERT(x)
71 #define	PPTP_CTRL_DBG(x)
72 #endif
73 
74 static unsigned pptp_ctrl_seqno = 0;
75 
76 static void  pptp_ctrl_log (pptp_ctrl *, int, const char *, ...) __printflike(3,4);
77 static void        pptp_ctrl_timeout (int, short, void *);
78 static void        pptp_ctrl_reset_timeout (pptp_ctrl *);
79 static void        pptp_ctrl_io_event (int, short, void *);
80 static void        pptp_ctrl_set_io_event (pptp_ctrl *);
81 static int         pptp_ctrl_output_flush (pptp_ctrl *);
82 static void        pptp_ctrl_SCCRx_string (struct pptp_scc *, u_char *, int);
83 static int         pptp_ctrl_recv_SCCRQ (pptp_ctrl *, u_char *, int);
84 static int         pptp_ctrl_recv_StopCCRP (pptp_ctrl *, u_char *, int);
85 static int         pptp_ctrl_send_StopCCRQ (pptp_ctrl *, int);
86 static int         pptp_ctrl_recv_StopCCRQ (pptp_ctrl *, u_char *, int);
87 static int         pptp_ctrl_send_StopCCRP (pptp_ctrl *, int, int);
88 static int         pptp_ctrl_send_SCCRP (pptp_ctrl *, int, int);
89 static void        pptp_ctrl_send_CDN (pptp_ctrl *, int, int, int, const char *);
90 static void        pptp_ctrl_process_echo_req (pptp_ctrl *, u_char *, int);
91 static int         pptp_ctrl_recv_echo_rep (pptp_ctrl *, u_char *, int);
92 static void        pptp_ctrl_send_echo_req (pptp_ctrl *);
93 static int         pptp_ctrl_input (pptp_ctrl *, u_char *, int);
94 static int         pptp_ctrl_call_input (pptp_ctrl *, int, u_char *, int);
95 static const char  *pptp_ctrl_state_string (int);
96 static void        pptp_ctrl_fini(pptp_ctrl *);
97 
98 /*
99  * pptp_ctrl instance operation functions
100  */
101 pptp_ctrl *
pptp_ctrl_create(void)102 pptp_ctrl_create(void)
103 {
104 	pptp_ctrl *_this;
105 
106 	if ((_this = malloc(sizeof(pptp_ctrl))) == NULL)
107 		return NULL;
108 
109 	return _this;
110 }
111 
112 int
pptp_ctrl_init(pptp_ctrl * _this)113 pptp_ctrl_init(pptp_ctrl *_this)
114 {
115 	time_t curr_time;
116 
117 	PPTP_CTRL_ASSERT(_this != NULL);
118 	curr_time = get_monosec();
119 	memset(_this, 0, sizeof(pptp_ctrl));
120 	_this->id = pptp_ctrl_seqno++;
121 	_this->sock = -1;
122 
123 	if ((_this->recv_buf = bytebuffer_create(PPTP_BUFSIZ)) == NULL) {
124 		pptp_ctrl_log(_this, LOG_ERR, "bytebuffer_create() failed at "
125 		    "%s(): %m", __func__);
126 		goto fail;
127 	}
128 	if ((_this->send_buf = bytebuffer_create(PPTP_BUFSIZ)) == NULL) {
129 		pptp_ctrl_log(_this, LOG_ERR, "bytebuffer_create() failed at "
130 		    "%s(): %m", __func__);
131 		goto fail;
132 	}
133 	_this->last_rcv_ctrl = curr_time;
134 	_this->last_snd_ctrl = curr_time;
135 	_this->echo_seq = arc4random();
136 	_this->echo_interval = PPTP_CTRL_DEFAULT_ECHO_INTERVAL;
137 	_this->echo_timeout = PPTP_CTRL_DEFAULT_ECHO_TIMEOUT;
138 	slist_init(&_this->call_list);
139 	evtimer_set(&_this->ev_timer, pptp_ctrl_timeout, _this);
140 
141 	return 0;
142 fail:
143 	return 1;
144 }
145 
146 int
pptp_ctrl_start(pptp_ctrl * _this)147 pptp_ctrl_start(pptp_ctrl *_this)
148 {
149 	int ival;
150 	char hbuf0[NI_MAXHOST], sbuf0[NI_MAXSERV];
151 	char hbuf1[NI_MAXHOST], sbuf1[NI_MAXSERV];
152 	struct sockaddr_storage sock;
153 	socklen_t socklen;
154 
155 	PPTP_CTRL_ASSERT(_this != NULL);
156 	PPTP_CTRL_ASSERT(_this->sock >= 0);
157 
158 	/* convert address to strings for logging */
159 	strlcpy(hbuf0, "<unknown>", sizeof(hbuf0));
160 	strlcpy(sbuf0, "<unknown>", sizeof(sbuf0));
161 	strlcpy(hbuf1, "<unknown>", sizeof(hbuf1));
162 	strlcpy(sbuf1, "<unknown>", sizeof(sbuf1));
163 	if (getnameinfo((struct sockaddr *)&_this->peer, _this->peer.ss_len,
164 	    hbuf0, sizeof(hbuf0), sbuf0, sizeof(sbuf0),
165 	    NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
166 		pptp_ctrl_log(_this, LOG_ERR,
167 		    "getnameinfo() failed at %s(): %m", __func__);
168 	}
169 	socklen = sizeof(sock);
170 	if (getsockname(_this->sock, (struct sockaddr *)&sock, &socklen) != 0) {
171 		pptp_ctrl_log(_this, LOG_ERR,
172 		    "getsockname() failed at %s(): %m", __func__);
173 		goto fail;
174 	}
175 	if (getnameinfo((struct sockaddr *)&sock, sock.ss_len, hbuf1,
176 	    sizeof(hbuf1), sbuf1, sizeof(sbuf1),
177 	    NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
178 		pptp_ctrl_log(_this, LOG_ERR,
179 		    "getnameinfo() failed at %s(): %m", __func__);
180 	}
181 	pptp_ctrl_log(_this, LOG_INFO, "Starting peer=%s:%s/tcp "
182 	    "sock=%s:%s/tcp", hbuf0, sbuf0, hbuf1, sbuf1);
183 
184 	if ((ival = fcntl(_this->sock, F_GETFL)) < 0) {
185 		pptp_ctrl_log(_this, LOG_ERR,
186 		    "fcntl(F_GET_FL) failed at %s(): %m", __func__);
187 		goto fail;
188 	} else if (fcntl(_this->sock, F_SETFL, ival | O_NONBLOCK) < 0) {
189 		pptp_ctrl_log(_this, LOG_ERR,
190 		    "fcntl(F_SET_FL) failed at %s(): %m", __func__);
191 		goto fail;
192 	}
193 	pptp_ctrl_set_io_event(_this);
194 	pptp_ctrl_reset_timeout(_this);
195 
196 	return 0;
197 fail:
198 	return 1;
199 }
200 
201 /* Timer */
202 static void
pptp_ctrl_timeout(int fd,short event,void * ctx)203 pptp_ctrl_timeout(int fd, short event, void *ctx)
204 {
205 	int i;
206 	pptp_call *call;
207 	pptp_ctrl *_this;
208 	time_t last, curr_time;
209 
210 	_this = ctx;
211 	curr_time = get_monosec();
212 
213 	PPTP_CTRL_DBG((_this, DEBUG_LEVEL_3, "enter %s()", __func__));
214 	/* clean up call */
215 	i = 0;
216 	while (i < slist_length(&_this->call_list)) {
217 		call = slist_get(&_this->call_list, i);
218 		if (call->state == PPTP_CALL_STATE_CLEANUP_WAIT &&
219 		    curr_time - call->last_io > PPTP_CALL_CLEANUP_WAIT_TIME) {
220 			pptp_call_stop(call);
221 			pptp_call_destroy(call);
222 			slist_remove(&_this->call_list, i);
223 		} else
224 			i++;
225 	}
226 
227 	/* State machine: Timeout */
228 	switch (_this->state) {
229 	default:
230 	case PPTP_CTRL_STATE_WAIT_CTRL_REPLY:
231 	case PPTP_CTRL_STATE_IDLE:
232 		if (curr_time - _this->last_rcv_ctrl > PPTPD_IDLE_TIMEOUT) {
233 			pptp_ctrl_log(_this, LOG_ERR,
234 			    "Timeout in state %s",
235 			    pptp_ctrl_state_string(_this->state));
236 			pptp_ctrl_fini(_this);
237 			return;
238 		}
239 		break;
240 	case PPTP_CTRL_STATE_ESTABLISHED:
241 		last = MAXIMUM(_this->last_rcv_ctrl, _this->last_snd_ctrl);
242 
243 		if (curr_time - _this->last_rcv_ctrl
244 			    >= _this->echo_interval + _this->echo_timeout) {
245 			pptp_ctrl_log(_this, LOG_INFO,
246 			    "Timeout waiting for echo reply");
247 			pptp_ctrl_fini(_this);
248 			return;
249 		}
250 		if (curr_time - last >= _this->echo_interval) {
251 			PPTP_CTRL_DBG((_this, LOG_DEBUG, "Echo"));
252 			_this->echo_seq++;
253 			pptp_ctrl_send_echo_req(_this);
254 		}
255 		break;
256 	case PPTP_CTRL_STATE_WAIT_STOP_REPLY:
257 		if (curr_time - _this->last_snd_ctrl >
258 		    PPTP_CTRL_StopCCRP_WAIT_TIME) {
259 			pptp_ctrl_log(_this, LOG_WARNING,
260 			    "Timeout waiting for StopCCRP");
261 			pptp_ctrl_fini(_this);
262 			return;
263 		}
264 		break;
265 	case PPTP_CTRL_STATE_DISPOSING:
266 		pptp_ctrl_fini(_this);
267 		return;
268 	}
269 	pptp_ctrl_reset_timeout(_this);
270 }
271 
272 static void
pptp_ctrl_reset_timeout(pptp_ctrl * _this)273 pptp_ctrl_reset_timeout(pptp_ctrl *_this)
274 {
275 	struct timeval tv;
276 
277 	switch (_this->state) {
278 	case PPTP_CTRL_STATE_DISPOSING:
279 		/* call back immediately */
280 		timerclear(&tv);
281 		break;
282 	default:
283 		tv.tv_sec = PPTP_CTRL_TIMEOUT_IVAL_SEC;
284 		tv.tv_usec = 0;
285 		break;
286 	}
287 	evtimer_add(&_this->ev_timer, &tv);
288 }
289 
290 /**
291  * Terminate PPTP control connection
292  * @result	The value for Stop-Control-Connection-Request(StopCCRQ) result.
293 		This function will not sent StopCCRQ when the value == 0 and
294 		the specification does not require to sent it.
295  * @see		::#PPTP_StopCCRQ_REASON_STOP_PROTOCOL
296  * @see		::#PPTP_StopCCRQ_REASON_STOP_LOCAL_SHUTDOWN
297  */
298 void
pptp_ctrl_stop(pptp_ctrl * _this,int result)299 pptp_ctrl_stop(pptp_ctrl *_this, int result)
300 {
301 	int i;
302 	pptp_call *call;
303 
304 	switch (_this->state) {
305 	case PPTP_CTRL_STATE_WAIT_STOP_REPLY:
306 		/* waiting response. */
307 		/* this state will timeout by pptp_ctrl_timeout */
308 		break;
309 	case PPTP_CTRL_STATE_ESTABLISHED:
310 		if (result != 0) {
311 			for (i = 0; i < slist_length(&_this->call_list); i++) {
312 				call = slist_get(&_this->call_list, i);
313 				pptp_call_disconnect(call,
314 				    PPTP_CDN_RESULT_ADMIN_SHUTDOWN, 0, NULL);
315 			}
316 			pptp_ctrl_send_StopCCRQ(_this, result);
317 			_this->state = PPTP_CTRL_STATE_WAIT_STOP_REPLY;
318 			break;
319 		}
320 		/* FALLTHROUGH */
321 	default:
322 		pptp_ctrl_fini(_this);
323 	}
324 	return;
325 }
326 
327 
328 /* finish PPTP control */
329 static void
pptp_ctrl_fini(pptp_ctrl * _this)330 pptp_ctrl_fini(pptp_ctrl *_this)
331 {
332 	pptp_call *call;
333 
334 	PPTP_CTRL_ASSERT(_this != NULL);
335 
336 	if (_this->sock >= 0) {
337 		event_del(&_this->ev_sock);
338 		close(_this->sock);
339 		_this->sock = -1;
340 	}
341 	for (slist_itr_first(&_this->call_list);
342 	    slist_itr_has_next(&_this->call_list);) {
343 		call = slist_itr_next(&_this->call_list);
344 		pptp_call_stop(call);
345 		pptp_call_destroy(call);
346 		slist_itr_remove(&_this->call_list);
347 	}
348 
349 	if (_this->on_io_event != 0) {
350 		/*
351 		 * as the complete terminate process needs complicated
352 		 * exception handling, do partially at here.
353 		 * rest of part will be handled by timer-event-handler.
354 		 */
355 		PPTP_CTRL_DBG((_this, LOG_DEBUG, "Disposing"));
356 		_this->state = PPTP_CTRL_STATE_DISPOSING;
357 		pptp_ctrl_reset_timeout(_this);
358 		return;
359 	}
360 
361 	evtimer_del(&_this->ev_timer);
362 	slist_fini(&_this->call_list);
363 
364 	pptp_ctrl_log (_this, LOG_NOTICE, "logtype=Finished");
365 
366 	/* disable _this */
367 	pptpd_ctrl_finished_notify(_this->pptpd, _this);
368 }
369 
370 /* free PPTP control context */
371 void
pptp_ctrl_destroy(pptp_ctrl * _this)372 pptp_ctrl_destroy(pptp_ctrl *_this)
373 {
374 	if (_this->send_buf != NULL) {
375 		bytebuffer_destroy(_this->send_buf);
376 		_this->send_buf = NULL;
377 	}
378 	if (_this->recv_buf != NULL) {
379 		bytebuffer_destroy(_this->recv_buf);
380 		_this->recv_buf = NULL;
381 	}
382 	free(_this);
383 }
384 
385 /*
386  * network I/O
387  */
388 /* I/O event dispather */
389 static void
pptp_ctrl_io_event(int fd,short evmask,void * ctx)390 pptp_ctrl_io_event(int fd, short evmask, void *ctx)
391 {
392 	int sz, lpkt, hdrlen;
393 	u_char *pkt;
394 	pptp_ctrl *_this;
395 
396 	_this = ctx;
397 	PPTP_CTRL_ASSERT(_this != NULL);
398 
399 	_this->on_io_event = 1;
400 	if ((evmask & EV_WRITE) != 0) {
401 		if (pptp_ctrl_output_flush(_this) != 0 ||
402 		    _this->state == PPTP_CTRL_STATE_DISPOSING)
403 			goto fail;
404 		_this->send_ready = 1;
405 	}
406 	if ((evmask & EV_READ) != 0) {
407 		sz = read(_this->sock, bytebuffer_pointer(_this->recv_buf),
408 		    bytebuffer_remaining(_this->recv_buf));
409 		if (sz <= 0) {
410 			if (sz == 0 || errno == ECONNRESET) {
411 				pptp_ctrl_log(_this, LOG_INFO,
412 				    "Connection closed by foreign host");
413 				pptp_ctrl_fini(_this);
414 				goto fail;
415 			} else if (errno != EAGAIN && errno != EINTR) {
416 				pptp_ctrl_log(_this, LOG_INFO,
417 				    "read() failed at %s(): %m", __func__);
418 				pptp_ctrl_fini(_this);
419 				goto fail;
420 			}
421 		}
422 		bytebuffer_put(_this->recv_buf, BYTEBUFFER_PUT_DIRECT, sz);
423 		bytebuffer_flip(_this->recv_buf);
424 
425 		for (;;) {
426 			pkt = bytebuffer_pointer(_this->recv_buf);
427 			lpkt = bytebuffer_remaining(_this->recv_buf);
428 			if (pkt == NULL ||
429 			    lpkt < sizeof(struct pptp_ctrl_header))
430 				break;	/* read again */
431 
432 			hdrlen = pkt[0] << 8 | pkt[1];
433 			if (lpkt < hdrlen)
434 				break;	/* read again */
435 
436 			bytebuffer_get(_this->recv_buf, NULL, hdrlen);
437 			if (pptp_ctrl_input(_this, pkt, hdrlen) != 0 ||
438 			    _this->state == PPTP_CTRL_STATE_DISPOSING) {
439 				bytebuffer_compact(_this->recv_buf);
440 				goto fail;
441 			}
442 		}
443 		bytebuffer_compact(_this->recv_buf);
444 	}
445 	if (pptp_ctrl_output_flush(_this) != 0)
446 		goto fail;
447 	pptp_ctrl_set_io_event(_this);
448 fail:
449 	_this->on_io_event = 0;
450 }
451 
452 
453 /* set i/o event mask */
454 static void
pptp_ctrl_set_io_event(pptp_ctrl * _this)455 pptp_ctrl_set_io_event(pptp_ctrl *_this)
456 {
457 	int evmask;
458 
459 	PPTP_CTRL_ASSERT(_this != NULL);
460 	PPTP_CTRL_ASSERT(_this->sock >= 0);
461 
462 	evmask = 0;
463 	if (bytebuffer_remaining(_this->recv_buf) > 128)
464 		evmask |= EV_READ;
465 	if (_this->send_ready == 0)
466 		evmask |= EV_WRITE;
467 
468 	event_del(&_this->ev_sock);
469 	if (evmask != 0) {
470 		event_set(&_this->ev_sock, _this->sock, evmask,
471 		    pptp_ctrl_io_event, _this);
472 		event_add(&_this->ev_sock, NULL);
473 	}
474 }
475 
476 /**
477  * Output PPTP control packet
478  * @param pkt	pointer to packet buffer.
479  *		when it was appended by _this-.send_buf using bytebuffer,
480  *		specify NULL.
481  * @param lpkt	packet length
482  */
483 void
pptp_ctrl_output(pptp_ctrl * _this,u_char * pkt,int lpkt)484 pptp_ctrl_output(pptp_ctrl *_this, u_char *pkt, int lpkt)
485 {
486 	PPTP_CTRL_ASSERT(_this != NULL);
487 	PPTP_CTRL_ASSERT(lpkt > 0);
488 
489 	/* just put the packet into the buffer now.  send it later */
490 	bytebuffer_put(_this->send_buf, pkt, lpkt);
491 
492 	if (_this->on_io_event != 0) {
493 		/*
494 		 * pptp_ctrl_output_flush() will be called by the end of
495 		 * the I/O event handler.
496 		 */
497 	} else {
498 		/*
499 		 * When this function is called by other than I/O event handler,
500 		 * we need to call pptp_ctrl_output_flush().  However if we do
501 		 * it here, then we need to consider the situation
502 		 * 'flush => write failure => finalize'.  The situation requires
503 		 * the caller function to handle the exception and causes
504 		 * complication.  So we call pptp_ctrl_output_flush() by the
505 		 * the next send ready event.
506 		 */
507 		_this->send_ready = 0;		/* clear 'send ready' */
508 		pptp_ctrl_set_io_event(_this);	/* wait 'send ready */
509 	}
510 
511 	return;
512 }
513 
514 /* Send Stop-Control-Connection-Request */
515 
516 /* flush output packet */
517 static int
pptp_ctrl_output_flush(pptp_ctrl * _this)518 pptp_ctrl_output_flush(pptp_ctrl *_this)
519 {
520 	int sz;
521 	time_t curr_time;
522 
523 	curr_time = get_monosec();
524 
525 	if (bytebuffer_position(_this->send_buf) <= 0)
526 		return 0;		/* nothing to write */
527 	if (_this->send_ready == 0) {
528 		pptp_ctrl_set_io_event(_this);
529 		return 0;		/* not ready to write */
530 	}
531 
532 	bytebuffer_flip(_this->send_buf);
533 
534 	if (PPTP_CTRL_CONF(_this)->ctrl_out_pktdump != 0) {
535 		pptp_ctrl_log(_this, LOG_DEBUG, "PPTP Control output packet");
536 		show_hd(debug_get_debugfp(),
537 		    bytebuffer_pointer(_this->send_buf),
538 		    bytebuffer_remaining(_this->send_buf));
539 	}
540 	if ((sz = write(_this->sock, bytebuffer_pointer(_this->send_buf),
541 	    bytebuffer_remaining(_this->send_buf))) < 0) {
542 		pptp_ctrl_log(_this, LOG_ERR, "write to socket failed: %m");
543 		pptp_ctrl_fini(_this);
544 
545 		return 1;
546 	}
547 	_this->last_snd_ctrl = curr_time;
548 	bytebuffer_get(_this->send_buf, NULL, sz);
549 	bytebuffer_compact(_this->send_buf);
550 	_this->send_ready = 0;
551 
552 	return 0;
553 }
554 
555 /* convert Start-Control-Connection-{Request,Reply} packet to strings */
556 static void
pptp_ctrl_SCCRx_string(struct pptp_scc * scc,u_char * buf,int lbuf)557 pptp_ctrl_SCCRx_string(struct pptp_scc *scc, u_char *buf, int lbuf)
558 {
559 	char results[128];
560 
561 	if (scc->result_code != 0)
562 		snprintf(results, sizeof(results), "result=%d error=%d ",
563 		    scc->result_code, scc->error_code);
564 	else
565 		results[0] = '\0';
566 
567 	snprintf(buf, lbuf,
568 	    "protocol_version=%d.%d %sframing=%s bearer=%s max_channels=%d "
569 	    "firmware_revision=%d(0x%04x) host_name=\"%.*s\" "
570 	    "vendor_string=\"%.*s\"",
571 	    scc->protocol_version >> 8, scc->protocol_version & 0xff, results,
572 	    pptp_framing_string(scc->framing_caps),
573 	    pptp_bearer_string(scc->bearer_caps), scc->max_channels,
574 	    scc->firmware_revision, scc->firmware_revision,
575 	    (u_int)sizeof(scc->host_name), scc->host_name,
576 	    (u_int)sizeof(scc->vendor_string), scc->vendor_string);
577 }
578 
579 /* receive Start-Control-Connection-Request */
580 static int
pptp_ctrl_recv_SCCRQ(pptp_ctrl * _this,u_char * pkt,int lpkt)581 pptp_ctrl_recv_SCCRQ(pptp_ctrl *_this, u_char *pkt, int lpkt)
582 {
583 	char logbuf[512];
584 	struct pptp_scc *scc;
585 
586 	/* sanity check */
587 	if (lpkt < sizeof(struct pptp_scc)) {
588 		pptp_ctrl_log(_this, LOG_ERR, "Received bad SCCRQ: packet too "
589 		    "short: %d < %d", lpkt, (int)sizeof(struct pptp_scc));
590 		return 1;
591 	}
592 	scc = (struct pptp_scc *)pkt;
593 
594 	scc->protocol_version = ntohs(scc->protocol_version);
595 	scc->framing_caps = htonl(scc->framing_caps);
596 	scc->bearer_caps = htonl(scc->bearer_caps);
597 	scc->max_channels = htons(scc->max_channels);
598 	scc->firmware_revision = htons(scc->firmware_revision);
599 
600 	/* check protocol version */
601 	if (scc->protocol_version != PPTP_RFC_2637_VERSION) {
602 		pptp_ctrl_log(_this, LOG_ERR, "Received bad SCCRQ: "
603 		    "unknown protocol version %d", scc->protocol_version);
604 		return 1;
605 	}
606 
607 	pptp_ctrl_SCCRx_string(scc, logbuf, sizeof(logbuf));
608 	pptp_ctrl_log(_this, LOG_INFO, "RecvSCCRQ %s", logbuf);
609 
610 	return 0;
611 }
612 
613 /* Receive Stop-Control-Connection-Reply */
614 static int
pptp_ctrl_recv_StopCCRP(pptp_ctrl * _this,u_char * pkt,int lpkt)615 pptp_ctrl_recv_StopCCRP(pptp_ctrl *_this, u_char *pkt, int lpkt)
616 {
617 	struct pptp_stop_ccrp *stop_ccrp;
618 
619 	if (lpkt < sizeof(struct pptp_stop_ccrp)) {
620 		pptp_ctrl_log(_this, LOG_ERR, "Received bad StopCCRP: packet "
621 		    "too short: %d < %d", lpkt,
622 		    (int)sizeof(struct pptp_stop_ccrp));
623 		return 1;
624 	}
625 	stop_ccrp = (struct pptp_stop_ccrp *)pkt;
626 
627 	pptp_ctrl_log(_this, LOG_INFO, "RecvStopCCRP reason=%s(%u)",
628 	    pptp_StopCCRP_result_string(stop_ccrp->result), stop_ccrp->result);
629 
630 	return 0;
631 }
632 
633 static int
pptp_ctrl_send_StopCCRQ(pptp_ctrl * _this,int reason)634 pptp_ctrl_send_StopCCRQ(pptp_ctrl *_this, int reason)
635 {
636 	int lpkt;
637 	struct pptp_stop_ccrq *stop_ccrq;
638 
639 	stop_ccrq = bytebuffer_pointer(_this->send_buf);
640 	lpkt = bytebuffer_remaining(_this->send_buf);
641 	if (lpkt < sizeof(struct pptp_stop_ccrq)) {
642 		pptp_ctrl_log(_this, LOG_ERR,
643 		    "SendCCRP failed: No buffer space available");
644 		return -1;
645 	}
646 	memset(stop_ccrq, 0, sizeof(struct pptp_stop_ccrq));
647 
648 	pptp_init_header(&stop_ccrq->header, sizeof(struct pptp_stop_ccrq),
649 	    PPTP_CTRL_MES_CODE_StopCCRQ);
650 
651 	stop_ccrq->reason = reason;
652 
653 	pptp_ctrl_log(_this, LOG_INFO, "SendStopCCRQ reason=%s(%u)",
654 	    pptp_StopCCRQ_reason_string(stop_ccrq->reason), stop_ccrq->reason);
655 
656 	pptp_ctrl_output(_this, NULL, sizeof(struct pptp_stop_ccrq));
657 
658 	return 0;
659 }
660 
661 /* Receive Stop-Control-Connection-Request */
662 static int
pptp_ctrl_recv_StopCCRQ(pptp_ctrl * _this,u_char * pkt,int lpkt)663 pptp_ctrl_recv_StopCCRQ(pptp_ctrl *_this, u_char *pkt, int lpkt)
664 {
665 	struct pptp_stop_ccrq *stop_ccrq;
666 
667 	if (lpkt < sizeof(struct pptp_stop_ccrq)) {
668 		pptp_ctrl_log(_this, LOG_ERR, "Received bad StopCCRQ: packet "
669 		    "too short: %d < %d", lpkt,
670 		    (int)sizeof(struct pptp_stop_ccrq));
671 		return 1;
672 	}
673 	stop_ccrq = (struct pptp_stop_ccrq *)pkt;
674 
675 	pptp_ctrl_log(_this, LOG_INFO, "RecvStopCCRQ reason=%s(%u)",
676 	    pptp_StopCCRQ_reason_string(stop_ccrq->reason), stop_ccrq->reason);
677 
678 	return 0;
679 }
680 
681 /* Send Stop-Control-Connection-Reply */
682 static int
pptp_ctrl_send_StopCCRP(pptp_ctrl * _this,int result,int error)683 pptp_ctrl_send_StopCCRP(pptp_ctrl *_this, int result, int error)
684 {
685 	int lpkt;
686 	struct pptp_stop_ccrp *stop_ccrp;
687 
688 	stop_ccrp = bytebuffer_pointer(_this->send_buf);
689 
690 	lpkt = bytebuffer_remaining(_this->send_buf);
691 	if (lpkt < sizeof(struct pptp_stop_ccrp)) {
692 		pptp_ctrl_log(_this, LOG_ERR,
693 		    "SendCCRQ failed: No buffer space available");
694 		return -1;
695 	}
696 	memset(stop_ccrp, 0, sizeof(struct pptp_stop_ccrp));
697 
698 	pptp_init_header(&stop_ccrp->header, sizeof(struct pptp_stop_ccrp),
699 	    PPTP_CTRL_MES_CODE_StopCCRP);
700 
701 	stop_ccrp->result = result;
702 	stop_ccrp->error = error;
703 
704 	pptp_ctrl_log(_this, LOG_INFO,
705 	    "SendStopCCRP result=%s(%u) error=%s(%u)",
706 	    pptp_StopCCRP_result_string(stop_ccrp->result), stop_ccrp->result,
707 	    pptp_general_error_string(stop_ccrp->error), stop_ccrp->error);
708 
709 	pptp_ctrl_output(_this, NULL, sizeof(struct pptp_stop_ccrp));
710 
711 	return 0;
712 }
713 
714 /* Send Start-Control-Connection-Reply */
715 static int
pptp_ctrl_send_SCCRP(pptp_ctrl * _this,int result,int error)716 pptp_ctrl_send_SCCRP(pptp_ctrl *_this, int result, int error)
717 {
718 	int lpkt;
719 	struct pptp_scc *scc;
720 	char logbuf[512];
721 	const char *val;
722 
723 	scc = bytebuffer_pointer(_this->send_buf);
724 	lpkt = bytebuffer_remaining(_this->send_buf);
725 	if (lpkt < sizeof(struct pptp_scc)) {
726 		pptp_ctrl_log(_this, LOG_ERR,
727 		    "SendSCCRP failed: No buffer space available");
728 		return -1;
729 	}
730 	memset(scc, 0, sizeof(struct pptp_scc));
731 
732 	pptp_init_header(&scc->header, sizeof(struct pptp_scc),
733 	    PPTP_CTRL_MES_CODE_SCCRP);
734 
735 	scc->protocol_version = PPTP_RFC_2637_VERSION;
736 	scc->result_code = result;
737 	scc->error_code = error;
738 
739 	/* XXX only support sync frames */
740 	scc->framing_caps = PPTP_CTRL_FRAMING_SYNC;
741 	scc->bearer_caps = PPTP_CTRL_BEARER_DIGITAL;
742 
743 	scc->max_channels = 4;		/* XXX */
744 	scc->firmware_revision = MAJOR_VERSION << 8 | MINOR_VERSION;
745 
746 	/* this implementation only support these strings up to
747 	 * 63 character */
748 	/* host name */
749 
750 	if ((val = PPTP_CTRL_CONF(_this)->hostname) == NULL)
751 		val = "";
752 	strlcpy(scc->host_name, val, sizeof(scc->host_name));
753 
754 	/* vendor name */
755 	if (PPTP_CTRL_CONF(_this)->vendor_name == NULL)
756 		val = PPTPD_DEFAULT_VENDOR_NAME;
757 	strlcpy(scc->vendor_string, val, sizeof(scc->vendor_string));
758 
759 	pptp_ctrl_SCCRx_string(scc, logbuf, sizeof(logbuf));
760 	pptp_ctrl_log(_this, LOG_INFO, "SendSCCRP %s", logbuf);
761 
762 	scc->protocol_version = htons(scc->protocol_version);
763 	scc->framing_caps = htonl(scc->framing_caps);
764 	scc->bearer_caps = htonl(scc->bearer_caps);
765 	scc->max_channels = htons(scc->max_channels);
766 	scc->firmware_revision = htons(scc->firmware_revision);
767 
768 	pptp_ctrl_output(_this, NULL, sizeof(struct pptp_scc));
769 
770 	return 0;
771 }
772 
773 /* receive ECHO and reply */
774 static void
pptp_ctrl_process_echo_req(pptp_ctrl * _this,u_char * pkt,int lpkt)775 pptp_ctrl_process_echo_req(pptp_ctrl *_this, u_char *pkt, int lpkt)
776 {
777 	struct pptp_echo_rq *echo_rq;
778 	struct pptp_echo_rp *echo_rp;
779 
780 	if (lpkt < sizeof(struct pptp_echo_rq)) {
781 		pptp_ctrl_log(_this, LOG_ERR, "Received bad EchoReq: packet "
782 		    "too short: %d < %d", lpkt,
783 		    (int)sizeof(struct pptp_echo_rq));
784 		return;
785 	}
786 	echo_rq = (struct pptp_echo_rq *)pkt;
787 
788 	PPTP_CTRL_DBG((_this, LOG_DEBUG, "RecvEchoReq"));
789 
790 	echo_rp = bytebuffer_pointer(_this->send_buf);
791 	lpkt = bytebuffer_remaining(_this->send_buf);
792 	if (echo_rp == NULL || lpkt < sizeof(struct pptp_echo_rp)) {
793 		pptp_ctrl_log(_this, LOG_ERR,
794 		    "Failed to send EchoReq: No buffer space available");
795 		return;
796 	}
797 	memset(echo_rp, 0, sizeof(struct pptp_echo_rp));
798 
799 	pptp_init_header(&echo_rp->header, sizeof(struct pptp_echo_rp),
800 	    PPTP_CTRL_MES_CODE_ECHO_RP);
801 
802 	echo_rp->identifier = echo_rq->identifier;
803 	echo_rp->result_code = PPTP_ECHO_RP_RESULT_OK;
804 	echo_rp->error_code = PPTP_ERROR_NONE;
805 	echo_rp->reserved1 = htons(0);
806 
807 	pptp_ctrl_output(_this, NULL, sizeof(struct pptp_echo_rp));
808 	PPTP_CTRL_DBG((_this, LOG_DEBUG, "SendEchoReply"));
809 }
810 
811 /* receiver Echo-Reply */
812 static int
pptp_ctrl_recv_echo_rep(pptp_ctrl * _this,u_char * pkt,int lpkt)813 pptp_ctrl_recv_echo_rep(pptp_ctrl *_this, u_char *pkt, int lpkt)
814 {
815 	struct pptp_echo_rp *echo_rp;
816 
817 	if (lpkt < sizeof(struct pptp_echo_rp)) {
818 		pptp_ctrl_log(_this, LOG_ERR, "Received bad EchoReq: packet "
819 		    "too short: %d < %d", lpkt,
820 		    (int)sizeof(struct pptp_echo_rp));
821 		return 1;
822 	}
823 	echo_rp = (struct pptp_echo_rp *)pkt;
824 
825 	if (echo_rp->result_code != PPTP_ECHO_RP_RESULT_OK) {
826 		pptp_ctrl_log(_this, LOG_ERR, "Received negative EchoReply: %s",
827 		    pptp_general_error_string(echo_rp->error_code));
828 		return 1;
829 	}
830 	if (_this->echo_seq != ntohl(echo_rp->identifier)) {
831 		pptp_ctrl_log(_this, LOG_ERR, "Received bad EchoReply: "
832 		    "Identifier mismatch sent=%u recv=%u",
833 		    _this->echo_seq , ntohl(echo_rp->identifier));
834 		return 1;
835 	}
836 	PPTP_CTRL_DBG((_this, LOG_DEBUG, "RecvEchoReply"));
837 	return 0;
838 }
839 
840 /* send Echo-Request */
841 static void
pptp_ctrl_send_echo_req(pptp_ctrl * _this)842 pptp_ctrl_send_echo_req(pptp_ctrl *_this)
843 {
844 	int lpkt;
845 	struct pptp_echo_rq *echo_rq;
846 
847 	echo_rq = (struct pptp_echo_rq *)bytebuffer_pointer(_this->send_buf);
848 	lpkt = bytebuffer_remaining(_this->send_buf);
849 	if (echo_rq == NULL || lpkt < sizeof(struct pptp_echo_rq)) {
850 		pptp_ctrl_log(_this, LOG_ERR,
851 		    "SendEchoReq failed: No buffer space available");
852 		return;
853 	}
854 	memset(echo_rq, 0, sizeof(struct pptp_echo_rq));
855 
856 	pptp_init_header(&echo_rq->header, sizeof(struct pptp_echo_rq),
857 	    PPTP_CTRL_MES_CODE_ECHO_RQ);
858 
859 	echo_rq->identifier = htonl(_this->echo_seq);
860 
861 	pptp_ctrl_output(_this, NULL, sizeof(struct pptp_echo_rq));
862 	PPTP_CTRL_DBG((_this, LOG_DEBUG, "SendEchoReq"));
863 }
864 
865 /* send Call-Disconnect-Notify */
866 static void
pptp_ctrl_send_CDN(pptp_ctrl * _this,int result,int error,int cause,const char * statistics)867 pptp_ctrl_send_CDN(pptp_ctrl *_this, int result, int error, int cause,
868     const char *statistics)
869 {
870 	int lpkt;
871 	struct pptp_cdn *cdn;
872 
873 	cdn = bytebuffer_pointer(_this->send_buf);
874 	lpkt = bytebuffer_remaining(_this->send_buf);
875 	if (lpkt < sizeof(struct pptp_cdn)) {
876 		pptp_ctrl_log(_this, LOG_ERR,
877 		    "SendCCR failed: No buffer space available");
878 		return;
879 	}
880 	memset(cdn, 0, sizeof(struct pptp_cdn));
881 
882 	pptp_init_header(&cdn->header, sizeof(struct pptp_cdn),
883 	    PPTP_CTRL_MES_CODE_CDN);
884 
885 	cdn->call_id = _this->id;
886 	cdn->result_code = result;
887 	cdn->error_code = error;
888 	cdn->cause_code = cause;
889 	if (statistics != NULL)
890 		strlcpy(cdn->statistics, statistics, sizeof(cdn->statistics));
891 
892 	cdn->call_id = htons(cdn->call_id);
893 	cdn->cause_code = htons(cdn->cause_code);
894 
895 	pptp_ctrl_output(_this, NULL, sizeof(struct pptp_cdn));
896 }
897 
898 /* receive Control-packet */
899 static int
pptp_ctrl_input(pptp_ctrl * _this,u_char * pkt,int lpkt)900 pptp_ctrl_input(pptp_ctrl *_this, u_char *pkt, int lpkt)
901 {
902 	char errmes[256];
903 	time_t curr_time;
904 	struct pptp_ctrl_header *hdr;
905 
906 	PPTP_CTRL_ASSERT(lpkt >= sizeof(struct pptp_ctrl_header));
907 
908 	curr_time = get_monosec();
909 	hdr = (struct pptp_ctrl_header *)pkt;
910 
911 	hdr->length = ntohs(hdr->length);
912 	hdr->pptp_message_type  = ntohs(hdr->pptp_message_type);
913 	hdr->magic_cookie  = ntohl(hdr->magic_cookie);
914 	hdr->control_message_type = ntohs(hdr->control_message_type);
915 	hdr->reserved0 = ntohs(hdr->reserved0);
916 
917 	/* sanity check */
918 	PPTP_CTRL_ASSERT(hdr->length <= lpkt);
919 
920 	_this->last_rcv_ctrl = curr_time;
921 
922 	if (PPTP_CTRL_CONF(_this)->ctrl_in_pktdump != 0) {
923 		pptp_ctrl_log(_this, LOG_DEBUG,
924 		    "PPTP Control input packet dump: mestype=%s(%d)",
925 		    pptp_ctrl_mes_type_string(hdr->control_message_type),
926 		    hdr->control_message_type);
927 		show_hd(debug_get_debugfp(), pkt, lpkt);
928 	}
929 
930 	/* inspect packet body */
931 	/* message type */
932 	if (hdr->pptp_message_type != PPTP_MES_TYPE_CTRL) {
933 		snprintf(errmes, sizeof(errmes), "unknown message type %d",
934 		    hdr->pptp_message_type);
935 		goto bad_packet;
936 	}
937 	/* magic cookie */
938 	if (hdr->magic_cookie != PPTP_MAGIC_COOKIE) {
939 		snprintf(errmes, sizeof(errmes), "wrong magic %08x != %08x",
940 		    hdr->magic_cookie, PPTP_MAGIC_COOKIE);
941 		goto bad_packet;
942 	}
943 
944 	/* As there is possibility of state conflicts,
945 	 * ECHO Reply requiries special care.
946 	 */
947 	switch (hdr->control_message_type) {
948 	case PPTP_CTRL_MES_CODE_ECHO_RP:
949 		if (pptp_ctrl_recv_echo_rep(_this, pkt, lpkt) != 0) {
950 			pptp_ctrl_fini(_this);
951 			return 1;
952 		}
953 		return 0;
954 	}
955 
956 	/*
957 	 * State machine
958 	 */
959 	switch (_this->state) {
960 	case PPTP_CTRL_STATE_IDLE:
961 		switch (hdr->control_message_type) {
962 		case PPTP_CTRL_MES_CODE_SCCRQ:
963 			if (pptp_ctrl_recv_SCCRQ(_this, pkt, lpkt) != 0) {
964 				return 0;
965 			}
966 			if (pptp_ctrl_send_SCCRP(_this,
967 			    PPTP_SCCRP_RESULT_SUCCESS, PPTP_ERROR_NONE) != 0) {
968 				return 0;
969 			}
970 			_this->state = PPTP_CTRL_STATE_ESTABLISHED;
971 			return 0;
972 		default:
973 			break;
974 		}
975 		break;
976 	case PPTP_CTRL_STATE_ESTABLISHED:
977 		switch (hdr->control_message_type) {
978 		case PPTP_CTRL_MES_CODE_ECHO_RQ:
979 			pptp_ctrl_process_echo_req(_this, pkt, lpkt);
980 			return 0;
981 		/* dispatch to pptp_call_input() if it is call-related-packet */
982 		case PPTP_CTRL_MES_CODE_SLI:
983 		case PPTP_CTRL_MES_CODE_ICRQ:
984 		case PPTP_CTRL_MES_CODE_ICRP:
985 		case PPTP_CTRL_MES_CODE_OCRQ:
986 		case PPTP_CTRL_MES_CODE_OCRP:
987 		case PPTP_CTRL_MES_CODE_ICCN:
988 		case PPTP_CTRL_MES_CODE_CDN:
989 		case PPTP_CTRL_MES_CODE_CCR:
990 			return pptp_ctrl_call_input(_this,
991 			    hdr->control_message_type, pkt, lpkt);
992 		case PPTP_CTRL_MES_CODE_StopCCRQ:
993 			if (pptp_ctrl_recv_StopCCRQ(_this, pkt, lpkt) != 0) {
994 				pptp_ctrl_stop(_this,
995 				    PPTP_StopCCRQ_REASON_STOP_PROTOCOL);
996 				return 0;
997 			}
998 			if (pptp_ctrl_send_StopCCRP(_this,
999 				PPTP_StopCCRP_RESULT_OK, PPTP_ERROR_NONE)!= 0) {
1000 				return 0;
1001 			}
1002 			pptp_ctrl_fini(_this);
1003 			return 1;
1004 		default:
1005 			break;
1006 		}
1007 	case PPTP_CTRL_STATE_WAIT_STOP_REPLY:
1008 		switch (hdr->control_message_type) {
1009 		case PPTP_CTRL_MES_CODE_StopCCRP:
1010 			pptp_ctrl_recv_StopCCRP(_this, pkt, lpkt);
1011 			pptp_ctrl_fini(_this);
1012 			return 1;
1013 		}
1014 		break;
1015 	case PPTP_CTRL_STATE_WAIT_CTRL_REPLY:
1016 		/* XXX this implementation only support PAC mode */
1017 		break;
1018 	}
1019 	pptp_ctrl_log(_this, LOG_WARNING,
1020 	    "Unhandled control message type=%s(%d)",
1021 	    pptp_ctrl_mes_type_string(hdr->control_message_type),
1022 	    hdr->control_message_type);
1023 	return 0;
1024 
1025 bad_packet:
1026 	pptp_ctrl_log(_this, LOG_ERR, "Received bad packet: %s", errmes);
1027 	pptp_ctrl_stop(_this, PPTP_StopCCRQ_REASON_STOP_PROTOCOL);
1028 
1029 	return 0;
1030 }
1031 
1032 /* receiver PPTP Call related messages */
1033 static int
pptp_ctrl_call_input(pptp_ctrl * _this,int mes_type,u_char * pkt,int lpkt)1034 pptp_ctrl_call_input(pptp_ctrl *_this, int mes_type, u_char *pkt, int lpkt)
1035 {
1036 	int i, call_id, lpkt0;
1037 	pptp_call *call;
1038 	const char *reason;
1039 	u_char *pkt0;
1040 
1041 	pkt0 = pkt;
1042 	lpkt0 = lpkt;
1043 	call_id = -1;
1044 	pkt += sizeof(struct pptp_ctrl_header);
1045 	lpkt -= sizeof(struct pptp_ctrl_header);
1046 	reason = "(no reason)";
1047 
1048 	/* sanity check */
1049 	if (lpkt < 4) {
1050 		reason = "received packet is too short";
1051 		goto badpacket;
1052 	}
1053 	call = NULL;
1054 	call_id = ntohs(*(uint16_t *)pkt);
1055 
1056 	switch (mes_type) {
1057 	case PPTP_CTRL_MES_CODE_SLI:	/* PNS <=> PAC */
1058 		/* only SLI contains Call-ID of this peer */
1059 		for (i = 0; i < slist_length(&_this->call_list); i++) {
1060 			call = slist_get(&_this->call_list, i);
1061 			if (call->id == call_id)
1062 				break;
1063 			call = NULL;
1064 		}
1065 		if (call == NULL) {
1066 			reason = "Call Id is not associated by this control";
1067 			goto badpacket;
1068 		}
1069 		goto call_searched;
1070 	case PPTP_CTRL_MES_CODE_ICRP:	/* PNS => PAC */
1071 		/*
1072 		 * as this implementation never sent ICRQ, this case
1073 		 * should not happen.
1074 		 * But just to make sure, pptp_call.c can handle this
1075 		 * message.
1076 		 */
1077 		/* FALLTHROUGH */
1078 	case PPTP_CTRL_MES_CODE_OCRQ:	/* PNS => PAC */
1079 	case PPTP_CTRL_MES_CODE_CCR:	/* PNS => PAC */
1080 		/* liner-search will be enough */
1081 		for (i = 0; i < slist_length(&_this->call_list); i++) {
1082 			call = slist_get(&_this->call_list, i);
1083 			if (call->peers_call_id == call_id)
1084 				break;
1085 			call = NULL;
1086 		}
1087 		if (call == NULL && mes_type == PPTP_CTRL_MES_CODE_CCR) {
1088 			pptp_ctrl_send_CDN(_this, PPTP_CDN_RESULT_GENRIC_ERROR,
1089 			    PPTP_ERROR_BAD_CALL, 0, NULL);
1090 			goto call_searched;
1091 		}
1092 		if (mes_type == PPTP_CTRL_MES_CODE_OCRQ) {
1093 			/* make new call */
1094 			if (call != NULL) {
1095 				pptp_call_input(call, mes_type, pkt0, lpkt0);
1096 				return 0;
1097 			}
1098 			if ((call = pptp_call_create()) == NULL) {
1099 				pptp_ctrl_log(_this, LOG_ERR,
1100 				    "pptp_call_create() failed: %m");
1101 				goto fail;
1102 			}
1103 			if (pptp_call_init(call, _this) != 0) {
1104 				pptp_ctrl_log(_this, LOG_ERR,
1105 				    "pptp_call_init() failed: %m");
1106 				pptp_call_destroy(call);
1107 				goto fail;
1108 			}
1109 			slist_add(&_this->call_list, call);
1110 		}
1111 call_searched:
1112 		if (call == NULL) {
1113 			reason = "Call Id is not associated by this control";
1114 			goto badpacket;
1115 		}
1116 		pptp_call_input(call, mes_type, pkt0, lpkt0);
1117 		return 0;
1118 	case PPTP_CTRL_MES_CODE_OCRP:	/* PAC => PNS */
1119 	case PPTP_CTRL_MES_CODE_ICRQ:	/* PAC => PNS */
1120 	case PPTP_CTRL_MES_CODE_ICCN:	/* PAC => PNS */
1121 	case PPTP_CTRL_MES_CODE_CDN:	/* PAC => PNS */
1122 		/* don't receive because above messages are only of PNS */
1123 	default:
1124 		break;
1125 	}
1126 	reason = "Message type is unexpected.";
1127 	/* FALLTHROUGH */
1128 badpacket:
1129 	pptp_ctrl_log(_this, LOG_INFO,
1130 	    "Received a bad %s(%d) call_id=%d: %s",
1131 		pptp_ctrl_mes_type_string(mes_type), mes_type, call_id, reason);
1132 	return 0;
1133 fail:
1134 	pptp_ctrl_stop(_this, PPTP_StopCCRQ_REASON_STOP_PROTOCOL);
1135 	return 0;
1136 }
1137 
1138 
1139 /*
1140  * utilities
1141  */
1142 
1143 /* logging with the label of the instance */
1144 static void
pptp_ctrl_log(pptp_ctrl * _this,int prio,const char * fmt,...)1145 pptp_ctrl_log(pptp_ctrl *_this, int prio, const char *fmt, ...)
1146 {
1147 	char logbuf[BUFSIZ];
1148 	va_list ap;
1149 
1150 	va_start(ap, fmt);
1151 #ifdef	PPTPD_MULTIPLE
1152 	snprintf(logbuf, sizeof(logbuf), "pptpd id=%u ctrl=%u %s",
1153 	    _this->pptpd->id, _this->id, fmt);
1154 #else
1155 	snprintf(logbuf, sizeof(logbuf), "pptpd ctrl=%u %s", _this->id, fmt);
1156 #endif
1157 	vlog_printf(prio, logbuf, ap);
1158 	va_end(ap);
1159 }
1160 
1161 static const char *
pptp_ctrl_state_string(int state)1162 pptp_ctrl_state_string(int state)
1163 {
1164 	switch (state) {
1165 	case PPTP_CTRL_STATE_IDLE:
1166 		return "idle";
1167 	case PPTP_CTRL_STATE_WAIT_CTRL_REPLY:
1168 		return "wait-ctrl-reply";
1169 	case PPTP_CTRL_STATE_ESTABLISHED:
1170 		return "established";
1171 	case PPTP_CTRL_STATE_WAIT_STOP_REPLY:
1172 		return "wait-stop-reply";
1173 	}
1174 	return "unknown";
1175 }
1176