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.16 2001/01/03 06:55:31 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 CHECK_DISPLAY_AS_DATA(proto_pptp, tvb, pinfo, tree);
247 pinfo->current_proto = "PPTP";
249 if (check_col(pinfo->fd, COL_PROTOCOL))
250 col_set_str(pinfo->fd, COL_PROTOCOL, "PPTP");
251 if (check_col(pinfo->fd, COL_INFO))
252 col_clear(pinfo->fd, COL_INFO);
254 len = tvb_get_ntohs(tvb, offset);
255 cntrl_type = tvb_get_ntohs(tvb, offset + 8);
257 if (check_col(pinfo->fd, COL_INFO))
258 col_add_fstr(pinfo->fd, COL_INFO, "%s", cntrltype2str(cntrl_type));
263 proto_tree * pptp_tree;
265 ti = proto_tree_add_item(tree, proto_pptp, tvb, offset, len, FALSE);
266 pptp_tree = proto_item_add_subtree(ti, ett_pptp);
268 proto_tree_add_text(pptp_tree, tvb, offset, 2, "Length: %u", len);
271 proto_tree_add_item(pptp_tree, hf_pptp_message_type, tvb,
275 cookie = tvb_get_ntohl(tvb, offset);
277 if (cookie == MAGIC_COOKIE)
278 proto_tree_add_text(pptp_tree, tvb, offset, 4,
279 "Cookie: %#08x (correct)", cookie);
281 proto_tree_add_text(pptp_tree, tvb, offset, 4,
282 "Cookie: %#08x (incorrect)", cookie);
285 proto_tree_add_text(pptp_tree, tvb, offset, 2,
286 "Control type: %s (%u)", cntrltype2str(cntrl_type), cntrl_type);
289 proto_tree_add_text(pptp_tree, tvb, offset, 2,
290 "Reserved: %u", tvb_get_ntohs(tvb, offset));
293 if (cntrl_type < NUM_CNTRL_TYPES)
294 ( *(strfuncs[cntrl_type].func))(tvb, offset, pinfo, pptp_tree);
296 dissect_data(tvb, offset, pinfo, pptp_tree);
301 dissect_unknown(tvbuff_t *tvb, int offset, packet_info *pinfo,
304 dissect_data(tvb, offset, pinfo, tree);
308 dissect_cntrl_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
315 guint8 host[HOSTLEN+1];
316 guint8 vendor[VENDORLEN+1];
318 major_ver = tvb_get_guint8(tvb, offset);
319 minor_ver = tvb_get_guint8(tvb, offset + 1);
320 proto_tree_add_text(tree, tvb, offset, 2,
321 "Protocol version: %u.%u", major_ver, minor_ver);
324 proto_tree_add_text(tree, tvb, offset, 2,
325 "Reserved: %u", tvb_get_ntohs(tvb, offset));
328 frame = tvb_get_ntohl(tvb, offset);
329 proto_tree_add_text(tree, tvb, offset, 4,
330 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
333 bearer = tvb_get_ntohl(tvb, offset);
334 proto_tree_add_text(tree, tvb, offset, 4,
335 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
338 proto_tree_add_text(tree, tvb, offset, 2,
339 "Maximum channels: %u", tvb_get_ntohs(tvb, offset));
342 proto_tree_add_text(tree, tvb, offset, 2,
343 "Firmware revision: %u", tvb_get_ntohs(tvb, offset));
346 tvb_get_nstringz0(tvb, offset, HOSTLEN, host);
347 proto_tree_add_text(tree, tvb, offset, HOSTLEN,
348 "Hostname: %s", host);
351 tvb_get_nstringz0(tvb, offset, VENDORLEN, vendor);
352 proto_tree_add_text(tree, tvb, offset, VENDORLEN,
353 "Vendor: %s", vendor);
357 dissect_cntrl_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
366 guint8 host[HOSTLEN+1];
367 guint8 vendor[VENDORLEN+1];
369 major_ver = tvb_get_guint8(tvb, offset);
370 minor_ver = tvb_get_guint8(tvb, offset + 1);
371 proto_tree_add_text(tree, tvb, offset, 2,
372 "Protocol version: %u.%u", major_ver, minor_ver);
375 result = tvb_get_guint8(tvb, offset);
376 proto_tree_add_text(tree, tvb, offset, 1,
377 "Result: %s (%u)", cntrlresulttype2str(result), result);
380 error = tvb_get_guint8(tvb, offset);
381 proto_tree_add_text(tree, tvb, offset, 1,
382 "Error: %s (%u)", errortype2str(error), error);
385 frame = tvb_get_ntohl(tvb, offset);
386 proto_tree_add_text(tree, tvb, offset, 4,
387 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
390 bearer = tvb_get_ntohl(tvb, offset);
391 proto_tree_add_text(tree, tvb, offset, 4,
392 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
395 proto_tree_add_text(tree, tvb, offset, 2,
396 "Maximum channels: %u", tvb_get_ntohs(tvb, offset));
399 proto_tree_add_text(tree, tvb, offset, 2,
400 "Firmware revision: %u", tvb_get_ntohs(tvb, offset));
403 tvb_get_nstringz0(tvb, offset, HOSTLEN, host);
404 proto_tree_add_text(tree, tvb, offset, HOSTLEN,
405 "Hostname: %s", host);
408 tvb_get_nstringz0(tvb, offset, VENDORLEN, vendor);
409 proto_tree_add_text(tree, tvb, offset, VENDORLEN,
410 "Vendor: %s", vendor);
414 dissect_stop_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
419 reason = tvb_get_guint8(tvb, offset);
420 proto_tree_add_text(tree, tvb, offset, 1,
421 "Reason: %s (%u)", reasontype2str(reason), reason);
424 proto_tree_add_text(tree, tvb, offset, 1,
425 "Reserved: %u", tvb_get_guint8(tvb, offset));
428 proto_tree_add_text(tree, tvb, offset, 2,
429 "Reserved: %u", tvb_get_ntohs(tvb, offset));
433 dissect_stop_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
439 result = tvb_get_guint8(tvb, offset);
440 proto_tree_add_text(tree, tvb, offset, 1,
441 "Result: %s (%u)", stopresulttype2str(result), result);
444 error = tvb_get_guint8(tvb, offset);
445 proto_tree_add_text(tree, tvb, offset, 1,
446 "Error: %s (%u)", errortype2str(error), error);
449 proto_tree_add_text(tree, tvb, offset, 2,
450 "Reserved: %u", tvb_get_ntohs(tvb, offset));
454 dissect_echo_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
457 proto_tree_add_text(tree, tvb, offset, 4,
458 "Identifier: %u", tvb_get_ntohl(tvb, offset));
462 dissect_echo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
468 proto_tree_add_text(tree, tvb, offset, 4,
469 "Identifier: %u", tvb_get_ntohl(tvb, offset));
472 result = tvb_get_guint8(tvb, offset);
473 proto_tree_add_text(tree, tvb, offset, 1,
474 "Result: %s (%u)", echoresulttype2str(result), result);
477 error = tvb_get_guint8(tvb, offset);
478 proto_tree_add_text(tree, tvb, offset, sizeof(error),
479 "Error: %s (%u)", errortype2str(error), error);
482 proto_tree_add_text(tree, tvb, offset, 2,
483 "Reserved: %u", tvb_get_ntohs(tvb, offset));
487 dissect_out_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
492 guint8 phone[PHONELEN+1];
493 guint8 subaddr[SUBADDRLEN+1];
495 proto_tree_add_text(tree, tvb, offset, 2,
496 "Call ID: %u", tvb_get_ntohs(tvb, offset));
499 proto_tree_add_text(tree, tvb, offset, 2,
500 "Call Serial Number: %u", tvb_get_ntohs(tvb, offset));
503 proto_tree_add_text(tree, tvb, offset, 4,
504 "Minimum BPS: %u", tvb_get_ntohl(tvb, offset));
507 proto_tree_add_text(tree, tvb, offset, 4,
508 "Maximum BPS: %u", tvb_get_ntohl(tvb, offset));
511 bearer = tvb_get_ntohl(tvb, offset);
512 proto_tree_add_text(tree, tvb, offset, 4,
513 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
516 frame = tvb_get_ntohl(tvb, offset);
517 proto_tree_add_text(tree, tvb, offset, 4,
518 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
521 proto_tree_add_text(tree, tvb, offset, 2,
522 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
525 proto_tree_add_text(tree, tvb, offset, 2,
526 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
529 proto_tree_add_text(tree, tvb, offset, 2,
530 "Phone number length: %u", tvb_get_ntohs(tvb, offset));
533 proto_tree_add_text(tree, tvb, offset, 2,
534 "Reserved: %u", tvb_get_ntohs(tvb, offset));
537 tvb_get_nstringz0(tvb, offset, PHONELEN, phone);
538 proto_tree_add_text(tree, tvb, offset, PHONELEN,
539 "Phone number: %s", phone);
542 tvb_get_nstringz0(tvb, offset, SUBADDRLEN, subaddr);
543 proto_tree_add_text(tree, tvb, offset, SUBADDRLEN,
544 "Subaddress: %s", subaddr);
548 dissect_out_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
554 proto_tree_add_text(tree, tvb, offset, 2,
555 "Call ID: %u", tvb_get_ntohs(tvb, offset));
558 proto_tree_add_text(tree, tvb, offset, 2,
559 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
562 result = tvb_get_guint8(tvb, offset);
563 proto_tree_add_text(tree, tvb, offset, 1,
564 "Result: %s (%u)", outresulttype2str(result), result);
567 error = tvb_get_guint8(tvb, offset);
568 proto_tree_add_text(tree, tvb, offset, 1,
569 "Error: %s (%u)", errortype2str(error), error);
572 proto_tree_add_text(tree, tvb, offset, 2,
573 "Cause code: %u", tvb_get_ntohs(tvb, offset));
576 proto_tree_add_text(tree, tvb, offset, 4,
577 "Connect speed: %u", tvb_get_ntohl(tvb, offset));
580 proto_tree_add_text(tree, tvb, offset, 2,
581 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
584 proto_tree_add_text(tree, tvb, offset, 2,
585 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
588 proto_tree_add_text(tree, tvb, offset, 4,
589 "Physical channel ID: %u", tvb_get_ntohl(tvb, offset));
593 dissect_in_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
597 guint8 dialed[PHONELEN+1];
598 guint8 dialing[PHONELEN+1];
599 guint8 subaddr[SUBADDRLEN+1];
601 proto_tree_add_text(tree, tvb, offset, 2,
602 "Call ID: %u", tvb_get_ntohs(tvb, offset));
605 proto_tree_add_text(tree, tvb, offset, 2,
606 "Call serial number: %u", tvb_get_ntohs(tvb, offset));
609 bearer = tvb_get_ntohl(tvb, offset);
610 proto_tree_add_text(tree, tvb, offset, 4,
611 "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
614 proto_tree_add_text(tree, tvb, offset, 4,
615 "Physical channel ID: %u", tvb_get_ntohl(tvb, offset));
618 proto_tree_add_text(tree, tvb, offset, 2,
619 "Dialed number length: %u", tvb_get_ntohs(tvb, offset));
622 proto_tree_add_text(tree, tvb, offset, 2,
623 "Dialing number length: %u", tvb_get_ntohs(tvb, offset));
626 tvb_get_nstringz0(tvb, offset, PHONELEN, dialed);
627 proto_tree_add_text(tree, tvb, offset, PHONELEN,
628 "Dialed number: %s", dialed);
631 tvb_get_nstringz0(tvb, offset, PHONELEN, dialing);
632 proto_tree_add_text(tree, tvb, offset, PHONELEN,
633 "Dialing number: %s", dialing);
636 tvb_get_nstringz0(tvb, offset, SUBADDRLEN, subaddr);
637 proto_tree_add_text(tree, tvb, offset, SUBADDRLEN,
638 "Subaddress: %s", subaddr);
642 dissect_in_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
648 proto_tree_add_text(tree, tvb, offset, 2,
649 "Call ID: %u", tvb_get_ntohs(tvb, offset));
652 proto_tree_add_text(tree, tvb, offset, 2,
653 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
656 result = tvb_get_guint8(tvb, offset);
657 proto_tree_add_text(tree, tvb, offset, 1,
658 "Result: %s (%u)", inresulttype2str(result), result);
661 error = tvb_get_guint8(tvb, offset);
662 proto_tree_add_text(tree, tvb, offset, 1,
663 "Error: %s (%u)", errortype2str(error), error);
666 proto_tree_add_text(tree, tvb, offset, 2,
667 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
670 proto_tree_add_text(tree, tvb, offset, 2,
671 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
674 proto_tree_add_text(tree, tvb, offset, 2,
675 "Reserved: %u", tvb_get_ntohs(tvb, offset));
679 dissect_in_connected(tvbuff_t *tvb, int offset, packet_info *pinfo,
684 proto_tree_add_text(tree, tvb, offset, 2,
685 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
688 proto_tree_add_text(tree, tvb, offset, 2,
689 "Reserved: %u", tvb_get_ntohs(tvb, offset));
692 proto_tree_add_text(tree, tvb, offset, 4,
693 "Connect speed: %u", tvb_get_ntohl(tvb, offset));
696 proto_tree_add_text(tree, tvb, offset, 2,
697 "Receive window size: %u", tvb_get_ntohs(tvb, offset));
700 proto_tree_add_text(tree, tvb, offset, 2,
701 "Processing delay: %u", tvb_get_ntohs(tvb, offset));
704 frame = tvb_get_ntohl(tvb, offset);
705 proto_tree_add_text(tree, tvb, offset, 4,
706 "Framing capabilities: %s (%u)", frametype2str(frame), frame);
710 dissect_clear_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
713 proto_tree_add_text(tree, tvb, offset, 2,
714 "Call ID: %u", tvb_get_ntohs(tvb, offset));
717 proto_tree_add_text(tree, tvb, offset, 2,
718 "Reserved: %u", tvb_get_ntohs(tvb, offset));
722 dissect_disc_notify(tvbuff_t *tvb, int offset, packet_info *pinfo,
727 guint8 stats[STATSLEN+1];
729 proto_tree_add_text(tree, tvb, offset, 2,
730 "Call ID: %u", tvb_get_ntohs(tvb, offset));
733 result = tvb_get_guint8(tvb, offset);
734 proto_tree_add_text(tree, tvb, offset, 1,
735 "Result: %s (%u)", discresulttype2str(result), result);
738 error = tvb_get_guint8(tvb, offset);
739 proto_tree_add_text(tree, tvb, offset, 1,
740 "Error: %s (%u)", errortype2str(error), error);
743 proto_tree_add_text(tree, tvb, offset, 2,
744 "Cause code: %u", tvb_get_ntohs(tvb, offset));
747 proto_tree_add_text(tree, tvb, offset, 2,
748 "Reserved: %u", tvb_get_ntohs(tvb, offset));
751 tvb_get_nstringz0(tvb, offset, STATSLEN, stats);
752 proto_tree_add_text(tree, tvb, offset, STATSLEN,
753 "Call statistics: %s", stats);
757 dissect_error_notify(tvbuff_t *tvb, int offset, packet_info *pinfo,
760 proto_tree_add_text(tree, tvb, offset, 2,
761 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
764 proto_tree_add_text(tree, tvb, offset, 2,
765 "Reserved: %u", tvb_get_ntohs(tvb, offset));
768 proto_tree_add_text(tree, tvb, offset, 4,
769 "CRC errors: %u", tvb_get_ntohl(tvb, offset));
772 proto_tree_add_text(tree, tvb, offset, 4,
773 "Framing errors: %u", tvb_get_ntohl(tvb, offset));
776 proto_tree_add_text(tree, tvb, offset, 4,
777 "Hardware overruns: %u", tvb_get_ntohl(tvb, offset));
780 proto_tree_add_text(tree, tvb, offset, 4,
781 "Buffer overruns: %u", tvb_get_ntohl(tvb, offset));
784 proto_tree_add_text(tree, tvb, offset, 4,
785 "Time-out errors: %u", tvb_get_ntohl(tvb, offset));
788 proto_tree_add_text(tree, tvb, offset, 4,
789 "Alignment errors: %u", tvb_get_ntohl(tvb, offset));
793 dissect_set_link(tvbuff_t *tvb, int offset, packet_info *pinfo,
796 proto_tree_add_text(tree, tvb, offset, 2,
797 "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
800 proto_tree_add_text(tree, tvb, offset, 2,
801 "Reserved: %u", tvb_get_ntohs(tvb, offset));
804 proto_tree_add_text(tree, tvb, offset, 4,
805 "Send ACCM: %#08x", tvb_get_ntohl(tvb, offset));
808 proto_tree_add_text(tree, tvb, offset, 4,
809 "Recv ACCM: %#08x", tvb_get_ntohl(tvb, offset));
813 proto_register_pptp(void)
815 static gint *ett[] = {
819 static hf_register_info hf[] = {
820 { &hf_pptp_message_type,
821 { "Message type", "pptp.type",
822 FT_UINT16, BASE_DEC, VALS(msgtype_vals), 0x0,
823 "PPTP message type" }}
826 proto_pptp = proto_register_protocol("Point-to-Point Tunnelling Protocol",
828 proto_register_field_array(proto_pptp, hf, array_length(hf));
829 proto_register_subtree_array(ett, array_length(ett));
833 proto_reg_handoff_pptp(void)
835 dissector_add("tcp.port", TCP_PORT_PPTP, dissect_pptp);