2 * MATE -- Meta Analysis Tracing Engine
4 * Copyright 2004, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 typedef struct _mate_range mate_range;
37 typedef struct _tmp_pdu_data {
39 GHashTable* interesting;
44 typedef struct _gogkey {
50 static mate_runtime_data* rd = NULL;
51 static mate_config* mc = NULL;
55 static int* dbg = &zero;
56 static int* dbg_pdu = &zero;
57 static int* dbg_gop = &zero;
58 static int* dbg_gog = &zero;
59 static FILE* dbg_facility = NULL;
61 static gboolean destroy_mate_pdus(gpointer k _U_, gpointer v, gpointer p _U_) {
62 mate_pdu* pdu = (mate_pdu*) v;
63 if (pdu->avpl) delete_avpl(pdu->avpl,TRUE);
64 g_mem_chunk_free(rd->mate_items,pdu);
68 static gboolean destroy_mate_gops(gpointer k _U_, gpointer v, gpointer p _U_) {
69 mate_gop* gop = (mate_gop*) v;
71 if (gop->avpl) delete_avpl(gop->avpl,TRUE);
74 if (g_hash_table_lookup(gop->cfg->gop_index,gop->gop_key) == gop) {
75 g_hash_table_remove(gop->cfg->gop_index,gop->gop_key);
81 g_mem_chunk_free(rd->mate_items,gop);
87 static void gog_remove_keys (mate_gog* gog);
89 static gboolean destroy_mate_gogs(gpointer k _U_, gpointer v, gpointer p _U_) {
90 mate_gog* gog = (mate_gog*) v;
92 if (gog->avpl) delete_avpl(gog->avpl,TRUE);
96 g_ptr_array_free(gog->gog_keys,FALSE);
99 g_mem_chunk_free(rd->mate_items,gog);
104 static gboolean return_true(gpointer k _U_, gpointer v _U_, gpointer p _U_) {
108 static void destroy_pdus_in_cfg(gpointer k _U_, gpointer v, gpointer p _U_) {
110 g_hash_table_foreach_remove(c->items,destroy_mate_pdus,NULL);
115 static void destroy_gops_in_cfg(gpointer k _U_, gpointer v, gpointer p _U_) {
118 g_hash_table_foreach_remove(c->gop_index,return_true,NULL);
119 g_hash_table_destroy(c->gop_index);
120 c->gop_index = g_hash_table_new(g_str_hash,g_str_equal);
122 g_hash_table_foreach_remove(c->gog_index,return_true,NULL);
123 g_hash_table_destroy(c->gog_index);
124 c->gog_index = g_hash_table_new(g_str_hash,g_str_equal);
126 g_hash_table_foreach_remove(c->items,destroy_mate_gops,NULL);
130 static void destroy_gogs_in_cfg(gpointer k _U_, gpointer v, gpointer p _U_) {
132 g_hash_table_foreach_remove(c->items,destroy_mate_gogs,NULL);
136 extern void initialize_mate_runtime(void) {
138 dbg_print (dbg,5,dbg_facility,"initialize_mate: entering");
140 if (( mc = mate_cfg() )) {
142 rd = g_malloc(sizeof(mate_runtime_data));
143 rd->mate_items = g_mem_chunk_new("mate_items",sizeof(mate_max_size),1024,G_ALLOC_AND_FREE);
145 g_hash_table_foreach(mc->pducfgs,destroy_pdus_in_cfg,NULL);
146 g_hash_table_foreach(mc->gopcfgs,destroy_gops_in_cfg,NULL);
147 g_hash_table_foreach(mc->gogcfgs,destroy_gogs_in_cfg,NULL);
149 g_hash_table_destroy(rd->frames);
152 rd->current_items = 0;
154 rd->highest_analyzed_frame = 0;
155 rd->frames = g_hash_table_new(g_direct_hash,g_direct_equal);
158 /*mc->dbg_gop_lvl = 5;
161 dbg_pdu = &(mc->dbg_pdu_lvl);
162 dbg_gop = &(mc->dbg_gop_lvl);
163 dbg_gog = &(mc->dbg_gog_lvl);
164 dbg = &(mc->dbg_lvl);
165 dbg_facility = mc->dbg_facility;
167 dbg_print(dbg, 1, dbg_facility, "starting mate");
175 static mate_gop* new_gop(mate_cfg_gop* cfg, mate_pdu* pdu, gchar* key) {
176 mate_gop* gop = g_mem_chunk_alloc(rd->mate_items);
178 gop->id = ++(cfg->last_id);
181 dbg_print(dbg_gop, 1, dbg_facility, "new_gop: %s: ``%s:%d''", key, gop->cfg->name, gop->id);
184 gop->avpl = new_avpl(cfg->name);
190 gop->expiration = cfg->expiration > 0.0 ? cfg->expiration + rd->now : (float) -1.0 ;
191 gop->idle_expiration = cfg->idle_timeout > 0.0 ? cfg->idle_timeout + rd->now : (float) -1.0 ;
192 gop->time_to_die = cfg->lifetime > 0.0 ? cfg->lifetime + rd->now : (float) -1.0 ;
193 gop->time_to_timeout = 0.0;
195 gop->last_time = gop->start_time = rd->now;
196 gop->release_time = 0.0;
198 gop->num_of_pdus = 0;
199 gop->num_of_after_release_pdus = 0;
204 gop->released = FALSE;
208 pdu->is_start = TRUE;
209 pdu->time_in_gop = 0.0;
211 g_hash_table_insert(cfg->gop_index,gop->gop_key,gop);
215 static void adopt_gop(mate_gog* gog, mate_gop* gop) {
216 dbg_print (dbg_gog,5,dbg_facility,"adopt_gop: gog=%X gop=%X",gog,gop);
221 if (gop->cfg->start) {
222 gog->num_of_counting_gops++;
228 gog->last_gop->next = gop;
239 static mate_gog* new_gog(mate_cfg_gog* cfg, mate_gop* gop) {
240 mate_gog* gog = g_mem_chunk_alloc(rd->mate_items);
242 gog->id = ++(cfg->last_id);
245 dbg_print (dbg_gog,1,dbg_facility,"new_gog: %s:%u for %s:%u",gog->cfg->name,gog->id,gop->cfg->name,gop->id);
247 gog->avpl = new_avpl(cfg->name);
250 gog->expiration = 0.0;
251 gog->idle_expiration = 0.0;
253 gog->start_time = rd->now;
254 gog->release_time = 0.0;
255 gog->last_time = 0.0;
258 gog->last_gop = NULL;
260 gog->num_of_gops = 0;
261 gog->num_of_counting_gops = 0;
262 gog->num_of_released_gops = 0;
264 gog->gog_keys = g_ptr_array_new();
271 static void apply_transforms(GPtrArray* transforms, AVPL* avpl) {
272 AVPL_Transf* transform = NULL;
275 for (i = 0; i < transforms->len; i++) {
276 transform = g_ptr_array_index(transforms,i);
277 avpl_transform(avpl, transform);
282 /* applies the extras for which type to what avpl */
283 static void apply_extras(AVPL* from, AVPL* to, AVPL* extras) {
284 AVPL* our_extras = new_avpl_loose_match("",from, extras, FALSE) ;
287 merge_avpl(to,our_extras,TRUE);
288 delete_avpl(our_extras,FALSE);
292 static void gog_remove_keys (mate_gog* gog) {
295 while (gog->gog_keys->len) {
296 gog_key = g_ptr_array_remove_index_fast(gog->gog_keys,0);
298 if (g_hash_table_lookup(gog_key->cfg->gog_index,gog_key->key) == gog) {
299 g_hash_table_remove(gog_key->cfg->gog_index,gog_key->key);
302 g_free(gog_key->key);
308 static void reanalyze_gop(mate_gop* gop) {
309 LoAL* gog_keys = NULL;
310 AVPL* curr_gogkey = NULL;
311 mate_cfg_gop* gop_cfg = NULL;
313 AVPL* gogkey_match = NULL;
314 mate_gog* gog = gop->gog;
319 gog->last_time = rd->now;
321 dbg_print (dbg_gog,1,dbg_facility,"reanalize_gop: %s:%d",gop->cfg->name,gop->id);
323 apply_extras(gop->avpl,gog->avpl,gog->cfg->extra);
325 /* XXX: Instead of using the length of the avpl to check if an avpl has changed,
326 which is not accurate at all, we should have apply_extras,
327 apply_transformations and other functions that can modify the avpl
328 to flag the avpl if it has changed, then we'll check for the flag
329 and clear it after analysis */
331 if (gog->last_n != gog->avpl->len) {
333 dbg_print (dbg_gog,2,dbg_facility,"reanalize_gop: gog has new attributes let's look for new keys");
335 gog_keys = gog->cfg->keys;
337 while (( curr_gogkey = get_next_avpl(gog_keys,&cookie) )) {
338 gop_cfg = g_hash_table_lookup(mc->gopcfgs,curr_gogkey->name);
340 if (( gogkey_match = new_avpl_exact_match(gop_cfg->name,gog->avpl,curr_gogkey,FALSE) )) {
342 gog_key = g_malloc(sizeof(gogkey));
344 gog_key->key = avpl_to_str(gogkey_match);
345 delete_avpl(gogkey_match,FALSE);
347 gog_key->cfg = gop_cfg;
349 if (g_hash_table_lookup(gop_cfg->gog_index,gog_key->key)) {
350 g_free(gog_key->key);
356 /* XXX: since these gogs actually share key info
357 we should try to merge (non released) gogs
358 that happen to have equal keys */
360 dbg_print (dbg_gog,1,dbg_facility,"analize_gop: new key for gog=%s:%d : %s",gog->cfg->name,gog->id,gog_key->key);
361 g_ptr_array_add(gog->gog_keys,gog_key);
362 g_hash_table_insert(gog_key->cfg->gog_index,gog_key->key,gog);
368 gog->last_n = gog->avpl->len;
371 if (gog->num_of_released_gops == gog->num_of_counting_gops) {
372 gog->released = TRUE;
373 gog->expiration = gog->cfg->expiration + rd->now;
375 gog->released = FALSE;
379 static void analize_gop(mate_gop* gop) {
380 mate_cfg_gog* cfg = NULL;
381 LoAL* gog_keys = NULL;
382 AVPL* curr_gogkey = NULL;
384 AVPL* gogkey_match = NULL;
385 mate_gog* gog = NULL;
388 if ( ! ( gog = gop->gog ) ) {
389 /* no gog, let's either find one or create it if due */
390 dbg_print (dbg_gog,1,dbg_facility,"analize_gop: no gog");
392 gog_keys = g_hash_table_lookup(mc->gogs_by_gopname,gop->cfg->name);
395 dbg_print (dbg_gog,1,dbg_facility,"analize_gop: no gog_keys for this gop");
399 /* We have gog_keys! look for matching gogkeys */
401 dbg_print (dbg_gog,1,dbg_facility,"analize_gop: got gog_keys: %s",gog_keys->name) ;
403 while (( curr_gogkey = get_next_avpl(gog_keys,&cookie) )) {
404 if (( gogkey_match = new_avpl_exact_match(gop->cfg->name,gop->avpl,curr_gogkey,TRUE) )) {
406 key = avpl_to_str(gogkey_match);
408 dbg_print (dbg_gog,1,dbg_facility,"analize_gop: got gogkey_match: %s",key);
410 if (( gog = g_hash_table_lookup(gop->cfg->gog_index,key) )) {
411 dbg_print (dbg_gog,1,dbg_facility,"analize_gop: got already a matching gog");
413 if (gog->num_of_counting_gops == gog->num_of_released_gops && gog->expiration < rd->now) {
414 dbg_print (dbg_gog,1,dbg_facility,"analize_gop: this is a new gog, not the old one, let's create it");
416 gog_remove_keys(gog);
418 gog = new_gog(gog->cfg,gop);
422 dbg_print (dbg_gog,1,dbg_facility,"analize_gop: this is our gog");
424 if (! gop->gog ) adopt_gop(gog,gop);
429 dbg_print (dbg_gog,1,dbg_facility,"analize_gop: no such gog in hash, let's create a new %s",curr_gogkey->name);
431 cfg = g_hash_table_lookup(mc->gogcfgs,curr_gogkey->name);
434 gog = new_gog(cfg,gop);
435 gog->num_of_gops = 1;
437 if (gop->cfg->start) {
438 gog->num_of_counting_gops = 1;
442 dbg_print (dbg_gog,0,dbg_facility,"analize_gop: no such gog_cfg: %s",curr_gogkey->name);
449 delete_avpl(gogkey_match,TRUE);
453 if (key) g_free(key);
456 dbg_print (dbg_gog,1,dbg_facility,"analize_gop: no gogkey_match: %s",key);
459 if (key) g_free(key);
461 if (gogkey_match) delete_avpl(gogkey_match,TRUE);
469 static void analize_pdu(mate_pdu* pdu) {
471 return a g_boolean to tell we've destroyed the pdu when the pdu is unnassigned
472 destroy the unassigned pdu
474 mate_cfg_gop* cfg = NULL;
475 mate_gop* gop = NULL;
477 gchar* orig_gop_key = NULL;
478 AVPL* candidate_start = NULL;
479 AVPL* candidate_stop = NULL;
480 AVPL* is_start = NULL;
481 AVPL* is_stop = NULL;
482 AVPL* gopkey_match = NULL;
483 LoAL* gog_keys = NULL;
484 AVPL* curr_gogkey = NULL;
486 AVPL* gogkey_match = NULL;
487 gchar* gogkey = NULL;
489 dbg_print (dbg_gop,1,dbg_facility,"analize_pdu: %s",pdu->cfg->name);
491 if (! (cfg = g_hash_table_lookup(mc->gops_by_pduname,pdu->cfg->name)) )
494 if ((gopkey_match = new_avpl_exact_match("gop_key_match",pdu->avpl,cfg->key, TRUE))) {
495 gop_key = avpl_to_str(gopkey_match);
497 g_hash_table_lookup_extended(cfg->gop_index,(gconstpointer)gop_key,(gpointer*)&orig_gop_key,(gpointer*)&gop);
502 /* is the gop dead ? */
503 if ( ! gop->released &&
504 ( ( gop->cfg->lifetime > 0.0 && gop->time_to_die >= rd->now) ||
505 ( gop->cfg->idle_timeout > 0.0 && gop->time_to_timeout >= rd->now) ) ) {
506 dbg_print (dbg_gop,4,dbg_facility,"analize_pdu: expiring released gop");
507 gop->released = TRUE;
509 if (gop->gog && gop->cfg->start) gop->gog->num_of_released_gops++;
512 /* TODO: is the gop expired? */
514 gop_key = orig_gop_key;
516 dbg_print (dbg_gop,2,dbg_facility,"analize_pdu: got gop: %s",gop_key);
518 if (( candidate_start = cfg->start )) {
520 dbg_print (dbg_gop,2,dbg_facility,"analize_pdu: got candidate start");
522 if (( is_start = new_avpl_exact_match("",pdu->avpl, candidate_start, FALSE) )) {
523 delete_avpl(is_start,FALSE);
524 if ( gop->released ) {
525 dbg_print (dbg_gop,3,dbg_facility,"analize_pdu: start on released gop, let's create a new gop");
527 g_hash_table_remove(cfg->gop_index,gop_key);
529 gop = new_gop(cfg,pdu,gop_key);
530 g_hash_table_insert(cfg->gop_index,gop_key,gop);
532 dbg_print (dbg_gop,1,dbg_facility,"analize_pdu: duplicate start on gop");
539 if (gop->last_pdu) gop->last_pdu->next = pdu;
542 pdu->time_in_gop = rd->now - gop->start_time;
544 if (gop->released) pdu->after_release = TRUE;
548 dbg_print (dbg_gop,1,dbg_facility,"analize_pdu: no gop already");
550 if ( ! cfg->start ) {
551 /* there is no GopStart, we'll check for matching GogKeys
552 if we have one we'll create the Gop */
554 apply_extras(pdu->avpl,gopkey_match,cfg->extra);
556 gog_keys = g_hash_table_lookup(mc->gogs_by_gopname,cfg->name);
560 while (( curr_gogkey = get_next_avpl(gog_keys,&cookie) )) {
561 if (( gogkey_match = new_avpl_exact_match(cfg->name,gopkey_match,curr_gogkey,FALSE) )) {
562 gogkey = avpl_to_str(gogkey_match);
564 if (g_hash_table_lookup(cfg->gog_index,gogkey)) {
565 gop = new_gop(cfg,pdu,gop_key);
566 g_hash_table_insert(cfg->gop_index,gop_key,gop);
567 delete_avpl(gogkey_match,FALSE);
571 delete_avpl(gogkey_match,FALSE);
579 delete_avpl(gopkey_match,TRUE);
585 delete_avpl(gopkey_match,TRUE);
590 candidate_start = cfg->start;
592 if (( is_start = new_avpl_exact_match("",pdu->avpl, candidate_start, FALSE) )) {
593 delete_avpl(is_start,FALSE);
594 gop = new_gop(cfg,pdu,gop_key);
604 if (gop->last_pdu) gop->last_pdu->next = pdu;
608 pdu->time_in_gop = rd->now - gop->start_time;
611 gop->time_to_timeout = cfg->idle_timeout > 0.0 ? cfg->idle_timeout + rd->now : (float) -1.0 ;
613 dbg_print (dbg_gop,4,dbg_facility,"analize_pdu: merge with key");
615 merge_avpl(gop->avpl,gopkey_match,TRUE);
616 delete_avpl(gopkey_match,TRUE);
618 dbg_print (dbg_gop,4,dbg_facility,"analize_pdu: apply extras");
620 apply_extras(pdu->avpl,gop->avpl,gop->cfg->extra);
622 gop->last_time = pdu->rel_time;
624 if ( ! gop->released) {
625 candidate_stop = cfg->stop;
627 if (candidate_stop) {
628 is_stop = new_avpl_exact_match("",pdu->avpl, candidate_stop,FALSE);
630 is_stop = new_avpl("");
634 dbg_print (dbg_gop,1,dbg_facility,"analize_pdu: is a `stop");
635 delete_avpl(is_stop,FALSE);
637 if (! gop->released) {
638 gop->released = TRUE;
639 gop->release_time = pdu->rel_time;
640 if (gop->gog && gop->cfg->start) gop->gog->num_of_released_gops++;
648 if (gop->last_n != gop->avpl->len) apply_transforms(gop->cfg->transforms,gop->avpl);
650 gop->last_n = gop->avpl->len;
659 dbg_print (dbg_gop,4,dbg_facility,"analize_pdu: no match for this pdu");
665 static void get_pdu_fields(gpointer k, gpointer v, gpointer p) {
666 int hfid = *((int*) k);
667 gchar* name = (gchar*) v;
668 tmp_pdu_data* data = (tmp_pdu_data*) p;
672 mate_range* curr_range;
679 fis = (GPtrArray*) g_hash_table_lookup(data->interesting,(gpointer) hfid);
682 for (i = 0; i < fis->len; i++) {
683 fi = (field_info*) g_ptr_array_index(fis,i);
687 end = fi->start + fi->length;
689 dbg_print(dbg_pdu,5,dbg_facility,"get_pdu_fields: found field %i-%i",start,end);
691 for (j = 0; j < data->ranges->len; j++) {
693 curr_range = (mate_range*) g_ptr_array_index(data->ranges,j);
695 if (curr_range->end >= end && curr_range->start <= start) {
696 avp = new_avp_from_finfo(name, fi);
700 dbg_print(dbg_pdu,0,dbg_facility,"get_pdu_fields: got %s",s);
704 if (! insert_avp(data->pdu->avpl,avp) ) {
714 static mate_pdu* new_pdu(mate_cfg_pdu* cfg, guint32 framenum, field_info* proto, GHashTable* interesting) {
715 mate_pdu* pdu = g_mem_chunk_alloc(rd->mate_items);
719 mate_range* proto_range;
723 field_info* range_fi;
729 dbg_print (dbg_pdu,1,dbg_facility,"new_pdu: type=%s framenum=%i",cfg->name,framenum);
731 pdu->id = ++(cfg->last_id);
734 pdu->avpl = new_avpl(cfg->name);
736 pdu->frame = framenum;
737 pdu->next_in_frame = NULL;
738 pdu->rel_time = rd->now;
742 pdu->time_in_gop = -1.0;
745 pdu->is_start = FALSE;
746 pdu->is_stop = FALSE;
747 pdu->after_release = FALSE;
749 data.ranges = g_ptr_array_new();
751 data.interesting = interesting;
753 /* first we create the proto range */
754 proto_range = g_malloc(sizeof(mate_range));
755 proto_range->start = proto->start;
756 proto_range->end = proto->start + proto->length;
757 g_ptr_array_add(data.ranges,proto_range);
759 dbg_print(dbg_pdu,3,dbg_facility,"new_pdu: proto range %u-%u",proto_range->start,proto_range->end);
761 last_start = proto_range->start;
763 /* we move forward in the tranport */
764 for (i = cfg->transport_ranges->len; i--; ) {
765 hfid = *((int*)g_ptr_array_index(cfg->transport_ranges,i));
766 ptrs = (GPtrArray*) g_hash_table_lookup(interesting,GINT_TO_POINTER(hfid));
771 for (j=0; j < ptrs->len; j++) {
772 cfi = (field_info*) g_ptr_array_index(ptrs,j);
773 if (cfi->start < last_start && min_dist >= (last_start - cfi->start) ) {
775 min_dist = last_start - cfi->start;
780 range = g_malloc(sizeof(range));
781 range->start = range_fi->start;
782 range->end = range_fi->start + range_fi->length;
783 g_ptr_array_add(data.ranges,range);
785 last_start = range_fi->start;
787 dbg_print(dbg_pdu,3,dbg_facility,"new_pdu: transport(%i) range %i-%i",hfid,range->start,range->end);
789 /* we missed a range */
790 dbg_print(dbg_pdu,6,dbg_facility,"new_pdu: transport(%i) missed",hfid);
796 if (cfg->payload_ranges) {
798 first_end = proto_range->end;
800 for (i = 0 ; i < cfg->payload_ranges->len; i++) {
801 hfid = *((int*)g_ptr_array_index(cfg->payload_ranges,i));
802 ptrs = (GPtrArray*) g_hash_table_lookup(interesting,GINT_TO_POINTER(hfid));
807 for (j=0; j < ptrs->len; j++) {
808 cfi = (field_info*) g_ptr_array_index(ptrs,j);
809 curr_end = cfi->start + cfi->length;
810 if (curr_end > first_end && min_dist >= (curr_end - first_end) ) {
812 min_dist = curr_end - first_end;
817 range = g_malloc(sizeof(range));
818 range->start = range_fi->start;
819 range->end = range_fi->start + range_fi->length;
820 g_ptr_array_add(data.ranges,range);
822 last_start = range_fi->start;
824 dbg_print(dbg_pdu,3,dbg_facility,"new_pdu: payload(%i) range %i-%i",hfid,range->start,range->end);
826 /* we missed a range */
827 dbg_print(dbg_pdu,5,dbg_facility,"new_pdu: payload(%i) missed",hfid);
834 g_hash_table_foreach(cfg->hfids_attr,get_pdu_fields,&data);
836 apply_transforms(pdu->cfg->transforms,pdu->avpl);
838 g_ptr_array_free(data.ranges,TRUE);
844 extern void mate_analyze_frame(packet_info *pinfo, proto_tree* tree) {
849 AVPL* criterium_match;
851 mate_pdu* pdu = NULL;
852 mate_pdu* last = NULL;
854 rd->now = (float) nstime_to_sec(&pinfo->fd->rel_ts);
856 if ( tree->tree_data && tree->tree_data->interesting_hfids
857 && rd->highest_analyzed_frame < pinfo->fd->num ) {
858 for ( i = 0; i < mc->pducfglist->len; i++ ) {
860 cfg = g_ptr_array_index(mc->pducfglist,i);
862 dbg_print (dbg_pdu,4,dbg_facility,"mate_analyze_frame: tryning to extract: %s",cfg->name);
863 protos = (GPtrArray*) g_hash_table_lookup(tree->tree_data->interesting_hfids,(gpointer) cfg->hfid_proto);
868 for (j = 0; j < protos->len; j++) {
870 dbg_print (dbg_pdu,3,dbg_facility,"mate_analyze_frame: found matching proto, extracting: %s",cfg->name);
872 proto = (field_info*) g_ptr_array_index(protos,j);
873 pdu = new_pdu(cfg, pinfo->fd->num, proto, tree->tree_data->interesting_hfids);
875 if (cfg->criterium) {
876 criterium_match = new_avpl_from_match(cfg->criterium_match_mode,"",pdu->avpl,cfg->criterium,FALSE);
878 if (criterium_match) {
879 delete_avpl(criterium_match,FALSE);
882 if ( (criterium_match && cfg->criterium_accept_mode == REJECT_MODE )
883 || ( ! criterium_match && cfg->criterium_accept_mode == ACCEPT_MODE )) {
885 delete_avpl(pdu->avpl,TRUE);
886 g_mem_chunk_free(rd->mate_items,pdu);
895 if ( ! pdu->gop && cfg->drop_unassigned) {
896 delete_avpl(pdu->avpl,TRUE);
897 g_mem_chunk_free(rd->mate_items,pdu);
902 if ( cfg->discard ) {
903 delete_avpl(pdu->avpl,TRUE);
908 g_hash_table_insert(rd->frames,GINT_TO_POINTER(pinfo->fd->num),pdu);
911 last->next_in_frame = pdu;
917 if ( pdu && cfg->last_extracted ) break;
921 rd->highest_analyzed_frame = pinfo->fd->num;
925 extern mate_pdu* mate_get_pdus(guint32 framenum) {
928 return (mate_pdu*) g_hash_table_lookup(rd->frames,GUINT_TO_POINTER(framenum));