Do not use "match_strval()" unless you're prepared to check whether it
[metze/wireshark/wip.git] / packet-l2tp.c
1 /* packet-l2tp.c
2  * Routines for Layer Two Tunnelling Protocol (L2TP) (RFC 2661) packet
3  * disassembly
4  * John Thomes <john@ensemblecom.com>
5  *
6  * Minor changes by: (2000-01-10)
7  * Laurent Cazalet <laurent.cazalet@mailclub.net>
8  * Thomas Parvais <thomas.parvais@advalvas.be>
9  *
10  * $Id: packet-l2tp.c,v 1.20 2001/01/09 06:31:38 guy Exp $
11  *
12  * Ethereal - Network traffic analyzer
13  * By Gerald Combs <gerald@zing.org>
14  * Copyright 1998 Gerald Combs
15  *
16  * 
17  * This program is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU General Public License
19  * as published by the Free Software Foundation; either version 2
20  * of the License, or (at your option) any later version.
21  * 
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  * 
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
30  */
31
32
33 static int proto_l2tp = -1;
34 static int hf_l2tp_code = -1; /* XXX - to be removed */
35 static int hf_l2tp_type = -1;
36 static int hf_l2tp_length_bit = -1;
37 static int hf_l2tp_seq_bit = -1;
38 static int hf_l2tp_offset_bit = -1;
39 static int hf_l2tp_priority = -1; 
40 static int hf_l2tp_version = -1;
41 static int hf_l2tp_length = -1;
42 static int hf_l2tp_tunnel = -1;
43 static int hf_l2tp_session = -1;
44 static int hf_l2tp_Ns = -1;
45 static int hf_l2tp_Nr = -1;
46 static int hf_l2tp_offset = -1;
47
48 #ifdef HAVE_CONFIG_H
49 #include "config.h"
50 #endif
51
52 #ifdef HAVE_SYS_TYPES_H
53 # include <sys/types.h>
54 #endif
55
56 #ifdef HAVE_NETINET_IN_H
57 #include <netinet/in.h>
58 #endif
59
60 #include <stdio.h>
61 #include <stdlib.h>
62 #include <string.h>
63 #include <ctype.h>
64 #include <glib.h>
65 #include "packet.h"
66 #include "resolv.h"
67
68 #define UDP_PORT_L2TP   1701
69
70 #define CONTROL_BIT(msg_info) (msg_info & 0x8000)   /* Type bit control = 1 data = 0 */
71 #define LENGTH_BIT(msg_info) (msg_info & 0x4000)    /* Length bit = 1  */ 
72 #define RESERVE_BITS(msg_info) (msg_info &0x37F8)   /* Reserved bit - usused */
73 #define SEQUENCE_BIT(msg_info) (msg_info & 0x0800)  /* SEQUENCE bit = 1 Ns and Nr fields */
74 #define OFFSET_BIT(msg_info) (msg_info & 0x0200)    /* Offset */
75 #define PRIORITY_BIT(msg_info) (msg_info & 0x0100)  /* Priority */
76 #define L2TP_VERSION(msg_info) (msg_info & 0x000f)  /* Version of l2tp */
77 #define MANDATORY_BIT(msg_info) (msg_info & 0x8000) /* Mandatory = 1 */
78 #define HIDDEN_BIT(msg_info) (msg_info & 0x4000)    /* Hidden = 1 */
79 #define AVP_LENGTH(msg_info) (msg_info & 0x03ff)    /* AVP Length */
80 #define FRAMING_ASYNC(msg_info) (msg_info & 0x0001) /* ASYNCFraming Type */
81 #define FRAMING_SYNC(msg_info)  (msg_info & 0x0002) /* SYNC Type */
82
83
84 static gint ett_l2tp = -1;
85 static gint ett_l2tp_ctrl = -1;
86 static gint ett_l2tp_avp = -1;
87
88 #define AVP_SCCRQ      1
89 #define AVP_SCCRP      2
90 #define AVP_SCCCN      3
91 #define AVP_StopCCN    4
92 #define AVP_Reserved   5
93 #define AVP_HELLO      6 
94 #define AVP_OCRQ       7 
95 #define AVP_OCRP       8 
96 #define AVP_ORCRP      9 
97 #define AVP_ICRQ      10 
98 #define AVP_ICRP      11 
99 #define AVP_ICCN      12 
100 #define AVP_Reserved1 13 
101 #define AVP_CDN       14 
102
103
104 #define NUM_CONTROL_CALL_TYPES  16
105 static const char *calltypestr[NUM_CONTROL_CALL_TYPES+1] = {
106   "Unknown Call Type           ",
107   "Start_Control_Request       ",
108   "Start_Control_Reply         ",
109   "Start_Control_Connected     ",
110   "Stop_Control_Notification   ",
111   "Reserved                    ",
112   "Hello                       ",
113   "Outgoing_Call_Request       ",
114   "Outgoing_Call_Reply         ",
115   "Outgoing_Call_Connected     ",
116   "Incoming_Call_Request       ",
117   "Incoming_Call_Reply         ",
118   "Incoming_Call_Connected     ",
119   "Reserved                    ",
120   "Call_Disconnect_Notification",
121   "WAN_Error_Notify            ",
122   "Set_Link_Info               ",
123 };
124
125 static const char *calltype_short_str[NUM_CONTROL_CALL_TYPES+1] = {
126   "Unknown ",
127   "SCCRQ   ",
128   "SCCRP   ",
129   "SCCCN   ",
130   "StopCCN ",
131   "Reserved",
132   "Hello   ",
133   "OCRQ    ",
134   "OCRP    ",
135   "OCCN    ",
136   "ICRQ    ",
137   "ICRP    ",
138   "ICCN    ",
139   "Reserved",
140   "CDN     ",
141   "WEN     ",
142   "SLI     ",
143 };
144
145
146 static const char *control_msg  = "Control Message";
147 static const char *data_msg     = "Data    Message";
148 static const value_string l2tp_type_vals[] = {
149         { 0, "Data Message" },
150         { 1, "Control Message" },
151         { 0, NULL },
152 };
153
154 static const true_false_string l2tp_length_bit_truth =
155         { "Length field is present", "Length field is not present" };
156
157 static const true_false_string l2tp_seq_bit_truth =
158         { "Ns and Nr fields are present", "Ns and Nr fields are not present" };
159
160 static const true_false_string l2tp_offset_bit_truth =
161         { "Offset Size field is present", "Offset size field is not present" };
162
163 static const true_false_string l2tp_priority_truth =
164         { "This data message has priority", "No priority" };
165
166 #define NUM_AUTH_TYPES  6
167 static const char *authen_types[NUM_AUTH_TYPES] = {
168   "Reserved",
169   "Textual username and password",
170   "PPP CHAP",
171   "PPP PAP",
172   "No Authentication",
173   "Microsoft CHAP Version 1",
174 };
175
176 #define  CONTROL_MESSAGE  0
177 #define  RESULT_ERROR_CODE 1
178 #define  PROTOCOL_VERSION  2
179 #define  FRAMING_CAPABIlITIES 3
180 #define  BEARER_CAPABIlITIES 4
181 #define  TIE_BREAKER 5
182 #define  FIRMWARE_REVISION 6
183 #define  HOST_NAME 7
184 #define  VENDOR_NAME 8
185 #define  ASSIGNED_TUNNEL_ID 9
186 #define  RECEIVE_WINDOW_SIZE 10
187 #define  CHALLENGE 11
188 #define  CAUSE_CODE 12 
189 #define  CHALLENGE_RESPONSE 13
190 #define  ASSIGNED_SESSION 14
191 #define  CALL_SERIAL_NUMBER 15
192 #define  MINIMUM_BPS 16
193 #define  MAXIMUM_BPS 17
194 #define  BEARER_TYPE 18
195 #define  FRAMING_TYPE 19
196 #define  UNKNOWN_MESSAGE 20
197 #define  CALLED_NUMBER 21
198 #define  CALLING_NUMBER 22
199 #define  SUB_ADDRESS 23
200 #define  TX_CONNECT_SPEED 24
201 #define  PHYSICAL_CHANNEL 25
202 #define  INITIAL_RECEIVED_LCP 26
203 #define  LAST_SEND_LCP_CONFREQ 27
204 #define  LAST_RECEIVED_LCP_CONFREQ 28
205 #define  PROXY_AUTHEN_TYPE 29
206 #define  PROXY_AUTHEN_NAME 30
207 #define  PROXY_AUTHEN_CHALLENGE 31
208 #define  PROXY_AUTHEN_ID 32
209 #define  PROXY_AUTHEN_RESPONSE 33
210 #define  CALL_STATUS_AVPS 34
211 #define  ACCM 35
212 #define  UNKOWN_MESSAGE_36
213 #define  PRIVATE_GROUP_ID 37
214 #define  RX_CONNECT_SPEED 38
215 #define  SEQUENCING_REQUIRED 39
216
217 #define NUM_AVP_TYPES  40
218 static const char *avptypestr[NUM_AVP_TYPES] = {
219   "Control Message ",
220   "Result-Error Code ",
221   "Protocol Version ",
222   "Framing Capabilities ",
223   "Bearer Capabilities  ",
224   "Tie Breaker ",
225   "Firmware Revision ",
226   "Host Name ",
227   "Vendor Name ",
228   "Assigned Tunnel ID ",
229   "Receive Window Size ",
230   "Challenge ",
231   "Cause Code ",
232   "Challenge Response ",
233   "Assigned Session ",
234   "Call Serial Number ",
235   "Minimun BPS ",
236   "Maximum bps ",
237   "Bearer Type ",
238   "Framing Type ",
239   "Unknown Message ",
240   "Called Number ",
241   "Calling Number ",
242   "Sub-Address ",
243   "Connect Speed ",
244   "Physical Channel ",
245   "Initial Received lcP ",
246   "Last Send LCP CONFREQ ",
247   "Last Received LCP CONFREQ ",
248   "Proxy Authen Type ",
249   "Proxy Authen Name ",
250   "Proxy Authen Challenge ",
251   "Proxy Authen ID ",
252   "Proxy Authen Response ",
253   "Call status AVPs ",
254   "ACCM ",
255   "Unknown Message ",
256   "Private group ID ",
257   "RxConnect Speed ",
258   "Sequencing Required ",
259 };
260
261
262 static gchar textbuffer[200];
263
264 static dissector_handle_t ppp_handle;
265
266 static void
267 dissect_l2tp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
268 {
269   proto_tree *l2tp_tree=NULL, *l2tp_avp_tree, *ctrl_tree;
270   proto_item *ti, *tf;
271   int rhcode;
272   int index = 0;
273   int tmp_index;
274   int proto_length = 0;
275   unsigned short  length = 0;           /* Length field */
276   unsigned short  tid;                  /* Tunnel ID */
277   unsigned short  cid;                  /* Call ID */
278   unsigned short  offset_size;          /* Offset size */
279   unsigned short ver_len_hidden;
280   unsigned short vendor;
281   unsigned short avp_type;
282   unsigned short msg_type;
283   unsigned short avp_len;
284   unsigned short result_code;
285   unsigned short error_code;
286   unsigned short avp_ver;
287   unsigned short avp_rev;
288   unsigned short framing;
289   unsigned short firmware_rev;
290   unsigned short gen_type;
291   unsigned long long_type;
292   char  error_string[100];
293   char  message_string[200];
294
295   guint16       control;
296   tvbuff_t      *next_tvb;
297
298   CHECK_DISPLAY_AS_DATA(proto_l2tp, tvb, pinfo, tree);
299
300   pinfo->current_proto = "L2TP";
301   if (check_col(pinfo->fd, COL_PROTOCOL))       /* build output for closed L2tp frame displayed  */
302         col_set_str(pinfo->fd, COL_PROTOCOL, "L2TP"); 
303
304   control = tvb_get_ntohs(tvb, 0);
305
306   if (L2TP_VERSION(control) != 2) {
307           if (check_col(pinfo->fd, COL_INFO)) {
308                 col_add_fstr(pinfo->fd, COL_INFO, "L2TP Version %u", L2TP_VERSION(control) );
309           }
310           return;
311   }
312
313   rhcode= 10;
314
315   if (LENGTH_BIT(control)) {            /* length field included ? */
316       index += 2;                       /* skip ahead */
317       length = tvb_get_ntohs(tvb, index);
318   }
319
320   /* collect the tunnel id & call id */
321   index += 2;
322   tid = tvb_get_ntohs(tvb, index);
323   index += 2;
324   cid = tvb_get_ntohs(tvb, index);
325
326   if (check_col(pinfo->fd, COL_INFO)) {
327         if (CONTROL_BIT(control)) {
328             /* CONTROL MESSAGE */
329             tmp_index = index;
330
331               if ((LENGTH_BIT(control))&&(length==12))                  /* ZLB Message */
332                   sprintf(textbuffer,"%s - ZLB      (tunnel id=%d, session id=%d)",
333                           control_msg , tid ,cid);
334               else
335               {
336                 if (SEQUENCE_BIT(control)) {
337                     tmp_index += 4;
338                 }
339     
340                 tmp_index+=4;
341     
342                 avp_type = tvb_get_ntohs(tvb, (tmp_index+=2));
343     
344                 if (avp_type == CONTROL_MESSAGE)
345                 {
346                     /* We print message type */
347                     msg_type = tvb_get_ntohs(tvb, (tmp_index+=2));
348                     sprintf(textbuffer,"%s - %s (tunnel id=%d, session id=%d)",
349                             control_msg ,
350                             ((NUM_CONTROL_CALL_TYPES + 1 ) > msg_type) ?
351                             calltype_short_str[msg_type] : "Unknown",
352                             tid ,cid);
353                 }
354                 else
355                 {
356                     /*
357                      * This is not a control message.
358                      * We never pass here except in case of bad l2tp packet!
359                      */
360                     sprintf(textbuffer,"%s (tunnel id=%d, session id=%d)",
361                             control_msg ,  tid ,cid);
362     
363                 }
364               }
365         }
366         else {
367             /* DATA Message */
368                sprintf(textbuffer,"%s            (tunnel id=%d, session id=%d)",
369                        data_msg, tid ,cid);
370         }
371         col_add_fstr(pinfo->fd,COL_INFO,textbuffer);
372   }
373
374   if (LENGTH_BIT(control)) {
375         proto_length = length;
376   }
377   else {
378         proto_length = tvb_length(tvb);
379   }
380
381   if (tree) {
382         ti = proto_tree_add_item(tree,proto_l2tp, tvb, 0, proto_length, FALSE);
383         l2tp_tree = proto_item_add_subtree(ti, ett_l2tp);
384
385         ti = proto_tree_add_text(l2tp_tree, tvb, 0, 2,
386                         "Packet Type: %s Tunnel Id=%d Session Id=%d",
387                         (CONTROL_BIT(control) ? control_msg : data_msg), tid, cid);
388
389         ctrl_tree = proto_item_add_subtree(ti, ett_l2tp_ctrl);
390         proto_tree_add_uint(ctrl_tree, hf_l2tp_type, tvb, 0, 2, control);
391         proto_tree_add_boolean(ctrl_tree, hf_l2tp_length_bit, tvb, 0, 2, control);
392         proto_tree_add_boolean(ctrl_tree, hf_l2tp_seq_bit, tvb, 0, 2, control);
393         proto_tree_add_boolean(ctrl_tree, hf_l2tp_offset_bit, tvb, 0, 2, control);
394         proto_tree_add_boolean(ctrl_tree, hf_l2tp_priority, tvb, 0, 2, control);
395         proto_tree_add_uint(ctrl_tree, hf_l2tp_version, tvb, 0, 2, control);
396   }
397   index = 2;
398   if (LENGTH_BIT(control)) {
399           if (tree) {
400                 proto_tree_add_item(l2tp_tree, hf_l2tp_length, tvb, index, 2, FALSE);
401           }
402         index += 2;
403   }
404
405   if (tree) {
406         proto_tree_add_item(l2tp_tree, hf_l2tp_tunnel, tvb, index, 2, FALSE);
407   }
408   index += 2;
409   if (tree) {
410         proto_tree_add_item(l2tp_tree, hf_l2tp_session, tvb, index, 2, FALSE);
411   }
412   index += 2;
413
414   if (SEQUENCE_BIT(control)) {
415           if (tree) {
416                 proto_tree_add_item(l2tp_tree, hf_l2tp_Ns, tvb, index, 2, FALSE);
417           }
418           index += 2;
419           if (tree) {
420                 proto_tree_add_item(l2tp_tree, hf_l2tp_Nr, tvb, index, 2, FALSE);
421           }
422           index += 2;
423   }
424   if (OFFSET_BIT(control)) {
425         offset_size = tvb_get_ntohs(tvb, index);
426         if (tree) {
427                 proto_tree_add_uint(l2tp_tree, hf_l2tp_offset, tvb, index, 2, FALSE);
428         }
429         index += 2;
430         if (tree) {
431                 proto_tree_add_text(l2tp_tree, tvb, index, offset_size, "Offset Padding");
432         }
433         index += offset_size;
434   }
435   if (tree && (LENGTH_BIT(control))&&(length==12)) {
436             proto_tree_add_text(l2tp_tree, tvb, 0, 0, "Zero Length Bit message");
437   }
438
439   if (!CONTROL_BIT(control)) {  /* Data Messages so we are done */
440         /* If we have data, signified by having a length bit, dissect it */
441         if (tvb_offset_exists(tvb, index)) {
442                 next_tvb = tvb_new_subset(tvb, index, -1, proto_length - index);
443                 call_dissector(ppp_handle, next_tvb, pinfo, tree);
444         }
445         return;
446   }
447
448   if (tree) {
449         if (!LENGTH_BIT(control)) {
450                 return;
451         }
452         while (index < length ) {    /* Process AVP's */
453                 tmp_index       = index;
454                 ver_len_hidden  = tvb_get_ntohs(tvb, tmp_index);
455                 avp_len         = AVP_LENGTH(ver_len_hidden);
456                 vendor          = tvb_get_ntohs(tvb, (tmp_index+=2));
457                 avp_type        = tvb_get_ntohs(tvb, (tmp_index+=2));
458
459                 tf =  proto_tree_add_uint_format(l2tp_tree,hf_l2tp_code, tvb, index , avp_len,
460                                                  rhcode, "AVP Type  %s  ",  (NUM_AVP_TYPES > avp_type)
461                                                  ? avptypestr[avp_type] : "Unknown");
462                 l2tp_avp_tree = proto_item_add_subtree(tf,  ett_l2tp_avp);
463
464                 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index , 1,
465                                            rhcode, " Mandatory:%s" ,
466                                            (MANDATORY_BIT(ver_len_hidden)) ? "True" : "False" );
467                 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index , 1,
468                                            rhcode, " Hidden:%s" ,
469                                            (HIDDEN_BIT(ver_len_hidden)) ? "True" : "False" );
470                 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, (index + 1), 1,
471                                            rhcode, " Length:%d" , avp_len );
472
473                 if (avp_len == 0) {
474                         proto_tree_add_text(l2tp_avp_tree, tvb, (index + 1), 1, "Length should not be zero");
475                         return;
476                 }
477
478                 if (HIDDEN_BIT(ver_len_hidden)) { /* don't try do display hidden */
479                         index += avp_len;
480                         continue;
481                 }
482
483                 switch (avp_type) {
484
485                 case CONTROL_MESSAGE:
486                     msg_type = tvb_get_ntohs(tvb, (tmp_index+=2));
487                     proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 2 ,
488                                                rhcode, " Control Message Type: (%d)  %s", msg_type,
489                                                ((NUM_CONTROL_CALL_TYPES + 1 ) > msg_type) ?
490                                                calltypestr[msg_type] : "Unknown" );
491                     break;
492
493                 case RESULT_ERROR_CODE:
494                         if ( avp_len >= 8 ) {
495                                 result_code = tvb_get_ntohs(tvb, (tmp_index+=2));
496                                 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
497                                   2, rhcode,
498                                   " Result code: %d",  result_code  );
499                 
500                         }
501                         if ( avp_len >= 10 ) {
502                                 error_code = tvb_get_ntohs(tvb, (tmp_index+=2));
503                                 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 8,
504                                   2, rhcode,
505                                   " Error code: %d", error_code);
506                         }
507                         if ( avp_len > 10 ) {
508                                 memset(error_string,'\0' ,sizeof(error_string));
509                                 strncpy(error_string, tvb_get_ptr(tvb, tmp_index,(avp_len - 10)),
510                                                 avp_len - 10);
511                                 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 10, (avp_len - 10),
512                                   rhcode, " Error Message: %s",  error_string  );
513                         }
514                         break;
515
516                 case PROTOCOL_VERSION:
517                         avp_ver = tvb_get_ntohs(tvb, (tmp_index+=2));
518                         avp_rev = tvb_get_ntohs(tvb, (tmp_index+=2));
519                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 1,
520                           rhcode, " Version: %d",  ((avp_ver&0xff00)>>8)  );
521                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 7, 1,
522                           rhcode, " Revision: %d",  (avp_ver&0x00ff));
523                         break;
524
525                 case FRAMING_CAPABIlITIES:
526                         tmp_index+=2;
527                         framing = tvb_get_ntohs(tvb, (tmp_index+=2));
528                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 4,
529                           rhcode, " ASYNC FRAMING: %s" , (FRAMING_ASYNC(framing)) ? "True" : "False" );  
530                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 4,
531                           rhcode, " SYNC FRAMING: %s" , (FRAMING_SYNC(framing)) ? "True" : "False" );  
532                         break;
533
534                 case BEARER_CAPABIlITIES:
535                         tmp_index+=2;
536                         framing = tvb_get_ntohs(tvb, (tmp_index+=2));
537                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 4 ,
538                           rhcode, " Analog Access: %s" , (FRAMING_ASYNC(framing)) ? "True" : "False" );  
539                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 4,
540                           rhcode, " Digital Access: %s" , (FRAMING_SYNC(framing)) ? "True" : "False" );  
541                         break;
542
543                 case TIE_BREAKER:
544                         long_type = tvb_get_ntohl(tvb, (tmp_index+=8));
545                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 1,
546                           rhcode, " TIE_BREAKER %lu 0x%lx", long_type,long_type );
547                         break;
548
549                 case FIRMWARE_REVISION:
550                         firmware_rev = tvb_get_ntohs(tvb, (tmp_index+=2));
551                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 2,
552                           rhcode, " Firmware Revision: %d 0x%x", firmware_rev,firmware_rev );
553                         break;
554
555                 case HOST_NAME:
556                         memset(error_string,'\0',sizeof(error_string));
557                         strncpy(error_string, tvb_get_ptr(tvb, (tmp_index+=2), (avp_len - 6)),
558                                         avp_len - 6);
559                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 
560                           (avp_len - 6), rhcode, " Host Name: %s",  error_string  );
561                         break;
562
563                 case VENDOR_NAME:
564                         memset(message_string,'\0' ,sizeof(message_string));
565                         strncpy(message_string, tvb_get_ptr(tvb, (tmp_index+=2),(avp_len - 6)),
566                                         avp_len - 6);
567                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 
568                           (avp_len - 6), rhcode, " Vendor Name: %s",  message_string  );
569                         break;
570
571                 case ASSIGNED_TUNNEL_ID:
572                         gen_type = tvb_get_ntohs(tvb, (tmp_index+=2));
573                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
574                           2, rhcode, " Tunnel ID: %d",  gen_type  );
575                         break;
576
577                 case RECEIVE_WINDOW_SIZE:
578                         gen_type = tvb_get_ntohs(tvb, (tmp_index+=2));
579                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
580                           2, rhcode, " Receive Window Size: %d",  gen_type  );
581                         break;
582
583                 case CHALLENGE:
584                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
585                           (avp_len - 6 ), rhcode, "  CHAP Challenge: ");
586                         break;
587
588                 case CHALLENGE_RESPONSE:
589                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
590                           (avp_len - 6 ), rhcode, "  CHAP Challenge Response: ");
591                         break;
592
593                 case CAUSE_CODE:
594                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
595                           1, rhcode, " Cause Code: ");
596                         break;
597
598                 case ASSIGNED_SESSION:
599                         gen_type = tvb_get_ntohs(tvb, (tmp_index+=2));
600                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
601                           2, rhcode, " Assigned Session: %d",  gen_type  );
602                         break;
603
604                 case CALL_SERIAL_NUMBER:
605                         gen_type = tvb_get_ntohs(tvb, (tmp_index+=2));
606                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
607                           4, rhcode, " Call Serial Number: %d",  gen_type  );
608                         break;
609
610                 case MINIMUM_BPS:
611                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
612                           4, rhcode, " Minimum BPS: ");
613                         break;
614
615                 case MAXIMUM_BPS:
616                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
617                           4, rhcode, " Maximum BPS ");
618                         break;
619
620                 case BEARER_TYPE:
621                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
622                           4, rhcode, " Bearer Type: ");
623                         break;
624
625                 case FRAMING_TYPE:
626                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
627                           4, rhcode, " Framing Type: ");
628                         break;
629
630                 case UNKNOWN_MESSAGE:
631                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
632                           1, rhcode, " Unknown Message: ");
633                         break;
634
635                 case CALLED_NUMBER:
636                         memset(message_string,'\0' ,sizeof(message_string));
637                         strncpy(message_string, tvb_get_ptr(tvb, (tmp_index+=2),(avp_len - 6)),
638                                         avp_len - 6);
639                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 
640                           (avp_len - 6), rhcode, " Called Number: %s",  message_string  );
641                         break;
642
643                 case CALLING_NUMBER:
644                         memset(message_string,'\0' ,sizeof(message_string));
645                         strncpy(message_string, tvb_get_ptr(tvb, (tmp_index+=2),(avp_len - 6)),
646                                         avp_len - 6);
647                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 
648                           (avp_len - 6), rhcode, " Calling Number: %s",  message_string  );
649                         break;
650
651                 case SUB_ADDRESS:
652                         memset(message_string,'\0' ,sizeof(message_string));
653                         strncpy(message_string, tvb_get_ptr(tvb, (tmp_index+=2),(avp_len - 6)),
654                                         avp_len - 6);
655                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 
656                           (avp_len - 6), rhcode, " Sub-Address: %s",  message_string  );
657                         break;
658
659                 case TX_CONNECT_SPEED:
660                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
661                           4, rhcode, " Connect Speed: ");
662                         break;
663
664                 case PHYSICAL_CHANNEL:
665                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
666                           4, rhcode, " Physical Channel: ");
667                         break;
668
669                 case INITIAL_RECEIVED_LCP:
670                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
671                           (avp_len - 6 ), rhcode, " Initial LCP Conf REQ: ");
672                         break;
673
674                 case LAST_SEND_LCP_CONFREQ:
675                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
676                           (avp_len - 6 ), rhcode, " Last Sent LCP Conf REQ: ");
677                         break;
678
679                 case LAST_RECEIVED_LCP_CONFREQ:
680                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
681                           (avp_len - 6 ), rhcode, " Last Received LCP Conf REQ: ");
682                         break;
683
684                 case PROXY_AUTHEN_TYPE:
685                         msg_type = tvb_get_ntohs(tvb, (tmp_index+=2));
686                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
687                           1, rhcode, " Proxy Authen Type: %s ", authen_types[msg_type] );
688                         break;
689
690                 case PROXY_AUTHEN_NAME:
691                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
692                           (avp_len - 6 ), rhcode, " Proxy Authen Name: ");
693                         break;
694
695                 case PROXY_AUTHEN_CHALLENGE:
696                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
697                           (avp_len - 6 ), rhcode, " Proxy Authen Challenge: ");
698                         break;
699
700                 case PROXY_AUTHEN_ID:
701                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
702                           2, rhcode, " Paorx Authen ID: ");
703                         break;
704
705                 case PROXY_AUTHEN_RESPONSE:
706                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
707                           (avp_len - 6 ), rhcode, " Proxy Authen Response: ");
708                         break;
709
710                 case CALL_STATUS_AVPS:
711                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
712                           4, rhcode, "  CRC Errors: ");
713                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 10,
714                           4, rhcode, "  Framing Errors: ");
715                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 14,
716                           4, rhcode, "  Hardware Overruns: ");
717                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 18,
718                           4, rhcode, "  Buffer Overruns: ");
719                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 23,
720                           4, rhcode, "  Time-out Errors: ");
721                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 26,
722                           4, rhcode, "  Alignment Errors: ");
723                         break;
724
725                 case ACCM:
726                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
727                           2, rhcode, " Reserve Quantity: ");
728                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 8,
729                           4, rhcode, " Send ACCM: ");
730                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 12,
731                           4, rhcode, " Recv ACCM: ");
732                         break;
733
734                 case PRIVATE_GROUP_ID:
735                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
736                           1, rhcode, " Private Group ID: ");
737                         break;
738
739                 case RX_CONNECT_SPEED:
740                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
741                           4, rhcode, " RX Connect Speed: ");
742                         break;
743
744                 case SEQUENCING_REQUIRED:
745                         proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index ,
746                           1, rhcode, " Sequencing Required: ");
747                         break;
748                 }
749
750                 /* printf("Avp Decode avp_len= %d index= %d length= %d %x\n ",avp_len,
751                    index,length,length); */
752
753                 index += avp_len;
754         }
755
756   }
757 }
758
759 /* registration with the filtering engine */
760 void
761 proto_register_l2tp(void)
762 {
763         static hf_register_info hf[] = {
764                 { &hf_l2tp_code,
765                 { "code", "lt2p.code", FT_UINT16, BASE_DEC, NULL, 0, /* XXX - to be removed */
766                         "Type bit" }},
767
768                 { &hf_l2tp_type,
769                 { "Type", "lt2p.type", FT_UINT16, BASE_DEC, VALS(l2tp_type_vals), 0x8000,
770                         "Type bit" }},
771
772                 { &hf_l2tp_length_bit,
773                 { "Length Bit", "lt2p.length_bit", FT_BOOLEAN, 16, TFS(&l2tp_length_bit_truth), 0x4000,
774                         "Length bit" }},
775
776                 { &hf_l2tp_seq_bit,
777                 { "Sequence Bit", "lt2p.seq_bit", FT_BOOLEAN, 16, TFS(&l2tp_seq_bit_truth), 0x0800,
778                         "Sequence bit" }},
779
780                 { &hf_l2tp_offset_bit,
781                 { "Offset bit", "lt2p.offset_bit", FT_BOOLEAN, 16, TFS(&l2tp_offset_bit_truth), 0x0200,
782                         "Offset bit" }},
783
784                 { &hf_l2tp_priority,
785                 { "Priority", "lt2p.priority", FT_BOOLEAN, 16, TFS(&l2tp_priority_truth), 0x0100,
786                         "Priority bit" }},
787
788                 { &hf_l2tp_version,
789                 { "Version", "lt2p.version", FT_UINT16, BASE_DEC, NULL, 0x000f,
790                         "Version" }},
791
792                 { &hf_l2tp_length,
793                 { "Length","l2tp.length", FT_UINT16, BASE_DEC, NULL, 0x0,
794                         "" }},
795
796                 { &hf_l2tp_tunnel,
797                 { "Tunnel ID","l2tp.tunnel", FT_UINT16, BASE_DEC, NULL, 0x0, /* Probably should be FT_BYTES */
798                         "Tunnel ID" }},
799
800                 { &hf_l2tp_session,
801                 { "Session ID","l2tp.session", FT_UINT16, BASE_DEC, NULL, 0x0, /* Probably should be FT_BYTES */
802                         "Session ID" }},
803
804                 { &hf_l2tp_Ns,
805                 { "Ns","l2tp.Ns", FT_UINT16, BASE_DEC, NULL, 0x0,
806                         "" }},
807
808                 { &hf_l2tp_Nr,
809                 { "Nr","l2tp.Nr", FT_UINT16, BASE_DEC, NULL, 0x0,
810                         "" }},
811
812                 { &hf_l2tp_offset,
813                 { "Offset","l2tp.offset", FT_UINT16, BASE_DEC, NULL, 0x0,
814                         "Number of octest past the L2TP header at which the"
815                                 "payload data starts." }},
816
817         };
818
819         static gint *ett[] = {
820                 &ett_l2tp,
821                 &ett_l2tp_ctrl,
822                 &ett_l2tp_avp,
823         };
824
825         proto_l2tp = proto_register_protocol(
826                 "Layer 2 Tunneling Protocol", "L2TP", "l2tp");
827         proto_register_field_array(proto_l2tp, hf, array_length(hf));
828         proto_register_subtree_array(ett, array_length(ett));
829 }
830
831 void
832 proto_reg_handoff_l2tp(void)
833 {
834         dissector_add("udp.port", UDP_PORT_L2TP, dissect_l2tp,
835             proto_l2tp);
836
837         /*
838          * Get a handle for the PPP dissector.
839          */
840         ppp_handle = find_dissector("ppp");
841 }