diff options
author | Anders Broman <anders.broman@ericsson.com> | 2007-02-27 06:25:07 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2007-02-27 06:25:07 +0000 |
commit | c637027427d3cccfdf079f81e0be4a9435bfd517 (patch) | |
tree | 01c48aac3a834bc17e132f92ee58d52c4c53db92 /plugins | |
parent | cf13f56dc8a74bd47e60f3ff37664c8321db715c (diff) |
From Richard van der Hoff:
- Registers H.223 as a dissector for RTP CLEARMODE payloads -
and makes some other modifications to the H.223 dissector to make this
work correctly.
-Allows a standalone binary, epan/reassemble_test, to be built; this can be run from the commandline and should end up printing out "success"
if all goes well.
svn path=/trunk/; revision=20935
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/h223/packet-h223.c | 184 |
1 files changed, 125 insertions, 59 deletions
diff --git a/plugins/h223/packet-h223.c b/plugins/h223/packet-h223.c index 810172447c..9f9bde5997 100644 --- a/plugins/h223/packet-h223.c +++ b/plugins/h223/packet-h223.c @@ -388,100 +388,165 @@ static h223_vc_info* h223_vc_info_new( h223_call_info* call_info ) return vc_info; } -static void init_logical_channel( packet_info* pinfo, h223_call_info* call_info, int vc, int direction, h223_lc_params* params ) +static void init_logical_channel( guint32 start_frame, h223_call_info* call_info, int vc, int direction, h223_lc_params* params ) { guint32 circuit_id = circuit_chain_lookup(call_info, vc); circuit_t *subcircuit; h223_vc_info *vc_info; - subcircuit = find_circuit( CT_H223, circuit_id, pinfo->fd->num ); + subcircuit = find_circuit( CT_H223, circuit_id, start_frame ); if( subcircuit == NULL ) { - subcircuit = circuit_new( CT_H223, circuit_id, pinfo->fd->num ); + subcircuit = circuit_new( CT_H223, circuit_id, start_frame ); #ifdef DEBUG_H223 - g_debug("%d: Created new circuit %d for call %p VC %d", pinfo->fd->num, circuit_id, call_info, vc); + g_debug("%d: Created new circuit %d for call %p VC %d", start_frame, circuit_id, call_info, vc); #endif vc_info = h223_vc_info_new( call_info ); circuit_add_proto_data( subcircuit, proto_h223, vc_info ); } else { vc_info = circuit_get_proto_data( subcircuit, proto_h223 ); } - add_h223_lc_params( vc_info, direction, params, pinfo->fd->num ); + add_h223_lc_params( vc_info, direction, params, start_frame ); } -static void init_control_channels( packet_info* pinfo, h223_call_info* call_info ) +/* create a brand-new h223_call_info structure */ +static h223_call_info *create_call_info( guint32 start_frame ) { - h223_lc_params *vc0_params = se_alloc(sizeof(h223_lc_params)); + h223_call_info *data; + h223_lc_params *vc0_params; + + data = se_alloc(sizeof(h223_call_info)); + + /* initialise the call info */ + init_direction_data(&data -> direction_data[0]); + init_direction_data(&data -> direction_data[1]); + + /* FIXME shouldn't this be figured out dynamically? */ + data -> h223_level = 2; + + vc0_params = se_alloc(sizeof(h223_lc_params)); vc0_params->al_type = al1Framed; vc0_params->al_params = NULL; vc0_params->segmentable = TRUE; vc0_params->subdissector = srp_handle; - init_logical_channel( pinfo, call_info, 0, P2P_DIR_SENT, vc0_params ); - init_logical_channel( pinfo, call_info, 0, P2P_DIR_RECV, vc0_params ); + init_logical_channel( start_frame, data, 0, P2P_DIR_SENT, vc0_params ); + init_logical_channel( start_frame, data, 0, P2P_DIR_RECV, vc0_params ); + return data; } -static h223_call_info *find_or_create_call_info ( packet_info * pinfo ) +/* find or create call_info struct for calls over circuits (eg, IAX) */ +static h223_call_info *find_or_create_call_info_circ(packet_info * pinfo) { - circuit_t *circ; - conversation_t *conv = NULL; h223_call_info *data; + circuit_t *circ = NULL; - /* look for a circuit (eg, IAX call) first */ - circ = find_circuit( pinfo->ctype, pinfo->circuit_id, pinfo->fd->num ); - if( circ == NULL ) { - /* assume we're running atop TCP; use the converstion support */ - conv = find_conversation( pinfo->fd->num, - &pinfo->src,&pinfo->dst, - pinfo->ptype, - pinfo->srcport,pinfo->destport, 0 ); - if( conv == NULL ) { - conv = conversation_new( pinfo->fd->num, - &pinfo->src,&pinfo->dst, - pinfo->ptype, - pinfo->srcport,pinfo->destport, 0 ); - } - + if(pinfo->ctype != CT_NONE) + circ = find_circuit( pinfo->ctype, pinfo->circuit_id, pinfo->fd->num ); + if(circ == NULL) + return NULL; + + data = (h223_call_info *)circuit_get_proto_data(circ, proto_h223); + + if( data == NULL ) { + data = create_call_info(pinfo->fd->num); + +#ifdef DEBUG_H223 + g_debug("%u: Created new call %p for circuit %p ctype %d, id %u", + pinfo->fd->num, data, circ, pinfo->ctype, pinfo->circuit_id); +#endif + circuit_add_proto_data(circ, proto_h223, data); } + + /* work out what direction we're really going in */ + if( pinfo->p2p_dir < 0 || pinfo->p2p_dir > 1) + pinfo->p2p_dir = P2P_DIR_SENT; + + return data; +} - if( circ ) - data = (h223_call_info *)circuit_get_proto_data(circ, proto_h223); - else - data = (h223_call_info *)conversation_get_proto_data(conv, proto_h223); +/* find or create call_info struct for calls over conversations (eg, RTP) */ +static h223_call_info *find_or_create_call_info_conv(packet_info * pinfo) +{ + h223_call_info *data; + conversation_t *conv; - if( data == NULL ) { - data = se_alloc(sizeof(h223_call_info)); + /* assume we're running atop TCP or RTP; use the conversation support */ + conv = find_conversation( pinfo->fd->num, + &pinfo->src,&pinfo->dst, + pinfo->ptype, + pinfo->srcport,pinfo->destport, 0 ); - if( circ ) { - circuit_add_proto_data(circ, proto_h223, data); - } else { - conversation_add_proto_data(conv, proto_h223, data); - /* add the source details so we can distinguish directions - * in future */ - COPY_ADDRESS(&(data -> srcaddress), &(pinfo->src)); - data -> srcport = pinfo->srcport; - } + /* both RTP and TCP track their conversations, so just assert here if + * we can't find one */ + DISSECTOR_ASSERT(conv); + + data = (h223_call_info *)conversation_get_proto_data(conv, proto_h223); - /* initialise the call info */ - init_direction_data(&data -> direction_data[0]); - init_direction_data(&data -> direction_data[1]); + if(data == NULL && pinfo->ptype == PT_UDP ) { + conversation_t *conv2; - /* FIXME shouldn't this be figured out dynamically? */ - data -> h223_level = 2; + /* RTP tracks the two sides of the conversation totally separately; + * this messes us up totally. + * + * Look for another converstation, going in the opposite direction. + */ + conv2 = find_conversation( pinfo->fd->num, + &pinfo->dst,&pinfo->src, + pinfo->ptype, + pinfo->destport,pinfo->srcport, 0 ); + if(conv2 != NULL) + data = (h223_call_info *)conversation_get_proto_data(conv2, proto_h223); + + if(data != NULL) { +#ifdef DEBUG_H223 + g_debug("%u: Identified conv %p as reverse of conv %p with call %p and type=%u src=%u.%u.%u.%u:%u dst=%u.%u.%u.%u:%u", + pinfo->fd->num, conv, conv2, data, pinfo->ptype, + pinfo->dst.data[0], pinfo->dst.data[1], pinfo->dst.data[2], pinfo->dst.data[3], + pinfo->destport, + pinfo->src.data[0], pinfo->src.data[1], pinfo->src.data[2], pinfo->src.data[3], + pinfo->srcport); +#endif + conversation_add_proto_data(conv, proto_h223, data); + } + } - init_control_channels( pinfo, data ); + /* we still haven't found any call data - create a new one for this + * conversation */ + if(data == NULL) { + data = create_call_info(pinfo->fd->num); + +#ifdef DEBUG_H223 + g_debug("%u: Created new call %p for conv %p type=%u src=%u.%u.%u.%u:%u dst=%u.%u.%u.%u:%u", + pinfo->fd->num, data, conv, pinfo->ptype, + pinfo->src.data[0], pinfo->src.data[1], pinfo->src.data[2], pinfo->src.data[3], + pinfo->srcport, + pinfo->dst.data[0], pinfo->dst.data[1], pinfo->dst.data[2], pinfo->dst.data[3], + pinfo->destport); +#endif + + conversation_add_proto_data(conv, proto_h223, data); + /* add the source details so we can distinguish directions + * in future */ + COPY_ADDRESS(&(data -> srcaddress), &(pinfo->src)); + data -> srcport = pinfo->srcport; } /* work out what direction we're really going in */ - if( circ ) { - if( pinfo->p2p_dir < 0 || pinfo->p2p_dir > 1) - pinfo->p2p_dir = P2P_DIR_SENT; - } else { - if( ADDRESSES_EQUAL( &(pinfo->src), &(data->srcaddress)) - && pinfo->srcport == data->srcport ) - pinfo->p2p_dir = P2P_DIR_SENT; - else - pinfo->p2p_dir = P2P_DIR_RECV; - } + if( ADDRESSES_EQUAL( &(pinfo->src), &(data->srcaddress)) + && pinfo->srcport == data->srcport ) + pinfo->p2p_dir = P2P_DIR_SENT; + else + pinfo->p2p_dir = P2P_DIR_RECV; + + return data; +} + +static h223_call_info *find_or_create_call_info ( packet_info * pinfo ) +{ + h223_call_info *data; + data = find_or_create_call_info_circ(pinfo); + if(data == NULL) + data = find_or_create_call_info_conv(pinfo); return data; } @@ -509,7 +574,7 @@ static void h223_add_lc( packet_info* pinfo, guint16 lc, h223_lc_params* params * the new channel */ if(circ) { vc_info = circuit_get_proto_data(circ, proto_h223); - init_logical_channel( pinfo, vc_info->call_info, lc, pinfo->p2p_dir, params ); + init_logical_channel( pinfo->fd->num, vc_info->call_info, lc, pinfo->p2p_dir, params ); } } @@ -1512,6 +1577,7 @@ void proto_reg_handoff_h223(void) dissector_add_handle("tcp.port", h223); dissector_add_handle("tcp.port", h223_bitswapped); + dissector_add_string("rtp_dyn_payload_type","CLEARMODE", h223_bitswapped); dissector_add("iax2.dataformat", AST_DATAFORMAT_H223_H245, h223_bitswapped); } /* vim:set ts=8 et: */ |