static int get_address_v5(tvbuff_t *tvb, int offset, socks_hash_entry_t *hash_info) { /* decode the v5 address and return offset of next byte */ int a_type; address addr; a_type = tvb_get_guint8(tvb, offset); offset += 1; switch(a_type) { case 1: /* IPv4 address */ if ( hash_info) { TVB_SET_ADDRESS(&addr, AT_IPv4, tvb, offset, 4); SE_COPY_ADDRESS(&hash_info->dst_addr, &addr); } offset += 4; break; case 4: /* IPv6 address */ if ( hash_info) { TVB_SET_ADDRESS(&addr, AT_IPv6, tvb, offset, 16); SE_COPY_ADDRESS(&hash_info->dst_addr, &addr); } offset += 16; break; case 3: /* domain name address */ offset += tvb_get_guint8(tvb, offset) + 1; break; } return offset; }
/* * Given two address/port pairs for a packet, create a new conversation * to contain packets between those address/port pairs. * * The options field is used to specify whether the address 2 value * and/or port 2 value are not given and any value is acceptable * when searching for this conversation. */ conversation_t * conversation_new(const guint32 setup_frame, const address *addr1, const address *addr2, const port_type ptype, const guint32 port1, const guint32 port2, const guint options) { /* DISSECTOR_ASSERT(!(options | CONVERSATION_TEMPLATE) || ((options | (NO_ADDR2 | NO_PORT2 | NO_PORT2_FORCE))) && "A conversation template may not be constructed without wildcard options"); */ GHashTable* hashtable; conversation_t *conversation=NULL; conversation_key *new_key; if (options & NO_ADDR2) { if (options & (NO_PORT2|NO_PORT2_FORCE)) { hashtable = conversation_hashtable_no_addr2_or_port2; } else { hashtable = conversation_hashtable_no_addr2; } } else { if (options & (NO_PORT2|NO_PORT2_FORCE)) { hashtable = conversation_hashtable_no_port2; } else { hashtable = conversation_hashtable_exact; } } new_key = se_alloc(sizeof(struct conversation_key)); new_key->next = conversation_keys; conversation_keys = new_key; SE_COPY_ADDRESS(&new_key->addr1, addr1); SE_COPY_ADDRESS(&new_key->addr2, addr2); new_key->ptype = ptype; new_key->port1 = port1; new_key->port2 = port2; conversation = se_new(conversation_t); memset(conversation, 0, sizeof(conversation_t)); conversation->index = new_index; conversation->setup_frame = setup_frame; conversation->data_list = NULL; /* clear dissector handle */ conversation->dissector_handle = NULL; /* set the options and key pointer */ conversation->options = options; conversation->key_ptr = new_key; new_index++; conversation_insert_into_hashtable(hashtable, conversation); return conversation; }
/* * Set the address 2 value in a key. Remove the original from * table, update the options and port values, insert the updated key. */ void conversation_set_addr2(conversation_t *conv, const address *addr) { DISSECTOR_ASSERT(!(conv->options & CONVERSATION_TEMPLATE) && "Use the conversation_create_from_template function when the CONVERSATION_TEMPLATE bit is set in the options mask"); /* * If the address 2 value is not wildcarded, don't set it. */ if (!(conv->options & NO_ADDR2)) return; if (conv->options & NO_PORT2) { g_hash_table_remove(conversation_hashtable_no_addr2_or_port2, conv->key_ptr); } else { g_hash_table_remove(conversation_hashtable_no_addr2, conv->key_ptr); } conv->options &= ~NO_ADDR2; SE_COPY_ADDRESS(&conv->key_ptr->addr2, addr); if (conv->options & NO_PORT2) { g_hash_table_insert(conversation_hashtable_no_port2, conv->key_ptr, conv); } else { g_hash_table_insert(conversation_hashtable_exact, conv->key_ptr, conv); } }
/* * Given two address/port pairs for a packet, create a new conversation * to contain packets between those address/port pairs. * * The options field is used to specify whether the address 2 value * and/or port 2 value are not given and any value is acceptable * when searching for this conversation. */ conversation_t * conversation_new(const guint32 setup_frame, const address *addr1, const address *addr2, const port_type ptype, const guint32 port1, const guint32 port2, const guint options) { /* DISSECTOR_ASSERT(!(options | CONVERSATION_TEMPLATE) || ((options | (NO_ADDR2 | NO_PORT2 | NO_PORT2_FORCE))) && "A conversation template may not be constructed without wildcard options"); */ GHashTable* hashtable; conversation_t *conversation; conversation_t *tc; conversation_key existing_key; conversation_key *new_key; if (options & NO_ADDR2) { if (options & (NO_PORT2|NO_PORT2_FORCE)) { hashtable = conversation_hashtable_no_addr2_or_port2; } else { hashtable = conversation_hashtable_no_addr2; } } else { if (options & (NO_PORT2|NO_PORT2_FORCE)) { hashtable = conversation_hashtable_no_port2; } else { hashtable = conversation_hashtable_exact; } } existing_key.addr1 = *addr1; existing_key.addr2 = *addr2; existing_key.ptype = ptype; existing_key.port1 = port1; existing_key.port2 = port2; conversation = g_hash_table_lookup(hashtable, &existing_key); tc = conversation; /* Remember if lookup was successful */ new_key = se_alloc(sizeof(struct conversation_key)); new_key->next = conversation_keys; conversation_keys = new_key; SE_COPY_ADDRESS(&new_key->addr1, addr1); SE_COPY_ADDRESS(&new_key->addr2, addr2); new_key->ptype = ptype; new_key->port1 = port1; new_key->port2 = port2; if (conversation) { for (; conversation->next; conversation = conversation->next) ; conversation->next = se_alloc(sizeof(conversation_t)); conversation = conversation->next; } else { conversation = se_alloc(sizeof(conversation_t)); } conversation->next = NULL; conversation->index = new_index; conversation->setup_frame = setup_frame; conversation->data_list = NULL; /* clear dissector handle */ conversation->dissector_handle = NULL; /* set the options and key pointer */ conversation->options = options; conversation->key_ptr = new_key; new_index++; /* only insert a hash table entry if this * is the first conversation with this key */ if (!tc) g_hash_table_insert(hashtable, new_key, conversation); return conversation; }