static void checksum_ipv4_packet(struct packet *packet)
{
	struct ipv4 *ipv4 = packet->ipv4;

	/* Fill in IPv4 header checksum. */
	ipv4->check = 0;
	ipv4->check = ipv4_checksum(ipv4, ipv4_header_len(ipv4));
	assert(packet->ip_bytes >= ntohs(ipv4->tot_len));

	/* Find the length of layer 4 header, options, and payload. */
	const int l4_bytes = ntohs(ipv4->tot_len) - ipv4_header_len(ipv4);
	assert(l4_bytes > 0);

	/* Fill in IPv4-based layer 4 checksum. */
	if (packet->tcp != NULL) {
		struct tcp *tcp = packet->tcp;
		tcp->check = 0;
		tcp->check = tcp_udp_v4_checksum(ipv4->src_ip,
						 ipv4->dst_ip,
						 IPPROTO_TCP, tcp, l4_bytes);
	} else if (packet->udp != NULL) {
		struct udp *udp = packet->udp;
		udp->check = 0;
		udp->check = tcp_udp_v4_checksum(ipv4->src_ip,
						 ipv4->dst_ip,
						 IPPROTO_UDP, udp, l4_bytes);
	} else if (packet->icmpv4 != NULL) {
		struct icmpv4 *icmpv4 = packet->icmpv4;
		icmpv4->checksum = 0;
		icmpv4->checksum = ipv4_checksum(icmpv4, l4_bytes);
	} else {
		assert(!"not TCP or ICMP");
	}
}
示例#2
0
static void checksum_ipv4_packet(struct packet *packet)
{
	struct ipv4 *ipv4 = packet->ipv4;

	/* Fill in IPv4 header checksum. */
	ipv4->check = 0;
	ipv4->check = ipv4_checksum(ipv4, ipv4_header_len(ipv4));
	assert(packet->ip_bytes >= ntohs(ipv4->tot_len));

	/* Find the length of layer 4 header, options, and payload. */
	const int l4_bytes = ntohs(ipv4->tot_len) - ipv4_header_len(ipv4);
	assert(l4_bytes > 0);

	/* Fill in IPv4-based layer 4 checksum. */
	if (packet->sctp != NULL) {
		struct sctp_common_header *sctp = packet->sctp;
		sctp->crc32c = 0;
		sctp->crc32c = sctp_crc32c(sctp, l4_bytes);
	} else if (packet->tcp != NULL) {
		struct tcp *tcp = packet->tcp;
		tcp->check = 0;
		tcp->check = tcp_udp_v4_checksum(ipv4->src_ip,
						 ipv4->dst_ip,
						 IPPROTO_TCP, tcp, l4_bytes);
	} else if (packet->udp != NULL) {
		struct udp *udp = packet->udp;
		udp->check = 0;
		udp->check = tcp_udp_v4_checksum(ipv4->src_ip,
						 ipv4->dst_ip,
						 IPPROTO_UDP, udp, l4_bytes);
	} else if (packet->udplite != NULL) {
		struct udplite *udplite = packet->udplite;
		u16 coverage;

		coverage = ntohs(udplite->cov);
		if ((coverage == 0) || (coverage > l4_bytes))
			coverage = l4_bytes;
		udplite->check = 0;
		udplite->check = udplite_v4_checksum(ipv4->src_ip,
						     ipv4->dst_ip,
						     IPPROTO_UDPLITE,
						     udplite,
						     l4_bytes, coverage);
	} else if (packet->icmpv4 != NULL) {
		struct icmpv4 *icmpv4 = packet->icmpv4;
		icmpv4->checksum = 0;
		icmpv4->checksum = ipv4_checksum(icmpv4, l4_bytes);
	} else {
		assert(!"not SCTP or TCP or UDP or UDPLite or ICMP");
	}
}
示例#3
0
		0xa0, 0x12, 0x16, 0xa0, 0x54, 0x12, 0x00, 0x00,
		0x02, 0x04, 0x05, 0xb4, 0x04, 0x02, 0x08, 0x0a,
		0x00, 0x00, 0x02, 0xbc, 0x00, 0x06, 0x0a, 0xd8,
		0x01, 0x03, 0x03, 0x07,
	};

	struct in_addr src_ip, dst_ip;
	struct tcp *tcp = (struct tcp *) (data + sizeof(struct ipv4));
	int len = sizeof(data) - sizeof(struct ipv4);
	u16 checksum = 0;

	assert(inet_pton(AF_INET, "1.1.1.1", &src_ip) == 1);
	assert(inet_pton(AF_INET, "192.168.0.1", &dst_ip) == 1);

	checksum =
	    ntohs(tcp_udp_v4_checksum(src_ip, dst_ip, IPPROTO_TCP, tcp, len));
	assert(checksum == 0);

	tcp->check = 0;
	checksum =
	    ntohs(tcp_udp_v4_checksum(src_ip, dst_ip, IPPROTO_TCP, tcp, len));
	assert(checksum == 0x5412);
}

static void test_tcp_udp_v6_checksum(void)
{
	u8 data[] __aligned(4) = {
		0x60, 0x00, 0x00, 0x00, 0x00, 0x20, 0x06, 0xff,
		0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
		0xfd, 0x3d, 0xfa, 0x7b, 0xd1, 0x7d, 0x00, 0x00,