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