/*- * Copyright (c) 2005 Andrey Simonenko * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "config.h" #ifndef lint static const char rcsid[] ATTR_UNUSED = "@(#)$Id: ipastat_thresholds.c,v 1.1.4.2 2007/05/11 16:29:59 simon Exp $"; #endif /* !lint */ #include #include #include #include #include "ipa_mod.h" #include "dlapi.h" #include "confcommon.h" #include "memfunc.h" #include "ipastat_log.h" #include "ipastat_main.h" #include "ipastat_rules.h" #include "ipastat_st.h" int has_opt_thresholds = 0; /* 1, if -q ... -t ... */ #ifdef WITH_THRESHOLDS int dynamic_thresholds = -1;/* dynamic_thresholds parameter. */ ipa_mzone *threshold_mzone; /* Mzone for struct threshold{}. */ struct threshold * alloc_threshold(void) { struct threshold *threshold; if ( (threshold = mzone_alloc(threshold_mzone)) == NULL) { xlogmsgx(IPA_LOG_ERR, "alloc_threshold: mzone_alloc failed"); return NULL; } threshold->threshold_info = NULL; threshold->st_list = NULL; threshold->inited = 0; return threshold; } /* * Return pointer to threshold with the give name. */ struct threshold * threshold_by_name(const struct rule *rule, const char *name) { struct threshold *threshold; STAILQ_FOREACH(threshold, &rule->thresholds, link) if (strcmp(name, threshold->threshold_name) == 0) return threshold; return NULL; } static void get_min_max_no( const struct opt_thresholds *opt_thresholds, u_int *minno, u_int *maxno) { const struct threshold *threshold; const struct opt_threshold *opt_threshold; *minno = *maxno = STAILQ_FIRST(opt_thresholds)->threshold->thresholdno; STAILQ_FOREACH(opt_threshold, opt_thresholds, link) { threshold = opt_threshold->threshold; if (*minno > threshold->thresholdno) *minno = threshold->thresholdno; if (*maxno < threshold->thresholdno) *maxno = threshold->thresholdno; } } /* * Init all thresholds from one rule in modules. */ int init_thresholds(const struct opt_rule *opt_rule) { u_int minno, maxno, no; struct threshold *threshold; const struct rule *rule; const struct opt_threshold *opt_threshold; const struct opt_thresholds *opt_thresholds; rule = opt_rule->rule; opt_thresholds = &opt_rule->opt_thresholds; get_min_max_no(opt_thresholds, &minno, &maxno); for (no = minno; no <= maxno; ++no) STAILQ_FOREACH(opt_threshold, opt_thresholds, link) { threshold = opt_threshold->threshold; if (threshold->thresholdno == no) { if (!threshold->inited) { threshold->inited = 1; /* Init in modules. */ if (st_init_threshold(rule, threshold) < 0) { logmsgx(IPA_LOG_ERR, "rule %s, threshold %s: init_thresholds: st_init_threshold failed", rule->rule_name, threshold->threshold_name); return -1; } } break; } } return 0; } int deinit_thresholds(const struct opt_rule *opt_rule) { int error = 0; u_int minno, maxno, no; struct threshold *threshold; const struct rule *rule; const struct opt_threshold *opt_threshold; const struct opt_thresholds *opt_thresholds; rule = opt_rule->rule; opt_thresholds = &opt_rule->opt_thresholds; get_min_max_no(opt_thresholds, &minno, &maxno); for (no = minno; no <= maxno; ++no) STAILQ_FOREACH(opt_threshold, &opt_rule->opt_thresholds, link) { threshold = opt_threshold->threshold; if (threshold->thresholdno == no) { if (threshold->inited) { threshold->inited = 0; /* Deinit in modules. */ if (st_deinit_threshold(rule, threshold) < 0) { logmsgx(IPA_LOG_ERR, "rule %s, threshold %s: deinit_thresholds: st_deinit_threshold failed", rule->rule_name, threshold->threshold_name); error = -1; } } break; } } return error; } /* * Copy all thresholds from list_src to rule. */ int copy_thresholds(struct rule *rule, const struct thresholds_list *list_src) { struct threshold *threshold_dst; const struct threshold *threshold_src; STAILQ_FOREACH(threshold_src, list_src, link) { if ( (threshold_dst = mzone_alloc(threshold_mzone)) == NULL) { xlogmsgx(IPA_LOG_ERR, "copy_thresholds: mzone_alloc failed"); return -1; } /* Copy settings from source threshold. */ *threshold_dst = *threshold_src; threshold_dst->free_mask = 0; /* Link just allocated threshold to rule. */ STAILQ_INSERT_TAIL(&rule->thresholds, threshold_dst, link); } return 0; } #include /* * Release memory used by a list of thresholds. */ void free_thresholds(struct thresholds_list *thresholds) { struct threshold *threshold, *threshold_next; for (threshold = STAILQ_FIRST(thresholds); threshold != NULL; threshold = threshold_next) { threshold_next = STAILQ_NEXT(threshold, link); if (threshold->free_mask & THRESHOLD_FREE_NAME) mem_free(threshold->threshold_name, m_anon); mem_free(threshold->threshold_info, m_result); mzone_free(threshold_mzone, threshold); } } /* * Add one optional threshold given in the -q -r option. */ int add_opt_threshold(const char *threshold_name) { struct opt_threshold *opt_threshold; if ( (opt_threshold = mem_malloc(sizeof *opt_threshold, m_anon)) == NULL) { logmsgx(IPA_LOG_ERR, "add_opt_threshold: mem_malloc failed"); return -1; } opt_threshold->threshold_name = threshold_name; opt_threshold->opt_st = cur_opt_st; cur_opt_rule->type = OPT_RULE_THRESHOLD; STAILQ_INSERT_TAIL(&cur_opt_rule->opt_thresholds, opt_threshold, link); has_opt_thresholds = 1; return 0; } int parse_opt_thresholds(const struct opt_rule *opt_rule) { u_int thresholdno; struct rule *rule; struct threshold *threshold; struct opt_threshold *opt_threshold; if (!STAILQ_EMPTY(&opt_rule->opt_thresholds)) { rule = opt_rule->rule; if (STAILQ_EMPTY(&rule->thresholds)) thresholdno = 0; else { threshold = STAILQ_LAST(&rule->thresholds, threshold, link); thresholdno = threshold->thresholdno + 1; } STAILQ_FOREACH(opt_threshold, &opt_rule->opt_thresholds, link) { if ( (threshold = threshold_by_name(rule, opt_threshold->threshold_name)) == NULL) { /* This threshold is not given in the configuration file. */ if (!dynamic_thresholds) { logmsgx(IPA_LOG_ERR, "parse_opt_thresholds: unknown rule %s, threshold %s", rule->rule_name, opt_threshold->threshold_name); return -1; } if ( (threshold = alloc_threshold()) == NULL) { logmsgx(IPA_LOG_ERR, "parse_opt_thresholds: alloc_threshold failed"); return -1; } STAILQ_INSERT_TAIL(&rule->thresholds, threshold, link); threshold->thresholdno = thresholdno++; threshold->threshold_name = (char *)opt_threshold->threshold_name; threshold->free_mask = 0; } opt_threshold->threshold = threshold; if (opt_threshold->opt_st != NULL) threshold->st_list = opt_threshold->opt_st->st_list; if (threshold->st_list == NULL) threshold->st_list = rule->st_list; } } return 0; } void free_opt_thresholds(const struct opt_thresholds *opt_thresholds) { struct opt_threshold *opt_threshold, *opt_threshold_next; for (opt_threshold = STAILQ_FIRST(opt_thresholds); opt_threshold != NULL; opt_threshold = opt_threshold_next) { opt_threshold_next = STAILQ_NEXT(opt_threshold, link); mem_free(opt_threshold, m_anon); } } #endif /* WITH_THRESHOLDS */