Replace ep_address_to_str with address_to_str.
[metze/wireshark/wip.git] / epan / conversation.c
1 /* conversation.c
2  * Routines for building lists of packets that are part of a "conversation"
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22
23 #include "config.h"
24
25 #include <stdio.h>
26
27 #include <string.h>
28 #include <glib.h>
29 #include "packet.h"
30 #include "emem.h"
31 #include "to_str.h"
32 #include "conversation.h"
33
34 /* define DEBUG_CONVERSATION for pretty debug printing */
35 /* #define DEBUG_CONVERSATION */
36 #include "conversation_debug.h"
37
38 #ifdef DEBUG_CONVERSATION
39 int _debug_conversation_indent = 0;
40 #endif
41
42 /*
43  * Hash table for conversations with no wildcards.
44  */
45 static GHashTable *conversation_hashtable_exact = NULL;
46
47 /*
48  * Hash table for conversations with one wildcard address.
49  */
50 static GHashTable *conversation_hashtable_no_addr2 = NULL;
51
52 /*
53  * Hash table for conversations with one wildcard port.
54  */
55 static GHashTable *conversation_hashtable_no_port2 = NULL;
56
57 /*
58  * Hash table for conversations with one wildcard address and port.
59  */
60 static GHashTable *conversation_hashtable_no_addr2_or_port2 = NULL;
61
62
63 #ifdef __NOT_USED__
64 typedef struct conversation_key {
65         struct conversation_key *next;
66         address addr1;
67         address addr2;
68         port_type ptype;
69         guint32 port1;
70         guint32 port2;
71 } conversation_key;
72 #endif
73 /*
74  * Linked list of conversation keys, so we can, before freeing them all,
75  * free the address data allocations associated with them.
76  */
77 static conversation_key *conversation_keys;
78
79 static guint32 new_index;
80
81 /*
82  * Protocol-specific data attached to a conversation_t structure - protocol
83  * index and opaque pointer.
84  */
85 typedef struct _conv_proto_data {
86         int     proto;
87         void    *proto_data;
88 } conv_proto_data;
89
90 /*
91  * Creates a new conversation with known endpoints based on a conversation
92  * created with the CONVERSATION_TEMPLATE option while keeping the
93  * conversation created with the CONVERSATION_TEMPLATE option so it can still
94  * match future connections.
95  *
96  * Passing a pointer to a conversation whose options mask does not include
97  * CONVERSATION_TEMPLATE or where the conversation's protocol type (ptype)
98  * indicates a non-connnection oriented protocol will return the conversation
99  * without changes.
100  *
101  * addr2 and port2 are used in the function if their respective conversation
102  * options bits are set (NO_ADDR2 and NO_PORT2).
103  */
104 static conversation_t *
105 conversation_create_from_template(conversation_t *conversation, const address *addr2, const guint32 port2)
106 {
107    /*
108     * Add a new conversation and keep the conversation template only if the
109     * CONVERSATION_TEMPLATE bit is set for a connection oriented protocol.
110     */
111    if(conversation->options & CONVERSATION_TEMPLATE &&
112       conversation->key_ptr->ptype != PT_UDP)
113    {
114       /*
115        * Set up a new options mask where the conversation template bit and the
116        * bits for absence of a second address and port pair have been removed.
117        */
118       conversation_t *new_conversation_from_template;
119       guint options = conversation->options & ~(CONVERSATION_TEMPLATE | NO_ADDR2 | NO_PORT2);
120
121       /*
122        * Are both the NO_ADDR2 and NO_PORT2 wildcards set in the options mask?
123        */
124       if(conversation->options & NO_ADDR2 &&
125          conversation->options & NO_PORT2)
126       {
127          /*
128           * The conversation template was created without knowledge of both
129           * the second address as well as the second port. Create a new
130           * conversation with new 2nd address and 2nd port.
131           */
132          new_conversation_from_template =
133             conversation_new(conversation->setup_frame,
134                              &conversation->key_ptr->addr1, addr2,
135                              conversation->key_ptr->ptype, conversation->key_ptr->port1,
136                              port2, options);
137       }
138       else if(conversation->options & NO_PORT2)
139       {
140          /*
141           * The conversation template was created without knowledge of port 2
142           * only. Create a new conversation with new 2nd port.
143           */
144          new_conversation_from_template =
145             conversation_new(conversation->setup_frame,
146                              &conversation->key_ptr->addr1, &conversation->key_ptr->addr2,
147                              conversation->key_ptr->ptype, conversation->key_ptr->port1,
148                              port2, options);
149       }
150       else if(conversation->options & NO_ADDR2)
151       {
152          /*
153           * The conversation template was created without knowledge of address
154           * 2. Create a new conversation with new 2nd address.
155           */
156          new_conversation_from_template =
157             conversation_new(conversation->setup_frame,
158                              &conversation->key_ptr->addr1, addr2,
159                              conversation->key_ptr->ptype, conversation->key_ptr->port1,
160                              conversation->key_ptr->port2, options);
161       }
162       else
163       {
164          /*
165           * The CONVERSATION_TEMPLATE bit was set, but no other bit that the
166           * CONVERSATION_TEMPLATE bit controls is active. Just return the old
167           * conversation.
168           */
169          return conversation;
170       }
171
172       /*
173        * Set the protocol dissector used for the template conversation as
174        * the handler of the new conversation as well.
175        */
176       new_conversation_from_template->dissector_handle = conversation->dissector_handle;
177
178       return new_conversation_from_template;
179    }
180    else
181    {
182       return conversation;
183    }
184 }
185
186 /*
187  * Compute the hash value for two given address/port pairs if the match
188  * is to be exact.
189  */
190 /* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx#existing
191  * One-at-a-Time hash
192  */
193 static guint
194 conversation_hash_exact(gconstpointer v)
195 {
196         const conversation_key *key = (const conversation_key *)v;
197         guint hash_val;
198         address tmp_addr;
199
200         hash_val = 0;
201         tmp_addr.len  = 4;
202
203         ADD_ADDRESS_TO_HASH(hash_val, &key->addr1);
204
205         tmp_addr.data = &key->port1;
206         ADD_ADDRESS_TO_HASH(hash_val, &tmp_addr);
207
208         ADD_ADDRESS_TO_HASH(hash_val, &key->addr2);
209
210         tmp_addr.data = &key->port2;
211         ADD_ADDRESS_TO_HASH(hash_val, &tmp_addr);
212
213         hash_val += ( hash_val << 3 );
214         hash_val ^= ( hash_val >> 11 );
215         hash_val += ( hash_val << 15 );
216
217         return hash_val;
218 }
219
220 /*
221  * Compare two conversation keys for an exact match.
222  */
223 static gint
224 conversation_match_exact(gconstpointer v, gconstpointer w)
225 {
226         const conversation_key *v1 = (const conversation_key *)v;
227         const conversation_key *v2 = (const conversation_key *)w;
228
229         if (v1->ptype != v2->ptype)
230                 return 0;       /* different types of port */
231
232         /*
233          * Are the first and second port 1 values the same, the first and
234          * second port 2 values the same, the first and second address
235          * 1 values the same, and the first and second address 2 values
236          * the same?
237          */
238         if (v1->port1 == v2->port1 &&
239             v1->port2 == v2->port2 &&
240             ADDRESSES_EQUAL(&v1->addr1, &v2->addr1) &&
241             ADDRESSES_EQUAL(&v1->addr2, &v2->addr2)) {
242                 /*
243                  * Yes.  It's the same conversation, and the two
244                  * address/port pairs are going in the same direction.
245                  */
246                 return 1;
247         }
248
249         /*
250          * Is the first port 2 the same as the second port 1, the first
251          * port 1 the same as the second port 2, the first address 2
252          * the same as the second address 1, and the first address 1
253          * the same as the second address 2?
254          */
255         if (v1->port2 == v2->port1 &&
256             v1->port1 == v2->port2 &&
257             ADDRESSES_EQUAL(&v1->addr2, &v2->addr1) &&
258             ADDRESSES_EQUAL(&v1->addr1, &v2->addr2)) {
259                 /*
260                  * Yes.  It's the same conversation, and the two
261                  * address/port pairs are going in opposite directions.
262                  */
263                 return 1;
264         }
265
266         /*
267          * The addresses or the ports don't match.
268          */
269         return 0;
270 }
271
272 /*
273  * Compute the hash value for two given address/port pairs if the match
274  * has a wildcard address 2.
275  */
276 static guint
277 conversation_hash_no_addr2(gconstpointer v)
278 {
279         const conversation_key *key = (const conversation_key *)v;
280         guint hash_val;
281         address tmp_addr;
282
283         hash_val = 0;
284         tmp_addr.len  = 4;
285
286         ADD_ADDRESS_TO_HASH(hash_val, &key->addr1);
287
288         tmp_addr.data = &key->port1;
289         ADD_ADDRESS_TO_HASH(hash_val, &tmp_addr);
290
291         tmp_addr.data = &key->port2;
292         ADD_ADDRESS_TO_HASH(hash_val, &tmp_addr);
293
294         hash_val += ( hash_val << 3 );
295         hash_val ^= ( hash_val >> 11 );
296         hash_val += ( hash_val << 15 );
297
298         return hash_val;
299 }
300
301 /*
302  * Compare two conversation keys, except for the address 2 value.
303  * We don't check both directions of the conversation - the routine
304  * doing the hash lookup has to do two searches, as the hash key
305  * will be different for the two directions.
306  */
307 static gint
308 conversation_match_no_addr2(gconstpointer v, gconstpointer w)
309 {
310         const conversation_key *v1 = (const conversation_key *)v;
311         const conversation_key *v2 = (const conversation_key *)w;
312
313         if (v1->ptype != v2->ptype)
314                 return 0;       /* different types of port */
315
316         /*
317          * Are the first and second port 1 values the same, the first and
318          * second port 2 valuess the same, and the first and second
319          * address 1 values the same?
320          */
321         if (v1->port1 == v2->port1 &&
322             v1->port2 == v2->port2 &&
323             ADDRESSES_EQUAL(&v1->addr1, &v2->addr1)) {
324                 /*
325                  * Yes.  It's the same conversation, and the two
326                  * address/port pairs are going in the same direction.
327                  */
328                 return 1;
329         }
330
331         /*
332          * The addresses or the ports don't match.
333          */
334         return 0;
335 }
336
337 /*
338  * Compute the hash value for two given address/port pairs if the match
339  * has a wildcard port 2.
340  */
341 static guint
342 conversation_hash_no_port2(gconstpointer v)
343 {
344         const conversation_key *key = (const conversation_key *)v;
345         guint hash_val;
346         address tmp_addr;
347
348         hash_val = 0;
349         tmp_addr.len  = 4;
350
351         ADD_ADDRESS_TO_HASH(hash_val, &key->addr1);
352
353         tmp_addr.data = &key->port1;
354         ADD_ADDRESS_TO_HASH(hash_val, &tmp_addr);
355
356         ADD_ADDRESS_TO_HASH(hash_val, &key->addr2);
357
358         hash_val += ( hash_val << 3 );
359         hash_val ^= ( hash_val >> 11 );
360         hash_val += ( hash_val << 15 );
361
362         return hash_val;
363 }
364
365 /*
366  * Compare two conversation keys, except for the port 2 value.
367  * We don't check both directions of the conversation - the routine
368  * doing the hash lookup has to do two searches, as the hash key
369  * will be different for the two directions.
370  */
371 static gint
372 conversation_match_no_port2(gconstpointer v, gconstpointer w)
373 {
374         const conversation_key *v1 = (const conversation_key *)v;
375         const conversation_key *v2 = (const conversation_key *)w;
376
377         if (v1->ptype != v2->ptype)
378                 return 0;       /* different types of port */
379
380         /*
381          * Are the first and second port 1 values the same, the first and
382          * second address 1 values the same, and the first and second
383          * address 2 values the same?
384          */
385         if (v1->port1 == v2->port1 &&
386             ADDRESSES_EQUAL(&v1->addr1, &v2->addr1) &&
387             ADDRESSES_EQUAL(&v1->addr2, &v2->addr2)) {
388                 /*
389                  * Yes.  It's the same conversation, and the two
390                  * address/port pairs are going in the same direction.
391                  */
392                 return 1;
393         }
394
395         /*
396          * The addresses or the ports don't match.
397          */
398         return 0;
399 }
400
401 /*
402  * Compute the hash value for two given address/port pairs if the match
403  * has a wildcard address 2 and port 2.
404  */
405 static guint
406 conversation_hash_no_addr2_or_port2(gconstpointer v)
407 {
408         const conversation_key *key = (const conversation_key *)v;
409         guint hash_val;
410         address tmp_addr;
411
412         hash_val = 0;
413         tmp_addr.len  = 4;
414
415         ADD_ADDRESS_TO_HASH(hash_val, &key->addr1);
416
417         tmp_addr.data = &key->port1;
418         ADD_ADDRESS_TO_HASH(hash_val, &tmp_addr);
419
420         hash_val += ( hash_val << 3 );
421         hash_val ^= ( hash_val >> 11 );
422         hash_val += ( hash_val << 15 );
423
424         return hash_val;
425 }
426
427 /*
428  * Compare the address 1 and port 1 in the two conversation keys.
429  * We don't check both directions of the conversation - the routine
430  * doing the hash lookup has to do two searches, as the hash key
431  * will be different for the two directions.
432  */
433 static gint
434 conversation_match_no_addr2_or_port2(gconstpointer v, gconstpointer w)
435 {
436         const conversation_key *v1 = (const conversation_key *)v;
437         const conversation_key *v2 = (const conversation_key *)w;
438
439         if (v1->ptype != v2->ptype)
440                 return 0;       /* different types of port */
441
442         /*
443          * Are the first and second port 1 values the same and the first
444          * and second address 1 values the same?
445          */
446         if (v1->port1 == v2->port1 &&
447             ADDRESSES_EQUAL(&v1->addr1, &v2->addr1)) {
448                 /*
449                  * Yes.  It's the same conversation, and the two
450                  * address/port pairs are going in the same direction.
451                  */
452                 return 1;
453         }
454
455         /*
456          * The addresses or the ports don't match.
457          */
458         return 0;
459 }
460
461 /*
462  * Free the proto_data.  The conversation itself is se_allocated.
463  */
464 static void
465 free_data_list(gpointer value)
466 {
467         conversation_t *conv = (conversation_t *)value;
468
469         /* TODO: se_slist? */
470         g_slist_free(conv->data_list);
471
472         /* Not really necessary, but... */
473         conv->data_list = NULL;
474
475 }
476
477 /*
478  * Destroy all existing conversations
479  */
480 void
481 conversation_cleanup(void)
482 {
483         /*  Clean up the hash tables, but only after freeing any proto_data
484          *  that may be hanging off the conversations.
485          *  The conversation keys are se_ allocated so we don't have to clean them up.
486          */
487         conversation_keys = NULL;
488         if (conversation_hashtable_exact != NULL) {
489                 g_hash_table_destroy(conversation_hashtable_exact);
490         }
491         if (conversation_hashtable_no_addr2 != NULL) {
492                 g_hash_table_destroy(conversation_hashtable_no_addr2);
493         }
494         if (conversation_hashtable_no_port2 != NULL) {
495                 g_hash_table_destroy(conversation_hashtable_no_port2);
496         }
497         if (conversation_hashtable_no_addr2_or_port2 != NULL) {
498                 g_hash_table_destroy(conversation_hashtable_no_addr2_or_port2);
499         }
500
501         conversation_hashtable_exact = NULL;
502         conversation_hashtable_no_addr2 = NULL;
503         conversation_hashtable_no_port2 = NULL;
504         conversation_hashtable_no_addr2_or_port2 = NULL;
505 }
506
507 /*
508  * Initialize some variables every time a file is loaded or re-loaded.
509  * Create a new hash table for the conversations in the new file.
510  */
511 void
512 conversation_init(void)
513 {
514         /*
515          * Free up any space allocated for conversation protocol data
516          * areas.
517          *
518          * We can free the space, as the structures it contains are
519          * pointed to by conversation data structures that were freed
520          * above.
521          */
522         conversation_hashtable_exact =
523             g_hash_table_new_full(conversation_hash_exact,
524               conversation_match_exact, NULL, free_data_list);
525         conversation_hashtable_no_addr2 =
526             g_hash_table_new_full(conversation_hash_no_addr2,
527               conversation_match_no_addr2, NULL, free_data_list);
528         conversation_hashtable_no_port2 =
529             g_hash_table_new_full(conversation_hash_no_port2,
530               conversation_match_no_port2, NULL, free_data_list);
531         conversation_hashtable_no_addr2_or_port2 =
532             g_hash_table_new_full(conversation_hash_no_addr2_or_port2,
533               conversation_match_no_addr2_or_port2, NULL, free_data_list);
534
535         /*
536          * Start the conversation indices over at 0.
537          */
538         new_index = 0;
539 }
540
541 /*
542  * Does the right thing when inserting into one of the conversation hash tables,
543  * taking into account ordering and hash chains and all that good stuff.
544  *
545  * Mostly adapted from the old conversation_new().
546  */
547 static void
548 conversation_insert_into_hashtable(GHashTable *hashtable, conversation_t *conv)
549 {
550         conversation_t *chain_head, *chain_tail, *cur, *prev;
551
552         chain_head = (conversation_t *)g_hash_table_lookup(hashtable, conv->key_ptr);
553
554         if (NULL==chain_head) {
555                 /* New entry */
556                 conv->next = NULL;
557                 conv->last = conv;
558                 g_hash_table_insert(hashtable, conv->key_ptr, conv);
559                 DPRINT(("created a new conversation chain"));
560         }
561         else {
562                 /* There's an existing chain for this key */
563                 DPRINT(("there's an existing conversation chain"));
564
565                 chain_tail = chain_head->last;
566
567                 if(conv->setup_frame >= chain_tail->setup_frame) {
568                         /* This convo belongs at the end of the chain */
569                         conv->next = NULL;
570                         conv->last = NULL;
571                         chain_tail->next = conv;
572                         chain_head->last = conv;
573                 }
574                 else {
575                         /* Loop through the chain to find the right spot */
576                         cur = chain_head;
577                         prev = NULL;
578
579                         for (; (conv->setup_frame > cur->setup_frame) && cur->next; prev=cur, cur=cur->next)
580                                 ;
581
582                         if (NULL==prev) {
583                                 /* Changing the head of the chain */
584                                 conv->next = chain_head;
585                                 conv->last = chain_tail;
586                                 chain_head->last = NULL;
587                                 g_hash_table_insert(hashtable, conv->key_ptr, conv);
588                         }
589                         else {
590                                 /* Inserting into the middle of the chain */
591                                 conv->next = cur;
592                                 conv->last = NULL;
593                                 prev->next = conv;
594                         }
595                 }
596         }
597 }
598
599 /*
600  * Does the right thing when removing from one of the conversation hash tables,
601  * taking into account ordering and hash chains and all that good stuff.
602  */
603 static void
604 conversation_remove_from_hashtable(GHashTable *hashtable, conversation_t *conv)
605 {
606         conversation_t *chain_head, *cur, *prev;
607
608         chain_head = (conversation_t *)g_hash_table_lookup(hashtable, conv->key_ptr);
609
610         if (conv == chain_head) {
611                 /* We are currently the front of the chain */
612                 if (NULL == conv->next) {
613                         /* We are the only conversation in the chain, no need to
614                          * update next pointer, but do not call
615                          * g_hash_table_remove() either because the conv data
616                          * will be re-inserted. The memory is released when
617                          * conversion_cleanup() is called. */
618                         g_hash_table_steal(hashtable, conv->key_ptr);
619                 }
620                 else {
621                         /* Update the head of the chain */
622                         chain_head = conv->next;
623                         chain_head->last = conv->last;
624
625                         if (conv->latest_found == conv)
626                                 chain_head->latest_found = NULL;
627                         else
628                                 chain_head->latest_found = conv->latest_found;
629
630                         g_hash_table_insert(hashtable, chain_head->key_ptr, chain_head);
631                 }
632         }
633         else {
634                 /* We are not the front of the chain. Loop through to find us.
635                  * Start loop at chain_head->next rather than chain_head because
636                  * we already know we're not at the head. */
637                 cur = chain_head->next;
638                 prev = chain_head;
639
640                 for (; (cur != conv) && cur->next; prev=cur, cur=cur->next)
641                         ;
642
643                 if (cur != conv) {
644                         /* XXX: Conversation not found. Wrong hashtable? */
645                         return;
646                 }
647
648                 prev->next = conv->next;
649
650                 if (NULL == conv->next) {
651                         /* We're at the very end of the list. */
652                         chain_head->last = prev;
653                 }
654
655                 if (chain_head->latest_found == conv)
656                         chain_head->latest_found = prev;
657         }
658 }
659
660 /*
661  * Given two address/port pairs for a packet, create a new conversation
662  * to contain packets between those address/port pairs.
663  *
664  * The options field is used to specify whether the address 2 value
665  * and/or port 2 value are not given and any value is acceptable
666  * when searching for this conversation.
667  */
668 conversation_t *
669 conversation_new(const guint32 setup_frame, const address *addr1, const address *addr2, const port_type ptype,
670     const guint32 port1, const guint32 port2, const guint options)
671 {
672 /*
673         DISSECTOR_ASSERT(!(options | CONVERSATION_TEMPLATE) || ((options | (NO_ADDR2 | NO_PORT2 | NO_PORT2_FORCE))) &&
674                                 "A conversation template may not be constructed without wildcard options");
675 */
676         GHashTable* hashtable;
677         conversation_t *conversation=NULL;
678         conversation_key *new_key;
679
680         DPRINT(("creating conversation for frame #%d: %s:%d -> %s:%d (ptype=%d)",
681                     setup_frame, address_to_str(wmem_packet_scope(), addr1), port1,
682                     address_to_str(wmem_packet_scope(), addr2), port2, ptype));
683
684         if (options & NO_ADDR2) {
685                 if (options & (NO_PORT2|NO_PORT2_FORCE)) {
686                         hashtable = conversation_hashtable_no_addr2_or_port2;
687                 } else {
688                         hashtable = conversation_hashtable_no_addr2;
689                 }
690         } else {
691                 if (options & (NO_PORT2|NO_PORT2_FORCE)) {
692                         hashtable = conversation_hashtable_no_port2;
693                 } else {
694                         hashtable = conversation_hashtable_exact;
695                 }
696         }
697
698         new_key = se_new(struct conversation_key);
699         new_key->next = conversation_keys;
700         conversation_keys = new_key;
701         SE_COPY_ADDRESS(&new_key->addr1, addr1);
702         SE_COPY_ADDRESS(&new_key->addr2, addr2);
703         new_key->ptype = ptype;
704         new_key->port1 = port1;
705         new_key->port2 = port2;
706
707         conversation = se_new(conversation_t);
708         memset(conversation, 0, sizeof(conversation_t));
709
710         conversation->index = new_index;
711         conversation->setup_frame = conversation->last_frame = setup_frame;
712         conversation->data_list = NULL;
713
714         /* clear dissector handle */
715         conversation->dissector_handle = NULL;
716
717         /* set the options and key pointer */
718         conversation->options = options;
719         conversation->key_ptr = new_key;
720
721         new_index++;
722
723         DINDENT();
724         conversation_insert_into_hashtable(hashtable, conversation);
725         DENDENT();
726
727         return conversation;
728 }
729
730 /*
731  * Set the port 2 value in a key.  Remove the original from table,
732  * update the options and port values, insert the updated key.
733  */
734 void
735 conversation_set_port2(conversation_t *conv, const guint32 port)
736 {
737    DISSECTOR_ASSERT_HINT(!(conv->options & CONVERSATION_TEMPLATE),
738             "Use the conversation_create_from_template function when the CONVERSATION_TEMPLATE bit is set in the options mask");
739
740         DPRINT(("called for port=%d", port));
741
742         /*
743          * If the port 2 value is not wildcarded, don't set it.
744          */
745         if ((!(conv->options & NO_PORT2)) || (conv->options & NO_PORT2_FORCE))
746                 return;
747
748         DINDENT();
749         if (conv->options & NO_ADDR2) {
750                 conversation_remove_from_hashtable(conversation_hashtable_no_addr2_or_port2, conv);
751         } else {
752                 conversation_remove_from_hashtable(conversation_hashtable_no_port2, conv);
753         }
754         conv->options &= ~NO_PORT2;
755         conv->key_ptr->port2  = port;
756         if (conv->options & NO_ADDR2) {
757                 conversation_insert_into_hashtable(conversation_hashtable_no_addr2, conv);
758         } else {
759                 conversation_insert_into_hashtable(conversation_hashtable_exact, conv);
760         }
761         DENDENT();
762 }
763
764 /*
765  * Set the address 2 value in a key.  Remove the original from
766  * table, update the options and port values, insert the updated key.
767  */
768 void
769 conversation_set_addr2(conversation_t *conv, const address *addr)
770 {
771         char* addr_str;
772         DISSECTOR_ASSERT_HINT(!(conv->options & CONVERSATION_TEMPLATE),
773                         "Use the conversation_create_from_template function when the CONVERSATION_TEMPLATE bit is set in the options mask");
774
775         addr_str = address_to_str(NULL, addr);
776         DPRINT(("called for addr=%s", addr_str));
777         wmem_free(NULL, addr_str);
778
779         /*
780          * If the address 2 value is not wildcarded, don't set it.
781          */
782         if (!(conv->options & NO_ADDR2))
783                 return;
784
785         DINDENT();
786         if (conv->options & NO_PORT2) {
787                 conversation_remove_from_hashtable(conversation_hashtable_no_addr2_or_port2, conv);
788         } else {
789                 conversation_remove_from_hashtable(conversation_hashtable_no_port2, conv);
790         }
791         conv->options &= ~NO_ADDR2;
792         SE_COPY_ADDRESS(&conv->key_ptr->addr2, addr);
793         if (conv->options & NO_PORT2) {
794                 conversation_insert_into_hashtable(conversation_hashtable_no_port2, conv);
795         } else {
796                 conversation_insert_into_hashtable(conversation_hashtable_exact, conv);
797         }
798         DENDENT();
799 }
800
801 /*
802  * Search a particular hash table for a conversation with the specified
803  * {addr1, port1, addr2, port2} and set up before frame_num.
804  */
805 static conversation_t *
806 conversation_lookup_hashtable(GHashTable *hashtable, const guint32 frame_num, const address *addr1, const address *addr2,
807     const port_type ptype, const guint32 port1, const guint32 port2)
808 {
809         conversation_t* convo=NULL;
810         conversation_t* match=NULL;
811         conversation_t* chain_head=NULL;
812         conversation_key key;
813
814         /*
815          * We don't make a copy of the address data, we just copy the
816          * pointer to it, as "key" disappears when we return.
817          */
818         key.addr1 = *addr1;
819         key.addr2 = *addr2;
820         key.ptype = ptype;
821         key.port1 = port1;
822         key.port2 = port2;
823
824         chain_head = (conversation_t *)g_hash_table_lookup(hashtable, &key);
825
826         if (chain_head && (chain_head->setup_frame <= frame_num)) {
827                 match = chain_head;
828
829                 if((chain_head->last)&&(chain_head->last->setup_frame<=frame_num))
830                         return chain_head->last;
831
832                 if((chain_head->latest_found)&&(chain_head->latest_found->setup_frame<=frame_num))
833                         match = chain_head->latest_found;
834
835                 for (convo = match; convo && convo->setup_frame <= frame_num; convo = convo->next) {
836                         if (convo->setup_frame > match->setup_frame) {
837                                 match = convo;
838                         }
839                 }
840         }
841
842     if (match)
843         chain_head->latest_found = match;
844
845         return match;
846 }
847
848
849 /*
850  * Given two address/port pairs for a packet, search for a conversation
851  * containing packets between those address/port pairs.  Returns NULL if
852  * not found.
853  *
854  * We try to find the most exact match that we can, and then proceed to
855  * try wildcard matches on the "addr_b" and/or "port_b" argument if a more
856  * exact match failed.
857  *
858  * Either or both of the "addr_b" and "port_b" arguments may be specified as
859  * a wildcard by setting the NO_ADDR_B or NO_PORT_B flags in the "options"
860  * argument.  We do only wildcard matches on addresses and ports specified
861  * as wildcards.
862  *
863  * I.e.:
864  *
865  *      if neither "addr_b" nor "port_b" were specified as wildcards, we
866  *      do an exact match (addr_a/port_a and addr_b/port_b) and, if that
867  *      succeeds, we return a pointer to the matched conversation;
868  *
869  *      otherwise, if "port_b" wasn't specified as a wildcard, we try to
870  *      match any address 2 with the specified port 2 (addr_a/port_a and
871  *      {any}/port_b) and, if that succeeds, we return a pointer to the
872  *      matched conversation;
873  *
874  *      otherwise, if "addr_b" wasn't specified as a wildcard, we try to
875  *      match any port 2 with the specified address 2 (addr_a/port_a and
876  *      addr_b/{any}) and, if that succeeds, we return a pointer to the
877  *      matched conversation;
878  *
879  *      otherwise, we try to match any address 2 and any port 2
880  *      (addr_a/port_a and {any}/{any}) and, if that succeeds, we return
881  *      a pointer to the matched conversation;
882  *
883  *      otherwise, we found no matching conversation, and return NULL.
884  */
885 conversation_t *
886 find_conversation(const guint32 frame_num, const address *addr_a, const address *addr_b, const port_type ptype,
887     const guint32 port_a, const guint32 port_b, const guint options)
888 {
889    conversation_t *conversation;
890
891    /*
892     * First try an exact match, if we have two addresses and ports.
893     */
894    if (!(options & (NO_ADDR_B|NO_PORT_B))) {
895       /*
896        * Neither search address B nor search port B are wildcarded,
897        * start out with an exact match.
898        */
899       DPRINT(("trying exact match"));
900       conversation =
901          conversation_lookup_hashtable(conversation_hashtable_exact,
902          frame_num, addr_a, addr_b, ptype,
903          port_a, port_b);
904       /* Didn't work, try the other direction */
905       if (conversation == NULL) {
906               DPRINT(("trying opposite direction"));
907               conversation =
908                  conversation_lookup_hashtable(conversation_hashtable_exact,
909                  frame_num, addr_b, addr_a, ptype,
910                  port_b, port_a);
911       }
912       if ((conversation == NULL) && (addr_a->type == AT_FC)) {
913          /* In Fibre channel, OXID & RXID are never swapped as
914           * TCP/UDP ports are in TCP/IP.
915           */
916          conversation =
917             conversation_lookup_hashtable(conversation_hashtable_exact,
918             frame_num, addr_b, addr_a, ptype,
919             port_a, port_b);
920       }
921           DPRINT(("exact match %sfound",conversation?"":"not "));
922       if (conversation != NULL)
923          return conversation;
924    }
925
926    /*
927     * Well, that didn't find anything.  Try matches that wildcard
928     * one of the addresses, if we have two ports.
929     */
930    if (!(options & NO_PORT_B)) {
931       /*
932        * Search port B isn't wildcarded.
933        *
934        * First try looking for a conversation with the specified
935        * address A and port A as the first address and port, and
936        * with any address and the specified port B as the second
937        * address and port.
938        * ("addr_b" doesn't take part in this lookup.)
939        */
940       DPRINT(("trying wildcarded dest address"));
941       conversation =
942          conversation_lookup_hashtable(conversation_hashtable_no_addr2,
943          frame_num, addr_a, addr_b, ptype, port_a, port_b);
944       if ((conversation == NULL) && (addr_a->type == AT_FC)) {
945          /* In Fibre channel, OXID & RXID are never swapped as
946           * TCP/UDP ports are in TCP/IP.
947           */
948          conversation =
949             conversation_lookup_hashtable(conversation_hashtable_no_addr2,
950             frame_num, addr_b, addr_a, ptype,
951             port_a, port_b);
952       }
953       if (conversation != NULL) {
954          /*
955           * If search address B isn't wildcarded, and this is for a
956           * connection-oriented protocol, set the second address for this
957           * conversation to address B, as that's the address that matched the
958           * wildcarded second address for this conversation.
959           *
960           * (This assumes that, for all connection oriented protocols, the
961           * endpoints of a connection have only one address each, i.e. you
962           * don't get packets in a given direction coming from more than one
963           * address, unless the CONVERSATION_TEMPLATE option is set.)
964           */
965          DPRINT(("wildcarded dest address match found"));
966          if (!(conversation->options & NO_ADDR_B) && ptype != PT_UDP)
967          {
968             if(!(conversation->options & CONVERSATION_TEMPLATE))
969             {
970                conversation_set_addr2(conversation, addr_b);
971             }
972             else
973             {
974                conversation =
975                   conversation_create_from_template(conversation, addr_b, 0);
976             }
977          }
978          return conversation;
979       }
980
981       /*
982        * Well, that didn't find anything.
983        * If search address B was specified, try looking for a
984        * conversation with the specified address B and port B as
985        * the first address and port, and with any address and the
986        * specified port A as the second address and port (this
987        * packet may be going in the opposite direction from the
988        * first packet in the conversation).
989        * ("addr_a" doesn't take part in this lookup.)
990        */
991       if (!(options & NO_ADDR_B)) {
992          DPRINT(("trying dest addr:port as source addr:port with wildcarded dest addr"));
993          conversation =
994             conversation_lookup_hashtable(conversation_hashtable_no_addr2,
995             frame_num, addr_b, addr_a, ptype, port_b, port_a);
996          if (conversation != NULL) {
997             /*
998              * If this is for a connection-oriented
999              * protocol, set the second address for
1000              * this conversation to address A, as
1001              * that's the address that matched the
1002              * wildcarded second address for this
1003              * conversation.
1004              */
1005                 DPRINT(("match found"));
1006             if (ptype != PT_UDP) {
1007                if(!(conversation->options & CONVERSATION_TEMPLATE))
1008                {
1009                   conversation_set_addr2(conversation, addr_a);
1010                }
1011                else
1012                {
1013                   conversation =
1014                      conversation_create_from_template(conversation, addr_a, 0);
1015                }
1016             }
1017             return conversation;
1018          }
1019       }
1020    }
1021
1022    /*
1023     * Well, that didn't find anything.  Try matches that wildcard
1024     * one of the ports, if we have two addresses.
1025    */
1026    if (!(options & NO_ADDR_B)) {
1027       /*
1028        * Search address B isn't wildcarded.
1029        *
1030        * First try looking for a conversation with the specified
1031        * address A and port A as the first address and port, and
1032        * with the specified address B and any port as the second
1033        * address and port.
1034        * ("port_b" doesn't take part in this lookup.)
1035        */
1036       DPRINT(("trying wildcarded dest port"));
1037       conversation =
1038          conversation_lookup_hashtable(conversation_hashtable_no_port2,
1039          frame_num, addr_a, addr_b, ptype, port_a, port_b);
1040       if ((conversation == NULL) && (addr_a->type == AT_FC)) {
1041          /* In Fibre channel, OXID & RXID are never swapped as
1042           * TCP/UDP ports are in TCP/IP
1043           */
1044          conversation =
1045             conversation_lookup_hashtable(conversation_hashtable_no_port2,
1046             frame_num, addr_b, addr_a, ptype, port_a, port_b);
1047       }
1048       if (conversation != NULL) {
1049          /*
1050           * If search port B isn't wildcarded, and this is for a connection-
1051           * oriented protocol, set the second port for this conversation to
1052           * port B, as that's the port that matched the wildcarded second port
1053           * for this conversation.
1054           *
1055           * (This assumes that, for all connection oriented protocols, the
1056           * endpoints of a connection have only one port each, i.e. you don't
1057           * get packets in a given direction coming from more than one port,
1058           * unless the CONVERSATION_TEMPLATE option is set.)
1059           */
1060          DPRINT(("match found"));
1061          if (!(conversation->options & NO_PORT_B) && ptype != PT_UDP)
1062          {
1063             if(!(conversation->options & CONVERSATION_TEMPLATE))
1064             {
1065                conversation_set_port2(conversation, port_b);
1066             }
1067             else
1068             {
1069                conversation =
1070                   conversation_create_from_template(conversation, 0, port_b);
1071             }
1072          }
1073          return conversation;
1074       }
1075
1076       /*
1077        * Well, that didn't find anything.
1078        * If search port B was specified, try looking for a
1079        * conversation with the specified address B and port B
1080        * as the first address and port, and with the specified
1081        * address A and any port as the second address and port
1082        * (this packet may be going in the opposite direction
1083        * from the first packet in the conversation).
1084        * ("port_a" doesn't take part in this lookup.)
1085        */
1086       if (!(options & NO_PORT_B)) {
1087          DPRINT(("trying dest addr:port as source addr:port and wildcarded dest port"));
1088          conversation =
1089             conversation_lookup_hashtable(conversation_hashtable_no_port2,
1090             frame_num, addr_b, addr_a, ptype, port_b, port_a);
1091          if (conversation != NULL) {
1092             /*
1093              * If this is for a connection-oriented
1094              * protocol, set the second port for
1095              * this conversation to port A, as
1096              * that's the address that matched the
1097              * wildcarded second address for this
1098              * conversation.
1099              */
1100             DPRINT(("match found"));
1101             if (ptype != PT_UDP)
1102             {
1103                if(!(conversation->options & CONVERSATION_TEMPLATE))
1104                {
1105                   conversation_set_port2(conversation, port_a);
1106                }
1107                else
1108                {
1109                   conversation =
1110                      conversation_create_from_template(conversation, 0, port_a);
1111                }
1112             }
1113             return conversation;
1114          }
1115       }
1116    }
1117
1118    /*
1119     * Well, that didn't find anything.  Try matches that wildcard
1120     * one address/port pair.
1121     *
1122     * First try looking for a conversation with the specified address A
1123     * and port A as the first address and port.
1124     * (Neither "addr_b" nor "port_b" take part in this lookup.)
1125     */
1126    DPRINT(("trying wildcarding dest addr:port"));
1127    conversation =
1128       conversation_lookup_hashtable(conversation_hashtable_no_addr2_or_port2,
1129       frame_num, addr_a, addr_b, ptype, port_a, port_b);
1130    if (conversation != NULL) {
1131       /*
1132        * If this is for a connection-oriented protocol:
1133        *
1134        * if search address B isn't wildcarded, set the
1135        * second address for this conversation to address
1136        * B, as that's the address that matched the
1137        * wildcarded second address for this conversation;
1138        *
1139        * if search port B isn't wildcarded, set the
1140        * second port for this conversation to port B,
1141        * as that's the port that matched the wildcarded
1142        * second port for this conversation.
1143        */
1144       DPRINT(("match found"));
1145       if (ptype != PT_UDP)
1146       {
1147          if(!(conversation->options & CONVERSATION_TEMPLATE))
1148          {
1149             if (!(conversation->options & NO_ADDR_B))
1150                conversation_set_addr2(conversation, addr_b);
1151             if (!(conversation->options & NO_PORT_B))
1152                conversation_set_port2(conversation, port_b);
1153          }
1154          else
1155          {
1156             conversation =
1157                conversation_create_from_template(conversation, addr_b, port_b);
1158          }
1159       }
1160       return conversation;
1161    }
1162
1163    /*
1164     * Well, that didn't find anything.
1165     * If search address and port B were specified, try looking for a
1166     * conversation with the specified address B and port B as the
1167     * first address and port, and with any second address and port
1168     * (this packet may be going in the opposite direction from the
1169     * first packet in the conversation).
1170     * (Neither "addr_a" nor "port_a" take part in this lookup.)
1171     */
1172    DPRINT(("trying dest addr:port as source addr:port and wildcarding dest addr:port"));
1173    if (addr_a->type == AT_FC)
1174       conversation =
1175       conversation_lookup_hashtable(conversation_hashtable_no_addr2_or_port2,
1176       frame_num, addr_b, addr_a, ptype, port_a, port_b);
1177    else
1178       conversation =
1179       conversation_lookup_hashtable(conversation_hashtable_no_addr2_or_port2,
1180       frame_num, addr_b, addr_a, ptype, port_b, port_a);
1181    if (conversation != NULL) {
1182       /*
1183        * If this is for a connection-oriented protocol, set the
1184        * second address for this conversation to address A, as
1185        * that's the address that matched the wildcarded second
1186        * address for this conversation, and set the second port
1187        * for this conversation to port A, as that's the port
1188        * that matched the wildcarded second port for this
1189        * conversation.
1190        */
1191       DPRINT(("match found"));
1192       if (ptype != PT_UDP)
1193       {
1194          if(!(conversation->options & CONVERSATION_TEMPLATE))
1195          {
1196             conversation_set_addr2(conversation, addr_a);
1197             conversation_set_port2(conversation, port_a);
1198          }
1199          else
1200          {
1201             conversation = conversation_create_from_template(conversation, addr_a, port_a);
1202          }
1203       }
1204       return conversation;
1205    }
1206
1207    DPRINT(("no matches found"));
1208
1209    /*
1210     * We found no conversation.
1211     */
1212    return NULL;
1213 }
1214
1215 static gint
1216 p_compare(gconstpointer a, gconstpointer b)
1217 {
1218         const conv_proto_data *ap = (const conv_proto_data *)a;
1219         const conv_proto_data *bp = (const conv_proto_data *)b;
1220
1221         if (ap->proto > bp->proto)
1222                 return 1;
1223         else if (ap->proto == bp->proto)
1224                 return 0;
1225         else
1226                 return -1;
1227 }
1228
1229 void
1230 conversation_add_proto_data(conversation_t *conv, const int proto, void *proto_data)
1231 {
1232         conv_proto_data *p1 = se_new(conv_proto_data);
1233
1234         p1->proto = proto;
1235         p1->proto_data = proto_data;
1236
1237         /* Add it to the list of items for this conversation. */
1238
1239         conv->data_list = g_slist_insert_sorted(conv->data_list, (gpointer *)p1,
1240             p_compare);
1241 }
1242
1243 void *
1244 conversation_get_proto_data(const conversation_t *conv, const int proto)
1245 {
1246         conv_proto_data temp, *p1;
1247         GSList *item;
1248
1249         temp.proto = proto;
1250         temp.proto_data = NULL;
1251
1252         item = g_slist_find_custom(conv->data_list, (gpointer *)&temp,
1253             p_compare);
1254
1255         if (item != NULL) {
1256                 p1 = (conv_proto_data *)item->data;
1257                 return p1->proto_data;
1258         }
1259
1260         return NULL;
1261 }
1262
1263 void
1264 conversation_delete_proto_data(conversation_t *conv, const int proto)
1265 {
1266         conv_proto_data temp;
1267         GSList *item;
1268
1269         temp.proto = proto;
1270         temp.proto_data = NULL;
1271
1272         item = g_slist_find_custom(conv->data_list, (gpointer *)&temp,
1273             p_compare);
1274
1275         while(item){
1276                 conv->data_list = g_slist_remove(conv->data_list, item->data);
1277                 item=item->next;
1278         }
1279 }
1280
1281 void
1282 conversation_set_dissector(conversation_t *conversation, const dissector_handle_t handle)
1283 {
1284         conversation->dissector_handle = handle;
1285 }
1286
1287 /*
1288  * Given two address/port pairs for a packet, search for a matching
1289  * conversation and, if found and it has a conversation dissector,
1290  * call that dissector and return TRUE, otherwise return FALSE.
1291  *
1292  * This helper uses call_dissector_only which will NOT call the default
1293  * "data" dissector if the packet was rejected.
1294  * Our caller is responsible to call the data dissector explicitly in case
1295  * this function returns FALSE.
1296  */
1297 gboolean
1298 try_conversation_dissector(const address *addr_a, const address *addr_b, const port_type ptype,
1299     const guint32 port_a, const guint32 port_b, tvbuff_t *tvb, packet_info *pinfo,
1300     proto_tree *tree, void* data)
1301 {
1302         conversation_t *conversation;
1303
1304         conversation = find_conversation(pinfo->fd->num, addr_a, addr_b, ptype, port_a,
1305             port_b, 0);
1306
1307         if (conversation != NULL) {
1308                 int ret;
1309                 if (conversation->dissector_handle == NULL)
1310                         return FALSE;
1311                 ret=call_dissector_only(conversation->dissector_handle, tvb, pinfo,
1312                     tree, data);
1313                 if(!ret) {
1314                         /* this packet was rejected by the dissector
1315                          * so return FALSE in case our caller wants
1316                          * to do some cleaning up.
1317                          */
1318                         return FALSE;
1319                 }
1320                 return TRUE;
1321         }
1322         return FALSE;
1323 }
1324
1325 /*  A helper function that calls find_conversation() and, if a conversation is
1326  *  not found, calls conversation_new().
1327  *  The frame number and addresses are taken from pinfo.
1328  *  No options are used, though we could extend this API to include an options
1329  *  parameter.
1330  */
1331 conversation_t *
1332 find_or_create_conversation(packet_info *pinfo)
1333 {
1334         conversation_t *conv=NULL;
1335
1336         DPRINT(("called for frame #%d: %s:%d -> %s:%d (ptype=%d)",
1337                 pinfo->fd->num, address_to_str(wmem_packet_scope(), &pinfo->src), pinfo->srcport,
1338                 address_to_str(wmem_packet_scope(), &pinfo->dst), pinfo->destport, pinfo->ptype));
1339         DINDENT();
1340
1341         /* Have we seen this conversation before? */
1342         if((conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1343                                      pinfo->ptype, pinfo->srcport,
1344                                      pinfo->destport, 0)) != NULL) {
1345                 DPRINT(("found previous conversation for frame #%d (last_frame=%d)",
1346                                 pinfo->fd->num, conv->last_frame));
1347                 if (pinfo->fd->num > conv->last_frame) {
1348                         conv->last_frame = pinfo->fd->num;
1349                 }
1350         } else {
1351                 /* No, this is a new conversation. */
1352                 DPRINT(("did not find previous conversation for frame #%d",
1353                                 pinfo->fd->num));
1354                 DINDENT();
1355                 conv = conversation_new(pinfo->fd->num, &pinfo->src,
1356                                         &pinfo->dst, pinfo->ptype,
1357                                         pinfo->srcport, pinfo->destport, 0);
1358                 DENDENT();
1359         }
1360
1361         DENDENT();
1362
1363         return conv;
1364 }
1365
1366 GHashTable *
1367 get_conversation_hashtable_exact(void)
1368 {
1369         return conversation_hashtable_exact;
1370 }
1371
1372 GHashTable *
1373 get_conversation_hashtable_no_addr2(void)
1374 {
1375         return conversation_hashtable_no_addr2;
1376 }
1377
1378 GHashTable *
1379 get_conversation_hashtable_no_port2(void)
1380 {
1381         return conversation_hashtable_no_port2;
1382 }
1383
1384 GHashTable *
1385 get_conversation_hashtable_no_addr2_or_port2(void)
1386 {
1387         return conversation_hashtable_no_addr2_or_port2;
1388 }
1389
1390 /*
1391  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
1392  *
1393  * Local variables:
1394  * c-basic-offset: 8
1395  * tab-width: 8
1396  * indent-tabs-mode: t
1397  * End:
1398  *
1399  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1400  * :indentSize=8:tabSize=8:noTabs=false:
1401  */