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