GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/npppd/npppd/../pptp/pptp_ctrl.c Lines: 0 457 0.0 %
Date: 2017-11-13 Branches: 0 208 0.0 %

Line Branch Exec Source
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
}