static void dissect_ata_pdu(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean response, guint32 tag) { proto_item *tmp_item; guint8 aflags; guint64 lba; ata_info_t *ata_info=NULL; conversation_t *conversation; /* only create a conversation for ATA commands */ conversation = find_or_create_conversation(pinfo); if( !(pinfo->fd->flags.visited) ){ if(!response){ ata_info_t *tmp_ata_info; /* first time we see this request so add a struct for request/response matching */ ata_info=wmem_new(wmem_file_scope(), ata_info_t); ata_info->tag=tag; ata_info->conversation=conversation; ata_info->request_frame=pinfo->fd->num; ata_info->response_frame=0; ata_info->cmd=tvb_get_guint8(tvb, offset+3); ata_info->req_time=pinfo->fd->abs_ts; tmp_ata_info=(ata_info_t *)g_hash_table_lookup(ata_cmd_unmatched, ata_info); if(tmp_ata_info){ g_hash_table_remove(ata_cmd_unmatched, tmp_ata_info); } g_hash_table_insert(ata_cmd_unmatched, ata_info, ata_info); } else { ata_info_t tmp_ata_info; /* first time we see this response so see if we can match it with a request */ tmp_ata_info.tag=tag; tmp_ata_info.conversation=conversation; ata_info=(ata_info_t *)g_hash_table_lookup(ata_cmd_unmatched, &tmp_ata_info); /* woo hoo we could, so no need to store this in unmatched any more, move both request and response to the matched table */ if(ata_info){ ata_info->response_frame=pinfo->fd->num; g_hash_table_remove(ata_cmd_unmatched, ata_info); g_hash_table_insert(ata_cmd_matched, GUINT_TO_POINTER(ata_info->request_frame), ata_info); g_hash_table_insert(ata_cmd_matched, GUINT_TO_POINTER(ata_info->response_frame), ata_info); } } } else { ata_info=(ata_info_t *)g_hash_table_lookup(ata_cmd_matched, GUINT_TO_POINTER(pinfo->fd->num)); } if(ata_info){ if(response){ if(ata_info->request_frame){ nstime_t delta_ts; tmp_item=proto_tree_add_uint(tree, hf_aoe_response_to, tvb, 0, 0, ata_info->request_frame); PROTO_ITEM_SET_GENERATED(tmp_item); nstime_delta(&delta_ts, &pinfo->fd->abs_ts, &ata_info->req_time); tmp_item=proto_tree_add_time(tree, hf_aoe_time, tvb, offset, 0, &delta_ts); PROTO_ITEM_SET_GENERATED(tmp_item); } } else { if(ata_info->response_frame){ tmp_item=proto_tree_add_uint(tree, hf_aoe_response_in, tvb, 0, 0, ata_info->response_frame); PROTO_ITEM_SET_GENERATED(tmp_item); } } } /* aflags */ aflags=tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_aoe_aflags_e, tvb, offset, 1, ENC_BIG_ENDIAN); if(aflags&AOE_AFLAGS_E){ proto_tree_add_item(tree, hf_aoe_aflags_d, tvb, offset, 1, ENC_BIG_ENDIAN); } if(aflags&AOE_AFLAGS_W){ proto_tree_add_item(tree, hf_aoe_aflags_a, tvb, offset, 1, ENC_BIG_ENDIAN); } proto_tree_add_item(tree, hf_aoe_aflags_w, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; /* err/feature */ proto_tree_add_item(tree, hf_aoe_err_feature, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; /* sector count */ proto_tree_add_item(tree, hf_aoe_sector_count, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; /* ata command/status */ if(!response){ proto_tree_add_item(tree, hf_aoe_acmd, tvb, offset, 1, ENC_BIG_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, " ATA:%s", val_to_str(tvb_get_guint8(tvb, offset), ata_cmd_vals, " Unknown ATA<0x%02x>")); } else { proto_tree_add_item(tree, hf_aoe_astatus, tvb, offset, 1, ENC_BIG_ENDIAN); if(ata_info != NULL && ata_info->request_frame){ /* we don't know what command it was unless we saw the request_frame */ tmp_item=proto_tree_add_uint(tree, hf_aoe_acmd, tvb, 0, 0, ata_info->cmd); PROTO_ITEM_SET_GENERATED(tmp_item); col_append_fstr(pinfo->cinfo, COL_INFO, " ATA:%s", val_to_str(ata_info->cmd, ata_cmd_vals, " Unknown ATA<0x%02x>")); } } offset++; /*lba probably complete wrong */ lba=tvb_get_letohs(tvb, offset+4); lba=(lba<<32)|tvb_get_letohl(tvb, offset); offset+=8; proto_tree_add_uint64(tree, hf_aoe_lba, tvb, offset-8, 6, lba); }
static void dissect_exec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Set up structures needed to add the protocol subtree and manage it */ proto_item *ti; proto_tree *exec_tree=NULL; /* Variables for extracting and displaying data from the packet */ guchar *field_stringz; /* Temporary storage for each field we extract */ gint length; guint offset = 0; conversation_t *conversation; exec_hash_entry_t *hash_info; conversation = find_or_create_conversation(pinfo); /* Retrieve information from conversation * or add it if it isn't there yet */ hash_info = (exec_hash_entry_t *)conversation_get_proto_data(conversation, proto_exec); if(!hash_info){ hash_info = wmem_new(wmem_file_scope(), exec_hash_entry_t); hash_info->first_packet_number = pinfo->fd->num; hash_info->second_packet_number = 0; hash_info->third_packet_number = 0; hash_info->fourth_packet_number = 0; hash_info->state = WAIT_FOR_STDERR_PORT; /* The first field we'll see */ /* Start with empty username and command strings */ hash_info->username=NULL; hash_info->command=NULL; /* These will be set on the first pass by the first * four packets of the conversation */ hash_info->first_packet_state = NONE; hash_info->second_packet_state = NONE; hash_info->third_packet_state = NONE; hash_info->fourth_packet_state = NONE; conversation_add_proto_data(conversation, proto_exec, hash_info); } /* Store the number of the first three packets of this conversation * as we reach them the first time */ if(!hash_info->second_packet_number && pinfo->fd->num > hash_info->first_packet_number){ /* We're on the second packet of the conversation */ hash_info->second_packet_number = pinfo->fd->num; } else if(hash_info->second_packet_number && !hash_info->third_packet_number && pinfo->fd->num > hash_info->second_packet_number) { /* We're on the third packet of the conversation */ hash_info->third_packet_number = pinfo->fd->num; } else if(hash_info->third_packet_number && !hash_info->fourth_packet_number && pinfo->fd->num > hash_info->third_packet_number) { /* We're on the fourth packet of the conversation */ hash_info->fourth_packet_number = pinfo->fd->num; } /* Save this packet's state so we can retrieve it if this packet * is selected again later. If the packet's state was already stored, * then retrieve it */ if(pinfo->fd->num == hash_info->first_packet_number){ if(hash_info->first_packet_state == NONE){ hash_info->first_packet_state = hash_info->state; } else { hash_info->state = hash_info->first_packet_state; } } if(pinfo->fd->num == hash_info->second_packet_number){ if(hash_info->second_packet_state == NONE){ hash_info->second_packet_state = hash_info->state; } else { hash_info->state = hash_info->second_packet_state; } } if(pinfo->fd->num == hash_info->third_packet_number){ if(hash_info->third_packet_state == NONE){ hash_info->third_packet_state = hash_info->state; } else { hash_info->state = hash_info->third_packet_state; } } if(pinfo->fd->num == hash_info->fourth_packet_number){ if(hash_info->fourth_packet_state == NONE){ hash_info->fourth_packet_state = hash_info->state; } else { hash_info->state = hash_info->fourth_packet_state; } } col_set_str(pinfo->cinfo, COL_PROTOCOL, "EXEC"); /* First, clear the info column */ col_clear(pinfo->cinfo, COL_INFO); /*username */ if(hash_info->username && preference_info_show_username == TRUE){ col_append_fstr(pinfo->cinfo, COL_INFO, "Username:%s ", hash_info->username); } /* Command */ if(hash_info->command && preference_info_show_command == TRUE){ col_append_fstr(pinfo->cinfo, COL_INFO, "Command:%s ", hash_info->command); } /* create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_exec, tvb, 0, -1, ENC_NA); exec_tree = proto_item_add_subtree(ti, ett_exec); /* If this packet doesn't end with a null terminated string, * then it must be session data only and we can skip looking * for the other fields. */ if(tvb_find_guint8(tvb, tvb_length(tvb)-1, 1, '\0') == -1){ hash_info->state = WAIT_FOR_DATA; } if(hash_info->state == WAIT_FOR_STDERR_PORT && tvb_length_remaining(tvb, offset)){ field_stringz = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII); /* Check if this looks like the stderr_port field. * It is optional, so it may only be 1 character long * (the NULL) */ if(length == 1 || (isdigit_string(field_stringz) && length <= EXEC_STDERR_PORT_LEN)){ proto_tree_add_string(exec_tree, hf_exec_stderr_port, tvb, offset, length, (gchar*)field_stringz); /* Next field we need */ hash_info->state = WAIT_FOR_USERNAME; } else { /* Since the data doesn't match this field, it must be data only */ hash_info->state = WAIT_FOR_DATA; } /* Used if the next field is in the same packet */ offset += length; } if(hash_info->state == WAIT_FOR_USERNAME && tvb_length_remaining(tvb, offset)){ field_stringz = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII); /* Check if this looks like the username field */ if(length != 1 && length <= EXEC_USERNAME_LEN && isprint_string(field_stringz)){ proto_tree_add_string(exec_tree, hf_exec_username, tvb, offset, length, (gchar*)field_stringz); /* Store the username so we can display it in the * info column of the entire conversation */ if(!hash_info->username){ hash_info->username=wmem_strdup(wmem_file_scope(), (gchar*)field_stringz); } /* Next field we need */ hash_info->state = WAIT_FOR_PASSWORD; } else { /* Since the data doesn't match this field, it must be data only */ hash_info->state = WAIT_FOR_DATA; } /* Used if the next field is in the same packet */ offset += length; } if(hash_info->state == WAIT_FOR_PASSWORD && tvb_length_remaining(tvb, offset)){ field_stringz = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII); /* Check if this looks like the password field */ if(length != 1 && length <= EXEC_PASSWORD_LEN && isprint_string(field_stringz)){ proto_tree_add_string(exec_tree, hf_exec_password, tvb, offset, length, (gchar*)field_stringz); /* Next field we need */ hash_info->state = WAIT_FOR_COMMAND; } else { /* Since the data doesn't match this field, it must be data only */ hash_info->state = WAIT_FOR_DATA; } /* Used if the next field is in the same packet */ offset += length; /* Next field we are looking for */ hash_info->state = WAIT_FOR_COMMAND; } if(hash_info->state == WAIT_FOR_COMMAND && tvb_length_remaining(tvb, offset)){ field_stringz = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII); /* Check if this looks like the command field */ if(length != 1 && length <= EXEC_COMMAND_LEN && isprint_string(field_stringz)){ proto_tree_add_string(exec_tree, hf_exec_command, tvb, offset, length, (gchar*)field_stringz); /* Store the command so we can display it in the * info column of the entire conversation */ if(!hash_info->command){ hash_info->command=wmem_strdup(wmem_file_scope(), (gchar*)field_stringz); } } else { /* Since the data doesn't match this field, it must be data only */ hash_info->state = WAIT_FOR_DATA; } } if(hash_info->state == WAIT_FOR_DATA && tvb_length_remaining(tvb, offset)){ if(pinfo->destport == EXEC_PORT){ /* Packet going to the server */ /* offset = 0 since the whole packet is data */ proto_tree_add_item(exec_tree, hf_exec_client_server_data, tvb, 0, -1, ENC_NA); col_append_str(pinfo->cinfo, COL_INFO, "Client -> Server data"); } else { /* This packet must be going back to the client */ /* offset = 0 since the whole packet is data */ proto_tree_add_item(exec_tree, hf_exec_server_client_data, tvb, 0, -1, ENC_NA); col_append_str(pinfo->cinfo, COL_INFO, "Server -> Client Data"); } } /* We haven't seen all of the fields yet */ if(hash_info->state < WAIT_FOR_DATA){ col_set_str(pinfo->cinfo, COL_INFO, "Session Establishment"); } }
void xmpp_iq(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet) { proto_item *xmpp_iq_item; proto_tree *xmpp_iq_tree; xmpp_attr_t *attr_id, *attr_type; xmpp_attr_info attrs_info[] = { {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL}, {"id", hf_xmpp_id, TRUE, TRUE, NULL, NULL}, {"type", hf_xmpp_type, TRUE, TRUE, NULL, NULL}, {"from", hf_xmpp_from, FALSE, TRUE, NULL, NULL}, {"to", hf_xmpp_to, FALSE, TRUE, NULL, NULL}, {"xml:lang", -1, FALSE, FALSE, NULL, NULL} }; conversation_t *conversation; xmpp_conv_info_t *xmpp_info; xmpp_transaction_t *reqresp_trans; xmpp_elem_info elems_info [] = { {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","http://jabber.org/protocol/disco#items"), xmpp_disco_items_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "jabber:iq:roster"), xmpp_roster_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/disco#info"), xmpp_disco_info_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/bytestreams"), xmpp_bytestreams_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/muc#owner"), xmpp_muc_owner_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/muc#admin"), xmpp_muc_admin_query, ONE}, {NAME, "bind", xmpp_iq_bind, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("session", "xmlns", "urn:ietf:params:xml:ns:xmpp-session"), xmpp_session, ONE}, {NAME, "vCard", xmpp_vcard, ONE}, {NAME, "jingle", xmpp_jingle, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("services", "xmlns", "http://jabber.org/protocol/jinglenodes"), xmpp_jinglenodes_services, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("channel", "xmlns", "http://jabber.org/protocol/jinglenodes#channel"), xmpp_jinglenodes_channel, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("open", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_open, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("close", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_close, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("data", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_data, ONE}, {NAME, "si", xmpp_si, ONE}, {NAME, "error", xmpp_error, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("session", "xmlns", "http://www.google.com/session"), xmpp_gtalk_session, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","google:jingleinfo"), xmpp_gtalk_jingleinfo_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("usersetting", "xmlns","google:setting"), xmpp_gtalk_usersetting, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","jabber:iq:last"), xmpp_last_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","jabber:iq:version"), xmpp_version_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","google:mail:notify"), xmpp_gtalk_mail_query, ONE}, {NAME, "mailbox", xmpp_gtalk_mail_mailbox, ONE}, {NAME, "new-mail", xmpp_gtalk_mail_new_mail, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","google:shared-status"), xmpp_gtalk_status_query, ONE}, {NAME, "conference-info", xmpp_conference_info, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("ping", "xmlns","urn:xmpp:ping"), xmpp_ping, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("inputevt", "xmlns","http://jitsi.org/protocol/inputevt"), xmpp_jitsi_inputevt, ONE}, }; attr_id = xmpp_get_attr(packet, "id"); attr_type = xmpp_get_attr(packet, "type"); conversation = find_or_create_conversation(pinfo); xmpp_info = (xmpp_conv_info_t *)conversation_get_proto_data(conversation, proto_xmpp); xmpp_iq_item = proto_tree_add_item(tree, hf_xmpp_iq, tvb, packet->offset, packet->length, ENC_LITTLE_ENDIAN); xmpp_iq_tree = proto_item_add_subtree(xmpp_iq_item,ett_xmpp_iq); xmpp_display_attrs(xmpp_iq_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info)); col_clear(pinfo->cinfo, COL_INFO); col_add_fstr(pinfo->cinfo, COL_INFO, "IQ(%s) ", attr_type?attr_type->value:""); xmpp_display_elems(xmpp_iq_tree, packet, pinfo, tvb, elems_info, array_length(elems_info)); /*displays generated info such as req/resp tracking, jingle sid * in each packet related to specified jingle session and IBB sid in packet related to it*/ if(xmpp_info && attr_id) { gchar *jingle_sid, *ibb_sid, *gtalk_sid; jingle_sid = (gchar *)wmem_tree_lookup_string(xmpp_info->jingle_sessions, attr_id->value, WMEM_TREE_STRING_NOCASE); if (jingle_sid) { proto_item *it = proto_tree_add_string(tree, hf_xmpp_jingle_session, tvb, 0, 0, jingle_sid); PROTO_ITEM_SET_GENERATED(it); } ibb_sid = (gchar *)wmem_tree_lookup_string(xmpp_info->ibb_sessions, attr_id->value, WMEM_TREE_STRING_NOCASE); if (ibb_sid) { proto_item *it = proto_tree_add_string(tree, hf_xmpp_ibb, tvb, 0, 0, ibb_sid); PROTO_ITEM_SET_GENERATED(it); } gtalk_sid = (gchar *)wmem_tree_lookup_string(xmpp_info->gtalk_sessions, attr_id->value, WMEM_TREE_STRING_NOCASE); if (gtalk_sid) { proto_item *it = proto_tree_add_string(tree, hf_xmpp_gtalk, tvb, 0, 0, gtalk_sid); PROTO_ITEM_SET_GENERATED(it); } reqresp_trans = (xmpp_transaction_t *)wmem_tree_lookup_string(xmpp_info->req_resp, attr_id->value, WMEM_TREE_STRING_NOCASE); /*displays request/response field in each iq packet*/ if (reqresp_trans) { if (reqresp_trans->req_frame == pinfo->fd->num) { if (reqresp_trans->resp_frame) { proto_item *it = proto_tree_add_uint(tree, hf_xmpp_response_in, tvb, 0, 0, reqresp_trans->resp_frame); PROTO_ITEM_SET_GENERATED(it); } else { expert_add_info(pinfo, xmpp_iq_item, &ei_xmpp_packet_without_response); } } else { if (reqresp_trans->req_frame) { proto_item *it = proto_tree_add_uint(tree, hf_xmpp_response_to, tvb, 0, 0, reqresp_trans->req_frame); PROTO_ITEM_SET_GENERATED(it); } else { expert_add_info(pinfo, xmpp_iq_item, &ei_xmpp_packet_without_response); } } } } }
void xmpp_message(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet) { proto_item *message_item; proto_tree *message_tree; static const gchar *type_enums[] = {"chat", "error", "groupchat", "headline", "normal"}; xmpp_array_t *type_array = xmpp_ep_init_array_t(type_enums, array_length(type_enums)); xmpp_attr_info attrs_info[] = { {"from", hf_xmpp_from, FALSE, FALSE, NULL, NULL}, {"id", hf_xmpp_id, FALSE, TRUE, NULL, NULL}, {"to", hf_xmpp_to, FALSE, FALSE, NULL, NULL}, {"type", hf_xmpp_type, FALSE, TRUE, xmpp_val_enum_list, type_array}, {"xml:lang",-1, FALSE, FALSE, NULL,NULL}, {"chatstate", hf_xmpp_message_chatstate, FALSE, TRUE, NULL, NULL} }; xmpp_elem_info elems_info [] = { {NAME_AND_ATTR, xmpp_name_attr_struct("data", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_data, ONE}, {NAME, "thread", xmpp_message_thread, ONE}, {NAME, "body", xmpp_message_body, MANY}, {NAME, "subject", xmpp_message_subject, MANY}, {NAME, "delay", xmpp_delay, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","jabber:x:event"), xmpp_x_event, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","http://jabber.org/protocol/muc#user"), xmpp_muc_user_x, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","google:nosave"), xmpp_gtalk_nosave_x, ONE}, {NAME, "error", xmpp_error, ONE} }; xmpp_element_t *chatstate; xmpp_attr_t *id; conversation_t *conversation; xmpp_conv_info_t *xmpp_info; col_clear(pinfo->cinfo, COL_INFO); col_append_fstr(pinfo->cinfo, COL_INFO, "MESSAGE "); id = xmpp_get_attr(packet, "id"); conversation = find_or_create_conversation(pinfo); xmpp_info = (xmpp_conv_info_t *)conversation_get_proto_data(conversation, proto_xmpp); message_item = proto_tree_add_item(tree, hf_xmpp_message, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN); message_tree = proto_item_add_subtree(message_item, ett_xmpp_message); if((chatstate = xmpp_steal_element_by_attr(packet, "xmlns", "http://jabber.org/protocol/chatstates"))!=NULL) { xmpp_attr_t *fake_chatstate_attr = xmpp_ep_init_attr_t(chatstate->name, chatstate->offset, chatstate->length); g_hash_table_insert(packet->attrs, (gpointer)"chatstate", fake_chatstate_attr); } xmpp_display_attrs(message_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info)); xmpp_display_elems(message_tree, packet, pinfo, tvb, elems_info, array_length(elems_info)); /*Displays data about IBB session*/ if(xmpp_info && id) { gchar *ibb_sid; ibb_sid = (gchar *)wmem_tree_lookup_string(xmpp_info->ibb_sessions, id->value, WMEM_TREE_STRING_NOCASE); if (ibb_sid) { proto_item *it = proto_tree_add_string(tree, hf_xmpp_ibb, tvb, 0, 0, ibb_sid); PROTO_ITEM_SET_GENERATED(it); } } }
static void dissect_smb_direct_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 remaining_length) { gboolean save_fragmented = pinfo->fragmented; int save_visited = pinfo->fd->flags.visited; conversation_t *conversation = NULL; fragment_head *fd_head = NULL; tvbuff_t *payload_tvb = NULL; gboolean more_frags = FALSE; gboolean fd_head_not_cached = FALSE; heur_dtbl_entry_t *hdtbl_entry; if (!smb_direct_reassemble) { payload_tvb = tvb; goto dissect_payload; } conversation = find_or_create_conversation(pinfo); if (remaining_length > 0) { more_frags = TRUE; } fd_head = (fragment_head *)p_get_proto_data(wmem_file_scope(), pinfo, proto_smb_direct, 0); if (fd_head == NULL) { fd_head_not_cached = TRUE; pinfo->fd->flags.visited = 0; fd_head = fragment_add_seq_next(&smb_direct_reassembly_table, tvb, 0, pinfo, conversation->index, NULL, tvb_captured_length(tvb), more_frags); } if (fd_head == NULL) { /* * We really want the fd_head and pass it to * process_reassembled_data() * * So that individual fragments gets the * reassembled in field. */ fd_head = fragment_get_reassembled_id(&smb_direct_reassembly_table, pinfo, conversation->index); } if (fd_head == NULL) { /* * we need more data... */ goto done; } if (fd_head_not_cached) { p_add_proto_data(wmem_file_scope(), pinfo, proto_smb_direct, 0, fd_head); } payload_tvb = process_reassembled_data(tvb, 0, pinfo, "Reassembled SMB Direct", fd_head, &smb_direct_frag_items, NULL, /* update_col_info*/ tree); if (payload_tvb == NULL) { /* * we need more data... */ goto done; } dissect_payload: pinfo->fragmented = FALSE; if (!dissector_try_heuristic(smb_direct_heur_subdissector_list, payload_tvb, pinfo, tree, &hdtbl_entry, NULL)) { call_data_dissector(payload_tvb, pinfo, tree); } done: pinfo->fragmented = save_fragmented; pinfo->fd->flags.visited = save_visited; return; }
static void adwin_request_response_handling(tvbuff_t *tvb, packet_info *pinfo, proto_tree *adwin_tree, guint32 seq_num, adwin_direction_t direction) { conversation_t *conversation; adwin_conv_info_t *adwin_info; adwin_transaction_t *adwin_trans; /* * Find or create a conversation for this connection. */ conversation = find_or_create_conversation(pinfo); /* * Do we already have a state structure for this conv */ adwin_info = (adwin_conv_info_t *)conversation_get_proto_data(conversation, proto_adwin); if (!adwin_info) { /* * No. Attach that information to the conversation, and add * it to the list of information structures. */ adwin_info = se_new(adwin_conv_info_t); adwin_info->pdus = se_tree_create_non_persistent( EMEM_TREE_TYPE_RED_BLACK, "adwin_pdus"); conversation_add_proto_data(conversation, proto_adwin, adwin_info); } if (!pinfo->fd->flags.visited) { if (direction == ADWIN_REQUEST) { /* This is a request */ adwin_trans = se_new(adwin_transaction_t); adwin_trans->req_frame = pinfo->fd->num; adwin_trans->rep_frame = 0; adwin_trans->req_time = pinfo->fd->abs_ts; se_tree_insert32(adwin_info->pdus, seq_num, (void *)adwin_trans); } else { adwin_trans = (adwin_transaction_t *)se_tree_lookup32(adwin_info->pdus, seq_num); if (adwin_trans) { adwin_trans->rep_frame = pinfo->fd->num; } } } else { adwin_trans = (adwin_transaction_t *)se_tree_lookup32(adwin_info->pdus, seq_num); } if (!adwin_trans) { /* create a "fake" adwin_trans structure */ adwin_trans = wmem_new(wmem_packet_scope(), adwin_transaction_t); adwin_trans->req_frame = 0; adwin_trans->rep_frame = 0; adwin_trans->req_time = pinfo->fd->abs_ts; } /* print state tracking in the tree */ if (direction == ADWIN_REQUEST) { /* This is a request */ if (adwin_trans->rep_frame) { proto_item *it; it = proto_tree_add_uint(adwin_tree, hf_adwin_response_in, tvb, 0, 0, adwin_trans->rep_frame); PROTO_ITEM_SET_GENERATED(it); } } else { /* This is a reply */ if (adwin_trans->req_frame) { proto_item *it; nstime_t ns; it = proto_tree_add_uint(adwin_tree, hf_adwin_response_to, tvb, 0, 0, adwin_trans->req_frame); PROTO_ITEM_SET_GENERATED(it); nstime_delta(&ns, &pinfo->fd->abs_ts, &adwin_trans->req_time); it = proto_tree_add_time(adwin_tree, hf_adwin_response_time, tvb, 0, 0, &ns); PROTO_ITEM_SET_GENERATED(it); } } }
/* main dissector function. wireshark calls it for segments in both * directions. */ static void dissect_ajp13_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint16 mag; /* guint16 len; */ conversation_t *conv = NULL; ajp13_conv_data *cd = NULL; proto_tree *ajp13_tree = NULL; ajp13_frame_data* fd = NULL; /* conversational state really only does us good during the first * in-order traversal */ conv = find_or_create_conversation(pinfo); cd = (ajp13_conv_data*)conversation_get_proto_data(conv, proto_ajp13); if (!cd) { cd = se_new(ajp13_conv_data); cd->content_length = 0; cd->was_get_body_chunk = FALSE; conversation_add_proto_data(conv, proto_ajp13, cd); } /* we use the per segment user data to record the conversational * state for use later on when we're called out of order (see * comments at top of this file) */ fd = (ajp13_frame_data*)p_get_proto_data(pinfo->fd, proto_ajp13); if (!fd) { /*printf("ajp13:dissect_ajp13_common():no frame data, adding");*/ /* since there's no per-packet user data, this must be the first * time we've see the packet, and it must be the first "in order" * pass through the data. */ fd = se_new(ajp13_frame_data); p_add_proto_data(pinfo->fd, proto_ajp13, fd); fd->is_request_body = FALSE; if (cd->content_length) { /* this is screwy, see AJPv13.html. the idea is that if the * request has a body (as determined by the content-length * header), then there's always an immediate follow-up PDU with * no GET_BODY_CHUNK from the container. */ fd->is_request_body = TRUE; } } col_clear(pinfo->cinfo, COL_INFO); mag = tvb_get_ntohs(tvb, 0); /* len = tvb_get_ntohs(tvb, 2); */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "AJP13"); if (mag == 0x1234 && !fd->is_request_body) col_append_fstr(pinfo->cinfo, COL_INFO, "%d:REQ:", conv->index); else if (mag == 0x1234 && fd->is_request_body) col_append_fstr(pinfo->cinfo, COL_INFO, "%d:REQ:Body", conv->index); else if (mag == 0x4142) col_append_fstr(pinfo->cinfo, COL_INFO, "%d:RSP:", conv->index); else col_set_str(pinfo->cinfo, COL_INFO, "AJP13 Error?"); if (tree) { proto_item *ti; ti = proto_tree_add_item(tree, proto_ajp13, tvb, 0, -1, ENC_NA); ajp13_tree = proto_item_add_subtree(ti, ett_ajp13); } if (mag == 0x1234) { if (fd->is_request_body) display_req_body(tvb, ajp13_tree, cd); else display_req_forward(tvb, pinfo, ajp13_tree, cd); } else if (mag == 0x4142) { display_rsp(tvb, pinfo, ajp13_tree, cd); } }