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