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.19 2001/06/18 02:17:50 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@zing.org>
9 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
37 #ifdef HAVE_NETINET_IN_H
38 #include <netinet/in.h>
44 static int proto_pptp = -1;
45 static int hf_pptp_message_type = -1;
47 static gint ett_pptp = -1;
49 #define TCP_PORT_PPTP 1723
51 #define MAGIC_COOKIE 0x1A2B3C4D
53 static const value_string msgtype_vals[] = {
54 { 1, "CONTROL-MESSAGE" },
55 { 2, "MANAGEMENT-MESSAGE" },
59 #define NUM_FRAME_TYPES 4
60 #define frametype2str(t) \
61 ((t < NUM_FRAME_TYPES) ? frametypestr[t] : "UNKNOWN-FRAMING-TYPE")
63 static const char *frametypestr[NUM_FRAME_TYPES] = {
64 "UNKNOWN-FRAMING-TYPE",
70 #define NUM_BEARER_TYPES 4
71 #define bearertype2str(t) \
72 ((t < NUM_BEARER_TYPES) ? bearertypestr[t] : "UNKNOWN-BEARER-TYPE")
74 static const char *bearertypestr[NUM_BEARER_TYPES] = {
75 "UNKNOWN-BEARER-TYPE",
81 #define NUM_CNTRLRESULT_TYPES 6
82 #define cntrlresulttype2str(t) \
83 ((t < NUM_CNTRLRESULT_TYPES) ? cntrlresulttypestr[t] : "UNKNOWN-CNTRLRESULT-TYPE")
85 static const char *cntrlresulttypestr[NUM_CNTRLRESULT_TYPES] = {
86 "UNKNOWN-CNTRLRESULT-TYPE",
89 "COMMAND-CHANNEL-EXISTS",
91 "VERSION-NOT-SUPPORTED"
94 #define NUM_ERROR_TYPES 7
95 #define errortype2str(t) \
96 ((t < NUM_ERROR_TYPES) ? errortypestr[t] : "UNKNOWN-ERROR-TYPE")
98 static const char *errortypestr[NUM_ERROR_TYPES] = {
108 #define NUM_REASON_TYPES 4
109 #define reasontype2str(t) \
110 ((t < NUM_REASON_TYPES) ? reasontypestr[t] : "UNKNOWN-REASON-TYPE")
112 static const char *reasontypestr[NUM_REASON_TYPES] = {
113 "UNKNOWN-REASON-TYPE",
116 "STOP-LOCAL-SHUTDOWN"
119 #define NUM_STOPRESULT_TYPES 3
120 #define stopresulttype2str(t) \
121 ((t < NUM_STOPRESULT_TYPES) ? stopresulttypestr[t] : "UNKNOWN-STOPRESULT-TYPE")
123 static const char *stopresulttypestr[NUM_STOPRESULT_TYPES] = {
124 "UNKNOWN-STOPRESULT-TYPE",
129 #define NUM_ECHORESULT_TYPES 3
130 #define echoresulttype2str(t) \
131 ((t < NUM_ECHORESULT_TYPES) ? echoresulttypestr[t] : "UNKNOWN-ECHORESULT-TYPE")
133 static const char *echoresulttypestr[NUM_ECHORESULT_TYPES] = {
134 "UNKNOWN-ECHORESULT-TYPE",
139 #define NUM_OUTRESULT_TYPES 8
140 #define outresulttype2str(t) \
141 ((t < NUM_OUTRESULT_TYPES) ? outresulttypestr[t] : "UNKNOWN-OUTRESULT-TYPE")
143 static const char *outresulttypestr[NUM_OUTRESULT_TYPES] = {
144 "UNKNOWN-OUTRESULT-TYPE",
154 #define NUM_INRESULT_TYPES 4
155 #define inresulttype2str(t) \
156 ((t < NUM_INRESULT_TYPES) ? inresulttypestr[t] : "UNKNOWN-INRESULT-TYPE")
158 static const char *inresulttypestr[NUM_INRESULT_TYPES] = {
159 "UNKNOWN-INRESULT-TYPE",
165 #define NUM_DISCRESULT_TYPES 5
166 #define discresulttype2str(t) \
167 ((t < NUM_DISCRESULT_TYPES) ? discresulttypestr[t] : "UNKNOWN-DISCRESULT-TYPE")
169 static const char *discresulttypestr[NUM_DISCRESULT_TYPES] = {
170 "UNKNOWN-DISCRESULT-TYPE",
177 static void dissect_unknown(tvbuff_t *, int, packet_info *, proto_tree *);
178 static void dissect_cntrl_req(tvbuff_t *, int, packet_info *, proto_tree *);
179 static void dissect_cntrl_reply(tvbuff_t *, int, packet_info *, proto_tree *);
180 static void dissect_stop_req(tvbuff_t *, int, packet_info *, proto_tree *);
181 static void dissect_stop_reply(tvbuff_t *, int, packet_info *, proto_tree *);
182 static void dissect_echo_req(tvbuff_t *, int, packet_info *, proto_tree *);
183 static void dissect_echo_reply(tvbuff_t *, int, packet_info *, proto_tree *);
184 static void dissect_out_req(tvbuff_t *, int, packet_info *, proto_tree *);
185 static void dissect_out_reply(tvbuff_t *, int, packet_info *, proto_tree *);
186 static void dissect_in_req(tvbuff_t *, int, packet_info *, proto_tree *);
187 static void dissect_in_reply(tvbuff_t *, int, packet_info *, proto_tree *);
188 static void dissect_in_connected(tvbuff_t *, int, packet_info *, proto_tree *);
189 static void dissect_clear_req(tvbuff_t *, int, packet_info *, proto_tree *);
190 static void dissect_disc_notify(tvbuff_t *, int, packet_info *, proto_tree *);
191 static void dissect_error_notify(tvbuff_t *, int, packet_info *, proto_tree *);
192 static void dissect_set_link(tvbuff_t *, int, packet_info *, proto_tree *);
194 #define NUM_CNTRL_TYPES 16
195 #define cntrltype2str(t) \
196 ((t < NUM_CNTRL_TYPES) ? strfuncs[t].str : "UNKNOWN-CONTROL-TYPE")
198 static struct strfunc {
200 void (*func)(tvbuff_t *, int, packet_info *, proto_tree *);
201 } strfuncs[NUM_CNTRL_TYPES] = {
202 {"UNKNOWN-CONTROL-TYPE", dissect_unknown },
203 {"START-CONTROL-REQUEST", dissect_cntrl_req },
204 {"START-CONTROL-REPLY", dissect_cntrl_reply },
205 {"STOP-CONTROL-REQUEST", dissect_stop_req },
206 {"STOP-CONTROL-REPLY", dissect_stop_reply },
207 {"ECHO-REQUEST", dissect_echo_req },
208 {"ECHO-REPLY", dissect_echo_reply },
209 {"OUTGOING-CALL-REQUEST", dissect_out_req },
210 {"OUTGOING-CALL-REPLY", dissect_out_reply },
211 {"INCOMING-CALL-REQUEST", dissect_in_req },
212 {"INCOMING-CALL-REPLY", dissect_in_reply },
213 {"INCOMING-CALL-CONNECTED", dissect_in_connected },
214 {"CLEAR-CALL-REQUEST", dissect_clear_req },
215 {"DISCONNECT-NOTIFY", dissect_disc_notify },
216 {"ERROR-NOTIFY", dissect_error_notify },
217 {"SET-LINK", dissect_set_link }
221 * Length of host name and vendor name strings in control requests and
228 * Length of phone number(s) and subaddress in call requests.
231 #define SUBADDRLEN 64
234 * Length of statistics in a Call-Disconnect-Notify message.
239 dissect_pptp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
245 if (check_col(pinfo->fd, COL_PROTOCOL))
246 col_set_str(pinfo->fd, COL_PROTOCOL, "PPTP");
247 if (check_col(pinfo->fd, COL_INFO))
248 col_clear(pinfo->fd, COL_INFO);
250 len = tvb_get_ntohs(tvb, offset);
251 cntrl_type = tvb_get_ntohs(tvb, offset + 8);
253 if (check_col(pinfo->fd, COL_INFO))
254 col_add_fstr(pinfo->fd, COL_INFO, "%s", cntrltype2str(cntrl_type));
259 proto_tree * pptp_tree;
261 ti = proto_tree_add_item(tree, proto_pptp, tvb, offset, len, FALSE);
262 pptp_tree = proto_item_add_subtree(ti, ett_pptp);
264 proto_tree_add_text(pptp_tree, tvb, offset, 2, "Length: %u", len);
267 proto_tree_add_item(pptp_tree, hf_pptp_message_type, tvb,
271 cookie = tvb_get_ntohl(tvb, offset);
273 if (cookie == MAGIC_COOKIE)
274 proto_tree_add_text(pptp_tree, tvb, offset, 4,
275 "Cookie: %#08x (correct)", cookie);
277 proto_tree_add_text(pptp_tree, tvb, offset, 4,
278 "Cookie: %#08x (incorrect)", cookie);
281 proto_tree_add_text(pptp_tree, tvb, offset, 2,
282 "Control type: %s (%u)", cntrltype2str(cntrl_type), cntrl_type);
285 proto_tree_add_text(pptp_tree, tvb, offset, 2,
286 "Reserved: %u", tvb_get_ntohs(tvb, offset));
289 if (cntrl_type < NUM_CNTRL_TYPES)
290 ( *(strfuncs[cntrl_type].func))(tvb, offset, pinfo, pptp_tree);
292 dissect_data(tvb, offset, pinfo, pptp_tree);
297 dissect_unknown(tvbuff_t *tvb, int offset, packet_info *pinfo,
300 dissect_data(tvb, offset, pinfo, tree);
304 dissect_cntrl_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
311 guint8 host[HOSTLEN+1];
312 guint8 vendor[VENDORLEN+1];
314 major_ver = tvb_get_guint8(tvb, offset);
315 minor_ver = tvb_get_guint8(tvb, offset + 1);
316 proto_tree_add_text(tree, tvb, offset, 2,
317 "Protocol version: %u.%u", major_ver, minor_ver);
320 proto_tree_add_text(tree, tvb, offset, 2,
321 "Reserved: %u", tvb_get_ntohs(tvb, offset));
324 frame = tvb_get_ntohl(tvb, offset);
325 proto_tree_add_text(tree, tvb, offset, 4,
326 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
329 bearer = tvb_get_ntohl(tvb, offset);
330 proto_tree_add_text(tree, tvb, offset, 4,
331 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
334 proto_tree_add_text(tree, tvb, offset, 2,
335 "Maximum channels: %u", tvb_get_ntohs(tvb, offset));
338 proto_tree_add_text(tree, tvb, offset, 2,
339 "Firmware revision: %u", tvb_get_ntohs(tvb, offset));
342 tvb_get_nstringz0(tvb, offset, HOSTLEN, host);
343 proto_tree_add_text(tree, tvb, offset, HOSTLEN,
344 "Hostname: %s", host);
347 tvb_get_nstringz0(tvb, offset, VENDORLEN, vendor);
348 proto_tree_add_text(tree, tvb, offset, VENDORLEN,
349 "Vendor: %s", vendor);
353 dissect_cntrl_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
362 guint8 host[HOSTLEN+1];
363 guint8 vendor[VENDORLEN+1];
365 major_ver = tvb_get_guint8(tvb, offset);
366 minor_ver = tvb_get_guint8(tvb, offset + 1);
367 proto_tree_add_text(tree, tvb, offset, 2,
368 "Protocol version: %u.%u", major_ver, minor_ver);
371 result = tvb_get_guint8(tvb, offset);
372 proto_tree_add_text(tree, tvb, offset, 1,
373 "Result: %s (%u)", cntrlresulttype2str(result), result);
376 error = tvb_get_guint8(tvb, offset);
377 proto_tree_add_text(tree, tvb, offset, 1,
378 "Error: %s (%u)", errortype2str(error), error);
381 frame = tvb_get_ntohl(tvb, offset);
382 proto_tree_add_text(tree, tvb, offset, 4,
383 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
386 bearer = tvb_get_ntohl(tvb, offset);
387 proto_tree_add_text(tree, tvb, offset, 4,
388 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
391 proto_tree_add_text(tree, tvb, offset, 2,
392 "Maximum channels: %u", tvb_get_ntohs(tvb, offset));
395 proto_tree_add_text(tree, tvb, offset, 2,
396 "Firmware revision: %u", tvb_get_ntohs(tvb, offset));
399 tvb_get_nstringz0(tvb, offset, HOSTLEN, host);
400 proto_tree_add_text(tree, tvb, offset, HOSTLEN,
401 "Hostname: %s", host);
404 tvb_get_nstringz0(tvb, offset, VENDORLEN, vendor);
405 proto_tree_add_text(tree, tvb, offset, VENDORLEN,
406 "Vendor: %s", vendor);
410 dissect_stop_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
415 reason = tvb_get_guint8(tvb, offset);
416 proto_tree_add_text(tree, tvb, offset, 1,
417 "Reason: %s (%u)", reasontype2str(reason), reason);
420 proto_tree_add_text(tree, tvb, offset, 1,
421 "Reserved: %u", tvb_get_guint8(tvb, offset));
424 proto_tree_add_text(tree, tvb, offset, 2,
425 "Reserved: %u", tvb_get_ntohs(tvb, offset));
429 dissect_stop_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
435 result = tvb_get_guint8(tvb, offset);
436 proto_tree_add_text(tree, tvb, offset, 1,
437 "Result: %s (%u)", stopresulttype2str(result), result);
440 error = tvb_get_guint8(tvb, offset);
441 proto_tree_add_text(tree, tvb, offset, 1,
442 "Error: %s (%u)", errortype2str(error), error);
445 proto_tree_add_text(tree, tvb, offset, 2,
446 "Reserved: %u", tvb_get_ntohs(tvb, offset));
450 dissect_echo_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
453 proto_tree_add_text(tree, tvb, offset, 4,
454 "Identifier: %u", tvb_get_ntohl(tvb, offset));
458 dissect_echo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
464 proto_tree_add_text(tree, tvb, offset, 4,
465 "Identifier: %u", tvb_get_ntohl(tvb, offset));
468 result = tvb_get_guint8(tvb, offset);
469 proto_tree_add_text(tree, tvb, offset, 1,
470 "Result: %s (%u)", echoresulttype2str(result), result);
473 error = tvb_get_guint8(tvb, offset);
474 proto_tree_add_text(tree, tvb, offset, sizeof(error),
475 "Error: %s (%u)", errortype2str(error), error);
478 proto_tree_add_text(tree, tvb, offset, 2,
479 "Reserved: %u", tvb_get_ntohs(tvb, offset));
483 dissect_out_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
488 guint8 phone[PHONELEN+1];
489 guint8 subaddr[SUBADDRLEN+1];
491 proto_tree_add_text(tree, tvb, offset, 2,
492 "Call ID: %u", tvb_get_ntohs(tvb, offset));
495 proto_tree_add_text(tree, tvb, offset, 2,
496 "Call Serial Number: %u", tvb_get_ntohs(tvb, offset));
499 proto_tree_add_text(tree, tvb, offset, 4,
500 "Minimum BPS: %u", tvb_get_ntohl(tvb, offset));
503 proto_tree_add_text(tree, tvb, offset, 4,
504 "Maximum BPS: %u", tvb_get_ntohl(tvb, offset));
507 bearer = tvb_get_ntohl(tvb, offset);
508 proto_tree_add_text(tree, tvb, offset, 4,
509 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
512 frame = tvb_get_ntohl(tvb, offset);
513 proto_tree_add_text(tree, tvb, offset, 4,
514 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
517 proto_tree_add_text(tree, tvb, offset, 2,
518 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
521 proto_tree_add_text(tree, tvb, offset, 2,
522 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
525 proto_tree_add_text(tree, tvb, offset, 2,
526 "Phone number length: %u", tvb_get_ntohs(tvb, offset));
529 proto_tree_add_text(tree, tvb, offset, 2,
530 "Reserved: %u", tvb_get_ntohs(tvb, offset));
533 tvb_get_nstringz0(tvb, offset, PHONELEN, phone);
534 proto_tree_add_text(tree, tvb, offset, PHONELEN,
535 "Phone number: %s", phone);
538 tvb_get_nstringz0(tvb, offset, SUBADDRLEN, subaddr);
539 proto_tree_add_text(tree, tvb, offset, SUBADDRLEN,
540 "Subaddress: %s", subaddr);
544 dissect_out_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
550 proto_tree_add_text(tree, tvb, offset, 2,
551 "Call ID: %u", tvb_get_ntohs(tvb, offset));
554 proto_tree_add_text(tree, tvb, offset, 2,
555 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
558 result = tvb_get_guint8(tvb, offset);
559 proto_tree_add_text(tree, tvb, offset, 1,
560 "Result: %s (%u)", outresulttype2str(result), result);
563 error = tvb_get_guint8(tvb, offset);
564 proto_tree_add_text(tree, tvb, offset, 1,
565 "Error: %s (%u)", errortype2str(error), error);
568 proto_tree_add_text(tree, tvb, offset, 2,
569 "Cause code: %u", tvb_get_ntohs(tvb, offset));
572 proto_tree_add_text(tree, tvb, offset, 4,
573 "Connect speed: %u", tvb_get_ntohl(tvb, offset));
576 proto_tree_add_text(tree, tvb, offset, 2,
577 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
580 proto_tree_add_text(tree, tvb, offset, 2,
581 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
584 proto_tree_add_text(tree, tvb, offset, 4,
585 "Physical channel ID: %u", tvb_get_ntohl(tvb, offset));
589 dissect_in_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
593 guint8 dialed[PHONELEN+1];
594 guint8 dialing[PHONELEN+1];
595 guint8 subaddr[SUBADDRLEN+1];
597 proto_tree_add_text(tree, tvb, offset, 2,
598 "Call ID: %u", tvb_get_ntohs(tvb, offset));
601 proto_tree_add_text(tree, tvb, offset, 2,
602 "Call serial number: %u", tvb_get_ntohs(tvb, offset));
605 bearer = tvb_get_ntohl(tvb, offset);
606 proto_tree_add_text(tree, tvb, offset, 4,
607 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
610 proto_tree_add_text(tree, tvb, offset, 4,
611 "Physical channel ID: %u", tvb_get_ntohl(tvb, offset));
614 proto_tree_add_text(tree, tvb, offset, 2,
615 "Dialed number length: %u", tvb_get_ntohs(tvb, offset));
618 proto_tree_add_text(tree, tvb, offset, 2,
619 "Dialing number length: %u", tvb_get_ntohs(tvb, offset));
622 tvb_get_nstringz0(tvb, offset, PHONELEN, dialed);
623 proto_tree_add_text(tree, tvb, offset, PHONELEN,
624 "Dialed number: %s", dialed);
627 tvb_get_nstringz0(tvb, offset, PHONELEN, dialing);
628 proto_tree_add_text(tree, tvb, offset, PHONELEN,
629 "Dialing number: %s", dialing);
632 tvb_get_nstringz0(tvb, offset, SUBADDRLEN, subaddr);
633 proto_tree_add_text(tree, tvb, offset, SUBADDRLEN,
634 "Subaddress: %s", subaddr);
638 dissect_in_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
644 proto_tree_add_text(tree, tvb, offset, 2,
645 "Call ID: %u", tvb_get_ntohs(tvb, offset));
648 proto_tree_add_text(tree, tvb, offset, 2,
649 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
652 result = tvb_get_guint8(tvb, offset);
653 proto_tree_add_text(tree, tvb, offset, 1,
654 "Result: %s (%u)", inresulttype2str(result), result);
657 error = tvb_get_guint8(tvb, offset);
658 proto_tree_add_text(tree, tvb, offset, 1,
659 "Error: %s (%u)", errortype2str(error), error);
662 proto_tree_add_text(tree, tvb, offset, 2,
663 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
666 proto_tree_add_text(tree, tvb, offset, 2,
667 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
670 proto_tree_add_text(tree, tvb, offset, 2,
671 "Reserved: %u", tvb_get_ntohs(tvb, offset));
675 dissect_in_connected(tvbuff_t *tvb, int offset, packet_info *pinfo,
680 proto_tree_add_text(tree, tvb, offset, 2,
681 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
684 proto_tree_add_text(tree, tvb, offset, 2,
685 "Reserved: %u", tvb_get_ntohs(tvb, offset));
688 proto_tree_add_text(tree, tvb, offset, 4,
689 "Connect speed: %u", tvb_get_ntohl(tvb, offset));
692 proto_tree_add_text(tree, tvb, offset, 2,
693 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
696 proto_tree_add_text(tree, tvb, offset, 2,
697 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
700 frame = tvb_get_ntohl(tvb, offset);
701 proto_tree_add_text(tree, tvb, offset, 4,
702 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
706 dissect_clear_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
709 proto_tree_add_text(tree, tvb, offset, 2,
710 "Call ID: %u", tvb_get_ntohs(tvb, offset));
713 proto_tree_add_text(tree, tvb, offset, 2,
714 "Reserved: %u", tvb_get_ntohs(tvb, offset));
718 dissect_disc_notify(tvbuff_t *tvb, int offset, packet_info *pinfo,
723 guint8 stats[STATSLEN+1];
725 proto_tree_add_text(tree, tvb, offset, 2,
726 "Call ID: %u", tvb_get_ntohs(tvb, offset));
729 result = tvb_get_guint8(tvb, offset);
730 proto_tree_add_text(tree, tvb, offset, 1,
731 "Result: %s (%u)", discresulttype2str(result), result);
734 error = tvb_get_guint8(tvb, offset);
735 proto_tree_add_text(tree, tvb, offset, 1,
736 "Error: %s (%u)", errortype2str(error), error);
739 proto_tree_add_text(tree, tvb, offset, 2,
740 "Cause code: %u", tvb_get_ntohs(tvb, offset));
743 proto_tree_add_text(tree, tvb, offset, 2,
744 "Reserved: %u", tvb_get_ntohs(tvb, offset));
747 tvb_get_nstringz0(tvb, offset, STATSLEN, stats);
748 proto_tree_add_text(tree, tvb, offset, STATSLEN,
749 "Call statistics: %s", stats);
753 dissect_error_notify(tvbuff_t *tvb, int offset, packet_info *pinfo,
756 proto_tree_add_text(tree, tvb, offset, 2,
757 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
760 proto_tree_add_text(tree, tvb, offset, 2,
761 "Reserved: %u", tvb_get_ntohs(tvb, offset));
764 proto_tree_add_text(tree, tvb, offset, 4,
765 "CRC errors: %u", tvb_get_ntohl(tvb, offset));
768 proto_tree_add_text(tree, tvb, offset, 4,
769 "Framing errors: %u", tvb_get_ntohl(tvb, offset));
772 proto_tree_add_text(tree, tvb, offset, 4,
773 "Hardware overruns: %u", tvb_get_ntohl(tvb, offset));
776 proto_tree_add_text(tree, tvb, offset, 4,
777 "Buffer overruns: %u", tvb_get_ntohl(tvb, offset));
780 proto_tree_add_text(tree, tvb, offset, 4,
781 "Time-out errors: %u", tvb_get_ntohl(tvb, offset));
784 proto_tree_add_text(tree, tvb, offset, 4,
785 "Alignment errors: %u", tvb_get_ntohl(tvb, offset));
789 dissect_set_link(tvbuff_t *tvb, int offset, packet_info *pinfo,
792 proto_tree_add_text(tree, tvb, offset, 2,
793 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
796 proto_tree_add_text(tree, tvb, offset, 2,
797 "Reserved: %u", tvb_get_ntohs(tvb, offset));
800 proto_tree_add_text(tree, tvb, offset, 4,
801 "Send ACCM: %#08x", tvb_get_ntohl(tvb, offset));
804 proto_tree_add_text(tree, tvb, offset, 4,
805 "Recv ACCM: %#08x", tvb_get_ntohl(tvb, offset));
809 proto_register_pptp(void)
811 static gint *ett[] = {
815 static hf_register_info hf[] = {
816 { &hf_pptp_message_type,
817 { "Message type", "pptp.type",
818 FT_UINT16, BASE_DEC, VALS(msgtype_vals), 0x0,
819 "PPTP message type", HFILL }}
822 proto_pptp = proto_register_protocol("Point-to-Point Tunnelling Protocol",
824 proto_register_field_array(proto_pptp, hf, array_length(hf));
825 proto_register_subtree_array(ett, array_length(ett));
829 proto_reg_handoff_pptp(void)
831 dissector_add("tcp.port", TCP_PORT_PPTP, dissect_pptp, proto_pptp);