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); }
// 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 void dissect_usb_i1d3_command( tvbuff_t *tvb, packet_info *pinfo, usb_i1d3_conversation_t *conversation, proto_tree *tree) { // Parsing the command code is a bit tricky: if the most significant // byte is non-zero, the command code is the most significant byte, // *and* the next byte is the first byte of the payload. guint32 command_code = tvb_get_ntohs(tvb, 0); guint32 command_code_msb = command_code & 0xff00; gint command_code_length = 2; if (command_code_msb) { command_code = command_code_msb; command_code_length = 1; } proto_item *command_code_item = proto_tree_add_uint( tree, hf_usb_i1d3_command_code, tvb, 0, command_code_length, command_code); usb_i1d3_transaction_t *transaction; if (!PINFO_FD_VISITED(pinfo)) { transaction = usb_i1d3_create_transaction(conversation, pinfo->num); transaction->command_code = command_code; } else { transaction = (usb_i1d3_transaction_t *)wmem_map_lookup( conversation->request_to_transaction, GUINT_TO_POINTER(pinfo->num)); } DISSECTOR_ASSERT(transaction); if (transaction->response != 0) { proto_item *response_item = proto_tree_add_uint( tree, hf_usb_i1d3_response_in, tvb, 0, 0, transaction->response); PROTO_ITEM_SET_GENERATED(response_item); } const gchar *command_code_string = try_val_to_str( command_code, usb_i1d3_command_code_strings); if (command_code_string) { col_set_str(pinfo->cinfo, COL_INFO, command_code_string); } else { expert_add_info(pinfo, command_code_item, &ei_usb_i1d3_unknown_command); col_set_str(pinfo->cinfo, COL_INFO, "Unknown command"); } switch (command_code) { case USB_I1D3_LOCKRESP: { // TODO: verify that the challenge response is correct proto_tree_add_item( tree, hf_usb_i1d3_challenge_response, tvb, 24, 16, ENC_NA); break; } case USB_I1D3_READINTEE: { guint32 offset, length; proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_readintee_offset, tvb, 1, 1, ENC_NA, &offset); proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_readintee_length, tvb, 2, 1, ENC_NA, &length); col_add_fstr(pinfo->cinfo, COL_INFO, "%s (offset: %u, length: %u)", command_code_string, offset, length); if (!PINFO_FD_VISITED(pinfo)) { transaction->offset = offset; transaction->length = length; } break; } case USB_I1D3_READEXTEE: { guint32 offset, length; proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_readextee_offset, tvb, 1, 2, ENC_BIG_ENDIAN, &offset); proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_readextee_length, tvb, 3, 1, ENC_NA, &length); col_add_fstr(pinfo->cinfo, COL_INFO, "%s (offset: %u, length: %u)", command_code_string, offset, length); if (!PINFO_FD_VISITED(pinfo)) { transaction->offset = offset; transaction->length = length; } break; } case USB_I1D3_MEASURE1: { guint32 integration_time; proto_item *integration_time_item = proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_requested_integration_time, tvb, 1, 4, ENC_LITTLE_ENDIAN, &integration_time); double integration_time_seconds = integration_time / USB_I1D3_CLOCK_FREQUENCY; proto_item_append_text( integration_time_item, " [%.6f seconds]", integration_time_seconds); col_add_fstr(pinfo->cinfo, COL_INFO, "Measure for %.6fs", integration_time_seconds); break; } case USB_I1D3_MEASURE2: { proto_item *edge_count_item = proto_tree_add_item( tree, hf_usb_i1d3_requested_edge_count, tvb, 1, 6, ENC_NA); proto_tree *edge_count_tree = proto_item_add_subtree( edge_count_item, ett_usb_i1d3_requested_edge_count); guint32 edge_count_red, edge_count_green, edge_count_blue; proto_tree_add_item_ret_uint( edge_count_tree, hf_usb_i1d3_requested_edge_count_red, tvb, 1, 2, ENC_LITTLE_ENDIAN, &edge_count_red); proto_tree_add_item_ret_uint( edge_count_tree, hf_usb_i1d3_requested_edge_count_green, tvb, 3, 2, ENC_LITTLE_ENDIAN, &edge_count_green); proto_tree_add_item_ret_uint( edge_count_tree, hf_usb_i1d3_requested_edge_count_blue, tvb, 5, 2, ENC_LITTLE_ENDIAN, &edge_count_blue); proto_item_append_text( edge_count_item, ": R%u G%u B%u", edge_count_red, edge_count_green, edge_count_blue); col_add_fstr(pinfo->cinfo, COL_INFO, "Measure R%u G%u B%u edges", edge_count_red, edge_count_green, edge_count_blue); break; } case USB_I1D3_SETLED: { guint32 led_mode, led_offtime, led_ontime, pulse_count; proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_led_mode, tvb, 1, 1, ENC_NA, &led_mode); proto_item *led_offtime_item = proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_led_offtime, tvb, 2, 1, ENC_NA, &led_offtime); double led_offtime_seconds = led_offtime / USB_I1D3_LED_OFFTIME_FACTOR; proto_item_append_text( led_offtime_item, " [%.6f seconds]", led_offtime_seconds); proto_item *led_ontime_item = proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_led_ontime, tvb, 3, 1, ENC_NA, &led_ontime); double led_ontime_seconds = led_ontime / ((led_mode == USB_I1D3_LED_BLINK) ? USB_I1D3_LED_ONTIME_FACTOR : USB_I1D3_LED_ONTIME_FADE_FACTOR); proto_item_append_text( led_ontime_item, " [%.6f seconds]", led_ontime_seconds); proto_item *pulse_count_item = proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_led_pulse_count, tvb, 4, 1, ENC_NA, &pulse_count); if (pulse_count == 0x80) { proto_item_append_text(pulse_count_item, " [infinity]"); col_add_fstr(pinfo->cinfo, COL_INFO, "Pulse LED off (%.6fs) and on (%.6fs%s) " "indefinitely", led_offtime_seconds, led_ontime_seconds, (led_mode == USB_I1D3_LED_BLINK_FADE_ON) ? " fading" : ""); } else { col_add_fstr(pinfo->cinfo, COL_INFO, "Pulse LED off (%.6fs) and on (%.6fs%s) " "%u times", led_offtime_seconds, led_ontime_seconds, (led_mode == USB_I1D3_LED_BLINK_FADE_ON) ? " fading" : "", pulse_count); } } } }
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 int ros_try_string(const char *oid, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, struct SESSION_DATA_STRUCTURE* session) { ros_info_t *rinfo; gint32 opcode_lcl = 0; const gchar *opname = NULL; const gchar *suffix = NULL; dissector_t opdissector = NULL; const value_string *lookup; proto_item *item=NULL; proto_tree *ros_tree=NULL; if((session != NULL) && (oid != NULL) && ((rinfo = (ros_info_t*)wmem_map_lookup(protocol_table, oid)) != NULL)) { if(tree){ item = proto_tree_add_item(tree, *(rinfo->proto), tvb, 0, -1, ENC_NA); ros_tree = proto_item_add_subtree(item, *(rinfo->ett_proto)); } col_set_str(pinfo->cinfo, COL_PROTOCOL, rinfo->name); /* if this is a bind operation */ if((session->ros_op & ROS_OP_TYPE_MASK) == ROS_OP_BIND) { /* use the in-built operation codes */ if((session->ros_op & ROS_OP_PDU_MASK) == ROS_OP_ERROR) opcode_lcl = err_ros_bind; else opcode_lcl = op_ros_bind; } else /* otherwise just take the opcode */ opcode_lcl = session->ros_op & ROS_OP_OPCODE_MASK; /* default lookup in the operations */ lookup = rinfo->opr_code_strings; switch(session->ros_op & ROS_OP_PDU_MASK) { case ROS_OP_ARGUMENT: opdissector = ros_lookup_opr_dissector(opcode_lcl, rinfo->opr_code_dissectors, TRUE); suffix = "_argument"; break; case ROS_OP_RESULT: opdissector = ros_lookup_opr_dissector(opcode_lcl, rinfo->opr_code_dissectors, FALSE); suffix = "_result"; break; case ROS_OP_ERROR: opdissector = ros_lookup_err_dissector(opcode_lcl, rinfo->err_code_dissectors); lookup = rinfo->err_code_strings; break; default: break; } if(opdissector) { opname = val_to_str(opcode_lcl, lookup, "Unknown opcode (%d)"); col_set_str(pinfo->cinfo, COL_INFO, opname); if(suffix) col_append_str(pinfo->cinfo, COL_INFO, suffix); return (*opdissector)(tvb, pinfo, ros_tree, NULL); } } return 0; }
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); } } } }