Ejemplo n.º 1
0
/* Parse the IPv6 header and the TCP header inside. We do not
 * currently support parsing IPv6 extension headers or any layer 4
 * protocol other than TCP. Return a packet_parse_result_t.
 * Note that packet_end points to the byte beyond the end of packet.
 */
static int parse_ipv6(struct packet *packet, u8 *header_start, u8 *packet_end,
		      char **error)
{
	u8 *p = header_start;

	packet->ipv6 = (struct ipv6 *) (p);

	/* Check that header fits in sniffed packet. */
	const int ip_header_bytes = packet_ip_header_len(packet);
	assert(ip_header_bytes >= 0);
	assert(ip_header_bytes == sizeof(*packet->ipv6));
	if (p + ip_header_bytes > packet_end) {
		asprintf(error, "IPv6 header overflows packet");
		goto error_out;
	}

	/* Check that payload fits in sniffed packet. */
	const int ip_total_bytes = (ip_header_bytes +
				    ntohs(packet->ipv6->payload_len));
	packet->ip_bytes = ip_total_bytes;
	if (p + ip_total_bytes > packet_end) {
		asprintf(error, "IPv6 payload overflows packet");
		goto error_out;
	}
	assert(ip_header_bytes <= ip_total_bytes);

	/* Move on to the header inside. */
	p += ip_header_bytes;
	assert(p <= packet_end);

	if (DEBUG_LOGGING) {
		char src_string[ADDR_STR_LEN];
		char dst_string[ADDR_STR_LEN];
		struct ip_address src_ip, dst_ip;
		ip_from_ipv6(&packet->ipv6->src_ip, &src_ip);
		ip_from_ipv6(&packet->ipv6->dst_ip, &dst_ip);
		DEBUGP("src IP: %s\n", ip_to_string(&src_ip, src_string));
		DEBUGP("dst IP: %s\n", ip_to_string(&dst_ip, dst_string));
	}

	/* Examine the L4 header. */
	const int layer4_bytes = ip_total_bytes - ip_header_bytes;
	const int layer4_protocol = packet->ipv6->next_header;
	return parse_layer4(packet, p, layer4_protocol, layer4_bytes,
			    packet_end, error);

error_out:
	return PACKET_BAD;
}
Ejemplo n.º 2
0
/* Parse the IPv6 header and the TCP header inside. We do not
 * currently support parsing IPv6 extension headers or any layer 4
 * protocol other than TCP. Return a packet_parse_result_t.
 * Note that packet_end points to the byte beyond the end of packet.
 */
static int parse_ipv6(struct packet *packet, u8 *header_start, u8 *packet_end,
		      char **error)
{
	struct header *ip_header = NULL;
	u8 *p = header_start;
	const bool is_outer = (packet->ip_bytes == 0);
	bool is_inner = false;
	struct ipv6 *ipv6 = (struct ipv6 *) (p);
	enum packet_parse_result_t result = PACKET_BAD;

	/* Check that header fits in sniffed packet. */
	const int ip_header_bytes = sizeof(*ipv6);
	if (p + ip_header_bytes > packet_end) {
		asprintf(error, "IPv6 header overflows packet");
		goto error_out;
	}

	/* Check that payload fits in sniffed packet. */
	const int ip_total_bytes = (ip_header_bytes +
				    ntohs(ipv6->payload_len));

	if (p + ip_total_bytes > packet_end) {
		asprintf(error, "IPv6 payload overflows packet");
		goto error_out;
	}
	assert(ip_header_bytes <= ip_total_bytes);

	ip_header = packet_append_header(packet, HEADER_IPV6, ip_header_bytes);
	if (ip_header == NULL) {
		asprintf(error, "Too many nested headers at IPv6 header");
		goto error_out;
	}
	ip_header->total_bytes = ip_total_bytes;

	/* Move on to the header inside. */
	p += ip_header_bytes;
	assert(p <= packet_end);

	if (DEBUG_LOGGING) {
		char src_string[ADDR_STR_LEN];
		char dst_string[ADDR_STR_LEN];
		struct ip_address src_ip, dst_ip;
		ip_from_ipv6(&ipv6->src_ip, &src_ip);
		ip_from_ipv6(&ipv6->dst_ip, &dst_ip);
		DEBUGP("src IP: %s\n", ip_to_string(&src_ip, src_string));
		DEBUGP("dst IP: %s\n", ip_to_string(&dst_ip, dst_string));
	}

	/* Examine the L4 header. */
	const int layer4_bytes = ip_total_bytes - ip_header_bytes;
	const int layer4_protocol = ipv6->next_header;
	result = parse_layer4(packet, p, layer4_protocol, layer4_bytes,
			      packet_end, &is_inner, error);

	/* If this is the innermost IP header then this is the primary. */
	if (is_inner)
		packet->ipv6 = ipv6;
	/* If this is the outermost IP header then this is the packet length. */
	if (is_outer)
		packet->ip_bytes = ip_total_bytes;

	return result;

error_out:
	return PACKET_BAD;
}