Lines Matching +full:ipv4 +full:- +full:no +full:- +full:config +full:- +full:for +full:- +full:cpp
8 * http://www.apache.org/licenses/LICENSE-2.0
13 * See the License for the specific language governing permissions and
16 * clatd_test.cpp - unit tests for clatd
35 #include "config.h"
39 // For convenience.
49 // clang-format off
76 0xc8, 0x8b, 0, 53, /* Port 51339->53 */ \
77 0x00, UDP_LEN, 0, 0, /* Length 21, checksum empty for now */
89 // Macros to return pseudo-headers from packets.
174 // clang-format on
189 return ntohs(ip->frag_off) & (IP_OFFMASK | IP_MF); in is_ipv4_fragment()
193 if (ip6->ip6_nxt != IPPROTO_FRAGMENT) { in is_ipv6_fragment()
198 (frag->ip6f_offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG)); in is_ipv6_fragment()
202 return ntohs(ip->frag_off) & IP_OFFMASK; in ipv4_fragment_offset()
206 return ntohs((frag->ip6f_offlg & IP6F_OFF_MASK) >> 3); in ipv6_fragment_offset()
218 ASSERT_GE(len, sizeof(*ip)) << msg << ": IPv4 packet shorter than IPv4 header\n"; in check_packet()
219 EXPECT_EQ(5, ip->ihl) << msg << ": Unsupported IP header length\n"; in check_packet()
220 EXPECT_EQ(len, ntohs(ip->tot_len)) << msg << ": Incorrect IPv4 length\n"; in check_packet()
222 protocol = ip->protocol; in check_packet()
225 payload_length = len - sizeof(*ip); in check_packet()
229 << msg << ": Unsupported IPv4 protocol " << protocol << "\n"; in check_packet()
235 EXPECT_EQ(len - sizeof(*ip6), htons(ip6->ip6_plen)) << msg << ": Incorrect IPv6 length\n"; in check_packet()
237 if (ip6->ip6_nxt == IPPROTO_FRAGMENT) { in check_packet()
241 protocol = frag->ip6f_nxt; in check_packet()
245 payload_length = len - sizeof(*ip6) - sizeof(*frag); in check_packet()
248 // Since there are no extension headers except Fragment, this must be the payload. in check_packet()
249 protocol = ip6->ip6_nxt; in check_packet()
251 payload_length = len - sizeof(*ip6); in check_packet()
286 EXPECT_NE(0, udp->check) << msg << ": UDP checksum 0 should be 0xffff"; in check_packet()
289 EXPECT_EQ(payload_length, ntohs(udp->len)) << msg << ": Incorrect UDP length\n"; in check_packet()
302 for (int i = 0; i < numpackets; i++) { in reassemble_packet()
315 << msg << ": IPv4 fragment #" << i + 1 << " not a fragment\n"; in reassemble_packet()
317 << msg << ": IPv4 fragment #" << i + 1 << ": inconsistent offset\n"; in reassemble_packet()
338 protocol = frag->ip6f_nxt; in reassemble_packet()
355 int payload_length = len - payload_offset; in reassemble_packet()
362 // Fix up the reassembled headers to reflect fragmentation and length (and IPv4 checksum). in reassemble_packet()
365 ip->frag_off &= ~htons(IP_MF); in reassemble_packet()
366 ip->tot_len = htons(total_length); in reassemble_packet()
367 ip->check = 0; in reassemble_packet()
368 ip->check = ip_checksum(ip, sizeof(*ip)); in reassemble_packet()
369 ASSERT_FALSE(is_ipv4_fragment(ip)) << msg << ": reassembled IPv4 packet is a fragment!\n"; in reassemble_packet()
372 ip6->ip6_nxt = protocol; in reassemble_packet()
373 ip6->ip6_plen = htons(total_length - sizeof(*ip6)); in reassemble_packet()
374 ASSERT_FALSE(is_ipv6_fragment(ip6, ip6->ip6_plen)) in reassemble_packet()
387 for (unsigned i = 0; i < len; i++) { in check_data_matches()
389 snprintf(expected_hexdump + pos, hexdump_len - pos, "\n "); in check_data_matches()
390 snprintf(actual_hexdump + pos, hexdump_len - pos, "\n "); in check_data_matches()
393 snprintf(expected_hexdump + pos, hexdump_len - pos, " %02x", ((uint8_t *)expected)[i]); in check_data_matches()
394 snprintf(actual_hexdump + pos, hexdump_len - pos, " %02x", ((uint8_t *)actual)[i]); in check_data_matches()
411 pseudo_checksum = ipv4_pseudo_header_checksum(ip, ntohs(udp->len)); in fix_udp_checksum()
417 pseudo_checksum = ipv6_pseudo_header_checksum(ip6, ntohs(udp->len), IPPROTO_UDP); in fix_udp_checksum()
425 udp->check = 0; in fix_udp_checksum()
426 udp->check = ip_checksum_finish(ip_checksum_add(pseudo_checksum, udp, ntohs(udp->len))); in fix_udp_checksum()
429 // Testing stub for send_rawv6. The real version uses sendmsg() with a
468 // Translating to IPv4. Expect a tun header. in do_translate_packet()
479 *outlen = len - sizeof(new_tun_header); in do_translate_packet()
504 for (int i = 0; i < numfragments; i++) { in check_fragment_translation()
535 return -1; in get_transport_checksum()
537 protocol = ip->protocol; in get_transport_checksum()
542 protocol = ip6->ip6_nxt; in get_transport_checksum()
546 return -1; in get_transport_checksum()
551 return ((struct udphdr *)payload)->check; in get_transport_checksum()
554 return ((struct tcphdr *)payload)->check; in get_transport_checksum()
558 return -1; in get_transport_checksum()
615 ASSERT_EQ(sizeof(struct iphdr), sizeof(v4_header)) << "Test IPv4 header: incorrect length\n"; in TEST_F()
628 ASSERT_EQ(kUdpV4Checksum, udp->check) << "UDP/IPv4 packet checksum sanity check\n"; in TEST_F()
629 check_packet(v4_udp_packet, sizeof(v4_udp_packet), "UDP/IPv4 packet sanity check"); in TEST_F()
634 ASSERT_EQ(kUdpV6Checksum, udp->check) << "UDP/IPv6 packet checksum sanity check\n"; in TEST_F()
638 check_packet(ipv4_ping, sizeof(ipv4_ping), "IPv4 ping sanity check"); in TEST_F()
648 check_packet(reassembled, total_length, "IPv4 Reassembled packet is valid"); in TEST_F()
649 ASSERT_EQ(sizeof(kReassembledIPv4), total_length) << "IPv4 reassembly sanity check: length\n"; in TEST_F()
652 check_data_matches(kReassembledIPv4, reassembled, total_length, "IPv4 reassembly sanity check"); in TEST_F()
696 EXPECT_EQ(0x3ad0U, ipv4_pseudo_sum % 0xFFFF) << "IPv4 pseudo-checksum sanity check\n"; in TEST_F()
697 EXPECT_EQ(0x644dU, ipv6_pseudo_sum % 0xFFFF) << "IPv6 pseudo-checksum sanity check\n"; in TEST_F()
701 << "Unexpected UDP/IPv4 checksum\n"; in TEST_F()
709 << "Adjust IPv4/UDP checksum to IPv6\n"; in TEST_F()
712 << "Adjust IPv6/UDP checksum to IPv4\n"; in TEST_F()
730 for (i = 0; i < ARRAYSIZE(DATA); i++) { in TEST_F()
732 uint16_t result = ip_checksum_adjust(data->checksum, data->old_hdr_sum, data->new_hdr_sum); in TEST_F()
733 EXPECT_EQ(result, data->result) in TEST_F()
735 << "\n Expected: " << data->result in TEST_F()
737 << "\n checksum=" << data->checksum in TEST_F()
738 << " old_sum=" << data->old_hdr_sum << " new_sum=" << data->new_hdr_sum << "\n"; in TEST_F()
751 "UDP/IPv4 -> UDP/IPv6 translation"); in TEST_F()
753 "UDP/IPv6 -> UDP/IPv4 translation"); in TEST_F()
758 "ICMP->ICMPv6 translation"); in TEST_F()
760 "ICMPv6->ICMP translation"); in TEST_F()
768 ARRAYSIZE(kIPv4Fragments), "IPv4->IPv6 fragment translation"); in TEST_F()
771 ARRAYSIZE(kIPv6Fragments), "IPv6->IPv4 fragment translation"); in TEST_F()
774 // picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix
778 arc4random_buf(&myaddr->s6_addr[8], 8); in gen_random_iid()
780 // Make the IID checksum-neutral. That is, make it so that: in gen_random_iid()
781 // checksum(Local IPv4 | Remote IPv4) = checksum(Local IPv6 | Remote IPv6) in gen_random_iid()
782 // in other words (because remote IPv6 = NAT64 prefix | Remote IPv4): in gen_random_iid()
783 // checksum(Local IPv4) = checksum(Local IPv6 | NAT64 prefix) in gen_random_iid()
786 uint16_t middlebytes = (myaddr->s6_addr[11] << 8) + myaddr->s6_addr[12]; in gen_random_iid()
793 myaddr->s6_addr[11] = delta >> 8; in gen_random_iid()
794 myaddr->s6_addr[12] = delta & 0xff; in gen_random_iid()
803 // do_translate_packet already checks packets for validity and verifies the checksum. in check_translate_checksum_neutral()
806 ASSERT_NE(-1, original_check); in check_translate_checksum_neutral()
807 ASSERT_NE(-1, translated_check); in check_translate_checksum_neutral()
813 // Generate a random clat IPv6 address and check that translation is checksum-neutral. in TEST_F()
823 // Check that translating UDP packets is checksum-neutral. First, IPv4. in TEST_F()
827 "UDP/IPv4 -> UDP/IPv6 checksum neutral"); in TEST_F()
833 memcpy(&ip6->ip6_src, &Global_Clatd_Config.ipv6_local_subnet, sizeof(ip6->ip6_src)); in TEST_F()
836 "UDP/IPv4 -> UDP/IPv6 checksum neutral"); in TEST_F()