bool test_allocate_ipv4_transport_address( void ) { struct tuple tuple; struct ipv4_tuple_address tuple_addr; struct in_addr expected_addr; bool success = true; success &= str_to_addr4_verbose(IPV4_ALLOCATED_ADDR, &expected_addr); success &= inject_bib_entry( IPPROTO_ICMP ); success &= inject_bib_entry( IPPROTO_TCP ); success &= inject_bib_entry( IPPROTO_UDP ); if (!success) return false; init_tuple_for_test_ipv6(&tuple, IPPROTO_ICMP); success &= assert_true(allocate_ipv4_transport_address(&tuple, IPPROTO_ICMP, &tuple_addr), "Function result for ICMP"); success &= assert_equals_ipv4(&expected_addr , &tuple_addr.address, "IPv4 address for ICMP"); init_tuple_for_test_ipv6(&tuple, IPPROTO_TCP); success &= assert_true(allocate_ipv4_transport_address(&tuple, IPPROTO_TCP, &tuple_addr), "Function result for TCP"); success &= assert_equals_ipv4(&expected_addr , &tuple_addr.address, "IPv4 address for TCP"); success &= assert_true(tuple_addr.l4_id > 1023, "Port range for TCP"); init_tuple_for_test_ipv6(&tuple, IPPROTO_UDP); success &= assert_true(allocate_ipv4_transport_address(&tuple, IPPROTO_UDP, &tuple_addr), "Function result for UDP"); success &= assert_equals_ipv4(&expected_addr , &tuple_addr.address, "IPv4 address for UDP"); success &= assert_true(tuple_addr.l4_id % 2 == 0, "Port parity for UDP"); success &= assert_true( tuple_addr.l4_id > 1023, "Port range for UDP"); return success; }
bool test_allocate_ipv4_transport_address_digger( void ) { struct in_addr expected_addr; struct tuple tuple; struct ipv4_tuple_address new_ipv4_transport_address; bool success = true; success &= inject_bib_entry( IPPROTO_ICMP ); success &= inject_bib_entry( IPPROTO_TCP ); success &= init_tuple_for_test_ipv6(&tuple, IPPROTO_UDP); success &= str_to_addr4_verbose(IPV4_ALLOCATED_ADDR, &expected_addr); if (!success) return false; success &= assert_true( allocate_ipv4_transport_address_digger(&tuple, IPPROTO_UDP, &new_ipv4_transport_address), "Check that we can allocate a brand new IPv4 transport address for UDP."); success &= assert_true( ipv4_addr_equals(&new_ipv4_transport_address.address, &expected_addr) , "Check that the allocated IPv4 address is correct for UDP."); success &= assert_true( new_ipv4_transport_address.l4_id % 2 == 0, "Check that the allocated IPv4 port is even."); success &= assert_true( new_ipv4_transport_address.l4_id > 1023, "Check that the allocated IPv4 port is in the upper range."); return success; }
static bool init_skb_and_session(struct sk_buff **skb, struct session_entry *session, unsigned char type, u_int8_t state, unsigned int lifetime) { struct tuple tuple4, tuple6; /* Init the packet. */ *skb = init_packet_type_for_test(type); if (!(*skb)) return false; /* Init the session. */ if (!init_tuple_for_test_ipv4(&tuple4, IPPROTO_TCP)) goto failure; if (!init_tuple_for_test_ipv6(&tuple6, IPPROTO_TCP)) goto failure; session->ipv6.remote.address = tuple6.src.addr.ipv6; session->ipv6.remote.l4_id = tuple6.src.l4_id; session->ipv6.local.address = tuple6.dst.addr.ipv6; session->ipv6.local.l4_id = tuple6.dst.l4_id; session->ipv4.remote.address = tuple4.src.addr.ipv4; session->ipv4.remote.l4_id = tuple4.src.l4_id; session->ipv4.local.address = tuple4.dst.addr.ipv4; session->ipv4.local.l4_id = tuple4.dst.l4_id; session->dying_time = 10; session->state = state; return true; failure: kfree(skb); return false; }
bool test_ipv4_icmp4( void ) { u_int8_t protocol; struct tuple tuple; struct sk_buff* skb = NULL; bool success = true; protocol = IPPROTO_ICMP; success &= init_tuple_for_test_ipv4( &tuple , protocol ); skb = init_skb_for_test( &tuple, protocol ); success &= assert_not_null(skb, "init_skb_for_test"); success &= assert_equals_int(NF_DROP, ipv4_icmp4( skb, &tuple ), "See if we discard an IPv4 ICMP packet, which tries to start a communication."); kfree_skb(skb); protocol = IPPROTO_ICMP; success &= init_tuple_for_test_ipv6( &tuple , protocol ); skb = init_skb_for_test( &tuple, protocol ); success &= assert_not_null(skb, "init_skb_for_test"); success &= assert_equals_int(NF_ACCEPT, ipv6_icmp6(skb, &tuple ), "See if we can process correctly an IPv6 ICMP packet."); kfree_skb(skb); protocol = IPPROTO_ICMP; success &= init_tuple_for_test_ipv4( &tuple , protocol ); skb = init_skb_for_test( &tuple, protocol ); success &= assert_not_null(skb, "init_skb_for_test"); success &= assert_equals_int(NF_ACCEPT, ipv4_icmp4( skb, &tuple ), "See if we can process correctly an expected IPv4 ICMP packet."); kfree_skb(skb); return success; }
bool test_ipv4_udp( void ) { u_int8_t protocol = IPPROTO_UDP; struct tuple tuple; struct sk_buff* skb; bool success = true; skb = init_skb_for_test( &tuple, protocol ); if (!skb) return false; success &= init_tuple_for_test_ipv4( &tuple , protocol ); success &= assert_equals_int(NF_DROP, ipv4_udp( skb, &tuple ), "See if we discard an IPv4 UDP packet, which tries to start a communication."); success &= init_tuple_for_test_ipv6( &tuple , protocol ); success &= assert_equals_int(NF_ACCEPT, ipv6_udp( skb, &tuple ), "See if we can process correctly an IPv6 UDP packet."); success &= init_tuple_for_test_ipv4( &tuple , protocol ); success &= assert_equals_int(NF_ACCEPT, ipv4_udp( skb, &tuple ), "See if we can process correctly an expected IPv4 UDP packet."); kfree_skb(skb); return success; }
bool test_allocate_ipv4_transport_address_digger( void ) { struct in_addr expected_addr; struct tuple tuple; struct ipv4_tuple_address new_ipv4_transport_address; bool success = true; bib_init(); pool4_init(true); success &= inject_bib_entry( IPPROTO_ICMP ); success &= inject_bib_entry( IPPROTO_TCP ); success &= init_tuple_for_test_ipv6(&tuple, IPPROTO_UDP); success &= str_to_addr4_verbose(IPV4_ALLOCATED_ADDR, &expected_addr); if (!success) return false; success &= assert_true( allocate_ipv4_transport_address_digger(&tuple, IPPROTO_UDP, &new_ipv4_transport_address), "Check that we can allocate a brand new IPv4 transport address for UDP."); success &= assert_true( ipv4_addr_equals(&new_ipv4_transport_address.address, &expected_addr) , "Check that the allocated IPv4 address is correct for UDP."); success &= assert_equals_u16( IPV4_ALLOCATED_PORT_DIGGER, new_ipv4_transport_address.l4_id, "Check that the allocated IPv4 port is correct for UDP."); pool4_destroy(); bib_destroy(); return success; }
bool test_ipv4_udp( void ) { u_int8_t protocol = IPPROTO_UDP; struct tuple tuple; struct sk_buff* skb; bool success = true; if (!init_tuple_for_test_ipv4( &tuple , protocol)) return false; skb = init_skb_for_test( &tuple, protocol ); if (!skb) return false; success &= assert_equals_int(NF_DROP, ipv4_udp( skb, &tuple ), "See if we discard an IPv4 UDP packet, which tries to start a communication."); kfree_skb(skb); if (!init_tuple_for_test_ipv6( &tuple , protocol )) return false; skb = init_skb_for_test( &tuple, protocol ); if (!skb) return false; success &= assert_equals_int(NF_ACCEPT, ipv6_udp( skb, &tuple ), "See if we can process correctly an IPv6 UDP packet."); kfree_skb(skb); /* * TODO (test) The following code no longer works, because the BIB stored in the previous step * now uses a random port. These tests are missing lots of asserts anyway, so I'll fix both * issues at the same time later. */ /* if (!init_tuple_for_test_ipv4( &tuple , protocol )) return false; skb = init_skb_for_test( &tuple, protocol ); if (!skb) return false; success &= assert_equals_int(NF_ACCEPT, ipv4_udp( skb, &tuple ), "See if we can process correctly an expected IPv4 UDP packet."); kfree_skb(skb); */ return success; }
bool test_ipv6_udp( void ) { u_int8_t protocol = IPPROTO_UDP; struct tuple tuple; struct sk_buff *skb; bool success = true; if (!init_tuple_for_test_ipv6( &tuple, protocol )) return false; skb = init_skb_for_test( &tuple, protocol ); if (!skb) return false; success &= assert_equals_int(NF_ACCEPT, ipv6_udp( skb, &tuple ), "See if we can process correctly an IPv6 UDP packet."); kfree_skb(skb); return success; }
bool test_allocate_ipv4_transport_address( void ) { u_int8_t protocols[] = { IPPROTO_ICMP, IPPROTO_TCP, IPPROTO_UDP }; __u16 expected_ports[] = { IPV6_ALLOCATE_PORT, IPV6_ALLOCATE_PORT, IPV6_ALLOCATE_PORT }; struct in_addr expected_addr; struct tuple tuple; struct ipv4_tuple_address new_ipv4_transport_address; bool success = true; int i; success &= pool6_init(); success &= pool4_init(true); success &= bib_init(); success &= str_to_addr4_verbose(IPV4_ALLOCATED_ADDR, &expected_addr); success &= inject_bib_entry( IPPROTO_ICMP ); success &= inject_bib_entry( IPPROTO_TCP ); success &= inject_bib_entry( IPPROTO_UDP ); if (!success) return false; for (i = 0; i < ARRAY_SIZE(protocols); i++) { init_tuple_for_test_ipv6(&tuple, protocols[i]); success &= assert_true(allocate_ipv4_transport_address(&tuple, protocols[i], &new_ipv4_transport_address), "Check that we can allocate a brand new IPv4 transport address."); success &= assert_equals_ipv4(&expected_addr , &new_ipv4_transport_address.address, "Check that the allocated IPv4 address is correct."); success &= assert_equals_u16( expected_ports[i], new_ipv4_transport_address.l4_id, "Check that the allocated IPv4 port is correct."); } bib_destroy(); pool4_destroy(); pool6_destroy(); 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; }
bool test_filtering_and_updating( void ) { u_int8_t protocol; struct tuple tuple; struct sk_buff *skb; struct in_addr addr4; struct in6_addr addr6; bool success = true; log_debug(" >>> Errores de ICMP no deben afectar las tablas "); protocol = IPPROTO_ICMP; success &= init_tuple_for_test_ipv4( &tuple , protocol ); skb = init_skb_for_test( &tuple, protocol ); success &= assert_not_null(skb, "init_skb_for_test"); icmp_hdr(skb)->type = ICMP_DEST_UNREACH; /* Error packet */ /* Process a tuple generated from a incoming IPv6 packet: */ success &= assert_equals_int(NF_ACCEPT, filtering_and_updating( skb, &tuple), "See if we can forward an IPv4 ICMP packet."); kfree_skb(skb); log_debug(" >>> Get rid of hairpinning loop "); protocol = IPPROTO_UDP; success &= init_tuple_for_test_ipv6( &tuple , protocol ); skb = init_skb_for_test( &tuple, protocol ); success &= assert_not_null(skb, "init_skb_for_test"); /* Add pref64 */ success &= str_to_addr6_verbose(INIT_TUPLE_IPV6_HAIR_LOOP_SRC_ADDR , &addr6); tuple.src.addr.ipv6 = addr6; success &= assert_equals_int(NF_DROP, filtering_and_updating( skb, &tuple), "See if we can get rid of hairpinning loop in IPv6."); kfree_skb(skb); log_debug(" >>> Get rid of unwanted packets "); success &= init_tuple_for_test_ipv6( &tuple , protocol ); skb = init_skb_for_test( &tuple, protocol ); success &= assert_not_null(skb, "init_skb_for_test"); /* Unwanted packet */ success &= str_to_addr6_verbose(INIT_TUPLE_IPV6_HAIR_LOOP_DST_ADDR , &addr6); tuple.dst.addr.ipv6 = addr6; success &= assert_equals_int(NF_DROP, filtering_and_updating( skb, &tuple), "See if we can get rid of unwanted packets in IPv6."); kfree_skb(skb); log_debug(" >>> Get rid of un-expected packets, destined to an address not in pool"); success &= init_tuple_for_test_ipv4( &tuple , protocol ); skb = init_skb_for_test( &tuple, protocol ); success &= assert_not_null(skb, "init_skb_for_test"); /* Packet destined to an address not in pool */ success &= str_to_addr4_verbose(INIT_TUPLE_IPV4_NOT_POOL_DST_ADDR , &addr4); tuple.dst.addr.ipv4 = addr4; success &= assert_equals_int(NF_DROP, filtering_and_updating( skb, &tuple), "See if we can get rid of packet destined to an address not in pool."); kfree_skb(skb); log_debug(" >>> IPv4 incoming packet --> reject"); success &= init_tuple_for_test_ipv4( &tuple , protocol ); skb = init_skb_for_test( &tuple, protocol ); success &= assert_not_null(skb, "init_skb_for_test"); success &= assert_equals_int(NF_DROP, filtering_and_updating( skb, &tuple), "See if we can do reject an incoming IPv4 UDP packet."); kfree_skb(skb); log_debug(" >>> IPv6 incoming packet --> accept"); success &= init_tuple_for_test_ipv6( &tuple , protocol ); skb = init_skb_for_test( &tuple, protocol ); success &= assert_not_null(skb, "init_skb_for_test"); success &= assert_equals_int(NF_ACCEPT, filtering_and_updating( skb, &tuple), "See if we can do filtering and updating on an incoming IPv6 UDP packet."); kfree_skb(skb); /* TODO (test) see test_ipv4_udp(). */ /* log_debug(" >>> IPv4 incoming packet --> accept"); success &= init_tuple_for_test_ipv4( &tuple , protocol ); skb = init_skb_for_test( &tuple, protocol ); success &= assert_not_null(skb, "init_skb_for_test"); success &= assert_equals_int(NF_ACCEPT, filtering_and_updating( skb, &tuple), "See if we can do filtering and updating on an incoming IPv4 UDP packet."); kfree_skb(skb); */ 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; }