MSWSP: add two more Property Sets
[wireshark-wip.git] / epan / dissectors / packet-pptp.c
blob606eb4833e994d1b540485e987dbdcdb2549fa4b
1 /* packet-pptp.c
2 * Routines for the Point-to-Point Tunnelling Protocol (PPTP) (RFC 2637)
3 * Brad Robel-Forrest <brad.robel-forrest@watchguard.com>
5 * 10/2010 - Rework PPTP Dissector
6 * Alexis La Goutte <alexis.lagoutte at gmail dot com>
8 * $Id$
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "config.h"
31 #include <glib.h>
32 #include <epan/packet.h>
33 #include <epan/expert.h>
35 static int proto_pptp = -1;
36 static int hf_pptp_length = -1;
37 static int hf_pptp_message_type = -1;
38 static int hf_pptp_magic_cookie = -1;
39 static int hf_pptp_control_message_type = -1;
40 static int hf_pptp_reserved = -1;
41 static int hf_pptp_protocol_version = -1;
42 static int hf_pptp_framing_capabilities = -1;
43 static int hf_pptp_bearer_capabilities = -1;
44 static int hf_pptp_maximum_channels = -1;
45 static int hf_pptp_firmware_revision = -1;
46 static int hf_pptp_host_name = -1;
47 static int hf_pptp_vendor_name = -1;
48 static int hf_pptp_control_result = -1;
49 static int hf_pptp_error = -1;
50 static int hf_pptp_reason = -1;
51 static int hf_pptp_stop_result = -1;
52 static int hf_pptp_identifier = -1;
53 static int hf_pptp_echo_result = -1;
54 static int hf_pptp_call_id = -1;
55 static int hf_pptp_call_serial_number = -1;
56 static int hf_pptp_minimum_bps = -1;
57 static int hf_pptp_maximum_bps = -1;
58 static int hf_pptp_bearer_type = -1;
59 static int hf_pptp_framing_type = -1;
60 static int hf_pptp_packet_receive_window_size = -1;
61 static int hf_pptp_packet_processing_delay = -1;
62 static int hf_pptp_phone_number_length = -1;
63 static int hf_pptp_phone_number = -1;
64 static int hf_pptp_subaddress = -1;
65 static int hf_pptp_peer_call_id = -1;
66 static int hf_pptp_out_result = -1;
67 static int hf_pptp_cause = -1;
68 static int hf_pptp_connect_speed = -1;
69 static int hf_pptp_physical_channel_id = -1;
70 static int hf_pptp_dialed_number_length = -1;
71 static int hf_pptp_dialed_number = -1;
72 static int hf_pptp_dialing_number_length = -1;
73 static int hf_pptp_dialing_number = -1;
74 static int hf_pptp_in_result = -1;
75 static int hf_pptp_disc_result = -1;
76 static int hf_pptp_call_statistics = -1;
77 static int hf_pptp_crc_errors = -1;
78 static int hf_pptp_framing_errors = -1;
79 static int hf_pptp_hardware_overruns = -1;
80 static int hf_pptp_buffer_overruns = -1;
81 static int hf_pptp_timeout_errors = -1;
82 static int hf_pptp_alignment_errors = -1;
83 static int hf_pptp_send_accm = -1;
84 static int hf_pptp_receive_accm = -1;
86 static gint ett_pptp = -1;
88 static expert_field ei_pptp_incorrect_magic_cookie = EI_INIT;
90 static dissector_handle_t data_handle;
92 #define TCP_PORT_PPTP 1723
94 #define MAGIC_COOKIE 0x1A2B3C4D
96 #define CNTRL_REQ 0x01
97 #define CNTRL_REPLY 0x02
98 #define STOP_REQ 0x03
99 #define STOP_REPLY 0x04
100 #define ECHO_REQ 0x05
101 #define ECHO_REPLY 0x06
102 #define OUT_REQ 0x07
103 #define OUT_REPLY 0x08
104 #define IN_REQ 0x09
105 #define IN_REPLY 0x0A
106 #define IN_CONNECTED 0x0B
107 #define CLEAR_REQ 0x0C
108 #define DISC_NOTIFY 0x0D
109 #define ERROR_NOTIFY 0x0E
110 #define SET_LINK 0x0F
112 static const value_string control_message_type_vals[] = {
113 { CNTRL_REQ, "Start-Control-Connection-Request" },
114 { CNTRL_REPLY, "Start-Control-Connection-Reply" },
115 { STOP_REQ, "Stop-Control-Connection-Request" },
116 { STOP_REPLY, "Stop-Control-Connection-Reply" },
117 { ECHO_REQ, "Echo-Request" },
118 { ECHO_REPLY, "Echo-Reply" },
119 { OUT_REQ, "Outgoing-Call-Request" },
120 { OUT_REPLY, "Outgoing-Call-Reply" },
121 { IN_REQ, "Incoming-Call-Request" },
122 { IN_REPLY, "Incoming-Call-Reply" },
123 { IN_CONNECTED, "Incoming-Call-Connected" },
124 { CLEAR_REQ, "Call-Clear-Request" },
125 { DISC_NOTIFY, "Call-Disconnect-Notify" },
126 { ERROR_NOTIFY, "WAN-Error-Notify" },
127 { SET_LINK, "Set-Link-Info" },
128 { 0, NULL },
130 static const value_string msgtype_vals[] = {
131 { 1, "Control Message" },
132 { 2, "Management Message" },
133 { 0, NULL }
136 static const value_string frametype_vals[] = {
137 { 1, "Asynchronous Framing supported" },
138 { 2, "Synchronous Framing supported"},
139 { 3, "Either Framing supported" },
140 { 0, NULL }
143 static const value_string bearertype_vals[] = {
144 { 1, "Analog access supported" },
145 { 2, "Digital access supported" },
146 { 3, "Either access supported" },
147 { 0, NULL }
150 static const value_string control_resulttype_vals[] = {
151 { 1, "Successful channel establishment" },
152 { 2, "General error" },
153 { 3, "Command channel already exists" },
154 { 4, "Requester not authorized" },
155 { 5, "Protocol version not supported" },
156 { 0, NULL }
159 static const value_string errortype_vals[] = {
160 { 0, "None" },
161 { 1, "Not-Connected" },
162 { 2, "Bad-Format" },
163 { 3, "Bad-Value" },
164 { 4, "No-Resource" },
165 { 5, "Bad-Call ID" },
166 { 6, "PAC-Error" },
167 { 0, NULL }
170 static const value_string reasontype_vals[] = {
171 { 1, "None" },
172 { 2, "Stop-Protocol" },
173 { 3, "Stop-Local-Shutdown" },
174 { 0, NULL }
177 static const value_string stop_resulttype_vals[] = {
178 { 1, "OK" },
179 { 2, "General error" },
180 { 0, NULL }
183 static const value_string echo_resulttype_vals[] = {
184 { 1, "OK" },
185 { 2, "General error" },
186 { 0, NULL }
189 static const value_string out_resulttype_vals[] = {
190 { 1, "Connected" },
191 { 2, "General Error" },
192 { 3, "No Carrier" },
193 { 4, "Busy" },
194 { 5, "No Dial Tone" },
195 { 6, "Time-out" },
196 { 7, "Do Not Accept" },
197 { 0, NULL }
200 static const value_string in_resulttype_vals[] = {
201 { 1, "Connect" },
202 { 2, "General error" },
203 { 3, "Do Not Accept" },
204 { 0, NULL }
207 static const value_string disc_resulttype_vals[] = {
208 { 1, "Lost Carrier" },
209 { 2, "General Error" },
210 { 3, "Admin Shutdown" },
211 { 4, "Request" },
212 { 0, NULL }
215 static void
216 dissect_unknown(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
218 call_dissector(data_handle,tvb_new_subset_remaining(tvb, offset), pinfo, tree);
221 static void
222 dissect_cntrl_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
224 if (!tree)
225 return;
227 proto_tree_add_uint_format_value(tree, hf_pptp_protocol_version, tvb, offset,
228 2, tvb_get_ntohs(tvb, offset), "%u.%u",
229 tvb_get_guint8(tvb, offset), tvb_get_guint8(tvb, offset + 1));
230 offset += 2;
232 proto_tree_add_item(tree, hf_pptp_reserved, tvb, offset, 2, ENC_NA);
233 offset += 2;
235 proto_tree_add_item(tree, hf_pptp_framing_capabilities, tvb, offset, 4, ENC_BIG_ENDIAN);
236 offset += 4;
238 proto_tree_add_item(tree, hf_pptp_bearer_capabilities, tvb, offset, 4, ENC_BIG_ENDIAN);
239 offset += 4;
241 proto_tree_add_item(tree, hf_pptp_maximum_channels, tvb, offset, 2, ENC_BIG_ENDIAN);
242 offset += 2;
244 proto_tree_add_item(tree, hf_pptp_firmware_revision, tvb, offset, 2, ENC_BIG_ENDIAN);
245 offset += 2;
247 proto_tree_add_item(tree, hf_pptp_host_name, tvb, offset, 64, ENC_ASCII|ENC_NA);
248 offset += 64;
250 proto_tree_add_item(tree, hf_pptp_vendor_name, tvb, offset, 64, ENC_ASCII|ENC_NA);
253 static void
254 dissect_cntrl_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
256 if (!tree)
257 return;
259 proto_tree_add_uint_format_value(tree, hf_pptp_protocol_version, tvb, offset,
260 2, tvb_get_ntohs(tvb, offset), "%u.%u",
261 tvb_get_guint8(tvb, offset), tvb_get_guint8(tvb, offset + 1));
262 offset += 2;
264 proto_tree_add_item(tree, hf_pptp_control_result, tvb, offset, 1, ENC_BIG_ENDIAN);
265 offset += 1;
267 proto_tree_add_item(tree, hf_pptp_error, tvb, offset, 1, ENC_BIG_ENDIAN);
268 offset += 1;
270 proto_tree_add_item(tree, hf_pptp_framing_capabilities, tvb, offset, 4, ENC_BIG_ENDIAN);
271 offset += 4;
273 proto_tree_add_item(tree, hf_pptp_bearer_capabilities, tvb, offset, 4, ENC_BIG_ENDIAN);
274 offset += 4;
276 proto_tree_add_item(tree, hf_pptp_maximum_channels, tvb, offset, 2, ENC_BIG_ENDIAN);
277 offset += 2;
279 proto_tree_add_item(tree, hf_pptp_firmware_revision, tvb, offset, 2, ENC_BIG_ENDIAN);
280 offset += 2;
282 proto_tree_add_item(tree, hf_pptp_host_name, tvb, offset, 64, ENC_ASCII|ENC_NA);
283 offset += 64;
285 proto_tree_add_item(tree, hf_pptp_vendor_name, tvb, offset, 64, ENC_ASCII|ENC_NA);
289 static void
290 dissect_stop_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
292 if (!tree)
293 return;
295 proto_tree_add_item(tree, hf_pptp_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
296 offset += 1;
298 proto_tree_add_item(tree, hf_pptp_reserved, tvb, offset, 1, ENC_NA);
299 offset += 1;
301 proto_tree_add_item(tree, hf_pptp_reserved, tvb, offset, 2, ENC_NA);
304 static void
305 dissect_stop_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
307 if (!tree)
308 return;
310 proto_tree_add_item(tree, hf_pptp_stop_result, tvb, offset, 1, ENC_BIG_ENDIAN);
311 offset += 1;
313 proto_tree_add_item(tree, hf_pptp_error, tvb, offset, 1, ENC_BIG_ENDIAN);
314 offset += 1;
316 proto_tree_add_item(tree, hf_pptp_reserved, tvb, offset, 2, ENC_NA);
320 static void
321 dissect_echo_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
323 if (!tree)
324 return;
326 proto_tree_add_item(tree, hf_pptp_identifier, tvb, offset, 4, ENC_BIG_ENDIAN);
329 static void
330 dissect_echo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
332 if (!tree)
333 return;
335 proto_tree_add_item(tree, hf_pptp_identifier, tvb, offset, 4, ENC_BIG_ENDIAN);
336 offset += 4;
338 proto_tree_add_item(tree, hf_pptp_echo_result, tvb, offset, 1, ENC_BIG_ENDIAN);
339 offset += 1;
341 proto_tree_add_item(tree, hf_pptp_error, tvb, offset, 1, ENC_BIG_ENDIAN);
342 offset += 1;
344 proto_tree_add_item(tree, hf_pptp_reserved, tvb, offset, 2, ENC_NA);
347 static void
348 dissect_out_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
350 if (!tree)
351 return;
353 proto_tree_add_item(tree, hf_pptp_call_id, tvb, offset, 2, ENC_BIG_ENDIAN);
354 offset += 2;
356 proto_tree_add_item(tree, hf_pptp_call_serial_number, tvb, offset, 2, ENC_BIG_ENDIAN);
357 offset += 2;
359 proto_tree_add_item(tree, hf_pptp_minimum_bps, tvb, offset, 4, ENC_BIG_ENDIAN);
360 offset += 4;
362 proto_tree_add_item(tree, hf_pptp_maximum_bps, tvb, offset, 4, ENC_BIG_ENDIAN);
363 offset += 4;
365 proto_tree_add_item(tree, hf_pptp_bearer_type, tvb, offset, 4, ENC_BIG_ENDIAN);
366 offset += 4;
368 proto_tree_add_item(tree, hf_pptp_framing_type, tvb, offset, 4, ENC_BIG_ENDIAN);
369 offset += 4;
371 proto_tree_add_item(tree, hf_pptp_packet_receive_window_size, tvb, offset, 2, ENC_BIG_ENDIAN);
372 offset += 2;
374 proto_tree_add_item(tree, hf_pptp_packet_processing_delay, tvb, offset, 2, ENC_BIG_ENDIAN);
375 offset += 2;
377 proto_tree_add_item(tree, hf_pptp_phone_number_length, tvb, offset, 2, ENC_BIG_ENDIAN);
378 offset += 2;
380 proto_tree_add_item(tree, hf_pptp_reserved, tvb, offset, 2, ENC_NA);
381 offset += 2;
383 proto_tree_add_item(tree, hf_pptp_phone_number, tvb, offset, 64, ENC_ASCII|ENC_NA);
384 offset += 64;
386 proto_tree_add_item(tree, hf_pptp_subaddress, tvb, offset, 64, ENC_ASCII|ENC_NA);
389 static void
390 dissect_out_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
392 if (!tree)
393 return;
395 proto_tree_add_item(tree, hf_pptp_call_id, tvb, offset, 2, ENC_BIG_ENDIAN);
396 offset += 2;
398 proto_tree_add_item(tree, hf_pptp_peer_call_id, tvb, offset, 2, ENC_BIG_ENDIAN);
399 offset += 2;
401 proto_tree_add_item(tree, hf_pptp_out_result, tvb, offset, 1, ENC_BIG_ENDIAN);
402 offset += 1;
404 proto_tree_add_item(tree, hf_pptp_error, tvb, offset, 1, ENC_BIG_ENDIAN);
405 offset += 1;
407 proto_tree_add_item(tree, hf_pptp_cause, tvb, offset, 2, ENC_BIG_ENDIAN);
408 offset += 2;
410 proto_tree_add_item(tree, hf_pptp_connect_speed, tvb, offset, 4, ENC_BIG_ENDIAN);
411 offset += 4;
413 proto_tree_add_item(tree, hf_pptp_packet_receive_window_size, tvb, offset, 2, ENC_BIG_ENDIAN);
414 offset += 2;
416 proto_tree_add_item(tree, hf_pptp_packet_processing_delay, tvb, offset, 2, ENC_BIG_ENDIAN);
417 offset += 2;
419 proto_tree_add_item(tree, hf_pptp_physical_channel_id, tvb, offset, 4, ENC_BIG_ENDIAN);
422 static void
423 dissect_in_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
425 if (!tree)
426 return;
428 proto_tree_add_item(tree, hf_pptp_call_id, tvb, offset, 2, ENC_BIG_ENDIAN);
429 offset += 2;
431 proto_tree_add_item(tree, hf_pptp_call_serial_number, tvb, offset, 2, ENC_BIG_ENDIAN);
432 offset += 2;
434 proto_tree_add_item(tree, hf_pptp_bearer_type, tvb, offset, 4, ENC_BIG_ENDIAN);
435 offset += 4;
437 proto_tree_add_item(tree, hf_pptp_physical_channel_id, tvb, offset, 4, ENC_BIG_ENDIAN);
438 offset += 4;
440 proto_tree_add_item(tree, hf_pptp_dialed_number_length, tvb, offset, 2, ENC_BIG_ENDIAN);
441 offset += 2;
443 proto_tree_add_item(tree, hf_pptp_dialing_number_length, tvb, offset, 2, ENC_BIG_ENDIAN);
444 offset += 2;
446 proto_tree_add_item(tree, hf_pptp_dialed_number, tvb, offset, 64, ENC_ASCII|ENC_NA);
447 offset += 64;
449 proto_tree_add_item(tree, hf_pptp_dialing_number, tvb, offset, 64, ENC_ASCII|ENC_NA);
450 offset += 64;
452 proto_tree_add_item(tree, hf_pptp_subaddress, tvb, offset, 64, ENC_ASCII|ENC_NA);
455 static void
456 dissect_in_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
458 if (!tree)
459 return;
461 proto_tree_add_item(tree, hf_pptp_call_id, tvb, offset, 2, ENC_BIG_ENDIAN);
462 offset += 2;
464 proto_tree_add_item(tree, hf_pptp_peer_call_id, tvb, offset, 2, ENC_BIG_ENDIAN);
465 offset += 2;
467 proto_tree_add_item(tree, hf_pptp_in_result, tvb, offset, 1, ENC_BIG_ENDIAN);
468 offset += 1;
470 proto_tree_add_item(tree, hf_pptp_error, tvb, offset, 1, ENC_BIG_ENDIAN);
471 offset += 1;
473 proto_tree_add_item(tree, hf_pptp_packet_receive_window_size, tvb, offset, 2, ENC_BIG_ENDIAN);
474 offset += 2;
476 proto_tree_add_item(tree, hf_pptp_packet_processing_delay, tvb, offset, 2, ENC_BIG_ENDIAN);
477 offset += 2;
479 proto_tree_add_item(tree, hf_pptp_reserved, tvb, offset, 2, ENC_NA);
482 static void
483 dissect_in_connected(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
485 if (!tree)
486 return;
488 proto_tree_add_item(tree, hf_pptp_peer_call_id, tvb, offset, 2, ENC_BIG_ENDIAN);
489 offset += 2;
491 proto_tree_add_item(tree, hf_pptp_reserved, tvb, offset, 2, ENC_NA);
492 offset += 2;
494 proto_tree_add_item(tree, hf_pptp_connect_speed, tvb, offset, 4, ENC_BIG_ENDIAN);
495 offset += 4;
497 proto_tree_add_item(tree, hf_pptp_packet_receive_window_size, tvb, offset, 2, ENC_BIG_ENDIAN);
498 offset += 2;
500 proto_tree_add_item(tree, hf_pptp_packet_processing_delay, tvb, offset, 2, ENC_BIG_ENDIAN);
501 offset += 2;
503 proto_tree_add_item(tree, hf_pptp_framing_type, tvb, offset, 4, ENC_BIG_ENDIAN);
506 static void
507 dissect_clear_req(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
509 if (!tree)
510 return;
512 proto_tree_add_item(tree, hf_pptp_call_id, tvb, offset, 2, ENC_BIG_ENDIAN);
513 offset += 2;
515 proto_tree_add_item(tree, hf_pptp_reserved, tvb, offset, 2, ENC_NA);
518 static void
519 dissect_disc_notify(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
521 if (!tree)
522 return;
524 proto_tree_add_item(tree, hf_pptp_call_id, tvb, offset, 2, ENC_BIG_ENDIAN);
525 offset += 2;
527 proto_tree_add_item(tree, hf_pptp_disc_result, tvb, offset, 1, ENC_BIG_ENDIAN);
528 offset += 1;
530 proto_tree_add_item(tree, hf_pptp_error, tvb, offset, 1, ENC_BIG_ENDIAN);
531 offset += 1;
533 proto_tree_add_item(tree, hf_pptp_cause, tvb, offset, 2, ENC_BIG_ENDIAN);
534 offset += 2;
536 proto_tree_add_item(tree, hf_pptp_reserved, tvb, offset, 2, ENC_NA);
537 offset += 2;
539 proto_tree_add_item(tree, hf_pptp_call_statistics, tvb, offset, 64, ENC_ASCII|ENC_NA);
542 static void
543 dissect_error_notify(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
545 if (!tree)
546 return;
548 proto_tree_add_item(tree, hf_pptp_peer_call_id, tvb, offset, 2, ENC_BIG_ENDIAN);
549 offset += 2;
551 proto_tree_add_item(tree, hf_pptp_reserved, tvb, offset, 2, ENC_NA);
552 offset += 2;
554 proto_tree_add_item(tree, hf_pptp_crc_errors, tvb, offset, 4, ENC_BIG_ENDIAN);
555 offset += 4;
557 proto_tree_add_item(tree, hf_pptp_framing_errors, tvb, offset, 4, ENC_BIG_ENDIAN);
558 offset += 4;
560 proto_tree_add_item(tree, hf_pptp_hardware_overruns, tvb, offset, 4, ENC_BIG_ENDIAN);
561 offset += 4;
563 proto_tree_add_item(tree, hf_pptp_buffer_overruns, tvb, offset, 4, ENC_BIG_ENDIAN);
564 offset += 4;
566 proto_tree_add_item(tree, hf_pptp_timeout_errors, tvb, offset, 4, ENC_BIG_ENDIAN);
567 offset += 4;
569 proto_tree_add_item(tree, hf_pptp_alignment_errors, tvb, offset, 4, ENC_BIG_ENDIAN);
572 static void
573 dissect_set_link(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
575 if (!tree)
576 return;
578 proto_tree_add_item(tree, hf_pptp_peer_call_id, tvb, offset, 2, ENC_BIG_ENDIAN);
579 offset += 2;
581 proto_tree_add_item(tree, hf_pptp_reserved, tvb, offset, 2, ENC_NA);
582 offset += 2;
584 proto_tree_add_item(tree, hf_pptp_send_accm, tvb, offset, 4, ENC_BIG_ENDIAN);
585 offset += 4;
587 proto_tree_add_item(tree, hf_pptp_receive_accm, tvb, offset, 4, ENC_BIG_ENDIAN);
590 static void
591 dissect_pptp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
593 proto_tree *pptp_tree = NULL;
594 proto_item *item = NULL;
595 int offset = 0;
596 guint16 len;
597 guint16 control_message_type;
599 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPTP");
600 col_clear(pinfo->cinfo, COL_INFO);
602 len = tvb_get_ntohs(tvb, offset);
603 control_message_type = tvb_get_ntohs(tvb, offset + 8);
605 col_add_str(pinfo->cinfo, COL_INFO,
606 val_to_str(control_message_type, control_message_type_vals,
607 "Unknown control type (%d)"));
609 if (tree) {
610 proto_item *ti;
612 ti = proto_tree_add_item(tree, proto_pptp, tvb, offset, len, ENC_NA);
613 pptp_tree = proto_item_add_subtree(ti, ett_pptp);
615 proto_tree_add_item(pptp_tree, hf_pptp_length, tvb, offset, 2, ENC_BIG_ENDIAN);
617 proto_tree_add_item(pptp_tree, hf_pptp_message_type, tvb, offset+2, 2, ENC_BIG_ENDIAN);
619 item = proto_tree_add_item(pptp_tree, hf_pptp_magic_cookie, tvb, offset+4, 4, ENC_BIG_ENDIAN);
622 if (tvb_get_ntohl(tvb, offset+4) == MAGIC_COOKIE)
623 proto_item_append_text(item," (correct)");
624 else {
625 proto_item_append_text(item," (incorrect)");
626 expert_add_info(pinfo, item, &ei_pptp_incorrect_magic_cookie);
629 if (tree) {
630 proto_tree_add_item(pptp_tree, hf_pptp_control_message_type, tvb, offset+8, 2, ENC_BIG_ENDIAN);
632 proto_tree_add_item(pptp_tree, hf_pptp_reserved, tvb, offset+10, 2, ENC_NA);
635 offset += offset + 12;
637 switch(control_message_type){
638 case CNTRL_REQ: /* Start-Control-Connection-Request */
639 dissect_cntrl_req(tvb, offset, pinfo, pptp_tree);
640 break;
641 case CNTRL_REPLY: /* Start-Control-Connection-Reply */
642 dissect_cntrl_reply(tvb, offset, pinfo, pptp_tree);
643 break;
644 case STOP_REQ: /* Stop-Control-Connection-Request */
645 dissect_stop_req(tvb, offset, pinfo, pptp_tree);
646 break;
647 case STOP_REPLY: /* Stop-Control-Connection-Reply */
648 dissect_stop_reply(tvb, offset, pinfo, pptp_tree);
649 break;
650 case ECHO_REQ: /* Echo-Request */
651 dissect_echo_req(tvb, offset, pinfo, pptp_tree);
652 break;
653 case ECHO_REPLY: /* Echo-Reply */
654 dissect_echo_reply(tvb, offset, pinfo, pptp_tree);
655 break;
656 case OUT_REQ: /* Outgoing-Call-Request */
657 dissect_out_req(tvb, offset, pinfo, pptp_tree);
658 break;
659 case OUT_REPLY: /* Outgoing-Call-Reply */
660 dissect_out_reply(tvb, offset, pinfo, pptp_tree);
661 break;
662 case IN_REQ: /* Incoming-Call-Request */
663 dissect_in_req(tvb, offset, pinfo, pptp_tree);
664 break;
665 case IN_REPLY: /* Incoming-Call-Reply */
666 dissect_in_reply(tvb, offset, pinfo, pptp_tree);
667 break;
668 case IN_CONNECTED: /* Incoming-Call-Connected */
669 dissect_in_connected(tvb, offset, pinfo, pptp_tree);
670 break;
671 case CLEAR_REQ: /* Call-Clear-Request */
672 dissect_clear_req(tvb, offset, pinfo, pptp_tree);
673 break;
674 case DISC_NOTIFY: /* Call-Disconnect-Notify */
675 dissect_disc_notify(tvb, offset, pinfo, pptp_tree);
676 break;
677 case ERROR_NOTIFY: /* WAN-Error-Notify */
678 dissect_error_notify(tvb, offset, pinfo, pptp_tree);
679 break;
680 case SET_LINK: /* Set-Link-Info */
681 dissect_set_link(tvb, offset, pinfo, pptp_tree);
682 break;
683 default: /* Unknown Type... */
684 dissect_unknown(tvb, offset, pinfo, pptp_tree);
685 break;
689 void
690 proto_register_pptp(void)
692 static gint *ett[] = {
693 &ett_pptp,
696 static hf_register_info hf[] = {
697 { &hf_pptp_length,
698 { "Length", "pptp.length",
699 FT_UINT16, BASE_DEC, NULL, 0x0,
700 "Total length in octets of this PPTP message", HFILL }
702 { &hf_pptp_message_type,
703 { "Message type", "pptp.type",
704 FT_UINT16, BASE_DEC, VALS(msgtype_vals), 0x0,
705 "PPTP message type", HFILL }
707 { &hf_pptp_magic_cookie,
708 { "Magic Cookie", "pptp.magic_cookie",
709 FT_UINT32, BASE_HEX, NULL, 0x0,
710 "This constant value is used as a sanity check on received messages", HFILL }
712 { &hf_pptp_control_message_type,
713 { "Control Message Type", "pptp.control_message_type",
714 FT_UINT16, BASE_DEC, VALS(control_message_type_vals), 0x0,
715 NULL, HFILL }
717 { &hf_pptp_reserved,
718 { "Reserved", "pptp.reserved",
719 FT_BYTES, BASE_NONE, NULL, 0x0,
720 "This field MUST be 0", HFILL }
722 { &hf_pptp_protocol_version,
723 { "Protocol version", "pptp.protocol_version",
724 FT_UINT16, BASE_DEC, NULL, 0x0,
725 "The version of the PPTP protocol", HFILL }
727 { &hf_pptp_framing_capabilities,
728 { "Framing Capabilities", "pptp.framing_capabilities",
729 FT_UINT32, BASE_DEC, VALS(frametype_vals), 0x0,
730 "A set of bits indicating the type of framing", HFILL }
732 { &hf_pptp_bearer_capabilities,
733 { "Bearer Capabilities", "pptp.bearer_capabilities",
734 FT_UINT32, BASE_DEC, VALS(bearertype_vals), 0x0,
735 "A set of bits indicating the type of bearer", HFILL }
737 { &hf_pptp_maximum_channels,
738 { "Maximum Channels", "pptp.maximum_channels",
739 FT_UINT16, BASE_DEC, NULL, 0x0,
740 "The total number of individual PPP sessions this PAC can support", HFILL }
742 { &hf_pptp_firmware_revision,
743 { "Firmware Revision", "pptp.firmware_revision",
744 FT_UINT16, BASE_DEC, NULL, 0x0,
745 "This field contains the firmware revision", HFILL }
747 { &hf_pptp_host_name,
748 { "Host Name", "pptp.host_name",
749 FT_STRING, BASE_NONE, NULL, 0x0,
750 "A 64 octet field containing the DNS name", HFILL }
752 { &hf_pptp_vendor_name,
753 { "Vendor Name", "pptp.vendor_name",
754 FT_STRING, BASE_NONE, NULL, 0x0,
755 "A 64 octet field containing a vendor", HFILL }
757 { &hf_pptp_control_result,
758 { "Result Code", "pptp.control_result",
759 FT_UINT8, BASE_DEC, VALS(control_resulttype_vals), 0x0,
760 "Indicates the result of the command channel establishment attempt", HFILL }
762 { &hf_pptp_error,
763 { "Error Code", "pptp.error",
764 FT_UINT8, BASE_DEC, VALS(errortype_vals), 0x0,
765 NULL, HFILL }
767 { &hf_pptp_reason,
768 { "Reason", "pptp.reason",
769 FT_UINT8, BASE_DEC, VALS(reasontype_vals), 0x0,
770 "Indicates the reason for the control connection being close", HFILL }
772 { &hf_pptp_stop_result,
773 { "Result Code", "pptp.stop_result",
774 FT_UINT8, BASE_DEC, VALS(stop_resulttype_vals), 0x0,
775 "Indicates the result of the attempt to close the control connection", HFILL }
777 { &hf_pptp_identifier,
778 { "Identifier", "pptp.identifier",
779 FT_UINT32, BASE_DEC, NULL, 0x0,
780 NULL, HFILL }
782 { &hf_pptp_echo_result,
783 { "Result Code", "pptp.echo_result",
784 FT_UINT8, BASE_DEC, VALS(echo_resulttype_vals), 0x0,
785 "Indicates the result of the receipt of the Echo-Request", HFILL }
787 { &hf_pptp_call_id,
788 { "Call ID", "pptp.call_id",
789 FT_UINT16, BASE_DEC, NULL, 0x0,
790 "A unique identifier, unique to a particular PAC-PNS pair assigned by the PNS", HFILL }
792 { &hf_pptp_call_serial_number,
793 { "Call Serial Number", "pptp.call_serial_number",
794 FT_UINT16, BASE_DEC, NULL, 0x0,
795 "An identifier assigned by the PNS to this session for the purpose of identifying this particular session in logged session information", HFILL }
797 { &hf_pptp_minimum_bps,
798 { "Minimum BPS", "pptp.minimum_bps",
799 FT_UINT32, BASE_DEC, NULL, 0x0,
800 "The lowest acceptable line speed (in bits/second) for this session", HFILL }
802 { &hf_pptp_maximum_bps,
803 { "Maximum BPS", "pptp.maximum_bps",
804 FT_UINT32, BASE_DEC, NULL, 0x0,
805 "The highest acceptable line speed (in bits/second) for this session", HFILL }
807 { &hf_pptp_framing_type,
808 { "Framing Type", "pptp.framing_type",
809 FT_UINT32, BASE_DEC, VALS(frametype_vals), 0x0,
810 "A value indicating the type of PPP framing to be used for this outgoing call", HFILL }
812 { &hf_pptp_bearer_type,
813 { "Bearer Type", "pptp.bearer_type",
814 FT_UINT32, BASE_DEC, VALS(bearertype_vals), 0x0,
815 "A value indicating the bearer capability required for this outgoing call", HFILL }
817 { &hf_pptp_packet_receive_window_size,
818 { "Packet Receive Window Size", "pptp.packet_receive_window_size",
819 FT_UINT16, BASE_DEC, NULL, 0x0,
820 "A unique identifier, unique to a particular PAC-PNS pair assigned by the PNS", HFILL }
822 { &hf_pptp_packet_processing_delay,
823 { "Packet Processing Delay", "pptp.packet_processing_delay",
824 FT_UINT16, BASE_DEC, NULL, 0x0,
825 "A measure of the packet processing delay that might be imposed on data sent to the PNS from the PAC", HFILL }
827 { &hf_pptp_phone_number_length,
828 { "Phone Number Length", "pptp.phone_number_length",
829 FT_UINT16, BASE_DEC, NULL, 0x0,
830 "The actual number of valid digits in the Phone Number field", HFILL }
832 { &hf_pptp_phone_number,
833 { "Phone Number", "pptp.phone_number",
834 FT_STRING, BASE_NONE, NULL, 0x0,
835 "The number to be dialed to establish the outgoing session", HFILL }
837 { &hf_pptp_subaddress,
838 { "Subaddress", "pptp.subaddress",
839 FT_STRING, BASE_NONE, NULL, 0x0,
840 "A 64 octet field used to specify additional dialing information.", HFILL }
842 { &hf_pptp_peer_call_id,
843 { "Peer Call ID", "pptp.peer_call_id",
844 FT_UINT16, BASE_DEC, NULL, 0x0,
845 "This field is set to the value received in the Call ID field of the corresponding Outgoing-Call-Request message", HFILL }
847 { &hf_pptp_out_result,
848 { "Result Code", "pptp.out_result",
849 FT_UINT8, BASE_DEC, VALS(out_resulttype_vals), 0x0,
850 "Indicates the result of the receipt of the Outgoing-Call-Request attempt", HFILL }
852 { &hf_pptp_cause,
853 { "Cause Code", "pptp.cause",
854 FT_UINT16, BASE_DEC, NULL, 0x0,
855 "This field gives additional information", HFILL }
857 { &hf_pptp_connect_speed,
858 { "Connect Speed", "pptp.connect_speed",
859 FT_UINT32, BASE_DEC, NULL, 0x0,
860 "The actual connection speed used, in bits/second.", HFILL }
862 { &hf_pptp_physical_channel_id,
863 { "Physical Channel ID", "pptp.physical_channel_id",
864 FT_UINT32, BASE_DEC, NULL, 0x0,
865 "This field is set by the PAC in a vendor-specific manner to the physical channel number used to place this call", HFILL }
867 { &hf_pptp_dialed_number_length,
868 { "Dialed Number Length", "pptp.dialed_number_length",
869 FT_UINT16, BASE_DEC, NULL, 0x0,
870 "The actual number of valid digits in the Dialed Number field", HFILL }
872 { &hf_pptp_dialed_number,
873 { "Dialed Number", "pptp.dialed_number",
874 FT_STRING, BASE_NONE, NULL, 0x0,
875 "The number that was dialed by the caller", HFILL }
878 { &hf_pptp_dialing_number_length,
879 { "Dialing Number Length", "pptp.dialing_number_length",
880 FT_UINT16, BASE_DEC, NULL, 0x0,
881 "The actual number of valid digits in the Dialing Number field", HFILL }
883 { &hf_pptp_dialing_number,
884 { "Dialing Number", "pptp.dialing_number",
885 FT_STRING, BASE_NONE, NULL, 0x0,
886 "The number from which the call was placed", HFILL }
888 { &hf_pptp_in_result,
889 { "Result Code", "pptp.in_result",
890 FT_UINT8, BASE_DEC, VALS(in_resulttype_vals), 0x0,
891 "This value indicates the result of the Incoming-Call-Request attempt", HFILL }
893 { &hf_pptp_disc_result,
894 { "Result Code", "pptp.disc_result",
895 FT_UINT8, BASE_DEC, VALS(disc_resulttype_vals), 0x0,
896 "This value indicates the reason for the disconnect", HFILL }
898 { &hf_pptp_call_statistics,
899 { "Call Statistics", "pptp.call_Statistics",
900 FT_STRING, BASE_NONE, NULL, 0x0,
901 "This field is an ASCII string containing vendor-specific call statistics that can be logged for diagnostic purpose", HFILL }
903 { &hf_pptp_crc_errors,
904 { "CRC Errors", "pptp.crc_errors",
905 FT_UINT32, BASE_DEC, NULL, 0x0,
906 "Number of PPP frames received with CRC errors since session was established", HFILL }
908 { &hf_pptp_framing_errors,
909 { "Framing Errors", "pptp.framing_errors",
910 FT_UINT32, BASE_DEC, NULL, 0x0,
911 "Number of improperly framed PPP packets received", HFILL }
913 { &hf_pptp_hardware_overruns,
914 { "Hardware overruns", "pptp.hardware_overruns",
915 FT_UINT32, BASE_DEC, NULL, 0x0,
916 "Number of receive buffer over-runs since session was established", HFILL }
918 { &hf_pptp_buffer_overruns,
919 { "Buffer overruns", "pptp.buffer_overruns",
920 FT_UINT32, BASE_DEC, NULL, 0x0,
921 "Number of buffer over-runs detected since session was established", HFILL }
923 { &hf_pptp_timeout_errors,
924 { "Time-out Errors", "pptp.timeout_errors",
925 FT_UINT32, BASE_DEC, NULL, 0x0,
926 "Number of time-outs since call was established", HFILL }
928 { &hf_pptp_alignment_errors,
929 { "Alignment Errors", "pptp.alignment_errors",
930 FT_UINT32, BASE_DEC, NULL, 0x0,
931 "Number of Alignment errors since call was established", HFILL }
933 { &hf_pptp_send_accm,
934 { "Send ACCM", "pptp.send_accm",
935 FT_UINT32, BASE_HEX, NULL, 0x0,
936 "The send ACCM value the client should use to process outgoing PPP packets", HFILL }
938 { &hf_pptp_receive_accm,
939 { "Receive ACCM", "pptp.receive_accm",
940 FT_UINT32, BASE_HEX, NULL, 0x0,
941 "The Receive ACCM value the client should use to process incoming PPP packets", HFILL }
945 static ei_register_info ei[] = {
946 { &ei_pptp_incorrect_magic_cookie, { "pptp.magic_cookie.incorrect", PI_PROTOCOL, PI_WARN, "Incorrect Magic Cookie", EXPFILL }},
949 expert_module_t* expert_pptp;
951 proto_pptp = proto_register_protocol("Point-to-Point Tunnelling Protocol",
952 "PPTP", "pptp");
953 proto_register_field_array(proto_pptp, hf, array_length(hf));
954 proto_register_subtree_array(ett, array_length(ett));
955 expert_pptp = expert_register_protocol(proto_pptp);
956 expert_register_field_array(expert_pptp, ei, array_length(ei));
959 void
960 proto_reg_handoff_pptp(void)
962 dissector_handle_t pptp_handle;
964 pptp_handle = create_dissector_handle(dissect_pptp, proto_pptp);
965 dissector_add_uint("tcp.port", TCP_PORT_PPTP, pptp_handle);
966 data_handle = find_dissector("data");