static gboolean
test_njack(tvbuff_t *tvb)
{
	/* We need at least 'NJ200' + 1 Byte packet type */
	if ( (tvb_length(tvb) < 6) ||
	     (tvb_strncaseeql(tvb, 0, "NJ200", 5) != 0) ) {
		return FALSE;
	}
	return TRUE;
}
Esempio n. 2
0
/* Returns index of headers */
static gint msrp_is_known_msrp_header(tvbuff_t *tvb, int offset, guint header_len)
{
	guint i;

	for (i = 1; i < array_length(msrp_headers); i++) {
		if (header_len == strlen(msrp_headers[i].name) &&
		    tvb_strncaseeql(tvb, offset, msrp_headers[i].name, header_len) == 0)
		{
			return i;
		}
	}

	return -1;
}
Esempio n. 3
0
static int cond_casestring(tvbparse_t* tt, const int offset, const tvbparse_wanted_t * wanted, tvbparse_elem_t** tok) {
    int len = wanted->len;
#ifdef TVBPARSE_DEBUG
    if (TVBPARSE_DEBUG & TVBPARSE_DEBUG_CASESTRING) g_warning("cond_casestring: control='%s'",wanted->control.str);
#endif

    if ( offset + len > tt->end_offset )
        return -1;

    if ( tvb_strncaseeql(tt->tvb, offset, wanted->control.str, len) == 0 ) {
        *tok = new_tok(tt,wanted->id,offset,len,wanted);
#ifdef TVBPARSE_DEBUG
        if (TVBPARSE_DEBUG & TVBPARSE_DEBUG_CASESTRING) g_warning("cond_casestring: GOT len=%i",len);
#endif
        return len;
    } else {
        *tok = NULL;
        return -1;
    }
}
Esempio n. 4
0
static int
dissect_text_lines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
	proto_tree	*subtree;
	proto_item	*ti;
	gint		offset = 0, next_offset;
	gint		len;
	http_message_info_t *message_info;
	const char	*data_name;
	int length = tvb_captured_length(tvb);

	/* Check if this is actually xml
	 * If there is less than 38 characters this is not XML
	 * <?xml version="1.0" encoding="UTF-8"?>
	 */
	if(length > 38){
		if (tvb_strncaseeql(tvb, 0, "<?xml", 5) == 0){
			call_dissector(xml_handle, tvb, pinfo, tree);
			return length;
		}
	}

	data_name = pinfo->match_string;
	if (! (data_name && data_name[0])) {
		/*
		 * No information from "match_string"
		 */
		message_info = (http_message_info_t *)data;
		if (message_info == NULL) {
			/*
			 * No information from dissector data
			 */
			data_name = NULL;
		} else {
			data_name = message_info->media_str;
			if (! (data_name && data_name[0])) {
				/*
				 * No information from dissector data
				 */
				data_name = NULL;
			}
		}
	}

	if (data_name)
		col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "(%s)",
				data_name);

	if (tree) {
		guint lines_read = 0;
		ti = proto_tree_add_item(tree, proto_text_lines,
				tvb, 0, -1, ENC_NA);
		if (data_name)
			proto_item_append_text(ti, ": %s", data_name);
		subtree = proto_item_add_subtree(ti, ett_text_lines);
		/* Read the media line by line */
		while (tvb_offset_exists(tvb, offset)) {
			/*
			 * XXX - we need to be passed the parameters
			 * of the content type via data parameter,
			 * so that we know the character set.  We'd
			 * have to handle that character set, which
			 * might be a multibyte character set such
			 * as "iso-10646-ucs-2", or might require other
			 * special processing.
			 */
			len = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
			if (len == -1)
				break;

			/* We use next_offset - offset instead of len in the
			 * call to proto_tree_add_format_text() so it will include the
			 * line terminator(s) (\r and/or \n) in the display.
			 */
			proto_tree_add_format_text(subtree, tvb, offset, next_offset - offset);
			lines_read++;
			offset = next_offset;
		}
		proto_item_append_text(subtree, " (%u lines)", lines_read);
	}

	return length;
}
Esempio n. 5
0
/* Code to actually dissect the packets */
static int
dissect_tivoconnect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    /* parsing variables */
    gchar * string = NULL;
    gint length = -1;
    /* value strings */
    gchar * proto_name = NULL;
    gchar * packet_identity = NULL;
    gchar * packet_machine = NULL;

    /* validate that we have a tivoconnect packet */
    if ( tvb_strncaseeql(tvb, 0, "tivoconnect", 11) != 0) {
        return 0;
    }

    length = tvb_length(tvb);
    string = (gchar*)tvb_get_ephemeral_string(tvb, 0, length);

    /* Make entries in Protocol column and Info column on summary display */
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "TiVoConnect");

    /* make a distinction between UDP and TCP packets */
    proto_name = pinfo->ipproto == IP_PROTO_TCP ?
                    "Discovery Connection" :
                    "Discovery Beacon";

    col_set_str(pinfo->cinfo, COL_INFO, proto_name);

    if (tree) {
        /* Set up structures needed to add the protocol subtree and manage it */
        proto_item *ti = NULL;
        proto_tree *tivoconnect_tree = NULL;

        /* parsing variables */
        guint offset = 0;
        gchar * field = NULL;

        /* create display subtree for the protocol */
        ti = proto_tree_add_item(tree, proto_tivoconnect, tvb, 0, -1, ENC_NA);

        tivoconnect_tree = proto_item_add_subtree(ti, ett_tivoconnect);

        /* process the packet */
        for ( field = strtok(string,"\n");
              field;
              offset+=length, field = strtok(NULL,"\n") ) {
            gchar * value = NULL;
            gint fieldlen;

            length = (int)strlen(field) + 1;

            if ( !(value=strchr(field, '=')) ) {
                /* bad packet: missing the field separator */
                continue;
            }
            *value++='\0';
            fieldlen=(int)strlen(field)+1;

            if ( g_ascii_strcasecmp(field,"tivoconnect") == 0 ) {
                proto_tree_add_item(tivoconnect_tree,
                    hf_tivoconnect_flavor, tvb, offset+fieldlen,
                    length-fieldlen-1, ENC_ASCII|ENC_NA);
            }
            else if ( g_ascii_strcasecmp(field,"method") == 0 ) {
                proto_tree_add_item(tivoconnect_tree,
                    hf_tivoconnect_method, tvb, offset+fieldlen,
                    length-fieldlen-1, ENC_ASCII|ENC_NA);
            }
            else if ( g_ascii_strcasecmp(field,"platform") == 0 ) {
                proto_tree_add_item(tivoconnect_tree,
                    hf_tivoconnect_platform, tvb, offset+fieldlen,
                    length-fieldlen-1, ENC_ASCII|ENC_NA);
            }
            else if ( g_ascii_strcasecmp(field,"machine") == 0 ) {
                proto_tree_add_item(tivoconnect_tree,
                    hf_tivoconnect_machine, tvb, offset+fieldlen,
                    length-fieldlen-1, ENC_ASCII|ENC_NA);
                packet_machine = value;
            }
            else if ( g_ascii_strcasecmp(field,"identity") == 0 ) {
                proto_tree_add_item(tivoconnect_tree,
                    hf_tivoconnect_identity, tvb, offset+fieldlen,
                    length-fieldlen-1, ENC_ASCII|ENC_NA);
                packet_identity = value;
            }
            else if ( g_ascii_strcasecmp(field,"services") == 0 ) {
                proto_tree_add_item(tivoconnect_tree,
                    hf_tivoconnect_services, tvb, offset+fieldlen,
                    length-fieldlen-1, ENC_ASCII|ENC_NA);
            }
            else if ( g_ascii_strcasecmp(field,"swversion") == 0 ) {
                proto_tree_add_item(tivoconnect_tree,
                    hf_tivoconnect_version, tvb, offset+fieldlen,
                    length-fieldlen-1, ENC_ASCII|ENC_NA);
            }
            else {
                /* unknown field! */
            }
        }

        /* Adjust "Info" column and top of tree into more useful info */
        if (packet_machine) {
            proto_item_append_text(ti, ", %s", packet_machine);
            if (check_col(pinfo->cinfo, COL_INFO))
                col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
                                            proto_name, packet_machine);
        }
        if (packet_identity) {
            proto_item_append_text(ti,
                        packet_machine ? " (%s)" : ", ID:%s",
                        packet_identity);
            if (packet_machine) {
                if (check_col(pinfo->cinfo, COL_INFO))
                    col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s (%s)",
                                 proto_name, packet_machine, packet_identity);
            }
            else {
                if (check_col(pinfo->cinfo, COL_INFO))
                    col_add_fstr(pinfo->cinfo, COL_INFO, "%s ID:%s",
                                 proto_name, packet_identity);
            }
        }

    }

    /* If this protocol has a sub-dissector call it here, see section 1.8 */

    return tvb_length(tvb);
}
Esempio n. 6
0
static int
ssh_dissect_protocol(tvbuff_t *tvb, packet_info *pinfo,
		struct ssh_flow_data *global_data,
		int offset, proto_tree *tree, int is_response, guint * version,
		gboolean *need_desegmentation)
{
	guint	remain_length;
	gint	linelen, protolen;

	/*
	 *  If the first packet do not contain the banner,
	 *  it is dump in the middle of a flow or not a ssh at all
	 */
	if (tvb_strncaseeql(tvb, offset, "SSH-", 4) != 0) {
		offset = ssh_dissect_encrypted_packet(tvb, pinfo,
			&global_data->peer_data[is_response], offset, tree);
		return offset;
	}

	if (!is_response) {
		if (tvb_strncaseeql(tvb, offset, "SSH-2.", 6) == 0) {
			*(version) = SSH_VERSION_2;
		} else if (tvb_strncaseeql(tvb, offset, "SSH-1.99-", 9) == 0) {
			*(version) = SSH_VERSION_2;
		} else if (tvb_strncaseeql(tvb, offset, "SSH-1.", 6) == 0) {
			*(version) = SSH_VERSION_1;
		}
	}

	/*
	 * 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);
	/*linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
	 */
	linelen = tvb_find_guint8(tvb, offset, -1, '\n');

	if (ssh_desegment && pinfo->can_desegment) {
		if (linelen == -1 || remain_length < (guint)linelen-offset) {
			pinfo->desegment_offset = offset;
			pinfo->desegment_len = linelen-remain_length;
			*need_desegmentation = TRUE;
			return offset;
		}
	}
	if (linelen == -1) {
		/* XXX - reassemble across segment boundaries? */
		linelen = remain_length;
		protolen = linelen;
	} else {
		linelen = linelen - offset + 1;

		if (linelen > 1 && tvb_get_guint8(tvb, offset + linelen - 2) == '\r')
			protolen = linelen - 2;
		else
			protolen = linelen - 1;
	}

	col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Protocol (%s)",
			tvb_format_text(tvb, offset, protolen));

	proto_tree_add_item(tree, hf_ssh_protocol,
					tvb, offset, linelen, ENC_ASCII|ENC_NA);
	offset+=linelen;
	return offset;
}
Esempio n. 7
0
static void
dissect_ssh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

	proto_tree	*ssh_tree = NULL;
	proto_item	*ti;
	conversation_t *conversation;
	int		last_offset, offset = 0;

	gboolean	is_response = (pinfo->destport != pinfo->match_uint),
				need_desegmentation;
	guint		version;

	struct ssh_flow_data *global_data=NULL;
	struct ssh_peer_data *peer_data;

	conversation = find_or_create_conversation(pinfo);

	global_data = (struct ssh_flow_data *)conversation_get_proto_data(conversation, proto_ssh);
	if (!global_data) {
		global_data = (struct ssh_flow_data *)wmem_alloc0(wmem_file_scope(), sizeof(struct ssh_flow_data));
		global_data->version=SSH_VERSION_UNKNOWN;
		global_data->kex_specific_dissector=ssh_dissect_kex_dh;
		global_data->peer_data[CLIENT_PEER_DATA].mac_length=-1;
		global_data->peer_data[SERVER_PEER_DATA].mac_length=-1;

		conversation_add_proto_data(conversation, proto_ssh, global_data);
	}

	peer_data = &global_data->peer_data[is_response];

	if (tree) {
		  ti = proto_tree_add_item(tree, proto_ssh, tvb, offset, -1, ENC_NA);
		  ssh_tree = proto_item_add_subtree(ti, ett_ssh);
	}

	version = global_data->version;

	switch(version) {
		case SSH_VERSION_UNKNOWN:
			col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSH");
			break;
		case SSH_VERSION_1:
			col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSHv1");
			break;
		case SSH_VERSION_2:
			col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSHv2");
			break;

	}

	col_clear(pinfo->cinfo, COL_INFO);

	while(tvb_reported_length_remaining(tvb, offset)> 0) {
		gboolean after_version_start = (peer_data->frame_version_start == 0 ||
			pinfo->fd->num >= peer_data->frame_version_start);
		gboolean before_version_end = (peer_data->frame_version_end == 0 ||
			pinfo->fd->num <= peer_data->frame_version_end);

		need_desegmentation = FALSE;
		last_offset = offset;

		peer_data->counter++;

		if (after_version_start && before_version_end &&
			  (tvb_strncaseeql(tvb, offset, "SSH-", 4) == 0)) {
			if (peer_data->frame_version_start == 0)
				peer_data->frame_version_start = pinfo->fd->num;

			offset = ssh_dissect_protocol(tvb, pinfo,
					global_data,
					offset, ssh_tree, is_response,
					&version, &need_desegmentation);

			if (!need_desegmentation) {
				peer_data->frame_version_end = pinfo->fd->num;
				global_data->version = version;
			}
		} else {
			switch(version) {

			case SSH_VERSION_UNKNOWN:
				offset = ssh_dissect_encrypted_packet(tvb, pinfo,
						&global_data->peer_data[is_response], offset, ssh_tree);
				break;

			case SSH_VERSION_1:
				offset = ssh_dissect_ssh1(tvb, pinfo, global_data,
						offset, ssh_tree, is_response,
						&need_desegmentation);
				break;

			case SSH_VERSION_2:
				offset = ssh_dissect_ssh2(tvb, pinfo, global_data,
						offset, ssh_tree, is_response,
						&need_desegmentation);
				break;
			}
		}

		if (need_desegmentation)
			return;
		if (offset <= last_offset)
			THROW(ReportedBoundsError);
	}

	col_prepend_fstr(pinfo->cinfo, COL_INFO, "%s: ", is_response ? "Server" : "Client");
}