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.20 2001/01/09 06:31:38 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" },
154 static const true_false_string l2tp_length_bit_truth =
155 { "Length field is present", "Length field is not present" };
157 static const true_false_string l2tp_seq_bit_truth =
158 { "Ns and Nr fields are present", "Ns and Nr fields are not present" };
160 static const true_false_string l2tp_offset_bit_truth =
161 { "Offset Size field is present", "Offset size field is not present" };
163 static const true_false_string l2tp_priority_truth =
164 { "This data message has priority", "No priority" };
166 #define NUM_AUTH_TYPES 6
167 static const char *authen_types[NUM_AUTH_TYPES] = {
169 "Textual username and password",
173 "Microsoft CHAP Version 1",
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
184 #define VENDOR_NAME 8
185 #define ASSIGNED_TUNNEL_ID 9
186 #define RECEIVE_WINDOW_SIZE 10
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
212 #define UNKOWN_MESSAGE_36
213 #define PRIVATE_GROUP_ID 37
214 #define RX_CONNECT_SPEED 38
215 #define SEQUENCING_REQUIRED 39
217 #define NUM_AVP_TYPES 40
218 static const char *avptypestr[NUM_AVP_TYPES] = {
220 "Result-Error Code ",
222 "Framing Capabilities ",
223 "Bearer Capabilities ",
225 "Firmware Revision ",
228 "Assigned Tunnel ID ",
229 "Receive Window Size ",
232 "Challenge Response ",
234 "Call Serial Number ",
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 ",
252 "Proxy Authen Response ",
258 "Sequencing Required ",
262 static gchar textbuffer[200];
264 static dissector_handle_t ppp_handle;
267 dissect_l2tp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
269 proto_tree *l2tp_tree=NULL, *l2tp_avp_tree, *ctrl_tree;
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];
298 CHECK_DISPLAY_AS_DATA(proto_l2tp, tvb, pinfo, tree);
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");
304 control = tvb_get_ntohs(tvb, 0);
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) );
315 if (LENGTH_BIT(control)) { /* length field included ? */
316 index += 2; /* skip ahead */
317 length = tvb_get_ntohs(tvb, index);
320 /* collect the tunnel id & call id */
322 tid = tvb_get_ntohs(tvb, index);
324 cid = tvb_get_ntohs(tvb, index);
326 if (check_col(pinfo->fd, COL_INFO)) {
327 if (CONTROL_BIT(control)) {
328 /* CONTROL MESSAGE */
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);
336 if (SEQUENCE_BIT(control)) {
342 avp_type = tvb_get_ntohs(tvb, (tmp_index+=2));
344 if (avp_type == CONTROL_MESSAGE)
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)",
350 ((NUM_CONTROL_CALL_TYPES + 1 ) > msg_type) ?
351 calltype_short_str[msg_type] : "Unknown",
357 * This is not a control message.
358 * We never pass here except in case of bad l2tp packet!
360 sprintf(textbuffer,"%s (tunnel id=%d, session id=%d)",
361 control_msg , tid ,cid);
368 sprintf(textbuffer,"%s (tunnel id=%d, session id=%d)",
371 col_add_fstr(pinfo->fd,COL_INFO,textbuffer);
374 if (LENGTH_BIT(control)) {
375 proto_length = length;
378 proto_length = tvb_length(tvb);
382 ti = proto_tree_add_item(tree,proto_l2tp, tvb, 0, proto_length, FALSE);
383 l2tp_tree = proto_item_add_subtree(ti, ett_l2tp);
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);
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);
398 if (LENGTH_BIT(control)) {
400 proto_tree_add_item(l2tp_tree, hf_l2tp_length, tvb, index, 2, FALSE);
406 proto_tree_add_item(l2tp_tree, hf_l2tp_tunnel, tvb, index, 2, FALSE);
410 proto_tree_add_item(l2tp_tree, hf_l2tp_session, tvb, index, 2, FALSE);
414 if (SEQUENCE_BIT(control)) {
416 proto_tree_add_item(l2tp_tree, hf_l2tp_Ns, tvb, index, 2, FALSE);
420 proto_tree_add_item(l2tp_tree, hf_l2tp_Nr, tvb, index, 2, FALSE);
424 if (OFFSET_BIT(control)) {
425 offset_size = tvb_get_ntohs(tvb, index);
427 proto_tree_add_uint(l2tp_tree, hf_l2tp_offset, tvb, index, 2, FALSE);
431 proto_tree_add_text(l2tp_tree, tvb, index, offset_size, "Offset Padding");
433 index += offset_size;
435 if (tree && (LENGTH_BIT(control))&&(length==12)) {
436 proto_tree_add_text(l2tp_tree, tvb, 0, 0, "Zero Length Bit message");
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);
449 if (!LENGTH_BIT(control)) {
452 while (index < length ) { /* Process AVP's */
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));
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);
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 );
474 proto_tree_add_text(l2tp_avp_tree, tvb, (index + 1), 1, "Length should not be zero");
478 if (HIDDEN_BIT(ver_len_hidden)) { /* don't try do display hidden */
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" );
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,
498 " Result code: %d", result_code );
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,
505 " Error code: %d", error_code);
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)),
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 );
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));
525 case FRAMING_CAPABIlITIES:
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" );
534 case BEARER_CAPABIlITIES:
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" );
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 );
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 );
556 memset(error_string,'\0',sizeof(error_string));
557 strncpy(error_string, tvb_get_ptr(tvb, (tmp_index+=2), (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 );
564 memset(message_string,'\0' ,sizeof(message_string));
565 strncpy(message_string, tvb_get_ptr(tvb, (tmp_index+=2),(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 );
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 );
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 );
584 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
585 (avp_len - 6 ), rhcode, " CHAP Challenge: ");
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: ");
594 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
595 1, rhcode, " Cause Code: ");
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 );
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 );
611 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
612 4, rhcode, " Minimum BPS: ");
616 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
617 4, rhcode, " Maximum BPS ");
621 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
622 4, rhcode, " Bearer Type: ");
626 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
627 4, rhcode, " Framing Type: ");
630 case UNKNOWN_MESSAGE:
631 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
632 1, rhcode, " Unknown Message: ");
636 memset(message_string,'\0' ,sizeof(message_string));
637 strncpy(message_string, tvb_get_ptr(tvb, (tmp_index+=2),(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 );
644 memset(message_string,'\0' ,sizeof(message_string));
645 strncpy(message_string, tvb_get_ptr(tvb, (tmp_index+=2),(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 );
652 memset(message_string,'\0' ,sizeof(message_string));
653 strncpy(message_string, tvb_get_ptr(tvb, (tmp_index+=2),(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 );
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: ");
664 case PHYSICAL_CHANNEL:
665 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index + 6,
666 4, rhcode, " Physical Channel: ");
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: ");
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: ");
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: ");
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] );
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: ");
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: ");
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: ");
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: ");
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: ");
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: ");
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: ");
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: ");
744 case SEQUENCING_REQUIRED:
745 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_code, tvb,index ,
746 1, rhcode, " Sequencing Required: ");
750 /* printf("Avp Decode avp_len= %d index= %d length= %d %x\n ",avp_len,
751 index,length,length); */
759 /* registration with the filtering engine */
761 proto_register_l2tp(void)
763 static hf_register_info hf[] = {
765 { "code", "lt2p.code", FT_UINT16, BASE_DEC, NULL, 0, /* XXX - to be removed */
769 { "Type", "lt2p.type", FT_UINT16, BASE_DEC, VALS(l2tp_type_vals), 0x8000,
772 { &hf_l2tp_length_bit,
773 { "Length Bit", "lt2p.length_bit", FT_BOOLEAN, 16, TFS(&l2tp_length_bit_truth), 0x4000,
777 { "Sequence Bit", "lt2p.seq_bit", FT_BOOLEAN, 16, TFS(&l2tp_seq_bit_truth), 0x0800,
780 { &hf_l2tp_offset_bit,
781 { "Offset bit", "lt2p.offset_bit", FT_BOOLEAN, 16, TFS(&l2tp_offset_bit_truth), 0x0200,
785 { "Priority", "lt2p.priority", FT_BOOLEAN, 16, TFS(&l2tp_priority_truth), 0x0100,
789 { "Version", "lt2p.version", FT_UINT16, BASE_DEC, NULL, 0x000f,
793 { "Length","l2tp.length", FT_UINT16, BASE_DEC, NULL, 0x0,
797 { "Tunnel ID","l2tp.tunnel", FT_UINT16, BASE_DEC, NULL, 0x0, /* Probably should be FT_BYTES */
801 { "Session ID","l2tp.session", FT_UINT16, BASE_DEC, NULL, 0x0, /* Probably should be FT_BYTES */
805 { "Ns","l2tp.Ns", FT_UINT16, BASE_DEC, NULL, 0x0,
809 { "Nr","l2tp.Nr", FT_UINT16, BASE_DEC, NULL, 0x0,
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." }},
819 static gint *ett[] = {
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));
832 proto_reg_handoff_l2tp(void)
834 dissector_add("udp.port", UDP_PORT_L2TP, dissect_l2tp,
838 * Get a handle for the PPP dissector.
840 ppp_handle = find_dissector("ppp");