aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2013-03-22 23:59:54 +0000
committerGuy Harris <guy@alum.mit.edu>2013-03-22 23:59:54 +0000
commita2414d8909088ddb40c907886e725993e6baecb5 (patch)
tree53f0ebac8baa171f4317c7eb502a354da8596c72 /epan
parent3295912210fa1a8d7d0b1a18aa7c100f27905ed1 (diff)
Don't wire into the reassembly code the notion that reassemblies should
be done on flows from one address to another; reassembly for protocols running atop TCP should be done on flows from one TCP endpoint to another. We do this by: adding "reassembly table" as a data structure; associating hash tables for both in-progress reassemblies and completed reassemblies with that data structure (currently, not all reassemblies use the latter; they might keep completed reassemblies in the first table); having functions to create and destroy keys in that table; offering standard routines for doing address-based and address-and-port-based flow processing, so that dissectors not needing their own specialized flow processing can just use them. This fixes some mis-reassemblies of NIS YPSERV YPALL responses (where the second YPALL response is processed as if it were a continuation of a previous response between different endpoints, even though said response is already reassembled), and also allows the DCE RPC-specific stuff to be moved out of epan/reassembly.c into the DCE RPC dissector. svn path=/trunk/; revision=48491
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-6lowpan.c15
-rw-r--r--epan/dissectors/packet-atalk.c12
-rw-r--r--epan/dissectors/packet-bacapp.c16
-rw-r--r--epan/dissectors/packet-batadv.c21
-rw-r--r--epan/dissectors/packet-ber.c12
-rw-r--r--epan/dissectors/packet-btobex.c23
-rw-r--r--epan/dissectors/packet-capwap.c17
-rw-r--r--epan/dissectors/packet-cell_broadcast.c11
-rw-r--r--epan/dissectors/packet-clnp.c13
-rw-r--r--epan/dissectors/packet-dcerpc.c154
-rw-r--r--epan/dissectors/packet-dcm.c14
-rw-r--r--epan/dissectors/packet-dcp-etsi.c19
-rw-r--r--epan/dissectors/packet-dnp.c12
-rw-r--r--epan/dissectors/packet-dtls.c12
-rw-r--r--epan/dissectors/packet-dtn.c15
-rw-r--r--epan/dissectors/packet-dvbci.c26
-rw-r--r--epan/dissectors/packet-eap.c13
-rw-r--r--epan/dissectors/packet-fc.c10
-rw-r--r--epan/dissectors/packet-gsm_cbch.c17
-rw-r--r--epan/dissectors/packet-gsm_sms.c13
-rw-r--r--epan/dissectors/packet-gsm_sms_ud.c14
-rw-r--r--epan/dissectors/packet-gssapi.c22
-rw-r--r--epan/dissectors/packet-hci_usb.c13
-rw-r--r--epan/dissectors/packet-iax2.c14
-rw-r--r--epan/dissectors/packet-idmp.c11
-rw-r--r--epan/dissectors/packet-ieee80211.c28
-rw-r--r--epan/dissectors/packet-ip.c12
-rw-r--r--epan/dissectors/packet-ipv6.c12
-rw-r--r--epan/dissectors/packet-isakmp.c13
-rw-r--r--epan/dissectors/packet-isup.c20
-rw-r--r--epan/dissectors/packet-lapdm.c13
-rw-r--r--epan/dissectors/packet-lapsat.c14
-rw-r--r--epan/dissectors/packet-ltp.c17
-rw-r--r--epan/dissectors/packet-mp2t.c16
-rw-r--r--epan/dissectors/packet-mq.c11
-rw-r--r--epan/dissectors/packet-mux27010.c14
-rw-r--r--epan/dissectors/packet-ncp-int.h2
-rw-r--r--epan/dissectors/packet-ncp.c3
-rw-r--r--epan/dissectors/packet-ncp2222.inc13
-rw-r--r--epan/dissectors/packet-ndmp.c13
-rw-r--r--epan/dissectors/packet-ndps.c11
-rw-r--r--epan/dissectors/packet-netbios.c18
-rw-r--r--epan/dissectors/packet-openvpn.c11
-rw-r--r--epan/dissectors/packet-ositp.c22
-rw-r--r--epan/dissectors/packet-p_mul.c18
-rw-r--r--epan/dissectors/packet-pop.c13
-rw-r--r--epan/dissectors/packet-ppi.c18
-rw-r--r--epan/dissectors/packet-q931.c19
-rw-r--r--epan/dissectors/packet-reload.c13
-rw-r--r--epan/dissectors/packet-rpc.c21
-rw-r--r--epan/dissectors/packet-rtp.c19
-rw-r--r--epan/dissectors/packet-rtse.c20
-rw-r--r--epan/dissectors/packet-sccp.c35
-rw-r--r--epan/dissectors/packet-scsi.c13
-rw-r--r--epan/dissectors/packet-ses.c14
-rw-r--r--epan/dissectors/packet-smb-pipe.c33
-rw-r--r--epan/dissectors/packet-smb.c19
-rw-r--r--epan/dissectors/packet-smtp.c23
-rw-r--r--epan/dissectors/packet-sna.c17
-rw-r--r--epan/dissectors/packet-sndcp.c14
-rw-r--r--epan/dissectors/packet-ssl.c18
-rw-r--r--epan/dissectors/packet-t38.c67
-rw-r--r--epan/dissectors/packet-tcp.c23
-rw-r--r--epan/dissectors/packet-tds.c17
-rw-r--r--epan/dissectors/packet-teamspeak2.c9
-rw-r--r--epan/dissectors/packet-tipc.c25
-rw-r--r--epan/dissectors/packet-usb-audio.c21
-rw-r--r--epan/dissectors/packet-wai.c14
-rw-r--r--epan/dissectors/packet-wtp.c9
-rw-r--r--epan/dissectors/packet-x25.c14
-rw-r--r--epan/dissectors/packet-zbee-aps.c16
-rw-r--r--epan/reassemble.c926
-rw-r--r--epan/reassemble.h176
-rw-r--r--epan/stream.c13
74 files changed, 1294 insertions, 1145 deletions
diff --git a/epan/dissectors/packet-6lowpan.c b/epan/dissectors/packet-6lowpan.c
index d419276a50..f01da072dd 100644
--- a/epan/dissectors/packet-6lowpan.c
+++ b/epan/dissectors/packet-6lowpan.c
@@ -412,8 +412,7 @@ static const fragment_items lowpan_frag_items = {
"6LoWPAN fragments"
};
-static GHashTable *lowpan_fragment_table = NULL;
-static GHashTable *lowpan_reassembled_table = NULL;
+static reassembly_table lowpan_reassembly_table;
static GHashTable *lowpan_context_table = NULL;
/* Link-Local prefix used by 6LoWPAN (FF80::/10) */
@@ -2325,8 +2324,8 @@ dissect_6lowpan_frag_first(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
tvb_set_reported_length(frag_tvb, frag_size);
save_fragmented = pinfo->fragmented;
pinfo->fragmented = TRUE;
- frag_data = fragment_add_check(frag_tvb, 0, pinfo, dgram_tag,
- lowpan_fragment_table, lowpan_reassembled_table,
+ frag_data = fragment_add_check(&lowpan_reassembly_table,
+ frag_tvb, 0, pinfo, dgram_tag, NULL,
0, frag_size, (frag_size < dgram_size));
/* Attempt reassembly. */
@@ -2417,8 +2416,8 @@ dissect_6lowpan_frag_middle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Add this datagram to the fragment table. */
save_fragmented = pinfo->fragmented;
pinfo->fragmented = TRUE;
- frag_data = fragment_add_check(tvb, offset, pinfo, dgram_tag,
- lowpan_fragment_table, lowpan_reassembled_table,
+ frag_data = fragment_add_check(&lowpan_reassembly_table,
+ tvb, offset, pinfo, dgram_tag, NULL,
dgram_offset, frag_size, ((dgram_offset + frag_size) < dgram_size));
/* Attempt reassembly. */
@@ -2784,8 +2783,8 @@ static void
proto_init_6lowpan(void)
{
/* Initialize the fragment reassembly table. */
- fragment_table_init(&lowpan_fragment_table);
- reassembled_table_init(&lowpan_reassembled_table);
+ reassembly_table_init(&lowpan_reassembly_table,
+ &addresses_reassembly_table_functions);
/* Initialize the context table. */
if (lowpan_context_table)
diff --git a/epan/dissectors/packet-atalk.c b/epan/dissectors/packet-atalk.c
index 39550718c1..273f211599 100644
--- a/epan/dissectors/packet-atalk.c
+++ b/epan/dissectors/packet-atalk.c
@@ -49,8 +49,7 @@ void proto_register_atalk(void);
void proto_reg_handoff_atalk(void);
/* Tables for reassembly of fragments. */
-static GHashTable *atp_fragment_table = NULL;
-static GHashTable *atp_reassembled_table = NULL;
+static reassembly_table atp_reassembly_table;
/* desegmentation of ATP */
static gboolean atp_defragment = TRUE;
@@ -896,9 +895,8 @@ dissect_atp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
if (frag_number != 0)
hdr += 4; /* asp header */
len = tvb_reported_length_remaining(tvb, hdr);
- fd_head = fragment_add_seq_check(tvb, hdr, pinfo, tid,
- atp_fragment_table,
- atp_reassembled_table,
+ fd_head = fragment_add_seq_check(&atp_reassembly_table,
+ tvb, hdr, pinfo, tid, NULL,
frag_number,
len,
more_fragment);
@@ -1864,8 +1862,8 @@ static void
atp_init(void)
{
/* fragment */
- fragment_table_init(&atp_fragment_table);
- reassembled_table_init(&atp_reassembled_table);
+ reassembly_table_init(&atp_reassembly_table,
+ &addresses_reassembly_table_functions);
/* bitmap */
if (atp_request_hash)
g_hash_table_destroy(atp_request_hash);
diff --git a/epan/dissectors/packet-bacapp.c b/epan/dissectors/packet-bacapp.c
index 822493366e..4530c550da 100644
--- a/epan/dissectors/packet-bacapp.c
+++ b/epan/dissectors/packet-bacapp.c
@@ -2329,9 +2329,8 @@ uni_to_string(char * data, gsize str_length, char *dest_buf);
/* <<<< formerly bacapp.h */
-/* some hashes for segmented messages */
-static GHashTable *msg_fragment_table = NULL;
-static GHashTable *msg_reassembled_table = NULL;
+/* reassembly table for segmented messages */
+static reassembly_table msg_reassembly_table;
/* some necessary forward function prototypes */
static guint
@@ -10804,10 +10803,11 @@ dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
pinfo->fragmented = TRUE;
- frag_msg = fragment_add_seq_check(tvb, data_offset, pinfo,
+ frag_msg = fragment_add_seq_check(&msg_reassembly_table,
+ tvb, data_offset,
+ pinfo,
bacapp_invoke_id, /* ID for fragments belonging together */
- msg_fragment_table, /* list of message fragments */
- msg_reassembled_table, /* list of reassembled messages */
+ NULL,
bacapp_seqno, /* fragment sequence number */
tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
@@ -10846,8 +10846,8 @@ dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void
bacapp_init_routine(void)
{
- fragment_table_init(&msg_fragment_table);
- reassembled_table_init(&msg_reassembled_table);
+ reassembly_table_init(&msg_reassembly_table,
+ &addresses_reassembly_table_functions);
}
static guint32
diff --git a/epan/dissectors/packet-batadv.c b/epan/dissectors/packet-batadv.c
index 8e3cf01b72..357ab2d69c 100644
--- a/epan/dissectors/packet-batadv.c
+++ b/epan/dissectors/packet-batadv.c
@@ -581,8 +581,7 @@ static int batadv_tap = -1;
static int batadv_follow_tap = -1;
/* segmented messages */
-static GHashTable *msg_fragment_table = NULL;
-static GHashTable *msg_reassembled_table = NULL;
+static reassembly_table msg_reassembly_table;
static unsigned int batadv_ethertype = ETH_P_BATMAN;
@@ -2320,10 +2319,9 @@ static void dissect_batadv_unicast_frag_v12(tvbuff_t *tvb, packet_info *pinfo, p
length_remaining = tvb_length_remaining(tvb, offset);
if (length_remaining < 0)
length_remaining = 0;
- frag_msg = fragment_add_seq_check(tvb, offset, pinfo,
- unicast_frag_packeth->seqno + head,
- msg_fragment_table,
- msg_reassembled_table,
+ frag_msg = fragment_add_seq_check(&msg_reassembly_table,
+ tvb, offset,
+ pinfo, unicast_frag_packeth->seqno + head, NULL,
1 - head,
length_remaining,
head);
@@ -2435,10 +2433,9 @@ static void dissect_batadv_unicast_frag_v14(tvbuff_t *tvb, packet_info *pinfo, p
length_remaining = tvb_length_remaining(tvb, offset);
if (length_remaining < 0)
length_remaining = 0;
- frag_msg = fragment_add_seq_check(tvb, offset, pinfo,
- unicast_frag_packeth->seqno + head,
- msg_fragment_table,
- msg_reassembled_table,
+ frag_msg = fragment_add_seq_check(&msg_reassembly_table,
+ tvb, offset,
+ pinfo, unicast_frag_packeth->seqno + head, NULL,
1 - head,
length_remaining,
head);
@@ -3159,8 +3156,8 @@ static void dissect_batadv_roam_adv_v14(tvbuff_t *tvb, packet_info *pinfo, proto
static void batadv_init_routine(void)
{
- fragment_table_init(&msg_fragment_table);
- reassembled_table_init(&msg_reassembled_table);
+ reassembly_table_init(&msg_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void proto_register_batadv(void)
diff --git a/epan/dissectors/packet-ber.c b/epan/dissectors/packet-ber.c
index 5197cce706..0428cb9a1a 100644
--- a/epan/dissectors/packet-ber.c
+++ b/epan/dissectors/packet-ber.c
@@ -1323,12 +1323,11 @@ printf("dissect BER length %d, offset %d (remaining %d)\n", tmp_length, offset,
return offset;
}
-static GHashTable *octet_segment_table = NULL;
-static GHashTable *octet_reassembled_table = NULL;
+static reassembly_table octet_segment_reassembly_table;
static void ber_defragment_init(void) {
- fragment_table_init(&octet_segment_table);
- reassembled_table_init(&octet_reassembled_table);
+ reassembly_table_init(&octet_segment_reassembly_table,
+ &addresses_reassembly_table_functions);
}
static int
@@ -1394,9 +1393,8 @@ reassemble_octet_string(asn1_ctx_t *actx, proto_tree *tree, gint hf_id, tvbuff_t
/* Don't cause an assertion in the reassembly code. */
THROW(ReportedBoundsError);
}
- fd_head = fragment_add_seq_next(next_tvb, 0, actx->pinfo, dst_ref,
- octet_segment_table,
- octet_reassembled_table,
+ fd_head = fragment_add_seq_next(&octet_segment_reassembly_table,
+ next_tvb, 0, actx->pinfo, dst_ref, NULL,
tvb_length(next_tvb),
fragment);
diff --git a/epan/dissectors/packet-btobex.c b/epan/dissectors/packet-btobex.c
index 9877b269cd..fbdbdc24d3 100644
--- a/epan/dissectors/packet-btobex.c
+++ b/epan/dissectors/packet-btobex.c
@@ -188,8 +188,7 @@ static int hf_btobex_reassembled_length = -1;
static gint ett_btobex_fragment = -1;
static gint ett_btobex_fragments = -1;
-static GHashTable *fragment_table;
-static GHashTable *reassembled_table;
+static reassembly_table btobex_reassembly_table;
static const fragment_items btobex_frag_items = {
&ett_btobex_fragment,
@@ -552,8 +551,8 @@ void proto_reg_handoff_btobex(void);
static void
defragment_init(void)
{
- fragment_table_init(&fragment_table);
- reassembled_table_init(&reassembled_table);
+ reassembly_table_init(&btobex_reassembly_table,
+ &addresses_reassembly_table_functions);
}
static int
@@ -1327,10 +1326,11 @@ dissect_btobex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
complete = FALSE;
- if (fragment_get(pinfo, pinfo->p2p_dir, fragment_table)) {
+ if (fragment_get(&btobex_reassembly_table, pinfo, pinfo->p2p_dir, NULL)) {
/* not the first fragment */
- frag_msg = fragment_add_seq_next(tvb, 0, pinfo, pinfo->p2p_dir,
- fragment_table, reassembled_table, tvb_length(tvb), TRUE);
+ frag_msg = fragment_add_seq_next(&btobex_reassembly_table,
+ tvb, 0, pinfo, pinfo->p2p_dir, NULL,
+ tvb_length(tvb), TRUE);
new_tvb = process_reassembled_data(tvb, 0, pinfo,
"Reassembled Obex packet", frag_msg, &btobex_frag_items, NULL, tree);
@@ -1343,10 +1343,13 @@ dissect_btobex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (tvb_get_ntohs(tvb, offset+1) > (no_of_segments * tvb_length(tvb)))
no_of_segments++;
- frag_msg = fragment_add_seq_next(tvb, 0, pinfo, pinfo->p2p_dir,
- fragment_table, reassembled_table, tvb_length(tvb), TRUE);
+ frag_msg = fragment_add_seq_next(&btobex_reassembly_table,
+ tvb, 0, pinfo, pinfo->p2p_dir, NULL,
+ tvb_length(tvb), TRUE);
- fragment_set_tot_len(pinfo, pinfo->p2p_dir, fragment_table, no_of_segments-1);
+ fragment_set_tot_len(&btobex_reassembly_table,
+ pinfo, pinfo->p2p_dir, NULL,
+ no_of_segments-1);
new_tvb = process_reassembled_data(tvb, 0, pinfo,
"Reassembled Obex packet", frag_msg, &btobex_frag_items, NULL, tree);
diff --git a/epan/dissectors/packet-capwap.c b/epan/dissectors/packet-capwap.c
index 80b081d83b..c152aa20bb 100644
--- a/epan/dissectors/packet-capwap.c
+++ b/epan/dissectors/packet-capwap.c
@@ -43,8 +43,7 @@ static gboolean global_capwap_draft_8_cisco = FALSE;
static gboolean global_capwap_reassemble = TRUE;
static gboolean global_capwap_swap_frame_control = TRUE;
-static GHashTable *capwap_fragment_table = NULL;
-static GHashTable *capwap_reassembled_table = NULL;
+static reassembly_table capwap_reassembly_table;
/* TODO LIST !
* add decryption of DLTS Message
@@ -705,8 +704,8 @@ static const value_string last_failure_type_vals[] = {
static void capwap_reassemble_init(void)
{
- fragment_table_init(&capwap_fragment_table);
- reassembled_table_init(&capwap_reassembled_table);
+ reassembly_table_init(&capwap_reassembly_table,
+ &addresses_reassembly_table_functions);
}
static void
@@ -1405,9 +1404,8 @@ dissect_capwap_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
pinfo->fragmented = TRUE;
- frag_msg = fragment_add_check(tvb, offset, pinfo,fragment_id,
- capwap_fragment_table,
- capwap_reassembled_table,
+ frag_msg = fragment_add_check(&capwap_reassembly_table,
+ tvb, offset, pinfo, fragment_id, NULL,
fragment_offset,
len_rem,
fragment_more);
@@ -1493,9 +1491,8 @@ dissect_capwap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
pinfo->fragmented = TRUE;
- frag_msg = fragment_add_check(tvb, offset, pinfo,fragment_id,
- capwap_fragment_table,
- capwap_reassembled_table,
+ frag_msg = fragment_add_check(&capwap_reassembly_table,
+ tvb, offset, pinfo, fragment_id, NULL,
fragment_offset,
len_rem,
fragment_more);
diff --git a/epan/dissectors/packet-cell_broadcast.c b/epan/dissectors/packet-cell_broadcast.c
index c6c0821317..61f6536618 100644
--- a/epan/dissectors/packet-cell_broadcast.c
+++ b/epan/dissectors/packet-cell_broadcast.c
@@ -138,8 +138,7 @@ static gint ett_gsm_cbs_page_content = -1;
static gint ett_gsm_cbs_pages = -1;
/* reassembly of GSM multi-page messages */
-static GHashTable *gsm_cbs_page_table = NULL;
-static GHashTable *gsm_cbs_message_table = NULL;
+static reassembly_table gsm_cbs_reassembly_table;
/* Structure needed for the fragmentation routines in reassemble.c */
static const fragment_items gsm_page_items = {
@@ -163,8 +162,8 @@ static const fragment_items gsm_page_items = {
static void gsm_cbs_message_reassembly_init(void)
{
- fragment_table_init(&gsm_cbs_page_table);
- reassembled_table_init(&gsm_cbs_message_table);
+ reassembly_table_init(&gsm_cbs_reassembly_table,
+ &addresses_reassembly_table_functions);
}
guint16 dissect_cbs_serial_number(tvbuff_t *tvb, proto_tree *tree, guint16 offset)
@@ -357,8 +356,8 @@ dissect_gsm_cell_broadcast(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* now we have a complete page, try to concatenate the full message */
/* we can use the serial number and message ID as keys, as they are the same for all pages of a message */
msg_key = (serial_number << 16) + message_id;
- frag_data = fragment_add_check(cbs_page_tvb, 0, pinfo, msg_key,
- gsm_cbs_page_table, gsm_cbs_message_table,
+ frag_data = fragment_add_check(&gsm_cbs_reassembly_table,
+ cbs_page_tvb, 0, pinfo, msg_key, NULL,
((current_page -1) * GSM_CBS_PAGE_SIZE),
GSM_CBS_PAGE_SIZE, (current_page!=total_pages));
cbs_msg_tvb = process_reassembled_data(cbs_page_tvb, 0, pinfo, "Reassembled Cell Broadcast message",
diff --git a/epan/dissectors/packet-clnp.c b/epan/dissectors/packet-clnp.c
index 8cd2791d94..b6cd15b6dd 100644
--- a/epan/dissectors/packet-clnp.c
+++ b/epan/dissectors/packet-clnp.c
@@ -182,8 +182,7 @@ static heur_dissector_list_t clnp_heur_subdissector_list;
/*
* Reassembly of CLNP.
*/
-static GHashTable *clnp_segment_table = NULL;
-static GHashTable *clnp_reassembled_table = NULL;
+static reassembly_table clnp_reassembly_table;
/* options */
static guint tp_nsap_selector = NSEL_TP;
@@ -435,9 +434,9 @@ dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tvb_bytes_exist(tvb, offset, segment_length - cnf_hdr_len) &&
segment_length > cnf_hdr_len &&
cksum_status != CKSUM_NOT_OK) {
- fd_head = fragment_add_check(tvb, offset, pinfo, du_id, clnp_segment_table,
- clnp_reassembled_table, segment_offset,
- segment_length - cnf_hdr_len,
+ fd_head = fragment_add_check(&clnp_reassembly_table,
+ tvb, offset, pinfo, du_id, NULL,
+ segment_offset, segment_length - cnf_hdr_len,
cnf_type & CNF_MORE_SEGS);
next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled CLNP",
@@ -546,8 +545,8 @@ dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void
clnp_reassemble_init(void)
{
- fragment_table_init(&clnp_segment_table);
- reassembled_table_init(&clnp_reassembled_table);
+ reassembly_table_init(&clnp_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void
diff --git a/epan/dissectors/packet-dcerpc.c b/epan/dissectors/packet-dcerpc.c
index 479d744d1d..c06344ab65 100644
--- a/epan/dissectors/packet-dcerpc.c
+++ b/epan/dissectors/packet-dcerpc.c
@@ -646,16 +646,127 @@ static gboolean dcerpc_cn_desegment = TRUE;
are coming in out of sequence, but that will hurt in a lot of other places as well.
*/
static gboolean dcerpc_reassemble = TRUE;
-static GHashTable *dcerpc_co_fragment_table = NULL;
-static GHashTable *dcerpc_co_reassemble_table = NULL;
-static GHashTable *dcerpc_cl_reassemble_table = NULL;
+static reassembly_table dcerpc_co_reassembly_table;
+static reassembly_table dcerpc_cl_reassembly_table;
+
+typedef struct _dcerpc_fragment_key {
+ address src;
+ address dst;
+ guint32 id;
+ e_uuid_t act_id;
+} dcerpc_fragment_key;
+
+static guint
+dcerpc_fragment_hash(gconstpointer k)
+{
+ const dcerpc_fragment_key* key = (const dcerpc_fragment_key*) k;
+ guint hash_val;
+
+ hash_val = 0;
+
+ hash_val += key->id;
+ hash_val += key->act_id.Data1;
+ hash_val += key->act_id.Data2 << 16;
+ hash_val += key->act_id.Data3;
+
+ return hash_val;
+}
+
+static gint
+dcerpc_fragment_equal(gconstpointer k1, gconstpointer k2)
+{
+ const dcerpc_fragment_key* key1 = (const dcerpc_fragment_key*) k1;
+ const dcerpc_fragment_key* key2 = (const dcerpc_fragment_key*) k2;
+
+ /*key.id is the first item to compare since item is most
+ likely to differ between sessions, thus shortcircuiting
+ the comparison of addresses.
+ */
+ return (((key1->id == key2->id)
+ && (ADDRESSES_EQUAL(&key1->src, &key2->src))
+ && (ADDRESSES_EQUAL(&key1->dst, &key2->dst))
+ && (memcmp (&key1->act_id, &key2->act_id, sizeof (e_uuid_t)) == 0))
+ ? TRUE : FALSE);
+}
+
+/* allocate a persistent dcerpc fragment key to insert in the hash */
+static void *
+dcerpc_fragment_temporary_key(const packet_info *pinfo, const guint32 id,
+ const void *data)
+{
+ dcerpc_fragment_key *key = g_slice_new(dcerpc_fragment_key);
+ e_dce_dg_common_hdr_t *hdr = (e_dce_dg_common_hdr_t *)data;
+
+ key->src = pinfo->src;
+ key->dst = pinfo->dst;
+ key->id = id;
+ key->act_id = hdr->act_id;
+
+ return key;
+}
+
+/* allocate a persistent dcerpc fragment key to insert in the hash */
+static void *
+dcerpc_fragment_persistent_key(const packet_info *pinfo, const guint32 id,
+ const void *data)
+{
+ dcerpc_fragment_key *key = g_slice_new(dcerpc_fragment_key);
+ e_dce_dg_common_hdr_t *hdr = (e_dce_dg_common_hdr_t *)data;
+
+ COPY_ADDRESS(&key->src, &pinfo->src);
+ COPY_ADDRESS(&key->dst, &pinfo->dst);
+ key->id = id;
+ key->act_id = hdr->act_id;
+
+ return key;
+}
+
+static void
+dcerpc_fragment_free_temporary_key(gpointer ptr)
+{
+ dcerpc_fragment_key *key = (dcerpc_fragment_key *)ptr;
+
+ if(key)
+ g_slice_free(dcerpc_fragment_key, key);
+}
+
+static void
+dcerpc_fragment_free_persistent_key(gpointer ptr)
+{
+ dcerpc_fragment_key *key = (dcerpc_fragment_key *)ptr;
+
+ if(key){
+ /*
+ * Free up the copies of the addresses from the old key.
+ */
+ g_free((gpointer)key->src.data);
+ g_free((gpointer)key->dst.data);
+
+ g_slice_free(dcerpc_fragment_key, key);
+ }
+}
+
+static const reassembly_table_functions dcerpc_cl_reassembly_table_functions = {
+ dcerpc_fragment_hash,
+ dcerpc_fragment_equal,
+ dcerpc_fragment_temporary_key,
+ dcerpc_fragment_persistent_key,
+ dcerpc_fragment_free_temporary_key,
+ dcerpc_fragment_free_persistent_key
+};
static void
dcerpc_reassemble_init(void)
{
- fragment_table_init(&dcerpc_co_fragment_table);
- reassembled_table_init(&dcerpc_co_reassemble_table);
- dcerpc_fragment_table_init(&dcerpc_cl_reassemble_table);
+ /*
+ * XXX - addresses_ports_reassembly_table_functions?
+ * Or can a single connection-oriented DCE RPC session persist
+ * over multiple transport layer connections?
+ */
+ reassembly_table_init(&dcerpc_co_reassembly_table,
+ &addresses_reassembly_table_functions);
+ reassembly_table_init(&dcerpc_cl_reassembly_table,
+ &dcerpc_cl_reassembly_table_functions);
}
/*
@@ -3261,7 +3372,7 @@ dissect_dcerpc_cn_stub(tvbuff_t *tvb, int offset, packet_info *pinfo,
then exit
*/
if (pinfo->fd->flags.visited) {
- fd_head = fragment_get_reassembled(frame, dcerpc_co_reassemble_table);
+ fd_head = fragment_get_reassembled(&dcerpc_co_reassembly_table, frame);
goto end_cn_stub;
}
@@ -3298,8 +3409,8 @@ dissect_dcerpc_cn_stub(tvbuff_t *tvb, int offset, packet_info *pinfo,
* just use fragment_add_seq_next() and hope that TCP/SMB segments coming
* in with the correct sequence.
*/
- fd_head = fragment_add_seq_next(decrypted_tvb, 0, pinfo, frame,
- dcerpc_co_fragment_table, dcerpc_co_reassemble_table,
+ fd_head = fragment_add_seq_next(&dcerpc_co_reassembly_table,
+ decrypted_tvb, 0, pinfo, frame, NULL,
tvb_length(decrypted_tvb),
hdr->flags&PFC_LAST_FRAG ? FALSE : TRUE /* more_frags */);
@@ -3929,8 +4040,9 @@ dissect_dcerpc_cn_fault(tvbuff_t *tvb, gint offset, packet_info *pinfo,
}
if (hdr->flags&PFC_FIRST_FRAG) { /* FIRST fragment */
if ( (!pinfo->fd->flags.visited) && value->rep_frame ) {
- fragment_add_seq_next(tvb, offset, pinfo, value->rep_frame,
- dcerpc_co_fragment_table, dcerpc_co_reassemble_table,
+ fragment_add_seq_next(&dcerpc_co_reassembly_table,
+ tvb, offset,
+ pinfo, value->rep_frame, NULL,
stub_length,
TRUE);
}
@@ -3938,9 +4050,9 @@ dissect_dcerpc_cn_fault(tvbuff_t *tvb, gint offset, packet_info *pinfo,
if ( value->rep_frame ) {
fragment_data *fd_head;
- fd_head = fragment_add_seq_next(tvb, offset, pinfo,
- value->rep_frame,
- dcerpc_co_fragment_table, dcerpc_co_reassemble_table,
+ fd_head = fragment_add_seq_next(&dcerpc_co_reassembly_table,
+ tvb, offset,
+ pinfo, value->rep_frame, NULL,
stub_length,
TRUE);
@@ -3977,8 +4089,9 @@ dissect_dcerpc_cn_fault(tvbuff_t *tvb, gint offset, packet_info *pinfo,
}
} else { /* MIDDLE fragment(s) */
if ( (!pinfo->fd->flags.visited) && value->rep_frame ) {
- fragment_add_seq_next(tvb, offset, pinfo, value->rep_frame,
- dcerpc_co_fragment_table, dcerpc_co_reassemble_table,
+ fragment_add_seq_next(&dcerpc_co_reassembly_table,
+ tvb, offset,
+ pinfo, value->rep_frame, NULL,
stub_length,
TRUE);
}
@@ -4933,10 +5046,11 @@ dissect_dcerpc_dg_stub(tvbuff_t *tvb, int offset, packet_info *pinfo,
}
}
- fd_head = fragment_add_dcerpc_dg(tvb, offset, pinfo,
- hdr->seqnum, &hdr->act_id, dcerpc_cl_reassemble_table,
- hdr->frag_num, stub_length,
- !(hdr->flags1 & PFCL1_LASTFRAG));
+ fd_head = fragment_add_seq(&dcerpc_cl_reassembly_table,
+ tvb, offset,
+ pinfo, hdr->seqnum, (void *)hdr,
+ hdr->frag_num, stub_length,
+ !(hdr->flags1 & PFCL1_LASTFRAG), 0);
if (fd_head != NULL) {
/* We completed reassembly... */
if (pinfo->fd->num == fd_head->reassembled_in) {
diff --git a/epan/dissectors/packet-dcm.c b/epan/dissectors/packet-dcm.c
index 459ee91bd6..1dd89591f4 100644
--- a/epan/dissectors/packet-dcm.c
+++ b/epan/dissectors/packet-dcm.c
@@ -402,9 +402,8 @@ static const fragment_items dcm_pdv_fragment_items = {
"Message fragments"
};
-/* Structures to handle fragmented DICOM PDU packets */
-static GHashTable *dcm_pdv_fragment_table = NULL;
-static GHashTable *dcm_pdv_reassembled_table = NULL;
+/* Structure to handle fragmented DICOM PDU packets */
+static reassembly_table dcm_pdv_reassembly_table;
typedef struct dcm_open_tag {
@@ -3976,8 +3975,8 @@ dcm_init(void)
}
/* Register processing of fragmented DICOM PDVs */
- fragment_table_init(&dcm_pdv_fragment_table);
- reassembled_table_init(&dcm_pdv_reassembled_table);
+ reassembly_table_init(&dcm_pdv_reassembly_table,
+ &addresses_reassembly_table_functions);
}
static dcm_state_t *
@@ -6665,9 +6664,8 @@ dissect_dcm_pdv_fragmented(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
*/
reassembly_id = (((conv->index) & 0x00FFFFFF) << 8) + pdv->pctx_id;
- head = fragment_add_seq_next(tvb, offset, pinfo, reassembly_id,
- dcm_pdv_fragment_table,
- dcm_pdv_reassembled_table,
+ head = fragment_add_seq_next(&dcm_pdv_reassembly_table,
+ tvb, offset, pinfo, reassembly_id, NULL,
pdv_body_len,
!(pdv->is_last_fragment));
diff --git a/epan/dissectors/packet-dcp-etsi.c b/epan/dissectors/packet-dcp-etsi.c
index 3fb9cfcf29..86071b3399 100644
--- a/epan/dissectors/packet-dcp-etsi.c
+++ b/epan/dissectors/packet-dcp-etsi.c
@@ -100,8 +100,7 @@ static gint ett_tpl = -1;
static gint ett_edcp_fragment = -1;
static gint ett_edcp_fragments = -1;
-static GHashTable *dcp_fragment_table = NULL;
-static GHashTable *dcp_reassembled_table = NULL;
+static reassembly_table dcp_reassembly_table;
static const fragment_items dcp_frag_items = {
/* Fragment subtrees */
@@ -132,8 +131,8 @@ static const fragment_items dcp_frag_items = {
static void
dcp_init_protocol(void)
{
- fragment_table_init (&dcp_fragment_table);
- reassembled_table_init (&dcp_reassembled_table);
+ reassembly_table_init (&dcp_reassembly_table,
+ &addresses_reassembly_table_functions);
}
@@ -292,7 +291,7 @@ dissect_pft_fec_detailed(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
got = (guint32 *)ep_alloc(fcount*sizeof(guint32));
/* make a list of the findex (offset) numbers of the fragments we have */
- fd = fragment_get(pinfo, seq, dcp_fragment_table);
+ fd = fragment_get(&dcp_reassembly_table, pinfo, seq, NULL);
for (fd_head = fd; fd_head != NULL && fragments < fcount; fd_head = fd_head->next) {
if(fd_head->data) {
got[fragments++] = fd_head->offset; /* this is the findex of the fragment */
@@ -324,8 +323,8 @@ dissect_pft_fec_detailed(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
return NULL;
}
for(; current_findex<next_fragment_we_have; current_findex++) {
- frag = fragment_add_seq_check (dummytvb, 0, pinfo, seq,
- dcp_fragment_table, dcp_reassembled_table,
+ frag = fragment_add_seq_check (&dcp_reassembly_table,
+ dummytvb, 0, pinfo, seq, NULL,
current_findex, plen, (current_findex+1!=fcount));
}
current_findex++; /* skip over the fragment we have */
@@ -399,9 +398,9 @@ dissect_pft_fragmented(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
first = findex == 0;
last = fcount == (findex+1);
frag_edcp = fragment_add_seq_check (
- tvb, offset, pinfo,
- seq,
- dcp_fragment_table, dcp_reassembled_table,
+ &dcp_reassembly_table,
+ tvb, offset,
+ pinfo, seq, NULL,
findex,
plen,
!last);
diff --git a/epan/dissectors/packet-dnp.c b/epan/dissectors/packet-dnp.c
index bb87fbc61d..8967e09a9c 100644
--- a/epan/dissectors/packet-dnp.c
+++ b/epan/dissectors/packet-dnp.c
@@ -1067,8 +1067,7 @@ static gint ett_dnp3_al_obj_point = -1;
static gint ett_dnp3_al_obj_point_perms = -1;
/* Tables for reassembly of fragments. */
-static GHashTable *al_fragment_table = NULL;
-static GHashTable *al_reassembled_table = NULL;
+static reassembly_table al_reassembly_table;
static GHashTable *dl_conversation_table = NULL;
/* Data-Link-Layer Conversation Key Structure */
@@ -3069,9 +3068,8 @@ dissect_dnp3_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* if it's done.
*/
- frag_msg = fragment_add_seq_next(al_tvb, 0, pinfo, conv_seq_number,
- al_fragment_table,
- al_reassembled_table,
+ frag_msg = fragment_add_seq_next(&al_reassembly_table,
+ al_tvb, 0, pinfo, conv_seq_number, NULL,
tvb_reported_length(al_tvb), /* As this is a constructed tvb, all of it is ok */
!tr_fin);
@@ -3172,8 +3170,8 @@ dnp3_init(void)
}
dl_conversation_table = g_hash_table_new(dl_conversation_hash, dl_conversation_equal);
- fragment_table_init(&al_fragment_table);
- reassembled_table_init(&al_reassembled_table);
+ reassembly_table_init(&al_reassembly_table,
+ &addresses_reassembly_table_functions);
}
/* Register the protocol with Wireshark */
diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c
index 72a7712a1b..cfd3b9b6b6 100644
--- a/epan/dissectors/packet-dtls.c
+++ b/epan/dissectors/packet-dtls.c
@@ -174,7 +174,7 @@ static gint ett_dtls_fragments = -1;
static GHashTable *dtls_session_hash = NULL;
static GHashTable *dtls_key_hash = NULL;
-static GHashTable *dtls_fragment_table = NULL;
+static reassembly_table dtls_reassembly_table;
static GTree* dtls_associations = NULL;
static dissector_handle_t dtls_handle = NULL;
static StringInfo dtls_compressed_data = {NULL, 0};
@@ -220,7 +220,7 @@ dtls_init(void)
pref_t *keys_list_pref;
ssl_common_init(&dtls_session_hash, &dtls_decrypted_data, &dtls_compressed_data);
- fragment_table_init (&dtls_fragment_table);
+ reassembly_table_init (&dtls_reassembly_table, &addresses_reassembly_table_functions);
/* We should have loaded "keys_list" by now. Mark it obsolete */
if (dtls_module) {
@@ -1223,11 +1223,11 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo,
/* Don't pass the reassembly code data that doesn't exist */
tvb_ensure_bytes_exist(tvb, offset+12, fragment_length);
- frag_msg = fragment_add(tvb, offset+12, pinfo, message_seq,
- dtls_fragment_table,
+ frag_msg = fragment_add(&dtls_reassembly_table,
+ tvb, offset+12, pinfo, message_seq, NULL,
fragment_offset, fragment_length, TRUE);
- fragment_set_tot_len(pinfo, message_seq, dtls_fragment_table,
- length);
+ fragment_set_tot_len(&dtls_reassembly_table,
+ pinfo, message_seq, NULL, length);
if (frag_msg && (fragment_length + fragment_offset) == length)
{
diff --git a/epan/dissectors/packet-dtn.c b/epan/dissectors/packet-dtn.c
index d428fe007d..1e47aacd60 100644
--- a/epan/dissectors/packet-dtn.c
+++ b/epan/dissectors/packet-dtn.c
@@ -61,8 +61,7 @@ static int add_dtn_time_to_tree(proto_tree *tree, tvbuff_t *tvb, int offset, con
static int add_sdnv_time_to_tree(proto_tree *tree, tvbuff_t *tvb, int offset, const char *field_id);
/* For Reassembling TCP Convergence Layer segments */
-static GHashTable *msg_fragment_table = NULL;
-static GHashTable *msg_reassembled_table = NULL;
+static reassembly_table msg_reassembly_table;
static char magic[] = {'d', 't', 'n', '!'};
@@ -382,10 +381,10 @@ dissect_tcp_bundle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* Convergence layer header.
*/
- frag_msg = fragment_add_seq_next(tvb, frame_offset + convergence_hdr_size,
- pinfo, 0, msg_fragment_table,
- msg_reassembled_table, segment_length,
- more_frags);
+ frag_msg = fragment_add_seq_next(&msg_reassembly_table,
+ tvb, frame_offset + convergence_hdr_size,
+ pinfo, 0, NULL,
+ segment_length, more_frags);
if(frag_msg && !more_frags) {
proto_item *ti;
@@ -2432,8 +2431,8 @@ add_sdnv_time_to_tree(proto_tree *tree, tvbuff_t *tvb, int offset, const char *f
static void
bundle_defragment_init(void) {
- fragment_table_init(&msg_fragment_table);
- reassembled_table_init(&msg_reassembled_table);
+ reassembly_table_init(&msg_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void
diff --git a/epan/dissectors/packet-dvbci.c b/epan/dissectors/packet-dvbci.c
index caf2fdbc35..e6b5441a47 100644
--- a/epan/dissectors/packet-dvbci.c
+++ b/epan/dissectors/packet-dvbci.c
@@ -1041,10 +1041,8 @@ static int hf_dvbci_sas_msg_len = -1;
static dissector_table_t sas_msg_dissector_table;
-static GHashTable *tpdu_fragment_table = NULL;
-static GHashTable *tpdu_reassembled_table = NULL;
-static GHashTable *spdu_fragment_table = NULL;
-static GHashTable *spdu_reassembled_table = NULL;
+static reassembly_table tpdu_reassembly_table;
+static reassembly_table spdu_reassembly_table;
static const fragment_items tpdu_frag_items = {
&ett_dvbci_link_frag,
@@ -1525,10 +1523,10 @@ dvbci_init(void)
buf_size_cam = 0;
buf_size_host = 0;
- fragment_table_init(&tpdu_fragment_table);
- reassembled_table_init(&tpdu_reassembled_table);
- fragment_table_init(&spdu_fragment_table);
- reassembled_table_init(&spdu_reassembled_table);
+ reassembly_table_init(&tpdu_reassembly_table,
+ &addresses_reassembly_table_functions);
+ reassembly_table_init(&spdu_reassembly_table,
+ &addresses_reassembly_table_functions);
}
@@ -4224,10 +4222,8 @@ dissect_dvbci_tpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
input to reassembly routines */
body_tvb = tvb_new_subset(tvb, offset, body_len, body_len);
/* dissect_dvbci_tpdu_hdr() checked that lpdu_tcid==t_c_id */
- frag_msg = fragment_add_seq_next(body_tvb, 0, pinfo,
- SPDU_SEQ_ID_BASE+lpdu_tcid,
- spdu_fragment_table,
- spdu_reassembled_table,
+ frag_msg = fragment_add_seq_next(&spdu_reassembly_table,
+ body_tvb, 0, pinfo, SPDU_SEQ_ID_BASE+lpdu_tcid, NULL,
body_len,
hdr_tag == T_DATA_MORE ? 1 : 0);
payload_tvb = process_reassembled_data(body_tvb, 0, pinfo,
@@ -4309,10 +4305,8 @@ dissect_dvbci_lpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
buf_size_host);
}
- frag_msg = fragment_add_seq_next(tvb, 2, pinfo,
- TPDU_SEQ_ID_BASE+tcid,
- tpdu_fragment_table,
- tpdu_reassembled_table,
+ frag_msg = fragment_add_seq_next(&tpdu_reassembly_table,
+ tvb, 2, pinfo, TPDU_SEQ_ID_BASE+tcid, NULL,
tvb_reported_length_remaining(tvb, 2),
more_last == ML_MORE ? 1 : 0);
diff --git a/epan/dissectors/packet-eap.c b/epan/dissectors/packet-eap.c
index c886b8bc8f..b8a1c47a58 100644
--- a/epan/dissectors/packet-eap.c
+++ b/epan/dissectors/packet-eap.c
@@ -320,7 +320,7 @@ from RFC2716, pg 17
/*
* reassembly of EAP-TLS
*/
-static GHashTable *eap_tls_fragment_table = NULL;
+static reassembly_table eap_tls_reassembly_table;
static int hf_eap_tls_flags = -1;
static int hf_eap_tls_flag_l = -1;
@@ -413,7 +413,8 @@ test_flag(unsigned char flag, unsigned char mask)
static void
eap_tls_defragment_init(void)
{
- fragment_table_init(&eap_tls_fragment_table);
+ reassembly_table_init(&eap_tls_reassembly_table,
+ &addresses_reassembly_table_functions);
}
static void
@@ -1002,12 +1003,12 @@ dissect_eap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
*/
save_fragmented = pinfo->fragmented;
pinfo->fragmented = TRUE;
- fd_head = fragment_add_seq(tvb, offset, pinfo,
- eap_reass_cookie,
- eap_tls_fragment_table,
+ fd_head = fragment_add_seq(&eap_tls_reassembly_table,
+ tvb, offset,
+ pinfo, eap_reass_cookie, NULL,
eap_tls_seq,
size,
- more_fragments);
+ more_fragments, 0);
if (fd_head != NULL) /* Reassembled */
{
diff --git a/epan/dissectors/packet-fc.c b/epan/dissectors/packet-fc.c
index 394b6ac774..e5482bb3d7 100644
--- a/epan/dissectors/packet-fc.c
+++ b/epan/dissectors/packet-fc.c
@@ -151,7 +151,7 @@ typedef struct _fc_conv_data_t {
/* Reassembly stuff */
static gboolean fc_reassemble = TRUE;
static guint32 fc_max_frame_size = 1024;
-static GHashTable *fc_fragment_table = NULL;
+static reassembly_table fc_reassembly_table;
typedef struct _fcseq_conv_key {
guint32 conv_idx;
@@ -189,7 +189,8 @@ fcseq_hash (gconstpointer v)
static void
fc_exchange_init_protocol(void)
{
- fragment_table_init(&fc_fragment_table);
+ reassembly_table_init(&fc_reassembly_table,
+ &addresses_reassembly_table_functions);
if (fcseq_req_hash)
g_hash_table_destroy(fcseq_req_hash);
@@ -1159,8 +1160,9 @@ dissect_fc_helper (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean
frag_id = ((pinfo->oxid << 16) ^ seq_id) | is_exchg_resp ;
/* We assume that all frames are of the same max size */
- fcfrag_head = fragment_add (tvb, FC_HEADER_SIZE, pinfo, frag_id,
- fc_fragment_table,
+ fcfrag_head = fragment_add (&fc_reassembly_table,
+ tvb, FC_HEADER_SIZE,
+ pinfo, frag_id, NULL,
real_seqcnt * fc_max_frame_size,
frag_size,
!is_lastframe_inseq);
diff --git a/epan/dissectors/packet-gsm_cbch.c b/epan/dissectors/packet-gsm_cbch.c
index a8e97f2047..69791d900a 100644
--- a/epan/dissectors/packet-gsm_cbch.c
+++ b/epan/dissectors/packet-gsm_cbch.c
@@ -93,8 +93,7 @@ static dissector_handle_t data_handle;
static dissector_handle_t cbs_handle;
/* reassembly of CHCH blocks */
-static GHashTable *fragment_block_table = NULL;
-static GHashTable *reassembled_message_table = NULL;
+static reassembly_table cbch_block_reassembly_table;
/* Structure needed for the fragmentation routines in reassemble.c
*/
@@ -119,8 +118,8 @@ static const fragment_items cbch_frag_items = {
static void
cbch_defragment_init(void)
{
- fragment_table_init(&fragment_block_table);
- reassembled_table_init(&reassembled_message_table);
+ reassembly_table_init(&cbch_block_reassembly_table,
+ &addresses_reassembly_table_functions);
}
static void
@@ -370,8 +369,8 @@ dissect_cbch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
this information is carried in the initial sequence number, not the payload,
so we prepend the reassembly with the octet containing the initial sequence number
to allow later dissection of the payload */
- frag_data = fragment_add_seq_check(tvb, offset, pinfo, 0,
- fragment_block_table, reassembled_message_table,
+ frag_data = fragment_add_seq_check(&cbch_block_reassembly_table,
+ tvb, offset, pinfo, 0, NULL,
seq_num & 0x03, CBCH_FRAGMENT_SIZE + 1, !lb);
reass_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled CBCH message",
frag_data, &cbch_frag_items, NULL, cbch_tree);
@@ -382,9 +381,9 @@ dissect_cbch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
case 0x03:
pinfo->fragmented = TRUE;
offset++; /* step to beginning of payload */
- frag_data = fragment_add_seq_check(tvb, offset, pinfo, 0,
- fragment_block_table, reassembled_message_table, seq_num,
- CBCH_FRAGMENT_SIZE, !lb);
+ frag_data = fragment_add_seq_check(&cbch_block_reassembly_table,
+ tvb, offset, pinfo, 0, NULL,
+ seq_num, CBCH_FRAGMENT_SIZE, !lb);
reass_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled CBCH message",
frag_data, &cbch_frag_items, NULL, cbch_tree);
break;
diff --git a/epan/dissectors/packet-gsm_sms.c b/epan/dissectors/packet-gsm_sms.c
index ba4a91beae..3ee4e3b37e 100644
--- a/epan/dissectors/packet-gsm_sms.c
+++ b/epan/dissectors/packet-gsm_sms.c
@@ -192,8 +192,7 @@ static gboolean g_is_wsp;
static dissector_table_t gsm_sms_dissector_tbl;
/* Short Message reassembly */
-static GHashTable *g_sm_fragment_table = NULL;
-static GHashTable *g_sm_reassembled_table = NULL;
+static reassembly_table g_sm_reassembly_table;
static GHashTable *g_sm_fragment_params_table = NULL;
static gint ett_gsm_sms_ud_fragment = -1;
static gint ett_gsm_sms_ud_fragments = -1;
@@ -242,8 +241,8 @@ typedef struct {
static void
gsm_sms_defragment_init (void)
{
- fragment_table_init (&g_sm_fragment_table);
- reassembled_table_init(&g_sm_reassembled_table);
+ reassembly_table_init(&g_sm_reassembly_table,
+ &addresses_reassembly_table_functions);
if (g_sm_fragment_params_table) {
g_hash_table_destroy(g_sm_fragment_params_table);
}
@@ -2672,10 +2671,10 @@ dis_field_ud(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 length, gb
try_gsm_sms_ud_reassemble = TRUE;
save_fragmented = g_pinfo->fragmented;
g_pinfo->fragmented = TRUE;
- fd_sm = fragment_add_seq_check (tvb, offset, g_pinfo,
+ fd_sm = fragment_add_seq_check (&g_sm_reassembly_table, tvb, offset,
+ g_pinfo,
g_sm_id, /* guint32 ID for fragments belonging together */
- g_sm_fragment_table, /* list of message fragments */
- g_sm_reassembled_table, /* list of reassembled messages */
+ NULL,
g_frag-1, /* guint32 fragment sequence number */
length, /* guint32 fragment length */
(g_frag != g_frags)); /* More fragments? */
diff --git a/epan/dissectors/packet-gsm_sms_ud.c b/epan/dissectors/packet-gsm_sms_ud.c
index cf311c6c87..e6cd369c45 100644
--- a/epan/dissectors/packet-gsm_sms_ud.c
+++ b/epan/dissectors/packet-gsm_sms_ud.c
@@ -105,8 +105,7 @@ static gint ett_gsm_sms_ud_fragments = -1;
static dissector_table_t gsm_sms_dissector_table;
/* Short Message reassembly */
-static GHashTable *sm_fragment_table = NULL;
-static GHashTable *sm_reassembled_table = NULL;
+static reassembly_table sm_reassembly_table;
static const fragment_items sm_frag_items = {
/* Fragment subtrees */
@@ -146,8 +145,8 @@ static dissector_handle_t wsp_handle;
static void
gsm_sms_ud_defragment_init(void)
{
- fragment_table_init(&sm_fragment_table);
- reassembled_table_init(&sm_reassembled_table);
+ reassembly_table_init(&sm_reassembly_table,
+ &addresses_reassembly_table_functions);
}
/*
@@ -354,10 +353,11 @@ parse_gsm_sms_ud_message(proto_tree *sm_tree, tvbuff_t *tvb, packet_info *pinfo,
try_gsm_sms_ud_reassemble = TRUE;
save_fragmented = pinfo->fragmented;
pinfo->fragmented = TRUE;
- fd_sm = fragment_add_seq_check(tvb, i, pinfo,
+ fd_sm = fragment_add_seq_check(&sm_reassembly_table,
+ tvb, i,
+ pinfo,
sm_id, /* guint32 ID for fragments belonging together */
- sm_fragment_table, /* list of message fragments */
- sm_reassembled_table, /* list of reassembled messages */
+ NULL,
frag-1, /* guint32 fragment sequence number */
sm_data_len, /* guint32 fragment length */
(frag != frags)); /* More fragments? */
diff --git a/epan/dissectors/packet-gssapi.c b/epan/dissectors/packet-gssapi.c
index e6b7c832c9..248908762d 100644
--- a/epan/dissectors/packet-gssapi.c
+++ b/epan/dissectors/packet-gssapi.c
@@ -98,12 +98,13 @@ static const fragment_items gssapi_frag_items = {
};
-static GHashTable *gssapi_fragment_table = NULL;
+static reassembly_table gssapi_reassembly_table;
static void
gssapi_reassembly_init(void)
{
- fragment_table_init(&gssapi_fragment_table);
+ reassembly_table_init(&gssapi_reassembly_table,
+ &addresses_reassembly_table_functions);
}
/*
@@ -255,8 +256,9 @@ dissect_gssapi_work(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
goto done;
}
se_tree_insert32(gss_info->frags, pinfo->fd->num, fi);
- fd_head=fragment_add(tvb, 0, pinfo, fi->first_frame,
- gssapi_fragment_table, gss_info->frag_offset,
+ fd_head=fragment_add(&gssapi_reassembly_table,
+ tvb, 0, pinfo, fi->first_frame, NULL,
+ gss_info->frag_offset,
tvb_length(tvb), TRUE);
gss_info->frag_offset+=tvb_length(tvb);
@@ -279,7 +281,8 @@ dissect_gssapi_work(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
&& (gssapi_reassembly) ){
fi=(gssapi_frag_info_t *)se_tree_lookup32(gss_info->frags, pinfo->fd->num);
if(fi){
- fd_head=fragment_get(pinfo, fi->first_frame, gssapi_fragment_table);
+ fd_head=fragment_get(&gssapi_reassembly_table,
+ pinfo, fi->first_frame, NULL);
if(fd_head && (fd_head->flags&FD_DEFRAGMENTED)){
if(pinfo->fd->num==fi->reassembled_in){
proto_item *frag_tree_item;
@@ -424,10 +427,11 @@ dissect_gssapi_work(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
fi->reassembled_in=0;
se_tree_insert32(gss_info->frags, pinfo->fd->num, fi);
- fragment_add(gss_tvb, 0, pinfo, pinfo->fd->num,
- gssapi_fragment_table, 0,
- tvb_length(gss_tvb), TRUE);
- fragment_set_tot_len(pinfo, pinfo->fd->num, gssapi_fragment_table, len1+oid_start_offset);
+ fragment_add(&gssapi_reassembly_table,
+ gss_tvb, 0, pinfo, pinfo->fd->num, NULL,
+ 0, tvb_length(gss_tvb), TRUE);
+ fragment_set_tot_len(&gssapi_reassembly_table,
+ pinfo, pinfo->fd->num, NULL, len1+oid_start_offset);
gss_info->do_reassembly=TRUE;
gss_info->first_frame=pinfo->fd->num;
diff --git a/epan/dissectors/packet-hci_usb.c b/epan/dissectors/packet-hci_usb.c
index cc833fe552..6cdf2a706a 100644
--- a/epan/dissectors/packet-hci_usb.c
+++ b/epan/dissectors/packet-hci_usb.c
@@ -58,8 +58,7 @@ static emem_tree_t *localhost_name = NULL;
static emem_tree_t *localhost_bdaddr = NULL;
static emem_tree_t *fragment_info_table = NULL;
-static GHashTable *fragment_table = NULL;
-static GHashTable *reassembled_table = NULL;
+static reassembly_table hci_usb_reassembly_table;
typedef struct _fragment_info_t {
gint remaining_length;
@@ -175,14 +174,16 @@ dissect_hci_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
fragment_info->remaining_length -= tvb_ensure_length_remaining(tvb, offset);
- fragment_add_seq_check(tvb, offset, pinfo, session_id, fragment_table, reassembled_table, fragment_info->fragment_id, tvb_length_remaining(tvb, offset), (fragment_info->remaining_length == 0) ? FALSE : TRUE);
+ fragment_add_seq_check(&hci_usb_reassembly_table,
+ tvb, offset, pinfo, session_id, NULL,
+ fragment_info->fragment_id, tvb_length_remaining(tvb, offset), (fragment_info->remaining_length == 0) ? FALSE : TRUE);
if (fragment_info->remaining_length > 0)
fragment_info->fragment_id += 1;
else
fragment_info->fragment_id = 0;
}
- reassembled = fragment_get_reassembled_id(pinfo, session_id, reassembled_table);
+ reassembled = fragment_get_reassembled_id(&hci_usb_reassembly_table, pinfo, session_id);
if (reassembled && pinfo->fd->num < reassembled->reassembled_in) {
pitem = proto_tree_add_text(ttree, tvb, offset, -1, "Fragment");
PROTO_ITEM_SET_GENERATED(pitem);
@@ -294,8 +295,8 @@ proto_register_hci_usb(void)
&ett_hci_usb_msg_fragments,
};
- fragment_table_init(&fragment_table);
- reassembled_table_init(&reassembled_table);
+ reassembly_table_init(&hci_usb_reassembly_table,
+ &addresses_reassembly_table_functions);
fragment_info_table = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "hci_usb fragment_info");
chandle_to_bdaddr_table = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "hci_usb adapter/chandle to bdaddr");
diff --git a/epan/dissectors/packet-iax2.c b/epan/dissectors/packet-iax2.c
index 67b4a85d05..070da5a47c 100644
--- a/epan/dissectors/packet-iax2.c
+++ b/epan/dissectors/packet-iax2.c
@@ -508,7 +508,7 @@ typedef struct {
/* tables */
static GHashTable *iax_fid_table = NULL;
-static GHashTable *iax_fragment_table = NULL;
+static reassembly_table iax_reassembly_table;
static GHashTable *iax_circuit_hashtab = NULL;
static guint circuitcount = 0;
@@ -674,7 +674,8 @@ static void iax_init_hash( void )
g_hash_table_destroy(iax_fid_table);
iax_fid_table = g_hash_table_new(g_direct_hash, g_direct_equal);
- fragment_table_init(&iax_fragment_table);
+ reassembly_table_init(&iax_reassembly_table,
+ &addresses_reassembly_table_functions);
}
@@ -2156,8 +2157,7 @@ static void desegment_iax(tvbuff_t *tvb, packet_info *pinfo, proto_tree *iax2_tr
}
/* fragment_add checks for already-added */
- fd_head = fragment_add(tvb, 0, pinfo, fid,
- iax_fragment_table,
+ fd_head = fragment_add(&iax_reassembly_table, tvb, 0, pinfo, fid, NULL,
frag_offset,
frag_len, !complete);
@@ -2177,7 +2177,7 @@ static void desegment_iax(tvbuff_t *tvb, packet_info *pinfo, proto_tree *iax2_tr
if (pinfo->desegment_len &&
(pinfo->desegment_offset < old_len)) {
/* oops, it wasn't actually complete */
- fragment_set_partial_reassembly(pinfo, fid, iax_fragment_table);
+ fragment_set_partial_reassembly(&iax_reassembly_table, pinfo, fid, NULL);
if (pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) {
/* only one more byte should be enough for a retry */
dirdata->current_frag_minlen = fd_head->datalen + 1;
@@ -2244,8 +2244,8 @@ static void desegment_iax(tvbuff_t *tvb, packet_info *pinfo, proto_tree *iax2_tr
dirdata->current_frag_minlen = frag_len + pinfo->desegment_len;
}
- fd_head = fragment_add(tvb, deseg_offset, pinfo, fid,
- iax_fragment_table,
+ fd_head = fragment_add(&iax_reassembly_table,
+ tvb, deseg_offset, pinfo, fid, NULL,
0, frag_len, TRUE);
#ifdef DEBUG_DESEGMENT
g_debug("Start offset of undissected bytes: %u; "
diff --git a/epan/dissectors/packet-idmp.c b/epan/dissectors/packet-idmp.c
index b236d77b16..74c856f8fe 100644
--- a/epan/dissectors/packet-idmp.c
+++ b/epan/dissectors/packet-idmp.c
@@ -75,8 +75,7 @@ static int hf_idmp_final = -1;
static int hf_idmp_length = -1;
static int hf_idmp_PDU = -1;
-static GHashTable *idmp_segment_table = NULL;
-static GHashTable *idmp_reassembled_table = NULL;
+static reassembly_table idmp_reassembly_table;
static int hf_idmp_fragments = -1;
static int hf_idmp_fragment = -1;
@@ -677,8 +676,8 @@ static void dissect_idmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_t
idmp_final ? "Final " : "" ,
idmp_length, plurality(idmp_length, "", "s"));
- fd_head = fragment_add_seq_next(tvb, offset, pinfo, dst_ref,
- idmp_segment_table, idmp_reassembled_table,
+ fd_head = fragment_add_seq_next(&idmp_reassembly_table, tvb, offset,
+ pinfo, dst_ref, NULL,
idmp_length, !idmp_final);
if(fd_head && fd_head->next) {
@@ -740,8 +739,8 @@ static void dissect_idmp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pare
static void idmp_reassemble_init (void)
{
- fragment_table_init (&idmp_segment_table);
- reassembled_table_init (&idmp_reassembled_table);
+ reassembly_table_init (&idmp_reassembly_table,
+ &addresses_reassembly_table_functions);
saved_protocolID = NULL;
}
diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c
index 335cf9a491..78458c9702 100644
--- a/epan/dissectors/packet-ieee80211.c
+++ b/epan/dissectors/packet-ieee80211.c
@@ -137,9 +137,8 @@ static gboolean wlan_ignore_draft_ht = FALSE;
#define WLAN_IGNORE_WEP_W_IV 2
static gint wlan_ignore_wep = WLAN_IGNORE_WEP_NO;
-/* Tables for reassembly of fragments. */
-static GHashTable *wlan_fragment_table = NULL;
-static GHashTable *wlan_reassembled_table = NULL;
+/* Table for reassembly of fragments. */
+static reassembly_table wlan_reassembly_table;
/* Statistical data */
static struct _wlan_stats wlan_stats;
@@ -5469,14 +5468,13 @@ dissect_gas_initial_response(proto_tree *tree, tvbuff_t *tvb, int offset,
return offset - start;
}
-static GHashTable *gas_fragment_table = NULL;
-static GHashTable *gas_reassembled_table = NULL;
+static reassembly_table gas_reassembly_table;
static void
ieee80211_gas_reassembly_init(void)
{
- fragment_table_init(&gas_fragment_table);
- reassembled_table_init(&gas_reassembled_table);
+ reassembly_table_init(&gas_reassembly_table,
+ &addresses_reassembly_table_functions);
}
static gint ett_gas_resp_fragment = -1;
@@ -5547,10 +5545,9 @@ dissect_gas_comeback_response(proto_tree *tree, tvbuff_t *tvb, int offset,
save_fragmented = g_pinfo->fragmented;
g_pinfo->fragmented = TRUE;
- frag_msg = fragment_add_seq_check(tvb, offset, g_pinfo, dialog_token,
- gas_fragment_table,
- gas_reassembled_table, frag, resp_len,
- more);
+ frag_msg = fragment_add_seq_check(&gas_reassembly_table, tvb, offset,
+ g_pinfo, dialog_token, NULL,
+ frag, resp_len, more);
new_tvb = process_reassembled_data(tvb, offset, g_pinfo,
"Reassembled GAS Query Response",
frag_msg, &gas_resp_frag_items,
@@ -13416,9 +13413,8 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
*/
if (reported_len < 0)
THROW(ReportedBoundsError);
- fd_head = fragment_add_seq_802_11(next_tvb, hdr_len, pinfo, seq_number,
- wlan_fragment_table,
- wlan_reassembled_table,
+ fd_head = fragment_add_seq_802_11(&wlan_reassembly_table,
+ next_tvb, hdr_len, pinfo, seq_number, NULL,
frag_number,
reported_len,
more_frags);
@@ -13630,8 +13626,8 @@ dissect_ieee80211_ht (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void
wlan_defragment_init(void)
{
- fragment_table_init(&wlan_fragment_table);
- reassembled_table_init(&wlan_reassembled_table);
+ reassembly_table_init(&wlan_reassembly_table,
+ &addresses_reassembly_table_functions);
}
/* ------------- */
diff --git a/epan/dissectors/packet-ip.c b/epan/dissectors/packet-ip.c
index 98e447ab1a..0032133070 100644
--- a/epan/dissectors/packet-ip.c
+++ b/epan/dissectors/packet-ip.c
@@ -451,14 +451,13 @@ static dissector_handle_t tapa_handle;
/*
* defragmentation of IPv4
*/
-static GHashTable *ip_fragment_table = NULL;
-static GHashTable *ip_reassembled_table = NULL;
+static reassembly_table ip_reassembly_table;
static void
ip_defragment_init(void)
{
- fragment_table_init(&ip_fragment_table);
- reassembled_table_init(&ip_reassembled_table);
+ reassembly_table_init(&ip_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void
@@ -2340,9 +2339,10 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
if (ip_defragment && (iph->ip_off & (IP_MF|IP_OFFSET)) &&
tvb_bytes_exist(tvb, offset, pinfo->iplen - pinfo->iphdrlen) &&
ipsum == 0) {
- ipfd_head = fragment_add_check(tvb, offset, pinfo,
+ ipfd_head = fragment_add_check(&ip_reassembly_table, tvb, offset,
+ pinfo,
iph->ip_p ^ iph->ip_id ^ src32 ^ dst32,
- ip_fragment_table, ip_reassembled_table,
+ NULL,
(iph->ip_off & IP_OFFSET) * 8,
pinfo->iplen - pinfo->iphdrlen,
iph->ip_off & IP_MF);
diff --git a/epan/dissectors/packet-ipv6.c b/epan/dissectors/packet-ipv6.c
index d9fa90b063..6993354136 100644
--- a/epan/dissectors/packet-ipv6.c
+++ b/epan/dissectors/packet-ipv6.c
@@ -320,8 +320,7 @@ static gboolean g_ipv6_rpl_srh_strict_rfc_checking = FALSE;
/*
* defragmentation of IPv6
*/
-static GHashTable *ipv6_fragment_table = NULL;
-static GHashTable *ipv6_reassembled_table = NULL;
+static reassembly_table ipv6_reassembly_table;
/* http://www.iana.org/assignments/icmpv6-parameters (last updated 2012-12-22) */
static const value_string ipv6_opt_vals[] = {
@@ -556,8 +555,8 @@ add_geoip_info(proto_tree *tree, tvbuff_t *tvb, gint offset, const struct e_in6_
static void
ipv6_reassemble_init(void)
{
- fragment_table_init(&ipv6_fragment_table);
- reassembled_table_init(&ipv6_reassembled_table);
+ reassembly_table_init(&ipv6_reassembly_table,
+ &addresses_reassembly_table_functions);
}
enum {
@@ -1965,9 +1964,8 @@ again:
frag = offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG);
save_fragmented |= frag;
if (ipv6_reassemble && frag && tvb_bytes_exist(tvb, offset, plen)) {
- ipfd_head = fragment_add_check(tvb, offset, pinfo, ident,
- ipv6_fragment_table,
- ipv6_reassembled_table,
+ ipfd_head = fragment_add_check(&ipv6_reassembly_table,
+ tvb, offset, pinfo, ident, NULL,
offlg & IP6F_OFF_MASK,
plen,
offlg & IP6F_MORE_FRAG);
diff --git a/epan/dissectors/packet-isakmp.c b/epan/dissectors/packet-isakmp.c
index fa89fb5057..d29b68ee38 100644
--- a/epan/dissectors/packet-isakmp.c
+++ b/epan/dissectors/packet-isakmp.c
@@ -370,8 +370,7 @@ static gint ett_isakmp_decrypted_payloads = -1;
static dissector_handle_t eap_handle = NULL;
-static GHashTable *isakmp_fragment_table = NULL;
-static GHashTable *isakmp_reassembled_table = NULL;
+static reassembly_table isakmp_reassembly_table;
static const fragment_items isakmp_frag_items = {
/* Fragment subtrees */
@@ -3814,10 +3813,10 @@ dissect_cisco_fragmentation(tvbuff_t *tvb, int offset, int length, proto_tree *t
save_fragmented = pinfo->fragmented;
pinfo->fragmented = TRUE;
- frag_msg = fragment_add_seq_check(tvb, offset, pinfo,
+ frag_msg = fragment_add_seq_check(&isakmp_reassembly_table, tvb, offset,
+ pinfo,
12345, /*FIXME: Fragmented packet id, guint16, somehow get CKY here */
- isakmp_fragment_table, /* list of message fragments */
- isakmp_reassembled_table, /* list of reassembled messages */
+ NULL,
seq-1, /* fragment sequence number, starting from 0 */
tvb_length_remaining(tvb, offset), /* fragment length - to the end */
last); /* More fragments? */
@@ -4870,8 +4869,8 @@ isakmp_init_protocol(void) {
decrypt_data_t *decr;
guint8 *ic_key;
#endif /* HAVE_LIBGCRYPT */
- fragment_table_init(&isakmp_fragment_table);
- reassembled_table_init(&isakmp_reassembled_table);
+ reassembly_table_init(&isakmp_reassembly_table,
+ &addresses_reassembly_table_functions);
#ifdef HAVE_LIBGCRYPT
if (isakmp_hash) {
diff --git a/epan/dissectors/packet-isup.c b/epan/dissectors/packet-isup.c
index 8baf0d5566..81199eac97 100644
--- a/epan/dissectors/packet-isup.c
+++ b/epan/dissectors/packet-isup.c
@@ -3066,15 +3066,14 @@ static const fragment_items isup_apm_msg_frag_items = {
"ISUP APM Message fragments"
};
-static GHashTable *isup_apm_msg_fragment_table = NULL;
-static GHashTable *isup_apm_msg_reassembled_table = NULL;
+static reassembly_table isup_apm_msg_reassembly_table;
static void
isup_apm_defragment_init(void)
{
- fragment_table_init (&isup_apm_msg_fragment_table);
- reassembled_table_init(&isup_apm_msg_reassembled_table);
+ reassembly_table_init (&isup_apm_msg_reassembly_table,
+ &addresses_reassembly_table_functions);
}
/* Info for the tap that must be passed between procedures */
@@ -5004,16 +5003,21 @@ dissect_isup_application_transport_parameter(tvbuff_t *parameter_tvb, packet_inf
if (si_and_apm_seg_ind == 0)
more_frag = FALSE;
- frag_msg = fragment_add_seq_next(parameter_tvb, offset, pinfo,
+ frag_msg = fragment_add_seq_next(&isup_apm_msg_reassembly_table,
+ parameter_tvb, offset,
+ pinfo,
(apm_Segmentation_local_ref & 0x7f), /* ID for fragments belonging together */
- isup_apm_msg_fragment_table, /* list of message fragments */
- isup_apm_msg_reassembled_table, /* list of reassembled messages */
+ NULL,
tvb_length_remaining(parameter_tvb, offset), /* fragment length - to the end */
more_frag); /* More fragments? */
if ((si_and_apm_seg_ind & 0x3f) !=0 && (si_and_apm_seg_ind &0x40) !=0) {
/* First fragment set number of fragments */
- fragment_set_tot_len(pinfo, apm_Segmentation_local_ref & 0x7f, isup_apm_msg_fragment_table, (si_and_apm_seg_ind & 0x3f));
+ fragment_set_tot_len(&isup_apm_msg_reassembly_table,
+ pinfo,
+ apm_Segmentation_local_ref & 0x7f,
+ NULL,
+ (si_and_apm_seg_ind & 0x3f));
}
new_tvb = process_reassembled_data(parameter_tvb, offset, pinfo,
diff --git a/epan/dissectors/packet-lapdm.c b/epan/dissectors/packet-lapdm.c
index b8932bdb1e..35b272a3aa 100644
--- a/epan/dissectors/packet-lapdm.c
+++ b/epan/dissectors/packet-lapdm.c
@@ -103,8 +103,7 @@ static gint ett_lapdm_length = -1;
static gint ett_lapdm_fragment = -1;
static gint ett_lapdm_fragments = -1;
-static GHashTable *lapdm_fragment_table = NULL;
-static GHashTable *lapdm_reassembled_table = NULL;
+static reassembly_table lapdm_reassembly_table;
static dissector_table_t lapdm_sapi_dissector_table;
@@ -205,8 +204,8 @@ static const fragment_items lapdm_frag_items = {
static void
lapdm_defragment_init (void)
{
- fragment_table_init (&lapdm_fragment_table);
- reassembled_table_init(&lapdm_reassembled_table);
+ reassembly_table_init (&lapdm_reassembly_table,
+ &addresses_reassembly_table_functions);
}
@@ -301,10 +300,10 @@ dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
take N(S) into account, but N(S) isn't always 0 for
the first fragment!
*/
- fd_m = fragment_add_seq_next (payload, 0, pinfo,
+ fd_m = fragment_add_seq_next (&lapdm_reassembly_table, payload, 0,
+ pinfo,
fragment_id, /* guint32 ID for fragments belonging together */
- lapdm_fragment_table, /* list of message fragments */
- lapdm_reassembled_table, /* list of reassembled messages */
+ NULL,
/*n_s guint32 fragment sequence number */
len, /* guint32 fragment length */
m); /* More fragments? */
diff --git a/epan/dissectors/packet-lapsat.c b/epan/dissectors/packet-lapsat.c
index 8020eb9414..e4e989df99 100644
--- a/epan/dissectors/packet-lapsat.c
+++ b/epan/dissectors/packet-lapsat.c
@@ -42,8 +42,7 @@
static int proto_lapsat = -1;
-static GHashTable *lapsat_fragment_table = NULL;
-static GHashTable *lapsat_reassembled_table = NULL;
+static reassembly_table lapsat_reassembly_table;
static dissector_table_t lapsat_sapi_dissector_table;
@@ -251,8 +250,8 @@ static const fragment_items lapsat_frag_items = {
static void
lapsat_defragment_init(void)
{
- fragment_table_init(&lapsat_fragment_table);
- reassembled_table_init(&lapsat_reassembled_table);
+ reassembly_table_init(&lapsat_reassembly_table,
+ &addresses_reassembly_table_functions);
}
@@ -535,10 +534,11 @@ dissect_lapsat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Fragment reconstruction helpers */
fd_m = fragment_add_seq_next(
- payload, 0, pinfo,
+ &lapsat_reassembly_table,
+ payload, 0,
+ pinfo,
fragment_id, /* To group fragments */
- lapsat_fragment_table,
- lapsat_reassembled_table,
+ NULL,
plen,
!!(addr & LAPSAT_SI) /* More fragment ? */
);
diff --git a/epan/dissectors/packet-ltp.c b/epan/dissectors/packet-ltp.c
index 024368e997..2eea5eda69 100644
--- a/epan/dissectors/packet-ltp.c
+++ b/epan/dissectors/packet-ltp.c
@@ -44,8 +44,7 @@
void proto_reg_handoff_ltp(void);
/* For reassembling LTP segments */
-static GHashTable *ltp_fragment_table = NULL;
-static GHashTable *ltp_reassembled_table = NULL;
+static reassembly_table ltp_reassembly_table;
/* Initialize the protocol and registered fields */
static int proto_ltp = -1;
@@ -316,14 +315,16 @@ dissect_data_segment(proto_tree *ltp_tree, tvbuff_t *tvb,packet_info *pinfo,int
frame_offset += rpt_sno_size;
more_frags = FALSE;
- frag_msg = fragment_add_check(tvb, frame_offset, pinfo, (guint32)session_num, ltp_fragment_table,
- ltp_reassembled_table, (guint32)offset, (guint32)length, more_frags);
+ frag_msg = fragment_add_check(&ltp_reassembly_table,
+ tvb, frame_offset, pinfo, (guint32)session_num, NULL,
+ (guint32)offset, (guint32)length, more_frags);
}
else
{
more_frags = TRUE;
- frag_msg = fragment_add_check(tvb, frame_offset, pinfo, (guint32)session_num, ltp_fragment_table,
- ltp_reassembled_table, (guint32)offset, (guint32)length, more_frags);
+ frag_msg = fragment_add_check(&ltp_reassembly_table,
+ tvb, frame_offset, pinfo, (guint32)session_num, NULL,
+ (guint32)offset, (guint32)length, more_frags);
}
@@ -777,8 +778,8 @@ dissect_ltp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
static void
ltp_defragment_init(void) {
- fragment_table_init(&ltp_fragment_table);
- reassembled_table_init(&ltp_reassembled_table);
+ reassembly_table_init(&ltp_reassembly_table,
+ &addresses_reassembly_table_functions);
}
/* Register the protocol with Wireshark */
diff --git a/epan/dissectors/packet-mp2t.c b/epan/dissectors/packet-mp2t.c
index d5aa5027e7..eefed9cbc3 100644
--- a/epan/dissectors/packet-mp2t.c
+++ b/epan/dissectors/packet-mp2t.c
@@ -418,11 +418,10 @@ get_pid_analysis(guint32 pid, conversation_t *conv)
}
return pid_data;
}
-/* Structures to handle packets, spanned across
+/* Structure to handle packets, spanned across
* multiple MPEG packets
*/
-static GHashTable *mp2t_fragment_table = NULL;
-static GHashTable *mp2t_reassembled_table = NULL;
+static reassembly_table mp2t_reassembly_table;
static void
mp2t_dissect_packet(tvbuff_t *tvb, enum pid_payload_type pload_type,
@@ -467,7 +466,7 @@ mp2t_get_packet_length(tvbuff_t *tvb, guint offset, packet_info *pinfo,
remaining_len = tvb_length_remaining(tvb, offset);
- frag = fragment_get(pinfo, frag_id, mp2t_fragment_table);
+ frag = fragment_get(&mp2t_reassembly_table, pinfo, frag_id, NULL);
if (frag)
frag = frag->next;
@@ -537,9 +536,8 @@ mp2t_fragment_handle(tvbuff_t *tvb, guint offset, packet_info *pinfo,
pinfo->fragmented = TRUE;
/* check length; send frame for reassembly */
- frag_msg = fragment_add_check(tvb, offset, pinfo,
- frag_id, mp2t_fragment_table,
- mp2t_reassembled_table,
+ frag_msg = fragment_add_check(&mp2t_reassembly_table,
+ tvb, offset, pinfo, frag_id, NULL,
frag_offset,
frag_len,
!fragment_last);
@@ -1289,8 +1287,8 @@ heur_dissect_mp2t( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *da
static void
mp2t_init(void) {
- fragment_table_init(&mp2t_fragment_table);
- reassembled_table_init(&mp2t_reassembled_table);
+ reassembly_table_init(&mp2t_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void
diff --git a/epan/dissectors/packet-mq.c b/epan/dissectors/packet-mq.c
index 3fe6c2f615..4ae68cc731 100644
--- a/epan/dissectors/packet-mq.c
+++ b/epan/dissectors/packet-mq.c
@@ -368,8 +368,7 @@ static heur_dissector_list_t mq_heur_subdissector_list;
static gboolean mq_desegment = TRUE;
static gboolean mq_reassembly = TRUE;
-static GHashTable *mq_fragment_table = NULL;
-static GHashTable *mq_reassembled_table = NULL;
+static reassembly_table mq_reassembly_table;
#define MQ_PORT_TCP 1414
@@ -2425,7 +2424,9 @@ reassemble_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
fragment_data* fd_head;
guint32 iConnectionId = (pinfo->srcport + pinfo->destport);
if (opcode > 0x80 && !bFirstSegment) iBeginLength = 28;
- fd_head = fragment_add_seq_next(tvb, iBeginLength, pinfo, iConnectionId, mq_fragment_table, mq_reassembled_table,
+ fd_head = fragment_add_seq_next(&mq_reassembly_table,
+ tvb, iBeginLength,
+ pinfo, iConnectionId, NULL,
iSegmentLength - iBeginLength, !bLastSegment);
if (fd_head != NULL && pinfo->fd->num == fd_head->reassembled_in)
{
@@ -2556,8 +2557,8 @@ dissect_mq_heur_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
static void
mq_init(void)
{
- fragment_table_init(&mq_fragment_table);
- reassembled_table_init(&mq_reassembled_table);
+ reassembly_table_init(&mq_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void
diff --git a/epan/dissectors/packet-mux27010.c b/epan/dissectors/packet-mux27010.c
index bb716ffdef..727bd38567 100644
--- a/epan/dissectors/packet-mux27010.c
+++ b/epan/dissectors/packet-mux27010.c
@@ -289,8 +289,7 @@ static gint ett_msg_fragments = -1;
"Message fragments"
};
-static GHashTable *msg_fragment_table = NULL;
-static GHashTable *msg_reassembled_table = NULL;
+static reassembly_table msg_reassembly_table;
@@ -1059,10 +1058,11 @@ dissect_mux27010(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
memcpy(&pinfo_tmp, pinfo, sizeof(*pinfo));
- frag_msg = fragment_add_seq_check(tvb, tmpOffsetBegin, pinfo,
+ frag_msg = fragment_add_seq_check(&msg_reassembly_table,
+ tvb, tmpOffsetBegin,
+ pinfo,
msg_seqid, /* ID for fragments belonging together */
- msg_fragment_table, /* list of message fragments */
- msg_reassembled_table, /* list of reassembled messages */
+ NULL,
msg_num, /* fragment sequence number */
(tmpOffsetEnd-tmpOffsetBegin)+1, /* fragment length */
msg_flag); /* More fragments? */
@@ -1134,8 +1134,8 @@ mux27010_init(void)
/*
* Initialize the fragment and reassembly tables.
*/
- fragment_table_init(&msg_fragment_table);
- reassembled_table_init(&msg_reassembled_table);
+ reassembly_table_init(&msg_reassembly_table,
+ &addresses_reassembly_table_functions);
}
/*Register the protocol*/
diff --git a/epan/dissectors/packet-ncp-int.h b/epan/dissectors/packet-ncp-int.h
index e2d9a597ef..b7daacb15a 100644
--- a/epan/dissectors/packet-ncp-int.h
+++ b/epan/dissectors/packet-ncp-int.h
@@ -155,8 +155,6 @@ extern gint ett_nds_segments;
extern gint ett_nds_segment;
/*extern dissector_handle_t nds_data_handle;*/
-extern GHashTable *nds_fragment_table;
-extern GHashTable *nds_reassembled_table;
/*
* NCP packet types.
diff --git a/epan/dissectors/packet-ncp.c b/epan/dissectors/packet-ncp.c
index 0c822940a1..d1b4240ca3 100644
--- a/epan/dissectors/packet-ncp.c
+++ b/epan/dissectors/packet-ncp.c
@@ -110,9 +110,6 @@ static struct novell_tap ncp_tap;
static struct ncp_common_header header;
static struct ncp_common_header *ncp_hdr;
-/* Tables for reassembly of fragments. */
-GHashTable *nds_fragment_table = NULL;
-GHashTable *nds_reassembled_table = NULL;
dissector_handle_t nds_data_handle;
/* desegmentation of NCP over TCP */
diff --git a/epan/dissectors/packet-ncp2222.inc b/epan/dissectors/packet-ncp2222.inc
index 2f3c2b1077..be08cc62d1 100644
--- a/epan/dissectors/packet-ncp2222.inc
+++ b/epan/dissectors/packet-ncp2222.inc
@@ -83,6 +83,9 @@ static const fragment_items nds_frag_items = {
"segments"
};
+/* Table for reassembly of fragments. */
+static reassembly_table nds_reassembly_table;
+
#define NDS_TAG_NO_SUCH_ENTRY 0x00000000
#define NDS_TAG_LOCAL_ENTRY 0x00000001
#define NDS_TAG_REMOTE_ENTRY 0x00000002
@@ -1695,8 +1698,8 @@ ncp_init_protocol(void)
int i;
/* fragment */
- fragment_table_init(&nds_fragment_table);
- reassembled_table_init(&nds_reassembled_table);
+ reassembly_table_init(&nds_reassembly_table,
+ &addresses_reassembly_table_functions);
for (i = 0; i < 99; i++) {
frags[i].nds_frag = 0xfffffff0;
@@ -7236,7 +7239,7 @@ nds_defrag(tvbuff_t *tvb, packet_info *pinfo, guint32 nw_connection, guint8 sequ
frags[frag_count].nds_frag_version = request_value->nds_version;
frags[frag_count].nds_frag_flags = request_value->req_nds_flags;
frags[frag_count].nds_frag_prot_flags = request_value->req_nds_prot_flags;
- fd_head = fragment_add_seq_next(tvb, 0, pinfo, tid, nds_fragment_table, nds_reassembled_table, len, request_value->nds_frag);
+ fd_head = fragment_add_seq_next(&nds_reassembly_table, tvb, 0, pinfo, tid, NULL, len, request_value->nds_frag);
frags[frag_count].sequence = sequence;
frags[frag_count].nds_length = 1;
}
@@ -7248,7 +7251,7 @@ nds_defrag(tvbuff_t *tvb, packet_info *pinfo, guint32 nw_connection, guint8 sequ
if (!pinfo->fd->flags.visited)
{
if (sequence != frags[frag_count].sequence) {
- fd_head = fragment_add_seq_next(tvb, 16, pinfo, tid, nds_fragment_table, nds_reassembled_table, len-16, request_value->nds_frag);
+ fd_head = fragment_add_seq_next(&nds_reassembly_table, tvb, 16, pinfo, tid, NULL, len-16, request_value->nds_frag);
frags[frag_count].sequence = sequence;
}
else
@@ -7261,7 +7264,7 @@ nds_defrag(tvbuff_t *tvb, packet_info *pinfo, guint32 nw_connection, guint8 sequ
}
else
{
- fd_head = fragment_add_seq_next(tvb, 16, pinfo, tid, nds_fragment_table, nds_reassembled_table, len-16, request_value->nds_frag);
+ fd_head = fragment_add_seq_next(&nds_reassembly_table, tvb, 16, pinfo, tid, NULL, len-16, request_value->nds_frag);
frags[frag_count].sequence = sequence;
}
}
diff --git a/epan/dissectors/packet-ndmp.c b/epan/dissectors/packet-ndmp.c
index 3b51cfc8f3..5b51fac8e4 100644
--- a/epan/dissectors/packet-ndmp.c
+++ b/epan/dissectors/packet-ndmp.c
@@ -283,8 +283,7 @@ static const fragment_items ndmp_frag_items = {
"NDMP fragments"
};
-static GHashTable *ndmp_fragment_table = NULL;
-static GHashTable *ndmp_reassembled_table = NULL;
+static reassembly_table ndmp_reassembly_table;
/* XXX someone should start adding the new stuff from v3, v4 and v5*/
#define NDMP_PROTOCOL_UNKNOWN 0
@@ -3249,10 +3248,8 @@ dissect_ndmp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
pinfo->fragmented = TRUE;
- frag_msg = fragment_add_seq_check(tvb, 4, pinfo,
- seq,
- ndmp_fragment_table,
- ndmp_reassembled_table,
+ frag_msg = fragment_add_seq_check(&ndmp_reassembly_table,
+ tvb, 4, pinfo, seq, NULL,
frag_num,
tvb_length_remaining(tvb, offset)-4,
!(ndmp_rm & RPC_RM_LASTFRAG));
@@ -3538,8 +3535,8 @@ dissect_ndmp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
static void
ndmp_init(void)
{
- fragment_table_init(&ndmp_fragment_table);
- reassembled_table_init(&ndmp_reassembled_table);
+ reassembly_table_init(&ndmp_reassembly_table,
+ &addresses_reassembly_table_functions);
}
diff --git a/epan/dissectors/packet-ndps.c b/epan/dissectors/packet-ndps.c
index a09a5d1b8f..5383d422e2 100644
--- a/epan/dissectors/packet-ndps.c
+++ b/epan/dissectors/packet-ndps.c
@@ -42,9 +42,8 @@
/* Limit the number of items we can add to the tree. */
#define NDPS_MAX_ITEMS 100
-/* Tables for reassembly of fragments. */
-static GHashTable *ndps_fragment_table = NULL;
-static GHashTable *ndps_reassembled_table = NULL;
+/* Table for reassembly of fragments. */
+static reassembly_table ndps_reassembly_table;
/* desegmentation of ndps */
static gboolean ndps_defragment = TRUE;
@@ -4103,8 +4102,8 @@ static void
ndps_init_protocol(void)
{
/* fragment */
- fragment_table_init(&ndps_fragment_table);
- reassembled_table_init(&ndps_reassembled_table);
+ reassembly_table_init(&ndps_reassembly_table,
+ &addresses_reassembly_table_functions);
if (ndps_req_hash)
g_hash_table_destroy(ndps_req_hash);
@@ -4393,7 +4392,7 @@ ndps_defrag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
len = tvb_reported_length(tvb);
if (tvb_length(tvb) >= len)
{
- fd_head = fragment_add_seq_next(tvb, 0, pinfo, tid, ndps_fragment_table, ndps_reassembled_table, len, !spx_info_p->eom);
+ fd_head = fragment_add_seq_next(&ndps_reassembly_table, tvb, 0, pinfo, tid, NULL, len, !spx_info_p->eom);
if (fd_head != NULL)
{
/* Is this the last fragment? EOM will indicate */
diff --git a/epan/dissectors/packet-netbios.c b/epan/dissectors/packet-netbios.c
index ce5b4371a8..abaf5f80b7 100644
--- a/epan/dissectors/packet-netbios.c
+++ b/epan/dissectors/packet-netbios.c
@@ -188,9 +188,8 @@ static const value_string nb_name_type_vals[] = {
{0x00, NULL}
};
-/* Tables for reassembly of fragments. */
-static GHashTable *netbios_fragment_table = NULL;
-static GHashTable *netbios_reassembled_table = NULL;
+/* Table for reassembly of fragments. */
+static reassembly_table netbios_reassembly_table;
/* defragmentation of NetBIOS Frame */
static gboolean netbios_defragment = TRUE;
@@ -1169,10 +1168,9 @@ dissect_netbios(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
len = tvb_reported_length_remaining(tvb, offset);
if (netbios_defragment &&
tvb_bytes_exist(tvb, offset, len)) {
- fd_head = fragment_add_seq_next(tvb, offset,
- pinfo, session_id,
- netbios_fragment_table,
- netbios_reassembled_table,
+ fd_head = fragment_add_seq_next(&netbios_reassembly_table,
+ tvb, offset,
+ pinfo, session_id, NULL,
len, command == NB_DATA_FIRST_MIDDLE);
if (fd_head != NULL) {
if (fd_head->next != NULL) {
@@ -1232,10 +1230,10 @@ static void
netbios_init(void)
{
/*
- * Initialize the fragment and reassembly tables.
+ * Initialize the reassembly table.
*/
- fragment_table_init(&netbios_fragment_table);
- reassembled_table_init(&netbios_reassembled_table);
+ reassembly_table_init(&netbios_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void proto_register_netbios(void)
diff --git a/epan/dissectors/packet-openvpn.c b/epan/dissectors/packet-openvpn.c
index d8078c0e09..a4871d5136 100644
--- a/epan/dissectors/packet-openvpn.c
+++ b/epan/dissectors/packet-openvpn.c
@@ -106,8 +106,7 @@ static const value_string openvpn_message_types[] =
};
/* everything used during the reassembly process */
-static GHashTable *msg_fragment_table = NULL;
-static GHashTable *msg_reassembled_table = NULL;
+static reassembly_table msg_reassembly_table;
static gint ett_openvpn_fragment = -1;
static gint ett_openvpn_fragments = -1;
@@ -148,8 +147,8 @@ static const fragment_items openvpn_frag_items = {
static void
openvpn_reassemble_init(void)
{
- fragment_table_init(&msg_fragment_table);
- reassembled_table_init(&msg_reassembled_table);
+ reassembly_table_init(&msg_reassembly_table,
+ &addresses_reassembly_table_functions);
}
/* we check the leading 4 byte of a suspected hmac for 0x00 bytes,
@@ -347,12 +346,12 @@ dissect_openvpn_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
pinfo->fragmented = TRUE;
frag_msg = fragment_add_seq_next(
+ &msg_reassembly_table,
tvb,
offset,
pinfo,
msg_sessionid, /* ID for fragments belonging together */
- msg_fragment_table, /* list of message fragments */
- msg_reassembled_table, /* list of reassembled messages */
+ NULL,
msg_length_remaining, /* fragment length - to the end */
!(msg_lastframe)); /* More fragments ? */
diff --git a/epan/dissectors/packet-ositp.c b/epan/dissectors/packet-ositp.c
index 9011cd04e8..342f89d418 100644
--- a/epan/dissectors/packet-ositp.c
+++ b/epan/dissectors/packet-ositp.c
@@ -296,8 +296,7 @@ static heur_dissector_list_t cltp_heur_subdissector_list;
/*
* Reassembly of COTP.
*/
-static GHashTable *cotp_segment_table = NULL;
-static GHashTable *cotp_reassembled_table = NULL;
+static reassembly_table cotp_reassembly_table;
static guint16 cotp_dst_ref = 0;
static gboolean cotp_frame_reset = FALSE;
static gboolean cotp_last_fragment = FALSE;
@@ -1184,10 +1183,9 @@ static int ositp_decode_DT(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
* Note also that TP0 has no sequence number, and relies on
* the protocol atop which it runs to guarantee in-order delivery.
*/
- fd_head = fragment_add_seq_next(next_tvb, 0, pinfo, dst_ref,
- cotp_segment_table,
- cotp_reassembled_table,
- fragment_length, fragment);
+ fd_head = fragment_add_seq_next(&cotp_reassembly_table,
+ next_tvb, 0, pinfo, dst_ref, NULL,
+ fragment_length, fragment);
if (fd_head && fd_head->next) {
/* don't use -1 if fragment length is zero (throws Exception) */
proto_tree_add_text(cotp_tree, tvb, offset, (fragment_length) ? -1 : 0,
@@ -2259,8 +2257,16 @@ static gint dissect_ositp_inactive(tvbuff_t *tvb, packet_info *pinfo, proto_tree
static void
cotp_reassemble_init(void)
{
- fragment_table_init(&cotp_segment_table);
- reassembled_table_init(&cotp_reassembled_table);
+ /*
+ * XXX - this is a connection-oriented transport-layer protocol,
+ * so we should probably use more than just network-layer
+ * endpoint addresses to match segments together, but the functions
+ * in addresses_ports_reassembly_table_functions do matching based
+ * on port numbers, so they won't let us ensure that segments from
+ * different connections don't get assembled together.
+ */
+ reassembly_table_init(&cotp_reassembly_table,
+ &addresses_reassembly_table_functions);
cotp_dst_ref = 0;
}
diff --git a/epan/dissectors/packet-p_mul.c b/epan/dissectors/packet-p_mul.c
index eb984a9fe9..a357601ce7 100644
--- a/epan/dissectors/packet-p_mul.c
+++ b/epan/dissectors/packet-p_mul.c
@@ -201,8 +201,7 @@ static gint decode_option = DECODE_NONE;
static gboolean use_relative_msgid = TRUE;
static gboolean use_seq_ack_analysis = TRUE;
-static GHashTable *p_mul_fragment_table = NULL;
-static GHashTable *p_mul_reassembled_table = NULL;
+static reassembly_table p_mul_reassembly_table;
static guint32 message_id_offset = 0;
@@ -1294,8 +1293,8 @@ static void dissect_p_mul (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (pdu_type == Address_PDU && no_pdus > 0) {
/* Start fragment table */
- fragment_start_seq_check (pinfo, message_id, p_mul_fragment_table,
- no_pdus - 1);
+ fragment_start_seq_check (&p_mul_reassembly_table,
+ pinfo, message_id, NULL, no_pdus - 1);
} else if (pdu_type == Data_PDU) {
fragment_data *frag_msg;
tvbuff_t *new_tvb;
@@ -1303,10 +1302,9 @@ static void dissect_p_mul (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
pinfo->fragmented = TRUE;
/* Add fragment to fragment table */
- frag_msg = fragment_add_seq_check (tvb, offset, pinfo, message_id,
- p_mul_fragment_table,
- p_mul_reassembled_table, seq_no - 1,
- data_len, TRUE);
+ frag_msg = fragment_add_seq_check (&p_mul_reassembly_table,
+ tvb, offset, pinfo, message_id, NULL,
+ seq_no - 1, data_len, TRUE);
new_tvb = process_reassembled_data (tvb, offset, pinfo,
"Reassembled P_MUL", frag_msg,
&p_mul_frag_items, NULL, tree);
@@ -1338,8 +1336,8 @@ static void dissect_p_mul (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void p_mul_init_routine (void)
{
- fragment_table_init (&p_mul_fragment_table);
- reassembled_table_init (&p_mul_reassembled_table);
+ reassembly_table_init (&p_mul_reassembly_table,
+ &addresses_reassembly_table_functions);
message_id_offset = 0;
if (p_mul_id_hash_table) {
diff --git a/epan/dissectors/packet-pop.c b/epan/dissectors/packet-pop.c
index 3f5ef9de3a..fea778027d 100644
--- a/epan/dissectors/packet-pop.c
+++ b/epan/dissectors/packet-pop.c
@@ -78,8 +78,7 @@ static dissector_handle_t ssl_handle = NULL;
/* desegmentation of POP command and response lines */
static gboolean pop_data_desegment = TRUE;
-static GHashTable *pop_data_segment_table = NULL;
-static GHashTable *pop_data_reassembled_table = NULL;
+static reassembly_table pop_data_reassembly_table;
static const fragment_items pop_data_frag_items = {
/* Fragment subtrees */
@@ -231,10 +230,10 @@ dissect_pop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
p_add_proto_data(pinfo->fd, proto_pop, frame_data_p);
}
- frag_msg = fragment_add_seq_next(tvb, 0, pinfo,
+ frag_msg = fragment_add_seq_next(&pop_data_reassembly_table, tvb, 0,
+ pinfo,
frame_data_p->conversation_id,
- pop_data_segment_table,
- pop_data_reassembled_table,
+ NULL,
tvb_length(tvb),
frame_data_p->more_frags);
@@ -386,8 +385,8 @@ static gboolean response_is_continuation(const guchar *data)
static void pop_data_reassemble_init (void)
{
- fragment_table_init (&pop_data_segment_table);
- reassembled_table_init (&pop_data_reassembled_table);
+ reassembly_table_init (&pop_data_reassembly_table,
+ &addresses_ports_reassembly_table_functions);
}
void
diff --git a/epan/dissectors/packet-ppi.c b/epan/dissectors/packet-ppi.c
index 1fda7f3445..27cd3b54b1 100644
--- a/epan/dissectors/packet-ppi.c
+++ b/epan/dissectors/packet-ppi.c
@@ -362,9 +362,8 @@ static const value_string vs_80211_common_phy_type[] = {
};
/* XXX - End - Copied from packet-radiotap.c */
-/* Tables for A-MPDU reassembly */
-static GHashTable *ampdu_fragment_table = NULL;
-static GHashTable *ampdu_reassembled_table = NULL;
+/* Table for A-MPDU reassembly */
+static reassembly_table ampdu_reassembly_table;
/* Reassemble A-MPDUs? */
static gboolean ppi_ampdu_reassemble = TRUE;
@@ -904,7 +903,7 @@ dissect_ppi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Make sure we aren't going to go past AGGREGATE_MAX
* and caclulate our full A-MPDU length */
- fd_head = fragment_get(pinfo, ampdu_id, ampdu_fragment_table);
+ fd_head = fragment_get(&ampdu_reassembly_table, pinfo, ampdu_id, NULL);
while (fd_head) {
ampdu_len += fd_head->len + PADDING4(fd_head->len) + 4;
fd_head = fd_head->next;
@@ -926,13 +925,12 @@ dissect_ppi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* routine which would un-do the work we just did. We're using
* the reassembly code to track MPDU sizes and frame numbers.
*/
- /*??fd_head = */fragment_add_seq_next(tvb, offset, pinfo, ampdu_id,
- ampdu_fragment_table, ampdu_reassembled_table,
- len_remain, TRUE);
+ /*??fd_head = */fragment_add_seq_next(&ampdu_reassembly_table,
+ tvb, offset, pinfo, ampdu_id, NULL, len_remain, TRUE);
pinfo->fragmented = TRUE;
/* Do reassembly? */
- fd_head = fragment_get(pinfo, ampdu_id, ampdu_fragment_table);
+ fd_head = fragment_get(&ampdu_reassembly_table, pinfo, ampdu_id, NULL);
/* Show our fragments */
if (fd_head && tree) {
@@ -1014,8 +1012,8 @@ dissect_ppi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void
ampdu_reassemble_init(void)
{
- fragment_table_init(&ampdu_fragment_table);
- reassembled_table_init(&ampdu_reassembled_table);
+ reassembly_table_init(&ampdu_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void
diff --git a/epan/dissectors/packet-q931.c b/epan/dissectors/packet-q931.c
index fe69fe65dc..b6ea896ead 100644
--- a/epan/dissectors/packet-q931.c
+++ b/epan/dissectors/packet-q931.c
@@ -141,9 +141,8 @@ static const fragment_items q931_frag_items = {
"segments"
};
-/* Tables for reassembly of fragments. */
-static GHashTable *q931_fragment_table = NULL;
-static GHashTable *q931_reassembled_table = NULL;
+/* Table for reassembly of fragments. */
+static reassembly_table q931_reassembly_table;
/* Preferences */
static gboolean q931_reassembly = TRUE;
@@ -2670,13 +2669,13 @@ dissect_q931_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
offset += 1 + 1 + info_element_len;
/* Reassembly */
frag_len = tvb_reported_length_remaining(tvb, offset);
- if (first_frag && fragment_get(pinfo, call_ref_val, q931_fragment_table)) {
+ if (first_frag && fragment_get(&q931_reassembly_table, pinfo, call_ref_val, NULL)) {
/* there are some unreassembled segments, ignore them */
- fragment_end_seq_next(pinfo, call_ref_val, q931_fragment_table, q931_reassembled_table);
+ fragment_end_seq_next(&q931_reassembly_table, pinfo, call_ref_val, NULL);
}
- fd_head = fragment_add_seq_next(tvb, offset, pinfo, call_ref_val,
- q931_fragment_table, q931_reassembled_table,
- frag_len, more_frags);
+ fd_head = fragment_add_seq_next(&q931_reassembly_table,
+ tvb, offset, pinfo, call_ref_val, NULL,
+ frag_len, more_frags);
if (fd_head) {
if (pinfo->fd->num == fd_head->reassembled_in) { /* last fragment */
if (fd_head->next != NULL) { /* 2 or more segments */
@@ -3338,8 +3337,8 @@ dissect_q931_ie_cs7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void
q931_init(void) {
/* Initialize the fragment and reassembly tables */
- fragment_table_init(&q931_fragment_table);
- reassembled_table_init(&q931_reassembled_table);
+ reassembly_table_init(&q931_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void
diff --git a/epan/dissectors/packet-reload.c b/epan/dissectors/packet-reload.c
index 509696450b..95f0ab21ef 100644
--- a/epan/dissectors/packet-reload.c
+++ b/epan/dissectors/packet-reload.c
@@ -1020,14 +1020,13 @@ static const value_string applicationids[] = {
/*
* defragmentation
*/
-static GHashTable *reload_fragment_table = NULL;
-static GHashTable *reload_reassembled_table = NULL;
+static reassembly_table reload_reassembly_table;
static void
reload_defragment_init(void)
{
- fragment_table_init(&reload_fragment_table);
- reassembled_table_init(&reload_reassembled_table);
+ reassembly_table_init(&reload_reassembly_table,
+ &addresses_reassembly_table_functions);
}
@@ -4119,10 +4118,10 @@ dissect_reload_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
reload_fd_head = NULL;
if (tvb_bytes_exist(tvb, offset, msg_length - offset)) {
- reload_fd_head = fragment_add_check(tvb, offset, pinfo,
+ reload_fd_head = fragment_add_check(&reload_reassembly_table, tvb, offset,
+ pinfo,
transaction_id[0]^transaction_id[1],
- reload_fragment_table,
- reload_reassembled_table,
+ NULL,
fragment,
msg_length - offset,
!last_fragment);
diff --git a/epan/dissectors/packet-rpc.c b/epan/dissectors/packet-rpc.c
index 5111fcbf2e..2fa5e8103e 100644
--- a/epan/dissectors/packet-rpc.c
+++ b/epan/dissectors/packet-rpc.c
@@ -2941,8 +2941,15 @@ dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Defragmentation of RPC-over-TCP records */
/* table to hold defragmented RPC records */
-static GHashTable *rpc_fragment_table = NULL;
+static reassembly_table rpc_fragment_table;
+/*
+ * XXX - can we eliminate this by defining our own key-handling functions
+ * for rpc_fragment_table? (Note that those functions must look at
+ * not only the addresses of the endpoints, but the ports of the endpoints,
+ * so that they don't try to combine fragments from different TCP
+ * connections.)
+ */
static GHashTable *rpc_reassembly_table = NULL;
typedef struct _rpc_fragment_key {
@@ -3302,8 +3309,9 @@ dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
/*
* Start defragmentation.
*/
- ipfd_head = fragment_add_multiple_ok(tvb, offset + 4,
- pinfo, rfk->start_seq, rpc_fragment_table,
+ ipfd_head = fragment_add_multiple_ok(&rpc_fragment_table,
+ tvb, offset + 4,
+ pinfo, rfk->start_seq, NULL,
rfk->offset, len - 4, TRUE);
/*
@@ -3359,8 +3367,8 @@ dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
* a record. This means we must defragment it.
* Add it to the defragmentation lists.
*/
- ipfd_head = fragment_add_multiple_ok(tvb, offset + 4, pinfo,
- rfk->start_seq, rpc_fragment_table,
+ ipfd_head = fragment_add_multiple_ok(&rpc_fragment_table,
+ tvb, offset + 4, pinfo, rfk->start_seq, NULL,
rfk->offset, len - 4, !(rpc_rm & RPC_RM_LASTFRAG));
if (ipfd_head == NULL) {
@@ -3782,7 +3790,8 @@ rpc_init_protocol(void)
rpc_reassembly_table = g_hash_table_new(rpc_fragment_hash,
rpc_fragment_equal);
- fragment_table_init(&rpc_fragment_table);
+ reassembly_table_init(&rpc_fragment_table,
+ &addresses_ports_reassembly_table_functions);
}
/* will be called once from register.c at startup time */
diff --git a/epan/dissectors/packet-rtp.c b/epan/dissectors/packet-rtp.c
index 41557d4b2d..68843b5b88 100644
--- a/epan/dissectors/packet-rtp.c
+++ b/epan/dissectors/packet-rtp.c
@@ -97,7 +97,7 @@ typedef struct _rtp_private_conv_info {
emem_tree_t *multisegment_pdus;
} rtp_private_conv_info;
-static GHashTable *fragment_table = NULL;
+static reassembly_table rtp_reassembly_table;
static int hf_rtp_fragments = -1;
static int hf_rtp_fragment = -1;
@@ -790,7 +790,8 @@ static const value_string srtp_auth_alg_vals[] =
static void
rtp_fragment_init(void)
{
- fragment_table_init(&fragment_table);
+ reassembly_table_init(&rtp_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void
@@ -1110,8 +1111,10 @@ dissect_rtp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
* first pass, that's our best guess, and if it's not, what we
* say gets ignored anyway.
*/
- fd_head = fragment_add_seq(tvb, offset, pinfo, fid, fragment_table,
- seqno-msp->startseq, data_len, FALSE);
+ fd_head = fragment_add_seq(&rtp_reassembly_table,
+ tvb, offset, pinfo, fid, NULL,
+ seqno-msp->startseq, data_len,
+ FALSE, 0);
newtvb = process_reassembled_data(tvb,offset, pinfo, "Reassembled RTP", fd_head,
&rtp_fragment_items, NULL, tree);
@@ -1134,7 +1137,8 @@ dissect_rtp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
g_debug("\tNo complete pdus in payload" );
#endif
/* Mark the fragments and not complete yet */
- fragment_set_partial_reassembly(pinfo, fid, fragment_table);
+ fragment_set_partial_reassembly(&rtp_reassembly_table,
+ pinfo, fid, NULL);
/* we must need another segment */
msp->endseq = MIN(msp->endseq,seqno) + 1;
@@ -1201,8 +1205,9 @@ dissect_rtp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
/*
* Add the fragment to the fragment table
*/
- fd_head = fragment_add_seq(newtvb,deseg_offset, pinfo, seqno, fragment_table, 0, frag_len,
- TRUE );
+ fd_head = fragment_add_seq(&rtp_reassembly_table,
+ newtvb, deseg_offset, pinfo, seqno, NULL, 0, frag_len,
+ TRUE, 0);
if(fd_head != NULL)
{
diff --git a/epan/dissectors/packet-rtse.c b/epan/dissectors/packet-rtse.c
index de151473b7..12e40338fc 100644
--- a/epan/dissectors/packet-rtse.c
+++ b/epan/dissectors/packet-rtse.c
@@ -117,8 +117,7 @@ static dissector_table_t rtse_oid_dissector_table=NULL;
static GHashTable *oid_table=NULL;
static gint ett_rtse_unknown = -1;
-static GHashTable *rtse_segment_table = NULL;
-static GHashTable *rtse_reassembled_table = NULL;
+static reassembly_table rtse_reassembly_table;
static int hf_rtse_segment_data = -1;
static int hf_rtse_fragments = -1;
@@ -732,7 +731,7 @@ dissect_rtse_RTSE_apdus(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset
/*--- End of included file: packet-rtse-fn.c ---*/
-#line 185 "../../asn1/rtse/packet-rtse-template.c"
+#line 184 "../../asn1/rtse/packet-rtse-template.c"
/*
* Dissect RTSE PDUs inside a PPDU.
@@ -786,8 +785,8 @@ dissect_rtse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
session->rtse_reassemble = TRUE;
}
if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) {
- frag_msg = fragment_end_seq_next (pinfo, rtse_id, rtse_segment_table,
- rtse_reassembled_table);
+ frag_msg = fragment_end_seq_next (&rtse_reassembly_table,
+ pinfo, rtse_id, NULL);
next_tvb = process_reassembled_data (tvb, offset, pinfo, "Reassembled RTSE",
frag_msg, &rtse_frag_items, NULL, parent_tree);
}
@@ -803,9 +802,10 @@ dissect_rtse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
fragment_length = tvb_length_remaining (data_tvb, 0);
proto_item_append_text(asn1_ctx.created_item, " (%u byte%s)", fragment_length,
plurality(fragment_length, "", "s"));
- frag_msg = fragment_add_seq_next (data_tvb, 0, pinfo,
- rtse_id, rtse_segment_table,
- rtse_reassembled_table, fragment_length, TRUE);
+ frag_msg = fragment_add_seq_next (&rtse_reassembly_table,
+ data_tvb, 0, pinfo,
+ rtse_id, NULL,
+ fragment_length, TRUE);
if (frag_msg && pinfo->fd->num != frag_msg->reassembled_in) {
/* Add a "Reassembled in" link if not reassembled in this frame */
proto_tree_add_uint (tree, *(rtse_frag_items.hf_reassembled_in),
@@ -855,8 +855,8 @@ dissect_rtse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
static void rtse_reassemble_init (void)
{
- fragment_table_init (&rtse_segment_table);
- reassembled_table_init (&rtse_reassembled_table);
+ reassembly_table_init (&rtse_reassembly_table,
+ &addresses_reassembly_table_functions);
}
/*--- proto_register_rtse -------------------------------------------*/
diff --git a/epan/dissectors/packet-sccp.c b/epan/dissectors/packet-sccp.c
index 4fb754b71e..28d5f120f6 100644
--- a/epan/dissectors/packet-sccp.c
+++ b/epan/dissectors/packet-sccp.c
@@ -738,8 +738,7 @@ static const fragment_items sccp_xudt_msg_frag_items = {
"SCCP XUDT Message fragments"
};
-static GHashTable *sccp_xudt_msg_fragment_table = NULL;
-static GHashTable *sccp_xudt_msg_reassembled_table = NULL;
+static reassembly_table sccp_xudt_msg_reassembly_table;
#define SCCP_USER_DATA 0
@@ -2870,10 +2869,11 @@ dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
} else {
save_fragmented = pinfo->fragmented;
pinfo->fragmented = TRUE;
- frag_msg = fragment_add_seq_next(tvb, variable_pointer1 + 1, pinfo,
+ frag_msg = fragment_add_seq_next(&sccp_xudt_msg_reassembly_table,
+ tvb, variable_pointer1 + 1,
+ pinfo,
source_local_ref, /* ID for fragments belonging together */
- sccp_xudt_msg_fragment_table, /* list of message fragments */
- sccp_xudt_msg_reassembled_table, /* list of reassembled messages */
+ NULL,
tvb_get_guint8(tvb,variable_pointer1), /* fragment length - to the end */
more); /* More fragments? */
@@ -3109,15 +3109,17 @@ dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
save_fragmented = pinfo->fragmented;
pinfo->fragmented = TRUE;
- frag_msg = fragment_add_seq_next(tvb, variable_pointer3 + 1, pinfo,
+ frag_msg = fragment_add_seq_next(&sccp_xudt_msg_reassembly_table,
+ tvb, variable_pointer3 + 1,
+ pinfo,
source_local_ref, /* ID for fragments belonging together */
- sccp_xudt_msg_fragment_table, /* list of message fragments */
- sccp_xudt_msg_reassembled_table, /* list of reassembled messages */
+ NULL,
tvb_get_guint8(tvb,variable_pointer3), /* fragment length - to the end */
more_frag); /* More fragments? */
if ((octet & 0x80) == 0x80) /*First segment, set number of segments*/
- fragment_set_tot_len(pinfo, source_local_ref, sccp_xudt_msg_fragment_table,(octet & 0xf));
+ fragment_set_tot_len(&sccp_xudt_msg_reassembly_table,
+ pinfo, source_local_ref, NULL, (octet & 0xf));
new_tvb = process_reassembled_data(tvb, variable_pointer3 + 1,
pinfo, "Reassembled SCCP",
@@ -3196,15 +3198,17 @@ dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
save_fragmented = pinfo->fragmented;
pinfo->fragmented = TRUE;
- frag_msg = fragment_add_seq_next(tvb, variable_pointer3 + 1, pinfo,
+ frag_msg = fragment_add_seq_next(&sccp_xudt_msg_reassembly_table,
+ tvb, variable_pointer3 + 1,
+ pinfo,
source_local_ref, /* ID for fragments belonging together */
- sccp_xudt_msg_fragment_table, /* list of message fragments */
- sccp_xudt_msg_reassembled_table, /* list of reassembled messages */
+ NULL,
tvb_get_guint8(tvb,variable_pointer3), /* fragment length - to the end */
more_frag); /* More fragments? */
if ((octet & 0x80) == 0x80) /*First segment, set number of segments*/
- fragment_set_tot_len(pinfo, source_local_ref, sccp_xudt_msg_fragment_table,(octet & 0xf));
+ fragment_set_tot_len(&sccp_xudt_msg_reassembly_table,
+ pinfo, source_local_ref, NULL, (octet & 0xf));
new_tvb = process_reassembled_data(tvb, variable_pointer3 + 1,
pinfo, "Reassembled SCCP",
@@ -3470,9 +3474,8 @@ static void
init_sccp(void)
{
next_assoc_id = 1;
- fragment_table_init (&sccp_xudt_msg_fragment_table);
- reassembled_table_init(&sccp_xudt_msg_reassembled_table);
-
+ reassembly_table_init (&sccp_xudt_msg_reassembly_table,
+ &addresses_reassembly_table_functions);
}
/* Register the protocol with Wireshark */
diff --git a/epan/dissectors/packet-scsi.c b/epan/dissectors/packet-scsi.c
index 7d81410f39..ed38aa76ad 100644
--- a/epan/dissectors/packet-scsi.c
+++ b/epan/dissectors/packet-scsi.c
@@ -353,8 +353,7 @@ static int scsi_tap = -1;
/* Defragment of SCSI DATA IN/OUT */
static gboolean scsi_defragment = FALSE;
-static GHashTable *scsi_fragment_table = NULL;
-static GHashTable *scsi_reassembled_table = NULL;
+static reassembly_table scsi_reassembly_table;
/*
* Required by all commands
@@ -371,8 +370,8 @@ const int *cdb_control_fields[6] = {
static void
scsi_defragment_init(void)
{
- fragment_table_init(&scsi_fragment_table);
- reassembled_table_init(&scsi_reassembled_table);
+ reassembly_table_init(&scsi_reassembly_table,
+ &addresses_reassembly_table_functions);
}
static const fragment_items scsi_frag_items = {
@@ -5093,10 +5092,10 @@ dissect_scsi_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if ((tvb_length_remaining(tvb,offset) + relative_offset) != expected_length) {
more_frags = TRUE;
}
- ipfd_head = fragment_add_check(tvb, offset, pinfo,
+ ipfd_head = fragment_add_check(&scsi_reassembly_table, tvb, offset,
+ pinfo,
itlq->first_exchange_frame, /* key */
- scsi_fragment_table,
- scsi_reassembled_table,
+ NULL,
relative_offset,
tvb_length_remaining(tvb, offset),
more_frags);
diff --git a/epan/dissectors/packet-ses.c b/epan/dissectors/packet-ses.c
index 5b75b5feda..71239e2947 100644
--- a/epan/dissectors/packet-ses.c
+++ b/epan/dissectors/packet-ses.c
@@ -182,8 +182,7 @@ static int proto_clses = -1;
static dissector_handle_t pres_handle = NULL;
-static GHashTable *ses_fragment_table = NULL;
-static GHashTable *ses_reassembled_table = NULL;
+static reassembly_table ses_reassembly_table;
static const fragment_items ses_frag_items = {
/* Segment subtrees */
@@ -1148,9 +1147,10 @@ dissect_spdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
ti = proto_tree_add_item (ses_tree, hf_ses_segment_data, tvb, offset,
fragment_len, ENC_NA);
proto_item_append_text (ti, " (%d byte%s)", fragment_len, plurality (fragment_len, "", "s"));
- frag_msg = fragment_add_seq_next (tvb, offset, pinfo,
- ses_id, ses_fragment_table,
- ses_reassembled_table, fragment_len,
+ frag_msg = fragment_add_seq_next (&ses_reassembly_table,
+ tvb, offset,
+ pinfo, ses_id, NULL,
+ fragment_len,
(enclosure_item_flags & END_SPDU) ? FALSE : TRUE);
next_tvb = process_reassembled_data (tvb, offset, pinfo, "Reassembled SES",
frag_msg, &ses_frag_items, NULL,
@@ -1221,8 +1221,8 @@ dissect_ses(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void ses_reassemble_init (void)
{
- fragment_table_init (&ses_fragment_table);
- reassembled_table_init (&ses_reassembled_table);
+ reassembly_table_init (&ses_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void
diff --git a/epan/dissectors/packet-smb-pipe.c b/epan/dissectors/packet-smb-pipe.c
index 5509bf97ea..80c5a87f99 100644
--- a/epan/dissectors/packet-smb-pipe.c
+++ b/epan/dissectors/packet-smb-pipe.c
@@ -3264,14 +3264,20 @@ proto_register_pipe_lanman(void)
static heur_dissector_list_t smb_transact_heur_subdissector_list;
-static GHashTable *dcerpc_fragment_table = NULL;
-static GHashTable *dcerpc_reassembled_table = NULL;
+static reassembly_table dcerpc_reassembly_table;
static void
smb_dcerpc_reassembly_init(void)
{
- fragment_table_init(&dcerpc_fragment_table);
- reassembled_table_init(&dcerpc_reassembled_table);
+ /*
+ * XXX - addresses_ports_reassembly_table_functions?
+ * Probably correct for SMB-over-NBT and SMB-over-TCP,
+ * as stuff from two different connections should
+ * probably not be combined, but what about other
+ * transports for SMB, e.g. NBF or Netware?
+ */
+ reassembly_table_init(&dcerpc_reassembly_table,
+ &addresses_reassembly_table_functions);
}
gboolean
@@ -3328,7 +3334,7 @@ dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree
* in this direction, by searching for its reassembly
* structure.
*/
- fd_head=fragment_get(pinfo, fid, dcerpc_fragment_table);
+ fd_head=fragment_get(&dcerpc_reassembly_table, pinfo, fid, NULL);
if(!fd_head){
/* No reassembly, so this is a new pdu. check if the
dissector wants us to reassemble it or if we
@@ -3350,12 +3356,11 @@ dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree
more data ?
*/
if(pinfo->desegment_len){
- fragment_add_check(d_tvb, 0, pinfo, fid,
- dcerpc_fragment_table,
- dcerpc_reassembled_table,
+ fragment_add_check(&dcerpc_reassembly_table,
+ d_tvb, 0, pinfo, fid, NULL,
0, reported_len, TRUE);
- fragment_set_tot_len(pinfo, fid,
- dcerpc_fragment_table,
+ fragment_set_tot_len(&dcerpc_reassembly_table,
+ pinfo, fid, NULL,
pinfo->desegment_len+reported_len);
}
goto clean_up_and_exit;
@@ -3372,8 +3377,8 @@ dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree
while(fd_head->next){
fd_head=fd_head->next;
}
- fd_head=fragment_add_check(d_tvb, 0, pinfo, fid,
- dcerpc_fragment_table, dcerpc_reassembled_table,
+ fd_head=fragment_add_check(&dcerpc_reassembly_table,
+ d_tvb, 0, pinfo, fid, NULL,
fd_head->offset+fd_head->len,
reported_len, TRUE);
@@ -3406,8 +3411,8 @@ dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree
* up so that we don't have to distinguish between the first
* pass and subsequent passes?
*/
- fd_head=fragment_add_check(d_tvb, 0, pinfo, fid, dcerpc_fragment_table,
- dcerpc_reassembled_table, 0, 0, TRUE);
+ fd_head=fragment_add_check(&dcerpc_reassembly_table,
+ d_tvb, 0, pinfo, fid, NULL, 0, 0, TRUE);
if(!fd_head){
/* we didnt find it, try any of the heuristic dissectors
and bail out
diff --git a/epan/dissectors/packet-smb.c b/epan/dissectors/packet-smb.c
index 041ed824fd..18b49f897c 100644
--- a/epan/dissectors/packet-smb.c
+++ b/epan/dissectors/packet-smb.c
@@ -1039,12 +1039,20 @@ fid_cmp(smb_fid_info_t *fida, smb_fid_info_t *fidb)
static gboolean smb_trans_reassembly = TRUE;
gboolean smb_dcerpc_reassembly = TRUE;
-static GHashTable *smb_trans_fragment_table = NULL;
+static reassembly_table smb_trans_reassembly_table;
static void
smb_trans_reassembly_init(void)
{
- fragment_table_init(&smb_trans_fragment_table);
+ /*
+ * XXX - addresses_ports_reassembly_table_functions?
+ * Probably correct for SMB-over-NBT and SMB-over-TCP,
+ * as stuff from two different connections should
+ * probably not be combined, but what about other
+ * transports for SMB, e.g. NBF or Netware?
+ */
+ reassembly_table_init(&smb_trans_reassembly_table,
+ &addresses_reassembly_table_functions);
}
static fragment_data *
@@ -1074,11 +1082,12 @@ smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
}
if (!pinfo->fd->flags.visited) {
- fd_head = fragment_add(tvb, offset, pinfo,
- si->sip->frame_req, smb_trans_fragment_table,
+ fd_head = fragment_add(&smb_trans_reassembly_table, tvb, offset,
+ pinfo, si->sip->frame_req, NULL,
pos, count, more_frags);
} else {
- fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
+ fd_head = fragment_get(&smb_trans_reassembly_table,
+ pinfo, si->sip->frame_req, NULL);
}
if (!fd_head || !(fd_head->flags & FD_DEFRAGMENTED)) {
diff --git a/epan/dissectors/packet-smtp.c b/epan/dissectors/packet-smtp.c
index ed4b974413..038d228645 100644
--- a/epan/dissectors/packet-smtp.c
+++ b/epan/dissectors/packet-smtp.c
@@ -86,8 +86,7 @@ static gboolean stmp_decryption_enabled = FALSE;
static gboolean smtp_desegment = TRUE;
static gboolean smtp_data_desegment = TRUE;
-static GHashTable *smtp_data_segment_table = NULL;
-static GHashTable *smtp_data_reassembled_table = NULL;
+static reassembly_table smtp_data_reassembly_table;
static const fragment_items smtp_data_frag_items = {
/* Fragment subtrees */
@@ -664,8 +663,8 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
plurality (length_remaining, "", "s"));
if (smtp_data_desegment) {
- frag_msg = fragment_add_seq_next(tvb, 0, pinfo, spd_frame_data->conversation_id,
- smtp_data_segment_table, smtp_data_reassembled_table,
+ frag_msg = fragment_add_seq_next(&smtp_data_reassembly_table, tvb, 0,
+ pinfo, spd_frame_data->conversation_id, NULL,
tvb_length(tvb), spd_frame_data->more_frags);
} else {
/*
@@ -692,13 +691,13 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (smtp_data_desegment) {
/* add final data segment */
if (loffset)
- fragment_add_seq_next(tvb, 0, pinfo, spd_frame_data->conversation_id,
- smtp_data_segment_table, smtp_data_reassembled_table,
+ fragment_add_seq_next(&smtp_data_reassembly_table, tvb, 0,
+ pinfo, spd_frame_data->conversation_id, NULL,
loffset, spd_frame_data->more_frags);
/* terminate the desegmentation */
- frag_msg = fragment_end_seq_next (pinfo, spd_frame_data->conversation_id, smtp_data_segment_table,
- smtp_data_reassembled_table);
+ frag_msg = fragment_end_seq_next(&smtp_data_reassembly_table,
+ pinfo, spd_frame_data->conversation_id, NULL);
}
break;
@@ -781,8 +780,8 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (smtp_data_desegment && !spd_frame_data->more_frags) {
/* terminate the desegmentation */
- frag_msg = fragment_end_seq_next (pinfo, spd_frame_data->conversation_id, smtp_data_segment_table,
- smtp_data_reassembled_table);
+ frag_msg = fragment_end_seq_next(&smtp_data_reassembly_table,
+ pinfo, spd_frame_data->conversation_id, NULL);
}
}
/*
@@ -940,8 +939,8 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void
smtp_data_reassemble_init (void)
{
- fragment_table_init (&smtp_data_segment_table);
- reassembled_table_init (&smtp_data_reassembled_table);
+ reassembly_table_init(&smtp_data_reassembly_table,
+ &addresses_ports_reassembly_table_functions);
}
diff --git a/epan/dissectors/packet-sna.c b/epan/dissectors/packet-sna.c
index 5d8e8d7096..fdddfea2bb 100644
--- a/epan/dissectors/packet-sna.c
+++ b/epan/dissectors/packet-sna.c
@@ -298,7 +298,7 @@ static dissector_handle_t data_handle;
/* Defragment fragmented SNA BIUs*/
static gboolean sna_defragment = TRUE;
-static GHashTable *sna_fragment_table = NULL;
+static reassembly_table sna_reassembly_table;
/* Format Identifier */
static const value_string sna_th_fid_vals[] = {
@@ -1684,9 +1684,9 @@ defragment_by_sequence(packet_info *pinfo, tvbuff_t *tvb, int offset, int mpf,
/* XXX - check length ??? */
frag_len = tvb_reported_length_remaining(tvb, offset);
if (tvb_bytes_exist(tvb, offset, frag_len)) {
- fd_head = fragment_add_seq(tvb, offset, pinfo, id,
- sna_fragment_table, frag_number, frag_len,
- more_frags);
+ fd_head = fragment_add_seq(&sna_reassembly_table,
+ tvb, offset, pinfo, id, NULL,
+ frag_number, frag_len, more_frags, 0);
/* We added the LAST segment and reassembly didn't
* complete. Insert a zero-length MIDDLE segment to
@@ -1695,9 +1695,9 @@ defragment_by_sequence(packet_info *pinfo, tvbuff_t *tvb, int offset, int mpf,
* See above long comment about this trickery. */
if (mpf == MPF_LAST_SEGMENT && !fd_head) {
- fd_head = fragment_add_seq(tvb, offset, pinfo,
- id, sna_fragment_table,
- MIDDLE_FRAG_NUMBER, 0, TRUE);
+ fd_head = fragment_add_seq(&sna_reassembly_table,
+ tvb, offset, pinfo, id, NULL,
+ MIDDLE_FRAG_NUMBER, 0, TRUE, 0);
}
if (fd_head != NULL) {
@@ -2610,7 +2610,8 @@ dissect_sna_xid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void
sna_init(void)
{
- fragment_table_init(&sna_fragment_table);
+ reassembly_table_init(&sna_reassembly_table,
+ &addresses_reassembly_table_functions);
}
diff --git a/epan/dissectors/packet-sndcp.c b/epan/dissectors/packet-sndcp.c
index eaa85aff6c..1f2d34de30 100644
--- a/epan/dissectors/packet-sndcp.c
+++ b/epan/dissectors/packet-sndcp.c
@@ -101,14 +101,12 @@ static dissector_handle_t ip_handle;
/* reassembly of N-PDU
*/
-static GHashTable *npdu_fragment_table = NULL;
-static GHashTable *sndcp_reassembled_table = NULL;
+static reassembly_table npdu_reassembly_table;
static void
sndcp_defragment_init(void)
{
- fragment_table_init(&npdu_fragment_table);
- reassembled_table_init(&sndcp_reassembled_table);
+ reassembly_table_init(&npdu_reassembly_table, &addresses_reassembly_table_functions);
}
/* value strings
@@ -332,11 +330,11 @@ dissect_sndcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
pinfo->fragmented = TRUE;
if (unack)
- fd_npdu = fragment_add_seq_check(tvb, offset, pinfo, npdu,
- npdu_fragment_table, sndcp_reassembled_table, segment, len, more_frags);
+ fd_npdu = fragment_add_seq_check(&npdu_reassembly_table, tvb, offset,
+ pinfo, npdu, NULL, segment, len, more_frags);
else
- fd_npdu = fragment_add(tvb, offset, pinfo, npdu,
- npdu_fragment_table, offset, len, more_frags);
+ fd_npdu = fragment_add(&npdu_reassembly_table, tvb, offset, pinfo, npdu, NULL,
+ offset, len, more_frags);
npdu_tvb = process_reassembled_data(tvb, offset, pinfo,
"Reassembled N-PDU", fd_npdu, &npdu_frag_items,
diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c
index 5f90a86baf..f1ac01db2e 100644
--- a/epan/dissectors/packet-ssl.c
+++ b/epan/dissectors/packet-ssl.c
@@ -372,11 +372,12 @@ void proto_reg_handoff_ssl(void);
/* Desegmentation of SSL streams */
/* table to hold defragmented SSL streams */
-static GHashTable *ssl_fragment_table = NULL;
+static reassembly_table ssl_reassembly_table;
static void
ssl_fragment_init(void)
{
- fragment_table_init(&ssl_fragment_table);
+ reassembly_table_init(&ssl_reassembly_table,
+ &addresses_ports_reassembly_table_functions);
}
/* initialize/reset per capture state data (ssl sessions cache) */
@@ -1029,8 +1030,9 @@ again:
len = MIN(nxtseq, msp->nxtpdu) - seq;
}
- ipfd_head = fragment_add(tvb, offset, pinfo, msp->first_frame,
- ssl_fragment_table, seq - msp->seq,
+ ipfd_head = fragment_add(&ssl_reassembly_table, tvb, offset,
+ pinfo, msp->first_frame, NULL,
+ seq - msp->seq,
len, (LT_SEQ (nxtseq,msp->nxtpdu)));
if (msp->flags & MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT) {
@@ -1134,7 +1136,8 @@ again:
* being a new higher-level PDU that also
* needs desegmentation).
*/
- fragment_set_partial_reassembly(pinfo, msp->first_frame, ssl_fragment_table);
+ fragment_set_partial_reassembly(&ssl_reassembly_table,
+ pinfo, msp->first_frame, NULL);
/* Update msp->nxtpdu to point to the new next
* pdu boundary.
*/
@@ -1279,8 +1282,9 @@ again:
}
/* add this segment as the first one for this new pdu */
- fragment_add(tvb, deseg_offset, pinfo, msp->first_frame,
- ssl_fragment_table, 0, nxtseq - deseg_seq,
+ fragment_add(&ssl_reassembly_table, tvb, deseg_offset,
+ pinfo, msp->first_frame, NULL,
+ 0, nxtseq - deseg_seq,
LT_SEQ(nxtseq, msp->nxtpdu));
}
}
diff --git a/epan/dissectors/packet-t38.c b/epan/dissectors/packet-t38.c
index 239dbd4076..94633d9b33 100644
--- a/epan/dissectors/packet-t38.c
+++ b/epan/dissectors/packet-t38.c
@@ -193,7 +193,7 @@ static gboolean primary_part = TRUE;
static guint32 seq_number = 0;
/* Tables for reassembly of Data fragments. */
-static GHashTable *data_fragment_table = NULL;
+static reassembly_table data_reassembly_table;
static const fragment_items data_frag_items = {
/* Fragment subtrees */
@@ -248,8 +248,9 @@ static t38_packet_info *t38_info=NULL;
static void t38_defragment_init(void)
{
- /* Init reassemble tables */
- fragment_table_init(&data_fragment_table);
+ /* Init reassembly table */
+ reassembly_table_init(&data_reassembly_table,
+ &addresses_reassembly_table_functions);
}
@@ -334,21 +335,14 @@ void t38_add_address(packet_info *pinfo,
fragment_data *
-force_reassemble_seq(packet_info *pinfo, guint32 id,
- GHashTable *fragment_table)
+force_reassemble_seq(reassembly_table *table, packet_info *pinfo, guint32 id)
{
- fragment_key key;
fragment_data *fd_head;
fragment_data *fd_i;
fragment_data *last_fd;
guint32 dfpos, size, packet_lost, burst_lost, seq_num;
- /* create key to search hash with */
- key.src = pinfo->src;
- key.dst = pinfo->dst;
- key.id = id;
-
- fd_head = (fragment_data *)g_hash_table_lookup(fragment_table, &key);
+ fd_head = fragment_get(table, pinfo, id, NULL);
/* have we already seen this frame ?*/
if (pinfo->fd->flags.visited) {
@@ -379,8 +373,8 @@ force_reassemble_seq(packet_info *pinfo, guint32 id,
}
/* we have received an entire packet, defragment it and
- * free all fragments
- */
+ * free all fragments
+ */
size=0;
last_fd=NULL;
for(fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
@@ -595,13 +589,15 @@ dissect_t38_T_field_type(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_
/* if reass_start_seqnum=-1 it means we have received the end of the fragmente, without received any fragment data */
if (p_t38_packet_conv_info->reass_start_seqnum != -1) {
- frag_msg = fragment_add_seq(tvb, offset, actx->pinfo,
+ frag_msg = fragment_add_seq(&data_reassembly_table, /* reassembly table */
+ tvb, offset, actx->pinfo,
p_t38_packet_conv_info->reass_ID, /* ID for fragments belonging together */
- data_fragment_table, /* list of message fragments */
+ NULL,
seq_number + Data_Field_item_num - (guint32)p_t38_packet_conv_info->reass_start_seqnum + (guint32)p_t38_packet_conv_info->additional_hdlc_data_field_counter, /* fragment sequence number */
/*0,*/
0, /* fragment length */
- FALSE); /* More fragments */
+ FALSE, /* More fragments */
+ 0);
if ( Data_Field_field_type_value == 7 ) {
/* if there was packet lost or other errors during the defrag then frag_msg is NULL. This could also means
* there are out of order packets (e.g, got the tail frame t4-non-ecm-sig-end before the last fragment),
@@ -609,9 +605,9 @@ dissect_t38_T_field_type(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_
* and get some stat, like packet lost and burst number of packet lost
*/
if (!frag_msg) {
- force_reassemble_seq(actx->pinfo,
- p_t38_packet_conv_info->reass_ID, /* ID for fragments belonging together */
- data_fragment_table /* list of message fragments */
+ force_reassemble_seq(&data_reassembly_table, /* reassembly table */
+ actx->pinfo,
+ p_t38_packet_conv_info->reass_ID /* ID for fragments belonging together */
);
} else {
col_append_str(actx->pinfo->cinfo, COL_INFO, " (t4-data Reassembled: No packet lost)");
@@ -672,7 +668,7 @@ dissect_t38_T_field_type(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_
static int
dissect_t38_T_field_data(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 154 "../../asn1/t38/t38.cnf"
+#line 156 "../../asn1/t38/t38.cnf"
tvbuff_t *value_tvb = NULL;
guint32 value_len;
@@ -683,7 +679,7 @@ dissect_t38_T_field_data(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_
-#line 161 "../../asn1/t38/t38.cnf"
+#line 163 "../../asn1/t38/t38.cnf"
if (primary_part){
if(value_len < 8){
col_append_fstr(actx->pinfo->cinfo, COL_INFO, "[%s]",
@@ -727,12 +723,15 @@ dissect_t38_T_field_data(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_
p_t38_conv_info->additional_hdlc_data_field_counter = p_t38_packet_conv_info->additional_hdlc_data_field_counter;
}
}
- frag_msg = fragment_add_seq(value_tvb, 0, actx->pinfo,
+ frag_msg = fragment_add_seq(&data_reassembly_table,
+ value_tvb, 0,
+ actx->pinfo,
p_t38_packet_conv_info->reass_ID, /* ID for fragments belonging together */
- data_fragment_table, /* list of message fragments */
+ NULL,
seq_number - (guint32)p_t38_packet_conv_info->reass_start_seqnum + (guint32)p_t38_packet_conv_info->additional_hdlc_data_field_counter, /* fragment sequence number */
value_len, /* fragment length */
- TRUE); /* More fragments */
+ TRUE, /* More fragments */
+ 0);
p_t38_packet_conv_info->seqnum_prev_data_field = (gint32)seq_number;
process_reassembled_data(tvb, offset, actx->pinfo,
"Reassembled T38", frag_msg, &data_frag_items, NULL, tree);
@@ -808,7 +807,7 @@ dissect_t38_T_seq_number(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_
offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index,
0U, 65535U, &seq_number, FALSE);
-#line 238 "../../asn1/t38/t38.cnf"
+#line 243 "../../asn1/t38/t38.cnf"
/* info for tap */
if (primary_part)
t38_info->seq_num = seq_number;
@@ -822,12 +821,12 @@ dissect_t38_T_seq_number(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_
static int
dissect_t38_T_primary_ifp_packet(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 246 "../../asn1/t38/t38.cnf"
+#line 251 "../../asn1/t38/t38.cnf"
primary_part = TRUE;
offset = dissect_per_open_type(tvb, offset, actx, tree, hf_index, dissect_t38_IFPPacket);
-#line 248 "../../asn1/t38/t38.cnf"
+#line 253 "../../asn1/t38/t38.cnf"
/* if is a valid t38 packet, add to tap */
if (p_t38_packet_conv && (!actx->pinfo->flags.in_error_pkt) && ((gint32) seq_number != p_t38_packet_conv_info->last_seqnum))
tap_queue_packet(t38_tap, actx->pinfo, t38_info);
@@ -921,14 +920,14 @@ static const per_choice_t T_error_recovery_choice[] = {
static int
dissect_t38_T_error_recovery(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 256 "../../asn1/t38/t38.cnf"
+#line 261 "../../asn1/t38/t38.cnf"
primary_part = FALSE;
offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
ett_t38_T_error_recovery, T_error_recovery_choice,
NULL);
-#line 258 "../../asn1/t38/t38.cnf"
+#line 263 "../../asn1/t38/t38.cnf"
primary_part = TRUE;
return offset;
@@ -944,7 +943,7 @@ static const per_sequence_t UDPTLPacket_sequence[] = {
static int
dissect_t38_UDPTLPacket(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 232 "../../asn1/t38/t38.cnf"
+#line 237 "../../asn1/t38/t38.cnf"
/* Initialize to something else than data type */
Data_Field_field_type_value = 1;
@@ -975,7 +974,7 @@ static int dissect_UDPTLPacket_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, pr
/*--- End of included file: packet-t38-fn.c ---*/
-#line 394 "../../asn1/t38/packet-t38-template.c"
+#line 388 "../../asn1/t38/packet-t38-template.c"
/* initialize the tap t38_info and the conversation */
static void
@@ -1331,7 +1330,7 @@ proto_register_t38(void)
"OCTET_STRING", HFILL }},
/*--- End of included file: packet-t38-hfarr.c ---*/
-#line 673 "../../asn1/t38/packet-t38-template.c"
+#line 667 "../../asn1/t38/packet-t38-template.c"
{ &hf_t38_setup,
{ "Stream setup", "t38.setup", FT_STRING, BASE_NONE,
NULL, 0x0, "Stream setup, method and frame number", HFILL }},
@@ -1392,7 +1391,7 @@ proto_register_t38(void)
&ett_t38_T_fec_data,
/*--- End of included file: packet-t38-ettarr.c ---*/
-#line 720 "../../asn1/t38/packet-t38-template.c"
+#line 714 "../../asn1/t38/packet-t38-template.c"
&ett_t38_setup,
&ett_data_fragment,
&ett_data_fragments
diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c
index 9084d2b10c..4020450e00 100644
--- a/epan/dissectors/packet-tcp.c
+++ b/epan/dissectors/packet-tcp.c
@@ -1684,8 +1684,7 @@ print_tcp_fragment_tree(fragment_data *ipfd_head, proto_tree *tree, proto_tree *
#define TCPH_MIN_LEN 20
/* Desegmentation of TCP streams */
-/* table to hold defragmented TCP streams */
-static GHashTable *tcp_fragment_table = NULL;
+static reassembly_table tcp_reassembly_table;
/* functions to trace tcp segments */
/* Enable desegmenting of TCP streams */
@@ -1790,8 +1789,9 @@ again:
}
last_fragment_len = len;
- ipfd_head = fragment_add(tvb, offset, pinfo, msp->first_frame,
- tcp_fragment_table, seq - msp->seq, len,
+ ipfd_head = fragment_add(&tcp_reassembly_table, tvb, offset,
+ pinfo, msp->first_frame, NULL,
+ seq - msp->seq, len,
(LT_SEQ (nxtseq,msp->nxtpdu)) );
if (!PINFO_FD_VISITED(pinfo)
@@ -1916,7 +1916,8 @@ again:
* being a new higher-level PDU that also
* needs desegmentation).
*/
- fragment_set_partial_reassembly(pinfo,msp->first_frame, tcp_fragment_table);
+ fragment_set_partial_reassembly(&tcp_reassembly_table,
+ pinfo, msp->first_frame, NULL);
/* Update msp->nxtpdu to point to the new next
* pdu boundary.
@@ -2057,8 +2058,9 @@ again:
}
/* add this segment as the first one for this new pdu */
- fragment_add(tvb, deseg_offset, pinfo, msp->first_frame,
- tcp_fragment_table, 0, nxtseq - deseg_seq,
+ fragment_add(&tcp_reassembly_table, tvb, deseg_offset,
+ pinfo, msp->first_frame, NULL,
+ 0, nxtseq - deseg_seq,
LT_SEQ(nxtseq, msp->nxtpdu));
}
}
@@ -4760,8 +4762,8 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if(msp) {
fragment_data *ipfd_head;
- ipfd_head = fragment_add(tvb, offset, pinfo, msp->first_frame,
- tcp_fragment_table,
+ ipfd_head = fragment_add(&tcp_reassembly_table, tvb, offset,
+ pinfo, msp->first_frame, NULL,
tcph->th_seq - msp->seq,
tcph->th_seglen,
FALSE );
@@ -4854,7 +4856,8 @@ static void
tcp_init(void)
{
tcp_stream_index = 0;
- fragment_table_init(&tcp_fragment_table);
+ reassembly_table_init(&tcp_reassembly_table,
+ &addresses_ports_reassembly_table_functions);
}
void
diff --git a/epan/dissectors/packet-tds.c b/epan/dissectors/packet-tds.c
index 72c584be47..7c86cf7066 100644
--- a/epan/dissectors/packet-tds.c
+++ b/epan/dissectors/packet-tds.c
@@ -549,8 +549,7 @@ static const fragment_items tds_frag_items = {
};
/* Tables for reassembly of fragments. */
-static GHashTable *tds_fragment_table = NULL;
-static GHashTable *tds_reassembled_table = NULL;
+static reassembly_table tds_reassembly_table;
/* defragmentation of multi-buffer TDS PDUs */
static gboolean tds_defragment = TRUE;
@@ -2387,8 +2386,8 @@ dissect_netlib_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* XXX - I've seen captures that start with a login
* packet with a sequence number of 2.
*/
- fd_head = fragment_add_seq_check(tvb, offset, pinfo, channel,
- tds_fragment_table, tds_reassembled_table,
+ fd_head = fragment_add_seq_check(&tds_reassembly_table, tvb, offset,
+ pinfo, channel, NULL,
packet_number - 1, len, (status & STATUS_LAST_BUFFER) == 0);
next_tvb = process_reassembled_data(tvb, offset, pinfo,
"Reassembled TDS", fd_head, &tds_frag_items, NULL,
@@ -2694,11 +2693,13 @@ static void
tds_init(void)
{
/*
- * Initialize the fragment and reassembly tables.
+ * Initialize the reassembly table.
+ *
+ * XXX - should fragments be reassembled across multiple TCP
+ * connections?
*/
- fragment_table_init(&tds_fragment_table);
- reassembled_table_init(&tds_reassembled_table);
-
+ reassembly_table_init(&tds_reassembly_table,
+ &addresses_ports_reassembly_table_functions);
}
/* Register the protocol with Wireshark */
diff --git a/epan/dissectors/packet-teamspeak2.c b/epan/dissectors/packet-teamspeak2.c
index 06ffad0628..8a07e47ddc 100644
--- a/epan/dissectors/packet-teamspeak2.c
+++ b/epan/dissectors/packet-teamspeak2.c
@@ -302,8 +302,7 @@ typedef struct
#define my_init_count 5
-static GHashTable *msg_fragment_table = NULL;
-static GHashTable *msg_reassembled_table = NULL;
+static reassembly_table msg_reassembly_table;
/* forward reference */
static gboolean ts2_add_checked_crc32(proto_tree *tree, int hf_item, tvbuff_t *tvb, guint16 offset, guint32 icrc32);
@@ -433,7 +432,7 @@ static void ts2_standard_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
frag_msg = NULL;
pinfo->fragmented = TRUE;
fragment_number = tvb_get_letohs(tvb, 18);
- frag_msg = fragment_add_seq_check(tvb, 24, pinfo, type, msg_fragment_table, msg_reassembled_table, frag->frag_num, tvb_length_remaining(tvb, 24), fragment_number);
+ frag_msg = fragment_add_seq_check(&msg_reassembly_table, tvb, 24, pinfo, type, NULL, frag->frag_num, tvb_length_remaining(tvb, 24), fragment_number);
new_tvb = process_reassembled_data(tvb, 24, pinfo,"Reassembled TeamSpeak2", frag_msg, &msg_frag_items, NULL, ts2_tree);
if (frag_msg) /* XXX: should be if (new_tvb) ?? */
{ /* Reassembled */
@@ -843,8 +842,8 @@ static gboolean ts2_add_checked_crc32(proto_tree *tree, int hf_item, tvbuff_t *t
static void ts2_init(void)
{
- fragment_table_init(&msg_fragment_table);
- reassembled_table_init(&msg_reassembled_table);
+ reassembly_table_init(&msg_reassembly_table,
+ &addresses_reassembly_table_functions);
}
/*
diff --git a/epan/dissectors/packet-tipc.c b/epan/dissectors/packet-tipc.c
index 7c78897a89..ea5094d348 100644
--- a/epan/dissectors/packet-tipc.c
+++ b/epan/dissectors/packet-tipc.c
@@ -554,15 +554,14 @@ static const value_string tipcv2_networkplane_strings[] = {
static void dissect_tipc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
void proto_reg_handoff_tipc(void);
-static GHashTable *tipc_msg_fragment_table = NULL;
-static GHashTable *tipc_msg_reassembled_table = NULL;
+static reassembly_table tipc_msg_reassembly_table;
static void
tipc_defragment_init(void)
{
- fragment_table_init (&tipc_msg_fragment_table);
- reassembled_table_init(&tipc_msg_reassembled_table);
+ reassembly_table_init(&tipc_msg_reassembly_table,
+ &addresses_reassembly_table_functions);
}
@@ -1386,11 +1385,12 @@ dissect_tipc_v2_internal_msg(tvbuff_t *tipc_tvb, proto_tree *tipc_tree, packet_i
save_fragmented = pinfo->fragmented;
pinfo->fragmented = TRUE;
- frag_msg = fragment_add_seq_check(tipc_tvb, offset, pinfo,
+ frag_msg = fragment_add_seq_check(&tipc_msg_reassembly_table,
+ tipc_tvb, offset,
+ pinfo,
frag_msg_no, /* ID for fragments belonging together */
+ NULL,
/* TODO: make sure that fragments are on the same LINK */
- tipc_msg_fragment_table, /* list of message fragments */
- tipc_msg_reassembled_table, /* list of reassembled messages */
/* TIPC starts with "1" but we * need "0" */
(frag_no-1), /* number of the fragment */
len, /* fragment length - to the end of the data */
@@ -1920,10 +1920,11 @@ dissect_tipc_int_prot_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tipc_tr
if (tipc_defragment) {
pinfo->fragmented = TRUE;
- frag_msg = fragment_add_seq_next(tvb, offset, pinfo,
+ frag_msg = fragment_add_seq_next(&tipc_msg_reassembly_table,
+ tvb, offset,
+ pinfo,
link_sel, /* ID for fragments belonging together - NEEDS IMPROVING? */
- tipc_msg_fragment_table, /* list of message fragments */
- tipc_msg_reassembled_table, /* list of reassembled messages */
+ NULL,
tvb_length_remaining(tvb, offset), /* fragment length - to the end */
TRUE); /* More fragments? */
if (msg_type == TIPC_FIRST_SEGMENT) {
@@ -1935,7 +1936,9 @@ dissect_tipc_int_prot_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tipc_tr
no_of_segments = reassembled_msg_length/(msg_size - 28);
if (reassembled_msg_length > (no_of_segments * (msg_size - 28)))
no_of_segments++;
- fragment_set_tot_len(pinfo, link_sel, tipc_msg_fragment_table, no_of_segments-1);
+ fragment_set_tot_len(&tipc_msg_reassembly_table,
+ pinfo, link_sel, NULL,
+ no_of_segments-1);
item = proto_tree_add_text(tipc_tree, tvb, offset, -1, "Segmented message size %u bytes -> No segments = %i",
reassembled_msg_length, no_of_segments);
PROTO_ITEM_SET_GENERATED(item);
diff --git a/epan/dissectors/packet-usb-audio.c b/epan/dissectors/packet-usb-audio.c
index 31d3ca8a3e..1d7d551796 100644
--- a/epan/dissectors/packet-usb-audio.c
+++ b/epan/dissectors/packet-usb-audio.c
@@ -36,8 +36,7 @@ static int hf_midi_cable_number = -1;
static int hf_midi_code_index = -1;
static int hf_midi_event = -1;
-static GHashTable *midi_data_segment_table = NULL;
-static GHashTable *midi_data_reassembled_table = NULL;
+static reassembly_table midi_data_reassembly_table;
static gint ett_usb_audio = -1;
@@ -182,19 +181,21 @@ dissect_usb_midi_event(tvbuff_t *tvb, packet_info *pinfo,
if (code == 0x04)
{
- frag_sysex_msg = fragment_add_seq_next(tvb, offset+1, pinfo,
+ frag_sysex_msg = fragment_add_seq_next(&midi_data_reassembly_table,
+ tvb, offset+1,
+ pinfo,
cable, /* ID for fragments belonging together */
- midi_data_segment_table,
- midi_data_reassembled_table,
+ NULL,
3,
TRUE);
}
else
{
- frag_sysex_msg = fragment_add_seq_next(tvb, offset+1, pinfo,
+ frag_sysex_msg = fragment_add_seq_next(&midi_data_reassembly_table,
+ tvb, offset+1,
+ pinfo,
cable, /* ID for fragments belonging together */
- midi_data_segment_table,
- midi_data_reassembled_table,
+ NULL,
(gint)(code - 4),
FALSE);
}
@@ -265,8 +266,8 @@ dissect_usb_audio_bulk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tre
static void
midi_data_reassemble_init(void)
{
- fragment_table_init(&midi_data_segment_table);
- reassembled_table_init(&midi_data_reassembled_table);
+ reassembly_table_init(&midi_data_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void
diff --git a/epan/dissectors/packet-wai.c b/epan/dissectors/packet-wai.c
index 642652d41a..810b449d4d 100644
--- a/epan/dissectors/packet-wai.c
+++ b/epan/dissectors/packet-wai.c
@@ -61,8 +61,7 @@
#define FLAG_BIT6 0x40
#define FLAG_BIT7 0x80
-static GHashTable *wai_fragment_table = NULL;
-static GHashTable *wai_reassembled_table = NULL;
+static reassembly_table wai_reassembly_table;
static int proto_wai = -1;
@@ -881,10 +880,11 @@ Figure 18 from [ref:1]
proto_tree_add_item(wai_tree, hf_wai_flag, tvb, 11, 1, ENC_BIG_ENDIAN);
}
- frag_msg = fragment_add_seq_check (tvb, WAI_DATA_OFFSET, pinfo,
+ frag_msg = fragment_add_seq_check (&wai_reassembly_table,
+ tvb, WAI_DATA_OFFSET,
+ pinfo,
packet_num,
- wai_fragment_table,
- wai_reassembled_table,
+ NULL,
fragment_num,
length,
flags);
@@ -926,8 +926,8 @@ Figure 18 from [ref:1]
static void wai_reassemble_init (void)
{
- fragment_table_init(&wai_fragment_table);
- reassembled_table_init(&wai_reassembled_table);
+ reassembly_table_init(&wai_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void
diff --git a/epan/dissectors/packet-wtp.c b/epan/dissectors/packet-wtp.c
index 2ef9a8b7ba..4c2fe24e2f 100644
--- a/epan/dissectors/packet-wtp.c
+++ b/epan/dissectors/packet-wtp.c
@@ -226,12 +226,13 @@ static dissector_handle_t wsp_handle;
/*
* reassembly of WSP
*/
-static GHashTable *wtp_fragment_table = NULL;
+static reassembly_table wtp_reassembly_table;
static void
wtp_defragment_init(void)
{
- fragment_table_init(&wtp_fragment_table);
+ reassembly_table_init(&wtp_reassembly_table,
+ &addresses_reassembly_table_functions);
}
/*
@@ -685,8 +686,8 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
gboolean save_fragmented = pinfo->fragmented;
pinfo->fragmented = TRUE;
- fd_wtp = fragment_add_seq(tvb, dataOffset, pinfo, TID,
- wtp_fragment_table, psn, dataLen, !fTTR);
+ fd_wtp = fragment_add_seq(&wtp_reassembly_table, tvb, dataOffset,
+ pinfo, TID, NULL, psn, dataLen, !fTTR, 0);
/* XXX - fragment_add_seq() yields NULL unless Wireshark knows
* that the packet is part of a reassembled whole. This means
* that fd_wtp will be NULL as long as Wireshark did not encounter
diff --git a/epan/dissectors/packet-x25.c b/epan/dissectors/packet-x25.c
index 10c94f3edd..ab7579a559 100644
--- a/epan/dissectors/packet-x25.c
+++ b/epan/dissectors/packet-x25.c
@@ -516,8 +516,7 @@ static gboolean reassemble_x25 = TRUE;
/* Reassembly of X.25 */
-static GHashTable *x25_segment_table = NULL;
-static GHashTable *x25_reassembled_table = NULL;
+static reassembly_table x25_reassembly_table;
static dissector_table_t x25_subdissector_table;
static heur_dissector_list_t x25_heur_subdissector_list;
@@ -1941,10 +1940,9 @@ dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
*/
frag_key |= 0x10000;
}
- fd_head = fragment_add_seq_next(tvb, localoffset,
- pinfo, frag_key,
- x25_segment_table,
- x25_reassembled_table,
+ fd_head = fragment_add_seq_next(&x25_reassembly_table,
+ tvb, localoffset,
+ pinfo, frag_key, NULL,
payload_len, m_bit_set);
pinfo->fragmented = m_bit_set;
@@ -2127,8 +2125,8 @@ dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void
x25_reassemble_init(void)
{
- fragment_table_init(&x25_segment_table);
- reassembled_table_init(&x25_reassembled_table);
+ reassembly_table_init(&x25_reassembly_table,
+ &addresses_reassembly_table_functions);
}
void
diff --git a/epan/dissectors/packet-zbee-aps.c b/epan/dissectors/packet-zbee-aps.c
index 9135759cd5..3d3b44caac 100644
--- a/epan/dissectors/packet-zbee-aps.c
+++ b/epan/dissectors/packet-zbee-aps.c
@@ -143,9 +143,8 @@ static dissector_handle_t zbee_apf_handle;
/* Dissector List. */
static dissector_table_t zbee_aps_dissector_table;
-/* Fragment and Reassembly tables. */
-static GHashTable *zbee_aps_fragment_table = NULL;
-static GHashTable *zbee_aps_reassembled_table = NULL;
+/* Reassembly table. */
+static reassembly_table zbee_aps_reassembly_table;
static const fragment_items zbee_aps_frag_items = {
/* Fragment subtrees */
@@ -879,7 +878,7 @@ dissect_zbee_aps_no_endpt:
* the block number is the block being sent.
*/
if (packet.fragmentation == ZBEE_APS_EXT_FCF_FRAGMENT_FIRST) {
- fragment_set_tot_len(pinfo, msg_id, zbee_aps_fragment_table, packet.block_number);
+ fragment_set_tot_len(&zbee_aps_reassembly_table, pinfo, msg_id, NULL, packet.block_number);
block_num = 0; /* first packet. */
}
else {
@@ -887,8 +886,9 @@ dissect_zbee_aps_no_endpt:
}
/* Add this fragment to the reassembly handler. */
- frag_msg = fragment_add_seq_check(payload_tvb, 0, pinfo, msg_id, zbee_aps_fragment_table,
- zbee_aps_reassembled_table, block_num, tvb_length(payload_tvb), TRUE);
+ frag_msg = fragment_add_seq_check(&zbee_aps_reassembly_table,
+ payload_tvb, 0, pinfo, msg_id, NULL,
+ block_num, tvb_length(payload_tvb), TRUE);
new_tvb = process_reassembled_data(payload_tvb, 0, pinfo, "Reassembled ZigBee APS" ,
frag_msg, &zbee_aps_frag_items, NULL, aps_tree);
@@ -2009,7 +2009,7 @@ void proto_reg_handoff_zbee_aps(void)
*/
static void proto_init_zbee_aps(void)
{
- fragment_table_init(&zbee_aps_fragment_table);
- reassembled_table_init(&zbee_aps_reassembled_table);
+ reassembly_table_init(&zbee_aps_reassembly_table,
+ &addresses_reassembly_table_functions);
} /* proto_init_zbee_aps */
diff --git a/epan/reassemble.c b/epan/reassemble.c
index 82f71df677..3e29947506 100644
--- a/epan/reassemble.c
+++ b/epan/reassemble.c
@@ -30,83 +30,150 @@
#include <epan/reassemble.h>
-#include <epan/dissectors/packet-dcerpc.h>
-
-typedef struct _fragment_key {
- address src;
- address dst;
- guint32 id;
-} fragment_key;
-
-typedef struct _dcerpc_fragment_key {
+/*
+ * Functions for reassembly tables where the endpoint addresses, and a
+ * fragment ID, are used as the key.
+ */
+typedef struct _fragment_addresses_key {
address src;
address dst;
guint32 id;
- e_uuid_t act_id;
-} dcerpc_fragment_key;
+} fragment_addresses_key;
-static void LINK_FRAG(fragment_data *fd_head,fragment_data *fd)
+static guint
+fragment_addresses_hash(gconstpointer k)
{
- fragment_data *fd_i;
+ const fragment_addresses_key* key = (const fragment_addresses_key*) k;
+ guint hash_val;
+/*
+ int i;
+*/
- /* add fragment to list, keep list sorted */
- for(fd_i= fd_head; fd_i->next;fd_i=fd_i->next) {
- if (fd->offset < fd_i->next->offset )
- break;
- }
- fd->next=fd_i->next;
- fd_i->next=fd;
+ hash_val = 0;
+
+/* More than likely: in most captures src and dst addresses are the
+ same, and would hash the same.
+ We only use id as the hash as an optimization.
+
+ for (i = 0; i < key->src.len; i++)
+ hash_val += key->src.data[i];
+ for (i = 0; i < key->dst.len; i++)
+ hash_val += key->dst.data[i];
+*/
+
+ hash_val += key->id;
+
+ return hash_val;
}
-/* copy a fragment key to heap store to insert in the hash */
-static void *fragment_key_copy(const void *k)
+static gint
+fragment_addresses_equal(gconstpointer k1, gconstpointer k2)
{
- const fragment_key* key = (const fragment_key*) k;
- fragment_key *new_key = g_slice_new(fragment_key);
+ const fragment_addresses_key* key1 = (const fragment_addresses_key*) k1;
+ const fragment_addresses_key* key2 = (const fragment_addresses_key*) k2;
- COPY_ADDRESS(&new_key->src, &key->src);
- COPY_ADDRESS(&new_key->dst, &key->dst);
- new_key->id = key->id;
- return new_key;
+ /*
+ * key.id is the first item to compare since it's the item most
+ * likely to differ between sessions, thus short-circuiting
+ * the comparison of addresses.
+ */
+ return (key1->id == key2->id) &&
+ (ADDRESSES_EQUAL(&key1->src, &key2->src)) &&
+ (ADDRESSES_EQUAL(&key1->dst, &key2->dst));
}
-/* copy a dcerpc fragment key to heap store to insert in the hash */
-static void *dcerpc_fragment_key_copy(const void *k)
+/*
+ * Create a fragment key for temporary use; it can point to non-
+ * persistent data, and so must only be used to look up and
+ * delete entries, not to add them.
+ */
+static gpointer
+fragment_addresses_temporary_key(const packet_info *pinfo, const guint32 id,
+ const void *data _U_)
{
- const dcerpc_fragment_key* key = (const dcerpc_fragment_key*) k;
+ fragment_addresses_key *key = g_slice_new(fragment_addresses_key);
- dcerpc_fragment_key *new_key = g_slice_new(dcerpc_fragment_key);
+ /*
+ * Do a shallow copy of the addresses.
+ */
+ key->src = pinfo->src;
+ key->dst = pinfo->dst;
+ key->id = id;
+
+ return (gpointer)key;
+}
+
+/*
+ * Create a fragment key for permanent use; it must point to persistent
+ * data, so that it can be used to add entries.
+ */
+static gpointer
+fragment_addresses_persistent_key(const packet_info *pinfo, const guint32 id,
+ const void *data _U_)
+{
+ fragment_addresses_key *key = g_slice_new(fragment_addresses_key);
- COPY_ADDRESS(&new_key->src, &key->src);
- COPY_ADDRESS(&new_key->dst, &key->dst);
- new_key->id = key->id;
- new_key->act_id = key->act_id;
+ /*
+ * Do a deep copy of the addresses.
+ */
+ COPY_ADDRESS(&key->src, &pinfo->src);
+ COPY_ADDRESS(&key->dst, &pinfo->dst);
+ key->id = id;
- return new_key;
+ return (gpointer)key;
}
+static void
+fragment_addresses_free_temporary_key(gpointer ptr)
+{
+ fragment_addresses_key *key = (fragment_addresses_key *)ptr;
-static gint
-fragment_equal(gconstpointer k1, gconstpointer k2)
+ if(key)
+ g_slice_free(fragment_addresses_key, key);
+}
+
+static void
+fragment_addresses_free_persistent_key(gpointer ptr)
{
- const fragment_key* key1 = (const fragment_key*) k1;
- const fragment_key* key2 = (const fragment_key*) k2;
+ fragment_addresses_key *key = (fragment_addresses_key *)ptr;
- /*key.id is the first item to compare since item is most
- likely to differ between sessions, thus shortcircuiting
- the comparasion of addresses.
- */
- return ( ( (key1->id == key2->id) &&
- (ADDRESSES_EQUAL(&key1->src, &key2->src)) &&
- (ADDRESSES_EQUAL(&key1->dst, &key2->dst))
- ) ?
- TRUE : FALSE);
+ if(key){
+ /*
+ * Free up the copies of the addresses from the old key.
+ */
+ g_free((gpointer)key->src.data);
+ g_free((gpointer)key->dst.data);
+
+ g_slice_free(fragment_addresses_key, key);
+ }
}
+const reassembly_table_functions
+addresses_reassembly_table_functions = {
+ fragment_addresses_hash,
+ fragment_addresses_equal,
+ fragment_addresses_temporary_key,
+ fragment_addresses_persistent_key,
+ fragment_addresses_free_temporary_key,
+ fragment_addresses_free_persistent_key
+};
+
+/*
+ * Functions for reassembly tables where the endpoint addresses and ports,
+ * and a fragment ID, are used as the key.
+ */
+typedef struct _fragment_addresses_ports_key {
+ address src_addr;
+ address dst_addr;
+ guint32 src_port;
+ guint32 dst_port;
+ guint32 id;
+} fragment_addresses_ports_key;
+
static guint
-fragment_hash(gconstpointer k)
+fragment_addresses_ports_hash(gconstpointer k)
{
- const fragment_key* key = (const fragment_key*) k;
+ const fragment_addresses_ports_key* key = (const fragment_addresses_ports_key*) k;
guint hash_val;
/*
int i;
@@ -114,14 +181,16 @@ fragment_hash(gconstpointer k)
hash_val = 0;
-/* More than likely: in most captures src and dst addresses are the
- same, and would hash the same.
+/* More than likely: in most captures src and dst addresses and ports
+ are the same, and would hash the same.
We only use id as the hash as an optimization.
for (i = 0; i < key->src.len; i++)
- hash_val += key->src.data[i];
+ hash_val += key->src_addr.data[i];
for (i = 0; i < key->dst.len; i++)
- hash_val += key->dst.data[i];
+ hash_val += key->dst_addr.data[i];
+ hash_val += key->src_port;
+ hash_val += key->dst_port;
*/
hash_val += key->id;
@@ -130,38 +199,103 @@ fragment_hash(gconstpointer k)
}
static gint
-dcerpc_fragment_equal(gconstpointer k1, gconstpointer k2)
+fragment_addresses_ports_equal(gconstpointer k1, gconstpointer k2)
{
- const dcerpc_fragment_key* key1 = (const dcerpc_fragment_key*) k1;
- const dcerpc_fragment_key* key2 = (const dcerpc_fragment_key*) k2;
+ const fragment_addresses_ports_key* key1 = (const fragment_addresses_ports_key*) k1;
+ const fragment_addresses_ports_key* key2 = (const fragment_addresses_ports_key*) k2;
- /*key.id is the first item to compare since item is most
- likely to differ between sessions, thus shortcircuiting
- the comparison of addresses.
- */
- return (((key1->id == key2->id)
- && (ADDRESSES_EQUAL(&key1->src, &key2->src))
- && (ADDRESSES_EQUAL(&key1->dst, &key2->dst))
- && (memcmp (&key1->act_id, &key2->act_id, sizeof (e_uuid_t)) == 0))
- ? TRUE : FALSE);
+ /*
+ * key.id is the first item to compare since it's the item most
+ * likely to differ between sessions, thus short-circuiting
+ * the comparison of addresses and ports.
+ */
+ return (key1->id == key2->id) &&
+ (ADDRESSES_EQUAL(&key1->src_addr, &key2->src_addr)) &&
+ (ADDRESSES_EQUAL(&key1->dst_addr, &key2->dst_addr)) &&
+ (key1->src_port == key2->src_port) &&
+ (key1->dst_port == key2->dst_port);
}
-static guint
-dcerpc_fragment_hash(gconstpointer k)
+/*
+ * Create a fragment key for temporary use; it can point to non-
+ * persistent data, and so must only be used to look up and
+ * delete entries, not to add them.
+ */
+static gpointer
+fragment_addresses_ports_temporary_key(const packet_info *pinfo, const guint32 id,
+ const void *data _U_)
{
- const dcerpc_fragment_key* key = (const dcerpc_fragment_key*) k;
- guint hash_val;
+ fragment_addresses_ports_key *key = g_slice_new(fragment_addresses_ports_key);
- hash_val = 0;
+ /*
+ * Do a shallow copy of the addresses.
+ */
+ key->src_addr = pinfo->src;
+ key->dst_addr = pinfo->dst;
+ key->src_port = pinfo->srcport;
+ key->dst_port = pinfo->destport;
+ key->id = id;
- hash_val += key->id;
- hash_val += key->act_id.Data1;
- hash_val += key->act_id.Data2 << 16;
- hash_val += key->act_id.Data3;
+ return (gpointer)key;
+}
- return hash_val;
+/*
+ * Create a fragment key for permanent use; it must point to persistent
+ * data, so that it can be used to add entries.
+ */
+static gpointer
+fragment_addresses_ports_persistent_key(const packet_info *pinfo,
+ const guint32 id, const void *data _U_)
+{
+ fragment_addresses_ports_key *key = g_slice_new(fragment_addresses_ports_key);
+
+ /*
+ * Do a deep copy of the addresses.
+ */
+ COPY_ADDRESS(&key->src_addr, &pinfo->src);
+ COPY_ADDRESS(&key->dst_addr, &pinfo->dst);
+ key->src_port = pinfo->srcport;
+ key->dst_port = pinfo->destport;
+ key->id = id;
+
+ return (gpointer)key;
+}
+
+static void
+fragment_addresses_ports_free_temporary_key(gpointer ptr)
+{
+ fragment_addresses_ports_key *key = (fragment_addresses_ports_key *)ptr;
+
+ if(key)
+ g_slice_free(fragment_addresses_ports_key, key);
+}
+
+static void
+fragment_addresses_ports_free_persistent_key(gpointer ptr)
+{
+ fragment_addresses_ports_key *key = (fragment_addresses_ports_key *)ptr;
+
+ if(key){
+ /*
+ * Free up the copies of the addresses from the old key.
+ */
+ g_free((gpointer)key->src_addr.data);
+ g_free((gpointer)key->dst_addr.data);
+
+ g_slice_free(fragment_addresses_ports_key, key);
+ }
}
+const reassembly_table_functions
+addresses_ports_reassembly_table_functions = {
+ fragment_addresses_ports_hash,
+ fragment_addresses_ports_equal,
+ fragment_addresses_ports_temporary_key,
+ fragment_addresses_ports_persistent_key,
+ fragment_addresses_ports_free_temporary_key,
+ fragment_addresses_ports_free_persistent_key
+};
+
typedef struct _reassembled_key {
guint32 id;
guint32 frame;
@@ -191,8 +325,8 @@ reassembled_hash(gconstpointer k)
/*
* For a fragment hash table entry, free the associated fragments.
* The entry value (fd_chain) is freed herein and the entry is freed
- * when fragment_free_key() [or dcerpc_fragment_free_key()] is called
- * (as a consequence of returning TRUE from this function).
+ * when the key freeing routine is called (as a consequence of returning
+ * TRUE from this function).
*/
static gboolean
free_all_fragments(gpointer key_arg _U_, gpointer value, gpointer user_data _U_)
@@ -200,7 +334,7 @@ free_all_fragments(gpointer key_arg _U_, gpointer value, gpointer user_data _U_)
fragment_data *fd_head, *tmp_fd;
/* g_hash_table_new_full() was used to supply a function
- * to free the key and the addresses.
+ * to free the key and anything to which it points
*/
for (fd_head = (fragment_data *)value; fd_head != NULL; fd_head = tmp_fd) {
tmp_fd=fd_head->next;
@@ -262,150 +396,134 @@ free_all_reassembled_fragments(gpointer key_arg, gpointer value,
}
static void
-fragment_free_key(void *ptr)
-{
- fragment_key *key = (fragment_key *)ptr;
-
- if(key){
- /*
- * Free up the copies of the addresses from the old key.
- */
- g_free((gpointer)key->src.data);
- g_free((gpointer)key->dst.data);
-
- g_slice_free(fragment_key, key);
- }
-}
-
-static void
-dcerpc_fragment_free_key(void *ptr)
+free_fragments(gpointer data, gpointer user_data _U_)
{
- dcerpc_fragment_key *key = (dcerpc_fragment_key *)ptr;
-
- if(key){
- /*
- * Free up the copies of the addresses from the old key.
- */
- g_free((gpointer)key->src.data);
- g_free((gpointer)key->dst.data);
+ fragment_data *fd_head = (fragment_data *) data;
- g_slice_free(dcerpc_fragment_key, key);
- }
+ g_free(fd_head->data);
+ g_slice_free(fragment_data, fd_head);
}
/*
- * Initialize a fragment table.
+ * Initialize a reassembly table, with specified functions.
*/
void
-fragment_table_init(GHashTable **fragment_table)
+reassembly_table_init(reassembly_table *table,
+ const reassembly_table_functions *funcs)
{
- if (*fragment_table != NULL) {
+ if (table->temporary_key_func == NULL)
+ table->temporary_key_func = funcs->temporary_key_func;
+ if (table->persistent_key_func == NULL)
+ table->persistent_key_func = funcs->persistent_key_func;
+ if (table->free_temporary_key_func == NULL)
+ table->free_temporary_key_func = funcs->free_temporary_key_func;
+ if (table->fragment_table != NULL) {
/*
* The fragment hash table exists.
*
* Remove all entries and free fragment data for each entry.
*
- * The keys are freed by calling fragment_free_key()
- * and the values are freed in free_all_fragments().
- *
- * free_all_fragments()
- * will free the address data associated with the key
+ * The keys, and anything to which they point, are freed by
+ * calling the table's key freeing function. The values
+ * are freed in free_all_fragments().
*/
- g_hash_table_foreach_remove(*fragment_table,
- free_all_fragments, NULL);
+ g_hash_table_foreach_remove(table->fragment_table,
+ free_all_fragments, NULL);
} else {
/* The fragment table does not exist. Create it */
- *fragment_table = g_hash_table_new_full(fragment_hash,
- fragment_equal, fragment_free_key, NULL);
+ table->fragment_table = g_hash_table_new_full(funcs->hash_func,
+ funcs->equal_func, funcs->free_persistent_key_func, NULL);
}
-}
-/*
- * Destroy a fragment table.
- */
-void
-frgment_table_destroy(GHashTable **fragment_table)
-{
- if (*fragment_table != NULL) {
+ if (table->reassembled_table != NULL) {
+ GPtrArray *allocated_fragments;
+
/*
- * The fragment hash table exists.
- *
- * Remove all entries and free fragment data for each entry.
- *
- * The keys are freed by calling fragment_free_key()
- * and the values are freed in free_all_fragments().
+ * The reassembled-packet hash table exists.
*
- * free_all_fragments()
- * will free the address data associated with the key
+ * Remove all entries and free reassembled packet
+ * data and key for each entry.
*/
- g_hash_table_foreach_remove(*fragment_table,
- free_all_fragments, NULL);
- g_hash_table_destroy(*fragment_table);
- *fragment_table = NULL;
+ allocated_fragments = g_ptr_array_new();
+ g_hash_table_foreach_remove(table->reassembled_table,
+ free_all_reassembled_fragments, allocated_fragments);
+
+ g_ptr_array_foreach(allocated_fragments, free_fragments, NULL);
+ g_ptr_array_free(allocated_fragments, TRUE);
+ } else {
+ /* The fragment table does not exist. Create it */
+ table->reassembled_table = g_hash_table_new(reassembled_hash,
+ reassembled_equal);
}
}
+/*
+ * Destroy a reassembly table.
+ */
void
-dcerpc_fragment_table_init(GHashTable **fragment_table)
+reassembly_table_destroy(reassembly_table *table)
{
- if (*fragment_table != NULL) {
+ if (table->fragment_table != NULL) {
/*
* The fragment hash table exists.
*
* Remove all entries and free fragment data for each entry.
*
- * If slices are used (GLIB >= 2.10)
- * the keys are freed by calling dcerpc_fragment_free_key()
- * and the values are freed in free_all_fragments().
- *
- * free_all_fragments()
- * will free the adrress data associated with the key
+ * The keys, and anything to which they point, are freed by
+ * calling the table's key freeing function. The values
+ * are freed in free_all_fragments().
*/
- g_hash_table_foreach_remove(*fragment_table,
- free_all_fragments, NULL);
- } else {
- /* The fragment table does not exist. Create it */
- *fragment_table = g_hash_table_new_full(dcerpc_fragment_hash,
- dcerpc_fragment_equal, dcerpc_fragment_free_key, NULL);
+ g_hash_table_foreach_remove(table->fragment_table,
+ free_all_fragments, NULL);
+
+ g_hash_table_destroy(table->fragment_table);
+ table->fragment_table = NULL;
}
}
-static void
-free_fragments(gpointer data, gpointer user_data _U_)
+/*
+ * Look up an fd_head in the fragment table, optionally returning the key
+ * for it.
+ */
+static fragment_data *
+lookup_fd_head(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id, const void *data, gpointer *orig_keyp)
{
- fragment_data *fd_head = (fragment_data *) data;
+ gpointer key;
+ gpointer value;
- g_free(fd_head->data);
- g_slice_free(fragment_data, fd_head);
+ /* Create key to search hash with */
+ key = table->temporary_key_func(pinfo, id, data);
+
+ /*
+ * Look up the reassembly in the fragment table.
+ */
+ if (!g_hash_table_lookup_extended(table->fragment_table, key, orig_keyp,
+ &value))
+ value = NULL;
+ /* Free the key */
+ table->free_temporary_key_func(key);
+
+ return (fragment_data *)value;
}
/*
- * Initialize a reassembled-packet table.
+ * Insert an fd_head into the fragment table, and return the key used.
*/
-void
-reassembled_table_init(GHashTable **reassembled_table)
+gpointer
+insert_fd_head(reassembly_table *table, fragment_data *fd_head,
+ const packet_info *pinfo, const guint32 id, const void *data)
{
- if (*reassembled_table != NULL) {
- GPtrArray *allocated_fragments;
+ gpointer key;
- /*
- * The reassembled-packet hash table exists.
- *
- * Remove all entries and free reassembled packet
- * data and key for each entry.
- */
-
- allocated_fragments = g_ptr_array_new();
- g_hash_table_foreach_remove(*reassembled_table,
- free_all_reassembled_fragments, allocated_fragments);
-
- g_ptr_array_foreach(allocated_fragments, free_fragments, NULL);
- g_ptr_array_free(allocated_fragments, TRUE);
- } else {
- /* The fragment table does not exist. Create it */
- *reassembled_table = g_hash_table_new(reassembled_hash, reassembled_equal);
- }
+ /*
+ * We're going to use the key to insert the fragment,
+ * so make a persistent version of it.
+ */
+ key = table->persistent_key_func(pinfo, id, data);
+ g_hash_table_insert(table->fragment_table, key, fd_head);
+ return key;
}
/* This function cleans up the stored state and removes the reassembly data and
@@ -421,25 +539,20 @@ reassembled_table_init(GHashTable **reassembled_table)
* g_free() that buffer.
*/
unsigned char *
-fragment_delete(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table)
+fragment_delete(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id, const void *data)
{
fragment_data *fd_head, *fd;
- fragment_key key;
- unsigned char *data=NULL;
-
- /* create key to search hash with */
- key.src = pinfo->src;
- key.dst = pinfo->dst;
- key.id = id;
-
- fd_head = (fragment_data *)g_hash_table_lookup(fragment_table, &key);
+ unsigned char *fd_data=NULL;
+ gpointer key;
+ fd_head = lookup_fd_head(table, pinfo, id, data, &key);
if(fd_head==NULL){
/* We do not recognize this as a PDU we have seen before. return */
return NULL;
}
- data=fd_head->data;
+ fd_data=fd_head->data;
/* loop over all partial fragments and free any buffers */
for(fd=fd_head->next;fd;){
fragment_data *tmp_fd;
@@ -451,33 +564,24 @@ fragment_delete(const packet_info *pinfo, const guint32 id, GHashTable *fragment
fd=tmp_fd;
}
g_slice_free(fragment_data, fd_head);
- g_hash_table_remove(fragment_table, &key);
+ g_hash_table_remove(table->fragment_table, key);
- return data;
+ return fd_data;
}
/* This function is used to check if there is partial or completed reassembly state
* matching this packet. I.e. Is there reassembly going on or not for this packet?
*/
fragment_data *
-fragment_get(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table)
+fragment_get(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id, const void *data)
{
- fragment_data *fd_head;
- fragment_key key;
-
- /* create key to search hash with */
- key.src = pinfo->src;
- key.dst = pinfo->dst;
- key.id = id;
-
- fd_head = (fragment_data *)g_hash_table_lookup(fragment_table, &key);
-
- return fd_head;
+ return lookup_fd_head(table, pinfo, id, data, NULL);
}
/* id *must* be the frame number for this to work! */
fragment_data *
-fragment_get_reassembled(const guint32 id, GHashTable *reassembled_table)
+fragment_get_reassembled(reassembly_table *table, const guint32 id)
{
fragment_data *fd_head;
reassembled_key key;
@@ -485,13 +589,14 @@ fragment_get_reassembled(const guint32 id, GHashTable *reassembled_table)
/* create key to search hash with */
key.frame = id;
key.id = id;
- fd_head = (fragment_data *)g_hash_table_lookup(reassembled_table, &key);
+ fd_head = (fragment_data *)g_hash_table_lookup(table->reassembled_table, &key);
return fd_head;
}
fragment_data *
-fragment_get_reassembled_id(const packet_info *pinfo, const guint32 id, GHashTable *reassembled_table)
+fragment_get_reassembled_id(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id)
{
fragment_data *fd_head;
reassembled_key key;
@@ -499,7 +604,7 @@ fragment_get_reassembled_id(const packet_info *pinfo, const guint32 id, GHashTab
/* create key to search hash with */
key.frame = pinfo->fd->num;
key.id = id;
- fd_head = (fragment_data *)g_hash_table_lookup(reassembled_table, &key);
+ fd_head = (fragment_data *)g_hash_table_lookup(table->reassembled_table, &key);
return fd_head;
}
@@ -519,20 +624,14 @@ fragment_get_reassembled_id(const packet_info *pinfo, const guint32 id, GHashTab
* actually means we want to defragment 3 blocks, block 0, 1 and 2.
*/
void
-fragment_set_tot_len(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table,
- const guint32 tot_len)
+fragment_set_tot_len(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id, const void *data, const guint32 tot_len)
{
fragment_data *fd_head;
fragment_data *fd;
- fragment_key key;
guint32 max_offset = 0;
- /* create key to search hash with */
- key.src = pinfo->src;
- key.dst = pinfo->dst;
- key.id = id;
-
- fd_head = (fragment_data *)g_hash_table_lookup(fragment_table, &key);
+ fd_head = lookup_fd_head(table, pinfo, id, data, NULL);
if (!fd_head)
return;
@@ -569,17 +668,12 @@ fragment_set_tot_len(const packet_info *pinfo, const guint32 id, GHashTable *fra
}
guint32
-fragment_get_tot_len(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table)
+fragment_get_tot_len(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id, const void *data)
{
fragment_data *fd_head;
- fragment_key key;
-
- /* create key to search hash with */
- key.src = pinfo->src;
- key.dst = pinfo->dst;
- key.id = id;
- fd_head = (fragment_data *)g_hash_table_lookup(fragment_table, &key);
+ fd_head = lookup_fd_head(table, pinfo, id, data, NULL);
if(fd_head){
return fd_head->datalen;
@@ -598,17 +692,13 @@ fragment_get_tot_len(const packet_info *pinfo, const guint32 id, GHashTable *fra
*/
void
-fragment_set_partial_reassembly(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table)
+fragment_set_partial_reassembly(reassembly_table *table,
+ const packet_info *pinfo, const guint32 id,
+ const void *data)
{
fragment_data *fd_head;
- fragment_key key;
-
- /* create key to search hash with */
- key.src = pinfo->src;
- key.dst = pinfo->dst;
- key.id = id;
- fd_head = (fragment_data *)g_hash_table_lookup(fragment_table, &key);
+ fd_head = lookup_fd_head(table, pinfo, id, data, NULL);
/*
* XXX - why not do all the stuff done early in "fragment_add_work()",
@@ -628,23 +718,17 @@ fragment_set_partial_reassembly(const packet_info *pinfo, const guint32 id, GHas
/*
* This function gets rid of an entry from a fragment table, given
- * a pointer to the key for that entry; it also frees up the key
- * and the addresses in it.
- * Note: If we use slices keys are freed by fragment_free_key()
- [or dcerpc_fragment_free_key()] being called
- * during g_hash_table_remove().
+ * a pointer to the key for that entry.
+ *
+ * The key freeing routine will be called by g_hash_table_remove().
*/
static void
-fragment_unhash(GHashTable *fragment_table, fragment_key *key)
+fragment_unhash(reassembly_table *table, gpointer key)
{
/*
* Remove the entry from the fragment table.
*/
- g_hash_table_remove(fragment_table, key);
-
- /*
- * Free the key itself.
- */
+ g_hash_table_remove(table->fragment_table, key);
}
/*
@@ -654,8 +738,8 @@ fragment_unhash(GHashTable *fragment_table, fragment_key *key)
* frame number.
*/
static void
-fragment_reassembled(fragment_data *fd_head, const packet_info *pinfo,
- GHashTable *reassembled_table, const guint32 id)
+fragment_reassembled(reassembly_table *table, fragment_data *fd_head,
+ const packet_info *pinfo, const guint32 id)
{
reassembled_key *new_key;
fragment_data *fd;
@@ -668,7 +752,7 @@ fragment_reassembled(fragment_data *fd_head, const packet_info *pinfo,
new_key = g_slice_new(reassembled_key);
new_key->frame = pinfo->fd->num;
new_key->id = id;
- g_hash_table_insert(reassembled_table, new_key, fd_head);
+ g_hash_table_insert(table->reassembled_table, new_key, fd_head);
} else {
/*
* Hash it with the frame numbers for all the frames.
@@ -677,7 +761,7 @@ fragment_reassembled(fragment_data *fd_head, const packet_info *pinfo,
new_key = g_slice_new(reassembled_key);
new_key->frame = fd->frame;
new_key->id = id;
- g_hash_table_insert(reassembled_table, new_key,
+ g_hash_table_insert(table->reassembled_table, new_key,
fd_head);
}
}
@@ -685,6 +769,20 @@ fragment_reassembled(fragment_data *fd_head, const packet_info *pinfo,
fd_head->reassembled_in = pinfo->fd->num;
}
+static void
+LINK_FRAG(fragment_data *fd_head,fragment_data *fd)
+{
+ fragment_data *fd_i;
+
+ /* add fragment to list, keep list sorted */
+ for(fd_i= fd_head; fd_i->next;fd_i=fd_i->next) {
+ if (fd->offset < fd_i->next->offset )
+ break;
+ }
+ fd->next=fd_i->next;
+ fd_i->next=fd;
+}
+
/*
* This function adds a new fragment to the fragment hash table.
* If this is the first fragment seen for this datagram, a new entry
@@ -944,12 +1042,12 @@ fragment_add_work(fragment_data *fd_head, tvbuff_t *tvb, const int offset,
}
static fragment_data *
-fragment_add_common(tvbuff_t *tvb, const int offset, const packet_info *pinfo, const guint32 id,
- GHashTable *fragment_table, const guint32 frag_offset,
- const guint32 frag_data_len, const gboolean more_frags,
- const gboolean check_already_added)
+fragment_add_common(reassembly_table *table, tvbuff_t *tvb, const int offset,
+ const packet_info *pinfo, const guint32 id,
+ const void *data, const guint32 frag_offset,
+ const guint32 frag_data_len, const gboolean more_frags,
+ const gboolean check_already_added)
{
- fragment_key key, *new_key;
fragment_data *fd_head;
fragment_data *fd_item;
gboolean already_added=pinfo->fd->flags.visited;
@@ -958,12 +1056,7 @@ fragment_add_common(tvbuff_t *tvb, const int offset, const packet_info *pinfo, c
/* dissector shouldn't give us garbage tvb info */
DISSECTOR_ASSERT(tvb_bytes_exist(tvb, offset, frag_data_len));
- /* create key to search hash with */
- key.src = pinfo->src;
- key.dst = pinfo->dst;
- key.id = id;
-
- fd_head = (fragment_data *)g_hash_table_lookup(fragment_table, &key);
+ fd_head = lookup_fd_head(table, pinfo, id, data, NULL);
#if 0
/* debug output of associated fragments. */
@@ -1027,16 +1120,9 @@ fragment_add_common(tvbuff_t *tvb, const int offset, const packet_info *pinfo, c
fd_head = new_head(0);
/*
- * We're going to use the key to insert the fragment,
- * so allocate a structure for it, and copy the
- * addresses, allocating new buffers for the address
- * data.
+ * Insert it into the hash table.
*/
- new_key = g_slice_new(fragment_key);
- COPY_ADDRESS(&new_key->src, &key.src);
- COPY_ADDRESS(&new_key->dst, &key.dst);
- new_key->id = key.id;
- g_hash_table_insert(fragment_table, new_key, fd_head);
+ insert_fd_head(table, fd_head, pinfo, id, data);
}
if (fragment_add_work(fd_head, tvb, offset, pinfo, frag_offset,
@@ -1054,11 +1140,12 @@ fragment_add_common(tvbuff_t *tvb, const int offset, const packet_info *pinfo, c
}
fragment_data *
-fragment_add(tvbuff_t *tvb, const int offset, const packet_info *pinfo, const guint32 id,
- GHashTable *fragment_table, const guint32 frag_offset,
- const guint32 frag_data_len, const gboolean more_frags)
+fragment_add(reassembly_table *table, tvbuff_t *tvb, const int offset,
+ const packet_info *pinfo, const guint32 id, const void *data,
+ const guint32 frag_offset, const guint32 frag_data_len,
+ const gboolean more_frags)
{
- return fragment_add_common(tvb, offset, pinfo, id, fragment_table,
+ return fragment_add_common(table, tvb, offset, pinfo, id, data,
frag_offset, frag_data_len, more_frags, TRUE);
}
@@ -1067,25 +1154,25 @@ fragment_add(tvbuff_t *tvb, const int offset, const packet_info *pinfo, const gu
* to the same reassembled PDU, e.g. with ONC RPC-over-TCP.
*/
fragment_data *
-fragment_add_multiple_ok(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
- const guint32 id, GHashTable *fragment_table,
- const guint32 frag_offset, const guint32 frag_data_len,
- const gboolean more_frags)
+fragment_add_multiple_ok(reassembly_table *table, tvbuff_t *tvb,
+ const int offset, const packet_info *pinfo,
+ const guint32 id, const void *data,
+ const guint32 frag_offset,
+ const guint32 frag_data_len, const gboolean more_frags)
{
- return fragment_add_common(tvb, offset, pinfo, id, fragment_table,
+ return fragment_add_common(table, tvb, offset, pinfo, id, data,
frag_offset, frag_data_len, more_frags, FALSE);
}
fragment_data *
-fragment_add_check(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
- const guint32 id, GHashTable *fragment_table,
- GHashTable *reassembled_table, const guint32 frag_offset,
- const guint32 frag_data_len, const gboolean more_frags)
+fragment_add_check(reassembly_table *table, tvbuff_t *tvb, const int offset,
+ const packet_info *pinfo, const guint32 id,
+ const void *data, const guint32 frag_offset,
+ const guint32 frag_data_len, const gboolean more_frags)
{
reassembled_key reass_key;
- fragment_key key, *new_key, *old_key;
- gpointer orig_key, value;
fragment_data *fd_head;
+ gpointer orig_key;
/*
* If this isn't the first pass, look for this frame in the table
@@ -1094,43 +1181,24 @@ fragment_add_check(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
if (pinfo->fd->flags.visited) {
reass_key.frame = pinfo->fd->num;
reass_key.id = id;
- return (fragment_data *)g_hash_table_lookup(reassembled_table, &reass_key);
+ return (fragment_data *)g_hash_table_lookup(table->reassembled_table, &reass_key);
}
- /* create key to search hash with */
- key.src = pinfo->src;
- key.dst = pinfo->dst;
- key.id = id;
-
/* Looks up a key in the GHashTable, returning the original key and the associated value
* and a gboolean which is TRUE if the key was found. This is useful if you need to free
* the memory allocated for the original key, for example before calling g_hash_table_remove()
*/
- if (!g_hash_table_lookup_extended(fragment_table, &key,
- &orig_key, &value)) {
+ fd_head = lookup_fd_head(table, pinfo, id, data, &orig_key);
+ if (fd_head == NULL) {
/* not found, this must be the first snooped fragment for this
- * packet. Create list-head.
+ * packet. Create list-head.
*/
fd_head = new_head(0);
/*
- * We're going to use the key to insert the fragment,
- * so allocate a structure for it, and copy the
- * addresses, allocating new buffers for the address
- * data.
+ * Save the key, for unhashing it later.
*/
- new_key = g_slice_new(fragment_key);
- COPY_ADDRESS(&new_key->src, &key.src);
- COPY_ADDRESS(&new_key->dst, &key.dst);
- new_key->id = key.id;
- g_hash_table_insert(fragment_table, new_key, fd_head);
-
- orig_key = new_key; /* for unhashing it later */
- } else {
- /*
- * We found it.
- */
- fd_head = (fragment_data *)value;
+ orig_key = insert_fd_head(table, fd_head, pinfo, id, data);
}
/*
@@ -1153,13 +1221,12 @@ fragment_add_check(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
* Remove this from the table of in-progress reassemblies,
* and free up any memory used for it in that table.
*/
- old_key = (fragment_key *)orig_key;
- fragment_unhash(fragment_table, old_key);
+ fragment_unhash(table, orig_key);
/*
* Add this item to the table of reassembled packets.
*/
- fragment_reassembled(fd_head, pinfo, reassembled_table, id);
+ fragment_reassembled(table, fd_head, pinfo, id);
return fd_head;
} else {
/*
@@ -1243,8 +1310,7 @@ fragment_defragment_and_free (fragment_data *fd_head, const packet_info *pinfo)
static gboolean
fragment_add_seq_work(fragment_data *fd_head, tvbuff_t *tvb, const int offset,
const packet_info *pinfo, const guint32 frag_number,
- const guint32 frag_data_len, const gboolean more_frags,
- const guint32 flags _U_)
+ const guint32 frag_data_len, const gboolean more_frags)
{
fragment_data *fd;
fragment_data *fd_i;
@@ -1471,59 +1537,24 @@ fragment_add_seq_work(fragment_data *fd_head, tvbuff_t *tvb, const int offset,
* This function assumes frag_number being a block sequence number.
* The bsn for the first block is 0.
*/
-fragment_data *
-fragment_add_seq(tvbuff_t *tvb, const int offset, const packet_info *pinfo, const guint32 id,
- GHashTable *fragment_table, const guint32 frag_number,
- const guint32 frag_data_len, const gboolean more_frags)
-{
- fragment_key key;
-
- /* create key to search hash with */
- key.src = pinfo->src;
- key.dst = pinfo->dst;
- key.id = id;
-
- return fragment_add_seq_key(tvb, offset, pinfo,
- &key, fragment_key_copy,
- fragment_table, frag_number,
- frag_data_len, more_frags, 0);
-}
-
-
-fragment_data *
-fragment_add_dcerpc_dg(tvbuff_t *tvb, const int offset, const packet_info *pinfo, const guint32 id,
- void *v_act_id,
- GHashTable *fragment_table, const guint32 frag_number,
- const guint32 frag_data_len, const gboolean more_frags)
-{
- e_uuid_t *act_id = (e_uuid_t *)v_act_id;
- dcerpc_fragment_key key;
-
- /* create key to search hash with */
- key.src = pinfo->src;
- key.dst = pinfo->dst;
- key.id = id;
- key.act_id = *act_id;
-
- return fragment_add_seq_key(tvb, offset, pinfo,
- &key, dcerpc_fragment_key_copy,
- fragment_table, frag_number,
- frag_data_len, more_frags, 0);
-}
-
-fragment_data *
-fragment_add_seq_key(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
- void *key, fragment_key_copier key_copier,
- GHashTable *fragment_table, guint32 frag_number,
- const guint32 frag_data_len, const gboolean more_frags,
- const guint32 flags)
+static fragment_data *
+fragment_add_seq_common(reassembly_table *table, tvbuff_t *tvb,
+ const int offset, const packet_info *pinfo,
+ const guint32 id, const void *data,
+ guint32 frag_number, const guint32 frag_data_len,
+ const gboolean more_frags, const guint32 flags,
+ gpointer *orig_keyp)
{
fragment_data *fd_head;
- fd_head = (fragment_data *)g_hash_table_lookup(fragment_table, key);
+ gpointer orig_key;
+
+ fd_head = lookup_fd_head(table, pinfo, id, data, &orig_key);
/* have we already seen this frame ?*/
if (pinfo->fd->flags.visited) {
if (fd_head != NULL && fd_head->flags & FD_DEFRAGMENTED) {
+ if (orig_keyp != NULL)
+ *orig_keyp = orig_key;
return fd_head;
} else {
return NULL;
@@ -1532,7 +1563,7 @@ fragment_add_seq_key(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
if (fd_head==NULL){
/* not found, this must be the first snooped fragment for this
- * packet. Create list-head.
+ * packet. Create list-head.
*/
fd_head= new_head(FD_BLOCKSEQUENCE);
@@ -1552,17 +1583,15 @@ fragment_add_seq_key(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
* fragment_add_seq_check will then add it to the table
* of reassembled packets.
*/
+ if (*orig_keyp != NULL)
+ *orig_keyp = NULL;
fd_head->reassembled_in=pinfo->fd->num;
return fd_head;
}
- /*
- * We're going to use the key to insert the fragment,
- * so copy it to a long-term store.
- */
- if(key_copier != NULL)
- key = key_copier(key);
- g_hash_table_insert(fragment_table, key, fd_head);
+ orig_key = insert_fd_head(table, fd_head, pinfo, id, data);
+ if (orig_keyp != NULL)
+ *orig_keyp = orig_key;
/*
* If we weren't given an initial fragment number,
@@ -1571,6 +1600,9 @@ fragment_add_seq_key(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
if (flags & REASSEMBLE_FLAGS_NO_FRAG_NUMBER)
frag_number = 0;
} else {
+ if (orig_keyp != NULL)
+ *orig_keyp = orig_key;
+
if (flags & REASSEMBLE_FLAGS_NO_FRAG_NUMBER) {
fragment_data *fd;
/*
@@ -1602,23 +1634,19 @@ fragment_add_seq_key(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
if ((flags & REASSEMBLE_FLAGS_CHECK_DATA_PRESENT) &&
!tvb_bytes_exist(tvb, offset, frag_data_len)) {
if (!more_frags) {
- gpointer orig_key;
/*
* Remove this from the table of in-progress
* reassemblies, and free up any memory used for
* it in that table.
*/
- if (g_hash_table_lookup_extended(fragment_table, key,
- &orig_key, NULL)) {
- fragment_unhash(fragment_table, (fragment_key *)orig_key);
- }
+ fragment_unhash(table, *orig_keyp);
}
fd_head -> flags |= FD_DATA_NOT_PRESENT;
return frag_number == 0 ? fd_head : NULL;
}
if (fragment_add_seq_work(fd_head, tvb, offset, pinfo,
- frag_number, frag_data_len, more_frags, flags)) {
+ frag_number, frag_data_len, more_frags)) {
/*
* Reassembly is complete.
*/
@@ -1631,6 +1659,17 @@ fragment_add_seq_key(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
}
}
+fragment_data *
+fragment_add_seq(reassembly_table *table, tvbuff_t *tvb, const int offset,
+ const packet_info *pinfo, const guint32 id, const void *data,
+ const guint32 frag_number, const guint32 frag_data_len,
+ const gboolean more_frags, const guint32 flags)
+{
+ return fragment_add_seq_common(table, tvb, offset, pinfo, id, data,
+ frag_number, frag_data_len,
+ more_frags, flags, NULL);
+}
+
/*
* This does the work for "fragment_add_seq_check()" and
* "fragment_add_seq_next()".
@@ -1666,17 +1705,16 @@ fragment_add_seq_key(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
* XXX - Should we simply return NULL for zero-length fragments?
*/
static fragment_data *
-fragment_add_seq_check_work(tvbuff_t *tvb, const int offset,
- const packet_info *pinfo, const guint32 id,
- GHashTable *fragment_table,
- GHashTable *reassembled_table,
+fragment_add_seq_check_work(reassembly_table *table, tvbuff_t *tvb,
+ const int offset, const packet_info *pinfo,
+ const guint32 id, const void *data,
const guint32 frag_number,
const guint32 frag_data_len,
const gboolean more_frags, const guint32 flags)
{
reassembled_key reass_key;
- fragment_key key;
fragment_data *fd_head;
+ gpointer orig_key;
/*
* Have we already seen this frame?
@@ -1685,21 +1723,15 @@ fragment_add_seq_check_work(tvbuff_t *tvb, const int offset,
if (pinfo->fd->flags.visited) {
reass_key.frame = pinfo->fd->num;
reass_key.id = id;
- return (fragment_data *)g_hash_table_lookup(reassembled_table, &reass_key);
+ return (fragment_data *)g_hash_table_lookup(table->reassembled_table, &reass_key);
}
- /* create key to search hash with */
- key.src = pinfo->src;
- key.dst = pinfo->dst;
- key.id = id;
-
- fd_head = fragment_add_seq_key(tvb, offset, pinfo,
- &key, fragment_key_copy,
- fragment_table, frag_number,
- frag_data_len, more_frags, flags|REASSEMBLE_FLAGS_CHECK_DATA_PRESENT);
+ fd_head = fragment_add_seq_common(table, tvb, offset, pinfo, id, data,
+ frag_number, frag_data_len,
+ more_frags,
+ flags|REASSEMBLE_FLAGS_CHECK_DATA_PRESENT,
+ &orig_key);
if (fd_head) {
- gpointer orig_key;
-
if(fd_head->flags & FD_DATA_NOT_PRESENT) {
/* this is the first fragment of a datagram with
* truncated fragments. Don't move it to the
@@ -1709,23 +1741,19 @@ fragment_add_seq_check_work(tvbuff_t *tvb, const int offset,
/*
* Reassembly is complete.
- * Remove this from the table of in-progress
- * reassemblies, add it to the table of
- * reassembled packets, and return it.
+ *
+ * If this is in the table of in-progress reassemblies,
+ * remove it from that table. (It could be that this
+ * was the first and last fragment, so that no
+ * reassembly was done.)
*/
- if (g_hash_table_lookup_extended(fragment_table, &key,
- &orig_key, NULL)) {
- /*
- * Remove this from the table of in-progress reassemblies,
- * and free up any memory used for it in that table.
- */
- fragment_unhash(fragment_table, (fragment_key *)orig_key);
- }
+ if (orig_key != NULL)
+ fragment_unhash(table, orig_key);
/*
* Add this item to the table of reassembled packets.
*/
- fragment_reassembled(fd_head, pinfo, reassembled_table, id);
+ fragment_reassembled(table, fd_head, pinfo, id);
return fd_head;
} else {
/*
@@ -1736,50 +1764,46 @@ fragment_add_seq_check_work(tvbuff_t *tvb, const int offset,
}
fragment_data *
-fragment_add_seq_check(tvbuff_t *tvb, const int offset,
+fragment_add_seq_check(reassembly_table *table, tvbuff_t *tvb, const int offset,
const packet_info *pinfo, const guint32 id,
- GHashTable *fragment_table,
- GHashTable *reassembled_table, const guint32 frag_number,
- const guint32 frag_data_len, const gboolean more_frags)
+ const void *data,
+ const guint32 frag_number, const guint32 frag_data_len,
+ const gboolean more_frags)
{
- return fragment_add_seq_check_work(tvb, offset, pinfo, id,
- fragment_table, reassembled_table,
+ return fragment_add_seq_check_work(table, tvb, offset, pinfo, id, data,
frag_number, frag_data_len,
more_frags, 0);
}
fragment_data *
-fragment_add_seq_802_11(tvbuff_t *tvb, const int offset,
- const packet_info *pinfo, const guint32 id,
- GHashTable *fragment_table,
- GHashTable *reassembled_table,
+fragment_add_seq_802_11(reassembly_table *table, tvbuff_t *tvb,
+ const int offset, const packet_info *pinfo,
+ const guint32 id, const void *data,
const guint32 frag_number, const guint32 frag_data_len,
const gboolean more_frags)
{
- return fragment_add_seq_check_work(tvb, offset, pinfo, id,
- fragment_table, reassembled_table,
+ return fragment_add_seq_check_work(table, tvb, offset, pinfo, id, data,
frag_number, frag_data_len,
more_frags,
REASSEMBLE_FLAGS_802_11_HACK);
}
fragment_data *
-fragment_add_seq_next(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
- const guint32 id, GHashTable *fragment_table,
- GHashTable *reassembled_table, const guint32 frag_data_len,
+fragment_add_seq_next(reassembly_table *table, tvbuff_t *tvb, const int offset,
+ const packet_info *pinfo, const guint32 id,
+ const void *data, const guint32 frag_data_len,
const gboolean more_frags)
{
- return fragment_add_seq_check_work(tvb, offset, pinfo, id,
- fragment_table, reassembled_table, 0,
- frag_data_len, more_frags,
+ return fragment_add_seq_check_work(table, tvb, offset, pinfo, id, data,
+ 0, frag_data_len, more_frags,
REASSEMBLE_FLAGS_NO_FRAG_NUMBER);
}
void
-fragment_start_seq_check(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table,
+fragment_start_seq_check(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id, const void *data,
const guint32 tot_len)
{
- fragment_key key, *new_key;
fragment_data *fd_head;
/* Have we already seen this frame ?*/
@@ -1787,13 +1811,8 @@ fragment_start_seq_check(const packet_info *pinfo, const guint32 id, GHashTable
return;
}
- /* Create key to search hash with */
- key.src = pinfo->src;
- key.dst = pinfo->dst;
- key.id = id;
-
- /* Check if fragment data exist for this key */
- fd_head = (fragment_data *)g_hash_table_lookup(fragment_table, &key);
+ /* Check if fragment data exists */
+ fd_head = lookup_fd_head(table, pinfo, id, data, NULL);
if (fd_head == NULL) {
/* Create list-head. */
@@ -1805,23 +1824,19 @@ fragment_start_seq_check(const packet_info *pinfo, const guint32 id, GHashTable
fd_head->flags = FD_BLOCKSEQUENCE|FD_DATALEN_SET;
fd_head->data = NULL;
fd_head->reassembled_in = 0;
- /*
- * We're going to use the key to insert the fragment,
- * so copy it to a long-term store.
- */
- new_key = (fragment_key *)fragment_key_copy(&key);
- g_hash_table_insert(fragment_table, new_key, fd_head);
+
+ insert_fd_head(table, fd_head, pinfo, id, data);
}
}
fragment_data *
-fragment_end_seq_next(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table,
- GHashTable *reassembled_table)
+fragment_end_seq_next(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id, const void *data)
{
reassembled_key reass_key;
reassembled_key *new_key;
- fragment_key key;
fragment_data *fd_head;
+ gpointer orig_key;
/*
* Have we already seen this frame?
@@ -1830,19 +1845,12 @@ fragment_end_seq_next(const packet_info *pinfo, const guint32 id, GHashTable *fr
if (pinfo->fd->flags.visited) {
reass_key.frame = pinfo->fd->num;
reass_key.id = id;
- return (fragment_data *)g_hash_table_lookup(reassembled_table, &reass_key);
+ return (fragment_data *)g_hash_table_lookup(table->reassembled_table, &reass_key);
}
- /* create key to search hash with */
- key.src = pinfo->src;
- key.dst = pinfo->dst;
- key.id = id;
-
- fd_head = (fragment_data *)g_hash_table_lookup (fragment_table, &key);
+ fd_head = lookup_fd_head(table, pinfo, id, data, &orig_key);
if (fd_head) {
- gpointer orig_key;
-
if (fd_head->flags & FD_DATA_NOT_PRESENT) {
/* No data added */
return NULL;
@@ -1854,28 +1862,20 @@ fragment_end_seq_next(const packet_info *pinfo, const guint32 id, GHashTable *fr
fragment_defragment_and_free (fd_head, pinfo);
/*
- * Remove this from the table of in-progress
- * reassemblies, add it to the table of
- * reassembled packets, and return it.
+ * Remove this from the table of in-progress reassemblies,
+ * and free up any memory used for it in that table.
*/
- if (g_hash_table_lookup_extended(fragment_table, &key,
- &orig_key, NULL)) {
- /*
- * Remove this from the table of in-progress reassemblies,
- * and free up any memory used for it in that table.
- */
- fragment_unhash(fragment_table, (fragment_key *)orig_key);
- }
+ fragment_unhash(table, orig_key);
/*
* Add this item to the table of reassembled packets.
*/
- fragment_reassembled(fd_head, pinfo, reassembled_table, id);
+ fragment_reassembled(table, fd_head, pinfo, id);
if (fd_head->next != NULL) {
new_key = g_slice_new(reassembled_key);
new_key->frame = pinfo->fd->num;
new_key->id = id;
- g_hash_table_insert(reassembled_table, new_key, fd_head);
+ g_hash_table_insert(table->reassembled_table, new_key, fd_head);
}
return fd_head;
diff --git a/epan/reassemble.h b/epan/reassemble.h
index 4acd6619d9..c62eaa055e 100644
--- a/epan/reassemble.h
+++ b/epan/reassemble.h
@@ -101,29 +101,64 @@ typedef struct _fragment_data {
* in the tvb, and if not, do something a bit odd. */
#define REASSEMBLE_FLAGS_CHECK_DATA_PRESENT 0x0004
-/* a function for copying hash keys */
-typedef void *(*fragment_key_copier)(const void *key);
+/* a function for creating temporary hash keys */
+typedef gpointer (*fragment_temporary_key)(const packet_info *pinfo,
+ const guint32 id, const void *data);
+
+/* a function for creating persistent hash keys */
+typedef gpointer (*fragment_persistent_key)(const packet_info *pinfo,
+ const guint32 id, const void *data);
+
+/*
+ * Data structure to keep track of fragments and reassemblies.
+ */
+typedef struct {
+ GHashTable *fragment_table;
+ GHashTable *reassembled_table;
+ fragment_temporary_key temporary_key_func;
+ fragment_persistent_key persistent_key_func;
+ GDestroyNotify free_temporary_key_func; /* temporary key destruction function */
+} reassembly_table;
/*
- * Initialize/destroy a fragment table.
+ * Table of functions for a reassembly table.
+ */
+typedef struct {
+ /* Functions for fragment table */
+ GHashFunc hash_func; /* hash function */
+ GEqualFunc equal_func; /* comparison function */
+ fragment_temporary_key temporary_key_func; /* temporary key creation function */
+ fragment_persistent_key persistent_key_func; /* persistent key creation function */
+ GDestroyNotify free_temporary_key_func; /* temporary key destruction function */
+ GDestroyNotify free_persistent_key_func; /* persistent key destruction function */
+} reassembly_table_functions;
+
+/*
+ * Tables of functions exported for the benefit of dissectors that
+ * don't need special items in their keys.
+ */
+WS_DLL_PUBLIC const reassembly_table_functions
+ addresses_reassembly_table_functions; /* keys have endpoint addresses and an ID */
+WS_DLL_PUBLIC const reassembly_table_functions
+ addresses_ports_reassembly_table_functions; /* keys have endpoint addresses and ports and an ID */
+
+/*
+ * Initialize/destroy a reassembly table.
*
* init: If table doesn't exist: create table;
* else: just remove any entries;
* destroy: remove entries and destroy table;
*/
-WS_DLL_PUBLIC void fragment_table_init(GHashTable **fragment_table);
-extern void fragment_table_destroy(GHashTable **fragment_table);
-WS_DLL_PUBLIC void dcerpc_fragment_table_init(GHashTable **fragment_table);
-
-/*
- * Initialize a reassembled-packet table.
- */
-WS_DLL_PUBLIC void reassembled_table_init(GHashTable **reassembled_table);
+WS_DLL_PUBLIC void
+reassembly_table_init(reassembly_table *table,
+ const reassembly_table_functions *funcs);
+WS_DLL_PUBLIC void
+reassembly_table_destroy(reassembly_table *table);
/*
- * This function adds a new fragment to the fragment hash table.
+ * This function adds a new fragment to the reassembly table
* If this is the first fragment seen for this datagram, a new entry
- * is created in the hash table, otherwise this fragment is just added
+ * is created in the table, otherwise this fragment is just added
* to the linked list of fragments for this packet.
* The list of fragments for a specific datagram is kept sorted for
* easier handling.
@@ -131,25 +166,33 @@ WS_DLL_PUBLIC void reassembled_table_init(GHashTable **reassembled_table);
* Returns a pointer to the head of the fragment data list if we have all the
* fragments, NULL otherwise.
*/
-WS_DLL_PUBLIC fragment_data *fragment_add(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
- const guint32 id, GHashTable *fragment_table, const guint32 frag_offset,
- guint32 const frag_data_len, const gboolean more_frags);
-WS_DLL_PUBLIC fragment_data *fragment_add_multiple_ok(tvbuff_t *tvb, const int offset,
- const packet_info *pinfo, const guint32 id, GHashTable *fragment_table,
- const guint32 frag_offset, const guint32 frag_data_len, const gboolean more_frags);
+WS_DLL_PUBLIC fragment_data *
+fragment_add(reassembly_table *table, tvbuff_t *tvb, const int offset,
+ const packet_info *pinfo, const guint32 id, const void *data,
+ const guint32 frag_offset, const guint32 frag_data_len,
+ const gboolean more_frags);
+WS_DLL_PUBLIC fragment_data *
+fragment_add_multiple_ok(reassembly_table *table, tvbuff_t *tvb,
+ const int offset, const packet_info *pinfo,
+ const guint32 id, const void *data,
+ const guint32 frag_offset,
+ const guint32 frag_data_len,
+ const gboolean more_frags);
/*
- * This routine extends fragment_add to use a "reassembled_table".
+ * This routine extends fragment_add to use a "reassembled_table"
+ * included in the reassembly table.
*
* If, after processing this fragment, we have all the fragments, they
* remove that from the fragment hash table if necessary and add it
* to the table of reassembled fragments, and return a pointer to the
* head of the fragment list.
*/
-WS_DLL_PUBLIC fragment_data *fragment_add_check(tvbuff_t *tvb, const int offset,
- const packet_info *pinfo, const guint32 id, GHashTable *fragment_table,
- GHashTable *reassembled_table, const guint32 frag_offset,
- const guint32 frag_data_len, const gboolean more_frags);
+WS_DLL_PUBLIC fragment_data *
+fragment_add_check(reassembly_table *table, tvbuff_t *tvb, const int offset,
+ const packet_info *pinfo, const guint32 id,
+ const void *data, const guint32 frag_offset,
+ const guint32 frag_data_len, const gboolean more_frags);
/* same as fragment_add() but this one assumes frag_number is a block
sequence number. note that frag_number is 0 for the first fragment. */
@@ -179,33 +222,14 @@ WS_DLL_PUBLIC fragment_data *fragment_add_check(tvbuff_t *tvb, const int offset,
* If this packet completes assembly, these functions return the head of the
* fragment data; otherwise, they return null.
*/
-
-/* "key" should be an arbitrary key used for indexing the fragment hash;
- * "key_copier" is called to copy the key to a more appropriate store before
- * inserting a new entry to the hash.
- */
-fragment_data *
-fragment_add_seq_key(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
- void *key, fragment_key_copier key_copier,
- GHashTable *fragment_table, guint32 frag_number,
- const guint32 frag_data_len, const gboolean more_frags,
- const guint32 flags);
-
-/* a wrapper for fragment_add_seq_key - uses a key of source, dest and id */
-WS_DLL_PUBLIC fragment_data *fragment_add_seq(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
- const guint32 id, GHashTable *fragment_table, const guint32 frag_number,
- const guint32 frag_data_len, const gboolean more_frags);
-
-/* another wrapper for fragment_add_seq_key - uses a key of source, dest, id
- * and act_id */
WS_DLL_PUBLIC fragment_data *
-fragment_add_dcerpc_dg(tvbuff_t *tvb, const int offset, const packet_info *pinfo, const guint32 id,
- void *act_id,
- GHashTable *fragment_table, const guint32 frag_number,
- const guint32 frag_data_len, const gboolean more_frags);
+fragment_add_seq(reassembly_table *table, tvbuff_t *tvb, const int offset,
+ const packet_info *pinfo, const guint32 id, const void *data,
+ const guint32 frag_number, const guint32 frag_data_len,
+ const gboolean more_frags, const guint32 flags);
/*
- * These routines extend fragment_add_seq_key to use a "reassembled_table".
+ * These routines extend fragment_add_seq to use the "reassembled_table".
*
* If, after processing this fragment, we have all the fragments, they
* remove that from the fragment hash table if necessary and add it
@@ -213,33 +237,33 @@ fragment_add_dcerpc_dg(tvbuff_t *tvb, const int offset, const packet_info *pinfo
* head of the fragment list.
*/
WS_DLL_PUBLIC fragment_data *
-fragment_add_seq_check(tvbuff_t *tvb, const int offset,
+fragment_add_seq_check(reassembly_table *table, tvbuff_t *tvb, const int offset,
const packet_info *pinfo, const guint32 id,
- GHashTable *fragment_table,
- GHashTable *reassembled_table, const guint32 frag_number,
- const guint32 frag_data_len, const gboolean more_frags);
+ const void *data,
+ const guint32 frag_number, const guint32 frag_data_len,
+ const gboolean more_frags);
WS_DLL_PUBLIC fragment_data *
-fragment_add_seq_802_11(tvbuff_t *tvb, const int offset,
- const packet_info *pinfo, const guint32 id,
- GHashTable *fragment_table,
- GHashTable *reassembled_table,
+fragment_add_seq_802_11(reassembly_table *table, tvbuff_t *tvb,
+ const int offset, const packet_info *pinfo,
+ const guint32 id, const void *data,
const guint32 frag_number, const guint32 frag_data_len,
const gboolean more_frags);
WS_DLL_PUBLIC fragment_data *
-fragment_add_seq_next(tvbuff_t *tvb, const int offset, const packet_info *pinfo,
- const guint32 id, GHashTable *fragment_table,
- GHashTable *reassembled_table,
- const guint32 frag_data_len, const gboolean more_frags);
+fragment_add_seq_next(reassembly_table *table, tvbuff_t *tvb, const int offset,
+ const packet_info *pinfo, const guint32 id,
+ const void *data, const guint32 frag_data_len,
+ const gboolean more_frags);
-extern void
-fragment_start_seq_check(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table,
+WS_DLL_PUBLIC void
+fragment_start_seq_check(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id, const void *data,
const guint32 tot_len);
WS_DLL_PUBLIC fragment_data *
-fragment_end_seq_next(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table,
- GHashTable *reassembled_table);
+fragment_end_seq_next(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id, const void *data);
/* to specify how much to reassemble, for fragmentation where last fragment can not be
* identified by flags or such.
* note that for FD_BLOCKSEQUENCE tot_len is the index for the tail fragment.
@@ -248,12 +272,13 @@ fragment_end_seq_next(const packet_info *pinfo, const guint32 id, GHashTable *fr
*
*/
WS_DLL_PUBLIC void
-fragment_set_tot_len(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table,
- const guint32 tot_len);
+fragment_set_tot_len(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id, const void *data, const guint32 tot_len);
/* to resad whatever totlen previously set */
WS_DLL_PUBLIC guint32
-fragment_get_tot_len(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table);
+fragment_get_tot_len(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id, const void *data);
/*
* This function will set the partial reassembly flag(FD_PARTIAL_REASSEMBLY) for a fh.
@@ -264,21 +289,25 @@ fragment_get_tot_len(const packet_info *pinfo, const guint32 id, GHashTable *fra
* and if FD_DEFRAGMENTED is set, the reassembly process will be continued.
*/
WS_DLL_PUBLIC void
-fragment_set_partial_reassembly(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table);
+fragment_set_partial_reassembly(reassembly_table *table,
+ const packet_info *pinfo, const guint32 id,
+ const void *data);
/* This function is used to check if there is partial or completed reassembly state
* matching this packet. I.e. Are there reassembly going on or not for this packet?
*/
WS_DLL_PUBLIC fragment_data *
-fragment_get(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table);
+fragment_get(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id, const void *data);
/* The same for the reassemble table */
/* id *must* be the frame number for this to work! */
-fragment_data *
-fragment_get_reassembled(const guint32 id, GHashTable *reassembled_table);
+WS_DLL_PUBLIC fragment_data *
+fragment_get_reassembled(reassembly_table *table, const guint32 id);
WS_DLL_PUBLIC fragment_data *
-fragment_get_reassembled_id(const packet_info *pinfo, const guint32 id, GHashTable *reassembled_table);
+fragment_get_reassembled_id(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id);
/* This will free up all resources and delete reassembly state for this PDU.
* Except if the PDU is completely reassembled, then it would NOT deallocate the
@@ -289,7 +318,8 @@ fragment_get_reassembled_id(const packet_info *pinfo, const guint32 id, GHashTab
* g_free() that buffer.
*/
WS_DLL_PUBLIC unsigned char *
-fragment_delete(const packet_info *pinfo, const guint32 id, GHashTable *fragment_table);
+fragment_delete(reassembly_table *table, const packet_info *pinfo,
+ const guint32 id, const void *data);
/* This struct holds references to all the tree and field handles used when
* displaying the reassembled fragment tree in the packet details view. A
diff --git a/epan/stream.c b/epan/stream.c
index 66ee51b763..3f24d25597 100644
--- a/epan/stream.c
+++ b/epan/stream.c
@@ -312,9 +312,8 @@ static stream_pdu_fragment_t *fragment_hash_insert( const stream_t *stream, guin
/*****************************************************************************/
-/* fragmentation hash tables */
-static GHashTable *stream_fragment_table = NULL;
-static GHashTable *stream_reassembled_table = NULL;
+/* reassembly table */
+static reassembly_table stream_reassembly_table;
/* Initialise a new stream. Call this when you first identify a distinct
* stream. */
@@ -378,8 +377,8 @@ void stream_init( void )
init_fragment_hash();
stream_init_pdu_data();
- fragment_table_init(&stream_fragment_table);
- reassembled_table_init(&stream_reassembled_table);
+ reassembly_table_init(&stream_reassembly_table,
+ &addresses_reassembly_table_functions);
}
/*****************************************************************************/
@@ -410,8 +409,8 @@ stream_pdu_fragment_t *stream_add_frag( stream_t *stream, guint32 framenum, guin
}
/* add it to the reassembly tables */
- fd_head = fragment_add_seq_next(tvb, 0, pinfo, pdu->id,
- stream_fragment_table, stream_reassembled_table,
+ fd_head = fragment_add_seq_next(&stream_reassembly_table,
+ tvb, 0, pinfo, pdu->id, NULL,
tvb_reported_length(tvb), more_frags);
/* add it to our hash */
frag_data = fragment_hash_insert( stream, framenum, offset, tvb_reported_length(tvb));