コード例 #1
0
static bool test_get_ext_function_overflow(void)
{
	bool success = true;

	/* Init */
	struct ipv6hdr *ip6_header;
	struct frag_hdr *fragment_hdr;
	struct ipv6_opt_hdr *hop_by_hop_hdr;

	ip6_header = kmalloc_packet(FRAG_HDR_LEN + OPT_HDR_LEN, NEXTHDR_FRAGMENT);
	if (!ip6_header)
		return false;
	fragment_hdr = add_frag_hdr(ip6_header, sizeof(struct ipv6hdr), NEXTHDR_HOP);
	hop_by_hop_hdr = add_opt_hdr(fragment_hdr, FRAG_HDR_LEN, NEXTHDR_ROUTING);

	/* Test */
	success &= assert_equals_ptr(fragment_hdr, get_extension_header(ip6_header, NEXTHDR_FRAGMENT),
			"Frag hdr");
	success &= assert_equals_ptr(hop_by_hop_hdr, get_extension_header(ip6_header, NEXTHDR_HOP),
			"Hop-by-hop hdr");
	success &= assert_equals_ptr(NULL, get_extension_header(ip6_header, NEXTHDR_UDP),
			"Payload"); /* The UDP header is not an extension header. */

	/* End */
	kfree(ip6_header);
	return success;
}
コード例 #2
0
static bool test_get_ext_function_unsupported(void)
{
	bool success = true;

	/* Init */
	struct ipv6hdr *ip6_header;
	struct frag_hdr *fragment_hdr;
	struct ipv6_opt_hdr *esp_hdr, *routing_hdr;
	unsigned char *payload;

	ip6_header = kmalloc_packet(FRAG_HDR_LEN + OPT_HDR_LEN + ROUTING_HDR_LEN + 4, NEXTHDR_FRAGMENT);
	if (!ip6_header)
		return false;
	fragment_hdr = add_frag_hdr(ip6_header, sizeof(struct ipv6hdr), NEXTHDR_ESP);
	esp_hdr = add_opt_hdr(fragment_hdr, FRAG_HDR_LEN, FRAG_HDR_LEN);
	routing_hdr = add_routing_hdr(esp_hdr, OPT_HDR_LEN, NEXTHDR_UDP);
	payload = add_payload(routing_hdr, ROUTING_HDR_LEN);

	/* Test */
	success &= assert_equals_ptr(fragment_hdr, get_extension_header(ip6_header, NEXTHDR_FRAGMENT),
			"Frag hdr");
	success &= assert_equals_ptr(esp_hdr, get_extension_header(ip6_header, NEXTHDR_ESP),
			"ESP header");
	success &= assert_equals_ptr(NULL, get_extension_header(ip6_header, NEXTHDR_ROUTING),
			"Routing header"); /* The ESP header is in the way. */
	success &= assert_equals_ptr(NULL, get_extension_header(ip6_header, NEXTHDR_UDP),
			"Payload"); /* Same, but that isn't an extension header anyway. */

	/* End */
	kfree(ip6_header);
	return success;
}
コード例 #3
0
static bool test_get_ext_function_no_subheaders(void)
{
	bool success = true;

	/* Init */
	struct ipv6hdr *ip6_header;
	unsigned char *payload;

	ip6_header = kmalloc_packet(4, NEXTHDR_UDP);
	if (!ip6_header)
		return false;
	payload = add_payload(ip6_header, sizeof(struct ipv6hdr));

	/* Test */
	success &= assert_equals_ptr(NULL, get_extension_header(ip6_header, NEXTHDR_FRAGMENT),
			"Frag hdr");
	success &= assert_equals_ptr(NULL, get_extension_header(ip6_header, NEXTHDR_HOP),
			"Hop-by-hop hdr");
	success &= assert_equals_ptr(NULL, get_extension_header(ip6_header, NEXTHDR_ESP),
			"ESP hdr");
	success &= assert_equals_ptr(NULL, get_extension_header(ip6_header, NEXTHDR_UDP),
			"Payload"); /* The UDP header is not an extension header. */

	/* End */
	kfree(ip6_header);
	return success;
}
コード例 #4
0
static bool test_no_subheaders(void)
{
	// Init.
	struct ipv6hdr *ip6_header;
	unsigned char *payload;

	ip6_header = kmalloc(sizeof(struct ipv6hdr) + 4, GFP_ATOMIC);
	if (!ip6_header) {
		log_warning("Unable to allocate a test header.");
		return false;
	}
	ip6_header->nexthdr = NEXTHDR_UDP;

	payload = (unsigned char *) (ip6_header + 1);

	// Test next function.
	{
		struct hdr_iterator iterator = HDR_ITERATOR_INIT(ip6_header);
		ASSERT_EQUALS_PTR(ip6_header, iterator.data, "First header, data");
		ASSERT_EQUALS(-1, iterator.hdr_type, "First header, hdr type");

		hdr_iterator_next(&iterator);
		ASSERT_EQUALS_PTR(payload, iterator.data, "Payload 1st, data");
		ASSERT_EQUALS(NEXTHDR_UDP, iterator.hdr_type, "Payload 1st, hdr type");

		hdr_iterator_next(&iterator);
		ASSERT_EQUALS_PTR(payload, iterator.data, "Payload 2nd, data");
		ASSERT_EQUALS(NEXTHDR_UDP, iterator.hdr_type, "Payload 2nd, hdr type");

		hdr_iterator_next(&iterator);
		hdr_iterator_next(&iterator);
		hdr_iterator_next(&iterator);
		ASSERT_EQUALS_PTR(payload, iterator.data, "Payload 3rd, data");
		ASSERT_EQUALS(NEXTHDR_UDP, iterator.hdr_type, "Payload 3rd, hdr type");
	}

	// Test last function.
	{
		struct hdr_iterator iterator = HDR_ITERATOR_INIT(ip6_header);
		hdr_iterator_last(&iterator);
		ASSERT_EQUALS_PTR(payload, iterator.data, "Last function, data");
		ASSERT_EQUALS(NEXTHDR_UDP, iterator.hdr_type, "Last function, hdr type");
	}

	// Test get extension header function.
	{
		void *frag_hdr_computed = get_extension_header(ip6_header, NEXTHDR_FRAGMENT);
		void *hop_by_hop_hdr_computed = get_extension_header(ip6_header, NEXTHDR_HOP);
		void *udp_hdr_computed = get_extension_header(ip6_header, NEXTHDR_UDP);

		ASSERT_EQUALS_PTR(NULL, frag_hdr_computed, "Get function, frag hdr");
		ASSERT_EQUALS_PTR(NULL, hop_by_hop_hdr_computed, "Get function, hop-by-hop hdr");
		// Cause the UDP header is not an extension header.
		ASSERT_EQUALS_PTR(NULL, udp_hdr_computed, "Get function, payload");
	}

	return true;
}
コード例 #5
0
ファイル: send_packet_test.c プロジェクト: magg/NAT64
static bool validate_frag6(struct sk_buff *skb, bool is_first, bool is_last, u16 offset,
		u16 payload_len, u16 payload_offset, struct tuple *tuple, l4_protocol l4proto,
		u16 total_payload)
{
	size_t l4hdr_size;
	u16 l4_next_hdr;
	u16 mf = is_last ? 0 : IP6_MF;
	u16 hdr_payload_len;

	switch (l4proto) {
	case (L4PROTO_TCP):
		l4hdr_size = sizeof(struct tcphdr);
		l4_next_hdr = NEXTHDR_TCP;
		break;
	case (L4PROTO_UDP):
		l4hdr_size = sizeof(struct udphdr);
		l4_next_hdr = NEXTHDR_UDP;
		break;
	case (L4PROTO_ICMP):
		l4hdr_size = sizeof(struct icmp6hdr);
		l4_next_hdr = NEXTHDR_ICMP;
		break;
	default:
		log_debug("Invalid l4 protocol: %u", l4proto);
		return false;
	}
	hdr_payload_len = sizeof(struct frag_hdr) + (is_first ? l4hdr_size : 0)	+ payload_len;

	if (!skb) {
		log_err("The skb is NULL.");
		return false;
	}

	if (!validate_cb_l3(skb, L3PROTO_IPV6, sizeof(struct ipv6hdr) + sizeof(struct frag_hdr)))
		return false;
	if (!validate_cb_l4(skb, l4proto, is_first ? l4hdr_size : 0))
		return false;
	if (!validate_cb_payload(skb, payload_len))
		return false;

	if (!validate_ipv6_hdr(ipv6_hdr(skb), hdr_payload_len, NEXTHDR_FRAGMENT, tuple))
		return false;
	if (!validate_frag_hdr(get_extension_header(ipv6_hdr(skb), NEXTHDR_FRAGMENT), offset, mf,
			l4_next_hdr))
		return false;
	switch (l4proto) {
	case (L4PROTO_TCP):
		if (is_first && !validate_tcp_hdr(tcp_hdr(skb), tuple))
			return false;
		break;
	case (L4PROTO_UDP):
		if (is_first && !validate_udp_hdr(udp_hdr(skb), total_payload, tuple))
			return false;
		break;
	case (L4PROTO_ICMP):
		/*id field is not used in the validate_icmp6_hdr function.*/
		if (is_first && !validate_icmp6_hdr(icmp6_hdr(skb), 1234, tuple))
			return false;
		break;
	}

	if (!validate_payload(skb_payload(skb), payload_len, payload_offset))
		return false;

	return true;
}
コード例 #6
0
static bool test_subheaders(void)
{
	// Init.
	const __u16 HOP_BY_HOP_HDR_LEN = 32;
	const __u16 ROUTING_HDR_LEN = 40;

	struct ipv6hdr *ip6_header;
	struct frag_hdr *fragment_hdr;
	struct ipv6_opt_hdr *hop_by_hop_hdr;
	struct ipv6_opt_hdr *routing_hdr;
	unsigned char *payload;

	ip6_header = kmalloc(sizeof(struct ipv6hdr)
				+ sizeof(struct frag_hdr)
				+ HOP_BY_HOP_HDR_LEN
				+ ROUTING_HDR_LEN
				+ 4, // (payload.)
				GFP_ATOMIC);
	if (!ip6_header) {
		log_warning("Unable to allocate a test header.");
		return false;
	}
	ip6_header->nexthdr = NEXTHDR_FRAGMENT;

	fragment_hdr = (struct frag_hdr *) (ip6_header + 1);
	fragment_hdr->nexthdr = NEXTHDR_HOP;

	hop_by_hop_hdr = (struct ipv6_opt_hdr *) (fragment_hdr + 1);
	hop_by_hop_hdr->nexthdr = NEXTHDR_ROUTING;
	hop_by_hop_hdr->hdrlen = (HOP_BY_HOP_HDR_LEN / 8) - 1;

	routing_hdr = ((void *) hop_by_hop_hdr) + HOP_BY_HOP_HDR_LEN;
	routing_hdr->nexthdr = NEXTHDR_UDP;
	routing_hdr->hdrlen = (ROUTING_HDR_LEN / 8) - 1;

	payload = ((void *) routing_hdr) + ROUTING_HDR_LEN;

	// Test next function.
	{
		struct hdr_iterator next_iterator = HDR_ITERATOR_INIT(ip6_header);
		ASSERT_EQUALS_PTR(ip6_header, next_iterator.data, "First (main) header, data");
		ASSERT_EQUALS(-1, next_iterator.hdr_type, "First (main) header, hdr type");

		hdr_iterator_next(&next_iterator);
		ASSERT_EQUALS_PTR(fragment_hdr, next_iterator.data, "Second (frag) header, data");
		ASSERT_EQUALS(NEXTHDR_FRAGMENT, next_iterator.hdr_type, "Second (frag) header, hdr type");

		hdr_iterator_next(&next_iterator);
		ASSERT_EQUALS_PTR(hop_by_hop_hdr, next_iterator.data, "Third (hop-by-hop) header, data");
		ASSERT_EQUALS(NEXTHDR_HOP, next_iterator.hdr_type, "Third (hop-by-hop) header, hdr type");

		hdr_iterator_next(&next_iterator);
		ASSERT_EQUALS_PTR(routing_hdr, next_iterator.data, "Fourth (Routing) header, data");
		ASSERT_EQUALS(NEXTHDR_ROUTING, next_iterator.hdr_type, "Fourth (Routing) header, hdr type");

		hdr_iterator_next(&next_iterator);
		ASSERT_EQUALS_PTR(payload, next_iterator.data, "Payload 1st, data");
		ASSERT_EQUALS(NEXTHDR_UDP, next_iterator.hdr_type, "Payload 1st, hdr type");

		hdr_iterator_next(&next_iterator);
		ASSERT_EQUALS_PTR(payload, next_iterator.data, "Payload 2nd, data");
		ASSERT_EQUALS(NEXTHDR_UDP, next_iterator.hdr_type, "Payload 2nd, hdr type");
	}

	// Test last function.
	{
		struct hdr_iterator last_iterator = HDR_ITERATOR_INIT(ip6_header);
		hdr_iterator_init(&last_iterator, ip6_header);
		hdr_iterator_last(&last_iterator);
		ASSERT_EQUALS_PTR(payload, last_iterator.data, "Last function, data");
		ASSERT_EQUALS(NEXTHDR_UDP, last_iterator.hdr_type, "Last function, hdr type");
	}

	// Test get extension header function.
	{
		void *frag_hdr_computed = get_extension_header(ip6_header, NEXTHDR_FRAGMENT);
		void *hop_by_hop_hdr_computed = get_extension_header(ip6_header, NEXTHDR_HOP);
		void *udp_hdr_computed = get_extension_header(ip6_header, NEXTHDR_UDP);

		ASSERT_EQUALS_PTR(fragment_hdr, frag_hdr_computed, "Get function, frag hdr");
		ASSERT_EQUALS_PTR(hop_by_hop_hdr, hop_by_hop_hdr_computed, "Get function, hop-by-hop hdr");
		// Cause the UDP header is not an extension header.
		ASSERT_EQUALS_PTR(NULL, udp_hdr_computed, "Get function, payload");
	}

	return true;
}