2 * Routines for Layer Two Tunnelling Protocol (L2TP) (RFC 2661) packet
4 * John Thomes <john@ensemblecom.com>
6 * Minor changes by: (2000-01-10)
7 * Laurent Cazalet <laurent.cazalet@mailclub.net>
8 * Thomas Parvais <thomas.parvais@advalvas.be>
10 * $Id: packet-l2tp.c,v 1.18 2001/01/03 06:55:29 guy Exp $
12 * Ethereal - Network traffic analyzer
13 * By Gerald Combs <gerald@zing.org>
14 * Copyright 1998 Gerald Combs
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.
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.
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.
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;
52 #ifdef HAVE_SYS_TYPES_H
53 # include <sys/types.h>
56 #ifdef HAVE_NETINET_IN_H
57 #include <netinet/in.h>
68 #define UDP_PORT_L2TP 1701
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 */
84 static gint ett_l2tp = -1;
85 static gint ett_l2tp_ctrl = -1;
86 static gint ett_l2tp_avp = -1;
92 #define AVP_Reserved 5
100 #define AVP_Reserved1 13
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 ",
113 "Outgoing_Call_Request ",
114 "Outgoing_Call_Reply ",
115 "Outgoing_Call_Connected ",
116 "Incoming_Call_Request ",
117 "Incoming_Call_Reply ",
118 "Incoming_Call_Connected ",
120 "Call_Disconnect_Notification",
125 static const char *calltype_short_str[NUM_CONTROL_CALL_TYPES+1] = {
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" },
153 static const true_false_string l2tp_length_bit_truth =
154 { "Length field is present", "Length field is not present" };
156 static const true_false_string l2tp_seq_bit_truth =
157 { "Ns and Nr fields are present", "Ns and Nr fields are not present" };
159 static const true_false_string l2tp_offset_bit_truth =
160 { "Offset Size field is present", "Offset size field is not present" };
162 static const true_false_string l2tp_priority_truth =
163 { "This data message has priority", "No priority" };
165 #define NUM_AUTH_TYPES 6
166 static const char *authen_types[NUM_AUTH_TYPES] = {
168 "Textual username and password",
172 "Microsoft CHAP Version 1",
175 #define CONTROL_MESSAGE 0
176 #define RESULT_ERROR_CODE 1
177 #define PROTOCOL_VERSION 2
178 #define FRAMING_CAPABIlITIES 3
179 #define BEARER_CAPABIlITIES 4
180 #define TIE_BREAKER 5
181 #define FIRMWARE_REVISION 6
183 #define VENDOR_NAME 8
184 #define ASSIGNED_TUNNEL_ID 9
185 #define RECEIVE_WINDOW_SIZE 10
187 #define CAUSE_CODE 12
188 #define CHALLENGE_RESPONSE 13
189 #define ASSIGNED_SESSION 14
190 #define CALL_SERIAL_NUMBER 15
191 #define MINIMUM_BPS 16
192 #define MAXIMUM_BPS 17
193 #define BEARER_TYPE 18
194 #define FRAMING_TYPE 19
195 #define UNKNOWN_MESSAGE 20
196 #define CALLED_NUMBER 21
197 #define CALLING_NUMBER 22
198 #define SUB_ADDRESS 23
199 #define TX_CONNECT_SPEED 24
200 #define PHYSICAL_CHANNEL 25
201 #define INITIAL_RECEIVED_LCP 26
202 #define LAST_SEND_LCP_CONFREQ 27
203 #define LAST_RECEIVED_LCP_CONFREQ 28
204 #define PROXY_AUTHEN_TYPE 29
205 #define PROXY_AUTHEN_NAME 30
206 #define PROXY_AUTHEN_CHALLENGE 31
207 #define PROXY_AUTHEN_ID 32
208 #define PROXY_AUTHEN_RESPONSE 33
209 #define CALL_STATUS_AVPS 34
211 #define UNKOWN_MESSAGE_36
212 #define PRIVATE_GROUP_ID 37
213 #define RX_CONNECT_SPEED 38
214 #define SEQUENCING_REQUIRED 39
216 #define NUM_AVP_TYPES 40
217 static const char *avptypestr[NUM_AVP_TYPES] = {
219 "Result-Error Code ",
221 "Framing Capabilities ",
222 "Bearer Capabilities ",
224 "Firmware Revision ",
227 "Assigned Tunnel ID ",
228 "Receive Window Size ",
231 "Challenge Response ",
233 "Call Serial Number ",
244 "Initial Received lcP ",
245 "Last Send LCP CONFREQ ",
246 "Last Received LCP CONFREQ ",
247 "Proxy Authen Type ",
248 "Proxy Authen Name ",
249 "Proxy Authen Challenge ",
251 "Proxy Authen Response ",
257 "Sequencing Required ",
261 static gchar textbuffer[200];
263 static dissector_handle_t ppp_handle;
266 dissect_l2tp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
268 proto_tree *l2tp_tree=NULL, *l2tp_avp_tree, *ctrl_tree;
273 int proto_length = 0;
274 unsigned short length = 0; /* Length field */
275 unsigned short tid; /* Tunnel ID */
276 unsigned short cid; /* Call ID */
277 unsigned short offset_size; /* Offset size */
278 unsigned short ver_len_hidden;
279 unsigned short vendor;
280 unsigned short avp_type;
281 unsigned short msg_type;
282 unsigned short avp_len;
283 unsigned short result_code;
284 unsigned short error_code;
285 unsigned short avp_ver;
286 unsigned short avp_rev;
287 unsigned short framing;
288 unsigned short firmware_rev;
289 unsigned short gen_type;
290 unsigned long long_type;
291 char error_string[100];
292 char message_string[200];
297 CHECK_DISPLAY_AS_DATA(proto_l2tp, tvb, pinfo, tree);
299 pinfo->current_proto = "L2TP";
300 if (check_col(pinfo->fd, COL_PROTOCOL)) /* build output for closed L2tp frame displayed */
301 col_set_str(pinfo->fd, COL_PROTOCOL, "L2TP");
303 control = tvb_get_ntohs(tvb, 0);
305 if (L2TP_VERSION(control) != 2) {
306 if (check_col(pinfo->fd, COL_INFO)) {
307 col_add_fstr(pinfo->fd, COL_INFO, "L2TP Version %u", L2TP_VERSION(control) );
314 if (LENGTH_BIT(control)) { /* length field included ? */
315 index += 2; /* skip ahead */
316 length = tvb_get_ntohs(tvb, index);
319 /* collect the tunnel id & call id */
321 tid = tvb_get_ntohs(tvb, index);
323 cid = tvb_get_ntohs(tvb, index);
325 if (check_col(pinfo->fd, COL_INFO)) {
326 if (CONTROL_BIT(control)) {
327 /* CONTROL MESSAGE */
330 if ((LENGTH_BIT(control))&&(length==12)) /* ZLB Message */
331 sprintf(textbuffer,"%s - ZLB (tunnel id=%d, session id=%d)",
332 control_msg , tid ,cid);
335 if (SEQUENCE_BIT(control)) {
341 avp_type = tvb_get_ntohs(tvb, (tmp_index+=2));
343 if (avp_type == CONTROL_MESSAGE)
345 /* We print message type */
346 msg_type = tvb_get_ntohs(tvb, (tmp_index+=2));
347 sprintf(textbuffer,"%s - %s (tunnel id=%d, session id=%d)",
349 ((NUM_CONTROL_CALL_TYPES + 1 ) > msg_type) ?
350 calltype_short_str[msg_type] : "Unknown",
356 * This is not a control message.
357 * We never pass here except in case of bad l2tp packet!
359 sprintf(textbuffer,"%s (tunnel id=%d, session id=%d)",
360 control_msg , tid ,cid);
367 sprintf(textbuffer,"%s (tunnel id=%d, session id=%d)",
370 col_add_fstr(pinfo->fd,COL_INFO,textbuffer);
373 if (LENGTH_BIT(control)) {
374 proto_length = length;
377 proto_length = tvb_length(tvb);
381 ti = proto_tree_add_item(tree,proto_l2tp, tvb, 0, proto_length, FALSE);
382 l2tp_tree = proto_item_add_subtree(ti, ett_l2tp);
384 ti = proto_tree_add_text(l2tp_tree, tvb, 0, 2,
385 "Packet Type: %s Tunnel Id=%d Session Id=%d",
386 (CONTROL_BIT(control) ? control_msg : data_msg), tid, cid);
388 ctrl_tree = proto_item_add_subtree(ti, ett_l2tp_ctrl);
389 proto_tree_add_uint(ctrl_tree, hf_l2tp_type, tvb, 0, 2, control);
390 proto_tree_add_boolean(ctrl_tree, hf_l2tp_length_bit, tvb, 0, 2, control);
391 proto_tree_add_boolean(ctrl_tree, hf_l2tp_seq_bit, tvb, 0, 2, control);
392 proto_tree_add_boolean(ctrl_tree, hf_l2tp_offset_bit, tvb, 0, 2, control);
393 proto_tree_add_boolean(ctrl_tree, hf_l2tp_priority, tvb, 0, 2, control);
394 proto_tree_add_uint(ctrl_tree, hf_l2tp_version, tvb, 0, 2, control);
397 if (LENGTH_BIT(control)) {
399 proto_tree_add_item(l2tp_tree, hf_l2tp_length, tvb, index, 2, FALSE);
405 proto_tree_add_item(l2tp_tree, hf_l2tp_tunnel, tvb, index, 2, FALSE);
409 proto_tree_add_item(l2tp_tree, hf_l2tp_session, tvb, index, 2, FALSE);
413 if (SEQUENCE_BIT(control)) {
415 proto_tree_add_item(l2tp_tree, hf_l2tp_Ns, tvb, index, 2, FALSE);
419 proto_tree_add_item(l2tp_tree, hf_l2tp_Nr, tvb, index, 2, FALSE);
423 if (OFFSET_BIT(control)) {
424 offset_size = tvb_get_ntohs(tvb, index);
426 proto_tree_add_uint(l2tp_tree, hf_l2tp_offset, tvb, index, 2, FALSE);
430 proto_tree_add_text(l2tp_tree, tvb, index, offset_size, "Offset Padding");
432 index += offset_size;
434 if (tree && (LENGTH_BIT(control))&&(length==12)) {
435 proto_tree_add_text(l2tp_tree, tvb, 0, 0, "Zero Length Bit message");
438 if (!CONTROL_BIT(control)) { /* Data Messages so we are done */
439 /* If we have data, signified by having a length bit, dissect it */
440 if (tvb_offset_exists(tvb, index)) {
441 next_tvb = tvb_new_subset(tvb, index, -1, proto_length - index);
442 call_dissector(ppp_handle, next_tvb, pinfo, tree);
448 if (!LENGTH_BIT(control)) {
451 while (index < length ) { /* Process AVP's */
453 ver_len_hidden = tvb_get_ntohs(tvb, tmp_index);
454 avp_len = AVP_LENGTH(ver_len_hidden);
455 vendor = tvb_get_ntohs(tvb, (tmp_index+=2));
456 avp_type = tvb_get_ntohs(tvb, (tmp_index+=2));
458 tf = proto_tree_add_uint_format(l2tp_tree,hf_l2tp_code, tvb, index , avp_len,
459 rhcode, "AVP Type %s ", (NUM_AVP_TYPES > avp_type)
460 ? avptypestr[avp_type] : "Unknown");
461 l2tp_avp_tree = proto_item_add_subtree(tf, ett_l2tp_avp);
463 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index , 1,
464 rhcode, " Mandatory:%s" ,
465 (MANDATORY_BIT(ver_len_hidden)) ? "True" : "False" );
466 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index , 1,
467 rhcode, " Hidden:%s" ,
468 (HIDDEN_BIT(ver_len_hidden)) ? "True" : "False" );
469 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, (index + 1), 1,
470 rhcode, " Length:%d" , avp_len );
473 proto_tree_add_text(l2tp_avp_tree, tvb, (index + 1), 1, "Length should not be zero");
477 if (HIDDEN_BIT(ver_len_hidden)) { /* don't try do display hidden */
484 case CONTROL_MESSAGE:
485 msg_type = tvb_get_ntohs(tvb, (tmp_index+=2));
486 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 2 ,
487 rhcode, " Control Message Type: (%d) %s", msg_type,
488 ((NUM_CONTROL_CALL_TYPES + 1 ) > msg_type) ?
489 calltypestr[msg_type] : "Unknown" );
492 case RESULT_ERROR_CODE:
493 if ( avp_len >= 8 ) {
494 result_code = tvb_get_ntohs(tvb, (tmp_index+=2));
495 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
497 " Result code: %d", result_code );
500 if ( avp_len >= 10 ) {
501 error_code = tvb_get_ntohs(tvb, (tmp_index+=2));
502 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 8,
504 " Error code: %d", error_code);
506 if ( avp_len > 10 ) {
507 memset(error_string,'\0' ,sizeof(error_string));
508 strncpy(error_string, tvb_get_ptr(tvb, tmp_index,(avp_len - 10)),
510 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 10, (avp_len - 10),
511 rhcode, " Error Message: %s", error_string );
515 case PROTOCOL_VERSION:
516 avp_ver = tvb_get_ntohs(tvb, (tmp_index+=2));
517 avp_rev = tvb_get_ntohs(tvb, (tmp_index+=2));
518 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 1,
519 rhcode, " Version: %d", ((avp_ver&0xff00)>>8) );
520 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 7, 1,
521 rhcode, " Revision: %d", (avp_ver&0x00ff));
524 case FRAMING_CAPABIlITIES:
526 framing = tvb_get_ntohs(tvb, (tmp_index+=2));
527 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 4,
528 rhcode, " ASYNC FRAMING: %s" , (FRAMING_ASYNC(framing)) ? "True" : "False" );
529 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 4,
530 rhcode, " SYNC FRAMING: %s" , (FRAMING_SYNC(framing)) ? "True" : "False" );
533 case BEARER_CAPABIlITIES:
535 framing = tvb_get_ntohs(tvb, (tmp_index+=2));
536 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 4 ,
537 rhcode, " Analog Access: %s" , (FRAMING_ASYNC(framing)) ? "True" : "False" );
538 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 4,
539 rhcode, " Digital Access: %s" , (FRAMING_SYNC(framing)) ? "True" : "False" );
543 long_type = tvb_get_ntohl(tvb, (tmp_index+=8));
544 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 1,
545 rhcode, " TIE_BREAKER %lu 0x%lx", long_type,long_type );
548 case FIRMWARE_REVISION:
549 firmware_rev = tvb_get_ntohs(tvb, (tmp_index+=2));
550 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6, 2,
551 rhcode, " Firmware Revision: %d 0x%x", firmware_rev,firmware_rev );
555 memset(error_string,'\0',sizeof(error_string));
556 strncpy(error_string, tvb_get_ptr(tvb, (tmp_index+=2), (avp_len - 6)),
558 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6,
559 (avp_len - 6), rhcode, " Host Name: %s", error_string );
563 memset(message_string,'\0' ,sizeof(message_string));
564 strncpy(message_string, tvb_get_ptr(tvb, (tmp_index+=2),(avp_len - 6)),
566 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6,
567 (avp_len - 6), rhcode, " Vendor Name: %s", message_string );
570 case ASSIGNED_TUNNEL_ID:
571 gen_type = tvb_get_ntohs(tvb, (tmp_index+=2));
572 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
573 2, rhcode, " Tunnel ID: %d", gen_type );
576 case RECEIVE_WINDOW_SIZE:
577 gen_type = tvb_get_ntohs(tvb, (tmp_index+=2));
578 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
579 2, rhcode, " Receive Window Size: %d", gen_type );
583 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
584 (avp_len - 6 ), rhcode, " CHAP Challenge: ");
587 case CHALLENGE_RESPONSE:
588 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
589 (avp_len - 6 ), rhcode, " CHAP Challenge Response: ");
593 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
594 1, rhcode, " Cause Code: ");
597 case ASSIGNED_SESSION:
598 gen_type = tvb_get_ntohs(tvb, (tmp_index+=2));
599 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
600 2, rhcode, " Assigned Session: %d", gen_type );
603 case CALL_SERIAL_NUMBER:
604 gen_type = tvb_get_ntohs(tvb, (tmp_index+=2));
605 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
606 4, rhcode, " Call Serial Number: %d", gen_type );
610 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
611 4, rhcode, " Minimum BPS: ");
615 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
616 4, rhcode, " Maximum BPS ");
620 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
621 4, rhcode, " Bearer Type: ");
625 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
626 4, rhcode, " Framing Type: ");
629 case UNKNOWN_MESSAGE:
630 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
631 1, rhcode, " Unknown Message: ");
635 memset(message_string,'\0' ,sizeof(message_string));
636 strncpy(message_string, tvb_get_ptr(tvb, (tmp_index+=2),(avp_len - 6)),
638 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6,
639 (avp_len - 6), rhcode, " Called Number: %s", message_string );
643 memset(message_string,'\0' ,sizeof(message_string));
644 strncpy(message_string, tvb_get_ptr(tvb, (tmp_index+=2),(avp_len - 6)),
646 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6,
647 (avp_len - 6), rhcode, " Calling Number: %s", message_string );
651 memset(message_string,'\0' ,sizeof(message_string));
652 strncpy(message_string, tvb_get_ptr(tvb, (tmp_index+=2),(avp_len - 6)),
654 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb, index + 6,
655 (avp_len - 6), rhcode, " Sub-Address: %s", message_string );
658 case TX_CONNECT_SPEED:
659 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
660 4, rhcode, " Connect Speed: ");
663 case PHYSICAL_CHANNEL:
664 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
665 4, rhcode, " Physical Channel: ");
668 case INITIAL_RECEIVED_LCP:
669 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
670 (avp_len - 6 ), rhcode, " Initial LCP Conf REQ: ");
673 case LAST_SEND_LCP_CONFREQ:
674 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
675 (avp_len - 6 ), rhcode, " Last Sent LCP Conf REQ: ");
678 case LAST_RECEIVED_LCP_CONFREQ:
679 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
680 (avp_len - 6 ), rhcode, " Last Received LCP Conf REQ: ");
683 case PROXY_AUTHEN_TYPE:
684 msg_type = tvb_get_ntohs(tvb, (tmp_index+=2));
685 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
686 1, rhcode, " Proxy Authen Type: %s ", authen_types[msg_type] );
689 case PROXY_AUTHEN_NAME:
690 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
691 (avp_len - 6 ), rhcode, " Proxy Authen Name: ");
694 case PROXY_AUTHEN_CHALLENGE:
695 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
696 (avp_len - 6 ), rhcode, " Proxy Authen Challenge: ");
699 case PROXY_AUTHEN_ID:
700 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
701 2, rhcode, " Paorx Authen ID: ");
704 case PROXY_AUTHEN_RESPONSE:
705 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
706 (avp_len - 6 ), rhcode, " Proxy Authen Response: ");
709 case CALL_STATUS_AVPS:
710 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
711 4, rhcode, " CRC Errors: ");
712 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 10,
713 4, rhcode, " Framing Errors: ");
714 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 14,
715 4, rhcode, " Hardware Overruns: ");
716 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 18,
717 4, rhcode, " Buffer Overruns: ");
718 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 23,
719 4, rhcode, " Time-out Errors: ");
720 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 26,
721 4, rhcode, " Alignment Errors: ");
725 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
726 2, rhcode, " Reserve Quantity: ");
727 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 8,
728 4, rhcode, " Send ACCM: ");
729 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 12,
730 4, rhcode, " Recv ACCM: ");
733 case PRIVATE_GROUP_ID:
734 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
735 1, rhcode, " Private Group ID: ");
738 case RX_CONNECT_SPEED:
739 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
740 4, rhcode, " RX Connect Speed: ");
743 case SEQUENCING_REQUIRED:
744 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index ,
745 1, rhcode, " Sequencing Required: ");
749 /* printf("Avp Decode avp_len= %d index= %d length= %d %x\n ",avp_len,
750 index,length,length); */
758 /* registration with the filtering engine */
760 proto_register_l2tp(void)
762 static hf_register_info hf[] = {
764 { "code", "lt2p.code", FT_UINT16, BASE_DEC, NULL, 0, /* XXX - to be removed */
768 { "Type", "lt2p.type", FT_UINT16, BASE_DEC, VALS(l2tp_type_vals), 0x8000,
771 { &hf_l2tp_length_bit,
772 { "Length Bit", "lt2p.length_bit", FT_BOOLEAN, 16, TFS(&l2tp_length_bit_truth), 0x4000,
776 { "Sequence Bit", "lt2p.seq_bit", FT_BOOLEAN, 16, TFS(&l2tp_seq_bit_truth), 0x0800,
779 { &hf_l2tp_offset_bit,
780 { "Offset bit", "lt2p.offset_bit", FT_BOOLEAN, 16, TFS(&l2tp_offset_bit_truth), 0x0200,
784 { "Priority", "lt2p.priority", FT_BOOLEAN, 16, TFS(&l2tp_priority_truth), 0x0100,
788 { "Version", "lt2p.version", FT_UINT16, BASE_DEC, NULL, 0x000f,
792 { "Length","l2tp.length", FT_UINT16, BASE_DEC, NULL, 0x0,
796 { "Tunnel ID","l2tp.tunnel", FT_UINT16, BASE_DEC, NULL, 0x0, /* Probably should be FT_BYTES */
800 { "Session ID","l2tp.session", FT_UINT16, BASE_DEC, NULL, 0x0, /* Probably should be FT_BYTES */
804 { "Ns","l2tp.Ns", FT_UINT16, BASE_DEC, NULL, 0x0,
808 { "Nr","l2tp.Nr", FT_UINT16, BASE_DEC, NULL, 0x0,
812 { "Offset","l2tp.offset", FT_UINT16, BASE_DEC, NULL, 0x0,
813 "Number of octest past the L2TP header at which the"
814 "payload data starts." }},
818 static gint *ett[] = {
824 proto_l2tp = proto_register_protocol(
825 "Layer 2 Tunneling Protocol", "L2TP", "l2tp");
826 proto_register_field_array(proto_l2tp, hf, array_length(hf));
827 proto_register_subtree_array(ett, array_length(ett));
831 proto_reg_handoff_l2tp(void)
833 dissector_add("udp.port", UDP_PORT_L2TP, dissect_l2tp);
836 * Get a handle for the PPP dissector.
838 ppp_handle = find_dissector("ppp");