From d2ac9458d31eb6a8cf012fa0927091bd4c33d275 Mon Sep 17 00:00:00 2001 From: guy Date: Fri, 8 Nov 2002 01:00:07 +0000 Subject: Allow more than one circuit with the same circuit ID; a circuit has a starting and ending frame number, and circuits with the same circuit ID are sorted by the starting frame number (the last circuit can have 0 as the ending frame number, meaning "unknown"), and, when looking up a circuit, we take a frame number as an argument and return the circuit that includes that frame. Add a new circuit ID type for X.25 virtual circuits, and use the circuit mechanism to keep track of the dissector for an X.25 virtual circuit rather than having a private mechanism. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@6580 f5534014-38df-0310-8fa8-9805f1628bb7 --- packet-x25.c | 272 +++++++++++------------------------------------------------ 1 file changed, 47 insertions(+), 225 deletions(-) (limited to 'packet-x25.c') diff --git a/packet-x25.c b/packet-x25.c index 035d107f9b..ac876fa95c 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.70 2002/09/01 14:30:30 oabad Exp $ + * $Id: packet-x25.c,v 1.71 2002/11/08 01:00:04 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -33,6 +33,7 @@ #include #include "llcsaps.h" #include +#include #include "prefs.h" #include "nlpid.h" #include "x264_prt_id.h" @@ -170,219 +171,48 @@ static gboolean non_q_bit_is_sna = FALSE; static dissector_table_t x25_subdissector_table; static heur_dissector_list_t x25_heur_subdissector_list; -/* - * 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) - * 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 - * is received - */ -typedef struct _vc_info { - guint32 first_frame_secs, first_frame_usecs; - guint32 last_frame_secs, last_frame_usecs; - dissector_handle_t dissect; - struct _vc_info *next; -} vc_info; - -/* - * the hash table will contain linked lists of global_vc_info - * each global_vc_info struct contains : - * the VC number (the hash table is indexed with VC % 64) - * a linked list of vc_info - */ -typedef struct _global_vc_info { - int vc_num; - vc_info *info; - struct _global_vc_info *next; -} global_vc_info; - -static global_vc_info *hash_table[64]; - static void -free_vc_info(vc_info *pt) +x25_hash_add_proto_start(guint16 vc, guint32 frame, dissector_handle_t dissect) { - vc_info *vci = pt; + circuit_t *circuit; - while (pt) { - vci = pt; - pt = pt->next; - g_free(vci); + /* + * Is there already a circuit with this VC number? + */ + circuit = find_circuit(CT_X25, vc, frame); + if (circuit != NULL) { + /* + * Yes - close it, as we're creating a new one. + */ + close_circuit(circuit, frame - 1); } -} -static void -reinit_x25_hashtable(void) -{ - int i; + /* + * Set up a new circuit. + */ + circuit = circuit_new(CT_X25, vc, frame); - for (i=0; i<64; i++) { - if (hash_table[i]) /* not NULL ==> free */ - { - global_vc_info *hash_ent, *hash_ent2; - hash_ent2 = hash_ent = hash_table[i]; - while (hash_ent) - { - hash_ent2 = hash_ent; - hash_ent = hash_ent->next; - free_vc_info(hash_ent2->info); - g_free(hash_ent2); - } - hash_table[i]=0; - } - } + /* + * Set its dissector. + */ + circuit_set_dissector(circuit, dissect); } static void -x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs, - dissector_handle_t dissect) +x25_hash_add_proto_end(guint16 vc, guint32 frame) { - int idx = vc % 64; - global_vc_info *hash_ent; - global_vc_info *hash_ent2; - - if (hash_table[idx] == 0) - { - hash_ent = (global_vc_info *)g_malloc(sizeof(global_vc_info)); - if (!hash_ent) { - fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n"); - exit(1); - } - hash_ent->vc_num = vc; - hash_ent->next=0; - hash_ent->info = (vc_info *)g_malloc(sizeof(vc_info)); - if (!hash_ent->info) { - fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n"); - exit(1); - } - hash_ent->info->first_frame_secs = frame_secs; - 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->dissect = dissect; - hash_ent->info->next = 0; - hash_table[idx] = hash_ent; - } - else - { - hash_ent2 = hash_ent = hash_table[idx]; - /* search an entry with the same VC number */ - while (hash_ent != NULL && hash_ent->vc_num != vc) { - hash_ent2 = hash_ent; - hash_ent = hash_ent->next; - } - if (hash_ent != NULL) /* hash_ent->vc_num == vc */ - { - vc_info *vci = hash_ent->info; - while (vci->next) vci = vci->next; /* last element */ - if (vci->dissect == dissect) { - vci->last_frame_secs = 0; - vci->last_frame_usecs = 0; - } - else { - vci->next = (vc_info *)g_malloc(sizeof(vc_info)); - if (vci->next == 0) { - fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n"); - exit(1); - } - vci->next->first_frame_secs = frame_secs; - vci->next->first_frame_usecs = frame_usecs; - vci->next->last_frame_secs = 0; - vci->next->last_frame_usecs = 0; - vci->next->dissect = dissect; - vci->next->next = 0; - } - } - else /* new vc number */ - { - hash_ent2->next = (global_vc_info *)g_malloc(sizeof(global_vc_info)); - if (!hash_ent2->next) { - fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n"); - exit(1); - } - hash_ent2->next->info = (vc_info *)g_malloc(sizeof(vc_info)); - if (!hash_ent2->next->info) { - fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n"); - exit(1); - } - hash_ent2->next->info->first_frame_secs = frame_secs; - 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->dissect = dissect; - hash_ent2->next->info->next = 0; - } - } -} - -static void -x25_hash_add_proto_end(guint16 vc, guint32 frame_secs, guint32 frame_usecs) -{ - global_vc_info *hash_ent = hash_table[vc%64]; - vc_info *vci; - - if (!hash_ent) return; - while(hash_ent->vc_num != vc) hash_ent = hash_ent->next; - if (!hash_ent) return; - - vci = hash_ent->info; - while (vci->next) vci = vci->next; - vci->last_frame_secs = frame_secs; - vci->last_frame_usecs = frame_usecs; -} - -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 NULL; - - while (hash_ent && hash_ent->vc_num != vc) - hash_ent = hash_ent->next; - if (!hash_ent) - return NULL; - - /* a hash_ent was found for this VC number */ - vci2 = vci = hash_ent->info; - - /* looking for an entry matching our frame time */ - while (vci && (vci->last_frame_secs < frame_secs || - (vci->last_frame_secs == frame_secs && - vci->last_frame_usecs < frame_usecs))) { - vci2 = vci; - vci = vci->next; - } - /* we reached last record, and previous record has a non zero - * last frame time ==> no dissector */ - if (!vci && (vci2->last_frame_secs || vci2->last_frame_usecs)) - 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 dissector */ - if (frame_secs < vci2->first_frame_secs || - (frame_secs == vci2->first_frame_secs && - frame_usecs < vci2->first_frame_usecs)) - return NULL; - else - 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 NULL; - else - return vci->dissect; + circuit_t *circuit; + + /* + * Try to find the circuit. + */ + circuit = find_circuit(CT_X25, vc, frame); + + /* + * If we succeeded, close it. + */ + if (circuit != NULL) + close_circuit(circuit, frame); } static char *clear_code(unsigned char code) @@ -1585,6 +1415,9 @@ dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, modulo = ((bytes0_1 & 0x2000) ? 128 : 8); vc = (int)(bytes0_1 & 0x0FFF); + pinfo->ctype = CT_X25; + pinfo->circuit_id = vc; + if (bytes0_1 & 0x8000) toa = TRUE; else toa = FALSE; @@ -1842,18 +1675,14 @@ dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, case PRT_ID_ISO_8073: /* ISO 8073 COTP */ - x25_hash_add_proto_start(vc, pinfo->fd->abs_secs, - pinfo->fd->abs_usecs, - ositp_handle); + x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle); /* XXX - disssect the rest of the user data as COTP? That needs support for NCM TPDUs, etc. */ break; case PRT_ID_ISO_8602: /* ISO 8602 CLTP */ - x25_hash_add_proto_start(vc, pinfo->fd->abs_secs, - pinfo->fd->abs_usecs, - ositp_handle); + x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle); break; } } else if (is_x_264 == 0) { @@ -1872,8 +1701,7 @@ dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, * 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, dissect); + x25_hash_add_proto_start(vc, pinfo->fd->num, dissect); } if (localoffset < tvb_length(tvb)) { if (userdata_tree) { @@ -1950,7 +1778,7 @@ dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vc, clear_code(tvb_get_guint8(tvb, 3)), clear_diag(tvb_get_guint8(tvb, 4))); } - x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs); + x25_hash_add_proto_end(vc, pinfo->fd->num); if (x25_tree) { proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1); proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, @@ -2038,7 +1866,7 @@ dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, short_name, vc, reset_code(tvb_get_guint8(tvb, 3)), (int)tvb_get_guint8(tvb, 4)); } - x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs); + x25_hash_add_proto_end(vc, pinfo->fd->num); if (x25_tree) { proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1); proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1, @@ -2296,18 +2124,14 @@ dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, return; } - /* search the dissector in the hash table */ - if ((dissect = x25_hash_get_dissect(pinfo->fd->abs_secs, pinfo->fd->abs_usecs, vc))) { - /* Found it in the hash table; use it. */ - call_dissector(dissect, next_tvb, pinfo, tree); - return; - } + /* See if there's already a dissector for this circuit. */ + if (try_circuit_dissector(CT_X25, vc, pinfo->fd->num, next_tvb, pinfo, tree)) + return; /* found it and dissected it */ /* Did the user suggest SNA-over-X.25? */ if (non_q_bit_is_sna) { /* Yes - dissect it as SNA. */ - x25_hash_add_proto_start(vc, pinfo->fd->abs_secs, - pinfo->fd->abs_usecs, sna_handle); + x25_hash_add_proto_start(vc, pinfo->fd->num, sna_handle); call_dissector(sna_handle, next_tvb, pinfo, tree); return; } @@ -2316,8 +2140,7 @@ dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, with what appears to be an IP header, assume these packets carry IP */ if (tvb_get_guint8(tvb, localoffset) == 0x45) { - x25_hash_add_proto_start(vc, pinfo->fd->abs_secs, - pinfo->fd->abs_usecs, ip_handle); + x25_hash_add_proto_start(vc, pinfo->fd->num, ip_handle); call_dissector(ip_handle, next_tvb, pinfo, tree); return; } @@ -2431,7 +2254,6 @@ proto_register_x25(void) proto_x25 = proto_register_protocol ("X.25", "X.25", "x.25"); proto_register_field_array (proto_x25, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); - register_init_routine(&reinit_x25_hashtable); x25_subdissector_table = register_dissector_table("x.25.spi", "X.25 secondary protocol identifier", FT_UINT8, BASE_HEX); -- cgit v1.2.3