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.29 2003/08/12 02:05:41 gerald 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",
58 "Asynchronous Framing supported",
59 "Synchronous Framing supported",
60 "Either Framing supported"
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",
69 "Analog access supported",
70 "Digital access supported",
71 "Either access supported"
74 #define NUM_CNTRLRESULT_TYPES 6
75 #define cntrlresulttype2str(t) \
76 ((t < NUM_CNTRLRESULT_TYPES) ? cntrlresulttypestr[t] : "Unknown Start-Control-connection-Reply result code")
78 static const char *cntrlresulttypestr[NUM_CNTRLRESULT_TYPES] = {
79 "Unknown Start-Control-connection-Reply result code",
80 "Successful channel establishment",
82 "Command channel already exists",
83 "Requester not authorized",
84 "Protocol version not supported"
87 #define NUM_ERROR_TYPES 7
88 #define errortype2str(t) \
89 ((t < NUM_ERROR_TYPES) ? errortypestr[t] : "Unknown general error code")
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 Stop-Control-Connection-Request reason code")
105 static const char *reasontypestr[NUM_REASON_TYPES] = {
106 "Unknown Stop-Control-Connection-Request reason code",
109 "Stop-Local-Shutdown"
112 #define NUM_STOPRESULT_TYPES 3
113 #define stopresulttype2str(t) \
114 ((t < NUM_STOPRESULT_TYPES) ? stopresulttypestr[t] : "Unknown Stop-Control-Connection-Reply result code")
116 static const char *stopresulttypestr[NUM_STOPRESULT_TYPES] = {
117 "Unknown Stop-Control-Connection-Reply result code",
122 #define NUM_ECHORESULT_TYPES 3
123 #define echoresulttype2str(t) \
124 ((t < NUM_ECHORESULT_TYPES) ? echoresulttypestr[t] : "Unknown Echo-Reply result code")
126 static const char *echoresulttypestr[NUM_ECHORESULT_TYPES] = {
127 "Unknown Echo-Reply result code",
132 #define NUM_OUTRESULT_TYPES 8
133 #define outresulttype2str(t) \
134 ((t < NUM_OUTRESULT_TYPES) ? outresulttypestr[t] : "Unknown Outgoing-Call-Reply result code")
136 static const char *outresulttypestr[NUM_OUTRESULT_TYPES] = {
137 "Unknown Outgoing-Call-Reply result code",
147 #define NUM_INRESULT_TYPES 4
148 #define inresulttype2str(t) \
149 ((t < NUM_INRESULT_TYPES) ? inresulttypestr[t] : "Unknown Incoming-Call-Reply result code")
151 static const char *inresulttypestr[NUM_INRESULT_TYPES] = {
152 "Unknown Incoming-Call-Reply result code",
158 #define NUM_DISCRESULT_TYPES 5
159 #define discresulttype2str(t) \
160 ((t < NUM_DISCRESULT_TYPES) ? discresulttypestr[t] : "Unknown Call-Disconnect-Notify result code")
162 static const char *discresulttypestr[NUM_DISCRESULT_TYPES] = {
163 "Unknown Call-Disconnect-Notify result code",
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-Connection-Request", dissect_cntrl_req },
197 {"Start-Control-Connection-Reply", dissect_cntrl_reply },
198 {"Stop-Control-Connection-Request", dissect_stop_req },
199 {"Stop-Control-Connection-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 {"Call-Clear-Request", dissect_clear_req },
208 {"Call-Disconnect-Notify", dissect_disc_notify },
209 {"WAN-Error-Notify", dissect_error_notify },
210 {"Set-Link-Info", 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_memcpy(tvb, host, offset, HOSTLEN);
336 host[HOSTLEN] = '\0';
337 proto_tree_add_text(tree, tvb, offset, HOSTLEN,
338 "Hostname: %s", host);
341 tvb_memcpy(tvb, vendor, offset, VENDORLEN);
342 vendor[VENDORLEN] = '\0';
343 proto_tree_add_text(tree, tvb, offset, VENDORLEN,
344 "Vendor: %s", vendor);
348 dissect_cntrl_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
357 guint8 host[HOSTLEN+1];
358 guint8 vendor[VENDORLEN+1];
360 major_ver = tvb_get_guint8(tvb, offset);
361 minor_ver = tvb_get_guint8(tvb, offset + 1);
362 proto_tree_add_text(tree, tvb, offset, 2,
363 "Protocol version: %u.%u", major_ver, minor_ver);
366 result = tvb_get_guint8(tvb, offset);
367 proto_tree_add_text(tree, tvb, offset, 1,
368 "Result: %s (%u)", cntrlresulttype2str(result), result);
371 error = tvb_get_guint8(tvb, offset);
372 proto_tree_add_text(tree, tvb, offset, 1,
373 "Error: %s (%u)", errortype2str(error), error);
376 frame = tvb_get_ntohl(tvb, offset);
377 proto_tree_add_text(tree, tvb, offset, 4,
378 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
381 bearer = tvb_get_ntohl(tvb, offset);
382 proto_tree_add_text(tree, tvb, offset, 4,
383 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
386 proto_tree_add_text(tree, tvb, offset, 2,
387 "Maximum channels: %u", tvb_get_ntohs(tvb, offset));
390 proto_tree_add_text(tree, tvb, offset, 2,
391 "Firmware revision: %u", tvb_get_ntohs(tvb, offset));
394 tvb_memcpy(tvb, host, offset, HOSTLEN);
395 host[HOSTLEN] = '\0';
396 proto_tree_add_text(tree, tvb, offset, HOSTLEN,
397 "Hostname: %s", host);
400 tvb_memcpy(tvb, vendor, offset, VENDORLEN);
401 vendor[VENDORLEN] = '\0';
402 proto_tree_add_text(tree, tvb, offset, VENDORLEN,
403 "Vendor: %s", vendor);
407 dissect_stop_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
412 reason = tvb_get_guint8(tvb, offset);
413 proto_tree_add_text(tree, tvb, offset, 1,
414 "Reason: %s (%u)", reasontype2str(reason), reason);
417 proto_tree_add_text(tree, tvb, offset, 1,
418 "Reserved: %u", tvb_get_guint8(tvb, offset));
421 proto_tree_add_text(tree, tvb, offset, 2,
422 "Reserved: %u", tvb_get_ntohs(tvb, offset));
426 dissect_stop_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
432 result = tvb_get_guint8(tvb, offset);
433 proto_tree_add_text(tree, tvb, offset, 1,
434 "Result: %s (%u)", stopresulttype2str(result), result);
437 error = tvb_get_guint8(tvb, offset);
438 proto_tree_add_text(tree, tvb, offset, 1,
439 "Error: %s (%u)", errortype2str(error), error);
442 proto_tree_add_text(tree, tvb, offset, 2,
443 "Reserved: %u", tvb_get_ntohs(tvb, offset));
447 dissect_echo_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
450 proto_tree_add_text(tree, tvb, offset, 4,
451 "Identifier: %u", tvb_get_ntohl(tvb, offset));
455 dissect_echo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
461 proto_tree_add_text(tree, tvb, offset, 4,
462 "Identifier: %u", tvb_get_ntohl(tvb, offset));
465 result = tvb_get_guint8(tvb, offset);
466 proto_tree_add_text(tree, tvb, offset, 1,
467 "Result: %s (%u)", echoresulttype2str(result), result);
470 error = tvb_get_guint8(tvb, offset);
471 proto_tree_add_text(tree, tvb, offset, sizeof(error),
472 "Error: %s (%u)", errortype2str(error), error);
475 proto_tree_add_text(tree, tvb, offset, 2,
476 "Reserved: %u", tvb_get_ntohs(tvb, offset));
480 dissect_out_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
485 guint8 phone[PHONELEN+1];
486 guint8 subaddr[SUBADDRLEN+1];
488 proto_tree_add_text(tree, tvb, offset, 2,
489 "Call ID: %u", tvb_get_ntohs(tvb, offset));
492 proto_tree_add_text(tree, tvb, offset, 2,
493 "Call Serial Number: %u", tvb_get_ntohs(tvb, offset));
496 proto_tree_add_text(tree, tvb, offset, 4,
497 "Minimum BPS: %u", tvb_get_ntohl(tvb, offset));
500 proto_tree_add_text(tree, tvb, offset, 4,
501 "Maximum BPS: %u", tvb_get_ntohl(tvb, offset));
504 bearer = tvb_get_ntohl(tvb, offset);
505 proto_tree_add_text(tree, tvb, offset, 4,
506 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
509 frame = tvb_get_ntohl(tvb, offset);
510 proto_tree_add_text(tree, tvb, offset, 4,
511 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
514 proto_tree_add_text(tree, tvb, offset, 2,
515 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
518 proto_tree_add_text(tree, tvb, offset, 2,
519 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
522 proto_tree_add_text(tree, tvb, offset, 2,
523 "Phone number length: %u", tvb_get_ntohs(tvb, offset));
526 proto_tree_add_text(tree, tvb, offset, 2,
527 "Reserved: %u", tvb_get_ntohs(tvb, offset));
530 tvb_memcpy(tvb, phone, offset, PHONELEN);
531 phone[PHONELEN] = '\0';
532 proto_tree_add_text(tree, tvb, offset, PHONELEN,
533 "Phone number: %s", phone);
536 tvb_memcpy(tvb, subaddr, offset, SUBADDRLEN);
537 subaddr[SUBADDRLEN] = '\0';
538 proto_tree_add_text(tree, tvb, offset, SUBADDRLEN,
539 "Subaddress: %s", subaddr);
543 dissect_out_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
549 proto_tree_add_text(tree, tvb, offset, 2,
550 "Call ID: %u", tvb_get_ntohs(tvb, offset));
553 proto_tree_add_text(tree, tvb, offset, 2,
554 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
557 result = tvb_get_guint8(tvb, offset);
558 proto_tree_add_text(tree, tvb, offset, 1,
559 "Result: %s (%u)", outresulttype2str(result), result);
562 error = tvb_get_guint8(tvb, offset);
563 proto_tree_add_text(tree, tvb, offset, 1,
564 "Error: %s (%u)", errortype2str(error), error);
567 proto_tree_add_text(tree, tvb, offset, 2,
568 "Cause code: %u", tvb_get_ntohs(tvb, offset));
571 proto_tree_add_text(tree, tvb, offset, 4,
572 "Connect speed: %u", tvb_get_ntohl(tvb, offset));
575 proto_tree_add_text(tree, tvb, offset, 2,
576 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
579 proto_tree_add_text(tree, tvb, offset, 2,
580 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
583 proto_tree_add_text(tree, tvb, offset, 4,
584 "Physical channel ID: %u", tvb_get_ntohl(tvb, offset));
588 dissect_in_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
592 guint8 dialed[PHONELEN+1];
593 guint8 dialing[PHONELEN+1];
594 guint8 subaddr[SUBADDRLEN+1];
596 proto_tree_add_text(tree, tvb, offset, 2,
597 "Call ID: %u", tvb_get_ntohs(tvb, offset));
600 proto_tree_add_text(tree, tvb, offset, 2,
601 "Call serial number: %u", tvb_get_ntohs(tvb, offset));
604 bearer = tvb_get_ntohl(tvb, offset);
605 proto_tree_add_text(tree, tvb, offset, 4,
606 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
609 proto_tree_add_text(tree, tvb, offset, 4,
610 "Physical channel ID: %u", tvb_get_ntohl(tvb, offset));
613 proto_tree_add_text(tree, tvb, offset, 2,
614 "Dialed number length: %u", tvb_get_ntohs(tvb, offset));
617 proto_tree_add_text(tree, tvb, offset, 2,
618 "Dialing number length: %u", tvb_get_ntohs(tvb, offset));
621 tvb_memcpy(tvb, dialing, offset, PHONELEN);
622 dialed[PHONELEN] = '\0';
623 proto_tree_add_text(tree, tvb, offset, PHONELEN,
624 "Dialed number: %s", dialed);
627 tvb_memcpy(tvb, dialing, offset, PHONELEN);
628 dialing[PHONELEN] = '\0';
629 proto_tree_add_text(tree, tvb, offset, PHONELEN,
630 "Dialing number: %s", dialing);
633 tvb_memcpy(tvb, subaddr, offset, SUBADDRLEN);
634 subaddr[SUBADDRLEN] = '\0';
635 proto_tree_add_text(tree, tvb, offset, SUBADDRLEN,
636 "Subaddress: %s", subaddr);
640 dissect_in_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
646 proto_tree_add_text(tree, tvb, offset, 2,
647 "Call ID: %u", tvb_get_ntohs(tvb, offset));
650 proto_tree_add_text(tree, tvb, offset, 2,
651 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
654 result = tvb_get_guint8(tvb, offset);
655 proto_tree_add_text(tree, tvb, offset, 1,
656 "Result: %s (%u)", inresulttype2str(result), result);
659 error = tvb_get_guint8(tvb, offset);
660 proto_tree_add_text(tree, tvb, offset, 1,
661 "Error: %s (%u)", errortype2str(error), error);
664 proto_tree_add_text(tree, tvb, offset, 2,
665 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
668 proto_tree_add_text(tree, tvb, offset, 2,
669 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
672 proto_tree_add_text(tree, tvb, offset, 2,
673 "Reserved: %u", tvb_get_ntohs(tvb, offset));
677 dissect_in_connected(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
682 proto_tree_add_text(tree, tvb, offset, 2,
683 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
686 proto_tree_add_text(tree, tvb, offset, 2,
687 "Reserved: %u", tvb_get_ntohs(tvb, offset));
690 proto_tree_add_text(tree, tvb, offset, 4,
691 "Connect speed: %u", tvb_get_ntohl(tvb, offset));
694 proto_tree_add_text(tree, tvb, offset, 2,
695 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
698 proto_tree_add_text(tree, tvb, offset, 2,
699 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
702 frame = tvb_get_ntohl(tvb, offset);
703 proto_tree_add_text(tree, tvb, offset, 4,
704 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
708 dissect_clear_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
711 proto_tree_add_text(tree, tvb, offset, 2,
712 "Call ID: %u", tvb_get_ntohs(tvb, offset));
715 proto_tree_add_text(tree, tvb, offset, 2,
716 "Reserved: %u", tvb_get_ntohs(tvb, offset));
720 dissect_disc_notify(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
725 guint8 stats[STATSLEN+1];
727 proto_tree_add_text(tree, tvb, offset, 2,
728 "Call ID: %u", tvb_get_ntohs(tvb, offset));
731 result = tvb_get_guint8(tvb, offset);
732 proto_tree_add_text(tree, tvb, offset, 1,
733 "Result: %s (%u)", discresulttype2str(result), result);
736 error = tvb_get_guint8(tvb, offset);
737 proto_tree_add_text(tree, tvb, offset, 1,
738 "Error: %s (%u)", errortype2str(error), error);
741 proto_tree_add_text(tree, tvb, offset, 2,
742 "Cause code: %u", tvb_get_ntohs(tvb, offset));
745 proto_tree_add_text(tree, tvb, offset, 2,
746 "Reserved: %u", tvb_get_ntohs(tvb, offset));
749 tvb_memcpy(tvb, stats, offset, STATSLEN);
750 stats[STATSLEN] = '\0';
751 proto_tree_add_text(tree, tvb, offset, STATSLEN,
752 "Call statistics: %s", stats);
756 dissect_error_notify(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
759 proto_tree_add_text(tree, tvb, offset, 2,
760 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
763 proto_tree_add_text(tree, tvb, offset, 2,
764 "Reserved: %u", tvb_get_ntohs(tvb, offset));
767 proto_tree_add_text(tree, tvb, offset, 4,
768 "CRC errors: %u", tvb_get_ntohl(tvb, offset));
771 proto_tree_add_text(tree, tvb, offset, 4,
772 "Framing errors: %u", tvb_get_ntohl(tvb, offset));
775 proto_tree_add_text(tree, tvb, offset, 4,
776 "Hardware overruns: %u", tvb_get_ntohl(tvb, offset));
779 proto_tree_add_text(tree, tvb, offset, 4,
780 "Buffer overruns: %u", tvb_get_ntohl(tvb, offset));
783 proto_tree_add_text(tree, tvb, offset, 4,
784 "Time-out errors: %u", tvb_get_ntohl(tvb, offset));
787 proto_tree_add_text(tree, tvb, offset, 4,
788 "Alignment errors: %u", tvb_get_ntohl(tvb, offset));
792 dissect_set_link(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
795 proto_tree_add_text(tree, tvb, offset, 2,
796 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
799 proto_tree_add_text(tree, tvb, offset, 2,
800 "Reserved: %u", tvb_get_ntohs(tvb, offset));
803 proto_tree_add_text(tree, tvb, offset, 4,
804 "Send ACCM: %#08x", tvb_get_ntohl(tvb, offset));
807 proto_tree_add_text(tree, tvb, offset, 4,
808 "Recv ACCM: %#08x", tvb_get_ntohl(tvb, offset));
812 proto_register_pptp(void)
814 static gint *ett[] = {
818 static hf_register_info hf[] = {
819 { &hf_pptp_message_type,
820 { "Message type", "pptp.type",
821 FT_UINT16, BASE_DEC, VALS(msgtype_vals), 0x0,
822 "PPTP message type", HFILL }}
825 proto_pptp = proto_register_protocol("Point-to-Point Tunnelling Protocol",
827 proto_register_field_array(proto_pptp, hf, array_length(hf));
828 proto_register_subtree_array(ett, array_length(ett));
832 proto_reg_handoff_pptp(void)
834 dissector_handle_t pptp_handle;
836 pptp_handle = create_dissector_handle(dissect_pptp, proto_pptp);
837 dissector_add("tcp.port", TCP_PORT_PPTP, pptp_handle);
838 data_handle = find_dissector("data");