xref: /netbsd-src/external/bsd/tcpdump/dist/print-pptp.c (revision cc576e1d8e4f4078fd4e81238abca9fca216f6ec)
1 /*
2  * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that: (1) source code distributions
7  * retain the above copyright notice and this paragraph in its entirety, (2)
8  * distributions including binary code include the above copyright notice and
9  * this paragraph in its entirety in the documentation or other materials
10  * provided with the distribution, and (3) all advertising materials mentioning
11  * features or use of this software display the following acknowledgement:
12  * ``This product includes software developed by the University of California,
13  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14  * the University nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior
16  * written permission.
17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  * PPTP support contributed by Motonori Shindo (mshindo@mshindo.net)
22  */
23 
24 #include <sys/cdefs.h>
25 #ifndef lint
26 __RCSID("$NetBSD: print-pptp.c,v 1.5 2017/01/24 23:29:14 christos Exp $");
27 #endif
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include <netdissect-stdinc.h>
34 
35 #include "netdissect.h"
36 #include "extract.h"
37 
38 static const char tstr[] = " [|pptp]";
39 
40 #define PPTP_MSG_TYPE_CTRL	1	/* Control Message */
41 #define PPTP_MSG_TYPE_MGMT	2	/* Management Message (currently not used */
42 #define PPTP_MAGIC_COOKIE	0x1a2b3c4d	/* for sanity check */
43 
44 #define PPTP_CTRL_MSG_TYPE_SCCRQ	1
45 #define PPTP_CTRL_MSG_TYPE_SCCRP	2
46 #define PPTP_CTRL_MSG_TYPE_StopCCRQ	3
47 #define PPTP_CTRL_MSG_TYPE_StopCCRP	4
48 #define PPTP_CTRL_MSG_TYPE_ECHORQ	5
49 #define PPTP_CTRL_MSG_TYPE_ECHORP	6
50 #define PPTP_CTRL_MSG_TYPE_OCRQ		7
51 #define PPTP_CTRL_MSG_TYPE_OCRP		8
52 #define PPTP_CTRL_MSG_TYPE_ICRQ		9
53 #define PPTP_CTRL_MSG_TYPE_ICRP		10
54 #define PPTP_CTRL_MSG_TYPE_ICCN		11
55 #define PPTP_CTRL_MSG_TYPE_CCRQ		12
56 #define PPTP_CTRL_MSG_TYPE_CDN		13
57 #define PPTP_CTRL_MSG_TYPE_WEN		14
58 #define PPTP_CTRL_MSG_TYPE_SLI		15
59 
60 #define PPTP_FRAMING_CAP_ASYNC_MASK	0x00000001      /* Aynchronous */
61 #define PPTP_FRAMING_CAP_SYNC_MASK	0x00000002      /* Synchronous */
62 
63 #define PPTP_BEARER_CAP_ANALOG_MASK	0x00000001      /* Analog */
64 #define PPTP_BEARER_CAP_DIGITAL_MASK	0x00000002      /* Digital */
65 
66 static const char *pptp_message_type_string[] = {
67 	"NOT_DEFINED",		/* 0  Not defined in the RFC2637 */
68 	"SCCRQ",		/* 1  Start-Control-Connection-Request */
69 	"SCCRP",		/* 2  Start-Control-Connection-Reply */
70 	"StopCCRQ",		/* 3  Stop-Control-Connection-Request */
71 	"StopCCRP",		/* 4  Stop-Control-Connection-Reply */
72 	"ECHORQ",		/* 5  Echo Request */
73 	"ECHORP",		/* 6  Echo Reply */
74 
75 	"OCRQ",			/* 7  Outgoing-Call-Request */
76 	"OCRP",			/* 8  Outgoing-Call-Reply */
77 	"ICRQ",			/* 9  Incoming-Call-Request */
78 	"ICRP",			/* 10 Incoming-Call-Reply */
79 	"ICCN",			/* 11 Incoming-Call-Connected */
80 	"CCRQ",			/* 12 Call-Clear-Request */
81 	"CDN",			/* 13 Call-Disconnect-Notify */
82 
83 	"WEN",			/* 14 WAN-Error-Notify */
84 
85 	"SLI"			/* 15 Set-Link-Info */
86 #define PPTP_MAX_MSGTYPE_INDEX	16
87 };
88 
89 /* common for all PPTP control messages */
90 struct pptp_hdr {
91 	uint16_t length;
92 	uint16_t msg_type;
93 	uint32_t magic_cookie;
94 	uint16_t ctrl_msg_type;
95 	uint16_t reserved0;
96 };
97 
98 struct pptp_msg_sccrq {
99 	uint16_t proto_ver;
100 	uint16_t reserved1;
101 	uint32_t framing_cap;
102 	uint32_t bearer_cap;
103 	uint16_t max_channel;
104 	uint16_t firm_rev;
105 	u_char hostname[64];
106 	u_char vendor[64];
107 };
108 
109 struct pptp_msg_sccrp {
110 	uint16_t proto_ver;
111 	uint8_t result_code;
112 	uint8_t err_code;
113 	uint32_t framing_cap;
114 	uint32_t bearer_cap;
115 	uint16_t max_channel;
116 	uint16_t firm_rev;
117 	u_char hostname[64];
118 	u_char vendor[64];
119 };
120 
121 struct pptp_msg_stopccrq {
122 	uint8_t reason;
123 	uint8_t reserved1;
124 	uint16_t reserved2;
125 };
126 
127 struct pptp_msg_stopccrp {
128 	uint8_t result_code;
129 	uint8_t err_code;
130 	uint16_t reserved1;
131 };
132 
133 struct pptp_msg_echorq {
134 	uint32_t id;
135 };
136 
137 struct pptp_msg_echorp {
138 	uint32_t id;
139 	uint8_t result_code;
140 	uint8_t err_code;
141 	uint16_t reserved1;
142 };
143 
144 struct pptp_msg_ocrq {
145 	uint16_t call_id;
146 	uint16_t call_ser;
147 	uint32_t min_bps;
148 	uint32_t max_bps;
149 	uint32_t bearer_type;
150 	uint32_t framing_type;
151 	uint16_t recv_winsiz;
152 	uint16_t pkt_proc_delay;
153 	uint16_t phone_no_len;
154 	uint16_t reserved1;
155 	u_char phone_no[64];
156 	u_char subaddr[64];
157 };
158 
159 struct pptp_msg_ocrp {
160 	uint16_t call_id;
161 	uint16_t peer_call_id;
162 	uint8_t result_code;
163 	uint8_t err_code;
164 	uint16_t cause_code;
165 	uint32_t conn_speed;
166 	uint16_t recv_winsiz;
167 	uint16_t pkt_proc_delay;
168 	uint32_t phy_chan_id;
169 };
170 
171 struct pptp_msg_icrq {
172 	uint16_t call_id;
173 	uint16_t call_ser;
174 	uint32_t bearer_type;
175 	uint32_t phy_chan_id;
176 	uint16_t dialed_no_len;
177 	uint16_t dialing_no_len;
178 	u_char dialed_no[64];		/* DNIS */
179 	u_char dialing_no[64];		/* CLID */
180 	u_char subaddr[64];
181 };
182 
183 struct pptp_msg_icrp {
184 	uint16_t call_id;
185 	uint16_t peer_call_id;
186 	uint8_t result_code;
187 	uint8_t err_code;
188 	uint16_t recv_winsiz;
189 	uint16_t pkt_proc_delay;
190 	uint16_t reserved1;
191 };
192 
193 struct pptp_msg_iccn {
194 	uint16_t peer_call_id;
195 	uint16_t reserved1;
196 	uint32_t conn_speed;
197 	uint16_t recv_winsiz;
198 	uint16_t pkt_proc_delay;
199 	uint32_t framing_type;
200 };
201 
202 struct pptp_msg_ccrq {
203 	uint16_t call_id;
204 	uint16_t reserved1;
205 };
206 
207 struct pptp_msg_cdn {
208 	uint16_t call_id;
209 	uint8_t result_code;
210 	uint8_t err_code;
211 	uint16_t cause_code;
212 	uint16_t reserved1;
213 	u_char call_stats[128];
214 };
215 
216 struct pptp_msg_wen {
217 	uint16_t peer_call_id;
218 	uint16_t reserved1;
219 	uint32_t crc_err;
220 	uint32_t framing_err;
221 	uint32_t hardware_overrun;
222 	uint32_t buffer_overrun;
223 	uint32_t timeout_err;
224 	uint32_t align_err;
225 };
226 
227 struct pptp_msg_sli {
228 	uint16_t peer_call_id;
229 	uint16_t reserved1;
230 	uint32_t send_accm;
231 	uint32_t recv_accm;
232 };
233 
234 /* attributes that appear more than once in above messages:
235 
236    Number of
237    occurence    attributes
238   --------------------------------------
239       2         uint32_t bearer_cap;
240       2         uint32_t bearer_type;
241       6         uint16_t call_id;
242       2         uint16_t call_ser;
243       2         uint16_t cause_code;
244       2         uint32_t conn_speed;
245       6         uint8_t err_code;
246       2         uint16_t firm_rev;
247       2         uint32_t framing_cap;
248       2         uint32_t framing_type;
249       2         u_char hostname[64];
250       2         uint32_t id;
251       2         uint16_t max_channel;
252       5         uint16_t peer_call_id;
253       2         uint32_t phy_chan_id;
254       4         uint16_t pkt_proc_delay;
255       2         uint16_t proto_ver;
256       4         uint16_t recv_winsiz;
257       2         uint8_t reserved1;
258       9         uint16_t reserved1;
259       6         uint8_t result_code;
260       2         u_char subaddr[64];
261       2         u_char vendor[64];
262 
263   so I will prepare print out functions for these attributes (except for
264   reserved*).
265 */
266 
267 /******************************************/
268 /* Attribute-specific print out functions */
269 /******************************************/
270 
271 /* In these attribute-specific print-out functions, it't not necessary
272    to do ND_TCHECK because they are already checked in the caller of
273    these functions. */
274 
275 static void
276 pptp_bearer_cap_print(netdissect_options *ndo,
277                       const uint32_t *bearer_cap)
278 {
279 	ND_PRINT((ndo, " BEARER_CAP(%s%s)",
280 	          EXTRACT_32BITS(bearer_cap) & PPTP_BEARER_CAP_DIGITAL_MASK ? "D" : "",
281 	          EXTRACT_32BITS(bearer_cap) & PPTP_BEARER_CAP_ANALOG_MASK ? "A" : ""));
282 }
283 
284 static const struct tok pptp_btype_str[] = {
285 	{ 1, "A"   }, /* Analog */
286 	{ 2, "D"   }, /* Digital */
287 	{ 3, "Any" },
288 	{ 0, NULL }
289 };
290 
291 static void
292 pptp_bearer_type_print(netdissect_options *ndo,
293                        const uint32_t *bearer_type)
294 {
295 	ND_PRINT((ndo, " BEARER_TYPE(%s)",
296 	          tok2str(pptp_btype_str, "?", EXTRACT_32BITS(bearer_type))));
297 }
298 
299 static void
300 pptp_call_id_print(netdissect_options *ndo,
301                    const uint16_t *call_id)
302 {
303 	ND_PRINT((ndo, " CALL_ID(%u)", EXTRACT_16BITS(call_id)));
304 }
305 
306 static void
307 pptp_call_ser_print(netdissect_options *ndo,
308                     const uint16_t *call_ser)
309 {
310 	ND_PRINT((ndo, " CALL_SER_NUM(%u)", EXTRACT_16BITS(call_ser)));
311 }
312 
313 static void
314 pptp_cause_code_print(netdissect_options *ndo,
315                       const uint16_t *cause_code)
316 {
317 	ND_PRINT((ndo, " CAUSE_CODE(%u)", EXTRACT_16BITS(cause_code)));
318 }
319 
320 static void
321 pptp_conn_speed_print(netdissect_options *ndo,
322                       const uint32_t *conn_speed)
323 {
324 	ND_PRINT((ndo, " CONN_SPEED(%u)", EXTRACT_32BITS(conn_speed)));
325 }
326 
327 static const struct tok pptp_errcode_str[] = {
328 	{ 0, "None"          },
329 	{ 1, "Not-Connected" },
330 	{ 2, "Bad-Format"    },
331 	{ 3, "Bad-Value"     },
332 	{ 4, "No-Resource"   },
333 	{ 5, "Bad-Call-ID"   },
334 	{ 6, "PAC-Error"     },
335 	{ 0, NULL }
336 };
337 
338 static void
339 pptp_err_code_print(netdissect_options *ndo,
340                     const uint8_t *err_code)
341 {
342 	ND_PRINT((ndo, " ERR_CODE(%u", *err_code));
343 	if (ndo->ndo_vflag) {
344 		ND_PRINT((ndo, ":%s", tok2str(pptp_errcode_str, "?", *err_code)));
345 	}
346 	ND_PRINT((ndo, ")"));
347 }
348 
349 static void
350 pptp_firm_rev_print(netdissect_options *ndo,
351                     const uint16_t *firm_rev)
352 {
353 	ND_PRINT((ndo, " FIRM_REV(%u)", EXTRACT_16BITS(firm_rev)));
354 }
355 
356 static void
357 pptp_framing_cap_print(netdissect_options *ndo,
358                        const uint32_t *framing_cap)
359 {
360 	ND_PRINT((ndo, " FRAME_CAP("));
361 	if (EXTRACT_32BITS(framing_cap) & PPTP_FRAMING_CAP_ASYNC_MASK) {
362                 ND_PRINT((ndo, "A"));		/* Async */
363         }
364         if (EXTRACT_32BITS(framing_cap) & PPTP_FRAMING_CAP_SYNC_MASK) {
365                 ND_PRINT((ndo, "S"));		/* Sync */
366         }
367 	ND_PRINT((ndo, ")"));
368 }
369 
370 static const struct tok pptp_ftype_str[] = {
371 	{ 1, "A" }, /* Async */
372 	{ 2, "S" }, /* Sync */
373 	{ 3, "E" }, /* Either */
374 	{ 0, NULL }
375 };
376 
377 static void
378 pptp_framing_type_print(netdissect_options *ndo,
379                         const uint32_t *framing_type)
380 {
381 	ND_PRINT((ndo, " FRAME_TYPE(%s)",
382 	          tok2str(pptp_ftype_str, "?", EXTRACT_32BITS(framing_type))));
383 }
384 
385 static void
386 pptp_hostname_print(netdissect_options *ndo,
387                     const u_char *hostname)
388 {
389 	ND_PRINT((ndo, " HOSTNAME(%.64s)", hostname));
390 }
391 
392 static void
393 pptp_id_print(netdissect_options *ndo,
394               const uint32_t *id)
395 {
396 	ND_PRINT((ndo, " ID(%u)", EXTRACT_32BITS(id)));
397 }
398 
399 static void
400 pptp_max_channel_print(netdissect_options *ndo,
401                        const uint16_t *max_channel)
402 {
403 	ND_PRINT((ndo, " MAX_CHAN(%u)", EXTRACT_16BITS(max_channel)));
404 }
405 
406 static void
407 pptp_peer_call_id_print(netdissect_options *ndo,
408                         const uint16_t *peer_call_id)
409 {
410 	ND_PRINT((ndo, " PEER_CALL_ID(%u)", EXTRACT_16BITS(peer_call_id)));
411 }
412 
413 static void
414 pptp_phy_chan_id_print(netdissect_options *ndo,
415                        const uint32_t *phy_chan_id)
416 {
417 	ND_PRINT((ndo, " PHY_CHAN_ID(%u)", EXTRACT_32BITS(phy_chan_id)));
418 }
419 
420 static void
421 pptp_pkt_proc_delay_print(netdissect_options *ndo,
422                           const uint16_t *pkt_proc_delay)
423 {
424 	ND_PRINT((ndo, " PROC_DELAY(%u)", EXTRACT_16BITS(pkt_proc_delay)));
425 }
426 
427 static void
428 pptp_proto_ver_print(netdissect_options *ndo,
429                      const uint16_t *proto_ver)
430 {
431 	ND_PRINT((ndo, " PROTO_VER(%u.%u)",	/* Version.Revision */
432 	       EXTRACT_16BITS(proto_ver) >> 8,
433 	       EXTRACT_16BITS(proto_ver) & 0xff));
434 }
435 
436 static void
437 pptp_recv_winsiz_print(netdissect_options *ndo,
438                        const uint16_t *recv_winsiz)
439 {
440 	ND_PRINT((ndo, " RECV_WIN(%u)", EXTRACT_16BITS(recv_winsiz)));
441 }
442 
443 static const struct tok pptp_scrrp_str[] = {
444 	{ 1, "Successful channel establishment"                           },
445 	{ 2, "General error"                                              },
446 	{ 3, "Command channel already exists"                             },
447 	{ 4, "Requester is not authorized to establish a command channel" },
448 	{ 5, "The protocol version of the requester is not supported"     },
449 	{ 0, NULL }
450 };
451 
452 static const struct tok pptp_echorp_str[] = {
453 	{ 1, "OK" },
454 	{ 2, "General Error" },
455 	{ 0, NULL }
456 };
457 
458 static const struct tok pptp_ocrp_str[] = {
459 	{ 1, "Connected"     },
460 	{ 2, "General Error" },
461 	{ 3, "No Carrier"    },
462 	{ 4, "Busy"          },
463 	{ 5, "No Dial Tone"  },
464 	{ 6, "Time-out"      },
465 	{ 7, "Do Not Accept" },
466 	{ 0, NULL }
467 };
468 
469 static const struct tok pptp_icrp_str[] = {
470 	{ 1, "Connect"       },
471 	{ 2, "General Error" },
472 	{ 3, "Do Not Accept" },
473 	{ 0, NULL }
474 };
475 
476 static const struct tok pptp_cdn_str[] = {
477 	{ 1, "Lost Carrier"   },
478 	{ 2, "General Error"  },
479 	{ 3, "Admin Shutdown" },
480 	{ 4, "Request"        },
481 	{ 0, NULL }
482 };
483 
484 static void
485 pptp_result_code_print(netdissect_options *ndo,
486                        const uint8_t *result_code, int ctrl_msg_type)
487 {
488 	ND_PRINT((ndo, " RESULT_CODE(%u", *result_code));
489 	if (ndo->ndo_vflag) {
490 		const struct tok *dict =
491 			ctrl_msg_type == PPTP_CTRL_MSG_TYPE_SCCRP    ? pptp_scrrp_str :
492 			ctrl_msg_type == PPTP_CTRL_MSG_TYPE_StopCCRP ? pptp_echorp_str :
493 			ctrl_msg_type == PPTP_CTRL_MSG_TYPE_ECHORP   ? pptp_echorp_str :
494 			ctrl_msg_type == PPTP_CTRL_MSG_TYPE_OCRP     ? pptp_ocrp_str :
495 			ctrl_msg_type == PPTP_CTRL_MSG_TYPE_ICRP     ? pptp_icrp_str :
496 			ctrl_msg_type == PPTP_CTRL_MSG_TYPE_CDN      ? pptp_cdn_str :
497 			NULL; /* assertion error */
498 		if (dict != NULL)
499 			ND_PRINT((ndo, ":%s", tok2str(dict, "?", *result_code)));
500 	}
501 	ND_PRINT((ndo, ")"));
502 }
503 
504 static void
505 pptp_subaddr_print(netdissect_options *ndo,
506                    const u_char *subaddr)
507 {
508 	ND_PRINT((ndo, " SUB_ADDR(%.64s)", subaddr));
509 }
510 
511 static void
512 pptp_vendor_print(netdissect_options *ndo,
513                   const u_char *vendor)
514 {
515 	ND_PRINT((ndo, " VENDOR(%.64s)", vendor));
516 }
517 
518 /************************************/
519 /* PPTP message print out functions */
520 /************************************/
521 static void
522 pptp_sccrq_print(netdissect_options *ndo,
523                  const u_char *dat)
524 {
525 	const struct pptp_msg_sccrq *ptr = (const struct pptp_msg_sccrq *)dat;
526 
527 	ND_TCHECK(ptr->proto_ver);
528 	pptp_proto_ver_print(ndo, &ptr->proto_ver);
529 	ND_TCHECK(ptr->reserved1);
530 	ND_TCHECK(ptr->framing_cap);
531 	pptp_framing_cap_print(ndo, &ptr->framing_cap);
532 	ND_TCHECK(ptr->bearer_cap);
533 	pptp_bearer_cap_print(ndo, &ptr->bearer_cap);
534 	ND_TCHECK(ptr->max_channel);
535 	pptp_max_channel_print(ndo, &ptr->max_channel);
536 	ND_TCHECK(ptr->firm_rev);
537 	pptp_firm_rev_print(ndo, &ptr->firm_rev);
538 	ND_TCHECK(ptr->hostname);
539 	pptp_hostname_print(ndo, &ptr->hostname[0]);
540 	ND_TCHECK(ptr->vendor);
541 	pptp_vendor_print(ndo, &ptr->vendor[0]);
542 
543 	return;
544 
545 trunc:
546 	ND_PRINT((ndo, "%s", tstr));
547 }
548 
549 static void
550 pptp_sccrp_print(netdissect_options *ndo,
551                  const u_char *dat)
552 {
553 	const struct pptp_msg_sccrp *ptr = (const struct pptp_msg_sccrp *)dat;
554 
555 	ND_TCHECK(ptr->proto_ver);
556 	pptp_proto_ver_print(ndo, &ptr->proto_ver);
557 	ND_TCHECK(ptr->result_code);
558 	pptp_result_code_print(ndo, &ptr->result_code, PPTP_CTRL_MSG_TYPE_SCCRP);
559 	ND_TCHECK(ptr->err_code);
560 	pptp_err_code_print(ndo, &ptr->err_code);
561 	ND_TCHECK(ptr->framing_cap);
562 	pptp_framing_cap_print(ndo, &ptr->framing_cap);
563 	ND_TCHECK(ptr->bearer_cap);
564 	pptp_bearer_cap_print(ndo, &ptr->bearer_cap);
565 	ND_TCHECK(ptr->max_channel);
566 	pptp_max_channel_print(ndo, &ptr->max_channel);
567 	ND_TCHECK(ptr->firm_rev);
568 	pptp_firm_rev_print(ndo, &ptr->firm_rev);
569 	ND_TCHECK(ptr->hostname);
570 	pptp_hostname_print(ndo, &ptr->hostname[0]);
571 	ND_TCHECK(ptr->vendor);
572 	pptp_vendor_print(ndo, &ptr->vendor[0]);
573 
574 	return;
575 
576 trunc:
577 	ND_PRINT((ndo, "%s", tstr));
578 }
579 
580 static void
581 pptp_stopccrq_print(netdissect_options *ndo,
582                     const u_char *dat)
583 {
584 	const struct pptp_msg_stopccrq *ptr = (const struct pptp_msg_stopccrq *)dat;
585 
586 	ND_TCHECK(ptr->reason);
587 	ND_PRINT((ndo, " REASON(%u", ptr->reason));
588 	if (ndo->ndo_vflag) {
589 		switch (ptr->reason) {
590 		case 1:
591 			ND_PRINT((ndo, ":None"));
592 			break;
593 		case 2:
594 			ND_PRINT((ndo, ":Stop-Protocol"));
595 			break;
596 		case 3:
597 			ND_PRINT((ndo, ":Stop-Local-Shutdown"));
598 			break;
599 		default:
600 			ND_PRINT((ndo, ":?"));
601 			break;
602 		}
603 	}
604 	ND_PRINT((ndo, ")"));
605 	ND_TCHECK(ptr->reserved1);
606 	ND_TCHECK(ptr->reserved2);
607 
608 	return;
609 
610 trunc:
611 	ND_PRINT((ndo, "%s", tstr));
612 }
613 
614 static void
615 pptp_stopccrp_print(netdissect_options *ndo,
616                     const u_char *dat)
617 {
618 	const struct pptp_msg_stopccrp *ptr = (const struct pptp_msg_stopccrp *)dat;
619 
620 	ND_TCHECK(ptr->result_code);
621 	pptp_result_code_print(ndo, &ptr->result_code, PPTP_CTRL_MSG_TYPE_StopCCRP);
622 	ND_TCHECK(ptr->err_code);
623 	pptp_err_code_print(ndo, &ptr->err_code);
624 	ND_TCHECK(ptr->reserved1);
625 
626 	return;
627 
628 trunc:
629 	ND_PRINT((ndo, "%s", tstr));
630 }
631 
632 static void
633 pptp_echorq_print(netdissect_options *ndo,
634                   const u_char *dat)
635 {
636 	const struct pptp_msg_echorq *ptr = (const struct pptp_msg_echorq *)dat;
637 
638 	ND_TCHECK(ptr->id);
639 	pptp_id_print(ndo, &ptr->id);
640 
641 	return;
642 
643 trunc:
644 	ND_PRINT((ndo, "%s", tstr));
645 }
646 
647 static void
648 pptp_echorp_print(netdissect_options *ndo,
649                   const u_char *dat)
650 {
651 	const struct pptp_msg_echorp *ptr = (const struct pptp_msg_echorp *)dat;
652 
653 	ND_TCHECK(ptr->id);
654 	pptp_id_print(ndo, &ptr->id);
655 	ND_TCHECK(ptr->result_code);
656 	pptp_result_code_print(ndo, &ptr->result_code, PPTP_CTRL_MSG_TYPE_ECHORP);
657 	ND_TCHECK(ptr->err_code);
658 	pptp_err_code_print(ndo, &ptr->err_code);
659 	ND_TCHECK(ptr->reserved1);
660 
661 	return;
662 
663 trunc:
664 	ND_PRINT((ndo, "%s", tstr));
665 }
666 
667 static void
668 pptp_ocrq_print(netdissect_options *ndo,
669                 const u_char *dat)
670 {
671 	const struct pptp_msg_ocrq *ptr = (const struct pptp_msg_ocrq *)dat;
672 
673 	ND_TCHECK(ptr->call_id);
674 	pptp_call_id_print(ndo, &ptr->call_id);
675 	ND_TCHECK(ptr->call_ser);
676 	pptp_call_ser_print(ndo, &ptr->call_ser);
677 	ND_TCHECK(ptr->min_bps);
678 	ND_PRINT((ndo, " MIN_BPS(%u)", EXTRACT_32BITS(&ptr->min_bps)));
679 	ND_TCHECK(ptr->max_bps);
680 	ND_PRINT((ndo, " MAX_BPS(%u)", EXTRACT_32BITS(&ptr->max_bps)));
681 	ND_TCHECK(ptr->bearer_type);
682 	pptp_bearer_type_print(ndo, &ptr->bearer_type);
683 	ND_TCHECK(ptr->framing_type);
684 	pptp_framing_type_print(ndo, &ptr->framing_type);
685 	ND_TCHECK(ptr->recv_winsiz);
686 	pptp_recv_winsiz_print(ndo, &ptr->recv_winsiz);
687 	ND_TCHECK(ptr->pkt_proc_delay);
688 	pptp_pkt_proc_delay_print(ndo, &ptr->pkt_proc_delay);
689 	ND_TCHECK(ptr->phone_no_len);
690 	ND_PRINT((ndo, " PHONE_NO_LEN(%u)", EXTRACT_16BITS(&ptr->phone_no_len)));
691 	ND_TCHECK(ptr->reserved1);
692 	ND_TCHECK(ptr->phone_no);
693 	ND_PRINT((ndo, " PHONE_NO(%.64s)", ptr->phone_no));
694 	ND_TCHECK(ptr->subaddr);
695 	pptp_subaddr_print(ndo, &ptr->subaddr[0]);
696 
697 	return;
698 
699 trunc:
700 	ND_PRINT((ndo, "%s", tstr));
701 }
702 
703 static void
704 pptp_ocrp_print(netdissect_options *ndo,
705                 const u_char *dat)
706 {
707 	const struct pptp_msg_ocrp *ptr = (const struct pptp_msg_ocrp *)dat;
708 
709 	ND_TCHECK(ptr->call_id);
710 	pptp_call_id_print(ndo, &ptr->call_id);
711 	ND_TCHECK(ptr->peer_call_id);
712 	pptp_peer_call_id_print(ndo, &ptr->peer_call_id);
713 	ND_TCHECK(ptr->result_code);
714 	pptp_result_code_print(ndo, &ptr->result_code, PPTP_CTRL_MSG_TYPE_OCRP);
715 	ND_TCHECK(ptr->err_code);
716 	pptp_err_code_print(ndo, &ptr->err_code);
717 	ND_TCHECK(ptr->cause_code);
718 	pptp_cause_code_print(ndo, &ptr->cause_code);
719 	ND_TCHECK(ptr->conn_speed);
720 	pptp_conn_speed_print(ndo, &ptr->conn_speed);
721 	ND_TCHECK(ptr->recv_winsiz);
722 	pptp_recv_winsiz_print(ndo, &ptr->recv_winsiz);
723 	ND_TCHECK(ptr->pkt_proc_delay);
724 	pptp_pkt_proc_delay_print(ndo, &ptr->pkt_proc_delay);
725 	ND_TCHECK(ptr->phy_chan_id);
726 	pptp_phy_chan_id_print(ndo, &ptr->phy_chan_id);
727 
728 	return;
729 
730 trunc:
731 	ND_PRINT((ndo, "%s", tstr));
732 }
733 
734 static void
735 pptp_icrq_print(netdissect_options *ndo,
736                 const u_char *dat)
737 {
738 	const struct pptp_msg_icrq *ptr = (const struct pptp_msg_icrq *)dat;
739 
740 	ND_TCHECK(ptr->call_id);
741 	pptp_call_id_print(ndo, &ptr->call_id);
742 	ND_TCHECK(ptr->call_ser);
743 	pptp_call_ser_print(ndo, &ptr->call_ser);
744 	ND_TCHECK(ptr->bearer_type);
745 	pptp_bearer_type_print(ndo, &ptr->bearer_type);
746 	ND_TCHECK(ptr->phy_chan_id);
747 	pptp_phy_chan_id_print(ndo, &ptr->phy_chan_id);
748 	ND_TCHECK(ptr->dialed_no_len);
749 	ND_PRINT((ndo, " DIALED_NO_LEN(%u)", EXTRACT_16BITS(&ptr->dialed_no_len)));
750 	ND_TCHECK(ptr->dialing_no_len);
751 	ND_PRINT((ndo, " DIALING_NO_LEN(%u)", EXTRACT_16BITS(&ptr->dialing_no_len)));
752 	ND_TCHECK(ptr->dialed_no);
753 	ND_PRINT((ndo, " DIALED_NO(%.64s)", ptr->dialed_no));
754 	ND_TCHECK(ptr->dialing_no);
755 	ND_PRINT((ndo, " DIALING_NO(%.64s)", ptr->dialing_no));
756 	ND_TCHECK(ptr->subaddr);
757 	pptp_subaddr_print(ndo, &ptr->subaddr[0]);
758 
759 	return;
760 
761 trunc:
762 	ND_PRINT((ndo, "%s", tstr));
763 }
764 
765 static void
766 pptp_icrp_print(netdissect_options *ndo,
767                 const u_char *dat)
768 {
769 	const struct pptp_msg_icrp *ptr = (const struct pptp_msg_icrp *)dat;
770 
771 	ND_TCHECK(ptr->call_id);
772 	pptp_call_id_print(ndo, &ptr->call_id);
773 	ND_TCHECK(ptr->peer_call_id);
774 	pptp_peer_call_id_print(ndo, &ptr->peer_call_id);
775 	ND_TCHECK(ptr->result_code);
776 	pptp_result_code_print(ndo, &ptr->result_code, PPTP_CTRL_MSG_TYPE_ICRP);
777 	ND_TCHECK(ptr->err_code);
778 	pptp_err_code_print(ndo, &ptr->err_code);
779 	ND_TCHECK(ptr->recv_winsiz);
780 	pptp_recv_winsiz_print(ndo, &ptr->recv_winsiz);
781 	ND_TCHECK(ptr->pkt_proc_delay);
782 	pptp_pkt_proc_delay_print(ndo, &ptr->pkt_proc_delay);
783 	ND_TCHECK(ptr->reserved1);
784 
785 	return;
786 
787 trunc:
788 	ND_PRINT((ndo, "%s", tstr));
789 }
790 
791 static void
792 pptp_iccn_print(netdissect_options *ndo,
793                 const u_char *dat)
794 {
795 	const struct pptp_msg_iccn *ptr = (const struct pptp_msg_iccn *)dat;
796 
797 	ND_TCHECK(ptr->peer_call_id);
798 	pptp_peer_call_id_print(ndo, &ptr->peer_call_id);
799 	ND_TCHECK(ptr->reserved1);
800 	ND_TCHECK(ptr->conn_speed);
801 	pptp_conn_speed_print(ndo, &ptr->conn_speed);
802 	ND_TCHECK(ptr->recv_winsiz);
803 	pptp_recv_winsiz_print(ndo, &ptr->recv_winsiz);
804 	ND_TCHECK(ptr->pkt_proc_delay);
805 	pptp_pkt_proc_delay_print(ndo, &ptr->pkt_proc_delay);
806 	ND_TCHECK(ptr->framing_type);
807 	pptp_framing_type_print(ndo, &ptr->framing_type);
808 
809 	return;
810 
811 trunc:
812 	ND_PRINT((ndo, "%s", tstr));
813 }
814 
815 static void
816 pptp_ccrq_print(netdissect_options *ndo,
817                 const u_char *dat)
818 {
819 	const struct pptp_msg_ccrq *ptr = (const struct pptp_msg_ccrq *)dat;
820 
821 	ND_TCHECK(ptr->call_id);
822 	pptp_call_id_print(ndo, &ptr->call_id);
823 	ND_TCHECK(ptr->reserved1);
824 
825 	return;
826 
827 trunc:
828 	ND_PRINT((ndo, "%s", tstr));
829 }
830 
831 static void
832 pptp_cdn_print(netdissect_options *ndo,
833                const u_char *dat)
834 {
835 	const struct pptp_msg_cdn *ptr = (const struct pptp_msg_cdn *)dat;
836 
837 	ND_TCHECK(ptr->call_id);
838 	pptp_call_id_print(ndo, &ptr->call_id);
839 	ND_TCHECK(ptr->result_code);
840 	pptp_result_code_print(ndo, &ptr->result_code, PPTP_CTRL_MSG_TYPE_CDN);
841 	ND_TCHECK(ptr->err_code);
842 	pptp_err_code_print(ndo, &ptr->err_code);
843 	ND_TCHECK(ptr->cause_code);
844 	pptp_cause_code_print(ndo, &ptr->cause_code);
845 	ND_TCHECK(ptr->reserved1);
846 	ND_TCHECK(ptr->call_stats);
847 	ND_PRINT((ndo, " CALL_STATS(%.128s)", ptr->call_stats));
848 
849 	return;
850 
851 trunc:
852 	ND_PRINT((ndo, "%s", tstr));
853 }
854 
855 static void
856 pptp_wen_print(netdissect_options *ndo,
857                const u_char *dat)
858 {
859 	const struct pptp_msg_wen *ptr = (const struct pptp_msg_wen *)dat;
860 
861 	ND_TCHECK(ptr->peer_call_id);
862 	pptp_peer_call_id_print(ndo, &ptr->peer_call_id);
863 	ND_TCHECK(ptr->reserved1);
864 	ND_TCHECK(ptr->crc_err);
865 	ND_PRINT((ndo, " CRC_ERR(%u)", EXTRACT_32BITS(&ptr->crc_err)));
866 	ND_TCHECK(ptr->framing_err);
867 	ND_PRINT((ndo, " FRAMING_ERR(%u)", EXTRACT_32BITS(&ptr->framing_err)));
868 	ND_TCHECK(ptr->hardware_overrun);
869 	ND_PRINT((ndo, " HARDWARE_OVERRUN(%u)", EXTRACT_32BITS(&ptr->hardware_overrun)));
870 	ND_TCHECK(ptr->buffer_overrun);
871 	ND_PRINT((ndo, " BUFFER_OVERRUN(%u)", EXTRACT_32BITS(&ptr->buffer_overrun)));
872 	ND_TCHECK(ptr->timeout_err);
873 	ND_PRINT((ndo, " TIMEOUT_ERR(%u)", EXTRACT_32BITS(&ptr->timeout_err)));
874 	ND_TCHECK(ptr->align_err);
875 	ND_PRINT((ndo, " ALIGN_ERR(%u)", EXTRACT_32BITS(&ptr->align_err)));
876 
877 	return;
878 
879 trunc:
880 	ND_PRINT((ndo, "%s", tstr));
881 }
882 
883 static void
884 pptp_sli_print(netdissect_options *ndo,
885                const u_char *dat)
886 {
887 	const struct pptp_msg_sli *ptr = (const struct pptp_msg_sli *)dat;
888 
889 	ND_TCHECK(ptr->peer_call_id);
890 	pptp_peer_call_id_print(ndo, &ptr->peer_call_id);
891 	ND_TCHECK(ptr->reserved1);
892 	ND_TCHECK(ptr->send_accm);
893 	ND_PRINT((ndo, " SEND_ACCM(0x%08x)", EXTRACT_32BITS(&ptr->send_accm)));
894 	ND_TCHECK(ptr->recv_accm);
895 	ND_PRINT((ndo, " RECV_ACCM(0x%08x)", EXTRACT_32BITS(&ptr->recv_accm)));
896 
897 	return;
898 
899 trunc:
900 	ND_PRINT((ndo, "%s", tstr));
901 }
902 
903 void
904 pptp_print(netdissect_options *ndo,
905            const u_char *dat)
906 {
907 	const struct pptp_hdr *hdr;
908 	uint32_t mc;
909 	uint16_t ctrl_msg_type;
910 
911 	ND_PRINT((ndo, ": pptp"));
912 
913 	hdr = (const struct pptp_hdr *)dat;
914 
915 	ND_TCHECK(hdr->length);
916 	if (ndo->ndo_vflag) {
917 		ND_PRINT((ndo, " Length=%u", EXTRACT_16BITS(&hdr->length)));
918 	}
919 	ND_TCHECK(hdr->msg_type);
920 	if (ndo->ndo_vflag) {
921 		switch(EXTRACT_16BITS(&hdr->msg_type)) {
922 		case PPTP_MSG_TYPE_CTRL:
923 			ND_PRINT((ndo, " CTRL-MSG"));
924 			break;
925 		case PPTP_MSG_TYPE_MGMT:
926 			ND_PRINT((ndo, " MGMT-MSG"));
927 			break;
928 		default:
929 			ND_PRINT((ndo, " UNKNOWN-MSG-TYPE"));
930 			break;
931 		}
932 	}
933 
934 	ND_TCHECK(hdr->magic_cookie);
935 	mc = EXTRACT_32BITS(&hdr->magic_cookie);
936 	if (mc != PPTP_MAGIC_COOKIE) {
937 		ND_PRINT((ndo, " UNEXPECTED Magic-Cookie!!(%08x)", mc));
938 	}
939 	if (ndo->ndo_vflag || mc != PPTP_MAGIC_COOKIE) {
940 		ND_PRINT((ndo, " Magic-Cookie=%08x", mc));
941 	}
942 	ND_TCHECK(hdr->ctrl_msg_type);
943 	ctrl_msg_type = EXTRACT_16BITS(&hdr->ctrl_msg_type);
944 	if (ctrl_msg_type < PPTP_MAX_MSGTYPE_INDEX) {
945 		ND_PRINT((ndo, " CTRL_MSGTYPE=%s",
946 		       pptp_message_type_string[ctrl_msg_type]));
947 	} else {
948 		ND_PRINT((ndo, " UNKNOWN_CTRL_MSGTYPE(%u)", ctrl_msg_type));
949 	}
950 	ND_TCHECK(hdr->reserved0);
951 
952 	dat += 12;
953 
954 	switch(ctrl_msg_type) {
955 	case PPTP_CTRL_MSG_TYPE_SCCRQ:
956 		pptp_sccrq_print(ndo, dat);
957 		break;
958 	case PPTP_CTRL_MSG_TYPE_SCCRP:
959 		pptp_sccrp_print(ndo, dat);
960 		break;
961 	case PPTP_CTRL_MSG_TYPE_StopCCRQ:
962 		pptp_stopccrq_print(ndo, dat);
963 		break;
964 	case PPTP_CTRL_MSG_TYPE_StopCCRP:
965 		pptp_stopccrp_print(ndo, dat);
966 		break;
967 	case PPTP_CTRL_MSG_TYPE_ECHORQ:
968 		pptp_echorq_print(ndo, dat);
969 		break;
970 	case PPTP_CTRL_MSG_TYPE_ECHORP:
971 		pptp_echorp_print(ndo, dat);
972 		break;
973 	case PPTP_CTRL_MSG_TYPE_OCRQ:
974 		pptp_ocrq_print(ndo, dat);
975 		break;
976 	case PPTP_CTRL_MSG_TYPE_OCRP:
977 		pptp_ocrp_print(ndo, dat);
978 		break;
979 	case PPTP_CTRL_MSG_TYPE_ICRQ:
980 		pptp_icrq_print(ndo, dat);
981 		break;
982 	case PPTP_CTRL_MSG_TYPE_ICRP:
983 		pptp_icrp_print(ndo, dat);
984 		break;
985 	case PPTP_CTRL_MSG_TYPE_ICCN:
986 		pptp_iccn_print(ndo, dat);
987 		break;
988 	case PPTP_CTRL_MSG_TYPE_CCRQ:
989 		pptp_ccrq_print(ndo, dat);
990 		break;
991 	case PPTP_CTRL_MSG_TYPE_CDN:
992 		pptp_cdn_print(ndo, dat);
993 		break;
994 	case PPTP_CTRL_MSG_TYPE_WEN:
995 		pptp_wen_print(ndo, dat);
996 		break;
997 	case PPTP_CTRL_MSG_TYPE_SLI:
998 		pptp_sli_print(ndo, dat);
999 		break;
1000 	default:
1001 		/* do nothing */
1002 		break;
1003 	}
1004 
1005 	return;
1006 
1007 trunc:
1008 	ND_PRINT((ndo, "%s", tstr));
1009 }
1010