bool test_tcp_v6_fin_rcv_state_handle( void ) { struct sk_buff *skb; struct session_entry session; bool success = true; /* A V4 FIN packet arrives. */ if (!init_skb_and_session(&skb, &session, PACKET_TYPE_V4_FIN, V6_FIN_RCV, 10)) return false; success &= assert_true(tcp_v6_fin_rcv_state_handle( skb, &session ), "V4 fin-result"); success &= assert_equals_u8(V4_FIN_V6_FIN_RCV, session.state, "V4 fin-state"); success &= assert_not_equals_int(10, session.dying_time, "V4 fin-lifetime"); kfree_skb(skb); /* Something else arrives. */ if (!init_skb_and_session(&skb, &session, PACKET_TYPE_V4_SYN, V6_FIN_RCV, 10)) return false; success &= assert_true(tcp_v6_fin_rcv_state_handle(skb, &session), "else-result"); success &= assert_equals_u8(V6_FIN_RCV, session.state, "else-state"); success &= assert_not_equals_int(10, session.dying_time, "else-lifetime"); kfree_skb(skb); return success; }
bool test_tcp_v6_init_state_handle( void ) { struct sk_buff *skb; struct session_entry session; bool success = true; // A V4 SYN packet arrives. if (!init_skb_and_session(&skb, &session, PACKET_TYPE_V4_SYN, V6_INIT, 10)) return false; success &= assert_true(tcp_v6_init_state_handle(skb, &session), "V4 syn-result"); success &= assert_equals_u8(ESTABLISHED, session.state, "V4 syn-state"); success &= assert_not_equals_int(10, session.dying_time, "V4 syn-lifetime"); kfree_skb(skb); // A V6 SYN packet arrives. if (!init_skb_and_session(&skb, &session, PACKET_TYPE_V6_SYN, V6_INIT, 10)) return false; success &= assert_true(tcp_v6_init_state_handle(skb, &session), "V6 syn-result"); success &= assert_equals_u8(V6_INIT, session.state, "V6 syn-state"); success &= assert_not_equals_int(10, session.dying_time, "V6 syn-lifetime"); kfree_skb(skb); // Something else arrives. if (!init_skb_and_session(&skb, &session, PACKET_TYPE_V6_RST, V6_INIT, 10)) return false; success &= assert_true(tcp_v6_init_state_handle(skb, &session), "else-result"); success &= assert_equals_u8(V6_INIT, session.state, "else-state"); success &= assert_equals_int(10, session.dying_time, "else-lifetime"); kfree_skb(skb); return success; }
bool validate_ipv4_hdr(struct iphdr *hdr, u16 total_len, u16 id, u16 df, u16 mf, u16 frag_off, u8 protocol, struct tuple *tuple4) { struct in_addr addr; bool success = true; success &= assert_equals_u8(4, hdr->version, "IPv4hdr-Version"); success &= assert_equals_u8(5, hdr->ihl, "IPv4hdr-IHL"); success &= assert_equals_u8(0, hdr->tos, "IPv4hdr-TOS"); success &= assert_equals_u16(total_len, be16_to_cpu(hdr->tot_len), "IPv4hdr-total length"); success &= assert_equals_u16(id, be16_to_cpu(hdr->id), "IPv4hdr-ID"); success &= assert_equals_u16(df, be16_to_cpu(hdr->frag_off) & IP_DF, "IPv4hdr-DF"); success &= assert_equals_u16(mf, be16_to_cpu(hdr->frag_off) & IP_MF, "IPv4hdr-MF"); success &= assert_equals_u16(frag_off, get_fragment_offset_ipv4(hdr), "IPv4hdr-Frag offset"); /* success &= assert_equals_u8(, hdr->ttl, "IPv4 header - TTL"); */ success &= assert_equals_u8(protocol, hdr->protocol, "IPv4hdr-protocol"); addr.s_addr = hdr->saddr; success &= assert_equals_ipv4(&tuple4->src.addr4.l3, &addr, "IPv4hdr-src address"); addr.s_addr = hdr->daddr; success &= assert_equals_ipv4(&tuple4->dst.addr4.l3, &addr, "IPv4hdr-dst address"); return success; }
bool test_tcp_trans_state_handle( void ) { struct sk_buff *skb; struct session_entry session; bool success = true; /* A V4 RST packet arrives. */ if (!init_skb_and_session(&skb, &session, PACKET_TYPE_V4_RST, TRANS, 10)) return false; success &= assert_true(tcp_trans_state_handle( skb, &session ), "V4 rst-result"); success &= assert_equals_u8(TRANS, session.state, "V4 rst-state"); success &= assert_equals_int(10, session.dying_time, "V4 rst-lifetime"); kfree_skb(skb); /* A V6 RST packet arrives. */ if (!init_skb_and_session(&skb, &session, PACKET_TYPE_V6_RST, TRANS, 10)) return false; success &= assert_true(tcp_trans_state_handle( skb, &session ), "V6 rst-result"); success &= assert_equals_u8(TRANS, session.state, "V6 rst-state"); success &= assert_equals_int(10, session.dying_time, "V6 rst-lifetime"); kfree_skb(skb); /* Something else arrives. */ if (!init_skb_and_session(&skb, &session, PACKET_TYPE_V4_SYN, TRANS, 10)) return false; success &= assert_true(tcp_trans_state_handle(skb, &session), "else-result"); success &= assert_equals_u8(ESTABLISHED, session.state, "else-state"); success &= assert_not_equals_int(10, session.dying_time, "else-lifetime"); kfree_skb(skb); return success; }
bool validate_icmp4_hdr_error(struct icmphdr *hdr) { bool success = true; success &= assert_equals_u8(ICMP_DEST_UNREACH, hdr->type, "ICMP4hdr-type"); success &= assert_equals_u8(ICMP_FRAG_NEEDED, hdr->code, "ICMP4hdr-code"); /* success &= assert_equals_u16(3100, be16_to_cpu(hdr->un.frag.mtu), "ICMP4hdr-MTU"); */ return success; }
bool validate_icmp6_hdr_error(struct icmp6hdr *hdr) { bool success = true; success &= assert_equals_u8(ICMPV6_PKT_TOOBIG, hdr->icmp6_type, "ICMP6hdr-type"); success &= assert_equals_u8(0, hdr->icmp6_code, "ICMP6hdr-code"); /* success &= assert_equals_u32(1300, be32_to_cpu(hdr->icmp6_mtu), "ICMP6hdr-MTU"); */ return success; }
bool validate_icmp4_hdr(struct icmphdr *hdr, u16 id, struct tuple *tuple4) { bool success = true; success &= assert_equals_u8(ICMP_ECHO, hdr->type, "ICMP4hdr-type"); success &= assert_equals_u8(0, hdr->code, "ICMP4hdr-code"); success &= assert_equals_u16(tuple4->src.addr4.l4, be16_to_cpu(hdr->un.echo.id), "ICMP4id"); return success; }
bool validate_icmp6_hdr(struct icmp6hdr *hdr, u16 id, struct tuple *tuple6) { bool success = true; success &= assert_equals_u8(ICMPV6_ECHO_REQUEST, hdr->icmp6_type, "ICMP6hdr-type"); success &= assert_equals_u8(0, hdr->icmp6_code, "ICMP6hdr-code"); success &= assert_equals_u16(tuple6->src.addr6.l4, be16_to_cpu(hdr->icmp6_identifier), "ICMP6hdr id"); return success; }
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; }
bool validate_frag_hdr(struct frag_hdr *hdr, u16 frag_offset, u16 mf, __u8 nexthdr) { bool success = true; success &= assert_equals_u8(nexthdr, hdr->nexthdr, "Fraghdr-nexthdr"); success &= assert_equals_u8(0, hdr->reserved, "Fraghdr-nexthdr"); success &= assert_equals_u16(frag_offset, get_fragment_offset_ipv6(hdr), "Fraghdr-frag offset"); success &= assert_equals_u16(mf, is_more_fragments_set_ipv6(hdr), "Fraghdr-MF"); success &= assert_equals_u16(4321, be32_to_cpu(hdr->identification), "Fraghdr-ID"); return success; }
/** * By the way. This test kind of looks like it should test more combinations of headers. * But that'd be testing the header iterator, not the build_protocol_field() function. * Please look elsewhere for that. */ static bool test_function_build_protocol_field(void) { struct ipv6hdr *ip6_hdr; struct ipv6_opt_hdr *hop_by_hop_hdr; struct ipv6_opt_hdr *routing_hdr; struct ipv6_opt_hdr *dest_options_hdr; struct icmp6hdr *icmp6_hdr; ip6_hdr = kmalloc(sizeof(*ip6_hdr) + 8 + 16 + 24 + sizeof(struct tcphdr), GFP_ATOMIC); if (!ip6_hdr) { log_err("Could not allocate a test packet."); goto failure; } /* Just ICMP. */ ip6_hdr->nexthdr = NEXTHDR_ICMP; ip6_hdr->payload_len = cpu_to_be16(sizeof(*icmp6_hdr)); if (!assert_equals_u8(IPPROTO_ICMP, build_protocol_field(ip6_hdr), "Just ICMP")) goto failure; /* Skippable headers then ICMP. */ ip6_hdr->nexthdr = NEXTHDR_HOP; ip6_hdr->payload_len = cpu_to_be16(8 + 16 + 24 + sizeof(*icmp6_hdr)); hop_by_hop_hdr = (struct ipv6_opt_hdr *) (ip6_hdr + 1); hop_by_hop_hdr->nexthdr = NEXTHDR_ROUTING; hop_by_hop_hdr->hdrlen = 0; /* the hdrlen field does not include the first 8 octets. */ routing_hdr = (struct ipv6_opt_hdr *) (((unsigned char *) hop_by_hop_hdr) + 8); routing_hdr->nexthdr = NEXTHDR_DEST; routing_hdr->hdrlen = 1; dest_options_hdr = (struct ipv6_opt_hdr *) (((unsigned char *) routing_hdr) + 16); dest_options_hdr->nexthdr = NEXTHDR_ICMP; dest_options_hdr->hdrlen = 2; if (!assert_equals_u8(IPPROTO_ICMP, build_protocol_field(ip6_hdr), "Skippable then ICMP")) goto failure; /* Skippable headers then something else */ dest_options_hdr->nexthdr = NEXTHDR_TCP; ip6_hdr->payload_len = cpu_to_be16(8 + 16 + 24 + sizeof(struct tcphdr)); if (!assert_equals_u8(IPPROTO_TCP, build_protocol_field(ip6_hdr), "Skippable then TCP")) goto failure; kfree(ip6_hdr); return true; failure: kfree(ip6_hdr); return false; }
/* * A V6 RST packet arrives. */ static bool test_tcp_established_state_handle_v6rst(void) { struct session_entry *session; struct expire_timer *expirer; struct sk_buff *skb; unsigned long timeout; bool success = true; /* Prepare */ session = session_create_str_tcp("1::2", 1212, "3::4", 3434, "5.6.7.8", 5678, "8.7.6.5", 8765, ESTABLISHED); if (!session) return false; if (is_error(create_tcp_packet(&skb, L3PROTO_IPV6, false, true, false))) return false; /* Evaluate */ success &= assert_equals_int(0, tcp_established_state_handle(skb, session, &expirer), "result"); success &= assert_equals_u8(TRANS, session->state, "V6 rst-state"); success &= assert_equals_int(0, sessiondb_get_timeout(session, &timeout), "V6 rst-toresult"); success &= assert_equals_ulong(TCPTRANS_TIMEOUT, timeout, "V6 rst-lifetime"); kfree_skb(skb); return success; }
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_4to6(l4_protocol l4_proto) { struct tuple incoming, outgoing; bool success = true; incoming.src.addr.ipv4 = remote_ipv4; incoming.dst.addr.ipv4 = local_ipv4; incoming.src.l4_id = 123; /* Whatever */ incoming.dst.l4_id = 80; /* Lookup will use this. */ incoming.l3_proto = L3PROTO_IPV4; incoming.l4_proto = l4_proto; if (l4_proto != L4PROTO_ICMP) { success &= assert_equals_int(VER_CONTINUE, tuple5(&incoming, &outgoing), "Function5 call"); success &= assert_equals_u16(123, outgoing.src.l4_id, "Source port"); success &= assert_equals_u16(1500, outgoing.dst.l4_id, "Destination port"); } else { success &= assert_equals_int(VER_CONTINUE, tuple3(&incoming, &outgoing), "Function3 call"); success &= assert_equals_u16(1500, outgoing.icmp_id, "ICMP ID"); } success &= assert_equals_ipv6(&local_ipv6, &outgoing.src.addr.ipv6, "Source address"); success &= assert_equals_ipv6(&remote_ipv6, &outgoing.dst.addr.ipv6, "Destination address"); success &= assert_equals_u16(L3PROTO_IPV6, outgoing.l3_proto, "Layer-3 protocol"); success &= assert_equals_u8(l4_proto, outgoing.l4_proto, "Layer-4 protocol"); return success; }
/* * Something else arrives. */ static bool test_tcp_trans_state_handle_else(void) { struct session_entry *session; struct expire_timer *expirer; struct packet pkt; struct sk_buff *skb; unsigned long timeout = 0; bool success = true; /* Prepare */ session = session_create_str_tcp("1::2", 1212, "3::4", 3434, "5.6.7.8", 5678, "8.7.6.5", 8765, TRANS); if (!session) return false; if (is_error(create_tcp_packet(&skb, L3PROTO_IPV4, true, false, false))) return false; if (is_error(pkt_init_ipv4(&pkt, skb))) return false; /* Evaluate */ success &= assert_equals_int(0, tcp_trans_state_handle(&pkt, session, &expirer), "else-result"); success &= assert_equals_u8(ESTABLISHED, session->state, "else-state"); success &= assert_equals_int(0, sessiondb_get_timeout(session, &timeout), "else-toresult"); success &= assert_equals_ulong(TCPEST_TIMEOUT, timeout, "else-lifetime"); kfree_skb(skb); return success; }
/* * A V6 FIN packet arrives. */ static bool test_tcp_v4_fin_rcv_state_handle_v6fin(void) { struct session_entry *session; struct expire_timer *expirer; struct packet pkt; struct sk_buff *skb; unsigned long timeout = 0; bool success = true; /* Prepare */ session = session_create_str_tcp("1::2", 1212, "3::4", 3434, "5.6.7.8", 5678, "8.7.6.5", 8765, V4_FIN_RCV); if (!session) return false; if (is_error(create_tcp_packet(&skb, L3PROTO_IPV6, false, false, true))) return false; if (is_error(pkt_init_ipv6(&pkt, skb))) return false; /* Evaluate */ success &= assert_equals_int(0, tcp_v4_fin_rcv_state_handle(&pkt, session, &expirer), "V6 fin-result"); success &= assert_equals_u8(V4_FIN_V6_FIN_RCV, session->state, "V6 fin-state"); success &= assert_equals_int(0, sessiondb_get_timeout(session, &timeout), "V6 fin-toresult"); success &= assert_equals_ulong(TCPTRANS_TIMEOUT, timeout, "V6 fin-lifetime"); kfree_skb(skb); return success; }
/* * A V6 RST packet arrives. */ static bool test_tcp_trans_state_handle_v6rst(void) { struct session_entry *session; struct expire_timer *expirer; struct packet pkt; struct sk_buff *skb; bool success = true; /* Prepare */ session = session_create_str_tcp("1::2", 1212, "3::4", 3434, "5.6.7.8", 5678, "8.7.6.5", 8765, TRANS); if (!session) return false; if (is_error(create_tcp_packet(&skb, L3PROTO_IPV6, false, true, false))) return false; if (is_error(pkt_init_ipv6(&pkt, skb))) return false; /* Evaluate */ success &= assert_equals_int(0, tcp_trans_state_handle(&pkt, session, &expirer), "V6 rst-result"); success &= assert_equals_u8(TRANS, session->state, "V6 rst-state"); success &= assert_null(session->expirer, "null expirer"); kfree_skb(skb); return success; }
/* * A V4 FIN packet arrives. */ static bool test_tcp_established_state_handle_v4fin(void) { struct session_entry *session; struct expire_timer *expirer; struct packet pkt; struct sk_buff *skb; bool success = true; /* Prepare */ session = session_create_str_tcp("1::2", 1212, "3::4", 3434, "5.6.7.8", 5678, "8.7.6.5", 8765, ESTABLISHED); if (!session) return false; if (is_error(create_tcp_packet(&skb, L3PROTO_IPV4, false, false, true))) return false; if (is_error(pkt_init_ipv4(&pkt, skb))) return false; /* Evaluate */ success &= assert_equals_int(0, tcp_established_state_handle(&pkt, session, &expirer), "result"); success &= assert_equals_u8(V4_FIN_RCV, session->state, "V4 fin-state"); success &= assert_null(session->expirer, "null expirer"); kfree_skb(skb); return success; }
static bool test_function_icmp4_to_icmp6_param_prob(void) { struct icmphdr hdr4; struct icmp6hdr hdr6; bool success = true; hdr4.type = ICMP_PARAMETERPROB; hdr4.code = ICMP_PTR_INDICATES_ERROR; hdr4.icmp4_unused = cpu_to_be32(0x08000000); success &= assert_equals_int(0, icmp4_to_icmp6_param_prob(&hdr4, &hdr6), "func result 1"); success &= assert_equals_u8(ICMPV6_HDR_FIELD, hdr6.icmp6_code, "code"); success &= assert_equals_u8(7, be32_to_cpu(hdr6.icmp6_pointer), "pointer"); hdr4.icmp4_unused = cpu_to_be32(0x05000000); success &= assert_equals_int(-EINVAL, icmp4_to_icmp6_param_prob(&hdr4, &hdr6), "func result 2"); 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; }
bool validate_payload(unsigned char *payload, u16 len, u16 offset) { u16 i; for (i = 0; i < len; i++) { if (!assert_equals_u8(i + offset, payload[i], "Payload content")) return false; } return true; }
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_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; }
bool test_tcp_closed_state_handle_6( void ) { struct sk_buff *skb; struct session_entry *session; struct tuple tuple; bool success = true; if (!init_tuple_for_test_ipv6( &tuple, IPPROTO_TCP )) return false; if (!(skb = init_packet_type_for_test( PACKET_TYPE_V6_SYN ))) return false; success &= assert_true(tcp_closed_state_handle( skb, &tuple ), "V6 syn-result"); session = session_get( &tuple ); success &= assert_not_null(session, "V6 syn-session."); if (session) success &= assert_equals_u8(V6_INIT, session->state, "V6 syn-state"); kfree_skb(skb); return success; }
static bool test_4to6(bool (*function)(struct tuple *, struct tuple *), u_int8_t in_l4_protocol, u_int8_t out_l4_protocol) { struct tuple incoming, outgoing; bool success = true; incoming.src.addr.ipv4 = remote_ipv4; incoming.dst.addr.ipv4 = local_ipv4; incoming.src.l4_id = 123; // Whatever incoming.dst.l4_id = 80; // Lookup will use this. incoming.l3_proto = PF_INET; incoming.l4_proto = in_l4_protocol; success &= assert_true(function(&incoming, &outgoing), "Function call"); success &= assert_equals_ipv6(&local_ipv6, &outgoing.src.addr.ipv6, "Source address"); success &= assert_equals_ipv6(&remote_ipv6, &outgoing.dst.addr.ipv6, "Destination address"); success &= assert_equals_u16(PF_INET6, outgoing.l3_proto, "Layer-3 protocol"); success &= assert_equals_u8(out_l4_protocol, outgoing.l4_proto, "Layer-4 protocol"); // TODO (test) need to test ports? return success; }
bool validate_ipv6_hdr(struct ipv6hdr *hdr, u16 payload_len, u8 nexthdr, struct tuple *tuple6) { bool success = true; success &= assert_equals_u8(6, hdr->version, "IPv6hdr-version"); success &= assert_equals_u8(0, hdr->priority, "IPv6hdr-priority"); success &= assert_equals_u8(0, hdr->flow_lbl[0], "IPv6hdr-flow lbl[0]"); success &= assert_equals_u8(0, hdr->flow_lbl[1], "IPv6hdr-flow lbl[1]"); success &= assert_equals_u8(0, hdr->flow_lbl[2], "IPv6hdr-flow lbl[2]"); success &= assert_equals_u16(payload_len, be16_to_cpu(hdr->payload_len), "IPv6hdr-payload len"); success &= assert_equals_u8(nexthdr, hdr->nexthdr, "IPv6hdr-nexthdr"); /* success &= assert_equals_u8(, hdr->hop_limit, "IPv6hdr-hop limit"); */ success &= assert_equals_ipv6(&tuple6->src.addr6.l3, &hdr->saddr, "IPv6hdr-src address"); success &= assert_equals_ipv6(&tuple6->dst.addr6.l3, &hdr->daddr, "IPv6hdr-dst address"); 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; }
/** * We'll just chain a handful of packets, since testing every combination would take forever and * the inner functions were tested above anyway. * The chain is V6 SYN --> V4 SYN --> V6 RST --> V6 SYN. * * TODO (test) see test_ipv4_udp(). */ bool test_tcp( void ) { struct sk_buff *skb; struct session_entry *session; struct tuple tuple; bool success = true; /* V6 SYN */ skb = init_packet_type_for_test( PACKET_TYPE_V6_SYN ); if (!skb) goto failure; if (!init_tuple_for_test_ipv6( &tuple, IPPROTO_TCP )) goto failure; success &= assert_equals_int(NF_ACCEPT, tcp( skb, &tuple ), "Closed-result"); session = session_get(&tuple); success &= assert_not_null(session, "Closed-session"); if (session) success &= assert_equals_u8(V6_INIT, session->state, "Closed-state"); kfree_skb(skb); /* V4 SYN */ skb = init_packet_type_for_test( PACKET_TYPE_V4_SYN ); if (!skb) goto failure; if (!init_tuple_for_test_ipv4( &tuple, IPPROTO_TCP )) goto failure; success &= assert_equals_int(NF_ACCEPT, tcp( skb, &tuple ), "V6 init-result"); session = session_get(&tuple); success &= assert_not_null(session, "V6 init-session"); if (session) success &= assert_equals_u8(ESTABLISHED, session->state, "V6 init-state"); kfree_skb(skb); /* V6 RST */ skb = init_packet_type_for_test( PACKET_TYPE_V6_RST ); if (!skb) goto failure; if (!init_tuple_for_test_ipv6( &tuple, IPPROTO_TCP )) goto failure; success &= assert_equals_int(NF_ACCEPT, tcp( skb, &tuple ), "Established-result"); session = session_get(&tuple); success &= assert_not_null(session, "Established-session"); if (session) success &= assert_equals_u8(TRANS, session->state, "Established-state"); kfree_skb(skb); /* V6 SYN */ skb = init_packet_type_for_test( PACKET_TYPE_V6_SYN ); if (!skb) goto failure; if (!init_tuple_for_test_ipv6( &tuple, IPPROTO_TCP )) goto failure; success &= assert_equals_int(NF_ACCEPT, tcp( skb, &tuple ), "Trans-result"); session = session_get(&tuple); success &= assert_not_null(session, "Trans-session"); if (session) success &= assert_equals_u8(ESTABLISHED, session->state, "Trans-state"); kfree_skb(skb); return success; failure: kfree_skb(skb); return false; }