xref: /openbsd/usr.sbin/npppd/pptp/pptp_ctrl.c (revision 898184e3)
1 /*	$OpenBSD: pptp_ctrl.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $	*/
2 
3 /*-
4  * Copyright (c) 2009 Internet Initiative Japan Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 /**@file
29  * PPTP(RFC 2637) control connection implementation.
30  * currently it only support PAC part
31  */
32 /* $Id: pptp_ctrl.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $ */
33 #include <sys/types.h>
34 #include <sys/param.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <stdio.h>
38 #include <stdarg.h>
39 #include <stdlib.h>
40 #include <netdb.h>
41 #include <unistd.h>
42 #include <syslog.h>
43 #include <time.h>
44 #include <fcntl.h>
45 #include <errno.h>
46 #include <string.h>
47 #include <event.h>
48 
49 #include "bytebuf.h"
50 #include "debugutil.h"
51 #include "hash.h"
52 #include "slist.h"
53 #include "time_utils.h"
54 
55 #include "version.h"
56 
57 #include "pptp.h"
58 #include "pptp_local.h"
59 #include "pptp_subr.h"
60 
61 /* periods of pptp_ctrl_timeout */
62 #define PPTP_CTRL_TIMEOUT_IVAL_SEC	2
63 
64 #ifdef	PPTP_CTRL_DEBUG
65 #define	PPTP_CTRL_ASSERT(x)	ASSERT(x)
66 #define	PPTP_CTRL_DBG(x)	pptp_ctrl_log x
67 #else
68 #define	PPTP_CTRL_ASSERT(x)
69 #define	PPTP_CTRL_DBG(x)
70 #endif
71 
72 static unsigned pptp_ctrl_seqno = 0;
73 
74 static void  pptp_ctrl_log (pptp_ctrl *, int, const char *, ...) __printflike(3,4);
75 static void        pptp_ctrl_timeout (int, short, void *);
76 static void        pptp_ctrl_reset_timeout (pptp_ctrl *);
77 static void        pptp_ctrl_io_event (int, short, void *);
78 static void        pptp_ctrl_set_io_event (pptp_ctrl *);
79 static int         pptp_ctrl_output_flush (pptp_ctrl *);
80 static void        pptp_ctrl_SCCRx_string (struct pptp_scc *, u_char *, int);
81 static int         pptp_ctrl_recv_SCCRQ (pptp_ctrl *, u_char *, int);
82 static int         pptp_ctrl_recv_StopCCRP (pptp_ctrl *, u_char *, int);
83 static int         pptp_ctrl_send_StopCCRQ (pptp_ctrl *, int);
84 static int         pptp_ctrl_recv_StopCCRQ (pptp_ctrl *, u_char *, int);
85 static int         pptp_ctrl_send_StopCCRP (pptp_ctrl *, int, int);
86 static int         pptp_ctrl_send_SCCRP (pptp_ctrl *, int, int);
87 static void        pptp_ctrl_send_CDN (pptp_ctrl *, int, int, int, const char *);
88 static void        pptp_ctrl_process_echo_req (pptp_ctrl *, u_char *, int);
89 static int         pptp_ctrl_recv_echo_rep (pptp_ctrl *, u_char *, int);
90 static void        pptp_ctrl_send_echo_req (pptp_ctrl *);
91 static int         pptp_ctrl_input (pptp_ctrl *, u_char *, int);
92 static int         pptp_ctrl_call_input (pptp_ctrl *, int, u_char *, int);
93 static const char  *pptp_ctrl_state_string (int);
94 static void        pptp_ctrl_fini(pptp_ctrl *);
95 
96 /*
97  * pptp_ctrl instance operation functions
98  */
99 pptp_ctrl *
100 pptp_ctrl_create(void)
101 {
102 	pptp_ctrl *_this;
103 
104 	if ((_this = malloc(sizeof(pptp_ctrl))) == NULL)
105 		return NULL;
106 
107 	return _this;
108 }
109 
110 int
111 pptp_ctrl_init(pptp_ctrl *_this)
112 {
113 	time_t curr_time;
114 
115 	PPTP_CTRL_ASSERT(_this != NULL);
116 	curr_time = get_monosec();
117 	memset(_this, 0, sizeof(pptp_ctrl));
118 	_this->id = pptp_ctrl_seqno++;
119 	_this->sock = -1;
120 
121 	if ((_this->recv_buf = bytebuffer_create(PPTP_BUFSIZ)) == NULL) {
122 		pptp_ctrl_log(_this, LOG_ERR, "bytebuffer_create() failed at "
123 		    "%s(): %m", __func__);
124 		goto fail;
125 	}
126 	if ((_this->send_buf = bytebuffer_create(PPTP_BUFSIZ)) == NULL) {
127 		pptp_ctrl_log(_this, LOG_ERR, "bytebuffer_create() failed at "
128 		    "%s(): %m", __func__);
129 		goto fail;
130 	}
131 	_this->last_rcv_ctrl = curr_time;
132 	_this->last_snd_ctrl = curr_time;
133 	_this->echo_seq = (random() << 16 )| (random() & 0xffff);
134 	_this->echo_interval = PPTP_CTRL_DEFAULT_ECHO_INTERVAL;
135 	_this->echo_timeout = PPTP_CTRL_DEFAULT_ECHO_TIMEOUT;
136 	slist_init(&_this->call_list);
137 	evtimer_set(&_this->ev_timer, pptp_ctrl_timeout, _this);
138 
139 	return 0;
140 fail:
141 	return 1;
142 }
143 
144 int
145 pptp_ctrl_start(pptp_ctrl *_this)
146 {
147 	int ival;
148 	char hbuf0[NI_MAXHOST], sbuf0[NI_MAXSERV];
149 	char hbuf1[NI_MAXHOST], sbuf1[NI_MAXSERV];
150 	struct sockaddr_storage sock;
151 	socklen_t socklen;
152 
153 	PPTP_CTRL_ASSERT(_this != NULL);
154 	PPTP_CTRL_ASSERT(_this->sock >= 0);
155 
156 	/* convert address to strings for logging */
157 	strlcpy(hbuf0, "<unknown>", sizeof(hbuf0));
158 	strlcpy(sbuf0, "<unknown>", sizeof(sbuf0));
159 	strlcpy(hbuf1, "<unknown>", sizeof(hbuf1));
160 	strlcpy(sbuf1, "<unknown>", sizeof(sbuf1));
161 	if (getnameinfo((struct sockaddr *)&_this->peer, _this->peer.ss_len,
162 	    hbuf0, sizeof(hbuf0), sbuf0, sizeof(sbuf0),
163 	    NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
164 		pptp_ctrl_log(_this, LOG_ERR,
165 		    "getnameinfo() failed at %s(): %m", __func__);
166 	}
167 	socklen = sizeof(sock);
168 	if (getsockname(_this->sock, (struct sockaddr *)&sock, &socklen) != 0) {
169 		pptp_ctrl_log(_this, LOG_ERR,
170 		    "getsockname() failed at %s(): %m", __func__);
171 		goto fail;
172 	}
173 	if (getnameinfo((struct sockaddr *)&sock, sock.ss_len, hbuf1,
174 	    sizeof(hbuf1), sbuf1, sizeof(sbuf1),
175 	    NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
176 		pptp_ctrl_log(_this, LOG_ERR,
177 		    "getnameinfo() failed at %s(): %m", __func__);
178 	}
179 	pptp_ctrl_log(_this, LOG_INFO, "Starting peer=%s:%s/tcp "
180 	    "sock=%s:%s/tcp", hbuf0, sbuf0, hbuf1, sbuf1);
181 
182 	if ((ival = fcntl(_this->sock, F_GETFL, 0)) < 0) {
183 		pptp_ctrl_log(_this, LOG_ERR,
184 		    "fcntl(F_GET_FL) failed at %s(): %m", __func__);
185 		goto fail;
186 	} else if (fcntl(_this->sock, F_SETFL, ival | O_NONBLOCK) < 0) {
187 		pptp_ctrl_log(_this, LOG_ERR,
188 		    "fcntl(F_SET_FL) failed at %s(): %m", __func__);
189 		goto fail;
190 	}
191 	pptp_ctrl_set_io_event(_this);
192 	pptp_ctrl_reset_timeout(_this);
193 
194 	return 0;
195 fail:
196 	return 1;
197 }
198 
199 /* Timer */
200 static void
201 pptp_ctrl_timeout(int fd, short event, void *ctx)
202 {
203 	int i;
204 	pptp_call *call;
205 	pptp_ctrl *_this;
206 	time_t last, curr_time;
207 
208 	_this = ctx;
209 	curr_time = get_monosec();
210 
211 	PPTP_CTRL_DBG((_this, DEBUG_LEVEL_3, "enter %s()", __func__));
212 	/* clean up call */
213 	i = 0;
214 	while (i < slist_length(&_this->call_list)) {
215 		call = slist_get(&_this->call_list, i);
216 		if (call->state == PPTP_CALL_STATE_CLEANUP_WAIT &&
217 		    curr_time - call->last_io > PPTP_CALL_CLEANUP_WAIT_TIME) {
218 			pptp_call_stop(call);
219 			pptp_call_destroy(call);
220 			slist_remove(&_this->call_list, i);
221 		} else
222 			i++;
223 	}
224 
225 	/* State machine: Timeout */
226 	switch (_this->state) {
227 	default:
228 	case PPTP_CTRL_STATE_WAIT_CTRL_REPLY:
229 	case PPTP_CTRL_STATE_IDLE:
230 		if (curr_time - _this->last_rcv_ctrl > PPTPD_IDLE_TIMEOUT) {
231 			pptp_ctrl_log(_this, LOG_ERR,
232 			    "Timeout in state %s",
233 			    pptp_ctrl_state_string(_this->state));
234 			pptp_ctrl_fini(_this);
235 			return;
236 		}
237 		break;
238 	case PPTP_CTRL_STATE_ESTABLISHED:
239 		last = MAX(_this->last_rcv_ctrl, _this->last_snd_ctrl);
240 
241 		if (curr_time - _this->last_rcv_ctrl
242 			    >= _this->echo_interval + _this->echo_timeout) {
243 			pptp_ctrl_log(_this, LOG_INFO,
244 			    "Timeout waiting for echo reply");
245 			pptp_ctrl_fini(_this);
246 			return;
247 		}
248 		if (curr_time - last >= _this->echo_interval) {
249 			PPTP_CTRL_DBG((_this, LOG_DEBUG, "Echo"));
250 			_this->echo_seq++;
251 			pptp_ctrl_send_echo_req(_this);
252 		}
253 		break;
254 	case PPTP_CTRL_STATE_WAIT_STOP_REPLY:
255 		if (curr_time - _this->last_snd_ctrl >
256 		    PPTP_CTRL_StopCCRP_WAIT_TIME) {
257 			pptp_ctrl_log(_this, LOG_WARNING,
258 			    "Timeout waiting for StopCCRP");
259 			pptp_ctrl_fini(_this);
260 			return;
261 		}
262 		break;
263 	case PPTP_CTRL_STATE_DISPOSING:
264 		pptp_ctrl_fini(_this);
265 		return;
266 	}
267 	pptp_ctrl_reset_timeout(_this);
268 }
269 
270 static void
271 pptp_ctrl_reset_timeout(pptp_ctrl *_this)
272 {
273 	struct timeval tv;
274 
275 	switch (_this->state) {
276 	case PPTP_CTRL_STATE_DISPOSING:
277 		/* call back immediately */
278 		timerclear(&tv);
279 		break;
280 	default:
281 		tv.tv_sec = PPTP_CTRL_TIMEOUT_IVAL_SEC;
282 		tv.tv_usec = 0;
283 		break;
284 	}
285 	evtimer_add(&_this->ev_timer, &tv);
286 }
287 
288 /**
289  * Terminate PPTP control connection
290  * @result	The value for Stop-Control-Connection-Request(StopCCRQ) result.
291 		This function will not sent StopCCRQ when the value == 0 and
292 		the specification does not require to sent it.
293  * @see		::#PPTP_StopCCRQ_REASON_STOP_PROTOCOL
294  * @see		::#PPTP_StopCCRQ_REASON_STOP_LOCAL_SHUTDOWN
295  */
296 void
297 pptp_ctrl_stop(pptp_ctrl *_this, int result)
298 {
299 	int i;
300 	pptp_call *call;
301 
302 	switch (_this->state) {
303 	case PPTP_CTRL_STATE_WAIT_STOP_REPLY:
304 		/* waiting responce. */
305 		/* this state will timeout by pptp_ctrl_timeout */
306 		break;
307 	case PPTP_CTRL_STATE_ESTABLISHED:
308 		if (result != 0) {
309 			for (i = 0; i < slist_length(&_this->call_list); i++) {
310 				call = slist_get(&_this->call_list, i);
311 				pptp_call_disconnect(call,
312 				    PPTP_CDN_RESULT_ADMIN_SHUTDOWN, 0, NULL);
313 			}
314 			pptp_ctrl_send_StopCCRQ(_this, result);
315 			_this->state = PPTP_CTRL_STATE_WAIT_STOP_REPLY;
316 			break;
317 		}
318 		/* FALLTHROUGH */
319 	default:
320 		pptp_ctrl_fini(_this);
321 	}
322 	return;
323 }
324 
325 
326 /* finish PPTP control */
327 static void
328 pptp_ctrl_fini(pptp_ctrl *_this)
329 {
330 	pptp_call *call;
331 
332 	PPTP_CTRL_ASSERT(_this != NULL);
333 
334 	if (_this->sock >= 0) {
335 		event_del(&_this->ev_sock);
336 		close(_this->sock);
337 		_this->sock = -1;
338 	}
339 	for (slist_itr_first(&_this->call_list);
340 	    slist_itr_has_next(&_this->call_list);) {
341 		call = slist_itr_next(&_this->call_list);
342 		pptp_call_stop(call);
343 		pptp_call_destroy(call);
344 		slist_itr_remove(&_this->call_list);
345 	}
346 
347 	if (_this->on_io_event != 0) {
348 		/*
349 		 * as the complete terminate process needs complicated
350 		 * exception handling, do partially at here.
351 		 * rest of part will be handled by timer-event-handler.
352 		 */
353 		PPTP_CTRL_DBG((_this, LOG_DEBUG, "Disposing"));
354 		_this->state = PPTP_CTRL_STATE_DISPOSING;
355 		pptp_ctrl_reset_timeout(_this);
356 		return;
357 	}
358 
359 	evtimer_del(&_this->ev_timer);
360 	slist_fini(&_this->call_list);
361 
362 	pptp_ctrl_log (_this, LOG_NOTICE, "logtype=Finished");
363 
364 	/* disable _this */
365 	pptpd_ctrl_finished_notify(_this->pptpd, _this);
366 }
367 
368 /* free PPTP control context */
369 void
370 pptp_ctrl_destroy(pptp_ctrl *_this)
371 {
372 	if (_this->send_buf != NULL) {
373 		bytebuffer_destroy(_this->send_buf);
374 		_this->send_buf = NULL;
375 	}
376 	if (_this->recv_buf != NULL) {
377 		bytebuffer_destroy(_this->recv_buf);
378 		_this->recv_buf = NULL;
379 	}
380 	free(_this);
381 }
382 
383 /*
384  * network I/O
385  */
386 /* I/O event dispather */
387 static void
388 pptp_ctrl_io_event(int fd, short evmask, void *ctx)
389 {
390 	int sz, lpkt, hdrlen;
391 	u_char *pkt;
392 	pptp_ctrl *_this;
393 
394 	_this = ctx;
395 	PPTP_CTRL_ASSERT(_this != NULL);
396 
397 	_this->on_io_event = 1;
398 	if ((evmask & EV_WRITE) != 0) {
399 		if (pptp_ctrl_output_flush(_this) != 0 ||
400 		    _this->state == PPTP_CTRL_STATE_DISPOSING)
401 			goto fail;
402 		_this->send_ready = 1;
403 	}
404 	if ((evmask & EV_READ) != 0) {
405 		sz = read(_this->sock, bytebuffer_pointer(_this->recv_buf),
406 		    bytebuffer_remaining(_this->recv_buf));
407 		if (sz <= 0) {
408 			if (sz == 0 || errno == ECONNRESET) {
409 				pptp_ctrl_log(_this, LOG_INFO,
410 				    "Connection closed by foreign host");
411 				pptp_ctrl_fini(_this);
412 				goto fail;
413 			} else if (errno != EAGAIN && errno != EINTR) {
414 				pptp_ctrl_log(_this, LOG_INFO,
415 				    "read() failed at %s(): %m", __func__);
416 				pptp_ctrl_fini(_this);
417 				goto fail;
418 			}
419 		}
420 		bytebuffer_put(_this->recv_buf, BYTEBUFFER_PUT_DIRECT, sz);
421 		bytebuffer_flip(_this->recv_buf);
422 
423 		for (;;) {
424 			pkt = bytebuffer_pointer(_this->recv_buf);
425 			lpkt = bytebuffer_remaining(_this->recv_buf);
426 			if (pkt == NULL ||
427 			    lpkt < sizeof(struct pptp_ctrl_header))
428 				break;	/* read again */
429 
430 			hdrlen = pkt[0] << 8 | pkt[1];
431 			if (lpkt < hdrlen)
432 				break;	/* read again */
433 
434 			bytebuffer_get(_this->recv_buf, NULL, hdrlen);
435 			if (pptp_ctrl_input(_this, pkt, hdrlen) != 0 ||
436 			    _this->state == PPTP_CTRL_STATE_DISPOSING) {
437 				bytebuffer_compact(_this->recv_buf);
438 				goto fail;
439 			}
440 		}
441 		bytebuffer_compact(_this->recv_buf);
442 	}
443 	if (pptp_ctrl_output_flush(_this) != 0)
444 		goto fail;
445 	pptp_ctrl_set_io_event(_this);
446 fail:
447 	_this->on_io_event = 0;
448 }
449 
450 
451 /* set i/o event mask */
452 static void
453 pptp_ctrl_set_io_event(pptp_ctrl *_this)
454 {
455 	int evmask;
456 
457 	PPTP_CTRL_ASSERT(_this != NULL);
458 	PPTP_CTRL_ASSERT(_this->sock >= 0);
459 
460 	evmask = 0;
461 	if (bytebuffer_remaining(_this->recv_buf) > 128)
462 		evmask |= EV_READ;
463 	if (_this->send_ready == 0)
464 		evmask |= EV_WRITE;
465 
466 	event_del(&_this->ev_sock);
467 	if (evmask != 0) {
468 		event_set(&_this->ev_sock, _this->sock, evmask,
469 		    pptp_ctrl_io_event, _this);
470 		event_add(&_this->ev_sock, NULL);
471 	}
472 }
473 
474 /**
475  * Output PPTP control packet
476  * @param pkt	pointer to packet buffer.
477  *		when it was appended by _this-.send_buf using bytebuffer,
478  *		specify NULL.
479  * @param lpkt	packet length
480  */
481 void
482 pptp_ctrl_output(pptp_ctrl *_this, u_char *pkt, int lpkt)
483 {
484 	PPTP_CTRL_ASSERT(_this != NULL);
485 	PPTP_CTRL_ASSERT(lpkt > 0);
486 
487 	/* just put the packet into the buffer now.  send it later */
488 	bytebuffer_put(_this->send_buf, pkt, lpkt);
489 
490 	if (_this->on_io_event != 0) {
491 		/*
492 		 * pptp_ctrl_output_flush() will be called by the end of
493 		 * the I/O event handler.
494 		 */
495 	} else {
496 		/*
497 		 * When this function is called by other than I/O event handler,
498 		 * we need to call pptp_ctrl_output_flush().  However if we do
499 		 * it here, then we need to consider the situation
500 		 * 'flush => write failure => finalize'.  The situation requires
501 		 * the caller function to handle the exception and causes
502 		 * complication.  So we call pptp_ctrl_output_flush() by the
503 		 * the next send ready event.
504 		 */
505 		_this->send_ready = 0;		/* clear 'send ready' */
506 		pptp_ctrl_set_io_event(_this);	/* wait 'send ready */
507 	}
508 
509 	return;
510 }
511 
512 /* Send Stop-Control-Connection-Request */
513 
514 /* flush output packet */
515 static int
516 pptp_ctrl_output_flush(pptp_ctrl *_this)
517 {
518 	int sz;
519 	time_t curr_time;
520 
521 	curr_time = get_monosec();
522 
523 	if (bytebuffer_position(_this->send_buf) <= 0)
524 		return 0;		/* nothing to write */
525 	if (_this->send_ready == 0) {
526 		pptp_ctrl_set_io_event(_this);
527 		return 0;		/* not ready to write */
528 	}
529 
530 	bytebuffer_flip(_this->send_buf);
531 
532 	if (PPTP_CTRL_CONF(_this)->ctrl_out_pktdump != 0) {
533 		pptp_ctrl_log(_this, LOG_DEBUG, "PPTP Control output packet");
534 		show_hd(debug_get_debugfp(),
535 		    bytebuffer_pointer(_this->send_buf),
536 		    bytebuffer_remaining(_this->send_buf));
537 	}
538 	if ((sz = write(_this->sock, bytebuffer_pointer(_this->send_buf),
539 	    bytebuffer_remaining(_this->send_buf))) < 0) {
540 		pptp_ctrl_log(_this, LOG_ERR, "write to socket failed: %m");
541 		pptp_ctrl_fini(_this);
542 
543 		return 1;
544 	}
545 	_this->last_snd_ctrl = curr_time;
546 	bytebuffer_get(_this->send_buf, NULL, sz);
547 	bytebuffer_compact(_this->send_buf);
548 	_this->send_ready = 0;
549 
550 	return 0;
551 }
552 
553 /* convert Start-Control-Connection-{Request,Reply} packet to strings */
554 static void
555 pptp_ctrl_SCCRx_string(struct pptp_scc *scc, u_char *buf, int lbuf)
556 {
557 	char buf1[128], buf2[128], buf3[128];
558 
559 	/* sanity check */
560 	strlcpy(buf1, scc->host_name, sizeof(buf1));
561 	strlcpy(buf2, scc->vendor_string, sizeof(buf2));
562 
563 	if (scc->result_code != 0)
564 		snprintf(buf3, sizeof(buf3), "result=%d error=%d ",
565 		    scc->result_code, scc->error_code);
566 	else
567 		buf3[0] = '\0';
568 
569 	snprintf(buf, lbuf,
570 	    "protocol_version=%d.%d %sframing=%s bearer=%s max_channels=%d "
571 	    "firmware_revision=%d(0x%04x) host_name=\"%s\" "
572 	    "vendor_string=\"%s\"",
573 	    scc->protocol_version >> 8, scc->protocol_version & 0xff, buf3,
574 	    pptp_framing_string(scc->framing_caps),
575 	    pptp_bearer_string(scc->bearer_caps), scc->max_channels,
576 	    scc->firmware_revision, scc->firmware_revision, buf1, buf2);
577 }
578 
579 /* receive Start-Control-Connection-Request */
580 static int
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
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
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
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
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
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 (PPTP_CTRL_CONF(_this)->hostname == NULL)
751 		val = "";
752 	strlcpy(scc->host_name, val, sizeof(scc->host_name));
753 
754 	/* vender 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
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
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
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
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
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
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
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 *
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