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:
Guy Harris 2000-10-19 06:45:11 +00:00
parent 9de17c39f5
commit 3f8b7cd0fc
13 changed files with 2536 additions and 634 deletions

11
AUTHORS
View File

@ -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> {

View File

@ -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 \

View File

@ -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 \

262
packet-h261.c Normal file
View File

@ -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));
}

30
packet-h261.h Normal file
View File

@ -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 );

View File

@ -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
}

File diff suppressed because it is too large Load Diff

View File

@ -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 );

View File

@ -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
}

View File

@ -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 );

View File

@ -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,

187
packet-tpkt.c Normal file
View File

@ -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));
}

30
packet-tpkt.h Normal file
View File

@ -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 );