static bool test_6to4(l4_protocol l4_proto, int (*create_skb6_fn)(struct tuple *, struct sk_buff **, u16, u8), int (*create_skb4_fn)(struct tuple *, struct sk_buff **, u16, u8), u16 expected_payload4_len) { struct sk_buff *skb6 = NULL, *skb4_expected = NULL, *skb4_actual = NULL; struct tuple tuple6, tuple4; bool result = false; if (init_ipv6_tuple(&tuple6, "1::1", 50080, "64::192.0.2.5", 51234, L4PROTO_UDP) != 0 || init_ipv4_tuple(&tuple4, "192.0.2.2", 80, "192.0.2.5", 1234, L4PROTO_UDP) != 0 || create_skb6_fn(&tuple6, &skb6, 100, 32) != 0 || create_skb4_fn(&tuple4, &skb4_expected, expected_payload4_len, 31) != 0) goto end; if (translating_the_packet(&tuple4, skb6, &skb4_actual) != VER_CONTINUE) goto end; result = compare_skbs(skb4_expected, skb4_actual); /* Fall through. */ end: kfree_skb(skb6); kfree_skb(skb4_expected); kfree_skb(skb4_actual); return result; }
/** * "ars" means add, remove, send */ static bool test_pkt_queue_ars(void) { struct session_entry *session; struct sk_buff *skb; struct tuple tuple4; struct tcphdr *hdr_tcp; bool success = true; /* Prepare */ if (is_error(init_ipv4_tuple(&tuple4, "5.6.7.8", 5678, "192.168.2.1", 8765, L4PROTO_TCP))) return false; session = session_create_str_tcp("1::2", 1212, "3::4", 3434, "192.168.2.1", 8765, "5.6.7.8", 5678, V4_INIT); /* The session entry that is supposed to be created in "tcp_close_state_handle". */ if (!session) return false; if (is_error(create_skb4_tcp(&tuple4, &skb, 100, 32))) { session_return(session); return false; } hdr_tcp = tcp_hdr(skb); hdr_tcp->syn = true; hdr_tcp->rst = false; hdr_tcp->fin = false; success &= assert_equals_int(0, pktqueue_add(session, skb), "pktqueue_add 1"); success &= assert_equals_int(0, pktqueue_remove(session), "pktqueue_remove 1"); success &= assert_equals_int(-ENOENT, pktqueue_send(session), "pktqueue_send 1"); success &= assert_equals_int(0, icmp64_pop(), "pktqueue not sent an icmp error"); session_return(session); /* kfree_skb(skb); "skb" kfreed when pktqueue_remove is executed */ return success; }
int create_tcp_packet(struct sk_buff **skb, l3_protocol l3_proto, bool syn, bool rst, bool fin) { struct tcphdr *hdr_tcp; struct tuple tuple; int error; switch (l3_proto) { case L3PROTO_IPV4: error = init_ipv4_tuple(&tuple, "8.7.6.5", 8765, "5.6.7.8", 5678, L4PROTO_TCP); if (error) return error; error = create_skb4_tcp(&tuple, skb, 100, 32); if (error) return error; break; case L3PROTO_IPV6: error = init_ipv6_tuple(&tuple, "1::2", 1212, "3::4", 3434, L4PROTO_TCP); if (error) return error; error = create_skb6_tcp(&tuple, skb, 100, 32); if (error) return error; break; } hdr_tcp = tcp_hdr(*skb); hdr_tcp->syn = syn; hdr_tcp->rst = rst; hdr_tcp->fin = fin; return 0; }
static int init_payload_inner_ipv4(void *target, u16 payload_len) { struct iphdr *hdr_ipv4; struct tcphdr *hdr_tcp; struct iphdr tmp_hdr_ipv4; struct tcphdr tmp_hdr_tcp; unsigned char *inner_payload; struct tuple tuple4; int error; if (payload_len <= 0) return 0; /* Nothing to do here. */ error = init_ipv4_tuple(&tuple4, "192.0.2.5", 1234, "192.0.2.2", 80, L4PROTO_TCP); if (error) return error; hdr_ipv4 = target; hdr_tcp = (struct tcphdr *) (hdr_ipv4 + 1); inner_payload = (unsigned char *) (hdr_tcp + 1); error = init_ipv4_hdr(&tmp_hdr_ipv4, 1300, IPPROTO_TCP, &tuple4, true, false, 0, 32); if (error) return error; if (payload_len >= IPV4_HDR_LEN) { memcpy(hdr_ipv4, &tmp_hdr_ipv4, IPV4_HDR_LEN); payload_len -= IPV4_HDR_LEN; } else { memcpy(hdr_ipv4, &tmp_hdr_ipv4, payload_len); goto end; } error = init_tcp_hdr(&tmp_hdr_tcp, ETH_P_IP, 1300, &tuple4); if (error) return error; if (payload_len >= TCP_HDR_LEN) { memcpy(hdr_tcp, &tmp_hdr_tcp, TCP_HDR_LEN); payload_len -= TCP_HDR_LEN; } else { memcpy(hdr_tcp, &tmp_hdr_tcp, payload_len); goto end; } error = init_payload_normal(inner_payload, payload_len); if (error) return error; hdr_tcp->check = csum_tcpudp_magic(hdr_ipv4->saddr, hdr_ipv4->daddr, sizeof(*hdr_tcp) + payload_len, IPPROTO_TCP, csum_partial(hdr_tcp, sizeof(*hdr_tcp) + payload_len, 0)); /* Fall through. */ end: return 0; }
static bool test_determine_in_tuple_ipv4(void) { struct packet pkt; struct sk_buff *skb; struct tuple actual, expected; bool success = true; if (is_error(init_ipv4_tuple(&expected, "8.7.6.5", 8765, "5.6.7.8", 5678, L4PROTO_UDP))) return false; if (is_error(create_skb4_udp(&expected, &skb, 8, 32))) return false; if (is_error(pkt_init_ipv4(&pkt, skb))) return false; success &= assert_equals_int(VERDICT_CONTINUE, determine_in_tuple(&pkt, &actual), "verdict"); success &= assert_equals_tuple(&expected, &actual, "tuple"); kfree_skb(skb); return success; }
static bool test_4to6(l4_protocol l4_proto) { struct tuple in, out; int field = 0; bool success = true; if (is_error(init_ipv4_tuple(&in, remote4, 80, local4, 5678, l4_proto))) return false; success &= assert_equals_int(VER_CONTINUE, compute_out_tuple(&in, &out, NULL), "Call"); success &= assert_equals_int(L3PROTO_IPV6, out.l3_proto, "l3 proto"); success &= assert_equals_int(l4_proto, out.l4_proto, "l4 proto"); success &= assert_equals_ipv6_str(local6, &out.src.addr6.l3, "src addr"); if (l4_proto == L4PROTO_ICMP) success &= assert_equals_u16(1234, out.src.addr6.l4, "src port (icmp id)"); else success &= assert_equals_u16(80, out.src.addr6.l4, "src port"); success &= assert_equals_ipv6_str(remote6, &out.dst.addr6.l3, "dst addr"); success &= assert_equals_u16(1234, out.dst.addr6.l4, "dst port"); success &= assert_equals_int(0, field, "unchanged field"); return success; }
bool validate_inner_pkt_ipv4(unsigned char *payload, u16 len) { struct iphdr *hdr_ipv4; struct tcphdr *hdr_tcp; unsigned char *inner_payload; struct tuple tuple4; if (init_ipv4_tuple(&tuple4, "2.2.2.2", 4321, "1.1.1.1", 1234, L4PROTO_TCP) != 0) return false; hdr_ipv4 = (struct iphdr *) payload; hdr_tcp = (struct tcphdr *) (hdr_ipv4 + 1); inner_payload = (unsigned char *) (hdr_tcp + 1); if (!validate_ipv4_hdr(hdr_ipv4, 1320, 0, IP_DF, 0, 0, IPPROTO_TCP, &tuple4)) return false; if (!validate_tcp_hdr(hdr_tcp, &tuple4)) return false; if (!validate_payload(inner_payload, len - sizeof(*hdr_ipv4) - sizeof(*hdr_tcp), 0)) return false; return true; }
static bool test_determine_in_tuple_ipv4(void) { struct sk_buff *skb; struct fragment *frag; struct tuple actual, expected; struct ipv4_pair pair4; bool success = true; if (is_error(init_ipv4_tuple(&expected, "8.7.6.5", 8765, "5.6.7.8", 5678, L4PROTO_UDP))) return false; if (is_error(init_pair4(&pair4, "8.7.6.5", 8765, "5.6.7.8", 5678))) return false; if (is_error(create_skb_ipv4_udp(&pair4, &skb, 8))) return false; if (is_error(frag_create_from_skb(skb, &frag))) return false; success &= assert_equals_int(VER_CONTINUE, determine_in_tuple(frag, &actual), "verdict"); success &= assert_equals_tuple(&expected, &actual, "tuple"); frag_kfree(frag); return success; }