static void wmem_test_map(void) { wmem_allocator_t *allocator; wmem_map_t *map; gchar *str_key; unsigned int i; void *ret; allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT); /* insertion, lookup and removal of simple integer keys */ map = wmem_map_new(allocator, g_direct_hash, g_direct_equal); g_assert(map); for (i=0; i<CONTAINER_ITERS; i++) { ret = wmem_map_insert(map, GINT_TO_POINTER(i), GINT_TO_POINTER(777777)); g_assert(ret == NULL); ret = wmem_map_insert(map, GINT_TO_POINTER(i), GINT_TO_POINTER(i)); g_assert(ret == GINT_TO_POINTER(777777)); ret = wmem_map_insert(map, GINT_TO_POINTER(i), GINT_TO_POINTER(i)); g_assert(ret == GINT_TO_POINTER(i)); } for (i=0; i<CONTAINER_ITERS; i++) { ret = wmem_map_lookup(map, GINT_TO_POINTER(i)); g_assert(ret == GINT_TO_POINTER(i)); ret = wmem_map_remove(map, GINT_TO_POINTER(i)); g_assert(ret == GINT_TO_POINTER(i)); ret = wmem_map_lookup(map, GINT_TO_POINTER(i)); g_assert(ret == NULL); ret = wmem_map_remove(map, GINT_TO_POINTER(i)); g_assert(ret == NULL); } wmem_free_all(allocator); map = wmem_map_new(allocator, wmem_str_hash, g_str_equal); g_assert(map); /* string keys and for-each */ for (i=0; i<CONTAINER_ITERS; i++) { str_key = wmem_test_rand_string(allocator, 1, 64); wmem_map_insert(map, str_key, GINT_TO_POINTER(i)); ret = wmem_map_lookup(map, str_key); g_assert(ret == GINT_TO_POINTER(i)); } wmem_destroy_allocator(allocator); }
void register_ros_protocol_info(const char *oid, const ros_info_t *rinfo, int proto _U_, const char *name, gboolean uses_rtse) { wmem_map_insert(protocol_table, (gpointer)oid, (gpointer)rinfo); if(!uses_rtse) /* if we are not using RTSE, then we must register ROS with BER (ACSE) */ register_ber_oid_dissector_handle(oid, ros_handle, proto, name); }
static usb_i1d3_transaction_t *usb_i1d3_create_transaction( usb_i1d3_conversation_t *conversation, guint32 request) { usb_i1d3_transaction_t *transaction = wmem_new0( wmem_file_scope(), usb_i1d3_transaction_t); transaction->request = request; wmem_map_insert( conversation->request_to_transaction, GUINT_TO_POINTER(transaction->request), (void *)transaction); return transaction; }
/* * Add an entry for a new OUI. */ void llc_add_oui(guint32 oui, const char *table_name, const char *table_ui_name, hf_register_info *hf_item, const int proto) { oui_info_t *new_info; new_info = wmem_new(wmem_epan_scope(), oui_info_t); new_info->table = register_dissector_table(table_name, table_ui_name, proto, FT_UINT16, BASE_HEX); new_info->field_info = hf_item; /* * Create the hash table for OUI information, if it doesn't * already exist. */ if (oui_info_table == NULL) { oui_info_table = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal); } wmem_map_insert(oui_info_table, GUINT_TO_POINTER(oui), new_info); }
// Finds out whether this is the first blip frame in the blip message (which can consist of a series of frames). // If it is, updates the conversation_entry_ptr->blip_requests hash to record the pinfo->num (wireshark packet number) static gboolean is_first_frame_in_msg(blip_conversation_entry_t *conversation_entry_ptr, packet_info *pinfo, guint64 value_frame_flags, guint64 value_message_num) { gboolean first_frame_in_msg = TRUE; // Temporary pool for the lookup hash_key. Will get duplicated on the file_scope() pool if needed to be // stored in the hashtable. gchar *hash_key = message_hash_key_convo(pinfo, value_frame_flags, value_message_num); guint* first_frame_number_for_msg = (guint*)wmem_map_lookup(conversation_entry_ptr->blip_requests, (void *) hash_key); if (first_frame_number_for_msg != NULL) { if (GPOINTER_TO_UINT(first_frame_number_for_msg) != pinfo->num) { first_frame_in_msg = FALSE; } } else { // If storing the key in the hashmap, re-allocate it with the file_scope() allocator gchar *hash_key_copy = wmem_strdup(wmem_file_scope(), hash_key); wmem_map_insert(conversation_entry_ptr->blip_requests, (void *) hash_key_copy, GUINT_TO_POINTER(pinfo->num)); } return first_frame_in_msg; }
static void dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, proto_tree *tree, conversation_t *conversation, fc_hdr *fchdr, fcp_conv_data_t *fcp_conv_data) { int offset = 0; int add_len = 0; guint8 flags, rwflags, lun0; guint16 lun = 0xffff; tvbuff_t *cdb_tvb; int tvb_len; fcp_request_data_t *request_data = NULL; itl_nexus_t itl; fcp_proto_data_t *proto_data; /* Determine the length of the FCP part of the packet */ flags = tvb_get_guint8(tvb, offset+10); if (flags) { add_len = tvb_get_guint8(tvb, offset+11) & 0x7C; add_len = add_len >> 2; } lun0 = tvb_get_guint8(tvb, offset); /* Display single-level LUNs in decimal for clarity */ /* I'm taking a shortcut here by assuming that if the first byte of the * LUN field is 0, it is a single-level LUN. This is not true. For a * real single-level LUN, all 8 bytes except byte 1 must be 0. */ if (lun0) { proto_tree_add_item(tree, hf_fcp_multilun, tvb, offset, 8, ENC_NA); lun = tvb_get_guint8(tvb, offset) & 0x3f; lun <<= 8; lun |= tvb_get_guint8(tvb, offset+1); } else { proto_tree_add_item(tree, hf_fcp_singlelun, tvb, offset+1, 1, ENC_BIG_ENDIAN); lun = tvb_get_guint8(tvb, offset+1); } if (!pinfo->fd->flags.visited) { proto_data = wmem_new(wmem_file_scope(), fcp_proto_data_t); proto_data->lun = lun; p_add_proto_data(wmem_file_scope(), pinfo, proto_fcp, 0, proto_data); } request_data = (fcp_request_data_t*)wmem_map_lookup(fcp_conv_data->luns, GUINT_TO_POINTER((guint)lun)); if (!request_data) { request_data = wmem_new(wmem_file_scope(), fcp_request_data_t); request_data->request_frame = pinfo->num; request_data->response_frame = 0; request_data->request_time = pinfo->abs_ts; request_data->itlq = wmem_new(wmem_file_scope(), itlq_nexus_t); request_data->itlq->first_exchange_frame=0; request_data->itlq->last_exchange_frame=0; request_data->itlq->lun=lun; request_data->itlq->scsi_opcode=0xffff; request_data->itlq->task_flags=0; request_data->itlq->data_length=0; request_data->itlq->bidir_data_length=0; request_data->itlq->fc_time=pinfo->abs_ts; request_data->itlq->flags=0; request_data->itlq->alloc_len=0; request_data->itlq->extra_data=NULL; wmem_map_insert(fcp_conv_data->luns, GUINT_TO_POINTER((guint)lun), request_data); } /* populate the exchange struct */ if(!pinfo->fd->flags.visited){ if(fchdr->fctl&FC_FCTL_EXCHANGE_FIRST){ request_data->itlq->first_exchange_frame=pinfo->num; request_data->itlq->fc_time = pinfo->abs_ts; } if(fchdr->fctl&FC_FCTL_EXCHANGE_LAST){ request_data->itlq->last_exchange_frame=pinfo->num; } } if (request_data->itlq) request_data->itlq->lun = lun; fchdr->lun = lun; proto_tree_add_item(tree, hf_fcp_crn, tvb, offset+8, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fcp_taskattr, tvb, offset+9, 1, ENC_BIG_ENDIAN); dissect_task_mgmt_flags(pinfo, tree, tvb, offset+10); proto_tree_add_item(tree, hf_fcp_addlcdblen, tvb, offset+11, 1, ENC_BIG_ENDIAN); rwflags = tvb_get_guint8(tvb, offset+11); if (request_data->itlq) { if (rwflags & 0x02) { request_data->itlq->task_flags |= SCSI_DATA_READ; } if (rwflags & 0x01) { request_data->itlq->task_flags |= SCSI_DATA_WRITE; } } proto_tree_add_item(tree, hf_fcp_rddata, tvb, offset+11, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fcp_wrdata, tvb, offset+11, 1, ENC_BIG_ENDIAN); tvb_len = tvb_captured_length_remaining(tvb, offset+12); if (tvb_len > (16 + add_len)) tvb_len = 16 + add_len; itl.cmdset = 0xff; itl.conversation = conversation; cdb_tvb = tvb_new_subset_length(tvb, offset+12, tvb_len); dissect_scsi_cdb(cdb_tvb, pinfo, parent_tree, SCSI_DEV_UNKNOWN, request_data->itlq, &itl); proto_tree_add_item(tree, hf_fcp_dl, tvb, offset+12+16+add_len, 4, ENC_BIG_ENDIAN); if (request_data->itlq) { request_data->itlq->data_length = tvb_get_ntohl(tvb, offset+12+16+add_len); } if ( ((rwflags & 0x03) == 0x03) && tvb_reported_length_remaining(tvb, offset+12+16+add_len+4) >= 4) { proto_tree_add_item(tree, hf_fcp_bidir_dl, tvb, offset+12+16+add_len+4, 4, ENC_BIG_ENDIAN); if (request_data->itlq) { request_data->itlq->bidir_data_length = tvb_get_ntohl(tvb, offset+12+16+add_len+4); } } }
/* * 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_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal); 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->num; pana_trans->rep_frame=0; pana_trans->req_time=pinfo->abs_ts; wmem_map_insert(pana_info->pdus, GUINT_TO_POINTER(seq_num), (void *)pana_trans); } else { pana_trans=(pana_transaction_t *)wmem_map_lookup(pana_info->pdus, GUINT_TO_POINTER(seq_num)); if(pana_trans){ pana_trans->rep_frame=pinfo->num; } } } else { pana_trans=(pana_transaction_t *)wmem_map_lookup(pana_info->pdus, GUINT_TO_POINTER(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->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->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; avp_tvb = tvb_new_subset_length(tvb, offset, avp_length); avp_tree = proto_tree_add_subtree(pana_tree, tvb, offset, avp_length, ett_pana_avp, NULL, "Attribute Value Pairs"); dissect_avps(avp_tvb, pinfo, avp_tree); } }
static void dissect_usb_i1d3_response( tvbuff_t *tvb, packet_info *pinfo, usb_i1d3_conversation_t *conversation, proto_tree *tree) { // The response packet does not contain any information about the command // it is a response to, so we need to reconstruct this information using the // previous packet that we saw. // // Note: currently, for simplicity's sake, this assumes that there is only // one inflight request at any given time - in other words, that there is no // pipelining going on. It is not clear if the device would even be able to // service more than one request at the same time in the first place. usb_i1d3_transaction_t *transaction; if (!PINFO_FD_VISITED(pinfo)) { transaction = (usb_i1d3_transaction_t *)wmem_map_lookup( conversation->request_to_transaction, GUINT_TO_POINTER(conversation->previous_packet)); if (transaction) { DISSECTOR_ASSERT(transaction->response == 0); transaction->response = pinfo->num; wmem_map_insert( conversation->response_to_transaction, GUINT_TO_POINTER(transaction->response), (void *)transaction); } } else { // After the first pass, we can't use previous_packet anymore since // there is no guarantee the dissector is called in order, so we use // the reverse mapping that we populated above. transaction = (usb_i1d3_transaction_t *)wmem_map_lookup( conversation->response_to_transaction, GUINT_TO_POINTER(pinfo->num)); } if (transaction) { DISSECTOR_ASSERT(transaction->response == pinfo->num); DISSECTOR_ASSERT(transaction->request != 0); } proto_item *request_item = proto_tree_add_uint( tree, hf_usb_i1d3_request_in, tvb, 0, 0, transaction ? transaction->request : 0); PROTO_ITEM_SET_GENERATED(request_item); if (!transaction) { expert_add_info(pinfo, request_item, &ei_usb_i1d3_unexpected_response); } else { proto_item *command_code_item = proto_tree_add_uint( tree, hf_usb_i1d3_command_code, tvb, 0, 0, transaction->command_code); PROTO_ITEM_SET_GENERATED(command_code_item); } const gchar *command_string = transaction ? try_val_to_str( transaction->command_code, usb_i1d3_command_code_strings) : NULL; if (!command_string) command_string = "unknown"; guint32 response_code; proto_item *response_code_item = proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_response_code, tvb, 0, 1, ENC_NA, &response_code); proto_item_append_text( response_code_item, " (%s)", (response_code == 0) ? "OK" : "error"); if (response_code != 0) { col_add_fstr( pinfo->cinfo, COL_INFO, "Error code %u (%s)", response_code, command_string); expert_add_info(pinfo, response_code_item, &ei_usb_i1d3_error); return; } col_add_fstr(pinfo->cinfo, COL_INFO, "OK (%s)", command_string); if (!transaction) return; // As mentioned in ArgyllCMS spectro/i1d3.c, the second byte is usually the // first byte of the command code, except for GET_DIFF. if (transaction->command_code != USB_I1D3_GET_DIFF) { guint32 echoed_command_code; proto_item *echoed_command_code_item = proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_echoed_command_code, tvb, 1, 1, ENC_NA, &echoed_command_code); guint8 expected_command_code = transaction->command_code >> 8; proto_item_append_text( echoed_command_code_item, " [expected 0x%02x]", expected_command_code); if (echoed_command_code != expected_command_code) { expert_add_info( pinfo, echoed_command_code_item, &ei_usb_i1d3_echoed_command_code_mismatch); } }
static ros_call_response_t * ros_match_call_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint invokeId, gboolean isInvoke) { ros_call_response_t rcr, *rcrp=NULL; ros_conv_info_t *ros_info; conversation_t *conversation; /* first see if we have already matched this */ conversation = find_conversation_pinfo(pinfo, 0); if (conversation == NULL) return NULL; ros_info = (ros_conv_info_t *)conversation_get_proto_data(conversation, proto_ros); if (ros_info == NULL) return NULL; rcr.invokeId=invokeId; rcr.is_request = isInvoke; if(isInvoke) { rcr.req_frame=pinfo->num; rcr.rep_frame=0; } else { rcr.req_frame=0; rcr.rep_frame=pinfo->num; } rcrp=(ros_call_response_t *)wmem_map_lookup(ros_info->matched, &rcr); if(rcrp) { /* we have found a match */ rcrp->is_request=rcr.is_request; } else { /* we haven't found a match - try and match it up */ if(isInvoke) { /* this a a request - add it to the unmatched list */ /* check that we don't already have one of those in the unmatched list and if so remove it */ rcr.invokeId=invokeId; rcrp=(ros_call_response_t *)wmem_map_lookup(ros_info->unmatched, &rcr); if(rcrp){ wmem_map_remove(ros_info->unmatched, rcrp); } /* if we can't reuse the old one, grab a new chunk */ if(!rcrp){ rcrp=wmem_new(wmem_file_scope(), ros_call_response_t); } rcrp->invokeId=invokeId; rcrp->req_frame=pinfo->num; rcrp->req_time=pinfo->abs_ts; rcrp->rep_frame=0; rcrp->is_request=TRUE; wmem_map_insert(ros_info->unmatched, rcrp, rcrp); return NULL; } else { /* this is a result - it should be in our unmatched list */ rcr.invokeId=invokeId; rcrp=(ros_call_response_t *)wmem_map_lookup(ros_info->unmatched, &rcr); if(rcrp){ if(!rcrp->rep_frame){ wmem_map_remove(ros_info->unmatched, rcrp); rcrp->rep_frame=pinfo->num; rcrp->is_request=FALSE; wmem_map_insert(ros_info->matched, rcrp, rcrp); } } } } if(rcrp){ /* we have found a match */ proto_item *item = NULL; if(rcrp->is_request){ item=proto_tree_add_uint(tree, hf_ros_response_in, tvb, 0, 0, rcrp->rep_frame); PROTO_ITEM_SET_GENERATED (item); } else { nstime_t ns; item=proto_tree_add_uint(tree, hf_ros_response_to, tvb, 0, 0, rcrp->req_frame); PROTO_ITEM_SET_GENERATED (item); nstime_delta(&ns, &pinfo->abs_ts, &rcrp->req_time); item=proto_tree_add_time(tree, hf_ros_time, tvb, 0, 0, &ns); PROTO_ITEM_SET_GENERATED (item); } } return rcrp; }
static void request_response_handling(tvbuff_t *tvb, packet_info *pinfo, proto_tree *djiuav_tree, guint32 offset) { conversation_t *conversation; djiuav_conv_info_t *djiuav_info; djiuav_transaction_t *djiuav_trans; guint16 seq_no; gboolean is_cmd; guint8 packet_type; is_cmd = (pinfo->match_uint == pinfo->destport); seq_no = tvb_get_letohs(tvb, offset + 4); packet_type = tvb_get_guint8(tvb, offset + 6); conversation = find_or_create_conversation(pinfo); djiuav_info = (djiuav_conv_info_t *)conversation_get_proto_data(conversation, proto_djiuav); if (!djiuav_info) { djiuav_info = wmem_new(wmem_file_scope(), djiuav_conv_info_t); djiuav_info->pdus=wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal); conversation_add_proto_data(conversation, proto_djiuav, djiuav_info); } if (!pinfo->fd->flags.visited) { if (is_cmd) { djiuav_trans=wmem_new(wmem_file_scope(), djiuav_transaction_t); djiuav_trans->request_frame=pinfo->fd->num; djiuav_trans->reply_frame=0; djiuav_trans->request_time=pinfo->fd->abs_ts; djiuav_trans->seqno=seq_no; djiuav_trans->command=packet_type; wmem_map_insert(djiuav_info->pdus, GUINT_TO_POINTER((guint)seq_no), (void *)djiuav_trans); } else { djiuav_trans=(djiuav_transaction_t *)wmem_map_lookup(djiuav_info->pdus, GUINT_TO_POINTER((guint)seq_no)); if (djiuav_trans) { /* Special case: djiuav seems to send 0x24 replies with seqno 0 and without a request */ if (djiuav_trans->reply_frame == 0) djiuav_trans->reply_frame=pinfo->fd->num; } } } else { djiuav_trans=(djiuav_transaction_t *)wmem_map_lookup(djiuav_info->pdus, GUINT_TO_POINTER((guint)seq_no)); } /* djiuav_trans may be 0 in case it's a reply without a matching request */ if (djiuav_tree && djiuav_trans) { if (is_cmd) { if (djiuav_trans->reply_frame) { proto_item *it; it = proto_tree_add_uint(djiuav_tree, hf_djiuav_response_in, tvb, 0, 0, djiuav_trans->reply_frame); PROTO_ITEM_SET_GENERATED(it); } } else { if (djiuav_trans->request_frame) { proto_item *it; nstime_t ns; it = proto_tree_add_uint(djiuav_tree, hf_djiuav_response_to, tvb, 0, 0, djiuav_trans->request_frame); PROTO_ITEM_SET_GENERATED(it); nstime_delta(&ns, &pinfo->fd->abs_ts, &djiuav_trans->request_time); it = proto_tree_add_time(djiuav_tree, hf_djiuav_response_time, tvb, 0, 0, &ns); PROTO_ITEM_SET_GENERATED(it); } } } }