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