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