예제 #1
0
static gboolean
val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
{
	fvalue_t *fv_bytes;

	/* Free up the old value, if we have one */
	string_fvalue_free(fv);

	/* Does this look like a byte-string? */
	fv_bytes = fvalue_from_unparsed(FT_BYTES, s, TRUE, NULL);
	if (fv_bytes) {
		/* Copy the bytes over to a string and terminate it
		 * with a NUL. XXX - what if the user embeds a NUL
		 * in the middle of the byte string? */
		int num_bytes = fv_bytes->value.bytes->len;

		fv->value.string = (gchar *)g_malloc(num_bytes + 1);
		memcpy(fv->value.string, fv_bytes->value.bytes->data, num_bytes);
		fv->value.string[num_bytes] = '\0';

		FVALUE_FREE(fv_bytes);
		return TRUE;
	}

	/* Just turn it into a string */
	return val_from_string(fv, s, logfunc);
}
예제 #2
0
static gboolean
val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
{
	fvalue_t *fv_bytes;
	tvbuff_t *new_tvb;
	guint8 *private_data;

	/* Free up the old value, if we have one */
	value_free(fv);

	/* Does this look like a byte string? */
	fv_bytes = fvalue_from_unparsed(FT_BYTES, s, TRUE, NULL);
	if (fv_bytes) {
		/* Make a tvbuff from the bytes */
		private_data = (guint8 *)g_memdup(fv_bytes->value.bytes->data,
				fv_bytes->value.bytes->len);
		new_tvb = tvb_new_real_data(private_data,
				fv_bytes->value.bytes->len,
				fv_bytes->value.bytes->len);

		/* Let the tvbuff know how to delete the data. */
		tvb_set_free_cb(new_tvb, free_tvb_data);

		/* And let us know that we need to free the tvbuff */
		fv->tvb_is_private = TRUE;
		fv->value.tvb = new_tvb;
		return TRUE;
	}

	/* Treat it as a string. */
	return val_from_string(fv, s, logfunc);
}
예제 #3
0
/* Gets an fvalue from a string, and sets the error message on failure. */
static fvalue_t*
dfilter_fvalue_from_unparsed(dfwork_t *dfw, ftenum_t ftype, const char *s, gboolean allow_partial_value)
{
	/*
	 * Don't set the error message if it's already set.
	 */
	return fvalue_from_unparsed(ftype, s, allow_partial_value,
	    dfw->error_message == NULL ? &dfw->error_message : NULL);
}
예제 #4
0
static gboolean
val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
{
	guint32	addr;
	unsigned int nmask_bits;

	const char *has_slash;
	const char *net_str, *addr_str;
	fvalue_t *nmask_fvalue;

	/* Look for CIDR: Is there a single slash in the string? */
	has_slash = strchr(s, '/');
	if (has_slash) {
		/* Make a copy of the string up to but not including the
		 * slash; that's the address portion. */
		addr_str = ep_strndup(s, has_slash - s);
	}
	else {
		addr_str = s;
	}

	if (!get_host_ipaddr(addr_str, &addr)) {
		logfunc("\"%s\" is not a valid hostname or IPv4 address.",
		    addr_str);
		return FALSE;
	}

	ipv4_addr_set_net_order_addr(&(fv->value.ipv4), addr);

	/* If CIDR, get netmask bits. */
	if (has_slash) {
		/* Skip past the slash */
		net_str = has_slash + 1;

		/* XXX - this is inefficient */
		nmask_fvalue = fvalue_from_unparsed(FT_UINT32, net_str, FALSE, logfunc);
		if (!nmask_fvalue) {
			return FALSE;
		}
		nmask_bits = fvalue_get_uinteger(nmask_fvalue);
		FVALUE_FREE(nmask_fvalue);

		if (nmask_bits > 32) {
			logfunc("Netmask bits in a CIDR IPv4 address should be <= 32, not %u",
					nmask_bits);
			return FALSE;
		}
		ipv4_addr_set_netmask_bits(&fv->value.ipv4, nmask_bits);
	}
	else {
		/* Not CIDR; mask covers entire address. */
		ipv4_addr_set_netmask_bits(&(fv->value.ipv4), 32);
	}

	return TRUE;
}
예제 #5
0
파일: ftype-ipv6.c 프로젝트: K4rr/wireshark
static gboolean
ipv6_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
	const char *slash;
	const char *addr_str;
	char *addr_str_to_free = NULL;
	unsigned int nmask_bits;
	fvalue_t *nmask_fvalue;

	/* Look for prefix: Is there a single slash in the string? */
	slash = strchr(s, '/');
	if (slash) {
		/* Make a copy of the string up to but not including the
		 * slash; that's the address portion. */
		addr_str_to_free = wmem_strndup(NULL, s, slash-s);
		addr_str = addr_str_to_free;
	}
	else
		addr_str = s;

	if (!get_host_ipaddr6(addr_str, &(fv->value.ipv6.addr))) {
		if (err_msg != NULL)
			*err_msg = g_strdup_printf("\"%s\" is not a valid hostname or IPv6 address.", s);
		if (addr_str_to_free)
			wmem_free(NULL, addr_str_to_free);
		return FALSE;
	}

	if (addr_str_to_free)
		wmem_free(NULL, addr_str_to_free);

	/* If prefix */
	if (slash) {
		/* XXX - this is inefficient */
		nmask_fvalue = fvalue_from_unparsed(FT_UINT32, slash+1, FALSE, err_msg);
		if (!nmask_fvalue) {
			return FALSE;
		}
		nmask_bits = fvalue_get_uinteger(nmask_fvalue);
		FVALUE_FREE(nmask_fvalue);

		if (nmask_bits > 128) {
			if (err_msg != NULL) {
				*err_msg = g_strdup_printf("Prefix in a IPv6 address should be <= 128, not %u",
						nmask_bits);
			}
			return FALSE;
		}
		fv->value.ipv6.prefix = nmask_bits;
	} else {
		/* Not CIDR; mask covers entire address. */
		fv->value.ipv6.prefix = 128;
	}

	return TRUE;
}
예제 #6
0
static gboolean
ipv6_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
{
	char *has_slash, *addr_str;
	unsigned int nmask_bits;
	fvalue_t *nmask_fvalue;

	/* Look for prefix: Is there a single slash in the string? */
	if ((has_slash = strchr(s, '/')))
		addr_str = ep_strndup(s, has_slash-s);
	else
		addr_str = s;

	if (!get_host_ipaddr6(addr_str, &(fv->value.ipv6.addr))) {
		logfunc("\"%s\" is not a valid hostname or IPv6 address.", s);
		return FALSE;
	}

	/* If prefix */
	if (has_slash) {
		/* XXX - this is inefficient */
		nmask_fvalue = fvalue_from_unparsed(FT_UINT32, has_slash+1, FALSE, logfunc);
		if (!nmask_fvalue) {
			return FALSE;
		}
		nmask_bits = fvalue_get_uinteger(nmask_fvalue);
		FVALUE_FREE(nmask_fvalue);

		if (nmask_bits > 128) {
			logfunc("Prefix in a IPv6 address should be <= 128, not %u",
					nmask_bits);
			return FALSE;
		}
		fv->value.ipv6.prefix = nmask_bits;
	} else {
		/* Not CIDR; mask covers entire address. */
		fv->value.ipv6.prefix = 128;
	}

	return TRUE;
}
예제 #7
0
static stnode_t*
check_param_entity(stnode_t *st_node)
{
	sttype_id_t		e_type;
	stnode_t		*new_st;
	fvalue_t		*fvalue;
	char *s;

	e_type = stnode_type_id(st_node);
	/* If there's an unparsed string, change it to an FT_STRING */
	if (e_type == STTYPE_UNPARSED) {
		s = stnode_data(st_node);
		fvalue = fvalue_from_unparsed(FT_STRING, s, FALSE, dfilter_fail);
		if (!fvalue) {
			THROW(TypeError);
		}

		new_st = stnode_new(STTYPE_FVALUE, fvalue);
		stnode_free(st_node);
		return new_st;
	}
	return st_node;
}
예제 #8
0
/* If the LHS of a relation test is a FUNCTION, run some checks
 * and possibly some modifications of syntax tree nodes. */
static void
check_relation_LHS_FUNCTION(const char *relation_string, FtypeCanFunc can_func,
		gboolean allow_partial_value,
		stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
{
	stnode_t		*new_st;
	sttype_id_t		type2;
	header_field_info	*hfinfo2;
	ftenum_t		ftype1, ftype2;
	fvalue_t		*fvalue;
	char			*s;
	drange_node		*rn;
	df_func_def_t   *funcdef;
	df_func_def_t   *funcdef2;
	GSList          *params;

	check_function(st_arg1);
	type2 = stnode_type_id(st_arg2);

	funcdef = sttype_function_funcdef(st_arg1);
	ftype1 = funcdef->retval_ftype;

	params = sttype_function_params(st_arg1);

	DebugLog(("    5 check_relation_LHS_FUNCTION(%s)\n", relation_string));

	if (!can_func(ftype1)) {
		dfilter_fail("Function %s (type=%s) cannot participate in '%s' comparison.",
				funcdef->name, ftype_pretty_name(ftype1),
				relation_string);
		THROW(TypeError);
	}

	if (type2 == STTYPE_FIELD) {
		hfinfo2 = stnode_data(st_arg2);
		ftype2 = hfinfo2->type;

		if (!compatible_ftypes(ftype1, ftype2)) {
			dfilter_fail("Function %s and %s are not of compatible types.",
					funcdef->name, hfinfo2->abbrev);
			THROW(TypeError);
		}
		/* Do this check even though you'd think that if
		 * they're compatible, then can_func() would pass. */
		if (!can_func(ftype2)) {
			dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
					hfinfo2->abbrev, ftype_pretty_name(ftype2));
			THROW(TypeError);
		}
	}
	else if (type2 == STTYPE_STRING) {
		s = stnode_data(st_arg2);
		if (strcmp(relation_string, "matches") == 0) {
			/* Convert to a FT_PCRE */
			fvalue = fvalue_from_string(FT_PCRE, s, dfilter_fail);
		} else {
			fvalue = fvalue_from_string(ftype1, s, dfilter_fail);
		}
		if (!fvalue) {
			THROW(TypeError);
		}

		new_st = stnode_new(STTYPE_FVALUE, fvalue);
		sttype_test_set2_args(st_node, st_arg1, new_st);
		stnode_free(st_arg2);
	}
	else if (type2 == STTYPE_UNPARSED) {
		s = stnode_data(st_arg2);
		if (strcmp(relation_string, "matches") == 0) {
			/* Convert to a FT_PCRE */
			fvalue = fvalue_from_unparsed(FT_PCRE, s, FALSE, dfilter_fail);
		} else {
			fvalue = fvalue_from_unparsed(ftype1, s, allow_partial_value, dfilter_fail);
		}
		if (!fvalue) {
			THROW(TypeError);
		}

		new_st = stnode_new(STTYPE_FVALUE, fvalue);
		sttype_test_set2_args(st_node, st_arg1, new_st);
		stnode_free(st_arg2);
	}
	else if (type2 == STTYPE_RANGE) {
		check_drange_sanity(st_arg2);
		if (!is_bytes_type(ftype1)) {
			if (!ftype_can_slice(ftype1)) {
				dfilter_fail("Function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
						funcdef->name,
						ftype_pretty_name(ftype1));
				THROW(TypeError);
			}

			/* Convert entire field to bytes */
			new_st = stnode_new(STTYPE_RANGE, NULL);

			rn = drange_node_new();
			drange_node_set_start_offset(rn, 0);
			drange_node_set_to_the_end(rn);
			/* st_arg1 is freed in this step */
			sttype_range_set1(new_st, st_arg1, rn);

			sttype_test_set2_args(st_node, new_st, st_arg2);
		}
	}
	else if (type2 == STTYPE_FUNCTION) {
		funcdef2 = sttype_function_funcdef(st_arg2);
		ftype2 = funcdef2->retval_ftype;

		if (!compatible_ftypes(ftype1, ftype2)) {
			dfilter_fail("Return values of function %s (type=%s) and function %s (type=%s) are not of compatible types.",
				     funcdef->name, ftype_pretty_name(ftype1), funcdef2->name, ftype_pretty_name(ftype2));
			THROW(TypeError);
		}

		/* Do this check even though you'd think that if
		 * they're compatible, then can_func() would pass. */
		if (!can_func(ftype2)) {
			dfilter_fail("Return value of %s (type=%s) cannot participate in specified comparison.",
				     funcdef2->name, ftype_pretty_name(ftype2));
			THROW(TypeError);
		}

		check_function(st_arg2);
	}
	else {
		g_assert_not_reached();
	}
}
예제 #9
0
static void
check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
		gboolean allow_partial_value,
		stnode_t *st_node,
		stnode_t *st_arg1, stnode_t *st_arg2)
{
	stnode_t		*new_st;
	sttype_id_t		type1, type2;
	header_field_info	*hfinfo1, *hfinfo2;
	df_func_def_t		*funcdef;
	ftenum_t		ftype1, ftype2;
	fvalue_t		*fvalue;
	char			*s;
	drange_node		*rn;

	type1 = stnode_type_id(st_arg1);
	type2 = stnode_type_id(st_arg2);
	hfinfo1 = sttype_range_hfinfo(st_arg1);
	ftype1 = hfinfo1->type;

	DebugLog(("    5 check_relation_LHS_RANGE(%s)\n", relation_string));

	if (!ftype_can_slice(ftype1)) {
		dfilter_fail("\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
				hfinfo1->abbrev, ftype_pretty_name(ftype1));
		THROW(TypeError);
	}

	check_drange_sanity(st_arg1);

	if (type2 == STTYPE_FIELD) {
		DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_FIELD)\n"));
		hfinfo2 = stnode_data(st_arg2);
		ftype2 = hfinfo2->type;

		if (!is_bytes_type(ftype2)) {
			if (!ftype_can_slice(ftype2)) {
				dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
						hfinfo2->abbrev,
						ftype_pretty_name(ftype2));
				THROW(TypeError);
			}

			/* Convert entire field to bytes */
			new_st = stnode_new(STTYPE_RANGE, NULL);

			rn = drange_node_new();
			drange_node_set_start_offset(rn, 0);
			drange_node_set_to_the_end(rn);
			/* st_arg2 is freed in this step */
			sttype_range_set1(new_st, st_arg2, rn);

			sttype_test_set2_args(st_node, st_arg1, new_st);
		}
	}
	else if (type2 == STTYPE_STRING) {
		DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_STRING)\n"));
		s = stnode_data(st_arg2);
		if (strcmp(relation_string, "matches") == 0) {
			/* Convert to a FT_PCRE */
			fvalue = fvalue_from_string(FT_PCRE, s, dfilter_fail);
		} else {
			fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
		}
		if (!fvalue) {
			DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_STRING): Could not convert from string!\n"));
			THROW(TypeError);
		}
		new_st = stnode_new(STTYPE_FVALUE, fvalue);
		sttype_test_set2_args(st_node, st_arg1, new_st);
		stnode_free(st_arg2);
	}
	else if (type2 == STTYPE_UNPARSED) {
		DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_UNPARSED)\n"));
		s = stnode_data(st_arg2);
		if (strcmp(relation_string, "matches") == 0) {
			/* Convert to a FT_PCRE */
			fvalue = fvalue_from_unparsed(FT_PCRE, s, FALSE, dfilter_fail);
		} else {
			fvalue = fvalue_from_unparsed(FT_BYTES, s, allow_partial_value, dfilter_fail);
		}
		if (!fvalue) {
			DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_UNPARSED): Could not convert from string!\n"));
			THROW(TypeError);
		}
		new_st = stnode_new(STTYPE_FVALUE, fvalue);
		sttype_test_set2_args(st_node, st_arg1, new_st);
		stnode_free(st_arg2);
	}
	else if (type2 == STTYPE_RANGE) {
		DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_RANGE)\n"));
		check_drange_sanity(st_arg2);
	}
	else if (type2 == STTYPE_FUNCTION) {
		funcdef = sttype_function_funcdef(st_arg2);
		ftype2  = funcdef->retval_ftype;
		
		if (!is_bytes_type(ftype2)) {
			if (!ftype_can_slice(ftype2)) {
				dfilter_fail("Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
					funcdef->name,
					ftype_pretty_name(ftype2));
				THROW(TypeError);
			}

			/* XXX should I add a new drange node? */
		}

		check_function(st_arg2);
	}
	else {
		g_assert_not_reached();
	}
}
예제 #10
0
static void
check_relation_LHS_UNPARSED(const char* relation_string,
		FtypeCanFunc can_func, gboolean allow_partial_value,
		stnode_t *st_node,
		stnode_t *st_arg1, stnode_t *st_arg2)
{
	stnode_t		*new_st;
	sttype_id_t		type1, type2;
	header_field_info	*hfinfo2;
	df_func_def_t		*funcdef;
	ftenum_t		ftype2;
	fvalue_t		*fvalue;
	char			*s;

	type1 = stnode_type_id(st_arg1);
	type2 = stnode_type_id(st_arg2);

	DebugLog(("    5 check_relation_LHS_UNPARSED()\n"));

	if (type2 == STTYPE_FIELD) {
		hfinfo2 = stnode_data(st_arg2);
		ftype2 = hfinfo2->type;

		if (!can_func(ftype2)) {
			dfilter_fail("%s (type=%s) cannot participate in '%s' comparison.",
					hfinfo2->abbrev, ftype_pretty_name(ftype2),
					relation_string);
			THROW(TypeError);
		}

		s = stnode_data(st_arg1);
		fvalue = fvalue_from_unparsed(ftype2, s, allow_partial_value, dfilter_fail);
		if (!fvalue) {
			/* check value_string */
			fvalue = mk_fvalue_from_val_string(hfinfo2, s);
			if (!fvalue) {
				THROW(TypeError);
			}
		}

		new_st = stnode_new(STTYPE_FVALUE, fvalue);
		sttype_test_set2_args(st_node, new_st, st_arg2);
		stnode_free(st_arg1);
	}
	else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) {
		/* Well now that's silly... */
		dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.",
				stnode_data(st_arg1),
				stnode_data(st_arg2));
		THROW(TypeError);
	}
	else if (type2 == STTYPE_RANGE) {
		check_drange_sanity(st_arg2);
		s = stnode_data(st_arg1);
		fvalue = fvalue_from_unparsed(FT_BYTES, s, allow_partial_value, dfilter_fail);
		if (!fvalue) {
			THROW(TypeError);
		}
		new_st = stnode_new(STTYPE_FVALUE, fvalue);
		sttype_test_set2_args(st_node, new_st, st_arg2);
		stnode_free(st_arg1);
	}
	else if (type2 == STTYPE_FUNCTION) {
		funcdef = sttype_function_funcdef(st_arg2);
		ftype2  = funcdef->retval_ftype;

		if (!can_func(ftype2)) {
			dfilter_fail("return value of function %s() (type=%s) cannot participate in '%s' comparison.",
					funcdef->name, ftype_pretty_name(ftype2), relation_string);
			THROW(TypeError);
		}

		s =  stnode_data(st_arg1);
		fvalue = fvalue_from_unparsed(ftype2, s, allow_partial_value, dfilter_fail);
		
		if (!fvalue) {
			THROW(TypeError);
		}

		check_function(st_arg2);

		new_st = stnode_new(STTYPE_FVALUE, fvalue);
		sttype_test_set2_args(st_node, new_st, st_arg2);
		stnode_free(st_arg1);
	}
	else {
		g_assert_not_reached();
	}
}
예제 #11
0
static void
check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
		gboolean allow_partial_value,
		stnode_t *st_node,
		stnode_t *st_arg1, stnode_t *st_arg2)
{
	stnode_t		*new_st;
	sttype_id_t		type2;
	header_field_info	*hfinfo1, *hfinfo2;
	df_func_def_t		*funcdef;
	ftenum_t		ftype1, ftype2;
	fvalue_t		*fvalue;
	char			*s;
	drange_node		*rn;
        int                     len_range;

	type2 = stnode_type_id(st_arg2);
	hfinfo1 = sttype_range_hfinfo(st_arg1);
	ftype1 = hfinfo1->type;

	DebugLog(("    5 check_relation_LHS_RANGE(%s)\n", relation_string));

	if (!ftype_can_slice(ftype1)) {
		dfilter_fail("\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
				hfinfo1->abbrev, ftype_pretty_name(ftype1));
		THROW(TypeError);
	}

	check_drange_sanity(st_arg1);

	if (type2 == STTYPE_FIELD) {
		DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_FIELD)\n"));
		hfinfo2 = stnode_data(st_arg2);
		ftype2 = hfinfo2->type;

		if (!is_bytes_type(ftype2)) {
			if (!ftype_can_slice(ftype2)) {
				dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
						hfinfo2->abbrev,
						ftype_pretty_name(ftype2));
				THROW(TypeError);
			}

			/* Convert entire field to bytes */
			new_st = stnode_new(STTYPE_RANGE, NULL);

			rn = drange_node_new();
			drange_node_set_start_offset(rn, 0);
			drange_node_set_to_the_end(rn);
			/* st_arg2 is freed in this step */
			sttype_range_set1(new_st, st_arg2, rn);

			sttype_test_set2_args(st_node, st_arg1, new_st);
		}
	}
	else if (type2 == STTYPE_STRING) {
		DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_STRING)\n"));
		s = stnode_data(st_arg2);
		if (strcmp(relation_string, "matches") == 0) {
			/* Convert to a FT_PCRE */
			fvalue = fvalue_from_string(FT_PCRE, s, dfilter_fail);
		} else {
			fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
		}
		if (!fvalue) {
			DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_STRING): Could not convert from string!\n"));
			THROW(TypeError);
		}
		new_st = stnode_new(STTYPE_FVALUE, fvalue);
		sttype_test_set2_args(st_node, st_arg1, new_st);
		stnode_free(st_arg2);
	}
	else if (type2 == STTYPE_UNPARSED) {
		DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_UNPARSED)\n"));
		s = stnode_data(st_arg2);
                len_range = drange_get_total_length(sttype_range_drange(st_arg1));
		if (strcmp(relation_string, "matches") == 0) {
			/* Convert to a FT_PCRE */
			fvalue = fvalue_from_unparsed(FT_PCRE, s, FALSE, dfilter_fail);
		}

                /* The RHS should be FT_BYTES. However, there is a special case where
                 * the range slice on the LHS is one byte long. In that case, it is natural
                 * for the user to specify a normal hex integer on the RHS, with the "0x"
                 * notation, as in "slice[0] == 0x10". We can't allow this for any
                 * slices that are longer than one byte, because then we'd have to know
                 * which endianness the byte string should be in. */
                else if (len_range == 1 && strlen(s) == 4 && strncmp(s, "0x", 2) == 0) {
                    /* Even if the RHS string starts with "0x", it still could fail to
                     * be an integer.  Try converting it here. */
                    fvalue = fvalue_from_unparsed(FT_UINT8, s, allow_partial_value, dfilter_fail);
                    if (fvalue) {
                        FVALUE_FREE(fvalue);
                        /* The value doees indeed fit into 8 bits. Create a BYTE_STRING
                         * from it. Since we know that the last 2 characters are a valid
                         * hex string, just use those directly. */
                        fvalue = fvalue_from_unparsed(FT_BYTES, s+2, allow_partial_value, dfilter_fail);
                    }
                }
                else {
                    fvalue = fvalue_from_unparsed(FT_BYTES, s, allow_partial_value, dfilter_fail);
                }
		if (!fvalue) {
			DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_UNPARSED): Could not convert from string!\n"));
			THROW(TypeError);
		}
		new_st = stnode_new(STTYPE_FVALUE, fvalue);
		sttype_test_set2_args(st_node, st_arg1, new_st);
		stnode_free(st_arg2);
	}
	else if (type2 == STTYPE_RANGE) {
		DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_RANGE)\n"));
		check_drange_sanity(st_arg2);
	}
	else if (type2 == STTYPE_FUNCTION) {
		funcdef = sttype_function_funcdef(st_arg2);
		ftype2  = funcdef->retval_ftype;

		if (!is_bytes_type(ftype2)) {
			if (!ftype_can_slice(ftype2)) {
				dfilter_fail("Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
					funcdef->name,
					ftype_pretty_name(ftype2));
				THROW(TypeError);
			}

			/* XXX should I add a new drange node? */
		}

		check_function(st_arg2);
	}
	else {
		g_assert_not_reached();
	}
}
예제 #12
0
/* If the LHS of a relation test is a FIELD, run some checks
 * and possibly some modifications of syntax tree nodes. */
static void
check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func,
		gboolean allow_partial_value,
		stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
{
	stnode_t		*new_st;
	sttype_id_t		type2;
	header_field_info	*hfinfo1, *hfinfo2;
	df_func_def_t		*funcdef;
	ftenum_t		ftype1, ftype2;
	fvalue_t		*fvalue;
	char			*s;

	type2 = stnode_type_id(st_arg2);

	hfinfo1 = (header_field_info*)stnode_data(st_arg1);
	ftype1 = hfinfo1->type;

	DebugLog(("    5 check_relation_LHS_FIELD(%s)\n", relation_string));

	if (!can_func(ftype1)) {
		dfilter_fail("%s (type=%s) cannot participate in '%s' comparison.",
				hfinfo1->abbrev, ftype_pretty_name(ftype1),
				relation_string);
		THROW(TypeError);
	}

	if (type2 == STTYPE_FIELD) {
		hfinfo2 = (header_field_info*)stnode_data(st_arg2);
		ftype2 = hfinfo2->type;

		if (!compatible_ftypes(ftype1, ftype2)) {
			dfilter_fail("%s and %s are not of compatible types.",
					hfinfo1->abbrev, hfinfo2->abbrev);
			THROW(TypeError);
		}
		/* Do this check even though you'd think that if
		 * they're compatible, then can_func() would pass. */
		if (!can_func(ftype2)) {
			dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
					hfinfo2->abbrev, ftype_pretty_name(ftype2));
			THROW(TypeError);
		}
	}
	else if (type2 == STTYPE_STRING) {
		s = (char *)stnode_data(st_arg2);
		if (strcmp(relation_string, "matches") == 0) {
			/* Convert to a FT_PCRE */
			fvalue = fvalue_from_string(FT_PCRE, s, dfilter_fail);
		} else {
			fvalue = fvalue_from_string(ftype1, s, dfilter_fail);
			if (!fvalue) {
				/* check value_string */
				fvalue = mk_fvalue_from_val_string(hfinfo1, s);
			}
		}
		if (!fvalue) {
			THROW(TypeError);
		}

		new_st = stnode_new(STTYPE_FVALUE, fvalue);
		sttype_test_set2_args(st_node, st_arg1, new_st);
		stnode_free(st_arg2);
	}
	else if (type2 == STTYPE_UNPARSED) {
		s = (char *)stnode_data(st_arg2);
		if (strcmp(relation_string, "matches") == 0) {
			/* Convert to a FT_PCRE */
			fvalue = fvalue_from_unparsed(FT_PCRE, s, FALSE, dfilter_fail);
		} else {
			do {
				fvalue = fvalue_from_unparsed(ftype1, s, allow_partial_value, dfilter_fail);
				if (!fvalue) {
					/* check value_string */
					fvalue = mk_fvalue_from_val_string(hfinfo1, s);
				}
				if (!fvalue) {
					/* Try another field with the same name */
					if (hfinfo1->same_name_prev_id != -1) {
						hfinfo1 = proto_registrar_get_nth(hfinfo1->same_name_prev_id);
						ftype1 = hfinfo1->type;
					} else {
						break;
					}
				}
			} while (!fvalue);
		}
		if (!fvalue) {
			THROW(TypeError);
		}

		new_st = stnode_new(STTYPE_FVALUE, fvalue);
		sttype_test_set2_args(st_node, st_arg1, new_st);
		stnode_free(st_arg2);
	}
	else if (type2 == STTYPE_RANGE) {
		check_drange_sanity(st_arg2);
		if (!is_bytes_type(ftype1)) {
			if (!ftype_can_slice(ftype1)) {
				dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
						hfinfo1->abbrev,
						ftype_pretty_name(ftype1));
				THROW(TypeError);
			}

			/* Convert entire field to bytes */
			new_st = convert_to_bytes(st_arg1);

			sttype_test_set2_args(st_node, new_st, st_arg2);
		}
	}
	else if (type2 == STTYPE_FUNCTION) {
		funcdef = sttype_function_funcdef(st_arg2);
		ftype2 = funcdef->retval_ftype;

		if (!compatible_ftypes(ftype1, ftype2)) {
			dfilter_fail("%s (type=%s) and return value of %s() (type=%s) are not of compatible types.",
					hfinfo1->abbrev, ftype_pretty_name(ftype1),
					funcdef->name, ftype_pretty_name(ftype2));
			THROW(TypeError);
		}

		if (!can_func(ftype2)) {
			dfilter_fail("return value of %s() (type=%s) cannot participate in specified comparison.",
					funcdef->name, ftype_pretty_name(ftype2));
			THROW(TypeError);
		}

		check_function(st_arg2);
	}
	else {
		g_assert_not_reached();
	}
}
예제 #13
0
파일: ftype-ipv4.c 프로젝트: flaub/HotFuzz
static gboolean
val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
{
	guint32	addr;
	unsigned int nmask_bits;

	char *has_slash, *s_copy = NULL;
	char *net_str, *addr_str;
	fvalue_t *nmask_fvalue;

	/* Look for CIDR: Is there a single slash in the string? */
	has_slash = strchr(s, '/');
	if (has_slash) {
		/* Make a copy of the string and use strtok() to
		 * get the address portion. */
		s_copy = ep_strdup(s);
		addr_str = strtok(s_copy, "/");

		/* I just checked for slash! I shouldn't get NULL here.
		 * Double check just in case. */
		if (!addr_str) {
			logfunc("Unexpected strtok() error parsing IP address: %s",
			    s_copy);
			return FALSE;
		}
	}
	else {
		addr_str = s;
	}

	if (!get_host_ipaddr(addr_str, &addr)) {
		logfunc("\"%s\" is not a valid hostname or IPv4 address.",
		    addr_str);
		return FALSE;
	}

	ipv4_addr_set_host_order_addr(&(fv->value.ipv4), addr);

	/* If CIDR, get netmask bits. */
	if (has_slash) {
		net_str = strtok(NULL, "/");
		/* I checked for slash! I shouldn't get NULL here.
		 * Double check just in case. */
		if (!net_str) {
			logfunc("Unexpected strtok() error parsing netmask: %s",
			    s_copy);
			return FALSE;
		}

		/* XXX - this is inefficient */
		nmask_fvalue = fvalue_from_unparsed(FT_UINT32, net_str, FALSE, logfunc);
		if (!nmask_fvalue) {
			return FALSE;
		}
		nmask_bits = fvalue_get_uinteger(nmask_fvalue);
		FVALUE_FREE(nmask_fvalue);

		if (nmask_bits > 32) {
			logfunc("Netmask bits in a CIDR IPv4 address should be <= 32, not %u",
					nmask_bits);
			return FALSE;
		}
		ipv4_addr_set_netmask_bits(&fv->value.ipv4, nmask_bits);
	}
	else {
		/* Not CIDR; mask covers entire address. */
		ipv4_addr_set_netmask_bits(&(fv->value.ipv4), 32);
	}

	return TRUE;
}