Make the Zebra dissector, and a routine it uses, static, as they're not
[obnox/wireshark/wip.git] / packet-pptp.c
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>
4  *
5  * $Id: packet-pptp.c,v 1.16 2001/01/03 06:55:31 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@zing.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * 
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.
16  * 
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.
21  * 
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.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
33 #endif
34
35 #include <stdio.h>
36
37 #ifdef HAVE_NETINET_IN_H
38 #include <netinet/in.h>
39 #endif
40
41 #include <glib.h>
42 #include "packet.h"
43
44 static int proto_pptp = -1;
45 static int hf_pptp_message_type = -1;
46
47 static gint ett_pptp = -1;
48
49 #define TCP_PORT_PPTP                   1723
50
51 #define MAGIC_COOKIE            0x1A2B3C4D
52
53 static const value_string msgtype_vals[] = {
54   { 1, "CONTROL-MESSAGE" },
55   { 2, "MANAGEMENT-MESSAGE" },
56   { 0, NULL }
57 };
58
59 #define NUM_FRAME_TYPES         4
60 #define frametype2str(t)        \
61   ((t < NUM_FRAME_TYPES) ? frametypestr[t] : "UNKNOWN-FRAMING-TYPE")
62
63 static const char *frametypestr[NUM_FRAME_TYPES] = {
64   "UNKNOWN-FRAMING-TYPE",
65   "ASYNCHRONOUS",
66   "SYNCHRONOUS",
67   "EITHER"
68 };
69
70 #define NUM_BEARER_TYPES        4
71 #define bearertype2str(t)       \
72   ((t < NUM_BEARER_TYPES) ? bearertypestr[t] : "UNKNOWN-BEARER-TYPE")
73
74 static const char *bearertypestr[NUM_BEARER_TYPES] = {
75   "UNKNOWN-BEARER-TYPE",
76   "ANALOG",
77   "DIGITAL",
78   "EITHER"
79 };
80
81 #define NUM_CNTRLRESULT_TYPES   6
82 #define cntrlresulttype2str(t)  \
83   ((t < NUM_CNTRLRESULT_TYPES) ? cntrlresulttypestr[t] : "UNKNOWN-CNTRLRESULT-TYPE")
84
85 static const char *cntrlresulttypestr[NUM_CNTRLRESULT_TYPES] = {
86   "UNKNOWN-CNTRLRESULT-TYPE",
87   "SUCCESS",
88   "GENERAL-ERROR",
89   "COMMAND-CHANNEL-EXISTS",
90   "NOT-AUTHORIZED",
91   "VERSION-NOT-SUPPORTED"
92 };
93
94 #define NUM_ERROR_TYPES         7
95 #define errortype2str(t)        \
96   ((t < NUM_ERROR_TYPES) ? errortypestr[t] : "UNKNOWN-ERROR-TYPE")
97
98 static const char *errortypestr[NUM_ERROR_TYPES] = {
99   "NONE",
100   "NOT-CONNECTED",
101   "BAD-FORMAT",
102   "BAD-VALUE",
103   "NO-RESOURCE",
104   "BAD-CALL-ID",
105   "PAC-ERROR"
106 };
107
108 #define NUM_REASON_TYPES        4
109 #define reasontype2str(t)       \
110   ((t < NUM_REASON_TYPES) ? reasontypestr[t] : "UNKNOWN-REASON-TYPE")
111
112 static const char *reasontypestr[NUM_REASON_TYPES] = {
113   "UNKNOWN-REASON-TYPE",
114   "NONE",
115   "STOP-PROTOCOL",
116   "STOP-LOCAL-SHUTDOWN"
117 };
118
119 #define NUM_STOPRESULT_TYPES    3
120 #define stopresulttype2str(t)   \
121   ((t < NUM_STOPRESULT_TYPES) ? stopresulttypestr[t] : "UNKNOWN-STOPRESULT-TYPE")
122
123 static const char *stopresulttypestr[NUM_STOPRESULT_TYPES] = {
124   "UNKNOWN-STOPRESULT-TYPE",
125   "SUCCESS",
126   "GENERAL-ERROR"
127 };
128
129 #define NUM_ECHORESULT_TYPES    3
130 #define echoresulttype2str(t)   \
131   ((t < NUM_ECHORESULT_TYPES) ? echoresulttypestr[t] : "UNKNOWN-ECHORESULT-TYPE")
132
133 static const char *echoresulttypestr[NUM_ECHORESULT_TYPES] = {
134   "UNKNOWN-ECHORESULT-TYPE",
135   "SUCCESS",
136   "GENERAL-ERROR"
137 };
138
139 #define NUM_OUTRESULT_TYPES     8
140 #define outresulttype2str(t)    \
141   ((t < NUM_OUTRESULT_TYPES) ? outresulttypestr[t] : "UNKNOWN-OUTRESULT-TYPE")
142
143 static const char *outresulttypestr[NUM_OUTRESULT_TYPES] = {
144   "UNKNOWN-OUTRESULT-TYPE",
145   "CONNECTED",
146   "GENERAL-ERROR",
147   "NO-CARRIER",
148   "BUSY",
149   "NO-DIAL-TONE",
150   "TIME-OUT",
151   "DO-NOT-ACCEPT"
152 };
153
154 #define NUM_INRESULT_TYPES      4
155 #define inresulttype2str(t)     \
156   ((t < NUM_INRESULT_TYPES) ? inresulttypestr[t] : "UNKNOWN-INRESULT-TYPE")
157
158 static const char *inresulttypestr[NUM_INRESULT_TYPES] = {
159   "UNKNOWN-INRESULT-TYPE",
160   "CONNECT",
161   "GENERAL-ERROR",
162   "DO-NOT-ACCEPT"
163 };
164
165 #define NUM_DISCRESULT_TYPES    5
166 #define discresulttype2str(t)   \
167   ((t < NUM_DISCRESULT_TYPES) ? discresulttypestr[t] : "UNKNOWN-DISCRESULT-TYPE")
168
169 static const char *discresulttypestr[NUM_DISCRESULT_TYPES] = {
170   "UNKNOWN-DISCRESULT-TYPE",
171   "LOST-CARRIER",
172   "GENERAL-ERROR",
173   "ADMIN-SHUTDOWN",
174   "REQUEST"
175 };
176
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 *);
193
194 #define NUM_CNTRL_TYPES         16
195 #define cntrltype2str(t)        \
196   ((t < NUM_CNTRL_TYPES) ? strfuncs[t].str : "UNKNOWN-CONTROL-TYPE")
197
198 static struct strfunc {
199   const char *  str;
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     }
218 };
219
220 /*
221  * Length of host name and vendor name strings in control requests and
222  * replies.
223  */
224 #define HOSTLEN         64
225 #define VENDORLEN       64
226
227 /*
228  * Length of phone number(s) and subaddress in call requests.
229  */
230 #define PHONELEN        64
231 #define SUBADDRLEN      64
232
233 /*
234  * Length of statistics in a Call-Disconnect-Notify message.
235  */
236 #define STATSLEN        128
237
238 static void
239 dissect_pptp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
240 {
241   int                   offset = 0;
242   guint16               len;
243   guint16               cntrl_type;
244
245   CHECK_DISPLAY_AS_DATA(proto_pptp, tvb, pinfo, tree);
246
247   pinfo->current_proto = "PPTP";
248
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);
253   
254   len        = tvb_get_ntohs(tvb, offset);
255   cntrl_type = tvb_get_ntohs(tvb, offset + 8);
256
257   if (check_col(pinfo->fd, COL_INFO))
258     col_add_fstr(pinfo->fd, COL_INFO, "%s", cntrltype2str(cntrl_type));
259
260   if (tree) {
261     guint32             cookie;
262     proto_item *        ti;
263     proto_tree *        pptp_tree;
264
265     ti = proto_tree_add_item(tree, proto_pptp, tvb, offset, len, FALSE);
266     pptp_tree = proto_item_add_subtree(ti, ett_pptp);
267     
268     proto_tree_add_text(pptp_tree, tvb, offset, 2, "Length: %u", len);
269     offset += 2;
270
271     proto_tree_add_item(pptp_tree, hf_pptp_message_type, tvb,
272                                offset, 2, FALSE);
273     offset += 2;
274
275     cookie = tvb_get_ntohl(tvb, offset);
276
277     if (cookie == MAGIC_COOKIE)
278       proto_tree_add_text(pptp_tree, tvb, offset, 4,
279                           "Cookie: %#08x (correct)", cookie);
280     else
281       proto_tree_add_text(pptp_tree, tvb, offset, 4,
282                           "Cookie: %#08x (incorrect)", cookie);
283     offset += 4;
284     
285     proto_tree_add_text(pptp_tree, tvb, offset, 2,
286                         "Control type: %s (%u)", cntrltype2str(cntrl_type), cntrl_type);
287     offset += 2;
288
289     proto_tree_add_text(pptp_tree, tvb, offset, 2,
290                         "Reserved: %u", tvb_get_ntohs(tvb, offset));
291     offset += 2;
292
293     if (cntrl_type < NUM_CNTRL_TYPES)
294       ( *(strfuncs[cntrl_type].func))(tvb, offset, pinfo, pptp_tree);
295     else
296       dissect_data(tvb, offset, pinfo, pptp_tree);
297   }
298 }
299
300 static void
301 dissect_unknown(tvbuff_t *tvb, int offset, packet_info *pinfo,
302                 proto_tree *tree)
303 {
304   dissect_data(tvb, offset, pinfo, tree);
305 }
306
307 static void
308 dissect_cntrl_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
309                   proto_tree *tree)
310 {
311   guint8                major_ver;
312   guint8                minor_ver;
313   guint32               frame;
314   guint32               bearer;
315   guint8                host[HOSTLEN+1];
316   guint8                vendor[VENDORLEN+1];
317
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);
322   offset += 2;
323
324   proto_tree_add_text(tree, tvb, offset, 2,
325                       "Reserved: %u", tvb_get_ntohs(tvb, offset));
326   offset += 2;
327
328   frame = tvb_get_ntohl(tvb, offset);
329   proto_tree_add_text(tree, tvb, offset, 4,
330                       "Framing capabilities: %s (%u)", frametype2str(frame), frame);
331   offset += 4;
332
333   bearer = tvb_get_ntohl(tvb, offset);
334   proto_tree_add_text(tree, tvb, offset, 4,
335                       "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
336   offset += 4;
337
338   proto_tree_add_text(tree, tvb, offset, 2,
339                       "Maximum channels: %u", tvb_get_ntohs(tvb, offset));
340   offset += 2;
341   
342   proto_tree_add_text(tree, tvb, offset, 2,
343                       "Firmware revision: %u", tvb_get_ntohs(tvb, offset));
344   offset += 2;
345   
346   tvb_get_nstringz0(tvb, offset, HOSTLEN, host);
347   proto_tree_add_text(tree, tvb, offset, HOSTLEN,
348                       "Hostname: %s", host);
349   offset += HOSTLEN;
350   
351   tvb_get_nstringz0(tvb, offset, VENDORLEN, vendor);
352   proto_tree_add_text(tree, tvb, offset, VENDORLEN,
353                       "Vendor: %s", vendor);
354 }
355
356 static void
357 dissect_cntrl_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
358                     proto_tree *tree)
359 {
360   guint8                major_ver;
361   guint8                minor_ver;
362   guint8                result;
363   guint8                error;
364   guint32               frame;
365   guint32               bearer;
366   guint8                host[HOSTLEN+1];
367   guint8                vendor[VENDORLEN+1];
368
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);
373   offset += 2;
374
375   result = tvb_get_guint8(tvb, offset);
376   proto_tree_add_text(tree, tvb, offset, 1,
377                       "Result: %s (%u)", cntrlresulttype2str(result), result);
378   offset += 1;
379   
380   error = tvb_get_guint8(tvb, offset);
381   proto_tree_add_text(tree, tvb, offset, 1,
382                       "Error: %s (%u)", errortype2str(error), error);
383   offset += 1;
384   
385   frame = tvb_get_ntohl(tvb, offset);
386   proto_tree_add_text(tree, tvb, offset, 4,
387                       "Framing capabilities: %s (%u)", frametype2str(frame), frame);
388   offset += 4;
389
390   bearer = tvb_get_ntohl(tvb, offset);
391   proto_tree_add_text(tree, tvb, offset, 4,
392                       "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
393   offset += 4;
394
395   proto_tree_add_text(tree, tvb, offset, 2,
396                       "Maximum channels: %u", tvb_get_ntohs(tvb, offset));
397   offset += 2;
398   
399   proto_tree_add_text(tree, tvb, offset, 2,
400                       "Firmware revision: %u", tvb_get_ntohs(tvb, offset));
401   offset += 2;
402   
403   tvb_get_nstringz0(tvb, offset, HOSTLEN, host);
404   proto_tree_add_text(tree, tvb, offset, HOSTLEN,
405                       "Hostname: %s", host);
406   offset += HOSTLEN;
407   
408   tvb_get_nstringz0(tvb, offset, VENDORLEN, vendor);
409   proto_tree_add_text(tree, tvb, offset, VENDORLEN,
410                       "Vendor: %s", vendor);
411 }
412
413 static void
414 dissect_stop_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
415                  proto_tree *tree)
416 {
417   guint8                reason;
418
419   reason = tvb_get_guint8(tvb, offset);
420   proto_tree_add_text(tree, tvb, offset, 1,
421                       "Reason: %s (%u)", reasontype2str(reason), reason);
422   offset += 1;
423   
424   proto_tree_add_text(tree, tvb, offset, 1,
425                       "Reserved: %u", tvb_get_guint8(tvb, offset));
426   offset += 1;
427   
428   proto_tree_add_text(tree, tvb, offset, 2,
429                       "Reserved: %u", tvb_get_ntohs(tvb, offset));
430 }
431
432 static void
433 dissect_stop_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
434                    proto_tree *tree)
435 {
436   guint8                result;
437   guint8                error;
438
439   result = tvb_get_guint8(tvb, offset);
440   proto_tree_add_text(tree, tvb, offset, 1,
441                       "Result: %s (%u)", stopresulttype2str(result), result);
442   offset += 1;
443   
444   error = tvb_get_guint8(tvb, offset);
445   proto_tree_add_text(tree, tvb, offset, 1,
446                       "Error: %s (%u)", errortype2str(error), error);
447   offset += 1;
448   
449   proto_tree_add_text(tree, tvb, offset, 2,
450                       "Reserved: %u", tvb_get_ntohs(tvb, offset));
451 }
452
453 static void
454 dissect_echo_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
455                  proto_tree *tree)
456 {
457   proto_tree_add_text(tree, tvb, offset, 4,
458                       "Identifier: %u", tvb_get_ntohl(tvb, offset));
459 }
460
461 static void
462 dissect_echo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
463                    proto_tree *tree)
464 {
465   guint8                result;
466   guint8                error;
467
468   proto_tree_add_text(tree, tvb, offset, 4,
469                       "Identifier: %u", tvb_get_ntohl(tvb, offset));
470   offset += 4;
471   
472   result = tvb_get_guint8(tvb, offset);
473   proto_tree_add_text(tree, tvb, offset, 1,
474                       "Result: %s (%u)", echoresulttype2str(result), result);
475   offset += 1;
476   
477   error = tvb_get_guint8(tvb, offset);
478   proto_tree_add_text(tree, tvb, offset, sizeof(error),
479                       "Error: %s (%u)", errortype2str(error), error);
480   offset += 1;
481   
482   proto_tree_add_text(tree, tvb, offset, 2,
483                       "Reserved: %u", tvb_get_ntohs(tvb, offset));
484 }
485
486 static void
487 dissect_out_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
488                 proto_tree *tree)
489 {
490   guint32               bearer;
491   guint32               frame;
492   guint8                phone[PHONELEN+1];
493   guint8                subaddr[SUBADDRLEN+1];
494
495   proto_tree_add_text(tree, tvb, offset, 2,
496                       "Call ID: %u", tvb_get_ntohs(tvb, offset));
497   offset += 2;
498   
499   proto_tree_add_text(tree, tvb, offset, 2,
500                       "Call Serial Number: %u", tvb_get_ntohs(tvb, offset));
501   offset += 2;
502   
503   proto_tree_add_text(tree, tvb, offset, 4,
504                       "Minimum BPS: %u", tvb_get_ntohl(tvb, offset));
505   offset += 4;
506   
507   proto_tree_add_text(tree, tvb, offset, 4,
508                       "Maximum BPS: %u", tvb_get_ntohl(tvb, offset));
509   offset += 4;
510   
511   bearer = tvb_get_ntohl(tvb, offset);
512   proto_tree_add_text(tree, tvb, offset, 4,
513                       "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
514   offset += 4;
515
516   frame = tvb_get_ntohl(tvb, offset);
517   proto_tree_add_text(tree, tvb, offset, 4,
518                       "Framing capabilities: %s (%u)", frametype2str(frame), frame);
519   offset += 4;
520
521   proto_tree_add_text(tree, tvb, offset, 2,
522                       "Receive window size: %u", tvb_get_ntohs(tvb, offset));
523   offset += 2;
524
525   proto_tree_add_text(tree, tvb, offset, 2,
526                       "Processing delay: %u", tvb_get_ntohs(tvb, offset));
527   offset += 2;
528   
529   proto_tree_add_text(tree, tvb, offset, 2,
530                       "Phone number length: %u", tvb_get_ntohs(tvb, offset));
531   offset += 2;
532   
533   proto_tree_add_text(tree, tvb, offset, 2,
534                       "Reserved: %u", tvb_get_ntohs(tvb, offset));
535   offset += 2;
536   
537   tvb_get_nstringz0(tvb, offset, PHONELEN, phone);
538   proto_tree_add_text(tree, tvb, offset, PHONELEN,
539                       "Phone number: %s", phone);
540   offset += PHONELEN;
541
542   tvb_get_nstringz0(tvb, offset, SUBADDRLEN, subaddr);
543   proto_tree_add_text(tree, tvb, offset, SUBADDRLEN,
544                       "Subaddress: %s", subaddr);
545 }
546
547 static void
548 dissect_out_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
549                   proto_tree *tree)
550 {
551   guint8                result;
552   guint8                error;
553
554   proto_tree_add_text(tree, tvb, offset, 2,
555                       "Call ID: %u", tvb_get_ntohs(tvb, offset));
556   offset += 2;
557   
558   proto_tree_add_text(tree, tvb, offset, 2,
559                       "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
560   offset += 2;
561
562   result = tvb_get_guint8(tvb, offset);
563   proto_tree_add_text(tree, tvb, offset, 1,
564                       "Result: %s (%u)", outresulttype2str(result), result);
565   offset += 1;
566   
567   error = tvb_get_guint8(tvb, offset);
568   proto_tree_add_text(tree, tvb, offset, 1,
569                       "Error: %s (%u)", errortype2str(error), error);
570   offset += 1;
571
572   proto_tree_add_text(tree, tvb, offset, 2,
573                       "Cause code: %u", tvb_get_ntohs(tvb, offset));
574   offset += 2;
575   
576   proto_tree_add_text(tree, tvb, offset, 4,
577                       "Connect speed: %u", tvb_get_ntohl(tvb, offset));
578   offset += 4;
579
580   proto_tree_add_text(tree, tvb, offset, 2,
581                       "Receive window size: %u", tvb_get_ntohs(tvb, offset));
582   offset += 2;
583
584   proto_tree_add_text(tree, tvb, offset, 2,
585                       "Processing delay: %u", tvb_get_ntohs(tvb, offset));
586   offset += 2;
587   
588   proto_tree_add_text(tree, tvb, offset, 4,
589                       "Physical channel ID: %u", tvb_get_ntohl(tvb, offset));
590 }
591
592 static void
593 dissect_in_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
594                proto_tree *tree)
595 {
596   guint32               bearer;
597   guint8                dialed[PHONELEN+1];
598   guint8                dialing[PHONELEN+1];
599   guint8                subaddr[SUBADDRLEN+1];
600
601   proto_tree_add_text(tree, tvb, offset, 2,
602                       "Call ID: %u", tvb_get_ntohs(tvb, offset));
603   offset += 2;
604   
605   proto_tree_add_text(tree, tvb, offset, 2,
606                       "Call serial number: %u", tvb_get_ntohs(tvb, offset));
607   offset += 2;
608   
609   bearer = tvb_get_ntohl(tvb, offset);
610   proto_tree_add_text(tree, tvb, offset, 4,
611                       "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
612   offset += 4;
613
614   proto_tree_add_text(tree, tvb, offset, 4,
615                       "Physical channel ID: %u", tvb_get_ntohl(tvb, offset));
616   offset += 4;
617
618   proto_tree_add_text(tree, tvb, offset, 2,
619                       "Dialed number length: %u", tvb_get_ntohs(tvb, offset));
620   offset += 2;
621   
622   proto_tree_add_text(tree, tvb, offset, 2,
623                       "Dialing number length: %u", tvb_get_ntohs(tvb, offset));
624   offset += 2;
625   
626   tvb_get_nstringz0(tvb, offset, PHONELEN, dialed);
627   proto_tree_add_text(tree, tvb, offset, PHONELEN,
628                       "Dialed number: %s", dialed);
629   offset += PHONELEN;
630   
631   tvb_get_nstringz0(tvb, offset, PHONELEN, dialing);
632   proto_tree_add_text(tree, tvb, offset, PHONELEN,
633                       "Dialing number: %s", dialing);
634   offset += PHONELEN;
635   
636   tvb_get_nstringz0(tvb, offset, SUBADDRLEN, subaddr);
637   proto_tree_add_text(tree, tvb, offset, SUBADDRLEN,
638                       "Subaddress: %s", subaddr);
639 }
640
641 static void
642 dissect_in_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
643                  proto_tree *tree)
644 {
645   guint8                result;
646   guint8                error;
647
648   proto_tree_add_text(tree, tvb, offset, 2,
649                       "Call ID: %u", tvb_get_ntohs(tvb, offset));
650   offset += 2;
651   
652   proto_tree_add_text(tree, tvb, offset, 2,
653                       "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
654   offset += 2;
655
656   result = tvb_get_guint8(tvb, offset);
657   proto_tree_add_text(tree, tvb, offset, 1,
658                       "Result: %s (%u)", inresulttype2str(result), result);
659   offset += 1;
660   
661   error = tvb_get_guint8(tvb, offset);
662   proto_tree_add_text(tree, tvb, offset, 1,
663                       "Error: %s (%u)", errortype2str(error), error);
664   offset += 1;
665
666   proto_tree_add_text(tree, tvb, offset, 2,
667                       "Receive window size: %u", tvb_get_ntohs(tvb, offset));
668   offset += 2;
669
670   proto_tree_add_text(tree, tvb, offset, 2,
671                       "Processing delay: %u", tvb_get_ntohs(tvb, offset));
672   offset += 2;
673   
674   proto_tree_add_text(tree, tvb, offset, 2,
675                       "Reserved: %u", tvb_get_ntohs(tvb, offset));
676 }
677
678 static void
679 dissect_in_connected(tvbuff_t *tvb, int offset, packet_info *pinfo,
680                      proto_tree *tree)
681 {
682   guint32               frame;
683   
684   proto_tree_add_text(tree, tvb, offset, 2,
685                       "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
686   offset += 2;
687
688   proto_tree_add_text(tree, tvb, offset, 2,
689                       "Reserved: %u", tvb_get_ntohs(tvb, offset));
690   offset += 2;
691
692   proto_tree_add_text(tree, tvb, offset, 4,
693                       "Connect speed: %u", tvb_get_ntohl(tvb, offset));
694   offset += 4;
695   
696   proto_tree_add_text(tree, tvb, offset, 2,
697                       "Receive window size: %u", tvb_get_ntohs(tvb, offset));
698   offset += 2;
699
700   proto_tree_add_text(tree, tvb, offset, 2,
701                       "Processing delay: %u", tvb_get_ntohs(tvb, offset));
702   offset += 2;
703   
704   frame = tvb_get_ntohl(tvb, offset);
705   proto_tree_add_text(tree, tvb, offset, 4,
706                       "Framing capabilities: %s (%u)", frametype2str(frame), frame);
707 }
708
709 static void
710 dissect_clear_req(tvbuff_t *tvb, int offset, packet_info *pinfo,
711                   proto_tree *tree)
712 {
713   proto_tree_add_text(tree, tvb, offset, 2,
714                       "Call ID: %u", tvb_get_ntohs(tvb, offset));
715   offset += 2;
716
717   proto_tree_add_text(tree, tvb, offset, 2,
718                       "Reserved: %u", tvb_get_ntohs(tvb, offset));
719 }
720
721 static void
722 dissect_disc_notify(tvbuff_t *tvb, int offset, packet_info *pinfo,
723                     proto_tree *tree)
724 {
725   guint8                result;
726   guint8                error;
727   guint8                stats[STATSLEN+1];
728
729   proto_tree_add_text(tree, tvb, offset, 2,
730                       "Call ID: %u", tvb_get_ntohs(tvb, offset));
731   offset += 2;
732
733   result = tvb_get_guint8(tvb, offset);
734   proto_tree_add_text(tree, tvb, offset, 1,
735                       "Result: %s (%u)", discresulttype2str(result), result);
736   offset += 1;
737   
738   error = tvb_get_guint8(tvb, offset);
739   proto_tree_add_text(tree, tvb, offset, 1,
740                       "Error: %s (%u)", errortype2str(error), error);
741   offset += 1;
742
743   proto_tree_add_text(tree, tvb, offset, 2,
744                       "Cause code: %u", tvb_get_ntohs(tvb, offset));
745   offset += 2;
746   
747   proto_tree_add_text(tree, tvb, offset, 2,
748                       "Reserved: %u", tvb_get_ntohs(tvb, offset));
749   offset += 2;
750
751   tvb_get_nstringz0(tvb, offset, STATSLEN, stats);
752   proto_tree_add_text(tree, tvb, offset, STATSLEN,
753                       "Call statistics: %s", stats);
754 }
755
756 static void
757 dissect_error_notify(tvbuff_t *tvb, int offset, packet_info *pinfo,
758                      proto_tree *tree)
759 {
760   proto_tree_add_text(tree, tvb, offset, 2,
761                       "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
762   offset += 2;
763
764   proto_tree_add_text(tree, tvb, offset, 2,
765                       "Reserved: %u", tvb_get_ntohs(tvb, offset));
766   offset += 2;
767
768   proto_tree_add_text(tree, tvb, offset, 4,
769                       "CRC errors: %u", tvb_get_ntohl(tvb, offset));
770   offset += 4;
771   
772   proto_tree_add_text(tree, tvb, offset, 4,
773                       "Framing errors: %u", tvb_get_ntohl(tvb, offset));
774   offset += 4;
775   
776   proto_tree_add_text(tree, tvb, offset, 4,
777                       "Hardware overruns: %u", tvb_get_ntohl(tvb, offset));
778   offset += 4;
779   
780   proto_tree_add_text(tree, tvb, offset, 4,
781                       "Buffer overruns: %u", tvb_get_ntohl(tvb, offset));
782   offset += 4;
783   
784   proto_tree_add_text(tree, tvb, offset, 4,
785                       "Time-out errors: %u", tvb_get_ntohl(tvb, offset));
786   offset += 4;
787   
788   proto_tree_add_text(tree, tvb, offset, 4,
789                       "Alignment errors: %u", tvb_get_ntohl(tvb, offset));
790 }
791
792 static void
793 dissect_set_link(tvbuff_t *tvb, int offset, packet_info *pinfo,
794                  proto_tree *tree)
795 {
796   proto_tree_add_text(tree, tvb, offset, 2,
797                       "Peer's call ID: %u", tvb_get_ntohs(tvb, offset));
798   offset += 2;
799
800   proto_tree_add_text(tree, tvb, offset, 2,
801                       "Reserved: %u", tvb_get_ntohs(tvb, offset));
802   offset += 2;
803
804   proto_tree_add_text(tree, tvb, offset, 4,
805                       "Send ACCM: %#08x", tvb_get_ntohl(tvb, offset));
806   offset += 4;
807   
808   proto_tree_add_text(tree, tvb, offset, 4,
809                       "Recv ACCM: %#08x", tvb_get_ntohl(tvb, offset));
810 }
811
812 void
813 proto_register_pptp(void)
814 {
815   static gint *ett[] = {
816     &ett_pptp,
817   };
818
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" }}
824   };
825
826   proto_pptp = proto_register_protocol("Point-to-Point Tunnelling Protocol",
827                                        "PPTP", "pptp");
828   proto_register_field_array(proto_pptp, hf, array_length(hf));
829   proto_register_subtree_array(ett, array_length(ett));
830 }
831
832 void
833 proto_reg_handoff_pptp(void)
834 {
835   dissector_add("tcp.port", TCP_PORT_PPTP, dissect_pptp);
836 }