/* XXX - We depend on the UDP dissector finding the conversation first */ void add_udp_process_info(guint32 frame_num, address *local_addr, address *remote_addr, guint16 local_port, guint16 remote_port, guint32 uid, guint32 pid, gchar *username, gchar *command) { conversation_t *conv; struct udp_analysis *udpd; udp_flow_t *flow = NULL; if (!udp_process_info) { return; } conv = find_conversation(frame_num, local_addr, remote_addr, PT_UDP, local_port, remote_port, 0); if (!conv) { return; } udpd = (struct udp_analysis *)conversation_get_proto_data(conv, hfi_udp->id); if (!udpd) { return; } if ((CMP_ADDRESS(local_addr, &conv->key_ptr->addr1) == 0) && (local_port == conv->key_ptr->port1)) { flow = &udpd->flow1; } else if ((CMP_ADDRESS(remote_addr, &conv->key_ptr->addr1) == 0) && (remote_port == conv->key_ptr->port1)) { flow = &udpd->flow2; } if (!flow || flow->command) { return; } flow->process_uid = uid; flow->process_pid = pid; flow->username = wmem_strdup(wmem_file_scope(), username); flow->command = wmem_strdup(wmem_file_scope(), command); }
void xmpp_jingle_session_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info) { xmpp_element_t *jingle_packet; GList *jingle_packet_l; jingle_packet_l = xmpp_find_element_by_name(packet,"jingle"); jingle_packet = (xmpp_element_t *)(jingle_packet_l?jingle_packet_l->data:NULL); if (jingle_packet && !pinfo->fd->flags.visited) { xmpp_attr_t *attr_id; xmpp_attr_t *attr_sid; char *se_id; char *se_sid; attr_id = xmpp_get_attr(packet, "id"); if (!attr_id) { return; } attr_sid = xmpp_get_attr(jingle_packet, "sid"); if (!attr_sid) { return; } se_id = wmem_strdup(wmem_file_scope(), attr_id->value); se_sid = wmem_strdup(wmem_file_scope(), attr_sid->value); wmem_tree_insert_string(xmpp_info->jingle_sessions, se_id, (void*) se_sid, WMEM_TREE_STRING_NOCASE); } }
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; }
/* returns the command name */ static const gchar * csm_fc(guint16 fc, guint16 ct) { if (fc == 0x0000) { return wmem_strdup(wmem_packet_scope(), val_to_str(ct, class_type_vals, "0x%04x")); } else { return wmem_strdup(wmem_packet_scope(), val_to_str(fc, function_code_vals, "0x%04x")); } }
static void wmem_test_strutls(void) { wmem_allocator_t *allocator; const char *orig_str; char *new_str; char **split_str; allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT); orig_str = "TEST1"; new_str = wmem_strdup(allocator, orig_str); g_assert_cmpstr(new_str, ==, orig_str); new_str[0] = 'X'; g_assert_cmpstr(new_str, >, orig_str); wmem_strict_check_canaries(allocator); orig_str = "TEST123456789"; new_str = wmem_strndup(allocator, orig_str, 6); g_assert_cmpstr(new_str, ==, "TEST12"); g_assert_cmpstr(new_str, <, orig_str); new_str[0] = 'X'; g_assert_cmpstr(new_str, >, orig_str); wmem_strict_check_canaries(allocator); new_str = wmem_strdup_printf(allocator, "abc %s %% %d", "boo", 23); g_assert_cmpstr(new_str, ==, "abc boo % 23"); new_str = wmem_strdup_printf(allocator, "%s", STRING_80); g_assert_cmpstr(new_str, ==, STRING_80); wmem_strict_check_canaries(allocator); new_str = wmem_strconcat(allocator, "ABC", NULL); g_assert_cmpstr(new_str, ==, "ABC"); new_str = wmem_strconcat(allocator, "ABC", "DEF", NULL); g_assert_cmpstr(new_str, ==, "ABCDEF"); wmem_strict_check_canaries(allocator); new_str = wmem_strconcat(allocator, "", "", "ABCDEF", "", "GH", NULL); g_assert_cmpstr(new_str, ==, "ABCDEFGH"); wmem_strict_check_canaries(allocator); split_str = wmem_strsplit(allocator, "A-C", "-", 2); g_assert_cmpstr(split_str[0], ==, "A"); g_assert_cmpstr(split_str[1], ==, "C"); split_str = wmem_strsplit(allocator, "--aslkf-asio--asfj-as--", "-", 10); g_assert_cmpstr(split_str[0], ==, "aslkf"); g_assert_cmpstr(split_str[1], ==, "asio"); g_assert_cmpstr(split_str[2], ==, "asfj"); g_assert_cmpstr(split_str[3], ==, "as"); split_str = wmem_strsplit(allocator, "--aslkf-asio--asfj-as--", "-", 4); g_assert_cmpstr(split_str[0], ==, "aslkf"); g_assert_cmpstr(split_str[1], ==, "asio"); g_assert_cmpstr(split_str[2], ==, "-asfj-as--"); wmem_strict_check_canaries(allocator); orig_str = "TeStAsCiIsTrDoWn"; new_str = wmem_ascii_strdown(allocator, orig_str, -1); g_assert_cmpstr(new_str, ==, "testasciistrdown"); wmem_destroy_allocator(allocator); }
/* expects that *result is NULL */ static void ssh_choose_algo(gchar *client, gchar *server, gchar **result) { gchar **server_strings=NULL; gchar **client_strings=NULL; gchar **step; GSList *server_list = NULL; if (!client || !server || !result || *result) return; server_strings = g_strsplit(server, ",", 0); for (step = server_strings; *step; step++) { server_list = g_slist_append(server_list, *step); } client_strings = g_strsplit(client, ",", 0); for (step = client_strings; *step; step++) { GSList *agreed; if ((agreed=g_slist_find_custom(server_list, *step, ssh_gslist_compare_strings))) { *result = wmem_strdup(wmem_file_scope(), (const gchar *)agreed->data); break; } } g_strfreev(client_strings); g_slist_free(server_list); g_strfreev(server_strings); }
void xmpp_ibb_session_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info) { xmpp_element_t *ibb_packet = NULL; GList *ibb_packet_l; if(strcmp(packet->name, "message") == 0) { ibb_packet_l = xmpp_find_element_by_name(packet,"data"); ibb_packet = (xmpp_element_t *)(ibb_packet_l?ibb_packet_l->data:NULL); } else if(strcmp(packet->name, "iq") == 0) { ibb_packet_l = xmpp_find_element_by_name(packet,"open"); if(!ibb_packet_l) ibb_packet_l = xmpp_find_element_by_name(packet,"close"); if(!ibb_packet_l) ibb_packet_l = xmpp_find_element_by_name(packet,"data"); ibb_packet = (xmpp_element_t *)(ibb_packet_l?ibb_packet_l->data:NULL); } if (ibb_packet && !pinfo->fd->flags.visited) { xmpp_attr_t *attr_id; xmpp_attr_t *attr_sid; char *se_id; char *se_sid; attr_id = xmpp_get_attr(packet, "id"); attr_sid = xmpp_get_attr(ibb_packet, "sid"); if(attr_id && attr_sid) { se_id = wmem_strdup(wmem_file_scope(), attr_id->value); se_sid = wmem_strdup(wmem_file_scope(), attr_sid->value); wmem_tree_insert_string(xmpp_info->ibb_sessions, se_id, (void*) se_sid, WMEM_TREE_STRING_NOCASE); } } }
gchar * val64_to_str_ext_wmem(wmem_allocator_t *scope, const guint64 val, val64_string_ext *vse, const char *fmt) { const gchar *ret; DISSECTOR_ASSERT(fmt != NULL); ret = try_val64_to_str_ext(val, vse); if (ret != NULL) return wmem_strdup(scope, ret); return wmem_strdup_printf(scope, fmt, val); }
gchar * val_to_str_wmem(wmem_allocator_t *scope, const guint32 val, const value_string *vs, const char *fmt) { const gchar *ret; DISSECTOR_ASSERT(fmt != NULL); ret = try_val_to_str(val, vs); if (ret != NULL) return wmem_strdup(scope, ret); return wmem_strdup_printf(scope, fmt, val); }
/* Like val_to_str, but tries to find a prefix (instead of an exact) match of any prefix from the bytes_string array bs against the haystack. */ const gchar * bytesprefix_to_str(const guint8 *haystack, const size_t haystack_len, const bytes_string *bs, const char *fmt) { const gchar *ret; DISSECTOR_ASSERT(fmt != NULL); ret = try_bytesprefix_to_str(haystack, haystack_len, bs); if (ret != NULL) return ret; /* XXX See note at bytesval_to_str. */ return wmem_strdup(wmem_packet_scope(), fmt); }
void xmpp_gtalk_session_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info) { xmpp_element_t *gtalk_packet; GList *gtalk_packet_l; gtalk_packet_l = xmpp_find_element_by_name(packet,"session"); gtalk_packet = (xmpp_element_t *)(gtalk_packet_l?gtalk_packet_l->data:NULL); if (gtalk_packet && !pinfo->fd->flags.visited) { xmpp_attr_t *attr_id; xmpp_attr_t *attr_sid; char *se_id; char *se_sid; xmpp_attr_t *xmlns = xmpp_get_attr(gtalk_packet, "xmlns"); if(xmlns && strcmp(xmlns->value,"http://www.google.com/session") != 0) return; attr_id = xmpp_get_attr(packet, "id"); if (!attr_id) { return; } attr_sid = xmpp_get_attr(gtalk_packet, "id"); if (!attr_sid) { return; } se_id = wmem_strdup(wmem_file_scope(), attr_id->value); se_sid = wmem_strdup(wmem_file_scope(), attr_sid->value); wmem_tree_insert_string(xmpp_info->gtalk_sessions, se_id, (void*) se_sid, WMEM_TREE_STRING_NOCASE); } }
void xmpp_iq_reqresp_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info) { xmpp_transaction_t *xmpp_trans = NULL; xmpp_attr_t *attr_id; char *id; attr_id = xmpp_get_attr(packet, "id"); if (!attr_id) { return; } id = wmem_strdup(wmem_packet_scope(), attr_id->value); if (!pinfo->fd->flags.visited) { xmpp_trans = (xmpp_transaction_t *)wmem_tree_lookup_string(xmpp_info->req_resp, id, WMEM_TREE_STRING_NOCASE); if (xmpp_trans) { xmpp_trans->resp_frame = pinfo->fd->num; } else { char *se_id = wmem_strdup(wmem_file_scope(), id); xmpp_trans = wmem_new(wmem_file_scope(), xmpp_transaction_t); xmpp_trans->req_frame = pinfo->fd->num; xmpp_trans->resp_frame = 0; wmem_tree_insert_string(xmpp_info->req_resp, se_id, (void *) xmpp_trans, WMEM_TREE_STRING_NOCASE); } } else { wmem_tree_lookup_string(xmpp_info->req_resp, id, WMEM_TREE_STRING_NOCASE); } }
static int call_idmp_oid_callback(tvbuff_t *tvb, int offset, packet_info *pinfo, int op, proto_tree *tree, struct SESSION_DATA_STRUCTURE *session) { if(session != NULL) { if((!saved_protocolID) && (op == (ROS_OP_BIND | ROS_OP_RESULT))) { /* save for subsequent operations - should be into session data */ saved_protocolID = wmem_strdup(wmem_file_scope(), protocolID); } /* mimic ROS! */ session->ros_op = op; offset = call_ros_oid_callback(saved_protocolID ? saved_protocolID : protocolID, tvb, offset, pinfo, tree, session); } return offset; }
static void xmpp_error(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element) { proto_item *error_item; proto_tree *error_tree; xmpp_element_t *text_element, *cond_element; xmpp_attr_info attrs_info[] = { {"type", &hf_xmpp_error_type, TRUE, TRUE, NULL, NULL}, {"code", &hf_xmpp_error_code, FALSE, TRUE, NULL, NULL}, {"condition", &hf_xmpp_error_condition, TRUE, TRUE, NULL, NULL} /*TODO: validate list to the condition element*/ }; gchar *error_info; xmpp_attr_t *fake_condition = NULL; error_info = wmem_strdup(wmem_packet_scope(), "Stanza error"); error_item = proto_tree_add_item(tree, hf_xmpp_error, tvb, element->offset, element->length, ENC_BIG_ENDIAN); error_tree = proto_item_add_subtree(error_item, ett_xmpp_query_item); cond_element = xmpp_steal_element_by_attr(element, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas"); if(cond_element) { fake_condition = xmpp_ep_init_attr_t(cond_element->name, cond_element->offset, cond_element->length); g_hash_table_insert(element->attrs, (gpointer)"condition", fake_condition); error_info = wmem_strdup_printf(wmem_packet_scope(), "%s: %s;", error_info, cond_element->name); } xmpp_display_attrs(error_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info)); while((text_element = xmpp_steal_element_by_name(element, "text")) != NULL) { xmpp_error_text(error_tree, tvb, text_element); error_info = wmem_strdup_printf(wmem_packet_scope(), "%s Text: %s", error_info, text_element->data?text_element->data->value:""); } expert_add_info_format(pinfo, error_item, &ei_xmpp_response, "%s", error_info); xmpp_unknown(error_tree, tvb, pinfo, element); }
/* Like val_to_str except for bytes_string */ const gchar * bytesval_to_str(const guint8 *val, const size_t val_len, const bytes_string *bs, const char *fmt) { const gchar *ret; DISSECTOR_ASSERT(fmt != NULL); ret = try_bytesval_to_str(val, val_len, bs); if (ret != NULL) return ret; /* * XXX should this use bytes_to_str as format parameter for consistency? * Though for bytes I guess most of the time you want to show "Unknown" * anyway rather than "Unknown (\x13\x37...)" */ return wmem_strdup(wmem_packet_scope(), fmt); }
void register_stat_tap_ui(stat_tap_ui *ui, void *userdata) { stat_cmd_arg *newsca; if (stat_cmd_arg_list == NULL) stat_cmd_arg_list = wmem_list_new(wmem_epan_scope()); /* Key is already present */ if (wmem_list_find_custom(stat_cmd_arg_list, ui->cli_string, search_duplicate)) return; newsca = wmem_new(wmem_epan_scope(), stat_cmd_arg); newsca->cmd= wmem_strdup(wmem_epan_scope(), ui->cli_string); newsca->func=ui->tap_init_cb; newsca->userdata=userdata; wmem_list_insert_sorted(stat_cmd_arg_list, newsca, sort_by_name); }
static void ssh_set_mac_length(struct ssh_peer_data *peer_data) { char *size_str; guint size=0; char *mac_name = peer_data->mac; char *strip; if (!mac_name) return; mac_name = wmem_strdup(NULL, (const gchar *)mac_name); if (!mac_name) return; /* strip trailing "*****@*****.**" or "@openssh.com" */ strip = strstr(mac_name, "*****@*****.**"); if (strip) { peer_data->length_is_plaintext = 1; *strip = '\0'; } else { strip = strstr(mac_name, "@openssh.com"); if (strip) *strip = '\0'; } if ((size_str=g_strrstr(mac_name, "-")) && ((size=atoi(size_str+1)))) { peer_data->mac_length = (size > 0) ? size / 8 : 0; } else if (strcmp(mac_name, "hmac-sha1") == 0) { peer_data->mac_length = 20; } else if (strcmp(mac_name, "hmac-md5") == 0) { peer_data->mac_length = 16; } else if (strcmp(mac_name, "hmac-ripemd160") == 0) { peer_data->mac_length = 20; } else if (strcmp(mac_name, "none") == 0) { peer_data->mac_length = 0; } wmem_free(NULL, mac_name); }
static void Cmd_TokenizeString(const char* text) { int start; cmd_argc = 0; start = 0; while (TRUE) { /* skip whitespace up to a \n */ while (*text && *text <= ' ' && *text != '\n') { text++; start++; } if (*text == '\n') { /* a newline seperates commands in the buffer */ text++; break; } if (!*text) return; text = COM_Parse (text); if (!text) return; if (cmd_argc < MAX_ARGS) { cmd_argv[cmd_argc] = wmem_strdup(wmem_packet_scope(), com_token); cmd_argv_start[cmd_argc] = start + com_token_start; cmd_argv_length[cmd_argc] = com_token_length; cmd_argc++; } start += com_token_start + com_token_length; } }
// 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; }
/* * Process a multipart body-part: * MIME-part-headers [ line-end *OCTET ] * line-end dashed-boundary transport-padding line-end * * If applicable, call a media subdissector. * * Return the offset to the start of the next body-part. */ static gint process_body_part(proto_tree *tree, tvbuff_t *tvb, const guint8 *boundary, gint boundary_len, packet_info *pinfo, gint start, gboolean *last_boundary) { proto_tree *subtree; proto_item *ti; gint offset = start, next_offset = 0; char *parameters = NULL; gint body_start, boundary_start, boundary_line_len; gchar *content_type_str = NULL; gchar *content_encoding_str = NULL; char *filename = NULL; char *mimetypename = NULL; int len = 0; gboolean last_field = FALSE; ti = proto_tree_add_item(tree, hf_multipart_part, tvb, start, 0, ENC_ASCII|ENC_NA); subtree = proto_item_add_subtree(ti, ett_multipart_body); /* * Process the MIME-part-headers */ while (!last_field) { gint colon_offset; char *hdr_str; char *header_str; /* Look for the end of the header (denoted by cr) * 3:d argument to imf_find_field_end() maxlen; must be last offset in the tvb. */ next_offset = imf_find_field_end(tvb, offset, tvb_length_remaining(tvb, offset)+offset, &last_field); /* If cr not found, won't have advanced - get out to avoid infinite loop! */ if (next_offset == offset) { break; } hdr_str = tvb_get_string(wmem_packet_scope(), tvb, offset, next_offset - offset); header_str = unfold_and_compact_mime_header(hdr_str, &colon_offset); if (colon_offset <= 0) { proto_tree_add_text(subtree, tvb, offset, next_offset - offset, "%s", tvb_format_text(tvb, offset, next_offset - offset)); } else { gint hf_index; /* Split header name from header value */ header_str[colon_offset] = '\0'; hf_index = is_known_multipart_header(header_str, colon_offset); if (hf_index == -1) { proto_tree_add_text(subtree, tvb, offset, next_offset - offset, "%s", tvb_format_text(tvb, offset, next_offset - offset)); } else { char *value_str = header_str + colon_offset + 1; proto_tree_add_string_format(subtree, hf_header_array[hf_index], tvb, offset, next_offset - offset, (const char *)value_str, "%s", tvb_format_text(tvb, offset, next_offset - offset)); switch (hf_index) { case POS_CONTENT_TYPE: { /* The Content-Type starts at colon_offset + 1 */ gint semicolon_offset = index_of_char( value_str, ';'); if (semicolon_offset > 0) { value_str[semicolon_offset] = '\0'; parameters = wmem_strdup(wmem_packet_scope(), value_str + semicolon_offset + 1); } else { parameters = NULL; } content_type_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1); /* Show content-type in root 'part' label */ proto_item_append_text(ti, " (%s)", content_type_str); /* find the "name" parameter in case we don't find a content disposition "filename" */ if((mimetypename = find_parameter(parameters, "name=", &len)) != NULL) { mimetypename = g_strndup(mimetypename, len); } } break; case POS_CONTENT_TRANSFER_ENCODING: { /* The Content-Transfeing starts at colon_offset + 1 */ gint cr_offset = index_of_char(value_str, '\r'); if (cr_offset > 0) { value_str[cr_offset] = '\0'; } content_encoding_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1); } break; case POS_CONTENT_DISPOSITION: { /* find the "filename" parameter */ if((filename = find_parameter(value_str, "filename=", &len)) != NULL) { filename = g_strndup(filename, len); } } break; default: break; } } } offset = next_offset; } body_start = next_offset; /* * Process the body */ boundary_start = find_next_boundary(tvb, body_start, boundary, boundary_len, &boundary_line_len, last_boundary); if (boundary_start > 0) { gint body_len = boundary_start - body_start; tvbuff_t *tmp_tvb = tvb_new_subset(tvb, body_start, body_len, body_len); if (content_type_str) { /* * subdissection */ void *save_private_data = pinfo->private_data; gboolean dissected; /* * Try and remove any content transfer encoding so that each sub-dissector * doesn't have to do it itself * */ if(content_encoding_str && remove_base64_encoding) { if(!g_ascii_strncasecmp(content_encoding_str, "base64", 6)) tmp_tvb = base64_decode(pinfo, tmp_tvb, filename ? filename : (mimetypename ? mimetypename : content_type_str)); } pinfo->private_data = parameters; /* * First try the dedicated multipart dissector table */ dissected = dissector_try_string(multipart_media_subdissector_table, content_type_str, tmp_tvb, pinfo, subtree, NULL); if (! dissected) { /* * Fall back to the default media dissector table */ dissected = dissector_try_string(media_type_dissector_table, content_type_str, tmp_tvb, pinfo, subtree, NULL); } if (! dissected) { const char *save_match_string = pinfo->match_string; pinfo->match_string = content_type_str; call_dissector(media_handle, tmp_tvb, pinfo, subtree); pinfo->match_string = save_match_string; } pinfo->private_data = save_private_data; parameters = NULL; /* Shares same memory as content_type_str */ } else { call_dissector(data_handle, tmp_tvb, pinfo, subtree); } proto_item_set_len(ti, boundary_start - start); if (*last_boundary == TRUE) { proto_tree_add_text(tree, tvb, boundary_start, boundary_line_len, "Last boundary: %s", tvb_format_text(tvb, boundary_start, boundary_line_len)); } else { proto_tree_add_text(tree, tvb, boundary_start, boundary_line_len, "Boundary: %s", tvb_format_text(tvb, boundary_start, boundary_line_len)); } g_free(filename); g_free(mimetypename); return boundary_start + boundary_line_len; } g_free(filename); g_free(mimetypename); return -1; }
/* * This function dissects an "Ice string", adds hf to "tree" and returns consumed * bytes in "*consumed", if errors "*consumed" is -1. * * "*dest" is a null terminated version of the dissected Ice string. */ static void dissect_ice_string(packet_info *pinfo, proto_tree *tree, proto_item *item, int hf_icep, tvbuff_t *tvb, guint32 offset, gint32 *consumed, char **dest) { /* p. 586 chapter 23.2.1 and p. 588 chapter 23.2.5 * string == Size + content * string = 1byte (0..254) + string not null terminated * or * string = 1byte (255) + 1int (255..2^32-1) + string not null terminated */ guint32 Size = 0; char *s = NULL; (*consumed) = 0; /* check for first byte */ if ( !tvb_bytes_exist(tvb, offset, 1) ) { expert_add_info_format(pinfo, item, &ei_icep_string_malformed, "1st byte of Size missing"); col_append_str(pinfo->cinfo, COL_INFO, " (1st byte of Size missing)"); (*consumed) = -1; return; } /* get the Size */ Size = tvb_get_guint8(tvb, offset); offset++; (*consumed)++; if ( Size == 255 ) { /* check for next 4 bytes */ if ( !tvb_bytes_exist(tvb, offset, 4) ) { expert_add_info_format(pinfo, item, &ei_icep_string_malformed, "second field of Size missing"); col_append_str(pinfo->cinfo, COL_INFO, " (second field of Size missing)"); (*consumed) = -1; return; } /* get second field of Size */ Size = tvb_get_letohl(tvb, offset); offset += 4; (*consumed) += 4; } DBG1("string.Size --> %d\n", Size); /* check if the string exists */ if ( !tvb_bytes_exist(tvb, offset, Size) ) { expert_add_info_format(pinfo, item, &ei_icep_string_malformed, "missing or truncated string"); col_append_str(pinfo->cinfo, COL_INFO, " (missing or truncated string)"); (*consumed) = -1; return; } if ( Size > icep_max_ice_string_len ) { expert_add_info(pinfo, item, &ei_icep_string_too_long); col_append_str(pinfo->cinfo, COL_INFO, " (string too long)"); (*consumed) = -1; return; } if ( Size != 0 ) { s = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, Size, ENC_ASCII); proto_tree_add_string(tree, hf_icep, tvb, offset, Size, s); } else { s = wmem_strdup(wmem_packet_scope(), "(empty)"); /* display the 0x00 Size byte when click on a empty ice_string */ proto_tree_add_string(tree, hf_icep, tvb, offset - 1, 1, s); } if ( dest != NULL ) *dest = s; /*offset += Size;*/ (*consumed) += Size; return; }
char *get_conversation_filter(conv_item_t *conv_item, conv_direction_e direction) { char *sport, *dport, *src_addr, *dst_addr; char *str; sport = ct_port_to_str(conv_item->ptype, conv_item->src_port); dport = ct_port_to_str(conv_item->ptype, conv_item->dst_port); src_addr = address_to_str(NULL, &conv_item->src_address); dst_addr = address_to_str(NULL, &conv_item->dst_address); if (conv_item->src_address.type == AT_STRINGZ || conv_item->src_address.type == AT_USB) { char *new_addr; new_addr = wmem_strdup_printf(NULL, "\"%s\"", src_addr); wmem_free(NULL, src_addr); src_addr = new_addr; } if (conv_item->dst_address.type == AT_STRINGZ || conv_item->dst_address.type == AT_USB) { char *new_addr; new_addr = wmem_strdup_printf(NULL, "\"%s\"", dst_addr); wmem_free(NULL, dst_addr); dst_addr = new_addr; } switch(direction){ case CONV_DIR_A_TO_FROM_B: /* A <-> B */ str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s && %s==%s%s%s%s%s", conversation_get_filter_name(conv_item, CONV_FT_ANY_ADDRESS), src_addr, sport?" && ":"", sport?conversation_get_filter_name(conv_item, CONV_FT_ANY_PORT):"", sport?"==":"", sport?sport:"", conversation_get_filter_name(conv_item, CONV_FT_ANY_ADDRESS), dst_addr, dport?" && ":"", dport?conversation_get_filter_name(conv_item, CONV_FT_ANY_PORT):"", dport?"==":"", dport?dport:"" ); break; case CONV_DIR_A_TO_B: /* A --> B */ str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s && %s==%s%s%s%s%s", conversation_get_filter_name(conv_item, CONV_FT_SRC_ADDRESS), src_addr, sport?" && ":"", sport?conversation_get_filter_name(conv_item, CONV_FT_SRC_PORT):"", sport?"==":"", sport?sport:"", conversation_get_filter_name(conv_item, CONV_FT_DST_ADDRESS), dst_addr, dport?" && ":"", dport?conversation_get_filter_name(conv_item, CONV_FT_DST_PORT):"", dport?"==":"", dport?dport:"" ); break; case CONV_DIR_A_FROM_B: /* A <-- B */ str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s && %s==%s%s%s%s%s", conversation_get_filter_name(conv_item, CONV_FT_DST_ADDRESS), src_addr, sport?" && ":"", sport?conversation_get_filter_name(conv_item, CONV_FT_DST_PORT):"", sport?"==":"", sport?sport:"", conversation_get_filter_name(conv_item, CONV_FT_SRC_ADDRESS), dst_addr, dport?" && ":"", dport?conversation_get_filter_name(conv_item, CONV_FT_SRC_PORT):"", dport?"==":"", dport?dport:"" ); break; case CONV_DIR_A_TO_FROM_ANY: /* A <-> ANY */ str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s", conversation_get_filter_name(conv_item, CONV_FT_ANY_ADDRESS), src_addr, sport?" && ":"", sport?conversation_get_filter_name(conv_item, CONV_FT_ANY_PORT):"", sport?"==":"", sport?sport:"" ); break; case CONV_DIR_A_TO_ANY: /* A --> ANY */ str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s", conversation_get_filter_name(conv_item, CONV_FT_SRC_ADDRESS), src_addr, sport?" && ":"", sport?conversation_get_filter_name(conv_item, CONV_FT_SRC_PORT):"", sport?"==":"", sport?sport:"" ); break; case CONV_DIR_A_FROM_ANY: /* A <-- ANY */ str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s", conversation_get_filter_name(conv_item, CONV_FT_DST_ADDRESS), src_addr, sport?" && ":"", sport?conversation_get_filter_name(conv_item, CONV_FT_DST_PORT):"", sport?"==":"", sport?sport:"" ); break; case CONV_DIR_ANY_TO_FROM_B: /* ANY <-> B */ str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s", conversation_get_filter_name(conv_item, CONV_FT_ANY_ADDRESS), dst_addr, dport?" && ":"", dport?conversation_get_filter_name(conv_item, CONV_FT_ANY_PORT):"", dport?"==":"", dport?dport:"" ); break; case CONV_DIR_ANY_FROM_B: /* ANY <-- B */ str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s", conversation_get_filter_name(conv_item, CONV_FT_SRC_ADDRESS), dst_addr, dport?" && ":"", dport?conversation_get_filter_name(conv_item, CONV_FT_SRC_PORT):"", dport?"==":"", dport?dport:"" ); break; case CONV_DIR_ANY_TO_B: /* ANY --> B */ str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s", conversation_get_filter_name(conv_item, CONV_FT_DST_ADDRESS), dst_addr, dport?" && ":"", dport?conversation_get_filter_name(conv_item, CONV_FT_DST_PORT):"", dport?"==":"", dport?dport:"" ); break; default: str = wmem_strdup(NULL, "INVALID"); break; } g_free(sport); g_free(dport); wmem_free(NULL, src_addr); wmem_free(NULL, dst_addr); return str; }
if( acse_ctx_oid_table ){ g_hash_table_destroy(acse_ctx_oid_table); acse_ctx_oid_table = NULL; } acse_ctx_oid_table = g_hash_table_new(acse_ctx_oid_hash, acse_ctx_oid_equal); } static void register_ctx_id_and_oid(packet_info *pinfo _U_, guint32 idx, char *oid) { acse_ctx_oid_t *aco, *tmpaco; aco=wmem_new(wmem_file_scope(), acse_ctx_oid_t); aco->ctx_id=idx; aco->oid=wmem_strdup(wmem_file_scope(), oid); /* if this ctx already exists, remove the old one first */ tmpaco=(acse_ctx_oid_t *)g_hash_table_lookup(acse_ctx_oid_table, aco); if(tmpaco){ g_hash_table_remove(acse_ctx_oid_table, tmpaco); } g_hash_table_insert(acse_ctx_oid_table, aco, aco); } static char * find_oid_by_ctx_id(packet_info *pinfo _U_, guint32 idx) { acse_ctx_oid_t aco, *tmpaco; aco.ctx_id=idx; tmpaco=(acse_ctx_oid_t *)g_hash_table_lookup(acse_ctx_oid_table, &aco); if(tmpaco){
static gchar* dfilter_macro_apply_recurse(const gchar* text, guint depth, gchar** error) { enum { OUTSIDE, STARTING, NAME, ARGS } state = OUTSIDE; GString* out; GString* name = NULL; GString* arg = NULL; GPtrArray* args = NULL; gchar c; const gchar* r = text; gboolean changed = FALSE; if ( depth > 31) { if (error != NULL) *error = g_strdup("too much nesting in macros"); return NULL; } #define FGS(n) if (n) g_string_free(n,TRUE); n = NULL #define FREE_ALL() \ do { \ FGS(name); \ FGS(arg); \ if (args) { \ while(args->len) { void* p = g_ptr_array_remove_index_fast(args,0); if (p) g_free(p); } \ g_ptr_array_free(args,TRUE); \ args = NULL; \ } \ } while(0) if (error != NULL) *error = NULL; out = g_string_sized_new(64); while(1) { c = *r++; switch(state) { case OUTSIDE: { switch(c) { case '\0': { goto finish; } case '$': { state = STARTING; break; } default: { g_string_append_c(out,c); break; } } break; } case STARTING: { switch (c) { case '{': { args = g_ptr_array_new(); arg = g_string_sized_new(32); name = g_string_sized_new(32); state = NAME; break; } case '\0': { g_string_append_c(out,'$'); goto finish; } default: { g_string_append_c(out,'$'); g_string_append_c(out,c); state = OUTSIDE; break; } } break; } case NAME: { if ( g_ascii_isalnum(c) || c == '_' || c == '-' || c == '.' ) { g_string_append_c(name,c); } else if ( c == ':') { state = ARGS; } else if ( c == '}') { gchar* resolved; g_ptr_array_add(args,NULL); resolved = dfilter_macro_resolve(name->str, (gchar**)args->pdata, error); if (resolved == NULL) goto on_error; changed = TRUE; g_string_append(out,resolved); wmem_free(NULL, resolved); FREE_ALL(); state = OUTSIDE; } else if ( c == '\0') { if (error != NULL) *error = g_strdup("end of filter in the middle of a macro expression"); goto on_error; } else { if (error != NULL) *error = g_strdup("invalid character in macro name"); goto on_error; } break; } case ARGS: { switch(c) { case '\0': { if (error != NULL) *error = g_strdup("end of filter in the middle of a macro expression"); goto on_error; } case ';': { g_ptr_array_add(args,g_string_free(arg,FALSE)); arg = g_string_sized_new(32); break; } case '\\': { c = *r++; if (c) { g_string_append_c(arg,c); break; } else { if (error != NULL) *error = g_strdup("end of filter in the middle of a macro expression"); goto on_error; } } default: { g_string_append_c(arg,c); break; } case '}': { gchar* resolved; g_ptr_array_add(args,g_string_free(arg,FALSE)); g_ptr_array_add(args,NULL); arg = NULL; resolved = dfilter_macro_resolve(name->str, (gchar**)args->pdata, error); if (resolved == NULL) goto on_error; changed = TRUE; g_string_append(out,resolved); wmem_free(NULL, resolved); FREE_ALL(); state = OUTSIDE; break; } } break; } } } finish: { FREE_ALL(); if (changed) { gchar* resolved = dfilter_macro_apply_recurse(out->str, depth + 1, error); g_string_free(out,TRUE); return resolved; } else { gchar* out_str = wmem_strdup(NULL, out->str); g_string_free(out,TRUE); return out_str; } } on_error: { FREE_ALL(); if (error != NULL) { if (*error == NULL) *error = g_strdup("unknown error in macro expression"); } g_string_free(out,TRUE); return NULL; } }
static gchar* dfilter_macro_resolve(gchar* name, gchar** args, gchar** error) { GString* text; int argc = 0; dfilter_macro_t* m = NULL; fvt_cache_entry_t* e; int* arg_pos_p; gchar** parts; gchar* ret; guint i; for (i = 0; i < num_macros; i++) { dfilter_macro_t* c = &(macros[i]); if ( c->usable && g_str_equal(c->name,name) ) { m = c; break; } } if (!m) { if (fvt_cache && (e = (fvt_cache_entry_t *)g_hash_table_lookup(fvt_cache,name)) != NULL) { if(e->usable) { return wmem_strdup(NULL, e->repr); } else { if (error != NULL) *error = g_strdup_printf("macro '%s' is unusable", name); return NULL; } } else { if (error != NULL) *error = g_strdup_printf("macro '%s' does not exist", name); return NULL; } } DUMP_MACRO(m); if (args) { while(args[argc]) argc++; } if (argc != m->argc) { if (error != NULL) { *error = g_strdup_printf("wrong number of arguments for macro '%s', expecting %d instead of %d", name, m->argc, argc); } return NULL; } arg_pos_p = m->args_pos; parts = m->parts; text = g_string_new(*(parts++)); if (args) { while (*parts) { g_string_append_printf(text,"%s%s", args[*(arg_pos_p++)], *(parts++)); } } ret = wmem_strdup(NULL, text->str); g_string_free(text,TRUE); return ret; }
static void dissect_fw1(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 *volatile fh_tree = NULL; char direction; char chain; char *interface_name; guint32 iface_len = 10; wmem_strbuf_t *header; int i; gboolean found; static const char fw1_header[] = "FW1 Monitor"; ethertype_data_t ethertype_data; header = wmem_strbuf_new_label(wmem_epan_scope()); wmem_strbuf_append(header, fw1_header); /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "FW1"); col_clear(pinfo->cinfo, COL_INFO); /* g_snprintf(header, sizeof(header), fw1_header); */ /* fetch info to local variable */ direction = tvb_get_guint8(tvb, 0); if (!fw1_iflist_with_chain) chain = ' '; else chain = tvb_get_guint8(tvb, 1); if (fw1_with_uuid) iface_len = 6; interface_name=(char *)wmem_alloc(wmem_packet_scope(), iface_len+1); tvb_get_nstringz0(tvb, 2, iface_len+1, interface_name); /* Known interface name - if not, remember it */ found=FALSE; for (i=0; i<interface_anzahl; i++) { if ( strcmp(p_interfaces[i], interface_name) == 0 ) { found=TRUE; break; } } if (!found && interface_anzahl < MAX_INTERFACES) { p_interfaces[interface_anzahl] = wmem_strdup(wmem_file_scope(), interface_name); interface_anzahl++; } /* display all interfaces always in the same order */ for (i=0; i<interface_anzahl; i++) { if ( strcmp(p_interfaces[i], interface_name) == 0 ) { wmem_strbuf_append_printf(header, " %c%c %s %c%c", direction == 'i' ? 'i' : (direction == 'O' ? 'O' : ' '), (direction == 'i' || direction == 'O') ? chain : ' ', p_interfaces[i], direction == 'I' ? 'I' : (direction == 'o' ? 'o' : ' '), (direction == 'I' || direction == 'o') ? chain : ' ' ); } else { wmem_strbuf_append_printf(header, " %s ", p_interfaces[i]); } } col_add_str(pinfo->cinfo, COL_IF_DIR, wmem_strbuf_get_str(header) + sizeof(fw1_header) + 1); if (tree) { if (!fw1_summary_in_tree) /* Do not show the summary in Protocol Tree */ ti = proto_tree_add_protocol_format(tree, proto_fw1, tvb, 0, ETH_HEADER_SIZE, "%s", fw1_header); else ti = proto_tree_add_protocol_format(tree, proto_fw1, tvb, 0, ETH_HEADER_SIZE, "%s", wmem_strbuf_get_str(header)); /* create display subtree for the protocol */ fh_tree = proto_item_add_subtree(ti, ett_fw1); proto_tree_add_item(fh_tree, hf_fw1_direction, tvb, 0, 1, ENC_ASCII|ENC_NA); if (fw1_iflist_with_chain) proto_tree_add_item(fh_tree, hf_fw1_chain, tvb, 1, 1, ENC_ASCII|ENC_NA); proto_tree_add_item(fh_tree, hf_fw1_interface, tvb, 2, iface_len, ENC_ASCII|ENC_NA); if (fw1_with_uuid) proto_tree_add_item(fh_tree, hf_fw1_uuid, tvb, 8, 4, ENC_BIG_ENDIAN); } ethertype_data.etype = tvb_get_ntohs(tvb, 12); ethertype_data.offset_after_ethertype = ETH_HEADER_SIZE; ethertype_data.fh_tree = fh_tree; ethertype_data.etype_id = hf_fw1_type; ethertype_data.trailer_id = hf_fw1_trailer; ethertype_data.fcs_len = 0; call_dissector_with_data(ethertype_handle, tvb, pinfo, tree, ðertype_data); }
static void expert_set_info_vformat(packet_info *pinfo, proto_item *pi, int group, int severity, int hf_index, gboolean use_vaformat, const char *format, va_list ap) { char formatted[ITEM_LABEL_LENGTH]; int tap; expert_info_t *ei; proto_tree *tree; proto_item *ti; if (pinfo == NULL && pi && pi->tree_data) { pinfo = PTREE_DATA(pi)->pinfo; } /* if this packet isn't loaded because of a read filter, don't output anything */ if (pinfo == NULL || pinfo->num == 0) { return; } if (severity > highest_severity) { highest_severity = severity; } /* XXX: can we get rid of these checks and make them programming errors instead now? */ if (pi != NULL && PITEM_FINFO(pi) != NULL) { expert_set_item_flags(pi, group, severity); } if ((pi == NULL) || (PITEM_FINFO(pi) == NULL) || ((guint)severity >= FI_GET_FLAG(PITEM_FINFO(pi), PI_SEVERITY_MASK))) { col_add_str(pinfo->cinfo, COL_EXPERT, val_to_str(severity, expert_severity_vals, "Unknown (%u)")); } if (use_vaformat) { g_vsnprintf(formatted, ITEM_LABEL_LENGTH, format, ap); } else { g_strlcpy(formatted, format, ITEM_LABEL_LENGTH); } tree = expert_create_tree(pi, group, severity, formatted); if (hf_index == -1) { /* If no filterable expert info, just add the message */ ti = proto_tree_add_string(tree, hf_expert_msg, NULL, 0, 0, formatted); PROTO_ITEM_SET_GENERATED(ti); } else { /* If filterable expert info, hide the "generic" form of the message, and generate the formatted filterable expert info */ ti = proto_tree_add_none_format(tree, hf_index, NULL, 0, 0, "%s", formatted); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_string(tree, hf_expert_msg, NULL, 0, 0, formatted); PROTO_ITEM_SET_HIDDEN(ti); } ti = proto_tree_add_uint_format_value(tree, hf_expert_severity, NULL, 0, 0, severity, "%s", val_to_str_const(severity, expert_severity_vals, "Unknown")); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_uint_format_value(tree, hf_expert_group, NULL, 0, 0, group, "%s", val_to_str_const(group, expert_group_vals, "Unknown")); PROTO_ITEM_SET_GENERATED(ti); tap = have_tap_listener(expert_tap); if (!tap) return; ei = wmem_new(wmem_packet_scope(), expert_info_t); ei->packet_num = pinfo->num; ei->group = group; ei->severity = severity; ei->hf_index = hf_index; ei->protocol = pinfo->current_proto; ei->summary = wmem_strdup(wmem_packet_scope(), formatted); /* if we have a proto_item (not a faked item), set expert attributes to it */ if (pi != NULL && PITEM_FINFO(pi) != NULL) { ei->pitem = pi; } /* XXX: remove this because we don't have an internal-only function now? */ else { ei->pitem = NULL; } tap_queue_packet(expert_tap, pinfo, ei); }
/* * Process a multipart body-part: * MIME-part-headers [ line-end *OCTET ] * line-end dashed-boundary transport-padding line-end * * If applicable, call a media subdissector. * * Return the offset to the start of the next body-part. */ static gint process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info, packet_info *pinfo, gint start, gint idx, gboolean *last_boundary) { proto_tree *subtree; proto_item *ti; gint offset = start, next_offset = 0; char *parameters = NULL; gint body_start, boundary_start, boundary_line_len; gchar *content_type_str = NULL; gchar *content_encoding_str = NULL; char *filename = NULL; char *mimetypename = NULL; int len = 0; gboolean last_field = FALSE; gboolean is_raw_data = FALSE; const guint8 *boundary = (guint8 *)m_info->boundary; gint boundary_len = m_info->boundary_length; ti = proto_tree_add_item(tree, hf_multipart_part, tvb, start, 0, ENC_ASCII|ENC_NA); subtree = proto_item_add_subtree(ti, ett_multipart_body); /* find the next boundary to find the end of this body part */ boundary_start = find_next_boundary(tvb, offset, boundary, boundary_len, &boundary_line_len, last_boundary); if (boundary_start <= 0) { return -1; } /* * Process the MIME-part-headers */ while (!last_field) { gint colon_offset; char *hdr_str; char *header_str; /* Look for the end of the header (denoted by cr) * 3:d argument to imf_find_field_end() maxlen; must be last offset in the tvb. */ next_offset = imf_find_field_end(tvb, offset, tvb_reported_length_remaining(tvb, offset)+offset, &last_field); /* the following should never happen */ /* If cr not found, won't have advanced - get out to avoid infinite loop! */ /* if (next_offset == offset) { break; } */ if (last_field && (next_offset+2) <= boundary_start) { /* Add the extra CRLF of the last field */ next_offset += 2; } else if((next_offset-2) == boundary_start) { /* if CRLF is the start of next boundary it belongs to the boundary and not the field, so it's the last field without CRLF */ last_field = TRUE; next_offset -= 2; } else if (next_offset > boundary_start) { /* if there is no CRLF between last field and next boundary - trim it! */ next_offset = boundary_start; } hdr_str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, next_offset - offset, ENC_ASCII); header_str = unfold_and_compact_mime_header(hdr_str, &colon_offset); if (colon_offset <= 0) { /* if there is no colon it's no header, so break and add complete line to the body */ next_offset = offset; break; } else { gint hf_index; /* Split header name from header value */ header_str[colon_offset] = '\0'; hf_index = is_known_multipart_header(header_str, colon_offset); if (hf_index == -1) { if(isprint_string(hdr_str)) { proto_tree_add_format_text(subtree, tvb, offset, next_offset - offset); } else { /* if the header name is unkown and not printable, break and add complete line to the body */ next_offset = offset; break; } } else { char *value_str = header_str + colon_offset + 1; proto_tree_add_string_format(subtree, hf_header_array[hf_index], tvb, offset, next_offset - offset, (const char *)value_str, "%s", tvb_format_text(tvb, offset, next_offset - offset)); switch (hf_index) { case POS_ORIGINALCONTENT: { gint semicolon_offset; /* The Content-Type starts at colon_offset + 1 or after the type parameter */ char* type_str = find_parameter(value_str, "type=", NULL); if(type_str != NULL) { value_str = type_str; } semicolon_offset = index_of_char( value_str, ';'); if (semicolon_offset > 0) { value_str[semicolon_offset] = '\0'; m_info->orig_parameters = wmem_strdup(wmem_packet_scope(), value_str + semicolon_offset + 1); } m_info->orig_content_type = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1); } break; case POS_CONTENT_TYPE: { /* The Content-Type starts at colon_offset + 1 */ gint semicolon_offset = index_of_char( value_str, ';'); if (semicolon_offset > 0) { value_str[semicolon_offset] = '\0'; parameters = wmem_strdup(wmem_packet_scope(), value_str + semicolon_offset + 1); } else { parameters = NULL; } content_type_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1); /* Show content-type in root 'part' label */ proto_item_append_text(ti, " (%s)", content_type_str); /* find the "name" parameter in case we don't find a content disposition "filename" */ if((mimetypename = find_parameter(parameters, "name=", &len)) != NULL) { mimetypename = g_strndup(mimetypename, len); } if(strncmp(content_type_str, "application/octet-stream", sizeof("application/octet-stream")-1) == 0) { is_raw_data = TRUE; } /* there are only 2 body parts possible and each part has specific content types */ if(m_info->protocol && idx == 0 && (is_raw_data || g_ascii_strncasecmp(content_type_str, m_info->protocol, strlen(m_info->protocol)) != 0)) { return -1; } } break; case POS_CONTENT_TRANSFER_ENCODING: { /* The Content-Transferring starts at colon_offset + 1 */ gint cr_offset = index_of_char(value_str, '\r'); if (cr_offset > 0) { value_str[cr_offset] = '\0'; } content_encoding_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1); } break; case POS_CONTENT_DISPOSITION: { /* find the "filename" parameter */ if((filename = find_parameter(value_str, "filename=", &len)) != NULL) { filename = g_strndup(filename, len); } } break; default: break; } } } offset = next_offset; } body_start = next_offset; /* * Process the body */ { gint body_len = boundary_start - body_start; tvbuff_t *tmp_tvb = tvb_new_subset_length(tvb, body_start, body_len); /* if multipart subtype is encrypted the protcol string was set */ /* see: https://msdn.microsoft.com/en-us/library/cc251581.aspx */ /* there are only 2 body parts possible and each part has specific content types */ if(m_info->protocol && idx == 1 && is_raw_data) { gssapi_encrypt_info_t encrypt; memset(&encrypt, 0, sizeof(encrypt)); encrypt.decrypt_gssapi_tvb=DECRYPT_GSSAPI_NORMAL; dissect_kerberos_encrypted_message(tmp_tvb, pinfo, subtree, &encrypt); if(encrypt.gssapi_decrypted_tvb) { tmp_tvb = encrypt.gssapi_decrypted_tvb; is_raw_data = FALSE; content_type_str = m_info->orig_content_type; parameters = m_info->orig_parameters; } else if(encrypt.gssapi_encrypted_tvb) { tmp_tvb = encrypt.gssapi_encrypted_tvb; proto_tree_add_expert(tree, pinfo, &ei_multipart_decryption_not_possible, tmp_tvb, 0, -1); } } if (!is_raw_data && content_type_str) { /* * subdissection */ gboolean dissected; /* * Try and remove any content transfer encoding so that each sub-dissector * doesn't have to do it itself * */ if(content_encoding_str && remove_base64_encoding) { if(!g_ascii_strncasecmp(content_encoding_str, "base64", 6)) tmp_tvb = base64_decode(pinfo, tmp_tvb, filename ? filename : (mimetypename ? mimetypename : content_type_str)); } /* * First try the dedicated multipart dissector table */ dissected = dissector_try_string(multipart_media_subdissector_table, content_type_str, tmp_tvb, pinfo, subtree, parameters); if (! dissected) { /* * Fall back to the default media dissector table */ dissected = dissector_try_string(media_type_dissector_table, content_type_str, tmp_tvb, pinfo, subtree, parameters); } if (! dissected) { const char *save_match_string = pinfo->match_string; pinfo->match_string = content_type_str; call_dissector_with_data(media_handle, tmp_tvb, pinfo, subtree, parameters); pinfo->match_string = save_match_string; } parameters = NULL; /* Shares same memory as content_type_str */ } else { call_dissector(data_handle, tmp_tvb, pinfo, subtree); } proto_item_set_len(ti, boundary_start - start); if (*last_boundary == TRUE) { proto_tree_add_item(tree, hf_multipart_last_boundary, tvb, boundary_start, boundary_line_len, ENC_NA|ENC_ASCII); } else { proto_tree_add_item(tree, hf_multipart_boundary, tvb, boundary_start, boundary_line_len, ENC_NA|ENC_ASCII); } g_free(filename); g_free(mimetypename); return boundary_start + boundary_line_len; } }
static void dissect_quakeworld_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int direction) { proto_tree *cl_tree = NULL; proto_tree *text_tree = NULL; guint8 *text; int len; int offset; guint32 marker; int command_len; const char *command = ""; gboolean command_finished = FALSE; marker = tvb_get_ntohl(tvb, 0); if (tree) { proto_item *cl_item; cl_item = proto_tree_add_text(tree, tvb, 0, -1, "Connectionless"); cl_tree = proto_item_add_subtree(cl_item, ett_quakeworld_connectionless); proto_tree_add_uint(cl_tree, hf_quakeworld_connectionless_marker, tvb, 0, 4, marker); } /* all the rest of the packet is just text */ offset = 4; text = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &len, ENC_ASCII|ENC_NA); /* actually, we should look for a eol char and stop already there */ if (cl_tree) { proto_item *text_item; text_item = proto_tree_add_string(cl_tree, hf_quakeworld_connectionless_text, tvb, offset, len, text); text_tree = proto_item_add_subtree(text_item, ett_quakeworld_connectionless_text); } if (direction == DIR_C2S) { /* client to server commands */ const char *c; Cmd_TokenizeString(text); c = Cmd_Argv(0); /* client to sever commands */ if (strcmp(c,"ping") == 0) { command = "Ping"; command_len = 4; } else if (strcmp(c,"status") == 0) { command = "Status"; command_len = 6; } else if (strcmp(c,"log") == 0) { command = "Log"; command_len = 3; } else if (strcmp(c,"connect") == 0) { int version; int qport; int challenge; const char *infostring; proto_tree *argument_tree = NULL; command = "Connect"; command_len = Cmd_Argv_length(0); if (text_tree) { proto_item *argument_item; proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command, tvb, offset, command_len, command); argument_item = proto_tree_add_string(text_tree, hf_quakeworld_connectionless_arguments, tvb, offset + Cmd_Argv_start(1), len + 1 - Cmd_Argv_start(1), text + Cmd_Argv_start(1)); argument_tree = proto_item_add_subtree(argument_item, ett_quakeworld_connectionless_arguments); command_finished=TRUE; } version = atoi(Cmd_Argv(1)); qport = atoi(Cmd_Argv(2)); challenge = atoi(Cmd_Argv(3)); infostring = Cmd_Argv(4); if (argument_tree) { proto_item *info_item; proto_tree *info_tree; proto_tree_add_uint(argument_tree, hf_quakeworld_connectionless_connect_version, tvb, offset + Cmd_Argv_start(1), Cmd_Argv_length(1), version); proto_tree_add_uint(argument_tree, hf_quakeworld_connectionless_connect_qport, tvb, offset + Cmd_Argv_start(2), Cmd_Argv_length(2), qport); proto_tree_add_int(argument_tree, hf_quakeworld_connectionless_connect_challenge, tvb, offset + Cmd_Argv_start(3), Cmd_Argv_length(3), challenge); info_item = proto_tree_add_string(argument_tree, hf_quakeworld_connectionless_connect_infostring, tvb, offset + Cmd_Argv_start(4), Cmd_Argv_length(4), infostring); info_tree = proto_item_add_subtree( info_item, ett_quakeworld_connectionless_connect_infostring); dissect_id_infostring(tvb, info_tree, offset + Cmd_Argv_start(4), wmem_strdup(wmem_packet_scope(), infostring), ett_quakeworld_connectionless_connect_infostring_key_value, hf_quakeworld_connectionless_connect_infostring_key_value, hf_quakeworld_connectionless_connect_infostring_key, hf_quakeworld_connectionless_connect_infostring_value); } } else if (strcmp(c,"getchallenge") == 0) { command = "Get Challenge"; command_len = Cmd_Argv_length(0); } else if (strcmp(c,"rcon") == 0) { const char* password; int i; char remaining[MAX_TEXT_SIZE+1]; proto_tree *argument_tree = NULL; command = "Remote Command"; command_len = Cmd_Argv_length(0); if (text_tree) { proto_item *argument_item; proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command, tvb, offset, command_len, command); argument_item = proto_tree_add_string(text_tree, hf_quakeworld_connectionless_arguments, tvb, offset + Cmd_Argv_start(1), len - Cmd_Argv_start(1), text + Cmd_Argv_start(1)); argument_tree = proto_item_add_subtree(argument_item, ett_quakeworld_connectionless_arguments); command_finished=TRUE; } password = Cmd_Argv(1); if (argument_tree) { proto_tree_add_string(argument_tree, hf_quakeworld_connectionless_rcon_password, tvb, offset + Cmd_Argv_start(1), Cmd_Argv_length(1), password); } remaining[0] = '\0'; for (i=2; i<Cmd_Argc() ; i++) { g_strlcat (remaining, Cmd_Argv(i), MAX_TEXT_SIZE+1); g_strlcat (remaining, " ", MAX_TEXT_SIZE+1); } if (text_tree) { proto_tree_add_string(argument_tree, hf_quakeworld_connectionless_rcon_command, tvb, offset + Cmd_Argv_start(2), Cmd_Argv_start(Cmd_Argc()-1) + Cmd_Argv_length(Cmd_Argc()-1) - Cmd_Argv_start(2), remaining); } } else if (c[0]==A2A_PING && ( c[1]=='\0' || c[1]=='\n')) { command = "Ping"; command_len = 1; } else if (c[0]==A2A_ACK && ( c[1]=='\0' || c[1]=='\n')) { command = "Ack"; command_len = 1; } else { command = "Unknown"; command_len = len - 1; } } else { /* server to client commands */ if (text[0] == S2C_CONNECTION) { command = "Connected"; command_len = 1; } else if (text[0] == A2C_CLIENT_COMMAND) { command = "Client Command"; command_len = 1; /* stringz (command), stringz (localid) */ } else if (text[0] == A2C_PRINT) { command = "Print"; command_len = 1; /* string */ } else if (text[0] == A2A_PING) { command = "Ping"; command_len = 1; } else if (text[0] == S2C_CHALLENGE) { command = "Challenge"; command_len = 1; /* string, atoi */ } else { command = "Unknown"; command_len = len - 1; } } col_append_fstr(pinfo->cinfo, COL_INFO, " %s", command); if (!command_finished) { proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command, tvb, offset, command_len, command); } /*offset += len;*/ }
static int ssh_dissect_key_exchange(tvbuff_t *tvb, packet_info *pinfo, struct ssh_flow_data *global_data, int offset, proto_tree *tree, int is_response, gboolean *need_desegmentation) { guint plen, len; guint8 padding_length; guint remain_length; int last_offset=offset; guint msg_code; proto_item *ti; proto_item *key_ex_tree =NULL; struct ssh_peer_data *peer_data = &global_data->peer_data[is_response]; /* * We use "tvb_ensure_length_remaining()" to make sure there * actually *is* data remaining. * * This means we're guaranteed that "remain_length" is positive. */ remain_length = tvb_ensure_length_remaining(tvb, offset); /* * Can we do reassembly? */ if (ssh_desegment && pinfo->can_desegment) { /* * Yes - would an SSH header starting at this offset * be split across segment boundaries? */ if (remain_length < 4) { /* * Yes. Tell the TCP dissector where the data for * this message starts in the data it handed us and * that we need "some more data." Don't tell it * exactly how many bytes we need because if/when we * ask for even more (after the header) that will * break reassembly. */ pinfo->desegment_offset = offset; pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; *need_desegmentation = TRUE; return offset; } } plen = tvb_get_ntohl(tvb, offset) ; if (ssh_desegment && pinfo->can_desegment) { if (plen +4 > remain_length) { pinfo->desegment_offset = offset; pinfo->desegment_len = plen+4 - remain_length; *need_desegmentation = TRUE; return offset; } } /* * Need to check plen > 0x80000000 here */ ti = proto_tree_add_uint(tree, hf_ssh_packet_length, tvb, offset, 4, plen); if (plen >= 0xffff) { expert_add_info_format(pinfo, ti, &ei_ssh_packet_length, "Overly large number %d", plen); plen = remain_length-4; } offset+=4; /* padding length */ padding_length = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_ssh_padding_length, tvb, offset, 1, padding_length); offset += 1; key_ex_tree=proto_tree_add_subtree(tree, tvb, offset, -1, ett_key_exchange, NULL, "Key Exchange"); /* msg_code */ msg_code = tvb_get_guint8(tvb, offset); if (msg_code >= 30 && msg_code < 40) { offset = global_data->kex_specific_dissector(msg_code, tvb, pinfo, offset, key_ex_tree); } else { proto_tree_add_item(key_ex_tree, hf_ssh2_msg_code, tvb, offset, 1, ENC_NA); offset += 1; col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, val_to_str(msg_code, ssh2_msg_vals, "Unknown (%u)")); /* 16 bytes cookie */ switch(msg_code) { case SSH_MSG_KEXINIT: if ((peer_data->frame_key_start == 0) || (peer_data->frame_key_start == pinfo->fd->num)) { offset = ssh_dissect_key_init(tvb, offset, key_ex_tree, is_response, global_data); peer_data->frame_key_start = pinfo->fd->num; } break; case SSH_MSG_NEWKEYS: if (peer_data->frame_key_end == 0) { peer_data->frame_key_end = pinfo->fd->num; ssh_choose_algo(global_data->peer_data[CLIENT_PEER_DATA].enc_proposals[is_response], global_data->peer_data[SERVER_PEER_DATA].enc_proposals[is_response], &peer_data->enc); /* some ciphers have their own MAC so the "negotiated" one is meaningless */ if(peer_data->enc && (0 == strcmp(peer_data->enc, "*****@*****.**") || 0 == strcmp(peer_data->enc, "*****@*****.**"))) { peer_data->mac = wmem_strdup(wmem_file_scope(), (const gchar *)"<implicit>"); peer_data->mac_length = 16; peer_data->length_is_plaintext = 1; } else if(peer_data->enc && 0 == strcmp(peer_data->enc, "*****@*****.**")) { peer_data->mac = wmem_strdup(wmem_file_scope(), (const gchar *)"<implicit>"); peer_data->mac_length = 16; } else { ssh_choose_algo(global_data->peer_data[CLIENT_PEER_DATA].mac_proposals[is_response], global_data->peer_data[SERVER_PEER_DATA].mac_proposals[is_response], &peer_data->mac); ssh_set_mac_length(peer_data); } ssh_choose_algo(global_data->peer_data[CLIENT_PEER_DATA].comp_proposals[is_response], global_data->peer_data[SERVER_PEER_DATA].comp_proposals[is_response], &peer_data->comp); } break; } } len = plen+4-padding_length-(offset-last_offset); if (len > 0) { proto_tree_add_item(key_ex_tree, hf_ssh_payload, tvb, offset, len, ENC_NA); } offset +=len; /* padding */ proto_tree_add_item(key_ex_tree, hf_ssh_padding_string, tvb, offset, padding_length, ENC_NA); offset+= padding_length; return offset; }