/*
** Copyright (C) 2009-2016 Quadrant Information Security <quadrantsec.com>
** Copyright (C) 2009-2016 Champ Clark III <cclark@quadrantsec.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License Version 2 as
** published by the Free Software Foundation.  You may not use, modify or
** distribute this program under any other version of the GNU General
** Public License.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#ifdef HAVE_CONFIG_H
#include "config.h"             /* From autoconf */
#endif

#ifdef WITH_BLUEDOT
#define BLUEDOT_MAX_CAT        10
#endif

typedef struct arr_flow_1 arr_flow_1;
struct arr_flow_1 {
    uint32_t lo;
    uint32_t hi;
};

typedef struct arr_flow_2 arr_flow_2;
struct arr_flow_2 {
    uint32_t lo;
    uint32_t hi;
};

typedef struct meta_content_conversion meta_content_conversion;
struct meta_content_conversion {
    char meta_content_converted[MAX_META_CONTENT][256];
    int  meta_counter;
};

typedef struct _Rule_Struct _Rule_Struct;
struct _Rule_Struct {
    unsigned s_size_rule;
    char s_msg[256];

    pcre *re_pcre[MAX_PCRE];
    pcre_extra *pcre_extra[MAX_PCRE];

    char s_content[MAX_CONTENT][256];
    char s_reference[MAX_REFERENCE][256];
    char s_classtype[32];
    char s_sid[32];
    char s_rev[5];
    int  s_pri;
    char s_program[256];
    char s_facility[50];
    char s_syspri[25];
    char s_level[25];
    char s_tag[10];

    char email[255];
    sbool email_flag;

    /* Check Flow */
    struct arr_flow_1 flow_1[MAX_CHECK_FLOWS];
    struct arr_flow_2 flow_2[MAX_CHECK_FLOWS];

    struct meta_content_conversion meta_content_containers[MAX_META_CONTENT];

    int direction;

    sbool flow_1_var;
    sbool flow_2_var;

    sbool has_flow;

    int flow_1_type[MAX_CHECK_FLOWS];
    int flow_2_type[MAX_CHECK_FLOWS];
    int  flow_1_counter;
    int  flow_2_counter;

    sbool s_nocase[MAX_CONTENT];
    int s_offset[MAX_CONTENT];
    int s_depth[MAX_CONTENT];
    int s_distance[MAX_CONTENT];
    int s_within[MAX_CONTENT];

    sbool meta_nocase[MAX_META_CONTENT];
    int meta_offset[MAX_META_CONTENT];
    int meta_depth[MAX_META_CONTENT];
    int meta_distance[MAX_META_CONTENT];
    int meta_within[MAX_META_CONTENT];

    int pcre_count;
    int content_count;
    int meta_content_count;
    int meta_content_converted_count;
    int flowbit_count;				/* Number of flowbits in memory */

    int flowbit_condition_count;		/* Number of isset/isnot within a rule */
    int flowbit_set_count;			/* Number of set/unset within a rule */

    int ref_count;
    int dst_port;
    int src_port;
    int ip_proto;
    sbool s_find_port;
    sbool s_find_proto;
    sbool s_find_proto_program;

    sbool s_find_src_ip;
    int   s_find_src_pos;

    sbool s_find_dst_ip;
    int   s_find_dst_pos;

    int   s_find_hash_type;

    sbool flowbit_flag;                   	/* Does the rule contain a flowbit? */
    sbool flowbit_noalert;			/* Do we want to suppress "alerts" from flowbits in ALL output plugins? */
    sbool flowbit_nounified2;	 		/* Do we want to suppress "unified2" from flowbits in unified2 output */

    int flowbit_type[MAX_FLOWBITS];		/* 1 == set, 2 == unset,  3 == isset, 4 == isnotset */
    int flowbit_direction[MAX_FLOWBITS];	/* 0 == none, 1 == both, 2 == by_src, 3 == by_dst */
    int flowbit_memory_position[MAX_FLOWBITS];	/* "Where" in the flowbit struct flowbit is */
    int flowbit_timeout[MAX_FLOWBITS];		/* How long a flowbit is to stay alive (seconds) */
    char flowbit_name[MAX_FLOWBITS][64]; 	/* Name of the flowbit */

    sbool normalize;
    sbool content_not[MAX_CONTENT];     /* content: ! "something" */

    int drop;                   /* inline DROP for ext. */

    int threshold_type;         /* 1 = limit,  2 = thresh */
    int threshold_method;       /* 1 ==  src,  2 == dst,  3 == username, 4 == srcport, 5 == dstport */
    int threshold_count;
    int threshold_seconds;

    int after_method;               /* 1 ==  src,  2 == dst, 3 == username, 4 == dstport */
    int after_count;
    int after_seconds;

    int fwsam_src_or_dst;               /* 1 == src,  2 == dst */
    unsigned long  fwsam_seconds;

    sbool meta_content_flag;
    sbool meta_content_case[MAX_META_CONTENT];
    sbool meta_content_not[MAX_META_CONTENT];

    char meta_content[MAX_META_CONTENT][CONFBUF];
    char meta_content_help[MAX_META_CONTENT][CONFBUF];

    sbool alert_time_flag;
    unsigned char alert_days;
    sbool aetas_next_day;

    int	 aetas_start;
    int  aetas_end;

    int  alert_end_hour;
    int  alert_end_minute;

    sbool external_flag;
    char  external_program[MAXPATH];

    /* Bro Intel */

    sbool brointel_flag;

    sbool brointel_ipaddr_src;
    sbool brointel_ipaddr_dst;
    sbool brointel_ipaddr_both;
    sbool brointel_ipaddr_all;

    sbool brointel_domain;
    sbool brointel_file_hash;
    sbool brointel_url;
    sbool brointel_software;
    sbool brointel_email;
    sbool brointel_user_name;
    sbool brointel_file_name;
    sbool brointel_cert_hash;

    /* Blacklist */

    sbool blacklist_flag;

    sbool blacklist_ipaddr_src;
    sbool blacklist_ipaddr_dst;
    sbool blacklist_ipaddr_both;
    sbool blacklist_ipaddr_all;

#ifdef WITH_BLUEDOT

    int   bluedot_ipaddr_type;                 /* 1 == src,  2 == dst,  3 == both,  4 == all */

    int   bluedot_ip_cats[BLUEDOT_MAX_CAT];
    int   bluedot_ip_cat_count;

    uintmax_t bluedot_mdate_effective_period;
    uintmax_t bluedot_cdate_effective_period;

    int   bluedot_hash_cats[BLUEDOT_MAX_CAT];
    int   bluedot_hash_cat_count;

    int   bluedot_url_cats[BLUEDOT_MAX_CAT];
    int   bluedot_url_cat_count;

    int   bluedot_filename_cats[BLUEDOT_MAX_CAT];
    int   bluedot_filename_cat_count;

    sbool bluedot_file_hash;
    sbool bluedot_url;
    sbool bluedot_filename;

#endif


#ifdef HAVE_LIBMAXMINDDB

    sbool geoip2_flag;
    int   geoip2_type;           /* 1 == isnot, 2 == is */
    char  geoip2_country_codes[256];
    int   geoip2_src_or_dst;             /* 1 == src, 2 == dst */

#endif

};

void Load_Rules ( const char * );
