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.37 2003/01/14 18:57:07 guy Exp $
12 * Ethereal - Network traffic analyzer
13 * By Gerald Combs <gerald@ethereal.com>
14 * Copyright 1998 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 static int proto_l2tp = -1;
32 static int hf_l2tp_type = -1;
33 static int hf_l2tp_length_bit = -1;
34 static int hf_l2tp_seq_bit = -1;
35 static int hf_l2tp_offset_bit = -1;
36 static int hf_l2tp_priority = -1;
37 static int hf_l2tp_version = -1;
38 static int hf_l2tp_length = -1;
39 static int hf_l2tp_tunnel = -1;
40 static int hf_l2tp_session = -1;
41 static int hf_l2tp_Ns = -1;
42 static int hf_l2tp_Nr = -1;
43 static int hf_l2tp_offset = -1;
44 static int hf_l2tp_avp_mandatory = -1;
45 static int hf_l2tp_avp_hidden = -1;
46 static int hf_l2tp_avp_length = -1;
47 static int hf_l2tp_avp_vendor_id = -1;
48 static int hf_l2tp_avp_type = -1;
49 static int hf_l2tp_tie_breaker = -1;
60 #include <epan/packet.h>
61 #include <epan/resolv.h>
63 #define UDP_PORT_L2TP 1701
65 #define CONTROL_BIT(msg_info) (msg_info & 0x8000) /* Type bit control = 1 data = 0 */
66 #define LENGTH_BIT(msg_info) (msg_info & 0x4000) /* Length bit = 1 */
67 #define RESERVE_BITS(msg_info) (msg_info &0x37F8) /* Reserved bit - usused */
68 #define SEQUENCE_BIT(msg_info) (msg_info & 0x0800) /* SEQUENCE bit = 1 Ns and Nr fields */
69 #define OFFSET_BIT(msg_info) (msg_info & 0x0200) /* Offset */
70 #define PRIORITY_BIT(msg_info) (msg_info & 0x0100) /* Priority */
71 #define L2TP_VERSION(msg_info) (msg_info & 0x000f) /* Version of l2tp */
72 #define MANDATORY_BIT(msg_info) (msg_info & 0x8000) /* Mandatory = 1 */
73 #define HIDDEN_BIT(msg_info) (msg_info & 0x4000) /* Hidden = 1 */
74 #define AVP_LENGTH(msg_info) (msg_info & 0x03ff) /* AVP Length */
75 #define FRAMING_SYNC(msg_info) (msg_info & 0x0001) /* SYNC Framing Type */
76 #define FRAMING_ASYNC(msg_info) (msg_info & 0x0002) /* ASYNC Framing Type */
77 #define BEARER_DIGITAL(msg_info) (msg_info & 0x0001) /* Digital Bearer Type */
78 #define BEARER_ANALOG(msg_info) (msg_info & 0x0002) /* Analog Bearer Type */
80 static gint ett_l2tp = -1;
81 static gint ett_l2tp_ctrl = -1;
82 static gint ett_l2tp_avp = -1;
83 static gint ett_l2tp_lcp = -1;
89 #define AVP_Reserved 5
97 #define AVP_Reserved1 13
101 #define NUM_CONTROL_CALL_TYPES 16
102 static const char *calltypestr[NUM_CONTROL_CALL_TYPES+1] = {
103 "Unknown Call Type ",
104 "Start_Control_Request ",
105 "Start_Control_Reply ",
106 "Start_Control_Connected ",
107 "Stop_Control_Notification ",
110 "Outgoing_Call_Request ",
111 "Outgoing_Call_Reply ",
112 "Outgoing_Call_Connected ",
113 "Incoming_Call_Request ",
114 "Incoming_Call_Reply ",
115 "Incoming_Call_Connected ",
117 "Call_Disconnect_Notification",
122 static const char *calltype_short_str[NUM_CONTROL_CALL_TYPES+1] = {
143 static const char *control_msg = "Control Message";
144 static const char *data_msg = "Data Message";
145 static const value_string l2tp_type_vals[] = {
146 { 0, "Data Message" },
147 { 1, "Control Message" },
151 static const value_string cause_code_direction_vals[] = {
152 { 0, "global error" },
158 static const true_false_string l2tp_length_bit_truth =
159 { "Length field is present", "Length field is not present" };
161 static const true_false_string l2tp_seq_bit_truth =
162 { "Ns and Nr fields are present", "Ns and Nr fields are not present" };
164 static const true_false_string l2tp_offset_bit_truth =
165 { "Offset Size field is present", "Offset size field is not present" };
167 static const true_false_string l2tp_priority_truth =
168 { "This data message has priority", "No priority" };
170 static const value_string authen_type_vals[] = {
172 { 1, "Textual username and password" },
175 { 4, "No Authentication" },
176 { 5, "Microsoft CHAP Version 1" },
180 #define CONTROL_MESSAGE 0
181 #define RESULT_ERROR_CODE 1
182 #define PROTOCOL_VERSION 2
183 #define FRAMING_CAPABILITIES 3
184 #define BEARER_CAPABILITIES 4
185 #define TIE_BREAKER 5
186 #define FIRMWARE_REVISION 6
188 #define VENDOR_NAME 8
189 #define ASSIGNED_TUNNEL_ID 9
190 #define RECEIVE_WINDOW_SIZE 10
192 #define CAUSE_CODE 12
193 #define CHALLENGE_RESPONSE 13
194 #define ASSIGNED_SESSION 14
195 #define CALL_SERIAL_NUMBER 15
196 #define MINIMUM_BPS 16
197 #define MAXIMUM_BPS 17
198 #define BEARER_TYPE 18
199 #define FRAMING_TYPE 19
200 #define CALLED_NUMBER 21
201 #define CALLING_NUMBER 22
202 #define SUB_ADDRESS 23
203 #define TX_CONNECT_SPEED 24
204 #define PHYSICAL_CHANNEL 25
205 #define INITIAL_RECEIVED_LCP_CONFREQ 26
206 #define LAST_SENT_LCP_CONFREQ 27
207 #define LAST_RECEIVED_LCP_CONFREQ 28
208 #define PROXY_AUTHEN_TYPE 29
209 #define PROXY_AUTHEN_NAME 30
210 #define PROXY_AUTHEN_CHALLENGE 31
211 #define PROXY_AUTHEN_ID 32
212 #define PROXY_AUTHEN_RESPONSE 33
213 #define CALL_STATUS_AVPS 34
215 #define RANDOM_VECTOR 36
216 #define PRIVATE_GROUP_ID 37
217 #define RX_CONNECT_SPEED 38
218 #define SEQUENCING_REQUIRED 39
219 #define PPP_DISCONNECT_CAUSE_CODE 46 /* RFC 3145 */
221 #define NUM_AVP_TYPES 40
222 static const value_string avp_type_vals[] = {
223 { CONTROL_MESSAGE, "Control Message" },
224 { RESULT_ERROR_CODE, "Result-Error Code" },
225 { PROTOCOL_VERSION, "Protocol Version" },
226 { FRAMING_CAPABILITIES, "Framing Capabilities" },
227 { BEARER_CAPABILITIES, "Bearer Capabilities" },
228 { TIE_BREAKER, "Tie Breaker" },
229 { FIRMWARE_REVISION, "Firmware Revision" },
230 { HOST_NAME, "Host Name" },
231 { VENDOR_NAME, "Vendor Name" },
232 { ASSIGNED_TUNNEL_ID, "Assigned Tunnel ID" },
233 { RECEIVE_WINDOW_SIZE, "Receive Window Size" },
234 { CHALLENGE, "Challenge" },
235 { CAUSE_CODE, "Cause Code" },
236 { CHALLENGE_RESPONSE, "Challenge Response" },
237 { ASSIGNED_SESSION, "Assigned Session" },
238 { CALL_SERIAL_NUMBER, "Call Serial Number" },
239 { MINIMUM_BPS, "Minimum BPS" },
240 { MAXIMUM_BPS, "Maximum BPS" },
241 { BEARER_TYPE, "Bearer Type" },
242 { FRAMING_TYPE, "Framing Type" },
243 { CALLED_NUMBER, "Called Number" },
244 { CALLING_NUMBER, "Calling Number" },
245 { SUB_ADDRESS, "Sub-Address" },
246 { TX_CONNECT_SPEED, "Connect Speed" },
247 { PHYSICAL_CHANNEL, "Physical Channel" },
248 { INITIAL_RECEIVED_LCP_CONFREQ, "Initial Received LCP CONFREQ" },
249 { LAST_SENT_LCP_CONFREQ, "Last Sent LCP CONFREQ" },
250 { LAST_RECEIVED_LCP_CONFREQ, "Last Received LCP CONFREQ" },
251 { PROXY_AUTHEN_TYPE, "Proxy Authen Type" },
252 { PROXY_AUTHEN_NAME, "Proxy Authen Name" },
253 { PROXY_AUTHEN_CHALLENGE, "Proxy Authen Challenge" },
254 { PROXY_AUTHEN_ID, "Proxy Authen ID" },
255 { PROXY_AUTHEN_RESPONSE, "Proxy Authen Response" },
256 { CALL_STATUS_AVPS, "Call status AVPs" },
258 { RANDOM_VECTOR, "Random Vector" },
259 { PRIVATE_GROUP_ID, "Private group ID" },
260 { RX_CONNECT_SPEED, "RxConnect Speed" },
261 { SEQUENCING_REQUIRED, "Sequencing Required" },
262 { PPP_DISCONNECT_CAUSE_CODE, "PPP Disconnect Cause Code" },
267 * These are SMI Network Management Private Enterprise Codes for
270 * http://www.isi.edu/in-notes/iana/assignments/enterprise-numbers
274 #define VENDOR_IETF 0
276 #define VENDOR_CISCO 9
277 #define VENDOR_SHIVA 166
278 #define VENDOR_LIVINGSTON 307
279 #define VENDOR_3COM 429
280 #define VENDOR_ASCEND 529
281 #define VENDOR_BAY 1584
282 #define VENDOR_REDBACK 2352
283 #define VENDOR_JUNIPER 2636
284 #define VENDOR_COSINE 3085
285 #define VENDOR_UNISPHERE 4874
287 static const value_string avp_vendor_id_vals[] =
288 {{VENDOR_IETF,"IETF"},
290 {VENDOR_CISCO,"Cisco"},
291 {VENDOR_SHIVA,"Shiva"},
292 {VENDOR_LIVINGSTON,"Livingston"},
293 {VENDOR_3COM,"3Com"},
294 {VENDOR_ASCEND,"Ascend"},
295 {VENDOR_BAY,"Bay Networks"},
296 {VENDOR_REDBACK,"Redback"},
297 {VENDOR_JUNIPER,"Juniper Networks"},
298 {VENDOR_COSINE,"CoSine Communications"},
299 {VENDOR_UNISPHERE,"Unisphere Networks"},
302 static gchar textbuffer[200];
304 static dissector_handle_t ppp_hdlc_handle;
305 static dissector_handle_t ppp_lcp_options_handle;
308 dissect_l2tp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
310 proto_tree *l2tp_tree=NULL, *l2tp_avp_tree, *l2tp_lcp_avp_tree, *ctrl_tree;
311 proto_item *l2tp_item = NULL, *ti, *tf, *te;
315 guint16 length = 0; /* Length field */
316 guint16 tid; /* Tunnel ID */
317 guint16 cid; /* Call ID */
318 guint16 offset_size; /* Offset size */
319 guint16 ver_len_hidden;
320 guint16 avp_vendor_id;
327 guint16 firmware_rev;
331 if (check_col(pinfo->cinfo, COL_PROTOCOL)) /* build output for closed L2tp frame displayed */
332 col_set_str(pinfo->cinfo, COL_PROTOCOL, "L2TP");
333 if (check_col(pinfo->cinfo, COL_INFO))
334 col_clear(pinfo->cinfo, COL_INFO);
336 control = tvb_get_ntohs(tvb, 0);
338 if (L2TP_VERSION(control) != 2) {
339 if (check_col(pinfo->cinfo, COL_INFO)) {
340 col_add_fstr(pinfo->cinfo, COL_INFO, "L2TP Version %u", L2TP_VERSION(control) );
347 if (LENGTH_BIT(control)) { /* length field included ? */
348 index += 2; /* skip ahead */
349 length = tvb_get_ntohs(tvb, index);
352 /* collect the tunnel id & call id */
354 tid = tvb_get_ntohs(tvb, index);
356 cid = tvb_get_ntohs(tvb, index);
358 if (check_col(pinfo->cinfo, COL_INFO)) {
359 if (CONTROL_BIT(control)) {
360 /* CONTROL MESSAGE */
363 if ((LENGTH_BIT(control))&&(length==12)) /* ZLB Message */
364 sprintf(textbuffer,"%s - ZLB (tunnel id=%d, session id=%d)",
365 control_msg , tid ,cid);
368 if (SEQUENCE_BIT(control)) {
374 avp_type = tvb_get_ntohs(tvb, (tmp_index+=2));
376 if (avp_type == CONTROL_MESSAGE)
378 /* We print message type */
379 msg_type = tvb_get_ntohs(tvb, (tmp_index+=2));
380 sprintf(textbuffer,"%s - %s (tunnel id=%d, session id=%d)",
382 ((NUM_CONTROL_CALL_TYPES + 1 ) > msg_type) ?
383 calltype_short_str[msg_type] : "Unknown",
389 * This is not a control message.
390 * We never pass here except in case of bad l2tp packet!
392 sprintf(textbuffer,"%s (tunnel id=%d, session id=%d)",
393 control_msg , tid ,cid);
400 sprintf(textbuffer,"%s (tunnel id=%d, session id=%d)",
403 col_add_fstr(pinfo->cinfo,COL_INFO,textbuffer);
406 if (LENGTH_BIT(control)) {
408 * Set the length of this tvbuff to be no longer than the length
411 * XXX - complain if that length is longer than the length of
412 * the tvbuff? Have "set_actual_length()" return a Boolean
413 * and have its callers check the result?
415 set_actual_length(tvb, length);
419 l2tp_item = proto_tree_add_item(tree,proto_l2tp, tvb, 0, -1, FALSE);
420 l2tp_tree = proto_item_add_subtree(l2tp_item, ett_l2tp);
422 ti = proto_tree_add_text(l2tp_tree, tvb, 0, 2,
423 "Packet Type: %s Tunnel Id=%d Session Id=%d",
424 (CONTROL_BIT(control) ? control_msg : data_msg), tid, cid);
426 ctrl_tree = proto_item_add_subtree(ti, ett_l2tp_ctrl);
427 proto_tree_add_uint(ctrl_tree, hf_l2tp_type, tvb, 0, 2, control);
428 proto_tree_add_boolean(ctrl_tree, hf_l2tp_length_bit, tvb, 0, 2, control);
429 proto_tree_add_boolean(ctrl_tree, hf_l2tp_seq_bit, tvb, 0, 2, control);
430 proto_tree_add_boolean(ctrl_tree, hf_l2tp_offset_bit, tvb, 0, 2, control);
431 proto_tree_add_boolean(ctrl_tree, hf_l2tp_priority, tvb, 0, 2, control);
432 proto_tree_add_uint(ctrl_tree, hf_l2tp_version, tvb, 0, 2, control);
435 if (LENGTH_BIT(control)) {
437 proto_tree_add_item(l2tp_tree, hf_l2tp_length, tvb, index, 2, FALSE);
443 proto_tree_add_item(l2tp_tree, hf_l2tp_tunnel, tvb, index, 2, FALSE);
447 proto_tree_add_item(l2tp_tree, hf_l2tp_session, tvb, index, 2, FALSE);
451 if (SEQUENCE_BIT(control)) {
453 proto_tree_add_item(l2tp_tree, hf_l2tp_Ns, tvb, index, 2, FALSE);
457 proto_tree_add_item(l2tp_tree, hf_l2tp_Nr, tvb, index, 2, FALSE);
461 if (OFFSET_BIT(control)) {
462 offset_size = tvb_get_ntohs(tvb, index);
464 proto_tree_add_uint(l2tp_tree, hf_l2tp_offset, tvb, index, 2,
468 if (offset_size != 0) {
470 proto_tree_add_text(l2tp_tree, tvb, index, offset_size, "Offset Padding");
472 index += offset_size;
475 if (tree && (LENGTH_BIT(control))&&(length==12)) {
476 proto_tree_add_text(l2tp_tree, tvb, 0, 0, "Zero Length Bit message");
479 if (!CONTROL_BIT(control)) { /* Data Messages so we are done */
481 proto_item_set_len(l2tp_item, index);
482 /* If we have data, signified by having a length bit, dissect it */
483 if (tvb_offset_exists(tvb, index)) {
484 next_tvb = tvb_new_subset(tvb, index, -1, -1);
485 call_dissector(ppp_hdlc_handle, next_tvb, pinfo, tree);
491 if (!LENGTH_BIT(control)) {
494 while (index < length ) { /* Process AVP's */
495 ver_len_hidden = tvb_get_ntohs(tvb, index);
496 avp_len = AVP_LENGTH(ver_len_hidden);
497 avp_vendor_id = tvb_get_ntohs(tvb, index + 2);
498 avp_type = tvb_get_ntohs(tvb, index + 4);
500 if (avp_vendor_id == VENDOR_IETF) {
501 tf = proto_tree_add_text(l2tp_tree, tvb, index,
503 val_to_str(avp_type, avp_type_vals, "Unknown (%u)"));
504 } else { /* Vendor-Specific AVP */
505 tf = proto_tree_add_text(l2tp_tree, tvb, index,
506 avp_len, "Vendor %s AVP",
507 val_to_str(avp_vendor_id, avp_vendor_id_vals, "Unknown (%u)"));
510 l2tp_avp_tree = proto_item_add_subtree(tf, ett_l2tp_avp);
512 proto_tree_add_boolean_format(l2tp_avp_tree,hf_l2tp_avp_mandatory, tvb, index, 1,
513 rhcode, "Mandatory: %s",
514 (MANDATORY_BIT(ver_len_hidden)) ? "True" : "False" );
515 proto_tree_add_boolean_format(l2tp_avp_tree,hf_l2tp_avp_hidden, tvb, index, 1,
516 rhcode, "Hidden: %s",
517 (HIDDEN_BIT(ver_len_hidden)) ? "True" : "False" );
518 proto_tree_add_uint_format(l2tp_avp_tree,hf_l2tp_avp_length, tvb, index, 2,
519 rhcode, "Length: %u", avp_len);
520 if (HIDDEN_BIT(ver_len_hidden)) { /* don't try do display hidden */
526 proto_tree_add_text(l2tp_avp_tree, tvb, index, 0,
527 "AVP length must not be zero");
533 proto_tree_add_item(l2tp_avp_tree, hf_l2tp_avp_vendor_id,
534 tvb, index, 2, FALSE);
538 if (avp_vendor_id != VENDOR_IETF) {
539 proto_tree_add_text(l2tp_avp_tree, tvb, index, 2,
540 "Type: %u", avp_type);
544 /* For the time being, we don't decode any Vendor-
546 proto_tree_add_text(l2tp_avp_tree, tvb, index,
547 avp_len, "Vendor-Specific AVP");
553 proto_tree_add_uint(l2tp_avp_tree, hf_l2tp_avp_type,
554 tvb, index, 2, avp_type);
560 case CONTROL_MESSAGE:
561 msg_type = tvb_get_ntohs(tvb, index);
562 proto_tree_add_text(l2tp_avp_tree,tvb, index, 2,
563 "Control Message Type: (%u) %s", msg_type,
564 ((NUM_CONTROL_CALL_TYPES + 1 ) > msg_type) ?
565 calltypestr[msg_type] : "Unknown");
568 case RESULT_ERROR_CODE:
571 result_code = tvb_get_ntohs(tvb, index);
572 proto_tree_add_text(l2tp_avp_tree, tvb, index, 2,
573 "Result code: %u", result_code);
579 error_code = tvb_get_ntohs(tvb, index);
580 proto_tree_add_text(l2tp_avp_tree, tvb, index, 2,
581 "Error code: %u", error_code);
587 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
588 "Error Message: %.*s", avp_len,
589 tvb_get_ptr(tvb, index, avp_len));
592 case PROTOCOL_VERSION:
595 proto_tree_add_text(l2tp_avp_tree, tvb, index, 1,
596 "Version: %u", tvb_get_guint8(tvb, index));
600 proto_tree_add_text(l2tp_avp_tree, tvb, index, 1,
601 "Revision: %u", tvb_get_guint8(tvb, index));
604 case FRAMING_CAPABILITIES:
605 bits = tvb_get_ntohl(tvb, index);
606 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
607 "Async Framing Supported: %s",
608 (FRAMING_ASYNC(bits)) ? "True" : "False");
609 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
610 "Sync Framing Supported: %s",
611 (FRAMING_SYNC(bits)) ? "True" : "False");
614 case BEARER_CAPABILITIES:
615 bits = tvb_get_ntohl(tvb, index);
616 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
617 "Analog Access Supported: %s",
618 (BEARER_ANALOG(bits)) ? "True" : "False");
619 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
620 "Digital Access Supported: %s",
621 (BEARER_DIGITAL(bits)) ? "True" : "False");
625 proto_tree_add_item(l2tp_avp_tree, hf_l2tp_tie_breaker, tvb, index, 8, FALSE);
628 case FIRMWARE_REVISION:
629 firmware_rev = tvb_get_ntohs(tvb, index);
630 proto_tree_add_text(l2tp_avp_tree, tvb, index, 2,
631 "Firmware Revision: %d 0x%x", firmware_rev,firmware_rev );
635 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
636 "Host Name: %.*s", avp_len,
637 tvb_get_ptr(tvb, index, avp_len));
641 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
642 "Vendor Name: %.*s", avp_len,
643 tvb_get_ptr(tvb, index, avp_len));
646 case ASSIGNED_TUNNEL_ID:
647 proto_tree_add_text(l2tp_avp_tree, tvb, index, 2,
648 "Tunnel ID: %u", tvb_get_ntohs(tvb, index));
651 case RECEIVE_WINDOW_SIZE:
652 proto_tree_add_text(l2tp_avp_tree, tvb, index, 2,
653 "Receive Window Size: %u",
654 tvb_get_ntohs(tvb, index));
658 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
659 "CHAP Challenge: %s",
660 tvb_bytes_to_str(tvb, index, avp_len));
665 * XXX - export stuff from the Q.931 dissector
666 * to dissect the cause code and cause message,
671 proto_tree_add_text(l2tp_avp_tree, tvb, index, 2,
673 tvb_get_ntohs(tvb, index));
679 proto_tree_add_text(l2tp_avp_tree, tvb, index, 1,
681 tvb_get_guint8(tvb, index));
687 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
688 "Advisory Msg: %.*s", avp_len,
689 tvb_get_ptr(tvb, index, avp_len));
692 case CHALLENGE_RESPONSE:
693 proto_tree_add_text(l2tp_avp_tree, tvb, index, 16,
694 "CHAP Challenge Response: %s",
695 tvb_bytes_to_str(tvb, index, 16));
698 case ASSIGNED_SESSION:
699 proto_tree_add_text(l2tp_avp_tree, tvb, index, 2,
700 "Assigned Session: %u",
701 tvb_get_ntohs(tvb, index));
704 case CALL_SERIAL_NUMBER:
705 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
706 "Call Serial Number: %u",
707 tvb_get_ntohl(tvb, index));
711 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
713 tvb_get_ntohl(tvb, index));
717 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
719 tvb_get_ntohl(tvb, index));
723 bits = tvb_get_ntohl(tvb, index);
724 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
725 "Analog Bearer Type: %s",
726 (BEARER_ANALOG(bits)) ? "True" : "False");
727 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
728 "Digital Bearer Type: %s",
729 (BEARER_DIGITAL(bits)) ? "True" : "False");
733 bits = tvb_get_ntohl(tvb, index);
734 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
735 "Async Framing Type: %s",
736 (FRAMING_ASYNC(bits)) ? "True" : "False");
737 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
738 "Sync Framing Type: %s",
739 (FRAMING_SYNC(bits)) ? "True" : "False");
745 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
746 "Called Number: %.*s", avp_len,
747 tvb_get_ptr(tvb, index, avp_len));
753 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
754 "Calling Number: %.*s", avp_len,
755 tvb_get_ptr(tvb, index, avp_len));
761 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
762 "Sub-Address: %.*s", avp_len,
763 tvb_get_ptr(tvb, index, avp_len));
766 case TX_CONNECT_SPEED:
767 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
769 tvb_get_ntohl(tvb, index));
772 case PHYSICAL_CHANNEL:
773 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
774 "Physical Channel: %u",
775 tvb_get_ntohl(tvb, index));
778 case INITIAL_RECEIVED_LCP_CONFREQ:
779 te = proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
780 "Initial Received LCP CONFREQ: %s",
781 tvb_bytes_to_str(tvb, index, avp_len));
782 l2tp_lcp_avp_tree = proto_item_add_subtree(te, ett_l2tp_lcp);
783 next_tvb = tvb_new_subset(tvb, index, avp_len, avp_len);
784 call_dissector(ppp_lcp_options_handle, next_tvb, pinfo, l2tp_lcp_avp_tree );
787 case LAST_SENT_LCP_CONFREQ:
788 te = proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
789 "Last Sent LCP CONFREQ: %s",
790 tvb_bytes_to_str(tvb, index, avp_len));
791 l2tp_lcp_avp_tree = proto_item_add_subtree(te, ett_l2tp_lcp);
792 next_tvb = tvb_new_subset(tvb, index, avp_len, avp_len);
793 call_dissector(ppp_lcp_options_handle, next_tvb, pinfo, l2tp_lcp_avp_tree );
796 case LAST_RECEIVED_LCP_CONFREQ:
797 te = proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
798 "Last Received LCP CONFREQ: %s",
799 tvb_bytes_to_str(tvb, index, avp_len));
800 l2tp_lcp_avp_tree = proto_item_add_subtree(te, ett_l2tp_lcp);
801 next_tvb = tvb_new_subset(tvb, index, avp_len, avp_len);
802 call_dissector(ppp_lcp_options_handle, next_tvb, pinfo, l2tp_lcp_avp_tree );
805 case PROXY_AUTHEN_TYPE:
806 msg_type = tvb_get_ntohs(tvb, index);
807 proto_tree_add_text(l2tp_avp_tree, tvb, index, 2,
808 "Proxy Authen Type: %s",
809 val_to_str(msg_type, authen_type_vals, "Unknown (%u)"));
812 case PROXY_AUTHEN_NAME:
815 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
816 "Proxy Authen Name: %.*s", avp_len,
817 tvb_get_ptr(tvb, index, avp_len));
820 case PROXY_AUTHEN_CHALLENGE:
821 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
822 "Proxy Authen Challenge: %s",
823 tvb_bytes_to_str(tvb, index, avp_len));
826 case PROXY_AUTHEN_ID:
827 proto_tree_add_text(l2tp_avp_tree, tvb, index + 1, 1,
828 "Proxy Authen ID: %u",
829 tvb_get_guint8(tvb, index + 1));
832 case PROXY_AUTHEN_RESPONSE:
833 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
834 "Proxy Authen Response: %s",
835 tvb_bytes_to_str(tvb, index, avp_len));
838 case CALL_STATUS_AVPS:
846 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
847 "CRC Errors: %u", tvb_get_ntohl(tvb, index));
853 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
854 "Framing Errors: %u", tvb_get_ntohl(tvb, index));
860 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
861 "Hardware Overruns: %u", tvb_get_ntohl(tvb, index));
867 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
868 "Buffer Overruns: %u", tvb_get_ntohl(tvb, index));
874 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
875 "Time-out Errors: %u", tvb_get_ntohl(tvb, index));
881 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
882 "Alignment Errors: %u", tvb_get_ntohl(tvb, index));
895 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
896 "Send ACCM: %u", tvb_get_ntohl(tvb, index));
902 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
903 "Receive ACCM: %u", tvb_get_ntohl(tvb, index));
909 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
911 tvb_bytes_to_str(tvb, index, avp_len));
914 case PRIVATE_GROUP_ID:
915 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
916 "Private Group ID: %s",
917 tvb_bytes_to_str(tvb, index, avp_len));
920 case RX_CONNECT_SPEED:
921 proto_tree_add_text(l2tp_avp_tree, tvb, index, 4,
922 "Rx Connect Speed: %u",
923 tvb_get_ntohl(tvb, index));
926 case PPP_DISCONNECT_CAUSE_CODE:
929 proto_tree_add_text(l2tp_avp_tree, tvb, index, 2,
930 "Disconnect Code: %u",
931 tvb_get_ntohs(tvb, index));
937 proto_tree_add_text(l2tp_avp_tree, tvb, index, 2,
938 "Control Protocol Number: %u",
939 tvb_get_ntohs(tvb, index));
945 proto_tree_add_text(l2tp_avp_tree, tvb, index, 1,
947 val_to_str(tvb_get_guint8(tvb, index),
948 cause_code_direction_vals,
955 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
956 "Message: %.*s", avp_len,
957 tvb_get_ptr(tvb, index, avp_len));
961 proto_tree_add_text(l2tp_avp_tree, tvb, index, avp_len,
966 /* printf("Avp Decode avp_len= %d index= %d length= %d %x\n ",avp_len,
967 index,length,length); */
975 /* registration with the filtering engine */
977 proto_register_l2tp(void)
979 static hf_register_info hf[] = {
981 { "Type", "l2tp.type", FT_UINT16, BASE_DEC, VALS(l2tp_type_vals), 0x8000,
982 "Type bit", HFILL }},
984 { &hf_l2tp_length_bit,
985 { "Length Bit", "l2tp.length_bit", FT_BOOLEAN, 16, TFS(&l2tp_length_bit_truth), 0x4000,
986 "Length bit", HFILL }},
989 { "Sequence Bit", "l2tp.seq_bit", FT_BOOLEAN, 16, TFS(&l2tp_seq_bit_truth), 0x0800,
990 "Sequence bit", HFILL }},
992 { &hf_l2tp_offset_bit,
993 { "Offset bit", "l2tp.offset_bit", FT_BOOLEAN, 16, TFS(&l2tp_offset_bit_truth), 0x0200,
994 "Offset bit", HFILL }},
997 { "Priority", "l2tp.priority", FT_BOOLEAN, 16, TFS(&l2tp_priority_truth), 0x0100,
998 "Priority bit", HFILL }},
1001 { "Version", "l2tp.version", FT_UINT16, BASE_DEC, NULL, 0x000f,
1002 "Version", HFILL }},
1005 { "Length","l2tp.length", FT_UINT16, BASE_DEC, NULL, 0x0,
1009 { "Tunnel ID","l2tp.tunnel", FT_UINT16, BASE_DEC, NULL, 0x0, /* Probably should be FT_BYTES */
1010 "Tunnel ID", HFILL }},
1013 { "Session ID","l2tp.session", FT_UINT16, BASE_DEC, NULL, 0x0, /* Probably should be FT_BYTES */
1014 "Session ID", HFILL }},
1017 { "Ns","l2tp.Ns", FT_UINT16, BASE_DEC, NULL, 0x0,
1021 { "Nr","l2tp.Nr", FT_UINT16, BASE_DEC, NULL, 0x0,
1025 { "Offset","l2tp.offset", FT_UINT16, BASE_DEC, NULL, 0x0,
1026 "Number of octest past the L2TP header at which the"
1027 "payload data starts.", HFILL }},
1029 { &hf_l2tp_avp_mandatory,
1030 { "Mandatory", "l2tp.avp.mandatory", FT_BOOLEAN, BASE_NONE, NULL, 0,
1031 "Mandatory AVP", HFILL }},
1033 { &hf_l2tp_avp_hidden,
1034 { "Hidden", "l2tp.avp.hidden", FT_BOOLEAN, BASE_NONE, NULL, 0,
1035 "Hidden AVP", HFILL }},
1037 { &hf_l2tp_avp_length,
1038 { "Length", "l2tp.avp.length", FT_UINT16, BASE_DEC, NULL, 0,
1039 "AVP Length", HFILL }},
1041 { &hf_l2tp_avp_vendor_id,
1042 { "Vendor ID", "l2tp.avp.vendor_id", FT_UINT16, BASE_DEC, VALS(avp_vendor_id_vals), 0,
1043 "AVP Vendor ID", HFILL }},
1045 { &hf_l2tp_avp_type,
1046 { "Type", "l2tp.avp.type", FT_UINT16, BASE_DEC, VALS(avp_type_vals), 0,
1047 "AVP Type", HFILL }},
1049 { &hf_l2tp_tie_breaker,
1050 { "Tie Breaker", "l2tp.tie_breaker", FT_UINT64, BASE_HEX, NULL, 0,
1051 "Tie Breaker", HFILL }},
1055 static gint *ett[] = {
1062 proto_l2tp = proto_register_protocol(
1063 "Layer 2 Tunneling Protocol", "L2TP", "l2tp");
1064 proto_register_field_array(proto_l2tp, hf, array_length(hf));
1065 proto_register_subtree_array(ett, array_length(ett));
1069 proto_reg_handoff_l2tp(void)
1071 dissector_handle_t l2tp_handle;
1073 l2tp_handle = create_dissector_handle(dissect_l2tp, proto_l2tp);
1074 dissector_add("udp.port", UDP_PORT_L2TP, l2tp_handle);
1077 * Get a handle for the PPP-in-HDLC-like-framing dissector.
1079 ppp_hdlc_handle = find_dissector("ppp_hdlc");
1080 ppp_lcp_options_handle = find_dissector("ppp_lcp_options");