2 * Routines for building lists of packets that are part of a "conversation"
4 * $Id: conversation.c,v 1.17 2001/11/29 09:05:25 guy Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
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.
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.
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.
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
35 #ifdef HAVE_NETINET_IN_H
36 # include <netinet/in.h>
42 #include "conversation.h"
45 * Hash table for conversations with no wildcards.
47 static GHashTable *conversation_hashtable_exact = NULL;
50 * Hash table for conversations with one wildcard address.
52 static GHashTable *conversation_hashtable_no_addr2 = NULL;
55 * Hash table for conversations with one wildcard port.
57 static GHashTable *conversation_hashtable_no_port2 = NULL;
60 * Hash table for conversations with one wildcard address and port.
62 static GHashTable *conversation_hashtable_no_addr2_or_port2 = NULL;
64 static GMemChunk *conversation_key_chunk = NULL;
65 static GMemChunk *conversation_chunk = NULL;
68 typedef struct conversation_key {
69 struct conversation_key *next;
78 * Linked list of conversation keys, so we can, before freeing them all,
79 * free the address data allocations associated with them.
81 static conversation_key *conversation_keys;
83 static guint32 new_index;
85 static int conversation_init_count = 200;
88 * Protocol-specific data attached to a conversation_t structure - protocol
89 * index and opaque pointer.
91 typedef struct _conv_proto_data {
96 static GMemChunk *conv_proto_data_area = NULL;
99 * Compute the hash value for two given address/port pairs if the match
103 conversation_hash_exact(gconstpointer v)
105 conversation_key *key = (conversation_key *)v;
110 for (i = 0; i < key->addr1.len; i++)
111 hash_val += key->addr1.data[i];
113 hash_val += key->port1;
115 for (i = 0; i < key->addr2.len; i++)
116 hash_val += key->addr2.data[i];
118 hash_val += key->port2;
124 * Compare two conversation keys for an exact match.
127 conversation_match_exact(gconstpointer v, gconstpointer w)
129 conversation_key *v1 = (conversation_key *)v;
130 conversation_key *v2 = (conversation_key *)w;
132 if (v1->ptype != v2->ptype)
133 return 0; /* different types of port */
136 * Are the first and second port 1 values the same, the first and
137 * second port 2 values the same, the first and second address
138 * 1 values the same, and the first and second address 2 values
141 if (v1->port1 == v2->port1 &&
142 v1->port2 == v2->port2 &&
143 ADDRESSES_EQUAL(&v1->addr1, &v2->addr1) &&
144 ADDRESSES_EQUAL(&v1->addr2, &v2->addr2)) {
146 * Yes. It's the same conversation, and the two
147 * address/port pairs are going in the same direction.
153 * Is the first port 2 the same as the second port 1, the first
154 * port 1 the same as the second port 2, the first address 2
155 * the same as the second address 1, and the first address 1
156 * the same as the second address 2?
158 if (v1->port2 == v2->port1 &&
159 v1->port1 == v2->port2 &&
160 ADDRESSES_EQUAL(&v1->addr2, &v2->addr1) &&
161 ADDRESSES_EQUAL(&v1->addr1, &v2->addr2)) {
163 * Yes. It's the same conversation, and the two
164 * address/port pairs are going in opposite directions.
170 * The addresses or the ports don't match.
176 * Compute the hash value for two given address/port pairs if the match
177 * has a wildcard address 2.
180 conversation_hash_no_addr2(gconstpointer v)
182 conversation_key *key = (conversation_key *)v;
187 for (i = 0; i < key->addr1.len; i++)
188 hash_val += key->addr1.data[i];
190 hash_val += key->port1;
192 hash_val += key->port2;
198 * Compare two conversation keys, except for the address 2 value.
199 * We don't check both directions of the conversation - the routine
200 * doing the hash lookup has to do two searches, as the hash key
201 * will be different for the two directions.
204 conversation_match_no_addr2(gconstpointer v, gconstpointer w)
206 conversation_key *v1 = (conversation_key *)v;
207 conversation_key *v2 = (conversation_key *)w;
209 if (v1->ptype != v2->ptype)
210 return 0; /* different types of port */
213 * Are the first and second port 1 values the same, the first and
214 * second port 2 valuess the same, and the first and second
215 * address 1 values the same?
217 if (v1->port1 == v2->port1 &&
218 v1->port2 == v2->port2 &&
219 ADDRESSES_EQUAL(&v1->addr1, &v2->addr1)) {
221 * Yes. It's the same conversation, and the two
222 * address/port pairs are going in the same direction.
228 * The addresses or the ports don't match.
234 * Compute the hash value for two given address/port pairs if the match
235 * has a wildcard port 2.
238 conversation_hash_no_port2(gconstpointer v)
240 conversation_key *key = (conversation_key *)v;
245 for (i = 0; i < key->addr1.len; i++)
246 hash_val += key->addr1.data[i];
248 hash_val += key->port1;
250 for (i = 0; i < key->addr2.len; i++)
251 hash_val += key->addr2.data[i];
257 * Compare two conversation keys, except for the port 2 value.
258 * We don't check both directions of the conversation - the routine
259 * doing the hash lookup has to do two searches, as the hash key
260 * will be different for the two directions.
263 conversation_match_no_port2(gconstpointer v, gconstpointer w)
265 conversation_key *v1 = (conversation_key *)v;
266 conversation_key *v2 = (conversation_key *)w;
268 if (v1->ptype != v2->ptype)
269 return 0; /* different types of port */
272 * Are the first and second port 1 values the same, the first and
273 * second address 1 values the same, and the first and second
274 * address 2 values the same?
276 if (v1->port1 == v2->port1 &&
277 ADDRESSES_EQUAL(&v1->addr1, &v2->addr1) &&
278 ADDRESSES_EQUAL(&v1->addr2, &v2->addr2)) {
280 * Yes. It's the same conversation, and the two
281 * address/port pairs are going in the same direction.
287 * The addresses or the ports don't match.
293 * Compute the hash value for two given address/port pairs if the match
294 * has a wildcard address 2 and port 2.
297 conversation_hash_no_addr2_or_port2(gconstpointer v)
299 conversation_key *key = (conversation_key *)v;
304 for (i = 0; i < key->addr1.len; i++)
305 hash_val += key->addr1.data[i];
307 hash_val += key->port1;
313 * Compare the address 1 and port 1 in the two conversation keys.
314 * We don't check both directions of the conversation - the routine
315 * doing the hash lookup has to do two searches, as the hash key
316 * will be different for the two directions.
319 conversation_match_no_addr2_or_port2(gconstpointer v, gconstpointer w)
321 conversation_key *v1 = (conversation_key *)v;
322 conversation_key *v2 = (conversation_key *)w;
324 if (v1->ptype != v2->ptype)
325 return 0; /* different types of port */
328 * Are the first and second port 1 values the same and the first
329 * and second address 1 values the same?
331 if (v1->port1 == v2->port1 &&
332 ADDRESSES_EQUAL(&v1->addr1, &v2->addr1)) {
334 * Yes. It's the same conversation, and the two
335 * address/port pairs are going in the same direction.
341 * The addresses or the ports don't match.
347 * Initialize some variables every time a file is loaded or re-loaded.
348 * Destroy all existing conversations, and create a new hash table
349 * for the conversations in the new file.
352 conversation_init(void)
354 conversation_key *key;
357 * Free the addresses associated with the conversation keys.
359 for (key = conversation_keys; key != NULL; key = key->next) {
361 * Grr. I guess the theory here is that freeing
362 * something sure as heck modifies it, so you
363 * want to ban attempts to free it, but, alas,
364 * if we make the "data" field of an "address"
365 * structure not a "const", the compiler whines if
366 * we try to make it point into the data for a packet,
367 * as that's a "const" array (and should be, as dissectors
368 * shouldn't trash it).
370 * So we cast the complaint into oblivion, and rely on
371 * the fact that these addresses are known to have had
372 * their data mallocated, i.e. they don't point into,
373 * say, the middle of the data for a packet.
375 g_free((gpointer)key->addr1.data);
376 g_free((gpointer)key->addr2.data);
378 conversation_keys = NULL;
379 if (conversation_hashtable_exact != NULL)
380 g_hash_table_destroy(conversation_hashtable_exact);
381 if (conversation_hashtable_no_addr2 != NULL)
382 g_hash_table_destroy(conversation_hashtable_no_addr2);
383 if (conversation_hashtable_no_port2 != NULL)
384 g_hash_table_destroy(conversation_hashtable_no_port2);
385 if (conversation_hashtable_no_addr2_or_port2 != NULL)
386 g_hash_table_destroy(conversation_hashtable_no_addr2_or_port2);
387 if (conversation_key_chunk != NULL)
388 g_mem_chunk_destroy(conversation_key_chunk);
389 if (conversation_chunk != NULL)
390 g_mem_chunk_destroy(conversation_chunk);
393 * Free up any space allocated for conversation protocol data
396 * We can free the space, as the structures it contains are
397 * pointed to by conversation data structures that were freed
400 if (conv_proto_data_area != NULL)
401 g_mem_chunk_destroy(conv_proto_data_area);
403 conversation_hashtable_exact =
404 g_hash_table_new(conversation_hash_exact,
405 conversation_match_exact);
406 conversation_hashtable_no_addr2 =
407 g_hash_table_new(conversation_hash_no_addr2,
408 conversation_match_no_addr2);
409 conversation_hashtable_no_port2 =
410 g_hash_table_new(conversation_hash_no_port2,
411 conversation_match_no_port2);
412 conversation_hashtable_no_addr2_or_port2 =
413 g_hash_table_new(conversation_hash_no_addr2_or_port2,
414 conversation_match_no_addr2_or_port2);
415 conversation_key_chunk = g_mem_chunk_new("conversation_key_chunk",
416 sizeof(conversation_key),
417 conversation_init_count * sizeof(struct conversation_key),
419 conversation_chunk = g_mem_chunk_new("conversation_chunk",
420 sizeof(conversation_t),
421 conversation_init_count * sizeof(conversation_t),
425 * Allocate a new area for conversation protocol data items.
427 conv_proto_data_area = g_mem_chunk_new("conv_proto_data_area",
428 sizeof(conv_proto_data), 20 * sizeof(conv_proto_data), /* FIXME*/
432 * Start the conversation indices over at 0.
438 * Given two address/port pairs for a packet, create a new conversation
439 * to contain packets between those address/port pairs.
441 * The options field is used to specify whether the address 2 value
442 * and/or port 2 value are not given and any value is acceptable
443 * when searching for this conversation.
446 conversation_new(address *addr1, address *addr2, port_type ptype,
447 guint32 port1, guint32 port2, guint options)
449 conversation_t *conversation;
450 conversation_key *new_key;
452 new_key = g_mem_chunk_alloc(conversation_key_chunk);
453 new_key->next = conversation_keys;
454 conversation_keys = new_key;
455 COPY_ADDRESS(&new_key->addr1, addr1);
456 COPY_ADDRESS(&new_key->addr2, addr2);
457 new_key->ptype = ptype;
458 new_key->port1 = port1;
459 new_key->port2 = port2;
461 conversation = g_mem_chunk_alloc(conversation_chunk);
462 conversation->index = new_index;
463 conversation->data_list = NULL;
465 /* clear dissector handle */
466 conversation->dissector_handle = NULL;
468 /* set the options and key pointer */
469 conversation->options = options;
470 conversation->key_ptr = new_key;
474 if (options & NO_ADDR2) {
475 if (options & NO_PORT2) {
476 g_hash_table_insert(conversation_hashtable_no_addr2_or_port2,
477 new_key, conversation);
479 g_hash_table_insert(conversation_hashtable_no_addr2,
480 new_key, conversation);
483 if (options & NO_PORT2) {
484 g_hash_table_insert(conversation_hashtable_no_port2,
485 new_key, conversation);
487 g_hash_table_insert(conversation_hashtable_exact,
488 new_key, conversation);
495 * Set the port 2 value in a key. Remove the original from table,
496 * update the options and port values, insert the updated key.
499 conversation_set_port2(conversation_t *conv, guint32 port)
502 * If the port 2 value is wildcarded, don't set it.
504 if (!(conv->options & NO_PORT2))
507 if (conv->options & NO_ADDR2) {
508 g_hash_table_remove(conversation_hashtable_no_addr2_or_port2,
511 g_hash_table_remove(conversation_hashtable_no_port2,
514 conv->options &= ~NO_PORT2;
515 conv->key_ptr->port2 = port;
516 if (conv->options & NO_ADDR2) {
517 g_hash_table_insert(conversation_hashtable_no_addr2,
518 conv->key_ptr, conv);
520 g_hash_table_insert(conversation_hashtable_exact,
521 conv->key_ptr, conv);
526 * Set the address 2 value in a key. Remove the original from
527 * table, update the options and port values, insert the updated key.
530 conversation_set_addr2(conversation_t *conv, address *addr)
533 * If the address 2 value is wildcarded, don't set it.
535 if (!(conv->options & NO_ADDR2))
538 if (conv->options & NO_PORT2) {
539 g_hash_table_remove(conversation_hashtable_no_addr2_or_port2,
542 g_hash_table_remove(conversation_hashtable_no_addr2,
545 conv->options &= ~NO_ADDR2;
546 COPY_ADDRESS(&conv->key_ptr->addr2, addr);
547 if (conv->options & NO_PORT2) {
548 g_hash_table_insert(conversation_hashtable_no_port2,
549 conv->key_ptr, conv);
551 g_hash_table_insert(conversation_hashtable_exact,
552 conv->key_ptr, conv);
557 * Search a particular hash table for a conversaton with the specified
558 * addr1, port1, addr2, and port2.
560 static conversation_t *
561 conversation_lookup_hashtable(GHashTable *hashtable, address *addr1, address *addr2,
562 port_type ptype, guint32 port1, guint32 port2)
564 conversation_key key;
567 * We don't make a copy of the address data, we just copy the
568 * pointer to it, as "key" disappears when we return.
575 return g_hash_table_lookup(hashtable, &key);
580 * Given two address/port pairs for a packet, search for a conversation
581 * containing packets between those address/port pairs. Returns NULL if
584 * We try to find the most exact match that we can, and then proceed to
585 * try wildcard matches on the "addr_b" and/or "port_b" argument if a more
586 * exact match failed.
588 * Either or both of the "addr_b" and "port_b" arguments may be specified as
589 * a wildcard by setting the NO_ADDR_B or NO_PORT_B flags in the "options"
590 * argument. We do only wildcard matches on addresses and ports specified
595 * if neither "addr_b" nor "port_b" were specified as wildcards, we
596 * do an exact match (addr_a/port_a and addr_b/port_b) and, if that
597 * succeeds, we return a pointer to the matched conversation;
599 * otherwise, if "port_b" wasn't specified as a wildcard, we try to
600 * match any address 2 with the specified port 2 (addr_a/port_a and
601 * {any}/addr_b) and, if that succeeds, we return a pointer to the
602 * matched conversation;
604 * otherwise, if "addr_b" wasn't specified as a wildcard, we try to
605 * match any port 2 with the specified address 2 (addr_a/port_a and
606 * addr_b/{any}) and, if that succeeds, we return a pointer to the
607 * matched conversation;
609 * otherwise, we try to match any address 2 and any port 2
610 * (addr_a/port_a and {any}/{any}) and, if that succeeds, we return
611 * a pointer to the matched conversation;
613 * otherwise, we found no matching conversation, and return NULL.
616 find_conversation(address *addr_a, address *addr_b, port_type ptype,
617 guint32 port_a, guint32 port_b, guint options)
619 conversation_t *conversation;
622 * First try an exact match, if we have two addresses and ports.
624 if (!(options & (NO_ADDR_B|NO_PORT_B))) {
626 * Neither search address B nor search port B are wildcarded,
627 * start out with an exact match.
628 * Exact matches check both directions.
631 conversation_lookup_hashtable(conversation_hashtable_exact,
632 addr_a, addr_b, ptype, port_a, port_b);
633 if (conversation != NULL)
638 * Well, that didn't find anything. Try matches that wildcard
639 * one of the addresses, if we have two ports.
641 if (!(options & NO_PORT_B)) {
643 * Search port B isn't wildcarded.
645 * First try looking for a conversation with the specified
646 * address A and port A as the first address and port, and
647 * with any address and the specified port B as the second
649 * ("addr_b" doesn't take part in this lookup.)
652 conversation_lookup_hashtable(conversation_hashtable_no_addr2,
653 addr_a, addr_b, ptype, port_a, port_b);
654 if (conversation != NULL) {
656 * If search address B isn't wildcarded, and this
657 * is for a connection-oriented protocol, set the
658 * second address for this conversation to address
659 * B, as that's the address that matched the
660 * wildcarded second address for this conversation.
662 * (XXX - this assumes that, for all connection-
663 * oriented protocols, the endpoints of a connection
664 * have only one address each, i.e. you don't get
665 * packets in a given direction coming from more than
668 if (!(options & NO_ADDR_B) && ptype != PT_UDP)
669 conversation_set_addr2(conversation, addr_b);
674 * Well, that didn't find anything.
675 * If search address B was specified, try looking for a
676 * conversation with the specified address B and port B as
677 * the first address and port, and with any address and the
678 * specified port A as the second address and port (this
679 * packet may be going in the opposite direction from the
680 * first packet in the conversation).
681 * ("addr_a" doesn't take part in this lookup.)
683 if (!(options & NO_ADDR_B)) {
685 conversation_lookup_hashtable(conversation_hashtable_no_addr2,
686 addr_b, addr_a, ptype, port_b, port_a);
687 if (conversation != NULL) {
689 * If this is for a connection-oriented
690 * protocol, set the second address for
691 * this conversation to address A, as
692 * that's the address that matched the
693 * wildcarded second address for this
696 if (ptype != PT_UDP) {
697 conversation_set_addr2(conversation,
706 * Well, that didn't find anything. Try matches that wildcard
707 * one of the ports, if we have two addresses.
709 if (!(options & NO_ADDR_B)) {
711 * Search address B isn't wildcarded.
713 * First try looking for a conversation with the specified
714 * address A and port A as the first address and port, and
715 * with the specified address B and any port as the second
717 * ("port_b" doesn't take part in this lookup.)
720 conversation_lookup_hashtable(conversation_hashtable_no_port2,
721 addr_a, addr_b, ptype, port_a, port_b);
722 if (conversation != NULL) {
724 * If search port B isn't wildcarded, and this is
725 * for a connection-oriented protocol, set the
726 * second port for this conversation to port B,
727 * as that's the port that matched the wildcarded
728 * second port for this conversation.
730 * (XXX - this assumes that, for all connection-
731 * oriented protocols, the endpoints of a connection
732 * have only one port each, i.e. you don't get
733 * packets in a given direction coming from more than
736 if (!(options & NO_PORT_B) && ptype != PT_UDP)
737 conversation_set_port2(conversation, port_b);
742 * Well, that didn't find anything.
743 * If search port B was specified, try looking for a
744 * conversation with the specified address B and port B
745 * as the first address and port, and with the specified
746 * address A and any port as the second address and port
747 * (this packet may be going in the opposite direction
748 * from the first packet in the conversation).
749 * ("port_a" doesn't take part in this lookup.)
751 if (!(options & NO_PORT_B)) {
753 conversation_lookup_hashtable(conversation_hashtable_no_port2,
754 addr_b, addr_a, ptype, port_b, port_a);
755 if (conversation != NULL) {
757 * If this is for a connection-oriented
758 * protocol, set the second port for
759 * this conversation to port A, as
760 * that's the address that matched the
761 * wildcarded second address for this
764 if (ptype != PT_UDP) {
765 conversation_set_port2(conversation,
774 * Well, that didn't find anything. Try matches that wildcard
775 * one address/port pair.
777 * First try looking for a conversation with the specified address A
778 * and port B as the first address and port.
779 * (Neither "addr_b" nor "port_b" take part in this lookup.)
782 conversation_lookup_hashtable(conversation_hashtable_no_addr2_or_port2,
783 addr_a, addr_b, ptype, port_a, port_b);
784 if (conversation != NULL) {
786 * If this is for a connection-oriented protocol:
788 * if search address B isn't wildcarded, set the
789 * second address for this conversation to address
790 * B, as that's the address that matched the
791 * wildcarded second address for this conversation;
793 * if search port B isn't wildcarded, set the
794 * second port for this conversation to port B,
795 * as that's the port that matched the wildcarded
796 * second port for this conversation.
798 if (ptype != PT_UDP) {
799 if (!(options & NO_ADDR_B))
800 conversation_set_addr2(conversation, addr_b);
801 if (!(options & NO_PORT_B))
802 conversation_set_port2(conversation, port_b);
808 * Well, that didn't find anything.
809 * If search address and port B were specified, try looking for a
810 * conversation with the specified address B and port B as the
811 * first address and port, and with any second address and port
812 * (this packet may be going in the opposite direction from the
813 * first packet in the conversation).
814 * (Neither "addr_a" nor "port_a" take part in this lookup.)
817 conversation_lookup_hashtable(conversation_hashtable_no_addr2_or_port2,
818 addr_b, addr_a, ptype, port_b, port_a);
819 if (conversation != NULL) {
821 * If this is for a connection-oriented protocol, set the
822 * second address for this conversation to address A, as
823 * that's the address that matched the wildcarded second
824 * address for this conversation, and set the second port
825 * for this conversation to port A, as that's the port
826 * that matched the wildcarded second port for this
829 if (ptype != PT_UDP) {
830 conversation_set_addr2(conversation, addr_a);
831 conversation_set_port2(conversation, port_a);
837 * We found no conversation.
843 p_compare(gconstpointer a, gconstpointer b)
845 if (((conv_proto_data *)a)->proto > ((conv_proto_data *)b)->proto)
847 else if (((conv_proto_data *)a)->proto == ((conv_proto_data *)b)->proto)
854 conversation_add_proto_data(conversation_t *conv, int proto, void *proto_data)
856 conv_proto_data *p1 = g_mem_chunk_alloc(conv_proto_data_area);
859 p1->proto_data = proto_data;
861 /* Add it to the list of items for this conversation. */
863 conv->data_list = g_slist_insert_sorted(conv->data_list, (gpointer *)p1,
868 conversation_get_proto_data(conversation_t *conv, int proto)
870 conv_proto_data temp, *p1;
874 temp.proto_data = NULL;
876 item = g_slist_find_custom(conv->data_list, (gpointer *)&temp,
880 p1 = (conv_proto_data *)item->data;
881 return p1->proto_data;
888 conversation_delete_proto_data(conversation_t *conv, int proto)
890 conv_proto_data temp;
894 temp.proto_data = NULL;
896 item = g_slist_find_custom(conv->data_list, (gpointer *)&temp,
900 conv->data_list = g_slist_remove(conv->data_list, item);
904 conversation_set_dissector(conversation_t *conversation,
905 dissector_handle_t handle)
907 conversation->dissector_handle = handle;
911 * Given two address/port pairs for a packet, search for a matching
912 * conversation and, if found and it has a conversation dissector,
913 * call that dissector and return TRUE, otherwise return FALSE.
916 try_conversation_dissector(address *addr_a, address *addr_b, port_type ptype,
917 guint32 port_a, guint32 port_b, tvbuff_t *tvb, packet_info *pinfo,
920 conversation_t *conversation;
921 guint16 saved_can_desegment;
923 /* can_desegment is set to 2 by anyone which offers this api/service.
924 then everytime a subdissector is called it is decremented by one.
925 thus only the subdissector immediately ontop of whoever offers this
928 saved_can_desegment=pinfo->can_desegment;
929 pinfo->can_desegment = saved_can_desegment-(saved_can_desegment>0);
931 conversation = find_conversation(addr_a, addr_b, ptype, port_a,
934 if (conversation != NULL) {
935 if (conversation->dissector_handle == NULL){
936 pinfo->can_desegment=saved_can_desegment;
939 call_dissector(conversation->dissector_handle, tvb, pinfo,
941 pinfo->can_desegment=saved_can_desegment;
944 pinfo->can_desegment=saved_can_desegment;