lbttcp_transport_t * lbttcp_transport_add(const address * source_address, guint16 source_port, guint32 session_id, guint32 frame) { lbttcp_transport_t * entry = NULL; conversation_t * conv = NULL; lbttcp_transport_conv_data_t * conv_data = NULL; conv = find_conversation(frame, source_address, &lbttcp_null_address, PT_TCP, source_port, 0, 0); if (conv == NULL) { conv = conversation_new(frame, source_address, &lbttcp_null_address, PT_TCP, source_port, 0, 0); } conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp); if (conv_data == NULL) { conv_data = wmem_new(wmem_file_scope(), lbttcp_transport_conv_data_t); conv_data->frame_tree = wmem_tree_new(wmem_file_scope()); conv_data->session_tree = wmem_tree_new(wmem_file_scope()); conversation_add_proto_data(conv, proto_lbttcp, (void *) conv_data); } entry = (lbttcp_transport_t *) wmem_tree_lookup32(conv_data->session_tree, session_id); if (entry != NULL) { return (entry); } entry = lbttcp_transport_create(source_address, source_port, session_id); wmem_tree_insert32(conv_data->session_tree, session_id, (void *) entry); wmem_tree_insert32(conv_data->frame_tree, frame, (void *) entry); return (entry); }
void lbttcp_transport_sid_add(const address * source_address, guint16 source_port, guint32 frame, guint32 session_id) { conversation_t * conv = NULL; lbttcp_transport_conv_data_t * conv_data = NULL; lbttcp_transport_t * transport = NULL; conv = find_conversation(frame, source_address, &lbttcp_null_address, PT_TCP, source_port, 0, 0); if (conv == NULL) { conv = conversation_new(frame, source_address, &lbttcp_null_address, PT_TCP, source_port, 0, 0); } conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp); if (conv_data == NULL) { conv_data = wmem_new(wmem_file_scope(), lbttcp_transport_conv_data_t); conv_data->frame_tree = wmem_tree_new(wmem_file_scope()); conv_data->session_tree = wmem_tree_new(wmem_file_scope()); conversation_add_proto_data(conv, proto_lbttcp, (void *) conv_data); } /* Lookup by frame */ transport = (lbttcp_transport_t *) wmem_tree_lookup32_le(conv_data->frame_tree, frame); if (transport != NULL) { if (transport->session_id != session_id) { transport = NULL; } } if (transport == NULL) { transport = lbttcp_transport_create(source_address, source_port, session_id); wmem_tree_insert32(conv_data->session_tree, session_id, (void *) transport); wmem_tree_insert32(conv_data->frame_tree, frame, (void *) transport); } }
void register_follow_stream(const int proto_id, const char* tap_listener, follow_conv_filter_func conv_filter, follow_index_filter_func index_filter, follow_address_filter_func address_filter, follow_port_to_display_func port_to_display, tap_packet_cb tap_handler) { register_follow_t *follower; DISSECTOR_ASSERT(tap_listener); DISSECTOR_ASSERT(conv_filter); DISSECTOR_ASSERT(index_filter); DISSECTOR_ASSERT(address_filter); DISSECTOR_ASSERT(port_to_display); DISSECTOR_ASSERT(tap_handler); follower = wmem_new(wmem_epan_scope(), register_follow_t); follower->proto_id = proto_id; follower->tap_listen_str = tap_listener; follower->conv_filter = conv_filter; follower->index_filter = index_filter; follower->address_filter = address_filter; follower->port_to_display = port_to_display; follower->tap_handler = tap_handler; if (registered_followers == NULL) registered_followers = wmem_tree_new(wmem_epan_scope()); wmem_tree_insert_string(registered_followers, proto_get_protocol_short_name(find_protocol_by_id(proto_id)), follower, 0); }
static ipmi_packet_data_t * get_packet_data(packet_info * pinfo) { ipmi_packet_data_t * data; /* get conversation data */ conversation_t * conv = find_or_create_conversation(pinfo); /* get protocol-specific data */ data = (ipmi_packet_data_t *) conversation_get_proto_data(conv, proto_ipmi); if (!data) { /* allocate per-packet data */ data = wmem_new0(wmem_file_scope(), ipmi_packet_data_t); /* allocate request list and frame tree */ data->frame_tree = wmem_tree_new(wmem_file_scope()); data->request_list = wmem_list_new(wmem_file_scope()); /* add protocol data */ conversation_add_proto_data(conv, proto_ipmi, data); } /* check if packet has changed */ if (pinfo->num != data->curr_frame_num) { data->curr_level = 0; data->next_level = 0; } return data; }
wmem_itree_t * wmem_itree_new(wmem_allocator_t *allocator) { wmem_itree_t *tree = wmem_tree_new(allocator); tree->post_rotation_cb = &update_edges_after_rotation; return tree; }
/* * 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; DPRINT(("creating conversation for frame #%d: %s:%d -> %s:%d (ptype=%d)", setup_frame, address_to_str(wmem_packet_scope(), addr1), port1, address_to_str(wmem_packet_scope(), addr2), port2, ptype)); 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 = wmem_new(wmem_file_scope(), struct conversation_key); new_key->next = conversation_keys; conversation_keys = new_key; copy_address_wmem(wmem_file_scope(), &new_key->addr1, addr1); copy_address_wmem(wmem_file_scope(), &new_key->addr2, addr2); new_key->ptype = ptype; new_key->port1 = port1; new_key->port2 = port2; conversation = wmem_new(wmem_file_scope(), conversation_t); memset(conversation, 0, sizeof(conversation_t)); conversation->index = new_index; conversation->setup_frame = conversation->last_frame = setup_frame; conversation->data_list = NULL; conversation->dissector_tree = wmem_tree_new(wmem_file_scope()); /* set the options and key pointer */ conversation->options = options; conversation->key_ptr = new_key; new_index++; DINDENT(); conversation_insert_into_hashtable(hashtable, conversation); DENDENT(); return conversation; }
void register_stat_tap_table_ui(stat_tap_table_ui *ui) { if (registered_stat_tables == NULL) registered_stat_tables = wmem_tree_new(wmem_epan_scope()); wmem_tree_insert_string(registered_stat_tables, ui->cli_string, ui, 0); }
static oid_info_t* add_oid(const char* name, oid_kind_t kind, const oid_value_type_t* type, oid_key_t* key, guint oid_len, guint32 *subids) { guint i = 0; oid_info_t* c = &oid_root; prepopulate_oids(); oid_len--; do { oid_info_t* n = (oid_info_t *)wmem_tree_lookup32(c->children,subids[i]); if(n) { if (i == oid_len) { if (n->name) { if (!g_str_equal(n->name,name)) { D(2,("Renaming Oid from: %s -> %s, this means the same oid is registered more than once",n->name,name)); } wmem_free(wmem_epan_scope(), n->name); } n->name = wmem_strdup(wmem_epan_scope(), name); if (! n->value_type) { n->value_type = type; } return n; } } else { n = wmem_new(wmem_epan_scope(), oid_info_t); n->subid = subids[i]; n->kind = kind; n->children = wmem_tree_new(wmem_epan_scope()); n->value_hfid = -2; n->key = key; n->parent = c; n->bits = NULL; wmem_tree_insert32(c->children,n->subid,n); if (i == oid_len) { n->name = wmem_strdup(wmem_epan_scope(), name); n->value_type = type; n->kind = kind; return n; } else { n->name = NULL; n->value_type = NULL; n->kind = OID_KIND_UNKNOWN; } } c = n; } while(++i); g_assert_not_reached(); return NULL; }
static lbttcp_client_transport_t * lbttcp_client_transport_add(lbttcp_transport_t * transport, const address * receiver_address, guint16 receiver_port, guint32 frame) { lbttcp_client_transport_t * entry; conversation_t * client_conv = NULL; wmem_tree_t * session_tree = NULL; if (transport == NULL) { return (NULL); } entry = lbttcp_client_transport_find(transport, receiver_address, receiver_port, frame); if (entry != NULL) { return (entry); } entry = wmem_new(wmem_file_scope(), lbttcp_client_transport_t); copy_address_wmem(wmem_file_scope(), &(entry->receiver_address), receiver_address); entry->receiver_port = receiver_port; entry->id = transport->next_client_id++; /* See if a conversation for this address/port pair exists. */ client_conv = find_conversation(frame, &(transport->source_address), receiver_address, PT_TCP, transport->source_port, receiver_port, 0); if (client_conv == NULL) { client_conv = conversation_new(frame, &(transport->source_address), receiver_address, PT_TCP, transport->source_port, receiver_port, 0); session_tree = wmem_tree_new(wmem_file_scope()); conversation_add_proto_data(client_conv, proto_lbttcp, (void *) session_tree); } session_tree = (wmem_tree_t *) conversation_get_proto_data(client_conv, proto_lbttcp); if (session_tree == NULL) { session_tree = wmem_tree_new(wmem_file_scope()); conversation_add_proto_data(client_conv, proto_lbttcp, (void *) session_tree); } wmem_tree_insert32(session_tree, transport->session_id, (void *) entry); /* Add this client to the transport. */ wmem_list_append(transport->client_list, (void *) entry); return (entry); }
static usbip_conv_info_t * usbip_get_usbip_conv(packet_info *pinfo) { conversation_t *conversation; usbip_conv_info_t *usbip_info; conversation = find_or_create_conversation(pinfo); usbip_info = (usbip_conv_info_t *) conversation_get_proto_data(conversation, proto_usbip); if (!usbip_info) { usbip_info = wmem_new(wmem_file_scope(), usbip_conv_info_t); usbip_info->pdus = wmem_tree_new(wmem_file_scope()); conversation_add_proto_data(conversation, proto_usbip, usbip_info); } return usbip_info; }
static void prepopulate_oids(void) { if (!oid_root.children) { char* debug_env = getenv("WIRESHARK_DEBUG_MIBS"); guint32 subid; debuglevel = debug_env ? (int)strtoul(debug_env,NULL,10) : 0; oid_root.children = wmem_tree_new(wmem_epan_scope()); /* * make sure we got strings at least in the three root-children oids * that way oid_resolved() will always have a string to print */ subid = 0; oid_add("itu-t",1,&subid); subid = 1; oid_add("iso",1,&subid); subid = 2; oid_add("joint-iso-itu-t",1,&subid); } }
int register_export_object(const int proto_id, tap_packet_cb export_packet_func, export_object_gui_reset_cb reset_cb) { register_eo_t *table; DISSECTOR_ASSERT(export_packet_func); table = wmem_new(wmem_epan_scope(), register_eo_t); table->proto_id = proto_id; table->tap_listen_str = wmem_strdup_printf(wmem_epan_scope(), "%s_eo", proto_get_protocol_filter_name(proto_id)); table->eo_func = export_packet_func; table->reset_cb = reset_cb; if (registered_eo_tables == NULL) registered_eo_tables = wmem_tree_new(wmem_epan_scope()); wmem_tree_insert_string(registered_eo_tables, proto_get_protocol_filter_name(proto_id), table, 0); return register_tap(table->tap_listen_str); }
lbm_transport_sqn_t * lbm_transport_sqn_add(wmem_tree_t * list, lbm_transport_frame_t * frame) { lbm_transport_sqn_t * sqn_entry = NULL; lbm_transport_sqn_frame_t * frame_entry = NULL; /* Locate the SQN. */ sqn_entry = (lbm_transport_sqn_t *) wmem_tree_lookup32(list, frame->sqn); if (sqn_entry == NULL) { sqn_entry = wmem_new(wmem_file_scope(), lbm_transport_sqn_t); sqn_entry->sqn = frame->sqn; sqn_entry->frame_count = 0; sqn_entry->frame = wmem_tree_new(wmem_file_scope()); wmem_tree_insert32(list, frame->sqn, (void *) sqn_entry); } /* Add this frame to the list of frames this SQN appears in. */ frame_entry = wmem_new(wmem_file_scope(), lbm_transport_sqn_frame_t); frame_entry->frame = frame->frame; frame_entry->retransmission = frame->retransmission; wmem_tree_insert32(sqn_entry->frame, frame->frame, (void *) frame_entry); sqn_entry->frame_count++; return (sqn_entry); }
void register_seq_analysis(const char* name, const char* ui_name, const int proto_id, const char* tap_listener, guint tap_flags, tap_packet_cb tap_func) { register_analysis_t* analysis; DISSECTOR_ASSERT(tap_func); analysis = wmem_new0(wmem_epan_scope(), register_analysis_t); analysis->name = name; analysis->ui_name = ui_name; analysis->proto_id = proto_id; if (tap_listener != NULL) analysis->tap_listen_str = tap_listener; else analysis->tap_listen_str = proto_get_protocol_filter_name(proto_id); analysis->tap_flags = tap_flags; analysis->analysis_func = tap_func; if (registered_seq_analysis == NULL) registered_seq_analysis = wmem_tree_new(wmem_epan_scope()); wmem_tree_insert_string(registered_seq_analysis, name, analysis, 0); }
/* * Function for the PANA PDU dissector. */ static void dissect_pana_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *pana_tree = NULL; guint16 flags; guint16 msg_type; guint32 msg_length; guint32 avp_length; guint32 seq_num; conversation_t *conversation; pana_conv_info_t *pana_info; pana_transaction_t *pana_trans; int offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "PANA"); col_clear(pinfo->cinfo, COL_INFO); /* Get message length, type and flags */ msg_length = tvb_get_ntohs(tvb, 2); flags = tvb_get_ntohs(tvb, 4); msg_type = tvb_get_ntohs(tvb, 6); seq_num = tvb_get_ntohl(tvb, 12); avp_length = msg_length - 16; col_add_fstr(pinfo->cinfo, COL_INFO, "Type %s-%s", val_to_str(msg_type, msg_type_names, "Unknown (%d)"), val_to_str(flags & PANA_FLAG_R, msg_subtype_names, "Unknown (%d)")); /* Make the protocol tree */ if (tree) { proto_item *ti; ti = proto_tree_add_item(tree, proto_pana, tvb, 0, -1, ENC_NA); pana_tree = proto_item_add_subtree(ti, ett_pana); } /* * We need to track some state for this protocol on a per conversation * basis so we can do neat things like request/response tracking */ conversation = find_or_create_conversation(pinfo); /* * Do we already have a state structure for this conv */ pana_info = (pana_conv_info_t *)conversation_get_proto_data(conversation, proto_pana); if (!pana_info) { /* No. Attach that information to the conversation, and add * it to the list of information structures. */ pana_info = wmem_new(wmem_file_scope(), pana_conv_info_t); pana_info->pdus=wmem_tree_new(wmem_file_scope()); conversation_add_proto_data(conversation, proto_pana, pana_info); } if(!pinfo->fd->flags.visited){ if(flags&PANA_FLAG_R){ /* This is a request */ pana_trans=wmem_new(wmem_file_scope(), pana_transaction_t); pana_trans->req_frame=pinfo->fd->num; pana_trans->rep_frame=0; pana_trans->req_time=pinfo->fd->abs_ts; wmem_tree_insert32(pana_info->pdus, seq_num, (void *)pana_trans); } else { pana_trans=(pana_transaction_t *)wmem_tree_lookup32(pana_info->pdus, seq_num); if(pana_trans){ pana_trans->rep_frame=pinfo->fd->num; } } } else { pana_trans=(pana_transaction_t *)wmem_tree_lookup32(pana_info->pdus, seq_num); } if(!pana_trans){ /* create a "fake" pana_trans structure */ pana_trans=wmem_new(wmem_packet_scope(), pana_transaction_t); pana_trans->req_frame=0; pana_trans->rep_frame=0; pana_trans->req_time=pinfo->fd->abs_ts; } /* print state tracking in the tree */ if(flags&PANA_FLAG_R){ /* This is a request */ if(pana_trans->rep_frame){ proto_item *it; it=proto_tree_add_uint(pana_tree, hf_pana_response_in, tvb, 0, 0, pana_trans->rep_frame); PROTO_ITEM_SET_GENERATED(it); } } else { /* This is a reply */ if(pana_trans->req_frame){ proto_item *it; nstime_t ns; it=proto_tree_add_uint(pana_tree, hf_pana_response_to, tvb, 0, 0, pana_trans->req_frame); PROTO_ITEM_SET_GENERATED(it); nstime_delta(&ns, &pinfo->fd->abs_ts, &pana_trans->req_time); it=proto_tree_add_time(pana_tree, hf_pana_response_time, tvb, 0, 0, &ns); PROTO_ITEM_SET_GENERATED(it); } } /* Reserved field */ proto_tree_add_item(pana_tree, hf_pana_reserved_type, tvb, offset, 2, ENC_NA); offset += 2; /* Length */ proto_tree_add_item(pana_tree, hf_pana_length_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* Flags */ dissect_pana_flags(pana_tree, tvb, offset, flags); offset += 2; /* Message Type */ proto_tree_add_uint_format_value(pana_tree, hf_pana_msg_type, tvb, offset, 2, msg_type, "%s-%s (%d)", val_to_str(msg_type, msg_type_names, "Unknown (%d)"), val_to_str(flags & PANA_FLAG_R, msg_subtype_names, "Unknown (%d)"), msg_type); offset += 2; /* Session ID */ proto_tree_add_item(pana_tree, hf_pana_session_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* Sequence Number */ proto_tree_add_item(pana_tree, hf_pana_seqnumber, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* AVPs */ if(avp_length != 0){ tvbuff_t *avp_tvb; proto_tree *avp_tree; proto_item *avp_item; avp_tvb = tvb_new_subset(tvb, offset, avp_length, avp_length); avp_item = proto_tree_add_text(pana_tree, tvb, offset, avp_length, "Attribute Value Pairs"); avp_tree = proto_item_add_subtree(avp_item, ett_pana_avp); if (avp_tree != NULL) { dissect_avps(avp_tvb, pinfo, avp_tree); } } }
static int dissect_gssapi_work(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean is_verifier, gssapi_encrypt_info_t* encrypt_info) { proto_item *volatile item; proto_tree *volatile subtree; volatile int return_offset = 0; gssapi_conv_info_t *volatile gss_info; gssapi_oid_value *oidvalue; dissector_handle_t handle; conversation_t *conversation; tvbuff_t *oid_tvb; int len, start_offset, oid_start_offset; volatile int offset; gint8 appclass; gboolean pc, ind_field; gint32 tag; guint32 len1; const char *oid; fragment_head *fd_head=NULL; gssapi_frag_info_t *fi; tvbuff_t *volatile gss_tvb=NULL; asn1_ctx_t asn1_ctx; start_offset=0; offset=0; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); /* * We don't know whether the data is encrypted, so say it's * not, for now. The subdissector must set gssapi_data_encrypted * if it is. */ encrypt_info->gssapi_data_encrypted = FALSE; /* * We need a conversation for later */ conversation = find_or_create_conversation(pinfo); gss_info = (gssapi_conv_info_t *)conversation_get_proto_data(conversation, proto_gssapi); if (!gss_info) { gss_info = wmem_new(wmem_file_scope(), gssapi_conv_info_t); gss_info->oid=NULL; gss_info->do_reassembly=FALSE; gss_info->frags=wmem_tree_new(wmem_file_scope()); conversation_add_proto_data(conversation, proto_gssapi, gss_info); } item = proto_tree_add_item( tree, proto_gssapi, tvb, offset, -1, ENC_NA); subtree = proto_item_add_subtree(item, ett_gssapi); /* * Catch the ReportedBoundsError exception; the stuff we've been * handed doesn't necessarily run to the end of the packet, it's * an item inside a packet, so if it happens to be malformed (or * we, or a dissector we call, has a bug), so that an exception * is thrown, we want to report the error, but return and let * our caller dissect the rest of the packet. * * If it gets a BoundsError, we can stop, as there's nothing more * in the packet after our blob to see, so we just re-throw the * exception. */ TRY { gss_tvb=tvb; /* First of all, if it's the first time we see this packet * then check whether we are in the middle of reassembly or not */ if( (!pinfo->fd->flags.visited) && (gss_info->do_reassembly) && (gssapi_reassembly) ){ fi=(gssapi_frag_info_t *)wmem_tree_lookup32(gss_info->frags, gss_info->first_frame); if(!fi){ goto done; } wmem_tree_insert32(gss_info->frags, pinfo->num, fi); fd_head=fragment_add(&gssapi_reassembly_table, tvb, 0, pinfo, fi->first_frame, NULL, gss_info->frag_offset, tvb_captured_length(tvb), TRUE); gss_info->frag_offset+=tvb_captured_length(tvb); /* we need more fragments */ if(!fd_head){ goto done; } /* this blob is now fully reassembled */ gss_info->do_reassembly=FALSE; fi->reassembled_in=pinfo->num; gss_tvb=tvb_new_chain(tvb, fd_head->tvb_data); add_new_data_source(pinfo, gss_tvb, "Reassembled GSSAPI"); } /* We have seen this packet before. * Is this blob part of reassembly or a normal blob ? */ if( (pinfo->fd->flags.visited) && (gssapi_reassembly) ){ fi=(gssapi_frag_info_t *)wmem_tree_lookup32(gss_info->frags, pinfo->num); if(fi){ fd_head=fragment_get(&gssapi_reassembly_table, pinfo, fi->first_frame, NULL); if(fd_head && (fd_head->flags&FD_DEFRAGMENTED)){ if(pinfo->num==fi->reassembled_in){ proto_item *frag_tree_item; gss_tvb=tvb_new_chain(tvb, fd_head->tvb_data); add_new_data_source(pinfo, gss_tvb, "Reassembled GSSAPI"); show_fragment_tree(fd_head, &gssapi_frag_items, tree, pinfo, tvb, &frag_tree_item); } else { proto_item *it; it=proto_tree_add_uint(tree, hf_gssapi_reassembled_in, tvb, 0, 0, fi->reassembled_in); PROTO_ITEM_SET_GENERATED(it); goto done; } } } } /* Read header */ offset = get_ber_identifier(gss_tvb, offset, &appclass, &pc, &tag); offset = get_ber_length(gss_tvb, offset, &len1, &ind_field); if (!(appclass == BER_CLASS_APP && pc && tag == 0)) { /* It could be NTLMSSP, with no OID. This can happen for anything that microsoft calls 'Negotiate' or GSS-SPNEGO */ if ((tvb_captured_length_remaining(gss_tvb, start_offset)>7) && (tvb_strneql(gss_tvb, start_offset, "NTLMSSP", 7) == 0)) { return_offset = call_dissector(ntlmssp_handle, tvb_new_subset_remaining(gss_tvb, start_offset), pinfo, subtree); goto done; } /* Maybe it's new NTLMSSP payload */ if ((tvb_captured_length_remaining(gss_tvb, start_offset)>16) && ((tvb_memeql(gss_tvb, start_offset, "\x01\x00\x00\x00", 4) == 0))) { return_offset = call_dissector(ntlmssp_payload_handle, tvb_new_subset_remaining(gss_tvb, start_offset), pinfo, subtree); encrypt_info->gssapi_data_encrypted = TRUE; goto done; } if ((tvb_captured_length_remaining(gss_tvb, start_offset)==16) && ((tvb_memeql(gss_tvb, start_offset, "\x01\x00\x00\x00", 4) == 0))) { if( is_verifier ) { return_offset = call_dissector(ntlmssp_verf_handle, tvb_new_subset_remaining(gss_tvb, start_offset), pinfo, subtree); } else if( encrypt_info->gssapi_encrypted_tvb ) { return_offset = call_dissector_with_data(ntlmssp_data_only_handle, tvb_new_subset_remaining(encrypt_info->gssapi_encrypted_tvb, 0), pinfo, subtree, &encrypt_info->gssapi_decrypted_tvb); encrypt_info->gssapi_data_encrypted = TRUE; } goto done; } /* Maybe it's new GSSKRB5 CFX Wrapping */ if ((tvb_captured_length_remaining(gss_tvb, start_offset)>2) && ((tvb_memeql(gss_tvb, start_offset, "\04\x04", 2) == 0) || (tvb_memeql(gss_tvb, start_offset, "\05\x04", 2) == 0))) { return_offset = call_dissector_with_data(spnego_krb5_wrap_handle, tvb_new_subset_remaining(gss_tvb, start_offset), pinfo, subtree, encrypt_info); goto done; } /* * If we do not recognise an Application class, * then we are probably dealing with an inner context * token or a wrap token, and we should retrieve the * gssapi_oid_value pointer from the per-frame data or, * if there is no per-frame data (as would be the case * the first time we dissect this frame), from the * conversation that exists or that we created from * pinfo (and then make it per-frame data). * We need to make it per-frame data as there can be * more than one GSS-API negotiation in a conversation. * * Note! We "cheat". Since we only need the pointer, * we store that as the data. (That's not really * "cheating" - the per-frame data and per-conversation * data code doesn't care what you supply as a data * pointer; it just treats it as an opaque pointer, it * doesn't dereference it or free what it points to.) */ oidvalue = (gssapi_oid_value *)p_get_proto_data(wmem_file_scope(), pinfo, proto_gssapi, 0); if (!oidvalue && !pinfo->fd->flags.visited) { /* No handle attached to this frame, but it's the first */ /* pass, so it'd be attached to the conversation. */ oidvalue = gss_info->oid; if (gss_info->oid) p_add_proto_data(wmem_file_scope(), pinfo, proto_gssapi, 0, gss_info->oid); } if (!oidvalue) { proto_tree_add_expert_format(subtree, pinfo, &ei_gssapi_unknown_header, gss_tvb, start_offset, 0, "Unknown header (class=%d, pc=%d, tag=%d)", appclass, pc, tag); return_offset = tvb_captured_length(gss_tvb); goto done; } else { tvbuff_t *oid_tvb_local; oid_tvb_local = tvb_new_subset_remaining(gss_tvb, start_offset); if (is_verifier) handle = oidvalue->wrap_handle; else handle = oidvalue->handle; len = call_dissector_with_data(handle, oid_tvb_local, pinfo, subtree, encrypt_info); if (len == 0) return_offset = tvb_captured_length(gss_tvb); else return_offset = start_offset + len; goto done; /* We are finished here */ } } /* Read oid */ oid_start_offset=offset; offset=dissect_ber_object_identifier_str(FALSE, &asn1_ctx, subtree, gss_tvb, offset, hf_gssapi_oid, &oid); oidvalue = gssapi_lookup_oid_str(oid); /* Check if we need reassembly of this blob. * Only try reassembly for OIDs we recognize * and when we have the entire tvb * * SMB will sometimes split one large GSSAPI blob * across multiple SMB/SessionSetup commands. * While we should look at the uid returned in the response * to the first SessionSetup and use that as a key * instead for simplicity we assume there will not be several * such authentication at once on a single tcp session */ if( (!pinfo->fd->flags.visited) && (oidvalue) && (tvb_captured_length(gss_tvb)==tvb_reported_length(gss_tvb)) && (len1>(guint32)tvb_captured_length_remaining(gss_tvb, oid_start_offset)) && (gssapi_reassembly) ){ fi=wmem_new(wmem_file_scope(), gssapi_frag_info_t); fi->first_frame=pinfo->num; fi->reassembled_in=0; wmem_tree_insert32(gss_info->frags, pinfo->num, fi); fragment_add(&gssapi_reassembly_table, gss_tvb, 0, pinfo, pinfo->num, NULL, 0, tvb_captured_length(gss_tvb), TRUE); fragment_set_tot_len(&gssapi_reassembly_table, pinfo, pinfo->num, NULL, len1+oid_start_offset); gss_info->do_reassembly=TRUE; gss_info->first_frame=pinfo->num; gss_info->frag_offset=tvb_captured_length(gss_tvb); goto done; } /* * Hand off to subdissector. */ if ((oidvalue == NULL) || !proto_is_protocol_enabled(oidvalue->proto)) { /* No dissector for this oid */ proto_tree_add_item(subtree, hf_gssapi_token_object, gss_tvb, oid_start_offset, -1, ENC_NA); return_offset = tvb_captured_length(gss_tvb); goto done; } /* Save a pointer to the data for the OID for the * GSSAPI protocol for this conversation. */ /* * Now add the proto data ... * but only if it is not already there. */ if(!gss_info->oid){ gss_info->oid=oidvalue; } if (is_verifier) { handle = oidvalue->wrap_handle; if (handle != NULL) { oid_tvb = tvb_new_subset_remaining(gss_tvb, offset); len = call_dissector_with_data(handle, oid_tvb, pinfo, subtree, encrypt_info); if (len == 0) return_offset = tvb_captured_length(gss_tvb); else return_offset = offset + len; } else { proto_tree_add_item(subtree, hf_gssapi_auth_verifier, gss_tvb, offset, -1, ENC_NA); return_offset = tvb_captured_length(gss_tvb); } } else { handle = oidvalue->handle; if (handle != NULL) { oid_tvb = tvb_new_subset_remaining(gss_tvb, offset); len = call_dissector_with_data(handle, oid_tvb, pinfo, subtree, encrypt_info); if (len == 0) return_offset = tvb_captured_length(gss_tvb); else return_offset = offset + len; } else { proto_tree_add_item(subtree, hf_gssapi_auth_credentials, gss_tvb, offset, -1, ENC_NA); return_offset = tvb_captured_length(gss_tvb); } } done: ; } CATCH_NONFATAL_ERRORS { /* * Somebody threw an exception that means that there * was a problem dissecting the payload; that means * that a dissector was found, so we don't need to * dissect the payload as data or update the protocol * or info columns. * * Just show the exception and then drive on to show * the trailer, after noting that a dissector was found * and restoring the protocol value that was in effect * before we called the subdissector. */ show_exception(gss_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; proto_item_set_len(item, return_offset); return return_offset; }
void guids_init(void) { guid_to_name_tree=wmem_tree_new(wmem_epan_scope()); /* XXX here is a good place to read a config file with wellknown guids */ }
static void wmem_test_tree(void) { wmem_allocator_t *allocator, *extra_allocator; wmem_tree_t *tree; guint32 i; int seen_values = 0; int j; gchar *str_key; #define WMEM_TREE_MAX_KEY_COUNT 8 #define WMEM_TREE_MAX_KEY_LEN 4 int key_count; wmem_tree_key_t keys[WMEM_TREE_MAX_KEY_COUNT]; allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT); extra_allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT); tree = wmem_tree_new(allocator); g_assert(tree); g_assert(wmem_tree_is_empty(tree)); /* test basic 32-bit key operations */ for (i=0; i<CONTAINER_ITERS; i++) { g_assert(wmem_tree_lookup32(tree, i) == NULL); if (i > 0) { g_assert(wmem_tree_lookup32_le(tree, i) == GINT_TO_POINTER(i-1)); } wmem_tree_insert32(tree, i, GINT_TO_POINTER(i)); g_assert(wmem_tree_lookup32(tree, i) == GINT_TO_POINTER(i)); g_assert(!wmem_tree_is_empty(tree)); } wmem_free_all(allocator); tree = wmem_tree_new(allocator); for (i=0; i<CONTAINER_ITERS; i++) { guint32 rand_int = g_test_rand_int(); wmem_tree_insert32(tree, rand_int, GINT_TO_POINTER(i)); g_assert(wmem_tree_lookup32(tree, rand_int) == GINT_TO_POINTER(i)); } wmem_free_all(allocator); /* test auto-reset functionality */ tree = wmem_tree_new_autoreset(allocator, extra_allocator); for (i=0; i<CONTAINER_ITERS; i++) { g_assert(wmem_tree_lookup32(tree, i) == NULL); wmem_tree_insert32(tree, i, GINT_TO_POINTER(i)); g_assert(wmem_tree_lookup32(tree, i) == GINT_TO_POINTER(i)); } wmem_free_all(extra_allocator); for (i=0; i<CONTAINER_ITERS; i++) { g_assert(wmem_tree_lookup32(tree, i) == NULL); g_assert(wmem_tree_lookup32_le(tree, i) == NULL); } wmem_free_all(allocator); /* test array key functionality */ tree = wmem_tree_new(allocator); key_count = g_random_int_range(1, WMEM_TREE_MAX_KEY_COUNT); for (j=0; j<key_count; j++) { keys[j].length = g_random_int_range(1, WMEM_TREE_MAX_KEY_LEN); } keys[key_count].length = 0; for (i=0; i<CONTAINER_ITERS; i++) { for (j=0; j<key_count; j++) { keys[j].key = (guint32*)wmem_test_rand_string(allocator, (keys[j].length*4), (keys[j].length*4)+1); } wmem_tree_insert32_array(tree, keys, GINT_TO_POINTER(i)); g_assert(wmem_tree_lookup32_array(tree, keys) == GINT_TO_POINTER(i)); } wmem_free_all(allocator); tree = wmem_tree_new(allocator); keys[0].length = 1; keys[0].key = wmem_new(allocator, guint32); *(keys[0].key) = 0; keys[1].length = 0; for (i=0; i<CONTAINER_ITERS; i++) { wmem_tree_insert32_array(tree, keys, GINT_TO_POINTER(i)); *(keys[0].key) += 4; } *(keys[0].key) = 0; for (i=0; i<CONTAINER_ITERS; i++) { g_assert(wmem_tree_lookup32_array(tree, keys) == GINT_TO_POINTER(i)); for (j=0; j<3; j++) { (*(keys[0].key)) += 1; g_assert(wmem_tree_lookup32_array_le(tree, keys) == GINT_TO_POINTER(i)); } *(keys[0].key) += 1; } wmem_free_all(allocator); /* test string key functionality */ tree = wmem_tree_new(allocator); for (i=0; i<CONTAINER_ITERS; i++) { str_key = wmem_test_rand_string(allocator, 1, 64); wmem_tree_insert_string(tree, str_key, GINT_TO_POINTER(i), 0); g_assert(wmem_tree_lookup_string(tree, str_key, 0) == GINT_TO_POINTER(i)); } wmem_free_all(allocator); tree = wmem_tree_new(allocator); for (i=0; i<CONTAINER_ITERS; i++) { str_key = wmem_test_rand_string(allocator, 1, 64); wmem_tree_insert_string(tree, str_key, GINT_TO_POINTER(i), WMEM_TREE_STRING_NOCASE); g_assert(wmem_tree_lookup_string(tree, str_key, WMEM_TREE_STRING_NOCASE) == GINT_TO_POINTER(i)); } wmem_free_all(allocator); /* test for-each functionality */ tree = wmem_tree_new(allocator); expected_user_data = GINT_TO_POINTER(g_test_rand_int()); for (i=0; i<CONTAINER_ITERS; i++) { gint tmp; do { tmp = g_test_rand_int(); } while (wmem_tree_lookup32(tree, tmp)); value_seen[i] = FALSE; wmem_tree_insert32(tree, tmp, GINT_TO_POINTER(i)); } cb_called_count = 0; cb_continue_count = CONTAINER_ITERS; wmem_tree_foreach(tree, wmem_test_foreach_cb, expected_user_data); g_assert(cb_called_count == CONTAINER_ITERS); g_assert(cb_continue_count == 0); for (i=0; i<CONTAINER_ITERS; i++) { g_assert(value_seen[i]); value_seen[i] = FALSE; } cb_called_count = 0; cb_continue_count = 10; wmem_tree_foreach(tree, wmem_test_foreach_cb, expected_user_data); g_assert(cb_called_count == 10); g_assert(cb_continue_count == 0); for (i=0; i<CONTAINER_ITERS; i++) { if (value_seen[i]) { seen_values++; } } g_assert(seen_values == 10); wmem_destroy_allocator(extra_allocator); wmem_destroy_allocator(allocator); }