From Carlos Pignataro: Add MPLS Echo support.
svn path=/trunk/; revision=10876
This commit is contained in:
parent
fa774f5231
commit
939512198d
7
AUTHORS
7
AUTHORS
|
@ -2104,11 +2104,16 @@ Lukas Pokorny <maskis [AT] seznam.cz> {
|
|||
RTPS (Real-Time Publish-Subscribe) support
|
||||
}
|
||||
|
||||
Carlos M. Pignataro <cpignata [AT] cisco.com> {
|
||||
Carlos Pignataro <cpignata [AT] cisco.com> {
|
||||
Graceful Restart Mechanism for LDP [RFC3478]
|
||||
Fault Tolerance for LDP [RFC3479]
|
||||
Other LDP enhancements
|
||||
PPP OSI Network Layer Control Protocol [RFC1377]
|
||||
Fix dissecting of CLNS Protocols over Cisco HDLC
|
||||
PWE3 Interface parameter additions and miscelaneous updates
|
||||
from various IETF PWE3 drafts
|
||||
MPLS PW Control Channel Header
|
||||
Multiprotocol Label Switching Echo [draft-ietf-mpls-lsp-ping-05]
|
||||
}
|
||||
|
||||
Thomas Anders <thomas.anders [AT] blue-cable.de> {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# a) common to both files and
|
||||
# b) portable between both files
|
||||
#
|
||||
# $Id: Makefile.common,v 1.43 2004/05/10 03:30:24 gerald Exp $
|
||||
# $Id: Makefile.common,v 1.44 2004/05/13 20:20:33 gerald Exp $
|
||||
#
|
||||
# Ethereal - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -128,6 +128,7 @@ DISSECTOR_INCLUDES = \
|
|||
packet-kerberos.h \
|
||||
packet-klm.h \
|
||||
packet-ldap.h \
|
||||
packet-ldp.h \
|
||||
packet-llc.h \
|
||||
packet-mip6.h \
|
||||
packet-mount.h \
|
||||
|
|
4
NEWS
4
NEWS
|
@ -1,4 +1,4 @@
|
|||
$Id: NEWS,v 1.146 2004/05/13 20:02:24 gerald Exp $
|
||||
$Id: NEWS,v 1.147 2004/05/13 20:20:33 gerald Exp $
|
||||
|
||||
== May ??, 2004
|
||||
|
||||
|
@ -34,7 +34,7 @@ New and updated features
|
|||
New protocol support
|
||||
|
||||
ANSI IS-801, BEA Tuxedo, DCERPC EFS, DICOM, GPRS LLC, GPRS SNDCP,
|
||||
IEEE 1588/PTP, PVSTP, RTPS, WBXML OPAQUE
|
||||
IEEE 1588/PTP, PVSTP, MPLS Echo, RTPS, WBXML OPAQUE
|
||||
|
||||
|
||||
Updated protocol support
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# a) common to both files and
|
||||
# b) portable between both files
|
||||
#
|
||||
# $Id: Makefile.common,v 1.24 2004/05/12 03:37:28 gerald Exp $
|
||||
# $Id: Makefile.common,v 1.25 2004/05/13 20:20:34 gerald Exp $
|
||||
#
|
||||
# Ethereal - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -308,6 +308,7 @@ DISSECTOR_SRC = \
|
|||
../packet-mount.c \
|
||||
../packet-mpeg1.c \
|
||||
../packet-mpls.c \
|
||||
../packet-mpls-echo.c \
|
||||
../packet-mq.c \
|
||||
../packet-mq-pcf.c \
|
||||
../packet-mrdisc.c \
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* packet-ldp.c
|
||||
* Routines for LDP (RFC 3036) packet disassembly
|
||||
*
|
||||
* $Id: packet-ldp.c,v 1.52 2004/05/11 11:20:34 guy Exp $
|
||||
* $Id: packet-ldp.c,v 1.53 2004/05/13 20:20:33 gerald Exp $
|
||||
*
|
||||
* Copyright (c) November 2000 by Richard Sharpe <rsharpe@ns.aus.com>
|
||||
*
|
||||
|
@ -397,7 +397,7 @@ static const value_string fec_types[] = {
|
|||
};
|
||||
|
||||
|
||||
static const value_string fec_vc_types_vals[] = {
|
||||
const value_string fec_vc_types_vals[] = {
|
||||
{0x0001, "Frame Relay DLCI"},
|
||||
{0x0002, "ATM AAL5 SDU VCC transport"},
|
||||
{0x0003, "ATM transparent cell transport"},
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* packet-ldp.h
|
||||
* Declarations of exported routines from LDP dissector
|
||||
* Copyright 2004, Carlos Pignataro <cpignata@cisco.com>
|
||||
*
|
||||
* $Id: packet-ldp.h,v 1.1 2004/05/13 20:20:34 gerald Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PACKET_LDP_H_
|
||||
#define __PACKET_LDP_H__
|
||||
|
||||
/*
|
||||
* Used by MPLS Echo dissector as well.
|
||||
*/
|
||||
extern const enum_val_t fec_vc_types_vals[];
|
||||
|
||||
#endif
|
|
@ -0,0 +1,526 @@
|
|||
/* packet-mpls-echo.c
|
||||
* Routines for Multiprotocol Label Switching Echo dissection
|
||||
* Copyright 2004, Carlos Pignataro <cpignata@cisco.com>
|
||||
*
|
||||
* $Id: packet-mpls-echo.c,v 1.1 2004/05/13 20:20:34 gerald Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include <epan/packet.h>
|
||||
#include "prefs.h"
|
||||
#include "packet-ntp.h"
|
||||
#include "packet-ldp.h"
|
||||
|
||||
#define UDP_PORT_MPLS_ECHO 3503
|
||||
|
||||
void proto_reg_handoff_mpls_echo(void);
|
||||
|
||||
static int proto_mpls_echo = -1;
|
||||
static int hf_mpls_echo_version = -1;
|
||||
static int hf_mpls_echo_mbz = -1;
|
||||
static int hf_mpls_echo_msgtype = -1;
|
||||
static int hf_mpls_echo_replymode = -1;
|
||||
static int hf_mpls_echo_returncode = -1;
|
||||
static int hf_mpls_echo_returnsubcode = -1;
|
||||
static int hf_mpls_echo_handle = -1;
|
||||
static int hf_mpls_echo_sequence = -1;
|
||||
static int hf_mpls_echo_ts_sent = -1;
|
||||
static int hf_mpls_echo_ts_rec = -1;
|
||||
static int hf_mpls_echo_tlv_type = -1;
|
||||
static int hf_mpls_echo_tlv_len = -1;
|
||||
static int hf_mpls_echo_tlv_value = -1;
|
||||
static int hf_mpls_echo_tlv_fec_type = -1;
|
||||
static int hf_mpls_echo_tlv_fec_len = -1;
|
||||
static int hf_mpls_echo_tlv_fec_value = -1;
|
||||
static int hf_mpls_echo_tlv_fec_ldp_ipv4 = -1;
|
||||
static int hf_mpls_echo_tlv_fec_ldp_ipv4_mask = -1;
|
||||
static int hf_mpls_echo_tlv_fec_l2cid_sender = -1;
|
||||
static int hf_mpls_echo_tlv_fec_l2cid_remote = -1;
|
||||
static int hf_mpls_echo_tlv_fec_l2cid_vcid = -1;
|
||||
static int hf_mpls_echo_tlv_fec_l2cid_encap = -1;
|
||||
static int hf_mpls_echo_tlv_fec_l2cid_mbz = -1;
|
||||
static int hf_mpls_echo_tlv_padaction = -1;
|
||||
static int hf_mpls_echo_tlv_padding = -1;
|
||||
|
||||
static gint ett_mpls_echo = -1;
|
||||
static gint ett_mpls_echo_tlv = -1;
|
||||
static gint ett_mpls_echo_tlv_fec = -1;
|
||||
|
||||
static int mpls_echo_udp_port = 0;
|
||||
|
||||
static guint32 global_mpls_echo_udp_port = UDP_PORT_MPLS_ECHO;
|
||||
|
||||
static const value_string mpls_echo_msgtype[] = {
|
||||
{1, "MPLS Echo Request"},
|
||||
{2, "MPLS Echo Reply"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static const value_string mpls_echo_replymode[] = {
|
||||
{1, "Do not reply"},
|
||||
{2, "Reply via an IPv4/IPv6 UDP packet"},
|
||||
{3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"},
|
||||
{4, "Reply via application level control channel"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static const value_string mpls_echo_returncode[] = {
|
||||
{0, "No return code"},
|
||||
{1, "Malformed echo request received"},
|
||||
{2, "One or more of the TLVs was not understood"},
|
||||
{3, "Replying router is an egress for the FEC at stack depth RSC"},
|
||||
{4, "Replying router has no mapping for the FEC at stack depth RSC"},
|
||||
{5, "Reserved"},
|
||||
{6, "Reserved"},
|
||||
{7, "Reserved"},
|
||||
{8, "Label switched at stack-depth RSC"},
|
||||
{9, "Label switched but no MPLS forwarding at stack-depth RSC"},
|
||||
{10, "Mapping for this FEC is not the given label at stack depth RSC"},
|
||||
{11, "No label entry at stack-depth RSC"},
|
||||
{12, "Protocol not associated with interface at FEC stack depth RSC"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
#define TLV_TARGET_FEC_STACK 0x0001
|
||||
#define TLV_DOWNSTREAM_MAPPING 0x0002
|
||||
#define TLV_PAD 0x0003
|
||||
#define TLV_ERROR_CODE 0x0004
|
||||
#define TLV_VENDOR_CODE 0x0005
|
||||
|
||||
/* MPLS Echo TLV Type names */
|
||||
static const value_string mpls_echo_tlv_type_names[] = {
|
||||
{ TLV_TARGET_FEC_STACK, "Target FEC Stack" },
|
||||
{ TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" },
|
||||
{ TLV_PAD, "Pad" },
|
||||
{ TLV_ERROR_CODE, "Error Code" },
|
||||
{ TLV_VENDOR_CODE, "Vendor Enterprise Code" },
|
||||
{ 0, NULL}
|
||||
};
|
||||
|
||||
#define TLV_FEC_STACK_LDP_IPv4 1
|
||||
#define TLV_FEC_STACK_LDP_IPv6 2
|
||||
#define TLV_FEC_STACK_RSVP_IPv4 3
|
||||
#define TLV_FEC_STACK_RSVP_IPv6 4
|
||||
#define TLV_FEC_STACK_RES 5
|
||||
#define TLV_FEC_STACK_VPN_IPv4 6
|
||||
#define TLV_FEC_STACK_VPN_IPv6 7
|
||||
#define TLV_FEC_STACK_L2_VPN 8
|
||||
#define TLV_FEC_STACK_L2_CID 9
|
||||
|
||||
/* FEC sub-TLV Type names */
|
||||
static const value_string mpls_echo_tlv_fec_names[] = {
|
||||
{ TLV_FEC_STACK_LDP_IPv4, "LDP IPv4 prefix"},
|
||||
{ TLV_FEC_STACK_LDP_IPv6, "LDP IPv6 prefix"},
|
||||
{ TLV_FEC_STACK_RSVP_IPv4, "RSVP IPv4 Session Query"},
|
||||
{ TLV_FEC_STACK_RSVP_IPv6, "RSVP IPv6 Session Query"},
|
||||
{ TLV_FEC_STACK_RES, "Reserved"},
|
||||
{ TLV_FEC_STACK_VPN_IPv4, "VPN IPv4 prefix"},
|
||||
{ TLV_FEC_STACK_VPN_IPv6, "VPN IPv6 prefix"},
|
||||
{ TLV_FEC_STACK_L2_VPN, "L2 VPN endpoint"},
|
||||
{ TLV_FEC_STACK_L2_CID, "L2 cirtuit ID"},
|
||||
{ 0, NULL}
|
||||
};
|
||||
|
||||
static const value_string mpls_echo_tlv_pad[] = {
|
||||
{ 1, "Drop Pad TLV from reply" },
|
||||
{ 2, "Copy Pad TLV to reply" },
|
||||
{ 0, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
* Dissector for FEC sub-TLVs
|
||||
*/
|
||||
static void
|
||||
dissect_mpls_echo_tlv_fec(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
|
||||
{
|
||||
proto_tree *ti = NULL, *tlv_fec_tree = NULL;
|
||||
guint16 index = 1, type;
|
||||
int length;
|
||||
|
||||
if (tree){
|
||||
while (rem >= 4){ /* Type, Length */
|
||||
type = tvb_get_ntohs(tvb, offset);
|
||||
length = tvb_get_ntohs(tvb, offset + 2);
|
||||
ti = proto_tree_add_text(tree, tvb, offset, length + 4, "FEC Element %u: %s",
|
||||
index, val_to_str(type, mpls_echo_tlv_fec_names,
|
||||
"Unknown FEC type (0x%04X)"));
|
||||
tlv_fec_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_fec);
|
||||
if(tlv_fec_tree == NULL) return;
|
||||
|
||||
/* FEC sub-TLV Type and Length */
|
||||
proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_type, tvb, offset,
|
||||
2, FALSE);
|
||||
proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_len, tvb, offset + 2,
|
||||
2, FALSE);
|
||||
|
||||
/* FEC sub-TLV Value */
|
||||
switch (type) {
|
||||
case TLV_FEC_STACK_LDP_IPv4:
|
||||
proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv4,
|
||||
tvb, offset + 4, 4, FALSE);
|
||||
proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv4_mask,
|
||||
tvb, offset + 8, 1, FALSE);
|
||||
if (length == 9)
|
||||
proto_tree_add_text(tlv_fec_tree, tvb, offset + 6, 3, "Padding");
|
||||
break;
|
||||
case TLV_FEC_STACK_L2_CID:
|
||||
if (length != 16){
|
||||
if(tree)
|
||||
proto_tree_add_text(tree, tvb, offset, rem,
|
||||
"Error processing sub-TLV: length is %d, should be 16", length);
|
||||
return;
|
||||
}
|
||||
proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_sender,
|
||||
tvb, offset + 4, 4, FALSE);
|
||||
proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_remote,
|
||||
tvb, offset + 8, 4, FALSE);
|
||||
proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_vcid,
|
||||
tvb, offset + 12, 4, FALSE);
|
||||
proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_encap,
|
||||
tvb, offset + 16, 2, FALSE);
|
||||
proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_mbz,
|
||||
tvb, offset + 18, 2, FALSE);
|
||||
break;
|
||||
case TLV_FEC_STACK_LDP_IPv6:
|
||||
case TLV_FEC_STACK_RSVP_IPv4:
|
||||
case TLV_FEC_STACK_RSVP_IPv6:
|
||||
case TLV_FEC_STACK_RES:
|
||||
case TLV_FEC_STACK_VPN_IPv4:
|
||||
case TLV_FEC_STACK_VPN_IPv6:
|
||||
case TLV_FEC_STACK_L2_VPN:
|
||||
default:
|
||||
proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_value, tvb, offset + 4,
|
||||
length, FALSE);
|
||||
break;
|
||||
}
|
||||
rem -= 4 + length;
|
||||
offset += 4 + length;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Dissector for MPLS Echo TLVs and return bytes consumed
|
||||
*/
|
||||
static int
|
||||
dissect_mpls_echo_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
|
||||
{
|
||||
guint16 type;
|
||||
int length;
|
||||
proto_tree *ti = NULL, *mpls_echo_tlv_tree = NULL;
|
||||
|
||||
length = tvb_reported_length_remaining(tvb, offset);
|
||||
rem = MIN(rem, length);
|
||||
|
||||
if( rem < 4 ) { /* Type Length */
|
||||
if(tree)
|
||||
proto_tree_add_text(tree, tvb, offset, rem,
|
||||
"Error processing TLV: length is %d, should be >= 4",
|
||||
rem);
|
||||
return rem;
|
||||
}
|
||||
type = tvb_get_ntohs(tvb, offset);
|
||||
length = tvb_get_ntohs(tvb, offset + 2),
|
||||
rem -= 4; /* do not count Type Length */
|
||||
length = MIN(length, rem);
|
||||
|
||||
if (tree) {
|
||||
ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
|
||||
val_to_str(type, mpls_echo_tlv_type_names, "Unknown TLV type (0x%04X)"));
|
||||
mpls_echo_tlv_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv);
|
||||
if(mpls_echo_tlv_tree == NULL) return length+4;
|
||||
|
||||
/* MPLS Echo TLV Type and Length */
|
||||
proto_tree_add_uint_format(mpls_echo_tlv_tree, hf_mpls_echo_tlv_type, tvb,
|
||||
offset, 2, type, "Type: %s (%u)",
|
||||
val_to_str(type, mpls_echo_tlv_type_names, "Unknown TLV type"), type );
|
||||
proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_len, tvb, offset + 2, 2, FALSE);
|
||||
|
||||
/* MPLS Echo TLV Value */
|
||||
switch (type) {
|
||||
case TLV_TARGET_FEC_STACK:
|
||||
dissect_mpls_echo_tlv_fec(tvb, offset + 4, mpls_echo_tlv_tree, length);
|
||||
break;
|
||||
case TLV_PAD:
|
||||
proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_padaction, tvb,
|
||||
offset + 4, 1, FALSE);
|
||||
proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_padding, tvb,
|
||||
offset + 5, length - 1, FALSE);
|
||||
break;
|
||||
case TLV_DOWNSTREAM_MAPPING:
|
||||
case TLV_ERROR_CODE:
|
||||
case TLV_VENDOR_CODE:
|
||||
default:
|
||||
proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_value, tvb,
|
||||
offset + 4, length, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return length + 4; /* Length of the Value field + Type Length */
|
||||
}
|
||||
|
||||
/*
|
||||
* Dissector for MPLS Echo (LSP PING) packets
|
||||
*/
|
||||
static void
|
||||
dissect_mpls_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
int offset = 0, rem = 0, len;
|
||||
proto_item *ti = NULL;
|
||||
proto_tree *mpls_echo_tree = NULL;
|
||||
guint8 msgtype;
|
||||
const guint8 *ts_sent, *ts_rec;
|
||||
gchar buff[NTP_TS_SIZE];
|
||||
|
||||
/* If version != 1 we assume it's not an mpls ping packet */
|
||||
if (!tvb_bytes_exist(tvb, 0, 2)) {
|
||||
return; /* Not enough information to tell. */
|
||||
}
|
||||
if (tvb_get_ntohs(tvb, 0) != 1) {
|
||||
return; /* Not version 1. */
|
||||
}
|
||||
|
||||
if (check_col(pinfo->cinfo, COL_PROTOCOL))
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPLS ECHO");
|
||||
|
||||
rem = tvb_reported_length_remaining(tvb, offset);
|
||||
|
||||
if( rem < 32 ) { /* The fixed part of the packet is 32 Bytes */
|
||||
if( check_col(pinfo->cinfo, COL_INFO) )
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "Malformed Message");
|
||||
if(tree)
|
||||
proto_tree_add_text(tree, tvb, offset, rem,
|
||||
"Error processing Message: length is %d, should be >= 32",
|
||||
rem);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the message type and fill in the Column info */
|
||||
msgtype = tvb_get_guint8(tvb, offset + 4);
|
||||
if (check_col(pinfo->cinfo, COL_INFO))
|
||||
col_set_str(pinfo->cinfo, COL_INFO,
|
||||
val_to_str(msgtype, mpls_echo_msgtype, "Unknown Message Type (0x%02X)"));
|
||||
|
||||
|
||||
if (tree) {
|
||||
|
||||
/* Add subtree and dissect the fixed part of the message */
|
||||
ti = proto_tree_add_item(tree, proto_mpls_echo, tvb, 0, -1, FALSE);
|
||||
mpls_echo_tree = proto_item_add_subtree(ti, ett_mpls_echo);
|
||||
|
||||
proto_tree_add_item(mpls_echo_tree,
|
||||
hf_mpls_echo_version, tvb, offset, 2, FALSE);
|
||||
proto_tree_add_item(mpls_echo_tree,
|
||||
hf_mpls_echo_mbz, tvb, offset + 2, 2, FALSE);
|
||||
proto_tree_add_item(mpls_echo_tree,
|
||||
hf_mpls_echo_msgtype, tvb, offset + 4, 1, FALSE);
|
||||
proto_tree_add_item(mpls_echo_tree,
|
||||
hf_mpls_echo_replymode, tvb, offset + 5, 1, FALSE);
|
||||
proto_tree_add_item(mpls_echo_tree,
|
||||
hf_mpls_echo_returncode, tvb, offset + 6, 1, FALSE);
|
||||
proto_tree_add_item(mpls_echo_tree,
|
||||
hf_mpls_echo_returnsubcode, tvb, offset + 7, 1, FALSE);
|
||||
proto_tree_add_item(mpls_echo_tree,
|
||||
hf_mpls_echo_handle, tvb, offset + 8, 4, FALSE);
|
||||
proto_tree_add_item(mpls_echo_tree,
|
||||
hf_mpls_echo_sequence, tvb, offset + 12, 4, FALSE);
|
||||
|
||||
/* Using NTP routine to calculate the timestamp */
|
||||
ts_sent = tvb_get_ptr(tvb, 16, 8);
|
||||
proto_tree_add_bytes_format(mpls_echo_tree, hf_mpls_echo_ts_sent, tvb,
|
||||
offset + 16, 8, ts_sent, "Timestamp Sent: %s", ntp_fmt_ts(ts_sent, buff));
|
||||
ts_rec = tvb_get_ptr(tvb, 24, 8);
|
||||
proto_tree_add_bytes_format(mpls_echo_tree, hf_mpls_echo_ts_rec, tvb,
|
||||
offset + 24, 8, ts_rec, "Timestamp Received: %s", ntp_fmt_ts(ts_rec, buff));
|
||||
|
||||
}
|
||||
|
||||
offset += 32;
|
||||
rem -= 32;
|
||||
|
||||
/* Dissect all TLVs */
|
||||
while(tvb_reported_length_remaining(tvb, offset) > 0 ) {
|
||||
len = dissect_mpls_echo_tlv(tvb, offset, mpls_echo_tree, rem);
|
||||
offset += len;
|
||||
rem -= len;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Register the protocol with Ethereal */
|
||||
|
||||
void
|
||||
proto_register_mpls_echo(void)
|
||||
{
|
||||
|
||||
static hf_register_info hf[] = {
|
||||
{ &hf_mpls_echo_version,
|
||||
{ "Version", "mpls_echo.version",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO Version Number", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_mbz,
|
||||
{ "MBZ", "mpls_echo.mbz",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO Must Be Zero", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_msgtype,
|
||||
{ "Message Type", "mpls_echo.msg_type",
|
||||
FT_UINT8, BASE_DEC, VALS(mpls_echo_msgtype), 0x0, "MPLS ECHO Message Type", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_replymode,
|
||||
{ "Reply Mode", "mpls_echo.reply_mode",
|
||||
FT_UINT8, BASE_DEC, VALS(mpls_echo_replymode), 0x0, "MPLS ECHO Reply Mode", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_returncode,
|
||||
{ "Return Code", "mpls_echo.return_code",
|
||||
FT_UINT8, BASE_DEC, VALS(mpls_echo_returncode), 0x0, "MPLS ECHO Return Code", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_returnsubcode,
|
||||
{ "Return Subcode", "mpls_echo.return_subcode",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO Return Subcode", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_handle,
|
||||
{ "Sender's Handle", "mpls_echo.sender_handle",
|
||||
FT_UINT32, BASE_HEX, NULL, 0x0, "MPLS ECHO Sender's Handle", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_sequence,
|
||||
{ "Sequence Number", "mpls_echo.sequence",
|
||||
FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO Sequence Number", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_ts_sent,
|
||||
{ "Timestamp Sent", "mpls_echo.timestamp_sent",
|
||||
FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO Timestamp Sent", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_ts_rec,
|
||||
{ "Timestamp Received", "mpls_echo.timestamp_rec",
|
||||
FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO Timestamp Received", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_type,
|
||||
{ "Type", "mpls_echo.tlv.type",
|
||||
FT_UINT16, BASE_DEC, VALS(mpls_echo_tlv_type_names), 0x0,
|
||||
"MPLS ECHO TLV Type", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_len,
|
||||
{ "Length", "mpls_echo.tlv.len",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Length", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_value,
|
||||
{ "Value", "mpls_echo.tlv.value",
|
||||
FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Value", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_fec_type,
|
||||
{ "Type", "mpls_echo.tlv.fec.type",
|
||||
FT_UINT16, BASE_DEC, VALS(mpls_echo_tlv_fec_names), 0x0,
|
||||
"MPLS ECHO TLV FEC Stack Type", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_fec_len,
|
||||
{ "Length", "mpls_echo.tlv.fec.len",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack Length", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_fec_value,
|
||||
{ "Value", "mpls_echo.tlv.fec.value",
|
||||
FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack Value", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_fec_ldp_ipv4,
|
||||
{ "IPv4 Prefix", "mpls_echo.tlv.fec.ldp_ipv4",
|
||||
FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IPv4", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_fec_ldp_ipv4_mask,
|
||||
{ "Prefix Length", "mpls_echo.tlv.fec.ldp_ipv4_mask",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack IPv4 Prefix Length", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_fec_l2cid_sender,
|
||||
{ "Sender's PE Address", "mpls_echo.tlv.fec.l2cid_sender",
|
||||
FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID Sender", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_fec_l2cid_remote,
|
||||
{ "Remote PE Address", "mpls_echo.tlv.fec.l2cid_remote",
|
||||
FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID Remote", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_fec_l2cid_vcid,
|
||||
{ "VC ID", "mpls_echo.tlv.fec.l2cid_vcid",
|
||||
FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID VCID", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_fec_l2cid_encap,
|
||||
{ "Encapsulation", "mpls_echo.tlv.fec.l2cid_encap",
|
||||
FT_UINT16, BASE_DEC, VALS(fec_vc_types_vals), 0x0, "MPLS ECHO TLV FEC Stack L2CID Encapsulation", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_fec_l2cid_mbz,
|
||||
{ "MBZ", "mpls_echo.tlv.fec.l2cid_mbz",
|
||||
FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID MBZ", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_padaction,
|
||||
{ "Pad Action", "mpls_echo.tlv.pad_action",
|
||||
FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_pad), 0x0, "MPLS ECHO Pad TLV Action", HFILL}
|
||||
},
|
||||
{ &hf_mpls_echo_tlv_padding,
|
||||
{ "Padding", "mpls_echo.tlv.pad_padding",
|
||||
FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO Pad TLV Padding", HFILL}
|
||||
}
|
||||
};
|
||||
|
||||
static gint *ett[] = {
|
||||
&ett_mpls_echo,
|
||||
&ett_mpls_echo_tlv,
|
||||
&ett_mpls_echo_tlv_fec,
|
||||
};
|
||||
|
||||
module_t *mpls_echo_module;
|
||||
|
||||
proto_mpls_echo = proto_register_protocol("Multiprotocol Label Switching Echo",
|
||||
"MPLS Echo", "mpls-echo");
|
||||
|
||||
proto_register_field_array(proto_mpls_echo, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
|
||||
mpls_echo_module = prefs_register_protocol(proto_mpls_echo, proto_reg_handoff_mpls_echo);
|
||||
prefs_register_uint_preference(mpls_echo_module, "udp.port", "MPLS Echo UDP Port",
|
||||
"Set the UDP port for messages (if other"
|
||||
" than the default of 3503)",
|
||||
10, &global_mpls_echo_udp_port);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
proto_reg_handoff_mpls_echo(void)
|
||||
{
|
||||
static gboolean mpls_echo_prefs_initialized = FALSE;
|
||||
static dissector_handle_t mpls_echo_handle;
|
||||
|
||||
if(!mpls_echo_prefs_initialized) {
|
||||
mpls_echo_handle = create_dissector_handle(dissect_mpls_echo,
|
||||
proto_mpls_echo);
|
||||
mpls_echo_prefs_initialized = TRUE;
|
||||
} else {
|
||||
dissector_delete("udp.port", mpls_echo_udp_port, mpls_echo_handle);
|
||||
}
|
||||
|
||||
mpls_echo_udp_port = global_mpls_echo_udp_port;
|
||||
dissector_add("udp.port", global_mpls_echo_udp_port, mpls_echo_handle);
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
* Routines for NTP packet dissection
|
||||
* Copyright 1999, Nathan Neulinger <nneul@umr.edu>
|
||||
*
|
||||
* $Id: packet-ntp.c,v 1.40 2003/11/18 19:28:24 guy Exp $
|
||||
* $Id: packet-ntp.c,v 1.41 2004/05/13 20:20:34 gerald Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -359,7 +359,7 @@ static int dissect_ntp_ext(tvbuff_t *, proto_tree *, int);
|
|||
* buff - string buffer for result (OUT)
|
||||
* returns pointer to filled buffer.
|
||||
*/
|
||||
static char *
|
||||
char *
|
||||
ntp_fmt_ts(const guint8 *reftime, char* buff)
|
||||
{
|
||||
guint32 tempstmp, tempfrac;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* packet-ntp.h
|
||||
* Definitions for packet disassembly structures and routines
|
||||
*
|
||||
* $Id: packet-ntp.h,v 1.8 2002/08/28 21:00:24 jmayer Exp $
|
||||
* $Id: packet-ntp.h,v 1.9 2004/05/13 20:20:34 gerald Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -33,4 +33,6 @@
|
|||
#define NTP_BASETIME 2208988800ul
|
||||
#define NTP_TS_SIZE 100
|
||||
|
||||
extern char * ntp_fmt_ts(const guint8 *reftime, char* buff);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue