Add a inflateEnd() call to free up the stream in the re-init block.
[obnox/wireshark/wip.git] / epan / conversation.c
1 /* conversation.c
2  * Routines for building lists of packets that are part of a "conversation"
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <stdio.h>
30
31 #include <string.h>
32 #include <glib.h>
33 #include "packet.h"
34 #include "emem.h"
35 #include "conversation.h"
36
37 /*
38  * Hash table for conversations with no wildcards.
39  */
40 static GHashTable *conversation_hashtable_exact = NULL;
41
42 /*
43  * Hash table for conversations with one wildcard address.
44  */
45 static GHashTable *conversation_hashtable_no_addr2 = NULL;
46
47 /*
48  * Hash table for conversations with one wildcard port.
49  */
50 static GHashTable *conversation_hashtable_no_port2 = NULL;
51
52 /*
53  * Hash table for conversations with one wildcard address and port.
54  */
55 static GHashTable *conversation_hashtable_no_addr2_or_port2 = NULL;
56
57
58 #ifdef __NOT_USED__
59 typedef struct conversation_key {
60         struct conversation_key *next;
61         address addr1;
62         address addr2;
63         port_type ptype;
64         guint32 port1;
65         guint32 port2;
66 } conversation_key;
67 #endif
68 /*
69  * Linked list of conversation keys, so we can, before freeing them all,
70  * free the address data allocations associated with them.
71  */
72 static conversation_key *conversation_keys;
73
74 static guint32 new_index;
75
76 /*
77  * Protocol-specific data attached to a conversation_t structure - protocol
78  * index and opaque pointer.
79  */
80 typedef struct _conv_proto_data {
81         int     proto;
82         void    *proto_data;
83 } conv_proto_data;
84
85 /*
86  * Creates a new conversation with known endpoints based on a conversation
87  * created with the CONVERSATION_TEMPLATE option while keeping the
88  * conversation created with the CONVERSATION_TEMPLATE option so it can still
89  * match future connections.
90  *
91  * Passing a pointer to a conversation whose options mask does not include
92  * CONVERSATION_TEMPLATE or where the conversation's protocol type (ptype)
93  * indicates a non-connnection oriented protocol will return the conversation
94  * without changes.
95  *
96  * addr2 and port2 are used in the function if their respective conversation
97  * options bits are set (NO_ADDR2 and NO_PORT2).
98  */
99 static conversation_t *
100 conversation_create_from_template(conversation_t *conversation, address *addr2, guint32 port2)
101 {
102    /*
103     * Add a new conversation and keep the conversation template only if the
104     * CONVERSATION_TEMPLATE bit is set for a connection oriented protocol.
105     */
106    if(conversation->options & CONVERSATION_TEMPLATE &&
107       conversation->key_ptr->ptype != PT_UDP)
108    {
109       /*
110        * Set up a new options mask where the conversation template bit and the
111        * bits for absence of a second address and port pair have been removed.
112        */
113       conversation_t *new_conversation_from_template;
114       guint options = conversation->options & ~(CONVERSATION_TEMPLATE | NO_ADDR2 | NO_PORT2);
115
116       /*
117        * Are both the NO_ADDR2 and NO_PORT2 wildcards set in the options mask?
118        */
119       if(conversation->options & NO_ADDR2 &&
120          conversation->options & NO_PORT2)
121       {
122          /*
123           * The conversation template was created without knowledge of both
124           * the second address as well as the second port. Create a new
125           * conversation with new 2nd address and 2nd port.
126           */
127          new_conversation_from_template =
128             conversation_new(conversation->setup_frame,
129                              &conversation->key_ptr->addr1, addr2,
130                              conversation->key_ptr->ptype, conversation->key_ptr->port1,
131                              port2, options);
132       }
133       else if(conversation->options & NO_PORT2)
134       {
135          /*
136           * The conversation template was created without knowledge of port 2
137           * only. Create a new conversation with new 2nd port.
138           */
139          new_conversation_from_template =
140             conversation_new(conversation->setup_frame,
141                              &conversation->key_ptr->addr1, &conversation->key_ptr->addr2,
142                              conversation->key_ptr->ptype, conversation->key_ptr->port1,
143                              port2, options);
144       }
145       else if(conversation->options & NO_ADDR2)
146       {
147          /*
148           * The conversation template was created without knowledge of address
149           * 2. Create a new conversation with new 2nd address.
150           */
151          new_conversation_from_template =
152             conversation_new(conversation->setup_frame,
153                              &conversation->key_ptr->addr1, addr2,
154                              conversation->key_ptr->ptype, conversation->key_ptr->port1,
155                              conversation->key_ptr->port2, options);
156       }
157       else
158       {
159          /*
160           * The CONVERSATION_TEMPLATE bit was set, but no other bit that the
161           * CONVERSATION_TEMPLATE bit controls is active. Just return the old
162           * conversation.
163           */
164          return conversation;
165       }
166
167       /*
168        * Set the protocol dissector used for the template conversation as
169        * the handler of the new conversation as well.
170        */
171       new_conversation_from_template->dissector_handle = conversation->dissector_handle;
172
173       return new_conversation_from_template;
174    }
175    else
176    {
177       return conversation;
178    }
179 }
180
181 /*
182  * Compute the hash value for two given address/port pairs if the match
183  * is to be exact.
184  */
185 static guint
186 conversation_hash_exact(gconstpointer v)
187 {
188         const conversation_key *key = (const conversation_key *)v;
189         guint hash_val;
190
191         hash_val = 0;
192         ADD_ADDRESS_TO_HASH(hash_val, &key->addr1);
193         hash_val += key->port1;
194         ADD_ADDRESS_TO_HASH(hash_val, &key->addr2);
195         hash_val += key->port2;
196
197         return hash_val;
198 }
199
200 /*
201  * Compare two conversation keys for an exact match.
202  */
203 static gint
204 conversation_match_exact(gconstpointer v, gconstpointer w)
205 {
206         const conversation_key *v1 = (const conversation_key *)v;
207         const conversation_key *v2 = (const conversation_key *)w;
208
209         if (v1->ptype != v2->ptype)
210                 return 0;       /* different types of port */
211
212         /*
213          * Are the first and second port 1 values the same, the first and
214          * second port 2 values the same, the first and second address
215          * 1 values the same, and the first and second address 2 values
216          * the same?
217          */
218         if (v1->port1 == v2->port1 &&
219             v1->port2 == v2->port2 &&
220             ADDRESSES_EQUAL(&v1->addr1, &v2->addr1) &&
221             ADDRESSES_EQUAL(&v1->addr2, &v2->addr2)) {
222                 /*
223                  * Yes.  It's the same conversation, and the two
224                  * address/port pairs are going in the same direction.
225                  */
226                 return 1;
227         }
228
229         /*
230          * Is the first port 2 the same as the second port 1, the first
231          * port 1 the same as the second port 2, the first address 2
232          * the same as the second address 1, and the first address 1
233          * the same as the second address 2?
234          */
235         if (v1->port2 == v2->port1 &&
236             v1->port1 == v2->port2 &&
237             ADDRESSES_EQUAL(&v1->addr2, &v2->addr1) &&
238             ADDRESSES_EQUAL(&v1->addr1, &v2->addr2)) {
239                 /*
240                  * Yes.  It's the same conversation, and the two
241                  * address/port pairs are going in opposite directions.
242                  */
243                 return 1;
244         }
245
246         /*
247          * The addresses or the ports don't match.
248          */
249         return 0;
250 }
251
252 /*
253  * Compute the hash value for two given address/port pairs if the match
254  * has a wildcard address 2.
255  */
256 static guint
257 conversation_hash_no_addr2(gconstpointer v)
258 {
259         const conversation_key *key = (const conversation_key *)v;
260         guint hash_val;
261
262         hash_val = 0;
263         ADD_ADDRESS_TO_HASH(hash_val, &key->addr1);
264         hash_val += key->port1;
265         hash_val += key->port2;
266
267         return hash_val;
268 }
269
270 /*
271  * Compare two conversation keys, except for the address 2 value.
272  * We don't check both directions of the conversation - the routine
273  * doing the hash lookup has to do two searches, as the hash key
274  * will be different for the two directions.
275  */
276 static gint
277 conversation_match_no_addr2(gconstpointer v, gconstpointer w)
278 {
279         const conversation_key *v1 = (const conversation_key *)v;
280         const conversation_key *v2 = (const conversation_key *)w;
281
282         if (v1->ptype != v2->ptype)
283                 return 0;       /* different types of port */
284
285         /*
286          * Are the first and second port 1 values the same, the first and
287          * second port 2 valuess the same, and the first and second
288          * address 1 values the same?
289          */
290         if (v1->port1 == v2->port1 &&
291             v1->port2 == v2->port2 &&
292             ADDRESSES_EQUAL(&v1->addr1, &v2->addr1)) {
293                 /*
294                  * Yes.  It's the same conversation, and the two
295                  * address/port pairs are going in the same direction.
296                  */
297                 return 1;
298         }
299
300         /*
301          * The addresses or the ports don't match.
302          */
303         return 0;
304 }
305
306 /*
307  * Compute the hash value for two given address/port pairs if the match
308  * has a wildcard port 2.
309  */
310 static guint
311 conversation_hash_no_port2(gconstpointer v)
312 {
313         const conversation_key *key = (const conversation_key *)v;
314         guint hash_val;
315
316         hash_val = 0;
317         ADD_ADDRESS_TO_HASH(hash_val, &key->addr1);
318         hash_val += key->port1;
319         ADD_ADDRESS_TO_HASH(hash_val, &key->addr2);
320
321         return hash_val;
322 }
323
324 /*
325  * Compare two conversation keys, except for the port 2 value.
326  * We don't check both directions of the conversation - the routine
327  * doing the hash lookup has to do two searches, as the hash key
328  * will be different for the two directions.
329  */
330 static gint
331 conversation_match_no_port2(gconstpointer v, gconstpointer w)
332 {
333         const conversation_key *v1 = (const conversation_key *)v;
334         const conversation_key *v2 = (const conversation_key *)w;
335
336         if (v1->ptype != v2->ptype)
337                 return 0;       /* different types of port */
338
339         /*
340          * Are the first and second port 1 values the same, the first and
341          * second address 1 values the same, and the first and second
342          * address 2 values the same?
343          */
344         if (v1->port1 == v2->port1 &&
345             ADDRESSES_EQUAL(&v1->addr1, &v2->addr1) &&
346             ADDRESSES_EQUAL(&v1->addr2, &v2->addr2)) {
347                 /*
348                  * Yes.  It's the same conversation, and the two
349                  * address/port pairs are going in the same direction.
350                  */
351                 return 1;
352         }
353
354         /*
355          * The addresses or the ports don't match.
356          */
357         return 0;
358 }
359
360 /*
361  * Compute the hash value for two given address/port pairs if the match
362  * has a wildcard address 2 and port 2.
363  */
364 static guint
365 conversation_hash_no_addr2_or_port2(gconstpointer v)
366 {
367         const conversation_key *key = (const conversation_key *)v;
368         guint hash_val;
369
370         hash_val = 0;
371         ADD_ADDRESS_TO_HASH(hash_val, &key->addr1);
372         hash_val += key->port1;
373
374         return hash_val;
375 }
376
377 /*
378  * Compare the address 1 and port 1 in the two conversation keys.
379  * We don't check both directions of the conversation - the routine
380  * doing the hash lookup has to do two searches, as the hash key
381  * will be different for the two directions.
382  */
383 static gint
384 conversation_match_no_addr2_or_port2(gconstpointer v, gconstpointer w)
385 {
386         const conversation_key *v1 = (const conversation_key *)v;
387         const conversation_key *v2 = (const conversation_key *)w;
388
389         if (v1->ptype != v2->ptype)
390                 return 0;       /* different types of port */
391
392         /*
393          * Are the first and second port 1 values the same and the first
394          * and second address 1 values the same?
395          */
396         if (v1->port1 == v2->port1 &&
397             ADDRESSES_EQUAL(&v1->addr1, &v2->addr1)) {
398                 /*
399                  * Yes.  It's the same conversation, and the two
400                  * address/port pairs are going in the same direction.
401                  */
402                 return 1;
403         }
404
405         /*
406          * The addresses or the ports don't match.
407          */
408         return 0;
409 }
410
411 /*
412  * Initialize some variables every time a file is loaded or re-loaded.
413  * Destroy all existing conversations, and create a new hash table
414  * for the conversations in the new file.
415  */
416 void
417 conversation_init(void)
418 {
419         conversation_key *key;
420
421         /*
422          * Free the addresses associated with the conversation keys.
423          */
424         for (key = conversation_keys; key != NULL; key = key->next) {
425                 /*
426                  * Grr.  I guess the theory here is that freeing
427                  * something sure as heck modifies it, so you
428                  * want to ban attempts to free it, but, alas,
429                  * if we make the "data" field of an "address"
430                  * structure not a "const", the compiler whines if
431                  * we try to make it point into the data for a packet,
432                  * as that's a "const" array (and should be, as dissectors
433                  * shouldn't trash it).
434                  *
435                  * So we cast the complaint into oblivion, and rely on
436                  * the fact that these addresses are known to have had
437                  * their data mallocated, i.e. they don't point into,
438                  * say, the middle of the data for a packet.
439                  */
440                 g_free((gpointer)key->addr1.data);
441                 g_free((gpointer)key->addr2.data);
442         }
443         conversation_keys = NULL;
444         if (conversation_hashtable_exact != NULL)
445                 g_hash_table_destroy(conversation_hashtable_exact);
446         if (conversation_hashtable_no_addr2 != NULL)
447                 g_hash_table_destroy(conversation_hashtable_no_addr2);
448         if (conversation_hashtable_no_port2 != NULL)
449                 g_hash_table_destroy(conversation_hashtable_no_port2);
450         if (conversation_hashtable_no_addr2_or_port2 != NULL)
451                 g_hash_table_destroy(conversation_hashtable_no_addr2_or_port2);
452
453         /*
454          * Free up any space allocated for conversation protocol data
455          * areas.
456          *
457          * We can free the space, as the structures it contains are
458          * pointed to by conversation data structures that were freed
459          * above.
460          */
461         conversation_hashtable_exact =
462             g_hash_table_new(conversation_hash_exact,
463               conversation_match_exact);
464         conversation_hashtable_no_addr2 =
465             g_hash_table_new(conversation_hash_no_addr2,
466               conversation_match_no_addr2);
467         conversation_hashtable_no_port2 =
468             g_hash_table_new(conversation_hash_no_port2,
469               conversation_match_no_port2);
470         conversation_hashtable_no_addr2_or_port2 =
471             g_hash_table_new(conversation_hash_no_addr2_or_port2,
472               conversation_match_no_addr2_or_port2);
473
474         /*
475          * Start the conversation indices over at 0.
476          */
477         new_index = 0;
478 }
479
480 /*
481  * Given two address/port pairs for a packet, create a new conversation
482  * to contain packets between those address/port pairs.
483  *
484  * The options field is used to specify whether the address 2 value
485  * and/or port 2 value are not given and any value is acceptable
486  * when searching for this conversation.
487  */
488 conversation_t *
489 conversation_new(guint32 setup_frame, address *addr1, address *addr2, port_type ptype,
490     guint32 port1, guint32 port2, guint options)
491 {
492 /*
493         DISSECTOR_ASSERT(!(options | CONVERSATION_TEMPLATE) || ((options | (NO_ADDR2 | NO_PORT2 | NO_PORT2_FORCE))) &&
494                                 "A conversation template may not be constructed without wildcard options");
495 */
496         GHashTable* hashtable;
497         conversation_t *conversation;
498         conversation_t *tc;
499         conversation_key existing_key;
500         conversation_key *new_key;
501
502         if (options & NO_ADDR2) {
503                 if (options & (NO_PORT2|NO_PORT2_FORCE)) {
504                         hashtable = conversation_hashtable_no_addr2_or_port2;
505                 } else {
506                         hashtable = conversation_hashtable_no_addr2;
507                 }
508         } else {
509                 if (options & (NO_PORT2|NO_PORT2_FORCE)) {
510                         hashtable = conversation_hashtable_no_port2;
511                 } else {
512                         hashtable = conversation_hashtable_exact;
513                 }
514         }
515
516         existing_key.addr1 = *addr1;
517         existing_key.addr2 = *addr2;
518         existing_key.ptype = ptype;
519         existing_key.port1 = port1;
520         existing_key.port2 = port2;
521
522         conversation = g_hash_table_lookup(hashtable, &existing_key);
523         tc = conversation; /* Remember if lookup was successful */
524
525         new_key = se_alloc(sizeof(struct conversation_key));
526         new_key->next = conversation_keys;
527         conversation_keys = new_key;
528         COPY_ADDRESS(&new_key->addr1, addr1);
529         COPY_ADDRESS(&new_key->addr2, addr2);
530         new_key->ptype = ptype;
531         new_key->port1 = port1;
532         new_key->port2 = port2;
533
534         if (conversation) {
535                 for (; conversation->next; conversation = conversation->next)
536                         ;
537                 conversation->next = se_alloc(sizeof(conversation_t));
538                 conversation = conversation->next;
539         } else {
540                 conversation = se_alloc(sizeof(conversation_t));
541         }
542
543         conversation->next = NULL;
544         conversation->index = new_index;
545         conversation->setup_frame = setup_frame;
546         conversation->data_list = NULL;
547
548         /* clear dissector handle */
549         conversation->dissector_handle = NULL;
550
551         /* set the options and key pointer */
552         conversation->options = options;
553         conversation->key_ptr = new_key;
554
555         new_index++;
556
557         /* only insert a hash table entry if this
558          * is the first conversation with this key */
559         if (!tc)
560                 g_hash_table_insert(hashtable, new_key, conversation);
561
562         return conversation;
563 }
564
565 /*
566  * Set the port 2 value in a key.  Remove the original from table,
567  * update the options and port values, insert the updated key.
568  */
569 void
570 conversation_set_port2(conversation_t *conv, guint32 port)
571 {
572    DISSECTOR_ASSERT(!(conv->options & CONVERSATION_TEMPLATE) &&
573             "Use the conversation_create_from_template function when the CONVERSATION_TEMPLATE bit is set in the options mask");
574
575         /*
576          * If the port 2 value is not wildcarded, don't set it.
577          */
578         if ((!(conv->options & NO_PORT2)) || (conv->options & NO_PORT2_FORCE))
579                 return;
580
581         if (conv->options & NO_ADDR2) {
582                 g_hash_table_remove(conversation_hashtable_no_addr2_or_port2,
583                     conv->key_ptr);
584         } else {
585                 g_hash_table_remove(conversation_hashtable_no_port2,
586                     conv->key_ptr);
587         }
588         conv->options &= ~NO_PORT2;
589         conv->key_ptr->port2  = port;
590         if (conv->options & NO_ADDR2) {
591                 g_hash_table_insert(conversation_hashtable_no_addr2,
592                     conv->key_ptr, conv);
593         } else {
594                 g_hash_table_insert(conversation_hashtable_exact,
595                     conv->key_ptr, conv);
596         }
597 }
598
599 /*
600  * Set the address 2 value in a key.  Remove the original from
601  * table, update the options and port values, insert the updated key.
602  */
603 void
604 conversation_set_addr2(conversation_t *conv, address *addr)
605 {
606    DISSECTOR_ASSERT(!(conv->options & CONVERSATION_TEMPLATE) &&
607             "Use the conversation_create_from_template function when the CONVERSATION_TEMPLATE bit is set in the options mask");
608    
609         /*
610          * If the address 2 value is not wildcarded, don't set it.
611          */
612         if (!(conv->options & NO_ADDR2))
613                 return;
614
615         if (conv->options & NO_PORT2) {
616                 g_hash_table_remove(conversation_hashtable_no_addr2_or_port2,
617                     conv->key_ptr);
618         } else {
619                 g_hash_table_remove(conversation_hashtable_no_addr2,
620                     conv->key_ptr);
621         }
622         conv->options &= ~NO_ADDR2;
623         COPY_ADDRESS(&conv->key_ptr->addr2, addr);
624         if (conv->options & NO_PORT2) {
625                 g_hash_table_insert(conversation_hashtable_no_port2,
626                     conv->key_ptr, conv);
627         } else {
628                 g_hash_table_insert(conversation_hashtable_exact,
629                     conv->key_ptr, conv);
630         }
631 }
632
633 /*
634  * Search a particular hash table for a conversaton with the specified
635  * addr1, port1, addr2, and port2.
636  */
637 static conversation_t *
638 conversation_lookup_hashtable(GHashTable *hashtable, guint32 frame_num, address *addr1, address *addr2,
639     port_type ptype, guint32 port1, guint32 port2)
640 {
641         conversation_t* conversation;
642         conversation_t* match;
643         conversation_key key;
644
645         /*
646          * We don't make a copy of the address data, we just copy the
647          * pointer to it, as "key" disappears when we return.
648          */
649         key.addr1 = *addr1;
650         key.addr2 = *addr2;
651         key.ptype = ptype;
652         key.port1 = port1;
653         key.port2 = port2;
654
655         match = g_hash_table_lookup(hashtable, &key);
656
657         if (match) {
658                 for (conversation = match->next; conversation; conversation = conversation->next) {
659                         if ((conversation->setup_frame <= frame_num)
660                                 && (conversation->setup_frame > match->setup_frame))
661                                 match = conversation;
662                 }
663         }
664
665         return match;
666 }
667
668
669 /*
670  * Given two address/port pairs for a packet, search for a conversation
671  * containing packets between those address/port pairs.  Returns NULL if
672  * not found.
673  *
674  * We try to find the most exact match that we can, and then proceed to
675  * try wildcard matches on the "addr_b" and/or "port_b" argument if a more
676  * exact match failed.
677  *
678  * Either or both of the "addr_b" and "port_b" arguments may be specified as
679  * a wildcard by setting the NO_ADDR_B or NO_PORT_B flags in the "options"
680  * argument.  We do only wildcard matches on addresses and ports specified
681  * as wildcards.
682  *
683  * I.e.:
684  *
685  *      if neither "addr_b" nor "port_b" were specified as wildcards, we
686  *      do an exact match (addr_a/port_a and addr_b/port_b) and, if that
687  *      succeeds, we return a pointer to the matched conversation;
688  *
689  *      otherwise, if "port_b" wasn't specified as a wildcard, we try to
690  *      match any address 2 with the specified port 2 (addr_a/port_a and
691  *      {any}/addr_b) and, if that succeeds, we return a pointer to the
692  *      matched conversation;
693  *
694  *      otherwise, if "addr_b" wasn't specified as a wildcard, we try to
695  *      match any port 2 with the specified address 2 (addr_a/port_a and
696  *      addr_b/{any}) and, if that succeeds, we return a pointer to the
697  *      matched conversation;
698  *
699  *      otherwise, we try to match any address 2 and any port 2
700  *      (addr_a/port_a and {any}/{any}) and, if that succeeds, we return
701  *      a pointer to the matched conversation;
702  *
703  *      otherwise, we found no matching conversation, and return NULL.
704  */
705 conversation_t *
706 find_conversation(guint32 frame_num, address *addr_a, address *addr_b, port_type ptype,
707     guint32 port_a, guint32 port_b, guint options)
708 {
709    conversation_t *conversation;
710
711    /*
712     * First try an exact match, if we have two addresses and ports.
713     */
714    if (!(options & (NO_ADDR_B|NO_PORT_B))) {
715       /*
716        * Neither search address B nor search port B are wildcarded,
717        * start out with an exact match.
718        * Exact matches check both directions.
719        */
720       conversation =
721          conversation_lookup_hashtable(conversation_hashtable_exact,
722          frame_num, addr_a, addr_b, ptype,
723          port_a, port_b);
724       if ((conversation == NULL) && (addr_a->type == AT_FC)) {
725          /* In Fibre channel, OXID & RXID are never swapped as
726           * TCP/UDP ports are in TCP/IP.
727           */
728          conversation =
729             conversation_lookup_hashtable(conversation_hashtable_exact,
730             frame_num, addr_b, addr_a, ptype,
731             port_a, port_b);
732       }
733       if (conversation != NULL)
734          return conversation;
735    }
736
737    /*
738     * Well, that didn't find anything.  Try matches that wildcard
739     * one of the addresses, if we have two ports.
740     */
741    if (!(options & NO_PORT_B)) {
742       /*
743        * Search port B isn't wildcarded.
744        *
745        * First try looking for a conversation with the specified
746        * address A and port A as the first address and port, and
747        * with any address and the specified port B as the second
748        * address and port.
749        * ("addr_b" doesn't take part in this lookup.)
750        */
751       conversation =
752          conversation_lookup_hashtable(conversation_hashtable_no_addr2,
753          frame_num, addr_a, addr_b, ptype, port_a, port_b);
754       if ((conversation == NULL) && (addr_a->type == AT_FC)) {
755          /* In Fibre channel, OXID & RXID are never swapped as
756           * TCP/UDP ports are in TCP/IP.
757           */
758          conversation =
759             conversation_lookup_hashtable(conversation_hashtable_no_addr2,
760             frame_num, addr_b, addr_a, ptype,
761             port_a, port_b);
762       }
763       if (conversation != NULL) {
764          /*
765           * If search address B isn't wildcarded, and this is for a
766           * connection-oriented protocol, set the second address for this
767           * conversation to address B, as that's the address that matched the
768           * wildcarded second address for this conversation.
769           *
770           * (This assumes that, for all connection oriented protocols, the
771           * endpoints of a connection have only one address each, i.e. you
772           * don't get packets in a given direction coming from more than one
773           * address, unless the CONVERSATION_TEMPLATE option is set.)
774           */
775          if (!(conversation->options & NO_ADDR_B) && ptype != PT_UDP)
776          {
777             if(!(conversation->options & CONVERSATION_TEMPLATE))
778             {
779                conversation_set_addr2(conversation, addr_b);
780             }
781             else
782             {
783                conversation =
784                   conversation_create_from_template(conversation, addr_b, 0);
785             }
786          }
787          return conversation;
788       }
789
790       /*
791        * Well, that didn't find anything.
792        * If search address B was specified, try looking for a
793        * conversation with the specified address B and port B as
794        * the first address and port, and with any address and the
795        * specified port A as the second address and port (this
796        * packet may be going in the opposite direction from the
797        * first packet in the conversation).
798        * ("addr_a" doesn't take part in this lookup.)
799        */
800       if (!(options & NO_ADDR_B)) {
801          conversation =
802             conversation_lookup_hashtable(conversation_hashtable_no_addr2,
803             frame_num, addr_b, addr_a, ptype, port_b, port_a);
804          if (conversation != NULL) {
805             /*
806              * If this is for a connection-oriented
807              * protocol, set the second address for
808              * this conversation to address A, as
809              * that's the address that matched the
810              * wildcarded second address for this
811              * conversation.
812              */
813             if (ptype != PT_UDP) {
814                if(!(conversation->options & CONVERSATION_TEMPLATE))
815                {
816                   conversation_set_addr2(conversation, addr_a);
817                }
818                else
819                {
820                   conversation =
821                      conversation_create_from_template(conversation, addr_a, 0);
822                }
823             }
824             return conversation;
825          }
826       }
827    }
828
829    /*
830     * Well, that didn't find anything.  Try matches that wildcard
831     * one of the ports, if we have two addresses.
832    */
833    if (!(options & NO_ADDR_B)) {
834       /*
835        * Search address B isn't wildcarded.
836        *
837        * First try looking for a conversation with the specified
838        * address A and port A as the first address and port, and
839        * with the specified address B and any port as the second
840        * address and port.
841        * ("port_b" doesn't take part in this lookup.)
842        */
843       conversation =
844          conversation_lookup_hashtable(conversation_hashtable_no_port2,
845          frame_num, addr_a, addr_b, ptype, port_a, port_b);
846       if ((conversation == NULL) && (addr_a->type == AT_FC)) {
847          /* In Fibre channel, OXID & RXID are never swapped as
848           * TCP/UDP ports are in TCP/IP
849           */
850          conversation =
851             conversation_lookup_hashtable(conversation_hashtable_no_port2,
852             frame_num, addr_b, addr_a, ptype, port_a, port_b);
853       }
854       if (conversation != NULL) {
855          /*
856           * If search port B isn't wildcarded, and this is for a connection-
857           * oriented protocol, set the second port for this conversation to
858           * port B, as that's the port that matched the wildcarded second port
859           * for this conversation.
860           *
861           * (This assumes that, for all connection oriented protocols, the
862           * endpoints of a connection have only one port each, i.e. you don't
863           * get packets in a given direction coming from more than one port,
864           * unless the CONVERSATION_TEMPLATE option is set.)
865           */
866          if (!(conversation->options & NO_PORT_B) && ptype != PT_UDP)
867          {
868             if(!(conversation->options & CONVERSATION_TEMPLATE))
869             {
870                conversation_set_port2(conversation, port_b);
871             }
872             else
873             {
874                conversation =
875                   conversation_create_from_template(conversation, 0, port_b);
876             }
877          }
878          return conversation;
879       }
880
881       /*
882        * Well, that didn't find anything.
883        * If search port B was specified, try looking for a
884        * conversation with the specified address B and port B
885        * as the first address and port, and with the specified
886        * address A and any port as the second address and port
887        * (this packet may be going in the opposite direction
888        * from the first packet in the conversation).
889        * ("port_a" doesn't take part in this lookup.)
890        */
891       if (!(options & NO_PORT_B)) {
892          conversation =
893             conversation_lookup_hashtable(conversation_hashtable_no_port2,
894             frame_num, addr_b, addr_a, ptype, port_b, port_a);
895          if (conversation != NULL) {
896             /*
897              * If this is for a connection-oriented
898              * protocol, set the second port for
899              * this conversation to port A, as
900              * that's the address that matched the
901              * wildcarded second address for this
902              * conversation.
903              */
904             if (ptype != PT_UDP)
905             {
906                if(!(conversation->options & CONVERSATION_TEMPLATE))
907                {
908                   conversation_set_port2(conversation, port_a);
909                }
910                else
911                {
912                   conversation =
913                      conversation_create_from_template(conversation, 0, port_a);
914                }
915             }
916             return conversation;
917          }
918       }
919    }
920
921    /*
922     * Well, that didn't find anything.  Try matches that wildcard
923     * one address/port pair.
924     *
925     * First try looking for a conversation with the specified address A
926     * and port A as the first address and port.
927     * (Neither "addr_b" nor "port_b" take part in this lookup.)
928     */
929    conversation =
930       conversation_lookup_hashtable(conversation_hashtable_no_addr2_or_port2,
931       frame_num, addr_a, addr_b, ptype, port_a, port_b);
932    if (conversation != NULL) {
933       /*
934        * If this is for a connection-oriented protocol:
935        *
936        * if search address B isn't wildcarded, set the
937        * second address for this conversation to address
938        * B, as that's the address that matched the
939        * wildcarded second address for this conversation;
940        *
941        * if search port B isn't wildcarded, set the
942        * second port for this conversation to port B,
943        * as that's the port that matched the wildcarded
944        * second port for this conversation.
945        */
946       if (ptype != PT_UDP)
947       {
948          if(!(conversation->options & CONVERSATION_TEMPLATE))
949          {
950             if (!(conversation->options & NO_ADDR_B))
951                conversation_set_addr2(conversation, addr_b);
952             if (!(conversation->options & NO_PORT_B))
953                conversation_set_port2(conversation, port_b);
954          }
955          else
956          {
957             conversation =
958                conversation_create_from_template(conversation, addr_b, port_b);
959          }
960       }
961       return conversation;
962    }
963
964    /*
965     * Well, that didn't find anything.
966     * If search address and port B were specified, try looking for a
967     * conversation with the specified address B and port B as the
968     * first address and port, and with any second address and port
969     * (this packet may be going in the opposite direction from the
970     * first packet in the conversation).
971     * (Neither "addr_a" nor "port_a" take part in this lookup.)
972     */
973    if (addr_a->type == AT_FC)
974       conversation =
975       conversation_lookup_hashtable(conversation_hashtable_no_addr2_or_port2,
976       frame_num, addr_b, addr_a, ptype, port_a, port_b);
977    else 
978       conversation =
979       conversation_lookup_hashtable(conversation_hashtable_no_addr2_or_port2,
980       frame_num, addr_b, addr_a, ptype, port_b, port_a);
981    if (conversation != NULL) {
982       /*
983        * If this is for a connection-oriented protocol, set the
984        * second address for this conversation to address A, as
985        * that's the address that matched the wildcarded second
986        * address for this conversation, and set the second port
987        * for this conversation to port A, as that's the port
988        * that matched the wildcarded second port for this
989        * conversation.
990        */
991       if (ptype != PT_UDP)
992       {
993          if(!(conversation->options & CONVERSATION_TEMPLATE))
994          {
995             conversation_set_addr2(conversation, addr_a);
996             conversation_set_port2(conversation, port_a);
997          }
998          else
999          {
1000             conversation = conversation_create_from_template(conversation, addr_a, port_a);
1001          }
1002       }
1003       return conversation;
1004    }
1005
1006    /*
1007     * We found no conversation.
1008     */
1009    return NULL;
1010 }
1011
1012 static gint
1013 p_compare(gconstpointer a, gconstpointer b)
1014 {
1015         const conv_proto_data *ap = (const conv_proto_data *)a;
1016         const conv_proto_data *bp = (const conv_proto_data *)b;
1017
1018         if (ap->proto > bp->proto)
1019                 return 1;
1020         else if (ap->proto == bp->proto)
1021                 return 0;
1022         else
1023                 return -1;
1024 }
1025
1026 void
1027 conversation_add_proto_data(conversation_t *conv, int proto, void *proto_data)
1028 {
1029         conv_proto_data *p1 = se_alloc(sizeof(conv_proto_data));
1030
1031         p1->proto = proto;
1032         p1->proto_data = proto_data;
1033
1034         /* Add it to the list of items for this conversation. */
1035
1036         conv->data_list = g_slist_insert_sorted(conv->data_list, (gpointer *)p1,
1037             p_compare);
1038 }
1039
1040 void *
1041 conversation_get_proto_data(conversation_t *conv, int proto)
1042 {
1043         conv_proto_data temp, *p1;
1044         GSList *item;
1045
1046         temp.proto = proto;
1047         temp.proto_data = NULL;
1048
1049         item = g_slist_find_custom(conv->data_list, (gpointer *)&temp,
1050             p_compare);
1051
1052         if (item != NULL) {
1053                 p1 = (conv_proto_data *)item->data;
1054                 return p1->proto_data;
1055         }
1056
1057         return NULL;
1058 }
1059
1060 void
1061 conversation_delete_proto_data(conversation_t *conv, int proto)
1062 {
1063         conv_proto_data temp;
1064         GSList *item;
1065
1066         temp.proto = proto;
1067         temp.proto_data = NULL;
1068
1069         item = g_slist_find_custom(conv->data_list, (gpointer *)&temp,
1070             p_compare);
1071
1072         while(item){
1073                 conv->data_list = g_slist_remove(conv->data_list, item->data);
1074                 item=item->next;
1075         }
1076 }
1077
1078 void
1079 conversation_set_dissector(conversation_t *conversation, dissector_handle_t handle)
1080 {
1081         conversation->dissector_handle = handle;
1082 }
1083
1084 /*
1085  * Given two address/port pairs for a packet, search for a matching
1086  * conversation and, if found and it has a conversation dissector,
1087  * call that dissector and return TRUE, otherwise return FALSE.
1088  *
1089  * This helper uses call_dissector_only which will NOT call the default
1090  * "data" dissector if the packet was rejected.
1091  * Our caller is responsible to call the data dissector explicitely in case 
1092  * this function returns FALSE.
1093  */
1094 gboolean
1095 try_conversation_dissector(address *addr_a, address *addr_b, port_type ptype,
1096     guint32 port_a, guint32 port_b, tvbuff_t *tvb, packet_info *pinfo,
1097     proto_tree *tree)
1098 {
1099         conversation_t *conversation;
1100
1101         conversation = find_conversation(pinfo->fd->num, addr_a, addr_b, ptype, port_a,
1102             port_b, 0);
1103
1104         if (conversation != NULL) {
1105                 int ret;
1106                 if (conversation->dissector_handle == NULL)
1107                         return FALSE;
1108                 ret=call_dissector_only(conversation->dissector_handle, tvb, pinfo,
1109                     tree);
1110                 if(!ret) {
1111                         /* this packet was rejected by the dissector
1112                          * so return FALSE in case our caller wants
1113                          * to do some cleaning up.
1114                          */
1115                         return FALSE;
1116                 }
1117                 return TRUE;
1118         }
1119         return FALSE;
1120 }