view src/syslogconfig.h @ 51:206448c00b55 stable-1-0-12

Allow multiple contexts with independent add/remove commands.
author Carl Byington <carl@five-ten-sg.com>
date Sat, 24 Jan 2009 15:52:20 -0800
parents ba0259c9e411
children b45dddebe8fc
line wrap: on
line source

/*

Copyright (c) 2007 Carl Byington - 510 Software Group, released under
the GPL version 3 or any later version at your choice available at
http://www.gnu.org/licenses/gpl-3.0.txt

*/


class SYSLOGCONFIG;
class CONTEXT;
class CONFIG;

struct IPPAIR {
    int first;
    int last;
    int cidr;
};

class PATTERN {
    const char *    pattern;    // owned by the string table
    regex_t         re;
    int             index;      // zero based substring of the regex match that contains the ip address or hostname
    int             amount;     // count to add to the ip address leaky bucket
    const char *    message;    // for logging, owned by the string table
public:
    ~PATTERN();
    PATTERN(TOKEN &tok, const char *pattern_, int index_, int amount_, const char *msg_);
    bool    process(char *buf, CONTEXT &con, const char *file_name, int pattern_index);
    void    dump(int level);
};

struct ltint
{
  bool operator()(const int s1, const int s2) const
  {
    return (unsigned)s1 < (unsigned)s2;
  }
};

struct bucket {
    int  count;
    bool latch; // true iff ever count>threshold
};

typedef map<int, bucket, ltint>   ip_buckets;

class IPR {
    int         reference_count;    // number of contexts using this recorder
    ip_buckets  violations;
public:
    IPR();
    int  reference(int delta)   {reference_count += delta; return reference_count;};
    void add(int ip, int amount, CONTEXT &con, const char *file_name, int pattern_index, const char *message);
    void leak(int amount, CONTEXT &con);
    void free_all(CONTEXT &con);
    void update(int ip, bool added, const char *file_name, int pattern_index, const char *message);
    void changed(CONTEXT &con, int ip, bool added);
    static IPR* find(const char* name);
    static void release(const char* name);
};


typedef SYSLOGCONFIG *          SYSLOGCONFIGP;
typedef PATTERN *               PATTERNP;
typedef CONTEXT *               CONTEXTP;
typedef map<const char *, IPR*> recorder_map;
typedef list<CONTEXTP>          context_list;
typedef list<SYSLOGCONFIGP>     syslogconfig_list;
typedef list<IPPAIR>            ippair_list;
typedef list<PATTERNP>          pattern_list;
const int buflen = 1024;

class SYSLOGCONFIG {
    TOKEN *         tokp;
    const char *    file_name;  // name of the syslog file
    pattern_list    patterns;   // owns the patterns
    int             fd;
    struct stat     openfdstat;
    int             len;        // bytes in the buffer
    char            buf[buflen];
public:
    SYSLOGCONFIG(TOKEN &tok, const char *file_name_);
    ~SYSLOGCONFIG();
    bool    failed()    { return (fd == -1); };
    void    open(bool msg);
    bool    read(CONTEXT &con);
    void    close();
    void    add_pattern(PATTERNP pat);
    void    process(CONTEXT &con);
    void    dump(int level);
};


class CONTEXT {
public:
    const char *        name;               // name of this context
    int                 threshold;
    ippair_list         ignore;             // owns all the ippairs
    const char *        add_command;        // owned by the string table
    const char *        remove_command;     // ""
    IPR *               recorder;           // used to record violations
    syslogconfig_list   syslogconfigs;      // owns all the syslogconfigs

    CONTEXT(const char *nam);
    ~CONTEXT();
    void    set_add(const char *add)        { add_command    = add;        };
    void    set_remove(const char *remove)  { remove_command = remove;     };
    void    set_threshold(int threshold_)   { threshold      = threshold_; };
    int     get_threshold()                 { return threshold;            };
    void    add_syslogconfig(SYSLOGCONFIGP con);
    void    add_pair(IPPAIR pair);
    void    dump();
    void    read(CONFIG &con);
    void    free_all();
    void    leak(int delta);
    bool    looking(int ip);
};


class CONFIG {
public:
    // the only mutable stuff once it has been loaded from the config file
    int                 reference_count;    // protected by the global config_mutex
    // all the rest is constant after loading from the config file
    int                 generation;
    time_t              load_time;
    string_set          config_files;
    context_list        contexts;

    CONFIG();
    ~CONFIG();
    void    add_context(CONTEXTP con)  {contexts.push_back(con);} ;
    void    dump();
    void    read();
    void    sleep(int duration, time_t &previous);
    void    free_all();
};

void        discard(string_set &s);
const char* register_string(string_set &s, const char *name);
const char* register_string(const char *name);
void        clear_strings();
int         ip_address(const char *have);
bool        load_conf(CONFIG &dc, const char *fn);
void        token_init();

extern const char *token_add;
extern const char *token_bucket;
extern const char *token_context;
extern const char *token_file;
extern const char *token_ignore;
extern const char *token_include;
extern const char *token_index;
extern const char *token_lbrace;
extern const char *token_pattern;
extern const char *token_rbrace;
extern const char *token_remove;
extern const char *token_semi;
extern const char *token_slash;
extern const char *token_threshold;