Andreas Sikkema's new H.261 and TPKT dissectors, replacement RTCP and
RTP dissectors, and changes to the Q.931 dissector for use with H.323. svn path=/trunk/; revision=2511
This commit is contained in:
parent
9de17c39f5
commit
3f8b7cd0fc
11
AUTHORS
11
AUTHORS
|
@ -124,7 +124,7 @@ Aaron Hillegass <aaron@classmax.com> {
|
|||
}
|
||||
|
||||
Jason Lango <jal@netapp.com> {
|
||||
RTSP, SDP, RTCP, RTP
|
||||
RTSP, SDP
|
||||
}
|
||||
|
||||
Johan Feyaerts <Johan.Feyaerts@siemens.atea.be> {
|
||||
|
@ -203,7 +203,7 @@ Heikki Vatiainen <hessu@cs.tut.fi> {
|
|||
VRRP (Virtual Router Redundancy)
|
||||
HSRP (Hot Standby Router Protocol)
|
||||
option to control whether to interpret the IPv4 TOS field as
|
||||
such or as the DiffServ field
|
||||
such or as the DiffServ field
|
||||
COPS
|
||||
}
|
||||
|
||||
|
@ -295,6 +295,7 @@ Doug Nazar <nazard@dragoninc.on.ca> {
|
|||
Andreas Sikkema <andreas.sikkema@philips.com> {
|
||||
Fixes to SMB dissector
|
||||
Fixes to capture file handling on Win32
|
||||
RTCP, RTP, TPKT (RFC 1006), H.261
|
||||
}
|
||||
|
||||
Mark Muhlestein <mmm@netapp.com> {
|
||||
|
@ -307,10 +308,10 @@ Graham Bloice <graham.bloice@trihedral.com> {
|
|||
Support for sorting columns in the summary by clicking on them
|
||||
Win32 Makefile improvements
|
||||
Support for "Update list of packets in real time" during capture
|
||||
on Win32
|
||||
on Win32
|
||||
Support for inverse video rather than boldface highlighting of
|
||||
the bytes, in the hex dump window, corresponding to a selected
|
||||
field
|
||||
the bytes, in the hex dump window, corresponding to a selected
|
||||
field
|
||||
}
|
||||
|
||||
Ralf Schneider <ralf.schneider@alcatel.se> {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Makefile.am
|
||||
# Automake file for Ethereal
|
||||
#
|
||||
# $Id: Makefile.am,v 1.235 2000/10/14 05:11:11 gram Exp $
|
||||
# $Id: Makefile.am,v 1.236 2000/10/19 06:45:10 guy Exp $
|
||||
#
|
||||
# Ethereal - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@zing.org>
|
||||
|
@ -63,6 +63,7 @@ DISSECTOR_SOURCES = \
|
|||
packet-giop.c \
|
||||
packet-gre.c \
|
||||
packet-h1.c \
|
||||
packet-h261.c \
|
||||
packet-hsrp.c \
|
||||
packet-http.c \
|
||||
packet-icmpv6.c\
|
||||
|
@ -151,6 +152,7 @@ DISSECTOR_SOURCES = \
|
|||
packet-tftp.c \
|
||||
packet-time.c \
|
||||
packet-tns.c \
|
||||
packet-tpkt.c \
|
||||
packet-tr.c \
|
||||
packet-trmac.c \
|
||||
packet-udp.c \
|
||||
|
@ -190,6 +192,7 @@ noinst_HEADERS = \
|
|||
packet-eth.h \
|
||||
packet-fddi.h \
|
||||
packet-frame.h \
|
||||
packet-h261.h \
|
||||
packet-http.h \
|
||||
packet-ip.h \
|
||||
packet-ipp.h \
|
||||
|
@ -239,6 +242,7 @@ noinst_HEADERS = \
|
|||
packet-tcp.h \
|
||||
packet-tftp.h \
|
||||
packet-tns.h \
|
||||
packet-tpkt.h \
|
||||
packet-tr.h \
|
||||
packet-trmac.h \
|
||||
packet-udp.h \
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## Makefile for building ethereal.exe with Microsoft C and nmake
|
||||
## Use: nmake -f makefile.nmake
|
||||
#
|
||||
# $Id: Makefile.nmake,v 1.58 2000/10/14 04:31:24 gram Exp $
|
||||
# $Id: Makefile.nmake,v 1.59 2000/10/19 06:45:10 guy Exp $
|
||||
|
||||
include config.nmake
|
||||
|
||||
|
@ -51,6 +51,7 @@ DISSECTOR_SOURCES = \
|
|||
packet-giop.c \
|
||||
packet-gre.c \
|
||||
packet-h1.c \
|
||||
packet-h261.c \
|
||||
packet-hsrp.c \
|
||||
packet-http.c \
|
||||
packet-icmpv6.c\
|
||||
|
@ -139,6 +140,7 @@ DISSECTOR_SOURCES = \
|
|||
packet-tftp.c \
|
||||
packet-time.c \
|
||||
packet-tns.c \
|
||||
packet-tpkt.c \
|
||||
packet-tr.c \
|
||||
packet-trmac.c \
|
||||
packet-udp.c \
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
/* packet-h261.c
|
||||
*
|
||||
* Routines for ITU-T Recommendation H.261 dissection
|
||||
*
|
||||
* Copyright 2000, Philips Electronics N.V.
|
||||
* Andreas Sikkema <andreas.sikkema@philips.com>
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This dissector tries to dissect the H261 protocol according to Annex C
|
||||
* of ITU-T Recommendation H.225.0 (02/98)
|
||||
*
|
||||
* This dissector is called by the RTP dissector
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include "packet.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "packet-h261.h"
|
||||
|
||||
/* H261 header fields */
|
||||
static int proto_h261 = -1;
|
||||
static int hf_h261_sbit = -1;
|
||||
static int hf_h261_ebit = -1;
|
||||
static int hf_h261_ibit = -1;
|
||||
static int hf_h261_vbit = -1;
|
||||
static int hf_h261_gobn = -1;
|
||||
static int hf_h261_mbap = -1;
|
||||
static int hf_h261_quant = -1;
|
||||
static int hf_h261_hmvd = -1; /* Mislabeled in a figure in section C.3.1 as HMDV */
|
||||
static int hf_h261_vmvd = -1;
|
||||
static int hf_h261_data = -1;
|
||||
|
||||
/* H261 fields defining a sub tree */
|
||||
static gint ett_h261 = -1;
|
||||
|
||||
void
|
||||
dissect_h261( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
|
||||
{
|
||||
proto_item *ti = NULL;
|
||||
proto_tree *h261_tree = NULL;
|
||||
unsigned int offset = 0;
|
||||
|
||||
if ( check_col( pinfo->fd, COL_PROTOCOL ) ) {
|
||||
col_add_str( pinfo->fd, COL_PROTOCOL, "H261" );
|
||||
}
|
||||
|
||||
if ( check_col( pinfo->fd, COL_INFO) ) {
|
||||
col_add_str( pinfo->fd, COL_INFO, "H.261 message");
|
||||
}
|
||||
|
||||
if ( tree ) {
|
||||
/* Using fd->pkt_len here instead of END_OF_FRAME. This variable is changed in dissect_rtp()! */
|
||||
ti = proto_tree_add_item( tree, proto_h261, tvb, offset, tvb_length( tvb ), FALSE );
|
||||
h261_tree = proto_item_add_subtree( ti, ett_h261 );
|
||||
/* SBIT 1st octet, 3 bits */
|
||||
proto_tree_add_uint( h261_tree, hf_h261_sbit, tvb, offset, 1, tvb_get_guint8( tvb, offset ) >> 5 );
|
||||
/* EBIT 1st octet, 3 bits */
|
||||
proto_tree_add_item( h261_tree, hf_h261_ebit, tvb, offset, 1, ( tvb_get_guint8( tvb, offset ) << 3 ) >> 5 );
|
||||
/* I flag, 1 bit */
|
||||
proto_tree_add_boolean( h261_tree, hf_h261_ibit, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 2 );
|
||||
/* V flag, 1 bit */
|
||||
proto_tree_add_boolean( h261_tree, hf_h261_vbit, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 1 );
|
||||
offset++;
|
||||
|
||||
/* GOBN 2nd octet, 4 bits */
|
||||
proto_tree_add_uint( h261_tree, hf_h261_gobn, tvb, offset, 1, tvb_get_guint8( tvb, offset ) >> 4 );
|
||||
/* MBAP 2nd octet, 4 bits, 3rd octet 1 bit */
|
||||
proto_tree_add_uint( h261_tree, hf_h261_mbap, tvb, offset, 1,
|
||||
( tvb_get_guint8( tvb, offset ) & 15 )
|
||||
+ ( tvb_get_guint8( tvb, offset + 1 ) >> 7 ) );
|
||||
offset++;
|
||||
|
||||
/* QUANT 3rd octet, 5 bits (starting at bit 2!) */
|
||||
proto_tree_add_uint( h261_tree, hf_h261_mbap, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 124 );
|
||||
/* HMDV 3rd octet 2 bits, 4th octet 3 bits */
|
||||
proto_tree_add_uint( h261_tree, hf_h261_mbap, tvb, offset, 1,
|
||||
( ( tvb_get_guint8( tvb, offset ) << 4) >> 4 )
|
||||
+ ( tvb_get_guint8( tvb, offset ) >> 5 ) );
|
||||
offset++;
|
||||
|
||||
/* VMVD 4th octet, last 5 bits */
|
||||
proto_tree_add_uint( h261_tree, hf_h261_mbap, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 31 );
|
||||
offset++;
|
||||
|
||||
/* The rest of the packet is the H.261 stream */
|
||||
proto_tree_add_bytes( h261_tree, hf_h261_data, tvb, offset, tvb_length_remaining( tvb, offset ), tvb_get_ptr( tvb, offset, tvb_length_remaining( tvb, offset ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
proto_register_h261(void)
|
||||
{
|
||||
static hf_register_info hf[] =
|
||||
{
|
||||
{
|
||||
&hf_h261_sbit,
|
||||
{
|
||||
"Start bit position",
|
||||
"h261.sbit",
|
||||
FT_UINT8,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_h261_ebit,
|
||||
{
|
||||
"End bit position",
|
||||
"h261.ebit",
|
||||
FT_UINT8,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_h261_ibit,
|
||||
{
|
||||
"Intra frame encoded data flag",
|
||||
"h261.i",
|
||||
FT_BOOLEAN,
|
||||
BASE_NONE,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_h261_vbit,
|
||||
{
|
||||
"Motion vector flag",
|
||||
"h261.v",
|
||||
FT_BOOLEAN,
|
||||
BASE_NONE,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_h261_gobn,
|
||||
{
|
||||
"GOB Number",
|
||||
"h261.gobn",
|
||||
FT_UINT8,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_h261_mbap,
|
||||
{
|
||||
"Macroblock address predictor",
|
||||
"h261.mbap",
|
||||
FT_UINT8,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_h261_quant,
|
||||
{
|
||||
"Quantizer",
|
||||
"h261.quant",
|
||||
FT_UINT8,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_h261_hmvd,
|
||||
{
|
||||
"Horizontal motion vctor data",
|
||||
"h261.hmvd",
|
||||
FT_UINT8,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_h261_vmvd,
|
||||
{
|
||||
"Vertical motion vector data",
|
||||
"h261.vmvd",
|
||||
FT_UINT8,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_h261_data,
|
||||
{
|
||||
"H.261 stream",
|
||||
"h261.stream",
|
||||
FT_BYTES,
|
||||
BASE_NONE,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static gint *ett[] =
|
||||
{
|
||||
&ett_h261,
|
||||
};
|
||||
|
||||
|
||||
proto_h261 = proto_register_protocol("ITU-T Recommendation H.261", "h261");
|
||||
proto_register_field_array(proto_h261, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/* packet-h261.h
|
||||
*
|
||||
* Routines for ITU-T Recommendation H.261 dissection
|
||||
*
|
||||
* Copyright 2000, Philips Electronics N.V.
|
||||
* Andreas Sikkema <andreas.sikkema@philips.com>
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
void dissect_h261( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree );
|
||||
void proto_register_h261( void );
|
369
packet-q931.c
369
packet-q931.c
|
@ -2,7 +2,9 @@
|
|||
* Routines for Q.931 frame disassembly
|
||||
* Guy Harris <guy@alum.mit.edu>
|
||||
*
|
||||
* $Id: packet-q931.c,v 1.17 2000/08/13 14:08:38 deniel Exp $
|
||||
* $Id: packet-q931.c,v 1.18 2000/10/19 06:45:10 guy Exp $
|
||||
*
|
||||
* Modified by Andreas Sikkema for possible use with H.323
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -39,6 +41,11 @@
|
|||
#include "nlpid.h"
|
||||
#include "packet-q931.h"
|
||||
|
||||
#ifdef H323
|
||||
#include "packet-tpkt.h"
|
||||
#include "packet-h225.h"
|
||||
#endif
|
||||
|
||||
/* Q.931 references:
|
||||
*
|
||||
* http://www.acacia-net.com/Clarinet/Protocol/q9313svn.htm
|
||||
|
@ -63,6 +70,7 @@ static gint ett_q931_ie = -1;
|
|||
/*
|
||||
* Q.931 message types.
|
||||
*/
|
||||
#define Q931_ESCAPE 0x00
|
||||
#define Q931_ALERTING 0x01
|
||||
#define Q931_CALL_PROCEEDING 0x02
|
||||
#define Q931_CONNECT 0x07
|
||||
|
@ -98,6 +106,7 @@ static gint ett_q931_ie = -1;
|
|||
#define Q931_STATUS_ENQUIRY 0x75
|
||||
|
||||
static const value_string q931_message_type_vals[] = {
|
||||
{ Q931_ESCAPE, "ESCAPE" },
|
||||
{ Q931_ALERTING, "ALERTING" },
|
||||
{ Q931_CALL_PROCEEDING, "CALL PROCEEDING" },
|
||||
{ Q931_CONNECT, "CONNECT" },
|
||||
|
@ -506,6 +515,46 @@ static const value_string q931_uil3_vals[] = {
|
|||
{ 0, NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX - should this (or, rather, a routine to return a string containing
|
||||
* the stuff we put after "Protocol discriminator:") be in "packet-osi.c"?
|
||||
*
|
||||
* I.e., is the convention that 16-63 and 80-254 are for network-layer
|
||||
* or layer-3 protocols, and 64-79 are for national use, specific to
|
||||
* Q.931 (and maybe Q.2931), or is it a more general ISO standard?
|
||||
*/
|
||||
static void
|
||||
dissect_q931_protocol_discriminator(tvbuff_t *tvb, int offset, proto_tree *tree)
|
||||
{
|
||||
unsigned int discriminator = tvb_get_guint8(tvb, offset);
|
||||
char *nlpid_string;
|
||||
|
||||
nlpid_string = match_strval(discriminator, nlpid_vals);
|
||||
if (nlpid_string != NULL) {
|
||||
proto_tree_add_uint_format(tree, hf_q931_discriminator,
|
||||
tvb, offset, 1, discriminator,
|
||||
"Protocol discriminator: %s", nlpid_string);
|
||||
} else {
|
||||
if ((discriminator >= 16 && discriminator < 63)
|
||||
|| ((discriminator >= 80) && (discriminator < 254))) {
|
||||
proto_tree_add_uint_format(tree, hf_q931_discriminator,
|
||||
tvb, offset, 1, discriminator,
|
||||
"Protocol discriminator: Network layer or layer 3 protocol (0x%02X)",
|
||||
discriminator);
|
||||
} else if (discriminator >= 64 && discriminator <= 79) {
|
||||
proto_tree_add_uint_format(tree, hf_q931_discriminator,
|
||||
tvb, offset, 1, discriminator,
|
||||
"Protocol discriminator: National use (0x%02X)",
|
||||
discriminator);
|
||||
} else {
|
||||
proto_tree_add_uint_format(tree, hf_q931_discriminator,
|
||||
tvb, offset, 1, discriminator,
|
||||
"Protocol discriminator: Reserved (0x%02X)",
|
||||
discriminator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dissect_q931_bearer_capability_ie(tvbuff_t *tvb, int offset, int len,
|
||||
proto_tree *tree)
|
||||
|
@ -699,7 +748,7 @@ dissect_q931_bearer_capability_ie(tvbuff_t *tvb, int offset, int len,
|
|||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"Modem type: %s",
|
||||
val_to_str(modem_type, q931_l1_modem_type_vals,
|
||||
NULL));
|
||||
"Unknown (0x%02X)"));
|
||||
}
|
||||
offset += 1;
|
||||
len -= 1;
|
||||
|
@ -1004,7 +1053,7 @@ dissect_q931_cause_ie(tvbuff_t *tvb, int offset, int len,
|
|||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"Recommendation: %s",
|
||||
val_to_str(octet & 0x7F, q931_cause_recommendation_vals,
|
||||
"Unknown (0x%X)"));
|
||||
"Unknown (0x%02X)"));
|
||||
offset += 1;
|
||||
len -= 1;
|
||||
}
|
||||
|
@ -1015,7 +1064,7 @@ dissect_q931_cause_ie(tvbuff_t *tvb, int offset, int len,
|
|||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"Cause value: %s",
|
||||
val_to_str(octet & 0x7F, q931_cause_code_vals,
|
||||
"Unknown (0x%X)"));
|
||||
"Unknown (0x%02X)"));
|
||||
offset += 1;
|
||||
len -= 1;
|
||||
|
||||
|
@ -1148,7 +1197,7 @@ dissect_q931_channel_identification_ie(tvbuff_t *tvb, int offset, int len,
|
|||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"Channel selection: %s",
|
||||
val_to_str(octet & 0x03, q931_not_basic_channel_selection_vals,
|
||||
NULL));
|
||||
"Unknown (0x%X)"));
|
||||
} else {
|
||||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"Channel selection: %s",
|
||||
|
@ -1210,7 +1259,7 @@ dissect_q931_channel_identification_ie(tvbuff_t *tvb, int offset, int len,
|
|||
"%s type: %s",
|
||||
(octet & Q931_IS_SLOT_MAP) ? "Map element" : "Channel",
|
||||
val_to_str(octet & 0x0F, q931_element_type_vals,
|
||||
"Unknown (0x%02X)"));
|
||||
"Unknown (0x%02X)"));
|
||||
|
||||
/*
|
||||
* XXX - dump the channel number or slot map.
|
||||
|
@ -1327,9 +1376,8 @@ dissect_q931_ns_facilities_ie(tvbuff_t *tvb, int offset, int len,
|
|||
netid_len = len;
|
||||
if (netid_len != 0) {
|
||||
proto_tree_add_text(tree, tvb, offset, netid_len,
|
||||
"Network identification: %.*s",
|
||||
netid_len,
|
||||
tvb_get_ptr(tvb, offset, netid_len));
|
||||
"Network identification: %s",
|
||||
tvb_format_text(tvb, offset, netid_len));
|
||||
offset += netid_len;
|
||||
len -= netid_len;
|
||||
}
|
||||
|
@ -1431,7 +1479,8 @@ dissect_q931_signal_ie(tvbuff_t *tvb, int offset, int len,
|
|||
}
|
||||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"Signal: %s",
|
||||
val_to_str(tvb_get_guint8(tvb, offset), q931_signal_vals, "Unknown (0x%02X)"));
|
||||
val_to_str(tvb_get_guint8(tvb, offset), q931_signal_vals,
|
||||
"Unknown (0x%02X)"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1463,20 +1512,20 @@ dissect_q931_information_rate_ie(tvbuff_t *tvb, int offset, int len,
|
|||
}
|
||||
proto_tree_add_text(tree, tvb, offset + 0, 1,
|
||||
"Incoming information rate: %s",
|
||||
val_to_str(tvb_get_guint8(tvb, offset + 0) & 0x1F, q931_throughput_class_vals,
|
||||
"Unknown (0x%02X)"));
|
||||
val_to_str(tvb_get_guint8(tvb, offset + 0) & 0x1F,
|
||||
q931_throughput_class_vals, "Unknown (0x%02X)"));
|
||||
proto_tree_add_text(tree, tvb, offset + 1, 1,
|
||||
"Outgoing information rate: %s",
|
||||
val_to_str(tvb_get_guint8(tvb, offset + 1) & 0x1F, q931_throughput_class_vals,
|
||||
"Unknown (0x%02X)"));
|
||||
val_to_str(tvb_get_guint8(tvb, offset + 1) & 0x1F,
|
||||
q931_throughput_class_vals, "Unknown (0x%02X)"));
|
||||
proto_tree_add_text(tree, tvb, offset + 2, 1,
|
||||
"Minimum incoming information rate: %s",
|
||||
val_to_str(tvb_get_guint8(tvb, offset + 2) & 0x1F, q931_throughput_class_vals,
|
||||
"Unknown (0x%02X)"));
|
||||
val_to_str(tvb_get_guint8(tvb, offset + 2) & 0x1F,
|
||||
q931_throughput_class_vals, "Unknown (0x%02X)"));
|
||||
proto_tree_add_text(tree, tvb, offset + 3, 1,
|
||||
"Minimum outgoing information rate: %s",
|
||||
val_to_str(tvb_get_guint8(tvb, offset + 3) & 0x1F, q931_throughput_class_vals,
|
||||
"Unknown (0x%02X)"));
|
||||
val_to_str(tvb_get_guint8(tvb, offset + 3) & 0x1F,
|
||||
q931_throughput_class_vals, "Unknown (0x%02X)"));
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1620,8 +1669,7 @@ dissect_q931_pl_binary_parameters_ie(tvbuff_t *tvb, int offset, int len,
|
|||
octet = tvb_get_guint8(tvb, offset);
|
||||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"Fast select: %s",
|
||||
val_to_str(octet & 0x18, q931_fast_selected_vals,
|
||||
NULL));
|
||||
val_to_str(octet & 0x18, q931_fast_selected_vals, NULL));
|
||||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"%s",
|
||||
(octet & 0x04) ? "No request/request denied" :
|
||||
|
@ -1690,15 +1738,15 @@ dissect_q931_cug_ie(tvbuff_t *tvb, int offset, int len, proto_tree *tree)
|
|||
return;
|
||||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"CUG indication: %s",
|
||||
val_to_str(tvb_get_guint8(tvb, offset) & 0x07, q931_cug_indication_vals,
|
||||
"Unknown (0x%02X)"));
|
||||
val_to_str(tvb_get_guint8(tvb, offset) & 0x07,
|
||||
q931_cug_indication_vals, "Unknown (0x%02X)"));
|
||||
offset += 1;
|
||||
len -= 1;
|
||||
|
||||
if (len == 0)
|
||||
return;
|
||||
proto_tree_add_text(tree, tvb, offset, len, "CUG index code: %.*s", len,
|
||||
tvb_get_ptr(tvb, offset, len));
|
||||
proto_tree_add_text(tree, tvb, offset, len, "CUG index code: %s",
|
||||
tvb_format_text(tvb, offset, len));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1717,8 +1765,8 @@ dissect_q931_reverse_charge_ind_ie(tvbuff_t *tvb, int offset, int len,
|
|||
return;
|
||||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"Reverse charging indication: %s",
|
||||
val_to_str(tvb_get_guint8(tvb, offset) & 0x07, q931_reverse_charging_indication_vals,
|
||||
"Unknown (0x%02X)"));
|
||||
val_to_str(tvb_get_guint8(tvb, offset) & 0x07,
|
||||
q931_reverse_charging_indication_vals, "Unknown (0x%02X)"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1823,8 +1871,8 @@ dissect_q931_number_ie(tvbuff_t *tvb, int offset, int len,
|
|||
|
||||
if (len == 0)
|
||||
return;
|
||||
proto_tree_add_text(tree, tvb, offset, len, "Number: %.*s",
|
||||
len, tvb_get_ptr(tvb, offset, len));
|
||||
proto_tree_add_text(tree, tvb, offset, len, "Number: %s",
|
||||
tvb_format_text(tvb, offset, len));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1889,8 +1937,8 @@ dissect_q931_restart_indicator_ie(tvbuff_t *tvb, int offset, int len,
|
|||
}
|
||||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"Restart indicator: %s",
|
||||
val_to_str(tvb_get_guint8(tvb, offset) & 0x07, q931_restart_indicator_class_vals,
|
||||
"Unknown (0x%02X)"));
|
||||
val_to_str(tvb_get_guint8(tvb, offset) & 0x07,
|
||||
q931_restart_indicator_class_vals, "Unknown (0x%02X)"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1958,7 +2006,7 @@ dissect_q931_high_layer_compat_ie(tvbuff_t *tvb, int offset, int len,
|
|||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"High layer characteristics identification: %s",
|
||||
val_to_str(characteristics, q931_high_layer_characteristics_vals,
|
||||
NULL));
|
||||
"Unknown (0x%02X)"));
|
||||
offset += 1;
|
||||
len -= 1;
|
||||
|
||||
|
@ -1969,13 +2017,15 @@ dissect_q931_high_layer_compat_ie(tvbuff_t *tvb, int offset, int len,
|
|||
if (characteristics == Q931_AUDIOVISUAL) {
|
||||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"Extended audiovisual characteristics identification: %s",
|
||||
val_to_str(octet & 0x7F, q931_audiovisual_characteristics_vals,
|
||||
NULL));
|
||||
val_to_str(octet & 0x7F,
|
||||
q931_audiovisual_characteristics_vals,
|
||||
"Unknown (0x%02X)"));
|
||||
} else {
|
||||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
"Extended high layer characteristics identification: %s",
|
||||
val_to_str(octet & 0x7F, q931_high_layer_characteristics_vals,
|
||||
NULL));
|
||||
val_to_str(octet & 0x7F,
|
||||
q931_high_layer_characteristics_vals,
|
||||
"Unknown (0x%02X)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2018,8 +2068,8 @@ dissect_q931_user_user_ie(tvbuff_t *tvb, int offset, int len,
|
|||
switch (octet) {
|
||||
|
||||
case Q931_PROTOCOL_DISCRIMINATOR_IA5:
|
||||
proto_tree_add_text(tree, tvb, offset, len, "User information: %.*s",
|
||||
len, tvb_get_ptr(tvb, offset, len));
|
||||
proto_tree_add_text(tree, tvb, offset, len, "User information: %s",
|
||||
tvb_format_text(tvb, offset, len));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -2037,8 +2087,8 @@ dissect_q931_ia5_ie(tvbuff_t *tvb, int offset, int len, proto_tree *tree,
|
|||
char *label)
|
||||
{
|
||||
if (len != 0) {
|
||||
proto_tree_add_text(tree, tvb, offset, len, "%s: %.*s", label, len,
|
||||
tvb_get_ptr(tvb, offset, len));
|
||||
proto_tree_add_text(tree, tvb, offset, len, "%s: %s", label,
|
||||
tvb_format_text(tvb, offset, len));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2051,8 +2101,9 @@ static const value_string q931_codeset_vals[] = {
|
|||
{ 0x00, NULL },
|
||||
};
|
||||
|
||||
void
|
||||
dissect_q931(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
static gboolean
|
||||
q931_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
gboolean started_heuristic)
|
||||
{
|
||||
int offset = 0;
|
||||
guint reported_length;
|
||||
|
@ -2063,13 +2114,107 @@ dissect_q931(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
guint8 call_ref[15];
|
||||
guint8 message_type;
|
||||
guint8 info_element;
|
||||
guint8 info_element_len;
|
||||
int codeset;
|
||||
guint16 info_element_len;
|
||||
int codeset;
|
||||
gboolean non_locking_shift;
|
||||
guint8 protocol_discriminator;
|
||||
|
||||
CHECK_DISPLAY_AS_DATA(proto_q931, tvb, pinfo, tree);
|
||||
#ifdef H323
|
||||
tvbuff_t *h225_tvb;
|
||||
gboolean is_h323_h225 = FALSE;
|
||||
/*
|
||||
* It is very much possible to find a TPKT header here
|
||||
* TPKT is defined in RFC 1009 as a wrapper around ISO
|
||||
* defined protocols. There could even be several TPKT
|
||||
* wrapped messages in one TCP data field...
|
||||
* XXXXXXXX THIS IS NOT IMPLEMENTED YET!!! XXXXXXXXXXX
|
||||
*
|
||||
* For Q.931 related messages this is easy. If a
|
||||
* protocol discriminator is found with a value of 3
|
||||
* and it's the first discriminator in the Q.931
|
||||
* message one can safely assume it to be a TPKT
|
||||
* header. See also Q.931 Table 4-1/Q.931
|
||||
*/
|
||||
#endif
|
||||
|
||||
pinfo->current_proto = "Q.931";
|
||||
protocol_discriminator = tvb_get_guint8( tvb, offset );
|
||||
/* Keep the protocol discriminator for later use */
|
||||
|
||||
#ifdef H323
|
||||
if ( started_heuristic ) {
|
||||
/*
|
||||
* The heuristic Q.931 message should conform to this
|
||||
*/
|
||||
if ( protocol_discriminator != NLPID_Q_931 )
|
||||
return FALSE;
|
||||
|
||||
if ( ! is_tpkt( tvb, &offset ) )
|
||||
return FALSE;
|
||||
|
||||
if ( tvb_length_remaining( tvb, offset ) <= 3 )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* The first byte should be < 8 (3 is TPKT, rest is Q.931)
|
||||
*/
|
||||
if ( protocol_discriminator < 8 ) {
|
||||
/*
|
||||
* The minimum length of a Q.931 message is 3:
|
||||
* 1 byte for the protocol discriminator,
|
||||
* 1 for the call_reference length,
|
||||
* and one for the message type.
|
||||
*/
|
||||
if ( tvb_length_remaining( tvb, offset ) <= 3 )
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* OK, there are a couple of bytes available, but is there
|
||||
* also a protocol discriminator?
|
||||
*/
|
||||
if ( tvb_length_remaining( tvb, offset ) > 3 ) {
|
||||
/* Reread the protocol discriminator */
|
||||
protocol_discriminator =
|
||||
tvb_get_guint8( tvb, offset + 4);
|
||||
} else {
|
||||
/* No discriminator available */
|
||||
protocol_discriminator = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it's not H.323 related Q.931 no heuristic action needed
|
||||
* Dangerous, there might be other uses for this code.....
|
||||
*/
|
||||
if ( ( started_heuristic ) && (protocol_discriminator != 8 ) )
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Always check if it's a real TPKT message
|
||||
*/
|
||||
if ( ! is_tpkt( tvb, &offset ) )
|
||||
return FALSE;
|
||||
|
||||
dissect_tpkt( tvb, &offset, pinfo, tree );
|
||||
|
||||
/*
|
||||
* Reset the current_proto variable because dissect_tpkt
|
||||
* messed with it
|
||||
*/
|
||||
if ( started_heuristic )
|
||||
pinfo->current_proto = "Q.931 HEUR";
|
||||
else
|
||||
pinfo->current_proto = "Q.931";
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The minimum length of a Q.931 message is
|
||||
* 3, 1 byte for the protocol discr. 1 for the call_reference length,
|
||||
* and one for the message type.
|
||||
*/
|
||||
if ( tvb_length_remaining( tvb, offset ) <= 3 ) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (check_col(pinfo->fd, COL_PROTOCOL))
|
||||
col_add_str(pinfo->fd, COL_PROTOCOL, "Q.931");
|
||||
|
@ -2079,7 +2224,7 @@ dissect_q931(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
tvb_length(tvb), FALSE);
|
||||
q931_tree = proto_item_add_subtree(ti, ett_q931);
|
||||
|
||||
proto_tree_add_uint(q931_tree, hf_q931_discriminator, tvb, offset, 1, tvb_get_guint8(tvb, offset));
|
||||
dissect_q931_protocol_discriminator( tvb, offset, q931_tree );
|
||||
}
|
||||
offset += 1;
|
||||
call_ref_len = tvb_get_guint8(tvb, offset) & 0xF; /* XXX - do as a bit field? */
|
||||
|
@ -2195,20 +2340,72 @@ dissect_q931(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
/*
|
||||
* Variable-length IE.
|
||||
*/
|
||||
#ifndef H323
|
||||
info_element_len = tvb_get_guint8(tvb, offset + 1);
|
||||
if (q931_tree != NULL) {
|
||||
ti = proto_tree_add_text(q931_tree, tvb, offset,
|
||||
1+1+info_element_len, "%s",
|
||||
val_to_str(info_element, q931_info_element_vals,
|
||||
"Unknown information element (0x%02X)"));
|
||||
ie_tree = proto_item_add_subtree(ti, ett_q931_ie);
|
||||
proto_tree_add_text(ie_tree, tvb, offset, 1,
|
||||
"Information element: %s",
|
||||
val_to_str(info_element, q931_info_element_vals,
|
||||
"Unknown (0x%02X)"));
|
||||
proto_tree_add_text(ie_tree, tvb, offset + 1, 1,
|
||||
"Length: %u", info_element_len);
|
||||
#else
|
||||
/*
|
||||
* According to page 18 from Recommendation H.225.0 :
|
||||
* " Length of user-user contents contents
|
||||
* - Shall be 2 octets instead of 1 (as in Figure 4-36/Q.931)"
|
||||
*
|
||||
* This will be true for all messages going to / from TCP port
|
||||
* 1720 and with the first and fourth octet of the user-user
|
||||
* IE having the values 0x7E and 0x05 resp.
|
||||
* See http://www.mbuf.org/~moto/h323/h323decoder.html
|
||||
*
|
||||
*/
|
||||
|
||||
if ( ( tvb_get_guint8( tvb, offset ) == 0x7E ) &&
|
||||
( tvb_get_guint8( tvb, offset + 3 ) == 0x05 ) &&
|
||||
/* ( ( pi.srcport == 1720 ) || ( pi.destport == 1720 ) ) && */
|
||||
( protocol_discriminator == NLPID_Q_931 ) ) {
|
||||
info_element_len = tvb_get_ntohs( tvb, offset + 1 );
|
||||
is_h323_h225 = TRUE;
|
||||
if ( tree == NULL ) {
|
||||
h225_tvb = tvb_new_subset( tvb, offset + 4, info_element_len - 1, info_element_len - 1 );
|
||||
dissect_h225_cs( h225_tvb, pinfo, tree );
|
||||
/*
|
||||
* Skip the 4 bytes of the element header and then the element itself
|
||||
*/
|
||||
offset += 4;
|
||||
offset += info_element_len - 1;
|
||||
}
|
||||
} else {
|
||||
info_element_len = tvb_get_guint8( tvb, offset + 1 );
|
||||
}
|
||||
#endif
|
||||
if (q931_tree != NULL) {
|
||||
#ifdef H323
|
||||
if (is_h323_h225) {
|
||||
ti = proto_tree_add_text(q931_tree, tvb, offset,
|
||||
1+1+1, "%s",
|
||||
val_to_str(info_element,
|
||||
q931_info_element_vals,
|
||||
"Unknown information element (0x%02X)"));
|
||||
ie_tree = proto_item_add_subtree(ti,
|
||||
ett_q931_ie);
|
||||
proto_tree_add_text(ie_tree, tvb, offset, 1,
|
||||
"Information element: %s",
|
||||
val_to_str(info_element,
|
||||
q931_info_element_vals, "Unknown (0x%02X)"));
|
||||
proto_tree_add_text(ie_tree, tvb, offset + 1,
|
||||
2, "Length: %u", info_element_len);
|
||||
} else {
|
||||
#endif
|
||||
ti = proto_tree_add_text(q931_tree, tvb, offset,
|
||||
1+1+info_element_len, "%s",
|
||||
val_to_str(info_element, q931_info_element_vals,
|
||||
"Unknown information element (0x%02X)"));
|
||||
ie_tree = proto_item_add_subtree(ti, ett_q931_ie);
|
||||
proto_tree_add_text(ie_tree, tvb, offset, 1,
|
||||
"Information element: %s",
|
||||
val_to_str(info_element, q931_info_element_vals,
|
||||
"Unknown (0x%02X)"));
|
||||
proto_tree_add_text(ie_tree, tvb, offset + 1, 1,
|
||||
"Length: %u", info_element_len);
|
||||
#ifdef H323
|
||||
}
|
||||
#endif
|
||||
switch (info_element) {
|
||||
|
||||
case Q931_IE_SEGMENTED_MESSAGE:
|
||||
|
@ -2339,8 +2536,28 @@ dissect_q931(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
break;
|
||||
|
||||
case Q931_IE_USER_USER:
|
||||
dissect_q931_user_user_ie(tvb,
|
||||
offset + 2, info_element_len, ie_tree);
|
||||
#ifdef H323
|
||||
if (is_h323_h225) {
|
||||
h225_tvb = tvb_new_subset(tvb,
|
||||
offset + 4, info_element_len - 1,
|
||||
info_element_len - 1);
|
||||
dissect_h225_cs(h225_tvb, pinfo, tree);
|
||||
offset += 3;
|
||||
proto_tree_add_text(ie_tree, tvb,
|
||||
offset, 1,
|
||||
"Protocol discriminator: %s",
|
||||
val_to_str(tvb_get_guint8(tvb, offset),
|
||||
q931_protocol_discriminator_vals,
|
||||
"Unknown (0x%02x)"));
|
||||
offset += info_element_len;
|
||||
} else {
|
||||
#endif
|
||||
dissect_q931_user_user_ie(tvb,
|
||||
offset + 2, info_element_len,
|
||||
ie_tree);
|
||||
#ifdef H323
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -2356,6 +2573,29 @@ dissect_q931(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
if (non_locking_shift)
|
||||
codeset = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Heuristic should return TRUE if it get's here.
|
||||
*/
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
#ifdef H323
|
||||
gboolean
|
||||
dissect_q931_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
pinfo->current_proto = "Q.931 HEUR";
|
||||
return q931_dissector(tvb, pinfo, tree, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
dissect_q931(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
pinfo->current_proto = "Q.931";
|
||||
q931_dissector(tvb, pinfo, tree, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2387,4 +2627,13 @@ proto_register_q931(void)
|
|||
proto_q931 = proto_register_protocol ("Q.931", "q931");
|
||||
proto_register_field_array (proto_q931, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
proto_reg_handoff_q931(void)
|
||||
{
|
||||
#ifdef H323
|
||||
heur_dissector_add("tcp", dissect_q931_heur);
|
||||
#endif
|
||||
}
|
||||
|
|
1509
packet-rtcp.c
1509
packet-rtcp.c
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +1,10 @@
|
|||
/* packet-rtcp.h
|
||||
* Declarations for RTCP packet disassembly
|
||||
*
|
||||
* Jason Lango <jal@netapp.com>
|
||||
*
|
||||
* $Id: packet-rtcp.h,v 1.2 2000/08/11 13:34:01 deniel Exp $
|
||||
* Routines for RTCP dissection
|
||||
* RTCP = Real-time Transport Control Protocol
|
||||
*
|
||||
* Copyright 2000, Philips Electronics N.V.
|
||||
* Written by Andreas Sikkema <andreas.sikkema@philips.com>
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -25,9 +26,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PACKET_RTCP_H__
|
||||
#define __PACKET_RTCP_H__
|
||||
|
||||
void dissect_rtcp(const u_char *, int, frame_data *, proto_tree *);
|
||||
|
||||
#endif
|
||||
void rtcp_add_address ( const unsigned char* ip_addr, int prt );
|
||||
gboolean dissect_rtcp_heur ( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree );
|
||||
void dissect_rtcp ( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree );
|
||||
void proto_register_rtcp( void );
|
||||
|
|
718
packet-rtp.c
718
packet-rtp.c
|
@ -1,9 +1,10 @@
|
|||
/* packet-rtp.c
|
||||
* Routines for RTP packet disassembly
|
||||
*
|
||||
* Jason Lango <jal@netapp.com>
|
||||
*
|
||||
* $Id: packet-rtp.c,v 1.5 2000/08/13 14:08:43 deniel Exp $
|
||||
* Routines for RTP dissection
|
||||
* RTP = Real time Transport Protocol
|
||||
*
|
||||
* Copyright 2000, Philips Electronics N.V.
|
||||
* Written by Andreas Sikkema <andreas.sikkema@philips.com>
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -23,195 +24,596 @@
|
|||
* 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
/*
|
||||
* This dissector tries to dissect the RTP protocol according to Annex A
|
||||
* of ITU-T Recommendation H.225.0 (02/98) or RFC 1889
|
||||
*
|
||||
* RTP traffic is handled by an even UDP portnumber. This can be any
|
||||
* port number, but there is a registered port available, port 5004
|
||||
* See Annex B of ITU-T Recommendation H.225.0, section B.7
|
||||
*/
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include "packet.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "packet-rtp.h"
|
||||
#include "packet-h261.h"
|
||||
#include "conversation.h"
|
||||
|
||||
static int proto_rtp = -1;
|
||||
/* RTP header fields */
|
||||
static int proto_rtp = -1;
|
||||
static int hf_rtp_version = -1;
|
||||
static int hf_rtp_padding = -1;
|
||||
static int hf_rtp_extension = -1;
|
||||
static int hf_rtp_csrc_count = -1;
|
||||
static int hf_rtp_marker = -1;
|
||||
static int hf_rtp_payload_type = -1;
|
||||
static int hf_rtp_seq_nr = -1;
|
||||
static int hf_rtp_timestamp = -1;
|
||||
static int hf_rtp_ssrc = -1;
|
||||
static int hf_rtp_csrc_item = -1;
|
||||
static int hf_rtp_data = -1;
|
||||
static int hf_rtp_padding_data = -1;
|
||||
static int hf_rtp_padding_count= -1;
|
||||
|
||||
static gint ett_rtp = -1;
|
||||
/* RTP header extension fields */
|
||||
static int hf_rtp_prof_define = -1;
|
||||
static int hf_rtp_length = -1;
|
||||
static int hf_rtp_hdr_ext = -1;
|
||||
|
||||
#define _RTP_FLAG_BITS(hdr, s, n) \
|
||||
((u_int)(((hdr)->rtp_flag_bits >> (8 - (s) - (n))) & ((1 << (n)) - 1)))
|
||||
#define RTP_VERSION(hdr) _RTP_FLAG_BITS(hdr, 0, 2)
|
||||
#define RTP_PADDING(hdr) _RTP_FLAG_BITS(hdr, 2, 1)
|
||||
#define RTP_EXTENSION(hdr) _RTP_FLAG_BITS(hdr, 3, 1)
|
||||
#define RTP_CSRC_COUNT(hdr) _RTP_FLAG_BITS(hdr, 4, 4)
|
||||
/* RTP fields defining a sub tree */
|
||||
static gint ett_rtp = -1;
|
||||
static gint ett_csrc_list = -1;
|
||||
static gint ett_hdr_ext = -1;
|
||||
|
||||
#define RTP_MARKER(hdr) ((u_int)((hdr)->rtp_type_bits >> 7))
|
||||
#define RTP_PAYLOAD_TYPE(hdr) ((u_int)((hdr)->rtp_type_bits & 0x7F))
|
||||
/*
|
||||
* Fields in the first octet of the RTP header.
|
||||
*/
|
||||
|
||||
typedef struct rtp_hdr {
|
||||
guint8 rtp_flag_bits;
|
||||
guint8 rtp_type_bits;
|
||||
guint16 rtp_seq;
|
||||
guint32 rtp_timestamp;
|
||||
guint32 rtp_ssrc;
|
||||
} rtp_hdr_t;
|
||||
/* Version is the first 2 bits of the first octet*/
|
||||
#define RTP_VERSION(octet) ((octet) >> 6)
|
||||
|
||||
typedef struct rtp_hdr_ext {
|
||||
guint16 rtp_ext_app; /* defined by RTP profile */
|
||||
guint16 rtp_ext_length; /* length of extension data in 32 bit words */
|
||||
} rtp_hdr_ext_t;
|
||||
/* Padding is the third bit; No need to shift, because true is any value
|
||||
other than 0! */
|
||||
#define RTP_PADDING(octet) ((octet) & 0x20)
|
||||
|
||||
/* Extension bit is the fourth bit */
|
||||
#define RTP_EXTENSION(octet) ((octet) & 0x10)
|
||||
|
||||
/* CSRC count is the last four bits */
|
||||
#define RTP_CSRC_COUNT(octet) ((octet) & 0xF)
|
||||
|
||||
static const value_string rtp_version_vals[] =
|
||||
{
|
||||
{ 0, "Old VAT Version" },
|
||||
{ 1, "First Draft Version" },
|
||||
{ 2, "RFC 1889 Version" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
* Fields in the second octet of the RTP header.
|
||||
*/
|
||||
|
||||
/* Marker is the first bit of the second octet */
|
||||
#define RTP_MARKER(octet) ((octet) & 0x80)
|
||||
|
||||
/* Payload type is the last 7 bits */
|
||||
#define RTP_PAYLOAD_TYPE(octet) ((octet) & 0x7F)
|
||||
|
||||
/*
|
||||
* RTP Payload types
|
||||
* Table B.2 / H.225.0
|
||||
*/
|
||||
#define PT_PCMU 0
|
||||
#define PT_PCMA 8
|
||||
#define PT_G722 9
|
||||
#define PT_G723 4
|
||||
#define PT_G728 15
|
||||
#define PT_G729 18
|
||||
#define PT_H261 31
|
||||
#define PT_H263 34
|
||||
|
||||
static const value_string rtp_payload_type_vals[] =
|
||||
{
|
||||
{ PT_PCMU, "ITU-T G.711 PCMU" },
|
||||
{ PT_PCMA, "ITU-T G.711 PCMA" },
|
||||
{ PT_G722, "ITU-T G.722" },
|
||||
{ PT_G723, "ITU-T G.723" },
|
||||
{ PT_G728, "ITU-T G.728" },
|
||||
{ PT_G729, "ITU-T G.729" },
|
||||
{ PT_H261, "ITU-T H.261" },
|
||||
{ PT_H263, "ITU-T H.263" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
static address fake_addr;
|
||||
static int heur_init = FALSE;
|
||||
|
||||
static const char rtp_proto[] = "RTP";
|
||||
|
||||
void rtp_add_address( const unsigned char* ip_addr, int prt )
|
||||
{
|
||||
address src_addr;
|
||||
conversation_t* pconv = ( conversation_t* ) NULL;
|
||||
|
||||
src_addr.type = AT_IPv4;
|
||||
src_addr.len = 4;
|
||||
src_addr.data = ip_addr;
|
||||
|
||||
/*
|
||||
* The first time the function is called let the tcp dissector
|
||||
* know that we're interested in traffic
|
||||
*/
|
||||
if ( ! heur_init ) {
|
||||
heur_dissector_add( "udp", dissect_rtp_heur );
|
||||
heur_init = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the ip address an dport combination is not
|
||||
* already registered
|
||||
*/
|
||||
pconv = find_conversation( &src_addr, &fake_addr, PT_UDP, prt, 0 );
|
||||
|
||||
/*
|
||||
* If not, add
|
||||
*/
|
||||
if ( ! pconv ) {
|
||||
conversation_new( &src_addr, &fake_addr, PT_UDP, (guint32) prt, (guint32) 0, ( void * ) rtp_proto );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void rtp_init( void )
|
||||
{
|
||||
unsigned char* tmp_data;
|
||||
int i;
|
||||
|
||||
/* Create a fake adddress... */
|
||||
fake_addr.type = AT_IPv4;
|
||||
fake_addr.len = 4;
|
||||
|
||||
tmp_data = malloc( fake_addr.len );
|
||||
for ( i = 0; i < fake_addr.len; i++) {
|
||||
tmp_data[i] = 0;
|
||||
}
|
||||
fake_addr.data = tmp_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
gboolean
|
||||
dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
|
||||
{
|
||||
/* This is a heuristic dissector, which means we get all the tcp traffic
|
||||
* not send to a known dissector!
|
||||
* So we first check if the frame is really meant for us.
|
||||
*/
|
||||
conversation_t* pconv;
|
||||
if ( ( pconv = find_conversation( &pi.src, &fake_addr, pi.ptype, pi.srcport, 0 ) ) == NULL ) {
|
||||
/*
|
||||
* The source ip:port combination was not what we were looking for, check the destination
|
||||
*/
|
||||
if ( ( pconv = find_conversation( &pi.dst, &fake_addr, pi.ptype, pi.destport, 0 ) ) == NULL ) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* An RTP conversation always contains data
|
||||
*/
|
||||
if ( pconv->data == NULL )
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* An RTP conversation data always contains "RTP"
|
||||
*/
|
||||
if ( strcmp( pconv->data, rtp_proto ) != 0 )
|
||||
return FALSE;
|
||||
|
||||
dissect_rtp( tvb, pinfo, tree );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
dissect_rtp_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *rtp_tree, int offset, unsigned int data_len, unsigned int payload_type )
|
||||
{
|
||||
tvbuff_t *newtvb;
|
||||
|
||||
switch( payload_type ) {
|
||||
case PT_H261:
|
||||
/*
|
||||
* What does reported length DO?
|
||||
*/
|
||||
newtvb = tvb_new_subset( tvb, offset, data_len, -1 );
|
||||
dissect_h261(newtvb, pinfo, tree);
|
||||
break;
|
||||
default:
|
||||
proto_tree_add_bytes( rtp_tree, hf_rtp_data, tvb, offset, data_len, tvb_get_ptr( tvb, offset, data_len ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dissect_rtp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
|
||||
dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
|
||||
{
|
||||
proto_tree *rtp_tree;
|
||||
proto_item *ti;
|
||||
const u_char *data, *dataend;
|
||||
rtp_hdr_t hdr;
|
||||
int end_offset;
|
||||
int ii;
|
||||
guint32 *csrc_ptr;
|
||||
rtp_hdr_ext_t ext;
|
||||
proto_item *ti = NULL;
|
||||
proto_tree *rtp_tree = NULL;
|
||||
proto_tree *rtp_csrc_tree = NULL;
|
||||
guint8 octet;
|
||||
unsigned int version;
|
||||
gboolean padding_set;
|
||||
gboolean extension_set;
|
||||
unsigned int csrc_count;
|
||||
gboolean marker_set;
|
||||
unsigned int payload_type;
|
||||
unsigned int i = 0;
|
||||
unsigned int hdr_extension= 0;
|
||||
unsigned int padding_count= 0;
|
||||
unsigned int offset = 0;
|
||||
guint16 seq_num;
|
||||
guint32 timestamp;
|
||||
guint32 sync_src;
|
||||
guint32 csrc_item;
|
||||
|
||||
OLD_CHECK_DISPLAY_AS_DATA(proto_rtp, pd, offset, fd, tree);
|
||||
pinfo->current_proto = "RTP";
|
||||
|
||||
data = &pd[offset];
|
||||
dataend = data + END_OF_FRAME;
|
||||
end_offset = offset + END_OF_FRAME;
|
||||
/* Get the fields in the first octet */
|
||||
octet = tvb_get_guint8( tvb, offset );
|
||||
version = RTP_VERSION( octet );
|
||||
padding_set = RTP_PADDING( octet );
|
||||
extension_set = RTP_EXTENSION( octet );
|
||||
csrc_count = RTP_CSRC_COUNT( octet );
|
||||
|
||||
memcpy(&hdr, data, END_OF_FRAME < sizeof(rtp_hdr_t) ?
|
||||
END_OF_FRAME : sizeof(rtp_hdr_t));
|
||||
hdr.rtp_seq = ntohs(hdr.rtp_seq);
|
||||
hdr.rtp_timestamp = ntohl(hdr.rtp_timestamp);
|
||||
hdr.rtp_ssrc = ntohl(hdr.rtp_ssrc);
|
||||
/* Get the fields in the second octet */
|
||||
octet = tvb_get_guint8( tvb, offset + 1 );
|
||||
marker_set = RTP_MARKER( octet );
|
||||
payload_type = RTP_PAYLOAD_TYPE( octet );
|
||||
|
||||
if (check_col(fd, COL_PROTOCOL))
|
||||
col_add_str(fd, COL_PROTOCOL, "RTP");
|
||||
if (check_col(fd, COL_INFO)) {
|
||||
col_add_fstr(fd, COL_INFO, "SSRC=%lu, Seq=%u, Time=%lu%s",
|
||||
(u_long) hdr.rtp_ssrc,
|
||||
(u_int) hdr.rtp_seq,
|
||||
(u_long) hdr.rtp_timestamp,
|
||||
RTP_MARKER(&hdr) ? ", Mark" : "");
|
||||
/* Get the subsequent fields */
|
||||
seq_num = tvb_get_ntohs( tvb, offset + 2 );
|
||||
timestamp = tvb_get_ntohl( tvb, offset + 4 );
|
||||
sync_src = tvb_get_ntohl( tvb, offset + 8 );
|
||||
|
||||
if ( check_col( pinfo->fd, COL_PROTOCOL ) ) {
|
||||
col_add_str( pinfo->fd, COL_PROTOCOL, "RTP" );
|
||||
}
|
||||
|
||||
if ( check_col( pinfo->fd, COL_INFO) ) {
|
||||
col_add_fstr( pinfo->fd, COL_INFO,
|
||||
"Payload type=%s, SSRC=%u, Seq=%u, Time=%u%s",
|
||||
val_to_str( payload_type, rtp_payload_type_vals,
|
||||
"Unknown (%u)" ),
|
||||
sync_src,
|
||||
seq_num,
|
||||
timestamp,
|
||||
marker_set ? ", Mark" : "");
|
||||
}
|
||||
|
||||
rtp_tree = NULL;
|
||||
if ( tree ) {
|
||||
ti = proto_tree_add_item( tree, proto_rtp, tvb, offset, tvb_length_remaining( tvb, offset ), FALSE );
|
||||
rtp_tree = proto_item_add_subtree( ti, ett_rtp );
|
||||
|
||||
proto_tree_add_uint( rtp_tree, hf_rtp_version, tvb,
|
||||
offset, 1, version );
|
||||
proto_tree_add_boolean( rtp_tree, hf_rtp_padding, tvb,
|
||||
offset, 1, padding_set );
|
||||
proto_tree_add_boolean( rtp_tree, hf_rtp_extension, tvb,
|
||||
offset, 1, extension_set );
|
||||
proto_tree_add_uint( rtp_tree, hf_rtp_csrc_count, tvb,
|
||||
offset, 1, csrc_count );
|
||||
offset++;
|
||||
|
||||
if (tree) {
|
||||
ti = proto_tree_add_item(tree, proto_rtp, NullTVB, offset, END_OF_FRAME,
|
||||
FALSE);
|
||||
rtp_tree = proto_item_add_subtree(ti, ett_rtp);
|
||||
}
|
||||
proto_tree_add_boolean( rtp_tree, hf_rtp_marker, tvb, offset,
|
||||
1, marker_set );
|
||||
proto_tree_add_uint( rtp_tree, hf_rtp_payload_type, tvb,
|
||||
offset, 1, payload_type );
|
||||
offset++;
|
||||
|
||||
if (!rtp_tree)
|
||||
return;
|
||||
/* Sequence number 16 bits (2 octets) */
|
||||
proto_tree_add_uint( rtp_tree, hf_rtp_seq_nr, tvb, offset, 2, seq_num );
|
||||
offset += 2;
|
||||
|
||||
if (offset >= end_offset)
|
||||
goto bad_len;
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, 1, "Version: %u (%s)",
|
||||
RTP_VERSION(&hdr),
|
||||
RTP_VERSION(&hdr) == 3 ? "New Unknown Version" :
|
||||
RTP_VERSION(&hdr) == 2 ? "RFC 1889 Version" :
|
||||
RTP_VERSION(&hdr) == 1 ? "First Draft Version" :
|
||||
"Old Vat Version");
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, 1, "Padding: %u",
|
||||
RTP_PADDING(&hdr));
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, 1, "Extension: %u",
|
||||
RTP_EXTENSION(&hdr));
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, 1, "CSRC Count: %u",
|
||||
RTP_CSRC_COUNT(&hdr));
|
||||
offset++;
|
||||
|
||||
if (offset >= end_offset)
|
||||
goto bad_len;
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, 1, "Marker: %u",
|
||||
RTP_MARKER(&hdr));
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, 1, "Payload Type: %u",
|
||||
RTP_PAYLOAD_TYPE(&hdr));
|
||||
offset++;
|
||||
|
||||
if (offset >= end_offset)
|
||||
goto bad_len;
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, 2, "Seq: %u",
|
||||
(u_int) hdr.rtp_seq);
|
||||
offset += 2;
|
||||
|
||||
if (offset >= end_offset)
|
||||
goto bad_len;
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, 4, "Timestamp: %lu",
|
||||
(u_long) hdr.rtp_timestamp);
|
||||
offset += 4;
|
||||
|
||||
if (offset >= end_offset)
|
||||
goto bad_len;
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, 4, "SSRC: %lu",
|
||||
(u_long) hdr.rtp_ssrc);
|
||||
offset += 4;
|
||||
|
||||
csrc_ptr = (guint32*) (data + sizeof(rtp_hdr_t));
|
||||
for (ii = 0; ii < RTP_CSRC_COUNT(&hdr); ii++) {
|
||||
guint32 csrc;
|
||||
if (offset >= end_offset)
|
||||
goto bad_len;
|
||||
csrc = pntohl(csrc_ptr);
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, 4, "CSRC %d: %lu",
|
||||
ii + 1, (u_long) csrc);
|
||||
/* Timestamp 32 bits (4 octets) */
|
||||
proto_tree_add_uint( rtp_tree, hf_rtp_timestamp, tvb, offset, 4, timestamp );
|
||||
offset += 4;
|
||||
csrc_ptr++;
|
||||
|
||||
/* Synchronization source identifier 32 bits (4 octets) */
|
||||
proto_tree_add_uint( rtp_tree, hf_rtp_ssrc, tvb, offset, 4, sync_src );
|
||||
offset += 4;
|
||||
|
||||
/* CSRC list*/
|
||||
if ( csrc_count > 0 ) {
|
||||
ti = proto_tree_add_text(rtp_tree, tvb, offset, csrc_count * 4, "Contributing Source identifiers");
|
||||
rtp_csrc_tree = proto_item_add_subtree( ti, ett_csrc_list );
|
||||
for (i = 0; i < csrc_count; i++ ) {
|
||||
csrc_item = tvb_get_ntohl( tvb, offset );
|
||||
proto_tree_add_uint_format( rtp_csrc_tree,
|
||||
hf_rtp_csrc_item, tvb, offset, 4,
|
||||
csrc_item,
|
||||
"CSRC item %d: %u",
|
||||
i, csrc_item );
|
||||
offset += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* Optional RTP header extension */
|
||||
if ( extension_set ) {
|
||||
/* Defined by profile field is 16 bits (2 octets) */
|
||||
proto_tree_add_uint( rtp_tree, hf_rtp_prof_define, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
|
||||
offset += 2;
|
||||
|
||||
hdr_extension = tvb_get_ntohs( tvb, offset );
|
||||
proto_tree_add_uint( rtp_tree, hf_rtp_length, tvb,
|
||||
offset, 2, hdr_extension);
|
||||
if ( hdr_extension > 0 ) {
|
||||
ti = proto_tree_add_text(rtp_tree, tvb, offset, csrc_count * 4, "Header extensions");
|
||||
/* I'm re-using the old tree variable here
|
||||
from the CSRC list!*/
|
||||
rtp_csrc_tree = proto_item_add_subtree( ti,
|
||||
ett_hdr_ext );
|
||||
for (i = 0; i < hdr_extension; i++ ) {
|
||||
proto_tree_add_uint( rtp_csrc_tree, hf_rtp_hdr_ext, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
|
||||
offset += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Find the padding
|
||||
* The padding count is found in the LAST octet of the packet
|
||||
* This contains the number of octets that can be ignored at
|
||||
* the end of the packet
|
||||
*/
|
||||
if ( padding_set ) {
|
||||
padding_count = tvb_get_guint8( tvb, tvb_length( tvb ) - 1 );
|
||||
if ( padding_count > 0 ) {
|
||||
dissect_rtp_data( tvb, pinfo, tree, rtp_tree, offset, tvb_length( tvb ) - padding_count, payload_type );
|
||||
offset = tvb_length( tvb ) - padding_count;
|
||||
proto_tree_add_item( rtp_tree, hf_rtp_padding_data, tvb, offset, padding_count - 1, FALSE );
|
||||
offset += padding_count - 1;
|
||||
proto_tree_add_item( rtp_tree, hf_rtp_padding_count, tvb, offset, 1, FALSE );
|
||||
}
|
||||
else {
|
||||
proto_tree_add_item( rtp_tree, hf_rtp_padding_count, tvb, tvb_length( tvb ) - 1, 1, FALSE );
|
||||
}
|
||||
}
|
||||
else {
|
||||
dissect_rtp_data( tvb, pinfo, tree, rtp_tree, offset, tvb_length_remaining( tvb, offset ) - padding_count, payload_type );
|
||||
}
|
||||
}
|
||||
|
||||
if (RTP_EXTENSION(&hdr)) {
|
||||
memcpy(&ext, data + sizeof(rtp_hdr_t),
|
||||
END_OF_FRAME < sizeof(rtp_hdr_ext_t) ?
|
||||
END_OF_FRAME : sizeof(rtp_hdr_ext_t));
|
||||
ext.rtp_ext_app = ntohs(ext.rtp_ext_app);
|
||||
ext.rtp_ext_length = ntohs(ext.rtp_ext_length);
|
||||
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, 2,
|
||||
"Extension-defined: %x", (u_int) ext.rtp_ext_app);
|
||||
offset += 2;
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, 2,
|
||||
"Extension length: %u", (u_int) ext.rtp_ext_length);
|
||||
offset += 2;
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, 4 * ext.rtp_ext_length,
|
||||
"Extension Data (%d bytes)",
|
||||
(int) 4 * ext.rtp_ext_length);
|
||||
offset += 4 * ext.rtp_ext_length;
|
||||
}
|
||||
|
||||
proto_tree_add_text(rtp_tree, NullTVB, offset, END_OF_FRAME,
|
||||
"Data (%d bytes)", END_OF_FRAME);
|
||||
|
||||
return;
|
||||
|
||||
bad_len:
|
||||
proto_tree_add_text(rtp_tree, NullTVB, end_offset, 0,
|
||||
"Unexpected end of packet");
|
||||
}
|
||||
|
||||
void
|
||||
proto_register_rtp(void)
|
||||
{
|
||||
/* static hf_register_info hf[] = {
|
||||
{ &variable,
|
||||
{ "Name", "rtp.abbreviation", TYPE, VALS_POINTER }},
|
||||
};*/
|
||||
static gint *ett[] = {
|
||||
static hf_register_info hf[] =
|
||||
{
|
||||
{
|
||||
&hf_rtp_version,
|
||||
{
|
||||
"Version",
|
||||
"rtp.version",
|
||||
FT_UINT8,
|
||||
BASE_DEC,
|
||||
VALS(rtp_version_vals),
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_padding,
|
||||
{
|
||||
"Padding",
|
||||
"rtp.padding",
|
||||
FT_BOOLEAN,
|
||||
BASE_NONE,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_extension,
|
||||
{
|
||||
"Extension",
|
||||
"rtp.ext",
|
||||
FT_BOOLEAN,
|
||||
BASE_NONE,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_csrc_count,
|
||||
{
|
||||
"Contributing source identifiers count",
|
||||
"rtp.cc",
|
||||
FT_UINT8,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_marker,
|
||||
{
|
||||
"Marker",
|
||||
"rtp.marker",
|
||||
FT_BOOLEAN,
|
||||
BASE_NONE,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_payload_type,
|
||||
{
|
||||
"Payload type",
|
||||
"rtp.p_type",
|
||||
FT_UINT8,
|
||||
BASE_DEC,
|
||||
VALS(rtp_payload_type_vals),
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_seq_nr,
|
||||
{
|
||||
"Sequence number",
|
||||
"rtp.seq",
|
||||
FT_UINT16,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_timestamp,
|
||||
{
|
||||
"Timestamp",
|
||||
"rtp.timestamp",
|
||||
FT_UINT32,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_ssrc,
|
||||
{
|
||||
"Synchronization Source identifier",
|
||||
"rtp.ssrc",
|
||||
FT_UINT32,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_prof_define,
|
||||
{
|
||||
"Defined by profile",
|
||||
"rtp.ext.profile",
|
||||
FT_UINT16,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_length,
|
||||
{
|
||||
"Extension length",
|
||||
"rtp.ext.len",
|
||||
FT_UINT16,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_csrc_item,
|
||||
{
|
||||
"CSRC item",
|
||||
"rtp.csrc.item",
|
||||
FT_UINT32,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_hdr_ext,
|
||||
{
|
||||
"Header extension",
|
||||
"rtp.hdr_ext",
|
||||
FT_UINT32,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_data,
|
||||
{
|
||||
"Payload",
|
||||
"rtp.payload",
|
||||
FT_BYTES,
|
||||
BASE_HEX,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_padding_data,
|
||||
{
|
||||
"Padding data",
|
||||
"rtp.padding.data",
|
||||
FT_BYTES,
|
||||
BASE_HEX,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_rtp_padding_count,
|
||||
{
|
||||
"Padding count",
|
||||
"rtp.padding.count",
|
||||
FT_UINT8,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static gint *ett[] =
|
||||
{
|
||||
&ett_rtp,
|
||||
&ett_csrc_list,
|
||||
&ett_hdr_ext,
|
||||
};
|
||||
|
||||
proto_rtp = proto_register_protocol("Realtime Transport Protocol", "rtp");
|
||||
/* proto_register_field_array(proto_rtp, hf, array_length(hf));*/
|
||||
|
||||
proto_rtp = proto_register_protocol("Real-Time Transport Protocol", "rtp");
|
||||
proto_register_field_array(proto_rtp, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
|
||||
#if 0
|
||||
register_init_routine( &rtp_init );
|
||||
#endif
|
||||
}
|
||||
|
|
19
packet-rtp.h
19
packet-rtp.h
|
@ -1,9 +1,10 @@
|
|||
/* packet-rtp.h
|
||||
* Declarations for RTP packet disassembly
|
||||
*
|
||||
* Jason Lango <jal@netapp.com>
|
||||
*
|
||||
* $Id: packet-rtp.h,v 1.2 2000/08/11 13:34:01 deniel Exp $
|
||||
* Routines for RTP dissection
|
||||
* RTP = Real time Transport Protocol
|
||||
*
|
||||
* Copyright 2000, Philips Electronics N.V.
|
||||
* Written by Andreas Sikkema <andreas.sikkema@philips.com>
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -25,9 +26,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PACKET_RTP_H__
|
||||
#define __PACKET_RTP_H__
|
||||
|
||||
void dissect_rtp(const u_char *, int, frame_data *, proto_tree *);
|
||||
|
||||
#endif
|
||||
void rtp_add_address ( const unsigned char* ip_addr, int prt );
|
||||
gboolean dissect_rtp_heur ( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree );
|
||||
void dissect_rtp ( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree );
|
||||
void proto_register_rtp( void );
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Jason Lango <jal@netapp.com>
|
||||
* Liberally copied from packet-http.c, by Guy Harris <guy@alum.mit.edu>
|
||||
*
|
||||
* $Id: packet-rtsp.c,v 1.19 2000/09/30 05:46:27 guy Exp $
|
||||
* $Id: packet-rtsp.c,v 1.20 2000/10/19 06:45:11 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -126,14 +126,14 @@ rtsp_create_conversation(const u_char *trans_begin, const u_char *trans_end)
|
|||
|
||||
conv = conversation_new(&pi.src, &pi.dst, PT_UDP, s_data_port,
|
||||
c_data_port, 0);
|
||||
old_conversation_set_dissector(conv, dissect_rtp);
|
||||
conversation_set_dissector(conv, dissect_rtp);
|
||||
|
||||
if (!c_mon_port || !s_mon_port)
|
||||
return;
|
||||
|
||||
conv = conversation_new(&pi.src, &pi.dst, PT_UDP, s_mon_port,
|
||||
c_mon_port, 0);
|
||||
old_conversation_set_dissector(conv, dissect_rtcp);
|
||||
conversation_set_dissector(conv, dissect_rtcp);
|
||||
}
|
||||
|
||||
static void dissect_rtsp(const u_char *pd, int offset, frame_data *fd,
|
||||
|
|
|
@ -0,0 +1,187 @@
|
|||
/* packet-tpkt.c
|
||||
*
|
||||
* Routines for TPKT dissection
|
||||
* Copyright 2000, Philips Electronics N.V.
|
||||
* Andreas Sikkema <andreas.sikkema@philips.com>
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This dissector tries to dissect the TPKT protocol according to
|
||||
* RFC 1006
|
||||
*
|
||||
* IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
|
||||
*
|
||||
* Please examine the dissector. It is NOT defined in the normal way!
|
||||
* Some variables are references and the dissector also returns a
|
||||
* value! And no, this is not a heuristic dissector!
|
||||
*
|
||||
* IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include "packet.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "packet-tpkt.h"
|
||||
|
||||
/* TPKT header fields */
|
||||
static int proto_tpkt = -1;
|
||||
static int hf_tpkt_version = -1;
|
||||
static int hf_tpkt_reserved = -1;
|
||||
static int hf_tpkt_length = -1;
|
||||
|
||||
/* TPKT fields defining a sub tree */
|
||||
static gint ett_tpkt = -1;
|
||||
|
||||
int
|
||||
is_tpkt( tvbuff_t *tvb, unsigned int* offset )
|
||||
{
|
||||
if ( (*offset) + 4 > tvb_length( tvb ) ) return FALSE;
|
||||
if ( ! ( ( tvb_get_guint8( tvb, ( *offset ) ) == 3 ) &&
|
||||
( tvb_get_guint8( tvb, ( *offset ) + 1 ) == 0 ) ) ) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
dissect_tpkt( tvbuff_t *tvb, unsigned int* offset, packet_info *pinfo, proto_tree *tree )
|
||||
{
|
||||
proto_item *ti = NULL;
|
||||
proto_tree *tpkt_tree = NULL;
|
||||
unsigned int data_len = 0;
|
||||
|
||||
|
||||
pinfo->current_proto = "TPKT";
|
||||
|
||||
/* There should at least be 4 bytes left in the frame */
|
||||
if ( (*offset) + 4 > tvb_length( tvb ) ) return -1;
|
||||
/*
|
||||
* The first octet should be 3 and the second one should be 0
|
||||
* The H.323 implementers guide suggests that this migh not
|
||||
* always be the case....
|
||||
*/
|
||||
if ( ! ( ( tvb_get_guint8( tvb, ( *offset ) ) == 3 ) &&
|
||||
( tvb_get_guint8( tvb, ( *offset ) + 1 ) == 0 ) ) ) return -1;
|
||||
|
||||
if ( check_col( pinfo->fd, COL_PROTOCOL ) ) {
|
||||
col_add_str( pinfo->fd, COL_PROTOCOL, "TPKT" );
|
||||
}
|
||||
|
||||
if ( check_col( pinfo->fd, COL_INFO) ) {
|
||||
/*data_len = pntohs( &pd[ (*offset) + 2 ] );*/
|
||||
data_len = tvb_get_ntohs( tvb, (*offset) + 2 );
|
||||
|
||||
col_add_fstr( pinfo->fd, COL_INFO, "TPKT Data length = %d", data_len );
|
||||
}
|
||||
|
||||
if ( tree ) {
|
||||
ti = proto_tree_add_item( tree, proto_tpkt, tvb, (*offset), 4, FALSE );
|
||||
tpkt_tree = proto_item_add_subtree( ti, ett_tpkt );
|
||||
/* Version 1st octet */
|
||||
proto_tree_add_item( tpkt_tree, hf_tpkt_version, tvb, (*offset), 1, FALSE );
|
||||
(*offset)++;
|
||||
/* Reserved octet*/
|
||||
proto_tree_add_item( tpkt_tree, hf_tpkt_reserved, tvb, (*offset), 1, FALSE );
|
||||
(*offset)++;
|
||||
}
|
||||
else {
|
||||
(*offset) += 2;
|
||||
}
|
||||
/* Length, two octets */
|
||||
/*data_len = pntohs( &pd[ (*offset) ] );*/
|
||||
data_len = tvb_get_ntohs( tvb, (*offset) );
|
||||
|
||||
if ( tree )
|
||||
proto_tree_add_uint_format( tpkt_tree, hf_tpkt_length, tvb, (*offset), 2, data_len, "Length: %d", data_len );
|
||||
|
||||
(*offset) += 2;
|
||||
return data_len;
|
||||
}
|
||||
|
||||
void
|
||||
proto_register_tpkt(void)
|
||||
{
|
||||
static hf_register_info hf[] =
|
||||
{
|
||||
{
|
||||
&hf_tpkt_version,
|
||||
{
|
||||
"Version",
|
||||
"tpkt.version",
|
||||
FT_UINT8,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_tpkt_reserved,
|
||||
{
|
||||
"Reserved",
|
||||
"tpkt.reserved",
|
||||
FT_UINT8,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
&hf_tpkt_length,
|
||||
{
|
||||
"Length",
|
||||
"tpkt.length",
|
||||
FT_UINT16,
|
||||
BASE_DEC,
|
||||
NULL,
|
||||
0x0,
|
||||
""
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static gint *ett[] =
|
||||
{
|
||||
&ett_tpkt,
|
||||
};
|
||||
|
||||
|
||||
proto_tpkt = proto_register_protocol("TPKT", "tpkt");
|
||||
proto_register_field_array(proto_tpkt, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/* packet-tpkt.h
|
||||
*
|
||||
* Routines for TPKT dissection
|
||||
*
|
||||
* Copyright 2000, Philips Electronics N.V.
|
||||
* Andreas Sikkema <andreas.sikkema@philips.com>
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
int is_tpkt( tvbuff_t *tvb, unsigned int* offset );
|
||||
int dissect_tpkt( tvbuff_t *tvb, unsigned int* offset, packet_info *pinfo, proto_tree *tree );
|
||||
void proto_register_tpkt( void );
|
Loading…
Reference in New Issue