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.3 2000/01/10 23:22:22 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_length = -1;
35 static int hf_l2tp_code = -1;
36 static int hf_l2tp_id =-1;
42 #ifdef HAVE_SYS_TYPES_H
43 # include <sys/types.h>
46 #ifdef HAVE_NETINET_IN_H
47 #include <netinet/in.h>
60 #define CONTROL_BIT(msg_info) (msg_info & 0x8000) /* Type bit control = 1 data = 0 */
61 #define LENGTH_BIT(msg_info) (msg_info & 0x4000) /* Length bit = 1 */
62 #define RESERVE_BITS(msg_info) (msg_info &0x37F8) /* Reserved bit - usused */
63 #define SEQUENCE_BIT(msg_info) (msg_info & 0x0800) /* SEQUENCE bit = 1 Ns and Nr fields */
64 #define OFFSET_BIT(msg_info) (msg_info & 0x0300) /* Offset */
65 #define PRIORITY_BIT(msg_info) (msg_info & 0x0100) /* Priority */
66 #define L2TP_VERSION(msg_info) (msg_info & 0x0007) /* Version of l2tp */
67 #define MANDATORY_BIT(msg_info) (msg_info & 0x8000) /* Mandatory = 1 */
68 #define HIDDEN_BIT(msg_info) (msg_info & 0x4000) /* Hidden = 1 */
69 #define AVP_LENGTH(msg_info) (msg_info & 0x03ff) /* AVP Length */
70 #define FRAMING_ASYNC(msg_info) (msg_info & 0x0001) /* ASYNCFraming Type */
71 #define FRAMING_SYNC(msg_info) (msg_info & 0x0002) /* SYNC Type */
75 static gint ett_l2tp = -1;
76 static gint ett_l2tp_avp = -1;
82 #define AVP_Reserved 5
90 #define AVP_Reserved1 13
94 #define NUM_CONTROL_CALL_TYPES 16
95 static const char *calltypestr[NUM_CONTROL_CALL_TYPES+1] = {
97 "Start_Control_Request ",
98 "Start_Control_Reply ",
99 "Start_Control_Connected ",
100 "Stop_Control_Notification ",
103 "Outgoing_Call_Request ",
104 "Outgoing_Call_Reply ",
105 "Outgoing_Call_Connected ",
106 "Incoming_Call_Request ",
107 "Incoming_Call_Reply ",
108 "Incoming_Call_Connected ",
110 "Call_Disconnect_Notification",
115 static const char *calltype_short_str[NUM_CONTROL_CALL_TYPES+1] = {
136 static const char *control_msg="Control Message";
137 static const char *data_msg="Data Message";
140 #define NUM_AUTH_TYPES 6
141 static const char *authen_types[NUM_AUTH_TYPES] = {
143 "Textual username and password",
147 "Microsoft CHAP Version 1",
150 #define CONTROL_MESSAGE 0
151 #define RESULT_ERROR_CODE 1
152 #define PROTOCOL_VERSION 2
153 #define FRAMING_CAPABIlITIES 3
154 #define BEARER_CAPABIlITIES 4
155 #define TIE_BREAKER 5
156 #define FIRMWARE_REVISION 6
158 #define VENDOR_NAME 8
159 #define ASSIGNED_TUNNEL_ID 9
160 #define RECEIVE_WINDOW_SIZE 10
162 #define CAUSE_CODE 12
163 #define CHALLENGE_RESPONSE 13
164 #define ASSIGNED_SESSION 14
165 #define CALL_SERIAL_NUMBER 15
166 #define MINIMUM_BPS 16
167 #define MAXIMUM_BPS 17
168 #define BEARER_TYPE 18
169 #define FRAMING_TYPE 19
170 #define UNKNOWN_MESSAGE 20
171 #define CALLED_NUMBER 21
172 #define CALLING_NUMBER 22
173 #define SUB_ADDRESS 23
174 #define TX_CONNECT_SPEED 24
175 #define PHYSICAL_CHANNEL 25
176 #define INITIAL_RECEIVED_LCP 26
177 #define LAST_SEND_LCP_CONFREQ 27
178 #define LAST_RECEIVED_LCP_CONFREQ 28
179 #define PROXY_AUTHEN_TYPE 29
180 #define PROXY_AUTHEN_NAME 30
181 #define PROXY_AUTHEN_CHALLENGE 31
182 #define PROXY_AUTHEN_ID 32
183 #define PROXY_AUTHEN_RESPONSE 33
184 #define CALL_STATUS_AVPS 34
186 #define UNOWN_MESSAGE_36
187 #define PRIVATE_GROUP_ID 37
188 #define RX_CONNECT_SPEED 38
189 #define SEQUENCING_REQUIRED 39
191 #define NUM_AVP_TYPES 40
192 static const char *avptypestr[NUM_AVP_TYPES] = {
194 "Result-Error Code ",
196 "Framing Capabilities ",
197 "Bearer Capabilities ",
199 "Firmware Revision ",
202 "Assigned Tunnel ID ",
203 "Receive Window Size ",
206 "Challenge Response ",
208 "Call Serial Number ",
219 "Initial Received lcP ",
220 "Last Send LCP CONFREQ ",
221 "Last Received LCP CONFREQ ",
222 "Proxy Authen Type ",
223 "Proxy Authen Name ",
224 "Proxy Authen Challenge ",
226 "Proxy Authen Response ",
232 "Sequencing Required ",
236 static gchar textbuffer[200];
237 void dissect_l2tp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
239 proto_tree *l2tp_tree, *l2tp_avp_tree;
242 u_char *tmp_ptr; /* temp pointer used during AVP decode */
243 u_char *ptr; /* pointer used during l2tp decode */
244 int index = 2; /* keeps track of depth into the AVP */
245 unsigned short ver; /* Version and more */
246 unsigned short length; /* Length field */
247 unsigned short tid; /* Tunnel ID */
248 unsigned short cid; /* Call ID */
249 unsigned short Nr; /* Next recv */
250 unsigned short Ns; /* Next sent */
251 unsigned short ver_len_hidden;
252 unsigned short vendor;
253 unsigned short avp_type;
254 unsigned short msg_type;
255 unsigned short avp_len;
256 unsigned short error_type;
257 unsigned short avp_ver;
258 unsigned short avp_rev;
259 unsigned short framing;
260 unsigned short firmware_rev;
261 unsigned short gen_type;
262 unsigned long long_type;
263 char error_string[100];
264 char message_string[200];
266 ptr = (u_char * )pd; /* point to the frame */
267 ptr = ptr + offset; /* current offset into the decoded frame */
268 memcpy(&ver,ptr,sizeof(unsigned short)); /* collect the version */
273 if (LENGTH_BIT(ver)) { /* length field included ? */
274 ptr += 2; index += 2; /* skip ahead */
275 memcpy(&length,ptr,sizeof(unsigned short)); /* collect the length */
276 length = (htons(length));
279 memcpy(&tid,(ptr+=2),sizeof(unsigned short)); /* collect the tunnel id & call id */
280 memcpy(&cid,(ptr+=2),sizeof(unsigned short));
282 if (check_col(fd, COL_PROTOCOL)) /* build output for closed L2tp frame displayed */
283 col_add_str(fd, COL_PROTOCOL, "L2TP");
284 if (check_col(fd, COL_INFO)) {
285 tid = htons(tid); cid = htons(cid);
287 if (CONTROL_BIT(ver)) {
288 /* CONTROL MESSAGE */
291 if ((LENGTH_BIT(ver))&&(length==12)) /* ZLB Message */
292 sprintf(textbuffer,"%s - ZLB (tunnel id=%d, session id=%d)",
293 control_msg , tid ,cid);
296 if (SEQUENCE_BIT(ver)) {
302 memcpy(&avp_type,(tmp_ptr+=2),sizeof(unsigned short));
303 avp_type=htons(avp_type);
305 if (avp_type == CONTROL_MESSAGE)
307 /* We print message type */
308 memcpy(&msg_type,(tmp_ptr+=2),sizeof(unsigned short));
309 msg_type=ntohs(msg_type);
310 sprintf(textbuffer,"%s - %s (tunnel id=%d, session id=%d)",
312 ((NUM_CONTROL_CALL_TYPES + 1 ) > msg_type) ?
313 calltype_short_str[msg_type] : "Unknown",
319 * This is not a control message.
320 * We never pass here except in case of bad l2tp packet!
322 sprintf(textbuffer,"%s (tunnel id=%d, session id=%d)",
323 control_msg , tid ,cid);
330 sprintf(textbuffer,"%s (tunnel id=%d, session id=%d)",
333 col_add_fstr(fd,COL_INFO,textbuffer);
336 ti = proto_tree_add_item(tree,proto_l2tp, offset, length , NULL);
337 l2tp_tree = proto_item_add_subtree(ti, ett_l2tp);
338 proto_tree_add_item_format(l2tp_tree,hf_l2tp_code, offset ,1,
339 rhcode, "Packet Type: %s Tunnel Id=%d Session Id=%d",( CONTROL_BIT(ver) ? control_msg : data_msg) ,tid,cid);
340 if (LENGTH_BIT(ver)) {
341 proto_tree_add_item_format(l2tp_tree,hf_l2tp_code, (offset += 2), 2,
342 rhcode, "Length: %d ", length);
344 if (SEQUENCE_BIT(ver)) {
345 memcpy(&Ns,(ptr+=2),sizeof(unsigned short));
346 memcpy(&Nr,(ptr+=2),sizeof(unsigned short));
348 proto_tree_add_item_format(l2tp_tree,hf_l2tp_code, (offset += 6 ), 4,
349 rhcode, "Ns: %d Nr: %d ", htons(Ns), htons(Nr));
351 if ((LENGTH_BIT(ver))&&(length==12)) {
352 proto_tree_add_item_format(l2tp_tree,hf_l2tp_code,offset,1,rhcode,
353 "Zero Length Bit message");
355 if (!CONTROL_BIT(ver)) { /* Data Messages so we are done */
356 proto_tree_add_item_format(l2tp_tree,hf_l2tp_code, (offset += 4) , (length - 12 ) , rhcode, "Data: ");
361 while (index < length ) { /* Process AVP's */
363 memcpy(&ver_len_hidden,(tmp_ptr+=2),sizeof(unsigned short));
364 avp_len = AVP_LENGTH(htons(ver_len_hidden));
365 index += avp_len; /* track how far into the control msg */
366 memcpy(&vendor,(tmp_ptr+=2),sizeof(unsigned short));
367 memcpy(&avp_type,(tmp_ptr+=2),sizeof(unsigned short));
368 avp_type=htons(avp_type);
369 tf = proto_tree_add_item_format(l2tp_tree,hf_l2tp_code, offset , avp_len,
370 rhcode, "AVP Type %s ", (NUM_AVP_TYPES > avp_type)
371 ? avptypestr[avp_type] : "Unknown");
372 l2tp_avp_tree = proto_item_add_subtree(tf, ett_l2tp_avp);
374 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset , 1,
375 rhcode, " Mandatory:%s" , (MANDATORY_BIT(htons(ver_len_hidden))) ? "True" : "False" );
376 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset , 1,
377 rhcode, " Hidden:%s" , (HIDDEN_BIT(htons(ver_len_hidden))) ? "True" : "False" );
378 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, (offset + 1), 1,
379 rhcode, " Length:%d" , avp_len );
381 if (HIDDEN_BIT(htons(ver_len_hidden))) { /* don't try do display hidden */
388 case CONTROL_MESSAGE:
389 memcpy(&msg_type,(tmp_ptr+=2),sizeof(unsigned short));
390 msg_type=htons(msg_type);
391 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 6, 2 ,
392 rhcode, " Control Message Type: (%d) %s", msg_type,
393 ((NUM_CONTROL_CALL_TYPES + 1 ) > msg_type) ?
394 calltypestr[msg_type] : "Unknown" );
397 case RESULT_ERROR_CODE:
398 if ( avp_len >= 10 ) {
399 memcpy(&error_type,(tmp_ptr+=2),sizeof(unsigned short));
400 error_type=htons(error_type);
401 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
403 " Error Type: %d", error_type );
407 if ( avp_len > 10 ) {
408 memset(error_string,'\0' ,sizeof(error_string));
410 strncpy(error_string,(tmp_ptr),(avp_len - 10));
411 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 9, (avp_len - 10),
412 rhcode, " Error Message: %s", error_string );
416 case PROTOCOL_VERSION:
418 memcpy(&avp_ver,(tmp_ptr),sizeof(unsigned short));
419 memcpy(&avp_rev,(tmp_ptr),sizeof(unsigned short));
420 avp_ver=(htons(avp_ver));
421 avp_rev=(htons(avp_rev));
422 memcpy(&avp_rev,(tmp_ptr+=2),sizeof(unsigned short));
423 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 6, 1,
424 rhcode, " Version: %d", ((avp_ver&0xff00)>>8) );
425 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 7, 1,
426 rhcode, " Revision: %d", (avp_ver&0x00ff));
429 case FRAMING_CAPABIlITIES:
431 memcpy(&framing,(tmp_ptr+=2),sizeof(unsigned short));
432 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 6, 4,
433 rhcode, " ASYNC FRAMING: %s" , (FRAMING_ASYNC(htons(framing))) ? "True" : "False" );
434 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 6, 4,
435 rhcode, " SYNC FRAMING: %s" , (FRAMING_SYNC(htons(framing))) ? "True" : "False" );
438 case BEARER_CAPABIlITIES:
440 memcpy(&framing,(tmp_ptr+=2),sizeof(unsigned short));
441 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 6, 4 ,
442 rhcode, " Analog Access: %s" , (FRAMING_ASYNC(htons(framing))) ? "True" : "False" );
443 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 6, 4,
444 rhcode, " Digital Access: %s" , (FRAMING_SYNC(htons(framing))) ? "True" : "False" );
448 memcpy(&long_type,(tmp_ptr+=8),sizeof(unsigned long));
449 long_type = htonl(long_type);
450 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 6, 1,
451 rhcode, " TIE_BREAKER %l 0x%x", long_type,long_type );
454 case FIRMWARE_REVISION:
455 memcpy(&firmware_rev,(tmp_ptr+=2),sizeof(unsigned short));
456 firmware_rev=htons(firmware_rev);
457 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 6, 2,
458 rhcode, " Firmware Revision: %d 0x%x", firmware_rev,firmware_rev );
462 memset(error_string,'\0',sizeof(error_string));
463 strncpy(error_string,(tmp_ptr+=2),(avp_len - 6));
464 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 6,
465 (avp_len - 6), rhcode, " Host Name: %s", error_string );
469 memset(message_string,'\0' ,sizeof(message_string));
470 strncpy(message_string,(tmp_ptr+=2),(avp_len - 6));
471 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 6,
472 (avp_len - 6), rhcode, " Vendor Name: %s", message_string );
475 case ASSIGNED_TUNNEL_ID:
476 memcpy(&gen_type,(tmp_ptr+=2),sizeof(unsigned short));
477 gen_type=htons(gen_type);
478 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
479 2, rhcode, " Tunnel ID: %d", gen_type );
482 case RECEIVE_WINDOW_SIZE:
483 memcpy(&gen_type,(tmp_ptr+=2),sizeof(unsigned short));
484 gen_type=htons(gen_type);
485 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
486 2, rhcode, " Receive Window Size: %d", gen_type );
490 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
491 (avp_len - 6 ), rhcode, " CHAP Challenge: ");
494 case CHALLENGE_RESPONSE:
495 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
496 (avp_len - 6 ), rhcode, " CHAP Challenge Response: ");
500 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
501 1, rhcode, " Cause Code: ");
504 case ASSIGNED_SESSION:
505 memcpy(&gen_type,(tmp_ptr+=2),sizeof(unsigned short));
506 gen_type=htons(gen_type);
507 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
508 2, rhcode, " Assigned Session: %d", gen_type );
511 case CALL_SERIAL_NUMBER:
512 memcpy(&gen_type,(tmp_ptr+=2),sizeof(unsigned short));
513 gen_type=htons(gen_type);
514 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
515 4, rhcode, " Call Serial Number: %d", gen_type );
519 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
520 4, rhcode, " Minimum BPS: ");
524 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
525 4, rhcode, " Maximum BPS ");
529 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
530 4, rhcode, " Bearer Type: ");
534 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
535 4, rhcode, " Framing Type: ");
538 case UNKNOWN_MESSAGE:
539 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
540 1, rhcode, " Unknown Message: ");
544 memset(message_string,'\0' ,sizeof(message_string));
545 strncpy(message_string,(tmp_ptr+=2),(avp_len - 6));
546 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 6,
547 (avp_len - 6), rhcode, " Called Number: %s", message_string );
551 memset(message_string,'\0' ,sizeof(message_string));
552 strncpy(message_string,(tmp_ptr+=2),(avp_len - 6));
553 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 6,
554 (avp_len - 6), rhcode, " Calling Number: %s", message_string );
558 memset(message_string,'\0' ,sizeof(message_string));
559 strncpy(message_string,(tmp_ptr+=2),(avp_len - 6));
560 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code, offset + 6,
561 (avp_len - 6), rhcode, " Sub-Address: %s", message_string );
564 case TX_CONNECT_SPEED:
565 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
566 4, rhcode, " Connect Speed: ");
569 case PHYSICAL_CHANNEL:
570 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
571 4, rhcode, " Physical Channel: ");
574 case INITIAL_RECEIVED_LCP:
575 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
576 (avp_len - 6 ), rhcode, " Initial LCP Conf REQ: ");
579 case LAST_SEND_LCP_CONFREQ:
580 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
581 (avp_len - 6 ), rhcode, " Last Sent LCP Conf REQ: ");
584 case LAST_RECEIVED_LCP_CONFREQ:
585 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
586 (avp_len - 6 ), rhcode, " Last Received LCP Conf REQ: ");
589 case PROXY_AUTHEN_TYPE:
590 memcpy(&msg_type,(tmp_ptr+=2),sizeof(unsigned short));
591 msg_type=htons(msg_type);
592 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
593 1, rhcode, " Proxy Authen Type: %s ", authen_types[msg_type] );
596 case PROXY_AUTHEN_NAME:
597 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
598 (avp_len - 6 ), rhcode, " Proxy Authen Name: ");
601 case PROXY_AUTHEN_CHALLENGE:
602 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
603 (avp_len - 6 ), rhcode, " Proxy Authen Challenge: ");
606 case PROXY_AUTHEN_ID:
607 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
608 2, rhcode, " Paorx Authen ID: ");
611 case PROXY_AUTHEN_RESPONSE:
612 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
613 (avp_len - 6 ), rhcode, " Proxy Authen Response: ");
616 case CALL_STATUS_AVPS:
617 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
618 4, rhcode, " CRC Errors: ");
619 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 10,
620 4, rhcode, " Framing Errors: ");
621 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 14,
622 4, rhcode, " Hardware Overruns: ");
623 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 18,
624 4, rhcode, " Buffer Overruns: ");
625 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 23,
626 4, rhcode, " Time-out Errors: ");
627 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 26,
628 4, rhcode, " Alignment Errors: ");
632 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
633 2, rhcode, " Reserve Quantity: ");
634 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 8,
635 4, rhcode, " Send ACCM: ");
636 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 12,
637 4, rhcode, " Recv ACCM: ");
640 case PRIVATE_GROUP_ID:
641 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
642 1, rhcode, " Private Group ID: ");
645 case RX_CONNECT_SPEED:
646 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset + 6,
647 4, rhcode, " RX Connect Speed: ");
650 case SEQUENCING_REQUIRED:
651 proto_tree_add_item_format(l2tp_avp_tree,hf_l2tp_code,offset ,
652 1, rhcode, " Sequencing Required: ");
656 /* printf("Avp Decode avp_len= %d index= %d length= %d %x\n ",avp_len,
657 index,length,length); */
665 /* registration with the filtering engine */
667 proto_register_l2tp(void)
669 static hf_register_info hf[] = {
671 { "Code","l2tp.code", FT_UINT8, BASE_DEC, NULL, 0x0,
675 { "Identifier", "l2tp.id", FT_UINT8, BASE_DEC, NULL, 0x0,
679 { "Length","l2tp.length", FT_UINT16, BASE_DEC, NULL, 0x0,
683 static gint *ett[] = {
688 proto_l2tp = proto_register_protocol ("L2TP Protocol", "l2tp");
689 proto_register_field_array(proto_l2tp, hf, array_length(hf));
690 proto_register_subtree_array(ett, array_length(ett));