From 21b9a88b2942558536c9b0f5191261a874b8034a Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Mon, 3 Dec 2001 05:07:18 +0000 Subject: [PATCH] Add a routine tro look for a given port in a given dissector table and, if found, return the dissector handle for that port. Use that routine in the X.25 dissector; revert to attaching a dissector handle to an X.25 virtual circuit. svn path=/trunk/; revision=4310 --- epan/packet.c | 22 ++++++++--- epan/packet.h | 7 +++- packet-x25.c | 104 ++++++++++++++++++++------------------------------ 3 files changed, 64 insertions(+), 69 deletions(-) diff --git a/epan/packet.c b/epan/packet.c index 1b04a0db03..bee5f2a43e 100644 --- a/epan/packet.c +++ b/epan/packet.c @@ -1,7 +1,7 @@ /* packet.c * Routines for packet disassembly * - * $Id: packet.c,v 1.48 2001/12/03 04:00:14 guy Exp $ + * $Id: packet.c,v 1.49 2001/12/03 05:07:17 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -348,10 +348,7 @@ dissector_reset(const char *name, guint32 pattern) /* Look for a given port in a given dissector table and, if found, call the dissector with the arguments supplied, and return TRUE, otherwise - return FALSE. - - If the arguments supplied don't match the arguments to the dissector, - do the appropriate translation. */ + return FALSE. */ gboolean dissector_try_port(dissector_table_t sub_dissectors, guint32 port, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) @@ -419,6 +416,21 @@ dissector_try_port(dissector_table_t sub_dissectors, guint32 port, return FALSE; } +/* Look for a given port in a given dissector table and, if found, return + the dissector handle for that port. */ +dissector_handle_t +dissector_get_port_handle(dissector_table_t sub_dissectors, guint32 port) +{ + dtbl_entry_t *dtbl_entry; + + dtbl_entry = g_hash_table_lookup(sub_dissectors, + GUINT_TO_POINTER(port)); + if (dtbl_entry != NULL) + return dtbl_entry->current; + else + return NULL; +} + dissector_handle_t dtbl_entry_get_handle (dtbl_entry_t *dtbl_entry) { diff --git a/epan/packet.h b/epan/packet.h index 83f69c2ee2..c4235eecf9 100644 --- a/epan/packet.h +++ b/epan/packet.h @@ -1,7 +1,7 @@ /* packet.h * Definitions for packet disassembly structures and routines * - * $Id: packet.h,v 1.43 2001/12/03 04:00:14 guy Exp $ + * $Id: packet.h,v 1.44 2001/12/03 05:07:18 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -131,6 +131,11 @@ extern void dissector_reset(const char *name, guint32 pattern); extern gboolean dissector_try_port(dissector_table_t sub_dissectors, guint32 port, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); +/* Look for a given port in a given dissector table and, if found, return + the dissector handle for that port. */ +extern dissector_handle_t dissector_get_port_handle( + dissector_table_t sub_dissectors, guint32 port); + /* List of "heuristic" dissectors (which get handed a packet, look at it, and either recognize it as being for their protocol, dissect it, and return TRUE, or don't recognize it and return FALSE) to be called diff --git a/packet-x25.c b/packet-x25.c index f7f4fcce54..0a800e76a8 100644 --- a/packet-x25.c +++ b/packet-x25.c @@ -2,7 +2,7 @@ * Routines for x25 packet disassembly * Olivier Abad * - * $Id: packet-x25.c,v 1.58 2001/12/03 03:59:43 guy Exp $ + * $Id: packet-x25.c,v 1.59 2001/12/03 05:07:16 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -155,6 +155,7 @@ static const value_string vals_x25_type[] = { { 0, NULL} }; +static dissector_handle_t ip_handle; static dissector_handle_t ositp_handle; static dissector_handle_t sna_handle; static dissector_handle_t qllc_handle; @@ -169,7 +170,7 @@ static dissector_table_t x25_subdissector_table; * each vc_info node contains : * the time of the first frame using this dissector (secs and usecs) * the time of the last frame using this dissector (0 if it is unknown) - * the protocol used over the VC + * a handle for the dissector * * the "time of first frame" is initialized when a Call Req. is received * the "time of last frame" is initialized when a Clear, Reset, or Restart @@ -178,22 +179,10 @@ static dissector_table_t x25_subdissector_table; typedef struct _vc_info { guint32 first_frame_secs, first_frame_usecs; guint32 last_frame_secs, last_frame_usecs; - int proto; + dissector_handle_t dissect; struct _vc_info *next; } vc_info; -/* - * Protocol unknown for connection. - */ -#define PROTO_UNKNOWN -1 - -/* - * Special protocol values, for protocols not indicated by an NLPID as a - * secondary protocol identifier. - */ -#define PROTO_SNA -2 -#define PROTO_OSITP -3 - /* * the hash table will contain linked lists of global_vc_info * each global_vc_info struct contains : @@ -244,7 +233,7 @@ reinit_x25_hashtable(void) static void x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs, - int proto) + dissector_handle_t dissect) { int idx = vc % 64; global_vc_info *hash_ent; @@ -268,7 +257,7 @@ x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs, hash_ent->info->first_frame_usecs = frame_usecs; hash_ent->info->last_frame_secs = 0; hash_ent->info->last_frame_usecs = 0; - hash_ent->info->proto = proto; + hash_ent->info->dissect = dissect; hash_ent->info->next = 0; hash_table[idx] = hash_ent; } @@ -284,7 +273,7 @@ x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs, { vc_info *vci = hash_ent->info; while (vci->next) vci = vci->next; /* last element */ - if (vci->proto == proto) { + if (vci->dissect == dissect) { vci->last_frame_secs = 0; vci->last_frame_usecs = 0; } @@ -298,7 +287,7 @@ x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs, vci->next->first_frame_usecs = frame_usecs; vci->next->last_frame_secs = 0; vci->next->last_frame_usecs = 0; - vci->next->proto = proto; + vci->next->dissect = dissect; vci->next->next = 0; } } @@ -318,7 +307,7 @@ x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs, hash_ent2->next->info->first_frame_usecs = frame_usecs; hash_ent2->next->info->last_frame_secs = 0; hash_ent2->next->info->last_frame_usecs = 0; - hash_ent2->next->info->proto = proto; + hash_ent2->next->info->dissect = dissect; hash_ent2->next->info->next = 0; } } @@ -340,20 +329,20 @@ x25_hash_add_proto_end(guint16 vc, guint32 frame_secs, guint32 frame_usecs) vci->last_frame_usecs = frame_usecs; } -static int -x25_hash_get_proto(guint32 frame_secs, guint32 frame_usecs, guint16 vc) +static dissector_handle_t +x25_hash_get_dissect(guint32 frame_secs, guint32 frame_usecs, guint16 vc) { global_vc_info *hash_ent = hash_table[vc%64]; vc_info *vci; vc_info *vci2; if (!hash_ent) - return PROTO_UNKNOWN; + return NULL; while (hash_ent && hash_ent->vc_num != vc) hash_ent = hash_ent->next; if (!hash_ent) - return PROTO_UNKNOWN; + return NULL; /* a hash_ent was found for this VC number */ vci2 = vci = hash_ent->info; @@ -366,30 +355,30 @@ x25_hash_get_proto(guint32 frame_secs, guint32 frame_usecs, guint16 vc) vci = vci->next; } /* we reached last record, and previous record has a non zero - * last frame time ==> no protocol known */ + * last frame time ==> no dissector */ if (!vci && (vci2->last_frame_secs || vci2->last_frame_usecs)) - return PROTO_UNKNOWN; + return NULL; /* we reached last record, and previous record has a zero last frame time * ==> dissector for previous frame has not been "stopped" by a Clear, etc */ if (!vci) { /* if the start time for vci2 is greater than our frame time - * ==> no protocol known */ + * ==> no dissector */ if (frame_secs < vci2->first_frame_secs || (frame_secs == vci2->first_frame_secs && frame_usecs < vci2->first_frame_usecs)) - return PROTO_UNKNOWN; + return NULL; else - return vci2->proto; + return vci2->dissect; } /* our frame time is before vci's end. Check if it is after vci's start */ if (frame_secs < vci->first_frame_secs || (frame_secs == vci->first_frame_secs && frame_usecs < vci->first_frame_usecs)) - return 0; + return NULL; else - return vci->proto; + return vci->dissect; } static char *clear_code(unsigned char code) @@ -1500,7 +1489,7 @@ dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) guint x25_pkt_len; int modulo; guint16 vc; - int proto; + dissector_handle_t dissect; gboolean toa; /* TOA/NPI address format */ guint16 bytes0_1; guint8 pkt_type; @@ -1759,7 +1748,7 @@ dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* ISO 8073 COTP */ x25_hash_add_proto_start(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs, - PROTO_OSITP); + ositp_handle); /* XXX - disssect the rest of the user data as COTP? That needs support for NCM TPDUs, etc. */ break; @@ -1768,7 +1757,7 @@ dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* ISO 8602 CLTP */ x25_hash_add_proto_start(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs, - PROTO_OSITP); + ositp_handle); break; } } else if (is_x_264 == 0) { @@ -1783,8 +1772,12 @@ dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } localoffset++; + /* + * What's the dissector handle for this SPI? + */ + dissect = dissector_get_port_handle(x25_subdissector_table, spi); x25_hash_add_proto_start(vc, pinfo->fd->abs_secs, - pinfo->fd->abs_usecs, spi); + pinfo->fd->abs_usecs, dissect); } if (localoffset < tvb_length(tvb)) { if (userdata_tree) { @@ -2147,45 +2140,29 @@ dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) return; } - /* search the protocol in the hash table */ - proto = x25_hash_get_proto(pinfo->fd->abs_secs, pinfo->fd->abs_usecs, vc); - switch (proto) { - - case PROTO_UNKNOWN: + /* search the dissector in the hash table */ + if ((dissect = x25_hash_get_dissect(pinfo->fd->abs_secs, pinfo->fd->abs_usecs, vc))) { + call_dissector(dissect, next_tvb, pinfo, tree); + } + else { /* Did the user suggest SNA-over-X.25? */ if (non_q_bit_is_sna) { x25_hash_add_proto_start(vc, pinfo->fd->abs_secs, - pinfo->fd->abs_usecs, PROTO_SNA); + pinfo->fd->abs_usecs, sna_handle); call_dissector(sna_handle, next_tvb, pinfo, tree); - return; } /* If the Call Req. has not been captured, and the payload begins with what appears to be an IP header, assume these packets carry IP */ - if (tvb_get_guint8(tvb, localoffset) == 0x45) { + else if (tvb_get_guint8(tvb, localoffset) == 0x45) { x25_hash_add_proto_start(vc, pinfo->fd->abs_secs, - pinfo->fd->abs_usecs, NLPID_IP); - if (dissector_try_port(x25_subdissector_table, NLPID_IP, - next_tvb, pinfo, tree)) - return; + pinfo->fd->abs_usecs, ip_handle); + call_dissector(ip_handle, next_tvb, pinfo, tree); } - break; - - case PROTO_SNA: - call_dissector(sna_handle, next_tvb, pinfo, tree); - return; - - case PROTO_OSITP: - call_dissector(ositp_handle, next_tvb, pinfo, tree); - return; - - default: - if (dissector_try_port(x25_subdissector_table, proto, - next_tvb, pinfo, tree)) - return; - break; + else { + call_dissector(data_handle,next_tvb, pinfo, tree); + } } - call_dissector(data_handle, next_tvb, pinfo, tree); } void @@ -2284,6 +2261,7 @@ proto_reg_handoff_x25(void) /* * Get handles for various dissectors. */ + ip_handle = find_dissector("ip"); ositp_handle = find_dissector("ositp"); sna_handle = find_dissector("sna"); qllc_handle = find_dissector("qllc");