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.26 2002/08/28 21:00:25 jmayer 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.
33 #include <epan/packet.h>
35 static int proto_pptp = -1;
36 static int hf_pptp_message_type = -1;
38 static gint ett_pptp = -1;
40 static dissector_handle_t data_handle;
42 #define TCP_PORT_PPTP 1723
44 #define MAGIC_COOKIE 0x1A2B3C4D
46 static const value_string msgtype_vals[] = {
47 { 1, "CONTROL-MESSAGE" },
48 { 2, "MANAGEMENT-MESSAGE" },
52 #define NUM_FRAME_TYPES 4
53 #define frametype2str(t) \
54 ((t < NUM_FRAME_TYPES) ? frametypestr[t] : "UNKNOWN-FRAMING-TYPE")
56 static const char *frametypestr[NUM_FRAME_TYPES] = {
57 "UNKNOWN-FRAMING-TYPE",
63 #define NUM_BEARER_TYPES 4
64 #define bearertype2str(t) \
65 ((t < NUM_BEARER_TYPES) ? bearertypestr[t] : "UNKNOWN-BEARER-TYPE")
67 static const char *bearertypestr[NUM_BEARER_TYPES] = {
68 "UNKNOWN-BEARER-TYPE",
74 #define NUM_CNTRLRESULT_TYPES 6
75 #define cntrlresulttype2str(t) \
76 ((t < NUM_CNTRLRESULT_TYPES) ? cntrlresulttypestr[t] : "UNKNOWN-CNTRLRESULT-TYPE")
78 static const char *cntrlresulttypestr[NUM_CNTRLRESULT_TYPES] = {
79 "UNKNOWN-CNTRLRESULT-TYPE",
82 "COMMAND-CHANNEL-EXISTS",
84 "VERSION-NOT-SUPPORTED"
87 #define NUM_ERROR_TYPES 7
88 #define errortype2str(t) \
89 ((t < NUM_ERROR_TYPES) ? errortypestr[t] : "UNKNOWN-ERROR-TYPE")
91 static const char *errortypestr[NUM_ERROR_TYPES] = {
101 #define NUM_REASON_TYPES 4
102 #define reasontype2str(t) \
103 ((t < NUM_REASON_TYPES) ? reasontypestr[t] : "UNKNOWN-REASON-TYPE")
105 static const char *reasontypestr[NUM_REASON_TYPES] = {
106 "UNKNOWN-REASON-TYPE",
109 "STOP-LOCAL-SHUTDOWN"
112 #define NUM_STOPRESULT_TYPES 3
113 #define stopresulttype2str(t) \
114 ((t < NUM_STOPRESULT_TYPES) ? stopresulttypestr[t] : "UNKNOWN-STOPRESULT-TYPE")
116 static const char *stopresulttypestr[NUM_STOPRESULT_TYPES] = {
117 "UNKNOWN-STOPRESULT-TYPE",
122 #define NUM_ECHORESULT_TYPES 3
123 #define echoresulttype2str(t) \
124 ((t < NUM_ECHORESULT_TYPES) ? echoresulttypestr[t] : "UNKNOWN-ECHORESULT-TYPE")
126 static const char *echoresulttypestr[NUM_ECHORESULT_TYPES] = {
127 "UNKNOWN-ECHORESULT-TYPE",
132 #define NUM_OUTRESULT_TYPES 8
133 #define outresulttype2str(t) \
134 ((t < NUM_OUTRESULT_TYPES) ? outresulttypestr[t] : "UNKNOWN-OUTRESULT-TYPE")
136 static const char *outresulttypestr[NUM_OUTRESULT_TYPES] = {
137 "UNKNOWN-OUTRESULT-TYPE",
147 #define NUM_INRESULT_TYPES 4
148 #define inresulttype2str(t) \
149 ((t < NUM_INRESULT_TYPES) ? inresulttypestr[t] : "UNKNOWN-INRESULT-TYPE")
151 static const char *inresulttypestr[NUM_INRESULT_TYPES] = {
152 "UNKNOWN-INRESULT-TYPE",
158 #define NUM_DISCRESULT_TYPES 5
159 #define discresulttype2str(t) \
160 ((t < NUM_DISCRESULT_TYPES) ? discresulttypestr[t] : "UNKNOWN-DISCRESULT-TYPE")
162 static const char *discresulttypestr[NUM_DISCRESULT_TYPES] = {
163 "UNKNOWN-DISCRESULT-TYPE",
170 static void dissect_unknown(tvbuff_t *, int, packet_info *, proto_tree *);
171 static void dissect_cntrl_req(tvbuff_t *, int, packet_info *, proto_tree *);
172 static void dissect_cntrl_reply(tvbuff_t *, int, packet_info *, proto_tree *);
173 static void dissect_stop_req(tvbuff_t *, int, packet_info *, proto_tree *);
174 static void dissect_stop_reply(tvbuff_t *, int, packet_info *, proto_tree *);
175 static void dissect_echo_req(tvbuff_t *, int, packet_info *, proto_tree *);
176 static void dissect_echo_reply(tvbuff_t *, int, packet_info *, proto_tree *);
177 static void dissect_out_req(tvbuff_t *, int, packet_info *, proto_tree *);
178 static void dissect_out_reply(tvbuff_t *, int, packet_info *, proto_tree *);
179 static void dissect_in_req(tvbuff_t *, int, packet_info *, proto_tree *);
180 static void dissect_in_reply(tvbuff_t *, int, packet_info *, proto_tree *);
181 static void dissect_in_connected(tvbuff_t *, int, packet_info *, proto_tree *);
182 static void dissect_clear_req(tvbuff_t *, int, packet_info *, proto_tree *);
183 static void dissect_disc_notify(tvbuff_t *, int, packet_info *, proto_tree *);
184 static void dissect_error_notify(tvbuff_t *, int, packet_info *, proto_tree *);
185 static void dissect_set_link(tvbuff_t *, int, packet_info *, proto_tree *);
187 #define NUM_CNTRL_TYPES 16
188 #define cntrltype2str(t) \
189 ((t < NUM_CNTRL_TYPES) ? strfuncs[t].str : "UNKNOWN-CONTROL-TYPE")
191 static struct strfunc {
193 void (*func)(tvbuff_t *, int, packet_info *, proto_tree *);
194 } strfuncs[NUM_CNTRL_TYPES] = {
195 {"UNKNOWN-CONTROL-TYPE", dissect_unknown },
196 {"START-CONTROL-REQUEST", dissect_cntrl_req },
197 {"START-CONTROL-REPLY", dissect_cntrl_reply },
198 {"STOP-CONTROL-REQUEST", dissect_stop_req },
199 {"STOP-CONTROL-REPLY", dissect_stop_reply },
200 {"ECHO-REQUEST", dissect_echo_req },
201 {"ECHO-REPLY", dissect_echo_reply },
202 {"OUTGOING-CALL-REQUEST", dissect_out_req },
203 {"OUTGOING-CALL-REPLY", dissect_out_reply },
204 {"INCOMING-CALL-REQUEST", dissect_in_req },
205 {"INCOMING-CALL-REPLY", dissect_in_reply },
206 {"INCOMING-CALL-CONNECTED", dissect_in_connected },
207 {"CLEAR-CALL-REQUEST", dissect_clear_req },
208 {"DISCONNECT-NOTIFY", dissect_disc_notify },
209 {"ERROR-NOTIFY", dissect_error_notify },
210 {"SET-LINK", dissect_set_link }
214 * Length of host name and vendor name strings in control requests and
221 * Length of phone number(s) and subaddress in call requests.
224 #define SUBADDRLEN 64
227 * Length of statistics in a Call-Disconnect-Notify message.
232 dissect_pptp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
238 if (check_col(pinfo->cinfo, COL_PROTOCOL))
239 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPTP");
240 if (check_col(pinfo->cinfo, COL_INFO))
241 col_clear(pinfo->cinfo, COL_INFO);
243 len = tvb_get_ntohs(tvb, offset);
244 cntrl_type = tvb_get_ntohs(tvb, offset + 8);
246 if (check_col(pinfo->cinfo, COL_INFO))
247 col_add_fstr(pinfo->cinfo, COL_INFO, "%s", cntrltype2str(cntrl_type));
252 proto_tree * pptp_tree;
254 ti = proto_tree_add_item(tree, proto_pptp, tvb, offset, len, FALSE);
255 pptp_tree = proto_item_add_subtree(ti, ett_pptp);
257 proto_tree_add_text(pptp_tree, tvb, offset, 2, "Length: %u", len);
260 proto_tree_add_item(pptp_tree, hf_pptp_message_type, tvb,
264 cookie = tvb_get_ntohl(tvb, offset);
266 if (cookie == MAGIC_COOKIE)
267 proto_tree_add_text(pptp_tree, tvb, offset, 4,
268 "Cookie: %#08x (correct)", cookie);
270 proto_tree_add_text(pptp_tree, tvb, offset, 4,
271 "Cookie: %#08x (incorrect)", cookie);
274 proto_tree_add_text(pptp_tree, tvb, offset, 2,
275 "Control type: %s (%u)", cntrltype2str(cntrl_type), cntrl_type);
278 proto_tree_add_text(pptp_tree, tvb, offset, 2,
279 "Reserved: %u", tvb_get_ntohs(tvb, offset));
282 if (cntrl_type < NUM_CNTRL_TYPES)
283 ( *(strfuncs[cntrl_type].func))(tvb, offset, pinfo, pptp_tree);
285 call_dissector(data_handle,tvb_new_subset(tvb, offset, -1, -1), pinfo, pptp_tree);
290 dissect_unknown(tvbuff_t *tvb, int offset, packet_info *pinfo,
293 call_dissector(data_handle,tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
297 dissect_cntrl_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
304 guint8 host[HOSTLEN+1];
305 guint8 vendor[VENDORLEN+1];
307 major_ver = tvb_get_guint8(tvb, offset);
308 minor_ver = tvb_get_guint8(tvb, offset + 1);
309 proto_tree_add_text(tree, tvb, offset, 2,
310 "Protocol version: %u.%u", major_ver, minor_ver);
313 proto_tree_add_text(tree, tvb, offset, 2,
314 "Reserved: %u", tvb_get_ntohs(tvb, offset));
317 frame = tvb_get_ntohl(tvb, offset);
318 proto_tree_add_text(tree, tvb, offset, 4,
319 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
322 bearer = tvb_get_ntohl(tvb, offset);
323 proto_tree_add_text(tree, tvb, offset, 4,
324 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
327 proto_tree_add_text(tree, tvb, offset, 2,
328 "Maximum channels: %u", tvb_get_ntohs(tvb, offset));
331 proto_tree_add_text(tree, tvb, offset, 2,
332 "Firmware revision: %u", tvb_get_ntohs(tvb, offset));
335 tvb_get_nstringz0(tvb, offset, HOSTLEN, host);
336 proto_tree_add_text(tree, tvb, offset, HOSTLEN,
337 "Hostname: %s", host);
340 tvb_get_nstringz0(tvb, offset, VENDORLEN, vendor);
341 proto_tree_add_text(tree, tvb, offset, VENDORLEN,
342 "Vendor: %s", vendor);
346 dissect_cntrl_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
355 guint8 host[HOSTLEN+1];
356 guint8 vendor[VENDORLEN+1];
358 major_ver = tvb_get_guint8(tvb, offset);
359 minor_ver = tvb_get_guint8(tvb, offset + 1);
360 proto_tree_add_text(tree, tvb, offset, 2,
361 "Protocol version: %u.%u", major_ver, minor_ver);
364 result = tvb_get_guint8(tvb, offset);
365 proto_tree_add_text(tree, tvb, offset, 1,
366 "Result: %s (%u)", cntrlresulttype2str(result), result);
369 error = tvb_get_guint8(tvb, offset);
370 proto_tree_add_text(tree, tvb, offset, 1,
371 "Error: %s (%u)", errortype2str(error), error);
374 frame = tvb_get_ntohl(tvb, offset);
375 proto_tree_add_text(tree, tvb, offset, 4,
376 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
379 bearer = tvb_get_ntohl(tvb, offset);
380 proto_tree_add_text(tree, tvb, offset, 4,
381 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
384 proto_tree_add_text(tree, tvb, offset, 2,
385 "Maximum channels: %u", tvb_get_ntohs(tvb, offset));
388 proto_tree_add_text(tree, tvb, offset, 2,
389 "Firmware revision: %u", tvb_get_ntohs(tvb, offset));
392 tvb_get_nstringz0(tvb, offset, HOSTLEN, host);
393 proto_tree_add_text(tree, tvb, offset, HOSTLEN,
394 "Hostname: %s", host);
397 tvb_get_nstringz0(tvb, offset, VENDORLEN, vendor);
398 proto_tree_add_text(tree, tvb, offset, VENDORLEN,
399 "Vendor: %s", vendor);
403 dissect_stop_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
408 reason = tvb_get_guint8(tvb, offset);
409 proto_tree_add_text(tree, tvb, offset, 1,
410 "Reason: %s (%u)", reasontype2str(reason), reason);
413 proto_tree_add_text(tree, tvb, offset, 1,
414 "Reserved: %u", tvb_get_guint8(tvb, offset));
417 proto_tree_add_text(tree, tvb, offset, 2,
418 "Reserved: %u", tvb_get_ntohs(tvb, offset));
422 dissect_stop_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
428 result = tvb_get_guint8(tvb, offset);
429 proto_tree_add_text(tree, tvb, offset, 1,
430 "Result: %s (%u)", stopresulttype2str(result), result);
433 error = tvb_get_guint8(tvb, offset);
434 proto_tree_add_text(tree, tvb, offset, 1,
435 "Error: %s (%u)", errortype2str(error), error);
438 proto_tree_add_text(tree, tvb, offset, 2,
439 "Reserved: %u", tvb_get_ntohs(tvb, offset));
443 dissect_echo_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
446 proto_tree_add_text(tree, tvb, offset, 4,
447 "Identifier: %u", tvb_get_ntohl(tvb, offset));
451 dissect_echo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
457 proto_tree_add_text(tree, tvb, offset, 4,
458 "Identifier: %u", tvb_get_ntohl(tvb, offset));
461 result = tvb_get_guint8(tvb, offset);
462 proto_tree_add_text(tree, tvb, offset, 1,
463 "Result: %s (%u)", echoresulttype2str(result), result);
466 error = tvb_get_guint8(tvb, offset);
467 proto_tree_add_text(tree, tvb, offset, sizeof(error),
468 "Error: %s (%u)", errortype2str(error), error);
471 proto_tree_add_text(tree, tvb, offset, 2,
472 "Reserved: %u", tvb_get_ntohs(tvb, offset));
476 dissect_out_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
481 guint8 phone[PHONELEN+1];
482 guint8 subaddr[SUBADDRLEN+1];
484 proto_tree_add_text(tree, tvb, offset, 2,
485 "Call ID: %u", tvb_get_ntohs(tvb, offset));
488 proto_tree_add_text(tree, tvb, offset, 2,
489 "Call Serial Number: %u", tvb_get_ntohs(tvb, offset));
492 proto_tree_add_text(tree, tvb, offset, 4,
493 "Minimum BPS: %u", tvb_get_ntohl(tvb, offset));
496 proto_tree_add_text(tree, tvb, offset, 4,
497 "Maximum BPS: %u", tvb_get_ntohl(tvb, offset));
500 bearer = tvb_get_ntohl(tvb, offset);
501 proto_tree_add_text(tree, tvb, offset, 4,
502 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
505 frame = tvb_get_ntohl(tvb, offset);
506 proto_tree_add_text(tree, tvb, offset, 4,
507 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
510 proto_tree_add_text(tree, tvb, offset, 2,
511 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
514 proto_tree_add_text(tree, tvb, offset, 2,
515 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
518 proto_tree_add_text(tree, tvb, offset, 2,
519 "Phone number length: %u", tvb_get_ntohs(tvb, offset));
522 proto_tree_add_text(tree, tvb, offset, 2,
523 "Reserved: %u", tvb_get_ntohs(tvb, offset));
526 tvb_get_nstringz0(tvb, offset, PHONELEN, phone);
527 proto_tree_add_text(tree, tvb, offset, PHONELEN,
528 "Phone number: %s", phone);
531 tvb_get_nstringz0(tvb, offset, SUBADDRLEN, subaddr);
532 proto_tree_add_text(tree, tvb, offset, SUBADDRLEN,
533 "Subaddress: %s", subaddr);
537 dissect_out_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
543 proto_tree_add_text(tree, tvb, offset, 2,
544 "Call ID: %u", tvb_get_ntohs(tvb, offset));
547 proto_tree_add_text(tree, tvb, offset, 2,
548 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
551 result = tvb_get_guint8(tvb, offset);
552 proto_tree_add_text(tree, tvb, offset, 1,
553 "Result: %s (%u)", outresulttype2str(result), result);
556 error = tvb_get_guint8(tvb, offset);
557 proto_tree_add_text(tree, tvb, offset, 1,
558 "Error: %s (%u)", errortype2str(error), error);
561 proto_tree_add_text(tree, tvb, offset, 2,
562 "Cause code: %u", tvb_get_ntohs(tvb, offset));
565 proto_tree_add_text(tree, tvb, offset, 4,
566 "Connect speed: %u", tvb_get_ntohl(tvb, offset));
569 proto_tree_add_text(tree, tvb, offset, 2,
570 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
573 proto_tree_add_text(tree, tvb, offset, 2,
574 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
577 proto_tree_add_text(tree, tvb, offset, 4,
578 "Physical channel ID: %u", tvb_get_ntohl(tvb, offset));
582 dissect_in_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
586 guint8 dialed[PHONELEN+1];
587 guint8 dialing[PHONELEN+1];
588 guint8 subaddr[SUBADDRLEN+1];
590 proto_tree_add_text(tree, tvb, offset, 2,
591 "Call ID: %u", tvb_get_ntohs(tvb, offset));
594 proto_tree_add_text(tree, tvb, offset, 2,
595 "Call serial number: %u", tvb_get_ntohs(tvb, offset));
598 bearer = tvb_get_ntohl(tvb, offset);
599 proto_tree_add_text(tree, tvb, offset, 4,
600 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
603 proto_tree_add_text(tree, tvb, offset, 4,
604 "Physical channel ID: %u", tvb_get_ntohl(tvb, offset));
607 proto_tree_add_text(tree, tvb, offset, 2,
608 "Dialed number length: %u", tvb_get_ntohs(tvb, offset));
611 proto_tree_add_text(tree, tvb, offset, 2,
612 "Dialing number length: %u", tvb_get_ntohs(tvb, offset));
615 tvb_get_nstringz0(tvb, offset, PHONELEN, dialed);
616 proto_tree_add_text(tree, tvb, offset, PHONELEN,
617 "Dialed number: %s", dialed);
620 tvb_get_nstringz0(tvb, offset, PHONELEN, dialing);
621 proto_tree_add_text(tree, tvb, offset, PHONELEN,
622 "Dialing number: %s", dialing);
625 tvb_get_nstringz0(tvb, offset, SUBADDRLEN, subaddr);
626 proto_tree_add_text(tree, tvb, offset, SUBADDRLEN,
627 "Subaddress: %s", subaddr);
631 dissect_in_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
637 proto_tree_add_text(tree, tvb, offset, 2,
638 "Call ID: %u", tvb_get_ntohs(tvb, offset));
641 proto_tree_add_text(tree, tvb, offset, 2,
642 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
645 result = tvb_get_guint8(tvb, offset);
646 proto_tree_add_text(tree, tvb, offset, 1,
647 "Result: %s (%u)", inresulttype2str(result), result);
650 error = tvb_get_guint8(tvb, offset);
651 proto_tree_add_text(tree, tvb, offset, 1,
652 "Error: %s (%u)", errortype2str(error), error);
655 proto_tree_add_text(tree, tvb, offset, 2,
656 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
659 proto_tree_add_text(tree, tvb, offset, 2,
660 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
663 proto_tree_add_text(tree, tvb, offset, 2,
664 "Reserved: %u", tvb_get_ntohs(tvb, offset));
668 dissect_in_connected(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
673 proto_tree_add_text(tree, tvb, offset, 2,
674 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
677 proto_tree_add_text(tree, tvb, offset, 2,
678 "Reserved: %u", tvb_get_ntohs(tvb, offset));
681 proto_tree_add_text(tree, tvb, offset, 4,
682 "Connect speed: %u", tvb_get_ntohl(tvb, offset));
685 proto_tree_add_text(tree, tvb, offset, 2,
686 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
689 proto_tree_add_text(tree, tvb, offset, 2,
690 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
693 frame = tvb_get_ntohl(tvb, offset);
694 proto_tree_add_text(tree, tvb, offset, 4,
695 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
699 dissect_clear_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
702 proto_tree_add_text(tree, tvb, offset, 2,
703 "Call ID: %u", tvb_get_ntohs(tvb, offset));
706 proto_tree_add_text(tree, tvb, offset, 2,
707 "Reserved: %u", tvb_get_ntohs(tvb, offset));
711 dissect_disc_notify(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
716 guint8 stats[STATSLEN+1];
718 proto_tree_add_text(tree, tvb, offset, 2,
719 "Call ID: %u", tvb_get_ntohs(tvb, offset));
722 result = tvb_get_guint8(tvb, offset);
723 proto_tree_add_text(tree, tvb, offset, 1,
724 "Result: %s (%u)", discresulttype2str(result), result);
727 error = tvb_get_guint8(tvb, offset);
728 proto_tree_add_text(tree, tvb, offset, 1,
729 "Error: %s (%u)", errortype2str(error), error);
732 proto_tree_add_text(tree, tvb, offset, 2,
733 "Cause code: %u", tvb_get_ntohs(tvb, offset));
736 proto_tree_add_text(tree, tvb, offset, 2,
737 "Reserved: %u", tvb_get_ntohs(tvb, offset));
740 tvb_get_nstringz0(tvb, offset, STATSLEN, stats);
741 proto_tree_add_text(tree, tvb, offset, STATSLEN,
742 "Call statistics: %s", stats);
746 dissect_error_notify(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
749 proto_tree_add_text(tree, tvb, offset, 2,
750 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
753 proto_tree_add_text(tree, tvb, offset, 2,
754 "Reserved: %u", tvb_get_ntohs(tvb, offset));
757 proto_tree_add_text(tree, tvb, offset, 4,
758 "CRC errors: %u", tvb_get_ntohl(tvb, offset));
761 proto_tree_add_text(tree, tvb, offset, 4,
762 "Framing errors: %u", tvb_get_ntohl(tvb, offset));
765 proto_tree_add_text(tree, tvb, offset, 4,
766 "Hardware overruns: %u", tvb_get_ntohl(tvb, offset));
769 proto_tree_add_text(tree, tvb, offset, 4,
770 "Buffer overruns: %u", tvb_get_ntohl(tvb, offset));
773 proto_tree_add_text(tree, tvb, offset, 4,
774 "Time-out errors: %u", tvb_get_ntohl(tvb, offset));
777 proto_tree_add_text(tree, tvb, offset, 4,
778 "Alignment errors: %u", tvb_get_ntohl(tvb, offset));
782 dissect_set_link(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
785 proto_tree_add_text(tree, tvb, offset, 2,
786 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
789 proto_tree_add_text(tree, tvb, offset, 2,
790 "Reserved: %u", tvb_get_ntohs(tvb, offset));
793 proto_tree_add_text(tree, tvb, offset, 4,
794 "Send ACCM: %#08x", tvb_get_ntohl(tvb, offset));
797 proto_tree_add_text(tree, tvb, offset, 4,
798 "Recv ACCM: %#08x", tvb_get_ntohl(tvb, offset));
802 proto_register_pptp(void)
804 static gint *ett[] = {
808 static hf_register_info hf[] = {
809 { &hf_pptp_message_type,
810 { "Message type", "pptp.type",
811 FT_UINT16, BASE_DEC, VALS(msgtype_vals), 0x0,
812 "PPTP message type", HFILL }}
815 proto_pptp = proto_register_protocol("Point-to-Point Tunnelling Protocol",
817 proto_register_field_array(proto_pptp, hf, array_length(hf));
818 proto_register_subtree_array(ett, array_length(ett));
822 proto_reg_handoff_pptp(void)
824 dissector_handle_t pptp_handle;
826 pptp_handle = create_dissector_handle(dissect_pptp, proto_pptp);
827 dissector_add("tcp.port", TCP_PORT_PPTP, pptp_handle);
828 data_handle = find_dissector("data");