static bool test_last_function_unsupported(void) { bool success = true; struct hdr_iterator iterator; /* Init */ struct ipv6hdr *ip6_header; struct frag_hdr *fragment_hdr; struct ipv6_opt_hdr *esp_hdr; struct ipv6_opt_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 */ hdr_iterator_init(&iterator, ip6_header); success &= assert_equals_int(HDR_ITERATOR_UNSUPPORTED, hdr_iterator_last(&iterator), "Result"); success &= assert_equals_ptr(esp_hdr, iterator.data, "Last function, data"); success &= assert_equals_u8(NEXTHDR_ESP, iterator.hdr_type, "Last function, type"); /* End */ kfree(ip6_header); return success; }
static bool test_last_unsupported(void) { bool success = true; struct hdr_iterator iterator; /* Init */ struct ipv6hdr *hdr6; struct frag_hdr *hdr_frag; struct ipv6_opt_hdr *hdr_esp; struct ipv6_opt_hdr *hdr_route; unsigned char *payload; hdr6 = kmalloc_packet(FRAG_HDR_LEN + OPT_HDR_LEN + ROUTE_HDR_LEN + 4, NEXTHDR_FRAGMENT); if (!hdr6) return false; hdr_frag = add_frag_hdr(hdr6, HDR6_LEN, NEXTHDR_ESP); hdr_esp = add_opt_hdr(hdr_frag, FRAG_HDR_LEN, FRAG_HDR_LEN); hdr_route = add_route_hdr(hdr_esp, OPT_HDR_LEN, NEXTHDR_UDP); payload = add_payload(hdr_route, ROUTE_HDR_LEN); /* Test */ hdr_iterator_init(&iterator, hdr6); hdr_iterator_last(&iterator); success &= ASSERT_PTR(hdr_esp, iterator.data, "Last:data"); success &= ASSERT_UINT(NEXTHDR_ESP, iterator.hdr_type, "Last:type"); /* End */ kfree(hdr6); return success; }
static bool test_next_subheaders(void) { bool success = true; struct hdr_iterator iterator; /* Init */ struct ipv6hdr *hdr6; struct frag_hdr *hdr_frag; struct ipv6_opt_hdr *hdr_hop; struct ipv6_opt_hdr *hdr_route; unsigned char *payload; hdr6 = kmalloc_packet(FRAG_HDR_LEN + OPT_HDR_LEN + ROUTE_HDR_LEN + 4, NEXTHDR_FRAGMENT); if (!hdr6) return false; hdr_frag = add_frag_hdr(hdr6, HDR6_LEN, NEXTHDR_HOP); hdr_hop = add_opt_hdr(hdr_frag, FRAG_HDR_LEN, NEXTHDR_ROUTING); hdr_route = add_route_hdr(hdr_hop, OPT_HDR_LEN, NEXTHDR_UDP); payload = add_payload(hdr_route, ROUTE_HDR_LEN); /* Test */ hdr_iterator_init(&iterator, hdr6); success &= ASSERT_PTR(hdr_frag, iterator.data, "Frag:data"); success &= ASSERT_UINT(NEXTHDR_FRAGMENT, iterator.hdr_type, "Frag:type"); if (!success) goto end; success &= ASSERT_INT(EAGAIN, hdr_iterator_next(&iterator), "Next 1"); success &= ASSERT_PTR(hdr_hop, iterator.data, "Hop:data"); success &= ASSERT_UINT(NEXTHDR_HOP, iterator.hdr_type, "Hop:type"); if (!success) goto end; success &= ASSERT_INT(EAGAIN, hdr_iterator_next(&iterator), "Next 2"); success &= ASSERT_PTR(hdr_route, iterator.data, "Routing:data"); success &= ASSERT_UINT(NEXTHDR_ROUTING, iterator.hdr_type, "Routing:type"); if (!success) goto end; success &= ASSERT_INT(EAGAIN, hdr_iterator_next(&iterator), "Next 3"); success &= ASSERT_PTR(payload, iterator.data, "Payload1:data"); success &= ASSERT_UINT(NEXTHDR_UDP, iterator.hdr_type, "Payload1:type"); if (!success) goto end; success &= ASSERT_INT(0, hdr_iterator_next(&iterator), "Next 4"); success &= ASSERT_PTR(payload, iterator.data, "Payload2:data"); success &= ASSERT_UINT(NEXTHDR_UDP, iterator.hdr_type, "Payload2:type"); /* Fall through. */ end: kfree(hdr6); return success; }
void hdr_iterator_init_truncated(struct hdr_iterator *iterator, struct ipv6hdr *main_hdr, unsigned int limit) { void *limit_ptr = main_hdr + limit; hdr_iterator_init(iterator, main_hdr); if (limit_ptr < iterator->limit) iterator->limit = limit_ptr; }
static bool test_next_function_subheaders(void) { bool success = true; struct hdr_iterator iterator; /* Init */ 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_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_HOP); hop_by_hop_hdr = add_opt_hdr(fragment_hdr, FRAG_HDR_LEN, NEXTHDR_ROUTING); routing_hdr = add_routing_hdr(hop_by_hop_hdr, OPT_HDR_LEN, NEXTHDR_UDP); payload = add_payload(routing_hdr, ROUTING_HDR_LEN); /* Test */ hdr_iterator_init(&iterator, ip6_header); success &= assert_equals_ptr(fragment_hdr, iterator.data, "Frag hdr, data"); success &= assert_equals_u8(NEXTHDR_FRAGMENT, iterator.hdr_type, "Frag hdr, type"); if (!success) goto end; success &= assert_equals_int(HDR_ITERATOR_SUCCESS, hdr_iterator_next(&iterator), "Next 1"); success &= assert_equals_ptr(hop_by_hop_hdr, iterator.data, "Hop-by-hop hdr, data"); success &= assert_equals_u8(NEXTHDR_HOP, iterator.hdr_type, "Hop-by-hop hdr, type"); if (!success) goto end; success &= assert_equals_int(HDR_ITERATOR_SUCCESS, hdr_iterator_next(&iterator), "Next 2"); success &= assert_equals_ptr(routing_hdr, iterator.data, "Routing hdr, data"); success &= assert_equals_u8(NEXTHDR_ROUTING, iterator.hdr_type, "Routing hdr, type"); if (!success) goto end; success &= assert_equals_int(HDR_ITERATOR_SUCCESS, hdr_iterator_next(&iterator), "Next 3"); success &= assert_equals_ptr(payload, iterator.data, "Payload 1, data"); success &= assert_equals_u8(NEXTHDR_UDP, iterator.hdr_type, "Payload 1, type"); if (!success) goto end; success &= assert_equals_int(HDR_ITERATOR_END, hdr_iterator_next(&iterator), "Next 4"); success &= assert_equals_ptr(payload, iterator.data, "Payload 2, data"); success &= assert_equals_u8(NEXTHDR_UDP, iterator.hdr_type, "Payload 2, type"); /* Fall through. */ end: kfree(ip6_header); return success; }
static bool test_next_unsupported(void) { bool success = true; struct hdr_iterator iterator; /* Init */ struct ipv6hdr *hdr6; struct frag_hdr *hdr_frag; struct ipv6_opt_hdr *hdr_esp; struct ipv6_opt_hdr *hdr_route; unsigned char *payload; hdr6 = kmalloc_packet(FRAG_HDR_LEN + OPT_HDR_LEN + ROUTE_HDR_LEN + 4, NEXTHDR_FRAGMENT); if (!hdr6) return false; hdr_frag = add_frag_hdr(hdr6, HDR6_LEN, NEXTHDR_ESP); hdr_esp = add_opt_hdr(hdr_frag, FRAG_HDR_LEN, FRAG_HDR_LEN); hdr_route = add_route_hdr(hdr_esp, OPT_HDR_LEN, NEXTHDR_UDP); payload = add_payload(hdr_route, ROUTE_HDR_LEN); /* Test */ hdr_iterator_init(&iterator, hdr6); success &= ASSERT_PTR(hdr_frag, iterator.data, "Frag:pointer"); success &= ASSERT_UINT(NEXTHDR_FRAGMENT, iterator.hdr_type, "Frag:type"); if (!success) goto end; success &= ASSERT_INT(EAGAIN, hdr_iterator_next(&iterator), "Next 1"); success &= ASSERT_PTR(hdr_esp, iterator.data, "ESP1:pointer"); success &= ASSERT_UINT(NEXTHDR_ESP, iterator.hdr_type, "ESP1:type"); if (!success) goto end; success &= ASSERT_INT(0, hdr_iterator_next(&iterator), "Next 2"); success &= ASSERT_PTR(hdr_esp, iterator.data, "ESP2:pointer"); success &= ASSERT_UINT(NEXTHDR_ESP, iterator.hdr_type, "ESP2:type"); /* Fall through. */ end: kfree(hdr6); return success; }
static bool test_next_function_unsupported(void) { bool success = true; struct hdr_iterator iterator; /* Init */ struct ipv6hdr *ip6_header; struct frag_hdr *fragment_hdr; struct ipv6_opt_hdr *esp_hdr; struct ipv6_opt_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 */ hdr_iterator_init(&iterator, ip6_header); success &= assert_equals_ptr(fragment_hdr, iterator.data, "Frag hdr, pointer"); success &= assert_equals_u8(NEXTHDR_FRAGMENT, iterator.hdr_type, "Frag hdr, type"); if (!success) goto end; success &= assert_equals_int(HDR_ITERATOR_SUCCESS, hdr_iterator_next(&iterator), "Next 1"); success &= assert_equals_ptr(esp_hdr, iterator.data, "ESP hdr, pointer"); success &= assert_equals_u8(NEXTHDR_ESP, iterator.hdr_type, "ESP hdr, type"); if (!success) goto end; success &= assert_equals_int(HDR_ITERATOR_UNSUPPORTED, hdr_iterator_next(&iterator), "Next 2"); success &= assert_equals_ptr(esp_hdr, iterator.data, "Still ESP header, pointer"); success &= assert_equals_u8(NEXTHDR_ESP, iterator.hdr_type, "Still ESP header, type"); /* Fall through. */ end: kfree(ip6_header); return success; }
static bool test_next_function_no_subheaders(void) { bool success = true; struct hdr_iterator iterator; /* 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 */ hdr_iterator_init(&iterator, ip6_header); success &= assert_equals_ptr(payload, iterator.data, "Payload 1, data"); success &= assert_equals_u8(NEXTHDR_UDP, iterator.hdr_type, "Payload 1, type"); if (!success) goto end; success &= assert_equals_int(HDR_ITERATOR_END, hdr_iterator_next(&iterator), "Result 1"); success &= assert_equals_ptr(payload, iterator.data, "Payload 2, data"); success &= assert_equals_u8(NEXTHDR_UDP, iterator.hdr_type, "Payload 2, type"); if (!success) goto end; success &= assert_equals_int(HDR_ITERATOR_END, hdr_iterator_next(&iterator), "Result 2"); success &= assert_equals_int(HDR_ITERATOR_END, hdr_iterator_next(&iterator), "Result 3"); success &= assert_equals_int(HDR_ITERATOR_END, hdr_iterator_next(&iterator), "Result 4"); success &= assert_equals_ptr(payload, iterator.data, "Payload 3, data"); success &= assert_equals_u8(NEXTHDR_UDP, iterator.hdr_type, "Payload 3, type"); /* Fall through. */ end: kfree(ip6_header); return success; }
static bool test_next_no_subheaders(void) { bool success = true; struct hdr_iterator iterator; /* Init */ struct ipv6hdr *hdr6; unsigned char *payload; hdr6 = kmalloc_packet(4, NEXTHDR_UDP); if (!hdr6) return false; payload = add_payload(hdr6, HDR6_LEN); /* Test */ hdr_iterator_init(&iterator, hdr6); success &= ASSERT_PTR(payload, iterator.data, "Payload1:data"); success &= ASSERT_UINT(NEXTHDR_UDP, iterator.hdr_type, "Payload1:type"); if (!success) goto end; success &= ASSERT_INT(0, hdr_iterator_next(&iterator), "Result1"); success &= ASSERT_PTR(payload, iterator.data, "Payload2:data"); success &= ASSERT_UINT(NEXTHDR_UDP, iterator.hdr_type, "Payload2:type"); if (!success) goto end; success &= ASSERT_INT(0, hdr_iterator_next(&iterator), "Result2"); success &= ASSERT_INT(0, hdr_iterator_next(&iterator), "Result3"); success &= ASSERT_INT(0, hdr_iterator_next(&iterator), "Result4"); success &= ASSERT_PTR(payload, iterator.data, "Payload3:data"); success &= ASSERT_UINT(NEXTHDR_UDP, iterator.hdr_type, "Payload3:type"); /* Fall through. */ end: kfree(hdr6); return success; }
static bool test_last_function_overflow(void) { bool success = true; struct hdr_iterator iterator; /* 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, NEXTHDR_FRAGMENT, NEXTHDR_ROUTING); /* Test */ hdr_iterator_init(&iterator, ip6_header); success &= assert_equals_int(HDR_ITERATOR_OVERFLOW, hdr_iterator_last(&iterator), "Result"); /* End */ kfree(ip6_header); return success; }
static bool test_last_function_no_subheaders(void) { bool success = true; struct hdr_iterator iterator; /* 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 */ hdr_iterator_init(&iterator, ip6_header); success &= assert_equals_int(HDR_ITERATOR_END, hdr_iterator_last(&iterator), "Result"); success &= assert_equals_ptr(payload, iterator.data, "Last function, data"); success &= assert_equals_u8(NEXTHDR_UDP, iterator.hdr_type, "Last function, type"); /* End */ kfree(ip6_header); return success; }
static bool test_next_function_overflow(void) { bool success = true; struct hdr_iterator iterator; /* 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 */ hdr_iterator_init(&iterator, ip6_header); success &= assert_equals_ptr(fragment_hdr, iterator.data, "Frag hdr, data"); success &= assert_equals_u8(NEXTHDR_FRAGMENT, iterator.hdr_type, "Frag hdr, type"); if (!success) goto end; success &= assert_equals_int(HDR_ITERATOR_SUCCESS, hdr_iterator_next(&iterator), "Next 1"); success &= assert_equals_ptr(hop_by_hop_hdr, iterator.data, "Hop-by-hop hdr, data"); success &= assert_equals_u8(NEXTHDR_HOP, iterator.hdr_type, "Hop-by-hop hdr, type"); if (!success) goto end; success &= assert_equals_int(HDR_ITERATOR_OVERFLOW, hdr_iterator_next(&iterator), "Next 2"); /* Fall through. */ end: kfree(ip6_header); return success; }
static bool test_last_no_subheaders(void) { bool success = true; struct hdr_iterator iterator; /* Init */ struct ipv6hdr *hdr6; unsigned char *payload; hdr6 = kmalloc_packet(4, NEXTHDR_UDP); if (!hdr6) return false; payload = add_payload(hdr6, HDR6_LEN); /* Test */ hdr_iterator_init(&iterator, hdr6); hdr_iterator_last(&iterator); success &= ASSERT_PTR(payload, iterator.data, "Last:data"); success &= ASSERT_UINT(NEXTHDR_UDP, iterator.hdr_type, "Last:type"); /* End */ kfree(hdr6); return success; }
bool determine_in_tuple(struct sk_buff *skb, struct tuple *tuple) { struct iphdr *hdr4; struct ipv6hdr *hdr6; struct icmphdr *icmp4; struct icmp6hdr *icmp6; struct hdr_iterator iterator; log_debug("Step 1: Determining the Incoming Tuple"); switch (be16_to_cpu(skb->protocol)) { case ETH_P_IP: hdr4 = ip_hdr(skb); switch (hdr4->protocol) { case IPPROTO_UDP: if (!ipv4_udp(hdr4, ipv4_extract_l4_hdr(hdr4), tuple)) return false; break; case IPPROTO_TCP: if (!ipv4_tcp(hdr4, ipv4_extract_l4_hdr(hdr4), tuple)) return false; break; case IPPROTO_ICMP: icmp4 = ipv4_extract_l4_hdr(hdr4); if (is_icmp4_info(icmp4->type)) { if (!ipv4_icmp_info(hdr4, icmp4, tuple)) return false; } else { if (!ipv4_icmp_err(hdr4, icmp4, tuple)) return false; } break; default: log_info("Unsupported transport protocol for IPv4: %d.", hdr4->protocol); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0); return false; } break; case ETH_P_IPV6: hdr6 = ipv6_hdr(skb); hdr_iterator_init(&iterator, hdr6); hdr_iterator_last(&iterator); switch (iterator.hdr_type) { case IPPROTO_UDP: if (!ipv6_udp(hdr6, iterator.data, tuple)) return false; break; case IPPROTO_TCP: if (!ipv6_tcp(hdr6, iterator.data, tuple)) return false; break; case IPPROTO_ICMPV6: icmp6 = iterator.data; if (is_icmp6_info(icmp6->icmp6_type)) { if (!ipv6_icmp_info(hdr6, icmp6, tuple)) return false; } else { if (!ipv6_icmp_err(hdr6, icmp6, tuple)) return false; } break; default: log_info("Unsupported transport protocol for IPv6: %d.", iterator.hdr_type); icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); return false; } break; default: log_info("Packet's protocol (%d) is not IPv4 or IPv6.", be16_to_cpu(skb->protocol)); return false; } log_tuple(tuple); log_debug("Done step 1."); return true; }
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; }