2 * Routines for the Point-to-Point Tunnelling Protocol (PPTP) (RFC 2637)
3 * Brad Robel-Forrest <brad.robel-forrest@watchguard.com>
5 * $Id: packet-pptp.c,v 1.23 2002/01/21 07:36:38 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
36 #ifdef HAVE_NETINET_IN_H
37 #include <netinet/in.h>
41 #include <epan/packet.h>
43 static int proto_pptp = -1;
44 static int hf_pptp_message_type = -1;
46 static gint ett_pptp = -1;
48 static dissector_handle_t data_handle;
50 #define TCP_PORT_PPTP 1723
52 #define MAGIC_COOKIE 0x1A2B3C4D
54 static const value_string msgtype_vals[] = {
55 { 1, "CONTROL-MESSAGE" },
56 { 2, "MANAGEMENT-MESSAGE" },
60 #define NUM_FRAME_TYPES 4
61 #define frametype2str(t) \
62 ((t < NUM_FRAME_TYPES) ? frametypestr[t] : "UNKNOWN-FRAMING-TYPE")
64 static const char *frametypestr[NUM_FRAME_TYPES] = {
65 "UNKNOWN-FRAMING-TYPE",
71 #define NUM_BEARER_TYPES 4
72 #define bearertype2str(t) \
73 ((t < NUM_BEARER_TYPES) ? bearertypestr[t] : "UNKNOWN-BEARER-TYPE")
75 static const char *bearertypestr[NUM_BEARER_TYPES] = {
76 "UNKNOWN-BEARER-TYPE",
82 #define NUM_CNTRLRESULT_TYPES 6
83 #define cntrlresulttype2str(t) \
84 ((t < NUM_CNTRLRESULT_TYPES) ? cntrlresulttypestr[t] : "UNKNOWN-CNTRLRESULT-TYPE")
86 static const char *cntrlresulttypestr[NUM_CNTRLRESULT_TYPES] = {
87 "UNKNOWN-CNTRLRESULT-TYPE",
90 "COMMAND-CHANNEL-EXISTS",
92 "VERSION-NOT-SUPPORTED"
95 #define NUM_ERROR_TYPES 7
96 #define errortype2str(t) \
97 ((t < NUM_ERROR_TYPES) ? errortypestr[t] : "UNKNOWN-ERROR-TYPE")
99 static const char *errortypestr[NUM_ERROR_TYPES] = {
109 #define NUM_REASON_TYPES 4
110 #define reasontype2str(t) \
111 ((t < NUM_REASON_TYPES) ? reasontypestr[t] : "UNKNOWN-REASON-TYPE")
113 static const char *reasontypestr[NUM_REASON_TYPES] = {
114 "UNKNOWN-REASON-TYPE",
117 "STOP-LOCAL-SHUTDOWN"
120 #define NUM_STOPRESULT_TYPES 3
121 #define stopresulttype2str(t) \
122 ((t < NUM_STOPRESULT_TYPES) ? stopresulttypestr[t] : "UNKNOWN-STOPRESULT-TYPE")
124 static const char *stopresulttypestr[NUM_STOPRESULT_TYPES] = {
125 "UNKNOWN-STOPRESULT-TYPE",
130 #define NUM_ECHORESULT_TYPES 3
131 #define echoresulttype2str(t) \
132 ((t < NUM_ECHORESULT_TYPES) ? echoresulttypestr[t] : "UNKNOWN-ECHORESULT-TYPE")
134 static const char *echoresulttypestr[NUM_ECHORESULT_TYPES] = {
135 "UNKNOWN-ECHORESULT-TYPE",
140 #define NUM_OUTRESULT_TYPES 8
141 #define outresulttype2str(t) \
142 ((t < NUM_OUTRESULT_TYPES) ? outresulttypestr[t] : "UNKNOWN-OUTRESULT-TYPE")
144 static const char *outresulttypestr[NUM_OUTRESULT_TYPES] = {
145 "UNKNOWN-OUTRESULT-TYPE",
155 #define NUM_INRESULT_TYPES 4
156 #define inresulttype2str(t) \
157 ((t < NUM_INRESULT_TYPES) ? inresulttypestr[t] : "UNKNOWN-INRESULT-TYPE")
159 static const char *inresulttypestr[NUM_INRESULT_TYPES] = {
160 "UNKNOWN-INRESULT-TYPE",
166 #define NUM_DISCRESULT_TYPES 5
167 #define discresulttype2str(t) \
168 ((t < NUM_DISCRESULT_TYPES) ? discresulttypestr[t] : "UNKNOWN-DISCRESULT-TYPE")
170 static const char *discresulttypestr[NUM_DISCRESULT_TYPES] = {
171 "UNKNOWN-DISCRESULT-TYPE",
178 static void dissect_unknown(tvbuff_t *, int, packet_info *, proto_tree *);
179 static void dissect_cntrl_req(tvbuff_t *, int, packet_info *, proto_tree *);
180 static void dissect_cntrl_reply(tvbuff_t *, int, packet_info *, proto_tree *);
181 static void dissect_stop_req(tvbuff_t *, int, packet_info *, proto_tree *);
182 static void dissect_stop_reply(tvbuff_t *, int, packet_info *, proto_tree *);
183 static void dissect_echo_req(tvbuff_t *, int, packet_info *, proto_tree *);
184 static void dissect_echo_reply(tvbuff_t *, int, packet_info *, proto_tree *);
185 static void dissect_out_req(tvbuff_t *, int, packet_info *, proto_tree *);
186 static void dissect_out_reply(tvbuff_t *, int, packet_info *, proto_tree *);
187 static void dissect_in_req(tvbuff_t *, int, packet_info *, proto_tree *);
188 static void dissect_in_reply(tvbuff_t *, int, packet_info *, proto_tree *);
189 static void dissect_in_connected(tvbuff_t *, int, packet_info *, proto_tree *);
190 static void dissect_clear_req(tvbuff_t *, int, packet_info *, proto_tree *);
191 static void dissect_disc_notify(tvbuff_t *, int, packet_info *, proto_tree *);
192 static void dissect_error_notify(tvbuff_t *, int, packet_info *, proto_tree *);
193 static void dissect_set_link(tvbuff_t *, int, packet_info *, proto_tree *);
195 #define NUM_CNTRL_TYPES 16
196 #define cntrltype2str(t) \
197 ((t < NUM_CNTRL_TYPES) ? strfuncs[t].str : "UNKNOWN-CONTROL-TYPE")
199 static struct strfunc {
201 void (*func)(tvbuff_t *, int, packet_info *, proto_tree *);
202 } strfuncs[NUM_CNTRL_TYPES] = {
203 {"UNKNOWN-CONTROL-TYPE", dissect_unknown },
204 {"START-CONTROL-REQUEST", dissect_cntrl_req },
205 {"START-CONTROL-REPLY", dissect_cntrl_reply },
206 {"STOP-CONTROL-REQUEST", dissect_stop_req },
207 {"STOP-CONTROL-REPLY", dissect_stop_reply },
208 {"ECHO-REQUEST", dissect_echo_req },
209 {"ECHO-REPLY", dissect_echo_reply },
210 {"OUTGOING-CALL-REQUEST", dissect_out_req },
211 {"OUTGOING-CALL-REPLY", dissect_out_reply },
212 {"INCOMING-CALL-REQUEST", dissect_in_req },
213 {"INCOMING-CALL-REPLY", dissect_in_reply },
214 {"INCOMING-CALL-CONNECTED", dissect_in_connected },
215 {"CLEAR-CALL-REQUEST", dissect_clear_req },
216 {"DISCONNECT-NOTIFY", dissect_disc_notify },
217 {"ERROR-NOTIFY", dissect_error_notify },
218 {"SET-LINK", dissect_set_link }
222 * Length of host name and vendor name strings in control requests and
229 * Length of phone number(s) and subaddress in call requests.
232 #define SUBADDRLEN 64
235 * Length of statistics in a Call-Disconnect-Notify message.
240 dissect_pptp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
246 if (check_col(pinfo->cinfo, COL_PROTOCOL))
247 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPTP");
248 if (check_col(pinfo->cinfo, COL_INFO))
249 col_clear(pinfo->cinfo, COL_INFO);
251 len = tvb_get_ntohs(tvb, offset);
252 cntrl_type = tvb_get_ntohs(tvb, offset + 8);
254 if (check_col(pinfo->cinfo, COL_INFO))
255 col_add_fstr(pinfo->cinfo, COL_INFO, "%s", cntrltype2str(cntrl_type));
260 proto_tree * pptp_tree;
262 ti = proto_tree_add_item(tree, proto_pptp, tvb, offset, len, FALSE);
263 pptp_tree = proto_item_add_subtree(ti, ett_pptp);
265 proto_tree_add_text(pptp_tree, tvb, offset, 2, "Length: %u", len);
268 proto_tree_add_item(pptp_tree, hf_pptp_message_type, tvb,
272 cookie = tvb_get_ntohl(tvb, offset);
274 if (cookie == MAGIC_COOKIE)
275 proto_tree_add_text(pptp_tree, tvb, offset, 4,
276 "Cookie: %#08x (correct)", cookie);
278 proto_tree_add_text(pptp_tree, tvb, offset, 4,
279 "Cookie: %#08x (incorrect)", cookie);
282 proto_tree_add_text(pptp_tree, tvb, offset, 2,
283 "Control type: %s (%u)", cntrltype2str(cntrl_type), cntrl_type);
286 proto_tree_add_text(pptp_tree, tvb, offset, 2,
287 "Reserved: %u", tvb_get_ntohs(tvb, offset));
290 if (cntrl_type < NUM_CNTRL_TYPES)
291 ( *(strfuncs[cntrl_type].func))(tvb, offset, pinfo, pptp_tree);
293 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,tvb_reported_length_remaining(tvb,offset)), pinfo, pptp_tree);
298 dissect_unknown(tvbuff_t *tvb, int offset, packet_info *pinfo,
301 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,tvb_reported_length_remaining(tvb,offset)), pinfo, tree);
305 dissect_cntrl_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
312 guint8 host[HOSTLEN+1];
313 guint8 vendor[VENDORLEN+1];
315 major_ver = tvb_get_guint8(tvb, offset);
316 minor_ver = tvb_get_guint8(tvb, offset + 1);
317 proto_tree_add_text(tree, tvb, offset, 2,
318 "Protocol version: %u.%u", major_ver, minor_ver);
321 proto_tree_add_text(tree, tvb, offset, 2,
322 "Reserved: %u", tvb_get_ntohs(tvb, offset));
325 frame = tvb_get_ntohl(tvb, offset);
326 proto_tree_add_text(tree, tvb, offset, 4,
327 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
330 bearer = tvb_get_ntohl(tvb, offset);
331 proto_tree_add_text(tree, tvb, offset, 4,
332 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
335 proto_tree_add_text(tree, tvb, offset, 2,
336 "Maximum channels: %u", tvb_get_ntohs(tvb, offset));
339 proto_tree_add_text(tree, tvb, offset, 2,
340 "Firmware revision: %u", tvb_get_ntohs(tvb, offset));
343 tvb_get_nstringz0(tvb, offset, HOSTLEN, host);
344 proto_tree_add_text(tree, tvb, offset, HOSTLEN,
345 "Hostname: %s", host);
348 tvb_get_nstringz0(tvb, offset, VENDORLEN, vendor);
349 proto_tree_add_text(tree, tvb, offset, VENDORLEN,
350 "Vendor: %s", vendor);
354 dissect_cntrl_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
363 guint8 host[HOSTLEN+1];
364 guint8 vendor[VENDORLEN+1];
366 major_ver = tvb_get_guint8(tvb, offset);
367 minor_ver = tvb_get_guint8(tvb, offset + 1);
368 proto_tree_add_text(tree, tvb, offset, 2,
369 "Protocol version: %u.%u", major_ver, minor_ver);
372 result = tvb_get_guint8(tvb, offset);
373 proto_tree_add_text(tree, tvb, offset, 1,
374 "Result: %s (%u)", cntrlresulttype2str(result), result);
377 error = tvb_get_guint8(tvb, offset);
378 proto_tree_add_text(tree, tvb, offset, 1,
379 "Error: %s (%u)", errortype2str(error), error);
382 frame = tvb_get_ntohl(tvb, offset);
383 proto_tree_add_text(tree, tvb, offset, 4,
384 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
387 bearer = tvb_get_ntohl(tvb, offset);
388 proto_tree_add_text(tree, tvb, offset, 4,
389 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
392 proto_tree_add_text(tree, tvb, offset, 2,
393 "Maximum channels: %u", tvb_get_ntohs(tvb, offset));
396 proto_tree_add_text(tree, tvb, offset, 2,
397 "Firmware revision: %u", tvb_get_ntohs(tvb, offset));
400 tvb_get_nstringz0(tvb, offset, HOSTLEN, host);
401 proto_tree_add_text(tree, tvb, offset, HOSTLEN,
402 "Hostname: %s", host);
405 tvb_get_nstringz0(tvb, offset, VENDORLEN, vendor);
406 proto_tree_add_text(tree, tvb, offset, VENDORLEN,
407 "Vendor: %s", vendor);
411 dissect_stop_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
416 reason = tvb_get_guint8(tvb, offset);
417 proto_tree_add_text(tree, tvb, offset, 1,
418 "Reason: %s (%u)", reasontype2str(reason), reason);
421 proto_tree_add_text(tree, tvb, offset, 1,
422 "Reserved: %u", tvb_get_guint8(tvb, offset));
425 proto_tree_add_text(tree, tvb, offset, 2,
426 "Reserved: %u", tvb_get_ntohs(tvb, offset));
430 dissect_stop_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
436 result = tvb_get_guint8(tvb, offset);
437 proto_tree_add_text(tree, tvb, offset, 1,
438 "Result: %s (%u)", stopresulttype2str(result), result);
441 error = tvb_get_guint8(tvb, offset);
442 proto_tree_add_text(tree, tvb, offset, 1,
443 "Error: %s (%u)", errortype2str(error), error);
446 proto_tree_add_text(tree, tvb, offset, 2,
447 "Reserved: %u", tvb_get_ntohs(tvb, offset));
451 dissect_echo_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
454 proto_tree_add_text(tree, tvb, offset, 4,
455 "Identifier: %u", tvb_get_ntohl(tvb, offset));
459 dissect_echo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
465 proto_tree_add_text(tree, tvb, offset, 4,
466 "Identifier: %u", tvb_get_ntohl(tvb, offset));
469 result = tvb_get_guint8(tvb, offset);
470 proto_tree_add_text(tree, tvb, offset, 1,
471 "Result: %s (%u)", echoresulttype2str(result), result);
474 error = tvb_get_guint8(tvb, offset);
475 proto_tree_add_text(tree, tvb, offset, sizeof(error),
476 "Error: %s (%u)", errortype2str(error), error);
479 proto_tree_add_text(tree, tvb, offset, 2,
480 "Reserved: %u", tvb_get_ntohs(tvb, offset));
484 dissect_out_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
489 guint8 phone[PHONELEN+1];
490 guint8 subaddr[SUBADDRLEN+1];
492 proto_tree_add_text(tree, tvb, offset, 2,
493 "Call ID: %u", tvb_get_ntohs(tvb, offset));
496 proto_tree_add_text(tree, tvb, offset, 2,
497 "Call Serial Number: %u", tvb_get_ntohs(tvb, offset));
500 proto_tree_add_text(tree, tvb, offset, 4,
501 "Minimum BPS: %u", tvb_get_ntohl(tvb, offset));
504 proto_tree_add_text(tree, tvb, offset, 4,
505 "Maximum BPS: %u", tvb_get_ntohl(tvb, offset));
508 bearer = tvb_get_ntohl(tvb, offset);
509 proto_tree_add_text(tree, tvb, offset, 4,
510 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
513 frame = tvb_get_ntohl(tvb, offset);
514 proto_tree_add_text(tree, tvb, offset, 4,
515 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
518 proto_tree_add_text(tree, tvb, offset, 2,
519 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
522 proto_tree_add_text(tree, tvb, offset, 2,
523 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
526 proto_tree_add_text(tree, tvb, offset, 2,
527 "Phone number length: %u", tvb_get_ntohs(tvb, offset));
530 proto_tree_add_text(tree, tvb, offset, 2,
531 "Reserved: %u", tvb_get_ntohs(tvb, offset));
534 tvb_get_nstringz0(tvb, offset, PHONELEN, phone);
535 proto_tree_add_text(tree, tvb, offset, PHONELEN,
536 "Phone number: %s", phone);
539 tvb_get_nstringz0(tvb, offset, SUBADDRLEN, subaddr);
540 proto_tree_add_text(tree, tvb, offset, SUBADDRLEN,
541 "Subaddress: %s", subaddr);
545 dissect_out_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
551 proto_tree_add_text(tree, tvb, offset, 2,
552 "Call ID: %u", tvb_get_ntohs(tvb, offset));
555 proto_tree_add_text(tree, tvb, offset, 2,
556 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
559 result = tvb_get_guint8(tvb, offset);
560 proto_tree_add_text(tree, tvb, offset, 1,
561 "Result: %s (%u)", outresulttype2str(result), result);
564 error = tvb_get_guint8(tvb, offset);
565 proto_tree_add_text(tree, tvb, offset, 1,
566 "Error: %s (%u)", errortype2str(error), error);
569 proto_tree_add_text(tree, tvb, offset, 2,
570 "Cause code: %u", tvb_get_ntohs(tvb, offset));
573 proto_tree_add_text(tree, tvb, offset, 4,
574 "Connect speed: %u", tvb_get_ntohl(tvb, offset));
577 proto_tree_add_text(tree, tvb, offset, 2,
578 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
581 proto_tree_add_text(tree, tvb, offset, 2,
582 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
585 proto_tree_add_text(tree, tvb, offset, 4,
586 "Physical channel ID: %u", tvb_get_ntohl(tvb, offset));
590 dissect_in_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
594 guint8 dialed[PHONELEN+1];
595 guint8 dialing[PHONELEN+1];
596 guint8 subaddr[SUBADDRLEN+1];
598 proto_tree_add_text(tree, tvb, offset, 2,
599 "Call ID: %u", tvb_get_ntohs(tvb, offset));
602 proto_tree_add_text(tree, tvb, offset, 2,
603 "Call serial number: %u", tvb_get_ntohs(tvb, offset));
606 bearer = tvb_get_ntohl(tvb, offset);
607 proto_tree_add_text(tree, tvb, offset, 4,
608 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
611 proto_tree_add_text(tree, tvb, offset, 4,
612 "Physical channel ID: %u", tvb_get_ntohl(tvb, offset));
615 proto_tree_add_text(tree, tvb, offset, 2,
616 "Dialed number length: %u", tvb_get_ntohs(tvb, offset));
619 proto_tree_add_text(tree, tvb, offset, 2,
620 "Dialing number length: %u", tvb_get_ntohs(tvb, offset));
623 tvb_get_nstringz0(tvb, offset, PHONELEN, dialed);
624 proto_tree_add_text(tree, tvb, offset, PHONELEN,
625 "Dialed number: %s", dialed);
628 tvb_get_nstringz0(tvb, offset, PHONELEN, dialing);
629 proto_tree_add_text(tree, tvb, offset, PHONELEN,
630 "Dialing number: %s", dialing);
633 tvb_get_nstringz0(tvb, offset, SUBADDRLEN, subaddr);
634 proto_tree_add_text(tree, tvb, offset, SUBADDRLEN,
635 "Subaddress: %s", subaddr);
639 dissect_in_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
645 proto_tree_add_text(tree, tvb, offset, 2,
646 "Call ID: %u", tvb_get_ntohs(tvb, offset));
649 proto_tree_add_text(tree, tvb, offset, 2,
650 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
653 result = tvb_get_guint8(tvb, offset);
654 proto_tree_add_text(tree, tvb, offset, 1,
655 "Result: %s (%u)", inresulttype2str(result), result);
658 error = tvb_get_guint8(tvb, offset);
659 proto_tree_add_text(tree, tvb, offset, 1,
660 "Error: %s (%u)", errortype2str(error), error);
663 proto_tree_add_text(tree, tvb, offset, 2,
664 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
667 proto_tree_add_text(tree, tvb, offset, 2,
668 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
671 proto_tree_add_text(tree, tvb, offset, 2,
672 "Reserved: %u", tvb_get_ntohs(tvb, offset));
676 dissect_in_connected(tvbuff_t *tvb, int offset, packet_info *pinfo,
681 proto_tree_add_text(tree, tvb, offset, 2,
682 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
685 proto_tree_add_text(tree, tvb, offset, 2,
686 "Reserved: %u", tvb_get_ntohs(tvb, offset));
689 proto_tree_add_text(tree, tvb, offset, 4,
690 "Connect speed: %u", tvb_get_ntohl(tvb, offset));
693 proto_tree_add_text(tree, tvb, offset, 2,
694 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
697 proto_tree_add_text(tree, tvb, offset, 2,
698 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
701 frame = tvb_get_ntohl(tvb, offset);
702 proto_tree_add_text(tree, tvb, offset, 4,
703 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
707 dissect_clear_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
710 proto_tree_add_text(tree, tvb, offset, 2,
711 "Call ID: %u", tvb_get_ntohs(tvb, offset));
714 proto_tree_add_text(tree, tvb, offset, 2,
715 "Reserved: %u", tvb_get_ntohs(tvb, offset));
719 dissect_disc_notify(tvbuff_t *tvb, int offset, packet_info *pinfo,
724 guint8 stats[STATSLEN+1];
726 proto_tree_add_text(tree, tvb, offset, 2,
727 "Call ID: %u", tvb_get_ntohs(tvb, offset));
730 result = tvb_get_guint8(tvb, offset);
731 proto_tree_add_text(tree, tvb, offset, 1,
732 "Result: %s (%u)", discresulttype2str(result), result);
735 error = tvb_get_guint8(tvb, offset);
736 proto_tree_add_text(tree, tvb, offset, 1,
737 "Error: %s (%u)", errortype2str(error), error);
740 proto_tree_add_text(tree, tvb, offset, 2,
741 "Cause code: %u", tvb_get_ntohs(tvb, offset));
744 proto_tree_add_text(tree, tvb, offset, 2,
745 "Reserved: %u", tvb_get_ntohs(tvb, offset));
748 tvb_get_nstringz0(tvb, offset, STATSLEN, stats);
749 proto_tree_add_text(tree, tvb, offset, STATSLEN,
750 "Call statistics: %s", stats);
754 dissect_error_notify(tvbuff_t *tvb, int offset, packet_info *pinfo,
757 proto_tree_add_text(tree, tvb, offset, 2,
758 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
761 proto_tree_add_text(tree, tvb, offset, 2,
762 "Reserved: %u", tvb_get_ntohs(tvb, offset));
765 proto_tree_add_text(tree, tvb, offset, 4,
766 "CRC errors: %u", tvb_get_ntohl(tvb, offset));
769 proto_tree_add_text(tree, tvb, offset, 4,
770 "Framing errors: %u", tvb_get_ntohl(tvb, offset));
773 proto_tree_add_text(tree, tvb, offset, 4,
774 "Hardware overruns: %u", tvb_get_ntohl(tvb, offset));
777 proto_tree_add_text(tree, tvb, offset, 4,
778 "Buffer overruns: %u", tvb_get_ntohl(tvb, offset));
781 proto_tree_add_text(tree, tvb, offset, 4,
782 "Time-out errors: %u", tvb_get_ntohl(tvb, offset));
785 proto_tree_add_text(tree, tvb, offset, 4,
786 "Alignment errors: %u", tvb_get_ntohl(tvb, offset));
790 dissect_set_link(tvbuff_t *tvb, int offset, packet_info *pinfo,
793 proto_tree_add_text(tree, tvb, offset, 2,
794 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
797 proto_tree_add_text(tree, tvb, offset, 2,
798 "Reserved: %u", tvb_get_ntohs(tvb, offset));
801 proto_tree_add_text(tree, tvb, offset, 4,
802 "Send ACCM: %#08x", tvb_get_ntohl(tvb, offset));
805 proto_tree_add_text(tree, tvb, offset, 4,
806 "Recv ACCM: %#08x", tvb_get_ntohl(tvb, offset));
810 proto_register_pptp(void)
812 static gint *ett[] = {
816 static hf_register_info hf[] = {
817 { &hf_pptp_message_type,
818 { "Message type", "pptp.type",
819 FT_UINT16, BASE_DEC, VALS(msgtype_vals), 0x0,
820 "PPTP message type", HFILL }}
823 proto_pptp = proto_register_protocol("Point-to-Point Tunnelling Protocol",
825 proto_register_field_array(proto_pptp, hf, array_length(hf));
826 proto_register_subtree_array(ett, array_length(ett));
830 proto_reg_handoff_pptp(void)
832 dissector_handle_t pptp_handle;
834 pptp_handle = create_dissector_handle(dissect_pptp, proto_pptp);
835 dissector_add("tcp.port", TCP_PORT_PPTP, pptp_handle);
836 data_handle = find_dissector("data");