xref: /openbsd/usr.sbin/npppd/pptp/pptp_ctrl.c (revision e5dd7070)
1 /*	$OpenBSD: pptp_ctrl.c,v 1.11 2016/04/16 18:32:29 krw 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.11 2016/04/16 18:32:29 krw 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 *
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
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
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
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
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
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 responce. */
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
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
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
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
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
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
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
557 pptp_ctrl_SCCRx_string(struct pptp_scc *scc, u_char *buf, int lbuf)
558 {
559 	char buf1[128], buf2[128], buf3[128];
560 
561 	/* sanity check */
562 	strlcpy(buf1, scc->host_name, sizeof(buf1));
563 	strlcpy(buf2, scc->vendor_string, sizeof(buf2));
564 
565 	if (scc->result_code != 0)
566 		snprintf(buf3, sizeof(buf3), "result=%d error=%d ",
567 		    scc->result_code, scc->error_code);
568 	else
569 		buf3[0] = '\0';
570 
571 	snprintf(buf, lbuf,
572 	    "protocol_version=%d.%d %sframing=%s bearer=%s max_channels=%d "
573 	    "firmware_revision=%d(0x%04x) host_name=\"%s\" "
574 	    "vendor_string=\"%s\"",
575 	    scc->protocol_version >> 8, scc->protocol_version & 0xff, buf3,
576 	    pptp_framing_string(scc->framing_caps),
577 	    pptp_bearer_string(scc->bearer_caps), scc->max_channels,
578 	    scc->firmware_revision, scc->firmware_revision, buf1, buf2);
579 }
580 
581 /* receive Start-Control-Connection-Request */
582 static int
583 pptp_ctrl_recv_SCCRQ(pptp_ctrl *_this, u_char *pkt, int lpkt)
584 {
585 	char logbuf[512];
586 	struct pptp_scc *scc;
587 
588 	/* sanity check */
589 	if (lpkt < sizeof(struct pptp_scc)) {
590 		pptp_ctrl_log(_this, LOG_ERR, "Received bad SCCRQ: packet too "
591 		    "short: %d < %d", lpkt, (int)sizeof(struct pptp_scc));
592 		return 1;
593 	}
594 	scc = (struct pptp_scc *)pkt;
595 
596 	scc->protocol_version = ntohs(scc->protocol_version);
597 	scc->framing_caps = htonl(scc->framing_caps);
598 	scc->bearer_caps = htonl(scc->bearer_caps);
599 	scc->max_channels = htons(scc->max_channels);
600 	scc->firmware_revision = htons(scc->firmware_revision);
601 
602 	/* check protocol version */
603 	if (scc->protocol_version != PPTP_RFC_2637_VERSION) {
604 		pptp_ctrl_log(_this, LOG_ERR, "Received bad SCCRQ: "
605 		    "unknown protocol version %d", scc->protocol_version);
606 		return 1;
607 	}
608 
609 	pptp_ctrl_SCCRx_string(scc, logbuf, sizeof(logbuf));
610 	pptp_ctrl_log(_this, LOG_INFO, "RecvSCCRQ %s", logbuf);
611 
612 	return 0;
613 }
614 
615 /* Receive Stop-Control-Connection-Reply */
616 static int
617 pptp_ctrl_recv_StopCCRP(pptp_ctrl *_this, u_char *pkt, int lpkt)
618 {
619 	struct pptp_stop_ccrp *stop_ccrp;
620 
621 	if (lpkt < sizeof(struct pptp_stop_ccrp)) {
622 		pptp_ctrl_log(_this, LOG_ERR, "Received bad StopCCRP: packet "
623 		    "too short: %d < %d", lpkt,
624 		    (int)sizeof(struct pptp_stop_ccrp));
625 		return 1;
626 	}
627 	stop_ccrp = (struct pptp_stop_ccrp *)pkt;
628 
629 	pptp_ctrl_log(_this, LOG_INFO, "RecvStopCCRP reason=%s(%u)",
630 	    pptp_StopCCRP_result_string(stop_ccrp->result), stop_ccrp->result);
631 
632 	return 0;
633 }
634 
635 static int
636 pptp_ctrl_send_StopCCRQ(pptp_ctrl *_this, int reason)
637 {
638 	int lpkt;
639 	struct pptp_stop_ccrq *stop_ccrq;
640 
641 	stop_ccrq = bytebuffer_pointer(_this->send_buf);
642 	lpkt = bytebuffer_remaining(_this->send_buf);
643 	if (lpkt < sizeof(struct pptp_stop_ccrq)) {
644 		pptp_ctrl_log(_this, LOG_ERR,
645 		    "SendCCRP failed: No buffer space available");
646 		return -1;
647 	}
648 	memset(stop_ccrq, 0, sizeof(struct pptp_stop_ccrq));
649 
650 	pptp_init_header(&stop_ccrq->header, sizeof(struct pptp_stop_ccrq),
651 	    PPTP_CTRL_MES_CODE_StopCCRQ);
652 
653 	stop_ccrq->reason = reason;
654 
655 	pptp_ctrl_log(_this, LOG_INFO, "SendStopCCRQ reason=%s(%u)",
656 	    pptp_StopCCRQ_reason_string(stop_ccrq->reason), stop_ccrq->reason);
657 
658 	pptp_ctrl_output(_this, NULL, sizeof(struct pptp_stop_ccrq));
659 
660 	return 0;
661 }
662 
663 /* Receive Stop-Control-Connection-Request */
664 static int
665 pptp_ctrl_recv_StopCCRQ(pptp_ctrl *_this, u_char *pkt, int lpkt)
666 {
667 	struct pptp_stop_ccrq *stop_ccrq;
668 
669 	if (lpkt < sizeof(struct pptp_stop_ccrq)) {
670 		pptp_ctrl_log(_this, LOG_ERR, "Received bad StopCCRQ: packet "
671 		    "too short: %d < %d", lpkt,
672 		    (int)sizeof(struct pptp_stop_ccrq));
673 		return 1;
674 	}
675 	stop_ccrq = (struct pptp_stop_ccrq *)pkt;
676 
677 	pptp_ctrl_log(_this, LOG_INFO, "RecvStopCCRQ reason=%s(%u)",
678 	    pptp_StopCCRQ_reason_string(stop_ccrq->reason), stop_ccrq->reason);
679 
680 	return 0;
681 }
682 
683 /* Send Stop-Control-Connection-Reply */
684 static int
685 pptp_ctrl_send_StopCCRP(pptp_ctrl *_this, int result, int error)
686 {
687 	int lpkt;
688 	struct pptp_stop_ccrp *stop_ccrp;
689 
690 	stop_ccrp = bytebuffer_pointer(_this->send_buf);
691 
692 	lpkt = bytebuffer_remaining(_this->send_buf);
693 	if (lpkt < sizeof(struct pptp_stop_ccrp)) {
694 		pptp_ctrl_log(_this, LOG_ERR,
695 		    "SendCCRQ failed: No buffer space available");
696 		return -1;
697 	}
698 	memset(stop_ccrp, 0, sizeof(struct pptp_stop_ccrp));
699 
700 	pptp_init_header(&stop_ccrp->header, sizeof(struct pptp_stop_ccrp),
701 	    PPTP_CTRL_MES_CODE_StopCCRP);
702 
703 	stop_ccrp->result = result;
704 	stop_ccrp->error = error;
705 
706 	pptp_ctrl_log(_this, LOG_INFO,
707 	    "SendStopCCRP result=%s(%u) error=%s(%u)",
708 	    pptp_StopCCRP_result_string(stop_ccrp->result), stop_ccrp->result,
709 	    pptp_general_error_string(stop_ccrp->error), stop_ccrp->error);
710 
711 	pptp_ctrl_output(_this, NULL, sizeof(struct pptp_stop_ccrp));
712 
713 	return 0;
714 }
715 
716 /* Send Start-Control-Connection-Reply */
717 static int
718 pptp_ctrl_send_SCCRP(pptp_ctrl *_this, int result, int error)
719 {
720 	int lpkt;
721 	struct pptp_scc *scc;
722 	char logbuf[512];
723 	const char *val;
724 
725 	scc = bytebuffer_pointer(_this->send_buf);
726 	lpkt = bytebuffer_remaining(_this->send_buf);
727 	if (lpkt < sizeof(struct pptp_scc)) {
728 		pptp_ctrl_log(_this, LOG_ERR,
729 		    "SendSCCRP failed: No buffer space available");
730 		return -1;
731 	}
732 	memset(scc, 0, sizeof(struct pptp_scc));
733 
734 	pptp_init_header(&scc->header, sizeof(struct pptp_scc),
735 	    PPTP_CTRL_MES_CODE_SCCRP);
736 
737 	scc->protocol_version = PPTP_RFC_2637_VERSION;
738 	scc->result_code = result;
739 	scc->error_code = error;
740 
741 	/* XXX only support sync frames */
742 	scc->framing_caps = PPTP_CTRL_FRAMING_SYNC;
743 	scc->bearer_caps = PPTP_CTRL_BEARER_DIGITAL;
744 
745 	scc->max_channels = 4;		/* XXX */
746 	scc->firmware_revision = MAJOR_VERSION << 8 | MINOR_VERSION;
747 
748 	/* this implementation only support these strings up to
749 	 * 63 character */
750 	/* host name */
751 
752 	if ((val = PPTP_CTRL_CONF(_this)->hostname) == NULL)
753 		val = "";
754 	strlcpy(scc->host_name, val, sizeof(scc->host_name));
755 
756 	/* vender name */
757 	if (PPTP_CTRL_CONF(_this)->vendor_name == NULL)
758 		val = PPTPD_DEFAULT_VENDOR_NAME;
759 	strlcpy(scc->vendor_string, val, sizeof(scc->vendor_string));
760 
761 	pptp_ctrl_SCCRx_string(scc, logbuf, sizeof(logbuf));
762 	pptp_ctrl_log(_this, LOG_INFO, "SendSCCRP %s", logbuf);
763 
764 	scc->protocol_version = htons(scc->protocol_version);
765 	scc->framing_caps = htonl(scc->framing_caps);
766 	scc->bearer_caps = htonl(scc->bearer_caps);
767 	scc->max_channels = htons(scc->max_channels);
768 	scc->firmware_revision = htons(scc->firmware_revision);
769 
770 	pptp_ctrl_output(_this, NULL, sizeof(struct pptp_scc));
771 
772 	return 0;
773 }
774 
775 /* receive ECHO and reply */
776 static void
777 pptp_ctrl_process_echo_req(pptp_ctrl *_this, u_char *pkt, int lpkt)
778 {
779 	struct pptp_echo_rq *echo_rq;
780 	struct pptp_echo_rp *echo_rp;
781 
782 	if (lpkt < sizeof(struct pptp_echo_rq)) {
783 		pptp_ctrl_log(_this, LOG_ERR, "Received bad EchoReq: packet "
784 		    "too short: %d < %d", lpkt,
785 		    (int)sizeof(struct pptp_echo_rq));
786 		return;
787 	}
788 	echo_rq = (struct pptp_echo_rq *)pkt;
789 
790 	PPTP_CTRL_DBG((_this, LOG_DEBUG, "RecvEchoReq"));
791 
792 	echo_rp = bytebuffer_pointer(_this->send_buf);
793 	lpkt = bytebuffer_remaining(_this->send_buf);
794 	if (echo_rp == NULL || lpkt < sizeof(struct pptp_echo_rp)) {
795 		pptp_ctrl_log(_this, LOG_ERR,
796 		    "Failed to send EchoReq: No buffer space available");
797 		return;
798 	}
799 	memset(echo_rp, 0, sizeof(struct pptp_echo_rp));
800 
801 	pptp_init_header(&echo_rp->header, sizeof(struct pptp_echo_rp),
802 	    PPTP_CTRL_MES_CODE_ECHO_RP);
803 
804 	echo_rp->identifier = echo_rq->identifier;
805 	echo_rp->result_code = PPTP_ECHO_RP_RESULT_OK;
806 	echo_rp->error_code = PPTP_ERROR_NONE;
807 	echo_rp->reserved1 = htons(0);
808 
809 	pptp_ctrl_output(_this, NULL, sizeof(struct pptp_echo_rp));
810 	PPTP_CTRL_DBG((_this, LOG_DEBUG, "SendEchoReply"));
811 }
812 
813 /* receiver Echo-Reply */
814 static int
815 pptp_ctrl_recv_echo_rep(pptp_ctrl *_this, u_char *pkt, int lpkt)
816 {
817 	struct pptp_echo_rp *echo_rp;
818 
819 	if (lpkt < sizeof(struct pptp_echo_rp)) {
820 		pptp_ctrl_log(_this, LOG_ERR, "Received bad EchoReq: packet "
821 		    "too short: %d < %d", lpkt,
822 		    (int)sizeof(struct pptp_echo_rp));
823 		return 1;
824 	}
825 	echo_rp = (struct pptp_echo_rp *)pkt;
826 
827 	if (echo_rp->result_code != PPTP_ECHO_RP_RESULT_OK) {
828 		pptp_ctrl_log(_this, LOG_ERR, "Received negative EchoReply: %s",
829 		    pptp_general_error_string(echo_rp->error_code));
830 		return 1;
831 	}
832 	if (_this->echo_seq != ntohl(echo_rp->identifier)) {
833 		pptp_ctrl_log(_this, LOG_ERR, "Received bad EchoReply: "
834 		    "Identifier mismatch sent=%u recv=%u",
835 		    _this->echo_seq , ntohl(echo_rp->identifier));
836 		return 1;
837 	}
838 	PPTP_CTRL_DBG((_this, LOG_DEBUG, "RecvEchoReply"));
839 	return 0;
840 }
841 
842 /* send Echo-Request */
843 static void
844 pptp_ctrl_send_echo_req(pptp_ctrl *_this)
845 {
846 	int lpkt;
847 	struct pptp_echo_rq *echo_rq;
848 
849 	echo_rq = (struct pptp_echo_rq *)bytebuffer_pointer(_this->send_buf);
850 	lpkt = bytebuffer_remaining(_this->send_buf);
851 	if (echo_rq == NULL || lpkt < sizeof(struct pptp_echo_rq)) {
852 		pptp_ctrl_log(_this, LOG_ERR,
853 		    "SendEchoReq failed: No buffer space available");
854 		return;
855 	}
856 	memset(echo_rq, 0, sizeof(struct pptp_echo_rq));
857 
858 	pptp_init_header(&echo_rq->header, sizeof(struct pptp_echo_rq),
859 	    PPTP_CTRL_MES_CODE_ECHO_RQ);
860 
861 	echo_rq->identifier = htonl(_this->echo_seq);
862 
863 	pptp_ctrl_output(_this, NULL, sizeof(struct pptp_echo_rq));
864 	PPTP_CTRL_DBG((_this, LOG_DEBUG, "SendEchoReq"));
865 }
866 
867 /* send Call-Disconnect-Notify */
868 static void
869 pptp_ctrl_send_CDN(pptp_ctrl *_this, int result, int error, int cause,
870     const char *statistics)
871 {
872 	int lpkt;
873 	struct pptp_cdn *cdn;
874 
875 	cdn = bytebuffer_pointer(_this->send_buf);
876 	lpkt = bytebuffer_remaining(_this->send_buf);
877 	if (lpkt < sizeof(struct pptp_cdn)) {
878 		pptp_ctrl_log(_this, LOG_ERR,
879 		    "SendCCR failed: No buffer space available");
880 		return;
881 	}
882 	memset(cdn, 0, sizeof(struct pptp_cdn));
883 
884 	pptp_init_header(&cdn->header, sizeof(struct pptp_cdn),
885 	    PPTP_CTRL_MES_CODE_CDN);
886 
887 	cdn->call_id = _this->id;
888 	cdn->result_code = result;
889 	cdn->error_code = error;
890 	cdn->cause_code = cause;
891 	if (statistics != NULL)
892 		strlcpy(cdn->statistics, statistics, sizeof(cdn->statistics));
893 
894 	cdn->call_id = htons(cdn->call_id);
895 	cdn->cause_code = htons(cdn->cause_code);
896 
897 	pptp_ctrl_output(_this, NULL, sizeof(struct pptp_cdn));
898 }
899 
900 /* receive Control-packet */
901 static int
902 pptp_ctrl_input(pptp_ctrl *_this, u_char *pkt, int lpkt)
903 {
904 	char errmes[256];
905 	time_t curr_time;
906 	struct pptp_ctrl_header *hdr;
907 
908 	PPTP_CTRL_ASSERT(lpkt >= sizeof(struct pptp_ctrl_header));
909 
910 	curr_time = get_monosec();
911 	hdr = (struct pptp_ctrl_header *)pkt;
912 
913 	hdr->length = ntohs(hdr->length);
914 	hdr->pptp_message_type  = ntohs(hdr->pptp_message_type);
915 	hdr->magic_cookie  = ntohl(hdr->magic_cookie);
916 	hdr->control_message_type = ntohs(hdr->control_message_type);
917 	hdr->reserved0 = ntohs(hdr->reserved0);
918 
919 	/* sanity check */
920 	PPTP_CTRL_ASSERT(hdr->length <= lpkt);
921 
922 	_this->last_rcv_ctrl = curr_time;
923 
924 	if (PPTP_CTRL_CONF(_this)->ctrl_in_pktdump != 0) {
925 		pptp_ctrl_log(_this, LOG_DEBUG,
926 		    "PPTP Control input packet dump: mestype=%s(%d)",
927 		    pptp_ctrl_mes_type_string(hdr->control_message_type),
928 		    hdr->control_message_type);
929 		show_hd(debug_get_debugfp(), pkt, lpkt);
930 	}
931 
932 	/* inspect packet body */
933 	/* message type */
934 	if (hdr->pptp_message_type != PPTP_MES_TYPE_CTRL) {
935 		snprintf(errmes, sizeof(errmes), "unknown message type %d",
936 		    hdr->pptp_message_type);
937 		goto bad_packet;
938 	}
939 	/* magic cookie */
940 	if (hdr->magic_cookie != PPTP_MAGIC_COOKIE) {
941 		snprintf(errmes, sizeof(errmes), "wrong magic %08x != %08x",
942 		    hdr->magic_cookie, PPTP_MAGIC_COOKIE);
943 		goto bad_packet;
944 	}
945 
946 	/* As there is possibility of state conflicts,
947 	 * ECHO Reply requiries special care.
948 	 */
949 	switch (hdr->control_message_type) {
950 	case PPTP_CTRL_MES_CODE_ECHO_RP:
951 		if (pptp_ctrl_recv_echo_rep(_this, pkt, lpkt) != 0) {
952 			pptp_ctrl_fini(_this);
953 			return 1;
954 		}
955 		return 0;
956 	}
957 
958 	/*
959 	 * State machine
960 	 */
961 	switch (_this->state) {
962 	case PPTP_CTRL_STATE_IDLE:
963 		switch (hdr->control_message_type) {
964 		case PPTP_CTRL_MES_CODE_SCCRQ:
965 			if (pptp_ctrl_recv_SCCRQ(_this, pkt, lpkt) != 0) {
966 				return 0;
967 			}
968 			if (pptp_ctrl_send_SCCRP(_this,
969 			    PPTP_SCCRP_RESULT_SUCCESS, PPTP_ERROR_NONE) != 0) {
970 				return 0;
971 			}
972 			_this->state = PPTP_CTRL_STATE_ESTABLISHED;
973 			return 0;
974 		default:
975 			break;
976 		}
977 		break;
978 	case PPTP_CTRL_STATE_ESTABLISHED:
979 		switch (hdr->control_message_type) {
980 		case PPTP_CTRL_MES_CODE_ECHO_RQ:
981 			pptp_ctrl_process_echo_req(_this, pkt, lpkt);
982 			return 0;
983 		/* dispatch to pptp_call_input() if it is call-related-packet */
984 		case PPTP_CTRL_MES_CODE_SLI:
985 		case PPTP_CTRL_MES_CODE_ICRQ:
986 		case PPTP_CTRL_MES_CODE_ICRP:
987 		case PPTP_CTRL_MES_CODE_OCRQ:
988 		case PPTP_CTRL_MES_CODE_OCRP:
989 		case PPTP_CTRL_MES_CODE_ICCN:
990 		case PPTP_CTRL_MES_CODE_CDN:
991 		case PPTP_CTRL_MES_CODE_CCR:
992 			return pptp_ctrl_call_input(_this,
993 			    hdr->control_message_type, pkt, lpkt);
994 		case PPTP_CTRL_MES_CODE_StopCCRQ:
995 			if (pptp_ctrl_recv_StopCCRQ(_this, pkt, lpkt) != 0) {
996 				pptp_ctrl_stop(_this,
997 				    PPTP_StopCCRQ_REASON_STOP_PROTOCOL);
998 				return 0;
999 			}
1000 			if (pptp_ctrl_send_StopCCRP(_this,
1001 				PPTP_StopCCRP_RESULT_OK, PPTP_ERROR_NONE)!= 0) {
1002 				return 0;
1003 			}
1004 			pptp_ctrl_fini(_this);
1005 			return 1;
1006 		default:
1007 			break;
1008 		}
1009 	case PPTP_CTRL_STATE_WAIT_STOP_REPLY:
1010 		switch (hdr->control_message_type) {
1011 		case PPTP_CTRL_MES_CODE_StopCCRP:
1012 			pptp_ctrl_recv_StopCCRP(_this, pkt, lpkt);
1013 			pptp_ctrl_fini(_this);
1014 			return 1;
1015 		}
1016 		break;
1017 	case PPTP_CTRL_STATE_WAIT_CTRL_REPLY:
1018 		/* XXX this implementation only support PAC mode */
1019 		break;
1020 	}
1021 	pptp_ctrl_log(_this, LOG_WARNING,
1022 	    "Unhandled control message type=%s(%d)",
1023 	    pptp_ctrl_mes_type_string(hdr->control_message_type),
1024 	    hdr->control_message_type);
1025 	return 0;
1026 
1027 bad_packet:
1028 	pptp_ctrl_log(_this, LOG_ERR, "Received bad packet: %s", errmes);
1029 	pptp_ctrl_stop(_this, PPTP_StopCCRQ_REASON_STOP_PROTOCOL);
1030 
1031 	return 0;
1032 }
1033 
1034 /* receiver PPTP Call related messages */
1035 static int
1036 pptp_ctrl_call_input(pptp_ctrl *_this, int mes_type, u_char *pkt, int lpkt)
1037 {
1038 	int i, call_id, lpkt0;
1039 	pptp_call *call;
1040 	const char *reason;
1041 	u_char *pkt0;
1042 
1043 	pkt0 = pkt;
1044 	lpkt0 = lpkt;
1045 	call_id = -1;
1046 	pkt += sizeof(struct pptp_ctrl_header);
1047 	lpkt -= sizeof(struct pptp_ctrl_header);
1048 	reason = "(no reason)";
1049 
1050 	/* sanity check */
1051 	if (lpkt < 4) {
1052 		reason = "received packet is too short";
1053 		goto badpacket;
1054 	}
1055 	call = NULL;
1056 	call_id = ntohs(*(uint16_t *)pkt);
1057 
1058 	switch (mes_type) {
1059 	case PPTP_CTRL_MES_CODE_SLI:	/* PNS <=> PAC */
1060 		/* only SLI contains Call-ID of this peer */
1061 		for (i = 0; i < slist_length(&_this->call_list); i++) {
1062 			call = slist_get(&_this->call_list, i);
1063 			if (call->id == call_id)
1064 				break;
1065 			call = NULL;
1066 		}
1067 		if (call == NULL) {
1068 			reason = "Call Id is not associated by this control";
1069 			goto badpacket;
1070 		}
1071 		goto call_searched;
1072 	case PPTP_CTRL_MES_CODE_ICRP:	/* PNS => PAC */
1073 		/*
1074 		 * as this implementation never sent ICRQ, this case
1075 		 * should not happen.
1076 		 * But just to make sure, pptp_call.c can handle this
1077 		 * message.
1078 		 */
1079 		/* FALLTHROUGH */
1080 	case PPTP_CTRL_MES_CODE_OCRQ:	/* PNS => PAC */
1081 	case PPTP_CTRL_MES_CODE_CCR:	/* PNS => PAC */
1082 		/* liner-search will be enough */
1083 		for (i = 0; i < slist_length(&_this->call_list); i++) {
1084 			call = slist_get(&_this->call_list, i);
1085 			if (call->peers_call_id == call_id)
1086 				break;
1087 			call = NULL;
1088 		}
1089 		if (call == NULL && mes_type == PPTP_CTRL_MES_CODE_CCR) {
1090 			pptp_ctrl_send_CDN(_this, PPTP_CDN_RESULT_GENRIC_ERROR,
1091 			    PPTP_ERROR_BAD_CALL, 0, NULL);
1092 			goto call_searched;
1093 		}
1094 		if (mes_type == PPTP_CTRL_MES_CODE_OCRQ) {
1095 			/* make new call */
1096 			if (call != NULL) {
1097 				pptp_call_input(call, mes_type, pkt0, lpkt0);
1098 				return 0;
1099 			}
1100 			if ((call = pptp_call_create()) == NULL) {
1101 				pptp_ctrl_log(_this, LOG_ERR,
1102 				    "pptp_call_create() failed: %m");
1103 				goto fail;
1104 			}
1105 			if (pptp_call_init(call, _this) != 0) {
1106 				pptp_ctrl_log(_this, LOG_ERR,
1107 				    "pptp_call_init() failed: %m");
1108 				pptp_call_destroy(call);
1109 				goto fail;
1110 			}
1111 			slist_add(&_this->call_list, call);
1112 		}
1113 call_searched:
1114 		if (call == NULL) {
1115 			reason = "Call Id is not associated by this control";
1116 			goto badpacket;
1117 		}
1118 		pptp_call_input(call, mes_type, pkt0, lpkt0);
1119 		return 0;
1120 	case PPTP_CTRL_MES_CODE_OCRP:	/* PAC => PNS */
1121 	case PPTP_CTRL_MES_CODE_ICRQ:	/* PAC => PNS */
1122 	case PPTP_CTRL_MES_CODE_ICCN:	/* PAC => PNS */
1123 	case PPTP_CTRL_MES_CODE_CDN:	/* PAC => PNS */
1124 		/* don't receive because above messages are only of PNS */
1125 	default:
1126 		break;
1127 	}
1128 	reason = "Message type is unexpected.";
1129 	/* FALLTHROUGH */
1130 badpacket:
1131 	pptp_ctrl_log(_this, LOG_INFO,
1132 	    "Received a bad %s(%d) call_id=%d: %s",
1133 		pptp_ctrl_mes_type_string(mes_type), mes_type, call_id, reason);
1134 	return 0;
1135 fail:
1136 	pptp_ctrl_stop(_this, PPTP_StopCCRQ_REASON_STOP_PROTOCOL);
1137 	return 0;
1138 }
1139 
1140 
1141 /*
1142  * utilities
1143  */
1144 
1145 /* logging with the label of the instance */
1146 static void
1147 pptp_ctrl_log(pptp_ctrl *_this, int prio, const char *fmt, ...)
1148 {
1149 	char logbuf[BUFSIZ];
1150 	va_list ap;
1151 
1152 	va_start(ap, fmt);
1153 #ifdef	PPTPD_MULTIPLE
1154 	snprintf(logbuf, sizeof(logbuf), "pptpd id=%u ctrl=%u %s",
1155 	    _this->pptpd->id, _this->id, fmt);
1156 #else
1157 	snprintf(logbuf, sizeof(logbuf), "pptpd ctrl=%u %s", _this->id, fmt);
1158 #endif
1159 	vlog_printf(prio, logbuf, ap);
1160 	va_end(ap);
1161 }
1162 
1163 static const char *
1164 pptp_ctrl_state_string(int state)
1165 {
1166 	switch (state) {
1167 	case PPTP_CTRL_STATE_IDLE:
1168 		return "idle";
1169 	case PPTP_CTRL_STATE_WAIT_CTRL_REPLY:
1170 		return "wait-ctrl-reply";
1171 	case PPTP_CTRL_STATE_ESTABLISHED:
1172 		return "established";
1173 	case PPTP_CTRL_STATE_WAIT_STOP_REPLY:
1174 		return "wait-stop-reply";
1175 	}
1176 	return "unknown";
1177 }
1178