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_packet_is_v6_rst( void )
{
    struct sk_buff *skb;
    bool success = true;

    /* Set packet type to V6 RST */
    if ((skb = init_packet_type_for_test( PACKET_TYPE_V6_RST )) == NULL)
        return false;

    success &= assert_true( packet_is_v6_rst( skb ), "Test if we detect a V6 RST packet.");

    kfree_skb(skb);
    return success;
}
bool test_packet_is_v4_fin( void )
{
    struct sk_buff *skb;
    bool success = true;

    /* Set packet type to V4 FIN */
    if ((skb = init_packet_type_for_test( PACKET_TYPE_V4_FIN )) == NULL)
        return false;

    success &= assert_true(packet_is_v4_fin( skb ), "Test if we detect a V4 FIN packet.");

    kfree_skb(skb);
    return success;
}
bool test_packet_is_ipv4( void )
{
    struct sk_buff *buffer;
    bool success = true;

    /* Set packet type to V4 SYN */
    if ((buffer = init_packet_type_for_test( PACKET_TYPE_V4_SYN )) == NULL)
        return false;

    success &= assert_true( packet_is_ipv4( buffer ), "Test if we detect an IPv4 packet.");

    kfree_skb(buffer);
    return success;
}
bool test_packet_is_ipv6( void )
{
    struct sk_buff *skb;
    bool success = true;

    // Set packet type to V6 SYN
    if ((skb = init_packet_type_for_test( PACKET_TYPE_V6_SYN )) == NULL)
        return false;

    success &= assert_true( packet_is_ipv6( skb ), "Test if we detect an IPv6 packet.");

    kfree_skb(skb);
    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;
}
/**
 * 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;
}