dhcpcd: update README.DRAGONFLY
[dragonfly.git] / contrib / tcpdump / print-pptp.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }